From 4384d4dcf3e603b8c500c43d6b8fe55947475eff Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 9 Nov 2024 02:51:50 +0900 Subject: [PATCH 01/22] Bump actions/attest-build-provenance from 1.4.3 to 1.4.4 (#1278) Bumps [actions/attest-build-provenance](https://github.com/actions/attest-build-provenance) from 1.4.3 to 1.4.4. - [Release notes](https://github.com/actions/attest-build-provenance/releases) - [Changelog](https://github.com/actions/attest-build-provenance/blob/main/RELEASE.md) - [Commits](https://github.com/actions/attest-build-provenance/compare/1c608d11d69870c2092266b3f9a6f3abbf17002c...ef244123eb79f2f7a7e75d99086184180e6d0018) --- updated-dependencies: - dependency-name: actions/attest-build-provenance dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 657445e42..17147aa87 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -75,7 +75,7 @@ jobs: AVES_GOOGLE_API_KEY: ${{ secrets.AVES_GOOGLE_API_KEY }} - name: Generate artifact attestation - uses: actions/attest-build-provenance@1c608d11d69870c2092266b3f9a6f3abbf17002c # v1.4.3 + uses: actions/attest-build-provenance@ef244123eb79f2f7a7e75d99086184180e6d0018 # v1.4.4 with: subject-path: 'outputs/*' From b5e6ce9c94197c2384f97393d12273868cd72793 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 9 Nov 2024 02:51:59 +0900 Subject: [PATCH 02/22] Bump github/codeql-action from 3.27.0 to 3.27.1 (#1281) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.27.0 to 3.27.1. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/662472033e021d55d94146f66f6058822b0b39fd...4f3212b61783c3c68e8309a0f18a699764811cda) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/quality-check.yml | 4 ++-- .github/workflows/scorecards.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/quality-check.yml b/.github/workflows/quality-check.yml index 3971f6bd7..8911a9452 100644 --- a/.github/workflows/quality-check.yml +++ b/.github/workflows/quality-check.yml @@ -69,7 +69,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@662472033e021d55d94146f66f6058822b0b39fd # v3.27.0 + uses: github/codeql-action/init@4f3212b61783c3c68e8309a0f18a699764811cda # v3.27.1 with: languages: ${{ matrix.language }} build-mode: ${{ matrix.build-mode }} @@ -83,6 +83,6 @@ jobs: ./flutterw build apk --profile -t lib/main_play.dart --flavor play - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@662472033e021d55d94146f66f6058822b0b39fd # v3.27.0 + uses: github/codeql-action/analyze@4f3212b61783c3c68e8309a0f18a699764811cda # v3.27.1 with: category: "/language:${{matrix.language}}" diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index a88b1673d..b097c8538 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -71,6 +71,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@662472033e021d55d94146f66f6058822b0b39fd # v3.27.0 + uses: github/codeql-action/upload-sarif@4f3212b61783c3c68e8309a0f18a699764811cda # v3.27.1 with: sarif_file: results.sarif From 1c61aa7d14d3f8b7e16efc28ab9631e5cae714bc Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Fri, 8 Nov 2024 19:20:37 +0100 Subject: [PATCH 03/22] l10n by weblate (#1270) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Translate-URL: https://hosted.weblate.org/projects/aves/app-android/ar/ Translate-URL: https://hosted.weblate.org/projects/aves/app-android/az/ Translate-URL: https://hosted.weblate.org/projects/aves/app-android/de/ Translate-URL: https://hosted.weblate.org/projects/aves/app-android/en_SHAW/ Translate-URL: https://hosted.weblate.org/projects/aves/app-android/fi/ Translate-URL: https://hosted.weblate.org/projects/aves/app-android/id/ Translate-URL: https://hosted.weblate.org/projects/aves/app-android/lt/ Translate-URL: https://hosted.weblate.org/projects/aves/app-android/pt/ Translate-URL: https://hosted.weblate.org/projects/aves/app-android/sk/ Translate-URL: https://hosted.weblate.org/projects/aves/app-android/tr/ Translate-URL: https://hosted.weblate.org/projects/aves/app-android/uk/ Translate-URL: https://hosted.weblate.org/projects/aves/app-android/vi/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/ar/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/az/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/de/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/en_Shaw/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/es/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/fa/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/fr/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/id/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/ko/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/lt/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/nb_NO/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/nl/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/pl/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/pt/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/ru/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/sk/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/sv/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/tr/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/uk/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/vi/ Translate-URL: https://hosted.weblate.org/projects/aves/store-full-description/ Translate-URL: https://hosted.weblate.org/projects/aves/store-full-description/en_Shaw/ Translate-URL: https://hosted.weblate.org/projects/aves/store-short-description/en_Shaw/ Translation: Aves/App - Android Translation: Aves/App - Main Translation: Aves/Store - Full description Translation: Aves/Store - Short description Co-authored-by: 5FeetUnder <15950507+5FeetUnder@users.noreply.github.com> Co-authored-by: Alireza Rashidi Co-authored-by: Femini Co-authored-by: Ihor Hordiichuk Co-authored-by: João Palmeiro Co-authored-by: LE NHUT BINH <125377511+lenhutbinh@users.noreply.github.com> Co-authored-by: Languages add-on Co-authored-by: Linerly Co-authored-by: Milan Šalka Co-authored-by: Mohamed Zeroug Co-authored-by: Noah Kenzie Rodriguez-Beus Co-authored-by: Olli Co-authored-by: Oğuz Ersen Co-authored-by: Paranoid Android Co-authored-by: Shift18 Co-authored-by: Stephan Paternotte Co-authored-by: Thibault Deckers Co-authored-by: Whoever4976 Co-authored-by: Your Average Code Co-authored-by: bittin1ddc447d824349b2 Co-authored-by: elea11 Co-authored-by: gallegonovato Co-authored-by: marciozomb13 Co-authored-by: rehork Co-authored-by: splice11 Co-authored-by: v1s7 --- .../app/src/main/res/values-az/strings.xml | 12 ++ .../metadata/android/az/full_description.txt | 5 + .../metadata/android/az/short_description.txt | 1 + lib/l10n/app_ar.arb | 8 +- lib/l10n/app_az.arb | 121 ++++++++++++++++++ lib/l10n/app_de.arb | 16 ++- lib/l10n/app_fa.arb | 84 ++++++------ lib/l10n/app_sk.arb | 6 +- 8 files changed, 206 insertions(+), 47 deletions(-) create mode 100644 android/app/src/main/res/values-az/strings.xml create mode 100644 fastlane/metadata/android/az/full_description.txt create mode 100644 fastlane/metadata/android/az/short_description.txt create mode 100644 lib/l10n/app_az.arb diff --git a/android/app/src/main/res/values-az/strings.xml b/android/app/src/main/res/values-az/strings.xml new file mode 100644 index 000000000..31f1b1c1d --- /dev/null +++ b/android/app/src/main/res/values-az/strings.xml @@ -0,0 +1,12 @@ + + + Aves + Şəkil Çərçivəsi + Divar kağızı + Xəritə + Axtarış + Videolar + Medianı yoxla + Media yoxlanılır + Dayandır + \ No newline at end of file diff --git a/fastlane/metadata/android/az/full_description.txt b/fastlane/metadata/android/az/full_description.txt new file mode 100644 index 000000000..6b96ec3ea --- /dev/null +++ b/fastlane/metadata/android/az/full_description.txt @@ -0,0 +1,5 @@ +Aves can handle all sorts of images and videos, including your typical JPEGs and MP4s, but also more exotic things like multi-page TIFFs, SVGs, old AVIs and more! It scans your media collection to identify motion photos, panoramas (aka photo spheres), 360° videos, as well as GeoTIFF files. + +Navigation and search is an important part of Aves. The goal is for users to easily flow from albums to photos to tags to maps, etc. + +Aves integrates with Android (from KitKat to Android 14, including Android TV) with features such as widgets, app shortcuts, screen saver and global search handling. It also works as a media viewer and picker. diff --git a/fastlane/metadata/android/az/short_description.txt b/fastlane/metadata/android/az/short_description.txt new file mode 100644 index 000000000..8c9445bd5 --- /dev/null +++ b/fastlane/metadata/android/az/short_description.txt @@ -0,0 +1 @@ +Gallery and metadata explorer \ No newline at end of file diff --git a/lib/l10n/app_ar.arb b/lib/l10n/app_ar.arb index f55426b8b..f73a6277c 100644 --- a/lib/l10n/app_ar.arb +++ b/lib/l10n/app_ar.arb @@ -269,7 +269,7 @@ "@tileLayoutGrid": {}, "settingsDisplayUseTvInterface": "واجهة أندرويد TV", "@settingsDisplayUseTvInterface": {}, - "settingsTimeToTakeActionTile": "حان الوقت لاتخاذ الإجراءات اللازمة", + "settingsTimeToTakeActionTile": "وقت إتخاذ الإجراءات", "@settingsTimeToTakeActionTile": {}, "aboutCreditsWorldAtlas1": "يستخدم هذا التطبيق ملف TopoJSON من", "@aboutCreditsWorldAtlas1": {}, @@ -1544,5 +1544,9 @@ "mapStyleOsmLiberty": "حرية خرائط OSM", "@mapStyleOsmLiberty": {}, "mapAttributionOsmLiberty": "البلاط بواسطة [OpenMapTiles](https://www.openmaptiles.org/), [CC BY](http://creativecommons.org/licenses/by/4.0) • مُستضاف بواسطة [OSM Americana](https://tile.ourmap.us)", - "@mapAttributionOsmLiberty": {} + "@mapAttributionOsmLiberty": {}, + "videoActionShowPreviousFrame": "إظهار الإطار السابق", + "@videoActionShowPreviousFrame": {}, + "videoActionShowNextFrame": "إظهار الإطار التالي", + "@videoActionShowNextFrame": {} } diff --git a/lib/l10n/app_az.arb b/lib/l10n/app_az.arb new file mode 100644 index 000000000..0b96ffecb --- /dev/null +++ b/lib/l10n/app_az.arb @@ -0,0 +1,121 @@ +{ + "columnCount": "{count, plural, =1{{count} sütun} other{{count} sütun}}", + "@columnCount": { + "placeholders": { + "count": { + "format": "decimalPattern" + } + } + }, + "timeSeconds": "{count, plural, =1{{count} saniyə} other{{count} saniyə}}", + "@timeSeconds": { + "placeholders": { + "count": { + "format": "decimalPattern" + } + } + }, + "hideTooltip": "Gizlət", + "@hideTooltip": {}, + "chipActionGoToAlbumPage": "Albomlarda Göstər", + "@chipActionGoToAlbumPage": {}, + "chipActionGoToCountryPage": "Ölkələrdə Göstər", + "@chipActionGoToCountryPage": {}, + "welcomeOptional": "Zəruri deyil", + "@welcomeOptional": {}, + "welcomeTermsToggle": "Mən hökm və şərtlərlə razıyam", + "@welcomeTermsToggle": {}, + "itemCount": "{count, plural, =1{{count} element}\n other{{count} element}}", + "@itemCount": { + "placeholders": { + "count": { + "format": "decimalPattern" + } + } + }, + "timeMinutes": "{count, plural, =1{{count} dəqiqə} other{{count} dəqiqə}}", + "@timeMinutes": { + "placeholders": { + "count": { + "format": "decimalPattern" + } + } + }, + "timeDays": "{count, plural, =1{{count} gün} other{{count} gün}}", + "@timeDays": { + "placeholders": { + "count": { + "format": "decimalPattern" + } + } + }, + "focalLength": "{length} mm", + "@focalLength": { + "placeholders": { + "length": { + "type": "String", + "example": "5.4" + } + } + }, + "applyButtonLabel": "TƏTBİQ ET", + "@applyButtonLabel": {}, + "deleteButtonLabel": "SİL", + "@deleteButtonLabel": {}, + "nextButtonLabel": "NÖVBƏTİ", + "@nextButtonLabel": {}, + "showButtonLabel": "GÖSTƏR", + "@showButtonLabel": {}, + "hideButtonLabel": "GİZLƏT", + "@hideButtonLabel": {}, + "continueButtonLabel": "DAVAM ET", + "@continueButtonLabel": {}, + "saveCopyButtonLabel": "NÜSXƏNİ SAXLA", + "@saveCopyButtonLabel": {}, + "applyTooltip": "Tətbiq et", + "@applyTooltip": {}, + "cancelTooltip": "Ləğv et", + "@cancelTooltip": {}, + "changeTooltip": "Dəyişdir", + "@changeTooltip": {}, + "clearTooltip": "Təmizlə", + "@clearTooltip": {}, + "previousTooltip": "Əvvəlki", + "@previousTooltip": {}, + "nextTooltip": "Növbəti", + "@nextTooltip": {}, + "showTooltip": "Göstər", + "@showTooltip": {}, + "actionRemove": "Təmizlə", + "@actionRemove": {}, + "resetTooltip": "Sıfırla", + "@resetTooltip": {}, + "saveTooltip": "Saxla", + "@saveTooltip": {}, + "stopTooltip": "Dayandır", + "@stopTooltip": {}, + "pickTooltip": "Seçin", + "@pickTooltip": {}, + "doubleBackExitMessage": "Çıxmaq üçün təkrar “geri”-yə kliklə.", + "@doubleBackExitMessage": {}, + "doNotAskAgain": "Təkrar soruşma", + "@doNotAskAgain": {}, + "sourceStateLoading": "Yüklənilir", + "@sourceStateLoading": {}, + "sourceStateCataloguing": "Sənədləşdirmə", + "@sourceStateCataloguing": {}, + "sourceStateLocatingCountries": "Ölkələr yerləşdirilir", + "@sourceStateLocatingCountries": {}, + "sourceStateLocatingPlaces": "Yerlər müəyyənləşdirilir", + "@sourceStateLocatingPlaces": {}, + "chipActionDelete": "Sil", + "@chipActionDelete": {}, + "chipActionShowCollection": "Kolleksiyada Göstər", + "@chipActionShowCollection": {}, + "chipActionGoToPlacePage": "Yerlərdə Göstər", + "@chipActionGoToPlacePage": {}, + "appName": "Aves", + "@appName": {}, + "welcomeMessage": "Aves-ə Xoş Gəlmisiniz", + "@welcomeMessage": {} +} diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb index 55cff8978..f440f013c 100644 --- a/lib/l10n/app_de.arb +++ b/lib/l10n/app_de.arb @@ -971,7 +971,7 @@ "@settingsRemoveAnimationsDialogTitle": {}, "settingsTimeToTakeActionTile": "Zeit zum Reagieren", "@settingsTimeToTakeActionTile": {}, - "settingsDisplaySectionTitle": "Anzeige", + "settingsDisplaySectionTitle": "Darstellung", "@settingsDisplaySectionTitle": {}, "settingsThemeBrightnessTile": "Thema", "@settingsThemeBrightnessTile": {}, @@ -1378,5 +1378,17 @@ "explorerPageTitle": "Explorer", "@explorerPageTitle": {}, "mapAttributionOsmData": "Kartendaten © [OpenStreetMap](https://www.openstreetmap.org/copyright) Mitwirkende", - "@mapAttributionOsmData": {} + "@mapAttributionOsmData": {}, + "videoActionShowPreviousFrame": "Vorigen Frame zeigen", + "@videoActionShowPreviousFrame": {}, + "videoActionShowNextFrame": "Nächsten Frame zeigen", + "@videoActionShowNextFrame": {}, + "mapStyleOpenTopoMap": "OpenTopoMap", + "@mapStyleOpenTopoMap": {}, + "mapStyleOsmLiberty": "OSM Liberty", + "@mapStyleOsmLiberty": {}, + "mapAttributionOsmLiberty": "Kacheln von [OpenMapTiles](https://www.openmaptiles.org/), [CC BY](http://creativecommons.org/licenses/by/4.0) • Gehostet von [OSM Americana](https://tile.ourmap.us)", + "@mapAttributionOsmLiberty": {}, + "mapAttributionOpenTopoMap": "[SRTM](https://www.earthdata.nasa.gov/sensors/srtm) | Kacheln von [OpenTopoMap](https://opentopomap.org/), [CC BY-SA](https://creativecommons.org/licenses/by-sa/3.0/)", + "@mapAttributionOpenTopoMap": {} } diff --git a/lib/l10n/app_fa.arb b/lib/l10n/app_fa.arb index e3e097cf1..f31e3a765 100644 --- a/lib/l10n/app_fa.arb +++ b/lib/l10n/app_fa.arb @@ -234,7 +234,7 @@ "@unitSystemImperial": {}, "videoControlsPlayOutside": "باز کردن با برنامه‌ای دیگر", "@videoControlsPlayOutside": {}, - "videoLoopModeShortOnly": "فقط برای ویدئو های کوتاه", + "videoLoopModeShortOnly": "فقط برای ویدئوهای کوتاه", "@videoLoopModeShortOnly": {}, "entryActionEdit": "ویرایش", "@entryActionEdit": {}, @@ -278,17 +278,17 @@ "@exportEntryDialogHeight": {}, "aboutTranslatorsSectionTitle": "مترجم ها", "@aboutTranslatorsSectionTitle": {}, - "aboutLicensesAndroidLibrariesSectionTitle": "کتابخانه های اندروید", + "aboutLicensesAndroidLibrariesSectionTitle": "کتابخانه‌های اندروید", "@aboutLicensesAndroidLibrariesSectionTitle": {}, - "aboutLicensesFlutterPackagesSectionTitle": "بسته های Flutter", + "aboutLicensesFlutterPackagesSectionTitle": "بسته‌های Flutter", "@aboutLicensesFlutterPackagesSectionTitle": {}, "aboutBugReportButton": "گزارش", "@aboutBugReportButton": {}, - "aboutLicensesFlutterPluginsSectionTitle": "پلاگین های Flutter", + "aboutLicensesFlutterPluginsSectionTitle": "افزونه‌های Flutter", "@aboutLicensesFlutterPluginsSectionTitle": {}, "aboutBugCopyInfoButton": "کپی", "@aboutBugCopyInfoButton": {}, - "aboutLicensesDartPackagesSectionTitle": "بسته های Dart", + "aboutLicensesDartPackagesSectionTitle": "بسته‌های Dart", "@aboutLicensesDartPackagesSectionTitle": {}, "policyPageTitle": "سیاست حفظ حریم خصوصی", "@policyPageTitle": {}, @@ -393,7 +393,7 @@ "@keepScreenOnAlways": {}, "albumTierRegular": "سایر", "@albumTierRegular": {}, - "accessibilityAnimationsKeep": "نمایش از جلوه های نمایشگر", + "accessibilityAnimationsKeep": "نمایش از جلوه‌های نمایشگر", "@accessibilityAnimationsKeep": {}, "widgetDisplayedItemMostRecent": "جدید‌ترین", "@widgetDisplayedItemMostRecent": {}, @@ -545,7 +545,7 @@ "@albumTierSpecial": {}, "viewerTransitionParallax": "انطباق", "@viewerTransitionParallax": {}, - "coordinateFormatDecimal": "درجه های اعشاری", + "coordinateFormatDecimal": "درجه‌های اعشاری", "@coordinateFormatDecimal": {}, "videoResumeButtonLabel": "ادامه", "@videoResumeButtonLabel": {}, @@ -559,7 +559,7 @@ "@videoPlaybackSkip": {}, "setCoverDialogCustom": "شخصی", "@setCoverDialogCustom": {}, - "nameConflictDialogSingleSourceMessage": "برخی از پرونده های موجود در پوشه مقصد به همین نام هستند.", + "nameConflictDialogSingleSourceMessage": "برخی از پرونده‌های موجود در پوشه مقصد به همین نام هستند.", "@nameConflictDialogSingleSourceMessage": {}, "missingSystemFilePickerDialogMessage": "انتخابگر پرونده سامانه وجود ندارد یا غیرفعال است. لطفا آن را فعال کنید و دوباره امتحان کنید.", "@missingSystemFilePickerDialogMessage": {}, @@ -603,11 +603,11 @@ "@searchDateSectionTitle": {}, "searchCountriesSectionTitle": "کشور ها", "@searchCountriesSectionTitle": {}, - "settingsConfirmationDialogTitle": "درخواست های‌ تایید", + "settingsConfirmationDialogTitle": "درخواست‌های‌ تایید", "@settingsConfirmationDialogTitle": {}, - "settingsViewerQuickActionEditorDisplayedButtonsSectionTitle": "دکمه های نمایش داده شده", + "settingsViewerQuickActionEditorDisplayedButtonsSectionTitle": "دکمه‌های نمایش داده شده", "@settingsViewerQuickActionEditorDisplayedButtonsSectionTitle": {}, - "settingsViewerQuickActionEditorAvailableButtonsSectionTitle": "دکمه های در دسترس", + "settingsViewerQuickActionEditorAvailableButtonsSectionTitle": "دکمه‌های در دسترس", "@settingsViewerQuickActionEditorAvailableButtonsSectionTitle": {}, "settingsViewerQuickActionEmpty": "بدون دکمه", "@settingsViewerQuickActionEmpty": {}, @@ -664,7 +664,7 @@ "@editEntryLocationDialogLongitude": {}, "viewerOpenPanoramaButtonLabel": "بازکردن پانوراما", "@viewerOpenPanoramaButtonLabel": {}, - "statsTopAlbumsSectionTitle": "آلبوم های ممتاز", + "statsTopAlbumsSectionTitle": "آلبوم‌های ممتاز", "@statsTopAlbumsSectionTitle": {}, "settingsSubtitleThemeTextColor": "رنگ متن", "@settingsSubtitleThemeTextColor": {}, @@ -672,7 +672,7 @@ "@mapStyleTooltip": {}, "viewerInfoSearchFieldLabel": "جستجو فراداده", "@viewerInfoSearchFieldLabel": {}, - "filePickerDoNotShowHiddenFiles": "پرونده های پنهان را نمایش نده", + "filePickerDoNotShowHiddenFiles": "پرونده‌های پنهان را نمایش نده", "@filePickerDoNotShowHiddenFiles": {}, "filePickerUseThisFolder": "استفاده از این پوشه", "@filePickerUseThisFolder": {}, @@ -696,7 +696,7 @@ "@sourceViewerPageTitle": {}, "panoramaDisableSensorControl": "خاموش کردن هدایت حسگر", "@panoramaDisableSensorControl": {}, - "filePickerShowHiddenFiles": "نمایش پرونده های پنهان", + "filePickerShowHiddenFiles": "نمایش پرونده‌های پنهان", "@filePickerShowHiddenFiles": {}, "setCoverDialogLatest": "آخرین مورد", "@setCoverDialogLatest": {}, @@ -794,9 +794,9 @@ "@settingsCollectionBrowsingQuickActionEditorBanner": {}, "settingsCoordinateFormatDialogTitle": "قالب مختصات‌", "@settingsCoordinateFormatDialogTitle": {}, - "statsTopStatesSectionTitle": "آمار های ممتاز", + "statsTopStatesSectionTitle": "آمارهای ممتاز", "@statsTopStatesSectionTitle": {}, - "statsTopTagsSectionTitle": "برچسب های ممتاز", + "statsTopTagsSectionTitle": "برچسب‌های ممتاز", "@statsTopTagsSectionTitle": {}, "coordinateFormatDms": "DMS", "@coordinateFormatDms": {}, @@ -824,7 +824,7 @@ "@sortByItemCount": {}, "settingsKeepScreenOnTile": "صفحه را روشن نگه دار", "@settingsKeepScreenOnTile": {}, - "settingsViewerGestureSideTapNext": "روی لبه های صفحه ضربه بزنید تا مورد قبلی/بعدی نشان داده شود", + "settingsViewerGestureSideTapNext": "روی لبه‌های صفحه ضربه بزنید تا مورد قبلی/بعدی نشان داده شود", "@settingsViewerGestureSideTapNext": {}, "deleteMultiAlbumConfirmationDialogMessage": "{count, plural, =1{این آلبوم ها و مورد موجود در آنها پاک شود؟} other{این آلبوم ها و {count} مورد موجود در آنها پاک شود؟}}", "@deleteMultiAlbumConfirmationDialogMessage": { @@ -834,7 +834,7 @@ }, "removeEntryMetadataMotionPhotoXmpWarningDialogMessage": "XMP برای پخش ویدیو در داخل یک عکس متحرک مورد نیاز است.\n\nار پاک‌سازی آن اطمینان دارید?", "@removeEntryMetadataMotionPhotoXmpWarningDialogMessage": {}, - "newVaultWarningDialogMessage": "موارد موجود در گاوصندوق تنها برای این برنامه در دسترس هستند و در هیچ برنامه دیگری وجود ندارد.\n\nاگر این برنامه را پاک کنید، یا داده های برنامه را پاک کنید، همه این موارد را از دست خواهید داد.", + "newVaultWarningDialogMessage": "موارد موجود در گاوصندوق تنها برای این برنامه در دسترس هستند و در هیچ برنامه دیگری وجود ندارد.\n\nاگر این برنامه را پاک کنید، یا داده‌های برنامه را پاک کنید، همه این موارد را از دست خواهید داد.", "@newVaultWarningDialogMessage": {}, "deleteEntriesConfirmationDialogMessage": "{count, plural, =1{این مورد پاک شود؟} other{این {count} مورد پاک شوند؟}}", "@deleteEntriesConfirmationDialogMessage": { @@ -905,7 +905,7 @@ "@sortOrderOldestFirst": {}, "settingsSlideshowFillScreen": "پر کردن صفحه", "@settingsSlideshowFillScreen": {}, - "settingsAccessibilityShowPinchGestureAlternatives": "نمایش جایگزین های چند لمس همزمان", + "settingsAccessibilityShowPinchGestureAlternatives": "نمایش جایگزین‌های چند لمس همزمان", "@settingsAccessibilityShowPinchGestureAlternatives": {}, "viewerInfoLabelDate": "تاریخ", "@viewerInfoLabelDate": {}, @@ -937,9 +937,9 @@ "@settingsHomeTile": {}, "settingsSlideshowAnimatedZoomEffect": "جلوه بزرگنمایی پویانمایی شده", "@settingsSlideshowAnimatedZoomEffect": {}, - "statsTopCountriesSectionTitle": "کشور های ممتاز", + "statsTopCountriesSectionTitle": "کشور‌های ممتاز", "@statsTopCountriesSectionTitle": {}, - "statsTopPlacesSectionTitle": "مکان های ممتاز", + "statsTopPlacesSectionTitle": "مکان‌های ممتاز", "@statsTopPlacesSectionTitle": {}, "editEntryDateDialogTitle": "تاریخ و زمان", "@editEntryDateDialogTitle": {}, @@ -1001,7 +1001,7 @@ "@appPickDialogNone": {}, "aboutLinkLicense": "مجوز", "@aboutLinkLicense": {}, - "aboutBugSaveLogInstruction": "ذخیره گزارش های برنامه در یک پرونده", + "aboutBugSaveLogInstruction": "ذخیره گزارش‌های برنامه در یک پرونده", "@aboutBugSaveLogInstruction": {}, "aboutDataUsageDatabase": "پایگاه داده", "@aboutDataUsageDatabase": {}, @@ -1019,7 +1019,7 @@ "@aboutDataUsageClearCache": {}, "aboutCreditsWorldAtlas2": "زیر مجوز ISC.", "@aboutCreditsWorldAtlas2": {}, - "aboutLicensesBanner": "این برنامه از بسته ها و کتابخانه های منبع باز زیر استفاده می کند.", + "aboutLicensesBanner": "این برنامه از بسته‌ها و کتابخانه‌های منبع باز زیر استفاده می کند.", "@aboutLicensesBanner": {}, "collectionSelectPageTitle": "انتخاب موارد", "@collectionSelectPageTitle": {}, @@ -1071,9 +1071,9 @@ "@albumGroupType": {}, "albumPickPageTitlePick": "انتخاب آلبوم", "@albumPickPageTitlePick": {}, - "albumScreenRecordings": "ضبط های از صفحه", + "albumScreenRecordings": "ضبط‌های از صفحه", "@albumScreenRecordings": {}, - "albumVideoCaptures": "ویدیو های ضبط شده", + "albumVideoCaptures": "ویدیو‌های ضبط شده", "@albumVideoCaptures": {}, "albumEmpty": "بدون آلبوم", "@albumEmpty": {}, @@ -1091,21 +1091,21 @@ "@settingsActionImport": {}, "settingsSystemDefault": "پیشفرض سامانه", "@settingsSystemDefault": {}, - "settingsConfirmationTile": "درخواست های تایید", + "settingsConfirmationTile": "درخواست‌های تایید", "@settingsConfirmationTile": {}, "settingsKeepScreenOnDialogTitle": "صفحه را روشن نگه دار", "@settingsKeepScreenOnDialogTitle": {}, - "settingsShowBottomNavigationBar": "نمایش گزینه‌گان پیمایش پایین", + "settingsShowBottomNavigationBar": "نمایش گزینه‌های پیمایش پایین", "@settingsShowBottomNavigationBar": {}, "settingsDoubleBackExit": "برای خروج دوبار روی «بازگشت» ضربه بزنید", "@settingsDoubleBackExit": {}, - "settingsNavigationDrawerEditorPageTitle": "گزینه‌گان پیمایش", + "settingsNavigationDrawerEditorPageTitle": "گزینه‌های پیمایش", "@settingsNavigationDrawerEditorPageTitle": {}, "settingsConfirmationBeforeMoveUndatedItems": "پیش از جابجایی موارد بدون تاریخ بپرسید", "@settingsConfirmationBeforeMoveUndatedItems": {}, "settingsNavigationDrawerBanner": "برای جابجایی و مرتب کردن مجدد موارد، لمس کنید و نگه دارید.", "@settingsNavigationDrawerBanner": {}, - "settingsConfirmationVaultDataLoss": "نمایش هشدار از دست دادن داده های گاوصندوق", + "settingsConfirmationVaultDataLoss": "نمایش هشدار از دست دادن داده‌های گاوصندوق", "@settingsConfirmationVaultDataLoss": {}, "settingsNavigationDrawerTabAlbums": "آلبوم ها", "@settingsNavigationDrawerTabAlbums": {}, @@ -1117,7 +1117,7 @@ "@settingsThumbnailShowHdrIcon": {}, "settingsCollectionQuickActionTabBrowsing": "مرور کردن", "@settingsCollectionQuickActionTabBrowsing": {}, - "settingsCollectionQuickActionEditorPageTitle": "کنش های سریع", + "settingsCollectionQuickActionEditorPageTitle": "کنش‌های سریع", "@settingsCollectionQuickActionEditorPageTitle": {}, "settingsCollectionQuickActionTabSelecting": "انتخاب کردن", "@settingsCollectionQuickActionTabSelecting": {}, @@ -1153,7 +1153,7 @@ "@settingsVideoBackgroundModeDialogTitle": {}, "settingsVideoGestureDoubleTapTogglePlay": "برای پخش/ایست دوبار ضربه زدن", "@settingsVideoGestureDoubleTapTogglePlay": {}, - "settingsVideoGestureSideDoubleTapSeek": "روی لبه های صفحه دوبار ضربه بزنید تا به عقب/جلو بروید", + "settingsVideoGestureSideDoubleTapSeek": "روی لبه‌های صفحه دوبار ضربه بزنید تا به عقب/جلو بروید", "@settingsVideoGestureSideDoubleTapSeek": {}, "settingsSubtitleThemePageTitle": "زیرنویس ها", "@settingsSubtitleThemePageTitle": {}, @@ -1179,7 +1179,7 @@ "@settingsAllowErrorReporting": {}, "settingsThemeColorHighlights": "رنگ متون برجسته", "@settingsThemeColorHighlights": {}, - "settingsThemeEnableDynamicColor": "رنگ های پویا", + "settingsThemeEnableDynamicColor": "رنگ‌های پویا", "@settingsThemeEnableDynamicColor": {}, "settingsHiddenFiltersEmpty": "پالایشی پنهان نیست", "@settingsHiddenFiltersEmpty": {}, @@ -1271,15 +1271,15 @@ "@settingsNavigationSectionTitle": {}, "settingsNavigationDrawerTabTypes": "انواع", "@settingsNavigationDrawerTabTypes": {}, - "settingsNavigationDrawerTile": "گزینه‌گان پیمایش", + "settingsNavigationDrawerTile": "گزینه‌های پیمایش", "@settingsNavigationDrawerTile": {}, "settingsSearchEmpty": "تنظیمی منطبق نشد", "@settingsSearchEmpty": {}, - "settingsCollectionBurstPatternsTile": "الگوهای انفجاری", + "settingsCollectionBurstPatternsTile": "الگوهای تصاویر چندتایی", "@settingsCollectionBurstPatternsTile": {}, "settingsCollectionBurstPatternsNone": "هیچکدام", "@settingsCollectionBurstPatternsNone": {}, - "settingsCollectionQuickActionsTile": "کنش های سریع", + "settingsCollectionQuickActionsTile": "کنش‌های سریع", "@settingsCollectionQuickActionsTile": {}, "settingsUnitSystemTile": "واحد ها", "@settingsUnitSystemTile": {}, @@ -1301,9 +1301,9 @@ "@settingsViewerSectionTitle": {}, "settingsViewerShowInformationSubtitle": "نمایش عنوان، تاریخ، مکان، و...", "@settingsViewerShowInformationSubtitle": {}, - "settingsViewerQuickActionsTile": "کنش های سریع", + "settingsViewerQuickActionsTile": "کنش‌های سریع", "@settingsViewerQuickActionsTile": {}, - "settingsViewerQuickActionEditorPageTitle": "کنش های سریع", + "settingsViewerQuickActionEditorPageTitle": "کنش‌های سریع", "@settingsViewerQuickActionEditorPageTitle": {}, "settingsViewerQuickActionEditorBanner": "لمس کنید و نگه دارید تا دکمه ها را حرکت دهید و انتخاب کنید که کدام کنش ها در بیننده نمایش داده می شود.", "@settingsViewerQuickActionEditorBanner": {}, @@ -1339,19 +1339,19 @@ "@searchRatingSectionTitle": {}, "searchMetadataSectionTitle": "فراداده", "@searchMetadataSectionTitle": {}, - "settingsConfirmationBeforeDeleteItems": "همیشه پیش از پاک‌سازی موارد پرسش کن", + "settingsConfirmationBeforeDeleteItems": "همیشه پیش از پاک‌سازی موارد بپرس", "@settingsConfirmationBeforeDeleteItems": {}, "genericSuccessFeedback": "انجام شد!", "@genericSuccessFeedback": {}, "aboutLicensesShowAllButtonLabel": "نمایش تمام مجوز ها", "@aboutLicensesShowAllButtonLabel": {}, - "drawerCollectionSphericalVideos": "ویدیو های 360°", + "drawerCollectionSphericalVideos": "ویدیو‌های 360°", "@drawerCollectionSphericalVideos": {}, "searchAlbumsSectionTitle": "آلبوم ها", "@searchAlbumsSectionTitle": {}, "tagPageTitle": "برچسب ها", "@tagPageTitle": {}, - "settingsEnableBin": "بهره‌وری از سطل زباله", + "settingsEnableBin": "به‌کارگیری سطل زباله", "@settingsEnableBin": {}, "settingsEnableBinSubtitle": "موارد پاک شده را به مدت 30 روز نگه دارید", "@settingsEnableBinSubtitle": {}, @@ -1445,9 +1445,9 @@ }, "settingsDisablingBinWarningDialogMessage": "موارد موجود در سطل زباله برای همیشه نابود خواهند شد.", "@settingsDisablingBinWarningDialogMessage": {}, - "settingsAllowInstalledAppAccessSubtitle": "برای بهبود نمایش آلبوم بهره‌وری میشود", + "settingsAllowInstalledAppAccessSubtitle": "برای بهبود نمایش آلبوم به‌کارگرفته میشود", "@settingsAllowInstalledAppAccessSubtitle": {}, - "settingsStorageAccessBanner": "برخی پوشه ها برای اصلاح پرونپه های موجود در آنها به یک مجوز دسترسی نیاز دارند. در اینجا می توانید پوشه هایی را که قبلاً به آنها دسترسی داشته اید، مرور کنید.", + "settingsStorageAccessBanner": "برخی پوشه ها برای اصلاح پرونده‌های موجود در آنها به یک مجوز دسترسی نیاز دارند. در اینجا می توانید پوشه هایی را که قبلاً به آنها دسترسی داشته اید، مرور کنید.", "@settingsStorageAccessBanner": {}, "collectionMoveFailureFeedback": "{count, plural, =1{هدایت ۱ مورد ناموفق بود} other{هدایت {count} مورد ناموفق بود}}", "@collectionMoveFailureFeedback": { diff --git a/lib/l10n/app_sk.arb b/lib/l10n/app_sk.arb index 1aa743de2..b31d388d4 100644 --- a/lib/l10n/app_sk.arb +++ b/lib/l10n/app_sk.arb @@ -1544,5 +1544,9 @@ "mapStyleOsmLiberty": "OSM Slobody", "@mapStyleOsmLiberty": {}, "mapAttributionOsmLiberty": "Dlaždice podľa [OpenMapTiles](https://www.openmaptiles.org/), [CC BY](http://creativecommons.org/licenses/by/4.0) • Hostovaný [OSM Americana](https://tile.ourmap.us)", - "@mapAttributionOsmLiberty": {} + "@mapAttributionOsmLiberty": {}, + "videoActionShowPreviousFrame": "Zobraziť predchádzajúci rám", + "@videoActionShowPreviousFrame": {}, + "videoActionShowNextFrame": "Zobraziť ďalší rám", + "@videoActionShowNextFrame": {} } From a65c0fe3b163bc8e812775a86acbdc050f61049a Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Fri, 8 Nov 2024 19:30:50 +0100 Subject: [PATCH 04/22] #1279 changed Shavian resource tag to prevent bug on Android <7 --- .../res/{values-b+en+Shaw => values-b+zxx+Shaw}/strings.xml | 0 lib/model/app/contributors.dart | 2 ++ lib/widgets/aves_app.dart | 1 + 3 files changed, 3 insertions(+) rename android/app/src/main/res/{values-b+en+Shaw => values-b+zxx+Shaw}/strings.xml (100%) diff --git a/android/app/src/main/res/values-b+en+Shaw/strings.xml b/android/app/src/main/res/values-b+zxx+Shaw/strings.xml similarity index 100% rename from android/app/src/main/res/values-b+en+Shaw/strings.xml rename to android/app/src/main/res/values-b+zxx+Shaw/strings.xml diff --git a/lib/model/app/contributors.dart b/lib/model/app/contributors.dart index 191d22cbf..db0b70d97 100644 --- a/lib/model/app/contributors.dart +++ b/lib/model/app/contributors.dart @@ -110,6 +110,8 @@ class Contributors { Contributor('Your Average Code', 'neumeiersi91358@th-nuernberg.de'), Contributor('Paranoid Android', 'f.cherdzhiev@innopolis.university'), Contributor('Noah Kenzie Rodriguez-Beus', 'noahbeus@protonmail.com'), + Contributor('5FeetUnder', '15950507+5FeetUnder@users.noreply.github.com'), + // Contributor('Femini', 'nizamismidov4@gmail.com'), // Azerbaijani // Contributor('Alvi Khan', 'aveenalvi@gmail.com'), // Bengali // Contributor('Htet Oo Hlaing', 'htetoh2006@outlook.com'), // Burmese // Contributor('Khant', 'khant@users.noreply.hosted.weblate.org'), // Burmese diff --git a/lib/widgets/aves_app.dart b/lib/widgets/aves_app.dart index 3b15aab04..8ed6e7d09 100644 --- a/lib/widgets/aves_app.dart +++ b/lib/widgets/aves_app.dart @@ -64,6 +64,7 @@ class AvesApp extends StatefulWidget { // temporary exclude locales not ready yet for prime time // `ckb`: add `flutter_ckb_localization` and necessary app localization delegates when ready static final _unsupportedLocales = { + 'az', // Azerbaijani 'bn', // Bengali 'ckb', // Kurdish (Central) 'da', // Danish From e071ff299aee0d7d37705682061ff5d57b8c5f70 Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Fri, 8 Nov 2024 19:38:17 +0100 Subject: [PATCH 05/22] #1253 changed fastlane tag for Shavian as workaround for f-droid broken resolution --- .../{en-Shaw => en-US-Shaw}/full_description.txt | 0 .../images/featureGraphic.png | Bin .../images/phoneScreenshots/1.png | Bin .../images/phoneScreenshots/2.png | Bin .../images/phoneScreenshots/3.png | Bin .../images/phoneScreenshots/4.png | Bin .../images/phoneScreenshots/5.png | Bin .../images/phoneScreenshots/6.png | Bin .../images/phoneScreenshots/7.png | Bin .../{en-Shaw => en-US-Shaw}/short_description.txt | 0 10 files changed, 0 insertions(+), 0 deletions(-) rename fastlane/metadata/android/{en-Shaw => en-US-Shaw}/full_description.txt (100%) rename fastlane/metadata/android/{en-Shaw => en-US-Shaw}/images/featureGraphic.png (100%) rename fastlane/metadata/android/{en-Shaw => en-US-Shaw}/images/phoneScreenshots/1.png (100%) rename fastlane/metadata/android/{en-Shaw => en-US-Shaw}/images/phoneScreenshots/2.png (100%) rename fastlane/metadata/android/{en-Shaw => en-US-Shaw}/images/phoneScreenshots/3.png (100%) rename fastlane/metadata/android/{en-Shaw => en-US-Shaw}/images/phoneScreenshots/4.png (100%) rename fastlane/metadata/android/{en-Shaw => en-US-Shaw}/images/phoneScreenshots/5.png (100%) rename fastlane/metadata/android/{en-Shaw => en-US-Shaw}/images/phoneScreenshots/6.png (100%) rename fastlane/metadata/android/{en-Shaw => en-US-Shaw}/images/phoneScreenshots/7.png (100%) rename fastlane/metadata/android/{en-Shaw => en-US-Shaw}/short_description.txt (100%) diff --git a/fastlane/metadata/android/en-Shaw/full_description.txt b/fastlane/metadata/android/en-US-Shaw/full_description.txt similarity index 100% rename from fastlane/metadata/android/en-Shaw/full_description.txt rename to fastlane/metadata/android/en-US-Shaw/full_description.txt diff --git a/fastlane/metadata/android/en-Shaw/images/featureGraphic.png b/fastlane/metadata/android/en-US-Shaw/images/featureGraphic.png similarity index 100% rename from fastlane/metadata/android/en-Shaw/images/featureGraphic.png rename to fastlane/metadata/android/en-US-Shaw/images/featureGraphic.png diff --git a/fastlane/metadata/android/en-Shaw/images/phoneScreenshots/1.png b/fastlane/metadata/android/en-US-Shaw/images/phoneScreenshots/1.png similarity index 100% rename from fastlane/metadata/android/en-Shaw/images/phoneScreenshots/1.png rename to fastlane/metadata/android/en-US-Shaw/images/phoneScreenshots/1.png diff --git a/fastlane/metadata/android/en-Shaw/images/phoneScreenshots/2.png b/fastlane/metadata/android/en-US-Shaw/images/phoneScreenshots/2.png similarity index 100% rename from fastlane/metadata/android/en-Shaw/images/phoneScreenshots/2.png rename to fastlane/metadata/android/en-US-Shaw/images/phoneScreenshots/2.png diff --git a/fastlane/metadata/android/en-Shaw/images/phoneScreenshots/3.png b/fastlane/metadata/android/en-US-Shaw/images/phoneScreenshots/3.png similarity index 100% rename from fastlane/metadata/android/en-Shaw/images/phoneScreenshots/3.png rename to fastlane/metadata/android/en-US-Shaw/images/phoneScreenshots/3.png diff --git a/fastlane/metadata/android/en-Shaw/images/phoneScreenshots/4.png b/fastlane/metadata/android/en-US-Shaw/images/phoneScreenshots/4.png similarity index 100% rename from fastlane/metadata/android/en-Shaw/images/phoneScreenshots/4.png rename to fastlane/metadata/android/en-US-Shaw/images/phoneScreenshots/4.png diff --git a/fastlane/metadata/android/en-Shaw/images/phoneScreenshots/5.png b/fastlane/metadata/android/en-US-Shaw/images/phoneScreenshots/5.png similarity index 100% rename from fastlane/metadata/android/en-Shaw/images/phoneScreenshots/5.png rename to fastlane/metadata/android/en-US-Shaw/images/phoneScreenshots/5.png diff --git a/fastlane/metadata/android/en-Shaw/images/phoneScreenshots/6.png b/fastlane/metadata/android/en-US-Shaw/images/phoneScreenshots/6.png similarity index 100% rename from fastlane/metadata/android/en-Shaw/images/phoneScreenshots/6.png rename to fastlane/metadata/android/en-US-Shaw/images/phoneScreenshots/6.png diff --git a/fastlane/metadata/android/en-Shaw/images/phoneScreenshots/7.png b/fastlane/metadata/android/en-US-Shaw/images/phoneScreenshots/7.png similarity index 100% rename from fastlane/metadata/android/en-Shaw/images/phoneScreenshots/7.png rename to fastlane/metadata/android/en-US-Shaw/images/phoneScreenshots/7.png diff --git a/fastlane/metadata/android/en-Shaw/short_description.txt b/fastlane/metadata/android/en-US-Shaw/short_description.txt similarity index 100% rename from fastlane/metadata/android/en-Shaw/short_description.txt rename to fastlane/metadata/android/en-US-Shaw/short_description.txt From 339a039dd67d3261f368c6336a5233608ab7902b Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Fri, 8 Nov 2024 23:29:51 +0100 Subject: [PATCH 06/22] #1272 albums: improved album creation feedback --- lib/l10n/app_en.arb | 1 + lib/model/source/album.dart | 6 +- lib/model/source/media_store_source.dart | 2 +- lib/utils/android_file_utils.dart | 16 +++- lib/widgets/collection/app_bar.dart | 2 +- .../collection/entry_set_action_delegate.dart | 2 +- .../filter_editors/create_album_dialog.dart | 91 +++++++++++-------- .../dialogs/pick_dialogs/album_pick_page.dart | 4 +- .../dialogs/selection_dialogs/common.dart | 2 +- .../common/action_delegates/album_set.dart | 71 +++++++++------ .../common/action_delegates/chip_set.dart | 2 +- .../settings/language/locale_tile.dart | 2 +- .../viewer/action/entry_action_delegate.dart | 2 +- 13 files changed, 121 insertions(+), 82 deletions(-) diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 95df01843..781a00af8 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -423,6 +423,7 @@ "newAlbumDialogTitle": "New Album", "newAlbumDialogNameLabel": "Album name", + "newAlbumDialogAlbumAlreadyExistsHelper": "Album already exists", "newAlbumDialogNameLabelAlreadyExistsHelper": "Directory already exists", "newAlbumDialogStorageLabel": "Storage:", diff --git a/lib/model/source/album.dart b/lib/model/source/album.dart index 859d4ad5c..b30b693d8 100644 --- a/lib/model/source/album.dart +++ b/lib/model/source/album.dart @@ -147,8 +147,10 @@ mixin AlbumMixin on SourceBase { // new albums void createAlbum(String directory) { - _newAlbums.add(directory); - addDirectories(albums: {directory}); + if (!_directories.contains(directory)) { + _newAlbums.add(directory); + addDirectories(albums: {directory}); + } } void renameNewAlbum(String source, String destination) { diff --git a/lib/model/source/media_store_source.dart b/lib/model/source/media_store_source.dart index 88acbcaed..c2a85e28f 100644 --- a/lib/model/source/media_store_source.dart +++ b/lib/model/source/media_store_source.dart @@ -63,7 +63,7 @@ class MediaStoreSource extends CollectionSource { if (currentTimeZoneOffset != null) { final catalogTimeZoneOffset = settings.catalogTimeZoneRawOffsetMillis; if (currentTimeZoneOffset != catalogTimeZoneOffset) { - unawaited(reportService.log('Time zone offset change: $currentTimeZoneOffset -> $catalogTimeZoneOffset. Clear catalog metadata to get correct date/times.')); + unawaited(reportService.recordError('Time zone offset change: $currentTimeZoneOffset -> $catalogTimeZoneOffset. Clear catalog metadata to get correct date/times.', null)); await localMediaDb.clearDates(); await localMediaDb.clearCatalogMetadata(); settings.catalogTimeZoneRawOffsetMillis = currentTimeZoneOffset; diff --git a/lib/utils/android_file_utils.dart b/lib/utils/android_file_utils.dart index 12b277132..637fbbbf8 100644 --- a/lib/utils/android_file_utils.dart +++ b/lib/utils/android_file_utils.dart @@ -19,6 +19,11 @@ class AndroidFileUtils { // cf https://developer.android.com/reference/android/provider/MediaStore#VOLUME_EXTERNAL static const externalVolume = 'external'; + static const standardDirDcim = 'DCIM'; + static const standardDirDownloads = 'Download'; + static const standardDirMovies = 'Movies'; + static const standardDirPictures = 'Pictures'; + static const mediaStoreUriRoot = '$contentScheme://$mediaStoreAuthority/'; static const mediaUriPathRoots = {'/$externalVolume/images/', '/$externalVolume/video/'}; @@ -43,12 +48,13 @@ class AndroidFileUtils { await _initStorageVolumes(); vaultRoot = await storageService.getVaultRoot(); primaryStorage = storageVolumes.firstWhereOrNull((volume) => volume.isPrimary)?.path ?? separator; - // standard - dcimPath = pContext.join(primaryStorage, 'DCIM'); + // standard dirs + dcimPath = pContext.join(primaryStorage, standardDirDcim); // effective download path may have a different case - downloadPath = pContext.join(primaryStorage, 'Download').toLowerCase(); - moviesPath = pContext.join(primaryStorage, 'Movies'); - picturesPath = pContext.join(primaryStorage, 'Pictures'); + downloadPath = pContext.join(primaryStorage, standardDirDownloads).toLowerCase(); + moviesPath = pContext.join(primaryStorage, standardDirMovies); + picturesPath = pContext.join(primaryStorage, standardDirPictures); + // custom dirs avesVideoCapturesPath = pContext.join(dcimPath, 'Video Captures'); videoCapturesPaths = { // from Samsung diff --git a/lib/widgets/collection/app_bar.dart b/lib/widgets/collection/app_bar.dart index 388ac7b7a..aae93bac0 100644 --- a/lib/widgets/collection/app_bar.dart +++ b/lib/widgets/collection/app_bar.dart @@ -689,7 +689,7 @@ class _CollectionAppBarState extends State with SingleTickerPr }, routeSettings: const RouteSettings(name: TileViewDialog.routeName), ); - // wait for the dialog to hide as applying the change may block the UI + // wait for the dialog to hide await Future.delayed(ADurations.dialogTransitionLoose * timeDilation); if (value != null && initialValue != value) { settings.collectionSortFactor = value.$1!; diff --git a/lib/widgets/collection/entry_set_action_delegate.dart b/lib/widgets/collection/entry_set_action_delegate.dart index 72fe2cf4a..fd9956bc4 100644 --- a/lib/widgets/collection/entry_set_action_delegate.dart +++ b/lib/widgets/collection/entry_set_action_delegate.dart @@ -512,7 +512,7 @@ class EntrySetActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAware ); if (confirmed == null || !confirmed) return null; - // wait for the dialog to hide as applying the change may block the UI + // wait for the dialog to hide await Future.delayed(ADurations.dialogTransitionLoose * timeDilation); return supported; } diff --git a/lib/widgets/dialogs/filter_editors/create_album_dialog.dart b/lib/widgets/dialogs/filter_editors/create_album_dialog.dart index 9af1c8ef5..af47176c0 100644 --- a/lib/widgets/dialogs/filter_editors/create_album_dialog.dart +++ b/lib/widgets/dialogs/filter_editors/create_album_dialog.dart @@ -1,5 +1,6 @@ import 'dart:io'; +import 'package:aves/model/source/collection_source.dart'; import 'package:aves/services/common/services.dart'; import 'package:aves/theme/durations.dart'; import 'package:aves/utils/android_file_utils.dart'; @@ -9,6 +10,7 @@ import 'package:aves/widgets/dialogs/aves_dialog.dart'; import 'package:aves_model/aves_model.dart'; import 'package:collection/collection.dart'; import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; class CreateAlbumDialog extends StatefulWidget { static const routeName = '/dialog/create_album'; @@ -23,7 +25,8 @@ class _CreateAlbumDialogState extends State { final ScrollController _scrollController = ScrollController(); final TextEditingController _nameController = TextEditingController(); final FocusNode _nameFieldFocusNode = FocusNode(); - final ValueNotifier _existsNotifier = ValueNotifier(false); + final ValueNotifier _directoryExistsNotifier = ValueNotifier(false); + final ValueNotifier _albumExistsNotifier = ValueNotifier(false); final ValueNotifier _isValidNotifier = ValueNotifier(false); late Set _allVolumes; late StorageVolume? _primaryVolume, _selectedVolume; @@ -43,13 +46,14 @@ class _CreateAlbumDialogState extends State { _nameController.dispose(); _nameFieldFocusNode.removeListener(_onFocus); _nameFieldFocusNode.dispose(); - _existsNotifier.dispose(); + _directoryExistsNotifier.dispose(); _isValidNotifier.dispose(); super.dispose(); } @override Widget build(BuildContext context) { + final l10n = context.l10n; const contentHorizontalPadding = EdgeInsets.symmetric(horizontal: AvesDialog.defaultHorizontalContentPadding); final volumeTiles = []; @@ -61,7 +65,7 @@ class _CreateAlbumDialogState extends State { volumeTiles.addAll([ Padding( padding: contentHorizontalPadding + const EdgeInsets.only(top: 20), - child: Text(context.l10n.newAlbumDialogStorageLabel), + child: Text(l10n.newAlbumDialogStorageLabel), ), ...primaryVolumes.map((volume) => _buildVolumeTile(context, volume)), ...otherVolumes.map((volume) => _buildVolumeTile(context, volume)), @@ -70,21 +74,27 @@ class _CreateAlbumDialogState extends State { } return AvesDialog( - title: context.l10n.newAlbumDialogTitle, + title: l10n.newAlbumDialogTitle, scrollController: _scrollController, scrollableContent: [ ...volumeTiles, Padding( padding: contentHorizontalPadding + const EdgeInsets.only(bottom: 8), - child: ValueListenableBuilder( - valueListenable: _existsNotifier, - builder: (context, exists, child) { + child: AnimatedBuilder( + animation: Listenable.merge([_albumExistsNotifier, _directoryExistsNotifier]), + builder: (context, child) { + var helperText = ''; + if (_albumExistsNotifier.value) { + helperText = l10n.newAlbumDialogAlbumAlreadyExistsHelper; + } else if (_directoryExistsNotifier.value) { + helperText = l10n.newAlbumDialogNameLabelAlreadyExistsHelper; + } return TextField( controller: _nameController, focusNode: _nameFieldFocusNode, decoration: InputDecoration( - labelText: context.l10n.newAlbumDialogNameLabel, - helperText: exists ? context.l10n.newAlbumDialogNameLabelAlreadyExistsHelper : '', + labelText: l10n.newAlbumDialogNameLabel, + helperText: helperText, ), autofocus: _allVolumes.length == 1, onChanged: (_) => _validate(), @@ -96,11 +106,16 @@ class _CreateAlbumDialogState extends State { actions: [ const CancelButton(), ValueListenableBuilder( - valueListenable: _isValidNotifier, - builder: (context, isValid, child) { - return TextButton( - onPressed: isValid ? () => _submit(context) : null, - child: Text(context.l10n.createAlbumButtonLabel), + valueListenable: _albumExistsNotifier, + builder: (context, albumExists, child) { + return ValueListenableBuilder( + valueListenable: _isValidNotifier, + builder: (context, isValid, child) { + return TextButton( + onPressed: isValid ? () => _submit(context) : null, + child: Text(albumExists ? l10n.showButtonLabel : l10n.createAlbumButtonLabel), + ); + }, ); }, ), @@ -147,34 +162,18 @@ class _CreateAlbumDialogState extends State { ); } - String _sanitize(String input) => input.trim(); + Future _buildAlbumPath() async { + final name = _nameController.text.trim(); + if (name.isEmpty) return null; - String? _buildAlbumPath(String name) { - final selectedVolume = _selectedVolume; - if (selectedVolume == null || name.isEmpty) return null; - return pContext.join(selectedVolume.path, 'Pictures', name); - } - - Future _validate() async { - final newName = _sanitize(_nameController.text); - final path = _buildAlbumPath(newName); - // this check ignores case - final exists = path != null && await Directory(path).exists(); - _existsNotifier.value = exists; - _isValidNotifier.value = path != null && newName.isNotEmpty; - } - - Future _submit(BuildContext context) async { - if (!_isValidNotifier.value) return; - - final newName = _sanitize(_nameController.text); - final albumPath = _buildAlbumPath(newName); final volumePath = _selectedVolume?.path; - if (albumPath == null || volumePath == null) return; + if (volumePath == null) return null; + + final candidatePath = pContext.join(volumePath, AndroidFileUtils.standardDirPictures, name); // uses resolved directory name case if it exists var resolvedPath = volumePath; - final relativePathSegments = pContext.split(pContext.relative(albumPath, from: volumePath)); + final relativePathSegments = pContext.split(pContext.relative(candidatePath, from: volumePath)); for (final targetSegment in relativePathSegments) { String? resolvedSegment; final directory = Directory(resolvedPath); @@ -184,6 +183,22 @@ class _CreateAlbumDialogState extends State { } resolvedPath = pContext.join(resolvedPath, resolvedSegment ?? targetSegment); } - Navigator.maybeOf(context)?.pop(resolvedPath); + + return resolvedPath; + } + + Future _validate() async { + final path = await _buildAlbumPath(); + final isValid = path != null; + _isValidNotifier.value = isValid; + _directoryExistsNotifier.value = isValid && await Directory(path).exists(); + _albumExistsNotifier.value = isValid && context.read().rawAlbums.contains(path); + } + + Future _submit(BuildContext context) async { + final path = await _buildAlbumPath(); + if (path == null) return; + + Navigator.maybeOf(context)?.pop(path); } } diff --git a/lib/widgets/dialogs/pick_dialogs/album_pick_page.dart b/lib/widgets/dialogs/pick_dialogs/album_pick_page.dart index 40b1682df..66fd7a2b4 100644 --- a/lib/widgets/dialogs/pick_dialogs/album_pick_page.dart +++ b/lib/widgets/dialogs/pick_dialogs/album_pick_page.dart @@ -250,7 +250,7 @@ class _AlbumPickPageState extends State<_AlbumPickPage> { ); if (directory == null) return; - // wait for the dialog to hide as applying the change may block the UI + // wait for the dialog to hide await Future.delayed(ADurations.dialogTransitionLoose * timeDilation); _pickAlbum(directory); @@ -274,7 +274,7 @@ class _AlbumPickPageState extends State<_AlbumPickPage> { ); if (details == null) return; - // wait for the dialog to hide as applying the change may block the UI + // wait for the dialog to hide await Future.delayed(ADurations.dialogTransitionLoose * timeDilation); await vaults.create(details); diff --git a/lib/widgets/dialogs/selection_dialogs/common.dart b/lib/widgets/dialogs/selection_dialogs/common.dart index 2f702780b..fe34e4f97 100644 --- a/lib/widgets/dialogs/selection_dialogs/common.dart +++ b/lib/widgets/dialogs/selection_dialogs/common.dart @@ -13,7 +13,7 @@ Future showSelectionDialog({ builder: builder, routeSettings: const RouteSettings(name: AvesSingleSelectionDialog.routeName), ); - // wait for the dialog to hide as applying the change may block the UI + // wait for the dialog to hide await Future.delayed(ADurations.dialogTransitionLoose * timeDilation); if (value != null) { onSelection(value); diff --git a/lib/widgets/filter_grids/common/action_delegates/album_set.dart b/lib/widgets/filter_grids/common/action_delegates/album_set.dart index aff3e0599..3b49cfb59 100644 --- a/lib/widgets/filter_grids/common/action_delegates/album_set.dart +++ b/lib/widgets/filter_grids/common/action_delegates/album_set.dart @@ -186,7 +186,7 @@ class AlbumChipSetActionDelegate extends ChipSetActionDelegate with }, routeSettings: const RouteSettings(name: TileViewDialog.routeName), ); - // wait for the dialog to hide as applying the change may block the UI + // wait for the dialog to hide await Future.delayed(ADurations.dialogTransitionLoose * timeDilation); if (value != null && initialValue != value) { sortFactor = value.$1!; @@ -199,6 +199,11 @@ class AlbumChipSetActionDelegate extends ChipSetActionDelegate with void _createAlbum(BuildContext context, {required bool locked}) async { final l10n = context.l10n; final source = context.read(); + + // get navigator beforehand because + // local context may be deactivated when action is triggered after navigation + final navigator = Navigator.maybeOf(context); + late final String? directory; if (locked) { if (!await showSkippableConfirmationDialog( @@ -226,36 +231,46 @@ class AlbumChipSetActionDelegate extends ChipSetActionDelegate with routeSettings: const RouteSettings(name: CreateAlbumDialog.routeName), ); if (directory == null) return; - } - source.createAlbum(directory); + // wait for the dialog to hide + await Future.delayed(ADurations.dialogTransitionLoose * timeDilation); + } final filter = AlbumFilter(directory, source.getAlbumDisplayName(context, directory)); - // get navigator beforehand because + + final albumExists = source.rawAlbums.contains(directory); + if (albumExists) { + // album already exists, so we just need to highlight it + await _showAlbum(navigator, filter); + } else { + // create the album and mark it as new + source.createAlbum(directory); + + final showAction = SnackBarAction( + label: l10n.showButtonLabel, + onPressed: () => _showAlbum(navigator, filter), + ); + showFeedback(context, FeedbackType.info, l10n.genericSuccessFeedback, showAction); + } + } + + Future _showAlbum(NavigatorState? navigator, AlbumFilter filter) async { // local context may be deactivated when action is triggered after navigation - final navigator = Navigator.maybeOf(context); - final showAction = SnackBarAction( - label: l10n.showButtonLabel, - onPressed: () async { - // local context may be deactivated when action is triggered after navigation - if (navigator != null) { - final context = navigator.context; - final highlightInfo = context.read(); - if (context.currentRouteName == AlbumListPage.routeName) { - highlightInfo.trackItem(FilterGridItem(filter, null), highlightItem: filter); - } else { - highlightInfo.set(filter); - await navigator.pushAndRemoveUntil( - MaterialPageRoute( - settings: const RouteSettings(name: AlbumListPage.routeName), - builder: (_) => const AlbumListPage(), - ), - (route) => false, - ); - } - } - }, - ); - showFeedback(context, FeedbackType.info, l10n.genericSuccessFeedback, showAction); + if (navigator != null) { + final context = navigator.context; + final highlightInfo = context.read(); + if (context.currentRouteName == AlbumListPage.routeName) { + highlightInfo.trackItem(FilterGridItem(filter, null), highlightItem: filter); + } else { + highlightInfo.set(filter); + await navigator.pushAndRemoveUntil( + MaterialPageRoute( + settings: const RouteSettings(name: AlbumListPage.routeName), + builder: (_) => const AlbumListPage(), + ), + (route) => false, + ); + } + } } Future _delete(BuildContext context) async { diff --git a/lib/widgets/filter_grids/common/action_delegates/chip_set.dart b/lib/widgets/filter_grids/common/action_delegates/chip_set.dart index 4d6bc1806..a6a6cb814 100644 --- a/lib/widgets/filter_grids/common/action_delegates/chip_set.dart +++ b/lib/widgets/filter_grids/common/action_delegates/chip_set.dart @@ -249,7 +249,7 @@ abstract class ChipSetActionDelegate with FeedbackMi }, routeSettings: const RouteSettings(name: TileViewDialog.routeName), ); - // wait for the dialog to hide as applying the change may block the UI + // wait for the dialog to hide await Future.delayed(ADurations.dialogTransitionLoose * timeDilation); if (value != null && initialValue != value) { sortFactor = value.$1!; diff --git a/lib/widgets/settings/language/locale_tile.dart b/lib/widgets/settings/language/locale_tile.dart index 4a2e50876..2469286a7 100644 --- a/lib/widgets/settings/language/locale_tile.dart +++ b/lib/widgets/settings/language/locale_tile.dart @@ -31,7 +31,7 @@ class LocaleTile extends StatelessWidget { builder: (context) => const LocaleSelectionPage(), ), ); - // wait for the dialog to hide as applying the change may block the UI + // wait for the dialog to hide await Future.delayed(ADurations.pageTransitionLoose * timeDilation); if (value != null) { settings.locale = value == systemLocaleOption ? null : value; diff --git a/lib/widgets/viewer/action/entry_action_delegate.dart b/lib/widgets/viewer/action/entry_action_delegate.dart index a53ae8dd0..1d2cba339 100644 --- a/lib/widgets/viewer/action/entry_action_delegate.dart +++ b/lib/widgets/viewer/action/entry_action_delegate.dart @@ -479,7 +479,7 @@ class EntryActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAwareMix ); if (newName == null || newName.isEmpty || newName == targetEntry.filenameWithoutExtension) return; - // wait for the dialog to hide as applying the change may block the UI + // wait for the dialog to hide await Future.delayed(ADurations.dialogTransitionLoose * timeDilation); await rename( context, From 88df125f5e93c69cef45810e428851fef30a0edb Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Mon, 11 Nov 2024 13:56:14 +0100 Subject: [PATCH 07/22] #1271 upgrade media-kit --- plugins/aves_magnifier/pubspec.lock | 4 +- plugins/aves_map/pubspec.lock | 4 +- plugins/aves_report_crashlytics/pubspec.lock | 16 ++-- plugins/aves_services/pubspec.lock | 4 +- plugins/aves_services_google/pubspec.lock | 24 ++--- plugins/aves_services_none/pubspec.lock | 4 +- plugins/aves_video/pubspec.lock | 4 +- plugins/aves_video_ffmpeg/pubspec.lock | 4 +- plugins/aves_video_mpv/pubspec.lock | 48 +++++----- plugins/aves_video_mpv/pubspec.yaml | 4 +- pubspec.lock | 96 ++++++++++---------- pubspec.yaml | 4 +- 12 files changed, 108 insertions(+), 108 deletions(-) diff --git a/plugins/aves_magnifier/pubspec.lock b/plugins/aves_magnifier/pubspec.lock index 60fb262be..d0263978c 100644 --- a/plugins/aves_magnifier/pubspec.lock +++ b/plugins/aves_magnifier/pubspec.lock @@ -20,10 +20,10 @@ packages: dependency: transitive description: name: clock - sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.1.2" collection: dependency: transitive description: diff --git a/plugins/aves_map/pubspec.lock b/plugins/aves_map/pubspec.lock index e11f3d826..19c0d1875 100644 --- a/plugins/aves_map/pubspec.lock +++ b/plugins/aves_map/pubspec.lock @@ -28,10 +28,10 @@ packages: dependency: transitive description: name: clock - sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.1.2" collection: dependency: "direct main" description: diff --git a/plugins/aves_report_crashlytics/pubspec.lock b/plugins/aves_report_crashlytics/pubspec.lock index 8f976b0c4..f9d01bb01 100644 --- a/plugins/aves_report_crashlytics/pubspec.lock +++ b/plugins/aves_report_crashlytics/pubspec.lock @@ -5,10 +5,10 @@ packages: dependency: transitive description: name: _flutterfire_internals - sha256: "5534e701a2c505fed1f0799e652dd6ae23bd4d2c4cf797220e5ced5764a7c1c2" + sha256: "5a0296da7ae717ffb7444dee8439ca25ac80e162a345b933aa57f0a4a48dca2c" url: "https://pub.dev" source: hosted - version: "1.3.44" + version: "1.3.45" async: dependency: transitive description: @@ -68,10 +68,10 @@ packages: dependency: "direct main" description: name: firebase_core - sha256: "51dfe2fbf3a984787a2e7b8592f2f05c986bfedd6fdacea3f9e0a7beb334de96" + sha256: e59141ff83e70a9ba571a1f8733c5598cf57e6e68037ab185581d7fc0a436738 url: "https://pub.dev" source: hosted - version: "3.6.0" + version: "3.7.0" firebase_core_platform_interface: dependency: transitive description: @@ -92,18 +92,18 @@ packages: dependency: "direct main" description: name: firebase_crashlytics - sha256: "6899800fff1af819955aef740f18c4c8600f8b952a2a1ea97bc0872ebb257387" + sha256: "859c0f9c40f44b555fc44227c3506b4236b86e6680cafb837e1eef40e661956e" url: "https://pub.dev" source: hosted - version: "4.1.3" + version: "4.1.4" firebase_crashlytics_platform_interface: dependency: transitive description: name: firebase_crashlytics_platform_interface - sha256: "97c47b0a1779a3d4118416a3f0c6c564cc59ad89095e899893204d4b2ad08f4c" + sha256: "4ae5bc279fd0a352d684340f9250b25571386fee0f7f3a750aae11c1cbbeaa40" url: "https://pub.dev" source: hosted - version: "3.6.44" + version: "3.6.45" flutter: dependency: "direct main" description: flutter diff --git a/plugins/aves_services/pubspec.lock b/plugins/aves_services/pubspec.lock index 595e6b7ee..a11d6931f 100644 --- a/plugins/aves_services/pubspec.lock +++ b/plugins/aves_services/pubspec.lock @@ -35,10 +35,10 @@ packages: dependency: transitive description: name: clock - sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.1.2" collection: dependency: transitive description: diff --git a/plugins/aves_services_google/pubspec.lock b/plugins/aves_services_google/pubspec.lock index c5a7795f3..abf0e6a60 100644 --- a/plugins/aves_services_google/pubspec.lock +++ b/plugins/aves_services_google/pubspec.lock @@ -49,10 +49,10 @@ packages: dependency: transitive description: name: clock - sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.1.2" collection: dependency: transitive description: @@ -65,10 +65,10 @@ packages: dependency: transitive description: name: csslib - sha256: "706b5707578e0c1b4b7550f64078f0a0f19dec3f50a178ffae7006b0a9ca58fb" + sha256: "09bad715f418841f976c77db72d5398dc1253c21fb9c0c7f0b0b985860b2d58e" url: "https://pub.dev" source: hosted - version: "1.0.0" + version: "1.0.2" custom_rounded_rectangle_border: dependency: transitive description: @@ -89,10 +89,10 @@ packages: dependency: "direct main" description: name: device_info_plus - sha256: c4af09051b4f0508f6c1dc0a5c085bf014d5c9a4a0678ce1799c2b4d716387a0 + sha256: f545ffbadee826f26f2e1a0f0cbd667ae9a6011cc0f77c0f8f00a969655e6e95 url: "https://pub.dev" source: hosted - version: "11.1.0" + version: "11.1.1" device_info_plus_platform_interface: dependency: transitive description: @@ -211,10 +211,10 @@ packages: dependency: "direct main" description: name: google_maps_flutter_android - sha256: "6caec25edb8014ec7d503babc597794de2d4c1baf3e3d20b57c41bd3e439b916" + sha256: bccf64ccbb2ea672dc62a61177b315a340af86b0228564484b023657544a3fd5 url: "https://pub.dev" source: hosted - version: "2.14.10" + version: "2.14.11" google_maps_flutter_ios: dependency: transitive description: @@ -243,10 +243,10 @@ packages: dependency: transitive description: name: html - sha256: "3a7812d5bcd2894edf53dfaf8cd640876cf6cef50a8f238745c8b8120ea74d3a" + sha256: "1fc58edeaec4307368c60d59b7e15b9d658b57d7f3125098b6294153c75337ec" url: "https://pub.dev" source: hosted - version: "0.15.4" + version: "0.15.5" http: dependency: transitive description: @@ -472,10 +472,10 @@ packages: dependency: transitive description: name: win32 - sha256: e1d0cc62e65dc2561f5071fcbccecf58ff20c344f8f3dc7d4922df372a11df1f + sha256: "84ba388638ed7a8cb3445a320c8273136ab2631cd5f2c57888335504ddab1bc2" url: "https://pub.dev" source: hosted - version: "5.7.1" + version: "5.8.0" win32_registry: dependency: transitive description: diff --git a/plugins/aves_services_none/pubspec.lock b/plugins/aves_services_none/pubspec.lock index 3cddaa2bd..20f5ada26 100644 --- a/plugins/aves_services_none/pubspec.lock +++ b/plugins/aves_services_none/pubspec.lock @@ -42,10 +42,10 @@ packages: dependency: transitive description: name: clock - sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.1.2" collection: dependency: transitive description: diff --git a/plugins/aves_video/pubspec.lock b/plugins/aves_video/pubspec.lock index 3bd054f59..86fad172f 100644 --- a/plugins/aves_video/pubspec.lock +++ b/plugins/aves_video/pubspec.lock @@ -27,10 +27,10 @@ packages: dependency: transitive description: name: clock - sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.1.2" collection: dependency: transitive description: diff --git a/plugins/aves_video_ffmpeg/pubspec.lock b/plugins/aves_video_ffmpeg/pubspec.lock index 6e3b9f1a3..a3b97d545 100644 --- a/plugins/aves_video_ffmpeg/pubspec.lock +++ b/plugins/aves_video_ffmpeg/pubspec.lock @@ -34,10 +34,10 @@ packages: dependency: transitive description: name: clock - sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.1.2" collection: dependency: transitive description: diff --git a/plugins/aves_video_mpv/pubspec.lock b/plugins/aves_video_mpv/pubspec.lock index 2cc027e8d..6d8cba9a3 100644 --- a/plugins/aves_video_mpv/pubspec.lock +++ b/plugins/aves_video_mpv/pubspec.lock @@ -58,10 +58,10 @@ packages: dependency: transitive description: name: clock - sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.1.2" collection: dependency: "direct main" description: @@ -156,10 +156,10 @@ packages: dependency: transitive description: name: js - sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 + sha256: c1b2e9b5ea78c45e1a0788d29606ba27dc5f71f019f32ca5140f61ef071838cf url: "https://pub.dev" source: hosted - version: "0.6.7" + version: "0.7.1" leak_tracker: dependency: transitive description: @@ -188,8 +188,8 @@ packages: dependency: "direct main" description: path: media_kit - ref: "3e7812ac2db4ec19ea501a387c1bf7a9c79bb64e" - resolved-ref: "3e7812ac2db4ec19ea501a387c1bf7a9c79bb64e" + ref: d094ba83715b0ac893e546781b2862e855d34502 + resolved-ref: d094ba83715b0ac893e546781b2862e855d34502 url: "https://github.com/media-kit/media-kit.git" source: git version: "1.1.11" @@ -205,8 +205,8 @@ packages: dependency: "direct main" description: path: media_kit_video - ref: "3e7812ac2db4ec19ea501a387c1bf7a9c79bb64e" - resolved-ref: "3e7812ac2db4ec19ea501a387c1bf7a9c79bb64e" + ref: d094ba83715b0ac893e546781b2862e855d34502 + resolved-ref: d094ba83715b0ac893e546781b2862e855d34502 url: "https://github.com/media-kit/media-kit.git" source: git version: "1.2.5" @@ -222,10 +222,10 @@ packages: dependency: transitive description: name: package_info_plus - sha256: df3eb3e0aed5c1107bb0fdb80a8e82e778114958b1c5ac5644fb1ac9cae8a998 + sha256: da8d9ac8c4b1df253d1a328b7bf01ae77ef132833479ab40763334db13b91cce url: "https://pub.dev" source: hosted - version: "8.1.0" + version: "8.1.1" package_info_plus_platform_interface: dependency: transitive description: @@ -270,50 +270,50 @@ packages: dependency: transitive description: name: screen_brightness - sha256: ed8da4a4511e79422fc1aa88138e920e4008cd312b72cdaa15ccb426c0faaedd + sha256: a43fdbccd5b90044f68057412dde7715cd7499a4c24f5d5da7e01ed4cf41e0af url: "https://pub.dev" source: hosted - version: "0.2.2+1" + version: "2.0.0+2" screen_brightness_android: dependency: transitive description: name: screen_brightness_android - sha256: "3df10961e3a9e968a5e076fe27e7f4741fa8a1d3950bdeb48cf121ed529d0caf" + sha256: "74455f9901ab8a1a45c9097b83855dbbb7498110cc2bc249cb5a86570dd1cf7c" url: "https://pub.dev" source: hosted - version: "0.1.0+2" + version: "2.0.0" screen_brightness_ios: dependency: transitive description: name: screen_brightness_ios - sha256: "99adc3ca5490b8294284aad5fcc87f061ad685050e03cf45d3d018fe398fd9a2" + sha256: caee02b34e0089b138a7aee35c461bd2d7c78446dd417f07613def192598ca08 url: "https://pub.dev" source: hosted - version: "0.1.0" + version: "2.0.0" screen_brightness_macos: dependency: transitive description: name: screen_brightness_macos - sha256: "64b34e7e3f4900d7687c8e8fb514246845a73ecec05ab53483ed025bd4a899fd" + sha256: "84fc8ffcbcf19c03d76b7673b0f2c2a2663c09aa2bc37c76ea83ab049294a97a" url: "https://pub.dev" source: hosted - version: "0.1.0+1" + version: "2.0.0" screen_brightness_platform_interface: dependency: transitive description: name: screen_brightness_platform_interface - sha256: b211d07f0c96637a15fb06f6168617e18030d5d74ad03795dd8547a52717c171 + sha256: "321e9455b0057e3647fd37700931e063739d94a8aa1b094f98133c01cb56c27b" url: "https://pub.dev" source: hosted - version: "0.1.0" + version: "2.0.0" screen_brightness_windows: dependency: transitive description: name: screen_brightness_windows - sha256: "9261bf33d0fc2707d8cf16339ce25768100a65e70af0fcabaf032fc12408ba86" + sha256: fa97ae838c42f762f04d2d70adb3d957350d6a84e3598ec800e269e7c466eedd url: "https://pub.dev" source: hosted - version: "0.1.3" + version: "2.0.0" sky_engine: dependency: transitive description: flutter @@ -443,10 +443,10 @@ packages: dependency: transitive description: name: win32 - sha256: e1d0cc62e65dc2561f5071fcbccecf58ff20c344f8f3dc7d4922df372a11df1f + sha256: "84ba388638ed7a8cb3445a320c8273136ab2631cd5f2c57888335504ddab1bc2" url: "https://pub.dev" source: hosted - version: "5.7.1" + version: "5.8.0" xml: dependency: transitive description: diff --git a/plugins/aves_video_mpv/pubspec.yaml b/plugins/aves_video_mpv/pubspec.yaml index 73fce6ec4..ac0ab896a 100644 --- a/plugins/aves_video_mpv/pubspec.yaml +++ b/plugins/aves_video_mpv/pubspec.yaml @@ -24,12 +24,12 @@ dependency_overrides: media_kit: git: url: https://github.com/media-kit/media-kit.git - ref: 18f155fe81cae93db712307411a17b2b93760eb6 + ref: d094ba83715b0ac893e546781b2862e855d34502 path: media_kit media_kit_video: git: url: https://github.com/media-kit/media-kit.git - ref: 18f155fe81cae93db712307411a17b2b93760eb6 + ref: d094ba83715b0ac893e546781b2862e855d34502 path: media_kit_video dev_dependencies: diff --git a/pubspec.lock b/pubspec.lock index aa22e10e2..9f037115d 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -13,10 +13,10 @@ packages: dependency: transitive description: name: _flutterfire_internals - sha256: "5534e701a2c505fed1f0799e652dd6ae23bd4d2c4cf797220e5ced5764a7c1c2" + sha256: "5a0296da7ae717ffb7444dee8439ca25ac80e162a345b933aa57f0a4a48dca2c" url: "https://pub.dev" source: hosted - version: "1.3.44" + version: "1.3.45" _macros: dependency: transitive description: dart @@ -247,10 +247,10 @@ packages: dependency: transitive description: name: coverage - sha256: "88b0fddbe4c92910fefc09cc0248f5e7f0cd23e450ded4c28f16ab8ee8f83268" + sha256: "4b03e11f6d5b8f6e5bb5e9f7889a56fe6c5cbe942da5378ea4d4d7f73ef9dfe5" url: "https://pub.dev" source: hosted - version: "1.10.0" + version: "1.11.0" crypto: dependency: transitive description: @@ -263,10 +263,10 @@ packages: dependency: transitive description: name: csslib - sha256: "706b5707578e0c1b4b7550f64078f0a0f19dec3f50a178ffae7006b0a9ca58fb" + sha256: "09bad715f418841f976c77db72d5398dc1253c21fb9c0c7f0b0b985860b2d58e" url: "https://pub.dev" source: hosted - version: "1.0.0" + version: "1.0.2" custom_rounded_rectangle_border: dependency: transitive description: @@ -303,10 +303,10 @@ packages: dependency: "direct main" description: name: device_info_plus - sha256: c4af09051b4f0508f6c1dc0a5c085bf014d5c9a4a0678ce1799c2b4d716387a0 + sha256: f545ffbadee826f26f2e1a0f0cbd667ae9a6011cc0f77c0f8f00a969655e6e95 url: "https://pub.dev" source: hosted - version: "11.1.0" + version: "11.1.1" device_info_plus_platform_interface: dependency: transitive description: @@ -409,10 +409,10 @@ packages: dependency: transitive description: name: firebase_core - sha256: "51dfe2fbf3a984787a2e7b8592f2f05c986bfedd6fdacea3f9e0a7beb334de96" + sha256: e59141ff83e70a9ba571a1f8733c5598cf57e6e68037ab185581d7fc0a436738 url: "https://pub.dev" source: hosted - version: "3.6.0" + version: "3.7.0" firebase_core_platform_interface: dependency: transitive description: @@ -433,18 +433,18 @@ packages: dependency: transitive description: name: firebase_crashlytics - sha256: "6899800fff1af819955aef740f18c4c8600f8b952a2a1ea97bc0872ebb257387" + sha256: "859c0f9c40f44b555fc44227c3506b4236b86e6680cafb837e1eef40e661956e" url: "https://pub.dev" source: hosted - version: "4.1.3" + version: "4.1.4" firebase_crashlytics_platform_interface: dependency: transitive description: name: firebase_crashlytics_platform_interface - sha256: "97c47b0a1779a3d4118416a3f0c6c564cc59ad89095e899893204d4b2ad08f4c" + sha256: "4ae5bc279fd0a352d684340f9250b25571386fee0f7f3a750aae11c1cbbeaa40" url: "https://pub.dev" source: hosted - version: "3.6.44" + version: "3.6.45" fixnum: dependency: transitive description: @@ -473,10 +473,10 @@ packages: dependency: "direct main" description: name: floating - sha256: aaebbbf0cef0454f68476edb6d79ca9734ee0e0080a03cee75db42fcc462efb5 + sha256: d6e7046bfec4c1ab9e09ef9d88fee104b1eb41171d6e083099bf310535d26b79 url: "https://pub.dev" source: hosted - version: "5.0.0" + version: "5.0.1" fluster: dependency: "direct main" description: @@ -600,10 +600,10 @@ packages: dependency: "direct main" description: name: get_it - sha256: "35c253f83f9e03cbac65ffa159510e41ae15f49b37291ab8c522d7a0b6f330cd" + sha256: c49895c1ecb0ee2a0ec568d39de882e2c299ba26355aa6744ab1001f98cebd15 url: "https://pub.dev" source: hosted - version: "8.0.1" + version: "8.0.2" glob: dependency: transitive description: @@ -656,10 +656,10 @@ packages: dependency: transitive description: name: google_maps_flutter_android - sha256: "6caec25edb8014ec7d503babc597794de2d4c1baf3e3d20b57c41bd3e439b916" + sha256: bccf64ccbb2ea672dc62a61177b315a340af86b0228564484b023657544a3fd5 url: "https://pub.dev" source: hosted - version: "2.14.10" + version: "2.14.11" google_maps_flutter_ios: dependency: transitive description: @@ -696,10 +696,10 @@ packages: dependency: transitive description: name: html - sha256: "3a7812d5bcd2894edf53dfaf8cd640876cf6cef50a8f238745c8b8120ea74d3a" + sha256: "1fc58edeaec4307368c60d59b7e15b9d658b57d7f3125098b6294153c75337ec" url: "https://pub.dev" source: hosted - version: "0.15.4" + version: "0.15.5" http: dependency: "direct main" description: @@ -904,8 +904,8 @@ packages: dependency: "direct overridden" description: path: media_kit - ref: "18f155fe81cae93db712307411a17b2b93760eb6" - resolved-ref: "18f155fe81cae93db712307411a17b2b93760eb6" + ref: d094ba83715b0ac893e546781b2862e855d34502 + resolved-ref: d094ba83715b0ac893e546781b2862e855d34502 url: "https://github.com/media-kit/media-kit.git" source: git version: "1.1.11" @@ -921,8 +921,8 @@ packages: dependency: "direct overridden" description: path: media_kit_video - ref: "18f155fe81cae93db712307411a17b2b93760eb6" - resolved-ref: "18f155fe81cae93db712307411a17b2b93760eb6" + ref: d094ba83715b0ac893e546781b2862e855d34502 + resolved-ref: d094ba83715b0ac893e546781b2862e855d34502 url: "https://github.com/media-kit/media-kit.git" source: git version: "1.2.5" @@ -971,10 +971,10 @@ packages: dependency: "direct main" description: name: network_info_plus - sha256: "89bad7bf9614e78716f0f86c905fe2a850dbdcc00c377968d5260c49c2c6f2eb" + sha256: bf9e39e523e9951d741868dc33ac386b0bc24301e9b7c8a7d60dbc34879150a8 url: "https://pub.dev" source: hosted - version: "6.1.0" + version: "6.1.1" network_info_plus_platform_interface: dependency: transitive description: @@ -1019,10 +1019,10 @@ packages: dependency: "direct main" description: name: package_info_plus - sha256: df3eb3e0aed5c1107bb0fdb80a8e82e778114958b1c5ac5644fb1ac9cae8a998 + sha256: da8d9ac8c4b1df253d1a328b7bf01ae77ef132833479ab40763334db13b91cce url: "https://pub.dev" source: hosted - version: "8.1.0" + version: "8.1.1" package_info_plus_platform_interface: dependency: transitive description: @@ -1035,10 +1035,10 @@ packages: dependency: "direct main" description: name: palette_generator - sha256: d50fbcd69abb80c5baec66d700033b1a320108b1aa17a5961866a12c0abb7c0c + sha256: "0b20245c451f14a5ca0818ab7a377765162389f8e8f0db361cceabf0fed9d1ea" url: "https://pub.dev" source: hosted - version: "0.3.3+4" + version: "0.3.3+5" panorama: dependency: "direct main" description: @@ -1060,18 +1060,18 @@ packages: dependency: transitive description: name: path_parsing - sha256: "45f7d6bba1128761de5540f39d5ca000ea8a1f22f06b76b61094a60a2997bd0e" + sha256: "883402936929eac138ee0a45da5b0f2c80f89913e6dc3bf77eb65b84b409c6ca" url: "https://pub.dev" source: hosted - version: "1.0.2" + version: "1.1.0" path_provider: dependency: transitive description: name: path_provider - sha256: fec0d61223fba3154d87759e3cc27fe2c8dc498f6386c6d6fc80d1afdd1bf378 + sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd" url: "https://pub.dev" source: hosted - version: "2.1.4" + version: "2.1.5" path_provider_android: dependency: transitive description: @@ -1244,10 +1244,10 @@ packages: dependency: "direct main" description: name: printing - sha256: b576764370c920b510cedf3eac7dc199d6d4af34336d608e97546392c0113362 + sha256: b535d177fc6e8f8908e19b0ff5c1d4a87e3c4d0bf675e05aa2562af1b7853906 url: "https://pub.dev" source: hosted - version: "5.13.3" + version: "5.13.4" process: dependency: transitive description: @@ -1364,10 +1364,10 @@ packages: dependency: "direct main" description: name: shared_preferences - sha256: "746e5369a43170c25816cc472ee016d3a66bc13fcf430c0bc41ad7b4b2922051" + sha256: "95f9997ca1fb9799d494d0cb2a780fd7be075818d59f00c43832ed112b158a82" url: "https://pub.dev" source: hosted - version: "2.3.2" + version: "2.3.3" shared_preferences_android: dependency: transitive description: @@ -1497,10 +1497,10 @@ packages: dependency: "direct main" description: name: sqflite - sha256: "79a297dc3cc137e758c6a4baf83342b039e5a6d2436fcdf3f96a00adaaf2ad62" + sha256: "2d7299468485dca85efeeadf5d38986909c5eb0cd71fd3db2c2f000e6c9454bb" url: "https://pub.dev" source: hosted - version: "2.4.0" + version: "2.4.1" sqflite_android: dependency: transitive description: @@ -1521,10 +1521,10 @@ packages: dependency: transitive description: name: sqflite_darwin - sha256: "769733dddf94622d5541c73e4ddc6aa7b252d865285914b6fcd54a63c4b4f027" + sha256: "96a698e2bc82bd770a4d6aab00b42396a7c63d9e33513a56945cbccb594c2474" url: "https://pub.dev" source: hosted - version: "2.4.1-1" + version: "2.4.1" sqflite_platform_interface: dependency: transitive description: @@ -1674,10 +1674,10 @@ packages: dependency: transitive description: name: url_launcher_android - sha256: "0dea215895a4d254401730ca0ba8204b29109a34a99fb06ae559a2b60988d2de" + sha256: "6fc2f56536ee873eeb867ad176ae15f304ccccc357848b351f6f0d8d4a40d193" url: "https://pub.dev" source: hosted - version: "6.3.13" + version: "6.3.14" url_launcher_ios: dependency: transitive description: @@ -1850,10 +1850,10 @@ packages: dependency: transitive description: name: win32 - sha256: e1d0cc62e65dc2561f5071fcbccecf58ff20c344f8f3dc7d4922df372a11df1f + sha256: "84ba388638ed7a8cb3445a320c8273136ab2631cd5f2c57888335504ddab1bc2" url: "https://pub.dev" source: hosted - version: "5.7.1" + version: "5.8.0" win32_registry: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 38ff93e9b..c441f1930 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -122,12 +122,12 @@ dependency_overrides: media_kit: git: url: https://github.com/media-kit/media-kit.git - ref: 18f155fe81cae93db712307411a17b2b93760eb6 + ref: d094ba83715b0ac893e546781b2862e855d34502 path: media_kit media_kit_video: git: url: https://github.com/media-kit/media-kit.git - ref: 18f155fe81cae93db712307411a17b2b93760eb6 + ref: d094ba83715b0ac893e546781b2862e855d34502 path: media_kit_video dev_dependencies: From e3eda2d330ee5bbbc236e7ac06319251a508cb09 Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Mon, 11 Nov 2024 22:04:56 +0100 Subject: [PATCH 08/22] l10n by weblate (#1282) Translate-URL: https://hosted.weblate.org/projects/aves/app-android/ru/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/es/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/fr/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/ko/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/pl/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/sv/ Translation: Aves/App - Android Translation: Aves/App - Main Co-authored-by: Thibault Deckers Co-authored-by: bittin1ddc447d824349b2 Co-authored-by: gallegonovato Co-authored-by: kaajjo Co-authored-by: rehork --- android/app/src/main/res/values-ru/strings.xml | 1 + lib/l10n/app_es.arb | 4 +++- lib/l10n/app_fr.arb | 4 +++- lib/l10n/app_ko.arb | 4 +++- lib/l10n/app_pl.arb | 4 +++- lib/l10n/app_sv.arb | 4 +++- 6 files changed, 16 insertions(+), 5 deletions(-) diff --git a/android/app/src/main/res/values-ru/strings.xml b/android/app/src/main/res/values-ru/strings.xml index 58e9cc54c..ca3cde898 100644 --- a/android/app/src/main/res/values-ru/strings.xml +++ b/android/app/src/main/res/values-ru/strings.xml @@ -8,4 +8,5 @@ Сканировать медия Сканирование медиа Стоп + Карта \ No newline at end of file diff --git a/lib/l10n/app_es.arb b/lib/l10n/app_es.arb index af2c69363..1e24e6b2b 100644 --- a/lib/l10n/app_es.arb +++ b/lib/l10n/app_es.arb @@ -1390,5 +1390,7 @@ "videoActionShowPreviousFrame": "Mostrar fotograma anterior", "@videoActionShowPreviousFrame": {}, "videoActionShowNextFrame": "Mostrar fotograma siguiente", - "@videoActionShowNextFrame": {} + "@videoActionShowNextFrame": {}, + "newAlbumDialogAlbumAlreadyExistsHelper": "El álbum ya existe", + "@newAlbumDialogAlbumAlreadyExistsHelper": {} } diff --git a/lib/l10n/app_fr.arb b/lib/l10n/app_fr.arb index 8380f1809..d654c6552 100644 --- a/lib/l10n/app_fr.arb +++ b/lib/l10n/app_fr.arb @@ -1390,5 +1390,7 @@ "videoActionShowNextFrame": "Montrer l’image suivante", "@videoActionShowNextFrame": {}, "videoActionShowPreviousFrame": "Montrer l’image précédente", - "@videoActionShowPreviousFrame": {} + "@videoActionShowPreviousFrame": {}, + "newAlbumDialogAlbumAlreadyExistsHelper": "L’album existe déjà", + "@newAlbumDialogAlbumAlreadyExistsHelper": {} } diff --git a/lib/l10n/app_ko.arb b/lib/l10n/app_ko.arb index b046e0674..18c0de660 100644 --- a/lib/l10n/app_ko.arb +++ b/lib/l10n/app_ko.arb @@ -1390,5 +1390,7 @@ "videoActionShowNextFrame": "다음 프레임 보기", "@videoActionShowNextFrame": {}, "videoActionShowPreviousFrame": "이전 프레임 보기", - "@videoActionShowPreviousFrame": {} + "@videoActionShowPreviousFrame": {}, + "newAlbumDialogAlbumAlreadyExistsHelper": "앨범이 이미 있습니다", + "@newAlbumDialogAlbumAlreadyExistsHelper": {} } diff --git a/lib/l10n/app_pl.arb b/lib/l10n/app_pl.arb index 292b5637a..a25b65419 100644 --- a/lib/l10n/app_pl.arb +++ b/lib/l10n/app_pl.arb @@ -1548,5 +1548,7 @@ "videoActionShowPreviousFrame": "Pokaż poprzednią klatkę", "@videoActionShowPreviousFrame": {}, "videoActionShowNextFrame": "Pokaż kolejną klatkę", - "@videoActionShowNextFrame": {} + "@videoActionShowNextFrame": {}, + "newAlbumDialogAlbumAlreadyExistsHelper": "Album już istnieje", + "@newAlbumDialogAlbumAlreadyExistsHelper": {} } diff --git a/lib/l10n/app_sv.arb b/lib/l10n/app_sv.arb index 05d0693a5..2cb81c06f 100644 --- a/lib/l10n/app_sv.arb +++ b/lib/l10n/app_sv.arb @@ -1570,5 +1570,7 @@ "videoActionShowPreviousFrame": "Visa föregående bildruta", "@videoActionShowPreviousFrame": {}, "videoActionShowNextFrame": "Visa nästa bildruta", - "@videoActionShowNextFrame": {} + "@videoActionShowNextFrame": {}, + "newAlbumDialogAlbumAlreadyExistsHelper": "Album existerar redan", + "@newAlbumDialogAlbumAlreadyExistsHelper": {} } From d83537f774b39b8468228c39c872b5b5e9a8f7a0 Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Mon, 11 Nov 2024 22:07:46 +0100 Subject: [PATCH 09/22] #1253 fastlane: changed Shavian tag --- .../{en-US-Shaw => en-XW-Shaw}/full_description.txt | 0 .../images/featureGraphic.png | Bin .../images/phoneScreenshots/1.png | Bin .../images/phoneScreenshots/2.png | Bin .../images/phoneScreenshots/3.png | Bin .../images/phoneScreenshots/4.png | Bin .../images/phoneScreenshots/5.png | Bin .../images/phoneScreenshots/6.png | Bin .../images/phoneScreenshots/7.png | Bin .../short_description.txt | 0 10 files changed, 0 insertions(+), 0 deletions(-) rename fastlane/metadata/android/{en-US-Shaw => en-XW-Shaw}/full_description.txt (100%) rename fastlane/metadata/android/{en-US-Shaw => en-XW-Shaw}/images/featureGraphic.png (100%) rename fastlane/metadata/android/{en-US-Shaw => en-XW-Shaw}/images/phoneScreenshots/1.png (100%) rename fastlane/metadata/android/{en-US-Shaw => en-XW-Shaw}/images/phoneScreenshots/2.png (100%) rename fastlane/metadata/android/{en-US-Shaw => en-XW-Shaw}/images/phoneScreenshots/3.png (100%) rename fastlane/metadata/android/{en-US-Shaw => en-XW-Shaw}/images/phoneScreenshots/4.png (100%) rename fastlane/metadata/android/{en-US-Shaw => en-XW-Shaw}/images/phoneScreenshots/5.png (100%) rename fastlane/metadata/android/{en-US-Shaw => en-XW-Shaw}/images/phoneScreenshots/6.png (100%) rename fastlane/metadata/android/{en-US-Shaw => en-XW-Shaw}/images/phoneScreenshots/7.png (100%) rename fastlane/metadata/android/{en-US-Shaw => en-XW-Shaw}/short_description.txt (100%) diff --git a/fastlane/metadata/android/en-US-Shaw/full_description.txt b/fastlane/metadata/android/en-XW-Shaw/full_description.txt similarity index 100% rename from fastlane/metadata/android/en-US-Shaw/full_description.txt rename to fastlane/metadata/android/en-XW-Shaw/full_description.txt diff --git a/fastlane/metadata/android/en-US-Shaw/images/featureGraphic.png b/fastlane/metadata/android/en-XW-Shaw/images/featureGraphic.png similarity index 100% rename from fastlane/metadata/android/en-US-Shaw/images/featureGraphic.png rename to fastlane/metadata/android/en-XW-Shaw/images/featureGraphic.png diff --git a/fastlane/metadata/android/en-US-Shaw/images/phoneScreenshots/1.png b/fastlane/metadata/android/en-XW-Shaw/images/phoneScreenshots/1.png similarity index 100% rename from fastlane/metadata/android/en-US-Shaw/images/phoneScreenshots/1.png rename to fastlane/metadata/android/en-XW-Shaw/images/phoneScreenshots/1.png diff --git a/fastlane/metadata/android/en-US-Shaw/images/phoneScreenshots/2.png b/fastlane/metadata/android/en-XW-Shaw/images/phoneScreenshots/2.png similarity index 100% rename from fastlane/metadata/android/en-US-Shaw/images/phoneScreenshots/2.png rename to fastlane/metadata/android/en-XW-Shaw/images/phoneScreenshots/2.png diff --git a/fastlane/metadata/android/en-US-Shaw/images/phoneScreenshots/3.png b/fastlane/metadata/android/en-XW-Shaw/images/phoneScreenshots/3.png similarity index 100% rename from fastlane/metadata/android/en-US-Shaw/images/phoneScreenshots/3.png rename to fastlane/metadata/android/en-XW-Shaw/images/phoneScreenshots/3.png diff --git a/fastlane/metadata/android/en-US-Shaw/images/phoneScreenshots/4.png b/fastlane/metadata/android/en-XW-Shaw/images/phoneScreenshots/4.png similarity index 100% rename from fastlane/metadata/android/en-US-Shaw/images/phoneScreenshots/4.png rename to fastlane/metadata/android/en-XW-Shaw/images/phoneScreenshots/4.png diff --git a/fastlane/metadata/android/en-US-Shaw/images/phoneScreenshots/5.png b/fastlane/metadata/android/en-XW-Shaw/images/phoneScreenshots/5.png similarity index 100% rename from fastlane/metadata/android/en-US-Shaw/images/phoneScreenshots/5.png rename to fastlane/metadata/android/en-XW-Shaw/images/phoneScreenshots/5.png diff --git a/fastlane/metadata/android/en-US-Shaw/images/phoneScreenshots/6.png b/fastlane/metadata/android/en-XW-Shaw/images/phoneScreenshots/6.png similarity index 100% rename from fastlane/metadata/android/en-US-Shaw/images/phoneScreenshots/6.png rename to fastlane/metadata/android/en-XW-Shaw/images/phoneScreenshots/6.png diff --git a/fastlane/metadata/android/en-US-Shaw/images/phoneScreenshots/7.png b/fastlane/metadata/android/en-XW-Shaw/images/phoneScreenshots/7.png similarity index 100% rename from fastlane/metadata/android/en-US-Shaw/images/phoneScreenshots/7.png rename to fastlane/metadata/android/en-XW-Shaw/images/phoneScreenshots/7.png diff --git a/fastlane/metadata/android/en-US-Shaw/short_description.txt b/fastlane/metadata/android/en-XW-Shaw/short_description.txt similarity index 100% rename from fastlane/metadata/android/en-US-Shaw/short_description.txt rename to fastlane/metadata/android/en-XW-Shaw/short_description.txt From e7ec41b8d5a2960c3696a922d3b9a721459601d0 Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Tue, 12 Nov 2024 18:58:41 +0100 Subject: [PATCH 10/22] #1280 print: ignore undecodable pages --- CHANGELOG.md | 10 ++++++++ lib/widgets/viewer/action/printer.dart | 32 +++++++++++++++----------- 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b290ba4c..a3308a2a4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,16 @@ All notable changes to this project will be documented in this file. ## [Unreleased] +### Changed + +- Albums: improved album creation feedback + +### Fixed + +- crash when playing video with DCL restriction enabled +- printing multi-page items containing some unprintable pages +- English (Shavian) locale tags for store listing + ## [v1.11.17] - 2024-10-30 ### Added diff --git a/lib/widgets/viewer/action/printer.dart b/lib/widgets/viewer/action/printer.dart index e8ed87d54..0871e0348 100644 --- a/lib/widgets/viewer/action/printer.dart +++ b/lib/widgets/viewer/action/printer.dart @@ -105,23 +105,27 @@ class EntryPrinter with FeedbackMixin { } Future _buildPageImage(AvesEntry entry) async { - if (entry.isSvg) { - final data = await mediaFetchService.getSvg( - entry.uri, - entry.mimeType, - sizeBytes: entry.sizeBytes, - ); - if (data.isNotEmpty) { - return pdf.SvgImage( - svg: utf8.decode(data), + try { + if (entry.isSvg) { + final data = await mediaFetchService.getSvg( + entry.uri, + entry.mimeType, + sizeBytes: entry.sizeBytes, + ); + if (data.isNotEmpty) { + return pdf.SvgImage( + svg: utf8.decode(data), + fit: _fit, + ); + } + } else { + return pdf.Image( + await flutterImageProvider(entry.uriImage), fit: _fit, ); } - } else { - return pdf.Image( - await flutterImageProvider(entry.uriImage), - fit: _fit, - ); + } catch (error) { + debugPrint('failed to load image for entry=$entry, error=$error'); } return null; } From d5fef14e9a13d1e8eb53ea222c19b71322617682 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 13 Nov 2024 02:58:57 +0900 Subject: [PATCH 11/22] Bump github/codeql-action from 3.27.1 to 3.27.2 (#1290) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.27.1 to 3.27.2. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/4f3212b61783c3c68e8309a0f18a699764811cda...9278e421667d5d90a2839487a482448c4ec7df4d) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/quality-check.yml | 4 ++-- .github/workflows/scorecards.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/quality-check.yml b/.github/workflows/quality-check.yml index 8911a9452..6d1147af9 100644 --- a/.github/workflows/quality-check.yml +++ b/.github/workflows/quality-check.yml @@ -69,7 +69,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@4f3212b61783c3c68e8309a0f18a699764811cda # v3.27.1 + uses: github/codeql-action/init@9278e421667d5d90a2839487a482448c4ec7df4d # v3.27.2 with: languages: ${{ matrix.language }} build-mode: ${{ matrix.build-mode }} @@ -83,6 +83,6 @@ jobs: ./flutterw build apk --profile -t lib/main_play.dart --flavor play - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@4f3212b61783c3c68e8309a0f18a699764811cda # v3.27.1 + uses: github/codeql-action/analyze@9278e421667d5d90a2839487a482448c4ec7df4d # v3.27.2 with: category: "/language:${{matrix.language}}" diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index b097c8538..08dd5476e 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -71,6 +71,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@4f3212b61783c3c68e8309a0f18a699764811cda # v3.27.1 + uses: github/codeql-action/upload-sarif@9278e421667d5d90a2839487a482448c4ec7df4d # v3.27.2 with: sarif_file: results.sarif From d7f5eabc3415d593bfbc93812b8f3a7fe521dd60 Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Sun, 17 Nov 2024 14:41:31 +0100 Subject: [PATCH 12/22] upgraded Flutter to stable v3.24.5 --- .flutter | 2 +- CHANGELOG.md | 1 + plugins/aves_map/pubspec.lock | 12 +++---- plugins/aves_report_crashlytics/pubspec.lock | 16 ++++----- plugins/aves_services/pubspec.lock | 12 +++---- plugins/aves_services_google/pubspec.lock | 20 ++++++------ plugins/aves_services_none/pubspec.lock | 12 +++---- pubspec.lock | 34 ++++++++++---------- pubspec.yaml | 2 +- shaders.sksl.json | 2 +- 10 files changed, 57 insertions(+), 56 deletions(-) diff --git a/.flutter b/.flutter index 603104015..dec2ee5c1 160000 --- a/.flutter +++ b/.flutter @@ -1 +1 @@ -Subproject commit 603104015dd692ea3403755b55d07813d5cf8965 +Subproject commit dec2ee5c1f98f8e84a7d5380c05eb8a3d0a81668 diff --git a/CHANGELOG.md b/CHANGELOG.md index a3308a2a4..d81f2a680 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file. ### Changed - Albums: improved album creation feedback +- upgraded Flutter to stable v3.24.5 ### Fixed diff --git a/plugins/aves_map/pubspec.lock b/plugins/aves_map/pubspec.lock index 19c0d1875..3a7cae9f8 100644 --- a/plugins/aves_map/pubspec.lock +++ b/plugins/aves_map/pubspec.lock @@ -113,10 +113,10 @@ packages: dependency: "direct main" description: name: intl - sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf + sha256: "99f282cb0e02edcbbf8c6b3bbc7c90b65635156c412e58f3975a7e55284ce685" url: "https://pub.dev" source: hosted - version: "0.19.0" + version: "0.20.0" latlong2: dependency: "direct main" description: @@ -153,10 +153,10 @@ packages: dependency: transitive description: name: logger - sha256: "697d067c60c20999686a0add96cf6aba723b3aa1f83ecf806a8097231529ec32" + sha256: be4b23575aac7ebf01f225a241eb7f6b5641eeaf43c6a8613510fc2f8cf187d1 url: "https://pub.dev" source: hosted - version: "2.4.0" + version: "2.5.0" material_color_utilities: dependency: transitive description: @@ -286,10 +286,10 @@ packages: dependency: transitive description: name: web - sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb + sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27" url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "0.5.1" wkt_parser: dependency: transitive description: diff --git a/plugins/aves_report_crashlytics/pubspec.lock b/plugins/aves_report_crashlytics/pubspec.lock index f9d01bb01..da24c1b41 100644 --- a/plugins/aves_report_crashlytics/pubspec.lock +++ b/plugins/aves_report_crashlytics/pubspec.lock @@ -5,10 +5,10 @@ packages: dependency: transitive description: name: _flutterfire_internals - sha256: "5a0296da7ae717ffb7444dee8439ca25ac80e162a345b933aa57f0a4a48dca2c" + sha256: "71c01c1998c40b3af1944ad0a5f374b4e6fef7f3d2df487f3970dbeadaeb25a1" url: "https://pub.dev" source: hosted - version: "1.3.45" + version: "1.3.46" async: dependency: transitive description: @@ -68,10 +68,10 @@ packages: dependency: "direct main" description: name: firebase_core - sha256: e59141ff83e70a9ba571a1f8733c5598cf57e6e68037ab185581d7fc0a436738 + sha256: "2438a75ad803e818ad3bd5df49137ee619c46b6fc7101f4dbc23da07305ce553" url: "https://pub.dev" source: hosted - version: "3.7.0" + version: "3.8.0" firebase_core_platform_interface: dependency: transitive description: @@ -92,18 +92,18 @@ packages: dependency: "direct main" description: name: firebase_crashlytics - sha256: "859c0f9c40f44b555fc44227c3506b4236b86e6680cafb837e1eef40e661956e" + sha256: "4e80ef22428dfecf609df8049419c7446c6e1d797d7f307cad3c7ab70e72ddc5" url: "https://pub.dev" source: hosted - version: "4.1.4" + version: "4.1.5" firebase_crashlytics_platform_interface: dependency: transitive description: name: firebase_crashlytics_platform_interface - sha256: "4ae5bc279fd0a352d684340f9250b25571386fee0f7f3a750aae11c1cbbeaa40" + sha256: "1104f428ec5249fff62016985719bb232ca91c4bde0d1a033af9b7d8b7451d70" url: "https://pub.dev" source: hosted - version: "3.6.45" + version: "3.6.46" flutter: dependency: "direct main" description: flutter diff --git a/plugins/aves_services/pubspec.lock b/plugins/aves_services/pubspec.lock index a11d6931f..39c23aac5 100644 --- a/plugins/aves_services/pubspec.lock +++ b/plugins/aves_services/pubspec.lock @@ -120,10 +120,10 @@ packages: dependency: transitive description: name: intl - sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf + sha256: "99f282cb0e02edcbbf8c6b3bbc7c90b65635156c412e58f3975a7e55284ce685" url: "https://pub.dev" source: hosted - version: "0.19.0" + version: "0.20.0" latlong2: dependency: "direct main" description: @@ -160,10 +160,10 @@ packages: dependency: transitive description: name: logger - sha256: "697d067c60c20999686a0add96cf6aba723b3aa1f83ecf806a8097231529ec32" + sha256: be4b23575aac7ebf01f225a241eb7f6b5641eeaf43c6a8613510fc2f8cf187d1 url: "https://pub.dev" source: hosted - version: "2.4.0" + version: "2.5.0" material_color_utilities: dependency: transitive description: @@ -293,10 +293,10 @@ packages: dependency: transitive description: name: web - sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb + sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27" url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "0.5.1" wkt_parser: dependency: transitive description: diff --git a/plugins/aves_services_google/pubspec.lock b/plugins/aves_services_google/pubspec.lock index abf0e6a60..eada00d60 100644 --- a/plugins/aves_services_google/pubspec.lock +++ b/plugins/aves_services_google/pubspec.lock @@ -89,10 +89,10 @@ packages: dependency: "direct main" description: name: device_info_plus - sha256: f545ffbadee826f26f2e1a0f0cbd667ae9a6011cc0f77c0f8f00a969655e6e95 + sha256: a7fd703482b391a87d60b6061d04dfdeab07826b96f9abd8f5ed98068acc0074 url: "https://pub.dev" source: hosted - version: "11.1.1" + version: "10.1.2" device_info_plus_platform_interface: dependency: transitive description: @@ -203,10 +203,10 @@ packages: dependency: "direct main" description: name: google_maps_flutter - sha256: "2e302fa3aaf4e2a297f0342d83ebc5e8e9f826e9a716aef473fe7f404ec630a7" + sha256: "209856c8e5571626afba7182cf634b2910069dc567954e76ec3e3fb37f5e9db3" url: "https://pub.dev" source: hosted - version: "2.9.0" + version: "2.10.0" google_maps_flutter_android: dependency: "direct main" description: @@ -267,10 +267,10 @@ packages: dependency: transitive description: name: intl - sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf + sha256: "99f282cb0e02edcbbf8c6b3bbc7c90b65635156c412e58f3975a7e55284ce685" url: "https://pub.dev" source: hosted - version: "0.19.0" + version: "0.20.0" latlong2: dependency: "direct main" description: @@ -307,10 +307,10 @@ packages: dependency: transitive description: name: logger - sha256: "697d067c60c20999686a0add96cf6aba723b3aa1f83ecf806a8097231529ec32" + sha256: be4b23575aac7ebf01f225a241eb7f6b5641eeaf43c6a8613510fc2f8cf187d1 url: "https://pub.dev" source: hosted - version: "2.4.0" + version: "2.5.0" material_color_utilities: dependency: transitive description: @@ -464,10 +464,10 @@ packages: dependency: transitive description: name: web - sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb + sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27" url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "0.5.1" win32: dependency: transitive description: diff --git a/plugins/aves_services_none/pubspec.lock b/plugins/aves_services_none/pubspec.lock index 20f5ada26..61e7f2bab 100644 --- a/plugins/aves_services_none/pubspec.lock +++ b/plugins/aves_services_none/pubspec.lock @@ -127,10 +127,10 @@ packages: dependency: transitive description: name: intl - sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf + sha256: "99f282cb0e02edcbbf8c6b3bbc7c90b65635156c412e58f3975a7e55284ce685" url: "https://pub.dev" source: hosted - version: "0.19.0" + version: "0.20.0" latlong2: dependency: "direct main" description: @@ -167,10 +167,10 @@ packages: dependency: transitive description: name: logger - sha256: "697d067c60c20999686a0add96cf6aba723b3aa1f83ecf806a8097231529ec32" + sha256: be4b23575aac7ebf01f225a241eb7f6b5641eeaf43c6a8613510fc2f8cf187d1 url: "https://pub.dev" source: hosted - version: "2.4.0" + version: "2.5.0" material_color_utilities: dependency: transitive description: @@ -300,10 +300,10 @@ packages: dependency: transitive description: name: web - sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb + sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27" url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "0.5.1" wkt_parser: dependency: transitive description: diff --git a/pubspec.lock b/pubspec.lock index 9f037115d..c03b4bffc 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -13,10 +13,10 @@ packages: dependency: transitive description: name: _flutterfire_internals - sha256: "5a0296da7ae717ffb7444dee8439ca25ac80e162a345b933aa57f0a4a48dca2c" + sha256: "71c01c1998c40b3af1944ad0a5f374b4e6fef7f3d2df487f3970dbeadaeb25a1" url: "https://pub.dev" source: hosted - version: "1.3.45" + version: "1.3.46" _macros: dependency: transitive description: dart @@ -409,10 +409,10 @@ packages: dependency: transitive description: name: firebase_core - sha256: e59141ff83e70a9ba571a1f8733c5598cf57e6e68037ab185581d7fc0a436738 + sha256: "2438a75ad803e818ad3bd5df49137ee619c46b6fc7101f4dbc23da07305ce553" url: "https://pub.dev" source: hosted - version: "3.7.0" + version: "3.8.0" firebase_core_platform_interface: dependency: transitive description: @@ -433,18 +433,18 @@ packages: dependency: transitive description: name: firebase_crashlytics - sha256: "859c0f9c40f44b555fc44227c3506b4236b86e6680cafb837e1eef40e661956e" + sha256: "4e80ef22428dfecf609df8049419c7446c6e1d797d7f307cad3c7ab70e72ddc5" url: "https://pub.dev" source: hosted - version: "4.1.4" + version: "4.1.5" firebase_crashlytics_platform_interface: dependency: transitive description: name: firebase_crashlytics_platform_interface - sha256: "4ae5bc279fd0a352d684340f9250b25571386fee0f7f3a750aae11c1cbbeaa40" + sha256: "1104f428ec5249fff62016985719bb232ca91c4bde0d1a033af9b7d8b7451d70" url: "https://pub.dev" source: hosted - version: "3.6.45" + version: "3.6.46" fixnum: dependency: transitive description: @@ -648,10 +648,10 @@ packages: dependency: transitive description: name: google_maps_flutter - sha256: "2e302fa3aaf4e2a297f0342d83ebc5e8e9f826e9a716aef473fe7f404ec630a7" + sha256: "209856c8e5571626afba7182cf634b2910069dc567954e76ec3e3fb37f5e9db3" url: "https://pub.dev" source: hosted - version: "2.9.0" + version: "2.10.0" google_maps_flutter_android: dependency: transitive description: @@ -848,10 +848,10 @@ packages: dependency: transitive description: name: logger - sha256: "697d067c60c20999686a0add96cf6aba723b3aa1f83ecf806a8097231529ec32" + sha256: be4b23575aac7ebf01f225a241eb7f6b5641eeaf43c6a8613510fc2f8cf187d1 url: "https://pub.dev" source: hosted - version: "2.4.0" + version: "2.5.0" logging: dependency: transitive description: @@ -1690,10 +1690,10 @@ packages: dependency: transitive description: name: url_launcher_linux - sha256: e2b9622b4007f97f504cd64c0128309dfb978ae66adbe944125ed9e1750f06af + sha256: "4e9ba368772369e3e08f231d2301b4ef72b9ff87c31192ef471b380ef29a4935" url: "https://pub.dev" source: hosted - version: "3.2.0" + version: "3.2.1" url_launcher_macos: dependency: transitive description: @@ -1762,10 +1762,10 @@ packages: dependency: "direct main" description: name: vector_tile_renderer - sha256: b58fa02b472ced87de00de2b4d5837576239bddb21b562481f25bde39bd117ae + sha256: "89746f1108eccbc0b6f33fbbef3fcf394cda3733fc0d5064ea03d53a459b56d3" url: "https://pub.dev" source: hosted - version: "5.2.0" + version: "5.2.1" vm_service: dependency: transitive description: @@ -1896,4 +1896,4 @@ packages: version: "3.1.2" sdks: dart: ">=3.5.0 <4.0.0" - flutter: ">=3.24.4" + flutter: ">=3.24.5" diff --git a/pubspec.yaml b/pubspec.yaml index c441f1930..576e6c6eb 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -13,7 +13,7 @@ publish_to: none environment: # this project bundles Flutter SDK via `flutter_wrapper` # cf https://github.com/passsy/flutter_wrapper - flutter: 3.24.4 + flutter: 3.24.5 sdk: '>=3.5.0 <4.0.0' # use `scripts/apply_flavor_{flavor}.sh` to set the right dependencies for the flavor diff --git a/shaders.sksl.json b/shaders.sksl.json index d87aea7e6..d9a1de377 100644 --- a/shaders.sksl.json +++ b/shaders.sksl.json @@ -1 +1 @@ -{"platform":"android","name":"XQ DE72","engineRevision":"db49896cf25ceabc44096d5f088d86414e05a7aa","data":{"AYQA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAAAAMYAAAAAAAQAAAABAMQAAAAA":"DAAAAExTS1MlAgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0NCB1bG9jYWxNYXRyaXhfUzA7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiBmbG9hdDQgaW5DaXJjbGVFZGdlOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIENpcmNsZUdlb21ldHJ5UHJvY2Vzc29yCgl2aW5DaXJjbGVFZGdlX1MwID0gaW5DaXJjbGVFZGdlOwoJdmluQ29sb3JfUzAgPSBpbkNvbG9yOwoJZmxvYXQyIF90bXBfMF9pblBvc2l0aW9uID0gaW5Qb3NpdGlvbjsKCWZsb2F0MiBfdG1wXzFfaW5Qb3NpdGlvbiA9IHVsb2NhbE1hdHJpeF9TMC54eiAqIGluUG9zaXRpb24gKyB1bG9jYWxNYXRyaXhfUzAueXc7Cglza19Qb3NpdGlvbiA9IF90bXBfMF9pblBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAAAEMCAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIENpcmNsZUdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDQgY2lyY2xlRWRnZTsKCWNpcmNsZUVkZ2UgPSB2aW5DaXJjbGVFZGdlX1MwOwoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZpbkNvbG9yX1MwOwoJZmxvYXQgZCA9IGxlbmd0aChjaXJjbGVFZGdlLnh5KTsKCWhhbGYgZGlzdGFuY2VUb091dGVyRWRnZSA9IGhhbGYoY2lyY2xlRWRnZS56ICogKDEuMCAtIGQpKTsKCWhhbGYgZWRnZUFscGhhID0gc2F0dXJhdGUoZGlzdGFuY2VUb091dGVyRWRnZSk7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGVkZ2VBbHBoYSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADAAAAGluQ2lyY2xlRWRnZQAAAAA=","B2ABSAAABQAAIAABBYAAB7777777777774ABICAAAAAAAAAAAAAABGABAAAAAEAAAAAIBEABAAAAA":"DAAAAExTS1PDAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGhhbGY0IHVDb2xvcl9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGYgaW5Db3ZlcmFnZTsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBEZWZhdWx0R2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IGNvbG9yID0gdUNvbG9yX1MwOwoJY29sb3IgPSBjb2xvciAqIGluQ292ZXJhZ2U7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCWZsb2F0MiBfdG1wXzFfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8zX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBfdG1wXzFfaW5Qb3NpdGlvbi54eTAxOwp9CgAAAAAAUQEAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQpub3BlcnNwZWN0aXZlIGluIGhhbGY0IHZjb2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIERlZmF1bHRHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAoAAABpblBvc2l0aW9uAAAKAAAAaW5Db3ZlcmFnZQAAAAAAAA==","GZIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAIIBAAAABAAAAALIEAAAAAAAAAAAAAABQAMAAAABAAAAAAABBAMAAAAA":"DAAAAExTS1PIAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfMl9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzEpICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAL8CAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7Cm5vcGVyc3BlY3RpdmUgaW4gaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MxLCB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMCkucnJycjsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzAoX2lucHV0KTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IE1hdHJpeEVmZmVjdF9TMShvdXRwdXRDb3ZlcmFnZV9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","GZJAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAABAAAAAABBAMABQAMAAAABAAAAAAABBAMAAA":"DAAAAExTS1N3AQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgcG9zaXRpb247CmluIGhhbGY0IGNvbG9yOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7Cgl2bG9jYWxDb29yZF9TMCA9IGxvY2FsQ29vcmQ7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cn0KAAAAAAApAgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQyIHZsb2NhbENvb3JkX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJZmxvYXQyIHRleENvb3JkOwoJdGV4Q29vcmQgPSB2bG9jYWxDb29yZF9TMDsKCW91dHB1dENvbG9yX1MwID0gKGJsZW5kX21vZHVsYXRlKHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMCwgdGV4Q29vcmQpLCBvdXRwdXRDb2xvcl9TMCkpOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","DAQAAAAAAAAAAAAAAJQAAIGAAEACBYQCAGAEFAIBAAAAAABAAAAAAAAAAAAAAMYAAAAAAAQAAAABAMQAAAAA":"DAAAAExTS1N4AgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0MiB1QXRsYXNTaXplSW52X1MwOwppbiBmbG9hdDIgaW5Qb3NpdGlvbjsKaW4gaGFsZjQgaW5Db2xvcjsKaW4gdXNob3J0MiBpblRleHR1cmVDb29yZHM7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQgdlRleEluZGV4X1MwOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgQml0bWFwVGV4dAoJaW50IHRleElkeCA9IDA7CglmbG9hdDIgdW5vcm1UZXhDb29yZHMgPSBmbG9hdDIoaW5UZXh0dXJlQ29vcmRzLngsIGluVGV4dHVyZUNvb3Jkcy55KTsKCXZUZXh0dXJlQ29vcmRzX1MwID0gdW5vcm1UZXhDb29yZHMgKiB1QXRsYXNTaXplSW52X1MwOwoJdlRleEluZGV4X1MwID0gZmxvYXQodGV4SWR4KTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzFfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247Cglza19Qb3NpdGlvbiA9IGluUG9zaXRpb24ueHkwMTsKfQoAAAAACwIAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQyIHZUZXh0dXJlQ29vcmRzX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0IHZUZXhJbmRleF9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIEJpdG1hcFRleHQKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWhhbGY0IHRleENvbG9yOwoJewoJCXRleENvbG9yID0gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB2VGV4dHVyZUNvb3Jkc19TMCkucnJycjsKCX0KCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gdGV4Q29sb3I7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADwAAAGluVGV4dHVyZUNvb3JkcwAAAAAA","AYQA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAACABZQA6AAAEAAAAAAAMADAAAAAIAAAAAAAIIDA":"DAAAAExTS1MlAgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0NCB1bG9jYWxNYXRyaXhfUzA7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiBmbG9hdDQgaW5DaXJjbGVFZGdlOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIENpcmNsZUdlb21ldHJ5UHJvY2Vzc29yCgl2aW5DaXJjbGVFZGdlX1MwID0gaW5DaXJjbGVFZGdlOwoJdmluQ29sb3JfUzAgPSBpbkNvbG9yOwoJZmxvYXQyIF90bXBfMF9pblBvc2l0aW9uID0gaW5Qb3NpdGlvbjsKCWZsb2F0MiBfdG1wXzFfaW5Qb3NpdGlvbiA9IHVsb2NhbE1hdHJpeF9TMC54eiAqIGluUG9zaXRpb24gKyB1bG9jYWxNYXRyaXhfUzAueXc7Cglza19Qb3NpdGlvbiA9IF90bXBfMF9pblBvc2l0aW9uLnh5MDE7Cn0KAAAAAQAAAOgDAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQ0IHZpbkNpcmNsZUVkZ2VfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gaGFsZjQgdmluQ29sb3JfUzA7CmhhbGY0IENpcmN1bGFyUlJlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MxLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MxLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CgloYWxmIGFscGhhID0gaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzEueCAtIGxlbmd0aChkeHkpKSk7CglhbHBoYSA9IDEuMCAtIGFscGhhOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQ0IGNpcmNsZUVkZ2U7CgljaXJjbGVFZGdlID0gdmluQ2lyY2xlRWRnZV9TMDsKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWZsb2F0IGQgPSBsZW5ndGgoY2lyY2xlRWRnZS54eSk7CgloYWxmIGRpc3RhbmNlVG9PdXRlckVkZ2UgPSBoYWxmKGNpcmNsZUVkZ2UueiAqICgxLjAgLSBkKSk7CgloYWxmIGVkZ2VBbHBoYSA9IHNhdHVyYXRlKGRpc3RhbmNlVG9PdXRlckVkZ2UpOwoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChlZGdlQWxwaGEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQ2lyY3VsYXJSUmVjdF9TMShvdXRwdXRDb3ZlcmFnZV9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADAAAAGluQ2lyY2xlRWRnZQAAAAA=","DAQAAAAAAAAAAAAAAJQAAIGAAEACBYQCAGAEFAIBAAAAAABAAAAAAAAAAAACAB4QA4AAAEAAAAAAAMADAAAAAIAAAAAAAIID":"DAAAAExTS1N4AgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0MiB1QXRsYXNTaXplSW52X1MwOwppbiBmbG9hdDIgaW5Qb3NpdGlvbjsKaW4gaGFsZjQgaW5Db2xvcjsKaW4gdXNob3J0MiBpblRleHR1cmVDb29yZHM7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQgdlRleEluZGV4X1MwOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgQml0bWFwVGV4dAoJaW50IHRleElkeCA9IDA7CglmbG9hdDIgdW5vcm1UZXhDb29yZHMgPSBmbG9hdDIoaW5UZXh0dXJlQ29vcmRzLngsIGluVGV4dHVyZUNvb3Jkcy55KTsKCXZUZXh0dXJlQ29vcmRzX1MwID0gdW5vcm1UZXhDb29yZHMgKiB1QXRsYXNTaXplSW52X1MwOwoJdlRleEluZGV4X1MwID0gZmxvYXQodGV4SWR4KTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzFfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247Cglza19Qb3NpdGlvbiA9IGluUG9zaXRpb24ueHkwMTsKfQoBAAAAmgMAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQp1bmlmb3JtIGZsb2F0NCB1aW5uZXJSZWN0X1MxOwp1bmlmb3JtIGhhbGYyIHVyYWRpdXNQbHVzSGFsZl9TMTsKc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdCB2VGV4SW5kZXhfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gaGFsZjQgdmluQ29sb3JfUzA7CmhhbGY0IENpcmN1bGFyUlJlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MxLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MxLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CgloYWxmIGFscGhhID0gaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzEueCAtIGxlbmd0aChkeHkpKSk7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIEJpdG1hcFRleHQKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWhhbGY0IHRleENvbG9yOwoJewoJCXRleENvbG9yID0gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB2VGV4dHVyZUNvb3Jkc19TMCkucnJycjsKCX0KCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gdGV4Q29sb3I7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBDaXJjdWxhclJSZWN0X1MxKG91dHB1dENvdmVyYWdlX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACgAAAGluUG9zaXRpb24AAAcAAABpbkNvbG9yAA8AAABpblRleHR1cmVDb29yZHMAAAAAAA==","AYQQ5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAAAAMYAAAAAAAQAAAABAMQAAAAA":"DAAAAExTS1MlAgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0NCB1bG9jYWxNYXRyaXhfUzA7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiBmbG9hdDQgaW5DaXJjbGVFZGdlOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIENpcmNsZUdlb21ldHJ5UHJvY2Vzc29yCgl2aW5DaXJjbGVFZGdlX1MwID0gaW5DaXJjbGVFZGdlOwoJdmluQ29sb3JfUzAgPSBpbkNvbG9yOwoJZmxvYXQyIF90bXBfMF9pblBvc2l0aW9uID0gaW5Qb3NpdGlvbjsKCWZsb2F0MiBfdG1wXzFfaW5Qb3NpdGlvbiA9IHVsb2NhbE1hdHJpeF9TMC54eiAqIGluUG9zaXRpb24gKyB1bG9jYWxNYXRyaXhfUzAueXc7Cglza19Qb3NpdGlvbiA9IF90bXBfMF9pblBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAAANQCAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIENpcmNsZUdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDQgY2lyY2xlRWRnZTsKCWNpcmNsZUVkZ2UgPSB2aW5DaXJjbGVFZGdlX1MwOwoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZpbkNvbG9yX1MwOwoJZmxvYXQgZCA9IGxlbmd0aChjaXJjbGVFZGdlLnh5KTsKCWhhbGYgZGlzdGFuY2VUb091dGVyRWRnZSA9IGhhbGYoY2lyY2xlRWRnZS56ICogKDEuMCAtIGQpKTsKCWhhbGYgZWRnZUFscGhhID0gc2F0dXJhdGUoZGlzdGFuY2VUb091dGVyRWRnZSk7CgloYWxmIGRpc3RhbmNlVG9Jbm5lckVkZ2UgPSBoYWxmKGNpcmNsZUVkZ2UueiAqIChkIC0gY2lyY2xlRWRnZS53KSk7CgloYWxmIGlubmVyQWxwaGEgPSBzYXR1cmF0ZShkaXN0YW5jZVRvSW5uZXJFZGdlKTsKCWVkZ2VBbHBoYSAqPSBpbm5lckFscGhhOwoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChlZGdlQWxwaGEpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADAAAAGluQ2lyY2xlRWRnZQAAAAA=","GYJAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAQAAAAAAQQGAAYAGAAAAAQAAAAAAAQQGAAA":"DAAAAExTS1MwAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgcG9zaXRpb247CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmxvY2FsQ29vcmRfUzAgPSBsb2NhbENvb3JkOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAADvAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwID0gaGFsZjQoMSk7CglmbG9hdDIgdGV4Q29vcmQ7Cgl0ZXhDb29yZCA9IHZsb2NhbENvb3JkX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSAoYmxlbmRfbW9kdWxhdGUoc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB0ZXhDb29yZCksIGhhbGY0KDEpKSk7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACAAAAHBvc2l0aW9uCgAAAGxvY2FsQ29vcmQAAAAAAAA=","GZIACAAAABQAAGAAAQ4AAAAAGQQAARC4GAAAIOCAAD6P7777777777YDAAAAAAAAAAAJIBBYGQ467YIAAAAAAQAAAAAMACTRNBZN5QYBAAAAAAAAAAAIAGIAAAAAAAIAAAAAQGIAAAAAA":"DAAAAExTS1M7AgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQgY292ZXJhZ2U7CmluIGhhbGY0IGNvbG9yOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdCB2Y292ZXJhZ2VfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDIgcG9zaXRpb24gPSBwb3NpdGlvbi54eTsKCXZjb2xvcl9TMCA9IGNvbG9yOwoJdmNvdmVyYWdlX1MwID0gY292ZXJhZ2U7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAAAJhwAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQpmbG9hdDQgZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzA7CmZsb2F0NCBmcmFnQ29sb3JfUzFfYzA7CmZsb2F0IHVfYWxwaGFfUzFfYzA7CmZsb2F0IHVfc3BhcmtsZV9hbHBoYV9TMV9jMDsKZmxvYXQgdV9ibHVyX1MxX2MwOwpmbG9hdCB1X3JhZGl1c19zY2FsZV9TMV9jMDsKdW5pZm9ybSBmbG9hdDQgdV9jb2xvcl9TMV9jMDsKdW5pZm9ybSBmbG9hdDQgdV9jb21wb3NpdGVfMV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jZW50ZXJfUzFfYzA7CnVuaWZvcm0gZmxvYXQgdV9tYXhfcmFkaXVzX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3Jlc29sdXRpb25fc2NhbGVfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfbm9pc2Vfc2NhbGVfUzFfYzA7CnVuaWZvcm0gZmxvYXQgdV9ub2lzZV9waGFzZV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jaXJjbGUxX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NpcmNsZTJfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2lyY2xlM19TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yb3RhdGlvbjFfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcm90YXRpb24yX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3JvdGF0aW9uM19TMV9jMDsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxOwpub3BlcnNwZWN0aXZlIGluIGhhbGY0IHZjb2xvcl9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdCB2Y292ZXJhZ2VfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwpmbG9hdDIgRkxUX2ZsdXR0ZXJfbG9jYWxfRmx1dHRlckZyYWdDb29yZF9TMV9jMCgpOwpmbG9hdDJ4MiBGTFRfZmx1dHRlcl9sb2NhbF9yb3RhdGUyZF9TMV9jMChmbG9hdDIgcmFkKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgYmx1cik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKGZsb2F0MiByZXNvbHV0aW9uLCBpbm91dCBmbG9hdDIgcCwgZmxvYXQyIHh5LCBmbG9hdDIgcm90YXRpb24sIGZsb2F0IGNlbGxfZGlhbWV0ZXIpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90dXJidWxlbmNlX1MxX2MwKGZsb2F0MiB1dik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfcmluZ19TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCB0aGlja25lc3MsIGZsb2F0IGJsdXIpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90cmlhbmdsZV9ub2lzZV9TMV9jMChpbm91dCBmbG9hdDIgbik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChmbG9hdCB2LCBmbG9hdCBsLCBmbG9hdCBoKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc3BhcmtsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0IHQpOwp2b2lkIEZMVF9tYWluX1MxX2MwKCk7CmZsb2F0MiBGTFRfZmx1dHRlcl9sb2NhbF9GbHV0dGVyRnJhZ0Nvb3JkX1MxX2MwKCkgCnsKCXJldHVybiBmbHV0dGVyX0ZyYWdDb29yZF9TMV9jMC54eTsKfQpmbG9hdDJ4MiBGTFRfZmx1dHRlcl9sb2NhbF9yb3RhdGUyZF9TMV9jMChmbG9hdDIgcmFkKSAKewoJcmV0dXJuIGZsb2F0MngyKHJhZC54LCAtcmFkLnksIHJhZC55LCByYWQueCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgYmx1cikgCnsKCWZsb2F0IGJsdXJfaGFsZiA9IGJsdXIgKiAwLjU7CglmbG9hdCBkID0gZGlzdGFuY2UodXYsIHh5KTsKCXJldHVybiAxLjAgLSBzbW9vdGhzdGVwKDEuMCAtIGJsdXJfaGFsZiwgMS4wICsgYmx1cl9oYWxmLCBkIC8gcmFkaXVzKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChmbG9hdDIgcmVzb2x1dGlvbiwgaW5vdXQgZmxvYXQyIHAsIGZsb2F0MiB4eSwgZmxvYXQyIHJvdGF0aW9uLCBmbG9hdCBjZWxsX2RpYW1ldGVyKSAKewoJZmxvYXQyIHBhcmFtID0gcm90YXRpb247CglwID0gRkxUX2ZsdXR0ZXJfbG9jYWxfcm90YXRlMmRfUzFfYzAocGFyYW0pICogKHh5IC0gcCkgKyB4eTsKCXAgPSBtb2QocCwgZmxvYXQyKGNlbGxfZGlhbWV0ZXIpKSAvIHJlc29sdXRpb247CglmbG9hdCBjZWxsX3V2ID0gKGNlbGxfZGlhbWV0ZXIgLyByZXNvbHV0aW9uLnkpICogMC41OwoJZmxvYXQgciA9IDAuNjUgKiBjZWxsX3V2OwoJZmxvYXQyIHBhcmFtXzEgPSBwOwoJZmxvYXQyIHBhcmFtXzIgPSBmbG9hdDIoY2VsbF91dik7CglmbG9hdCBwYXJhbV8zID0gcjsKCWZsb2F0IHBhcmFtXzQgPSByICogNTAuMDsKCXJldHVybiBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zLCBwYXJhbV80KTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90dXJidWxlbmNlX1MxX2MwKGZsb2F0MiB1dikgCnsKCWZsb2F0MiB1dl9zY2FsZSA9IHV2ICogZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW0gPSBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbV8xID0gdXZfc2NhbGU7CglmbG9hdDIgcGFyYW1fMiA9IHVfY2lyY2xlMV9TMV9jMDsKCWZsb2F0MiBwYXJhbV8zID0gdV9yb3RhdGlvbjFfUzFfYzA7CglmbG9hdCBwYXJhbV80ID0gMC4xNzsKCWZsb2F0IF8zMTkgPSBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChwYXJhbSwgcGFyYW1fMSwgcGFyYW1fMiwgcGFyYW1fMywgcGFyYW1fNCk7CglmbG9hdCBnMSA9IF8zMTk7CglmbG9hdDIgcGFyYW1fNSA9IGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtXzYgPSB1dl9zY2FsZTsKCWZsb2F0MiBwYXJhbV83ID0gdV9jaXJjbGUyX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzggPSB1X3JvdGF0aW9uMl9TMV9jMDsKCWZsb2F0IHBhcmFtXzkgPSAwLjI7CglmbG9hdCBfMzMxID0gRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAocGFyYW1fNSwgcGFyYW1fNiwgcGFyYW1fNywgcGFyYW1fOCwgcGFyYW1fOSk7CglmbG9hdCBnMiA9IF8zMzE7CglmbG9hdDIgcGFyYW1fMTAgPSBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbV8xMSA9IHV2X3NjYWxlOwoJZmxvYXQyIHBhcmFtXzEyID0gdV9jaXJjbGUzX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzEzID0gdV9yb3RhdGlvbjNfUzFfYzA7CglmbG9hdCBwYXJhbV8xNCA9IDAuMjc1OwoJZmxvYXQgXzM0NCA9IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKHBhcmFtXzEwLCBwYXJhbV8xMSwgcGFyYW1fMTIsIHBhcmFtXzEzLCBwYXJhbV8xNCk7CglmbG9hdCBnMyA9IF8zNDQ7CglmbG9hdCB2ID0gKChnMSAqIGcxICsgZzIpIC0gZzMpICogMC41OwoJcmV0dXJuIGNsYW1wKDAuNDUgKyAwLjggKiB2LCAwLjAsIDEuMCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9yaW5nX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IHRoaWNrbmVzcywgZmxvYXQgYmx1cikgCnsKCWZsb2F0MiBwYXJhbSA9IHV2OwoJZmxvYXQyIHBhcmFtXzEgPSB4eTsKCWZsb2F0IHBhcmFtXzIgPSByYWRpdXMgKyB0aGlja25lc3M7CglmbG9hdCBwYXJhbV8zID0gYmx1cjsKCWZsb2F0IGNpcmNsZV9vdXRlciA9IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtLCBwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zKTsKCWZsb2F0MiBwYXJhbV80ID0gdXY7CglmbG9hdDIgcGFyYW1fNSA9IHh5OwoJZmxvYXQgcGFyYW1fNiA9IG1heChyYWRpdXMgLSB0aGlja25lc3MsIDAuMCk7CglmbG9hdCBwYXJhbV83ID0gYmx1cjsKCWZsb2F0IGNpcmNsZV9pbm5lciA9IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtXzQsIHBhcmFtXzUsIHBhcmFtXzYsIHBhcmFtXzcpOwoJcmV0dXJuIGNsYW1wKGNpcmNsZV9vdXRlciAtIGNpcmNsZV9pbm5lciwgMC4wLCAxLjApOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RyaWFuZ2xlX25vaXNlX1MxX2MwKGlub3V0IGZsb2F0MiBuKSAKewoJbiA9IGZyYWN0KG4gKiBmbG9hdDIoNS4zOTg3LCA1LjQ0MjEpKTsKCW4gKz0gZmxvYXQyKGRvdChuLnl4LCBuICsgZmxvYXQyKDIxLjUzNTEsIDE0LjMxMzcpKSk7CglmbG9hdCB4eSA9IG4ueCAqIG4ueTsKCXJldHVybiAoZnJhY3QoeHkgKiA5NS40MzA3KSArIGZyYWN0KHh5ICogNzUuMDQ5NjEpKSAtIDEuMDsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAoZmxvYXQgdiwgZmxvYXQgbCwgZmxvYXQgaCkgCnsKCXJldHVybiBzdGVwKGwsIHYpICogKDEuMCAtIHN0ZXAoaCwgdikpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NwYXJrbGVfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdCB0KSAKewoJZmxvYXQyIHBhcmFtID0gdXY7CglmbG9hdCBfMjQyID0gRkxUX2ZsdXR0ZXJfbG9jYWxfdHJpYW5nbGVfbm9pc2VfUzFfYzAocGFyYW0pOwoJZmxvYXQgbiA9IF8yNDI7CglmbG9hdCBwYXJhbV8xID0gbjsKCWZsb2F0IHBhcmFtXzIgPSAwLjA7CglmbG9hdCBwYXJhbV8zID0gMC4wNTsKCWZsb2F0IHMgPSBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAocGFyYW1fMSwgcGFyYW1fMiwgcGFyYW1fMyk7CglmbG9hdCBwYXJhbV80ID0gbiArIHNpbigzLjE0MTU5Mjc0ICogKHQgKyAwLjM1KSk7CglmbG9hdCBwYXJhbV81ID0gMC4xOwoJZmxvYXQgcGFyYW1fNiA9IDAuMTU7CglzICs9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV80LCBwYXJhbV81LCBwYXJhbV82KTsKCWZsb2F0IHBhcmFtXzcgPSBuICsgc2luKDMuMTQxNTkyNzQgKiAodCArIDAuNykpOwoJZmxvYXQgcGFyYW1fOCA9IDAuMjsKCWZsb2F0IHBhcmFtXzkgPSAwLjI1OwoJcyArPSBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAocGFyYW1fNywgcGFyYW1fOCwgcGFyYW1fOSk7CglmbG9hdCBwYXJhbV8xMCA9IG4gKyBzaW4oMy4xNDE1OTI3NCAqICh0ICsgMS4wNSkpOwoJZmxvYXQgcGFyYW1fMTEgPSAwLjM7CglmbG9hdCBwYXJhbV8xMiA9IDAuMzU7CglzICs9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV8xMCwgcGFyYW1fMTEsIHBhcmFtXzEyKTsKCXJldHVybiBjbGFtcChzLCAwLjAsIDEuMCkgKiAwLjU1Owp9CnZvaWQgRkxUX21haW5fUzFfYzAoKSAKewoJdV9hbHBoYV9TMV9jMCA9IHVfY29tcG9zaXRlXzFfUzFfYzAueDsKCXVfc3BhcmtsZV9hbHBoYV9TMV9jMCA9IHVfY29tcG9zaXRlXzFfUzFfYzAueTsKCXVfYmx1cl9TMV9jMCA9IHVfY29tcG9zaXRlXzFfUzFfYzAuejsKCXVfcmFkaXVzX3NjYWxlX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC53OwoJZmxvYXQyIHAgPSBGTFRfZmx1dHRlcl9sb2NhbF9GbHV0dGVyRnJhZ0Nvb3JkX1MxX2MwKCk7CglmbG9hdDIgdXZfMSA9IHAgKiB1X3Jlc29sdXRpb25fc2NhbGVfUzFfYzA7CglmbG9hdDIgZGVuc2l0eV91diA9IHV2XzEgLSBtb2QocCwgdV9ub2lzZV9zY2FsZV9TMV9jMCk7CglmbG9hdCByYWRpdXMgPSB1X21heF9yYWRpdXNfUzFfYzAgKiB1X3JhZGl1c19zY2FsZV9TMV9jMDsKCWZsb2F0MiBwYXJhbV8xMyA9IHV2XzE7CglmbG9hdCB0dXJidWxlbmNlID0gRkxUX2ZsdXR0ZXJfbG9jYWxfdHVyYnVsZW5jZV9TMV9jMChwYXJhbV8xMyk7CglmbG9hdDIgcGFyYW1fMTQgPSBwOwoJZmxvYXQyIHBhcmFtXzE1ID0gdV9jZW50ZXJfUzFfYzA7CglmbG9hdCBwYXJhbV8xNiA9IHJhZGl1czsKCWZsb2F0IHBhcmFtXzE3ID0gMC4wNSAqIHVfbWF4X3JhZGl1c19TMV9jMDsKCWZsb2F0IHBhcmFtXzE4ID0gdV9ibHVyX1MxX2MwOwoJZmxvYXQgcmluZyA9IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfcmluZ19TMV9jMChwYXJhbV8xNCwgcGFyYW1fMTUsIHBhcmFtXzE2LCBwYXJhbV8xNywgcGFyYW1fMTgpOwoJZmxvYXQyIHBhcmFtXzE5ID0gZGVuc2l0eV91djsKCWZsb2F0IHBhcmFtXzIwID0gdV9ub2lzZV9waGFzZV9TMV9jMDsKCWZsb2F0IHNwYXJrbGUgPSAoKEZMVF9mbHV0dGVyX2xvY2FsX3NwYXJrbGVfUzFfYzAocGFyYW1fMTksIHBhcmFtXzIwKSAqIHJpbmcpICogdHVyYnVsZW5jZSkgKiB1X3NwYXJrbGVfYWxwaGFfUzFfYzA7CglmbG9hdDIgcGFyYW1fMjEgPSBwOwoJZmxvYXQyIHBhcmFtXzIyID0gdV9jZW50ZXJfUzFfYzA7CglmbG9hdCBwYXJhbV8yMyA9IHJhZGl1czsKCWZsb2F0IHBhcmFtXzI0ID0gdV9ibHVyX1MxX2MwOwoJZmxvYXQgd2F2ZV9hbHBoYSA9IChGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChwYXJhbV8yMSwgcGFyYW1fMjIsIHBhcmFtXzIzLCBwYXJhbV8yNCkgKiB1X2FscGhhX1MxX2MwKSAqIHVfY29sb3JfUzFfYzAudzsKCWZsb2F0NCB3YXZlX2NvbG9yID0gZmxvYXQ0KHVfY29sb3JfUzFfYzAueHl6ICogd2F2ZV9hbHBoYSwgd2F2ZV9hbHBoYSk7CglmcmFnQ29sb3JfUzFfYzAgPSBtaXgod2F2ZV9jb2xvciwgZmxvYXQ0KDEuMCksIGZsb2F0NChzcGFya2xlKSk7Cn0KaGFsZjQgcnVudGltZV9zaGFkZXJfUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF8wX2luQ29sb3IgPSBfaW5wdXQ7CglmbG9hdDIgX3RtcF8xX2Nvb3JkcyA9IHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwoJZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzAgPSBmbG9hdDQoX3RtcF8xX2Nvb3JkcywgMC4wLCAwLjApOwoJRkxUX21haW5fUzFfYzAoKTsKCXJldHVybiBoYWxmNChoYWxmNChmcmFnQ29sb3JfUzFfYzApKTsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIHJ1bnRpbWVfc2hhZGVyX1MxX2MwKF9pbnB1dCk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWZsb2F0IGNvdmVyYWdlID0gdmNvdmVyYWdlX1MwOwoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChjb3ZlcmFnZSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBNYXRyaXhFZmZlY3RfUzEob3V0cHV0Q29sb3JfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAAcG9zaXRpb24IAAAAY292ZXJhZ2UFAAAAY29sb3IAAAAKAAAAbG9jYWxDb29yZAAAAAAAAA==","GZIACAAAABQAAGAAAQ4AAAAAGQQAARC4GAAAIOCAAD6P7777777777YDAAAAAAAAAAAJQBBYGQ467YIAAAAAAQAAAAAMACTRNBZN5QYBAAAAAAAAAAAIAA6IAMAAACAAAAAABGABAAAAAEAAAAAIBEABAA":"DAAAAExTS1M7AgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQgY292ZXJhZ2U7CmluIGhhbGY0IGNvbG9yOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdCB2Y292ZXJhZ2VfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDIgcG9zaXRpb24gPSBwb3NpdGlvbi54eTsKCXZjb2xvcl9TMCA9IGNvbG9yOwoJdmNvdmVyYWdlX1MwID0gY292ZXJhZ2U7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgABAAAAtR0AACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQpmbG9hdDQgZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzA7CmZsb2F0NCBmcmFnQ29sb3JfUzFfYzA7CmZsb2F0IHVfYWxwaGFfUzFfYzA7CmZsb2F0IHVfc3BhcmtsZV9hbHBoYV9TMV9jMDsKZmxvYXQgdV9ibHVyX1MxX2MwOwpmbG9hdCB1X3JhZGl1c19zY2FsZV9TMV9jMDsKdW5pZm9ybSBmbG9hdDQgdV9jb2xvcl9TMV9jMDsKdW5pZm9ybSBmbG9hdDQgdV9jb21wb3NpdGVfMV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jZW50ZXJfUzFfYzA7CnVuaWZvcm0gZmxvYXQgdV9tYXhfcmFkaXVzX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3Jlc29sdXRpb25fc2NhbGVfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfbm9pc2Vfc2NhbGVfUzFfYzA7CnVuaWZvcm0gZmxvYXQgdV9ub2lzZV9waGFzZV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jaXJjbGUxX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NpcmNsZTJfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2lyY2xlM19TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yb3RhdGlvbjFfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcm90YXRpb24yX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3JvdGF0aW9uM19TMV9jMDsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxOwp1bmlmb3JtIGZsb2F0NCB1aW5uZXJSZWN0X1MyOwp1bmlmb3JtIGhhbGYyIHVyYWRpdXNQbHVzSGFsZl9TMjsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQgdmNvdmVyYWdlX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKZmxvYXQyIEZMVF9mbHV0dGVyX2xvY2FsX0ZsdXR0ZXJGcmFnQ29vcmRfUzFfYzAoKTsKZmxvYXQyeDIgRkxUX2ZsdXR0ZXJfbG9jYWxfcm90YXRlMmRfUzFfYzAoZmxvYXQyIHJhZCk7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IGJsdXIpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChmbG9hdDIgcmVzb2x1dGlvbiwgaW5vdXQgZmxvYXQyIHAsIGZsb2F0MiB4eSwgZmxvYXQyIHJvdGF0aW9uLCBmbG9hdCBjZWxsX2RpYW1ldGVyKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHVyYnVsZW5jZV9TMV9jMChmbG9hdDIgdXYpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X3JpbmdfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgdGhpY2tuZXNzLCBmbG9hdCBibHVyKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHJpYW5nbGVfbm9pc2VfUzFfYzAoaW5vdXQgZmxvYXQyIG4pOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAoZmxvYXQgdiwgZmxvYXQgbCwgZmxvYXQgaCk7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NwYXJrbGVfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdCB0KTsKdm9pZCBGTFRfbWFpbl9TMV9jMCgpOwpmbG9hdDIgRkxUX2ZsdXR0ZXJfbG9jYWxfRmx1dHRlckZyYWdDb29yZF9TMV9jMCgpIAp7CglyZXR1cm4gZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzAueHk7Cn0KZmxvYXQyeDIgRkxUX2ZsdXR0ZXJfbG9jYWxfcm90YXRlMmRfUzFfYzAoZmxvYXQyIHJhZCkgCnsKCXJldHVybiBmbG9hdDJ4MihyYWQueCwgLXJhZC55LCByYWQueSwgcmFkLngpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IGJsdXIpIAp7CglmbG9hdCBibHVyX2hhbGYgPSBibHVyICogMC41OwoJZmxvYXQgZCA9IGRpc3RhbmNlKHV2LCB4eSk7CglyZXR1cm4gMS4wIC0gc21vb3Roc3RlcCgxLjAgLSBibHVyX2hhbGYsIDEuMCArIGJsdXJfaGFsZiwgZCAvIHJhZGl1cyk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAoZmxvYXQyIHJlc29sdXRpb24sIGlub3V0IGZsb2F0MiBwLCBmbG9hdDIgeHksIGZsb2F0MiByb3RhdGlvbiwgZmxvYXQgY2VsbF9kaWFtZXRlcikgCnsKCWZsb2F0MiBwYXJhbSA9IHJvdGF0aW9uOwoJcCA9IEZMVF9mbHV0dGVyX2xvY2FsX3JvdGF0ZTJkX1MxX2MwKHBhcmFtKSAqICh4eSAtIHApICsgeHk7CglwID0gbW9kKHAsIGZsb2F0MihjZWxsX2RpYW1ldGVyKSkgLyByZXNvbHV0aW9uOwoJZmxvYXQgY2VsbF91diA9IChjZWxsX2RpYW1ldGVyIC8gcmVzb2x1dGlvbi55KSAqIDAuNTsKCWZsb2F0IHIgPSAwLjY1ICogY2VsbF91djsKCWZsb2F0MiBwYXJhbV8xID0gcDsKCWZsb2F0MiBwYXJhbV8yID0gZmxvYXQyKGNlbGxfdXYpOwoJZmxvYXQgcGFyYW1fMyA9IHI7CglmbG9hdCBwYXJhbV80ID0gciAqIDUwLjA7CglyZXR1cm4gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW1fMSwgcGFyYW1fMiwgcGFyYW1fMywgcGFyYW1fNCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHVyYnVsZW5jZV9TMV9jMChmbG9hdDIgdXYpIAp7CglmbG9hdDIgdXZfc2NhbGUgPSB1diAqIGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtID0gZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW1fMSA9IHV2X3NjYWxlOwoJZmxvYXQyIHBhcmFtXzIgPSB1X2NpcmNsZTFfUzFfYzA7CglmbG9hdDIgcGFyYW1fMyA9IHVfcm90YXRpb24xX1MxX2MwOwoJZmxvYXQgcGFyYW1fNCA9IDAuMTc7CglmbG9hdCBfMzE5ID0gRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAocGFyYW0sIHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMsIHBhcmFtXzQpOwoJZmxvYXQgZzEgPSBfMzE5OwoJZmxvYXQyIHBhcmFtXzUgPSBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbV82ID0gdXZfc2NhbGU7CglmbG9hdDIgcGFyYW1fNyA9IHVfY2lyY2xlMl9TMV9jMDsKCWZsb2F0MiBwYXJhbV84ID0gdV9yb3RhdGlvbjJfUzFfYzA7CglmbG9hdCBwYXJhbV85ID0gMC4yOwoJZmxvYXQgXzMzMSA9IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKHBhcmFtXzUsIHBhcmFtXzYsIHBhcmFtXzcsIHBhcmFtXzgsIHBhcmFtXzkpOwoJZmxvYXQgZzIgPSBfMzMxOwoJZmxvYXQyIHBhcmFtXzEwID0gZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW1fMTEgPSB1dl9zY2FsZTsKCWZsb2F0MiBwYXJhbV8xMiA9IHVfY2lyY2xlM19TMV9jMDsKCWZsb2F0MiBwYXJhbV8xMyA9IHVfcm90YXRpb24zX1MxX2MwOwoJZmxvYXQgcGFyYW1fMTQgPSAwLjI3NTsKCWZsb2F0IF8zNDQgPSBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChwYXJhbV8xMCwgcGFyYW1fMTEsIHBhcmFtXzEyLCBwYXJhbV8xMywgcGFyYW1fMTQpOwoJZmxvYXQgZzMgPSBfMzQ0OwoJZmxvYXQgdiA9ICgoZzEgKiBnMSArIGcyKSAtIGczKSAqIDAuNTsKCXJldHVybiBjbGFtcCgwLjQ1ICsgMC44ICogdiwgMC4wLCAxLjApOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfcmluZ19TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCB0aGlja25lc3MsIGZsb2F0IGJsdXIpIAp7CglmbG9hdDIgcGFyYW0gPSB1djsKCWZsb2F0MiBwYXJhbV8xID0geHk7CglmbG9hdCBwYXJhbV8yID0gcmFkaXVzICsgdGhpY2tuZXNzOwoJZmxvYXQgcGFyYW1fMyA9IGJsdXI7CglmbG9hdCBjaXJjbGVfb3V0ZXIgPSBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChwYXJhbSwgcGFyYW1fMSwgcGFyYW1fMiwgcGFyYW1fMyk7CglmbG9hdDIgcGFyYW1fNCA9IHV2OwoJZmxvYXQyIHBhcmFtXzUgPSB4eTsKCWZsb2F0IHBhcmFtXzYgPSBtYXgocmFkaXVzIC0gdGhpY2tuZXNzLCAwLjApOwoJZmxvYXQgcGFyYW1fNyA9IGJsdXI7CglmbG9hdCBjaXJjbGVfaW5uZXIgPSBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChwYXJhbV80LCBwYXJhbV81LCBwYXJhbV82LCBwYXJhbV83KTsKCXJldHVybiBjbGFtcChjaXJjbGVfb3V0ZXIgLSBjaXJjbGVfaW5uZXIsIDAuMCwgMS4wKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90cmlhbmdsZV9ub2lzZV9TMV9jMChpbm91dCBmbG9hdDIgbikgCnsKCW4gPSBmcmFjdChuICogZmxvYXQyKDUuMzk4NywgNS40NDIxKSk7CgluICs9IGZsb2F0Mihkb3Qobi55eCwgbiArIGZsb2F0MigyMS41MzUxLCAxNC4zMTM3KSkpOwoJZmxvYXQgeHkgPSBuLnggKiBuLnk7CglyZXR1cm4gKGZyYWN0KHh5ICogOTUuNDMwNykgKyBmcmFjdCh4eSAqIDc1LjA0OTYxKSkgLSAxLjA7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKGZsb2F0IHYsIGZsb2F0IGwsIGZsb2F0IGgpIAp7CglyZXR1cm4gc3RlcChsLCB2KSAqICgxLjAgLSBzdGVwKGgsIHYpKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zcGFya2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQgdCkgCnsKCWZsb2F0MiBwYXJhbSA9IHV2OwoJZmxvYXQgXzI0MiA9IEZMVF9mbHV0dGVyX2xvY2FsX3RyaWFuZ2xlX25vaXNlX1MxX2MwKHBhcmFtKTsKCWZsb2F0IG4gPSBfMjQyOwoJZmxvYXQgcGFyYW1fMSA9IG47CglmbG9hdCBwYXJhbV8yID0gMC4wOwoJZmxvYXQgcGFyYW1fMyA9IDAuMDU7CglmbG9hdCBzID0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMpOwoJZmxvYXQgcGFyYW1fNCA9IG4gKyBzaW4oMy4xNDE1OTI3NCAqICh0ICsgMC4zNSkpOwoJZmxvYXQgcGFyYW1fNSA9IDAuMTsKCWZsb2F0IHBhcmFtXzYgPSAwLjE1OwoJcyArPSBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAocGFyYW1fNCwgcGFyYW1fNSwgcGFyYW1fNik7CglmbG9hdCBwYXJhbV83ID0gbiArIHNpbigzLjE0MTU5Mjc0ICogKHQgKyAwLjcpKTsKCWZsb2F0IHBhcmFtXzggPSAwLjI7CglmbG9hdCBwYXJhbV85ID0gMC4yNTsKCXMgKz0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzcsIHBhcmFtXzgsIHBhcmFtXzkpOwoJZmxvYXQgcGFyYW1fMTAgPSBuICsgc2luKDMuMTQxNTkyNzQgKiAodCArIDEuMDUpKTsKCWZsb2F0IHBhcmFtXzExID0gMC4zOwoJZmxvYXQgcGFyYW1fMTIgPSAwLjM1OwoJcyArPSBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAocGFyYW1fMTAsIHBhcmFtXzExLCBwYXJhbV8xMik7CglyZXR1cm4gY2xhbXAocywgMC4wLCAxLjApICogMC41NTsKfQp2b2lkIEZMVF9tYWluX1MxX2MwKCkgCnsKCXVfYWxwaGFfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLng7Cgl1X3NwYXJrbGVfYWxwaGFfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLnk7Cgl1X2JsdXJfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLno7Cgl1X3JhZGl1c19zY2FsZV9TMV9jMCA9IHVfY29tcG9zaXRlXzFfUzFfYzAudzsKCWZsb2F0MiBwID0gRkxUX2ZsdXR0ZXJfbG9jYWxfRmx1dHRlckZyYWdDb29yZF9TMV9jMCgpOwoJZmxvYXQyIHV2XzEgPSBwICogdV9yZXNvbHV0aW9uX3NjYWxlX1MxX2MwOwoJZmxvYXQyIGRlbnNpdHlfdXYgPSB1dl8xIC0gbW9kKHAsIHVfbm9pc2Vfc2NhbGVfUzFfYzApOwoJZmxvYXQgcmFkaXVzID0gdV9tYXhfcmFkaXVzX1MxX2MwICogdV9yYWRpdXNfc2NhbGVfUzFfYzA7CglmbG9hdDIgcGFyYW1fMTMgPSB1dl8xOwoJZmxvYXQgdHVyYnVsZW5jZSA9IEZMVF9mbHV0dGVyX2xvY2FsX3R1cmJ1bGVuY2VfUzFfYzAocGFyYW1fMTMpOwoJZmxvYXQyIHBhcmFtXzE0ID0gcDsKCWZsb2F0MiBwYXJhbV8xNSA9IHVfY2VudGVyX1MxX2MwOwoJZmxvYXQgcGFyYW1fMTYgPSByYWRpdXM7CglmbG9hdCBwYXJhbV8xNyA9IDAuMDUgKiB1X21heF9yYWRpdXNfUzFfYzA7CglmbG9hdCBwYXJhbV8xOCA9IHVfYmx1cl9TMV9jMDsKCWZsb2F0IHJpbmcgPSBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X3JpbmdfUzFfYzAocGFyYW1fMTQsIHBhcmFtXzE1LCBwYXJhbV8xNiwgcGFyYW1fMTcsIHBhcmFtXzE4KTsKCWZsb2F0MiBwYXJhbV8xOSA9IGRlbnNpdHlfdXY7CglmbG9hdCBwYXJhbV8yMCA9IHVfbm9pc2VfcGhhc2VfUzFfYzA7CglmbG9hdCBzcGFya2xlID0gKChGTFRfZmx1dHRlcl9sb2NhbF9zcGFya2xlX1MxX2MwKHBhcmFtXzE5LCBwYXJhbV8yMCkgKiByaW5nKSAqIHR1cmJ1bGVuY2UpICogdV9zcGFya2xlX2FscGhhX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzIxID0gcDsKCWZsb2F0MiBwYXJhbV8yMiA9IHVfY2VudGVyX1MxX2MwOwoJZmxvYXQgcGFyYW1fMjMgPSByYWRpdXM7CglmbG9hdCBwYXJhbV8yNCA9IHVfYmx1cl9TMV9jMDsKCWZsb2F0IHdhdmVfYWxwaGEgPSAoRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW1fMjEsIHBhcmFtXzIyLCBwYXJhbV8yMywgcGFyYW1fMjQpICogdV9hbHBoYV9TMV9jMCkgKiB1X2NvbG9yX1MxX2MwLnc7CglmbG9hdDQgd2F2ZV9jb2xvciA9IGZsb2F0NCh1X2NvbG9yX1MxX2MwLnh5eiAqIHdhdmVfYWxwaGEsIHdhdmVfYWxwaGEpOwoJZnJhZ0NvbG9yX1MxX2MwID0gbWl4KHdhdmVfY29sb3IsIGZsb2F0NCgxLjApLCBmbG9hdDQoc3BhcmtsZSkpOwp9CmhhbGY0IHJ1bnRpbWVfc2hhZGVyX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJZmxvYXQyIF90bXBfMV9jb29yZHMgPSB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKCWZsdXR0ZXJfRnJhZ0Nvb3JkX1MxX2MwID0gZmxvYXQ0KF90bXBfMV9jb29yZHMsIDAuMCwgMC4wKTsKCUZMVF9tYWluX1MxX2MwKCk7CglyZXR1cm4gaGFsZjQoaGFsZjQoZnJhZ0NvbG9yX1MxX2MwKSk7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBydW50aW1lX3NoYWRlcl9TMV9jMChfaW5wdXQpOwp9CmhhbGY0IENpcmN1bGFyUlJlY3RfUzIoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MyLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MyLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CgloYWxmIGFscGhhID0gaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzIueCAtIGxlbmd0aChkeHkpKSk7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWZsb2F0IGNvdmVyYWdlID0gdmNvdmVyYWdlX1MwOwoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChjb3ZlcmFnZSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBNYXRyaXhFZmZlY3RfUzEob3V0cHV0Q29sb3JfUzApOwoJaGFsZjQgb3V0cHV0X1MyOwoJb3V0cHV0X1MyID0gQ2lyY3VsYXJSUmVjdF9TMihvdXRwdXRDb3ZlcmFnZV9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0X1MxICogb3V0cHV0X1MyOwoJfQp9CgAAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAHBvc2l0aW9uCAAAAGNvdmVyYWdlBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","GYQAAAAAAAMAADAAAIOAAAH677776IZOCAAP577777777777777777YBAAAAAAAAAAADAAYAAAACAAAAAAACCAYAAA":"DAAAAExTS1MaAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgcG9zaXRpb247CmluIGhhbGY0IGNvbG9yOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2Y29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAAVwEAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQpub3BlcnNwZWN0aXZlIGluIGhhbGY0IHZjb2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAIAAAAcG9zaXRpb24FAAAAY29sb3IAAAAAAAAA","GYQACAAAAAMAADAAAIOAAAH677776IZOCAAP577777777777777777YBAAAAAAAAAAADAAYAAAACAAAAAAACCAYAAA":"DAAAAExTS1MaAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgcG9zaXRpb247CmluIGhhbGY0IGNvbG9yOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2Y29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAAVwEAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQpub3BlcnNwZWN0aXZlIGluIGhhbGY0IHZjb2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAIAAAAcG9zaXRpb24FAAAAY29sb3IAAAAAAAAA","BYIBQAAABQAAIAABBYAAAEIXBAAP777777777777AAAAAAAAAAAABGABAAAAAEAAAAAIBEABAAAAA":"DAAAAExTS1OJAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgaW5Qb3NpdGlvbjsKaW4gaGFsZjQgaW5Db2xvcjsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBEZWZhdWx0R2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IGNvbG9yID0gaW5Db2xvcjsKCXZjb2xvcl9TMCA9IGNvbG9yOwoJZmxvYXQyIF90bXBfMV9pblBvc2l0aW9uID0gaW5Qb3NpdGlvbjsKCWZsb2F0MiBfdG1wXzNfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247Cglza19Qb3NpdGlvbiA9IF90bXBfMV9pblBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAAAFEBAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2Y29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBEZWZhdWx0R2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IAAAAAAA==","GZIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAHIBIA5HZ2CAAAAAAAEAQCAAAAASBEEAQAAAAAUCCQAQQGAABAEAAAAAAGMAAAAAAAIAAAAAQGIAAAAAAA":"DAAAAExTS1POAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzA7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfM19TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzFfYzApICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAAAAcwQAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQp1bmlmb3JtIGZsb2F0NCB1Y2xhbXBfUzFfYzBfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMDsKc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MxOwpub3BlcnNwZWN0aXZlIGluIGhhbGY0IHZjb2xvcl9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzNfUzA7CmhhbGY0IFRleHR1cmVFZmZlY3RfUzFfYzBfYzAoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGluQ29vcmQgPSB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKCWZsb2F0MiBzdWJzZXRDb29yZDsKCXN1YnNldENvb3JkLnggPSBpbkNvb3JkLng7CglzdWJzZXRDb29yZC55ID0gaW5Db29yZC55OwoJZmxvYXQyIGNsYW1wZWRDb29yZDsKCWNsYW1wZWRDb29yZCA9IGNsYW1wKHN1YnNldENvb3JkLCB1Y2xhbXBfUzFfYzBfYzAueHksIHVjbGFtcF9TMV9jMF9jMC56dyk7CgloYWxmNCB0ZXh0dXJlQ29sb3IgPSBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzEsIGNsYW1wZWRDb29yZCk7CglyZXR1cm4gdGV4dHVyZUNvbG9yOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gVGV4dHVyZUVmZmVjdF9TMV9jMF9jMChfaW5wdXQpOwp9CmhhbGY0IERpc2FibGVDb3ZlcmFnZUFzQWxwaGFfUzEoaGFsZjQgX2lucHV0KSAKewoJX2lucHV0ID0gTWF0cml4RWZmZWN0X1MxX2MwKF9pbnB1dCk7CgloYWxmNCBfdG1wXzBfaW5Db2xvciA9IF9pbnB1dDsKCXJldHVybiBoYWxmNChfaW5wdXQpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gRGlzYWJsZUNvdmVyYWdlQXNBbHBoYV9TMShvdXRwdXRDb2xvcl9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0X1MxICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","GZIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAHIBIA5HZ2CAAAAAAAAAACAAAAASAEAAQAAAAAUCCQAQQGAAAAAAAAAAAGMAAAAAAAIAAAAAQGIAAAAAAA":"DAAAAExTS1POAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzA7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfM19TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzFfYzApICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAAAAYAMAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzA7CnNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMTsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc18zX1MwOwpoYWxmNCBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzEsIHZUcmFuc2Zvcm1lZENvb3Jkc18zX1MwKTsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzBfYzAoX2lucHV0KTsKfQpoYWxmNCBEaXNhYmxlQ292ZXJhZ2VBc0FscGhhX1MxKGhhbGY0IF9pbnB1dCkgCnsKCV9pbnB1dCA9IE1hdHJpeEVmZmVjdF9TMV9jMChfaW5wdXQpOwoJaGFsZjQgX3RtcF8wX2luQ29sb3IgPSBfaW5wdXQ7CglyZXR1cm4gaGFsZjQoX2lucHV0KTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IERpc2FibGVDb3ZlcmFnZUFzQWxwaGFfUzEob3V0cHV0Q29sb3JfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","GZIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAJIBAGMVUOTUABAAAAAAAIAAAAAWFBIEMVUOTUAAAAAAAAAIAAAACICAACAAAAACQIKACCAYAAAAAAAAAAAZQAAAAAABAAAAACAZAAAAAAA":"DAAAAExTS1PIAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfMl9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzEpICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAKkFAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKY29uc3QgaW50IGtNYXhMb29wTGltaXRfUzFfYzAgPSA4Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzBfYzA7CnVuaWZvcm0gaGFsZjQgdW9mZnNldHNBbmRLZXJuZWxfUzFfYzBbMTRdOwp1bmlmb3JtIGhhbGYyIHVkaXJfUzFfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MxOwpub3BlcnNwZWN0aXZlIGluIGhhbGY0IHZjb2xvcl9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CmhhbGY0IFRleHR1cmVFZmZlY3RfUzFfYzBfYzBfYzAoaGFsZjQgX2lucHV0LCBmbG9hdDIgX2Nvb3JkcykgCnsKCXJldHVybiBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzEsIF9jb29yZHMpOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMV9jMF9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzBfYzBfYzAoX2lucHV0LCBmbG9hdDN4Mih1bWF0cml4X1MxX2MwX2MwKSAqIF9jb29yZHMueHkxKTsKfQpoYWxmNCBydW50aW1lX3NoYWRlcl9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzBfaW5Db2xvciA9IF9pbnB1dDsKCWZsb2F0MiBfdG1wXzFfY29vcmRzID0gdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CgloYWxmNCBzdW0gPSBoYWxmNCgwLjApOwoJZm9yIChpbnQgaSA9IDA7aSA8IGtNYXhMb29wTGltaXRfUzFfYzA7ICsraSkgCgl7CgkJaGFsZjQgcyA9IHVvZmZzZXRzQW5kS2VybmVsX1MxX2MwW2ldOwoJCXN1bSArPSBzLnkgKiBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoX3RtcF8wX2luQ29sb3IsIF90bXBfMV9jb29yZHMgKyBmbG9hdDIocy54ICogdWRpcl9TMV9jMCkpOwoJCXN1bSArPSBzLncgKiBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoX3RtcF8wX2luQ29sb3IsIF90bXBfMV9jb29yZHMgKyBmbG9hdDIocy56ICogdWRpcl9TMV9jMCkpOwoJfQoJcmV0dXJuIGhhbGY0KHN1bSk7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBydW50aW1lX3NoYWRlcl9TMV9jMChfaW5wdXQpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gTWF0cml4RWZmZWN0X1MxKG91dHB1dENvbG9yX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRfUzEgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAgAAABwb3NpdGlvbgUAAABjb2xvcgAAAAoAAABsb2NhbENvb3JkAAAAAAAA","GZIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAJIBAGMVUOTUABAAAAQCAIAAAAAWFBIEMVUOTUAAAAAAQCAIAAAACIGAQCAAAAACQIKACCAYAAEAQAAAAAAZQAAAAAABAAAAACAZAAAAAAA":"DAAAAExTS1PIAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfMl9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzEpICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAMUGAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKY29uc3QgaW50IGtNYXhMb29wTGltaXRfUzFfYzAgPSA4Owp1bmlmb3JtIGZsb2F0NCB1Y2xhbXBfUzFfYzBfYzBfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMDsKdW5pZm9ybSBoYWxmNCB1b2Zmc2V0c0FuZEtlcm5lbF9TMV9jMFsxNF07CnVuaWZvcm0gaGFsZjIgdWRpcl9TMV9jMDsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7Cm5vcGVyc3BlY3RpdmUgaW4gaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMF9jMF9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJZmxvYXQyIGluQ29vcmQgPSBfY29vcmRzOwoJZmxvYXQyIHN1YnNldENvb3JkOwoJc3Vic2V0Q29vcmQueCA9IGluQ29vcmQueDsKCXN1YnNldENvb3JkLnkgPSBpbkNvb3JkLnk7CglmbG9hdDIgY2xhbXBlZENvb3JkOwoJY2xhbXBlZENvb3JkID0gY2xhbXAoc3Vic2V0Q29vcmQsIHVjbGFtcF9TMV9jMF9jMF9jMC54eSwgdWNsYW1wX1MxX2MwX2MwX2MwLnp3KTsKCWhhbGY0IHRleHR1cmVDb2xvciA9IHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMSwgY2xhbXBlZENvb3JkKTsKCXJldHVybiB0ZXh0dXJlQ29sb3I7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxX2MwX2MwKGhhbGY0IF9pbnB1dCwgZmxvYXQyIF9jb29yZHMpIAp7CglyZXR1cm4gVGV4dHVyZUVmZmVjdF9TMV9jMF9jMF9jMChfaW5wdXQsIGZsb2F0M3gyKHVtYXRyaXhfUzFfYzBfYzApICogX2Nvb3Jkcy54eTEpOwp9CmhhbGY0IHJ1bnRpbWVfc2hhZGVyX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJZmxvYXQyIF90bXBfMV9jb29yZHMgPSB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKCWhhbGY0IHN1bSA9IGhhbGY0KDAuMCk7Cglmb3IgKGludCBpID0gMDtpIDwga01heExvb3BMaW1pdF9TMV9jMDsgKytpKSAKCXsKCQloYWxmNCBzID0gdW9mZnNldHNBbmRLZXJuZWxfUzFfYzBbaV07CgkJc3VtICs9IHMueSAqIE1hdHJpeEVmZmVjdF9TMV9jMF9jMChfdG1wXzBfaW5Db2xvciwgX3RtcF8xX2Nvb3JkcyArIGZsb2F0MihzLnggKiB1ZGlyX1MxX2MwKSk7CgkJc3VtICs9IHMudyAqIE1hdHJpeEVmZmVjdF9TMV9jMF9jMChfdG1wXzBfaW5Db2xvciwgX3RtcF8xX2Nvb3JkcyArIGZsb2F0MihzLnogKiB1ZGlyX1MxX2MwKSk7Cgl9CglyZXR1cm4gaGFsZjQoc3VtKTsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIHJ1bnRpbWVfc2hhZGVyX1MxX2MwKF9pbnB1dCk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBNYXRyaXhFZmZlY3RfUzEob3V0cHV0Q29sb3JfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","G2JAAAAAAAUAADAAAIOAAAAADIIAB7X7777QGHAYAD7P7777777777YBAAAAAAQAAAAAAQQGAAYAGAAAAAQAAAAAAAQQGAAA":"DAAAAExTS1OjAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgcG9zaXRpb247CmluIGZsb2F0IGNvdmVyYWdlOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQyIHZsb2NhbENvb3JkX1MwOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdCB2Y292ZXJhZ2VfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQyIHBvc2l0aW9uID0gcG9zaXRpb24ueHk7Cgl2bG9jYWxDb29yZF9TMCA9IGxvY2FsQ29vcmQ7Cgl2Y292ZXJhZ2VfUzAgPSBjb3ZlcmFnZTsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKfQoAAAAAADUCAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2bG9jYWxDb29yZF9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdCB2Y292ZXJhZ2VfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwID0gaGFsZjQoMSk7CglmbG9hdDIgdGV4Q29vcmQ7Cgl0ZXhDb29yZCA9IHZsb2NhbENvb3JkX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSAoYmxlbmRfbW9kdWxhdGUoc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB0ZXhDb29yZCksIGhhbGY0KDEpKSk7CglmbG9hdCBjb3ZlcmFnZSA9IHZjb3ZlcmFnZV9TMDsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoY292ZXJhZ2UpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAIAAAAcG9zaXRpb24IAAAAY292ZXJhZ2UKAAAAbG9jYWxDb29yZAAAAAAAAA==","GXQAAGAABBYAAAEIXBAAAGEAMAAAAAAAAAAAAAAAYAGAAAAAQAAAAAAAQQGAAAAA":"DAAAAExTS1OYAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgaW5Qb3NpdGlvbjsKaW4gaGFsZjQgaW5Db2xvcjsKaW4gZmxvYXQ0IGluUXVhZEVkZ2U7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0NCB2UXVhZEVkZ2VfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBRdWFkRWRnZQoJdlF1YWRFZGdlX1MwID0gaW5RdWFkRWRnZTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247Cglza19Qb3NpdGlvbiA9IF90bXBfMF9pblBvc2l0aW9uLnh5MDE7Cn0KBAAAAF4DAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdDQgdlF1YWRFZGdlX1MwOwpub3BlcnNwZWN0aXZlIGluIGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZEVkZ2UKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWhhbGYgZWRnZUFscGhhOwoJaGFsZjIgZHV2ZHggPSBoYWxmMihkRmR4KHZRdWFkRWRnZV9TMC54eSkpOwoJaGFsZjIgZHV2ZHkgPSBoYWxmMihkRmR5KHZRdWFkRWRnZV9TMC54eSkpOwoJaWYgKHZRdWFkRWRnZV9TMC56ID4gMC4wICYmIHZRdWFkRWRnZV9TMC53ID4gMC4wKSAKCXsKCQllZGdlQWxwaGEgPSBoYWxmKG1pbihtaW4odlF1YWRFZGdlX1MwLnosIHZRdWFkRWRnZV9TMC53KSArIDAuNSwgMS4wKSk7Cgl9CgllbHNlIAoJewoJCWhhbGYyIGdGID0gaGFsZjIoaGFsZigyLjAqdlF1YWRFZGdlX1MwLngqZHV2ZHgueCAtIGR1dmR4LnkpLCAgICAgICAgICAgICAgICAgaGFsZigyLjAqdlF1YWRFZGdlX1MwLngqZHV2ZHkueCAtIGR1dmR5LnkpKTsKCQllZGdlQWxwaGEgPSBoYWxmKHZRdWFkRWRnZV9TMC54KnZRdWFkRWRnZV9TMC54IC0gdlF1YWRFZGdlX1MwLnkpOwoJCWVkZ2VBbHBoYSA9IHNhdHVyYXRlKDAuNSAtIGVkZ2VBbHBoYSAvIGxlbmd0aChnRikpOwoJfQoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChlZGdlQWxwaGEpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAEAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAoAAABpblBvc2l0aW9uAAAHAAAAaW5Db2xvcgAKAAAAaW5RdWFkRWRnZQAAAAAAAA==","GYJAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAQAAAAAAQQGABZAA6IAAAAACAAAAAADGAAAAAAAEAAAAAIDEAAAAAAA":"DAAAAExTS1MwAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgcG9zaXRpb247CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmxvY2FsQ29vcmRfUzAgPSBsb2NhbENvb3JkOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgEAAAB+AwAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHVpbm5lclJlY3RfUzE7CnVuaWZvcm0gaGFsZjIgdXJhZGl1c1BsdXNIYWxmX1MxOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQyIHZsb2NhbENvb3JkX1MwOwpoYWxmNCBDaXJjdWxhclJSZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCWZsb2F0MiBkeHkwID0gdWlubmVyUmVjdF9TMS5MVCAtIHNrX0ZyYWdDb29yZC54eTsKCWZsb2F0MiBkeHkxID0gc2tfRnJhZ0Nvb3JkLnh5IC0gdWlubmVyUmVjdF9TMS5SQjsKCWZsb2F0MiBkeHkgPSBtYXgobWF4KGR4eTAsIGR4eTEpLCAwLjApOwoJaGFsZiBhbHBoYSA9IGhhbGYoc2F0dXJhdGUodXJhZGl1c1BsdXNIYWxmX1MxLnggLSBsZW5ndGgoZHh5KSkpOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwID0gaGFsZjQoMSk7CglmbG9hdDIgdGV4Q29vcmQ7Cgl0ZXhDb29yZCA9IHZsb2NhbENvb3JkX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSAoYmxlbmRfbW9kdWxhdGUoc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB0ZXhDb29yZCksIGhhbGY0KDEpKSk7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQ2lyY3VsYXJSUmVjdF9TMShvdXRwdXRDb3ZlcmFnZV9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAAABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgoAAABsb2NhbENvb3JkAAAAAAAA","FIMAAAYAAEHAAAARC4EAAAQWBQAAAAAAAAAQAAAAIBCAAAEYAEAAAAAQAAAABAEQAEAAAAA":"DAAAAExTS1OtAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgaW5Qb3NpdGlvbjsKaW4gaGFsZjQgaW5Db2xvcjsKaW4gaGFsZjMgaW5TaGFkb3dQYXJhbXM7Cm5vcGVyc3BlY3RpdmUgb3V0IGhhbGYzIHZpblNoYWRvd1BhcmFtc19TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFJSZWN0U2hhZG93Cgl2aW5TaGFkb3dQYXJhbXNfUzAgPSBpblNoYWRvd1BhcmFtczsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247Cglza19Qb3NpdGlvbiA9IF90bXBfMF9pblBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAAAFwCAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwpub3BlcnNwZWN0aXZlIGluIGhhbGYzIHZpblNoYWRvd1BhcmFtc19TMDsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFJSZWN0U2hhZG93CgloYWxmMyBzaGFkb3dQYXJhbXM7CglzaGFkb3dQYXJhbXMgPSB2aW5TaGFkb3dQYXJhbXNfUzA7CgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmluQ29sb3JfUzA7CgloYWxmIGQgPSBsZW5ndGgoc2hhZG93UGFyYW1zLnh5KTsKCWZsb2F0MiB1diA9IGZsb2F0MihzaGFkb3dQYXJhbXMueiAqICgxLjAgLSBkKSwgMC41KTsKCWhhbGYgZmFjdG9yID0gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB1dikuMDAwci5hOwoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChmYWN0b3IpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADgAAAGluU2hhZG93UGFyYW1zAAAAAAAA","GZIACAAAABQAAGAAAQ4AAAAAGQQAARC4GAAAIOCAAD6P7777777777YDAAAAAAAAAAAJQBBYGQ467YIAAAAAAQAAAAAMACTRNBZN5QYBAAAAAAAAAAAIAALIAAAAAGFM37JKEAAAAAMAAAAAIAAAAAAAMBCQN25XWQUAAAAAAYAAAAAAAAAABGABAAAAAEAAAAAIBEABAAAAA":"DAAAAExTS1M7AgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQgY292ZXJhZ2U7CmluIGhhbGY0IGNvbG9yOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdCB2Y292ZXJhZ2VfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDIgcG9zaXRpb24gPSBwb3NpdGlvbi54eTsKCXZjb2xvcl9TMCA9IGNvbG9yOwoJdmNvdmVyYWdlX1MwID0gY292ZXJhZ2U7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgABAAAAKh8AACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQpmbG9hdDQgZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzA7CmZsb2F0NCBmcmFnQ29sb3JfUzFfYzA7CmZsb2F0IHVfYWxwaGFfUzFfYzA7CmZsb2F0IHVfc3BhcmtsZV9hbHBoYV9TMV9jMDsKZmxvYXQgdV9ibHVyX1MxX2MwOwpmbG9hdCB1X3JhZGl1c19zY2FsZV9TMV9jMDsKY29uc3QgaW50IGtGaWxsQUFfUzJfYzAgPSAxOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQldfUzJfYzAgPSAyOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQUFfUzJfYzAgPSAzOwp1bmlmb3JtIGZsb2F0NCB1X2NvbG9yX1MxX2MwOwp1bmlmb3JtIGZsb2F0NCB1X2NvbXBvc2l0ZV8xX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NlbnRlcl9TMV9jMDsKdW5pZm9ybSBmbG9hdCB1X21heF9yYWRpdXNfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcmVzb2x1dGlvbl9zY2FsZV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9ub2lzZV9zY2FsZV9TMV9jMDsKdW5pZm9ybSBmbG9hdCB1X25vaXNlX3BoYXNlX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NpcmNsZTFfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2lyY2xlMl9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jaXJjbGUzX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3JvdGF0aW9uMV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yb3RhdGlvbjJfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcm90YXRpb24zX1MxX2MwOwp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CnVuaWZvcm0gZmxvYXQ0IHVjaXJjbGVfUzJfYzA7Cm5vcGVyc3BlY3RpdmUgaW4gaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0IHZjb3ZlcmFnZV9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CmZsb2F0MiBGTFRfZmx1dHRlcl9sb2NhbF9GbHV0dGVyRnJhZ0Nvb3JkX1MxX2MwKCk7CmZsb2F0MngyIEZMVF9mbHV0dGVyX2xvY2FsX3JvdGF0ZTJkX1MxX2MwKGZsb2F0MiByYWQpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCBibHVyKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAoZmxvYXQyIHJlc29sdXRpb24sIGlub3V0IGZsb2F0MiBwLCBmbG9hdDIgeHksIGZsb2F0MiByb3RhdGlvbiwgZmxvYXQgY2VsbF9kaWFtZXRlcik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3R1cmJ1bGVuY2VfUzFfYzAoZmxvYXQyIHV2KTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9yaW5nX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IHRoaWNrbmVzcywgZmxvYXQgYmx1cik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RyaWFuZ2xlX25vaXNlX1MxX2MwKGlub3V0IGZsb2F0MiBuKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKGZsb2F0IHYsIGZsb2F0IGwsIGZsb2F0IGgpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zcGFya2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQgdCk7CnZvaWQgRkxUX21haW5fUzFfYzAoKTsKZmxvYXQyIEZMVF9mbHV0dGVyX2xvY2FsX0ZsdXR0ZXJGcmFnQ29vcmRfUzFfYzAoKSAKewoJcmV0dXJuIGZsdXR0ZXJfRnJhZ0Nvb3JkX1MxX2MwLnh5Owp9CmZsb2F0MngyIEZMVF9mbHV0dGVyX2xvY2FsX3JvdGF0ZTJkX1MxX2MwKGZsb2F0MiByYWQpIAp7CglyZXR1cm4gZmxvYXQyeDIocmFkLngsIC1yYWQueSwgcmFkLnksIHJhZC54KTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCBibHVyKSAKewoJZmxvYXQgYmx1cl9oYWxmID0gYmx1ciAqIDAuNTsKCWZsb2F0IGQgPSBkaXN0YW5jZSh1diwgeHkpOwoJcmV0dXJuIDEuMCAtIHNtb290aHN0ZXAoMS4wIC0gYmx1cl9oYWxmLCAxLjAgKyBibHVyX2hhbGYsIGQgLyByYWRpdXMpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKGZsb2F0MiByZXNvbHV0aW9uLCBpbm91dCBmbG9hdDIgcCwgZmxvYXQyIHh5LCBmbG9hdDIgcm90YXRpb24sIGZsb2F0IGNlbGxfZGlhbWV0ZXIpIAp7CglmbG9hdDIgcGFyYW0gPSByb3RhdGlvbjsKCXAgPSBGTFRfZmx1dHRlcl9sb2NhbF9yb3RhdGUyZF9TMV9jMChwYXJhbSkgKiAoeHkgLSBwKSArIHh5OwoJcCA9IG1vZChwLCBmbG9hdDIoY2VsbF9kaWFtZXRlcikpIC8gcmVzb2x1dGlvbjsKCWZsb2F0IGNlbGxfdXYgPSAoY2VsbF9kaWFtZXRlciAvIHJlc29sdXRpb24ueSkgKiAwLjU7CglmbG9hdCByID0gMC42NSAqIGNlbGxfdXY7CglmbG9hdDIgcGFyYW1fMSA9IHA7CglmbG9hdDIgcGFyYW1fMiA9IGZsb2F0MihjZWxsX3V2KTsKCWZsb2F0IHBhcmFtXzMgPSByOwoJZmxvYXQgcGFyYW1fNCA9IHIgKiA1MC4wOwoJcmV0dXJuIEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMsIHBhcmFtXzQpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3R1cmJ1bGVuY2VfUzFfYzAoZmxvYXQyIHV2KSAKewoJZmxvYXQyIHV2X3NjYWxlID0gdXYgKiBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbSA9IGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtXzEgPSB1dl9zY2FsZTsKCWZsb2F0MiBwYXJhbV8yID0gdV9jaXJjbGUxX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzMgPSB1X3JvdGF0aW9uMV9TMV9jMDsKCWZsb2F0IHBhcmFtXzQgPSAwLjE3OwoJZmxvYXQgXzMxOSA9IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKHBhcmFtLCBwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zLCBwYXJhbV80KTsKCWZsb2F0IGcxID0gXzMxOTsKCWZsb2F0MiBwYXJhbV81ID0gZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW1fNiA9IHV2X3NjYWxlOwoJZmxvYXQyIHBhcmFtXzcgPSB1X2NpcmNsZTJfUzFfYzA7CglmbG9hdDIgcGFyYW1fOCA9IHVfcm90YXRpb24yX1MxX2MwOwoJZmxvYXQgcGFyYW1fOSA9IDAuMjsKCWZsb2F0IF8zMzEgPSBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChwYXJhbV81LCBwYXJhbV82LCBwYXJhbV83LCBwYXJhbV84LCBwYXJhbV85KTsKCWZsb2F0IGcyID0gXzMzMTsKCWZsb2F0MiBwYXJhbV8xMCA9IGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtXzExID0gdXZfc2NhbGU7CglmbG9hdDIgcGFyYW1fMTIgPSB1X2NpcmNsZTNfUzFfYzA7CglmbG9hdDIgcGFyYW1fMTMgPSB1X3JvdGF0aW9uM19TMV9jMDsKCWZsb2F0IHBhcmFtXzE0ID0gMC4yNzU7CglmbG9hdCBfMzQ0ID0gRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAocGFyYW1fMTAsIHBhcmFtXzExLCBwYXJhbV8xMiwgcGFyYW1fMTMsIHBhcmFtXzE0KTsKCWZsb2F0IGczID0gXzM0NDsKCWZsb2F0IHYgPSAoKGcxICogZzEgKyBnMikgLSBnMykgKiAwLjU7CglyZXR1cm4gY2xhbXAoMC40NSArIDAuOCAqIHYsIDAuMCwgMS4wKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X3JpbmdfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgdGhpY2tuZXNzLCBmbG9hdCBibHVyKSAKewoJZmxvYXQyIHBhcmFtID0gdXY7CglmbG9hdDIgcGFyYW1fMSA9IHh5OwoJZmxvYXQgcGFyYW1fMiA9IHJhZGl1cyArIHRoaWNrbmVzczsKCWZsb2F0IHBhcmFtXzMgPSBibHVyOwoJZmxvYXQgY2lyY2xlX291dGVyID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW0sIHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMpOwoJZmxvYXQyIHBhcmFtXzQgPSB1djsKCWZsb2F0MiBwYXJhbV81ID0geHk7CglmbG9hdCBwYXJhbV82ID0gbWF4KHJhZGl1cyAtIHRoaWNrbmVzcywgMC4wKTsKCWZsb2F0IHBhcmFtXzcgPSBibHVyOwoJZmxvYXQgY2lyY2xlX2lubmVyID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW1fNCwgcGFyYW1fNSwgcGFyYW1fNiwgcGFyYW1fNyk7CglyZXR1cm4gY2xhbXAoY2lyY2xlX291dGVyIC0gY2lyY2xlX2lubmVyLCAwLjAsIDEuMCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHJpYW5nbGVfbm9pc2VfUzFfYzAoaW5vdXQgZmxvYXQyIG4pIAp7CgluID0gZnJhY3QobiAqIGZsb2F0Mig1LjM5ODcsIDUuNDQyMSkpOwoJbiArPSBmbG9hdDIoZG90KG4ueXgsIG4gKyBmbG9hdDIoMjEuNTM1MSwgMTQuMzEzNykpKTsKCWZsb2F0IHh5ID0gbi54ICogbi55OwoJcmV0dXJuIChmcmFjdCh4eSAqIDk1LjQzMDcpICsgZnJhY3QoeHkgKiA3NS4wNDk2MSkpIC0gMS4wOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChmbG9hdCB2LCBmbG9hdCBsLCBmbG9hdCBoKSAKewoJcmV0dXJuIHN0ZXAobCwgdikgKiAoMS4wIC0gc3RlcChoLCB2KSk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc3BhcmtsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0IHQpIAp7CglmbG9hdDIgcGFyYW0gPSB1djsKCWZsb2F0IF8yNDIgPSBGTFRfZmx1dHRlcl9sb2NhbF90cmlhbmdsZV9ub2lzZV9TMV9jMChwYXJhbSk7CglmbG9hdCBuID0gXzI0MjsKCWZsb2F0IHBhcmFtXzEgPSBuOwoJZmxvYXQgcGFyYW1fMiA9IDAuMDsKCWZsb2F0IHBhcmFtXzMgPSAwLjA1OwoJZmxvYXQgcyA9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zKTsKCWZsb2F0IHBhcmFtXzQgPSBuICsgc2luKDMuMTQxNTkyNzQgKiAodCArIDAuMzUpKTsKCWZsb2F0IHBhcmFtXzUgPSAwLjE7CglmbG9hdCBwYXJhbV82ID0gMC4xNTsKCXMgKz0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzQsIHBhcmFtXzUsIHBhcmFtXzYpOwoJZmxvYXQgcGFyYW1fNyA9IG4gKyBzaW4oMy4xNDE1OTI3NCAqICh0ICsgMC43KSk7CglmbG9hdCBwYXJhbV84ID0gMC4yOwoJZmxvYXQgcGFyYW1fOSA9IDAuMjU7CglzICs9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV83LCBwYXJhbV84LCBwYXJhbV85KTsKCWZsb2F0IHBhcmFtXzEwID0gbiArIHNpbigzLjE0MTU5Mjc0ICogKHQgKyAxLjA1KSk7CglmbG9hdCBwYXJhbV8xMSA9IDAuMzsKCWZsb2F0IHBhcmFtXzEyID0gMC4zNTsKCXMgKz0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzEwLCBwYXJhbV8xMSwgcGFyYW1fMTIpOwoJcmV0dXJuIGNsYW1wKHMsIDAuMCwgMS4wKSAqIDAuNTU7Cn0Kdm9pZCBGTFRfbWFpbl9TMV9jMCgpIAp7Cgl1X2FscGhhX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC54OwoJdV9zcGFya2xlX2FscGhhX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC55OwoJdV9ibHVyX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC56OwoJdV9yYWRpdXNfc2NhbGVfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLnc7CglmbG9hdDIgcCA9IEZMVF9mbHV0dGVyX2xvY2FsX0ZsdXR0ZXJGcmFnQ29vcmRfUzFfYzAoKTsKCWZsb2F0MiB1dl8xID0gcCAqIHVfcmVzb2x1dGlvbl9zY2FsZV9TMV9jMDsKCWZsb2F0MiBkZW5zaXR5X3V2ID0gdXZfMSAtIG1vZChwLCB1X25vaXNlX3NjYWxlX1MxX2MwKTsKCWZsb2F0IHJhZGl1cyA9IHVfbWF4X3JhZGl1c19TMV9jMCAqIHVfcmFkaXVzX3NjYWxlX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzEzID0gdXZfMTsKCWZsb2F0IHR1cmJ1bGVuY2UgPSBGTFRfZmx1dHRlcl9sb2NhbF90dXJidWxlbmNlX1MxX2MwKHBhcmFtXzEzKTsKCWZsb2F0MiBwYXJhbV8xNCA9IHA7CglmbG9hdDIgcGFyYW1fMTUgPSB1X2NlbnRlcl9TMV9jMDsKCWZsb2F0IHBhcmFtXzE2ID0gcmFkaXVzOwoJZmxvYXQgcGFyYW1fMTcgPSAwLjA1ICogdV9tYXhfcmFkaXVzX1MxX2MwOwoJZmxvYXQgcGFyYW1fMTggPSB1X2JsdXJfUzFfYzA7CglmbG9hdCByaW5nID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9yaW5nX1MxX2MwKHBhcmFtXzE0LCBwYXJhbV8xNSwgcGFyYW1fMTYsIHBhcmFtXzE3LCBwYXJhbV8xOCk7CglmbG9hdDIgcGFyYW1fMTkgPSBkZW5zaXR5X3V2OwoJZmxvYXQgcGFyYW1fMjAgPSB1X25vaXNlX3BoYXNlX1MxX2MwOwoJZmxvYXQgc3BhcmtsZSA9ICgoRkxUX2ZsdXR0ZXJfbG9jYWxfc3BhcmtsZV9TMV9jMChwYXJhbV8xOSwgcGFyYW1fMjApICogcmluZykgKiB0dXJidWxlbmNlKSAqIHVfc3BhcmtsZV9hbHBoYV9TMV9jMDsKCWZsb2F0MiBwYXJhbV8yMSA9IHA7CglmbG9hdDIgcGFyYW1fMjIgPSB1X2NlbnRlcl9TMV9jMDsKCWZsb2F0IHBhcmFtXzIzID0gcmFkaXVzOwoJZmxvYXQgcGFyYW1fMjQgPSB1X2JsdXJfUzFfYzA7CglmbG9hdCB3YXZlX2FscGhhID0gKEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtXzIxLCBwYXJhbV8yMiwgcGFyYW1fMjMsIHBhcmFtXzI0KSAqIHVfYWxwaGFfUzFfYzApICogdV9jb2xvcl9TMV9jMC53OwoJZmxvYXQ0IHdhdmVfY29sb3IgPSBmbG9hdDQodV9jb2xvcl9TMV9jMC54eXogKiB3YXZlX2FscGhhLCB3YXZlX2FscGhhKTsKCWZyYWdDb2xvcl9TMV9jMCA9IG1peCh3YXZlX2NvbG9yLCBmbG9hdDQoMS4wKSwgZmxvYXQ0KHNwYXJrbGUpKTsKfQpoYWxmNCBydW50aW1lX3NoYWRlcl9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzBfaW5Db2xvciA9IF9pbnB1dDsKCWZsb2F0MiBfdG1wXzFfY29vcmRzID0gdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CglmbHV0dGVyX0ZyYWdDb29yZF9TMV9jMCA9IGZsb2F0NChfdG1wXzFfY29vcmRzLCAwLjAsIDAuMCk7CglGTFRfbWFpbl9TMV9jMCgpOwoJcmV0dXJuIGhhbGY0KGhhbGY0KGZyYWdDb2xvcl9TMV9jMCkpOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gcnVudGltZV9zaGFkZXJfUzFfYzAoX2lucHV0KTsKfQpoYWxmNCBDaXJjbGVfUzJfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF8yX2luQ29sb3IgPSBfaW5wdXQ7CgloYWxmIGQ7CglpZiAoaW50KDEpID09IGtJbnZlcnNlRmlsbEJXX1MyX2MwIHx8IGludCgxKSA9PSBrSW52ZXJzZUZpbGxBQV9TMl9jMCkgCgl7CgkJZCA9IGhhbGYoKGxlbmd0aCgodWNpcmNsZV9TMl9jMC54eSAtIHNrX0ZyYWdDb29yZC54eSkgKiB1Y2lyY2xlX1MyX2MwLncpIC0gMS4wKSAqIHVjaXJjbGVfUzJfYzAueik7Cgl9CgllbHNlIAoJewoJCWQgPSBoYWxmKCgxLjAgLSBsZW5ndGgoKHVjaXJjbGVfUzJfYzAueHkgLSBza19GcmFnQ29vcmQueHkpICogdWNpcmNsZV9TMl9jMC53KSkgKiB1Y2lyY2xlX1MyX2MwLnopOwoJfQoJcmV0dXJuIGhhbGY0KGhhbGY0KGludCgxKSA9PSBrRmlsbEFBX1MyX2MwIHx8IGludCgxKSA9PSBrSW52ZXJzZUZpbGxBQV9TMl9jMCA/IHNhdHVyYXRlKGQpIDogaGFsZihkID4gMC41KSkpOwp9CmhhbGY0IEJsZW5kX1MyKGhhbGY0IF9zcmMsIGhhbGY0IF9kc3QpIAp7CglyZXR1cm4gYmxlbmRfbW9kdWxhdGUoX3NyYywgQ2lyY2xlX1MyX2MwKF9zcmMpKTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJZmxvYXQgY292ZXJhZ2UgPSB2Y292ZXJhZ2VfUzA7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGNvdmVyYWdlKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IE1hdHJpeEVmZmVjdF9TMShvdXRwdXRDb2xvcl9TMCk7CgloYWxmNCBvdXRwdXRfUzI7CglvdXRwdXRfUzIgPSBCbGVuZF9TMihvdXRwdXRDb3ZlcmFnZV9TMCwgaGFsZjQoMSkpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dF9TMjsKCX0KfQoAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAHBvc2l0aW9uCAAAAGNvdmVyYWdlBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","EEAQMYAAMAAAEADAAABAEYAAAICIAB5AABQAAAQAMAAAEATAAABAIIGAAEDCBYQCA4AAAAAAAAZQAAAAAABAAAAACAZAAAAA":"DAAAAExTS1MoDAAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDQgcmFkaWlfc2VsZWN0b3I7CmluIGZsb2F0NCBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzOwppbiBmbG9hdDQgYWFfYmxvYXRfYW5kX2NvdmVyYWdlOwppbiBmbG9hdDQgcmFkaWlfeDsKaW4gZmxvYXQ0IHJhZGlpX3k7CmluIGZsb2F0NCBza2V3OwppbiBmbG9hdDIgdHJhbnNsYXRlX2FuZF9sb2NhbHJvdGF0ZTsKaW4gaGFsZjQgY29sb3I7Cm5vcGVyc3BlY3RpdmUgb3V0IGhhbGY0IHZjb2xvcl9TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQyIHZhcmNjb29yZF9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgRmlsbFJSZWN0T3A6OlByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7CglmbG9hdCBhYV9ibG9hdF9tdWx0aXBsaWVyID0gMTsKCWZsb2F0MiBjb3JuZXIgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnh5OwoJZmxvYXQyIHJhZGl1c19vdXRzZXQgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnp3OwoJZmxvYXQyIGFhX2Jsb2F0X2RpcmVjdGlvbiA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS54eTsKCWZsb2F0IGlzX2xpbmVhcl9jb3ZlcmFnZSA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS53OwoJZmxvYXQyIHBpeGVsbGVuZ3RoID0gaW52ZXJzZXNxcnQoZmxvYXQyKGRvdChza2V3Lnh6LCBza2V3Lnh6KSwgZG90KHNrZXcueXcsIHNrZXcueXcpKSk7CglmbG9hdDQgbm9ybWFsaXplZF9heGlzX2RpcnMgPSBza2V3ICogcGl4ZWxsZW5ndGgueHl4eTsKCWZsb2F0MiBheGlzd2lkdGhzID0gKGFicyhub3JtYWxpemVkX2F4aXNfZGlycy54eSkgKyBhYnMobm9ybWFsaXplZF9heGlzX2RpcnMuencpKTsKCWZsb2F0MiBhYV9ibG9hdHJhZGl1cyA9IGF4aXN3aWR0aHMgKiBwaXhlbGxlbmd0aCAqIC41OwoJZmxvYXQ0IHJhZGlpX2FuZF9uZWlnaGJvcnMgPSByYWRpaV9zZWxlY3RvciogZmxvYXQ0eDQocmFkaWlfeCwgcmFkaWlfeSwgcmFkaWlfeC55eHd6LCByYWRpaV95Lnd6eXgpOwoJZmxvYXQyIHJhZGlpID0gcmFkaWlfYW5kX25laWdoYm9ycy54eTsKCWZsb2F0MiBuZWlnaGJvcl9yYWRpaSA9IHJhZGlpX2FuZF9uZWlnaGJvcnMuenc7CglmbG9hdCBjb3ZlcmFnZV9tdWx0aXBsaWVyID0gMTsKCWlmIChhbnkoZ3JlYXRlclRoYW4oYWFfYmxvYXRyYWRpdXMsIGZsb2F0MigxKSkpKSAKCXsKCQljb3JuZXIgPSBtYXgoYWJzKGNvcm5lciksIGFhX2Jsb2F0cmFkaXVzKSAqIHNpZ24oY29ybmVyKTsKCQljb3ZlcmFnZV9tdWx0aXBsaWVyID0gMSAvIChtYXgoYWFfYmxvYXRyYWRpdXMueCwgMSkgKiBtYXgoYWFfYmxvYXRyYWRpdXMueSwgMSkpOwoJCXJhZGlpID0gZmxvYXQyKDApOwoJfQoJZmxvYXQgY292ZXJhZ2UgPSBhYV9ibG9hdF9hbmRfY292ZXJhZ2UuejsKCWlmIChhbnkobGVzc1RoYW4ocmFkaWksIGFhX2Jsb2F0cmFkaXVzICogMS41KSkpIAoJewoJCXJhZGlpID0gZmxvYXQyKDApOwoJCWFhX2Jsb2F0X2RpcmVjdGlvbiA9IHNpZ24oY29ybmVyKTsKCQlpZiAoY292ZXJhZ2UgPiAuNSkgCgkJewoJCQlhYV9ibG9hdF9kaXJlY3Rpb24gPSAtYWFfYmxvYXRfZGlyZWN0aW9uOwoJCX0KCQlpc19saW5lYXJfY292ZXJhZ2UgPSAxOwoJfQoJZWxzZSAKCXsKCQlyYWRpaSA9IGNsYW1wKHJhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQluZWlnaGJvcl9yYWRpaSA9IGNsYW1wKG5laWdoYm9yX3JhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQlmbG9hdDIgc3BhY2luZyA9IDIgLSByYWRpaSAtIG5laWdoYm9yX3JhZGlpOwoJCWZsb2F0MiBleHRyYV9wYWQgPSBtYXgocGl4ZWxsZW5ndGggKiAuMDYyNSAtIHNwYWNpbmcsIGZsb2F0MigwKSk7CgkJcmFkaWkgLT0gZXh0cmFfcGFkICogLjU7Cgl9CglmbG9hdDIgYWFfb3V0c2V0ID0gYWFfYmxvYXRfZGlyZWN0aW9uICogYWFfYmxvYXRyYWRpdXMgKiBhYV9ibG9hdF9tdWx0aXBsaWVyOwoJZmxvYXQyIHZlcnRleHBvcyA9IGNvcm5lciArIHJhZGl1c19vdXRzZXQgKiByYWRpaSArIGFhX291dHNldDsKCWlmIChjb3ZlcmFnZSA+IC41KSAKCXsKCQlpZiAoYWFfYmxvYXRfZGlyZWN0aW9uLnggIT0gMCAmJiB2ZXJ0ZXhwb3MueCAqIGNvcm5lci54IDwgMCkgCgkJewoJCQlmbG9hdCBiYWNrc2V0ID0gYWJzKHZlcnRleHBvcy54KTsKCQkJdmVydGV4cG9zLnggPSAwOwoJCQl2ZXJ0ZXhwb3MueSArPSBiYWNrc2V0ICogc2lnbihjb3JuZXIueSkgKiBwaXhlbGxlbmd0aC55L3BpeGVsbGVuZ3RoLng7CgkJCWNvdmVyYWdlID0gKGNvdmVyYWdlIC0gLjUpICogYWJzKGNvcm5lci54KSAvIChhYnMoY29ybmVyLngpICsgYmFja3NldCkgKyAuNTsKCQl9CgkJaWYgKGFhX2Jsb2F0X2RpcmVjdGlvbi55ICE9IDAgJiYgdmVydGV4cG9zLnkgKiBjb3JuZXIueSA8IDApIAoJCXsKCQkJZmxvYXQgYmFja3NldCA9IGFicyh2ZXJ0ZXhwb3MueSk7CgkJCXZlcnRleHBvcy55ID0gMDsKCQkJdmVydGV4cG9zLnggKz0gYmFja3NldCAqIHNpZ24oY29ybmVyLngpICogcGl4ZWxsZW5ndGgueC9waXhlbGxlbmd0aC55OwoJCQljb3ZlcmFnZSA9IChjb3ZlcmFnZSAtIC41KSAqIGFicyhjb3JuZXIueSkgLyAoYWJzKGNvcm5lci55KSArIGJhY2tzZXQpICsgLjU7CgkJfQoJfQoJZmxvYXQyeDIgc2tld21hdHJpeCA9IGZsb2F0MngyKHNrZXcueHksIHNrZXcuencpOwoJZmxvYXQyIGRldmNvb3JkID0gdmVydGV4cG9zICogc2tld21hdHJpeCArIHRyYW5zbGF0ZV9hbmRfbG9jYWxyb3RhdGUueHk7CglpZiAoMCAhPSBpc19saW5lYXJfY292ZXJhZ2UpIAoJewoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MigwLCBjb3ZlcmFnZSAqIGNvdmVyYWdlX211bHRpcGxpZXIpOwoJfQoJZWxzZSAKCXsKCQlmbG9hdDIgYXJjY29vcmQgPSAxIC0gYWJzKHJhZGl1c19vdXRzZXQpICsgYWFfb3V0c2V0L3JhZGlpICogY29ybmVyOwoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MihhcmNjb29yZC54KzEsIGFyY2Nvb3JkLnkpOwoJfQoJc2tfUG9zaXRpb24gPSBkZXZjb29yZC54eTAxOwp9CgAAAACZAgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCm5vcGVyc3BlY3RpdmUgaW4gaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2YXJjY29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBGaWxsUlJlY3RPcDo6UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJZmxvYXQgeF9wbHVzXzE9dmFyY2Nvb3JkX1MwLngsIHk9dmFyY2Nvb3JkX1MwLnk7CgloYWxmIGNvdmVyYWdlOwoJaWYgKDAgPT0geF9wbHVzXzEpIAoJewoJCWNvdmVyYWdlID0gaGFsZih5KTsKCX0KCWVsc2UgCgl7CgkJZmxvYXQgZm4gPSB4X3BsdXNfMSAqICh4X3BsdXNfMSAtIDIpOwoJCWZuID0gZm1hKHkseSwgZm4pOwoJCWZsb2F0IGZud2lkdGggPSBmd2lkdGgoZm4pOwoJCWNvdmVyYWdlID0gLjUgLSBoYWxmKGZuL2Zud2lkdGgpOwoJCWNvdmVyYWdlID0gY2xhbXAoY292ZXJhZ2UsIDAsIDEpOwoJfQoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChjb3ZlcmFnZSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAACAAAAA4AAAByYWRpaV9zZWxlY3RvcgAAGQAAAGNvcm5lcl9hbmRfcmFkaXVzX291dHNldHMAAAAVAAAAYWFfYmxvYXRfYW5kX2NvdmVyYWdlAAAABwAAAHJhZGlpX3gABwAAAHJhZGlpX3kABAAAAHNrZXcZAAAAdHJhbnNsYXRlX2FuZF9sb2NhbHJvdGF0ZQAAAAUAAABjb2xvcgAAAAAAAAA=","GYQACAAAAAMAADAAAIOAAAH677776IZOCAAP577777777777777777YBAAAAAAAAAAADEAAGAAAAAAAAAIAAAAAPAIABAAAAABAGEAAAAEAAAABNARCAIAAAAAAAAAAAAAYAGAAAAAQAAAAAAAQQGAAAAA":"DAAAAExTS1O8AQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzBfYzA7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7Cm5vcGVyc3BlY3RpdmUgb3V0IGhhbGY0IHZjb2xvcl9TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc180X1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCXZjb2xvcl9TMCA9IGNvbG9yOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwoJewoJCXZUcmFuc2Zvcm1lZENvb3Jkc180X1MwID0gZmxvYXQzeDIodW1hdHJpeF9TMV9jMF9jMCkgKiBwb3NpdGlvbi54eTE7Cgl9Cn0KAAAAAI0DAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxX2MwX2MwOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7Cm5vcGVyc3BlY3RpdmUgaW4gaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfNF9TMDsKaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMF9jMF9jMChoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MxLCB2VHJhbnNmb3JtZWRDb29yZHNfNF9TMCkuMDAwcjsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzBfYzBfYzAoX2lucHV0KTsKfQpoYWxmNCBEZXZpY2VTcGFjZV9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gTWF0cml4RWZmZWN0X1MxX2MwX2MwKF9pbnB1dCk7Cn0KaGFsZjQgQmxlbmRfUzEoaGFsZjQgX3NyYywgaGFsZjQgX2RzdCkgCnsKCXJldHVybiBibGVuZF9kc3RfaW4oRGV2aWNlU3BhY2VfUzFfYzAoX3NyYyksIF9zcmMpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQmxlbmRfUzEob3V0cHV0Q292ZXJhZ2VfUzAsIGhhbGY0KDEpKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgUAAABjb2xvcgAAAAAAAAA=","GZIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAHIBK2VD3EOCAAAAAABUXHIMAQAAAAWSQ4HO4SAAAAAMAAAAAEBUEFLMJAIAAAQCI6KVAYAAAAAAAAAAAQAAEACUA2JT4HAIAAAADIIODXOJIBAAAGAAAAACAKAC5XEQEAAAAAEPF2SMAAAAAAAAIAAAACXUUGB3XUUAQAADAAAAAAABARO3SJCAAAAACGSZJWCAAAAAAAIAAAABLFBUEFLMJAIAAAAAAAAAAACIMVSTUFAEAAAAAIAAAAAWFBSHSVIGAAAAAAAAAAAAABEBAABAAAAADIEEQCEAAAAAAAAAAAQAMQAAAAAAAQAAAABAMQAAA":"DAAAAExTS1PaAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzBfYzBfYzE7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfNl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfNl9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzFfYzBfYzBfYzEpICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAABAAAAcQkAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQp1bmlmb3JtIGhhbGY0IHVzdGFydF9TMV9jMF9jMF9jMDsKdW5pZm9ybSBoYWxmNCB1ZW5kX1MxX2MwX2MwX2MwOwp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzBfYzBfYzE7CnVuaWZvcm0gaGFsZjQgdWxlZnRCb3JkZXJDb2xvcl9TMV9jMF9jMDsKdW5pZm9ybSBoYWxmNCB1cmlnaHRCb3JkZXJDb2xvcl9TMV9jMF9jMDsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxX2MxOwp1bmlmb3JtIGhhbGYgdXJhbmdlX1MxOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7Cm5vcGVyc3BlY3RpdmUgaW4gaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfNl9TMDsKaGFsZjQgU2luZ2xlSW50ZXJ2YWxDb2xvcml6ZXJfUzFfYzBfYzBfYzAoaGFsZjQgX2lucHV0LCBmbG9hdDIgX2Nvb3JkcykgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJZmxvYXQyIF90bXBfMV9jb29yZHMgPSBfY29vcmRzOwoJcmV0dXJuIGhhbGY0KG1peCh1c3RhcnRfUzFfYzBfYzBfYzAsIHVlbmRfUzFfYzBfYzBfYzAsIGhhbGYoX3RtcF8xX2Nvb3Jkcy54KSkpOwp9CmhhbGY0IExpbmVhckxheW91dF9TMV9jMF9jMF9jMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzJfaW5Db2xvciA9IF9pbnB1dDsKCWZsb2F0MiBfdG1wXzNfY29vcmRzID0gdlRyYW5zZm9ybWVkQ29vcmRzXzZfUzA7CglyZXR1cm4gaGFsZjQoaGFsZjQoaGFsZihfdG1wXzNfY29vcmRzLngpICsgMWUtMDUsIDEuMCwgMC4wLCAwLjApKTsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzFfYzBfYzBfYzEoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIExpbmVhckxheW91dF9TMV9jMF9jMF9jMV9jMChfaW5wdXQpOwp9CmhhbGY0IENsYW1wZWRHcmFkaWVudF9TMV9jMF9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzRfaW5Db2xvciA9IF9pbnB1dDsKCWhhbGY0IHQgPSBNYXRyaXhFZmZlY3RfUzFfYzBfYzBfYzEoX3RtcF80X2luQ29sb3IpOwoJaGFsZjQgb3V0Q29sb3I7CglpZiAoIWJvb2woaW50KDEpKSAmJiB0LnkgPCAwLjApIAoJewoJCW91dENvbG9yID0gaGFsZjQoMC4wKTsKCX0KCWVsc2UgaWYgKHQueCA8IDAuMCkgCgl7CgkJb3V0Q29sb3IgPSB1bGVmdEJvcmRlckNvbG9yX1MxX2MwX2MwOwoJfQoJZWxzZSBpZiAodC54ID4gMS4wKSAKCXsKCQlvdXRDb2xvciA9IHVyaWdodEJvcmRlckNvbG9yX1MxX2MwX2MwOwoJfQoJZWxzZSAKCXsKCQlvdXRDb2xvciA9IFNpbmdsZUludGVydmFsQ29sb3JpemVyX1MxX2MwX2MwX2MwKF90bXBfNF9pbkNvbG9yLCBmbG9hdDIoaGFsZjIodC54LCAwLjApKSk7Cgl9CglyZXR1cm4gaGFsZjQob3V0Q29sb3IpOwp9CmhhbGY0IERpc2FibGVDb3ZlcmFnZUFzQWxwaGFfUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJX2lucHV0ID0gQ2xhbXBlZEdyYWRpZW50X1MxX2MwX2MwKF9pbnB1dCk7CgloYWxmNCBfdG1wXzVfaW5Db2xvciA9IF9pbnB1dDsKCXJldHVybiBoYWxmNChfaW5wdXQpOwp9CmhhbGY0IFRleHR1cmVFZmZlY3RfUzFfYzFfYzAoaGFsZjQgX2lucHV0LCBmbG9hdDIgX2Nvb3JkcykgCnsKCXJldHVybiBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzEsIF9jb29yZHMpLjAwMHI7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxX2MxKGhhbGY0IF9pbnB1dCwgZmxvYXQyIF9jb29yZHMpIAp7CglyZXR1cm4gVGV4dHVyZUVmZmVjdF9TMV9jMV9jMChfaW5wdXQsIGZsb2F0M3gyKHVtYXRyaXhfUzFfYzEpICogX2Nvb3Jkcy54eTEpOwp9CmhhbGY0IERpdGhlcl9TMShoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzZfaW5Db2xvciA9IF9pbnB1dDsKCWhhbGY0IGNvbG9yID0gRGlzYWJsZUNvdmVyYWdlQXNBbHBoYV9TMV9jMChfdG1wXzZfaW5Db2xvcik7CgloYWxmIHZhbHVlID0gTWF0cml4RWZmZWN0X1MxX2MxKF90bXBfNl9pbkNvbG9yLCBza19GcmFnQ29vcmQueHkpLncgLSAwLjU7CglyZXR1cm4gaGFsZjQoaGFsZjQoY2xhbXAoY29sb3IueHl6ICsgdmFsdWUgKiB1cmFuZ2VfUzEsIDAuMCwgY29sb3IudyksIGNvbG9yLncpKTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IERpdGhlcl9TMShvdXRwdXRDb2xvcl9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0X1MxICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAIAAAAcG9zaXRpb24FAAAAY29sb3IAAAAKAAAAbG9jYWxDb29yZAAAAAAAAA==","GYJAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAQAAAAAAQQGAAZAABQAAAAAAAACAAAAADYCAAIAAAAAIBRAAAABAAAAALIEIQCAAAAAAAAAAAAAGABQAAAAEAAAAAAAEEBQAAAA":"DAAAAExTS1PSAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzBfYzA7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2bG9jYWxDb29yZF9TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc180X1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCXZsb2NhbENvb3JkX1MwID0gbG9jYWxDb29yZDsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfNF9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzFfYzBfYzApICogcG9zaXRpb24ueHkxOwoJfQp9CgAAAAAAACUEAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxX2MwX2MwOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzA7CnNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMTsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc180X1MwOwpoYWxmNCBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzEsIHZUcmFuc2Zvcm1lZENvb3Jkc180X1MwKS4wMDByOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMV9jMF9jMChoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gVGV4dHVyZUVmZmVjdF9TMV9jMF9jMF9jMChfaW5wdXQpOwp9CmhhbGY0IERldmljZVNwYWNlX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoX2lucHV0KTsKfQpoYWxmNCBCbGVuZF9TMShoYWxmNCBfc3JjLCBoYWxmNCBfZHN0KSAKewoJcmV0dXJuIGJsZW5kX2RzdF9pbihEZXZpY2VTcGFjZV9TMV9jMChfc3JjKSwgX3NyYyk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWZsb2F0MiB0ZXhDb29yZDsKCXRleENvb3JkID0gdmxvY2FsQ29vcmRfUzA7CglvdXRwdXRDb2xvcl9TMCA9IChibGVuZF9tb2R1bGF0ZShzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzAsIHRleENvb3JkKSwgaGFsZjQoMSkpKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBCbGVuZF9TMShvdXRwdXRDb3ZlcmFnZV9TMCwgaGFsZjQoMSkpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0X1MxOwoJfQp9CgAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACAAAAHBvc2l0aW9uCgAAAGxvY2FsQ29vcmQAAAAAAAA=","GZIACAAAABQAAGAAAQ4AAAAAGQQAARC4GAAAIOCAAD6P7777777777YDAAAAAAAAAAAJQBBYGQ467YIAAAAAAQAAAAAMACTRNBZN5QYBAAAAAAAAAAAIAAJQAAAAAAAANAAAAAHQVERARJYAAAABQAAAABAAAAAA4BAQAAACAAAAASAMAAQAAAAAUCCYBCAAAAAAAAAAAAAANJABAAAMBJ4KECOAEAAAMAAAAAAAAEAABAAV6GUSECFHAAAAAGAAAAAAAAAAAAAGABQAAAAEAAAAAAAEEBQA":"DAAAAExTS1PdAgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMl9jMF9jMDsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdCBjb3ZlcmFnZTsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0IHZjb3ZlcmFnZV9TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzZfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQyIHBvc2l0aW9uID0gcG9zaXRpb24ueHk7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCXZjb3ZlcmFnZV9TMCA9IGNvdmVyYWdlOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwoJewoJCXZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwID0gZmxvYXQzeDIodW1hdHJpeF9TMSkgKiBsb2NhbENvb3JkLnh5MTsKCX0KCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfNl9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzJfYzBfYzApICogcG9zaXRpb24ueHkxOwoJfQp9CgAAAAEAAADvIQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCmZsb2F0NCBmbHV0dGVyX0ZyYWdDb29yZF9TMV9jMDsKZmxvYXQ0IGZyYWdDb2xvcl9TMV9jMDsKZmxvYXQgdV9hbHBoYV9TMV9jMDsKZmxvYXQgdV9zcGFya2xlX2FscGhhX1MxX2MwOwpmbG9hdCB1X2JsdXJfUzFfYzA7CmZsb2F0IHVfcmFkaXVzX3NjYWxlX1MxX2MwOwpjb25zdCBpbnQga0ZpbGxCV19TMl9jMV9jMCA9IDA7CmNvbnN0IGludCBrSW52ZXJzZUZpbGxCV19TMl9jMV9jMCA9IDI7CmNvbnN0IGludCBrSW52ZXJzZUZpbGxBQV9TMl9jMV9jMCA9IDM7CnVuaWZvcm0gZmxvYXQ0IHVfY29sb3JfUzFfYzA7CnVuaWZvcm0gZmxvYXQ0IHVfY29tcG9zaXRlXzFfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2VudGVyX1MxX2MwOwp1bmlmb3JtIGZsb2F0IHVfbWF4X3JhZGl1c19TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yZXNvbHV0aW9uX3NjYWxlX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X25vaXNlX3NjYWxlX1MxX2MwOwp1bmlmb3JtIGZsb2F0IHVfbm9pc2VfcGhhc2VfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2lyY2xlMV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jaXJjbGUyX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NpcmNsZTNfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcm90YXRpb24xX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3JvdGF0aW9uMl9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yb3RhdGlvbjNfUzFfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MyX2MwX2MwOwp1bmlmb3JtIGZsb2F0NCB1cmVjdFVuaWZvcm1fUzJfYzFfYzA7CnNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMjsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQgdmNvdmVyYWdlX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzZfUzA7CmZsb2F0MiBGTFRfZmx1dHRlcl9sb2NhbF9GbHV0dGVyRnJhZ0Nvb3JkX1MxX2MwKCk7CmZsb2F0MngyIEZMVF9mbHV0dGVyX2xvY2FsX3JvdGF0ZTJkX1MxX2MwKGZsb2F0MiByYWQpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCBibHVyKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAoZmxvYXQyIHJlc29sdXRpb24sIGlub3V0IGZsb2F0MiBwLCBmbG9hdDIgeHksIGZsb2F0MiByb3RhdGlvbiwgZmxvYXQgY2VsbF9kaWFtZXRlcik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3R1cmJ1bGVuY2VfUzFfYzAoZmxvYXQyIHV2KTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9yaW5nX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IHRoaWNrbmVzcywgZmxvYXQgYmx1cik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RyaWFuZ2xlX25vaXNlX1MxX2MwKGlub3V0IGZsb2F0MiBuKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKGZsb2F0IHYsIGZsb2F0IGwsIGZsb2F0IGgpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zcGFya2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQgdCk7CnZvaWQgRkxUX21haW5fUzFfYzAoKTsKZmxvYXQyIEZMVF9mbHV0dGVyX2xvY2FsX0ZsdXR0ZXJGcmFnQ29vcmRfUzFfYzAoKSAKewoJcmV0dXJuIGZsdXR0ZXJfRnJhZ0Nvb3JkX1MxX2MwLnh5Owp9CmZsb2F0MngyIEZMVF9mbHV0dGVyX2xvY2FsX3JvdGF0ZTJkX1MxX2MwKGZsb2F0MiByYWQpIAp7CglyZXR1cm4gZmxvYXQyeDIocmFkLngsIC1yYWQueSwgcmFkLnksIHJhZC54KTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCBibHVyKSAKewoJZmxvYXQgYmx1cl9oYWxmID0gYmx1ciAqIDAuNTsKCWZsb2F0IGQgPSBkaXN0YW5jZSh1diwgeHkpOwoJcmV0dXJuIDEuMCAtIHNtb290aHN0ZXAoMS4wIC0gYmx1cl9oYWxmLCAxLjAgKyBibHVyX2hhbGYsIGQgLyByYWRpdXMpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKGZsb2F0MiByZXNvbHV0aW9uLCBpbm91dCBmbG9hdDIgcCwgZmxvYXQyIHh5LCBmbG9hdDIgcm90YXRpb24sIGZsb2F0IGNlbGxfZGlhbWV0ZXIpIAp7CglmbG9hdDIgcGFyYW0gPSByb3RhdGlvbjsKCXAgPSBGTFRfZmx1dHRlcl9sb2NhbF9yb3RhdGUyZF9TMV9jMChwYXJhbSkgKiAoeHkgLSBwKSArIHh5OwoJcCA9IG1vZChwLCBmbG9hdDIoY2VsbF9kaWFtZXRlcikpIC8gcmVzb2x1dGlvbjsKCWZsb2F0IGNlbGxfdXYgPSAoY2VsbF9kaWFtZXRlciAvIHJlc29sdXRpb24ueSkgKiAwLjU7CglmbG9hdCByID0gMC42NSAqIGNlbGxfdXY7CglmbG9hdDIgcGFyYW1fMSA9IHA7CglmbG9hdDIgcGFyYW1fMiA9IGZsb2F0MihjZWxsX3V2KTsKCWZsb2F0IHBhcmFtXzMgPSByOwoJZmxvYXQgcGFyYW1fNCA9IHIgKiA1MC4wOwoJcmV0dXJuIEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMsIHBhcmFtXzQpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3R1cmJ1bGVuY2VfUzFfYzAoZmxvYXQyIHV2KSAKewoJZmxvYXQyIHV2X3NjYWxlID0gdXYgKiBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbSA9IGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtXzEgPSB1dl9zY2FsZTsKCWZsb2F0MiBwYXJhbV8yID0gdV9jaXJjbGUxX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzMgPSB1X3JvdGF0aW9uMV9TMV9jMDsKCWZsb2F0IHBhcmFtXzQgPSAwLjE3OwoJZmxvYXQgXzMxOSA9IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKHBhcmFtLCBwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zLCBwYXJhbV80KTsKCWZsb2F0IGcxID0gXzMxOTsKCWZsb2F0MiBwYXJhbV81ID0gZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW1fNiA9IHV2X3NjYWxlOwoJZmxvYXQyIHBhcmFtXzcgPSB1X2NpcmNsZTJfUzFfYzA7CglmbG9hdDIgcGFyYW1fOCA9IHVfcm90YXRpb24yX1MxX2MwOwoJZmxvYXQgcGFyYW1fOSA9IDAuMjsKCWZsb2F0IF8zMzEgPSBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChwYXJhbV81LCBwYXJhbV82LCBwYXJhbV83LCBwYXJhbV84LCBwYXJhbV85KTsKCWZsb2F0IGcyID0gXzMzMTsKCWZsb2F0MiBwYXJhbV8xMCA9IGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtXzExID0gdXZfc2NhbGU7CglmbG9hdDIgcGFyYW1fMTIgPSB1X2NpcmNsZTNfUzFfYzA7CglmbG9hdDIgcGFyYW1fMTMgPSB1X3JvdGF0aW9uM19TMV9jMDsKCWZsb2F0IHBhcmFtXzE0ID0gMC4yNzU7CglmbG9hdCBfMzQ0ID0gRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAocGFyYW1fMTAsIHBhcmFtXzExLCBwYXJhbV8xMiwgcGFyYW1fMTMsIHBhcmFtXzE0KTsKCWZsb2F0IGczID0gXzM0NDsKCWZsb2F0IHYgPSAoKGcxICogZzEgKyBnMikgLSBnMykgKiAwLjU7CglyZXR1cm4gY2xhbXAoMC40NSArIDAuOCAqIHYsIDAuMCwgMS4wKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X3JpbmdfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgdGhpY2tuZXNzLCBmbG9hdCBibHVyKSAKewoJZmxvYXQyIHBhcmFtID0gdXY7CglmbG9hdDIgcGFyYW1fMSA9IHh5OwoJZmxvYXQgcGFyYW1fMiA9IHJhZGl1cyArIHRoaWNrbmVzczsKCWZsb2F0IHBhcmFtXzMgPSBibHVyOwoJZmxvYXQgY2lyY2xlX291dGVyID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW0sIHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMpOwoJZmxvYXQyIHBhcmFtXzQgPSB1djsKCWZsb2F0MiBwYXJhbV81ID0geHk7CglmbG9hdCBwYXJhbV82ID0gbWF4KHJhZGl1cyAtIHRoaWNrbmVzcywgMC4wKTsKCWZsb2F0IHBhcmFtXzcgPSBibHVyOwoJZmxvYXQgY2lyY2xlX2lubmVyID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW1fNCwgcGFyYW1fNSwgcGFyYW1fNiwgcGFyYW1fNyk7CglyZXR1cm4gY2xhbXAoY2lyY2xlX291dGVyIC0gY2lyY2xlX2lubmVyLCAwLjAsIDEuMCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHJpYW5nbGVfbm9pc2VfUzFfYzAoaW5vdXQgZmxvYXQyIG4pIAp7CgluID0gZnJhY3QobiAqIGZsb2F0Mig1LjM5ODcsIDUuNDQyMSkpOwoJbiArPSBmbG9hdDIoZG90KG4ueXgsIG4gKyBmbG9hdDIoMjEuNTM1MSwgMTQuMzEzNykpKTsKCWZsb2F0IHh5ID0gbi54ICogbi55OwoJcmV0dXJuIChmcmFjdCh4eSAqIDk1LjQzMDcpICsgZnJhY3QoeHkgKiA3NS4wNDk2MSkpIC0gMS4wOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChmbG9hdCB2LCBmbG9hdCBsLCBmbG9hdCBoKSAKewoJcmV0dXJuIHN0ZXAobCwgdikgKiAoMS4wIC0gc3RlcChoLCB2KSk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc3BhcmtsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0IHQpIAp7CglmbG9hdDIgcGFyYW0gPSB1djsKCWZsb2F0IF8yNDIgPSBGTFRfZmx1dHRlcl9sb2NhbF90cmlhbmdsZV9ub2lzZV9TMV9jMChwYXJhbSk7CglmbG9hdCBuID0gXzI0MjsKCWZsb2F0IHBhcmFtXzEgPSBuOwoJZmxvYXQgcGFyYW1fMiA9IDAuMDsKCWZsb2F0IHBhcmFtXzMgPSAwLjA1OwoJZmxvYXQgcyA9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zKTsKCWZsb2F0IHBhcmFtXzQgPSBuICsgc2luKDMuMTQxNTkyNzQgKiAodCArIDAuMzUpKTsKCWZsb2F0IHBhcmFtXzUgPSAwLjE7CglmbG9hdCBwYXJhbV82ID0gMC4xNTsKCXMgKz0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzQsIHBhcmFtXzUsIHBhcmFtXzYpOwoJZmxvYXQgcGFyYW1fNyA9IG4gKyBzaW4oMy4xNDE1OTI3NCAqICh0ICsgMC43KSk7CglmbG9hdCBwYXJhbV84ID0gMC4yOwoJZmxvYXQgcGFyYW1fOSA9IDAuMjU7CglzICs9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV83LCBwYXJhbV84LCBwYXJhbV85KTsKCWZsb2F0IHBhcmFtXzEwID0gbiArIHNpbigzLjE0MTU5Mjc0ICogKHQgKyAxLjA1KSk7CglmbG9hdCBwYXJhbV8xMSA9IDAuMzsKCWZsb2F0IHBhcmFtXzEyID0gMC4zNTsKCXMgKz0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzEwLCBwYXJhbV8xMSwgcGFyYW1fMTIpOwoJcmV0dXJuIGNsYW1wKHMsIDAuMCwgMS4wKSAqIDAuNTU7Cn0Kdm9pZCBGTFRfbWFpbl9TMV9jMCgpIAp7Cgl1X2FscGhhX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC54OwoJdV9zcGFya2xlX2FscGhhX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC55OwoJdV9ibHVyX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC56OwoJdV9yYWRpdXNfc2NhbGVfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLnc7CglmbG9hdDIgcCA9IEZMVF9mbHV0dGVyX2xvY2FsX0ZsdXR0ZXJGcmFnQ29vcmRfUzFfYzAoKTsKCWZsb2F0MiB1dl8xID0gcCAqIHVfcmVzb2x1dGlvbl9zY2FsZV9TMV9jMDsKCWZsb2F0MiBkZW5zaXR5X3V2ID0gdXZfMSAtIG1vZChwLCB1X25vaXNlX3NjYWxlX1MxX2MwKTsKCWZsb2F0IHJhZGl1cyA9IHVfbWF4X3JhZGl1c19TMV9jMCAqIHVfcmFkaXVzX3NjYWxlX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzEzID0gdXZfMTsKCWZsb2F0IHR1cmJ1bGVuY2UgPSBGTFRfZmx1dHRlcl9sb2NhbF90dXJidWxlbmNlX1MxX2MwKHBhcmFtXzEzKTsKCWZsb2F0MiBwYXJhbV8xNCA9IHA7CglmbG9hdDIgcGFyYW1fMTUgPSB1X2NlbnRlcl9TMV9jMDsKCWZsb2F0IHBhcmFtXzE2ID0gcmFkaXVzOwoJZmxvYXQgcGFyYW1fMTcgPSAwLjA1ICogdV9tYXhfcmFkaXVzX1MxX2MwOwoJZmxvYXQgcGFyYW1fMTggPSB1X2JsdXJfUzFfYzA7CglmbG9hdCByaW5nID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9yaW5nX1MxX2MwKHBhcmFtXzE0LCBwYXJhbV8xNSwgcGFyYW1fMTYsIHBhcmFtXzE3LCBwYXJhbV8xOCk7CglmbG9hdDIgcGFyYW1fMTkgPSBkZW5zaXR5X3V2OwoJZmxvYXQgcGFyYW1fMjAgPSB1X25vaXNlX3BoYXNlX1MxX2MwOwoJZmxvYXQgc3BhcmtsZSA9ICgoRkxUX2ZsdXR0ZXJfbG9jYWxfc3BhcmtsZV9TMV9jMChwYXJhbV8xOSwgcGFyYW1fMjApICogcmluZykgKiB0dXJidWxlbmNlKSAqIHVfc3BhcmtsZV9hbHBoYV9TMV9jMDsKCWZsb2F0MiBwYXJhbV8yMSA9IHA7CglmbG9hdDIgcGFyYW1fMjIgPSB1X2NlbnRlcl9TMV9jMDsKCWZsb2F0IHBhcmFtXzIzID0gcmFkaXVzOwoJZmxvYXQgcGFyYW1fMjQgPSB1X2JsdXJfUzFfYzA7CglmbG9hdCB3YXZlX2FscGhhID0gKEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtXzIxLCBwYXJhbV8yMiwgcGFyYW1fMjMsIHBhcmFtXzI0KSAqIHVfYWxwaGFfUzFfYzApICogdV9jb2xvcl9TMV9jMC53OwoJZmxvYXQ0IHdhdmVfY29sb3IgPSBmbG9hdDQodV9jb2xvcl9TMV9jMC54eXogKiB3YXZlX2FscGhhLCB3YXZlX2FscGhhKTsKCWZyYWdDb2xvcl9TMV9jMCA9IG1peCh3YXZlX2NvbG9yLCBmbG9hdDQoMS4wKSwgZmxvYXQ0KHNwYXJrbGUpKTsKfQpoYWxmNCBydW50aW1lX3NoYWRlcl9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzBfaW5Db2xvciA9IF9pbnB1dDsKCWZsb2F0MiBfdG1wXzFfY29vcmRzID0gdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CglmbHV0dGVyX0ZyYWdDb29yZF9TMV9jMCA9IGZsb2F0NChfdG1wXzFfY29vcmRzLCAwLjAsIDAuMCk7CglGTFRfbWFpbl9TMV9jMCgpOwoJcmV0dXJuIGhhbGY0KGhhbGY0KGZyYWdDb2xvcl9TMV9jMCkpOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gcnVudGltZV9zaGFkZXJfUzFfYzAoX2lucHV0KTsKfQpoYWxmNCBUZXh0dXJlRWZmZWN0X1MyX2MwX2MwX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzIsIHZUcmFuc2Zvcm1lZENvb3Jkc182X1MwKS4wMDByOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMl9jMF9jMChoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gVGV4dHVyZUVmZmVjdF9TMl9jMF9jMF9jMChfaW5wdXQpOwp9CmhhbGY0IERldmljZVNwYWNlX1MyX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBNYXRyaXhFZmZlY3RfUzJfYzBfYzAoX2lucHV0KTsKfQpoYWxmNCBSZWN0X1MyX2MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMl9pbkNvbG9yID0gX2lucHV0OwoJaGFsZiBjb3ZlcmFnZTsKCWlmIChpbnQoMSkgPT0ga0ZpbGxCV19TMl9jMV9jMCB8fCBpbnQoMSkgPT0ga0ludmVyc2VGaWxsQldfUzJfYzFfYzApIAoJewoJCWNvdmVyYWdlID0gaGFsZihhbGwoZ3JlYXRlclRoYW4oZmxvYXQ0KHNrX0ZyYWdDb29yZC54eSwgdXJlY3RVbmlmb3JtX1MyX2MxX2MwLnp3KSwgZmxvYXQ0KHVyZWN0VW5pZm9ybV9TMl9jMV9jMC54eSwgc2tfRnJhZ0Nvb3JkLnh5KSkpKTsKCX0KCWVsc2UgCgl7CgkJaGFsZjQgZGlzdHM0ID0gc2F0dXJhdGUoaGFsZjQoMS4wLCAxLjAsIC0xLjAsIC0xLjApICogaGFsZjQoc2tfRnJhZ0Nvb3JkLnh5eHkgLSB1cmVjdFVuaWZvcm1fUzJfYzFfYzApKTsKCQloYWxmMiBkaXN0czIgPSAoZGlzdHM0Lnh5ICsgZGlzdHM0Lnp3KSAtIDEuMDsKCQljb3ZlcmFnZSA9IGRpc3RzMi54ICogZGlzdHMyLnk7Cgl9CglpZiAoaW50KDEpID09IGtJbnZlcnNlRmlsbEJXX1MyX2MxX2MwIHx8IGludCgxKSA9PSBrSW52ZXJzZUZpbGxBQV9TMl9jMV9jMCkgCgl7CgkJY292ZXJhZ2UgPSAxLjAgLSBjb3ZlcmFnZTsKCX0KCXJldHVybiBoYWxmNChoYWxmNChjb3ZlcmFnZSkpOwp9CmhhbGY0IEJsZW5kX1MyX2MxKGhhbGY0IF9zcmMsIGhhbGY0IF9kc3QpIAp7CglyZXR1cm4gYmxlbmRfbW9kdWxhdGUoUmVjdF9TMl9jMV9jMChfc3JjKSwgX3NyYyk7Cn0KaGFsZjQgQmxlbmRfUzIoaGFsZjQgX3NyYywgaGFsZjQgX2RzdCkgCnsKCXJldHVybiBibGVuZF9kc3RfaW4oRGV2aWNlU3BhY2VfUzJfYzAoX3NyYyksIEJsZW5kX1MyX2MxKF9zcmMsIF9kc3QpKTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJZmxvYXQgY292ZXJhZ2UgPSB2Y292ZXJhZ2VfUzA7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGNvdmVyYWdlKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IE1hdHJpeEVmZmVjdF9TMShvdXRwdXRDb2xvcl9TMCk7CgloYWxmNCBvdXRwdXRfUzI7CglvdXRwdXRfUzIgPSBCbGVuZF9TMihvdXRwdXRDb3ZlcmFnZV9TMCwgaGFsZjQoMSkpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dF9TMjsKCX0KfQoAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAAcG9zaXRpb24IAAAAY292ZXJhZ2UFAAAAY29sb3IAAAAKAAAAbG9jYWxDb29yZAAAAAAAAA==","G2QACAAAABAAADAAAIOAAAAADIIAAIRODAAP577774DSAIAA737777YBAAAAAAAAAAADAAYAAAACAAAAAAACCAYAAA":"DAAAAExTS1PqAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgcG9zaXRpb247CmluIGZsb2F0IGNvdmVyYWdlOwppbiBoYWxmNCBjb2xvcjsKaW4gZmxvYXQ0IGdlb21TdWJzZXQ7Cm5vcGVyc3BlY3RpdmUgb3V0IGhhbGY0IHZjb2xvcl9TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQgdmNvdmVyYWdlX1MwOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDQgdmdlb21TdWJzZXRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQyIHBvc2l0aW9uID0gcG9zaXRpb24ueHk7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCXZjb3ZlcmFnZV9TMCA9IGNvdmVyYWdlOwoJdmdlb21TdWJzZXRfUzAgPSBnZW9tU3Vic2V0OwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAQAAAKQCAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQgdmNvdmVyYWdlX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0NCB2Z2VvbVN1YnNldF9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWZsb2F0IGNvdmVyYWdlID0gdmNvdmVyYWdlX1MwOwoJZmxvYXQ0IGdlb1N1YnNldDsKCWdlb1N1YnNldCA9IHZnZW9tU3Vic2V0X1MwOwoJZmxvYXQ0IGRpc3RzNCA9IHNhdHVyYXRlKGZsb2F0NCgxLCAxLCAtMSwgLTEpICogKHNrX0ZyYWdDb29yZC54eXh5IC0gZ2VvU3Vic2V0KSk7CglmbG9hdDIgZGlzdHMyID0gZGlzdHM0Lnh5ICsgZGlzdHM0Lnp3IC0gMTsKCWNvdmVyYWdlID0gbWluKGNvdmVyYWdlLCBkaXN0czIueCAqIGRpc3RzMi55KTsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoY292ZXJhZ2UpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAAcG9zaXRpb24IAAAAY292ZXJhZ2UFAAAAY29sb3IAAAAKAAAAZ2VvbVN1YnNldAAAAAAAAA==","AYQA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAAAAB3QA6AAAEAAAAAAAMAAPEAEAAABAAAAAABTAAAAAAACAAAAAEBSAAAA":"DAAAAExTS1MlAgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0NCB1bG9jYWxNYXRyaXhfUzA7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiBmbG9hdDQgaW5DaXJjbGVFZGdlOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIENpcmNsZUdlb21ldHJ5UHJvY2Vzc29yCgl2aW5DaXJjbGVFZGdlX1MwID0gaW5DaXJjbGVFZGdlOwoJdmluQ29sb3JfUzAgPSBpbkNvbG9yOwoJZmxvYXQyIF90bXBfMF9pblBvc2l0aW9uID0gaW5Qb3NpdGlvbjsKCWZsb2F0MiBfdG1wXzFfaW5Qb3NpdGlvbiA9IHVsb2NhbE1hdHJpeF9TMC54eiAqIGluUG9zaXRpb24gKyB1bG9jYWxNYXRyaXhfUzAueXc7Cglza19Qb3NpdGlvbiA9IF90bXBfMF9pblBvc2l0aW9uLnh5MDE7Cn0KAAAAAQAAAHcFAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CnVuaWZvcm0gZmxvYXQ0IHVpbm5lclJlY3RfUzI7CnVuaWZvcm0gaGFsZjIgdXJhZGl1c1BsdXNIYWxmX1MyOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0NCB2aW5DaXJjbGVFZGdlX1MwOwpub3BlcnNwZWN0aXZlIGluIGhhbGY0IHZpbkNvbG9yX1MwOwpoYWxmNCBDaXJjdWxhclJSZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCWZsb2F0MiBkeHkwID0gdWlubmVyUmVjdF9TMS5MVCAtIHNrX0ZyYWdDb29yZC54eTsKCWZsb2F0MiBkeHkxID0gc2tfRnJhZ0Nvb3JkLnh5IC0gdWlubmVyUmVjdF9TMS5SQjsKCWZsb2F0MiBkeHkgPSBtYXgobWF4KGR4eTAsIGR4eTEpLCAwLjApOwoJaGFsZiBhbHBoYSA9IGhhbGYoc2F0dXJhdGUodXJhZGl1c1BsdXNIYWxmX1MxLnggLSBsZW5ndGgoZHh5KSkpOwoJYWxwaGEgPSAxLjAgLSBhbHBoYTsKCXJldHVybiBfaW5wdXQgKiBhbHBoYTsKfQpoYWxmNCBDaXJjdWxhclJSZWN0X1MyKGhhbGY0IF9pbnB1dCkgCnsKCWZsb2F0MiBkeHkwID0gdWlubmVyUmVjdF9TMi5MVCAtIHNrX0ZyYWdDb29yZC54eTsKCWZsb2F0MiBkeHkxID0gc2tfRnJhZ0Nvb3JkLnh5IC0gdWlubmVyUmVjdF9TMi5SQjsKCWZsb2F0MiBkeHkgPSBtYXgobWF4KGR4eTAsIGR4eTEpLCAwLjApOwoJaGFsZiBhbHBoYSA9IGhhbGYoc2F0dXJhdGUodXJhZGl1c1BsdXNIYWxmX1MyLnggLSBsZW5ndGgoZHh5KSkpOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQ0IGNpcmNsZUVkZ2U7CgljaXJjbGVFZGdlID0gdmluQ2lyY2xlRWRnZV9TMDsKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWZsb2F0IGQgPSBsZW5ndGgoY2lyY2xlRWRnZS54eSk7CgloYWxmIGRpc3RhbmNlVG9PdXRlckVkZ2UgPSBoYWxmKGNpcmNsZUVkZ2UueiAqICgxLjAgLSBkKSk7CgloYWxmIGVkZ2VBbHBoYSA9IHNhdHVyYXRlKGRpc3RhbmNlVG9PdXRlckVkZ2UpOwoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChlZGdlQWxwaGEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQ2lyY3VsYXJSUmVjdF9TMShvdXRwdXRDb3ZlcmFnZV9TMCk7CgloYWxmNCBvdXRwdXRfUzI7CglvdXRwdXRfUzIgPSBDaXJjdWxhclJSZWN0X1MyKG91dHB1dF9TMSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzI7Cgl9Cn0KAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACgAAAGluUG9zaXRpb24AAAcAAABpbkNvbG9yAAwAAABpbkNpcmNsZUVkZ2UAAAAA","EADQAAAAAEAAAAAUAABQAAQPAAABCFYMAAKAUEAAAAAAAAABAAAAAAAAAAAJQAIAAAABAAAAACAJAAIAAAAA":"DAAAAExTS1NtAgAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQyIHVBdGxhc0RpbWVuc2lvbnNJbnZfUzA7CmluIGZsb2F0MyBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiB1c2hvcnQyIGluVGV4dHVyZUNvb3JkczsKb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKb3V0IGZsb2F0IHZUZXhJbmRleF9TMDsKb3V0IGZsb2F0MiB2SW50VGV4dHVyZUNvb3Jkc19TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBEaXN0YW5jZUZpZWxkUGF0aAoJaW50IHRleElkeCA9IDA7CglmbG9hdDIgdW5vcm1UZXhDb29yZHMgPSBmbG9hdDIoaW5UZXh0dXJlQ29vcmRzLngsIGluVGV4dHVyZUNvb3Jkcy55KTsKCXZUZXh0dXJlQ29vcmRzX1MwID0gdW5vcm1UZXhDb29yZHMgKiB1QXRsYXNEaW1lbnNpb25zSW52X1MwOwoJdlRleEluZGV4X1MwID0gZmxvYXQodGV4SWR4KTsKCXZJbnRUZXh0dXJlQ29vcmRzX1MwID0gdW5vcm1UZXhDb29yZHM7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDMgX3RtcF8xX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBpblBvc2l0aW9uLnh5MHo7Cn0KAAAAAAAAAJICAABzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzA7CmluIGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKaW4gZmxvYXQgdlRleEluZGV4X1MwOwppbiBmbG9hdDIgdkludFRleHR1cmVDb29yZHNfUzA7CmluIGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgRGlzdGFuY2VGaWVsZFBhdGgKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWZsb2F0MiB1diA9IHZUZXh0dXJlQ29vcmRzX1MwOwoJaGFsZjQgdGV4Q29sb3I7Cgl7CgkJdGV4Q29sb3IgPSBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzAsIHV2KS5ycnJyOwoJfQoJaGFsZiBkaXN0YW5jZSA9IDcuOTY4NzUqKHRleENvbG9yLnIgLSAwLjUwMTk2MDc4NDMxKTsKCWhhbGYgYWZ3aWR0aDsKCWFmd2lkdGggPSBhYnMoMC42NSpoYWxmKGRGZHgodkludFRleHR1cmVDb29yZHNfUzAueCkpKTsKCWhhbGYgdmFsID0gc21vb3Roc3RlcCgtYWZ3aWR0aCwgYWZ3aWR0aCwgZGlzdGFuY2UpOwoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCh2YWwpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAoAAABpblBvc2l0aW9uAAAHAAAAaW5Db2xvcgAPAAAAaW5UZXh0dXJlQ29vcmRzAAAAAAA=","GZIACAAAABQAAGAAAQ4AAAAAGQQAARC4GAAAIOCAAD6P7777777777YDAAAAAAAAAAAJQBBYGQ467YIAAAAAAQAAAAAMACTRNBZN5QYBAAAAAAAAAAAIAALIAAAAB4FJEIEKOAAAAAMAAAAAEAHQAACAAAAAAYCFPSVARQRJAAAAABQAAAAAAAAAAA4JAPAAACAAAAAAACABSAAAAAAACAAAAAEBSAAA":"DAAAAExTS1M7AgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQgY292ZXJhZ2U7CmluIGhhbGY0IGNvbG9yOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdCB2Y292ZXJhZ2VfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDIgcG9zaXRpb24gPSBwb3NpdGlvbi54eTsKCXZjb2xvcl9TMCA9IGNvbG9yOwoJdmNvdmVyYWdlX1MwID0gY292ZXJhZ2U7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgABAAAANCEAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQpmbG9hdDQgZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzA7CmZsb2F0NCBmcmFnQ29sb3JfUzFfYzA7CmZsb2F0IHVfYWxwaGFfUzFfYzA7CmZsb2F0IHVfc3BhcmtsZV9hbHBoYV9TMV9jMDsKZmxvYXQgdV9ibHVyX1MxX2MwOwpmbG9hdCB1X3JhZGl1c19zY2FsZV9TMV9jMDsKY29uc3QgaW50IGtGaWxsQldfUzJfYzAgPSAwOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQldfUzJfYzAgPSAyOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQUFfUzJfYzAgPSAzOwp1bmlmb3JtIGZsb2F0NCB1X2NvbG9yX1MxX2MwOwp1bmlmb3JtIGZsb2F0NCB1X2NvbXBvc2l0ZV8xX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NlbnRlcl9TMV9jMDsKdW5pZm9ybSBmbG9hdCB1X21heF9yYWRpdXNfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcmVzb2x1dGlvbl9zY2FsZV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9ub2lzZV9zY2FsZV9TMV9jMDsKdW5pZm9ybSBmbG9hdCB1X25vaXNlX3BoYXNlX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NpcmNsZTFfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2lyY2xlMl9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jaXJjbGUzX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3JvdGF0aW9uMV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yb3RhdGlvbjJfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcm90YXRpb24zX1MxX2MwOwp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CnVuaWZvcm0gZmxvYXQ0IHVyZWN0VW5pZm9ybV9TMl9jMDsKdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMl9jMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzJfYzE7Cm5vcGVyc3BlY3RpdmUgaW4gaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0IHZjb3ZlcmFnZV9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CmZsb2F0MiBGTFRfZmx1dHRlcl9sb2NhbF9GbHV0dGVyRnJhZ0Nvb3JkX1MxX2MwKCk7CmZsb2F0MngyIEZMVF9mbHV0dGVyX2xvY2FsX3JvdGF0ZTJkX1MxX2MwKGZsb2F0MiByYWQpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCBibHVyKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAoZmxvYXQyIHJlc29sdXRpb24sIGlub3V0IGZsb2F0MiBwLCBmbG9hdDIgeHksIGZsb2F0MiByb3RhdGlvbiwgZmxvYXQgY2VsbF9kaWFtZXRlcik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3R1cmJ1bGVuY2VfUzFfYzAoZmxvYXQyIHV2KTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9yaW5nX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IHRoaWNrbmVzcywgZmxvYXQgYmx1cik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RyaWFuZ2xlX25vaXNlX1MxX2MwKGlub3V0IGZsb2F0MiBuKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKGZsb2F0IHYsIGZsb2F0IGwsIGZsb2F0IGgpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zcGFya2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQgdCk7CnZvaWQgRkxUX21haW5fUzFfYzAoKTsKZmxvYXQyIEZMVF9mbHV0dGVyX2xvY2FsX0ZsdXR0ZXJGcmFnQ29vcmRfUzFfYzAoKSAKewoJcmV0dXJuIGZsdXR0ZXJfRnJhZ0Nvb3JkX1MxX2MwLnh5Owp9CmZsb2F0MngyIEZMVF9mbHV0dGVyX2xvY2FsX3JvdGF0ZTJkX1MxX2MwKGZsb2F0MiByYWQpIAp7CglyZXR1cm4gZmxvYXQyeDIocmFkLngsIC1yYWQueSwgcmFkLnksIHJhZC54KTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCBibHVyKSAKewoJZmxvYXQgYmx1cl9oYWxmID0gYmx1ciAqIDAuNTsKCWZsb2F0IGQgPSBkaXN0YW5jZSh1diwgeHkpOwoJcmV0dXJuIDEuMCAtIHNtb290aHN0ZXAoMS4wIC0gYmx1cl9oYWxmLCAxLjAgKyBibHVyX2hhbGYsIGQgLyByYWRpdXMpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKGZsb2F0MiByZXNvbHV0aW9uLCBpbm91dCBmbG9hdDIgcCwgZmxvYXQyIHh5LCBmbG9hdDIgcm90YXRpb24sIGZsb2F0IGNlbGxfZGlhbWV0ZXIpIAp7CglmbG9hdDIgcGFyYW0gPSByb3RhdGlvbjsKCXAgPSBGTFRfZmx1dHRlcl9sb2NhbF9yb3RhdGUyZF9TMV9jMChwYXJhbSkgKiAoeHkgLSBwKSArIHh5OwoJcCA9IG1vZChwLCBmbG9hdDIoY2VsbF9kaWFtZXRlcikpIC8gcmVzb2x1dGlvbjsKCWZsb2F0IGNlbGxfdXYgPSAoY2VsbF9kaWFtZXRlciAvIHJlc29sdXRpb24ueSkgKiAwLjU7CglmbG9hdCByID0gMC42NSAqIGNlbGxfdXY7CglmbG9hdDIgcGFyYW1fMSA9IHA7CglmbG9hdDIgcGFyYW1fMiA9IGZsb2F0MihjZWxsX3V2KTsKCWZsb2F0IHBhcmFtXzMgPSByOwoJZmxvYXQgcGFyYW1fNCA9IHIgKiA1MC4wOwoJcmV0dXJuIEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMsIHBhcmFtXzQpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3R1cmJ1bGVuY2VfUzFfYzAoZmxvYXQyIHV2KSAKewoJZmxvYXQyIHV2X3NjYWxlID0gdXYgKiBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbSA9IGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtXzEgPSB1dl9zY2FsZTsKCWZsb2F0MiBwYXJhbV8yID0gdV9jaXJjbGUxX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzMgPSB1X3JvdGF0aW9uMV9TMV9jMDsKCWZsb2F0IHBhcmFtXzQgPSAwLjE3OwoJZmxvYXQgXzMxOSA9IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKHBhcmFtLCBwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zLCBwYXJhbV80KTsKCWZsb2F0IGcxID0gXzMxOTsKCWZsb2F0MiBwYXJhbV81ID0gZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW1fNiA9IHV2X3NjYWxlOwoJZmxvYXQyIHBhcmFtXzcgPSB1X2NpcmNsZTJfUzFfYzA7CglmbG9hdDIgcGFyYW1fOCA9IHVfcm90YXRpb24yX1MxX2MwOwoJZmxvYXQgcGFyYW1fOSA9IDAuMjsKCWZsb2F0IF8zMzEgPSBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChwYXJhbV81LCBwYXJhbV82LCBwYXJhbV83LCBwYXJhbV84LCBwYXJhbV85KTsKCWZsb2F0IGcyID0gXzMzMTsKCWZsb2F0MiBwYXJhbV8xMCA9IGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtXzExID0gdXZfc2NhbGU7CglmbG9hdDIgcGFyYW1fMTIgPSB1X2NpcmNsZTNfUzFfYzA7CglmbG9hdDIgcGFyYW1fMTMgPSB1X3JvdGF0aW9uM19TMV9jMDsKCWZsb2F0IHBhcmFtXzE0ID0gMC4yNzU7CglmbG9hdCBfMzQ0ID0gRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAocGFyYW1fMTAsIHBhcmFtXzExLCBwYXJhbV8xMiwgcGFyYW1fMTMsIHBhcmFtXzE0KTsKCWZsb2F0IGczID0gXzM0NDsKCWZsb2F0IHYgPSAoKGcxICogZzEgKyBnMikgLSBnMykgKiAwLjU7CglyZXR1cm4gY2xhbXAoMC40NSArIDAuOCAqIHYsIDAuMCwgMS4wKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X3JpbmdfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgdGhpY2tuZXNzLCBmbG9hdCBibHVyKSAKewoJZmxvYXQyIHBhcmFtID0gdXY7CglmbG9hdDIgcGFyYW1fMSA9IHh5OwoJZmxvYXQgcGFyYW1fMiA9IHJhZGl1cyArIHRoaWNrbmVzczsKCWZsb2F0IHBhcmFtXzMgPSBibHVyOwoJZmxvYXQgY2lyY2xlX291dGVyID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW0sIHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMpOwoJZmxvYXQyIHBhcmFtXzQgPSB1djsKCWZsb2F0MiBwYXJhbV81ID0geHk7CglmbG9hdCBwYXJhbV82ID0gbWF4KHJhZGl1cyAtIHRoaWNrbmVzcywgMC4wKTsKCWZsb2F0IHBhcmFtXzcgPSBibHVyOwoJZmxvYXQgY2lyY2xlX2lubmVyID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW1fNCwgcGFyYW1fNSwgcGFyYW1fNiwgcGFyYW1fNyk7CglyZXR1cm4gY2xhbXAoY2lyY2xlX291dGVyIC0gY2lyY2xlX2lubmVyLCAwLjAsIDEuMCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHJpYW5nbGVfbm9pc2VfUzFfYzAoaW5vdXQgZmxvYXQyIG4pIAp7CgluID0gZnJhY3QobiAqIGZsb2F0Mig1LjM5ODcsIDUuNDQyMSkpOwoJbiArPSBmbG9hdDIoZG90KG4ueXgsIG4gKyBmbG9hdDIoMjEuNTM1MSwgMTQuMzEzNykpKTsKCWZsb2F0IHh5ID0gbi54ICogbi55OwoJcmV0dXJuIChmcmFjdCh4eSAqIDk1LjQzMDcpICsgZnJhY3QoeHkgKiA3NS4wNDk2MSkpIC0gMS4wOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChmbG9hdCB2LCBmbG9hdCBsLCBmbG9hdCBoKSAKewoJcmV0dXJuIHN0ZXAobCwgdikgKiAoMS4wIC0gc3RlcChoLCB2KSk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc3BhcmtsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0IHQpIAp7CglmbG9hdDIgcGFyYW0gPSB1djsKCWZsb2F0IF8yNDIgPSBGTFRfZmx1dHRlcl9sb2NhbF90cmlhbmdsZV9ub2lzZV9TMV9jMChwYXJhbSk7CglmbG9hdCBuID0gXzI0MjsKCWZsb2F0IHBhcmFtXzEgPSBuOwoJZmxvYXQgcGFyYW1fMiA9IDAuMDsKCWZsb2F0IHBhcmFtXzMgPSAwLjA1OwoJZmxvYXQgcyA9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zKTsKCWZsb2F0IHBhcmFtXzQgPSBuICsgc2luKDMuMTQxNTkyNzQgKiAodCArIDAuMzUpKTsKCWZsb2F0IHBhcmFtXzUgPSAwLjE7CglmbG9hdCBwYXJhbV82ID0gMC4xNTsKCXMgKz0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzQsIHBhcmFtXzUsIHBhcmFtXzYpOwoJZmxvYXQgcGFyYW1fNyA9IG4gKyBzaW4oMy4xNDE1OTI3NCAqICh0ICsgMC43KSk7CglmbG9hdCBwYXJhbV84ID0gMC4yOwoJZmxvYXQgcGFyYW1fOSA9IDAuMjU7CglzICs9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV83LCBwYXJhbV84LCBwYXJhbV85KTsKCWZsb2F0IHBhcmFtXzEwID0gbiArIHNpbigzLjE0MTU5Mjc0ICogKHQgKyAxLjA1KSk7CglmbG9hdCBwYXJhbV8xMSA9IDAuMzsKCWZsb2F0IHBhcmFtXzEyID0gMC4zNTsKCXMgKz0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzEwLCBwYXJhbV8xMSwgcGFyYW1fMTIpOwoJcmV0dXJuIGNsYW1wKHMsIDAuMCwgMS4wKSAqIDAuNTU7Cn0Kdm9pZCBGTFRfbWFpbl9TMV9jMCgpIAp7Cgl1X2FscGhhX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC54OwoJdV9zcGFya2xlX2FscGhhX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC55OwoJdV9ibHVyX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC56OwoJdV9yYWRpdXNfc2NhbGVfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLnc7CglmbG9hdDIgcCA9IEZMVF9mbHV0dGVyX2xvY2FsX0ZsdXR0ZXJGcmFnQ29vcmRfUzFfYzAoKTsKCWZsb2F0MiB1dl8xID0gcCAqIHVfcmVzb2x1dGlvbl9zY2FsZV9TMV9jMDsKCWZsb2F0MiBkZW5zaXR5X3V2ID0gdXZfMSAtIG1vZChwLCB1X25vaXNlX3NjYWxlX1MxX2MwKTsKCWZsb2F0IHJhZGl1cyA9IHVfbWF4X3JhZGl1c19TMV9jMCAqIHVfcmFkaXVzX3NjYWxlX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzEzID0gdXZfMTsKCWZsb2F0IHR1cmJ1bGVuY2UgPSBGTFRfZmx1dHRlcl9sb2NhbF90dXJidWxlbmNlX1MxX2MwKHBhcmFtXzEzKTsKCWZsb2F0MiBwYXJhbV8xNCA9IHA7CglmbG9hdDIgcGFyYW1fMTUgPSB1X2NlbnRlcl9TMV9jMDsKCWZsb2F0IHBhcmFtXzE2ID0gcmFkaXVzOwoJZmxvYXQgcGFyYW1fMTcgPSAwLjA1ICogdV9tYXhfcmFkaXVzX1MxX2MwOwoJZmxvYXQgcGFyYW1fMTggPSB1X2JsdXJfUzFfYzA7CglmbG9hdCByaW5nID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9yaW5nX1MxX2MwKHBhcmFtXzE0LCBwYXJhbV8xNSwgcGFyYW1fMTYsIHBhcmFtXzE3LCBwYXJhbV8xOCk7CglmbG9hdDIgcGFyYW1fMTkgPSBkZW5zaXR5X3V2OwoJZmxvYXQgcGFyYW1fMjAgPSB1X25vaXNlX3BoYXNlX1MxX2MwOwoJZmxvYXQgc3BhcmtsZSA9ICgoRkxUX2ZsdXR0ZXJfbG9jYWxfc3BhcmtsZV9TMV9jMChwYXJhbV8xOSwgcGFyYW1fMjApICogcmluZykgKiB0dXJidWxlbmNlKSAqIHVfc3BhcmtsZV9hbHBoYV9TMV9jMDsKCWZsb2F0MiBwYXJhbV8yMSA9IHA7CglmbG9hdDIgcGFyYW1fMjIgPSB1X2NlbnRlcl9TMV9jMDsKCWZsb2F0IHBhcmFtXzIzID0gcmFkaXVzOwoJZmxvYXQgcGFyYW1fMjQgPSB1X2JsdXJfUzFfYzA7CglmbG9hdCB3YXZlX2FscGhhID0gKEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtXzIxLCBwYXJhbV8yMiwgcGFyYW1fMjMsIHBhcmFtXzI0KSAqIHVfYWxwaGFfUzFfYzApICogdV9jb2xvcl9TMV9jMC53OwoJZmxvYXQ0IHdhdmVfY29sb3IgPSBmbG9hdDQodV9jb2xvcl9TMV9jMC54eXogKiB3YXZlX2FscGhhLCB3YXZlX2FscGhhKTsKCWZyYWdDb2xvcl9TMV9jMCA9IG1peCh3YXZlX2NvbG9yLCBmbG9hdDQoMS4wKSwgZmxvYXQ0KHNwYXJrbGUpKTsKfQpoYWxmNCBydW50aW1lX3NoYWRlcl9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzBfaW5Db2xvciA9IF9pbnB1dDsKCWZsb2F0MiBfdG1wXzFfY29vcmRzID0gdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CglmbHV0dGVyX0ZyYWdDb29yZF9TMV9jMCA9IGZsb2F0NChfdG1wXzFfY29vcmRzLCAwLjAsIDAuMCk7CglGTFRfbWFpbl9TMV9jMCgpOwoJcmV0dXJuIGhhbGY0KGhhbGY0KGZyYWdDb2xvcl9TMV9jMCkpOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gcnVudGltZV9zaGFkZXJfUzFfYzAoX2lucHV0KTsKfQpoYWxmNCBSZWN0X1MyX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMl9pbkNvbG9yID0gX2lucHV0OwoJaGFsZiBjb3ZlcmFnZTsKCWlmIChpbnQoMSkgPT0ga0ZpbGxCV19TMl9jMCB8fCBpbnQoMSkgPT0ga0ludmVyc2VGaWxsQldfUzJfYzApIAoJewoJCWNvdmVyYWdlID0gaGFsZihhbGwoZ3JlYXRlclRoYW4oZmxvYXQ0KHNrX0ZyYWdDb29yZC54eSwgdXJlY3RVbmlmb3JtX1MyX2MwLnp3KSwgZmxvYXQ0KHVyZWN0VW5pZm9ybV9TMl9jMC54eSwgc2tfRnJhZ0Nvb3JkLnh5KSkpKTsKCX0KCWVsc2UgCgl7CgkJaGFsZjQgZGlzdHM0ID0gc2F0dXJhdGUoaGFsZjQoMS4wLCAxLjAsIC0xLjAsIC0xLjApICogaGFsZjQoc2tfRnJhZ0Nvb3JkLnh5eHkgLSB1cmVjdFVuaWZvcm1fUzJfYzApKTsKCQloYWxmMiBkaXN0czIgPSAoZGlzdHM0Lnh5ICsgZGlzdHM0Lnp3KSAtIDEuMDsKCQljb3ZlcmFnZSA9IGRpc3RzMi54ICogZGlzdHMyLnk7Cgl9CglpZiAoaW50KDEpID09IGtJbnZlcnNlRmlsbEJXX1MyX2MwIHx8IGludCgxKSA9PSBrSW52ZXJzZUZpbGxBQV9TMl9jMCkgCgl7CgkJY292ZXJhZ2UgPSAxLjAgLSBjb3ZlcmFnZTsKCX0KCXJldHVybiBoYWxmNChoYWxmNChjb3ZlcmFnZSkpOwp9CmhhbGY0IENpcmN1bGFyUlJlY3RfUzJfYzEoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MyX2MxLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MyX2MxLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CgloYWxmIGFscGhhID0gaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzJfYzEueCAtIGxlbmd0aChkeHkpKSk7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0KaGFsZjQgQmxlbmRfUzIoaGFsZjQgX3NyYywgaGFsZjQgX2RzdCkgCnsKCXJldHVybiBibGVuZF9tb2R1bGF0ZShSZWN0X1MyX2MwKF9zcmMpLCBDaXJjdWxhclJSZWN0X1MyX2MxKF9zcmMpKTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJZmxvYXQgY292ZXJhZ2UgPSB2Y292ZXJhZ2VfUzA7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGNvdmVyYWdlKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IE1hdHJpeEVmZmVjdF9TMShvdXRwdXRDb2xvcl9TMCk7CgloYWxmNCBvdXRwdXRfUzI7CglvdXRwdXRfUzIgPSBCbGVuZF9TMihvdXRwdXRDb3ZlcmFnZV9TMCwgaGFsZjQoMSkpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dF9TMjsKCX0KfQoBAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAgAAABwb3NpdGlvbggAAABjb3ZlcmFnZQUAAABjb2xvcgAAAAoAAABsb2NhbENvb3JkAAAAAAAA","GZIACAAAABQAAGAAAQ4AAAAAGQQAARC4GAAAIOCAAD6P7777777777YDAAAAAAAAAAAJQBBYGQ467YIAAAAAAQAAAAAMACTRNBZN5QYBAAAAAAAAAAAIAA4IAEAAACAAAAAABGABAAAAAEAAAAAIBEABAA":"DAAAAExTS1M7AgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQgY292ZXJhZ2U7CmluIGhhbGY0IGNvbG9yOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdCB2Y292ZXJhZ2VfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDIgcG9zaXRpb24gPSBwb3NpdGlvbi54eTsKCXZjb2xvcl9TMCA9IGNvbG9yOwoJdmNvdmVyYWdlX1MwID0gY292ZXJhZ2U7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgABAAAAEh4AACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQpmbG9hdDQgZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzA7CmZsb2F0NCBmcmFnQ29sb3JfUzFfYzA7CmZsb2F0IHVfYWxwaGFfUzFfYzA7CmZsb2F0IHVfc3BhcmtsZV9hbHBoYV9TMV9jMDsKZmxvYXQgdV9ibHVyX1MxX2MwOwpmbG9hdCB1X3JhZGl1c19zY2FsZV9TMV9jMDsKdW5pZm9ybSBmbG9hdDQgdV9jb2xvcl9TMV9jMDsKdW5pZm9ybSBmbG9hdDQgdV9jb21wb3NpdGVfMV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jZW50ZXJfUzFfYzA7CnVuaWZvcm0gZmxvYXQgdV9tYXhfcmFkaXVzX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3Jlc29sdXRpb25fc2NhbGVfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfbm9pc2Vfc2NhbGVfUzFfYzA7CnVuaWZvcm0gZmxvYXQgdV9ub2lzZV9waGFzZV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jaXJjbGUxX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NpcmNsZTJfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2lyY2xlM19TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yb3RhdGlvbjFfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcm90YXRpb24yX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3JvdGF0aW9uM19TMV9jMDsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxOwp1bmlmb3JtIGZsb2F0NCB1aW5uZXJSZWN0X1MyOwp1bmlmb3JtIGhhbGYyIHVyYWRpdXNQbHVzSGFsZl9TMjsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQgdmNvdmVyYWdlX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKZmxvYXQyIEZMVF9mbHV0dGVyX2xvY2FsX0ZsdXR0ZXJGcmFnQ29vcmRfUzFfYzAoKTsKZmxvYXQyeDIgRkxUX2ZsdXR0ZXJfbG9jYWxfcm90YXRlMmRfUzFfYzAoZmxvYXQyIHJhZCk7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IGJsdXIpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChmbG9hdDIgcmVzb2x1dGlvbiwgaW5vdXQgZmxvYXQyIHAsIGZsb2F0MiB4eSwgZmxvYXQyIHJvdGF0aW9uLCBmbG9hdCBjZWxsX2RpYW1ldGVyKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHVyYnVsZW5jZV9TMV9jMChmbG9hdDIgdXYpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X3JpbmdfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgdGhpY2tuZXNzLCBmbG9hdCBibHVyKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHJpYW5nbGVfbm9pc2VfUzFfYzAoaW5vdXQgZmxvYXQyIG4pOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAoZmxvYXQgdiwgZmxvYXQgbCwgZmxvYXQgaCk7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NwYXJrbGVfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdCB0KTsKdm9pZCBGTFRfbWFpbl9TMV9jMCgpOwpmbG9hdDIgRkxUX2ZsdXR0ZXJfbG9jYWxfRmx1dHRlckZyYWdDb29yZF9TMV9jMCgpIAp7CglyZXR1cm4gZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzAueHk7Cn0KZmxvYXQyeDIgRkxUX2ZsdXR0ZXJfbG9jYWxfcm90YXRlMmRfUzFfYzAoZmxvYXQyIHJhZCkgCnsKCXJldHVybiBmbG9hdDJ4MihyYWQueCwgLXJhZC55LCByYWQueSwgcmFkLngpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IGJsdXIpIAp7CglmbG9hdCBibHVyX2hhbGYgPSBibHVyICogMC41OwoJZmxvYXQgZCA9IGRpc3RhbmNlKHV2LCB4eSk7CglyZXR1cm4gMS4wIC0gc21vb3Roc3RlcCgxLjAgLSBibHVyX2hhbGYsIDEuMCArIGJsdXJfaGFsZiwgZCAvIHJhZGl1cyk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAoZmxvYXQyIHJlc29sdXRpb24sIGlub3V0IGZsb2F0MiBwLCBmbG9hdDIgeHksIGZsb2F0MiByb3RhdGlvbiwgZmxvYXQgY2VsbF9kaWFtZXRlcikgCnsKCWZsb2F0MiBwYXJhbSA9IHJvdGF0aW9uOwoJcCA9IEZMVF9mbHV0dGVyX2xvY2FsX3JvdGF0ZTJkX1MxX2MwKHBhcmFtKSAqICh4eSAtIHApICsgeHk7CglwID0gbW9kKHAsIGZsb2F0MihjZWxsX2RpYW1ldGVyKSkgLyByZXNvbHV0aW9uOwoJZmxvYXQgY2VsbF91diA9IChjZWxsX2RpYW1ldGVyIC8gcmVzb2x1dGlvbi55KSAqIDAuNTsKCWZsb2F0IHIgPSAwLjY1ICogY2VsbF91djsKCWZsb2F0MiBwYXJhbV8xID0gcDsKCWZsb2F0MiBwYXJhbV8yID0gZmxvYXQyKGNlbGxfdXYpOwoJZmxvYXQgcGFyYW1fMyA9IHI7CglmbG9hdCBwYXJhbV80ID0gciAqIDUwLjA7CglyZXR1cm4gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW1fMSwgcGFyYW1fMiwgcGFyYW1fMywgcGFyYW1fNCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHVyYnVsZW5jZV9TMV9jMChmbG9hdDIgdXYpIAp7CglmbG9hdDIgdXZfc2NhbGUgPSB1diAqIGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtID0gZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW1fMSA9IHV2X3NjYWxlOwoJZmxvYXQyIHBhcmFtXzIgPSB1X2NpcmNsZTFfUzFfYzA7CglmbG9hdDIgcGFyYW1fMyA9IHVfcm90YXRpb24xX1MxX2MwOwoJZmxvYXQgcGFyYW1fNCA9IDAuMTc7CglmbG9hdCBfMzE5ID0gRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAocGFyYW0sIHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMsIHBhcmFtXzQpOwoJZmxvYXQgZzEgPSBfMzE5OwoJZmxvYXQyIHBhcmFtXzUgPSBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbV82ID0gdXZfc2NhbGU7CglmbG9hdDIgcGFyYW1fNyA9IHVfY2lyY2xlMl9TMV9jMDsKCWZsb2F0MiBwYXJhbV84ID0gdV9yb3RhdGlvbjJfUzFfYzA7CglmbG9hdCBwYXJhbV85ID0gMC4yOwoJZmxvYXQgXzMzMSA9IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKHBhcmFtXzUsIHBhcmFtXzYsIHBhcmFtXzcsIHBhcmFtXzgsIHBhcmFtXzkpOwoJZmxvYXQgZzIgPSBfMzMxOwoJZmxvYXQyIHBhcmFtXzEwID0gZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW1fMTEgPSB1dl9zY2FsZTsKCWZsb2F0MiBwYXJhbV8xMiA9IHVfY2lyY2xlM19TMV9jMDsKCWZsb2F0MiBwYXJhbV8xMyA9IHVfcm90YXRpb24zX1MxX2MwOwoJZmxvYXQgcGFyYW1fMTQgPSAwLjI3NTsKCWZsb2F0IF8zNDQgPSBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChwYXJhbV8xMCwgcGFyYW1fMTEsIHBhcmFtXzEyLCBwYXJhbV8xMywgcGFyYW1fMTQpOwoJZmxvYXQgZzMgPSBfMzQ0OwoJZmxvYXQgdiA9ICgoZzEgKiBnMSArIGcyKSAtIGczKSAqIDAuNTsKCXJldHVybiBjbGFtcCgwLjQ1ICsgMC44ICogdiwgMC4wLCAxLjApOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfcmluZ19TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCB0aGlja25lc3MsIGZsb2F0IGJsdXIpIAp7CglmbG9hdDIgcGFyYW0gPSB1djsKCWZsb2F0MiBwYXJhbV8xID0geHk7CglmbG9hdCBwYXJhbV8yID0gcmFkaXVzICsgdGhpY2tuZXNzOwoJZmxvYXQgcGFyYW1fMyA9IGJsdXI7CglmbG9hdCBjaXJjbGVfb3V0ZXIgPSBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChwYXJhbSwgcGFyYW1fMSwgcGFyYW1fMiwgcGFyYW1fMyk7CglmbG9hdDIgcGFyYW1fNCA9IHV2OwoJZmxvYXQyIHBhcmFtXzUgPSB4eTsKCWZsb2F0IHBhcmFtXzYgPSBtYXgocmFkaXVzIC0gdGhpY2tuZXNzLCAwLjApOwoJZmxvYXQgcGFyYW1fNyA9IGJsdXI7CglmbG9hdCBjaXJjbGVfaW5uZXIgPSBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChwYXJhbV80LCBwYXJhbV81LCBwYXJhbV82LCBwYXJhbV83KTsKCXJldHVybiBjbGFtcChjaXJjbGVfb3V0ZXIgLSBjaXJjbGVfaW5uZXIsIDAuMCwgMS4wKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90cmlhbmdsZV9ub2lzZV9TMV9jMChpbm91dCBmbG9hdDIgbikgCnsKCW4gPSBmcmFjdChuICogZmxvYXQyKDUuMzk4NywgNS40NDIxKSk7CgluICs9IGZsb2F0Mihkb3Qobi55eCwgbiArIGZsb2F0MigyMS41MzUxLCAxNC4zMTM3KSkpOwoJZmxvYXQgeHkgPSBuLnggKiBuLnk7CglyZXR1cm4gKGZyYWN0KHh5ICogOTUuNDMwNykgKyBmcmFjdCh4eSAqIDc1LjA0OTYxKSkgLSAxLjA7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKGZsb2F0IHYsIGZsb2F0IGwsIGZsb2F0IGgpIAp7CglyZXR1cm4gc3RlcChsLCB2KSAqICgxLjAgLSBzdGVwKGgsIHYpKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zcGFya2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQgdCkgCnsKCWZsb2F0MiBwYXJhbSA9IHV2OwoJZmxvYXQgXzI0MiA9IEZMVF9mbHV0dGVyX2xvY2FsX3RyaWFuZ2xlX25vaXNlX1MxX2MwKHBhcmFtKTsKCWZsb2F0IG4gPSBfMjQyOwoJZmxvYXQgcGFyYW1fMSA9IG47CglmbG9hdCBwYXJhbV8yID0gMC4wOwoJZmxvYXQgcGFyYW1fMyA9IDAuMDU7CglmbG9hdCBzID0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMpOwoJZmxvYXQgcGFyYW1fNCA9IG4gKyBzaW4oMy4xNDE1OTI3NCAqICh0ICsgMC4zNSkpOwoJZmxvYXQgcGFyYW1fNSA9IDAuMTsKCWZsb2F0IHBhcmFtXzYgPSAwLjE1OwoJcyArPSBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAocGFyYW1fNCwgcGFyYW1fNSwgcGFyYW1fNik7CglmbG9hdCBwYXJhbV83ID0gbiArIHNpbigzLjE0MTU5Mjc0ICogKHQgKyAwLjcpKTsKCWZsb2F0IHBhcmFtXzggPSAwLjI7CglmbG9hdCBwYXJhbV85ID0gMC4yNTsKCXMgKz0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzcsIHBhcmFtXzgsIHBhcmFtXzkpOwoJZmxvYXQgcGFyYW1fMTAgPSBuICsgc2luKDMuMTQxNTkyNzQgKiAodCArIDEuMDUpKTsKCWZsb2F0IHBhcmFtXzExID0gMC4zOwoJZmxvYXQgcGFyYW1fMTIgPSAwLjM1OwoJcyArPSBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAocGFyYW1fMTAsIHBhcmFtXzExLCBwYXJhbV8xMik7CglyZXR1cm4gY2xhbXAocywgMC4wLCAxLjApICogMC41NTsKfQp2b2lkIEZMVF9tYWluX1MxX2MwKCkgCnsKCXVfYWxwaGFfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLng7Cgl1X3NwYXJrbGVfYWxwaGFfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLnk7Cgl1X2JsdXJfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLno7Cgl1X3JhZGl1c19zY2FsZV9TMV9jMCA9IHVfY29tcG9zaXRlXzFfUzFfYzAudzsKCWZsb2F0MiBwID0gRkxUX2ZsdXR0ZXJfbG9jYWxfRmx1dHRlckZyYWdDb29yZF9TMV9jMCgpOwoJZmxvYXQyIHV2XzEgPSBwICogdV9yZXNvbHV0aW9uX3NjYWxlX1MxX2MwOwoJZmxvYXQyIGRlbnNpdHlfdXYgPSB1dl8xIC0gbW9kKHAsIHVfbm9pc2Vfc2NhbGVfUzFfYzApOwoJZmxvYXQgcmFkaXVzID0gdV9tYXhfcmFkaXVzX1MxX2MwICogdV9yYWRpdXNfc2NhbGVfUzFfYzA7CglmbG9hdDIgcGFyYW1fMTMgPSB1dl8xOwoJZmxvYXQgdHVyYnVsZW5jZSA9IEZMVF9mbHV0dGVyX2xvY2FsX3R1cmJ1bGVuY2VfUzFfYzAocGFyYW1fMTMpOwoJZmxvYXQyIHBhcmFtXzE0ID0gcDsKCWZsb2F0MiBwYXJhbV8xNSA9IHVfY2VudGVyX1MxX2MwOwoJZmxvYXQgcGFyYW1fMTYgPSByYWRpdXM7CglmbG9hdCBwYXJhbV8xNyA9IDAuMDUgKiB1X21heF9yYWRpdXNfUzFfYzA7CglmbG9hdCBwYXJhbV8xOCA9IHVfYmx1cl9TMV9jMDsKCWZsb2F0IHJpbmcgPSBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X3JpbmdfUzFfYzAocGFyYW1fMTQsIHBhcmFtXzE1LCBwYXJhbV8xNiwgcGFyYW1fMTcsIHBhcmFtXzE4KTsKCWZsb2F0MiBwYXJhbV8xOSA9IGRlbnNpdHlfdXY7CglmbG9hdCBwYXJhbV8yMCA9IHVfbm9pc2VfcGhhc2VfUzFfYzA7CglmbG9hdCBzcGFya2xlID0gKChGTFRfZmx1dHRlcl9sb2NhbF9zcGFya2xlX1MxX2MwKHBhcmFtXzE5LCBwYXJhbV8yMCkgKiByaW5nKSAqIHR1cmJ1bGVuY2UpICogdV9zcGFya2xlX2FscGhhX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzIxID0gcDsKCWZsb2F0MiBwYXJhbV8yMiA9IHVfY2VudGVyX1MxX2MwOwoJZmxvYXQgcGFyYW1fMjMgPSByYWRpdXM7CglmbG9hdCBwYXJhbV8yNCA9IHVfYmx1cl9TMV9jMDsKCWZsb2F0IHdhdmVfYWxwaGEgPSAoRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW1fMjEsIHBhcmFtXzIyLCBwYXJhbV8yMywgcGFyYW1fMjQpICogdV9hbHBoYV9TMV9jMCkgKiB1X2NvbG9yX1MxX2MwLnc7CglmbG9hdDQgd2F2ZV9jb2xvciA9IGZsb2F0NCh1X2NvbG9yX1MxX2MwLnh5eiAqIHdhdmVfYWxwaGEsIHdhdmVfYWxwaGEpOwoJZnJhZ0NvbG9yX1MxX2MwID0gbWl4KHdhdmVfY29sb3IsIGZsb2F0NCgxLjApLCBmbG9hdDQoc3BhcmtsZSkpOwp9CmhhbGY0IHJ1bnRpbWVfc2hhZGVyX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJZmxvYXQyIF90bXBfMV9jb29yZHMgPSB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKCWZsdXR0ZXJfRnJhZ0Nvb3JkX1MxX2MwID0gZmxvYXQ0KF90bXBfMV9jb29yZHMsIDAuMCwgMC4wKTsKCUZMVF9tYWluX1MxX2MwKCk7CglyZXR1cm4gaGFsZjQoaGFsZjQoZnJhZ0NvbG9yX1MxX2MwKSk7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBydW50aW1lX3NoYWRlcl9TMV9jMChfaW5wdXQpOwp9CmhhbGY0IENpcmN1bGFyUlJlY3RfUzIoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQgZHkwID0gdWlubmVyUmVjdF9TMi5UIC0gc2tfRnJhZ0Nvb3JkLnk7CglmbG9hdDIgZHh5MSA9IHNrX0ZyYWdDb29yZC54eSAtIHVpbm5lclJlY3RfUzIuUkI7CglmbG9hdDIgZHh5ID0gbWF4KGZsb2F0MihkeHkxLngsIG1heChkeTAsIGR4eTEueSkpLCAwLjApOwoJaGFsZiBsZWZ0QWxwaGEgPSBoYWxmKHNhdHVyYXRlKHNrX0ZyYWdDb29yZC54IC0gdWlubmVyUmVjdF9TMi5MKSk7CgloYWxmIGFscGhhID0gbGVmdEFscGhhICogaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzIueCAtIGxlbmd0aChkeHkpKSk7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWZsb2F0IGNvdmVyYWdlID0gdmNvdmVyYWdlX1MwOwoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChjb3ZlcmFnZSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBNYXRyaXhFZmZlY3RfUzEob3V0cHV0Q29sb3JfUzApOwoJaGFsZjQgb3V0cHV0X1MyOwoJb3V0cHV0X1MyID0gQ2lyY3VsYXJSUmVjdF9TMihvdXRwdXRDb3ZlcmFnZV9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0X1MxICogb3V0cHV0X1MyOwoJfQp9CgAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAAcG9zaXRpb24IAAAAY292ZXJhZ2UFAAAAY29sb3IAAAAKAAAAbG9jYWxDb29yZAAAAAAAAA==","AYAA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAAAAMYAAAAAAAQAAAABAMQAAAAA":"DAAAAExTS1PbAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgaW5Qb3NpdGlvbjsKaW4gaGFsZjQgaW5Db2xvcjsKaW4gZmxvYXQ0IGluQ2lyY2xlRWRnZTsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQ0IHZpbkNpcmNsZUVkZ2VfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJdmluQ2lyY2xlRWRnZV9TMCA9IGluQ2lyY2xlRWRnZTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8yX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgAAAAAAQwIAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQpub3BlcnNwZWN0aXZlIGluIGZsb2F0NCB2aW5DaXJjbGVFZGdlX1MwOwpub3BlcnNwZWN0aXZlIGluIGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgQ2lyY2xlR2VvbWV0cnlQcm9jZXNzb3IKCWZsb2F0NCBjaXJjbGVFZGdlOwoJY2lyY2xlRWRnZSA9IHZpbkNpcmNsZUVkZ2VfUzA7CgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmluQ29sb3JfUzA7CglmbG9hdCBkID0gbGVuZ3RoKGNpcmNsZUVkZ2UueHkpOwoJaGFsZiBkaXN0YW5jZVRvT3V0ZXJFZGdlID0gaGFsZihjaXJjbGVFZGdlLnogKiAoMS4wIC0gZCkpOwoJaGFsZiBlZGdlQWxwaGEgPSBzYXR1cmF0ZShkaXN0YW5jZVRvT3V0ZXJFZGdlKTsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoZWRnZUFscGhhKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAoAAABpblBvc2l0aW9uAAAHAAAAaW5Db2xvcgAMAAAAaW5DaXJjbGVFZGdlAAAAAA==","GYQACAAAAAMAADAAAIOAAAH677776IZOCAAP577777777777777777YBAAAAAAAAAAAHEADZAAAAAAIAAAAAAMYAAAAAAAQAAAABAMQAAAAAA":"DAAAAExTS1MaAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgcG9zaXRpb247CmluIGhhbGY0IGNvbG9yOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2Y29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cn0KAAABAAAA5gIAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQp1bmlmb3JtIGZsb2F0NCB1aW5uZXJSZWN0X1MxOwp1bmlmb3JtIGhhbGYyIHVyYWRpdXNQbHVzSGFsZl9TMTsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2Y29sb3JfUzA7CmhhbGY0IENpcmN1bGFyUlJlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MxLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MxLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CgloYWxmIGFscGhhID0gaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzEueCAtIGxlbmd0aChkeHkpKSk7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBDaXJjdWxhclJSZWN0X1MxKG91dHB1dENvdmVyYWdlX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAAAAAAAA==","G2QACAAAABAAADAAAIOAAAAADIIAAIRODAAP577774DSAIAA737777YBAAAAAAAAAAAHEADZAAAAAAIAAAAAAMYAAAAAAAQAAAABAMQAAAAAA":"DAAAAExTS1PqAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgcG9zaXRpb247CmluIGZsb2F0IGNvdmVyYWdlOwppbiBoYWxmNCBjb2xvcjsKaW4gZmxvYXQ0IGdlb21TdWJzZXQ7Cm5vcGVyc3BlY3RpdmUgb3V0IGhhbGY0IHZjb2xvcl9TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQgdmNvdmVyYWdlX1MwOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDQgdmdlb21TdWJzZXRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQyIHBvc2l0aW9uID0gcG9zaXRpb24ueHk7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCXZjb3ZlcmFnZV9TMCA9IGNvdmVyYWdlOwoJdmdlb21TdWJzZXRfUzAgPSBnZW9tU3Vic2V0OwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAQAAADMEAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7Cm5vcGVyc3BlY3RpdmUgaW4gaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0IHZjb3ZlcmFnZV9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdDQgdmdlb21TdWJzZXRfUzA7CmhhbGY0IENpcmN1bGFyUlJlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MxLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MxLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CgloYWxmIGFscGhhID0gaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzEueCAtIGxlbmd0aChkeHkpKSk7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWZsb2F0IGNvdmVyYWdlID0gdmNvdmVyYWdlX1MwOwoJZmxvYXQ0IGdlb1N1YnNldDsKCWdlb1N1YnNldCA9IHZnZW9tU3Vic2V0X1MwOwoJZmxvYXQ0IGRpc3RzNCA9IHNhdHVyYXRlKGZsb2F0NCgxLCAxLCAtMSwgLTEpICogKHNrX0ZyYWdDb29yZC54eXh5IC0gZ2VvU3Vic2V0KSk7CglmbG9hdDIgZGlzdHMyID0gZGlzdHM0Lnh5ICsgZGlzdHM0Lnp3IC0gMTsKCWNvdmVyYWdlID0gbWluKGNvdmVyYWdlLCBkaXN0czIueCAqIGRpc3RzMi55KTsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoY292ZXJhZ2UpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQ2lyY3VsYXJSUmVjdF9TMShvdXRwdXRDb3ZlcmFnZV9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAHBvc2l0aW9uCAAAAGNvdmVyYWdlBQAAAGNvbG9yAAAACgAAAGdlb21TdWJzZXQAAAAAAAA=","CMRQCIAABBYAAAEIXBAAACDQMAABRAFAAAAAAAAAAAAAAAGABQAAAAEAAAAAAAEEBQAAAAA":"DAAAAExTS1OZAgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0NCB1bG9jYWxNYXRyaXhfUzA7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiBmbG9hdDIgaW5FbGxpcHNlT2Zmc2V0OwppbiBmbG9hdDQgaW5FbGxpcHNlUmFkaWk7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2RWxsaXBzZU9mZnNldHNfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0NCB2RWxsaXBzZVJhZGlpX1MwOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgRWxsaXBzZUdlb21ldHJ5UHJvY2Vzc29yCgl2RWxsaXBzZU9mZnNldHNfUzAgPSBpbkVsbGlwc2VPZmZzZXQ7Cgl2RWxsaXBzZVJhZGlpX1MwID0gaW5FbGxpcHNlUmFkaWk7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8wX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJZmxvYXQyIF90bXBfMV9pblBvc2l0aW9uID0gdWxvY2FsTWF0cml4X1MwLnh6ICogaW5Qb3NpdGlvbiArIHVsb2NhbE1hdHJpeF9TMC55dzsKCXNrX1Bvc2l0aW9uID0gX3RtcF8wX2luUG9zaXRpb24ueHkwMTsKfQoAAAAAAAAA2QMAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2RWxsaXBzZU9mZnNldHNfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQ0IHZFbGxpcHNlUmFkaWlfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBFbGxpcHNlR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWZsb2F0MiBvZmZzZXQgPSB2RWxsaXBzZU9mZnNldHNfUzAueHk7CglvZmZzZXQgKj0gdkVsbGlwc2VSYWRpaV9TMC54eTsKCWZsb2F0IHRlc3QgPSBkb3Qob2Zmc2V0LCBvZmZzZXQpIC0gMS4wOwoJZmxvYXQyIGdyYWQgPSAyLjAqb2Zmc2V0KnZFbGxpcHNlUmFkaWlfUzAueHk7CglmbG9hdCBncmFkX2RvdCA9IGRvdChncmFkLCBncmFkKTsKCWdyYWRfZG90ID0gbWF4KGdyYWRfZG90LCAxLjE3NTVlLTM4KTsKCWZsb2F0IGludmxlbiA9IGludmVyc2VzcXJ0KGdyYWRfZG90KTsKCWZsb2F0IGVkZ2VBbHBoYSA9IHNhdHVyYXRlKDAuNS10ZXN0Kmludmxlbik7CglvZmZzZXQgPSB2RWxsaXBzZU9mZnNldHNfUzAueHkqdkVsbGlwc2VSYWRpaV9TMC56dzsKCXRlc3QgPSBkb3Qob2Zmc2V0LCBvZmZzZXQpIC0gMS4wOwoJZ3JhZCA9IDIuMCpvZmZzZXQqdkVsbGlwc2VSYWRpaV9TMC56dzsKCWdyYWRfZG90ID0gZG90KGdyYWQsIGdyYWQpOwoJaW52bGVuID0gaW52ZXJzZXNxcnQoZ3JhZF9kb3QpOwoJZWRnZUFscGhhICo9IHNhdHVyYXRlKDAuNSt0ZXN0Kmludmxlbik7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGhhbGYoZWRnZUFscGhhKSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAoAAABpblBvc2l0aW9uAAAHAAAAaW5Db2xvcgAPAAAAaW5FbGxpcHNlT2Zmc2V0AA4AAABpbkVsbGlwc2VSYWRpaQAAAAAAAA==","GYJAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAQAAAAAAQQGAAZAADIAAAAIH5K3LIKAAAAAAMAAAAAIAAAAAAFMZBQP3FQWAUAABQAAAAAAAAAAAAADGAAAAAAAEAAAAAIDEAAA":"DAAAAExTS1MwAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgcG9zaXRpb247CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmxvY2FsQ29vcmRfUzAgPSBsb2NhbENvb3JkOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgEAAADzBAAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCmNvbnN0IGludCBrRmlsbEFBX1MxX2MwID0gMTsKY29uc3QgaW50IGtJbnZlcnNlRmlsbEJXX1MxX2MwID0gMjsKY29uc3QgaW50IGtJbnZlcnNlRmlsbEFBX1MxX2MwID0gMzsKdW5pZm9ybSBmbG9hdDQgdWNpcmNsZV9TMV9jMDsKc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2bG9jYWxDb29yZF9TMDsKaGFsZjQgQ2lyY2xlX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJaGFsZiBkOwoJaWYgKGludCgxKSA9PSBrSW52ZXJzZUZpbGxCV19TMV9jMCB8fCBpbnQoMSkgPT0ga0ludmVyc2VGaWxsQUFfUzFfYzApIAoJewoJCWQgPSBoYWxmKChsZW5ndGgoKHVjaXJjbGVfUzFfYzAueHkgLSBza19GcmFnQ29vcmQueHkpICogdWNpcmNsZV9TMV9jMC53KSAtIDEuMCkgKiB1Y2lyY2xlX1MxX2MwLnopOwoJfQoJZWxzZSAKCXsKCQlkID0gaGFsZigoMS4wIC0gbGVuZ3RoKCh1Y2lyY2xlX1MxX2MwLnh5IC0gc2tfRnJhZ0Nvb3JkLnh5KSAqIHVjaXJjbGVfUzFfYzAudykpICogdWNpcmNsZV9TMV9jMC56KTsKCX0KCXJldHVybiBoYWxmNChoYWxmNChpbnQoMSkgPT0ga0ZpbGxBQV9TMV9jMCB8fCBpbnQoMSkgPT0ga0ludmVyc2VGaWxsQUFfUzFfYzAgPyBzYXR1cmF0ZShkKSA6IGhhbGYoZCA+IDAuNSkpKTsKfQpoYWxmNCBCbGVuZF9TMShoYWxmNCBfc3JjLCBoYWxmNCBfZHN0KSAKewoJcmV0dXJuIGJsZW5kX21vZHVsYXRlKF9zcmMsIENpcmNsZV9TMV9jMChfc3JjKSk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWZsb2F0MiB0ZXhDb29yZDsKCXRleENvb3JkID0gdmxvY2FsQ29vcmRfUzA7CglvdXRwdXRDb2xvcl9TMCA9IChibGVuZF9tb2R1bGF0ZShzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzAsIHRleENvb3JkKSwgaGFsZjQoMSkpKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBCbGVuZF9TMShvdXRwdXRDb3ZlcmFnZV9TMCwgaGFsZjQoMSkpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0X1MxOwoJfQp9CgABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgoAAABsb2NhbENvb3JkAAAAAAAA","EEAQMYAAMAAAEADAAABAEYAAAICIAB5AABQAAAQAMAAAEATAAABAIIGAAEDCBYQCA4AAAAAAEAB5AAAAAAYFRP5FIUAQAADQAAAABAAAAAAABQEKBTLG62KRAAAAAHAAAAAAAAAAAAYAGAAAAAQAAAAAAAQQGAAA":"DAAAAExTS1MoDAAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDQgcmFkaWlfc2VsZWN0b3I7CmluIGZsb2F0NCBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzOwppbiBmbG9hdDQgYWFfYmxvYXRfYW5kX2NvdmVyYWdlOwppbiBmbG9hdDQgcmFkaWlfeDsKaW4gZmxvYXQ0IHJhZGlpX3k7CmluIGZsb2F0NCBza2V3OwppbiBmbG9hdDIgdHJhbnNsYXRlX2FuZF9sb2NhbHJvdGF0ZTsKaW4gaGFsZjQgY29sb3I7Cm5vcGVyc3BlY3RpdmUgb3V0IGhhbGY0IHZjb2xvcl9TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQyIHZhcmNjb29yZF9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgRmlsbFJSZWN0T3A6OlByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7CglmbG9hdCBhYV9ibG9hdF9tdWx0aXBsaWVyID0gMTsKCWZsb2F0MiBjb3JuZXIgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnh5OwoJZmxvYXQyIHJhZGl1c19vdXRzZXQgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnp3OwoJZmxvYXQyIGFhX2Jsb2F0X2RpcmVjdGlvbiA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS54eTsKCWZsb2F0IGlzX2xpbmVhcl9jb3ZlcmFnZSA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS53OwoJZmxvYXQyIHBpeGVsbGVuZ3RoID0gaW52ZXJzZXNxcnQoZmxvYXQyKGRvdChza2V3Lnh6LCBza2V3Lnh6KSwgZG90KHNrZXcueXcsIHNrZXcueXcpKSk7CglmbG9hdDQgbm9ybWFsaXplZF9heGlzX2RpcnMgPSBza2V3ICogcGl4ZWxsZW5ndGgueHl4eTsKCWZsb2F0MiBheGlzd2lkdGhzID0gKGFicyhub3JtYWxpemVkX2F4aXNfZGlycy54eSkgKyBhYnMobm9ybWFsaXplZF9heGlzX2RpcnMuencpKTsKCWZsb2F0MiBhYV9ibG9hdHJhZGl1cyA9IGF4aXN3aWR0aHMgKiBwaXhlbGxlbmd0aCAqIC41OwoJZmxvYXQ0IHJhZGlpX2FuZF9uZWlnaGJvcnMgPSByYWRpaV9zZWxlY3RvciogZmxvYXQ0eDQocmFkaWlfeCwgcmFkaWlfeSwgcmFkaWlfeC55eHd6LCByYWRpaV95Lnd6eXgpOwoJZmxvYXQyIHJhZGlpID0gcmFkaWlfYW5kX25laWdoYm9ycy54eTsKCWZsb2F0MiBuZWlnaGJvcl9yYWRpaSA9IHJhZGlpX2FuZF9uZWlnaGJvcnMuenc7CglmbG9hdCBjb3ZlcmFnZV9tdWx0aXBsaWVyID0gMTsKCWlmIChhbnkoZ3JlYXRlclRoYW4oYWFfYmxvYXRyYWRpdXMsIGZsb2F0MigxKSkpKSAKCXsKCQljb3JuZXIgPSBtYXgoYWJzKGNvcm5lciksIGFhX2Jsb2F0cmFkaXVzKSAqIHNpZ24oY29ybmVyKTsKCQljb3ZlcmFnZV9tdWx0aXBsaWVyID0gMSAvIChtYXgoYWFfYmxvYXRyYWRpdXMueCwgMSkgKiBtYXgoYWFfYmxvYXRyYWRpdXMueSwgMSkpOwoJCXJhZGlpID0gZmxvYXQyKDApOwoJfQoJZmxvYXQgY292ZXJhZ2UgPSBhYV9ibG9hdF9hbmRfY292ZXJhZ2UuejsKCWlmIChhbnkobGVzc1RoYW4ocmFkaWksIGFhX2Jsb2F0cmFkaXVzICogMS41KSkpIAoJewoJCXJhZGlpID0gZmxvYXQyKDApOwoJCWFhX2Jsb2F0X2RpcmVjdGlvbiA9IHNpZ24oY29ybmVyKTsKCQlpZiAoY292ZXJhZ2UgPiAuNSkgCgkJewoJCQlhYV9ibG9hdF9kaXJlY3Rpb24gPSAtYWFfYmxvYXRfZGlyZWN0aW9uOwoJCX0KCQlpc19saW5lYXJfY292ZXJhZ2UgPSAxOwoJfQoJZWxzZSAKCXsKCQlyYWRpaSA9IGNsYW1wKHJhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQluZWlnaGJvcl9yYWRpaSA9IGNsYW1wKG5laWdoYm9yX3JhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQlmbG9hdDIgc3BhY2luZyA9IDIgLSByYWRpaSAtIG5laWdoYm9yX3JhZGlpOwoJCWZsb2F0MiBleHRyYV9wYWQgPSBtYXgocGl4ZWxsZW5ndGggKiAuMDYyNSAtIHNwYWNpbmcsIGZsb2F0MigwKSk7CgkJcmFkaWkgLT0gZXh0cmFfcGFkICogLjU7Cgl9CglmbG9hdDIgYWFfb3V0c2V0ID0gYWFfYmxvYXRfZGlyZWN0aW9uICogYWFfYmxvYXRyYWRpdXMgKiBhYV9ibG9hdF9tdWx0aXBsaWVyOwoJZmxvYXQyIHZlcnRleHBvcyA9IGNvcm5lciArIHJhZGl1c19vdXRzZXQgKiByYWRpaSArIGFhX291dHNldDsKCWlmIChjb3ZlcmFnZSA+IC41KSAKCXsKCQlpZiAoYWFfYmxvYXRfZGlyZWN0aW9uLnggIT0gMCAmJiB2ZXJ0ZXhwb3MueCAqIGNvcm5lci54IDwgMCkgCgkJewoJCQlmbG9hdCBiYWNrc2V0ID0gYWJzKHZlcnRleHBvcy54KTsKCQkJdmVydGV4cG9zLnggPSAwOwoJCQl2ZXJ0ZXhwb3MueSArPSBiYWNrc2V0ICogc2lnbihjb3JuZXIueSkgKiBwaXhlbGxlbmd0aC55L3BpeGVsbGVuZ3RoLng7CgkJCWNvdmVyYWdlID0gKGNvdmVyYWdlIC0gLjUpICogYWJzKGNvcm5lci54KSAvIChhYnMoY29ybmVyLngpICsgYmFja3NldCkgKyAuNTsKCQl9CgkJaWYgKGFhX2Jsb2F0X2RpcmVjdGlvbi55ICE9IDAgJiYgdmVydGV4cG9zLnkgKiBjb3JuZXIueSA8IDApIAoJCXsKCQkJZmxvYXQgYmFja3NldCA9IGFicyh2ZXJ0ZXhwb3MueSk7CgkJCXZlcnRleHBvcy55ID0gMDsKCQkJdmVydGV4cG9zLnggKz0gYmFja3NldCAqIHNpZ24oY29ybmVyLngpICogcGl4ZWxsZW5ndGgueC9waXhlbGxlbmd0aC55OwoJCQljb3ZlcmFnZSA9IChjb3ZlcmFnZSAtIC41KSAqIGFicyhjb3JuZXIueSkgLyAoYWJzKGNvcm5lci55KSArIGJhY2tzZXQpICsgLjU7CgkJfQoJfQoJZmxvYXQyeDIgc2tld21hdHJpeCA9IGZsb2F0MngyKHNrZXcueHksIHNrZXcuencpOwoJZmxvYXQyIGRldmNvb3JkID0gdmVydGV4cG9zICogc2tld21hdHJpeCArIHRyYW5zbGF0ZV9hbmRfbG9jYWxyb3RhdGUueHk7CglpZiAoMCAhPSBpc19saW5lYXJfY292ZXJhZ2UpIAoJewoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MigwLCBjb3ZlcmFnZSAqIGNvdmVyYWdlX211bHRpcGxpZXIpOwoJfQoJZWxzZSAKCXsKCQlmbG9hdDIgYXJjY29vcmQgPSAxIC0gYWJzKHJhZGl1c19vdXRzZXQpICsgYWFfb3V0c2V0L3JhZGlpICogY29ybmVyOwoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MihhcmNjb29yZC54KzEsIGFyY2Nvb3JkLnkpOwoJfQoJc2tfUG9zaXRpb24gPSBkZXZjb29yZC54eTAxOwp9CgEAAACdBQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCmNvbnN0IGludCBrRmlsbEFBX1MxX2MwID0gMTsKY29uc3QgaW50IGtJbnZlcnNlRmlsbEJXX1MxX2MwID0gMjsKY29uc3QgaW50IGtJbnZlcnNlRmlsbEFBX1MxX2MwID0gMzsKdW5pZm9ybSBmbG9hdDQgdWNpcmNsZV9TMV9jMDsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQyIHZhcmNjb29yZF9TMDsKaGFsZjQgQ2lyY2xlX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJaGFsZiBkOwoJaWYgKGludCgzKSA9PSBrSW52ZXJzZUZpbGxCV19TMV9jMCB8fCBpbnQoMykgPT0ga0ludmVyc2VGaWxsQUFfUzFfYzApIAoJewoJCWQgPSBoYWxmKChsZW5ndGgoKHVjaXJjbGVfUzFfYzAueHkgLSBza19GcmFnQ29vcmQueHkpICogdWNpcmNsZV9TMV9jMC53KSAtIDEuMCkgKiB1Y2lyY2xlX1MxX2MwLnopOwoJfQoJZWxzZSAKCXsKCQlkID0gaGFsZigoMS4wIC0gbGVuZ3RoKCh1Y2lyY2xlX1MxX2MwLnh5IC0gc2tfRnJhZ0Nvb3JkLnh5KSAqIHVjaXJjbGVfUzFfYzAudykpICogdWNpcmNsZV9TMV9jMC56KTsKCX0KCXJldHVybiBoYWxmNChoYWxmNChpbnQoMykgPT0ga0ZpbGxBQV9TMV9jMCB8fCBpbnQoMykgPT0ga0ludmVyc2VGaWxsQUFfUzFfYzAgPyBzYXR1cmF0ZShkKSA6IGhhbGYoZCA+IDAuNSkpKTsKfQpoYWxmNCBCbGVuZF9TMShoYWxmNCBfc3JjLCBoYWxmNCBfZHN0KSAKewoJcmV0dXJuIGJsZW5kX21vZHVsYXRlKF9zcmMsIENpcmNsZV9TMV9jMChfc3JjKSk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIEZpbGxSUmVjdE9wOjpQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7CglmbG9hdCB4X3BsdXNfMT12YXJjY29vcmRfUzAueCwgeT12YXJjY29vcmRfUzAueTsKCWhhbGYgY292ZXJhZ2U7CglpZiAoMCA9PSB4X3BsdXNfMSkgCgl7CgkJY292ZXJhZ2UgPSBoYWxmKHkpOwoJfQoJZWxzZSAKCXsKCQlmbG9hdCBmbiA9IHhfcGx1c18xICogKHhfcGx1c18xIC0gMik7CgkJZm4gPSBmbWEoeSx5LCBmbik7CgkJZmxvYXQgZm53aWR0aCA9IGZ3aWR0aChmbik7CgkJY292ZXJhZ2UgPSAuNSAtIGhhbGYoZm4vZm53aWR0aCk7CgkJY292ZXJhZ2UgPSBjbGFtcChjb3ZlcmFnZSwgMCwgMSk7Cgl9CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGNvdmVyYWdlKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IEJsZW5kX1MxKG91dHB1dENvdmVyYWdlX1MwLCBoYWxmNCgxKSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAOAAAAcmFkaWlfc2VsZWN0b3IAABkAAABjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzAAAAFQAAAGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZQAAAAcAAAByYWRpaV94AAcAAAByYWRpaV95AAQAAABza2V3GQAAAHRyYW5zbGF0ZV9hbmRfbG9jYWxyb3RhdGUAAAAFAAAAY29sb3IAAAAAAAAA","AYTRVAADQAAAOAEARAFQJAABBADAAAILBYAACCYUQD777777777767YAAAAAAAAAAAAMYAAAAAAAQAAAABAMQAAAAA":"DAAAAExTS1PnAgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0NCB1bG9jYWxNYXRyaXhfUzA7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiBmbG9hdDQgaW5DaXJjbGVFZGdlOwppbiBoYWxmMyBpbkNsaXBQbGFuZTsKaW4gaGFsZjMgaW5Jc2VjdFBsYW5lOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjMgdmluQ2xpcFBsYW5lX1MwOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmMyB2aW5Jc2VjdFBsYW5lX1MwOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgQ2lyY2xlR2VvbWV0cnlQcm9jZXNzb3IKCXZpbkNpcmNsZUVkZ2VfUzAgPSBpbkNpcmNsZUVkZ2U7Cgl2aW5DbGlwUGxhbmVfUzAgPSBpbkNsaXBQbGFuZTsKCXZpbklzZWN0UGxhbmVfUzAgPSBpbklzZWN0UGxhbmU7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8wX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJZmxvYXQyIF90bXBfMV9pblBvc2l0aW9uID0gdWxvY2FsTWF0cml4X1MwLnh6ICogaW5Qb3NpdGlvbiArIHVsb2NhbE1hdHJpeF9TMC55dzsKCXNrX1Bvc2l0aW9uID0gX3RtcF8wX2luUG9zaXRpb24ueHkwMTsKfQoAAAAAAFIEAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmMyB2aW5DbGlwUGxhbmVfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gaGFsZjMgdmluSXNlY3RQbGFuZV9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIENpcmNsZUdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDQgY2lyY2xlRWRnZTsKCWNpcmNsZUVkZ2UgPSB2aW5DaXJjbGVFZGdlX1MwOwoJaGFsZjMgY2xpcFBsYW5lOwoJY2xpcFBsYW5lID0gdmluQ2xpcFBsYW5lX1MwOwoJaGFsZjMgaXNlY3RQbGFuZTsKCWlzZWN0UGxhbmUgPSB2aW5Jc2VjdFBsYW5lX1MwOwoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZpbkNvbG9yX1MwOwoJZmxvYXQgZCA9IGxlbmd0aChjaXJjbGVFZGdlLnh5KTsKCWhhbGYgZGlzdGFuY2VUb091dGVyRWRnZSA9IGhhbGYoY2lyY2xlRWRnZS56ICogKDEuMCAtIGQpKTsKCWhhbGYgZWRnZUFscGhhID0gc2F0dXJhdGUoZGlzdGFuY2VUb091dGVyRWRnZSk7CgloYWxmIGRpc3RhbmNlVG9Jbm5lckVkZ2UgPSBoYWxmKGNpcmNsZUVkZ2UueiAqIChkIC0gY2lyY2xlRWRnZS53KSk7CgloYWxmIGlubmVyQWxwaGEgPSBzYXR1cmF0ZShkaXN0YW5jZVRvSW5uZXJFZGdlKTsKCWVkZ2VBbHBoYSAqPSBpbm5lckFscGhhOwoJaGFsZiBjbGlwID0gaGFsZihzYXR1cmF0ZShjaXJjbGVFZGdlLnogKiBkb3QoY2lyY2xlRWRnZS54eSwgY2xpcFBsYW5lLnh5KSArIGNsaXBQbGFuZS56KSk7CgljbGlwICo9IGhhbGYoc2F0dXJhdGUoY2lyY2xlRWRnZS56ICogZG90KGNpcmNsZUVkZ2UueHksIGlzZWN0UGxhbmUueHkpICsgaXNlY3RQbGFuZS56KSk7CgllZGdlQWxwaGEgKj0gY2xpcDsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoZWRnZUFscGhhKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADAAAAGluQ2lyY2xlRWRnZQsAAABpbkNsaXBQbGFuZQAMAAAAaW5Jc2VjdFBsYW5lAAAAAA==","GYJAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAQAAAAAEQQGABZAA6IAAAAACAAAAAADGAAAAAAAEAAAAAIDEAAAAAAA":"DAAAAExTS1MwAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgcG9zaXRpb247CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmxvY2FsQ29vcmRfUzAgPSBsb2NhbENvb3JkOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgEAAACHAwAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHVpbm5lclJlY3RfUzE7CnVuaWZvcm0gaGFsZjIgdXJhZGl1c1BsdXNIYWxmX1MxOwpzYW1wbGVyRXh0ZXJuYWxPRVMgdVRleHR1cmVTYW1wbGVyXzBfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQyIHZsb2NhbENvb3JkX1MwOwpoYWxmNCBDaXJjdWxhclJSZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCWZsb2F0MiBkeHkwID0gdWlubmVyUmVjdF9TMS5MVCAtIHNrX0ZyYWdDb29yZC54eTsKCWZsb2F0MiBkeHkxID0gc2tfRnJhZ0Nvb3JkLnh5IC0gdWlubmVyUmVjdF9TMS5SQjsKCWZsb2F0MiBkeHkgPSBtYXgobWF4KGR4eTAsIGR4eTEpLCAwLjApOwoJaGFsZiBhbHBoYSA9IGhhbGYoc2F0dXJhdGUodXJhZGl1c1BsdXNIYWxmX1MxLnggLSBsZW5ndGgoZHh5KSkpOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwID0gaGFsZjQoMSk7CglmbG9hdDIgdGV4Q29vcmQ7Cgl0ZXhDb29yZCA9IHZsb2NhbENvb3JkX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSAoYmxlbmRfbW9kdWxhdGUoc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB0ZXhDb29yZCksIGhhbGY0KDEpKSk7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQ2lyY3VsYXJSUmVjdF9TMShvdXRwdXRDb3ZlcmFnZV9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACAAAAHBvc2l0aW9uCgAAAGxvY2FsQ29vcmQAAAAAAAA=","GZIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAJIBAGMVUOTUABAAAAQAAIAAAAAWFBIEMVUOTUAAAAAAQAAIAAAACIGAACAAAAACQIKACCAYAAEAAAAAAAAZQAAAAAABAAAAACAZAAAAAAA":"DAAAAExTS1PIAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfMl9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzEpICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAOgGAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKY29uc3QgaW50IGtNYXhMb29wTGltaXRfUzFfYzAgPSA4Owp1bmlmb3JtIGZsb2F0NCB1Y2xhbXBfUzFfYzBfYzBfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMDsKdW5pZm9ybSBoYWxmNCB1b2Zmc2V0c0FuZEtlcm5lbF9TMV9jMFsxNF07CnVuaWZvcm0gaGFsZjIgdWRpcl9TMV9jMDsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7Cm5vcGVyc3BlY3RpdmUgaW4gaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMF9jMF9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJZmxvYXQyIGluQ29vcmQgPSBfY29vcmRzOwoJZmxvYXQyIHN1YnNldENvb3JkOwoJc3Vic2V0Q29vcmQueCA9IGluQ29vcmQueDsKCXN1YnNldENvb3JkLnkgPSBpbkNvb3JkLnk7CglmbG9hdDIgY2xhbXBlZENvb3JkOwoJY2xhbXBlZENvb3JkLnggPSBjbGFtcChzdWJzZXRDb29yZC54LCB1Y2xhbXBfUzFfYzBfYzBfYzAueCwgdWNsYW1wX1MxX2MwX2MwX2MwLnopOwoJY2xhbXBlZENvb3JkLnkgPSBzdWJzZXRDb29yZC55OwoJaGFsZjQgdGV4dHVyZUNvbG9yID0gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MxLCBjbGFtcGVkQ29vcmQpOwoJcmV0dXJuIHRleHR1cmVDb2xvcjsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoaGFsZjQgX2lucHV0LCBmbG9hdDIgX2Nvb3JkcykgCnsKCXJldHVybiBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwX2MwKF9pbnB1dCwgZmxvYXQzeDIodW1hdHJpeF9TMV9jMF9jMCkgKiBfY29vcmRzLnh5MSk7Cn0KaGFsZjQgcnVudGltZV9zaGFkZXJfUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF8wX2luQ29sb3IgPSBfaW5wdXQ7CglmbG9hdDIgX3RtcF8xX2Nvb3JkcyA9IHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwoJaGFsZjQgc3VtID0gaGFsZjQoMC4wKTsKCWZvciAoaW50IGkgPSAwO2kgPCBrTWF4TG9vcExpbWl0X1MxX2MwOyArK2kpIAoJewoJCWhhbGY0IHMgPSB1b2Zmc2V0c0FuZEtlcm5lbF9TMV9jMFtpXTsKCQlzdW0gKz0gcy55ICogTWF0cml4RWZmZWN0X1MxX2MwX2MwKF90bXBfMF9pbkNvbG9yLCBfdG1wXzFfY29vcmRzICsgZmxvYXQyKHMueCAqIHVkaXJfUzFfYzApKTsKCQlzdW0gKz0gcy53ICogTWF0cml4RWZmZWN0X1MxX2MwX2MwKF90bXBfMF9pbkNvbG9yLCBfdG1wXzFfY29vcmRzICsgZmxvYXQyKHMueiAqIHVkaXJfUzFfYzApKTsKCX0KCXJldHVybiBoYWxmNChzdW0pOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gcnVudGltZV9zaGFkZXJfUzFfYzAoX2lucHV0KTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IE1hdHJpeEVmZmVjdF9TMShvdXRwdXRDb2xvcl9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0X1MxICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAIAAAAcG9zaXRpb24FAAAAY29sb3IAAAAKAAAAbG9jYWxDb29yZAAAAAAAAA==","GZIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAHIBIA5HZ2CAAAAAAAAAQCAAAAASAEEAQAAAAAUCCQAQQGAAAAEAAAAAAGMAAAAAAAIAAAAAQGIAAAAAAA":"DAAAAExTS1POAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzA7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfM19TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzFfYzApICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAAAAlgQAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQp1bmlmb3JtIGZsb2F0NCB1Y2xhbXBfUzFfYzBfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMDsKc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MxOwpub3BlcnNwZWN0aXZlIGluIGhhbGY0IHZjb2xvcl9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzNfUzA7CmhhbGY0IFRleHR1cmVFZmZlY3RfUzFfYzBfYzAoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGluQ29vcmQgPSB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKCWZsb2F0MiBzdWJzZXRDb29yZDsKCXN1YnNldENvb3JkLnggPSBpbkNvb3JkLng7CglzdWJzZXRDb29yZC55ID0gaW5Db29yZC55OwoJZmxvYXQyIGNsYW1wZWRDb29yZDsKCWNsYW1wZWRDb29yZC54ID0gc3Vic2V0Q29vcmQueDsKCWNsYW1wZWRDb29yZC55ID0gY2xhbXAoc3Vic2V0Q29vcmQueSwgdWNsYW1wX1MxX2MwX2MwLnksIHVjbGFtcF9TMV9jMF9jMC53KTsKCWhhbGY0IHRleHR1cmVDb2xvciA9IHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMSwgY2xhbXBlZENvb3JkKTsKCXJldHVybiB0ZXh0dXJlQ29sb3I7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwKF9pbnB1dCk7Cn0KaGFsZjQgRGlzYWJsZUNvdmVyYWdlQXNBbHBoYV9TMShoYWxmNCBfaW5wdXQpIAp7CglfaW5wdXQgPSBNYXRyaXhFZmZlY3RfUzFfYzAoX2lucHV0KTsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJcmV0dXJuIGhhbGY0KF9pbnB1dCk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBEaXNhYmxlQ292ZXJhZ2VBc0FscGhhX1MxKG91dHB1dENvbG9yX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRfUzEgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","GYJBYAQCAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAQAAAAAAQQGABZAA6IAAAAACAAAAAADGAAAAAAAEAAAAAIDEAAAAAAA":"DAAAAExTS1MwAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgcG9zaXRpb247CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmxvY2FsQ29vcmRfUzAgPSBsb2NhbENvb3JkOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgEAAADEBwAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQgdVNyY1RGX1MwWzddOwp1bmlmb3JtIGZsb2F0M3gzIHVDb2xvclhmb3JtX1MwOwp1bmlmb3JtIGZsb2F0IHVEc3RURl9TMFs3XTsKdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CnNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CmZsb2F0IHNyY190Zl9TMChmbG9hdCB4KSAKewoJZmxvYXQgRyA9IHVTcmNURl9TMFswXTsKCWZsb2F0IEEgPSB1U3JjVEZfUzBbMV07CglmbG9hdCBCID0gdVNyY1RGX1MwWzJdOwoJZmxvYXQgQyA9IHVTcmNURl9TMFszXTsKCWZsb2F0IEQgPSB1U3JjVEZfUzBbNF07CglmbG9hdCBFID0gdVNyY1RGX1MwWzVdOwoJZmxvYXQgRiA9IHVTcmNURl9TMFs2XTsKCWZsb2F0IHMgPSBzaWduKHgpOwoJeCA9IGFicyh4KTsKCXggPSAoeCA8IEQpID8gKEMgKiB4KSArIEYgOiBwb3coQSAqIHggKyBCLCBHKSArIEU7CglyZXR1cm4gcyAqIHg7Cn0KZmxvYXQgZHN0X3RmX1MwKGZsb2F0IHgpIAp7CglmbG9hdCBHID0gdURzdFRGX1MwWzBdOwoJZmxvYXQgQSA9IHVEc3RURl9TMFsxXTsKCWZsb2F0IEIgPSB1RHN0VEZfUzBbMl07CglmbG9hdCBDID0gdURzdFRGX1MwWzNdOwoJZmxvYXQgRCA9IHVEc3RURl9TMFs0XTsKCWZsb2F0IEUgPSB1RHN0VEZfUzBbNV07CglmbG9hdCBGID0gdURzdFRGX1MwWzZdOwoJZmxvYXQgcyA9IHNpZ24oeCk7Cgl4ID0gYWJzKHgpOwoJeCA9ICh4IDwgRCkgPyAoQyAqIHgpICsgRiA6IHBvdyhBICogeCArIEIsIEcpICsgRTsKCXJldHVybiBzICogeDsKfQpmbG9hdDQgZ2FtdXRfeGZvcm1fUzAoZmxvYXQ0IGNvbG9yKSAKewoJY29sb3IucmdiID0gKHVDb2xvclhmb3JtX1MwICogY29sb3IucmdiKTsKCXJldHVybiBjb2xvcjsKfQpoYWxmNCBjb2xvcl94Zm9ybV9TMChmbG9hdDQgY29sb3IpIAp7Cgljb2xvci5yID0gc3JjX3RmX1MwKGNvbG9yLnIpOwoJY29sb3IuZyA9IHNyY190Zl9TMChjb2xvci5nKTsKCWNvbG9yLmIgPSBzcmNfdGZfUzAoY29sb3IuYik7Cgljb2xvciA9IGdhbXV0X3hmb3JtX1MwKGNvbG9yKTsKCWNvbG9yLnIgPSBkc3RfdGZfUzAoY29sb3Iucik7Cgljb2xvci5nID0gZHN0X3RmX1MwKGNvbG9yLmcpOwoJY29sb3IuYiA9IGRzdF90Zl9TMChjb2xvci5iKTsKCXJldHVybiBoYWxmNChjb2xvcik7Cn0KaGFsZjQgQ2lyY3VsYXJSUmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglmbG9hdDIgZHh5MCA9IHVpbm5lclJlY3RfUzEuTFQgLSBza19GcmFnQ29vcmQueHk7CglmbG9hdDIgZHh5MSA9IHNrX0ZyYWdDb29yZC54eSAtIHVpbm5lclJlY3RfUzEuUkI7CglmbG9hdDIgZHh5ID0gbWF4KG1heChkeHkwLCBkeHkxKSwgMC4wKTsKCWhhbGYgYWxwaGEgPSBoYWxmKHNhdHVyYXRlKHVyYWRpdXNQbHVzSGFsZl9TMS54IC0gbGVuZ3RoKGR4eSkpKTsKCXJldHVybiBfaW5wdXQgKiBhbHBoYTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMCA9IGhhbGY0KDEpOwoJZmxvYXQyIHRleENvb3JkOwoJdGV4Q29vcmQgPSB2bG9jYWxDb29yZF9TMDsKCW91dHB1dENvbG9yX1MwID0gKGJsZW5kX21vZHVsYXRlKGNvbG9yX3hmb3JtX1MwKHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMCwgdGV4Q29vcmQpKSwgaGFsZjQoMSkpKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBDaXJjdWxhclJSZWN0X1MxKG91dHB1dENvdmVyYWdlX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoBAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgoAAABsb2NhbENvb3JkAAAAAAAA","DAQAAAAAAAAAAAAAAJQAAIGAAEACBYQCAGAEFAIBAAAAAABAAAAAAAAAAAACAA6QAAAABYCTIUIE4AIAAAYAAAAAQAAAAAGARL4FIEMEKMAAAAAMAAAAAAAAAAAAAMADAAAAAIAAAAAAAIIDAAAA":"DAAAAExTS1N4AgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0MiB1QXRsYXNTaXplSW52X1MwOwppbiBmbG9hdDIgaW5Qb3NpdGlvbjsKaW4gaGFsZjQgaW5Db2xvcjsKaW4gdXNob3J0MiBpblRleHR1cmVDb29yZHM7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQgdlRleEluZGV4X1MwOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgQml0bWFwVGV4dAoJaW50IHRleElkeCA9IDA7CglmbG9hdDIgdW5vcm1UZXhDb29yZHMgPSBmbG9hdDIoaW5UZXh0dXJlQ29vcmRzLngsIGluVGV4dHVyZUNvb3Jkcy55KTsKCXZUZXh0dXJlQ29vcmRzX1MwID0gdW5vcm1UZXhDb29yZHMgKiB1QXRsYXNTaXplSW52X1MwOwoJdlRleEluZGV4X1MwID0gZmxvYXQodGV4SWR4KTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzFfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247Cglza19Qb3NpdGlvbiA9IGluUG9zaXRpb24ueHkwMTsKfQoBAAAAnwUAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQpjb25zdCBpbnQga0ZpbGxCV19TMV9jMCA9IDA7CmNvbnN0IGludCBrSW52ZXJzZUZpbGxCV19TMV9jMCA9IDI7CmNvbnN0IGludCBrSW52ZXJzZUZpbGxBQV9TMV9jMCA9IDM7CnVuaWZvcm0gZmxvYXQ0IHVyZWN0VW5pZm9ybV9TMV9jMDsKc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdCB2VGV4SW5kZXhfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gaGFsZjQgdmluQ29sb3JfUzA7CmhhbGY0IFJlY3RfUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF8wX2luQ29sb3IgPSBfaW5wdXQ7CgloYWxmIGNvdmVyYWdlOwoJaWYgKGludCgxKSA9PSBrRmlsbEJXX1MxX2MwIHx8IGludCgxKSA9PSBrSW52ZXJzZUZpbGxCV19TMV9jMCkgCgl7CgkJY292ZXJhZ2UgPSBoYWxmKGFsbChncmVhdGVyVGhhbihmbG9hdDQoc2tfRnJhZ0Nvb3JkLnh5LCB1cmVjdFVuaWZvcm1fUzFfYzAuencpLCBmbG9hdDQodXJlY3RVbmlmb3JtX1MxX2MwLnh5LCBza19GcmFnQ29vcmQueHkpKSkpOwoJfQoJZWxzZSAKCXsKCQloYWxmNCBkaXN0czQgPSBzYXR1cmF0ZShoYWxmNCgxLjAsIDEuMCwgLTEuMCwgLTEuMCkgKiBoYWxmNChza19GcmFnQ29vcmQueHl4eSAtIHVyZWN0VW5pZm9ybV9TMV9jMCkpOwoJCWhhbGYyIGRpc3RzMiA9IChkaXN0czQueHkgKyBkaXN0czQuencpIC0gMS4wOwoJCWNvdmVyYWdlID0gZGlzdHMyLnggKiBkaXN0czIueTsKCX0KCWlmIChpbnQoMSkgPT0ga0ludmVyc2VGaWxsQldfUzFfYzAgfHwgaW50KDEpID09IGtJbnZlcnNlRmlsbEFBX1MxX2MwKSAKCXsKCQljb3ZlcmFnZSA9IDEuMCAtIGNvdmVyYWdlOwoJfQoJcmV0dXJuIGhhbGY0KGhhbGY0KGNvdmVyYWdlKSk7Cn0KaGFsZjQgQmxlbmRfUzEoaGFsZjQgX3NyYywgaGFsZjQgX2RzdCkgCnsKCXJldHVybiBibGVuZF9tb2R1bGF0ZShSZWN0X1MxX2MwKF9zcmMpLCBfc3JjKTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgQml0bWFwVGV4dAoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZpbkNvbG9yX1MwOwoJaGFsZjQgdGV4Q29sb3I7Cgl7CgkJdGV4Q29sb3IgPSBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzAsIHZUZXh0dXJlQ29vcmRzX1MwKS5ycnJyOwoJfQoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSB0ZXhDb2xvcjsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IEJsZW5kX1MxKG91dHB1dENvdmVyYWdlX1MwLCBoYWxmNCgxKSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACgAAAGluUG9zaXRpb24AAAcAAABpbkNvbG9yAA8AAABpblRleHR1cmVDb29yZHMAAAAAAA==","GZIACAAAABQAAGAAAQ4AAAAAGQQAARC4GAAAIOCAAD6P7777777777YDAAAAAAAAAAAHIBK2VD3EOCAAAAAABUXHIMAQAAAAWSQ4HO4SAAAAAMAAAAAAAAQAABANBBK3CICAAAEASHSVIGAAAAAAAAAAAEAABAAVAGSM7BYCAAAAA2CDQ53SKAIAABQAAAAAAACAAAEAUAF3OJAIAAAAAI6LVEYAAAAAAAAQAAAAFPJIMDXPJIBAAAGAAAAAAAAIAAAAAQIXNZERAAAAABDJMU3BAAAAAAAEAAAAAMQQAIAAAQGQQVNREBAAACAAAAAAQAKRC5HBSYCACAAAAAAAAAEAIRDJMU3BAAAAAAACAAAAAVTIMQ4RKBQAAAAAAAAAACAAIAIAAIAAAAC2BCEAQAAAAAAAAAAAMADAAAAAUAAAAAAAIIDA":"DAAAAExTS1NNAgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzBfYzBfYzE7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQgY292ZXJhZ2U7CmluIGhhbGY0IGNvbG9yOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdCB2Y292ZXJhZ2VfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfN19TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDIgcG9zaXRpb24gPSBwb3NpdGlvbi54eTsKCXZjb2xvcl9TMCA9IGNvbG9yOwoJdmNvdmVyYWdlX1MwID0gY292ZXJhZ2U7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzdfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxX2MwX2MwX2MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAEAAADKCgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gaGFsZjQgdXN0YXJ0X1MxX2MwX2MwX2MwX2MwOwp1bmlmb3JtIGhhbGY0IHVlbmRfUzFfYzBfYzBfYzBfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMF9jMTsKdW5pZm9ybSBoYWxmNCB1bGVmdEJvcmRlckNvbG9yX1MxX2MwX2MwOwp1bmlmb3JtIGhhbGY0IHVyaWdodEJvcmRlckNvbG9yX1MxX2MwX2MwOwp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzE7CnVuaWZvcm0gaGFsZiB1cmFuZ2VfUzE7CnNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMTsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQgdmNvdmVyYWdlX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfN19TMDsKaGFsZjQgU2luZ2xlSW50ZXJ2YWxDb2xvcml6ZXJfUzFfYzBfYzBfYzBfYzAoaGFsZjQgX2lucHV0LCBmbG9hdDIgX2Nvb3JkcykgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJZmxvYXQyIF90bXBfMV9jb29yZHMgPSBfY29vcmRzOwoJcmV0dXJuIGhhbGY0KG1peCh1c3RhcnRfUzFfYzBfYzBfYzBfYzAsIHVlbmRfUzFfYzBfYzBfYzBfYzAsIGhhbGYoX3RtcF8xX2Nvb3Jkcy54KSkpOwp9CmhhbGY0IGNvbG9yX3hmb3JtX1MxX2MwX2MwX2MwKGZsb2F0NCBjb2xvcikgCnsKCWNvbG9yLnJnYiAqPSBjb2xvci5hOwoJcmV0dXJuIGhhbGY0KGNvbG9yKTsKfQpoYWxmNCBDb2xvclNwYWNlWGZvcm1fUzFfYzBfYzBfYzAoaGFsZjQgX2lucHV0LCBmbG9hdDIgX2Nvb3JkcykgCnsKCXJldHVybiBjb2xvcl94Zm9ybV9TMV9jMF9jMF9jMChTaW5nbGVJbnRlcnZhbENvbG9yaXplcl9TMV9jMF9jMF9jMF9jMChfaW5wdXQsIF9jb29yZHMpKTsKfQpoYWxmNCBMaW5lYXJMYXlvdXRfUzFfYzBfYzBfYzFfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF8yX2luQ29sb3IgPSBfaW5wdXQ7CglmbG9hdDIgX3RtcF8zX2Nvb3JkcyA9IHZUcmFuc2Zvcm1lZENvb3Jkc183X1MwOwoJcmV0dXJuIGhhbGY0KGhhbGY0KGhhbGYoX3RtcF8zX2Nvb3Jkcy54KSArIDFlLTA1LCAxLjAsIDAuMCwgMC4wKSk7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxX2MwX2MwX2MxKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBMaW5lYXJMYXlvdXRfUzFfYzBfYzBfYzFfYzAoX2lucHV0KTsKfQpoYWxmNCBDbGFtcGVkR3JhZGllbnRfUzFfYzBfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF80X2luQ29sb3IgPSBfaW5wdXQ7CgloYWxmNCB0ID0gTWF0cml4RWZmZWN0X1MxX2MwX2MwX2MxKF90bXBfNF9pbkNvbG9yKTsKCWhhbGY0IG91dENvbG9yOwoJaWYgKCFib29sKGludCgxKSkgJiYgdC55IDwgMC4wKSAKCXsKCQlvdXRDb2xvciA9IGhhbGY0KDAuMCk7Cgl9CgllbHNlIGlmICh0LnggPCAwLjApIAoJewoJCW91dENvbG9yID0gdWxlZnRCb3JkZXJDb2xvcl9TMV9jMF9jMDsKCX0KCWVsc2UgaWYgKHQueCA+IDEuMCkgCgl7CgkJb3V0Q29sb3IgPSB1cmlnaHRCb3JkZXJDb2xvcl9TMV9jMF9jMDsKCX0KCWVsc2UgCgl7CgkJb3V0Q29sb3IgPSBDb2xvclNwYWNlWGZvcm1fUzFfYzBfYzBfYzAoX3RtcF80X2luQ29sb3IsIGZsb2F0MihoYWxmMih0LngsIDAuMCkpKTsKCX0KCXJldHVybiBoYWxmNChvdXRDb2xvcik7Cn0KaGFsZjQgRGlzYWJsZUNvdmVyYWdlQXNBbHBoYV9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CglfaW5wdXQgPSBDbGFtcGVkR3JhZGllbnRfUzFfYzBfYzAoX2lucHV0KTsKCWhhbGY0IF90bXBfNV9pbkNvbG9yID0gX2lucHV0OwoJcmV0dXJuIGhhbGY0KF9pbnB1dCk7Cn0KaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMV9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJcmV0dXJuIHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMSwgX2Nvb3JkcykuMDAwcjsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzFfYzEoaGFsZjQgX2lucHV0LCBmbG9hdDIgX2Nvb3JkcykgCnsKCXJldHVybiBUZXh0dXJlRWZmZWN0X1MxX2MxX2MwKF9pbnB1dCwgZmxvYXQzeDIodW1hdHJpeF9TMV9jMSkgKiBfY29vcmRzLnh5MSk7Cn0KaGFsZjQgRGl0aGVyX1MxKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfNl9pbkNvbG9yID0gX2lucHV0OwoJaGFsZjQgY29sb3IgPSBEaXNhYmxlQ292ZXJhZ2VBc0FscGhhX1MxX2MwKF90bXBfNl9pbkNvbG9yKTsKCWhhbGYgdmFsdWUgPSBNYXRyaXhFZmZlY3RfUzFfYzEoX3RtcF82X2luQ29sb3IsIHNrX0ZyYWdDb29yZC54eSkudyAtIDAuNTsKCXJldHVybiBoYWxmNChoYWxmNChjbGFtcChjb2xvci54eXogKyB2YWx1ZSAqIHVyYW5nZV9TMSwgMC4wLCBjb2xvci53KSwgY29sb3IudykpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7CglmbG9hdCBjb3ZlcmFnZSA9IHZjb3ZlcmFnZV9TMDsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoY292ZXJhZ2UpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gRGl0aGVyX1MxKG91dHB1dENvbG9yX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSAoaGFsZjQoMS4wKSAtIG91dHB1dF9TMSkgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAHBvc2l0aW9uCAAAAGNvdmVyYWdlBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","GYJBYAQCAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAQAAAAAAQQGAAYAGAAAAAQAAAAAAAQQGAAA":"DAAAAExTS1MwAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgcG9zaXRpb247CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmxvY2FsQ29vcmRfUzAgPSBsb2NhbENvb3JkOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAAA1BgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQgdVNyY1RGX1MwWzddOwp1bmlmb3JtIGZsb2F0M3gzIHVDb2xvclhmb3JtX1MwOwp1bmlmb3JtIGZsb2F0IHVEc3RURl9TMFs3XTsKc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2bG9jYWxDb29yZF9TMDsKZmxvYXQgc3JjX3RmX1MwKGZsb2F0IHgpIAp7CglmbG9hdCBHID0gdVNyY1RGX1MwWzBdOwoJZmxvYXQgQSA9IHVTcmNURl9TMFsxXTsKCWZsb2F0IEIgPSB1U3JjVEZfUzBbMl07CglmbG9hdCBDID0gdVNyY1RGX1MwWzNdOwoJZmxvYXQgRCA9IHVTcmNURl9TMFs0XTsKCWZsb2F0IEUgPSB1U3JjVEZfUzBbNV07CglmbG9hdCBGID0gdVNyY1RGX1MwWzZdOwoJZmxvYXQgcyA9IHNpZ24oeCk7Cgl4ID0gYWJzKHgpOwoJeCA9ICh4IDwgRCkgPyAoQyAqIHgpICsgRiA6IHBvdyhBICogeCArIEIsIEcpICsgRTsKCXJldHVybiBzICogeDsKfQpmbG9hdCBkc3RfdGZfUzAoZmxvYXQgeCkgCnsKCWZsb2F0IEcgPSB1RHN0VEZfUzBbMF07CglmbG9hdCBBID0gdURzdFRGX1MwWzFdOwoJZmxvYXQgQiA9IHVEc3RURl9TMFsyXTsKCWZsb2F0IEMgPSB1RHN0VEZfUzBbM107CglmbG9hdCBEID0gdURzdFRGX1MwWzRdOwoJZmxvYXQgRSA9IHVEc3RURl9TMFs1XTsKCWZsb2F0IEYgPSB1RHN0VEZfUzBbNl07CglmbG9hdCBzID0gc2lnbih4KTsKCXggPSBhYnMoeCk7Cgl4ID0gKHggPCBEKSA/IChDICogeCkgKyBGIDogcG93KEEgKiB4ICsgQiwgRykgKyBFOwoJcmV0dXJuIHMgKiB4Owp9CmZsb2F0NCBnYW11dF94Zm9ybV9TMChmbG9hdDQgY29sb3IpIAp7Cgljb2xvci5yZ2IgPSAodUNvbG9yWGZvcm1fUzAgKiBjb2xvci5yZ2IpOwoJcmV0dXJuIGNvbG9yOwp9CmhhbGY0IGNvbG9yX3hmb3JtX1MwKGZsb2F0NCBjb2xvcikgCnsKCWNvbG9yLnIgPSBzcmNfdGZfUzAoY29sb3Iucik7Cgljb2xvci5nID0gc3JjX3RmX1MwKGNvbG9yLmcpOwoJY29sb3IuYiA9IHNyY190Zl9TMChjb2xvci5iKTsKCWNvbG9yID0gZ2FtdXRfeGZvcm1fUzAoY29sb3IpOwoJY29sb3IuciA9IGRzdF90Zl9TMChjb2xvci5yKTsKCWNvbG9yLmcgPSBkc3RfdGZfUzAoY29sb3IuZyk7Cgljb2xvci5iID0gZHN0X3RmX1MwKGNvbG9yLmIpOwoJcmV0dXJuIGhhbGY0KGNvbG9yKTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMCA9IGhhbGY0KDEpOwoJZmxvYXQyIHRleENvb3JkOwoJdGV4Q29vcmQgPSB2bG9jYWxDb29yZF9TMDsKCW91dHB1dENvbG9yX1MwID0gKGJsZW5kX21vZHVsYXRlKGNvbG9yX3hmb3JtX1MwKHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMCwgdGV4Q29vcmQpKSwgaGFsZjQoMSkpKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgoAAABsb2NhbENvb3JkAAAAAAAA","DASAAAAAAAAAAAEAAFQAAIGAAEAOB77776PUEAIBAAAAAABAAAAAAABAMQAAAMYAAAAAAAQAAAABAMQAAAAA":"DAAAAExTS1MpAgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0MiB1QXRsYXNTaXplSW52X1MwOwppbiBmbG9hdDIgaW5Qb3NpdGlvbjsKaW4gdXNob3J0MiBpblRleHR1cmVDb29yZHM7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQgdlRleEluZGV4X1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBCaXRtYXBUZXh0CglpbnQgdGV4SWR4ID0gMDsKCWZsb2F0MiB1bm9ybVRleENvb3JkcyA9IGZsb2F0MihpblRleHR1cmVDb29yZHMueCwgaW5UZXh0dXJlQ29vcmRzLnkpOwoJdlRleHR1cmVDb29yZHNfUzAgPSB1bm9ybVRleENvb3JkcyAqIHVBdGxhc1NpemVJbnZfUzA7Cgl2VGV4SW5kZXhfUzAgPSBmbG9hdCh0ZXhJZHgpOwoJZmxvYXQyIF90bXBfMV9pblBvc2l0aW9uID0gaW5Qb3NpdGlvbjsKCXNrX1Bvc2l0aW9uID0gaW5Qb3NpdGlvbi54eTAxOwp9CgAAAAAAAAAsAgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gaGFsZjQgdUNvbG9yX1MwOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQyIHZUZXh0dXJlQ29vcmRzX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0IHZUZXhJbmRleF9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIEJpdG1hcFRleHQKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB1Q29sb3JfUzA7CgloYWxmNCB0ZXhDb2xvcjsKCXsKCQl0ZXhDb2xvciA9IHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMCwgdlRleHR1cmVDb29yZHNfUzApOwoJfQoJb3V0cHV0Q29sb3JfUzAgPSBvdXRwdXRDb2xvcl9TMCAqIHRleENvbG9yOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACgAAAGluUG9zaXRpb24AAA8AAABpblRleHR1cmVDb29yZHMAAAAAAA==","G2JQAAAAABEAADAAAIOAAAAADIIAB7X7777QGHAYAD7P7777A4QCQAAAAAAAAAQAAAAAAQQGAAYAGAAAAAQAAAAAAAQQGAAA":"DAAAAExTS1P8AQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgcG9zaXRpb247CmluIGZsb2F0IGNvdmVyYWdlOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKaW4gZmxvYXQ0IHRleFN1YnNldDsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQyIHZsb2NhbENvb3JkX1MwOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDQgdnRleFN1YnNldF9TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQgdmNvdmVyYWdlX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWZsb2F0MiBwb3NpdGlvbiA9IHBvc2l0aW9uLnh5OwoJdmxvY2FsQ29vcmRfUzAgPSBsb2NhbENvb3JkOwoJdnRleFN1YnNldF9TMCA9IHRleFN1YnNldDsKCXZjb3ZlcmFnZV9TMCA9IGNvdmVyYWdlOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAAC4AgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQ0IHZ0ZXhTdWJzZXRfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQgdmNvdmVyYWdlX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMCA9IGhhbGY0KDEpOwoJZmxvYXQyIHRleENvb3JkOwoJdGV4Q29vcmQgPSB2bG9jYWxDb29yZF9TMDsKCWZsb2F0NCBzdWJzZXQ7CglzdWJzZXQgPSB2dGV4U3Vic2V0X1MwOwoJdGV4Q29vcmQgPSBjbGFtcCh0ZXhDb29yZCwgc3Vic2V0LkxULCBzdWJzZXQuUkIpOwoJb3V0cHV0Q29sb3JfUzAgPSAoYmxlbmRfbW9kdWxhdGUoc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB0ZXhDb29yZCksIGhhbGY0KDEpKSk7CglmbG9hdCBjb3ZlcmFnZSA9IHZjb3ZlcmFnZV9TMDsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoY292ZXJhZ2UpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAAcG9zaXRpb24IAAAAY292ZXJhZ2UKAAAAbG9jYWxDb29yZAAACQAAAHRleFN1YnNldAAAAAAAAAA=","B2AAQAAABQAAIAABBYAAB7777777777774ABICAAAAAAAAAAAAAABGABAAAAAEAAAAAIBEABAAAAA":"DAAAAExTS1NZAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgaW5Qb3NpdGlvbjsKaW4gaGFsZiBpbkNvdmVyYWdlOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmIHZpbkNvdmVyYWdlX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBEZWZhdWx0R2VvbWV0cnlQcm9jZXNzb3IKCWZsb2F0MiBfdG1wXzFfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247Cgl2aW5Db3ZlcmFnZV9TMCA9IGluQ292ZXJhZ2U7Cglza19Qb3NpdGlvbiA9IF90bXBfMV9pblBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAAAJgBAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKdW5pZm9ybSBoYWxmNCB1Q29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gaGFsZiB2aW5Db3ZlcmFnZV9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIERlZmF1bHRHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHVDb2xvcl9TMDsKCWhhbGYgYWxwaGEgPSAxLjA7CglhbHBoYSA9IHZpbkNvdmVyYWdlX1MwOwoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChhbHBoYSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAoAAABpblBvc2l0aW9uAAAKAAAAaW5Db3ZlcmFnZQAAAAAAAA==","GYJAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAQAAAAAAQQGAAZAADIAAAAAJKLCRQQAAAAAAMAAAAACAAAAAIAAAAALAIQEVFRIYIAAAAAAGAAAAABAAAAAAAAAAAAAGABQAAAAEAAAAAAAEEBQA":"DAAAAExTS1MwAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgcG9zaXRpb247CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmxvY2FsQ29vcmRfUzAgPSBsb2NhbENvb3JkOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgEAAACEBgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCmNvbnN0IGludCBrRmlsbEJXX1MxX2MwID0gMDsKY29uc3QgaW50IGtGaWxsQUFfUzFfYzAgPSAxOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQldfUzFfYzAgPSAyOwp1bmlmb3JtIGZsb2F0NCB1ZWxsaXBzZV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdXNjYWxlX1MxX2MwOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQyIHZsb2NhbENvb3JkX1MwOwpoYWxmNCBFbGxpcHNlX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJZmxvYXQyIGQgPSBza19GcmFnQ29vcmQueHkgLSB1ZWxsaXBzZV9TMV9jMC54eTsKCWlmIChib29sKGludCgwKSkpIAoJewoJCWQgKj0gdXNjYWxlX1MxX2MwLnk7Cgl9CglmbG9hdDIgWiA9IGQgKiB1ZWxsaXBzZV9TMV9jMC56dzsKCWZsb2F0IGltcGxpY2l0ID0gZG90KFosIGQpIC0gMS4wOwoJZmxvYXQgZ3JhZF9kb3QgPSA0LjAgKiBkb3QoWiwgWik7CglpZiAoYm9vbChpbnQoMCkpKSAKCXsKCQlncmFkX2RvdCA9IG1heChncmFkX2RvdCwgNi4xMDM2ZS0wNSk7Cgl9CgllbHNlIAoJewoJCWdyYWRfZG90ID0gbWF4KGdyYWRfZG90LCAxLjE3NTVlLTM4KTsKCX0KCWZsb2F0IGFwcHJveF9kaXN0ID0gaW1wbGljaXQgKiBpbnZlcnNlc3FydChncmFkX2RvdCk7CglpZiAoYm9vbChpbnQoMCkpKSAKCXsKCQlhcHByb3hfZGlzdCAqPSB1c2NhbGVfUzFfYzAueDsKCX0KCWhhbGYgYWxwaGE7CglpZiAoaW50KDEpID09IGtGaWxsQldfUzFfYzApIAoJewoJCWFscGhhID0gaGFsZihhcHByb3hfZGlzdCA+IDAuMCA/IDAuMCA6IDEuMCk7Cgl9CgllbHNlIGlmIChpbnQoMSkgPT0ga0ZpbGxBQV9TMV9jMCkgCgl7CgkJYWxwaGEgPSBzYXR1cmF0ZSgwLjUgLSBoYWxmKGFwcHJveF9kaXN0KSk7Cgl9CgllbHNlIGlmIChpbnQoMSkgPT0ga0ludmVyc2VGaWxsQldfUzFfYzApIAoJewoJCWFscGhhID0gaGFsZihhcHByb3hfZGlzdCA+IDAuMCk7Cgl9CgllbHNlIAoJewoJCWFscGhhID0gc2F0dXJhdGUoMC41ICsgaGFsZihhcHByb3hfZGlzdCkpOwoJfQoJcmV0dXJuIGhhbGY0KGhhbGY0KGFscGhhKSk7Cn0KaGFsZjQgQmxlbmRfUzEoaGFsZjQgX3NyYywgaGFsZjQgX2RzdCkgCnsKCXJldHVybiBibGVuZF9tb2R1bGF0ZShFbGxpcHNlX1MxX2MwKF9zcmMpLCBfc3JjKTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMCA9IGhhbGY0KDEpOwoJZmxvYXQyIHRleENvb3JkOwoJdGV4Q29vcmQgPSB2bG9jYWxDb29yZF9TMDsKCW91dHB1dENvbG9yX1MwID0gKGJsZW5kX21vZHVsYXRlKHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMCwgdGV4Q29vcmQpLCBoYWxmNCgxKSkpOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IEJsZW5kX1MxKG91dHB1dENvdmVyYWdlX1MwLCBoYWxmNCgxKSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAIAAAAcG9zaXRpb24KAAAAbG9jYWxDb29yZAAAAAAAAA==","GZIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAJIBBKQPNFTIACAAADQOAIAAAAAWFBZKQHMFVIAAAAADQOAIAAAACI6DQCAAAAACQIKACCAYAA4DQAAAAAAZQAAAAAABAAAAACAZAAAAAAA":"DAAAAExTS1PIAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfMl9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzEpICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAAkJAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKY29uc3QgaW50IGtNYXhMb29wTGltaXRfUzFfYzAgPSAzOwp1bmlmb3JtIGhhbGY0IHVib3JkZXJfUzFfYzBfYzBfYzA7CnVuaWZvcm0gZmxvYXQ0IHVzdWJzZXRfUzFfYzBfYzBfYzA7CnVuaWZvcm0gZmxvYXQyIHVpZGltc19TMV9jMF9jMF9jMDsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxX2MwX2MwOwp1bmlmb3JtIGhhbGY0IHVrZXJuZWxfUzFfYzBbN107CnVuaWZvcm0gaGFsZjQgdW9mZnNldHNfUzFfYzBbMTRdOwp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CnNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMTsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwpoYWxmNCBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwX2MwKGhhbGY0IF9pbnB1dCwgZmxvYXQyIF9jb29yZHMpIAp7CglmbG9hdDIgaW5Db29yZCA9IF9jb29yZHM7CglmbG9hdDIgc3Vic2V0Q29vcmQ7CglzdWJzZXRDb29yZC54ID0gaW5Db29yZC54OwoJc3Vic2V0Q29vcmQueSA9IGluQ29vcmQueTsKCWZsb2F0MiBjbGFtcGVkQ29vcmQ7CgljbGFtcGVkQ29vcmQgPSBzdWJzZXRDb29yZDsKCWhhbGY0IHRleHR1cmVDb2xvciA9IHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMSwgKGNsYW1wZWRDb29yZCkgKiB1aWRpbXNfUzFfYzBfYzBfYzApOwoJZmxvYXQgc25hcHBlZFggPSBmbG9vcihpbkNvb3JkLnggKyAwLjAwMSkgKyAwLjU7CglpZiAoc25hcHBlZFggPCB1c3Vic2V0X1MxX2MwX2MwX2MwLnggfHwgc25hcHBlZFggPiB1c3Vic2V0X1MxX2MwX2MwX2MwLnopIAoJewoJCXRleHR1cmVDb2xvciA9IHVib3JkZXJfUzFfYzBfYzBfYzA7Cgl9CglmbG9hdCBzbmFwcGVkWSA9IGZsb29yKGluQ29vcmQueSArIDAuMDAxKSArIDAuNTsKCWlmIChzbmFwcGVkWSA8IHVzdWJzZXRfUzFfYzBfYzBfYzAueSB8fCBzbmFwcGVkWSA+IHVzdWJzZXRfUzFfYzBfYzBfYzAudykgCgl7CgkJdGV4dHVyZUNvbG9yID0gdWJvcmRlcl9TMV9jMF9jMF9jMDsKCX0KCXJldHVybiB0ZXh0dXJlQ29sb3I7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxX2MwX2MwKGhhbGY0IF9pbnB1dCwgZmxvYXQyIF9jb29yZHMpIAp7CglyZXR1cm4gVGV4dHVyZUVmZmVjdF9TMV9jMF9jMF9jMChfaW5wdXQsIGZsb2F0M3gyKHVtYXRyaXhfUzFfYzBfYzApICogX2Nvb3Jkcy54eTEpOwp9CmhhbGY0IHJ1bnRpbWVfc2hhZGVyX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJZmxvYXQyIF90bXBfMV9jb29yZHMgPSB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKCWhhbGY0IHN1bSA9IGhhbGY0KDAuMCk7Cglmb3IgKGludCBpID0gMDtpIDwga01heExvb3BMaW1pdF9TMV9jMDsgKytpKSAKCXsKCQloYWxmNCBrID0gdWtlcm5lbF9TMV9jMFtpXTsKCQloYWxmNCBvID0gdW9mZnNldHNfUzFfYzBbMiAqIGldOwoJCXN1bSArPSBrLnggKiBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoX3RtcF8wX2luQ29sb3IsIF90bXBfMV9jb29yZHMgKyBmbG9hdDIoby54eSkpOwoJCXN1bSArPSBrLnkgKiBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoX3RtcF8wX2luQ29sb3IsIF90bXBfMV9jb29yZHMgKyBmbG9hdDIoby56dykpOwoJCW8gPSB1b2Zmc2V0c19TMV9jMFsyICogaSArIDFdOwoJCXN1bSArPSBrLnogKiBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoX3RtcF8wX2luQ29sb3IsIF90bXBfMV9jb29yZHMgKyBmbG9hdDIoby54eSkpOwoJCXN1bSArPSBrLncgKiBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoX3RtcF8wX2luQ29sb3IsIF90bXBfMV9jb29yZHMgKyBmbG9hdDIoby56dykpOwoJfQoJcmV0dXJuIGhhbGY0KHN1bSk7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBydW50aW1lX3NoYWRlcl9TMV9jMChfaW5wdXQpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gTWF0cml4RWZmZWN0X1MxKG91dHB1dENvbG9yX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRfUzEgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAgAAABwb3NpdGlvbgUAAABjb2xvcgAAAAoAAABsb2NhbENvb3JkAAAAAAAA","GZIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAHIBIA5HZ2CAAAAAAAEAACAAAAASBEAAQAAAAAUCCQAQQGAABAAAAAAAAGMAAAAAAAIAAAAAQGIAAAAAAA":"DAAAAExTS1POAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzA7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfM19TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzFfYzApICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAAAAlgQAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQp1bmlmb3JtIGZsb2F0NCB1Y2xhbXBfUzFfYzBfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMDsKc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MxOwpub3BlcnNwZWN0aXZlIGluIGhhbGY0IHZjb2xvcl9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzNfUzA7CmhhbGY0IFRleHR1cmVFZmZlY3RfUzFfYzBfYzAoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGluQ29vcmQgPSB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKCWZsb2F0MiBzdWJzZXRDb29yZDsKCXN1YnNldENvb3JkLnggPSBpbkNvb3JkLng7CglzdWJzZXRDb29yZC55ID0gaW5Db29yZC55OwoJZmxvYXQyIGNsYW1wZWRDb29yZDsKCWNsYW1wZWRDb29yZC54ID0gY2xhbXAoc3Vic2V0Q29vcmQueCwgdWNsYW1wX1MxX2MwX2MwLngsIHVjbGFtcF9TMV9jMF9jMC56KTsKCWNsYW1wZWRDb29yZC55ID0gc3Vic2V0Q29vcmQueTsKCWhhbGY0IHRleHR1cmVDb2xvciA9IHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMSwgY2xhbXBlZENvb3JkKTsKCXJldHVybiB0ZXh0dXJlQ29sb3I7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwKF9pbnB1dCk7Cn0KaGFsZjQgRGlzYWJsZUNvdmVyYWdlQXNBbHBoYV9TMShoYWxmNCBfaW5wdXQpIAp7CglfaW5wdXQgPSBNYXRyaXhFZmZlY3RfUzFfYzAoX2lucHV0KTsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJcmV0dXJuIGhhbGY0KF9pbnB1dCk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBEaXNhYmxlQ292ZXJhZ2VBc0FscGhhX1MxKG91dHB1dENvbG9yX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRfUzEgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","GZIACAAAABQAAGAAAQ4AAAAAGQQAARC4GAAAIOCAAD6P7777777777YDAAAAAAAAAAAJQBBYGQ467YIAAAAAAQAAAAAMACTRNBZN5QYBAAAAAAAAAAAIAALIAAAAB4FJEIEKOAAAAAMAAAAAUAAQAADAWB7EXCYCAAAGAAAAAAAACAAAQAK7DKJCBCTQAAAADAAAAAAAAAAAAYCADIAAAAAG5O33IKAAAAAAMAAAAAIAAAAAABMJDQP2FUWQUAAAQAAQAAAAAAAAAADGAAAAAAAEAAAAAIDEAAAAAAA":"DAAAAExTS1M7AgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQgY292ZXJhZ2U7CmluIGhhbGY0IGNvbG9yOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdCB2Y292ZXJhZ2VfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDIgcG9zaXRpb24gPSBwb3NpdGlvbi54eTsKCXZjb2xvcl9TMCA9IGNvbG9yOwoJdmNvdmVyYWdlX1MwID0gY292ZXJhZ2U7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgABAAAAxiIAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQpmbG9hdDQgZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzA7CmZsb2F0NCBmcmFnQ29sb3JfUzFfYzA7CmZsb2F0IHVfYWxwaGFfUzFfYzA7CmZsb2F0IHVfc3BhcmtsZV9hbHBoYV9TMV9jMDsKZmxvYXQgdV9ibHVyX1MxX2MwOwpmbG9hdCB1X3JhZGl1c19zY2FsZV9TMV9jMDsKY29uc3QgaW50IGtGaWxsQldfUzJfYzAgPSAwOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQldfUzJfYzAgPSAyOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQUFfUzJfYzAgPSAzOwpjb25zdCBpbnQga0ZpbGxBQV9TMl9jMV9jMCA9IDE7CmNvbnN0IGludCBrSW52ZXJzZUZpbGxCV19TMl9jMV9jMCA9IDI7CmNvbnN0IGludCBrSW52ZXJzZUZpbGxBQV9TMl9jMV9jMCA9IDM7CnVuaWZvcm0gZmxvYXQ0IHVfY29sb3JfUzFfYzA7CnVuaWZvcm0gZmxvYXQ0IHVfY29tcG9zaXRlXzFfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2VudGVyX1MxX2MwOwp1bmlmb3JtIGZsb2F0IHVfbWF4X3JhZGl1c19TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yZXNvbHV0aW9uX3NjYWxlX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X25vaXNlX3NjYWxlX1MxX2MwOwp1bmlmb3JtIGZsb2F0IHVfbm9pc2VfcGhhc2VfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2lyY2xlMV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jaXJjbGUyX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NpcmNsZTNfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcm90YXRpb24xX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3JvdGF0aW9uMl9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yb3RhdGlvbjNfUzFfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKdW5pZm9ybSBmbG9hdDQgdXJlY3RVbmlmb3JtX1MyX2MwOwp1bmlmb3JtIGZsb2F0NCB1Y2lyY2xlX1MyX2MxX2MwOwpub3BlcnNwZWN0aXZlIGluIGhhbGY0IHZjb2xvcl9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdCB2Y292ZXJhZ2VfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwpmbG9hdDIgRkxUX2ZsdXR0ZXJfbG9jYWxfRmx1dHRlckZyYWdDb29yZF9TMV9jMCgpOwpmbG9hdDJ4MiBGTFRfZmx1dHRlcl9sb2NhbF9yb3RhdGUyZF9TMV9jMChmbG9hdDIgcmFkKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgYmx1cik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKGZsb2F0MiByZXNvbHV0aW9uLCBpbm91dCBmbG9hdDIgcCwgZmxvYXQyIHh5LCBmbG9hdDIgcm90YXRpb24sIGZsb2F0IGNlbGxfZGlhbWV0ZXIpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90dXJidWxlbmNlX1MxX2MwKGZsb2F0MiB1dik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfcmluZ19TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCB0aGlja25lc3MsIGZsb2F0IGJsdXIpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90cmlhbmdsZV9ub2lzZV9TMV9jMChpbm91dCBmbG9hdDIgbik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChmbG9hdCB2LCBmbG9hdCBsLCBmbG9hdCBoKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc3BhcmtsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0IHQpOwp2b2lkIEZMVF9tYWluX1MxX2MwKCk7CmZsb2F0MiBGTFRfZmx1dHRlcl9sb2NhbF9GbHV0dGVyRnJhZ0Nvb3JkX1MxX2MwKCkgCnsKCXJldHVybiBmbHV0dGVyX0ZyYWdDb29yZF9TMV9jMC54eTsKfQpmbG9hdDJ4MiBGTFRfZmx1dHRlcl9sb2NhbF9yb3RhdGUyZF9TMV9jMChmbG9hdDIgcmFkKSAKewoJcmV0dXJuIGZsb2F0MngyKHJhZC54LCAtcmFkLnksIHJhZC55LCByYWQueCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgYmx1cikgCnsKCWZsb2F0IGJsdXJfaGFsZiA9IGJsdXIgKiAwLjU7CglmbG9hdCBkID0gZGlzdGFuY2UodXYsIHh5KTsKCXJldHVybiAxLjAgLSBzbW9vdGhzdGVwKDEuMCAtIGJsdXJfaGFsZiwgMS4wICsgYmx1cl9oYWxmLCBkIC8gcmFkaXVzKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChmbG9hdDIgcmVzb2x1dGlvbiwgaW5vdXQgZmxvYXQyIHAsIGZsb2F0MiB4eSwgZmxvYXQyIHJvdGF0aW9uLCBmbG9hdCBjZWxsX2RpYW1ldGVyKSAKewoJZmxvYXQyIHBhcmFtID0gcm90YXRpb247CglwID0gRkxUX2ZsdXR0ZXJfbG9jYWxfcm90YXRlMmRfUzFfYzAocGFyYW0pICogKHh5IC0gcCkgKyB4eTsKCXAgPSBtb2QocCwgZmxvYXQyKGNlbGxfZGlhbWV0ZXIpKSAvIHJlc29sdXRpb247CglmbG9hdCBjZWxsX3V2ID0gKGNlbGxfZGlhbWV0ZXIgLyByZXNvbHV0aW9uLnkpICogMC41OwoJZmxvYXQgciA9IDAuNjUgKiBjZWxsX3V2OwoJZmxvYXQyIHBhcmFtXzEgPSBwOwoJZmxvYXQyIHBhcmFtXzIgPSBmbG9hdDIoY2VsbF91dik7CglmbG9hdCBwYXJhbV8zID0gcjsKCWZsb2F0IHBhcmFtXzQgPSByICogNTAuMDsKCXJldHVybiBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zLCBwYXJhbV80KTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90dXJidWxlbmNlX1MxX2MwKGZsb2F0MiB1dikgCnsKCWZsb2F0MiB1dl9zY2FsZSA9IHV2ICogZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW0gPSBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbV8xID0gdXZfc2NhbGU7CglmbG9hdDIgcGFyYW1fMiA9IHVfY2lyY2xlMV9TMV9jMDsKCWZsb2F0MiBwYXJhbV8zID0gdV9yb3RhdGlvbjFfUzFfYzA7CglmbG9hdCBwYXJhbV80ID0gMC4xNzsKCWZsb2F0IF8zMTkgPSBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChwYXJhbSwgcGFyYW1fMSwgcGFyYW1fMiwgcGFyYW1fMywgcGFyYW1fNCk7CglmbG9hdCBnMSA9IF8zMTk7CglmbG9hdDIgcGFyYW1fNSA9IGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtXzYgPSB1dl9zY2FsZTsKCWZsb2F0MiBwYXJhbV83ID0gdV9jaXJjbGUyX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzggPSB1X3JvdGF0aW9uMl9TMV9jMDsKCWZsb2F0IHBhcmFtXzkgPSAwLjI7CglmbG9hdCBfMzMxID0gRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAocGFyYW1fNSwgcGFyYW1fNiwgcGFyYW1fNywgcGFyYW1fOCwgcGFyYW1fOSk7CglmbG9hdCBnMiA9IF8zMzE7CglmbG9hdDIgcGFyYW1fMTAgPSBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbV8xMSA9IHV2X3NjYWxlOwoJZmxvYXQyIHBhcmFtXzEyID0gdV9jaXJjbGUzX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzEzID0gdV9yb3RhdGlvbjNfUzFfYzA7CglmbG9hdCBwYXJhbV8xNCA9IDAuMjc1OwoJZmxvYXQgXzM0NCA9IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKHBhcmFtXzEwLCBwYXJhbV8xMSwgcGFyYW1fMTIsIHBhcmFtXzEzLCBwYXJhbV8xNCk7CglmbG9hdCBnMyA9IF8zNDQ7CglmbG9hdCB2ID0gKChnMSAqIGcxICsgZzIpIC0gZzMpICogMC41OwoJcmV0dXJuIGNsYW1wKDAuNDUgKyAwLjggKiB2LCAwLjAsIDEuMCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9yaW5nX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IHRoaWNrbmVzcywgZmxvYXQgYmx1cikgCnsKCWZsb2F0MiBwYXJhbSA9IHV2OwoJZmxvYXQyIHBhcmFtXzEgPSB4eTsKCWZsb2F0IHBhcmFtXzIgPSByYWRpdXMgKyB0aGlja25lc3M7CglmbG9hdCBwYXJhbV8zID0gYmx1cjsKCWZsb2F0IGNpcmNsZV9vdXRlciA9IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtLCBwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zKTsKCWZsb2F0MiBwYXJhbV80ID0gdXY7CglmbG9hdDIgcGFyYW1fNSA9IHh5OwoJZmxvYXQgcGFyYW1fNiA9IG1heChyYWRpdXMgLSB0aGlja25lc3MsIDAuMCk7CglmbG9hdCBwYXJhbV83ID0gYmx1cjsKCWZsb2F0IGNpcmNsZV9pbm5lciA9IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtXzQsIHBhcmFtXzUsIHBhcmFtXzYsIHBhcmFtXzcpOwoJcmV0dXJuIGNsYW1wKGNpcmNsZV9vdXRlciAtIGNpcmNsZV9pbm5lciwgMC4wLCAxLjApOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RyaWFuZ2xlX25vaXNlX1MxX2MwKGlub3V0IGZsb2F0MiBuKSAKewoJbiA9IGZyYWN0KG4gKiBmbG9hdDIoNS4zOTg3LCA1LjQ0MjEpKTsKCW4gKz0gZmxvYXQyKGRvdChuLnl4LCBuICsgZmxvYXQyKDIxLjUzNTEsIDE0LjMxMzcpKSk7CglmbG9hdCB4eSA9IG4ueCAqIG4ueTsKCXJldHVybiAoZnJhY3QoeHkgKiA5NS40MzA3KSArIGZyYWN0KHh5ICogNzUuMDQ5NjEpKSAtIDEuMDsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAoZmxvYXQgdiwgZmxvYXQgbCwgZmxvYXQgaCkgCnsKCXJldHVybiBzdGVwKGwsIHYpICogKDEuMCAtIHN0ZXAoaCwgdikpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NwYXJrbGVfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdCB0KSAKewoJZmxvYXQyIHBhcmFtID0gdXY7CglmbG9hdCBfMjQyID0gRkxUX2ZsdXR0ZXJfbG9jYWxfdHJpYW5nbGVfbm9pc2VfUzFfYzAocGFyYW0pOwoJZmxvYXQgbiA9IF8yNDI7CglmbG9hdCBwYXJhbV8xID0gbjsKCWZsb2F0IHBhcmFtXzIgPSAwLjA7CglmbG9hdCBwYXJhbV8zID0gMC4wNTsKCWZsb2F0IHMgPSBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAocGFyYW1fMSwgcGFyYW1fMiwgcGFyYW1fMyk7CglmbG9hdCBwYXJhbV80ID0gbiArIHNpbigzLjE0MTU5Mjc0ICogKHQgKyAwLjM1KSk7CglmbG9hdCBwYXJhbV81ID0gMC4xOwoJZmxvYXQgcGFyYW1fNiA9IDAuMTU7CglzICs9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV80LCBwYXJhbV81LCBwYXJhbV82KTsKCWZsb2F0IHBhcmFtXzcgPSBuICsgc2luKDMuMTQxNTkyNzQgKiAodCArIDAuNykpOwoJZmxvYXQgcGFyYW1fOCA9IDAuMjsKCWZsb2F0IHBhcmFtXzkgPSAwLjI1OwoJcyArPSBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAocGFyYW1fNywgcGFyYW1fOCwgcGFyYW1fOSk7CglmbG9hdCBwYXJhbV8xMCA9IG4gKyBzaW4oMy4xNDE1OTI3NCAqICh0ICsgMS4wNSkpOwoJZmxvYXQgcGFyYW1fMTEgPSAwLjM7CglmbG9hdCBwYXJhbV8xMiA9IDAuMzU7CglzICs9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV8xMCwgcGFyYW1fMTEsIHBhcmFtXzEyKTsKCXJldHVybiBjbGFtcChzLCAwLjAsIDEuMCkgKiAwLjU1Owp9CnZvaWQgRkxUX21haW5fUzFfYzAoKSAKewoJdV9hbHBoYV9TMV9jMCA9IHVfY29tcG9zaXRlXzFfUzFfYzAueDsKCXVfc3BhcmtsZV9hbHBoYV9TMV9jMCA9IHVfY29tcG9zaXRlXzFfUzFfYzAueTsKCXVfYmx1cl9TMV9jMCA9IHVfY29tcG9zaXRlXzFfUzFfYzAuejsKCXVfcmFkaXVzX3NjYWxlX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC53OwoJZmxvYXQyIHAgPSBGTFRfZmx1dHRlcl9sb2NhbF9GbHV0dGVyRnJhZ0Nvb3JkX1MxX2MwKCk7CglmbG9hdDIgdXZfMSA9IHAgKiB1X3Jlc29sdXRpb25fc2NhbGVfUzFfYzA7CglmbG9hdDIgZGVuc2l0eV91diA9IHV2XzEgLSBtb2QocCwgdV9ub2lzZV9zY2FsZV9TMV9jMCk7CglmbG9hdCByYWRpdXMgPSB1X21heF9yYWRpdXNfUzFfYzAgKiB1X3JhZGl1c19zY2FsZV9TMV9jMDsKCWZsb2F0MiBwYXJhbV8xMyA9IHV2XzE7CglmbG9hdCB0dXJidWxlbmNlID0gRkxUX2ZsdXR0ZXJfbG9jYWxfdHVyYnVsZW5jZV9TMV9jMChwYXJhbV8xMyk7CglmbG9hdDIgcGFyYW1fMTQgPSBwOwoJZmxvYXQyIHBhcmFtXzE1ID0gdV9jZW50ZXJfUzFfYzA7CglmbG9hdCBwYXJhbV8xNiA9IHJhZGl1czsKCWZsb2F0IHBhcmFtXzE3ID0gMC4wNSAqIHVfbWF4X3JhZGl1c19TMV9jMDsKCWZsb2F0IHBhcmFtXzE4ID0gdV9ibHVyX1MxX2MwOwoJZmxvYXQgcmluZyA9IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfcmluZ19TMV9jMChwYXJhbV8xNCwgcGFyYW1fMTUsIHBhcmFtXzE2LCBwYXJhbV8xNywgcGFyYW1fMTgpOwoJZmxvYXQyIHBhcmFtXzE5ID0gZGVuc2l0eV91djsKCWZsb2F0IHBhcmFtXzIwID0gdV9ub2lzZV9waGFzZV9TMV9jMDsKCWZsb2F0IHNwYXJrbGUgPSAoKEZMVF9mbHV0dGVyX2xvY2FsX3NwYXJrbGVfUzFfYzAocGFyYW1fMTksIHBhcmFtXzIwKSAqIHJpbmcpICogdHVyYnVsZW5jZSkgKiB1X3NwYXJrbGVfYWxwaGFfUzFfYzA7CglmbG9hdDIgcGFyYW1fMjEgPSBwOwoJZmxvYXQyIHBhcmFtXzIyID0gdV9jZW50ZXJfUzFfYzA7CglmbG9hdCBwYXJhbV8yMyA9IHJhZGl1czsKCWZsb2F0IHBhcmFtXzI0ID0gdV9ibHVyX1MxX2MwOwoJZmxvYXQgd2F2ZV9hbHBoYSA9IChGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChwYXJhbV8yMSwgcGFyYW1fMjIsIHBhcmFtXzIzLCBwYXJhbV8yNCkgKiB1X2FscGhhX1MxX2MwKSAqIHVfY29sb3JfUzFfYzAudzsKCWZsb2F0NCB3YXZlX2NvbG9yID0gZmxvYXQ0KHVfY29sb3JfUzFfYzAueHl6ICogd2F2ZV9hbHBoYSwgd2F2ZV9hbHBoYSk7CglmcmFnQ29sb3JfUzFfYzAgPSBtaXgod2F2ZV9jb2xvciwgZmxvYXQ0KDEuMCksIGZsb2F0NChzcGFya2xlKSk7Cn0KaGFsZjQgcnVudGltZV9zaGFkZXJfUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF8wX2luQ29sb3IgPSBfaW5wdXQ7CglmbG9hdDIgX3RtcF8xX2Nvb3JkcyA9IHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwoJZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzAgPSBmbG9hdDQoX3RtcF8xX2Nvb3JkcywgMC4wLCAwLjApOwoJRkxUX21haW5fUzFfYzAoKTsKCXJldHVybiBoYWxmNChoYWxmNChmcmFnQ29sb3JfUzFfYzApKTsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIHJ1bnRpbWVfc2hhZGVyX1MxX2MwKF9pbnB1dCk7Cn0KaGFsZjQgUmVjdF9TMl9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzJfaW5Db2xvciA9IF9pbnB1dDsKCWhhbGYgY292ZXJhZ2U7CglpZiAoaW50KDEpID09IGtGaWxsQldfUzJfYzAgfHwgaW50KDEpID09IGtJbnZlcnNlRmlsbEJXX1MyX2MwKSAKCXsKCQljb3ZlcmFnZSA9IGhhbGYoYWxsKGdyZWF0ZXJUaGFuKGZsb2F0NChza19GcmFnQ29vcmQueHksIHVyZWN0VW5pZm9ybV9TMl9jMC56dyksIGZsb2F0NCh1cmVjdFVuaWZvcm1fUzJfYzAueHksIHNrX0ZyYWdDb29yZC54eSkpKSk7Cgl9CgllbHNlIAoJewoJCWhhbGY0IGRpc3RzNCA9IHNhdHVyYXRlKGhhbGY0KDEuMCwgMS4wLCAtMS4wLCAtMS4wKSAqIGhhbGY0KHNrX0ZyYWdDb29yZC54eXh5IC0gdXJlY3RVbmlmb3JtX1MyX2MwKSk7CgkJaGFsZjIgZGlzdHMyID0gKGRpc3RzNC54eSArIGRpc3RzNC56dykgLSAxLjA7CgkJY292ZXJhZ2UgPSBkaXN0czIueCAqIGRpc3RzMi55OwoJfQoJaWYgKGludCgxKSA9PSBrSW52ZXJzZUZpbGxCV19TMl9jMCB8fCBpbnQoMSkgPT0ga0ludmVyc2VGaWxsQUFfUzJfYzApIAoJewoJCWNvdmVyYWdlID0gMS4wIC0gY292ZXJhZ2U7Cgl9CglyZXR1cm4gaGFsZjQoaGFsZjQoY292ZXJhZ2UpKTsKfQpoYWxmNCBDaXJjbGVfUzJfYzFfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF8zX2luQ29sb3IgPSBfaW5wdXQ7CgloYWxmIGQ7CglpZiAoaW50KDEpID09IGtJbnZlcnNlRmlsbEJXX1MyX2MxX2MwIHx8IGludCgxKSA9PSBrSW52ZXJzZUZpbGxBQV9TMl9jMV9jMCkgCgl7CgkJZCA9IGhhbGYoKGxlbmd0aCgodWNpcmNsZV9TMl9jMV9jMC54eSAtIHNrX0ZyYWdDb29yZC54eSkgKiB1Y2lyY2xlX1MyX2MxX2MwLncpIC0gMS4wKSAqIHVjaXJjbGVfUzJfYzFfYzAueik7Cgl9CgllbHNlIAoJewoJCWQgPSBoYWxmKCgxLjAgLSBsZW5ndGgoKHVjaXJjbGVfUzJfYzFfYzAueHkgLSBza19GcmFnQ29vcmQueHkpICogdWNpcmNsZV9TMl9jMV9jMC53KSkgKiB1Y2lyY2xlX1MyX2MxX2MwLnopOwoJfQoJcmV0dXJuIGhhbGY0KGhhbGY0KGludCgxKSA9PSBrRmlsbEFBX1MyX2MxX2MwIHx8IGludCgxKSA9PSBrSW52ZXJzZUZpbGxBQV9TMl9jMV9jMCA/IHNhdHVyYXRlKGQpIDogaGFsZihkID4gMC41KSkpOwp9CmhhbGY0IEJsZW5kX1MyX2MxKGhhbGY0IF9zcmMsIGhhbGY0IF9kc3QpIAp7CglyZXR1cm4gYmxlbmRfbW9kdWxhdGUoX3NyYywgQ2lyY2xlX1MyX2MxX2MwKF9zcmMpKTsKfQpoYWxmNCBCbGVuZF9TMihoYWxmNCBfc3JjLCBoYWxmNCBfZHN0KSAKewoJcmV0dXJuIGJsZW5kX21vZHVsYXRlKFJlY3RfUzJfYzAoX3NyYyksIEJsZW5kX1MyX2MxKF9zcmMsIF9kc3QpKTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJZmxvYXQgY292ZXJhZ2UgPSB2Y292ZXJhZ2VfUzA7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGNvdmVyYWdlKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IE1hdHJpeEVmZmVjdF9TMShvdXRwdXRDb2xvcl9TMCk7CgloYWxmNCBvdXRwdXRfUzI7CglvdXRwdXRfUzIgPSBCbGVuZF9TMihvdXRwdXRDb3ZlcmFnZV9TMCwgaGFsZjQoMSkpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dF9TMjsKCX0KfQoAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAHBvc2l0aW9uCAAAAGNvdmVyYWdlBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA="}} \ No newline at end of file +{"platform":"android","name":"XQ DE72","engineRevision":"a18df97ca57a249df5d8d68cd0820600223ce262","data":{"AYQA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAAAAMYAAAAAAAQAAAABAMQAAAAA":"DAAAAExTS1MlAgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0NCB1bG9jYWxNYXRyaXhfUzA7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiBmbG9hdDQgaW5DaXJjbGVFZGdlOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIENpcmNsZUdlb21ldHJ5UHJvY2Vzc29yCgl2aW5DaXJjbGVFZGdlX1MwID0gaW5DaXJjbGVFZGdlOwoJdmluQ29sb3JfUzAgPSBpbkNvbG9yOwoJZmxvYXQyIF90bXBfMF9pblBvc2l0aW9uID0gaW5Qb3NpdGlvbjsKCWZsb2F0MiBfdG1wXzFfaW5Qb3NpdGlvbiA9IHVsb2NhbE1hdHJpeF9TMC54eiAqIGluUG9zaXRpb24gKyB1bG9jYWxNYXRyaXhfUzAueXc7Cglza19Qb3NpdGlvbiA9IF90bXBfMF9pblBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAAAEMCAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIENpcmNsZUdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDQgY2lyY2xlRWRnZTsKCWNpcmNsZUVkZ2UgPSB2aW5DaXJjbGVFZGdlX1MwOwoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZpbkNvbG9yX1MwOwoJZmxvYXQgZCA9IGxlbmd0aChjaXJjbGVFZGdlLnh5KTsKCWhhbGYgZGlzdGFuY2VUb091dGVyRWRnZSA9IGhhbGYoY2lyY2xlRWRnZS56ICogKDEuMCAtIGQpKTsKCWhhbGYgZWRnZUFscGhhID0gc2F0dXJhdGUoZGlzdGFuY2VUb091dGVyRWRnZSk7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGVkZ2VBbHBoYSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADAAAAGluQ2lyY2xlRWRnZQAAAAA=","B2ABSAAABQAAIAABBYAAB7777777777774ABICAAAAAAAAAAAAAABGABAAAAAEAAAAAIBEABAAAAA":"DAAAAExTS1PDAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGhhbGY0IHVDb2xvcl9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGYgaW5Db3ZlcmFnZTsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBEZWZhdWx0R2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IGNvbG9yID0gdUNvbG9yX1MwOwoJY29sb3IgPSBjb2xvciAqIGluQ292ZXJhZ2U7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCWZsb2F0MiBfdG1wXzFfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8zX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBfdG1wXzFfaW5Qb3NpdGlvbi54eTAxOwp9CgAAAAAAUQEAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQpub3BlcnNwZWN0aXZlIGluIGhhbGY0IHZjb2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIERlZmF1bHRHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAoAAABpblBvc2l0aW9uAAAKAAAAaW5Db3ZlcmFnZQAAAAAAAA==","GZIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAIIBAAAABAAAAALIEAAAAAAAAAAAAAABQAMAAAABAAAAAAABBAMAAAAA":"DAAAAExTS1PIAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfMl9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzEpICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAL8CAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7Cm5vcGVyc3BlY3RpdmUgaW4gaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MxLCB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMCkucnJycjsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzAoX2lucHV0KTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IE1hdHJpeEVmZmVjdF9TMShvdXRwdXRDb3ZlcmFnZV9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","GZJAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAABAAAAAABBAMABQAMAAAABAAAAAAABBAMAAA":"DAAAAExTS1N3AQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgcG9zaXRpb247CmluIGhhbGY0IGNvbG9yOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7Cgl2bG9jYWxDb29yZF9TMCA9IGxvY2FsQ29vcmQ7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cn0KAAAAAAApAgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQyIHZsb2NhbENvb3JkX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJZmxvYXQyIHRleENvb3JkOwoJdGV4Q29vcmQgPSB2bG9jYWxDb29yZF9TMDsKCW91dHB1dENvbG9yX1MwID0gKGJsZW5kX21vZHVsYXRlKHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMCwgdGV4Q29vcmQpLCBvdXRwdXRDb2xvcl9TMCkpOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","DAQAAAAAAAAAAAAAAJQAAIGAAEACBYQCAGAEFAIBAAAAAABAAAAAAAAAAAAAAMYAAAAAAAQAAAABAMQAAAAA":"DAAAAExTS1N4AgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0MiB1QXRsYXNTaXplSW52X1MwOwppbiBmbG9hdDIgaW5Qb3NpdGlvbjsKaW4gaGFsZjQgaW5Db2xvcjsKaW4gdXNob3J0MiBpblRleHR1cmVDb29yZHM7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQgdlRleEluZGV4X1MwOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgQml0bWFwVGV4dAoJaW50IHRleElkeCA9IDA7CglmbG9hdDIgdW5vcm1UZXhDb29yZHMgPSBmbG9hdDIoaW5UZXh0dXJlQ29vcmRzLngsIGluVGV4dHVyZUNvb3Jkcy55KTsKCXZUZXh0dXJlQ29vcmRzX1MwID0gdW5vcm1UZXhDb29yZHMgKiB1QXRsYXNTaXplSW52X1MwOwoJdlRleEluZGV4X1MwID0gZmxvYXQodGV4SWR4KTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzFfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247Cglza19Qb3NpdGlvbiA9IGluUG9zaXRpb24ueHkwMTsKfQoAAAAACwIAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQyIHZUZXh0dXJlQ29vcmRzX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0IHZUZXhJbmRleF9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIEJpdG1hcFRleHQKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWhhbGY0IHRleENvbG9yOwoJewoJCXRleENvbG9yID0gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB2VGV4dHVyZUNvb3Jkc19TMCkucnJycjsKCX0KCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gdGV4Q29sb3I7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADwAAAGluVGV4dHVyZUNvb3JkcwAAAAAA","AYQA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAACABZQA6AAAEAAAAAAAMADAAAAAIAAAAAAAIIDA":"DAAAAExTS1MlAgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0NCB1bG9jYWxNYXRyaXhfUzA7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiBmbG9hdDQgaW5DaXJjbGVFZGdlOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIENpcmNsZUdlb21ldHJ5UHJvY2Vzc29yCgl2aW5DaXJjbGVFZGdlX1MwID0gaW5DaXJjbGVFZGdlOwoJdmluQ29sb3JfUzAgPSBpbkNvbG9yOwoJZmxvYXQyIF90bXBfMF9pblBvc2l0aW9uID0gaW5Qb3NpdGlvbjsKCWZsb2F0MiBfdG1wXzFfaW5Qb3NpdGlvbiA9IHVsb2NhbE1hdHJpeF9TMC54eiAqIGluUG9zaXRpb24gKyB1bG9jYWxNYXRyaXhfUzAueXc7Cglza19Qb3NpdGlvbiA9IF90bXBfMF9pblBvc2l0aW9uLnh5MDE7Cn0KAAAAAQAAAOgDAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQ0IHZpbkNpcmNsZUVkZ2VfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gaGFsZjQgdmluQ29sb3JfUzA7CmhhbGY0IENpcmN1bGFyUlJlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MxLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MxLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CgloYWxmIGFscGhhID0gaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzEueCAtIGxlbmd0aChkeHkpKSk7CglhbHBoYSA9IDEuMCAtIGFscGhhOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQ0IGNpcmNsZUVkZ2U7CgljaXJjbGVFZGdlID0gdmluQ2lyY2xlRWRnZV9TMDsKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWZsb2F0IGQgPSBsZW5ndGgoY2lyY2xlRWRnZS54eSk7CgloYWxmIGRpc3RhbmNlVG9PdXRlckVkZ2UgPSBoYWxmKGNpcmNsZUVkZ2UueiAqICgxLjAgLSBkKSk7CgloYWxmIGVkZ2VBbHBoYSA9IHNhdHVyYXRlKGRpc3RhbmNlVG9PdXRlckVkZ2UpOwoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChlZGdlQWxwaGEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQ2lyY3VsYXJSUmVjdF9TMShvdXRwdXRDb3ZlcmFnZV9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADAAAAGluQ2lyY2xlRWRnZQAAAAA=","DAQAAAAAAAAAAAAAAJQAAIGAAEACBYQCAGAEFAIBAAAAAABAAAAAAAAAAAACAB4QA4AAAEAAAAAAAMADAAAAAIAAAAAAAIID":"DAAAAExTS1N4AgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0MiB1QXRsYXNTaXplSW52X1MwOwppbiBmbG9hdDIgaW5Qb3NpdGlvbjsKaW4gaGFsZjQgaW5Db2xvcjsKaW4gdXNob3J0MiBpblRleHR1cmVDb29yZHM7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQgdlRleEluZGV4X1MwOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgQml0bWFwVGV4dAoJaW50IHRleElkeCA9IDA7CglmbG9hdDIgdW5vcm1UZXhDb29yZHMgPSBmbG9hdDIoaW5UZXh0dXJlQ29vcmRzLngsIGluVGV4dHVyZUNvb3Jkcy55KTsKCXZUZXh0dXJlQ29vcmRzX1MwID0gdW5vcm1UZXhDb29yZHMgKiB1QXRsYXNTaXplSW52X1MwOwoJdlRleEluZGV4X1MwID0gZmxvYXQodGV4SWR4KTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzFfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247Cglza19Qb3NpdGlvbiA9IGluUG9zaXRpb24ueHkwMTsKfQoBAAAAmgMAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQp1bmlmb3JtIGZsb2F0NCB1aW5uZXJSZWN0X1MxOwp1bmlmb3JtIGhhbGYyIHVyYWRpdXNQbHVzSGFsZl9TMTsKc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdCB2VGV4SW5kZXhfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gaGFsZjQgdmluQ29sb3JfUzA7CmhhbGY0IENpcmN1bGFyUlJlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MxLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MxLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CgloYWxmIGFscGhhID0gaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzEueCAtIGxlbmd0aChkeHkpKSk7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIEJpdG1hcFRleHQKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWhhbGY0IHRleENvbG9yOwoJewoJCXRleENvbG9yID0gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB2VGV4dHVyZUNvb3Jkc19TMCkucnJycjsKCX0KCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gdGV4Q29sb3I7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBDaXJjdWxhclJSZWN0X1MxKG91dHB1dENvdmVyYWdlX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACgAAAGluUG9zaXRpb24AAAcAAABpbkNvbG9yAA8AAABpblRleHR1cmVDb29yZHMAAAAAAA==","AYQQ5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAAAAMYAAAAAAAQAAAABAMQAAAAA":"DAAAAExTS1MlAgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0NCB1bG9jYWxNYXRyaXhfUzA7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiBmbG9hdDQgaW5DaXJjbGVFZGdlOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIENpcmNsZUdlb21ldHJ5UHJvY2Vzc29yCgl2aW5DaXJjbGVFZGdlX1MwID0gaW5DaXJjbGVFZGdlOwoJdmluQ29sb3JfUzAgPSBpbkNvbG9yOwoJZmxvYXQyIF90bXBfMF9pblBvc2l0aW9uID0gaW5Qb3NpdGlvbjsKCWZsb2F0MiBfdG1wXzFfaW5Qb3NpdGlvbiA9IHVsb2NhbE1hdHJpeF9TMC54eiAqIGluUG9zaXRpb24gKyB1bG9jYWxNYXRyaXhfUzAueXc7Cglza19Qb3NpdGlvbiA9IF90bXBfMF9pblBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAAANQCAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIENpcmNsZUdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDQgY2lyY2xlRWRnZTsKCWNpcmNsZUVkZ2UgPSB2aW5DaXJjbGVFZGdlX1MwOwoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZpbkNvbG9yX1MwOwoJZmxvYXQgZCA9IGxlbmd0aChjaXJjbGVFZGdlLnh5KTsKCWhhbGYgZGlzdGFuY2VUb091dGVyRWRnZSA9IGhhbGYoY2lyY2xlRWRnZS56ICogKDEuMCAtIGQpKTsKCWhhbGYgZWRnZUFscGhhID0gc2F0dXJhdGUoZGlzdGFuY2VUb091dGVyRWRnZSk7CgloYWxmIGRpc3RhbmNlVG9Jbm5lckVkZ2UgPSBoYWxmKGNpcmNsZUVkZ2UueiAqIChkIC0gY2lyY2xlRWRnZS53KSk7CgloYWxmIGlubmVyQWxwaGEgPSBzYXR1cmF0ZShkaXN0YW5jZVRvSW5uZXJFZGdlKTsKCWVkZ2VBbHBoYSAqPSBpbm5lckFscGhhOwoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChlZGdlQWxwaGEpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADAAAAGluQ2lyY2xlRWRnZQAAAAA=","GYJAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAQAAAAAAQQGAAYAGAAAAAQAAAAAAAQQGAAA":"DAAAAExTS1MwAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgcG9zaXRpb247CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmxvY2FsQ29vcmRfUzAgPSBsb2NhbENvb3JkOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAADvAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwID0gaGFsZjQoMSk7CglmbG9hdDIgdGV4Q29vcmQ7Cgl0ZXhDb29yZCA9IHZsb2NhbENvb3JkX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSAoYmxlbmRfbW9kdWxhdGUoc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB0ZXhDb29yZCksIGhhbGY0KDEpKSk7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACAAAAHBvc2l0aW9uCgAAAGxvY2FsQ29vcmQAAAAAAAA=","GZIACAAAABQAAGAAAQ4AAAAAGQQAARC4GAAAIOCAAD6P7777777777YDAAAAAAAAAAAJIBBYGQ467YIAAAAAAQAAAAAMACTRNBZN5QYBAAAAAAAAAAAIAGIAAAAAAAIAAAAAQGIAAAAAA":"DAAAAExTS1M7AgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQgY292ZXJhZ2U7CmluIGhhbGY0IGNvbG9yOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdCB2Y292ZXJhZ2VfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDIgcG9zaXRpb24gPSBwb3NpdGlvbi54eTsKCXZjb2xvcl9TMCA9IGNvbG9yOwoJdmNvdmVyYWdlX1MwID0gY292ZXJhZ2U7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAAAJhwAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQpmbG9hdDQgZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzA7CmZsb2F0NCBmcmFnQ29sb3JfUzFfYzA7CmZsb2F0IHVfYWxwaGFfUzFfYzA7CmZsb2F0IHVfc3BhcmtsZV9hbHBoYV9TMV9jMDsKZmxvYXQgdV9ibHVyX1MxX2MwOwpmbG9hdCB1X3JhZGl1c19zY2FsZV9TMV9jMDsKdW5pZm9ybSBmbG9hdDQgdV9jb2xvcl9TMV9jMDsKdW5pZm9ybSBmbG9hdDQgdV9jb21wb3NpdGVfMV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jZW50ZXJfUzFfYzA7CnVuaWZvcm0gZmxvYXQgdV9tYXhfcmFkaXVzX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3Jlc29sdXRpb25fc2NhbGVfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfbm9pc2Vfc2NhbGVfUzFfYzA7CnVuaWZvcm0gZmxvYXQgdV9ub2lzZV9waGFzZV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jaXJjbGUxX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NpcmNsZTJfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2lyY2xlM19TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yb3RhdGlvbjFfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcm90YXRpb24yX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3JvdGF0aW9uM19TMV9jMDsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxOwpub3BlcnNwZWN0aXZlIGluIGhhbGY0IHZjb2xvcl9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdCB2Y292ZXJhZ2VfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwpmbG9hdDIgRkxUX2ZsdXR0ZXJfbG9jYWxfRmx1dHRlckZyYWdDb29yZF9TMV9jMCgpOwpmbG9hdDJ4MiBGTFRfZmx1dHRlcl9sb2NhbF9yb3RhdGUyZF9TMV9jMChmbG9hdDIgcmFkKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgYmx1cik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKGZsb2F0MiByZXNvbHV0aW9uLCBpbm91dCBmbG9hdDIgcCwgZmxvYXQyIHh5LCBmbG9hdDIgcm90YXRpb24sIGZsb2F0IGNlbGxfZGlhbWV0ZXIpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90dXJidWxlbmNlX1MxX2MwKGZsb2F0MiB1dik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfcmluZ19TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCB0aGlja25lc3MsIGZsb2F0IGJsdXIpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90cmlhbmdsZV9ub2lzZV9TMV9jMChpbm91dCBmbG9hdDIgbik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChmbG9hdCB2LCBmbG9hdCBsLCBmbG9hdCBoKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc3BhcmtsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0IHQpOwp2b2lkIEZMVF9tYWluX1MxX2MwKCk7CmZsb2F0MiBGTFRfZmx1dHRlcl9sb2NhbF9GbHV0dGVyRnJhZ0Nvb3JkX1MxX2MwKCkgCnsKCXJldHVybiBmbHV0dGVyX0ZyYWdDb29yZF9TMV9jMC54eTsKfQpmbG9hdDJ4MiBGTFRfZmx1dHRlcl9sb2NhbF9yb3RhdGUyZF9TMV9jMChmbG9hdDIgcmFkKSAKewoJcmV0dXJuIGZsb2F0MngyKHJhZC54LCAtcmFkLnksIHJhZC55LCByYWQueCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgYmx1cikgCnsKCWZsb2F0IGJsdXJfaGFsZiA9IGJsdXIgKiAwLjU7CglmbG9hdCBkID0gZGlzdGFuY2UodXYsIHh5KTsKCXJldHVybiAxLjAgLSBzbW9vdGhzdGVwKDEuMCAtIGJsdXJfaGFsZiwgMS4wICsgYmx1cl9oYWxmLCBkIC8gcmFkaXVzKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChmbG9hdDIgcmVzb2x1dGlvbiwgaW5vdXQgZmxvYXQyIHAsIGZsb2F0MiB4eSwgZmxvYXQyIHJvdGF0aW9uLCBmbG9hdCBjZWxsX2RpYW1ldGVyKSAKewoJZmxvYXQyIHBhcmFtID0gcm90YXRpb247CglwID0gRkxUX2ZsdXR0ZXJfbG9jYWxfcm90YXRlMmRfUzFfYzAocGFyYW0pICogKHh5IC0gcCkgKyB4eTsKCXAgPSBtb2QocCwgZmxvYXQyKGNlbGxfZGlhbWV0ZXIpKSAvIHJlc29sdXRpb247CglmbG9hdCBjZWxsX3V2ID0gKGNlbGxfZGlhbWV0ZXIgLyByZXNvbHV0aW9uLnkpICogMC41OwoJZmxvYXQgciA9IDAuNjUgKiBjZWxsX3V2OwoJZmxvYXQyIHBhcmFtXzEgPSBwOwoJZmxvYXQyIHBhcmFtXzIgPSBmbG9hdDIoY2VsbF91dik7CglmbG9hdCBwYXJhbV8zID0gcjsKCWZsb2F0IHBhcmFtXzQgPSByICogNTAuMDsKCXJldHVybiBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zLCBwYXJhbV80KTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90dXJidWxlbmNlX1MxX2MwKGZsb2F0MiB1dikgCnsKCWZsb2F0MiB1dl9zY2FsZSA9IHV2ICogZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW0gPSBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbV8xID0gdXZfc2NhbGU7CglmbG9hdDIgcGFyYW1fMiA9IHVfY2lyY2xlMV9TMV9jMDsKCWZsb2F0MiBwYXJhbV8zID0gdV9yb3RhdGlvbjFfUzFfYzA7CglmbG9hdCBwYXJhbV80ID0gMC4xNzsKCWZsb2F0IF8zMTkgPSBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChwYXJhbSwgcGFyYW1fMSwgcGFyYW1fMiwgcGFyYW1fMywgcGFyYW1fNCk7CglmbG9hdCBnMSA9IF8zMTk7CglmbG9hdDIgcGFyYW1fNSA9IGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtXzYgPSB1dl9zY2FsZTsKCWZsb2F0MiBwYXJhbV83ID0gdV9jaXJjbGUyX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzggPSB1X3JvdGF0aW9uMl9TMV9jMDsKCWZsb2F0IHBhcmFtXzkgPSAwLjI7CglmbG9hdCBfMzMxID0gRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAocGFyYW1fNSwgcGFyYW1fNiwgcGFyYW1fNywgcGFyYW1fOCwgcGFyYW1fOSk7CglmbG9hdCBnMiA9IF8zMzE7CglmbG9hdDIgcGFyYW1fMTAgPSBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbV8xMSA9IHV2X3NjYWxlOwoJZmxvYXQyIHBhcmFtXzEyID0gdV9jaXJjbGUzX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzEzID0gdV9yb3RhdGlvbjNfUzFfYzA7CglmbG9hdCBwYXJhbV8xNCA9IDAuMjc1OwoJZmxvYXQgXzM0NCA9IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKHBhcmFtXzEwLCBwYXJhbV8xMSwgcGFyYW1fMTIsIHBhcmFtXzEzLCBwYXJhbV8xNCk7CglmbG9hdCBnMyA9IF8zNDQ7CglmbG9hdCB2ID0gKChnMSAqIGcxICsgZzIpIC0gZzMpICogMC41OwoJcmV0dXJuIGNsYW1wKDAuNDUgKyAwLjggKiB2LCAwLjAsIDEuMCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9yaW5nX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IHRoaWNrbmVzcywgZmxvYXQgYmx1cikgCnsKCWZsb2F0MiBwYXJhbSA9IHV2OwoJZmxvYXQyIHBhcmFtXzEgPSB4eTsKCWZsb2F0IHBhcmFtXzIgPSByYWRpdXMgKyB0aGlja25lc3M7CglmbG9hdCBwYXJhbV8zID0gYmx1cjsKCWZsb2F0IGNpcmNsZV9vdXRlciA9IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtLCBwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zKTsKCWZsb2F0MiBwYXJhbV80ID0gdXY7CglmbG9hdDIgcGFyYW1fNSA9IHh5OwoJZmxvYXQgcGFyYW1fNiA9IG1heChyYWRpdXMgLSB0aGlja25lc3MsIDAuMCk7CglmbG9hdCBwYXJhbV83ID0gYmx1cjsKCWZsb2F0IGNpcmNsZV9pbm5lciA9IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtXzQsIHBhcmFtXzUsIHBhcmFtXzYsIHBhcmFtXzcpOwoJcmV0dXJuIGNsYW1wKGNpcmNsZV9vdXRlciAtIGNpcmNsZV9pbm5lciwgMC4wLCAxLjApOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RyaWFuZ2xlX25vaXNlX1MxX2MwKGlub3V0IGZsb2F0MiBuKSAKewoJbiA9IGZyYWN0KG4gKiBmbG9hdDIoNS4zOTg3LCA1LjQ0MjEpKTsKCW4gKz0gZmxvYXQyKGRvdChuLnl4LCBuICsgZmxvYXQyKDIxLjUzNTEsIDE0LjMxMzcpKSk7CglmbG9hdCB4eSA9IG4ueCAqIG4ueTsKCXJldHVybiAoZnJhY3QoeHkgKiA5NS40MzA3KSArIGZyYWN0KHh5ICogNzUuMDQ5NjEpKSAtIDEuMDsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAoZmxvYXQgdiwgZmxvYXQgbCwgZmxvYXQgaCkgCnsKCXJldHVybiBzdGVwKGwsIHYpICogKDEuMCAtIHN0ZXAoaCwgdikpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NwYXJrbGVfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdCB0KSAKewoJZmxvYXQyIHBhcmFtID0gdXY7CglmbG9hdCBfMjQyID0gRkxUX2ZsdXR0ZXJfbG9jYWxfdHJpYW5nbGVfbm9pc2VfUzFfYzAocGFyYW0pOwoJZmxvYXQgbiA9IF8yNDI7CglmbG9hdCBwYXJhbV8xID0gbjsKCWZsb2F0IHBhcmFtXzIgPSAwLjA7CglmbG9hdCBwYXJhbV8zID0gMC4wNTsKCWZsb2F0IHMgPSBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAocGFyYW1fMSwgcGFyYW1fMiwgcGFyYW1fMyk7CglmbG9hdCBwYXJhbV80ID0gbiArIHNpbigzLjE0MTU5Mjc0ICogKHQgKyAwLjM1KSk7CglmbG9hdCBwYXJhbV81ID0gMC4xOwoJZmxvYXQgcGFyYW1fNiA9IDAuMTU7CglzICs9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV80LCBwYXJhbV81LCBwYXJhbV82KTsKCWZsb2F0IHBhcmFtXzcgPSBuICsgc2luKDMuMTQxNTkyNzQgKiAodCArIDAuNykpOwoJZmxvYXQgcGFyYW1fOCA9IDAuMjsKCWZsb2F0IHBhcmFtXzkgPSAwLjI1OwoJcyArPSBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAocGFyYW1fNywgcGFyYW1fOCwgcGFyYW1fOSk7CglmbG9hdCBwYXJhbV8xMCA9IG4gKyBzaW4oMy4xNDE1OTI3NCAqICh0ICsgMS4wNSkpOwoJZmxvYXQgcGFyYW1fMTEgPSAwLjM7CglmbG9hdCBwYXJhbV8xMiA9IDAuMzU7CglzICs9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV8xMCwgcGFyYW1fMTEsIHBhcmFtXzEyKTsKCXJldHVybiBjbGFtcChzLCAwLjAsIDEuMCkgKiAwLjU1Owp9CnZvaWQgRkxUX21haW5fUzFfYzAoKSAKewoJdV9hbHBoYV9TMV9jMCA9IHVfY29tcG9zaXRlXzFfUzFfYzAueDsKCXVfc3BhcmtsZV9hbHBoYV9TMV9jMCA9IHVfY29tcG9zaXRlXzFfUzFfYzAueTsKCXVfYmx1cl9TMV9jMCA9IHVfY29tcG9zaXRlXzFfUzFfYzAuejsKCXVfcmFkaXVzX3NjYWxlX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC53OwoJZmxvYXQyIHAgPSBGTFRfZmx1dHRlcl9sb2NhbF9GbHV0dGVyRnJhZ0Nvb3JkX1MxX2MwKCk7CglmbG9hdDIgdXZfMSA9IHAgKiB1X3Jlc29sdXRpb25fc2NhbGVfUzFfYzA7CglmbG9hdDIgZGVuc2l0eV91diA9IHV2XzEgLSBtb2QocCwgdV9ub2lzZV9zY2FsZV9TMV9jMCk7CglmbG9hdCByYWRpdXMgPSB1X21heF9yYWRpdXNfUzFfYzAgKiB1X3JhZGl1c19zY2FsZV9TMV9jMDsKCWZsb2F0MiBwYXJhbV8xMyA9IHV2XzE7CglmbG9hdCB0dXJidWxlbmNlID0gRkxUX2ZsdXR0ZXJfbG9jYWxfdHVyYnVsZW5jZV9TMV9jMChwYXJhbV8xMyk7CglmbG9hdDIgcGFyYW1fMTQgPSBwOwoJZmxvYXQyIHBhcmFtXzE1ID0gdV9jZW50ZXJfUzFfYzA7CglmbG9hdCBwYXJhbV8xNiA9IHJhZGl1czsKCWZsb2F0IHBhcmFtXzE3ID0gMC4wNSAqIHVfbWF4X3JhZGl1c19TMV9jMDsKCWZsb2F0IHBhcmFtXzE4ID0gdV9ibHVyX1MxX2MwOwoJZmxvYXQgcmluZyA9IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfcmluZ19TMV9jMChwYXJhbV8xNCwgcGFyYW1fMTUsIHBhcmFtXzE2LCBwYXJhbV8xNywgcGFyYW1fMTgpOwoJZmxvYXQyIHBhcmFtXzE5ID0gZGVuc2l0eV91djsKCWZsb2F0IHBhcmFtXzIwID0gdV9ub2lzZV9waGFzZV9TMV9jMDsKCWZsb2F0IHNwYXJrbGUgPSAoKEZMVF9mbHV0dGVyX2xvY2FsX3NwYXJrbGVfUzFfYzAocGFyYW1fMTksIHBhcmFtXzIwKSAqIHJpbmcpICogdHVyYnVsZW5jZSkgKiB1X3NwYXJrbGVfYWxwaGFfUzFfYzA7CglmbG9hdDIgcGFyYW1fMjEgPSBwOwoJZmxvYXQyIHBhcmFtXzIyID0gdV9jZW50ZXJfUzFfYzA7CglmbG9hdCBwYXJhbV8yMyA9IHJhZGl1czsKCWZsb2F0IHBhcmFtXzI0ID0gdV9ibHVyX1MxX2MwOwoJZmxvYXQgd2F2ZV9hbHBoYSA9IChGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChwYXJhbV8yMSwgcGFyYW1fMjIsIHBhcmFtXzIzLCBwYXJhbV8yNCkgKiB1X2FscGhhX1MxX2MwKSAqIHVfY29sb3JfUzFfYzAudzsKCWZsb2F0NCB3YXZlX2NvbG9yID0gZmxvYXQ0KHVfY29sb3JfUzFfYzAueHl6ICogd2F2ZV9hbHBoYSwgd2F2ZV9hbHBoYSk7CglmcmFnQ29sb3JfUzFfYzAgPSBtaXgod2F2ZV9jb2xvciwgZmxvYXQ0KDEuMCksIGZsb2F0NChzcGFya2xlKSk7Cn0KaGFsZjQgcnVudGltZV9zaGFkZXJfUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF8wX2luQ29sb3IgPSBfaW5wdXQ7CglmbG9hdDIgX3RtcF8xX2Nvb3JkcyA9IHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwoJZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzAgPSBmbG9hdDQoX3RtcF8xX2Nvb3JkcywgMC4wLCAwLjApOwoJRkxUX21haW5fUzFfYzAoKTsKCXJldHVybiBoYWxmNChoYWxmNChmcmFnQ29sb3JfUzFfYzApKTsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIHJ1bnRpbWVfc2hhZGVyX1MxX2MwKF9pbnB1dCk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWZsb2F0IGNvdmVyYWdlID0gdmNvdmVyYWdlX1MwOwoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChjb3ZlcmFnZSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBNYXRyaXhFZmZlY3RfUzEob3V0cHV0Q29sb3JfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAAcG9zaXRpb24IAAAAY292ZXJhZ2UFAAAAY29sb3IAAAAKAAAAbG9jYWxDb29yZAAAAAAAAA==","GZIACAAAABQAAGAAAQ4AAAAAGQQAARC4GAAAIOCAAD6P7777777777YDAAAAAAAAAAAJQBBYGQ467YIAAAAAAQAAAAAMACTRNBZN5QYBAAAAAAAAAAAIAA6IAMAAACAAAAAABGABAAAAAEAAAAAIBEABAA":"DAAAAExTS1M7AgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQgY292ZXJhZ2U7CmluIGhhbGY0IGNvbG9yOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdCB2Y292ZXJhZ2VfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDIgcG9zaXRpb24gPSBwb3NpdGlvbi54eTsKCXZjb2xvcl9TMCA9IGNvbG9yOwoJdmNvdmVyYWdlX1MwID0gY292ZXJhZ2U7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgABAAAAtR0AACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQpmbG9hdDQgZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzA7CmZsb2F0NCBmcmFnQ29sb3JfUzFfYzA7CmZsb2F0IHVfYWxwaGFfUzFfYzA7CmZsb2F0IHVfc3BhcmtsZV9hbHBoYV9TMV9jMDsKZmxvYXQgdV9ibHVyX1MxX2MwOwpmbG9hdCB1X3JhZGl1c19zY2FsZV9TMV9jMDsKdW5pZm9ybSBmbG9hdDQgdV9jb2xvcl9TMV9jMDsKdW5pZm9ybSBmbG9hdDQgdV9jb21wb3NpdGVfMV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jZW50ZXJfUzFfYzA7CnVuaWZvcm0gZmxvYXQgdV9tYXhfcmFkaXVzX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3Jlc29sdXRpb25fc2NhbGVfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfbm9pc2Vfc2NhbGVfUzFfYzA7CnVuaWZvcm0gZmxvYXQgdV9ub2lzZV9waGFzZV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jaXJjbGUxX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NpcmNsZTJfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2lyY2xlM19TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yb3RhdGlvbjFfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcm90YXRpb24yX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3JvdGF0aW9uM19TMV9jMDsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxOwp1bmlmb3JtIGZsb2F0NCB1aW5uZXJSZWN0X1MyOwp1bmlmb3JtIGhhbGYyIHVyYWRpdXNQbHVzSGFsZl9TMjsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQgdmNvdmVyYWdlX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKZmxvYXQyIEZMVF9mbHV0dGVyX2xvY2FsX0ZsdXR0ZXJGcmFnQ29vcmRfUzFfYzAoKTsKZmxvYXQyeDIgRkxUX2ZsdXR0ZXJfbG9jYWxfcm90YXRlMmRfUzFfYzAoZmxvYXQyIHJhZCk7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IGJsdXIpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChmbG9hdDIgcmVzb2x1dGlvbiwgaW5vdXQgZmxvYXQyIHAsIGZsb2F0MiB4eSwgZmxvYXQyIHJvdGF0aW9uLCBmbG9hdCBjZWxsX2RpYW1ldGVyKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHVyYnVsZW5jZV9TMV9jMChmbG9hdDIgdXYpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X3JpbmdfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgdGhpY2tuZXNzLCBmbG9hdCBibHVyKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHJpYW5nbGVfbm9pc2VfUzFfYzAoaW5vdXQgZmxvYXQyIG4pOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAoZmxvYXQgdiwgZmxvYXQgbCwgZmxvYXQgaCk7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NwYXJrbGVfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdCB0KTsKdm9pZCBGTFRfbWFpbl9TMV9jMCgpOwpmbG9hdDIgRkxUX2ZsdXR0ZXJfbG9jYWxfRmx1dHRlckZyYWdDb29yZF9TMV9jMCgpIAp7CglyZXR1cm4gZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzAueHk7Cn0KZmxvYXQyeDIgRkxUX2ZsdXR0ZXJfbG9jYWxfcm90YXRlMmRfUzFfYzAoZmxvYXQyIHJhZCkgCnsKCXJldHVybiBmbG9hdDJ4MihyYWQueCwgLXJhZC55LCByYWQueSwgcmFkLngpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IGJsdXIpIAp7CglmbG9hdCBibHVyX2hhbGYgPSBibHVyICogMC41OwoJZmxvYXQgZCA9IGRpc3RhbmNlKHV2LCB4eSk7CglyZXR1cm4gMS4wIC0gc21vb3Roc3RlcCgxLjAgLSBibHVyX2hhbGYsIDEuMCArIGJsdXJfaGFsZiwgZCAvIHJhZGl1cyk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAoZmxvYXQyIHJlc29sdXRpb24sIGlub3V0IGZsb2F0MiBwLCBmbG9hdDIgeHksIGZsb2F0MiByb3RhdGlvbiwgZmxvYXQgY2VsbF9kaWFtZXRlcikgCnsKCWZsb2F0MiBwYXJhbSA9IHJvdGF0aW9uOwoJcCA9IEZMVF9mbHV0dGVyX2xvY2FsX3JvdGF0ZTJkX1MxX2MwKHBhcmFtKSAqICh4eSAtIHApICsgeHk7CglwID0gbW9kKHAsIGZsb2F0MihjZWxsX2RpYW1ldGVyKSkgLyByZXNvbHV0aW9uOwoJZmxvYXQgY2VsbF91diA9IChjZWxsX2RpYW1ldGVyIC8gcmVzb2x1dGlvbi55KSAqIDAuNTsKCWZsb2F0IHIgPSAwLjY1ICogY2VsbF91djsKCWZsb2F0MiBwYXJhbV8xID0gcDsKCWZsb2F0MiBwYXJhbV8yID0gZmxvYXQyKGNlbGxfdXYpOwoJZmxvYXQgcGFyYW1fMyA9IHI7CglmbG9hdCBwYXJhbV80ID0gciAqIDUwLjA7CglyZXR1cm4gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW1fMSwgcGFyYW1fMiwgcGFyYW1fMywgcGFyYW1fNCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHVyYnVsZW5jZV9TMV9jMChmbG9hdDIgdXYpIAp7CglmbG9hdDIgdXZfc2NhbGUgPSB1diAqIGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtID0gZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW1fMSA9IHV2X3NjYWxlOwoJZmxvYXQyIHBhcmFtXzIgPSB1X2NpcmNsZTFfUzFfYzA7CglmbG9hdDIgcGFyYW1fMyA9IHVfcm90YXRpb24xX1MxX2MwOwoJZmxvYXQgcGFyYW1fNCA9IDAuMTc7CglmbG9hdCBfMzE5ID0gRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAocGFyYW0sIHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMsIHBhcmFtXzQpOwoJZmxvYXQgZzEgPSBfMzE5OwoJZmxvYXQyIHBhcmFtXzUgPSBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbV82ID0gdXZfc2NhbGU7CglmbG9hdDIgcGFyYW1fNyA9IHVfY2lyY2xlMl9TMV9jMDsKCWZsb2F0MiBwYXJhbV84ID0gdV9yb3RhdGlvbjJfUzFfYzA7CglmbG9hdCBwYXJhbV85ID0gMC4yOwoJZmxvYXQgXzMzMSA9IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKHBhcmFtXzUsIHBhcmFtXzYsIHBhcmFtXzcsIHBhcmFtXzgsIHBhcmFtXzkpOwoJZmxvYXQgZzIgPSBfMzMxOwoJZmxvYXQyIHBhcmFtXzEwID0gZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW1fMTEgPSB1dl9zY2FsZTsKCWZsb2F0MiBwYXJhbV8xMiA9IHVfY2lyY2xlM19TMV9jMDsKCWZsb2F0MiBwYXJhbV8xMyA9IHVfcm90YXRpb24zX1MxX2MwOwoJZmxvYXQgcGFyYW1fMTQgPSAwLjI3NTsKCWZsb2F0IF8zNDQgPSBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChwYXJhbV8xMCwgcGFyYW1fMTEsIHBhcmFtXzEyLCBwYXJhbV8xMywgcGFyYW1fMTQpOwoJZmxvYXQgZzMgPSBfMzQ0OwoJZmxvYXQgdiA9ICgoZzEgKiBnMSArIGcyKSAtIGczKSAqIDAuNTsKCXJldHVybiBjbGFtcCgwLjQ1ICsgMC44ICogdiwgMC4wLCAxLjApOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfcmluZ19TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCB0aGlja25lc3MsIGZsb2F0IGJsdXIpIAp7CglmbG9hdDIgcGFyYW0gPSB1djsKCWZsb2F0MiBwYXJhbV8xID0geHk7CglmbG9hdCBwYXJhbV8yID0gcmFkaXVzICsgdGhpY2tuZXNzOwoJZmxvYXQgcGFyYW1fMyA9IGJsdXI7CglmbG9hdCBjaXJjbGVfb3V0ZXIgPSBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChwYXJhbSwgcGFyYW1fMSwgcGFyYW1fMiwgcGFyYW1fMyk7CglmbG9hdDIgcGFyYW1fNCA9IHV2OwoJZmxvYXQyIHBhcmFtXzUgPSB4eTsKCWZsb2F0IHBhcmFtXzYgPSBtYXgocmFkaXVzIC0gdGhpY2tuZXNzLCAwLjApOwoJZmxvYXQgcGFyYW1fNyA9IGJsdXI7CglmbG9hdCBjaXJjbGVfaW5uZXIgPSBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChwYXJhbV80LCBwYXJhbV81LCBwYXJhbV82LCBwYXJhbV83KTsKCXJldHVybiBjbGFtcChjaXJjbGVfb3V0ZXIgLSBjaXJjbGVfaW5uZXIsIDAuMCwgMS4wKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90cmlhbmdsZV9ub2lzZV9TMV9jMChpbm91dCBmbG9hdDIgbikgCnsKCW4gPSBmcmFjdChuICogZmxvYXQyKDUuMzk4NywgNS40NDIxKSk7CgluICs9IGZsb2F0Mihkb3Qobi55eCwgbiArIGZsb2F0MigyMS41MzUxLCAxNC4zMTM3KSkpOwoJZmxvYXQgeHkgPSBuLnggKiBuLnk7CglyZXR1cm4gKGZyYWN0KHh5ICogOTUuNDMwNykgKyBmcmFjdCh4eSAqIDc1LjA0OTYxKSkgLSAxLjA7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKGZsb2F0IHYsIGZsb2F0IGwsIGZsb2F0IGgpIAp7CglyZXR1cm4gc3RlcChsLCB2KSAqICgxLjAgLSBzdGVwKGgsIHYpKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zcGFya2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQgdCkgCnsKCWZsb2F0MiBwYXJhbSA9IHV2OwoJZmxvYXQgXzI0MiA9IEZMVF9mbHV0dGVyX2xvY2FsX3RyaWFuZ2xlX25vaXNlX1MxX2MwKHBhcmFtKTsKCWZsb2F0IG4gPSBfMjQyOwoJZmxvYXQgcGFyYW1fMSA9IG47CglmbG9hdCBwYXJhbV8yID0gMC4wOwoJZmxvYXQgcGFyYW1fMyA9IDAuMDU7CglmbG9hdCBzID0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMpOwoJZmxvYXQgcGFyYW1fNCA9IG4gKyBzaW4oMy4xNDE1OTI3NCAqICh0ICsgMC4zNSkpOwoJZmxvYXQgcGFyYW1fNSA9IDAuMTsKCWZsb2F0IHBhcmFtXzYgPSAwLjE1OwoJcyArPSBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAocGFyYW1fNCwgcGFyYW1fNSwgcGFyYW1fNik7CglmbG9hdCBwYXJhbV83ID0gbiArIHNpbigzLjE0MTU5Mjc0ICogKHQgKyAwLjcpKTsKCWZsb2F0IHBhcmFtXzggPSAwLjI7CglmbG9hdCBwYXJhbV85ID0gMC4yNTsKCXMgKz0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzcsIHBhcmFtXzgsIHBhcmFtXzkpOwoJZmxvYXQgcGFyYW1fMTAgPSBuICsgc2luKDMuMTQxNTkyNzQgKiAodCArIDEuMDUpKTsKCWZsb2F0IHBhcmFtXzExID0gMC4zOwoJZmxvYXQgcGFyYW1fMTIgPSAwLjM1OwoJcyArPSBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAocGFyYW1fMTAsIHBhcmFtXzExLCBwYXJhbV8xMik7CglyZXR1cm4gY2xhbXAocywgMC4wLCAxLjApICogMC41NTsKfQp2b2lkIEZMVF9tYWluX1MxX2MwKCkgCnsKCXVfYWxwaGFfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLng7Cgl1X3NwYXJrbGVfYWxwaGFfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLnk7Cgl1X2JsdXJfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLno7Cgl1X3JhZGl1c19zY2FsZV9TMV9jMCA9IHVfY29tcG9zaXRlXzFfUzFfYzAudzsKCWZsb2F0MiBwID0gRkxUX2ZsdXR0ZXJfbG9jYWxfRmx1dHRlckZyYWdDb29yZF9TMV9jMCgpOwoJZmxvYXQyIHV2XzEgPSBwICogdV9yZXNvbHV0aW9uX3NjYWxlX1MxX2MwOwoJZmxvYXQyIGRlbnNpdHlfdXYgPSB1dl8xIC0gbW9kKHAsIHVfbm9pc2Vfc2NhbGVfUzFfYzApOwoJZmxvYXQgcmFkaXVzID0gdV9tYXhfcmFkaXVzX1MxX2MwICogdV9yYWRpdXNfc2NhbGVfUzFfYzA7CglmbG9hdDIgcGFyYW1fMTMgPSB1dl8xOwoJZmxvYXQgdHVyYnVsZW5jZSA9IEZMVF9mbHV0dGVyX2xvY2FsX3R1cmJ1bGVuY2VfUzFfYzAocGFyYW1fMTMpOwoJZmxvYXQyIHBhcmFtXzE0ID0gcDsKCWZsb2F0MiBwYXJhbV8xNSA9IHVfY2VudGVyX1MxX2MwOwoJZmxvYXQgcGFyYW1fMTYgPSByYWRpdXM7CglmbG9hdCBwYXJhbV8xNyA9IDAuMDUgKiB1X21heF9yYWRpdXNfUzFfYzA7CglmbG9hdCBwYXJhbV8xOCA9IHVfYmx1cl9TMV9jMDsKCWZsb2F0IHJpbmcgPSBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X3JpbmdfUzFfYzAocGFyYW1fMTQsIHBhcmFtXzE1LCBwYXJhbV8xNiwgcGFyYW1fMTcsIHBhcmFtXzE4KTsKCWZsb2F0MiBwYXJhbV8xOSA9IGRlbnNpdHlfdXY7CglmbG9hdCBwYXJhbV8yMCA9IHVfbm9pc2VfcGhhc2VfUzFfYzA7CglmbG9hdCBzcGFya2xlID0gKChGTFRfZmx1dHRlcl9sb2NhbF9zcGFya2xlX1MxX2MwKHBhcmFtXzE5LCBwYXJhbV8yMCkgKiByaW5nKSAqIHR1cmJ1bGVuY2UpICogdV9zcGFya2xlX2FscGhhX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzIxID0gcDsKCWZsb2F0MiBwYXJhbV8yMiA9IHVfY2VudGVyX1MxX2MwOwoJZmxvYXQgcGFyYW1fMjMgPSByYWRpdXM7CglmbG9hdCBwYXJhbV8yNCA9IHVfYmx1cl9TMV9jMDsKCWZsb2F0IHdhdmVfYWxwaGEgPSAoRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW1fMjEsIHBhcmFtXzIyLCBwYXJhbV8yMywgcGFyYW1fMjQpICogdV9hbHBoYV9TMV9jMCkgKiB1X2NvbG9yX1MxX2MwLnc7CglmbG9hdDQgd2F2ZV9jb2xvciA9IGZsb2F0NCh1X2NvbG9yX1MxX2MwLnh5eiAqIHdhdmVfYWxwaGEsIHdhdmVfYWxwaGEpOwoJZnJhZ0NvbG9yX1MxX2MwID0gbWl4KHdhdmVfY29sb3IsIGZsb2F0NCgxLjApLCBmbG9hdDQoc3BhcmtsZSkpOwp9CmhhbGY0IHJ1bnRpbWVfc2hhZGVyX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJZmxvYXQyIF90bXBfMV9jb29yZHMgPSB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKCWZsdXR0ZXJfRnJhZ0Nvb3JkX1MxX2MwID0gZmxvYXQ0KF90bXBfMV9jb29yZHMsIDAuMCwgMC4wKTsKCUZMVF9tYWluX1MxX2MwKCk7CglyZXR1cm4gaGFsZjQoaGFsZjQoZnJhZ0NvbG9yX1MxX2MwKSk7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBydW50aW1lX3NoYWRlcl9TMV9jMChfaW5wdXQpOwp9CmhhbGY0IENpcmN1bGFyUlJlY3RfUzIoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MyLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MyLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CgloYWxmIGFscGhhID0gaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzIueCAtIGxlbmd0aChkeHkpKSk7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWZsb2F0IGNvdmVyYWdlID0gdmNvdmVyYWdlX1MwOwoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChjb3ZlcmFnZSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBNYXRyaXhFZmZlY3RfUzEob3V0cHV0Q29sb3JfUzApOwoJaGFsZjQgb3V0cHV0X1MyOwoJb3V0cHV0X1MyID0gQ2lyY3VsYXJSUmVjdF9TMihvdXRwdXRDb3ZlcmFnZV9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0X1MxICogb3V0cHV0X1MyOwoJfQp9CgAAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAHBvc2l0aW9uCAAAAGNvdmVyYWdlBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","GYQAAAAAAAMAADAAAIOAAAH677776IZOCAAP577777777777777777YBAAAAAAAAAAADAAYAAAACAAAAAAACCAYAAA":"DAAAAExTS1MaAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgcG9zaXRpb247CmluIGhhbGY0IGNvbG9yOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2Y29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAAVwEAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQpub3BlcnNwZWN0aXZlIGluIGhhbGY0IHZjb2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAIAAAAcG9zaXRpb24FAAAAY29sb3IAAAAAAAAA","GYQACAAAAAMAADAAAIOAAAH677776IZOCAAP577777777777777777YBAAAAAAAAAAADAAYAAAACAAAAAAACCAYAAA":"DAAAAExTS1MaAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgcG9zaXRpb247CmluIGhhbGY0IGNvbG9yOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2Y29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAAVwEAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQpub3BlcnNwZWN0aXZlIGluIGhhbGY0IHZjb2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAIAAAAcG9zaXRpb24FAAAAY29sb3IAAAAAAAAA","BYIBQAAABQAAIAABBYAAAEIXBAAP777777777777AAAAAAAAAAAABGABAAAAAEAAAAAIBEABAAAAA":"DAAAAExTS1OJAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgaW5Qb3NpdGlvbjsKaW4gaGFsZjQgaW5Db2xvcjsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBEZWZhdWx0R2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IGNvbG9yID0gaW5Db2xvcjsKCXZjb2xvcl9TMCA9IGNvbG9yOwoJZmxvYXQyIF90bXBfMV9pblBvc2l0aW9uID0gaW5Qb3NpdGlvbjsKCWZsb2F0MiBfdG1wXzNfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247Cglza19Qb3NpdGlvbiA9IF90bXBfMV9pblBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAAAFEBAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2Y29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBEZWZhdWx0R2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IAAAAAAA==","GZIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAHIBIA5HZ2CAAAAAAAEAQCAAAAASBEEAQAAAAAUCCQAQQGAABAEAAAAAAGMAAAAAAAIAAAAAQGIAAAAAAA":"DAAAAExTS1POAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzA7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfM19TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzFfYzApICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAAAAcwQAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQp1bmlmb3JtIGZsb2F0NCB1Y2xhbXBfUzFfYzBfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMDsKc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MxOwpub3BlcnNwZWN0aXZlIGluIGhhbGY0IHZjb2xvcl9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzNfUzA7CmhhbGY0IFRleHR1cmVFZmZlY3RfUzFfYzBfYzAoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGluQ29vcmQgPSB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKCWZsb2F0MiBzdWJzZXRDb29yZDsKCXN1YnNldENvb3JkLnggPSBpbkNvb3JkLng7CglzdWJzZXRDb29yZC55ID0gaW5Db29yZC55OwoJZmxvYXQyIGNsYW1wZWRDb29yZDsKCWNsYW1wZWRDb29yZCA9IGNsYW1wKHN1YnNldENvb3JkLCB1Y2xhbXBfUzFfYzBfYzAueHksIHVjbGFtcF9TMV9jMF9jMC56dyk7CgloYWxmNCB0ZXh0dXJlQ29sb3IgPSBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzEsIGNsYW1wZWRDb29yZCk7CglyZXR1cm4gdGV4dHVyZUNvbG9yOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gVGV4dHVyZUVmZmVjdF9TMV9jMF9jMChfaW5wdXQpOwp9CmhhbGY0IERpc2FibGVDb3ZlcmFnZUFzQWxwaGFfUzEoaGFsZjQgX2lucHV0KSAKewoJX2lucHV0ID0gTWF0cml4RWZmZWN0X1MxX2MwKF9pbnB1dCk7CgloYWxmNCBfdG1wXzBfaW5Db2xvciA9IF9pbnB1dDsKCXJldHVybiBoYWxmNChfaW5wdXQpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gRGlzYWJsZUNvdmVyYWdlQXNBbHBoYV9TMShvdXRwdXRDb2xvcl9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0X1MxICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","GZIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAHIBIA5HZ2CAAAAAAAAAACAAAAASAEAAQAAAAAUCCQAQQGAAAAAAAAAAAGMAAAAAAAIAAAAAQGIAAAAAAA":"DAAAAExTS1POAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzA7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfM19TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzFfYzApICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAAAAYAMAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzA7CnNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMTsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc18zX1MwOwpoYWxmNCBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzEsIHZUcmFuc2Zvcm1lZENvb3Jkc18zX1MwKTsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzBfYzAoX2lucHV0KTsKfQpoYWxmNCBEaXNhYmxlQ292ZXJhZ2VBc0FscGhhX1MxKGhhbGY0IF9pbnB1dCkgCnsKCV9pbnB1dCA9IE1hdHJpeEVmZmVjdF9TMV9jMChfaW5wdXQpOwoJaGFsZjQgX3RtcF8wX2luQ29sb3IgPSBfaW5wdXQ7CglyZXR1cm4gaGFsZjQoX2lucHV0KTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IERpc2FibGVDb3ZlcmFnZUFzQWxwaGFfUzEob3V0cHV0Q29sb3JfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","GZIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAJIBAGMVUOTUABAAAAAAAIAAAAAWFBIEMVUOTUAAAAAAAAAIAAAACICAACAAAAACQIKACCAYAAAAAAAAAAAZQAAAAAABAAAAACAZAAAAAAA":"DAAAAExTS1PIAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfMl9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzEpICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAKkFAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKY29uc3QgaW50IGtNYXhMb29wTGltaXRfUzFfYzAgPSA4Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzBfYzA7CnVuaWZvcm0gaGFsZjQgdW9mZnNldHNBbmRLZXJuZWxfUzFfYzBbMTRdOwp1bmlmb3JtIGhhbGYyIHVkaXJfUzFfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MxOwpub3BlcnNwZWN0aXZlIGluIGhhbGY0IHZjb2xvcl9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CmhhbGY0IFRleHR1cmVFZmZlY3RfUzFfYzBfYzBfYzAoaGFsZjQgX2lucHV0LCBmbG9hdDIgX2Nvb3JkcykgCnsKCXJldHVybiBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzEsIF9jb29yZHMpOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMV9jMF9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzBfYzBfYzAoX2lucHV0LCBmbG9hdDN4Mih1bWF0cml4X1MxX2MwX2MwKSAqIF9jb29yZHMueHkxKTsKfQpoYWxmNCBydW50aW1lX3NoYWRlcl9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzBfaW5Db2xvciA9IF9pbnB1dDsKCWZsb2F0MiBfdG1wXzFfY29vcmRzID0gdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CgloYWxmNCBzdW0gPSBoYWxmNCgwLjApOwoJZm9yIChpbnQgaSA9IDA7aSA8IGtNYXhMb29wTGltaXRfUzFfYzA7ICsraSkgCgl7CgkJaGFsZjQgcyA9IHVvZmZzZXRzQW5kS2VybmVsX1MxX2MwW2ldOwoJCXN1bSArPSBzLnkgKiBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoX3RtcF8wX2luQ29sb3IsIF90bXBfMV9jb29yZHMgKyBmbG9hdDIocy54ICogdWRpcl9TMV9jMCkpOwoJCXN1bSArPSBzLncgKiBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoX3RtcF8wX2luQ29sb3IsIF90bXBfMV9jb29yZHMgKyBmbG9hdDIocy56ICogdWRpcl9TMV9jMCkpOwoJfQoJcmV0dXJuIGhhbGY0KHN1bSk7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBydW50aW1lX3NoYWRlcl9TMV9jMChfaW5wdXQpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gTWF0cml4RWZmZWN0X1MxKG91dHB1dENvbG9yX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRfUzEgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAgAAABwb3NpdGlvbgUAAABjb2xvcgAAAAoAAABsb2NhbENvb3JkAAAAAAAA","GZIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAJIBAGMVUOTUABAAAAQCAIAAAAAWFBIEMVUOTUAAAAAAQCAIAAAACIGAQCAAAAACQIKACCAYAAEAQAAAAAAZQAAAAAABAAAAACAZAAAAAAA":"DAAAAExTS1PIAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfMl9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzEpICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAMUGAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKY29uc3QgaW50IGtNYXhMb29wTGltaXRfUzFfYzAgPSA4Owp1bmlmb3JtIGZsb2F0NCB1Y2xhbXBfUzFfYzBfYzBfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMDsKdW5pZm9ybSBoYWxmNCB1b2Zmc2V0c0FuZEtlcm5lbF9TMV9jMFsxNF07CnVuaWZvcm0gaGFsZjIgdWRpcl9TMV9jMDsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7Cm5vcGVyc3BlY3RpdmUgaW4gaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMF9jMF9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJZmxvYXQyIGluQ29vcmQgPSBfY29vcmRzOwoJZmxvYXQyIHN1YnNldENvb3JkOwoJc3Vic2V0Q29vcmQueCA9IGluQ29vcmQueDsKCXN1YnNldENvb3JkLnkgPSBpbkNvb3JkLnk7CglmbG9hdDIgY2xhbXBlZENvb3JkOwoJY2xhbXBlZENvb3JkID0gY2xhbXAoc3Vic2V0Q29vcmQsIHVjbGFtcF9TMV9jMF9jMF9jMC54eSwgdWNsYW1wX1MxX2MwX2MwX2MwLnp3KTsKCWhhbGY0IHRleHR1cmVDb2xvciA9IHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMSwgY2xhbXBlZENvb3JkKTsKCXJldHVybiB0ZXh0dXJlQ29sb3I7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxX2MwX2MwKGhhbGY0IF9pbnB1dCwgZmxvYXQyIF9jb29yZHMpIAp7CglyZXR1cm4gVGV4dHVyZUVmZmVjdF9TMV9jMF9jMF9jMChfaW5wdXQsIGZsb2F0M3gyKHVtYXRyaXhfUzFfYzBfYzApICogX2Nvb3Jkcy54eTEpOwp9CmhhbGY0IHJ1bnRpbWVfc2hhZGVyX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJZmxvYXQyIF90bXBfMV9jb29yZHMgPSB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKCWhhbGY0IHN1bSA9IGhhbGY0KDAuMCk7Cglmb3IgKGludCBpID0gMDtpIDwga01heExvb3BMaW1pdF9TMV9jMDsgKytpKSAKCXsKCQloYWxmNCBzID0gdW9mZnNldHNBbmRLZXJuZWxfUzFfYzBbaV07CgkJc3VtICs9IHMueSAqIE1hdHJpeEVmZmVjdF9TMV9jMF9jMChfdG1wXzBfaW5Db2xvciwgX3RtcF8xX2Nvb3JkcyArIGZsb2F0MihzLnggKiB1ZGlyX1MxX2MwKSk7CgkJc3VtICs9IHMudyAqIE1hdHJpeEVmZmVjdF9TMV9jMF9jMChfdG1wXzBfaW5Db2xvciwgX3RtcF8xX2Nvb3JkcyArIGZsb2F0MihzLnogKiB1ZGlyX1MxX2MwKSk7Cgl9CglyZXR1cm4gaGFsZjQoc3VtKTsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIHJ1bnRpbWVfc2hhZGVyX1MxX2MwKF9pbnB1dCk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBNYXRyaXhFZmZlY3RfUzEob3V0cHV0Q29sb3JfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","G2JAAAAAAAUAADAAAIOAAAAADIIAB7X7777QGHAYAD7P7777777777YBAAAAAAQAAAAAAQQGAAYAGAAAAAQAAAAAAAQQGAAA":"DAAAAExTS1OjAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgcG9zaXRpb247CmluIGZsb2F0IGNvdmVyYWdlOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQyIHZsb2NhbENvb3JkX1MwOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdCB2Y292ZXJhZ2VfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQyIHBvc2l0aW9uID0gcG9zaXRpb24ueHk7Cgl2bG9jYWxDb29yZF9TMCA9IGxvY2FsQ29vcmQ7Cgl2Y292ZXJhZ2VfUzAgPSBjb3ZlcmFnZTsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKfQoAAAAAADUCAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2bG9jYWxDb29yZF9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdCB2Y292ZXJhZ2VfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwID0gaGFsZjQoMSk7CglmbG9hdDIgdGV4Q29vcmQ7Cgl0ZXhDb29yZCA9IHZsb2NhbENvb3JkX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSAoYmxlbmRfbW9kdWxhdGUoc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB0ZXhDb29yZCksIGhhbGY0KDEpKSk7CglmbG9hdCBjb3ZlcmFnZSA9IHZjb3ZlcmFnZV9TMDsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoY292ZXJhZ2UpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAIAAAAcG9zaXRpb24IAAAAY292ZXJhZ2UKAAAAbG9jYWxDb29yZAAAAAAAAA==","GXQAAGAABBYAAAEIXBAAAGEAMAAAAAAAAAAAAAAAYAGAAAAAQAAAAAAAQQGAAAAA":"DAAAAExTS1OYAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgaW5Qb3NpdGlvbjsKaW4gaGFsZjQgaW5Db2xvcjsKaW4gZmxvYXQ0IGluUXVhZEVkZ2U7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0NCB2UXVhZEVkZ2VfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBRdWFkRWRnZQoJdlF1YWRFZGdlX1MwID0gaW5RdWFkRWRnZTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247Cglza19Qb3NpdGlvbiA9IF90bXBfMF9pblBvc2l0aW9uLnh5MDE7Cn0KBAAAAF4DAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdDQgdlF1YWRFZGdlX1MwOwpub3BlcnNwZWN0aXZlIGluIGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZEVkZ2UKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWhhbGYgZWRnZUFscGhhOwoJaGFsZjIgZHV2ZHggPSBoYWxmMihkRmR4KHZRdWFkRWRnZV9TMC54eSkpOwoJaGFsZjIgZHV2ZHkgPSBoYWxmMihkRmR5KHZRdWFkRWRnZV9TMC54eSkpOwoJaWYgKHZRdWFkRWRnZV9TMC56ID4gMC4wICYmIHZRdWFkRWRnZV9TMC53ID4gMC4wKSAKCXsKCQllZGdlQWxwaGEgPSBoYWxmKG1pbihtaW4odlF1YWRFZGdlX1MwLnosIHZRdWFkRWRnZV9TMC53KSArIDAuNSwgMS4wKSk7Cgl9CgllbHNlIAoJewoJCWhhbGYyIGdGID0gaGFsZjIoaGFsZigyLjAqdlF1YWRFZGdlX1MwLngqZHV2ZHgueCAtIGR1dmR4LnkpLCAgICAgICAgICAgICAgICAgaGFsZigyLjAqdlF1YWRFZGdlX1MwLngqZHV2ZHkueCAtIGR1dmR5LnkpKTsKCQllZGdlQWxwaGEgPSBoYWxmKHZRdWFkRWRnZV9TMC54KnZRdWFkRWRnZV9TMC54IC0gdlF1YWRFZGdlX1MwLnkpOwoJCWVkZ2VBbHBoYSA9IHNhdHVyYXRlKDAuNSAtIGVkZ2VBbHBoYSAvIGxlbmd0aChnRikpOwoJfQoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChlZGdlQWxwaGEpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAEAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAoAAABpblBvc2l0aW9uAAAHAAAAaW5Db2xvcgAKAAAAaW5RdWFkRWRnZQAAAAAAAA==","GYJAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAQAAAAAAQQGABZAA6IAAAAACAAAAAADGAAAAAAAEAAAAAIDEAAAAAAA":"DAAAAExTS1MwAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgcG9zaXRpb247CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmxvY2FsQ29vcmRfUzAgPSBsb2NhbENvb3JkOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgEAAAB+AwAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHVpbm5lclJlY3RfUzE7CnVuaWZvcm0gaGFsZjIgdXJhZGl1c1BsdXNIYWxmX1MxOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQyIHZsb2NhbENvb3JkX1MwOwpoYWxmNCBDaXJjdWxhclJSZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCWZsb2F0MiBkeHkwID0gdWlubmVyUmVjdF9TMS5MVCAtIHNrX0ZyYWdDb29yZC54eTsKCWZsb2F0MiBkeHkxID0gc2tfRnJhZ0Nvb3JkLnh5IC0gdWlubmVyUmVjdF9TMS5SQjsKCWZsb2F0MiBkeHkgPSBtYXgobWF4KGR4eTAsIGR4eTEpLCAwLjApOwoJaGFsZiBhbHBoYSA9IGhhbGYoc2F0dXJhdGUodXJhZGl1c1BsdXNIYWxmX1MxLnggLSBsZW5ndGgoZHh5KSkpOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwID0gaGFsZjQoMSk7CglmbG9hdDIgdGV4Q29vcmQ7Cgl0ZXhDb29yZCA9IHZsb2NhbENvb3JkX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSAoYmxlbmRfbW9kdWxhdGUoc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB0ZXhDb29yZCksIGhhbGY0KDEpKSk7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQ2lyY3VsYXJSUmVjdF9TMShvdXRwdXRDb3ZlcmFnZV9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAAABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgoAAABsb2NhbENvb3JkAAAAAAAA","FIMAAAYAAEHAAAARC4EAAAQWBQAAAAAAAAAQAAAAIBCAAAEYAEAAAAAQAAAABAEQAEAAAAA":"DAAAAExTS1OtAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgaW5Qb3NpdGlvbjsKaW4gaGFsZjQgaW5Db2xvcjsKaW4gaGFsZjMgaW5TaGFkb3dQYXJhbXM7Cm5vcGVyc3BlY3RpdmUgb3V0IGhhbGYzIHZpblNoYWRvd1BhcmFtc19TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFJSZWN0U2hhZG93Cgl2aW5TaGFkb3dQYXJhbXNfUzAgPSBpblNoYWRvd1BhcmFtczsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247Cglza19Qb3NpdGlvbiA9IF90bXBfMF9pblBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAAAFwCAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwpub3BlcnNwZWN0aXZlIGluIGhhbGYzIHZpblNoYWRvd1BhcmFtc19TMDsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFJSZWN0U2hhZG93CgloYWxmMyBzaGFkb3dQYXJhbXM7CglzaGFkb3dQYXJhbXMgPSB2aW5TaGFkb3dQYXJhbXNfUzA7CgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmluQ29sb3JfUzA7CgloYWxmIGQgPSBsZW5ndGgoc2hhZG93UGFyYW1zLnh5KTsKCWZsb2F0MiB1diA9IGZsb2F0MihzaGFkb3dQYXJhbXMueiAqICgxLjAgLSBkKSwgMC41KTsKCWhhbGYgZmFjdG9yID0gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB1dikuMDAwci5hOwoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChmYWN0b3IpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADgAAAGluU2hhZG93UGFyYW1zAAAAAAAA","GYJBYAQCAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAQAAAAAAQQGAAYAGAAAAAQAAAAAAAQQGAAA":"DAAAAExTS1MwAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgcG9zaXRpb247CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmxvY2FsQ29vcmRfUzAgPSBsb2NhbENvb3JkOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAAA1BgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQgdVNyY1RGX1MwWzddOwp1bmlmb3JtIGZsb2F0M3gzIHVDb2xvclhmb3JtX1MwOwp1bmlmb3JtIGZsb2F0IHVEc3RURl9TMFs3XTsKc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2bG9jYWxDb29yZF9TMDsKZmxvYXQgc3JjX3RmX1MwKGZsb2F0IHgpIAp7CglmbG9hdCBHID0gdVNyY1RGX1MwWzBdOwoJZmxvYXQgQSA9IHVTcmNURl9TMFsxXTsKCWZsb2F0IEIgPSB1U3JjVEZfUzBbMl07CglmbG9hdCBDID0gdVNyY1RGX1MwWzNdOwoJZmxvYXQgRCA9IHVTcmNURl9TMFs0XTsKCWZsb2F0IEUgPSB1U3JjVEZfUzBbNV07CglmbG9hdCBGID0gdVNyY1RGX1MwWzZdOwoJZmxvYXQgcyA9IHNpZ24oeCk7Cgl4ID0gYWJzKHgpOwoJeCA9ICh4IDwgRCkgPyAoQyAqIHgpICsgRiA6IHBvdyhBICogeCArIEIsIEcpICsgRTsKCXJldHVybiBzICogeDsKfQpmbG9hdCBkc3RfdGZfUzAoZmxvYXQgeCkgCnsKCWZsb2F0IEcgPSB1RHN0VEZfUzBbMF07CglmbG9hdCBBID0gdURzdFRGX1MwWzFdOwoJZmxvYXQgQiA9IHVEc3RURl9TMFsyXTsKCWZsb2F0IEMgPSB1RHN0VEZfUzBbM107CglmbG9hdCBEID0gdURzdFRGX1MwWzRdOwoJZmxvYXQgRSA9IHVEc3RURl9TMFs1XTsKCWZsb2F0IEYgPSB1RHN0VEZfUzBbNl07CglmbG9hdCBzID0gc2lnbih4KTsKCXggPSBhYnMoeCk7Cgl4ID0gKHggPCBEKSA/IChDICogeCkgKyBGIDogcG93KEEgKiB4ICsgQiwgRykgKyBFOwoJcmV0dXJuIHMgKiB4Owp9CmZsb2F0NCBnYW11dF94Zm9ybV9TMChmbG9hdDQgY29sb3IpIAp7Cgljb2xvci5yZ2IgPSAodUNvbG9yWGZvcm1fUzAgKiBjb2xvci5yZ2IpOwoJcmV0dXJuIGNvbG9yOwp9CmhhbGY0IGNvbG9yX3hmb3JtX1MwKGZsb2F0NCBjb2xvcikgCnsKCWNvbG9yLnIgPSBzcmNfdGZfUzAoY29sb3Iucik7Cgljb2xvci5nID0gc3JjX3RmX1MwKGNvbG9yLmcpOwoJY29sb3IuYiA9IHNyY190Zl9TMChjb2xvci5iKTsKCWNvbG9yID0gZ2FtdXRfeGZvcm1fUzAoY29sb3IpOwoJY29sb3IuciA9IGRzdF90Zl9TMChjb2xvci5yKTsKCWNvbG9yLmcgPSBkc3RfdGZfUzAoY29sb3IuZyk7Cgljb2xvci5iID0gZHN0X3RmX1MwKGNvbG9yLmIpOwoJcmV0dXJuIGhhbGY0KGNvbG9yKTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMCA9IGhhbGY0KDEpOwoJZmxvYXQyIHRleENvb3JkOwoJdGV4Q29vcmQgPSB2bG9jYWxDb29yZF9TMDsKCW91dHB1dENvbG9yX1MwID0gKGJsZW5kX21vZHVsYXRlKGNvbG9yX3hmb3JtX1MwKHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMCwgdGV4Q29vcmQpKSwgaGFsZjQoMSkpKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgoAAABsb2NhbENvb3JkAAAAAAAA","GZIACAAAABQAAGAAAQ4AAAAAGQQAARC4GAAAIOCAAD6P7777777777YDAAAAAAAAAAAJQBBYGQ467YIAAAAAAQAAAAAMACTRNBZN5QYBAAAAAAAAAAAIAALIAAAAAGFM37JKEAAAAAMAAAAAIAAAAAAAMBCQN25XWQUAAAAAAYAAAAAAAAAABGABAAAAAEAAAAAIBEABAAAAA":"DAAAAExTS1M7AgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQgY292ZXJhZ2U7CmluIGhhbGY0IGNvbG9yOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdCB2Y292ZXJhZ2VfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDIgcG9zaXRpb24gPSBwb3NpdGlvbi54eTsKCXZjb2xvcl9TMCA9IGNvbG9yOwoJdmNvdmVyYWdlX1MwID0gY292ZXJhZ2U7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgABAAAAKh8AACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQpmbG9hdDQgZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzA7CmZsb2F0NCBmcmFnQ29sb3JfUzFfYzA7CmZsb2F0IHVfYWxwaGFfUzFfYzA7CmZsb2F0IHVfc3BhcmtsZV9hbHBoYV9TMV9jMDsKZmxvYXQgdV9ibHVyX1MxX2MwOwpmbG9hdCB1X3JhZGl1c19zY2FsZV9TMV9jMDsKY29uc3QgaW50IGtGaWxsQUFfUzJfYzAgPSAxOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQldfUzJfYzAgPSAyOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQUFfUzJfYzAgPSAzOwp1bmlmb3JtIGZsb2F0NCB1X2NvbG9yX1MxX2MwOwp1bmlmb3JtIGZsb2F0NCB1X2NvbXBvc2l0ZV8xX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NlbnRlcl9TMV9jMDsKdW5pZm9ybSBmbG9hdCB1X21heF9yYWRpdXNfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcmVzb2x1dGlvbl9zY2FsZV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9ub2lzZV9zY2FsZV9TMV9jMDsKdW5pZm9ybSBmbG9hdCB1X25vaXNlX3BoYXNlX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NpcmNsZTFfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2lyY2xlMl9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jaXJjbGUzX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3JvdGF0aW9uMV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yb3RhdGlvbjJfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcm90YXRpb24zX1MxX2MwOwp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CnVuaWZvcm0gZmxvYXQ0IHVjaXJjbGVfUzJfYzA7Cm5vcGVyc3BlY3RpdmUgaW4gaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0IHZjb3ZlcmFnZV9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CmZsb2F0MiBGTFRfZmx1dHRlcl9sb2NhbF9GbHV0dGVyRnJhZ0Nvb3JkX1MxX2MwKCk7CmZsb2F0MngyIEZMVF9mbHV0dGVyX2xvY2FsX3JvdGF0ZTJkX1MxX2MwKGZsb2F0MiByYWQpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCBibHVyKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAoZmxvYXQyIHJlc29sdXRpb24sIGlub3V0IGZsb2F0MiBwLCBmbG9hdDIgeHksIGZsb2F0MiByb3RhdGlvbiwgZmxvYXQgY2VsbF9kaWFtZXRlcik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3R1cmJ1bGVuY2VfUzFfYzAoZmxvYXQyIHV2KTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9yaW5nX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IHRoaWNrbmVzcywgZmxvYXQgYmx1cik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RyaWFuZ2xlX25vaXNlX1MxX2MwKGlub3V0IGZsb2F0MiBuKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKGZsb2F0IHYsIGZsb2F0IGwsIGZsb2F0IGgpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zcGFya2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQgdCk7CnZvaWQgRkxUX21haW5fUzFfYzAoKTsKZmxvYXQyIEZMVF9mbHV0dGVyX2xvY2FsX0ZsdXR0ZXJGcmFnQ29vcmRfUzFfYzAoKSAKewoJcmV0dXJuIGZsdXR0ZXJfRnJhZ0Nvb3JkX1MxX2MwLnh5Owp9CmZsb2F0MngyIEZMVF9mbHV0dGVyX2xvY2FsX3JvdGF0ZTJkX1MxX2MwKGZsb2F0MiByYWQpIAp7CglyZXR1cm4gZmxvYXQyeDIocmFkLngsIC1yYWQueSwgcmFkLnksIHJhZC54KTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCBibHVyKSAKewoJZmxvYXQgYmx1cl9oYWxmID0gYmx1ciAqIDAuNTsKCWZsb2F0IGQgPSBkaXN0YW5jZSh1diwgeHkpOwoJcmV0dXJuIDEuMCAtIHNtb290aHN0ZXAoMS4wIC0gYmx1cl9oYWxmLCAxLjAgKyBibHVyX2hhbGYsIGQgLyByYWRpdXMpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKGZsb2F0MiByZXNvbHV0aW9uLCBpbm91dCBmbG9hdDIgcCwgZmxvYXQyIHh5LCBmbG9hdDIgcm90YXRpb24sIGZsb2F0IGNlbGxfZGlhbWV0ZXIpIAp7CglmbG9hdDIgcGFyYW0gPSByb3RhdGlvbjsKCXAgPSBGTFRfZmx1dHRlcl9sb2NhbF9yb3RhdGUyZF9TMV9jMChwYXJhbSkgKiAoeHkgLSBwKSArIHh5OwoJcCA9IG1vZChwLCBmbG9hdDIoY2VsbF9kaWFtZXRlcikpIC8gcmVzb2x1dGlvbjsKCWZsb2F0IGNlbGxfdXYgPSAoY2VsbF9kaWFtZXRlciAvIHJlc29sdXRpb24ueSkgKiAwLjU7CglmbG9hdCByID0gMC42NSAqIGNlbGxfdXY7CglmbG9hdDIgcGFyYW1fMSA9IHA7CglmbG9hdDIgcGFyYW1fMiA9IGZsb2F0MihjZWxsX3V2KTsKCWZsb2F0IHBhcmFtXzMgPSByOwoJZmxvYXQgcGFyYW1fNCA9IHIgKiA1MC4wOwoJcmV0dXJuIEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMsIHBhcmFtXzQpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3R1cmJ1bGVuY2VfUzFfYzAoZmxvYXQyIHV2KSAKewoJZmxvYXQyIHV2X3NjYWxlID0gdXYgKiBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbSA9IGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtXzEgPSB1dl9zY2FsZTsKCWZsb2F0MiBwYXJhbV8yID0gdV9jaXJjbGUxX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzMgPSB1X3JvdGF0aW9uMV9TMV9jMDsKCWZsb2F0IHBhcmFtXzQgPSAwLjE3OwoJZmxvYXQgXzMxOSA9IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKHBhcmFtLCBwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zLCBwYXJhbV80KTsKCWZsb2F0IGcxID0gXzMxOTsKCWZsb2F0MiBwYXJhbV81ID0gZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW1fNiA9IHV2X3NjYWxlOwoJZmxvYXQyIHBhcmFtXzcgPSB1X2NpcmNsZTJfUzFfYzA7CglmbG9hdDIgcGFyYW1fOCA9IHVfcm90YXRpb24yX1MxX2MwOwoJZmxvYXQgcGFyYW1fOSA9IDAuMjsKCWZsb2F0IF8zMzEgPSBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChwYXJhbV81LCBwYXJhbV82LCBwYXJhbV83LCBwYXJhbV84LCBwYXJhbV85KTsKCWZsb2F0IGcyID0gXzMzMTsKCWZsb2F0MiBwYXJhbV8xMCA9IGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtXzExID0gdXZfc2NhbGU7CglmbG9hdDIgcGFyYW1fMTIgPSB1X2NpcmNsZTNfUzFfYzA7CglmbG9hdDIgcGFyYW1fMTMgPSB1X3JvdGF0aW9uM19TMV9jMDsKCWZsb2F0IHBhcmFtXzE0ID0gMC4yNzU7CglmbG9hdCBfMzQ0ID0gRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAocGFyYW1fMTAsIHBhcmFtXzExLCBwYXJhbV8xMiwgcGFyYW1fMTMsIHBhcmFtXzE0KTsKCWZsb2F0IGczID0gXzM0NDsKCWZsb2F0IHYgPSAoKGcxICogZzEgKyBnMikgLSBnMykgKiAwLjU7CglyZXR1cm4gY2xhbXAoMC40NSArIDAuOCAqIHYsIDAuMCwgMS4wKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X3JpbmdfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgdGhpY2tuZXNzLCBmbG9hdCBibHVyKSAKewoJZmxvYXQyIHBhcmFtID0gdXY7CglmbG9hdDIgcGFyYW1fMSA9IHh5OwoJZmxvYXQgcGFyYW1fMiA9IHJhZGl1cyArIHRoaWNrbmVzczsKCWZsb2F0IHBhcmFtXzMgPSBibHVyOwoJZmxvYXQgY2lyY2xlX291dGVyID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW0sIHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMpOwoJZmxvYXQyIHBhcmFtXzQgPSB1djsKCWZsb2F0MiBwYXJhbV81ID0geHk7CglmbG9hdCBwYXJhbV82ID0gbWF4KHJhZGl1cyAtIHRoaWNrbmVzcywgMC4wKTsKCWZsb2F0IHBhcmFtXzcgPSBibHVyOwoJZmxvYXQgY2lyY2xlX2lubmVyID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW1fNCwgcGFyYW1fNSwgcGFyYW1fNiwgcGFyYW1fNyk7CglyZXR1cm4gY2xhbXAoY2lyY2xlX291dGVyIC0gY2lyY2xlX2lubmVyLCAwLjAsIDEuMCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHJpYW5nbGVfbm9pc2VfUzFfYzAoaW5vdXQgZmxvYXQyIG4pIAp7CgluID0gZnJhY3QobiAqIGZsb2F0Mig1LjM5ODcsIDUuNDQyMSkpOwoJbiArPSBmbG9hdDIoZG90KG4ueXgsIG4gKyBmbG9hdDIoMjEuNTM1MSwgMTQuMzEzNykpKTsKCWZsb2F0IHh5ID0gbi54ICogbi55OwoJcmV0dXJuIChmcmFjdCh4eSAqIDk1LjQzMDcpICsgZnJhY3QoeHkgKiA3NS4wNDk2MSkpIC0gMS4wOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChmbG9hdCB2LCBmbG9hdCBsLCBmbG9hdCBoKSAKewoJcmV0dXJuIHN0ZXAobCwgdikgKiAoMS4wIC0gc3RlcChoLCB2KSk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc3BhcmtsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0IHQpIAp7CglmbG9hdDIgcGFyYW0gPSB1djsKCWZsb2F0IF8yNDIgPSBGTFRfZmx1dHRlcl9sb2NhbF90cmlhbmdsZV9ub2lzZV9TMV9jMChwYXJhbSk7CglmbG9hdCBuID0gXzI0MjsKCWZsb2F0IHBhcmFtXzEgPSBuOwoJZmxvYXQgcGFyYW1fMiA9IDAuMDsKCWZsb2F0IHBhcmFtXzMgPSAwLjA1OwoJZmxvYXQgcyA9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zKTsKCWZsb2F0IHBhcmFtXzQgPSBuICsgc2luKDMuMTQxNTkyNzQgKiAodCArIDAuMzUpKTsKCWZsb2F0IHBhcmFtXzUgPSAwLjE7CglmbG9hdCBwYXJhbV82ID0gMC4xNTsKCXMgKz0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzQsIHBhcmFtXzUsIHBhcmFtXzYpOwoJZmxvYXQgcGFyYW1fNyA9IG4gKyBzaW4oMy4xNDE1OTI3NCAqICh0ICsgMC43KSk7CglmbG9hdCBwYXJhbV84ID0gMC4yOwoJZmxvYXQgcGFyYW1fOSA9IDAuMjU7CglzICs9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV83LCBwYXJhbV84LCBwYXJhbV85KTsKCWZsb2F0IHBhcmFtXzEwID0gbiArIHNpbigzLjE0MTU5Mjc0ICogKHQgKyAxLjA1KSk7CglmbG9hdCBwYXJhbV8xMSA9IDAuMzsKCWZsb2F0IHBhcmFtXzEyID0gMC4zNTsKCXMgKz0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzEwLCBwYXJhbV8xMSwgcGFyYW1fMTIpOwoJcmV0dXJuIGNsYW1wKHMsIDAuMCwgMS4wKSAqIDAuNTU7Cn0Kdm9pZCBGTFRfbWFpbl9TMV9jMCgpIAp7Cgl1X2FscGhhX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC54OwoJdV9zcGFya2xlX2FscGhhX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC55OwoJdV9ibHVyX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC56OwoJdV9yYWRpdXNfc2NhbGVfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLnc7CglmbG9hdDIgcCA9IEZMVF9mbHV0dGVyX2xvY2FsX0ZsdXR0ZXJGcmFnQ29vcmRfUzFfYzAoKTsKCWZsb2F0MiB1dl8xID0gcCAqIHVfcmVzb2x1dGlvbl9zY2FsZV9TMV9jMDsKCWZsb2F0MiBkZW5zaXR5X3V2ID0gdXZfMSAtIG1vZChwLCB1X25vaXNlX3NjYWxlX1MxX2MwKTsKCWZsb2F0IHJhZGl1cyA9IHVfbWF4X3JhZGl1c19TMV9jMCAqIHVfcmFkaXVzX3NjYWxlX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzEzID0gdXZfMTsKCWZsb2F0IHR1cmJ1bGVuY2UgPSBGTFRfZmx1dHRlcl9sb2NhbF90dXJidWxlbmNlX1MxX2MwKHBhcmFtXzEzKTsKCWZsb2F0MiBwYXJhbV8xNCA9IHA7CglmbG9hdDIgcGFyYW1fMTUgPSB1X2NlbnRlcl9TMV9jMDsKCWZsb2F0IHBhcmFtXzE2ID0gcmFkaXVzOwoJZmxvYXQgcGFyYW1fMTcgPSAwLjA1ICogdV9tYXhfcmFkaXVzX1MxX2MwOwoJZmxvYXQgcGFyYW1fMTggPSB1X2JsdXJfUzFfYzA7CglmbG9hdCByaW5nID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9yaW5nX1MxX2MwKHBhcmFtXzE0LCBwYXJhbV8xNSwgcGFyYW1fMTYsIHBhcmFtXzE3LCBwYXJhbV8xOCk7CglmbG9hdDIgcGFyYW1fMTkgPSBkZW5zaXR5X3V2OwoJZmxvYXQgcGFyYW1fMjAgPSB1X25vaXNlX3BoYXNlX1MxX2MwOwoJZmxvYXQgc3BhcmtsZSA9ICgoRkxUX2ZsdXR0ZXJfbG9jYWxfc3BhcmtsZV9TMV9jMChwYXJhbV8xOSwgcGFyYW1fMjApICogcmluZykgKiB0dXJidWxlbmNlKSAqIHVfc3BhcmtsZV9hbHBoYV9TMV9jMDsKCWZsb2F0MiBwYXJhbV8yMSA9IHA7CglmbG9hdDIgcGFyYW1fMjIgPSB1X2NlbnRlcl9TMV9jMDsKCWZsb2F0IHBhcmFtXzIzID0gcmFkaXVzOwoJZmxvYXQgcGFyYW1fMjQgPSB1X2JsdXJfUzFfYzA7CglmbG9hdCB3YXZlX2FscGhhID0gKEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtXzIxLCBwYXJhbV8yMiwgcGFyYW1fMjMsIHBhcmFtXzI0KSAqIHVfYWxwaGFfUzFfYzApICogdV9jb2xvcl9TMV9jMC53OwoJZmxvYXQ0IHdhdmVfY29sb3IgPSBmbG9hdDQodV9jb2xvcl9TMV9jMC54eXogKiB3YXZlX2FscGhhLCB3YXZlX2FscGhhKTsKCWZyYWdDb2xvcl9TMV9jMCA9IG1peCh3YXZlX2NvbG9yLCBmbG9hdDQoMS4wKSwgZmxvYXQ0KHNwYXJrbGUpKTsKfQpoYWxmNCBydW50aW1lX3NoYWRlcl9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzBfaW5Db2xvciA9IF9pbnB1dDsKCWZsb2F0MiBfdG1wXzFfY29vcmRzID0gdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CglmbHV0dGVyX0ZyYWdDb29yZF9TMV9jMCA9IGZsb2F0NChfdG1wXzFfY29vcmRzLCAwLjAsIDAuMCk7CglGTFRfbWFpbl9TMV9jMCgpOwoJcmV0dXJuIGhhbGY0KGhhbGY0KGZyYWdDb2xvcl9TMV9jMCkpOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gcnVudGltZV9zaGFkZXJfUzFfYzAoX2lucHV0KTsKfQpoYWxmNCBDaXJjbGVfUzJfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF8yX2luQ29sb3IgPSBfaW5wdXQ7CgloYWxmIGQ7CglpZiAoaW50KDEpID09IGtJbnZlcnNlRmlsbEJXX1MyX2MwIHx8IGludCgxKSA9PSBrSW52ZXJzZUZpbGxBQV9TMl9jMCkgCgl7CgkJZCA9IGhhbGYoKGxlbmd0aCgodWNpcmNsZV9TMl9jMC54eSAtIHNrX0ZyYWdDb29yZC54eSkgKiB1Y2lyY2xlX1MyX2MwLncpIC0gMS4wKSAqIHVjaXJjbGVfUzJfYzAueik7Cgl9CgllbHNlIAoJewoJCWQgPSBoYWxmKCgxLjAgLSBsZW5ndGgoKHVjaXJjbGVfUzJfYzAueHkgLSBza19GcmFnQ29vcmQueHkpICogdWNpcmNsZV9TMl9jMC53KSkgKiB1Y2lyY2xlX1MyX2MwLnopOwoJfQoJcmV0dXJuIGhhbGY0KGhhbGY0KGludCgxKSA9PSBrRmlsbEFBX1MyX2MwIHx8IGludCgxKSA9PSBrSW52ZXJzZUZpbGxBQV9TMl9jMCA/IHNhdHVyYXRlKGQpIDogaGFsZihkID4gMC41KSkpOwp9CmhhbGY0IEJsZW5kX1MyKGhhbGY0IF9zcmMsIGhhbGY0IF9kc3QpIAp7CglyZXR1cm4gYmxlbmRfbW9kdWxhdGUoX3NyYywgQ2lyY2xlX1MyX2MwKF9zcmMpKTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJZmxvYXQgY292ZXJhZ2UgPSB2Y292ZXJhZ2VfUzA7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGNvdmVyYWdlKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IE1hdHJpeEVmZmVjdF9TMShvdXRwdXRDb2xvcl9TMCk7CgloYWxmNCBvdXRwdXRfUzI7CglvdXRwdXRfUzIgPSBCbGVuZF9TMihvdXRwdXRDb3ZlcmFnZV9TMCwgaGFsZjQoMSkpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dF9TMjsKCX0KfQoAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAHBvc2l0aW9uCAAAAGNvdmVyYWdlBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","EEAQMYAAMAAAEADAAABAEYAAAICIAB5AABQAAAQAMAAAEATAAABAIIGAAEDCBYQCA4AAAAAAAAZQAAAAAABAAAAACAZAAAAA":"DAAAAExTS1MoDAAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDQgcmFkaWlfc2VsZWN0b3I7CmluIGZsb2F0NCBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzOwppbiBmbG9hdDQgYWFfYmxvYXRfYW5kX2NvdmVyYWdlOwppbiBmbG9hdDQgcmFkaWlfeDsKaW4gZmxvYXQ0IHJhZGlpX3k7CmluIGZsb2F0NCBza2V3OwppbiBmbG9hdDIgdHJhbnNsYXRlX2FuZF9sb2NhbHJvdGF0ZTsKaW4gaGFsZjQgY29sb3I7Cm5vcGVyc3BlY3RpdmUgb3V0IGhhbGY0IHZjb2xvcl9TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQyIHZhcmNjb29yZF9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgRmlsbFJSZWN0T3A6OlByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7CglmbG9hdCBhYV9ibG9hdF9tdWx0aXBsaWVyID0gMTsKCWZsb2F0MiBjb3JuZXIgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnh5OwoJZmxvYXQyIHJhZGl1c19vdXRzZXQgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnp3OwoJZmxvYXQyIGFhX2Jsb2F0X2RpcmVjdGlvbiA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS54eTsKCWZsb2F0IGlzX2xpbmVhcl9jb3ZlcmFnZSA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS53OwoJZmxvYXQyIHBpeGVsbGVuZ3RoID0gaW52ZXJzZXNxcnQoZmxvYXQyKGRvdChza2V3Lnh6LCBza2V3Lnh6KSwgZG90KHNrZXcueXcsIHNrZXcueXcpKSk7CglmbG9hdDQgbm9ybWFsaXplZF9heGlzX2RpcnMgPSBza2V3ICogcGl4ZWxsZW5ndGgueHl4eTsKCWZsb2F0MiBheGlzd2lkdGhzID0gKGFicyhub3JtYWxpemVkX2F4aXNfZGlycy54eSkgKyBhYnMobm9ybWFsaXplZF9heGlzX2RpcnMuencpKTsKCWZsb2F0MiBhYV9ibG9hdHJhZGl1cyA9IGF4aXN3aWR0aHMgKiBwaXhlbGxlbmd0aCAqIC41OwoJZmxvYXQ0IHJhZGlpX2FuZF9uZWlnaGJvcnMgPSByYWRpaV9zZWxlY3RvciogZmxvYXQ0eDQocmFkaWlfeCwgcmFkaWlfeSwgcmFkaWlfeC55eHd6LCByYWRpaV95Lnd6eXgpOwoJZmxvYXQyIHJhZGlpID0gcmFkaWlfYW5kX25laWdoYm9ycy54eTsKCWZsb2F0MiBuZWlnaGJvcl9yYWRpaSA9IHJhZGlpX2FuZF9uZWlnaGJvcnMuenc7CglmbG9hdCBjb3ZlcmFnZV9tdWx0aXBsaWVyID0gMTsKCWlmIChhbnkoZ3JlYXRlclRoYW4oYWFfYmxvYXRyYWRpdXMsIGZsb2F0MigxKSkpKSAKCXsKCQljb3JuZXIgPSBtYXgoYWJzKGNvcm5lciksIGFhX2Jsb2F0cmFkaXVzKSAqIHNpZ24oY29ybmVyKTsKCQljb3ZlcmFnZV9tdWx0aXBsaWVyID0gMSAvIChtYXgoYWFfYmxvYXRyYWRpdXMueCwgMSkgKiBtYXgoYWFfYmxvYXRyYWRpdXMueSwgMSkpOwoJCXJhZGlpID0gZmxvYXQyKDApOwoJfQoJZmxvYXQgY292ZXJhZ2UgPSBhYV9ibG9hdF9hbmRfY292ZXJhZ2UuejsKCWlmIChhbnkobGVzc1RoYW4ocmFkaWksIGFhX2Jsb2F0cmFkaXVzICogMS41KSkpIAoJewoJCXJhZGlpID0gZmxvYXQyKDApOwoJCWFhX2Jsb2F0X2RpcmVjdGlvbiA9IHNpZ24oY29ybmVyKTsKCQlpZiAoY292ZXJhZ2UgPiAuNSkgCgkJewoJCQlhYV9ibG9hdF9kaXJlY3Rpb24gPSAtYWFfYmxvYXRfZGlyZWN0aW9uOwoJCX0KCQlpc19saW5lYXJfY292ZXJhZ2UgPSAxOwoJfQoJZWxzZSAKCXsKCQlyYWRpaSA9IGNsYW1wKHJhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQluZWlnaGJvcl9yYWRpaSA9IGNsYW1wKG5laWdoYm9yX3JhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQlmbG9hdDIgc3BhY2luZyA9IDIgLSByYWRpaSAtIG5laWdoYm9yX3JhZGlpOwoJCWZsb2F0MiBleHRyYV9wYWQgPSBtYXgocGl4ZWxsZW5ndGggKiAuMDYyNSAtIHNwYWNpbmcsIGZsb2F0MigwKSk7CgkJcmFkaWkgLT0gZXh0cmFfcGFkICogLjU7Cgl9CglmbG9hdDIgYWFfb3V0c2V0ID0gYWFfYmxvYXRfZGlyZWN0aW9uICogYWFfYmxvYXRyYWRpdXMgKiBhYV9ibG9hdF9tdWx0aXBsaWVyOwoJZmxvYXQyIHZlcnRleHBvcyA9IGNvcm5lciArIHJhZGl1c19vdXRzZXQgKiByYWRpaSArIGFhX291dHNldDsKCWlmIChjb3ZlcmFnZSA+IC41KSAKCXsKCQlpZiAoYWFfYmxvYXRfZGlyZWN0aW9uLnggIT0gMCAmJiB2ZXJ0ZXhwb3MueCAqIGNvcm5lci54IDwgMCkgCgkJewoJCQlmbG9hdCBiYWNrc2V0ID0gYWJzKHZlcnRleHBvcy54KTsKCQkJdmVydGV4cG9zLnggPSAwOwoJCQl2ZXJ0ZXhwb3MueSArPSBiYWNrc2V0ICogc2lnbihjb3JuZXIueSkgKiBwaXhlbGxlbmd0aC55L3BpeGVsbGVuZ3RoLng7CgkJCWNvdmVyYWdlID0gKGNvdmVyYWdlIC0gLjUpICogYWJzKGNvcm5lci54KSAvIChhYnMoY29ybmVyLngpICsgYmFja3NldCkgKyAuNTsKCQl9CgkJaWYgKGFhX2Jsb2F0X2RpcmVjdGlvbi55ICE9IDAgJiYgdmVydGV4cG9zLnkgKiBjb3JuZXIueSA8IDApIAoJCXsKCQkJZmxvYXQgYmFja3NldCA9IGFicyh2ZXJ0ZXhwb3MueSk7CgkJCXZlcnRleHBvcy55ID0gMDsKCQkJdmVydGV4cG9zLnggKz0gYmFja3NldCAqIHNpZ24oY29ybmVyLngpICogcGl4ZWxsZW5ndGgueC9waXhlbGxlbmd0aC55OwoJCQljb3ZlcmFnZSA9IChjb3ZlcmFnZSAtIC41KSAqIGFicyhjb3JuZXIueSkgLyAoYWJzKGNvcm5lci55KSArIGJhY2tzZXQpICsgLjU7CgkJfQoJfQoJZmxvYXQyeDIgc2tld21hdHJpeCA9IGZsb2F0MngyKHNrZXcueHksIHNrZXcuencpOwoJZmxvYXQyIGRldmNvb3JkID0gdmVydGV4cG9zICogc2tld21hdHJpeCArIHRyYW5zbGF0ZV9hbmRfbG9jYWxyb3RhdGUueHk7CglpZiAoMCAhPSBpc19saW5lYXJfY292ZXJhZ2UpIAoJewoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MigwLCBjb3ZlcmFnZSAqIGNvdmVyYWdlX211bHRpcGxpZXIpOwoJfQoJZWxzZSAKCXsKCQlmbG9hdDIgYXJjY29vcmQgPSAxIC0gYWJzKHJhZGl1c19vdXRzZXQpICsgYWFfb3V0c2V0L3JhZGlpICogY29ybmVyOwoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MihhcmNjb29yZC54KzEsIGFyY2Nvb3JkLnkpOwoJfQoJc2tfUG9zaXRpb24gPSBkZXZjb29yZC54eTAxOwp9CgAAAACZAgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCm5vcGVyc3BlY3RpdmUgaW4gaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2YXJjY29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBGaWxsUlJlY3RPcDo6UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJZmxvYXQgeF9wbHVzXzE9dmFyY2Nvb3JkX1MwLngsIHk9dmFyY2Nvb3JkX1MwLnk7CgloYWxmIGNvdmVyYWdlOwoJaWYgKDAgPT0geF9wbHVzXzEpIAoJewoJCWNvdmVyYWdlID0gaGFsZih5KTsKCX0KCWVsc2UgCgl7CgkJZmxvYXQgZm4gPSB4X3BsdXNfMSAqICh4X3BsdXNfMSAtIDIpOwoJCWZuID0gZm1hKHkseSwgZm4pOwoJCWZsb2F0IGZud2lkdGggPSBmd2lkdGgoZm4pOwoJCWNvdmVyYWdlID0gLjUgLSBoYWxmKGZuL2Zud2lkdGgpOwoJCWNvdmVyYWdlID0gY2xhbXAoY292ZXJhZ2UsIDAsIDEpOwoJfQoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChjb3ZlcmFnZSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAACAAAAA4AAAByYWRpaV9zZWxlY3RvcgAAGQAAAGNvcm5lcl9hbmRfcmFkaXVzX291dHNldHMAAAAVAAAAYWFfYmxvYXRfYW5kX2NvdmVyYWdlAAAABwAAAHJhZGlpX3gABwAAAHJhZGlpX3kABAAAAHNrZXcZAAAAdHJhbnNsYXRlX2FuZF9sb2NhbHJvdGF0ZQAAAAUAAABjb2xvcgAAAAAAAAA=","GYQACAAAAAMAADAAAIOAAAH677776IZOCAAP577777777777777777YBAAAAAAAAAAADEAAGAAAAAAAAAIAAAAAPAIABAAAAABAGEAAAAEAAAABNARCAIAAAAAAAAAAAAAYAGAAAAAQAAAAAAAQQGAAAAA":"DAAAAExTS1O8AQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzBfYzA7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7Cm5vcGVyc3BlY3RpdmUgb3V0IGhhbGY0IHZjb2xvcl9TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc180X1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCXZjb2xvcl9TMCA9IGNvbG9yOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwoJewoJCXZUcmFuc2Zvcm1lZENvb3Jkc180X1MwID0gZmxvYXQzeDIodW1hdHJpeF9TMV9jMF9jMCkgKiBwb3NpdGlvbi54eTE7Cgl9Cn0KAAAAAI0DAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxX2MwX2MwOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7Cm5vcGVyc3BlY3RpdmUgaW4gaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfNF9TMDsKaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMF9jMF9jMChoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MxLCB2VHJhbnNmb3JtZWRDb29yZHNfNF9TMCkuMDAwcjsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzBfYzBfYzAoX2lucHV0KTsKfQpoYWxmNCBEZXZpY2VTcGFjZV9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gTWF0cml4RWZmZWN0X1MxX2MwX2MwKF9pbnB1dCk7Cn0KaGFsZjQgQmxlbmRfUzEoaGFsZjQgX3NyYywgaGFsZjQgX2RzdCkgCnsKCXJldHVybiBibGVuZF9kc3RfaW4oRGV2aWNlU3BhY2VfUzFfYzAoX3NyYyksIF9zcmMpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQmxlbmRfUzEob3V0cHV0Q292ZXJhZ2VfUzAsIGhhbGY0KDEpKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgUAAABjb2xvcgAAAAAAAAA=","GZIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAHIBK2VD3EOCAAAAAABUXHIMAQAAAAWSQ4HO4SAAAAAMAAAAAEBUEFLMJAIAAAQCI6KVAYAAAAAAAAAAAQAAEACUA2JT4HAIAAAADIIODXOJIBAAAGAAAAACAKAC5XEQEAAAAAEPF2SMAAAAAAAAIAAAACXUUGB3XUUAQAADAAAAAAABARO3SJCAAAAACGSZJWCAAAAAAAIAAAABLFBUEFLMJAIAAAAAAAAAAACIMVSTUFAEAAAAAIAAAAAWFBSHSVIGAAAAAAAAAAAAABEBAABAAAAADIEEQCEAAAAAAAAAAAQAMQAAAAAAAQAAAABAMQAAA":"DAAAAExTS1PaAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzBfYzBfYzE7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfNl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfNl9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzFfYzBfYzBfYzEpICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAABAAAAcQkAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQp1bmlmb3JtIGhhbGY0IHVzdGFydF9TMV9jMF9jMF9jMDsKdW5pZm9ybSBoYWxmNCB1ZW5kX1MxX2MwX2MwX2MwOwp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzBfYzBfYzE7CnVuaWZvcm0gaGFsZjQgdWxlZnRCb3JkZXJDb2xvcl9TMV9jMF9jMDsKdW5pZm9ybSBoYWxmNCB1cmlnaHRCb3JkZXJDb2xvcl9TMV9jMF9jMDsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxX2MxOwp1bmlmb3JtIGhhbGYgdXJhbmdlX1MxOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7Cm5vcGVyc3BlY3RpdmUgaW4gaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfNl9TMDsKaGFsZjQgU2luZ2xlSW50ZXJ2YWxDb2xvcml6ZXJfUzFfYzBfYzBfYzAoaGFsZjQgX2lucHV0LCBmbG9hdDIgX2Nvb3JkcykgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJZmxvYXQyIF90bXBfMV9jb29yZHMgPSBfY29vcmRzOwoJcmV0dXJuIGhhbGY0KG1peCh1c3RhcnRfUzFfYzBfYzBfYzAsIHVlbmRfUzFfYzBfYzBfYzAsIGhhbGYoX3RtcF8xX2Nvb3Jkcy54KSkpOwp9CmhhbGY0IExpbmVhckxheW91dF9TMV9jMF9jMF9jMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzJfaW5Db2xvciA9IF9pbnB1dDsKCWZsb2F0MiBfdG1wXzNfY29vcmRzID0gdlRyYW5zZm9ybWVkQ29vcmRzXzZfUzA7CglyZXR1cm4gaGFsZjQoaGFsZjQoaGFsZihfdG1wXzNfY29vcmRzLngpICsgMWUtMDUsIDEuMCwgMC4wLCAwLjApKTsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzFfYzBfYzBfYzEoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIExpbmVhckxheW91dF9TMV9jMF9jMF9jMV9jMChfaW5wdXQpOwp9CmhhbGY0IENsYW1wZWRHcmFkaWVudF9TMV9jMF9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzRfaW5Db2xvciA9IF9pbnB1dDsKCWhhbGY0IHQgPSBNYXRyaXhFZmZlY3RfUzFfYzBfYzBfYzEoX3RtcF80X2luQ29sb3IpOwoJaGFsZjQgb3V0Q29sb3I7CglpZiAoIWJvb2woaW50KDEpKSAmJiB0LnkgPCAwLjApIAoJewoJCW91dENvbG9yID0gaGFsZjQoMC4wKTsKCX0KCWVsc2UgaWYgKHQueCA8IDAuMCkgCgl7CgkJb3V0Q29sb3IgPSB1bGVmdEJvcmRlckNvbG9yX1MxX2MwX2MwOwoJfQoJZWxzZSBpZiAodC54ID4gMS4wKSAKCXsKCQlvdXRDb2xvciA9IHVyaWdodEJvcmRlckNvbG9yX1MxX2MwX2MwOwoJfQoJZWxzZSAKCXsKCQlvdXRDb2xvciA9IFNpbmdsZUludGVydmFsQ29sb3JpemVyX1MxX2MwX2MwX2MwKF90bXBfNF9pbkNvbG9yLCBmbG9hdDIoaGFsZjIodC54LCAwLjApKSk7Cgl9CglyZXR1cm4gaGFsZjQob3V0Q29sb3IpOwp9CmhhbGY0IERpc2FibGVDb3ZlcmFnZUFzQWxwaGFfUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJX2lucHV0ID0gQ2xhbXBlZEdyYWRpZW50X1MxX2MwX2MwKF9pbnB1dCk7CgloYWxmNCBfdG1wXzVfaW5Db2xvciA9IF9pbnB1dDsKCXJldHVybiBoYWxmNChfaW5wdXQpOwp9CmhhbGY0IFRleHR1cmVFZmZlY3RfUzFfYzFfYzAoaGFsZjQgX2lucHV0LCBmbG9hdDIgX2Nvb3JkcykgCnsKCXJldHVybiBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzEsIF9jb29yZHMpLjAwMHI7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxX2MxKGhhbGY0IF9pbnB1dCwgZmxvYXQyIF9jb29yZHMpIAp7CglyZXR1cm4gVGV4dHVyZUVmZmVjdF9TMV9jMV9jMChfaW5wdXQsIGZsb2F0M3gyKHVtYXRyaXhfUzFfYzEpICogX2Nvb3Jkcy54eTEpOwp9CmhhbGY0IERpdGhlcl9TMShoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzZfaW5Db2xvciA9IF9pbnB1dDsKCWhhbGY0IGNvbG9yID0gRGlzYWJsZUNvdmVyYWdlQXNBbHBoYV9TMV9jMChfdG1wXzZfaW5Db2xvcik7CgloYWxmIHZhbHVlID0gTWF0cml4RWZmZWN0X1MxX2MxKF90bXBfNl9pbkNvbG9yLCBza19GcmFnQ29vcmQueHkpLncgLSAwLjU7CglyZXR1cm4gaGFsZjQoaGFsZjQoY2xhbXAoY29sb3IueHl6ICsgdmFsdWUgKiB1cmFuZ2VfUzEsIDAuMCwgY29sb3IudyksIGNvbG9yLncpKTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IERpdGhlcl9TMShvdXRwdXRDb2xvcl9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0X1MxICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAIAAAAcG9zaXRpb24FAAAAY29sb3IAAAAKAAAAbG9jYWxDb29yZAAAAAAAAA==","GYJAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAQAAAAAAQQGAAZAABQAAAAAAAACAAAAADYCAAIAAAAAIBRAAAABAAAAALIEIQCAAAAAAAAAAAAAGABQAAAAEAAAAAAAEEBQAAAA":"DAAAAExTS1PSAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzBfYzA7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2bG9jYWxDb29yZF9TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc180X1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCXZsb2NhbENvb3JkX1MwID0gbG9jYWxDb29yZDsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfNF9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzFfYzBfYzApICogcG9zaXRpb24ueHkxOwoJfQp9CgAAAAAAACUEAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxX2MwX2MwOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzA7CnNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMTsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc180X1MwOwpoYWxmNCBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzEsIHZUcmFuc2Zvcm1lZENvb3Jkc180X1MwKS4wMDByOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMV9jMF9jMChoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gVGV4dHVyZUVmZmVjdF9TMV9jMF9jMF9jMChfaW5wdXQpOwp9CmhhbGY0IERldmljZVNwYWNlX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoX2lucHV0KTsKfQpoYWxmNCBCbGVuZF9TMShoYWxmNCBfc3JjLCBoYWxmNCBfZHN0KSAKewoJcmV0dXJuIGJsZW5kX2RzdF9pbihEZXZpY2VTcGFjZV9TMV9jMChfc3JjKSwgX3NyYyk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWZsb2F0MiB0ZXhDb29yZDsKCXRleENvb3JkID0gdmxvY2FsQ29vcmRfUzA7CglvdXRwdXRDb2xvcl9TMCA9IChibGVuZF9tb2R1bGF0ZShzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzAsIHRleENvb3JkKSwgaGFsZjQoMSkpKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBCbGVuZF9TMShvdXRwdXRDb3ZlcmFnZV9TMCwgaGFsZjQoMSkpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0X1MxOwoJfQp9CgAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACAAAAHBvc2l0aW9uCgAAAGxvY2FsQ29vcmQAAAAAAAA=","GZIACAAAABQAAGAAAQ4AAAAAGQQAARC4GAAAIOCAAD6P7777777777YDAAAAAAAAAAAJQBBYGQ467YIAAAAAAQAAAAAMACTRNBZN5QYBAAAAAAAAAAAIAAJQAAAAAAAANAAAAAHQVERARJYAAAABQAAAABAAAAAA4BAQAAACAAAAASAMAAQAAAAAUCCYBCAAAAAAAAAAAAAANJABAAAMBJ4KECOAEAAAMAAAAAAAAEAABAAV6GUSECFHAAAAAGAAAAAAAAAAAAAGABQAAAAEAAAAAAAEEBQA":"DAAAAExTS1PdAgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMl9jMF9jMDsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdCBjb3ZlcmFnZTsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0IHZjb3ZlcmFnZV9TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzZfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQyIHBvc2l0aW9uID0gcG9zaXRpb24ueHk7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCXZjb3ZlcmFnZV9TMCA9IGNvdmVyYWdlOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwoJewoJCXZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwID0gZmxvYXQzeDIodW1hdHJpeF9TMSkgKiBsb2NhbENvb3JkLnh5MTsKCX0KCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfNl9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzJfYzBfYzApICogcG9zaXRpb24ueHkxOwoJfQp9CgAAAAEAAADvIQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCmZsb2F0NCBmbHV0dGVyX0ZyYWdDb29yZF9TMV9jMDsKZmxvYXQ0IGZyYWdDb2xvcl9TMV9jMDsKZmxvYXQgdV9hbHBoYV9TMV9jMDsKZmxvYXQgdV9zcGFya2xlX2FscGhhX1MxX2MwOwpmbG9hdCB1X2JsdXJfUzFfYzA7CmZsb2F0IHVfcmFkaXVzX3NjYWxlX1MxX2MwOwpjb25zdCBpbnQga0ZpbGxCV19TMl9jMV9jMCA9IDA7CmNvbnN0IGludCBrSW52ZXJzZUZpbGxCV19TMl9jMV9jMCA9IDI7CmNvbnN0IGludCBrSW52ZXJzZUZpbGxBQV9TMl9jMV9jMCA9IDM7CnVuaWZvcm0gZmxvYXQ0IHVfY29sb3JfUzFfYzA7CnVuaWZvcm0gZmxvYXQ0IHVfY29tcG9zaXRlXzFfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2VudGVyX1MxX2MwOwp1bmlmb3JtIGZsb2F0IHVfbWF4X3JhZGl1c19TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yZXNvbHV0aW9uX3NjYWxlX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X25vaXNlX3NjYWxlX1MxX2MwOwp1bmlmb3JtIGZsb2F0IHVfbm9pc2VfcGhhc2VfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2lyY2xlMV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jaXJjbGUyX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NpcmNsZTNfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcm90YXRpb24xX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3JvdGF0aW9uMl9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yb3RhdGlvbjNfUzFfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MyX2MwX2MwOwp1bmlmb3JtIGZsb2F0NCB1cmVjdFVuaWZvcm1fUzJfYzFfYzA7CnNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMjsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQgdmNvdmVyYWdlX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzZfUzA7CmZsb2F0MiBGTFRfZmx1dHRlcl9sb2NhbF9GbHV0dGVyRnJhZ0Nvb3JkX1MxX2MwKCk7CmZsb2F0MngyIEZMVF9mbHV0dGVyX2xvY2FsX3JvdGF0ZTJkX1MxX2MwKGZsb2F0MiByYWQpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCBibHVyKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAoZmxvYXQyIHJlc29sdXRpb24sIGlub3V0IGZsb2F0MiBwLCBmbG9hdDIgeHksIGZsb2F0MiByb3RhdGlvbiwgZmxvYXQgY2VsbF9kaWFtZXRlcik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3R1cmJ1bGVuY2VfUzFfYzAoZmxvYXQyIHV2KTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9yaW5nX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IHRoaWNrbmVzcywgZmxvYXQgYmx1cik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RyaWFuZ2xlX25vaXNlX1MxX2MwKGlub3V0IGZsb2F0MiBuKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKGZsb2F0IHYsIGZsb2F0IGwsIGZsb2F0IGgpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zcGFya2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQgdCk7CnZvaWQgRkxUX21haW5fUzFfYzAoKTsKZmxvYXQyIEZMVF9mbHV0dGVyX2xvY2FsX0ZsdXR0ZXJGcmFnQ29vcmRfUzFfYzAoKSAKewoJcmV0dXJuIGZsdXR0ZXJfRnJhZ0Nvb3JkX1MxX2MwLnh5Owp9CmZsb2F0MngyIEZMVF9mbHV0dGVyX2xvY2FsX3JvdGF0ZTJkX1MxX2MwKGZsb2F0MiByYWQpIAp7CglyZXR1cm4gZmxvYXQyeDIocmFkLngsIC1yYWQueSwgcmFkLnksIHJhZC54KTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCBibHVyKSAKewoJZmxvYXQgYmx1cl9oYWxmID0gYmx1ciAqIDAuNTsKCWZsb2F0IGQgPSBkaXN0YW5jZSh1diwgeHkpOwoJcmV0dXJuIDEuMCAtIHNtb290aHN0ZXAoMS4wIC0gYmx1cl9oYWxmLCAxLjAgKyBibHVyX2hhbGYsIGQgLyByYWRpdXMpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKGZsb2F0MiByZXNvbHV0aW9uLCBpbm91dCBmbG9hdDIgcCwgZmxvYXQyIHh5LCBmbG9hdDIgcm90YXRpb24sIGZsb2F0IGNlbGxfZGlhbWV0ZXIpIAp7CglmbG9hdDIgcGFyYW0gPSByb3RhdGlvbjsKCXAgPSBGTFRfZmx1dHRlcl9sb2NhbF9yb3RhdGUyZF9TMV9jMChwYXJhbSkgKiAoeHkgLSBwKSArIHh5OwoJcCA9IG1vZChwLCBmbG9hdDIoY2VsbF9kaWFtZXRlcikpIC8gcmVzb2x1dGlvbjsKCWZsb2F0IGNlbGxfdXYgPSAoY2VsbF9kaWFtZXRlciAvIHJlc29sdXRpb24ueSkgKiAwLjU7CglmbG9hdCByID0gMC42NSAqIGNlbGxfdXY7CglmbG9hdDIgcGFyYW1fMSA9IHA7CglmbG9hdDIgcGFyYW1fMiA9IGZsb2F0MihjZWxsX3V2KTsKCWZsb2F0IHBhcmFtXzMgPSByOwoJZmxvYXQgcGFyYW1fNCA9IHIgKiA1MC4wOwoJcmV0dXJuIEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMsIHBhcmFtXzQpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3R1cmJ1bGVuY2VfUzFfYzAoZmxvYXQyIHV2KSAKewoJZmxvYXQyIHV2X3NjYWxlID0gdXYgKiBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbSA9IGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtXzEgPSB1dl9zY2FsZTsKCWZsb2F0MiBwYXJhbV8yID0gdV9jaXJjbGUxX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzMgPSB1X3JvdGF0aW9uMV9TMV9jMDsKCWZsb2F0IHBhcmFtXzQgPSAwLjE3OwoJZmxvYXQgXzMxOSA9IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKHBhcmFtLCBwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zLCBwYXJhbV80KTsKCWZsb2F0IGcxID0gXzMxOTsKCWZsb2F0MiBwYXJhbV81ID0gZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW1fNiA9IHV2X3NjYWxlOwoJZmxvYXQyIHBhcmFtXzcgPSB1X2NpcmNsZTJfUzFfYzA7CglmbG9hdDIgcGFyYW1fOCA9IHVfcm90YXRpb24yX1MxX2MwOwoJZmxvYXQgcGFyYW1fOSA9IDAuMjsKCWZsb2F0IF8zMzEgPSBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChwYXJhbV81LCBwYXJhbV82LCBwYXJhbV83LCBwYXJhbV84LCBwYXJhbV85KTsKCWZsb2F0IGcyID0gXzMzMTsKCWZsb2F0MiBwYXJhbV8xMCA9IGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtXzExID0gdXZfc2NhbGU7CglmbG9hdDIgcGFyYW1fMTIgPSB1X2NpcmNsZTNfUzFfYzA7CglmbG9hdDIgcGFyYW1fMTMgPSB1X3JvdGF0aW9uM19TMV9jMDsKCWZsb2F0IHBhcmFtXzE0ID0gMC4yNzU7CglmbG9hdCBfMzQ0ID0gRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAocGFyYW1fMTAsIHBhcmFtXzExLCBwYXJhbV8xMiwgcGFyYW1fMTMsIHBhcmFtXzE0KTsKCWZsb2F0IGczID0gXzM0NDsKCWZsb2F0IHYgPSAoKGcxICogZzEgKyBnMikgLSBnMykgKiAwLjU7CglyZXR1cm4gY2xhbXAoMC40NSArIDAuOCAqIHYsIDAuMCwgMS4wKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X3JpbmdfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgdGhpY2tuZXNzLCBmbG9hdCBibHVyKSAKewoJZmxvYXQyIHBhcmFtID0gdXY7CglmbG9hdDIgcGFyYW1fMSA9IHh5OwoJZmxvYXQgcGFyYW1fMiA9IHJhZGl1cyArIHRoaWNrbmVzczsKCWZsb2F0IHBhcmFtXzMgPSBibHVyOwoJZmxvYXQgY2lyY2xlX291dGVyID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW0sIHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMpOwoJZmxvYXQyIHBhcmFtXzQgPSB1djsKCWZsb2F0MiBwYXJhbV81ID0geHk7CglmbG9hdCBwYXJhbV82ID0gbWF4KHJhZGl1cyAtIHRoaWNrbmVzcywgMC4wKTsKCWZsb2F0IHBhcmFtXzcgPSBibHVyOwoJZmxvYXQgY2lyY2xlX2lubmVyID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW1fNCwgcGFyYW1fNSwgcGFyYW1fNiwgcGFyYW1fNyk7CglyZXR1cm4gY2xhbXAoY2lyY2xlX291dGVyIC0gY2lyY2xlX2lubmVyLCAwLjAsIDEuMCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHJpYW5nbGVfbm9pc2VfUzFfYzAoaW5vdXQgZmxvYXQyIG4pIAp7CgluID0gZnJhY3QobiAqIGZsb2F0Mig1LjM5ODcsIDUuNDQyMSkpOwoJbiArPSBmbG9hdDIoZG90KG4ueXgsIG4gKyBmbG9hdDIoMjEuNTM1MSwgMTQuMzEzNykpKTsKCWZsb2F0IHh5ID0gbi54ICogbi55OwoJcmV0dXJuIChmcmFjdCh4eSAqIDk1LjQzMDcpICsgZnJhY3QoeHkgKiA3NS4wNDk2MSkpIC0gMS4wOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChmbG9hdCB2LCBmbG9hdCBsLCBmbG9hdCBoKSAKewoJcmV0dXJuIHN0ZXAobCwgdikgKiAoMS4wIC0gc3RlcChoLCB2KSk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc3BhcmtsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0IHQpIAp7CglmbG9hdDIgcGFyYW0gPSB1djsKCWZsb2F0IF8yNDIgPSBGTFRfZmx1dHRlcl9sb2NhbF90cmlhbmdsZV9ub2lzZV9TMV9jMChwYXJhbSk7CglmbG9hdCBuID0gXzI0MjsKCWZsb2F0IHBhcmFtXzEgPSBuOwoJZmxvYXQgcGFyYW1fMiA9IDAuMDsKCWZsb2F0IHBhcmFtXzMgPSAwLjA1OwoJZmxvYXQgcyA9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zKTsKCWZsb2F0IHBhcmFtXzQgPSBuICsgc2luKDMuMTQxNTkyNzQgKiAodCArIDAuMzUpKTsKCWZsb2F0IHBhcmFtXzUgPSAwLjE7CglmbG9hdCBwYXJhbV82ID0gMC4xNTsKCXMgKz0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzQsIHBhcmFtXzUsIHBhcmFtXzYpOwoJZmxvYXQgcGFyYW1fNyA9IG4gKyBzaW4oMy4xNDE1OTI3NCAqICh0ICsgMC43KSk7CglmbG9hdCBwYXJhbV84ID0gMC4yOwoJZmxvYXQgcGFyYW1fOSA9IDAuMjU7CglzICs9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV83LCBwYXJhbV84LCBwYXJhbV85KTsKCWZsb2F0IHBhcmFtXzEwID0gbiArIHNpbigzLjE0MTU5Mjc0ICogKHQgKyAxLjA1KSk7CglmbG9hdCBwYXJhbV8xMSA9IDAuMzsKCWZsb2F0IHBhcmFtXzEyID0gMC4zNTsKCXMgKz0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzEwLCBwYXJhbV8xMSwgcGFyYW1fMTIpOwoJcmV0dXJuIGNsYW1wKHMsIDAuMCwgMS4wKSAqIDAuNTU7Cn0Kdm9pZCBGTFRfbWFpbl9TMV9jMCgpIAp7Cgl1X2FscGhhX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC54OwoJdV9zcGFya2xlX2FscGhhX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC55OwoJdV9ibHVyX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC56OwoJdV9yYWRpdXNfc2NhbGVfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLnc7CglmbG9hdDIgcCA9IEZMVF9mbHV0dGVyX2xvY2FsX0ZsdXR0ZXJGcmFnQ29vcmRfUzFfYzAoKTsKCWZsb2F0MiB1dl8xID0gcCAqIHVfcmVzb2x1dGlvbl9zY2FsZV9TMV9jMDsKCWZsb2F0MiBkZW5zaXR5X3V2ID0gdXZfMSAtIG1vZChwLCB1X25vaXNlX3NjYWxlX1MxX2MwKTsKCWZsb2F0IHJhZGl1cyA9IHVfbWF4X3JhZGl1c19TMV9jMCAqIHVfcmFkaXVzX3NjYWxlX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzEzID0gdXZfMTsKCWZsb2F0IHR1cmJ1bGVuY2UgPSBGTFRfZmx1dHRlcl9sb2NhbF90dXJidWxlbmNlX1MxX2MwKHBhcmFtXzEzKTsKCWZsb2F0MiBwYXJhbV8xNCA9IHA7CglmbG9hdDIgcGFyYW1fMTUgPSB1X2NlbnRlcl9TMV9jMDsKCWZsb2F0IHBhcmFtXzE2ID0gcmFkaXVzOwoJZmxvYXQgcGFyYW1fMTcgPSAwLjA1ICogdV9tYXhfcmFkaXVzX1MxX2MwOwoJZmxvYXQgcGFyYW1fMTggPSB1X2JsdXJfUzFfYzA7CglmbG9hdCByaW5nID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9yaW5nX1MxX2MwKHBhcmFtXzE0LCBwYXJhbV8xNSwgcGFyYW1fMTYsIHBhcmFtXzE3LCBwYXJhbV8xOCk7CglmbG9hdDIgcGFyYW1fMTkgPSBkZW5zaXR5X3V2OwoJZmxvYXQgcGFyYW1fMjAgPSB1X25vaXNlX3BoYXNlX1MxX2MwOwoJZmxvYXQgc3BhcmtsZSA9ICgoRkxUX2ZsdXR0ZXJfbG9jYWxfc3BhcmtsZV9TMV9jMChwYXJhbV8xOSwgcGFyYW1fMjApICogcmluZykgKiB0dXJidWxlbmNlKSAqIHVfc3BhcmtsZV9hbHBoYV9TMV9jMDsKCWZsb2F0MiBwYXJhbV8yMSA9IHA7CglmbG9hdDIgcGFyYW1fMjIgPSB1X2NlbnRlcl9TMV9jMDsKCWZsb2F0IHBhcmFtXzIzID0gcmFkaXVzOwoJZmxvYXQgcGFyYW1fMjQgPSB1X2JsdXJfUzFfYzA7CglmbG9hdCB3YXZlX2FscGhhID0gKEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtXzIxLCBwYXJhbV8yMiwgcGFyYW1fMjMsIHBhcmFtXzI0KSAqIHVfYWxwaGFfUzFfYzApICogdV9jb2xvcl9TMV9jMC53OwoJZmxvYXQ0IHdhdmVfY29sb3IgPSBmbG9hdDQodV9jb2xvcl9TMV9jMC54eXogKiB3YXZlX2FscGhhLCB3YXZlX2FscGhhKTsKCWZyYWdDb2xvcl9TMV9jMCA9IG1peCh3YXZlX2NvbG9yLCBmbG9hdDQoMS4wKSwgZmxvYXQ0KHNwYXJrbGUpKTsKfQpoYWxmNCBydW50aW1lX3NoYWRlcl9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzBfaW5Db2xvciA9IF9pbnB1dDsKCWZsb2F0MiBfdG1wXzFfY29vcmRzID0gdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CglmbHV0dGVyX0ZyYWdDb29yZF9TMV9jMCA9IGZsb2F0NChfdG1wXzFfY29vcmRzLCAwLjAsIDAuMCk7CglGTFRfbWFpbl9TMV9jMCgpOwoJcmV0dXJuIGhhbGY0KGhhbGY0KGZyYWdDb2xvcl9TMV9jMCkpOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gcnVudGltZV9zaGFkZXJfUzFfYzAoX2lucHV0KTsKfQpoYWxmNCBUZXh0dXJlRWZmZWN0X1MyX2MwX2MwX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzIsIHZUcmFuc2Zvcm1lZENvb3Jkc182X1MwKS4wMDByOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMl9jMF9jMChoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gVGV4dHVyZUVmZmVjdF9TMl9jMF9jMF9jMChfaW5wdXQpOwp9CmhhbGY0IERldmljZVNwYWNlX1MyX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBNYXRyaXhFZmZlY3RfUzJfYzBfYzAoX2lucHV0KTsKfQpoYWxmNCBSZWN0X1MyX2MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMl9pbkNvbG9yID0gX2lucHV0OwoJaGFsZiBjb3ZlcmFnZTsKCWlmIChpbnQoMSkgPT0ga0ZpbGxCV19TMl9jMV9jMCB8fCBpbnQoMSkgPT0ga0ludmVyc2VGaWxsQldfUzJfYzFfYzApIAoJewoJCWNvdmVyYWdlID0gaGFsZihhbGwoZ3JlYXRlclRoYW4oZmxvYXQ0KHNrX0ZyYWdDb29yZC54eSwgdXJlY3RVbmlmb3JtX1MyX2MxX2MwLnp3KSwgZmxvYXQ0KHVyZWN0VW5pZm9ybV9TMl9jMV9jMC54eSwgc2tfRnJhZ0Nvb3JkLnh5KSkpKTsKCX0KCWVsc2UgCgl7CgkJaGFsZjQgZGlzdHM0ID0gc2F0dXJhdGUoaGFsZjQoMS4wLCAxLjAsIC0xLjAsIC0xLjApICogaGFsZjQoc2tfRnJhZ0Nvb3JkLnh5eHkgLSB1cmVjdFVuaWZvcm1fUzJfYzFfYzApKTsKCQloYWxmMiBkaXN0czIgPSAoZGlzdHM0Lnh5ICsgZGlzdHM0Lnp3KSAtIDEuMDsKCQljb3ZlcmFnZSA9IGRpc3RzMi54ICogZGlzdHMyLnk7Cgl9CglpZiAoaW50KDEpID09IGtJbnZlcnNlRmlsbEJXX1MyX2MxX2MwIHx8IGludCgxKSA9PSBrSW52ZXJzZUZpbGxBQV9TMl9jMV9jMCkgCgl7CgkJY292ZXJhZ2UgPSAxLjAgLSBjb3ZlcmFnZTsKCX0KCXJldHVybiBoYWxmNChoYWxmNChjb3ZlcmFnZSkpOwp9CmhhbGY0IEJsZW5kX1MyX2MxKGhhbGY0IF9zcmMsIGhhbGY0IF9kc3QpIAp7CglyZXR1cm4gYmxlbmRfbW9kdWxhdGUoUmVjdF9TMl9jMV9jMChfc3JjKSwgX3NyYyk7Cn0KaGFsZjQgQmxlbmRfUzIoaGFsZjQgX3NyYywgaGFsZjQgX2RzdCkgCnsKCXJldHVybiBibGVuZF9kc3RfaW4oRGV2aWNlU3BhY2VfUzJfYzAoX3NyYyksIEJsZW5kX1MyX2MxKF9zcmMsIF9kc3QpKTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJZmxvYXQgY292ZXJhZ2UgPSB2Y292ZXJhZ2VfUzA7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGNvdmVyYWdlKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IE1hdHJpeEVmZmVjdF9TMShvdXRwdXRDb2xvcl9TMCk7CgloYWxmNCBvdXRwdXRfUzI7CglvdXRwdXRfUzIgPSBCbGVuZF9TMihvdXRwdXRDb3ZlcmFnZV9TMCwgaGFsZjQoMSkpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dF9TMjsKCX0KfQoAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAAcG9zaXRpb24IAAAAY292ZXJhZ2UFAAAAY29sb3IAAAAKAAAAbG9jYWxDb29yZAAAAAAAAA==","G2QACAAAABAAADAAAIOAAAAADIIAAIRODAAP577774DSAIAA737777YBAAAAAAAAAAADAAYAAAACAAAAAAACCAYAAA":"DAAAAExTS1PqAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgcG9zaXRpb247CmluIGZsb2F0IGNvdmVyYWdlOwppbiBoYWxmNCBjb2xvcjsKaW4gZmxvYXQ0IGdlb21TdWJzZXQ7Cm5vcGVyc3BlY3RpdmUgb3V0IGhhbGY0IHZjb2xvcl9TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQgdmNvdmVyYWdlX1MwOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDQgdmdlb21TdWJzZXRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQyIHBvc2l0aW9uID0gcG9zaXRpb24ueHk7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCXZjb3ZlcmFnZV9TMCA9IGNvdmVyYWdlOwoJdmdlb21TdWJzZXRfUzAgPSBnZW9tU3Vic2V0OwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAQAAAKQCAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQgdmNvdmVyYWdlX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0NCB2Z2VvbVN1YnNldF9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWZsb2F0IGNvdmVyYWdlID0gdmNvdmVyYWdlX1MwOwoJZmxvYXQ0IGdlb1N1YnNldDsKCWdlb1N1YnNldCA9IHZnZW9tU3Vic2V0X1MwOwoJZmxvYXQ0IGRpc3RzNCA9IHNhdHVyYXRlKGZsb2F0NCgxLCAxLCAtMSwgLTEpICogKHNrX0ZyYWdDb29yZC54eXh5IC0gZ2VvU3Vic2V0KSk7CglmbG9hdDIgZGlzdHMyID0gZGlzdHM0Lnh5ICsgZGlzdHM0Lnp3IC0gMTsKCWNvdmVyYWdlID0gbWluKGNvdmVyYWdlLCBkaXN0czIueCAqIGRpc3RzMi55KTsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoY292ZXJhZ2UpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAAcG9zaXRpb24IAAAAY292ZXJhZ2UFAAAAY29sb3IAAAAKAAAAZ2VvbVN1YnNldAAAAAAAAA==","AYQA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAAAAB3QA6AAAEAAAAAAAMAAPEAEAAABAAAAAABTAAAAAAACAAAAAEBSAAAA":"DAAAAExTS1MlAgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0NCB1bG9jYWxNYXRyaXhfUzA7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiBmbG9hdDQgaW5DaXJjbGVFZGdlOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIENpcmNsZUdlb21ldHJ5UHJvY2Vzc29yCgl2aW5DaXJjbGVFZGdlX1MwID0gaW5DaXJjbGVFZGdlOwoJdmluQ29sb3JfUzAgPSBpbkNvbG9yOwoJZmxvYXQyIF90bXBfMF9pblBvc2l0aW9uID0gaW5Qb3NpdGlvbjsKCWZsb2F0MiBfdG1wXzFfaW5Qb3NpdGlvbiA9IHVsb2NhbE1hdHJpeF9TMC54eiAqIGluUG9zaXRpb24gKyB1bG9jYWxNYXRyaXhfUzAueXc7Cglza19Qb3NpdGlvbiA9IF90bXBfMF9pblBvc2l0aW9uLnh5MDE7Cn0KAAAAAQAAAHcFAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CnVuaWZvcm0gZmxvYXQ0IHVpbm5lclJlY3RfUzI7CnVuaWZvcm0gaGFsZjIgdXJhZGl1c1BsdXNIYWxmX1MyOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0NCB2aW5DaXJjbGVFZGdlX1MwOwpub3BlcnNwZWN0aXZlIGluIGhhbGY0IHZpbkNvbG9yX1MwOwpoYWxmNCBDaXJjdWxhclJSZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCWZsb2F0MiBkeHkwID0gdWlubmVyUmVjdF9TMS5MVCAtIHNrX0ZyYWdDb29yZC54eTsKCWZsb2F0MiBkeHkxID0gc2tfRnJhZ0Nvb3JkLnh5IC0gdWlubmVyUmVjdF9TMS5SQjsKCWZsb2F0MiBkeHkgPSBtYXgobWF4KGR4eTAsIGR4eTEpLCAwLjApOwoJaGFsZiBhbHBoYSA9IGhhbGYoc2F0dXJhdGUodXJhZGl1c1BsdXNIYWxmX1MxLnggLSBsZW5ndGgoZHh5KSkpOwoJYWxwaGEgPSAxLjAgLSBhbHBoYTsKCXJldHVybiBfaW5wdXQgKiBhbHBoYTsKfQpoYWxmNCBDaXJjdWxhclJSZWN0X1MyKGhhbGY0IF9pbnB1dCkgCnsKCWZsb2F0MiBkeHkwID0gdWlubmVyUmVjdF9TMi5MVCAtIHNrX0ZyYWdDb29yZC54eTsKCWZsb2F0MiBkeHkxID0gc2tfRnJhZ0Nvb3JkLnh5IC0gdWlubmVyUmVjdF9TMi5SQjsKCWZsb2F0MiBkeHkgPSBtYXgobWF4KGR4eTAsIGR4eTEpLCAwLjApOwoJaGFsZiBhbHBoYSA9IGhhbGYoc2F0dXJhdGUodXJhZGl1c1BsdXNIYWxmX1MyLnggLSBsZW5ndGgoZHh5KSkpOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQ0IGNpcmNsZUVkZ2U7CgljaXJjbGVFZGdlID0gdmluQ2lyY2xlRWRnZV9TMDsKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWZsb2F0IGQgPSBsZW5ndGgoY2lyY2xlRWRnZS54eSk7CgloYWxmIGRpc3RhbmNlVG9PdXRlckVkZ2UgPSBoYWxmKGNpcmNsZUVkZ2UueiAqICgxLjAgLSBkKSk7CgloYWxmIGVkZ2VBbHBoYSA9IHNhdHVyYXRlKGRpc3RhbmNlVG9PdXRlckVkZ2UpOwoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChlZGdlQWxwaGEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQ2lyY3VsYXJSUmVjdF9TMShvdXRwdXRDb3ZlcmFnZV9TMCk7CgloYWxmNCBvdXRwdXRfUzI7CglvdXRwdXRfUzIgPSBDaXJjdWxhclJSZWN0X1MyKG91dHB1dF9TMSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzI7Cgl9Cn0KAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACgAAAGluUG9zaXRpb24AAAcAAABpbkNvbG9yAAwAAABpbkNpcmNsZUVkZ2UAAAAA","EADQAAAAAEAAAAAUAABQAAQPAAABCFYMAAKAUEAAAAAAAAABAAAAAAAAAAAJQAIAAAABAAAAACAJAAIAAAAA":"DAAAAExTS1NtAgAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQyIHVBdGxhc0RpbWVuc2lvbnNJbnZfUzA7CmluIGZsb2F0MyBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiB1c2hvcnQyIGluVGV4dHVyZUNvb3JkczsKb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKb3V0IGZsb2F0IHZUZXhJbmRleF9TMDsKb3V0IGZsb2F0MiB2SW50VGV4dHVyZUNvb3Jkc19TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBEaXN0YW5jZUZpZWxkUGF0aAoJaW50IHRleElkeCA9IDA7CglmbG9hdDIgdW5vcm1UZXhDb29yZHMgPSBmbG9hdDIoaW5UZXh0dXJlQ29vcmRzLngsIGluVGV4dHVyZUNvb3Jkcy55KTsKCXZUZXh0dXJlQ29vcmRzX1MwID0gdW5vcm1UZXhDb29yZHMgKiB1QXRsYXNEaW1lbnNpb25zSW52X1MwOwoJdlRleEluZGV4X1MwID0gZmxvYXQodGV4SWR4KTsKCXZJbnRUZXh0dXJlQ29vcmRzX1MwID0gdW5vcm1UZXhDb29yZHM7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDMgX3RtcF8xX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBpblBvc2l0aW9uLnh5MHo7Cn0KAAAAAAAAAJICAABzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzA7CmluIGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKaW4gZmxvYXQgdlRleEluZGV4X1MwOwppbiBmbG9hdDIgdkludFRleHR1cmVDb29yZHNfUzA7CmluIGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgRGlzdGFuY2VGaWVsZFBhdGgKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWZsb2F0MiB1diA9IHZUZXh0dXJlQ29vcmRzX1MwOwoJaGFsZjQgdGV4Q29sb3I7Cgl7CgkJdGV4Q29sb3IgPSBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzAsIHV2KS5ycnJyOwoJfQoJaGFsZiBkaXN0YW5jZSA9IDcuOTY4NzUqKHRleENvbG9yLnIgLSAwLjUwMTk2MDc4NDMxKTsKCWhhbGYgYWZ3aWR0aDsKCWFmd2lkdGggPSBhYnMoMC42NSpoYWxmKGRGZHgodkludFRleHR1cmVDb29yZHNfUzAueCkpKTsKCWhhbGYgdmFsID0gc21vb3Roc3RlcCgtYWZ3aWR0aCwgYWZ3aWR0aCwgZGlzdGFuY2UpOwoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCh2YWwpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAoAAABpblBvc2l0aW9uAAAHAAAAaW5Db2xvcgAPAAAAaW5UZXh0dXJlQ29vcmRzAAAAAAA=","GZIACAAAABQAAGAAAQ4AAAAAGQQAARC4GAAAIOCAAD6P7777777777YDAAAAAAAAAAAJQBBYGQ467YIAAAAAAQAAAAAMACTRNBZN5QYBAAAAAAAAAAAIAALIAAAAB4FJEIEKOAAAAAMAAAAAEAHQAACAAAAAAYCFPSVARQRJAAAAABQAAAAAAAAAAA4JAPAAACAAAAAAACABSAAAAAAACAAAAAEBSAAA":"DAAAAExTS1M7AgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQgY292ZXJhZ2U7CmluIGhhbGY0IGNvbG9yOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdCB2Y292ZXJhZ2VfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDIgcG9zaXRpb24gPSBwb3NpdGlvbi54eTsKCXZjb2xvcl9TMCA9IGNvbG9yOwoJdmNvdmVyYWdlX1MwID0gY292ZXJhZ2U7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgABAAAANCEAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQpmbG9hdDQgZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzA7CmZsb2F0NCBmcmFnQ29sb3JfUzFfYzA7CmZsb2F0IHVfYWxwaGFfUzFfYzA7CmZsb2F0IHVfc3BhcmtsZV9hbHBoYV9TMV9jMDsKZmxvYXQgdV9ibHVyX1MxX2MwOwpmbG9hdCB1X3JhZGl1c19zY2FsZV9TMV9jMDsKY29uc3QgaW50IGtGaWxsQldfUzJfYzAgPSAwOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQldfUzJfYzAgPSAyOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQUFfUzJfYzAgPSAzOwp1bmlmb3JtIGZsb2F0NCB1X2NvbG9yX1MxX2MwOwp1bmlmb3JtIGZsb2F0NCB1X2NvbXBvc2l0ZV8xX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NlbnRlcl9TMV9jMDsKdW5pZm9ybSBmbG9hdCB1X21heF9yYWRpdXNfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcmVzb2x1dGlvbl9zY2FsZV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9ub2lzZV9zY2FsZV9TMV9jMDsKdW5pZm9ybSBmbG9hdCB1X25vaXNlX3BoYXNlX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NpcmNsZTFfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2lyY2xlMl9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jaXJjbGUzX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3JvdGF0aW9uMV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yb3RhdGlvbjJfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcm90YXRpb24zX1MxX2MwOwp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CnVuaWZvcm0gZmxvYXQ0IHVyZWN0VW5pZm9ybV9TMl9jMDsKdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMl9jMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzJfYzE7Cm5vcGVyc3BlY3RpdmUgaW4gaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0IHZjb3ZlcmFnZV9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CmZsb2F0MiBGTFRfZmx1dHRlcl9sb2NhbF9GbHV0dGVyRnJhZ0Nvb3JkX1MxX2MwKCk7CmZsb2F0MngyIEZMVF9mbHV0dGVyX2xvY2FsX3JvdGF0ZTJkX1MxX2MwKGZsb2F0MiByYWQpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCBibHVyKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAoZmxvYXQyIHJlc29sdXRpb24sIGlub3V0IGZsb2F0MiBwLCBmbG9hdDIgeHksIGZsb2F0MiByb3RhdGlvbiwgZmxvYXQgY2VsbF9kaWFtZXRlcik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3R1cmJ1bGVuY2VfUzFfYzAoZmxvYXQyIHV2KTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9yaW5nX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IHRoaWNrbmVzcywgZmxvYXQgYmx1cik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RyaWFuZ2xlX25vaXNlX1MxX2MwKGlub3V0IGZsb2F0MiBuKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKGZsb2F0IHYsIGZsb2F0IGwsIGZsb2F0IGgpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zcGFya2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQgdCk7CnZvaWQgRkxUX21haW5fUzFfYzAoKTsKZmxvYXQyIEZMVF9mbHV0dGVyX2xvY2FsX0ZsdXR0ZXJGcmFnQ29vcmRfUzFfYzAoKSAKewoJcmV0dXJuIGZsdXR0ZXJfRnJhZ0Nvb3JkX1MxX2MwLnh5Owp9CmZsb2F0MngyIEZMVF9mbHV0dGVyX2xvY2FsX3JvdGF0ZTJkX1MxX2MwKGZsb2F0MiByYWQpIAp7CglyZXR1cm4gZmxvYXQyeDIocmFkLngsIC1yYWQueSwgcmFkLnksIHJhZC54KTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCBibHVyKSAKewoJZmxvYXQgYmx1cl9oYWxmID0gYmx1ciAqIDAuNTsKCWZsb2F0IGQgPSBkaXN0YW5jZSh1diwgeHkpOwoJcmV0dXJuIDEuMCAtIHNtb290aHN0ZXAoMS4wIC0gYmx1cl9oYWxmLCAxLjAgKyBibHVyX2hhbGYsIGQgLyByYWRpdXMpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKGZsb2F0MiByZXNvbHV0aW9uLCBpbm91dCBmbG9hdDIgcCwgZmxvYXQyIHh5LCBmbG9hdDIgcm90YXRpb24sIGZsb2F0IGNlbGxfZGlhbWV0ZXIpIAp7CglmbG9hdDIgcGFyYW0gPSByb3RhdGlvbjsKCXAgPSBGTFRfZmx1dHRlcl9sb2NhbF9yb3RhdGUyZF9TMV9jMChwYXJhbSkgKiAoeHkgLSBwKSArIHh5OwoJcCA9IG1vZChwLCBmbG9hdDIoY2VsbF9kaWFtZXRlcikpIC8gcmVzb2x1dGlvbjsKCWZsb2F0IGNlbGxfdXYgPSAoY2VsbF9kaWFtZXRlciAvIHJlc29sdXRpb24ueSkgKiAwLjU7CglmbG9hdCByID0gMC42NSAqIGNlbGxfdXY7CglmbG9hdDIgcGFyYW1fMSA9IHA7CglmbG9hdDIgcGFyYW1fMiA9IGZsb2F0MihjZWxsX3V2KTsKCWZsb2F0IHBhcmFtXzMgPSByOwoJZmxvYXQgcGFyYW1fNCA9IHIgKiA1MC4wOwoJcmV0dXJuIEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMsIHBhcmFtXzQpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3R1cmJ1bGVuY2VfUzFfYzAoZmxvYXQyIHV2KSAKewoJZmxvYXQyIHV2X3NjYWxlID0gdXYgKiBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbSA9IGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtXzEgPSB1dl9zY2FsZTsKCWZsb2F0MiBwYXJhbV8yID0gdV9jaXJjbGUxX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzMgPSB1X3JvdGF0aW9uMV9TMV9jMDsKCWZsb2F0IHBhcmFtXzQgPSAwLjE3OwoJZmxvYXQgXzMxOSA9IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKHBhcmFtLCBwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zLCBwYXJhbV80KTsKCWZsb2F0IGcxID0gXzMxOTsKCWZsb2F0MiBwYXJhbV81ID0gZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW1fNiA9IHV2X3NjYWxlOwoJZmxvYXQyIHBhcmFtXzcgPSB1X2NpcmNsZTJfUzFfYzA7CglmbG9hdDIgcGFyYW1fOCA9IHVfcm90YXRpb24yX1MxX2MwOwoJZmxvYXQgcGFyYW1fOSA9IDAuMjsKCWZsb2F0IF8zMzEgPSBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChwYXJhbV81LCBwYXJhbV82LCBwYXJhbV83LCBwYXJhbV84LCBwYXJhbV85KTsKCWZsb2F0IGcyID0gXzMzMTsKCWZsb2F0MiBwYXJhbV8xMCA9IGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtXzExID0gdXZfc2NhbGU7CglmbG9hdDIgcGFyYW1fMTIgPSB1X2NpcmNsZTNfUzFfYzA7CglmbG9hdDIgcGFyYW1fMTMgPSB1X3JvdGF0aW9uM19TMV9jMDsKCWZsb2F0IHBhcmFtXzE0ID0gMC4yNzU7CglmbG9hdCBfMzQ0ID0gRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAocGFyYW1fMTAsIHBhcmFtXzExLCBwYXJhbV8xMiwgcGFyYW1fMTMsIHBhcmFtXzE0KTsKCWZsb2F0IGczID0gXzM0NDsKCWZsb2F0IHYgPSAoKGcxICogZzEgKyBnMikgLSBnMykgKiAwLjU7CglyZXR1cm4gY2xhbXAoMC40NSArIDAuOCAqIHYsIDAuMCwgMS4wKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X3JpbmdfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgdGhpY2tuZXNzLCBmbG9hdCBibHVyKSAKewoJZmxvYXQyIHBhcmFtID0gdXY7CglmbG9hdDIgcGFyYW1fMSA9IHh5OwoJZmxvYXQgcGFyYW1fMiA9IHJhZGl1cyArIHRoaWNrbmVzczsKCWZsb2F0IHBhcmFtXzMgPSBibHVyOwoJZmxvYXQgY2lyY2xlX291dGVyID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW0sIHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMpOwoJZmxvYXQyIHBhcmFtXzQgPSB1djsKCWZsb2F0MiBwYXJhbV81ID0geHk7CglmbG9hdCBwYXJhbV82ID0gbWF4KHJhZGl1cyAtIHRoaWNrbmVzcywgMC4wKTsKCWZsb2F0IHBhcmFtXzcgPSBibHVyOwoJZmxvYXQgY2lyY2xlX2lubmVyID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW1fNCwgcGFyYW1fNSwgcGFyYW1fNiwgcGFyYW1fNyk7CglyZXR1cm4gY2xhbXAoY2lyY2xlX291dGVyIC0gY2lyY2xlX2lubmVyLCAwLjAsIDEuMCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHJpYW5nbGVfbm9pc2VfUzFfYzAoaW5vdXQgZmxvYXQyIG4pIAp7CgluID0gZnJhY3QobiAqIGZsb2F0Mig1LjM5ODcsIDUuNDQyMSkpOwoJbiArPSBmbG9hdDIoZG90KG4ueXgsIG4gKyBmbG9hdDIoMjEuNTM1MSwgMTQuMzEzNykpKTsKCWZsb2F0IHh5ID0gbi54ICogbi55OwoJcmV0dXJuIChmcmFjdCh4eSAqIDk1LjQzMDcpICsgZnJhY3QoeHkgKiA3NS4wNDk2MSkpIC0gMS4wOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChmbG9hdCB2LCBmbG9hdCBsLCBmbG9hdCBoKSAKewoJcmV0dXJuIHN0ZXAobCwgdikgKiAoMS4wIC0gc3RlcChoLCB2KSk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc3BhcmtsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0IHQpIAp7CglmbG9hdDIgcGFyYW0gPSB1djsKCWZsb2F0IF8yNDIgPSBGTFRfZmx1dHRlcl9sb2NhbF90cmlhbmdsZV9ub2lzZV9TMV9jMChwYXJhbSk7CglmbG9hdCBuID0gXzI0MjsKCWZsb2F0IHBhcmFtXzEgPSBuOwoJZmxvYXQgcGFyYW1fMiA9IDAuMDsKCWZsb2F0IHBhcmFtXzMgPSAwLjA1OwoJZmxvYXQgcyA9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zKTsKCWZsb2F0IHBhcmFtXzQgPSBuICsgc2luKDMuMTQxNTkyNzQgKiAodCArIDAuMzUpKTsKCWZsb2F0IHBhcmFtXzUgPSAwLjE7CglmbG9hdCBwYXJhbV82ID0gMC4xNTsKCXMgKz0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzQsIHBhcmFtXzUsIHBhcmFtXzYpOwoJZmxvYXQgcGFyYW1fNyA9IG4gKyBzaW4oMy4xNDE1OTI3NCAqICh0ICsgMC43KSk7CglmbG9hdCBwYXJhbV84ID0gMC4yOwoJZmxvYXQgcGFyYW1fOSA9IDAuMjU7CglzICs9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV83LCBwYXJhbV84LCBwYXJhbV85KTsKCWZsb2F0IHBhcmFtXzEwID0gbiArIHNpbigzLjE0MTU5Mjc0ICogKHQgKyAxLjA1KSk7CglmbG9hdCBwYXJhbV8xMSA9IDAuMzsKCWZsb2F0IHBhcmFtXzEyID0gMC4zNTsKCXMgKz0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzEwLCBwYXJhbV8xMSwgcGFyYW1fMTIpOwoJcmV0dXJuIGNsYW1wKHMsIDAuMCwgMS4wKSAqIDAuNTU7Cn0Kdm9pZCBGTFRfbWFpbl9TMV9jMCgpIAp7Cgl1X2FscGhhX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC54OwoJdV9zcGFya2xlX2FscGhhX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC55OwoJdV9ibHVyX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC56OwoJdV9yYWRpdXNfc2NhbGVfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLnc7CglmbG9hdDIgcCA9IEZMVF9mbHV0dGVyX2xvY2FsX0ZsdXR0ZXJGcmFnQ29vcmRfUzFfYzAoKTsKCWZsb2F0MiB1dl8xID0gcCAqIHVfcmVzb2x1dGlvbl9zY2FsZV9TMV9jMDsKCWZsb2F0MiBkZW5zaXR5X3V2ID0gdXZfMSAtIG1vZChwLCB1X25vaXNlX3NjYWxlX1MxX2MwKTsKCWZsb2F0IHJhZGl1cyA9IHVfbWF4X3JhZGl1c19TMV9jMCAqIHVfcmFkaXVzX3NjYWxlX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzEzID0gdXZfMTsKCWZsb2F0IHR1cmJ1bGVuY2UgPSBGTFRfZmx1dHRlcl9sb2NhbF90dXJidWxlbmNlX1MxX2MwKHBhcmFtXzEzKTsKCWZsb2F0MiBwYXJhbV8xNCA9IHA7CglmbG9hdDIgcGFyYW1fMTUgPSB1X2NlbnRlcl9TMV9jMDsKCWZsb2F0IHBhcmFtXzE2ID0gcmFkaXVzOwoJZmxvYXQgcGFyYW1fMTcgPSAwLjA1ICogdV9tYXhfcmFkaXVzX1MxX2MwOwoJZmxvYXQgcGFyYW1fMTggPSB1X2JsdXJfUzFfYzA7CglmbG9hdCByaW5nID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9yaW5nX1MxX2MwKHBhcmFtXzE0LCBwYXJhbV8xNSwgcGFyYW1fMTYsIHBhcmFtXzE3LCBwYXJhbV8xOCk7CglmbG9hdDIgcGFyYW1fMTkgPSBkZW5zaXR5X3V2OwoJZmxvYXQgcGFyYW1fMjAgPSB1X25vaXNlX3BoYXNlX1MxX2MwOwoJZmxvYXQgc3BhcmtsZSA9ICgoRkxUX2ZsdXR0ZXJfbG9jYWxfc3BhcmtsZV9TMV9jMChwYXJhbV8xOSwgcGFyYW1fMjApICogcmluZykgKiB0dXJidWxlbmNlKSAqIHVfc3BhcmtsZV9hbHBoYV9TMV9jMDsKCWZsb2F0MiBwYXJhbV8yMSA9IHA7CglmbG9hdDIgcGFyYW1fMjIgPSB1X2NlbnRlcl9TMV9jMDsKCWZsb2F0IHBhcmFtXzIzID0gcmFkaXVzOwoJZmxvYXQgcGFyYW1fMjQgPSB1X2JsdXJfUzFfYzA7CglmbG9hdCB3YXZlX2FscGhhID0gKEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtXzIxLCBwYXJhbV8yMiwgcGFyYW1fMjMsIHBhcmFtXzI0KSAqIHVfYWxwaGFfUzFfYzApICogdV9jb2xvcl9TMV9jMC53OwoJZmxvYXQ0IHdhdmVfY29sb3IgPSBmbG9hdDQodV9jb2xvcl9TMV9jMC54eXogKiB3YXZlX2FscGhhLCB3YXZlX2FscGhhKTsKCWZyYWdDb2xvcl9TMV9jMCA9IG1peCh3YXZlX2NvbG9yLCBmbG9hdDQoMS4wKSwgZmxvYXQ0KHNwYXJrbGUpKTsKfQpoYWxmNCBydW50aW1lX3NoYWRlcl9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzBfaW5Db2xvciA9IF9pbnB1dDsKCWZsb2F0MiBfdG1wXzFfY29vcmRzID0gdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CglmbHV0dGVyX0ZyYWdDb29yZF9TMV9jMCA9IGZsb2F0NChfdG1wXzFfY29vcmRzLCAwLjAsIDAuMCk7CglGTFRfbWFpbl9TMV9jMCgpOwoJcmV0dXJuIGhhbGY0KGhhbGY0KGZyYWdDb2xvcl9TMV9jMCkpOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gcnVudGltZV9zaGFkZXJfUzFfYzAoX2lucHV0KTsKfQpoYWxmNCBSZWN0X1MyX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMl9pbkNvbG9yID0gX2lucHV0OwoJaGFsZiBjb3ZlcmFnZTsKCWlmIChpbnQoMSkgPT0ga0ZpbGxCV19TMl9jMCB8fCBpbnQoMSkgPT0ga0ludmVyc2VGaWxsQldfUzJfYzApIAoJewoJCWNvdmVyYWdlID0gaGFsZihhbGwoZ3JlYXRlclRoYW4oZmxvYXQ0KHNrX0ZyYWdDb29yZC54eSwgdXJlY3RVbmlmb3JtX1MyX2MwLnp3KSwgZmxvYXQ0KHVyZWN0VW5pZm9ybV9TMl9jMC54eSwgc2tfRnJhZ0Nvb3JkLnh5KSkpKTsKCX0KCWVsc2UgCgl7CgkJaGFsZjQgZGlzdHM0ID0gc2F0dXJhdGUoaGFsZjQoMS4wLCAxLjAsIC0xLjAsIC0xLjApICogaGFsZjQoc2tfRnJhZ0Nvb3JkLnh5eHkgLSB1cmVjdFVuaWZvcm1fUzJfYzApKTsKCQloYWxmMiBkaXN0czIgPSAoZGlzdHM0Lnh5ICsgZGlzdHM0Lnp3KSAtIDEuMDsKCQljb3ZlcmFnZSA9IGRpc3RzMi54ICogZGlzdHMyLnk7Cgl9CglpZiAoaW50KDEpID09IGtJbnZlcnNlRmlsbEJXX1MyX2MwIHx8IGludCgxKSA9PSBrSW52ZXJzZUZpbGxBQV9TMl9jMCkgCgl7CgkJY292ZXJhZ2UgPSAxLjAgLSBjb3ZlcmFnZTsKCX0KCXJldHVybiBoYWxmNChoYWxmNChjb3ZlcmFnZSkpOwp9CmhhbGY0IENpcmN1bGFyUlJlY3RfUzJfYzEoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MyX2MxLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MyX2MxLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CgloYWxmIGFscGhhID0gaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzJfYzEueCAtIGxlbmd0aChkeHkpKSk7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0KaGFsZjQgQmxlbmRfUzIoaGFsZjQgX3NyYywgaGFsZjQgX2RzdCkgCnsKCXJldHVybiBibGVuZF9tb2R1bGF0ZShSZWN0X1MyX2MwKF9zcmMpLCBDaXJjdWxhclJSZWN0X1MyX2MxKF9zcmMpKTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJZmxvYXQgY292ZXJhZ2UgPSB2Y292ZXJhZ2VfUzA7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGNvdmVyYWdlKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IE1hdHJpeEVmZmVjdF9TMShvdXRwdXRDb2xvcl9TMCk7CgloYWxmNCBvdXRwdXRfUzI7CglvdXRwdXRfUzIgPSBCbGVuZF9TMihvdXRwdXRDb3ZlcmFnZV9TMCwgaGFsZjQoMSkpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dF9TMjsKCX0KfQoBAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAgAAABwb3NpdGlvbggAAABjb3ZlcmFnZQUAAABjb2xvcgAAAAoAAABsb2NhbENvb3JkAAAAAAAA","GZIACAAAABQAAGAAAQ4AAAAAGQQAARC4GAAAIOCAAD6P7777777777YDAAAAAAAAAAAJQBBYGQ467YIAAAAAAQAAAAAMACTRNBZN5QYBAAAAAAAAAAAIAA4IAEAAACAAAAAABGABAAAAAEAAAAAIBEABAA":"DAAAAExTS1M7AgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQgY292ZXJhZ2U7CmluIGhhbGY0IGNvbG9yOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdCB2Y292ZXJhZ2VfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDIgcG9zaXRpb24gPSBwb3NpdGlvbi54eTsKCXZjb2xvcl9TMCA9IGNvbG9yOwoJdmNvdmVyYWdlX1MwID0gY292ZXJhZ2U7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgABAAAAEh4AACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQpmbG9hdDQgZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzA7CmZsb2F0NCBmcmFnQ29sb3JfUzFfYzA7CmZsb2F0IHVfYWxwaGFfUzFfYzA7CmZsb2F0IHVfc3BhcmtsZV9hbHBoYV9TMV9jMDsKZmxvYXQgdV9ibHVyX1MxX2MwOwpmbG9hdCB1X3JhZGl1c19zY2FsZV9TMV9jMDsKdW5pZm9ybSBmbG9hdDQgdV9jb2xvcl9TMV9jMDsKdW5pZm9ybSBmbG9hdDQgdV9jb21wb3NpdGVfMV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jZW50ZXJfUzFfYzA7CnVuaWZvcm0gZmxvYXQgdV9tYXhfcmFkaXVzX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3Jlc29sdXRpb25fc2NhbGVfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfbm9pc2Vfc2NhbGVfUzFfYzA7CnVuaWZvcm0gZmxvYXQgdV9ub2lzZV9waGFzZV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jaXJjbGUxX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NpcmNsZTJfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2lyY2xlM19TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yb3RhdGlvbjFfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcm90YXRpb24yX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3JvdGF0aW9uM19TMV9jMDsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxOwp1bmlmb3JtIGZsb2F0NCB1aW5uZXJSZWN0X1MyOwp1bmlmb3JtIGhhbGYyIHVyYWRpdXNQbHVzSGFsZl9TMjsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQgdmNvdmVyYWdlX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKZmxvYXQyIEZMVF9mbHV0dGVyX2xvY2FsX0ZsdXR0ZXJGcmFnQ29vcmRfUzFfYzAoKTsKZmxvYXQyeDIgRkxUX2ZsdXR0ZXJfbG9jYWxfcm90YXRlMmRfUzFfYzAoZmxvYXQyIHJhZCk7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IGJsdXIpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChmbG9hdDIgcmVzb2x1dGlvbiwgaW5vdXQgZmxvYXQyIHAsIGZsb2F0MiB4eSwgZmxvYXQyIHJvdGF0aW9uLCBmbG9hdCBjZWxsX2RpYW1ldGVyKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHVyYnVsZW5jZV9TMV9jMChmbG9hdDIgdXYpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X3JpbmdfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgdGhpY2tuZXNzLCBmbG9hdCBibHVyKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHJpYW5nbGVfbm9pc2VfUzFfYzAoaW5vdXQgZmxvYXQyIG4pOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAoZmxvYXQgdiwgZmxvYXQgbCwgZmxvYXQgaCk7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NwYXJrbGVfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdCB0KTsKdm9pZCBGTFRfbWFpbl9TMV9jMCgpOwpmbG9hdDIgRkxUX2ZsdXR0ZXJfbG9jYWxfRmx1dHRlckZyYWdDb29yZF9TMV9jMCgpIAp7CglyZXR1cm4gZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzAueHk7Cn0KZmxvYXQyeDIgRkxUX2ZsdXR0ZXJfbG9jYWxfcm90YXRlMmRfUzFfYzAoZmxvYXQyIHJhZCkgCnsKCXJldHVybiBmbG9hdDJ4MihyYWQueCwgLXJhZC55LCByYWQueSwgcmFkLngpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IGJsdXIpIAp7CglmbG9hdCBibHVyX2hhbGYgPSBibHVyICogMC41OwoJZmxvYXQgZCA9IGRpc3RhbmNlKHV2LCB4eSk7CglyZXR1cm4gMS4wIC0gc21vb3Roc3RlcCgxLjAgLSBibHVyX2hhbGYsIDEuMCArIGJsdXJfaGFsZiwgZCAvIHJhZGl1cyk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAoZmxvYXQyIHJlc29sdXRpb24sIGlub3V0IGZsb2F0MiBwLCBmbG9hdDIgeHksIGZsb2F0MiByb3RhdGlvbiwgZmxvYXQgY2VsbF9kaWFtZXRlcikgCnsKCWZsb2F0MiBwYXJhbSA9IHJvdGF0aW9uOwoJcCA9IEZMVF9mbHV0dGVyX2xvY2FsX3JvdGF0ZTJkX1MxX2MwKHBhcmFtKSAqICh4eSAtIHApICsgeHk7CglwID0gbW9kKHAsIGZsb2F0MihjZWxsX2RpYW1ldGVyKSkgLyByZXNvbHV0aW9uOwoJZmxvYXQgY2VsbF91diA9IChjZWxsX2RpYW1ldGVyIC8gcmVzb2x1dGlvbi55KSAqIDAuNTsKCWZsb2F0IHIgPSAwLjY1ICogY2VsbF91djsKCWZsb2F0MiBwYXJhbV8xID0gcDsKCWZsb2F0MiBwYXJhbV8yID0gZmxvYXQyKGNlbGxfdXYpOwoJZmxvYXQgcGFyYW1fMyA9IHI7CglmbG9hdCBwYXJhbV80ID0gciAqIDUwLjA7CglyZXR1cm4gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW1fMSwgcGFyYW1fMiwgcGFyYW1fMywgcGFyYW1fNCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHVyYnVsZW5jZV9TMV9jMChmbG9hdDIgdXYpIAp7CglmbG9hdDIgdXZfc2NhbGUgPSB1diAqIGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtID0gZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW1fMSA9IHV2X3NjYWxlOwoJZmxvYXQyIHBhcmFtXzIgPSB1X2NpcmNsZTFfUzFfYzA7CglmbG9hdDIgcGFyYW1fMyA9IHVfcm90YXRpb24xX1MxX2MwOwoJZmxvYXQgcGFyYW1fNCA9IDAuMTc7CglmbG9hdCBfMzE5ID0gRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAocGFyYW0sIHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMsIHBhcmFtXzQpOwoJZmxvYXQgZzEgPSBfMzE5OwoJZmxvYXQyIHBhcmFtXzUgPSBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbV82ID0gdXZfc2NhbGU7CglmbG9hdDIgcGFyYW1fNyA9IHVfY2lyY2xlMl9TMV9jMDsKCWZsb2F0MiBwYXJhbV84ID0gdV9yb3RhdGlvbjJfUzFfYzA7CglmbG9hdCBwYXJhbV85ID0gMC4yOwoJZmxvYXQgXzMzMSA9IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKHBhcmFtXzUsIHBhcmFtXzYsIHBhcmFtXzcsIHBhcmFtXzgsIHBhcmFtXzkpOwoJZmxvYXQgZzIgPSBfMzMxOwoJZmxvYXQyIHBhcmFtXzEwID0gZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW1fMTEgPSB1dl9zY2FsZTsKCWZsb2F0MiBwYXJhbV8xMiA9IHVfY2lyY2xlM19TMV9jMDsKCWZsb2F0MiBwYXJhbV8xMyA9IHVfcm90YXRpb24zX1MxX2MwOwoJZmxvYXQgcGFyYW1fMTQgPSAwLjI3NTsKCWZsb2F0IF8zNDQgPSBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChwYXJhbV8xMCwgcGFyYW1fMTEsIHBhcmFtXzEyLCBwYXJhbV8xMywgcGFyYW1fMTQpOwoJZmxvYXQgZzMgPSBfMzQ0OwoJZmxvYXQgdiA9ICgoZzEgKiBnMSArIGcyKSAtIGczKSAqIDAuNTsKCXJldHVybiBjbGFtcCgwLjQ1ICsgMC44ICogdiwgMC4wLCAxLjApOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfcmluZ19TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCB0aGlja25lc3MsIGZsb2F0IGJsdXIpIAp7CglmbG9hdDIgcGFyYW0gPSB1djsKCWZsb2F0MiBwYXJhbV8xID0geHk7CglmbG9hdCBwYXJhbV8yID0gcmFkaXVzICsgdGhpY2tuZXNzOwoJZmxvYXQgcGFyYW1fMyA9IGJsdXI7CglmbG9hdCBjaXJjbGVfb3V0ZXIgPSBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChwYXJhbSwgcGFyYW1fMSwgcGFyYW1fMiwgcGFyYW1fMyk7CglmbG9hdDIgcGFyYW1fNCA9IHV2OwoJZmxvYXQyIHBhcmFtXzUgPSB4eTsKCWZsb2F0IHBhcmFtXzYgPSBtYXgocmFkaXVzIC0gdGhpY2tuZXNzLCAwLjApOwoJZmxvYXQgcGFyYW1fNyA9IGJsdXI7CglmbG9hdCBjaXJjbGVfaW5uZXIgPSBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChwYXJhbV80LCBwYXJhbV81LCBwYXJhbV82LCBwYXJhbV83KTsKCXJldHVybiBjbGFtcChjaXJjbGVfb3V0ZXIgLSBjaXJjbGVfaW5uZXIsIDAuMCwgMS4wKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90cmlhbmdsZV9ub2lzZV9TMV9jMChpbm91dCBmbG9hdDIgbikgCnsKCW4gPSBmcmFjdChuICogZmxvYXQyKDUuMzk4NywgNS40NDIxKSk7CgluICs9IGZsb2F0Mihkb3Qobi55eCwgbiArIGZsb2F0MigyMS41MzUxLCAxNC4zMTM3KSkpOwoJZmxvYXQgeHkgPSBuLnggKiBuLnk7CglyZXR1cm4gKGZyYWN0KHh5ICogOTUuNDMwNykgKyBmcmFjdCh4eSAqIDc1LjA0OTYxKSkgLSAxLjA7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKGZsb2F0IHYsIGZsb2F0IGwsIGZsb2F0IGgpIAp7CglyZXR1cm4gc3RlcChsLCB2KSAqICgxLjAgLSBzdGVwKGgsIHYpKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zcGFya2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQgdCkgCnsKCWZsb2F0MiBwYXJhbSA9IHV2OwoJZmxvYXQgXzI0MiA9IEZMVF9mbHV0dGVyX2xvY2FsX3RyaWFuZ2xlX25vaXNlX1MxX2MwKHBhcmFtKTsKCWZsb2F0IG4gPSBfMjQyOwoJZmxvYXQgcGFyYW1fMSA9IG47CglmbG9hdCBwYXJhbV8yID0gMC4wOwoJZmxvYXQgcGFyYW1fMyA9IDAuMDU7CglmbG9hdCBzID0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMpOwoJZmxvYXQgcGFyYW1fNCA9IG4gKyBzaW4oMy4xNDE1OTI3NCAqICh0ICsgMC4zNSkpOwoJZmxvYXQgcGFyYW1fNSA9IDAuMTsKCWZsb2F0IHBhcmFtXzYgPSAwLjE1OwoJcyArPSBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAocGFyYW1fNCwgcGFyYW1fNSwgcGFyYW1fNik7CglmbG9hdCBwYXJhbV83ID0gbiArIHNpbigzLjE0MTU5Mjc0ICogKHQgKyAwLjcpKTsKCWZsb2F0IHBhcmFtXzggPSAwLjI7CglmbG9hdCBwYXJhbV85ID0gMC4yNTsKCXMgKz0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzcsIHBhcmFtXzgsIHBhcmFtXzkpOwoJZmxvYXQgcGFyYW1fMTAgPSBuICsgc2luKDMuMTQxNTkyNzQgKiAodCArIDEuMDUpKTsKCWZsb2F0IHBhcmFtXzExID0gMC4zOwoJZmxvYXQgcGFyYW1fMTIgPSAwLjM1OwoJcyArPSBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAocGFyYW1fMTAsIHBhcmFtXzExLCBwYXJhbV8xMik7CglyZXR1cm4gY2xhbXAocywgMC4wLCAxLjApICogMC41NTsKfQp2b2lkIEZMVF9tYWluX1MxX2MwKCkgCnsKCXVfYWxwaGFfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLng7Cgl1X3NwYXJrbGVfYWxwaGFfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLnk7Cgl1X2JsdXJfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLno7Cgl1X3JhZGl1c19zY2FsZV9TMV9jMCA9IHVfY29tcG9zaXRlXzFfUzFfYzAudzsKCWZsb2F0MiBwID0gRkxUX2ZsdXR0ZXJfbG9jYWxfRmx1dHRlckZyYWdDb29yZF9TMV9jMCgpOwoJZmxvYXQyIHV2XzEgPSBwICogdV9yZXNvbHV0aW9uX3NjYWxlX1MxX2MwOwoJZmxvYXQyIGRlbnNpdHlfdXYgPSB1dl8xIC0gbW9kKHAsIHVfbm9pc2Vfc2NhbGVfUzFfYzApOwoJZmxvYXQgcmFkaXVzID0gdV9tYXhfcmFkaXVzX1MxX2MwICogdV9yYWRpdXNfc2NhbGVfUzFfYzA7CglmbG9hdDIgcGFyYW1fMTMgPSB1dl8xOwoJZmxvYXQgdHVyYnVsZW5jZSA9IEZMVF9mbHV0dGVyX2xvY2FsX3R1cmJ1bGVuY2VfUzFfYzAocGFyYW1fMTMpOwoJZmxvYXQyIHBhcmFtXzE0ID0gcDsKCWZsb2F0MiBwYXJhbV8xNSA9IHVfY2VudGVyX1MxX2MwOwoJZmxvYXQgcGFyYW1fMTYgPSByYWRpdXM7CglmbG9hdCBwYXJhbV8xNyA9IDAuMDUgKiB1X21heF9yYWRpdXNfUzFfYzA7CglmbG9hdCBwYXJhbV8xOCA9IHVfYmx1cl9TMV9jMDsKCWZsb2F0IHJpbmcgPSBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X3JpbmdfUzFfYzAocGFyYW1fMTQsIHBhcmFtXzE1LCBwYXJhbV8xNiwgcGFyYW1fMTcsIHBhcmFtXzE4KTsKCWZsb2F0MiBwYXJhbV8xOSA9IGRlbnNpdHlfdXY7CglmbG9hdCBwYXJhbV8yMCA9IHVfbm9pc2VfcGhhc2VfUzFfYzA7CglmbG9hdCBzcGFya2xlID0gKChGTFRfZmx1dHRlcl9sb2NhbF9zcGFya2xlX1MxX2MwKHBhcmFtXzE5LCBwYXJhbV8yMCkgKiByaW5nKSAqIHR1cmJ1bGVuY2UpICogdV9zcGFya2xlX2FscGhhX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzIxID0gcDsKCWZsb2F0MiBwYXJhbV8yMiA9IHVfY2VudGVyX1MxX2MwOwoJZmxvYXQgcGFyYW1fMjMgPSByYWRpdXM7CglmbG9hdCBwYXJhbV8yNCA9IHVfYmx1cl9TMV9jMDsKCWZsb2F0IHdhdmVfYWxwaGEgPSAoRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW1fMjEsIHBhcmFtXzIyLCBwYXJhbV8yMywgcGFyYW1fMjQpICogdV9hbHBoYV9TMV9jMCkgKiB1X2NvbG9yX1MxX2MwLnc7CglmbG9hdDQgd2F2ZV9jb2xvciA9IGZsb2F0NCh1X2NvbG9yX1MxX2MwLnh5eiAqIHdhdmVfYWxwaGEsIHdhdmVfYWxwaGEpOwoJZnJhZ0NvbG9yX1MxX2MwID0gbWl4KHdhdmVfY29sb3IsIGZsb2F0NCgxLjApLCBmbG9hdDQoc3BhcmtsZSkpOwp9CmhhbGY0IHJ1bnRpbWVfc2hhZGVyX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJZmxvYXQyIF90bXBfMV9jb29yZHMgPSB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKCWZsdXR0ZXJfRnJhZ0Nvb3JkX1MxX2MwID0gZmxvYXQ0KF90bXBfMV9jb29yZHMsIDAuMCwgMC4wKTsKCUZMVF9tYWluX1MxX2MwKCk7CglyZXR1cm4gaGFsZjQoaGFsZjQoZnJhZ0NvbG9yX1MxX2MwKSk7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBydW50aW1lX3NoYWRlcl9TMV9jMChfaW5wdXQpOwp9CmhhbGY0IENpcmN1bGFyUlJlY3RfUzIoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQgZHkwID0gdWlubmVyUmVjdF9TMi5UIC0gc2tfRnJhZ0Nvb3JkLnk7CglmbG9hdDIgZHh5MSA9IHNrX0ZyYWdDb29yZC54eSAtIHVpbm5lclJlY3RfUzIuUkI7CglmbG9hdDIgZHh5ID0gbWF4KGZsb2F0MihkeHkxLngsIG1heChkeTAsIGR4eTEueSkpLCAwLjApOwoJaGFsZiBsZWZ0QWxwaGEgPSBoYWxmKHNhdHVyYXRlKHNrX0ZyYWdDb29yZC54IC0gdWlubmVyUmVjdF9TMi5MKSk7CgloYWxmIGFscGhhID0gbGVmdEFscGhhICogaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzIueCAtIGxlbmd0aChkeHkpKSk7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWZsb2F0IGNvdmVyYWdlID0gdmNvdmVyYWdlX1MwOwoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChjb3ZlcmFnZSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBNYXRyaXhFZmZlY3RfUzEob3V0cHV0Q29sb3JfUzApOwoJaGFsZjQgb3V0cHV0X1MyOwoJb3V0cHV0X1MyID0gQ2lyY3VsYXJSUmVjdF9TMihvdXRwdXRDb3ZlcmFnZV9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0X1MxICogb3V0cHV0X1MyOwoJfQp9CgAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAAcG9zaXRpb24IAAAAY292ZXJhZ2UFAAAAY29sb3IAAAAKAAAAbG9jYWxDb29yZAAAAAAAAA==","AYAA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAAAAMYAAAAAAAQAAAABAMQAAAAA":"DAAAAExTS1PbAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgaW5Qb3NpdGlvbjsKaW4gaGFsZjQgaW5Db2xvcjsKaW4gZmxvYXQ0IGluQ2lyY2xlRWRnZTsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQ0IHZpbkNpcmNsZUVkZ2VfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJdmluQ2lyY2xlRWRnZV9TMCA9IGluQ2lyY2xlRWRnZTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8yX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgAAAAAAQwIAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQpub3BlcnNwZWN0aXZlIGluIGZsb2F0NCB2aW5DaXJjbGVFZGdlX1MwOwpub3BlcnNwZWN0aXZlIGluIGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgQ2lyY2xlR2VvbWV0cnlQcm9jZXNzb3IKCWZsb2F0NCBjaXJjbGVFZGdlOwoJY2lyY2xlRWRnZSA9IHZpbkNpcmNsZUVkZ2VfUzA7CgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmluQ29sb3JfUzA7CglmbG9hdCBkID0gbGVuZ3RoKGNpcmNsZUVkZ2UueHkpOwoJaGFsZiBkaXN0YW5jZVRvT3V0ZXJFZGdlID0gaGFsZihjaXJjbGVFZGdlLnogKiAoMS4wIC0gZCkpOwoJaGFsZiBlZGdlQWxwaGEgPSBzYXR1cmF0ZShkaXN0YW5jZVRvT3V0ZXJFZGdlKTsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoZWRnZUFscGhhKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAoAAABpblBvc2l0aW9uAAAHAAAAaW5Db2xvcgAMAAAAaW5DaXJjbGVFZGdlAAAAAA==","GYQACAAAAAMAADAAAIOAAAH677776IZOCAAP577777777777777777YBAAAAAAAAAAAHEADZAAAAAAIAAAAAAMYAAAAAAAQAAAABAMQAAAAAA":"DAAAAExTS1MaAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgcG9zaXRpb247CmluIGhhbGY0IGNvbG9yOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2Y29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cn0KAAABAAAA5gIAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQp1bmlmb3JtIGZsb2F0NCB1aW5uZXJSZWN0X1MxOwp1bmlmb3JtIGhhbGYyIHVyYWRpdXNQbHVzSGFsZl9TMTsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2Y29sb3JfUzA7CmhhbGY0IENpcmN1bGFyUlJlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MxLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MxLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CgloYWxmIGFscGhhID0gaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzEueCAtIGxlbmd0aChkeHkpKSk7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBDaXJjdWxhclJSZWN0X1MxKG91dHB1dENvdmVyYWdlX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAAAAAAAA==","G2QACAAAABAAADAAAIOAAAAADIIAAIRODAAP577774DSAIAA737777YBAAAAAAAAAAAHEADZAAAAAAIAAAAAAMYAAAAAAAQAAAABAMQAAAAAA":"DAAAAExTS1PqAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgcG9zaXRpb247CmluIGZsb2F0IGNvdmVyYWdlOwppbiBoYWxmNCBjb2xvcjsKaW4gZmxvYXQ0IGdlb21TdWJzZXQ7Cm5vcGVyc3BlY3RpdmUgb3V0IGhhbGY0IHZjb2xvcl9TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQgdmNvdmVyYWdlX1MwOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDQgdmdlb21TdWJzZXRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQyIHBvc2l0aW9uID0gcG9zaXRpb24ueHk7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCXZjb3ZlcmFnZV9TMCA9IGNvdmVyYWdlOwoJdmdlb21TdWJzZXRfUzAgPSBnZW9tU3Vic2V0OwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAQAAADMEAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7Cm5vcGVyc3BlY3RpdmUgaW4gaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0IHZjb3ZlcmFnZV9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdDQgdmdlb21TdWJzZXRfUzA7CmhhbGY0IENpcmN1bGFyUlJlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MxLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MxLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CgloYWxmIGFscGhhID0gaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzEueCAtIGxlbmd0aChkeHkpKSk7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWZsb2F0IGNvdmVyYWdlID0gdmNvdmVyYWdlX1MwOwoJZmxvYXQ0IGdlb1N1YnNldDsKCWdlb1N1YnNldCA9IHZnZW9tU3Vic2V0X1MwOwoJZmxvYXQ0IGRpc3RzNCA9IHNhdHVyYXRlKGZsb2F0NCgxLCAxLCAtMSwgLTEpICogKHNrX0ZyYWdDb29yZC54eXh5IC0gZ2VvU3Vic2V0KSk7CglmbG9hdDIgZGlzdHMyID0gZGlzdHM0Lnh5ICsgZGlzdHM0Lnp3IC0gMTsKCWNvdmVyYWdlID0gbWluKGNvdmVyYWdlLCBkaXN0czIueCAqIGRpc3RzMi55KTsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoY292ZXJhZ2UpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQ2lyY3VsYXJSUmVjdF9TMShvdXRwdXRDb3ZlcmFnZV9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAHBvc2l0aW9uCAAAAGNvdmVyYWdlBQAAAGNvbG9yAAAACgAAAGdlb21TdWJzZXQAAAAAAAA=","CMRQCIAABBYAAAEIXBAAACDQMAABRAFAAAAAAAAAAAAAAAGABQAAAAEAAAAAAAEEBQAAAAA":"DAAAAExTS1OZAgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0NCB1bG9jYWxNYXRyaXhfUzA7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiBmbG9hdDIgaW5FbGxpcHNlT2Zmc2V0OwppbiBmbG9hdDQgaW5FbGxpcHNlUmFkaWk7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2RWxsaXBzZU9mZnNldHNfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0NCB2RWxsaXBzZVJhZGlpX1MwOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgRWxsaXBzZUdlb21ldHJ5UHJvY2Vzc29yCgl2RWxsaXBzZU9mZnNldHNfUzAgPSBpbkVsbGlwc2VPZmZzZXQ7Cgl2RWxsaXBzZVJhZGlpX1MwID0gaW5FbGxpcHNlUmFkaWk7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8wX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJZmxvYXQyIF90bXBfMV9pblBvc2l0aW9uID0gdWxvY2FsTWF0cml4X1MwLnh6ICogaW5Qb3NpdGlvbiArIHVsb2NhbE1hdHJpeF9TMC55dzsKCXNrX1Bvc2l0aW9uID0gX3RtcF8wX2luUG9zaXRpb24ueHkwMTsKfQoAAAAAAAAA2QMAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2RWxsaXBzZU9mZnNldHNfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQ0IHZFbGxpcHNlUmFkaWlfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBFbGxpcHNlR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWZsb2F0MiBvZmZzZXQgPSB2RWxsaXBzZU9mZnNldHNfUzAueHk7CglvZmZzZXQgKj0gdkVsbGlwc2VSYWRpaV9TMC54eTsKCWZsb2F0IHRlc3QgPSBkb3Qob2Zmc2V0LCBvZmZzZXQpIC0gMS4wOwoJZmxvYXQyIGdyYWQgPSAyLjAqb2Zmc2V0KnZFbGxpcHNlUmFkaWlfUzAueHk7CglmbG9hdCBncmFkX2RvdCA9IGRvdChncmFkLCBncmFkKTsKCWdyYWRfZG90ID0gbWF4KGdyYWRfZG90LCAxLjE3NTVlLTM4KTsKCWZsb2F0IGludmxlbiA9IGludmVyc2VzcXJ0KGdyYWRfZG90KTsKCWZsb2F0IGVkZ2VBbHBoYSA9IHNhdHVyYXRlKDAuNS10ZXN0Kmludmxlbik7CglvZmZzZXQgPSB2RWxsaXBzZU9mZnNldHNfUzAueHkqdkVsbGlwc2VSYWRpaV9TMC56dzsKCXRlc3QgPSBkb3Qob2Zmc2V0LCBvZmZzZXQpIC0gMS4wOwoJZ3JhZCA9IDIuMCpvZmZzZXQqdkVsbGlwc2VSYWRpaV9TMC56dzsKCWdyYWRfZG90ID0gZG90KGdyYWQsIGdyYWQpOwoJaW52bGVuID0gaW52ZXJzZXNxcnQoZ3JhZF9kb3QpOwoJZWRnZUFscGhhICo9IHNhdHVyYXRlKDAuNSt0ZXN0Kmludmxlbik7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGhhbGYoZWRnZUFscGhhKSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAoAAABpblBvc2l0aW9uAAAHAAAAaW5Db2xvcgAPAAAAaW5FbGxpcHNlT2Zmc2V0AA4AAABpbkVsbGlwc2VSYWRpaQAAAAAAAA==","GYJAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAQAAAAAAQQGAAZAADIAAAAIH5K3LIKAAAAAAMAAAAAIAAAAAAFMZBQP3FQWAUAABQAAAAAAAAAAAAADGAAAAAAAEAAAAAIDEAAA":"DAAAAExTS1MwAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgcG9zaXRpb247CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmxvY2FsQ29vcmRfUzAgPSBsb2NhbENvb3JkOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgEAAADzBAAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCmNvbnN0IGludCBrRmlsbEFBX1MxX2MwID0gMTsKY29uc3QgaW50IGtJbnZlcnNlRmlsbEJXX1MxX2MwID0gMjsKY29uc3QgaW50IGtJbnZlcnNlRmlsbEFBX1MxX2MwID0gMzsKdW5pZm9ybSBmbG9hdDQgdWNpcmNsZV9TMV9jMDsKc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2bG9jYWxDb29yZF9TMDsKaGFsZjQgQ2lyY2xlX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJaGFsZiBkOwoJaWYgKGludCgxKSA9PSBrSW52ZXJzZUZpbGxCV19TMV9jMCB8fCBpbnQoMSkgPT0ga0ludmVyc2VGaWxsQUFfUzFfYzApIAoJewoJCWQgPSBoYWxmKChsZW5ndGgoKHVjaXJjbGVfUzFfYzAueHkgLSBza19GcmFnQ29vcmQueHkpICogdWNpcmNsZV9TMV9jMC53KSAtIDEuMCkgKiB1Y2lyY2xlX1MxX2MwLnopOwoJfQoJZWxzZSAKCXsKCQlkID0gaGFsZigoMS4wIC0gbGVuZ3RoKCh1Y2lyY2xlX1MxX2MwLnh5IC0gc2tfRnJhZ0Nvb3JkLnh5KSAqIHVjaXJjbGVfUzFfYzAudykpICogdWNpcmNsZV9TMV9jMC56KTsKCX0KCXJldHVybiBoYWxmNChoYWxmNChpbnQoMSkgPT0ga0ZpbGxBQV9TMV9jMCB8fCBpbnQoMSkgPT0ga0ludmVyc2VGaWxsQUFfUzFfYzAgPyBzYXR1cmF0ZShkKSA6IGhhbGYoZCA+IDAuNSkpKTsKfQpoYWxmNCBCbGVuZF9TMShoYWxmNCBfc3JjLCBoYWxmNCBfZHN0KSAKewoJcmV0dXJuIGJsZW5kX21vZHVsYXRlKF9zcmMsIENpcmNsZV9TMV9jMChfc3JjKSk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWZsb2F0MiB0ZXhDb29yZDsKCXRleENvb3JkID0gdmxvY2FsQ29vcmRfUzA7CglvdXRwdXRDb2xvcl9TMCA9IChibGVuZF9tb2R1bGF0ZShzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzAsIHRleENvb3JkKSwgaGFsZjQoMSkpKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBCbGVuZF9TMShvdXRwdXRDb3ZlcmFnZV9TMCwgaGFsZjQoMSkpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0X1MxOwoJfQp9CgABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgoAAABsb2NhbENvb3JkAAAAAAAA","EEAQMYAAMAAAEADAAABAEYAAAICIAB5AABQAAAQAMAAAEATAAABAIIGAAEDCBYQCA4AAAAAAEAB5AAAAAAYFRP5FIUAQAADQAAAABAAAAAAABQEKBTLG62KRAAAAAHAAAAAAAAAAAAYAGAAAAAQAAAAAAAQQGAAA":"DAAAAExTS1MoDAAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDQgcmFkaWlfc2VsZWN0b3I7CmluIGZsb2F0NCBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzOwppbiBmbG9hdDQgYWFfYmxvYXRfYW5kX2NvdmVyYWdlOwppbiBmbG9hdDQgcmFkaWlfeDsKaW4gZmxvYXQ0IHJhZGlpX3k7CmluIGZsb2F0NCBza2V3OwppbiBmbG9hdDIgdHJhbnNsYXRlX2FuZF9sb2NhbHJvdGF0ZTsKaW4gaGFsZjQgY29sb3I7Cm5vcGVyc3BlY3RpdmUgb3V0IGhhbGY0IHZjb2xvcl9TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQyIHZhcmNjb29yZF9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgRmlsbFJSZWN0T3A6OlByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7CglmbG9hdCBhYV9ibG9hdF9tdWx0aXBsaWVyID0gMTsKCWZsb2F0MiBjb3JuZXIgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnh5OwoJZmxvYXQyIHJhZGl1c19vdXRzZXQgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnp3OwoJZmxvYXQyIGFhX2Jsb2F0X2RpcmVjdGlvbiA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS54eTsKCWZsb2F0IGlzX2xpbmVhcl9jb3ZlcmFnZSA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS53OwoJZmxvYXQyIHBpeGVsbGVuZ3RoID0gaW52ZXJzZXNxcnQoZmxvYXQyKGRvdChza2V3Lnh6LCBza2V3Lnh6KSwgZG90KHNrZXcueXcsIHNrZXcueXcpKSk7CglmbG9hdDQgbm9ybWFsaXplZF9heGlzX2RpcnMgPSBza2V3ICogcGl4ZWxsZW5ndGgueHl4eTsKCWZsb2F0MiBheGlzd2lkdGhzID0gKGFicyhub3JtYWxpemVkX2F4aXNfZGlycy54eSkgKyBhYnMobm9ybWFsaXplZF9heGlzX2RpcnMuencpKTsKCWZsb2F0MiBhYV9ibG9hdHJhZGl1cyA9IGF4aXN3aWR0aHMgKiBwaXhlbGxlbmd0aCAqIC41OwoJZmxvYXQ0IHJhZGlpX2FuZF9uZWlnaGJvcnMgPSByYWRpaV9zZWxlY3RvciogZmxvYXQ0eDQocmFkaWlfeCwgcmFkaWlfeSwgcmFkaWlfeC55eHd6LCByYWRpaV95Lnd6eXgpOwoJZmxvYXQyIHJhZGlpID0gcmFkaWlfYW5kX25laWdoYm9ycy54eTsKCWZsb2F0MiBuZWlnaGJvcl9yYWRpaSA9IHJhZGlpX2FuZF9uZWlnaGJvcnMuenc7CglmbG9hdCBjb3ZlcmFnZV9tdWx0aXBsaWVyID0gMTsKCWlmIChhbnkoZ3JlYXRlclRoYW4oYWFfYmxvYXRyYWRpdXMsIGZsb2F0MigxKSkpKSAKCXsKCQljb3JuZXIgPSBtYXgoYWJzKGNvcm5lciksIGFhX2Jsb2F0cmFkaXVzKSAqIHNpZ24oY29ybmVyKTsKCQljb3ZlcmFnZV9tdWx0aXBsaWVyID0gMSAvIChtYXgoYWFfYmxvYXRyYWRpdXMueCwgMSkgKiBtYXgoYWFfYmxvYXRyYWRpdXMueSwgMSkpOwoJCXJhZGlpID0gZmxvYXQyKDApOwoJfQoJZmxvYXQgY292ZXJhZ2UgPSBhYV9ibG9hdF9hbmRfY292ZXJhZ2UuejsKCWlmIChhbnkobGVzc1RoYW4ocmFkaWksIGFhX2Jsb2F0cmFkaXVzICogMS41KSkpIAoJewoJCXJhZGlpID0gZmxvYXQyKDApOwoJCWFhX2Jsb2F0X2RpcmVjdGlvbiA9IHNpZ24oY29ybmVyKTsKCQlpZiAoY292ZXJhZ2UgPiAuNSkgCgkJewoJCQlhYV9ibG9hdF9kaXJlY3Rpb24gPSAtYWFfYmxvYXRfZGlyZWN0aW9uOwoJCX0KCQlpc19saW5lYXJfY292ZXJhZ2UgPSAxOwoJfQoJZWxzZSAKCXsKCQlyYWRpaSA9IGNsYW1wKHJhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQluZWlnaGJvcl9yYWRpaSA9IGNsYW1wKG5laWdoYm9yX3JhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQlmbG9hdDIgc3BhY2luZyA9IDIgLSByYWRpaSAtIG5laWdoYm9yX3JhZGlpOwoJCWZsb2F0MiBleHRyYV9wYWQgPSBtYXgocGl4ZWxsZW5ndGggKiAuMDYyNSAtIHNwYWNpbmcsIGZsb2F0MigwKSk7CgkJcmFkaWkgLT0gZXh0cmFfcGFkICogLjU7Cgl9CglmbG9hdDIgYWFfb3V0c2V0ID0gYWFfYmxvYXRfZGlyZWN0aW9uICogYWFfYmxvYXRyYWRpdXMgKiBhYV9ibG9hdF9tdWx0aXBsaWVyOwoJZmxvYXQyIHZlcnRleHBvcyA9IGNvcm5lciArIHJhZGl1c19vdXRzZXQgKiByYWRpaSArIGFhX291dHNldDsKCWlmIChjb3ZlcmFnZSA+IC41KSAKCXsKCQlpZiAoYWFfYmxvYXRfZGlyZWN0aW9uLnggIT0gMCAmJiB2ZXJ0ZXhwb3MueCAqIGNvcm5lci54IDwgMCkgCgkJewoJCQlmbG9hdCBiYWNrc2V0ID0gYWJzKHZlcnRleHBvcy54KTsKCQkJdmVydGV4cG9zLnggPSAwOwoJCQl2ZXJ0ZXhwb3MueSArPSBiYWNrc2V0ICogc2lnbihjb3JuZXIueSkgKiBwaXhlbGxlbmd0aC55L3BpeGVsbGVuZ3RoLng7CgkJCWNvdmVyYWdlID0gKGNvdmVyYWdlIC0gLjUpICogYWJzKGNvcm5lci54KSAvIChhYnMoY29ybmVyLngpICsgYmFja3NldCkgKyAuNTsKCQl9CgkJaWYgKGFhX2Jsb2F0X2RpcmVjdGlvbi55ICE9IDAgJiYgdmVydGV4cG9zLnkgKiBjb3JuZXIueSA8IDApIAoJCXsKCQkJZmxvYXQgYmFja3NldCA9IGFicyh2ZXJ0ZXhwb3MueSk7CgkJCXZlcnRleHBvcy55ID0gMDsKCQkJdmVydGV4cG9zLnggKz0gYmFja3NldCAqIHNpZ24oY29ybmVyLngpICogcGl4ZWxsZW5ndGgueC9waXhlbGxlbmd0aC55OwoJCQljb3ZlcmFnZSA9IChjb3ZlcmFnZSAtIC41KSAqIGFicyhjb3JuZXIueSkgLyAoYWJzKGNvcm5lci55KSArIGJhY2tzZXQpICsgLjU7CgkJfQoJfQoJZmxvYXQyeDIgc2tld21hdHJpeCA9IGZsb2F0MngyKHNrZXcueHksIHNrZXcuencpOwoJZmxvYXQyIGRldmNvb3JkID0gdmVydGV4cG9zICogc2tld21hdHJpeCArIHRyYW5zbGF0ZV9hbmRfbG9jYWxyb3RhdGUueHk7CglpZiAoMCAhPSBpc19saW5lYXJfY292ZXJhZ2UpIAoJewoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MigwLCBjb3ZlcmFnZSAqIGNvdmVyYWdlX211bHRpcGxpZXIpOwoJfQoJZWxzZSAKCXsKCQlmbG9hdDIgYXJjY29vcmQgPSAxIC0gYWJzKHJhZGl1c19vdXRzZXQpICsgYWFfb3V0c2V0L3JhZGlpICogY29ybmVyOwoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MihhcmNjb29yZC54KzEsIGFyY2Nvb3JkLnkpOwoJfQoJc2tfUG9zaXRpb24gPSBkZXZjb29yZC54eTAxOwp9CgEAAACdBQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCmNvbnN0IGludCBrRmlsbEFBX1MxX2MwID0gMTsKY29uc3QgaW50IGtJbnZlcnNlRmlsbEJXX1MxX2MwID0gMjsKY29uc3QgaW50IGtJbnZlcnNlRmlsbEFBX1MxX2MwID0gMzsKdW5pZm9ybSBmbG9hdDQgdWNpcmNsZV9TMV9jMDsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQyIHZhcmNjb29yZF9TMDsKaGFsZjQgQ2lyY2xlX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJaGFsZiBkOwoJaWYgKGludCgzKSA9PSBrSW52ZXJzZUZpbGxCV19TMV9jMCB8fCBpbnQoMykgPT0ga0ludmVyc2VGaWxsQUFfUzFfYzApIAoJewoJCWQgPSBoYWxmKChsZW5ndGgoKHVjaXJjbGVfUzFfYzAueHkgLSBza19GcmFnQ29vcmQueHkpICogdWNpcmNsZV9TMV9jMC53KSAtIDEuMCkgKiB1Y2lyY2xlX1MxX2MwLnopOwoJfQoJZWxzZSAKCXsKCQlkID0gaGFsZigoMS4wIC0gbGVuZ3RoKCh1Y2lyY2xlX1MxX2MwLnh5IC0gc2tfRnJhZ0Nvb3JkLnh5KSAqIHVjaXJjbGVfUzFfYzAudykpICogdWNpcmNsZV9TMV9jMC56KTsKCX0KCXJldHVybiBoYWxmNChoYWxmNChpbnQoMykgPT0ga0ZpbGxBQV9TMV9jMCB8fCBpbnQoMykgPT0ga0ludmVyc2VGaWxsQUFfUzFfYzAgPyBzYXR1cmF0ZShkKSA6IGhhbGYoZCA+IDAuNSkpKTsKfQpoYWxmNCBCbGVuZF9TMShoYWxmNCBfc3JjLCBoYWxmNCBfZHN0KSAKewoJcmV0dXJuIGJsZW5kX21vZHVsYXRlKF9zcmMsIENpcmNsZV9TMV9jMChfc3JjKSk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIEZpbGxSUmVjdE9wOjpQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7CglmbG9hdCB4X3BsdXNfMT12YXJjY29vcmRfUzAueCwgeT12YXJjY29vcmRfUzAueTsKCWhhbGYgY292ZXJhZ2U7CglpZiAoMCA9PSB4X3BsdXNfMSkgCgl7CgkJY292ZXJhZ2UgPSBoYWxmKHkpOwoJfQoJZWxzZSAKCXsKCQlmbG9hdCBmbiA9IHhfcGx1c18xICogKHhfcGx1c18xIC0gMik7CgkJZm4gPSBmbWEoeSx5LCBmbik7CgkJZmxvYXQgZm53aWR0aCA9IGZ3aWR0aChmbik7CgkJY292ZXJhZ2UgPSAuNSAtIGhhbGYoZm4vZm53aWR0aCk7CgkJY292ZXJhZ2UgPSBjbGFtcChjb3ZlcmFnZSwgMCwgMSk7Cgl9CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGNvdmVyYWdlKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IEJsZW5kX1MxKG91dHB1dENvdmVyYWdlX1MwLCBoYWxmNCgxKSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAOAAAAcmFkaWlfc2VsZWN0b3IAABkAAABjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzAAAAFQAAAGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZQAAAAcAAAByYWRpaV94AAcAAAByYWRpaV95AAQAAABza2V3GQAAAHRyYW5zbGF0ZV9hbmRfbG9jYWxyb3RhdGUAAAAFAAAAY29sb3IAAAAAAAAA","GYJAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAQAAAAAEQQGABZAA6IAAAAACAAAAAADGAAAAAAAEAAAAAIDEAAAAAAA":"DAAAAExTS1MwAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgcG9zaXRpb247CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmxvY2FsQ29vcmRfUzAgPSBsb2NhbENvb3JkOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgEAAACHAwAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHVpbm5lclJlY3RfUzE7CnVuaWZvcm0gaGFsZjIgdXJhZGl1c1BsdXNIYWxmX1MxOwpzYW1wbGVyRXh0ZXJuYWxPRVMgdVRleHR1cmVTYW1wbGVyXzBfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQyIHZsb2NhbENvb3JkX1MwOwpoYWxmNCBDaXJjdWxhclJSZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCWZsb2F0MiBkeHkwID0gdWlubmVyUmVjdF9TMS5MVCAtIHNrX0ZyYWdDb29yZC54eTsKCWZsb2F0MiBkeHkxID0gc2tfRnJhZ0Nvb3JkLnh5IC0gdWlubmVyUmVjdF9TMS5SQjsKCWZsb2F0MiBkeHkgPSBtYXgobWF4KGR4eTAsIGR4eTEpLCAwLjApOwoJaGFsZiBhbHBoYSA9IGhhbGYoc2F0dXJhdGUodXJhZGl1c1BsdXNIYWxmX1MxLnggLSBsZW5ndGgoZHh5KSkpOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwID0gaGFsZjQoMSk7CglmbG9hdDIgdGV4Q29vcmQ7Cgl0ZXhDb29yZCA9IHZsb2NhbENvb3JkX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSAoYmxlbmRfbW9kdWxhdGUoc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB0ZXhDb29yZCksIGhhbGY0KDEpKSk7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQ2lyY3VsYXJSUmVjdF9TMShvdXRwdXRDb3ZlcmFnZV9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACAAAAHBvc2l0aW9uCgAAAGxvY2FsQ29vcmQAAAAAAAA=","AYTRVAADQAAAOAEARAFQJAABBADAAAILBYAACCYUQD777777777767YAAAAAAAAAAAAMYAAAAAAAQAAAABAMQAAAAA":"DAAAAExTS1PnAgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0NCB1bG9jYWxNYXRyaXhfUzA7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiBmbG9hdDQgaW5DaXJjbGVFZGdlOwppbiBoYWxmMyBpbkNsaXBQbGFuZTsKaW4gaGFsZjMgaW5Jc2VjdFBsYW5lOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjMgdmluQ2xpcFBsYW5lX1MwOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmMyB2aW5Jc2VjdFBsYW5lX1MwOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgQ2lyY2xlR2VvbWV0cnlQcm9jZXNzb3IKCXZpbkNpcmNsZUVkZ2VfUzAgPSBpbkNpcmNsZUVkZ2U7Cgl2aW5DbGlwUGxhbmVfUzAgPSBpbkNsaXBQbGFuZTsKCXZpbklzZWN0UGxhbmVfUzAgPSBpbklzZWN0UGxhbmU7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8wX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJZmxvYXQyIF90bXBfMV9pblBvc2l0aW9uID0gdWxvY2FsTWF0cml4X1MwLnh6ICogaW5Qb3NpdGlvbiArIHVsb2NhbE1hdHJpeF9TMC55dzsKCXNrX1Bvc2l0aW9uID0gX3RtcF8wX2luUG9zaXRpb24ueHkwMTsKfQoAAAAAAFIEAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmMyB2aW5DbGlwUGxhbmVfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gaGFsZjMgdmluSXNlY3RQbGFuZV9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIENpcmNsZUdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDQgY2lyY2xlRWRnZTsKCWNpcmNsZUVkZ2UgPSB2aW5DaXJjbGVFZGdlX1MwOwoJaGFsZjMgY2xpcFBsYW5lOwoJY2xpcFBsYW5lID0gdmluQ2xpcFBsYW5lX1MwOwoJaGFsZjMgaXNlY3RQbGFuZTsKCWlzZWN0UGxhbmUgPSB2aW5Jc2VjdFBsYW5lX1MwOwoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZpbkNvbG9yX1MwOwoJZmxvYXQgZCA9IGxlbmd0aChjaXJjbGVFZGdlLnh5KTsKCWhhbGYgZGlzdGFuY2VUb091dGVyRWRnZSA9IGhhbGYoY2lyY2xlRWRnZS56ICogKDEuMCAtIGQpKTsKCWhhbGYgZWRnZUFscGhhID0gc2F0dXJhdGUoZGlzdGFuY2VUb091dGVyRWRnZSk7CgloYWxmIGRpc3RhbmNlVG9Jbm5lckVkZ2UgPSBoYWxmKGNpcmNsZUVkZ2UueiAqIChkIC0gY2lyY2xlRWRnZS53KSk7CgloYWxmIGlubmVyQWxwaGEgPSBzYXR1cmF0ZShkaXN0YW5jZVRvSW5uZXJFZGdlKTsKCWVkZ2VBbHBoYSAqPSBpbm5lckFscGhhOwoJaGFsZiBjbGlwID0gaGFsZihzYXR1cmF0ZShjaXJjbGVFZGdlLnogKiBkb3QoY2lyY2xlRWRnZS54eSwgY2xpcFBsYW5lLnh5KSArIGNsaXBQbGFuZS56KSk7CgljbGlwICo9IGhhbGYoc2F0dXJhdGUoY2lyY2xlRWRnZS56ICogZG90KGNpcmNsZUVkZ2UueHksIGlzZWN0UGxhbmUueHkpICsgaXNlY3RQbGFuZS56KSk7CgllZGdlQWxwaGEgKj0gY2xpcDsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoZWRnZUFscGhhKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADAAAAGluQ2lyY2xlRWRnZQsAAABpbkNsaXBQbGFuZQAMAAAAaW5Jc2VjdFBsYW5lAAAAAA==","G2JQAAAAABEAADAAAIOAAAAADIIAB7X7777QGHAYAD7P7777A4QCQAAAAAAAAAQAAAAAAQQGAAYAGAAAAAQAAAAAAAQQGAAA":"DAAAAExTS1P8AQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgcG9zaXRpb247CmluIGZsb2F0IGNvdmVyYWdlOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKaW4gZmxvYXQ0IHRleFN1YnNldDsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQyIHZsb2NhbENvb3JkX1MwOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDQgdnRleFN1YnNldF9TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQgdmNvdmVyYWdlX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWZsb2F0MiBwb3NpdGlvbiA9IHBvc2l0aW9uLnh5OwoJdmxvY2FsQ29vcmRfUzAgPSBsb2NhbENvb3JkOwoJdnRleFN1YnNldF9TMCA9IHRleFN1YnNldDsKCXZjb3ZlcmFnZV9TMCA9IGNvdmVyYWdlOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAAC4AgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQ0IHZ0ZXhTdWJzZXRfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQgdmNvdmVyYWdlX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMCA9IGhhbGY0KDEpOwoJZmxvYXQyIHRleENvb3JkOwoJdGV4Q29vcmQgPSB2bG9jYWxDb29yZF9TMDsKCWZsb2F0NCBzdWJzZXQ7CglzdWJzZXQgPSB2dGV4U3Vic2V0X1MwOwoJdGV4Q29vcmQgPSBjbGFtcCh0ZXhDb29yZCwgc3Vic2V0LkxULCBzdWJzZXQuUkIpOwoJb3V0cHV0Q29sb3JfUzAgPSAoYmxlbmRfbW9kdWxhdGUoc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB0ZXhDb29yZCksIGhhbGY0KDEpKSk7CglmbG9hdCBjb3ZlcmFnZSA9IHZjb3ZlcmFnZV9TMDsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoY292ZXJhZ2UpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAAcG9zaXRpb24IAAAAY292ZXJhZ2UKAAAAbG9jYWxDb29yZAAACQAAAHRleFN1YnNldAAAAAAAAAA=","GZIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAJIBAGMVUOTUABAAAAQAAIAAAAAWFBIEMVUOTUAAAAAAQAAIAAAACIGAACAAAAACQIKACCAYAAEAAAAAAAAZQAAAAAABAAAAACAZAAAAAAA":"DAAAAExTS1PIAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfMl9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzEpICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAOgGAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKY29uc3QgaW50IGtNYXhMb29wTGltaXRfUzFfYzAgPSA4Owp1bmlmb3JtIGZsb2F0NCB1Y2xhbXBfUzFfYzBfYzBfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMDsKdW5pZm9ybSBoYWxmNCB1b2Zmc2V0c0FuZEtlcm5lbF9TMV9jMFsxNF07CnVuaWZvcm0gaGFsZjIgdWRpcl9TMV9jMDsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7Cm5vcGVyc3BlY3RpdmUgaW4gaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMF9jMF9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJZmxvYXQyIGluQ29vcmQgPSBfY29vcmRzOwoJZmxvYXQyIHN1YnNldENvb3JkOwoJc3Vic2V0Q29vcmQueCA9IGluQ29vcmQueDsKCXN1YnNldENvb3JkLnkgPSBpbkNvb3JkLnk7CglmbG9hdDIgY2xhbXBlZENvb3JkOwoJY2xhbXBlZENvb3JkLnggPSBjbGFtcChzdWJzZXRDb29yZC54LCB1Y2xhbXBfUzFfYzBfYzBfYzAueCwgdWNsYW1wX1MxX2MwX2MwX2MwLnopOwoJY2xhbXBlZENvb3JkLnkgPSBzdWJzZXRDb29yZC55OwoJaGFsZjQgdGV4dHVyZUNvbG9yID0gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MxLCBjbGFtcGVkQ29vcmQpOwoJcmV0dXJuIHRleHR1cmVDb2xvcjsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoaGFsZjQgX2lucHV0LCBmbG9hdDIgX2Nvb3JkcykgCnsKCXJldHVybiBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwX2MwKF9pbnB1dCwgZmxvYXQzeDIodW1hdHJpeF9TMV9jMF9jMCkgKiBfY29vcmRzLnh5MSk7Cn0KaGFsZjQgcnVudGltZV9zaGFkZXJfUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF8wX2luQ29sb3IgPSBfaW5wdXQ7CglmbG9hdDIgX3RtcF8xX2Nvb3JkcyA9IHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwoJaGFsZjQgc3VtID0gaGFsZjQoMC4wKTsKCWZvciAoaW50IGkgPSAwO2kgPCBrTWF4TG9vcExpbWl0X1MxX2MwOyArK2kpIAoJewoJCWhhbGY0IHMgPSB1b2Zmc2V0c0FuZEtlcm5lbF9TMV9jMFtpXTsKCQlzdW0gKz0gcy55ICogTWF0cml4RWZmZWN0X1MxX2MwX2MwKF90bXBfMF9pbkNvbG9yLCBfdG1wXzFfY29vcmRzICsgZmxvYXQyKHMueCAqIHVkaXJfUzFfYzApKTsKCQlzdW0gKz0gcy53ICogTWF0cml4RWZmZWN0X1MxX2MwX2MwKF90bXBfMF9pbkNvbG9yLCBfdG1wXzFfY29vcmRzICsgZmxvYXQyKHMueiAqIHVkaXJfUzFfYzApKTsKCX0KCXJldHVybiBoYWxmNChzdW0pOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gcnVudGltZV9zaGFkZXJfUzFfYzAoX2lucHV0KTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IE1hdHJpeEVmZmVjdF9TMShvdXRwdXRDb2xvcl9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0X1MxICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAIAAAAcG9zaXRpb24FAAAAY29sb3IAAAAKAAAAbG9jYWxDb29yZAAAAAAAAA==","GYJD4AQCAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAQAAAAAAQQGAAYAGAAAAAQAAAAAAAQQGAAA":"DAAAAExTS1MwAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgcG9zaXRpb247CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmxvY2FsQ29vcmRfUzAgPSBsb2NhbENvb3JkOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAABmBgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQgdVNyY1RGX1MwWzddOwp1bmlmb3JtIGZsb2F0M3gzIHVDb2xvclhmb3JtX1MwOwp1bmlmb3JtIGZsb2F0IHVEc3RURl9TMFs3XTsKc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2bG9jYWxDb29yZF9TMDsKZmxvYXQgc3JjX3RmX1MwKGZsb2F0IHgpIAp7CglmbG9hdCBHID0gdVNyY1RGX1MwWzBdOwoJZmxvYXQgQSA9IHVTcmNURl9TMFsxXTsKCWZsb2F0IEIgPSB1U3JjVEZfUzBbMl07CglmbG9hdCBDID0gdVNyY1RGX1MwWzNdOwoJZmxvYXQgRCA9IHVTcmNURl9TMFs0XTsKCWZsb2F0IEUgPSB1U3JjVEZfUzBbNV07CglmbG9hdCBGID0gdVNyY1RGX1MwWzZdOwoJZmxvYXQgcyA9IHNpZ24oeCk7Cgl4ID0gYWJzKHgpOwoJeCA9ICh4IDwgRCkgPyAoQyAqIHgpICsgRiA6IHBvdyhBICogeCArIEIsIEcpICsgRTsKCXJldHVybiBzICogeDsKfQpmbG9hdCBkc3RfdGZfUzAoZmxvYXQgeCkgCnsKCWZsb2F0IEcgPSB1RHN0VEZfUzBbMF07CglmbG9hdCBBID0gdURzdFRGX1MwWzFdOwoJZmxvYXQgQiA9IHVEc3RURl9TMFsyXTsKCWZsb2F0IEMgPSB1RHN0VEZfUzBbM107CglmbG9hdCBEID0gdURzdFRGX1MwWzRdOwoJZmxvYXQgRSA9IHVEc3RURl9TMFs1XTsKCWZsb2F0IEYgPSB1RHN0VEZfUzBbNl07CglmbG9hdCBzID0gc2lnbih4KTsKCXggPSBhYnMoeCk7Cgl4ID0gKHggPCBEKSA/IChDICogeCkgKyBGIDogcG93KEEgKiB4ICsgQiwgRykgKyBFOwoJcmV0dXJuIHMgKiB4Owp9CmZsb2F0NCBnYW11dF94Zm9ybV9TMChmbG9hdDQgY29sb3IpIAp7Cgljb2xvci5yZ2IgPSAodUNvbG9yWGZvcm1fUzAgKiBjb2xvci5yZ2IpOwoJcmV0dXJuIGNvbG9yOwp9CmhhbGY0IGNvbG9yX3hmb3JtX1MwKGZsb2F0NCBjb2xvcikgCnsKCWNvbG9yID0gdW5wcmVtdWwoY29sb3IpOwoJY29sb3IuciA9IHNyY190Zl9TMChjb2xvci5yKTsKCWNvbG9yLmcgPSBzcmNfdGZfUzAoY29sb3IuZyk7Cgljb2xvci5iID0gc3JjX3RmX1MwKGNvbG9yLmIpOwoJY29sb3IgPSBnYW11dF94Zm9ybV9TMChjb2xvcik7Cgljb2xvci5yID0gZHN0X3RmX1MwKGNvbG9yLnIpOwoJY29sb3IuZyA9IGRzdF90Zl9TMChjb2xvci5nKTsKCWNvbG9yLmIgPSBkc3RfdGZfUzAoY29sb3IuYik7Cgljb2xvci5yZ2IgKj0gY29sb3IuYTsKCXJldHVybiBoYWxmNChjb2xvcik7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWZsb2F0MiB0ZXhDb29yZDsKCXRleENvb3JkID0gdmxvY2FsQ29vcmRfUzA7CglvdXRwdXRDb2xvcl9TMCA9IChibGVuZF9tb2R1bGF0ZShjb2xvcl94Zm9ybV9TMChzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzAsIHRleENvb3JkKSksIGhhbGY0KDEpKSk7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgoAAABsb2NhbENvb3JkAAAAAAAA","GZIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAHIBIA5HZ2CAAAAAAAAAQCAAAAASAEEAQAAAAAUCCQAQQGAAAAEAAAAAAGMAAAAAAAIAAAAAQGIAAAAAAA":"DAAAAExTS1POAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzA7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfM19TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzFfYzApICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAAAAlgQAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQp1bmlmb3JtIGZsb2F0NCB1Y2xhbXBfUzFfYzBfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMDsKc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MxOwpub3BlcnNwZWN0aXZlIGluIGhhbGY0IHZjb2xvcl9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzNfUzA7CmhhbGY0IFRleHR1cmVFZmZlY3RfUzFfYzBfYzAoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGluQ29vcmQgPSB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKCWZsb2F0MiBzdWJzZXRDb29yZDsKCXN1YnNldENvb3JkLnggPSBpbkNvb3JkLng7CglzdWJzZXRDb29yZC55ID0gaW5Db29yZC55OwoJZmxvYXQyIGNsYW1wZWRDb29yZDsKCWNsYW1wZWRDb29yZC54ID0gc3Vic2V0Q29vcmQueDsKCWNsYW1wZWRDb29yZC55ID0gY2xhbXAoc3Vic2V0Q29vcmQueSwgdWNsYW1wX1MxX2MwX2MwLnksIHVjbGFtcF9TMV9jMF9jMC53KTsKCWhhbGY0IHRleHR1cmVDb2xvciA9IHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMSwgY2xhbXBlZENvb3JkKTsKCXJldHVybiB0ZXh0dXJlQ29sb3I7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwKF9pbnB1dCk7Cn0KaGFsZjQgRGlzYWJsZUNvdmVyYWdlQXNBbHBoYV9TMShoYWxmNCBfaW5wdXQpIAp7CglfaW5wdXQgPSBNYXRyaXhFZmZlY3RfUzFfYzAoX2lucHV0KTsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJcmV0dXJuIGhhbGY0KF9pbnB1dCk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBEaXNhYmxlQ292ZXJhZ2VBc0FscGhhX1MxKG91dHB1dENvbG9yX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRfUzEgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","GYJBYAQCAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAQAAAAAAQQGABZAA6IAAAAACAAAAAADGAAAAAAAEAAAAAIDEAAAAAAA":"DAAAAExTS1MwAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgcG9zaXRpb247CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmxvY2FsQ29vcmRfUzAgPSBsb2NhbENvb3JkOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgEAAADEBwAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQgdVNyY1RGX1MwWzddOwp1bmlmb3JtIGZsb2F0M3gzIHVDb2xvclhmb3JtX1MwOwp1bmlmb3JtIGZsb2F0IHVEc3RURl9TMFs3XTsKdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CnNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CmZsb2F0IHNyY190Zl9TMChmbG9hdCB4KSAKewoJZmxvYXQgRyA9IHVTcmNURl9TMFswXTsKCWZsb2F0IEEgPSB1U3JjVEZfUzBbMV07CglmbG9hdCBCID0gdVNyY1RGX1MwWzJdOwoJZmxvYXQgQyA9IHVTcmNURl9TMFszXTsKCWZsb2F0IEQgPSB1U3JjVEZfUzBbNF07CglmbG9hdCBFID0gdVNyY1RGX1MwWzVdOwoJZmxvYXQgRiA9IHVTcmNURl9TMFs2XTsKCWZsb2F0IHMgPSBzaWduKHgpOwoJeCA9IGFicyh4KTsKCXggPSAoeCA8IEQpID8gKEMgKiB4KSArIEYgOiBwb3coQSAqIHggKyBCLCBHKSArIEU7CglyZXR1cm4gcyAqIHg7Cn0KZmxvYXQgZHN0X3RmX1MwKGZsb2F0IHgpIAp7CglmbG9hdCBHID0gdURzdFRGX1MwWzBdOwoJZmxvYXQgQSA9IHVEc3RURl9TMFsxXTsKCWZsb2F0IEIgPSB1RHN0VEZfUzBbMl07CglmbG9hdCBDID0gdURzdFRGX1MwWzNdOwoJZmxvYXQgRCA9IHVEc3RURl9TMFs0XTsKCWZsb2F0IEUgPSB1RHN0VEZfUzBbNV07CglmbG9hdCBGID0gdURzdFRGX1MwWzZdOwoJZmxvYXQgcyA9IHNpZ24oeCk7Cgl4ID0gYWJzKHgpOwoJeCA9ICh4IDwgRCkgPyAoQyAqIHgpICsgRiA6IHBvdyhBICogeCArIEIsIEcpICsgRTsKCXJldHVybiBzICogeDsKfQpmbG9hdDQgZ2FtdXRfeGZvcm1fUzAoZmxvYXQ0IGNvbG9yKSAKewoJY29sb3IucmdiID0gKHVDb2xvclhmb3JtX1MwICogY29sb3IucmdiKTsKCXJldHVybiBjb2xvcjsKfQpoYWxmNCBjb2xvcl94Zm9ybV9TMChmbG9hdDQgY29sb3IpIAp7Cgljb2xvci5yID0gc3JjX3RmX1MwKGNvbG9yLnIpOwoJY29sb3IuZyA9IHNyY190Zl9TMChjb2xvci5nKTsKCWNvbG9yLmIgPSBzcmNfdGZfUzAoY29sb3IuYik7Cgljb2xvciA9IGdhbXV0X3hmb3JtX1MwKGNvbG9yKTsKCWNvbG9yLnIgPSBkc3RfdGZfUzAoY29sb3Iucik7Cgljb2xvci5nID0gZHN0X3RmX1MwKGNvbG9yLmcpOwoJY29sb3IuYiA9IGRzdF90Zl9TMChjb2xvci5iKTsKCXJldHVybiBoYWxmNChjb2xvcik7Cn0KaGFsZjQgQ2lyY3VsYXJSUmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglmbG9hdDIgZHh5MCA9IHVpbm5lclJlY3RfUzEuTFQgLSBza19GcmFnQ29vcmQueHk7CglmbG9hdDIgZHh5MSA9IHNrX0ZyYWdDb29yZC54eSAtIHVpbm5lclJlY3RfUzEuUkI7CglmbG9hdDIgZHh5ID0gbWF4KG1heChkeHkwLCBkeHkxKSwgMC4wKTsKCWhhbGYgYWxwaGEgPSBoYWxmKHNhdHVyYXRlKHVyYWRpdXNQbHVzSGFsZl9TMS54IC0gbGVuZ3RoKGR4eSkpKTsKCXJldHVybiBfaW5wdXQgKiBhbHBoYTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMCA9IGhhbGY0KDEpOwoJZmxvYXQyIHRleENvb3JkOwoJdGV4Q29vcmQgPSB2bG9jYWxDb29yZF9TMDsKCW91dHB1dENvbG9yX1MwID0gKGJsZW5kX21vZHVsYXRlKGNvbG9yX3hmb3JtX1MwKHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMCwgdGV4Q29vcmQpKSwgaGFsZjQoMSkpKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBDaXJjdWxhclJSZWN0X1MxKG91dHB1dENvdmVyYWdlX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoBAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgoAAABsb2NhbENvb3JkAAAAAAAA","DAQAAAAAAAAAAAAAAJQAAIGAAEACBYQCAGAEFAIBAAAAAABAAAAAAAAAAAACAA6QAAAABYCTIUIE4AIAAAYAAAAAQAAAAAGARL4FIEMEKMAAAAAMAAAAAAAAAAAAAMADAAAAAIAAAAAAAIIDAAAA":"DAAAAExTS1N4AgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0MiB1QXRsYXNTaXplSW52X1MwOwppbiBmbG9hdDIgaW5Qb3NpdGlvbjsKaW4gaGFsZjQgaW5Db2xvcjsKaW4gdXNob3J0MiBpblRleHR1cmVDb29yZHM7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQgdlRleEluZGV4X1MwOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgQml0bWFwVGV4dAoJaW50IHRleElkeCA9IDA7CglmbG9hdDIgdW5vcm1UZXhDb29yZHMgPSBmbG9hdDIoaW5UZXh0dXJlQ29vcmRzLngsIGluVGV4dHVyZUNvb3Jkcy55KTsKCXZUZXh0dXJlQ29vcmRzX1MwID0gdW5vcm1UZXhDb29yZHMgKiB1QXRsYXNTaXplSW52X1MwOwoJdlRleEluZGV4X1MwID0gZmxvYXQodGV4SWR4KTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzFfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247Cglza19Qb3NpdGlvbiA9IGluUG9zaXRpb24ueHkwMTsKfQoBAAAAnwUAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQpjb25zdCBpbnQga0ZpbGxCV19TMV9jMCA9IDA7CmNvbnN0IGludCBrSW52ZXJzZUZpbGxCV19TMV9jMCA9IDI7CmNvbnN0IGludCBrSW52ZXJzZUZpbGxBQV9TMV9jMCA9IDM7CnVuaWZvcm0gZmxvYXQ0IHVyZWN0VW5pZm9ybV9TMV9jMDsKc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdCB2VGV4SW5kZXhfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gaGFsZjQgdmluQ29sb3JfUzA7CmhhbGY0IFJlY3RfUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF8wX2luQ29sb3IgPSBfaW5wdXQ7CgloYWxmIGNvdmVyYWdlOwoJaWYgKGludCgxKSA9PSBrRmlsbEJXX1MxX2MwIHx8IGludCgxKSA9PSBrSW52ZXJzZUZpbGxCV19TMV9jMCkgCgl7CgkJY292ZXJhZ2UgPSBoYWxmKGFsbChncmVhdGVyVGhhbihmbG9hdDQoc2tfRnJhZ0Nvb3JkLnh5LCB1cmVjdFVuaWZvcm1fUzFfYzAuencpLCBmbG9hdDQodXJlY3RVbmlmb3JtX1MxX2MwLnh5LCBza19GcmFnQ29vcmQueHkpKSkpOwoJfQoJZWxzZSAKCXsKCQloYWxmNCBkaXN0czQgPSBzYXR1cmF0ZShoYWxmNCgxLjAsIDEuMCwgLTEuMCwgLTEuMCkgKiBoYWxmNChza19GcmFnQ29vcmQueHl4eSAtIHVyZWN0VW5pZm9ybV9TMV9jMCkpOwoJCWhhbGYyIGRpc3RzMiA9IChkaXN0czQueHkgKyBkaXN0czQuencpIC0gMS4wOwoJCWNvdmVyYWdlID0gZGlzdHMyLnggKiBkaXN0czIueTsKCX0KCWlmIChpbnQoMSkgPT0ga0ludmVyc2VGaWxsQldfUzFfYzAgfHwgaW50KDEpID09IGtJbnZlcnNlRmlsbEFBX1MxX2MwKSAKCXsKCQljb3ZlcmFnZSA9IDEuMCAtIGNvdmVyYWdlOwoJfQoJcmV0dXJuIGhhbGY0KGhhbGY0KGNvdmVyYWdlKSk7Cn0KaGFsZjQgQmxlbmRfUzEoaGFsZjQgX3NyYywgaGFsZjQgX2RzdCkgCnsKCXJldHVybiBibGVuZF9tb2R1bGF0ZShSZWN0X1MxX2MwKF9zcmMpLCBfc3JjKTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgQml0bWFwVGV4dAoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZpbkNvbG9yX1MwOwoJaGFsZjQgdGV4Q29sb3I7Cgl7CgkJdGV4Q29sb3IgPSBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzAsIHZUZXh0dXJlQ29vcmRzX1MwKS5ycnJyOwoJfQoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSB0ZXhDb2xvcjsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IEJsZW5kX1MxKG91dHB1dENvdmVyYWdlX1MwLCBoYWxmNCgxKSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACgAAAGluUG9zaXRpb24AAAcAAABpbkNvbG9yAA8AAABpblRleHR1cmVDb29yZHMAAAAAAA==","GZIACAAAABQAAGAAAQ4AAAAAGQQAARC4GAAAIOCAAD6P7777777777YDAAAAAAAAAAAHIBK2VD3EOCAAAAAABUXHIMAQAAAAWSQ4HO4SAAAAAMAAAAAAAAQAABANBBK3CICAAAEASHSVIGAAAAAAAAAAAEAABAAVAGSM7BYCAAAAA2CDQ53SKAIAABQAAAAAAACAAAEAUAF3OJAIAAAAAI6LVEYAAAAAAAAQAAAAFPJIMDXPJIBAAAGAAAAAAAAIAAAAAQIXNZERAAAAABDJMU3BAAAAAAAEAAAAAMQQAIAAAQGQQVNREBAAACAAAAAAQAKRC5HBSYCACAAAAAAAAAEAIRDJMU3BAAAAAAACAAAAAVTIMQ4RKBQAAAAAAAAAACAAIAIAAIAAAAC2BCEAQAAAAAAAAAAAMADAAAAAUAAAAAAAIIDA":"DAAAAExTS1NNAgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzBfYzBfYzE7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQgY292ZXJhZ2U7CmluIGhhbGY0IGNvbG9yOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdCB2Y292ZXJhZ2VfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfN19TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDIgcG9zaXRpb24gPSBwb3NpdGlvbi54eTsKCXZjb2xvcl9TMCA9IGNvbG9yOwoJdmNvdmVyYWdlX1MwID0gY292ZXJhZ2U7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzdfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxX2MwX2MwX2MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAEAAADKCgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gaGFsZjQgdXN0YXJ0X1MxX2MwX2MwX2MwX2MwOwp1bmlmb3JtIGhhbGY0IHVlbmRfUzFfYzBfYzBfYzBfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMF9jMTsKdW5pZm9ybSBoYWxmNCB1bGVmdEJvcmRlckNvbG9yX1MxX2MwX2MwOwp1bmlmb3JtIGhhbGY0IHVyaWdodEJvcmRlckNvbG9yX1MxX2MwX2MwOwp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzE7CnVuaWZvcm0gaGFsZiB1cmFuZ2VfUzE7CnNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMTsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQgdmNvdmVyYWdlX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfN19TMDsKaGFsZjQgU2luZ2xlSW50ZXJ2YWxDb2xvcml6ZXJfUzFfYzBfYzBfYzBfYzAoaGFsZjQgX2lucHV0LCBmbG9hdDIgX2Nvb3JkcykgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJZmxvYXQyIF90bXBfMV9jb29yZHMgPSBfY29vcmRzOwoJcmV0dXJuIGhhbGY0KG1peCh1c3RhcnRfUzFfYzBfYzBfYzBfYzAsIHVlbmRfUzFfYzBfYzBfYzBfYzAsIGhhbGYoX3RtcF8xX2Nvb3Jkcy54KSkpOwp9CmhhbGY0IGNvbG9yX3hmb3JtX1MxX2MwX2MwX2MwKGZsb2F0NCBjb2xvcikgCnsKCWNvbG9yLnJnYiAqPSBjb2xvci5hOwoJcmV0dXJuIGhhbGY0KGNvbG9yKTsKfQpoYWxmNCBDb2xvclNwYWNlWGZvcm1fUzFfYzBfYzBfYzAoaGFsZjQgX2lucHV0LCBmbG9hdDIgX2Nvb3JkcykgCnsKCXJldHVybiBjb2xvcl94Zm9ybV9TMV9jMF9jMF9jMChTaW5nbGVJbnRlcnZhbENvbG9yaXplcl9TMV9jMF9jMF9jMF9jMChfaW5wdXQsIF9jb29yZHMpKTsKfQpoYWxmNCBMaW5lYXJMYXlvdXRfUzFfYzBfYzBfYzFfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF8yX2luQ29sb3IgPSBfaW5wdXQ7CglmbG9hdDIgX3RtcF8zX2Nvb3JkcyA9IHZUcmFuc2Zvcm1lZENvb3Jkc183X1MwOwoJcmV0dXJuIGhhbGY0KGhhbGY0KGhhbGYoX3RtcF8zX2Nvb3Jkcy54KSArIDFlLTA1LCAxLjAsIDAuMCwgMC4wKSk7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxX2MwX2MwX2MxKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBMaW5lYXJMYXlvdXRfUzFfYzBfYzBfYzFfYzAoX2lucHV0KTsKfQpoYWxmNCBDbGFtcGVkR3JhZGllbnRfUzFfYzBfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF80X2luQ29sb3IgPSBfaW5wdXQ7CgloYWxmNCB0ID0gTWF0cml4RWZmZWN0X1MxX2MwX2MwX2MxKF90bXBfNF9pbkNvbG9yKTsKCWhhbGY0IG91dENvbG9yOwoJaWYgKCFib29sKGludCgxKSkgJiYgdC55IDwgMC4wKSAKCXsKCQlvdXRDb2xvciA9IGhhbGY0KDAuMCk7Cgl9CgllbHNlIGlmICh0LnggPCAwLjApIAoJewoJCW91dENvbG9yID0gdWxlZnRCb3JkZXJDb2xvcl9TMV9jMF9jMDsKCX0KCWVsc2UgaWYgKHQueCA+IDEuMCkgCgl7CgkJb3V0Q29sb3IgPSB1cmlnaHRCb3JkZXJDb2xvcl9TMV9jMF9jMDsKCX0KCWVsc2UgCgl7CgkJb3V0Q29sb3IgPSBDb2xvclNwYWNlWGZvcm1fUzFfYzBfYzBfYzAoX3RtcF80X2luQ29sb3IsIGZsb2F0MihoYWxmMih0LngsIDAuMCkpKTsKCX0KCXJldHVybiBoYWxmNChvdXRDb2xvcik7Cn0KaGFsZjQgRGlzYWJsZUNvdmVyYWdlQXNBbHBoYV9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CglfaW5wdXQgPSBDbGFtcGVkR3JhZGllbnRfUzFfYzBfYzAoX2lucHV0KTsKCWhhbGY0IF90bXBfNV9pbkNvbG9yID0gX2lucHV0OwoJcmV0dXJuIGhhbGY0KF9pbnB1dCk7Cn0KaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMV9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJcmV0dXJuIHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMSwgX2Nvb3JkcykuMDAwcjsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzFfYzEoaGFsZjQgX2lucHV0LCBmbG9hdDIgX2Nvb3JkcykgCnsKCXJldHVybiBUZXh0dXJlRWZmZWN0X1MxX2MxX2MwKF9pbnB1dCwgZmxvYXQzeDIodW1hdHJpeF9TMV9jMSkgKiBfY29vcmRzLnh5MSk7Cn0KaGFsZjQgRGl0aGVyX1MxKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfNl9pbkNvbG9yID0gX2lucHV0OwoJaGFsZjQgY29sb3IgPSBEaXNhYmxlQ292ZXJhZ2VBc0FscGhhX1MxX2MwKF90bXBfNl9pbkNvbG9yKTsKCWhhbGYgdmFsdWUgPSBNYXRyaXhFZmZlY3RfUzFfYzEoX3RtcF82X2luQ29sb3IsIHNrX0ZyYWdDb29yZC54eSkudyAtIDAuNTsKCXJldHVybiBoYWxmNChoYWxmNChjbGFtcChjb2xvci54eXogKyB2YWx1ZSAqIHVyYW5nZV9TMSwgMC4wLCBjb2xvci53KSwgY29sb3IudykpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7CglmbG9hdCBjb3ZlcmFnZSA9IHZjb3ZlcmFnZV9TMDsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoY292ZXJhZ2UpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gRGl0aGVyX1MxKG91dHB1dENvbG9yX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSAoaGFsZjQoMS4wKSAtIG91dHB1dF9TMSkgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAHBvc2l0aW9uCAAAAGNvdmVyYWdlBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","DASAAAAAAAAAAAEAAFQAAIGAAEAOB77776PUEAIBAAAAAABAAAAAAABAMQAAAMYAAAAAAAQAAAABAMQAAAAA":"DAAAAExTS1MpAgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0MiB1QXRsYXNTaXplSW52X1MwOwppbiBmbG9hdDIgaW5Qb3NpdGlvbjsKaW4gdXNob3J0MiBpblRleHR1cmVDb29yZHM7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQgdlRleEluZGV4X1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBCaXRtYXBUZXh0CglpbnQgdGV4SWR4ID0gMDsKCWZsb2F0MiB1bm9ybVRleENvb3JkcyA9IGZsb2F0MihpblRleHR1cmVDb29yZHMueCwgaW5UZXh0dXJlQ29vcmRzLnkpOwoJdlRleHR1cmVDb29yZHNfUzAgPSB1bm9ybVRleENvb3JkcyAqIHVBdGxhc1NpemVJbnZfUzA7Cgl2VGV4SW5kZXhfUzAgPSBmbG9hdCh0ZXhJZHgpOwoJZmxvYXQyIF90bXBfMV9pblBvc2l0aW9uID0gaW5Qb3NpdGlvbjsKCXNrX1Bvc2l0aW9uID0gaW5Qb3NpdGlvbi54eTAxOwp9CgAAAAAAAAAsAgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gaGFsZjQgdUNvbG9yX1MwOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQyIHZUZXh0dXJlQ29vcmRzX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0IHZUZXhJbmRleF9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIEJpdG1hcFRleHQKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB1Q29sb3JfUzA7CgloYWxmNCB0ZXhDb2xvcjsKCXsKCQl0ZXhDb2xvciA9IHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMCwgdlRleHR1cmVDb29yZHNfUzApOwoJfQoJb3V0cHV0Q29sb3JfUzAgPSBvdXRwdXRDb2xvcl9TMCAqIHRleENvbG9yOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACgAAAGluUG9zaXRpb24AAA8AAABpblRleHR1cmVDb29yZHMAAAAAAA==","GYJAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAQAAAAAAQQGAAZAADIAAAAAJKLCRQQAAAAAAMAAAAACAAAAAIAAAAALAIQEVFRIYIAAAAAAGAAAAABAAAAAAAAAAAAAGABQAAAAEAAAAAAAEEBQA":"DAAAAExTS1MwAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgcG9zaXRpb247CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmxvY2FsQ29vcmRfUzAgPSBsb2NhbENvb3JkOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgEAAACEBgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCmNvbnN0IGludCBrRmlsbEJXX1MxX2MwID0gMDsKY29uc3QgaW50IGtGaWxsQUFfUzFfYzAgPSAxOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQldfUzFfYzAgPSAyOwp1bmlmb3JtIGZsb2F0NCB1ZWxsaXBzZV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdXNjYWxlX1MxX2MwOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQyIHZsb2NhbENvb3JkX1MwOwpoYWxmNCBFbGxpcHNlX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJZmxvYXQyIGQgPSBza19GcmFnQ29vcmQueHkgLSB1ZWxsaXBzZV9TMV9jMC54eTsKCWlmIChib29sKGludCgwKSkpIAoJewoJCWQgKj0gdXNjYWxlX1MxX2MwLnk7Cgl9CglmbG9hdDIgWiA9IGQgKiB1ZWxsaXBzZV9TMV9jMC56dzsKCWZsb2F0IGltcGxpY2l0ID0gZG90KFosIGQpIC0gMS4wOwoJZmxvYXQgZ3JhZF9kb3QgPSA0LjAgKiBkb3QoWiwgWik7CglpZiAoYm9vbChpbnQoMCkpKSAKCXsKCQlncmFkX2RvdCA9IG1heChncmFkX2RvdCwgNi4xMDM2ZS0wNSk7Cgl9CgllbHNlIAoJewoJCWdyYWRfZG90ID0gbWF4KGdyYWRfZG90LCAxLjE3NTVlLTM4KTsKCX0KCWZsb2F0IGFwcHJveF9kaXN0ID0gaW1wbGljaXQgKiBpbnZlcnNlc3FydChncmFkX2RvdCk7CglpZiAoYm9vbChpbnQoMCkpKSAKCXsKCQlhcHByb3hfZGlzdCAqPSB1c2NhbGVfUzFfYzAueDsKCX0KCWhhbGYgYWxwaGE7CglpZiAoaW50KDEpID09IGtGaWxsQldfUzFfYzApIAoJewoJCWFscGhhID0gaGFsZihhcHByb3hfZGlzdCA+IDAuMCA/IDAuMCA6IDEuMCk7Cgl9CgllbHNlIGlmIChpbnQoMSkgPT0ga0ZpbGxBQV9TMV9jMCkgCgl7CgkJYWxwaGEgPSBzYXR1cmF0ZSgwLjUgLSBoYWxmKGFwcHJveF9kaXN0KSk7Cgl9CgllbHNlIGlmIChpbnQoMSkgPT0ga0ludmVyc2VGaWxsQldfUzFfYzApIAoJewoJCWFscGhhID0gaGFsZihhcHByb3hfZGlzdCA+IDAuMCk7Cgl9CgllbHNlIAoJewoJCWFscGhhID0gc2F0dXJhdGUoMC41ICsgaGFsZihhcHByb3hfZGlzdCkpOwoJfQoJcmV0dXJuIGhhbGY0KGhhbGY0KGFscGhhKSk7Cn0KaGFsZjQgQmxlbmRfUzEoaGFsZjQgX3NyYywgaGFsZjQgX2RzdCkgCnsKCXJldHVybiBibGVuZF9tb2R1bGF0ZShFbGxpcHNlX1MxX2MwKF9zcmMpLCBfc3JjKTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMCA9IGhhbGY0KDEpOwoJZmxvYXQyIHRleENvb3JkOwoJdGV4Q29vcmQgPSB2bG9jYWxDb29yZF9TMDsKCW91dHB1dENvbG9yX1MwID0gKGJsZW5kX21vZHVsYXRlKHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMCwgdGV4Q29vcmQpLCBoYWxmNCgxKSkpOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IEJsZW5kX1MxKG91dHB1dENvdmVyYWdlX1MwLCBoYWxmNCgxKSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAIAAAAcG9zaXRpb24KAAAAbG9jYWxDb29yZAAAAAAAAA==","B2AAQAAABQAAIAABBYAAB7777777777774ABICAAAAAAAAAAAAAABGABAAAAAEAAAAAIBEABAAAAA":"DAAAAExTS1NZAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgaW5Qb3NpdGlvbjsKaW4gaGFsZiBpbkNvdmVyYWdlOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmIHZpbkNvdmVyYWdlX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBEZWZhdWx0R2VvbWV0cnlQcm9jZXNzb3IKCWZsb2F0MiBfdG1wXzFfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247Cgl2aW5Db3ZlcmFnZV9TMCA9IGluQ292ZXJhZ2U7Cglza19Qb3NpdGlvbiA9IF90bXBfMV9pblBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAAAJgBAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKdW5pZm9ybSBoYWxmNCB1Q29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gaGFsZiB2aW5Db3ZlcmFnZV9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIERlZmF1bHRHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHVDb2xvcl9TMDsKCWhhbGYgYWxwaGEgPSAxLjA7CglhbHBoYSA9IHZpbkNvdmVyYWdlX1MwOwoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChhbHBoYSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAoAAABpblBvc2l0aW9uAAAKAAAAaW5Db3ZlcmFnZQAAAAAAAA==","GZIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAJIBBKQPNFTIACAAADQOAIAAAAAWFBZKQHMFVIAAAAADQOAIAAAACI6DQCAAAAACQIKACCAYAA4DQAAAAAAZQAAAAAABAAAAACAZAAAAAAA":"DAAAAExTS1PIAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfMl9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzEpICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAAkJAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKY29uc3QgaW50IGtNYXhMb29wTGltaXRfUzFfYzAgPSAzOwp1bmlmb3JtIGhhbGY0IHVib3JkZXJfUzFfYzBfYzBfYzA7CnVuaWZvcm0gZmxvYXQ0IHVzdWJzZXRfUzFfYzBfYzBfYzA7CnVuaWZvcm0gZmxvYXQyIHVpZGltc19TMV9jMF9jMF9jMDsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxX2MwX2MwOwp1bmlmb3JtIGhhbGY0IHVrZXJuZWxfUzFfYzBbN107CnVuaWZvcm0gaGFsZjQgdW9mZnNldHNfUzFfYzBbMTRdOwp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CnNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMTsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwpoYWxmNCBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwX2MwKGhhbGY0IF9pbnB1dCwgZmxvYXQyIF9jb29yZHMpIAp7CglmbG9hdDIgaW5Db29yZCA9IF9jb29yZHM7CglmbG9hdDIgc3Vic2V0Q29vcmQ7CglzdWJzZXRDb29yZC54ID0gaW5Db29yZC54OwoJc3Vic2V0Q29vcmQueSA9IGluQ29vcmQueTsKCWZsb2F0MiBjbGFtcGVkQ29vcmQ7CgljbGFtcGVkQ29vcmQgPSBzdWJzZXRDb29yZDsKCWhhbGY0IHRleHR1cmVDb2xvciA9IHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMSwgKGNsYW1wZWRDb29yZCkgKiB1aWRpbXNfUzFfYzBfYzBfYzApOwoJZmxvYXQgc25hcHBlZFggPSBmbG9vcihpbkNvb3JkLnggKyAwLjAwMSkgKyAwLjU7CglpZiAoc25hcHBlZFggPCB1c3Vic2V0X1MxX2MwX2MwX2MwLnggfHwgc25hcHBlZFggPiB1c3Vic2V0X1MxX2MwX2MwX2MwLnopIAoJewoJCXRleHR1cmVDb2xvciA9IHVib3JkZXJfUzFfYzBfYzBfYzA7Cgl9CglmbG9hdCBzbmFwcGVkWSA9IGZsb29yKGluQ29vcmQueSArIDAuMDAxKSArIDAuNTsKCWlmIChzbmFwcGVkWSA8IHVzdWJzZXRfUzFfYzBfYzBfYzAueSB8fCBzbmFwcGVkWSA+IHVzdWJzZXRfUzFfYzBfYzBfYzAudykgCgl7CgkJdGV4dHVyZUNvbG9yID0gdWJvcmRlcl9TMV9jMF9jMF9jMDsKCX0KCXJldHVybiB0ZXh0dXJlQ29sb3I7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxX2MwX2MwKGhhbGY0IF9pbnB1dCwgZmxvYXQyIF9jb29yZHMpIAp7CglyZXR1cm4gVGV4dHVyZUVmZmVjdF9TMV9jMF9jMF9jMChfaW5wdXQsIGZsb2F0M3gyKHVtYXRyaXhfUzFfYzBfYzApICogX2Nvb3Jkcy54eTEpOwp9CmhhbGY0IHJ1bnRpbWVfc2hhZGVyX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJZmxvYXQyIF90bXBfMV9jb29yZHMgPSB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKCWhhbGY0IHN1bSA9IGhhbGY0KDAuMCk7Cglmb3IgKGludCBpID0gMDtpIDwga01heExvb3BMaW1pdF9TMV9jMDsgKytpKSAKCXsKCQloYWxmNCBrID0gdWtlcm5lbF9TMV9jMFtpXTsKCQloYWxmNCBvID0gdW9mZnNldHNfUzFfYzBbMiAqIGldOwoJCXN1bSArPSBrLnggKiBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoX3RtcF8wX2luQ29sb3IsIF90bXBfMV9jb29yZHMgKyBmbG9hdDIoby54eSkpOwoJCXN1bSArPSBrLnkgKiBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoX3RtcF8wX2luQ29sb3IsIF90bXBfMV9jb29yZHMgKyBmbG9hdDIoby56dykpOwoJCW8gPSB1b2Zmc2V0c19TMV9jMFsyICogaSArIDFdOwoJCXN1bSArPSBrLnogKiBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoX3RtcF8wX2luQ29sb3IsIF90bXBfMV9jb29yZHMgKyBmbG9hdDIoby54eSkpOwoJCXN1bSArPSBrLncgKiBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoX3RtcF8wX2luQ29sb3IsIF90bXBfMV9jb29yZHMgKyBmbG9hdDIoby56dykpOwoJfQoJcmV0dXJuIGhhbGY0KHN1bSk7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBydW50aW1lX3NoYWRlcl9TMV9jMChfaW5wdXQpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gTWF0cml4RWZmZWN0X1MxKG91dHB1dENvbG9yX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRfUzEgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAgAAABwb3NpdGlvbgUAAABjb2xvcgAAAAoAAABsb2NhbENvb3JkAAAAAAAA","GZIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAHIBIA5HZ2CAAAAAAAEAACAAAAASBEAAQAAAAAUCCQAQQGAABAAAAAAAAGMAAAAAAAIAAAAAQGIAAAAAAA":"DAAAAExTS1POAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzA7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfM19TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzFfYzApICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAAAAlgQAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQp1bmlmb3JtIGZsb2F0NCB1Y2xhbXBfUzFfYzBfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMDsKc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MxOwpub3BlcnNwZWN0aXZlIGluIGhhbGY0IHZjb2xvcl9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzNfUzA7CmhhbGY0IFRleHR1cmVFZmZlY3RfUzFfYzBfYzAoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGluQ29vcmQgPSB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKCWZsb2F0MiBzdWJzZXRDb29yZDsKCXN1YnNldENvb3JkLnggPSBpbkNvb3JkLng7CglzdWJzZXRDb29yZC55ID0gaW5Db29yZC55OwoJZmxvYXQyIGNsYW1wZWRDb29yZDsKCWNsYW1wZWRDb29yZC54ID0gY2xhbXAoc3Vic2V0Q29vcmQueCwgdWNsYW1wX1MxX2MwX2MwLngsIHVjbGFtcF9TMV9jMF9jMC56KTsKCWNsYW1wZWRDb29yZC55ID0gc3Vic2V0Q29vcmQueTsKCWhhbGY0IHRleHR1cmVDb2xvciA9IHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMSwgY2xhbXBlZENvb3JkKTsKCXJldHVybiB0ZXh0dXJlQ29sb3I7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwKF9pbnB1dCk7Cn0KaGFsZjQgRGlzYWJsZUNvdmVyYWdlQXNBbHBoYV9TMShoYWxmNCBfaW5wdXQpIAp7CglfaW5wdXQgPSBNYXRyaXhFZmZlY3RfUzFfYzAoX2lucHV0KTsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJcmV0dXJuIGhhbGY0KF9pbnB1dCk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBEaXNhYmxlQ292ZXJhZ2VBc0FscGhhX1MxKG91dHB1dENvbG9yX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRfUzEgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","GZIACAAAABQAAGAAAQ4AAAAAGQQAARC4GAAAIOCAAD6P7777777777YDAAAAAAAAAAAJQBBYGQ467YIAAAAAAQAAAAAMACTRNBZN5QYBAAAAAAAAAAAIAALIAAAAB4FJEIEKOAAAAAMAAAAAUAAQAADAWB7EXCYCAAAGAAAAAAAACAAAQAK7DKJCBCTQAAAADAAAAAAAAAAAAYCADIAAAAAG5O33IKAAAAAAMAAAAAIAAAAAABMJDQP2FUWQUAAAQAAQAAAAAAAAAADGAAAAAAAEAAAAAIDEAAAAAAA":"DAAAAExTS1M7AgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQgY292ZXJhZ2U7CmluIGhhbGY0IGNvbG9yOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdCB2Y292ZXJhZ2VfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDIgcG9zaXRpb24gPSBwb3NpdGlvbi54eTsKCXZjb2xvcl9TMCA9IGNvbG9yOwoJdmNvdmVyYWdlX1MwID0gY292ZXJhZ2U7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgABAAAAxiIAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQpmbG9hdDQgZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzA7CmZsb2F0NCBmcmFnQ29sb3JfUzFfYzA7CmZsb2F0IHVfYWxwaGFfUzFfYzA7CmZsb2F0IHVfc3BhcmtsZV9hbHBoYV9TMV9jMDsKZmxvYXQgdV9ibHVyX1MxX2MwOwpmbG9hdCB1X3JhZGl1c19zY2FsZV9TMV9jMDsKY29uc3QgaW50IGtGaWxsQldfUzJfYzAgPSAwOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQldfUzJfYzAgPSAyOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQUFfUzJfYzAgPSAzOwpjb25zdCBpbnQga0ZpbGxBQV9TMl9jMV9jMCA9IDE7CmNvbnN0IGludCBrSW52ZXJzZUZpbGxCV19TMl9jMV9jMCA9IDI7CmNvbnN0IGludCBrSW52ZXJzZUZpbGxBQV9TMl9jMV9jMCA9IDM7CnVuaWZvcm0gZmxvYXQ0IHVfY29sb3JfUzFfYzA7CnVuaWZvcm0gZmxvYXQ0IHVfY29tcG9zaXRlXzFfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2VudGVyX1MxX2MwOwp1bmlmb3JtIGZsb2F0IHVfbWF4X3JhZGl1c19TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yZXNvbHV0aW9uX3NjYWxlX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X25vaXNlX3NjYWxlX1MxX2MwOwp1bmlmb3JtIGZsb2F0IHVfbm9pc2VfcGhhc2VfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2lyY2xlMV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jaXJjbGUyX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NpcmNsZTNfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcm90YXRpb24xX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3JvdGF0aW9uMl9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yb3RhdGlvbjNfUzFfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKdW5pZm9ybSBmbG9hdDQgdXJlY3RVbmlmb3JtX1MyX2MwOwp1bmlmb3JtIGZsb2F0NCB1Y2lyY2xlX1MyX2MxX2MwOwpub3BlcnNwZWN0aXZlIGluIGhhbGY0IHZjb2xvcl9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdCB2Y292ZXJhZ2VfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwpmbG9hdDIgRkxUX2ZsdXR0ZXJfbG9jYWxfRmx1dHRlckZyYWdDb29yZF9TMV9jMCgpOwpmbG9hdDJ4MiBGTFRfZmx1dHRlcl9sb2NhbF9yb3RhdGUyZF9TMV9jMChmbG9hdDIgcmFkKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgYmx1cik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKGZsb2F0MiByZXNvbHV0aW9uLCBpbm91dCBmbG9hdDIgcCwgZmxvYXQyIHh5LCBmbG9hdDIgcm90YXRpb24sIGZsb2F0IGNlbGxfZGlhbWV0ZXIpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90dXJidWxlbmNlX1MxX2MwKGZsb2F0MiB1dik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfcmluZ19TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCB0aGlja25lc3MsIGZsb2F0IGJsdXIpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90cmlhbmdsZV9ub2lzZV9TMV9jMChpbm91dCBmbG9hdDIgbik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChmbG9hdCB2LCBmbG9hdCBsLCBmbG9hdCBoKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc3BhcmtsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0IHQpOwp2b2lkIEZMVF9tYWluX1MxX2MwKCk7CmZsb2F0MiBGTFRfZmx1dHRlcl9sb2NhbF9GbHV0dGVyRnJhZ0Nvb3JkX1MxX2MwKCkgCnsKCXJldHVybiBmbHV0dGVyX0ZyYWdDb29yZF9TMV9jMC54eTsKfQpmbG9hdDJ4MiBGTFRfZmx1dHRlcl9sb2NhbF9yb3RhdGUyZF9TMV9jMChmbG9hdDIgcmFkKSAKewoJcmV0dXJuIGZsb2F0MngyKHJhZC54LCAtcmFkLnksIHJhZC55LCByYWQueCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgYmx1cikgCnsKCWZsb2F0IGJsdXJfaGFsZiA9IGJsdXIgKiAwLjU7CglmbG9hdCBkID0gZGlzdGFuY2UodXYsIHh5KTsKCXJldHVybiAxLjAgLSBzbW9vdGhzdGVwKDEuMCAtIGJsdXJfaGFsZiwgMS4wICsgYmx1cl9oYWxmLCBkIC8gcmFkaXVzKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChmbG9hdDIgcmVzb2x1dGlvbiwgaW5vdXQgZmxvYXQyIHAsIGZsb2F0MiB4eSwgZmxvYXQyIHJvdGF0aW9uLCBmbG9hdCBjZWxsX2RpYW1ldGVyKSAKewoJZmxvYXQyIHBhcmFtID0gcm90YXRpb247CglwID0gRkxUX2ZsdXR0ZXJfbG9jYWxfcm90YXRlMmRfUzFfYzAocGFyYW0pICogKHh5IC0gcCkgKyB4eTsKCXAgPSBtb2QocCwgZmxvYXQyKGNlbGxfZGlhbWV0ZXIpKSAvIHJlc29sdXRpb247CglmbG9hdCBjZWxsX3V2ID0gKGNlbGxfZGlhbWV0ZXIgLyByZXNvbHV0aW9uLnkpICogMC41OwoJZmxvYXQgciA9IDAuNjUgKiBjZWxsX3V2OwoJZmxvYXQyIHBhcmFtXzEgPSBwOwoJZmxvYXQyIHBhcmFtXzIgPSBmbG9hdDIoY2VsbF91dik7CglmbG9hdCBwYXJhbV8zID0gcjsKCWZsb2F0IHBhcmFtXzQgPSByICogNTAuMDsKCXJldHVybiBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zLCBwYXJhbV80KTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90dXJidWxlbmNlX1MxX2MwKGZsb2F0MiB1dikgCnsKCWZsb2F0MiB1dl9zY2FsZSA9IHV2ICogZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW0gPSBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbV8xID0gdXZfc2NhbGU7CglmbG9hdDIgcGFyYW1fMiA9IHVfY2lyY2xlMV9TMV9jMDsKCWZsb2F0MiBwYXJhbV8zID0gdV9yb3RhdGlvbjFfUzFfYzA7CglmbG9hdCBwYXJhbV80ID0gMC4xNzsKCWZsb2F0IF8zMTkgPSBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChwYXJhbSwgcGFyYW1fMSwgcGFyYW1fMiwgcGFyYW1fMywgcGFyYW1fNCk7CglmbG9hdCBnMSA9IF8zMTk7CglmbG9hdDIgcGFyYW1fNSA9IGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtXzYgPSB1dl9zY2FsZTsKCWZsb2F0MiBwYXJhbV83ID0gdV9jaXJjbGUyX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzggPSB1X3JvdGF0aW9uMl9TMV9jMDsKCWZsb2F0IHBhcmFtXzkgPSAwLjI7CglmbG9hdCBfMzMxID0gRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAocGFyYW1fNSwgcGFyYW1fNiwgcGFyYW1fNywgcGFyYW1fOCwgcGFyYW1fOSk7CglmbG9hdCBnMiA9IF8zMzE7CglmbG9hdDIgcGFyYW1fMTAgPSBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbV8xMSA9IHV2X3NjYWxlOwoJZmxvYXQyIHBhcmFtXzEyID0gdV9jaXJjbGUzX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzEzID0gdV9yb3RhdGlvbjNfUzFfYzA7CglmbG9hdCBwYXJhbV8xNCA9IDAuMjc1OwoJZmxvYXQgXzM0NCA9IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKHBhcmFtXzEwLCBwYXJhbV8xMSwgcGFyYW1fMTIsIHBhcmFtXzEzLCBwYXJhbV8xNCk7CglmbG9hdCBnMyA9IF8zNDQ7CglmbG9hdCB2ID0gKChnMSAqIGcxICsgZzIpIC0gZzMpICogMC41OwoJcmV0dXJuIGNsYW1wKDAuNDUgKyAwLjggKiB2LCAwLjAsIDEuMCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9yaW5nX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IHRoaWNrbmVzcywgZmxvYXQgYmx1cikgCnsKCWZsb2F0MiBwYXJhbSA9IHV2OwoJZmxvYXQyIHBhcmFtXzEgPSB4eTsKCWZsb2F0IHBhcmFtXzIgPSByYWRpdXMgKyB0aGlja25lc3M7CglmbG9hdCBwYXJhbV8zID0gYmx1cjsKCWZsb2F0IGNpcmNsZV9vdXRlciA9IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtLCBwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zKTsKCWZsb2F0MiBwYXJhbV80ID0gdXY7CglmbG9hdDIgcGFyYW1fNSA9IHh5OwoJZmxvYXQgcGFyYW1fNiA9IG1heChyYWRpdXMgLSB0aGlja25lc3MsIDAuMCk7CglmbG9hdCBwYXJhbV83ID0gYmx1cjsKCWZsb2F0IGNpcmNsZV9pbm5lciA9IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtXzQsIHBhcmFtXzUsIHBhcmFtXzYsIHBhcmFtXzcpOwoJcmV0dXJuIGNsYW1wKGNpcmNsZV9vdXRlciAtIGNpcmNsZV9pbm5lciwgMC4wLCAxLjApOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RyaWFuZ2xlX25vaXNlX1MxX2MwKGlub3V0IGZsb2F0MiBuKSAKewoJbiA9IGZyYWN0KG4gKiBmbG9hdDIoNS4zOTg3LCA1LjQ0MjEpKTsKCW4gKz0gZmxvYXQyKGRvdChuLnl4LCBuICsgZmxvYXQyKDIxLjUzNTEsIDE0LjMxMzcpKSk7CglmbG9hdCB4eSA9IG4ueCAqIG4ueTsKCXJldHVybiAoZnJhY3QoeHkgKiA5NS40MzA3KSArIGZyYWN0KHh5ICogNzUuMDQ5NjEpKSAtIDEuMDsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAoZmxvYXQgdiwgZmxvYXQgbCwgZmxvYXQgaCkgCnsKCXJldHVybiBzdGVwKGwsIHYpICogKDEuMCAtIHN0ZXAoaCwgdikpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NwYXJrbGVfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdCB0KSAKewoJZmxvYXQyIHBhcmFtID0gdXY7CglmbG9hdCBfMjQyID0gRkxUX2ZsdXR0ZXJfbG9jYWxfdHJpYW5nbGVfbm9pc2VfUzFfYzAocGFyYW0pOwoJZmxvYXQgbiA9IF8yNDI7CglmbG9hdCBwYXJhbV8xID0gbjsKCWZsb2F0IHBhcmFtXzIgPSAwLjA7CglmbG9hdCBwYXJhbV8zID0gMC4wNTsKCWZsb2F0IHMgPSBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAocGFyYW1fMSwgcGFyYW1fMiwgcGFyYW1fMyk7CglmbG9hdCBwYXJhbV80ID0gbiArIHNpbigzLjE0MTU5Mjc0ICogKHQgKyAwLjM1KSk7CglmbG9hdCBwYXJhbV81ID0gMC4xOwoJZmxvYXQgcGFyYW1fNiA9IDAuMTU7CglzICs9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV80LCBwYXJhbV81LCBwYXJhbV82KTsKCWZsb2F0IHBhcmFtXzcgPSBuICsgc2luKDMuMTQxNTkyNzQgKiAodCArIDAuNykpOwoJZmxvYXQgcGFyYW1fOCA9IDAuMjsKCWZsb2F0IHBhcmFtXzkgPSAwLjI1OwoJcyArPSBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAocGFyYW1fNywgcGFyYW1fOCwgcGFyYW1fOSk7CglmbG9hdCBwYXJhbV8xMCA9IG4gKyBzaW4oMy4xNDE1OTI3NCAqICh0ICsgMS4wNSkpOwoJZmxvYXQgcGFyYW1fMTEgPSAwLjM7CglmbG9hdCBwYXJhbV8xMiA9IDAuMzU7CglzICs9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV8xMCwgcGFyYW1fMTEsIHBhcmFtXzEyKTsKCXJldHVybiBjbGFtcChzLCAwLjAsIDEuMCkgKiAwLjU1Owp9CnZvaWQgRkxUX21haW5fUzFfYzAoKSAKewoJdV9hbHBoYV9TMV9jMCA9IHVfY29tcG9zaXRlXzFfUzFfYzAueDsKCXVfc3BhcmtsZV9hbHBoYV9TMV9jMCA9IHVfY29tcG9zaXRlXzFfUzFfYzAueTsKCXVfYmx1cl9TMV9jMCA9IHVfY29tcG9zaXRlXzFfUzFfYzAuejsKCXVfcmFkaXVzX3NjYWxlX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC53OwoJZmxvYXQyIHAgPSBGTFRfZmx1dHRlcl9sb2NhbF9GbHV0dGVyRnJhZ0Nvb3JkX1MxX2MwKCk7CglmbG9hdDIgdXZfMSA9IHAgKiB1X3Jlc29sdXRpb25fc2NhbGVfUzFfYzA7CglmbG9hdDIgZGVuc2l0eV91diA9IHV2XzEgLSBtb2QocCwgdV9ub2lzZV9zY2FsZV9TMV9jMCk7CglmbG9hdCByYWRpdXMgPSB1X21heF9yYWRpdXNfUzFfYzAgKiB1X3JhZGl1c19zY2FsZV9TMV9jMDsKCWZsb2F0MiBwYXJhbV8xMyA9IHV2XzE7CglmbG9hdCB0dXJidWxlbmNlID0gRkxUX2ZsdXR0ZXJfbG9jYWxfdHVyYnVsZW5jZV9TMV9jMChwYXJhbV8xMyk7CglmbG9hdDIgcGFyYW1fMTQgPSBwOwoJZmxvYXQyIHBhcmFtXzE1ID0gdV9jZW50ZXJfUzFfYzA7CglmbG9hdCBwYXJhbV8xNiA9IHJhZGl1czsKCWZsb2F0IHBhcmFtXzE3ID0gMC4wNSAqIHVfbWF4X3JhZGl1c19TMV9jMDsKCWZsb2F0IHBhcmFtXzE4ID0gdV9ibHVyX1MxX2MwOwoJZmxvYXQgcmluZyA9IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfcmluZ19TMV9jMChwYXJhbV8xNCwgcGFyYW1fMTUsIHBhcmFtXzE2LCBwYXJhbV8xNywgcGFyYW1fMTgpOwoJZmxvYXQyIHBhcmFtXzE5ID0gZGVuc2l0eV91djsKCWZsb2F0IHBhcmFtXzIwID0gdV9ub2lzZV9waGFzZV9TMV9jMDsKCWZsb2F0IHNwYXJrbGUgPSAoKEZMVF9mbHV0dGVyX2xvY2FsX3NwYXJrbGVfUzFfYzAocGFyYW1fMTksIHBhcmFtXzIwKSAqIHJpbmcpICogdHVyYnVsZW5jZSkgKiB1X3NwYXJrbGVfYWxwaGFfUzFfYzA7CglmbG9hdDIgcGFyYW1fMjEgPSBwOwoJZmxvYXQyIHBhcmFtXzIyID0gdV9jZW50ZXJfUzFfYzA7CglmbG9hdCBwYXJhbV8yMyA9IHJhZGl1czsKCWZsb2F0IHBhcmFtXzI0ID0gdV9ibHVyX1MxX2MwOwoJZmxvYXQgd2F2ZV9hbHBoYSA9IChGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChwYXJhbV8yMSwgcGFyYW1fMjIsIHBhcmFtXzIzLCBwYXJhbV8yNCkgKiB1X2FscGhhX1MxX2MwKSAqIHVfY29sb3JfUzFfYzAudzsKCWZsb2F0NCB3YXZlX2NvbG9yID0gZmxvYXQ0KHVfY29sb3JfUzFfYzAueHl6ICogd2F2ZV9hbHBoYSwgd2F2ZV9hbHBoYSk7CglmcmFnQ29sb3JfUzFfYzAgPSBtaXgod2F2ZV9jb2xvciwgZmxvYXQ0KDEuMCksIGZsb2F0NChzcGFya2xlKSk7Cn0KaGFsZjQgcnVudGltZV9zaGFkZXJfUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF8wX2luQ29sb3IgPSBfaW5wdXQ7CglmbG9hdDIgX3RtcF8xX2Nvb3JkcyA9IHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwoJZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzAgPSBmbG9hdDQoX3RtcF8xX2Nvb3JkcywgMC4wLCAwLjApOwoJRkxUX21haW5fUzFfYzAoKTsKCXJldHVybiBoYWxmNChoYWxmNChmcmFnQ29sb3JfUzFfYzApKTsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIHJ1bnRpbWVfc2hhZGVyX1MxX2MwKF9pbnB1dCk7Cn0KaGFsZjQgUmVjdF9TMl9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzJfaW5Db2xvciA9IF9pbnB1dDsKCWhhbGYgY292ZXJhZ2U7CglpZiAoaW50KDEpID09IGtGaWxsQldfUzJfYzAgfHwgaW50KDEpID09IGtJbnZlcnNlRmlsbEJXX1MyX2MwKSAKCXsKCQljb3ZlcmFnZSA9IGhhbGYoYWxsKGdyZWF0ZXJUaGFuKGZsb2F0NChza19GcmFnQ29vcmQueHksIHVyZWN0VW5pZm9ybV9TMl9jMC56dyksIGZsb2F0NCh1cmVjdFVuaWZvcm1fUzJfYzAueHksIHNrX0ZyYWdDb29yZC54eSkpKSk7Cgl9CgllbHNlIAoJewoJCWhhbGY0IGRpc3RzNCA9IHNhdHVyYXRlKGhhbGY0KDEuMCwgMS4wLCAtMS4wLCAtMS4wKSAqIGhhbGY0KHNrX0ZyYWdDb29yZC54eXh5IC0gdXJlY3RVbmlmb3JtX1MyX2MwKSk7CgkJaGFsZjIgZGlzdHMyID0gKGRpc3RzNC54eSArIGRpc3RzNC56dykgLSAxLjA7CgkJY292ZXJhZ2UgPSBkaXN0czIueCAqIGRpc3RzMi55OwoJfQoJaWYgKGludCgxKSA9PSBrSW52ZXJzZUZpbGxCV19TMl9jMCB8fCBpbnQoMSkgPT0ga0ludmVyc2VGaWxsQUFfUzJfYzApIAoJewoJCWNvdmVyYWdlID0gMS4wIC0gY292ZXJhZ2U7Cgl9CglyZXR1cm4gaGFsZjQoaGFsZjQoY292ZXJhZ2UpKTsKfQpoYWxmNCBDaXJjbGVfUzJfYzFfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF8zX2luQ29sb3IgPSBfaW5wdXQ7CgloYWxmIGQ7CglpZiAoaW50KDEpID09IGtJbnZlcnNlRmlsbEJXX1MyX2MxX2MwIHx8IGludCgxKSA9PSBrSW52ZXJzZUZpbGxBQV9TMl9jMV9jMCkgCgl7CgkJZCA9IGhhbGYoKGxlbmd0aCgodWNpcmNsZV9TMl9jMV9jMC54eSAtIHNrX0ZyYWdDb29yZC54eSkgKiB1Y2lyY2xlX1MyX2MxX2MwLncpIC0gMS4wKSAqIHVjaXJjbGVfUzJfYzFfYzAueik7Cgl9CgllbHNlIAoJewoJCWQgPSBoYWxmKCgxLjAgLSBsZW5ndGgoKHVjaXJjbGVfUzJfYzFfYzAueHkgLSBza19GcmFnQ29vcmQueHkpICogdWNpcmNsZV9TMl9jMV9jMC53KSkgKiB1Y2lyY2xlX1MyX2MxX2MwLnopOwoJfQoJcmV0dXJuIGhhbGY0KGhhbGY0KGludCgxKSA9PSBrRmlsbEFBX1MyX2MxX2MwIHx8IGludCgxKSA9PSBrSW52ZXJzZUZpbGxBQV9TMl9jMV9jMCA/IHNhdHVyYXRlKGQpIDogaGFsZihkID4gMC41KSkpOwp9CmhhbGY0IEJsZW5kX1MyX2MxKGhhbGY0IF9zcmMsIGhhbGY0IF9kc3QpIAp7CglyZXR1cm4gYmxlbmRfbW9kdWxhdGUoX3NyYywgQ2lyY2xlX1MyX2MxX2MwKF9zcmMpKTsKfQpoYWxmNCBCbGVuZF9TMihoYWxmNCBfc3JjLCBoYWxmNCBfZHN0KSAKewoJcmV0dXJuIGJsZW5kX21vZHVsYXRlKFJlY3RfUzJfYzAoX3NyYyksIEJsZW5kX1MyX2MxKF9zcmMsIF9kc3QpKTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJZmxvYXQgY292ZXJhZ2UgPSB2Y292ZXJhZ2VfUzA7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGNvdmVyYWdlKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IE1hdHJpeEVmZmVjdF9TMShvdXRwdXRDb2xvcl9TMCk7CgloYWxmNCBvdXRwdXRfUzI7CglvdXRwdXRfUzIgPSBCbGVuZF9TMihvdXRwdXRDb3ZlcmFnZV9TMCwgaGFsZjQoMSkpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dF9TMjsKCX0KfQoAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAHBvc2l0aW9uCAAAAGNvdmVyYWdlBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA="}} \ No newline at end of file From 925845a130d117cc0f1f4c84c59bf459805cb0a7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 17 Nov 2024 22:42:58 +0900 Subject: [PATCH 13/22] Bump github/codeql-action from 3.27.2 to 3.27.4 (#1298) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.27.2 to 3.27.4. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/9278e421667d5d90a2839487a482448c4ec7df4d...ea9e4e37992a54ee68a9622e985e60c8e8f12d9f) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/quality-check.yml | 4 ++-- .github/workflows/scorecards.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/quality-check.yml b/.github/workflows/quality-check.yml index 6d1147af9..4051df96a 100644 --- a/.github/workflows/quality-check.yml +++ b/.github/workflows/quality-check.yml @@ -69,7 +69,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@9278e421667d5d90a2839487a482448c4ec7df4d # v3.27.2 + uses: github/codeql-action/init@ea9e4e37992a54ee68a9622e985e60c8e8f12d9f # v3.27.4 with: languages: ${{ matrix.language }} build-mode: ${{ matrix.build-mode }} @@ -83,6 +83,6 @@ jobs: ./flutterw build apk --profile -t lib/main_play.dart --flavor play - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@9278e421667d5d90a2839487a482448c4ec7df4d # v3.27.2 + uses: github/codeql-action/analyze@ea9e4e37992a54ee68a9622e985e60c8e8f12d9f # v3.27.4 with: category: "/language:${{matrix.language}}" diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index 08dd5476e..a2291978f 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -71,6 +71,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@9278e421667d5d90a2839487a482448c4ec7df4d # v3.27.2 + uses: github/codeql-action/upload-sarif@ea9e4e37992a54ee68a9622e985e60c8e8f12d9f # v3.27.4 with: sarif_file: results.sarif From b16bb127496ccb94c973ec6ae6fc9f8b3ec88320 Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Sun, 17 Nov 2024 15:20:25 +0100 Subject: [PATCH 14/22] l10n by weblate (#1288) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Translate-URL: https://hosted.weblate.org/projects/aves/app-android/et/ Translate-URL: https://hosted.weblate.org/projects/aves/app-android/ru/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/ar/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/es/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/et/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/fr/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/id/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/ko/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/nl/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/pl/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/pt/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/sv/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/tr/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/zh_Hans/ Translate-URL: https://hosted.weblate.org/projects/aves/store-short-description/et/ Translation: Aves/App - Android Translation: Aves/App - Main Translation: Aves/Store - Short description Co-authored-by: Cleverson Cândido Co-authored-by: Hasan Kara Co-authored-by: Languages add-on Co-authored-by: Linerly Co-authored-by: Mohamed Zeroug Co-authored-by: Priit Jõerüüt Co-authored-by: Shift18 Co-authored-by: Stephan Paternotte Co-authored-by: Thibault Deckers Co-authored-by: bittin1ddc447d824349b2 Co-authored-by: gallegonovato Co-authored-by: kaajjo Co-authored-by: rehork Co-authored-by: wanzh --- .../app/src/main/res/values-et/strings.xml | 12 + .../metadata/android/et/full_description.txt | 5 + .../metadata/android/et/short_description.txt | 1 + lib/l10n/app_ar.arb | 4 +- lib/l10n/app_et.arb | 468 ++++++++++++++++++ lib/l10n/app_id.arb | 4 +- lib/l10n/app_nl.arb | 4 +- lib/l10n/app_pt.arb | 8 +- lib/l10n/app_sv.arb | 2 +- lib/l10n/app_tr.arb | 8 +- lib/l10n/app_zh.arb | 10 +- 11 files changed, 519 insertions(+), 7 deletions(-) create mode 100644 android/app/src/main/res/values-et/strings.xml create mode 100644 fastlane/metadata/android/et/full_description.txt create mode 100644 fastlane/metadata/android/et/short_description.txt create mode 100644 lib/l10n/app_et.arb diff --git a/android/app/src/main/res/values-et/strings.xml b/android/app/src/main/res/values-et/strings.xml new file mode 100644 index 000000000..b596c8b41 --- /dev/null +++ b/android/app/src/main/res/values-et/strings.xml @@ -0,0 +1,12 @@ + + + Aves + Fotoraam + Taustapilt + Kaart + Otsi + Videod + Meedia tuvastamine + Tuvastame meediat + Peata + \ No newline at end of file diff --git a/fastlane/metadata/android/et/full_description.txt b/fastlane/metadata/android/et/full_description.txt new file mode 100644 index 000000000..6b96ec3ea --- /dev/null +++ b/fastlane/metadata/android/et/full_description.txt @@ -0,0 +1,5 @@ +Aves can handle all sorts of images and videos, including your typical JPEGs and MP4s, but also more exotic things like multi-page TIFFs, SVGs, old AVIs and more! It scans your media collection to identify motion photos, panoramas (aka photo spheres), 360° videos, as well as GeoTIFF files. + +Navigation and search is an important part of Aves. The goal is for users to easily flow from albums to photos to tags to maps, etc. + +Aves integrates with Android (from KitKat to Android 14, including Android TV) with features such as widgets, app shortcuts, screen saver and global search handling. It also works as a media viewer and picker. diff --git a/fastlane/metadata/android/et/short_description.txt b/fastlane/metadata/android/et/short_description.txt new file mode 100644 index 000000000..9900c3286 --- /dev/null +++ b/fastlane/metadata/android/et/short_description.txt @@ -0,0 +1 @@ +Galerii ja metainfo kuvaja \ No newline at end of file diff --git a/lib/l10n/app_ar.arb b/lib/l10n/app_ar.arb index f73a6277c..815c167c3 100644 --- a/lib/l10n/app_ar.arb +++ b/lib/l10n/app_ar.arb @@ -1548,5 +1548,7 @@ "videoActionShowPreviousFrame": "إظهار الإطار السابق", "@videoActionShowPreviousFrame": {}, "videoActionShowNextFrame": "إظهار الإطار التالي", - "@videoActionShowNextFrame": {} + "@videoActionShowNextFrame": {}, + "newAlbumDialogAlbumAlreadyExistsHelper": "الألبوم موجود بالفعل", + "@newAlbumDialogAlbumAlreadyExistsHelper": {} } diff --git a/lib/l10n/app_et.arb b/lib/l10n/app_et.arb new file mode 100644 index 000000000..9bc9c3e5c --- /dev/null +++ b/lib/l10n/app_et.arb @@ -0,0 +1,468 @@ +{ + "welcomeMessage": "Tere tulemast kasutama Avest", + "@welcomeMessage": {}, + "welcomeOptional": "Pole kohustuslik", + "@welcomeOptional": {}, + "itemCount": "{count, plural, =1{{count} objekt} other{{count} objekti}}", + "@itemCount": { + "placeholders": { + "count": { + "format": "decimalPattern" + } + } + }, + "timeSeconds": "{count, plural, =1{{count} sekund} other{{count} sekundit}}", + "@timeSeconds": { + "placeholders": { + "count": { + "format": "decimalPattern" + } + } + }, + "timeMinutes": "{count, plural, =1{{count} minut} other{{count} minutit}}", + "@timeMinutes": { + "placeholders": { + "count": { + "format": "decimalPattern" + } + } + }, + "timeDays": "{count, plural, =1{{count} päev} other{{count} päeva}}", + "@timeDays": { + "placeholders": { + "count": { + "format": "decimalPattern" + } + } + }, + "applyTooltip": "Rakenda", + "@applyTooltip": {}, + "cancelTooltip": "Katkesta", + "@cancelTooltip": {}, + "changeTooltip": "Muuda", + "@changeTooltip": {}, + "nextTooltip": "Järgmine", + "@nextTooltip": {}, + "showTooltip": "Näita", + "@showTooltip": {}, + "hideTooltip": "Peida", + "@hideTooltip": {}, + "actionRemove": "Eemalda", + "@actionRemove": {}, + "resetTooltip": "Lähtesta", + "@resetTooltip": {}, + "saveTooltip": "Salvesta", + "@saveTooltip": {}, + "pickTooltip": "Vali", + "@pickTooltip": {}, + "doubleBackExitMessage": "Väljumiseks klõpsi uuesti nuppu „Tagasi“.", + "@doubleBackExitMessage": {}, + "doNotAskAgain": "Ära küsi enam uuesti", + "@doNotAskAgain": {}, + "sourceStateLoading": "Laadime andmeid", + "@sourceStateLoading": {}, + "sourceStateCataloguing": "Katalogiseerime", + "@sourceStateCataloguing": {}, + "sourceStateLocatingCountries": "Tuvastame riike", + "@sourceStateLocatingCountries": {}, + "sourceStateLocatingPlaces": "Tuvastame asukohti", + "@sourceStateLocatingPlaces": {}, + "chipActionDelete": "Kustuta", + "@chipActionDelete": {}, + "applyButtonLabel": "RAKENDA", + "@applyButtonLabel": {}, + "deleteButtonLabel": "KUSTUTA", + "@deleteButtonLabel": {}, + "nextButtonLabel": "JÄRGMINE", + "@nextButtonLabel": {}, + "showButtonLabel": "NÄITA", + "@showButtonLabel": {}, + "continueButtonLabel": "JÄTKA", + "@continueButtonLabel": {}, + "saveCopyButtonLabel": "SALVESTA KOOPIA", + "@saveCopyButtonLabel": {}, + "chipActionShowCollection": "Näita kogumikus", + "@chipActionShowCollection": {}, + "chipActionGoToAlbumPage": "Näita albumites", + "@chipActionGoToAlbumPage": {}, + "chipActionGoToCountryPage": "Näita riikides", + "@chipActionGoToCountryPage": {}, + "chipActionGoToPlacePage": "Näita asukohtades", + "@chipActionGoToPlacePage": {}, + "chipActionGoToTagPage": "Näita siltides", + "@chipActionGoToTagPage": {}, + "chipActionGoToExplorerPage": "Näita sirvijas", + "@chipActionGoToExplorerPage": {}, + "chipActionFilterOut": "Sõelu välja", + "@chipActionFilterOut": {}, + "chipActionFilterIn": "Sõelu sisse", + "@chipActionFilterIn": {}, + "chipActionHide": "Peida", + "@chipActionHide": {}, + "chipActionLock": "Lukusta", + "@chipActionLock": {}, + "chipActionPin": "Kinnita üles äärde", + "@chipActionPin": {}, + "stopTooltip": "Lõpeta", + "@stopTooltip": {}, + "entryActionOpenMap": "Näita kaardirakenduses", + "@entryActionOpenMap": {}, + "chipActionUnpin": "Eemalda ülalt äärest", + "@chipActionUnpin": {}, + "chipActionRename": "Muuda nime", + "@chipActionRename": {}, + "chipActionShowCountryStates": "Näita riike", + "@chipActionShowCountryStates": {}, + "chipActionCreateAlbum": "Loo album", + "@chipActionCreateAlbum": {}, + "chipActionCreateVault": "Loo turvaruum", + "@chipActionCreateVault": {}, + "chipActionConfigureVault": "Seadista turvaruumi", + "@chipActionConfigureVault": {}, + "entryActionCopyToClipboard": "Kopeeri lõikelauale", + "@entryActionCopyToClipboard": {}, + "entryActionDelete": "Kustuta", + "@entryActionDelete": {}, + "entryActionConvert": "Konverteeri", + "@entryActionConvert": {}, + "entryActionExport": "Ekspordi", + "@entryActionExport": {}, + "entryActionInfo": "Teave", + "@entryActionInfo": {}, + "entryActionRename": "Muuda nime", + "@entryActionRename": {}, + "entryActionRotateCCW": "Pööra vastupäeva", + "@entryActionRotateCCW": {}, + "entryActionRotateCW": "Pööra päripäeva", + "@entryActionRotateCW": {}, + "entryActionFlip": "Pööra ümber horisontaalselt", + "@entryActionFlip": {}, + "entryActionPrint": "Trüki", + "@entryActionPrint": {}, + "entryActionShareImageOnly": "Jaga vaid pilti", + "@entryActionShareImageOnly": {}, + "entryActionShareVideoOnly": "Jaga vaid videot", + "@entryActionShareVideoOnly": {}, + "entryActionViewSource": "Vaata allikat", + "@entryActionViewSource": {}, + "entryActionShowGeoTiffOnMap": "Näita kaardi ülekattena", + "@entryActionShowGeoTiffOnMap": {}, + "entryActionConvertMotionPhotoToStillImage": "Muuda stoppkaadriks", + "@entryActionConvertMotionPhotoToStillImage": {}, + "entryActionViewMotionPhotoVideo": "Ava video", + "@entryActionViewMotionPhotoVideo": {}, + "entryActionEdit": "Muuda", + "@entryActionEdit": {}, + "entryActionOpen": "Ava rakendusega", + "@entryActionOpen": {}, + "entryActionSetAs": "Seadista kui", + "@entryActionSetAs": {}, + "entryActionRotateScreen": "Pööra ekraani", + "@entryActionRotateScreen": {}, + "entryActionAddFavourite": "Lisa lemmikuks", + "@entryActionAddFavourite": {}, + "entryActionRemoveFavourite": "Eemalda lemmikute hulgast", + "@entryActionRemoveFavourite": {}, + "videoActionMute": "Summuta", + "@videoActionMute": {}, + "videoActionUnmute": "Eemalda summutamine", + "@videoActionUnmute": {}, + "videoActionPause": "Peata", + "@videoActionPause": {}, + "videoActionPlay": "Esita", + "@videoActionPlay": {}, + "videoActionReplay10": "Keri tagasi 10 sekundit", + "@videoActionReplay10": {}, + "videoActionSkip10": "Keri edasi 10 sekundit", + "@videoActionSkip10": {}, + "videoActionShowPreviousFrame": "Näita eelmist kaadrit", + "@videoActionShowPreviousFrame": {}, + "videoActionShowNextFrame": "Näita järgmist kaadrit", + "@videoActionShowNextFrame": {}, + "videoActionSelectStreams": "Vali meediavood", + "@videoActionSelectStreams": {}, + "videoActionSetSpeed": "Taasesituse kiirus", + "@videoActionSetSpeed": {}, + "videoRepeatActionSetStart": "Määra algus", + "@videoRepeatActionSetStart": {}, + "videoRepeatActionSetEnd": "Määra lõpp", + "@videoRepeatActionSetEnd": {}, + "viewerActionSettings": "Seadistused", + "@viewerActionSettings": {}, + "configureVaultDialogTitle": "Seadista turvaruumi", + "@configureVaultDialogTitle": {}, + "vaultDialogLockTypeLabel": "Lukustuse tüüp", + "@vaultDialogLockTypeLabel": {}, + "authenticateToConfigureVault": "Turvaruumi seadistamiseks autendi", + "@authenticateToConfigureVault": {}, + "authenticateToUnlockVault": "Turvaruumi lukustuse eemaldamiseks autendi", + "@authenticateToUnlockVault": {}, + "vaultBinUsageDialogMessage": "Mõned turvaruumid kasutavad prügikasti.", + "@vaultBinUsageDialogMessage": {}, + "settingsConfirmationVaultDataLoss": "Näita turvaruumi andmekao hoiatust", + "@settingsConfirmationVaultDataLoss": {}, + "statsTopPlacesSectionTitle": "Populaarsemad kohad", + "@statsTopPlacesSectionTitle": {}, + "statsTopCountriesSectionTitle": "Populaarsemad riigid", + "@statsTopCountriesSectionTitle": {}, + "appName": "Aves", + "@appName": {}, + "welcomeTermsToggle": "Nõustun kasutustingimustega", + "@welcomeTermsToggle": {}, + "columnCount": "{count, plural, =1{{count} veerg} other{{count} veergu}}", + "@columnCount": { + "placeholders": { + "count": { + "format": "decimalPattern" + } + } + }, + "focalLength": "{length} mm", + "@focalLength": { + "placeholders": { + "length": { + "type": "String", + "example": "5.4" + } + } + }, + "clearTooltip": "Tühjenda", + "@clearTooltip": {}, + "previousTooltip": "Eelmine", + "@previousTooltip": {}, + "hideButtonLabel": "PEIDA", + "@hideButtonLabel": {}, + "chipActionSetCover": "Määra kaanepildiks", + "@chipActionSetCover": {}, + "vaultLockTypePattern": "Muster", + "@vaultLockTypePattern": {}, + "vaultLockTypePin": "PIN-kood", + "@vaultLockTypePin": {}, + "newVaultDialogTitle": "Uus turvaruum", + "@newVaultDialogTitle": {}, + "albumTierVaults": "Turvaruumid", + "@albumTierVaults": {}, + "vaultLockTypePassword": "Salasõna", + "@vaultLockTypePassword": {}, + "vaultDialogLockModeWhenScreenOff": "Ekraani väljalülitumisel lukusta turvaruum", + "@vaultDialogLockModeWhenScreenOff": {}, + "newVaultWarningDialogMessage": "Turvaruumis asuvad objektid on nähtavad vaid sellele rakendusele ja mitte ühelgi muul viisil.\n\nKui sa eemaldad nutiseadmest selle rakenduse või kustutad rakenduse andmed, siis kaob igasugune ligipääs nendele objektidele.", + "@newVaultWarningDialogMessage": {}, + "entryActionRestore": "Taasta", + "@entryActionRestore": {}, + "entryActionShare": "Jaga", + "@entryActionShare": {}, + "statsTopTagsSectionTitle": "Populaarsemad sildid", + "@statsTopTagsSectionTitle": {}, + "statsTopStatesSectionTitle": "Populaarsemad osariigid", + "@statsTopStatesSectionTitle": {}, + "statsTopAlbumsSectionTitle": "Populaarsemad albumid", + "@statsTopAlbumsSectionTitle": {}, + "videoActionABRepeat": "A-B kordus", + "@videoActionABRepeat": {}, + "viewerActionLock": "Lukusta vaade", + "@viewerActionLock": {}, + "viewerActionUnlock": "Eemalda vaate lukustus", + "@viewerActionUnlock": {}, + "slideshowActionResume": "Jätka", + "@slideshowActionResume": {}, + "slideshowActionShowInCollection": "Näita kogumikus", + "@slideshowActionShowInCollection": {}, + "entryInfoActionEditDate": "Muuda kuupäeva ja kellaaega", + "@entryInfoActionEditDate": {}, + "entryInfoActionEditLocation": "Muuda asukohta", + "@entryInfoActionEditLocation": {}, + "entryInfoActionEditTitleDescription": "Muuda pealkirja ja kirjeldust", + "@entryInfoActionEditTitleDescription": {}, + "entryInfoActionEditRating": "Muuda hinnangut", + "@entryInfoActionEditRating": {}, + "entryInfoActionEditTags": "Muuda silte", + "@entryInfoActionEditTags": {}, + "entryInfoActionRemoveMetadata": "Eemalda metainfo", + "@entryInfoActionRemoveMetadata": {}, + "videoActionCaptureFrame": "Tee stoppkaader", + "@videoActionCaptureFrame": {}, + "entryInfoActionExportMetadata": "Ekspordi metainfo", + "@entryInfoActionExportMetadata": {}, + "entryInfoActionRemoveLocation": "Eemalda asukoht", + "@entryInfoActionRemoveLocation": {}, + "editorActionTransform": "Muuda", + "@editorActionTransform": {}, + "editorTransformCrop": "Kadreeri", + "@editorTransformCrop": {}, + "editorTransformRotate": "Pööra", + "@editorTransformRotate": {}, + "cropAspectRatioFree": "Vaba", + "@cropAspectRatioFree": {}, + "cropAspectRatioOriginal": "Algne", + "@cropAspectRatioOriginal": {}, + "cropAspectRatioSquare": "Ruut", + "@cropAspectRatioSquare": {}, + "filterAspectRatioLandscapeLabel": "Rõhtloodis", + "@filterAspectRatioLandscapeLabel": {}, + "filterAspectRatioPortraitLabel": "Püstloodis", + "@filterAspectRatioPortraitLabel": {}, + "filterBinLabel": "Prügikast", + "@filterBinLabel": {}, + "filterFavouriteLabel": "Lemmik", + "@filterFavouriteLabel": {}, + "filterNoDateLabel": "Kuupäevata", + "@filterNoDateLabel": {}, + "filterNoAddressLabel": "Aadressita", + "@filterNoAddressLabel": {}, + "filterNoTagLabel": "Sildistamata", + "@filterNoTagLabel": {}, + "filterNoTitleLabel": "Ilma nimeta", + "@filterNoTitleLabel": {}, + "filterOnThisDayLabel": "Täna", + "@filterOnThisDayLabel": {}, + "filterRecentlyAddedLabel": "Hiljuti lisatud", + "@filterRecentlyAddedLabel": {}, + "filterRatingRejectedLabel": "Tagasilükatud", + "@filterRatingRejectedLabel": {}, + "filterTypeAnimatedLabel": "Animeeritud", + "@filterTypeAnimatedLabel": {}, + "filterTypeMotionPhotoLabel": "Liikuv foto", + "@filterTypeMotionPhotoLabel": {}, + "filterTypePanoramaLabel": "Panoraam", + "@filterTypePanoramaLabel": {}, + "filterTypeRawLabel": "Töötlemata raw-vormingus foto", + "@filterTypeRawLabel": {}, + "filterTypeSphericalVideoLabel": "360° video", + "@filterTypeSphericalVideoLabel": {}, + "filterTypeGeotiffLabel": "GeoTIFF", + "@filterTypeGeotiffLabel": {}, + "accessibilityAnimationsRemove": "Eemalda ekraanieffektid", + "@accessibilityAnimationsRemove": {}, + "accessibilityAnimationsKeep": "Jäta ekraanieffektid alles", + "@accessibilityAnimationsKeep": {}, + "albumTierNew": "Uus", + "@albumTierNew": {}, + "albumTierPinned": "Esiletõstetud", + "@albumTierPinned": {}, + "albumTierSpecial": "Üldised", + "@albumTierSpecial": {}, + "albumTierApps": "Rakendused", + "@albumTierApps": {}, + "albumTierRegular": "Muud", + "@albumTierRegular": {}, + "coordinateFormatDms": "KMS", + "@coordinateFormatDms": {}, + "coordinateFormatDecimal": "Kümnendsüsteem", + "@coordinateFormatDecimal": {}, + "coordinateDmsWest": "W", + "@coordinateDmsWest": {}, + "coordinateDmsNorth": "N", + "@coordinateDmsNorth": {}, + "coordinateDmsEast": "E", + "@coordinateDmsEast": {}, + "displayRefreshRatePreferLowest": "Madalaim sagedus", + "@displayRefreshRatePreferLowest": {}, + "displayRefreshRatePreferHighest": "Kõrgeim sagedus", + "@displayRefreshRatePreferHighest": {}, + "keepScreenOnVideoPlayback": "Video taasesitusel", + "@keepScreenOnVideoPlayback": {}, + "keepScreenOnViewerOnly": "Vaid vaate lehel", + "@keepScreenOnViewerOnly": {}, + "keepScreenOnAlways": "Alati", + "@keepScreenOnAlways": {}, + "lengthUnitPixel": "px", + "@lengthUnitPixel": {}, + "lengthUnitPercent": "%", + "@lengthUnitPercent": {}, + "mapStyleGoogleNormal": "Google Maps", + "@mapStyleGoogleNormal": {}, + "mapStyleGoogleHybrid": "Google Maps (hübriidkaart)", + "@mapStyleGoogleHybrid": {}, + "mapStyleGoogleTerrain": "Google Maps (maastik)", + "@mapStyleGoogleTerrain": {}, + "mapStyleOsmLiberty": "OSM Liberty", + "@mapStyleOsmLiberty": {}, + "mapStyleOpenTopoMap": "OpenTopoMap", + "@mapStyleOpenTopoMap": {}, + "mapStyleOsmHot": "OSMi humanitaarkaart", + "@mapStyleOsmHot": {}, + "mapStyleStamenWatercolor": "Stamen Watercolor", + "@mapStyleStamenWatercolor": {}, + "maxBrightnessNever": "Mitte kunagi", + "@maxBrightnessNever": {}, + "subtitlePositionTop": "Üleval", + "@subtitlePositionTop": {}, + "subtitlePositionBottom": "All", + "@subtitlePositionBottom": {}, + "themeBrightnessLight": "Hele kujundus", + "@themeBrightnessLight": {}, + "settingsVideoEnablePip": "Pilt pildis", + "@settingsVideoEnablePip": {}, + "videoControlsPlayOutside": "Ava välises meediamängijas", + "@videoControlsPlayOutside": {}, + "videoLoopModeShortOnly": "Vaid lühivideod", + "@videoLoopModeShortOnly": {}, + "videoPlaybackSkip": "Jäta vahele", + "@videoPlaybackSkip": {}, + "videoPlaybackMuted": "Esita summutatuna", + "@videoPlaybackMuted": {}, + "videoPlaybackWithSound": "Esita heliga", + "@videoPlaybackWithSound": {}, + "videoResumptionModeNever": "Mitte kunagi", + "@videoResumptionModeNever": {}, + "videoResumptionModeAlways": "Alati", + "@videoResumptionModeAlways": {}, + "settingsDisplayRefreshRateModeDialogTitle": "Värskendussagedus", + "@settingsDisplayRefreshRateModeDialogTitle": {}, + "settingsDisplayRefreshRateModeTile": "Ekraani värskendussagedus", + "@settingsDisplayRefreshRateModeTile": {}, + "filterLocatedLabel": "Asukoht tuvastatud", + "@filterLocatedLabel": {}, + "filterNoLocationLabel": "Asukoht tuvastamata", + "@filterNoLocationLabel": {}, + "filterNoRatingLabel": "Pole hinnatud", + "@filterNoRatingLabel": {}, + "filterTaggedLabel": "Sildistatud", + "@filterTaggedLabel": {}, + "filterMimeImageLabel": "Pilt", + "@filterMimeImageLabel": {}, + "filterMimeVideoLabel": "Video", + "@filterMimeVideoLabel": {}, + "coordinateDms": "{coordinate} {direction}", + "@coordinateDms": { + "placeholders": { + "coordinate": { + "type": "String", + "example": "38° 41′ 47.72″" + }, + "direction": { + "type": "String", + "example": "S" + } + } + }, + "coordinateDmsSouth": "S", + "@coordinateDmsSouth": {}, + "nameConflictStrategySkip": "Jäta vahele", + "@nameConflictStrategySkip": {}, + "overlayHistogramLuminance": "Heledus", + "@overlayHistogramLuminance": {}, + "maxBrightnessAlways": "Alati", + "@maxBrightnessAlways": {}, + "overlayHistogramNone": "Määratlemata", + "@overlayHistogramNone": {}, + "nameConflictStrategyRename": "Muuda nime", + "@nameConflictStrategyRename": {}, + "nameConflictStrategyReplace": "Asenda", + "@nameConflictStrategyReplace": {}, + "overlayHistogramRGB": "RGB", + "@overlayHistogramRGB": {}, + "keepScreenOnNever": "Mitte kunagi", + "@keepScreenOnNever": {}, + "videoLoopModeNever": "Mitte kunagi", + "@videoLoopModeNever": {}, + "themeBrightnessDark": "Tume kujundus", + "@themeBrightnessDark": {}, + "themeBrightnessBlack": "Süsimust kujundus", + "@themeBrightnessBlack": {}, + "videoLoopModeAlways": "Alati", + "@videoLoopModeAlways": {}, + "unitSystemMetric": "Meetermõõdustik", + "@unitSystemMetric": {} +} diff --git a/lib/l10n/app_id.arb b/lib/l10n/app_id.arb index 38d90b999..7883a79f3 100644 --- a/lib/l10n/app_id.arb +++ b/lib/l10n/app_id.arb @@ -1390,5 +1390,7 @@ "videoActionShowPreviousFrame": "Tampilkan bingkai sebelumnya", "@videoActionShowPreviousFrame": {}, "videoActionShowNextFrame": "Tampilkan bingkai berikutnya", - "@videoActionShowNextFrame": {} + "@videoActionShowNextFrame": {}, + "newAlbumDialogAlbumAlreadyExistsHelper": "Album sudah ada", + "@newAlbumDialogAlbumAlreadyExistsHelper": {} } diff --git a/lib/l10n/app_nl.arb b/lib/l10n/app_nl.arb index dc244329c..5b16b8702 100644 --- a/lib/l10n/app_nl.arb +++ b/lib/l10n/app_nl.arb @@ -1392,5 +1392,7 @@ "videoActionShowNextFrame": "Volgend frame weergeven", "@videoActionShowNextFrame": {}, "videoActionShowPreviousFrame": "Vorig frame weergeven", - "@videoActionShowPreviousFrame": {} + "@videoActionShowPreviousFrame": {}, + "newAlbumDialogAlbumAlreadyExistsHelper": "Album bestaat al", + "@newAlbumDialogAlbumAlreadyExistsHelper": {} } diff --git a/lib/l10n/app_pt.arb b/lib/l10n/app_pt.arb index 2814a863d..e1132b8b6 100644 --- a/lib/l10n/app_pt.arb +++ b/lib/l10n/app_pt.arb @@ -1386,5 +1386,11 @@ "mapAttributionOsmLiberty": "Blocos por [OpenMapTiles](https://www.openmaptiles.org/), [CC BY](http://creativecommons.org/licenses/by/4.0) • Hospedado por [OSM Americana](https://tile.ourmap.us)", "@mapAttributionOsmLiberty": {}, "mapAttributionOpenTopoMap": "[SRTM](https://www.earthdata.nasa.gov/sensors/srtm) | Blocos por [OpenTopoMap](https://opentopomap.org/), [CC BY-SA](https://creativecommons.org/licenses/by-sa/3.0/)", - "@mapAttributionOpenTopoMap": {} + "@mapAttributionOpenTopoMap": {}, + "videoActionShowNextFrame": "Mostrar próximo quadro", + "@videoActionShowNextFrame": {}, + "newAlbumDialogAlbumAlreadyExistsHelper": "O álbum já existe", + "@newAlbumDialogAlbumAlreadyExistsHelper": {}, + "videoActionShowPreviousFrame": "Mostrar quadro anterior", + "@videoActionShowPreviousFrame": {} } diff --git a/lib/l10n/app_sv.arb b/lib/l10n/app_sv.arb index 2cb81c06f..cf8ed13f6 100644 --- a/lib/l10n/app_sv.arb +++ b/lib/l10n/app_sv.arb @@ -1571,6 +1571,6 @@ "@videoActionShowPreviousFrame": {}, "videoActionShowNextFrame": "Visa nästa bildruta", "@videoActionShowNextFrame": {}, - "newAlbumDialogAlbumAlreadyExistsHelper": "Album existerar redan", + "newAlbumDialogAlbumAlreadyExistsHelper": "Albumet existerar redan", "@newAlbumDialogAlbumAlreadyExistsHelper": {} } diff --git a/lib/l10n/app_tr.arb b/lib/l10n/app_tr.arb index 22b9df042..8b51a1f34 100644 --- a/lib/l10n/app_tr.arb +++ b/lib/l10n/app_tr.arb @@ -1386,5 +1386,11 @@ "mapAttributionOsmLiberty": "Döşemeler [OpenMapTiles](https://www.openmaptiles.org/), [CC BY](http://creativecommons.org/licenses/by/4.0) • Barındıran [OSM Americana](https://tile.ourmap.us)", "@mapAttributionOsmLiberty": {}, "mapAttributionOsmData": "Harita verileri © [OpenStreetMap](https://www.openstreetmap.org/copyright) katkıda bulunanlar", - "@mapAttributionOsmData": {} + "@mapAttributionOsmData": {}, + "videoActionShowNextFrame": "Sonraki kareyi göster", + "@videoActionShowNextFrame": {}, + "newAlbumDialogAlbumAlreadyExistsHelper": "Böyle bir albüm zaten var", + "@newAlbumDialogAlbumAlreadyExistsHelper": {}, + "videoActionShowPreviousFrame": "Önceki kareyi göster", + "@videoActionShowPreviousFrame": {} } diff --git a/lib/l10n/app_zh.arb b/lib/l10n/app_zh.arb index 59046c3c6..f7dc3860a 100644 --- a/lib/l10n/app_zh.arb +++ b/lib/l10n/app_zh.arb @@ -1382,5 +1382,13 @@ "mapAttributionOpenTopoMap": "[SRTM](https://www.earthdata.nasa.gov/sensors/srtm) | 图块由 [OpenTopoMap](https://opentopomap.org/)提供,[CC BY-SA](https://creativecommons.org/licenses/by-sa/3.0/)", "@mapAttributionOpenTopoMap": {}, "mapAttributionOsmData": "地图数据由 © [OpenStreetMap](https://www.openstreetmap.org/copyright) 贡献", - "@mapAttributionOsmData": {} + "@mapAttributionOsmData": {}, + "videoActionShowPreviousFrame": "显示上一帧", + "@videoActionShowPreviousFrame": {}, + "videoActionShowNextFrame": "显示下一帧", + "@videoActionShowNextFrame": {}, + "newAlbumDialogAlbumAlreadyExistsHelper": "相册已存在", + "@newAlbumDialogAlbumAlreadyExistsHelper": {}, + "mapAttributionOsmLiberty": "绘制于 [OpenMapTiles](https://www.openmaptiles.org/), [CC BY](http://creativecommons.org/licenses/by/4.0) • 主办方 [OSM Americana](https://tile.ourmap.us)", + "@mapAttributionOsmLiberty": {} } From a25f117e1bdf7d3842f811681fb2aa479781b2f7 Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Sun, 17 Nov 2024 15:23:00 +0100 Subject: [PATCH 15/22] l10n --- lib/model/app/contributors.dart | 3 +++ lib/widgets/aves_app.dart | 1 + 2 files changed, 4 insertions(+) diff --git a/lib/model/app/contributors.dart b/lib/model/app/contributors.dart index db0b70d97..216c02707 100644 --- a/lib/model/app/contributors.dart +++ b/lib/model/app/contributors.dart @@ -111,12 +111,15 @@ class Contributors { Contributor('Paranoid Android', 'f.cherdzhiev@innopolis.university'), Contributor('Noah Kenzie Rodriguez-Beus', 'noahbeus@protonmail.com'), Contributor('5FeetUnder', '15950507+5FeetUnder@users.noreply.github.com'), + Contributor('Cleverson Cândido', 'optimuspraimu@gmail.com'), + Contributor('Hasan Kara', 'hasanbeytullahkara@gmail.com'), // Contributor('Femini', 'nizamismidov4@gmail.com'), // Azerbaijani // Contributor('Alvi Khan', 'aveenalvi@gmail.com'), // Bengali // Contributor('Htet Oo Hlaing', 'htetoh2006@outlook.com'), // Burmese // Contributor('Khant', 'khant@users.noreply.hosted.weblate.org'), // Burmese // Contributor('Grooty12', 'Rasmus@rosendahl-kaa.name'), // Danish // Contributor('Victor M', 'victormorita@tuta.io'), // Danish + // Contributor('Priit Jõerüüt', 'hwlate@joeruut.com'), // Estonian // Contributor('Åzze', 'laitinen.jere222@gmail.com'), // Finnish // Contributor('Olli', 'ollinen@ollit.dev'), // Finnish // Contributor('Idj', 'joneltmp+goahn@gmail.com'), // Hebrew diff --git a/lib/widgets/aves_app.dart b/lib/widgets/aves_app.dart index 8ed6e7d09..e75829d11 100644 --- a/lib/widgets/aves_app.dart +++ b/lib/widgets/aves_app.dart @@ -68,6 +68,7 @@ class AvesApp extends StatefulWidget { 'bn', // Bengali 'ckb', // Kurdish (Central) 'da', // Danish + 'et', // Estonian 'fi', // Finnish 'gl', // Galician 'he', // Hebrew From ad214b3f5616f6ab8d21b0b6503d2ceeee3dceab Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Sun, 17 Nov 2024 18:15:53 +0100 Subject: [PATCH 16/22] ExifInterface upgrade --- android/app/build.gradle | 8 +- android/exifinterface/build.gradle | 3 +- .../src/main/AndroidManifest.xml | 4 +- .../media/ExifInterfaceFork.java | 837 +++++++++++------- .../media/ExifInterfaceUtilsFork.java | 46 +- 5 files changed, 542 insertions(+), 356 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index eb8171a4a..2eade1cc3 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -154,12 +154,12 @@ dependencies { implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.1' implementation "androidx.appcompat:appcompat:1.7.0" - implementation 'androidx.core:core-ktx:1.13.1' - implementation 'androidx.lifecycle:lifecycle-process:2.8.6' + implementation 'androidx.core:core-ktx:1.15.0' + implementation 'androidx.lifecycle:lifecycle-process:2.8.7' implementation 'androidx.media:media:1.7.0' implementation 'androidx.multidex:multidex:2.0.1' implementation 'androidx.security:security-crypto:1.1.0-alpha06' - implementation 'androidx.work:work-runtime-ktx:2.9.1' + implementation 'androidx.work:work-runtime-ktx:2.10.0' implementation 'com.caverock:androidsvg-aar:1.4' implementation 'com.commonsware.cwac:document:0.5.0' @@ -181,7 +181,7 @@ dependencies { testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.10.3' - kapt 'androidx.annotation:annotation:1.8.2' + kapt 'androidx.annotation:annotation:1.9.1' ksp "com.github.bumptech.glide:ksp:$glide_version" compileOnly rootProject.findProject(':streams_channel') diff --git a/android/exifinterface/build.gradle b/android/exifinterface/build.gradle index 46bfa54d8..7d83b50a2 100644 --- a/android/exifinterface/build.gradle +++ b/android/exifinterface/build.gradle @@ -26,5 +26,6 @@ android { } dependencies { - implementation 'androidx.annotation:annotation:1.8.2' + implementation 'androidx.annotation:annotation:1.9.1' + implementation 'org.jspecify:jspecify:1.0.0' } \ No newline at end of file diff --git a/android/exifinterface/src/main/AndroidManifest.xml b/android/exifinterface/src/main/AndroidManifest.xml index a5918e68a..568741e54 100644 --- a/android/exifinterface/src/main/AndroidManifest.xml +++ b/android/exifinterface/src/main/AndroidManifest.xml @@ -1,4 +1,2 @@ - - - \ No newline at end of file + \ No newline at end of file diff --git a/android/exifinterface/src/main/java/androidx/exifinterface/media/ExifInterfaceFork.java b/android/exifinterface/src/main/java/androidx/exifinterface/media/ExifInterfaceFork.java index 934ee16b5..07bab0f4c 100644 --- a/android/exifinterface/src/main/java/androidx/exifinterface/media/ExifInterfaceFork.java +++ b/android/exifinterface/src/main/java/androidx/exifinterface/media/ExifInterfaceFork.java @@ -22,6 +22,8 @@ import static androidx.exifinterface.media.ExifInterfaceUtilsFork.convertToLongA import static androidx.exifinterface.media.ExifInterfaceUtilsFork.copy; import static androidx.exifinterface.media.ExifInterfaceUtilsFork.parseSubSeconds; import static androidx.exifinterface.media.ExifInterfaceUtilsFork.startsWith; + +import static java.lang.annotation.ElementType.TYPE_USE; import static java.nio.ByteOrder.BIG_ENDIAN; import static java.nio.ByteOrder.LITTLE_ENDIAN; @@ -33,17 +35,19 @@ import android.location.Location; import android.media.MediaDataSource; import android.media.MediaMetadataRetriever; import android.os.Build; +import android.system.Os; import android.system.OsConstants; import android.util.Log; import android.util.Pair; import androidx.annotation.IntDef; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import androidx.annotation.RestrictTo; -import androidx.exifinterface.media.ExifInterfaceUtilsFork.Api21Impl; +import androidx.annotation.VisibleForTesting; import androidx.exifinterface.media.ExifInterfaceUtilsFork.Api23Impl; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; + import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.ByteArrayInputStream; @@ -62,12 +66,14 @@ import java.io.InputStream; import java.io.OutputStream; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.charset.Charset; import java.text.ParsePosition; import java.text.SimpleDateFormat; import java.util.Arrays; +import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.HashSet; @@ -83,20 +89,48 @@ import java.util.regex.Pattern; import java.util.zip.CRC32; /* - * Forked from 'androidx.exifinterface:exifinterface:1.3.7' on 2024/02/21 + * Forked from 'androidx.exifinterface:exifinterface:1.4.0-alpha01' on 2024/11/17 * Named differently to let ExifInterface be loaded as subdependency. + * cf https://github.com/androidx/androidx/tree/androidx-main/exifinterface/exifinterface/src/main/java/androidx/exifinterface/media */ /** * This is a class for reading and writing Exif tags in various image file formats. + * + *

Supported for reading: JPEG, PNG, WebP, HEIC, DNG, CR2, NEF, NRW, ARW, RW2, ORF, PEF, SRW, + * RAF, AVIF (on API 31+). + * + *

Supported for writing: JPEG, PNG, WebP. + * *

- * Supported for reading: JPEG, PNG, WebP, HEIF, DNG, CR2, NEF, NRW, ARW, RW2, ORF, PEF, SRW, RAF. + * + *

XMP Support

*

- * Supported for writing: JPEG, PNG, WebP. - *

- * Note: JPEG and HEIF files may contain XMP data either inside the Exif data chunk or outside of - * it. This class will search both locations for XMP data, but if XMP data exist both inside and - * outside Exif, will favor the XMP data inside Exif over the one outside. + * This class can read raw XMP data from the supported image file formats. + * + *

XMP data can be stored within Exif data (under tag 700), but many of the formats also define a + * separate storage location for XMP. ExifInterface handles this ambiguity as follows: + * + *

    + *
  • JPEG + *
      + *
    • The XMP spec part 3 section 3.3.2 forbids the XMP tag (700) being present in the Exif + * segment of JPEG files (i.e. XMP should always be in a separate APP1 segment). + *
    • If XMP is present in both Exif and separate segments, the XMP from the Exif segment + * is returned from {@link #getAttributeBytes} and modifications to the XMP with {@link + * #setAttribute} are written back to the XMP in the Exif segment, the XMP in the + * separate segment is preserved unmodified. This is contrary to the spec described + * above (which suggests the standalone XMP should be preferred over the XMP in the Exif + * segment). + *
    • If XMP is not present in either location, and is added with {@link #setAttribute}, it + * is written as a standalone segment, in line with the spec described above. + *
    + *
  • HEIC & AVIF + *
      + *
    • If XMP is present in both Exif and separate segments, the XMP from the separate + * segment is returned from {@link #getAttributeBytes}. + *
    + *
*/ public class ExifInterfaceFork { // TLAD threshold for safer Exif attribute parsing @@ -882,29 +916,43 @@ public class ExifInterfaceFork { // G. Tags related to picture-taking condition /** - *

Exposure time, given in seconds.

+ * Exposure time, given in seconds. + * + *

Note: For backwards compatibility this attribute is returned from {@link + * #getAttribute(String)} in decimal form (i.e. the format produced by {@link + * Double#toString(double)}). It is accepted into {@link #setAttribute(String, String)} in both + * rational (e.g. {@code "1/3"}) and decimal forms. The decimal format is anything accepted by + * {@link Double#parseDouble(String)}, e.g. {@code "0.125"}. * *

    - *
  • Tag = 33434
  • - *
  • Type = Unsigned rational
  • - *
  • Count = 1
  • - *
  • Default = None
  • + *
  • Tag = 33434 + *
  • Type = Unsigned rational + *
  • Count = 1 + *
  • Default = None *
*/ public static final String TAG_EXPOSURE_TIME = "ExposureTime"; + /** - *

The F number.

+ * The F number. + * + *

Note: For backwards compatibility this attribute is returned from {@link + * #getAttribute(String)} in decimal form (i.e. the format produced by {@link + * Double#toString(double)}). It is accepted into {@link #setAttribute(String, String)} in both + * rational (e.g. {@code "1/3"}) and decimal forms. The decimal format is anything accepted by + * {@link Double#parseDouble(String)}, e.g. {@code "0.125"}. * *

    - *
  • Tag = 33437
  • - *
  • Type = Unsigned rational
  • - *
  • Count = 1
  • - *
  • Default = None
  • + *
  • Tag = 33437 + *
  • Type = Unsigned rational + *
  • Count = 1 + *
  • Default = None *
*/ public static final String TAG_F_NUMBER = "FNumber"; + /** - *

TThe class of the program used by the camera to set exposure when the picture is taken. + *

The class of the program used by the camera to set exposure when the picture is taken. * The tag values are as follows.

* *
    @@ -1117,19 +1165,28 @@ public class ExifInterfaceFork { *
*/ public static final String TAG_MAX_APERTURE_VALUE = "MaxApertureValue"; + /** - *

The distance to the subject, given in meters. Note that if the numerator of the recorded - * value is 0xFFFFFFFF, Infinity shall be indicated; and if the numerator is 0, Distance - * unknown shall be indicated.

+ * The distance to the subject, given in meters. + * + *

Note that if the numerator of the recorded value is 0xFFFFFFFF, Infinity shall be + * indicated; and if the numerator is 0, Distance unknown shall be indicated. + * + *

Note: For backwards compatibility this attribute is returned from {@link + * #getAttribute(String)} in decimal form (i.e. the format produced by {@link + * Double#toString(double)}). It is accepted into {@link #setAttribute(String, String)} in both + * rational (e.g. {@code "1/3"}) and decimal forms. The decimal format is anything accepted by + * {@link Double#parseDouble(String)}, e.g. {@code "0.125"}. * *

    - *
  • Tag = 37382
  • - *
  • Type = Unsigned rational
  • - *
  • Count = 1
  • - *
  • Default = None
  • + *
  • Tag = 37382 + *
  • Type = Unsigned rational + *
  • Count = 1 + *
  • Default = None *
*/ public static final String TAG_SUBJECT_DISTANCE = "SubjectDistance"; + /** *

The metering mode.

* @@ -1451,18 +1508,26 @@ public class ExifInterfaceFork { * @see #WHITEBALANCE_MANUAL */ public static final String TAG_WHITE_BALANCE = "WhiteBalance"; + /** - *

This tag indicates the digital zoom ratio when the image was shot. If the numerator of - * the recorded value is 0, this indicates that digital zoom was not used.

+ * This tag indicates the digital zoom ratio when the image was shot. If the numerator of the + * recorded value is 0, this indicates that digital zoom was not used. + * + *

Note: For backwards compatibility this attribute is returned from {@link + * #getAttribute(String)} in decimal form (i.e. the format produced by {@link + * Double#toString(double)}). It is accepted into {@link #setAttribute(String, String)} in both + * rational (e.g. {@code "1/3"}) and decimal forms. The decimal format is anything accepted by + * {@link Double#parseDouble(String)}, e.g. {@code "0.125"}. * *

    - *
  • Tag = 41988
  • - *
  • Type = Unsigned rational
  • - *
  • Count = 1
  • - *
  • Default = None
  • + *
  • Tag = 41988 + *
  • Type = Unsigned rational + *
  • Count = 1 + *
  • Default = None *
*/ public static final String TAG_DIGITAL_ZOOM_RATIO = "DigitalZoomRatio"; + /** *

This tag indicates the equivalent focal length assuming a 35mm film camera, in mm. * A value of 0 means the focal length is unknown. Note that this tag differs from @@ -1792,18 +1857,24 @@ public class ExifInterfaceFork { * */ public static final String TAG_GPS_ALTITUDE = "GPSAltitude"; + /** - *

Indicates the time as UTC (Coordinated Universal Time). TimeStamp is expressed as three - * unsigned rational values giving the hour, minute, and second.

+ * Indicates the time as UTC (Coordinated Universal Time). TimeStamp is expressed as three + * unsigned rational values giving the hour, minute, and second. + * + *

Note: This attribute is returned from {@link #getAttribute(String)} and accepted into + * {@link #setAttribute(String, String)} as 3 colon-separated integers, e.g. {@code "11:05:32"}. + * Decimal or rational hours, minutes or seconds parts are not supported. * *

    - *
  • Tag = 7
  • - *
  • Type = Unsigned rational
  • - *
  • Count = 3
  • - *
  • Default = None
  • + *
  • Tag = 7 + *
  • Type = Unsigned rational + *
  • Count = 3 + *
  • Default = None *
*/ public static final String TAG_GPS_TIMESTAMP = "GPSTimeStamp"; + /** *

Indicates the GPS satellites used for measurements. This tag may be used to describe * the number of satellites, their ID number, angle of elevation, azimuth, SNR and other @@ -1876,7 +1947,8 @@ public class ExifInterfaceFork { */ public static final String TAG_GPS_SPEED_REF = "GPSSpeedRef"; /** - *

Indicates the speed of GPS receiver movement.

+ * Indicates the speed of GPS receiver movement. The units are indicated by {@link + * #TAG_GPS_SPEED_REF}. * *
    *
  • Tag = 13
  • @@ -2214,8 +2286,11 @@ public class ExifInterfaceFork { public static final String TAG_RW2_JPG_FROM_RAW = "JpgFromRaw"; /** * Type is byte[]. See Extensible - * Metadata Platform (XMP) for details on contents. + * "https://en.wikipedia.org/wiki/Extensible_Metadata_Platform">Extensible Metadata Platform + * (XMP) for details on contents. + * + *

    See also notes about XMP handling in different containers in the class-level javadoc of + * this class. */ public static final String TAG_XMP = "Xmp"; /** @@ -2984,6 +3059,37 @@ public class ExifInterfaceFork { public @interface ExifStreamType { } + @Retention(RetentionPolicy.SOURCE) + @Target(TYPE_USE) + @IntDef({ + XMP_HANDLING_TIFF_700_ONLY, + XMP_HANDLING_PREFER_SEPARATE, + XMP_HANDLING_PREFER_TIFF_700_IF_PRESENT + }) + private @interface XmpHandling { + } + + /** + * The format only supports XMP data stored in the TIFF/Exif 700 tag (or it supports storing XMP + * in a separate segment but this should never be used). + */ + private static final int XMP_HANDLING_TIFF_700_ONLY = 1; + + /** + * The format supports XMP data stored in a separate segment, and this should always be + * preferred if present. + * + *

    If XMP data is only present in the TIFF/Exif 700 tag it will be read and written from + * there. + */ + private static final int XMP_HANDLING_PREFER_SEPARATE = 2; + + /** + * The format supports XMP data stored in a separate segment, and this should be preferred + * unless XMP is also present in the TIFF/Exif 700 tag. + */ + private static final int XMP_HANDLING_PREFER_TIFF_700_IF_PRESENT = 3; + // Maximum size for checking file type signature (see image_type_recognition_lite.cc) private static final int SIGNATURE_CHECK_SIZE = 5000; @@ -2994,6 +3100,8 @@ public class ExifInterfaceFork { private static final byte[] HEIF_TYPE_FTYP = new byte[]{'f', 't', 'y', 'p'}; private static final byte[] HEIF_BRAND_MIF1 = new byte[]{'m', 'i', 'f', '1'}; private static final byte[] HEIF_BRAND_HEIC = new byte[]{'h', 'e', 'i', 'c'}; + private static final byte[] HEIF_BRAND_AVIF = new byte[]{'a', 'v', 'i', 'f'}; + private static final byte[] HEIF_BRAND_AVIS = new byte[]{'a', 'v', 'i', 's'}; // See http://fileformats.archiveteam.org/wiki/Olympus_ORF private static final short ORF_SIGNATURE_1 = 0x4f52; @@ -3023,12 +3131,9 @@ public class ExifInterfaceFork { (byte) 0x47, (byte) 0x0d, (byte) 0x0a, (byte) 0x1a, (byte) 0x0a}; // See "Extensions to the PNG 1.2 Specification, Version 1.5.0", // 3.7. eXIf Exchangeable Image File (Exif) Profile - private static final byte[] PNG_CHUNK_TYPE_EXIF = new byte[]{(byte) 0x65, (byte) 0x58, - (byte) 0x49, (byte) 0x66}; - private static final byte[] PNG_CHUNK_TYPE_IHDR = new byte[]{(byte) 0x49, (byte) 0x48, - (byte) 0x44, (byte) 0x52}; - private static final byte[] PNG_CHUNK_TYPE_IEND = new byte[]{(byte) 0x49, (byte) 0x45, - (byte) 0x4e, (byte) 0x44}; + private static final int PNG_CHUNK_TYPE_EXIF = 'e' << 24 | 'X' << 16 | 'I' << 8 | 'f'; + private static final int PNG_CHUNK_TYPE_IHDR = 'I' << 24 | 'H' << 16 | 'D' << 8 | 'R'; + private static final int PNG_CHUNK_TYPE_IEND = 'I' << 24 | 'E' << 16 | 'N' << 8 | 'D'; private static final int PNG_CHUNK_TYPE_BYTE_LENGTH = 4; private static final int PNG_CHUNK_CRC_BYTE_LENGTH = 4; @@ -3050,8 +3155,8 @@ public class ExifInterfaceFork { private static final int WEBP_CHUNK_TYPE_BYTE_LENGTH = 4; private static final int WEBP_CHUNK_SIZE_BYTE_LENGTH = 4; - private static SimpleDateFormat sFormatterPrimary; - private static SimpleDateFormat sFormatterSecondary; + private static final SimpleDateFormat sFormatterPrimary; + private static final SimpleDateFormat sFormatterSecondary; // See Exchangeable image file format for digital still cameras: Exif version 2.2. // The following values are for parsing EXIF data area. There are tag groups in EXIF data area. @@ -3085,32 +3190,27 @@ public class ExifInterfaceFork { private static final int SKIP_BUFFER_SIZE = 8192; // Names for the data formats for debugging purpose. - static final String[] IFD_FORMAT_NAMES = new String[]{ + private static final String[] IFD_FORMAT_NAMES = new String[]{ "", "BYTE", "STRING", "USHORT", "ULONG", "URATIONAL", "SBYTE", "UNDEFINED", "SSHORT", "SLONG", "SRATIONAL", "SINGLE", "DOUBLE", "IFD" }; // Sizes of the components of each IFD value format - static final int[] IFD_FORMAT_BYTES_PER_FORMAT = new int[]{ + private static final int[] IFD_FORMAT_BYTES_PER_FORMAT = new int[]{ 0, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8, 1 }; - @SuppressWarnings("WeakerAccess") /* synthetic access */ - static final byte[] EXIF_ASCII_PREFIX = new byte[]{ + private static final byte[] EXIF_ASCII_PREFIX = new byte[]{ 0x41, 0x53, 0x43, 0x49, 0x49, 0x0, 0x0, 0x0 }; // A class for indicating EXIF rational type. - private static class Rational { + // TODO: b/308978831 - Migrate to android.util.Rational when the min API is 21. + @VisibleForTesting + static class Rational { public final long numerator; public final long denominator; - @SuppressWarnings("WeakerAccess") /* synthetic access */ - Rational(double value) { - this((long) (value * 10000), 10000); - } - - @SuppressWarnings("WeakerAccess") /* synthetic access */ - Rational(long numerator, long denominator) { + private Rational(long numerator, long denominator) { // Handle erroneous case if (denominator == 0) { this.numerator = 0; @@ -3121,9 +3221,44 @@ public class ExifInterfaceFork { this.denominator = denominator; } - @NonNull + /** + * Creates a new {@code Rational} which approximates the provided {@code double} value by + * using continued fractions. + */ + public static @NonNull Rational createFromDouble(double value) { + if (value >= Long.MAX_VALUE || value <= Long.MIN_VALUE) { + // value is too large to represent as a long, so just return the max/min value. + return new Rational( + /* numerator= */ value > 0 ? Long.MAX_VALUE : Long.MIN_VALUE, + /* denominator= */ 1); + } + + double absoluteValue = Math.abs(value); + double threshold = 0.00000001 * absoluteValue; + double remainingValue = absoluteValue; + long numerator = 1; + long previousNumerator = 0; + long denominator = 0; + long previousDenominator = 1; + do { + double remainder = remainingValue % 1; + long wholePart = (long) (remainingValue - remainder); + long tmp = numerator; + numerator = wholePart * numerator + previousNumerator; + previousNumerator = tmp; + + tmp = denominator; + denominator = wholePart * denominator + previousDenominator; + previousDenominator = tmp; + + remainingValue = 1 / remainder; + } while ((Math.abs(absoluteValue - numerator / (double) denominator) > threshold)); + + return new Rational(value < 0 ? -numerator : numerator, denominator); + } + @Override - public String toString() { + public @NonNull String toString() { return numerator + "/" + denominator; } @@ -3141,12 +3276,10 @@ public class ExifInterfaceFork { public final long bytesOffset; public final byte[] bytes; - @SuppressWarnings("WeakerAccess") /* synthetic access */ ExifAttribute(int format, int numberOfComponents, byte[] bytes) { this(format, numberOfComponents, BYTES_OFFSET_UNKNOWN, bytes); } - @SuppressWarnings("WeakerAccess") /* synthetic access */ ExifAttribute(int format, int numberOfComponents, long bytesOffset, byte[] bytes) { this.format = format; this.numberOfComponents = numberOfComponents; @@ -3243,13 +3376,11 @@ public class ExifInterfaceFork { return new ExifAttribute(IFD_FORMAT_DOUBLE, values.length, buffer.array()); } - @NonNull @Override - public String toString() { + public @NonNull String toString() { return "(" + IFD_FORMAT_NAMES[format] + ", data length:" + bytes.length + ")"; } - @SuppressWarnings("WeakerAccess") /* synthetic access */ Object getValue(ByteOrder byteOrder) { ByteOrderedDataInputStream inputStream = null; try { @@ -3497,13 +3628,12 @@ public class ExifInterfaceFork { } // A class for indicating EXIF tag. - static class ExifTag { + private static class ExifTag { public final int number; public final String name; public final int primaryFormat; public final int secondaryFormat; - @SuppressWarnings("WeakerAccess") /* synthetic access */ ExifTag(String name, int number, int format) { this.name = name; this.number = number; @@ -3511,7 +3641,6 @@ public class ExifInterfaceFork { this.secondaryFormat = -1; } - @SuppressWarnings("WeakerAccess") /* synthetic access */ ExifTag(String name, int number, int primaryFormat, int secondaryFormat) { this.name = name; this.number = number; @@ -3519,7 +3648,6 @@ public class ExifInterfaceFork { this.secondaryFormat = secondaryFormat; } - @SuppressWarnings("WeakerAccess") /* synthetic access */ boolean isFormatCompatible(int format) { if (primaryFormat == IFD_FORMAT_UNDEFINED || format == IFD_FORMAT_UNDEFINED) { return true; @@ -3785,23 +3913,24 @@ public class ExifInterfaceFork { public @interface IfdType { } - static final int IFD_TYPE_PRIMARY = 0; + private static final int IFD_TYPE_PRIMARY = 0; private static final int IFD_TYPE_EXIF = 1; private static final int IFD_TYPE_GPS = 2; private static final int IFD_TYPE_INTEROPERABILITY = 3; - static final int IFD_TYPE_THUMBNAIL = 4; - static final int IFD_TYPE_PREVIEW = 5; + private static final int IFD_TYPE_THUMBNAIL = 4; + private static final int IFD_TYPE_PREVIEW = 5; private static final int IFD_TYPE_ORF_MAKER_NOTE = 6; private static final int IFD_TYPE_ORF_CAMERA_SETTINGS = 7; private static final int IFD_TYPE_ORF_IMAGE_PROCESSING = 8; private static final int IFD_TYPE_PEF = 9; - // List of Exif tag groups - static final ExifTag[][] EXIF_TAGS = new ExifTag[][]{ - IFD_TIFF_TAGS, IFD_EXIF_TAGS, IFD_GPS_TAGS, IFD_INTEROPERABILITY_TAGS, - IFD_THUMBNAIL_TAGS, IFD_TIFF_TAGS, ORF_MAKER_NOTE_TAGS, ORF_CAMERA_SETTINGS_TAGS, - ORF_IMAGE_PROCESSING_TAGS, PEF_TAGS - }; + // List of Exif tag groups, indexed by the IDF_TYPE_* constants above. + static final ExifTag[][] EXIF_TAGS = + new ExifTag[][]{ + IFD_TIFF_TAGS, IFD_EXIF_TAGS, IFD_GPS_TAGS, IFD_INTEROPERABILITY_TAGS, + IFD_THUMBNAIL_TAGS, IFD_TIFF_TAGS, ORF_MAKER_NOTE_TAGS, ORF_CAMERA_SETTINGS_TAGS, + ORF_IMAGE_PROCESSING_TAGS, PEF_TAGS + }; // List of tags for pointing to the other image file directory offset. private static final ExifTag[] EXIF_POINTER_TAGS = new ExifTag[]{ new ExifTag(TAG_SUB_IFD_POINTER, 330, IFD_FORMAT_ULONG), @@ -3820,9 +3949,30 @@ public class ExifInterfaceFork { @SuppressWarnings("unchecked") private static final HashMap[] sExifTagMapsForWriting = new HashMap[EXIF_TAGS.length]; - private static final HashSet sTagSetForCompatibility = new HashSet<>(Arrays.asList( - TAG_F_NUMBER, TAG_DIGITAL_ZOOM_RATIO, TAG_EXPOSURE_TIME, TAG_SUBJECT_DISTANCE, - TAG_GPS_TIMESTAMP)); + + /** + * These are tags of type 'Unsigned rational' but which are handled in decimal form. + * + *

    This means they are output from {@link #getAttribute(String)}, and accepted into {@link + * #setAttribute(String, String)}, as strings in decimal form (e.g. {@code "0.125"}, {@code + * "6.25E-4"}). + * + *

    This is to maintain backwards compatibility with a previous implementation of the {@link + * android.media.ExifInterface} (the platform variant of this class). + * + *

    See this + * internal code review comment from 2016 for more details. + */ + private static final Set RATIONAL_TAGS_HANDLED_AS_DECIMALS_FOR_COMPATIBILITY = + Collections.unmodifiableSet( + new HashSet<>( + Arrays.asList( + TAG_F_NUMBER, + TAG_DIGITAL_ZOOM_RATIO, + TAG_EXPOSURE_TIME, + TAG_SUBJECT_DISTANCE))); + // Mappings from tag number to IFD type for pointer tags. private static final HashMap sExifPointerTagMap = new HashMap<>(); @@ -3830,9 +3980,9 @@ public class ExifInterfaceFork { // The following values are defined for handling JPEG streams. In this implementation, we are // not only getting information from EXIF but also from some JPEG special segments such as // MARKER_COM for user comment and MARKER_SOFx for image width and height. - @SuppressWarnings("WeakerAccess") /* synthetic access */ - static final Charset ASCII = Charset.forName("US-ASCII"); + private static final Charset ASCII = Charset.forName("US-ASCII"); // Identifier for EXIF APP1 segment in JPEG + @VisibleForTesting static final byte[] IDENTIFIER_EXIF_APP1 = "Exif\0\0".getBytes(ASCII); // Identifier for XMP APP1 segment in JPEG private static final byte[] IDENTIFIER_XMP_APP1 = @@ -3840,7 +3990,7 @@ public class ExifInterfaceFork { // JPEG segment markers, that each marker consumes two bytes beginning with 0xff and ending with // the indicator. There is no SOF4, SOF8, SOF16 markers in JPEG and SOFx markers indicates start // of frame(baseline DCT) and the image size info exists in its beginning part. - static final byte MARKER = (byte) 0xff; + private static final byte MARKER = (byte) 0xff; private static final byte MARKER_SOI = (byte) 0xd8; private static final byte MARKER_SOF0 = (byte) 0xc0; private static final byte MARKER_SOF1 = (byte) 0xc1; @@ -3856,26 +4006,23 @@ public class ExifInterfaceFork { private static final byte MARKER_SOF14 = (byte) 0xce; private static final byte MARKER_SOF15 = (byte) 0xcf; private static final byte MARKER_SOS = (byte) 0xda; + @VisibleForTesting static final byte MARKER_APP1 = (byte) 0xe1; private static final byte MARKER_COM = (byte) 0xfe; - static final byte MARKER_EOI = (byte) 0xd9; + private static final byte MARKER_EOI = (byte) 0xd9; // Supported Image File Types - static final int IMAGE_TYPE_UNKNOWN = 0; - static final int IMAGE_TYPE_ARW = 1; - static final int IMAGE_TYPE_CR2 = 2; - static final int IMAGE_TYPE_DNG = 3; - static final int IMAGE_TYPE_JPEG = 4; - static final int IMAGE_TYPE_NEF = 5; - static final int IMAGE_TYPE_NRW = 6; - static final int IMAGE_TYPE_ORF = 7; - static final int IMAGE_TYPE_PEF = 8; - static final int IMAGE_TYPE_RAF = 9; - static final int IMAGE_TYPE_RW2 = 10; - static final int IMAGE_TYPE_SRW = 11; - static final int IMAGE_TYPE_HEIF = 12; - static final int IMAGE_TYPE_PNG = 13; - static final int IMAGE_TYPE_WEBP = 14; + private static final int IMAGE_TYPE_UNKNOWN = 0; + private static final int IMAGE_TYPE_DNG = 3; + private static final int IMAGE_TYPE_JPEG = 4; + private static final int IMAGE_TYPE_ORF = 7; + private static final int IMAGE_TYPE_PEF = 8; + private static final int IMAGE_TYPE_RAF = 9; + private static final int IMAGE_TYPE_RW2 = 10; + private static final int IMAGE_TYPE_HEIC = 12; + private static final int IMAGE_TYPE_PNG = 13; + private static final int IMAGE_TYPE_WEBP = 14; + private static final int IMAGE_TYPE_AVIF = 15; static { sFormatterPrimary = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss", Locale.US); @@ -3925,9 +4072,16 @@ public class ExifInterfaceFork { private int mOrfThumbnailOffset; private int mOrfThumbnailLength; private boolean mModified; - // XMP data can be contained as either part of the EXIF data (tag number 700), or as a - // separate data marker (a separate MARKER_APP1). - private boolean mXmpIsFromSeparateMarker; + + /** + * XMP data can occur as either part of the TIFF/Exif data (tag number 700), or as a separate + * section of the file (e.g. a separate APP1 segment in JPEG). XMP read from within the + * TIFF/Exif data is stored in {@link #mAttributes}, while XMP read from a separate section is + * here. If both are present, the disambiguation rules vary per file format, see + * {@link #getXmpHandlingForImageType(int)}. + */ + @Nullable + private ExifAttribute mXmpFromSeparateMarker; // Pattern to check non zero timestamp private static final Pattern NON_ZERO_TIME_PATTERN = Pattern.compile(".*[1-9].*"); @@ -3989,13 +4143,13 @@ public class ExifInterfaceFork { mFilename = null; boolean isFdDuped = false; - if (Build.VERSION.SDK_INT >= 21 && isSeekableFD(fileDescriptor)) { + if (isSeekableFD(fileDescriptor)) { mSeekableFileDescriptor = fileDescriptor; // Keep the original file descriptor in order to save attributes when it's seekable. // Otherwise, just close the given file descriptor after reading it because the save // feature won't be working. try { - fileDescriptor = Api21Impl.dup(fileDescriptor); + fileDescriptor = Os.dup(fileDescriptor); isFdDuped = true; } catch (Exception e) { throw new IOException("Failed to duplicate file descriptor", e); @@ -4106,9 +4260,7 @@ public class ExifInterfaceFork { * * @param tag the name of the tag. */ - @SuppressWarnings("deprecation") - @Nullable - private ExifAttribute getExifAttribute(@NonNull String tag) { + private @Nullable ExifAttribute getExifAttribute(@NonNull String tag) { if (tag == null) { throw new NullPointerException("tag shouldn't be null"); } @@ -4120,6 +4272,11 @@ public class ExifInterfaceFork { } tag = TAG_PHOTOGRAPHIC_SENSITIVITY; } + if (TAG_XMP.equals(tag) + && getXmpHandlingForImageType(mMimeType) == XMP_HANDLING_PREFER_SEPARATE + && mXmpFromSeparateMarker != null) { + return mXmpFromSeparateMarker; + } // Retrieves all tag groups. The value from primary image tag group has a higher priority // than the value from the thumbnail tag group if there are more than one candidates. for (int i = 0; i < EXIF_TAGS.length; ++i) { @@ -4128,49 +4285,80 @@ public class ExifInterfaceFork { return value; } } + if (TAG_XMP.equals(tag) && mXmpFromSeparateMarker != null) { + return mXmpFromSeparateMarker; + } return null; } + private static @XmpHandling int getXmpHandlingForImageType(int imageType) { + switch (imageType) { + // ExifInterface has a documented (but spec-violating) preference for reading and + // writing JPEG XMP data from Exif/TIFF tag 700 instead of a separate XMP APP1 segment + // if both are present. + case IMAGE_TYPE_JPEG: + return XMP_HANDLING_PREFER_TIFF_700_IF_PRESENT; + case IMAGE_TYPE_AVIF: + case IMAGE_TYPE_HEIC: + // RAF stores XMP/Exif in JPEG, but we have no documented backwards-compat obligations + // so we can implement the spec to store XMP in a separate APP1 segment. + case IMAGE_TYPE_RAF: + return XMP_HANDLING_PREFER_SEPARATE; + case IMAGE_TYPE_DNG: + case IMAGE_TYPE_ORF: + case IMAGE_TYPE_PEF: + case IMAGE_TYPE_RW2: + case IMAGE_TYPE_UNKNOWN: + // PNG and WebP support a separate XMP chunk (so should be + // XMP_HANDLING_PREFER_SEPARATE), but ExifInterface doesn't currently read or write + // them. + case IMAGE_TYPE_PNG: + case IMAGE_TYPE_WEBP: + default: + return XMP_HANDLING_TIFF_700_ONLY; + } + } + /** * Returns the value of the specified tag or {@code null} if there * is no such tag in the image file. * * @param tag the name of the tag. */ - @Nullable - public String getAttribute(@NonNull String tag) { + public @Nullable String getAttribute(@NonNull String tag) { if (tag == null) { throw new NullPointerException("tag shouldn't be null"); } ExifAttribute attribute = getExifAttribute(tag); - if (attribute != null) { - if (!sTagSetForCompatibility.contains(tag)) { - return attribute.getStringValue(mExifByteOrder); + if (attribute == null) { + return null; + } + if (tag.equals(TAG_GPS_TIMESTAMP)) { + // Convert GPS timestamp value to a custom format for backwards compatibility. + if (attribute.format != IFD_FORMAT_URATIONAL + && attribute.format != IFD_FORMAT_SRATIONAL) { + Log.w(TAG, "GPS Timestamp format is not rational. format=" + attribute.format); + return null; } - if (tag.equals(TAG_GPS_TIMESTAMP)) { - // Convert the rational values to the custom formats for backwards compatibility. - if (attribute.format != IFD_FORMAT_URATIONAL - && attribute.format != IFD_FORMAT_SRATIONAL) { - Log.w(TAG, "GPS Timestamp format is not rational. format=" + attribute.format); - return null; - } - Rational[] array = (Rational[]) attribute.getValue(mExifByteOrder); - if (array == null || array.length != 3) { - Log.w(TAG, "Invalid GPS Timestamp array. array=" + Arrays.toString(array)); - return null; - } - return String.format(Locale.ROOT, "%02d:%02d:%02d", - (int) ((float) array[0].numerator / array[0].denominator), - (int) ((float) array[1].numerator / array[1].denominator), - (int) ((float) array[2].numerator / array[2].denominator)); + Rational[] array = (Rational[]) attribute.getValue(mExifByteOrder); + if (array == null || array.length != 3) { + Log.w(TAG, "Invalid GPS Timestamp array. array=" + Arrays.toString(array)); + return null; } + return String.format("%02d:%02d:%02d", + (int) ((float) array[0].numerator / array[0].denominator), + (int) ((float) array[1].numerator / array[1].denominator), + (int) ((float) array[2].numerator / array[2].denominator)); + } else if (RATIONAL_TAGS_HANDLED_AS_DECIMALS_FOR_COMPATIBILITY.contains(tag)) { + // Convert the rational values to the custom formats for backwards compatibility. try { return Double.toString(attribute.getDoubleValue(mExifByteOrder)); } catch (NumberFormatException e) { return null; } + } else { + return attribute.getStringValue(mExifByteOrder); } - return null; } /** @@ -4232,10 +4420,45 @@ public class ExifInterfaceFork { if (tag == null) { throw new NullPointerException("tag shouldn't be null"); } - // Validate and convert if necessary. - if (TAG_DATETIME.equals(tag) || TAG_DATETIME_ORIGINAL.equals(tag) - || TAG_DATETIME_DIGITIZED.equals(tag)) { - if (value != null) { + + // Maintain compatibility. + if (TAG_ISO_SPEED_RATINGS.equals(tag)) { + if (DEBUG) { + Log.d(TAG, "setAttribute: Replacing TAG_ISO_SPEED_RATINGS with " + + "TAG_PHOTOGRAPHIC_SENSITIVITY."); + } + tag = TAG_PHOTOGRAPHIC_SENSITIVITY; + } + // Maybe convert the given value for backwards compatibility. + if (value != null) { + if (RATIONAL_TAGS_HANDLED_AS_DECIMALS_FOR_COMPATIBILITY.contains(tag) + && !value.contains("/")) { + // Convert floating point values to rational for rational tags that are emitted and + // consumed as floating point values for backwards compatibility. + try { + double doubleValue = Double.parseDouble(value); + value = Rational.createFromDouble(doubleValue).toString(); + } catch (NumberFormatException e) { + Log.w(TAG, "Invalid value for " + tag + " : " + value); + return; + } + } else if (tag.equals(TAG_GPS_TIMESTAMP)) { + Matcher m = GPS_TIMESTAMP_PATTERN.matcher(value); + if (!m.find()) { + Log.w(TAG, "Invalid value for " + tag + " : " + value); + return; + } + value = + Integer.parseInt(m.group(1)) + + "/1," + + Integer.parseInt(m.group(2)) + + "/1," + + Integer.parseInt(m.group(3)) + + "/1"; + } else if (TAG_DATETIME.equals(tag) + || TAG_DATETIME_ORIGINAL.equals(tag) + || TAG_DATETIME_DIGITIZED.equals(tag)) { + // Validate and convert datetime values if necessary. boolean isPrimaryFormat = DATETIME_PRIMARY_FORMAT_PATTERN.matcher(value).find(); boolean isSecondaryFormat = DATETIME_SECONDARY_FORMAT_PATTERN.matcher(value).find(); // Validate @@ -4245,8 +4468,8 @@ public class ExifInterfaceFork { return; } // If datetime value has secondary format (e.g. 2020-01-01 00:00:00), convert it to - // primary format (e.g. 2020:01:01 00:00:00) since it is the format in the - // official documentation. + // primary format (e.g. 2020:01:01 00:00:00) since it is the format in the official + // documentation. // See JEITA CP-3451C Section 4.6.4. D. Other Tags, DateTime if (isSecondaryFormat) { // Replace "-" with ":" to match the primary format. @@ -4254,32 +4477,18 @@ public class ExifInterfaceFork { } } } - // Maintain compatibility. - if (TAG_ISO_SPEED_RATINGS.equals(tag)) { - if (DEBUG) { - Log.d(TAG, "setAttribute: Replacing TAG_ISO_SPEED_RATINGS with " - + "TAG_PHOTOGRAPHIC_SENSITIVITY."); - } - tag = TAG_PHOTOGRAPHIC_SENSITIVITY; - } - // Convert the given value to rational values for backwards compatibility. - if (value != null && sTagSetForCompatibility.contains(tag)) { - if (tag.equals(TAG_GPS_TIMESTAMP)) { - Matcher m = GPS_TIMESTAMP_PATTERN.matcher(value); - if (!m.find()) { - Log.w(TAG, "Invalid value for " + tag + " : " + value); - return; - } - value = Integer.parseInt(m.group(1)) + "/1," + Integer.parseInt(m.group(2)) + "/1," - + Integer.parseInt(m.group(3)) + "/1"; - } else { - try { - double doubleValue = Double.parseDouble(value); - value = new Rational(doubleValue).toString(); - } catch (NumberFormatException e) { - Log.w(TAG, "Invalid value for " + tag + " : " + value); - return; - } + + if (TAG_XMP.equals(tag)) { + boolean containsTiff700Xmp = + mAttributes[IFD_TYPE_PRIMARY].containsKey(TAG_XMP) + || mAttributes[IFD_TYPE_PREVIEW].containsKey(TAG_XMP); + @XmpHandling int xmpHandling = getXmpHandlingForImageType(mMimeType); + if ((xmpHandling == XMP_HANDLING_PREFER_SEPARATE + && (mXmpFromSeparateMarker != null || !containsTiff700Xmp)) + || (xmpHandling == XMP_HANDLING_PREFER_TIFF_700_IF_PRESENT + && !containsTiff700Xmp)) { + mXmpFromSeparateMarker = ExifAttribute.createByte(value); + return; } } @@ -4600,8 +4809,8 @@ public class ExifInterfaceFork { return; } } else { - if (mMimeType == IMAGE_TYPE_HEIF) { - getHeifAttributes(inputStream); + if (mMimeType == IMAGE_TYPE_HEIC || mMimeType == IMAGE_TYPE_AVIF) { + getHeifAttributes(inputStream, mMimeType); } else if (mMimeType == IMAGE_TYPE_ORF) { getOrfAttributes(inputStream); } else if (mMimeType == IMAGE_TYPE_RW2) { @@ -4630,7 +4839,7 @@ public class ExifInterfaceFork { // Ignore exceptions in order to keep the compatibility with the old versions of // ExifInterface. if (DEBUG) { - Log.w(TAG, "Invalid image: ExifInterface got an unsupported image format file" + Log.w(TAG, "Invalid image: ExifInterface got an unsupported image format file " + "(ExifInterface supports JPEG and some RAW image formats only) " + "or a corrupted JPEG file to ExifInterface.", e); } @@ -4644,18 +4853,15 @@ public class ExifInterfaceFork { } private static boolean isSeekableFD(FileDescriptor fd) { - if (Build.VERSION.SDK_INT >= 21) { - try { - Api21Impl.lseek(fd, 0, OsConstants.SEEK_CUR); - return true; - } catch (Exception e) { - if (DEBUG) { - Log.d(TAG, "The file descriptor for the given input is not seekable"); - } - return false; + try { + Os.lseek(fd, /* offset= */ 0, /* whence= */ OsConstants.SEEK_CUR); + return true; + } catch (Exception e) { + if (DEBUG) { + Log.d(TAG, "The file descriptor for the given input is not seekable"); } + return false; } - return false; } // Prints out attributes for debugging. @@ -4719,12 +4925,11 @@ public class ExifInterfaceFork { if (mFilename != null) { in = new FileInputStream(mFilename); } else { - // mSeekableFileDescriptor will be non-null only for SDK_INT >= 21, but this check - // is needed to prevent calling Os.lseek at runtime for SDK < 21. - if (Build.VERSION.SDK_INT >= 21) { - Api21Impl.lseek(mSeekableFileDescriptor, 0, OsConstants.SEEK_SET); - in = new FileInputStream(mSeekableFileDescriptor); - } + Os.lseek( + mSeekableFileDescriptor, + /* offset= */ 0, + /* whence= */ OsConstants.SEEK_SET); + in = new FileInputStream(mSeekableFileDescriptor); } out = new FileOutputStream(tempFile); copy(in, out); @@ -4746,12 +4951,9 @@ public class ExifInterfaceFork { if (mFilename != null) { out = new FileOutputStream(mFilename); } else { - // mSeekableFileDescriptor will be non-null only for SDK_INT >= 21, but this check - // is needed to prevent calling Os.lseek at runtime for SDK < 21. - if (Build.VERSION.SDK_INT >= 21) { - Api21Impl.lseek(mSeekableFileDescriptor, 0, OsConstants.SEEK_SET); - out = new FileOutputStream(mSeekableFileDescriptor); - } + FileDescriptor fd = mSeekableFileDescriptor; + Os.lseek(fd, /* offset= */ 0, /* whence= */ OsConstants.SEEK_SET); + out = new FileOutputStream(mSeekableFileDescriptor); } bufferedIn = new BufferedInputStream(in); bufferedOut = new BufferedOutputStream(out); @@ -4769,12 +4971,11 @@ public class ExifInterfaceFork { if (mFilename != null) { out = new FileOutputStream(mFilename); } else { - // mSeekableFileDescriptor will be non-null only for SDK_INT >= 21, but this - // check is needed to prevent calling Os.lseek at runtime for SDK < 21. - if (Build.VERSION.SDK_INT >= 21) { - Api21Impl.lseek(mSeekableFileDescriptor, 0, OsConstants.SEEK_SET); - out = new FileOutputStream(mSeekableFileDescriptor); - } + Os.lseek( + mSeekableFileDescriptor, + /* offset= */ 0, + /* whence= */ OsConstants.SEEK_SET); + out = new FileOutputStream(mSeekableFileDescriptor); } copy(in, out); } catch (Exception exception) { @@ -4820,8 +5021,7 @@ public class ExifInterfaceFork { * The returned data can be decoded using * {@link BitmapFactory#decodeByteArray(byte[], int, int)} */ - @Nullable - public byte[] getThumbnail() { + public byte @Nullable [] getThumbnail() { if (mThumbnailCompression == DATA_JPEG || mThumbnailCompression == DATA_JPEG_COMPRESSED) { return getThumbnailBytes(); } @@ -4832,8 +5032,7 @@ public class ExifInterfaceFork { * Returns the thumbnail bytes inside the image file, regardless of the compression type of the * thumbnail image. */ - @Nullable - public byte[] getThumbnailBytes() { + public byte @Nullable [] getThumbnailBytes() { if (!mHasThumbnail) { return null; } @@ -4856,13 +5055,9 @@ public class ExifInterfaceFork { } else if (mFilename != null) { in = new FileInputStream(mFilename); } else { - // mSeekableFileDescriptor will be non-null only for SDK_INT >= 21, but this check - // is needed to prevent calling Os.lseek and Os.dup at runtime for SDK < 21. - if (Build.VERSION.SDK_INT >= 21) { - newFileDescriptor = Api21Impl.dup(mSeekableFileDescriptor); - Api21Impl.lseek(newFileDescriptor, 0, OsConstants.SEEK_SET); - in = new FileInputStream(newFileDescriptor); - } + newFileDescriptor = Os.dup(mSeekableFileDescriptor); + Os.lseek(newFileDescriptor, /* offset= */ 0, /* whence= */ OsConstants.SEEK_SET); + in = new FileInputStream(newFileDescriptor); } if (in == null) { // Should not be reached this. @@ -4892,8 +5087,7 @@ public class ExifInterfaceFork { * Creates and returns a Bitmap object of the thumbnail image based on the byte array and the * thumbnail compression value, or {@code null} if the compression type is unsupported. */ - @Nullable - public Bitmap getThumbnailBitmap() { + public @Nullable Bitmap getThumbnailBitmap() { if (!mHasThumbnail) { return null; } else if (mThumbnailBytes == null) { @@ -4950,8 +5144,7 @@ public class ExifInterfaceFork { * called since the underlying file was initially parsed, since * that means offsets may have changed. */ - @Nullable - public long[] getThumbnailRange() { + public long @Nullable [] getThumbnailRange() { if (mModified) { throw new IllegalStateException( "The underlying file has been modified since being parsed"); @@ -4976,8 +5169,7 @@ public class ExifInterfaceFork { * called since the underlying file was initially parsed, since * that means offsets may have changed. */ - @Nullable - public long[] getAttributeRange(@NonNull String tag) { + public long @Nullable [] getAttributeRange(@NonNull String tag) { if (tag == null) { throw new NullPointerException("tag shouldn't be null"); } @@ -5001,8 +5193,7 @@ public class ExifInterfaceFork { * @return raw bytes for the value of the requested tag, or {@code null} if * no tag was found. */ - @Nullable - public byte[] getAttributeBytes(@NonNull String tag) { + public byte @Nullable [] getAttributeBytes(@NonNull String tag) { if (tag == null) { throw new NullPointerException("tag shouldn't be null"); } @@ -5039,8 +5230,7 @@ public class ExifInterfaceFork { * array where the first element is the latitude and the second element is the longitude. * Otherwise, it returns null. */ - @Nullable - public double[] getLatLong() { + public double @Nullable [] getLatLong() { String latValue = getAttribute(TAG_GPS_LATITUDE); String latRef = getAttribute(TAG_GPS_LATITUDE_REF); String lngValue = getAttribute(TAG_GPS_LONGITUDE); @@ -5077,8 +5267,10 @@ public class ExifInterfaceFork { setAltitude(location.getAltitude()); // Location objects store speeds in m/sec. Translates it to km/hr here. setAttribute(TAG_GPS_SPEED_REF, "K"); - setAttribute(TAG_GPS_SPEED, new Rational(location.getSpeed() - * TimeUnit.HOURS.toSeconds(1) / 1000).toString()); + setAttribute( + TAG_GPS_SPEED, + Rational.createFromDouble(location.getSpeed() * TimeUnit.HOURS.toSeconds(1) / 1000) + .toString()); String[] dateTime = sFormatterPrimary.format( new Date(location.getTime())).split("\\s+", -1); setAttribute(ExifInterfaceFork.TAG_GPS_DATESTAMP, dateTime[0]); @@ -5130,7 +5322,7 @@ public class ExifInterfaceFork { */ public void setAltitude(double altitude) { String ref = altitude >= 0 ? "0" : "1"; - setAttribute(TAG_GPS_ALTITUDE, new Rational(Math.abs(altitude)).toString()); + setAttribute(TAG_GPS_ALTITUDE, Rational.createFromDouble(Math.abs(altitude)).toString()); setAttribute(TAG_GPS_ALTITUDE_REF, ref); } @@ -5168,8 +5360,7 @@ public class ExifInterfaceFork { * @return null if date time information is unavailable or invalid. */ @RestrictTo(RestrictTo.Scope.LIBRARY) - @Nullable - public Long getDateTime() { + public @Nullable Long getDateTime() { return parseDateTime(getAttribute(TAG_DATETIME), getAttribute(TAG_SUBSEC_TIME), getAttribute(TAG_OFFSET_TIME)); @@ -5185,8 +5376,7 @@ public class ExifInterfaceFork { * @return null if digitized date time information is unavailable or invalid. */ @RestrictTo(RestrictTo.Scope.LIBRARY) - @Nullable - public Long getDateTimeDigitized() { + public @Nullable Long getDateTimeDigitized() { return parseDateTime(getAttribute(TAG_DATETIME_DIGITIZED), getAttribute(TAG_SUBSEC_TIME_DIGITIZED), getAttribute(TAG_OFFSET_TIME_DIGITIZED)); @@ -5202,8 +5392,7 @@ public class ExifInterfaceFork { * @return null if original date time information is unavailable or invalid. */ @RestrictTo(RestrictTo.Scope.LIBRARY) - @Nullable - public Long getDateTimeOriginal() { + public @Nullable Long getDateTimeOriginal() { return parseDateTime(getAttribute(TAG_DATETIME_ORIGINAL), getAttribute(TAG_SUBSEC_TIME_ORIGINAL), getAttribute(TAG_OFFSET_TIME_ORIGINAL)); @@ -5253,8 +5442,7 @@ public class ExifInterfaceFork { * @return null if the date time information is not available. */ @SuppressLint("AutoBoxing") /* Not a performance-critical call, thus not a big concern. */ - @Nullable - public Long getGpsDateTime() { + public @Nullable Long getGpsDateTime() { String date = getAttribute(TAG_GPS_DATESTAMP); String time = getAttribute(TAG_GPS_TIMESTAMP); if (date == null || time == null @@ -5328,7 +5516,7 @@ public class ExifInterfaceFork { } } catch (NumberFormatException | ArrayIndexOutOfBoundsException e) { // Not valid - throw new IllegalArgumentException(); + throw new IllegalArgumentException(e); } } @@ -5347,17 +5535,24 @@ public class ExifInterfaceFork { in.reset(); if (isJpegFormat(signatureCheckBytes)) { return IMAGE_TYPE_JPEG; - } else if (isRafFormat(signatureCheckBytes)) { + } + if (isRafFormat(signatureCheckBytes)) { return IMAGE_TYPE_RAF; - } else if (isHeifFormat(signatureCheckBytes)) { - return IMAGE_TYPE_HEIF; - } else if (isOrfFormat(signatureCheckBytes)) { + } + int heicOrAvifImageType = isHeicOrAvifFormat(signatureCheckBytes); + if (heicOrAvifImageType != IMAGE_TYPE_UNKNOWN) { + return heicOrAvifImageType; + } + if (isOrfFormat(signatureCheckBytes)) { return IMAGE_TYPE_ORF; - } else if (isRw2Format(signatureCheckBytes)) { + } + if (isRw2Format(signatureCheckBytes)) { return IMAGE_TYPE_RW2; - } else if (isPngFormat(signatureCheckBytes)) { + } + if (isPngFormat(signatureCheckBytes)) { return IMAGE_TYPE_PNG; - } else if (isWebpFormat(signatureCheckBytes)) { + } + if (isWebpFormat(signatureCheckBytes)) { return IMAGE_TYPE_WEBP; } // Certain file formats (PEF) are identified in readImageFileDirectory() @@ -5393,7 +5588,7 @@ public class ExifInterfaceFork { return true; } - private boolean isHeifFormat(byte[] signatureCheckBytes) throws IOException { + private int isHeicOrAvifFormat(byte[] signatureCheckBytes) throws IOException { ByteOrderedDataInputStream signatureInputStream = null; try { signatureInputStream = new ByteOrderedDataInputStream(signatureCheckBytes); @@ -5403,7 +5598,7 @@ public class ExifInterfaceFork { signatureInputStream.readFully(chunkType); if (!Arrays.equals(chunkType, HEIF_TYPE_FTYP)) { - return false; + return IMAGE_TYPE_UNKNOWN; } long chunkDataOffset = 8; @@ -5413,7 +5608,7 @@ public class ExifInterfaceFork { chunkSize = signatureInputStream.readLong(); if (chunkSize < 16) { // The smallest valid chunk is 16 bytes long in this case. - return false; + return IMAGE_TYPE_UNKNOWN; } chunkDataOffset += 8; } @@ -5428,17 +5623,18 @@ public class ExifInterfaceFork { // It should at least have major brand (4-byte) and minor version (4-byte). // The rest of the chunk (if any) is a list of (4-byte) compatible brands. if (chunkDataSize < 8) { - return false; + return IMAGE_TYPE_UNKNOWN; } byte[] brand = new byte[4]; boolean isMif1 = false; boolean isHeic = false; + boolean isAvif = false; for (long i = 0; i < chunkDataSize / 4; ++i) { try { signatureInputStream.readFully(brand); } catch (EOFException e) { - return false; + return IMAGE_TYPE_UNKNOWN; } if (i == 1) { // Skip this index, it refers to the minorVersion, not a brand. @@ -5448,9 +5644,16 @@ public class ExifInterfaceFork { isMif1 = true; } else if (Arrays.equals(brand, HEIF_BRAND_HEIC)) { isHeic = true; + } else if (Arrays.equals(brand, HEIF_BRAND_AVIF) + || Arrays.equals(brand, HEIF_BRAND_AVIS)) { + isAvif = true; } - if (isMif1 && isHeic) { - return true; + if (isMif1) { + if (isHeic) { + return IMAGE_TYPE_HEIC; + } else if (isAvif) { + return IMAGE_TYPE_AVIF; + } } } } catch (Exception e) { @@ -5463,7 +5666,7 @@ public class ExifInterfaceFork { signatureInputStream = null; } } - return false; + return IMAGE_TYPE_UNKNOWN; } /** @@ -5636,13 +5839,8 @@ public class ExifInterfaceFork { final int offset = start + IDENTIFIER_XMP_APP1.length; final byte[] value = Arrays.copyOfRange(bytes, IDENTIFIER_XMP_APP1.length, bytes.length); - // TODO: check if ignoring separate XMP data when tag 700 already exists is - // valid. - if (getAttribute(TAG_XMP) == null) { - mAttributes[IFD_TYPE_PRIMARY].put(TAG_XMP, new ExifAttribute( - IFD_FORMAT_BYTE, value.length, offset, value)); - mXmpIsFromSeparateMarker = true; - } + mXmpFromSeparateMarker = + new ExifAttribute(IFD_FORMAT_BYTE, value.length, offset, value); } break; } @@ -5805,9 +6003,15 @@ public class ExifInterfaceFork { } // Support for getting MediaMetadataRetriever.METADATA_KEY_EXIF_OFFSET and - // MediaMetadataRetriever.METADATA_KEY_EXIF_LENGTH was added SDK 28. - private void getHeifAttributes(final SeekableByteOrderedDataInputStream in) throws IOException { + // MediaMetadataRetriever.METADATA_KEY_EXIF_LENGTH was added in SDK 28 for HEIC and in SDK 31 + // for AVIF. + private void getHeifAttributes(final SeekableByteOrderedDataInputStream in, int imageType) + throws IOException { if (Build.VERSION.SDK_INT >= 28) { + if (imageType == IMAGE_TYPE_AVIF && Build.VERSION.SDK_INT < 31) { + throw new UnsupportedOperationException("Reading EXIF from AVIF files " + + "is supported from SDK 31 and above"); + } MediaMetadataRetriever retriever = new MediaMetadataRetriever(); try { Api23Impl.setDataSource(retriever, new MediaDataSource() { @@ -5864,14 +6068,10 @@ public class ExifInterfaceFork { } }); - String exifOffsetStr = null, exifLengthStr = null; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { - exifOffsetStr = retriever.extractMetadata( - MediaMetadataRetriever.METADATA_KEY_EXIF_OFFSET); - exifLengthStr = retriever.extractMetadata( - MediaMetadataRetriever.METADATA_KEY_EXIF_LENGTH); - } - + String exifOffsetStr = retriever.extractMetadata( + MediaMetadataRetriever.METADATA_KEY_EXIF_OFFSET); + String exifLengthStr = retriever.extractMetadata( + MediaMetadataRetriever.METADATA_KEY_EXIF_LENGTH); String hasImage = retriever.extractMetadata( MediaMetadataRetriever.METADATA_KEY_HAS_IMAGE); String hasVideo = retriever.extractMetadata( @@ -5953,23 +6153,18 @@ public class ExifInterfaceFork { readExifSegment(bytes, IFD_TYPE_PRIMARY); } - String xmpOffsetStr = null, xmpLengthStr = null; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { - xmpOffsetStr = retriever.extractMetadata( - MediaMetadataRetriever.METADATA_KEY_XMP_OFFSET); - xmpLengthStr = retriever.extractMetadata( - MediaMetadataRetriever.METADATA_KEY_XMP_LENGTH); - } + String xmpOffsetStr = retriever.extractMetadata( + MediaMetadataRetriever.METADATA_KEY_XMP_OFFSET); + String xmpLengthStr = retriever.extractMetadata( + MediaMetadataRetriever.METADATA_KEY_XMP_LENGTH); if (xmpOffsetStr != null && xmpLengthStr != null) { int offset = Integer.parseInt(xmpOffsetStr); int length = Integer.parseInt(xmpLengthStr); in.seek(offset); byte[] xmpBytes = new byte[length]; in.readFully(xmpBytes); - if (getAttribute(TAG_XMP) == null) { - mAttributes[IFD_TYPE_PRIMARY].put(TAG_XMP, new ExifAttribute( - IFD_FORMAT_BYTE, xmpBytes.length, offset, xmpBytes)); - } + mXmpFromSeparateMarker = + new ExifAttribute(IFD_FORMAT_BYTE, xmpBytes.length, offset, xmpBytes); } if (DEBUG) { @@ -5977,7 +6172,7 @@ public class ExifInterfaceFork { } } catch (RuntimeException e) { throw new UnsupportedOperationException("Failed to read EXIF from HEIF file. " - + "Given stream is either malformed or unsupported."); + + "Given stream is either malformed or unsupported.", e); } finally { try { retriever.release(); @@ -5986,7 +6181,7 @@ public class ExifInterfaceFork { } } } else { - throw new UnsupportedOperationException("Reading EXIF from HEIF files " + throw new UnsupportedOperationException("Reading EXIF from HEIC files " + "is supported from SDK 28 and above"); } } @@ -6141,11 +6336,10 @@ public class ExifInterfaceFork { // 2.1. Integers and byte order in.setByteOrder(BIG_ENDIAN); - int bytesRead = 0; + int startPosition = in.position(); // Skip the signature bytes in.skipFully(PNG_SIGNATURE.length); - bytesRead += PNG_SIGNATURE.length; // Each chunk is made up of four parts: // 1) Length: 4-byte unsigned integer indicating the number of bytes in the @@ -6160,27 +6354,30 @@ public class ExifInterfaceFork { try { while (true) { int length = in.readInt(); - bytesRead += 4; - byte[] type = new byte[PNG_CHUNK_TYPE_BYTE_LENGTH]; - in.readFully(type); - bytesRead += PNG_CHUNK_TYPE_BYTE_LENGTH; + int type = in.readInt(); // The first chunk must be the IHDR chunk - if (bytesRead == 16 && !Arrays.equals(type, PNG_CHUNK_TYPE_IHDR)) { - throw new IOException("Encountered invalid PNG file--IHDR chunk should appear" - + "as the first chunk"); + if (in.position() - startPosition == 16 && type != PNG_CHUNK_TYPE_IHDR) { + throw new IOException( + "Encountered invalid PNG file--IHDR chunk should appear as the first " + + "chunk"); } - if (Arrays.equals(type, PNG_CHUNK_TYPE_IEND)) { + if (type == PNG_CHUNK_TYPE_IEND) { // IEND marks the end of the image. break; - } else if (Arrays.equals(type, PNG_CHUNK_TYPE_EXIF)) { + } else if (type == PNG_CHUNK_TYPE_EXIF) { + // Save offset to EXIF data for handling thumbnail and attribute offsets. + mOffsetToExifData = in.position() - startPosition; + // TLAD start if (length > ATTRIBUTE_SIZE_DANGER_THRESHOLD) { throw new IOException("dangerous exif chunk size=" + length); } // TLAD end + + // TODO: Need to handle potential OutOfMemoryError byte[] data = new byte[length]; in.readFully(data); @@ -6188,15 +6385,13 @@ public class ExifInterfaceFork { int dataCrcValue = in.readInt(); // Cyclic Redundancy Code used to check for corruption of the data CRC32 crc = new CRC32(); - crc.update(type); + updateCrcWithInt(crc, type); crc.update(data); if ((int) crc.getValue() != dataCrcValue) { throw new IOException("Encountered invalid CRC value for PNG-EXIF chunk." + "\n recorded CRC value: " + dataCrcValue + ", calculated CRC " + "value: " + crc.getValue()); } - // Save offset to EXIF data for handling thumbnail and attribute offsets. - mOffsetToExifData = bytesRead; readExifSegment(data, IFD_TYPE_PRIMARY); validateImages(); @@ -6205,16 +6400,22 @@ public class ExifInterfaceFork { } else { // Skip to next chunk in.skipFully(length + PNG_CHUNK_CRC_BYTE_LENGTH); - bytesRead += length + PNG_CHUNK_CRC_BYTE_LENGTH; } } } catch (EOFException e) { // Should not reach here. Will only reach here if the file is corrupted or // does not follow the PNG specifications - throw new IOException("Encountered corrupt PNG file."); + throw new IOException("Encountered corrupt PNG file.", e); } } + private static void updateCrcWithInt(CRC32 crc, int value) { + crc.update(value >>> 24); + crc.update(value >>> 16); + crc.update(value >>> 8); + crc.update(value); + } + // WebP contains EXIF data as a RIFF File Format Chunk // All references below can be found in the following link. // https://developers.google.com/speed/webp/docs/riff_container @@ -6294,7 +6495,7 @@ public class ExifInterfaceFork { } catch (EOFException e) { // Should not reach here. Will only reach here if the file is corrupted or // does not follow the WebP specifications - throw new IOException("Encountered corrupt WebP file."); + throw new IOException("Encountered corrupt WebP file.", e); } } @@ -6318,22 +6519,20 @@ public class ExifInterfaceFork { } dataOutputStream.writeByte(MARKER_SOI); - // Remove XMP data if it is from a separate marker (IDENTIFIER_XMP_APP1, not - // IDENTIFIER_EXIF_APP1) - // Will re-add it later after the rest of the file is written - ExifAttribute xmpAttribute = null; - if (getAttribute(TAG_XMP) != null && mXmpIsFromSeparateMarker) { - xmpAttribute = mAttributes[IFD_TYPE_PRIMARY].remove(TAG_XMP); - } - // Write EXIF APP1 segment dataOutputStream.writeByte(MARKER); dataOutputStream.writeByte(MARKER_APP1); writeExifSegment(dataOutputStream); - // Re-add previously removed XMP data. - if (xmpAttribute != null) { - mAttributes[IFD_TYPE_PRIMARY].put(TAG_XMP, xmpAttribute); + if (mXmpFromSeparateMarker != null) { + // Write XMP APP1 segment. The XMP spec (part 3, section 1.1.3) recommends for this to + // directly follow the Exif APP1 segment. + dataOutputStream.write(MARKER); + dataOutputStream.writeByte(MARKER_APP1); + int length = 2 + IDENTIFIER_XMP_APP1.length + mXmpFromSeparateMarker.bytes.length; + dataOutputStream.writeUnsignedShort(length); + dataOutputStream.write(IDENTIFIER_XMP_APP1); + dataOutputStream.write(mXmpFromSeparateMarker.bytes); } byte[] bytes = new byte[4096]; @@ -6350,12 +6549,22 @@ public class ExifInterfaceFork { if (length < 0) { throw new IOException("Invalid length"); } - byte[] identifier = new byte[6]; - if (length >= 6) { + // If the length is long enough, we read enough bytes for the XMP identifier, + // because it's longer than the EXIF one. + byte[] identifier; + if (length >= IDENTIFIER_XMP_APP1.length) { + identifier = new byte[IDENTIFIER_XMP_APP1.length]; + } else if (length >= IDENTIFIER_EXIF_APP1.length) { + identifier = new byte[IDENTIFIER_EXIF_APP1.length]; + } else { + identifier = null; + } + if (identifier != null) { dataInputStream.readFully(identifier); - if (Arrays.equals(identifier, IDENTIFIER_EXIF_APP1)) { - // Skip the original EXIF APP1 segment. - dataInputStream.skipFully(length - 6); + if (startsWith(identifier, IDENTIFIER_EXIF_APP1) + || startsWith(identifier, IDENTIFIER_XMP_APP1)) { + // Skip the original EXIF or XMP APP1 segment. + dataInputStream.skipFully(length - identifier.length); break; } } @@ -6363,8 +6572,8 @@ public class ExifInterfaceFork { dataOutputStream.writeByte(MARKER); dataOutputStream.writeByte(marker); dataOutputStream.writeUnsignedShort(length + 2); - if (length >= 6) { - length -= 6; + if (identifier != null) { + length -= identifier.length; dataOutputStream.write(identifier); } int read; @@ -6632,8 +6841,8 @@ public class ExifInterfaceFork { // Retrieve image width/height widthAndHeight = totalInputStream.readInt(); - width = (widthAndHeight << 18) >> 18; - height = (widthAndHeight << 2) >> 18; + width = widthAndHeight & 0x3FFF; + height = (widthAndHeight >> 16) & 0x3FFF; bytesToRead -= (vp8Frame.length + vp8Signature.length + 4); } else if (Arrays.equals(firstChunkType, WEBP_CHUNK_TYPE_VP8L)) { // Check signature @@ -7554,7 +7763,7 @@ public class ExifInterfaceFork { case IMAGE_TYPE_PNG: // Write PNG specific data (chunk size, chunk type) dataOutputStream.writeInt(totalSize); - dataOutputStream.write(PNG_CHUNK_TYPE_EXIF); + dataOutputStream.writeInt(PNG_CHUNK_TYPE_EXIF); break; case IMAGE_TYPE_WEBP: // Write WebP specific data (chunk type, chunk size) diff --git a/android/exifinterface/src/main/java/androidx/exifinterface/media/ExifInterfaceUtilsFork.java b/android/exifinterface/src/main/java/androidx/exifinterface/media/ExifInterfaceUtilsFork.java index df7ed9320..301e306fa 100644 --- a/android/exifinterface/src/main/java/androidx/exifinterface/media/ExifInterfaceUtilsFork.java +++ b/android/exifinterface/src/main/java/androidx/exifinterface/media/ExifInterfaceUtilsFork.java @@ -18,12 +18,10 @@ package androidx.exifinterface.media; import android.media.MediaDataSource; import android.media.MediaMetadataRetriever; -import android.os.Build; import android.system.ErrnoException; import android.system.Os; import android.util.Log; -import androidx.annotation.DoNotInline; import androidx.annotation.RequiresApi; import java.io.Closeable; @@ -32,12 +30,19 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +/* + * Forked from 'androidx.exifinterface:exifinterface:1.4.0-alpha01' on 2024/11/17 + * Named differently to let ExifInterface be loaded as subdependency. + * cf https://github.com/androidx/androidx/tree/androidx-main/exifinterface/exifinterface/src/main/java/androidx/exifinterface/media + */ + class ExifInterfaceUtilsFork { private static final String TAG = "ExifInterfaceUtils"; private ExifInterfaceUtilsFork() { // Prevent instantiation } + /** * Copies all of the bytes from {@code in} to {@code out}. Neither stream is closed. * Returns the total number of bytes transferred. @@ -146,45 +151,18 @@ class ExifInterfaceUtilsFork { * Closes a file descriptor that has been duplicated. */ static void closeFileDescriptor(FileDescriptor fd) { - // Os.dup and Os.close was introduced in API 21 so this method shouldn't be called - // in API < 21. - if (Build.VERSION.SDK_INT >= 21) { - try { - Api21Impl.close(fd); - // Catching ErrnoException will raise error in API < 21 - } catch (Exception ex) { - Log.e(TAG, "Error closing fd."); - } - } else { - Log.e(TAG, "closeFileDescriptor is called in API < 21, which must be wrong."); - } - } - - @RequiresApi(21) - static class Api21Impl { - private Api21Impl() {} - - @DoNotInline - static FileDescriptor dup(FileDescriptor fileDescriptor) throws ErrnoException { - return Os.dup(fileDescriptor); - } - - @DoNotInline - static long lseek(FileDescriptor fd, long offset, int whence) throws ErrnoException { - return Os.lseek(fd, offset, whence); - } - - @DoNotInline - static void close(FileDescriptor fd) throws ErrnoException { + try { Os.close(fd); + } catch (ErrnoException ex) { + Log.e(TAG, "Error closing fd.", ex); } } @RequiresApi(23) static class Api23Impl { - private Api23Impl() {} + private Api23Impl() { + } - @DoNotInline static void setDataSource(MediaMetadataRetriever retriever, MediaDataSource dataSource) { retriever.setDataSource(dataSource); } From 039de32faab9da847e12c32b1a5179f06c80d1e2 Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Sun, 17 Nov 2024 18:18:40 +0100 Subject: [PATCH 17/22] avif: fixed decoding of rotated still, fixed sizing during cataloguing info: show avif metadata via exifinterface --- .../kotlin/deckers/thibault/aves/utils/MimeTypes.kt | 11 +++++++---- lib/model/entry/extensions/catalog.dart | 8 +++++++- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/utils/MimeTypes.kt b/android/app/src/main/kotlin/deckers/thibault/aves/utils/MimeTypes.kt index e024acd72..8cc0aa52a 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/utils/MimeTypes.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/utils/MimeTypes.kt @@ -99,9 +99,12 @@ object MimeTypes { else -> true } - // as of `ExifInterface` v1.3.1, `isSupportedMimeType` reports - // no support for TIFF images, but it can actually open them (maybe other formats too) - fun canReadWithExifInterface(mimeType: String, strict: Boolean = true) = ExifInterface.isSupportedMimeType(mimeType) || !strict + // as of `ExifInterface` v1.4.0-alpha01, `isSupportedMimeType` reports + // no support for AVIF/TIFF images, but it can actually open them (maybe other formats too) + fun canReadWithExifInterface(mimeType: String, strict: Boolean = true): Boolean { + if (!strict) return true + return ExifInterface.isSupportedMimeType(mimeType) || mimeType == AVIF + } // as of latest PixyMeta fun canReadWithPixyMeta(mimeType: String) = when (mimeType) { @@ -143,7 +146,7 @@ object MimeTypes { return if (pageId != null && MultiPageImage.isSupported(mimeType)) { true } else when (mimeType) { - DNG, DNG_ADOBE, HEIC, HEIF, PNG, WEBP -> true + AVIF, DNG, DNG_ADOBE, HEIC, HEIF, PNG, WEBP -> true else -> false } } diff --git a/lib/model/entry/extensions/catalog.dart b/lib/model/entry/extensions/catalog.dart index fc158c122..c6c7605ba 100644 --- a/lib/model/entry/extensions/catalog.dart +++ b/lib/model/entry/extensions/catalog.dart @@ -33,7 +33,13 @@ extension ExtraAvesEntryCatalog on AvesEntry { if ((isVideo && (!isSized || durationMillis == 0)) || mimeType == MimeTypes.avif) { // exotic video that is not sized during loading final fields = await VideoMetadataFormatter.getLoadingMetadata(this); - await applyNewFields(fields, persist: persist); + // check size as the video interpreter may fail on some AVIF stills + final width = fields['width']; + final height = fields['height']; + final isValid = (width == null || width > 0) && (height == null || height > 0); + if (isValid) { + await applyNewFields(fields, persist: persist); + } } // cataloguing on platform From 89c4fdd8546719b747e4e429efcb4eaa7dc8640b Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Sun, 17 Nov 2024 18:27:20 +0100 Subject: [PATCH 18/22] info: show avif metadata as video --- lib/model/entry/extensions/info.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/model/entry/extensions/info.dart b/lib/model/entry/extensions/info.dart index 5c001d865..7353a0726 100644 --- a/lib/model/entry/extensions/info.dart +++ b/lib/model/entry/extensions/info.dart @@ -50,7 +50,7 @@ extension ExtraAvesEntryInfo on AvesEntry { ); }).toList(); - if (isVideo || (mimeType == MimeTypes.heif && isMultiPage)) { + if (isVideo || (mimeType == MimeTypes.heif && isMultiPage) || mimeType == MimeTypes.avif) { directories.addAll(await _getStreamDirectories(context)); } From 58e3912f86ed55a6cc9bd142b322b1f8e5d0f246 Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Mon, 18 Nov 2024 21:51:20 +0100 Subject: [PATCH 19/22] #1269 fixed cataloguing images with wrong MPF offsets --- CHANGELOG.md | 1 + .../aves/channel/calls/MetadataFetchHandler.kt | 12 ++++++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d81f2a680..58e670d27 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ All notable changes to this project will be documented in this file. ### Fixed - crash when playing video with DCL restriction enabled +- cataloguing images with wrong MPF offsets - printing multi-page items containing some unprintable pages - English (Shavian) locale tags for store listing diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MetadataFetchHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MetadataFetchHandler.kt index d1db4d173..98de3e4e0 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MetadataFetchHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MetadataFetchHandler.kt @@ -792,7 +792,7 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler { private fun hasAppleHdrGainMap(uri: Uri, sizeBytes: Long?): Boolean { val mpEntries = MultiPage.getJpegMpfEntries(context, uri, sizeBytes) ?: return false - mpEntries.filter { it.type == MpEntry.TYPE_UNDEFINED }.forEach { mpEntry -> + mpEntries.filter { it.type == MpEntry.TYPE_UNDEFINED }.forEachIndexed { mpIndex, mpEntry -> var dataOffset = mpEntry.dataOffset if (dataOffset > 0) { val baseOffset = MultiPage.getJpegMpfBaseOffset(context, uri, sizeBytes) @@ -802,9 +802,13 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler { } StorageUtils.openInputStream(context, uri)?.let { input -> input.skip(dataOffset) - val pageMetadata = Helper.safeRead(input, sizeBytes) - if (pageMetadata.getDirectoriesOfType(XmpDirectory::class.java).any { it.xmpMeta.hasHdrGainMap() }) { - return true + try { + val pageMetadata = Helper.safeRead(input, sizeBytes) + if (pageMetadata.getDirectoriesOfType(XmpDirectory::class.java).any { it.xmpMeta.hasHdrGainMap() }) { + return true + } + } catch (e: Exception) { + Log.w(LOG_TAG, "failed to read metadata by metadata-extractor for uri=$uri mpIndex=$mpIndex mpEntry=$mpEntry", e) } } } From 46374dfcc12cedc0d93c4a585a37fa851a158423 Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Mon, 18 Nov 2024 23:41:13 +0100 Subject: [PATCH 20/22] do not try to start analysis service when app goes to background --- lib/model/source/collection_source.dart | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/lib/model/source/collection_source.dart b/lib/model/source/collection_source.dart index 6ea63b1b2..b87f599e8 100644 --- a/lib/model/source/collection_source.dart +++ b/lib/model/source/collection_source.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'dart:ui'; import 'package:aves/model/covers.dart'; import 'package:aves/model/entry/entry.dart'; @@ -26,6 +27,7 @@ import 'package:aves/model/vaults/vaults.dart'; import 'package:aves/services/analysis_service.dart'; import 'package:aves/services/common/image_op_events.dart'; import 'package:aves/services/common/services.dart'; +import 'package:aves/widgets/aves_app.dart'; import 'package:aves_model/aves_model.dart'; import 'package:collection/collection.dart'; import 'package:event_bus/event_bus.dart'; @@ -498,11 +500,19 @@ abstract class CollectionSource with SourceBase, AlbumMixin, CountryMixin, Place } } } + if (startAnalysisService) { - await AnalysisService.startService( - force: force, - entryIds: entries?.map((entry) => entry.id).toList(), - ); + final lifecycleState = AvesApp.lifecycleStateNotifier.value; + switch (lifecycleState) { + case AppLifecycleState.resumed: + case AppLifecycleState.inactive: + await AnalysisService.startService( + force: force, + entryIds: entries?.map((entry) => entry.id).toList(), + ); + default: + unawaited(reportService.log('analysis service not started because app is in state=$lifecycleState')); + } } else { // explicit GC before cataloguing multiple items await deviceService.requestGarbageCollection(); From 0c55c7eab09bfa40da517f68659ee4dfc8aa74c8 Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Mon, 18 Nov 2024 23:41:45 +0100 Subject: [PATCH 21/22] l10n by weblate (#1302) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Translate-URL: https://hosted.weblate.org/projects/aves/app-android/et/ Translate-URL: https://hosted.weblate.org/projects/aves/app-android/ru/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/ar/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/de/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/es/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/et/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/fr/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/id/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/ko/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/nl/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/pl/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/pt/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/sv/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/tr/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/zh_Hans/ Translate-URL: https://hosted.weblate.org/projects/aves/store-short-description/et/ Translation: Aves/App - Android Translation: Aves/App - Main Translation: Aves/Store - Short description Co-authored-by: 5FeetUnder <15950507+5FeetUnder@users.noreply.github.com> Co-authored-by: Cleverson Cândido Co-authored-by: Hasan Kara Co-authored-by: Languages add-on Co-authored-by: Linerly Co-authored-by: Mohamed Zeroug Co-authored-by: Priit Jõerüüt Co-authored-by: Shift18 Co-authored-by: Stephan Paternotte Co-authored-by: Thibault Deckers Co-authored-by: bittin1ddc447d824349b2 Co-authored-by: gallegonovato Co-authored-by: kaajjo Co-authored-by: rehork Co-authored-by: wanzh --- lib/l10n/app_de.arb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb index f440f013c..94e785e5c 100644 --- a/lib/l10n/app_de.arb +++ b/lib/l10n/app_de.arb @@ -1390,5 +1390,7 @@ "mapAttributionOsmLiberty": "Kacheln von [OpenMapTiles](https://www.openmaptiles.org/), [CC BY](http://creativecommons.org/licenses/by/4.0) • Gehostet von [OSM Americana](https://tile.ourmap.us)", "@mapAttributionOsmLiberty": {}, "mapAttributionOpenTopoMap": "[SRTM](https://www.earthdata.nasa.gov/sensors/srtm) | Kacheln von [OpenTopoMap](https://opentopomap.org/), [CC BY-SA](https://creativecommons.org/licenses/by-sa/3.0/)", - "@mapAttributionOpenTopoMap": {} + "@mapAttributionOpenTopoMap": {}, + "newAlbumDialogAlbumAlreadyExistsHelper": "Album existiert bereits", + "@newAlbumDialogAlbumAlreadyExistsHelper": {} } From 0dee00dbcaeffd846dbc8876f31424b70529bb4e Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Mon, 18 Nov 2024 23:46:12 +0100 Subject: [PATCH 22/22] version bump --- CHANGELOG.md | 2 ++ fastlane/metadata/android/en-US/changelogs/137.txt | 5 +++++ fastlane/metadata/android/en-US/changelogs/13701.txt | 5 +++++ pubspec.yaml | 2 +- whatsnew/whatsnew-en-US | 2 +- 5 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 fastlane/metadata/android/en-US/changelogs/137.txt create mode 100644 fastlane/metadata/android/en-US/changelogs/13701.txt diff --git a/CHANGELOG.md b/CHANGELOG.md index 58e670d27..741cb66d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ All notable changes to this project will be documented in this file. ## [Unreleased] +## [v1.11.18] - 2024-11-18 + ### Changed - Albums: improved album creation feedback diff --git a/fastlane/metadata/android/en-US/changelogs/137.txt b/fastlane/metadata/android/en-US/changelogs/137.txt new file mode 100644 index 000000000..444e6cae9 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/137.txt @@ -0,0 +1,5 @@ +In v1.11.18: +- peruse your videos frame by frame +- create map shortcuts to filtered collections +- enjoy the app in Shavian +Full changelog available on GitHub \ No newline at end of file diff --git a/fastlane/metadata/android/en-US/changelogs/13701.txt b/fastlane/metadata/android/en-US/changelogs/13701.txt new file mode 100644 index 000000000..444e6cae9 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/13701.txt @@ -0,0 +1,5 @@ +In v1.11.18: +- peruse your videos frame by frame +- create map shortcuts to filtered collections +- enjoy the app in Shavian +Full changelog available on GitHub \ No newline at end of file diff --git a/pubspec.yaml b/pubspec.yaml index 576e6c6eb..c19cd905d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -7,7 +7,7 @@ repository: https://github.com/deckerst/aves # - play changelog: /whatsnew/whatsnew-en-US # - izzy changelog: /fastlane/metadata/android/en-US/changelogs/XXX01.txt # - libre changelog: /fastlane/metadata/android/en-US/changelogs/XXX.txt -version: 1.11.17+136 +version: 1.11.18+137 publish_to: none environment: diff --git a/whatsnew/whatsnew-en-US b/whatsnew/whatsnew-en-US index 10f3ff7c4..444e6cae9 100644 --- a/whatsnew/whatsnew-en-US +++ b/whatsnew/whatsnew-en-US @@ -1,4 +1,4 @@ -In v1.11.17: +In v1.11.18: - peruse your videos frame by frame - create map shortcuts to filtered collections - enjoy the app in Shavian