diff --git a/.flutter b/.flutter index ea121f885..d8a9f9a52 160000 --- a/.flutter +++ b/.flutter @@ -1 +1 @@ -Subproject commit ea121f8859e4b13e47a8f845e4586164519588bc +Subproject commit d8a9f9a52e5af486f80d932e838ee93861ffd863 diff --git a/.github/workflows/quality-check.yml b/.github/workflows/quality-check.yml index 0f696248d..a738c7a58 100644 --- a/.github/workflows/quality-check.yml +++ b/.github/workflows/quality-check.yml @@ -28,6 +28,9 @@ jobs: - name: Get Flutter packages run: ./flutterw pub get + - name: Generate app localizations + run: ./flutterw gen-l10n + - name: Static analysis. run: ./flutterw analyze @@ -69,7 +72,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@60168efe1c415ce0f5521ea06d5c2062adbeed1b # v3.28.17 + uses: github/codeql-action/init@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18 with: languages: ${{ matrix.language }} build-mode: ${{ matrix.build-mode }} @@ -83,6 +86,6 @@ jobs: ./flutterw build apk --profile -t lib/main_play.dart --flavor play - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@60168efe1c415ce0f5521ea06d5c2062adbeed1b # v3.28.17 + uses: github/codeql-action/analyze@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18 with: category: "/language:${{matrix.language}}" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 25d2aa731..de3ee347d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -36,6 +36,9 @@ jobs: - name: Get Flutter packages run: ./flutterw pub get + - name: Generate app localizations + run: ./flutterw gen-l10n + - name: Update Flutter version file run: scripts/update_flutter_version.sh diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index c7170c96d..8f9422486 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -41,7 +41,7 @@ jobs: persist-credentials: false - name: "Run analysis" - uses: ossf/scorecard-action@f49aabe0b5af0936a0987cfb85d86b75731b0186 # v2.4.1 + uses: ossf/scorecard-action@05b42c624433fc40578a4040d5cf5e36ddca8cde # v2.4.2 with: results_file: results.sarif results_format: sarif @@ -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@60168efe1c415ce0f5521ea06d5c2062adbeed1b # v3.28.17 + uses: github/codeql-action/upload-sarif@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18 with: sarif_file: results.sarif diff --git a/CHANGELOG.md b/CHANGELOG.md index 98fb110e9..a46ac3322 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,21 @@ All notable changes to this project will be documented in this file. ## [Unreleased] +## [v1.13.2] - 2025-06-02 + +### Changed + +- downgraded Flutter to stable v3.27.4 +- prevent display orientation flip when device rotation is locked + +### Fixed + +- moved file losing its extension and no longer being detected as media in some cases +- opening home when launching app as media picker +- removing groups with obsolete albums +- loading group custom covers +- crash when parsing some large media with trailing thumbnail + ## [v1.13.1] - 2025-05-14 ### Fixed diff --git a/analysis_options.yaml b/analysis_options.yaml index f9925ff6f..a6531e827 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -9,6 +9,11 @@ analyzer: # implicit-casts: false # implicit-dynamic: false +# cf https://github.com/dart-lang/dart_style/wiki/Configuration +formatter: + page_width: 240 + trailing_commas: preserve + linter: rules: # from 'flutter_lints', excluded diff --git a/android/.gitignore b/android/.gitignore index 82677b89f..5343532a4 100644 --- a/android/.gitignore +++ b/android/.gitignore @@ -7,6 +7,7 @@ gradle-wrapper.jar GeneratedPluginRegistrant.java .cxx/ .kotlin/ +/build/ # Remember to never publicly share your keystore. # See https://flutter.dev/to/reference-keystore diff --git a/android/app/build.gradle b/android/app/build.gradle index 42711a403..bb6a533fb 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -134,14 +134,14 @@ flutter { repositories { maven { - url 'https://jitpack.io' + url = 'https://jitpack.io' content { includeGroup "com.github.deckerst" includeGroup "com.github.deckerst.mp4parser" } } maven { - url 'https://s3.amazonaws.com/repo.commonsware.com' + url = 'https://s3.amazonaws.com/repo.commonsware.com' content { excludeGroupByRegex "com\\.github\\.deckerst.*" } @@ -152,12 +152,12 @@ dependencies { implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.10.1' implementation "androidx.appcompat:appcompat:1.7.0" - implementation 'androidx.core:core-ktx:1.15.0' - implementation 'androidx.lifecycle:lifecycle-process:2.8.7' + implementation 'androidx.core:core-ktx:1.16.0' + implementation 'androidx.lifecycle:lifecycle-process:2.9.0' 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.10.0' + implementation 'androidx.security:security-crypto:1.1.0-alpha07' + implementation 'androidx.work:work-runtime-ktx:2.10.1' implementation 'com.commonsware.cwac:document:0.5.0' implementation 'com.drewnoakes:metadata-extractor:2.19.0' @@ -171,11 +171,11 @@ dependencies { // - https://jitpack.io/p/deckerst/androidsvg // - https://jitpack.io/p/deckerst/mp4parser // - https://jitpack.io/p/deckerst/pixymeta-android - implementation 'com.github.deckerst:Android-TiffBitmapFactory:3ed067f021' - implementation 'com.github.deckerst:androidsvg:cc9d59a88f' - implementation 'com.github.deckerst.mp4parser:isoparser:d5caf7a3dd' - implementation 'com.github.deckerst.mp4parser:muxer:d5caf7a3dd' - implementation 'com.github.deckerst:pixymeta-android:71eee77dc4' + implementation 'com.github.deckerst:Android-TiffBitmapFactory:d6b2b0aa4f' + implementation 'com.github.deckerst:androidsvg:67db933051' + implementation 'com.github.deckerst.mp4parser:isoparser:c2898f1832' + implementation 'com.github.deckerst.mp4parser:muxer:c2898f1832' + implementation 'com.github.deckerst:pixymeta-android:cb1cdc932e' implementation project(':exifinterface') testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.11.4' diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/EmbeddedDataHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/EmbeddedDataHandler.kt index 58c07fbf4..9b23fbc9d 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/EmbeddedDataHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/EmbeddedDataHandler.kt @@ -311,7 +311,7 @@ class EmbeddedDataHandler(private val context: Context) : MethodCallHandler { embeddedByteStream: InputStream, embeddedByteLength: Long, ) { - val extension = extensionFor(mimeType) + val extension = extensionFor(mimeType, defaultExtension = null) val targetFile = StorageUtils.createTempFile(context, extension).apply { transferFrom(embeddedByteStream, embeddedByteLength) } @@ -319,7 +319,7 @@ class EmbeddedDataHandler(private val context: Context) : MethodCallHandler { val authority = "${context.applicationContext.packageName}.file_provider" val uri = if (displayName != null) { // add extension to ease type identification when sharing this content - val displayNameWithExtension = if (extension == null || displayName.endsWith(extension, ignoreCase = true)) { + val displayNameWithExtension = if (displayName.endsWith(extension, ignoreCase = true)) { displayName } else { "$displayName$extension" diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/MediaStoreChangeStreamHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/MediaStoreChangeStreamHandler.kt index e926b5b6a..0f16007e5 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/MediaStoreChangeStreamHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/MediaStoreChangeStreamHandler.kt @@ -31,9 +31,15 @@ class MediaStoreChangeStreamHandler(private val context: Context) : EventChannel init { Log.i(LOG_TAG, "start listening to Media Store") - context.contentResolver.apply { - registerContentObserver(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, true, contentObserver) - registerContentObserver(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, true, contentObserver) + try { + context.contentResolver.apply { + registerContentObserver(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, true, contentObserver) + registerContentObserver(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, true, contentObserver) + } + } catch (e: SecurityException) { + // Trying to register an observer may yield a security exception with this message: + // "Failed to find provider media for user 0; expected to find a valid ContentProvider for this authority" + Log.w(LOG_TAG, "failed to register content observer", e) } } diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/model/provider/ImageProvider.kt b/android/app/src/main/kotlin/deckers/thibault/aves/model/provider/ImageProvider.kt index 9d36f1812..2804bda5f 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/model/provider/ImageProvider.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/model/provider/ImageProvider.kt @@ -142,16 +142,18 @@ abstract class ImageProvider { val oldFile = File(sourcePath) if (oldFile.nameWithoutExtension != desiredNameWithoutExtension) { + val defaultExtension = oldFile.extension oldFile.parent?.let { dir -> val resolution = resolveTargetFileNameWithoutExtension( contextWrapper = activity, dir = dir, desiredNameWithoutExtension = desiredNameWithoutExtension, mimeType = mimeType, + defaultExtension = defaultExtension, conflictStrategy = NameConflictStrategy.RENAME, ) resolution.nameWithoutExtension?.let { targetNameWithoutExtension -> - val targetFileName = "$targetNameWithoutExtension${extensionFor(mimeType)}" + val targetFileName = "$targetNameWithoutExtension${extensionFor(mimeType, defaultExtension)}" val newFile = File(dir, targetFileName) if (oldFile != newFile) { newFields = renameSingle( @@ -277,11 +279,17 @@ abstract class ImageProvider { val page = if (sourceMimeType == MimeTypes.TIFF) pageId + 1 else pageId desiredNameWithoutExtension += "_${page.toString().padStart(3, '0')}" } + + // there is no benefit providing input extension + // for known output MIME type + val defaultExtension = null + val resolution = resolveTargetFileNameWithoutExtension( contextWrapper = activity, dir = targetDir, desiredNameWithoutExtension = desiredNameWithoutExtension, mimeType = exportMimeType, + defaultExtension = defaultExtension, conflictStrategy = nameConflictStrategy, ) val targetNameWithoutExtension = resolution.nameWithoutExtension ?: return skippedFieldMap @@ -358,6 +366,7 @@ abstract class ImageProvider { targetDir = targetDir, targetDirDocFile = targetDirDocFile, targetNameWithoutExtension = targetNameWithoutExtension, + defaultExtension = defaultExtension, write = write, ) @@ -465,6 +474,7 @@ abstract class ImageProvider { dir = targetDir, desiredNameWithoutExtension = desiredNameWithoutExtension, mimeType = captureMimeType, + defaultExtension = null, conflictStrategy = nameConflictStrategy, ) } catch (e: Exception) { @@ -571,13 +581,14 @@ abstract class ImageProvider { dir: String, desiredNameWithoutExtension: String, mimeType: String, + defaultExtension: String?, conflictStrategy: NameConflictStrategy, ): NameConflictResolution { val sanitizedNameWithoutExtension = sanitizeDesiredFileName(desiredNameWithoutExtension) var resolvedName: String? = sanitizedNameWithoutExtension var replacementFile: File? = null - val extension = extensionFor(mimeType) + val extension = extensionFor(mimeType, defaultExtension) val targetFile = File(dir, "$sanitizedNameWithoutExtension$extension") when (conflictStrategy) { NameConflictStrategy.RENAME -> { diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/model/provider/MediaStoreImageProvider.kt b/android/app/src/main/kotlin/deckers/thibault/aves/model/provider/MediaStoreImageProvider.kt index 7b1b7b190..7aca99e80 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/model/provider/MediaStoreImageProvider.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/model/provider/MediaStoreImageProvider.kt @@ -557,6 +557,7 @@ class MediaStoreImageProvider : ImageProvider() { toBin: Boolean, ): FieldMap { val sourcePath = sourceFile?.path + val sourceExtension = sourceFile?.extension val sourceDir = sourceFile?.parent?.let { ensureTrailingSeparator(it) } if (sourceDir == targetDir && !(copy && nameConflictStrategy == NameConflictStrategy.RENAME)) { // nothing to do unless it's a renamed copy @@ -569,6 +570,7 @@ class MediaStoreImageProvider : ImageProvider() { dir = targetDir, desiredNameWithoutExtension = desiredNameWithoutExtension, mimeType = mimeType, + defaultExtension = sourceExtension, conflictStrategy = nameConflictStrategy, ) val targetNameWithoutExtension = resolution.nameWithoutExtension ?: return skippedFieldMap @@ -580,6 +582,7 @@ class MediaStoreImageProvider : ImageProvider() { targetDir = targetDir, targetDirDocFile = targetDirDocFile, targetNameWithoutExtension = targetNameWithoutExtension, + defaultExtension = sourceExtension, ) { output: OutputStream -> try { sourceDocFile.copyTo(output) @@ -615,12 +618,13 @@ class MediaStoreImageProvider : ImageProvider() { targetDir: String, targetDirDocFile: DocumentFileCompat?, targetNameWithoutExtension: String, + defaultExtension: String?, write: (OutputStream) -> Unit, ): String { if (StorageUtils.isInVault(activity, targetDir)) { return insertByFile( targetDir = targetDir, - targetFileName = "$targetNameWithoutExtension${extensionFor(mimeType)}", + targetFileName = "$targetNameWithoutExtension${extensionFor(mimeType, defaultExtension)}", write = write, ) } @@ -630,7 +634,7 @@ class MediaStoreImageProvider : ImageProvider() { return insertByMediaStore( activity = activity, targetDir = targetDir, - targetFileName = "$targetNameWithoutExtension${extensionFor(mimeType)}", + targetFileName = "$targetNameWithoutExtension${extensionFor(mimeType, defaultExtension)}", write = write, ) } @@ -642,6 +646,7 @@ class MediaStoreImageProvider : ImageProvider() { targetDir = targetDir, targetDirDocFile = targetDirDocFile, targetNameWithoutExtension = targetNameWithoutExtension, + defaultExtension = defaultExtension, write = write, ) } @@ -700,6 +705,7 @@ class MediaStoreImageProvider : ImageProvider() { targetDir: String, targetDirDocFile: DocumentFileCompat?, targetNameWithoutExtension: String, + defaultExtension: String?, write: (OutputStream) -> Unit, ): String { targetDirDocFile ?: throw Exception("failed to get tree doc for directory at path=$targetDir") @@ -708,8 +714,22 @@ class MediaStoreImageProvider : ImageProvider() { // but in order to open an output stream to it, we need to use a `SingleDocumentFile` // through a document URI, not a tree URI // note that `DocumentFile.getParentFile()` returns null if we did not pick a tree first - val targetTreeFile = targetDirDocFile.createFile(mimeType, targetNameWithoutExtension) - val targetDocFile = DocumentFileCompat.fromSingleUri(activity, targetTreeFile.uri) + var targetTreeFile = targetDirDocFile.createFile(mimeType, targetNameWithoutExtension) + var targetDocFile = DocumentFileCompat.fromSingleUri(activity, targetTreeFile.uri) + + // providing a display name and a MIME type does not guarantee + // that the created document will be backed by a file with a valid media extension, + // but having an extension is essential for media detection by Android, + // so we retry with a display name that includes the extension + if ((targetDocFile.extension == null || targetDocFile.extension.isEmpty() || targetDocFile.extension == "bin") && defaultExtension != null) { + if (targetDocFile.exists()) { + targetDocFile.delete() + } + + val extension = if (defaultExtension.startsWith(".")) defaultExtension else ".$defaultExtension" + targetTreeFile = targetDirDocFile.createFile(mimeType, "$targetNameWithoutExtension$extension") + targetDocFile = DocumentFileCompat.fromSingleUri(activity, targetTreeFile.uri) + } try { targetDocFile.openOutputStream().use(write) 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 c0bef41c9..1e6ae58cd 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 @@ -163,12 +163,24 @@ object MimeTypes { // among other refs: // - https://android.googlesource.com/platform/external/mime-support/+/refs/heads/master/mime.types - fun extensionFor(mimeType: String): String? = when (mimeType) { + fun extensionFor(mimeType: String, defaultExtension: String?): String = when (mimeType) { AVI, AVI_VND -> ".avi" + DNG, DNG_ADOBE -> ".dng" HEIC, HEIF -> ".heif" MP2T, MP2TS -> ".m2ts" PSD_VND, PSD_X -> ".psd" - else -> MimeTypeMap.getSingleton().getExtensionFromMimeType(mimeType)?.let { ".$it" } + else -> { + val ext = MimeTypeMap.getSingleton().getExtensionFromMimeType(mimeType) ?: defaultExtension + if (ext != null) { + // fallback to provided extension when available, + // typically the original file extension when moving/renaming + if (ext.startsWith(".")) ext else ".$ext" + } else { + // fallback to generic extensions, + // as incorrect file extensions are better than none for media detection + if (isVideo(mimeType)) ".mp4" else ".jpg" + } + } } val TIFF_EXTENSION_PATTERN = Regex(".*\\.tiff?", RegexOption.IGNORE_CASE) diff --git a/android/app/src/main/res/values-my/strings.xml b/android/app/src/main/res/values-my/strings.xml index dfacebf6d..ae4237c81 100644 --- a/android/app/src/main/res/values-my/strings.xml +++ b/android/app/src/main/res/values-my/strings.xml @@ -8,4 +8,5 @@ ဗီဒီယိုများ မီဒီယာ ကိုစကင်ဖတ်နေသည် ရပ်ရန် - \ 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 7643c4193..19b6a15ae 100644 --- a/android/exifinterface/src/main/java/androidx/exifinterface/media/ExifInterfaceFork.java +++ b/android/exifinterface/src/main/java/androidx/exifinterface/media/ExifInterfaceFork.java @@ -22,7 +22,6 @@ 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; @@ -91,7 +90,7 @@ import java.util.regex.Pattern; import java.util.zip.CRC32; /* - * Forked from 'androidx.exifinterface:exifinterface:1.4.0' + * Forked from 'androidx.exifinterface:exifinterface:1.4.1' * Named differently to let ExifInterface be loaded as subdependency. * cf https://maven.google.com/web/index.html?q=exifinterface#androidx.exifinterface:exifinterface * cf https://github.com/androidx/androidx/tree/androidx-main/exifinterface/exifinterface/src/main/java/androidx/exifinterface/media @@ -139,6 +138,12 @@ public class ExifInterfaceFork { // TLAD threshold for safer Exif attribute parsing private static final int ATTRIBUTE_SIZE_DANGER_THRESHOLD = 3 * (1 << 20); // MB + // TLAD available heap size, to check allocations + private long getAvailableHeapSize() { + final Runtime runtime = Runtime.getRuntime(); + return runtime.maxMemory() - (runtime.totalMemory() - runtime.freeMemory()); + } + private static final String TAG = "ExifInterface"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); @@ -4553,7 +4558,7 @@ public class ExifInterfaceFork { && (mXmpFromSeparateMarker != null || !containsTiff700Xmp)) || (xmpHandling == XMP_HANDLING_PREFER_TIFF_700_IF_PRESENT && !containsTiff700Xmp)) { - mXmpFromSeparateMarker = ExifAttribute.createByte(value); + mXmpFromSeparateMarker = value != null ? ExifAttribute.createByte(value) : null; return; } } @@ -6558,8 +6563,9 @@ public class ExifInterfaceFork { // Exif data in WebP images (e.g. // https://github.com/ImageMagick/ImageMagick/issues/3140) if (startsWith(payload, IDENTIFIER_EXIF_APP1)) { - payload = Arrays.copyOfRange(payload, IDENTIFIER_EXIF_APP1.length, - payload.length); + payload = + Arrays.copyOfRange( + payload, IDENTIFIER_EXIF_APP1.length, payload.length); } // Save offset to EXIF data for handling thumbnail and attribute offsets. @@ -6722,8 +6728,11 @@ public class ExifInterfaceFork { copy(dataInputStream, dataOutputStream, PNG_SIGNATURE.length); boolean needToWriteExif = true; - boolean needToWriteXmp = mXmpFromSeparateMarker != null; - while (needToWriteExif || needToWriteXmp) { + // Either there's some XMP data to write, or it has been cleared locally but was present in + // the file when it was read (and so needs to be removed). + boolean needToHandleXmpChunk = + mXmpFromSeparateMarker != null || mFileOnDiskContainsSeparateXmpMarker; + while (needToWriteExif || needToHandleXmpChunk) { int chunkLength = dataInputStream.readInt(); int chunkType = dataInputStream.readInt(); if (chunkType == PNG_CHUNK_TYPE_IHDR) { @@ -6738,7 +6747,7 @@ public class ExifInterfaceFork { } if (mXmpFromSeparateMarker != null && !mFileOnDiskContainsSeparateXmpMarker) { writePngXmpItxtChunk(dataOutputStream); - needToWriteXmp = false; + needToHandleXmpChunk = false; } continue; } else if (chunkType == PNG_CHUNK_TYPE_EXIF && needToWriteExif) { @@ -6746,10 +6755,25 @@ public class ExifInterfaceFork { dataInputStream.skipFully(chunkLength + PNG_CHUNK_CRC_BYTE_LENGTH); needToWriteExif = false; continue; - } else if (chunkType == PNG_CHUNK_TYPE_ITXT && needToWriteXmp) { - writePngXmpItxtChunk(dataOutputStream); - dataInputStream.skipFully(chunkLength + PNG_CHUNK_CRC_BYTE_LENGTH); - needToWriteXmp = false; + } else if (chunkType == PNG_CHUNK_TYPE_ITXT + && chunkLength >= PNG_ITXT_XMP_KEYWORD.length) { + // Read the 17 byte keyword and 5 expected null bytes. + byte[] keyword = new byte[PNG_ITXT_XMP_KEYWORD.length]; + dataInputStream.readFully(keyword); + int remainingChunkBytes = chunkLength - keyword.length + PNG_CHUNK_CRC_BYTE_LENGTH; + if (Arrays.equals(keyword, PNG_ITXT_XMP_KEYWORD)) { + if (mXmpFromSeparateMarker != null) { + writePngXmpItxtChunk(dataOutputStream); + } + dataInputStream.skipFully(remainingChunkBytes); + needToHandleXmpChunk = false; + } else { + // This is a non-XMP iTXt chunk, so just copy it to the output and continue. + dataOutputStream.writeInt(chunkLength); + dataOutputStream.writeInt(chunkType); + dataOutputStream.write(keyword); + copy(dataInputStream, dataOutputStream, remainingChunkBytes); + } continue; } dataOutputStream.writeInt(chunkLength); @@ -7536,6 +7560,13 @@ public class ExifInterfaceFork { Log.d(TAG, "Invalid strip offset value"); return; } + + // TLAD start + if (bytesToSkip > getAvailableHeapSize()) { + throw new IOException("cannot allocate " + bytesToSkip + " bytes to skip to retrieve thumbnail"); + } + // TLAD end + try { in.skipFully(bytesToSkip); } catch (EOFException e) { 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 301e306fa..266959a5c 100644 --- a/android/exifinterface/src/main/java/androidx/exifinterface/media/ExifInterfaceUtilsFork.java +++ b/android/exifinterface/src/main/java/androidx/exifinterface/media/ExifInterfaceUtilsFork.java @@ -31,7 +31,7 @@ import java.io.InputStream; import java.io.OutputStream; /* - * Forked from 'androidx.exifinterface:exifinterface:1.4.0-alpha01' on 2024/11/17 + * Forked from 'androidx.exifinterface:exifinterface:1.4.1' * 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 */ diff --git a/fastlane/metadata/android/en-US/changelogs/153.txt b/fastlane/metadata/android/en-US/changelogs/153.txt new file mode 100644 index 000000000..34f08c4ad --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/153.txt @@ -0,0 +1,4 @@ +In v1.13.2: +- group albums +- filter by day of the week +Full changelog available on GitHub \ No newline at end of file diff --git a/fastlane/metadata/android/en-US/changelogs/15301.txt b/fastlane/metadata/android/en-US/changelogs/15301.txt new file mode 100644 index 000000000..34f08c4ad --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/15301.txt @@ -0,0 +1,4 @@ +In v1.13.2: +- group albums +- filter by day of the week +Full changelog available on GitHub \ No newline at end of file diff --git a/lib/l10n/app_ar.arb b/lib/l10n/app_ar.arb index 07e322eb4..02fd24fc6 100644 --- a/lib/l10n/app_ar.arb +++ b/lib/l10n/app_ar.arb @@ -599,7 +599,7 @@ "@settingsLanguagePageTitle": {}, "rootDirectoryDescription": "دليل الجذر", "@rootDirectoryDescription": {}, - "viewDialogGroupSectionTitle": "مجموعة", + "viewDialogGroupSectionTitle": "الأقسام", "@viewDialogGroupSectionTitle": {}, "maxBrightnessAlways": "دائماً", "@maxBrightnessAlways": {}, @@ -1449,7 +1449,7 @@ "@binPageTitle": {}, "tagPlaceholderState": "الولاية", "@tagPlaceholderState": {}, - "sortByAlbumFileName": "حسب الألبوم واسم الملف", + "sortByAlbumFileName": "حسب عنوان الألبوم والعنصر", "@sortByAlbumFileName": {}, "deleteMultiAlbumConfirmationDialogMessage": "{count, plural, =1{هل تريد حذف هذه الألبومات والعنصر الموجود فيها؟} other{احذف هذه الألبومات و {count} العناصر فيها؟}}", "@deleteMultiAlbumConfirmationDialogMessage": { @@ -1599,8 +1599,28 @@ "@sortByPath": {}, "searchFormatSectionTitle": "التنسيقات", "@searchFormatSectionTitle": {}, - "chipActionGroup": "مجموعة", + "chipActionGroup": "تغيير التجميع", "@chipActionGroup": {}, "createButtonLabel": "خلق", - "@createButtonLabel": {} + "@createButtonLabel": {}, + "sectionNone": "لا يوجد أقسام", + "@sectionNone": {}, + "chipActionCreateGroup": "إنشاء مجموعة", + "@chipActionCreateGroup": {}, + "albumTierGroups": "المجموعات", + "@albumTierGroups": {}, + "newGroupDialogTitle": "مجموعة جديدة", + "@newGroupDialogTitle": {}, + "newGroupDialogNameLabel": "اسم المجموعة", + "@newGroupDialogNameLabel": {}, + "groupAlreadyExists": "المجموعة موجودة بالفعل", + "@groupAlreadyExists": {}, + "groupEmpty": "لا توجد مجموعات", + "@groupEmpty": {}, + "ungrouped": "غير مجمعة", + "@ungrouped": {}, + "groupPickerTitle": "اختر المجموعة", + "@groupPickerTitle": {}, + "groupPickerUseThisGroupButton": "استخدم هذه المجموعة", + "@groupPickerUseThisGroupButton": {} } diff --git a/lib/l10n/app_az.arb b/lib/l10n/app_az.arb index 90ebd78a5..920c5e318 100644 --- a/lib/l10n/app_az.arb +++ b/lib/l10n/app_az.arb @@ -142,5 +142,15 @@ "chipActionUnpin": "Sabitləməyin", "@chipActionUnpin": {}, "chipActionRename": "Bir də adlandır", - "@chipActionRename": {} + "@chipActionRename": {}, + "chipActionDecompose": "Böl", + "@chipActionDecompose": {}, + "chipActionCreateAlbum": "Albom yarat", + "@chipActionCreateAlbum": {}, + "createButtonLabel": "YARAT", + "@createButtonLabel": {}, + "chipActionGroup": "Qruplandırmanı dəyişdir", + "@chipActionGroup": {}, + "chipActionCreateGroup": "Qrup yarat", + "@chipActionCreateGroup": {} } diff --git a/lib/l10n/app_bg.arb b/lib/l10n/app_bg.arb index a31471659..e02243331 100644 --- a/lib/l10n/app_bg.arb +++ b/lib/l10n/app_bg.arb @@ -1624,5 +1624,19 @@ "sortByPath": "Според пътя", "@sortByPath": {}, "searchFormatSectionTitle": "Формати", - "@searchFormatSectionTitle": {} + "@searchFormatSectionTitle": {}, + "chipActionCreateGroup": "Създайте група", + "@chipActionCreateGroup": {}, + "chipActionGroup": "Групиране", + "@chipActionGroup": {}, + "newGroupDialogTitle": "Нова Група", + "@newGroupDialogTitle": {}, + "groupAlreadyExists": "Групата вече съществува", + "@groupAlreadyExists": {}, + "albumTierGroups": "Групи", + "@albumTierGroups": {}, + "groupPickerUseThisGroupButton": "Използвайте тази група", + "@groupPickerUseThisGroupButton": {}, + "newGroupDialogNameLabel": "Име на групата", + "@newGroupDialogNameLabel": {} } diff --git a/lib/l10n/app_da.arb b/lib/l10n/app_da.arb index 46cd5bbbb..bc845fd97 100644 --- a/lib/l10n/app_da.arb +++ b/lib/l10n/app_da.arb @@ -850,7 +850,7 @@ "@drawerCollectionRaws": {}, "sortByRating": "Efter bedømmelse", "@sortByRating": {}, - "sortByAlbumFileName": "Efter album og filnavn", + "sortByAlbumFileName": "Efter album og elementtitel", "@sortByAlbumFileName": {}, "albumGroupVolume": "Efter lagervolume", "@albumGroupVolume": {}, @@ -1627,7 +1627,7 @@ "@searchFormatSectionTitle": {}, "createButtonLabel": "OPRET", "@createButtonLabel": {}, - "chipActionGroup": "Gruppér", + "chipActionGroup": "Ændr gruppering", "@chipActionGroup": {}, "chipActionCreateGroup": "Opret gruppe", "@chipActionCreateGroup": {}, diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 50dafb3b1..258a0e464 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -105,7 +105,7 @@ "chipActionLock": "Lock", "chipActionPin": "Pin to top", "chipActionUnpin": "Unpin from top", - "chipActionGroup": "Group", + "chipActionGroup": "Change grouping", "chipActionRename": "Rename", "chipActionSetCover": "Set cover", "chipActionShowCountryStates": "Show states", @@ -767,7 +767,7 @@ "sortByName": "By name", "sortByItemCount": "By item count", "sortBySize": "By size", - "sortByAlbumFileName": "By album & file name", + "sortByAlbumFileName": "By album & item title", "sortByRating": "By rating", "sortByDuration": "By duration", "sortByPath": "By path", diff --git a/lib/l10n/app_et.arb b/lib/l10n/app_et.arb index fe0e6b1a6..ce5eba554 100644 --- a/lib/l10n/app_et.arb +++ b/lib/l10n/app_et.arb @@ -790,7 +790,7 @@ "@aboutLicensesDartPackagesSectionTitle": {}, "aboutLicensesShowAllButtonLabel": "Näita kõiki litsentse", "@aboutLicensesShowAllButtonLabel": {}, - "policyPageTitle": "Privaatsuspoliitika", + "policyPageTitle": "Andmekaitsepõhimõtted", "@policyPageTitle": {}, "collectionPageTitle": "Meediakogu", "@collectionPageTitle": {}, @@ -1036,7 +1036,7 @@ "@sortBySize": {}, "sortByName": "Nime alusel", "@sortByName": {}, - "sortByAlbumFileName": "Albumi ja failinime alusel", + "sortByAlbumFileName": "Albumi ja objekti nime alusel", "@sortByAlbumFileName": {}, "sortByRating": "Hinnangu alusel", "@sortByRating": {}, @@ -1645,7 +1645,7 @@ "@groupPickerUseThisGroupButton": {}, "createButtonLabel": "LOO", "@createButtonLabel": {}, - "chipActionGroup": "Rühmita", + "chipActionGroup": "Muuda grupeerimist", "@chipActionGroup": {}, "sectionNone": "Rubriike pole", "@sectionNone": {} diff --git a/lib/l10n/app_fr.arb b/lib/l10n/app_fr.arb index bd5eedfc9..560c9aad3 100644 --- a/lib/l10n/app_fr.arb +++ b/lib/l10n/app_fr.arb @@ -637,7 +637,7 @@ "@sortByItemCount": {}, "sortBySize": "par taille", "@sortBySize": {}, - "sortByAlbumFileName": "alphabétique", + "sortByAlbumFileName": "par titre d’album et élément", "@sortByAlbumFileName": {}, "sortByRating": "par notation", "@sortByRating": {}, @@ -1407,7 +1407,7 @@ "@sortByPath": {}, "searchFormatSectionTitle": "Formats", "@searchFormatSectionTitle": {}, - "chipActionGroup": "Grouper", + "chipActionGroup": "Modifier groupement", "@chipActionGroup": {}, "createButtonLabel": "CRÉER", "@createButtonLabel": {}, diff --git a/lib/l10n/app_he.arb b/lib/l10n/app_he.arb index 0cdef30e9..1b4456987 100644 --- a/lib/l10n/app_he.arb +++ b/lib/l10n/app_he.arb @@ -158,5 +158,49 @@ "chipActionCreateGroup": "צור קבוצה", "@chipActionCreateGroup": {}, "chipActionCreateVault": "צור כספת", - "@chipActionCreateVault": {} + "@chipActionCreateVault": {}, + "newGroupDialogTitle": "קבוצה חדשה", + "@newGroupDialogTitle": {}, + "groupAlreadyExists": "הקבוצה כבר קיימת", + "@groupAlreadyExists": {}, + "entryActionDelete": "מחיקה", + "@entryActionDelete": {}, + "entryActionConvert": "המרה", + "@entryActionConvert": {}, + "entryActionRotateCCW": "סובב נגד כיוון השעון", + "@entryActionRotateCCW": {}, + "entryActionShare": "שיתוף", + "@entryActionShare": {}, + "entryActionShareVideoOnly": "שיתוף וידיאו בלבד‍", + "@entryActionShareVideoOnly": {}, + "videoActionSelectStreams": "בחר מסלולים", + "@videoActionSelectStreams": {}, + "videoActionShowPreviousFrame": "הצג פריים קודם", + "@videoActionShowPreviousFrame": {}, + "videoActionShowNextFrame": "הצג פריים הבא", + "@videoActionShowNextFrame": {}, + "chipActionConfigureVault": "הגדרת כספת", + "@chipActionConfigureVault": {}, + "entryActionCopyToClipboard": "הועתק ללוח", + "@entryActionCopyToClipboard": {}, + "entryActionShareImageOnly": "שיתוף תמונה בלבד", + "@entryActionShareImageOnly": {}, + "entryActionRotateCW": "סובב עם כיוון השעון", + "@entryActionRotateCW": {}, + "entryActionFlip": "הפוך אופקית", + "@entryActionFlip": {}, + "entryActionPrint": "הדפסה", + "@entryActionPrint": {}, + "entryActionViewSource": "מקור וידאו", + "@entryActionViewSource": {}, + "entryActionShowGeoTiffOnMap": "הצג כשכבת מפה", + "@entryActionShowGeoTiffOnMap": {}, + "entryActionInfo": "מידע", + "@entryActionInfo": {}, + "entryActionExport": "ייצוא", + "@entryActionExport": {}, + "entryActionRename": "שינוי שם", + "@entryActionRename": {}, + "entryActionRestore": "שחזור", + "@entryActionRestore": {} } diff --git a/lib/l10n/app_hu.arb b/lib/l10n/app_hu.arb index 28afd1bd1..41c85250c 100644 --- a/lib/l10n/app_hu.arb +++ b/lib/l10n/app_hu.arb @@ -291,7 +291,7 @@ "@tileLayoutMosaic": {}, "tileLayoutGrid": "Rács", "@tileLayoutGrid": {}, - "viewDialogGroupSectionTitle": "Csoport", + "viewDialogGroupSectionTitle": "Szekciók", "@viewDialogGroupSectionTitle": {}, "menuActionStats": "Statisztikák", "@menuActionStats": {}, @@ -1594,5 +1594,33 @@ "editEntryLocationDialogTimeShift": "Időeltolódás", "@editEntryLocationDialogTimeShift": {}, "removeEntryMetadataDialogAll": "Összes", - "@removeEntryMetadataDialogAll": {} + "@removeEntryMetadataDialogAll": {}, + "sortByPath": "Útvonal szerint", + "@sortByPath": {}, + "chipActionCreateGroup": "Csoport létrehozása", + "@chipActionCreateGroup": {}, + "albumTierGroups": "Csoportok", + "@albumTierGroups": {}, + "chipActionGroup": "Csoportosítás", + "@chipActionGroup": {}, + "createButtonLabel": "LÉTREHOZÁS", + "@createButtonLabel": {}, + "newGroupDialogTitle": "Új csoport", + "@newGroupDialogTitle": {}, + "newGroupDialogNameLabel": "Csoport neve", + "@newGroupDialogNameLabel": {}, + "groupAlreadyExists": "Csoport már létezik", + "@groupAlreadyExists": {}, + "groupEmpty": "Nincsenek csoportok", + "@groupEmpty": {}, + "ungrouped": "Csoportosítatlan", + "@ungrouped": {}, + "groupPickerTitle": "Válassza ki a csoportot", + "@groupPickerTitle": {}, + "groupPickerUseThisGroupButton": "Használja ezt a csoportot", + "@groupPickerUseThisGroupButton": {}, + "searchFormatSectionTitle": "Formátumok", + "@searchFormatSectionTitle": {}, + "sectionNone": "Semmi szerint", + "@sectionNone": {} } diff --git a/lib/l10n/app_id.arb b/lib/l10n/app_id.arb index 31920cddc..78272d192 100644 --- a/lib/l10n/app_id.arb +++ b/lib/l10n/app_id.arb @@ -453,7 +453,7 @@ "@menuActionStats": {}, "viewDialogSortSectionTitle": "Sortir", "@viewDialogSortSectionTitle": {}, - "viewDialogGroupSectionTitle": "Grup", + "viewDialogGroupSectionTitle": "Bagian", "@viewDialogGroupSectionTitle": {}, "viewDialogLayoutSectionTitle": "Tata letak", "@viewDialogLayoutSectionTitle": {}, @@ -1406,5 +1406,29 @@ "sortByPath": "Melalui lokasi", "@sortByPath": {}, "searchFormatSectionTitle": "Format", - "@searchFormatSectionTitle": {} + "@searchFormatSectionTitle": {}, + "sectionNone": "Tidak ada bagian", + "@sectionNone": {}, + "albumTierGroups": "Kelompok", + "@albumTierGroups": {}, + "createButtonLabel": "BUAT", + "@createButtonLabel": {}, + "chipActionGroup": "Kelompok", + "@chipActionGroup": {}, + "chipActionCreateGroup": "Buat kelompok", + "@chipActionCreateGroup": {}, + "ungrouped": "Tidak dikelompokkan", + "@ungrouped": {}, + "newGroupDialogTitle": "Kelompok Baru", + "@newGroupDialogTitle": {}, + "newGroupDialogNameLabel": "Nama kelompok", + "@newGroupDialogNameLabel": {}, + "groupAlreadyExists": "Kelompok sudah ada", + "@groupAlreadyExists": {}, + "groupEmpty": "Tidak ada kelompok", + "@groupEmpty": {}, + "groupPickerTitle": "Pilih Kelompok", + "@groupPickerTitle": {}, + "groupPickerUseThisGroupButton": "Gunakan kelompok ini", + "@groupPickerUseThisGroupButton": {} } diff --git a/lib/l10n/app_is.arb b/lib/l10n/app_is.arb index 8cc3550cf..7f02e481a 100644 --- a/lib/l10n/app_is.arb +++ b/lib/l10n/app_is.arb @@ -1346,7 +1346,7 @@ "@binPageTitle": {}, "tagPlaceholderState": "Hérað", "@tagPlaceholderState": {}, - "sortByAlbumFileName": "Eftir heiti albúma og skráa", + "sortByAlbumFileName": "Eftir heiti albúma og atriða", "@sortByAlbumFileName": {}, "deleteMultiAlbumConfirmationDialogMessage": "{count, plural, =1{Eyða þessum albúmum og atriðinu í þeim?} other{Eyða þessum albúmum og {count} atriðum í þeim??}}", "@deleteMultiAlbumConfirmationDialogMessage": { diff --git a/lib/l10n/app_ja.arb b/lib/l10n/app_ja.arb index d4c4dc39a..3dda76d12 100644 --- a/lib/l10n/app_ja.arb +++ b/lib/l10n/app_ja.arb @@ -317,7 +317,7 @@ "@binEntriesConfirmationDialogMessage": {}, "deleteEntriesConfirmationDialogMessage": "{count, plural, =1{このアイテムを削除しますか?} other{{count} 件のアイテムを削除しますか?}}", "@deleteEntriesConfirmationDialogMessage": {}, - "moveUndatedConfirmationDialogMessage": "いくつかのアイテムはメタデータ上に日付がありません。メタデータ上の日付が設定されない場合、この操作によりこれらの現在の日付はリセットされます", + "moveUndatedConfirmationDialogMessage": "続行する前にアイテムの日付を保存しますか?", "@moveUndatedConfirmationDialogMessage": {}, "moveUndatedConfirmationDialogSetDate": "日付を設定", "@moveUndatedConfirmationDialogSetDate": {}, diff --git a/lib/l10n/app_ko.arb b/lib/l10n/app_ko.arb index 1b98169ea..ba7163367 100644 --- a/lib/l10n/app_ko.arb +++ b/lib/l10n/app_ko.arb @@ -637,7 +637,7 @@ "@sortByItemCount": {}, "sortBySize": "크기", "@sortBySize": {}, - "sortByAlbumFileName": "이름", + "sortByAlbumFileName": "앨범 및 항목 제목", "@sortByAlbumFileName": {}, "sortByRating": "별점", "@sortByRating": {}, @@ -1409,7 +1409,7 @@ "@searchFormatSectionTitle": {}, "chipActionCreateGroup": "그룹 만들기", "@chipActionCreateGroup": {}, - "chipActionGroup": "그룹으로 이동", + "chipActionGroup": "그룹 변경", "@chipActionGroup": {}, "albumTierGroups": "그룹", "@albumTierGroups": {}, diff --git a/lib/l10n/app_my.arb b/lib/l10n/app_my.arb index eea760908..fdb5da7fb 100644 --- a/lib/l10n/app_my.arb +++ b/lib/l10n/app_my.arb @@ -1312,5 +1312,19 @@ "settingsVideoPlaybackTile": "ဖွင့်ကြည့်ခြင်း", "@settingsVideoPlaybackTile": {}, "chipActionShowCollection": "စုစည်းမှုထဲမှာ ပြရန်", - "@chipActionShowCollection": {} + "@chipActionShowCollection": {}, + "chipActionDecompose": "ဖြတ်ထုတ်ရန်", + "@chipActionDecompose": {}, + "chipActionGroup": "အုပ်စုဖွဲ့မည်", + "@chipActionGroup": {}, + "stopTooltip": "ရပ်ရန်", + "@stopTooltip": {}, + "createButtonLabel": "အသစ်ထည့်ရန်", + "@createButtonLabel": {}, + "chipActionRemove": "ဖယ်ရှားမည်", + "@chipActionRemove": {}, + "chipActionGoToExplorerPage": "Explorer ထဲတွင်ပြမည်", + "@chipActionGoToExplorerPage": {}, + "chipActionCreateGroup": "အုပ်စုအသစ်ပြုလုပ်မည်", + "@chipActionCreateGroup": {} } diff --git a/lib/l10n/app_nl.arb b/lib/l10n/app_nl.arb index 8c5a1ef28..dd6de2ab7 100644 --- a/lib/l10n/app_nl.arb +++ b/lib/l10n/app_nl.arb @@ -627,7 +627,7 @@ "@sortByItemCount": {}, "sortBySize": "Op grootte", "@sortBySize": {}, - "sortByAlbumFileName": "Op album- en bestandsnaam", + "sortByAlbumFileName": "Op album- en itemnaam", "@sortByAlbumFileName": {}, "sortByRating": "Op waardering", "@sortByRating": {}, @@ -1416,7 +1416,7 @@ "@groupPickerUseThisGroupButton": {}, "newGroupDialogTitle": "Nieuwe groep", "@newGroupDialogTitle": {}, - "chipActionGroup": "Groeperen", + "chipActionGroup": "Groepering wijzigen", "@chipActionGroup": {}, "chipActionCreateGroup": "Groep aanmaken", "@chipActionCreateGroup": {}, diff --git a/lib/l10n/app_pl.arb b/lib/l10n/app_pl.arb index cb2d24739..083d7d734 100644 --- a/lib/l10n/app_pl.arb +++ b/lib/l10n/app_pl.arb @@ -769,7 +769,7 @@ "@drawerCollectionPanoramas": {}, "drawerCollectionRaws": "Nieprzetworzone zdjęcia", "@drawerCollectionRaws": {}, - "sortByAlbumFileName": "Według albumu i nazwy pliku", + "sortByAlbumFileName": "Według albumu i nazwy elementu", "@sortByAlbumFileName": {}, "albumMimeTypeMixed": "Mieszane", "@albumMimeTypeMixed": {}, @@ -1603,7 +1603,7 @@ "@sectionNone": {}, "createButtonLabel": "UTWÓRZ", "@createButtonLabel": {}, - "chipActionGroup": "Grupuj", + "chipActionGroup": "Zmień grupowanie", "@chipActionGroup": {}, "chipActionCreateGroup": "Utwórz grupę", "@chipActionCreateGroup": {}, diff --git a/lib/l10n/app_pt.arb b/lib/l10n/app_pt.arb index e99663ee3..7cb1973b1 100644 --- a/lib/l10n/app_pt.arb +++ b/lib/l10n/app_pt.arb @@ -463,7 +463,7 @@ "@menuActionStats": {}, "viewDialogSortSectionTitle": "Organizar", "@viewDialogSortSectionTitle": {}, - "viewDialogGroupSectionTitle": "Grupo", + "viewDialogGroupSectionTitle": "Seções", "@viewDialogGroupSectionTitle": {}, "viewDialogLayoutSectionTitle": "Layout", "@viewDialogLayoutSectionTitle": {}, @@ -633,7 +633,7 @@ "@sortByItemCount": {}, "sortBySize": "Por tamanho", "@sortBySize": {}, - "sortByAlbumFileName": "Por álbum e nome de arquivo", + "sortByAlbumFileName": "Por álbum e título do item", "@sortByAlbumFileName": {}, "sortByRating": "Por classificação", "@sortByRating": {}, @@ -1406,5 +1406,29 @@ "sortByPath": "Pelo caminho", "@sortByPath": {}, "searchFormatSectionTitle": "Formatos", - "@searchFormatSectionTitle": {} + "@searchFormatSectionTitle": {}, + "createButtonLabel": "CRIAR", + "@createButtonLabel": {}, + "chipActionGroup": "Alterar agrupamento", + "@chipActionGroup": {}, + "chipActionCreateGroup": "Criar grupo", + "@chipActionCreateGroup": {}, + "albumTierGroups": "Grupos", + "@albumTierGroups": {}, + "newGroupDialogTitle": "Novo Grupo", + "@newGroupDialogTitle": {}, + "newGroupDialogNameLabel": "Nome do grupo", + "@newGroupDialogNameLabel": {}, + "groupAlreadyExists": "O grupo já existe", + "@groupAlreadyExists": {}, + "groupEmpty": "Nenhum grupo", + "@groupEmpty": {}, + "ungrouped": "Desagrupado", + "@ungrouped": {}, + "groupPickerTitle": "Selecionar Grupo", + "@groupPickerTitle": {}, + "groupPickerUseThisGroupButton": "Usar este grupo", + "@groupPickerUseThisGroupButton": {}, + "sectionNone": "Nenhuma seção", + "@sectionNone": {} } diff --git a/lib/l10n/app_ro.arb b/lib/l10n/app_ro.arb index 0fec3d949..0ec2a544c 100644 --- a/lib/l10n/app_ro.arb +++ b/lib/l10n/app_ro.arb @@ -526,7 +526,7 @@ "@menuActionStats": {}, "viewDialogSortSectionTitle": "Sortează", "@viewDialogSortSectionTitle": {}, - "viewDialogGroupSectionTitle": "Grup", + "viewDialogGroupSectionTitle": "Secțiuni", "@viewDialogGroupSectionTitle": {}, "viewDialogLayoutSectionTitle": "Aspect", "@viewDialogLayoutSectionTitle": {}, @@ -887,7 +887,7 @@ "@drawerCollectionSphericalVideos": {}, "drawerAlbumPage": "Albume", "@drawerAlbumPage": {}, - "sortByAlbumFileName": "După album și numele fișierului", + "sortByAlbumFileName": "După album și numele elementului", "@sortByAlbumFileName": {}, "sortOrderZtoA": "De la Z la A", "@sortOrderZtoA": {}, @@ -1598,5 +1598,29 @@ "sortByPath": "După cale", "@sortByPath": {}, "searchFormatSectionTitle": "Formate", - "@searchFormatSectionTitle": {} + "@searchFormatSectionTitle": {}, + "createButtonLabel": "CREARE", + "@createButtonLabel": {}, + "chipActionCreateGroup": "Creați un grup", + "@chipActionCreateGroup": {}, + "newGroupDialogTitle": "Grup nou", + "@newGroupDialogTitle": {}, + "newGroupDialogNameLabel": "Nume grup", + "@newGroupDialogNameLabel": {}, + "groupAlreadyExists": "Grupul deja există", + "@groupAlreadyExists": {}, + "chipActionGroup": "Grupe", + "@chipActionGroup": {}, + "albumTierGroups": "Grupe", + "@albumTierGroups": {}, + "groupPickerTitle": "Alege un grup", + "@groupPickerTitle": {}, + "groupPickerUseThisGroupButton": "Folosește acest grup", + "@groupPickerUseThisGroupButton": {}, + "sectionNone": "Nicio secțiune", + "@sectionNone": {}, + "ungrouped": "Fără grup", + "@ungrouped": {}, + "groupEmpty": "Niciun grup", + "@groupEmpty": {} } diff --git a/lib/l10n/app_ru.arb b/lib/l10n/app_ru.arb index 4313c7ee2..b39efc64f 100644 --- a/lib/l10n/app_ru.arb +++ b/lib/l10n/app_ru.arb @@ -463,7 +463,7 @@ "@menuActionStats": {}, "viewDialogSortSectionTitle": "Сортировка", "@viewDialogSortSectionTitle": {}, - "viewDialogGroupSectionTitle": "Группировка", + "viewDialogGroupSectionTitle": "Разделы", "@viewDialogGroupSectionTitle": {}, "viewDialogLayoutSectionTitle": "Макет", "@viewDialogLayoutSectionTitle": {}, @@ -633,7 +633,7 @@ "@sortByItemCount": {}, "sortBySize": "По размеру", "@sortBySize": {}, - "sortByAlbumFileName": "По имени альбома и файла", + "sortByAlbumFileName": "По названию альбома и пункта", "@sortByAlbumFileName": {}, "sortByRating": "По рейтингу", "@sortByRating": {}, @@ -1406,5 +1406,29 @@ "searchFormatSectionTitle": "Форматы", "@searchFormatSectionTitle": {}, "sortByPath": "По пути", - "@sortByPath": {} + "@sortByPath": {}, + "chipActionGroup": "Изменить группировку", + "@chipActionGroup": {}, + "createButtonLabel": "СОЗДАТЬ", + "@createButtonLabel": {}, + "chipActionCreateGroup": "Создать группу", + "@chipActionCreateGroup": {}, + "albumTierGroups": "Группы", + "@albumTierGroups": {}, + "newGroupDialogTitle": "Новая группа", + "@newGroupDialogTitle": {}, + "newGroupDialogNameLabel": "Название группы", + "@newGroupDialogNameLabel": {}, + "groupAlreadyExists": "Группа уже существует", + "@groupAlreadyExists": {}, + "groupEmpty": "Групп нету", + "@groupEmpty": {}, + "ungrouped": "Без группировки", + "@ungrouped": {}, + "groupPickerTitle": "Выбор группы", + "@groupPickerTitle": {}, + "groupPickerUseThisGroupButton": "Использовать эту группу", + "@groupPickerUseThisGroupButton": {}, + "sectionNone": "Без разделов", + "@sectionNone": {} } diff --git a/lib/l10n/app_tr.arb b/lib/l10n/app_tr.arb index dbbfd44fb..25677d9f2 100644 --- a/lib/l10n/app_tr.arb +++ b/lib/l10n/app_tr.arb @@ -417,7 +417,7 @@ "@menuActionStats": {}, "viewDialogSortSectionTitle": "Sırala", "@viewDialogSortSectionTitle": {}, - "viewDialogGroupSectionTitle": "Grup", + "viewDialogGroupSectionTitle": "Bölümler", "@viewDialogGroupSectionTitle": {}, "viewDialogLayoutSectionTitle": "Düzen", "@viewDialogLayoutSectionTitle": {}, @@ -489,7 +489,7 @@ "@collectionActionHideTitleSearch": {}, "collectionActionAddShortcut": "Kısayol ekle", "@collectionActionAddShortcut": {}, - "collectionActionEmptyBin": "Boş çöp kutusu", + "collectionActionEmptyBin": "Çöp kutusu boş", "@collectionActionEmptyBin": {}, "collectionActionCopy": "Albüme kopyala", "@collectionActionCopy": {}, @@ -583,7 +583,7 @@ "@sortByItemCount": {}, "sortBySize": "Boyuta göre", "@sortBySize": {}, - "sortByAlbumFileName": "Albüm ve dosya adına göre", + "sortByAlbumFileName": "Albüm ve başlığı göre", "@sortByAlbumFileName": {}, "sortByRating": "Derecelendirmeye göre", "@sortByRating": {}, @@ -1400,5 +1400,35 @@ "collectionActionAddDynamicAlbum": "Dinamik albüm ekle", "@collectionActionAddDynamicAlbum": {}, "searchFormatSectionTitle": "Biçimler", - "@searchFormatSectionTitle": {} + "@searchFormatSectionTitle": {}, + "createButtonLabel": "YARAT", + "@createButtonLabel": {}, + "chipActionGroup": "Gruplandırmayı değiştir", + "@chipActionGroup": {}, + "chipActionCreateGroup": "Grup oluştur", + "@chipActionCreateGroup": {}, + "albumTierGroups": "Gruplar", + "@albumTierGroups": {}, + "coordinateFormatDdm": "DDS", + "@coordinateFormatDdm": {}, + "newGroupDialogTitle": "Yeni grup", + "@newGroupDialogTitle": {}, + "newGroupDialogNameLabel": "Grup adı", + "@newGroupDialogNameLabel": {}, + "groupAlreadyExists": "Grup zaten var", + "@groupAlreadyExists": {}, + "groupEmpty": "Grup yok", + "@groupEmpty": {}, + "ungrouped": "Gruplandırılmamış", + "@ungrouped": {}, + "groupPickerTitle": "Grubu seç", + "@groupPickerTitle": {}, + "groupPickerUseThisGroupButton": "Bu grubu kullan", + "@groupPickerUseThisGroupButton": {}, + "sectionNone": "Bölüm yok", + "@sectionNone": {}, + "sortByPath": "Yolu", + "@sortByPath": {}, + "editEntryLocationDialogTimeShift": "Zaman farkı", + "@editEntryLocationDialogTimeShift": {} } diff --git a/lib/l10n/app_uk.arb b/lib/l10n/app_uk.arb index fbb700f5c..7d123bc3d 100644 --- a/lib/l10n/app_uk.arb +++ b/lib/l10n/app_uk.arb @@ -607,7 +607,7 @@ "@drawerCountryPage": {}, "sortByName": "За назвою", "@sortByName": {}, - "sortByAlbumFileName": "За назвою альбому та файлу", + "sortByAlbumFileName": "За назвою альбому та елемента", "@sortByAlbumFileName": {}, "sortByItemCount": "За кількістю елементів", "@sortByItemCount": {}, @@ -1601,7 +1601,7 @@ "@sortByPath": {}, "createButtonLabel": "СТВОРИТИ", "@createButtonLabel": {}, - "chipActionGroup": "Згрупувати", + "chipActionGroup": "Змінити групування", "@chipActionGroup": {}, "chipActionCreateGroup": "Створити групу", "@chipActionCreateGroup": {}, diff --git a/lib/l10n/app_zh.arb b/lib/l10n/app_zh.arb index 2ae75db41..a82594120 100644 --- a/lib/l10n/app_zh.arb +++ b/lib/l10n/app_zh.arb @@ -625,7 +625,7 @@ "@sortByItemCount": {}, "sortBySize": "按大小", "@sortBySize": {}, - "sortByAlbumFileName": "按相册和文件名", + "sortByAlbumFileName": "按相册和项目标题", "@sortByAlbumFileName": {}, "sortByRating": "按评分", "@sortByRating": {}, @@ -1419,7 +1419,7 @@ "@newGroupDialogTitle": {}, "createButtonLabel": "创建", "@createButtonLabel": {}, - "chipActionGroup": "分组", + "chipActionGroup": "更改分组", "@chipActionGroup": {}, "groupAlreadyExists": "组已存在", "@groupAlreadyExists": {}, diff --git a/lib/model/app/contributors.dart b/lib/model/app/contributors.dart index f2c810b43..7b511b648 100644 --- a/lib/model/app/contributors.dart +++ b/lib/model/app/contributors.dart @@ -140,10 +140,14 @@ class Contributors { Contributor('Miquel Martí', 'miquelmarti111@gmail.com'), Contributor('Yurt Page', 'yurtpage@gmail.com'), Contributor('Murcielago', 'weblate.j9bmx@slmail.me'), + Contributor('vm', 'varga.m007@gmail.com'), + Contributor('WMatheist', 'wmatheist@protonmail.com'), // Contributor('Femini', 'nizamismidov4@gmail.com'), // Azerbaijani + // Contributor('Jamil Farajov', 'jamilfarajov@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('Thit Lwin', 'thitlwincoder@gmail.com'), // Burmese // Contributor('Åzze', 'laitinen.jere222@gmail.com'), // Finnish // Contributor('Olli', 'ollinen@ollit.dev'), // Finnish // Contributor('Ricky Tigg', 'ricky.tigg@gmail.com'), // Finnish diff --git a/lib/model/app/dependencies.dart b/lib/model/app/dependencies.dart index cf408038b..c660a2a87 100644 --- a/lib/model/app/dependencies.dart +++ b/lib/model/app/dependencies.dart @@ -212,9 +212,9 @@ class Dependencies { sourceUrl: 'https://github.com/fleaflet/flutter_map', ), Dependency( - name: 'Flutter Markdown', + name: 'Flutter Markdown Plus', license: bsd3, - sourceUrl: 'https://github.com/flutter/packages/tree/main/packages/flutter_markdown', + sourceUrl: 'https://github.com/foresightmobile/flutter_markdown_plus', ), Dependency( name: 'Flutter Staggered Animations', diff --git a/lib/model/covers.dart b/lib/model/covers.dart index a99308f35..0dcb9e023 100644 --- a/lib/model/covers.dart +++ b/lib/model/covers.dart @@ -25,7 +25,7 @@ final Covers covers = Covers._private(); typedef CoverProps = (int? entryId, String? packageName, Color? color); class Covers { - final List _subscriptions = []; + final Set _subscriptions = {}; final _lock = Lock(); final StreamController?> _entryChangeStreamController = StreamController.broadcast(); @@ -40,6 +40,8 @@ class Covers { Set _rows = {}; + // do not subscribe to events from other modules in constructor + // so that modules can subscribe to each other Covers._private(); Future init() async { diff --git a/lib/model/dynamic_albums.dart b/lib/model/dynamic_albums.dart index 2313f0773..f943803bb 100644 --- a/lib/model/dynamic_albums.dart +++ b/lib/model/dynamic_albums.dart @@ -15,19 +15,21 @@ import 'package:synchronized/synchronized.dart'; final DynamicAlbums dynamicAlbums = DynamicAlbums._private(); class DynamicAlbums with ChangeNotifier { - final List _subscriptions = []; + final Set _subscriptions = {}; final _lock = Lock(); Set _rows = {}; final EventBus eventBus = EventBus(); + // do not subscribe to events from other modules in constructor + // so that modules can subscribe to each other DynamicAlbums._private() { if (kFlutterMemoryAllocationsEnabled) ChangeNotifier.maybeDispatchObjectCreation(this); - _subscriptions.add(albumGrouping.eventBus.on().listen((e) => _onGroupUriChanged(e.oldGroupUri, e.newGroupUri))); } Future init() async { _rows = (await localMediaDb.loadAllDynamicAlbums()).map((v) => DynamicAlbumFilter(v.name, v.filter)).toSet(); + _subscriptions.add(albumGrouping.eventBus.on().listen((e) => _onGroupUriChanged(e.oldGroupUri, e.newGroupUri))); } int get count => _rows.length; @@ -57,6 +59,7 @@ class DynamicAlbums with ChangeNotifier { await _lock.synchronized(() async { await _doRemove(filters.map((filter) => filter.name).toSet()); notifyListeners(); + eventBus.fire(DynamicAlbumChangedEvent(Map.fromEntries(filters.map((v) => MapEntry(v, null))))); }); } @@ -81,13 +84,7 @@ class DynamicAlbums with ChangeNotifier { }); } - Future clear() async { - await _lock.synchronized(() async { - await localMediaDb.clearDynamicAlbums(); - _rows.clear(); - notifyListeners(); - }); - } + Future clear() => remove(all); DynamicAlbumFilter? get(String name) => _rows.firstWhereOrNull((row) => row.name == name); diff --git a/lib/model/entry/extensions/catalog.dart b/lib/model/entry/extensions/catalog.dart index 5312f8655..900cfe8e5 100644 --- a/lib/model/entry/extensions/catalog.dart +++ b/lib/model/entry/extensions/catalog.dart @@ -4,8 +4,8 @@ import 'package:aves/model/entry/entry.dart'; import 'package:aves/model/entry/extensions/keys.dart'; import 'package:aves/model/entry/extensions/props.dart'; import 'package:aves/model/media/geotiff.dart'; -import 'package:aves/model/metadata/catalog.dart'; import 'package:aves/model/media/video/metadata.dart'; +import 'package:aves/model/metadata/catalog.dart'; import 'package:aves/ref/mime_types.dart'; import 'package:aves/services/common/services.dart'; import 'package:aves/services/metadata/svg_metadata_service.dart'; diff --git a/lib/model/filters/container/set_and.dart b/lib/model/filters/container/set_and.dart index 396f5d2ea..82b09fe90 100644 --- a/lib/model/filters/container/set_and.dart +++ b/lib/model/filters/container/set_and.dart @@ -1,7 +1,7 @@ import 'package:aves/model/filters/container/container.dart'; +import 'package:aves/model/filters/covered/location.dart'; import 'package:aves/model/filters/covered/stored_album.dart'; import 'package:aves/model/filters/filters.dart'; -import 'package:aves/model/filters/covered/location.dart'; import 'package:aves/theme/icons.dart'; import 'package:collection/collection.dart'; import 'package:flutter/widgets.dart'; @@ -38,8 +38,6 @@ class SetAndFilter extends CollectionFilter with ContainerFilter { static SetAndFilter? fromMap(Map json) { final filters = (json['filters'] as List).cast().map(CollectionFilter.fromJson).nonNulls.toSet(); - if (filters.isEmpty) return null; - return SetAndFilter( filters, reversed: json['reversed'] ?? false, diff --git a/lib/model/filters/container/set_or.dart b/lib/model/filters/container/set_or.dart index 10d1f74de..27a271bbf 100644 --- a/lib/model/filters/container/set_or.dart +++ b/lib/model/filters/container/set_or.dart @@ -38,8 +38,6 @@ class SetOrFilter extends CollectionFilter with ContainerFilter { static SetOrFilter? fromMap(Map json) { final filters = (json['filters'] as List).cast().map(CollectionFilter.fromJson).nonNulls.toSet(); - if (filters.isEmpty) return null; - return SetOrFilter( filters, reversed: json['reversed'] ?? false, diff --git a/lib/model/filters/covered/covered.dart b/lib/model/filters/covered/covered.dart index bea2e8506..6e4b2c6f4 100644 --- a/lib/model/filters/covered/covered.dart +++ b/lib/model/filters/covered/covered.dart @@ -14,4 +14,3 @@ mixin CoveredFilter on CollectionFilter { return super.color(context); } } - diff --git a/lib/model/filters/filters.dart b/lib/model/filters/filters.dart index 5aa653568..cfc8c608f 100644 --- a/lib/model/filters/filters.dart +++ b/lib/model/filters/filters.dart @@ -2,9 +2,11 @@ import 'dart:convert'; import 'package:aves/model/entry/entry.dart'; import 'package:aves/model/filters/aspect_ratio.dart'; -import 'package:aves/model/filters/coordinate.dart'; import 'package:aves/model/filters/container/album_group.dart'; import 'package:aves/model/filters/container/dynamic_album.dart'; +import 'package:aves/model/filters/container/set_and.dart'; +import 'package:aves/model/filters/container/set_or.dart'; +import 'package:aves/model/filters/coordinate.dart'; import 'package:aves/model/filters/covered/location.dart'; import 'package:aves/model/filters/covered/stored_album.dart'; import 'package:aves/model/filters/covered/tag.dart'; @@ -17,8 +19,6 @@ import 'package:aves/model/filters/placeholder.dart'; import 'package:aves/model/filters/query.dart'; import 'package:aves/model/filters/rating.dart'; import 'package:aves/model/filters/recent.dart'; -import 'package:aves/model/filters/container/set_and.dart'; -import 'package:aves/model/filters/container/set_or.dart'; import 'package:aves/model/filters/trash.dart'; import 'package:aves/model/filters/type.dart'; import 'package:aves/model/filters/weekday.dart'; diff --git a/lib/model/grouping/common.dart b/lib/model/grouping/common.dart index 423d86fbd..e91a1c13a 100644 --- a/lib/model/grouping/common.dart +++ b/lib/model/grouping/common.dart @@ -1,10 +1,17 @@ +import 'dart:async'; import 'dart:convert'; +import 'package:aves/model/dynamic_albums.dart'; import 'package:aves/model/filters/container/album_group.dart'; +import 'package:aves/model/filters/container/dynamic_album.dart'; import 'package:aves/model/filters/container/group_base.dart'; import 'package:aves/model/filters/container/set_or.dart'; +import 'package:aves/model/filters/covered/stored_album.dart'; import 'package:aves/model/filters/filters.dart'; import 'package:aves/model/grouping/convert.dart'; +import 'package:aves/model/source/album.dart'; +import 'package:aves/model/source/collection_source.dart'; +import 'package:aves/model/source/events.dart'; import 'package:aves/services/common/services.dart'; import 'package:aves/utils/collection_utils.dart'; import 'package:collection/collection.dart'; @@ -28,18 +35,53 @@ class FilterGrouping with ChangeNotifier { final String _host; final T Function(Uri uri, SetOrFilter filter) _createGroupFilter; final Map> _groups = {}; + final Set _subscriptions = {}; + final Map> _sourceSubscriptions = {}; + CollectionSource? _source; Map> get allGroups => Map.unmodifiable(_groups); + // do not subscribe to events from other modules in constructor + // so that modules can subscribe to each other FilterGrouping._private(this._host, this._createGroupFilter) { if (kFlutterMemoryAllocationsEnabled) ChangeNotifier.maybeDispatchObjectCreation(this); } - void init(Map> groups) { + void init() { + _subscriptions.add(dynamicAlbums.eventBus.on().listen((e) => _clearObsoleteFilters())); + } + + void setGroups(Map> groups) { _groups.clear(); _groups.addAll(groups); } + @override + void dispose() { + _subscriptions + ..forEach((sub) => sub.cancel()) + ..clear(); + _sourceSubscriptions.keys.toSet().forEach(unregisterSource); + super.dispose(); + } + + void registerSource(CollectionSource source) { + unregisterSource(_source); + final sourceEvents = source.eventBus; + _sourceSubscriptions[source] = { + sourceEvents.on().listen((e) => _clearObsoleteFilters()), + sourceEvents.on().listen((e) => _clearObsoleteFilters()), + sourceEvents.on().listen((e) => _clearObsoleteFilters()), + }; + _source = source; + } + + void unregisterSource(CollectionSource? source) { + _sourceSubscriptions.remove(source) + ?..forEach((sub) => sub.cancel()) + ..clear(); + } + void addToGroup(Set childrenUris, Uri? destinationGroup) { _removeFromGroups(childrenUris); if (destinationGroup != null) { @@ -73,9 +115,9 @@ class FilterGrouping with ChangeNotifier { int countLeaves(Uri? groupUri) { int count = 0; if (groupUri != null) { - final childrenUri = _groups[groupUri]; - if (childrenUri != null) { - childrenUri.map(uriToFilter).nonNulls.forEach((filter) { + final childrenUris = _groups[groupUri]; + if (childrenUris != null) { + childrenUris.map(uriToFilter).nonNulls.forEach((filter) { if (filter is GroupBaseFilter) { count += countLeaves(filter.uri); } else { @@ -93,15 +135,15 @@ class FilterGrouping with ChangeNotifier { if (currentGroupUri == null) { return _groups.entries.where((kv) => getParentGroup(kv.key) == currentGroupUri).map((kv) { final groupUri = kv.key; - final childrenUri = kv.value; - final childrenFilters = childrenUri.map(uriToFilter).nonNulls.toSet(); + final childrenUris = kv.value; + final childrenFilters = childrenUris.map(uriToFilter).nonNulls.toSet(); return _createGroupFilter(groupUri, SetOrFilter(childrenFilters)); }).toSet(); } - final childrenUri = _groups.entries.firstWhereOrNull((kv) => kv.key == currentGroupUri)?.value; - if (childrenUri != null) { - return childrenUri.map(uriToFilter).nonNulls.toSet(); + final childrenUris = _groups.entries.firstWhereOrNull((kv) => kv.key == currentGroupUri)?.value; + if (childrenUris != null) { + return childrenUris.map(uriToFilter).nonNulls.toSet(); } return {}; @@ -172,6 +214,46 @@ class FilterGrouping with ChangeNotifier { } } + void _clearObsoleteFilters() { + final source = _source; + if (source == null || source.targetScope != CollectionSource.fullScope || !source.isReady) return; + + _groups.entries.forEach((kv) { + final groupUri = kv.key; + final childrenUris = kv.value; + + final rawAlbums = source.rawAlbums; + final allEntries = source.allEntries; + + childrenUris.toSet().forEach((childUri) { + final filter = uriToFilter(childUri); + var valid = false; + if (filter != null) { + switch (filter) { + case GroupBaseFilter _: + valid = true; + case StoredAlbumFilter _: + // check album itself + final isVisibleAlbum = rawAlbums.contains(filter.album); + if (isVisibleAlbum) { + valid = true; + } else { + // check non-visible content (hidden, trash, etc.) + valid = allEntries.any(filter.test); + } + case DynamicAlbumFilter _: + valid = dynamicAlbums.contains(filter.name); + } + } + if (!valid) { + childrenUris.remove(childUri); + debugPrint('Removed obsolete childUri=$childUri from group=$groupUri'); + } + }); + }); + _cleanEmptyGroups(); + } + // group uri / filter conversion static String? getGroupPath(Uri? uri) => uri?.queryParameters[_groupPathParamKey]; diff --git a/lib/model/settings/settings.dart b/lib/model/settings/settings.dart index 873900386..592e1768b 100644 --- a/lib/model/settings/settings.dart +++ b/lib/model/settings/settings.dart @@ -46,7 +46,7 @@ import 'package:latlong2/latlong.dart'; final Settings settings = Settings._private(); class Settings with ChangeNotifier, SettingsAccess, SearchSettings, AppSettings, CollectionSettings, DebugSettings, DisplaySettings, FilterGridsSettings, InfoSettings, NavigationSettings, PrivacySettings, ScreenSaverSettings, SlideshowSettings, SubtitlesSettings, VideoSettings, ViewerSettings, WidgetSettings { - final List _subscriptions = []; + final Set _subscriptions = {}; final EventChannel _platformSettingsChangeChannel = const OptionalEventChannel('deckers.thibault/aves/settings_change'); final StreamController _updateStreamController = StreamController.broadcast(); final StreamController _updateTileExtentStreamController = StreamController.broadcast(); diff --git a/lib/model/source/collection_lens.dart b/lib/model/source/collection_lens.dart index 97b29fc9d..f8be3a91d 100644 --- a/lib/model/source/collection_lens.dart +++ b/lib/model/source/collection_lens.dart @@ -34,7 +34,7 @@ class CollectionLens with ChangeNotifier { EntrySortFactor sortFactor; bool sortReverse; final AChangeNotifier filterChangeNotifier = AChangeNotifier(), sortSectionChangeNotifier = AChangeNotifier(); - final List _subscriptions = []; + final Set _subscriptions = {}; int? id; bool listenToSource, stackBursts, stackDevelopedRaws, fixedSort; List? fixedSelection; diff --git a/lib/model/source/media_store_source.dart b/lib/model/source/media_store_source.dart index eb53c729e..7d1f1f131 100644 --- a/lib/model/source/media_store_source.dart +++ b/lib/model/source/media_store_source.dart @@ -60,7 +60,9 @@ class MediaStoreSource extends CollectionSource { await localMediaDb.init(); await vaults.init(); await favourites.init(); - albumGrouping.init(settings.albumGroups); + albumGrouping.init(); + albumGrouping.setGroups(settings.albumGroups); + albumGrouping.registerSource(this); await covers.init(); await dynamicAlbums.init(); diff --git a/lib/model/vaults/vaults.dart b/lib/model/vaults/vaults.dart index 7f80c563a..c2bfd653a 100644 --- a/lib/model/vaults/vaults.dart +++ b/lib/model/vaults/vaults.dart @@ -15,7 +15,7 @@ import 'package:provider/provider.dart'; final Vaults vaults = Vaults._private(); class Vaults extends ChangeNotifier { - final List _subscriptions = []; + final Set _subscriptions = {}; Set _rows = {}; final Set _unlockedDirPaths = {}; diff --git a/lib/services/media/media_fetch_service.dart b/lib/services/media/media_fetch_service.dart index 4d1bb10b0..057f544aa 100644 --- a/lib/services/media/media_fetch_service.dart +++ b/lib/services/media/media_fetch_service.dart @@ -1,5 +1,6 @@ import 'dart:async'; import 'dart:math'; +import 'dart:ui' as ui; import 'package:aves/model/app/support.dart'; import 'package:aves/model/entry/entry.dart'; @@ -13,7 +14,6 @@ import 'package:equatable/equatable.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; import 'package:streams_channel/streams_channel.dart'; -import 'dart:ui' as ui; abstract class MediaFetchService { Future getEntry(String uri, String? mimeType, {bool allowUnsized = false}); diff --git a/lib/services/media/media_session_service.dart b/lib/services/media/media_session_service.dart index 8b970a7a6..33db933ac 100644 --- a/lib/services/media/media_session_service.dart +++ b/lib/services/media/media_session_service.dart @@ -25,7 +25,7 @@ abstract class MediaSessionService { class PlatformMediaSessionService implements MediaSessionService, Disposable { static const _platformObject = MethodChannel('deckers.thibault/aves/media_session'); - final List _subscriptions = []; + final Set _subscriptions = {}; final EventChannel _mediaCommandChannel = const OptionalEventChannel('deckers.thibault/aves/media_command'); final StreamController _streamController = StreamController.broadcast(); diff --git a/lib/services/window_service.dart b/lib/services/window_service.dart index f0a9b8087..341f5ad07 100644 --- a/lib/services/window_service.dart +++ b/lib/services/window_service.dart @@ -74,20 +74,24 @@ class PlatformWindowService implements WindowService { return false; } + // cf https://developer.android.com/guide/topics/manifest/activity-element#screen + // cf Android `ActivityInfo.ScreenOrientation` + static const screenOrientationUnspecified = -1; // SCREEN_ORIENTATION_UNSPECIFIED + // use the `USER` variants rather than the `SENSOR` ones, + // so that it does not flip even if it is reversed by sensor + static const screenOrientationUserLandscape = 11; // SCREEN_ORIENTATION_USER_LANDSCAPE + static const screenOrientationUserPortrait = 12; // SCREEN_ORIENTATION_USER_PORTRAIT + @override Future requestOrientation([Orientation? orientation]) async { - // cf Android `ActivityInfo.ScreenOrientation` late final int orientationCode; switch (orientation) { case Orientation.landscape: - // SCREEN_ORIENTATION_SENSOR_LANDSCAPE - orientationCode = 6; + orientationCode = screenOrientationUserLandscape; case Orientation.portrait: - // SCREEN_ORIENTATION_SENSOR_PORTRAIT - orientationCode = 7; + orientationCode = screenOrientationUserPortrait; default: - // SCREEN_ORIENTATION_UNSPECIFIED - orientationCode = -1; + orientationCode = screenOrientationUnspecified; } try { await _platform.invokeMethod('requestOrientation', { diff --git a/lib/theme/styles.dart b/lib/theme/styles.dart index bc679416d..94b0a21ac 100644 --- a/lib/theme/styles.dart +++ b/lib/theme/styles.dart @@ -1,4 +1,3 @@ - import 'package:flutter/painting.dart'; class AStyles { diff --git a/lib/widgets/aves_app.dart b/lib/widgets/aves_app.dart index 0c4b507d0..45e76d824 100644 --- a/lib/widgets/aves_app.dart +++ b/lib/widgets/aves_app.dart @@ -160,7 +160,7 @@ class AvesApp extends StatefulWidget { } class _AvesAppState extends State with WidgetsBindingObserver { - final List _subscriptions = []; + final Set _subscriptions = {}; late final Future _appSetup; late final Future _shouldUseBoldFontLoader; final TvRailController _tvRailController = TvRailController(); diff --git a/lib/widgets/collection/app_bar.dart b/lib/widgets/collection/app_bar.dart index f85689966..7cfa92611 100644 --- a/lib/widgets/collection/app_bar.dart +++ b/lib/widgets/collection/app_bar.dart @@ -4,9 +4,9 @@ import 'dart:math'; import 'package:aves/app_mode.dart'; import 'package:aves/model/entry/entry.dart'; import 'package:aves/model/filters/container/dynamic_album.dart'; +import 'package:aves/model/filters/container/set_and.dart'; import 'package:aves/model/filters/filters.dart'; import 'package:aves/model/filters/query.dart'; -import 'package:aves/model/filters/container/set_and.dart'; import 'package:aves/model/filters/trash.dart'; import 'package:aves/model/query.dart'; import 'package:aves/model/selection.dart'; @@ -57,7 +57,7 @@ class CollectionAppBar extends StatefulWidget { } class _CollectionAppBarState extends State with SingleTickerProviderStateMixin, WidgetsBindingObserver { - final List _subscriptions = []; + final Set _subscriptions = {}; final EntrySetActionDelegate _actionDelegate = EntrySetActionDelegate(); late AnimationController _browseToSelectAnimation; final ValueNotifier _isSelectingNotifier = ValueNotifier(false); diff --git a/lib/widgets/collection/collection_page.dart b/lib/widgets/collection/collection_page.dart index e2631b6bd..3d4d958f6 100644 --- a/lib/widgets/collection/collection_page.dart +++ b/lib/widgets/collection/collection_page.dart @@ -52,7 +52,7 @@ class CollectionPage extends StatefulWidget { } class _CollectionPageState extends State { - final List _subscriptions = []; + final Set _subscriptions = {}; late CollectionLens _collection; final StreamController _draggableScrollBarEventStreamController = StreamController.broadcast(); diff --git a/lib/widgets/collection/entry_set_action_delegate.dart b/lib/widgets/collection/entry_set_action_delegate.dart index 407f61315..53edf37fe 100644 --- a/lib/widgets/collection/entry_set_action_delegate.dart +++ b/lib/widgets/collection/entry_set_action_delegate.dart @@ -10,8 +10,8 @@ import 'package:aves/model/entry/extensions/multipage.dart'; import 'package:aves/model/entry/extensions/props.dart'; import 'package:aves/model/favourites.dart'; import 'package:aves/model/filters/container/dynamic_album.dart'; -import 'package:aves/model/filters/filters.dart'; import 'package:aves/model/filters/container/set_and.dart'; +import 'package:aves/model/filters/filters.dart'; import 'package:aves/model/grouping/common.dart'; import 'package:aves/model/highlight.dart'; import 'package:aves/model/metadata/date_modifier.dart'; diff --git a/lib/widgets/collection/filter_bar.dart b/lib/widgets/collection/filter_bar.dart index a88ff1be9..b565d7bc6 100644 --- a/lib/widgets/collection/filter_bar.dart +++ b/lib/widgets/collection/filter_bar.dart @@ -9,8 +9,8 @@ import 'package:provider/provider.dart'; class FilterBar extends StatefulWidget { static const EdgeInsets chipPadding = EdgeInsets.symmetric(horizontal: 4); static const EdgeInsets rowPadding = EdgeInsets.symmetric(horizontal: 4); - static const double verticalPadding = 16; - static const double preferredHeight = AvesFilterChip.minChipHeight + verticalPadding; + static const EdgeInsets padding = EdgeInsets.only(top: 4, bottom: 8); + static final double preferredHeight = AvesFilterChip.minChipHeight + padding.vertical; final List filters; final bool interactive; @@ -84,6 +84,7 @@ class _FilterBarState extends State { return Container( // specify transparent as a workaround to prevent // chip border clipping when the floating app bar is fading + padding: FilterBar.padding, color: Colors.transparent, height: FilterBar.preferredHeight, child: AnimatedList( diff --git a/lib/widgets/common/action_controls/quick_choosers/common/menu.dart b/lib/widgets/common/action_controls/quick_choosers/common/menu.dart index a70fbee60..68660854f 100644 --- a/lib/widgets/common/action_controls/quick_choosers/common/menu.dart +++ b/lib/widgets/common/action_controls/quick_choosers/common/menu.dart @@ -45,7 +45,7 @@ class MenuQuickChooser extends StatefulWidget { } class _MenuQuickChooserState extends State> { - final List _subscriptions = []; + final Set _subscriptions = {}; final ValueNotifier _selectedRowRect = ValueNotifier(Rect.zero); final ScrollController _scrollController = ScrollController(); int _scrollDirection = 0; diff --git a/lib/widgets/common/action_controls/quick_choosers/rate_chooser.dart b/lib/widgets/common/action_controls/quick_choosers/rate_chooser.dart index cdb857522..687d4ea65 100644 --- a/lib/widgets/common/action_controls/quick_choosers/rate_chooser.dart +++ b/lib/widgets/common/action_controls/quick_choosers/rate_chooser.dart @@ -23,7 +23,7 @@ class RateQuickChooser extends StatefulWidget { } class _RateQuickChooserState extends State { - final List _subscriptions = []; + final Set _subscriptions = {}; ValueNotifier get valueNotifier => widget.valueNotifier; diff --git a/lib/widgets/common/action_controls/togglers/play.dart b/lib/widgets/common/action_controls/togglers/play.dart index 9e76d2d13..67c5a5bf6 100644 --- a/lib/widgets/common/action_controls/togglers/play.dart +++ b/lib/widgets/common/action_controls/togglers/play.dart @@ -28,7 +28,7 @@ class PlayToggler extends StatefulWidget { } class _PlayTogglerState extends State with SingleTickerProviderStateMixin { - final List _subscriptions = []; + final Set _subscriptions = {}; late AnimationController _playPauseAnimation; AvesVideoController? get controller => widget.controller; diff --git a/lib/widgets/common/app_bar/app_bar_subtitle.dart b/lib/widgets/common/app_bar/app_bar_subtitle.dart index 5a30727e9..4eb44ee5b 100644 --- a/lib/widgets/common/app_bar/app_bar_subtitle.dart +++ b/lib/widgets/common/app_bar/app_bar_subtitle.dart @@ -1,4 +1,3 @@ - import 'package:aves/model/source/collection_source.dart'; import 'package:aves/model/source/events.dart'; import 'package:aves/theme/durations.dart'; diff --git a/lib/widgets/common/app_bar/crumb_line.dart b/lib/widgets/common/app_bar/crumb_line.dart index 4ad8e3414..580f1ecd0 100644 --- a/lib/widgets/common/app_bar/crumb_line.dart +++ b/lib/widgets/common/app_bar/crumb_line.dart @@ -8,6 +8,8 @@ class CrumbLine extends StatefulWidget { final T Function(BuildContext context, int index) combine; final void Function(T combined) onTap; + static const EdgeInsets padding = EdgeInsets.only(top: 6, bottom: 20); + const CrumbLine({ super.key, required this.split, @@ -18,7 +20,7 @@ class CrumbLine extends StatefulWidget { @override State> createState() => _CrumbLineState(); - static double getPreferredHeight(TextScaler textScaler) => textScaler.scale(kToolbarHeight); + static double getPreferredHeight(TextScaler textScaler) => textScaler.scale(22) + padding.vertical; } class _CrumbLineState extends State> { diff --git a/lib/widgets/common/basic/gestures/ink_well.dart b/lib/widgets/common/basic/gestures/ink_well.dart index ffc21b4cc..1c3c8546e 100644 --- a/lib/widgets/common/basic/gestures/ink_well.dart +++ b/lib/widgets/common/basic/gestures/ink_well.dart @@ -522,7 +522,7 @@ class _InkResponseStateWidget extends StatefulWidget { if (onSecondaryTap != null) 'secondary tap', if (onSecondaryTapUp != null) 'secondary tap up', if (onSecondaryTapDown != null) 'secondary tap down', - if (onSecondaryTapCancel != null) 'secondary tap cancel' + if (onSecondaryTapCancel != null) 'secondary tap cancel', ]; properties.add(IterableProperty('gestures', gestures, ifEmpty: '')); properties.add(DiagnosticsProperty('mouseCursor', mouseCursor)); @@ -544,10 +544,7 @@ enum _HighlightType { focus, } -class _InkResponseState extends State<_InkResponseStateWidget> - with AutomaticKeepAliveClientMixin<_InkResponseStateWidget> - implements _ParentInkResponseState -{ +class _InkResponseState extends State<_InkResponseStateWidget> with AutomaticKeepAliveClientMixin<_InkResponseStateWidget> implements _ParentInkResponseState { Set? _splashes; InteractiveInkFeature? _currentSplash; bool _hovering = false; @@ -578,6 +575,7 @@ class _InkResponseState extends State<_InkResponseStateWidget> widget.parentState?.markChildInkResponsePressed(this, nowAnyPressed); } } + bool get _anyChildInkResponsePressed => _activeChildren.isNotEmpty; void activateOnIntent(Intent? intent) { @@ -611,7 +609,7 @@ class _InkResponseState extends State<_InkResponseStateWidget> void handleStatesControllerChange() { // Force a rebuild to resolve widget.overlayColor, widget.mouseCursor - setState(() { }); + setState(() {}); } WidgetStatesController get statesController => widget.statesController ?? internalStatesController!; @@ -642,9 +640,7 @@ class _InkResponseState extends State<_InkResponseStateWidget> } initStatesController(); } - if (widget.radius != oldWidget.radius || - widget.highlightShape != oldWidget.highlightShape || - widget.borderRadius != oldWidget.borderRadius) { + if (widget.radius != oldWidget.radius || widget.highlightShape != oldWidget.highlightShape || widget.borderRadius != oldWidget.borderRadius) { final InkHighlight? hoverHighlight = _highlights[_HighlightType.hover]; if (hoverHighlight != null) { hoverHighlight.dispose(); @@ -701,7 +697,7 @@ class _InkResponseState extends State<_InkResponseStateWidget> } } - void updateHighlight(_HighlightType type, { required bool value, bool callOnHover = true }) { + void updateHighlight(_HighlightType type, {required bool value, bool callOnHover = true}) { final InkHighlight? highlight = _highlights[type]; void handleInkRemoval() { assert(_highlights[type] != null); @@ -717,7 +713,7 @@ class _InkResponseState extends State<_InkResponseStateWidget> statesController.update(WidgetState.hovered, value); } case _HighlightType.focus: - // see handleFocusUpdate() + // see handleFocusUpdate() break; } @@ -730,9 +726,9 @@ class _InkResponseState extends State<_InkResponseStateWidget> if (value) { if (highlight == null) { - final Color resolvedOverlayColor = widget.overlayColor?.resolve(statesController.value) - ?? switch (type) { - // Use the backwards compatible defaults + final Color resolvedOverlayColor = widget.overlayColor?.resolve(statesController.value) ?? + switch (type) { + // Use the backwards compatible defaults _HighlightType.pressed => widget.highlightColor ?? Theme.of(context).highlightColor, _HighlightType.focus => widget.focusColor ?? Theme.of(context).focusColor, _HighlightType.hover => widget.hoverColor ?? Theme.of(context).hoverColor, @@ -789,7 +785,7 @@ class _InkResponseState extends State<_InkResponseStateWidget> final MaterialInkController inkController = Material.of(context); final RenderBox referenceBox = context.findRenderObject()! as RenderBox; final Offset position = referenceBox.globalToLocal(globalPosition); - final Color color = widget.overlayColor?.resolve(statesController.value) ?? widget.splashColor ?? Theme.of(context).splashColor; + final Color color = widget.overlayColor?.resolve(statesController.value) ?? widget.splashColor ?? Theme.of(context).splashColor; final RectCallback? rectCallback = widget.containedInkWell ? widget.getRectCallback!(referenceBox) : null; final BorderRadius? borderRadius = widget.borderRadius; final ShapeBorder? customBorder = widget.customBorder; @@ -846,6 +842,7 @@ class _InkResponseState extends State<_InkResponseStateWidget> } bool _hasFocus = false; + void handleFocusUpdate(bool hasFocus) { _hasFocus = hasFocus; // Set here rather than updateHighlight because this widget's @@ -978,21 +975,17 @@ class _InkResponseState extends State<_InkResponseStateWidget> } bool _primaryButtonEnabled(_InkResponseStateWidget widget) { - return widget.onTap != null - || widget.onDoubleTap != null - || widget.onLongPress != null - || widget.onTapUp != null - || widget.onTapDown != null; + return widget.onTap != null || widget.onDoubleTap != null || widget.onLongPress != null || widget.onTapUp != null || widget.onTapDown != null; } bool _secondaryButtonEnabled(_InkResponseStateWidget widget) { - return widget.onSecondaryTap != null - || widget.onSecondaryTapUp != null - || widget.onSecondaryTapDown != null; + return widget.onSecondaryTap != null || widget.onSecondaryTapUp != null || widget.onSecondaryTapDown != null; } bool get enabled => isWidgetEnabled(widget); + bool get _primaryEnabled => _primaryButtonEnabled(widget); + bool get _secondaryEnabled => _secondaryButtonEnabled(widget); void handleMouseEnter(PointerEnterEvent event) { @@ -1032,14 +1025,15 @@ class _InkResponseState extends State<_InkResponseStateWidget> final ThemeData theme = Theme.of(context); return switch (type) { - // The pressed state triggers a ripple (ink splash), per the current - // Material Design spec. A separate highlight is no longer used. - // See https://material.io/design/interaction/states.html#pressed + // The pressed state triggers a ripple (ink splash), per the current + // Material Design spec. A separate highlight is no longer used. + // See https://material.io/design/interaction/states.html#pressed _HighlightType.pressed => widget.overlayColor?.resolve(pressed) ?? widget.highlightColor ?? theme.highlightColor, - _HighlightType.focus => widget.overlayColor?.resolve(focused) ?? widget.focusColor ?? theme.focusColor, - _HighlightType.hover => widget.overlayColor?.resolve(hovered) ?? widget.hoverColor ?? theme.hoverColor, + _HighlightType.focus => widget.overlayColor?.resolve(focused) ?? widget.focusColor ?? theme.focusColor, + _HighlightType.hover => widget.overlayColor?.resolve(hovered) ?? widget.hoverColor ?? theme.hoverColor, }; } + for (final _HighlightType type in _highlights.keys) { _highlights[type]?.color = getHighlightColorForType(type); } @@ -1077,7 +1071,7 @@ class _InkResponseState extends State<_InkResponseStateWidget> onDoubleTap: widget.onDoubleTap != null ? handleDoubleTap : null, onLongPress: widget.onLongPress != null ? handleLongPress : null, onSecondaryTapDown: _secondaryEnabled ? handleSecondaryTapDown : null, - onSecondaryTapUp: _secondaryEnabled ? handleSecondaryTapUp: null, + onSecondaryTapUp: _secondaryEnabled ? handleSecondaryTapUp : null, onSecondaryTap: _secondaryEnabled ? handleSecondaryTap : null, onSecondaryTapCancel: _secondaryEnabled ? handleSecondaryTapCancel : null, behavior: HitTestBehavior.opaque, diff --git a/lib/widgets/common/basic/markdown_container.dart b/lib/widgets/common/basic/markdown_container.dart index de44dcd4f..391b34a95 100644 --- a/lib/widgets/common/basic/markdown_container.dart +++ b/lib/widgets/common/basic/markdown_container.dart @@ -3,7 +3,7 @@ import 'package:aves/theme/themes.dart'; import 'package:aves/widgets/aves_app.dart'; import 'package:aves/widgets/common/fx/borders.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_markdown/flutter_markdown.dart'; +import 'package:flutter_markdown_plus/flutter_markdown_plus.dart'; class MarkdownContainer extends StatelessWidget { final String data; diff --git a/lib/widgets/common/fx/blurred.dart b/lib/widgets/common/fx/blurred.dart index 796188fa7..f1e41390e 100644 --- a/lib/widgets/common/fx/blurred.dart +++ b/lib/widgets/common/fx/blurred.dart @@ -20,7 +20,8 @@ class BlurredRect extends StatelessWidget { @override Widget build(BuildContext context) { return ClipRect( - child: BackdropFilter.grouped( + // TODO TLAD [flutter vNext] use `BackdropFilter.grouped` + child: BackdropFilter( // do not modify tree when disabling filter filter: enabled ? _filter : _identity, child: child, @@ -59,7 +60,8 @@ class BlurredRRect extends StatelessWidget { Widget build(BuildContext context) { return ClipRRect( borderRadius: borderRadius ?? BorderRadius.zero, - child: BackdropFilter.grouped( + // TODO TLAD [flutter vNext] use `BackdropFilter.grouped` + child: BackdropFilter( // do not modify tree when disabling filter filter: enabled ? _filter : _identity, child: child, @@ -81,7 +83,8 @@ class BlurredOval extends StatelessWidget { @override Widget build(BuildContext context) { return ClipOval( - child: BackdropFilter.grouped( + // TODO TLAD [flutter vNext] use `BackdropFilter.grouped` + child: BackdropFilter( // do not modify tree when disabling filter filter: enabled ? _filter : _identity, child: child, diff --git a/lib/widgets/common/grid/item_tracker.dart b/lib/widgets/common/grid/item_tracker.dart index 52048a563..ea8aadf68 100644 --- a/lib/widgets/common/grid/item_tracker.dart +++ b/lib/widgets/common/grid/item_tracker.dart @@ -44,7 +44,7 @@ class _GridItemTrackerState extends State> with WidgetsBin return (scrollableContext.findRenderObject() as RenderBox).size; } - final List _subscriptions = []; + final Set _subscriptions = {}; // grid section metrics before the app is laid out with the new orientation late SectionedListLayout _lastSectionedListLayout; diff --git a/lib/widgets/common/grid/sliver.dart b/lib/widgets/common/grid/sliver.dart index 299e70134..3d7ed7502 100644 --- a/lib/widgets/common/grid/sliver.dart +++ b/lib/widgets/common/grid/sliver.dart @@ -71,7 +71,7 @@ class _RenderSliverKnownExtentBoxAdaptor extends RenderSliverMultiBoxAdaptor { _RenderSliverKnownExtentBoxAdaptor({ required super.childManager, required List sectionLayouts, - }) : _sectionLayouts = sectionLayouts; + }) : _sectionLayouts = sectionLayouts; SectionLayout? sectionAtIndex(int index) => sectionLayouts.firstWhereOrNull((section) => section.hasChild(index)); diff --git a/lib/widgets/common/identity/aves_filter_chip.dart b/lib/widgets/common/identity/aves_filter_chip.dart index 163017c57..1bbe9f22a 100644 --- a/lib/widgets/common/identity/aves_filter_chip.dart +++ b/lib/widgets/common/identity/aves_filter_chip.dart @@ -150,7 +150,7 @@ class AvesFilterChip extends StatefulWidget { } class _AvesFilterChipState extends State { - final List _subscriptions = []; + final Set _subscriptions = {}; late Future _colorFuture; late Color _outlineColor; late bool _tapped; diff --git a/lib/widgets/common/map/attribution.dart b/lib/widgets/common/map/attribution.dart index bfe8c7aee..f1cd7b023 100644 --- a/lib/widgets/common/map/attribution.dart +++ b/lib/widgets/common/map/attribution.dart @@ -5,7 +5,7 @@ import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/viewer/info/common.dart'; import 'package:aves_map/aves_map.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_markdown/flutter_markdown.dart'; +import 'package:flutter_markdown_plus/flutter_markdown_plus.dart'; import 'package:provider/provider.dart'; class Attribution extends StatelessWidget { diff --git a/lib/widgets/common/map/geo_map.dart b/lib/widgets/common/map/geo_map.dart index b8a43c7aa..c19aab548 100644 --- a/lib/widgets/common/map/geo_map.dart +++ b/lib/widgets/common/map/geo_map.dart @@ -83,7 +83,7 @@ class GeoMap extends StatefulWidget { } class _GeoMapState extends State { - final List _subscriptions = []; + final Set _subscriptions = {}; // as of google_maps_flutter v2.0.6, Google map initialization is blocking // cf https://github.com/flutter/flutter/issues/28493 @@ -249,14 +249,13 @@ class _GeoMapState extends State { child = Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - BackdropGroup( - child: mapHeight != null - ? SizedBox( - height: mapHeight, - child: child, - ) - : Expanded(child: child), - ), + // TODO TLAD [flutter vNext] wrap into `BackdropGroup` + mapHeight != null + ? SizedBox( + height: mapHeight, + child: child, + ) + : Expanded(child: child), SafeArea( top: false, bottom: false, diff --git a/lib/widgets/common/map/leaflet/map.dart b/lib/widgets/common/map/leaflet/map.dart index 39ee02248..829476be7 100644 --- a/lib/widgets/common/map/leaflet/map.dart +++ b/lib/widgets/common/map/leaflet/map.dart @@ -66,7 +66,7 @@ class EntryLeafletMap extends StatefulWidget { class _EntryLeafletMapState extends State> with TickerProviderStateMixin { final MapController _leafletMapController = MapController(); - final List _subscriptions = []; + final Set _subscriptions = {}; Map, GeoEntry> _geoEntryByMarkerKey = {}; final Debouncer _debouncer = Debouncer(delay: ADurations.mapIdleDebounceDelay); diff --git a/lib/widgets/common/search/delegate.dart b/lib/widgets/common/search/delegate.dart index da4176455..e48a21f5b 100644 --- a/lib/widgets/common/search/delegate.dart +++ b/lib/widgets/common/search/delegate.dart @@ -43,10 +43,12 @@ abstract class AvesSearchDelegate extends SearchDelegate { final animate = context.read().animate; return canPop ? IconButton( - icon: animate ? AnimatedIcon( - icon: AnimatedIcons.menu_arrow, - progress: transitionAnimation, - ): const Icon(Icons.arrow_back), + icon: animate + ? AnimatedIcon( + icon: AnimatedIcons.menu_arrow, + progress: transitionAnimation, + ) + : const Icon(Icons.arrow_back), onPressed: () => goBack(context), tooltip: MaterialLocalizations.of(context).backButtonTooltip, ) diff --git a/lib/widgets/common/tile_extent_controller.dart b/lib/widgets/common/tile_extent_controller.dart index f328f12a4..bf4567d02 100644 --- a/lib/widgets/common/tile_extent_controller.dart +++ b/lib/widgets/common/tile_extent_controller.dart @@ -15,7 +15,7 @@ class TileExtentController { late double userPreferredExtent; Size _viewportSize = Size.zero; - final List _subscriptions = []; + final Set _subscriptions = {}; Size get viewportSize => _viewportSize; diff --git a/lib/widgets/dialogs/entry_editors/edit_location_dialog.dart b/lib/widgets/dialogs/entry_editors/edit_location_dialog.dart index fbdbef1d1..a133210ae 100644 --- a/lib/widgets/dialogs/entry_editors/edit_location_dialog.dart +++ b/lib/widgets/dialogs/entry_editors/edit_location_dialog.dart @@ -56,7 +56,7 @@ class EditEntryLocationDialog extends StatefulWidget { } class _EditEntryLocationDialogState extends State with FeedbackMixin { - final List _subscriptions = []; + final Set _subscriptions = {}; LocationEditAction _action = LocationEditAction.chooseOnMap; LatLng? _mapCoordinates; late final AvesEntry mainEntry; diff --git a/lib/widgets/dialogs/pick_dialogs/location_pick_page.dart b/lib/widgets/dialogs/pick_dialogs/location_pick_page.dart index 217e2b282..ca2fa32b2 100644 --- a/lib/widgets/dialogs/pick_dialogs/location_pick_page.dart +++ b/lib/widgets/dialogs/pick_dialogs/location_pick_page.dart @@ -63,7 +63,7 @@ class _Content extends StatefulWidget { } class _ContentState extends State<_Content> with SingleTickerProviderStateMixin { - final List _subscriptions = []; + final Set _subscriptions = {}; final AvesMapController _mapController = AvesMapController(); late final ValueNotifier _isPageAnimatingNotifier; final ValueNotifier _dotLocationNotifier = ValueNotifier(null), _infoLocationNotifier = ValueNotifier(null); diff --git a/lib/widgets/editor/entry_editor_page.dart b/lib/widgets/editor/entry_editor_page.dart index c8cba2b81..87eca7848 100644 --- a/lib/widgets/editor/entry_editor_page.dart +++ b/lib/widgets/editor/entry_editor_page.dart @@ -28,7 +28,7 @@ class ImageEditorPage extends StatefulWidget { } class _ImageEditorPageState extends State { - final List _subscriptions = []; + final Set _subscriptions = {}; final ValueNotifier _actionNotifier = ValueNotifier(null); final ValueNotifier _marginNotifier = ValueNotifier(EdgeInsets.zero); final ValueNotifier _viewStateNotifier = ValueNotifier(ViewState.zero); @@ -118,7 +118,7 @@ class _ImageEditorPageState extends State { } void _onActionChanged() { - switch(_actionNotifier.value) { + switch (_actionNotifier.value) { case EditorAction.transform: _transformController.reset(); _marginNotifier.value = Cropper.imageMargin; diff --git a/lib/widgets/editor/image.dart b/lib/widgets/editor/image.dart index ce5836c84..df6213591 100644 --- a/lib/widgets/editor/image.dart +++ b/lib/widgets/editor/image.dart @@ -36,7 +36,7 @@ class EditorImage extends StatefulWidget { } class _EditorImageState extends State { - final List _subscriptions = []; + final Set _subscriptions = {}; final ValueNotifier _scrimOpacityNotifier = ValueNotifier(0); AvesEntry get entry => widget.entry; diff --git a/lib/widgets/editor/transform/cropper.dart b/lib/widgets/editor/transform/cropper.dart index a160ef408..1c37f85bc 100644 --- a/lib/widgets/editor/transform/cropper.dart +++ b/lib/widgets/editor/transform/cropper.dart @@ -38,7 +38,7 @@ class Cropper extends StatefulWidget { } class _CropperState extends State with SingleTickerProviderStateMixin { - final List _subscriptions = []; + final Set _subscriptions = {}; final ValueNotifier _outlineNotifier = ValueNotifier(Rect.zero); final ValueNotifier _gridDivisionNotifier = ValueNotifier(0); late AnimationController _gridAnimationController; diff --git a/lib/widgets/explorer/app_bar.dart b/lib/widgets/explorer/app_bar.dart index 7ee7e14a5..dc43f661f 100644 --- a/lib/widgets/explorer/app_bar.dart +++ b/lib/widgets/explorer/app_bar.dart @@ -65,7 +65,8 @@ class _ExplorerAppBarState extends State with WidgetsBindingObse actions: _buildActions, bottom: LayoutBuilder( builder: (context, constraints) { - return SizedBox( + return Container( + padding: CrumbLine.padding, width: constraints.maxWidth, height: CrumbLine.getPreferredHeight(MediaQuery.textScalerOf(context)), child: ValueListenableBuilder( diff --git a/lib/widgets/explorer/explorer_page.dart b/lib/widgets/explorer/explorer_page.dart index cadf2e5f5..749f1a0e8 100644 --- a/lib/widgets/explorer/explorer_page.dart +++ b/lib/widgets/explorer/explorer_page.dart @@ -40,7 +40,7 @@ class ExplorerPage extends StatefulWidget { } class _ExplorerPageState extends State { - final List _subscriptions = []; + final Set _subscriptions = {}; final ValueNotifier _directory = ValueNotifier(null); final ValueNotifier _contentsDirectory = ValueNotifier(null); final ValueNotifier> _contents = ValueNotifier([]); diff --git a/lib/widgets/filter_grids/albums_page.dart b/lib/widgets/filter_grids/albums_page.dart index 01ceee68c..b7d1f96a9 100644 --- a/lib/widgets/filter_grids/albums_page.dart +++ b/lib/widgets/filter_grids/albums_page.dart @@ -44,12 +44,12 @@ class AlbumListPage extends StatelessWidget { child: Builder( // to access filter group provider from subtree context builder: (context) { - return Selector)>( - selector: (context, s) => (s.albumSectionFactor, s.albumSortFactor, s.albumSortReverse, s.pinnedFilters), + return Selector, Set)>( + selector: (context, s) => (s.albumSectionFactor, s.albumSortFactor, s.albumSortReverse, s.hiddenFilters, s.pinnedFilters), shouldRebuild: (t1, t2) { // `Selector` by default uses `DeepCollectionEquality`, which does not go deep in collections within records const eq = DeepCollectionEquality(); - return !(eq.equals(t1.$1, t2.$1) && eq.equals(t1.$2, t2.$2) && eq.equals(t1.$3, t2.$3) && eq.equals(t1.$4, t2.$4)); + return !(eq.equals(t1.$1, t2.$1) && eq.equals(t1.$2, t2.$2) && eq.equals(t1.$3, t2.$3) && eq.equals(t1.$4, t2.$4) && eq.equals(t1.$5, t2.$5)); }, builder: (context, s, child) { return ValueListenableBuilder( @@ -123,7 +123,7 @@ class AlbumListPage extends StatelessWidget { final listedDynamicAlbums = {}; if (albumChipTypes.contains(AlbumChipType.dynamic)) { - final allDynamicAlbums = dynamicAlbums.all; + final allDynamicAlbums = dynamicAlbums.all.whereNot(settings.hiddenFilters.contains).toSet(); if (groupUri == null) { final withinGroups = whereTypeRecursively(groupContent).toSet(); listedDynamicAlbums.addAll(allDynamicAlbums.whereNot(withinGroups.contains)); @@ -134,7 +134,7 @@ class AlbumListPage extends StatelessWidget { } // always show groups, which are needed to navigate to other types - final albumGroupFilters = groupContent.whereType().toSet(); + final albumGroupFilters = groupContent.whereType().whereNot(settings.hiddenFilters.contains).toSet(); final filters = { ...albumGroupFilters, diff --git a/lib/widgets/filter_grids/common/app_bar.dart b/lib/widgets/filter_grids/common/app_bar.dart index 322e8fe1d..680ab82bc 100644 --- a/lib/widgets/filter_grids/common/app_bar.dart +++ b/lib/widgets/filter_grids/common/app_bar.dart @@ -79,7 +79,7 @@ class FilterGridAppBar> extends State> with SingleTickerProviderStateMixin, WidgetsBindingObserver { - final List _subscriptions = []; + final Set _subscriptions = {}; late AnimationController _browseToSelectAnimation; final ValueNotifier _isSelectingNotifier = ValueNotifier(false); final FocusNode _queryBarFocusNode = FocusNode(); @@ -170,7 +170,8 @@ class _FilterGridAppBarState( diff --git a/lib/widgets/filter_grids/common/covered_filter_chip.dart b/lib/widgets/filter_grids/common/covered_filter_chip.dart index 83058c16d..13c74802e 100644 --- a/lib/widgets/filter_grids/common/covered_filter_chip.dart +++ b/lib/widgets/filter_grids/common/covered_filter_chip.dart @@ -61,9 +61,13 @@ class CoveredFilterChip extends StatelessWidget { static Radius radius(double extent) => Radius.circular(min(AvesFilterChip.defaultRadius, extent / 4)); - static double detailIconSize(double extent) => min(AvesFilterChip.fontSize, extent / 8); + static double detailIconSize(double extent) => min(AvesFilterChip.fontSize, extent / 7); - static double detailFontSize(double extent) => min(AvesFilterChip.fontSize, extent / 6); + static double detailFontSize(double extent) => min(AvesFilterChip.fontSize, extent / 7); + + static double detailIconPadding(double extent) => min(8.0, extent / 16); + + static double detailIconTextPadding(double extent) => detailIconPadding(extent) / 2; @override Widget build(BuildContext context) { @@ -201,30 +205,33 @@ class CoveredFilterChip extends StatelessWidget { if (filter is StoredAlbumFilter && vaults.isVault(filter.album)) _buildDetailIcon(context, AIcons.locked), if (filter is DynamicAlbumFilter) _buildDetailIcon(context, AIcons.dynamicAlbum), if (filter is AlbumGroupFilter) ...[ - _buildDetailIcon(context, AIcons.album), + _buildDetailIcon(context, AIcons.album, padding: detailIconTextPadding(extent)), Text( '${NumberFormat.decimalPattern(context.locale).format(albumGrouping.countLeaves(filter.uri))}${AText.separator}', style: textStyle, ), ], - Text( - locked ? AText.valueNotAvailable : NumberFormat.decimalPattern(context.locale).format(source.count(filter)), - style: textStyle, + Flexible( + child: Text( + locked ? AText.valueNotAvailable : NumberFormat.decimalPattern(context.locale).format(source.count(filter)), + style: textStyle, + softWrap: false, + overflow: TextOverflow.fade, + maxLines: 1, + ), ), ], ); } - Widget _buildDetailIcon(BuildContext context, IconData icon) { - final padding = min(8.0, extent / 16); - final iconSize = detailIconSize(extent); + Widget _buildDetailIcon(BuildContext context, IconData icon, {double? padding}) { return AnimatedPadding( - padding: EdgeInsetsDirectional.only(end: padding), + padding: EdgeInsetsDirectional.only(end: padding ?? detailIconPadding(extent)), duration: ADurations.chipDecorationAnimation, child: Icon( icon, color: _detailColor(context), - size: iconSize, + size: detailIconSize(extent), ), ); } diff --git a/lib/widgets/home/home_page.dart b/lib/widgets/home/home_page.dart index 98c353fa2..12ee7e758 100644 --- a/lib/widgets/home/home_page.dart +++ b/lib/widgets/home/home_page.dart @@ -304,9 +304,6 @@ class _HomePageState extends State { String routeName; Set? filters; switch (appMode) { - case AppMode.pickSingleMediaExternal: - case AppMode.pickMultipleMediaExternal: - routeName = CollectionPage.routeName; case AppMode.setWallpaper: return DirectMaterialPageRoute( settings: const RouteSettings(name: WallpaperPage.routeName), @@ -374,7 +371,17 @@ class _HomePageState extends State { ); }, ); - default: + case AppMode.initialization: + case AppMode.main: + case AppMode.pickCollectionFiltersExternal: + case AppMode.pickSingleMediaExternal: + case AppMode.pickMultipleMediaExternal: + case AppMode.pickFilteredMediaInternal: + case AppMode.pickUnfilteredMediaInternal: + case AppMode.pickFilterInternal: + case AppMode.previewMap: + case AppMode.screenSaver: + case AppMode.slideshow: routeName = _initialRouteName ?? settings.homePage.routeName; filters = _initialFilters ?? (settings.homePage == HomePageSetting.collection ? settings.homeCustomCollection : {}); } diff --git a/lib/widgets/map/map_page.dart b/lib/widgets/map/map_page.dart index 0131ea2b4..83bca4a6b 100644 --- a/lib/widgets/map/map_page.dart +++ b/lib/widgets/map/map_page.dart @@ -115,7 +115,7 @@ class _Content extends StatefulWidget { } class _ContentState extends State<_Content> with SingleTickerProviderStateMixin { - final List _subscriptions = []; + final Set _subscriptions = {}; final AvesMapController _mapController = AvesMapController(); final ValueNotifier _isPageAnimatingNotifier = ValueNotifier(false); final ValueNotifier _selectedIndexNotifier = ValueNotifier(0); diff --git a/lib/widgets/navigation/nav_bar/floating.dart b/lib/widgets/navigation/nav_bar/floating.dart index 63ffb53a4..da0e7d51b 100644 --- a/lib/widgets/navigation/nav_bar/floating.dart +++ b/lib/widgets/navigation/nav_bar/floating.dart @@ -23,7 +23,7 @@ class FloatingNavBar extends StatefulWidget { } class _FloatingNavBarState extends State with SingleTickerProviderStateMixin { - final List _subscriptions = []; + final Set _subscriptions = {}; late AnimationController _controller; late CurvedAnimation _animation; late Animation _offset; diff --git a/lib/widgets/settings/app_export/items.dart b/lib/widgets/settings/app_export/items.dart index 2a69b82c9..a77f690c9 100644 --- a/lib/widgets/settings/app_export/items.dart +++ b/lib/widgets/settings/app_export/items.dart @@ -39,7 +39,7 @@ extension ExtraAppExportItem on AppExportItem { favourites.import(jsonMap, source); case AppExportItem.settings: await settings.import(jsonMap); - albumGrouping.init(settings.albumGroups); + albumGrouping.setGroups(settings.albumGroups); } } } diff --git a/lib/widgets/settings/language/language.dart b/lib/widgets/settings/language/language.dart index b0e6730b1..3bba84db9 100644 --- a/lib/widgets/settings/language/language.dart +++ b/lib/widgets/settings/language/language.dart @@ -82,8 +82,8 @@ class SettingsTileLanguageNumerals extends SettingsTile { @override Widget build(BuildContext context) => SettingsSwitchListTile( - selector: (context, s) => s.forceWesternArabicNumerals, - onChanged: (v) => settings.forceWesternArabicNumerals = v, - title: title(context), - ); + selector: (context, s) => s.forceWesternArabicNumerals, + onChanged: (v) => settings.forceWesternArabicNumerals = v, + title: title(context), + ); } diff --git a/lib/widgets/viewer/entry_vertical_pager.dart b/lib/widgets/viewer/entry_vertical_pager.dart index 8f32956cb..61ec662c2 100644 --- a/lib/widgets/viewer/entry_vertical_pager.dart +++ b/lib/widgets/viewer/entry_vertical_pager.dart @@ -64,7 +64,7 @@ class ViewerVerticalPageView extends StatefulWidget { } class _ViewerVerticalPageViewState extends State { - final List _subscriptions = []; + final Set _subscriptions = {}; final ValueNotifier _backgroundOpacityNotifier = ValueNotifier(1); final ValueNotifier _isVerticallyScrollingNotifier = ValueNotifier(false); final ValueNotifier _isImageFocusedNotifier = ValueNotifier(true); diff --git a/lib/widgets/viewer/entry_viewer_stack.dart b/lib/widgets/viewer/entry_viewer_stack.dart index b5fe46efd..b9e17d973 100644 --- a/lib/widgets/viewer/entry_viewer_stack.dart +++ b/lib/widgets/viewer/entry_viewer_stack.dart @@ -261,29 +261,35 @@ class _EntryViewerStackState extends State with EntryViewContr return ValueListenableBuilder( valueListenable: _viewLocked, builder: (context, locked, child) { - return BackdropGroup( - child: Stack( - children: [ - child!, - if (!pipEnabled) ...[ - if (locked) ...[ - const Positioned.fill( - child: AbsorbPointer(), - ), - Positioned.fill( - child: GestureDetector( - onTap: () => _overlayVisible.value = !_overlayVisible.value, - ), - ), - _buildViewerLockedBottomOverlay(), - ] else - ..._buildOverlays(availableSize).map(_decorateOverlay), - const TopGestureAreaProtector(), - const SideGestureAreaProtector(), - const BottomGestureAreaProtector(), - ], - ], - ), + final children = [child!]; + if (!pipEnabled) { + if (locked) { + children.addAll([ + const Positioned.fill( + child: AbsorbPointer(), + ), + Positioned.fill( + child: GestureDetector( + onTap: () => _overlayVisible.value = !_overlayVisible.value, + ), + ), + _buildViewerLockedBottomOverlay(), + ]); + } else { + // regular overlay + children.addAll(_buildOverlays(availableSize).map(_decorateOverlay)); + } + + children.addAll([ + const TopGestureAreaProtector(), + const SideGestureAreaProtector(), + const BottomGestureAreaProtector(), + ]); + } + + // TODO TLAD [flutter vNext] wrap into `BackdropGroup` + return Stack( + children: children, ); }, child: viewer, diff --git a/lib/widgets/viewer/info/info_page.dart b/lib/widgets/viewer/info/info_page.dart index 2b88828f2..0326d636d 100644 --- a/lib/widgets/viewer/info/info_page.dart +++ b/lib/widgets/viewer/info/info_page.dart @@ -150,7 +150,7 @@ class _InfoPageContent extends StatefulWidget { } class _InfoPageContentState extends State<_InfoPageContent> { - final List _subscriptions = []; + final Set _subscriptions = {}; late EntryInfoActionDelegate _actionDelegate; final ValueNotifier> _metadataNotifier = ValueNotifier({}); final ValueNotifier _isEditingMetadataNotifier = ValueNotifier(null); diff --git a/lib/widgets/viewer/visual/entry_page_view.dart b/lib/widgets/viewer/visual/entry_page_view.dart index 9ef35fabc..3a5cbd7ff 100644 --- a/lib/widgets/viewer/visual/entry_page_view.dart +++ b/lib/widgets/viewer/visual/entry_page_view.dart @@ -54,7 +54,7 @@ class EntryPageView extends StatefulWidget { class _EntryPageViewState extends State with TickerProviderStateMixin { late ValueNotifier _viewStateNotifier; late AvesMagnifierController _magnifierController; - final List _subscriptions = []; + final Set _subscriptions = {}; final ValueNotifier _actionFeedbackChildNotifier = ValueNotifier(null); OverlayEntry? _actionFeedbackOverlayEntry; diff --git a/plugins/aves_platform_meta/.gitignore b/plugins/aves_platform_meta/.gitignore deleted file mode 100644 index 79c113f9b..000000000 --- a/plugins/aves_platform_meta/.gitignore +++ /dev/null @@ -1,45 +0,0 @@ -# Miscellaneous -*.class -*.log -*.pyc -*.swp -.DS_Store -.atom/ -.build/ -.buildlog/ -.history -.svn/ -.swiftpm/ -migrate_working_dir/ - -# IntelliJ related -*.iml -*.ipr -*.iws -.idea/ - -# The .vscode folder contains launch configuration and tasks you configure in -# VS Code which you may wish to be included in version control, so this line -# is commented out by default. -#.vscode/ - -# Flutter/Dart/Pub related -**/doc/api/ -**/ios/Flutter/.last_build_id -.dart_tool/ -.flutter-plugins -.flutter-plugins-dependencies -.pub-cache/ -.pub/ -/build/ - -# Symbolication related -app.*.symbols - -# Obfuscation related -app.*.map.json - -# Android Studio will place build artifacts here -/android/app/debug -/android/app/profile -/android/app/release diff --git a/plugins/aves_platform_meta/.metadata b/plugins/aves_platform_meta/.metadata deleted file mode 100644 index 93fddf202..000000000 --- a/plugins/aves_platform_meta/.metadata +++ /dev/null @@ -1,30 +0,0 @@ -# This file tracks properties of this Flutter project. -# Used by Flutter tool to assess capabilities and perform upgrades etc. -# -# This file should be version controlled. - -version: - revision: 85684f9300908116a78138ea4c6036c35c9a1236 - channel: stable - -project_type: plugin - -# Tracks metadata for the flutter migrate command -migration: - platforms: - - platform: root - create_revision: 85684f9300908116a78138ea4c6036c35c9a1236 - base_revision: 85684f9300908116a78138ea4c6036c35c9a1236 - - platform: android - create_revision: 85684f9300908116a78138ea4c6036c35c9a1236 - base_revision: 85684f9300908116a78138ea4c6036c35c9a1236 - - # User provided section - - # List of Local paths (relative to this file) that should be - # ignored by the migrate tool. - # - # Files that are not part of the templates will be ignored by default. - unmanaged_files: - - 'lib/main.dart' - - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/plugins/aves_platform_meta/analysis_options.yaml b/plugins/aves_platform_meta/analysis_options.yaml deleted file mode 100644 index f04c6cf0f..000000000 --- a/plugins/aves_platform_meta/analysis_options.yaml +++ /dev/null @@ -1 +0,0 @@ -include: ../../analysis_options.yaml diff --git a/plugins/aves_platform_meta/android/.gitignore b/plugins/aves_platform_meta/android/.gitignore deleted file mode 100644 index 82677b89f..000000000 --- a/plugins/aves_platform_meta/android/.gitignore +++ /dev/null @@ -1,15 +0,0 @@ -gradle-wrapper.jar -/.gradle -/captures/ -/gradlew -/gradlew.bat -/local.properties -GeneratedPluginRegistrant.java -.cxx/ -.kotlin/ - -# Remember to never publicly share your keystore. -# See https://flutter.dev/to/reference-keystore -key.properties -**/*.keystore -**/*.jks diff --git a/plugins/aves_platform_meta/android/build.gradle b/plugins/aves_platform_meta/android/build.gradle deleted file mode 100644 index ce435aea5..000000000 --- a/plugins/aves_platform_meta/android/build.gradle +++ /dev/null @@ -1,52 +0,0 @@ -group 'deckers.thibault.aves.aves_platform_meta' -version '1.0-SNAPSHOT' - -buildscript { - ext { - kotlin_version = '2.1.10' - agp_version = '8.8.0' - } - - repositories { - google() - mavenCentral() - } - - dependencies { - classpath "com.android.tools.build:gradle:$agp_version" - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - } -} - -allprojects { - repositories { - google() - mavenCentral() - } -} - -apply plugin: 'com.android.library' -apply plugin: 'kotlin-android' - -kotlin { - jvmToolchain 17 -} - -android { - namespace 'deckers.thibault.aves.aves_platform_meta' - compileSdk 35 - - lintOptions { - checkAllWarnings true - warningsAsErrors true - disable 'InvalidPackage' - } - - sourceSets { - main.java.srcDirs += 'src/main/kotlin' - } - - defaultConfig { - minSdk 21 - } -} diff --git a/plugins/aves_platform_meta/android/gradle/wrapper/gradle-wrapper.properties b/plugins/aves_platform_meta/android/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 849633dd6..000000000 --- a/plugins/aves_platform_meta/android/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,5 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.12.1-bin.zip \ No newline at end of file diff --git a/plugins/aves_platform_meta/android/settings.gradle b/plugins/aves_platform_meta/android/settings.gradle deleted file mode 100644 index d69766b76..000000000 --- a/plugins/aves_platform_meta/android/settings.gradle +++ /dev/null @@ -1 +0,0 @@ -rootProject.name = 'aves_platform_meta' diff --git a/plugins/aves_platform_meta/android/src/main/AndroidManifest.xml b/plugins/aves_platform_meta/android/src/main/AndroidManifest.xml deleted file mode 100644 index cc947c567..000000000 --- a/plugins/aves_platform_meta/android/src/main/AndroidManifest.xml +++ /dev/null @@ -1 +0,0 @@ - diff --git a/plugins/aves_platform_meta/android/src/main/kotlin/deckers/thibault/aves/aves_platform_meta/AvesPlatformMetaPlugin.kt b/plugins/aves_platform_meta/android/src/main/kotlin/deckers/thibault/aves/aves_platform_meta/AvesPlatformMetaPlugin.kt deleted file mode 100644 index 55aca1e2b..000000000 --- a/plugins/aves_platform_meta/android/src/main/kotlin/deckers/thibault/aves/aves_platform_meta/AvesPlatformMetaPlugin.kt +++ /dev/null @@ -1,52 +0,0 @@ -package deckers.thibault.aves.aves_platform_meta - -import android.content.Context -import android.content.pm.PackageManager -import androidx.annotation.NonNull -import io.flutter.embedding.engine.plugins.FlutterPlugin -import io.flutter.plugin.common.MethodCall -import io.flutter.plugin.common.MethodChannel -import io.flutter.plugin.common.MethodChannel.MethodCallHandler - -class AvesPlatformMetaPlugin : FlutterPlugin, MethodCallHandler { - private var context: Context? = null - private lateinit var channel: MethodChannel - - override fun onAttachedToEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) { - context = binding.applicationContext - channel = MethodChannel(binding.binaryMessenger, "deckers.thibault/aves/aves_platform_meta") - channel.setMethodCallHandler(this) - } - - override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) { - context = null - channel.setMethodCallHandler(null) - } - - override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: MethodChannel.Result) { - if (call.method == "getMetadata") { - getMetadata(call, result) - } else { - result.notImplemented() - } - } - - - private fun getMetadata(@NonNull call: MethodCall, @NonNull result: MethodChannel.Result) { - val key = call.argument("key") - if (key == null) { - result.error("getMetadata-args", "missing arguments", null) - return - } - - val ctx = context - if (ctx == null) { - result.error("getMetadata-context", "no context", null) - return - } - - val metadata = ctx.packageManager.getApplicationInfoCompat(ctx.packageName, PackageManager.GET_META_DATA).metaData - val value = metadata.getString(key) - result.success(value) - } -} diff --git a/plugins/aves_platform_meta/android/src/main/kotlin/deckers/thibault/aves/aves_platform_meta/Compat.kt b/plugins/aves_platform_meta/android/src/main/kotlin/deckers/thibault/aves/aves_platform_meta/Compat.kt deleted file mode 100644 index 499c0d1ce..000000000 --- a/plugins/aves_platform_meta/android/src/main/kotlin/deckers/thibault/aves/aves_platform_meta/Compat.kt +++ /dev/null @@ -1,14 +0,0 @@ -package deckers.thibault.aves.aves_platform_meta - -import android.content.pm.ApplicationInfo -import android.content.pm.PackageManager -import android.os.Build - -fun PackageManager.getApplicationInfoCompat(packageName: String, flags: Int): ApplicationInfo { - return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - getApplicationInfo(packageName, PackageManager.ApplicationInfoFlags.of(flags.toLong())) - } else { - @Suppress("deprecation") - getApplicationInfo(packageName, flags) - } -} diff --git a/plugins/aves_platform_meta/lib/aves_platform_meta.dart b/plugins/aves_platform_meta/lib/aves_platform_meta.dart deleted file mode 100644 index e086a65d5..000000000 --- a/plugins/aves_platform_meta/lib/aves_platform_meta.dart +++ /dev/null @@ -1,7 +0,0 @@ -import 'aves_platform_meta_platform_interface.dart'; - -class AvesPlatformMeta { - Future getMetadata(String key) { - return AvesPlatformMetaPlatform.instance.getMetadata(key); - } -} diff --git a/plugins/aves_platform_meta/lib/aves_platform_meta_method_channel.dart b/plugins/aves_platform_meta/lib/aves_platform_meta_method_channel.dart deleted file mode 100644 index 6cabfa2e8..000000000 --- a/plugins/aves_platform_meta/lib/aves_platform_meta_method_channel.dart +++ /dev/null @@ -1,16 +0,0 @@ -import 'package:flutter/foundation.dart'; -import 'package:flutter/services.dart'; - -import 'aves_platform_meta_platform_interface.dart'; - -class MethodChannelAvesPlatformMeta extends AvesPlatformMetaPlatform { - @visibleForTesting - final methodChannel = const MethodChannel('deckers.thibault/aves/aves_platform_meta'); - - @override - Future getMetadata(String key) { - return methodChannel.invokeMethod('getMetadata', { - 'key': key, - }); - } -} diff --git a/plugins/aves_platform_meta/lib/aves_platform_meta_platform_interface.dart b/plugins/aves_platform_meta/lib/aves_platform_meta_platform_interface.dart deleted file mode 100644 index 89438ca2f..000000000 --- a/plugins/aves_platform_meta/lib/aves_platform_meta_platform_interface.dart +++ /dev/null @@ -1,22 +0,0 @@ -import 'package:plugin_platform_interface/plugin_platform_interface.dart'; - -import 'aves_platform_meta_method_channel.dart'; - -abstract class AvesPlatformMetaPlatform extends PlatformInterface { - AvesPlatformMetaPlatform() : super(token: _token); - - static final Object _token = Object(); - - static AvesPlatformMetaPlatform _instance = MethodChannelAvesPlatformMeta(); - - static AvesPlatformMetaPlatform get instance => _instance; - - static set instance(AvesPlatformMetaPlatform instance) { - PlatformInterface.verifyToken(instance, _token); - _instance = instance; - } - - Future getMetadata(String key) { - throw UnimplementedError('platformVersion() has not been implemented.'); - } -} diff --git a/plugins/aves_platform_meta/pubspec.yaml b/plugins/aves_platform_meta/pubspec.yaml deleted file mode 100644 index 7b5fadc0b..000000000 --- a/plugins/aves_platform_meta/pubspec.yaml +++ /dev/null @@ -1,22 +0,0 @@ -name: aves_platform_meta -version: 0.0.1 -publish_to: none - -environment: - sdk: ">=3.6.0 <4.0.0" # incoherent dartfmt from 3.7.0 -resolution: workspace - -dependencies: - flutter: - sdk: flutter - plugin_platform_interface: - -dev_dependencies: - flutter_lints: - -flutter: - plugin: - platforms: - android: - package: deckers.thibault.aves.aves_platform_meta - pluginClass: AvesPlatformMetaPlugin diff --git a/pubspec.lock b/pubspec.lock index 7cc2091eb..fd9594647 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,26 +5,31 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: e55636ed79578b9abca5fecf9437947798f5ef7456308b5cb85720b793eac92f + sha256: "16e298750b6d0af7ce8a3ba7c18c69c3785d11b15ec83f6dcd0ad2a0009b3cab" url: "https://pub.dev" source: hosted - version: "82.0.0" + version: "76.0.0" _flutterfire_internals: dependency: transitive description: name: _flutterfire_internals - sha256: de9ecbb3ddafd446095f7e833c853aff2fa1682b017921fe63a833f9d6f0e422 + sha256: "214e6f07e2a44f45972e0365c7b537eaeaddb4598db0778dd4ac64b4acd3f5b1" url: "https://pub.dev" source: hosted - version: "1.3.54" + version: "1.3.55" + _macros: + dependency: transitive + description: dart + source: sdk + version: "0.3.3" analyzer: dependency: transitive description: name: analyzer - sha256: "13c1e6c6fd460522ea840abec3f677cc226f5fec7872c04ad7b425517ccf54f7" + sha256: "1f14db053a8c23e260789e9b0980fa27f2680dd640932cae5e1137cce0e46e1e" url: "https://pub.dev" source: hosted - version: "7.4.4" + version: "6.11.0" archive: dependency: transitive description: @@ -45,10 +50,10 @@ packages: dependency: transitive description: name: async - sha256: d2872f9c19731c2e5f10444b14686eb7cc85c76274bd6c16e1816bff9a3bab63 + sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" url: "https://pub.dev" source: hosted - version: "2.12.0" + version: "2.11.0" barcode: dependency: transitive description: @@ -69,10 +74,10 @@ packages: dependency: transitive description: name: boolean_selector - sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea" + sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.1.1" chalkdart: dependency: transitive description: @@ -85,10 +90,10 @@ packages: dependency: transitive description: name: characters - sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" url: "https://pub.dev" source: hosted - version: "1.4.0" + version: "1.3.0" charts_common: dependency: transitive description: @@ -107,6 +112,14 @@ packages: url: "https://github.com/deckerst/flutter_google_charts.git" source: git version: "0.12.0" + checked_yaml: + dependency: transitive + description: + name: checked_yaml + sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff + url: "https://pub.dev" + source: hosted + version: "2.0.3" cli_config: dependency: transitive description: @@ -119,18 +132,18 @@ packages: dependency: transitive description: name: clock - sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b + sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf url: "https://pub.dev" source: hosted - version: "1.1.2" + version: "1.1.1" collection: dependency: "direct main" description: name: collection - sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" + sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf url: "https://pub.dev" source: hosted - version: "1.19.1" + version: "1.19.0" connectivity_plus: dependency: "direct main" description: @@ -167,10 +180,10 @@ packages: dependency: transitive description: name: coverage - sha256: "802bd084fb82e55df091ec8ad1553a7331b61c08251eef19a508b6f3f3a9858d" + sha256: "4b8701e48a58f7712492c9b1f7ba0bb9d525644dd66d023b62e1fc8cdb560c8a" url: "https://pub.dev" source: hosted - version: "1.13.1" + version: "1.14.0" crypto: dependency: transitive description: @@ -223,10 +236,10 @@ packages: dependency: "direct main" description: name: device_info_plus - sha256: "0c6396126421b590089447154c5f98a5de423b70cfb15b1578fd018843ee6f53" + sha256: "72d146c6d7098689ff5c5f66bcf593ac11efc530095385356e131070333e64da" url: "https://pub.dev" source: hosted - version: "11.4.0" + version: "11.3.0" device_info_plus_platform_interface: dependency: transitive description: @@ -288,34 +301,34 @@ packages: dependency: transitive description: name: fake_async - sha256: "6a95e56b2449df2273fd8c45a662d6947ce1ebb7aafe80e550a3f68297f3cacc" + sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" url: "https://pub.dev" source: hosted - version: "1.3.2" + version: "1.3.1" ffi: dependency: transitive description: name: ffi - sha256: "289279317b4b16eb2bb7e271abccd4bf84ec9bdcbe999e278a94b804f5630418" + sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6" url: "https://pub.dev" source: hosted - version: "2.1.4" + version: "2.1.3" file: dependency: transitive description: name: file - sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 + sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" url: "https://pub.dev" source: hosted - version: "7.0.1" + version: "7.0.0" firebase_core: dependency: transitive description: name: firebase_core - sha256: "017d17d9915670e6117497e640b2859e0b868026ea36bf3a57feb28c3b97debe" + sha256: "8cfe3c900512399ce8d50fcc817e5758ff8615eeb6fa5c846a4cc47bbf6353b6" url: "https://pub.dev" source: hosted - version: "3.13.0" + version: "3.13.1" firebase_core_platform_interface: dependency: transitive description: @@ -328,26 +341,26 @@ packages: dependency: transitive description: name: firebase_core_web - sha256: "129a34d1e0fb62e2b488d988a1fc26cc15636357e50944ffee2862efe8929b23" + sha256: ddd72baa6f727e5b23f32d9af23d7d453d67946f380bd9c21daf474ee0f7326e url: "https://pub.dev" source: hosted - version: "2.22.0" + version: "2.23.0" firebase_crashlytics: dependency: transitive description: name: firebase_crashlytics - sha256: f3fa4a17c2f061b16b2e3ac7aaed889ae954b8952d0fd3e0009a9870cde7bbd2 + sha256: "49d20b1dd87bb42746e27b5c72c1e3a3d84ae6415d062f8b31ecb71a35d36d0c" url: "https://pub.dev" source: hosted - version: "4.3.5" + version: "4.3.6" firebase_crashlytics_platform_interface: dependency: transitive description: name: firebase_crashlytics_platform_interface - sha256: cedfbe39927711c0e56fc38bfecbd89e17816b21698a3d88d63298c530ed375c + sha256: "0a5b2c9a662db7563482547b31da06a3951277cbfb42af12c5b52a15456ea951" url: "https://pub.dev" source: hosted - version: "3.8.5" + version: "3.8.6" fixnum: dependency: transitive description: @@ -439,7 +452,7 @@ packages: dependency: "direct main" description: path: "." - ref: HEAD + ref: "6a8c14bceaefd00e703ad517fd2a32fa2081b5de" resolved-ref: "6a8c14bceaefd00e703ad517fd2a32fa2081b5de" url: "https://github.com/deckerst/flutter_localizations_plus.git" source: git @@ -452,14 +465,14 @@ packages: url: "https://pub.dev" source: hosted version: "7.0.2" - flutter_markdown: + flutter_markdown_plus: dependency: "direct main" description: - name: flutter_markdown - sha256: "634622a3a826d67cb05c0e3e576d1812c430fa98404e95b60b131775c73d76ec" + name: flutter_markdown_plus + sha256: fe74214c5ac2f850d93efda290dcde3f18006e90a87caa9e3e6c13222a5db4de url: "https://pub.dev" source: hosted - version: "0.7.7" + version: "1.0.3" flutter_plugin_android_lifecycle: dependency: transitive description: @@ -551,10 +564,10 @@ packages: dependency: transitive description: name: google_maps_flutter - sha256: "830d8f7b51b4a950bf0d7daa675324fed6c9beb57a7ecca2a59018270c96b4e0" + sha256: d7e4704e6b9f3452c7cd9eb6efc226e1f9e8273c28da47b0a1e7451916d71005 url: "https://pub.dev" source: hosted - version: "2.12.1" + version: "2.12.2" google_maps_flutter_android: dependency: transitive description: @@ -615,10 +628,10 @@ packages: dependency: "direct main" description: name: http - sha256: fe7ab022b76f3034adc518fb6ea04a82387620e19977665ea18d30a1cf43442f + sha256: "2c11f3f94c687ee9bad77c171151672986360b2b001d109814ee7140b2cf261b" url: "https://pub.dev" source: hosted - version: "1.3.0" + version: "1.4.0" http_multi_server: dependency: transitive description: @@ -663,10 +676,18 @@ packages: dependency: transitive description: name: js - sha256: "53385261521cc4a0c4658fd0ad07a7d14591cf8fc33abbceae306ddb974888dc" + sha256: c1b2e9b5ea78c45e1a0788d29606ba27dc5f71f019f32ca5140f61ef071838cf url: "https://pub.dev" source: hosted - version: "0.7.2" + version: "0.7.1" + json_annotation: + dependency: transitive + description: + name: json_annotation + sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1" + url: "https://pub.dev" + source: hosted + version: "4.9.0" latlong2: dependency: "direct main" description: @@ -679,18 +700,18 @@ packages: dependency: "direct main" description: name: leak_tracker - sha256: c35baad643ba394b40aac41080300150a4f08fd0fd6a10378f8f7c6bc161acec + sha256: "7bb2830ebd849694d1ec25bf1f44582d6ac531a57a365a803a6034ff751d2d06" url: "https://pub.dev" source: hosted - version: "10.0.8" + version: "10.0.7" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573 + sha256: "9491a714cca3667b60b5c420da8217e6de0d1ba7a5ec322fab01758f6998f379" url: "https://pub.dev" source: hosted - version: "3.0.9" + version: "3.0.8" leak_tracker_testing: dependency: transitive description: @@ -771,6 +792,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.0" + macros: + dependency: transitive + description: + name: macros + sha256: "1d9e801cd66f7ea3663c45fc708450db1fa57f988142c64289142c9b7ee80656" + url: "https://pub.dev" + source: hosted + version: "0.1.3-main.0" markdown: dependency: transitive description: @@ -783,10 +812,10 @@ packages: dependency: transitive description: name: matcher - sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb url: "https://pub.dev" source: hosted - version: "0.12.17" + version: "0.12.16+1" material_color_utilities: dependency: transitive description: @@ -807,10 +836,10 @@ packages: dependency: "direct main" description: name: material_symbols_icons - sha256: d45b6c36c3effa8cb51b1afb8698107d5ff1f88fa4631428f34a8a01abc295d7 + sha256: "7c50901b39d1ad645ee25d920aed008061e1fd541a897b4ebf2c01d966dbf16b" url: "https://pub.dev" source: hosted - version: "4.2815.0" + version: "4.2815.1" media_kit: dependency: transitive description: @@ -839,10 +868,10 @@ packages: dependency: transitive description: name: meta - sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c + sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 url: "https://pub.dev" source: hosted - version: "1.16.0" + version: "1.15.0" mgrs_dart: dependency: transitive description: @@ -944,10 +973,10 @@ packages: dependency: "direct main" description: name: palette_generator - sha256: "5a96b78983752faeb94866b30cb8f52e94ef176722bf51d1c5541d6a3044368f" + sha256: "4420f7ccc3f0a4a906144e73f8b6267cd940b64f57a7262e95cb8cec3a8ae0ed" url: "https://pub.dev" source: hosted - version: "0.3.3+6" + version: "0.3.3+7" panorama: dependency: "direct main" description: @@ -961,10 +990,10 @@ packages: dependency: "direct main" description: name: path - sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.9.0" path_parsing: dependency: transitive description: @@ -1105,10 +1134,10 @@ packages: dependency: transitive description: name: petitparser - sha256: "07c8f0b1913bcde1ff0d26e57ace2f3012ccbf2b204e070290dad3bb22797646" + sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27 url: "https://pub.dev" source: hosted - version: "6.1.0" + version: "6.0.2" pin_code_fields: dependency: "direct main" description: @@ -1121,10 +1150,10 @@ packages: dependency: transitive description: name: platform - sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984" + sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65" url: "https://pub.dev" source: hosted - version: "3.1.6" + version: "3.1.5" plugin_platform_interface: dependency: transitive description: @@ -1169,10 +1198,10 @@ packages: dependency: transitive description: name: process - sha256: "107d8be718f120bbba9dcd1e95e3bd325b1b4a4f07db64154635ba03f2567a0d" + sha256: "21e54fd2faf1b5bdd5102afd25012184a6793927648ea81eea80552ac9405b32" url: "https://pub.dev" source: hosted - version: "5.0.3" + version: "5.0.2" proj4dart: dependency: "direct main" description: @@ -1205,6 +1234,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.2.0" + pubspec_parse: + dependency: transitive + description: + name: pubspec_parse + sha256: "0560ba233314abbed0a48a2956f7f022cce7c3e1e73df540277da7544cad4082" + url: "https://pub.dev" + source: hosted + version: "1.5.0" qr: dependency: transitive description: @@ -1241,10 +1278,10 @@ packages: dependency: "direct main" description: name: screen_brightness - sha256: eca7bd9d2c3c688bcad14855361cab7097839400b6b4a56f62b7ae511c709958 + sha256: "20b43489fbb12316d64633d5abb731f8d3e2c49871f65c8e434c6225d0f58fcf" url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.1.4" screen_brightness_android: dependency: transitive description: @@ -1257,10 +1294,10 @@ packages: dependency: transitive description: name: screen_brightness_ios - sha256: bfd9bfd0ac852e7aa170e7e356cc27195b2a75037b72c8c6336cf6fb2115cffb + sha256: "2493953340ecfe8f4f13f61db50ce72533a55b0bbd58ba1402893feecf3727f5" url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" screen_brightness_macos: dependency: transitive description: @@ -1269,6 +1306,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.1" + screen_brightness_ohos: + dependency: transitive + description: + name: screen_brightness_ohos + sha256: "61e313e46eaee3f83dd4e85a2a91f8a81be02c154bc9e60830a7c0fd76dac286" + url: "https://pub.dev" + source: hosted + version: "2.1.0" screen_brightness_platform_interface: dependency: transitive description: @@ -1369,10 +1414,10 @@ packages: dependency: transitive description: name: shelf_web_socket - sha256: "3632775c8e90d6c9712f883e633716432a27758216dfb61bd86a8321c0580925" + sha256: cc36c297b52866d203dbf9332263c94becc2fe0ceaa9681d07b6ef9807023b67 url: "https://pub.dev" source: hosted - version: "3.0.0" + version: "2.0.1" sky_engine: dependency: transitive description: flutter @@ -1406,10 +1451,10 @@ packages: dependency: transitive description: name: source_span - sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c" + sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" url: "https://pub.dev" source: hosted - version: "1.10.1" + version: "1.10.0" sprintf: dependency: transitive description: @@ -1422,34 +1467,34 @@ packages: dependency: "direct main" description: name: sqflite - sha256: e2297b1da52f127bc7a3da11439985d9b536f75070f3325e62ada69a5c585d03 + sha256: "2d7299468485dca85efeeadf5d38986909c5eb0cd71fd3db2c2f000e6c9454bb" url: "https://pub.dev" source: hosted - version: "2.4.2" + version: "2.4.1" sqflite_android: dependency: transitive description: name: sqflite_android - sha256: "2b3070c5fa881839f8b402ee4a39c1b4d561704d4ebbbcfb808a119bc2a1701b" + sha256: "78f489aab276260cdd26676d2169446c7ecd3484bbd5fead4ca14f3ed4dd9ee3" url: "https://pub.dev" source: hosted - version: "2.4.1" + version: "2.4.0" sqflite_common: dependency: transitive description: name: sqflite_common - sha256: "84731e8bfd8303a3389903e01fb2141b6e59b5973cacbb0929021df08dddbe8b" + sha256: "761b9740ecbd4d3e66b8916d784e581861fd3c3553eda85e167bc49fdb68f709" url: "https://pub.dev" source: hosted - version: "2.5.5" + version: "2.5.4+6" sqflite_darwin: dependency: transitive description: name: sqflite_darwin - sha256: "279832e5cde3fe99e8571879498c9211f3ca6391b0d818df4e17d9fff5c6ccb3" + sha256: "22adfd9a2c7d634041e96d6241e6e1c8138ca6817018afc5d443fef91dcefa9c" url: "https://pub.dev" source: hosted - version: "2.4.2" + version: "2.4.1+1" sqflite_platform_interface: dependency: transitive description: @@ -1462,18 +1507,18 @@ packages: dependency: "direct main" description: name: stack_trace - sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" + sha256: "9f47fd3630d76be3ab26f0ee06d213679aa425996925ff3feffdec504931c377" url: "https://pub.dev" source: hosted - version: "1.12.1" + version: "1.12.0" stream_channel: dependency: transitive description: name: stream_channel - sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d" + sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 url: "https://pub.dev" source: hosted - version: "2.1.4" + version: "2.1.2" stream_transform: dependency: transitive description: @@ -1495,10 +1540,10 @@ packages: dependency: transitive description: name: string_scanner - sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43" + sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3" url: "https://pub.dev" source: hosted - version: "1.4.1" + version: "1.3.0" sync_http: dependency: transitive description: @@ -1511,42 +1556,42 @@ packages: dependency: "direct main" description: name: synchronized - sha256: "0669c70faae6270521ee4f05bffd2919892d42d1276e6c495be80174b6bc0ef6" + sha256: "69fe30f3a8b04a0be0c15ae6490fc859a78ef4c43ae2dd5e8a623d45bfcf9225" url: "https://pub.dev" source: hosted - version: "3.3.1" + version: "3.3.0+3" term_glyph: dependency: transitive description: name: term_glyph - sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e" + sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 url: "https://pub.dev" source: hosted - version: "1.2.2" + version: "1.2.1" test: dependency: "direct dev" description: name: test - sha256: "301b213cd241ca982e9ba50266bd3f5bd1ea33f1455554c5abb85d1be0e2d87e" + sha256: "713a8789d62f3233c46b4a90b174737b2c04cb6ae4500f2aa8b1be8f03f5e67f" url: "https://pub.dev" source: hosted - version: "1.25.15" + version: "1.25.8" test_api: dependency: transitive description: name: test_api - sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd + sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c" url: "https://pub.dev" source: hosted - version: "0.7.4" + version: "0.7.3" test_core: dependency: transitive description: name: test_core - sha256: "84d17c3486c8dfdbe5e12a50c8ae176d15e2a771b96909a9442b40173649ccaa" + sha256: "12391302411737c176b0b5d6491f466b0dd56d4763e347b6714efbaa74d7953d" url: "https://pub.dev" source: hosted - version: "0.6.8" + version: "0.6.5" typed_data: dependency: transitive description: @@ -1671,10 +1716,10 @@ packages: dependency: transitive description: name: vector_tile - sha256: "3adb04426f3aebefce56f3fdf8ab2e23cc9f7d5b06ff8ca33ae87e3a1e441874" + sha256: "7ae290246e3a8734422672dbe791d3f7b8ab631734489fc6d405f1cc2080e38c" url: "https://pub.dev" source: hosted - version: "2.0.0" + version: "2.0.1" vector_tile_renderer: dependency: "direct main" description: @@ -1687,18 +1732,18 @@ packages: dependency: transitive description: name: vm_service - sha256: "0968250880a6c5fe7edc067ed0a13d4bae1577fe2771dcf3010d52c4a9d3ca14" + sha256: f6be3ed8bd01289b34d679c2b62226f63c0e69f9fd2e50a6b3c1c729a961041b url: "https://pub.dev" source: hosted - version: "14.3.1" + version: "14.3.0" volume_controller: dependency: "direct main" description: name: volume_controller - sha256: e82fd689bb8e1fe8e64be3fa5946ff8699058f8cf9f4c1679acdba20cda7f5bd + sha256: d75039e69c0d90e7810bfd47e3eedf29ff8543ea7a10392792e81f9bded7edf5 url: "https://pub.dev" source: hosted - version: "3.3.3" + version: "3.4.0" wakelock_plus: dependency: transitive description: @@ -1735,10 +1780,10 @@ packages: dependency: transitive description: name: web_socket - sha256: bfe6f435f6ec49cb6c01da1e275ae4228719e59a6b067048c51e72d9d63bcc4b + sha256: "34d64019aa8e36bf9842ac014bb5d2f5586ca73df5e4d9bf5c936975cae6982c" url: "https://pub.dev" source: hosted - version: "1.0.0" + version: "1.0.1" web_socket_channel: dependency: transitive description: @@ -1767,18 +1812,18 @@ packages: dependency: transitive description: name: win32 - sha256: dc6ecaa00a7c708e5b4d10ee7bec8c270e9276dfcab1783f57e9962d7884305f + sha256: daf97c9d80197ed7b619040e86c8ab9a9dad285e7671ee7390f9180cc828a51e url: "https://pub.dev" source: hosted - version: "5.12.0" + version: "5.10.1" win32_registry: dependency: transitive description: name: win32_registry - sha256: "6f1b564492d0147b330dd794fee8f512cec4977957f310f9951b5f9d83618dae" + sha256: "21ec76dfc731550fd3e2ce7a33a9ea90b828fdf19a5c3bcf556fa992cfa99852" url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "1.1.5" wkt_parser: dependency: transitive description: @@ -1812,5 +1857,5 @@ packages: source: hosted version: "3.1.3" sdks: - dart: ">=3.7.0 <4.0.0" - flutter: ">=3.29.3" + dart: ">=3.6.0 <4.0.0" + flutter: ">=3.27.4" diff --git a/pubspec.yaml b/pubspec.yaml index de9243f95..8f6459168 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -7,19 +7,18 @@ 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.13.1+152 +version: 1.13.2+153 publish_to: none environment: # this project bundles Flutter SDK via `flutter_wrapper` # cf https://github.com/passsy/flutter_wrapper - flutter: 3.29.3 + flutter: 3.27.4 sdk: ">=3.6.0 <4.0.0" # incoherent dartfmt from 3.7.0 workspace: - plugins/aves_magnifier - plugins/aves_map - plugins/aves_model - - plugins/aves_platform_meta - plugins/aves_report - plugins/aves_report_crashlytics - plugins/aves_screen_state @@ -86,8 +85,9 @@ dependencies: flutter_localizations_plus: git: url: https://github.com/deckerst/flutter_localizations_plus.git + ref: 6a8c14bceaefd00e703ad517fd2a32fa2081b5de flutter_map: - flutter_markdown: # discontinued on 2025/04/30 + flutter_markdown_plus: flutter_staggered_animations: get_it: gpx: diff --git a/shaders.sksl.json b/shaders.sksl.json index a1cf9cd25..b441388bc 100644 --- a/shaders.sksl.json +++ b/shaders.sksl.json @@ -1 +1 @@ -{"platform":"android","name":"XQ DE72","engineRevision":"cf56914b326edb0ccb123ffdc60f00060bd513fa","data":{"AYQA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAAAAMYAAAAAAAQAAAABAMQAAAAA":"DAAAAExTS1MlAgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0NCB1bG9jYWxNYXRyaXhfUzA7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiBmbG9hdDQgaW5DaXJjbGVFZGdlOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIENpcmNsZUdlb21ldHJ5UHJvY2Vzc29yCgl2aW5DaXJjbGVFZGdlX1MwID0gaW5DaXJjbGVFZGdlOwoJdmluQ29sb3JfUzAgPSBpbkNvbG9yOwoJZmxvYXQyIF90bXBfMF9pblBvc2l0aW9uID0gaW5Qb3NpdGlvbjsKCWZsb2F0MiBfdG1wXzFfaW5Qb3NpdGlvbiA9IHVsb2NhbE1hdHJpeF9TMC54eiAqIGluUG9zaXRpb24gKyB1bG9jYWxNYXRyaXhfUzAueXc7Cglza19Qb3NpdGlvbiA9IF90bXBfMF9pblBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAAAEMCAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIENpcmNsZUdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDQgY2lyY2xlRWRnZTsKCWNpcmNsZUVkZ2UgPSB2aW5DaXJjbGVFZGdlX1MwOwoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZpbkNvbG9yX1MwOwoJZmxvYXQgZCA9IGxlbmd0aChjaXJjbGVFZGdlLnh5KTsKCWhhbGYgZGlzdGFuY2VUb091dGVyRWRnZSA9IGhhbGYoY2lyY2xlRWRnZS56ICogKDEuMCAtIGQpKTsKCWhhbGYgZWRnZUFscGhhID0gc2F0dXJhdGUoZGlzdGFuY2VUb091dGVyRWRnZSk7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGVkZ2VBbHBoYSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADAAAAGluQ2lyY2xlRWRnZQAAAAA=","B2ABSAAABQAAIAABBYAAB7777777777774ABICAAAAAAAAAAAAAABGABAAAAAEAAAAAIBEABAAAAA":"DAAAAExTS1PDAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGhhbGY0IHVDb2xvcl9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGYgaW5Db3ZlcmFnZTsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBEZWZhdWx0R2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IGNvbG9yID0gdUNvbG9yX1MwOwoJY29sb3IgPSBjb2xvciAqIGluQ292ZXJhZ2U7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCWZsb2F0MiBfdG1wXzFfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8zX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBfdG1wXzFfaW5Qb3NpdGlvbi54eTAxOwp9CgAAAAAAUQEAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQpub3BlcnNwZWN0aXZlIGluIGhhbGY0IHZjb2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIERlZmF1bHRHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAoAAABpblBvc2l0aW9uAAAKAAAAaW5Db3ZlcmFnZQAAAAAAAA==","GZIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAIIBAAAABAAAAALIEAAAAAAAAAAAAAABQAMAAAABAAAAAAABBAMAAAAA":"DAAAAExTS1PIAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfMl9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzEpICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAL8CAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7Cm5vcGVyc3BlY3RpdmUgaW4gaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MxLCB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMCkucnJycjsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzAoX2lucHV0KTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IE1hdHJpeEVmZmVjdF9TMShvdXRwdXRDb3ZlcmFnZV9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","GZJAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAABAAAAAABBAMABQAMAAAABAAAAAAABBAMAAA":"DAAAAExTS1N3AQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgcG9zaXRpb247CmluIGhhbGY0IGNvbG9yOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7Cgl2bG9jYWxDb29yZF9TMCA9IGxvY2FsQ29vcmQ7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cn0KAAAAAAApAgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQyIHZsb2NhbENvb3JkX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJZmxvYXQyIHRleENvb3JkOwoJdGV4Q29vcmQgPSB2bG9jYWxDb29yZF9TMDsKCW91dHB1dENvbG9yX1MwID0gKGJsZW5kX21vZHVsYXRlKHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMCwgdGV4Q29vcmQpLCBvdXRwdXRDb2xvcl9TMCkpOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","DAQAAAAAAAAAAAAAAJQAAIGAAEACBYQCAGAEFAIBAAAAAABAAAAAAAAAAAAAAMYAAAAAAAQAAAABAMQAAAAA":"DAAAAExTS1N4AgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0MiB1QXRsYXNTaXplSW52X1MwOwppbiBmbG9hdDIgaW5Qb3NpdGlvbjsKaW4gaGFsZjQgaW5Db2xvcjsKaW4gdXNob3J0MiBpblRleHR1cmVDb29yZHM7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQgdlRleEluZGV4X1MwOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgQml0bWFwVGV4dAoJaW50IHRleElkeCA9IDA7CglmbG9hdDIgdW5vcm1UZXhDb29yZHMgPSBmbG9hdDIoaW5UZXh0dXJlQ29vcmRzLngsIGluVGV4dHVyZUNvb3Jkcy55KTsKCXZUZXh0dXJlQ29vcmRzX1MwID0gdW5vcm1UZXhDb29yZHMgKiB1QXRsYXNTaXplSW52X1MwOwoJdlRleEluZGV4X1MwID0gZmxvYXQodGV4SWR4KTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzFfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247Cglza19Qb3NpdGlvbiA9IGluUG9zaXRpb24ueHkwMTsKfQoAAAAACwIAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQyIHZUZXh0dXJlQ29vcmRzX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0IHZUZXhJbmRleF9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIEJpdG1hcFRleHQKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWhhbGY0IHRleENvbG9yOwoJewoJCXRleENvbG9yID0gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB2VGV4dHVyZUNvb3Jkc19TMCkucnJycjsKCX0KCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gdGV4Q29sb3I7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADwAAAGluVGV4dHVyZUNvb3JkcwAAAAAA","AYQA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAACABZQA6AAAEAAAAAAAMADAAAAAIAAAAAAAIIDA":"DAAAAExTS1MlAgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0NCB1bG9jYWxNYXRyaXhfUzA7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiBmbG9hdDQgaW5DaXJjbGVFZGdlOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIENpcmNsZUdlb21ldHJ5UHJvY2Vzc29yCgl2aW5DaXJjbGVFZGdlX1MwID0gaW5DaXJjbGVFZGdlOwoJdmluQ29sb3JfUzAgPSBpbkNvbG9yOwoJZmxvYXQyIF90bXBfMF9pblBvc2l0aW9uID0gaW5Qb3NpdGlvbjsKCWZsb2F0MiBfdG1wXzFfaW5Qb3NpdGlvbiA9IHVsb2NhbE1hdHJpeF9TMC54eiAqIGluUG9zaXRpb24gKyB1bG9jYWxNYXRyaXhfUzAueXc7Cglza19Qb3NpdGlvbiA9IF90bXBfMF9pblBvc2l0aW9uLnh5MDE7Cn0KAAAAAQAAAOgDAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQ0IHZpbkNpcmNsZUVkZ2VfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gaGFsZjQgdmluQ29sb3JfUzA7CmhhbGY0IENpcmN1bGFyUlJlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MxLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MxLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CgloYWxmIGFscGhhID0gaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzEueCAtIGxlbmd0aChkeHkpKSk7CglhbHBoYSA9IDEuMCAtIGFscGhhOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQ0IGNpcmNsZUVkZ2U7CgljaXJjbGVFZGdlID0gdmluQ2lyY2xlRWRnZV9TMDsKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWZsb2F0IGQgPSBsZW5ndGgoY2lyY2xlRWRnZS54eSk7CgloYWxmIGRpc3RhbmNlVG9PdXRlckVkZ2UgPSBoYWxmKGNpcmNsZUVkZ2UueiAqICgxLjAgLSBkKSk7CgloYWxmIGVkZ2VBbHBoYSA9IHNhdHVyYXRlKGRpc3RhbmNlVG9PdXRlckVkZ2UpOwoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChlZGdlQWxwaGEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQ2lyY3VsYXJSUmVjdF9TMShvdXRwdXRDb3ZlcmFnZV9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADAAAAGluQ2lyY2xlRWRnZQAAAAA=","DAQAAAAAAAAAAAAAAJQAAIGAAEACBYQCAGAEFAIBAAAAAABAAAAAAAAAAAACAB4QA4AAAEAAAAAAAMADAAAAAIAAAAAAAIID":"DAAAAExTS1N4AgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0MiB1QXRsYXNTaXplSW52X1MwOwppbiBmbG9hdDIgaW5Qb3NpdGlvbjsKaW4gaGFsZjQgaW5Db2xvcjsKaW4gdXNob3J0MiBpblRleHR1cmVDb29yZHM7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQgdlRleEluZGV4X1MwOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgQml0bWFwVGV4dAoJaW50IHRleElkeCA9IDA7CglmbG9hdDIgdW5vcm1UZXhDb29yZHMgPSBmbG9hdDIoaW5UZXh0dXJlQ29vcmRzLngsIGluVGV4dHVyZUNvb3Jkcy55KTsKCXZUZXh0dXJlQ29vcmRzX1MwID0gdW5vcm1UZXhDb29yZHMgKiB1QXRsYXNTaXplSW52X1MwOwoJdlRleEluZGV4X1MwID0gZmxvYXQodGV4SWR4KTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzFfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247Cglza19Qb3NpdGlvbiA9IGluUG9zaXRpb24ueHkwMTsKfQoBAAAAmgMAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQp1bmlmb3JtIGZsb2F0NCB1aW5uZXJSZWN0X1MxOwp1bmlmb3JtIGhhbGYyIHVyYWRpdXNQbHVzSGFsZl9TMTsKc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdCB2VGV4SW5kZXhfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gaGFsZjQgdmluQ29sb3JfUzA7CmhhbGY0IENpcmN1bGFyUlJlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MxLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MxLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CgloYWxmIGFscGhhID0gaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzEueCAtIGxlbmd0aChkeHkpKSk7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIEJpdG1hcFRleHQKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWhhbGY0IHRleENvbG9yOwoJewoJCXRleENvbG9yID0gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB2VGV4dHVyZUNvb3Jkc19TMCkucnJycjsKCX0KCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gdGV4Q29sb3I7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBDaXJjdWxhclJSZWN0X1MxKG91dHB1dENvdmVyYWdlX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACgAAAGluUG9zaXRpb24AAAcAAABpbkNvbG9yAA8AAABpblRleHR1cmVDb29yZHMAAAAAAA==","EADQAAAAAEAAAAAUAABQAAQPAAABCFYMAAKAUEAAAAAAAAABAAAAAAAAAAAJQAIAAAABAAAAACAJAAIAAAAA":"DAAAAExTS1NtAgAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQyIHVBdGxhc0RpbWVuc2lvbnNJbnZfUzA7CmluIGZsb2F0MyBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiB1c2hvcnQyIGluVGV4dHVyZUNvb3JkczsKb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKb3V0IGZsb2F0IHZUZXhJbmRleF9TMDsKb3V0IGZsb2F0MiB2SW50VGV4dHVyZUNvb3Jkc19TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBEaXN0YW5jZUZpZWxkUGF0aAoJaW50IHRleElkeCA9IDA7CglmbG9hdDIgdW5vcm1UZXhDb29yZHMgPSBmbG9hdDIoaW5UZXh0dXJlQ29vcmRzLngsIGluVGV4dHVyZUNvb3Jkcy55KTsKCXZUZXh0dXJlQ29vcmRzX1MwID0gdW5vcm1UZXhDb29yZHMgKiB1QXRsYXNEaW1lbnNpb25zSW52X1MwOwoJdlRleEluZGV4X1MwID0gZmxvYXQodGV4SWR4KTsKCXZJbnRUZXh0dXJlQ29vcmRzX1MwID0gdW5vcm1UZXhDb29yZHM7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDMgX3RtcF8xX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBpblBvc2l0aW9uLnh5MHo7Cn0KAAAAAAAAAJICAABzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzA7CmluIGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKaW4gZmxvYXQgdlRleEluZGV4X1MwOwppbiBmbG9hdDIgdkludFRleHR1cmVDb29yZHNfUzA7CmluIGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgRGlzdGFuY2VGaWVsZFBhdGgKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWZsb2F0MiB1diA9IHZUZXh0dXJlQ29vcmRzX1MwOwoJaGFsZjQgdGV4Q29sb3I7Cgl7CgkJdGV4Q29sb3IgPSBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzAsIHV2KS5ycnJyOwoJfQoJaGFsZiBkaXN0YW5jZSA9IDcuOTY4NzUqKHRleENvbG9yLnIgLSAwLjUwMTk2MDc4NDMxKTsKCWhhbGYgYWZ3aWR0aDsKCWFmd2lkdGggPSBhYnMoMC42NSpoYWxmKGRGZHgodkludFRleHR1cmVDb29yZHNfUzAueCkpKTsKCWhhbGYgdmFsID0gc21vb3Roc3RlcCgtYWZ3aWR0aCwgYWZ3aWR0aCwgZGlzdGFuY2UpOwoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCh2YWwpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAoAAABpblBvc2l0aW9uAAAHAAAAaW5Db2xvcgAPAAAAaW5UZXh0dXJlQ29vcmRzAAAAAAA=","AYQQ5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAAAAMYAAAAAAAQAAAABAMQAAAAA":"DAAAAExTS1MlAgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0NCB1bG9jYWxNYXRyaXhfUzA7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiBmbG9hdDQgaW5DaXJjbGVFZGdlOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIENpcmNsZUdlb21ldHJ5UHJvY2Vzc29yCgl2aW5DaXJjbGVFZGdlX1MwID0gaW5DaXJjbGVFZGdlOwoJdmluQ29sb3JfUzAgPSBpbkNvbG9yOwoJZmxvYXQyIF90bXBfMF9pblBvc2l0aW9uID0gaW5Qb3NpdGlvbjsKCWZsb2F0MiBfdG1wXzFfaW5Qb3NpdGlvbiA9IHVsb2NhbE1hdHJpeF9TMC54eiAqIGluUG9zaXRpb24gKyB1bG9jYWxNYXRyaXhfUzAueXc7Cglza19Qb3NpdGlvbiA9IF90bXBfMF9pblBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAAANQCAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIENpcmNsZUdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDQgY2lyY2xlRWRnZTsKCWNpcmNsZUVkZ2UgPSB2aW5DaXJjbGVFZGdlX1MwOwoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZpbkNvbG9yX1MwOwoJZmxvYXQgZCA9IGxlbmd0aChjaXJjbGVFZGdlLnh5KTsKCWhhbGYgZGlzdGFuY2VUb091dGVyRWRnZSA9IGhhbGYoY2lyY2xlRWRnZS56ICogKDEuMCAtIGQpKTsKCWhhbGYgZWRnZUFscGhhID0gc2F0dXJhdGUoZGlzdGFuY2VUb091dGVyRWRnZSk7CgloYWxmIGRpc3RhbmNlVG9Jbm5lckVkZ2UgPSBoYWxmKGNpcmNsZUVkZ2UueiAqIChkIC0gY2lyY2xlRWRnZS53KSk7CgloYWxmIGlubmVyQWxwaGEgPSBzYXR1cmF0ZShkaXN0YW5jZVRvSW5uZXJFZGdlKTsKCWVkZ2VBbHBoYSAqPSBpbm5lckFscGhhOwoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChlZGdlQWxwaGEpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADAAAAGluQ2lyY2xlRWRnZQAAAAA=","GYJAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAQAAAAAAQQGAAYAGAAAAAQAAAAAAAQQGAAA":"DAAAAExTS1MwAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgcG9zaXRpb247CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmxvY2FsQ29vcmRfUzAgPSBsb2NhbENvb3JkOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAADvAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwID0gaGFsZjQoMSk7CglmbG9hdDIgdGV4Q29vcmQ7Cgl0ZXhDb29yZCA9IHZsb2NhbENvb3JkX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSAoYmxlbmRfbW9kdWxhdGUoc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB0ZXhDb29yZCksIGhhbGY0KDEpKSk7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACAAAAHBvc2l0aW9uCgAAAGxvY2FsQ29vcmQAAAAAAAA=","GZIACAAAABQAAGAAAQ4AAAAAGQQAARC4GAAAIOCAAD6P7777777777YDAAAAAAAAAAAJIBBYGQ467YIAAAAAAQAAAAAMACTRNBZN5QYBAAAAAAAAAAAIAGIAAAAAAAIAAAAAQGIAAAAAA":"DAAAAExTS1M7AgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQgY292ZXJhZ2U7CmluIGhhbGY0IGNvbG9yOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdCB2Y292ZXJhZ2VfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDIgcG9zaXRpb24gPSBwb3NpdGlvbi54eTsKCXZjb2xvcl9TMCA9IGNvbG9yOwoJdmNvdmVyYWdlX1MwID0gY292ZXJhZ2U7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAAAJhwAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQpmbG9hdDQgZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzA7CmZsb2F0NCBmcmFnQ29sb3JfUzFfYzA7CmZsb2F0IHVfYWxwaGFfUzFfYzA7CmZsb2F0IHVfc3BhcmtsZV9hbHBoYV9TMV9jMDsKZmxvYXQgdV9ibHVyX1MxX2MwOwpmbG9hdCB1X3JhZGl1c19zY2FsZV9TMV9jMDsKdW5pZm9ybSBmbG9hdDQgdV9jb2xvcl9TMV9jMDsKdW5pZm9ybSBmbG9hdDQgdV9jb21wb3NpdGVfMV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jZW50ZXJfUzFfYzA7CnVuaWZvcm0gZmxvYXQgdV9tYXhfcmFkaXVzX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3Jlc29sdXRpb25fc2NhbGVfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfbm9pc2Vfc2NhbGVfUzFfYzA7CnVuaWZvcm0gZmxvYXQgdV9ub2lzZV9waGFzZV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jaXJjbGUxX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NpcmNsZTJfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2lyY2xlM19TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yb3RhdGlvbjFfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcm90YXRpb24yX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3JvdGF0aW9uM19TMV9jMDsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxOwpub3BlcnNwZWN0aXZlIGluIGhhbGY0IHZjb2xvcl9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdCB2Y292ZXJhZ2VfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwpmbG9hdDIgRkxUX2ZsdXR0ZXJfbG9jYWxfRmx1dHRlckZyYWdDb29yZF9TMV9jMCgpOwpmbG9hdDJ4MiBGTFRfZmx1dHRlcl9sb2NhbF9yb3RhdGUyZF9TMV9jMChmbG9hdDIgcmFkKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgYmx1cik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKGZsb2F0MiByZXNvbHV0aW9uLCBpbm91dCBmbG9hdDIgcCwgZmxvYXQyIHh5LCBmbG9hdDIgcm90YXRpb24sIGZsb2F0IGNlbGxfZGlhbWV0ZXIpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90dXJidWxlbmNlX1MxX2MwKGZsb2F0MiB1dik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfcmluZ19TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCB0aGlja25lc3MsIGZsb2F0IGJsdXIpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90cmlhbmdsZV9ub2lzZV9TMV9jMChpbm91dCBmbG9hdDIgbik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChmbG9hdCB2LCBmbG9hdCBsLCBmbG9hdCBoKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc3BhcmtsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0IHQpOwp2b2lkIEZMVF9tYWluX1MxX2MwKCk7CmZsb2F0MiBGTFRfZmx1dHRlcl9sb2NhbF9GbHV0dGVyRnJhZ0Nvb3JkX1MxX2MwKCkgCnsKCXJldHVybiBmbHV0dGVyX0ZyYWdDb29yZF9TMV9jMC54eTsKfQpmbG9hdDJ4MiBGTFRfZmx1dHRlcl9sb2NhbF9yb3RhdGUyZF9TMV9jMChmbG9hdDIgcmFkKSAKewoJcmV0dXJuIGZsb2F0MngyKHJhZC54LCAtcmFkLnksIHJhZC55LCByYWQueCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgYmx1cikgCnsKCWZsb2F0IGJsdXJfaGFsZiA9IGJsdXIgKiAwLjU7CglmbG9hdCBkID0gZGlzdGFuY2UodXYsIHh5KTsKCXJldHVybiAxLjAgLSBzbW9vdGhzdGVwKDEuMCAtIGJsdXJfaGFsZiwgMS4wICsgYmx1cl9oYWxmLCBkIC8gcmFkaXVzKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChmbG9hdDIgcmVzb2x1dGlvbiwgaW5vdXQgZmxvYXQyIHAsIGZsb2F0MiB4eSwgZmxvYXQyIHJvdGF0aW9uLCBmbG9hdCBjZWxsX2RpYW1ldGVyKSAKewoJZmxvYXQyIHBhcmFtID0gcm90YXRpb247CglwID0gRkxUX2ZsdXR0ZXJfbG9jYWxfcm90YXRlMmRfUzFfYzAocGFyYW0pICogKHh5IC0gcCkgKyB4eTsKCXAgPSBtb2QocCwgZmxvYXQyKGNlbGxfZGlhbWV0ZXIpKSAvIHJlc29sdXRpb247CglmbG9hdCBjZWxsX3V2ID0gKGNlbGxfZGlhbWV0ZXIgLyByZXNvbHV0aW9uLnkpICogMC41OwoJZmxvYXQgciA9IDAuNjUgKiBjZWxsX3V2OwoJZmxvYXQyIHBhcmFtXzEgPSBwOwoJZmxvYXQyIHBhcmFtXzIgPSBmbG9hdDIoY2VsbF91dik7CglmbG9hdCBwYXJhbV8zID0gcjsKCWZsb2F0IHBhcmFtXzQgPSByICogNTAuMDsKCXJldHVybiBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zLCBwYXJhbV80KTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90dXJidWxlbmNlX1MxX2MwKGZsb2F0MiB1dikgCnsKCWZsb2F0MiB1dl9zY2FsZSA9IHV2ICogZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW0gPSBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbV8xID0gdXZfc2NhbGU7CglmbG9hdDIgcGFyYW1fMiA9IHVfY2lyY2xlMV9TMV9jMDsKCWZsb2F0MiBwYXJhbV8zID0gdV9yb3RhdGlvbjFfUzFfYzA7CglmbG9hdCBwYXJhbV80ID0gMC4xNzsKCWZsb2F0IF8zMTkgPSBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChwYXJhbSwgcGFyYW1fMSwgcGFyYW1fMiwgcGFyYW1fMywgcGFyYW1fNCk7CglmbG9hdCBnMSA9IF8zMTk7CglmbG9hdDIgcGFyYW1fNSA9IGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtXzYgPSB1dl9zY2FsZTsKCWZsb2F0MiBwYXJhbV83ID0gdV9jaXJjbGUyX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzggPSB1X3JvdGF0aW9uMl9TMV9jMDsKCWZsb2F0IHBhcmFtXzkgPSAwLjI7CglmbG9hdCBfMzMxID0gRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAocGFyYW1fNSwgcGFyYW1fNiwgcGFyYW1fNywgcGFyYW1fOCwgcGFyYW1fOSk7CglmbG9hdCBnMiA9IF8zMzE7CglmbG9hdDIgcGFyYW1fMTAgPSBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbV8xMSA9IHV2X3NjYWxlOwoJZmxvYXQyIHBhcmFtXzEyID0gdV9jaXJjbGUzX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzEzID0gdV9yb3RhdGlvbjNfUzFfYzA7CglmbG9hdCBwYXJhbV8xNCA9IDAuMjc1OwoJZmxvYXQgXzM0NCA9IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKHBhcmFtXzEwLCBwYXJhbV8xMSwgcGFyYW1fMTIsIHBhcmFtXzEzLCBwYXJhbV8xNCk7CglmbG9hdCBnMyA9IF8zNDQ7CglmbG9hdCB2ID0gKChnMSAqIGcxICsgZzIpIC0gZzMpICogMC41OwoJcmV0dXJuIGNsYW1wKDAuNDUgKyAwLjggKiB2LCAwLjAsIDEuMCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9yaW5nX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IHRoaWNrbmVzcywgZmxvYXQgYmx1cikgCnsKCWZsb2F0MiBwYXJhbSA9IHV2OwoJZmxvYXQyIHBhcmFtXzEgPSB4eTsKCWZsb2F0IHBhcmFtXzIgPSByYWRpdXMgKyB0aGlja25lc3M7CglmbG9hdCBwYXJhbV8zID0gYmx1cjsKCWZsb2F0IGNpcmNsZV9vdXRlciA9IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtLCBwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zKTsKCWZsb2F0MiBwYXJhbV80ID0gdXY7CglmbG9hdDIgcGFyYW1fNSA9IHh5OwoJZmxvYXQgcGFyYW1fNiA9IG1heChyYWRpdXMgLSB0aGlja25lc3MsIDAuMCk7CglmbG9hdCBwYXJhbV83ID0gYmx1cjsKCWZsb2F0IGNpcmNsZV9pbm5lciA9IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtXzQsIHBhcmFtXzUsIHBhcmFtXzYsIHBhcmFtXzcpOwoJcmV0dXJuIGNsYW1wKGNpcmNsZV9vdXRlciAtIGNpcmNsZV9pbm5lciwgMC4wLCAxLjApOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RyaWFuZ2xlX25vaXNlX1MxX2MwKGlub3V0IGZsb2F0MiBuKSAKewoJbiA9IGZyYWN0KG4gKiBmbG9hdDIoNS4zOTg3LCA1LjQ0MjEpKTsKCW4gKz0gZmxvYXQyKGRvdChuLnl4LCBuICsgZmxvYXQyKDIxLjUzNTEsIDE0LjMxMzcpKSk7CglmbG9hdCB4eSA9IG4ueCAqIG4ueTsKCXJldHVybiAoZnJhY3QoeHkgKiA5NS40MzA3KSArIGZyYWN0KHh5ICogNzUuMDQ5NjEpKSAtIDEuMDsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAoZmxvYXQgdiwgZmxvYXQgbCwgZmxvYXQgaCkgCnsKCXJldHVybiBzdGVwKGwsIHYpICogKDEuMCAtIHN0ZXAoaCwgdikpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NwYXJrbGVfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdCB0KSAKewoJZmxvYXQyIHBhcmFtID0gdXY7CglmbG9hdCBfMjQyID0gRkxUX2ZsdXR0ZXJfbG9jYWxfdHJpYW5nbGVfbm9pc2VfUzFfYzAocGFyYW0pOwoJZmxvYXQgbiA9IF8yNDI7CglmbG9hdCBwYXJhbV8xID0gbjsKCWZsb2F0IHBhcmFtXzIgPSAwLjA7CglmbG9hdCBwYXJhbV8zID0gMC4wNTsKCWZsb2F0IHMgPSBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAocGFyYW1fMSwgcGFyYW1fMiwgcGFyYW1fMyk7CglmbG9hdCBwYXJhbV80ID0gbiArIHNpbigzLjE0MTU5Mjc0ICogKHQgKyAwLjM1KSk7CglmbG9hdCBwYXJhbV81ID0gMC4xOwoJZmxvYXQgcGFyYW1fNiA9IDAuMTU7CglzICs9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV80LCBwYXJhbV81LCBwYXJhbV82KTsKCWZsb2F0IHBhcmFtXzcgPSBuICsgc2luKDMuMTQxNTkyNzQgKiAodCArIDAuNykpOwoJZmxvYXQgcGFyYW1fOCA9IDAuMjsKCWZsb2F0IHBhcmFtXzkgPSAwLjI1OwoJcyArPSBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAocGFyYW1fNywgcGFyYW1fOCwgcGFyYW1fOSk7CglmbG9hdCBwYXJhbV8xMCA9IG4gKyBzaW4oMy4xNDE1OTI3NCAqICh0ICsgMS4wNSkpOwoJZmxvYXQgcGFyYW1fMTEgPSAwLjM7CglmbG9hdCBwYXJhbV8xMiA9IDAuMzU7CglzICs9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV8xMCwgcGFyYW1fMTEsIHBhcmFtXzEyKTsKCXJldHVybiBjbGFtcChzLCAwLjAsIDEuMCkgKiAwLjU1Owp9CnZvaWQgRkxUX21haW5fUzFfYzAoKSAKewoJdV9hbHBoYV9TMV9jMCA9IHVfY29tcG9zaXRlXzFfUzFfYzAueDsKCXVfc3BhcmtsZV9hbHBoYV9TMV9jMCA9IHVfY29tcG9zaXRlXzFfUzFfYzAueTsKCXVfYmx1cl9TMV9jMCA9IHVfY29tcG9zaXRlXzFfUzFfYzAuejsKCXVfcmFkaXVzX3NjYWxlX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC53OwoJZmxvYXQyIHAgPSBGTFRfZmx1dHRlcl9sb2NhbF9GbHV0dGVyRnJhZ0Nvb3JkX1MxX2MwKCk7CglmbG9hdDIgdXZfMSA9IHAgKiB1X3Jlc29sdXRpb25fc2NhbGVfUzFfYzA7CglmbG9hdDIgZGVuc2l0eV91diA9IHV2XzEgLSBtb2QocCwgdV9ub2lzZV9zY2FsZV9TMV9jMCk7CglmbG9hdCByYWRpdXMgPSB1X21heF9yYWRpdXNfUzFfYzAgKiB1X3JhZGl1c19zY2FsZV9TMV9jMDsKCWZsb2F0MiBwYXJhbV8xMyA9IHV2XzE7CglmbG9hdCB0dXJidWxlbmNlID0gRkxUX2ZsdXR0ZXJfbG9jYWxfdHVyYnVsZW5jZV9TMV9jMChwYXJhbV8xMyk7CglmbG9hdDIgcGFyYW1fMTQgPSBwOwoJZmxvYXQyIHBhcmFtXzE1ID0gdV9jZW50ZXJfUzFfYzA7CglmbG9hdCBwYXJhbV8xNiA9IHJhZGl1czsKCWZsb2F0IHBhcmFtXzE3ID0gMC4wNSAqIHVfbWF4X3JhZGl1c19TMV9jMDsKCWZsb2F0IHBhcmFtXzE4ID0gdV9ibHVyX1MxX2MwOwoJZmxvYXQgcmluZyA9IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfcmluZ19TMV9jMChwYXJhbV8xNCwgcGFyYW1fMTUsIHBhcmFtXzE2LCBwYXJhbV8xNywgcGFyYW1fMTgpOwoJZmxvYXQyIHBhcmFtXzE5ID0gZGVuc2l0eV91djsKCWZsb2F0IHBhcmFtXzIwID0gdV9ub2lzZV9waGFzZV9TMV9jMDsKCWZsb2F0IHNwYXJrbGUgPSAoKEZMVF9mbHV0dGVyX2xvY2FsX3NwYXJrbGVfUzFfYzAocGFyYW1fMTksIHBhcmFtXzIwKSAqIHJpbmcpICogdHVyYnVsZW5jZSkgKiB1X3NwYXJrbGVfYWxwaGFfUzFfYzA7CglmbG9hdDIgcGFyYW1fMjEgPSBwOwoJZmxvYXQyIHBhcmFtXzIyID0gdV9jZW50ZXJfUzFfYzA7CglmbG9hdCBwYXJhbV8yMyA9IHJhZGl1czsKCWZsb2F0IHBhcmFtXzI0ID0gdV9ibHVyX1MxX2MwOwoJZmxvYXQgd2F2ZV9hbHBoYSA9IChGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChwYXJhbV8yMSwgcGFyYW1fMjIsIHBhcmFtXzIzLCBwYXJhbV8yNCkgKiB1X2FscGhhX1MxX2MwKSAqIHVfY29sb3JfUzFfYzAudzsKCWZsb2F0NCB3YXZlX2NvbG9yID0gZmxvYXQ0KHVfY29sb3JfUzFfYzAueHl6ICogd2F2ZV9hbHBoYSwgd2F2ZV9hbHBoYSk7CglmcmFnQ29sb3JfUzFfYzAgPSBtaXgod2F2ZV9jb2xvciwgZmxvYXQ0KDEuMCksIGZsb2F0NChzcGFya2xlKSk7Cn0KaGFsZjQgcnVudGltZV9zaGFkZXJfUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF8wX2luQ29sb3IgPSBfaW5wdXQ7CglmbG9hdDIgX3RtcF8xX2Nvb3JkcyA9IHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwoJZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzAgPSBmbG9hdDQoX3RtcF8xX2Nvb3JkcywgMC4wLCAwLjApOwoJRkxUX21haW5fUzFfYzAoKTsKCXJldHVybiBoYWxmNChoYWxmNChmcmFnQ29sb3JfUzFfYzApKTsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIHJ1bnRpbWVfc2hhZGVyX1MxX2MwKF9pbnB1dCk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWZsb2F0IGNvdmVyYWdlID0gdmNvdmVyYWdlX1MwOwoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChjb3ZlcmFnZSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBNYXRyaXhFZmZlY3RfUzEob3V0cHV0Q29sb3JfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAAcG9zaXRpb24IAAAAY292ZXJhZ2UFAAAAY29sb3IAAAAKAAAAbG9jYWxDb29yZAAAAAAAAA==","EEAQMYAAMAAAEADAAABAEYAAAICIAB5AABQAAAQAMAAAEATAAABAIIGAAEDCBYQCA4AAAAAAAAZQAAAAAABAAAAACAZAAAAA":"DAAAAExTS1MoDAAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDQgcmFkaWlfc2VsZWN0b3I7CmluIGZsb2F0NCBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzOwppbiBmbG9hdDQgYWFfYmxvYXRfYW5kX2NvdmVyYWdlOwppbiBmbG9hdDQgcmFkaWlfeDsKaW4gZmxvYXQ0IHJhZGlpX3k7CmluIGZsb2F0NCBza2V3OwppbiBmbG9hdDIgdHJhbnNsYXRlX2FuZF9sb2NhbHJvdGF0ZTsKaW4gaGFsZjQgY29sb3I7Cm5vcGVyc3BlY3RpdmUgb3V0IGhhbGY0IHZjb2xvcl9TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQyIHZhcmNjb29yZF9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgRmlsbFJSZWN0T3A6OlByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7CglmbG9hdCBhYV9ibG9hdF9tdWx0aXBsaWVyID0gMTsKCWZsb2F0MiBjb3JuZXIgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnh5OwoJZmxvYXQyIHJhZGl1c19vdXRzZXQgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnp3OwoJZmxvYXQyIGFhX2Jsb2F0X2RpcmVjdGlvbiA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS54eTsKCWZsb2F0IGlzX2xpbmVhcl9jb3ZlcmFnZSA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS53OwoJZmxvYXQyIHBpeGVsbGVuZ3RoID0gaW52ZXJzZXNxcnQoZmxvYXQyKGRvdChza2V3Lnh6LCBza2V3Lnh6KSwgZG90KHNrZXcueXcsIHNrZXcueXcpKSk7CglmbG9hdDQgbm9ybWFsaXplZF9heGlzX2RpcnMgPSBza2V3ICogcGl4ZWxsZW5ndGgueHl4eTsKCWZsb2F0MiBheGlzd2lkdGhzID0gKGFicyhub3JtYWxpemVkX2F4aXNfZGlycy54eSkgKyBhYnMobm9ybWFsaXplZF9heGlzX2RpcnMuencpKTsKCWZsb2F0MiBhYV9ibG9hdHJhZGl1cyA9IGF4aXN3aWR0aHMgKiBwaXhlbGxlbmd0aCAqIC41OwoJZmxvYXQ0IHJhZGlpX2FuZF9uZWlnaGJvcnMgPSByYWRpaV9zZWxlY3RvciogZmxvYXQ0eDQocmFkaWlfeCwgcmFkaWlfeSwgcmFkaWlfeC55eHd6LCByYWRpaV95Lnd6eXgpOwoJZmxvYXQyIHJhZGlpID0gcmFkaWlfYW5kX25laWdoYm9ycy54eTsKCWZsb2F0MiBuZWlnaGJvcl9yYWRpaSA9IHJhZGlpX2FuZF9uZWlnaGJvcnMuenc7CglmbG9hdCBjb3ZlcmFnZV9tdWx0aXBsaWVyID0gMTsKCWlmIChhbnkoZ3JlYXRlclRoYW4oYWFfYmxvYXRyYWRpdXMsIGZsb2F0MigxKSkpKSAKCXsKCQljb3JuZXIgPSBtYXgoYWJzKGNvcm5lciksIGFhX2Jsb2F0cmFkaXVzKSAqIHNpZ24oY29ybmVyKTsKCQljb3ZlcmFnZV9tdWx0aXBsaWVyID0gMSAvIChtYXgoYWFfYmxvYXRyYWRpdXMueCwgMSkgKiBtYXgoYWFfYmxvYXRyYWRpdXMueSwgMSkpOwoJCXJhZGlpID0gZmxvYXQyKDApOwoJfQoJZmxvYXQgY292ZXJhZ2UgPSBhYV9ibG9hdF9hbmRfY292ZXJhZ2UuejsKCWlmIChhbnkobGVzc1RoYW4ocmFkaWksIGFhX2Jsb2F0cmFkaXVzICogMS41KSkpIAoJewoJCXJhZGlpID0gZmxvYXQyKDApOwoJCWFhX2Jsb2F0X2RpcmVjdGlvbiA9IHNpZ24oY29ybmVyKTsKCQlpZiAoY292ZXJhZ2UgPiAuNSkgCgkJewoJCQlhYV9ibG9hdF9kaXJlY3Rpb24gPSAtYWFfYmxvYXRfZGlyZWN0aW9uOwoJCX0KCQlpc19saW5lYXJfY292ZXJhZ2UgPSAxOwoJfQoJZWxzZSAKCXsKCQlyYWRpaSA9IGNsYW1wKHJhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQluZWlnaGJvcl9yYWRpaSA9IGNsYW1wKG5laWdoYm9yX3JhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQlmbG9hdDIgc3BhY2luZyA9IDIgLSByYWRpaSAtIG5laWdoYm9yX3JhZGlpOwoJCWZsb2F0MiBleHRyYV9wYWQgPSBtYXgocGl4ZWxsZW5ndGggKiAuMDYyNSAtIHNwYWNpbmcsIGZsb2F0MigwKSk7CgkJcmFkaWkgLT0gZXh0cmFfcGFkICogLjU7Cgl9CglmbG9hdDIgYWFfb3V0c2V0ID0gYWFfYmxvYXRfZGlyZWN0aW9uICogYWFfYmxvYXRyYWRpdXMgKiBhYV9ibG9hdF9tdWx0aXBsaWVyOwoJZmxvYXQyIHZlcnRleHBvcyA9IGNvcm5lciArIHJhZGl1c19vdXRzZXQgKiByYWRpaSArIGFhX291dHNldDsKCWlmIChjb3ZlcmFnZSA+IC41KSAKCXsKCQlpZiAoYWFfYmxvYXRfZGlyZWN0aW9uLnggIT0gMCAmJiB2ZXJ0ZXhwb3MueCAqIGNvcm5lci54IDwgMCkgCgkJewoJCQlmbG9hdCBiYWNrc2V0ID0gYWJzKHZlcnRleHBvcy54KTsKCQkJdmVydGV4cG9zLnggPSAwOwoJCQl2ZXJ0ZXhwb3MueSArPSBiYWNrc2V0ICogc2lnbihjb3JuZXIueSkgKiBwaXhlbGxlbmd0aC55L3BpeGVsbGVuZ3RoLng7CgkJCWNvdmVyYWdlID0gKGNvdmVyYWdlIC0gLjUpICogYWJzKGNvcm5lci54KSAvIChhYnMoY29ybmVyLngpICsgYmFja3NldCkgKyAuNTsKCQl9CgkJaWYgKGFhX2Jsb2F0X2RpcmVjdGlvbi55ICE9IDAgJiYgdmVydGV4cG9zLnkgKiBjb3JuZXIueSA8IDApIAoJCXsKCQkJZmxvYXQgYmFja3NldCA9IGFicyh2ZXJ0ZXhwb3MueSk7CgkJCXZlcnRleHBvcy55ID0gMDsKCQkJdmVydGV4cG9zLnggKz0gYmFja3NldCAqIHNpZ24oY29ybmVyLngpICogcGl4ZWxsZW5ndGgueC9waXhlbGxlbmd0aC55OwoJCQljb3ZlcmFnZSA9IChjb3ZlcmFnZSAtIC41KSAqIGFicyhjb3JuZXIueSkgLyAoYWJzKGNvcm5lci55KSArIGJhY2tzZXQpICsgLjU7CgkJfQoJfQoJZmxvYXQyeDIgc2tld21hdHJpeCA9IGZsb2F0MngyKHNrZXcueHksIHNrZXcuencpOwoJZmxvYXQyIGRldmNvb3JkID0gdmVydGV4cG9zICogc2tld21hdHJpeCArIHRyYW5zbGF0ZV9hbmRfbG9jYWxyb3RhdGUueHk7CglpZiAoMCAhPSBpc19saW5lYXJfY292ZXJhZ2UpIAoJewoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MigwLCBjb3ZlcmFnZSAqIGNvdmVyYWdlX211bHRpcGxpZXIpOwoJfQoJZWxzZSAKCXsKCQlmbG9hdDIgYXJjY29vcmQgPSAxIC0gYWJzKHJhZGl1c19vdXRzZXQpICsgYWFfb3V0c2V0L3JhZGlpICogY29ybmVyOwoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MihhcmNjb29yZC54KzEsIGFyY2Nvb3JkLnkpOwoJfQoJc2tfUG9zaXRpb24gPSBkZXZjb29yZC54eTAxOwp9CgAAAACZAgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCm5vcGVyc3BlY3RpdmUgaW4gaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2YXJjY29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBGaWxsUlJlY3RPcDo6UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJZmxvYXQgeF9wbHVzXzE9dmFyY2Nvb3JkX1MwLngsIHk9dmFyY2Nvb3JkX1MwLnk7CgloYWxmIGNvdmVyYWdlOwoJaWYgKDAgPT0geF9wbHVzXzEpIAoJewoJCWNvdmVyYWdlID0gaGFsZih5KTsKCX0KCWVsc2UgCgl7CgkJZmxvYXQgZm4gPSB4X3BsdXNfMSAqICh4X3BsdXNfMSAtIDIpOwoJCWZuID0gZm1hKHkseSwgZm4pOwoJCWZsb2F0IGZud2lkdGggPSBmd2lkdGgoZm4pOwoJCWNvdmVyYWdlID0gLjUgLSBoYWxmKGZuL2Zud2lkdGgpOwoJCWNvdmVyYWdlID0gY2xhbXAoY292ZXJhZ2UsIDAsIDEpOwoJfQoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChjb3ZlcmFnZSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAACAAAAA4AAAByYWRpaV9zZWxlY3RvcgAAGQAAAGNvcm5lcl9hbmRfcmFkaXVzX291dHNldHMAAAAVAAAAYWFfYmxvYXRfYW5kX2NvdmVyYWdlAAAABwAAAHJhZGlpX3gABwAAAHJhZGlpX3kABAAAAHNrZXcZAAAAdHJhbnNsYXRlX2FuZF9sb2NhbHJvdGF0ZQAAAAUAAABjb2xvcgAAAAAAAAA=","GZIACAAAABQAAGAAAQ4AAAAAGQQAARC4GAAAIOCAAD6P7777777777YDAAAAAAAAAAAJQBBYGQ467YIAAAAAAQAAAAAMACTRNBZN5QYBAAAAAAAAAAAIAA6IAMAAACAAAAAABGABAAAAAEAAAAAIBEABAA":"DAAAAExTS1M7AgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQgY292ZXJhZ2U7CmluIGhhbGY0IGNvbG9yOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdCB2Y292ZXJhZ2VfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDIgcG9zaXRpb24gPSBwb3NpdGlvbi54eTsKCXZjb2xvcl9TMCA9IGNvbG9yOwoJdmNvdmVyYWdlX1MwID0gY292ZXJhZ2U7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgABAAAAtR0AACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQpmbG9hdDQgZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzA7CmZsb2F0NCBmcmFnQ29sb3JfUzFfYzA7CmZsb2F0IHVfYWxwaGFfUzFfYzA7CmZsb2F0IHVfc3BhcmtsZV9hbHBoYV9TMV9jMDsKZmxvYXQgdV9ibHVyX1MxX2MwOwpmbG9hdCB1X3JhZGl1c19zY2FsZV9TMV9jMDsKdW5pZm9ybSBmbG9hdDQgdV9jb2xvcl9TMV9jMDsKdW5pZm9ybSBmbG9hdDQgdV9jb21wb3NpdGVfMV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jZW50ZXJfUzFfYzA7CnVuaWZvcm0gZmxvYXQgdV9tYXhfcmFkaXVzX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3Jlc29sdXRpb25fc2NhbGVfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfbm9pc2Vfc2NhbGVfUzFfYzA7CnVuaWZvcm0gZmxvYXQgdV9ub2lzZV9waGFzZV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jaXJjbGUxX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NpcmNsZTJfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2lyY2xlM19TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yb3RhdGlvbjFfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcm90YXRpb24yX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3JvdGF0aW9uM19TMV9jMDsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxOwp1bmlmb3JtIGZsb2F0NCB1aW5uZXJSZWN0X1MyOwp1bmlmb3JtIGhhbGYyIHVyYWRpdXNQbHVzSGFsZl9TMjsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQgdmNvdmVyYWdlX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKZmxvYXQyIEZMVF9mbHV0dGVyX2xvY2FsX0ZsdXR0ZXJGcmFnQ29vcmRfUzFfYzAoKTsKZmxvYXQyeDIgRkxUX2ZsdXR0ZXJfbG9jYWxfcm90YXRlMmRfUzFfYzAoZmxvYXQyIHJhZCk7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IGJsdXIpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChmbG9hdDIgcmVzb2x1dGlvbiwgaW5vdXQgZmxvYXQyIHAsIGZsb2F0MiB4eSwgZmxvYXQyIHJvdGF0aW9uLCBmbG9hdCBjZWxsX2RpYW1ldGVyKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHVyYnVsZW5jZV9TMV9jMChmbG9hdDIgdXYpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X3JpbmdfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgdGhpY2tuZXNzLCBmbG9hdCBibHVyKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHJpYW5nbGVfbm9pc2VfUzFfYzAoaW5vdXQgZmxvYXQyIG4pOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAoZmxvYXQgdiwgZmxvYXQgbCwgZmxvYXQgaCk7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NwYXJrbGVfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdCB0KTsKdm9pZCBGTFRfbWFpbl9TMV9jMCgpOwpmbG9hdDIgRkxUX2ZsdXR0ZXJfbG9jYWxfRmx1dHRlckZyYWdDb29yZF9TMV9jMCgpIAp7CglyZXR1cm4gZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzAueHk7Cn0KZmxvYXQyeDIgRkxUX2ZsdXR0ZXJfbG9jYWxfcm90YXRlMmRfUzFfYzAoZmxvYXQyIHJhZCkgCnsKCXJldHVybiBmbG9hdDJ4MihyYWQueCwgLXJhZC55LCByYWQueSwgcmFkLngpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IGJsdXIpIAp7CglmbG9hdCBibHVyX2hhbGYgPSBibHVyICogMC41OwoJZmxvYXQgZCA9IGRpc3RhbmNlKHV2LCB4eSk7CglyZXR1cm4gMS4wIC0gc21vb3Roc3RlcCgxLjAgLSBibHVyX2hhbGYsIDEuMCArIGJsdXJfaGFsZiwgZCAvIHJhZGl1cyk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAoZmxvYXQyIHJlc29sdXRpb24sIGlub3V0IGZsb2F0MiBwLCBmbG9hdDIgeHksIGZsb2F0MiByb3RhdGlvbiwgZmxvYXQgY2VsbF9kaWFtZXRlcikgCnsKCWZsb2F0MiBwYXJhbSA9IHJvdGF0aW9uOwoJcCA9IEZMVF9mbHV0dGVyX2xvY2FsX3JvdGF0ZTJkX1MxX2MwKHBhcmFtKSAqICh4eSAtIHApICsgeHk7CglwID0gbW9kKHAsIGZsb2F0MihjZWxsX2RpYW1ldGVyKSkgLyByZXNvbHV0aW9uOwoJZmxvYXQgY2VsbF91diA9IChjZWxsX2RpYW1ldGVyIC8gcmVzb2x1dGlvbi55KSAqIDAuNTsKCWZsb2F0IHIgPSAwLjY1ICogY2VsbF91djsKCWZsb2F0MiBwYXJhbV8xID0gcDsKCWZsb2F0MiBwYXJhbV8yID0gZmxvYXQyKGNlbGxfdXYpOwoJZmxvYXQgcGFyYW1fMyA9IHI7CglmbG9hdCBwYXJhbV80ID0gciAqIDUwLjA7CglyZXR1cm4gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW1fMSwgcGFyYW1fMiwgcGFyYW1fMywgcGFyYW1fNCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHVyYnVsZW5jZV9TMV9jMChmbG9hdDIgdXYpIAp7CglmbG9hdDIgdXZfc2NhbGUgPSB1diAqIGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtID0gZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW1fMSA9IHV2X3NjYWxlOwoJZmxvYXQyIHBhcmFtXzIgPSB1X2NpcmNsZTFfUzFfYzA7CglmbG9hdDIgcGFyYW1fMyA9IHVfcm90YXRpb24xX1MxX2MwOwoJZmxvYXQgcGFyYW1fNCA9IDAuMTc7CglmbG9hdCBfMzE5ID0gRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAocGFyYW0sIHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMsIHBhcmFtXzQpOwoJZmxvYXQgZzEgPSBfMzE5OwoJZmxvYXQyIHBhcmFtXzUgPSBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbV82ID0gdXZfc2NhbGU7CglmbG9hdDIgcGFyYW1fNyA9IHVfY2lyY2xlMl9TMV9jMDsKCWZsb2F0MiBwYXJhbV84ID0gdV9yb3RhdGlvbjJfUzFfYzA7CglmbG9hdCBwYXJhbV85ID0gMC4yOwoJZmxvYXQgXzMzMSA9IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKHBhcmFtXzUsIHBhcmFtXzYsIHBhcmFtXzcsIHBhcmFtXzgsIHBhcmFtXzkpOwoJZmxvYXQgZzIgPSBfMzMxOwoJZmxvYXQyIHBhcmFtXzEwID0gZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW1fMTEgPSB1dl9zY2FsZTsKCWZsb2F0MiBwYXJhbV8xMiA9IHVfY2lyY2xlM19TMV9jMDsKCWZsb2F0MiBwYXJhbV8xMyA9IHVfcm90YXRpb24zX1MxX2MwOwoJZmxvYXQgcGFyYW1fMTQgPSAwLjI3NTsKCWZsb2F0IF8zNDQgPSBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChwYXJhbV8xMCwgcGFyYW1fMTEsIHBhcmFtXzEyLCBwYXJhbV8xMywgcGFyYW1fMTQpOwoJZmxvYXQgZzMgPSBfMzQ0OwoJZmxvYXQgdiA9ICgoZzEgKiBnMSArIGcyKSAtIGczKSAqIDAuNTsKCXJldHVybiBjbGFtcCgwLjQ1ICsgMC44ICogdiwgMC4wLCAxLjApOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfcmluZ19TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCB0aGlja25lc3MsIGZsb2F0IGJsdXIpIAp7CglmbG9hdDIgcGFyYW0gPSB1djsKCWZsb2F0MiBwYXJhbV8xID0geHk7CglmbG9hdCBwYXJhbV8yID0gcmFkaXVzICsgdGhpY2tuZXNzOwoJZmxvYXQgcGFyYW1fMyA9IGJsdXI7CglmbG9hdCBjaXJjbGVfb3V0ZXIgPSBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChwYXJhbSwgcGFyYW1fMSwgcGFyYW1fMiwgcGFyYW1fMyk7CglmbG9hdDIgcGFyYW1fNCA9IHV2OwoJZmxvYXQyIHBhcmFtXzUgPSB4eTsKCWZsb2F0IHBhcmFtXzYgPSBtYXgocmFkaXVzIC0gdGhpY2tuZXNzLCAwLjApOwoJZmxvYXQgcGFyYW1fNyA9IGJsdXI7CglmbG9hdCBjaXJjbGVfaW5uZXIgPSBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChwYXJhbV80LCBwYXJhbV81LCBwYXJhbV82LCBwYXJhbV83KTsKCXJldHVybiBjbGFtcChjaXJjbGVfb3V0ZXIgLSBjaXJjbGVfaW5uZXIsIDAuMCwgMS4wKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90cmlhbmdsZV9ub2lzZV9TMV9jMChpbm91dCBmbG9hdDIgbikgCnsKCW4gPSBmcmFjdChuICogZmxvYXQyKDUuMzk4NywgNS40NDIxKSk7CgluICs9IGZsb2F0Mihkb3Qobi55eCwgbiArIGZsb2F0MigyMS41MzUxLCAxNC4zMTM3KSkpOwoJZmxvYXQgeHkgPSBuLnggKiBuLnk7CglyZXR1cm4gKGZyYWN0KHh5ICogOTUuNDMwNykgKyBmcmFjdCh4eSAqIDc1LjA0OTYxKSkgLSAxLjA7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKGZsb2F0IHYsIGZsb2F0IGwsIGZsb2F0IGgpIAp7CglyZXR1cm4gc3RlcChsLCB2KSAqICgxLjAgLSBzdGVwKGgsIHYpKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zcGFya2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQgdCkgCnsKCWZsb2F0MiBwYXJhbSA9IHV2OwoJZmxvYXQgXzI0MiA9IEZMVF9mbHV0dGVyX2xvY2FsX3RyaWFuZ2xlX25vaXNlX1MxX2MwKHBhcmFtKTsKCWZsb2F0IG4gPSBfMjQyOwoJZmxvYXQgcGFyYW1fMSA9IG47CglmbG9hdCBwYXJhbV8yID0gMC4wOwoJZmxvYXQgcGFyYW1fMyA9IDAuMDU7CglmbG9hdCBzID0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMpOwoJZmxvYXQgcGFyYW1fNCA9IG4gKyBzaW4oMy4xNDE1OTI3NCAqICh0ICsgMC4zNSkpOwoJZmxvYXQgcGFyYW1fNSA9IDAuMTsKCWZsb2F0IHBhcmFtXzYgPSAwLjE1OwoJcyArPSBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAocGFyYW1fNCwgcGFyYW1fNSwgcGFyYW1fNik7CglmbG9hdCBwYXJhbV83ID0gbiArIHNpbigzLjE0MTU5Mjc0ICogKHQgKyAwLjcpKTsKCWZsb2F0IHBhcmFtXzggPSAwLjI7CglmbG9hdCBwYXJhbV85ID0gMC4yNTsKCXMgKz0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzcsIHBhcmFtXzgsIHBhcmFtXzkpOwoJZmxvYXQgcGFyYW1fMTAgPSBuICsgc2luKDMuMTQxNTkyNzQgKiAodCArIDEuMDUpKTsKCWZsb2F0IHBhcmFtXzExID0gMC4zOwoJZmxvYXQgcGFyYW1fMTIgPSAwLjM1OwoJcyArPSBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAocGFyYW1fMTAsIHBhcmFtXzExLCBwYXJhbV8xMik7CglyZXR1cm4gY2xhbXAocywgMC4wLCAxLjApICogMC41NTsKfQp2b2lkIEZMVF9tYWluX1MxX2MwKCkgCnsKCXVfYWxwaGFfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLng7Cgl1X3NwYXJrbGVfYWxwaGFfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLnk7Cgl1X2JsdXJfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLno7Cgl1X3JhZGl1c19zY2FsZV9TMV9jMCA9IHVfY29tcG9zaXRlXzFfUzFfYzAudzsKCWZsb2F0MiBwID0gRkxUX2ZsdXR0ZXJfbG9jYWxfRmx1dHRlckZyYWdDb29yZF9TMV9jMCgpOwoJZmxvYXQyIHV2XzEgPSBwICogdV9yZXNvbHV0aW9uX3NjYWxlX1MxX2MwOwoJZmxvYXQyIGRlbnNpdHlfdXYgPSB1dl8xIC0gbW9kKHAsIHVfbm9pc2Vfc2NhbGVfUzFfYzApOwoJZmxvYXQgcmFkaXVzID0gdV9tYXhfcmFkaXVzX1MxX2MwICogdV9yYWRpdXNfc2NhbGVfUzFfYzA7CglmbG9hdDIgcGFyYW1fMTMgPSB1dl8xOwoJZmxvYXQgdHVyYnVsZW5jZSA9IEZMVF9mbHV0dGVyX2xvY2FsX3R1cmJ1bGVuY2VfUzFfYzAocGFyYW1fMTMpOwoJZmxvYXQyIHBhcmFtXzE0ID0gcDsKCWZsb2F0MiBwYXJhbV8xNSA9IHVfY2VudGVyX1MxX2MwOwoJZmxvYXQgcGFyYW1fMTYgPSByYWRpdXM7CglmbG9hdCBwYXJhbV8xNyA9IDAuMDUgKiB1X21heF9yYWRpdXNfUzFfYzA7CglmbG9hdCBwYXJhbV8xOCA9IHVfYmx1cl9TMV9jMDsKCWZsb2F0IHJpbmcgPSBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X3JpbmdfUzFfYzAocGFyYW1fMTQsIHBhcmFtXzE1LCBwYXJhbV8xNiwgcGFyYW1fMTcsIHBhcmFtXzE4KTsKCWZsb2F0MiBwYXJhbV8xOSA9IGRlbnNpdHlfdXY7CglmbG9hdCBwYXJhbV8yMCA9IHVfbm9pc2VfcGhhc2VfUzFfYzA7CglmbG9hdCBzcGFya2xlID0gKChGTFRfZmx1dHRlcl9sb2NhbF9zcGFya2xlX1MxX2MwKHBhcmFtXzE5LCBwYXJhbV8yMCkgKiByaW5nKSAqIHR1cmJ1bGVuY2UpICogdV9zcGFya2xlX2FscGhhX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzIxID0gcDsKCWZsb2F0MiBwYXJhbV8yMiA9IHVfY2VudGVyX1MxX2MwOwoJZmxvYXQgcGFyYW1fMjMgPSByYWRpdXM7CglmbG9hdCBwYXJhbV8yNCA9IHVfYmx1cl9TMV9jMDsKCWZsb2F0IHdhdmVfYWxwaGEgPSAoRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW1fMjEsIHBhcmFtXzIyLCBwYXJhbV8yMywgcGFyYW1fMjQpICogdV9hbHBoYV9TMV9jMCkgKiB1X2NvbG9yX1MxX2MwLnc7CglmbG9hdDQgd2F2ZV9jb2xvciA9IGZsb2F0NCh1X2NvbG9yX1MxX2MwLnh5eiAqIHdhdmVfYWxwaGEsIHdhdmVfYWxwaGEpOwoJZnJhZ0NvbG9yX1MxX2MwID0gbWl4KHdhdmVfY29sb3IsIGZsb2F0NCgxLjApLCBmbG9hdDQoc3BhcmtsZSkpOwp9CmhhbGY0IHJ1bnRpbWVfc2hhZGVyX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJZmxvYXQyIF90bXBfMV9jb29yZHMgPSB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKCWZsdXR0ZXJfRnJhZ0Nvb3JkX1MxX2MwID0gZmxvYXQ0KF90bXBfMV9jb29yZHMsIDAuMCwgMC4wKTsKCUZMVF9tYWluX1MxX2MwKCk7CglyZXR1cm4gaGFsZjQoaGFsZjQoZnJhZ0NvbG9yX1MxX2MwKSk7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBydW50aW1lX3NoYWRlcl9TMV9jMChfaW5wdXQpOwp9CmhhbGY0IENpcmN1bGFyUlJlY3RfUzIoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MyLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MyLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CgloYWxmIGFscGhhID0gaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzIueCAtIGxlbmd0aChkeHkpKSk7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWZsb2F0IGNvdmVyYWdlID0gdmNvdmVyYWdlX1MwOwoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChjb3ZlcmFnZSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBNYXRyaXhFZmZlY3RfUzEob3V0cHV0Q29sb3JfUzApOwoJaGFsZjQgb3V0cHV0X1MyOwoJb3V0cHV0X1MyID0gQ2lyY3VsYXJSUmVjdF9TMihvdXRwdXRDb3ZlcmFnZV9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0X1MxICogb3V0cHV0X1MyOwoJfQp9CgAAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAHBvc2l0aW9uCAAAAGNvdmVyYWdlBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","GYQAAAAAAAMAADAAAIOAAAH677776IZOCAAP577777777777777777YBAAAAAAAAAAADAAYAAAACAAAAAAACCAYAAA":"DAAAAExTS1MaAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgcG9zaXRpb247CmluIGhhbGY0IGNvbG9yOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2Y29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAAVwEAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQpub3BlcnNwZWN0aXZlIGluIGhhbGY0IHZjb2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAIAAAAcG9zaXRpb24FAAAAY29sb3IAAAAAAAAA","GZIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAHIBIA5HZ2CAAAAAAAAAACAAAAASAEAAQAAAAAUCCQAQQGAAAAAAAAAAAGMAAAAAAAIAAAAAQGIAAAAAAA":"DAAAAExTS1POAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzA7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfM19TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzFfYzApICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAAAAYAMAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzA7CnNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMTsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc18zX1MwOwpoYWxmNCBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzEsIHZUcmFuc2Zvcm1lZENvb3Jkc18zX1MwKTsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzBfYzAoX2lucHV0KTsKfQpoYWxmNCBEaXNhYmxlQ292ZXJhZ2VBc0FscGhhX1MxKGhhbGY0IF9pbnB1dCkgCnsKCV9pbnB1dCA9IE1hdHJpeEVmZmVjdF9TMV9jMChfaW5wdXQpOwoJaGFsZjQgX3RtcF8wX2luQ29sb3IgPSBfaW5wdXQ7CglyZXR1cm4gaGFsZjQoX2lucHV0KTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IERpc2FibGVDb3ZlcmFnZUFzQWxwaGFfUzEob3V0cHV0Q29sb3JfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","GZIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAJIBAGMVUOTUABAAAAAAAIAAAAAWFBIEMVUOTUAAAAAAAAAIAAAACICAACAAAAACQIKACCAYAAAAAAAAAAAZQAAAAAABAAAAACAZAAAAAAA":"DAAAAExTS1PIAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfMl9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzEpICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAKkFAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKY29uc3QgaW50IGtNYXhMb29wTGltaXRfUzFfYzAgPSA4Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzBfYzA7CnVuaWZvcm0gaGFsZjQgdW9mZnNldHNBbmRLZXJuZWxfUzFfYzBbMTRdOwp1bmlmb3JtIGhhbGYyIHVkaXJfUzFfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MxOwpub3BlcnNwZWN0aXZlIGluIGhhbGY0IHZjb2xvcl9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CmhhbGY0IFRleHR1cmVFZmZlY3RfUzFfYzBfYzBfYzAoaGFsZjQgX2lucHV0LCBmbG9hdDIgX2Nvb3JkcykgCnsKCXJldHVybiBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzEsIF9jb29yZHMpOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMV9jMF9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzBfYzBfYzAoX2lucHV0LCBmbG9hdDN4Mih1bWF0cml4X1MxX2MwX2MwKSAqIF9jb29yZHMueHkxKTsKfQpoYWxmNCBydW50aW1lX3NoYWRlcl9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzBfaW5Db2xvciA9IF9pbnB1dDsKCWZsb2F0MiBfdG1wXzFfY29vcmRzID0gdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CgloYWxmNCBzdW0gPSBoYWxmNCgwLjApOwoJZm9yIChpbnQgaSA9IDA7aSA8IGtNYXhMb29wTGltaXRfUzFfYzA7ICsraSkgCgl7CgkJaGFsZjQgcyA9IHVvZmZzZXRzQW5kS2VybmVsX1MxX2MwW2ldOwoJCXN1bSArPSBzLnkgKiBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoX3RtcF8wX2luQ29sb3IsIF90bXBfMV9jb29yZHMgKyBmbG9hdDIocy54ICogdWRpcl9TMV9jMCkpOwoJCXN1bSArPSBzLncgKiBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoX3RtcF8wX2luQ29sb3IsIF90bXBfMV9jb29yZHMgKyBmbG9hdDIocy56ICogdWRpcl9TMV9jMCkpOwoJfQoJcmV0dXJuIGhhbGY0KHN1bSk7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBydW50aW1lX3NoYWRlcl9TMV9jMChfaW5wdXQpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gTWF0cml4RWZmZWN0X1MxKG91dHB1dENvbG9yX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRfUzEgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAgAAABwb3NpdGlvbgUAAABjb2xvcgAAAAoAAABsb2NhbENvb3JkAAAAAAAA","GZIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAJIBAGMVUOTUABAAADAMAIAAAAAWFBIEMVUOTUAAAAADAMAIAAAACI2DACAAAAACQIKACCAYAAYDAAAAAAAZQAAAAAABAAAAACAZAAAAAAA":"DAAAAExTS1PIAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfMl9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzEpICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAFcIAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKY29uc3QgaW50IGtNYXhMb29wTGltaXRfUzFfYzAgPSA4Owp1bmlmb3JtIGZsb2F0NCB1c3Vic2V0X1MxX2MwX2MwX2MwOwp1bmlmb3JtIGZsb2F0NCB1Y2xhbXBfUzFfYzBfYzBfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMDsKdW5pZm9ybSBoYWxmNCB1b2Zmc2V0c0FuZEtlcm5lbF9TMV9jMFsxNF07CnVuaWZvcm0gaGFsZjIgdWRpcl9TMV9jMDsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7Cm5vcGVyc3BlY3RpdmUgaW4gaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMF9jMF9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJZmxvYXQyIGluQ29vcmQgPSBfY29vcmRzOwoJZmxvYXQyIHN1YnNldENvb3JkOwoJewoJCWZsb2F0IHcgPSB1c3Vic2V0X1MxX2MwX2MwX2MwLnogLSB1c3Vic2V0X1MxX2MwX2MwX2MwLng7CgkJZmxvYXQgdzIgPSAyICogdzsKCQlmbG9hdCBtID0gbW9kKGluQ29vcmQueCAtIHVzdWJzZXRfUzFfYzBfYzBfYzAueCwgdzIpOwoJCXN1YnNldENvb3JkLnggPSBtaXgobSwgdzIgLSBtLCBzdGVwKHcsIG0pKSArIHVzdWJzZXRfUzFfYzBfYzBfYzAueDsKCX0KCXsKCQlmbG9hdCB3ID0gdXN1YnNldF9TMV9jMF9jMF9jMC53IC0gdXN1YnNldF9TMV9jMF9jMF9jMC55OwoJCWZsb2F0IHcyID0gMiAqIHc7CgkJZmxvYXQgbSA9IG1vZChpbkNvb3JkLnkgLSB1c3Vic2V0X1MxX2MwX2MwX2MwLnksIHcyKTsKCQlzdWJzZXRDb29yZC55ID0gbWl4KG0sIHcyIC0gbSwgc3RlcCh3LCBtKSkgKyB1c3Vic2V0X1MxX2MwX2MwX2MwLnk7Cgl9CglmbG9hdDIgY2xhbXBlZENvb3JkOwoJY2xhbXBlZENvb3JkID0gY2xhbXAoc3Vic2V0Q29vcmQsIHVjbGFtcF9TMV9jMF9jMF9jMC54eSwgdWNsYW1wX1MxX2MwX2MwX2MwLnp3KTsKCWhhbGY0IHRleHR1cmVDb2xvciA9IHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMSwgY2xhbXBlZENvb3JkKTsKCXJldHVybiB0ZXh0dXJlQ29sb3I7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxX2MwX2MwKGhhbGY0IF9pbnB1dCwgZmxvYXQyIF9jb29yZHMpIAp7CglyZXR1cm4gVGV4dHVyZUVmZmVjdF9TMV9jMF9jMF9jMChfaW5wdXQsIGZsb2F0M3gyKHVtYXRyaXhfUzFfYzBfYzApICogX2Nvb3Jkcy54eTEpOwp9CmhhbGY0IHJ1bnRpbWVfc2hhZGVyX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJZmxvYXQyIF90bXBfMV9jb29yZHMgPSB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKCWhhbGY0IHN1bSA9IGhhbGY0KDAuMCk7Cglmb3IgKGludCBpID0gMDtpIDwga01heExvb3BMaW1pdF9TMV9jMDsgKytpKSAKCXsKCQloYWxmNCBzID0gdW9mZnNldHNBbmRLZXJuZWxfUzFfYzBbaV07CgkJc3VtICs9IHMueSAqIE1hdHJpeEVmZmVjdF9TMV9jMF9jMChfdG1wXzBfaW5Db2xvciwgX3RtcF8xX2Nvb3JkcyArIGZsb2F0MihzLnggKiB1ZGlyX1MxX2MwKSk7CgkJc3VtICs9IHMudyAqIE1hdHJpeEVmZmVjdF9TMV9jMF9jMChfdG1wXzBfaW5Db2xvciwgX3RtcF8xX2Nvb3JkcyArIGZsb2F0MihzLnogKiB1ZGlyX1MxX2MwKSk7Cgl9CglyZXR1cm4gaGFsZjQoc3VtKTsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIHJ1bnRpbWVfc2hhZGVyX1MxX2MwKF9pbnB1dCk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBNYXRyaXhFZmZlY3RfUzEob3V0cHV0Q29sb3JfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAgAAABwb3NpdGlvbgUAAABjb2xvcgAAAAoAAABsb2NhbENvb3JkAAAAAAAA","GYQACAAAAAMAADAAAIOAAAH677776IZOCAAP577777777777777777YBAAAAAAAAAAADAAYAAAACAAAAAAACCAYAAA":"DAAAAExTS1MaAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgcG9zaXRpb247CmluIGhhbGY0IGNvbG9yOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2Y29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAAVwEAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQpub3BlcnNwZWN0aXZlIGluIGhhbGY0IHZjb2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAIAAAAcG9zaXRpb24FAAAAY29sb3IAAAAAAAAA","GXQAAGAABBYAAAEIXBAAAGEAMAAAAAAAAAAAAAAAYAGAAAAAQAAAAAAAQQGAAAAA":"DAAAAExTS1OYAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgaW5Qb3NpdGlvbjsKaW4gaGFsZjQgaW5Db2xvcjsKaW4gZmxvYXQ0IGluUXVhZEVkZ2U7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0NCB2UXVhZEVkZ2VfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBRdWFkRWRnZQoJdlF1YWRFZGdlX1MwID0gaW5RdWFkRWRnZTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247Cglza19Qb3NpdGlvbiA9IF90bXBfMF9pblBvc2l0aW9uLnh5MDE7Cn0KBAAAAF4DAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdDQgdlF1YWRFZGdlX1MwOwpub3BlcnNwZWN0aXZlIGluIGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZEVkZ2UKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWhhbGYgZWRnZUFscGhhOwoJaGFsZjIgZHV2ZHggPSBoYWxmMihkRmR4KHZRdWFkRWRnZV9TMC54eSkpOwoJaGFsZjIgZHV2ZHkgPSBoYWxmMihkRmR5KHZRdWFkRWRnZV9TMC54eSkpOwoJaWYgKHZRdWFkRWRnZV9TMC56ID4gMC4wICYmIHZRdWFkRWRnZV9TMC53ID4gMC4wKSAKCXsKCQllZGdlQWxwaGEgPSBoYWxmKG1pbihtaW4odlF1YWRFZGdlX1MwLnosIHZRdWFkRWRnZV9TMC53KSArIDAuNSwgMS4wKSk7Cgl9CgllbHNlIAoJewoJCWhhbGYyIGdGID0gaGFsZjIoaGFsZigyLjAqdlF1YWRFZGdlX1MwLngqZHV2ZHgueCAtIGR1dmR4LnkpLCAgICAgICAgICAgICAgICAgaGFsZigyLjAqdlF1YWRFZGdlX1MwLngqZHV2ZHkueCAtIGR1dmR5LnkpKTsKCQllZGdlQWxwaGEgPSBoYWxmKHZRdWFkRWRnZV9TMC54KnZRdWFkRWRnZV9TMC54IC0gdlF1YWRFZGdlX1MwLnkpOwoJCWVkZ2VBbHBoYSA9IHNhdHVyYXRlKDAuNSAtIGVkZ2VBbHBoYSAvIGxlbmd0aChnRikpOwoJfQoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChlZGdlQWxwaGEpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAEAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAoAAABpblBvc2l0aW9uAAAHAAAAaW5Db2xvcgAKAAAAaW5RdWFkRWRnZQAAAAAAAA==","GYJAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAQAAAAAAQQGABZAA6IAAAAACAAAAAADGAAAAAAAEAAAAAIDEAAAAAAA":"DAAAAExTS1MwAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgcG9zaXRpb247CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmxvY2FsQ29vcmRfUzAgPSBsb2NhbENvb3JkOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgEAAAB+AwAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHVpbm5lclJlY3RfUzE7CnVuaWZvcm0gaGFsZjIgdXJhZGl1c1BsdXNIYWxmX1MxOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQyIHZsb2NhbENvb3JkX1MwOwpoYWxmNCBDaXJjdWxhclJSZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCWZsb2F0MiBkeHkwID0gdWlubmVyUmVjdF9TMS5MVCAtIHNrX0ZyYWdDb29yZC54eTsKCWZsb2F0MiBkeHkxID0gc2tfRnJhZ0Nvb3JkLnh5IC0gdWlubmVyUmVjdF9TMS5SQjsKCWZsb2F0MiBkeHkgPSBtYXgobWF4KGR4eTAsIGR4eTEpLCAwLjApOwoJaGFsZiBhbHBoYSA9IGhhbGYoc2F0dXJhdGUodXJhZGl1c1BsdXNIYWxmX1MxLnggLSBsZW5ndGgoZHh5KSkpOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwID0gaGFsZjQoMSk7CglmbG9hdDIgdGV4Q29vcmQ7Cgl0ZXhDb29yZCA9IHZsb2NhbENvb3JkX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSAoYmxlbmRfbW9kdWxhdGUoc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB0ZXhDb29yZCksIGhhbGY0KDEpKSk7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQ2lyY3VsYXJSUmVjdF9TMShvdXRwdXRDb3ZlcmFnZV9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAAABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgoAAABsb2NhbENvb3JkAAAAAAAA","BYIBQAAABQAAIAABBYAAAEIXBAAP777777777777AAAAAAAAAAAABGABAAAAAEAAAAAIBEABAAAAA":"DAAAAExTS1OJAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgaW5Qb3NpdGlvbjsKaW4gaGFsZjQgaW5Db2xvcjsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBEZWZhdWx0R2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IGNvbG9yID0gaW5Db2xvcjsKCXZjb2xvcl9TMCA9IGNvbG9yOwoJZmxvYXQyIF90bXBfMV9pblBvc2l0aW9uID0gaW5Qb3NpdGlvbjsKCWZsb2F0MiBfdG1wXzNfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247Cglza19Qb3NpdGlvbiA9IF90bXBfMV9pblBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAAAFEBAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2Y29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBEZWZhdWx0R2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IAAAAAAA==","GZIACAAAABQAAGAAAQ4AAAAAGQQAARC4GAAAIOCAAD6P7777777777YDAAAAAAAAAAAJQBBYGQ467YIAAAAAAQAAAAAMACTRNBZN5QYBAAAAAAAAAAAIAALIAAAAAGFM37JKEAAAAAMAAAAAIAAAAAAAMBCQN25XWQUAAAAAAYAAAAAAAAAABGABAAAAAEAAAAAIBEABAAAAA":"DAAAAExTS1M7AgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQgY292ZXJhZ2U7CmluIGhhbGY0IGNvbG9yOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdCB2Y292ZXJhZ2VfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDIgcG9zaXRpb24gPSBwb3NpdGlvbi54eTsKCXZjb2xvcl9TMCA9IGNvbG9yOwoJdmNvdmVyYWdlX1MwID0gY292ZXJhZ2U7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgABAAAAKh8AACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQpmbG9hdDQgZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzA7CmZsb2F0NCBmcmFnQ29sb3JfUzFfYzA7CmZsb2F0IHVfYWxwaGFfUzFfYzA7CmZsb2F0IHVfc3BhcmtsZV9hbHBoYV9TMV9jMDsKZmxvYXQgdV9ibHVyX1MxX2MwOwpmbG9hdCB1X3JhZGl1c19zY2FsZV9TMV9jMDsKY29uc3QgaW50IGtGaWxsQUFfUzJfYzAgPSAxOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQldfUzJfYzAgPSAyOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQUFfUzJfYzAgPSAzOwp1bmlmb3JtIGZsb2F0NCB1X2NvbG9yX1MxX2MwOwp1bmlmb3JtIGZsb2F0NCB1X2NvbXBvc2l0ZV8xX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NlbnRlcl9TMV9jMDsKdW5pZm9ybSBmbG9hdCB1X21heF9yYWRpdXNfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcmVzb2x1dGlvbl9zY2FsZV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9ub2lzZV9zY2FsZV9TMV9jMDsKdW5pZm9ybSBmbG9hdCB1X25vaXNlX3BoYXNlX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NpcmNsZTFfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2lyY2xlMl9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jaXJjbGUzX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3JvdGF0aW9uMV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yb3RhdGlvbjJfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcm90YXRpb24zX1MxX2MwOwp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CnVuaWZvcm0gZmxvYXQ0IHVjaXJjbGVfUzJfYzA7Cm5vcGVyc3BlY3RpdmUgaW4gaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0IHZjb3ZlcmFnZV9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CmZsb2F0MiBGTFRfZmx1dHRlcl9sb2NhbF9GbHV0dGVyRnJhZ0Nvb3JkX1MxX2MwKCk7CmZsb2F0MngyIEZMVF9mbHV0dGVyX2xvY2FsX3JvdGF0ZTJkX1MxX2MwKGZsb2F0MiByYWQpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCBibHVyKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAoZmxvYXQyIHJlc29sdXRpb24sIGlub3V0IGZsb2F0MiBwLCBmbG9hdDIgeHksIGZsb2F0MiByb3RhdGlvbiwgZmxvYXQgY2VsbF9kaWFtZXRlcik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3R1cmJ1bGVuY2VfUzFfYzAoZmxvYXQyIHV2KTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9yaW5nX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IHRoaWNrbmVzcywgZmxvYXQgYmx1cik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RyaWFuZ2xlX25vaXNlX1MxX2MwKGlub3V0IGZsb2F0MiBuKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKGZsb2F0IHYsIGZsb2F0IGwsIGZsb2F0IGgpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zcGFya2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQgdCk7CnZvaWQgRkxUX21haW5fUzFfYzAoKTsKZmxvYXQyIEZMVF9mbHV0dGVyX2xvY2FsX0ZsdXR0ZXJGcmFnQ29vcmRfUzFfYzAoKSAKewoJcmV0dXJuIGZsdXR0ZXJfRnJhZ0Nvb3JkX1MxX2MwLnh5Owp9CmZsb2F0MngyIEZMVF9mbHV0dGVyX2xvY2FsX3JvdGF0ZTJkX1MxX2MwKGZsb2F0MiByYWQpIAp7CglyZXR1cm4gZmxvYXQyeDIocmFkLngsIC1yYWQueSwgcmFkLnksIHJhZC54KTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCBibHVyKSAKewoJZmxvYXQgYmx1cl9oYWxmID0gYmx1ciAqIDAuNTsKCWZsb2F0IGQgPSBkaXN0YW5jZSh1diwgeHkpOwoJcmV0dXJuIDEuMCAtIHNtb290aHN0ZXAoMS4wIC0gYmx1cl9oYWxmLCAxLjAgKyBibHVyX2hhbGYsIGQgLyByYWRpdXMpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKGZsb2F0MiByZXNvbHV0aW9uLCBpbm91dCBmbG9hdDIgcCwgZmxvYXQyIHh5LCBmbG9hdDIgcm90YXRpb24sIGZsb2F0IGNlbGxfZGlhbWV0ZXIpIAp7CglmbG9hdDIgcGFyYW0gPSByb3RhdGlvbjsKCXAgPSBGTFRfZmx1dHRlcl9sb2NhbF9yb3RhdGUyZF9TMV9jMChwYXJhbSkgKiAoeHkgLSBwKSArIHh5OwoJcCA9IG1vZChwLCBmbG9hdDIoY2VsbF9kaWFtZXRlcikpIC8gcmVzb2x1dGlvbjsKCWZsb2F0IGNlbGxfdXYgPSAoY2VsbF9kaWFtZXRlciAvIHJlc29sdXRpb24ueSkgKiAwLjU7CglmbG9hdCByID0gMC42NSAqIGNlbGxfdXY7CglmbG9hdDIgcGFyYW1fMSA9IHA7CglmbG9hdDIgcGFyYW1fMiA9IGZsb2F0MihjZWxsX3V2KTsKCWZsb2F0IHBhcmFtXzMgPSByOwoJZmxvYXQgcGFyYW1fNCA9IHIgKiA1MC4wOwoJcmV0dXJuIEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMsIHBhcmFtXzQpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3R1cmJ1bGVuY2VfUzFfYzAoZmxvYXQyIHV2KSAKewoJZmxvYXQyIHV2X3NjYWxlID0gdXYgKiBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbSA9IGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtXzEgPSB1dl9zY2FsZTsKCWZsb2F0MiBwYXJhbV8yID0gdV9jaXJjbGUxX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzMgPSB1X3JvdGF0aW9uMV9TMV9jMDsKCWZsb2F0IHBhcmFtXzQgPSAwLjE3OwoJZmxvYXQgXzMxOSA9IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKHBhcmFtLCBwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zLCBwYXJhbV80KTsKCWZsb2F0IGcxID0gXzMxOTsKCWZsb2F0MiBwYXJhbV81ID0gZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW1fNiA9IHV2X3NjYWxlOwoJZmxvYXQyIHBhcmFtXzcgPSB1X2NpcmNsZTJfUzFfYzA7CglmbG9hdDIgcGFyYW1fOCA9IHVfcm90YXRpb24yX1MxX2MwOwoJZmxvYXQgcGFyYW1fOSA9IDAuMjsKCWZsb2F0IF8zMzEgPSBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChwYXJhbV81LCBwYXJhbV82LCBwYXJhbV83LCBwYXJhbV84LCBwYXJhbV85KTsKCWZsb2F0IGcyID0gXzMzMTsKCWZsb2F0MiBwYXJhbV8xMCA9IGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtXzExID0gdXZfc2NhbGU7CglmbG9hdDIgcGFyYW1fMTIgPSB1X2NpcmNsZTNfUzFfYzA7CglmbG9hdDIgcGFyYW1fMTMgPSB1X3JvdGF0aW9uM19TMV9jMDsKCWZsb2F0IHBhcmFtXzE0ID0gMC4yNzU7CglmbG9hdCBfMzQ0ID0gRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAocGFyYW1fMTAsIHBhcmFtXzExLCBwYXJhbV8xMiwgcGFyYW1fMTMsIHBhcmFtXzE0KTsKCWZsb2F0IGczID0gXzM0NDsKCWZsb2F0IHYgPSAoKGcxICogZzEgKyBnMikgLSBnMykgKiAwLjU7CglyZXR1cm4gY2xhbXAoMC40NSArIDAuOCAqIHYsIDAuMCwgMS4wKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X3JpbmdfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgdGhpY2tuZXNzLCBmbG9hdCBibHVyKSAKewoJZmxvYXQyIHBhcmFtID0gdXY7CglmbG9hdDIgcGFyYW1fMSA9IHh5OwoJZmxvYXQgcGFyYW1fMiA9IHJhZGl1cyArIHRoaWNrbmVzczsKCWZsb2F0IHBhcmFtXzMgPSBibHVyOwoJZmxvYXQgY2lyY2xlX291dGVyID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW0sIHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMpOwoJZmxvYXQyIHBhcmFtXzQgPSB1djsKCWZsb2F0MiBwYXJhbV81ID0geHk7CglmbG9hdCBwYXJhbV82ID0gbWF4KHJhZGl1cyAtIHRoaWNrbmVzcywgMC4wKTsKCWZsb2F0IHBhcmFtXzcgPSBibHVyOwoJZmxvYXQgY2lyY2xlX2lubmVyID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW1fNCwgcGFyYW1fNSwgcGFyYW1fNiwgcGFyYW1fNyk7CglyZXR1cm4gY2xhbXAoY2lyY2xlX291dGVyIC0gY2lyY2xlX2lubmVyLCAwLjAsIDEuMCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHJpYW5nbGVfbm9pc2VfUzFfYzAoaW5vdXQgZmxvYXQyIG4pIAp7CgluID0gZnJhY3QobiAqIGZsb2F0Mig1LjM5ODcsIDUuNDQyMSkpOwoJbiArPSBmbG9hdDIoZG90KG4ueXgsIG4gKyBmbG9hdDIoMjEuNTM1MSwgMTQuMzEzNykpKTsKCWZsb2F0IHh5ID0gbi54ICogbi55OwoJcmV0dXJuIChmcmFjdCh4eSAqIDk1LjQzMDcpICsgZnJhY3QoeHkgKiA3NS4wNDk2MSkpIC0gMS4wOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChmbG9hdCB2LCBmbG9hdCBsLCBmbG9hdCBoKSAKewoJcmV0dXJuIHN0ZXAobCwgdikgKiAoMS4wIC0gc3RlcChoLCB2KSk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc3BhcmtsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0IHQpIAp7CglmbG9hdDIgcGFyYW0gPSB1djsKCWZsb2F0IF8yNDIgPSBGTFRfZmx1dHRlcl9sb2NhbF90cmlhbmdsZV9ub2lzZV9TMV9jMChwYXJhbSk7CglmbG9hdCBuID0gXzI0MjsKCWZsb2F0IHBhcmFtXzEgPSBuOwoJZmxvYXQgcGFyYW1fMiA9IDAuMDsKCWZsb2F0IHBhcmFtXzMgPSAwLjA1OwoJZmxvYXQgcyA9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zKTsKCWZsb2F0IHBhcmFtXzQgPSBuICsgc2luKDMuMTQxNTkyNzQgKiAodCArIDAuMzUpKTsKCWZsb2F0IHBhcmFtXzUgPSAwLjE7CglmbG9hdCBwYXJhbV82ID0gMC4xNTsKCXMgKz0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzQsIHBhcmFtXzUsIHBhcmFtXzYpOwoJZmxvYXQgcGFyYW1fNyA9IG4gKyBzaW4oMy4xNDE1OTI3NCAqICh0ICsgMC43KSk7CglmbG9hdCBwYXJhbV84ID0gMC4yOwoJZmxvYXQgcGFyYW1fOSA9IDAuMjU7CglzICs9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV83LCBwYXJhbV84LCBwYXJhbV85KTsKCWZsb2F0IHBhcmFtXzEwID0gbiArIHNpbigzLjE0MTU5Mjc0ICogKHQgKyAxLjA1KSk7CglmbG9hdCBwYXJhbV8xMSA9IDAuMzsKCWZsb2F0IHBhcmFtXzEyID0gMC4zNTsKCXMgKz0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzEwLCBwYXJhbV8xMSwgcGFyYW1fMTIpOwoJcmV0dXJuIGNsYW1wKHMsIDAuMCwgMS4wKSAqIDAuNTU7Cn0Kdm9pZCBGTFRfbWFpbl9TMV9jMCgpIAp7Cgl1X2FscGhhX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC54OwoJdV9zcGFya2xlX2FscGhhX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC55OwoJdV9ibHVyX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC56OwoJdV9yYWRpdXNfc2NhbGVfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLnc7CglmbG9hdDIgcCA9IEZMVF9mbHV0dGVyX2xvY2FsX0ZsdXR0ZXJGcmFnQ29vcmRfUzFfYzAoKTsKCWZsb2F0MiB1dl8xID0gcCAqIHVfcmVzb2x1dGlvbl9zY2FsZV9TMV9jMDsKCWZsb2F0MiBkZW5zaXR5X3V2ID0gdXZfMSAtIG1vZChwLCB1X25vaXNlX3NjYWxlX1MxX2MwKTsKCWZsb2F0IHJhZGl1cyA9IHVfbWF4X3JhZGl1c19TMV9jMCAqIHVfcmFkaXVzX3NjYWxlX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzEzID0gdXZfMTsKCWZsb2F0IHR1cmJ1bGVuY2UgPSBGTFRfZmx1dHRlcl9sb2NhbF90dXJidWxlbmNlX1MxX2MwKHBhcmFtXzEzKTsKCWZsb2F0MiBwYXJhbV8xNCA9IHA7CglmbG9hdDIgcGFyYW1fMTUgPSB1X2NlbnRlcl9TMV9jMDsKCWZsb2F0IHBhcmFtXzE2ID0gcmFkaXVzOwoJZmxvYXQgcGFyYW1fMTcgPSAwLjA1ICogdV9tYXhfcmFkaXVzX1MxX2MwOwoJZmxvYXQgcGFyYW1fMTggPSB1X2JsdXJfUzFfYzA7CglmbG9hdCByaW5nID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9yaW5nX1MxX2MwKHBhcmFtXzE0LCBwYXJhbV8xNSwgcGFyYW1fMTYsIHBhcmFtXzE3LCBwYXJhbV8xOCk7CglmbG9hdDIgcGFyYW1fMTkgPSBkZW5zaXR5X3V2OwoJZmxvYXQgcGFyYW1fMjAgPSB1X25vaXNlX3BoYXNlX1MxX2MwOwoJZmxvYXQgc3BhcmtsZSA9ICgoRkxUX2ZsdXR0ZXJfbG9jYWxfc3BhcmtsZV9TMV9jMChwYXJhbV8xOSwgcGFyYW1fMjApICogcmluZykgKiB0dXJidWxlbmNlKSAqIHVfc3BhcmtsZV9hbHBoYV9TMV9jMDsKCWZsb2F0MiBwYXJhbV8yMSA9IHA7CglmbG9hdDIgcGFyYW1fMjIgPSB1X2NlbnRlcl9TMV9jMDsKCWZsb2F0IHBhcmFtXzIzID0gcmFkaXVzOwoJZmxvYXQgcGFyYW1fMjQgPSB1X2JsdXJfUzFfYzA7CglmbG9hdCB3YXZlX2FscGhhID0gKEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtXzIxLCBwYXJhbV8yMiwgcGFyYW1fMjMsIHBhcmFtXzI0KSAqIHVfYWxwaGFfUzFfYzApICogdV9jb2xvcl9TMV9jMC53OwoJZmxvYXQ0IHdhdmVfY29sb3IgPSBmbG9hdDQodV9jb2xvcl9TMV9jMC54eXogKiB3YXZlX2FscGhhLCB3YXZlX2FscGhhKTsKCWZyYWdDb2xvcl9TMV9jMCA9IG1peCh3YXZlX2NvbG9yLCBmbG9hdDQoMS4wKSwgZmxvYXQ0KHNwYXJrbGUpKTsKfQpoYWxmNCBydW50aW1lX3NoYWRlcl9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzBfaW5Db2xvciA9IF9pbnB1dDsKCWZsb2F0MiBfdG1wXzFfY29vcmRzID0gdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CglmbHV0dGVyX0ZyYWdDb29yZF9TMV9jMCA9IGZsb2F0NChfdG1wXzFfY29vcmRzLCAwLjAsIDAuMCk7CglGTFRfbWFpbl9TMV9jMCgpOwoJcmV0dXJuIGhhbGY0KGhhbGY0KGZyYWdDb2xvcl9TMV9jMCkpOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gcnVudGltZV9zaGFkZXJfUzFfYzAoX2lucHV0KTsKfQpoYWxmNCBDaXJjbGVfUzJfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF8yX2luQ29sb3IgPSBfaW5wdXQ7CgloYWxmIGQ7CglpZiAoaW50KDEpID09IGtJbnZlcnNlRmlsbEJXX1MyX2MwIHx8IGludCgxKSA9PSBrSW52ZXJzZUZpbGxBQV9TMl9jMCkgCgl7CgkJZCA9IGhhbGYoKGxlbmd0aCgodWNpcmNsZV9TMl9jMC54eSAtIHNrX0ZyYWdDb29yZC54eSkgKiB1Y2lyY2xlX1MyX2MwLncpIC0gMS4wKSAqIHVjaXJjbGVfUzJfYzAueik7Cgl9CgllbHNlIAoJewoJCWQgPSBoYWxmKCgxLjAgLSBsZW5ndGgoKHVjaXJjbGVfUzJfYzAueHkgLSBza19GcmFnQ29vcmQueHkpICogdWNpcmNsZV9TMl9jMC53KSkgKiB1Y2lyY2xlX1MyX2MwLnopOwoJfQoJcmV0dXJuIGhhbGY0KGhhbGY0KGludCgxKSA9PSBrRmlsbEFBX1MyX2MwIHx8IGludCgxKSA9PSBrSW52ZXJzZUZpbGxBQV9TMl9jMCA/IHNhdHVyYXRlKGQpIDogaGFsZihkID4gMC41KSkpOwp9CmhhbGY0IEJsZW5kX1MyKGhhbGY0IF9zcmMsIGhhbGY0IF9kc3QpIAp7CglyZXR1cm4gYmxlbmRfbW9kdWxhdGUoX3NyYywgQ2lyY2xlX1MyX2MwKF9zcmMpKTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJZmxvYXQgY292ZXJhZ2UgPSB2Y292ZXJhZ2VfUzA7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGNvdmVyYWdlKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IE1hdHJpeEVmZmVjdF9TMShvdXRwdXRDb2xvcl9TMCk7CgloYWxmNCBvdXRwdXRfUzI7CglvdXRwdXRfUzIgPSBCbGVuZF9TMihvdXRwdXRDb3ZlcmFnZV9TMCwgaGFsZjQoMSkpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dF9TMjsKCX0KfQoAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAHBvc2l0aW9uCAAAAGNvdmVyYWdlBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","GYQACAAAAAMAADAAAIOAAAH677776IZOCAAP577777777777777777YBAAAAAAAAAAADEAAGAAAAAAAAAIAAAAAPAIABAAAAABAGEAAAAEAAAABNARCAIAAAAAAAAAAAAAYAGAAAAAQAAAAAAAQQGAAAAA":"DAAAAExTS1O8AQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzBfYzA7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7Cm5vcGVyc3BlY3RpdmUgb3V0IGhhbGY0IHZjb2xvcl9TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc180X1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCXZjb2xvcl9TMCA9IGNvbG9yOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwoJewoJCXZUcmFuc2Zvcm1lZENvb3Jkc180X1MwID0gZmxvYXQzeDIodW1hdHJpeF9TMV9jMF9jMCkgKiBwb3NpdGlvbi54eTE7Cgl9Cn0KAAAAAI0DAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxX2MwX2MwOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7Cm5vcGVyc3BlY3RpdmUgaW4gaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfNF9TMDsKaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMF9jMF9jMChoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MxLCB2VHJhbnNmb3JtZWRDb29yZHNfNF9TMCkuMDAwcjsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzBfYzBfYzAoX2lucHV0KTsKfQpoYWxmNCBEZXZpY2VTcGFjZV9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gTWF0cml4RWZmZWN0X1MxX2MwX2MwKF9pbnB1dCk7Cn0KaGFsZjQgQmxlbmRfUzEoaGFsZjQgX3NyYywgaGFsZjQgX2RzdCkgCnsKCXJldHVybiBibGVuZF9kc3RfaW4oRGV2aWNlU3BhY2VfUzFfYzAoX3NyYyksIF9zcmMpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQmxlbmRfUzEob3V0cHV0Q292ZXJhZ2VfUzAsIGhhbGY0KDEpKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgUAAABjb2xvcgAAAAAAAAA=","GZIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAHIBK2VD3EOCAAAAAABUXHIMAQAAAAWSQ4HO4SAAAAAMAAAAAEBUEFLMJAIAAAQCI6KVAYAAAAAAAAAAAQAAEACUA2JT4HAIAAAADIIODXOJIBAAAGAAAAACAKAC5XEQEAAAAAEPF2SMAAAAAAAAIAAAACXUUGB3XUUAQAADAAAAAAABARO3SJCAAAAACGSZJWCAAAAAAAIAAAABLFBUEFLMJAIAAAAAAAAAAACIMVSTUFAEAAAAAIAAAAAWFBSHSVIGAAAAAAAAAAAAABEBAABAAAAADIEEQCEAAAAAAAAAAAQAMQAAAAAAAQAAAABAMQAAA":"DAAAAExTS1PaAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzBfYzBfYzE7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfNl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfNl9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzFfYzBfYzBfYzEpICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAABAAAAcQkAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQp1bmlmb3JtIGhhbGY0IHVzdGFydF9TMV9jMF9jMF9jMDsKdW5pZm9ybSBoYWxmNCB1ZW5kX1MxX2MwX2MwX2MwOwp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzBfYzBfYzE7CnVuaWZvcm0gaGFsZjQgdWxlZnRCb3JkZXJDb2xvcl9TMV9jMF9jMDsKdW5pZm9ybSBoYWxmNCB1cmlnaHRCb3JkZXJDb2xvcl9TMV9jMF9jMDsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxX2MxOwp1bmlmb3JtIGhhbGYgdXJhbmdlX1MxOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7Cm5vcGVyc3BlY3RpdmUgaW4gaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfNl9TMDsKaGFsZjQgU2luZ2xlSW50ZXJ2YWxDb2xvcml6ZXJfUzFfYzBfYzBfYzAoaGFsZjQgX2lucHV0LCBmbG9hdDIgX2Nvb3JkcykgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJZmxvYXQyIF90bXBfMV9jb29yZHMgPSBfY29vcmRzOwoJcmV0dXJuIGhhbGY0KG1peCh1c3RhcnRfUzFfYzBfYzBfYzAsIHVlbmRfUzFfYzBfYzBfYzAsIGhhbGYoX3RtcF8xX2Nvb3Jkcy54KSkpOwp9CmhhbGY0IExpbmVhckxheW91dF9TMV9jMF9jMF9jMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzJfaW5Db2xvciA9IF9pbnB1dDsKCWZsb2F0MiBfdG1wXzNfY29vcmRzID0gdlRyYW5zZm9ybWVkQ29vcmRzXzZfUzA7CglyZXR1cm4gaGFsZjQoaGFsZjQoaGFsZihfdG1wXzNfY29vcmRzLngpICsgMWUtMDUsIDEuMCwgMC4wLCAwLjApKTsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzFfYzBfYzBfYzEoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIExpbmVhckxheW91dF9TMV9jMF9jMF9jMV9jMChfaW5wdXQpOwp9CmhhbGY0IENsYW1wZWRHcmFkaWVudF9TMV9jMF9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzRfaW5Db2xvciA9IF9pbnB1dDsKCWhhbGY0IHQgPSBNYXRyaXhFZmZlY3RfUzFfYzBfYzBfYzEoX3RtcF80X2luQ29sb3IpOwoJaGFsZjQgb3V0Q29sb3I7CglpZiAoIWJvb2woaW50KDEpKSAmJiB0LnkgPCAwLjApIAoJewoJCW91dENvbG9yID0gaGFsZjQoMC4wKTsKCX0KCWVsc2UgaWYgKHQueCA8IDAuMCkgCgl7CgkJb3V0Q29sb3IgPSB1bGVmdEJvcmRlckNvbG9yX1MxX2MwX2MwOwoJfQoJZWxzZSBpZiAodC54ID4gMS4wKSAKCXsKCQlvdXRDb2xvciA9IHVyaWdodEJvcmRlckNvbG9yX1MxX2MwX2MwOwoJfQoJZWxzZSAKCXsKCQlvdXRDb2xvciA9IFNpbmdsZUludGVydmFsQ29sb3JpemVyX1MxX2MwX2MwX2MwKF90bXBfNF9pbkNvbG9yLCBmbG9hdDIoaGFsZjIodC54LCAwLjApKSk7Cgl9CglyZXR1cm4gaGFsZjQob3V0Q29sb3IpOwp9CmhhbGY0IERpc2FibGVDb3ZlcmFnZUFzQWxwaGFfUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJX2lucHV0ID0gQ2xhbXBlZEdyYWRpZW50X1MxX2MwX2MwKF9pbnB1dCk7CgloYWxmNCBfdG1wXzVfaW5Db2xvciA9IF9pbnB1dDsKCXJldHVybiBoYWxmNChfaW5wdXQpOwp9CmhhbGY0IFRleHR1cmVFZmZlY3RfUzFfYzFfYzAoaGFsZjQgX2lucHV0LCBmbG9hdDIgX2Nvb3JkcykgCnsKCXJldHVybiBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzEsIF9jb29yZHMpLjAwMHI7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxX2MxKGhhbGY0IF9pbnB1dCwgZmxvYXQyIF9jb29yZHMpIAp7CglyZXR1cm4gVGV4dHVyZUVmZmVjdF9TMV9jMV9jMChfaW5wdXQsIGZsb2F0M3gyKHVtYXRyaXhfUzFfYzEpICogX2Nvb3Jkcy54eTEpOwp9CmhhbGY0IERpdGhlcl9TMShoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzZfaW5Db2xvciA9IF9pbnB1dDsKCWhhbGY0IGNvbG9yID0gRGlzYWJsZUNvdmVyYWdlQXNBbHBoYV9TMV9jMChfdG1wXzZfaW5Db2xvcik7CgloYWxmIHZhbHVlID0gTWF0cml4RWZmZWN0X1MxX2MxKF90bXBfNl9pbkNvbG9yLCBza19GcmFnQ29vcmQueHkpLncgLSAwLjU7CglyZXR1cm4gaGFsZjQoaGFsZjQoY2xhbXAoY29sb3IueHl6ICsgdmFsdWUgKiB1cmFuZ2VfUzEsIDAuMCwgY29sb3IudyksIGNvbG9yLncpKTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IERpdGhlcl9TMShvdXRwdXRDb2xvcl9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0X1MxICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAIAAAAcG9zaXRpb24FAAAAY29sb3IAAAAKAAAAbG9jYWxDb29yZAAAAAAAAA==","GYJAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAQAAAAAAQQGAAZAABQAAAAAAAACAAAAADYCAAIAAAAAIBRAAAABAAAAALIEIQCAAAAAAAAAAAAAGABQAAAAEAAAAAAAEEBQAAAA":"DAAAAExTS1PSAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzBfYzA7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2bG9jYWxDb29yZF9TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc180X1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCXZsb2NhbENvb3JkX1MwID0gbG9jYWxDb29yZDsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfNF9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzFfYzBfYzApICogcG9zaXRpb24ueHkxOwoJfQp9CgAAAAAAACUEAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxX2MwX2MwOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzA7CnNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMTsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc180X1MwOwpoYWxmNCBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzEsIHZUcmFuc2Zvcm1lZENvb3Jkc180X1MwKS4wMDByOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMV9jMF9jMChoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gVGV4dHVyZUVmZmVjdF9TMV9jMF9jMF9jMChfaW5wdXQpOwp9CmhhbGY0IERldmljZVNwYWNlX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoX2lucHV0KTsKfQpoYWxmNCBCbGVuZF9TMShoYWxmNCBfc3JjLCBoYWxmNCBfZHN0KSAKewoJcmV0dXJuIGJsZW5kX2RzdF9pbihEZXZpY2VTcGFjZV9TMV9jMChfc3JjKSwgX3NyYyk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWZsb2F0MiB0ZXhDb29yZDsKCXRleENvb3JkID0gdmxvY2FsQ29vcmRfUzA7CglvdXRwdXRDb2xvcl9TMCA9IChibGVuZF9tb2R1bGF0ZShzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzAsIHRleENvb3JkKSwgaGFsZjQoMSkpKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBCbGVuZF9TMShvdXRwdXRDb3ZlcmFnZV9TMCwgaGFsZjQoMSkpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0X1MxOwoJfQp9CgAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACAAAAHBvc2l0aW9uCgAAAGxvY2FsQ29vcmQAAAAAAAA=","GZIACAAAABQAAGAAAQ4AAAAAGQQAARC4GAAAIOCAAD6P7777777777YDAAAAAAAAAAAJQBBYGQ467YIAAAAAAQAAAAAMACTRNBZN5QYBAAAAAAAAAAAIAAJQAAAAAAAANAAAAAHQVERARJYAAAABQAAAABAAAAAA4BAQAAACAAAAASAMAAQAAAAAUCCYBCAAAAAAAAAAAAAANJABAAAMBJ4KECOAEAAAMAAAAAAAAEAABAAV6GUSECFHAAAAAGAAAAAAAAAAAAAGABQAAAAEAAAAAAAEEBQA":"DAAAAExTS1PdAgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMl9jMF9jMDsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdCBjb3ZlcmFnZTsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0IHZjb3ZlcmFnZV9TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzZfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQyIHBvc2l0aW9uID0gcG9zaXRpb24ueHk7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCXZjb3ZlcmFnZV9TMCA9IGNvdmVyYWdlOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwoJewoJCXZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwID0gZmxvYXQzeDIodW1hdHJpeF9TMSkgKiBsb2NhbENvb3JkLnh5MTsKCX0KCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfNl9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzJfYzBfYzApICogcG9zaXRpb24ueHkxOwoJfQp9CgAAAAEAAADvIQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCmZsb2F0NCBmbHV0dGVyX0ZyYWdDb29yZF9TMV9jMDsKZmxvYXQ0IGZyYWdDb2xvcl9TMV9jMDsKZmxvYXQgdV9hbHBoYV9TMV9jMDsKZmxvYXQgdV9zcGFya2xlX2FscGhhX1MxX2MwOwpmbG9hdCB1X2JsdXJfUzFfYzA7CmZsb2F0IHVfcmFkaXVzX3NjYWxlX1MxX2MwOwpjb25zdCBpbnQga0ZpbGxCV19TMl9jMV9jMCA9IDA7CmNvbnN0IGludCBrSW52ZXJzZUZpbGxCV19TMl9jMV9jMCA9IDI7CmNvbnN0IGludCBrSW52ZXJzZUZpbGxBQV9TMl9jMV9jMCA9IDM7CnVuaWZvcm0gZmxvYXQ0IHVfY29sb3JfUzFfYzA7CnVuaWZvcm0gZmxvYXQ0IHVfY29tcG9zaXRlXzFfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2VudGVyX1MxX2MwOwp1bmlmb3JtIGZsb2F0IHVfbWF4X3JhZGl1c19TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yZXNvbHV0aW9uX3NjYWxlX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X25vaXNlX3NjYWxlX1MxX2MwOwp1bmlmb3JtIGZsb2F0IHVfbm9pc2VfcGhhc2VfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2lyY2xlMV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jaXJjbGUyX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NpcmNsZTNfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcm90YXRpb24xX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3JvdGF0aW9uMl9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yb3RhdGlvbjNfUzFfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MyX2MwX2MwOwp1bmlmb3JtIGZsb2F0NCB1cmVjdFVuaWZvcm1fUzJfYzFfYzA7CnNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMjsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQgdmNvdmVyYWdlX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzZfUzA7CmZsb2F0MiBGTFRfZmx1dHRlcl9sb2NhbF9GbHV0dGVyRnJhZ0Nvb3JkX1MxX2MwKCk7CmZsb2F0MngyIEZMVF9mbHV0dGVyX2xvY2FsX3JvdGF0ZTJkX1MxX2MwKGZsb2F0MiByYWQpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCBibHVyKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAoZmxvYXQyIHJlc29sdXRpb24sIGlub3V0IGZsb2F0MiBwLCBmbG9hdDIgeHksIGZsb2F0MiByb3RhdGlvbiwgZmxvYXQgY2VsbF9kaWFtZXRlcik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3R1cmJ1bGVuY2VfUzFfYzAoZmxvYXQyIHV2KTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9yaW5nX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IHRoaWNrbmVzcywgZmxvYXQgYmx1cik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RyaWFuZ2xlX25vaXNlX1MxX2MwKGlub3V0IGZsb2F0MiBuKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKGZsb2F0IHYsIGZsb2F0IGwsIGZsb2F0IGgpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zcGFya2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQgdCk7CnZvaWQgRkxUX21haW5fUzFfYzAoKTsKZmxvYXQyIEZMVF9mbHV0dGVyX2xvY2FsX0ZsdXR0ZXJGcmFnQ29vcmRfUzFfYzAoKSAKewoJcmV0dXJuIGZsdXR0ZXJfRnJhZ0Nvb3JkX1MxX2MwLnh5Owp9CmZsb2F0MngyIEZMVF9mbHV0dGVyX2xvY2FsX3JvdGF0ZTJkX1MxX2MwKGZsb2F0MiByYWQpIAp7CglyZXR1cm4gZmxvYXQyeDIocmFkLngsIC1yYWQueSwgcmFkLnksIHJhZC54KTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCBibHVyKSAKewoJZmxvYXQgYmx1cl9oYWxmID0gYmx1ciAqIDAuNTsKCWZsb2F0IGQgPSBkaXN0YW5jZSh1diwgeHkpOwoJcmV0dXJuIDEuMCAtIHNtb290aHN0ZXAoMS4wIC0gYmx1cl9oYWxmLCAxLjAgKyBibHVyX2hhbGYsIGQgLyByYWRpdXMpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKGZsb2F0MiByZXNvbHV0aW9uLCBpbm91dCBmbG9hdDIgcCwgZmxvYXQyIHh5LCBmbG9hdDIgcm90YXRpb24sIGZsb2F0IGNlbGxfZGlhbWV0ZXIpIAp7CglmbG9hdDIgcGFyYW0gPSByb3RhdGlvbjsKCXAgPSBGTFRfZmx1dHRlcl9sb2NhbF9yb3RhdGUyZF9TMV9jMChwYXJhbSkgKiAoeHkgLSBwKSArIHh5OwoJcCA9IG1vZChwLCBmbG9hdDIoY2VsbF9kaWFtZXRlcikpIC8gcmVzb2x1dGlvbjsKCWZsb2F0IGNlbGxfdXYgPSAoY2VsbF9kaWFtZXRlciAvIHJlc29sdXRpb24ueSkgKiAwLjU7CglmbG9hdCByID0gMC42NSAqIGNlbGxfdXY7CglmbG9hdDIgcGFyYW1fMSA9IHA7CglmbG9hdDIgcGFyYW1fMiA9IGZsb2F0MihjZWxsX3V2KTsKCWZsb2F0IHBhcmFtXzMgPSByOwoJZmxvYXQgcGFyYW1fNCA9IHIgKiA1MC4wOwoJcmV0dXJuIEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMsIHBhcmFtXzQpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3R1cmJ1bGVuY2VfUzFfYzAoZmxvYXQyIHV2KSAKewoJZmxvYXQyIHV2X3NjYWxlID0gdXYgKiBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbSA9IGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtXzEgPSB1dl9zY2FsZTsKCWZsb2F0MiBwYXJhbV8yID0gdV9jaXJjbGUxX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzMgPSB1X3JvdGF0aW9uMV9TMV9jMDsKCWZsb2F0IHBhcmFtXzQgPSAwLjE3OwoJZmxvYXQgXzMxOSA9IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKHBhcmFtLCBwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zLCBwYXJhbV80KTsKCWZsb2F0IGcxID0gXzMxOTsKCWZsb2F0MiBwYXJhbV81ID0gZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW1fNiA9IHV2X3NjYWxlOwoJZmxvYXQyIHBhcmFtXzcgPSB1X2NpcmNsZTJfUzFfYzA7CglmbG9hdDIgcGFyYW1fOCA9IHVfcm90YXRpb24yX1MxX2MwOwoJZmxvYXQgcGFyYW1fOSA9IDAuMjsKCWZsb2F0IF8zMzEgPSBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChwYXJhbV81LCBwYXJhbV82LCBwYXJhbV83LCBwYXJhbV84LCBwYXJhbV85KTsKCWZsb2F0IGcyID0gXzMzMTsKCWZsb2F0MiBwYXJhbV8xMCA9IGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtXzExID0gdXZfc2NhbGU7CglmbG9hdDIgcGFyYW1fMTIgPSB1X2NpcmNsZTNfUzFfYzA7CglmbG9hdDIgcGFyYW1fMTMgPSB1X3JvdGF0aW9uM19TMV9jMDsKCWZsb2F0IHBhcmFtXzE0ID0gMC4yNzU7CglmbG9hdCBfMzQ0ID0gRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAocGFyYW1fMTAsIHBhcmFtXzExLCBwYXJhbV8xMiwgcGFyYW1fMTMsIHBhcmFtXzE0KTsKCWZsb2F0IGczID0gXzM0NDsKCWZsb2F0IHYgPSAoKGcxICogZzEgKyBnMikgLSBnMykgKiAwLjU7CglyZXR1cm4gY2xhbXAoMC40NSArIDAuOCAqIHYsIDAuMCwgMS4wKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X3JpbmdfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgdGhpY2tuZXNzLCBmbG9hdCBibHVyKSAKewoJZmxvYXQyIHBhcmFtID0gdXY7CglmbG9hdDIgcGFyYW1fMSA9IHh5OwoJZmxvYXQgcGFyYW1fMiA9IHJhZGl1cyArIHRoaWNrbmVzczsKCWZsb2F0IHBhcmFtXzMgPSBibHVyOwoJZmxvYXQgY2lyY2xlX291dGVyID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW0sIHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMpOwoJZmxvYXQyIHBhcmFtXzQgPSB1djsKCWZsb2F0MiBwYXJhbV81ID0geHk7CglmbG9hdCBwYXJhbV82ID0gbWF4KHJhZGl1cyAtIHRoaWNrbmVzcywgMC4wKTsKCWZsb2F0IHBhcmFtXzcgPSBibHVyOwoJZmxvYXQgY2lyY2xlX2lubmVyID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW1fNCwgcGFyYW1fNSwgcGFyYW1fNiwgcGFyYW1fNyk7CglyZXR1cm4gY2xhbXAoY2lyY2xlX291dGVyIC0gY2lyY2xlX2lubmVyLCAwLjAsIDEuMCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHJpYW5nbGVfbm9pc2VfUzFfYzAoaW5vdXQgZmxvYXQyIG4pIAp7CgluID0gZnJhY3QobiAqIGZsb2F0Mig1LjM5ODcsIDUuNDQyMSkpOwoJbiArPSBmbG9hdDIoZG90KG4ueXgsIG4gKyBmbG9hdDIoMjEuNTM1MSwgMTQuMzEzNykpKTsKCWZsb2F0IHh5ID0gbi54ICogbi55OwoJcmV0dXJuIChmcmFjdCh4eSAqIDk1LjQzMDcpICsgZnJhY3QoeHkgKiA3NS4wNDk2MSkpIC0gMS4wOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChmbG9hdCB2LCBmbG9hdCBsLCBmbG9hdCBoKSAKewoJcmV0dXJuIHN0ZXAobCwgdikgKiAoMS4wIC0gc3RlcChoLCB2KSk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc3BhcmtsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0IHQpIAp7CglmbG9hdDIgcGFyYW0gPSB1djsKCWZsb2F0IF8yNDIgPSBGTFRfZmx1dHRlcl9sb2NhbF90cmlhbmdsZV9ub2lzZV9TMV9jMChwYXJhbSk7CglmbG9hdCBuID0gXzI0MjsKCWZsb2F0IHBhcmFtXzEgPSBuOwoJZmxvYXQgcGFyYW1fMiA9IDAuMDsKCWZsb2F0IHBhcmFtXzMgPSAwLjA1OwoJZmxvYXQgcyA9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zKTsKCWZsb2F0IHBhcmFtXzQgPSBuICsgc2luKDMuMTQxNTkyNzQgKiAodCArIDAuMzUpKTsKCWZsb2F0IHBhcmFtXzUgPSAwLjE7CglmbG9hdCBwYXJhbV82ID0gMC4xNTsKCXMgKz0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzQsIHBhcmFtXzUsIHBhcmFtXzYpOwoJZmxvYXQgcGFyYW1fNyA9IG4gKyBzaW4oMy4xNDE1OTI3NCAqICh0ICsgMC43KSk7CglmbG9hdCBwYXJhbV84ID0gMC4yOwoJZmxvYXQgcGFyYW1fOSA9IDAuMjU7CglzICs9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV83LCBwYXJhbV84LCBwYXJhbV85KTsKCWZsb2F0IHBhcmFtXzEwID0gbiArIHNpbigzLjE0MTU5Mjc0ICogKHQgKyAxLjA1KSk7CglmbG9hdCBwYXJhbV8xMSA9IDAuMzsKCWZsb2F0IHBhcmFtXzEyID0gMC4zNTsKCXMgKz0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzEwLCBwYXJhbV8xMSwgcGFyYW1fMTIpOwoJcmV0dXJuIGNsYW1wKHMsIDAuMCwgMS4wKSAqIDAuNTU7Cn0Kdm9pZCBGTFRfbWFpbl9TMV9jMCgpIAp7Cgl1X2FscGhhX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC54OwoJdV9zcGFya2xlX2FscGhhX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC55OwoJdV9ibHVyX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC56OwoJdV9yYWRpdXNfc2NhbGVfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLnc7CglmbG9hdDIgcCA9IEZMVF9mbHV0dGVyX2xvY2FsX0ZsdXR0ZXJGcmFnQ29vcmRfUzFfYzAoKTsKCWZsb2F0MiB1dl8xID0gcCAqIHVfcmVzb2x1dGlvbl9zY2FsZV9TMV9jMDsKCWZsb2F0MiBkZW5zaXR5X3V2ID0gdXZfMSAtIG1vZChwLCB1X25vaXNlX3NjYWxlX1MxX2MwKTsKCWZsb2F0IHJhZGl1cyA9IHVfbWF4X3JhZGl1c19TMV9jMCAqIHVfcmFkaXVzX3NjYWxlX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzEzID0gdXZfMTsKCWZsb2F0IHR1cmJ1bGVuY2UgPSBGTFRfZmx1dHRlcl9sb2NhbF90dXJidWxlbmNlX1MxX2MwKHBhcmFtXzEzKTsKCWZsb2F0MiBwYXJhbV8xNCA9IHA7CglmbG9hdDIgcGFyYW1fMTUgPSB1X2NlbnRlcl9TMV9jMDsKCWZsb2F0IHBhcmFtXzE2ID0gcmFkaXVzOwoJZmxvYXQgcGFyYW1fMTcgPSAwLjA1ICogdV9tYXhfcmFkaXVzX1MxX2MwOwoJZmxvYXQgcGFyYW1fMTggPSB1X2JsdXJfUzFfYzA7CglmbG9hdCByaW5nID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9yaW5nX1MxX2MwKHBhcmFtXzE0LCBwYXJhbV8xNSwgcGFyYW1fMTYsIHBhcmFtXzE3LCBwYXJhbV8xOCk7CglmbG9hdDIgcGFyYW1fMTkgPSBkZW5zaXR5X3V2OwoJZmxvYXQgcGFyYW1fMjAgPSB1X25vaXNlX3BoYXNlX1MxX2MwOwoJZmxvYXQgc3BhcmtsZSA9ICgoRkxUX2ZsdXR0ZXJfbG9jYWxfc3BhcmtsZV9TMV9jMChwYXJhbV8xOSwgcGFyYW1fMjApICogcmluZykgKiB0dXJidWxlbmNlKSAqIHVfc3BhcmtsZV9hbHBoYV9TMV9jMDsKCWZsb2F0MiBwYXJhbV8yMSA9IHA7CglmbG9hdDIgcGFyYW1fMjIgPSB1X2NlbnRlcl9TMV9jMDsKCWZsb2F0IHBhcmFtXzIzID0gcmFkaXVzOwoJZmxvYXQgcGFyYW1fMjQgPSB1X2JsdXJfUzFfYzA7CglmbG9hdCB3YXZlX2FscGhhID0gKEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtXzIxLCBwYXJhbV8yMiwgcGFyYW1fMjMsIHBhcmFtXzI0KSAqIHVfYWxwaGFfUzFfYzApICogdV9jb2xvcl9TMV9jMC53OwoJZmxvYXQ0IHdhdmVfY29sb3IgPSBmbG9hdDQodV9jb2xvcl9TMV9jMC54eXogKiB3YXZlX2FscGhhLCB3YXZlX2FscGhhKTsKCWZyYWdDb2xvcl9TMV9jMCA9IG1peCh3YXZlX2NvbG9yLCBmbG9hdDQoMS4wKSwgZmxvYXQ0KHNwYXJrbGUpKTsKfQpoYWxmNCBydW50aW1lX3NoYWRlcl9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzBfaW5Db2xvciA9IF9pbnB1dDsKCWZsb2F0MiBfdG1wXzFfY29vcmRzID0gdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CglmbHV0dGVyX0ZyYWdDb29yZF9TMV9jMCA9IGZsb2F0NChfdG1wXzFfY29vcmRzLCAwLjAsIDAuMCk7CglGTFRfbWFpbl9TMV9jMCgpOwoJcmV0dXJuIGhhbGY0KGhhbGY0KGZyYWdDb2xvcl9TMV9jMCkpOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gcnVudGltZV9zaGFkZXJfUzFfYzAoX2lucHV0KTsKfQpoYWxmNCBUZXh0dXJlRWZmZWN0X1MyX2MwX2MwX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzIsIHZUcmFuc2Zvcm1lZENvb3Jkc182X1MwKS4wMDByOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMl9jMF9jMChoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gVGV4dHVyZUVmZmVjdF9TMl9jMF9jMF9jMChfaW5wdXQpOwp9CmhhbGY0IERldmljZVNwYWNlX1MyX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBNYXRyaXhFZmZlY3RfUzJfYzBfYzAoX2lucHV0KTsKfQpoYWxmNCBSZWN0X1MyX2MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMl9pbkNvbG9yID0gX2lucHV0OwoJaGFsZiBjb3ZlcmFnZTsKCWlmIChpbnQoMSkgPT0ga0ZpbGxCV19TMl9jMV9jMCB8fCBpbnQoMSkgPT0ga0ludmVyc2VGaWxsQldfUzJfYzFfYzApIAoJewoJCWNvdmVyYWdlID0gaGFsZihhbGwoZ3JlYXRlclRoYW4oZmxvYXQ0KHNrX0ZyYWdDb29yZC54eSwgdXJlY3RVbmlmb3JtX1MyX2MxX2MwLnp3KSwgZmxvYXQ0KHVyZWN0VW5pZm9ybV9TMl9jMV9jMC54eSwgc2tfRnJhZ0Nvb3JkLnh5KSkpKTsKCX0KCWVsc2UgCgl7CgkJaGFsZjQgZGlzdHM0ID0gc2F0dXJhdGUoaGFsZjQoMS4wLCAxLjAsIC0xLjAsIC0xLjApICogaGFsZjQoc2tfRnJhZ0Nvb3JkLnh5eHkgLSB1cmVjdFVuaWZvcm1fUzJfYzFfYzApKTsKCQloYWxmMiBkaXN0czIgPSAoZGlzdHM0Lnh5ICsgZGlzdHM0Lnp3KSAtIDEuMDsKCQljb3ZlcmFnZSA9IGRpc3RzMi54ICogZGlzdHMyLnk7Cgl9CglpZiAoaW50KDEpID09IGtJbnZlcnNlRmlsbEJXX1MyX2MxX2MwIHx8IGludCgxKSA9PSBrSW52ZXJzZUZpbGxBQV9TMl9jMV9jMCkgCgl7CgkJY292ZXJhZ2UgPSAxLjAgLSBjb3ZlcmFnZTsKCX0KCXJldHVybiBoYWxmNChoYWxmNChjb3ZlcmFnZSkpOwp9CmhhbGY0IEJsZW5kX1MyX2MxKGhhbGY0IF9zcmMsIGhhbGY0IF9kc3QpIAp7CglyZXR1cm4gYmxlbmRfbW9kdWxhdGUoUmVjdF9TMl9jMV9jMChfc3JjKSwgX3NyYyk7Cn0KaGFsZjQgQmxlbmRfUzIoaGFsZjQgX3NyYywgaGFsZjQgX2RzdCkgCnsKCXJldHVybiBibGVuZF9kc3RfaW4oRGV2aWNlU3BhY2VfUzJfYzAoX3NyYyksIEJsZW5kX1MyX2MxKF9zcmMsIF9kc3QpKTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJZmxvYXQgY292ZXJhZ2UgPSB2Y292ZXJhZ2VfUzA7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGNvdmVyYWdlKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IE1hdHJpeEVmZmVjdF9TMShvdXRwdXRDb2xvcl9TMCk7CgloYWxmNCBvdXRwdXRfUzI7CglvdXRwdXRfUzIgPSBCbGVuZF9TMihvdXRwdXRDb3ZlcmFnZV9TMCwgaGFsZjQoMSkpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dF9TMjsKCX0KfQoAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAAcG9zaXRpb24IAAAAY292ZXJhZ2UFAAAAY29sb3IAAAAKAAAAbG9jYWxDb29yZAAAAAAAAA==","FIMAAAYAAEHAAAARC4EAAAQWBQAAAAAAAAAQAAAAIBCAAAEYAEAAAAAQAAAABAEQAEAAAAA":"DAAAAExTS1OtAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgaW5Qb3NpdGlvbjsKaW4gaGFsZjQgaW5Db2xvcjsKaW4gaGFsZjMgaW5TaGFkb3dQYXJhbXM7Cm5vcGVyc3BlY3RpdmUgb3V0IGhhbGYzIHZpblNoYWRvd1BhcmFtc19TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFJSZWN0U2hhZG93Cgl2aW5TaGFkb3dQYXJhbXNfUzAgPSBpblNoYWRvd1BhcmFtczsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247Cglza19Qb3NpdGlvbiA9IF90bXBfMF9pblBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAAAFwCAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwpub3BlcnNwZWN0aXZlIGluIGhhbGYzIHZpblNoYWRvd1BhcmFtc19TMDsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFJSZWN0U2hhZG93CgloYWxmMyBzaGFkb3dQYXJhbXM7CglzaGFkb3dQYXJhbXMgPSB2aW5TaGFkb3dQYXJhbXNfUzA7CgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmluQ29sb3JfUzA7CgloYWxmIGQgPSBsZW5ndGgoc2hhZG93UGFyYW1zLnh5KTsKCWZsb2F0MiB1diA9IGZsb2F0MihzaGFkb3dQYXJhbXMueiAqICgxLjAgLSBkKSwgMC41KTsKCWhhbGYgZmFjdG9yID0gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB1dikuMDAwci5hOwoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChmYWN0b3IpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADgAAAGluU2hhZG93UGFyYW1zAAAAAAAA","G2QACAAAABAAADAAAIOAAAAADIIAAIRODAAP577774DSAIAA737777YBAAAAAAAAAAADAAYAAAACAAAAAAACCAYAAA":"DAAAAExTS1PqAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgcG9zaXRpb247CmluIGZsb2F0IGNvdmVyYWdlOwppbiBoYWxmNCBjb2xvcjsKaW4gZmxvYXQ0IGdlb21TdWJzZXQ7Cm5vcGVyc3BlY3RpdmUgb3V0IGhhbGY0IHZjb2xvcl9TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQgdmNvdmVyYWdlX1MwOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDQgdmdlb21TdWJzZXRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQyIHBvc2l0aW9uID0gcG9zaXRpb24ueHk7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCXZjb3ZlcmFnZV9TMCA9IGNvdmVyYWdlOwoJdmdlb21TdWJzZXRfUzAgPSBnZW9tU3Vic2V0OwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAQAAAKQCAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQgdmNvdmVyYWdlX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0NCB2Z2VvbVN1YnNldF9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWZsb2F0IGNvdmVyYWdlID0gdmNvdmVyYWdlX1MwOwoJZmxvYXQ0IGdlb1N1YnNldDsKCWdlb1N1YnNldCA9IHZnZW9tU3Vic2V0X1MwOwoJZmxvYXQ0IGRpc3RzNCA9IHNhdHVyYXRlKGZsb2F0NCgxLCAxLCAtMSwgLTEpICogKHNrX0ZyYWdDb29yZC54eXh5IC0gZ2VvU3Vic2V0KSk7CglmbG9hdDIgZGlzdHMyID0gZGlzdHM0Lnh5ICsgZGlzdHM0Lnp3IC0gMTsKCWNvdmVyYWdlID0gbWluKGNvdmVyYWdlLCBkaXN0czIueCAqIGRpc3RzMi55KTsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoY292ZXJhZ2UpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAAcG9zaXRpb24IAAAAY292ZXJhZ2UFAAAAY29sb3IAAAAKAAAAZ2VvbVN1YnNldAAAAAAAAA==","AYQA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAAAAB3QA6AAAEAAAAAAAMAAPEAEAAABAAAAAABTAAAAAAACAAAAAEBSAAAA":"DAAAAExTS1MlAgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0NCB1bG9jYWxNYXRyaXhfUzA7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiBmbG9hdDQgaW5DaXJjbGVFZGdlOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIENpcmNsZUdlb21ldHJ5UHJvY2Vzc29yCgl2aW5DaXJjbGVFZGdlX1MwID0gaW5DaXJjbGVFZGdlOwoJdmluQ29sb3JfUzAgPSBpbkNvbG9yOwoJZmxvYXQyIF90bXBfMF9pblBvc2l0aW9uID0gaW5Qb3NpdGlvbjsKCWZsb2F0MiBfdG1wXzFfaW5Qb3NpdGlvbiA9IHVsb2NhbE1hdHJpeF9TMC54eiAqIGluUG9zaXRpb24gKyB1bG9jYWxNYXRyaXhfUzAueXc7Cglza19Qb3NpdGlvbiA9IF90bXBfMF9pblBvc2l0aW9uLnh5MDE7Cn0KAAAAAQAAAHcFAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CnVuaWZvcm0gZmxvYXQ0IHVpbm5lclJlY3RfUzI7CnVuaWZvcm0gaGFsZjIgdXJhZGl1c1BsdXNIYWxmX1MyOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0NCB2aW5DaXJjbGVFZGdlX1MwOwpub3BlcnNwZWN0aXZlIGluIGhhbGY0IHZpbkNvbG9yX1MwOwpoYWxmNCBDaXJjdWxhclJSZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCWZsb2F0MiBkeHkwID0gdWlubmVyUmVjdF9TMS5MVCAtIHNrX0ZyYWdDb29yZC54eTsKCWZsb2F0MiBkeHkxID0gc2tfRnJhZ0Nvb3JkLnh5IC0gdWlubmVyUmVjdF9TMS5SQjsKCWZsb2F0MiBkeHkgPSBtYXgobWF4KGR4eTAsIGR4eTEpLCAwLjApOwoJaGFsZiBhbHBoYSA9IGhhbGYoc2F0dXJhdGUodXJhZGl1c1BsdXNIYWxmX1MxLnggLSBsZW5ndGgoZHh5KSkpOwoJYWxwaGEgPSAxLjAgLSBhbHBoYTsKCXJldHVybiBfaW5wdXQgKiBhbHBoYTsKfQpoYWxmNCBDaXJjdWxhclJSZWN0X1MyKGhhbGY0IF9pbnB1dCkgCnsKCWZsb2F0MiBkeHkwID0gdWlubmVyUmVjdF9TMi5MVCAtIHNrX0ZyYWdDb29yZC54eTsKCWZsb2F0MiBkeHkxID0gc2tfRnJhZ0Nvb3JkLnh5IC0gdWlubmVyUmVjdF9TMi5SQjsKCWZsb2F0MiBkeHkgPSBtYXgobWF4KGR4eTAsIGR4eTEpLCAwLjApOwoJaGFsZiBhbHBoYSA9IGhhbGYoc2F0dXJhdGUodXJhZGl1c1BsdXNIYWxmX1MyLnggLSBsZW5ndGgoZHh5KSkpOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQ0IGNpcmNsZUVkZ2U7CgljaXJjbGVFZGdlID0gdmluQ2lyY2xlRWRnZV9TMDsKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWZsb2F0IGQgPSBsZW5ndGgoY2lyY2xlRWRnZS54eSk7CgloYWxmIGRpc3RhbmNlVG9PdXRlckVkZ2UgPSBoYWxmKGNpcmNsZUVkZ2UueiAqICgxLjAgLSBkKSk7CgloYWxmIGVkZ2VBbHBoYSA9IHNhdHVyYXRlKGRpc3RhbmNlVG9PdXRlckVkZ2UpOwoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChlZGdlQWxwaGEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQ2lyY3VsYXJSUmVjdF9TMShvdXRwdXRDb3ZlcmFnZV9TMCk7CgloYWxmNCBvdXRwdXRfUzI7CglvdXRwdXRfUzIgPSBDaXJjdWxhclJSZWN0X1MyKG91dHB1dF9TMSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzI7Cgl9Cn0KAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACgAAAGluUG9zaXRpb24AAAcAAABpbkNvbG9yAAwAAABpbkNpcmNsZUVkZ2UAAAAA","GZIACAAAABQAAGAAAQ4AAAAAGQQAARC4GAAAIOCAAD6P7777777777YDAAAAAAAAAAAJQBBYGQ467YIAAAAAAQAAAAAMACTRNBZN5QYBAAAAAAAAAAAIAALIAAAAB4FJEIEKOAAAAAMAAAAAEAHQAACAAAAAAYCFPSVARQRJAAAAABQAAAAAAAAAAA4JAPAAACAAAAAAACABSAAAAAAACAAAAAEBSAAA":"DAAAAExTS1M7AgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQgY292ZXJhZ2U7CmluIGhhbGY0IGNvbG9yOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdCB2Y292ZXJhZ2VfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDIgcG9zaXRpb24gPSBwb3NpdGlvbi54eTsKCXZjb2xvcl9TMCA9IGNvbG9yOwoJdmNvdmVyYWdlX1MwID0gY292ZXJhZ2U7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgABAAAANCEAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQpmbG9hdDQgZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzA7CmZsb2F0NCBmcmFnQ29sb3JfUzFfYzA7CmZsb2F0IHVfYWxwaGFfUzFfYzA7CmZsb2F0IHVfc3BhcmtsZV9hbHBoYV9TMV9jMDsKZmxvYXQgdV9ibHVyX1MxX2MwOwpmbG9hdCB1X3JhZGl1c19zY2FsZV9TMV9jMDsKY29uc3QgaW50IGtGaWxsQldfUzJfYzAgPSAwOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQldfUzJfYzAgPSAyOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQUFfUzJfYzAgPSAzOwp1bmlmb3JtIGZsb2F0NCB1X2NvbG9yX1MxX2MwOwp1bmlmb3JtIGZsb2F0NCB1X2NvbXBvc2l0ZV8xX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NlbnRlcl9TMV9jMDsKdW5pZm9ybSBmbG9hdCB1X21heF9yYWRpdXNfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcmVzb2x1dGlvbl9zY2FsZV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9ub2lzZV9zY2FsZV9TMV9jMDsKdW5pZm9ybSBmbG9hdCB1X25vaXNlX3BoYXNlX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NpcmNsZTFfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2lyY2xlMl9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jaXJjbGUzX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3JvdGF0aW9uMV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yb3RhdGlvbjJfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcm90YXRpb24zX1MxX2MwOwp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CnVuaWZvcm0gZmxvYXQ0IHVyZWN0VW5pZm9ybV9TMl9jMDsKdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMl9jMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzJfYzE7Cm5vcGVyc3BlY3RpdmUgaW4gaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0IHZjb3ZlcmFnZV9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CmZsb2F0MiBGTFRfZmx1dHRlcl9sb2NhbF9GbHV0dGVyRnJhZ0Nvb3JkX1MxX2MwKCk7CmZsb2F0MngyIEZMVF9mbHV0dGVyX2xvY2FsX3JvdGF0ZTJkX1MxX2MwKGZsb2F0MiByYWQpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCBibHVyKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAoZmxvYXQyIHJlc29sdXRpb24sIGlub3V0IGZsb2F0MiBwLCBmbG9hdDIgeHksIGZsb2F0MiByb3RhdGlvbiwgZmxvYXQgY2VsbF9kaWFtZXRlcik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3R1cmJ1bGVuY2VfUzFfYzAoZmxvYXQyIHV2KTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9yaW5nX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IHRoaWNrbmVzcywgZmxvYXQgYmx1cik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RyaWFuZ2xlX25vaXNlX1MxX2MwKGlub3V0IGZsb2F0MiBuKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKGZsb2F0IHYsIGZsb2F0IGwsIGZsb2F0IGgpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zcGFya2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQgdCk7CnZvaWQgRkxUX21haW5fUzFfYzAoKTsKZmxvYXQyIEZMVF9mbHV0dGVyX2xvY2FsX0ZsdXR0ZXJGcmFnQ29vcmRfUzFfYzAoKSAKewoJcmV0dXJuIGZsdXR0ZXJfRnJhZ0Nvb3JkX1MxX2MwLnh5Owp9CmZsb2F0MngyIEZMVF9mbHV0dGVyX2xvY2FsX3JvdGF0ZTJkX1MxX2MwKGZsb2F0MiByYWQpIAp7CglyZXR1cm4gZmxvYXQyeDIocmFkLngsIC1yYWQueSwgcmFkLnksIHJhZC54KTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCBibHVyKSAKewoJZmxvYXQgYmx1cl9oYWxmID0gYmx1ciAqIDAuNTsKCWZsb2F0IGQgPSBkaXN0YW5jZSh1diwgeHkpOwoJcmV0dXJuIDEuMCAtIHNtb290aHN0ZXAoMS4wIC0gYmx1cl9oYWxmLCAxLjAgKyBibHVyX2hhbGYsIGQgLyByYWRpdXMpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKGZsb2F0MiByZXNvbHV0aW9uLCBpbm91dCBmbG9hdDIgcCwgZmxvYXQyIHh5LCBmbG9hdDIgcm90YXRpb24sIGZsb2F0IGNlbGxfZGlhbWV0ZXIpIAp7CglmbG9hdDIgcGFyYW0gPSByb3RhdGlvbjsKCXAgPSBGTFRfZmx1dHRlcl9sb2NhbF9yb3RhdGUyZF9TMV9jMChwYXJhbSkgKiAoeHkgLSBwKSArIHh5OwoJcCA9IG1vZChwLCBmbG9hdDIoY2VsbF9kaWFtZXRlcikpIC8gcmVzb2x1dGlvbjsKCWZsb2F0IGNlbGxfdXYgPSAoY2VsbF9kaWFtZXRlciAvIHJlc29sdXRpb24ueSkgKiAwLjU7CglmbG9hdCByID0gMC42NSAqIGNlbGxfdXY7CglmbG9hdDIgcGFyYW1fMSA9IHA7CglmbG9hdDIgcGFyYW1fMiA9IGZsb2F0MihjZWxsX3V2KTsKCWZsb2F0IHBhcmFtXzMgPSByOwoJZmxvYXQgcGFyYW1fNCA9IHIgKiA1MC4wOwoJcmV0dXJuIEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMsIHBhcmFtXzQpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3R1cmJ1bGVuY2VfUzFfYzAoZmxvYXQyIHV2KSAKewoJZmxvYXQyIHV2X3NjYWxlID0gdXYgKiBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbSA9IGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtXzEgPSB1dl9zY2FsZTsKCWZsb2F0MiBwYXJhbV8yID0gdV9jaXJjbGUxX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzMgPSB1X3JvdGF0aW9uMV9TMV9jMDsKCWZsb2F0IHBhcmFtXzQgPSAwLjE3OwoJZmxvYXQgXzMxOSA9IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKHBhcmFtLCBwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zLCBwYXJhbV80KTsKCWZsb2F0IGcxID0gXzMxOTsKCWZsb2F0MiBwYXJhbV81ID0gZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW1fNiA9IHV2X3NjYWxlOwoJZmxvYXQyIHBhcmFtXzcgPSB1X2NpcmNsZTJfUzFfYzA7CglmbG9hdDIgcGFyYW1fOCA9IHVfcm90YXRpb24yX1MxX2MwOwoJZmxvYXQgcGFyYW1fOSA9IDAuMjsKCWZsb2F0IF8zMzEgPSBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChwYXJhbV81LCBwYXJhbV82LCBwYXJhbV83LCBwYXJhbV84LCBwYXJhbV85KTsKCWZsb2F0IGcyID0gXzMzMTsKCWZsb2F0MiBwYXJhbV8xMCA9IGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtXzExID0gdXZfc2NhbGU7CglmbG9hdDIgcGFyYW1fMTIgPSB1X2NpcmNsZTNfUzFfYzA7CglmbG9hdDIgcGFyYW1fMTMgPSB1X3JvdGF0aW9uM19TMV9jMDsKCWZsb2F0IHBhcmFtXzE0ID0gMC4yNzU7CglmbG9hdCBfMzQ0ID0gRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAocGFyYW1fMTAsIHBhcmFtXzExLCBwYXJhbV8xMiwgcGFyYW1fMTMsIHBhcmFtXzE0KTsKCWZsb2F0IGczID0gXzM0NDsKCWZsb2F0IHYgPSAoKGcxICogZzEgKyBnMikgLSBnMykgKiAwLjU7CglyZXR1cm4gY2xhbXAoMC40NSArIDAuOCAqIHYsIDAuMCwgMS4wKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X3JpbmdfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgdGhpY2tuZXNzLCBmbG9hdCBibHVyKSAKewoJZmxvYXQyIHBhcmFtID0gdXY7CglmbG9hdDIgcGFyYW1fMSA9IHh5OwoJZmxvYXQgcGFyYW1fMiA9IHJhZGl1cyArIHRoaWNrbmVzczsKCWZsb2F0IHBhcmFtXzMgPSBibHVyOwoJZmxvYXQgY2lyY2xlX291dGVyID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW0sIHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMpOwoJZmxvYXQyIHBhcmFtXzQgPSB1djsKCWZsb2F0MiBwYXJhbV81ID0geHk7CglmbG9hdCBwYXJhbV82ID0gbWF4KHJhZGl1cyAtIHRoaWNrbmVzcywgMC4wKTsKCWZsb2F0IHBhcmFtXzcgPSBibHVyOwoJZmxvYXQgY2lyY2xlX2lubmVyID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW1fNCwgcGFyYW1fNSwgcGFyYW1fNiwgcGFyYW1fNyk7CglyZXR1cm4gY2xhbXAoY2lyY2xlX291dGVyIC0gY2lyY2xlX2lubmVyLCAwLjAsIDEuMCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHJpYW5nbGVfbm9pc2VfUzFfYzAoaW5vdXQgZmxvYXQyIG4pIAp7CgluID0gZnJhY3QobiAqIGZsb2F0Mig1LjM5ODcsIDUuNDQyMSkpOwoJbiArPSBmbG9hdDIoZG90KG4ueXgsIG4gKyBmbG9hdDIoMjEuNTM1MSwgMTQuMzEzNykpKTsKCWZsb2F0IHh5ID0gbi54ICogbi55OwoJcmV0dXJuIChmcmFjdCh4eSAqIDk1LjQzMDcpICsgZnJhY3QoeHkgKiA3NS4wNDk2MSkpIC0gMS4wOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChmbG9hdCB2LCBmbG9hdCBsLCBmbG9hdCBoKSAKewoJcmV0dXJuIHN0ZXAobCwgdikgKiAoMS4wIC0gc3RlcChoLCB2KSk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc3BhcmtsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0IHQpIAp7CglmbG9hdDIgcGFyYW0gPSB1djsKCWZsb2F0IF8yNDIgPSBGTFRfZmx1dHRlcl9sb2NhbF90cmlhbmdsZV9ub2lzZV9TMV9jMChwYXJhbSk7CglmbG9hdCBuID0gXzI0MjsKCWZsb2F0IHBhcmFtXzEgPSBuOwoJZmxvYXQgcGFyYW1fMiA9IDAuMDsKCWZsb2F0IHBhcmFtXzMgPSAwLjA1OwoJZmxvYXQgcyA9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zKTsKCWZsb2F0IHBhcmFtXzQgPSBuICsgc2luKDMuMTQxNTkyNzQgKiAodCArIDAuMzUpKTsKCWZsb2F0IHBhcmFtXzUgPSAwLjE7CglmbG9hdCBwYXJhbV82ID0gMC4xNTsKCXMgKz0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzQsIHBhcmFtXzUsIHBhcmFtXzYpOwoJZmxvYXQgcGFyYW1fNyA9IG4gKyBzaW4oMy4xNDE1OTI3NCAqICh0ICsgMC43KSk7CglmbG9hdCBwYXJhbV84ID0gMC4yOwoJZmxvYXQgcGFyYW1fOSA9IDAuMjU7CglzICs9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV83LCBwYXJhbV84LCBwYXJhbV85KTsKCWZsb2F0IHBhcmFtXzEwID0gbiArIHNpbigzLjE0MTU5Mjc0ICogKHQgKyAxLjA1KSk7CglmbG9hdCBwYXJhbV8xMSA9IDAuMzsKCWZsb2F0IHBhcmFtXzEyID0gMC4zNTsKCXMgKz0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzEwLCBwYXJhbV8xMSwgcGFyYW1fMTIpOwoJcmV0dXJuIGNsYW1wKHMsIDAuMCwgMS4wKSAqIDAuNTU7Cn0Kdm9pZCBGTFRfbWFpbl9TMV9jMCgpIAp7Cgl1X2FscGhhX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC54OwoJdV9zcGFya2xlX2FscGhhX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC55OwoJdV9ibHVyX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC56OwoJdV9yYWRpdXNfc2NhbGVfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLnc7CglmbG9hdDIgcCA9IEZMVF9mbHV0dGVyX2xvY2FsX0ZsdXR0ZXJGcmFnQ29vcmRfUzFfYzAoKTsKCWZsb2F0MiB1dl8xID0gcCAqIHVfcmVzb2x1dGlvbl9zY2FsZV9TMV9jMDsKCWZsb2F0MiBkZW5zaXR5X3V2ID0gdXZfMSAtIG1vZChwLCB1X25vaXNlX3NjYWxlX1MxX2MwKTsKCWZsb2F0IHJhZGl1cyA9IHVfbWF4X3JhZGl1c19TMV9jMCAqIHVfcmFkaXVzX3NjYWxlX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzEzID0gdXZfMTsKCWZsb2F0IHR1cmJ1bGVuY2UgPSBGTFRfZmx1dHRlcl9sb2NhbF90dXJidWxlbmNlX1MxX2MwKHBhcmFtXzEzKTsKCWZsb2F0MiBwYXJhbV8xNCA9IHA7CglmbG9hdDIgcGFyYW1fMTUgPSB1X2NlbnRlcl9TMV9jMDsKCWZsb2F0IHBhcmFtXzE2ID0gcmFkaXVzOwoJZmxvYXQgcGFyYW1fMTcgPSAwLjA1ICogdV9tYXhfcmFkaXVzX1MxX2MwOwoJZmxvYXQgcGFyYW1fMTggPSB1X2JsdXJfUzFfYzA7CglmbG9hdCByaW5nID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9yaW5nX1MxX2MwKHBhcmFtXzE0LCBwYXJhbV8xNSwgcGFyYW1fMTYsIHBhcmFtXzE3LCBwYXJhbV8xOCk7CglmbG9hdDIgcGFyYW1fMTkgPSBkZW5zaXR5X3V2OwoJZmxvYXQgcGFyYW1fMjAgPSB1X25vaXNlX3BoYXNlX1MxX2MwOwoJZmxvYXQgc3BhcmtsZSA9ICgoRkxUX2ZsdXR0ZXJfbG9jYWxfc3BhcmtsZV9TMV9jMChwYXJhbV8xOSwgcGFyYW1fMjApICogcmluZykgKiB0dXJidWxlbmNlKSAqIHVfc3BhcmtsZV9hbHBoYV9TMV9jMDsKCWZsb2F0MiBwYXJhbV8yMSA9IHA7CglmbG9hdDIgcGFyYW1fMjIgPSB1X2NlbnRlcl9TMV9jMDsKCWZsb2F0IHBhcmFtXzIzID0gcmFkaXVzOwoJZmxvYXQgcGFyYW1fMjQgPSB1X2JsdXJfUzFfYzA7CglmbG9hdCB3YXZlX2FscGhhID0gKEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtXzIxLCBwYXJhbV8yMiwgcGFyYW1fMjMsIHBhcmFtXzI0KSAqIHVfYWxwaGFfUzFfYzApICogdV9jb2xvcl9TMV9jMC53OwoJZmxvYXQ0IHdhdmVfY29sb3IgPSBmbG9hdDQodV9jb2xvcl9TMV9jMC54eXogKiB3YXZlX2FscGhhLCB3YXZlX2FscGhhKTsKCWZyYWdDb2xvcl9TMV9jMCA9IG1peCh3YXZlX2NvbG9yLCBmbG9hdDQoMS4wKSwgZmxvYXQ0KHNwYXJrbGUpKTsKfQpoYWxmNCBydW50aW1lX3NoYWRlcl9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzBfaW5Db2xvciA9IF9pbnB1dDsKCWZsb2F0MiBfdG1wXzFfY29vcmRzID0gdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CglmbHV0dGVyX0ZyYWdDb29yZF9TMV9jMCA9IGZsb2F0NChfdG1wXzFfY29vcmRzLCAwLjAsIDAuMCk7CglGTFRfbWFpbl9TMV9jMCgpOwoJcmV0dXJuIGhhbGY0KGhhbGY0KGZyYWdDb2xvcl9TMV9jMCkpOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gcnVudGltZV9zaGFkZXJfUzFfYzAoX2lucHV0KTsKfQpoYWxmNCBSZWN0X1MyX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMl9pbkNvbG9yID0gX2lucHV0OwoJaGFsZiBjb3ZlcmFnZTsKCWlmIChpbnQoMSkgPT0ga0ZpbGxCV19TMl9jMCB8fCBpbnQoMSkgPT0ga0ludmVyc2VGaWxsQldfUzJfYzApIAoJewoJCWNvdmVyYWdlID0gaGFsZihhbGwoZ3JlYXRlclRoYW4oZmxvYXQ0KHNrX0ZyYWdDb29yZC54eSwgdXJlY3RVbmlmb3JtX1MyX2MwLnp3KSwgZmxvYXQ0KHVyZWN0VW5pZm9ybV9TMl9jMC54eSwgc2tfRnJhZ0Nvb3JkLnh5KSkpKTsKCX0KCWVsc2UgCgl7CgkJaGFsZjQgZGlzdHM0ID0gc2F0dXJhdGUoaGFsZjQoMS4wLCAxLjAsIC0xLjAsIC0xLjApICogaGFsZjQoc2tfRnJhZ0Nvb3JkLnh5eHkgLSB1cmVjdFVuaWZvcm1fUzJfYzApKTsKCQloYWxmMiBkaXN0czIgPSAoZGlzdHM0Lnh5ICsgZGlzdHM0Lnp3KSAtIDEuMDsKCQljb3ZlcmFnZSA9IGRpc3RzMi54ICogZGlzdHMyLnk7Cgl9CglpZiAoaW50KDEpID09IGtJbnZlcnNlRmlsbEJXX1MyX2MwIHx8IGludCgxKSA9PSBrSW52ZXJzZUZpbGxBQV9TMl9jMCkgCgl7CgkJY292ZXJhZ2UgPSAxLjAgLSBjb3ZlcmFnZTsKCX0KCXJldHVybiBoYWxmNChoYWxmNChjb3ZlcmFnZSkpOwp9CmhhbGY0IENpcmN1bGFyUlJlY3RfUzJfYzEoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MyX2MxLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MyX2MxLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CgloYWxmIGFscGhhID0gaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzJfYzEueCAtIGxlbmd0aChkeHkpKSk7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0KaGFsZjQgQmxlbmRfUzIoaGFsZjQgX3NyYywgaGFsZjQgX2RzdCkgCnsKCXJldHVybiBibGVuZF9tb2R1bGF0ZShSZWN0X1MyX2MwKF9zcmMpLCBDaXJjdWxhclJSZWN0X1MyX2MxKF9zcmMpKTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJZmxvYXQgY292ZXJhZ2UgPSB2Y292ZXJhZ2VfUzA7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGNvdmVyYWdlKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IE1hdHJpeEVmZmVjdF9TMShvdXRwdXRDb2xvcl9TMCk7CgloYWxmNCBvdXRwdXRfUzI7CglvdXRwdXRfUzIgPSBCbGVuZF9TMihvdXRwdXRDb3ZlcmFnZV9TMCwgaGFsZjQoMSkpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dF9TMjsKCX0KfQoBAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAgAAABwb3NpdGlvbggAAABjb3ZlcmFnZQUAAABjb2xvcgAAAAoAAABsb2NhbENvb3JkAAAAAAAA","GZIACAAAABQAAGAAAQ4AAAAAGQQAARC4GAAAIOCAAD6P7777777777YDAAAAAAAAAAAJQBBYGQ467YIAAAAAAQAAAAAMACTRNBZN5QYBAAAAAAAAAAAIAA4IAEAAACAAAAAABGABAAAAAEAAAAAIBEABAA":"DAAAAExTS1M7AgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQgY292ZXJhZ2U7CmluIGhhbGY0IGNvbG9yOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdCB2Y292ZXJhZ2VfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDIgcG9zaXRpb24gPSBwb3NpdGlvbi54eTsKCXZjb2xvcl9TMCA9IGNvbG9yOwoJdmNvdmVyYWdlX1MwID0gY292ZXJhZ2U7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgABAAAAEh4AACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQpmbG9hdDQgZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzA7CmZsb2F0NCBmcmFnQ29sb3JfUzFfYzA7CmZsb2F0IHVfYWxwaGFfUzFfYzA7CmZsb2F0IHVfc3BhcmtsZV9hbHBoYV9TMV9jMDsKZmxvYXQgdV9ibHVyX1MxX2MwOwpmbG9hdCB1X3JhZGl1c19zY2FsZV9TMV9jMDsKdW5pZm9ybSBmbG9hdDQgdV9jb2xvcl9TMV9jMDsKdW5pZm9ybSBmbG9hdDQgdV9jb21wb3NpdGVfMV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jZW50ZXJfUzFfYzA7CnVuaWZvcm0gZmxvYXQgdV9tYXhfcmFkaXVzX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3Jlc29sdXRpb25fc2NhbGVfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfbm9pc2Vfc2NhbGVfUzFfYzA7CnVuaWZvcm0gZmxvYXQgdV9ub2lzZV9waGFzZV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jaXJjbGUxX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NpcmNsZTJfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2lyY2xlM19TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yb3RhdGlvbjFfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcm90YXRpb24yX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3JvdGF0aW9uM19TMV9jMDsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxOwp1bmlmb3JtIGZsb2F0NCB1aW5uZXJSZWN0X1MyOwp1bmlmb3JtIGhhbGYyIHVyYWRpdXNQbHVzSGFsZl9TMjsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQgdmNvdmVyYWdlX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKZmxvYXQyIEZMVF9mbHV0dGVyX2xvY2FsX0ZsdXR0ZXJGcmFnQ29vcmRfUzFfYzAoKTsKZmxvYXQyeDIgRkxUX2ZsdXR0ZXJfbG9jYWxfcm90YXRlMmRfUzFfYzAoZmxvYXQyIHJhZCk7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IGJsdXIpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChmbG9hdDIgcmVzb2x1dGlvbiwgaW5vdXQgZmxvYXQyIHAsIGZsb2F0MiB4eSwgZmxvYXQyIHJvdGF0aW9uLCBmbG9hdCBjZWxsX2RpYW1ldGVyKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHVyYnVsZW5jZV9TMV9jMChmbG9hdDIgdXYpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X3JpbmdfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgdGhpY2tuZXNzLCBmbG9hdCBibHVyKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHJpYW5nbGVfbm9pc2VfUzFfYzAoaW5vdXQgZmxvYXQyIG4pOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAoZmxvYXQgdiwgZmxvYXQgbCwgZmxvYXQgaCk7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NwYXJrbGVfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdCB0KTsKdm9pZCBGTFRfbWFpbl9TMV9jMCgpOwpmbG9hdDIgRkxUX2ZsdXR0ZXJfbG9jYWxfRmx1dHRlckZyYWdDb29yZF9TMV9jMCgpIAp7CglyZXR1cm4gZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzAueHk7Cn0KZmxvYXQyeDIgRkxUX2ZsdXR0ZXJfbG9jYWxfcm90YXRlMmRfUzFfYzAoZmxvYXQyIHJhZCkgCnsKCXJldHVybiBmbG9hdDJ4MihyYWQueCwgLXJhZC55LCByYWQueSwgcmFkLngpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IGJsdXIpIAp7CglmbG9hdCBibHVyX2hhbGYgPSBibHVyICogMC41OwoJZmxvYXQgZCA9IGRpc3RhbmNlKHV2LCB4eSk7CglyZXR1cm4gMS4wIC0gc21vb3Roc3RlcCgxLjAgLSBibHVyX2hhbGYsIDEuMCArIGJsdXJfaGFsZiwgZCAvIHJhZGl1cyk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAoZmxvYXQyIHJlc29sdXRpb24sIGlub3V0IGZsb2F0MiBwLCBmbG9hdDIgeHksIGZsb2F0MiByb3RhdGlvbiwgZmxvYXQgY2VsbF9kaWFtZXRlcikgCnsKCWZsb2F0MiBwYXJhbSA9IHJvdGF0aW9uOwoJcCA9IEZMVF9mbHV0dGVyX2xvY2FsX3JvdGF0ZTJkX1MxX2MwKHBhcmFtKSAqICh4eSAtIHApICsgeHk7CglwID0gbW9kKHAsIGZsb2F0MihjZWxsX2RpYW1ldGVyKSkgLyByZXNvbHV0aW9uOwoJZmxvYXQgY2VsbF91diA9IChjZWxsX2RpYW1ldGVyIC8gcmVzb2x1dGlvbi55KSAqIDAuNTsKCWZsb2F0IHIgPSAwLjY1ICogY2VsbF91djsKCWZsb2F0MiBwYXJhbV8xID0gcDsKCWZsb2F0MiBwYXJhbV8yID0gZmxvYXQyKGNlbGxfdXYpOwoJZmxvYXQgcGFyYW1fMyA9IHI7CglmbG9hdCBwYXJhbV80ID0gciAqIDUwLjA7CglyZXR1cm4gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW1fMSwgcGFyYW1fMiwgcGFyYW1fMywgcGFyYW1fNCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHVyYnVsZW5jZV9TMV9jMChmbG9hdDIgdXYpIAp7CglmbG9hdDIgdXZfc2NhbGUgPSB1diAqIGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtID0gZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW1fMSA9IHV2X3NjYWxlOwoJZmxvYXQyIHBhcmFtXzIgPSB1X2NpcmNsZTFfUzFfYzA7CglmbG9hdDIgcGFyYW1fMyA9IHVfcm90YXRpb24xX1MxX2MwOwoJZmxvYXQgcGFyYW1fNCA9IDAuMTc7CglmbG9hdCBfMzE5ID0gRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAocGFyYW0sIHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMsIHBhcmFtXzQpOwoJZmxvYXQgZzEgPSBfMzE5OwoJZmxvYXQyIHBhcmFtXzUgPSBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbV82ID0gdXZfc2NhbGU7CglmbG9hdDIgcGFyYW1fNyA9IHVfY2lyY2xlMl9TMV9jMDsKCWZsb2F0MiBwYXJhbV84ID0gdV9yb3RhdGlvbjJfUzFfYzA7CglmbG9hdCBwYXJhbV85ID0gMC4yOwoJZmxvYXQgXzMzMSA9IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKHBhcmFtXzUsIHBhcmFtXzYsIHBhcmFtXzcsIHBhcmFtXzgsIHBhcmFtXzkpOwoJZmxvYXQgZzIgPSBfMzMxOwoJZmxvYXQyIHBhcmFtXzEwID0gZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW1fMTEgPSB1dl9zY2FsZTsKCWZsb2F0MiBwYXJhbV8xMiA9IHVfY2lyY2xlM19TMV9jMDsKCWZsb2F0MiBwYXJhbV8xMyA9IHVfcm90YXRpb24zX1MxX2MwOwoJZmxvYXQgcGFyYW1fMTQgPSAwLjI3NTsKCWZsb2F0IF8zNDQgPSBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChwYXJhbV8xMCwgcGFyYW1fMTEsIHBhcmFtXzEyLCBwYXJhbV8xMywgcGFyYW1fMTQpOwoJZmxvYXQgZzMgPSBfMzQ0OwoJZmxvYXQgdiA9ICgoZzEgKiBnMSArIGcyKSAtIGczKSAqIDAuNTsKCXJldHVybiBjbGFtcCgwLjQ1ICsgMC44ICogdiwgMC4wLCAxLjApOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfcmluZ19TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCB0aGlja25lc3MsIGZsb2F0IGJsdXIpIAp7CglmbG9hdDIgcGFyYW0gPSB1djsKCWZsb2F0MiBwYXJhbV8xID0geHk7CglmbG9hdCBwYXJhbV8yID0gcmFkaXVzICsgdGhpY2tuZXNzOwoJZmxvYXQgcGFyYW1fMyA9IGJsdXI7CglmbG9hdCBjaXJjbGVfb3V0ZXIgPSBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChwYXJhbSwgcGFyYW1fMSwgcGFyYW1fMiwgcGFyYW1fMyk7CglmbG9hdDIgcGFyYW1fNCA9IHV2OwoJZmxvYXQyIHBhcmFtXzUgPSB4eTsKCWZsb2F0IHBhcmFtXzYgPSBtYXgocmFkaXVzIC0gdGhpY2tuZXNzLCAwLjApOwoJZmxvYXQgcGFyYW1fNyA9IGJsdXI7CglmbG9hdCBjaXJjbGVfaW5uZXIgPSBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChwYXJhbV80LCBwYXJhbV81LCBwYXJhbV82LCBwYXJhbV83KTsKCXJldHVybiBjbGFtcChjaXJjbGVfb3V0ZXIgLSBjaXJjbGVfaW5uZXIsIDAuMCwgMS4wKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90cmlhbmdsZV9ub2lzZV9TMV9jMChpbm91dCBmbG9hdDIgbikgCnsKCW4gPSBmcmFjdChuICogZmxvYXQyKDUuMzk4NywgNS40NDIxKSk7CgluICs9IGZsb2F0Mihkb3Qobi55eCwgbiArIGZsb2F0MigyMS41MzUxLCAxNC4zMTM3KSkpOwoJZmxvYXQgeHkgPSBuLnggKiBuLnk7CglyZXR1cm4gKGZyYWN0KHh5ICogOTUuNDMwNykgKyBmcmFjdCh4eSAqIDc1LjA0OTYxKSkgLSAxLjA7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKGZsb2F0IHYsIGZsb2F0IGwsIGZsb2F0IGgpIAp7CglyZXR1cm4gc3RlcChsLCB2KSAqICgxLjAgLSBzdGVwKGgsIHYpKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zcGFya2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQgdCkgCnsKCWZsb2F0MiBwYXJhbSA9IHV2OwoJZmxvYXQgXzI0MiA9IEZMVF9mbHV0dGVyX2xvY2FsX3RyaWFuZ2xlX25vaXNlX1MxX2MwKHBhcmFtKTsKCWZsb2F0IG4gPSBfMjQyOwoJZmxvYXQgcGFyYW1fMSA9IG47CglmbG9hdCBwYXJhbV8yID0gMC4wOwoJZmxvYXQgcGFyYW1fMyA9IDAuMDU7CglmbG9hdCBzID0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMpOwoJZmxvYXQgcGFyYW1fNCA9IG4gKyBzaW4oMy4xNDE1OTI3NCAqICh0ICsgMC4zNSkpOwoJZmxvYXQgcGFyYW1fNSA9IDAuMTsKCWZsb2F0IHBhcmFtXzYgPSAwLjE1OwoJcyArPSBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAocGFyYW1fNCwgcGFyYW1fNSwgcGFyYW1fNik7CglmbG9hdCBwYXJhbV83ID0gbiArIHNpbigzLjE0MTU5Mjc0ICogKHQgKyAwLjcpKTsKCWZsb2F0IHBhcmFtXzggPSAwLjI7CglmbG9hdCBwYXJhbV85ID0gMC4yNTsKCXMgKz0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzcsIHBhcmFtXzgsIHBhcmFtXzkpOwoJZmxvYXQgcGFyYW1fMTAgPSBuICsgc2luKDMuMTQxNTkyNzQgKiAodCArIDEuMDUpKTsKCWZsb2F0IHBhcmFtXzExID0gMC4zOwoJZmxvYXQgcGFyYW1fMTIgPSAwLjM1OwoJcyArPSBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAocGFyYW1fMTAsIHBhcmFtXzExLCBwYXJhbV8xMik7CglyZXR1cm4gY2xhbXAocywgMC4wLCAxLjApICogMC41NTsKfQp2b2lkIEZMVF9tYWluX1MxX2MwKCkgCnsKCXVfYWxwaGFfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLng7Cgl1X3NwYXJrbGVfYWxwaGFfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLnk7Cgl1X2JsdXJfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLno7Cgl1X3JhZGl1c19zY2FsZV9TMV9jMCA9IHVfY29tcG9zaXRlXzFfUzFfYzAudzsKCWZsb2F0MiBwID0gRkxUX2ZsdXR0ZXJfbG9jYWxfRmx1dHRlckZyYWdDb29yZF9TMV9jMCgpOwoJZmxvYXQyIHV2XzEgPSBwICogdV9yZXNvbHV0aW9uX3NjYWxlX1MxX2MwOwoJZmxvYXQyIGRlbnNpdHlfdXYgPSB1dl8xIC0gbW9kKHAsIHVfbm9pc2Vfc2NhbGVfUzFfYzApOwoJZmxvYXQgcmFkaXVzID0gdV9tYXhfcmFkaXVzX1MxX2MwICogdV9yYWRpdXNfc2NhbGVfUzFfYzA7CglmbG9hdDIgcGFyYW1fMTMgPSB1dl8xOwoJZmxvYXQgdHVyYnVsZW5jZSA9IEZMVF9mbHV0dGVyX2xvY2FsX3R1cmJ1bGVuY2VfUzFfYzAocGFyYW1fMTMpOwoJZmxvYXQyIHBhcmFtXzE0ID0gcDsKCWZsb2F0MiBwYXJhbV8xNSA9IHVfY2VudGVyX1MxX2MwOwoJZmxvYXQgcGFyYW1fMTYgPSByYWRpdXM7CglmbG9hdCBwYXJhbV8xNyA9IDAuMDUgKiB1X21heF9yYWRpdXNfUzFfYzA7CglmbG9hdCBwYXJhbV8xOCA9IHVfYmx1cl9TMV9jMDsKCWZsb2F0IHJpbmcgPSBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X3JpbmdfUzFfYzAocGFyYW1fMTQsIHBhcmFtXzE1LCBwYXJhbV8xNiwgcGFyYW1fMTcsIHBhcmFtXzE4KTsKCWZsb2F0MiBwYXJhbV8xOSA9IGRlbnNpdHlfdXY7CglmbG9hdCBwYXJhbV8yMCA9IHVfbm9pc2VfcGhhc2VfUzFfYzA7CglmbG9hdCBzcGFya2xlID0gKChGTFRfZmx1dHRlcl9sb2NhbF9zcGFya2xlX1MxX2MwKHBhcmFtXzE5LCBwYXJhbV8yMCkgKiByaW5nKSAqIHR1cmJ1bGVuY2UpICogdV9zcGFya2xlX2FscGhhX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzIxID0gcDsKCWZsb2F0MiBwYXJhbV8yMiA9IHVfY2VudGVyX1MxX2MwOwoJZmxvYXQgcGFyYW1fMjMgPSByYWRpdXM7CglmbG9hdCBwYXJhbV8yNCA9IHVfYmx1cl9TMV9jMDsKCWZsb2F0IHdhdmVfYWxwaGEgPSAoRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW1fMjEsIHBhcmFtXzIyLCBwYXJhbV8yMywgcGFyYW1fMjQpICogdV9hbHBoYV9TMV9jMCkgKiB1X2NvbG9yX1MxX2MwLnc7CglmbG9hdDQgd2F2ZV9jb2xvciA9IGZsb2F0NCh1X2NvbG9yX1MxX2MwLnh5eiAqIHdhdmVfYWxwaGEsIHdhdmVfYWxwaGEpOwoJZnJhZ0NvbG9yX1MxX2MwID0gbWl4KHdhdmVfY29sb3IsIGZsb2F0NCgxLjApLCBmbG9hdDQoc3BhcmtsZSkpOwp9CmhhbGY0IHJ1bnRpbWVfc2hhZGVyX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJZmxvYXQyIF90bXBfMV9jb29yZHMgPSB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKCWZsdXR0ZXJfRnJhZ0Nvb3JkX1MxX2MwID0gZmxvYXQ0KF90bXBfMV9jb29yZHMsIDAuMCwgMC4wKTsKCUZMVF9tYWluX1MxX2MwKCk7CglyZXR1cm4gaGFsZjQoaGFsZjQoZnJhZ0NvbG9yX1MxX2MwKSk7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBydW50aW1lX3NoYWRlcl9TMV9jMChfaW5wdXQpOwp9CmhhbGY0IENpcmN1bGFyUlJlY3RfUzIoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQgZHkwID0gdWlubmVyUmVjdF9TMi5UIC0gc2tfRnJhZ0Nvb3JkLnk7CglmbG9hdDIgZHh5MSA9IHNrX0ZyYWdDb29yZC54eSAtIHVpbm5lclJlY3RfUzIuUkI7CglmbG9hdDIgZHh5ID0gbWF4KGZsb2F0MihkeHkxLngsIG1heChkeTAsIGR4eTEueSkpLCAwLjApOwoJaGFsZiBsZWZ0QWxwaGEgPSBoYWxmKHNhdHVyYXRlKHNrX0ZyYWdDb29yZC54IC0gdWlubmVyUmVjdF9TMi5MKSk7CgloYWxmIGFscGhhID0gbGVmdEFscGhhICogaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzIueCAtIGxlbmd0aChkeHkpKSk7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWZsb2F0IGNvdmVyYWdlID0gdmNvdmVyYWdlX1MwOwoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChjb3ZlcmFnZSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBNYXRyaXhFZmZlY3RfUzEob3V0cHV0Q29sb3JfUzApOwoJaGFsZjQgb3V0cHV0X1MyOwoJb3V0cHV0X1MyID0gQ2lyY3VsYXJSUmVjdF9TMihvdXRwdXRDb3ZlcmFnZV9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0X1MxICogb3V0cHV0X1MyOwoJfQp9CgAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAAcG9zaXRpb24IAAAAY292ZXJhZ2UFAAAAY29sb3IAAAAKAAAAbG9jYWxDb29yZAAAAAAAAA==","AYAA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAAAAMYAAAAAAAQAAAABAMQAAAAA":"DAAAAExTS1PbAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgaW5Qb3NpdGlvbjsKaW4gaGFsZjQgaW5Db2xvcjsKaW4gZmxvYXQ0IGluQ2lyY2xlRWRnZTsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQ0IHZpbkNpcmNsZUVkZ2VfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJdmluQ2lyY2xlRWRnZV9TMCA9IGluQ2lyY2xlRWRnZTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8yX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgAAAAAAQwIAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQpub3BlcnNwZWN0aXZlIGluIGZsb2F0NCB2aW5DaXJjbGVFZGdlX1MwOwpub3BlcnNwZWN0aXZlIGluIGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgQ2lyY2xlR2VvbWV0cnlQcm9jZXNzb3IKCWZsb2F0NCBjaXJjbGVFZGdlOwoJY2lyY2xlRWRnZSA9IHZpbkNpcmNsZUVkZ2VfUzA7CgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmluQ29sb3JfUzA7CglmbG9hdCBkID0gbGVuZ3RoKGNpcmNsZUVkZ2UueHkpOwoJaGFsZiBkaXN0YW5jZVRvT3V0ZXJFZGdlID0gaGFsZihjaXJjbGVFZGdlLnogKiAoMS4wIC0gZCkpOwoJaGFsZiBlZGdlQWxwaGEgPSBzYXR1cmF0ZShkaXN0YW5jZVRvT3V0ZXJFZGdlKTsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoZWRnZUFscGhhKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAoAAABpblBvc2l0aW9uAAAHAAAAaW5Db2xvcgAMAAAAaW5DaXJjbGVFZGdlAAAAAA==","GYQACAAAAAMAADAAAIOAAAH677776IZOCAAP577777777777777777YBAAAAAAAAAAAHEADZAAAAAAIAAAAAAMYAAAAAAAQAAAABAMQAAAAAA":"DAAAAExTS1MaAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgcG9zaXRpb247CmluIGhhbGY0IGNvbG9yOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2Y29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cn0KAAABAAAA5gIAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQp1bmlmb3JtIGZsb2F0NCB1aW5uZXJSZWN0X1MxOwp1bmlmb3JtIGhhbGYyIHVyYWRpdXNQbHVzSGFsZl9TMTsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2Y29sb3JfUzA7CmhhbGY0IENpcmN1bGFyUlJlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MxLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MxLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CgloYWxmIGFscGhhID0gaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzEueCAtIGxlbmd0aChkeHkpKSk7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBDaXJjdWxhclJSZWN0X1MxKG91dHB1dENvdmVyYWdlX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAAAAAAAA==","G2QACAAAABAAADAAAIOAAAAADIIAAIRODAAP577774DSAIAA737777YBAAAAAAAAAAAHEADZAAAAAAIAAAAAAMYAAAAAAAQAAAABAMQAAAAAA":"DAAAAExTS1PqAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgcG9zaXRpb247CmluIGZsb2F0IGNvdmVyYWdlOwppbiBoYWxmNCBjb2xvcjsKaW4gZmxvYXQ0IGdlb21TdWJzZXQ7Cm5vcGVyc3BlY3RpdmUgb3V0IGhhbGY0IHZjb2xvcl9TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQgdmNvdmVyYWdlX1MwOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDQgdmdlb21TdWJzZXRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQyIHBvc2l0aW9uID0gcG9zaXRpb24ueHk7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCXZjb3ZlcmFnZV9TMCA9IGNvdmVyYWdlOwoJdmdlb21TdWJzZXRfUzAgPSBnZW9tU3Vic2V0OwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAQAAADMEAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7Cm5vcGVyc3BlY3RpdmUgaW4gaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0IHZjb3ZlcmFnZV9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdDQgdmdlb21TdWJzZXRfUzA7CmhhbGY0IENpcmN1bGFyUlJlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MxLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MxLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CgloYWxmIGFscGhhID0gaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzEueCAtIGxlbmd0aChkeHkpKSk7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWZsb2F0IGNvdmVyYWdlID0gdmNvdmVyYWdlX1MwOwoJZmxvYXQ0IGdlb1N1YnNldDsKCWdlb1N1YnNldCA9IHZnZW9tU3Vic2V0X1MwOwoJZmxvYXQ0IGRpc3RzNCA9IHNhdHVyYXRlKGZsb2F0NCgxLCAxLCAtMSwgLTEpICogKHNrX0ZyYWdDb29yZC54eXh5IC0gZ2VvU3Vic2V0KSk7CglmbG9hdDIgZGlzdHMyID0gZGlzdHM0Lnh5ICsgZGlzdHM0Lnp3IC0gMTsKCWNvdmVyYWdlID0gbWluKGNvdmVyYWdlLCBkaXN0czIueCAqIGRpc3RzMi55KTsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoY292ZXJhZ2UpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQ2lyY3VsYXJSUmVjdF9TMShvdXRwdXRDb3ZlcmFnZV9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAHBvc2l0aW9uCAAAAGNvdmVyYWdlBQAAAGNvbG9yAAAACgAAAGdlb21TdWJzZXQAAAAAAAA=","CMRQCIAABBYAAAEIXBAAACDQMAABRAFAAAAAAAAAAAAAAAGABQAAAAEAAAAAAAEEBQAAAAA":"DAAAAExTS1OZAgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0NCB1bG9jYWxNYXRyaXhfUzA7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiBmbG9hdDIgaW5FbGxpcHNlT2Zmc2V0OwppbiBmbG9hdDQgaW5FbGxpcHNlUmFkaWk7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2RWxsaXBzZU9mZnNldHNfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0NCB2RWxsaXBzZVJhZGlpX1MwOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgRWxsaXBzZUdlb21ldHJ5UHJvY2Vzc29yCgl2RWxsaXBzZU9mZnNldHNfUzAgPSBpbkVsbGlwc2VPZmZzZXQ7Cgl2RWxsaXBzZVJhZGlpX1MwID0gaW5FbGxpcHNlUmFkaWk7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8wX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJZmxvYXQyIF90bXBfMV9pblBvc2l0aW9uID0gdWxvY2FsTWF0cml4X1MwLnh6ICogaW5Qb3NpdGlvbiArIHVsb2NhbE1hdHJpeF9TMC55dzsKCXNrX1Bvc2l0aW9uID0gX3RtcF8wX2luUG9zaXRpb24ueHkwMTsKfQoAAAAAAAAA2QMAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2RWxsaXBzZU9mZnNldHNfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQ0IHZFbGxpcHNlUmFkaWlfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBFbGxpcHNlR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWZsb2F0MiBvZmZzZXQgPSB2RWxsaXBzZU9mZnNldHNfUzAueHk7CglvZmZzZXQgKj0gdkVsbGlwc2VSYWRpaV9TMC54eTsKCWZsb2F0IHRlc3QgPSBkb3Qob2Zmc2V0LCBvZmZzZXQpIC0gMS4wOwoJZmxvYXQyIGdyYWQgPSAyLjAqb2Zmc2V0KnZFbGxpcHNlUmFkaWlfUzAueHk7CglmbG9hdCBncmFkX2RvdCA9IGRvdChncmFkLCBncmFkKTsKCWdyYWRfZG90ID0gbWF4KGdyYWRfZG90LCAxLjE3NTVlLTM4KTsKCWZsb2F0IGludmxlbiA9IGludmVyc2VzcXJ0KGdyYWRfZG90KTsKCWZsb2F0IGVkZ2VBbHBoYSA9IHNhdHVyYXRlKDAuNS10ZXN0Kmludmxlbik7CglvZmZzZXQgPSB2RWxsaXBzZU9mZnNldHNfUzAueHkqdkVsbGlwc2VSYWRpaV9TMC56dzsKCXRlc3QgPSBkb3Qob2Zmc2V0LCBvZmZzZXQpIC0gMS4wOwoJZ3JhZCA9IDIuMCpvZmZzZXQqdkVsbGlwc2VSYWRpaV9TMC56dzsKCWdyYWRfZG90ID0gZG90KGdyYWQsIGdyYWQpOwoJaW52bGVuID0gaW52ZXJzZXNxcnQoZ3JhZF9kb3QpOwoJZWRnZUFscGhhICo9IHNhdHVyYXRlKDAuNSt0ZXN0Kmludmxlbik7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGhhbGYoZWRnZUFscGhhKSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAoAAABpblBvc2l0aW9uAAAHAAAAaW5Db2xvcgAPAAAAaW5FbGxpcHNlT2Zmc2V0AA4AAABpbkVsbGlwc2VSYWRpaQAAAAAAAA==","GYJAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAQAAAAAAQQGAAZAADIAAAAIH5K3LIKAAAAAAMAAAAAIAAAAAAFMZBQP3FQWAUAABQAAAAAAAAAAAAADGAAAAAAAEAAAAAIDEAAA":"DAAAAExTS1MwAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgcG9zaXRpb247CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmxvY2FsQ29vcmRfUzAgPSBsb2NhbENvb3JkOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgEAAADzBAAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCmNvbnN0IGludCBrRmlsbEFBX1MxX2MwID0gMTsKY29uc3QgaW50IGtJbnZlcnNlRmlsbEJXX1MxX2MwID0gMjsKY29uc3QgaW50IGtJbnZlcnNlRmlsbEFBX1MxX2MwID0gMzsKdW5pZm9ybSBmbG9hdDQgdWNpcmNsZV9TMV9jMDsKc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2bG9jYWxDb29yZF9TMDsKaGFsZjQgQ2lyY2xlX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJaGFsZiBkOwoJaWYgKGludCgxKSA9PSBrSW52ZXJzZUZpbGxCV19TMV9jMCB8fCBpbnQoMSkgPT0ga0ludmVyc2VGaWxsQUFfUzFfYzApIAoJewoJCWQgPSBoYWxmKChsZW5ndGgoKHVjaXJjbGVfUzFfYzAueHkgLSBza19GcmFnQ29vcmQueHkpICogdWNpcmNsZV9TMV9jMC53KSAtIDEuMCkgKiB1Y2lyY2xlX1MxX2MwLnopOwoJfQoJZWxzZSAKCXsKCQlkID0gaGFsZigoMS4wIC0gbGVuZ3RoKCh1Y2lyY2xlX1MxX2MwLnh5IC0gc2tfRnJhZ0Nvb3JkLnh5KSAqIHVjaXJjbGVfUzFfYzAudykpICogdWNpcmNsZV9TMV9jMC56KTsKCX0KCXJldHVybiBoYWxmNChoYWxmNChpbnQoMSkgPT0ga0ZpbGxBQV9TMV9jMCB8fCBpbnQoMSkgPT0ga0ludmVyc2VGaWxsQUFfUzFfYzAgPyBzYXR1cmF0ZShkKSA6IGhhbGYoZCA+IDAuNSkpKTsKfQpoYWxmNCBCbGVuZF9TMShoYWxmNCBfc3JjLCBoYWxmNCBfZHN0KSAKewoJcmV0dXJuIGJsZW5kX21vZHVsYXRlKF9zcmMsIENpcmNsZV9TMV9jMChfc3JjKSk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWZsb2F0MiB0ZXhDb29yZDsKCXRleENvb3JkID0gdmxvY2FsQ29vcmRfUzA7CglvdXRwdXRDb2xvcl9TMCA9IChibGVuZF9tb2R1bGF0ZShzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzAsIHRleENvb3JkKSwgaGFsZjQoMSkpKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBCbGVuZF9TMShvdXRwdXRDb3ZlcmFnZV9TMCwgaGFsZjQoMSkpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0X1MxOwoJfQp9CgABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgoAAABsb2NhbENvb3JkAAAAAAAA","EEAQMYAAMAAAEADAAABAEYAAAICIAB5AABQAAAQAMAAAEATAAABAIIGAAEDCBYQCA4AAAAAAEAB5AAAAAAYFRP5FIUAQAADQAAAABAAAAAAABQEKBTLG62KRAAAAAHAAAAAAAAAAAAYAGAAAAAQAAAAAAAQQGAAA":"DAAAAExTS1MoDAAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDQgcmFkaWlfc2VsZWN0b3I7CmluIGZsb2F0NCBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzOwppbiBmbG9hdDQgYWFfYmxvYXRfYW5kX2NvdmVyYWdlOwppbiBmbG9hdDQgcmFkaWlfeDsKaW4gZmxvYXQ0IHJhZGlpX3k7CmluIGZsb2F0NCBza2V3OwppbiBmbG9hdDIgdHJhbnNsYXRlX2FuZF9sb2NhbHJvdGF0ZTsKaW4gaGFsZjQgY29sb3I7Cm5vcGVyc3BlY3RpdmUgb3V0IGhhbGY0IHZjb2xvcl9TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQyIHZhcmNjb29yZF9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgRmlsbFJSZWN0T3A6OlByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7CglmbG9hdCBhYV9ibG9hdF9tdWx0aXBsaWVyID0gMTsKCWZsb2F0MiBjb3JuZXIgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnh5OwoJZmxvYXQyIHJhZGl1c19vdXRzZXQgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnp3OwoJZmxvYXQyIGFhX2Jsb2F0X2RpcmVjdGlvbiA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS54eTsKCWZsb2F0IGlzX2xpbmVhcl9jb3ZlcmFnZSA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS53OwoJZmxvYXQyIHBpeGVsbGVuZ3RoID0gaW52ZXJzZXNxcnQoZmxvYXQyKGRvdChza2V3Lnh6LCBza2V3Lnh6KSwgZG90KHNrZXcueXcsIHNrZXcueXcpKSk7CglmbG9hdDQgbm9ybWFsaXplZF9heGlzX2RpcnMgPSBza2V3ICogcGl4ZWxsZW5ndGgueHl4eTsKCWZsb2F0MiBheGlzd2lkdGhzID0gKGFicyhub3JtYWxpemVkX2F4aXNfZGlycy54eSkgKyBhYnMobm9ybWFsaXplZF9heGlzX2RpcnMuencpKTsKCWZsb2F0MiBhYV9ibG9hdHJhZGl1cyA9IGF4aXN3aWR0aHMgKiBwaXhlbGxlbmd0aCAqIC41OwoJZmxvYXQ0IHJhZGlpX2FuZF9uZWlnaGJvcnMgPSByYWRpaV9zZWxlY3RvciogZmxvYXQ0eDQocmFkaWlfeCwgcmFkaWlfeSwgcmFkaWlfeC55eHd6LCByYWRpaV95Lnd6eXgpOwoJZmxvYXQyIHJhZGlpID0gcmFkaWlfYW5kX25laWdoYm9ycy54eTsKCWZsb2F0MiBuZWlnaGJvcl9yYWRpaSA9IHJhZGlpX2FuZF9uZWlnaGJvcnMuenc7CglmbG9hdCBjb3ZlcmFnZV9tdWx0aXBsaWVyID0gMTsKCWlmIChhbnkoZ3JlYXRlclRoYW4oYWFfYmxvYXRyYWRpdXMsIGZsb2F0MigxKSkpKSAKCXsKCQljb3JuZXIgPSBtYXgoYWJzKGNvcm5lciksIGFhX2Jsb2F0cmFkaXVzKSAqIHNpZ24oY29ybmVyKTsKCQljb3ZlcmFnZV9tdWx0aXBsaWVyID0gMSAvIChtYXgoYWFfYmxvYXRyYWRpdXMueCwgMSkgKiBtYXgoYWFfYmxvYXRyYWRpdXMueSwgMSkpOwoJCXJhZGlpID0gZmxvYXQyKDApOwoJfQoJZmxvYXQgY292ZXJhZ2UgPSBhYV9ibG9hdF9hbmRfY292ZXJhZ2UuejsKCWlmIChhbnkobGVzc1RoYW4ocmFkaWksIGFhX2Jsb2F0cmFkaXVzICogMS41KSkpIAoJewoJCXJhZGlpID0gZmxvYXQyKDApOwoJCWFhX2Jsb2F0X2RpcmVjdGlvbiA9IHNpZ24oY29ybmVyKTsKCQlpZiAoY292ZXJhZ2UgPiAuNSkgCgkJewoJCQlhYV9ibG9hdF9kaXJlY3Rpb24gPSAtYWFfYmxvYXRfZGlyZWN0aW9uOwoJCX0KCQlpc19saW5lYXJfY292ZXJhZ2UgPSAxOwoJfQoJZWxzZSAKCXsKCQlyYWRpaSA9IGNsYW1wKHJhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQluZWlnaGJvcl9yYWRpaSA9IGNsYW1wKG5laWdoYm9yX3JhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQlmbG9hdDIgc3BhY2luZyA9IDIgLSByYWRpaSAtIG5laWdoYm9yX3JhZGlpOwoJCWZsb2F0MiBleHRyYV9wYWQgPSBtYXgocGl4ZWxsZW5ndGggKiAuMDYyNSAtIHNwYWNpbmcsIGZsb2F0MigwKSk7CgkJcmFkaWkgLT0gZXh0cmFfcGFkICogLjU7Cgl9CglmbG9hdDIgYWFfb3V0c2V0ID0gYWFfYmxvYXRfZGlyZWN0aW9uICogYWFfYmxvYXRyYWRpdXMgKiBhYV9ibG9hdF9tdWx0aXBsaWVyOwoJZmxvYXQyIHZlcnRleHBvcyA9IGNvcm5lciArIHJhZGl1c19vdXRzZXQgKiByYWRpaSArIGFhX291dHNldDsKCWlmIChjb3ZlcmFnZSA+IC41KSAKCXsKCQlpZiAoYWFfYmxvYXRfZGlyZWN0aW9uLnggIT0gMCAmJiB2ZXJ0ZXhwb3MueCAqIGNvcm5lci54IDwgMCkgCgkJewoJCQlmbG9hdCBiYWNrc2V0ID0gYWJzKHZlcnRleHBvcy54KTsKCQkJdmVydGV4cG9zLnggPSAwOwoJCQl2ZXJ0ZXhwb3MueSArPSBiYWNrc2V0ICogc2lnbihjb3JuZXIueSkgKiBwaXhlbGxlbmd0aC55L3BpeGVsbGVuZ3RoLng7CgkJCWNvdmVyYWdlID0gKGNvdmVyYWdlIC0gLjUpICogYWJzKGNvcm5lci54KSAvIChhYnMoY29ybmVyLngpICsgYmFja3NldCkgKyAuNTsKCQl9CgkJaWYgKGFhX2Jsb2F0X2RpcmVjdGlvbi55ICE9IDAgJiYgdmVydGV4cG9zLnkgKiBjb3JuZXIueSA8IDApIAoJCXsKCQkJZmxvYXQgYmFja3NldCA9IGFicyh2ZXJ0ZXhwb3MueSk7CgkJCXZlcnRleHBvcy55ID0gMDsKCQkJdmVydGV4cG9zLnggKz0gYmFja3NldCAqIHNpZ24oY29ybmVyLngpICogcGl4ZWxsZW5ndGgueC9waXhlbGxlbmd0aC55OwoJCQljb3ZlcmFnZSA9IChjb3ZlcmFnZSAtIC41KSAqIGFicyhjb3JuZXIueSkgLyAoYWJzKGNvcm5lci55KSArIGJhY2tzZXQpICsgLjU7CgkJfQoJfQoJZmxvYXQyeDIgc2tld21hdHJpeCA9IGZsb2F0MngyKHNrZXcueHksIHNrZXcuencpOwoJZmxvYXQyIGRldmNvb3JkID0gdmVydGV4cG9zICogc2tld21hdHJpeCArIHRyYW5zbGF0ZV9hbmRfbG9jYWxyb3RhdGUueHk7CglpZiAoMCAhPSBpc19saW5lYXJfY292ZXJhZ2UpIAoJewoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MigwLCBjb3ZlcmFnZSAqIGNvdmVyYWdlX211bHRpcGxpZXIpOwoJfQoJZWxzZSAKCXsKCQlmbG9hdDIgYXJjY29vcmQgPSAxIC0gYWJzKHJhZGl1c19vdXRzZXQpICsgYWFfb3V0c2V0L3JhZGlpICogY29ybmVyOwoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MihhcmNjb29yZC54KzEsIGFyY2Nvb3JkLnkpOwoJfQoJc2tfUG9zaXRpb24gPSBkZXZjb29yZC54eTAxOwp9CgEAAACdBQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCmNvbnN0IGludCBrRmlsbEFBX1MxX2MwID0gMTsKY29uc3QgaW50IGtJbnZlcnNlRmlsbEJXX1MxX2MwID0gMjsKY29uc3QgaW50IGtJbnZlcnNlRmlsbEFBX1MxX2MwID0gMzsKdW5pZm9ybSBmbG9hdDQgdWNpcmNsZV9TMV9jMDsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQyIHZhcmNjb29yZF9TMDsKaGFsZjQgQ2lyY2xlX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJaGFsZiBkOwoJaWYgKGludCgzKSA9PSBrSW52ZXJzZUZpbGxCV19TMV9jMCB8fCBpbnQoMykgPT0ga0ludmVyc2VGaWxsQUFfUzFfYzApIAoJewoJCWQgPSBoYWxmKChsZW5ndGgoKHVjaXJjbGVfUzFfYzAueHkgLSBza19GcmFnQ29vcmQueHkpICogdWNpcmNsZV9TMV9jMC53KSAtIDEuMCkgKiB1Y2lyY2xlX1MxX2MwLnopOwoJfQoJZWxzZSAKCXsKCQlkID0gaGFsZigoMS4wIC0gbGVuZ3RoKCh1Y2lyY2xlX1MxX2MwLnh5IC0gc2tfRnJhZ0Nvb3JkLnh5KSAqIHVjaXJjbGVfUzFfYzAudykpICogdWNpcmNsZV9TMV9jMC56KTsKCX0KCXJldHVybiBoYWxmNChoYWxmNChpbnQoMykgPT0ga0ZpbGxBQV9TMV9jMCB8fCBpbnQoMykgPT0ga0ludmVyc2VGaWxsQUFfUzFfYzAgPyBzYXR1cmF0ZShkKSA6IGhhbGYoZCA+IDAuNSkpKTsKfQpoYWxmNCBCbGVuZF9TMShoYWxmNCBfc3JjLCBoYWxmNCBfZHN0KSAKewoJcmV0dXJuIGJsZW5kX21vZHVsYXRlKF9zcmMsIENpcmNsZV9TMV9jMChfc3JjKSk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIEZpbGxSUmVjdE9wOjpQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7CglmbG9hdCB4X3BsdXNfMT12YXJjY29vcmRfUzAueCwgeT12YXJjY29vcmRfUzAueTsKCWhhbGYgY292ZXJhZ2U7CglpZiAoMCA9PSB4X3BsdXNfMSkgCgl7CgkJY292ZXJhZ2UgPSBoYWxmKHkpOwoJfQoJZWxzZSAKCXsKCQlmbG9hdCBmbiA9IHhfcGx1c18xICogKHhfcGx1c18xIC0gMik7CgkJZm4gPSBmbWEoeSx5LCBmbik7CgkJZmxvYXQgZm53aWR0aCA9IGZ3aWR0aChmbik7CgkJY292ZXJhZ2UgPSAuNSAtIGhhbGYoZm4vZm53aWR0aCk7CgkJY292ZXJhZ2UgPSBjbGFtcChjb3ZlcmFnZSwgMCwgMSk7Cgl9CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGNvdmVyYWdlKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IEJsZW5kX1MxKG91dHB1dENvdmVyYWdlX1MwLCBoYWxmNCgxKSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAOAAAAcmFkaWlfc2VsZWN0b3IAABkAAABjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzAAAAFQAAAGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZQAAAAcAAAByYWRpaV94AAcAAAByYWRpaV95AAQAAABza2V3GQAAAHRyYW5zbGF0ZV9hbmRfbG9jYWxyb3RhdGUAAAAFAAAAY29sb3IAAAAAAAAA","GYJAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAQAAAAAEQQGABZAA6IAAAAACAAAAAADGAAAAAAAEAAAAAIDEAAAAAAA":"DAAAAExTS1MwAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgcG9zaXRpb247CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmxvY2FsQ29vcmRfUzAgPSBsb2NhbENvb3JkOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgEAAACHAwAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHVpbm5lclJlY3RfUzE7CnVuaWZvcm0gaGFsZjIgdXJhZGl1c1BsdXNIYWxmX1MxOwpzYW1wbGVyRXh0ZXJuYWxPRVMgdVRleHR1cmVTYW1wbGVyXzBfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQyIHZsb2NhbENvb3JkX1MwOwpoYWxmNCBDaXJjdWxhclJSZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCWZsb2F0MiBkeHkwID0gdWlubmVyUmVjdF9TMS5MVCAtIHNrX0ZyYWdDb29yZC54eTsKCWZsb2F0MiBkeHkxID0gc2tfRnJhZ0Nvb3JkLnh5IC0gdWlubmVyUmVjdF9TMS5SQjsKCWZsb2F0MiBkeHkgPSBtYXgobWF4KGR4eTAsIGR4eTEpLCAwLjApOwoJaGFsZiBhbHBoYSA9IGhhbGYoc2F0dXJhdGUodXJhZGl1c1BsdXNIYWxmX1MxLnggLSBsZW5ndGgoZHh5KSkpOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwID0gaGFsZjQoMSk7CglmbG9hdDIgdGV4Q29vcmQ7Cgl0ZXhDb29yZCA9IHZsb2NhbENvb3JkX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSAoYmxlbmRfbW9kdWxhdGUoc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB0ZXhDb29yZCksIGhhbGY0KDEpKSk7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQ2lyY3VsYXJSUmVjdF9TMShvdXRwdXRDb3ZlcmFnZV9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACAAAAHBvc2l0aW9uCgAAAGxvY2FsQ29vcmQAAAAAAAA=","AYTRVAADQAAAOAEARAFQJAABBADAAAILBYAACCYUQD777777777767YAAAAAAAAAAAAMYAAAAAAAQAAAABAMQAAAAA":"DAAAAExTS1PnAgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0NCB1bG9jYWxNYXRyaXhfUzA7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiBmbG9hdDQgaW5DaXJjbGVFZGdlOwppbiBoYWxmMyBpbkNsaXBQbGFuZTsKaW4gaGFsZjMgaW5Jc2VjdFBsYW5lOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjMgdmluQ2xpcFBsYW5lX1MwOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmMyB2aW5Jc2VjdFBsYW5lX1MwOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgQ2lyY2xlR2VvbWV0cnlQcm9jZXNzb3IKCXZpbkNpcmNsZUVkZ2VfUzAgPSBpbkNpcmNsZUVkZ2U7Cgl2aW5DbGlwUGxhbmVfUzAgPSBpbkNsaXBQbGFuZTsKCXZpbklzZWN0UGxhbmVfUzAgPSBpbklzZWN0UGxhbmU7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8wX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJZmxvYXQyIF90bXBfMV9pblBvc2l0aW9uID0gdWxvY2FsTWF0cml4X1MwLnh6ICogaW5Qb3NpdGlvbiArIHVsb2NhbE1hdHJpeF9TMC55dzsKCXNrX1Bvc2l0aW9uID0gX3RtcF8wX2luUG9zaXRpb24ueHkwMTsKfQoAAAAAAFIEAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmMyB2aW5DbGlwUGxhbmVfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gaGFsZjMgdmluSXNlY3RQbGFuZV9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIENpcmNsZUdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDQgY2lyY2xlRWRnZTsKCWNpcmNsZUVkZ2UgPSB2aW5DaXJjbGVFZGdlX1MwOwoJaGFsZjMgY2xpcFBsYW5lOwoJY2xpcFBsYW5lID0gdmluQ2xpcFBsYW5lX1MwOwoJaGFsZjMgaXNlY3RQbGFuZTsKCWlzZWN0UGxhbmUgPSB2aW5Jc2VjdFBsYW5lX1MwOwoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZpbkNvbG9yX1MwOwoJZmxvYXQgZCA9IGxlbmd0aChjaXJjbGVFZGdlLnh5KTsKCWhhbGYgZGlzdGFuY2VUb091dGVyRWRnZSA9IGhhbGYoY2lyY2xlRWRnZS56ICogKDEuMCAtIGQpKTsKCWhhbGYgZWRnZUFscGhhID0gc2F0dXJhdGUoZGlzdGFuY2VUb091dGVyRWRnZSk7CgloYWxmIGRpc3RhbmNlVG9Jbm5lckVkZ2UgPSBoYWxmKGNpcmNsZUVkZ2UueiAqIChkIC0gY2lyY2xlRWRnZS53KSk7CgloYWxmIGlubmVyQWxwaGEgPSBzYXR1cmF0ZShkaXN0YW5jZVRvSW5uZXJFZGdlKTsKCWVkZ2VBbHBoYSAqPSBpbm5lckFscGhhOwoJaGFsZiBjbGlwID0gaGFsZihzYXR1cmF0ZShjaXJjbGVFZGdlLnogKiBkb3QoY2lyY2xlRWRnZS54eSwgY2xpcFBsYW5lLnh5KSArIGNsaXBQbGFuZS56KSk7CgljbGlwICo9IGhhbGYoc2F0dXJhdGUoY2lyY2xlRWRnZS56ICogZG90KGNpcmNsZUVkZ2UueHksIGlzZWN0UGxhbmUueHkpICsgaXNlY3RQbGFuZS56KSk7CgllZGdlQWxwaGEgKj0gY2xpcDsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoZWRnZUFscGhhKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADAAAAGluQ2lyY2xlRWRnZQsAAABpbkNsaXBQbGFuZQAMAAAAaW5Jc2VjdFBsYW5lAAAAAA==","G2JAAAAAAAUAADAAAIOAAAAADIIAB7X7777QGHAYAD7P7777777777YBAAAAAAQAAAAAAQQGAAYAGAAAAAQAAAAAAAQQGAAA":"DAAAAExTS1OjAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgcG9zaXRpb247CmluIGZsb2F0IGNvdmVyYWdlOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQyIHZsb2NhbENvb3JkX1MwOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdCB2Y292ZXJhZ2VfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQyIHBvc2l0aW9uID0gcG9zaXRpb24ueHk7Cgl2bG9jYWxDb29yZF9TMCA9IGxvY2FsQ29vcmQ7Cgl2Y292ZXJhZ2VfUzAgPSBjb3ZlcmFnZTsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKfQoAAAAAADUCAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2bG9jYWxDb29yZF9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdCB2Y292ZXJhZ2VfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwID0gaGFsZjQoMSk7CglmbG9hdDIgdGV4Q29vcmQ7Cgl0ZXhDb29yZCA9IHZsb2NhbENvb3JkX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSAoYmxlbmRfbW9kdWxhdGUoc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB0ZXhDb29yZCksIGhhbGY0KDEpKSk7CglmbG9hdCBjb3ZlcmFnZSA9IHZjb3ZlcmFnZV9TMDsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoY292ZXJhZ2UpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAIAAAAcG9zaXRpb24IAAAAY292ZXJhZ2UKAAAAbG9jYWxDb29yZAAAAAAAAA==","GYJQAAAAABAAADAAAIOAAAH677777777777QGHAQAD7P7777A4QCAAAAAAAAAAQAAAAAAQQGAAYAGAAAAAQAAAAAAAQQGAAA":"DAAAAExTS1OJAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgcG9zaXRpb247CmluIGZsb2F0MiBsb2NhbENvb3JkOwppbiBmbG9hdDQgdGV4U3Vic2V0Owpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0NCB2dGV4U3Vic2V0X1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCXZsb2NhbENvb3JkX1MwID0gbG9jYWxDb29yZDsKCXZ0ZXhTdWJzZXRfUzAgPSB0ZXhTdWJzZXQ7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAAAHICAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2bG9jYWxDb29yZF9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdDQgdnRleFN1YnNldF9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWZsb2F0MiB0ZXhDb29yZDsKCXRleENvb3JkID0gdmxvY2FsQ29vcmRfUzA7CglmbG9hdDQgc3Vic2V0OwoJc3Vic2V0ID0gdnRleFN1YnNldF9TMDsKCXRleENvb3JkID0gY2xhbXAodGV4Q29vcmQsIHN1YnNldC5MVCwgc3Vic2V0LlJCKTsKCW91dHB1dENvbG9yX1MwID0gKGJsZW5kX21vZHVsYXRlKHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMCwgdGV4Q29vcmQpLCBoYWxmNCgxKSkpOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAIAAAAcG9zaXRpb24KAAAAbG9jYWxDb29yZAAACQAAAHRleFN1YnNldAAAAAAAAAA=","G2JQAAAAABEAADAAAIOAAAAADIIAB7X7777QGHAYAD7P7777A4QCQAAAAAAAAAQAAAAAAQQGAAYAGAAAAAQAAAAAAAQQGAAA":"DAAAAExTS1P8AQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgcG9zaXRpb247CmluIGZsb2F0IGNvdmVyYWdlOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKaW4gZmxvYXQ0IHRleFN1YnNldDsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQyIHZsb2NhbENvb3JkX1MwOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDQgdnRleFN1YnNldF9TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQgdmNvdmVyYWdlX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWZsb2F0MiBwb3NpdGlvbiA9IHBvc2l0aW9uLnh5OwoJdmxvY2FsQ29vcmRfUzAgPSBsb2NhbENvb3JkOwoJdnRleFN1YnNldF9TMCA9IHRleFN1YnNldDsKCXZjb3ZlcmFnZV9TMCA9IGNvdmVyYWdlOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAAC4AgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQ0IHZ0ZXhTdWJzZXRfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQgdmNvdmVyYWdlX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMCA9IGhhbGY0KDEpOwoJZmxvYXQyIHRleENvb3JkOwoJdGV4Q29vcmQgPSB2bG9jYWxDb29yZF9TMDsKCWZsb2F0NCBzdWJzZXQ7CglzdWJzZXQgPSB2dGV4U3Vic2V0X1MwOwoJdGV4Q29vcmQgPSBjbGFtcCh0ZXhDb29yZCwgc3Vic2V0LkxULCBzdWJzZXQuUkIpOwoJb3V0cHV0Q29sb3JfUzAgPSAoYmxlbmRfbW9kdWxhdGUoc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB0ZXhDb29yZCksIGhhbGY0KDEpKSk7CglmbG9hdCBjb3ZlcmFnZSA9IHZjb3ZlcmFnZV9TMDsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoY292ZXJhZ2UpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAAcG9zaXRpb24IAAAAY292ZXJhZ2UKAAAAbG9jYWxDb29yZAAACQAAAHRleFN1YnNldAAAAAAAAAA=","GZIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAHIBIA5HZ2CAAAAAAAEAQCAAAAASBEEAQAAAAAUCCQAQQGAABAEAAAAAAGMAAAAAAAIAAAAAQGIAAAAAAA":"DAAAAExTS1POAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzA7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfM19TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzFfYzApICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAAAAcwQAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQp1bmlmb3JtIGZsb2F0NCB1Y2xhbXBfUzFfYzBfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMDsKc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MxOwpub3BlcnNwZWN0aXZlIGluIGhhbGY0IHZjb2xvcl9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzNfUzA7CmhhbGY0IFRleHR1cmVFZmZlY3RfUzFfYzBfYzAoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGluQ29vcmQgPSB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKCWZsb2F0MiBzdWJzZXRDb29yZDsKCXN1YnNldENvb3JkLnggPSBpbkNvb3JkLng7CglzdWJzZXRDb29yZC55ID0gaW5Db29yZC55OwoJZmxvYXQyIGNsYW1wZWRDb29yZDsKCWNsYW1wZWRDb29yZCA9IGNsYW1wKHN1YnNldENvb3JkLCB1Y2xhbXBfUzFfYzBfYzAueHksIHVjbGFtcF9TMV9jMF9jMC56dyk7CgloYWxmNCB0ZXh0dXJlQ29sb3IgPSBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzEsIGNsYW1wZWRDb29yZCk7CglyZXR1cm4gdGV4dHVyZUNvbG9yOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gVGV4dHVyZUVmZmVjdF9TMV9jMF9jMChfaW5wdXQpOwp9CmhhbGY0IERpc2FibGVDb3ZlcmFnZUFzQWxwaGFfUzEoaGFsZjQgX2lucHV0KSAKewoJX2lucHV0ID0gTWF0cml4RWZmZWN0X1MxX2MwKF9pbnB1dCk7CgloYWxmNCBfdG1wXzBfaW5Db2xvciA9IF9pbnB1dDsKCXJldHVybiBoYWxmNChfaW5wdXQpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gRGlzYWJsZUNvdmVyYWdlQXNBbHBoYV9TMShvdXRwdXRDb2xvcl9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0X1MxICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","DAQAAAAAAAAAAAAAAJQAAIGAAEACBYQCAGAEFAIBAAAAAABAAAAAAAAAAAACAA6QAAAABYCTIUIE4AIAAAYAAAAAQAAAAAGARL4FIEMEKMAAAAAMAAAAAAAAAAAAAMADAAAAAIAAAAAAAIIDAAAA":"DAAAAExTS1N4AgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0MiB1QXRsYXNTaXplSW52X1MwOwppbiBmbG9hdDIgaW5Qb3NpdGlvbjsKaW4gaGFsZjQgaW5Db2xvcjsKaW4gdXNob3J0MiBpblRleHR1cmVDb29yZHM7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQgdlRleEluZGV4X1MwOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgQml0bWFwVGV4dAoJaW50IHRleElkeCA9IDA7CglmbG9hdDIgdW5vcm1UZXhDb29yZHMgPSBmbG9hdDIoaW5UZXh0dXJlQ29vcmRzLngsIGluVGV4dHVyZUNvb3Jkcy55KTsKCXZUZXh0dXJlQ29vcmRzX1MwID0gdW5vcm1UZXhDb29yZHMgKiB1QXRsYXNTaXplSW52X1MwOwoJdlRleEluZGV4X1MwID0gZmxvYXQodGV4SWR4KTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzFfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247Cglza19Qb3NpdGlvbiA9IGluUG9zaXRpb24ueHkwMTsKfQoBAAAAnwUAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQpjb25zdCBpbnQga0ZpbGxCV19TMV9jMCA9IDA7CmNvbnN0IGludCBrSW52ZXJzZUZpbGxCV19TMV9jMCA9IDI7CmNvbnN0IGludCBrSW52ZXJzZUZpbGxBQV9TMV9jMCA9IDM7CnVuaWZvcm0gZmxvYXQ0IHVyZWN0VW5pZm9ybV9TMV9jMDsKc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdCB2VGV4SW5kZXhfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gaGFsZjQgdmluQ29sb3JfUzA7CmhhbGY0IFJlY3RfUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF8wX2luQ29sb3IgPSBfaW5wdXQ7CgloYWxmIGNvdmVyYWdlOwoJaWYgKGludCgxKSA9PSBrRmlsbEJXX1MxX2MwIHx8IGludCgxKSA9PSBrSW52ZXJzZUZpbGxCV19TMV9jMCkgCgl7CgkJY292ZXJhZ2UgPSBoYWxmKGFsbChncmVhdGVyVGhhbihmbG9hdDQoc2tfRnJhZ0Nvb3JkLnh5LCB1cmVjdFVuaWZvcm1fUzFfYzAuencpLCBmbG9hdDQodXJlY3RVbmlmb3JtX1MxX2MwLnh5LCBza19GcmFnQ29vcmQueHkpKSkpOwoJfQoJZWxzZSAKCXsKCQloYWxmNCBkaXN0czQgPSBzYXR1cmF0ZShoYWxmNCgxLjAsIDEuMCwgLTEuMCwgLTEuMCkgKiBoYWxmNChza19GcmFnQ29vcmQueHl4eSAtIHVyZWN0VW5pZm9ybV9TMV9jMCkpOwoJCWhhbGYyIGRpc3RzMiA9IChkaXN0czQueHkgKyBkaXN0czQuencpIC0gMS4wOwoJCWNvdmVyYWdlID0gZGlzdHMyLnggKiBkaXN0czIueTsKCX0KCWlmIChpbnQoMSkgPT0ga0ludmVyc2VGaWxsQldfUzFfYzAgfHwgaW50KDEpID09IGtJbnZlcnNlRmlsbEFBX1MxX2MwKSAKCXsKCQljb3ZlcmFnZSA9IDEuMCAtIGNvdmVyYWdlOwoJfQoJcmV0dXJuIGhhbGY0KGhhbGY0KGNvdmVyYWdlKSk7Cn0KaGFsZjQgQmxlbmRfUzEoaGFsZjQgX3NyYywgaGFsZjQgX2RzdCkgCnsKCXJldHVybiBibGVuZF9tb2R1bGF0ZShSZWN0X1MxX2MwKF9zcmMpLCBfc3JjKTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgQml0bWFwVGV4dAoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZpbkNvbG9yX1MwOwoJaGFsZjQgdGV4Q29sb3I7Cgl7CgkJdGV4Q29sb3IgPSBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzAsIHZUZXh0dXJlQ29vcmRzX1MwKS5ycnJyOwoJfQoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSB0ZXhDb2xvcjsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IEJsZW5kX1MxKG91dHB1dENvdmVyYWdlX1MwLCBoYWxmNCgxKSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACgAAAGluUG9zaXRpb24AAAcAAABpbkNvbG9yAA8AAABpblRleHR1cmVDb29yZHMAAAAAAA==","GZIACAAAABQAAGAAAQ4AAAAAGQQAARC4GAAAIOCAAD6P7777777777YDAAAAAAAAAAAHIBK2VD3EOCAAAAAABUXHIMAQAAAAWSQ4HO4SAAAAAMAAAAAAAAQAABANBBK3CICAAAEASHSVIGAAAAAAAAAAAEAABAAVAGSM7BYCAAAAA2CDQ53SKAIAABQAAAAAAACAAAEAUAF3OJAIAAAAAI6LVEYAAAAAAAAQAAAAFPJIMDXPJIBAAAGAAAAAAAAIAAAAAQIXNZERAAAAABDJMU3BAAAAAAAEAAAAAMQQAIAAAQGQQVNREBAAACAAAAAAQAKRC5HBSYCACAAAAAAAAAEAIRDJMU3BAAAAAAACAAAAAVTIMQ4RKBQAAAAAAAAAACAAIAIAAIAAAAC2BCEAQAAAAAAAAAAAMADAAAAAUAAAAAAAIIDA":"DAAAAExTS1NNAgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzBfYzBfYzE7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQgY292ZXJhZ2U7CmluIGhhbGY0IGNvbG9yOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdCB2Y292ZXJhZ2VfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfN19TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDIgcG9zaXRpb24gPSBwb3NpdGlvbi54eTsKCXZjb2xvcl9TMCA9IGNvbG9yOwoJdmNvdmVyYWdlX1MwID0gY292ZXJhZ2U7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzdfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxX2MwX2MwX2MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAEAAADKCgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gaGFsZjQgdXN0YXJ0X1MxX2MwX2MwX2MwX2MwOwp1bmlmb3JtIGhhbGY0IHVlbmRfUzFfYzBfYzBfYzBfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMF9jMTsKdW5pZm9ybSBoYWxmNCB1bGVmdEJvcmRlckNvbG9yX1MxX2MwX2MwOwp1bmlmb3JtIGhhbGY0IHVyaWdodEJvcmRlckNvbG9yX1MxX2MwX2MwOwp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzE7CnVuaWZvcm0gaGFsZiB1cmFuZ2VfUzE7CnNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMTsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQgdmNvdmVyYWdlX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfN19TMDsKaGFsZjQgU2luZ2xlSW50ZXJ2YWxDb2xvcml6ZXJfUzFfYzBfYzBfYzBfYzAoaGFsZjQgX2lucHV0LCBmbG9hdDIgX2Nvb3JkcykgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJZmxvYXQyIF90bXBfMV9jb29yZHMgPSBfY29vcmRzOwoJcmV0dXJuIGhhbGY0KG1peCh1c3RhcnRfUzFfYzBfYzBfYzBfYzAsIHVlbmRfUzFfYzBfYzBfYzBfYzAsIGhhbGYoX3RtcF8xX2Nvb3Jkcy54KSkpOwp9CmhhbGY0IGNvbG9yX3hmb3JtX1MxX2MwX2MwX2MwKGZsb2F0NCBjb2xvcikgCnsKCWNvbG9yLnJnYiAqPSBjb2xvci5hOwoJcmV0dXJuIGhhbGY0KGNvbG9yKTsKfQpoYWxmNCBDb2xvclNwYWNlWGZvcm1fUzFfYzBfYzBfYzAoaGFsZjQgX2lucHV0LCBmbG9hdDIgX2Nvb3JkcykgCnsKCXJldHVybiBjb2xvcl94Zm9ybV9TMV9jMF9jMF9jMChTaW5nbGVJbnRlcnZhbENvbG9yaXplcl9TMV9jMF9jMF9jMF9jMChfaW5wdXQsIF9jb29yZHMpKTsKfQpoYWxmNCBMaW5lYXJMYXlvdXRfUzFfYzBfYzBfYzFfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF8yX2luQ29sb3IgPSBfaW5wdXQ7CglmbG9hdDIgX3RtcF8zX2Nvb3JkcyA9IHZUcmFuc2Zvcm1lZENvb3Jkc183X1MwOwoJcmV0dXJuIGhhbGY0KGhhbGY0KGhhbGYoX3RtcF8zX2Nvb3Jkcy54KSArIDFlLTA1LCAxLjAsIDAuMCwgMC4wKSk7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxX2MwX2MwX2MxKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBMaW5lYXJMYXlvdXRfUzFfYzBfYzBfYzFfYzAoX2lucHV0KTsKfQpoYWxmNCBDbGFtcGVkR3JhZGllbnRfUzFfYzBfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF80X2luQ29sb3IgPSBfaW5wdXQ7CgloYWxmNCB0ID0gTWF0cml4RWZmZWN0X1MxX2MwX2MwX2MxKF90bXBfNF9pbkNvbG9yKTsKCWhhbGY0IG91dENvbG9yOwoJaWYgKCFib29sKGludCgxKSkgJiYgdC55IDwgMC4wKSAKCXsKCQlvdXRDb2xvciA9IGhhbGY0KDAuMCk7Cgl9CgllbHNlIGlmICh0LnggPCAwLjApIAoJewoJCW91dENvbG9yID0gdWxlZnRCb3JkZXJDb2xvcl9TMV9jMF9jMDsKCX0KCWVsc2UgaWYgKHQueCA+IDEuMCkgCgl7CgkJb3V0Q29sb3IgPSB1cmlnaHRCb3JkZXJDb2xvcl9TMV9jMF9jMDsKCX0KCWVsc2UgCgl7CgkJb3V0Q29sb3IgPSBDb2xvclNwYWNlWGZvcm1fUzFfYzBfYzBfYzAoX3RtcF80X2luQ29sb3IsIGZsb2F0MihoYWxmMih0LngsIDAuMCkpKTsKCX0KCXJldHVybiBoYWxmNChvdXRDb2xvcik7Cn0KaGFsZjQgRGlzYWJsZUNvdmVyYWdlQXNBbHBoYV9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CglfaW5wdXQgPSBDbGFtcGVkR3JhZGllbnRfUzFfYzBfYzAoX2lucHV0KTsKCWhhbGY0IF90bXBfNV9pbkNvbG9yID0gX2lucHV0OwoJcmV0dXJuIGhhbGY0KF9pbnB1dCk7Cn0KaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMV9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJcmV0dXJuIHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMSwgX2Nvb3JkcykuMDAwcjsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzFfYzEoaGFsZjQgX2lucHV0LCBmbG9hdDIgX2Nvb3JkcykgCnsKCXJldHVybiBUZXh0dXJlRWZmZWN0X1MxX2MxX2MwKF9pbnB1dCwgZmxvYXQzeDIodW1hdHJpeF9TMV9jMSkgKiBfY29vcmRzLnh5MSk7Cn0KaGFsZjQgRGl0aGVyX1MxKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfNl9pbkNvbG9yID0gX2lucHV0OwoJaGFsZjQgY29sb3IgPSBEaXNhYmxlQ292ZXJhZ2VBc0FscGhhX1MxX2MwKF90bXBfNl9pbkNvbG9yKTsKCWhhbGYgdmFsdWUgPSBNYXRyaXhFZmZlY3RfUzFfYzEoX3RtcF82X2luQ29sb3IsIHNrX0ZyYWdDb29yZC54eSkudyAtIDAuNTsKCXJldHVybiBoYWxmNChoYWxmNChjbGFtcChjb2xvci54eXogKyB2YWx1ZSAqIHVyYW5nZV9TMSwgMC4wLCBjb2xvci53KSwgY29sb3IudykpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7CglmbG9hdCBjb3ZlcmFnZSA9IHZjb3ZlcmFnZV9TMDsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoY292ZXJhZ2UpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gRGl0aGVyX1MxKG91dHB1dENvbG9yX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSAoaGFsZjQoMS4wKSAtIG91dHB1dF9TMSkgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAHBvc2l0aW9uCAAAAGNvdmVyYWdlBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","DASAAAAAAAAAAAEAAFQAAIGAAEAOB77776PUEAIBAAAAAABAAAAAAABAMQAAAMYAAAAAAAQAAAABAMQAAAAA":"DAAAAExTS1MpAgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0MiB1QXRsYXNTaXplSW52X1MwOwppbiBmbG9hdDIgaW5Qb3NpdGlvbjsKaW4gdXNob3J0MiBpblRleHR1cmVDb29yZHM7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQgdlRleEluZGV4X1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBCaXRtYXBUZXh0CglpbnQgdGV4SWR4ID0gMDsKCWZsb2F0MiB1bm9ybVRleENvb3JkcyA9IGZsb2F0MihpblRleHR1cmVDb29yZHMueCwgaW5UZXh0dXJlQ29vcmRzLnkpOwoJdlRleHR1cmVDb29yZHNfUzAgPSB1bm9ybVRleENvb3JkcyAqIHVBdGxhc1NpemVJbnZfUzA7Cgl2VGV4SW5kZXhfUzAgPSBmbG9hdCh0ZXhJZHgpOwoJZmxvYXQyIF90bXBfMV9pblBvc2l0aW9uID0gaW5Qb3NpdGlvbjsKCXNrX1Bvc2l0aW9uID0gaW5Qb3NpdGlvbi54eTAxOwp9CgAAAAAAAAAsAgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gaGFsZjQgdUNvbG9yX1MwOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQyIHZUZXh0dXJlQ29vcmRzX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0IHZUZXhJbmRleF9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIEJpdG1hcFRleHQKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB1Q29sb3JfUzA7CgloYWxmNCB0ZXhDb2xvcjsKCXsKCQl0ZXhDb2xvciA9IHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMCwgdlRleHR1cmVDb29yZHNfUzApOwoJfQoJb3V0cHV0Q29sb3JfUzAgPSBvdXRwdXRDb2xvcl9TMCAqIHRleENvbG9yOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACgAAAGluUG9zaXRpb24AAA8AAABpblRleHR1cmVDb29yZHMAAAAAAA==","GYJAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAQAAAAAAQQGAAZAADIAAAAAJKLCRQQAAAAAAMAAAAACAAAAAIAAAAALAIQEVFRIYIAAAAAAGAAAAABAAAAAAAAAAAAAGABQAAAAEAAAAAAAEEBQA":"DAAAAExTS1MwAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgcG9zaXRpb247CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmxvY2FsQ29vcmRfUzAgPSBsb2NhbENvb3JkOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgEAAACEBgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCmNvbnN0IGludCBrRmlsbEJXX1MxX2MwID0gMDsKY29uc3QgaW50IGtGaWxsQUFfUzFfYzAgPSAxOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQldfUzFfYzAgPSAyOwp1bmlmb3JtIGZsb2F0NCB1ZWxsaXBzZV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdXNjYWxlX1MxX2MwOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQyIHZsb2NhbENvb3JkX1MwOwpoYWxmNCBFbGxpcHNlX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJZmxvYXQyIGQgPSBza19GcmFnQ29vcmQueHkgLSB1ZWxsaXBzZV9TMV9jMC54eTsKCWlmIChib29sKGludCgwKSkpIAoJewoJCWQgKj0gdXNjYWxlX1MxX2MwLnk7Cgl9CglmbG9hdDIgWiA9IGQgKiB1ZWxsaXBzZV9TMV9jMC56dzsKCWZsb2F0IGltcGxpY2l0ID0gZG90KFosIGQpIC0gMS4wOwoJZmxvYXQgZ3JhZF9kb3QgPSA0LjAgKiBkb3QoWiwgWik7CglpZiAoYm9vbChpbnQoMCkpKSAKCXsKCQlncmFkX2RvdCA9IG1heChncmFkX2RvdCwgNi4xMDM2ZS0wNSk7Cgl9CgllbHNlIAoJewoJCWdyYWRfZG90ID0gbWF4KGdyYWRfZG90LCAxLjE3NTVlLTM4KTsKCX0KCWZsb2F0IGFwcHJveF9kaXN0ID0gaW1wbGljaXQgKiBpbnZlcnNlc3FydChncmFkX2RvdCk7CglpZiAoYm9vbChpbnQoMCkpKSAKCXsKCQlhcHByb3hfZGlzdCAqPSB1c2NhbGVfUzFfYzAueDsKCX0KCWhhbGYgYWxwaGE7CglpZiAoaW50KDEpID09IGtGaWxsQldfUzFfYzApIAoJewoJCWFscGhhID0gaGFsZihhcHByb3hfZGlzdCA+IDAuMCA/IDAuMCA6IDEuMCk7Cgl9CgllbHNlIGlmIChpbnQoMSkgPT0ga0ZpbGxBQV9TMV9jMCkgCgl7CgkJYWxwaGEgPSBzYXR1cmF0ZSgwLjUgLSBoYWxmKGFwcHJveF9kaXN0KSk7Cgl9CgllbHNlIGlmIChpbnQoMSkgPT0ga0ludmVyc2VGaWxsQldfUzFfYzApIAoJewoJCWFscGhhID0gaGFsZihhcHByb3hfZGlzdCA+IDAuMCk7Cgl9CgllbHNlIAoJewoJCWFscGhhID0gc2F0dXJhdGUoMC41ICsgaGFsZihhcHByb3hfZGlzdCkpOwoJfQoJcmV0dXJuIGhhbGY0KGhhbGY0KGFscGhhKSk7Cn0KaGFsZjQgQmxlbmRfUzEoaGFsZjQgX3NyYywgaGFsZjQgX2RzdCkgCnsKCXJldHVybiBibGVuZF9tb2R1bGF0ZShFbGxpcHNlX1MxX2MwKF9zcmMpLCBfc3JjKTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMCA9IGhhbGY0KDEpOwoJZmxvYXQyIHRleENvb3JkOwoJdGV4Q29vcmQgPSB2bG9jYWxDb29yZF9TMDsKCW91dHB1dENvbG9yX1MwID0gKGJsZW5kX21vZHVsYXRlKHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMCwgdGV4Q29vcmQpLCBoYWxmNCgxKSkpOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IEJsZW5kX1MxKG91dHB1dENvdmVyYWdlX1MwLCBoYWxmNCgxKSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAIAAAAcG9zaXRpb24KAAAAbG9jYWxDb29yZAAAAAAAAA==","GZIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAHIBIA5HZ2CAAAAAAAYAAAAAAAAAQAAAAERRAAAAAAAABAAAAABYECBQAAAAAAAABAAAAAJAIAAIAAAAAKBBIAIIDAAAAAAAAAAADGAAAAAAAEAAAAAIDEAA":"DAAAAExTS1POAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzA7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfM19TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzFfYzApICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAAAAgQwAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzBfYzBfYzA7CnVuaWZvcm0gaGFsZjR4NCB1Y29lZmZpY2llbnRzX1MxX2MwX2MwOwp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzA7CnNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMTsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc18zX1MwOwpoYWxmNCBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwX2MwX2MwKGhhbGY0IF9pbnB1dCwgZmxvYXQyIF9jb29yZHMpIAp7CglyZXR1cm4gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MxLCBfY29vcmRzKTsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzFfYzBfYzBfYzAoaGFsZjQgX2lucHV0LCBmbG9hdDIgX2Nvb3JkcykgCnsKCXJldHVybiBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwX2MwX2MwKF9pbnB1dCwgZmxvYXQzeDIodW1hdHJpeF9TMV9jMF9jMF9jMCkgKiBfY29vcmRzLnh5MSk7Cn0KaGFsZjQgQmljdWJpY19TMV9jMF9jMChoYWxmNCBfaW5wdXQpIAp7CglmbG9hdDIgY29vcmQgPSB2VHJhbnNmb3JtZWRDb29yZHNfM19TMCAtIGZsb2F0MigwLjUpOwoJaGFsZjIgZiA9IGhhbGYyKGZyYWN0KGNvb3JkKSk7Cgljb29yZCArPSAwLjUgLSBmOwoJaGFsZjQgd3ggPSB1Y29lZmZpY2llbnRzX1MxX2MwX2MwICogaGFsZjQoMS4wLCBmLngsIGYueCAqIGYueCwgZi54ICogZi54ICogZi54KTsKCWhhbGY0IHd5ID0gdWNvZWZmaWNpZW50c19TMV9jMF9jMCAqIGhhbGY0KDEuMCwgZi55LCBmLnkgKiBmLnksIGYueSAqIGYueSAqIGYueSk7CgloYWxmNCByb3dDb2xvcnNbNF07Cglyb3dDb2xvcnNbMF0gPSBNYXRyaXhFZmZlY3RfUzFfYzBfYzBfYzAoX2lucHV0LCBjb29yZCArIGZsb2F0MigtMSwgLTEpKTsKCXJvd0NvbG9yc1sxXSA9IE1hdHJpeEVmZmVjdF9TMV9jMF9jMF9jMChfaW5wdXQsIGNvb3JkICsgZmxvYXQyKDAsIC0xKSk7Cglyb3dDb2xvcnNbMl0gPSBNYXRyaXhFZmZlY3RfUzFfYzBfYzBfYzAoX2lucHV0LCBjb29yZCArIGZsb2F0MigxLCAtMSkpOwoJcm93Q29sb3JzWzNdID0gTWF0cml4RWZmZWN0X1MxX2MwX2MwX2MwKF9pbnB1dCwgY29vcmQgKyBmbG9hdDIoMiwgLTEpKTsKCWhhbGY0IHMwID0gd3gueCAqIHJvd0NvbG9yc1swXSArIHd4LnkgKiByb3dDb2xvcnNbMV0gKyB3eC56ICogcm93Q29sb3JzWzJdICsgd3gudyAqIHJvd0NvbG9yc1szXTsKCXJvd0NvbG9yc1swXSA9IE1hdHJpeEVmZmVjdF9TMV9jMF9jMF9jMChfaW5wdXQsIGNvb3JkICsgZmxvYXQyKC0xLCAwKSk7Cglyb3dDb2xvcnNbMV0gPSBNYXRyaXhFZmZlY3RfUzFfYzBfYzBfYzAoX2lucHV0LCBjb29yZCArIGZsb2F0MigwLCAwKSk7Cglyb3dDb2xvcnNbMl0gPSBNYXRyaXhFZmZlY3RfUzFfYzBfYzBfYzAoX2lucHV0LCBjb29yZCArIGZsb2F0MigxLCAwKSk7Cglyb3dDb2xvcnNbM10gPSBNYXRyaXhFZmZlY3RfUzFfYzBfYzBfYzAoX2lucHV0LCBjb29yZCArIGZsb2F0MigyLCAwKSk7CgloYWxmNCBzMSA9IHd4LnggKiByb3dDb2xvcnNbMF0gKyB3eC55ICogcm93Q29sb3JzWzFdICsgd3gueiAqIHJvd0NvbG9yc1syXSArIHd4LncgKiByb3dDb2xvcnNbM107Cglyb3dDb2xvcnNbMF0gPSBNYXRyaXhFZmZlY3RfUzFfYzBfYzBfYzAoX2lucHV0LCBjb29yZCArIGZsb2F0MigtMSwgMSkpOwoJcm93Q29sb3JzWzFdID0gTWF0cml4RWZmZWN0X1MxX2MwX2MwX2MwKF9pbnB1dCwgY29vcmQgKyBmbG9hdDIoMCwgMSkpOwoJcm93Q29sb3JzWzJdID0gTWF0cml4RWZmZWN0X1MxX2MwX2MwX2MwKF9pbnB1dCwgY29vcmQgKyBmbG9hdDIoMSwgMSkpOwoJcm93Q29sb3JzWzNdID0gTWF0cml4RWZmZWN0X1MxX2MwX2MwX2MwKF9pbnB1dCwgY29vcmQgKyBmbG9hdDIoMiwgMSkpOwoJaGFsZjQgczIgPSB3eC54ICogcm93Q29sb3JzWzBdICsgd3gueSAqIHJvd0NvbG9yc1sxXSArIHd4LnogKiByb3dDb2xvcnNbMl0gKyB3eC53ICogcm93Q29sb3JzWzNdOwoJcm93Q29sb3JzWzBdID0gTWF0cml4RWZmZWN0X1MxX2MwX2MwX2MwKF9pbnB1dCwgY29vcmQgKyBmbG9hdDIoLTEsIDIpKTsKCXJvd0NvbG9yc1sxXSA9IE1hdHJpeEVmZmVjdF9TMV9jMF9jMF9jMChfaW5wdXQsIGNvb3JkICsgZmxvYXQyKDAsIDIpKTsKCXJvd0NvbG9yc1syXSA9IE1hdHJpeEVmZmVjdF9TMV9jMF9jMF9jMChfaW5wdXQsIGNvb3JkICsgZmxvYXQyKDEsIDIpKTsKCXJvd0NvbG9yc1szXSA9IE1hdHJpeEVmZmVjdF9TMV9jMF9jMF9jMChfaW5wdXQsIGNvb3JkICsgZmxvYXQyKDIsIDIpKTsKCWhhbGY0IHMzID0gd3gueCAqIHJvd0NvbG9yc1swXSArIHd4LnkgKiByb3dDb2xvcnNbMV0gKyB3eC56ICogcm93Q29sb3JzWzJdICsgd3gudyAqIHJvd0NvbG9yc1szXTsKCWhhbGY0IGJpY3ViaWNDb2xvciA9IHd5LnggKiBzMCArIHd5LnkgKiBzMSArIHd5LnogKiBzMiArIHd5LncgKiBzMzsKCWJpY3ViaWNDb2xvci5hID0gc2F0dXJhdGUoYmljdWJpY0NvbG9yLmEpOwoJYmljdWJpY0NvbG9yLnJnYiA9IG1heChoYWxmMygwLjApLCBtaW4oYmljdWJpY0NvbG9yLnJnYiwgYmljdWJpY0NvbG9yLmFhYSkpOwoJcmV0dXJuIGJpY3ViaWNDb2xvcjsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIEJpY3ViaWNfUzFfYzBfYzAoX2lucHV0KTsKfQpoYWxmNCBEaXNhYmxlQ292ZXJhZ2VBc0FscGhhX1MxKGhhbGY0IF9pbnB1dCkgCnsKCV9pbnB1dCA9IE1hdHJpeEVmZmVjdF9TMV9jMChfaW5wdXQpOwoJaGFsZjQgX3RtcF8wX2luQ29sb3IgPSBfaW5wdXQ7CglyZXR1cm4gaGFsZjQoX2lucHV0KTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IERpc2FibGVDb3ZlcmFnZUFzQWxwaGFfUzEob3V0cHV0Q29sb3JfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","B2AAQAAABQAAIAABBYAAB7777777777774ABICAAAAAAAAAAAAAABGABAAAAAEAAAAAIBEABAAAAA":"DAAAAExTS1NZAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgaW5Qb3NpdGlvbjsKaW4gaGFsZiBpbkNvdmVyYWdlOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmIHZpbkNvdmVyYWdlX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBEZWZhdWx0R2VvbWV0cnlQcm9jZXNzb3IKCWZsb2F0MiBfdG1wXzFfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247Cgl2aW5Db3ZlcmFnZV9TMCA9IGluQ292ZXJhZ2U7Cglza19Qb3NpdGlvbiA9IF90bXBfMV9pblBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAAAJgBAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKdW5pZm9ybSBoYWxmNCB1Q29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gaGFsZiB2aW5Db3ZlcmFnZV9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIERlZmF1bHRHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHVDb2xvcl9TMDsKCWhhbGYgYWxwaGEgPSAxLjA7CglhbHBoYSA9IHZpbkNvdmVyYWdlX1MwOwoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChhbHBoYSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAoAAABpblBvc2l0aW9uAAAKAAAAaW5Db3ZlcmFnZQAAAAAAAA==","GZIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAJIBE4KMRCBIACAAADQOAIAAAAAWBB46KAQCFIAAAAADQOAIAAAACI6DQCAAAAACQIKACCAYAA4DQAAAAAAZQAAAAAABAAAAACAZAAAAAAA":"DAAAAExTS1PIAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfMl9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzEpICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAAkJAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKY29uc3QgaW50IGtNYXhMb29wTGltaXRfUzFfYzAgPSA3Owp1bmlmb3JtIGhhbGY0IHVib3JkZXJfUzFfYzBfYzBfYzA7CnVuaWZvcm0gZmxvYXQ0IHVzdWJzZXRfUzFfYzBfYzBfYzA7CnVuaWZvcm0gZmxvYXQyIHVpZGltc19TMV9jMF9jMF9jMDsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxX2MwX2MwOwp1bmlmb3JtIGhhbGY0IHVrZXJuZWxfUzFfYzBbN107CnVuaWZvcm0gaGFsZjQgdW9mZnNldHNfUzFfYzBbMTRdOwp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CnNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMTsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwpoYWxmNCBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwX2MwKGhhbGY0IF9pbnB1dCwgZmxvYXQyIF9jb29yZHMpIAp7CglmbG9hdDIgaW5Db29yZCA9IF9jb29yZHM7CglmbG9hdDIgc3Vic2V0Q29vcmQ7CglzdWJzZXRDb29yZC54ID0gaW5Db29yZC54OwoJc3Vic2V0Q29vcmQueSA9IGluQ29vcmQueTsKCWZsb2F0MiBjbGFtcGVkQ29vcmQ7CgljbGFtcGVkQ29vcmQgPSBzdWJzZXRDb29yZDsKCWhhbGY0IHRleHR1cmVDb2xvciA9IHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMSwgKGNsYW1wZWRDb29yZCkgKiB1aWRpbXNfUzFfYzBfYzBfYzApOwoJZmxvYXQgc25hcHBlZFggPSBmbG9vcihpbkNvb3JkLnggKyAwLjAwMSkgKyAwLjU7CglpZiAoc25hcHBlZFggPCB1c3Vic2V0X1MxX2MwX2MwX2MwLnggfHwgc25hcHBlZFggPiB1c3Vic2V0X1MxX2MwX2MwX2MwLnopIAoJewoJCXRleHR1cmVDb2xvciA9IHVib3JkZXJfUzFfYzBfYzBfYzA7Cgl9CglmbG9hdCBzbmFwcGVkWSA9IGZsb29yKGluQ29vcmQueSArIDAuMDAxKSArIDAuNTsKCWlmIChzbmFwcGVkWSA8IHVzdWJzZXRfUzFfYzBfYzBfYzAueSB8fCBzbmFwcGVkWSA+IHVzdWJzZXRfUzFfYzBfYzBfYzAudykgCgl7CgkJdGV4dHVyZUNvbG9yID0gdWJvcmRlcl9TMV9jMF9jMF9jMDsKCX0KCXJldHVybiB0ZXh0dXJlQ29sb3I7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxX2MwX2MwKGhhbGY0IF9pbnB1dCwgZmxvYXQyIF9jb29yZHMpIAp7CglyZXR1cm4gVGV4dHVyZUVmZmVjdF9TMV9jMF9jMF9jMChfaW5wdXQsIGZsb2F0M3gyKHVtYXRyaXhfUzFfYzBfYzApICogX2Nvb3Jkcy54eTEpOwp9CmhhbGY0IHJ1bnRpbWVfc2hhZGVyX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJZmxvYXQyIF90bXBfMV9jb29yZHMgPSB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKCWhhbGY0IHN1bSA9IGhhbGY0KDAuMCk7Cglmb3IgKGludCBpID0gMDtpIDwga01heExvb3BMaW1pdF9TMV9jMDsgKytpKSAKCXsKCQloYWxmNCBrID0gdWtlcm5lbF9TMV9jMFtpXTsKCQloYWxmNCBvID0gdW9mZnNldHNfUzFfYzBbMiAqIGldOwoJCXN1bSArPSBrLnggKiBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoX3RtcF8wX2luQ29sb3IsIF90bXBfMV9jb29yZHMgKyBmbG9hdDIoby54eSkpOwoJCXN1bSArPSBrLnkgKiBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoX3RtcF8wX2luQ29sb3IsIF90bXBfMV9jb29yZHMgKyBmbG9hdDIoby56dykpOwoJCW8gPSB1b2Zmc2V0c19TMV9jMFsyICogaSArIDFdOwoJCXN1bSArPSBrLnogKiBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoX3RtcF8wX2luQ29sb3IsIF90bXBfMV9jb29yZHMgKyBmbG9hdDIoby54eSkpOwoJCXN1bSArPSBrLncgKiBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoX3RtcF8wX2luQ29sb3IsIF90bXBfMV9jb29yZHMgKyBmbG9hdDIoby56dykpOwoJfQoJcmV0dXJuIGhhbGY0KHN1bSk7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBydW50aW1lX3NoYWRlcl9TMV9jMChfaW5wdXQpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gTWF0cml4RWZmZWN0X1MxKG91dHB1dENvbG9yX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRfUzEgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAgAAABwb3NpdGlvbgUAAABjb2xvcgAAAAoAAABsb2NhbENvb3JkAAAAAAAA","GZIACAAAABQAAGAAAQ4AAAAAGQQAARC4GAAAIOCAAD6P7777777777YDAAAAAAAAAAAJQBBYGQ467YIAAAAAAQAAAAAMACTRNBZN5QYBAAAAAAAAAAAIAALIAAAAB4FJEIEKOAAAAAMAAAAAUAAQAADAWB7EXCYCAAAGAAAAAAAACAAAQAK7DKJCBCTQAAAADAAAAAAAAAAAAYCADIAAAAAG5O33IKAAAAAAMAAAAAIAAAAAABMJDQP2FUWQUAAAQAAQAAAAAAAAAADGAAAAAAAEAAAAAIDEAAAAAAA":"DAAAAExTS1M7AgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQgY292ZXJhZ2U7CmluIGhhbGY0IGNvbG9yOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdCB2Y292ZXJhZ2VfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDIgcG9zaXRpb24gPSBwb3NpdGlvbi54eTsKCXZjb2xvcl9TMCA9IGNvbG9yOwoJdmNvdmVyYWdlX1MwID0gY292ZXJhZ2U7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgABAAAAxiIAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQpmbG9hdDQgZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzA7CmZsb2F0NCBmcmFnQ29sb3JfUzFfYzA7CmZsb2F0IHVfYWxwaGFfUzFfYzA7CmZsb2F0IHVfc3BhcmtsZV9hbHBoYV9TMV9jMDsKZmxvYXQgdV9ibHVyX1MxX2MwOwpmbG9hdCB1X3JhZGl1c19zY2FsZV9TMV9jMDsKY29uc3QgaW50IGtGaWxsQldfUzJfYzAgPSAwOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQldfUzJfYzAgPSAyOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQUFfUzJfYzAgPSAzOwpjb25zdCBpbnQga0ZpbGxBQV9TMl9jMV9jMCA9IDE7CmNvbnN0IGludCBrSW52ZXJzZUZpbGxCV19TMl9jMV9jMCA9IDI7CmNvbnN0IGludCBrSW52ZXJzZUZpbGxBQV9TMl9jMV9jMCA9IDM7CnVuaWZvcm0gZmxvYXQ0IHVfY29sb3JfUzFfYzA7CnVuaWZvcm0gZmxvYXQ0IHVfY29tcG9zaXRlXzFfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2VudGVyX1MxX2MwOwp1bmlmb3JtIGZsb2F0IHVfbWF4X3JhZGl1c19TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yZXNvbHV0aW9uX3NjYWxlX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X25vaXNlX3NjYWxlX1MxX2MwOwp1bmlmb3JtIGZsb2F0IHVfbm9pc2VfcGhhc2VfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2lyY2xlMV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jaXJjbGUyX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NpcmNsZTNfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcm90YXRpb24xX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3JvdGF0aW9uMl9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yb3RhdGlvbjNfUzFfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKdW5pZm9ybSBmbG9hdDQgdXJlY3RVbmlmb3JtX1MyX2MwOwp1bmlmb3JtIGZsb2F0NCB1Y2lyY2xlX1MyX2MxX2MwOwpub3BlcnNwZWN0aXZlIGluIGhhbGY0IHZjb2xvcl9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdCB2Y292ZXJhZ2VfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwpmbG9hdDIgRkxUX2ZsdXR0ZXJfbG9jYWxfRmx1dHRlckZyYWdDb29yZF9TMV9jMCgpOwpmbG9hdDJ4MiBGTFRfZmx1dHRlcl9sb2NhbF9yb3RhdGUyZF9TMV9jMChmbG9hdDIgcmFkKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgYmx1cik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKGZsb2F0MiByZXNvbHV0aW9uLCBpbm91dCBmbG9hdDIgcCwgZmxvYXQyIHh5LCBmbG9hdDIgcm90YXRpb24sIGZsb2F0IGNlbGxfZGlhbWV0ZXIpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90dXJidWxlbmNlX1MxX2MwKGZsb2F0MiB1dik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfcmluZ19TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCB0aGlja25lc3MsIGZsb2F0IGJsdXIpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90cmlhbmdsZV9ub2lzZV9TMV9jMChpbm91dCBmbG9hdDIgbik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChmbG9hdCB2LCBmbG9hdCBsLCBmbG9hdCBoKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc3BhcmtsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0IHQpOwp2b2lkIEZMVF9tYWluX1MxX2MwKCk7CmZsb2F0MiBGTFRfZmx1dHRlcl9sb2NhbF9GbHV0dGVyRnJhZ0Nvb3JkX1MxX2MwKCkgCnsKCXJldHVybiBmbHV0dGVyX0ZyYWdDb29yZF9TMV9jMC54eTsKfQpmbG9hdDJ4MiBGTFRfZmx1dHRlcl9sb2NhbF9yb3RhdGUyZF9TMV9jMChmbG9hdDIgcmFkKSAKewoJcmV0dXJuIGZsb2F0MngyKHJhZC54LCAtcmFkLnksIHJhZC55LCByYWQueCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgYmx1cikgCnsKCWZsb2F0IGJsdXJfaGFsZiA9IGJsdXIgKiAwLjU7CglmbG9hdCBkID0gZGlzdGFuY2UodXYsIHh5KTsKCXJldHVybiAxLjAgLSBzbW9vdGhzdGVwKDEuMCAtIGJsdXJfaGFsZiwgMS4wICsgYmx1cl9oYWxmLCBkIC8gcmFkaXVzKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChmbG9hdDIgcmVzb2x1dGlvbiwgaW5vdXQgZmxvYXQyIHAsIGZsb2F0MiB4eSwgZmxvYXQyIHJvdGF0aW9uLCBmbG9hdCBjZWxsX2RpYW1ldGVyKSAKewoJZmxvYXQyIHBhcmFtID0gcm90YXRpb247CglwID0gRkxUX2ZsdXR0ZXJfbG9jYWxfcm90YXRlMmRfUzFfYzAocGFyYW0pICogKHh5IC0gcCkgKyB4eTsKCXAgPSBtb2QocCwgZmxvYXQyKGNlbGxfZGlhbWV0ZXIpKSAvIHJlc29sdXRpb247CglmbG9hdCBjZWxsX3V2ID0gKGNlbGxfZGlhbWV0ZXIgLyByZXNvbHV0aW9uLnkpICogMC41OwoJZmxvYXQgciA9IDAuNjUgKiBjZWxsX3V2OwoJZmxvYXQyIHBhcmFtXzEgPSBwOwoJZmxvYXQyIHBhcmFtXzIgPSBmbG9hdDIoY2VsbF91dik7CglmbG9hdCBwYXJhbV8zID0gcjsKCWZsb2F0IHBhcmFtXzQgPSByICogNTAuMDsKCXJldHVybiBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zLCBwYXJhbV80KTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90dXJidWxlbmNlX1MxX2MwKGZsb2F0MiB1dikgCnsKCWZsb2F0MiB1dl9zY2FsZSA9IHV2ICogZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW0gPSBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbV8xID0gdXZfc2NhbGU7CglmbG9hdDIgcGFyYW1fMiA9IHVfY2lyY2xlMV9TMV9jMDsKCWZsb2F0MiBwYXJhbV8zID0gdV9yb3RhdGlvbjFfUzFfYzA7CglmbG9hdCBwYXJhbV80ID0gMC4xNzsKCWZsb2F0IF8zMTkgPSBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChwYXJhbSwgcGFyYW1fMSwgcGFyYW1fMiwgcGFyYW1fMywgcGFyYW1fNCk7CglmbG9hdCBnMSA9IF8zMTk7CglmbG9hdDIgcGFyYW1fNSA9IGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtXzYgPSB1dl9zY2FsZTsKCWZsb2F0MiBwYXJhbV83ID0gdV9jaXJjbGUyX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzggPSB1X3JvdGF0aW9uMl9TMV9jMDsKCWZsb2F0IHBhcmFtXzkgPSAwLjI7CglmbG9hdCBfMzMxID0gRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAocGFyYW1fNSwgcGFyYW1fNiwgcGFyYW1fNywgcGFyYW1fOCwgcGFyYW1fOSk7CglmbG9hdCBnMiA9IF8zMzE7CglmbG9hdDIgcGFyYW1fMTAgPSBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbV8xMSA9IHV2X3NjYWxlOwoJZmxvYXQyIHBhcmFtXzEyID0gdV9jaXJjbGUzX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzEzID0gdV9yb3RhdGlvbjNfUzFfYzA7CglmbG9hdCBwYXJhbV8xNCA9IDAuMjc1OwoJZmxvYXQgXzM0NCA9IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKHBhcmFtXzEwLCBwYXJhbV8xMSwgcGFyYW1fMTIsIHBhcmFtXzEzLCBwYXJhbV8xNCk7CglmbG9hdCBnMyA9IF8zNDQ7CglmbG9hdCB2ID0gKChnMSAqIGcxICsgZzIpIC0gZzMpICogMC41OwoJcmV0dXJuIGNsYW1wKDAuNDUgKyAwLjggKiB2LCAwLjAsIDEuMCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9yaW5nX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IHRoaWNrbmVzcywgZmxvYXQgYmx1cikgCnsKCWZsb2F0MiBwYXJhbSA9IHV2OwoJZmxvYXQyIHBhcmFtXzEgPSB4eTsKCWZsb2F0IHBhcmFtXzIgPSByYWRpdXMgKyB0aGlja25lc3M7CglmbG9hdCBwYXJhbV8zID0gYmx1cjsKCWZsb2F0IGNpcmNsZV9vdXRlciA9IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtLCBwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zKTsKCWZsb2F0MiBwYXJhbV80ID0gdXY7CglmbG9hdDIgcGFyYW1fNSA9IHh5OwoJZmxvYXQgcGFyYW1fNiA9IG1heChyYWRpdXMgLSB0aGlja25lc3MsIDAuMCk7CglmbG9hdCBwYXJhbV83ID0gYmx1cjsKCWZsb2F0IGNpcmNsZV9pbm5lciA9IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtXzQsIHBhcmFtXzUsIHBhcmFtXzYsIHBhcmFtXzcpOwoJcmV0dXJuIGNsYW1wKGNpcmNsZV9vdXRlciAtIGNpcmNsZV9pbm5lciwgMC4wLCAxLjApOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RyaWFuZ2xlX25vaXNlX1MxX2MwKGlub3V0IGZsb2F0MiBuKSAKewoJbiA9IGZyYWN0KG4gKiBmbG9hdDIoNS4zOTg3LCA1LjQ0MjEpKTsKCW4gKz0gZmxvYXQyKGRvdChuLnl4LCBuICsgZmxvYXQyKDIxLjUzNTEsIDE0LjMxMzcpKSk7CglmbG9hdCB4eSA9IG4ueCAqIG4ueTsKCXJldHVybiAoZnJhY3QoeHkgKiA5NS40MzA3KSArIGZyYWN0KHh5ICogNzUuMDQ5NjEpKSAtIDEuMDsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAoZmxvYXQgdiwgZmxvYXQgbCwgZmxvYXQgaCkgCnsKCXJldHVybiBzdGVwKGwsIHYpICogKDEuMCAtIHN0ZXAoaCwgdikpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NwYXJrbGVfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdCB0KSAKewoJZmxvYXQyIHBhcmFtID0gdXY7CglmbG9hdCBfMjQyID0gRkxUX2ZsdXR0ZXJfbG9jYWxfdHJpYW5nbGVfbm9pc2VfUzFfYzAocGFyYW0pOwoJZmxvYXQgbiA9IF8yNDI7CglmbG9hdCBwYXJhbV8xID0gbjsKCWZsb2F0IHBhcmFtXzIgPSAwLjA7CglmbG9hdCBwYXJhbV8zID0gMC4wNTsKCWZsb2F0IHMgPSBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAocGFyYW1fMSwgcGFyYW1fMiwgcGFyYW1fMyk7CglmbG9hdCBwYXJhbV80ID0gbiArIHNpbigzLjE0MTU5Mjc0ICogKHQgKyAwLjM1KSk7CglmbG9hdCBwYXJhbV81ID0gMC4xOwoJZmxvYXQgcGFyYW1fNiA9IDAuMTU7CglzICs9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV80LCBwYXJhbV81LCBwYXJhbV82KTsKCWZsb2F0IHBhcmFtXzcgPSBuICsgc2luKDMuMTQxNTkyNzQgKiAodCArIDAuNykpOwoJZmxvYXQgcGFyYW1fOCA9IDAuMjsKCWZsb2F0IHBhcmFtXzkgPSAwLjI1OwoJcyArPSBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAocGFyYW1fNywgcGFyYW1fOCwgcGFyYW1fOSk7CglmbG9hdCBwYXJhbV8xMCA9IG4gKyBzaW4oMy4xNDE1OTI3NCAqICh0ICsgMS4wNSkpOwoJZmxvYXQgcGFyYW1fMTEgPSAwLjM7CglmbG9hdCBwYXJhbV8xMiA9IDAuMzU7CglzICs9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV8xMCwgcGFyYW1fMTEsIHBhcmFtXzEyKTsKCXJldHVybiBjbGFtcChzLCAwLjAsIDEuMCkgKiAwLjU1Owp9CnZvaWQgRkxUX21haW5fUzFfYzAoKSAKewoJdV9hbHBoYV9TMV9jMCA9IHVfY29tcG9zaXRlXzFfUzFfYzAueDsKCXVfc3BhcmtsZV9hbHBoYV9TMV9jMCA9IHVfY29tcG9zaXRlXzFfUzFfYzAueTsKCXVfYmx1cl9TMV9jMCA9IHVfY29tcG9zaXRlXzFfUzFfYzAuejsKCXVfcmFkaXVzX3NjYWxlX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC53OwoJZmxvYXQyIHAgPSBGTFRfZmx1dHRlcl9sb2NhbF9GbHV0dGVyRnJhZ0Nvb3JkX1MxX2MwKCk7CglmbG9hdDIgdXZfMSA9IHAgKiB1X3Jlc29sdXRpb25fc2NhbGVfUzFfYzA7CglmbG9hdDIgZGVuc2l0eV91diA9IHV2XzEgLSBtb2QocCwgdV9ub2lzZV9zY2FsZV9TMV9jMCk7CglmbG9hdCByYWRpdXMgPSB1X21heF9yYWRpdXNfUzFfYzAgKiB1X3JhZGl1c19zY2FsZV9TMV9jMDsKCWZsb2F0MiBwYXJhbV8xMyA9IHV2XzE7CglmbG9hdCB0dXJidWxlbmNlID0gRkxUX2ZsdXR0ZXJfbG9jYWxfdHVyYnVsZW5jZV9TMV9jMChwYXJhbV8xMyk7CglmbG9hdDIgcGFyYW1fMTQgPSBwOwoJZmxvYXQyIHBhcmFtXzE1ID0gdV9jZW50ZXJfUzFfYzA7CglmbG9hdCBwYXJhbV8xNiA9IHJhZGl1czsKCWZsb2F0IHBhcmFtXzE3ID0gMC4wNSAqIHVfbWF4X3JhZGl1c19TMV9jMDsKCWZsb2F0IHBhcmFtXzE4ID0gdV9ibHVyX1MxX2MwOwoJZmxvYXQgcmluZyA9IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfcmluZ19TMV9jMChwYXJhbV8xNCwgcGFyYW1fMTUsIHBhcmFtXzE2LCBwYXJhbV8xNywgcGFyYW1fMTgpOwoJZmxvYXQyIHBhcmFtXzE5ID0gZGVuc2l0eV91djsKCWZsb2F0IHBhcmFtXzIwID0gdV9ub2lzZV9waGFzZV9TMV9jMDsKCWZsb2F0IHNwYXJrbGUgPSAoKEZMVF9mbHV0dGVyX2xvY2FsX3NwYXJrbGVfUzFfYzAocGFyYW1fMTksIHBhcmFtXzIwKSAqIHJpbmcpICogdHVyYnVsZW5jZSkgKiB1X3NwYXJrbGVfYWxwaGFfUzFfYzA7CglmbG9hdDIgcGFyYW1fMjEgPSBwOwoJZmxvYXQyIHBhcmFtXzIyID0gdV9jZW50ZXJfUzFfYzA7CglmbG9hdCBwYXJhbV8yMyA9IHJhZGl1czsKCWZsb2F0IHBhcmFtXzI0ID0gdV9ibHVyX1MxX2MwOwoJZmxvYXQgd2F2ZV9hbHBoYSA9IChGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChwYXJhbV8yMSwgcGFyYW1fMjIsIHBhcmFtXzIzLCBwYXJhbV8yNCkgKiB1X2FscGhhX1MxX2MwKSAqIHVfY29sb3JfUzFfYzAudzsKCWZsb2F0NCB3YXZlX2NvbG9yID0gZmxvYXQ0KHVfY29sb3JfUzFfYzAueHl6ICogd2F2ZV9hbHBoYSwgd2F2ZV9hbHBoYSk7CglmcmFnQ29sb3JfUzFfYzAgPSBtaXgod2F2ZV9jb2xvciwgZmxvYXQ0KDEuMCksIGZsb2F0NChzcGFya2xlKSk7Cn0KaGFsZjQgcnVudGltZV9zaGFkZXJfUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF8wX2luQ29sb3IgPSBfaW5wdXQ7CglmbG9hdDIgX3RtcF8xX2Nvb3JkcyA9IHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwoJZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzAgPSBmbG9hdDQoX3RtcF8xX2Nvb3JkcywgMC4wLCAwLjApOwoJRkxUX21haW5fUzFfYzAoKTsKCXJldHVybiBoYWxmNChoYWxmNChmcmFnQ29sb3JfUzFfYzApKTsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIHJ1bnRpbWVfc2hhZGVyX1MxX2MwKF9pbnB1dCk7Cn0KaGFsZjQgUmVjdF9TMl9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzJfaW5Db2xvciA9IF9pbnB1dDsKCWhhbGYgY292ZXJhZ2U7CglpZiAoaW50KDEpID09IGtGaWxsQldfUzJfYzAgfHwgaW50KDEpID09IGtJbnZlcnNlRmlsbEJXX1MyX2MwKSAKCXsKCQljb3ZlcmFnZSA9IGhhbGYoYWxsKGdyZWF0ZXJUaGFuKGZsb2F0NChza19GcmFnQ29vcmQueHksIHVyZWN0VW5pZm9ybV9TMl9jMC56dyksIGZsb2F0NCh1cmVjdFVuaWZvcm1fUzJfYzAueHksIHNrX0ZyYWdDb29yZC54eSkpKSk7Cgl9CgllbHNlIAoJewoJCWhhbGY0IGRpc3RzNCA9IHNhdHVyYXRlKGhhbGY0KDEuMCwgMS4wLCAtMS4wLCAtMS4wKSAqIGhhbGY0KHNrX0ZyYWdDb29yZC54eXh5IC0gdXJlY3RVbmlmb3JtX1MyX2MwKSk7CgkJaGFsZjIgZGlzdHMyID0gKGRpc3RzNC54eSArIGRpc3RzNC56dykgLSAxLjA7CgkJY292ZXJhZ2UgPSBkaXN0czIueCAqIGRpc3RzMi55OwoJfQoJaWYgKGludCgxKSA9PSBrSW52ZXJzZUZpbGxCV19TMl9jMCB8fCBpbnQoMSkgPT0ga0ludmVyc2VGaWxsQUFfUzJfYzApIAoJewoJCWNvdmVyYWdlID0gMS4wIC0gY292ZXJhZ2U7Cgl9CglyZXR1cm4gaGFsZjQoaGFsZjQoY292ZXJhZ2UpKTsKfQpoYWxmNCBDaXJjbGVfUzJfYzFfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF8zX2luQ29sb3IgPSBfaW5wdXQ7CgloYWxmIGQ7CglpZiAoaW50KDEpID09IGtJbnZlcnNlRmlsbEJXX1MyX2MxX2MwIHx8IGludCgxKSA9PSBrSW52ZXJzZUZpbGxBQV9TMl9jMV9jMCkgCgl7CgkJZCA9IGhhbGYoKGxlbmd0aCgodWNpcmNsZV9TMl9jMV9jMC54eSAtIHNrX0ZyYWdDb29yZC54eSkgKiB1Y2lyY2xlX1MyX2MxX2MwLncpIC0gMS4wKSAqIHVjaXJjbGVfUzJfYzFfYzAueik7Cgl9CgllbHNlIAoJewoJCWQgPSBoYWxmKCgxLjAgLSBsZW5ndGgoKHVjaXJjbGVfUzJfYzFfYzAueHkgLSBza19GcmFnQ29vcmQueHkpICogdWNpcmNsZV9TMl9jMV9jMC53KSkgKiB1Y2lyY2xlX1MyX2MxX2MwLnopOwoJfQoJcmV0dXJuIGhhbGY0KGhhbGY0KGludCgxKSA9PSBrRmlsbEFBX1MyX2MxX2MwIHx8IGludCgxKSA9PSBrSW52ZXJzZUZpbGxBQV9TMl9jMV9jMCA/IHNhdHVyYXRlKGQpIDogaGFsZihkID4gMC41KSkpOwp9CmhhbGY0IEJsZW5kX1MyX2MxKGhhbGY0IF9zcmMsIGhhbGY0IF9kc3QpIAp7CglyZXR1cm4gYmxlbmRfbW9kdWxhdGUoX3NyYywgQ2lyY2xlX1MyX2MxX2MwKF9zcmMpKTsKfQpoYWxmNCBCbGVuZF9TMihoYWxmNCBfc3JjLCBoYWxmNCBfZHN0KSAKewoJcmV0dXJuIGJsZW5kX21vZHVsYXRlKFJlY3RfUzJfYzAoX3NyYyksIEJsZW5kX1MyX2MxKF9zcmMsIF9kc3QpKTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJZmxvYXQgY292ZXJhZ2UgPSB2Y292ZXJhZ2VfUzA7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGNvdmVyYWdlKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IE1hdHJpeEVmZmVjdF9TMShvdXRwdXRDb2xvcl9TMCk7CgloYWxmNCBvdXRwdXRfUzI7CglvdXRwdXRfUzIgPSBCbGVuZF9TMihvdXRwdXRDb3ZlcmFnZV9TMCwgaGFsZjQoMSkpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dF9TMjsKCX0KfQoAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAHBvc2l0aW9uCAAAAGNvdmVyYWdlBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA="}} \ No newline at end of file +{"platform":"android","name":"XQ DE72","engineRevision":"82bd5b7209295a5b7ff8cae0df96e7870171e3a5","data":{"AYQA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAAAAMYAAAAAAAQAAAABAMQAAAAA":"DAAAAExTS1MlAgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0NCB1bG9jYWxNYXRyaXhfUzA7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiBmbG9hdDQgaW5DaXJjbGVFZGdlOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIENpcmNsZUdlb21ldHJ5UHJvY2Vzc29yCgl2aW5DaXJjbGVFZGdlX1MwID0gaW5DaXJjbGVFZGdlOwoJdmluQ29sb3JfUzAgPSBpbkNvbG9yOwoJZmxvYXQyIF90bXBfMF9pblBvc2l0aW9uID0gaW5Qb3NpdGlvbjsKCWZsb2F0MiBfdG1wXzFfaW5Qb3NpdGlvbiA9IHVsb2NhbE1hdHJpeF9TMC54eiAqIGluUG9zaXRpb24gKyB1bG9jYWxNYXRyaXhfUzAueXc7Cglza19Qb3NpdGlvbiA9IF90bXBfMF9pblBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAAAEMCAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIENpcmNsZUdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDQgY2lyY2xlRWRnZTsKCWNpcmNsZUVkZ2UgPSB2aW5DaXJjbGVFZGdlX1MwOwoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZpbkNvbG9yX1MwOwoJZmxvYXQgZCA9IGxlbmd0aChjaXJjbGVFZGdlLnh5KTsKCWhhbGYgZGlzdGFuY2VUb091dGVyRWRnZSA9IGhhbGYoY2lyY2xlRWRnZS56ICogKDEuMCAtIGQpKTsKCWhhbGYgZWRnZUFscGhhID0gc2F0dXJhdGUoZGlzdGFuY2VUb091dGVyRWRnZSk7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGVkZ2VBbHBoYSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADAAAAGluQ2lyY2xlRWRnZQAAAAA=","B2ABSAAABQAAIAABBYAAB7777777777774ABICAAAAAAAAAAAAAABGABAAAAAEAAAAAIBEABAAAAA":"DAAAAExTS1PDAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGhhbGY0IHVDb2xvcl9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGYgaW5Db3ZlcmFnZTsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBEZWZhdWx0R2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IGNvbG9yID0gdUNvbG9yX1MwOwoJY29sb3IgPSBjb2xvciAqIGluQ292ZXJhZ2U7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCWZsb2F0MiBfdG1wXzFfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8zX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBfdG1wXzFfaW5Qb3NpdGlvbi54eTAxOwp9CgAAAAAAUQEAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQpub3BlcnNwZWN0aXZlIGluIGhhbGY0IHZjb2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIERlZmF1bHRHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAoAAABpblBvc2l0aW9uAAAKAAAAaW5Db3ZlcmFnZQAAAAAAAA==","GZIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAIIBAAAABAAAAALIEAAAAAAAAAAAAAABQAMAAAABAAAAAAABBAMAAAAA":"DAAAAExTS1PIAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfMl9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzEpICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAL8CAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7Cm5vcGVyc3BlY3RpdmUgaW4gaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MxLCB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMCkucnJycjsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzAoX2lucHV0KTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IE1hdHJpeEVmZmVjdF9TMShvdXRwdXRDb3ZlcmFnZV9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","GZJAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAABAAAAAABBAMABQAMAAAABAAAAAAABBAMAAA":"DAAAAExTS1N3AQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgcG9zaXRpb247CmluIGhhbGY0IGNvbG9yOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7Cgl2bG9jYWxDb29yZF9TMCA9IGxvY2FsQ29vcmQ7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cn0KAAAAAAApAgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQyIHZsb2NhbENvb3JkX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJZmxvYXQyIHRleENvb3JkOwoJdGV4Q29vcmQgPSB2bG9jYWxDb29yZF9TMDsKCW91dHB1dENvbG9yX1MwID0gKGJsZW5kX21vZHVsYXRlKHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMCwgdGV4Q29vcmQpLCBvdXRwdXRDb2xvcl9TMCkpOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","DAQAAAAAAAAAAAAAAJQAAIGAAEACBYQCAGAEFAIBAAAAAABAAAAAAAAAAAAAAMYAAAAAAAQAAAABAMQAAAAA":"DAAAAExTS1N4AgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0MiB1QXRsYXNTaXplSW52X1MwOwppbiBmbG9hdDIgaW5Qb3NpdGlvbjsKaW4gaGFsZjQgaW5Db2xvcjsKaW4gdXNob3J0MiBpblRleHR1cmVDb29yZHM7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQgdlRleEluZGV4X1MwOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgQml0bWFwVGV4dAoJaW50IHRleElkeCA9IDA7CglmbG9hdDIgdW5vcm1UZXhDb29yZHMgPSBmbG9hdDIoaW5UZXh0dXJlQ29vcmRzLngsIGluVGV4dHVyZUNvb3Jkcy55KTsKCXZUZXh0dXJlQ29vcmRzX1MwID0gdW5vcm1UZXhDb29yZHMgKiB1QXRsYXNTaXplSW52X1MwOwoJdlRleEluZGV4X1MwID0gZmxvYXQodGV4SWR4KTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzFfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247Cglza19Qb3NpdGlvbiA9IGluUG9zaXRpb24ueHkwMTsKfQoAAAAACwIAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQyIHZUZXh0dXJlQ29vcmRzX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0IHZUZXhJbmRleF9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIEJpdG1hcFRleHQKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWhhbGY0IHRleENvbG9yOwoJewoJCXRleENvbG9yID0gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB2VGV4dHVyZUNvb3Jkc19TMCkucnJycjsKCX0KCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gdGV4Q29sb3I7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADwAAAGluVGV4dHVyZUNvb3JkcwAAAAAA","AYQA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAACABZQA6AAAEAAAAAAAMADAAAAAIAAAAAAAIIDA":"DAAAAExTS1MlAgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0NCB1bG9jYWxNYXRyaXhfUzA7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiBmbG9hdDQgaW5DaXJjbGVFZGdlOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIENpcmNsZUdlb21ldHJ5UHJvY2Vzc29yCgl2aW5DaXJjbGVFZGdlX1MwID0gaW5DaXJjbGVFZGdlOwoJdmluQ29sb3JfUzAgPSBpbkNvbG9yOwoJZmxvYXQyIF90bXBfMF9pblBvc2l0aW9uID0gaW5Qb3NpdGlvbjsKCWZsb2F0MiBfdG1wXzFfaW5Qb3NpdGlvbiA9IHVsb2NhbE1hdHJpeF9TMC54eiAqIGluUG9zaXRpb24gKyB1bG9jYWxNYXRyaXhfUzAueXc7Cglza19Qb3NpdGlvbiA9IF90bXBfMF9pblBvc2l0aW9uLnh5MDE7Cn0KAAAAAQAAAOgDAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQ0IHZpbkNpcmNsZUVkZ2VfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gaGFsZjQgdmluQ29sb3JfUzA7CmhhbGY0IENpcmN1bGFyUlJlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MxLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MxLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CgloYWxmIGFscGhhID0gaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzEueCAtIGxlbmd0aChkeHkpKSk7CglhbHBoYSA9IDEuMCAtIGFscGhhOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQ0IGNpcmNsZUVkZ2U7CgljaXJjbGVFZGdlID0gdmluQ2lyY2xlRWRnZV9TMDsKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWZsb2F0IGQgPSBsZW5ndGgoY2lyY2xlRWRnZS54eSk7CgloYWxmIGRpc3RhbmNlVG9PdXRlckVkZ2UgPSBoYWxmKGNpcmNsZUVkZ2UueiAqICgxLjAgLSBkKSk7CgloYWxmIGVkZ2VBbHBoYSA9IHNhdHVyYXRlKGRpc3RhbmNlVG9PdXRlckVkZ2UpOwoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChlZGdlQWxwaGEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQ2lyY3VsYXJSUmVjdF9TMShvdXRwdXRDb3ZlcmFnZV9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADAAAAGluQ2lyY2xlRWRnZQAAAAA=","DAQAAAAAAAAAAAAAAJQAAIGAAEACBYQCAGAEFAIBAAAAAABAAAAAAAAAAAACAB4QA4AAAEAAAAAAAMADAAAAAIAAAAAAAIID":"DAAAAExTS1N4AgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0MiB1QXRsYXNTaXplSW52X1MwOwppbiBmbG9hdDIgaW5Qb3NpdGlvbjsKaW4gaGFsZjQgaW5Db2xvcjsKaW4gdXNob3J0MiBpblRleHR1cmVDb29yZHM7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQgdlRleEluZGV4X1MwOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgQml0bWFwVGV4dAoJaW50IHRleElkeCA9IDA7CglmbG9hdDIgdW5vcm1UZXhDb29yZHMgPSBmbG9hdDIoaW5UZXh0dXJlQ29vcmRzLngsIGluVGV4dHVyZUNvb3Jkcy55KTsKCXZUZXh0dXJlQ29vcmRzX1MwID0gdW5vcm1UZXhDb29yZHMgKiB1QXRsYXNTaXplSW52X1MwOwoJdlRleEluZGV4X1MwID0gZmxvYXQodGV4SWR4KTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzFfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247Cglza19Qb3NpdGlvbiA9IGluUG9zaXRpb24ueHkwMTsKfQoBAAAAmgMAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQp1bmlmb3JtIGZsb2F0NCB1aW5uZXJSZWN0X1MxOwp1bmlmb3JtIGhhbGYyIHVyYWRpdXNQbHVzSGFsZl9TMTsKc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdCB2VGV4SW5kZXhfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gaGFsZjQgdmluQ29sb3JfUzA7CmhhbGY0IENpcmN1bGFyUlJlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MxLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MxLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CgloYWxmIGFscGhhID0gaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzEueCAtIGxlbmd0aChkeHkpKSk7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIEJpdG1hcFRleHQKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWhhbGY0IHRleENvbG9yOwoJewoJCXRleENvbG9yID0gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB2VGV4dHVyZUNvb3Jkc19TMCkucnJycjsKCX0KCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gdGV4Q29sb3I7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBDaXJjdWxhclJSZWN0X1MxKG91dHB1dENvdmVyYWdlX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACgAAAGluUG9zaXRpb24AAAcAAABpbkNvbG9yAA8AAABpblRleHR1cmVDb29yZHMAAAAAAA==","EADQAAAAAEAAAAAUAABQAAQPAAABCFYMAAKAUEAAAAAAAAABAAAAAAAAAAAJQAIAAAABAAAAACAJAAIAAAAA":"DAAAAExTS1NtAgAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQyIHVBdGxhc0RpbWVuc2lvbnNJbnZfUzA7CmluIGZsb2F0MyBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiB1c2hvcnQyIGluVGV4dHVyZUNvb3JkczsKb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKb3V0IGZsb2F0IHZUZXhJbmRleF9TMDsKb3V0IGZsb2F0MiB2SW50VGV4dHVyZUNvb3Jkc19TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBEaXN0YW5jZUZpZWxkUGF0aAoJaW50IHRleElkeCA9IDA7CglmbG9hdDIgdW5vcm1UZXhDb29yZHMgPSBmbG9hdDIoaW5UZXh0dXJlQ29vcmRzLngsIGluVGV4dHVyZUNvb3Jkcy55KTsKCXZUZXh0dXJlQ29vcmRzX1MwID0gdW5vcm1UZXhDb29yZHMgKiB1QXRsYXNEaW1lbnNpb25zSW52X1MwOwoJdlRleEluZGV4X1MwID0gZmxvYXQodGV4SWR4KTsKCXZJbnRUZXh0dXJlQ29vcmRzX1MwID0gdW5vcm1UZXhDb29yZHM7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDMgX3RtcF8xX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBpblBvc2l0aW9uLnh5MHo7Cn0KAAAAAAAAAJICAABzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzA7CmluIGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKaW4gZmxvYXQgdlRleEluZGV4X1MwOwppbiBmbG9hdDIgdkludFRleHR1cmVDb29yZHNfUzA7CmluIGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgRGlzdGFuY2VGaWVsZFBhdGgKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWZsb2F0MiB1diA9IHZUZXh0dXJlQ29vcmRzX1MwOwoJaGFsZjQgdGV4Q29sb3I7Cgl7CgkJdGV4Q29sb3IgPSBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzAsIHV2KS5ycnJyOwoJfQoJaGFsZiBkaXN0YW5jZSA9IDcuOTY4NzUqKHRleENvbG9yLnIgLSAwLjUwMTk2MDc4NDMxKTsKCWhhbGYgYWZ3aWR0aDsKCWFmd2lkdGggPSBhYnMoMC42NSpoYWxmKGRGZHgodkludFRleHR1cmVDb29yZHNfUzAueCkpKTsKCWhhbGYgdmFsID0gc21vb3Roc3RlcCgtYWZ3aWR0aCwgYWZ3aWR0aCwgZGlzdGFuY2UpOwoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCh2YWwpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAoAAABpblBvc2l0aW9uAAAHAAAAaW5Db2xvcgAPAAAAaW5UZXh0dXJlQ29vcmRzAAAAAAA=","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","GZIACAAAABQAAGAAAQ4AAAAAGQQAARC4GAAAIOCAAD6P7777777777YDAAAAAAAAAAAJQBBYGQ467YIAAAAAAQAAAAAMACTRNBZN5QYBAAAAAAAAAAAIAALIAAAAAGFM37JKEAAAAAMAAAAAIAAAAAAAMBCQN25XWQUAAAAAAYAAAAAAAAAABGABAAAAAEAAAAAIBEABAAAAA":"DAAAAExTS1M7AgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQgY292ZXJhZ2U7CmluIGhhbGY0IGNvbG9yOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdCB2Y292ZXJhZ2VfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDIgcG9zaXRpb24gPSBwb3NpdGlvbi54eTsKCXZjb2xvcl9TMCA9IGNvbG9yOwoJdmNvdmVyYWdlX1MwID0gY292ZXJhZ2U7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgABAAAAKh8AACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQpmbG9hdDQgZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzA7CmZsb2F0NCBmcmFnQ29sb3JfUzFfYzA7CmZsb2F0IHVfYWxwaGFfUzFfYzA7CmZsb2F0IHVfc3BhcmtsZV9hbHBoYV9TMV9jMDsKZmxvYXQgdV9ibHVyX1MxX2MwOwpmbG9hdCB1X3JhZGl1c19zY2FsZV9TMV9jMDsKY29uc3QgaW50IGtGaWxsQUFfUzJfYzAgPSAxOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQldfUzJfYzAgPSAyOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQUFfUzJfYzAgPSAzOwp1bmlmb3JtIGZsb2F0NCB1X2NvbG9yX1MxX2MwOwp1bmlmb3JtIGZsb2F0NCB1X2NvbXBvc2l0ZV8xX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NlbnRlcl9TMV9jMDsKdW5pZm9ybSBmbG9hdCB1X21heF9yYWRpdXNfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcmVzb2x1dGlvbl9zY2FsZV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9ub2lzZV9zY2FsZV9TMV9jMDsKdW5pZm9ybSBmbG9hdCB1X25vaXNlX3BoYXNlX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NpcmNsZTFfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2lyY2xlMl9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jaXJjbGUzX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3JvdGF0aW9uMV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yb3RhdGlvbjJfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcm90YXRpb24zX1MxX2MwOwp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CnVuaWZvcm0gZmxvYXQ0IHVjaXJjbGVfUzJfYzA7Cm5vcGVyc3BlY3RpdmUgaW4gaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0IHZjb3ZlcmFnZV9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CmZsb2F0MiBGTFRfZmx1dHRlcl9sb2NhbF9GbHV0dGVyRnJhZ0Nvb3JkX1MxX2MwKCk7CmZsb2F0MngyIEZMVF9mbHV0dGVyX2xvY2FsX3JvdGF0ZTJkX1MxX2MwKGZsb2F0MiByYWQpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCBibHVyKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAoZmxvYXQyIHJlc29sdXRpb24sIGlub3V0IGZsb2F0MiBwLCBmbG9hdDIgeHksIGZsb2F0MiByb3RhdGlvbiwgZmxvYXQgY2VsbF9kaWFtZXRlcik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3R1cmJ1bGVuY2VfUzFfYzAoZmxvYXQyIHV2KTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9yaW5nX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IHRoaWNrbmVzcywgZmxvYXQgYmx1cik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RyaWFuZ2xlX25vaXNlX1MxX2MwKGlub3V0IGZsb2F0MiBuKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKGZsb2F0IHYsIGZsb2F0IGwsIGZsb2F0IGgpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zcGFya2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQgdCk7CnZvaWQgRkxUX21haW5fUzFfYzAoKTsKZmxvYXQyIEZMVF9mbHV0dGVyX2xvY2FsX0ZsdXR0ZXJGcmFnQ29vcmRfUzFfYzAoKSAKewoJcmV0dXJuIGZsdXR0ZXJfRnJhZ0Nvb3JkX1MxX2MwLnh5Owp9CmZsb2F0MngyIEZMVF9mbHV0dGVyX2xvY2FsX3JvdGF0ZTJkX1MxX2MwKGZsb2F0MiByYWQpIAp7CglyZXR1cm4gZmxvYXQyeDIocmFkLngsIC1yYWQueSwgcmFkLnksIHJhZC54KTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCBibHVyKSAKewoJZmxvYXQgYmx1cl9oYWxmID0gYmx1ciAqIDAuNTsKCWZsb2F0IGQgPSBkaXN0YW5jZSh1diwgeHkpOwoJcmV0dXJuIDEuMCAtIHNtb290aHN0ZXAoMS4wIC0gYmx1cl9oYWxmLCAxLjAgKyBibHVyX2hhbGYsIGQgLyByYWRpdXMpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKGZsb2F0MiByZXNvbHV0aW9uLCBpbm91dCBmbG9hdDIgcCwgZmxvYXQyIHh5LCBmbG9hdDIgcm90YXRpb24sIGZsb2F0IGNlbGxfZGlhbWV0ZXIpIAp7CglmbG9hdDIgcGFyYW0gPSByb3RhdGlvbjsKCXAgPSBGTFRfZmx1dHRlcl9sb2NhbF9yb3RhdGUyZF9TMV9jMChwYXJhbSkgKiAoeHkgLSBwKSArIHh5OwoJcCA9IG1vZChwLCBmbG9hdDIoY2VsbF9kaWFtZXRlcikpIC8gcmVzb2x1dGlvbjsKCWZsb2F0IGNlbGxfdXYgPSAoY2VsbF9kaWFtZXRlciAvIHJlc29sdXRpb24ueSkgKiAwLjU7CglmbG9hdCByID0gMC42NSAqIGNlbGxfdXY7CglmbG9hdDIgcGFyYW1fMSA9IHA7CglmbG9hdDIgcGFyYW1fMiA9IGZsb2F0MihjZWxsX3V2KTsKCWZsb2F0IHBhcmFtXzMgPSByOwoJZmxvYXQgcGFyYW1fNCA9IHIgKiA1MC4wOwoJcmV0dXJuIEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMsIHBhcmFtXzQpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3R1cmJ1bGVuY2VfUzFfYzAoZmxvYXQyIHV2KSAKewoJZmxvYXQyIHV2X3NjYWxlID0gdXYgKiBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbSA9IGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtXzEgPSB1dl9zY2FsZTsKCWZsb2F0MiBwYXJhbV8yID0gdV9jaXJjbGUxX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzMgPSB1X3JvdGF0aW9uMV9TMV9jMDsKCWZsb2F0IHBhcmFtXzQgPSAwLjE3OwoJZmxvYXQgXzMxOSA9IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKHBhcmFtLCBwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zLCBwYXJhbV80KTsKCWZsb2F0IGcxID0gXzMxOTsKCWZsb2F0MiBwYXJhbV81ID0gZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW1fNiA9IHV2X3NjYWxlOwoJZmxvYXQyIHBhcmFtXzcgPSB1X2NpcmNsZTJfUzFfYzA7CglmbG9hdDIgcGFyYW1fOCA9IHVfcm90YXRpb24yX1MxX2MwOwoJZmxvYXQgcGFyYW1fOSA9IDAuMjsKCWZsb2F0IF8zMzEgPSBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChwYXJhbV81LCBwYXJhbV82LCBwYXJhbV83LCBwYXJhbV84LCBwYXJhbV85KTsKCWZsb2F0IGcyID0gXzMzMTsKCWZsb2F0MiBwYXJhbV8xMCA9IGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtXzExID0gdXZfc2NhbGU7CglmbG9hdDIgcGFyYW1fMTIgPSB1X2NpcmNsZTNfUzFfYzA7CglmbG9hdDIgcGFyYW1fMTMgPSB1X3JvdGF0aW9uM19TMV9jMDsKCWZsb2F0IHBhcmFtXzE0ID0gMC4yNzU7CglmbG9hdCBfMzQ0ID0gRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAocGFyYW1fMTAsIHBhcmFtXzExLCBwYXJhbV8xMiwgcGFyYW1fMTMsIHBhcmFtXzE0KTsKCWZsb2F0IGczID0gXzM0NDsKCWZsb2F0IHYgPSAoKGcxICogZzEgKyBnMikgLSBnMykgKiAwLjU7CglyZXR1cm4gY2xhbXAoMC40NSArIDAuOCAqIHYsIDAuMCwgMS4wKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X3JpbmdfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgdGhpY2tuZXNzLCBmbG9hdCBibHVyKSAKewoJZmxvYXQyIHBhcmFtID0gdXY7CglmbG9hdDIgcGFyYW1fMSA9IHh5OwoJZmxvYXQgcGFyYW1fMiA9IHJhZGl1cyArIHRoaWNrbmVzczsKCWZsb2F0IHBhcmFtXzMgPSBibHVyOwoJZmxvYXQgY2lyY2xlX291dGVyID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW0sIHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMpOwoJZmxvYXQyIHBhcmFtXzQgPSB1djsKCWZsb2F0MiBwYXJhbV81ID0geHk7CglmbG9hdCBwYXJhbV82ID0gbWF4KHJhZGl1cyAtIHRoaWNrbmVzcywgMC4wKTsKCWZsb2F0IHBhcmFtXzcgPSBibHVyOwoJZmxvYXQgY2lyY2xlX2lubmVyID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW1fNCwgcGFyYW1fNSwgcGFyYW1fNiwgcGFyYW1fNyk7CglyZXR1cm4gY2xhbXAoY2lyY2xlX291dGVyIC0gY2lyY2xlX2lubmVyLCAwLjAsIDEuMCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHJpYW5nbGVfbm9pc2VfUzFfYzAoaW5vdXQgZmxvYXQyIG4pIAp7CgluID0gZnJhY3QobiAqIGZsb2F0Mig1LjM5ODcsIDUuNDQyMSkpOwoJbiArPSBmbG9hdDIoZG90KG4ueXgsIG4gKyBmbG9hdDIoMjEuNTM1MSwgMTQuMzEzNykpKTsKCWZsb2F0IHh5ID0gbi54ICogbi55OwoJcmV0dXJuIChmcmFjdCh4eSAqIDk1LjQzMDcpICsgZnJhY3QoeHkgKiA3NS4wNDk2MSkpIC0gMS4wOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChmbG9hdCB2LCBmbG9hdCBsLCBmbG9hdCBoKSAKewoJcmV0dXJuIHN0ZXAobCwgdikgKiAoMS4wIC0gc3RlcChoLCB2KSk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc3BhcmtsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0IHQpIAp7CglmbG9hdDIgcGFyYW0gPSB1djsKCWZsb2F0IF8yNDIgPSBGTFRfZmx1dHRlcl9sb2NhbF90cmlhbmdsZV9ub2lzZV9TMV9jMChwYXJhbSk7CglmbG9hdCBuID0gXzI0MjsKCWZsb2F0IHBhcmFtXzEgPSBuOwoJZmxvYXQgcGFyYW1fMiA9IDAuMDsKCWZsb2F0IHBhcmFtXzMgPSAwLjA1OwoJZmxvYXQgcyA9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zKTsKCWZsb2F0IHBhcmFtXzQgPSBuICsgc2luKDMuMTQxNTkyNzQgKiAodCArIDAuMzUpKTsKCWZsb2F0IHBhcmFtXzUgPSAwLjE7CglmbG9hdCBwYXJhbV82ID0gMC4xNTsKCXMgKz0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzQsIHBhcmFtXzUsIHBhcmFtXzYpOwoJZmxvYXQgcGFyYW1fNyA9IG4gKyBzaW4oMy4xNDE1OTI3NCAqICh0ICsgMC43KSk7CglmbG9hdCBwYXJhbV84ID0gMC4yOwoJZmxvYXQgcGFyYW1fOSA9IDAuMjU7CglzICs9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV83LCBwYXJhbV84LCBwYXJhbV85KTsKCWZsb2F0IHBhcmFtXzEwID0gbiArIHNpbigzLjE0MTU5Mjc0ICogKHQgKyAxLjA1KSk7CglmbG9hdCBwYXJhbV8xMSA9IDAuMzsKCWZsb2F0IHBhcmFtXzEyID0gMC4zNTsKCXMgKz0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzEwLCBwYXJhbV8xMSwgcGFyYW1fMTIpOwoJcmV0dXJuIGNsYW1wKHMsIDAuMCwgMS4wKSAqIDAuNTU7Cn0Kdm9pZCBGTFRfbWFpbl9TMV9jMCgpIAp7Cgl1X2FscGhhX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC54OwoJdV9zcGFya2xlX2FscGhhX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC55OwoJdV9ibHVyX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC56OwoJdV9yYWRpdXNfc2NhbGVfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLnc7CglmbG9hdDIgcCA9IEZMVF9mbHV0dGVyX2xvY2FsX0ZsdXR0ZXJGcmFnQ29vcmRfUzFfYzAoKTsKCWZsb2F0MiB1dl8xID0gcCAqIHVfcmVzb2x1dGlvbl9zY2FsZV9TMV9jMDsKCWZsb2F0MiBkZW5zaXR5X3V2ID0gdXZfMSAtIG1vZChwLCB1X25vaXNlX3NjYWxlX1MxX2MwKTsKCWZsb2F0IHJhZGl1cyA9IHVfbWF4X3JhZGl1c19TMV9jMCAqIHVfcmFkaXVzX3NjYWxlX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzEzID0gdXZfMTsKCWZsb2F0IHR1cmJ1bGVuY2UgPSBGTFRfZmx1dHRlcl9sb2NhbF90dXJidWxlbmNlX1MxX2MwKHBhcmFtXzEzKTsKCWZsb2F0MiBwYXJhbV8xNCA9IHA7CglmbG9hdDIgcGFyYW1fMTUgPSB1X2NlbnRlcl9TMV9jMDsKCWZsb2F0IHBhcmFtXzE2ID0gcmFkaXVzOwoJZmxvYXQgcGFyYW1fMTcgPSAwLjA1ICogdV9tYXhfcmFkaXVzX1MxX2MwOwoJZmxvYXQgcGFyYW1fMTggPSB1X2JsdXJfUzFfYzA7CglmbG9hdCByaW5nID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9yaW5nX1MxX2MwKHBhcmFtXzE0LCBwYXJhbV8xNSwgcGFyYW1fMTYsIHBhcmFtXzE3LCBwYXJhbV8xOCk7CglmbG9hdDIgcGFyYW1fMTkgPSBkZW5zaXR5X3V2OwoJZmxvYXQgcGFyYW1fMjAgPSB1X25vaXNlX3BoYXNlX1MxX2MwOwoJZmxvYXQgc3BhcmtsZSA9ICgoRkxUX2ZsdXR0ZXJfbG9jYWxfc3BhcmtsZV9TMV9jMChwYXJhbV8xOSwgcGFyYW1fMjApICogcmluZykgKiB0dXJidWxlbmNlKSAqIHVfc3BhcmtsZV9hbHBoYV9TMV9jMDsKCWZsb2F0MiBwYXJhbV8yMSA9IHA7CglmbG9hdDIgcGFyYW1fMjIgPSB1X2NlbnRlcl9TMV9jMDsKCWZsb2F0IHBhcmFtXzIzID0gcmFkaXVzOwoJZmxvYXQgcGFyYW1fMjQgPSB1X2JsdXJfUzFfYzA7CglmbG9hdCB3YXZlX2FscGhhID0gKEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtXzIxLCBwYXJhbV8yMiwgcGFyYW1fMjMsIHBhcmFtXzI0KSAqIHVfYWxwaGFfUzFfYzApICogdV9jb2xvcl9TMV9jMC53OwoJZmxvYXQ0IHdhdmVfY29sb3IgPSBmbG9hdDQodV9jb2xvcl9TMV9jMC54eXogKiB3YXZlX2FscGhhLCB3YXZlX2FscGhhKTsKCWZyYWdDb2xvcl9TMV9jMCA9IG1peCh3YXZlX2NvbG9yLCBmbG9hdDQoMS4wKSwgZmxvYXQ0KHNwYXJrbGUpKTsKfQpoYWxmNCBydW50aW1lX3NoYWRlcl9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzBfaW5Db2xvciA9IF9pbnB1dDsKCWZsb2F0MiBfdG1wXzFfY29vcmRzID0gdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CglmbHV0dGVyX0ZyYWdDb29yZF9TMV9jMCA9IGZsb2F0NChfdG1wXzFfY29vcmRzLCAwLjAsIDAuMCk7CglGTFRfbWFpbl9TMV9jMCgpOwoJcmV0dXJuIGhhbGY0KGhhbGY0KGZyYWdDb2xvcl9TMV9jMCkpOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gcnVudGltZV9zaGFkZXJfUzFfYzAoX2lucHV0KTsKfQpoYWxmNCBDaXJjbGVfUzJfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF8yX2luQ29sb3IgPSBfaW5wdXQ7CgloYWxmIGQ7CglpZiAoaW50KDEpID09IGtJbnZlcnNlRmlsbEJXX1MyX2MwIHx8IGludCgxKSA9PSBrSW52ZXJzZUZpbGxBQV9TMl9jMCkgCgl7CgkJZCA9IGhhbGYoKGxlbmd0aCgodWNpcmNsZV9TMl9jMC54eSAtIHNrX0ZyYWdDb29yZC54eSkgKiB1Y2lyY2xlX1MyX2MwLncpIC0gMS4wKSAqIHVjaXJjbGVfUzJfYzAueik7Cgl9CgllbHNlIAoJewoJCWQgPSBoYWxmKCgxLjAgLSBsZW5ndGgoKHVjaXJjbGVfUzJfYzAueHkgLSBza19GcmFnQ29vcmQueHkpICogdWNpcmNsZV9TMl9jMC53KSkgKiB1Y2lyY2xlX1MyX2MwLnopOwoJfQoJcmV0dXJuIGhhbGY0KGhhbGY0KGludCgxKSA9PSBrRmlsbEFBX1MyX2MwIHx8IGludCgxKSA9PSBrSW52ZXJzZUZpbGxBQV9TMl9jMCA/IHNhdHVyYXRlKGQpIDogaGFsZihkID4gMC41KSkpOwp9CmhhbGY0IEJsZW5kX1MyKGhhbGY0IF9zcmMsIGhhbGY0IF9kc3QpIAp7CglyZXR1cm4gYmxlbmRfbW9kdWxhdGUoX3NyYywgQ2lyY2xlX1MyX2MwKF9zcmMpKTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJZmxvYXQgY292ZXJhZ2UgPSB2Y292ZXJhZ2VfUzA7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGNvdmVyYWdlKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IE1hdHJpeEVmZmVjdF9TMShvdXRwdXRDb2xvcl9TMCk7CgloYWxmNCBvdXRwdXRfUzI7CglvdXRwdXRfUzIgPSBCbGVuZF9TMihvdXRwdXRDb3ZlcmFnZV9TMCwgaGFsZjQoMSkpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dF9TMjsKCX0KfQoAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAHBvc2l0aW9uCAAAAGNvdmVyYWdlBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","EEAQMYAAMAAAEADAAABAEYAAAICIAB5AABQAAAQAMAAAEATAAABAIIGAAEDCBYQCA4AAAAAAAAZQAAAAAABAAAAACAZAAAAA":"DAAAAExTS1MoDAAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDQgcmFkaWlfc2VsZWN0b3I7CmluIGZsb2F0NCBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzOwppbiBmbG9hdDQgYWFfYmxvYXRfYW5kX2NvdmVyYWdlOwppbiBmbG9hdDQgcmFkaWlfeDsKaW4gZmxvYXQ0IHJhZGlpX3k7CmluIGZsb2F0NCBza2V3OwppbiBmbG9hdDIgdHJhbnNsYXRlX2FuZF9sb2NhbHJvdGF0ZTsKaW4gaGFsZjQgY29sb3I7Cm5vcGVyc3BlY3RpdmUgb3V0IGhhbGY0IHZjb2xvcl9TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQyIHZhcmNjb29yZF9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgRmlsbFJSZWN0T3A6OlByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7CglmbG9hdCBhYV9ibG9hdF9tdWx0aXBsaWVyID0gMTsKCWZsb2F0MiBjb3JuZXIgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnh5OwoJZmxvYXQyIHJhZGl1c19vdXRzZXQgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnp3OwoJZmxvYXQyIGFhX2Jsb2F0X2RpcmVjdGlvbiA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS54eTsKCWZsb2F0IGlzX2xpbmVhcl9jb3ZlcmFnZSA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS53OwoJZmxvYXQyIHBpeGVsbGVuZ3RoID0gaW52ZXJzZXNxcnQoZmxvYXQyKGRvdChza2V3Lnh6LCBza2V3Lnh6KSwgZG90KHNrZXcueXcsIHNrZXcueXcpKSk7CglmbG9hdDQgbm9ybWFsaXplZF9heGlzX2RpcnMgPSBza2V3ICogcGl4ZWxsZW5ndGgueHl4eTsKCWZsb2F0MiBheGlzd2lkdGhzID0gKGFicyhub3JtYWxpemVkX2F4aXNfZGlycy54eSkgKyBhYnMobm9ybWFsaXplZF9heGlzX2RpcnMuencpKTsKCWZsb2F0MiBhYV9ibG9hdHJhZGl1cyA9IGF4aXN3aWR0aHMgKiBwaXhlbGxlbmd0aCAqIC41OwoJZmxvYXQ0IHJhZGlpX2FuZF9uZWlnaGJvcnMgPSByYWRpaV9zZWxlY3RvciogZmxvYXQ0eDQocmFkaWlfeCwgcmFkaWlfeSwgcmFkaWlfeC55eHd6LCByYWRpaV95Lnd6eXgpOwoJZmxvYXQyIHJhZGlpID0gcmFkaWlfYW5kX25laWdoYm9ycy54eTsKCWZsb2F0MiBuZWlnaGJvcl9yYWRpaSA9IHJhZGlpX2FuZF9uZWlnaGJvcnMuenc7CglmbG9hdCBjb3ZlcmFnZV9tdWx0aXBsaWVyID0gMTsKCWlmIChhbnkoZ3JlYXRlclRoYW4oYWFfYmxvYXRyYWRpdXMsIGZsb2F0MigxKSkpKSAKCXsKCQljb3JuZXIgPSBtYXgoYWJzKGNvcm5lciksIGFhX2Jsb2F0cmFkaXVzKSAqIHNpZ24oY29ybmVyKTsKCQljb3ZlcmFnZV9tdWx0aXBsaWVyID0gMSAvIChtYXgoYWFfYmxvYXRyYWRpdXMueCwgMSkgKiBtYXgoYWFfYmxvYXRyYWRpdXMueSwgMSkpOwoJCXJhZGlpID0gZmxvYXQyKDApOwoJfQoJZmxvYXQgY292ZXJhZ2UgPSBhYV9ibG9hdF9hbmRfY292ZXJhZ2UuejsKCWlmIChhbnkobGVzc1RoYW4ocmFkaWksIGFhX2Jsb2F0cmFkaXVzICogMS41KSkpIAoJewoJCXJhZGlpID0gZmxvYXQyKDApOwoJCWFhX2Jsb2F0X2RpcmVjdGlvbiA9IHNpZ24oY29ybmVyKTsKCQlpZiAoY292ZXJhZ2UgPiAuNSkgCgkJewoJCQlhYV9ibG9hdF9kaXJlY3Rpb24gPSAtYWFfYmxvYXRfZGlyZWN0aW9uOwoJCX0KCQlpc19saW5lYXJfY292ZXJhZ2UgPSAxOwoJfQoJZWxzZSAKCXsKCQlyYWRpaSA9IGNsYW1wKHJhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQluZWlnaGJvcl9yYWRpaSA9IGNsYW1wKG5laWdoYm9yX3JhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQlmbG9hdDIgc3BhY2luZyA9IDIgLSByYWRpaSAtIG5laWdoYm9yX3JhZGlpOwoJCWZsb2F0MiBleHRyYV9wYWQgPSBtYXgocGl4ZWxsZW5ndGggKiAuMDYyNSAtIHNwYWNpbmcsIGZsb2F0MigwKSk7CgkJcmFkaWkgLT0gZXh0cmFfcGFkICogLjU7Cgl9CglmbG9hdDIgYWFfb3V0c2V0ID0gYWFfYmxvYXRfZGlyZWN0aW9uICogYWFfYmxvYXRyYWRpdXMgKiBhYV9ibG9hdF9tdWx0aXBsaWVyOwoJZmxvYXQyIHZlcnRleHBvcyA9IGNvcm5lciArIHJhZGl1c19vdXRzZXQgKiByYWRpaSArIGFhX291dHNldDsKCWlmIChjb3ZlcmFnZSA+IC41KSAKCXsKCQlpZiAoYWFfYmxvYXRfZGlyZWN0aW9uLnggIT0gMCAmJiB2ZXJ0ZXhwb3MueCAqIGNvcm5lci54IDwgMCkgCgkJewoJCQlmbG9hdCBiYWNrc2V0ID0gYWJzKHZlcnRleHBvcy54KTsKCQkJdmVydGV4cG9zLnggPSAwOwoJCQl2ZXJ0ZXhwb3MueSArPSBiYWNrc2V0ICogc2lnbihjb3JuZXIueSkgKiBwaXhlbGxlbmd0aC55L3BpeGVsbGVuZ3RoLng7CgkJCWNvdmVyYWdlID0gKGNvdmVyYWdlIC0gLjUpICogYWJzKGNvcm5lci54KSAvIChhYnMoY29ybmVyLngpICsgYmFja3NldCkgKyAuNTsKCQl9CgkJaWYgKGFhX2Jsb2F0X2RpcmVjdGlvbi55ICE9IDAgJiYgdmVydGV4cG9zLnkgKiBjb3JuZXIueSA8IDApIAoJCXsKCQkJZmxvYXQgYmFja3NldCA9IGFicyh2ZXJ0ZXhwb3MueSk7CgkJCXZlcnRleHBvcy55ID0gMDsKCQkJdmVydGV4cG9zLnggKz0gYmFja3NldCAqIHNpZ24oY29ybmVyLngpICogcGl4ZWxsZW5ndGgueC9waXhlbGxlbmd0aC55OwoJCQljb3ZlcmFnZSA9IChjb3ZlcmFnZSAtIC41KSAqIGFicyhjb3JuZXIueSkgLyAoYWJzKGNvcm5lci55KSArIGJhY2tzZXQpICsgLjU7CgkJfQoJfQoJZmxvYXQyeDIgc2tld21hdHJpeCA9IGZsb2F0MngyKHNrZXcueHksIHNrZXcuencpOwoJZmxvYXQyIGRldmNvb3JkID0gdmVydGV4cG9zICogc2tld21hdHJpeCArIHRyYW5zbGF0ZV9hbmRfbG9jYWxyb3RhdGUueHk7CglpZiAoMCAhPSBpc19saW5lYXJfY292ZXJhZ2UpIAoJewoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MigwLCBjb3ZlcmFnZSAqIGNvdmVyYWdlX211bHRpcGxpZXIpOwoJfQoJZWxzZSAKCXsKCQlmbG9hdDIgYXJjY29vcmQgPSAxIC0gYWJzKHJhZGl1c19vdXRzZXQpICsgYWFfb3V0c2V0L3JhZGlpICogY29ybmVyOwoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MihhcmNjb29yZC54KzEsIGFyY2Nvb3JkLnkpOwoJfQoJc2tfUG9zaXRpb24gPSBkZXZjb29yZC54eTAxOwp9CgAAAACZAgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCm5vcGVyc3BlY3RpdmUgaW4gaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2YXJjY29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBGaWxsUlJlY3RPcDo6UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJZmxvYXQgeF9wbHVzXzE9dmFyY2Nvb3JkX1MwLngsIHk9dmFyY2Nvb3JkX1MwLnk7CgloYWxmIGNvdmVyYWdlOwoJaWYgKDAgPT0geF9wbHVzXzEpIAoJewoJCWNvdmVyYWdlID0gaGFsZih5KTsKCX0KCWVsc2UgCgl7CgkJZmxvYXQgZm4gPSB4X3BsdXNfMSAqICh4X3BsdXNfMSAtIDIpOwoJCWZuID0gZm1hKHkseSwgZm4pOwoJCWZsb2F0IGZud2lkdGggPSBmd2lkdGgoZm4pOwoJCWNvdmVyYWdlID0gLjUgLSBoYWxmKGZuL2Zud2lkdGgpOwoJCWNvdmVyYWdlID0gY2xhbXAoY292ZXJhZ2UsIDAsIDEpOwoJfQoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChjb3ZlcmFnZSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAACAAAAA4AAAByYWRpaV9zZWxlY3RvcgAAGQAAAGNvcm5lcl9hbmRfcmFkaXVzX291dHNldHMAAAAVAAAAYWFfYmxvYXRfYW5kX2NvdmVyYWdlAAAABwAAAHJhZGlpX3gABwAAAHJhZGlpX3kABAAAAHNrZXcZAAAAdHJhbnNsYXRlX2FuZF9sb2NhbHJvdGF0ZQAAAAUAAABjb2xvcgAAAAAAAAA=","GYQACAAAAAMAADAAAIOAAAH677776IZOCAAP577777777777777777YBAAAAAAAAAAADEAAGAAAAAAAAAIAAAAAPAIABAAAAABAGEAAAAEAAAABNARCAIAAAAAAAAAAAAAYAGAAAAAQAAAAAAAQQGAAAAA":"DAAAAExTS1O8AQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzBfYzA7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7Cm5vcGVyc3BlY3RpdmUgb3V0IGhhbGY0IHZjb2xvcl9TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc180X1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCXZjb2xvcl9TMCA9IGNvbG9yOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwoJewoJCXZUcmFuc2Zvcm1lZENvb3Jkc180X1MwID0gZmxvYXQzeDIodW1hdHJpeF9TMV9jMF9jMCkgKiBwb3NpdGlvbi54eTE7Cgl9Cn0KAAAAAI0DAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxX2MwX2MwOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7Cm5vcGVyc3BlY3RpdmUgaW4gaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfNF9TMDsKaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMF9jMF9jMChoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MxLCB2VHJhbnNmb3JtZWRDb29yZHNfNF9TMCkuMDAwcjsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzBfYzBfYzAoX2lucHV0KTsKfQpoYWxmNCBEZXZpY2VTcGFjZV9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gTWF0cml4RWZmZWN0X1MxX2MwX2MwKF9pbnB1dCk7Cn0KaGFsZjQgQmxlbmRfUzEoaGFsZjQgX3NyYywgaGFsZjQgX2RzdCkgCnsKCXJldHVybiBibGVuZF9kc3RfaW4oRGV2aWNlU3BhY2VfUzFfYzAoX3NyYyksIF9zcmMpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQmxlbmRfUzEob3V0cHV0Q292ZXJhZ2VfUzAsIGhhbGY0KDEpKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgUAAABjb2xvcgAAAAAAAAA=","GZIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAHIBK2VD3EOCAAAAAABUXHIMAQAAAAWSQ4HO4SAAAAAMAAAAAEBUEFLMJAIAAAQCI6KVAYAAAAAAAAAAAQAAEACUA2JT4HAIAAAADIIODXOJIBAAAGAAAAACAKAC5XEQEAAAAAEPF2SMAAAAAAAAIAAAACXUUGB3XUUAQAADAAAAAAABARO3SJCAAAAACGSZJWCAAAAAAAIAAAABLFBUEFLMJAIAAAAAAAAAAACIMVSTUFAEAAAAAIAAAAAWFBSHSVIGAAAAAAAAAAAAABEBAABAAAAADIEEQCEAAAAAAAAAAAQAMQAAAAAAAQAAAABAMQAAA":"DAAAAExTS1PaAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzBfYzBfYzE7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfNl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfNl9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzFfYzBfYzBfYzEpICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAABAAAAcQkAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQp1bmlmb3JtIGhhbGY0IHVzdGFydF9TMV9jMF9jMF9jMDsKdW5pZm9ybSBoYWxmNCB1ZW5kX1MxX2MwX2MwX2MwOwp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzBfYzBfYzE7CnVuaWZvcm0gaGFsZjQgdWxlZnRCb3JkZXJDb2xvcl9TMV9jMF9jMDsKdW5pZm9ybSBoYWxmNCB1cmlnaHRCb3JkZXJDb2xvcl9TMV9jMF9jMDsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxX2MxOwp1bmlmb3JtIGhhbGYgdXJhbmdlX1MxOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7Cm5vcGVyc3BlY3RpdmUgaW4gaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfNl9TMDsKaGFsZjQgU2luZ2xlSW50ZXJ2YWxDb2xvcml6ZXJfUzFfYzBfYzBfYzAoaGFsZjQgX2lucHV0LCBmbG9hdDIgX2Nvb3JkcykgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJZmxvYXQyIF90bXBfMV9jb29yZHMgPSBfY29vcmRzOwoJcmV0dXJuIGhhbGY0KG1peCh1c3RhcnRfUzFfYzBfYzBfYzAsIHVlbmRfUzFfYzBfYzBfYzAsIGhhbGYoX3RtcF8xX2Nvb3Jkcy54KSkpOwp9CmhhbGY0IExpbmVhckxheW91dF9TMV9jMF9jMF9jMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzJfaW5Db2xvciA9IF9pbnB1dDsKCWZsb2F0MiBfdG1wXzNfY29vcmRzID0gdlRyYW5zZm9ybWVkQ29vcmRzXzZfUzA7CglyZXR1cm4gaGFsZjQoaGFsZjQoaGFsZihfdG1wXzNfY29vcmRzLngpICsgMWUtMDUsIDEuMCwgMC4wLCAwLjApKTsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzFfYzBfYzBfYzEoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIExpbmVhckxheW91dF9TMV9jMF9jMF9jMV9jMChfaW5wdXQpOwp9CmhhbGY0IENsYW1wZWRHcmFkaWVudF9TMV9jMF9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzRfaW5Db2xvciA9IF9pbnB1dDsKCWhhbGY0IHQgPSBNYXRyaXhFZmZlY3RfUzFfYzBfYzBfYzEoX3RtcF80X2luQ29sb3IpOwoJaGFsZjQgb3V0Q29sb3I7CglpZiAoIWJvb2woaW50KDEpKSAmJiB0LnkgPCAwLjApIAoJewoJCW91dENvbG9yID0gaGFsZjQoMC4wKTsKCX0KCWVsc2UgaWYgKHQueCA8IDAuMCkgCgl7CgkJb3V0Q29sb3IgPSB1bGVmdEJvcmRlckNvbG9yX1MxX2MwX2MwOwoJfQoJZWxzZSBpZiAodC54ID4gMS4wKSAKCXsKCQlvdXRDb2xvciA9IHVyaWdodEJvcmRlckNvbG9yX1MxX2MwX2MwOwoJfQoJZWxzZSAKCXsKCQlvdXRDb2xvciA9IFNpbmdsZUludGVydmFsQ29sb3JpemVyX1MxX2MwX2MwX2MwKF90bXBfNF9pbkNvbG9yLCBmbG9hdDIoaGFsZjIodC54LCAwLjApKSk7Cgl9CglyZXR1cm4gaGFsZjQob3V0Q29sb3IpOwp9CmhhbGY0IERpc2FibGVDb3ZlcmFnZUFzQWxwaGFfUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJX2lucHV0ID0gQ2xhbXBlZEdyYWRpZW50X1MxX2MwX2MwKF9pbnB1dCk7CgloYWxmNCBfdG1wXzVfaW5Db2xvciA9IF9pbnB1dDsKCXJldHVybiBoYWxmNChfaW5wdXQpOwp9CmhhbGY0IFRleHR1cmVFZmZlY3RfUzFfYzFfYzAoaGFsZjQgX2lucHV0LCBmbG9hdDIgX2Nvb3JkcykgCnsKCXJldHVybiBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzEsIF9jb29yZHMpLjAwMHI7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxX2MxKGhhbGY0IF9pbnB1dCwgZmxvYXQyIF9jb29yZHMpIAp7CglyZXR1cm4gVGV4dHVyZUVmZmVjdF9TMV9jMV9jMChfaW5wdXQsIGZsb2F0M3gyKHVtYXRyaXhfUzFfYzEpICogX2Nvb3Jkcy54eTEpOwp9CmhhbGY0IERpdGhlcl9TMShoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzZfaW5Db2xvciA9IF9pbnB1dDsKCWhhbGY0IGNvbG9yID0gRGlzYWJsZUNvdmVyYWdlQXNBbHBoYV9TMV9jMChfdG1wXzZfaW5Db2xvcik7CgloYWxmIHZhbHVlID0gTWF0cml4RWZmZWN0X1MxX2MxKF90bXBfNl9pbkNvbG9yLCBza19GcmFnQ29vcmQueHkpLncgLSAwLjU7CglyZXR1cm4gaGFsZjQoaGFsZjQoY2xhbXAoY29sb3IueHl6ICsgdmFsdWUgKiB1cmFuZ2VfUzEsIDAuMCwgY29sb3IudyksIGNvbG9yLncpKTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IERpdGhlcl9TMShvdXRwdXRDb2xvcl9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0X1MxICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAIAAAAcG9zaXRpb24FAAAAY29sb3IAAAAKAAAAbG9jYWxDb29yZAAAAAAAAA==","GYJAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAQAAAAAAQQGAAZAABQAAAAAAAACAAAAADYCAAIAAAAAIBRAAAABAAAAALIEIQCAAAAAAAAAAAAAGABQAAAAEAAAAAAAEEBQAAAA":"DAAAAExTS1PSAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzBfYzA7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2bG9jYWxDb29yZF9TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc180X1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCXZsb2NhbENvb3JkX1MwID0gbG9jYWxDb29yZDsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfNF9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzFfYzBfYzApICogcG9zaXRpb24ueHkxOwoJfQp9CgAAAAAAACUEAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxX2MwX2MwOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzA7CnNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMTsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc180X1MwOwpoYWxmNCBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzEsIHZUcmFuc2Zvcm1lZENvb3Jkc180X1MwKS4wMDByOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMV9jMF9jMChoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gVGV4dHVyZUVmZmVjdF9TMV9jMF9jMF9jMChfaW5wdXQpOwp9CmhhbGY0IERldmljZVNwYWNlX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoX2lucHV0KTsKfQpoYWxmNCBCbGVuZF9TMShoYWxmNCBfc3JjLCBoYWxmNCBfZHN0KSAKewoJcmV0dXJuIGJsZW5kX2RzdF9pbihEZXZpY2VTcGFjZV9TMV9jMChfc3JjKSwgX3NyYyk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWZsb2F0MiB0ZXhDb29yZDsKCXRleENvb3JkID0gdmxvY2FsQ29vcmRfUzA7CglvdXRwdXRDb2xvcl9TMCA9IChibGVuZF9tb2R1bGF0ZShzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzAsIHRleENvb3JkKSwgaGFsZjQoMSkpKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBCbGVuZF9TMShvdXRwdXRDb3ZlcmFnZV9TMCwgaGFsZjQoMSkpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0X1MxOwoJfQp9CgAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACAAAAHBvc2l0aW9uCgAAAGxvY2FsQ29vcmQAAAAAAAA=","GZIACAAAABQAAGAAAQ4AAAAAGQQAARC4GAAAIOCAAD6P7777777777YDAAAAAAAAAAAJQBBYGQ467YIAAAAAAQAAAAAMACTRNBZN5QYBAAAAAAAAAAAIAAJQAAAAAAAANAAAAAHQVERARJYAAAABQAAAABAAAAAA4BAQAAACAAAAASAMAAQAAAAAUCCYBCAAAAAAAAAAAAAANJABAAAMBJ4KECOAEAAAMAAAAAAAAEAABAAV6GUSECFHAAAAAGAAAAAAAAAAAAAGABQAAAAEAAAAAAAEEBQA":"DAAAAExTS1PdAgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMl9jMF9jMDsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdCBjb3ZlcmFnZTsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0IHZjb3ZlcmFnZV9TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzZfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQyIHBvc2l0aW9uID0gcG9zaXRpb24ueHk7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCXZjb3ZlcmFnZV9TMCA9IGNvdmVyYWdlOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwoJewoJCXZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwID0gZmxvYXQzeDIodW1hdHJpeF9TMSkgKiBsb2NhbENvb3JkLnh5MTsKCX0KCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfNl9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzJfYzBfYzApICogcG9zaXRpb24ueHkxOwoJfQp9CgAAAAEAAADvIQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCmZsb2F0NCBmbHV0dGVyX0ZyYWdDb29yZF9TMV9jMDsKZmxvYXQ0IGZyYWdDb2xvcl9TMV9jMDsKZmxvYXQgdV9hbHBoYV9TMV9jMDsKZmxvYXQgdV9zcGFya2xlX2FscGhhX1MxX2MwOwpmbG9hdCB1X2JsdXJfUzFfYzA7CmZsb2F0IHVfcmFkaXVzX3NjYWxlX1MxX2MwOwpjb25zdCBpbnQga0ZpbGxCV19TMl9jMV9jMCA9IDA7CmNvbnN0IGludCBrSW52ZXJzZUZpbGxCV19TMl9jMV9jMCA9IDI7CmNvbnN0IGludCBrSW52ZXJzZUZpbGxBQV9TMl9jMV9jMCA9IDM7CnVuaWZvcm0gZmxvYXQ0IHVfY29sb3JfUzFfYzA7CnVuaWZvcm0gZmxvYXQ0IHVfY29tcG9zaXRlXzFfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2VudGVyX1MxX2MwOwp1bmlmb3JtIGZsb2F0IHVfbWF4X3JhZGl1c19TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yZXNvbHV0aW9uX3NjYWxlX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X25vaXNlX3NjYWxlX1MxX2MwOwp1bmlmb3JtIGZsb2F0IHVfbm9pc2VfcGhhc2VfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2lyY2xlMV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jaXJjbGUyX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NpcmNsZTNfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcm90YXRpb24xX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3JvdGF0aW9uMl9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yb3RhdGlvbjNfUzFfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MyX2MwX2MwOwp1bmlmb3JtIGZsb2F0NCB1cmVjdFVuaWZvcm1fUzJfYzFfYzA7CnNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMjsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQgdmNvdmVyYWdlX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzZfUzA7CmZsb2F0MiBGTFRfZmx1dHRlcl9sb2NhbF9GbHV0dGVyRnJhZ0Nvb3JkX1MxX2MwKCk7CmZsb2F0MngyIEZMVF9mbHV0dGVyX2xvY2FsX3JvdGF0ZTJkX1MxX2MwKGZsb2F0MiByYWQpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCBibHVyKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAoZmxvYXQyIHJlc29sdXRpb24sIGlub3V0IGZsb2F0MiBwLCBmbG9hdDIgeHksIGZsb2F0MiByb3RhdGlvbiwgZmxvYXQgY2VsbF9kaWFtZXRlcik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3R1cmJ1bGVuY2VfUzFfYzAoZmxvYXQyIHV2KTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9yaW5nX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IHRoaWNrbmVzcywgZmxvYXQgYmx1cik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RyaWFuZ2xlX25vaXNlX1MxX2MwKGlub3V0IGZsb2F0MiBuKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKGZsb2F0IHYsIGZsb2F0IGwsIGZsb2F0IGgpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zcGFya2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQgdCk7CnZvaWQgRkxUX21haW5fUzFfYzAoKTsKZmxvYXQyIEZMVF9mbHV0dGVyX2xvY2FsX0ZsdXR0ZXJGcmFnQ29vcmRfUzFfYzAoKSAKewoJcmV0dXJuIGZsdXR0ZXJfRnJhZ0Nvb3JkX1MxX2MwLnh5Owp9CmZsb2F0MngyIEZMVF9mbHV0dGVyX2xvY2FsX3JvdGF0ZTJkX1MxX2MwKGZsb2F0MiByYWQpIAp7CglyZXR1cm4gZmxvYXQyeDIocmFkLngsIC1yYWQueSwgcmFkLnksIHJhZC54KTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCBibHVyKSAKewoJZmxvYXQgYmx1cl9oYWxmID0gYmx1ciAqIDAuNTsKCWZsb2F0IGQgPSBkaXN0YW5jZSh1diwgeHkpOwoJcmV0dXJuIDEuMCAtIHNtb290aHN0ZXAoMS4wIC0gYmx1cl9oYWxmLCAxLjAgKyBibHVyX2hhbGYsIGQgLyByYWRpdXMpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKGZsb2F0MiByZXNvbHV0aW9uLCBpbm91dCBmbG9hdDIgcCwgZmxvYXQyIHh5LCBmbG9hdDIgcm90YXRpb24sIGZsb2F0IGNlbGxfZGlhbWV0ZXIpIAp7CglmbG9hdDIgcGFyYW0gPSByb3RhdGlvbjsKCXAgPSBGTFRfZmx1dHRlcl9sb2NhbF9yb3RhdGUyZF9TMV9jMChwYXJhbSkgKiAoeHkgLSBwKSArIHh5OwoJcCA9IG1vZChwLCBmbG9hdDIoY2VsbF9kaWFtZXRlcikpIC8gcmVzb2x1dGlvbjsKCWZsb2F0IGNlbGxfdXYgPSAoY2VsbF9kaWFtZXRlciAvIHJlc29sdXRpb24ueSkgKiAwLjU7CglmbG9hdCByID0gMC42NSAqIGNlbGxfdXY7CglmbG9hdDIgcGFyYW1fMSA9IHA7CglmbG9hdDIgcGFyYW1fMiA9IGZsb2F0MihjZWxsX3V2KTsKCWZsb2F0IHBhcmFtXzMgPSByOwoJZmxvYXQgcGFyYW1fNCA9IHIgKiA1MC4wOwoJcmV0dXJuIEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMsIHBhcmFtXzQpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3R1cmJ1bGVuY2VfUzFfYzAoZmxvYXQyIHV2KSAKewoJZmxvYXQyIHV2X3NjYWxlID0gdXYgKiBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbSA9IGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtXzEgPSB1dl9zY2FsZTsKCWZsb2F0MiBwYXJhbV8yID0gdV9jaXJjbGUxX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzMgPSB1X3JvdGF0aW9uMV9TMV9jMDsKCWZsb2F0IHBhcmFtXzQgPSAwLjE3OwoJZmxvYXQgXzMxOSA9IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKHBhcmFtLCBwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zLCBwYXJhbV80KTsKCWZsb2F0IGcxID0gXzMxOTsKCWZsb2F0MiBwYXJhbV81ID0gZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW1fNiA9IHV2X3NjYWxlOwoJZmxvYXQyIHBhcmFtXzcgPSB1X2NpcmNsZTJfUzFfYzA7CglmbG9hdDIgcGFyYW1fOCA9IHVfcm90YXRpb24yX1MxX2MwOwoJZmxvYXQgcGFyYW1fOSA9IDAuMjsKCWZsb2F0IF8zMzEgPSBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChwYXJhbV81LCBwYXJhbV82LCBwYXJhbV83LCBwYXJhbV84LCBwYXJhbV85KTsKCWZsb2F0IGcyID0gXzMzMTsKCWZsb2F0MiBwYXJhbV8xMCA9IGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtXzExID0gdXZfc2NhbGU7CglmbG9hdDIgcGFyYW1fMTIgPSB1X2NpcmNsZTNfUzFfYzA7CglmbG9hdDIgcGFyYW1fMTMgPSB1X3JvdGF0aW9uM19TMV9jMDsKCWZsb2F0IHBhcmFtXzE0ID0gMC4yNzU7CglmbG9hdCBfMzQ0ID0gRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAocGFyYW1fMTAsIHBhcmFtXzExLCBwYXJhbV8xMiwgcGFyYW1fMTMsIHBhcmFtXzE0KTsKCWZsb2F0IGczID0gXzM0NDsKCWZsb2F0IHYgPSAoKGcxICogZzEgKyBnMikgLSBnMykgKiAwLjU7CglyZXR1cm4gY2xhbXAoMC40NSArIDAuOCAqIHYsIDAuMCwgMS4wKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X3JpbmdfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgdGhpY2tuZXNzLCBmbG9hdCBibHVyKSAKewoJZmxvYXQyIHBhcmFtID0gdXY7CglmbG9hdDIgcGFyYW1fMSA9IHh5OwoJZmxvYXQgcGFyYW1fMiA9IHJhZGl1cyArIHRoaWNrbmVzczsKCWZsb2F0IHBhcmFtXzMgPSBibHVyOwoJZmxvYXQgY2lyY2xlX291dGVyID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW0sIHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMpOwoJZmxvYXQyIHBhcmFtXzQgPSB1djsKCWZsb2F0MiBwYXJhbV81ID0geHk7CglmbG9hdCBwYXJhbV82ID0gbWF4KHJhZGl1cyAtIHRoaWNrbmVzcywgMC4wKTsKCWZsb2F0IHBhcmFtXzcgPSBibHVyOwoJZmxvYXQgY2lyY2xlX2lubmVyID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW1fNCwgcGFyYW1fNSwgcGFyYW1fNiwgcGFyYW1fNyk7CglyZXR1cm4gY2xhbXAoY2lyY2xlX291dGVyIC0gY2lyY2xlX2lubmVyLCAwLjAsIDEuMCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHJpYW5nbGVfbm9pc2VfUzFfYzAoaW5vdXQgZmxvYXQyIG4pIAp7CgluID0gZnJhY3QobiAqIGZsb2F0Mig1LjM5ODcsIDUuNDQyMSkpOwoJbiArPSBmbG9hdDIoZG90KG4ueXgsIG4gKyBmbG9hdDIoMjEuNTM1MSwgMTQuMzEzNykpKTsKCWZsb2F0IHh5ID0gbi54ICogbi55OwoJcmV0dXJuIChmcmFjdCh4eSAqIDk1LjQzMDcpICsgZnJhY3QoeHkgKiA3NS4wNDk2MSkpIC0gMS4wOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChmbG9hdCB2LCBmbG9hdCBsLCBmbG9hdCBoKSAKewoJcmV0dXJuIHN0ZXAobCwgdikgKiAoMS4wIC0gc3RlcChoLCB2KSk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc3BhcmtsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0IHQpIAp7CglmbG9hdDIgcGFyYW0gPSB1djsKCWZsb2F0IF8yNDIgPSBGTFRfZmx1dHRlcl9sb2NhbF90cmlhbmdsZV9ub2lzZV9TMV9jMChwYXJhbSk7CglmbG9hdCBuID0gXzI0MjsKCWZsb2F0IHBhcmFtXzEgPSBuOwoJZmxvYXQgcGFyYW1fMiA9IDAuMDsKCWZsb2F0IHBhcmFtXzMgPSAwLjA1OwoJZmxvYXQgcyA9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zKTsKCWZsb2F0IHBhcmFtXzQgPSBuICsgc2luKDMuMTQxNTkyNzQgKiAodCArIDAuMzUpKTsKCWZsb2F0IHBhcmFtXzUgPSAwLjE7CglmbG9hdCBwYXJhbV82ID0gMC4xNTsKCXMgKz0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzQsIHBhcmFtXzUsIHBhcmFtXzYpOwoJZmxvYXQgcGFyYW1fNyA9IG4gKyBzaW4oMy4xNDE1OTI3NCAqICh0ICsgMC43KSk7CglmbG9hdCBwYXJhbV84ID0gMC4yOwoJZmxvYXQgcGFyYW1fOSA9IDAuMjU7CglzICs9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV83LCBwYXJhbV84LCBwYXJhbV85KTsKCWZsb2F0IHBhcmFtXzEwID0gbiArIHNpbigzLjE0MTU5Mjc0ICogKHQgKyAxLjA1KSk7CglmbG9hdCBwYXJhbV8xMSA9IDAuMzsKCWZsb2F0IHBhcmFtXzEyID0gMC4zNTsKCXMgKz0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzEwLCBwYXJhbV8xMSwgcGFyYW1fMTIpOwoJcmV0dXJuIGNsYW1wKHMsIDAuMCwgMS4wKSAqIDAuNTU7Cn0Kdm9pZCBGTFRfbWFpbl9TMV9jMCgpIAp7Cgl1X2FscGhhX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC54OwoJdV9zcGFya2xlX2FscGhhX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC55OwoJdV9ibHVyX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC56OwoJdV9yYWRpdXNfc2NhbGVfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLnc7CglmbG9hdDIgcCA9IEZMVF9mbHV0dGVyX2xvY2FsX0ZsdXR0ZXJGcmFnQ29vcmRfUzFfYzAoKTsKCWZsb2F0MiB1dl8xID0gcCAqIHVfcmVzb2x1dGlvbl9zY2FsZV9TMV9jMDsKCWZsb2F0MiBkZW5zaXR5X3V2ID0gdXZfMSAtIG1vZChwLCB1X25vaXNlX3NjYWxlX1MxX2MwKTsKCWZsb2F0IHJhZGl1cyA9IHVfbWF4X3JhZGl1c19TMV9jMCAqIHVfcmFkaXVzX3NjYWxlX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzEzID0gdXZfMTsKCWZsb2F0IHR1cmJ1bGVuY2UgPSBGTFRfZmx1dHRlcl9sb2NhbF90dXJidWxlbmNlX1MxX2MwKHBhcmFtXzEzKTsKCWZsb2F0MiBwYXJhbV8xNCA9IHA7CglmbG9hdDIgcGFyYW1fMTUgPSB1X2NlbnRlcl9TMV9jMDsKCWZsb2F0IHBhcmFtXzE2ID0gcmFkaXVzOwoJZmxvYXQgcGFyYW1fMTcgPSAwLjA1ICogdV9tYXhfcmFkaXVzX1MxX2MwOwoJZmxvYXQgcGFyYW1fMTggPSB1X2JsdXJfUzFfYzA7CglmbG9hdCByaW5nID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9yaW5nX1MxX2MwKHBhcmFtXzE0LCBwYXJhbV8xNSwgcGFyYW1fMTYsIHBhcmFtXzE3LCBwYXJhbV8xOCk7CglmbG9hdDIgcGFyYW1fMTkgPSBkZW5zaXR5X3V2OwoJZmxvYXQgcGFyYW1fMjAgPSB1X25vaXNlX3BoYXNlX1MxX2MwOwoJZmxvYXQgc3BhcmtsZSA9ICgoRkxUX2ZsdXR0ZXJfbG9jYWxfc3BhcmtsZV9TMV9jMChwYXJhbV8xOSwgcGFyYW1fMjApICogcmluZykgKiB0dXJidWxlbmNlKSAqIHVfc3BhcmtsZV9hbHBoYV9TMV9jMDsKCWZsb2F0MiBwYXJhbV8yMSA9IHA7CglmbG9hdDIgcGFyYW1fMjIgPSB1X2NlbnRlcl9TMV9jMDsKCWZsb2F0IHBhcmFtXzIzID0gcmFkaXVzOwoJZmxvYXQgcGFyYW1fMjQgPSB1X2JsdXJfUzFfYzA7CglmbG9hdCB3YXZlX2FscGhhID0gKEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtXzIxLCBwYXJhbV8yMiwgcGFyYW1fMjMsIHBhcmFtXzI0KSAqIHVfYWxwaGFfUzFfYzApICogdV9jb2xvcl9TMV9jMC53OwoJZmxvYXQ0IHdhdmVfY29sb3IgPSBmbG9hdDQodV9jb2xvcl9TMV9jMC54eXogKiB3YXZlX2FscGhhLCB3YXZlX2FscGhhKTsKCWZyYWdDb2xvcl9TMV9jMCA9IG1peCh3YXZlX2NvbG9yLCBmbG9hdDQoMS4wKSwgZmxvYXQ0KHNwYXJrbGUpKTsKfQpoYWxmNCBydW50aW1lX3NoYWRlcl9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzBfaW5Db2xvciA9IF9pbnB1dDsKCWZsb2F0MiBfdG1wXzFfY29vcmRzID0gdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CglmbHV0dGVyX0ZyYWdDb29yZF9TMV9jMCA9IGZsb2F0NChfdG1wXzFfY29vcmRzLCAwLjAsIDAuMCk7CglGTFRfbWFpbl9TMV9jMCgpOwoJcmV0dXJuIGhhbGY0KGhhbGY0KGZyYWdDb2xvcl9TMV9jMCkpOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gcnVudGltZV9zaGFkZXJfUzFfYzAoX2lucHV0KTsKfQpoYWxmNCBUZXh0dXJlRWZmZWN0X1MyX2MwX2MwX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzIsIHZUcmFuc2Zvcm1lZENvb3Jkc182X1MwKS4wMDByOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMl9jMF9jMChoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gVGV4dHVyZUVmZmVjdF9TMl9jMF9jMF9jMChfaW5wdXQpOwp9CmhhbGY0IERldmljZVNwYWNlX1MyX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBNYXRyaXhFZmZlY3RfUzJfYzBfYzAoX2lucHV0KTsKfQpoYWxmNCBSZWN0X1MyX2MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMl9pbkNvbG9yID0gX2lucHV0OwoJaGFsZiBjb3ZlcmFnZTsKCWlmIChpbnQoMSkgPT0ga0ZpbGxCV19TMl9jMV9jMCB8fCBpbnQoMSkgPT0ga0ludmVyc2VGaWxsQldfUzJfYzFfYzApIAoJewoJCWNvdmVyYWdlID0gaGFsZihhbGwoZ3JlYXRlclRoYW4oZmxvYXQ0KHNrX0ZyYWdDb29yZC54eSwgdXJlY3RVbmlmb3JtX1MyX2MxX2MwLnp3KSwgZmxvYXQ0KHVyZWN0VW5pZm9ybV9TMl9jMV9jMC54eSwgc2tfRnJhZ0Nvb3JkLnh5KSkpKTsKCX0KCWVsc2UgCgl7CgkJaGFsZjQgZGlzdHM0ID0gc2F0dXJhdGUoaGFsZjQoMS4wLCAxLjAsIC0xLjAsIC0xLjApICogaGFsZjQoc2tfRnJhZ0Nvb3JkLnh5eHkgLSB1cmVjdFVuaWZvcm1fUzJfYzFfYzApKTsKCQloYWxmMiBkaXN0czIgPSAoZGlzdHM0Lnh5ICsgZGlzdHM0Lnp3KSAtIDEuMDsKCQljb3ZlcmFnZSA9IGRpc3RzMi54ICogZGlzdHMyLnk7Cgl9CglpZiAoaW50KDEpID09IGtJbnZlcnNlRmlsbEJXX1MyX2MxX2MwIHx8IGludCgxKSA9PSBrSW52ZXJzZUZpbGxBQV9TMl9jMV9jMCkgCgl7CgkJY292ZXJhZ2UgPSAxLjAgLSBjb3ZlcmFnZTsKCX0KCXJldHVybiBoYWxmNChoYWxmNChjb3ZlcmFnZSkpOwp9CmhhbGY0IEJsZW5kX1MyX2MxKGhhbGY0IF9zcmMsIGhhbGY0IF9kc3QpIAp7CglyZXR1cm4gYmxlbmRfbW9kdWxhdGUoUmVjdF9TMl9jMV9jMChfc3JjKSwgX3NyYyk7Cn0KaGFsZjQgQmxlbmRfUzIoaGFsZjQgX3NyYywgaGFsZjQgX2RzdCkgCnsKCXJldHVybiBibGVuZF9kc3RfaW4oRGV2aWNlU3BhY2VfUzJfYzAoX3NyYyksIEJsZW5kX1MyX2MxKF9zcmMsIF9kc3QpKTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJZmxvYXQgY292ZXJhZ2UgPSB2Y292ZXJhZ2VfUzA7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGNvdmVyYWdlKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IE1hdHJpeEVmZmVjdF9TMShvdXRwdXRDb2xvcl9TMCk7CgloYWxmNCBvdXRwdXRfUzI7CglvdXRwdXRfUzIgPSBCbGVuZF9TMihvdXRwdXRDb3ZlcmFnZV9TMCwgaGFsZjQoMSkpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dF9TMjsKCX0KfQoAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAAcG9zaXRpb24IAAAAY292ZXJhZ2UFAAAAY29sb3IAAAAKAAAAbG9jYWxDb29yZAAAAAAAAA==","FIMAAAYAAEHAAAARC4EAAAQWBQAAAAAAAAAQAAAAIBCAAAEYAEAAAAAQAAAABAEQAEAAAAA":"DAAAAExTS1OtAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgaW5Qb3NpdGlvbjsKaW4gaGFsZjQgaW5Db2xvcjsKaW4gaGFsZjMgaW5TaGFkb3dQYXJhbXM7Cm5vcGVyc3BlY3RpdmUgb3V0IGhhbGYzIHZpblNoYWRvd1BhcmFtc19TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFJSZWN0U2hhZG93Cgl2aW5TaGFkb3dQYXJhbXNfUzAgPSBpblNoYWRvd1BhcmFtczsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247Cglza19Qb3NpdGlvbiA9IF90bXBfMF9pblBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAAAFwCAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwpub3BlcnNwZWN0aXZlIGluIGhhbGYzIHZpblNoYWRvd1BhcmFtc19TMDsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFJSZWN0U2hhZG93CgloYWxmMyBzaGFkb3dQYXJhbXM7CglzaGFkb3dQYXJhbXMgPSB2aW5TaGFkb3dQYXJhbXNfUzA7CgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmluQ29sb3JfUzA7CgloYWxmIGQgPSBsZW5ndGgoc2hhZG93UGFyYW1zLnh5KTsKCWZsb2F0MiB1diA9IGZsb2F0MihzaGFkb3dQYXJhbXMueiAqICgxLjAgLSBkKSwgMC41KTsKCWhhbGYgZmFjdG9yID0gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB1dikuMDAwci5hOwoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChmYWN0b3IpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADgAAAGluU2hhZG93UGFyYW1zAAAAAAAA","G2QACAAAABAAADAAAIOAAAAADIIAAIRODAAP577774DSAIAA737777YBAAAAAAAAAAADAAYAAAACAAAAAAACCAYAAA":"DAAAAExTS1PqAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgcG9zaXRpb247CmluIGZsb2F0IGNvdmVyYWdlOwppbiBoYWxmNCBjb2xvcjsKaW4gZmxvYXQ0IGdlb21TdWJzZXQ7Cm5vcGVyc3BlY3RpdmUgb3V0IGhhbGY0IHZjb2xvcl9TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQgdmNvdmVyYWdlX1MwOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDQgdmdlb21TdWJzZXRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQyIHBvc2l0aW9uID0gcG9zaXRpb24ueHk7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCXZjb3ZlcmFnZV9TMCA9IGNvdmVyYWdlOwoJdmdlb21TdWJzZXRfUzAgPSBnZW9tU3Vic2V0OwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAQAAAKQCAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQgdmNvdmVyYWdlX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0NCB2Z2VvbVN1YnNldF9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWZsb2F0IGNvdmVyYWdlID0gdmNvdmVyYWdlX1MwOwoJZmxvYXQ0IGdlb1N1YnNldDsKCWdlb1N1YnNldCA9IHZnZW9tU3Vic2V0X1MwOwoJZmxvYXQ0IGRpc3RzNCA9IHNhdHVyYXRlKGZsb2F0NCgxLCAxLCAtMSwgLTEpICogKHNrX0ZyYWdDb29yZC54eXh5IC0gZ2VvU3Vic2V0KSk7CglmbG9hdDIgZGlzdHMyID0gZGlzdHM0Lnh5ICsgZGlzdHM0Lnp3IC0gMTsKCWNvdmVyYWdlID0gbWluKGNvdmVyYWdlLCBkaXN0czIueCAqIGRpc3RzMi55KTsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoY292ZXJhZ2UpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAAcG9zaXRpb24IAAAAY292ZXJhZ2UFAAAAY29sb3IAAAAKAAAAZ2VvbVN1YnNldAAAAAAAAA==","AYQA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAAAAB3QA6AAAEAAAAAAAMAAPEAEAAABAAAAAABTAAAAAAACAAAAAEBSAAAA":"DAAAAExTS1MlAgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0NCB1bG9jYWxNYXRyaXhfUzA7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiBmbG9hdDQgaW5DaXJjbGVFZGdlOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIENpcmNsZUdlb21ldHJ5UHJvY2Vzc29yCgl2aW5DaXJjbGVFZGdlX1MwID0gaW5DaXJjbGVFZGdlOwoJdmluQ29sb3JfUzAgPSBpbkNvbG9yOwoJZmxvYXQyIF90bXBfMF9pblBvc2l0aW9uID0gaW5Qb3NpdGlvbjsKCWZsb2F0MiBfdG1wXzFfaW5Qb3NpdGlvbiA9IHVsb2NhbE1hdHJpeF9TMC54eiAqIGluUG9zaXRpb24gKyB1bG9jYWxNYXRyaXhfUzAueXc7Cglza19Qb3NpdGlvbiA9IF90bXBfMF9pblBvc2l0aW9uLnh5MDE7Cn0KAAAAAQAAAHcFAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CnVuaWZvcm0gZmxvYXQ0IHVpbm5lclJlY3RfUzI7CnVuaWZvcm0gaGFsZjIgdXJhZGl1c1BsdXNIYWxmX1MyOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0NCB2aW5DaXJjbGVFZGdlX1MwOwpub3BlcnNwZWN0aXZlIGluIGhhbGY0IHZpbkNvbG9yX1MwOwpoYWxmNCBDaXJjdWxhclJSZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCWZsb2F0MiBkeHkwID0gdWlubmVyUmVjdF9TMS5MVCAtIHNrX0ZyYWdDb29yZC54eTsKCWZsb2F0MiBkeHkxID0gc2tfRnJhZ0Nvb3JkLnh5IC0gdWlubmVyUmVjdF9TMS5SQjsKCWZsb2F0MiBkeHkgPSBtYXgobWF4KGR4eTAsIGR4eTEpLCAwLjApOwoJaGFsZiBhbHBoYSA9IGhhbGYoc2F0dXJhdGUodXJhZGl1c1BsdXNIYWxmX1MxLnggLSBsZW5ndGgoZHh5KSkpOwoJYWxwaGEgPSAxLjAgLSBhbHBoYTsKCXJldHVybiBfaW5wdXQgKiBhbHBoYTsKfQpoYWxmNCBDaXJjdWxhclJSZWN0X1MyKGhhbGY0IF9pbnB1dCkgCnsKCWZsb2F0MiBkeHkwID0gdWlubmVyUmVjdF9TMi5MVCAtIHNrX0ZyYWdDb29yZC54eTsKCWZsb2F0MiBkeHkxID0gc2tfRnJhZ0Nvb3JkLnh5IC0gdWlubmVyUmVjdF9TMi5SQjsKCWZsb2F0MiBkeHkgPSBtYXgobWF4KGR4eTAsIGR4eTEpLCAwLjApOwoJaGFsZiBhbHBoYSA9IGhhbGYoc2F0dXJhdGUodXJhZGl1c1BsdXNIYWxmX1MyLnggLSBsZW5ndGgoZHh5KSkpOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQ0IGNpcmNsZUVkZ2U7CgljaXJjbGVFZGdlID0gdmluQ2lyY2xlRWRnZV9TMDsKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWZsb2F0IGQgPSBsZW5ndGgoY2lyY2xlRWRnZS54eSk7CgloYWxmIGRpc3RhbmNlVG9PdXRlckVkZ2UgPSBoYWxmKGNpcmNsZUVkZ2UueiAqICgxLjAgLSBkKSk7CgloYWxmIGVkZ2VBbHBoYSA9IHNhdHVyYXRlKGRpc3RhbmNlVG9PdXRlckVkZ2UpOwoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChlZGdlQWxwaGEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQ2lyY3VsYXJSUmVjdF9TMShvdXRwdXRDb3ZlcmFnZV9TMCk7CgloYWxmNCBvdXRwdXRfUzI7CglvdXRwdXRfUzIgPSBDaXJjdWxhclJSZWN0X1MyKG91dHB1dF9TMSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzI7Cgl9Cn0KAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACgAAAGluUG9zaXRpb24AAAcAAABpbkNvbG9yAAwAAABpbkNpcmNsZUVkZ2UAAAAA","GZIACAAAABQAAGAAAQ4AAAAAGQQAARC4GAAAIOCAAD6P7777777777YDAAAAAAAAAAAJQBBYGQ467YIAAAAAAQAAAAAMACTRNBZN5QYBAAAAAAAAAAAIAALIAAAAB4FJEIEKOAAAAAMAAAAAEAHQAACAAAAAAYCFPSVARQRJAAAAABQAAAAAAAAAAA4JAPAAACAAAAAAACABSAAAAAAACAAAAAEBSAAA":"DAAAAExTS1M7AgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQgY292ZXJhZ2U7CmluIGhhbGY0IGNvbG9yOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdCB2Y292ZXJhZ2VfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDIgcG9zaXRpb24gPSBwb3NpdGlvbi54eTsKCXZjb2xvcl9TMCA9IGNvbG9yOwoJdmNvdmVyYWdlX1MwID0gY292ZXJhZ2U7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgABAAAANCEAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQpmbG9hdDQgZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzA7CmZsb2F0NCBmcmFnQ29sb3JfUzFfYzA7CmZsb2F0IHVfYWxwaGFfUzFfYzA7CmZsb2F0IHVfc3BhcmtsZV9hbHBoYV9TMV9jMDsKZmxvYXQgdV9ibHVyX1MxX2MwOwpmbG9hdCB1X3JhZGl1c19zY2FsZV9TMV9jMDsKY29uc3QgaW50IGtGaWxsQldfUzJfYzAgPSAwOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQldfUzJfYzAgPSAyOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQUFfUzJfYzAgPSAzOwp1bmlmb3JtIGZsb2F0NCB1X2NvbG9yX1MxX2MwOwp1bmlmb3JtIGZsb2F0NCB1X2NvbXBvc2l0ZV8xX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NlbnRlcl9TMV9jMDsKdW5pZm9ybSBmbG9hdCB1X21heF9yYWRpdXNfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcmVzb2x1dGlvbl9zY2FsZV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9ub2lzZV9zY2FsZV9TMV9jMDsKdW5pZm9ybSBmbG9hdCB1X25vaXNlX3BoYXNlX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NpcmNsZTFfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2lyY2xlMl9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jaXJjbGUzX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3JvdGF0aW9uMV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yb3RhdGlvbjJfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcm90YXRpb24zX1MxX2MwOwp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CnVuaWZvcm0gZmxvYXQ0IHVyZWN0VW5pZm9ybV9TMl9jMDsKdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMl9jMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzJfYzE7Cm5vcGVyc3BlY3RpdmUgaW4gaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0IHZjb3ZlcmFnZV9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CmZsb2F0MiBGTFRfZmx1dHRlcl9sb2NhbF9GbHV0dGVyRnJhZ0Nvb3JkX1MxX2MwKCk7CmZsb2F0MngyIEZMVF9mbHV0dGVyX2xvY2FsX3JvdGF0ZTJkX1MxX2MwKGZsb2F0MiByYWQpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCBibHVyKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAoZmxvYXQyIHJlc29sdXRpb24sIGlub3V0IGZsb2F0MiBwLCBmbG9hdDIgeHksIGZsb2F0MiByb3RhdGlvbiwgZmxvYXQgY2VsbF9kaWFtZXRlcik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3R1cmJ1bGVuY2VfUzFfYzAoZmxvYXQyIHV2KTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9yaW5nX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IHRoaWNrbmVzcywgZmxvYXQgYmx1cik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RyaWFuZ2xlX25vaXNlX1MxX2MwKGlub3V0IGZsb2F0MiBuKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKGZsb2F0IHYsIGZsb2F0IGwsIGZsb2F0IGgpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zcGFya2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQgdCk7CnZvaWQgRkxUX21haW5fUzFfYzAoKTsKZmxvYXQyIEZMVF9mbHV0dGVyX2xvY2FsX0ZsdXR0ZXJGcmFnQ29vcmRfUzFfYzAoKSAKewoJcmV0dXJuIGZsdXR0ZXJfRnJhZ0Nvb3JkX1MxX2MwLnh5Owp9CmZsb2F0MngyIEZMVF9mbHV0dGVyX2xvY2FsX3JvdGF0ZTJkX1MxX2MwKGZsb2F0MiByYWQpIAp7CglyZXR1cm4gZmxvYXQyeDIocmFkLngsIC1yYWQueSwgcmFkLnksIHJhZC54KTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCBibHVyKSAKewoJZmxvYXQgYmx1cl9oYWxmID0gYmx1ciAqIDAuNTsKCWZsb2F0IGQgPSBkaXN0YW5jZSh1diwgeHkpOwoJcmV0dXJuIDEuMCAtIHNtb290aHN0ZXAoMS4wIC0gYmx1cl9oYWxmLCAxLjAgKyBibHVyX2hhbGYsIGQgLyByYWRpdXMpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKGZsb2F0MiByZXNvbHV0aW9uLCBpbm91dCBmbG9hdDIgcCwgZmxvYXQyIHh5LCBmbG9hdDIgcm90YXRpb24sIGZsb2F0IGNlbGxfZGlhbWV0ZXIpIAp7CglmbG9hdDIgcGFyYW0gPSByb3RhdGlvbjsKCXAgPSBGTFRfZmx1dHRlcl9sb2NhbF9yb3RhdGUyZF9TMV9jMChwYXJhbSkgKiAoeHkgLSBwKSArIHh5OwoJcCA9IG1vZChwLCBmbG9hdDIoY2VsbF9kaWFtZXRlcikpIC8gcmVzb2x1dGlvbjsKCWZsb2F0IGNlbGxfdXYgPSAoY2VsbF9kaWFtZXRlciAvIHJlc29sdXRpb24ueSkgKiAwLjU7CglmbG9hdCByID0gMC42NSAqIGNlbGxfdXY7CglmbG9hdDIgcGFyYW1fMSA9IHA7CglmbG9hdDIgcGFyYW1fMiA9IGZsb2F0MihjZWxsX3V2KTsKCWZsb2F0IHBhcmFtXzMgPSByOwoJZmxvYXQgcGFyYW1fNCA9IHIgKiA1MC4wOwoJcmV0dXJuIEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMsIHBhcmFtXzQpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3R1cmJ1bGVuY2VfUzFfYzAoZmxvYXQyIHV2KSAKewoJZmxvYXQyIHV2X3NjYWxlID0gdXYgKiBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbSA9IGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtXzEgPSB1dl9zY2FsZTsKCWZsb2F0MiBwYXJhbV8yID0gdV9jaXJjbGUxX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzMgPSB1X3JvdGF0aW9uMV9TMV9jMDsKCWZsb2F0IHBhcmFtXzQgPSAwLjE3OwoJZmxvYXQgXzMxOSA9IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKHBhcmFtLCBwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zLCBwYXJhbV80KTsKCWZsb2F0IGcxID0gXzMxOTsKCWZsb2F0MiBwYXJhbV81ID0gZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW1fNiA9IHV2X3NjYWxlOwoJZmxvYXQyIHBhcmFtXzcgPSB1X2NpcmNsZTJfUzFfYzA7CglmbG9hdDIgcGFyYW1fOCA9IHVfcm90YXRpb24yX1MxX2MwOwoJZmxvYXQgcGFyYW1fOSA9IDAuMjsKCWZsb2F0IF8zMzEgPSBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChwYXJhbV81LCBwYXJhbV82LCBwYXJhbV83LCBwYXJhbV84LCBwYXJhbV85KTsKCWZsb2F0IGcyID0gXzMzMTsKCWZsb2F0MiBwYXJhbV8xMCA9IGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtXzExID0gdXZfc2NhbGU7CglmbG9hdDIgcGFyYW1fMTIgPSB1X2NpcmNsZTNfUzFfYzA7CglmbG9hdDIgcGFyYW1fMTMgPSB1X3JvdGF0aW9uM19TMV9jMDsKCWZsb2F0IHBhcmFtXzE0ID0gMC4yNzU7CglmbG9hdCBfMzQ0ID0gRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAocGFyYW1fMTAsIHBhcmFtXzExLCBwYXJhbV8xMiwgcGFyYW1fMTMsIHBhcmFtXzE0KTsKCWZsb2F0IGczID0gXzM0NDsKCWZsb2F0IHYgPSAoKGcxICogZzEgKyBnMikgLSBnMykgKiAwLjU7CglyZXR1cm4gY2xhbXAoMC40NSArIDAuOCAqIHYsIDAuMCwgMS4wKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X3JpbmdfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgdGhpY2tuZXNzLCBmbG9hdCBibHVyKSAKewoJZmxvYXQyIHBhcmFtID0gdXY7CglmbG9hdDIgcGFyYW1fMSA9IHh5OwoJZmxvYXQgcGFyYW1fMiA9IHJhZGl1cyArIHRoaWNrbmVzczsKCWZsb2F0IHBhcmFtXzMgPSBibHVyOwoJZmxvYXQgY2lyY2xlX291dGVyID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW0sIHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMpOwoJZmxvYXQyIHBhcmFtXzQgPSB1djsKCWZsb2F0MiBwYXJhbV81ID0geHk7CglmbG9hdCBwYXJhbV82ID0gbWF4KHJhZGl1cyAtIHRoaWNrbmVzcywgMC4wKTsKCWZsb2F0IHBhcmFtXzcgPSBibHVyOwoJZmxvYXQgY2lyY2xlX2lubmVyID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW1fNCwgcGFyYW1fNSwgcGFyYW1fNiwgcGFyYW1fNyk7CglyZXR1cm4gY2xhbXAoY2lyY2xlX291dGVyIC0gY2lyY2xlX2lubmVyLCAwLjAsIDEuMCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHJpYW5nbGVfbm9pc2VfUzFfYzAoaW5vdXQgZmxvYXQyIG4pIAp7CgluID0gZnJhY3QobiAqIGZsb2F0Mig1LjM5ODcsIDUuNDQyMSkpOwoJbiArPSBmbG9hdDIoZG90KG4ueXgsIG4gKyBmbG9hdDIoMjEuNTM1MSwgMTQuMzEzNykpKTsKCWZsb2F0IHh5ID0gbi54ICogbi55OwoJcmV0dXJuIChmcmFjdCh4eSAqIDk1LjQzMDcpICsgZnJhY3QoeHkgKiA3NS4wNDk2MSkpIC0gMS4wOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChmbG9hdCB2LCBmbG9hdCBsLCBmbG9hdCBoKSAKewoJcmV0dXJuIHN0ZXAobCwgdikgKiAoMS4wIC0gc3RlcChoLCB2KSk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc3BhcmtsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0IHQpIAp7CglmbG9hdDIgcGFyYW0gPSB1djsKCWZsb2F0IF8yNDIgPSBGTFRfZmx1dHRlcl9sb2NhbF90cmlhbmdsZV9ub2lzZV9TMV9jMChwYXJhbSk7CglmbG9hdCBuID0gXzI0MjsKCWZsb2F0IHBhcmFtXzEgPSBuOwoJZmxvYXQgcGFyYW1fMiA9IDAuMDsKCWZsb2F0IHBhcmFtXzMgPSAwLjA1OwoJZmxvYXQgcyA9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zKTsKCWZsb2F0IHBhcmFtXzQgPSBuICsgc2luKDMuMTQxNTkyNzQgKiAodCArIDAuMzUpKTsKCWZsb2F0IHBhcmFtXzUgPSAwLjE7CglmbG9hdCBwYXJhbV82ID0gMC4xNTsKCXMgKz0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzQsIHBhcmFtXzUsIHBhcmFtXzYpOwoJZmxvYXQgcGFyYW1fNyA9IG4gKyBzaW4oMy4xNDE1OTI3NCAqICh0ICsgMC43KSk7CglmbG9hdCBwYXJhbV84ID0gMC4yOwoJZmxvYXQgcGFyYW1fOSA9IDAuMjU7CglzICs9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV83LCBwYXJhbV84LCBwYXJhbV85KTsKCWZsb2F0IHBhcmFtXzEwID0gbiArIHNpbigzLjE0MTU5Mjc0ICogKHQgKyAxLjA1KSk7CglmbG9hdCBwYXJhbV8xMSA9IDAuMzsKCWZsb2F0IHBhcmFtXzEyID0gMC4zNTsKCXMgKz0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzEwLCBwYXJhbV8xMSwgcGFyYW1fMTIpOwoJcmV0dXJuIGNsYW1wKHMsIDAuMCwgMS4wKSAqIDAuNTU7Cn0Kdm9pZCBGTFRfbWFpbl9TMV9jMCgpIAp7Cgl1X2FscGhhX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC54OwoJdV9zcGFya2xlX2FscGhhX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC55OwoJdV9ibHVyX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC56OwoJdV9yYWRpdXNfc2NhbGVfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLnc7CglmbG9hdDIgcCA9IEZMVF9mbHV0dGVyX2xvY2FsX0ZsdXR0ZXJGcmFnQ29vcmRfUzFfYzAoKTsKCWZsb2F0MiB1dl8xID0gcCAqIHVfcmVzb2x1dGlvbl9zY2FsZV9TMV9jMDsKCWZsb2F0MiBkZW5zaXR5X3V2ID0gdXZfMSAtIG1vZChwLCB1X25vaXNlX3NjYWxlX1MxX2MwKTsKCWZsb2F0IHJhZGl1cyA9IHVfbWF4X3JhZGl1c19TMV9jMCAqIHVfcmFkaXVzX3NjYWxlX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzEzID0gdXZfMTsKCWZsb2F0IHR1cmJ1bGVuY2UgPSBGTFRfZmx1dHRlcl9sb2NhbF90dXJidWxlbmNlX1MxX2MwKHBhcmFtXzEzKTsKCWZsb2F0MiBwYXJhbV8xNCA9IHA7CglmbG9hdDIgcGFyYW1fMTUgPSB1X2NlbnRlcl9TMV9jMDsKCWZsb2F0IHBhcmFtXzE2ID0gcmFkaXVzOwoJZmxvYXQgcGFyYW1fMTcgPSAwLjA1ICogdV9tYXhfcmFkaXVzX1MxX2MwOwoJZmxvYXQgcGFyYW1fMTggPSB1X2JsdXJfUzFfYzA7CglmbG9hdCByaW5nID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9yaW5nX1MxX2MwKHBhcmFtXzE0LCBwYXJhbV8xNSwgcGFyYW1fMTYsIHBhcmFtXzE3LCBwYXJhbV8xOCk7CglmbG9hdDIgcGFyYW1fMTkgPSBkZW5zaXR5X3V2OwoJZmxvYXQgcGFyYW1fMjAgPSB1X25vaXNlX3BoYXNlX1MxX2MwOwoJZmxvYXQgc3BhcmtsZSA9ICgoRkxUX2ZsdXR0ZXJfbG9jYWxfc3BhcmtsZV9TMV9jMChwYXJhbV8xOSwgcGFyYW1fMjApICogcmluZykgKiB0dXJidWxlbmNlKSAqIHVfc3BhcmtsZV9hbHBoYV9TMV9jMDsKCWZsb2F0MiBwYXJhbV8yMSA9IHA7CglmbG9hdDIgcGFyYW1fMjIgPSB1X2NlbnRlcl9TMV9jMDsKCWZsb2F0IHBhcmFtXzIzID0gcmFkaXVzOwoJZmxvYXQgcGFyYW1fMjQgPSB1X2JsdXJfUzFfYzA7CglmbG9hdCB3YXZlX2FscGhhID0gKEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtXzIxLCBwYXJhbV8yMiwgcGFyYW1fMjMsIHBhcmFtXzI0KSAqIHVfYWxwaGFfUzFfYzApICogdV9jb2xvcl9TMV9jMC53OwoJZmxvYXQ0IHdhdmVfY29sb3IgPSBmbG9hdDQodV9jb2xvcl9TMV9jMC54eXogKiB3YXZlX2FscGhhLCB3YXZlX2FscGhhKTsKCWZyYWdDb2xvcl9TMV9jMCA9IG1peCh3YXZlX2NvbG9yLCBmbG9hdDQoMS4wKSwgZmxvYXQ0KHNwYXJrbGUpKTsKfQpoYWxmNCBydW50aW1lX3NoYWRlcl9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzBfaW5Db2xvciA9IF9pbnB1dDsKCWZsb2F0MiBfdG1wXzFfY29vcmRzID0gdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CglmbHV0dGVyX0ZyYWdDb29yZF9TMV9jMCA9IGZsb2F0NChfdG1wXzFfY29vcmRzLCAwLjAsIDAuMCk7CglGTFRfbWFpbl9TMV9jMCgpOwoJcmV0dXJuIGhhbGY0KGhhbGY0KGZyYWdDb2xvcl9TMV9jMCkpOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gcnVudGltZV9zaGFkZXJfUzFfYzAoX2lucHV0KTsKfQpoYWxmNCBSZWN0X1MyX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMl9pbkNvbG9yID0gX2lucHV0OwoJaGFsZiBjb3ZlcmFnZTsKCWlmIChpbnQoMSkgPT0ga0ZpbGxCV19TMl9jMCB8fCBpbnQoMSkgPT0ga0ludmVyc2VGaWxsQldfUzJfYzApIAoJewoJCWNvdmVyYWdlID0gaGFsZihhbGwoZ3JlYXRlclRoYW4oZmxvYXQ0KHNrX0ZyYWdDb29yZC54eSwgdXJlY3RVbmlmb3JtX1MyX2MwLnp3KSwgZmxvYXQ0KHVyZWN0VW5pZm9ybV9TMl9jMC54eSwgc2tfRnJhZ0Nvb3JkLnh5KSkpKTsKCX0KCWVsc2UgCgl7CgkJaGFsZjQgZGlzdHM0ID0gc2F0dXJhdGUoaGFsZjQoMS4wLCAxLjAsIC0xLjAsIC0xLjApICogaGFsZjQoc2tfRnJhZ0Nvb3JkLnh5eHkgLSB1cmVjdFVuaWZvcm1fUzJfYzApKTsKCQloYWxmMiBkaXN0czIgPSAoZGlzdHM0Lnh5ICsgZGlzdHM0Lnp3KSAtIDEuMDsKCQljb3ZlcmFnZSA9IGRpc3RzMi54ICogZGlzdHMyLnk7Cgl9CglpZiAoaW50KDEpID09IGtJbnZlcnNlRmlsbEJXX1MyX2MwIHx8IGludCgxKSA9PSBrSW52ZXJzZUZpbGxBQV9TMl9jMCkgCgl7CgkJY292ZXJhZ2UgPSAxLjAgLSBjb3ZlcmFnZTsKCX0KCXJldHVybiBoYWxmNChoYWxmNChjb3ZlcmFnZSkpOwp9CmhhbGY0IENpcmN1bGFyUlJlY3RfUzJfYzEoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MyX2MxLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MyX2MxLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CgloYWxmIGFscGhhID0gaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzJfYzEueCAtIGxlbmd0aChkeHkpKSk7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0KaGFsZjQgQmxlbmRfUzIoaGFsZjQgX3NyYywgaGFsZjQgX2RzdCkgCnsKCXJldHVybiBibGVuZF9tb2R1bGF0ZShSZWN0X1MyX2MwKF9zcmMpLCBDaXJjdWxhclJSZWN0X1MyX2MxKF9zcmMpKTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJZmxvYXQgY292ZXJhZ2UgPSB2Y292ZXJhZ2VfUzA7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGNvdmVyYWdlKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IE1hdHJpeEVmZmVjdF9TMShvdXRwdXRDb2xvcl9TMCk7CgloYWxmNCBvdXRwdXRfUzI7CglvdXRwdXRfUzIgPSBCbGVuZF9TMihvdXRwdXRDb3ZlcmFnZV9TMCwgaGFsZjQoMSkpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dF9TMjsKCX0KfQoBAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAgAAABwb3NpdGlvbggAAABjb3ZlcmFnZQUAAABjb2xvcgAAAAoAAABsb2NhbENvb3JkAAAAAAAA","GZIACAAAABQAAGAAAQ4AAAAAGQQAARC4GAAAIOCAAD6P7777777777YDAAAAAAAAAAAJQBBYGQ467YIAAAAAAQAAAAAMACTRNBZN5QYBAAAAAAAAAAAIAA4IAEAAACAAAAAABGABAAAAAEAAAAAIBEABAA":"DAAAAExTS1M7AgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQgY292ZXJhZ2U7CmluIGhhbGY0IGNvbG9yOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdCB2Y292ZXJhZ2VfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDIgcG9zaXRpb24gPSBwb3NpdGlvbi54eTsKCXZjb2xvcl9TMCA9IGNvbG9yOwoJdmNvdmVyYWdlX1MwID0gY292ZXJhZ2U7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgABAAAAEh4AACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQpmbG9hdDQgZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzA7CmZsb2F0NCBmcmFnQ29sb3JfUzFfYzA7CmZsb2F0IHVfYWxwaGFfUzFfYzA7CmZsb2F0IHVfc3BhcmtsZV9hbHBoYV9TMV9jMDsKZmxvYXQgdV9ibHVyX1MxX2MwOwpmbG9hdCB1X3JhZGl1c19zY2FsZV9TMV9jMDsKdW5pZm9ybSBmbG9hdDQgdV9jb2xvcl9TMV9jMDsKdW5pZm9ybSBmbG9hdDQgdV9jb21wb3NpdGVfMV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jZW50ZXJfUzFfYzA7CnVuaWZvcm0gZmxvYXQgdV9tYXhfcmFkaXVzX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3Jlc29sdXRpb25fc2NhbGVfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfbm9pc2Vfc2NhbGVfUzFfYzA7CnVuaWZvcm0gZmxvYXQgdV9ub2lzZV9waGFzZV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jaXJjbGUxX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NpcmNsZTJfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2lyY2xlM19TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yb3RhdGlvbjFfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcm90YXRpb24yX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3JvdGF0aW9uM19TMV9jMDsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxOwp1bmlmb3JtIGZsb2F0NCB1aW5uZXJSZWN0X1MyOwp1bmlmb3JtIGhhbGYyIHVyYWRpdXNQbHVzSGFsZl9TMjsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQgdmNvdmVyYWdlX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKZmxvYXQyIEZMVF9mbHV0dGVyX2xvY2FsX0ZsdXR0ZXJGcmFnQ29vcmRfUzFfYzAoKTsKZmxvYXQyeDIgRkxUX2ZsdXR0ZXJfbG9jYWxfcm90YXRlMmRfUzFfYzAoZmxvYXQyIHJhZCk7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IGJsdXIpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChmbG9hdDIgcmVzb2x1dGlvbiwgaW5vdXQgZmxvYXQyIHAsIGZsb2F0MiB4eSwgZmxvYXQyIHJvdGF0aW9uLCBmbG9hdCBjZWxsX2RpYW1ldGVyKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHVyYnVsZW5jZV9TMV9jMChmbG9hdDIgdXYpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X3JpbmdfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgdGhpY2tuZXNzLCBmbG9hdCBibHVyKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHJpYW5nbGVfbm9pc2VfUzFfYzAoaW5vdXQgZmxvYXQyIG4pOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAoZmxvYXQgdiwgZmxvYXQgbCwgZmxvYXQgaCk7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NwYXJrbGVfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdCB0KTsKdm9pZCBGTFRfbWFpbl9TMV9jMCgpOwpmbG9hdDIgRkxUX2ZsdXR0ZXJfbG9jYWxfRmx1dHRlckZyYWdDb29yZF9TMV9jMCgpIAp7CglyZXR1cm4gZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzAueHk7Cn0KZmxvYXQyeDIgRkxUX2ZsdXR0ZXJfbG9jYWxfcm90YXRlMmRfUzFfYzAoZmxvYXQyIHJhZCkgCnsKCXJldHVybiBmbG9hdDJ4MihyYWQueCwgLXJhZC55LCByYWQueSwgcmFkLngpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IGJsdXIpIAp7CglmbG9hdCBibHVyX2hhbGYgPSBibHVyICogMC41OwoJZmxvYXQgZCA9IGRpc3RhbmNlKHV2LCB4eSk7CglyZXR1cm4gMS4wIC0gc21vb3Roc3RlcCgxLjAgLSBibHVyX2hhbGYsIDEuMCArIGJsdXJfaGFsZiwgZCAvIHJhZGl1cyk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAoZmxvYXQyIHJlc29sdXRpb24sIGlub3V0IGZsb2F0MiBwLCBmbG9hdDIgeHksIGZsb2F0MiByb3RhdGlvbiwgZmxvYXQgY2VsbF9kaWFtZXRlcikgCnsKCWZsb2F0MiBwYXJhbSA9IHJvdGF0aW9uOwoJcCA9IEZMVF9mbHV0dGVyX2xvY2FsX3JvdGF0ZTJkX1MxX2MwKHBhcmFtKSAqICh4eSAtIHApICsgeHk7CglwID0gbW9kKHAsIGZsb2F0MihjZWxsX2RpYW1ldGVyKSkgLyByZXNvbHV0aW9uOwoJZmxvYXQgY2VsbF91diA9IChjZWxsX2RpYW1ldGVyIC8gcmVzb2x1dGlvbi55KSAqIDAuNTsKCWZsb2F0IHIgPSAwLjY1ICogY2VsbF91djsKCWZsb2F0MiBwYXJhbV8xID0gcDsKCWZsb2F0MiBwYXJhbV8yID0gZmxvYXQyKGNlbGxfdXYpOwoJZmxvYXQgcGFyYW1fMyA9IHI7CglmbG9hdCBwYXJhbV80ID0gciAqIDUwLjA7CglyZXR1cm4gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW1fMSwgcGFyYW1fMiwgcGFyYW1fMywgcGFyYW1fNCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHVyYnVsZW5jZV9TMV9jMChmbG9hdDIgdXYpIAp7CglmbG9hdDIgdXZfc2NhbGUgPSB1diAqIGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtID0gZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW1fMSA9IHV2X3NjYWxlOwoJZmxvYXQyIHBhcmFtXzIgPSB1X2NpcmNsZTFfUzFfYzA7CglmbG9hdDIgcGFyYW1fMyA9IHVfcm90YXRpb24xX1MxX2MwOwoJZmxvYXQgcGFyYW1fNCA9IDAuMTc7CglmbG9hdCBfMzE5ID0gRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAocGFyYW0sIHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMsIHBhcmFtXzQpOwoJZmxvYXQgZzEgPSBfMzE5OwoJZmxvYXQyIHBhcmFtXzUgPSBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbV82ID0gdXZfc2NhbGU7CglmbG9hdDIgcGFyYW1fNyA9IHVfY2lyY2xlMl9TMV9jMDsKCWZsb2F0MiBwYXJhbV84ID0gdV9yb3RhdGlvbjJfUzFfYzA7CglmbG9hdCBwYXJhbV85ID0gMC4yOwoJZmxvYXQgXzMzMSA9IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKHBhcmFtXzUsIHBhcmFtXzYsIHBhcmFtXzcsIHBhcmFtXzgsIHBhcmFtXzkpOwoJZmxvYXQgZzIgPSBfMzMxOwoJZmxvYXQyIHBhcmFtXzEwID0gZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW1fMTEgPSB1dl9zY2FsZTsKCWZsb2F0MiBwYXJhbV8xMiA9IHVfY2lyY2xlM19TMV9jMDsKCWZsb2F0MiBwYXJhbV8xMyA9IHVfcm90YXRpb24zX1MxX2MwOwoJZmxvYXQgcGFyYW1fMTQgPSAwLjI3NTsKCWZsb2F0IF8zNDQgPSBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChwYXJhbV8xMCwgcGFyYW1fMTEsIHBhcmFtXzEyLCBwYXJhbV8xMywgcGFyYW1fMTQpOwoJZmxvYXQgZzMgPSBfMzQ0OwoJZmxvYXQgdiA9ICgoZzEgKiBnMSArIGcyKSAtIGczKSAqIDAuNTsKCXJldHVybiBjbGFtcCgwLjQ1ICsgMC44ICogdiwgMC4wLCAxLjApOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfcmluZ19TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCB0aGlja25lc3MsIGZsb2F0IGJsdXIpIAp7CglmbG9hdDIgcGFyYW0gPSB1djsKCWZsb2F0MiBwYXJhbV8xID0geHk7CglmbG9hdCBwYXJhbV8yID0gcmFkaXVzICsgdGhpY2tuZXNzOwoJZmxvYXQgcGFyYW1fMyA9IGJsdXI7CglmbG9hdCBjaXJjbGVfb3V0ZXIgPSBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChwYXJhbSwgcGFyYW1fMSwgcGFyYW1fMiwgcGFyYW1fMyk7CglmbG9hdDIgcGFyYW1fNCA9IHV2OwoJZmxvYXQyIHBhcmFtXzUgPSB4eTsKCWZsb2F0IHBhcmFtXzYgPSBtYXgocmFkaXVzIC0gdGhpY2tuZXNzLCAwLjApOwoJZmxvYXQgcGFyYW1fNyA9IGJsdXI7CglmbG9hdCBjaXJjbGVfaW5uZXIgPSBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChwYXJhbV80LCBwYXJhbV81LCBwYXJhbV82LCBwYXJhbV83KTsKCXJldHVybiBjbGFtcChjaXJjbGVfb3V0ZXIgLSBjaXJjbGVfaW5uZXIsIDAuMCwgMS4wKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90cmlhbmdsZV9ub2lzZV9TMV9jMChpbm91dCBmbG9hdDIgbikgCnsKCW4gPSBmcmFjdChuICogZmxvYXQyKDUuMzk4NywgNS40NDIxKSk7CgluICs9IGZsb2F0Mihkb3Qobi55eCwgbiArIGZsb2F0MigyMS41MzUxLCAxNC4zMTM3KSkpOwoJZmxvYXQgeHkgPSBuLnggKiBuLnk7CglyZXR1cm4gKGZyYWN0KHh5ICogOTUuNDMwNykgKyBmcmFjdCh4eSAqIDc1LjA0OTYxKSkgLSAxLjA7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKGZsb2F0IHYsIGZsb2F0IGwsIGZsb2F0IGgpIAp7CglyZXR1cm4gc3RlcChsLCB2KSAqICgxLjAgLSBzdGVwKGgsIHYpKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zcGFya2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQgdCkgCnsKCWZsb2F0MiBwYXJhbSA9IHV2OwoJZmxvYXQgXzI0MiA9IEZMVF9mbHV0dGVyX2xvY2FsX3RyaWFuZ2xlX25vaXNlX1MxX2MwKHBhcmFtKTsKCWZsb2F0IG4gPSBfMjQyOwoJZmxvYXQgcGFyYW1fMSA9IG47CglmbG9hdCBwYXJhbV8yID0gMC4wOwoJZmxvYXQgcGFyYW1fMyA9IDAuMDU7CglmbG9hdCBzID0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMpOwoJZmxvYXQgcGFyYW1fNCA9IG4gKyBzaW4oMy4xNDE1OTI3NCAqICh0ICsgMC4zNSkpOwoJZmxvYXQgcGFyYW1fNSA9IDAuMTsKCWZsb2F0IHBhcmFtXzYgPSAwLjE1OwoJcyArPSBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAocGFyYW1fNCwgcGFyYW1fNSwgcGFyYW1fNik7CglmbG9hdCBwYXJhbV83ID0gbiArIHNpbigzLjE0MTU5Mjc0ICogKHQgKyAwLjcpKTsKCWZsb2F0IHBhcmFtXzggPSAwLjI7CglmbG9hdCBwYXJhbV85ID0gMC4yNTsKCXMgKz0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzcsIHBhcmFtXzgsIHBhcmFtXzkpOwoJZmxvYXQgcGFyYW1fMTAgPSBuICsgc2luKDMuMTQxNTkyNzQgKiAodCArIDEuMDUpKTsKCWZsb2F0IHBhcmFtXzExID0gMC4zOwoJZmxvYXQgcGFyYW1fMTIgPSAwLjM1OwoJcyArPSBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAocGFyYW1fMTAsIHBhcmFtXzExLCBwYXJhbV8xMik7CglyZXR1cm4gY2xhbXAocywgMC4wLCAxLjApICogMC41NTsKfQp2b2lkIEZMVF9tYWluX1MxX2MwKCkgCnsKCXVfYWxwaGFfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLng7Cgl1X3NwYXJrbGVfYWxwaGFfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLnk7Cgl1X2JsdXJfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLno7Cgl1X3JhZGl1c19zY2FsZV9TMV9jMCA9IHVfY29tcG9zaXRlXzFfUzFfYzAudzsKCWZsb2F0MiBwID0gRkxUX2ZsdXR0ZXJfbG9jYWxfRmx1dHRlckZyYWdDb29yZF9TMV9jMCgpOwoJZmxvYXQyIHV2XzEgPSBwICogdV9yZXNvbHV0aW9uX3NjYWxlX1MxX2MwOwoJZmxvYXQyIGRlbnNpdHlfdXYgPSB1dl8xIC0gbW9kKHAsIHVfbm9pc2Vfc2NhbGVfUzFfYzApOwoJZmxvYXQgcmFkaXVzID0gdV9tYXhfcmFkaXVzX1MxX2MwICogdV9yYWRpdXNfc2NhbGVfUzFfYzA7CglmbG9hdDIgcGFyYW1fMTMgPSB1dl8xOwoJZmxvYXQgdHVyYnVsZW5jZSA9IEZMVF9mbHV0dGVyX2xvY2FsX3R1cmJ1bGVuY2VfUzFfYzAocGFyYW1fMTMpOwoJZmxvYXQyIHBhcmFtXzE0ID0gcDsKCWZsb2F0MiBwYXJhbV8xNSA9IHVfY2VudGVyX1MxX2MwOwoJZmxvYXQgcGFyYW1fMTYgPSByYWRpdXM7CglmbG9hdCBwYXJhbV8xNyA9IDAuMDUgKiB1X21heF9yYWRpdXNfUzFfYzA7CglmbG9hdCBwYXJhbV8xOCA9IHVfYmx1cl9TMV9jMDsKCWZsb2F0IHJpbmcgPSBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X3JpbmdfUzFfYzAocGFyYW1fMTQsIHBhcmFtXzE1LCBwYXJhbV8xNiwgcGFyYW1fMTcsIHBhcmFtXzE4KTsKCWZsb2F0MiBwYXJhbV8xOSA9IGRlbnNpdHlfdXY7CglmbG9hdCBwYXJhbV8yMCA9IHVfbm9pc2VfcGhhc2VfUzFfYzA7CglmbG9hdCBzcGFya2xlID0gKChGTFRfZmx1dHRlcl9sb2NhbF9zcGFya2xlX1MxX2MwKHBhcmFtXzE5LCBwYXJhbV8yMCkgKiByaW5nKSAqIHR1cmJ1bGVuY2UpICogdV9zcGFya2xlX2FscGhhX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzIxID0gcDsKCWZsb2F0MiBwYXJhbV8yMiA9IHVfY2VudGVyX1MxX2MwOwoJZmxvYXQgcGFyYW1fMjMgPSByYWRpdXM7CglmbG9hdCBwYXJhbV8yNCA9IHVfYmx1cl9TMV9jMDsKCWZsb2F0IHdhdmVfYWxwaGEgPSAoRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW1fMjEsIHBhcmFtXzIyLCBwYXJhbV8yMywgcGFyYW1fMjQpICogdV9hbHBoYV9TMV9jMCkgKiB1X2NvbG9yX1MxX2MwLnc7CglmbG9hdDQgd2F2ZV9jb2xvciA9IGZsb2F0NCh1X2NvbG9yX1MxX2MwLnh5eiAqIHdhdmVfYWxwaGEsIHdhdmVfYWxwaGEpOwoJZnJhZ0NvbG9yX1MxX2MwID0gbWl4KHdhdmVfY29sb3IsIGZsb2F0NCgxLjApLCBmbG9hdDQoc3BhcmtsZSkpOwp9CmhhbGY0IHJ1bnRpbWVfc2hhZGVyX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJZmxvYXQyIF90bXBfMV9jb29yZHMgPSB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKCWZsdXR0ZXJfRnJhZ0Nvb3JkX1MxX2MwID0gZmxvYXQ0KF90bXBfMV9jb29yZHMsIDAuMCwgMC4wKTsKCUZMVF9tYWluX1MxX2MwKCk7CglyZXR1cm4gaGFsZjQoaGFsZjQoZnJhZ0NvbG9yX1MxX2MwKSk7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBydW50aW1lX3NoYWRlcl9TMV9jMChfaW5wdXQpOwp9CmhhbGY0IENpcmN1bGFyUlJlY3RfUzIoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQgZHkwID0gdWlubmVyUmVjdF9TMi5UIC0gc2tfRnJhZ0Nvb3JkLnk7CglmbG9hdDIgZHh5MSA9IHNrX0ZyYWdDb29yZC54eSAtIHVpbm5lclJlY3RfUzIuUkI7CglmbG9hdDIgZHh5ID0gbWF4KGZsb2F0MihkeHkxLngsIG1heChkeTAsIGR4eTEueSkpLCAwLjApOwoJaGFsZiBsZWZ0QWxwaGEgPSBoYWxmKHNhdHVyYXRlKHNrX0ZyYWdDb29yZC54IC0gdWlubmVyUmVjdF9TMi5MKSk7CgloYWxmIGFscGhhID0gbGVmdEFscGhhICogaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzIueCAtIGxlbmd0aChkeHkpKSk7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWZsb2F0IGNvdmVyYWdlID0gdmNvdmVyYWdlX1MwOwoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChjb3ZlcmFnZSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBNYXRyaXhFZmZlY3RfUzEob3V0cHV0Q29sb3JfUzApOwoJaGFsZjQgb3V0cHV0X1MyOwoJb3V0cHV0X1MyID0gQ2lyY3VsYXJSUmVjdF9TMihvdXRwdXRDb3ZlcmFnZV9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0X1MxICogb3V0cHV0X1MyOwoJfQp9CgAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAAcG9zaXRpb24IAAAAY292ZXJhZ2UFAAAAY29sb3IAAAAKAAAAbG9jYWxDb29yZAAAAAAAAA==","AYAA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAAAAMYAAAAAAAQAAAABAMQAAAAA":"DAAAAExTS1PbAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgaW5Qb3NpdGlvbjsKaW4gaGFsZjQgaW5Db2xvcjsKaW4gZmxvYXQ0IGluQ2lyY2xlRWRnZTsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQ0IHZpbkNpcmNsZUVkZ2VfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJdmluQ2lyY2xlRWRnZV9TMCA9IGluQ2lyY2xlRWRnZTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8yX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgAAAAAAQwIAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQpub3BlcnNwZWN0aXZlIGluIGZsb2F0NCB2aW5DaXJjbGVFZGdlX1MwOwpub3BlcnNwZWN0aXZlIGluIGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgQ2lyY2xlR2VvbWV0cnlQcm9jZXNzb3IKCWZsb2F0NCBjaXJjbGVFZGdlOwoJY2lyY2xlRWRnZSA9IHZpbkNpcmNsZUVkZ2VfUzA7CgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmluQ29sb3JfUzA7CglmbG9hdCBkID0gbGVuZ3RoKGNpcmNsZUVkZ2UueHkpOwoJaGFsZiBkaXN0YW5jZVRvT3V0ZXJFZGdlID0gaGFsZihjaXJjbGVFZGdlLnogKiAoMS4wIC0gZCkpOwoJaGFsZiBlZGdlQWxwaGEgPSBzYXR1cmF0ZShkaXN0YW5jZVRvT3V0ZXJFZGdlKTsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoZWRnZUFscGhhKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAoAAABpblBvc2l0aW9uAAAHAAAAaW5Db2xvcgAMAAAAaW5DaXJjbGVFZGdlAAAAAA==","GYQACAAAAAMAADAAAIOAAAH677776IZOCAAP577777777777777777YBAAAAAAAAAAAHEADZAAAAAAIAAAAAAMYAAAAAAAQAAAABAMQAAAAAA":"DAAAAExTS1MaAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgcG9zaXRpb247CmluIGhhbGY0IGNvbG9yOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2Y29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cn0KAAABAAAA5gIAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQp1bmlmb3JtIGZsb2F0NCB1aW5uZXJSZWN0X1MxOwp1bmlmb3JtIGhhbGYyIHVyYWRpdXNQbHVzSGFsZl9TMTsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2Y29sb3JfUzA7CmhhbGY0IENpcmN1bGFyUlJlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MxLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MxLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CgloYWxmIGFscGhhID0gaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzEueCAtIGxlbmd0aChkeHkpKSk7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBDaXJjdWxhclJSZWN0X1MxKG91dHB1dENvdmVyYWdlX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAAAAAAAA==","G2QACAAAABAAADAAAIOAAAAADIIAAIRODAAP577774DSAIAA737777YBAAAAAAAAAAAHEADZAAAAAAIAAAAAAMYAAAAAAAQAAAABAMQAAAAAA":"DAAAAExTS1PqAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgcG9zaXRpb247CmluIGZsb2F0IGNvdmVyYWdlOwppbiBoYWxmNCBjb2xvcjsKaW4gZmxvYXQ0IGdlb21TdWJzZXQ7Cm5vcGVyc3BlY3RpdmUgb3V0IGhhbGY0IHZjb2xvcl9TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQgdmNvdmVyYWdlX1MwOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDQgdmdlb21TdWJzZXRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQyIHBvc2l0aW9uID0gcG9zaXRpb24ueHk7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCXZjb3ZlcmFnZV9TMCA9IGNvdmVyYWdlOwoJdmdlb21TdWJzZXRfUzAgPSBnZW9tU3Vic2V0OwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAQAAADMEAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7Cm5vcGVyc3BlY3RpdmUgaW4gaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0IHZjb3ZlcmFnZV9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdDQgdmdlb21TdWJzZXRfUzA7CmhhbGY0IENpcmN1bGFyUlJlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MxLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MxLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CgloYWxmIGFscGhhID0gaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzEueCAtIGxlbmd0aChkeHkpKSk7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWZsb2F0IGNvdmVyYWdlID0gdmNvdmVyYWdlX1MwOwoJZmxvYXQ0IGdlb1N1YnNldDsKCWdlb1N1YnNldCA9IHZnZW9tU3Vic2V0X1MwOwoJZmxvYXQ0IGRpc3RzNCA9IHNhdHVyYXRlKGZsb2F0NCgxLCAxLCAtMSwgLTEpICogKHNrX0ZyYWdDb29yZC54eXh5IC0gZ2VvU3Vic2V0KSk7CglmbG9hdDIgZGlzdHMyID0gZGlzdHM0Lnh5ICsgZGlzdHM0Lnp3IC0gMTsKCWNvdmVyYWdlID0gbWluKGNvdmVyYWdlLCBkaXN0czIueCAqIGRpc3RzMi55KTsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoY292ZXJhZ2UpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQ2lyY3VsYXJSUmVjdF9TMShvdXRwdXRDb3ZlcmFnZV9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAHBvc2l0aW9uCAAAAGNvdmVyYWdlBQAAAGNvbG9yAAAACgAAAGdlb21TdWJzZXQAAAAAAAA=","CMRQCIAABBYAAAEIXBAAACDQMAABRAFAAAAAAAAAAAAAAAGABQAAAAEAAAAAAAEEBQAAAAA":"DAAAAExTS1OZAgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0NCB1bG9jYWxNYXRyaXhfUzA7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiBmbG9hdDIgaW5FbGxpcHNlT2Zmc2V0OwppbiBmbG9hdDQgaW5FbGxpcHNlUmFkaWk7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2RWxsaXBzZU9mZnNldHNfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0NCB2RWxsaXBzZVJhZGlpX1MwOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgRWxsaXBzZUdlb21ldHJ5UHJvY2Vzc29yCgl2RWxsaXBzZU9mZnNldHNfUzAgPSBpbkVsbGlwc2VPZmZzZXQ7Cgl2RWxsaXBzZVJhZGlpX1MwID0gaW5FbGxpcHNlUmFkaWk7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8wX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJZmxvYXQyIF90bXBfMV9pblBvc2l0aW9uID0gdWxvY2FsTWF0cml4X1MwLnh6ICogaW5Qb3NpdGlvbiArIHVsb2NhbE1hdHJpeF9TMC55dzsKCXNrX1Bvc2l0aW9uID0gX3RtcF8wX2luUG9zaXRpb24ueHkwMTsKfQoAAAAAAAAA2QMAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2RWxsaXBzZU9mZnNldHNfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQ0IHZFbGxpcHNlUmFkaWlfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBFbGxpcHNlR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWZsb2F0MiBvZmZzZXQgPSB2RWxsaXBzZU9mZnNldHNfUzAueHk7CglvZmZzZXQgKj0gdkVsbGlwc2VSYWRpaV9TMC54eTsKCWZsb2F0IHRlc3QgPSBkb3Qob2Zmc2V0LCBvZmZzZXQpIC0gMS4wOwoJZmxvYXQyIGdyYWQgPSAyLjAqb2Zmc2V0KnZFbGxpcHNlUmFkaWlfUzAueHk7CglmbG9hdCBncmFkX2RvdCA9IGRvdChncmFkLCBncmFkKTsKCWdyYWRfZG90ID0gbWF4KGdyYWRfZG90LCAxLjE3NTVlLTM4KTsKCWZsb2F0IGludmxlbiA9IGludmVyc2VzcXJ0KGdyYWRfZG90KTsKCWZsb2F0IGVkZ2VBbHBoYSA9IHNhdHVyYXRlKDAuNS10ZXN0Kmludmxlbik7CglvZmZzZXQgPSB2RWxsaXBzZU9mZnNldHNfUzAueHkqdkVsbGlwc2VSYWRpaV9TMC56dzsKCXRlc3QgPSBkb3Qob2Zmc2V0LCBvZmZzZXQpIC0gMS4wOwoJZ3JhZCA9IDIuMCpvZmZzZXQqdkVsbGlwc2VSYWRpaV9TMC56dzsKCWdyYWRfZG90ID0gZG90KGdyYWQsIGdyYWQpOwoJaW52bGVuID0gaW52ZXJzZXNxcnQoZ3JhZF9kb3QpOwoJZWRnZUFscGhhICo9IHNhdHVyYXRlKDAuNSt0ZXN0Kmludmxlbik7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGhhbGYoZWRnZUFscGhhKSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAoAAABpblBvc2l0aW9uAAAHAAAAaW5Db2xvcgAPAAAAaW5FbGxpcHNlT2Zmc2V0AA4AAABpbkVsbGlwc2VSYWRpaQAAAAAAAA==","GYJAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAQAAAAAAQQGAAZAADIAAAAIH5K3LIKAAAAAAMAAAAAIAAAAAAFMZBQP3FQWAUAABQAAAAAAAAAAAAADGAAAAAAAEAAAAAIDEAAA":"DAAAAExTS1MwAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgcG9zaXRpb247CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmxvY2FsQ29vcmRfUzAgPSBsb2NhbENvb3JkOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgEAAADzBAAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCmNvbnN0IGludCBrRmlsbEFBX1MxX2MwID0gMTsKY29uc3QgaW50IGtJbnZlcnNlRmlsbEJXX1MxX2MwID0gMjsKY29uc3QgaW50IGtJbnZlcnNlRmlsbEFBX1MxX2MwID0gMzsKdW5pZm9ybSBmbG9hdDQgdWNpcmNsZV9TMV9jMDsKc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2bG9jYWxDb29yZF9TMDsKaGFsZjQgQ2lyY2xlX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJaGFsZiBkOwoJaWYgKGludCgxKSA9PSBrSW52ZXJzZUZpbGxCV19TMV9jMCB8fCBpbnQoMSkgPT0ga0ludmVyc2VGaWxsQUFfUzFfYzApIAoJewoJCWQgPSBoYWxmKChsZW5ndGgoKHVjaXJjbGVfUzFfYzAueHkgLSBza19GcmFnQ29vcmQueHkpICogdWNpcmNsZV9TMV9jMC53KSAtIDEuMCkgKiB1Y2lyY2xlX1MxX2MwLnopOwoJfQoJZWxzZSAKCXsKCQlkID0gaGFsZigoMS4wIC0gbGVuZ3RoKCh1Y2lyY2xlX1MxX2MwLnh5IC0gc2tfRnJhZ0Nvb3JkLnh5KSAqIHVjaXJjbGVfUzFfYzAudykpICogdWNpcmNsZV9TMV9jMC56KTsKCX0KCXJldHVybiBoYWxmNChoYWxmNChpbnQoMSkgPT0ga0ZpbGxBQV9TMV9jMCB8fCBpbnQoMSkgPT0ga0ludmVyc2VGaWxsQUFfUzFfYzAgPyBzYXR1cmF0ZShkKSA6IGhhbGYoZCA+IDAuNSkpKTsKfQpoYWxmNCBCbGVuZF9TMShoYWxmNCBfc3JjLCBoYWxmNCBfZHN0KSAKewoJcmV0dXJuIGJsZW5kX21vZHVsYXRlKF9zcmMsIENpcmNsZV9TMV9jMChfc3JjKSk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWZsb2F0MiB0ZXhDb29yZDsKCXRleENvb3JkID0gdmxvY2FsQ29vcmRfUzA7CglvdXRwdXRDb2xvcl9TMCA9IChibGVuZF9tb2R1bGF0ZShzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzAsIHRleENvb3JkKSwgaGFsZjQoMSkpKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBCbGVuZF9TMShvdXRwdXRDb3ZlcmFnZV9TMCwgaGFsZjQoMSkpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0X1MxOwoJfQp9CgABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgoAAABsb2NhbENvb3JkAAAAAAAA","EEAQMYAAMAAAEADAAABAEYAAAICIAB5AABQAAAQAMAAAEATAAABAIIGAAEDCBYQCA4AAAAAAEAB5AAAAAAYFRP5FIUAQAADQAAAABAAAAAAABQEKBTLG62KRAAAAAHAAAAAAAAAAAAYAGAAAAAQAAAAAAAQQGAAA":"DAAAAExTS1MoDAAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDQgcmFkaWlfc2VsZWN0b3I7CmluIGZsb2F0NCBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzOwppbiBmbG9hdDQgYWFfYmxvYXRfYW5kX2NvdmVyYWdlOwppbiBmbG9hdDQgcmFkaWlfeDsKaW4gZmxvYXQ0IHJhZGlpX3k7CmluIGZsb2F0NCBza2V3OwppbiBmbG9hdDIgdHJhbnNsYXRlX2FuZF9sb2NhbHJvdGF0ZTsKaW4gaGFsZjQgY29sb3I7Cm5vcGVyc3BlY3RpdmUgb3V0IGhhbGY0IHZjb2xvcl9TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQyIHZhcmNjb29yZF9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgRmlsbFJSZWN0T3A6OlByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7CglmbG9hdCBhYV9ibG9hdF9tdWx0aXBsaWVyID0gMTsKCWZsb2F0MiBjb3JuZXIgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnh5OwoJZmxvYXQyIHJhZGl1c19vdXRzZXQgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnp3OwoJZmxvYXQyIGFhX2Jsb2F0X2RpcmVjdGlvbiA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS54eTsKCWZsb2F0IGlzX2xpbmVhcl9jb3ZlcmFnZSA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS53OwoJZmxvYXQyIHBpeGVsbGVuZ3RoID0gaW52ZXJzZXNxcnQoZmxvYXQyKGRvdChza2V3Lnh6LCBza2V3Lnh6KSwgZG90KHNrZXcueXcsIHNrZXcueXcpKSk7CglmbG9hdDQgbm9ybWFsaXplZF9heGlzX2RpcnMgPSBza2V3ICogcGl4ZWxsZW5ndGgueHl4eTsKCWZsb2F0MiBheGlzd2lkdGhzID0gKGFicyhub3JtYWxpemVkX2F4aXNfZGlycy54eSkgKyBhYnMobm9ybWFsaXplZF9heGlzX2RpcnMuencpKTsKCWZsb2F0MiBhYV9ibG9hdHJhZGl1cyA9IGF4aXN3aWR0aHMgKiBwaXhlbGxlbmd0aCAqIC41OwoJZmxvYXQ0IHJhZGlpX2FuZF9uZWlnaGJvcnMgPSByYWRpaV9zZWxlY3RvciogZmxvYXQ0eDQocmFkaWlfeCwgcmFkaWlfeSwgcmFkaWlfeC55eHd6LCByYWRpaV95Lnd6eXgpOwoJZmxvYXQyIHJhZGlpID0gcmFkaWlfYW5kX25laWdoYm9ycy54eTsKCWZsb2F0MiBuZWlnaGJvcl9yYWRpaSA9IHJhZGlpX2FuZF9uZWlnaGJvcnMuenc7CglmbG9hdCBjb3ZlcmFnZV9tdWx0aXBsaWVyID0gMTsKCWlmIChhbnkoZ3JlYXRlclRoYW4oYWFfYmxvYXRyYWRpdXMsIGZsb2F0MigxKSkpKSAKCXsKCQljb3JuZXIgPSBtYXgoYWJzKGNvcm5lciksIGFhX2Jsb2F0cmFkaXVzKSAqIHNpZ24oY29ybmVyKTsKCQljb3ZlcmFnZV9tdWx0aXBsaWVyID0gMSAvIChtYXgoYWFfYmxvYXRyYWRpdXMueCwgMSkgKiBtYXgoYWFfYmxvYXRyYWRpdXMueSwgMSkpOwoJCXJhZGlpID0gZmxvYXQyKDApOwoJfQoJZmxvYXQgY292ZXJhZ2UgPSBhYV9ibG9hdF9hbmRfY292ZXJhZ2UuejsKCWlmIChhbnkobGVzc1RoYW4ocmFkaWksIGFhX2Jsb2F0cmFkaXVzICogMS41KSkpIAoJewoJCXJhZGlpID0gZmxvYXQyKDApOwoJCWFhX2Jsb2F0X2RpcmVjdGlvbiA9IHNpZ24oY29ybmVyKTsKCQlpZiAoY292ZXJhZ2UgPiAuNSkgCgkJewoJCQlhYV9ibG9hdF9kaXJlY3Rpb24gPSAtYWFfYmxvYXRfZGlyZWN0aW9uOwoJCX0KCQlpc19saW5lYXJfY292ZXJhZ2UgPSAxOwoJfQoJZWxzZSAKCXsKCQlyYWRpaSA9IGNsYW1wKHJhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQluZWlnaGJvcl9yYWRpaSA9IGNsYW1wKG5laWdoYm9yX3JhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQlmbG9hdDIgc3BhY2luZyA9IDIgLSByYWRpaSAtIG5laWdoYm9yX3JhZGlpOwoJCWZsb2F0MiBleHRyYV9wYWQgPSBtYXgocGl4ZWxsZW5ndGggKiAuMDYyNSAtIHNwYWNpbmcsIGZsb2F0MigwKSk7CgkJcmFkaWkgLT0gZXh0cmFfcGFkICogLjU7Cgl9CglmbG9hdDIgYWFfb3V0c2V0ID0gYWFfYmxvYXRfZGlyZWN0aW9uICogYWFfYmxvYXRyYWRpdXMgKiBhYV9ibG9hdF9tdWx0aXBsaWVyOwoJZmxvYXQyIHZlcnRleHBvcyA9IGNvcm5lciArIHJhZGl1c19vdXRzZXQgKiByYWRpaSArIGFhX291dHNldDsKCWlmIChjb3ZlcmFnZSA+IC41KSAKCXsKCQlpZiAoYWFfYmxvYXRfZGlyZWN0aW9uLnggIT0gMCAmJiB2ZXJ0ZXhwb3MueCAqIGNvcm5lci54IDwgMCkgCgkJewoJCQlmbG9hdCBiYWNrc2V0ID0gYWJzKHZlcnRleHBvcy54KTsKCQkJdmVydGV4cG9zLnggPSAwOwoJCQl2ZXJ0ZXhwb3MueSArPSBiYWNrc2V0ICogc2lnbihjb3JuZXIueSkgKiBwaXhlbGxlbmd0aC55L3BpeGVsbGVuZ3RoLng7CgkJCWNvdmVyYWdlID0gKGNvdmVyYWdlIC0gLjUpICogYWJzKGNvcm5lci54KSAvIChhYnMoY29ybmVyLngpICsgYmFja3NldCkgKyAuNTsKCQl9CgkJaWYgKGFhX2Jsb2F0X2RpcmVjdGlvbi55ICE9IDAgJiYgdmVydGV4cG9zLnkgKiBjb3JuZXIueSA8IDApIAoJCXsKCQkJZmxvYXQgYmFja3NldCA9IGFicyh2ZXJ0ZXhwb3MueSk7CgkJCXZlcnRleHBvcy55ID0gMDsKCQkJdmVydGV4cG9zLnggKz0gYmFja3NldCAqIHNpZ24oY29ybmVyLngpICogcGl4ZWxsZW5ndGgueC9waXhlbGxlbmd0aC55OwoJCQljb3ZlcmFnZSA9IChjb3ZlcmFnZSAtIC41KSAqIGFicyhjb3JuZXIueSkgLyAoYWJzKGNvcm5lci55KSArIGJhY2tzZXQpICsgLjU7CgkJfQoJfQoJZmxvYXQyeDIgc2tld21hdHJpeCA9IGZsb2F0MngyKHNrZXcueHksIHNrZXcuencpOwoJZmxvYXQyIGRldmNvb3JkID0gdmVydGV4cG9zICogc2tld21hdHJpeCArIHRyYW5zbGF0ZV9hbmRfbG9jYWxyb3RhdGUueHk7CglpZiAoMCAhPSBpc19saW5lYXJfY292ZXJhZ2UpIAoJewoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MigwLCBjb3ZlcmFnZSAqIGNvdmVyYWdlX211bHRpcGxpZXIpOwoJfQoJZWxzZSAKCXsKCQlmbG9hdDIgYXJjY29vcmQgPSAxIC0gYWJzKHJhZGl1c19vdXRzZXQpICsgYWFfb3V0c2V0L3JhZGlpICogY29ybmVyOwoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MihhcmNjb29yZC54KzEsIGFyY2Nvb3JkLnkpOwoJfQoJc2tfUG9zaXRpb24gPSBkZXZjb29yZC54eTAxOwp9CgEAAACdBQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCmNvbnN0IGludCBrRmlsbEFBX1MxX2MwID0gMTsKY29uc3QgaW50IGtJbnZlcnNlRmlsbEJXX1MxX2MwID0gMjsKY29uc3QgaW50IGtJbnZlcnNlRmlsbEFBX1MxX2MwID0gMzsKdW5pZm9ybSBmbG9hdDQgdWNpcmNsZV9TMV9jMDsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQyIHZhcmNjb29yZF9TMDsKaGFsZjQgQ2lyY2xlX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJaGFsZiBkOwoJaWYgKGludCgzKSA9PSBrSW52ZXJzZUZpbGxCV19TMV9jMCB8fCBpbnQoMykgPT0ga0ludmVyc2VGaWxsQUFfUzFfYzApIAoJewoJCWQgPSBoYWxmKChsZW5ndGgoKHVjaXJjbGVfUzFfYzAueHkgLSBza19GcmFnQ29vcmQueHkpICogdWNpcmNsZV9TMV9jMC53KSAtIDEuMCkgKiB1Y2lyY2xlX1MxX2MwLnopOwoJfQoJZWxzZSAKCXsKCQlkID0gaGFsZigoMS4wIC0gbGVuZ3RoKCh1Y2lyY2xlX1MxX2MwLnh5IC0gc2tfRnJhZ0Nvb3JkLnh5KSAqIHVjaXJjbGVfUzFfYzAudykpICogdWNpcmNsZV9TMV9jMC56KTsKCX0KCXJldHVybiBoYWxmNChoYWxmNChpbnQoMykgPT0ga0ZpbGxBQV9TMV9jMCB8fCBpbnQoMykgPT0ga0ludmVyc2VGaWxsQUFfUzFfYzAgPyBzYXR1cmF0ZShkKSA6IGhhbGYoZCA+IDAuNSkpKTsKfQpoYWxmNCBCbGVuZF9TMShoYWxmNCBfc3JjLCBoYWxmNCBfZHN0KSAKewoJcmV0dXJuIGJsZW5kX21vZHVsYXRlKF9zcmMsIENpcmNsZV9TMV9jMChfc3JjKSk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIEZpbGxSUmVjdE9wOjpQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7CglmbG9hdCB4X3BsdXNfMT12YXJjY29vcmRfUzAueCwgeT12YXJjY29vcmRfUzAueTsKCWhhbGYgY292ZXJhZ2U7CglpZiAoMCA9PSB4X3BsdXNfMSkgCgl7CgkJY292ZXJhZ2UgPSBoYWxmKHkpOwoJfQoJZWxzZSAKCXsKCQlmbG9hdCBmbiA9IHhfcGx1c18xICogKHhfcGx1c18xIC0gMik7CgkJZm4gPSBmbWEoeSx5LCBmbik7CgkJZmxvYXQgZm53aWR0aCA9IGZ3aWR0aChmbik7CgkJY292ZXJhZ2UgPSAuNSAtIGhhbGYoZm4vZm53aWR0aCk7CgkJY292ZXJhZ2UgPSBjbGFtcChjb3ZlcmFnZSwgMCwgMSk7Cgl9CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGNvdmVyYWdlKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IEJsZW5kX1MxKG91dHB1dENvdmVyYWdlX1MwLCBoYWxmNCgxKSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAOAAAAcmFkaWlfc2VsZWN0b3IAABkAAABjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzAAAAFQAAAGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZQAAAAcAAAByYWRpaV94AAcAAAByYWRpaV95AAQAAABza2V3GQAAAHRyYW5zbGF0ZV9hbmRfbG9jYWxyb3RhdGUAAAAFAAAAY29sb3IAAAAAAAAA","AYTRVAADQAAAOAEARAFQJAABBADAAAILBYAACCYUQD777777777767YAAAAAAAAAAAAMYAAAAAAAQAAAABAMQAAAAA":"DAAAAExTS1PnAgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0NCB1bG9jYWxNYXRyaXhfUzA7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiBmbG9hdDQgaW5DaXJjbGVFZGdlOwppbiBoYWxmMyBpbkNsaXBQbGFuZTsKaW4gaGFsZjMgaW5Jc2VjdFBsYW5lOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjMgdmluQ2xpcFBsYW5lX1MwOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmMyB2aW5Jc2VjdFBsYW5lX1MwOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgQ2lyY2xlR2VvbWV0cnlQcm9jZXNzb3IKCXZpbkNpcmNsZUVkZ2VfUzAgPSBpbkNpcmNsZUVkZ2U7Cgl2aW5DbGlwUGxhbmVfUzAgPSBpbkNsaXBQbGFuZTsKCXZpbklzZWN0UGxhbmVfUzAgPSBpbklzZWN0UGxhbmU7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8wX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJZmxvYXQyIF90bXBfMV9pblBvc2l0aW9uID0gdWxvY2FsTWF0cml4X1MwLnh6ICogaW5Qb3NpdGlvbiArIHVsb2NhbE1hdHJpeF9TMC55dzsKCXNrX1Bvc2l0aW9uID0gX3RtcF8wX2luUG9zaXRpb24ueHkwMTsKfQoAAAAAAFIEAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmMyB2aW5DbGlwUGxhbmVfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gaGFsZjMgdmluSXNlY3RQbGFuZV9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIENpcmNsZUdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDQgY2lyY2xlRWRnZTsKCWNpcmNsZUVkZ2UgPSB2aW5DaXJjbGVFZGdlX1MwOwoJaGFsZjMgY2xpcFBsYW5lOwoJY2xpcFBsYW5lID0gdmluQ2xpcFBsYW5lX1MwOwoJaGFsZjMgaXNlY3RQbGFuZTsKCWlzZWN0UGxhbmUgPSB2aW5Jc2VjdFBsYW5lX1MwOwoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZpbkNvbG9yX1MwOwoJZmxvYXQgZCA9IGxlbmd0aChjaXJjbGVFZGdlLnh5KTsKCWhhbGYgZGlzdGFuY2VUb091dGVyRWRnZSA9IGhhbGYoY2lyY2xlRWRnZS56ICogKDEuMCAtIGQpKTsKCWhhbGYgZWRnZUFscGhhID0gc2F0dXJhdGUoZGlzdGFuY2VUb091dGVyRWRnZSk7CgloYWxmIGRpc3RhbmNlVG9Jbm5lckVkZ2UgPSBoYWxmKGNpcmNsZUVkZ2UueiAqIChkIC0gY2lyY2xlRWRnZS53KSk7CgloYWxmIGlubmVyQWxwaGEgPSBzYXR1cmF0ZShkaXN0YW5jZVRvSW5uZXJFZGdlKTsKCWVkZ2VBbHBoYSAqPSBpbm5lckFscGhhOwoJaGFsZiBjbGlwID0gaGFsZihzYXR1cmF0ZShjaXJjbGVFZGdlLnogKiBkb3QoY2lyY2xlRWRnZS54eSwgY2xpcFBsYW5lLnh5KSArIGNsaXBQbGFuZS56KSk7CgljbGlwICo9IGhhbGYoc2F0dXJhdGUoY2lyY2xlRWRnZS56ICogZG90KGNpcmNsZUVkZ2UueHksIGlzZWN0UGxhbmUueHkpICsgaXNlY3RQbGFuZS56KSk7CgllZGdlQWxwaGEgKj0gY2xpcDsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoZWRnZUFscGhhKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADAAAAGluQ2lyY2xlRWRnZQsAAABpbkNsaXBQbGFuZQAMAAAAaW5Jc2VjdFBsYW5lAAAAAA==","GYJAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAQAAAAAEQQGABZAA6IAAAAACAAAAAADGAAAAAAAEAAAAAIDEAAAAAAA":"DAAAAExTS1MwAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgcG9zaXRpb247CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmxvY2FsQ29vcmRfUzAgPSBsb2NhbENvb3JkOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgEAAACHAwAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHVpbm5lclJlY3RfUzE7CnVuaWZvcm0gaGFsZjIgdXJhZGl1c1BsdXNIYWxmX1MxOwpzYW1wbGVyRXh0ZXJuYWxPRVMgdVRleHR1cmVTYW1wbGVyXzBfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQyIHZsb2NhbENvb3JkX1MwOwpoYWxmNCBDaXJjdWxhclJSZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCWZsb2F0MiBkeHkwID0gdWlubmVyUmVjdF9TMS5MVCAtIHNrX0ZyYWdDb29yZC54eTsKCWZsb2F0MiBkeHkxID0gc2tfRnJhZ0Nvb3JkLnh5IC0gdWlubmVyUmVjdF9TMS5SQjsKCWZsb2F0MiBkeHkgPSBtYXgobWF4KGR4eTAsIGR4eTEpLCAwLjApOwoJaGFsZiBhbHBoYSA9IGhhbGYoc2F0dXJhdGUodXJhZGl1c1BsdXNIYWxmX1MxLnggLSBsZW5ndGgoZHh5KSkpOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwID0gaGFsZjQoMSk7CglmbG9hdDIgdGV4Q29vcmQ7Cgl0ZXhDb29yZCA9IHZsb2NhbENvb3JkX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSAoYmxlbmRfbW9kdWxhdGUoc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB0ZXhDb29yZCksIGhhbGY0KDEpKSk7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQ2lyY3VsYXJSUmVjdF9TMShvdXRwdXRDb3ZlcmFnZV9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACAAAAHBvc2l0aW9uCgAAAGxvY2FsQ29vcmQAAAAAAAA=","GZIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAHIBIA5HZ2CAAAAAABAEACAAAAASAEAEQQAAAAUCCQAQQGAAIBAAAAAAAGMAAAAAAAIAAAAAQGIAAAAAAA":"DAAAAExTS1POAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzA7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfM19TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzFfYzApICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAAAA3gUAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQp1bmlmb3JtIGhhbGY0IHVib3JkZXJfUzFfYzBfYzA7CnVuaWZvcm0gZmxvYXQ0IHVzdWJzZXRfUzFfYzBfYzA7CnVuaWZvcm0gZmxvYXQ0IHVjbGFtcF9TMV9jMF9jMDsKdW5pZm9ybSBmbG9hdDIgdWlkaW1zX1MxX2MwX2MwOwp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzA7CnNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMTsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc18zX1MwOwpoYWxmNCBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWZsb2F0MiBpbkNvb3JkID0gdlRyYW5zZm9ybWVkQ29vcmRzXzNfUzA7CglmbG9hdDIgc3Vic2V0Q29vcmQ7CglzdWJzZXRDb29yZC54ID0gaW5Db29yZC54OwoJc3Vic2V0Q29vcmQueSA9IGluQ29vcmQueTsKCWZsb2F0MiBjbGFtcGVkQ29vcmQ7CgljbGFtcGVkQ29vcmQgPSBjbGFtcChzdWJzZXRDb29yZCwgdWNsYW1wX1MxX2MwX2MwLnh5LCB1Y2xhbXBfUzFfYzBfYzAuencpOwoJaGFsZjQgdGV4dHVyZUNvbG9yID0gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MxLCAoY2xhbXBlZENvb3JkKSAqIHVpZGltc19TMV9jMF9jMCk7CgloYWxmIGVyclggPSBoYWxmKHN1YnNldENvb3JkLnggLSBjbGFtcGVkQ29vcmQueCk7CgloYWxmIGVyclkgPSBoYWxmKHN1YnNldENvb3JkLnkgLSBjbGFtcGVkQ29vcmQueSk7Cgl0ZXh0dXJlQ29sb3IgPSBtaXgodGV4dHVyZUNvbG9yLCB1Ym9yZGVyX1MxX2MwX2MwLCBtaW4oYWJzKGVyclgpLCAxKSk7Cgl0ZXh0dXJlQ29sb3IgPSBtaXgodGV4dHVyZUNvbG9yLCB1Ym9yZGVyX1MxX2MwX2MwLCBtaW4oYWJzKGVyclkpLCAxKSk7CglyZXR1cm4gdGV4dHVyZUNvbG9yOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gVGV4dHVyZUVmZmVjdF9TMV9jMF9jMChfaW5wdXQpOwp9CmhhbGY0IERpc2FibGVDb3ZlcmFnZUFzQWxwaGFfUzEoaGFsZjQgX2lucHV0KSAKewoJX2lucHV0ID0gTWF0cml4RWZmZWN0X1MxX2MwKF9pbnB1dCk7CgloYWxmNCBfdG1wXzBfaW5Db2xvciA9IF9pbnB1dDsKCXJldHVybiBoYWxmNChfaW5wdXQpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gRGlzYWJsZUNvdmVyYWdlQXNBbHBoYV9TMShvdXRwdXRDb2xvcl9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0X1MxICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAgAAABwb3NpdGlvbgUAAABjb2xvcgAAAAoAAABsb2NhbENvb3JkAAAAAAAA","GZIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAJIBAGMVUOTUABAAAAQAAIAAAAAWFBIEMVUOTUAAAAAAQAAIAAAACIGAACAAAAACQIKACCAYAAEAAAAAAAAZQAAAAAABAAAAACAZAAAAAAA":"DAAAAExTS1PIAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfMl9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzEpICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAOgGAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKY29uc3QgaW50IGtNYXhMb29wTGltaXRfUzFfYzAgPSA4Owp1bmlmb3JtIGZsb2F0NCB1Y2xhbXBfUzFfYzBfYzBfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMDsKdW5pZm9ybSBoYWxmNCB1b2Zmc2V0c0FuZEtlcm5lbF9TMV9jMFsxNF07CnVuaWZvcm0gaGFsZjIgdWRpcl9TMV9jMDsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7Cm5vcGVyc3BlY3RpdmUgaW4gaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMF9jMF9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJZmxvYXQyIGluQ29vcmQgPSBfY29vcmRzOwoJZmxvYXQyIHN1YnNldENvb3JkOwoJc3Vic2V0Q29vcmQueCA9IGluQ29vcmQueDsKCXN1YnNldENvb3JkLnkgPSBpbkNvb3JkLnk7CglmbG9hdDIgY2xhbXBlZENvb3JkOwoJY2xhbXBlZENvb3JkLnggPSBjbGFtcChzdWJzZXRDb29yZC54LCB1Y2xhbXBfUzFfYzBfYzBfYzAueCwgdWNsYW1wX1MxX2MwX2MwX2MwLnopOwoJY2xhbXBlZENvb3JkLnkgPSBzdWJzZXRDb29yZC55OwoJaGFsZjQgdGV4dHVyZUNvbG9yID0gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MxLCBjbGFtcGVkQ29vcmQpOwoJcmV0dXJuIHRleHR1cmVDb2xvcjsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoaGFsZjQgX2lucHV0LCBmbG9hdDIgX2Nvb3JkcykgCnsKCXJldHVybiBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwX2MwKF9pbnB1dCwgZmxvYXQzeDIodW1hdHJpeF9TMV9jMF9jMCkgKiBfY29vcmRzLnh5MSk7Cn0KaGFsZjQgcnVudGltZV9zaGFkZXJfUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF8wX2luQ29sb3IgPSBfaW5wdXQ7CglmbG9hdDIgX3RtcF8xX2Nvb3JkcyA9IHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwoJaGFsZjQgc3VtID0gaGFsZjQoMC4wKTsKCWZvciAoaW50IGkgPSAwO2kgPCBrTWF4TG9vcExpbWl0X1MxX2MwOyArK2kpIAoJewoJCWhhbGY0IHMgPSB1b2Zmc2V0c0FuZEtlcm5lbF9TMV9jMFtpXTsKCQlzdW0gKz0gcy55ICogTWF0cml4RWZmZWN0X1MxX2MwX2MwKF90bXBfMF9pbkNvbG9yLCBfdG1wXzFfY29vcmRzICsgZmxvYXQyKHMueCAqIHVkaXJfUzFfYzApKTsKCQlzdW0gKz0gcy53ICogTWF0cml4RWZmZWN0X1MxX2MwX2MwKF90bXBfMF9pbkNvbG9yLCBfdG1wXzFfY29vcmRzICsgZmxvYXQyKHMueiAqIHVkaXJfUzFfYzApKTsKCX0KCXJldHVybiBoYWxmNChzdW0pOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gcnVudGltZV9zaGFkZXJfUzFfYzAoX2lucHV0KTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IE1hdHJpeEVmZmVjdF9TMShvdXRwdXRDb2xvcl9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0X1MxICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAIAAAAcG9zaXRpb24FAAAAY29sb3IAAAAKAAAAbG9jYWxDb29yZAAAAAAAAA==","GZIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAHIBIA5HZ2CAAAAAAAAAQCAAAAASAEEAQAAAAAUCCQAQQGAAAAEAAAAAAGMAAAAAAAIAAAAAQGIAAAAAAA":"DAAAAExTS1POAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzA7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfM19TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzFfYzApICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAAAAlgQAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQp1bmlmb3JtIGZsb2F0NCB1Y2xhbXBfUzFfYzBfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMDsKc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MxOwpub3BlcnNwZWN0aXZlIGluIGhhbGY0IHZjb2xvcl9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzNfUzA7CmhhbGY0IFRleHR1cmVFZmZlY3RfUzFfYzBfYzAoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGluQ29vcmQgPSB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKCWZsb2F0MiBzdWJzZXRDb29yZDsKCXN1YnNldENvb3JkLnggPSBpbkNvb3JkLng7CglzdWJzZXRDb29yZC55ID0gaW5Db29yZC55OwoJZmxvYXQyIGNsYW1wZWRDb29yZDsKCWNsYW1wZWRDb29yZC54ID0gc3Vic2V0Q29vcmQueDsKCWNsYW1wZWRDb29yZC55ID0gY2xhbXAoc3Vic2V0Q29vcmQueSwgdWNsYW1wX1MxX2MwX2MwLnksIHVjbGFtcF9TMV9jMF9jMC53KTsKCWhhbGY0IHRleHR1cmVDb2xvciA9IHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMSwgY2xhbXBlZENvb3JkKTsKCXJldHVybiB0ZXh0dXJlQ29sb3I7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwKF9pbnB1dCk7Cn0KaGFsZjQgRGlzYWJsZUNvdmVyYWdlQXNBbHBoYV9TMShoYWxmNCBfaW5wdXQpIAp7CglfaW5wdXQgPSBNYXRyaXhFZmZlY3RfUzFfYzAoX2lucHV0KTsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJcmV0dXJuIGhhbGY0KF9pbnB1dCk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBEaXNhYmxlQ292ZXJhZ2VBc0FscGhhX1MxKG91dHB1dENvbG9yX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRfUzEgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","DAQAAAAAAAAAAAAAAJQAAIGAAEACBYQCAGAEFAIBAAAAAABAAAAAAAAAAAACAA6QAAAABYCTIUIE4AIAAAYAAAAAQAAAAAGARL4FIEMEKMAAAAAMAAAAAAAAAAAAAMADAAAAAIAAAAAAAIIDAAAA":"DAAAAExTS1N4AgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0MiB1QXRsYXNTaXplSW52X1MwOwppbiBmbG9hdDIgaW5Qb3NpdGlvbjsKaW4gaGFsZjQgaW5Db2xvcjsKaW4gdXNob3J0MiBpblRleHR1cmVDb29yZHM7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQgdlRleEluZGV4X1MwOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgQml0bWFwVGV4dAoJaW50IHRleElkeCA9IDA7CglmbG9hdDIgdW5vcm1UZXhDb29yZHMgPSBmbG9hdDIoaW5UZXh0dXJlQ29vcmRzLngsIGluVGV4dHVyZUNvb3Jkcy55KTsKCXZUZXh0dXJlQ29vcmRzX1MwID0gdW5vcm1UZXhDb29yZHMgKiB1QXRsYXNTaXplSW52X1MwOwoJdlRleEluZGV4X1MwID0gZmxvYXQodGV4SWR4KTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzFfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247Cglza19Qb3NpdGlvbiA9IGluUG9zaXRpb24ueHkwMTsKfQoBAAAAnwUAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQpjb25zdCBpbnQga0ZpbGxCV19TMV9jMCA9IDA7CmNvbnN0IGludCBrSW52ZXJzZUZpbGxCV19TMV9jMCA9IDI7CmNvbnN0IGludCBrSW52ZXJzZUZpbGxBQV9TMV9jMCA9IDM7CnVuaWZvcm0gZmxvYXQ0IHVyZWN0VW5pZm9ybV9TMV9jMDsKc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdCB2VGV4SW5kZXhfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gaGFsZjQgdmluQ29sb3JfUzA7CmhhbGY0IFJlY3RfUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF8wX2luQ29sb3IgPSBfaW5wdXQ7CgloYWxmIGNvdmVyYWdlOwoJaWYgKGludCgxKSA9PSBrRmlsbEJXX1MxX2MwIHx8IGludCgxKSA9PSBrSW52ZXJzZUZpbGxCV19TMV9jMCkgCgl7CgkJY292ZXJhZ2UgPSBoYWxmKGFsbChncmVhdGVyVGhhbihmbG9hdDQoc2tfRnJhZ0Nvb3JkLnh5LCB1cmVjdFVuaWZvcm1fUzFfYzAuencpLCBmbG9hdDQodXJlY3RVbmlmb3JtX1MxX2MwLnh5LCBza19GcmFnQ29vcmQueHkpKSkpOwoJfQoJZWxzZSAKCXsKCQloYWxmNCBkaXN0czQgPSBzYXR1cmF0ZShoYWxmNCgxLjAsIDEuMCwgLTEuMCwgLTEuMCkgKiBoYWxmNChza19GcmFnQ29vcmQueHl4eSAtIHVyZWN0VW5pZm9ybV9TMV9jMCkpOwoJCWhhbGYyIGRpc3RzMiA9IChkaXN0czQueHkgKyBkaXN0czQuencpIC0gMS4wOwoJCWNvdmVyYWdlID0gZGlzdHMyLnggKiBkaXN0czIueTsKCX0KCWlmIChpbnQoMSkgPT0ga0ludmVyc2VGaWxsQldfUzFfYzAgfHwgaW50KDEpID09IGtJbnZlcnNlRmlsbEFBX1MxX2MwKSAKCXsKCQljb3ZlcmFnZSA9IDEuMCAtIGNvdmVyYWdlOwoJfQoJcmV0dXJuIGhhbGY0KGhhbGY0KGNvdmVyYWdlKSk7Cn0KaGFsZjQgQmxlbmRfUzEoaGFsZjQgX3NyYywgaGFsZjQgX2RzdCkgCnsKCXJldHVybiBibGVuZF9tb2R1bGF0ZShSZWN0X1MxX2MwKF9zcmMpLCBfc3JjKTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgQml0bWFwVGV4dAoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZpbkNvbG9yX1MwOwoJaGFsZjQgdGV4Q29sb3I7Cgl7CgkJdGV4Q29sb3IgPSBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzAsIHZUZXh0dXJlQ29vcmRzX1MwKS5ycnJyOwoJfQoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSB0ZXhDb2xvcjsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IEJsZW5kX1MxKG91dHB1dENvdmVyYWdlX1MwLCBoYWxmNCgxKSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACgAAAGluUG9zaXRpb24AAAcAAABpbkNvbG9yAA8AAABpblRleHR1cmVDb29yZHMAAAAAAA==","GZIACAAAABQAAGAAAQ4AAAAAGQQAARC4GAAAIOCAAD6P7777777777YDAAAAAAAAAAAHIBK2VD3EOCAAAAAABUXHIMAQAAAAWSQ4HO4SAAAAAMAAAAAAAAQAABANBBK3CICAAAEASHSVIGAAAAAAAAAAAEAABAAVAGSM7BYCAAAAA2CDQ53SKAIAABQAAAAAAACAAAEAUAF3OJAIAAAAAI6LVEYAAAAAAAAQAAAAFPJIMDXPJIBAAAGAAAAAAAAIAAAAAQIXNZERAAAAABDJMU3BAAAAAAAEAAAAAMQQAIAAAQGQQVNREBAAACAAAAAAQAKRC5HBSYCACAAAAAAAAAEAIRDJMU3BAAAAAAACAAAAAVTIMQ4RKBQAAAAAAAAAACAAIAIAAIAAAAC2BCEAQAAAAAAAAAAAMADAAAAAUAAAAAAAIIDA":"DAAAAExTS1NNAgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzBfYzBfYzE7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQgY292ZXJhZ2U7CmluIGhhbGY0IGNvbG9yOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdCB2Y292ZXJhZ2VfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfN19TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDIgcG9zaXRpb24gPSBwb3NpdGlvbi54eTsKCXZjb2xvcl9TMCA9IGNvbG9yOwoJdmNvdmVyYWdlX1MwID0gY292ZXJhZ2U7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzdfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxX2MwX2MwX2MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAEAAADKCgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gaGFsZjQgdXN0YXJ0X1MxX2MwX2MwX2MwX2MwOwp1bmlmb3JtIGhhbGY0IHVlbmRfUzFfYzBfYzBfYzBfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMF9jMTsKdW5pZm9ybSBoYWxmNCB1bGVmdEJvcmRlckNvbG9yX1MxX2MwX2MwOwp1bmlmb3JtIGhhbGY0IHVyaWdodEJvcmRlckNvbG9yX1MxX2MwX2MwOwp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzE7CnVuaWZvcm0gaGFsZiB1cmFuZ2VfUzE7CnNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMTsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQgdmNvdmVyYWdlX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfN19TMDsKaGFsZjQgU2luZ2xlSW50ZXJ2YWxDb2xvcml6ZXJfUzFfYzBfYzBfYzBfYzAoaGFsZjQgX2lucHV0LCBmbG9hdDIgX2Nvb3JkcykgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJZmxvYXQyIF90bXBfMV9jb29yZHMgPSBfY29vcmRzOwoJcmV0dXJuIGhhbGY0KG1peCh1c3RhcnRfUzFfYzBfYzBfYzBfYzAsIHVlbmRfUzFfYzBfYzBfYzBfYzAsIGhhbGYoX3RtcF8xX2Nvb3Jkcy54KSkpOwp9CmhhbGY0IGNvbG9yX3hmb3JtX1MxX2MwX2MwX2MwKGZsb2F0NCBjb2xvcikgCnsKCWNvbG9yLnJnYiAqPSBjb2xvci5hOwoJcmV0dXJuIGhhbGY0KGNvbG9yKTsKfQpoYWxmNCBDb2xvclNwYWNlWGZvcm1fUzFfYzBfYzBfYzAoaGFsZjQgX2lucHV0LCBmbG9hdDIgX2Nvb3JkcykgCnsKCXJldHVybiBjb2xvcl94Zm9ybV9TMV9jMF9jMF9jMChTaW5nbGVJbnRlcnZhbENvbG9yaXplcl9TMV9jMF9jMF9jMF9jMChfaW5wdXQsIF9jb29yZHMpKTsKfQpoYWxmNCBMaW5lYXJMYXlvdXRfUzFfYzBfYzBfYzFfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF8yX2luQ29sb3IgPSBfaW5wdXQ7CglmbG9hdDIgX3RtcF8zX2Nvb3JkcyA9IHZUcmFuc2Zvcm1lZENvb3Jkc183X1MwOwoJcmV0dXJuIGhhbGY0KGhhbGY0KGhhbGYoX3RtcF8zX2Nvb3Jkcy54KSArIDFlLTA1LCAxLjAsIDAuMCwgMC4wKSk7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxX2MwX2MwX2MxKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBMaW5lYXJMYXlvdXRfUzFfYzBfYzBfYzFfYzAoX2lucHV0KTsKfQpoYWxmNCBDbGFtcGVkR3JhZGllbnRfUzFfYzBfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF80X2luQ29sb3IgPSBfaW5wdXQ7CgloYWxmNCB0ID0gTWF0cml4RWZmZWN0X1MxX2MwX2MwX2MxKF90bXBfNF9pbkNvbG9yKTsKCWhhbGY0IG91dENvbG9yOwoJaWYgKCFib29sKGludCgxKSkgJiYgdC55IDwgMC4wKSAKCXsKCQlvdXRDb2xvciA9IGhhbGY0KDAuMCk7Cgl9CgllbHNlIGlmICh0LnggPCAwLjApIAoJewoJCW91dENvbG9yID0gdWxlZnRCb3JkZXJDb2xvcl9TMV9jMF9jMDsKCX0KCWVsc2UgaWYgKHQueCA+IDEuMCkgCgl7CgkJb3V0Q29sb3IgPSB1cmlnaHRCb3JkZXJDb2xvcl9TMV9jMF9jMDsKCX0KCWVsc2UgCgl7CgkJb3V0Q29sb3IgPSBDb2xvclNwYWNlWGZvcm1fUzFfYzBfYzBfYzAoX3RtcF80X2luQ29sb3IsIGZsb2F0MihoYWxmMih0LngsIDAuMCkpKTsKCX0KCXJldHVybiBoYWxmNChvdXRDb2xvcik7Cn0KaGFsZjQgRGlzYWJsZUNvdmVyYWdlQXNBbHBoYV9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CglfaW5wdXQgPSBDbGFtcGVkR3JhZGllbnRfUzFfYzBfYzAoX2lucHV0KTsKCWhhbGY0IF90bXBfNV9pbkNvbG9yID0gX2lucHV0OwoJcmV0dXJuIGhhbGY0KF9pbnB1dCk7Cn0KaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMV9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJcmV0dXJuIHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMSwgX2Nvb3JkcykuMDAwcjsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzFfYzEoaGFsZjQgX2lucHV0LCBmbG9hdDIgX2Nvb3JkcykgCnsKCXJldHVybiBUZXh0dXJlRWZmZWN0X1MxX2MxX2MwKF9pbnB1dCwgZmxvYXQzeDIodW1hdHJpeF9TMV9jMSkgKiBfY29vcmRzLnh5MSk7Cn0KaGFsZjQgRGl0aGVyX1MxKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfNl9pbkNvbG9yID0gX2lucHV0OwoJaGFsZjQgY29sb3IgPSBEaXNhYmxlQ292ZXJhZ2VBc0FscGhhX1MxX2MwKF90bXBfNl9pbkNvbG9yKTsKCWhhbGYgdmFsdWUgPSBNYXRyaXhFZmZlY3RfUzFfYzEoX3RtcF82X2luQ29sb3IsIHNrX0ZyYWdDb29yZC54eSkudyAtIDAuNTsKCXJldHVybiBoYWxmNChoYWxmNChjbGFtcChjb2xvci54eXogKyB2YWx1ZSAqIHVyYW5nZV9TMSwgMC4wLCBjb2xvci53KSwgY29sb3IudykpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7CglmbG9hdCBjb3ZlcmFnZSA9IHZjb3ZlcmFnZV9TMDsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoY292ZXJhZ2UpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gRGl0aGVyX1MxKG91dHB1dENvbG9yX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSAoaGFsZjQoMS4wKSAtIG91dHB1dF9TMSkgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAHBvc2l0aW9uCAAAAGNvdmVyYWdlBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","DASAAAAAAAAAAAEAAFQAAIGAAEAOB77776PUEAIBAAAAAABAAAAAAABAMQAAAMYAAAAAAAQAAAABAMQAAAAA":"DAAAAExTS1MpAgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0MiB1QXRsYXNTaXplSW52X1MwOwppbiBmbG9hdDIgaW5Qb3NpdGlvbjsKaW4gdXNob3J0MiBpblRleHR1cmVDb29yZHM7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQgdlRleEluZGV4X1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBCaXRtYXBUZXh0CglpbnQgdGV4SWR4ID0gMDsKCWZsb2F0MiB1bm9ybVRleENvb3JkcyA9IGZsb2F0MihpblRleHR1cmVDb29yZHMueCwgaW5UZXh0dXJlQ29vcmRzLnkpOwoJdlRleHR1cmVDb29yZHNfUzAgPSB1bm9ybVRleENvb3JkcyAqIHVBdGxhc1NpemVJbnZfUzA7Cgl2VGV4SW5kZXhfUzAgPSBmbG9hdCh0ZXhJZHgpOwoJZmxvYXQyIF90bXBfMV9pblBvc2l0aW9uID0gaW5Qb3NpdGlvbjsKCXNrX1Bvc2l0aW9uID0gaW5Qb3NpdGlvbi54eTAxOwp9CgAAAAAAAAAsAgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gaGFsZjQgdUNvbG9yX1MwOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQyIHZUZXh0dXJlQ29vcmRzX1MwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0IHZUZXhJbmRleF9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIEJpdG1hcFRleHQKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB1Q29sb3JfUzA7CgloYWxmNCB0ZXhDb2xvcjsKCXsKCQl0ZXhDb2xvciA9IHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMCwgdlRleHR1cmVDb29yZHNfUzApOwoJfQoJb3V0cHV0Q29sb3JfUzAgPSBvdXRwdXRDb2xvcl9TMCAqIHRleENvbG9yOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACgAAAGluUG9zaXRpb24AAA8AAABpblRleHR1cmVDb29yZHMAAAAAAA==","GZIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAHIBIA5HZ2CAAAAAAAYAAAAAAAAAQAAAAERRAAAAAAAABAAAAABYECBQAAAAAAAABAAAAAJAIAAIAAAAAKBBIAIIDAAAAAAAAAAADGAAAAAAAEAAAAAIDEAA":"DAAAAExTS1POAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzA7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfM19TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzFfYzApICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAAAAgQwAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzBfYzBfYzA7CnVuaWZvcm0gaGFsZjR4NCB1Y29lZmZpY2llbnRzX1MxX2MwX2MwOwp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzA7CnNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMTsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc18zX1MwOwpoYWxmNCBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwX2MwX2MwKGhhbGY0IF9pbnB1dCwgZmxvYXQyIF9jb29yZHMpIAp7CglyZXR1cm4gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MxLCBfY29vcmRzKTsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzFfYzBfYzBfYzAoaGFsZjQgX2lucHV0LCBmbG9hdDIgX2Nvb3JkcykgCnsKCXJldHVybiBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwX2MwX2MwKF9pbnB1dCwgZmxvYXQzeDIodW1hdHJpeF9TMV9jMF9jMF9jMCkgKiBfY29vcmRzLnh5MSk7Cn0KaGFsZjQgQmljdWJpY19TMV9jMF9jMChoYWxmNCBfaW5wdXQpIAp7CglmbG9hdDIgY29vcmQgPSB2VHJhbnNmb3JtZWRDb29yZHNfM19TMCAtIGZsb2F0MigwLjUpOwoJaGFsZjIgZiA9IGhhbGYyKGZyYWN0KGNvb3JkKSk7Cgljb29yZCArPSAwLjUgLSBmOwoJaGFsZjQgd3ggPSB1Y29lZmZpY2llbnRzX1MxX2MwX2MwICogaGFsZjQoMS4wLCBmLngsIGYueCAqIGYueCwgZi54ICogZi54ICogZi54KTsKCWhhbGY0IHd5ID0gdWNvZWZmaWNpZW50c19TMV9jMF9jMCAqIGhhbGY0KDEuMCwgZi55LCBmLnkgKiBmLnksIGYueSAqIGYueSAqIGYueSk7CgloYWxmNCByb3dDb2xvcnNbNF07Cglyb3dDb2xvcnNbMF0gPSBNYXRyaXhFZmZlY3RfUzFfYzBfYzBfYzAoX2lucHV0LCBjb29yZCArIGZsb2F0MigtMSwgLTEpKTsKCXJvd0NvbG9yc1sxXSA9IE1hdHJpeEVmZmVjdF9TMV9jMF9jMF9jMChfaW5wdXQsIGNvb3JkICsgZmxvYXQyKDAsIC0xKSk7Cglyb3dDb2xvcnNbMl0gPSBNYXRyaXhFZmZlY3RfUzFfYzBfYzBfYzAoX2lucHV0LCBjb29yZCArIGZsb2F0MigxLCAtMSkpOwoJcm93Q29sb3JzWzNdID0gTWF0cml4RWZmZWN0X1MxX2MwX2MwX2MwKF9pbnB1dCwgY29vcmQgKyBmbG9hdDIoMiwgLTEpKTsKCWhhbGY0IHMwID0gd3gueCAqIHJvd0NvbG9yc1swXSArIHd4LnkgKiByb3dDb2xvcnNbMV0gKyB3eC56ICogcm93Q29sb3JzWzJdICsgd3gudyAqIHJvd0NvbG9yc1szXTsKCXJvd0NvbG9yc1swXSA9IE1hdHJpeEVmZmVjdF9TMV9jMF9jMF9jMChfaW5wdXQsIGNvb3JkICsgZmxvYXQyKC0xLCAwKSk7Cglyb3dDb2xvcnNbMV0gPSBNYXRyaXhFZmZlY3RfUzFfYzBfYzBfYzAoX2lucHV0LCBjb29yZCArIGZsb2F0MigwLCAwKSk7Cglyb3dDb2xvcnNbMl0gPSBNYXRyaXhFZmZlY3RfUzFfYzBfYzBfYzAoX2lucHV0LCBjb29yZCArIGZsb2F0MigxLCAwKSk7Cglyb3dDb2xvcnNbM10gPSBNYXRyaXhFZmZlY3RfUzFfYzBfYzBfYzAoX2lucHV0LCBjb29yZCArIGZsb2F0MigyLCAwKSk7CgloYWxmNCBzMSA9IHd4LnggKiByb3dDb2xvcnNbMF0gKyB3eC55ICogcm93Q29sb3JzWzFdICsgd3gueiAqIHJvd0NvbG9yc1syXSArIHd4LncgKiByb3dDb2xvcnNbM107Cglyb3dDb2xvcnNbMF0gPSBNYXRyaXhFZmZlY3RfUzFfYzBfYzBfYzAoX2lucHV0LCBjb29yZCArIGZsb2F0MigtMSwgMSkpOwoJcm93Q29sb3JzWzFdID0gTWF0cml4RWZmZWN0X1MxX2MwX2MwX2MwKF9pbnB1dCwgY29vcmQgKyBmbG9hdDIoMCwgMSkpOwoJcm93Q29sb3JzWzJdID0gTWF0cml4RWZmZWN0X1MxX2MwX2MwX2MwKF9pbnB1dCwgY29vcmQgKyBmbG9hdDIoMSwgMSkpOwoJcm93Q29sb3JzWzNdID0gTWF0cml4RWZmZWN0X1MxX2MwX2MwX2MwKF9pbnB1dCwgY29vcmQgKyBmbG9hdDIoMiwgMSkpOwoJaGFsZjQgczIgPSB3eC54ICogcm93Q29sb3JzWzBdICsgd3gueSAqIHJvd0NvbG9yc1sxXSArIHd4LnogKiByb3dDb2xvcnNbMl0gKyB3eC53ICogcm93Q29sb3JzWzNdOwoJcm93Q29sb3JzWzBdID0gTWF0cml4RWZmZWN0X1MxX2MwX2MwX2MwKF9pbnB1dCwgY29vcmQgKyBmbG9hdDIoLTEsIDIpKTsKCXJvd0NvbG9yc1sxXSA9IE1hdHJpeEVmZmVjdF9TMV9jMF9jMF9jMChfaW5wdXQsIGNvb3JkICsgZmxvYXQyKDAsIDIpKTsKCXJvd0NvbG9yc1syXSA9IE1hdHJpeEVmZmVjdF9TMV9jMF9jMF9jMChfaW5wdXQsIGNvb3JkICsgZmxvYXQyKDEsIDIpKTsKCXJvd0NvbG9yc1szXSA9IE1hdHJpeEVmZmVjdF9TMV9jMF9jMF9jMChfaW5wdXQsIGNvb3JkICsgZmxvYXQyKDIsIDIpKTsKCWhhbGY0IHMzID0gd3gueCAqIHJvd0NvbG9yc1swXSArIHd4LnkgKiByb3dDb2xvcnNbMV0gKyB3eC56ICogcm93Q29sb3JzWzJdICsgd3gudyAqIHJvd0NvbG9yc1szXTsKCWhhbGY0IGJpY3ViaWNDb2xvciA9IHd5LnggKiBzMCArIHd5LnkgKiBzMSArIHd5LnogKiBzMiArIHd5LncgKiBzMzsKCWJpY3ViaWNDb2xvci5hID0gc2F0dXJhdGUoYmljdWJpY0NvbG9yLmEpOwoJYmljdWJpY0NvbG9yLnJnYiA9IG1heChoYWxmMygwLjApLCBtaW4oYmljdWJpY0NvbG9yLnJnYiwgYmljdWJpY0NvbG9yLmFhYSkpOwoJcmV0dXJuIGJpY3ViaWNDb2xvcjsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIEJpY3ViaWNfUzFfYzBfYzAoX2lucHV0KTsKfQpoYWxmNCBEaXNhYmxlQ292ZXJhZ2VBc0FscGhhX1MxKGhhbGY0IF9pbnB1dCkgCnsKCV9pbnB1dCA9IE1hdHJpeEVmZmVjdF9TMV9jMChfaW5wdXQpOwoJaGFsZjQgX3RtcF8wX2luQ29sb3IgPSBfaW5wdXQ7CglyZXR1cm4gaGFsZjQoX2lucHV0KTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IERpc2FibGVDb3ZlcmFnZUFzQWxwaGFfUzEob3V0cHV0Q29sb3JfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","B2AAQAAABQAAIAABBYAAB7777777777774ABICAAAAAAAAAAAAAABGABAAAAAEAAAAAIBEABAAAAA":"DAAAAExTS1NZAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgaW5Qb3NpdGlvbjsKaW4gaGFsZiBpbkNvdmVyYWdlOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmIHZpbkNvdmVyYWdlX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBEZWZhdWx0R2VvbWV0cnlQcm9jZXNzb3IKCWZsb2F0MiBfdG1wXzFfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247Cgl2aW5Db3ZlcmFnZV9TMCA9IGluQ292ZXJhZ2U7Cglza19Qb3NpdGlvbiA9IF90bXBfMV9pblBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAAAJgBAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKdW5pZm9ybSBoYWxmNCB1Q29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gaGFsZiB2aW5Db3ZlcmFnZV9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIERlZmF1bHRHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHVDb2xvcl9TMDsKCWhhbGYgYWxwaGEgPSAxLjA7CglhbHBoYSA9IHZpbkNvdmVyYWdlX1MwOwoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChhbHBoYSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAoAAABpblBvc2l0aW9uAAAKAAAAaW5Db3ZlcmFnZQAAAAAAAA==","GZIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAJIBBKQPNFTIACAAADQOAIAAAAAWFBZKQHMFVIAAAAADQOAIAAAACI6DQCAAAAACQIKACCAYAA4DQAAAAAAZQAAAAAABAAAAACAZAAAAAAA":"DAAAAExTS1PIAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfMl9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzEpICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAAkJAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKY29uc3QgaW50IGtNYXhMb29wTGltaXRfUzFfYzAgPSAzOwp1bmlmb3JtIGhhbGY0IHVib3JkZXJfUzFfYzBfYzBfYzA7CnVuaWZvcm0gZmxvYXQ0IHVzdWJzZXRfUzFfYzBfYzBfYzA7CnVuaWZvcm0gZmxvYXQyIHVpZGltc19TMV9jMF9jMF9jMDsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxX2MwX2MwOwp1bmlmb3JtIGhhbGY0IHVrZXJuZWxfUzFfYzBbN107CnVuaWZvcm0gaGFsZjQgdW9mZnNldHNfUzFfYzBbMTRdOwp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CnNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMTsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwpoYWxmNCBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwX2MwKGhhbGY0IF9pbnB1dCwgZmxvYXQyIF9jb29yZHMpIAp7CglmbG9hdDIgaW5Db29yZCA9IF9jb29yZHM7CglmbG9hdDIgc3Vic2V0Q29vcmQ7CglzdWJzZXRDb29yZC54ID0gaW5Db29yZC54OwoJc3Vic2V0Q29vcmQueSA9IGluQ29vcmQueTsKCWZsb2F0MiBjbGFtcGVkQ29vcmQ7CgljbGFtcGVkQ29vcmQgPSBzdWJzZXRDb29yZDsKCWhhbGY0IHRleHR1cmVDb2xvciA9IHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMSwgKGNsYW1wZWRDb29yZCkgKiB1aWRpbXNfUzFfYzBfYzBfYzApOwoJZmxvYXQgc25hcHBlZFggPSBmbG9vcihpbkNvb3JkLnggKyAwLjAwMSkgKyAwLjU7CglpZiAoc25hcHBlZFggPCB1c3Vic2V0X1MxX2MwX2MwX2MwLnggfHwgc25hcHBlZFggPiB1c3Vic2V0X1MxX2MwX2MwX2MwLnopIAoJewoJCXRleHR1cmVDb2xvciA9IHVib3JkZXJfUzFfYzBfYzBfYzA7Cgl9CglmbG9hdCBzbmFwcGVkWSA9IGZsb29yKGluQ29vcmQueSArIDAuMDAxKSArIDAuNTsKCWlmIChzbmFwcGVkWSA8IHVzdWJzZXRfUzFfYzBfYzBfYzAueSB8fCBzbmFwcGVkWSA+IHVzdWJzZXRfUzFfYzBfYzBfYzAudykgCgl7CgkJdGV4dHVyZUNvbG9yID0gdWJvcmRlcl9TMV9jMF9jMF9jMDsKCX0KCXJldHVybiB0ZXh0dXJlQ29sb3I7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxX2MwX2MwKGhhbGY0IF9pbnB1dCwgZmxvYXQyIF9jb29yZHMpIAp7CglyZXR1cm4gVGV4dHVyZUVmZmVjdF9TMV9jMF9jMF9jMChfaW5wdXQsIGZsb2F0M3gyKHVtYXRyaXhfUzFfYzBfYzApICogX2Nvb3Jkcy54eTEpOwp9CmhhbGY0IHJ1bnRpbWVfc2hhZGVyX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJZmxvYXQyIF90bXBfMV9jb29yZHMgPSB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKCWhhbGY0IHN1bSA9IGhhbGY0KDAuMCk7Cglmb3IgKGludCBpID0gMDtpIDwga01heExvb3BMaW1pdF9TMV9jMDsgKytpKSAKCXsKCQloYWxmNCBrID0gdWtlcm5lbF9TMV9jMFtpXTsKCQloYWxmNCBvID0gdW9mZnNldHNfUzFfYzBbMiAqIGldOwoJCXN1bSArPSBrLnggKiBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoX3RtcF8wX2luQ29sb3IsIF90bXBfMV9jb29yZHMgKyBmbG9hdDIoby54eSkpOwoJCXN1bSArPSBrLnkgKiBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoX3RtcF8wX2luQ29sb3IsIF90bXBfMV9jb29yZHMgKyBmbG9hdDIoby56dykpOwoJCW8gPSB1b2Zmc2V0c19TMV9jMFsyICogaSArIDFdOwoJCXN1bSArPSBrLnogKiBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoX3RtcF8wX2luQ29sb3IsIF90bXBfMV9jb29yZHMgKyBmbG9hdDIoby54eSkpOwoJCXN1bSArPSBrLncgKiBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoX3RtcF8wX2luQ29sb3IsIF90bXBfMV9jb29yZHMgKyBmbG9hdDIoby56dykpOwoJfQoJcmV0dXJuIGhhbGY0KHN1bSk7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBydW50aW1lX3NoYWRlcl9TMV9jMChfaW5wdXQpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gTWF0cml4RWZmZWN0X1MxKG91dHB1dENvbG9yX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRfUzEgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAgAAABwb3NpdGlvbgUAAABjb2xvcgAAAAoAAABsb2NhbENvb3JkAAAAAAAA","GYJAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAQAAAAAAQQGAAZAADIAAAAAJKLCRQQAAAAAAMAAAAACAAAAAIAAAAALAIQEVFRIYIAAAAAAGAAAAABAAAAAAAAAAAAAGABQAAAAEAAAAAAAEEBQA":"DAAAAExTS1MwAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgcG9zaXRpb247CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmxvY2FsQ29vcmRfUzAgPSBsb2NhbENvb3JkOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgEAAACEBgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCmNvbnN0IGludCBrRmlsbEJXX1MxX2MwID0gMDsKY29uc3QgaW50IGtGaWxsQUFfUzFfYzAgPSAxOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQldfUzFfYzAgPSAyOwp1bmlmb3JtIGZsb2F0NCB1ZWxsaXBzZV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdXNjYWxlX1MxX2MwOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQyIHZsb2NhbENvb3JkX1MwOwpoYWxmNCBFbGxpcHNlX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJZmxvYXQyIGQgPSBza19GcmFnQ29vcmQueHkgLSB1ZWxsaXBzZV9TMV9jMC54eTsKCWlmIChib29sKGludCgwKSkpIAoJewoJCWQgKj0gdXNjYWxlX1MxX2MwLnk7Cgl9CglmbG9hdDIgWiA9IGQgKiB1ZWxsaXBzZV9TMV9jMC56dzsKCWZsb2F0IGltcGxpY2l0ID0gZG90KFosIGQpIC0gMS4wOwoJZmxvYXQgZ3JhZF9kb3QgPSA0LjAgKiBkb3QoWiwgWik7CglpZiAoYm9vbChpbnQoMCkpKSAKCXsKCQlncmFkX2RvdCA9IG1heChncmFkX2RvdCwgNi4xMDM2ZS0wNSk7Cgl9CgllbHNlIAoJewoJCWdyYWRfZG90ID0gbWF4KGdyYWRfZG90LCAxLjE3NTVlLTM4KTsKCX0KCWZsb2F0IGFwcHJveF9kaXN0ID0gaW1wbGljaXQgKiBpbnZlcnNlc3FydChncmFkX2RvdCk7CglpZiAoYm9vbChpbnQoMCkpKSAKCXsKCQlhcHByb3hfZGlzdCAqPSB1c2NhbGVfUzFfYzAueDsKCX0KCWhhbGYgYWxwaGE7CglpZiAoaW50KDEpID09IGtGaWxsQldfUzFfYzApIAoJewoJCWFscGhhID0gaGFsZihhcHByb3hfZGlzdCA+IDAuMCA/IDAuMCA6IDEuMCk7Cgl9CgllbHNlIGlmIChpbnQoMSkgPT0ga0ZpbGxBQV9TMV9jMCkgCgl7CgkJYWxwaGEgPSBzYXR1cmF0ZSgwLjUgLSBoYWxmKGFwcHJveF9kaXN0KSk7Cgl9CgllbHNlIGlmIChpbnQoMSkgPT0ga0ludmVyc2VGaWxsQldfUzFfYzApIAoJewoJCWFscGhhID0gaGFsZihhcHByb3hfZGlzdCA+IDAuMCk7Cgl9CgllbHNlIAoJewoJCWFscGhhID0gc2F0dXJhdGUoMC41ICsgaGFsZihhcHByb3hfZGlzdCkpOwoJfQoJcmV0dXJuIGhhbGY0KGhhbGY0KGFscGhhKSk7Cn0KaGFsZjQgQmxlbmRfUzEoaGFsZjQgX3NyYywgaGFsZjQgX2RzdCkgCnsKCXJldHVybiBibGVuZF9tb2R1bGF0ZShFbGxpcHNlX1MxX2MwKF9zcmMpLCBfc3JjKTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMCA9IGhhbGY0KDEpOwoJZmxvYXQyIHRleENvb3JkOwoJdGV4Q29vcmQgPSB2bG9jYWxDb29yZF9TMDsKCW91dHB1dENvbG9yX1MwID0gKGJsZW5kX21vZHVsYXRlKHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMCwgdGV4Q29vcmQpLCBoYWxmNCgxKSkpOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IEJsZW5kX1MxKG91dHB1dENvdmVyYWdlX1MwLCBoYWxmNCgxKSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAIAAAAcG9zaXRpb24KAAAAbG9jYWxDb29yZAAAAAAAAA==","GZIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAHIBIA5HZ2CAAAAAAAEAACAAAAASBEAAQAAAAAUCCQAQQGAABAAAAAAAAGMAAAAAAAIAAAAAQGIAAAAAAA":"DAAAAExTS1POAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzA7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2Y29sb3JfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfM19TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzFfYzApICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAAAAlgQAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQp1bmlmb3JtIGZsb2F0NCB1Y2xhbXBfUzFfYzBfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMDsKc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MxOwpub3BlcnNwZWN0aXZlIGluIGhhbGY0IHZjb2xvcl9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzNfUzA7CmhhbGY0IFRleHR1cmVFZmZlY3RfUzFfYzBfYzAoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGluQ29vcmQgPSB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKCWZsb2F0MiBzdWJzZXRDb29yZDsKCXN1YnNldENvb3JkLnggPSBpbkNvb3JkLng7CglzdWJzZXRDb29yZC55ID0gaW5Db29yZC55OwoJZmxvYXQyIGNsYW1wZWRDb29yZDsKCWNsYW1wZWRDb29yZC54ID0gY2xhbXAoc3Vic2V0Q29vcmQueCwgdWNsYW1wX1MxX2MwX2MwLngsIHVjbGFtcF9TMV9jMF9jMC56KTsKCWNsYW1wZWRDb29yZC55ID0gc3Vic2V0Q29vcmQueTsKCWhhbGY0IHRleHR1cmVDb2xvciA9IHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMSwgY2xhbXBlZENvb3JkKTsKCXJldHVybiB0ZXh0dXJlQ29sb3I7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwKF9pbnB1dCk7Cn0KaGFsZjQgRGlzYWJsZUNvdmVyYWdlQXNBbHBoYV9TMShoYWxmNCBfaW5wdXQpIAp7CglfaW5wdXQgPSBNYXRyaXhFZmZlY3RfUzFfYzAoX2lucHV0KTsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJcmV0dXJuIGhhbGY0KF9pbnB1dCk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBEaXNhYmxlQ292ZXJhZ2VBc0FscGhhX1MxKG91dHB1dENvbG9yX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRfUzEgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","GZIACAAAABQAAGAAAQ4AAAAAGQQAARC4GAAAIOCAAD6P7777777777YDAAAAAAAAAAAJQBBYGQ467YIAAAAAAQAAAAAMACTRNBZN5QYBAAAAAAAAAAAIAALIAAAAB4FJEIEKOAAAAAMAAAAAUAAQAADAWB7EXCYCAAAGAAAAAAAACAAAQAK7DKJCBCTQAAAADAAAAAAAAAAAAYCADIAAAAAG5O33IKAAAAAAMAAAAAIAAAAAABMJDQP2FUWQUAAAQAAQAAAAAAAAAADGAAAAAAAEAAAAAIDEAAAAAAA":"DAAAAExTS1M7AgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQgY292ZXJhZ2U7CmluIGhhbGY0IGNvbG9yOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmNvbG9yX1MwOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdCB2Y292ZXJhZ2VfUzA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDIgcG9zaXRpb24gPSBwb3NpdGlvbi54eTsKCXZjb2xvcl9TMCA9IGNvbG9yOwoJdmNvdmVyYWdlX1MwID0gY292ZXJhZ2U7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgABAAAAxiIAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQpmbG9hdDQgZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzA7CmZsb2F0NCBmcmFnQ29sb3JfUzFfYzA7CmZsb2F0IHVfYWxwaGFfUzFfYzA7CmZsb2F0IHVfc3BhcmtsZV9hbHBoYV9TMV9jMDsKZmxvYXQgdV9ibHVyX1MxX2MwOwpmbG9hdCB1X3JhZGl1c19zY2FsZV9TMV9jMDsKY29uc3QgaW50IGtGaWxsQldfUzJfYzAgPSAwOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQldfUzJfYzAgPSAyOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQUFfUzJfYzAgPSAzOwpjb25zdCBpbnQga0ZpbGxBQV9TMl9jMV9jMCA9IDE7CmNvbnN0IGludCBrSW52ZXJzZUZpbGxCV19TMl9jMV9jMCA9IDI7CmNvbnN0IGludCBrSW52ZXJzZUZpbGxBQV9TMl9jMV9jMCA9IDM7CnVuaWZvcm0gZmxvYXQ0IHVfY29sb3JfUzFfYzA7CnVuaWZvcm0gZmxvYXQ0IHVfY29tcG9zaXRlXzFfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2VudGVyX1MxX2MwOwp1bmlmb3JtIGZsb2F0IHVfbWF4X3JhZGl1c19TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yZXNvbHV0aW9uX3NjYWxlX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X25vaXNlX3NjYWxlX1MxX2MwOwp1bmlmb3JtIGZsb2F0IHVfbm9pc2VfcGhhc2VfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2lyY2xlMV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jaXJjbGUyX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NpcmNsZTNfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcm90YXRpb24xX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3JvdGF0aW9uMl9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yb3RhdGlvbjNfUzFfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKdW5pZm9ybSBmbG9hdDQgdXJlY3RVbmlmb3JtX1MyX2MwOwp1bmlmb3JtIGZsb2F0NCB1Y2lyY2xlX1MyX2MxX2MwOwpub3BlcnNwZWN0aXZlIGluIGhhbGY0IHZjb2xvcl9TMDsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdCB2Y292ZXJhZ2VfUzA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwpmbG9hdDIgRkxUX2ZsdXR0ZXJfbG9jYWxfRmx1dHRlckZyYWdDb29yZF9TMV9jMCgpOwpmbG9hdDJ4MiBGTFRfZmx1dHRlcl9sb2NhbF9yb3RhdGUyZF9TMV9jMChmbG9hdDIgcmFkKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgYmx1cik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKGZsb2F0MiByZXNvbHV0aW9uLCBpbm91dCBmbG9hdDIgcCwgZmxvYXQyIHh5LCBmbG9hdDIgcm90YXRpb24sIGZsb2F0IGNlbGxfZGlhbWV0ZXIpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90dXJidWxlbmNlX1MxX2MwKGZsb2F0MiB1dik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfcmluZ19TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCB0aGlja25lc3MsIGZsb2F0IGJsdXIpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90cmlhbmdsZV9ub2lzZV9TMV9jMChpbm91dCBmbG9hdDIgbik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChmbG9hdCB2LCBmbG9hdCBsLCBmbG9hdCBoKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc3BhcmtsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0IHQpOwp2b2lkIEZMVF9tYWluX1MxX2MwKCk7CmZsb2F0MiBGTFRfZmx1dHRlcl9sb2NhbF9GbHV0dGVyRnJhZ0Nvb3JkX1MxX2MwKCkgCnsKCXJldHVybiBmbHV0dGVyX0ZyYWdDb29yZF9TMV9jMC54eTsKfQpmbG9hdDJ4MiBGTFRfZmx1dHRlcl9sb2NhbF9yb3RhdGUyZF9TMV9jMChmbG9hdDIgcmFkKSAKewoJcmV0dXJuIGZsb2F0MngyKHJhZC54LCAtcmFkLnksIHJhZC55LCByYWQueCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgYmx1cikgCnsKCWZsb2F0IGJsdXJfaGFsZiA9IGJsdXIgKiAwLjU7CglmbG9hdCBkID0gZGlzdGFuY2UodXYsIHh5KTsKCXJldHVybiAxLjAgLSBzbW9vdGhzdGVwKDEuMCAtIGJsdXJfaGFsZiwgMS4wICsgYmx1cl9oYWxmLCBkIC8gcmFkaXVzKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChmbG9hdDIgcmVzb2x1dGlvbiwgaW5vdXQgZmxvYXQyIHAsIGZsb2F0MiB4eSwgZmxvYXQyIHJvdGF0aW9uLCBmbG9hdCBjZWxsX2RpYW1ldGVyKSAKewoJZmxvYXQyIHBhcmFtID0gcm90YXRpb247CglwID0gRkxUX2ZsdXR0ZXJfbG9jYWxfcm90YXRlMmRfUzFfYzAocGFyYW0pICogKHh5IC0gcCkgKyB4eTsKCXAgPSBtb2QocCwgZmxvYXQyKGNlbGxfZGlhbWV0ZXIpKSAvIHJlc29sdXRpb247CglmbG9hdCBjZWxsX3V2ID0gKGNlbGxfZGlhbWV0ZXIgLyByZXNvbHV0aW9uLnkpICogMC41OwoJZmxvYXQgciA9IDAuNjUgKiBjZWxsX3V2OwoJZmxvYXQyIHBhcmFtXzEgPSBwOwoJZmxvYXQyIHBhcmFtXzIgPSBmbG9hdDIoY2VsbF91dik7CglmbG9hdCBwYXJhbV8zID0gcjsKCWZsb2F0IHBhcmFtXzQgPSByICogNTAuMDsKCXJldHVybiBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zLCBwYXJhbV80KTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90dXJidWxlbmNlX1MxX2MwKGZsb2F0MiB1dikgCnsKCWZsb2F0MiB1dl9zY2FsZSA9IHV2ICogZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW0gPSBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbV8xID0gdXZfc2NhbGU7CglmbG9hdDIgcGFyYW1fMiA9IHVfY2lyY2xlMV9TMV9jMDsKCWZsb2F0MiBwYXJhbV8zID0gdV9yb3RhdGlvbjFfUzFfYzA7CglmbG9hdCBwYXJhbV80ID0gMC4xNzsKCWZsb2F0IF8zMTkgPSBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChwYXJhbSwgcGFyYW1fMSwgcGFyYW1fMiwgcGFyYW1fMywgcGFyYW1fNCk7CglmbG9hdCBnMSA9IF8zMTk7CglmbG9hdDIgcGFyYW1fNSA9IGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtXzYgPSB1dl9zY2FsZTsKCWZsb2F0MiBwYXJhbV83ID0gdV9jaXJjbGUyX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzggPSB1X3JvdGF0aW9uMl9TMV9jMDsKCWZsb2F0IHBhcmFtXzkgPSAwLjI7CglmbG9hdCBfMzMxID0gRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAocGFyYW1fNSwgcGFyYW1fNiwgcGFyYW1fNywgcGFyYW1fOCwgcGFyYW1fOSk7CglmbG9hdCBnMiA9IF8zMzE7CglmbG9hdDIgcGFyYW1fMTAgPSBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbV8xMSA9IHV2X3NjYWxlOwoJZmxvYXQyIHBhcmFtXzEyID0gdV9jaXJjbGUzX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzEzID0gdV9yb3RhdGlvbjNfUzFfYzA7CglmbG9hdCBwYXJhbV8xNCA9IDAuMjc1OwoJZmxvYXQgXzM0NCA9IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKHBhcmFtXzEwLCBwYXJhbV8xMSwgcGFyYW1fMTIsIHBhcmFtXzEzLCBwYXJhbV8xNCk7CglmbG9hdCBnMyA9IF8zNDQ7CglmbG9hdCB2ID0gKChnMSAqIGcxICsgZzIpIC0gZzMpICogMC41OwoJcmV0dXJuIGNsYW1wKDAuNDUgKyAwLjggKiB2LCAwLjAsIDEuMCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9yaW5nX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IHRoaWNrbmVzcywgZmxvYXQgYmx1cikgCnsKCWZsb2F0MiBwYXJhbSA9IHV2OwoJZmxvYXQyIHBhcmFtXzEgPSB4eTsKCWZsb2F0IHBhcmFtXzIgPSByYWRpdXMgKyB0aGlja25lc3M7CglmbG9hdCBwYXJhbV8zID0gYmx1cjsKCWZsb2F0IGNpcmNsZV9vdXRlciA9IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtLCBwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zKTsKCWZsb2F0MiBwYXJhbV80ID0gdXY7CglmbG9hdDIgcGFyYW1fNSA9IHh5OwoJZmxvYXQgcGFyYW1fNiA9IG1heChyYWRpdXMgLSB0aGlja25lc3MsIDAuMCk7CglmbG9hdCBwYXJhbV83ID0gYmx1cjsKCWZsb2F0IGNpcmNsZV9pbm5lciA9IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtXzQsIHBhcmFtXzUsIHBhcmFtXzYsIHBhcmFtXzcpOwoJcmV0dXJuIGNsYW1wKGNpcmNsZV9vdXRlciAtIGNpcmNsZV9pbm5lciwgMC4wLCAxLjApOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RyaWFuZ2xlX25vaXNlX1MxX2MwKGlub3V0IGZsb2F0MiBuKSAKewoJbiA9IGZyYWN0KG4gKiBmbG9hdDIoNS4zOTg3LCA1LjQ0MjEpKTsKCW4gKz0gZmxvYXQyKGRvdChuLnl4LCBuICsgZmxvYXQyKDIxLjUzNTEsIDE0LjMxMzcpKSk7CglmbG9hdCB4eSA9IG4ueCAqIG4ueTsKCXJldHVybiAoZnJhY3QoeHkgKiA5NS40MzA3KSArIGZyYWN0KHh5ICogNzUuMDQ5NjEpKSAtIDEuMDsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAoZmxvYXQgdiwgZmxvYXQgbCwgZmxvYXQgaCkgCnsKCXJldHVybiBzdGVwKGwsIHYpICogKDEuMCAtIHN0ZXAoaCwgdikpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NwYXJrbGVfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdCB0KSAKewoJZmxvYXQyIHBhcmFtID0gdXY7CglmbG9hdCBfMjQyID0gRkxUX2ZsdXR0ZXJfbG9jYWxfdHJpYW5nbGVfbm9pc2VfUzFfYzAocGFyYW0pOwoJZmxvYXQgbiA9IF8yNDI7CglmbG9hdCBwYXJhbV8xID0gbjsKCWZsb2F0IHBhcmFtXzIgPSAwLjA7CglmbG9hdCBwYXJhbV8zID0gMC4wNTsKCWZsb2F0IHMgPSBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAocGFyYW1fMSwgcGFyYW1fMiwgcGFyYW1fMyk7CglmbG9hdCBwYXJhbV80ID0gbiArIHNpbigzLjE0MTU5Mjc0ICogKHQgKyAwLjM1KSk7CglmbG9hdCBwYXJhbV81ID0gMC4xOwoJZmxvYXQgcGFyYW1fNiA9IDAuMTU7CglzICs9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV80LCBwYXJhbV81LCBwYXJhbV82KTsKCWZsb2F0IHBhcmFtXzcgPSBuICsgc2luKDMuMTQxNTkyNzQgKiAodCArIDAuNykpOwoJZmxvYXQgcGFyYW1fOCA9IDAuMjsKCWZsb2F0IHBhcmFtXzkgPSAwLjI1OwoJcyArPSBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAocGFyYW1fNywgcGFyYW1fOCwgcGFyYW1fOSk7CglmbG9hdCBwYXJhbV8xMCA9IG4gKyBzaW4oMy4xNDE1OTI3NCAqICh0ICsgMS4wNSkpOwoJZmxvYXQgcGFyYW1fMTEgPSAwLjM7CglmbG9hdCBwYXJhbV8xMiA9IDAuMzU7CglzICs9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV8xMCwgcGFyYW1fMTEsIHBhcmFtXzEyKTsKCXJldHVybiBjbGFtcChzLCAwLjAsIDEuMCkgKiAwLjU1Owp9CnZvaWQgRkxUX21haW5fUzFfYzAoKSAKewoJdV9hbHBoYV9TMV9jMCA9IHVfY29tcG9zaXRlXzFfUzFfYzAueDsKCXVfc3BhcmtsZV9hbHBoYV9TMV9jMCA9IHVfY29tcG9zaXRlXzFfUzFfYzAueTsKCXVfYmx1cl9TMV9jMCA9IHVfY29tcG9zaXRlXzFfUzFfYzAuejsKCXVfcmFkaXVzX3NjYWxlX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC53OwoJZmxvYXQyIHAgPSBGTFRfZmx1dHRlcl9sb2NhbF9GbHV0dGVyRnJhZ0Nvb3JkX1MxX2MwKCk7CglmbG9hdDIgdXZfMSA9IHAgKiB1X3Jlc29sdXRpb25fc2NhbGVfUzFfYzA7CglmbG9hdDIgZGVuc2l0eV91diA9IHV2XzEgLSBtb2QocCwgdV9ub2lzZV9zY2FsZV9TMV9jMCk7CglmbG9hdCByYWRpdXMgPSB1X21heF9yYWRpdXNfUzFfYzAgKiB1X3JhZGl1c19zY2FsZV9TMV9jMDsKCWZsb2F0MiBwYXJhbV8xMyA9IHV2XzE7CglmbG9hdCB0dXJidWxlbmNlID0gRkxUX2ZsdXR0ZXJfbG9jYWxfdHVyYnVsZW5jZV9TMV9jMChwYXJhbV8xMyk7CglmbG9hdDIgcGFyYW1fMTQgPSBwOwoJZmxvYXQyIHBhcmFtXzE1ID0gdV9jZW50ZXJfUzFfYzA7CglmbG9hdCBwYXJhbV8xNiA9IHJhZGl1czsKCWZsb2F0IHBhcmFtXzE3ID0gMC4wNSAqIHVfbWF4X3JhZGl1c19TMV9jMDsKCWZsb2F0IHBhcmFtXzE4ID0gdV9ibHVyX1MxX2MwOwoJZmxvYXQgcmluZyA9IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfcmluZ19TMV9jMChwYXJhbV8xNCwgcGFyYW1fMTUsIHBhcmFtXzE2LCBwYXJhbV8xNywgcGFyYW1fMTgpOwoJZmxvYXQyIHBhcmFtXzE5ID0gZGVuc2l0eV91djsKCWZsb2F0IHBhcmFtXzIwID0gdV9ub2lzZV9waGFzZV9TMV9jMDsKCWZsb2F0IHNwYXJrbGUgPSAoKEZMVF9mbHV0dGVyX2xvY2FsX3NwYXJrbGVfUzFfYzAocGFyYW1fMTksIHBhcmFtXzIwKSAqIHJpbmcpICogdHVyYnVsZW5jZSkgKiB1X3NwYXJrbGVfYWxwaGFfUzFfYzA7CglmbG9hdDIgcGFyYW1fMjEgPSBwOwoJZmxvYXQyIHBhcmFtXzIyID0gdV9jZW50ZXJfUzFfYzA7CglmbG9hdCBwYXJhbV8yMyA9IHJhZGl1czsKCWZsb2F0IHBhcmFtXzI0ID0gdV9ibHVyX1MxX2MwOwoJZmxvYXQgd2F2ZV9hbHBoYSA9IChGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChwYXJhbV8yMSwgcGFyYW1fMjIsIHBhcmFtXzIzLCBwYXJhbV8yNCkgKiB1X2FscGhhX1MxX2MwKSAqIHVfY29sb3JfUzFfYzAudzsKCWZsb2F0NCB3YXZlX2NvbG9yID0gZmxvYXQ0KHVfY29sb3JfUzFfYzAueHl6ICogd2F2ZV9hbHBoYSwgd2F2ZV9hbHBoYSk7CglmcmFnQ29sb3JfUzFfYzAgPSBtaXgod2F2ZV9jb2xvciwgZmxvYXQ0KDEuMCksIGZsb2F0NChzcGFya2xlKSk7Cn0KaGFsZjQgcnVudGltZV9zaGFkZXJfUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF8wX2luQ29sb3IgPSBfaW5wdXQ7CglmbG9hdDIgX3RtcF8xX2Nvb3JkcyA9IHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwoJZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzAgPSBmbG9hdDQoX3RtcF8xX2Nvb3JkcywgMC4wLCAwLjApOwoJRkxUX21haW5fUzFfYzAoKTsKCXJldHVybiBoYWxmNChoYWxmNChmcmFnQ29sb3JfUzFfYzApKTsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIHJ1bnRpbWVfc2hhZGVyX1MxX2MwKF9pbnB1dCk7Cn0KaGFsZjQgUmVjdF9TMl9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzJfaW5Db2xvciA9IF9pbnB1dDsKCWhhbGYgY292ZXJhZ2U7CglpZiAoaW50KDEpID09IGtGaWxsQldfUzJfYzAgfHwgaW50KDEpID09IGtJbnZlcnNlRmlsbEJXX1MyX2MwKSAKCXsKCQljb3ZlcmFnZSA9IGhhbGYoYWxsKGdyZWF0ZXJUaGFuKGZsb2F0NChza19GcmFnQ29vcmQueHksIHVyZWN0VW5pZm9ybV9TMl9jMC56dyksIGZsb2F0NCh1cmVjdFVuaWZvcm1fUzJfYzAueHksIHNrX0ZyYWdDb29yZC54eSkpKSk7Cgl9CgllbHNlIAoJewoJCWhhbGY0IGRpc3RzNCA9IHNhdHVyYXRlKGhhbGY0KDEuMCwgMS4wLCAtMS4wLCAtMS4wKSAqIGhhbGY0KHNrX0ZyYWdDb29yZC54eXh5IC0gdXJlY3RVbmlmb3JtX1MyX2MwKSk7CgkJaGFsZjIgZGlzdHMyID0gKGRpc3RzNC54eSArIGRpc3RzNC56dykgLSAxLjA7CgkJY292ZXJhZ2UgPSBkaXN0czIueCAqIGRpc3RzMi55OwoJfQoJaWYgKGludCgxKSA9PSBrSW52ZXJzZUZpbGxCV19TMl9jMCB8fCBpbnQoMSkgPT0ga0ludmVyc2VGaWxsQUFfUzJfYzApIAoJewoJCWNvdmVyYWdlID0gMS4wIC0gY292ZXJhZ2U7Cgl9CglyZXR1cm4gaGFsZjQoaGFsZjQoY292ZXJhZ2UpKTsKfQpoYWxmNCBDaXJjbGVfUzJfYzFfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF8zX2luQ29sb3IgPSBfaW5wdXQ7CgloYWxmIGQ7CglpZiAoaW50KDEpID09IGtJbnZlcnNlRmlsbEJXX1MyX2MxX2MwIHx8IGludCgxKSA9PSBrSW52ZXJzZUZpbGxBQV9TMl9jMV9jMCkgCgl7CgkJZCA9IGhhbGYoKGxlbmd0aCgodWNpcmNsZV9TMl9jMV9jMC54eSAtIHNrX0ZyYWdDb29yZC54eSkgKiB1Y2lyY2xlX1MyX2MxX2MwLncpIC0gMS4wKSAqIHVjaXJjbGVfUzJfYzFfYzAueik7Cgl9CgllbHNlIAoJewoJCWQgPSBoYWxmKCgxLjAgLSBsZW5ndGgoKHVjaXJjbGVfUzJfYzFfYzAueHkgLSBza19GcmFnQ29vcmQueHkpICogdWNpcmNsZV9TMl9jMV9jMC53KSkgKiB1Y2lyY2xlX1MyX2MxX2MwLnopOwoJfQoJcmV0dXJuIGhhbGY0KGhhbGY0KGludCgxKSA9PSBrRmlsbEFBX1MyX2MxX2MwIHx8IGludCgxKSA9PSBrSW52ZXJzZUZpbGxBQV9TMl9jMV9jMCA/IHNhdHVyYXRlKGQpIDogaGFsZihkID4gMC41KSkpOwp9CmhhbGY0IEJsZW5kX1MyX2MxKGhhbGY0IF9zcmMsIGhhbGY0IF9kc3QpIAp7CglyZXR1cm4gYmxlbmRfbW9kdWxhdGUoX3NyYywgQ2lyY2xlX1MyX2MxX2MwKF9zcmMpKTsKfQpoYWxmNCBCbGVuZF9TMihoYWxmNCBfc3JjLCBoYWxmNCBfZHN0KSAKewoJcmV0dXJuIGJsZW5kX21vZHVsYXRlKFJlY3RfUzJfYzAoX3NyYyksIEJsZW5kX1MyX2MxKF9zcmMsIF9kc3QpKTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJZmxvYXQgY292ZXJhZ2UgPSB2Y292ZXJhZ2VfUzA7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGNvdmVyYWdlKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IE1hdHJpeEVmZmVjdF9TMShvdXRwdXRDb2xvcl9TMCk7CgloYWxmNCBvdXRwdXRfUzI7CglvdXRwdXRfUzIgPSBCbGVuZF9TMihvdXRwdXRDb3ZlcmFnZV9TMCwgaGFsZjQoMSkpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dF9TMjsKCX0KfQoAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAHBvc2l0aW9uCAAAAGNvdmVyYWdlBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA="}} \ No newline at end of file diff --git a/test/fake/db.dart b/test/fake/db.dart index a0a979e82..3df10863c 100644 --- a/test/fake/db.dart +++ b/test/fake/db.dart @@ -125,6 +125,9 @@ class FakeAvesDb extends Fake implements LocalMediaDb { @override Future addDynamicAlbums(Set rows) => SynchronousFuture(null); + @override + Future removeDynamicAlbums(Set names) => SynchronousFuture(null); + // video playback @override diff --git a/test/model/collection_source_test.dart b/test/model/collection_source_test.dart index 9e922806f..f0e562bde 100644 --- a/test/model/collection_source_test.dart +++ b/test/model/collection_source_test.dart @@ -8,6 +8,8 @@ import 'package:aves/model/entry/extensions/favourites.dart'; import 'package:aves/model/favourites.dart'; import 'package:aves/model/filters/covered/stored_album.dart'; import 'package:aves/model/filters/covered/tag.dart'; +import 'package:aves/model/grouping/common.dart'; +import 'package:aves/model/grouping/convert.dart'; import 'package:aves/model/metadata/address.dart'; import 'package:aves/model/metadata/catalog.dart'; import 'package:aves/model/settings/settings.dart'; @@ -32,10 +34,10 @@ import 'package:shared_preferences_platform_interface/shared_preferences_platfor import '../fake/android_app_service.dart'; import '../fake/availability.dart'; +import '../fake/db.dart'; import '../fake/device_service.dart'; import '../fake/media_fetch_service.dart'; import '../fake/media_store_service.dart'; -import '../fake/db.dart'; import '../fake/metadata_fetch_service.dart'; import '../fake/report_service.dart'; import '../fake/storage_service.dart'; @@ -73,12 +75,17 @@ void main() { await settings.init(monitorPlatformSettings: false); settings.canUseAnalysisService = false; await androidFileUtils.init(); + albumGrouping.init(); }); setUp(() async { (getIt() as FakeMediaStoreService).reset(); }); + tearDown(() async { + albumGrouping.setGroups({}); + }); + tearDownAll(() async { await getIt.reset(); }); @@ -397,4 +404,28 @@ void main() { ), ); }); + + test('groups are cleared when removing entries', () async { + final image1 = FakeMediaStoreService.newImage(testAlbum, 'image1'); + (mediaStoreService as FakeMediaStoreService).entries = { + image1, + }; + + final albumFilter = StoredAlbumFilter(image1.directory!, 'whatever'); + + final source = await _initSource(); + final groupUri = albumGrouping.buildGroupUri(null, 'some group name'); + final childUri = GroupingConversion.filterToUri(albumFilter); + albumGrouping.addToGroup({childUri}.nonNulls.toSet(), groupUri); + expect(source.rawAlbums.length, 1); + expect(albumGrouping.exists(groupUri), true); + + await source.removeEntries({image1.uri}, includeTrash: true); + + // waiting for microtask to make sure event bus listeners executed + await Future.microtask(() {}); + + expect(source.rawAlbums.length, 0); + expect(albumGrouping.exists(groupUri), false); + }); } diff --git a/test/model/filters_test.dart b/test/model/filters_test.dart index a793f3005..eefc6edb7 100644 --- a/test/model/filters_test.dart +++ b/test/model/filters_test.dart @@ -29,13 +29,17 @@ import '../fake/media_store_service.dart'; import '../fake/storage_service.dart'; void main() { + setUpAll(() async { + albumGrouping.init(); + }); + setUp(() async { // specify Posix style path context for consistent behaviour when running tests on Windows getIt.registerLazySingleton(() => p.Context(style: p.Style.posix)); }); tearDown(() async { - albumGrouping.init({}); + albumGrouping.setGroups({}); await getIt.reset(); }); diff --git a/test/model/grouping/common_test.dart b/test/model/grouping/common_test.dart index 1a3b24763..28efd6ae9 100644 --- a/test/model/grouping/common_test.dart +++ b/test/model/grouping/common_test.dart @@ -16,6 +16,10 @@ void main() { const groupName = 'some group name'; const storedAlbumPath = '/path/to/album'; + setUpAll(() async { + albumGrouping.init(); + }); + setUp(() async { // specify Posix style path context for consistent behaviour when running tests on Windows getIt.registerLazySingleton(() => p.Context(style: p.Style.posix)); @@ -23,7 +27,7 @@ void main() { }); tearDown(() async { - albumGrouping.init({}); + albumGrouping.setGroups({}); await dynamicAlbums.clear(); await getIt.reset(); }); diff --git a/whatsnew/whatsnew-en-US b/whatsnew/whatsnew-en-US index 1400f36e5..34f08c4ad 100644 --- a/whatsnew/whatsnew-en-US +++ b/whatsnew/whatsnew-en-US @@ -1,4 +1,4 @@ -In v1.13.1: +In v1.13.2: - group albums - filter by day of the week Full changelog available on GitHub \ No newline at end of file