From 22d2b924ed065f8d0808a114fcf9827f0c8d557f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Chastanet?= Date: Sun, 12 Nov 2023 14:14:07 +0100 Subject: [PATCH] use bash-tools-framework pre-commit hooks --- .framework-config | 4 + .github/workflows/lint-test.yml | 119 ++++++++++-------- .gitignore | 9 +- .pre-commit-config.yaml | 19 ++- Commands.tmpl.md | 71 +---------- bin/cli | 4 +- bin/dbImport | 4 +- bin/dbImportProfile | 4 +- bin/dbImportStream | 4 +- bin/dbQueryAllDatabases | 8 +- bin/dbScriptAllDatabases | 8 +- bin/doc | 4 +- bin/gitIsAncestorOf | 4 +- bin/gitIsBranch | 4 +- bin/gitRenameBranch | 4 +- bin/installRequirements | 8 +- bin/mysql2puml | 4 +- bin/upgradeGithubRelease | 4 +- bin/waitForIt | 4 +- bin/waitForMysql | 4 +- conf/dbScripts/extractData | 4 +- install | 4 +- src/_binaries/DbImport/dbImportProfile.bats | 5 +- src/_binaries/Utils/waitForMysql.bats | 2 +- .../build/installRequirements.options.tpl | 7 -- 25 files changed, 126 insertions(+), 190 deletions(-) diff --git a/.framework-config b/.framework-config index fca7f907..e3320e82 100755 --- a/.framework-config +++ b/.framework-config @@ -1,6 +1,10 @@ #!/usr/bin/env bash # shellcheck disable=SC2034 +REAL_SCRIPT_FILE="$(readlink -e "$(realpath "${BASH_SOURCE[0]}")")" +FRAMEWORK_ROOT_DIR="$(cd "$(readlink -e "${REAL_SCRIPT_FILE%/*}")" && pwd -P)" +FRAMEWORK_SRC_DIR="${FRAMEWORK_ROOT_DIR}/src" + # describe the functions that will be skipped from being imported FRAMEWORK_FUNCTIONS_IGNORE_REGEXP='^(Namespace::functions|Functions::myFunction|Namespace::requireSomething|IMPORT::dir::file|Acquire::ForceIPv4)$' # describe the files that do not contain function to be imported diff --git a/.github/workflows/lint-test.yml b/.github/workflows/lint-test.yml index f946e9bc..2502eb00 100644 --- a/.github/workflows/lint-test.yml +++ b/.github/workflows/lint-test.yml @@ -1,7 +1,7 @@ --- # Lint the code base and launch unit test at each push or pull request name: Lint and test -on: +on: # yamllint disable-line rule:truthy push: workflow_dispatch: @@ -10,55 +10,44 @@ jobs: runs-on: ubuntu-22.04 strategy: fail-fast: true - matrix: - vendor: - - ubuntu steps: - - name: Checkout Code - uses: actions/checkout@v3 + - uses: actions/checkout@v3 + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: 3.9 + + - name: Install pre-commit + run: pip install pre-commit - uses: ouzi-dev/commit-status-updater@v2 with: name: lint status: pending - - name: Install vendors - run: | - set -exo pipefail - ./bin/installRequirements - - - name: Linting - Shellcheck - run: | - set -exo pipefail - ./bin/shellcheckLint -f checkstyle | tee logs/shellcheck-checkstyle.xml - - - name: Linting - Framework - run: | - set -exo pipefail - ./bin/frameworkLint -f checkstyle | tee logs/framework-checkstyle.xml - - - name: Linting - Awk - run: | - set -exo pipefail - ./bin/awkLint | tee logs/awk-checkstyle.xml - - - name: build bin files + check md5 - run: | - set -exo pipefail - ./bin/buildBinFiles 2>&1 | tee logs/buidBinFiles.log - - - name: Checkstyle aggregation - uses: jwgmeligmeyling/checkstyle-github-action@master - with: - path: 'logs/*-checkstyle.xml' + - name: Run pre-commit + run: pre-commit run -a --hook-stage manual - name: Archive results + if: ${{ always() }} + continue-on-error: true uses: actions/upload-artifact@v3 with: name: linter-reports path: | - logs/*.xml - logs/*.log + megalinter-reports/** + + - name: Create Pull Request + if: ${{ failure() }} + uses: peter-evans/create-pull-request@v4 + with: + branch: update/pre-commit-fixes + title: lint fixes + commit-message: Auto-update lint fixes + body: | + some auto fixes have been generated during pre-commit run + labels: updates - uses: ouzi-dev/commit-status-updater@v2 if: always() @@ -82,10 +71,10 @@ jobs: include: - vendor: ubuntu bashImage: ubuntu:20.04 - options: -j 1 + options: -j 30 - vendor: alpine bashImage: bash - options: -j 1 + options: -j 30 steps: - name: Checkout uses: actions/checkout@v3 @@ -110,21 +99,25 @@ jobs: ./bin/installRequirements + chmod -R 777 logs + # shellcheck disable=SC2266 - VENDOR="${{ matrix.vendor }}" \ - BASH_TAR_VERSION="${{ matrix.bashTarVersion }}" \ - BASH_IMAGE="${{ matrix.bashImage }}" \ - SKIP_BUILD=0 \ - SKIP_USER=1 \ - ./bin/test ${{matrix.options}} --report-formatter junit -o logs -r src - - - name: Publish Unit Test Results - uses: EnricoMi/publish-unit-test-result-action@v1 + USER_ID=1000 \ + GROUP_ID=1000 \ + ./bin/test \ + -vvv \ + --vendor "${{matrix.vendor}}" \ + --bash-version "${{matrix.bashTarVersion}}" \ + --bash-base-image "${{matrix.bashImage}}" \ + --branch-name "${BRANCH}" \ + ${{matrix.options}} --report-formatter junit -o logs -r src --ci + + - name: Upload Test Results if: always() + uses: actions/upload-artifact@v3 with: - files: logs/report.xml - check_name: - 'Unit Test Results ${{matrix.vendor}} ${{matrix.bashTarVersion}}' + name: Test Results ${{matrix.vendor}} ${{matrix.bashTarVersion}} + path: logs/report.xml - uses: ouzi-dev/commit-status-updater@v2 if: always() @@ -132,12 +125,30 @@ jobs: name: build bash-tools-${{matrix.vendor}}-${{matrix.bashTarVersion}} status: ${{ job.status }} - buildResults: + publishTestResults: + name: 'Publish Tests Results' if: ${{ always() }} - runs-on: ubuntu-latest - name: Final Build Results needs: [linters, tests] + runs-on: ubuntu-latest + permissions: + checks: write + + # needed by ouzi-dev/commit-status-updater@v2 + statuses: write + + # only needed unless run with comment_mode: off + pull-requests: write steps: + - name: Download Artifacts + uses: actions/download-artifact@v3 + with: + path: artifacts + + - name: Checkstyle aggregation + uses: lcollins/checkstyle-github-action@v2.0.0 + with: + path: 'artifacts/**/*.xml' + # run this action to get the workflow conclusion # You can get the conclusion via env (env.WORKFLOW_CONCLUSION) - uses: technote-space/workflow-conclusion-action@v3 diff --git a/.gitignore b/.gitignore index 9bb824d1..efb08e98 100644 --- a/.gitignore +++ b/.gitignore @@ -12,14 +12,7 @@ !/**/_sidebar.md !/**/_navbar.md -/bin/awkLint -/bin/buildBinFiles -/bin/generateShellDoc -/bin/megalinter -/bin/runBuildContainer -/bin/shellcheckLint +bin/runBuildContainer /bin/test -/bin/findShebangFiles /bin/buildPushDockerImages /bin/buildPushDockerImage -/bin/frameworkLint diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 922f4bcd..fa13bef3 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -67,7 +67,7 @@ repos: stages: [commit] - repo: https://github.com/fchastanet/bash-tools-framework - rev: 1.0.4 + rev: 1.1.3 hooks: - id: fixShebangExecutionBit - id: frameworkLinter @@ -79,19 +79,14 @@ repos: plain, --theme, default-force, + --bash-framework-config, + .framework-config, ] - id: shellcheckLint - - - repo: local - hooks: - id: buildShFiles - name: build sh files - entry: bash -c './bin/buildBinFiles --ignore-missing' - language: system - always_run: true - require_serial: true - fail_fast: true - stages: [commit] + args: [--bash-framework-config, .framework-config, --ignore-missing] + - id: buildShFilesGithubAction + args: [--bash-framework-config, .framework-config] - repo: local hooks: @@ -105,7 +100,7 @@ repos: stages: [push] - repo: https://github.com/fchastanet/bash-tools-framework - rev: 1.0.4 + rev: 1.1.3 hooks: - id: runUnitTests - id: plantuml diff --git a/Commands.tmpl.md b/Commands.tmpl.md index 899cd2c1..d59164a5 100644 --- a/Commands.tmpl.md +++ b/Commands.tmpl.md @@ -6,15 +6,8 @@ - [1.3. bin/waitForMysql](#13-binwaitformysql) - [1.4. bin/doc](#14-bindoc) - [1.5. bin/findShebangFiles](#15-binfindshebangfiles) - - [1.6. bin/dockerLint](#16-bindockerlint) - - [1.7. bin/shellcheckLint](#17-binshellchecklint) - - [1.8. bin/awkLint](#18-binawklint) - - [1.9. bin/frameworkLint](#19-binframeworklint) - - [1.10. bin/megalinter](#110-binmegalinter) - - [1.11. .github/workflows/buildBinFiles](#111-githubworkflowsbuildbinfiles) - - [1.12. bin/test](#112-bintest) - - [1.13. bin/runBuildContainer](#113-binrunbuildcontainer) - - [1.14. bin/buildPushDockerImage](#114-binbuildpushdockerimage) + - [1.6. bin/test](#16-bintest) + - [1.7. bin/runBuildContainer](#17-binrunbuildcontainer) - [2. Converter and Generator tools](#2-converter-and-generator-tools) - [2.1. bin/generateShellDoc](#21-bingenerateshelldoc) - [2.2. bin/mysql2puml](#22-binmysql2puml) @@ -77,55 +70,7 @@ imported from bash-tools-framework @@@findShebangFiles_help@@@ ``` -### 1.6. bin/dockerLint - -imported from bash-tools-framework - -```text -@@@dockerLint_help@@@ -``` - -### 1.7. bin/shellcheckLint - -imported from bash-tools-framework - -```text -@@@shellcheckLint_help@@@ -``` - -### 1.8. bin/awkLint - -imported from bash-tools-framework - -```text -@@@awkLint_help@@@ -``` - -### 1.9. bin/frameworkLint - -imported from bash-tools-framework - -```text -@@@frameworkLint_help@@@ -``` - -### 1.10. bin/megalinter - -imported from bash-tools-framework - -```text -@@@megalinter_help@@@ -``` - -### 1.11. .github/workflows/buildBinFiles - -imported from bash-tools-framework - -```text -@@@buildBinFiles_help@@@ -``` - -### 1.12. bin/test +### 1.6. bin/test imported from bash-tools-framework @@ -133,7 +78,7 @@ imported from bash-tools-framework @@@test_help@@@ ``` -### 1.13. bin/runBuildContainer +### 1.7. bin/runBuildContainer imported from bash-tools-framework @@ -141,14 +86,6 @@ imported from bash-tools-framework @@@runBuildContainer_help@@@ ``` -### 1.14. bin/buildPushDockerImage - -imported from bash-tools-framework - -```text -@@@buildPushDockerImage_help@@@ -``` - ## 2. Converter and Generator tools ### 2.1. bin/generateShellDoc diff --git a/bin/cli b/bin/cli index 8629fe9b..340599a1 100755 --- a/bin/cli +++ b/bin/cli @@ -1086,7 +1086,7 @@ Array::contains() { # FUNCTIONS -facade_main_738fd7f6601040de82a4a46d9d2efa6f() { +facade_main_clish() { BASH_TOOLS_ROOT_DIR="$(cd "${CURRENT_DIR}/.." && pwd -P)" if [[ -d "${BASH_TOOLS_ROOT_DIR}/vendor/bash-tools-framework/" ]]; then FRAMEWORK_ROOT_DIR="$(cd "${BASH_TOOLS_ROOT_DIR}/vendor/bash-tools-framework" && pwd -P)" @@ -1932,4 +1932,4 @@ fi } -facade_main_738fd7f6601040de82a4a46d9d2efa6f "$@" +facade_main_clish "$@" diff --git a/bin/dbImport b/bin/dbImport index 5515e90a..f60c8e5a 100755 --- a/bin/dbImport +++ b/bin/dbImport @@ -1323,7 +1323,7 @@ Linux::requireRealpathCommand() { # FUNCTIONS -facade_main_fc50b62ffd6b46bd903195f347ce1017() { +facade_main_dbImportsh() { BASH_TOOLS_ROOT_DIR="$(cd "${CURRENT_DIR}/.." && pwd -P)" if [[ -d "${BASH_TOOLS_ROOT_DIR}/vendor/bash-tools-framework/" ]]; then FRAMEWORK_ROOT_DIR="$(cd "${BASH_TOOLS_ROOT_DIR}/vendor/bash-tools-framework" && pwd -P)" @@ -2572,4 +2572,4 @@ fi } -facade_main_fc50b62ffd6b46bd903195f347ce1017 "$@" +facade_main_dbImportsh "$@" diff --git a/bin/dbImportProfile b/bin/dbImportProfile index 2147859a..70b85a95 100755 --- a/bin/dbImportProfile +++ b/bin/dbImportProfile @@ -1175,7 +1175,7 @@ Linux::requireRealpathCommand() { # FUNCTIONS -facade_main_dc9a7ae43eb7453ca997db3a8dcfeed0() { +facade_main_dbImportProfilesh() { BASH_TOOLS_ROOT_DIR="$(cd "${CURRENT_DIR}/.." && pwd -P)" if [[ -d "${BASH_TOOLS_ROOT_DIR}/vendor/bash-tools-framework/" ]]; then FRAMEWORK_ROOT_DIR="$(cd "${BASH_TOOLS_ROOT_DIR}/vendor/bash-tools-framework" && pwd -P)" @@ -2042,4 +2042,4 @@ fi } -facade_main_dc9a7ae43eb7453ca997db3a8dcfeed0 "$@" +facade_main_dbImportProfilesh "$@" diff --git a/bin/dbImportStream b/bin/dbImportStream index 433c8541..210b0409 100755 --- a/bin/dbImportStream +++ b/bin/dbImportStream @@ -1233,7 +1233,7 @@ Linux::requireRealpathCommand() { # FUNCTIONS -facade_main_d2bf5f5cbe1a441fbd98a9d712dd6116() { +facade_main_dbImportStreamsh() { BASH_TOOLS_ROOT_DIR="$(cd "${CURRENT_DIR}/.." && pwd -P)" if [[ -d "${BASH_TOOLS_ROOT_DIR}/vendor/bash-tools-framework/" ]]; then FRAMEWORK_ROOT_DIR="$(cd "${BASH_TOOLS_ROOT_DIR}/vendor/bash-tools-framework" && pwd -P)" @@ -2243,4 +2243,4 @@ fi } -facade_main_d2bf5f5cbe1a441fbd98a9d712dd6116 "$@" +facade_main_dbImportStreamsh "$@" diff --git a/bin/dbQueryAllDatabases b/bin/dbQueryAllDatabases index 7b5231f4..0fc29e68 100755 --- a/bin/dbQueryAllDatabases +++ b/bin/dbQueryAllDatabases @@ -1295,14 +1295,14 @@ Array::contains() { # @require Compiler::Embed::requireEmbedBinDir -declare -gx embed_function_DbQueryOneDatabase="${PERSISTENT_TMPDIR:-/tmp}/bin/831da3376e6ea1f6055692f8702d065c/dbQueryOneDatabase" -declare -gx encoded_binary_file_DbQueryOneDatabase="IyEvdXNyL2Jpbi9lbnYgYmFzaAojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCiMgR0VORVJBVEVEIEZBQ0FERSBGUk9NIGh0dHBzOi8vZ2l0aHViLmNvbS9mY2hhc3RhbmV0L2Jhc2gtdG9vbHMvdHJlZS9tYXN0ZXIvLi4vYmFzaC1kZXYtZW52L3ZlbmRvci9iYXNoLXRvb2xzLWZyYW1ld29yay9zcmMvQ29tcGlsZXIvRW1iZWQvZW1iZWRGcmFtZXdvcmtGdW5jdGlvbi5iaW5GaWxlLnRwbAojIERPIE5PVCBFRElUIElUCiMgQGdlbmVyYXRlZAojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCiMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjI4OCxTQzIwMzQKIyBCSU5fRklMRT0ke0JJTl9GSUxFfQojIEZBQ0FERQoKIyBlbnN1cmUgdGhhdCBubyB1c2VyIGFsaWFzZXMgY291bGQgaW50ZXJmZXJlIHdpdGgKIyBjb21tYW5kcyB1c2VkIGluIHRoaXMgc2NyaXB0CnVuYWxpYXMgLWEgfHwgdHJ1ZQpzaG9wdCAtdSBleHBhbmRfYWxpYXNlcwoKIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CigoZmFpbHVyZXMgPSAwKSkgfHwgdHJ1ZQoKIyBCYXNoIHdpbGwgcmVtZW1iZXIgJiByZXR1cm4gdGhlIGhpZ2hlc3QgZXhpdCBjb2RlIGluIGEgY2hhaW4gb2YgcGlwZXMuCiMgVGhpcyB3YXkgeW91IGNhbiBjYXRjaCB0aGUgZXJyb3IgaW5zaWRlIHBpcGVzLCBlLmcuIG15c3FsZHVtcCB8IGd6aXAKc2V0IC1vIHBpcGVmYWlsCnNldCAtbyBlcnJleGl0CgojIENvbW1hbmQgU3Vic3RpdHV0aW9uIGNhbiBpbmhlcml0IGVycmV4aXQgb3B0aW9uIHNpbmNlIGJhc2ggdjQuNApzaG9wdCAtcyBpbmhlcml0X2VycmV4aXQgfHwgdHJ1ZQoKIyBhIGxvZyBpcyBnZW5lcmF0ZWQgd2hlbiBhIGNvbW1hbmQgZmFpbHMKc2V0IC1vIGVycnRyYWNlCgojIHVzZSBudWxsZ2xvYiBzbyB0aGF0IChmaWxlKi5waHApIHdpbGwgcmV0dXJuIGFuIGVtcHR5IGFycmF5IGlmIG5vIGZpbGUgbWF0Y2hlcyB0aGUgd2lsZGNhcmQKc2hvcHQgLXMgbnVsbGdsb2IKCiMgZW5zdXJlIHJlZ2V4cCBhcmUgaW50ZXJwcmV0ZWQgd2l0aG91dCBhY2NlbnR1YXRlZCBjaGFyYWN0ZXJzCmV4cG9ydCBMQ19BTEw9UE9TSVgKCmV4cG9ydCBURVJNPXh0ZXJtLTI1NmNvbG9yCgojIGF2b2lkIGludGVyYWN0aXZlIGluc3RhbGwKZXhwb3J0IERFQklBTl9GUk9OVEVORD1ub25pbnRlcmFjdGl2ZQpleHBvcnQgREVCQ09ORl9OT05JTlRFUkFDVElWRV9TRUVOPXRydWUKCiMgc3RvcmUgY29tbWFuZCBhcmd1bWVudHMgZm9yIGxhdGVyIHVzYWdlCiMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNApkZWNsYXJlIC1hIEJBU0hfRlJBTUVXT1JLX0FSR1Y9KCIkQCIpCiMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNApkZWNsYXJlIC1hIE9SSUdJTkFMX0JBU0hfRlJBTUVXT1JLX0FSR1Y9KCIkQCIpCgojIEBzZWUgaHR0cHM6Ly91bml4LnN0YWNrZXhjaGFuZ2UuY29tL2EvMzg2ODU2CiMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjMxNwppbnRlcnJ1cHRNYW5hZ2VtZW50KCkgewogICMgcmVzdG9yZSBTSUdJTlQgaGFuZGxlcgogIHRyYXAgLSBJTlQKICAjIGVuc3VyZSB0aGF0IEN0cmwtQyBpcyB0cmFwcGVkIGJ5IHRoaXMgc2NyaXB0IGFuZCBub3QgYnkgc3ViIHByb2Nlc3MKICAjIHJlcG9ydCB0byB0aGUgcGFyZW50IHRoYXQgd2UgaGF2ZSBpbmRlZWQgYmVlbiBpbnRlcnJ1cHRlZAogIGtpbGwgLXMgSU5UICIkJCIKfQp0cmFwIGludGVycnVwdE1hbmFnZW1lbnQgSU5UClNDUklQVF9OQU1FPSR7MCMjKi99ClJFQUxfU0NSSVBUX0ZJTEU9IiQocmVhZGxpbmsgLWUgIiQocmVhbHBhdGggIiR7QkFTSF9TT1VSQ0VbMF19IikiKSIKQ1VSUkVOVF9ESVI9IiQoY2QgIiQocmVhZGxpbmsgLWUgIiR7UkVBTF9TQ1JJUFRfRklMRSUvKn0iKSIgJiYgcHdkIC1QKSIKCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwojIFRlbXAgZGlyIG1hbmFnZW1lbnQKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCgpLRUVQX1RFTVBfRklMRVM9IiR7S0VFUF9URU1QX0ZJTEVTOi0wfSIKZXhwb3J0IEtFRVBfVEVNUF9GSUxFUwoKIyBQRVJTSVNURU5UX1RNUERJUiBpcyBub3QgZGVsZXRlZCBieSB0cmFwcwpQRVJTSVNURU5UX1RNUERJUj0iJHtUTVBESVI6LS90bXB9L2Jhc2gtZnJhbWV3b3JrIgpleHBvcnQgUEVSU0lTVEVOVF9UTVBESVIKbWtkaXIgLXAgIiR7UEVSU0lTVEVOVF9UTVBESVJ9IgoKIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0ClRNUERJUj0iJChta3RlbXAgLWQgLXAgIiR7UEVSU0lTVEVOVF9UTVBESVI6LS90bXB9IiAtdCBiYXNoLWZyYW1ld29yay0kJC1YWFhYWFgpIgpleHBvcnQgVE1QRElSCgojIHRlbXAgZGlyIGNsZWFuaW5nCiMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjMxNwpjbGVhbk9uRXhpdCgpIHsKICBpZiBbWyAiJHtLRUVQX1RFTVBfRklMRVM6LTB9IiA9ICIxIiBdXTsgdGhlbgogICAgTG9nOjpkaXNwbGF5SW5mbyAiS0VFUF9URU1QX0ZJTEVTPTEgdGVtcCBmaWxlcyBrZXB0IGhlcmUgJyR7VE1QRElSfSciCiAgZWxpZiBbWyAtbiAiJHtUTVBESVIreHh4fSIgXV07IHRoZW4KICAgIExvZzo6ZGlzcGxheURlYnVnICJLRUVQX1RFTVBfRklMRVM9MCByZW1vdmluZyB0ZW1wIGZpbGVzICcke1RNUERJUn0nIgogICAgcm0gLVJmICIke1RNUERJUjotL3RtcC9mYWtlfSIgPi9kZXYvbnVsbCAyPiYxCiAgZmkKfQp0cmFwIGNsZWFuT25FeGl0IEVYSVQgSFVQIFFVSVQgQUJSVCBURVJNCgojIFZBUl9NQUlOX0ZVTkNUSU9OX1ZBUl9OQU1FPWRiUXVlcnlBbGxEYXRhYmFzZXNGYWNhZGUKCiMgQGRlc2NyaXB0aW9uIHVzZWQgdG8gZXhlY3V0ZSBnaXZlbiBxdWVyeSB3aGVuIHVzaW5nCiMgZGJTY3JpcHRBbGxEYXRhYmFzZXMKIyBAYXJnICQxIGRzbjpTdHJpbmcKIyBAYXJnICQyIGRiOlN0cmluZwojIEBlbnYgcXVlcnkgU3RyaW5nCiMgQGVudiBvcHRpb25TZXBhcmF0b3IgU3RyaW5nCiMgQHJlcXVpcmUgTGludXg6OnJlcXVpcmVFeGVjdXRlZEFzVXNlcgpEYjo6cXVlcnlPbmVEYXRhYmFzZSgpIHsKICAjIHF1ZXJ5IGFuZCBvcHRpb25TZXBhcmF0b3IgYXJlIHBhc3NlZCB2aWEgZXhwb3J0CiAgbG9jYWwgZHNuPSIkMSIKICBsb2NhbCBkYj0iJDIiCgogIGxvY2FsIC1BIGRiSW5zdGFuY2UKICBEYXRhYmFzZTo6bmV3SW5zdGFuY2UgZGJJbnN0YW5jZSAiJHtkc259IgogIERhdGFiYXNlOjpzZXRRdWVyeU9wdGlvbnMgZGJJbnN0YW5jZSAiJHtkYkluc3RhbmNlW1FVRVJZX09QVElPTlNdfSAtLWNvbm5lY3QtdGltZW91dD01IgoKICAjIGlkZW50aWZ5IGNvbHVtbnMgaGVhZGVyCiAgZWNobyAtbiAiQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAiCiAgRGF0YWJhc2U6OnNraXBDb2x1bW5OYW1lcyBkYkluc3RhbmNlIDAKCiAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMTU0CiAgaWYgISBEYXRhYmFzZTo6cXVlcnkgZGJJbnN0YW5jZSAiJHtxdWVyeX0iICIke2RifSIgfCBzZWQgInMvXHQvJHtvcHRpb25TZXBhcmF0b3J9L2ciOyB0aGVuCiAgICBMb2c6OmZhdGFsICJkYXRhYmFzZSAke2RifSBlcnJvciIgMT4mMgogIGZpCn0KCiMgQGRlc2NyaXB0aW9uIExvZyBuYW1lc3BhY2UgcHJvdmlkZXMgMiBraW5kIG9mIGZ1bmN0aW9ucwojIC0gTG9nOjpkaXNwbGF5KiBhbGxvd3MgdG8gZGlzcGxheSBnaXZlbiBtZXNzYWdlIHdpdGgKIyAgIGdpdmVuIGRpc3BsYXkgbGV2ZWwKIyAtIExvZzo6bG9nKiBhbGxvd3MgdG8gbG9nIGdpdmVuIG1lc3NhZ2Ugd2l0aAojICAgZ2l2ZW4gbG9nIGxldmVsCiMgTG9nOjpkaXNwbGF5KiBmdW5jdGlvbnMgYXV0b21hdGljYWxseSBsb2cgdGhlIG1lc3NhZ2UgdG9vCiMgQHNlZSBFbnY6OnJlcXVpcmVMb2FkIHRvIGxvYWQgdGhlIGRpc3BsYXkgYW5kIGxvZyBsZXZlbCBmcm9tIC5lbnYgZmlsZQoKIyBAZGVzY3JpcHRpb24gbG9nIGxldmVsIG9mZgpleHBvcnQgX19MRVZFTF9PRkY9MAojIEBkZXNjcmlwdGlvbiBsb2cgbGV2ZWwgZXJyb3IKZXhwb3J0IF9fTEVWRUxfRVJST1I9MQojIEBkZXNjcmlwdGlvbiBsb2cgbGV2ZWwgd2FybmluZwpleHBvcnQgX19MRVZFTF9XQVJOSU5HPTIKIyBAZGVzY3JpcHRpb24gbG9nIGxldmVsIGluZm8KZXhwb3J0IF9fTEVWRUxfSU5GTz0zCiMgQGRlc2NyaXB0aW9uIGxvZyBsZXZlbCBzdWNjZXNzCmV4cG9ydCBfX0xFVkVMX1NVQ0NFU1M9MwojIEBkZXNjcmlwdGlvbiBsb2cgbGV2ZWwgZGVidWcKZXhwb3J0IF9fTEVWRUxfREVCVUc9NAoKIyBAZGVzY3JpcHRpb24gdmVyYm9zZSBsZXZlbCBvZmYKZXhwb3J0IF9fVkVSQk9TRV9MRVZFTF9PRkY9MAojIEBkZXNjcmlwdGlvbiB2ZXJib3NlIGxldmVsIGluZm8KZXhwb3J0IF9fVkVSQk9TRV9MRVZFTF9JTkZPPTEKIyBAZGVzY3JpcHRpb24gdmVyYm9zZSBsZXZlbCBpbmZvCmV4cG9ydCBfX1ZFUkJPU0VfTEVWRUxfREVCVUc9MgojIEBkZXNjcmlwdGlvbiB2ZXJib3NlIGxldmVsIGluZm8KZXhwb3J0IF9fVkVSQk9TRV9MRVZFTF9UUkFDRT0zCgojIEBkZXNjcmlwdGlvbiBEaXNwbGF5IG1lc3NhZ2UgdXNpbmcgZGVidWcgY29sb3IgKGdyZXkpCiMgQGFyZyAkMSBtZXNzYWdlOlN0cmluZyB0aGUgbWVzc2FnZSB0byBkaXNwbGF5CkxvZzo6ZGlzcGxheURlYnVnKCkgewogIGlmICgoQkFTSF9GUkFNRVdPUktfRElTUExBWV9MRVZFTCA+PSBfX0xFVkVMX0RFQlVHKSk7IHRoZW4KICAgIGVjaG8gLWUgIiR7X19ERUJVR19DT0xPUn1ERUJVRyAgIC0gJHsxfSR7X19SRVNFVF9DT0xPUn0iID4mMgogIGZpCiAgTG9nOjpsb2dEZWJ1ZyAiJDEiCn0KCiMgQGRlc2NyaXB0aW9uIERpc3BsYXkgbWVzc2FnZSB1c2luZyBpbmZvIGNvbG9yIChiZyBsaWdodCBibHVlL2ZnIHdoaXRlKQojIEBhcmcgJDEgbWVzc2FnZTpTdHJpbmcgdGhlIG1lc3NhZ2UgdG8gZGlzcGxheQpMb2c6OmRpc3BsYXlJbmZvKCkgewogIGxvY2FsIHR5cGU9IiR7MjotSU5GT30iCiAgaWYgKChCQVNIX0ZSQU1FV09SS19ESVNQTEFZX0xFVkVMID49IF9fTEVWRUxfSU5GTykpOyB0aGVuCiAgICBlY2hvIC1lICIke19fSU5GT19DT0xPUn0ke3R5cGV9ICAgIC0gJHsxfSR7X19SRVNFVF9DT0xPUn0iID4mMgogIGZpCiAgTG9nOjpsb2dJbmZvICIkMSIgIiR7dHlwZX0iCn0KCiMgQGRlc2NyaXB0aW9uIGVuc3VyZSBDT01NQU5EX0JJTl9ESVIgZW52IHZhciBpcyBzZXQKIyBhbmQgUEFUSCBjb3JyZWN0bHkgcHJlcGFyZWQKIyBAbm9hcmdzCiMgQHNldCBDT01NQU5EX0JJTl9ESVIgc3RyaW5nIHRoZSBkaXJlY3Rvcnkgd2hlcmUgdG8gZmluZCB0aGlzIGNvbW1hbmQKIyBAc2V0IFBBVEggc3RyaW5nIGFkZCBkaXJlY3Rvcnkgd2hlcmUgdG8gZmluZCB0aGlzIGNvbW1hbmQgYmluYXJ5CkNvbXBpbGVyOjpGYWNhZGU6OnJlcXVpcmVDb21tYW5kQmluRGlyKCkgewogIENPTU1BTkRfQklOX0RJUj0iJHtDVVJSRU5UX0RJUn0iCiAgRW52OjpwYXRoUHJlcGVuZCAiJHtDT01NQU5EX0JJTl9ESVJ9Igp9CgojIEBkZXNjcmlwdGlvbiBjcmVhdGUgYSBuZXcgZGIgaW5zdGFuY2UKIyBSZXR1cm5zIGltbWVkaWF0ZWx5IGlmIHRoZSBpbnN0YW5jZSBpcyBhbHJlYWR5IGluaXRpYWxpemVkCiMKIyBAYXJnICQxIGluc3RhbmNlTmV3SW5zdGFuY2U6Jk1hcDxTdHJpbmcsU3RyaW5nPiAocGFzc2VkIGJ5IHJlZmVyZW5jZSkgZGF0YWJhc2UgaW5zdGFuY2UgdG8gdXNlCiMgQGFyZyAkMiBkc246U3RyaW5nIGRzbiBwcm9maWxlIC0gbG9hZCB0aGUgZHNuLmVudiBwcm9maWxlIGRlZHVjZWQgdXNpbmcgcnVsZXMgZGVmaW5lZCBpbiBDb25mOjpnZXRBYnNvbHV0ZUZpbGUKIwojIEBleGFtcGxlCiMgICBkZWNsYXJlIC1BZ3ggZGJJbnN0YW5jZQojICAgRGF0YWJhc2U6Om5ld0luc3RhbmNlIGRiSW5zdGFuY2UgImRlZmF1bHQubG9jYWwiCiMKIyBAZXhpdGNvZGUgMSBpZiBkbnMgZmlsZSBub3QgYWJsZSB0byBsb2FkZWQKRGF0YWJhc2U6Om5ld0luc3RhbmNlKCkgewogIGxvY2FsIC1uIGluc3RhbmNlTmV3SW5zdGFuY2U9JDEKICBsb2NhbCBkc249IiQyIgogIGxvY2FsIERTTl9GSUxFCgogIGlmIFtbIC12IGluc3RhbmNlTmV3SW5zdGFuY2VbJ0lOSVRJQUxJWkVEJ10gJiYgIiR7aW5zdGFuY2VOZXdJbnN0YW5jZVsnSU5JVElBTElaRUQnXTotMH0iID09ICIxIiBdXTsgdGhlbgogICAgcmV0dXJuCiAgZmkKCiAgIyBmaW5hbCBhdXRoIGZpbGUgZ2VuZXJhdGVkIGZyb20gZG5zIGZpbGUKICBpbnN0YW5jZU5ld0luc3RhbmNlWydBVVRIX0ZJTEUnXT0iIgogIGluc3RhbmNlTmV3SW5zdGFuY2VbJ0RTTl9GSUxFJ109IiIKCiAgIyBjaGVjayBkc24gZmlsZQogIERTTl9GSUxFPSIkKENvbmY6OmdldEFic29sdXRlRmlsZSAiZHNuIiAiJHtkc259IiAiZW52IikiIHx8IHJldHVybiAxCiAgRGF0YWJhc2U6OmNoZWNrRHNuRmlsZSAiJHtEU05fRklMRX0iIHx8IHJldHVybiAxCiAgaW5zdGFuY2VOZXdJbnN0YW5jZVsnRFNOX0ZJTEUnXT0iJHtEU05fRklMRX0iCgogICMgc2hlbGxjaGVjayBzb3VyY2U9L3NyYy9EYXRhYmFzZS90ZXN0c0RhdGEvZHNuX3ZhbGlkLmVudgogIHNvdXJjZSAiJHtpbnN0YW5jZU5ld0luc3RhbmNlWydEU05fRklMRSddfSIKCiAgaW5zdGFuY2VOZXdJbnN0YW5jZVsnVVNFUiddPSIke1VTRVJ9IgogIGluc3RhbmNlTmV3SW5zdGFuY2VbJ1BBU1NXT1JEJ109IiR7UEFTU1dPUkR9IgogIGluc3RhbmNlTmV3SW5zdGFuY2VbJ0hPU1ROQU1FJ109IiR7SE9TVE5BTUV9IgogIGluc3RhbmNlTmV3SW5zdGFuY2VbJ1BPUlQnXT0iJHtQT1JUfSIKCiAgIyBnZW5lcmF0ZSBhdXRoRmlsZSBmb3IgZWFzeSBhdXRoZW50aWNhdGlvbgogIGluc3RhbmNlTmV3SW5zdGFuY2VbJ0FVVEhfRklMRSddPSQobWt0ZW1wIC1wICIke1RNUERJUjotL3RtcH0iIC10ICJteXNxbC5YWFhYWFhYWFhYWFgiKQogICgKICAgIGVjaG8gIltjbGllbnRdIgogICAgZWNobyAidXNlciA9ICR7VVNFUn0iCiAgICBlY2hvICJwYXNzd29yZCA9ICR7UEFTU1dPUkR9IgogICAgZWNobyAiaG9zdCA9ICR7SE9TVE5BTUV9IgogICAgZWNobyAicG9ydCA9ICR7UE9SVH0iCiAgKSA+IiR7aW5zdGFuY2VOZXdJbnN0YW5jZVsnQVVUSF9GSUxFJ119IgoKICAjIHNvbWUgb2YgdGhvc2UgdmFsdWVzIGNhbiBiZSBvdmVycmlkZGVuIHVzaW5nIHRoZSBkc24gZmlsZQogICMgU0tJUF9DT0xVTU5fTkFNRVMgZW5hYmxlZCBieSBkZWZhdWx0CiAgaW5zdGFuY2VOZXdJbnN0YW5jZVsnU0tJUF9DT0xVTU5fTkFNRVMnXT0iJHtTS0lQX0NPTFVNTl9OQU1FUzotMX0iCiAgaW5zdGFuY2VOZXdJbnN0YW5jZVsnU1NMX09QVElPTlMnXT0iJHtNWVNRTF9TU0xfT1BUSU9OUzotLS1zc2wtbW9kZT1ESVNBQkxFRH0iCiAgaW5zdGFuY2VOZXdJbnN0YW5jZVsnUVVFUllfT1BUSU9OUyddPSIke01ZU1FMX1FVRVJZX09QVElPTlM6LS0tYmF0Y2ggLS1yYXcgLS1kZWZhdWx0LWNoYXJhY3Rlci1zZXQ9dXRmOH0iCiAgaW5zdGFuY2VOZXdJbnN0YW5jZVsnRFVNUF9PUFRJT05TJ109IiR7TVlTUUxfRFVNUF9PUFRJT05TOi0tLWRlZmF1bHQtY2hhcmFjdGVyLXNldD11dGY4IC0tY29tcHJlc3MgLS1oZXgtYmxvYiAtLXJvdXRpbmVzIC0tdHJpZ2dlcnMgLS1zaW5nbGUtdHJhbnNhY3Rpb24gLS1zZXQtZ3RpZC1wdXJnZWQ9T0ZGIC0tY29sdW1uLXN0YXRpc3RpY3M9MCAke2luc3RhbmNlTmV3SW5zdGFuY2VbJ1NTTF9PUFRJT05TJ119fSIKICBpbnN0YW5jZU5ld0luc3RhbmNlWydEQl9JTVBPUlRfT1BUSU9OUyddPSIke0RCX0lNUE9SVF9PUFRJT05TOi0tLWNvbm5lY3QtdGltZW91dD01IC0tYmF0Y2ggLS1yYXcgLS1kZWZhdWx0LWNoYXJhY3Rlci1zZXQ9dXRmOH0iCgogIGluc3RhbmNlTmV3SW5zdGFuY2VbJ0lOSVRJQUxJWkVEJ109MQp9CgojIEBkZXNjcmlwdGlvbiBteXNxbCBxdWVyeSBvbiBhIGdpdmVuIGRiCiMgQHdhcm5pbmcgY291bGQgdXNlIFFVRVJZX09QVElPTlMgdmFyaWFibGUgZnJvbSBkc24gaWYgZGVmaW5lZAojIEBleGFtcGxlCiMgICBjYXQgZmlsZS5zcWwgfCBEYXRhYmFzZTo6cXVlcnkgLi4uCiMgQGFyZyAkMSBpbnN0YW5jZVF1ZXJ5OiZNYXA8U3RyaW5nLFN0cmluZz4gKHBhc3NlZCBieSByZWZlcmVuY2UpIGRhdGFiYXNlIGluc3RhbmNlIHRvIHVzZQojIEBhcmcgJDIgc3FsUXVlcnk6U3RyaW5nIChvcHRpb25hbCkgc3FsIHF1ZXJ5IG9yIHNxbCBmaWxlIHRvIGV4ZWN1dGUuIGlmIG5vdCBwcm92aWRlZCBvciBlbXB0eSwgdGhlIGNvbW1hbmQgY2FuIGJlIHBpcGVkCiMgQGFyZyAkMyBkYk5hbWU6U3RyaW5nIChvcHRpb25hbCkgdGhlIGRiIG5hbWUKIwojIEBleGl0Y29kZSBteXNxbCBjb21tYW5kIHN0YXR1cyBjb2RlCkRhdGFiYXNlOjpxdWVyeSgpIHsKICBsb2NhbCAtbiBpbnN0YW5jZVF1ZXJ5PSQxCiAgbG9jYWwgLWEgbXlzcWxDb21tYW5kPSgpCiAgbG9jYWwgLWEgcXVlcnlPcHRpb25zCgogIG15c3FsQ29tbWFuZCs9KG15c3FsKQogIG15c3FsQ29tbWFuZCs9KCItLWRlZmF1bHRzLWV4dHJhLWZpbGU9JHtpbnN0YW5jZVF1ZXJ5WydBVVRIX0ZJTEUnXX0iKQogIElGUz0nICcgcmVhZCAtciAtYSBxdWVyeU9wdGlvbnMgPDw8IiR7aW5zdGFuY2VRdWVyeVsnUVVFUllfT1BUSU9OUyddfSIKICBteXNxbENvbW1hbmQrPSgiJHtxdWVyeU9wdGlvbnNbQF19IikKICBpZiBbWyAiJHtpbnN0YW5jZVF1ZXJ5WydTS0lQX0NPTFVNTl9OQU1FUyddfSIgPSAiMSIgXV07IHRoZW4KICAgIG15c3FsQ29tbWFuZCs9KCItcyIgIi0tc2tpcC1jb2x1bW4tbmFtZXMiKQogIGZpCiAgIyBhZGQgb3B0aW9uYWwgZGIgbmFtZQogIGlmIFtbIC1uICIkezMreH0iIF1dOyB0aGVuCiAgICBteXNxbENvbW1hbmQrPSgiJDMiKQogIGZpCiAgIyBhZGQgb3B0aW9uYWwgc3FsIHF1ZXJ5CiAgaWYgW1sgLW4gIiR7Mit4fSIgJiYgLW4gIiQyIiAmJiAhIC1mICIkMiIgXV07IHRoZW4KICAgIG15c3FsQ29tbWFuZCs9KCItZSIpCiAgICBteXNxbENvbW1hbmQrPSgiJDIiKQogIGZpCiAgTG9nOjpkaXNwbGF5RGVidWcgIiQocHJpbnRmICJleGVjdXRlIGNvbW1hbmQ6ICclcyciICIke215c3FsQ29tbWFuZFsqXX0iKSIKCiAgaWYgW1sgLWYgIiQyIiBdXTsgdGhlbgogICAgIiR7bXlzcWxDb21tYW5kW0BdfSIgPCIkMiIKICBlbHNlCiAgICAiJHtteXNxbENvbW1hbmRbQF19IgogIGZpCn0KCiMgQGRlc2NyaXB0aW9uIHNldCB0aGUgZ2VuZXJhbCBvcHRpb25zIHRvIHVzZSBvbiBteXNxbCBjb21tYW5kIHRvIHF1ZXJ5IHRoZSBkYXRhYmFzZQojIERpZmZlcnMgdGhhbiBzZXRPcHRpb25zIGluIHRoZSB3YXkgdGhhdCB0aGVzZSBvcHRpb25zIGNvdWxkIGNoYW5nZSBlYWNoIHRpbWUKIwojIEBhcmcgJDEgaW5zdGFuY2VTZXRRdWVyeU9wdGlvbnM6Jk1hcDxTdHJpbmcsU3RyaW5nPiAocGFzc2VkIGJ5IHJlZmVyZW5jZSkgZGF0YWJhc2UgaW5zdGFuY2UgdG8gdXNlCiMgQGFyZyAkMiBvcHRpb25zTGlzdDpTdHJpbmcgcXVlcnkgb3B0aW9ucyBsaXN0CkRhdGFiYXNlOjpzZXRRdWVyeU9wdGlvbnMoKSB7CiAgbG9jYWwgLW4gaW5zdGFuY2VTZXRRdWVyeU9wdGlvbnM9JDEKICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICBpbnN0YW5jZVNldFF1ZXJ5T3B0aW9uc1snUVVFUllfT1BUSU9OUyddPSIkMiIKfQoKIyBAZGVzY3JpcHRpb24gYnkgZGVmYXVsdCB3ZSBza2lwIHRoZSBjb2x1bW4gbmFtZXMKIyBidXQgc29tZXRpbWVzIHdlIG5lZWQgY29sdW1uIG5hbWVzIHRvIGRpc3BsYXkgc29tZSByZXN1bHRzCiMgZGlzYWJsZSB0aGlzIG9wdGlvbiB0ZW1wb3JhcmlseSBhbmQgdGhlbiByZXN0b3JlIGl0IHRvIHRydWUKIwojIEBhcmcgJDEgaW5zdGFuY2VTZXRRdWVyeU9wdGlvbnM6Jk1hcDxTdHJpbmcsU3RyaW5nPiAocGFzc2VkIGJ5IHJlZmVyZW5jZSkgZGF0YWJhc2UgaW5zdGFuY2UgdG8gdXNlCiMgQGFyZyAkMiBza2lwQ29sdW1uTmFtZXM6Qm9vbGVhbiAwIHRvIGRpc2FibGUsIDEgdG8gZW5hYmxlIChoaWRlIGNvbHVtbiBuYW1lcykKRGF0YWJhc2U6OnNraXBDb2x1bW5OYW1lcygpIHsKICBsb2NhbCAtbiBpbnN0YW5jZVNraXBDb2x1bW5OYW1lcz0kMQogICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogIGluc3RhbmNlU2tpcENvbHVtbk5hbWVzWydTS0lQX0NPTFVNTl9OQU1FUyddPSIkMiIKfQoKIyBAZGVzY3JpcHRpb24gcHJlcGVuZCBkaXJlY3RvcmllcyB0byB0aGUgUEFUSCBlbnZpcm9ubWVudCB2YXJpYWJsZQojIEBhcmcgJEAgYXJnczpTdHJpbmdbXSBsaXN0IG9mIGRpcmVjdG9yaWVzIHRvIHByZXBlbmQKIyBAc2V0IFBBVEggdXBkYXRlIFBBVEggd2l0aCB0aGUgZGlyZWN0b3JpZXMgcHJlcGVuZGVkCkVudjo6cGF0aFByZXBlbmQoKSB7CiAgbG9jYWwgYXJnCiAgZm9yIGFyZyBpbiAiJEAiOyBkbwogICAgaWYgW1sgLWQgIiR7YXJnfSIgJiYgIjoke1BBVEh9OiIgIT0gKiI6JHthcmd9OiIqIF1dOyB0aGVuCiAgICAgIFBBVEg9IiQocmVhbHBhdGggIiR7YXJnfSIpOiR7UEFUSH0iCiAgICBmaQogIGRvbmUKfQoKIyBAZGVzY3JpcHRpb24gRGlzcGxheSBtZXNzYWdlIHVzaW5nIGVycm9yIGNvbG9yIChyZWQpIGFuZCBleGl0IGltbWVkaWF0ZWx5IHdpdGggZXJyb3Igc3RhdHVzIDEKIyBAYXJnICQxIG1lc3NhZ2U6U3RyaW5nIHRoZSBtZXNzYWdlIHRvIGRpc3BsYXkKTG9nOjpmYXRhbCgpIHsKICBlY2hvIC1lICIke19fRVJST1JfQ09MT1J9RkFUQUwgICAtICR7MX0ke19fUkVTRVRfQ09MT1J9IiA+JjIKICBMb2c6OmxvZ0ZhdGFsICIkMSIKICBleGl0IDEKfQoKIyBAZGVzY3JpcHRpb24gbG9nIG1lc3NhZ2UgdG8gZmlsZQojIEBhcmcgJDEgbWVzc2FnZTpTdHJpbmcgdGhlIG1lc3NhZ2UgdG8gZGlzcGxheQpMb2c6OmxvZ0RlYnVnKCkgewogIGlmICgoQkFTSF9GUkFNRVdPUktfTE9HX0xFVkVMID49IF9fTEVWRUxfREVCVUcpKTsgdGhlbgogICAgTG9nOjpsb2dNZXNzYWdlICIkezI6LURFQlVHfSIgIiQxIgogIGZpCn0KCiMgQGRlc2NyaXB0aW9uIGxvZyBtZXNzYWdlIHRvIGZpbGUKIyBAYXJnICQxIG1lc3NhZ2U6U3RyaW5nIHRoZSBtZXNzYWdlIHRvIGRpc3BsYXkKTG9nOjpsb2dJbmZvKCkgewogIGlmICgoQkFTSF9GUkFNRVdPUktfTE9HX0xFVkVMID49IF9fTEVWRUxfSU5GTykpOyB0aGVuCiAgICBMb2c6OmxvZ01lc3NhZ2UgIiR7MjotSU5GT30iICIkMSIKICBmaQp9CgojIEBkZXNjcmlwdGlvbiBlbnN1cmUgcnVubmluZyB1c2VyIGlzIG5vdCByb290CiMgQGV4aXRjb2RlIDEgaWYgY3VycmVudCB1c2VyIGlzIHJvb3QKIyBAc3RkZXJyIGRpYWdub3N0aWNzIGluZm9ybWF0aW9uIGlzIGRpc3BsYXllZApMaW51eDo6cmVxdWlyZUV4ZWN1dGVkQXNVc2VyKCkgewogIGlmIFtbICIkKGlkIC11KSIgPSAiMCIgXV07IHRoZW4KICAgIExvZzo6ZmF0YWwgInRoaXMgc2NyaXB0IHNob3VsZCBiZSBleGVjdXRlZCBhcyBub3JtYWwgdXNlciIKICBmaQp9CgojIEBkZXNjcmlwdGlvbiBnZXQgYWJzb2x1dGUgY29uZiBmaWxlIGZyb20gc3BlY2lmaWVkIGNvbmYgZm9sZGVyIGRlZHVjZWQgdXNpbmcgdGhlc2UgcnVsZXMKIyAgICogZnJvbSBhYnNvbHV0ZSBmaWxlIChpZ25vcmVzIDxjb25mRm9sZGVyPiBhbmQgPGV4dGVuc2lvbj4pCiMgICAqIHJlbGF0aXZlIHRvIHdoZXJlIHNjcmlwdCBpcyBleGVjdXRlZCAoaWdub3JlcyA8Y29uZkZvbGRlcj4gYW5kIDxleHRlbnNpb24+KQojICAgKiBmcm9tIGhvbWUvLmJhc2gtdG9vbHMvPGNvbmZGb2xkZXI+CiMgICAqIGZyb20gZnJhbWV3b3JrIGNvbmYvPGNvbmZGb2xkZXI+CiMKIyBAYXJnICQxIGNvbmZGb2xkZXI6U3RyaW5nIHRoZSBkaXJlY3RvcnkgbmFtZSAobm90IHRoZSBwYXRoKSB0byBsaXN0CiMgQGFyZyAkMiBjb25mOlN0cmluZyBmaWxlIHRvIHVzZSB3aXRob3V0IGV4dGVuc2lvbgojIEBhcmcgJDMgZXh0ZW5zaW9uOlN0cmluZyB0aGUgZXh0ZW5zaW9uICguc2ggYnkgZGVmYXVsdCkKIwojIEBzdGRvdXQgYWJzb2x1dGUgY29uZiBmaWxlbmFtZQojIEBleGl0Y29kZSAxIGlmIGZpbGUgaXMgbm90IGZvdW5kIGluIGFueSBsb2NhdGlvbgpDb25mOjpnZXRBYnNvbHV0ZUZpbGUoKSB7CiAgbG9jYWwgY29uZkZvbGRlcj0iJDEiCiAgbG9jYWwgY29uZj0iJDIiCiAgbG9jYWwgZXh0ZW5zaW9uPSIkezMtLnNofSIKICBpZiBbWyAtbiAiJHtleHRlbnNpb259IiAmJiAiJHtleHRlbnNpb246MDoxfSIgIT0gIi4iIF1dOyB0aGVuCiAgICBleHRlbnNpb249Ii4ke2V4dGVuc2lvbn0iCiAgZmkKCiAgdGVzdEFicygpIHsKICAgIGxvY2FsIHJlc3VsdAogICAgcmVzdWx0PSIkKHJlYWxwYXRoIC1lICIkMSIgMj4vZGV2L251bGwpIgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMTgxCiAgICBpZiBbWyAiJD8iID0gIjAiICYmIC1mICIke3Jlc3VsdH0iIF1dOyB0aGVuCiAgICAgIGVjaG8gIiR7cmVzdWx0fSIKICAgICAgcmV0dXJuIDAKICAgIGZpCiAgICByZXR1cm4gMQogIH0KCiAgIyBjb25mIGlzIGFic29sdXRlIGZpbGUgKGluY2x1ZGluZyBleHRlbnNpb24pCiAgdGVzdEFicyAiJHtjb25mRm9sZGVyfSR7ZXh0ZW5zaW9ufSIgJiYgcmV0dXJuIDAKICAjIGNvbmYgaXMgYWJzb2x1dGUgZmlsZQogIHRlc3RBYnMgIiR7Y29uZkZvbGRlcn0iICYmIHJldHVybiAwCiAgIyBjb25mIGlzIGFic29sdXRlIGZpbGUgKGluY2x1ZGluZyBleHRlbnNpb24pCiAgdGVzdEFicyAiJHtjb25mfSR7ZXh0ZW5zaW9ufSIgJiYgcmV0dXJuIDAKICAjIGNvbmYgaXMgYWJzb2x1dGUgZmlsZQogIHRlc3RBYnMgIiR7Y29uZn0iICYmIHJldHVybiAwCgogICMgcmVsYXRpdmUgdG8gd2hlcmUgc2NyaXB0IGlzIGV4ZWN1dGVkIChpbmNsdWRpbmcgZXh0ZW5zaW9uKQogIGlmIFtbIC1uICIke0NVUlJFTlRfRElSK3h4eH0iIF1dOyB0aGVuCiAgICB0ZXN0QWJzICIkKEZpbGU6OmNvbmNhdGVuYXRlUGF0aCAiJHtDVVJSRU5UX0RJUn0iICIke2NvbmZGb2xkZXJ9IikvJHtjb25mfSR7ZXh0ZW5zaW9ufSIgJiYgcmV0dXJuIDAKICBmaQogICMgZnJvbSBob21lLy5iYXNoLXRvb2xzLzxjb25mRm9sZGVyPgogIHRlc3RBYnMgIiQoRmlsZTo6Y29uY2F0ZW5hdGVQYXRoICIke0hPTUV9Ly5iYXNoLXRvb2xzIiAiJHtjb25mRm9sZGVyfSIpLyR7Y29uZn0ke2V4dGVuc2lvbn0iICYmIHJldHVybiAwCgogIGlmIFtbIC1uICIke0ZSQU1FV09SS19ST09UX0RJUit4eHh9IiBdXTsgdGhlbgogICAgIyBmcm9tIGZyYW1ld29yayBjb25mLzxjb25mRm9sZGVyPiAoaW5jbHVkaW5nIGV4dGVuc2lvbikKICAgIHRlc3RBYnMgIiQoRmlsZTo6Y29uY2F0ZW5hdGVQYXRoICIke0ZSQU1FV09SS19ST09UX0RJUn0vY29uZiIgIiR7Y29uZkZvbGRlcn0iKS8ke2NvbmZ9JHtleHRlbnNpb259IiAmJiByZXR1cm4gMAoKICAgICMgZnJvbSBmcmFtZXdvcmsgY29uZi88Y29uZkZvbGRlcj4KICAgIHRlc3RBYnMgIiQoRmlsZTo6Y29uY2F0ZW5hdGVQYXRoICIke0ZSQU1FV09SS19ST09UX0RJUn0vY29uZiIgIiR7Y29uZkZvbGRlcn0iKS8ke2NvbmZ9IiAmJiByZXR1cm4gMAogIGZpCgogICMgZmlsZSBub3QgZm91bmQKICBMb2c6OmRpc3BsYXlFcnJvciAiY29uZiBmaWxlICcke2NvbmZ9JyBub3QgZm91bmQiCgogIHJldHVybiAxCn0KCiMgQGRlc2NyaXB0aW9uIGNoZWNrIGlmIGRzbiBmaWxlIGhhcyBhbGwgdGhlIG1hbmRhdG9yeSB2YXJpYWJsZXMgc2V0CiMgTWFuZGF0b3J5IHZhcmlhYmxlcyBhcmU6IEhPU1ROQU1FLCBVU0VSLCBQQVNTV09SRCwgUE9SVAojCiMgQGFyZyAkMSBkc25GaWxlTmFtZTpTdHJpbmcgZHNuIGFic29sdXRlIGZpbGVuYW1lCiMgQHNldCBIT1NUTkFNRSBsb2FkZWQgZnJvbSBkc24gZmlsZQojIEBzZXQgUE9SVCBsb2FkZWQgZnJvbSBkc24gZmlsZQojIEBzZXQgVVNFUiBsb2FkZWQgZnJvbSBkc24gZmlsZQojIEBzZXQgUEFTU1dPUkQgbG9hZGVkIGZyb20gZHNuIGZpbGUKIyBAZXhpdGNvZGUgMCBvbiB2YWxpZCBmaWxlCiMgQGV4aXRjb2RlIDEgaWYgb25lIG9mIHRoZSBwcm9wZXJ0aWVzIG9mIHRoZSBjb25mIGZpbGUgaXMgaW52YWxpZCBvciBpZiBmaWxlIG5vdCBmb3VuZAojIEBzdGRlcnIgbG9nIG91dHB1dCBpZiBlcnJvciBmb3VuZCBpbiBjb25mIGZpbGUKRGF0YWJhc2U6OmNoZWNrRHNuRmlsZSgpIHsKICBsb2NhbCBkc25GaWxlTmFtZT0iJDEiCiAgaWYgW1sgISAtZiAiJHtkc25GaWxlTmFtZX0iIF1dOyB0aGVuCiAgICBMb2c6OmRpc3BsYXlFcnJvciAiZHNuIGZpbGUgJHtkc25GaWxlTmFtZX0gbm90IGZvdW5kIgogICAgcmV0dXJuIDEKICBmaQoKICAoCiAgICB1bnNldCBIT1NUTkFNRSBQT1JUIFBBU1NXT1JEIFVTRVIKICAgICMgc2hlbGxjaGVjayBzb3VyY2U9L3NyYy9EYXRhYmFzZS90ZXN0c0RhdGEvZHNuX3ZhbGlkLmVudgogICAgc291cmNlICIke2RzbkZpbGVOYW1lfSIKICAgIGlmIFtbIC16ICR7SE9TVE5BTUUreH0gXV07IHRoZW4KICAgICAgTG9nOjpkaXNwbGF5RXJyb3IgImRzbiBmaWxlICR7ZHNuRmlsZU5hbWV9IDogSE9TVE5BTUUgbm90IHByb3ZpZGVkIgogICAgICByZXR1cm4gMQogICAgZmkKICAgIGlmIFtbIC16ICIke0hPU1ROQU1FfSIgXV07IHRoZW4KICAgICAgTG9nOjpkaXNwbGF5V2FybmluZyAiZHNuIGZpbGUgJHtkc25GaWxlTmFtZX0gOiBIT1NUTkFNRSB2YWx1ZSBub3QgcHJvdmlkZWQiCiAgICBmaQogICAgaWYgW1sgIiR7SE9TVE5BTUV9IiA9ICJsb2NhbGhvc3QiIF1dOyB0aGVuCiAgICAgIExvZzo6ZGlzcGxheVdhcm5pbmcgImRzbiBmaWxlICR7ZHNuRmlsZU5hbWV9IDogY2hlY2sgdGhhdCBIT1NUTkFNRSBzaG91bGQgbm90IGJlIDEyNy4wLjAuMSBpbnN0ZWFkIG9mIGxvY2FsaG9zdCIKICAgIGZpCiAgICBpZiBbWyAteiAiJHtQT1JUK3h9IiBdXTsgdGhlbgogICAgICBMb2c6OmRpc3BsYXlFcnJvciAiZHNuIGZpbGUgJHtkc25GaWxlTmFtZX0gOiBQT1JUIG5vdCBwcm92aWRlZCIKICAgICAgcmV0dXJuIDEKICAgIGZpCiAgICBpZiAhIFtbICR7UE9SVH0gPX4gXlswLTldKyQgXV07IHRoZW4KICAgICAgTG9nOjpkaXNwbGF5RXJyb3IgImRzbiBmaWxlICR7ZHNuRmlsZU5hbWV9IDogUE9SVCBpbnZhbGlkIgogICAgICByZXR1cm4gMQogICAgZmkKICAgIGlmIFtbIC16ICIke1VTRVIreH0iIF1dOyB0aGVuCiAgICAgIExvZzo6ZGlzcGxheUVycm9yICJkc24gZmlsZSAke2RzbkZpbGVOYW1lfSA6IFVTRVIgbm90IHByb3ZpZGVkIgogICAgICByZXR1cm4gMQogICAgZmkKICAgIGlmIFtbIC16ICIke1BBU1NXT1JEK3h9IiBdXTsgdGhlbgogICAgICBMb2c6OmRpc3BsYXlFcnJvciAiZHNuIGZpbGUgJHtkc25GaWxlTmFtZX0gOiBQQVNTV09SRCBub3QgcHJvdmlkZWQiCiAgICAgIHJldHVybiAxCiAgICBmaQogICkKfQoKIyBAZGVzY3JpcHRpb24gbG9nIG1lc3NhZ2UgdG8gZmlsZQojIEBhcmcgJDEgbWVzc2FnZTpTdHJpbmcgdGhlIG1lc3NhZ2UgdG8gZGlzcGxheQpMb2c6OmxvZ0ZhdGFsKCkgewogIExvZzo6bG9nTWVzc2FnZSAiJHsyOi1GQVRBTH0iICIkMSIKfQoKIyBAZGVzY3JpcHRpb24gSW50ZXJuYWw6IGNvbW1vbiBsb2cgbWVzc2FnZQojIEBleGFtcGxlIHRleHQKIyAgIFtkYXRlXXxbbGV2ZWxNc2ddfG1lc3NhZ2UKIwojIEBleGFtcGxlIHRleHQKIyAgIDIwMjAtMDEtMTkgMTk6MjA6MjF8RVJST1IgIHxsb2cgZXJyb3IKIyAgIDIwMjAtMDEtMTkgMTk6MjA6MjF8U0tJUFBFRHxsb2cgc2tpcHBlZAojCiMgQGFyZyAkMSBsZXZlbE1zZzpTdHJpbmcgbWVzc2FnZSdzIGxldmVsIGRlc2NyaXB0aW9uIChlZzogU1RBVFVTLCBFUlJPUiwgLi4uKQojIEBhcmcgJDIgbXNnOlN0cmluZyB0aGUgbWVzc2FnZSB0byBkaXNwbGF5CiMgQGVudiBCQVNIX0ZSQU1FV09SS19MT0dfRklMRSBTdHJpbmcgbG9nIGZpbGUgdG8gdXNlLCBkbyBub3RoaW5nIGlmIGVtcHR5CiMgQGVudiBCQVNIX0ZSQU1FV09SS19MT0dfTEVWRUwgaW50IGxvZyBsZXZlbCBsb2cgb25seSBpZiA+IE9GRiBvciBmYXRhbCBtZXNzYWdlcwojIEBzdGRlcnIgZGlhZ25vc3RpY3MgaW5mb3JtYXRpb24gaXMgZGlzcGxheWVkCiMgQHJlcXVpcmUgRW52OjpyZXF1aXJlTG9hZAojIEByZXF1aXJlIExvZzo6cmVxdWlyZUxvYWQKTG9nOjpsb2dNZXNzYWdlKCkgewogIGxvY2FsIGxldmVsTXNnPSIkMSIKICBsb2NhbCBtc2c9IiQyIgogIGxvY2FsIGRhdGUKCiAgaWYgW1sgLW4gIiR7QkFTSF9GUkFNRVdPUktfTE9HX0ZJTEV9IiBdXSAmJiAoKEJBU0hfRlJBTUVXT1JLX0xPR19MRVZFTCA+IF9fTEVWRUxfT0ZGKSk7IHRoZW4KICAgIGRhdGU9IiQoZGF0ZSAnKyVZLSVtLSVkICVIOiVNOiVTJykiCiAgICB0b3VjaCAiJHtCQVNIX0ZSQU1FV09SS19MT0dfRklMRX0iCiAgICBwcmludGYgIiVzfCU3c3wlc1xuIiAiJHtkYXRlfSIgIiR7bGV2ZWxNc2d9IiAiJHttc2d9IiA+PiIke0JBU0hfRlJBTUVXT1JLX0xPR19GSUxFfSIKICBmaQp9CgojIEBkZXNjcmlwdGlvbiBjb25jYXRlbmF0ZSAyIHBhdGhzIGFuZCBlbnN1cmUgdGhlIHBhdGggaXMgY29ycmVjdCB1c2luZyByZWFscGF0aCAtbQojIEBhcmcgJDEgYmFzZVBhdGg6U3RyaW5nCiMgQGFyZyAkMiBzdWJQYXRoOlN0cmluZwojIEByZXF1aXJlIExpbnV4OjpyZXF1aXJlUmVhbHBhdGhDb21tYW5kCkZpbGU6OmNvbmNhdGVuYXRlUGF0aCgpIHsKICBsb2NhbCBiYXNlUGF0aD0iJDEiCiAgbG9jYWwgc3ViUGF0aD0iJDIiCiAgbG9jYWwgZnVsbFBhdGg9IiR7YmFzZVBhdGg6KyR7YmFzZVBhdGh9L30ke3N1YlBhdGh9IgoKICByZWFscGF0aCAtbSAiJHtmdWxsUGF0aH0iIDI+L2Rldi9udWxsCn0KCiMgQGRlc2NyaXB0aW9uIERpc3BsYXkgbWVzc2FnZSB1c2luZyBlcnJvciBjb2xvciAocmVkKQojIEBhcmcgJDEgbWVzc2FnZTpTdHJpbmcgdGhlIG1lc3NhZ2UgdG8gZGlzcGxheQpMb2c6OmRpc3BsYXlFcnJvcigpIHsKICBpZiAoKEJBU0hfRlJBTUVXT1JLX0RJU1BMQVlfTEVWRUwgPj0gX19MRVZFTF9FUlJPUikpOyB0aGVuCiAgICBlY2hvIC1lICIke19fRVJST1JfQ09MT1J9RVJST1IgICAtICR7MX0ke19fUkVTRVRfQ09MT1J9IiA+JjIKICBmaQogIExvZzo6bG9nRXJyb3IgIiQxIgp9CgojIEBkZXNjcmlwdGlvbiBEaXNwbGF5IG1lc3NhZ2UgdXNpbmcgd2FybmluZyBjb2xvciAoeWVsbG93KQojIEBhcmcgJDEgbWVzc2FnZTpTdHJpbmcgdGhlIG1lc3NhZ2UgdG8gZGlzcGxheQpMb2c6OmRpc3BsYXlXYXJuaW5nKCkgewogIGlmICgoQkFTSF9GUkFNRVdPUktfRElTUExBWV9MRVZFTCA+PSBfX0xFVkVMX1dBUk5JTkcpKTsgdGhlbgogICAgZWNobyAtZSAiJHtfX1dBUk5JTkdfQ09MT1J9V0FSTiAgICAtICR7MX0ke19fUkVTRVRfQ09MT1J9IiA+JjIKICBmaQogIExvZzo6bG9nV2FybmluZyAiJDEiCn0KCiMgQGRlc2NyaXB0aW9uIGVuc3VyZSBlbnYgZmlsZXMgYXJlIGxvYWRlZAojIEBub2FyZ3MKIyBAZXhpdGNvZGUgMSBpZiBnZXRPcmRlcmVkQ29uZkZpbGVzIGZhaWxzCiMgQGV4aXRjb2RlIDIgaWYgb25lIG9mIGVudiBmaWxlcyBmYWlscyB0byBsb2FkCiMgQHN0ZGVyciBkaWFnbm9zdGljcyBpbmZvcm1hdGlvbiBpcyBkaXNwbGF5ZWQKRW52OjpyZXF1aXJlTG9hZCgpIHsKICBsb2NhbCBjb25maWdGaWxlc1N0cgogIGNvbmZpZ0ZpbGVzU3RyPSIkKEVudjo6Z2V0T3JkZXJlZENvbmZGaWxlcykiIHx8IHJldHVybiAxCgogIGxvY2FsIC1hIGNvbmZpZ0ZpbGVzCiAgcmVhZGFycmF5IC10IGNvbmZpZ0ZpbGVzIDw8PCIke2NvbmZpZ0ZpbGVzU3RyfSIKCiAgIyBpZiBlbXB0eSBzdHJpbmcsIHRoZXJlIHdpbGwgYmUgb25lIGVsZW1lbnQKICBpZiAoKCR7I2NvbmZpZ0ZpbGVzW0BdfSA9PSAwKSkgfHwgW1sgLXogIiR7Y29uZmlnRmlsZXNTdHJ9IiBdXTsgdGhlbgogICAgIyBzaG91bGQgbm90IGhhcHBlbiwgYXMgdGhlcmUgaXMgYWx3YXlzIGRlZmF1bHQgZmlsZQogICAgTG9nOjpkaXNwbGF5U2tpcHBlZCAibm8gZW52IGZpbGUgdG8gbG9hZCIKICAgIHJldHVybiAwCiAgZmkKCiAgRW52OjptZXJnZUNvbmZGaWxlcyAiJHtjb25maWdGaWxlc1tAXX0iIHx8IHsKICAgIExvZzo6ZGlzcGxheUVycm9yICJ3aGlsZSBsb2FkaW5nIGNvbmZpZyBmaWxlczogJHtjb25maWdGaWxlc1sqXX0iCiAgICByZXR1cm4gMgogIH0KfQoKIyBAZGVzY3JpcHRpb24gYWN0aXZhdGUgb3Igbm90IExvZzo6ZGlzcGxheSogYW5kIExvZzo6bG9nKiBmdW5jdGlvbnMKIyBiYXNlZCBvbiBCQVNIX0ZSQU1FV09SS19ESVNQTEFZX0xFVkVMIGFuZCBCQVNIX0ZSQU1FV09SS19MT0dfTEVWRUwKIyBlbnZpcm9ubWVudCB2YXJpYWJsZXMgbG9hZGVkIGJ5IEVudjo6cmVxdWlyZUxvYWQKIyB0cnkgdG8gY3JlYXRlIGxvZyBmaWxlIGFuZCByb3RhdGUgaXQgaWYgbmVjZXNzYXJ5CiMgQG5vYXJncwojIEBzZXQgQkFTSF9GUkFNRVdPUktfTE9HX0xFVkVMIGludCB0byBPRkYgbGV2ZWwgaWYgQkFTSF9GUkFNRVdPUktfTE9HX0ZJTEUgaXMgZW1wdHkgb3Igbm90IHdyaXRhYmxlCiMgQGVudiBCQVNIX0ZSQU1FV09SS19ESVNQTEFZX0xFVkVMIGludAojIEBlbnYgQkFTSF9GUkFNRVdPUktfTE9HX0xFVkVMIGludAojIEBlbnYgQkFTSF9GUkFNRVdPUktfTE9HX0ZJTEUgU3RyaW5nCiMgQGVudiBCQVNIX0ZSQU1FV09SS19MT0dfRklMRV9NQVhfUk9UQVRJT04gaW50IGRvIGxvZyByb3RhdGlvbiBpZiA+IDAKIyBAZXhpdGNvZGUgMCBhbHdheXMgc3VjY2Vzc2Z1bAojIEBzdGRlcnIgZGlhZ25vc3RpY3MgaW5mb3JtYXRpb24gYWJvdXQgbG9nIGZpbGUgaXMgZGlzcGxheWVkCiMgQHJlcXVpcmUgRW52OjpyZXF1aXJlTG9hZAojIEByZXF1aXJlIFVJOjpyZXF1aXJlVGhlbWUKTG9nOjpyZXF1aXJlTG9hZCgpIHsKICBpZiBbWyAteiAiJHtCQVNIX0ZSQU1FV09SS19MT0dfRklMRTotfSIgXV07IHRoZW4KICAgIEJBU0hfRlJBTUVXT1JLX0xPR19MRVZFTD0ke19fTEVWRUxfT0ZGfQogICAgZXhwb3J0IEJBU0hfRlJBTUVXT1JLX0xPR19MRVZFTAogIGZpCgogIGlmICgoQkFTSF9GUkFNRVdPUktfTE9HX0xFVkVMID4gX19MRVZFTF9PRkYpKTsgdGhlbgogICAgaWYgW1sgISAtZiAiJHtCQVNIX0ZSQU1FV09SS19MT0dfRklMRX0iIF1dOyB0aGVuCiAgICAgIGlmCiAgICAgICAgISBta2RpciAtcCAiJChkaXJuYW1lICIke0JBU0hfRlJBTUVXT1JLX0xPR19GSUxFfSIpIiAyPi9kZXYvbnVsbCB8fAogICAgICAgICAgISB0b3VjaCAtLW5vLWNyZWF0ZSAiJHtCQVNIX0ZSQU1FV09SS19MT0dfRklMRX0iIDI+L2Rldi9udWxsCiAgICAgIHRoZW4KICAgICAgICBCQVNIX0ZSQU1FV09SS19MT0dfTEVWRUw9JHtfX0xFVkVMX09GRn0KICAgICAgICBlY2hvIC1lICIke19fRVJST1JfQ09MT1J9RVJST1IgICAtIEZpbGUgJHtCQVNIX0ZSQU1FV09SS19MT0dfRklMRX0gaXMgbm90IHdyaXRhYmxlJHtfX1JFU0VUX0NPTE9SfSIgPiYyCiAgICAgIGZpCiAgICBlbGlmIFtbICEgLXcgIiR7QkFTSF9GUkFNRVdPUktfTE9HX0ZJTEV9IiBdXTsgdGhlbgogICAgICBCQVNIX0ZSQU1FV09SS19MT0dfTEVWRUw9JHtfX0xFVkVMX09GRn0KICAgICAgZWNobyAtZSAiJHtfX0VSUk9SX0NPTE9SfUVSUk9SICAgLSBGaWxlICR7QkFTSF9GUkFNRVdPUktfTE9HX0ZJTEV9IGlzIG5vdCB3cml0YWJsZSR7X19SRVNFVF9DT0xPUn0iID4mMgogICAgZmkKCiAgZmkKCiAgaWYgKChCQVNIX0ZSQU1FV09SS19MT0dfTEVWRUwgPiBfX0xFVkVMX09GRikpOyB0aGVuCiAgICAjIHdpbGwgYWx3YXlzIGJlIGNyZWF0ZWQgZXZlbiBpZiBub3QgaW4gaW5mbyBsZXZlbAogICAgTG9nOjpsb2dNZXNzYWdlICJJTkZPIiAiTG9nZ2luZyB0byBmaWxlICR7QkFTSF9GUkFNRVdPUktfTE9HX0ZJTEV9IC0gTG9nIGxldmVsICR7QkFTSF9GUkFNRVdPUktfTE9HX0xFVkVMfSIKICAgIGlmICgoQkFTSF9GUkFNRVdPUktfTE9HX0ZJTEVfTUFYX1JPVEFUSU9OID4gMCkpOyB0aGVuCiAgICAgIExvZzo6cm90YXRlICIke0JBU0hfRlJBTUVXT1JLX0xPR19GSUxFfSIgIiR7QkFTSF9GUkFNRVdPUktfTE9HX0ZJTEVfTUFYX1JPVEFUSU9OfSIKICAgIGZpCiAgZmkKfQoKIyBAZGVzY3JpcHRpb24gZ2V0IGxpc3Qgb2YgZW52IGZpbGVzIHRvIGxvYWQKIyBpbiBvcmRlciB0byBtYWtlIHRoZW0gYXZhaWxhYmxlIGZvciBFbnY6OnJlcXVpcmVMb2FkCiMgQGVudiBCQVNIX0ZSQU1FV09SS19FTlZfRklMRVMgU3RyaW5nW10gbGlzdCBvZiBlbnYgZmlsZXMgdGhhdCBzaG91bGQgYmUgbG9hZGVkCiMgQGV4aXRjb2RlIDEgaWYgb25lIG9mIHRoZSBlbnYgZmlsZSBjYW5ub3QgYmUgZ2VuZXJhdGVkCiMgQGV4aXRjb2RlIDIgaWYgb25lIG9mIHRoZSBlbnYgZmlsZSBpcyBub3QgYSBmaWxlIG9yIHJlYWRhYmxlCiMgQHN0ZG91dCB0aGUgZW52IGZpbGVzIGFza2VkIHRvIGJlIGxvYWRlZAojIEBzdGRlcnIgZGlhZ25vc3RpYyBpbmZvcm1hdGlvbiBvbiBmYWlsdXJlCiMgQHNlZSBodHRwczovL2dpdGh1Yi5jb20vZmNoYXN0YW5ldC9iYXNoLXRvb2xzLWZyYW1ld29yay9ibG9iL21hc3Rlci9GcmFtZXdvcmtEb2MubWQjY29uZmlnX2ZpbGVfb3JkZXIKRW52OjpnZXRPcmRlcmVkQ29uZkZpbGVzKCkgewogIGxvY2FsIC1hIGNvbmZpZ0ZpbGVzPSgpCgogIGlmIFtbIC1uICIke0JBU0hfRlJBTUVXT1JLX0VOVl9GSUxFU1swXSsxfSIgXV07IHRoZW4KICAgICMgQkFTSF9GUkFNRVdPUktfRU5WX0ZJTEVTIGlzIGFuIGFycmF5CiAgICBjb25maWdGaWxlcys9KCIke0JBU0hfRlJBTUVXT1JLX0VOVl9GSUxFU1tAXX0iKQogIGZpCgogIGxvY2FsIGRlZmF1bHRFbnZGaWxlCiAgZGVmYXVsdEVudkZpbGU9IiQoRW52OjpjcmVhdGVEZWZhdWx0RW52RmlsZSkiIHx8IHJldHVybiAxCiAgY29uZmlnRmlsZXMrPSgiJHtkZWZhdWx0RW52RmlsZX0iKQoKICBsb2NhbCBmaWxlCiAgZm9yIGZpbGUgaW4gIiR7Y29uZmlnRmlsZXNbQF19IjsgZG8KICAgIGlmIFtbICEgLWYgIiR7ZmlsZX0iIHx8ICEgLXIgIiR7ZmlsZX0iIF1dOyB0aGVuCiAgICAgIExvZzo6ZGlzcGxheUVycm9yICJPbmUgb2YgdGhlIGNvbmZpZyBmaWxlIGlzIG5vdCBhdmFpbGFibGUgJyR7ZmlsZX0nIgogICAgICByZXR1cm4gMgogICAgZmkKICAgIGVjaG8gIiR7ZmlsZX0iCiAgZG9uZQp9CgojIEBkZXNjcmlwdGlvbiBtZXJnZSBhbmQgbG9hZCBjb25mIGZpbGVzIHNwZWNpZmllZCBhcyBhcmd1bWVudAojIC0gZmlsZXMgYXJlIGNsZWFuZWQgZnJvbSBheSBjb21tZW50CiMgLSBtaXNzaW5nIHF1b3RlcyBhZnRlciBwcm9wZXJ0eSA9IHNpZ24gYXJlIGFkZGVkIGF1dG9tYXRpY2FsbHkKIyAtIGF1dG9tYXRpYyByZW1vdmUgb2YgYWxsIHdoaXRlc3BhY2UgYmVmb3JlIGFuZCBhZnRlciBkZWNsYXJhdGlvbnMKIyAtIGJhc2ggYXJyYXlzIGFyZSBub3Qgc3VwcG9ydGVkCiMgLSBpZiBhIHZhcmlhYmxlIGlzIGRlY2xhcmVkIGluIGZpcnN0IGZpbGUgYW5kIG92ZXJyaWRkZW4gbGF0ZXIgb24KIyAgIGluIHRoZSBzYW1lIGZpbGUgb3IgaW4gc3Vic2VxdWVudCBmaWxlcywgdGhvc2Ugb3ZlcmxvYWRzIHdpbGwgYmUKIyAgIGlnbm9yZWQKIyBAd2FybmluZyBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgbG9hZGluZyBvbmUgb2YgdGhlIGNvbmZpZyBmaWxlLCBleGl0IGNvZGUgMyBidXQgZW52aXJvbm1lbnQgY291bGQgYmUgcGFydGlhbGx5IGxvYWRlZAojIEBhcmcgJEAgYXJnczpTdHJpbmdbXSBsaXN0IG9mIGNvbmZpZ3VyYXRpb24gZmlsZXMgdG8gbG9hZCBpbiBvcmRlcgojIEBzZXQgZW52VmFycyBTdHJpbmcgd2lsbCBzZXQgaW4gZW52aXJvbm1lbnQgYWxsIHRoZSB2YXJpYWJsZXMgdGhhdCBoYXZlIGJlZW4gZGVjbGFyZWQgaW4gdGhlIGNvbmZpZyBmaWxlcwojIEBlbnYgZW52VmFycyBTdHJpbmcgdGhlIGVudiB2YXJpYWJsZXMgb2YgdGhlIGN1cnJlbnQgc2NyaXB0IGNvdWxkIGJlIHVzZWQgdG8gaW50ZXJwcmV0IHZhcmlhYmxlcyBkdXJpbmcgY29uZmlnIGZpbGVzIHBhcnNpbmcKIyBAZXhpdGNvZGUgMCBpZiBubyBjb25maWcgZmlsZXMgcHJvdmlkZWQgb3IgbG9hZCBjb21wbGV0ZWQgc3VjY2Vzc2Z1bGx5CiMgQGV4aXRjb2RlIDEgaWYgZXJyb3Igb2NjdXJyZWQgZHVyaW5nIHBhcnNpbmcgdGhlIGNvbmZpZyBmaWxlcyAoZmlsZSBub3QgZm91bmQsIGdyZXAsIGF3ayBvciBzZWQgZXJyb3IpCiMgQGV4aXRjb2RlIDIgaWYgdGVtcG9yYXJ5IGZpbGUgY2Fubm90IGJlIGNyZWF0ZWQKIyBAZXhpdGNvZGUgMyBpZiBhbiBlcnJvciBvY2N1cnJlZCBkdXJpbmcgY29uZmlnIGZpbGUgc291cmNpbmcKIyBAc3RkZXJyIGRpYWdub3N0aWNzIGluZm9ybWF0aW9uIGlzIGRpc3BsYXllZAojIEBzZWUgbGFyZ2VseSBpbnNwaXJlZCBidXQgbW9kaWZpZWQgZnJvbSBodHRwczovL29wZW5zb3VyY2UuY29tL2FydGljbGUvMjEvNS9wcm9jZXNzaW5nLWNvbmZpZ3VyYXRpb24tZmlsZXMtc2hlbGwKRW52OjptZXJnZUNvbmZGaWxlcygpIHsKICBsb2NhbCAtYSBjb25maWdGaWxlTGlzdD0oIiRAIikKCiAgaWYgKCgkeyNjb25maWdGaWxlTGlzdFtAXX0gPT0gMCkpOyB0aGVuCiAgICByZXR1cm4gMAogIGZpCgogIGxvY2FsIGNvbWJpbmVkQ29uZmlnRmlsZQogIGNvbWJpbmVkQ29uZmlnRmlsZT0iJChGcmFtZXdvcms6OmNyZWF0ZVRlbXBGaWxlICJtZXJnZUNvbmZGaWxlcyIpIiB8fCByZXR1cm4gMgoKICAoCiAgICAjIHJlbW92ZXMgYW55IHRyYWlsaW5nIHdoaXRlc3BhY2UgZnJvbSBlYWNoIGZpbGUsIGlmIGFueQogICAgIyB0aGlzIGlzIGFic29sdXRlbHkgcmVxdWlyZWQgd2hlbiBpbXBvcnRpbmcgaW50byBDb25maWdNYXBzCiAgICAjIHB1dCBxdW90ZXMgYXJvdW5kIHZhbHVlcwogICAgc2VkIC1FIC1lICQncy9ccyokLy8gOyAvXiQvZCA7IC9eIy4qJC9kIDsgcy89KFteIlwnXS4qKSQvPSJcXDEiLycgIiR7Y29uZmlnRmlsZUxpc3RbQF19IiB8CiAgICAgICMgcmVtb3ZlIGFsbCBjb21tZW50IGxpbmVzCiAgICAgIEZpbHRlcnM6OmNvbW1lbnRMaW5lcyB8CiAgICAgICMgaXRlcmF0ZXMgb3ZlciBlYWNoIGZpbGUgYW5kIHByaW50cyAoZGVmYXVsdCBhd2sgYmVoYXZpb3IpCiAgICAgICMgZWFjaCB1bmlxdWUgbGluZTsgb25seSB0YWtlcyBmaXJzdCB2YWx1ZSBhbmQgaWdub3JlcyBkdXBsaWNhdGVzCiAgICAgIGF3ayAtRj0gJyFsaW5lWyQxXSsrJwogICkgPiIke2NvbWJpbmVkQ29uZmlnRmlsZX0iIHx8IHJldHVybiAxCgogICMgaGF2ZSB0byBleHBvcnQgZXZlcnl0aGluZywgYW5kIHNvdXJjZSBpdCB0d2ljZToKICAjIDEpIGZpcnN0IHNvdXJjZSBpcyB0byByZWFsaXplIHZhcmlhYmxlcwogICMgMikgc2Vjb25kIHRpbWUgaXMgdG8gcmVhbGl6ZSByZWZlcmVuY2VzCiAgc2V0IC1vIGFsbGV4cG9ydAogICMgc2hlbGxjaGVjayBzb3VyY2U9LmZyYW1ld29yay1jb25maWcKICBzb3VyY2UgIiR7Y29tYmluZWRDb25maWdGaWxlfSIgfHwgcmV0dXJuIDMKICAjIHNoZWxsY2hlY2sgc291cmNlPS5mcmFtZXdvcmstY29uZmlnCiAgc291cmNlICIke2NvbWJpbmVkQ29uZmlnRmlsZX0iIHx8IHJldHVybiAzCiAgc2V0ICtvIGFsbGV4cG9ydAp9CgojIEBkZXNjcmlwdGlvbiBEaXNwbGF5IG1lc3NhZ2UgdXNpbmcgc2tpcCBjb2xvciAoeWVsbG93KQojIEBhcmcgJDEgbWVzc2FnZTpTdHJpbmcgdGhlIG1lc3NhZ2UgdG8gZGlzcGxheQpMb2c6OmRpc3BsYXlTa2lwcGVkKCkgewogIGlmICgoQkFTSF9GUkFNRVdPUktfRElTUExBWV9MRVZFTCA+PSBfX0xFVkVMX0lORk8pKTsgdGhlbgogICAgZWNobyAtZSAiJHtfX1NLSVBQRURfQ09MT1J9U0tJUFBFRCAtICR7MX0ke19fUkVTRVRfQ09MT1J9IiA+JjIKICBmaQogIExvZzo6bG9nU2tpcHBlZCAiJDEiCn0KCiMgQGRlc2NyaXB0aW9uIGxvZyBtZXNzYWdlIHRvIGZpbGUKIyBAYXJnICQxIG1lc3NhZ2U6U3RyaW5nIHRoZSBtZXNzYWdlIHRvIGRpc3BsYXkKTG9nOjpsb2dFcnJvcigpIHsKICBpZiAoKEJBU0hfRlJBTUVXT1JLX0xPR19MRVZFTCA+PSBfX0xFVkVMX0VSUk9SKSk7IHRoZW4KICAgIExvZzo6bG9nTWVzc2FnZSAiJHsyOi1FUlJPUn0iICIkMSIKICBmaQp9CgojIEBkZXNjcmlwdGlvbiBsb2cgbWVzc2FnZSB0byBmaWxlCiMgQGFyZyAkMSBtZXNzYWdlOlN0cmluZyB0aGUgbWVzc2FnZSB0byBkaXNwbGF5CkxvZzo6bG9nV2FybmluZygpIHsKICBpZiAoKEJBU0hfRlJBTUVXT1JLX0xPR19MRVZFTCA+PSBfX0xFVkVMX1dBUk5JTkcpKTsgdGhlbgogICAgTG9nOjpsb2dNZXNzYWdlICIkezI6LVdBUk5JTkd9IiAiJDEiCiAgZmkKfQoKIyBAZGVzY3JpcHRpb24gVG8gYmUgY2FsbGVkIGJlZm9yZSBsb2dnaW5nIGluIHRoZSBsb2cgZmlsZQojIEBhcmcgJDEgZmlsZTpzdHJpbmcgbG9nIGZpbGUgbmFtZQojIEBhcmcgJDIgbWF4TG9nRmlsZXNDb3VudDppbnQgbWF4aW11bSBudW1iZXIgb2YgbG9nIGZpbGVzCkxvZzo6cm90YXRlKCkgewogIGxvY2FsIGZpbGU9IiQxIgogIGxvY2FsIG1heExvZ0ZpbGVzQ291bnQ9IiR7MjotNX0iCgogIGlmIFtbICEgLWYgIiR7ZmlsZX0iIF1dOyB0aGVuCiAgICBMb2c6OmRpc3BsYXlTa2lwcGVkICJMb2cgZmlsZSAke2ZpbGV9IGRvZXNuJ3QgZXhpc3QgeWV0IgogICAgcmV0dXJuIDAKICBmaQogIGZvciBpIGluICQoc2VxICQoKG1heExvZ0ZpbGVzQ291bnQgLSAxKSkgLTEgMSk7IGRvCiAgICBMb2c6OmRpc3BsYXlJbmZvICJMb2cgcm90YXRpb24gJHtmaWxlfS4ke2l9IHRvICR7ZmlsZX0uJCgoaSArIDEpKSIKICAgIG12ICIke2ZpbGV9LiJ7IiR7aX0iLCIkKChpICsgMSkpIn0gJj4vZGV2L251bGwgfHwgdHJ1ZQogIGRvbmUKICBpZiBjcCAiJHtmaWxlfSIgIiR7ZmlsZX0uMSIgJj4vZGV2L251bGw7IHRoZW4KICAgIGVjaG8gPiIke2ZpbGV9IiAjIHJlc2V0IGxvZyBmaWxlCiAgICBMb2c6OmRpc3BsYXlJbmZvICJMb2cgcm90YXRpb24gJHtmaWxlfSB0byAke2ZpbGV9LjEiCiAgZmkKfQoKIyBAZGVzY3JpcHRpb24gZW5zdXJlIGNvbW1hbmQgcmVhbHBhdGggaXMgYXZhaWxhYmxlCiMgQGV4aXRjb2RlIDEgaWYgcmVhbHBhdGggY29tbWFuZCBub3QgYXZhaWxhYmxlCiMgQHN0ZGVyciBkaWFnbm9zdGljcyBpbmZvcm1hdGlvbiBpcyBkaXNwbGF5ZWQKTGludXg6OnJlcXVpcmVSZWFscGF0aENvbW1hbmQoKSB7CiAgQXNzZXJ0Ojpjb21tYW5kRXhpc3RzIHJlYWxwYXRoCn0KCiMgQGRlc2NyaXB0aW9uIGxvYWQgY29sb3IgdGhlbWUKIyBAbm9hcmdzCiMgQGVudiBCQVNIX0ZSQU1FV09SS19USEVNRSBTdHJpbmcgdGhlbWUgdG8gdXNlCiMgQGV4aXRjb2RlIDAgYWx3YXlzIHN1Y2Nlc3NmdWwKVUk6OnJlcXVpcmVUaGVtZSgpIHsKICBVSTo6dGhlbWUgIiR7QkFTSF9GUkFNRVdPUktfVEhFTUUtZGVmYXVsdH0iCn0KCiMgQGRlc2NyaXB0aW9uIGNoZWNrIGlmIGNvbW1hbmQgc3BlY2lmaWVkIGV4aXN0cyBvciByZXR1cm4gMQojIHdpdGggZXJyb3IgYW5kIG1lc3NhZ2UgaWYgbm90CiMKIyBAYXJnICQxIGNvbW1hbmROYW1lOlN0cmluZyBvbiB3aGljaCBleGlzdGVuY2UgbXVzdCBiZSBjaGVja2VkCiMgQGFyZyAkMiBoZWxwSWZOb3RFeGlzdHM6U3RyaW5nIGEgaGVscCBjb21tYW5kIHRvIGRpc3BsYXkgaWYgdGhlIGNvbW1hbmQgZG9lcyBub3QgZXhpc3QKIwojIEBleGl0Y29kZSAxIGlmIHRoZSBjb21tYW5kIHNwZWNpZmllZCBkb2VzIG5vdCBleGlzdAojIEBzdGRlcnIgZGlhZ25vc3RpYyBpbmZvcm1hdGlvbiArIGhlbHAgaWYgc2Vjb25kIGFyZ3VtZW50IGlzIHByb3ZpZGVkCkFzc2VydDo6Y29tbWFuZEV4aXN0cygpIHsKICBsb2NhbCBjb21tYW5kTmFtZT0iJDEiCiAgbG9jYWwgaGVscElmTm90RXhpc3RzPSIkMiIKCiAgIiR7QkFTSF9GUkFNRVdPUktfQ09NTUFORDotY29tbWFuZH0iIC12ICIke2NvbW1hbmROYW1lfSIgPi9kZXYvbnVsbCAyPi9kZXYvbnVsbCB8fCB7CiAgICBMb2c6OmRpc3BsYXlFcnJvciAiJHtjb21tYW5kTmFtZX0gaXMgbm90IGluc3RhbGxlZCwgcGxlYXNlIGluc3RhbGwgaXQiCiAgICBpZiBbWyAtbiAiJHtoZWxwSWZOb3RFeGlzdHN9IiBdXTsgdGhlbgogICAgICBMb2c6OmRpc3BsYXlJbmZvICIke2hlbHBJZk5vdEV4aXN0c30iCiAgICBmaQogICAgcmV0dXJuIDEKICB9CiAgcmV0dXJuIDAKfQoKIyBAZGVzY3JpcHRpb24gZGVmYXVsdCBlbnYgZmlsZSB3aXRoIGFsbCBkZWZhdWx0IHZhbHVlcwojIEBzdGRvdXQgdGhlIGRlZmF1bHQgZW52IGZpbGVwYXRoCkVudjo6Y3JlYXRlRGVmYXVsdEVudkZpbGUoKSB7CiAgbG9jYWwgZW52RmlsZQogIGVudkZpbGU9IiQoRnJhbWV3b3JrOjpjcmVhdGVUZW1wRmlsZSAiY3JlYXRlRGVmYXVsdEVudkZpbGVFbnZGaWxlIikiIHx8IHJldHVybiAyCgogICgKICAgIGVjaG8gIkJBU0hfRlJBTUVXT1JLX1RIRU1FPSR7QkFTSF9GUkFNRVdPUktfVEhFTUU6LWRlZmF1bHR9IgogICAgZWNobyAiQkFTSF9GUkFNRVdPUktfTE9HX0xFVkVMPSR7QkFTSF9GUkFNRVdPUktfTE9HX0xFVkVMOi0wfSIKICAgIGVjaG8gIkJBU0hfRlJBTUVXT1JLX0RJU1BMQVlfTEVWRUw9JHtCQVNIX0ZSQU1FV09SS19ESVNQTEFZX0xFVkVMOi0ke19fTEVWRUxfV0FSTklOR319IgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDE2CiAgICBlY2hvICdCQVNIX0ZSQU1FV09SS19MT0dfRklMRT0iJHtCQVNIX0ZSQU1FV09SS19MT0dfRklMRTotIiR7RlJBTUVXT1JLX1JPT1RfRElSfS9sb2dzLyR7U0NSSVBUX05BTUV9LmxvZyJ9IicKICAgIGVjaG8gIkJBU0hfRlJBTUVXT1JLX0xPR19GSUxFX01BWF9ST1RBVElPTj0ke0JBU0hfRlJBTUVXT1JLX0xPR19GSUxFX01BWF9ST1RBVElPTjotNX0iCiAgKSA+IiR7ZW52RmlsZX0iCiAgZWNobyAiJHtlbnZGaWxlfSIKfQoKIyBAZGVzY3JpcHRpb24gcmVtb3ZlIGNvbW1lbnQgbGluZXMgZnJvbSBpbnB1dCBvciBmaWxlcyBwcm92aWRlZCBhcyBhcmd1bWVudHMKIyBAYXJnICRAIGZpbGVzOlN0cmluZ1tdIChvcHRpb25hbCkgdGhlIGZpbGVzIHRvIGZpbHRlcgojIEBlbnYgY29tbWVudExpbmVQcmVmaXggU3RyaW5nIHRoZSBjb21tZW50IGxpbmUgcHJlZml4IChkZWZhdWx0IHZhbHVlOiAjKQojIEBleGl0Y29kZSAwIGlmIGxpbmVzIGZpbHRlcmVkIG9yIG5vdAojIEBleGl0Y29kZSAyIGlmIGdyZXAgZmFpbHMgZm9yIGFueSBvdGhlciByZWFzb25zIHRoYW4gbm90IGZvdW5kCiMgQHN0ZGluIHRoZSBmaWxlIGFzIHN0ZGluIHRvIGZpbHRlciAoYWx0ZXJuYXRpdmUgdG8gZmlsZXMgYXJndW1lbnQpCiMgQHN0ZG91dCB0aGUgZmlsdGVyZWQgbGluZXMKIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMTIwCkZpbHRlcnM6OmNvbW1lbnRMaW5lcygpIHsKICBncmVwIC12eEUgIltbOmJsYW5rOl1dKigke2NvbW1lbnRMaW5lUHJlZml4Oi0jfS4qKT8iICIkQCIgfHwgdGVzdCAkPyA9IDEKfQoKIyBAZGVzY3JpcHRpb24gY3JlYXRlIGEgdGVtcCBmaWxlIHVzaW5nIGRlZmF1bHQgVE1QRElSIHZhcmlhYmxlCiMgaW5pdGlhbGl6ZWQgaW4gX2luY2x1ZGVzL19jb21tb25IZWFkZXIuc2gKIyBAZW52IFRNUERJUiBTdHJpbmcgKGRlZmF1bHQgdmFsdWUgL3RtcCkKIyBAYXJnICQxIHRlbXBsYXRlTmFtZTpTdHJpbmcgdGVtcGxhdGUgbmFtZSB0byB1c2Uob3B0aW9uYWwpCkZyYW1ld29yazo6Y3JlYXRlVGVtcEZpbGUoKSB7CiAgbWt0ZW1wIC1wICIke1RNUERJUjotL3RtcH0iIC10ICIkezE6LX0uWFhYWFhYWFhYWFhYIgp9CgojIEBkZXNjcmlwdGlvbiBsb2cgbWVzc2FnZSB0byBmaWxlCiMgQGFyZyAkMSBtZXNzYWdlOlN0cmluZyB0aGUgbWVzc2FnZSB0byBkaXNwbGF5CkxvZzo6bG9nU2tpcHBlZCgpIHsKICBpZiAoKEJBU0hfRlJBTUVXT1JLX0xPR19MRVZFTCA+PSBfX0xFVkVMX0lORk8pKTsgdGhlbgogICAgTG9nOjpsb2dNZXNzYWdlICIkezI6LVNLSVBQRUR9IiAiJDEiCiAgZmkKfQoKIyBAZGVzY3JpcHRpb24gbG9hZCBjb2xvcnMgdGhlbWUgY29uc3RhbnRzCiMgQHdhcm5pbmcgaWYgdHR5IG5vdCBvcGVuZWQsIG5vQ29sb3IgdGhlbWUgd2lsbCBiZSBjaG9zZW4KIyBAYXJnICQxIHRoZW1lOlN0cmluZyB0aGUgdGhlbWUgdG8gdXNlIChkZWZhdWx0LCBub0NvbG9yKQojIEBhcmcgJEAgYXJnczpTdHJpbmdbXQojIEBzZXQgX19FUlJPUl9DT0xPUiBTdHJpbmcgaW5kaWNhdGUgZXJyb3Igc3RhdHVzCiMgQHNldCBfX0lORk9fQ09MT1IgU3RyaW5nIGluZGljYXRlIGluZm8gc3RhdHVzCiMgQHNldCBfX1NVQ0NFU1NfQ09MT1IgU3RyaW5nIGluZGljYXRlIHN1Y2Nlc3Mgc3RhdHVzCiMgQHNldCBfX1dBUk5JTkdfQ09MT1IgU3RyaW5nIGluZGljYXRlIHdhcm5pbmcgc3RhdHVzCiMgQHNldCBfX1NLSVBQRURfQ09MT1IgU3RyaW5nIGluZGljYXRlIHNraXBwZWQgc3RhdHVzCiMgQHNldCBfX0RFQlVHX0NPTE9SIFN0cmluZyBpbmRpY2F0ZSBkZWJ1ZyBzdGF0dXMKIyBAc2V0IF9fSEVMUF9DT0xPUiBTdHJpbmcgaW5kaWNhdGUgaGVscCBzdGF0dXMKIyBAc2V0IF9fVEVTVF9DT0xPUiBTdHJpbmcgbm90IHVzZWQKIyBAc2V0IF9fVEVTVF9FUlJPUl9DT0xPUiBTdHJpbmcgbm90IHVzZWQKIyBAc2V0IF9fSEVMUF9USVRMRV9DT0xPUiBTdHJpbmcgdXNlZCB0byBkaXNwbGF5IGhlbHAgdGl0bGUgaW4gaGVscCBzdHJpbmdzCiMgQHNldCBfX0hFTFBfT1BUSU9OX0NPTE9SIFN0cmluZyB1c2VkIHRvIGRpc3BsYXkgaGlnaGxpZ2h0IG9wdGlvbnMgaW4gaGVscCBzdHJpbmdzCiMKIyBAc2V0IF9fUkVTRVRfQ09MT1IgU3RyaW5nIHJlc2V0IGRlZmF1bHQgY29sb3IKIwojIEBzZXQgX19IRUxQX0VYQU1QTEUgU3RyaW5nIHRvIHJlbW92ZQojIEBzZXQgX19IRUxQX1RJVExFIFN0cmluZyB0byByZW1vdmUKIyBAc2V0IF9fSEVMUF9OT1JNQUwgU3RyaW5nIHRvIHJlbW92ZQojIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKVUk6OnRoZW1lKCkgewogIGxvY2FsIHRoZW1lPSIkezEtZGVmYXVsdH0iCiAgaWYgW1sgISAiJHt0aGVtZX0iID1+IC1mb3JjZSQgXV0gJiYgISBBc3NlcnQ6OnR0eTsgdGhlbgogICAgdGhlbWU9Im5vQ29sb3IiCiAgZmkKICBjYXNlICIke3RoZW1lfSIgaW4KICAgIGRlZmF1bHQgfCBkZWZhdWx0LWZvcmNlKQogICAgICB0aGVtZT0iZGVmYXVsdCIKICAgICAgOzsKICAgIG5vQ29sb3IpIDs7CiAgICAqKQogICAgICBMb2c6OmZhdGFsICJpbnZhbGlkIHRoZW1lIHByb3ZpZGVkIgogICAgICA7OwogIGVzYWMKICBpZiBbWyAiJHt0aGVtZX0iID0gImRlZmF1bHQiIF1dOyB0aGVuCiAgICBCQVNIX0ZSQU1FV09SS19USEVNRT0iZGVmYXVsdCIKICAgICMgY2hlY2sgY29sb3JzIGFwcGxpY2FibGUgaHR0cHM6Ly9taXNjLmZsb2dpc29mdC5jb20vYmFzaC90aXBfY29sb3JzX2FuZF9mb3JtYXR0aW5nCiAgICBfX0VSUk9SX0NPTE9SPSdcZVszMW0nICAgICAgICAgIyBSZWQKICAgIF9fSU5GT19DT0xPUj0nXGVbNDRtJyAgICAgICAgICAjIHdoaXRlIG9uIGxpZ2h0Qmx1ZQogICAgX19TVUNDRVNTX0NPTE9SPSdcZVszMm0nICAgICAgICMgR3JlZW4KICAgIF9fV0FSTklOR19DT0xPUj0nXGVbMzNtJyAgICAgICAjIFllbGxvdwogICAgX19TS0lQUEVEX0NPTE9SPSdcZVszM20nICAgICAgICMgWWVsbG93CiAgICBfX0RFQlVHX0NPTE9SPSdcZVszN20nICAgICAgICAgIyBHcmV5CiAgICBfX0hFTFBfQ09MT1I9J1xlWzc7NDk7MzNtJyAgICAgIyBCbGFjayBvbiBHb2xkCiAgICBfX1RFU1RfQ09MT1I9J1xlWzEwMG0nICAgICAgICAgIyBMaWdodCBtYWdlbnRhCiAgICBfX1RFU1RfRVJST1JfQ09MT1I9J1xlWzQxbScgICAgIyB3aGl0ZSBvbiByZWQKICAgIF9fSEVMUF9USVRMRV9DT0xPUj0iXGVbMTszN20iICAjIEJvbGQKICAgIF9fSEVMUF9PUFRJT05fQ09MT1I9IlxlWzE7MzRtIiAjIEJsdWUKICAgICMgSW50ZXJuYWw6IHJlc2V0IGNvbG9yCiAgICBfX1JFU0VUX0NPTE9SPSdcZVswbScgIyBSZXNldCBDb2xvcgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMTU1LFNDMjAzNAogICAgX19IRUxQX0VYQU1QTEU9IiQoZWNobyAtZSAiXGVbMjs5N20iKSIKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjE1NSxTQzIwMzQKICAgIF9fSEVMUF9USVRMRT0iJChlY2hvIC1lICJcZVsxOzM3bSIpIgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMTU1LFNDMjAzNAogICAgX19IRUxQX05PUk1BTD0iJChlY2hvIC1lICJcMDMzWzBtIikiCiAgZWxzZQogICAgQkFTSF9GUkFNRVdPUktfVEhFTUU9Im5vQ29sb3IiCiAgICAjIGNoZWNrIGNvbG9ycyBhcHBsaWNhYmxlIGh0dHBzOi8vbWlzYy5mbG9naXNvZnQuY29tL2Jhc2gvdGlwX2NvbG9yc19hbmRfZm9ybWF0dGluZwogICAgX19FUlJPUl9DT0xPUj0nJwogICAgX19JTkZPX0NPTE9SPScnCiAgICBfX1NVQ0NFU1NfQ09MT1I9JycKICAgIF9fV0FSTklOR19DT0xPUj0nJwogICAgX19TS0lQUEVEX0NPTE9SPScnCiAgICBfX0RFQlVHX0NPTE9SPScnCiAgICBfX0hFTFBfQ09MT1I9JycKICAgIF9fVEVTVF9DT0xPUj0nJwogICAgX19URVNUX0VSUk9SX0NPTE9SPScnCiAgICBfX0hFTFBfVElUTEVfQ09MT1I9JycKICAgIF9fSEVMUF9PUFRJT05fQ09MT1I9JycKICAgICMgSW50ZXJuYWw6IHJlc2V0IGNvbG9yCiAgICBfX1JFU0VUX0NPTE9SPScnCiAgICBfX0hFTFBfRVhBTVBMRT0nJwogICAgX19IRUxQX1RJVExFPScnCiAgICBfX0hFTFBfTk9STUFMPScnCiAgZmkKfQoKIyBAZGVzY3JpcHRpb24gY2hlY2sgaWYgdHR5IChpbnRlcmFjdGl2ZSBtb2RlKSBpcyBhY3RpdmUKIyBAbm9hcmdzCiMgQGV4aXRjb2RlIDEgaWYgdHR5IG5vdCBhY3RpdmUKIyBAZW52IE5PTl9JTlRFUkFDVElWRSBpZiAxIGNvbnNpZGVyIGFzIG5vdCBpbnRlcmFjdGl2ZSBldmVuIGlmIGVudmlyb25tZW50IGlzIGludGVyYWN0aXZlCiMgQGVudiBJTlRFUkFDVElWRSBpZiAxIGNvbnNpZGVyIGFzIGludGVyYWN0aXZlIGV2ZW4gaWYgZW52aXJvbm1lbnQgaXMgbm90IGludGVyYWN0aXZlCiMgQHN0ZGVyciBkaWFnbm9zdGljIGluZm9ybWF0aW9uICsgaGVscCBpZiBzZWNvbmQgYXJndW1lbnQgaXMgcHJvdmlkZWQKQXNzZXJ0Ojp0dHkoKSB7CiAgaWYgW1sgIiR7Tk9OX0lOVEVSQUNUSVZFOi0wfSIgPSAiMSIgXV07IHRoZW4KICAgIHJldHVybiAxCiAgZmkKICBpZiBbWyAiJHtJTlRFUkFDVElWRTotMH0iID0gIjEiIF1dOyB0aGVuCiAgICByZXR1cm4gMAogIGZpCiAgW1sgLXQgMSB8fCAtdCAyIF1dCn0KCiMgRlVOQ1RJT05TCgpmYWNhZGVfbWFpbl9hMzk2ZTNlN2NiMzE0MDg0OGRlNGYwYWI0MzM4NDNiYigpIHsKIyBSRVFVSVJFUwpMaW51eDo6cmVxdWlyZUV4ZWN1dGVkQXNVc2VyCkVudjo6cmVxdWlyZUxvYWQKTG9nOjpyZXF1aXJlTG9hZApMaW51eDo6cmVxdWlyZVJlYWxwYXRoQ29tbWFuZApVSTo6cmVxdWlyZVRoZW1lCkNvbXBpbGVyOjpGYWNhZGU6OnJlcXVpcmVDb21tYW5kQmluRGlyCgojIEByZXF1aXJlIENvbXBpbGVyOjpGYWNhZGU6OnJlcXVpcmVDb21tYW5kQmluRGlyCgojIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIxNTQsU0MyMDE2CmZ1bmN0aW9uVG9DYWxsPSdEYjo6cXVlcnlPbmVEYXRhYmFzZScKIiR7ZnVuY3Rpb25Ub0NhbGx9IiAiJEAiCgp9CgpmYWNhZGVfbWFpbl9hMzk2ZTNlN2NiMzE0MDg0OGRlNGYwYWI0MzM4NDNiYiAiJEAiCg==" +declare -gx embed_function_DbQueryOneDatabase="${PERSISTENT_TMPDIR:-/tmp}/bin/370dab633b77b22851fe46e08d43de97/dbQueryOneDatabase" +declare -gx encoded_binary_file_DbQueryOneDatabase="IyEvdXNyL2Jpbi9lbnYgYmFzaAojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCiMgR0VORVJBVEVEIEZBQ0FERSBGUk9NIGh0dHBzOi8vZ2l0aHViLmNvbS9mY2hhc3RhbmV0L2Jhc2gtdG9vbHMvdHJlZS9tYXN0ZXIvLi4vYmFzaC1kZXYtZW52L3ZlbmRvci9iYXNoLXRvb2xzLWZyYW1ld29yay9zcmMvQ29tcGlsZXIvRW1iZWQvZW1iZWRGcmFtZXdvcmtGdW5jdGlvbi5iaW5GaWxlLnRwbAojIERPIE5PVCBFRElUIElUCiMgQGdlbmVyYXRlZAojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCiMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjI4OCxTQzIwMzQKIyBCSU5fRklMRT0ke0JJTl9GSUxFfQojIEZBQ0FERQoKIyBlbnN1cmUgdGhhdCBubyB1c2VyIGFsaWFzZXMgY291bGQgaW50ZXJmZXJlIHdpdGgKIyBjb21tYW5kcyB1c2VkIGluIHRoaXMgc2NyaXB0CnVuYWxpYXMgLWEgfHwgdHJ1ZQpzaG9wdCAtdSBleHBhbmRfYWxpYXNlcwoKIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CigoZmFpbHVyZXMgPSAwKSkgfHwgdHJ1ZQoKIyBCYXNoIHdpbGwgcmVtZW1iZXIgJiByZXR1cm4gdGhlIGhpZ2hlc3QgZXhpdCBjb2RlIGluIGEgY2hhaW4gb2YgcGlwZXMuCiMgVGhpcyB3YXkgeW91IGNhbiBjYXRjaCB0aGUgZXJyb3IgaW5zaWRlIHBpcGVzLCBlLmcuIG15c3FsZHVtcCB8IGd6aXAKc2V0IC1vIHBpcGVmYWlsCnNldCAtbyBlcnJleGl0CgojIENvbW1hbmQgU3Vic3RpdHV0aW9uIGNhbiBpbmhlcml0IGVycmV4aXQgb3B0aW9uIHNpbmNlIGJhc2ggdjQuNApzaG9wdCAtcyBpbmhlcml0X2VycmV4aXQgfHwgdHJ1ZQoKIyBhIGxvZyBpcyBnZW5lcmF0ZWQgd2hlbiBhIGNvbW1hbmQgZmFpbHMKc2V0IC1vIGVycnRyYWNlCgojIHVzZSBudWxsZ2xvYiBzbyB0aGF0IChmaWxlKi5waHApIHdpbGwgcmV0dXJuIGFuIGVtcHR5IGFycmF5IGlmIG5vIGZpbGUgbWF0Y2hlcyB0aGUgd2lsZGNhcmQKc2hvcHQgLXMgbnVsbGdsb2IKCiMgZW5zdXJlIHJlZ2V4cCBhcmUgaW50ZXJwcmV0ZWQgd2l0aG91dCBhY2NlbnR1YXRlZCBjaGFyYWN0ZXJzCmV4cG9ydCBMQ19BTEw9UE9TSVgKCmV4cG9ydCBURVJNPXh0ZXJtLTI1NmNvbG9yCgojIGF2b2lkIGludGVyYWN0aXZlIGluc3RhbGwKZXhwb3J0IERFQklBTl9GUk9OVEVORD1ub25pbnRlcmFjdGl2ZQpleHBvcnQgREVCQ09ORl9OT05JTlRFUkFDVElWRV9TRUVOPXRydWUKCiMgc3RvcmUgY29tbWFuZCBhcmd1bWVudHMgZm9yIGxhdGVyIHVzYWdlCiMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNApkZWNsYXJlIC1hIEJBU0hfRlJBTUVXT1JLX0FSR1Y9KCIkQCIpCiMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNApkZWNsYXJlIC1hIE9SSUdJTkFMX0JBU0hfRlJBTUVXT1JLX0FSR1Y9KCIkQCIpCgojIEBzZWUgaHR0cHM6Ly91bml4LnN0YWNrZXhjaGFuZ2UuY29tL2EvMzg2ODU2CiMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjMxNwppbnRlcnJ1cHRNYW5hZ2VtZW50KCkgewogICMgcmVzdG9yZSBTSUdJTlQgaGFuZGxlcgogIHRyYXAgLSBJTlQKICAjIGVuc3VyZSB0aGF0IEN0cmwtQyBpcyB0cmFwcGVkIGJ5IHRoaXMgc2NyaXB0IGFuZCBub3QgYnkgc3ViIHByb2Nlc3MKICAjIHJlcG9ydCB0byB0aGUgcGFyZW50IHRoYXQgd2UgaGF2ZSBpbmRlZWQgYmVlbiBpbnRlcnJ1cHRlZAogIGtpbGwgLXMgSU5UICIkJCIKfQp0cmFwIGludGVycnVwdE1hbmFnZW1lbnQgSU5UClNDUklQVF9OQU1FPSR7MCMjKi99ClJFQUxfU0NSSVBUX0ZJTEU9IiQocmVhZGxpbmsgLWUgIiQocmVhbHBhdGggIiR7QkFTSF9TT1VSQ0VbMF19IikiKSIKQ1VSUkVOVF9ESVI9IiQoY2QgIiQocmVhZGxpbmsgLWUgIiR7UkVBTF9TQ1JJUFRfRklMRSUvKn0iKSIgJiYgcHdkIC1QKSIKCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwojIFRlbXAgZGlyIG1hbmFnZW1lbnQKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCgpLRUVQX1RFTVBfRklMRVM9IiR7S0VFUF9URU1QX0ZJTEVTOi0wfSIKZXhwb3J0IEtFRVBfVEVNUF9GSUxFUwoKIyBQRVJTSVNURU5UX1RNUERJUiBpcyBub3QgZGVsZXRlZCBieSB0cmFwcwpQRVJTSVNURU5UX1RNUERJUj0iJHtUTVBESVI6LS90bXB9L2Jhc2gtZnJhbWV3b3JrIgpleHBvcnQgUEVSU0lTVEVOVF9UTVBESVIKbWtkaXIgLXAgIiR7UEVSU0lTVEVOVF9UTVBESVJ9IgoKIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0ClRNUERJUj0iJChta3RlbXAgLWQgLXAgIiR7UEVSU0lTVEVOVF9UTVBESVI6LS90bXB9IiAtdCBiYXNoLWZyYW1ld29yay0kJC1YWFhYWFgpIgpleHBvcnQgVE1QRElSCgojIHRlbXAgZGlyIGNsZWFuaW5nCiMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjMxNwpjbGVhbk9uRXhpdCgpIHsKICBpZiBbWyAiJHtLRUVQX1RFTVBfRklMRVM6LTB9IiA9ICIxIiBdXTsgdGhlbgogICAgTG9nOjpkaXNwbGF5SW5mbyAiS0VFUF9URU1QX0ZJTEVTPTEgdGVtcCBmaWxlcyBrZXB0IGhlcmUgJyR7VE1QRElSfSciCiAgZWxpZiBbWyAtbiAiJHtUTVBESVIreHh4fSIgXV07IHRoZW4KICAgIExvZzo6ZGlzcGxheURlYnVnICJLRUVQX1RFTVBfRklMRVM9MCByZW1vdmluZyB0ZW1wIGZpbGVzICcke1RNUERJUn0nIgogICAgcm0gLVJmICIke1RNUERJUjotL3RtcC9mYWtlfSIgPi9kZXYvbnVsbCAyPiYxCiAgZmkKfQp0cmFwIGNsZWFuT25FeGl0IEVYSVQgSFVQIFFVSVQgQUJSVCBURVJNCgojIFZBUl9NQUlOX0ZVTkNUSU9OX1ZBUl9OQU1FPWRiUXVlcnlBbGxEYXRhYmFzZXNGYWNhZGUKCiMgQGRlc2NyaXB0aW9uIHVzZWQgdG8gZXhlY3V0ZSBnaXZlbiBxdWVyeSB3aGVuIHVzaW5nCiMgZGJTY3JpcHRBbGxEYXRhYmFzZXMKIyBAYXJnICQxIGRzbjpTdHJpbmcKIyBAYXJnICQyIGRiOlN0cmluZwojIEBlbnYgcXVlcnkgU3RyaW5nCiMgQGVudiBvcHRpb25TZXBhcmF0b3IgU3RyaW5nCiMgQHJlcXVpcmUgTGludXg6OnJlcXVpcmVFeGVjdXRlZEFzVXNlcgpEYjo6cXVlcnlPbmVEYXRhYmFzZSgpIHsKICAjIHF1ZXJ5IGFuZCBvcHRpb25TZXBhcmF0b3IgYXJlIHBhc3NlZCB2aWEgZXhwb3J0CiAgbG9jYWwgZHNuPSIkMSIKICBsb2NhbCBkYj0iJDIiCgogIGxvY2FsIC1BIGRiSW5zdGFuY2UKICBEYXRhYmFzZTo6bmV3SW5zdGFuY2UgZGJJbnN0YW5jZSAiJHtkc259IgogIERhdGFiYXNlOjpzZXRRdWVyeU9wdGlvbnMgZGJJbnN0YW5jZSAiJHtkYkluc3RhbmNlW1FVRVJZX09QVElPTlNdfSAtLWNvbm5lY3QtdGltZW91dD01IgoKICAjIGlkZW50aWZ5IGNvbHVtbnMgaGVhZGVyCiAgZWNobyAtbiAiQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAiCiAgRGF0YWJhc2U6OnNraXBDb2x1bW5OYW1lcyBkYkluc3RhbmNlIDAKCiAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMTU0CiAgaWYgISBEYXRhYmFzZTo6cXVlcnkgZGJJbnN0YW5jZSAiJHtxdWVyeX0iICIke2RifSIgfCBzZWQgInMvXHQvJHtvcHRpb25TZXBhcmF0b3J9L2ciOyB0aGVuCiAgICBMb2c6OmZhdGFsICJkYXRhYmFzZSAke2RifSBlcnJvciIgMT4mMgogIGZpCn0KCiMgQGRlc2NyaXB0aW9uIExvZyBuYW1lc3BhY2UgcHJvdmlkZXMgMiBraW5kIG9mIGZ1bmN0aW9ucwojIC0gTG9nOjpkaXNwbGF5KiBhbGxvd3MgdG8gZGlzcGxheSBnaXZlbiBtZXNzYWdlIHdpdGgKIyAgIGdpdmVuIGRpc3BsYXkgbGV2ZWwKIyAtIExvZzo6bG9nKiBhbGxvd3MgdG8gbG9nIGdpdmVuIG1lc3NhZ2Ugd2l0aAojICAgZ2l2ZW4gbG9nIGxldmVsCiMgTG9nOjpkaXNwbGF5KiBmdW5jdGlvbnMgYXV0b21hdGljYWxseSBsb2cgdGhlIG1lc3NhZ2UgdG9vCiMgQHNlZSBFbnY6OnJlcXVpcmVMb2FkIHRvIGxvYWQgdGhlIGRpc3BsYXkgYW5kIGxvZyBsZXZlbCBmcm9tIC5lbnYgZmlsZQoKIyBAZGVzY3JpcHRpb24gbG9nIGxldmVsIG9mZgpleHBvcnQgX19MRVZFTF9PRkY9MAojIEBkZXNjcmlwdGlvbiBsb2cgbGV2ZWwgZXJyb3IKZXhwb3J0IF9fTEVWRUxfRVJST1I9MQojIEBkZXNjcmlwdGlvbiBsb2cgbGV2ZWwgd2FybmluZwpleHBvcnQgX19MRVZFTF9XQVJOSU5HPTIKIyBAZGVzY3JpcHRpb24gbG9nIGxldmVsIGluZm8KZXhwb3J0IF9fTEVWRUxfSU5GTz0zCiMgQGRlc2NyaXB0aW9uIGxvZyBsZXZlbCBzdWNjZXNzCmV4cG9ydCBfX0xFVkVMX1NVQ0NFU1M9MwojIEBkZXNjcmlwdGlvbiBsb2cgbGV2ZWwgZGVidWcKZXhwb3J0IF9fTEVWRUxfREVCVUc9NAoKIyBAZGVzY3JpcHRpb24gdmVyYm9zZSBsZXZlbCBvZmYKZXhwb3J0IF9fVkVSQk9TRV9MRVZFTF9PRkY9MAojIEBkZXNjcmlwdGlvbiB2ZXJib3NlIGxldmVsIGluZm8KZXhwb3J0IF9fVkVSQk9TRV9MRVZFTF9JTkZPPTEKIyBAZGVzY3JpcHRpb24gdmVyYm9zZSBsZXZlbCBpbmZvCmV4cG9ydCBfX1ZFUkJPU0VfTEVWRUxfREVCVUc9MgojIEBkZXNjcmlwdGlvbiB2ZXJib3NlIGxldmVsIGluZm8KZXhwb3J0IF9fVkVSQk9TRV9MRVZFTF9UUkFDRT0zCgojIEBkZXNjcmlwdGlvbiBEaXNwbGF5IG1lc3NhZ2UgdXNpbmcgZGVidWcgY29sb3IgKGdyZXkpCiMgQGFyZyAkMSBtZXNzYWdlOlN0cmluZyB0aGUgbWVzc2FnZSB0byBkaXNwbGF5CkxvZzo6ZGlzcGxheURlYnVnKCkgewogIGlmICgoQkFTSF9GUkFNRVdPUktfRElTUExBWV9MRVZFTCA+PSBfX0xFVkVMX0RFQlVHKSk7IHRoZW4KICAgIGVjaG8gLWUgIiR7X19ERUJVR19DT0xPUn1ERUJVRyAgIC0gJHsxfSR7X19SRVNFVF9DT0xPUn0iID4mMgogIGZpCiAgTG9nOjpsb2dEZWJ1ZyAiJDEiCn0KCiMgQGRlc2NyaXB0aW9uIERpc3BsYXkgbWVzc2FnZSB1c2luZyBpbmZvIGNvbG9yIChiZyBsaWdodCBibHVlL2ZnIHdoaXRlKQojIEBhcmcgJDEgbWVzc2FnZTpTdHJpbmcgdGhlIG1lc3NhZ2UgdG8gZGlzcGxheQpMb2c6OmRpc3BsYXlJbmZvKCkgewogIGxvY2FsIHR5cGU9IiR7MjotSU5GT30iCiAgaWYgKChCQVNIX0ZSQU1FV09SS19ESVNQTEFZX0xFVkVMID49IF9fTEVWRUxfSU5GTykpOyB0aGVuCiAgICBlY2hvIC1lICIke19fSU5GT19DT0xPUn0ke3R5cGV9ICAgIC0gJHsxfSR7X19SRVNFVF9DT0xPUn0iID4mMgogIGZpCiAgTG9nOjpsb2dJbmZvICIkMSIgIiR7dHlwZX0iCn0KCiMgQGRlc2NyaXB0aW9uIGVuc3VyZSBDT01NQU5EX0JJTl9ESVIgZW52IHZhciBpcyBzZXQKIyBhbmQgUEFUSCBjb3JyZWN0bHkgcHJlcGFyZWQKIyBAbm9hcmdzCiMgQHNldCBDT01NQU5EX0JJTl9ESVIgc3RyaW5nIHRoZSBkaXJlY3Rvcnkgd2hlcmUgdG8gZmluZCB0aGlzIGNvbW1hbmQKIyBAc2V0IFBBVEggc3RyaW5nIGFkZCBkaXJlY3Rvcnkgd2hlcmUgdG8gZmluZCB0aGlzIGNvbW1hbmQgYmluYXJ5CkNvbXBpbGVyOjpGYWNhZGU6OnJlcXVpcmVDb21tYW5kQmluRGlyKCkgewogIENPTU1BTkRfQklOX0RJUj0iJHtDVVJSRU5UX0RJUn0iCiAgRW52OjpwYXRoUHJlcGVuZCAiJHtDT01NQU5EX0JJTl9ESVJ9Igp9CgojIEBkZXNjcmlwdGlvbiBjcmVhdGUgYSBuZXcgZGIgaW5zdGFuY2UKIyBSZXR1cm5zIGltbWVkaWF0ZWx5IGlmIHRoZSBpbnN0YW5jZSBpcyBhbHJlYWR5IGluaXRpYWxpemVkCiMKIyBAYXJnICQxIGluc3RhbmNlTmV3SW5zdGFuY2U6Jk1hcDxTdHJpbmcsU3RyaW5nPiAocGFzc2VkIGJ5IHJlZmVyZW5jZSkgZGF0YWJhc2UgaW5zdGFuY2UgdG8gdXNlCiMgQGFyZyAkMiBkc246U3RyaW5nIGRzbiBwcm9maWxlIC0gbG9hZCB0aGUgZHNuLmVudiBwcm9maWxlIGRlZHVjZWQgdXNpbmcgcnVsZXMgZGVmaW5lZCBpbiBDb25mOjpnZXRBYnNvbHV0ZUZpbGUKIwojIEBleGFtcGxlCiMgICBkZWNsYXJlIC1BZ3ggZGJJbnN0YW5jZQojICAgRGF0YWJhc2U6Om5ld0luc3RhbmNlIGRiSW5zdGFuY2UgImRlZmF1bHQubG9jYWwiCiMKIyBAZXhpdGNvZGUgMSBpZiBkbnMgZmlsZSBub3QgYWJsZSB0byBsb2FkZWQKRGF0YWJhc2U6Om5ld0luc3RhbmNlKCkgewogIGxvY2FsIC1uIGluc3RhbmNlTmV3SW5zdGFuY2U9JDEKICBsb2NhbCBkc249IiQyIgogIGxvY2FsIERTTl9GSUxFCgogIGlmIFtbIC12IGluc3RhbmNlTmV3SW5zdGFuY2VbJ0lOSVRJQUxJWkVEJ10gJiYgIiR7aW5zdGFuY2VOZXdJbnN0YW5jZVsnSU5JVElBTElaRUQnXTotMH0iID09ICIxIiBdXTsgdGhlbgogICAgcmV0dXJuCiAgZmkKCiAgIyBmaW5hbCBhdXRoIGZpbGUgZ2VuZXJhdGVkIGZyb20gZG5zIGZpbGUKICBpbnN0YW5jZU5ld0luc3RhbmNlWydBVVRIX0ZJTEUnXT0iIgogIGluc3RhbmNlTmV3SW5zdGFuY2VbJ0RTTl9GSUxFJ109IiIKCiAgIyBjaGVjayBkc24gZmlsZQogIERTTl9GSUxFPSIkKENvbmY6OmdldEFic29sdXRlRmlsZSAiZHNuIiAiJHtkc259IiAiZW52IikiIHx8IHJldHVybiAxCiAgRGF0YWJhc2U6OmNoZWNrRHNuRmlsZSAiJHtEU05fRklMRX0iIHx8IHJldHVybiAxCiAgaW5zdGFuY2VOZXdJbnN0YW5jZVsnRFNOX0ZJTEUnXT0iJHtEU05fRklMRX0iCgogICMgc2hlbGxjaGVjayBzb3VyY2U9L3NyYy9EYXRhYmFzZS90ZXN0c0RhdGEvZHNuX3ZhbGlkLmVudgogIHNvdXJjZSAiJHtpbnN0YW5jZU5ld0luc3RhbmNlWydEU05fRklMRSddfSIKCiAgaW5zdGFuY2VOZXdJbnN0YW5jZVsnVVNFUiddPSIke1VTRVJ9IgogIGluc3RhbmNlTmV3SW5zdGFuY2VbJ1BBU1NXT1JEJ109IiR7UEFTU1dPUkR9IgogIGluc3RhbmNlTmV3SW5zdGFuY2VbJ0hPU1ROQU1FJ109IiR7SE9TVE5BTUV9IgogIGluc3RhbmNlTmV3SW5zdGFuY2VbJ1BPUlQnXT0iJHtQT1JUfSIKCiAgIyBnZW5lcmF0ZSBhdXRoRmlsZSBmb3IgZWFzeSBhdXRoZW50aWNhdGlvbgogIGluc3RhbmNlTmV3SW5zdGFuY2VbJ0FVVEhfRklMRSddPSQobWt0ZW1wIC1wICIke1RNUERJUjotL3RtcH0iIC10ICJteXNxbC5YWFhYWFhYWFhYWFgiKQogICgKICAgIGVjaG8gIltjbGllbnRdIgogICAgZWNobyAidXNlciA9ICR7VVNFUn0iCiAgICBlY2hvICJwYXNzd29yZCA9ICR7UEFTU1dPUkR9IgogICAgZWNobyAiaG9zdCA9ICR7SE9TVE5BTUV9IgogICAgZWNobyAicG9ydCA9ICR7UE9SVH0iCiAgKSA+IiR7aW5zdGFuY2VOZXdJbnN0YW5jZVsnQVVUSF9GSUxFJ119IgoKICAjIHNvbWUgb2YgdGhvc2UgdmFsdWVzIGNhbiBiZSBvdmVycmlkZGVuIHVzaW5nIHRoZSBkc24gZmlsZQogICMgU0tJUF9DT0xVTU5fTkFNRVMgZW5hYmxlZCBieSBkZWZhdWx0CiAgaW5zdGFuY2VOZXdJbnN0YW5jZVsnU0tJUF9DT0xVTU5fTkFNRVMnXT0iJHtTS0lQX0NPTFVNTl9OQU1FUzotMX0iCiAgaW5zdGFuY2VOZXdJbnN0YW5jZVsnU1NMX09QVElPTlMnXT0iJHtNWVNRTF9TU0xfT1BUSU9OUzotLS1zc2wtbW9kZT1ESVNBQkxFRH0iCiAgaW5zdGFuY2VOZXdJbnN0YW5jZVsnUVVFUllfT1BUSU9OUyddPSIke01ZU1FMX1FVRVJZX09QVElPTlM6LS0tYmF0Y2ggLS1yYXcgLS1kZWZhdWx0LWNoYXJhY3Rlci1zZXQ9dXRmOH0iCiAgaW5zdGFuY2VOZXdJbnN0YW5jZVsnRFVNUF9PUFRJT05TJ109IiR7TVlTUUxfRFVNUF9PUFRJT05TOi0tLWRlZmF1bHQtY2hhcmFjdGVyLXNldD11dGY4IC0tY29tcHJlc3MgLS1oZXgtYmxvYiAtLXJvdXRpbmVzIC0tdHJpZ2dlcnMgLS1zaW5nbGUtdHJhbnNhY3Rpb24gLS1zZXQtZ3RpZC1wdXJnZWQ9T0ZGIC0tY29sdW1uLXN0YXRpc3RpY3M9MCAke2luc3RhbmNlTmV3SW5zdGFuY2VbJ1NTTF9PUFRJT05TJ119fSIKICBpbnN0YW5jZU5ld0luc3RhbmNlWydEQl9JTVBPUlRfT1BUSU9OUyddPSIke0RCX0lNUE9SVF9PUFRJT05TOi0tLWNvbm5lY3QtdGltZW91dD01IC0tYmF0Y2ggLS1yYXcgLS1kZWZhdWx0LWNoYXJhY3Rlci1zZXQ9dXRmOH0iCgogIGluc3RhbmNlTmV3SW5zdGFuY2VbJ0lOSVRJQUxJWkVEJ109MQp9CgojIEBkZXNjcmlwdGlvbiBteXNxbCBxdWVyeSBvbiBhIGdpdmVuIGRiCiMgQHdhcm5pbmcgY291bGQgdXNlIFFVRVJZX09QVElPTlMgdmFyaWFibGUgZnJvbSBkc24gaWYgZGVmaW5lZAojIEBleGFtcGxlCiMgICBjYXQgZmlsZS5zcWwgfCBEYXRhYmFzZTo6cXVlcnkgLi4uCiMgQGFyZyAkMSBpbnN0YW5jZVF1ZXJ5OiZNYXA8U3RyaW5nLFN0cmluZz4gKHBhc3NlZCBieSByZWZlcmVuY2UpIGRhdGFiYXNlIGluc3RhbmNlIHRvIHVzZQojIEBhcmcgJDIgc3FsUXVlcnk6U3RyaW5nIChvcHRpb25hbCkgc3FsIHF1ZXJ5IG9yIHNxbCBmaWxlIHRvIGV4ZWN1dGUuIGlmIG5vdCBwcm92aWRlZCBvciBlbXB0eSwgdGhlIGNvbW1hbmQgY2FuIGJlIHBpcGVkCiMgQGFyZyAkMyBkYk5hbWU6U3RyaW5nIChvcHRpb25hbCkgdGhlIGRiIG5hbWUKIwojIEBleGl0Y29kZSBteXNxbCBjb21tYW5kIHN0YXR1cyBjb2RlCkRhdGFiYXNlOjpxdWVyeSgpIHsKICBsb2NhbCAtbiBpbnN0YW5jZVF1ZXJ5PSQxCiAgbG9jYWwgLWEgbXlzcWxDb21tYW5kPSgpCiAgbG9jYWwgLWEgcXVlcnlPcHRpb25zCgogIG15c3FsQ29tbWFuZCs9KG15c3FsKQogIG15c3FsQ29tbWFuZCs9KCItLWRlZmF1bHRzLWV4dHJhLWZpbGU9JHtpbnN0YW5jZVF1ZXJ5WydBVVRIX0ZJTEUnXX0iKQogIElGUz0nICcgcmVhZCAtciAtYSBxdWVyeU9wdGlvbnMgPDw8IiR7aW5zdGFuY2VRdWVyeVsnUVVFUllfT1BUSU9OUyddfSIKICBteXNxbENvbW1hbmQrPSgiJHtxdWVyeU9wdGlvbnNbQF19IikKICBpZiBbWyAiJHtpbnN0YW5jZVF1ZXJ5WydTS0lQX0NPTFVNTl9OQU1FUyddfSIgPSAiMSIgXV07IHRoZW4KICAgIG15c3FsQ29tbWFuZCs9KCItcyIgIi0tc2tpcC1jb2x1bW4tbmFtZXMiKQogIGZpCiAgIyBhZGQgb3B0aW9uYWwgZGIgbmFtZQogIGlmIFtbIC1uICIkezMreH0iIF1dOyB0aGVuCiAgICBteXNxbENvbW1hbmQrPSgiJDMiKQogIGZpCiAgIyBhZGQgb3B0aW9uYWwgc3FsIHF1ZXJ5CiAgaWYgW1sgLW4gIiR7Mit4fSIgJiYgLW4gIiQyIiAmJiAhIC1mICIkMiIgXV07IHRoZW4KICAgIG15c3FsQ29tbWFuZCs9KCItZSIpCiAgICBteXNxbENvbW1hbmQrPSgiJDIiKQogIGZpCiAgTG9nOjpkaXNwbGF5RGVidWcgIiQocHJpbnRmICJleGVjdXRlIGNvbW1hbmQ6ICclcyciICIke215c3FsQ29tbWFuZFsqXX0iKSIKCiAgaWYgW1sgLWYgIiQyIiBdXTsgdGhlbgogICAgIiR7bXlzcWxDb21tYW5kW0BdfSIgPCIkMiIKICBlbHNlCiAgICAiJHtteXNxbENvbW1hbmRbQF19IgogIGZpCn0KCiMgQGRlc2NyaXB0aW9uIHNldCB0aGUgZ2VuZXJhbCBvcHRpb25zIHRvIHVzZSBvbiBteXNxbCBjb21tYW5kIHRvIHF1ZXJ5IHRoZSBkYXRhYmFzZQojIERpZmZlcnMgdGhhbiBzZXRPcHRpb25zIGluIHRoZSB3YXkgdGhhdCB0aGVzZSBvcHRpb25zIGNvdWxkIGNoYW5nZSBlYWNoIHRpbWUKIwojIEBhcmcgJDEgaW5zdGFuY2VTZXRRdWVyeU9wdGlvbnM6Jk1hcDxTdHJpbmcsU3RyaW5nPiAocGFzc2VkIGJ5IHJlZmVyZW5jZSkgZGF0YWJhc2UgaW5zdGFuY2UgdG8gdXNlCiMgQGFyZyAkMiBvcHRpb25zTGlzdDpTdHJpbmcgcXVlcnkgb3B0aW9ucyBsaXN0CkRhdGFiYXNlOjpzZXRRdWVyeU9wdGlvbnMoKSB7CiAgbG9jYWwgLW4gaW5zdGFuY2VTZXRRdWVyeU9wdGlvbnM9JDEKICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICBpbnN0YW5jZVNldFF1ZXJ5T3B0aW9uc1snUVVFUllfT1BUSU9OUyddPSIkMiIKfQoKIyBAZGVzY3JpcHRpb24gYnkgZGVmYXVsdCB3ZSBza2lwIHRoZSBjb2x1bW4gbmFtZXMKIyBidXQgc29tZXRpbWVzIHdlIG5lZWQgY29sdW1uIG5hbWVzIHRvIGRpc3BsYXkgc29tZSByZXN1bHRzCiMgZGlzYWJsZSB0aGlzIG9wdGlvbiB0ZW1wb3JhcmlseSBhbmQgdGhlbiByZXN0b3JlIGl0IHRvIHRydWUKIwojIEBhcmcgJDEgaW5zdGFuY2VTZXRRdWVyeU9wdGlvbnM6Jk1hcDxTdHJpbmcsU3RyaW5nPiAocGFzc2VkIGJ5IHJlZmVyZW5jZSkgZGF0YWJhc2UgaW5zdGFuY2UgdG8gdXNlCiMgQGFyZyAkMiBza2lwQ29sdW1uTmFtZXM6Qm9vbGVhbiAwIHRvIGRpc2FibGUsIDEgdG8gZW5hYmxlIChoaWRlIGNvbHVtbiBuYW1lcykKRGF0YWJhc2U6OnNraXBDb2x1bW5OYW1lcygpIHsKICBsb2NhbCAtbiBpbnN0YW5jZVNraXBDb2x1bW5OYW1lcz0kMQogICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogIGluc3RhbmNlU2tpcENvbHVtbk5hbWVzWydTS0lQX0NPTFVNTl9OQU1FUyddPSIkMiIKfQoKIyBAZGVzY3JpcHRpb24gcHJlcGVuZCBkaXJlY3RvcmllcyB0byB0aGUgUEFUSCBlbnZpcm9ubWVudCB2YXJpYWJsZQojIEBhcmcgJEAgYXJnczpTdHJpbmdbXSBsaXN0IG9mIGRpcmVjdG9yaWVzIHRvIHByZXBlbmQKIyBAc2V0IFBBVEggdXBkYXRlIFBBVEggd2l0aCB0aGUgZGlyZWN0b3JpZXMgcHJlcGVuZGVkCkVudjo6cGF0aFByZXBlbmQoKSB7CiAgbG9jYWwgYXJnCiAgZm9yIGFyZyBpbiAiJEAiOyBkbwogICAgaWYgW1sgLWQgIiR7YXJnfSIgJiYgIjoke1BBVEh9OiIgIT0gKiI6JHthcmd9OiIqIF1dOyB0aGVuCiAgICAgIFBBVEg9IiQocmVhbHBhdGggIiR7YXJnfSIpOiR7UEFUSH0iCiAgICBmaQogIGRvbmUKfQoKIyBAZGVzY3JpcHRpb24gRGlzcGxheSBtZXNzYWdlIHVzaW5nIGVycm9yIGNvbG9yIChyZWQpIGFuZCBleGl0IGltbWVkaWF0ZWx5IHdpdGggZXJyb3Igc3RhdHVzIDEKIyBAYXJnICQxIG1lc3NhZ2U6U3RyaW5nIHRoZSBtZXNzYWdlIHRvIGRpc3BsYXkKTG9nOjpmYXRhbCgpIHsKICBlY2hvIC1lICIke19fRVJST1JfQ09MT1J9RkFUQUwgICAtICR7MX0ke19fUkVTRVRfQ09MT1J9IiA+JjIKICBMb2c6OmxvZ0ZhdGFsICIkMSIKICBleGl0IDEKfQoKIyBAZGVzY3JpcHRpb24gbG9nIG1lc3NhZ2UgdG8gZmlsZQojIEBhcmcgJDEgbWVzc2FnZTpTdHJpbmcgdGhlIG1lc3NhZ2UgdG8gZGlzcGxheQpMb2c6OmxvZ0RlYnVnKCkgewogIGlmICgoQkFTSF9GUkFNRVdPUktfTE9HX0xFVkVMID49IF9fTEVWRUxfREVCVUcpKTsgdGhlbgogICAgTG9nOjpsb2dNZXNzYWdlICIkezI6LURFQlVHfSIgIiQxIgogIGZpCn0KCiMgQGRlc2NyaXB0aW9uIGxvZyBtZXNzYWdlIHRvIGZpbGUKIyBAYXJnICQxIG1lc3NhZ2U6U3RyaW5nIHRoZSBtZXNzYWdlIHRvIGRpc3BsYXkKTG9nOjpsb2dJbmZvKCkgewogIGlmICgoQkFTSF9GUkFNRVdPUktfTE9HX0xFVkVMID49IF9fTEVWRUxfSU5GTykpOyB0aGVuCiAgICBMb2c6OmxvZ01lc3NhZ2UgIiR7MjotSU5GT30iICIkMSIKICBmaQp9CgojIEBkZXNjcmlwdGlvbiBlbnN1cmUgcnVubmluZyB1c2VyIGlzIG5vdCByb290CiMgQGV4aXRjb2RlIDEgaWYgY3VycmVudCB1c2VyIGlzIHJvb3QKIyBAc3RkZXJyIGRpYWdub3N0aWNzIGluZm9ybWF0aW9uIGlzIGRpc3BsYXllZApMaW51eDo6cmVxdWlyZUV4ZWN1dGVkQXNVc2VyKCkgewogIGlmIFtbICIkKGlkIC11KSIgPSAiMCIgXV07IHRoZW4KICAgIExvZzo6ZmF0YWwgInRoaXMgc2NyaXB0IHNob3VsZCBiZSBleGVjdXRlZCBhcyBub3JtYWwgdXNlciIKICBmaQp9CgojIEBkZXNjcmlwdGlvbiBnZXQgYWJzb2x1dGUgY29uZiBmaWxlIGZyb20gc3BlY2lmaWVkIGNvbmYgZm9sZGVyIGRlZHVjZWQgdXNpbmcgdGhlc2UgcnVsZXMKIyAgICogZnJvbSBhYnNvbHV0ZSBmaWxlIChpZ25vcmVzIDxjb25mRm9sZGVyPiBhbmQgPGV4dGVuc2lvbj4pCiMgICAqIHJlbGF0aXZlIHRvIHdoZXJlIHNjcmlwdCBpcyBleGVjdXRlZCAoaWdub3JlcyA8Y29uZkZvbGRlcj4gYW5kIDxleHRlbnNpb24+KQojICAgKiBmcm9tIGhvbWUvLmJhc2gtdG9vbHMvPGNvbmZGb2xkZXI+CiMgICAqIGZyb20gZnJhbWV3b3JrIGNvbmYvPGNvbmZGb2xkZXI+CiMKIyBAYXJnICQxIGNvbmZGb2xkZXI6U3RyaW5nIHRoZSBkaXJlY3RvcnkgbmFtZSAobm90IHRoZSBwYXRoKSB0byBsaXN0CiMgQGFyZyAkMiBjb25mOlN0cmluZyBmaWxlIHRvIHVzZSB3aXRob3V0IGV4dGVuc2lvbgojIEBhcmcgJDMgZXh0ZW5zaW9uOlN0cmluZyB0aGUgZXh0ZW5zaW9uICguc2ggYnkgZGVmYXVsdCkKIwojIEBzdGRvdXQgYWJzb2x1dGUgY29uZiBmaWxlbmFtZQojIEBleGl0Y29kZSAxIGlmIGZpbGUgaXMgbm90IGZvdW5kIGluIGFueSBsb2NhdGlvbgpDb25mOjpnZXRBYnNvbHV0ZUZpbGUoKSB7CiAgbG9jYWwgY29uZkZvbGRlcj0iJDEiCiAgbG9jYWwgY29uZj0iJDIiCiAgbG9jYWwgZXh0ZW5zaW9uPSIkezMtLnNofSIKICBpZiBbWyAtbiAiJHtleHRlbnNpb259IiAmJiAiJHtleHRlbnNpb246MDoxfSIgIT0gIi4iIF1dOyB0aGVuCiAgICBleHRlbnNpb249Ii4ke2V4dGVuc2lvbn0iCiAgZmkKCiAgdGVzdEFicygpIHsKICAgIGxvY2FsIHJlc3VsdAogICAgcmVzdWx0PSIkKHJlYWxwYXRoIC1lICIkMSIgMj4vZGV2L251bGwpIgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMTgxCiAgICBpZiBbWyAiJD8iID0gIjAiICYmIC1mICIke3Jlc3VsdH0iIF1dOyB0aGVuCiAgICAgIGVjaG8gIiR7cmVzdWx0fSIKICAgICAgcmV0dXJuIDAKICAgIGZpCiAgICByZXR1cm4gMQogIH0KCiAgIyBjb25mIGlzIGFic29sdXRlIGZpbGUgKGluY2x1ZGluZyBleHRlbnNpb24pCiAgdGVzdEFicyAiJHtjb25mRm9sZGVyfSR7ZXh0ZW5zaW9ufSIgJiYgcmV0dXJuIDAKICAjIGNvbmYgaXMgYWJzb2x1dGUgZmlsZQogIHRlc3RBYnMgIiR7Y29uZkZvbGRlcn0iICYmIHJldHVybiAwCiAgIyBjb25mIGlzIGFic29sdXRlIGZpbGUgKGluY2x1ZGluZyBleHRlbnNpb24pCiAgdGVzdEFicyAiJHtjb25mfSR7ZXh0ZW5zaW9ufSIgJiYgcmV0dXJuIDAKICAjIGNvbmYgaXMgYWJzb2x1dGUgZmlsZQogIHRlc3RBYnMgIiR7Y29uZn0iICYmIHJldHVybiAwCgogICMgcmVsYXRpdmUgdG8gd2hlcmUgc2NyaXB0IGlzIGV4ZWN1dGVkIChpbmNsdWRpbmcgZXh0ZW5zaW9uKQogIGlmIFtbIC1uICIke0NVUlJFTlRfRElSK3h4eH0iIF1dOyB0aGVuCiAgICB0ZXN0QWJzICIkKEZpbGU6OmNvbmNhdGVuYXRlUGF0aCAiJHtDVVJSRU5UX0RJUn0iICIke2NvbmZGb2xkZXJ9IikvJHtjb25mfSR7ZXh0ZW5zaW9ufSIgJiYgcmV0dXJuIDAKICBmaQogICMgZnJvbSBob21lLy5iYXNoLXRvb2xzLzxjb25mRm9sZGVyPgogIHRlc3RBYnMgIiQoRmlsZTo6Y29uY2F0ZW5hdGVQYXRoICIke0hPTUV9Ly5iYXNoLXRvb2xzIiAiJHtjb25mRm9sZGVyfSIpLyR7Y29uZn0ke2V4dGVuc2lvbn0iICYmIHJldHVybiAwCgogIGlmIFtbIC1uICIke0ZSQU1FV09SS19ST09UX0RJUit4eHh9IiBdXTsgdGhlbgogICAgIyBmcm9tIGZyYW1ld29yayBjb25mLzxjb25mRm9sZGVyPiAoaW5jbHVkaW5nIGV4dGVuc2lvbikKICAgIHRlc3RBYnMgIiQoRmlsZTo6Y29uY2F0ZW5hdGVQYXRoICIke0ZSQU1FV09SS19ST09UX0RJUn0vY29uZiIgIiR7Y29uZkZvbGRlcn0iKS8ke2NvbmZ9JHtleHRlbnNpb259IiAmJiByZXR1cm4gMAoKICAgICMgZnJvbSBmcmFtZXdvcmsgY29uZi88Y29uZkZvbGRlcj4KICAgIHRlc3RBYnMgIiQoRmlsZTo6Y29uY2F0ZW5hdGVQYXRoICIke0ZSQU1FV09SS19ST09UX0RJUn0vY29uZiIgIiR7Y29uZkZvbGRlcn0iKS8ke2NvbmZ9IiAmJiByZXR1cm4gMAogIGZpCgogICMgZmlsZSBub3QgZm91bmQKICBMb2c6OmRpc3BsYXlFcnJvciAiY29uZiBmaWxlICcke2NvbmZ9JyBub3QgZm91bmQiCgogIHJldHVybiAxCn0KCiMgQGRlc2NyaXB0aW9uIGNoZWNrIGlmIGRzbiBmaWxlIGhhcyBhbGwgdGhlIG1hbmRhdG9yeSB2YXJpYWJsZXMgc2V0CiMgTWFuZGF0b3J5IHZhcmlhYmxlcyBhcmU6IEhPU1ROQU1FLCBVU0VSLCBQQVNTV09SRCwgUE9SVAojCiMgQGFyZyAkMSBkc25GaWxlTmFtZTpTdHJpbmcgZHNuIGFic29sdXRlIGZpbGVuYW1lCiMgQHNldCBIT1NUTkFNRSBsb2FkZWQgZnJvbSBkc24gZmlsZQojIEBzZXQgUE9SVCBsb2FkZWQgZnJvbSBkc24gZmlsZQojIEBzZXQgVVNFUiBsb2FkZWQgZnJvbSBkc24gZmlsZQojIEBzZXQgUEFTU1dPUkQgbG9hZGVkIGZyb20gZHNuIGZpbGUKIyBAZXhpdGNvZGUgMCBvbiB2YWxpZCBmaWxlCiMgQGV4aXRjb2RlIDEgaWYgb25lIG9mIHRoZSBwcm9wZXJ0aWVzIG9mIHRoZSBjb25mIGZpbGUgaXMgaW52YWxpZCBvciBpZiBmaWxlIG5vdCBmb3VuZAojIEBzdGRlcnIgbG9nIG91dHB1dCBpZiBlcnJvciBmb3VuZCBpbiBjb25mIGZpbGUKRGF0YWJhc2U6OmNoZWNrRHNuRmlsZSgpIHsKICBsb2NhbCBkc25GaWxlTmFtZT0iJDEiCiAgaWYgW1sgISAtZiAiJHtkc25GaWxlTmFtZX0iIF1dOyB0aGVuCiAgICBMb2c6OmRpc3BsYXlFcnJvciAiZHNuIGZpbGUgJHtkc25GaWxlTmFtZX0gbm90IGZvdW5kIgogICAgcmV0dXJuIDEKICBmaQoKICAoCiAgICB1bnNldCBIT1NUTkFNRSBQT1JUIFBBU1NXT1JEIFVTRVIKICAgICMgc2hlbGxjaGVjayBzb3VyY2U9L3NyYy9EYXRhYmFzZS90ZXN0c0RhdGEvZHNuX3ZhbGlkLmVudgogICAgc291cmNlICIke2RzbkZpbGVOYW1lfSIKICAgIGlmIFtbIC16ICR7SE9TVE5BTUUreH0gXV07IHRoZW4KICAgICAgTG9nOjpkaXNwbGF5RXJyb3IgImRzbiBmaWxlICR7ZHNuRmlsZU5hbWV9IDogSE9TVE5BTUUgbm90IHByb3ZpZGVkIgogICAgICByZXR1cm4gMQogICAgZmkKICAgIGlmIFtbIC16ICIke0hPU1ROQU1FfSIgXV07IHRoZW4KICAgICAgTG9nOjpkaXNwbGF5V2FybmluZyAiZHNuIGZpbGUgJHtkc25GaWxlTmFtZX0gOiBIT1NUTkFNRSB2YWx1ZSBub3QgcHJvdmlkZWQiCiAgICBmaQogICAgaWYgW1sgIiR7SE9TVE5BTUV9IiA9ICJsb2NhbGhvc3QiIF1dOyB0aGVuCiAgICAgIExvZzo6ZGlzcGxheVdhcm5pbmcgImRzbiBmaWxlICR7ZHNuRmlsZU5hbWV9IDogY2hlY2sgdGhhdCBIT1NUTkFNRSBzaG91bGQgbm90IGJlIDEyNy4wLjAuMSBpbnN0ZWFkIG9mIGxvY2FsaG9zdCIKICAgIGZpCiAgICBpZiBbWyAteiAiJHtQT1JUK3h9IiBdXTsgdGhlbgogICAgICBMb2c6OmRpc3BsYXlFcnJvciAiZHNuIGZpbGUgJHtkc25GaWxlTmFtZX0gOiBQT1JUIG5vdCBwcm92aWRlZCIKICAgICAgcmV0dXJuIDEKICAgIGZpCiAgICBpZiAhIFtbICR7UE9SVH0gPX4gXlswLTldKyQgXV07IHRoZW4KICAgICAgTG9nOjpkaXNwbGF5RXJyb3IgImRzbiBmaWxlICR7ZHNuRmlsZU5hbWV9IDogUE9SVCBpbnZhbGlkIgogICAgICByZXR1cm4gMQogICAgZmkKICAgIGlmIFtbIC16ICIke1VTRVIreH0iIF1dOyB0aGVuCiAgICAgIExvZzo6ZGlzcGxheUVycm9yICJkc24gZmlsZSAke2RzbkZpbGVOYW1lfSA6IFVTRVIgbm90IHByb3ZpZGVkIgogICAgICByZXR1cm4gMQogICAgZmkKICAgIGlmIFtbIC16ICIke1BBU1NXT1JEK3h9IiBdXTsgdGhlbgogICAgICBMb2c6OmRpc3BsYXlFcnJvciAiZHNuIGZpbGUgJHtkc25GaWxlTmFtZX0gOiBQQVNTV09SRCBub3QgcHJvdmlkZWQiCiAgICAgIHJldHVybiAxCiAgICBmaQogICkKfQoKIyBAZGVzY3JpcHRpb24gbG9nIG1lc3NhZ2UgdG8gZmlsZQojIEBhcmcgJDEgbWVzc2FnZTpTdHJpbmcgdGhlIG1lc3NhZ2UgdG8gZGlzcGxheQpMb2c6OmxvZ0ZhdGFsKCkgewogIExvZzo6bG9nTWVzc2FnZSAiJHsyOi1GQVRBTH0iICIkMSIKfQoKIyBAZGVzY3JpcHRpb24gSW50ZXJuYWw6IGNvbW1vbiBsb2cgbWVzc2FnZQojIEBleGFtcGxlIHRleHQKIyAgIFtkYXRlXXxbbGV2ZWxNc2ddfG1lc3NhZ2UKIwojIEBleGFtcGxlIHRleHQKIyAgIDIwMjAtMDEtMTkgMTk6MjA6MjF8RVJST1IgIHxsb2cgZXJyb3IKIyAgIDIwMjAtMDEtMTkgMTk6MjA6MjF8U0tJUFBFRHxsb2cgc2tpcHBlZAojCiMgQGFyZyAkMSBsZXZlbE1zZzpTdHJpbmcgbWVzc2FnZSdzIGxldmVsIGRlc2NyaXB0aW9uIChlZzogU1RBVFVTLCBFUlJPUiwgLi4uKQojIEBhcmcgJDIgbXNnOlN0cmluZyB0aGUgbWVzc2FnZSB0byBkaXNwbGF5CiMgQGVudiBCQVNIX0ZSQU1FV09SS19MT0dfRklMRSBTdHJpbmcgbG9nIGZpbGUgdG8gdXNlLCBkbyBub3RoaW5nIGlmIGVtcHR5CiMgQGVudiBCQVNIX0ZSQU1FV09SS19MT0dfTEVWRUwgaW50IGxvZyBsZXZlbCBsb2cgb25seSBpZiA+IE9GRiBvciBmYXRhbCBtZXNzYWdlcwojIEBzdGRlcnIgZGlhZ25vc3RpY3MgaW5mb3JtYXRpb24gaXMgZGlzcGxheWVkCiMgQHJlcXVpcmUgRW52OjpyZXF1aXJlTG9hZAojIEByZXF1aXJlIExvZzo6cmVxdWlyZUxvYWQKTG9nOjpsb2dNZXNzYWdlKCkgewogIGxvY2FsIGxldmVsTXNnPSIkMSIKICBsb2NhbCBtc2c9IiQyIgogIGxvY2FsIGRhdGUKCiAgaWYgW1sgLW4gIiR7QkFTSF9GUkFNRVdPUktfTE9HX0ZJTEV9IiBdXSAmJiAoKEJBU0hfRlJBTUVXT1JLX0xPR19MRVZFTCA+IF9fTEVWRUxfT0ZGKSk7IHRoZW4KICAgIGRhdGU9IiQoZGF0ZSAnKyVZLSVtLSVkICVIOiVNOiVTJykiCiAgICB0b3VjaCAiJHtCQVNIX0ZSQU1FV09SS19MT0dfRklMRX0iCiAgICBwcmludGYgIiVzfCU3c3wlc1xuIiAiJHtkYXRlfSIgIiR7bGV2ZWxNc2d9IiAiJHttc2d9IiA+PiIke0JBU0hfRlJBTUVXT1JLX0xPR19GSUxFfSIKICBmaQp9CgojIEBkZXNjcmlwdGlvbiBjb25jYXRlbmF0ZSAyIHBhdGhzIGFuZCBlbnN1cmUgdGhlIHBhdGggaXMgY29ycmVjdCB1c2luZyByZWFscGF0aCAtbQojIEBhcmcgJDEgYmFzZVBhdGg6U3RyaW5nCiMgQGFyZyAkMiBzdWJQYXRoOlN0cmluZwojIEByZXF1aXJlIExpbnV4OjpyZXF1aXJlUmVhbHBhdGhDb21tYW5kCkZpbGU6OmNvbmNhdGVuYXRlUGF0aCgpIHsKICBsb2NhbCBiYXNlUGF0aD0iJDEiCiAgbG9jYWwgc3ViUGF0aD0iJDIiCiAgbG9jYWwgZnVsbFBhdGg9IiR7YmFzZVBhdGg6KyR7YmFzZVBhdGh9L30ke3N1YlBhdGh9IgoKICByZWFscGF0aCAtbSAiJHtmdWxsUGF0aH0iIDI+L2Rldi9udWxsCn0KCiMgQGRlc2NyaXB0aW9uIERpc3BsYXkgbWVzc2FnZSB1c2luZyBlcnJvciBjb2xvciAocmVkKQojIEBhcmcgJDEgbWVzc2FnZTpTdHJpbmcgdGhlIG1lc3NhZ2UgdG8gZGlzcGxheQpMb2c6OmRpc3BsYXlFcnJvcigpIHsKICBpZiAoKEJBU0hfRlJBTUVXT1JLX0RJU1BMQVlfTEVWRUwgPj0gX19MRVZFTF9FUlJPUikpOyB0aGVuCiAgICBlY2hvIC1lICIke19fRVJST1JfQ09MT1J9RVJST1IgICAtICR7MX0ke19fUkVTRVRfQ09MT1J9IiA+JjIKICBmaQogIExvZzo6bG9nRXJyb3IgIiQxIgp9CgojIEBkZXNjcmlwdGlvbiBEaXNwbGF5IG1lc3NhZ2UgdXNpbmcgd2FybmluZyBjb2xvciAoeWVsbG93KQojIEBhcmcgJDEgbWVzc2FnZTpTdHJpbmcgdGhlIG1lc3NhZ2UgdG8gZGlzcGxheQpMb2c6OmRpc3BsYXlXYXJuaW5nKCkgewogIGlmICgoQkFTSF9GUkFNRVdPUktfRElTUExBWV9MRVZFTCA+PSBfX0xFVkVMX1dBUk5JTkcpKTsgdGhlbgogICAgZWNobyAtZSAiJHtfX1dBUk5JTkdfQ09MT1J9V0FSTiAgICAtICR7MX0ke19fUkVTRVRfQ09MT1J9IiA+JjIKICBmaQogIExvZzo6bG9nV2FybmluZyAiJDEiCn0KCiMgQGRlc2NyaXB0aW9uIGVuc3VyZSBlbnYgZmlsZXMgYXJlIGxvYWRlZAojIEBub2FyZ3MKIyBAZXhpdGNvZGUgMSBpZiBnZXRPcmRlcmVkQ29uZkZpbGVzIGZhaWxzCiMgQGV4aXRjb2RlIDIgaWYgb25lIG9mIGVudiBmaWxlcyBmYWlscyB0byBsb2FkCiMgQHN0ZGVyciBkaWFnbm9zdGljcyBpbmZvcm1hdGlvbiBpcyBkaXNwbGF5ZWQKRW52OjpyZXF1aXJlTG9hZCgpIHsKICBsb2NhbCBjb25maWdGaWxlc1N0cgogIGNvbmZpZ0ZpbGVzU3RyPSIkKEVudjo6Z2V0T3JkZXJlZENvbmZGaWxlcykiIHx8IHJldHVybiAxCgogIGxvY2FsIC1hIGNvbmZpZ0ZpbGVzCiAgcmVhZGFycmF5IC10IGNvbmZpZ0ZpbGVzIDw8PCIke2NvbmZpZ0ZpbGVzU3RyfSIKCiAgIyBpZiBlbXB0eSBzdHJpbmcsIHRoZXJlIHdpbGwgYmUgb25lIGVsZW1lbnQKICBpZiAoKCR7I2NvbmZpZ0ZpbGVzW0BdfSA9PSAwKSkgfHwgW1sgLXogIiR7Y29uZmlnRmlsZXNTdHJ9IiBdXTsgdGhlbgogICAgIyBzaG91bGQgbm90IGhhcHBlbiwgYXMgdGhlcmUgaXMgYWx3YXlzIGRlZmF1bHQgZmlsZQogICAgTG9nOjpkaXNwbGF5U2tpcHBlZCAibm8gZW52IGZpbGUgdG8gbG9hZCIKICAgIHJldHVybiAwCiAgZmkKCiAgRW52OjptZXJnZUNvbmZGaWxlcyAiJHtjb25maWdGaWxlc1tAXX0iIHx8IHsKICAgIExvZzo6ZGlzcGxheUVycm9yICJ3aGlsZSBsb2FkaW5nIGNvbmZpZyBmaWxlczogJHtjb25maWdGaWxlc1sqXX0iCiAgICByZXR1cm4gMgogIH0KfQoKIyBAZGVzY3JpcHRpb24gYWN0aXZhdGUgb3Igbm90IExvZzo6ZGlzcGxheSogYW5kIExvZzo6bG9nKiBmdW5jdGlvbnMKIyBiYXNlZCBvbiBCQVNIX0ZSQU1FV09SS19ESVNQTEFZX0xFVkVMIGFuZCBCQVNIX0ZSQU1FV09SS19MT0dfTEVWRUwKIyBlbnZpcm9ubWVudCB2YXJpYWJsZXMgbG9hZGVkIGJ5IEVudjo6cmVxdWlyZUxvYWQKIyB0cnkgdG8gY3JlYXRlIGxvZyBmaWxlIGFuZCByb3RhdGUgaXQgaWYgbmVjZXNzYXJ5CiMgQG5vYXJncwojIEBzZXQgQkFTSF9GUkFNRVdPUktfTE9HX0xFVkVMIGludCB0byBPRkYgbGV2ZWwgaWYgQkFTSF9GUkFNRVdPUktfTE9HX0ZJTEUgaXMgZW1wdHkgb3Igbm90IHdyaXRhYmxlCiMgQGVudiBCQVNIX0ZSQU1FV09SS19ESVNQTEFZX0xFVkVMIGludAojIEBlbnYgQkFTSF9GUkFNRVdPUktfTE9HX0xFVkVMIGludAojIEBlbnYgQkFTSF9GUkFNRVdPUktfTE9HX0ZJTEUgU3RyaW5nCiMgQGVudiBCQVNIX0ZSQU1FV09SS19MT0dfRklMRV9NQVhfUk9UQVRJT04gaW50IGRvIGxvZyByb3RhdGlvbiBpZiA+IDAKIyBAZXhpdGNvZGUgMCBhbHdheXMgc3VjY2Vzc2Z1bAojIEBzdGRlcnIgZGlhZ25vc3RpY3MgaW5mb3JtYXRpb24gYWJvdXQgbG9nIGZpbGUgaXMgZGlzcGxheWVkCiMgQHJlcXVpcmUgRW52OjpyZXF1aXJlTG9hZAojIEByZXF1aXJlIFVJOjpyZXF1aXJlVGhlbWUKTG9nOjpyZXF1aXJlTG9hZCgpIHsKICBpZiBbWyAteiAiJHtCQVNIX0ZSQU1FV09SS19MT0dfRklMRTotfSIgXV07IHRoZW4KICAgIEJBU0hfRlJBTUVXT1JLX0xPR19MRVZFTD0ke19fTEVWRUxfT0ZGfQogICAgZXhwb3J0IEJBU0hfRlJBTUVXT1JLX0xPR19MRVZFTAogIGZpCgogIGlmICgoQkFTSF9GUkFNRVdPUktfTE9HX0xFVkVMID4gX19MRVZFTF9PRkYpKTsgdGhlbgogICAgaWYgW1sgISAtZiAiJHtCQVNIX0ZSQU1FV09SS19MT0dfRklMRX0iIF1dOyB0aGVuCiAgICAgIGlmCiAgICAgICAgISBta2RpciAtcCAiJChkaXJuYW1lICIke0JBU0hfRlJBTUVXT1JLX0xPR19GSUxFfSIpIiAyPi9kZXYvbnVsbCB8fAogICAgICAgICAgISB0b3VjaCAtLW5vLWNyZWF0ZSAiJHtCQVNIX0ZSQU1FV09SS19MT0dfRklMRX0iIDI+L2Rldi9udWxsCiAgICAgIHRoZW4KICAgICAgICBCQVNIX0ZSQU1FV09SS19MT0dfTEVWRUw9JHtfX0xFVkVMX09GRn0KICAgICAgICBlY2hvIC1lICIke19fRVJST1JfQ09MT1J9RVJST1IgICAtIEZpbGUgJHtCQVNIX0ZSQU1FV09SS19MT0dfRklMRX0gaXMgbm90IHdyaXRhYmxlJHtfX1JFU0VUX0NPTE9SfSIgPiYyCiAgICAgIGZpCiAgICBlbGlmIFtbICEgLXcgIiR7QkFTSF9GUkFNRVdPUktfTE9HX0ZJTEV9IiBdXTsgdGhlbgogICAgICBCQVNIX0ZSQU1FV09SS19MT0dfTEVWRUw9JHtfX0xFVkVMX09GRn0KICAgICAgZWNobyAtZSAiJHtfX0VSUk9SX0NPTE9SfUVSUk9SICAgLSBGaWxlICR7QkFTSF9GUkFNRVdPUktfTE9HX0ZJTEV9IGlzIG5vdCB3cml0YWJsZSR7X19SRVNFVF9DT0xPUn0iID4mMgogICAgZmkKCiAgZmkKCiAgaWYgKChCQVNIX0ZSQU1FV09SS19MT0dfTEVWRUwgPiBfX0xFVkVMX09GRikpOyB0aGVuCiAgICAjIHdpbGwgYWx3YXlzIGJlIGNyZWF0ZWQgZXZlbiBpZiBub3QgaW4gaW5mbyBsZXZlbAogICAgTG9nOjpsb2dNZXNzYWdlICJJTkZPIiAiTG9nZ2luZyB0byBmaWxlICR7QkFTSF9GUkFNRVdPUktfTE9HX0ZJTEV9IC0gTG9nIGxldmVsICR7QkFTSF9GUkFNRVdPUktfTE9HX0xFVkVMfSIKICAgIGlmICgoQkFTSF9GUkFNRVdPUktfTE9HX0ZJTEVfTUFYX1JPVEFUSU9OID4gMCkpOyB0aGVuCiAgICAgIExvZzo6cm90YXRlICIke0JBU0hfRlJBTUVXT1JLX0xPR19GSUxFfSIgIiR7QkFTSF9GUkFNRVdPUktfTE9HX0ZJTEVfTUFYX1JPVEFUSU9OfSIKICAgIGZpCiAgZmkKfQoKIyBAZGVzY3JpcHRpb24gZ2V0IGxpc3Qgb2YgZW52IGZpbGVzIHRvIGxvYWQKIyBpbiBvcmRlciB0byBtYWtlIHRoZW0gYXZhaWxhYmxlIGZvciBFbnY6OnJlcXVpcmVMb2FkCiMgQGVudiBCQVNIX0ZSQU1FV09SS19FTlZfRklMRVMgU3RyaW5nW10gbGlzdCBvZiBlbnYgZmlsZXMgdGhhdCBzaG91bGQgYmUgbG9hZGVkCiMgQGV4aXRjb2RlIDEgaWYgb25lIG9mIHRoZSBlbnYgZmlsZSBjYW5ub3QgYmUgZ2VuZXJhdGVkCiMgQGV4aXRjb2RlIDIgaWYgb25lIG9mIHRoZSBlbnYgZmlsZSBpcyBub3QgYSBmaWxlIG9yIHJlYWRhYmxlCiMgQHN0ZG91dCB0aGUgZW52IGZpbGVzIGFza2VkIHRvIGJlIGxvYWRlZAojIEBzdGRlcnIgZGlhZ25vc3RpYyBpbmZvcm1hdGlvbiBvbiBmYWlsdXJlCiMgQHNlZSBodHRwczovL2dpdGh1Yi5jb20vZmNoYXN0YW5ldC9iYXNoLXRvb2xzLWZyYW1ld29yay9ibG9iL21hc3Rlci9GcmFtZXdvcmtEb2MubWQjY29uZmlnX2ZpbGVfb3JkZXIKRW52OjpnZXRPcmRlcmVkQ29uZkZpbGVzKCkgewogIGxvY2FsIC1hIGNvbmZpZ0ZpbGVzPSgpCgogIGlmIFtbIC1uICIke0JBU0hfRlJBTUVXT1JLX0VOVl9GSUxFU1swXSsxfSIgXV07IHRoZW4KICAgICMgQkFTSF9GUkFNRVdPUktfRU5WX0ZJTEVTIGlzIGFuIGFycmF5CiAgICBjb25maWdGaWxlcys9KCIke0JBU0hfRlJBTUVXT1JLX0VOVl9GSUxFU1tAXX0iKQogIGZpCgogIGxvY2FsIGRlZmF1bHRFbnZGaWxlCiAgZGVmYXVsdEVudkZpbGU9IiQoRW52OjpjcmVhdGVEZWZhdWx0RW52RmlsZSkiIHx8IHJldHVybiAxCiAgY29uZmlnRmlsZXMrPSgiJHtkZWZhdWx0RW52RmlsZX0iKQoKICBsb2NhbCBmaWxlCiAgZm9yIGZpbGUgaW4gIiR7Y29uZmlnRmlsZXNbQF19IjsgZG8KICAgIGlmIFtbICEgLWYgIiR7ZmlsZX0iIHx8ICEgLXIgIiR7ZmlsZX0iIF1dOyB0aGVuCiAgICAgIExvZzo6ZGlzcGxheUVycm9yICJPbmUgb2YgdGhlIGNvbmZpZyBmaWxlIGlzIG5vdCBhdmFpbGFibGUgJyR7ZmlsZX0nIgogICAgICByZXR1cm4gMgogICAgZmkKICAgIGVjaG8gIiR7ZmlsZX0iCiAgZG9uZQp9CgojIEBkZXNjcmlwdGlvbiBtZXJnZSBhbmQgbG9hZCBjb25mIGZpbGVzIHNwZWNpZmllZCBhcyBhcmd1bWVudAojIC0gZmlsZXMgYXJlIGNsZWFuZWQgZnJvbSBheSBjb21tZW50CiMgLSBtaXNzaW5nIHF1b3RlcyBhZnRlciBwcm9wZXJ0eSA9IHNpZ24gYXJlIGFkZGVkIGF1dG9tYXRpY2FsbHkKIyAtIGF1dG9tYXRpYyByZW1vdmUgb2YgYWxsIHdoaXRlc3BhY2UgYmVmb3JlIGFuZCBhZnRlciBkZWNsYXJhdGlvbnMKIyAtIGJhc2ggYXJyYXlzIGFyZSBub3Qgc3VwcG9ydGVkCiMgLSBpZiBhIHZhcmlhYmxlIGlzIGRlY2xhcmVkIGluIGZpcnN0IGZpbGUgYW5kIG92ZXJyaWRkZW4gbGF0ZXIgb24KIyAgIGluIHRoZSBzYW1lIGZpbGUgb3IgaW4gc3Vic2VxdWVudCBmaWxlcywgdGhvc2Ugb3ZlcmxvYWRzIHdpbGwgYmUKIyAgIGlnbm9yZWQKIyBAd2FybmluZyBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgbG9hZGluZyBvbmUgb2YgdGhlIGNvbmZpZyBmaWxlLCBleGl0IGNvZGUgMyBidXQgZW52aXJvbm1lbnQgY291bGQgYmUgcGFydGlhbGx5IGxvYWRlZAojIEBhcmcgJEAgYXJnczpTdHJpbmdbXSBsaXN0IG9mIGNvbmZpZ3VyYXRpb24gZmlsZXMgdG8gbG9hZCBpbiBvcmRlcgojIEBzZXQgZW52VmFycyBTdHJpbmcgd2lsbCBzZXQgaW4gZW52aXJvbm1lbnQgYWxsIHRoZSB2YXJpYWJsZXMgdGhhdCBoYXZlIGJlZW4gZGVjbGFyZWQgaW4gdGhlIGNvbmZpZyBmaWxlcwojIEBlbnYgZW52VmFycyBTdHJpbmcgdGhlIGVudiB2YXJpYWJsZXMgb2YgdGhlIGN1cnJlbnQgc2NyaXB0IGNvdWxkIGJlIHVzZWQgdG8gaW50ZXJwcmV0IHZhcmlhYmxlcyBkdXJpbmcgY29uZmlnIGZpbGVzIHBhcnNpbmcKIyBAZXhpdGNvZGUgMCBpZiBubyBjb25maWcgZmlsZXMgcHJvdmlkZWQgb3IgbG9hZCBjb21wbGV0ZWQgc3VjY2Vzc2Z1bGx5CiMgQGV4aXRjb2RlIDEgaWYgZXJyb3Igb2NjdXJyZWQgZHVyaW5nIHBhcnNpbmcgdGhlIGNvbmZpZyBmaWxlcyAoZmlsZSBub3QgZm91bmQsIGdyZXAsIGF3ayBvciBzZWQgZXJyb3IpCiMgQGV4aXRjb2RlIDIgaWYgdGVtcG9yYXJ5IGZpbGUgY2Fubm90IGJlIGNyZWF0ZWQKIyBAZXhpdGNvZGUgMyBpZiBhbiBlcnJvciBvY2N1cnJlZCBkdXJpbmcgY29uZmlnIGZpbGUgc291cmNpbmcKIyBAc3RkZXJyIGRpYWdub3N0aWNzIGluZm9ybWF0aW9uIGlzIGRpc3BsYXllZAojIEBzZWUgbGFyZ2VseSBpbnNwaXJlZCBidXQgbW9kaWZpZWQgZnJvbSBodHRwczovL29wZW5zb3VyY2UuY29tL2FydGljbGUvMjEvNS9wcm9jZXNzaW5nLWNvbmZpZ3VyYXRpb24tZmlsZXMtc2hlbGwKRW52OjptZXJnZUNvbmZGaWxlcygpIHsKICBsb2NhbCAtYSBjb25maWdGaWxlTGlzdD0oIiRAIikKCiAgaWYgKCgkeyNjb25maWdGaWxlTGlzdFtAXX0gPT0gMCkpOyB0aGVuCiAgICByZXR1cm4gMAogIGZpCgogIGxvY2FsIGNvbWJpbmVkQ29uZmlnRmlsZQogIGNvbWJpbmVkQ29uZmlnRmlsZT0iJChGcmFtZXdvcms6OmNyZWF0ZVRlbXBGaWxlICJtZXJnZUNvbmZGaWxlcyIpIiB8fCByZXR1cm4gMgoKICAoCiAgICAjIHJlbW92ZXMgYW55IHRyYWlsaW5nIHdoaXRlc3BhY2UgZnJvbSBlYWNoIGZpbGUsIGlmIGFueQogICAgIyB0aGlzIGlzIGFic29sdXRlbHkgcmVxdWlyZWQgd2hlbiBpbXBvcnRpbmcgaW50byBDb25maWdNYXBzCiAgICAjIHB1dCBxdW90ZXMgYXJvdW5kIHZhbHVlcwogICAgc2VkIC1FIC1lICQncy9ccyokLy8gOyAvXiQvZCA7IC9eIy4qJC9kIDsgcy89KFteIlwnXS4qKSQvPSJcXDEiLycgIiR7Y29uZmlnRmlsZUxpc3RbQF19IiB8CiAgICAgICMgcmVtb3ZlIGFsbCBjb21tZW50IGxpbmVzCiAgICAgIEZpbHRlcnM6OmNvbW1lbnRMaW5lcyB8CiAgICAgICMgaXRlcmF0ZXMgb3ZlciBlYWNoIGZpbGUgYW5kIHByaW50cyAoZGVmYXVsdCBhd2sgYmVoYXZpb3IpCiAgICAgICMgZWFjaCB1bmlxdWUgbGluZTsgb25seSB0YWtlcyBmaXJzdCB2YWx1ZSBhbmQgaWdub3JlcyBkdXBsaWNhdGVzCiAgICAgIGF3ayAtRj0gJyFsaW5lWyQxXSsrJwogICkgPiIke2NvbWJpbmVkQ29uZmlnRmlsZX0iIHx8IHJldHVybiAxCgogICMgaGF2ZSB0byBleHBvcnQgZXZlcnl0aGluZywgYW5kIHNvdXJjZSBpdCB0d2ljZToKICAjIDEpIGZpcnN0IHNvdXJjZSBpcyB0byByZWFsaXplIHZhcmlhYmxlcwogICMgMikgc2Vjb25kIHRpbWUgaXMgdG8gcmVhbGl6ZSByZWZlcmVuY2VzCiAgc2V0IC1vIGFsbGV4cG9ydAogICMgc2hlbGxjaGVjayBzb3VyY2U9LmZyYW1ld29yay1jb25maWcKICBzb3VyY2UgIiR7Y29tYmluZWRDb25maWdGaWxlfSIgfHwgcmV0dXJuIDMKICAjIHNoZWxsY2hlY2sgc291cmNlPS5mcmFtZXdvcmstY29uZmlnCiAgc291cmNlICIke2NvbWJpbmVkQ29uZmlnRmlsZX0iIHx8IHJldHVybiAzCiAgc2V0ICtvIGFsbGV4cG9ydAp9CgojIEBkZXNjcmlwdGlvbiBEaXNwbGF5IG1lc3NhZ2UgdXNpbmcgc2tpcCBjb2xvciAoeWVsbG93KQojIEBhcmcgJDEgbWVzc2FnZTpTdHJpbmcgdGhlIG1lc3NhZ2UgdG8gZGlzcGxheQpMb2c6OmRpc3BsYXlTa2lwcGVkKCkgewogIGlmICgoQkFTSF9GUkFNRVdPUktfRElTUExBWV9MRVZFTCA+PSBfX0xFVkVMX0lORk8pKTsgdGhlbgogICAgZWNobyAtZSAiJHtfX1NLSVBQRURfQ09MT1J9U0tJUFBFRCAtICR7MX0ke19fUkVTRVRfQ09MT1J9IiA+JjIKICBmaQogIExvZzo6bG9nU2tpcHBlZCAiJDEiCn0KCiMgQGRlc2NyaXB0aW9uIGxvZyBtZXNzYWdlIHRvIGZpbGUKIyBAYXJnICQxIG1lc3NhZ2U6U3RyaW5nIHRoZSBtZXNzYWdlIHRvIGRpc3BsYXkKTG9nOjpsb2dFcnJvcigpIHsKICBpZiAoKEJBU0hfRlJBTUVXT1JLX0xPR19MRVZFTCA+PSBfX0xFVkVMX0VSUk9SKSk7IHRoZW4KICAgIExvZzo6bG9nTWVzc2FnZSAiJHsyOi1FUlJPUn0iICIkMSIKICBmaQp9CgojIEBkZXNjcmlwdGlvbiBsb2cgbWVzc2FnZSB0byBmaWxlCiMgQGFyZyAkMSBtZXNzYWdlOlN0cmluZyB0aGUgbWVzc2FnZSB0byBkaXNwbGF5CkxvZzo6bG9nV2FybmluZygpIHsKICBpZiAoKEJBU0hfRlJBTUVXT1JLX0xPR19MRVZFTCA+PSBfX0xFVkVMX1dBUk5JTkcpKTsgdGhlbgogICAgTG9nOjpsb2dNZXNzYWdlICIkezI6LVdBUk5JTkd9IiAiJDEiCiAgZmkKfQoKIyBAZGVzY3JpcHRpb24gVG8gYmUgY2FsbGVkIGJlZm9yZSBsb2dnaW5nIGluIHRoZSBsb2cgZmlsZQojIEBhcmcgJDEgZmlsZTpzdHJpbmcgbG9nIGZpbGUgbmFtZQojIEBhcmcgJDIgbWF4TG9nRmlsZXNDb3VudDppbnQgbWF4aW11bSBudW1iZXIgb2YgbG9nIGZpbGVzCkxvZzo6cm90YXRlKCkgewogIGxvY2FsIGZpbGU9IiQxIgogIGxvY2FsIG1heExvZ0ZpbGVzQ291bnQ9IiR7MjotNX0iCgogIGlmIFtbICEgLWYgIiR7ZmlsZX0iIF1dOyB0aGVuCiAgICBMb2c6OmRpc3BsYXlTa2lwcGVkICJMb2cgZmlsZSAke2ZpbGV9IGRvZXNuJ3QgZXhpc3QgeWV0IgogICAgcmV0dXJuIDAKICBmaQogIGZvciBpIGluICQoc2VxICQoKG1heExvZ0ZpbGVzQ291bnQgLSAxKSkgLTEgMSk7IGRvCiAgICBMb2c6OmRpc3BsYXlJbmZvICJMb2cgcm90YXRpb24gJHtmaWxlfS4ke2l9IHRvICR7ZmlsZX0uJCgoaSArIDEpKSIKICAgIG12ICIke2ZpbGV9LiJ7IiR7aX0iLCIkKChpICsgMSkpIn0gJj4vZGV2L251bGwgfHwgdHJ1ZQogIGRvbmUKICBpZiBjcCAiJHtmaWxlfSIgIiR7ZmlsZX0uMSIgJj4vZGV2L251bGw7IHRoZW4KICAgIGVjaG8gPiIke2ZpbGV9IiAjIHJlc2V0IGxvZyBmaWxlCiAgICBMb2c6OmRpc3BsYXlJbmZvICJMb2cgcm90YXRpb24gJHtmaWxlfSB0byAke2ZpbGV9LjEiCiAgZmkKfQoKIyBAZGVzY3JpcHRpb24gZW5zdXJlIGNvbW1hbmQgcmVhbHBhdGggaXMgYXZhaWxhYmxlCiMgQGV4aXRjb2RlIDEgaWYgcmVhbHBhdGggY29tbWFuZCBub3QgYXZhaWxhYmxlCiMgQHN0ZGVyciBkaWFnbm9zdGljcyBpbmZvcm1hdGlvbiBpcyBkaXNwbGF5ZWQKTGludXg6OnJlcXVpcmVSZWFscGF0aENvbW1hbmQoKSB7CiAgQXNzZXJ0Ojpjb21tYW5kRXhpc3RzIHJlYWxwYXRoCn0KCiMgQGRlc2NyaXB0aW9uIGxvYWQgY29sb3IgdGhlbWUKIyBAbm9hcmdzCiMgQGVudiBCQVNIX0ZSQU1FV09SS19USEVNRSBTdHJpbmcgdGhlbWUgdG8gdXNlCiMgQGV4aXRjb2RlIDAgYWx3YXlzIHN1Y2Nlc3NmdWwKVUk6OnJlcXVpcmVUaGVtZSgpIHsKICBVSTo6dGhlbWUgIiR7QkFTSF9GUkFNRVdPUktfVEhFTUUtZGVmYXVsdH0iCn0KCiMgQGRlc2NyaXB0aW9uIGNoZWNrIGlmIGNvbW1hbmQgc3BlY2lmaWVkIGV4aXN0cyBvciByZXR1cm4gMQojIHdpdGggZXJyb3IgYW5kIG1lc3NhZ2UgaWYgbm90CiMKIyBAYXJnICQxIGNvbW1hbmROYW1lOlN0cmluZyBvbiB3aGljaCBleGlzdGVuY2UgbXVzdCBiZSBjaGVja2VkCiMgQGFyZyAkMiBoZWxwSWZOb3RFeGlzdHM6U3RyaW5nIGEgaGVscCBjb21tYW5kIHRvIGRpc3BsYXkgaWYgdGhlIGNvbW1hbmQgZG9lcyBub3QgZXhpc3QKIwojIEBleGl0Y29kZSAxIGlmIHRoZSBjb21tYW5kIHNwZWNpZmllZCBkb2VzIG5vdCBleGlzdAojIEBzdGRlcnIgZGlhZ25vc3RpYyBpbmZvcm1hdGlvbiArIGhlbHAgaWYgc2Vjb25kIGFyZ3VtZW50IGlzIHByb3ZpZGVkCkFzc2VydDo6Y29tbWFuZEV4aXN0cygpIHsKICBsb2NhbCBjb21tYW5kTmFtZT0iJDEiCiAgbG9jYWwgaGVscElmTm90RXhpc3RzPSIkMiIKCiAgIiR7QkFTSF9GUkFNRVdPUktfQ09NTUFORDotY29tbWFuZH0iIC12ICIke2NvbW1hbmROYW1lfSIgPi9kZXYvbnVsbCAyPi9kZXYvbnVsbCB8fCB7CiAgICBMb2c6OmRpc3BsYXlFcnJvciAiJHtjb21tYW5kTmFtZX0gaXMgbm90IGluc3RhbGxlZCwgcGxlYXNlIGluc3RhbGwgaXQiCiAgICBpZiBbWyAtbiAiJHtoZWxwSWZOb3RFeGlzdHN9IiBdXTsgdGhlbgogICAgICBMb2c6OmRpc3BsYXlJbmZvICIke2hlbHBJZk5vdEV4aXN0c30iCiAgICBmaQogICAgcmV0dXJuIDEKICB9CiAgcmV0dXJuIDAKfQoKIyBAZGVzY3JpcHRpb24gZGVmYXVsdCBlbnYgZmlsZSB3aXRoIGFsbCBkZWZhdWx0IHZhbHVlcwojIEBzdGRvdXQgdGhlIGRlZmF1bHQgZW52IGZpbGVwYXRoCkVudjo6Y3JlYXRlRGVmYXVsdEVudkZpbGUoKSB7CiAgbG9jYWwgZW52RmlsZQogIGVudkZpbGU9IiQoRnJhbWV3b3JrOjpjcmVhdGVUZW1wRmlsZSAiY3JlYXRlRGVmYXVsdEVudkZpbGVFbnZGaWxlIikiIHx8IHJldHVybiAyCgogICgKICAgIGVjaG8gIkJBU0hfRlJBTUVXT1JLX1RIRU1FPSR7QkFTSF9GUkFNRVdPUktfVEhFTUU6LWRlZmF1bHR9IgogICAgZWNobyAiQkFTSF9GUkFNRVdPUktfTE9HX0xFVkVMPSR7QkFTSF9GUkFNRVdPUktfTE9HX0xFVkVMOi0wfSIKICAgIGVjaG8gIkJBU0hfRlJBTUVXT1JLX0RJU1BMQVlfTEVWRUw9JHtCQVNIX0ZSQU1FV09SS19ESVNQTEFZX0xFVkVMOi0ke19fTEVWRUxfV0FSTklOR319IgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDE2CiAgICBlY2hvICdCQVNIX0ZSQU1FV09SS19MT0dfRklMRT0iJHtCQVNIX0ZSQU1FV09SS19MT0dfRklMRTotIiR7RlJBTUVXT1JLX1JPT1RfRElSfS9sb2dzLyR7U0NSSVBUX05BTUV9LmxvZyJ9IicKICAgIGVjaG8gIkJBU0hfRlJBTUVXT1JLX0xPR19GSUxFX01BWF9ST1RBVElPTj0ke0JBU0hfRlJBTUVXT1JLX0xPR19GSUxFX01BWF9ST1RBVElPTjotNX0iCiAgKSA+IiR7ZW52RmlsZX0iCiAgZWNobyAiJHtlbnZGaWxlfSIKfQoKIyBAZGVzY3JpcHRpb24gcmVtb3ZlIGNvbW1lbnQgbGluZXMgZnJvbSBpbnB1dCBvciBmaWxlcyBwcm92aWRlZCBhcyBhcmd1bWVudHMKIyBAYXJnICRAIGZpbGVzOlN0cmluZ1tdIChvcHRpb25hbCkgdGhlIGZpbGVzIHRvIGZpbHRlcgojIEBlbnYgY29tbWVudExpbmVQcmVmaXggU3RyaW5nIHRoZSBjb21tZW50IGxpbmUgcHJlZml4IChkZWZhdWx0IHZhbHVlOiAjKQojIEBleGl0Y29kZSAwIGlmIGxpbmVzIGZpbHRlcmVkIG9yIG5vdAojIEBleGl0Y29kZSAyIGlmIGdyZXAgZmFpbHMgZm9yIGFueSBvdGhlciByZWFzb25zIHRoYW4gbm90IGZvdW5kCiMgQHN0ZGluIHRoZSBmaWxlIGFzIHN0ZGluIHRvIGZpbHRlciAoYWx0ZXJuYXRpdmUgdG8gZmlsZXMgYXJndW1lbnQpCiMgQHN0ZG91dCB0aGUgZmlsdGVyZWQgbGluZXMKIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMTIwCkZpbHRlcnM6OmNvbW1lbnRMaW5lcygpIHsKICBncmVwIC12eEUgIltbOmJsYW5rOl1dKigke2NvbW1lbnRMaW5lUHJlZml4Oi0jfS4qKT8iICIkQCIgfHwgdGVzdCAkPyA9IDEKfQoKIyBAZGVzY3JpcHRpb24gY3JlYXRlIGEgdGVtcCBmaWxlIHVzaW5nIGRlZmF1bHQgVE1QRElSIHZhcmlhYmxlCiMgaW5pdGlhbGl6ZWQgaW4gX2luY2x1ZGVzL19jb21tb25IZWFkZXIuc2gKIyBAZW52IFRNUERJUiBTdHJpbmcgKGRlZmF1bHQgdmFsdWUgL3RtcCkKIyBAYXJnICQxIHRlbXBsYXRlTmFtZTpTdHJpbmcgdGVtcGxhdGUgbmFtZSB0byB1c2Uob3B0aW9uYWwpCkZyYW1ld29yazo6Y3JlYXRlVGVtcEZpbGUoKSB7CiAgbWt0ZW1wIC1wICIke1RNUERJUjotL3RtcH0iIC10ICIkezE6LX0uWFhYWFhYWFhYWFhYIgp9CgojIEBkZXNjcmlwdGlvbiBsb2cgbWVzc2FnZSB0byBmaWxlCiMgQGFyZyAkMSBtZXNzYWdlOlN0cmluZyB0aGUgbWVzc2FnZSB0byBkaXNwbGF5CkxvZzo6bG9nU2tpcHBlZCgpIHsKICBpZiAoKEJBU0hfRlJBTUVXT1JLX0xPR19MRVZFTCA+PSBfX0xFVkVMX0lORk8pKTsgdGhlbgogICAgTG9nOjpsb2dNZXNzYWdlICIkezI6LVNLSVBQRUR9IiAiJDEiCiAgZmkKfQoKIyBAZGVzY3JpcHRpb24gbG9hZCBjb2xvcnMgdGhlbWUgY29uc3RhbnRzCiMgQHdhcm5pbmcgaWYgdHR5IG5vdCBvcGVuZWQsIG5vQ29sb3IgdGhlbWUgd2lsbCBiZSBjaG9zZW4KIyBAYXJnICQxIHRoZW1lOlN0cmluZyB0aGUgdGhlbWUgdG8gdXNlIChkZWZhdWx0LCBub0NvbG9yKQojIEBhcmcgJEAgYXJnczpTdHJpbmdbXQojIEBzZXQgX19FUlJPUl9DT0xPUiBTdHJpbmcgaW5kaWNhdGUgZXJyb3Igc3RhdHVzCiMgQHNldCBfX0lORk9fQ09MT1IgU3RyaW5nIGluZGljYXRlIGluZm8gc3RhdHVzCiMgQHNldCBfX1NVQ0NFU1NfQ09MT1IgU3RyaW5nIGluZGljYXRlIHN1Y2Nlc3Mgc3RhdHVzCiMgQHNldCBfX1dBUk5JTkdfQ09MT1IgU3RyaW5nIGluZGljYXRlIHdhcm5pbmcgc3RhdHVzCiMgQHNldCBfX1NLSVBQRURfQ09MT1IgU3RyaW5nIGluZGljYXRlIHNraXBwZWQgc3RhdHVzCiMgQHNldCBfX0RFQlVHX0NPTE9SIFN0cmluZyBpbmRpY2F0ZSBkZWJ1ZyBzdGF0dXMKIyBAc2V0IF9fSEVMUF9DT0xPUiBTdHJpbmcgaW5kaWNhdGUgaGVscCBzdGF0dXMKIyBAc2V0IF9fVEVTVF9DT0xPUiBTdHJpbmcgbm90IHVzZWQKIyBAc2V0IF9fVEVTVF9FUlJPUl9DT0xPUiBTdHJpbmcgbm90IHVzZWQKIyBAc2V0IF9fSEVMUF9USVRMRV9DT0xPUiBTdHJpbmcgdXNlZCB0byBkaXNwbGF5IGhlbHAgdGl0bGUgaW4gaGVscCBzdHJpbmdzCiMgQHNldCBfX0hFTFBfT1BUSU9OX0NPTE9SIFN0cmluZyB1c2VkIHRvIGRpc3BsYXkgaGlnaGxpZ2h0IG9wdGlvbnMgaW4gaGVscCBzdHJpbmdzCiMKIyBAc2V0IF9fUkVTRVRfQ09MT1IgU3RyaW5nIHJlc2V0IGRlZmF1bHQgY29sb3IKIwojIEBzZXQgX19IRUxQX0VYQU1QTEUgU3RyaW5nIHRvIHJlbW92ZQojIEBzZXQgX19IRUxQX1RJVExFIFN0cmluZyB0byByZW1vdmUKIyBAc2V0IF9fSEVMUF9OT1JNQUwgU3RyaW5nIHRvIHJlbW92ZQojIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKVUk6OnRoZW1lKCkgewogIGxvY2FsIHRoZW1lPSIkezEtZGVmYXVsdH0iCiAgaWYgW1sgISAiJHt0aGVtZX0iID1+IC1mb3JjZSQgXV0gJiYgISBBc3NlcnQ6OnR0eTsgdGhlbgogICAgdGhlbWU9Im5vQ29sb3IiCiAgZmkKICBjYXNlICIke3RoZW1lfSIgaW4KICAgIGRlZmF1bHQgfCBkZWZhdWx0LWZvcmNlKQogICAgICB0aGVtZT0iZGVmYXVsdCIKICAgICAgOzsKICAgIG5vQ29sb3IpIDs7CiAgICAqKQogICAgICBMb2c6OmZhdGFsICJpbnZhbGlkIHRoZW1lIHByb3ZpZGVkIgogICAgICA7OwogIGVzYWMKICBpZiBbWyAiJHt0aGVtZX0iID0gImRlZmF1bHQiIF1dOyB0aGVuCiAgICBCQVNIX0ZSQU1FV09SS19USEVNRT0iZGVmYXVsdCIKICAgICMgY2hlY2sgY29sb3JzIGFwcGxpY2FibGUgaHR0cHM6Ly9taXNjLmZsb2dpc29mdC5jb20vYmFzaC90aXBfY29sb3JzX2FuZF9mb3JtYXR0aW5nCiAgICBfX0VSUk9SX0NPTE9SPSdcZVszMW0nICAgICAgICAgIyBSZWQKICAgIF9fSU5GT19DT0xPUj0nXGVbNDRtJyAgICAgICAgICAjIHdoaXRlIG9uIGxpZ2h0Qmx1ZQogICAgX19TVUNDRVNTX0NPTE9SPSdcZVszMm0nICAgICAgICMgR3JlZW4KICAgIF9fV0FSTklOR19DT0xPUj0nXGVbMzNtJyAgICAgICAjIFllbGxvdwogICAgX19TS0lQUEVEX0NPTE9SPSdcZVszM20nICAgICAgICMgWWVsbG93CiAgICBfX0RFQlVHX0NPTE9SPSdcZVszN20nICAgICAgICAgIyBHcmV5CiAgICBfX0hFTFBfQ09MT1I9J1xlWzc7NDk7MzNtJyAgICAgIyBCbGFjayBvbiBHb2xkCiAgICBfX1RFU1RfQ09MT1I9J1xlWzEwMG0nICAgICAgICAgIyBMaWdodCBtYWdlbnRhCiAgICBfX1RFU1RfRVJST1JfQ09MT1I9J1xlWzQxbScgICAgIyB3aGl0ZSBvbiByZWQKICAgIF9fSEVMUF9USVRMRV9DT0xPUj0iXGVbMTszN20iICAjIEJvbGQKICAgIF9fSEVMUF9PUFRJT05fQ09MT1I9IlxlWzE7MzRtIiAjIEJsdWUKICAgICMgSW50ZXJuYWw6IHJlc2V0IGNvbG9yCiAgICBfX1JFU0VUX0NPTE9SPSdcZVswbScgIyBSZXNldCBDb2xvcgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMTU1LFNDMjAzNAogICAgX19IRUxQX0VYQU1QTEU9IiQoZWNobyAtZSAiXGVbMjs5N20iKSIKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjE1NSxTQzIwMzQKICAgIF9fSEVMUF9USVRMRT0iJChlY2hvIC1lICJcZVsxOzM3bSIpIgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMTU1LFNDMjAzNAogICAgX19IRUxQX05PUk1BTD0iJChlY2hvIC1lICJcMDMzWzBtIikiCiAgZWxzZQogICAgQkFTSF9GUkFNRVdPUktfVEhFTUU9Im5vQ29sb3IiCiAgICAjIGNoZWNrIGNvbG9ycyBhcHBsaWNhYmxlIGh0dHBzOi8vbWlzYy5mbG9naXNvZnQuY29tL2Jhc2gvdGlwX2NvbG9yc19hbmRfZm9ybWF0dGluZwogICAgX19FUlJPUl9DT0xPUj0nJwogICAgX19JTkZPX0NPTE9SPScnCiAgICBfX1NVQ0NFU1NfQ09MT1I9JycKICAgIF9fV0FSTklOR19DT0xPUj0nJwogICAgX19TS0lQUEVEX0NPTE9SPScnCiAgICBfX0RFQlVHX0NPTE9SPScnCiAgICBfX0hFTFBfQ09MT1I9JycKICAgIF9fVEVTVF9DT0xPUj0nJwogICAgX19URVNUX0VSUk9SX0NPTE9SPScnCiAgICBfX0hFTFBfVElUTEVfQ09MT1I9JycKICAgIF9fSEVMUF9PUFRJT05fQ09MT1I9JycKICAgICMgSW50ZXJuYWw6IHJlc2V0IGNvbG9yCiAgICBfX1JFU0VUX0NPTE9SPScnCiAgICBfX0hFTFBfRVhBTVBMRT0nJwogICAgX19IRUxQX1RJVExFPScnCiAgICBfX0hFTFBfTk9STUFMPScnCiAgZmkKfQoKIyBAZGVzY3JpcHRpb24gY2hlY2sgaWYgdHR5IChpbnRlcmFjdGl2ZSBtb2RlKSBpcyBhY3RpdmUKIyBAbm9hcmdzCiMgQGV4aXRjb2RlIDEgaWYgdHR5IG5vdCBhY3RpdmUKIyBAZW52IE5PTl9JTlRFUkFDVElWRSBpZiAxIGNvbnNpZGVyIGFzIG5vdCBpbnRlcmFjdGl2ZSBldmVuIGlmIGVudmlyb25tZW50IGlzIGludGVyYWN0aXZlCiMgQGVudiBJTlRFUkFDVElWRSBpZiAxIGNvbnNpZGVyIGFzIGludGVyYWN0aXZlIGV2ZW4gaWYgZW52aXJvbm1lbnQgaXMgbm90IGludGVyYWN0aXZlCiMgQHN0ZGVyciBkaWFnbm9zdGljIGluZm9ybWF0aW9uICsgaGVscCBpZiBzZWNvbmQgYXJndW1lbnQgaXMgcHJvdmlkZWQKQXNzZXJ0Ojp0dHkoKSB7CiAgaWYgW1sgIiR7Tk9OX0lOVEVSQUNUSVZFOi0wfSIgPSAiMSIgXV07IHRoZW4KICAgIHJldHVybiAxCiAgZmkKICBpZiBbWyAiJHtJTlRFUkFDVElWRTotMH0iID0gIjEiIF1dOyB0aGVuCiAgICByZXR1cm4gMAogIGZpCiAgW1sgLXQgMSB8fCAtdCAyIF1dCn0KCiMgRlVOQ1RJT05TCgpmYWNhZGVfbWFpbl9lbWJlZEZyYW1ld29ya0Z1bmN0aW9uYmluRmlsZXRwbCgpIHsKIyBSRVFVSVJFUwpMaW51eDo6cmVxdWlyZUV4ZWN1dGVkQXNVc2VyCkVudjo6cmVxdWlyZUxvYWQKTG9nOjpyZXF1aXJlTG9hZApMaW51eDo6cmVxdWlyZVJlYWxwYXRoQ29tbWFuZApVSTo6cmVxdWlyZVRoZW1lCkNvbXBpbGVyOjpGYWNhZGU6OnJlcXVpcmVDb21tYW5kQmluRGlyCgojIEByZXF1aXJlIENvbXBpbGVyOjpGYWNhZGU6OnJlcXVpcmVDb21tYW5kQmluRGlyCgojIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIxNTQsU0MyMDE2CmZ1bmN0aW9uVG9DYWxsPSdEYjo6cXVlcnlPbmVEYXRhYmFzZScKIiR7ZnVuY3Rpb25Ub0NhbGx9IiAiJEAiCgp9CgpmYWNhZGVfbWFpbl9lbWJlZEZyYW1ld29ya0Z1bmN0aW9uYmluRmlsZXRwbCAiJEAiCg==" Compiler::Embed::extractFileFromBase64 \ "${embed_function_DbQueryOneDatabase}" \ "${encoded_binary_file_DbQueryOneDatabase}" -facade_main_605f842ea50b44028501669c69f3be71() { +facade_main_dbQueryAllDatabasessh() { BASH_TOOLS_ROOT_DIR="$(cd "${CURRENT_DIR}/.." && pwd -P)" if [[ -d "${BASH_TOOLS_ROOT_DIR}/vendor/bash-tools-framework/" ]]; then FRAMEWORK_ROOT_DIR="$(cd "${BASH_TOOLS_ROOT_DIR}/vendor/bash-tools-framework" && pwd -P)" @@ -2234,4 +2234,4 @@ fi } -facade_main_605f842ea50b44028501669c69f3be71 "$@" +facade_main_dbQueryAllDatabasessh "$@" diff --git a/bin/dbScriptAllDatabases b/bin/dbScriptAllDatabases index d7a9f782..f9a955ab 100755 --- a/bin/dbScriptAllDatabases +++ b/bin/dbScriptAllDatabases @@ -1215,14 +1215,14 @@ Array::contains() { # @require Compiler::Embed::requireEmbedBinDir -declare -gx embed_function_DbQueryOneDatabase="${PERSISTENT_TMPDIR:-/tmp}/bin/b9b7aa9e913cf5a0f1fa26f2830396d7/dbQueryOneDatabase" -declare -gx encoded_binary_file_DbQueryOneDatabase="IyEvdXNyL2Jpbi9lbnYgYmFzaAojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCiMgR0VORVJBVEVEIEZBQ0FERSBGUk9NIGh0dHBzOi8vZ2l0aHViLmNvbS9mY2hhc3RhbmV0L2Jhc2gtdG9vbHMvdHJlZS9tYXN0ZXIvLi4vYmFzaC1kZXYtZW52L3ZlbmRvci9iYXNoLXRvb2xzLWZyYW1ld29yay9zcmMvQ29tcGlsZXIvRW1iZWQvZW1iZWRGcmFtZXdvcmtGdW5jdGlvbi5iaW5GaWxlLnRwbAojIERPIE5PVCBFRElUIElUCiMgQGdlbmVyYXRlZAojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCiMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjI4OCxTQzIwMzQKIyBCSU5fRklMRT0ke0JJTl9GSUxFfQojIEZBQ0FERQoKIyBlbnN1cmUgdGhhdCBubyB1c2VyIGFsaWFzZXMgY291bGQgaW50ZXJmZXJlIHdpdGgKIyBjb21tYW5kcyB1c2VkIGluIHRoaXMgc2NyaXB0CnVuYWxpYXMgLWEgfHwgdHJ1ZQpzaG9wdCAtdSBleHBhbmRfYWxpYXNlcwoKIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CigoZmFpbHVyZXMgPSAwKSkgfHwgdHJ1ZQoKIyBCYXNoIHdpbGwgcmVtZW1iZXIgJiByZXR1cm4gdGhlIGhpZ2hlc3QgZXhpdCBjb2RlIGluIGEgY2hhaW4gb2YgcGlwZXMuCiMgVGhpcyB3YXkgeW91IGNhbiBjYXRjaCB0aGUgZXJyb3IgaW5zaWRlIHBpcGVzLCBlLmcuIG15c3FsZHVtcCB8IGd6aXAKc2V0IC1vIHBpcGVmYWlsCnNldCAtbyBlcnJleGl0CgojIENvbW1hbmQgU3Vic3RpdHV0aW9uIGNhbiBpbmhlcml0IGVycmV4aXQgb3B0aW9uIHNpbmNlIGJhc2ggdjQuNApzaG9wdCAtcyBpbmhlcml0X2VycmV4aXQgfHwgdHJ1ZQoKIyBhIGxvZyBpcyBnZW5lcmF0ZWQgd2hlbiBhIGNvbW1hbmQgZmFpbHMKc2V0IC1vIGVycnRyYWNlCgojIHVzZSBudWxsZ2xvYiBzbyB0aGF0IChmaWxlKi5waHApIHdpbGwgcmV0dXJuIGFuIGVtcHR5IGFycmF5IGlmIG5vIGZpbGUgbWF0Y2hlcyB0aGUgd2lsZGNhcmQKc2hvcHQgLXMgbnVsbGdsb2IKCiMgZW5zdXJlIHJlZ2V4cCBhcmUgaW50ZXJwcmV0ZWQgd2l0aG91dCBhY2NlbnR1YXRlZCBjaGFyYWN0ZXJzCmV4cG9ydCBMQ19BTEw9UE9TSVgKCmV4cG9ydCBURVJNPXh0ZXJtLTI1NmNvbG9yCgojIGF2b2lkIGludGVyYWN0aXZlIGluc3RhbGwKZXhwb3J0IERFQklBTl9GUk9OVEVORD1ub25pbnRlcmFjdGl2ZQpleHBvcnQgREVCQ09ORl9OT05JTlRFUkFDVElWRV9TRUVOPXRydWUKCiMgc3RvcmUgY29tbWFuZCBhcmd1bWVudHMgZm9yIGxhdGVyIHVzYWdlCiMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNApkZWNsYXJlIC1hIEJBU0hfRlJBTUVXT1JLX0FSR1Y9KCIkQCIpCiMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNApkZWNsYXJlIC1hIE9SSUdJTkFMX0JBU0hfRlJBTUVXT1JLX0FSR1Y9KCIkQCIpCgojIEBzZWUgaHR0cHM6Ly91bml4LnN0YWNrZXhjaGFuZ2UuY29tL2EvMzg2ODU2CiMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjMxNwppbnRlcnJ1cHRNYW5hZ2VtZW50KCkgewogICMgcmVzdG9yZSBTSUdJTlQgaGFuZGxlcgogIHRyYXAgLSBJTlQKICAjIGVuc3VyZSB0aGF0IEN0cmwtQyBpcyB0cmFwcGVkIGJ5IHRoaXMgc2NyaXB0IGFuZCBub3QgYnkgc3ViIHByb2Nlc3MKICAjIHJlcG9ydCB0byB0aGUgcGFyZW50IHRoYXQgd2UgaGF2ZSBpbmRlZWQgYmVlbiBpbnRlcnJ1cHRlZAogIGtpbGwgLXMgSU5UICIkJCIKfQp0cmFwIGludGVycnVwdE1hbmFnZW1lbnQgSU5UClNDUklQVF9OQU1FPSR7MCMjKi99ClJFQUxfU0NSSVBUX0ZJTEU9IiQocmVhZGxpbmsgLWUgIiQocmVhbHBhdGggIiR7QkFTSF9TT1VSQ0VbMF19IikiKSIKQ1VSUkVOVF9ESVI9IiQoY2QgIiQocmVhZGxpbmsgLWUgIiR7UkVBTF9TQ1JJUFRfRklMRSUvKn0iKSIgJiYgcHdkIC1QKSIKCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwojIFRlbXAgZGlyIG1hbmFnZW1lbnQKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCgpLRUVQX1RFTVBfRklMRVM9IiR7S0VFUF9URU1QX0ZJTEVTOi0wfSIKZXhwb3J0IEtFRVBfVEVNUF9GSUxFUwoKIyBQRVJTSVNURU5UX1RNUERJUiBpcyBub3QgZGVsZXRlZCBieSB0cmFwcwpQRVJTSVNURU5UX1RNUERJUj0iJHtUTVBESVI6LS90bXB9L2Jhc2gtZnJhbWV3b3JrIgpleHBvcnQgUEVSU0lTVEVOVF9UTVBESVIKbWtkaXIgLXAgIiR7UEVSU0lTVEVOVF9UTVBESVJ9IgoKIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0ClRNUERJUj0iJChta3RlbXAgLWQgLXAgIiR7UEVSU0lTVEVOVF9UTVBESVI6LS90bXB9IiAtdCBiYXNoLWZyYW1ld29yay0kJC1YWFhYWFgpIgpleHBvcnQgVE1QRElSCgojIHRlbXAgZGlyIGNsZWFuaW5nCiMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjMxNwpjbGVhbk9uRXhpdCgpIHsKICBpZiBbWyAiJHtLRUVQX1RFTVBfRklMRVM6LTB9IiA9ICIxIiBdXTsgdGhlbgogICAgTG9nOjpkaXNwbGF5SW5mbyAiS0VFUF9URU1QX0ZJTEVTPTEgdGVtcCBmaWxlcyBrZXB0IGhlcmUgJyR7VE1QRElSfSciCiAgZWxpZiBbWyAtbiAiJHtUTVBESVIreHh4fSIgXV07IHRoZW4KICAgIExvZzo6ZGlzcGxheURlYnVnICJLRUVQX1RFTVBfRklMRVM9MCByZW1vdmluZyB0ZW1wIGZpbGVzICcke1RNUERJUn0nIgogICAgcm0gLVJmICIke1RNUERJUjotL3RtcC9mYWtlfSIgPi9kZXYvbnVsbCAyPiYxCiAgZmkKfQp0cmFwIGNsZWFuT25FeGl0IEVYSVQgSFVQIFFVSVQgQUJSVCBURVJNCgojIFZBUl9NQUlOX0ZVTkNUSU9OX1ZBUl9OQU1FPWRiUXVlcnlBbGxEYXRhYmFzZXNGYWNhZGUKCiMgQGRlc2NyaXB0aW9uIHVzZWQgdG8gZXhlY3V0ZSBnaXZlbiBxdWVyeSB3aGVuIHVzaW5nCiMgZGJTY3JpcHRBbGxEYXRhYmFzZXMKIyBAYXJnICQxIGRzbjpTdHJpbmcKIyBAYXJnICQyIGRiOlN0cmluZwojIEBlbnYgcXVlcnkgU3RyaW5nCiMgQGVudiBvcHRpb25TZXBhcmF0b3IgU3RyaW5nCiMgQHJlcXVpcmUgTGludXg6OnJlcXVpcmVFeGVjdXRlZEFzVXNlcgpEYjo6cXVlcnlPbmVEYXRhYmFzZSgpIHsKICAjIHF1ZXJ5IGFuZCBvcHRpb25TZXBhcmF0b3IgYXJlIHBhc3NlZCB2aWEgZXhwb3J0CiAgbG9jYWwgZHNuPSIkMSIKICBsb2NhbCBkYj0iJDIiCgogIGxvY2FsIC1BIGRiSW5zdGFuY2UKICBEYXRhYmFzZTo6bmV3SW5zdGFuY2UgZGJJbnN0YW5jZSAiJHtkc259IgogIERhdGFiYXNlOjpzZXRRdWVyeU9wdGlvbnMgZGJJbnN0YW5jZSAiJHtkYkluc3RhbmNlW1FVRVJZX09QVElPTlNdfSAtLWNvbm5lY3QtdGltZW91dD01IgoKICAjIGlkZW50aWZ5IGNvbHVtbnMgaGVhZGVyCiAgZWNobyAtbiAiQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAiCiAgRGF0YWJhc2U6OnNraXBDb2x1bW5OYW1lcyBkYkluc3RhbmNlIDAKCiAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMTU0CiAgaWYgISBEYXRhYmFzZTo6cXVlcnkgZGJJbnN0YW5jZSAiJHtxdWVyeX0iICIke2RifSIgfCBzZWQgInMvXHQvJHtvcHRpb25TZXBhcmF0b3J9L2ciOyB0aGVuCiAgICBMb2c6OmZhdGFsICJkYXRhYmFzZSAke2RifSBlcnJvciIgMT4mMgogIGZpCn0KCiMgQGRlc2NyaXB0aW9uIExvZyBuYW1lc3BhY2UgcHJvdmlkZXMgMiBraW5kIG9mIGZ1bmN0aW9ucwojIC0gTG9nOjpkaXNwbGF5KiBhbGxvd3MgdG8gZGlzcGxheSBnaXZlbiBtZXNzYWdlIHdpdGgKIyAgIGdpdmVuIGRpc3BsYXkgbGV2ZWwKIyAtIExvZzo6bG9nKiBhbGxvd3MgdG8gbG9nIGdpdmVuIG1lc3NhZ2Ugd2l0aAojICAgZ2l2ZW4gbG9nIGxldmVsCiMgTG9nOjpkaXNwbGF5KiBmdW5jdGlvbnMgYXV0b21hdGljYWxseSBsb2cgdGhlIG1lc3NhZ2UgdG9vCiMgQHNlZSBFbnY6OnJlcXVpcmVMb2FkIHRvIGxvYWQgdGhlIGRpc3BsYXkgYW5kIGxvZyBsZXZlbCBmcm9tIC5lbnYgZmlsZQoKIyBAZGVzY3JpcHRpb24gbG9nIGxldmVsIG9mZgpleHBvcnQgX19MRVZFTF9PRkY9MAojIEBkZXNjcmlwdGlvbiBsb2cgbGV2ZWwgZXJyb3IKZXhwb3J0IF9fTEVWRUxfRVJST1I9MQojIEBkZXNjcmlwdGlvbiBsb2cgbGV2ZWwgd2FybmluZwpleHBvcnQgX19MRVZFTF9XQVJOSU5HPTIKIyBAZGVzY3JpcHRpb24gbG9nIGxldmVsIGluZm8KZXhwb3J0IF9fTEVWRUxfSU5GTz0zCiMgQGRlc2NyaXB0aW9uIGxvZyBsZXZlbCBzdWNjZXNzCmV4cG9ydCBfX0xFVkVMX1NVQ0NFU1M9MwojIEBkZXNjcmlwdGlvbiBsb2cgbGV2ZWwgZGVidWcKZXhwb3J0IF9fTEVWRUxfREVCVUc9NAoKIyBAZGVzY3JpcHRpb24gdmVyYm9zZSBsZXZlbCBvZmYKZXhwb3J0IF9fVkVSQk9TRV9MRVZFTF9PRkY9MAojIEBkZXNjcmlwdGlvbiB2ZXJib3NlIGxldmVsIGluZm8KZXhwb3J0IF9fVkVSQk9TRV9MRVZFTF9JTkZPPTEKIyBAZGVzY3JpcHRpb24gdmVyYm9zZSBsZXZlbCBpbmZvCmV4cG9ydCBfX1ZFUkJPU0VfTEVWRUxfREVCVUc9MgojIEBkZXNjcmlwdGlvbiB2ZXJib3NlIGxldmVsIGluZm8KZXhwb3J0IF9fVkVSQk9TRV9MRVZFTF9UUkFDRT0zCgojIEBkZXNjcmlwdGlvbiBEaXNwbGF5IG1lc3NhZ2UgdXNpbmcgZGVidWcgY29sb3IgKGdyZXkpCiMgQGFyZyAkMSBtZXNzYWdlOlN0cmluZyB0aGUgbWVzc2FnZSB0byBkaXNwbGF5CkxvZzo6ZGlzcGxheURlYnVnKCkgewogIGlmICgoQkFTSF9GUkFNRVdPUktfRElTUExBWV9MRVZFTCA+PSBfX0xFVkVMX0RFQlVHKSk7IHRoZW4KICAgIGVjaG8gLWUgIiR7X19ERUJVR19DT0xPUn1ERUJVRyAgIC0gJHsxfSR7X19SRVNFVF9DT0xPUn0iID4mMgogIGZpCiAgTG9nOjpsb2dEZWJ1ZyAiJDEiCn0KCiMgQGRlc2NyaXB0aW9uIERpc3BsYXkgbWVzc2FnZSB1c2luZyBpbmZvIGNvbG9yIChiZyBsaWdodCBibHVlL2ZnIHdoaXRlKQojIEBhcmcgJDEgbWVzc2FnZTpTdHJpbmcgdGhlIG1lc3NhZ2UgdG8gZGlzcGxheQpMb2c6OmRpc3BsYXlJbmZvKCkgewogIGxvY2FsIHR5cGU9IiR7MjotSU5GT30iCiAgaWYgKChCQVNIX0ZSQU1FV09SS19ESVNQTEFZX0xFVkVMID49IF9fTEVWRUxfSU5GTykpOyB0aGVuCiAgICBlY2hvIC1lICIke19fSU5GT19DT0xPUn0ke3R5cGV9ICAgIC0gJHsxfSR7X19SRVNFVF9DT0xPUn0iID4mMgogIGZpCiAgTG9nOjpsb2dJbmZvICIkMSIgIiR7dHlwZX0iCn0KCiMgQGRlc2NyaXB0aW9uIGVuc3VyZSBDT01NQU5EX0JJTl9ESVIgZW52IHZhciBpcyBzZXQKIyBhbmQgUEFUSCBjb3JyZWN0bHkgcHJlcGFyZWQKIyBAbm9hcmdzCiMgQHNldCBDT01NQU5EX0JJTl9ESVIgc3RyaW5nIHRoZSBkaXJlY3Rvcnkgd2hlcmUgdG8gZmluZCB0aGlzIGNvbW1hbmQKIyBAc2V0IFBBVEggc3RyaW5nIGFkZCBkaXJlY3Rvcnkgd2hlcmUgdG8gZmluZCB0aGlzIGNvbW1hbmQgYmluYXJ5CkNvbXBpbGVyOjpGYWNhZGU6OnJlcXVpcmVDb21tYW5kQmluRGlyKCkgewogIENPTU1BTkRfQklOX0RJUj0iJHtDVVJSRU5UX0RJUn0iCiAgRW52OjpwYXRoUHJlcGVuZCAiJHtDT01NQU5EX0JJTl9ESVJ9Igp9CgojIEBkZXNjcmlwdGlvbiBjcmVhdGUgYSBuZXcgZGIgaW5zdGFuY2UKIyBSZXR1cm5zIGltbWVkaWF0ZWx5IGlmIHRoZSBpbnN0YW5jZSBpcyBhbHJlYWR5IGluaXRpYWxpemVkCiMKIyBAYXJnICQxIGluc3RhbmNlTmV3SW5zdGFuY2U6Jk1hcDxTdHJpbmcsU3RyaW5nPiAocGFzc2VkIGJ5IHJlZmVyZW5jZSkgZGF0YWJhc2UgaW5zdGFuY2UgdG8gdXNlCiMgQGFyZyAkMiBkc246U3RyaW5nIGRzbiBwcm9maWxlIC0gbG9hZCB0aGUgZHNuLmVudiBwcm9maWxlIGRlZHVjZWQgdXNpbmcgcnVsZXMgZGVmaW5lZCBpbiBDb25mOjpnZXRBYnNvbHV0ZUZpbGUKIwojIEBleGFtcGxlCiMgICBkZWNsYXJlIC1BZ3ggZGJJbnN0YW5jZQojICAgRGF0YWJhc2U6Om5ld0luc3RhbmNlIGRiSW5zdGFuY2UgImRlZmF1bHQubG9jYWwiCiMKIyBAZXhpdGNvZGUgMSBpZiBkbnMgZmlsZSBub3QgYWJsZSB0byBsb2FkZWQKRGF0YWJhc2U6Om5ld0luc3RhbmNlKCkgewogIGxvY2FsIC1uIGluc3RhbmNlTmV3SW5zdGFuY2U9JDEKICBsb2NhbCBkc249IiQyIgogIGxvY2FsIERTTl9GSUxFCgogIGlmIFtbIC12IGluc3RhbmNlTmV3SW5zdGFuY2VbJ0lOSVRJQUxJWkVEJ10gJiYgIiR7aW5zdGFuY2VOZXdJbnN0YW5jZVsnSU5JVElBTElaRUQnXTotMH0iID09ICIxIiBdXTsgdGhlbgogICAgcmV0dXJuCiAgZmkKCiAgIyBmaW5hbCBhdXRoIGZpbGUgZ2VuZXJhdGVkIGZyb20gZG5zIGZpbGUKICBpbnN0YW5jZU5ld0luc3RhbmNlWydBVVRIX0ZJTEUnXT0iIgogIGluc3RhbmNlTmV3SW5zdGFuY2VbJ0RTTl9GSUxFJ109IiIKCiAgIyBjaGVjayBkc24gZmlsZQogIERTTl9GSUxFPSIkKENvbmY6OmdldEFic29sdXRlRmlsZSAiZHNuIiAiJHtkc259IiAiZW52IikiIHx8IHJldHVybiAxCiAgRGF0YWJhc2U6OmNoZWNrRHNuRmlsZSAiJHtEU05fRklMRX0iIHx8IHJldHVybiAxCiAgaW5zdGFuY2VOZXdJbnN0YW5jZVsnRFNOX0ZJTEUnXT0iJHtEU05fRklMRX0iCgogICMgc2hlbGxjaGVjayBzb3VyY2U9L3NyYy9EYXRhYmFzZS90ZXN0c0RhdGEvZHNuX3ZhbGlkLmVudgogIHNvdXJjZSAiJHtpbnN0YW5jZU5ld0luc3RhbmNlWydEU05fRklMRSddfSIKCiAgaW5zdGFuY2VOZXdJbnN0YW5jZVsnVVNFUiddPSIke1VTRVJ9IgogIGluc3RhbmNlTmV3SW5zdGFuY2VbJ1BBU1NXT1JEJ109IiR7UEFTU1dPUkR9IgogIGluc3RhbmNlTmV3SW5zdGFuY2VbJ0hPU1ROQU1FJ109IiR7SE9TVE5BTUV9IgogIGluc3RhbmNlTmV3SW5zdGFuY2VbJ1BPUlQnXT0iJHtQT1JUfSIKCiAgIyBnZW5lcmF0ZSBhdXRoRmlsZSBmb3IgZWFzeSBhdXRoZW50aWNhdGlvbgogIGluc3RhbmNlTmV3SW5zdGFuY2VbJ0FVVEhfRklMRSddPSQobWt0ZW1wIC1wICIke1RNUERJUjotL3RtcH0iIC10ICJteXNxbC5YWFhYWFhYWFhYWFgiKQogICgKICAgIGVjaG8gIltjbGllbnRdIgogICAgZWNobyAidXNlciA9ICR7VVNFUn0iCiAgICBlY2hvICJwYXNzd29yZCA9ICR7UEFTU1dPUkR9IgogICAgZWNobyAiaG9zdCA9ICR7SE9TVE5BTUV9IgogICAgZWNobyAicG9ydCA9ICR7UE9SVH0iCiAgKSA+IiR7aW5zdGFuY2VOZXdJbnN0YW5jZVsnQVVUSF9GSUxFJ119IgoKICAjIHNvbWUgb2YgdGhvc2UgdmFsdWVzIGNhbiBiZSBvdmVycmlkZGVuIHVzaW5nIHRoZSBkc24gZmlsZQogICMgU0tJUF9DT0xVTU5fTkFNRVMgZW5hYmxlZCBieSBkZWZhdWx0CiAgaW5zdGFuY2VOZXdJbnN0YW5jZVsnU0tJUF9DT0xVTU5fTkFNRVMnXT0iJHtTS0lQX0NPTFVNTl9OQU1FUzotMX0iCiAgaW5zdGFuY2VOZXdJbnN0YW5jZVsnU1NMX09QVElPTlMnXT0iJHtNWVNRTF9TU0xfT1BUSU9OUzotLS1zc2wtbW9kZT1ESVNBQkxFRH0iCiAgaW5zdGFuY2VOZXdJbnN0YW5jZVsnUVVFUllfT1BUSU9OUyddPSIke01ZU1FMX1FVRVJZX09QVElPTlM6LS0tYmF0Y2ggLS1yYXcgLS1kZWZhdWx0LWNoYXJhY3Rlci1zZXQ9dXRmOH0iCiAgaW5zdGFuY2VOZXdJbnN0YW5jZVsnRFVNUF9PUFRJT05TJ109IiR7TVlTUUxfRFVNUF9PUFRJT05TOi0tLWRlZmF1bHQtY2hhcmFjdGVyLXNldD11dGY4IC0tY29tcHJlc3MgLS1oZXgtYmxvYiAtLXJvdXRpbmVzIC0tdHJpZ2dlcnMgLS1zaW5nbGUtdHJhbnNhY3Rpb24gLS1zZXQtZ3RpZC1wdXJnZWQ9T0ZGIC0tY29sdW1uLXN0YXRpc3RpY3M9MCAke2luc3RhbmNlTmV3SW5zdGFuY2VbJ1NTTF9PUFRJT05TJ119fSIKICBpbnN0YW5jZU5ld0luc3RhbmNlWydEQl9JTVBPUlRfT1BUSU9OUyddPSIke0RCX0lNUE9SVF9PUFRJT05TOi0tLWNvbm5lY3QtdGltZW91dD01IC0tYmF0Y2ggLS1yYXcgLS1kZWZhdWx0LWNoYXJhY3Rlci1zZXQ9dXRmOH0iCgogIGluc3RhbmNlTmV3SW5zdGFuY2VbJ0lOSVRJQUxJWkVEJ109MQp9CgojIEBkZXNjcmlwdGlvbiBteXNxbCBxdWVyeSBvbiBhIGdpdmVuIGRiCiMgQHdhcm5pbmcgY291bGQgdXNlIFFVRVJZX09QVElPTlMgdmFyaWFibGUgZnJvbSBkc24gaWYgZGVmaW5lZAojIEBleGFtcGxlCiMgICBjYXQgZmlsZS5zcWwgfCBEYXRhYmFzZTo6cXVlcnkgLi4uCiMgQGFyZyAkMSBpbnN0YW5jZVF1ZXJ5OiZNYXA8U3RyaW5nLFN0cmluZz4gKHBhc3NlZCBieSByZWZlcmVuY2UpIGRhdGFiYXNlIGluc3RhbmNlIHRvIHVzZQojIEBhcmcgJDIgc3FsUXVlcnk6U3RyaW5nIChvcHRpb25hbCkgc3FsIHF1ZXJ5IG9yIHNxbCBmaWxlIHRvIGV4ZWN1dGUuIGlmIG5vdCBwcm92aWRlZCBvciBlbXB0eSwgdGhlIGNvbW1hbmQgY2FuIGJlIHBpcGVkCiMgQGFyZyAkMyBkYk5hbWU6U3RyaW5nIChvcHRpb25hbCkgdGhlIGRiIG5hbWUKIwojIEBleGl0Y29kZSBteXNxbCBjb21tYW5kIHN0YXR1cyBjb2RlCkRhdGFiYXNlOjpxdWVyeSgpIHsKICBsb2NhbCAtbiBpbnN0YW5jZVF1ZXJ5PSQxCiAgbG9jYWwgLWEgbXlzcWxDb21tYW5kPSgpCiAgbG9jYWwgLWEgcXVlcnlPcHRpb25zCgogIG15c3FsQ29tbWFuZCs9KG15c3FsKQogIG15c3FsQ29tbWFuZCs9KCItLWRlZmF1bHRzLWV4dHJhLWZpbGU9JHtpbnN0YW5jZVF1ZXJ5WydBVVRIX0ZJTEUnXX0iKQogIElGUz0nICcgcmVhZCAtciAtYSBxdWVyeU9wdGlvbnMgPDw8IiR7aW5zdGFuY2VRdWVyeVsnUVVFUllfT1BUSU9OUyddfSIKICBteXNxbENvbW1hbmQrPSgiJHtxdWVyeU9wdGlvbnNbQF19IikKICBpZiBbWyAiJHtpbnN0YW5jZVF1ZXJ5WydTS0lQX0NPTFVNTl9OQU1FUyddfSIgPSAiMSIgXV07IHRoZW4KICAgIG15c3FsQ29tbWFuZCs9KCItcyIgIi0tc2tpcC1jb2x1bW4tbmFtZXMiKQogIGZpCiAgIyBhZGQgb3B0aW9uYWwgZGIgbmFtZQogIGlmIFtbIC1uICIkezMreH0iIF1dOyB0aGVuCiAgICBteXNxbENvbW1hbmQrPSgiJDMiKQogIGZpCiAgIyBhZGQgb3B0aW9uYWwgc3FsIHF1ZXJ5CiAgaWYgW1sgLW4gIiR7Mit4fSIgJiYgLW4gIiQyIiAmJiAhIC1mICIkMiIgXV07IHRoZW4KICAgIG15c3FsQ29tbWFuZCs9KCItZSIpCiAgICBteXNxbENvbW1hbmQrPSgiJDIiKQogIGZpCiAgTG9nOjpkaXNwbGF5RGVidWcgIiQocHJpbnRmICJleGVjdXRlIGNvbW1hbmQ6ICclcyciICIke215c3FsQ29tbWFuZFsqXX0iKSIKCiAgaWYgW1sgLWYgIiQyIiBdXTsgdGhlbgogICAgIiR7bXlzcWxDb21tYW5kW0BdfSIgPCIkMiIKICBlbHNlCiAgICAiJHtteXNxbENvbW1hbmRbQF19IgogIGZpCn0KCiMgQGRlc2NyaXB0aW9uIHNldCB0aGUgZ2VuZXJhbCBvcHRpb25zIHRvIHVzZSBvbiBteXNxbCBjb21tYW5kIHRvIHF1ZXJ5IHRoZSBkYXRhYmFzZQojIERpZmZlcnMgdGhhbiBzZXRPcHRpb25zIGluIHRoZSB3YXkgdGhhdCB0aGVzZSBvcHRpb25zIGNvdWxkIGNoYW5nZSBlYWNoIHRpbWUKIwojIEBhcmcgJDEgaW5zdGFuY2VTZXRRdWVyeU9wdGlvbnM6Jk1hcDxTdHJpbmcsU3RyaW5nPiAocGFzc2VkIGJ5IHJlZmVyZW5jZSkgZGF0YWJhc2UgaW5zdGFuY2UgdG8gdXNlCiMgQGFyZyAkMiBvcHRpb25zTGlzdDpTdHJpbmcgcXVlcnkgb3B0aW9ucyBsaXN0CkRhdGFiYXNlOjpzZXRRdWVyeU9wdGlvbnMoKSB7CiAgbG9jYWwgLW4gaW5zdGFuY2VTZXRRdWVyeU9wdGlvbnM9JDEKICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICBpbnN0YW5jZVNldFF1ZXJ5T3B0aW9uc1snUVVFUllfT1BUSU9OUyddPSIkMiIKfQoKIyBAZGVzY3JpcHRpb24gYnkgZGVmYXVsdCB3ZSBza2lwIHRoZSBjb2x1bW4gbmFtZXMKIyBidXQgc29tZXRpbWVzIHdlIG5lZWQgY29sdW1uIG5hbWVzIHRvIGRpc3BsYXkgc29tZSByZXN1bHRzCiMgZGlzYWJsZSB0aGlzIG9wdGlvbiB0ZW1wb3JhcmlseSBhbmQgdGhlbiByZXN0b3JlIGl0IHRvIHRydWUKIwojIEBhcmcgJDEgaW5zdGFuY2VTZXRRdWVyeU9wdGlvbnM6Jk1hcDxTdHJpbmcsU3RyaW5nPiAocGFzc2VkIGJ5IHJlZmVyZW5jZSkgZGF0YWJhc2UgaW5zdGFuY2UgdG8gdXNlCiMgQGFyZyAkMiBza2lwQ29sdW1uTmFtZXM6Qm9vbGVhbiAwIHRvIGRpc2FibGUsIDEgdG8gZW5hYmxlIChoaWRlIGNvbHVtbiBuYW1lcykKRGF0YWJhc2U6OnNraXBDb2x1bW5OYW1lcygpIHsKICBsb2NhbCAtbiBpbnN0YW5jZVNraXBDb2x1bW5OYW1lcz0kMQogICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogIGluc3RhbmNlU2tpcENvbHVtbk5hbWVzWydTS0lQX0NPTFVNTl9OQU1FUyddPSIkMiIKfQoKIyBAZGVzY3JpcHRpb24gcHJlcGVuZCBkaXJlY3RvcmllcyB0byB0aGUgUEFUSCBlbnZpcm9ubWVudCB2YXJpYWJsZQojIEBhcmcgJEAgYXJnczpTdHJpbmdbXSBsaXN0IG9mIGRpcmVjdG9yaWVzIHRvIHByZXBlbmQKIyBAc2V0IFBBVEggdXBkYXRlIFBBVEggd2l0aCB0aGUgZGlyZWN0b3JpZXMgcHJlcGVuZGVkCkVudjo6cGF0aFByZXBlbmQoKSB7CiAgbG9jYWwgYXJnCiAgZm9yIGFyZyBpbiAiJEAiOyBkbwogICAgaWYgW1sgLWQgIiR7YXJnfSIgJiYgIjoke1BBVEh9OiIgIT0gKiI6JHthcmd9OiIqIF1dOyB0aGVuCiAgICAgIFBBVEg9IiQocmVhbHBhdGggIiR7YXJnfSIpOiR7UEFUSH0iCiAgICBmaQogIGRvbmUKfQoKIyBAZGVzY3JpcHRpb24gRGlzcGxheSBtZXNzYWdlIHVzaW5nIGVycm9yIGNvbG9yIChyZWQpIGFuZCBleGl0IGltbWVkaWF0ZWx5IHdpdGggZXJyb3Igc3RhdHVzIDEKIyBAYXJnICQxIG1lc3NhZ2U6U3RyaW5nIHRoZSBtZXNzYWdlIHRvIGRpc3BsYXkKTG9nOjpmYXRhbCgpIHsKICBlY2hvIC1lICIke19fRVJST1JfQ09MT1J9RkFUQUwgICAtICR7MX0ke19fUkVTRVRfQ09MT1J9IiA+JjIKICBMb2c6OmxvZ0ZhdGFsICIkMSIKICBleGl0IDEKfQoKIyBAZGVzY3JpcHRpb24gbG9nIG1lc3NhZ2UgdG8gZmlsZQojIEBhcmcgJDEgbWVzc2FnZTpTdHJpbmcgdGhlIG1lc3NhZ2UgdG8gZGlzcGxheQpMb2c6OmxvZ0RlYnVnKCkgewogIGlmICgoQkFTSF9GUkFNRVdPUktfTE9HX0xFVkVMID49IF9fTEVWRUxfREVCVUcpKTsgdGhlbgogICAgTG9nOjpsb2dNZXNzYWdlICIkezI6LURFQlVHfSIgIiQxIgogIGZpCn0KCiMgQGRlc2NyaXB0aW9uIGxvZyBtZXNzYWdlIHRvIGZpbGUKIyBAYXJnICQxIG1lc3NhZ2U6U3RyaW5nIHRoZSBtZXNzYWdlIHRvIGRpc3BsYXkKTG9nOjpsb2dJbmZvKCkgewogIGlmICgoQkFTSF9GUkFNRVdPUktfTE9HX0xFVkVMID49IF9fTEVWRUxfSU5GTykpOyB0aGVuCiAgICBMb2c6OmxvZ01lc3NhZ2UgIiR7MjotSU5GT30iICIkMSIKICBmaQp9CgojIEBkZXNjcmlwdGlvbiBlbnN1cmUgcnVubmluZyB1c2VyIGlzIG5vdCByb290CiMgQGV4aXRjb2RlIDEgaWYgY3VycmVudCB1c2VyIGlzIHJvb3QKIyBAc3RkZXJyIGRpYWdub3N0aWNzIGluZm9ybWF0aW9uIGlzIGRpc3BsYXllZApMaW51eDo6cmVxdWlyZUV4ZWN1dGVkQXNVc2VyKCkgewogIGlmIFtbICIkKGlkIC11KSIgPSAiMCIgXV07IHRoZW4KICAgIExvZzo6ZmF0YWwgInRoaXMgc2NyaXB0IHNob3VsZCBiZSBleGVjdXRlZCBhcyBub3JtYWwgdXNlciIKICBmaQp9CgojIEBkZXNjcmlwdGlvbiBnZXQgYWJzb2x1dGUgY29uZiBmaWxlIGZyb20gc3BlY2lmaWVkIGNvbmYgZm9sZGVyIGRlZHVjZWQgdXNpbmcgdGhlc2UgcnVsZXMKIyAgICogZnJvbSBhYnNvbHV0ZSBmaWxlIChpZ25vcmVzIDxjb25mRm9sZGVyPiBhbmQgPGV4dGVuc2lvbj4pCiMgICAqIHJlbGF0aXZlIHRvIHdoZXJlIHNjcmlwdCBpcyBleGVjdXRlZCAoaWdub3JlcyA8Y29uZkZvbGRlcj4gYW5kIDxleHRlbnNpb24+KQojICAgKiBmcm9tIGhvbWUvLmJhc2gtdG9vbHMvPGNvbmZGb2xkZXI+CiMgICAqIGZyb20gZnJhbWV3b3JrIGNvbmYvPGNvbmZGb2xkZXI+CiMKIyBAYXJnICQxIGNvbmZGb2xkZXI6U3RyaW5nIHRoZSBkaXJlY3RvcnkgbmFtZSAobm90IHRoZSBwYXRoKSB0byBsaXN0CiMgQGFyZyAkMiBjb25mOlN0cmluZyBmaWxlIHRvIHVzZSB3aXRob3V0IGV4dGVuc2lvbgojIEBhcmcgJDMgZXh0ZW5zaW9uOlN0cmluZyB0aGUgZXh0ZW5zaW9uICguc2ggYnkgZGVmYXVsdCkKIwojIEBzdGRvdXQgYWJzb2x1dGUgY29uZiBmaWxlbmFtZQojIEBleGl0Y29kZSAxIGlmIGZpbGUgaXMgbm90IGZvdW5kIGluIGFueSBsb2NhdGlvbgpDb25mOjpnZXRBYnNvbHV0ZUZpbGUoKSB7CiAgbG9jYWwgY29uZkZvbGRlcj0iJDEiCiAgbG9jYWwgY29uZj0iJDIiCiAgbG9jYWwgZXh0ZW5zaW9uPSIkezMtLnNofSIKICBpZiBbWyAtbiAiJHtleHRlbnNpb259IiAmJiAiJHtleHRlbnNpb246MDoxfSIgIT0gIi4iIF1dOyB0aGVuCiAgICBleHRlbnNpb249Ii4ke2V4dGVuc2lvbn0iCiAgZmkKCiAgdGVzdEFicygpIHsKICAgIGxvY2FsIHJlc3VsdAogICAgcmVzdWx0PSIkKHJlYWxwYXRoIC1lICIkMSIgMj4vZGV2L251bGwpIgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMTgxCiAgICBpZiBbWyAiJD8iID0gIjAiICYmIC1mICIke3Jlc3VsdH0iIF1dOyB0aGVuCiAgICAgIGVjaG8gIiR7cmVzdWx0fSIKICAgICAgcmV0dXJuIDAKICAgIGZpCiAgICByZXR1cm4gMQogIH0KCiAgIyBjb25mIGlzIGFic29sdXRlIGZpbGUgKGluY2x1ZGluZyBleHRlbnNpb24pCiAgdGVzdEFicyAiJHtjb25mRm9sZGVyfSR7ZXh0ZW5zaW9ufSIgJiYgcmV0dXJuIDAKICAjIGNvbmYgaXMgYWJzb2x1dGUgZmlsZQogIHRlc3RBYnMgIiR7Y29uZkZvbGRlcn0iICYmIHJldHVybiAwCiAgIyBjb25mIGlzIGFic29sdXRlIGZpbGUgKGluY2x1ZGluZyBleHRlbnNpb24pCiAgdGVzdEFicyAiJHtjb25mfSR7ZXh0ZW5zaW9ufSIgJiYgcmV0dXJuIDAKICAjIGNvbmYgaXMgYWJzb2x1dGUgZmlsZQogIHRlc3RBYnMgIiR7Y29uZn0iICYmIHJldHVybiAwCgogICMgcmVsYXRpdmUgdG8gd2hlcmUgc2NyaXB0IGlzIGV4ZWN1dGVkIChpbmNsdWRpbmcgZXh0ZW5zaW9uKQogIGlmIFtbIC1uICIke0NVUlJFTlRfRElSK3h4eH0iIF1dOyB0aGVuCiAgICB0ZXN0QWJzICIkKEZpbGU6OmNvbmNhdGVuYXRlUGF0aCAiJHtDVVJSRU5UX0RJUn0iICIke2NvbmZGb2xkZXJ9IikvJHtjb25mfSR7ZXh0ZW5zaW9ufSIgJiYgcmV0dXJuIDAKICBmaQogICMgZnJvbSBob21lLy5iYXNoLXRvb2xzLzxjb25mRm9sZGVyPgogIHRlc3RBYnMgIiQoRmlsZTo6Y29uY2F0ZW5hdGVQYXRoICIke0hPTUV9Ly5iYXNoLXRvb2xzIiAiJHtjb25mRm9sZGVyfSIpLyR7Y29uZn0ke2V4dGVuc2lvbn0iICYmIHJldHVybiAwCgogIGlmIFtbIC1uICIke0ZSQU1FV09SS19ST09UX0RJUit4eHh9IiBdXTsgdGhlbgogICAgIyBmcm9tIGZyYW1ld29yayBjb25mLzxjb25mRm9sZGVyPiAoaW5jbHVkaW5nIGV4dGVuc2lvbikKICAgIHRlc3RBYnMgIiQoRmlsZTo6Y29uY2F0ZW5hdGVQYXRoICIke0ZSQU1FV09SS19ST09UX0RJUn0vY29uZiIgIiR7Y29uZkZvbGRlcn0iKS8ke2NvbmZ9JHtleHRlbnNpb259IiAmJiByZXR1cm4gMAoKICAgICMgZnJvbSBmcmFtZXdvcmsgY29uZi88Y29uZkZvbGRlcj4KICAgIHRlc3RBYnMgIiQoRmlsZTo6Y29uY2F0ZW5hdGVQYXRoICIke0ZSQU1FV09SS19ST09UX0RJUn0vY29uZiIgIiR7Y29uZkZvbGRlcn0iKS8ke2NvbmZ9IiAmJiByZXR1cm4gMAogIGZpCgogICMgZmlsZSBub3QgZm91bmQKICBMb2c6OmRpc3BsYXlFcnJvciAiY29uZiBmaWxlICcke2NvbmZ9JyBub3QgZm91bmQiCgogIHJldHVybiAxCn0KCiMgQGRlc2NyaXB0aW9uIGNoZWNrIGlmIGRzbiBmaWxlIGhhcyBhbGwgdGhlIG1hbmRhdG9yeSB2YXJpYWJsZXMgc2V0CiMgTWFuZGF0b3J5IHZhcmlhYmxlcyBhcmU6IEhPU1ROQU1FLCBVU0VSLCBQQVNTV09SRCwgUE9SVAojCiMgQGFyZyAkMSBkc25GaWxlTmFtZTpTdHJpbmcgZHNuIGFic29sdXRlIGZpbGVuYW1lCiMgQHNldCBIT1NUTkFNRSBsb2FkZWQgZnJvbSBkc24gZmlsZQojIEBzZXQgUE9SVCBsb2FkZWQgZnJvbSBkc24gZmlsZQojIEBzZXQgVVNFUiBsb2FkZWQgZnJvbSBkc24gZmlsZQojIEBzZXQgUEFTU1dPUkQgbG9hZGVkIGZyb20gZHNuIGZpbGUKIyBAZXhpdGNvZGUgMCBvbiB2YWxpZCBmaWxlCiMgQGV4aXRjb2RlIDEgaWYgb25lIG9mIHRoZSBwcm9wZXJ0aWVzIG9mIHRoZSBjb25mIGZpbGUgaXMgaW52YWxpZCBvciBpZiBmaWxlIG5vdCBmb3VuZAojIEBzdGRlcnIgbG9nIG91dHB1dCBpZiBlcnJvciBmb3VuZCBpbiBjb25mIGZpbGUKRGF0YWJhc2U6OmNoZWNrRHNuRmlsZSgpIHsKICBsb2NhbCBkc25GaWxlTmFtZT0iJDEiCiAgaWYgW1sgISAtZiAiJHtkc25GaWxlTmFtZX0iIF1dOyB0aGVuCiAgICBMb2c6OmRpc3BsYXlFcnJvciAiZHNuIGZpbGUgJHtkc25GaWxlTmFtZX0gbm90IGZvdW5kIgogICAgcmV0dXJuIDEKICBmaQoKICAoCiAgICB1bnNldCBIT1NUTkFNRSBQT1JUIFBBU1NXT1JEIFVTRVIKICAgICMgc2hlbGxjaGVjayBzb3VyY2U9L3NyYy9EYXRhYmFzZS90ZXN0c0RhdGEvZHNuX3ZhbGlkLmVudgogICAgc291cmNlICIke2RzbkZpbGVOYW1lfSIKICAgIGlmIFtbIC16ICR7SE9TVE5BTUUreH0gXV07IHRoZW4KICAgICAgTG9nOjpkaXNwbGF5RXJyb3IgImRzbiBmaWxlICR7ZHNuRmlsZU5hbWV9IDogSE9TVE5BTUUgbm90IHByb3ZpZGVkIgogICAgICByZXR1cm4gMQogICAgZmkKICAgIGlmIFtbIC16ICIke0hPU1ROQU1FfSIgXV07IHRoZW4KICAgICAgTG9nOjpkaXNwbGF5V2FybmluZyAiZHNuIGZpbGUgJHtkc25GaWxlTmFtZX0gOiBIT1NUTkFNRSB2YWx1ZSBub3QgcHJvdmlkZWQiCiAgICBmaQogICAgaWYgW1sgIiR7SE9TVE5BTUV9IiA9ICJsb2NhbGhvc3QiIF1dOyB0aGVuCiAgICAgIExvZzo6ZGlzcGxheVdhcm5pbmcgImRzbiBmaWxlICR7ZHNuRmlsZU5hbWV9IDogY2hlY2sgdGhhdCBIT1NUTkFNRSBzaG91bGQgbm90IGJlIDEyNy4wLjAuMSBpbnN0ZWFkIG9mIGxvY2FsaG9zdCIKICAgIGZpCiAgICBpZiBbWyAteiAiJHtQT1JUK3h9IiBdXTsgdGhlbgogICAgICBMb2c6OmRpc3BsYXlFcnJvciAiZHNuIGZpbGUgJHtkc25GaWxlTmFtZX0gOiBQT1JUIG5vdCBwcm92aWRlZCIKICAgICAgcmV0dXJuIDEKICAgIGZpCiAgICBpZiAhIFtbICR7UE9SVH0gPX4gXlswLTldKyQgXV07IHRoZW4KICAgICAgTG9nOjpkaXNwbGF5RXJyb3IgImRzbiBmaWxlICR7ZHNuRmlsZU5hbWV9IDogUE9SVCBpbnZhbGlkIgogICAgICByZXR1cm4gMQogICAgZmkKICAgIGlmIFtbIC16ICIke1VTRVIreH0iIF1dOyB0aGVuCiAgICAgIExvZzo6ZGlzcGxheUVycm9yICJkc24gZmlsZSAke2RzbkZpbGVOYW1lfSA6IFVTRVIgbm90IHByb3ZpZGVkIgogICAgICByZXR1cm4gMQogICAgZmkKICAgIGlmIFtbIC16ICIke1BBU1NXT1JEK3h9IiBdXTsgdGhlbgogICAgICBMb2c6OmRpc3BsYXlFcnJvciAiZHNuIGZpbGUgJHtkc25GaWxlTmFtZX0gOiBQQVNTV09SRCBub3QgcHJvdmlkZWQiCiAgICAgIHJldHVybiAxCiAgICBmaQogICkKfQoKIyBAZGVzY3JpcHRpb24gbG9nIG1lc3NhZ2UgdG8gZmlsZQojIEBhcmcgJDEgbWVzc2FnZTpTdHJpbmcgdGhlIG1lc3NhZ2UgdG8gZGlzcGxheQpMb2c6OmxvZ0ZhdGFsKCkgewogIExvZzo6bG9nTWVzc2FnZSAiJHsyOi1GQVRBTH0iICIkMSIKfQoKIyBAZGVzY3JpcHRpb24gSW50ZXJuYWw6IGNvbW1vbiBsb2cgbWVzc2FnZQojIEBleGFtcGxlIHRleHQKIyAgIFtkYXRlXXxbbGV2ZWxNc2ddfG1lc3NhZ2UKIwojIEBleGFtcGxlIHRleHQKIyAgIDIwMjAtMDEtMTkgMTk6MjA6MjF8RVJST1IgIHxsb2cgZXJyb3IKIyAgIDIwMjAtMDEtMTkgMTk6MjA6MjF8U0tJUFBFRHxsb2cgc2tpcHBlZAojCiMgQGFyZyAkMSBsZXZlbE1zZzpTdHJpbmcgbWVzc2FnZSdzIGxldmVsIGRlc2NyaXB0aW9uIChlZzogU1RBVFVTLCBFUlJPUiwgLi4uKQojIEBhcmcgJDIgbXNnOlN0cmluZyB0aGUgbWVzc2FnZSB0byBkaXNwbGF5CiMgQGVudiBCQVNIX0ZSQU1FV09SS19MT0dfRklMRSBTdHJpbmcgbG9nIGZpbGUgdG8gdXNlLCBkbyBub3RoaW5nIGlmIGVtcHR5CiMgQGVudiBCQVNIX0ZSQU1FV09SS19MT0dfTEVWRUwgaW50IGxvZyBsZXZlbCBsb2cgb25seSBpZiA+IE9GRiBvciBmYXRhbCBtZXNzYWdlcwojIEBzdGRlcnIgZGlhZ25vc3RpY3MgaW5mb3JtYXRpb24gaXMgZGlzcGxheWVkCiMgQHJlcXVpcmUgRW52OjpyZXF1aXJlTG9hZAojIEByZXF1aXJlIExvZzo6cmVxdWlyZUxvYWQKTG9nOjpsb2dNZXNzYWdlKCkgewogIGxvY2FsIGxldmVsTXNnPSIkMSIKICBsb2NhbCBtc2c9IiQyIgogIGxvY2FsIGRhdGUKCiAgaWYgW1sgLW4gIiR7QkFTSF9GUkFNRVdPUktfTE9HX0ZJTEV9IiBdXSAmJiAoKEJBU0hfRlJBTUVXT1JLX0xPR19MRVZFTCA+IF9fTEVWRUxfT0ZGKSk7IHRoZW4KICAgIGRhdGU9IiQoZGF0ZSAnKyVZLSVtLSVkICVIOiVNOiVTJykiCiAgICB0b3VjaCAiJHtCQVNIX0ZSQU1FV09SS19MT0dfRklMRX0iCiAgICBwcmludGYgIiVzfCU3c3wlc1xuIiAiJHtkYXRlfSIgIiR7bGV2ZWxNc2d9IiAiJHttc2d9IiA+PiIke0JBU0hfRlJBTUVXT1JLX0xPR19GSUxFfSIKICBmaQp9CgojIEBkZXNjcmlwdGlvbiBjb25jYXRlbmF0ZSAyIHBhdGhzIGFuZCBlbnN1cmUgdGhlIHBhdGggaXMgY29ycmVjdCB1c2luZyByZWFscGF0aCAtbQojIEBhcmcgJDEgYmFzZVBhdGg6U3RyaW5nCiMgQGFyZyAkMiBzdWJQYXRoOlN0cmluZwojIEByZXF1aXJlIExpbnV4OjpyZXF1aXJlUmVhbHBhdGhDb21tYW5kCkZpbGU6OmNvbmNhdGVuYXRlUGF0aCgpIHsKICBsb2NhbCBiYXNlUGF0aD0iJDEiCiAgbG9jYWwgc3ViUGF0aD0iJDIiCiAgbG9jYWwgZnVsbFBhdGg9IiR7YmFzZVBhdGg6KyR7YmFzZVBhdGh9L30ke3N1YlBhdGh9IgoKICByZWFscGF0aCAtbSAiJHtmdWxsUGF0aH0iIDI+L2Rldi9udWxsCn0KCiMgQGRlc2NyaXB0aW9uIERpc3BsYXkgbWVzc2FnZSB1c2luZyBlcnJvciBjb2xvciAocmVkKQojIEBhcmcgJDEgbWVzc2FnZTpTdHJpbmcgdGhlIG1lc3NhZ2UgdG8gZGlzcGxheQpMb2c6OmRpc3BsYXlFcnJvcigpIHsKICBpZiAoKEJBU0hfRlJBTUVXT1JLX0RJU1BMQVlfTEVWRUwgPj0gX19MRVZFTF9FUlJPUikpOyB0aGVuCiAgICBlY2hvIC1lICIke19fRVJST1JfQ09MT1J9RVJST1IgICAtICR7MX0ke19fUkVTRVRfQ09MT1J9IiA+JjIKICBmaQogIExvZzo6bG9nRXJyb3IgIiQxIgp9CgojIEBkZXNjcmlwdGlvbiBEaXNwbGF5IG1lc3NhZ2UgdXNpbmcgd2FybmluZyBjb2xvciAoeWVsbG93KQojIEBhcmcgJDEgbWVzc2FnZTpTdHJpbmcgdGhlIG1lc3NhZ2UgdG8gZGlzcGxheQpMb2c6OmRpc3BsYXlXYXJuaW5nKCkgewogIGlmICgoQkFTSF9GUkFNRVdPUktfRElTUExBWV9MRVZFTCA+PSBfX0xFVkVMX1dBUk5JTkcpKTsgdGhlbgogICAgZWNobyAtZSAiJHtfX1dBUk5JTkdfQ09MT1J9V0FSTiAgICAtICR7MX0ke19fUkVTRVRfQ09MT1J9IiA+JjIKICBmaQogIExvZzo6bG9nV2FybmluZyAiJDEiCn0KCiMgQGRlc2NyaXB0aW9uIGVuc3VyZSBlbnYgZmlsZXMgYXJlIGxvYWRlZAojIEBub2FyZ3MKIyBAZXhpdGNvZGUgMSBpZiBnZXRPcmRlcmVkQ29uZkZpbGVzIGZhaWxzCiMgQGV4aXRjb2RlIDIgaWYgb25lIG9mIGVudiBmaWxlcyBmYWlscyB0byBsb2FkCiMgQHN0ZGVyciBkaWFnbm9zdGljcyBpbmZvcm1hdGlvbiBpcyBkaXNwbGF5ZWQKRW52OjpyZXF1aXJlTG9hZCgpIHsKICBsb2NhbCBjb25maWdGaWxlc1N0cgogIGNvbmZpZ0ZpbGVzU3RyPSIkKEVudjo6Z2V0T3JkZXJlZENvbmZGaWxlcykiIHx8IHJldHVybiAxCgogIGxvY2FsIC1hIGNvbmZpZ0ZpbGVzCiAgcmVhZGFycmF5IC10IGNvbmZpZ0ZpbGVzIDw8PCIke2NvbmZpZ0ZpbGVzU3RyfSIKCiAgIyBpZiBlbXB0eSBzdHJpbmcsIHRoZXJlIHdpbGwgYmUgb25lIGVsZW1lbnQKICBpZiAoKCR7I2NvbmZpZ0ZpbGVzW0BdfSA9PSAwKSkgfHwgW1sgLXogIiR7Y29uZmlnRmlsZXNTdHJ9IiBdXTsgdGhlbgogICAgIyBzaG91bGQgbm90IGhhcHBlbiwgYXMgdGhlcmUgaXMgYWx3YXlzIGRlZmF1bHQgZmlsZQogICAgTG9nOjpkaXNwbGF5U2tpcHBlZCAibm8gZW52IGZpbGUgdG8gbG9hZCIKICAgIHJldHVybiAwCiAgZmkKCiAgRW52OjptZXJnZUNvbmZGaWxlcyAiJHtjb25maWdGaWxlc1tAXX0iIHx8IHsKICAgIExvZzo6ZGlzcGxheUVycm9yICJ3aGlsZSBsb2FkaW5nIGNvbmZpZyBmaWxlczogJHtjb25maWdGaWxlc1sqXX0iCiAgICByZXR1cm4gMgogIH0KfQoKIyBAZGVzY3JpcHRpb24gYWN0aXZhdGUgb3Igbm90IExvZzo6ZGlzcGxheSogYW5kIExvZzo6bG9nKiBmdW5jdGlvbnMKIyBiYXNlZCBvbiBCQVNIX0ZSQU1FV09SS19ESVNQTEFZX0xFVkVMIGFuZCBCQVNIX0ZSQU1FV09SS19MT0dfTEVWRUwKIyBlbnZpcm9ubWVudCB2YXJpYWJsZXMgbG9hZGVkIGJ5IEVudjo6cmVxdWlyZUxvYWQKIyB0cnkgdG8gY3JlYXRlIGxvZyBmaWxlIGFuZCByb3RhdGUgaXQgaWYgbmVjZXNzYXJ5CiMgQG5vYXJncwojIEBzZXQgQkFTSF9GUkFNRVdPUktfTE9HX0xFVkVMIGludCB0byBPRkYgbGV2ZWwgaWYgQkFTSF9GUkFNRVdPUktfTE9HX0ZJTEUgaXMgZW1wdHkgb3Igbm90IHdyaXRhYmxlCiMgQGVudiBCQVNIX0ZSQU1FV09SS19ESVNQTEFZX0xFVkVMIGludAojIEBlbnYgQkFTSF9GUkFNRVdPUktfTE9HX0xFVkVMIGludAojIEBlbnYgQkFTSF9GUkFNRVdPUktfTE9HX0ZJTEUgU3RyaW5nCiMgQGVudiBCQVNIX0ZSQU1FV09SS19MT0dfRklMRV9NQVhfUk9UQVRJT04gaW50IGRvIGxvZyByb3RhdGlvbiBpZiA+IDAKIyBAZXhpdGNvZGUgMCBhbHdheXMgc3VjY2Vzc2Z1bAojIEBzdGRlcnIgZGlhZ25vc3RpY3MgaW5mb3JtYXRpb24gYWJvdXQgbG9nIGZpbGUgaXMgZGlzcGxheWVkCiMgQHJlcXVpcmUgRW52OjpyZXF1aXJlTG9hZAojIEByZXF1aXJlIFVJOjpyZXF1aXJlVGhlbWUKTG9nOjpyZXF1aXJlTG9hZCgpIHsKICBpZiBbWyAteiAiJHtCQVNIX0ZSQU1FV09SS19MT0dfRklMRTotfSIgXV07IHRoZW4KICAgIEJBU0hfRlJBTUVXT1JLX0xPR19MRVZFTD0ke19fTEVWRUxfT0ZGfQogICAgZXhwb3J0IEJBU0hfRlJBTUVXT1JLX0xPR19MRVZFTAogIGZpCgogIGlmICgoQkFTSF9GUkFNRVdPUktfTE9HX0xFVkVMID4gX19MRVZFTF9PRkYpKTsgdGhlbgogICAgaWYgW1sgISAtZiAiJHtCQVNIX0ZSQU1FV09SS19MT0dfRklMRX0iIF1dOyB0aGVuCiAgICAgIGlmCiAgICAgICAgISBta2RpciAtcCAiJChkaXJuYW1lICIke0JBU0hfRlJBTUVXT1JLX0xPR19GSUxFfSIpIiAyPi9kZXYvbnVsbCB8fAogICAgICAgICAgISB0b3VjaCAtLW5vLWNyZWF0ZSAiJHtCQVNIX0ZSQU1FV09SS19MT0dfRklMRX0iIDI+L2Rldi9udWxsCiAgICAgIHRoZW4KICAgICAgICBCQVNIX0ZSQU1FV09SS19MT0dfTEVWRUw9JHtfX0xFVkVMX09GRn0KICAgICAgICBlY2hvIC1lICIke19fRVJST1JfQ09MT1J9RVJST1IgICAtIEZpbGUgJHtCQVNIX0ZSQU1FV09SS19MT0dfRklMRX0gaXMgbm90IHdyaXRhYmxlJHtfX1JFU0VUX0NPTE9SfSIgPiYyCiAgICAgIGZpCiAgICBlbGlmIFtbICEgLXcgIiR7QkFTSF9GUkFNRVdPUktfTE9HX0ZJTEV9IiBdXTsgdGhlbgogICAgICBCQVNIX0ZSQU1FV09SS19MT0dfTEVWRUw9JHtfX0xFVkVMX09GRn0KICAgICAgZWNobyAtZSAiJHtfX0VSUk9SX0NPTE9SfUVSUk9SICAgLSBGaWxlICR7QkFTSF9GUkFNRVdPUktfTE9HX0ZJTEV9IGlzIG5vdCB3cml0YWJsZSR7X19SRVNFVF9DT0xPUn0iID4mMgogICAgZmkKCiAgZmkKCiAgaWYgKChCQVNIX0ZSQU1FV09SS19MT0dfTEVWRUwgPiBfX0xFVkVMX09GRikpOyB0aGVuCiAgICAjIHdpbGwgYWx3YXlzIGJlIGNyZWF0ZWQgZXZlbiBpZiBub3QgaW4gaW5mbyBsZXZlbAogICAgTG9nOjpsb2dNZXNzYWdlICJJTkZPIiAiTG9nZ2luZyB0byBmaWxlICR7QkFTSF9GUkFNRVdPUktfTE9HX0ZJTEV9IC0gTG9nIGxldmVsICR7QkFTSF9GUkFNRVdPUktfTE9HX0xFVkVMfSIKICAgIGlmICgoQkFTSF9GUkFNRVdPUktfTE9HX0ZJTEVfTUFYX1JPVEFUSU9OID4gMCkpOyB0aGVuCiAgICAgIExvZzo6cm90YXRlICIke0JBU0hfRlJBTUVXT1JLX0xPR19GSUxFfSIgIiR7QkFTSF9GUkFNRVdPUktfTE9HX0ZJTEVfTUFYX1JPVEFUSU9OfSIKICAgIGZpCiAgZmkKfQoKIyBAZGVzY3JpcHRpb24gZ2V0IGxpc3Qgb2YgZW52IGZpbGVzIHRvIGxvYWQKIyBpbiBvcmRlciB0byBtYWtlIHRoZW0gYXZhaWxhYmxlIGZvciBFbnY6OnJlcXVpcmVMb2FkCiMgQGVudiBCQVNIX0ZSQU1FV09SS19FTlZfRklMRVMgU3RyaW5nW10gbGlzdCBvZiBlbnYgZmlsZXMgdGhhdCBzaG91bGQgYmUgbG9hZGVkCiMgQGV4aXRjb2RlIDEgaWYgb25lIG9mIHRoZSBlbnYgZmlsZSBjYW5ub3QgYmUgZ2VuZXJhdGVkCiMgQGV4aXRjb2RlIDIgaWYgb25lIG9mIHRoZSBlbnYgZmlsZSBpcyBub3QgYSBmaWxlIG9yIHJlYWRhYmxlCiMgQHN0ZG91dCB0aGUgZW52IGZpbGVzIGFza2VkIHRvIGJlIGxvYWRlZAojIEBzdGRlcnIgZGlhZ25vc3RpYyBpbmZvcm1hdGlvbiBvbiBmYWlsdXJlCiMgQHNlZSBodHRwczovL2dpdGh1Yi5jb20vZmNoYXN0YW5ldC9iYXNoLXRvb2xzLWZyYW1ld29yay9ibG9iL21hc3Rlci9GcmFtZXdvcmtEb2MubWQjY29uZmlnX2ZpbGVfb3JkZXIKRW52OjpnZXRPcmRlcmVkQ29uZkZpbGVzKCkgewogIGxvY2FsIC1hIGNvbmZpZ0ZpbGVzPSgpCgogIGlmIFtbIC1uICIke0JBU0hfRlJBTUVXT1JLX0VOVl9GSUxFU1swXSsxfSIgXV07IHRoZW4KICAgICMgQkFTSF9GUkFNRVdPUktfRU5WX0ZJTEVTIGlzIGFuIGFycmF5CiAgICBjb25maWdGaWxlcys9KCIke0JBU0hfRlJBTUVXT1JLX0VOVl9GSUxFU1tAXX0iKQogIGZpCgogIGxvY2FsIGRlZmF1bHRFbnZGaWxlCiAgZGVmYXVsdEVudkZpbGU9IiQoRW52OjpjcmVhdGVEZWZhdWx0RW52RmlsZSkiIHx8IHJldHVybiAxCiAgY29uZmlnRmlsZXMrPSgiJHtkZWZhdWx0RW52RmlsZX0iKQoKICBsb2NhbCBmaWxlCiAgZm9yIGZpbGUgaW4gIiR7Y29uZmlnRmlsZXNbQF19IjsgZG8KICAgIGlmIFtbICEgLWYgIiR7ZmlsZX0iIHx8ICEgLXIgIiR7ZmlsZX0iIF1dOyB0aGVuCiAgICAgIExvZzo6ZGlzcGxheUVycm9yICJPbmUgb2YgdGhlIGNvbmZpZyBmaWxlIGlzIG5vdCBhdmFpbGFibGUgJyR7ZmlsZX0nIgogICAgICByZXR1cm4gMgogICAgZmkKICAgIGVjaG8gIiR7ZmlsZX0iCiAgZG9uZQp9CgojIEBkZXNjcmlwdGlvbiBtZXJnZSBhbmQgbG9hZCBjb25mIGZpbGVzIHNwZWNpZmllZCBhcyBhcmd1bWVudAojIC0gZmlsZXMgYXJlIGNsZWFuZWQgZnJvbSBheSBjb21tZW50CiMgLSBtaXNzaW5nIHF1b3RlcyBhZnRlciBwcm9wZXJ0eSA9IHNpZ24gYXJlIGFkZGVkIGF1dG9tYXRpY2FsbHkKIyAtIGF1dG9tYXRpYyByZW1vdmUgb2YgYWxsIHdoaXRlc3BhY2UgYmVmb3JlIGFuZCBhZnRlciBkZWNsYXJhdGlvbnMKIyAtIGJhc2ggYXJyYXlzIGFyZSBub3Qgc3VwcG9ydGVkCiMgLSBpZiBhIHZhcmlhYmxlIGlzIGRlY2xhcmVkIGluIGZpcnN0IGZpbGUgYW5kIG92ZXJyaWRkZW4gbGF0ZXIgb24KIyAgIGluIHRoZSBzYW1lIGZpbGUgb3IgaW4gc3Vic2VxdWVudCBmaWxlcywgdGhvc2Ugb3ZlcmxvYWRzIHdpbGwgYmUKIyAgIGlnbm9yZWQKIyBAd2FybmluZyBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgbG9hZGluZyBvbmUgb2YgdGhlIGNvbmZpZyBmaWxlLCBleGl0IGNvZGUgMyBidXQgZW52aXJvbm1lbnQgY291bGQgYmUgcGFydGlhbGx5IGxvYWRlZAojIEBhcmcgJEAgYXJnczpTdHJpbmdbXSBsaXN0IG9mIGNvbmZpZ3VyYXRpb24gZmlsZXMgdG8gbG9hZCBpbiBvcmRlcgojIEBzZXQgZW52VmFycyBTdHJpbmcgd2lsbCBzZXQgaW4gZW52aXJvbm1lbnQgYWxsIHRoZSB2YXJpYWJsZXMgdGhhdCBoYXZlIGJlZW4gZGVjbGFyZWQgaW4gdGhlIGNvbmZpZyBmaWxlcwojIEBlbnYgZW52VmFycyBTdHJpbmcgdGhlIGVudiB2YXJpYWJsZXMgb2YgdGhlIGN1cnJlbnQgc2NyaXB0IGNvdWxkIGJlIHVzZWQgdG8gaW50ZXJwcmV0IHZhcmlhYmxlcyBkdXJpbmcgY29uZmlnIGZpbGVzIHBhcnNpbmcKIyBAZXhpdGNvZGUgMCBpZiBubyBjb25maWcgZmlsZXMgcHJvdmlkZWQgb3IgbG9hZCBjb21wbGV0ZWQgc3VjY2Vzc2Z1bGx5CiMgQGV4aXRjb2RlIDEgaWYgZXJyb3Igb2NjdXJyZWQgZHVyaW5nIHBhcnNpbmcgdGhlIGNvbmZpZyBmaWxlcyAoZmlsZSBub3QgZm91bmQsIGdyZXAsIGF3ayBvciBzZWQgZXJyb3IpCiMgQGV4aXRjb2RlIDIgaWYgdGVtcG9yYXJ5IGZpbGUgY2Fubm90IGJlIGNyZWF0ZWQKIyBAZXhpdGNvZGUgMyBpZiBhbiBlcnJvciBvY2N1cnJlZCBkdXJpbmcgY29uZmlnIGZpbGUgc291cmNpbmcKIyBAc3RkZXJyIGRpYWdub3N0aWNzIGluZm9ybWF0aW9uIGlzIGRpc3BsYXllZAojIEBzZWUgbGFyZ2VseSBpbnNwaXJlZCBidXQgbW9kaWZpZWQgZnJvbSBodHRwczovL29wZW5zb3VyY2UuY29tL2FydGljbGUvMjEvNS9wcm9jZXNzaW5nLWNvbmZpZ3VyYXRpb24tZmlsZXMtc2hlbGwKRW52OjptZXJnZUNvbmZGaWxlcygpIHsKICBsb2NhbCAtYSBjb25maWdGaWxlTGlzdD0oIiRAIikKCiAgaWYgKCgkeyNjb25maWdGaWxlTGlzdFtAXX0gPT0gMCkpOyB0aGVuCiAgICByZXR1cm4gMAogIGZpCgogIGxvY2FsIGNvbWJpbmVkQ29uZmlnRmlsZQogIGNvbWJpbmVkQ29uZmlnRmlsZT0iJChGcmFtZXdvcms6OmNyZWF0ZVRlbXBGaWxlICJtZXJnZUNvbmZGaWxlcyIpIiB8fCByZXR1cm4gMgoKICAoCiAgICAjIHJlbW92ZXMgYW55IHRyYWlsaW5nIHdoaXRlc3BhY2UgZnJvbSBlYWNoIGZpbGUsIGlmIGFueQogICAgIyB0aGlzIGlzIGFic29sdXRlbHkgcmVxdWlyZWQgd2hlbiBpbXBvcnRpbmcgaW50byBDb25maWdNYXBzCiAgICAjIHB1dCBxdW90ZXMgYXJvdW5kIHZhbHVlcwogICAgc2VkIC1FIC1lICQncy9ccyokLy8gOyAvXiQvZCA7IC9eIy4qJC9kIDsgcy89KFteIlwnXS4qKSQvPSJcXDEiLycgIiR7Y29uZmlnRmlsZUxpc3RbQF19IiB8CiAgICAgICMgcmVtb3ZlIGFsbCBjb21tZW50IGxpbmVzCiAgICAgIEZpbHRlcnM6OmNvbW1lbnRMaW5lcyB8CiAgICAgICMgaXRlcmF0ZXMgb3ZlciBlYWNoIGZpbGUgYW5kIHByaW50cyAoZGVmYXVsdCBhd2sgYmVoYXZpb3IpCiAgICAgICMgZWFjaCB1bmlxdWUgbGluZTsgb25seSB0YWtlcyBmaXJzdCB2YWx1ZSBhbmQgaWdub3JlcyBkdXBsaWNhdGVzCiAgICAgIGF3ayAtRj0gJyFsaW5lWyQxXSsrJwogICkgPiIke2NvbWJpbmVkQ29uZmlnRmlsZX0iIHx8IHJldHVybiAxCgogICMgaGF2ZSB0byBleHBvcnQgZXZlcnl0aGluZywgYW5kIHNvdXJjZSBpdCB0d2ljZToKICAjIDEpIGZpcnN0IHNvdXJjZSBpcyB0byByZWFsaXplIHZhcmlhYmxlcwogICMgMikgc2Vjb25kIHRpbWUgaXMgdG8gcmVhbGl6ZSByZWZlcmVuY2VzCiAgc2V0IC1vIGFsbGV4cG9ydAogICMgc2hlbGxjaGVjayBzb3VyY2U9LmZyYW1ld29yay1jb25maWcKICBzb3VyY2UgIiR7Y29tYmluZWRDb25maWdGaWxlfSIgfHwgcmV0dXJuIDMKICAjIHNoZWxsY2hlY2sgc291cmNlPS5mcmFtZXdvcmstY29uZmlnCiAgc291cmNlICIke2NvbWJpbmVkQ29uZmlnRmlsZX0iIHx8IHJldHVybiAzCiAgc2V0ICtvIGFsbGV4cG9ydAp9CgojIEBkZXNjcmlwdGlvbiBEaXNwbGF5IG1lc3NhZ2UgdXNpbmcgc2tpcCBjb2xvciAoeWVsbG93KQojIEBhcmcgJDEgbWVzc2FnZTpTdHJpbmcgdGhlIG1lc3NhZ2UgdG8gZGlzcGxheQpMb2c6OmRpc3BsYXlTa2lwcGVkKCkgewogIGlmICgoQkFTSF9GUkFNRVdPUktfRElTUExBWV9MRVZFTCA+PSBfX0xFVkVMX0lORk8pKTsgdGhlbgogICAgZWNobyAtZSAiJHtfX1NLSVBQRURfQ09MT1J9U0tJUFBFRCAtICR7MX0ke19fUkVTRVRfQ09MT1J9IiA+JjIKICBmaQogIExvZzo6bG9nU2tpcHBlZCAiJDEiCn0KCiMgQGRlc2NyaXB0aW9uIGxvZyBtZXNzYWdlIHRvIGZpbGUKIyBAYXJnICQxIG1lc3NhZ2U6U3RyaW5nIHRoZSBtZXNzYWdlIHRvIGRpc3BsYXkKTG9nOjpsb2dFcnJvcigpIHsKICBpZiAoKEJBU0hfRlJBTUVXT1JLX0xPR19MRVZFTCA+PSBfX0xFVkVMX0VSUk9SKSk7IHRoZW4KICAgIExvZzo6bG9nTWVzc2FnZSAiJHsyOi1FUlJPUn0iICIkMSIKICBmaQp9CgojIEBkZXNjcmlwdGlvbiBsb2cgbWVzc2FnZSB0byBmaWxlCiMgQGFyZyAkMSBtZXNzYWdlOlN0cmluZyB0aGUgbWVzc2FnZSB0byBkaXNwbGF5CkxvZzo6bG9nV2FybmluZygpIHsKICBpZiAoKEJBU0hfRlJBTUVXT1JLX0xPR19MRVZFTCA+PSBfX0xFVkVMX1dBUk5JTkcpKTsgdGhlbgogICAgTG9nOjpsb2dNZXNzYWdlICIkezI6LVdBUk5JTkd9IiAiJDEiCiAgZmkKfQoKIyBAZGVzY3JpcHRpb24gVG8gYmUgY2FsbGVkIGJlZm9yZSBsb2dnaW5nIGluIHRoZSBsb2cgZmlsZQojIEBhcmcgJDEgZmlsZTpzdHJpbmcgbG9nIGZpbGUgbmFtZQojIEBhcmcgJDIgbWF4TG9nRmlsZXNDb3VudDppbnQgbWF4aW11bSBudW1iZXIgb2YgbG9nIGZpbGVzCkxvZzo6cm90YXRlKCkgewogIGxvY2FsIGZpbGU9IiQxIgogIGxvY2FsIG1heExvZ0ZpbGVzQ291bnQ9IiR7MjotNX0iCgogIGlmIFtbICEgLWYgIiR7ZmlsZX0iIF1dOyB0aGVuCiAgICBMb2c6OmRpc3BsYXlTa2lwcGVkICJMb2cgZmlsZSAke2ZpbGV9IGRvZXNuJ3QgZXhpc3QgeWV0IgogICAgcmV0dXJuIDAKICBmaQogIGZvciBpIGluICQoc2VxICQoKG1heExvZ0ZpbGVzQ291bnQgLSAxKSkgLTEgMSk7IGRvCiAgICBMb2c6OmRpc3BsYXlJbmZvICJMb2cgcm90YXRpb24gJHtmaWxlfS4ke2l9IHRvICR7ZmlsZX0uJCgoaSArIDEpKSIKICAgIG12ICIke2ZpbGV9LiJ7IiR7aX0iLCIkKChpICsgMSkpIn0gJj4vZGV2L251bGwgfHwgdHJ1ZQogIGRvbmUKICBpZiBjcCAiJHtmaWxlfSIgIiR7ZmlsZX0uMSIgJj4vZGV2L251bGw7IHRoZW4KICAgIGVjaG8gPiIke2ZpbGV9IiAjIHJlc2V0IGxvZyBmaWxlCiAgICBMb2c6OmRpc3BsYXlJbmZvICJMb2cgcm90YXRpb24gJHtmaWxlfSB0byAke2ZpbGV9LjEiCiAgZmkKfQoKIyBAZGVzY3JpcHRpb24gZW5zdXJlIGNvbW1hbmQgcmVhbHBhdGggaXMgYXZhaWxhYmxlCiMgQGV4aXRjb2RlIDEgaWYgcmVhbHBhdGggY29tbWFuZCBub3QgYXZhaWxhYmxlCiMgQHN0ZGVyciBkaWFnbm9zdGljcyBpbmZvcm1hdGlvbiBpcyBkaXNwbGF5ZWQKTGludXg6OnJlcXVpcmVSZWFscGF0aENvbW1hbmQoKSB7CiAgQXNzZXJ0Ojpjb21tYW5kRXhpc3RzIHJlYWxwYXRoCn0KCiMgQGRlc2NyaXB0aW9uIGxvYWQgY29sb3IgdGhlbWUKIyBAbm9hcmdzCiMgQGVudiBCQVNIX0ZSQU1FV09SS19USEVNRSBTdHJpbmcgdGhlbWUgdG8gdXNlCiMgQGV4aXRjb2RlIDAgYWx3YXlzIHN1Y2Nlc3NmdWwKVUk6OnJlcXVpcmVUaGVtZSgpIHsKICBVSTo6dGhlbWUgIiR7QkFTSF9GUkFNRVdPUktfVEhFTUUtZGVmYXVsdH0iCn0KCiMgQGRlc2NyaXB0aW9uIGNoZWNrIGlmIGNvbW1hbmQgc3BlY2lmaWVkIGV4aXN0cyBvciByZXR1cm4gMQojIHdpdGggZXJyb3IgYW5kIG1lc3NhZ2UgaWYgbm90CiMKIyBAYXJnICQxIGNvbW1hbmROYW1lOlN0cmluZyBvbiB3aGljaCBleGlzdGVuY2UgbXVzdCBiZSBjaGVja2VkCiMgQGFyZyAkMiBoZWxwSWZOb3RFeGlzdHM6U3RyaW5nIGEgaGVscCBjb21tYW5kIHRvIGRpc3BsYXkgaWYgdGhlIGNvbW1hbmQgZG9lcyBub3QgZXhpc3QKIwojIEBleGl0Y29kZSAxIGlmIHRoZSBjb21tYW5kIHNwZWNpZmllZCBkb2VzIG5vdCBleGlzdAojIEBzdGRlcnIgZGlhZ25vc3RpYyBpbmZvcm1hdGlvbiArIGhlbHAgaWYgc2Vjb25kIGFyZ3VtZW50IGlzIHByb3ZpZGVkCkFzc2VydDo6Y29tbWFuZEV4aXN0cygpIHsKICBsb2NhbCBjb21tYW5kTmFtZT0iJDEiCiAgbG9jYWwgaGVscElmTm90RXhpc3RzPSIkMiIKCiAgIiR7QkFTSF9GUkFNRVdPUktfQ09NTUFORDotY29tbWFuZH0iIC12ICIke2NvbW1hbmROYW1lfSIgPi9kZXYvbnVsbCAyPi9kZXYvbnVsbCB8fCB7CiAgICBMb2c6OmRpc3BsYXlFcnJvciAiJHtjb21tYW5kTmFtZX0gaXMgbm90IGluc3RhbGxlZCwgcGxlYXNlIGluc3RhbGwgaXQiCiAgICBpZiBbWyAtbiAiJHtoZWxwSWZOb3RFeGlzdHN9IiBdXTsgdGhlbgogICAgICBMb2c6OmRpc3BsYXlJbmZvICIke2hlbHBJZk5vdEV4aXN0c30iCiAgICBmaQogICAgcmV0dXJuIDEKICB9CiAgcmV0dXJuIDAKfQoKIyBAZGVzY3JpcHRpb24gZGVmYXVsdCBlbnYgZmlsZSB3aXRoIGFsbCBkZWZhdWx0IHZhbHVlcwojIEBzdGRvdXQgdGhlIGRlZmF1bHQgZW52IGZpbGVwYXRoCkVudjo6Y3JlYXRlRGVmYXVsdEVudkZpbGUoKSB7CiAgbG9jYWwgZW52RmlsZQogIGVudkZpbGU9IiQoRnJhbWV3b3JrOjpjcmVhdGVUZW1wRmlsZSAiY3JlYXRlRGVmYXVsdEVudkZpbGVFbnZGaWxlIikiIHx8IHJldHVybiAyCgogICgKICAgIGVjaG8gIkJBU0hfRlJBTUVXT1JLX1RIRU1FPSR7QkFTSF9GUkFNRVdPUktfVEhFTUU6LWRlZmF1bHR9IgogICAgZWNobyAiQkFTSF9GUkFNRVdPUktfTE9HX0xFVkVMPSR7QkFTSF9GUkFNRVdPUktfTE9HX0xFVkVMOi0wfSIKICAgIGVjaG8gIkJBU0hfRlJBTUVXT1JLX0RJU1BMQVlfTEVWRUw9JHtCQVNIX0ZSQU1FV09SS19ESVNQTEFZX0xFVkVMOi0ke19fTEVWRUxfV0FSTklOR319IgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDE2CiAgICBlY2hvICdCQVNIX0ZSQU1FV09SS19MT0dfRklMRT0iJHtCQVNIX0ZSQU1FV09SS19MT0dfRklMRTotIiR7RlJBTUVXT1JLX1JPT1RfRElSfS9sb2dzLyR7U0NSSVBUX05BTUV9LmxvZyJ9IicKICAgIGVjaG8gIkJBU0hfRlJBTUVXT1JLX0xPR19GSUxFX01BWF9ST1RBVElPTj0ke0JBU0hfRlJBTUVXT1JLX0xPR19GSUxFX01BWF9ST1RBVElPTjotNX0iCiAgKSA+IiR7ZW52RmlsZX0iCiAgZWNobyAiJHtlbnZGaWxlfSIKfQoKIyBAZGVzY3JpcHRpb24gcmVtb3ZlIGNvbW1lbnQgbGluZXMgZnJvbSBpbnB1dCBvciBmaWxlcyBwcm92aWRlZCBhcyBhcmd1bWVudHMKIyBAYXJnICRAIGZpbGVzOlN0cmluZ1tdIChvcHRpb25hbCkgdGhlIGZpbGVzIHRvIGZpbHRlcgojIEBlbnYgY29tbWVudExpbmVQcmVmaXggU3RyaW5nIHRoZSBjb21tZW50IGxpbmUgcHJlZml4IChkZWZhdWx0IHZhbHVlOiAjKQojIEBleGl0Y29kZSAwIGlmIGxpbmVzIGZpbHRlcmVkIG9yIG5vdAojIEBleGl0Y29kZSAyIGlmIGdyZXAgZmFpbHMgZm9yIGFueSBvdGhlciByZWFzb25zIHRoYW4gbm90IGZvdW5kCiMgQHN0ZGluIHRoZSBmaWxlIGFzIHN0ZGluIHRvIGZpbHRlciAoYWx0ZXJuYXRpdmUgdG8gZmlsZXMgYXJndW1lbnQpCiMgQHN0ZG91dCB0aGUgZmlsdGVyZWQgbGluZXMKIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMTIwCkZpbHRlcnM6OmNvbW1lbnRMaW5lcygpIHsKICBncmVwIC12eEUgIltbOmJsYW5rOl1dKigke2NvbW1lbnRMaW5lUHJlZml4Oi0jfS4qKT8iICIkQCIgfHwgdGVzdCAkPyA9IDEKfQoKIyBAZGVzY3JpcHRpb24gY3JlYXRlIGEgdGVtcCBmaWxlIHVzaW5nIGRlZmF1bHQgVE1QRElSIHZhcmlhYmxlCiMgaW5pdGlhbGl6ZWQgaW4gX2luY2x1ZGVzL19jb21tb25IZWFkZXIuc2gKIyBAZW52IFRNUERJUiBTdHJpbmcgKGRlZmF1bHQgdmFsdWUgL3RtcCkKIyBAYXJnICQxIHRlbXBsYXRlTmFtZTpTdHJpbmcgdGVtcGxhdGUgbmFtZSB0byB1c2Uob3B0aW9uYWwpCkZyYW1ld29yazo6Y3JlYXRlVGVtcEZpbGUoKSB7CiAgbWt0ZW1wIC1wICIke1RNUERJUjotL3RtcH0iIC10ICIkezE6LX0uWFhYWFhYWFhYWFhYIgp9CgojIEBkZXNjcmlwdGlvbiBsb2cgbWVzc2FnZSB0byBmaWxlCiMgQGFyZyAkMSBtZXNzYWdlOlN0cmluZyB0aGUgbWVzc2FnZSB0byBkaXNwbGF5CkxvZzo6bG9nU2tpcHBlZCgpIHsKICBpZiAoKEJBU0hfRlJBTUVXT1JLX0xPR19MRVZFTCA+PSBfX0xFVkVMX0lORk8pKTsgdGhlbgogICAgTG9nOjpsb2dNZXNzYWdlICIkezI6LVNLSVBQRUR9IiAiJDEiCiAgZmkKfQoKIyBAZGVzY3JpcHRpb24gbG9hZCBjb2xvcnMgdGhlbWUgY29uc3RhbnRzCiMgQHdhcm5pbmcgaWYgdHR5IG5vdCBvcGVuZWQsIG5vQ29sb3IgdGhlbWUgd2lsbCBiZSBjaG9zZW4KIyBAYXJnICQxIHRoZW1lOlN0cmluZyB0aGUgdGhlbWUgdG8gdXNlIChkZWZhdWx0LCBub0NvbG9yKQojIEBhcmcgJEAgYXJnczpTdHJpbmdbXQojIEBzZXQgX19FUlJPUl9DT0xPUiBTdHJpbmcgaW5kaWNhdGUgZXJyb3Igc3RhdHVzCiMgQHNldCBfX0lORk9fQ09MT1IgU3RyaW5nIGluZGljYXRlIGluZm8gc3RhdHVzCiMgQHNldCBfX1NVQ0NFU1NfQ09MT1IgU3RyaW5nIGluZGljYXRlIHN1Y2Nlc3Mgc3RhdHVzCiMgQHNldCBfX1dBUk5JTkdfQ09MT1IgU3RyaW5nIGluZGljYXRlIHdhcm5pbmcgc3RhdHVzCiMgQHNldCBfX1NLSVBQRURfQ09MT1IgU3RyaW5nIGluZGljYXRlIHNraXBwZWQgc3RhdHVzCiMgQHNldCBfX0RFQlVHX0NPTE9SIFN0cmluZyBpbmRpY2F0ZSBkZWJ1ZyBzdGF0dXMKIyBAc2V0IF9fSEVMUF9DT0xPUiBTdHJpbmcgaW5kaWNhdGUgaGVscCBzdGF0dXMKIyBAc2V0IF9fVEVTVF9DT0xPUiBTdHJpbmcgbm90IHVzZWQKIyBAc2V0IF9fVEVTVF9FUlJPUl9DT0xPUiBTdHJpbmcgbm90IHVzZWQKIyBAc2V0IF9fSEVMUF9USVRMRV9DT0xPUiBTdHJpbmcgdXNlZCB0byBkaXNwbGF5IGhlbHAgdGl0bGUgaW4gaGVscCBzdHJpbmdzCiMgQHNldCBfX0hFTFBfT1BUSU9OX0NPTE9SIFN0cmluZyB1c2VkIHRvIGRpc3BsYXkgaGlnaGxpZ2h0IG9wdGlvbnMgaW4gaGVscCBzdHJpbmdzCiMKIyBAc2V0IF9fUkVTRVRfQ09MT1IgU3RyaW5nIHJlc2V0IGRlZmF1bHQgY29sb3IKIwojIEBzZXQgX19IRUxQX0VYQU1QTEUgU3RyaW5nIHRvIHJlbW92ZQojIEBzZXQgX19IRUxQX1RJVExFIFN0cmluZyB0byByZW1vdmUKIyBAc2V0IF9fSEVMUF9OT1JNQUwgU3RyaW5nIHRvIHJlbW92ZQojIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKVUk6OnRoZW1lKCkgewogIGxvY2FsIHRoZW1lPSIkezEtZGVmYXVsdH0iCiAgaWYgW1sgISAiJHt0aGVtZX0iID1+IC1mb3JjZSQgXV0gJiYgISBBc3NlcnQ6OnR0eTsgdGhlbgogICAgdGhlbWU9Im5vQ29sb3IiCiAgZmkKICBjYXNlICIke3RoZW1lfSIgaW4KICAgIGRlZmF1bHQgfCBkZWZhdWx0LWZvcmNlKQogICAgICB0aGVtZT0iZGVmYXVsdCIKICAgICAgOzsKICAgIG5vQ29sb3IpIDs7CiAgICAqKQogICAgICBMb2c6OmZhdGFsICJpbnZhbGlkIHRoZW1lIHByb3ZpZGVkIgogICAgICA7OwogIGVzYWMKICBpZiBbWyAiJHt0aGVtZX0iID0gImRlZmF1bHQiIF1dOyB0aGVuCiAgICBCQVNIX0ZSQU1FV09SS19USEVNRT0iZGVmYXVsdCIKICAgICMgY2hlY2sgY29sb3JzIGFwcGxpY2FibGUgaHR0cHM6Ly9taXNjLmZsb2dpc29mdC5jb20vYmFzaC90aXBfY29sb3JzX2FuZF9mb3JtYXR0aW5nCiAgICBfX0VSUk9SX0NPTE9SPSdcZVszMW0nICAgICAgICAgIyBSZWQKICAgIF9fSU5GT19DT0xPUj0nXGVbNDRtJyAgICAgICAgICAjIHdoaXRlIG9uIGxpZ2h0Qmx1ZQogICAgX19TVUNDRVNTX0NPTE9SPSdcZVszMm0nICAgICAgICMgR3JlZW4KICAgIF9fV0FSTklOR19DT0xPUj0nXGVbMzNtJyAgICAgICAjIFllbGxvdwogICAgX19TS0lQUEVEX0NPTE9SPSdcZVszM20nICAgICAgICMgWWVsbG93CiAgICBfX0RFQlVHX0NPTE9SPSdcZVszN20nICAgICAgICAgIyBHcmV5CiAgICBfX0hFTFBfQ09MT1I9J1xlWzc7NDk7MzNtJyAgICAgIyBCbGFjayBvbiBHb2xkCiAgICBfX1RFU1RfQ09MT1I9J1xlWzEwMG0nICAgICAgICAgIyBMaWdodCBtYWdlbnRhCiAgICBfX1RFU1RfRVJST1JfQ09MT1I9J1xlWzQxbScgICAgIyB3aGl0ZSBvbiByZWQKICAgIF9fSEVMUF9USVRMRV9DT0xPUj0iXGVbMTszN20iICAjIEJvbGQKICAgIF9fSEVMUF9PUFRJT05fQ09MT1I9IlxlWzE7MzRtIiAjIEJsdWUKICAgICMgSW50ZXJuYWw6IHJlc2V0IGNvbG9yCiAgICBfX1JFU0VUX0NPTE9SPSdcZVswbScgIyBSZXNldCBDb2xvcgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMTU1LFNDMjAzNAogICAgX19IRUxQX0VYQU1QTEU9IiQoZWNobyAtZSAiXGVbMjs5N20iKSIKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjE1NSxTQzIwMzQKICAgIF9fSEVMUF9USVRMRT0iJChlY2hvIC1lICJcZVsxOzM3bSIpIgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMTU1LFNDMjAzNAogICAgX19IRUxQX05PUk1BTD0iJChlY2hvIC1lICJcMDMzWzBtIikiCiAgZWxzZQogICAgQkFTSF9GUkFNRVdPUktfVEhFTUU9Im5vQ29sb3IiCiAgICAjIGNoZWNrIGNvbG9ycyBhcHBsaWNhYmxlIGh0dHBzOi8vbWlzYy5mbG9naXNvZnQuY29tL2Jhc2gvdGlwX2NvbG9yc19hbmRfZm9ybWF0dGluZwogICAgX19FUlJPUl9DT0xPUj0nJwogICAgX19JTkZPX0NPTE9SPScnCiAgICBfX1NVQ0NFU1NfQ09MT1I9JycKICAgIF9fV0FSTklOR19DT0xPUj0nJwogICAgX19TS0lQUEVEX0NPTE9SPScnCiAgICBfX0RFQlVHX0NPTE9SPScnCiAgICBfX0hFTFBfQ09MT1I9JycKICAgIF9fVEVTVF9DT0xPUj0nJwogICAgX19URVNUX0VSUk9SX0NPTE9SPScnCiAgICBfX0hFTFBfVElUTEVfQ09MT1I9JycKICAgIF9fSEVMUF9PUFRJT05fQ09MT1I9JycKICAgICMgSW50ZXJuYWw6IHJlc2V0IGNvbG9yCiAgICBfX1JFU0VUX0NPTE9SPScnCiAgICBfX0hFTFBfRVhBTVBMRT0nJwogICAgX19IRUxQX1RJVExFPScnCiAgICBfX0hFTFBfTk9STUFMPScnCiAgZmkKfQoKIyBAZGVzY3JpcHRpb24gY2hlY2sgaWYgdHR5IChpbnRlcmFjdGl2ZSBtb2RlKSBpcyBhY3RpdmUKIyBAbm9hcmdzCiMgQGV4aXRjb2RlIDEgaWYgdHR5IG5vdCBhY3RpdmUKIyBAZW52IE5PTl9JTlRFUkFDVElWRSBpZiAxIGNvbnNpZGVyIGFzIG5vdCBpbnRlcmFjdGl2ZSBldmVuIGlmIGVudmlyb25tZW50IGlzIGludGVyYWN0aXZlCiMgQGVudiBJTlRFUkFDVElWRSBpZiAxIGNvbnNpZGVyIGFzIGludGVyYWN0aXZlIGV2ZW4gaWYgZW52aXJvbm1lbnQgaXMgbm90IGludGVyYWN0aXZlCiMgQHN0ZGVyciBkaWFnbm9zdGljIGluZm9ybWF0aW9uICsgaGVscCBpZiBzZWNvbmQgYXJndW1lbnQgaXMgcHJvdmlkZWQKQXNzZXJ0Ojp0dHkoKSB7CiAgaWYgW1sgIiR7Tk9OX0lOVEVSQUNUSVZFOi0wfSIgPSAiMSIgXV07IHRoZW4KICAgIHJldHVybiAxCiAgZmkKICBpZiBbWyAiJHtJTlRFUkFDVElWRTotMH0iID0gIjEiIF1dOyB0aGVuCiAgICByZXR1cm4gMAogIGZpCiAgW1sgLXQgMSB8fCAtdCAyIF1dCn0KCiMgRlVOQ1RJT05TCgpmYWNhZGVfbWFpbl9hMTc1Yjg1MjczNjg0ZjBkODkxMGQxNmQ2ZDgwY2FmZigpIHsKIyBSRVFVSVJFUwpMaW51eDo6cmVxdWlyZUV4ZWN1dGVkQXNVc2VyCkVudjo6cmVxdWlyZUxvYWQKTG9nOjpyZXF1aXJlTG9hZApMaW51eDo6cmVxdWlyZVJlYWxwYXRoQ29tbWFuZApVSTo6cmVxdWlyZVRoZW1lCkNvbXBpbGVyOjpGYWNhZGU6OnJlcXVpcmVDb21tYW5kQmluRGlyCgojIEByZXF1aXJlIENvbXBpbGVyOjpGYWNhZGU6OnJlcXVpcmVDb21tYW5kQmluRGlyCgojIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIxNTQsU0MyMDE2CmZ1bmN0aW9uVG9DYWxsPSdEYjo6cXVlcnlPbmVEYXRhYmFzZScKIiR7ZnVuY3Rpb25Ub0NhbGx9IiAiJEAiCgp9CgpmYWNhZGVfbWFpbl9hMTc1Yjg1MjczNjg0ZjBkODkxMGQxNmQ2ZDgwY2FmZiAiJEAiCg==" +declare -gx embed_function_DbQueryOneDatabase="${PERSISTENT_TMPDIR:-/tmp}/bin/370dab633b77b22851fe46e08d43de97/dbQueryOneDatabase" +declare -gx encoded_binary_file_DbQueryOneDatabase="IyEvdXNyL2Jpbi9lbnYgYmFzaAojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCiMgR0VORVJBVEVEIEZBQ0FERSBGUk9NIGh0dHBzOi8vZ2l0aHViLmNvbS9mY2hhc3RhbmV0L2Jhc2gtdG9vbHMvdHJlZS9tYXN0ZXIvLi4vYmFzaC1kZXYtZW52L3ZlbmRvci9iYXNoLXRvb2xzLWZyYW1ld29yay9zcmMvQ29tcGlsZXIvRW1iZWQvZW1iZWRGcmFtZXdvcmtGdW5jdGlvbi5iaW5GaWxlLnRwbAojIERPIE5PVCBFRElUIElUCiMgQGdlbmVyYXRlZAojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCiMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjI4OCxTQzIwMzQKIyBCSU5fRklMRT0ke0JJTl9GSUxFfQojIEZBQ0FERQoKIyBlbnN1cmUgdGhhdCBubyB1c2VyIGFsaWFzZXMgY291bGQgaW50ZXJmZXJlIHdpdGgKIyBjb21tYW5kcyB1c2VkIGluIHRoaXMgc2NyaXB0CnVuYWxpYXMgLWEgfHwgdHJ1ZQpzaG9wdCAtdSBleHBhbmRfYWxpYXNlcwoKIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CigoZmFpbHVyZXMgPSAwKSkgfHwgdHJ1ZQoKIyBCYXNoIHdpbGwgcmVtZW1iZXIgJiByZXR1cm4gdGhlIGhpZ2hlc3QgZXhpdCBjb2RlIGluIGEgY2hhaW4gb2YgcGlwZXMuCiMgVGhpcyB3YXkgeW91IGNhbiBjYXRjaCB0aGUgZXJyb3IgaW5zaWRlIHBpcGVzLCBlLmcuIG15c3FsZHVtcCB8IGd6aXAKc2V0IC1vIHBpcGVmYWlsCnNldCAtbyBlcnJleGl0CgojIENvbW1hbmQgU3Vic3RpdHV0aW9uIGNhbiBpbmhlcml0IGVycmV4aXQgb3B0aW9uIHNpbmNlIGJhc2ggdjQuNApzaG9wdCAtcyBpbmhlcml0X2VycmV4aXQgfHwgdHJ1ZQoKIyBhIGxvZyBpcyBnZW5lcmF0ZWQgd2hlbiBhIGNvbW1hbmQgZmFpbHMKc2V0IC1vIGVycnRyYWNlCgojIHVzZSBudWxsZ2xvYiBzbyB0aGF0IChmaWxlKi5waHApIHdpbGwgcmV0dXJuIGFuIGVtcHR5IGFycmF5IGlmIG5vIGZpbGUgbWF0Y2hlcyB0aGUgd2lsZGNhcmQKc2hvcHQgLXMgbnVsbGdsb2IKCiMgZW5zdXJlIHJlZ2V4cCBhcmUgaW50ZXJwcmV0ZWQgd2l0aG91dCBhY2NlbnR1YXRlZCBjaGFyYWN0ZXJzCmV4cG9ydCBMQ19BTEw9UE9TSVgKCmV4cG9ydCBURVJNPXh0ZXJtLTI1NmNvbG9yCgojIGF2b2lkIGludGVyYWN0aXZlIGluc3RhbGwKZXhwb3J0IERFQklBTl9GUk9OVEVORD1ub25pbnRlcmFjdGl2ZQpleHBvcnQgREVCQ09ORl9OT05JTlRFUkFDVElWRV9TRUVOPXRydWUKCiMgc3RvcmUgY29tbWFuZCBhcmd1bWVudHMgZm9yIGxhdGVyIHVzYWdlCiMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNApkZWNsYXJlIC1hIEJBU0hfRlJBTUVXT1JLX0FSR1Y9KCIkQCIpCiMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNApkZWNsYXJlIC1hIE9SSUdJTkFMX0JBU0hfRlJBTUVXT1JLX0FSR1Y9KCIkQCIpCgojIEBzZWUgaHR0cHM6Ly91bml4LnN0YWNrZXhjaGFuZ2UuY29tL2EvMzg2ODU2CiMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjMxNwppbnRlcnJ1cHRNYW5hZ2VtZW50KCkgewogICMgcmVzdG9yZSBTSUdJTlQgaGFuZGxlcgogIHRyYXAgLSBJTlQKICAjIGVuc3VyZSB0aGF0IEN0cmwtQyBpcyB0cmFwcGVkIGJ5IHRoaXMgc2NyaXB0IGFuZCBub3QgYnkgc3ViIHByb2Nlc3MKICAjIHJlcG9ydCB0byB0aGUgcGFyZW50IHRoYXQgd2UgaGF2ZSBpbmRlZWQgYmVlbiBpbnRlcnJ1cHRlZAogIGtpbGwgLXMgSU5UICIkJCIKfQp0cmFwIGludGVycnVwdE1hbmFnZW1lbnQgSU5UClNDUklQVF9OQU1FPSR7MCMjKi99ClJFQUxfU0NSSVBUX0ZJTEU9IiQocmVhZGxpbmsgLWUgIiQocmVhbHBhdGggIiR7QkFTSF9TT1VSQ0VbMF19IikiKSIKQ1VSUkVOVF9ESVI9IiQoY2QgIiQocmVhZGxpbmsgLWUgIiR7UkVBTF9TQ1JJUFRfRklMRSUvKn0iKSIgJiYgcHdkIC1QKSIKCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwojIFRlbXAgZGlyIG1hbmFnZW1lbnQKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCgpLRUVQX1RFTVBfRklMRVM9IiR7S0VFUF9URU1QX0ZJTEVTOi0wfSIKZXhwb3J0IEtFRVBfVEVNUF9GSUxFUwoKIyBQRVJTSVNURU5UX1RNUERJUiBpcyBub3QgZGVsZXRlZCBieSB0cmFwcwpQRVJTSVNURU5UX1RNUERJUj0iJHtUTVBESVI6LS90bXB9L2Jhc2gtZnJhbWV3b3JrIgpleHBvcnQgUEVSU0lTVEVOVF9UTVBESVIKbWtkaXIgLXAgIiR7UEVSU0lTVEVOVF9UTVBESVJ9IgoKIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0ClRNUERJUj0iJChta3RlbXAgLWQgLXAgIiR7UEVSU0lTVEVOVF9UTVBESVI6LS90bXB9IiAtdCBiYXNoLWZyYW1ld29yay0kJC1YWFhYWFgpIgpleHBvcnQgVE1QRElSCgojIHRlbXAgZGlyIGNsZWFuaW5nCiMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjMxNwpjbGVhbk9uRXhpdCgpIHsKICBpZiBbWyAiJHtLRUVQX1RFTVBfRklMRVM6LTB9IiA9ICIxIiBdXTsgdGhlbgogICAgTG9nOjpkaXNwbGF5SW5mbyAiS0VFUF9URU1QX0ZJTEVTPTEgdGVtcCBmaWxlcyBrZXB0IGhlcmUgJyR7VE1QRElSfSciCiAgZWxpZiBbWyAtbiAiJHtUTVBESVIreHh4fSIgXV07IHRoZW4KICAgIExvZzo6ZGlzcGxheURlYnVnICJLRUVQX1RFTVBfRklMRVM9MCByZW1vdmluZyB0ZW1wIGZpbGVzICcke1RNUERJUn0nIgogICAgcm0gLVJmICIke1RNUERJUjotL3RtcC9mYWtlfSIgPi9kZXYvbnVsbCAyPiYxCiAgZmkKfQp0cmFwIGNsZWFuT25FeGl0IEVYSVQgSFVQIFFVSVQgQUJSVCBURVJNCgojIFZBUl9NQUlOX0ZVTkNUSU9OX1ZBUl9OQU1FPWRiUXVlcnlBbGxEYXRhYmFzZXNGYWNhZGUKCiMgQGRlc2NyaXB0aW9uIHVzZWQgdG8gZXhlY3V0ZSBnaXZlbiBxdWVyeSB3aGVuIHVzaW5nCiMgZGJTY3JpcHRBbGxEYXRhYmFzZXMKIyBAYXJnICQxIGRzbjpTdHJpbmcKIyBAYXJnICQyIGRiOlN0cmluZwojIEBlbnYgcXVlcnkgU3RyaW5nCiMgQGVudiBvcHRpb25TZXBhcmF0b3IgU3RyaW5nCiMgQHJlcXVpcmUgTGludXg6OnJlcXVpcmVFeGVjdXRlZEFzVXNlcgpEYjo6cXVlcnlPbmVEYXRhYmFzZSgpIHsKICAjIHF1ZXJ5IGFuZCBvcHRpb25TZXBhcmF0b3IgYXJlIHBhc3NlZCB2aWEgZXhwb3J0CiAgbG9jYWwgZHNuPSIkMSIKICBsb2NhbCBkYj0iJDIiCgogIGxvY2FsIC1BIGRiSW5zdGFuY2UKICBEYXRhYmFzZTo6bmV3SW5zdGFuY2UgZGJJbnN0YW5jZSAiJHtkc259IgogIERhdGFiYXNlOjpzZXRRdWVyeU9wdGlvbnMgZGJJbnN0YW5jZSAiJHtkYkluc3RhbmNlW1FVRVJZX09QVElPTlNdfSAtLWNvbm5lY3QtdGltZW91dD01IgoKICAjIGlkZW50aWZ5IGNvbHVtbnMgaGVhZGVyCiAgZWNobyAtbiAiQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAiCiAgRGF0YWJhc2U6OnNraXBDb2x1bW5OYW1lcyBkYkluc3RhbmNlIDAKCiAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMTU0CiAgaWYgISBEYXRhYmFzZTo6cXVlcnkgZGJJbnN0YW5jZSAiJHtxdWVyeX0iICIke2RifSIgfCBzZWQgInMvXHQvJHtvcHRpb25TZXBhcmF0b3J9L2ciOyB0aGVuCiAgICBMb2c6OmZhdGFsICJkYXRhYmFzZSAke2RifSBlcnJvciIgMT4mMgogIGZpCn0KCiMgQGRlc2NyaXB0aW9uIExvZyBuYW1lc3BhY2UgcHJvdmlkZXMgMiBraW5kIG9mIGZ1bmN0aW9ucwojIC0gTG9nOjpkaXNwbGF5KiBhbGxvd3MgdG8gZGlzcGxheSBnaXZlbiBtZXNzYWdlIHdpdGgKIyAgIGdpdmVuIGRpc3BsYXkgbGV2ZWwKIyAtIExvZzo6bG9nKiBhbGxvd3MgdG8gbG9nIGdpdmVuIG1lc3NhZ2Ugd2l0aAojICAgZ2l2ZW4gbG9nIGxldmVsCiMgTG9nOjpkaXNwbGF5KiBmdW5jdGlvbnMgYXV0b21hdGljYWxseSBsb2cgdGhlIG1lc3NhZ2UgdG9vCiMgQHNlZSBFbnY6OnJlcXVpcmVMb2FkIHRvIGxvYWQgdGhlIGRpc3BsYXkgYW5kIGxvZyBsZXZlbCBmcm9tIC5lbnYgZmlsZQoKIyBAZGVzY3JpcHRpb24gbG9nIGxldmVsIG9mZgpleHBvcnQgX19MRVZFTF9PRkY9MAojIEBkZXNjcmlwdGlvbiBsb2cgbGV2ZWwgZXJyb3IKZXhwb3J0IF9fTEVWRUxfRVJST1I9MQojIEBkZXNjcmlwdGlvbiBsb2cgbGV2ZWwgd2FybmluZwpleHBvcnQgX19MRVZFTF9XQVJOSU5HPTIKIyBAZGVzY3JpcHRpb24gbG9nIGxldmVsIGluZm8KZXhwb3J0IF9fTEVWRUxfSU5GTz0zCiMgQGRlc2NyaXB0aW9uIGxvZyBsZXZlbCBzdWNjZXNzCmV4cG9ydCBfX0xFVkVMX1NVQ0NFU1M9MwojIEBkZXNjcmlwdGlvbiBsb2cgbGV2ZWwgZGVidWcKZXhwb3J0IF9fTEVWRUxfREVCVUc9NAoKIyBAZGVzY3JpcHRpb24gdmVyYm9zZSBsZXZlbCBvZmYKZXhwb3J0IF9fVkVSQk9TRV9MRVZFTF9PRkY9MAojIEBkZXNjcmlwdGlvbiB2ZXJib3NlIGxldmVsIGluZm8KZXhwb3J0IF9fVkVSQk9TRV9MRVZFTF9JTkZPPTEKIyBAZGVzY3JpcHRpb24gdmVyYm9zZSBsZXZlbCBpbmZvCmV4cG9ydCBfX1ZFUkJPU0VfTEVWRUxfREVCVUc9MgojIEBkZXNjcmlwdGlvbiB2ZXJib3NlIGxldmVsIGluZm8KZXhwb3J0IF9fVkVSQk9TRV9MRVZFTF9UUkFDRT0zCgojIEBkZXNjcmlwdGlvbiBEaXNwbGF5IG1lc3NhZ2UgdXNpbmcgZGVidWcgY29sb3IgKGdyZXkpCiMgQGFyZyAkMSBtZXNzYWdlOlN0cmluZyB0aGUgbWVzc2FnZSB0byBkaXNwbGF5CkxvZzo6ZGlzcGxheURlYnVnKCkgewogIGlmICgoQkFTSF9GUkFNRVdPUktfRElTUExBWV9MRVZFTCA+PSBfX0xFVkVMX0RFQlVHKSk7IHRoZW4KICAgIGVjaG8gLWUgIiR7X19ERUJVR19DT0xPUn1ERUJVRyAgIC0gJHsxfSR7X19SRVNFVF9DT0xPUn0iID4mMgogIGZpCiAgTG9nOjpsb2dEZWJ1ZyAiJDEiCn0KCiMgQGRlc2NyaXB0aW9uIERpc3BsYXkgbWVzc2FnZSB1c2luZyBpbmZvIGNvbG9yIChiZyBsaWdodCBibHVlL2ZnIHdoaXRlKQojIEBhcmcgJDEgbWVzc2FnZTpTdHJpbmcgdGhlIG1lc3NhZ2UgdG8gZGlzcGxheQpMb2c6OmRpc3BsYXlJbmZvKCkgewogIGxvY2FsIHR5cGU9IiR7MjotSU5GT30iCiAgaWYgKChCQVNIX0ZSQU1FV09SS19ESVNQTEFZX0xFVkVMID49IF9fTEVWRUxfSU5GTykpOyB0aGVuCiAgICBlY2hvIC1lICIke19fSU5GT19DT0xPUn0ke3R5cGV9ICAgIC0gJHsxfSR7X19SRVNFVF9DT0xPUn0iID4mMgogIGZpCiAgTG9nOjpsb2dJbmZvICIkMSIgIiR7dHlwZX0iCn0KCiMgQGRlc2NyaXB0aW9uIGVuc3VyZSBDT01NQU5EX0JJTl9ESVIgZW52IHZhciBpcyBzZXQKIyBhbmQgUEFUSCBjb3JyZWN0bHkgcHJlcGFyZWQKIyBAbm9hcmdzCiMgQHNldCBDT01NQU5EX0JJTl9ESVIgc3RyaW5nIHRoZSBkaXJlY3Rvcnkgd2hlcmUgdG8gZmluZCB0aGlzIGNvbW1hbmQKIyBAc2V0IFBBVEggc3RyaW5nIGFkZCBkaXJlY3Rvcnkgd2hlcmUgdG8gZmluZCB0aGlzIGNvbW1hbmQgYmluYXJ5CkNvbXBpbGVyOjpGYWNhZGU6OnJlcXVpcmVDb21tYW5kQmluRGlyKCkgewogIENPTU1BTkRfQklOX0RJUj0iJHtDVVJSRU5UX0RJUn0iCiAgRW52OjpwYXRoUHJlcGVuZCAiJHtDT01NQU5EX0JJTl9ESVJ9Igp9CgojIEBkZXNjcmlwdGlvbiBjcmVhdGUgYSBuZXcgZGIgaW5zdGFuY2UKIyBSZXR1cm5zIGltbWVkaWF0ZWx5IGlmIHRoZSBpbnN0YW5jZSBpcyBhbHJlYWR5IGluaXRpYWxpemVkCiMKIyBAYXJnICQxIGluc3RhbmNlTmV3SW5zdGFuY2U6Jk1hcDxTdHJpbmcsU3RyaW5nPiAocGFzc2VkIGJ5IHJlZmVyZW5jZSkgZGF0YWJhc2UgaW5zdGFuY2UgdG8gdXNlCiMgQGFyZyAkMiBkc246U3RyaW5nIGRzbiBwcm9maWxlIC0gbG9hZCB0aGUgZHNuLmVudiBwcm9maWxlIGRlZHVjZWQgdXNpbmcgcnVsZXMgZGVmaW5lZCBpbiBDb25mOjpnZXRBYnNvbHV0ZUZpbGUKIwojIEBleGFtcGxlCiMgICBkZWNsYXJlIC1BZ3ggZGJJbnN0YW5jZQojICAgRGF0YWJhc2U6Om5ld0luc3RhbmNlIGRiSW5zdGFuY2UgImRlZmF1bHQubG9jYWwiCiMKIyBAZXhpdGNvZGUgMSBpZiBkbnMgZmlsZSBub3QgYWJsZSB0byBsb2FkZWQKRGF0YWJhc2U6Om5ld0luc3RhbmNlKCkgewogIGxvY2FsIC1uIGluc3RhbmNlTmV3SW5zdGFuY2U9JDEKICBsb2NhbCBkc249IiQyIgogIGxvY2FsIERTTl9GSUxFCgogIGlmIFtbIC12IGluc3RhbmNlTmV3SW5zdGFuY2VbJ0lOSVRJQUxJWkVEJ10gJiYgIiR7aW5zdGFuY2VOZXdJbnN0YW5jZVsnSU5JVElBTElaRUQnXTotMH0iID09ICIxIiBdXTsgdGhlbgogICAgcmV0dXJuCiAgZmkKCiAgIyBmaW5hbCBhdXRoIGZpbGUgZ2VuZXJhdGVkIGZyb20gZG5zIGZpbGUKICBpbnN0YW5jZU5ld0luc3RhbmNlWydBVVRIX0ZJTEUnXT0iIgogIGluc3RhbmNlTmV3SW5zdGFuY2VbJ0RTTl9GSUxFJ109IiIKCiAgIyBjaGVjayBkc24gZmlsZQogIERTTl9GSUxFPSIkKENvbmY6OmdldEFic29sdXRlRmlsZSAiZHNuIiAiJHtkc259IiAiZW52IikiIHx8IHJldHVybiAxCiAgRGF0YWJhc2U6OmNoZWNrRHNuRmlsZSAiJHtEU05fRklMRX0iIHx8IHJldHVybiAxCiAgaW5zdGFuY2VOZXdJbnN0YW5jZVsnRFNOX0ZJTEUnXT0iJHtEU05fRklMRX0iCgogICMgc2hlbGxjaGVjayBzb3VyY2U9L3NyYy9EYXRhYmFzZS90ZXN0c0RhdGEvZHNuX3ZhbGlkLmVudgogIHNvdXJjZSAiJHtpbnN0YW5jZU5ld0luc3RhbmNlWydEU05fRklMRSddfSIKCiAgaW5zdGFuY2VOZXdJbnN0YW5jZVsnVVNFUiddPSIke1VTRVJ9IgogIGluc3RhbmNlTmV3SW5zdGFuY2VbJ1BBU1NXT1JEJ109IiR7UEFTU1dPUkR9IgogIGluc3RhbmNlTmV3SW5zdGFuY2VbJ0hPU1ROQU1FJ109IiR7SE9TVE5BTUV9IgogIGluc3RhbmNlTmV3SW5zdGFuY2VbJ1BPUlQnXT0iJHtQT1JUfSIKCiAgIyBnZW5lcmF0ZSBhdXRoRmlsZSBmb3IgZWFzeSBhdXRoZW50aWNhdGlvbgogIGluc3RhbmNlTmV3SW5zdGFuY2VbJ0FVVEhfRklMRSddPSQobWt0ZW1wIC1wICIke1RNUERJUjotL3RtcH0iIC10ICJteXNxbC5YWFhYWFhYWFhYWFgiKQogICgKICAgIGVjaG8gIltjbGllbnRdIgogICAgZWNobyAidXNlciA9ICR7VVNFUn0iCiAgICBlY2hvICJwYXNzd29yZCA9ICR7UEFTU1dPUkR9IgogICAgZWNobyAiaG9zdCA9ICR7SE9TVE5BTUV9IgogICAgZWNobyAicG9ydCA9ICR7UE9SVH0iCiAgKSA+IiR7aW5zdGFuY2VOZXdJbnN0YW5jZVsnQVVUSF9GSUxFJ119IgoKICAjIHNvbWUgb2YgdGhvc2UgdmFsdWVzIGNhbiBiZSBvdmVycmlkZGVuIHVzaW5nIHRoZSBkc24gZmlsZQogICMgU0tJUF9DT0xVTU5fTkFNRVMgZW5hYmxlZCBieSBkZWZhdWx0CiAgaW5zdGFuY2VOZXdJbnN0YW5jZVsnU0tJUF9DT0xVTU5fTkFNRVMnXT0iJHtTS0lQX0NPTFVNTl9OQU1FUzotMX0iCiAgaW5zdGFuY2VOZXdJbnN0YW5jZVsnU1NMX09QVElPTlMnXT0iJHtNWVNRTF9TU0xfT1BUSU9OUzotLS1zc2wtbW9kZT1ESVNBQkxFRH0iCiAgaW5zdGFuY2VOZXdJbnN0YW5jZVsnUVVFUllfT1BUSU9OUyddPSIke01ZU1FMX1FVRVJZX09QVElPTlM6LS0tYmF0Y2ggLS1yYXcgLS1kZWZhdWx0LWNoYXJhY3Rlci1zZXQ9dXRmOH0iCiAgaW5zdGFuY2VOZXdJbnN0YW5jZVsnRFVNUF9PUFRJT05TJ109IiR7TVlTUUxfRFVNUF9PUFRJT05TOi0tLWRlZmF1bHQtY2hhcmFjdGVyLXNldD11dGY4IC0tY29tcHJlc3MgLS1oZXgtYmxvYiAtLXJvdXRpbmVzIC0tdHJpZ2dlcnMgLS1zaW5nbGUtdHJhbnNhY3Rpb24gLS1zZXQtZ3RpZC1wdXJnZWQ9T0ZGIC0tY29sdW1uLXN0YXRpc3RpY3M9MCAke2luc3RhbmNlTmV3SW5zdGFuY2VbJ1NTTF9PUFRJT05TJ119fSIKICBpbnN0YW5jZU5ld0luc3RhbmNlWydEQl9JTVBPUlRfT1BUSU9OUyddPSIke0RCX0lNUE9SVF9PUFRJT05TOi0tLWNvbm5lY3QtdGltZW91dD01IC0tYmF0Y2ggLS1yYXcgLS1kZWZhdWx0LWNoYXJhY3Rlci1zZXQ9dXRmOH0iCgogIGluc3RhbmNlTmV3SW5zdGFuY2VbJ0lOSVRJQUxJWkVEJ109MQp9CgojIEBkZXNjcmlwdGlvbiBteXNxbCBxdWVyeSBvbiBhIGdpdmVuIGRiCiMgQHdhcm5pbmcgY291bGQgdXNlIFFVRVJZX09QVElPTlMgdmFyaWFibGUgZnJvbSBkc24gaWYgZGVmaW5lZAojIEBleGFtcGxlCiMgICBjYXQgZmlsZS5zcWwgfCBEYXRhYmFzZTo6cXVlcnkgLi4uCiMgQGFyZyAkMSBpbnN0YW5jZVF1ZXJ5OiZNYXA8U3RyaW5nLFN0cmluZz4gKHBhc3NlZCBieSByZWZlcmVuY2UpIGRhdGFiYXNlIGluc3RhbmNlIHRvIHVzZQojIEBhcmcgJDIgc3FsUXVlcnk6U3RyaW5nIChvcHRpb25hbCkgc3FsIHF1ZXJ5IG9yIHNxbCBmaWxlIHRvIGV4ZWN1dGUuIGlmIG5vdCBwcm92aWRlZCBvciBlbXB0eSwgdGhlIGNvbW1hbmQgY2FuIGJlIHBpcGVkCiMgQGFyZyAkMyBkYk5hbWU6U3RyaW5nIChvcHRpb25hbCkgdGhlIGRiIG5hbWUKIwojIEBleGl0Y29kZSBteXNxbCBjb21tYW5kIHN0YXR1cyBjb2RlCkRhdGFiYXNlOjpxdWVyeSgpIHsKICBsb2NhbCAtbiBpbnN0YW5jZVF1ZXJ5PSQxCiAgbG9jYWwgLWEgbXlzcWxDb21tYW5kPSgpCiAgbG9jYWwgLWEgcXVlcnlPcHRpb25zCgogIG15c3FsQ29tbWFuZCs9KG15c3FsKQogIG15c3FsQ29tbWFuZCs9KCItLWRlZmF1bHRzLWV4dHJhLWZpbGU9JHtpbnN0YW5jZVF1ZXJ5WydBVVRIX0ZJTEUnXX0iKQogIElGUz0nICcgcmVhZCAtciAtYSBxdWVyeU9wdGlvbnMgPDw8IiR7aW5zdGFuY2VRdWVyeVsnUVVFUllfT1BUSU9OUyddfSIKICBteXNxbENvbW1hbmQrPSgiJHtxdWVyeU9wdGlvbnNbQF19IikKICBpZiBbWyAiJHtpbnN0YW5jZVF1ZXJ5WydTS0lQX0NPTFVNTl9OQU1FUyddfSIgPSAiMSIgXV07IHRoZW4KICAgIG15c3FsQ29tbWFuZCs9KCItcyIgIi0tc2tpcC1jb2x1bW4tbmFtZXMiKQogIGZpCiAgIyBhZGQgb3B0aW9uYWwgZGIgbmFtZQogIGlmIFtbIC1uICIkezMreH0iIF1dOyB0aGVuCiAgICBteXNxbENvbW1hbmQrPSgiJDMiKQogIGZpCiAgIyBhZGQgb3B0aW9uYWwgc3FsIHF1ZXJ5CiAgaWYgW1sgLW4gIiR7Mit4fSIgJiYgLW4gIiQyIiAmJiAhIC1mICIkMiIgXV07IHRoZW4KICAgIG15c3FsQ29tbWFuZCs9KCItZSIpCiAgICBteXNxbENvbW1hbmQrPSgiJDIiKQogIGZpCiAgTG9nOjpkaXNwbGF5RGVidWcgIiQocHJpbnRmICJleGVjdXRlIGNvbW1hbmQ6ICclcyciICIke215c3FsQ29tbWFuZFsqXX0iKSIKCiAgaWYgW1sgLWYgIiQyIiBdXTsgdGhlbgogICAgIiR7bXlzcWxDb21tYW5kW0BdfSIgPCIkMiIKICBlbHNlCiAgICAiJHtteXNxbENvbW1hbmRbQF19IgogIGZpCn0KCiMgQGRlc2NyaXB0aW9uIHNldCB0aGUgZ2VuZXJhbCBvcHRpb25zIHRvIHVzZSBvbiBteXNxbCBjb21tYW5kIHRvIHF1ZXJ5IHRoZSBkYXRhYmFzZQojIERpZmZlcnMgdGhhbiBzZXRPcHRpb25zIGluIHRoZSB3YXkgdGhhdCB0aGVzZSBvcHRpb25zIGNvdWxkIGNoYW5nZSBlYWNoIHRpbWUKIwojIEBhcmcgJDEgaW5zdGFuY2VTZXRRdWVyeU9wdGlvbnM6Jk1hcDxTdHJpbmcsU3RyaW5nPiAocGFzc2VkIGJ5IHJlZmVyZW5jZSkgZGF0YWJhc2UgaW5zdGFuY2UgdG8gdXNlCiMgQGFyZyAkMiBvcHRpb25zTGlzdDpTdHJpbmcgcXVlcnkgb3B0aW9ucyBsaXN0CkRhdGFiYXNlOjpzZXRRdWVyeU9wdGlvbnMoKSB7CiAgbG9jYWwgLW4gaW5zdGFuY2VTZXRRdWVyeU9wdGlvbnM9JDEKICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICBpbnN0YW5jZVNldFF1ZXJ5T3B0aW9uc1snUVVFUllfT1BUSU9OUyddPSIkMiIKfQoKIyBAZGVzY3JpcHRpb24gYnkgZGVmYXVsdCB3ZSBza2lwIHRoZSBjb2x1bW4gbmFtZXMKIyBidXQgc29tZXRpbWVzIHdlIG5lZWQgY29sdW1uIG5hbWVzIHRvIGRpc3BsYXkgc29tZSByZXN1bHRzCiMgZGlzYWJsZSB0aGlzIG9wdGlvbiB0ZW1wb3JhcmlseSBhbmQgdGhlbiByZXN0b3JlIGl0IHRvIHRydWUKIwojIEBhcmcgJDEgaW5zdGFuY2VTZXRRdWVyeU9wdGlvbnM6Jk1hcDxTdHJpbmcsU3RyaW5nPiAocGFzc2VkIGJ5IHJlZmVyZW5jZSkgZGF0YWJhc2UgaW5zdGFuY2UgdG8gdXNlCiMgQGFyZyAkMiBza2lwQ29sdW1uTmFtZXM6Qm9vbGVhbiAwIHRvIGRpc2FibGUsIDEgdG8gZW5hYmxlIChoaWRlIGNvbHVtbiBuYW1lcykKRGF0YWJhc2U6OnNraXBDb2x1bW5OYW1lcygpIHsKICBsb2NhbCAtbiBpbnN0YW5jZVNraXBDb2x1bW5OYW1lcz0kMQogICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogIGluc3RhbmNlU2tpcENvbHVtbk5hbWVzWydTS0lQX0NPTFVNTl9OQU1FUyddPSIkMiIKfQoKIyBAZGVzY3JpcHRpb24gcHJlcGVuZCBkaXJlY3RvcmllcyB0byB0aGUgUEFUSCBlbnZpcm9ubWVudCB2YXJpYWJsZQojIEBhcmcgJEAgYXJnczpTdHJpbmdbXSBsaXN0IG9mIGRpcmVjdG9yaWVzIHRvIHByZXBlbmQKIyBAc2V0IFBBVEggdXBkYXRlIFBBVEggd2l0aCB0aGUgZGlyZWN0b3JpZXMgcHJlcGVuZGVkCkVudjo6cGF0aFByZXBlbmQoKSB7CiAgbG9jYWwgYXJnCiAgZm9yIGFyZyBpbiAiJEAiOyBkbwogICAgaWYgW1sgLWQgIiR7YXJnfSIgJiYgIjoke1BBVEh9OiIgIT0gKiI6JHthcmd9OiIqIF1dOyB0aGVuCiAgICAgIFBBVEg9IiQocmVhbHBhdGggIiR7YXJnfSIpOiR7UEFUSH0iCiAgICBmaQogIGRvbmUKfQoKIyBAZGVzY3JpcHRpb24gRGlzcGxheSBtZXNzYWdlIHVzaW5nIGVycm9yIGNvbG9yIChyZWQpIGFuZCBleGl0IGltbWVkaWF0ZWx5IHdpdGggZXJyb3Igc3RhdHVzIDEKIyBAYXJnICQxIG1lc3NhZ2U6U3RyaW5nIHRoZSBtZXNzYWdlIHRvIGRpc3BsYXkKTG9nOjpmYXRhbCgpIHsKICBlY2hvIC1lICIke19fRVJST1JfQ09MT1J9RkFUQUwgICAtICR7MX0ke19fUkVTRVRfQ09MT1J9IiA+JjIKICBMb2c6OmxvZ0ZhdGFsICIkMSIKICBleGl0IDEKfQoKIyBAZGVzY3JpcHRpb24gbG9nIG1lc3NhZ2UgdG8gZmlsZQojIEBhcmcgJDEgbWVzc2FnZTpTdHJpbmcgdGhlIG1lc3NhZ2UgdG8gZGlzcGxheQpMb2c6OmxvZ0RlYnVnKCkgewogIGlmICgoQkFTSF9GUkFNRVdPUktfTE9HX0xFVkVMID49IF9fTEVWRUxfREVCVUcpKTsgdGhlbgogICAgTG9nOjpsb2dNZXNzYWdlICIkezI6LURFQlVHfSIgIiQxIgogIGZpCn0KCiMgQGRlc2NyaXB0aW9uIGxvZyBtZXNzYWdlIHRvIGZpbGUKIyBAYXJnICQxIG1lc3NhZ2U6U3RyaW5nIHRoZSBtZXNzYWdlIHRvIGRpc3BsYXkKTG9nOjpsb2dJbmZvKCkgewogIGlmICgoQkFTSF9GUkFNRVdPUktfTE9HX0xFVkVMID49IF9fTEVWRUxfSU5GTykpOyB0aGVuCiAgICBMb2c6OmxvZ01lc3NhZ2UgIiR7MjotSU5GT30iICIkMSIKICBmaQp9CgojIEBkZXNjcmlwdGlvbiBlbnN1cmUgcnVubmluZyB1c2VyIGlzIG5vdCByb290CiMgQGV4aXRjb2RlIDEgaWYgY3VycmVudCB1c2VyIGlzIHJvb3QKIyBAc3RkZXJyIGRpYWdub3N0aWNzIGluZm9ybWF0aW9uIGlzIGRpc3BsYXllZApMaW51eDo6cmVxdWlyZUV4ZWN1dGVkQXNVc2VyKCkgewogIGlmIFtbICIkKGlkIC11KSIgPSAiMCIgXV07IHRoZW4KICAgIExvZzo6ZmF0YWwgInRoaXMgc2NyaXB0IHNob3VsZCBiZSBleGVjdXRlZCBhcyBub3JtYWwgdXNlciIKICBmaQp9CgojIEBkZXNjcmlwdGlvbiBnZXQgYWJzb2x1dGUgY29uZiBmaWxlIGZyb20gc3BlY2lmaWVkIGNvbmYgZm9sZGVyIGRlZHVjZWQgdXNpbmcgdGhlc2UgcnVsZXMKIyAgICogZnJvbSBhYnNvbHV0ZSBmaWxlIChpZ25vcmVzIDxjb25mRm9sZGVyPiBhbmQgPGV4dGVuc2lvbj4pCiMgICAqIHJlbGF0aXZlIHRvIHdoZXJlIHNjcmlwdCBpcyBleGVjdXRlZCAoaWdub3JlcyA8Y29uZkZvbGRlcj4gYW5kIDxleHRlbnNpb24+KQojICAgKiBmcm9tIGhvbWUvLmJhc2gtdG9vbHMvPGNvbmZGb2xkZXI+CiMgICAqIGZyb20gZnJhbWV3b3JrIGNvbmYvPGNvbmZGb2xkZXI+CiMKIyBAYXJnICQxIGNvbmZGb2xkZXI6U3RyaW5nIHRoZSBkaXJlY3RvcnkgbmFtZSAobm90IHRoZSBwYXRoKSB0byBsaXN0CiMgQGFyZyAkMiBjb25mOlN0cmluZyBmaWxlIHRvIHVzZSB3aXRob3V0IGV4dGVuc2lvbgojIEBhcmcgJDMgZXh0ZW5zaW9uOlN0cmluZyB0aGUgZXh0ZW5zaW9uICguc2ggYnkgZGVmYXVsdCkKIwojIEBzdGRvdXQgYWJzb2x1dGUgY29uZiBmaWxlbmFtZQojIEBleGl0Y29kZSAxIGlmIGZpbGUgaXMgbm90IGZvdW5kIGluIGFueSBsb2NhdGlvbgpDb25mOjpnZXRBYnNvbHV0ZUZpbGUoKSB7CiAgbG9jYWwgY29uZkZvbGRlcj0iJDEiCiAgbG9jYWwgY29uZj0iJDIiCiAgbG9jYWwgZXh0ZW5zaW9uPSIkezMtLnNofSIKICBpZiBbWyAtbiAiJHtleHRlbnNpb259IiAmJiAiJHtleHRlbnNpb246MDoxfSIgIT0gIi4iIF1dOyB0aGVuCiAgICBleHRlbnNpb249Ii4ke2V4dGVuc2lvbn0iCiAgZmkKCiAgdGVzdEFicygpIHsKICAgIGxvY2FsIHJlc3VsdAogICAgcmVzdWx0PSIkKHJlYWxwYXRoIC1lICIkMSIgMj4vZGV2L251bGwpIgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMTgxCiAgICBpZiBbWyAiJD8iID0gIjAiICYmIC1mICIke3Jlc3VsdH0iIF1dOyB0aGVuCiAgICAgIGVjaG8gIiR7cmVzdWx0fSIKICAgICAgcmV0dXJuIDAKICAgIGZpCiAgICByZXR1cm4gMQogIH0KCiAgIyBjb25mIGlzIGFic29sdXRlIGZpbGUgKGluY2x1ZGluZyBleHRlbnNpb24pCiAgdGVzdEFicyAiJHtjb25mRm9sZGVyfSR7ZXh0ZW5zaW9ufSIgJiYgcmV0dXJuIDAKICAjIGNvbmYgaXMgYWJzb2x1dGUgZmlsZQogIHRlc3RBYnMgIiR7Y29uZkZvbGRlcn0iICYmIHJldHVybiAwCiAgIyBjb25mIGlzIGFic29sdXRlIGZpbGUgKGluY2x1ZGluZyBleHRlbnNpb24pCiAgdGVzdEFicyAiJHtjb25mfSR7ZXh0ZW5zaW9ufSIgJiYgcmV0dXJuIDAKICAjIGNvbmYgaXMgYWJzb2x1dGUgZmlsZQogIHRlc3RBYnMgIiR7Y29uZn0iICYmIHJldHVybiAwCgogICMgcmVsYXRpdmUgdG8gd2hlcmUgc2NyaXB0IGlzIGV4ZWN1dGVkIChpbmNsdWRpbmcgZXh0ZW5zaW9uKQogIGlmIFtbIC1uICIke0NVUlJFTlRfRElSK3h4eH0iIF1dOyB0aGVuCiAgICB0ZXN0QWJzICIkKEZpbGU6OmNvbmNhdGVuYXRlUGF0aCAiJHtDVVJSRU5UX0RJUn0iICIke2NvbmZGb2xkZXJ9IikvJHtjb25mfSR7ZXh0ZW5zaW9ufSIgJiYgcmV0dXJuIDAKICBmaQogICMgZnJvbSBob21lLy5iYXNoLXRvb2xzLzxjb25mRm9sZGVyPgogIHRlc3RBYnMgIiQoRmlsZTo6Y29uY2F0ZW5hdGVQYXRoICIke0hPTUV9Ly5iYXNoLXRvb2xzIiAiJHtjb25mRm9sZGVyfSIpLyR7Y29uZn0ke2V4dGVuc2lvbn0iICYmIHJldHVybiAwCgogIGlmIFtbIC1uICIke0ZSQU1FV09SS19ST09UX0RJUit4eHh9IiBdXTsgdGhlbgogICAgIyBmcm9tIGZyYW1ld29yayBjb25mLzxjb25mRm9sZGVyPiAoaW5jbHVkaW5nIGV4dGVuc2lvbikKICAgIHRlc3RBYnMgIiQoRmlsZTo6Y29uY2F0ZW5hdGVQYXRoICIke0ZSQU1FV09SS19ST09UX0RJUn0vY29uZiIgIiR7Y29uZkZvbGRlcn0iKS8ke2NvbmZ9JHtleHRlbnNpb259IiAmJiByZXR1cm4gMAoKICAgICMgZnJvbSBmcmFtZXdvcmsgY29uZi88Y29uZkZvbGRlcj4KICAgIHRlc3RBYnMgIiQoRmlsZTo6Y29uY2F0ZW5hdGVQYXRoICIke0ZSQU1FV09SS19ST09UX0RJUn0vY29uZiIgIiR7Y29uZkZvbGRlcn0iKS8ke2NvbmZ9IiAmJiByZXR1cm4gMAogIGZpCgogICMgZmlsZSBub3QgZm91bmQKICBMb2c6OmRpc3BsYXlFcnJvciAiY29uZiBmaWxlICcke2NvbmZ9JyBub3QgZm91bmQiCgogIHJldHVybiAxCn0KCiMgQGRlc2NyaXB0aW9uIGNoZWNrIGlmIGRzbiBmaWxlIGhhcyBhbGwgdGhlIG1hbmRhdG9yeSB2YXJpYWJsZXMgc2V0CiMgTWFuZGF0b3J5IHZhcmlhYmxlcyBhcmU6IEhPU1ROQU1FLCBVU0VSLCBQQVNTV09SRCwgUE9SVAojCiMgQGFyZyAkMSBkc25GaWxlTmFtZTpTdHJpbmcgZHNuIGFic29sdXRlIGZpbGVuYW1lCiMgQHNldCBIT1NUTkFNRSBsb2FkZWQgZnJvbSBkc24gZmlsZQojIEBzZXQgUE9SVCBsb2FkZWQgZnJvbSBkc24gZmlsZQojIEBzZXQgVVNFUiBsb2FkZWQgZnJvbSBkc24gZmlsZQojIEBzZXQgUEFTU1dPUkQgbG9hZGVkIGZyb20gZHNuIGZpbGUKIyBAZXhpdGNvZGUgMCBvbiB2YWxpZCBmaWxlCiMgQGV4aXRjb2RlIDEgaWYgb25lIG9mIHRoZSBwcm9wZXJ0aWVzIG9mIHRoZSBjb25mIGZpbGUgaXMgaW52YWxpZCBvciBpZiBmaWxlIG5vdCBmb3VuZAojIEBzdGRlcnIgbG9nIG91dHB1dCBpZiBlcnJvciBmb3VuZCBpbiBjb25mIGZpbGUKRGF0YWJhc2U6OmNoZWNrRHNuRmlsZSgpIHsKICBsb2NhbCBkc25GaWxlTmFtZT0iJDEiCiAgaWYgW1sgISAtZiAiJHtkc25GaWxlTmFtZX0iIF1dOyB0aGVuCiAgICBMb2c6OmRpc3BsYXlFcnJvciAiZHNuIGZpbGUgJHtkc25GaWxlTmFtZX0gbm90IGZvdW5kIgogICAgcmV0dXJuIDEKICBmaQoKICAoCiAgICB1bnNldCBIT1NUTkFNRSBQT1JUIFBBU1NXT1JEIFVTRVIKICAgICMgc2hlbGxjaGVjayBzb3VyY2U9L3NyYy9EYXRhYmFzZS90ZXN0c0RhdGEvZHNuX3ZhbGlkLmVudgogICAgc291cmNlICIke2RzbkZpbGVOYW1lfSIKICAgIGlmIFtbIC16ICR7SE9TVE5BTUUreH0gXV07IHRoZW4KICAgICAgTG9nOjpkaXNwbGF5RXJyb3IgImRzbiBmaWxlICR7ZHNuRmlsZU5hbWV9IDogSE9TVE5BTUUgbm90IHByb3ZpZGVkIgogICAgICByZXR1cm4gMQogICAgZmkKICAgIGlmIFtbIC16ICIke0hPU1ROQU1FfSIgXV07IHRoZW4KICAgICAgTG9nOjpkaXNwbGF5V2FybmluZyAiZHNuIGZpbGUgJHtkc25GaWxlTmFtZX0gOiBIT1NUTkFNRSB2YWx1ZSBub3QgcHJvdmlkZWQiCiAgICBmaQogICAgaWYgW1sgIiR7SE9TVE5BTUV9IiA9ICJsb2NhbGhvc3QiIF1dOyB0aGVuCiAgICAgIExvZzo6ZGlzcGxheVdhcm5pbmcgImRzbiBmaWxlICR7ZHNuRmlsZU5hbWV9IDogY2hlY2sgdGhhdCBIT1NUTkFNRSBzaG91bGQgbm90IGJlIDEyNy4wLjAuMSBpbnN0ZWFkIG9mIGxvY2FsaG9zdCIKICAgIGZpCiAgICBpZiBbWyAteiAiJHtQT1JUK3h9IiBdXTsgdGhlbgogICAgICBMb2c6OmRpc3BsYXlFcnJvciAiZHNuIGZpbGUgJHtkc25GaWxlTmFtZX0gOiBQT1JUIG5vdCBwcm92aWRlZCIKICAgICAgcmV0dXJuIDEKICAgIGZpCiAgICBpZiAhIFtbICR7UE9SVH0gPX4gXlswLTldKyQgXV07IHRoZW4KICAgICAgTG9nOjpkaXNwbGF5RXJyb3IgImRzbiBmaWxlICR7ZHNuRmlsZU5hbWV9IDogUE9SVCBpbnZhbGlkIgogICAgICByZXR1cm4gMQogICAgZmkKICAgIGlmIFtbIC16ICIke1VTRVIreH0iIF1dOyB0aGVuCiAgICAgIExvZzo6ZGlzcGxheUVycm9yICJkc24gZmlsZSAke2RzbkZpbGVOYW1lfSA6IFVTRVIgbm90IHByb3ZpZGVkIgogICAgICByZXR1cm4gMQogICAgZmkKICAgIGlmIFtbIC16ICIke1BBU1NXT1JEK3h9IiBdXTsgdGhlbgogICAgICBMb2c6OmRpc3BsYXlFcnJvciAiZHNuIGZpbGUgJHtkc25GaWxlTmFtZX0gOiBQQVNTV09SRCBub3QgcHJvdmlkZWQiCiAgICAgIHJldHVybiAxCiAgICBmaQogICkKfQoKIyBAZGVzY3JpcHRpb24gbG9nIG1lc3NhZ2UgdG8gZmlsZQojIEBhcmcgJDEgbWVzc2FnZTpTdHJpbmcgdGhlIG1lc3NhZ2UgdG8gZGlzcGxheQpMb2c6OmxvZ0ZhdGFsKCkgewogIExvZzo6bG9nTWVzc2FnZSAiJHsyOi1GQVRBTH0iICIkMSIKfQoKIyBAZGVzY3JpcHRpb24gSW50ZXJuYWw6IGNvbW1vbiBsb2cgbWVzc2FnZQojIEBleGFtcGxlIHRleHQKIyAgIFtkYXRlXXxbbGV2ZWxNc2ddfG1lc3NhZ2UKIwojIEBleGFtcGxlIHRleHQKIyAgIDIwMjAtMDEtMTkgMTk6MjA6MjF8RVJST1IgIHxsb2cgZXJyb3IKIyAgIDIwMjAtMDEtMTkgMTk6MjA6MjF8U0tJUFBFRHxsb2cgc2tpcHBlZAojCiMgQGFyZyAkMSBsZXZlbE1zZzpTdHJpbmcgbWVzc2FnZSdzIGxldmVsIGRlc2NyaXB0aW9uIChlZzogU1RBVFVTLCBFUlJPUiwgLi4uKQojIEBhcmcgJDIgbXNnOlN0cmluZyB0aGUgbWVzc2FnZSB0byBkaXNwbGF5CiMgQGVudiBCQVNIX0ZSQU1FV09SS19MT0dfRklMRSBTdHJpbmcgbG9nIGZpbGUgdG8gdXNlLCBkbyBub3RoaW5nIGlmIGVtcHR5CiMgQGVudiBCQVNIX0ZSQU1FV09SS19MT0dfTEVWRUwgaW50IGxvZyBsZXZlbCBsb2cgb25seSBpZiA+IE9GRiBvciBmYXRhbCBtZXNzYWdlcwojIEBzdGRlcnIgZGlhZ25vc3RpY3MgaW5mb3JtYXRpb24gaXMgZGlzcGxheWVkCiMgQHJlcXVpcmUgRW52OjpyZXF1aXJlTG9hZAojIEByZXF1aXJlIExvZzo6cmVxdWlyZUxvYWQKTG9nOjpsb2dNZXNzYWdlKCkgewogIGxvY2FsIGxldmVsTXNnPSIkMSIKICBsb2NhbCBtc2c9IiQyIgogIGxvY2FsIGRhdGUKCiAgaWYgW1sgLW4gIiR7QkFTSF9GUkFNRVdPUktfTE9HX0ZJTEV9IiBdXSAmJiAoKEJBU0hfRlJBTUVXT1JLX0xPR19MRVZFTCA+IF9fTEVWRUxfT0ZGKSk7IHRoZW4KICAgIGRhdGU9IiQoZGF0ZSAnKyVZLSVtLSVkICVIOiVNOiVTJykiCiAgICB0b3VjaCAiJHtCQVNIX0ZSQU1FV09SS19MT0dfRklMRX0iCiAgICBwcmludGYgIiVzfCU3c3wlc1xuIiAiJHtkYXRlfSIgIiR7bGV2ZWxNc2d9IiAiJHttc2d9IiA+PiIke0JBU0hfRlJBTUVXT1JLX0xPR19GSUxFfSIKICBmaQp9CgojIEBkZXNjcmlwdGlvbiBjb25jYXRlbmF0ZSAyIHBhdGhzIGFuZCBlbnN1cmUgdGhlIHBhdGggaXMgY29ycmVjdCB1c2luZyByZWFscGF0aCAtbQojIEBhcmcgJDEgYmFzZVBhdGg6U3RyaW5nCiMgQGFyZyAkMiBzdWJQYXRoOlN0cmluZwojIEByZXF1aXJlIExpbnV4OjpyZXF1aXJlUmVhbHBhdGhDb21tYW5kCkZpbGU6OmNvbmNhdGVuYXRlUGF0aCgpIHsKICBsb2NhbCBiYXNlUGF0aD0iJDEiCiAgbG9jYWwgc3ViUGF0aD0iJDIiCiAgbG9jYWwgZnVsbFBhdGg9IiR7YmFzZVBhdGg6KyR7YmFzZVBhdGh9L30ke3N1YlBhdGh9IgoKICByZWFscGF0aCAtbSAiJHtmdWxsUGF0aH0iIDI+L2Rldi9udWxsCn0KCiMgQGRlc2NyaXB0aW9uIERpc3BsYXkgbWVzc2FnZSB1c2luZyBlcnJvciBjb2xvciAocmVkKQojIEBhcmcgJDEgbWVzc2FnZTpTdHJpbmcgdGhlIG1lc3NhZ2UgdG8gZGlzcGxheQpMb2c6OmRpc3BsYXlFcnJvcigpIHsKICBpZiAoKEJBU0hfRlJBTUVXT1JLX0RJU1BMQVlfTEVWRUwgPj0gX19MRVZFTF9FUlJPUikpOyB0aGVuCiAgICBlY2hvIC1lICIke19fRVJST1JfQ09MT1J9RVJST1IgICAtICR7MX0ke19fUkVTRVRfQ09MT1J9IiA+JjIKICBmaQogIExvZzo6bG9nRXJyb3IgIiQxIgp9CgojIEBkZXNjcmlwdGlvbiBEaXNwbGF5IG1lc3NhZ2UgdXNpbmcgd2FybmluZyBjb2xvciAoeWVsbG93KQojIEBhcmcgJDEgbWVzc2FnZTpTdHJpbmcgdGhlIG1lc3NhZ2UgdG8gZGlzcGxheQpMb2c6OmRpc3BsYXlXYXJuaW5nKCkgewogIGlmICgoQkFTSF9GUkFNRVdPUktfRElTUExBWV9MRVZFTCA+PSBfX0xFVkVMX1dBUk5JTkcpKTsgdGhlbgogICAgZWNobyAtZSAiJHtfX1dBUk5JTkdfQ09MT1J9V0FSTiAgICAtICR7MX0ke19fUkVTRVRfQ09MT1J9IiA+JjIKICBmaQogIExvZzo6bG9nV2FybmluZyAiJDEiCn0KCiMgQGRlc2NyaXB0aW9uIGVuc3VyZSBlbnYgZmlsZXMgYXJlIGxvYWRlZAojIEBub2FyZ3MKIyBAZXhpdGNvZGUgMSBpZiBnZXRPcmRlcmVkQ29uZkZpbGVzIGZhaWxzCiMgQGV4aXRjb2RlIDIgaWYgb25lIG9mIGVudiBmaWxlcyBmYWlscyB0byBsb2FkCiMgQHN0ZGVyciBkaWFnbm9zdGljcyBpbmZvcm1hdGlvbiBpcyBkaXNwbGF5ZWQKRW52OjpyZXF1aXJlTG9hZCgpIHsKICBsb2NhbCBjb25maWdGaWxlc1N0cgogIGNvbmZpZ0ZpbGVzU3RyPSIkKEVudjo6Z2V0T3JkZXJlZENvbmZGaWxlcykiIHx8IHJldHVybiAxCgogIGxvY2FsIC1hIGNvbmZpZ0ZpbGVzCiAgcmVhZGFycmF5IC10IGNvbmZpZ0ZpbGVzIDw8PCIke2NvbmZpZ0ZpbGVzU3RyfSIKCiAgIyBpZiBlbXB0eSBzdHJpbmcsIHRoZXJlIHdpbGwgYmUgb25lIGVsZW1lbnQKICBpZiAoKCR7I2NvbmZpZ0ZpbGVzW0BdfSA9PSAwKSkgfHwgW1sgLXogIiR7Y29uZmlnRmlsZXNTdHJ9IiBdXTsgdGhlbgogICAgIyBzaG91bGQgbm90IGhhcHBlbiwgYXMgdGhlcmUgaXMgYWx3YXlzIGRlZmF1bHQgZmlsZQogICAgTG9nOjpkaXNwbGF5U2tpcHBlZCAibm8gZW52IGZpbGUgdG8gbG9hZCIKICAgIHJldHVybiAwCiAgZmkKCiAgRW52OjptZXJnZUNvbmZGaWxlcyAiJHtjb25maWdGaWxlc1tAXX0iIHx8IHsKICAgIExvZzo6ZGlzcGxheUVycm9yICJ3aGlsZSBsb2FkaW5nIGNvbmZpZyBmaWxlczogJHtjb25maWdGaWxlc1sqXX0iCiAgICByZXR1cm4gMgogIH0KfQoKIyBAZGVzY3JpcHRpb24gYWN0aXZhdGUgb3Igbm90IExvZzo6ZGlzcGxheSogYW5kIExvZzo6bG9nKiBmdW5jdGlvbnMKIyBiYXNlZCBvbiBCQVNIX0ZSQU1FV09SS19ESVNQTEFZX0xFVkVMIGFuZCBCQVNIX0ZSQU1FV09SS19MT0dfTEVWRUwKIyBlbnZpcm9ubWVudCB2YXJpYWJsZXMgbG9hZGVkIGJ5IEVudjo6cmVxdWlyZUxvYWQKIyB0cnkgdG8gY3JlYXRlIGxvZyBmaWxlIGFuZCByb3RhdGUgaXQgaWYgbmVjZXNzYXJ5CiMgQG5vYXJncwojIEBzZXQgQkFTSF9GUkFNRVdPUktfTE9HX0xFVkVMIGludCB0byBPRkYgbGV2ZWwgaWYgQkFTSF9GUkFNRVdPUktfTE9HX0ZJTEUgaXMgZW1wdHkgb3Igbm90IHdyaXRhYmxlCiMgQGVudiBCQVNIX0ZSQU1FV09SS19ESVNQTEFZX0xFVkVMIGludAojIEBlbnYgQkFTSF9GUkFNRVdPUktfTE9HX0xFVkVMIGludAojIEBlbnYgQkFTSF9GUkFNRVdPUktfTE9HX0ZJTEUgU3RyaW5nCiMgQGVudiBCQVNIX0ZSQU1FV09SS19MT0dfRklMRV9NQVhfUk9UQVRJT04gaW50IGRvIGxvZyByb3RhdGlvbiBpZiA+IDAKIyBAZXhpdGNvZGUgMCBhbHdheXMgc3VjY2Vzc2Z1bAojIEBzdGRlcnIgZGlhZ25vc3RpY3MgaW5mb3JtYXRpb24gYWJvdXQgbG9nIGZpbGUgaXMgZGlzcGxheWVkCiMgQHJlcXVpcmUgRW52OjpyZXF1aXJlTG9hZAojIEByZXF1aXJlIFVJOjpyZXF1aXJlVGhlbWUKTG9nOjpyZXF1aXJlTG9hZCgpIHsKICBpZiBbWyAteiAiJHtCQVNIX0ZSQU1FV09SS19MT0dfRklMRTotfSIgXV07IHRoZW4KICAgIEJBU0hfRlJBTUVXT1JLX0xPR19MRVZFTD0ke19fTEVWRUxfT0ZGfQogICAgZXhwb3J0IEJBU0hfRlJBTUVXT1JLX0xPR19MRVZFTAogIGZpCgogIGlmICgoQkFTSF9GUkFNRVdPUktfTE9HX0xFVkVMID4gX19MRVZFTF9PRkYpKTsgdGhlbgogICAgaWYgW1sgISAtZiAiJHtCQVNIX0ZSQU1FV09SS19MT0dfRklMRX0iIF1dOyB0aGVuCiAgICAgIGlmCiAgICAgICAgISBta2RpciAtcCAiJChkaXJuYW1lICIke0JBU0hfRlJBTUVXT1JLX0xPR19GSUxFfSIpIiAyPi9kZXYvbnVsbCB8fAogICAgICAgICAgISB0b3VjaCAtLW5vLWNyZWF0ZSAiJHtCQVNIX0ZSQU1FV09SS19MT0dfRklMRX0iIDI+L2Rldi9udWxsCiAgICAgIHRoZW4KICAgICAgICBCQVNIX0ZSQU1FV09SS19MT0dfTEVWRUw9JHtfX0xFVkVMX09GRn0KICAgICAgICBlY2hvIC1lICIke19fRVJST1JfQ09MT1J9RVJST1IgICAtIEZpbGUgJHtCQVNIX0ZSQU1FV09SS19MT0dfRklMRX0gaXMgbm90IHdyaXRhYmxlJHtfX1JFU0VUX0NPTE9SfSIgPiYyCiAgICAgIGZpCiAgICBlbGlmIFtbICEgLXcgIiR7QkFTSF9GUkFNRVdPUktfTE9HX0ZJTEV9IiBdXTsgdGhlbgogICAgICBCQVNIX0ZSQU1FV09SS19MT0dfTEVWRUw9JHtfX0xFVkVMX09GRn0KICAgICAgZWNobyAtZSAiJHtfX0VSUk9SX0NPTE9SfUVSUk9SICAgLSBGaWxlICR7QkFTSF9GUkFNRVdPUktfTE9HX0ZJTEV9IGlzIG5vdCB3cml0YWJsZSR7X19SRVNFVF9DT0xPUn0iID4mMgogICAgZmkKCiAgZmkKCiAgaWYgKChCQVNIX0ZSQU1FV09SS19MT0dfTEVWRUwgPiBfX0xFVkVMX09GRikpOyB0aGVuCiAgICAjIHdpbGwgYWx3YXlzIGJlIGNyZWF0ZWQgZXZlbiBpZiBub3QgaW4gaW5mbyBsZXZlbAogICAgTG9nOjpsb2dNZXNzYWdlICJJTkZPIiAiTG9nZ2luZyB0byBmaWxlICR7QkFTSF9GUkFNRVdPUktfTE9HX0ZJTEV9IC0gTG9nIGxldmVsICR7QkFTSF9GUkFNRVdPUktfTE9HX0xFVkVMfSIKICAgIGlmICgoQkFTSF9GUkFNRVdPUktfTE9HX0ZJTEVfTUFYX1JPVEFUSU9OID4gMCkpOyB0aGVuCiAgICAgIExvZzo6cm90YXRlICIke0JBU0hfRlJBTUVXT1JLX0xPR19GSUxFfSIgIiR7QkFTSF9GUkFNRVdPUktfTE9HX0ZJTEVfTUFYX1JPVEFUSU9OfSIKICAgIGZpCiAgZmkKfQoKIyBAZGVzY3JpcHRpb24gZ2V0IGxpc3Qgb2YgZW52IGZpbGVzIHRvIGxvYWQKIyBpbiBvcmRlciB0byBtYWtlIHRoZW0gYXZhaWxhYmxlIGZvciBFbnY6OnJlcXVpcmVMb2FkCiMgQGVudiBCQVNIX0ZSQU1FV09SS19FTlZfRklMRVMgU3RyaW5nW10gbGlzdCBvZiBlbnYgZmlsZXMgdGhhdCBzaG91bGQgYmUgbG9hZGVkCiMgQGV4aXRjb2RlIDEgaWYgb25lIG9mIHRoZSBlbnYgZmlsZSBjYW5ub3QgYmUgZ2VuZXJhdGVkCiMgQGV4aXRjb2RlIDIgaWYgb25lIG9mIHRoZSBlbnYgZmlsZSBpcyBub3QgYSBmaWxlIG9yIHJlYWRhYmxlCiMgQHN0ZG91dCB0aGUgZW52IGZpbGVzIGFza2VkIHRvIGJlIGxvYWRlZAojIEBzdGRlcnIgZGlhZ25vc3RpYyBpbmZvcm1hdGlvbiBvbiBmYWlsdXJlCiMgQHNlZSBodHRwczovL2dpdGh1Yi5jb20vZmNoYXN0YW5ldC9iYXNoLXRvb2xzLWZyYW1ld29yay9ibG9iL21hc3Rlci9GcmFtZXdvcmtEb2MubWQjY29uZmlnX2ZpbGVfb3JkZXIKRW52OjpnZXRPcmRlcmVkQ29uZkZpbGVzKCkgewogIGxvY2FsIC1hIGNvbmZpZ0ZpbGVzPSgpCgogIGlmIFtbIC1uICIke0JBU0hfRlJBTUVXT1JLX0VOVl9GSUxFU1swXSsxfSIgXV07IHRoZW4KICAgICMgQkFTSF9GUkFNRVdPUktfRU5WX0ZJTEVTIGlzIGFuIGFycmF5CiAgICBjb25maWdGaWxlcys9KCIke0JBU0hfRlJBTUVXT1JLX0VOVl9GSUxFU1tAXX0iKQogIGZpCgogIGxvY2FsIGRlZmF1bHRFbnZGaWxlCiAgZGVmYXVsdEVudkZpbGU9IiQoRW52OjpjcmVhdGVEZWZhdWx0RW52RmlsZSkiIHx8IHJldHVybiAxCiAgY29uZmlnRmlsZXMrPSgiJHtkZWZhdWx0RW52RmlsZX0iKQoKICBsb2NhbCBmaWxlCiAgZm9yIGZpbGUgaW4gIiR7Y29uZmlnRmlsZXNbQF19IjsgZG8KICAgIGlmIFtbICEgLWYgIiR7ZmlsZX0iIHx8ICEgLXIgIiR7ZmlsZX0iIF1dOyB0aGVuCiAgICAgIExvZzo6ZGlzcGxheUVycm9yICJPbmUgb2YgdGhlIGNvbmZpZyBmaWxlIGlzIG5vdCBhdmFpbGFibGUgJyR7ZmlsZX0nIgogICAgICByZXR1cm4gMgogICAgZmkKICAgIGVjaG8gIiR7ZmlsZX0iCiAgZG9uZQp9CgojIEBkZXNjcmlwdGlvbiBtZXJnZSBhbmQgbG9hZCBjb25mIGZpbGVzIHNwZWNpZmllZCBhcyBhcmd1bWVudAojIC0gZmlsZXMgYXJlIGNsZWFuZWQgZnJvbSBheSBjb21tZW50CiMgLSBtaXNzaW5nIHF1b3RlcyBhZnRlciBwcm9wZXJ0eSA9IHNpZ24gYXJlIGFkZGVkIGF1dG9tYXRpY2FsbHkKIyAtIGF1dG9tYXRpYyByZW1vdmUgb2YgYWxsIHdoaXRlc3BhY2UgYmVmb3JlIGFuZCBhZnRlciBkZWNsYXJhdGlvbnMKIyAtIGJhc2ggYXJyYXlzIGFyZSBub3Qgc3VwcG9ydGVkCiMgLSBpZiBhIHZhcmlhYmxlIGlzIGRlY2xhcmVkIGluIGZpcnN0IGZpbGUgYW5kIG92ZXJyaWRkZW4gbGF0ZXIgb24KIyAgIGluIHRoZSBzYW1lIGZpbGUgb3IgaW4gc3Vic2VxdWVudCBmaWxlcywgdGhvc2Ugb3ZlcmxvYWRzIHdpbGwgYmUKIyAgIGlnbm9yZWQKIyBAd2FybmluZyBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgbG9hZGluZyBvbmUgb2YgdGhlIGNvbmZpZyBmaWxlLCBleGl0IGNvZGUgMyBidXQgZW52aXJvbm1lbnQgY291bGQgYmUgcGFydGlhbGx5IGxvYWRlZAojIEBhcmcgJEAgYXJnczpTdHJpbmdbXSBsaXN0IG9mIGNvbmZpZ3VyYXRpb24gZmlsZXMgdG8gbG9hZCBpbiBvcmRlcgojIEBzZXQgZW52VmFycyBTdHJpbmcgd2lsbCBzZXQgaW4gZW52aXJvbm1lbnQgYWxsIHRoZSB2YXJpYWJsZXMgdGhhdCBoYXZlIGJlZW4gZGVjbGFyZWQgaW4gdGhlIGNvbmZpZyBmaWxlcwojIEBlbnYgZW52VmFycyBTdHJpbmcgdGhlIGVudiB2YXJpYWJsZXMgb2YgdGhlIGN1cnJlbnQgc2NyaXB0IGNvdWxkIGJlIHVzZWQgdG8gaW50ZXJwcmV0IHZhcmlhYmxlcyBkdXJpbmcgY29uZmlnIGZpbGVzIHBhcnNpbmcKIyBAZXhpdGNvZGUgMCBpZiBubyBjb25maWcgZmlsZXMgcHJvdmlkZWQgb3IgbG9hZCBjb21wbGV0ZWQgc3VjY2Vzc2Z1bGx5CiMgQGV4aXRjb2RlIDEgaWYgZXJyb3Igb2NjdXJyZWQgZHVyaW5nIHBhcnNpbmcgdGhlIGNvbmZpZyBmaWxlcyAoZmlsZSBub3QgZm91bmQsIGdyZXAsIGF3ayBvciBzZWQgZXJyb3IpCiMgQGV4aXRjb2RlIDIgaWYgdGVtcG9yYXJ5IGZpbGUgY2Fubm90IGJlIGNyZWF0ZWQKIyBAZXhpdGNvZGUgMyBpZiBhbiBlcnJvciBvY2N1cnJlZCBkdXJpbmcgY29uZmlnIGZpbGUgc291cmNpbmcKIyBAc3RkZXJyIGRpYWdub3N0aWNzIGluZm9ybWF0aW9uIGlzIGRpc3BsYXllZAojIEBzZWUgbGFyZ2VseSBpbnNwaXJlZCBidXQgbW9kaWZpZWQgZnJvbSBodHRwczovL29wZW5zb3VyY2UuY29tL2FydGljbGUvMjEvNS9wcm9jZXNzaW5nLWNvbmZpZ3VyYXRpb24tZmlsZXMtc2hlbGwKRW52OjptZXJnZUNvbmZGaWxlcygpIHsKICBsb2NhbCAtYSBjb25maWdGaWxlTGlzdD0oIiRAIikKCiAgaWYgKCgkeyNjb25maWdGaWxlTGlzdFtAXX0gPT0gMCkpOyB0aGVuCiAgICByZXR1cm4gMAogIGZpCgogIGxvY2FsIGNvbWJpbmVkQ29uZmlnRmlsZQogIGNvbWJpbmVkQ29uZmlnRmlsZT0iJChGcmFtZXdvcms6OmNyZWF0ZVRlbXBGaWxlICJtZXJnZUNvbmZGaWxlcyIpIiB8fCByZXR1cm4gMgoKICAoCiAgICAjIHJlbW92ZXMgYW55IHRyYWlsaW5nIHdoaXRlc3BhY2UgZnJvbSBlYWNoIGZpbGUsIGlmIGFueQogICAgIyB0aGlzIGlzIGFic29sdXRlbHkgcmVxdWlyZWQgd2hlbiBpbXBvcnRpbmcgaW50byBDb25maWdNYXBzCiAgICAjIHB1dCBxdW90ZXMgYXJvdW5kIHZhbHVlcwogICAgc2VkIC1FIC1lICQncy9ccyokLy8gOyAvXiQvZCA7IC9eIy4qJC9kIDsgcy89KFteIlwnXS4qKSQvPSJcXDEiLycgIiR7Y29uZmlnRmlsZUxpc3RbQF19IiB8CiAgICAgICMgcmVtb3ZlIGFsbCBjb21tZW50IGxpbmVzCiAgICAgIEZpbHRlcnM6OmNvbW1lbnRMaW5lcyB8CiAgICAgICMgaXRlcmF0ZXMgb3ZlciBlYWNoIGZpbGUgYW5kIHByaW50cyAoZGVmYXVsdCBhd2sgYmVoYXZpb3IpCiAgICAgICMgZWFjaCB1bmlxdWUgbGluZTsgb25seSB0YWtlcyBmaXJzdCB2YWx1ZSBhbmQgaWdub3JlcyBkdXBsaWNhdGVzCiAgICAgIGF3ayAtRj0gJyFsaW5lWyQxXSsrJwogICkgPiIke2NvbWJpbmVkQ29uZmlnRmlsZX0iIHx8IHJldHVybiAxCgogICMgaGF2ZSB0byBleHBvcnQgZXZlcnl0aGluZywgYW5kIHNvdXJjZSBpdCB0d2ljZToKICAjIDEpIGZpcnN0IHNvdXJjZSBpcyB0byByZWFsaXplIHZhcmlhYmxlcwogICMgMikgc2Vjb25kIHRpbWUgaXMgdG8gcmVhbGl6ZSByZWZlcmVuY2VzCiAgc2V0IC1vIGFsbGV4cG9ydAogICMgc2hlbGxjaGVjayBzb3VyY2U9LmZyYW1ld29yay1jb25maWcKICBzb3VyY2UgIiR7Y29tYmluZWRDb25maWdGaWxlfSIgfHwgcmV0dXJuIDMKICAjIHNoZWxsY2hlY2sgc291cmNlPS5mcmFtZXdvcmstY29uZmlnCiAgc291cmNlICIke2NvbWJpbmVkQ29uZmlnRmlsZX0iIHx8IHJldHVybiAzCiAgc2V0ICtvIGFsbGV4cG9ydAp9CgojIEBkZXNjcmlwdGlvbiBEaXNwbGF5IG1lc3NhZ2UgdXNpbmcgc2tpcCBjb2xvciAoeWVsbG93KQojIEBhcmcgJDEgbWVzc2FnZTpTdHJpbmcgdGhlIG1lc3NhZ2UgdG8gZGlzcGxheQpMb2c6OmRpc3BsYXlTa2lwcGVkKCkgewogIGlmICgoQkFTSF9GUkFNRVdPUktfRElTUExBWV9MRVZFTCA+PSBfX0xFVkVMX0lORk8pKTsgdGhlbgogICAgZWNobyAtZSAiJHtfX1NLSVBQRURfQ09MT1J9U0tJUFBFRCAtICR7MX0ke19fUkVTRVRfQ09MT1J9IiA+JjIKICBmaQogIExvZzo6bG9nU2tpcHBlZCAiJDEiCn0KCiMgQGRlc2NyaXB0aW9uIGxvZyBtZXNzYWdlIHRvIGZpbGUKIyBAYXJnICQxIG1lc3NhZ2U6U3RyaW5nIHRoZSBtZXNzYWdlIHRvIGRpc3BsYXkKTG9nOjpsb2dFcnJvcigpIHsKICBpZiAoKEJBU0hfRlJBTUVXT1JLX0xPR19MRVZFTCA+PSBfX0xFVkVMX0VSUk9SKSk7IHRoZW4KICAgIExvZzo6bG9nTWVzc2FnZSAiJHsyOi1FUlJPUn0iICIkMSIKICBmaQp9CgojIEBkZXNjcmlwdGlvbiBsb2cgbWVzc2FnZSB0byBmaWxlCiMgQGFyZyAkMSBtZXNzYWdlOlN0cmluZyB0aGUgbWVzc2FnZSB0byBkaXNwbGF5CkxvZzo6bG9nV2FybmluZygpIHsKICBpZiAoKEJBU0hfRlJBTUVXT1JLX0xPR19MRVZFTCA+PSBfX0xFVkVMX1dBUk5JTkcpKTsgdGhlbgogICAgTG9nOjpsb2dNZXNzYWdlICIkezI6LVdBUk5JTkd9IiAiJDEiCiAgZmkKfQoKIyBAZGVzY3JpcHRpb24gVG8gYmUgY2FsbGVkIGJlZm9yZSBsb2dnaW5nIGluIHRoZSBsb2cgZmlsZQojIEBhcmcgJDEgZmlsZTpzdHJpbmcgbG9nIGZpbGUgbmFtZQojIEBhcmcgJDIgbWF4TG9nRmlsZXNDb3VudDppbnQgbWF4aW11bSBudW1iZXIgb2YgbG9nIGZpbGVzCkxvZzo6cm90YXRlKCkgewogIGxvY2FsIGZpbGU9IiQxIgogIGxvY2FsIG1heExvZ0ZpbGVzQ291bnQ9IiR7MjotNX0iCgogIGlmIFtbICEgLWYgIiR7ZmlsZX0iIF1dOyB0aGVuCiAgICBMb2c6OmRpc3BsYXlTa2lwcGVkICJMb2cgZmlsZSAke2ZpbGV9IGRvZXNuJ3QgZXhpc3QgeWV0IgogICAgcmV0dXJuIDAKICBmaQogIGZvciBpIGluICQoc2VxICQoKG1heExvZ0ZpbGVzQ291bnQgLSAxKSkgLTEgMSk7IGRvCiAgICBMb2c6OmRpc3BsYXlJbmZvICJMb2cgcm90YXRpb24gJHtmaWxlfS4ke2l9IHRvICR7ZmlsZX0uJCgoaSArIDEpKSIKICAgIG12ICIke2ZpbGV9LiJ7IiR7aX0iLCIkKChpICsgMSkpIn0gJj4vZGV2L251bGwgfHwgdHJ1ZQogIGRvbmUKICBpZiBjcCAiJHtmaWxlfSIgIiR7ZmlsZX0uMSIgJj4vZGV2L251bGw7IHRoZW4KICAgIGVjaG8gPiIke2ZpbGV9IiAjIHJlc2V0IGxvZyBmaWxlCiAgICBMb2c6OmRpc3BsYXlJbmZvICJMb2cgcm90YXRpb24gJHtmaWxlfSB0byAke2ZpbGV9LjEiCiAgZmkKfQoKIyBAZGVzY3JpcHRpb24gZW5zdXJlIGNvbW1hbmQgcmVhbHBhdGggaXMgYXZhaWxhYmxlCiMgQGV4aXRjb2RlIDEgaWYgcmVhbHBhdGggY29tbWFuZCBub3QgYXZhaWxhYmxlCiMgQHN0ZGVyciBkaWFnbm9zdGljcyBpbmZvcm1hdGlvbiBpcyBkaXNwbGF5ZWQKTGludXg6OnJlcXVpcmVSZWFscGF0aENvbW1hbmQoKSB7CiAgQXNzZXJ0Ojpjb21tYW5kRXhpc3RzIHJlYWxwYXRoCn0KCiMgQGRlc2NyaXB0aW9uIGxvYWQgY29sb3IgdGhlbWUKIyBAbm9hcmdzCiMgQGVudiBCQVNIX0ZSQU1FV09SS19USEVNRSBTdHJpbmcgdGhlbWUgdG8gdXNlCiMgQGV4aXRjb2RlIDAgYWx3YXlzIHN1Y2Nlc3NmdWwKVUk6OnJlcXVpcmVUaGVtZSgpIHsKICBVSTo6dGhlbWUgIiR7QkFTSF9GUkFNRVdPUktfVEhFTUUtZGVmYXVsdH0iCn0KCiMgQGRlc2NyaXB0aW9uIGNoZWNrIGlmIGNvbW1hbmQgc3BlY2lmaWVkIGV4aXN0cyBvciByZXR1cm4gMQojIHdpdGggZXJyb3IgYW5kIG1lc3NhZ2UgaWYgbm90CiMKIyBAYXJnICQxIGNvbW1hbmROYW1lOlN0cmluZyBvbiB3aGljaCBleGlzdGVuY2UgbXVzdCBiZSBjaGVja2VkCiMgQGFyZyAkMiBoZWxwSWZOb3RFeGlzdHM6U3RyaW5nIGEgaGVscCBjb21tYW5kIHRvIGRpc3BsYXkgaWYgdGhlIGNvbW1hbmQgZG9lcyBub3QgZXhpc3QKIwojIEBleGl0Y29kZSAxIGlmIHRoZSBjb21tYW5kIHNwZWNpZmllZCBkb2VzIG5vdCBleGlzdAojIEBzdGRlcnIgZGlhZ25vc3RpYyBpbmZvcm1hdGlvbiArIGhlbHAgaWYgc2Vjb25kIGFyZ3VtZW50IGlzIHByb3ZpZGVkCkFzc2VydDo6Y29tbWFuZEV4aXN0cygpIHsKICBsb2NhbCBjb21tYW5kTmFtZT0iJDEiCiAgbG9jYWwgaGVscElmTm90RXhpc3RzPSIkMiIKCiAgIiR7QkFTSF9GUkFNRVdPUktfQ09NTUFORDotY29tbWFuZH0iIC12ICIke2NvbW1hbmROYW1lfSIgPi9kZXYvbnVsbCAyPi9kZXYvbnVsbCB8fCB7CiAgICBMb2c6OmRpc3BsYXlFcnJvciAiJHtjb21tYW5kTmFtZX0gaXMgbm90IGluc3RhbGxlZCwgcGxlYXNlIGluc3RhbGwgaXQiCiAgICBpZiBbWyAtbiAiJHtoZWxwSWZOb3RFeGlzdHN9IiBdXTsgdGhlbgogICAgICBMb2c6OmRpc3BsYXlJbmZvICIke2hlbHBJZk5vdEV4aXN0c30iCiAgICBmaQogICAgcmV0dXJuIDEKICB9CiAgcmV0dXJuIDAKfQoKIyBAZGVzY3JpcHRpb24gZGVmYXVsdCBlbnYgZmlsZSB3aXRoIGFsbCBkZWZhdWx0IHZhbHVlcwojIEBzdGRvdXQgdGhlIGRlZmF1bHQgZW52IGZpbGVwYXRoCkVudjo6Y3JlYXRlRGVmYXVsdEVudkZpbGUoKSB7CiAgbG9jYWwgZW52RmlsZQogIGVudkZpbGU9IiQoRnJhbWV3b3JrOjpjcmVhdGVUZW1wRmlsZSAiY3JlYXRlRGVmYXVsdEVudkZpbGVFbnZGaWxlIikiIHx8IHJldHVybiAyCgogICgKICAgIGVjaG8gIkJBU0hfRlJBTUVXT1JLX1RIRU1FPSR7QkFTSF9GUkFNRVdPUktfVEhFTUU6LWRlZmF1bHR9IgogICAgZWNobyAiQkFTSF9GUkFNRVdPUktfTE9HX0xFVkVMPSR7QkFTSF9GUkFNRVdPUktfTE9HX0xFVkVMOi0wfSIKICAgIGVjaG8gIkJBU0hfRlJBTUVXT1JLX0RJU1BMQVlfTEVWRUw9JHtCQVNIX0ZSQU1FV09SS19ESVNQTEFZX0xFVkVMOi0ke19fTEVWRUxfV0FSTklOR319IgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDE2CiAgICBlY2hvICdCQVNIX0ZSQU1FV09SS19MT0dfRklMRT0iJHtCQVNIX0ZSQU1FV09SS19MT0dfRklMRTotIiR7RlJBTUVXT1JLX1JPT1RfRElSfS9sb2dzLyR7U0NSSVBUX05BTUV9LmxvZyJ9IicKICAgIGVjaG8gIkJBU0hfRlJBTUVXT1JLX0xPR19GSUxFX01BWF9ST1RBVElPTj0ke0JBU0hfRlJBTUVXT1JLX0xPR19GSUxFX01BWF9ST1RBVElPTjotNX0iCiAgKSA+IiR7ZW52RmlsZX0iCiAgZWNobyAiJHtlbnZGaWxlfSIKfQoKIyBAZGVzY3JpcHRpb24gcmVtb3ZlIGNvbW1lbnQgbGluZXMgZnJvbSBpbnB1dCBvciBmaWxlcyBwcm92aWRlZCBhcyBhcmd1bWVudHMKIyBAYXJnICRAIGZpbGVzOlN0cmluZ1tdIChvcHRpb25hbCkgdGhlIGZpbGVzIHRvIGZpbHRlcgojIEBlbnYgY29tbWVudExpbmVQcmVmaXggU3RyaW5nIHRoZSBjb21tZW50IGxpbmUgcHJlZml4IChkZWZhdWx0IHZhbHVlOiAjKQojIEBleGl0Y29kZSAwIGlmIGxpbmVzIGZpbHRlcmVkIG9yIG5vdAojIEBleGl0Y29kZSAyIGlmIGdyZXAgZmFpbHMgZm9yIGFueSBvdGhlciByZWFzb25zIHRoYW4gbm90IGZvdW5kCiMgQHN0ZGluIHRoZSBmaWxlIGFzIHN0ZGluIHRvIGZpbHRlciAoYWx0ZXJuYXRpdmUgdG8gZmlsZXMgYXJndW1lbnQpCiMgQHN0ZG91dCB0aGUgZmlsdGVyZWQgbGluZXMKIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMTIwCkZpbHRlcnM6OmNvbW1lbnRMaW5lcygpIHsKICBncmVwIC12eEUgIltbOmJsYW5rOl1dKigke2NvbW1lbnRMaW5lUHJlZml4Oi0jfS4qKT8iICIkQCIgfHwgdGVzdCAkPyA9IDEKfQoKIyBAZGVzY3JpcHRpb24gY3JlYXRlIGEgdGVtcCBmaWxlIHVzaW5nIGRlZmF1bHQgVE1QRElSIHZhcmlhYmxlCiMgaW5pdGlhbGl6ZWQgaW4gX2luY2x1ZGVzL19jb21tb25IZWFkZXIuc2gKIyBAZW52IFRNUERJUiBTdHJpbmcgKGRlZmF1bHQgdmFsdWUgL3RtcCkKIyBAYXJnICQxIHRlbXBsYXRlTmFtZTpTdHJpbmcgdGVtcGxhdGUgbmFtZSB0byB1c2Uob3B0aW9uYWwpCkZyYW1ld29yazo6Y3JlYXRlVGVtcEZpbGUoKSB7CiAgbWt0ZW1wIC1wICIke1RNUERJUjotL3RtcH0iIC10ICIkezE6LX0uWFhYWFhYWFhYWFhYIgp9CgojIEBkZXNjcmlwdGlvbiBsb2cgbWVzc2FnZSB0byBmaWxlCiMgQGFyZyAkMSBtZXNzYWdlOlN0cmluZyB0aGUgbWVzc2FnZSB0byBkaXNwbGF5CkxvZzo6bG9nU2tpcHBlZCgpIHsKICBpZiAoKEJBU0hfRlJBTUVXT1JLX0xPR19MRVZFTCA+PSBfX0xFVkVMX0lORk8pKTsgdGhlbgogICAgTG9nOjpsb2dNZXNzYWdlICIkezI6LVNLSVBQRUR9IiAiJDEiCiAgZmkKfQoKIyBAZGVzY3JpcHRpb24gbG9hZCBjb2xvcnMgdGhlbWUgY29uc3RhbnRzCiMgQHdhcm5pbmcgaWYgdHR5IG5vdCBvcGVuZWQsIG5vQ29sb3IgdGhlbWUgd2lsbCBiZSBjaG9zZW4KIyBAYXJnICQxIHRoZW1lOlN0cmluZyB0aGUgdGhlbWUgdG8gdXNlIChkZWZhdWx0LCBub0NvbG9yKQojIEBhcmcgJEAgYXJnczpTdHJpbmdbXQojIEBzZXQgX19FUlJPUl9DT0xPUiBTdHJpbmcgaW5kaWNhdGUgZXJyb3Igc3RhdHVzCiMgQHNldCBfX0lORk9fQ09MT1IgU3RyaW5nIGluZGljYXRlIGluZm8gc3RhdHVzCiMgQHNldCBfX1NVQ0NFU1NfQ09MT1IgU3RyaW5nIGluZGljYXRlIHN1Y2Nlc3Mgc3RhdHVzCiMgQHNldCBfX1dBUk5JTkdfQ09MT1IgU3RyaW5nIGluZGljYXRlIHdhcm5pbmcgc3RhdHVzCiMgQHNldCBfX1NLSVBQRURfQ09MT1IgU3RyaW5nIGluZGljYXRlIHNraXBwZWQgc3RhdHVzCiMgQHNldCBfX0RFQlVHX0NPTE9SIFN0cmluZyBpbmRpY2F0ZSBkZWJ1ZyBzdGF0dXMKIyBAc2V0IF9fSEVMUF9DT0xPUiBTdHJpbmcgaW5kaWNhdGUgaGVscCBzdGF0dXMKIyBAc2V0IF9fVEVTVF9DT0xPUiBTdHJpbmcgbm90IHVzZWQKIyBAc2V0IF9fVEVTVF9FUlJPUl9DT0xPUiBTdHJpbmcgbm90IHVzZWQKIyBAc2V0IF9fSEVMUF9USVRMRV9DT0xPUiBTdHJpbmcgdXNlZCB0byBkaXNwbGF5IGhlbHAgdGl0bGUgaW4gaGVscCBzdHJpbmdzCiMgQHNldCBfX0hFTFBfT1BUSU9OX0NPTE9SIFN0cmluZyB1c2VkIHRvIGRpc3BsYXkgaGlnaGxpZ2h0IG9wdGlvbnMgaW4gaGVscCBzdHJpbmdzCiMKIyBAc2V0IF9fUkVTRVRfQ09MT1IgU3RyaW5nIHJlc2V0IGRlZmF1bHQgY29sb3IKIwojIEBzZXQgX19IRUxQX0VYQU1QTEUgU3RyaW5nIHRvIHJlbW92ZQojIEBzZXQgX19IRUxQX1RJVExFIFN0cmluZyB0byByZW1vdmUKIyBAc2V0IF9fSEVMUF9OT1JNQUwgU3RyaW5nIHRvIHJlbW92ZQojIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKVUk6OnRoZW1lKCkgewogIGxvY2FsIHRoZW1lPSIkezEtZGVmYXVsdH0iCiAgaWYgW1sgISAiJHt0aGVtZX0iID1+IC1mb3JjZSQgXV0gJiYgISBBc3NlcnQ6OnR0eTsgdGhlbgogICAgdGhlbWU9Im5vQ29sb3IiCiAgZmkKICBjYXNlICIke3RoZW1lfSIgaW4KICAgIGRlZmF1bHQgfCBkZWZhdWx0LWZvcmNlKQogICAgICB0aGVtZT0iZGVmYXVsdCIKICAgICAgOzsKICAgIG5vQ29sb3IpIDs7CiAgICAqKQogICAgICBMb2c6OmZhdGFsICJpbnZhbGlkIHRoZW1lIHByb3ZpZGVkIgogICAgICA7OwogIGVzYWMKICBpZiBbWyAiJHt0aGVtZX0iID0gImRlZmF1bHQiIF1dOyB0aGVuCiAgICBCQVNIX0ZSQU1FV09SS19USEVNRT0iZGVmYXVsdCIKICAgICMgY2hlY2sgY29sb3JzIGFwcGxpY2FibGUgaHR0cHM6Ly9taXNjLmZsb2dpc29mdC5jb20vYmFzaC90aXBfY29sb3JzX2FuZF9mb3JtYXR0aW5nCiAgICBfX0VSUk9SX0NPTE9SPSdcZVszMW0nICAgICAgICAgIyBSZWQKICAgIF9fSU5GT19DT0xPUj0nXGVbNDRtJyAgICAgICAgICAjIHdoaXRlIG9uIGxpZ2h0Qmx1ZQogICAgX19TVUNDRVNTX0NPTE9SPSdcZVszMm0nICAgICAgICMgR3JlZW4KICAgIF9fV0FSTklOR19DT0xPUj0nXGVbMzNtJyAgICAgICAjIFllbGxvdwogICAgX19TS0lQUEVEX0NPTE9SPSdcZVszM20nICAgICAgICMgWWVsbG93CiAgICBfX0RFQlVHX0NPTE9SPSdcZVszN20nICAgICAgICAgIyBHcmV5CiAgICBfX0hFTFBfQ09MT1I9J1xlWzc7NDk7MzNtJyAgICAgIyBCbGFjayBvbiBHb2xkCiAgICBfX1RFU1RfQ09MT1I9J1xlWzEwMG0nICAgICAgICAgIyBMaWdodCBtYWdlbnRhCiAgICBfX1RFU1RfRVJST1JfQ09MT1I9J1xlWzQxbScgICAgIyB3aGl0ZSBvbiByZWQKICAgIF9fSEVMUF9USVRMRV9DT0xPUj0iXGVbMTszN20iICAjIEJvbGQKICAgIF9fSEVMUF9PUFRJT05fQ09MT1I9IlxlWzE7MzRtIiAjIEJsdWUKICAgICMgSW50ZXJuYWw6IHJlc2V0IGNvbG9yCiAgICBfX1JFU0VUX0NPTE9SPSdcZVswbScgIyBSZXNldCBDb2xvcgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMTU1LFNDMjAzNAogICAgX19IRUxQX0VYQU1QTEU9IiQoZWNobyAtZSAiXGVbMjs5N20iKSIKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjE1NSxTQzIwMzQKICAgIF9fSEVMUF9USVRMRT0iJChlY2hvIC1lICJcZVsxOzM3bSIpIgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMTU1LFNDMjAzNAogICAgX19IRUxQX05PUk1BTD0iJChlY2hvIC1lICJcMDMzWzBtIikiCiAgZWxzZQogICAgQkFTSF9GUkFNRVdPUktfVEhFTUU9Im5vQ29sb3IiCiAgICAjIGNoZWNrIGNvbG9ycyBhcHBsaWNhYmxlIGh0dHBzOi8vbWlzYy5mbG9naXNvZnQuY29tL2Jhc2gvdGlwX2NvbG9yc19hbmRfZm9ybWF0dGluZwogICAgX19FUlJPUl9DT0xPUj0nJwogICAgX19JTkZPX0NPTE9SPScnCiAgICBfX1NVQ0NFU1NfQ09MT1I9JycKICAgIF9fV0FSTklOR19DT0xPUj0nJwogICAgX19TS0lQUEVEX0NPTE9SPScnCiAgICBfX0RFQlVHX0NPTE9SPScnCiAgICBfX0hFTFBfQ09MT1I9JycKICAgIF9fVEVTVF9DT0xPUj0nJwogICAgX19URVNUX0VSUk9SX0NPTE9SPScnCiAgICBfX0hFTFBfVElUTEVfQ09MT1I9JycKICAgIF9fSEVMUF9PUFRJT05fQ09MT1I9JycKICAgICMgSW50ZXJuYWw6IHJlc2V0IGNvbG9yCiAgICBfX1JFU0VUX0NPTE9SPScnCiAgICBfX0hFTFBfRVhBTVBMRT0nJwogICAgX19IRUxQX1RJVExFPScnCiAgICBfX0hFTFBfTk9STUFMPScnCiAgZmkKfQoKIyBAZGVzY3JpcHRpb24gY2hlY2sgaWYgdHR5IChpbnRlcmFjdGl2ZSBtb2RlKSBpcyBhY3RpdmUKIyBAbm9hcmdzCiMgQGV4aXRjb2RlIDEgaWYgdHR5IG5vdCBhY3RpdmUKIyBAZW52IE5PTl9JTlRFUkFDVElWRSBpZiAxIGNvbnNpZGVyIGFzIG5vdCBpbnRlcmFjdGl2ZSBldmVuIGlmIGVudmlyb25tZW50IGlzIGludGVyYWN0aXZlCiMgQGVudiBJTlRFUkFDVElWRSBpZiAxIGNvbnNpZGVyIGFzIGludGVyYWN0aXZlIGV2ZW4gaWYgZW52aXJvbm1lbnQgaXMgbm90IGludGVyYWN0aXZlCiMgQHN0ZGVyciBkaWFnbm9zdGljIGluZm9ybWF0aW9uICsgaGVscCBpZiBzZWNvbmQgYXJndW1lbnQgaXMgcHJvdmlkZWQKQXNzZXJ0Ojp0dHkoKSB7CiAgaWYgW1sgIiR7Tk9OX0lOVEVSQUNUSVZFOi0wfSIgPSAiMSIgXV07IHRoZW4KICAgIHJldHVybiAxCiAgZmkKICBpZiBbWyAiJHtJTlRFUkFDVElWRTotMH0iID0gIjEiIF1dOyB0aGVuCiAgICByZXR1cm4gMAogIGZpCiAgW1sgLXQgMSB8fCAtdCAyIF1dCn0KCiMgRlVOQ1RJT05TCgpmYWNhZGVfbWFpbl9lbWJlZEZyYW1ld29ya0Z1bmN0aW9uYmluRmlsZXRwbCgpIHsKIyBSRVFVSVJFUwpMaW51eDo6cmVxdWlyZUV4ZWN1dGVkQXNVc2VyCkVudjo6cmVxdWlyZUxvYWQKTG9nOjpyZXF1aXJlTG9hZApMaW51eDo6cmVxdWlyZVJlYWxwYXRoQ29tbWFuZApVSTo6cmVxdWlyZVRoZW1lCkNvbXBpbGVyOjpGYWNhZGU6OnJlcXVpcmVDb21tYW5kQmluRGlyCgojIEByZXF1aXJlIENvbXBpbGVyOjpGYWNhZGU6OnJlcXVpcmVDb21tYW5kQmluRGlyCgojIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIxNTQsU0MyMDE2CmZ1bmN0aW9uVG9DYWxsPSdEYjo6cXVlcnlPbmVEYXRhYmFzZScKIiR7ZnVuY3Rpb25Ub0NhbGx9IiAiJEAiCgp9CgpmYWNhZGVfbWFpbl9lbWJlZEZyYW1ld29ya0Z1bmN0aW9uYmluRmlsZXRwbCAiJEAiCg==" Compiler::Embed::extractFileFromBase64 \ "${embed_function_DbQueryOneDatabase}" \ "${encoded_binary_file_DbQueryOneDatabase}" -facade_main_18f5ddcf2cbe4feba7e4cda5e715c153() { +facade_main_dbScriptAllDatabasessh() { BASH_TOOLS_ROOT_DIR="$(cd "${CURRENT_DIR}/.." && pwd -P)" if [[ -d "${BASH_TOOLS_ROOT_DIR}/vendor/bash-tools-framework/" ]]; then FRAMEWORK_ROOT_DIR="$(cd "${BASH_TOOLS_ROOT_DIR}/vendor/bash-tools-framework" && pwd -P)" @@ -2204,4 +2204,4 @@ fi } -facade_main_18f5ddcf2cbe4feba7e4cda5e715c153 "$@" +facade_main_dbScriptAllDatabasessh "$@" diff --git a/bin/doc b/bin/doc index be641d9d..1a773670 100755 --- a/bin/doc +++ b/bin/doc @@ -940,7 +940,7 @@ Array::contains() { # FUNCTIONS -facade_main_8fd47ebedea14305a1452a7b8820b174() { +facade_main_docsh() { BASH_TOOLS_ROOT_DIR="$(cd "${CURRENT_DIR}/.." && pwd -P)" if [[ -d "${BASH_TOOLS_ROOT_DIR}/vendor/bash-tools-framework/" ]]; then FRAMEWORK_ROOT_DIR="$(cd "${BASH_TOOLS_ROOT_DIR}/vendor/bash-tools-framework" && pwd -P)" @@ -1708,4 +1708,4 @@ fi } -facade_main_8fd47ebedea14305a1452a7b8820b174 "$@" +facade_main_docsh "$@" diff --git a/bin/gitIsAncestorOf b/bin/gitIsAncestorOf index 15206ac2..e19f3ad2 100755 --- a/bin/gitIsAncestorOf +++ b/bin/gitIsAncestorOf @@ -827,7 +827,7 @@ Array::contains() { # FUNCTIONS -facade_main_8f16db2b392c4f27975664b203757d91() { +facade_main_gitIsAncestorOfsh() { BASH_TOOLS_ROOT_DIR="$(cd "${CURRENT_DIR}/.." && pwd -P)" if [[ -d "${BASH_TOOLS_ROOT_DIR}/vendor/bash-tools-framework/" ]]; then FRAMEWORK_ROOT_DIR="$(cd "${BASH_TOOLS_ROOT_DIR}/vendor/bash-tools-framework" && pwd -P)" @@ -1552,4 +1552,4 @@ fi } -facade_main_8f16db2b392c4f27975664b203757d91 "$@" +facade_main_gitIsAncestorOfsh "$@" diff --git a/bin/gitIsBranch b/bin/gitIsBranch index 8295f9de..28ec6a54 100755 --- a/bin/gitIsBranch +++ b/bin/gitIsBranch @@ -827,7 +827,7 @@ Array::contains() { # FUNCTIONS -facade_main_5c164a34fb6c464a90667d094e1f3bef() { +facade_main_gitIsBranchsh() { BASH_TOOLS_ROOT_DIR="$(cd "${CURRENT_DIR}/.." && pwd -P)" if [[ -d "${BASH_TOOLS_ROOT_DIR}/vendor/bash-tools-framework/" ]]; then FRAMEWORK_ROOT_DIR="$(cd "${BASH_TOOLS_ROOT_DIR}/vendor/bash-tools-framework" && pwd -P)" @@ -1518,4 +1518,4 @@ fi } -facade_main_5c164a34fb6c464a90667d094e1f3bef "$@" +facade_main_gitIsBranchsh "$@" diff --git a/bin/gitRenameBranch b/bin/gitRenameBranch index 29b3af53..ee9aaf01 100755 --- a/bin/gitRenameBranch +++ b/bin/gitRenameBranch @@ -849,7 +849,7 @@ Array::contains() { # FUNCTIONS -facade_main_a7456d3b93ad4a0cb0c417608cfc15d7() { +facade_main_gitRenameBranchsh() { BASH_TOOLS_ROOT_DIR="$(cd "${CURRENT_DIR}/.." && pwd -P)" if [[ -d "${BASH_TOOLS_ROOT_DIR}/vendor/bash-tools-framework/" ]]; then FRAMEWORK_ROOT_DIR="$(cd "${BASH_TOOLS_ROOT_DIR}/vendor/bash-tools-framework" && pwd -P)" @@ -1708,4 +1708,4 @@ fi } -facade_main_a7456d3b93ad4a0cb0c417608cfc15d7 "$@" +facade_main_gitRenameBranchsh "$@" diff --git a/bin/installRequirements b/bin/installRequirements index f6a3b8f5..f55e72a6 100755 --- a/bin/installRequirements +++ b/bin/installRequirements @@ -922,7 +922,7 @@ Assert::commandExists() { # FUNCTIONS -facade_main_ae2d7ee85d7a47bdbda1838afc5f3c2c() { +facade_main_installRequirementssh() { BASH_TOOLS_ROOT_DIR="$(cd "${CURRENT_DIR}/.." && pwd -P)" if [[ -d "${BASH_TOOLS_ROOT_DIR}/vendor/bash-tools-framework/" ]]; then FRAMEWORK_ROOT_DIR="$(cd "${BASH_TOOLS_ROOT_DIR}/vendor/bash-tools-framework" && pwd -P)" @@ -1552,7 +1552,7 @@ installRequirementsCommand() { INSTALLS REQUIREMENTS: - fchastanet/bash-tools-framework - and fchastanet/bash-tools-framework useful binaries: - bin/awkLint, bin/buildBinFiles, bin/frameworkLint, bin/findShebangFiles, bin/megalinter, bin/runBuildContainer, bin/shellcheckLint, bin/test, bin/buildPushDockerImage""" + bin/runBuildContainer, bin/test""" echo echo -n -e "${__HELP_TITLE_COLOR}VERSION: ${__RESET_COLOR}" echo '1.0' @@ -1572,7 +1572,7 @@ installRequirementsCommand() { return 1 fi } -declare -a externalBinaries=([0]="bin/awkLint" [1]="bin/buildBinFiles" [2]="bin/frameworkLint" [3]="bin/findShebangFiles" [4]="bin/megalinter" [5]="bin/runBuildContainer" [6]="bin/shellcheckLint" [7]="bin/test" [8]="bin/buildPushDockerImage") +declare -a externalBinaries=([0]="bin/runBuildContainer" [1]="bin/test") installRequirementsCommand parse "${BASH_FRAMEWORK_ARGV[@]}" @@ -1599,4 +1599,4 @@ fi } -facade_main_ae2d7ee85d7a47bdbda1838afc5f3c2c "$@" +facade_main_installRequirementssh "$@" diff --git a/bin/mysql2puml b/bin/mysql2puml index eccbd84e..54e7f1fb 100755 --- a/bin/mysql2puml +++ b/bin/mysql2puml @@ -1001,7 +1001,7 @@ Assert::commandExists() { # FUNCTIONS -facade_main_0c81f03399944490b21f8ac30d7e073b() { +facade_main_mysql2pumlsh() { BASH_TOOLS_ROOT_DIR="$(cd "${CURRENT_DIR}/.." && pwd -P)" if [[ -d "${BASH_TOOLS_ROOT_DIR}/vendor/bash-tools-framework/" ]]; then FRAMEWORK_ROOT_DIR="$(cd "${BASH_TOOLS_ROOT_DIR}/vendor/bash-tools-framework" && pwd -P)" @@ -1983,4 +1983,4 @@ fi } -facade_main_0c81f03399944490b21f8ac30d7e073b "$@" +facade_main_mysql2pumlsh "$@" diff --git a/bin/upgradeGithubRelease b/bin/upgradeGithubRelease index 0edf5c04..bdf51ca0 100755 --- a/bin/upgradeGithubRelease +++ b/bin/upgradeGithubRelease @@ -1135,7 +1135,7 @@ Assert::commandExists() { # FUNCTIONS -facade_main_24dcc22b6cc8473babfc796abe45df9b() { +facade_main_upgradeGithubReleasesh() { BASH_TOOLS_ROOT_DIR="$(cd "${CURRENT_DIR}/.." && pwd -P)" if [[ -d "${BASH_TOOLS_ROOT_DIR}/vendor/bash-tools-framework/" ]]; then FRAMEWORK_ROOT_DIR="$(cd "${BASH_TOOLS_ROOT_DIR}/vendor/bash-tools-framework" && pwd -P)" @@ -2117,4 +2117,4 @@ fi } -facade_main_24dcc22b6cc8473babfc796abe45df9b "$@" +facade_main_upgradeGithubReleasesh "$@" diff --git a/bin/waitForIt b/bin/waitForIt index 41068c7f..460b992c 100755 --- a/bin/waitForIt +++ b/bin/waitForIt @@ -840,7 +840,7 @@ Log::logSkipped() { # FUNCTIONS -facade_main_d396e2bc1f6e43a7b79e8a25ad41ac25() { +facade_main_waitForItsh() { BASH_TOOLS_ROOT_DIR="$(cd "${CURRENT_DIR}/.." && pwd -P)" if [[ -d "${BASH_TOOLS_ROOT_DIR}/vendor/bash-tools-framework/" ]]; then FRAMEWORK_ROOT_DIR="$(cd "${BASH_TOOLS_ROOT_DIR}/vendor/bash-tools-framework" && pwd -P)" @@ -1854,4 +1854,4 @@ fi } -facade_main_d396e2bc1f6e43a7b79e8a25ad41ac25 "$@" +facade_main_waitForItsh "$@" diff --git a/bin/waitForMysql b/bin/waitForMysql index 6516a2c9..86db4069 100755 --- a/bin/waitForMysql +++ b/bin/waitForMysql @@ -840,7 +840,7 @@ Array::contains() { # FUNCTIONS -facade_main_665f5dabe75f418ea1c10f53fac6da5e() { +facade_main_waitForMysqlsh() { BASH_TOOLS_ROOT_DIR="$(cd "${CURRENT_DIR}/.." && pwd -P)" if [[ -d "${BASH_TOOLS_ROOT_DIR}/vendor/bash-tools-framework/" ]]; then FRAMEWORK_ROOT_DIR="$(cd "${BASH_TOOLS_ROOT_DIR}/vendor/bash-tools-framework" && pwd -P)" @@ -1663,4 +1663,4 @@ fi } -facade_main_665f5dabe75f418ea1c10f53fac6da5e "$@" +facade_main_waitForMysqlsh "$@" diff --git a/conf/dbScripts/extractData b/conf/dbScripts/extractData index f31cf2d2..53bf2742 100755 --- a/conf/dbScripts/extractData +++ b/conf/dbScripts/extractData @@ -864,7 +864,7 @@ Assert::tty() { # FUNCTIONS -facade_main_6e8b53ac69594d439449db19aae37378() { +facade_main_extractDatash() { # REQUIRES Linux::requireRealpathCommand Env::requireLoad @@ -951,4 +951,4 @@ run } -facade_main_6e8b53ac69594d439449db19aae37378 "$@" +facade_main_extractDatash "$@" diff --git a/install b/install index dba0adf6..278a454c 100755 --- a/install +++ b/install @@ -827,7 +827,7 @@ Array::contains() { # FUNCTIONS -facade_main_ddde11adc18142a8b5cc63d0041ff1b9() { +facade_main_installsh() { BASH_TOOLS_ROOT_DIR="$(cd "${CURRENT_DIR}/." && pwd -P)" if [[ -d "${BASH_TOOLS_ROOT_DIR}/vendor/bash-tools-framework/" ]]; then FRAMEWORK_ROOT_DIR="$(cd "${BASH_TOOLS_ROOT_DIR}/vendor/bash-tools-framework" && pwd -P)" @@ -1513,4 +1513,4 @@ fi } -facade_main_ddde11adc18142a8b5cc63d0041ff1b9 "$@" +facade_main_installsh "$@" diff --git a/src/_binaries/DbImport/dbImportProfile.bats b/src/_binaries/DbImport/dbImportProfile.bats index 320a65a8..9a40d19f 100755 --- a/src/_binaries/DbImport/dbImportProfile.bats +++ b/src/_binaries/DbImport/dbImportProfile.bats @@ -98,7 +98,10 @@ function Database::dbImportProfile::remote_db_fully_functional_default_ratio { # run "${binDir}/dbImportProfile" --verbose -f default.local fromDb 2>&1 [[ -f "${HOME}/tableSizeQuery.sql" ]] - assert_output --partial "Profile generated - 1/3 tables bigger than 70% of max table size (29MB) automatically excluded" + assert_lines_count 3 + assert_line --index 0 --partial "INFO - Using from dsn" + assert_line --index 1 --partial "INFO - Profile generated - 1/3 tables bigger than 70% of max table size (29MB) automatically excluded" + assert_line --index 2 --partial "INFO - File saved" diff >&3 "${HOME}/tableSizeQuery.sql" "${BATS_TEST_DIRNAME}/testsData/expectedDbImportProfileTableListQuery.sql" [[ -f "${HOME}/.bash-tools/dbImportProfiles/auto_default.local_fromDb.sh" ]] diff -u "${HOME}/.bash-tools/dbImportProfiles/auto_default.local_fromDb.sh" \ diff --git a/src/_binaries/Utils/waitForMysql.bats b/src/_binaries/Utils/waitForMysql.bats index 58dfff32..6bd011a9 100755 --- a/src/_binaries/Utils/waitForMysql.bats +++ b/src/_binaries/Utils/waitForMysql.bats @@ -93,6 +93,6 @@ function Utils::waitForMysql::mysqlNotAvailableAfter1SecondTimeout { #@test assert_failure 2 assert_line --index 0 --partial "INFO - Waiting for mysql" assert_line --index 1 --partial "." - assert_line --index 2 --partial "ERROR - waitForMysql - timeout for localhost:3306 occurred after 1 seconds" + assert_line --index 2 --partial "ERROR - waitForMysql - timeout for localhost:3306 occurred after" assert_lines_count 3 } diff --git a/src/_binaries/build/installRequirements.options.tpl b/src/_binaries/build/installRequirements.options.tpl index 8697294e..02df895f 100644 --- a/src/_binaries/build/installRequirements.options.tpl +++ b/src/_binaries/build/installRequirements.options.tpl @@ -1,14 +1,7 @@ % declare -a externalBinaries=( - bin/awkLint - bin/buildBinFiles - bin/frameworkLint - bin/findShebangFiles - bin/megalinter bin/runBuildContainer - bin/shellcheckLint bin/test - bin/buildPushDockerImage ) declare versionNumber="1.0" declare commandFunctionName="installRequirementsCommand"