#!/usr/bin/env bash
# XepertV6 client; legacy DynamicV6 redirect-compatible.
# The public script contains no credential. Keep personalized compatibility downloads private.
# Usage: sudo bash dynamicv6-SERVICE.sh install|uninstall|status [--json|--format readable]
set -euo pipefail
umask 077
# Dependency bootstrap. Prompts read /dev/tty, never the incoming Bash script.
dvn_fail() {
    local message=$1
    if [[ ${dvn_json:-0} == 1 ]]; then
        message=${message//\\/\\\\}; message=${message//\"/\\\"}; message=${message//$'\n'/\\n}
        printf '{"error":"%s"}\n' "$message"
    else
        printf 'Error: %s\n' "$message" >&2
    fi
    return 1
}
dvn_find_python() {
    local candidate
    for candidate in python3 python3.14 python3.13 python3.12 python3.11 python3.10 python3.9 python3.8 /usr/bin/python3; do
        if command -v "$candidate" >/dev/null 2>&1 && "$candidate" -c 'import sys,ssl; sys.exit(0 if sys.version_info >= (3,8) else 1)' >/dev/null 2>&1; then
            command -v "$candidate"; return 0
        fi
    done
    return 1
}
dvn_has_iproute() { command -v ip >/dev/null 2>&1 && ip -j link show >/dev/null 2>&1; }
dvn_has_ca() {
    local bundle
    for bundle in /etc/ssl/certs/ca-certificates.crt /etc/pki/tls/certs/ca-bundle.crt /var/lib/ca-certificates/ca-bundle.pem /etc/ssl/cert.pem; do
        [[ -s $bundle ]] && return 0
    done
    return 1
}
dvn_os_info() {
    ID=unknown; ID_LIKE=; VERSION_ID=
    [[ ! -r /etc/os-release ]] || . /etc/os-release
}
dvn_package_manager() {
    local candidate
    case " $ID $ID_LIKE " in
        *debian*|*ubuntu*) command -v apt-get >/dev/null && { printf apt; return; };;
        *rhel*|*fedora*|*centos*)
            for candidate in dnf yum; do command -v "$candidate" >/dev/null && { printf '%s' "$candidate"; return; }; done;;
        *arch*) command -v pacman >/dev/null && { printf pacman; return; };;
        *suse*) command -v zypper >/dev/null && { printf zypper; return; };;
        *alpine*) command -v apk >/dev/null && { printf apk; return; };;
    esac
    for candidate in apt-get dnf yum pacman zypper apk; do
        if command -v "$candidate" >/dev/null; then [[ $candidate != apt-get ]] || candidate=apt; printf '%s' "$candidate"; return; fi
    done
    return 1
}
dvn_install_packages() {
    local manager=$1; shift
    case "$manager" in
        apt) apt-get update && env DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends "$@";;
        dnf|yum) "$manager" install -y "$@";;
        pacman) pacman -S --needed --noconfirm "$@";;
        zypper) zypper --non-interactive install --no-recommends "$@";;
        apk) apk add --no-cache "$@";;
        *) return 1;;
    esac
}
dvn_dependencies() {
    local action=$1 arg manager python_package=python3 ip_package=iproute2 missing_python=0 missing_ip=0 missing_ca=0 answer
    local -a packages=()
    dvn_python=$(dvn_find_python) || missing_python=1
    dvn_has_iproute || missing_ip=1
    if [[ $action != uninstall ]]; then
        missing_ca=1
        for arg in "$@"; do [[ $arg != --offline ]] || missing_ca=0; done
        if (( missing_ca )); then dvn_has_ca && missing_ca=0; fi
    fi
    if (( !missing_python && !missing_ip && !missing_ca )); then return 0; fi
    dvn_os_info
    manager=$(dvn_package_manager) || { dvn_fail 'Missing dependencies. Install Python 3.8+, full iproute2 and CA certificates with your system package manager.'; return 1; }
    if [[ $manager == dnf || $manager == yum ]]; then
        ip_package=iproute
        if [[ ${VERSION_ID%%.*} == 8 && " $ID $ID_LIKE " == *rhel* || $ID == centos && ${VERSION_ID%%.*} == 8 ]]; then python_package=python39; fi
    fi
    [[ $manager != pacman ]] || python_package=python
    if [[ $manager == zypper && $ID == opensuse-leap && ${VERSION_ID%%.*} == 15 ]]; then python_package=python311; fi
    (( !missing_python )) || packages+=("$python_package")
    (( !missing_ip )) || packages+=("$ip_package")
    (( !missing_ca )) || packages+=(ca-certificates)
    if ! { exec 4<>/dev/tty; } 2>/dev/null; then
        dvn_fail "Missing packages: ${packages[*]}. Re-run in an interactive terminal to approve installation; no packages were installed."
        return 1
    fi
    printf 'Required packages are missing: %s\nInstall them using %s? [y/N]: ' "${packages[*]}" "$manager" >&4
    IFS= read -r -u 4 answer || answer=n
    exec 4>&-
    case "$answer" in y|Y|yes|YES) ;; *) dvn_fail 'Package installation declined. No packages or client files were changed.'; return 1;; esac
    if ! dvn_install_packages "$manager" "${packages[@]}" >&2; then dvn_fail 'Package installation failed. Correct the package manager error and run the command again.'; return 1; fi
    dvn_python=$(dvn_find_python) || { dvn_fail 'Python 3.8 or newer with SSL support is required.'; return 1; }
    dvn_has_iproute || { dvn_fail 'Full iproute2 with JSON support is required; the BusyBox ip command is insufficient.'; return 1; }
    if (( missing_ca )) && ! dvn_has_ca; then dvn_fail 'CA certificates are still unavailable after package installation.'; return 1; fi
}

dvn_json=0
for arg in "$@"; do [[ $arg != --json && $arg != json && $arg != --format=json ]] || dvn_json=1; done
if [[ ${1:-} == --help || ${1:-} == -h ]]; then printf '%s
' 'Usage: curl -fsSL URL | bash -s -- install|uninstall|status [--json|--format readable] [--interface NIC] [--default native|leased|IP]'; exit 0; fi
[[ $(uname -s) == Linux ]] || { dvn_fail 'This client requires Linux.'; exit 1; }
[[ $EUID == 0 ]] || { dvn_fail 'Run as root, or pipe the command into sudo bash.'; exit 1; }
# Legacy timers invoke the cached script with a single interface argument.
if [[ $# -eq 1 && $1 != install && $1 != uninstall && $1 != status && $1 =~ ^[A-Za-z0-9_.:-]{1,15}$ && -d /sys/class/net/$1 ]]; then
    set -- install --interface "$1"
fi
if [[ $# -eq 0 ]]; then
    if ! { exec 3<>/dev/tty; } 2>/dev/null; then
        printf '%s
' 'No terminal available. Use: curl -fsSL URL | bash -s -- install|uninstall|status [--json]' >&2
        exit 2
    fi
    printf '%s
' '1. install' '2. uninstall' '3. status' >&3
    read -r -u 3 -p 'Select [1-3]: ' choice
    exec 3>&-
    case "$choice" in 1) set -- install --choose-default;; 2) set -- uninstall;; 3) set -- status;; *) exit 2;; esac
fi
case "$1" in install|uninstall|status) ;; *) dvn_fail 'Choose install, uninstall or status.'; exit 2;; esac
dvn_dependencies "$@" || exit 1
# A separate service must own the upgrade: cleanup stops the old oneshot service.
if [[ $1 == install ]] && grep -q '/dynamicv6-client.service' /proc/$$/cgroup; then
    source_script=${BASH_SOURCE[0]:-}
    [[ -f $source_script ]] || { dvn_fail 'Save this script to a file before upgrading from the legacy service.'; exit 1; }
    upgrade_dir=$(mktemp -d /run/xepertv6-upgrade.XXXXXXXX)
    cp -- "$source_script" "$upgrade_dir/client.sh"
    chmod 700 "$upgrade_dir"; chmod 600 "$upgrade_dir/client.sh"
    upgrade_env=()
    for name in DYNAMICV6_STATE_DIR DYNAMICV6_CLIENT_BIN_PATH; do
        [[ ! -v $name ]] || upgrade_env+=("--setenv=$name=${!name}")
    done
    cat > "$upgrade_dir/run.sh" <<'DVN_UPGRADE_RUNNER'
#!/usr/bin/env bash
script=$1; shift
trap 'rm -f -- "$script" "${script%/*}/run.sh"; rmdir -- "${script%/*}"' EXIT
/bin/bash "$script" "$@"
DVN_UPGRADE_RUNNER
    chmod 600 "$upgrade_dir/run.sh"
    if ! systemd-run --quiet --unit="xepertv6-upgrade-$$" "${upgrade_env[@]}" /bin/bash "$upgrade_dir/run.sh" "$upgrade_dir/client.sh" "$@"; then
        rm -f -- "$upgrade_dir/client.sh" "$upgrade_dir/run.sh"; rmdir -- "$upgrade_dir"; dvn_fail 'Could not start the independent upgrade service.'; exit 1
    fi
    printf '%s
' 'XepertV6 upgrade started in a separate service. Run status to check completion.'
    exit 0
fi
"$dvn_python" - "$@" <<'DVN_EMBEDDED_PYTHON'
import base64,hashlib,json,pathlib,sys,tempfile
config_text='__DVN_SERVICE_CONFIG__'
config=None if config_text.startswith('__DVN_') else json.loads(base64.b64decode(config_text))
payload={'dvn_guest.py': 'IyEvdXNyL2Jpbi9lbnYgcHl0aG9uMwoiIiJEeW5hbWljVjYgZ3Vlc3QgcmVjb25jaWxpYXRpb24gd2l0aCB2YWxpZGF0ZWQgZGVhZGxpbmVzIGFuZCBkdXJhYmxlIHJlY292ZXJ5LiIiIgppbXBvcnQgYXJncGFyc2UsIGNvcHksIGhhc2hsaWIsIGlwYWRkcmVzcywgbWF0aCwgcGF0aGxpYiwgcmFuZG9tLCB0aW1lCmZyb20gZHZuX2V2ZW50cyBpbXBvcnQgRXZlbnRMaXN0ZW5lcgpmcm9tIGR2bl9jb21tb24gaW1wb3J0IHNhdmUsIHJlYWQsIGxvY2ssIHBvc3QsIGlwdjYsIHZhbGlkX25hbWUsIGxvZwpmcm9tIGR2bl90cmFuc2FjdGlvbiBpbXBvcnQgS2VybmVsLCBKb3VybmFsLCBtYWtlX3JvdXRlLCBub3JtYWxpemVfcm91dGUsIG5ldHdvcmssIGtleV9zdHJpbmcKCmNsYXNzIEd1ZXN0OgogICAgZGVmIF9faW5pdF9fKHNlbGYsY2ZnLGtlcm5lbD1Ob25lKToKICAgICAgICBzZWxmLmNmZz1jZmc7c2VsZi5yb290PXBhdGhsaWIuUGF0aChjZmcuZ2V0KCdzdGF0ZV9kaXInLCcvdmFyL2xpYi9keW5hbWljdjYtbmV4dC1ndWVzdCcpKTtzZWxmLnJvb3QubWtkaXIocGFyZW50cz1UcnVlLGV4aXN0X29rPVRydWUpCiAgICAgICAgc2VsZi5pZmFjZT12YWxpZF9uYW1lKGNmZy5nZXQoJ2ludGVyZmFjZScsJ2V0aDAnKSk7c2VsZi5rZXJuZWw9a2VybmVsIG9yIEtlcm5lbChzZWxmLmlmYWNlKQogICAgICAgIHNlbGYuc3RhdGU9cmVhZChzZWxmLnJvb3QvJ3N0YXRlLmpzb24nLHsnYWRkcmVzc2VzJzp7fSwncnVsZXMnOltdLCd0YWJsZXMnOltdLCdyZXZpc2lvbic6MH0pCiAgICAgICAgc2VsZi5qb3VybmFsPUpvdXJuYWwoc2VsZi5yb290LHNlbGYua2VybmVsKTtzZWxmLmV2ZW50cz1FdmVudExpc3RlbmVyKGNmZywnZ3Vlc3QnKTtzZWxmLm5leHRfaW50ZXJ2YWw9Y2ZnLmdldCgnaW50ZXJ2YWwnLDUpCiAgICAgICAgaWYgc2VsZi5zdGF0ZS5nZXQoJ2ludGVyZmFjZScsc2VsZi5pZmFjZSkhPXNlbGYuaWZhY2U6cmFpc2UgUnVudGltZUVycm9yKCdTdGF0ZSBiZWxvbmdzIHRvIGFub3RoZXIgaW50ZXJmYWNlOyBjbGVhbiBpdCB1cCBiZWZvcmUgY2hhbmdpbmcgaW50ZXJmYWNlcycpCiAgICAgICAgaWYgc2VsZi5zdGF0ZS5nZXQoJ3V1aWQnKSBhbmQgc2VsZi5zdGF0ZVsndXVpZCddIT1jZmcuZ2V0KCd1dWlkJyk6cmFpc2UgUnVudGltZUVycm9yKCdTdGF0ZSBiZWxvbmdzIHRvIGFub3RoZXIgVk0nKQogICAgICAgIHNlbGYuZmFpbHVyZXM9MDtzZWxmLnBlbmRpbmdfa2V5PU5vbmU7c2VsZi5wZW5kaW5nX2F0dGVtcHRzPTA7c2VsZi5zdGFsZV9yZXBvcnRlZD1GYWxzZQoKICAgIGRlZiByZXRhaW5zX2Fzc2lnbm1lbnQoc2VsZixzdGF0ZSk6CiAgICAgICAgcmV0dXJuIHN0YXRlLmdldCgnYXNzaWdubWVudF9wcm90b2NvbCcpPT0yIGFuZCBib29sKHNlbGYuY2ZnLmdldCgndXVpZCcpKSBhbmQgc3RhdGUuZ2V0KCd1dWlkJyk9PXNlbGYuY2ZnWyd1dWlkJ10KCiAgICBkZWYgcmVtZW1iZXJfYXNzaWdubWVudChzZWxmLHN0YXRlLHBvbGljeSk6CiAgICAgICAgc3RhdGVbJ3V1aWQnXT1wb2xpY3lbJ3V1aWQnXTtzdGF0ZVsnYXNzaWdubWVudF9wcm90b2NvbCddPTIgaWYgcG9saWN5LmdldCgnYXNzaWdubWVudF9wcm90b2NvbCcpPT0yIGVsc2UgMQoKICAgIGRlZiBjaG9vc2VfZGVmYXVsdChzZWxmLGxlYXNlcyxuYXRpdmVfYXZhaWxhYmxlPVRydWUpOgogICAgICAgIHNlbGVjdGVkPXNlbGYuY2ZnLmdldCgnZGVmYXVsdCcsJ25hdGl2ZScpCiAgICAgICAgaWYgc2VsZWN0ZWQ9PSduYXRpdmUnOgogICAgICAgICAgICBpZiBuYXRpdmVfYXZhaWxhYmxlOnJldHVybiBOb25lCiAgICAgICAgICAgIHNlbGVjdGVkPSdsZWFzZWQnCiAgICAgICAgaWYgc2VsZWN0ZWQhPSdsZWFzZWQnOnJldHVybiBuZXh0KChsIGZvciBsIGluIGxlYXNlcyBpZiBsWydzbG90J109PXNlbGVjdGVkKSxOb25lKQogICAgICAgIGlmIG5vdCBsZWFzZXM6cmV0dXJuIE5vbmUKICAgICAgICBwcmVmZXJyZWRfc2xvdD1zZWxmLmNmZy5nZXQoJ2RlZmF1bHRfc2xvdF9pbmRleCcsMCk7cHJlZmVycmVkX3Bvb2w9c2VsZi5jZmcuZ2V0KCdkZWZhdWx0X3Bvb2xfaWQnKQogICAgICAgIGNhbmRpZGF0ZXM9W2wgZm9yIGwgaW4gbGVhc2VzIGlmIGwuZ2V0KCdzbG90X2luZGV4JywwKT09cHJlZmVycmVkX3Nsb3RdIG9yIGxpc3QobGVhc2VzKQogICAgICAgIHJldHVybiBtaW4oY2FuZGlkYXRlcyxrZXk9bGFtYmRhIGw6KGwuZ2V0KCdwb29sX2lkJykhPXByZWZlcnJlZF9wb29sLGxbJ2lwdjYnXSE9c2VsZi5zdGF0ZS5nZXQoJ21haW5fZHluYW1pYycpLGwuZ2V0KCdzbG90X2luZGV4JywwKSxsLmdldCgncG9vbF9pZCcsMCksbFsnaXB2NiddKSkKCiAgICBkZWYgdGFibGUoc2VsZixzbG90KTpyZXR1cm4gNDMwMDAraW50KGhhc2hsaWIuc2hhMjU2KHNsb3QuZW5jb2RlKCkpLmhleGRpZ2VzdCgpWzo0XSwxNiklODAwMAogICAgQHN0YXRpY21ldGhvZAogICAgZGVmIGRlYWRsaW5lX3ZhbGlkKHBvbGljeSk6CiAgICAgICAgdmFsdWU9cG9saWN5LmdldCgnZXhwaXJlc19hdCcpCiAgICAgICAgcmV0dXJuIHR5cGUodmFsdWUpIGluIChpbnQsZmxvYXQpIGFuZCBtYXRoLmlzZmluaXRlKHZhbHVlKSBhbmQgdmFsdWU+dGltZS50aW1lKCkKICAgIGRlZiB2YWxpZGF0ZShzZWxmLHAscGVuZGluZz1GYWxzZSk6CiAgICAgICAgaWYgbm90IGlzaW5zdGFuY2UocCxkaWN0KTpyYWlzZSBWYWx1ZUVycm9yKCdJbnZhbGlkIHBvbGljeSBvYmplY3QnKQogICAgICAgIGlmIHNlbGYuY2ZnLmdldCgndXVpZCcpIGFuZCBwLmdldCgndXVpZCcpIT1zZWxmLmNmZ1sndXVpZCddOnJhaXNlIFZhbHVlRXJyb3IoJ1ZNIG1pc21hdGNoJykKICAgICAgICBpZiBub3Qgc2VsZi5kZWFkbGluZV92YWxpZChwKTpyYWlzZSBWYWx1ZUVycm9yKCdQb2xpY3kgZGVhZGxpbmUgaXMgZXhwaXJlZCBvciBpbnZhbGlkJykKICAgICAgICBmb3Iga2V5IGluIFsnZXBvY2gnLCdyZXZpc2lvbiddOgogICAgICAgICAgICBpZiB0eXBlKHAuZ2V0KGtleSkpIGlzIG5vdCBpbnQgb3IgcFtrZXldPDE6cmFpc2UgVmFsdWVFcnJvcignSW52YWxpZCBwb2xpY3kgJytrZXkpCiAgICAgICAgICAgIHNlZW49c2VsZi5zdGF0ZS5nZXQoJ3NlZW5fJytrZXksc2VsZi5zdGF0ZS5nZXQoa2V5LDApKQogICAgICAgICAgICBpZiBwW2tleV08c2VlbjpyYWlzZSBWYWx1ZUVycm9yKCdTdGFsZSBwb2xpY3kgJytrZXkpCiAgICAgICAgaWYgcGVuZGluZzoKICAgICAgICAgICAgaWYgbm90IGlzaW5zdGFuY2UocC5nZXQoJ3JldGFpbl9hZGRyZXNzZXMnKSxsaXN0KTpyYWlzZSBWYWx1ZUVycm9yKCdNaXNzaW5nIHJldGFpbmVkLWFkZHJlc3MgbWVtYmVyc2hpcCcpCiAgICAgICAgICAgIHJldHVybiB7aXB2NihhKSBmb3IgYSBpbiBwWydyZXRhaW5fYWRkcmVzc2VzJ119CiAgICAgICAgaWYgbm90IGlzaW5zdGFuY2UocC5nZXQoJ2xlYXNlcycpLGxpc3QpOnJhaXNlIFZhbHVlRXJyb3IoJ0ludmFsaWQgbGVhc2UgbGlzdCcpCiAgICAgICAgYWRkcmVzc2VzPXNldCgpO3Nsb3RzPXNldCgpO3RhYmxlcz1zZXQoKTtsZWFzZXM9W10KICAgICAgICBmb3IgcmF3IGluIHBbJ2xlYXNlcyddOgogICAgICAgICAgICBsPWRpY3QocmF3KTtsWydpcHY2J109aXB2NihsWydpcHY2J10pO2xbJ2dhdGV3YXknXT1pcHY2KGxbJ2dhdGV3YXknXSkKICAgICAgICAgICAgaWYgdHlwZShsLmdldCgnbXR1JykpIGlzIG5vdCBpbnQgb3Igbm90IDEyODA8PWxbJ210dSddPD05MDAwOnJhaXNlIFZhbHVlRXJyb3IoJ0ludmFsaWQgbGVhc2UgTVRVJykKICAgICAgICAgICAgaWYgbm90IGlzaW5zdGFuY2UobC5nZXQoJ3Nsb3QnKSxzdHIpIG9yIG5vdCBsWydzbG90J10gb3IgbGVuKGxbJ3Nsb3QnXSk+MTAwOnJhaXNlIFZhbHVlRXJyb3IoJ0ludmFsaWQgbGVhc2Ugc2xvdCcpCiAgICAgICAgICAgIGlmIGwuZ2V0KCdwcmVmaXgnKSBhbmQgaXBhZGRyZXNzLklQdjZBZGRyZXNzKGxbJ2lwdjYnXSkgbm90IGluIGlwYWRkcmVzcy5JUHY2TmV0d29yayhsWydwcmVmaXgnXSxzdHJpY3Q9VHJ1ZSk6cmFpc2UgVmFsdWVFcnJvcignQWRkcmVzcyBpcyBvdXRzaWRlIGl0cyBsZWFzZSBwcmVmaXgnKQogICAgICAgICAgICB0YWJsZT1zZWxmLnRhYmxlKGxbJ3Nsb3QnXSkKICAgICAgICAgICAgaWYgbFsnaXB2NiddIGluIGFkZHJlc3NlcyBvciBsWydzbG90J10gaW4gc2xvdHMgb3IgdGFibGUgaW4gdGFibGVzOnJhaXNlIFZhbHVlRXJyb3IoJ0R1cGxpY2F0ZSBhZGRyZXNzLCBzbG90LCBvciBwb2xpY3ktdGFibGUgY29sbGlzaW9uJykKICAgICAgICAgICAgYWRkcmVzc2VzLmFkZChsWydpcHY2J10pO3Nsb3RzLmFkZChsWydzbG90J10pO3RhYmxlcy5hZGQodGFibGUpO2xlYXNlcy5hcHBlbmQobCkKICAgICAgICByZXR1cm4gbGVhc2VzCgogICAgZGVmIGRpc2NvdmVyX25hdGl2ZShzZWxmKToKICAgICAgICBhZGRyZXNzZXM9c2VsZi5rZXJuZWwuYWRkcmVzc2VzKCkKICAgICAgICBuYXRpdmU9W2EgZm9yIGlwLGEgaW4gYWRkcmVzc2VzLml0ZW1zKCkgaWYgYS5nZXQoJ3Njb3BlJyk9PSdnbG9iYWwnIGFuZCBpcCBub3QgaW4gc2VsZi5zdGF0ZVsnYWRkcmVzc2VzJ10gYW5kIGEuZ2V0KCdwcmVmaXhsZW4nKSE9MTI4XQogICAgICAgIGlmIG5vdCBuYXRpdmU6cmV0dXJuIE5vbmUKICAgICAgICBwcmVmZXJyZWQ9c2VsZi5jZmcuZ2V0KCduYXRpdmVfc291cmNlJyk7YWRkcj1uZXh0KChhIGZvciBhIGluIG5hdGl2ZSBpZiBhWydsb2NhbCddPT1wcmVmZXJyZWQpLG5hdGl2ZVswXSkKICAgICAgICByb3V0ZXM9W3IgZm9yIHIgaW4gc2VsZi5rZXJuZWwucm91dGVzKCkgaWYgclsndGFibGUnXT09MjU0IGFuZCByWydkc3QnXT09Jzo6LzAnIGFuZCByLmdldCgnZGV2Jyk9PXNlbGYuaWZhY2UgYW5kIHIuZ2V0KCdnYXRld2F5JykgYW5kIHJbJ21ldHJpYyddIT05OV0KICAgICAgICByb3V0ZT1yb3V0ZXNbMF0gaWYgcm91dGVzIGVsc2UgTm9uZQogICAgICAgIGlmIHJvdXRlIGFuZCAndGFibGUnIG5vdCBpbiByb3V0ZTpyb3V0ZT1ub3JtYWxpemVfcm91dGUocm91dGUpCiAgICAgICAgaWYgbm90IHJvdXRlIG9yIHJvdXRlLmdldCgndW5zdXBwb3J0ZWQnKTpyZXR1cm4gTm9uZQogICAgICAgIHJldHVybiB7J2FkZHJlc3MnOmlwdjYoYWRkclsnbG9jYWwnXSksJ2NpZHInOm5ldHdvcmsoYWRkclsnbG9jYWwnXSsnLycrc3RyKGFkZHJbJ3ByZWZpeGxlbiddKSksJ3JvdXRlJzpjb3B5LmRlZXBjb3B5KHJvdXRlKX0KCiAgICBkZWYgZGVzaXJlZChzZWxmLHAsbGVhc2VzLG5hdGl2ZSk6CiAgICAgICAgc3RhdGU9Y29weS5kZWVwY29weShzZWxmLnN0YXRlKTtzdGF0ZS51cGRhdGUoeydhZGRyZXNzZXMnOnt9LCdydWxlcyc6W10sJ3RhYmxlcyc6W10sJ25hdGl2ZSc6bmF0aXZlLCdpbnRlcmZhY2UnOnNlbGYuaWZhY2V9KQogICAgICAgIGZvciBrIGluIFsnbWFpbl9keW5hbWljJywnbWFpbl9nYXRld2F5Jywnb3duZWRfcm91dGVzJ106c3RhdGUucG9wKGssTm9uZSkKICAgICAgICByb3V0ZXM9W107cnVsZXM9W10KICAgICAgICBkZWYgYWRkX3RhYmxlKHRhYmxlLHNvdXJjZSxnYXRld2F5LG10dSxjaWRyPU5vbmUpOgogICAgICAgICAgICBzdGF0ZVsndGFibGVzJ10uYXBwZW5kKHRhYmxlKQogICAgICAgICAgICByb3V0ZXMuZXh0ZW5kKFttYWtlX3JvdXRlKHRhYmxlLGdhdGV3YXkrJy8xMjgnLHNlbGYuaWZhY2UpLG1ha2Vfcm91dGUodGFibGUsJ2ZlODA6Oi82NCcsc2VsZi5pZmFjZSksCiAgICAgICAgICAgICAgICBtYWtlX3JvdXRlKHRhYmxlLCdkZWZhdWx0JyxzZWxmLmlmYWNlLGdhdGV3YXk9Z2F0ZXdheSxwcmVmc3JjPXNvdXJjZSxvbmxpbms9VHJ1ZSxtdHU9bXR1KSwKICAgICAgICAgICAgICAgIG1ha2Vfcm91dGUodGFibGUsJ2RlZmF1bHQnLCdsbycsdHlwZT0ndW5yZWFjaGFibGUnLG1ldHJpYz0zMjc2MCldKQogICAgICAgICAgICBpZiBjaWRyOnJvdXRlcy5hcHBlbmQobWFrZV9yb3V0ZSh0YWJsZSxjaWRyLHNlbGYuaWZhY2UpKQogICAgICAgIGlmIG5hdGl2ZToKICAgICAgICAgICAgYWRkX3RhYmxlKDQyOTk5LG5hdGl2ZVsnYWRkcmVzcyddLG5hdGl2ZVsncm91dGUnXVsnZ2F0ZXdheSddLDE1MDAsbmF0aXZlWydjaWRyJ10pCiAgICAgICAgICAgIHJ1bGVzLmFwcGVuZCh7J3ByaW9yaXR5JzoyMDAwMCwnc291cmNlJzpuYXRpdmVbJ2NpZHInXSwndGFibGUnOic0Mjk5OSd9KQogICAgICAgIGZvciBsIGluIGxlYXNlczoKICAgICAgICAgICAgdGFibGU9c2VsZi50YWJsZShsWydzbG90J10pO3ByZWY9MjEwMDArdGFibGUtNDMwMDAKICAgICAgICAgICAgc3RhdGVbJ2FkZHJlc3NlcyddW2xbJ2lwdjYnXV09eyd0YWJsZSc6dGFibGUsJ3Nsb3QnOmxbJ3Nsb3QnXSwnZ2F0ZXdheSc6bFsnZ2F0ZXdheSddLCdtdHUnOmxbJ210dSddfQogICAgICAgICAgICBhZGRfdGFibGUodGFibGUsbFsnaXB2NiddLGxbJ2dhdGV3YXknXSxsWydtdHUnXSkKICAgICAgICAgICAgcnVsZXMuYXBwZW5kKHsncHJpb3JpdHknOnByZWYsJ3NvdXJjZSc6bFsnaXB2NiddKycvMTI4JywndGFibGUnOnN0cih0YWJsZSl9KQogICAgICAgIGlmIG5hdGl2ZToKICAgICAgICAgICAgbWFpbj1jb3B5LmRlZXBjb3B5KG5hdGl2ZVsncm91dGUnXSk7bWFpblsncHJlZnNyYyddPW5hdGl2ZVsnYWRkcmVzcyddO3JvdXRlcy5hcHBlbmQobWFpbikKICAgICAgICBlbHNlOgogICAgICAgICAgICAjIENhcnJ5IGZvcndhcmQgYSBwcmVleGlzdGluZyBtYWluIHJvdXRlIGR1cmluZyBhIG5hdGl2ZS10by1sZWFzZWQgdHJhbnNpdGlvbi4KICAgICAgICAgICAgb2xkX2tleXM9e2tleV9zdHJpbmcocikgZm9yIHIgaW4gc2VsZi5vbGRfcm91dGVzKHNlbGYuc3RhdGUpfQogICAgICAgICAgICByb3V0ZXMuZXh0ZW5kKHIgZm9yIHIgaW4gc2VsZi5rZXJuZWwucm91dGVzKCkgaWYgclsndGFibGUnXT09MjU0IGFuZCByWydkc3QnXT09Jzo6LzAnIGFuZCByWydtZXRyaWMnXSE9OTkgYW5kIGtleV9zdHJpbmcocikgaW4gb2xkX2tleXMpCiAgICAgICAgY2hvc2VuPXNlbGYuY2hvb3NlX2RlZmF1bHQobGVhc2VzLGJvb2wobmF0aXZlKSkKICAgICAgICBpZiBjaG9zZW46CiAgICAgICAgICAgIHJvdXRlcy5leHRlbmQoW21ha2Vfcm91dGUoMjU0LGNob3NlblsnZ2F0ZXdheSddKycvMTI4JyxzZWxmLmlmYWNlKSwKICAgICAgICAgICAgICAgIG1ha2Vfcm91dGUoMjU0LCdkZWZhdWx0JyxzZWxmLmlmYWNlLGdhdGV3YXk9Y2hvc2VuWydnYXRld2F5J10scHJlZnNyYz1jaG9zZW5bJ2lwdjYnXSxvbmxpbms9VHJ1ZSxtdHU9Y2hvc2VuWydtdHUnXSxtZXRyaWM9OTkpXSkKICAgICAgICAgICAgc3RhdGVbJ21haW5fZHluYW1pYyddPWNob3NlblsnaXB2NiddO3N0YXRlWydtYWluX2dhdGV3YXknXT1jaG9zZW5bJ2dhdGV3YXknXQogICAgICAgIHN0YXRlWydydWxlcyddPVtbclsncHJpb3JpdHknXSxyWydzb3VyY2UnXSxpbnQoclsndGFibGUnXSldIGZvciByIGluIHJ1bGVzXQogICAgICAgIHN0YXRlLnVwZGF0ZSh7azpwW2tdIGZvciBrIGluIFsnZXBvY2gnLCdyZXZpc2lvbicsJ2V4cGlyZXNfYXQnXX0pCiAgICAgICAgc2VsZi5yZW1lbWJlcl9hc3NpZ25tZW50KHN0YXRlLHApCiAgICAgICAgc3RhdGUudXBkYXRlKHsnc2Vlbl9lcG9jaCc6cFsnZXBvY2gnXSwnc2Vlbl9yZXZpc2lvbic6cFsncmV2aXNpb24nXSwnb3duZWRfcm91dGVzJzpbciBmb3IgciBpbiByb3V0ZXMgaWYgbmF0aXZlIG9yIG5vdCAoclsndGFibGUnXT09MjU0IGFuZCByWydkc3QnXT09Jzo6LzAnIGFuZCByWydtZXRyaWMnXSE9OTkpXX0pCiAgICAgICAgcmV0dXJuIHsnYWRkcmVzc2VzJzpzb3J0ZWQoc3RhdGVbJ2FkZHJlc3NlcyddKSwncm91dGVzJzpyb3V0ZXMsJ3J1bGVzJzpydWxlc30sc3RhdGUKCiAgICBkZWYgb2xkX3JvdXRlcyhzZWxmLHN0YXRlKToKICAgICAgICBpZiAnb3duZWRfcm91dGVzJyBpbiBzdGF0ZTpyZXR1cm4gc3RhdGVbJ293bmVkX3JvdXRlcyddCiAgICAgICAgIyBVcGdyYWRlIHRoZSBwcmV2aW91cyBjbGllbnQncyBvd25lcnNoaXAgbWV0YWRhdGEgd2l0aG91dCBjbGFpbWluZyBvdGhlciByb3V0ZXMuCiAgICAgICAgcm91dGVzPVtdCiAgICAgICAgZm9yIGFkZHJlc3MsYSBpbiBzdGF0ZS5nZXQoJ2FkZHJlc3Nlcycse30pLml0ZW1zKCk6CiAgICAgICAgICAgIHQ9aW50KGFbJ3RhYmxlJ10pO3JvdXRlcy5leHRlbmQoW21ha2Vfcm91dGUodCxhWydnYXRld2F5J10rJy8xMjgnLHNlbGYuaWZhY2UpLG1ha2Vfcm91dGUodCwnZmU4MDo6LzY0JyxzZWxmLmlmYWNlKSxtYWtlX3JvdXRlKHQsJ2RlZmF1bHQnLHNlbGYuaWZhY2UpLG1ha2Vfcm91dGUodCwnZGVmYXVsdCcsJ2xvJyxtZXRyaWM9MzI3NjApXSkKICAgICAgICBuPXN0YXRlLmdldCgnbmF0aXZlJykKICAgICAgICBpZiBuIGFuZCA0Mjk5OSBpbiBzdGF0ZS5nZXQoJ3RhYmxlcycsW10pOgogICAgICAgICAgICByb3V0ZT1uWydyb3V0ZSddIGlmICd0YWJsZScgaW4gblsncm91dGUnXSBlbHNlIG5vcm1hbGl6ZV9yb3V0ZShuWydyb3V0ZSddKQogICAgICAgICAgICByb3V0ZXMuZXh0ZW5kKFttYWtlX3JvdXRlKDQyOTk5LHJvdXRlWydnYXRld2F5J10rJy8xMjgnLHNlbGYuaWZhY2UpLG1ha2Vfcm91dGUoNDI5OTksblsnY2lkciddLHNlbGYuaWZhY2UpLG1ha2Vfcm91dGUoNDI5OTksJ2ZlODA6Oi82NCcsc2VsZi5pZmFjZSksbWFrZV9yb3V0ZSg0Mjk5OSwnZGVmYXVsdCcsc2VsZi5pZmFjZSksbWFrZV9yb3V0ZSg0Mjk5OSwnZGVmYXVsdCcsJ2xvJyxtZXRyaWM9MzI3NjApLHJvdXRlXSkKICAgICAgICBpZiBzdGF0ZS5nZXQoJ21haW5fZHluYW1pYycpOnJvdXRlcy5hcHBlbmQobWFrZV9yb3V0ZSgyNTQsJ2RlZmF1bHQnLHNlbGYuaWZhY2UsbWV0cmljPTk5KSkKICAgICAgICBpZiBzdGF0ZS5nZXQoJ21haW5fZ2F0ZXdheScpOnJvdXRlcy5hcHBlbmQobWFrZV9yb3V0ZSgyNTQsc3RhdGVbJ21haW5fZ2F0ZXdheSddKycvMTI4JyxzZWxmLmlmYWNlKSkKICAgICAgICByZXR1cm4gcm91dGVzCgogICAgZGVmIHNjb3BlKHNlbGYsdGFyZ2V0LHN0YXRlPU5vbmUpOgogICAgICAgIHN0YXRlPXNlbGYuc3RhdGUgaWYgc3RhdGUgaXMgTm9uZSBlbHNlIHN0YXRlCiAgICAgICAga2V5cz17a2V5X3N0cmluZyhyKSBmb3IgciBpbiBzZWxmLm9sZF9yb3V0ZXMoc3RhdGUpK3RhcmdldFsncm91dGVzJ119CiAgICAgICAgcHJpb3JpdGllcz17aW50KHJbMF0pIGZvciByIGluIHN0YXRlLmdldCgncnVsZXMnLFtdKX18e3JbJ3ByaW9yaXR5J10gZm9yIHIgaW4gdGFyZ2V0WydydWxlcyddfQogICAgICAgIHJldHVybiB7J2FkZHJlc3Nlcyc6c29ydGVkKHNldChzdGF0ZS5nZXQoJ2FkZHJlc3Nlcycse30pKXxzZXQodGFyZ2V0WydhZGRyZXNzZXMnXSkpLAogICAgICAgICAgICAgICAgJ3JvdXRlX2tleXMnOnNvcnRlZChrZXlzKSwncHJpb3JpdGllcyc6c29ydGVkKHByaW9yaXRpZXMpfQoKICAgIGRlZiBwcmVmbGlnaHQoc2VsZixzY29wZSx0YXJnZXQpOgogICAgICAgIGN1cnJlbnRfYWRkcmVzc2VzPXNlbGYua2VybmVsLmFkZHJlc3NlcygpO29sZF9pcHM9c2V0KHNlbGYuc3RhdGVbJ2FkZHJlc3NlcyddKQogICAgICAgIGZvciBhIGluIHNjb3BlWydhZGRyZXNzZXMnXToKICAgICAgICAgICAgaWYgYSBpbiBjdXJyZW50X2FkZHJlc3NlcyBhbmQgKGEgbm90IGluIG9sZF9pcHMgb3IgY3VycmVudF9hZGRyZXNzZXNbYV1bJ3ByZWZpeGxlbiddIT0xMjgpOnJhaXNlIFJ1bnRpbWVFcnJvcignQWRkcmVzcyBjb25mbGljdHMgd2l0aCB1bm1hbmFnZWQgY29uZmlndXJhdGlvbicpCiAgICAgICAgb2xkX3RhYmxlcz1zZXQoc2VsZi5zdGF0ZS5nZXQoJ3RhYmxlcycsW10pKQogICAgICAgIG9sZF9rZXlzPXtrZXlfc3RyaW5nKHIpIGZvciByIGluIHNlbGYub2xkX3JvdXRlcyhzZWxmLnN0YXRlKX0KICAgICAgICB0YXJnZXRfdGFibGVzPXtyWyd0YWJsZSddIGZvciByIGluIHRhcmdldFsncm91dGVzJ10gaWYgclsndGFibGUnXSE9MjU0fQogICAgICAgIHNlZW49c2V0KCkKICAgICAgICBmb3IgciBpbiBzZWxmLmtlcm5lbC5yb3V0ZXMoKToKICAgICAgICAgICAgaWYgclsndGFibGUnXSBpbiB0YXJnZXRfdGFibGVzIGFuZCByWyd0YWJsZSddIG5vdCBpbiBvbGRfdGFibGVzOnJhaXNlIFJ1bnRpbWVFcnJvcignUm91dGluZyB0YWJsZSBjb2xsaXNpb24nKQogICAgICAgICAgICBpZiBrZXlfc3RyaW5nKHIpIG5vdCBpbiBzY29wZVsncm91dGVfa2V5cyddOmNvbnRpbnVlCiAgICAgICAgICAgIGlmIHIuZ2V0KCd1bnN1cHBvcnRlZCcpIG9yIHIuZ2V0KCdkZXYnKSBub3QgaW4gKHNlbGYuaWZhY2UsJ2xvJyk6cmFpc2UgUnVudGltZUVycm9yKCdDb25mbGljdGluZyBvciB1bnN1cHBvcnRlZCByb3V0ZScpCiAgICAgICAgICAgIGlmIGtleV9zdHJpbmcocikgaW4gc2VlbjpyYWlzZSBSdW50aW1lRXJyb3IoJ011bHRpcGxlIHJvdXRlcyBzaGFyZSBhIG1hbmFnZWQga2V5JykKICAgICAgICAgICAgc2Vlbi5hZGQoa2V5X3N0cmluZyhyKSkKICAgICAgICAgICAgbmF0aXZlX2RlZmF1bHQ9clsndGFibGUnXT09MjU0IGFuZCByWydkc3QnXT09Jzo6LzAnIGFuZCByWydtZXRyaWMnXSE9OTkKICAgICAgICAgICAgaWYgbm90IG5hdGl2ZV9kZWZhdWx0IGFuZCAoa2V5X3N0cmluZyhyKSBub3QgaW4gb2xkX2tleXMgb3IgclsncHJvdG9jb2wnXSBub3QgaW4gKDQsMTg2KSk6CiAgICAgICAgICAgICAgICByYWlzZSBSdW50aW1lRXJyb3IoJ1JvdXRlIGNvbmZsaWN0cyB3aXRoIHVubWFuYWdlZCBjb25maWd1cmF0aW9uJykKICAgICAgICBvd25lZD17KGludChwcmVmKSxuZXR3b3JrKHNyYyksc3RyKHQpKSBmb3IgcHJlZixzcmMsdCBpbiBzZWxmLnN0YXRlLmdldCgncnVsZXMnLFtdKX07c2Vlbj1zZXQoKQogICAgICAgIGZvciByIGluIHNlbGYua2VybmVsLnJ1bGVzKCk6CiAgICAgICAgICAgIGlmIHJbJ3ByaW9yaXR5J10gbm90IGluIHNjb3BlWydwcmlvcml0aWVzJ106Y29udGludWUKICAgICAgICAgICAgaWYgci5nZXQoJ3Vuc3VwcG9ydGVkJykgb3IgKHJbJ3ByaW9yaXR5J10sclsnc291cmNlJ10sclsndGFibGUnXSkgbm90IGluIG93bmVkIG9yIHJbJ3ByaW9yaXR5J10gaW4gc2VlbjpyYWlzZSBSdW50aW1lRXJyb3IoJ1BvbGljeSBwcmlvcml0eSBhbHJlYWR5IG93bmVkIGJ5IGFub3RoZXIgY29uZmlndXJhdGlvbicpCiAgICAgICAgICAgIHNlZW4uYWRkKHJbJ3ByaW9yaXR5J10pCgogICAgZGVmIGJhc2VsaW5lKHNlbGYsc25hcHNob3Qsc3RhdGUsbmF0aXZlLHJldGFpbixmb3JjZV9uYXRpdmU9RmFsc2UpOgogICAgICAgIHJlc3VsdD1jb3B5LmRlZXBjb3B5KHNuYXBzaG90KTtzdGF0ZT1jb3B5LmRlZXBjb3B5KHN0YXRlKQogICAgICAgIHJlbW92ZWQ9c2V0KHN0YXRlLmdldCgnYWRkcmVzc2VzJyx7fSkpLXNldChyZXRhaW4pCiAgICAgICAgZHJvcF90YWJsZXM9e2ludChzdGF0ZVsnYWRkcmVzc2VzJ11bYV1bJ3RhYmxlJ10pIGZvciBhIGluIHJlbW92ZWR9CiAgICAgICAgcHJldmlvdXM9c3RhdGUuZ2V0KCduYXRpdmUnKTtuYXRpdmVfY2hhbmdlZD1wcmV2aW91cyE9bmF0aXZlIGFuZCAobm90IHByZXZpb3VzIG9yIG5vdCBuYXRpdmUgb3IgcHJldmlvdXNbJ2NpZHInXSE9bmF0aXZlWydjaWRyJ10gb3IgcHJldmlvdXNbJ2FkZHJlc3MnXSE9bmF0aXZlWydhZGRyZXNzJ10gb3IgcHJldmlvdXNbJ3JvdXRlJ10uZ2V0KCdnYXRld2F5JykhPW5hdGl2ZVsncm91dGUnXVsnZ2F0ZXdheSddKQogICAgICAgIGlmIG5hdGl2ZV9jaGFuZ2VkOmRyb3BfdGFibGVzLmFkZCg0Mjk5OSk7Zm9yY2VfbmF0aXZlPVRydWUKICAgICAgICByZXN1bHRbJ2FkZHJlc3NlcyddPVthIGZvciBhIGluIHJlc3VsdFsnYWRkcmVzc2VzJ10gaWYgYSBub3QgaW4gcmVtb3ZlZF0KICAgICAgICByZXN1bHRbJ3J1bGVzJ109W3IgZm9yIHIgaW4gcmVzdWx0WydydWxlcyddIGlmIGludChyWyd0YWJsZSddKSBub3QgaW4gZHJvcF90YWJsZXMgYW5kIHJbJ3NvdXJjZSddIG5vdCBpbiB7YSsnLzEyOCcgZm9yIGEgaW4gcmVtb3ZlZH1dCiAgICAgICAgcmVzdWx0Wydyb3V0ZXMnXT1bciBmb3IgciBpbiByZXN1bHRbJ3JvdXRlcyddIGlmIHJbJ3RhYmxlJ10gbm90IGluIGRyb3BfdGFibGVzXQogICAgICAgIGlmIHN0YXRlLmdldCgnbWFpbl9keW5hbWljJykgaW4gcmVtb3ZlZCBvciBmb3JjZV9uYXRpdmU6CiAgICAgICAgICAgIG9sZF9nYXRld2F5PXN0YXRlLmdldCgnbWFpbl9nYXRld2F5JykKICAgICAgICAgICAgcmVzdWx0Wydyb3V0ZXMnXT1bciBmb3IgciBpbiByZXN1bHRbJ3JvdXRlcyddIGlmIG5vdCAoclsndGFibGUnXT09MjU0IGFuZCByWydwcm90b2NvbCddIGluICg0LDE4NikgYW5kIChyWydtZXRyaWMnXT09OTkgb3IgKG9sZF9nYXRld2F5IGFuZCByWydkc3QnXT09b2xkX2dhdGV3YXkrJy8xMjgnKSkpXQogICAgICAgICAgICBzdGF0ZS5wb3AoJ21haW5fZHluYW1pYycsTm9uZSk7c3RhdGUucG9wKCdtYWluX2dhdGV3YXknLE5vbmUpCiAgICAgICAgIyBBbHdheXMgcHJlc2VydmUgdGhlIGN1cnJlbnQgc3lzdGVtLW5hdGl2ZSByb3V0ZSwgaW5jbHVkaW5nIGR1cmluZyBtaWdyYXRpb24gcmVjb3ZlcnkuCiAgICAgICAgaWYgbmF0aXZlOgogICAgICAgICAgICBtYWluPWNvcHkuZGVlcGNvcHkobmF0aXZlWydyb3V0ZSddKTttYWluWydwcmVmc3JjJ109bmF0aXZlWydhZGRyZXNzJ10KICAgICAgICAgICAgcmVzdWx0Wydyb3V0ZXMnXT1bciBmb3IgciBpbiByZXN1bHRbJ3JvdXRlcyddIGlmIGtleV9zdHJpbmcocikhPWtleV9zdHJpbmcobWFpbildK1ttYWluXQogICAgICAgICMgV2l0aG91dCBhIHVzYWJsZSBuYXRpdmUgYWRkcmVzcywgcHJlc2VydmUgYW55IGV4aXN0aW5nIG1haW4gZGVmYXVsdHMKICAgICAgICAjIGV4YWN0bHkgYXMgZm91bmQ7IHRoZXkgYXJlIG5vdCBvd25lZCBieSB0aGlzIGNsaWVudC4KICAgICAgICBmb3IgYSBpbiByZW1vdmVkOnN0YXRlWydhZGRyZXNzZXMnXS5wb3AoYSxOb25lKQogICAgICAgIHN0YXRlWyd0YWJsZXMnXT1bdCBmb3IgdCBpbiBzdGF0ZS5nZXQoJ3RhYmxlcycsW10pIGlmIHQgbm90IGluIGRyb3BfdGFibGVzXQogICAgICAgIHN0YXRlWydydWxlcyddPVtbclsncHJpb3JpdHknXSxyWydzb3VyY2UnXSxpbnQoclsndGFibGUnXSldIGZvciByIGluIHJlc3VsdFsncnVsZXMnXV0KICAgICAgICBzdGF0ZVsnbmF0aXZlJ109bmF0aXZlO3N0YXRlWydpbnRlcmZhY2UnXT1zZWxmLmlmYWNlO3N0YXRlWydvd25lZF9yb3V0ZXMnXT1bciBmb3IgciBpbiByZXN1bHRbJ3JvdXRlcyddIGlmIG5hdGl2ZSBvciBub3QgKHJbJ3RhYmxlJ109PTI1NCBhbmQgclsnZHN0J109PSc6Oi8wJyBhbmQgclsnbWV0cmljJ10hPTk5KV0KICAgICAgICBpZiByZW1vdmVkIG9yIG5hdGl2ZV9jaGFuZ2VkIG9yIGZvcmNlX25hdGl2ZTpzdGF0ZVsncmV2aXNpb24nXT0wCiAgICAgICAgcmV0dXJuIHJlc3VsdCxzdGF0ZQoKICAgIGRlZiByZWNvdmVyKHNlbGYsZm9yY2U9RmFsc2UpOgogICAgICAgIGlmIG5vdCBzZWxmLmpvdXJuYWwucGF0aC5leGlzdHMoKTpyZXR1cm4KICAgICAgICBqPXJlYWQoc2VsZi5qb3VybmFsLnBhdGgpCiAgICAgICAgaWYgai5nZXQoJ3ZlcnNpb24nKSE9MSBvciBqLmdldCgnaWZhY2UnKSE9c2VsZi5pZmFjZTpyYWlzZSBSdW50aW1lRXJyb3IoJ1VucmVjb2duaXplZCBuZXR3b3JraW5nIGpvdXJuYWwnKQogICAgICAgIG9uX3NhbWVfYm9vdD1qLmdldCgnYm9vdF9pZCcpPT1Kb3VybmFsLmJvb3RfaWQoKQogICAgICAgIGRpc2s9cmVhZChzZWxmLnJvb3QvJ3N0YXRlLmpzb24nKQogICAgICAgIGlmIG5vdCBmb3JjZSBhbmQgb25fc2FtZV9ib290IGFuZCBkaXNrLmdldCgndHJhbnNhY3Rpb25faWQnKT09alsnaWQnXSBhbmQgKG5vdCBkaXNrLmdldCgnYWRkcmVzc2VzJykgb3Igc2VsZi5kZWFkbGluZV92YWxpZChkaXNrKSBvciBzZWxmLnJldGFpbnNfYXNzaWdubWVudChkaXNrKSk6CiAgICAgICAgICAgIHRyeTpzZWxmLmtlcm5lbC52ZXJpZnkoalsnc2NvcGUnXSxqWyd0YXJnZXQnXSkKICAgICAgICAgICAgZXhjZXB0IEV4Y2VwdGlvbjpwYXNzCiAgICAgICAgICAgIGVsc2U6c2VsZi5zdGF0ZT1kaXNrO3NlbGYuam91cm5hbC5yZW1vdmUoKTtyZXR1cm4KICAgICAgICB0YXJnZXQ9Y29weS5kZWVwY29weShqWydyZWNvdmVyeSddKTtzdGF0ZT1jb3B5LmRlZXBjb3B5KGpbJ3JlY292ZXJ5X3N0YXRlJ10pCiAgICAgICAgaWYgbm90IHNlbGYucmV0YWluc19hc3NpZ25tZW50KHN0YXRlKSBhbmQgKG5vdCBvbl9zYW1lX2Jvb3Qgb3IgKHN0YXRlLmdldCgnYWRkcmVzc2VzJykgYW5kIG5vdCBzZWxmLmRlYWRsaW5lX3ZhbGlkKHN0YXRlKSkpOgogICAgICAgICAgICBuYXRpdmU9c2VsZi5kaXNjb3Zlcl9uYXRpdmUoKQogICAgICAgICAgICB0YXJnZXQsc3RhdGU9c2VsZi5iYXNlbGluZSh0YXJnZXQsc3RhdGUsbmF0aXZlLHNldCgpLFRydWUpCiAgICAgICAgICAgIHN0YXRlLnVwZGF0ZSh7J2V4cGlyZXNfYXQnOjAsJ3JldmlzaW9uJzowfSkKICAgICAgICAgICAgIyBBIG5hdGl2ZSBnYXRld2F5IG1heSBoYXZlIGNoYW5nZWQgaW5kZXBlbmRlbnRseSB3aGlsZSB0aGUgY2xpZW50IHdhcyBzdG9wcGVkLgogICAgICAgICAgICBqWydzY29wZSddWydyb3V0ZV9rZXlzJ109c29ydGVkKHNldChqWydzY29wZSddWydyb3V0ZV9rZXlzJ10pfHtrZXlfc3RyaW5nKHIpIGZvciByIGluIHRhcmdldFsncm91dGVzJ119KQogICAgICAgIGpbJ3JlY292ZXJ5J109dGFyZ2V0O2pbJ3JlY292ZXJ5X3N0YXRlJ109c3RhdGU7c2F2ZShzZWxmLmpvdXJuYWwucGF0aCxqKQogICAgICAgIHNlbGYua2VybmVsLnRyYW5zaXRpb24oalsnc2NvcGUnXSx0YXJnZXQpCiAgICAgICAgaWYgc3RhdGUuZ2V0KCdhZGRyZXNzZXMnKSBhbmQgbm90IHNlbGYuZGVhZGxpbmVfdmFsaWQoc3RhdGUpIGFuZCBub3Qgc2VsZi5yZXRhaW5zX2Fzc2lnbm1lbnQoc3RhdGUpOgogICAgICAgICAgICAjIERlYWRsaW5lIGNyb3NzZWQgZHVyaW5nIHJvbGxiYWNrOiB3aXRoZHJhdyByYXRoZXIgdGhhbiByZXN1cnJlY3QgZXhwaXJlZCBsZWFzZXMuCiAgICAgICAgICAgIG5hdGl2ZT1zZWxmLmRpc2NvdmVyX25hdGl2ZSgpO3RhcmdldCxzdGF0ZT1zZWxmLmJhc2VsaW5lKHRhcmdldCxzdGF0ZSxuYXRpdmUsc2V0KCksVHJ1ZSk7c3RhdGUudXBkYXRlKHsnZXhwaXJlc19hdCc6MCwncmV2aXNpb24nOjB9KQogICAgICAgICAgICBqWydyZWNvdmVyeSddPXRhcmdldDtqWydyZWNvdmVyeV9zdGF0ZSddPXN0YXRlO3NhdmUoc2VsZi5qb3VybmFsLnBhdGgsaik7c2VsZi5rZXJuZWwudHJhbnNpdGlvbihqWydzY29wZSddLHRhcmdldCkKICAgICAgICBzYXZlKHNlbGYucm9vdC8nc3RhdGUuanNvbicsc3RhdGUpO3NlbGYuc3RhdGU9c3RhdGU7c2VsZi5qb3VybmFsLnJlbW92ZSgpCiAgICAgICAgbG9nKCduZXR3b3JrIHRyYW5zYWN0aW9uIHJlY292ZXJlZCcscmV2aXNpb249c3RhdGUuZ2V0KCdyZXZpc2lvbicsMCkpCgogICAgZGVmIHRyYW5zYWN0KHNlbGYsc2NvcGUsdGFyZ2V0LHN0YXRlLHJlY292ZXJ5LHJlY292ZXJ5X3N0YXRlLGRlYWRsaW5lPU5vbmUpOgogICAgICAgIGo9c2VsZi5qb3VybmFsLmJlZ2luKHNjb3BlLHRhcmdldCxzdGF0ZSxyZWNvdmVyeSxyZWNvdmVyeV9zdGF0ZSkKICAgICAgICB0cnk6CiAgICAgICAgICAgIHNlbGYua2VybmVsLnRyYW5zaXRpb24oc2NvcGUsdGFyZ2V0KQogICAgICAgICAgICBpZiBkZWFkbGluZSBpcyBub3QgTm9uZSBhbmQgbm90IHNlbGYuZGVhZGxpbmVfdmFsaWQoeydleHBpcmVzX2F0JzpkZWFkbGluZX0pOnJhaXNlIFJ1bnRpbWVFcnJvcignUG9saWN5IGV4cGlyZWQgZHVyaW5nIGFwcGxpY2F0aW9uJykKICAgICAgICAgICAgc2VsZi5zdGF0ZT1zZWxmLmpvdXJuYWwuY29tbWl0KGopCiAgICAgICAgZXhjZXB0IEV4Y2VwdGlvbjoKICAgICAgICAgICAgIyBSZWNvdmVyeSBmYWlsdXJlIGRlbGliZXJhdGVseSByZXRhaW5zIHRoZSBqb3VybmFsLiBObyBuZXh0IHBvbGljeSBvciBhY2tub3dsZWRnZW1lbnQKICAgICAgICAgICAgIyBpcyBhbGxvd2VkIHVudGlsIHJlY292ZXJ5IHN1Y2NlZWRzLCBpbmNsdWRpbmcgYWZ0ZXIgYSBwcm9jZXNzL2hvc3QgcmVzdGFydC4KICAgICAgICAgICAgc2VsZi5yZWNvdmVyKGZvcmNlPVRydWUpCiAgICAgICAgICAgIHJhaXNlCgogICAgZGVmIGFwcGx5KHNlbGYscG9saWN5KToKICAgICAgICBzZWxmLnJlY292ZXIoKTtsZWFzZXM9c2VsZi52YWxpZGF0ZShwb2xpY3kpO25hdGl2ZT1zZWxmLmRpc2NvdmVyX25hdGl2ZSgpCiAgICAgICAgd2FudGVkPXtsWydpcHY2J106bCBmb3IgbCBpbiBsZWFzZXN9CiAgICAgICAgcmV0YWluZWQ9e2EgZm9yIGEsciBpbiBzZWxmLnN0YXRlWydhZGRyZXNzZXMnXS5pdGVtcygpIGlmIGEgaW4gd2FudGVkIGFuZCByWydzbG90J109PXdhbnRlZFthXVsnc2xvdCddIGFuZCByWydnYXRld2F5J109PXdhbnRlZFthXVsnZ2F0ZXdheSddfQogICAgICAgICMgUmV2b2tlIG9ubHkgcmVzb3VyY2VzIGFscmVhZHkgb3duZWQuIE5ldyBjYW5kaWRhdGVzIGFyZSBjb2xsaXNpb24tY2hlY2tlZAogICAgICAgICMgc2VwYXJhdGVseSwgYmVmb3JlIGFueSBhdHRlbXB0IHRvIGluc3RhbGwgdGhlbSBvciBwdXQgdGhlbSBpbiBhIGpvdXJuYWwuCiAgICAgICAgbmF0aXZlX3JvdXRlcz1bXQogICAgICAgIGlmIG5hdGl2ZToKICAgICAgICAgICAgbWFpbj1jb3B5LmRlZXBjb3B5KG5hdGl2ZVsncm91dGUnXSk7bWFpblsncHJlZnNyYyddPW5hdGl2ZVsnYWRkcmVzcyddO25hdGl2ZV9yb3V0ZXM9W21haW5dCiAgICAgICAgc2NvcGU9c2VsZi5zY29wZSh7J2FkZHJlc3Nlcyc6W10sJ3JvdXRlcyc6bmF0aXZlX3JvdXRlcywncnVsZXMnOltdfSk7YmVmb3JlPXNlbGYua2VybmVsLnNuYXBzaG90KHNjb3BlKQogICAgICAgIHNlbGYucHJlZmxpZ2h0KHNjb3BlLGJlZm9yZSkKICAgICAgICBiYXNlbGluZSxiYXNlX3N0YXRlPXNlbGYuYmFzZWxpbmUoYmVmb3JlLHNlbGYuc3RhdGUsbmF0aXZlLHJldGFpbmVkKQogICAgICAgIGJhc2Vfc3RhdGUudXBkYXRlKHsnc2Vlbl9yZXZpc2lvbic6cG9saWN5WydyZXZpc2lvbiddLCdzZWVuX2Vwb2NoJzpwb2xpY3lbJ2Vwb2NoJ119KQogICAgICAgIGlmIGJhc2VsaW5lWydhZGRyZXNzZXMnXTpiYXNlX3N0YXRlWydleHBpcmVzX2F0J109cG9saWN5WydleHBpcmVzX2F0J10KICAgICAgICBpZiBzZXQoc2VsZi5zdGF0ZVsnYWRkcmVzc2VzJ10pLXJldGFpbmVkIG9yIGJhc2Vfc3RhdGUuZ2V0KCd0YWJsZXMnLFtdKSE9c2VsZi5zdGF0ZS5nZXQoJ3RhYmxlcycsW10pOgogICAgICAgICAgICAjIFJldm9jYXRpb24gaXMgaXRzIG93biBjb21taXR0ZWQgdHJhbnNpdGlvbiBhbmQgaXMgbmV2ZXIgdW5kb25lIGJ5IGEgbGF0ZXIgZmFpbHVyZS4KICAgICAgICAgICAgc2VsZi50cmFuc2FjdChzY29wZSxiYXNlbGluZSxiYXNlX3N0YXRlLGJhc2VsaW5lLGJhc2Vfc3RhdGUpCiAgICAgICAgdGFyZ2V0LHN0YXRlPXNlbGYuZGVzaXJlZChwb2xpY3ksbGVhc2VzLG5hdGl2ZSk7c2NvcGU9c2VsZi5zY29wZSh0YXJnZXQpO3NlbGYucHJlZmxpZ2h0KHNjb3BlLHRhcmdldCkKICAgICAgICBiZWZvcmU9c2VsZi5rZXJuZWwuc25hcHNob3Qoc2NvcGUpCiAgICAgICAgYmFzZWxpbmUsYmFzZV9zdGF0ZT1zZWxmLmJhc2VsaW5lKGJlZm9yZSxzZWxmLnN0YXRlLG5hdGl2ZSxyZXRhaW5lZCkKICAgICAgICBiYXNlX3N0YXRlLnVwZGF0ZSh7J3NlZW5fcmV2aXNpb24nOnBvbGljeVsncmV2aXNpb24nXSwnc2Vlbl9lcG9jaCc6cG9saWN5WydlcG9jaCddfSkKICAgICAgICBpZiBiYXNlbGluZVsnYWRkcmVzc2VzJ106YmFzZV9zdGF0ZVsnZXhwaXJlc19hdCddPXBvbGljeVsnZXhwaXJlc19hdCddCiAgICAgICAgaWYgbm90IHNlbGYuZGVhZGxpbmVfdmFsaWQocG9saWN5KTpyYWlzZSBSdW50aW1lRXJyb3IoJ1BvbGljeSBleHBpcmVkIGJlZm9yZSBhcHBsaWNhdGlvbicpCiAgICAgICAgc2VsZi50cmFuc2FjdChzY29wZSx0YXJnZXQsc3RhdGUsYmFzZWxpbmUsYmFzZV9zdGF0ZSxwb2xpY3lbJ2V4cGlyZXNfYXQnXSkKCiAgICBkZWYgcHJ1bmUoc2VsZixyZXRhaW5lZCxwb2xpY3k9Tm9uZSk6CiAgICAgICAgc2VsZi5yZWNvdmVyKCk7bmF0aXZlPXNlbGYuZGlzY292ZXJfbmF0aXZlKCkKICAgICAgICBuYXRpdmVfcm91dGVzPVtdCiAgICAgICAgaWYgbmF0aXZlOgogICAgICAgICAgICBtYWluPWNvcHkuZGVlcGNvcHkobmF0aXZlWydyb3V0ZSddKTttYWluWydwcmVmc3JjJ109bmF0aXZlWydhZGRyZXNzJ107bmF0aXZlX3JvdXRlcz1bbWFpbl0KICAgICAgICBzY29wZT1zZWxmLnNjb3BlKHsnYWRkcmVzc2VzJzpbXSwncm91dGVzJzpuYXRpdmVfcm91dGVzLCdydWxlcyc6W119KTtiZWZvcmU9c2VsZi5rZXJuZWwuc25hcHNob3Qoc2NvcGUpCiAgICAgICAgc2VsZi5wcmVmbGlnaHQoc2NvcGUsYmVmb3JlKQogICAgICAgIHRhcmdldCxzdGF0ZT1zZWxmLmJhc2VsaW5lKGJlZm9yZSxzZWxmLnN0YXRlLG5hdGl2ZSxyZXRhaW5lZCxub3QgcmV0YWluZWQpCiAgICAgICAgaWYgcG9saWN5OnN0YXRlLnVwZGF0ZSh7J3NlZW5fcmV2aXNpb24nOnBvbGljeVsncmV2aXNpb24nXSwnc2Vlbl9lcG9jaCc6cG9saWN5WydlcG9jaCddfSkKICAgICAgICBpZiBub3QgcmV0YWluZWQ6CiAgICAgICAgICAgIHRhcmdldFsncnVsZXMnXT1bXTt0YXJnZXRbJ3JvdXRlcyddPVtyIGZvciByIGluIHRhcmdldFsncm91dGVzJ10gaWYgclsndGFibGUnXT09MjU0XQogICAgICAgICAgICBzdGF0ZS51cGRhdGUoeydydWxlcyc6W10sJ3RhYmxlcyc6W10sJ293bmVkX3JvdXRlcyc6W3IgZm9yIHIgaW4gdGFyZ2V0Wydyb3V0ZXMnXSBpZiBuYXRpdmUgb3IgclsnbWV0cmljJ109PTk5XSwncmV2aXNpb24nOjAsJ2V4cGlyZXNfYXQnOjB9KQogICAgICAgIHNlbGYudHJhbnNhY3Qoc2NvcGUsdGFyZ2V0LHN0YXRlLHRhcmdldCxzdGF0ZSkKCiAgICBkZWYgY2xlYW51cChzZWxmKTpzZWxmLnBydW5lKHNldCgpKQoKICAgIGRlZiBjaGVja19leHBpcnkoc2VsZik6CiAgICAgICAgaWYgc2VsZi5yZXRhaW5zX2Fzc2lnbm1lbnQoc2VsZi5zdGF0ZSk6CiAgICAgICAgICAgIHN0YWxlPW5vdCBzZWxmLmRlYWRsaW5lX3ZhbGlkKHNlbGYuc3RhdGUpCiAgICAgICAgICAgIGlmIHN0YWxlIGFuZCBub3Qgc2VsZi5zdGFsZV9yZXBvcnRlZDpsb2coJ2Fzc2lnbm1lbnQgZnJlc2huZXNzIGV4cGlyZWQ7IGFkZHJlc3NlcyByZXRhaW5lZCBwZW5kaW5nIGNvbnRyb2xsZXIgcmVmcmVzaCcpCiAgICAgICAgICAgIHNlbGYuc3RhbGVfcmVwb3J0ZWQ9c3RhbGUKICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgaWYgbm90IHNlbGYuam91cm5hbC5wYXRoLmV4aXN0cygpIGFuZCBub3Qgc2VsZi5kZWFkbGluZV92YWxpZChzZWxmLnN0YXRlKToKICAgICAgICAgICAgdHJ5OnNlbGYuY2xlYW51cCgpCiAgICAgICAgICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgZTpsb2coJ2V4cGlyeSBjbGVhbnVwIHBlbmRpbmcnLGVycm9yPXN0cihlKSkKCiAgICBkZWYgdGljayhzZWxmKToKICAgICAgICB0cnk6c2VsZi5yZWNvdmVyKCkKICAgICAgICBleGNlcHQgRXhjZXB0aW9uIGFzIGU6bG9nKCdyZWNvdmVyeSBwZW5kaW5nOyBwb2xpY3kgYWNrbm93bGVkZ2VtZW50IHdpdGhoZWxkJyxlcnJvcj1zdHIoZSkpO3JldHVybgogICAgICAgIHRyeToKICAgICAgICAgICAgc2VsZi5jaGVja19leHBpcnkoKQogICAgICAgICAgICBhY2tub3dsZWRnZWQ9c2VsZi5zdGF0ZS5nZXQoJ3JldmlzaW9uJywwKSBpZiBzZWxmLmRlYWRsaW5lX3ZhbGlkKHNlbGYuc3RhdGUpIGVsc2UgMAogICAgICAgICAgICBwPXBvc3Qoc2VsZi5jZmdbJ2Jhc2VfdXJsJ10sJy9hcGkvZHluYW1pY3Y2LW5leHQvZ3Vlc3Qvc3luYycsc2VsZi5jZmdbJ3Rva2VuJ10seyd1dWlkJzpzZWxmLmNmZ1sndXVpZCddLCdhcHBsaWVkX3JldmlzaW9uJzphY2tub3dsZWRnZWQsJ2Fzc2lnbm1lbnRfcHJvdG9jb2wnOjJ9LHRpbWVvdXQ9bWF4KC4yLG1pbigxMixzZWxmLnN0YXRlLmdldCgnZXhwaXJlc19hdCcsMCktdGltZS50aW1lKCkpKSBpZiBhY2tub3dsZWRnZWQgZWxzZSAxMikKICAgICAgICAgICAgc3RhYmxlPXAuZ2V0KCdhc3NpZ25tZW50X3Byb3RvY29sJyk9PTIKICAgICAgICAgICAgc2VsZi5uZXh0X2ludGVydmFsPTkwIGlmIHN0YWJsZSBlbHNlIG1heCgzLG1pbigzMCxpbnQocC5nZXQoJ3JlZnJlc2hfaW50ZXJ2YWwnLHNlbGYuY2ZnLmdldCgnaW50ZXJ2YWwnLDUpKSkpKQogICAgICAgICAgICBpZiBwLmdldCgncGVuZGluZycpOgogICAgICAgICAgICAgICAga2V5PShwLmdldCgnZXBvY2gnKSxwLmdldCgncmV2aXNpb24nKSkKICAgICAgICAgICAgICAgIGlmIGtleSE9c2VsZi5wZW5kaW5nX2tleTpzZWxmLnBlbmRpbmdfa2V5PWtleTtzZWxmLnBlbmRpbmdfYXR0ZW1wdHM9MAogICAgICAgICAgICAgICAgc2VsZi5wZW5kaW5nX2F0dGVtcHRzKz0xCiAgICAgICAgICAgICAgICBzZWxmLm5leHRfaW50ZXJ2YWw9bWluKHNlbGYubmV4dF9pbnRlcnZhbCw1IGlmIHNlbGYucGVuZGluZ19hdHRlbXB0czw9MyBlbHNlIDMwIGlmIHNlbGYucGVuZGluZ19hdHRlbXB0czw9NiBlbHNlIDkwKQogICAgICAgICAgICBlbHNlOnNlbGYucGVuZGluZ19rZXk9Tm9uZTtzZWxmLnBlbmRpbmdfYXR0ZW1wdHM9MAogICAgICAgICAgICBpZiBwLmdldCgnZXhwaXJlc19hdCcsMCk+dGltZS50aW1lKCk6c2VsZi5uZXh0X2ludGVydmFsPW1heCgxLG1pbihzZWxmLm5leHRfaW50ZXJ2YWwsKHBbJ2V4cGlyZXNfYXQnXS10aW1lLnRpbWUoKSkvMikpCiAgICAgICAgICAgIHNlbGYuZXZlbnRzLmNvbmZpZ3VyZShwLmdldCgnZXZlbnRfc3RyZWFtJykgaXMgVHJ1ZSkKICAgICAgICAgICAgaWYgcC5nZXQoJ3BlbmRpbmcnKToKICAgICAgICAgICAgICAgIHJldGFpbj1zZWxmLnZhbGlkYXRlKHAsVHJ1ZSkKICAgICAgICAgICAgICAgIGlmIHNldChzZWxmLnN0YXRlWydhZGRyZXNzZXMnXSktcmV0YWluOnNlbGYucHJ1bmUocmV0YWluLHApCiAgICAgICAgICAgICAgICAjIFBlbmRpbmcgYXV0aG9yaXphdGlvbiBuZXZlciBpbnN0YWxscyBuZXcgYWRkcmVzc2VzLCBidXQgY2FuIHJlbmV3CiAgICAgICAgICAgICAgICAjIGZyZXNobmVzcyBvZiByZXRhaW5lZCwgYXV0aGVudGljYXRlZCB2MiBhc3NpZ25tZW50IG1lbWJlcnNoaXAuCiAgICAgICAgICAgICAgICBpZiBzdGFibGU6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5yZW1lbWJlcl9hc3NpZ25tZW50KHNlbGYuc3RhdGUscCkKICAgICAgICAgICAgICAgICAgICBzZWxmLnN0YXRlLnVwZGF0ZSh7J3NlZW5fZXBvY2gnOnBbJ2Vwb2NoJ10sJ3NlZW5fcmV2aXNpb24nOnBbJ3JldmlzaW9uJ10sJ2V4cGlyZXNfYXQnOnBbJ2V4cGlyZXNfYXQnXX0pCiAgICAgICAgICAgICAgICAgICAgc2F2ZShzZWxmLnJvb3QvJ3N0YXRlLmpzb24nLHNlbGYuc3RhdGUpCiAgICAgICAgICAgIGVsc2U6c2VsZi5hcHBseShwKQogICAgICAgICAgICBzZWxmLmZhaWx1cmVzPTAKICAgICAgICBleGNlcHQgRXhjZXB0aW9uIGFzIGU6CiAgICAgICAgICAgIHNlbGYuZmFpbHVyZXM9bWluKDYsc2VsZi5mYWlsdXJlcysxKTtzZWxmLm5leHRfaW50ZXJ2YWw9bWluKDkwLDUqMioqKHNlbGYuZmFpbHVyZXMtMSkpK3JhbmRvbS51bmlmb3JtKDAsNSkKICAgICAgICAgICAgbG9nKCdndWVzdCBzeW5jIGZhaWxlZCcsZXJyb3I9c3RyKGUpKQogICAgICAgIHNlbGYuY2hlY2tfZXhwaXJ5KCkKCmRlZiBtYWluKCk6CiAgICBwPWFyZ3BhcnNlLkFyZ3VtZW50UGFyc2VyKCk7cC5hZGRfYXJndW1lbnQoJy0tY29uZmlnJyxkZWZhdWx0PScvZXRjL2R5bmFtaWN2Ni1uZXh0L2d1ZXN0Lmpzb24nKTtwLmFkZF9hcmd1bWVudCgnLS1vbmNlJyxhY3Rpb249J3N0b3JlX3RydWUnKTtwLmFkZF9hcmd1bWVudCgnLS1jbGVhbnVwJyxhY3Rpb249J3N0b3JlX3RydWUnKTthPXAucGFyc2VfYXJncygpCiAgICBnPUd1ZXN0KHJlYWQoYS5jb25maWcpKQogICAgd2l0aCBsb2NrKGcucm9vdC8nYWdlbnQubG9jaycpOgogICAgICAgIGcucmVjb3ZlcigpCiAgICAgICAgaWYgYS5jbGVhbnVwOmcuY2xlYW51cCgpO3JldHVybgogICAgICAgIGR1ZT0wCiAgICAgICAgd2hpbGUgVHJ1ZToKICAgICAgICAgICAgaWYgdGltZS5tb25vdG9uaWMoKT49ZHVlIG9yIGcuZXZlbnRzLmNvbnN1bWUoKToKICAgICAgICAgICAgICAgIGcudGljaygpO2R1ZT10aW1lLm1vbm90b25pYygpK2cubmV4dF9pbnRlcnZhbCooLjkrcmFuZG9tLnJhbmRvbSgpKi4xKQogICAgICAgICAgICAgICAgaWYgYS5vbmNlOmJyZWFrCiAgICAgICAgICAgIGVsc2U6Zy5jaGVja19leHBpcnkoKQogICAgICAgICAgICBnLmV2ZW50cy53YWtlLndhaXQobWluKDEsbWF4KC4wNSxkdWUtdGltZS5tb25vdG9uaWMoKSkpKQppZiBfX25hbWVfXz09J19fbWFpbl9fJzptYWluKCkK', 'dvn_common.py': 'IyEvdXNyL2Jpbi9lbnYgcHl0aG9uMwppbXBvcnQgY29udGV4dGxpYiwgZmNudGwsIGh0dHAuY2xpZW50LCBpcGFkZHJlc3MsIGpzb24sIG9zLCBwYXRobGliLCBzb2NrZXQsIHNzbCwgc3VicHJvY2VzcywgdGVtcGZpbGUsIHRpbWUsIHVybGxpYi5yZXF1ZXN0CgpkZWYgY29ubmVjdF9pcHY0KGFkZHJlc3MsdGltZW91dD0xMixzb3VyY2VfYWRkcmVzcz1Ob25lKToKICAgIGVycm9yPU5vbmUKICAgIGZvciBmYW1pbHksa2luZCxwcm90b2NvbCxfLGRlc3RpbmF0aW9uIGluIHNvY2tldC5nZXRhZGRyaW5mbyhhZGRyZXNzWzBdLGFkZHJlc3NbMV0sc29ja2V0LkFGX0lORVQsc29ja2V0LlNPQ0tfU1RSRUFNKToKICAgICAgICBzPXNvY2tldC5zb2NrZXQoZmFtaWx5LGtpbmQscHJvdG9jb2wpO3Muc2V0dGltZW91dCh0aW1lb3V0KQogICAgICAgIHRyeToKICAgICAgICAgICAgaWYgc291cmNlX2FkZHJlc3M6cy5iaW5kKHNvdXJjZV9hZGRyZXNzKQogICAgICAgICAgICBzLmNvbm5lY3QoZGVzdGluYXRpb24pO3JldHVybiBzCiAgICAgICAgZXhjZXB0IE9TRXJyb3IgYXMgZTplcnJvcj1lO3MuY2xvc2UoKQogICAgcmFpc2UgZXJyb3Igb3IgT1NFcnJvcignTm8gSVB2NCBtYW5hZ2VtZW50IGVuZHBvaW50JykKCmNsYXNzIE1hbmFnZW1lbnRDb25uZWN0aW9uKGh0dHAuY2xpZW50LkhUVFBTQ29ubmVjdGlvbik6CiAgICBkZWYgX19pbml0X18oc2VsZiwqYXJncywqKmt3YXJncyk6CiAgICAgICAgc3VwZXIoKS5fX2luaXRfXygqYXJncywqKmt3YXJncyk7c2VsZi5fY3JlYXRlX2Nvbm5lY3Rpb249Y29ubmVjdF9pcHY0CgpjbGFzcyBNYW5hZ2VtZW50SFRUUFModXJsbGliLnJlcXVlc3QuSFRUUFNIYW5kbGVyKToKICAgIGRlZiBodHRwc19vcGVuKHNlbGYscmVxKTpyZXR1cm4gc2VsZi5kb19vcGVuKE1hbmFnZW1lbnRDb25uZWN0aW9uLHJlcSxjb250ZXh0PXNzbC5jcmVhdGVfZGVmYXVsdF9jb250ZXh0KCkpCgpjbGFzcyBOb1JlZGlyZWN0KHVybGxpYi5yZXF1ZXN0LkhUVFBSZWRpcmVjdEhhbmRsZXIpOgogICAgZGVmIHJlZGlyZWN0X3JlcXVlc3Qoc2VsZiwqYXJncywqKmt3YXJncyk6cmV0dXJuIE5vbmUKCmRlZiBydW4oYXJncywgY2hlY2s9VHJ1ZSk6CiAgICBwPXN1YnByb2Nlc3MucnVuKFtzdHIoYSkgZm9yIGEgaW4gYXJnc10sY2FwdHVyZV9vdXRwdXQ9VHJ1ZSx0ZXh0PVRydWUsdGltZW91dD0yNSkKICAgIGlmIGNoZWNrIGFuZCBwLnJldHVybmNvZGU6IHJhaXNlIFJ1bnRpbWVFcnJvcihmJ3thcmdzWzBdfSBmYWlsZWQ6IHtwLnN0ZGVyci5zdHJpcCgpWzoyNTBdfScpCiAgICByZXR1cm4gcC5zdGRvdXQuc3RyaXAoKQoKZGVmIHNhdmUocGF0aCwgZGF0YSk6CiAgICBwYXRoPXBhdGhsaWIuUGF0aChwYXRoKTtwYXRoLnBhcmVudC5ta2RpcihwYXJlbnRzPVRydWUsZXhpc3Rfb2s9VHJ1ZSkKICAgIGZkLHRtcD10ZW1wZmlsZS5ta3N0ZW1wKHByZWZpeD0nLicrcGF0aC5uYW1lLGRpcj1wYXRoLnBhcmVudCkKICAgIHRyeToKICAgICAgICBvcy5mY2htb2QoZmQsMG82MDApCiAgICAgICAgd2l0aCBvcy5mZG9wZW4oZmQsJ3cnKSBhcyBmOiBqc29uLmR1bXAoZGF0YSxmLHNvcnRfa2V5cz1UcnVlKTtmLmZsdXNoKCk7b3MuZnN5bmMoZi5maWxlbm8oKSkKICAgICAgICBvcy5yZXBsYWNlKHRtcCxwYXRoKQogICAgICAgIGQ9b3Mub3BlbihwYXRoLnBhcmVudCxvcy5PX0RJUkVDVE9SWSk7b3MuZnN5bmMoZCk7b3MuY2xvc2UoZCkKICAgIGZpbmFsbHk6CiAgICAgICAgaWYgb3MucGF0aC5leGlzdHModG1wKTpvcy51bmxpbmsodG1wKQoKZGVmIHJlYWQocGF0aCxkZWZhdWx0PU5vbmUpOgogICAgdHJ5OnJldHVybiBqc29uLmxvYWRzKHBhdGhsaWIuUGF0aChwYXRoKS5yZWFkX3RleHQoKSkKICAgIGV4Y2VwdCBGaWxlTm90Rm91bmRFcnJvcjpyZXR1cm4gZGVmYXVsdCBpZiBkZWZhdWx0IGlzIG5vdCBOb25lIGVsc2Uge30KCkBjb250ZXh0bGliLmNvbnRleHRtYW5hZ2VyCmRlZiBsb2NrKHBhdGgpOgogICAgcGF0aGxpYi5QYXRoKHBhdGgpLnBhcmVudC5ta2RpcihwYXJlbnRzPVRydWUsZXhpc3Rfb2s9VHJ1ZSkKICAgIHdpdGggb3BlbihwYXRoLCdhJykgYXMgZjoKICAgICAgICBmY250bC5mbG9jayhmLGZjbnRsLkxPQ0tfRVgpO3lpZWxkCgpkZWYgcG9zdChiYXNlLCBwYXRoLCB0b2tlbiwgYm9keSwgdGltZW91dD0xMik6CiAgICBpZiBub3QgYmFzZS5zdGFydHN3aXRoKCdodHRwczovLycpIGFuZCBub3QgYmFzZS5zdGFydHN3aXRoKCdodHRwOi8vMTI3LjAuMC4xOicpOnJhaXNlIFZhbHVlRXJyb3IoJ0hUVFBTIHJlcXVpcmVkJykKICAgIHJlcT11cmxsaWIucmVxdWVzdC5SZXF1ZXN0KGJhc2UucnN0cmlwKCcvJykrcGF0aCxkYXRhPWpzb24uZHVtcHMoYm9keSkuZW5jb2RlKCksaGVhZGVycz17J0NvbnRlbnQtVHlwZSc6J2FwcGxpY2F0aW9uL2pzb24nLCdBY2NlcHQnOidhcHBsaWNhdGlvbi9qc29uJywnVXNlci1BZ2VudCc6J0R5bmFtaWNWNk5leHQvMC4xJywnQXV0aG9yaXphdGlvbic6J0JlYXJlciAnK3Rva2VufSxtZXRob2Q9J1BPU1QnKQogICAgb3BlbmVyPXVybGxpYi5yZXF1ZXN0LmJ1aWxkX29wZW5lcih1cmxsaWIucmVxdWVzdC5Qcm94eUhhbmRsZXIoe30pLE1hbmFnZW1lbnRIVFRQUygpLE5vUmVkaXJlY3QoKSkKICAgIHdpdGggb3BlbmVyLm9wZW4ocmVxLHRpbWVvdXQ9dGltZW91dCkgYXMgcjoKICAgICAgICBkYXRhPXIucmVhZCg0KjEwMjQqMTAyNCsxKQogICAgICAgIGlmIGxlbihkYXRhKT40KjEwMjQqMTAyNDpyYWlzZSBWYWx1ZUVycm9yKCdPdmVyc2l6ZSBBUEkgcmVzcG9uc2UnKQogICAgICAgIHJldHVybiBqc29uLmxvYWRzKGRhdGEpCgpkZWYgaXB2NihzKTpyZXR1cm4gc3RyKGlwYWRkcmVzcy5JUHY2QWRkcmVzcyhzKSkKZGVmIHZhbGlkX25hbWUocyk6CiAgICBpbXBvcnQgcmUKICAgIGlmIG5vdCByZS5mdWxsbWF0Y2gocidbQS1aYS16MC05Xy4tXXsxLDE1fScscyk6cmFpc2UgVmFsdWVFcnJvcignSW52YWxpZCBpbnRlcmZhY2UgbmFtZScpCiAgICByZXR1cm4gcwoKZGVmIGxvZyhtZXNzYWdlLCoqZXh0cmEpOnByaW50KGpzb24uZHVtcHMoeyd0aW1lJzppbnQodGltZS50aW1lKCkpLCdtZXNzYWdlJzptZXNzYWdlLCoqZXh0cmF9KSxmbHVzaD1UcnVlKQo=', 'dvn_transaction.py': 'IiIiU2NvcGVkLCB3cml0ZS1haGVhZCByZWNvdmVyeSBmb3IgZ3Vlc3QgSVB2NiBuZXRsaW5rIG9wZXJhdGlvbnMuCgpUaGUga2VybmVsIGhhcyBubyB0cmFuc2FjdGlvbiBzcGFubmluZyBhZGRyZXNzZXMsIHJvdXRlcyBhbmQgcnVsZXMuIEEgam91cm5hbAp0aGVyZWZvcmUgcmVjb3JkcyB0aGUgcmVjb3ZlcnkgdGFyZ2V0IGJlZm9yZSBtdXRhdGlvbjsgc3RhdGUgaXMgY29tbWl0dGVkIG9ubHkKYWZ0ZXIgcmVhZC1iYWNrIHZlcmlmaWNhdGlvbi4gVW5yZWxhdGVkIG5hbWVzcGFjZXMvcmVzb3VyY2VzIGFyZSBuZXZlciBmbHVzaGVkLgoiIiIKaW1wb3J0IGNvcHksIGlwYWRkcmVzcywganNvbiwgb3MsIHBhdGhsaWIsIHRpbWUsIHV1aWQKZnJvbSBkdm5fY29tbW9uIGltcG9ydCBydW4sIHNhdmUKClBST1RPID0gNCAgIyBzdGF0aWM7IGxlZ2FjeSBjbGllbnQtb3duZWQgcm91dGVzIHVzZWQgMTg2IChkaXNwbGF5ZWQgYXMgYmdwKS4KUFJPVE9DT0xTID0geydib290JzogMywgJ3N0YXRpYyc6IDQsICdrZXJuZWwnOiAyLCAncmEnOiA5LCAnYmdwJzogMTg2fQoKZGVmIG5ldHdvcmsodmFsdWUpOgogICAgcmV0dXJuIHN0cihpcGFkZHJlc3MuSVB2Nk5ldHdvcmsoJzo6LzAnIGlmIHZhbHVlIGluICgnZGVmYXVsdCcsICdhbGwnKSBlbHNlIHZhbHVlLCBzdHJpY3Q9RmFsc2UpKQoKZGVmIHJvdXRlX2tleShyKTogcmV0dXJuIChpbnQoclsndGFibGUnXSksIHJbJ2RzdCddLCBpbnQoclsnbWV0cmljJ10pKQpkZWYga2V5X3N0cmluZyhyKTogcmV0dXJuIGpzb24uZHVtcHMocm91dGVfa2V5KHIpLCBzZXBhcmF0b3JzPSgnLCcsICc6JykpCgpkZWYgbm9ybWFsaXplX3JvdXRlKHJhdyk6CiAgICB0YWJsZSA9IHJhdy5nZXQoJ3RhYmxlJywgMjU0KQogICAgdGFibGUgPSB7J21haW4nOiAyNTQsICdsb2NhbCc6IDI1NSwgJ2RlZmF1bHQnOiAyNTN9LmdldChzdHIodGFibGUpLCB0YWJsZSkKICAgIHByb3RvID0gcmF3LmdldCgncHJvdG9jb2wnLCAzKQogICAgcHJvdG8gPSBQUk9UT0NPTFMuZ2V0KHN0cihwcm90byksIHByb3RvKQogICAgbWV0cmljcyA9IHJhdy5nZXQoJ21ldHJpY3MnLCB7fSkKICAgIGlmIGlzaW5zdGFuY2UobWV0cmljcywgbGlzdCk6IG1ldHJpY3MgPSB7azp2IGZvciBpdGVtIGluIG1ldHJpY3MgZm9yIGssdiBpbiBpdGVtLml0ZW1zKCl9CiAgICByID0geyd0YWJsZSc6IGludCh0YWJsZSksICdkc3QnOiBuZXR3b3JrKHJhdy5nZXQoJ2RzdCcsICdkZWZhdWx0JykpLCAnbWV0cmljJzogaW50KHJhdy5nZXQoJ21ldHJpYycsIDEwMjQpKSwKICAgICAgICAgJ3R5cGUnOiByYXcuZ2V0KCd0eXBlJywgJ3VuaWNhc3QnKSwgJ3Byb3RvY29sJzogaW50KHByb3RvKSBpZiBzdHIocHJvdG8pLmlzZGlnaXQoKSBlbHNlIHN0cihwcm90byksCiAgICAgICAgICdkZXYnOiByYXcuZ2V0KCdkZXYnKSwgJ3ByZWYnOiByYXcuZ2V0KCdwcmVmJywgJ21lZGl1bScpLCAnb25saW5rJzogJ29ubGluaycgaW4gcmF3LmdldCgnZmxhZ3MnLCBbXSl9CiAgICBmb3IgayBpbiAoJ2dhdGV3YXknLCAncHJlZnNyYycpOgogICAgICAgIGlmIHJhdy5nZXQoayk6IHJba10gPSBzdHIoaXBhZGRyZXNzLklQdjZBZGRyZXNzKHJhd1trXSkpCiAgICBpZiBtZXRyaWNzLmdldCgnbXR1Jyk6IHJbJ210dSddID0gaW50KG1ldHJpY3NbJ210dSddKQogICAgaWYgYW55KGsgaW4gcmF3IGZvciBrIGluICgnbmV4dGhvcHMnLCduaGlkJywnZW5jYXAnLCdleHBpcmVzJywnZnJvbScpKSBvciBzZXQobWV0cmljcykteydtdHUnfSBvciBzZXQocmF3LmdldCgnZmxhZ3MnLCBbXSkpLXsnb25saW5rJ306CiAgICAgICAgclsndW5zdXBwb3J0ZWQnXSA9IFRydWUKICAgIHJldHVybiByCgpkZWYgbWFrZV9yb3V0ZSh0YWJsZSwgZHN0LCBkZXYsICoqdmFsdWVzKToKICAgIHJldHVybiBkaWN0KHsndGFibGUnOiB0YWJsZSwgJ2RzdCc6IG5ldHdvcmsoZHN0KSwgJ2Rldic6IGRldiwgJ21ldHJpYyc6IDEwMjQsCiAgICAgICAgICAgICAgICAgJ3R5cGUnOiAndW5pY2FzdCcsICdwcm90b2NvbCc6IFBST1RPLCAncHJlZic6ICdtZWRpdW0nLCAnb25saW5rJzogRmFsc2V9LCAqKnZhbHVlcykKCmRlZiBub3JtYWxpemVfcnVsZShyKToKICAgIHNyYyA9IHIuZ2V0KCdzcmMnLCAnYWxsJykKICAgIGlmIHNyYyBub3QgaW4gKCdhbGwnLCAnZGVmYXVsdCcpIGFuZCAnLycgbm90IGluIHNyYzogc3JjICs9ICcvJyArIHN0cihyLmdldCgnc3JjbGVuJywxMjgpKQogICAgcmVzdWx0ID0geydwcmlvcml0eSc6aW50KHIuZ2V0KCdwcmlvcml0eScsMCkpLCAnc291cmNlJzpuZXR3b3JrKHNyYyksICd0YWJsZSc6c3RyKHIuZ2V0KCd0YWJsZScsJycpKX0KICAgIGlmIGFueShrIG5vdCBpbiAoJ3ByaW9yaXR5Jywnc3JjJywnc3JjbGVuJywndGFibGUnLCdwcm90b2NvbCcpIGZvciBrIGluIHIpOnJlc3VsdFsndW5zdXBwb3J0ZWQnXT1UcnVlCiAgICByZXR1cm4gcmVzdWx0CgpjbGFzcyBLZXJuZWw6CiAgICBkZWYgX19pbml0X18oc2VsZiwgaWZhY2UpOiBzZWxmLmlmYWNlPWlmYWNlCiAgICBkZWYgY29tbWFuZChzZWxmLCBhcmdzKTogcmV0dXJuIHJ1bihhcmdzKQogICAgZGVmIHJvdXRlcyhzZWxmKToKICAgICAgICByZXR1cm4gW25vcm1hbGl6ZV9yb3V0ZShyKSBmb3IgciBpbiBqc29uLmxvYWRzKHJ1bihbJ2lwJywnLWonLCctNicsJ3JvdXRlJywnc2hvdycsJ3RhYmxlJywnYWxsJ10pKV0KICAgIGRlZiBydWxlcyhzZWxmKTpyZXR1cm4gW25vcm1hbGl6ZV9ydWxlKHIpIGZvciByIGluIGpzb24ubG9hZHMocnVuKFsnaXAnLCctaicsJy02JywncnVsZScsJ3Nob3cnXSkpXQogICAgZGVmIGFkZHJlc3NlcyhzZWxmKToKICAgICAgICByb3dzPWpzb24ubG9hZHMocnVuKFsnaXAnLCctaicsJy02JywnYWRkcicsJ3Nob3cnLCdkZXYnLHNlbGYuaWZhY2VdKSkKICAgICAgICByZXR1cm4ge3N0cihpcGFkZHJlc3MuSVB2NkFkZHJlc3MoYVsnbG9jYWwnXSkpOmEgZm9yIGEgaW4gcm93c1swXVsnYWRkcl9pbmZvJ10gaWYgYVsnZmFtaWx5J109PSdpbmV0Nid9CiAgICBkZWYgcHV0X2FkZHJlc3Moc2VsZiwgYWRkcmVzcyk6CiAgICAgICAgaWYgYWRkcmVzcyBub3QgaW4gc2VsZi5hZGRyZXNzZXMoKTpzZWxmLmNvbW1hbmQoWydpcCcsJy02JywnYWRkcicsJ2FkZCcsYWRkcmVzcysnLzEyOCcsJ2Rldicsc2VsZi5pZmFjZV0pCiAgICBkZWYgZGVsX2FkZHJlc3Moc2VsZixhZGRyZXNzKToKICAgICAgICBjdXJyZW50PXNlbGYuYWRkcmVzc2VzKCkuZ2V0KGFkZHJlc3MpCiAgICAgICAgaWYgY3VycmVudDoKICAgICAgICAgICAgaWYgY3VycmVudFsncHJlZml4bGVuJ10hPTEyODpyYWlzZSBSdW50aW1lRXJyb3IoJ1JlZnVzaW5nIHRvIHJlbW92ZSBhIG5vbi0vMTI4IGFkZHJlc3MnKQogICAgICAgICAgICBzZWxmLmNvbW1hbmQoWydpcCcsJy02JywnYWRkcicsJ2RlbCcsYWRkcmVzcysnLzEyOCcsJ2Rldicsc2VsZi5pZmFjZV0pCiAgICBkZWYgd2FpdF9hZGRyZXNzZXMoc2VsZixhZGRyZXNzZXMpOgogICAgICAgIHVudGlsPXRpbWUubW9ub3RvbmljKCkrMwogICAgICAgIHdoaWxlIFRydWU6CiAgICAgICAgICAgIGN1cnJlbnQ9c2VsZi5hZGRyZXNzZXMoKTtwZW5kaW5nPUZhbHNlCiAgICAgICAgICAgIGZvciBhIGluIGFkZHJlc3NlczoKICAgICAgICAgICAgICAgIGlmIGEgbm90IGluIGN1cnJlbnQ6cmFpc2UgUnVudGltZUVycm9yKCdNYW5hZ2VkIElQdjYgYWRkcmVzcyBkaXNhcHBlYXJlZCcpCiAgICAgICAgICAgICAgICBpZiBjdXJyZW50W2FdLmdldCgnZGFkZmFpbGVkJyk6cmFpc2UgUnVudGltZUVycm9yKCdEdXBsaWNhdGUgSVB2NiBhZGRyZXNzIGRldGVjdGVkJykKICAgICAgICAgICAgICAgIHBlbmRpbmcgfD0gYm9vbChjdXJyZW50W2FdLmdldCgndGVudGF0aXZlJykpCiAgICAgICAgICAgIGlmIG5vdCBwZW5kaW5nOnJldHVybgogICAgICAgICAgICBpZiB0aW1lLm1vbm90b25pYygpPj11bnRpbDpyYWlzZSBSdW50aW1lRXJyb3IoJ0lQdjYgZHVwbGljYXRlLWFkZHJlc3MgZGV0ZWN0aW9uIGRpZCBub3QgZmluaXNoJykKICAgICAgICAgICAgdGltZS5zbGVlcCguMSkKICAgIGRlZiByb3V0ZV9hcmdzKHNlbGYsdmVyYixyKToKICAgICAgICBpZiByLmdldCgndW5zdXBwb3J0ZWQnKTpyYWlzZSBSdW50aW1lRXJyb3IoJ1Vuc3VwcG9ydGVkIHJvdXRlIGNhbm5vdCBiZSByZXN0b3JlZCBzYWZlbHknKQogICAgICAgIGFyZ3M9WydpcCcsJy02Jywncm91dGUnLHZlcmJdCiAgICAgICAgaWYgclsndHlwZSddIT0ndW5pY2FzdCc6YXJncy5hcHBlbmQoclsndHlwZSddKQogICAgICAgIGFyZ3MuYXBwZW5kKCdkZWZhdWx0JyBpZiByWydkc3QnXT09Jzo6LzAnIGVsc2UgclsnZHN0J10pCiAgICAgICAgaWYgci5nZXQoJ2dhdGV3YXknKTphcmdzKz1bJ3ZpYScsclsnZ2F0ZXdheSddXQogICAgICAgIGlmIHIuZ2V0KCdkZXYnKTphcmdzKz1bJ2RldicsclsnZGV2J11dCiAgICAgICAgYXJncys9Wyd0YWJsZScsc3RyKHJbJ3RhYmxlJ10pLCdtZXRyaWMnLHN0cihyWydtZXRyaWMnXSksJ3Byb3RvJyxzdHIoclsncHJvdG9jb2wnXSldCiAgICAgICAgaWYgdmVyYiE9J2RlbCc6CiAgICAgICAgICAgIGlmIHIuZ2V0KCdwcmVmc3JjJyk6YXJncys9WydzcmMnLHJbJ3ByZWZzcmMnXV0KICAgICAgICAgICAgaWYgci5nZXQoJ29ubGluaycpOmFyZ3MrPVsnb25saW5rJ10KICAgICAgICAgICAgaWYgci5nZXQoJ210dScpOmFyZ3MrPVsnbXR1JyxzdHIoclsnbXR1J10pXQogICAgICAgICAgICBpZiByLmdldCgncHJlZicpOmFyZ3MrPVsncHJlZicsclsncHJlZiddXQogICAgICAgIHJldHVybiBhcmdzCiAgICBkZWYgcHV0X3JvdXRlKHNlbGYscik6c2VsZi5jb21tYW5kKHNlbGYucm91dGVfYXJncygncmVwbGFjZScscikpCiAgICBkZWYgZGVsX3JvdXRlKHNlbGYscik6c2VsZi5jb21tYW5kKHNlbGYucm91dGVfYXJncygnZGVsJyxyKSkKICAgIGRlZiBwdXRfcnVsZShzZWxmLHIpOnNlbGYuY29tbWFuZChbJ2lwJywnLTYnLCdydWxlJywnYWRkJywncHJlZicsc3RyKHJbJ3ByaW9yaXR5J10pLCdmcm9tJyxyWydzb3VyY2UnXSwndGFibGUnLHJbJ3RhYmxlJ11dKQogICAgZGVmIGRlbF9ydWxlKHNlbGYscik6c2VsZi5jb21tYW5kKFsnaXAnLCctNicsJ3J1bGUnLCdkZWwnLCdwcmVmJyxzdHIoclsncHJpb3JpdHknXSksJ2Zyb20nLHJbJ3NvdXJjZSddLCd0YWJsZScsclsndGFibGUnXV0pCiAgICBkZWYgc25hcHNob3Qoc2VsZixzY29wZSk6CiAgICAgICAgYWRkcmVzc2VzPXNlbGYuYWRkcmVzc2VzKCkKICAgICAgICByb3V0ZXM9W3IgZm9yIHIgaW4gc2VsZi5yb3V0ZXMoKSBpZiBrZXlfc3RyaW5nKHIpIGluIHNjb3BlWydyb3V0ZV9rZXlzJ11dCiAgICAgICAgcnVsZXM9W3IgZm9yIHIgaW4gc2VsZi5ydWxlcygpIGlmIHJbJ3ByaW9yaXR5J10gaW4gc2NvcGVbJ3ByaW9yaXRpZXMnXV0KICAgICAgICByZXR1cm4geydhZGRyZXNzZXMnOnNvcnRlZChhIGZvciBhIGluIHNjb3BlWydhZGRyZXNzZXMnXSBpZiBhIGluIGFkZHJlc3NlcyksICdyb3V0ZXMnOnJvdXRlcywncnVsZXMnOnJ1bGVzfQogICAgZGVmIHRyYW5zaXRpb24oc2VsZixzY29wZSx0YXJnZXQpOgogICAgICAgICIiIkFkZCB1c2FibGUgcmVwbGFjZW1lbnRzIGZpcnN0LiBEZWxldGUgb2Jzb2xldGUgcmVzb3VyY2VzIGxhc3QuIiIiCiAgICAgICAgZm9yIGFkZHJlc3MgaW4gdGFyZ2V0WydhZGRyZXNzZXMnXTpzZWxmLnB1dF9hZGRyZXNzKGFkZHJlc3MpCiAgICAgICAgc2VsZi53YWl0X2FkZHJlc3Nlcyh0YXJnZXRbJ2FkZHJlc3NlcyddKQogICAgICAgIGN1cnJlbnQ9c2VsZi5zbmFwc2hvdChzY29wZSkKICAgICAgICBleGlzdGluZz17a2V5X3N0cmluZyhyKTpyIGZvciByIGluIGN1cnJlbnRbJ3JvdXRlcyddfQogICAgICAgICMgR2F0ZXdheSByZWFjaGFiaWxpdHkgcHJlY2VkZXMgZGVmYXVsdHMuIE1haW4tdGFibGUgc291cmNlIHNlbGVjdGlvbiBpcyBsYXN0LgogICAgICAgIG9yZGVyZWQ9c29ydGVkKHRhcmdldFsncm91dGVzJ10sa2V5PWxhbWJkYSByOihyWyd0YWJsZSddPT0yNTQsclsnZHN0J109PSc6Oi8wJyxyWydtZXRyaWMnXSkpCiAgICAgICAgZm9yIHIgaW4gb3JkZXJlZDoKICAgICAgICAgICAgaWYgclsndGFibGUnXT09MjU0OmNvbnRpbnVlCiAgICAgICAgICAgIGlmIGV4aXN0aW5nLmdldChrZXlfc3RyaW5nKHIpKSE9cjpzZWxmLnB1dF9yb3V0ZShyKQogICAgICAgIGRlc2lyZWRfcnVsZXM9e3JbJ3ByaW9yaXR5J106ciBmb3IgciBpbiB0YXJnZXRbJ3J1bGVzJ119CiAgICAgICAgZm9yIHIgaW4gY3VycmVudFsncnVsZXMnXToKICAgICAgICAgICAgaWYgZGVzaXJlZF9ydWxlcy5nZXQoclsncHJpb3JpdHknXSkhPXI6c2VsZi5kZWxfcnVsZShyKQogICAgICAgIHByZXNlbnQ9e3JbJ3ByaW9yaXR5J106ciBmb3IgciBpbiBzZWxmLnNuYXBzaG90KHNjb3BlKVsncnVsZXMnXX0KICAgICAgICBmb3IgciBpbiB0YXJnZXRbJ3J1bGVzJ106CiAgICAgICAgICAgIGlmIHByZXNlbnQuZ2V0KHJbJ3ByaW9yaXR5J10pIT1yOnNlbGYucHV0X3J1bGUocikKICAgICAgICBmb3IgciBpbiBvcmRlcmVkOgogICAgICAgICAgICBpZiByWyd0YWJsZSddPT0yNTQgYW5kIGV4aXN0aW5nLmdldChrZXlfc3RyaW5nKHIpKSE9cjpzZWxmLnB1dF9yb3V0ZShyKQogICAgICAgIGRlc2lyZWRfa2V5cz17a2V5X3N0cmluZyhyKSBmb3IgciBpbiB0YXJnZXRbJ3JvdXRlcyddfQogICAgICAgIGZvciByIGluIHNlbGYuc25hcHNob3Qoc2NvcGUpWydyb3V0ZXMnXToKICAgICAgICAgICAgaWYga2V5X3N0cmluZyhyKSBub3QgaW4gZGVzaXJlZF9rZXlzOnNlbGYuZGVsX3JvdXRlKHIpCiAgICAgICAgZm9yIGFkZHJlc3MgaW4gc2V0KHNlbGYuc25hcHNob3Qoc2NvcGUpWydhZGRyZXNzZXMnXSktc2V0KHRhcmdldFsnYWRkcmVzc2VzJ10pOnNlbGYuZGVsX2FkZHJlc3MoYWRkcmVzcykKICAgICAgICBzZWxmLnZlcmlmeShzY29wZSx0YXJnZXQpCiAgICBkZWYgdmVyaWZ5KHNlbGYsc2NvcGUsdGFyZ2V0KToKICAgICAgICBhY3R1YWw9c2VsZi5zbmFwc2hvdChzY29wZSkKICAgICAgICBkZWYgY2Fub25pY2FsKHgpOnJldHVybiB7azpzb3J0ZWQodixrZXk9bGFtYmRhIHI6anNvbi5kdW1wcyhyLHNvcnRfa2V5cz1UcnVlKSkgZm9yIGssdiBpbiB4Lml0ZW1zKCl9CiAgICAgICAgaWYgY2Fub25pY2FsKGFjdHVhbCkhPWNhbm9uaWNhbCh0YXJnZXQpOnJhaXNlIFJ1bnRpbWVFcnJvcignS2VybmVsIHN0YXRlIGRvZXMgbm90IG1hdGNoIHRoZSBzdGFnZWQgY29uZmlndXJhdGlvbicpCiAgICAgICAgc2VsZi53YWl0X2FkZHJlc3Nlcyh0YXJnZXRbJ2FkZHJlc3NlcyddKQoKY2xhc3MgSm91cm5hbDoKICAgIGRlZiBfX2luaXRfXyhzZWxmLHJvb3Qsa2VybmVsKToKICAgICAgICBzZWxmLnJvb3Q9cGF0aGxpYi5QYXRoKHJvb3QpO3NlbGYua2VybmVsPWtlcm5lbDtzZWxmLnBhdGg9c2VsZi5yb290Lyd0cmFuc2FjdGlvbi5qc29uJwogICAgQHN0YXRpY21ldGhvZAogICAgZGVmIGJvb3RfaWQoKTpyZXR1cm4gcGF0aGxpYi5QYXRoKCcvcHJvYy9zeXMva2VybmVsL3JhbmRvbS9ib290X2lkJykucmVhZF90ZXh0KCkuc3RyaXAoKQogICAgZGVmIHJlbW92ZShzZWxmKToKICAgICAgICBzZWxmLnBhdGgudW5saW5rKG1pc3Npbmdfb2s9VHJ1ZSkKICAgICAgICBmZD1vcy5vcGVuKHNlbGYucm9vdCxvcy5PX0RJUkVDVE9SWSkKICAgICAgICB0cnk6b3MuZnN5bmMoZmQpCiAgICAgICAgZmluYWxseTpvcy5jbG9zZShmZCkKICAgIGRlZiBiZWdpbihzZWxmLHNjb3BlLHRhcmdldCxzdGF0ZSxyZWNvdmVyeSxyZWNvdmVyeV9zdGF0ZSk6CiAgICAgICAgaWYgc2VsZi5wYXRoLmV4aXN0cygpOnJhaXNlIFJ1bnRpbWVFcnJvcignQSBwcmV2aW91cyBuZXR3b3JraW5nIHRyYW5zYWN0aW9uIHN0aWxsIG5lZWRzIHJlY292ZXJ5JykKICAgICAgICB0b2tlbj11dWlkLnV1aWQ0KCkuaGV4O3N0YXRlPWNvcHkuZGVlcGNvcHkoc3RhdGUpO3N0YXRlWyd0cmFuc2FjdGlvbl9pZCddPXRva2VuCiAgICAgICAgam91cm5hbD17J3ZlcnNpb24nOjEsJ2lkJzp0b2tlbiwnaWZhY2UnOnNlbGYua2VybmVsLmlmYWNlLCdib290X2lkJzpzZWxmLmJvb3RfaWQoKSwnc2NvcGUnOnNjb3BlLAogICAgICAgICAgICAgICAgICd0YXJnZXQnOnRhcmdldCwnc3RhdGUnOnN0YXRlLCdyZWNvdmVyeSc6cmVjb3ZlcnksJ3JlY292ZXJ5X3N0YXRlJzpyZWNvdmVyeV9zdGF0ZX0KICAgICAgICBzYXZlKHNlbGYucGF0aCxqb3VybmFsKQogICAgICAgIHJldHVybiBqb3VybmFsCiAgICBkZWYgY29tbWl0KHNlbGYsam91cm5hbCk6CiAgICAgICAgc2F2ZShzZWxmLnJvb3QvJ3N0YXRlLmpzb24nLGpvdXJuYWxbJ3N0YXRlJ10pCiAgICAgICAgc2VsZi5yZW1vdmUoKQogICAgICAgIHJldHVybiBjb3B5LmRlZXBjb3B5KGpvdXJuYWxbJ3N0YXRlJ10pCg==', 'dvn_events.py': 'IyEvdXNyL2Jpbi9lbnYgcHl0aG9uMwoiIiJPcHRpb25hbCBwZXJzaXN0ZW50IGNoYW5nZSBub3RpZmljYXRpb25zOyBwb2xsaW5nIGFuZCBhYnNvbHV0ZSBleHBpcnkgcmVtYWluIGF1dGhvcml0YXRpdmUuIiIiCmltcG9ydCBqc29uLHJhbmRvbSxzb2NrZXQsdGhyZWFkaW5nLHRpbWUsdXJsbGliLnJlcXVlc3QKZnJvbSBkdm5fY29tbW9uIGltcG9ydCBwb3N0LE1hbmFnZW1lbnRIVFRQUyxOb1JlZGlyZWN0CgpjbGFzcyBFdmVudExpc3RlbmVyOgogICAgZGVmIF9faW5pdF9fKHNlbGYsY2ZnLGtpbmQpOgogICAgICAgIHNlbGYuY2ZnPWNmZztzZWxmLmtpbmQ9a2luZDtzZWxmLndha2U9dGhyZWFkaW5nLkV2ZW50KCk7c2VsZi5zdG9wX2ZsYWc9dGhyZWFkaW5nLkV2ZW50KCk7c2VsZi50aHJlYWQ9Tm9uZTtzZWxmLnJlc3BvbnNlPU5vbmUKICAgIGRlZiBjb25maWd1cmUoc2VsZixlbmFibGVkKToKICAgICAgICBpZiBlbmFibGVkIGFuZCAoc2VsZi50aHJlYWQgaXMgTm9uZSBvciBub3Qgc2VsZi50aHJlYWQuaXNfYWxpdmUoKSk6CiAgICAgICAgICAgIHNlbGYuc3RvcF9mbGFnLmNsZWFyKCk7c2VsZi50aHJlYWQ9dGhyZWFkaW5nLlRocmVhZCh0YXJnZXQ9c2VsZi5ydW4sZGFlbW9uPVRydWUpO3NlbGYudGhyZWFkLnN0YXJ0KCkKICAgICAgICBlbGlmIG5vdCBlbmFibGVkIGFuZCBzZWxmLnRocmVhZCBpcyBub3QgTm9uZToKICAgICAgICAgICAgc2VsZi5zdG9wX2ZsYWcuc2V0KCkKICAgICAgICAgICAgaWYgc2VsZi5yZXNwb25zZToKICAgICAgICAgICAgICAgIHRyeTpzZWxmLnJlc3BvbnNlLmZwLnJhdy5fc29jay5zaHV0ZG93bihzb2NrZXQuU0hVVF9SRFdSKQogICAgICAgICAgICAgICAgZXhjZXB0IChPU0Vycm9yLEF0dHJpYnV0ZUVycm9yKTpwYXNzCiAgICBkZWYgY29uc3VtZShzZWxmKToKICAgICAgICBpZiBub3Qgc2VsZi53YWtlLmlzX3NldCgpOnJldHVybiBGYWxzZQogICAgICAgIHNlbGYud2FrZS5jbGVhcigpO3JldHVybiBUcnVlCiAgICBkZWYgcnVuKHNlbGYpOgogICAgICAgIGRlbGF5PTEKICAgICAgICB3aGlsZSBub3Qgc2VsZi5zdG9wX2ZsYWcuaXNfc2V0KCk6CiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIGJvZHk9eydraW5kJzpzZWxmLmtpbmR9O2JvZHkudXBkYXRlKHsnaG9zdF9pZCc6c2VsZi5jZmdbJ2hvc3RfaWQnXX1pZiBzZWxmLmtpbmQ9PSdob3N0J2Vsc2V7J3V1aWQnOnNlbGYuY2ZnWyd1dWlkJ119KQogICAgICAgICAgICAgICAgdGlja2V0PXBvc3Qoc2VsZi5jZmdbJ2Jhc2VfdXJsJ10sJy9hcGkvZHluYW1pY3Y2LW5leHQvc3RyZWFtL3RpY2tldCcsc2VsZi5jZmdbJ3Rva2VuJ10sYm9keSkKICAgICAgICAgICAgICAgIGlmIHRpY2tldC5nZXQoJ3VybCcpIT0nL2FwaS9keW5hbWljdjYtbmV4dC9ldmVudHMnOnJhaXNlIFZhbHVlRXJyb3IoJ1VuZXhwZWN0ZWQgc3RyZWFtIFVSTCcpCiAgICAgICAgICAgICAgICByZXE9dXJsbGliLnJlcXVlc3QuUmVxdWVzdChzZWxmLmNmZ1snYmFzZV91cmwnXS5yc3RyaXAoJy8nKSt0aWNrZXRbJ3VybCddLGhlYWRlcnM9eydBdXRob3JpemF0aW9uJzonQmVhcmVyICcrdGlja2V0Wyd0aWNrZXQnXSwnQWNjZXB0JzondGV4dC9ldmVudC1zdHJlYW0nLCdVc2VyLUFnZW50JzonWGVwZXJ0VjYtZXZlbnRzLzEnfSkKICAgICAgICAgICAgICAgIG9wZW5lcj11cmxsaWIucmVxdWVzdC5idWlsZF9vcGVuZXIodXJsbGliLnJlcXVlc3QuUHJveHlIYW5kbGVyKHt9KSxNYW5hZ2VtZW50SFRUUFMoKSxOb1JlZGlyZWN0KCkpCiAgICAgICAgICAgICAgICB3aXRoIG9wZW5lci5vcGVuKHJlcSx0aW1lb3V0PTM1KWFzIHJlc3BvbnNlOgogICAgICAgICAgICAgICAgICAgIHNlbGYucmVzcG9uc2U9cmVzcG9uc2U7ZGVsYXk9MTtsYXN0PTAKICAgICAgICAgICAgICAgICAgICB3aGlsZSBub3Qgc2VsZi5zdG9wX2ZsYWcuaXNfc2V0KCk6CiAgICAgICAgICAgICAgICAgICAgICAgIGxpbmU9cmVzcG9uc2UucmVhZGxpbmUoMTYzODUpCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIG5vdCBsaW5lOmJyZWFrCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIGxlbihsaW5lKT4xNjM4NDpyYWlzZSBWYWx1ZUVycm9yKCdPdmVyc2l6ZSBldmVudCcpCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIGxpbmUuc3RhcnRzd2l0aChiJ2RhdGE6Jyk6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBqc29uLmxvYWRzKGxpbmVbNTpdKTtub3c9dGltZS5tb25vdG9uaWMoKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgbm93LWxhc3Q+PS4yOnNlbGYud2FrZS5zZXQoKTtsYXN0PW5vdwogICAgICAgICAgICAgICAgc2VsZi5yZXNwb25zZT1Ob25lCiAgICAgICAgICAgIGV4Y2VwdCBFeGNlcHRpb246c2VsZi5yZXNwb25zZT1Ob25lCiAgICAgICAgICAgIGlmIHNlbGYuc3RvcF9mbGFnLndhaXQoZGVsYXkrcmFuZG9tLnJhbmRvbSgpKTpyZXR1cm4KICAgICAgICAgICAgZGVsYXk9bWluKDMwLGRlbGF5KjIpCg==', 'dynamicv6-next-guest.service': 'W1VuaXRdCkRlc2NyaXB0aW9uPUR5bmFtaWNWNiBOZXh0IGd1ZXN0IHJvdXRpbmcgcmVjb25jaWxlcgpBZnRlcj1uZXR3b3JrLW9ubGluZS50YXJnZXQKV2FudHM9bmV0d29yay1vbmxpbmUudGFyZ2V0CgpbU2VydmljZV0KVHlwZT1zaW1wbGUKRXhlY1N0YXJ0PS91c3IvYmluL3B5dGhvbjMgL29wdC9keW5hbWljdjYtbmV4dC9kdm5fZ3Vlc3QucHkKUmVzdGFydD1vbi1mYWlsdXJlClJlc3RhcnRTZWM9MwpVTWFzaz0wMDc3CgpbSW5zdGFsbF0KV2FudGVkQnk9bXVsdGktdXNlci50YXJnZXQK', 'dynamicv6-next-guest.openrc': 'IyEvc2Jpbi9vcGVucmMtcnVuCmRlc2NyaXB0aW9uPSJEeW5hbWljVjYgTmV4dCBndWVzdCByb3V0aW5nIHJlY29uY2lsZXIiCmNvbW1hbmQ9Ii91c3IvYmluL3B5dGhvbjMiCmNvbW1hbmRfYXJncz0iL29wdC9keW5hbWljdjYtbmV4dC9kdm5fZ3Vlc3QucHkiCnN1cGVydmlzb3I9InN1cGVydmlzZS1kYWVtb24iCnJlc3Bhd25fZGVsYXk9MwpyZXNwYXduX21heD0wCnBpZGZpbGU9Ii9ydW4vJHtSQ19TVkNOQU1FfS5waWQiCm91dHB1dF9sb2c9Ii92YXIvbG9nL2R5bmFtaWN2Ni1uZXh0LWd1ZXN0LmxvZyIKZXJyb3JfbG9nPSIvdmFyL2xvZy9keW5hbWljdjYtbmV4dC1ndWVzdC5sb2ciCmRlcGVuZCgpIHsKICAgIG5lZWQgbmV0CiAgICBhZnRlciBmaXJld2FsbAp9CnN0YXJ0X3ByZSgpIHsKICAgIHVtYXNrIDA3NwogICAgY2hlY2twYXRoIC0tZmlsZSAtLW1vZGUgMDYwMCAtLW93bmVyIHJvb3Q6cm9vdCAiJG91dHB1dF9sb2ciCn0K', 'dvn_cli.py': 'IiIiRW1iZWRkZWQgY29tbWFuZCBsYXllciBmb3IgdGhlIHNpbmdsZS1maWxlIER5bmFtaWNWNiBCYXNoIGNsaWVudC4iIiIKaW1wb3J0IGFyZ3BhcnNlLCBjb250ZXh0bGliLCBjb3B5LCBoYXNobGliLCBpcGFkZHJlc3MsIGpzb24sIG9zLCBwYXRobGliLCBzaGxleCwgc2h1dGlsLCBzdWJwcm9jZXNzLCBzeXMsIHRpbWUsIHV1aWQsIHVybGxpYi5lcnJvcgpmcm9tIGR2bl9jb21tb24gaW1wb3J0IHJlYWQsIHNhdmUsIGxvY2ssIHBvc3QsIHZhbGlkX25hbWUKZnJvbSBkdm5fZ3Vlc3QgaW1wb3J0IEd1ZXN0CmZyb20gZHZuX3RyYW5zYWN0aW9uIGltcG9ydCBrZXlfc3RyaW5nCgpVTklUPSdkeW5hbWljdjYtbmV4dC1ndWVzdC5zZXJ2aWNlJwpGSUxFUz0oJ2R2bl9ndWVzdC5weScsJ2R2bl9jb21tb24ucHknLCdkdm5fdHJhbnNhY3Rpb24ucHknLCdkdm5fZXZlbnRzLnB5JykKQ09OVFJPTExFUj0naHR0cHM6Ly9hZXRoZXJjbG91ZC5pbycKCmNsYXNzIEVucm9sbG1lbnRSZXF1aXJlZChSdW50aW1lRXJyb3IpOiBwYXNzCgpjbGFzcyBDbGllbnQ6CiAgICBkZWYgX19pbml0X18oc2VsZixidW5kbGUsYnVuZGxlZF9jb25maWc9Tm9uZSxyb290PScvJyk6CiAgICAgICAgc2VsZi5idW5kbGU9cGF0aGxpYi5QYXRoKGJ1bmRsZSk7c2VsZi5idW5kbGVkPWJ1bmRsZWRfY29uZmlnCiAgICAgICAgc2VsZi5yb290PXBhdGhsaWIuUGF0aChyb290KQogICAgICAgIHNlbGYuY29kZT1zZWxmLnJvb3QvJ29wdC9keW5hbWljdjYtbmV4dCc7c2VsZi5jZmdmaWxlPXNlbGYucm9vdC8nZXRjL2R5bmFtaWN2Ni1uZXh0L2d1ZXN0Lmpzb24nCiAgICAgICAgc2VsZi5zdGF0ZT1zZWxmLnJvb3QvJ3Zhci9saWIvZHluYW1pY3Y2LW5leHQtZ3Vlc3QnO3NlbGYudW5pdD1zZWxmLnJvb3QvJ2V0Yy9zeXN0ZW1kL3N5c3RlbScvVU5JVAogICAgICAgIHNlbGYuY2FjaGU9c2VsZi5zdGF0ZS8nc3RhdHVzLWNhY2hlLmpzb24nO3NlbGYuYmFzZWxpbmU9c2VsZi5zdGF0ZS8nbmV0d29yay1iYXNlbGluZS5qc29uJztzZWxmLmluaXQ9Tm9uZQogICAgZGVmIGNvbW1hbmQoc2VsZixhcmdzLGNoZWNrPVRydWUpOgogICAgICAgIHA9c3VicHJvY2Vzcy5ydW4oYXJncyxjYXB0dXJlX291dHB1dD1UcnVlLHRleHQ9VHJ1ZSx0aW1lb3V0PTQ1KQogICAgICAgIGlmIGNoZWNrIGFuZCBwLnJldHVybmNvZGU6cmFpc2UgUnVudGltZUVycm9yKHAuc3RkZXJyLnN0cmlwKClbOjI1MF0gb3IgJ0NvbW1hbmQgZmFpbGVkOiAnK2FyZ3NbMF0pCiAgICAgICAgcmV0dXJuIHAuc3Rkb3V0LnN0cmlwKCkKICAgIGRlZiBoYXJkd2FyZV91dWlkKHNlbGYpOgogICAgICAgIGZvciBuYW1lIGluIFsnc3lzL2NsYXNzL2RtaS9pZC9wcm9kdWN0X3V1aWQnLCdzeXMvZGV2aWNlcy92aXJ0dWFsL2RtaS9pZC9wcm9kdWN0X3V1aWQnXToKICAgICAgICAgICAgcGF0aD1zZWxmLnJvb3QvbmFtZQogICAgICAgICAgICBpZiBwYXRoLmV4aXN0cygpOnJldHVybiBzdHIodXVpZC5VVUlEKHBhdGgucmVhZF90ZXh0KCkuc3RyaXAoKSkpCiAgICAgICAgcmFpc2UgUnVudGltZUVycm9yKCdUaGUgVk0gVVVJRCBpcyB1bmF2YWlsYWJsZSBpbiBzeXNmczsgaW5zdGFsbGF0aW9uIGNhbm5vdCB2ZXJpZnkgdGhpcyBWTS4nKQogICAgZGVmIHNldHVwX2luaXQoc2VsZik6CiAgICAgICAgaWYgc2VsZi5pbml0OnJldHVybiBzZWxmLmluaXQKICAgICAgICBpZiAoc2VsZi5yb290LydydW4vc3lzdGVtZC9zeXN0ZW0nKS5leGlzdHMoKSBhbmQgc2h1dGlsLndoaWNoKCdzeXN0ZW1jdGwnKToKICAgICAgICAgICAgc2VsZi5pbml0PSdzeXN0ZW1kJztzZWxmLnVuaXQ9c2VsZi5yb290LydldGMvc3lzdGVtZC9zeXN0ZW0nL1VOSVQKICAgICAgICBlbGlmIChzZWxmLnJvb3QvJ3J1bi9vcGVucmMnKS5leGlzdHMoKSBhbmQgc2h1dGlsLndoaWNoKCdyYy1zZXJ2aWNlJykgYW5kIHNodXRpbC53aGljaCgncmMtdXBkYXRlJykgYW5kIHNodXRpbC53aGljaCgnc3VwZXJ2aXNlLWRhZW1vbicpOgogICAgICAgICAgICBzZWxmLmluaXQ9J29wZW5yYyc7c2VsZi51bml0PXNlbGYucm9vdC8nZXRjL2luaXQuZC9keW5hbWljdjYtbmV4dC1ndWVzdCcKICAgICAgICBlbHNlOnJhaXNlIFJ1bnRpbWVFcnJvcignQSBydW5uaW5nIHN5c3RlbWQgb3IgT3BlblJDIGluc3RhbGxhdGlvbiBpcyByZXF1aXJlZC4gVGhlIGluc3RhbGxlciB3aWxsIG5vdCByZXBsYWNlIHlvdXIgaW5pdCBzeXN0ZW0uJykKICAgICAgICByZXR1cm4gc2VsZi5pbml0CiAgICBkZWYgc2VydmljZV9zdGF0ZShzZWxmKToKICAgICAgICBpZiBzZWxmLnNldHVwX2luaXQoKT09J3N5c3RlbWQnOnJldHVybiBzZWxmLmNvbW1hbmQoWydzeXN0ZW1jdGwnLCdpcy1hY3RpdmUnLFVOSVRdLEZhbHNlKSBvciAnaW5hY3RpdmUnCiAgICAgICAgdHJ5OnNlbGYuY29tbWFuZChbJ3JjLXNlcnZpY2UnLCdkeW5hbWljdjYtbmV4dC1ndWVzdCcsJ3N0YXR1cyddKTtyZXR1cm4gJ2FjdGl2ZScKICAgICAgICBleGNlcHQgUnVudGltZUVycm9yOnJldHVybiAnaW5hY3RpdmUnCiAgICBkZWYgc2VydmljZV9lbmFibGVkKHNlbGYpOgogICAgICAgIGlmIHNlbGYuc2V0dXBfaW5pdCgpPT0nc3lzdGVtZCc6cmV0dXJuIHNlbGYuY29tbWFuZChbJ3N5c3RlbWN0bCcsJ2lzLWVuYWJsZWQnLFVOSVRdLEZhbHNlKT09J2VuYWJsZWQnCiAgICAgICAgcGF0aD1zZWxmLnJvb3QvJ2V0Yy9ydW5sZXZlbHMvZGVmYXVsdC9keW5hbWljdjYtbmV4dC1ndWVzdCcKICAgICAgICByZXR1cm4gcGF0aC5leGlzdHMoKSBvciBwYXRoLmlzX3N5bWxpbmsoKQogICAgZGVmIHNlcnZpY2Vfc3RvcChzZWxmLGNoZWNrPVRydWUpOgogICAgICAgIHJldHVybiBzZWxmLmNvbW1hbmQoWydzeXN0ZW1jdGwnLCdzdG9wJyxVTklUXSBpZiBzZWxmLnNldHVwX2luaXQoKT09J3N5c3RlbWQnIGVsc2UgWydyYy1zZXJ2aWNlJywnZHluYW1pY3Y2LW5leHQtZ3Vlc3QnLCdzdG9wJ10sY2hlY2spCiAgICBkZWYgc2VydmljZV9zdGFydChzZWxmLGNoZWNrPVRydWUpOgogICAgICAgIHJldHVybiBzZWxmLmNvbW1hbmQoWydzeXN0ZW1jdGwnLCdzdGFydCcsVU5JVF0gaWYgc2VsZi5zZXR1cF9pbml0KCk9PSdzeXN0ZW1kJyBlbHNlIFsncmMtc2VydmljZScsJ2R5bmFtaWN2Ni1uZXh0LWd1ZXN0Jywnc3RhcnQnXSxjaGVjaykKICAgIGRlZiBzZXJ2aWNlX2VuYWJsZV9zdGFydChzZWxmKToKICAgICAgICBpZiBzZWxmLnNldHVwX2luaXQoKT09J3N5c3RlbWQnOnNlbGYuY29tbWFuZChbJ3N5c3RlbWN0bCcsJ2VuYWJsZScsJy0tbm93JyxVTklUXSkKICAgICAgICBlbHNlOnNlbGYuY29tbWFuZChbJ3JjLXVwZGF0ZScsJ2FkZCcsJ2R5bmFtaWN2Ni1uZXh0LWd1ZXN0JywnZGVmYXVsdCddKTtzZWxmLnNlcnZpY2Vfc3RhcnQoKQogICAgZGVmIHNlcnZpY2VfZGlzYWJsZShzZWxmLGNoZWNrPVRydWUpOgogICAgICAgIHJldHVybiBzZWxmLmNvbW1hbmQoWydzeXN0ZW1jdGwnLCdkaXNhYmxlJyxVTklUXSBpZiBzZWxmLnNldHVwX2luaXQoKT09J3N5c3RlbWQnIGVsc2UgWydyYy11cGRhdGUnLCdkZWwnLCdkeW5hbWljdjYtbmV4dC1ndWVzdCcsJ2RlZmF1bHQnXSxjaGVjaykKICAgIGRlZiBzZXJ2aWNlX3JlbG9hZChzZWxmLGNoZWNrPVRydWUpOgogICAgICAgIGlmIHNlbGYuc2V0dXBfaW5pdCgpPT0nc3lzdGVtZCc6c2VsZi5jb21tYW5kKFsnc3lzdGVtY3RsJywnZGFlbW9uLXJlbG9hZCddLGNoZWNrKQogICAgZGVmIHRpbWVyX2ZpbGVzKHNlbGYpOgogICAgICAgIGlmIHNlbGYuc2V0dXBfaW5pdCgpIT0nc3lzdGVtZCc6cmV0dXJuIFtdCiAgICAgICAgcmV0dXJuIFtzZWxmLnJvb3QvcGF0aC8nZHluYW1pY3Y2LW5leHQtZ3Vlc3QudGltZXInIGZvciBwYXRoIGluIFsnZXRjL3N5c3RlbWQvc3lzdGVtJywncnVuL3N5c3RlbWQvc3lzdGVtJywndXNyL2xpYi9zeXN0ZW1kL3N5c3RlbScsJ2xpYi9zeXN0ZW1kL3N5c3RlbSddIGlmIChzZWxmLnJvb3QvcGF0aC8nZHluYW1pY3Y2LW5leHQtZ3Vlc3QudGltZXInKS5leGlzdHMoKV0KICAgIGRlZiBzdG9wX3RpbWVyKHNlbGYpOgogICAgICAgIGlmIHNlbGYuc2V0dXBfaW5pdCgpIT0nc3lzdGVtZCc6cmV0dXJuIEZhbHNlCiAgICAgICAgYWN0aXZlPXNlbGYuY29tbWFuZChbJ3N5c3RlbWN0bCcsJ2lzLWFjdGl2ZScsJ2R5bmFtaWN2Ni1uZXh0LWd1ZXN0LnRpbWVyJ10sRmFsc2UpPT0nYWN0aXZlJwogICAgICAgIHNlbGYuY29tbWFuZChbJ3N5c3RlbWN0bCcsJ3N0b3AnLCdkeW5hbWljdjYtbmV4dC1ndWVzdC50aW1lciddLGFjdGl2ZSkKICAgICAgICByZXR1cm4gYWN0aXZlCiAgICBkZWYgcmVzdG9yZV9uYXRpdmUoc2VsZixnLGJlZm9yZSk6CiAgICAgICAgYmFzZWxpbmU9cmVhZChzZWxmLmJhc2VsaW5lKTtvcmlnaW5hbD1iYXNlbGluZS5nZXQoJ25hdGl2ZScpIG9yIHt9CiAgICAgICAgaWYgbm90IGJlZm9yZToKICAgICAgICAgICAgZy5jbGVhbnVwKCk7cmV0dXJuIG5vdCBvcmlnaW5hbAogICAgICAgIHNhbWU9YmFzZWxpbmUuZ2V0KCd1dWlkJyk9PXNlbGYuaGFyZHdhcmVfdXVpZCgpIGFuZCBiYXNlbGluZS5nZXQoJ2ludGVyZmFjZScpPT1nLmlmYWNlIGFuZCBvcmlnaW5hbC5nZXQoJ2FkZHJlc3MnKT09YmVmb3JlWydhZGRyZXNzJ10gYW5kIG9yaWdpbmFsLmdldCgnY2lkcicpPT1iZWZvcmVbJ2NpZHInXSBhbmQgb3JpZ2luYWwuZ2V0KCdyb3V0ZScse30pLmdldCgnZ2F0ZXdheScpPT1iZWZvcmVbJ3JvdXRlJ10uZ2V0KCdnYXRld2F5JykKICAgICAgICBvcmlnaW5hbF9yb3V0ZT1jb3B5LmRlZXBjb3B5KG9yaWdpbmFsLmdldCgncm91dGUnLHt9KSk7Y3VycmVudF9yb3V0ZT1jb3B5LmRlZXBjb3B5KGJlZm9yZVsncm91dGUnXSkKICAgICAgICBvcmlnaW5hbF9yb3V0ZS5wb3AoJ3ByZWZzcmMnLE5vbmUpO2N1cnJlbnRfcm91dGUucG9wKCdwcmVmc3JjJyxOb25lKQogICAgICAgIHNhbWU9Ym9vbChzYW1lIGFuZCBvcmlnaW5hbF9yb3V0ZT09Y3VycmVudF9yb3V0ZSkKICAgICAgICBvd25lZD1uZXh0KChyIGZvciByIGluIGcuc3RhdGUuZ2V0KCdvd25lZF9yb3V0ZXMnLFtdKSBpZiBrZXlfc3RyaW5nKHIpPT1rZXlfc3RyaW5nKGJlZm9yZVsncm91dGUnXSkpLE5vbmUpCiAgICAgICAgcm91dGU9Y29weS5kZWVwY29weShvcmlnaW5hbFsncm91dGUnXSBpZiBzYW1lIGFuZCBvd25lZD09YmVmb3JlWydyb3V0ZSddIGVsc2UgYmVmb3JlWydyb3V0ZSddKQogICAgICAgIGcuY2xlYW51cCgpCiAgICAgICAgc2NvcGU9eydhZGRyZXNzZXMnOltdLCdyb3V0ZV9rZXlzJzpba2V5X3N0cmluZyhyb3V0ZSldLCdwcmlvcml0aWVzJzpbXX07cHJldmlvdXM9Zy5rZXJuZWwuc25hcHNob3Qoc2NvcGUpCiAgICAgICAgdGFyZ2V0PXsnYWRkcmVzc2VzJzpbXSwncm91dGVzJzpbcm91dGVdLCdydWxlcyc6W119O3N0YXRlPWNvcHkuZGVlcGNvcHkoZy5zdGF0ZSkKICAgICAgICBzdGF0ZVsnbmF0aXZlJ109eyoqYmVmb3JlLCdyb3V0ZSc6cm91dGV9O3N0YXRlWydvd25lZF9yb3V0ZXMnXT1bXQogICAgICAgIGcudHJhbnNhY3Qoc2NvcGUsdGFyZ2V0LHN0YXRlLHByZXZpb3VzLGcuc3RhdGUpCiAgICAgICAgcmV0dXJuIHNhbWUgYW5kIG93bmVkPT1iZWZvcmVbJ3JvdXRlJ10KICAgIGRlZiBkZXRlY3RfaW50ZXJmYWNlKHNlbGYsY2ZnKToKICAgICAgICBpbnRlcmZhY2VzPWpzb24ubG9hZHMoc2VsZi5jb21tYW5kKFsnaXAnLCctaicsJy02JywnYWRkcicsJ3Nob3cnXSkpCiAgICAgICAgbmF0aXZlPXtyb3dbJ2lmbmFtZSddIGZvciByb3cgaW4gaW50ZXJmYWNlcyBpZiByb3dbJ2lmbmFtZSddIT0nbG8nIGFuZCBhbnkoYS5nZXQoJ2ZhbWlseScpPT0naW5ldDYnIGFuZCBhLmdldCgnc2NvcGUnKT09J2dsb2JhbCcgYW5kIGEuZ2V0KCdwcmVmaXhsZW4nKSE9MTI4IGFuZCAobm90IGNmZy5nZXQoJ25hdGl2ZV9zb3VyY2UnKSBvciBhLmdldCgnbG9jYWwnKT09Y2ZnWyduYXRpdmVfc291cmNlJ10pIGZvciBhIGluIHJvdy5nZXQoJ2FkZHJfaW5mbycsW10pKX0KICAgICAgICByb3V0ZXM9anNvbi5sb2FkcyhzZWxmLmNvbW1hbmQoWydpcCcsJy1qJywnLTYnLCdyb3V0ZScsJ3Nob3cnLCdkZWZhdWx0J10pKQogICAgICAgIGNhbmRpZGF0ZXM9c29ydGVkKFtyIGZvciByIGluIHJvdXRlcyBpZiByLmdldCgnZ2F0ZXdheScpIGFuZCByLmdldCgnZGV2JykgaW4gbmF0aXZlIGFuZCByLmdldCgnbWV0cmljJykhPTk5XSxrZXk9bGFtYmRhIHI6ci5nZXQoJ21ldHJpYycsMTAyNCkpCiAgICAgICAgaWYgY2FuZGlkYXRlczpyZXR1cm4gdmFsaWRfbmFtZShjYW5kaWRhdGVzWzBdWydkZXYnXSkKICAgICAgICBpcHY0PWpzb24ubG9hZHMoc2VsZi5jb21tYW5kKFsnaXAnLCctaicsJy00Jywncm91dGUnLCdzaG93JywnZGVmYXVsdCddKSkKICAgICAgICBjYW5kaWRhdGVzPXNvcnRlZChbciBmb3IgciBpbiBpcHY0IGlmIHIuZ2V0KCdkZXYnKSBhbmQgclsnZGV2J10hPSdsbyddLGtleT1sYW1iZGEgcjpyLmdldCgnbWV0cmljJywwKSkKICAgICAgICBpZiBub3QgY2FuZGlkYXRlczpyYWlzZSBSdW50aW1lRXJyb3IoJ05vIGRlZmF1bHQgbmV0d29yayBpbnRlcmZhY2Ugd2FzIGZvdW5kLiBVc2UgaW5zdGFsbCAtLWludGVyZmFjZSBOSUMgdG8gc2VsZWN0IHRoZSBWTSBpbnRlcmZhY2UuJykKICAgICAgICByZXR1cm4gdmFsaWRfbmFtZShjYW5kaWRhdGVzWzBdWydkZXYnXSkKICAgIGRlZiBib290c3RyYXBfY29uZmlndXJhdGlvbihzZWxmLGVucm9sbD1GYWxzZSk6CiAgICAgICAgaWRlbnRpdHk9c2VsZi5oYXJkd2FyZV91dWlkKCkKICAgICAgICB0cnk6CiAgICAgICAgICAgIGRhdGE9cG9zdChDT05UUk9MTEVSLCcvYXBpL2R5bmFtaWN2Ni1uZXh0L2d1ZXN0L2xlYXNlJywnJyx7J3V1aWQnOmlkZW50aXR5LCdlbnJvbGwnOmVucm9sbH0pCiAgICAgICAgICAgIGNmZz1kYXRhLmdldCgnY29uZmlnJyxkYXRhKSBpZiBpc2luc3RhbmNlKGRhdGEsZGljdCkgZWxzZSBkYXRhCiAgICAgICAgZXhjZXB0IHVybGxpYi5lcnJvci5IVFRQRXJyb3IgYXMgZToKICAgICAgICAgICAgdHJ5OmRldGFpbD1qc29uLmxvYWRzKGUucmVhZCg4MTkyKSkKICAgICAgICAgICAgZXhjZXB0IEV4Y2VwdGlvbjpkZXRhaWw9e30KICAgICAgICAgICAgaWYgZGV0YWlsLmdldCgnY29kZScpIGluICgnZW5yb2xsbWVudF9yZXF1aXJlZCcsJ2Vucm9sbG1lbnRfdW5hdmFpbGFibGUnKToKICAgICAgICAgICAgICAgIHJhaXNlIEVucm9sbG1lbnRSZXF1aXJlZChkZXRhaWwuZ2V0KCdtZXNzYWdlJykgb3IgJ1VzZSBpbnN0YWxsIHRvIGVucm9sbCB0aGlzIFZNLCBvciBjb250YWN0IHN1cHBvcnQgaWYgaXQgaXMgcGF1c2VkLicpIGZyb20gTm9uZQogICAgICAgICAgICBpZiBlLmNvZGU9PTQwMzoKICAgICAgICAgICAgICAgIHJhaXNlIFJ1bnRpbWVFcnJvcignVk0gdmVyaWZpY2F0aW9uIGZhaWxlZC4gUnVuIHRoaXMgY29tbWFuZCBkaXJlY3RseSBvbiB0aGUgZW5yb2xsZWQgVk0gdXNpbmcgaXRzIGFzc2lnbmVkIHB1YmxpYyBJUCwgd2l0aG91dCBhbiBleHRlcm5hbCBWUE4sIE5BVCBvciBwcm94eS4nKSBmcm9tIE5vbmUKICAgICAgICAgICAgcmFpc2UgUnVudGltZUVycm9yKCdWTSBzZXR1cCB2ZXJpZmljYXRpb24gaXMgdW5hdmFpbGFibGUuIFBsZWFzZSByZXRyeSBsYXRlciBvciBjb250YWN0IHN1cHBvcnQuJykgZnJvbSBOb25lCiAgICAgICAgaWYgbm90IGlzaW5zdGFuY2UoY2ZnLGRpY3QpIG9yIGNmZy5nZXQoJ3V1aWQnKSE9aWRlbnRpdHk6cmFpc2UgUnVudGltZUVycm9yKCdCb290c3RyYXAgcmV0dXJuZWQgYSBkaWZmZXJlbnQgVk0gaWRlbnRpdHkuJykKICAgICAgICByZXR1cm4gY2ZnCiAgICBkZWYgaW5zdGFsbGVkKHNlbGYpOnJldHVybiBzZWxmLmNmZ2ZpbGUuaXNfZmlsZSgpIGFuZCAoc2VsZi5jb2RlLydkdm5fZ3Vlc3QucHknKS5pc19maWxlKCkKICAgIGRlZiBjb25maWd1cmF0aW9uKHNlbGYscGF0aD1Ob25lLGludGVyZmFjZT1Ob25lLGVucm9sbD1GYWxzZSk6CiAgICAgICAgY2ZnPXJlYWQocGF0aCkgaWYgcGF0aCBlbHNlIChyZWFkKHNlbGYuY2ZnZmlsZSkgaWYgc2VsZi5jZmdmaWxlLmV4aXN0cygpIGVsc2UgKHNlbGYuYnVuZGxlZCBvciBzZWxmLmJvb3RzdHJhcF9jb25maWd1cmF0aW9uKGVucm9sbCkpKQogICAgICAgIGlmIG5vdCBpc2luc3RhbmNlKGNmZyxkaWN0KTpyYWlzZSBFbnJvbGxtZW50UmVxdWlyZWQoJ0Vucm9sbCB0aGlzIFZNIGluIEV4cGVyaW1lbnRhbCBJUHY2IG9uIGl0cyBQYXltZW50ZXIgc2VydmljZSB3ZWJwYWdlIGZpcnN0LCB0aGVuIGRvd25sb2FkIGl0cyBjbGllbnQgc2NyaXB0LicpCiAgICAgICAgY2ZnPWRpY3QoY2ZnKTthY3R1YWw9c2VsZi5oYXJkd2FyZV91dWlkKCkKICAgICAgICBpZiBzZWxmLmJ1bmRsZWQgYW5kIHNlbGYuYnVuZGxlZC5nZXQoJ3V1aWQnLCcnKS5sb3dlcigpIT1hY3R1YWw6cmFpc2UgUnVudGltZUVycm9yKCdUaGlzIGRvd25sb2FkZWQgc2NyaXB0IGJlbG9uZ3MgdG8gYSBkaWZmZXJlbnQgVk0gVVVJRC4nKQogICAgICAgIGlmIHN0cih1dWlkLlVVSUQoY2ZnLmdldCgndXVpZCcsJycpKSkhPWFjdHVhbDpyYWlzZSBSdW50aW1lRXJyb3IoJ0NvbmZpZ3VyYXRpb24gVVVJRCBkb2VzIG5vdCBtYXRjaCB0aGlzIFZNLicpCiAgICAgICAgaWYgbm90IGlzaW5zdGFuY2UoY2ZnLmdldCgndG9rZW4nKSxzdHIpIG9yIGxlbihjZmdbJ3Rva2VuJ10pIT02NDpyYWlzZSBSdW50aW1lRXJyb3IoJ0ludmFsaWQgZ3Vlc3QgY3JlZGVudGlhbC4nKQogICAgICAgIGlmIG5vdCBjZmcuZ2V0KCdiYXNlX3VybCcsJycpLnN0YXJ0c3dpdGgoJ2h0dHBzOi8vJyk6cmFpc2UgUnVudGltZUVycm9yKCdIVFRQUyBjb250cm9sbGVyIFVSTCBpcyByZXF1aXJlZC4nKQogICAgICAgIGlmIGNmZy5nZXQoJ3N0YXRlX2Rpcicsc3RyKHNlbGYuc3RhdGUpKSE9c3RyKHNlbGYuc3RhdGUpOnJhaXNlIFJ1bnRpbWVFcnJvcignVGhpcyB3cmFwcGVyIHJlcXVpcmVzIHRoZSBzdGFuZGFyZCBjbGllbnQgc3RhdGUgZGlyZWN0b3J5LicpCiAgICAgICAgaWYgaW50ZXJmYWNlOmNmZ1snaW50ZXJmYWNlJ109aW50ZXJmYWNlCiAgICAgICAgaWYgY2ZnLmdldCgnaW50ZXJmYWNlJywnYXV0bycpPT0nYXV0byc6Y2ZnWydpbnRlcmZhY2UnXT1zZWxmLmRldGVjdF9pbnRlcmZhY2UoY2ZnKQogICAgICAgIHZhbGlkX25hbWUoY2ZnWydpbnRlcmZhY2UnXSk7Y2ZnLnNldGRlZmF1bHQoJ2RlZmF1bHQnLCduYXRpdmUnKTtjZmcuc2V0ZGVmYXVsdCgnaW50ZXJ2YWwnLDUpCiAgICAgICAgcmV0dXJuIGNmZwogICAgZGVmIGZldGNoKHNlbGYsY2ZnKToKICAgICAgICB0cnk6CiAgICAgICAgICAgIGRhdGE9cG9zdChjZmdbJ2Jhc2VfdXJsJ10sJy9hcGkvZHluYW1pY3Y2LW5leHQvZ3Vlc3Qvc3RhdHVzJyxjZmdbJ3Rva2VuJ10seyd1dWlkJzpjZmdbJ3V1aWQnXX0pCiAgICAgICAgZXhjZXB0IHVybGxpYi5lcnJvci5IVFRQRXJyb3IgYXMgZToKICAgICAgICAgICAgaWYgZS5jb2RlIGluICg0MDEsNDAzLDQwNCk6CiAgICAgICAgICAgICAgICByYWlzZSBFbnJvbGxtZW50UmVxdWlyZWQoJ0Vucm9sbCB0aGlzIFZNIGluIEV4cGVyaW1lbnRhbCBJUHY2IG9uIGl0cyBQYXltZW50ZXIgc2VydmljZSB3ZWJwYWdlIGZpcnN0LCB0aGVuIGRvd25sb2FkIGEgbmV3IGNsaWVudCBzY3JpcHQuIElmIHRoZSBmZWF0dXJlIGlzIHBhdXNlZCwgc3VibWl0IGEgdGlja2V0LicpIGZyb20gTm9uZQogICAgICAgICAgICByYWlzZQogICAgICAgIGlmIGlzaW5zdGFuY2UoZGF0YSxkaWN0KSBhbmQgZGF0YS5nZXQoJ2VuYWJsZWQnKSBpcyBGYWxzZToKICAgICAgICAgICAgcmFpc2UgRW5yb2xsbWVudFJlcXVpcmVkKCdFeHBlcmltZW50YWwgSVB2NiBpcyBub3QgZW5hYmxlZC4gRW5yb2xsIG9uIHRoZSBzZXJ2aWNlIHdlYnBhZ2UgZmlyc3QsIG9yIHN1Ym1pdCBhIHRpY2tldCBpZiBpdCBpcyBwYXVzZWQuJykKICAgICAgICBpZiBub3QgaXNpbnN0YW5jZShkYXRhLGRpY3QpIG9yIGRhdGEuZ2V0KCd1dWlkJykhPWNmZ1sndXVpZCddOnJhaXNlIFJ1bnRpbWVFcnJvcignQ29udHJvbGxlciBpZGVudGl0eSBtaXNtYXRjaC4nKQogICAgICAgIGlmIG5vdCBpc2luc3RhbmNlKGRhdGEuZ2V0KCd1c2FnZScpLGRpY3QpIG9yIG5vdCBpc2luc3RhbmNlKGRhdGEuZ2V0KCdhZGRyZXNzZXMnKSxsaXN0KTpyYWlzZSBSdW50aW1lRXJyb3IoJ0ludmFsaWQgY29udHJvbGxlciBzdGF0dXMuJykKICAgICAgICBmb3IgaXAgaW4gZGF0YVsnYWRkcmVzc2VzJ106aXBhZGRyZXNzLklQdjZBZGRyZXNzKGlwKQogICAgICAgIHJldHVybiBkYXRhCiAgICBkZWYgc3RhdHVzKHNlbGYsb2ZmbGluZT1GYWxzZSk6CiAgICAgICAgaWRlbnRpdHk9c2VsZi5oYXJkd2FyZV91dWlkKCk7bG9jYWw9cmVhZChzZWxmLnN0YXRlLydzdGF0ZS5qc29uJyk7aW5zdGFsbGVkPXNlbGYuaW5zdGFsbGVkKCkKICAgICAgICByZXN1bHQ9eyd1dWlkJzppZGVudGl0eSwnaW5zdGFsbGVkJzppbnN0YWxsZWQsJ2NsaWVudF9zdGF0ZSc6J25vdC1pbnN0YWxsZWQnLCdhZGRyZXNzZXMnOltdLAogICAgICAgICAgICAnYXNzaWduZWRfYWRkcmVzc2VzJzpbXSwnZGVmYXVsdF9wcmVmZXJlbmNlJzpOb25lLCdkZWZhdWx0X2ZhbGxiYWNrJzpOb25lLCdvdXRib3VuZF9pcHY2JzpOb25lLCd1c2FnZSc6Tm9uZSwnY29ubmVjdGlvbl9saW1pdCc6Tm9uZSwncmVwb3J0X3NvdXJjZSc6Tm9uZSwnc3RhbGUnOlRydWUsJ3dhcm5pbmcnOk5vbmV9CiAgICAgICAgaWYgb2ZmbGluZSBhbmQgbm90IGluc3RhbGxlZCBhbmQgbm90IHNlbGYuYnVuZGxlZCBhbmQgbm90IHNlbGYuY2ZnZmlsZS5leGlzdHMoKTpyZXR1cm4gcmVzdWx0CiAgICAgICAgaWYgbm90IG9mZmxpbmUgb3IgaW5zdGFsbGVkIG9yIHNlbGYuYnVuZGxlZCBvciBzZWxmLmNmZ2ZpbGUuZXhpc3RzKCk6CiAgICAgICAgICAgIGNmZz1zZWxmLmNvbmZpZ3VyYXRpb24oKQogICAgICAgICAgICByZXN1bHRbJ2RlZmF1bHRfcHJlZmVyZW5jZSddPWNmZy5nZXQoJ2RlZmF1bHQnLCduYXRpdmUnKTtyZXN1bHRbJ2RlZmF1bHRfZmFsbGJhY2snXT0nbmF0aXZlJyBpZiBjZmcuZ2V0KCdkZWZhdWx0Jyk9PSdsZWFzZWQnIGVsc2UgTm9uZQogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICByb3V0ZT1qc29uLmxvYWRzKHNlbGYuY29tbWFuZChbJ2lwJywnLWonLCctNicsJ3JvdXRlJywnZ2V0JywnMjYwNjo0NzAwOjQ3MDA6OjExMTEnXSkpCiAgICAgICAgICAgICAgICByZXN1bHRbJ291dGJvdW5kX2lwdjYnXT1yb3V0ZVswXS5nZXQoJ3ByZWZzcmMnKSBvciByb3V0ZVswXS5nZXQoJ3NyYycpCiAgICAgICAgICAgIGV4Y2VwdCBFeGNlcHRpb246cGFzcwogICAgICAgICAgICBpZiBpbnN0YWxsZWQ6cmVzdWx0WydjbGllbnRfc3RhdGUnXT1zZWxmLnNlcnZpY2Vfc3RhdGUoKQogICAgICAgICAgICByb3dzPWpzb24ubG9hZHMoc2VsZi5jb21tYW5kKFsnaXAnLCctaicsJy02JywnYWRkcicsJ3Nob3cnLCdkZXYnLGNmZ1snaW50ZXJmYWNlJ11dKSkKICAgICAgICAgICAgYWN0dWFsPXthWydsb2NhbCddIGZvciByb3cgaW4gcm93cyBmb3IgYSBpbiByb3dbJ2FkZHJfaW5mbyddIGlmIGFbJ2ZhbWlseSddPT0naW5ldDYnfQogICAgICAgICAgICByZXN1bHRbJ2FkZHJlc3NlcyddPXNvcnRlZChzZXQobG9jYWwuZ2V0KCdhZGRyZXNzZXMnLHt9KSkmYWN0dWFsKQogICAgICAgICAgICBkYXRhPU5vbmUKICAgICAgICAgICAgaWYgbm90IG9mZmxpbmU6CiAgICAgICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICAgICAgZGF0YT1zZWxmLmZldGNoKGNmZykKICAgICAgICAgICAgICAgICAgICBpZiBpbnN0YWxsZWQ6c2F2ZShzZWxmLmNhY2hlLHsndXVpZCc6aWRlbnRpdHksJ2ZldGNoZWRfYXQnOnRpbWUudGltZSgpLCdkYXRhJzpkYXRhfSkKICAgICAgICAgICAgICAgICAgICByZXN1bHRbJ3JlcG9ydF9zb3VyY2UnXT0nY29udHJvbGxlcicKICAgICAgICAgICAgICAgIGV4Y2VwdCBFbnJvbGxtZW50UmVxdWlyZWQ6cmFpc2UKICAgICAgICAgICAgICAgIGV4Y2VwdCBFeGNlcHRpb246cmVzdWx0Wyd3YXJuaW5nJ109J0NvbnRyb2xsZXIgdW5hdmFpbGFibGU7IHNob3dpbmcgdGhlIGxhc3QgY2FjaGVkIHJlcG9ydCBpZiBhdmFpbGFibGUuJwogICAgICAgICAgICBpZiBkYXRhIGlzIE5vbmU6CiAgICAgICAgICAgICAgICBjYWNoZWQ9cmVhZChzZWxmLmNhY2hlKQogICAgICAgICAgICAgICAgaWYgY2FjaGVkLmdldCgndXVpZCcpPT1pZGVudGl0eTpkYXRhPWNhY2hlZC5nZXQoJ2RhdGEnKTtyZXN1bHRbJ3JlcG9ydF9zb3VyY2UnXT0nY2FjaGUnIGlmIGRhdGEgZWxzZSBOb25lCiAgICAgICAgICAgIGlmIGRhdGE6CiAgICAgICAgICAgICAgICB1PWRhdGFbJ3VzYWdlJ107bGltaXQ9aW50KGRhdGFbJ2xpbWl0cyddWyd0cmFuc2Zlcl9ieXRlcyddKTt0b3RhbD1pbnQodVsndXNlZCddKStpbnQodVsnY29uc2VydmF0aXZlJ10pCiAgICAgICAgICAgICAgICByZXN1bHQudXBkYXRlKHsnYXNzaWduZWRfYWRkcmVzc2VzJzpkYXRhWydhZGRyZXNzZXMnXSwnY29ubmVjdGlvbl9saW1pdCc6aW50KGRhdGFbJ2xpbWl0cyddWydjb25uZWN0aW9ucyddKSwKICAgICAgICAgICAgICAgICAgICAnY29udHJvbGxlcl9zdGF0ZSc6ZGF0YVsnc3RhdGUnXSwnc2VydmljZV9pZCc6ZGF0YVsnc2VydmljZV9pZCddLCdyZXBvcnRlZF9hdCc6ZGF0YS5nZXQoJ3JlcG9ydGVkX2F0JyksCiAgICAgICAgICAgICAgICAgICAgJ3N0YWxlJzpyZXN1bHRbJ3JlcG9ydF9zb3VyY2UnXSE9J2NvbnRyb2xsZXInIG9yIG5vdCBkYXRhLmdldCgncmVwb3J0ZWRfYXQnKSBvciBpbnQoZGF0YVsnc2VydmVyX3RpbWUnXSktaW50KGRhdGFbJ3JlcG9ydGVkX2F0J10pPjkwLAogICAgICAgICAgICAgICAgICAgICd1c2FnZSc6eyd1c2VkX2J5dGVzJzppbnQodVsndXNlZCddKSwndXBsb2FkX2J5dGVzJzppbnQodVsndXBsb2FkJ10pLCdkb3dubG9hZF9ieXRlcyc6aW50KHVbJ2Rvd25sb2FkJ10pLAogICAgICAgICAgICAgICAgICAgICAgICAncmVjb3ZlcnlfYWRqdXN0bWVudF9ieXRlcyc6aW50KHVbJ2NvbnNlcnZhdGl2ZSddKSwnY2hhcmdlZF9ieXRlcyc6dG90YWwsJ2xpbWl0X2J5dGVzJzpsaW1pdCwKICAgICAgICAgICAgICAgICAgICAgICAgJ3JlbWFpbmluZ19ieXRlcyc6bWF4KDAsbGltaXQtdG90YWwpIGlmIGxpbWl0IGVsc2UgTm9uZSwncGVyaW9kX2lkJzpkYXRhWydwZXJpb2RfaWQnXSwncGVyaW9kX2VuZCc6ZGF0YVsncGVyaW9kX2VuZCddfX0pCiAgICAgICAgcmV0dXJuIHJlc3VsdAogICAgZGVmIGRlZmF1bHRfY2hvaWNlKHNlbGYsY2ZnLGRhdGEsc2VsZWN0aW9uPU5vbmUsaW50ZXJhY3RpdmU9RmFsc2UpOgogICAgICAgIGNob2ljZXM9ZGF0YS5nZXQoJ2xlYXNlcycsW10pCiAgICAgICAgaWYgaW50ZXJhY3RpdmU6CiAgICAgICAgICAgIHdpdGggb3BlbignL2Rldi90dHknLCdyJykgYXMgcmVhZGVyLCBvcGVuKCcvZGV2L3R0eScsJ3cnKSBhcyB0dHk6CiAgICAgICAgICAgICAgICB0dHkud3JpdGUoJ0RlZmF1bHQgb3V0Ym91bmQgSVB2NiAodW5ib3VuZCBhcHBsaWNhdGlvbnMpOlxuMS4gTmF0aXZlIElQdjYgd2hlbiBhdmFpbGFibGUgKG90aGVyd2lzZSBsZWFzZWQpXG4yLiBFeHBlcmltZW50YWwgSVB2NiAoYXV0b21hdGljIGxlYXNlIHNlbGVjdGlvbilcbicpCiAgICAgICAgICAgICAgICBmb3IgaSxsZWFzZSBpbiBlbnVtZXJhdGUoY2hvaWNlcywzKTp0dHkud3JpdGUoc3RyKGkpKycuICcrbGVhc2VbJ2lwdjYnXSsnXG4nKQogICAgICAgICAgICAgICAgdHR5LndyaXRlKCdDaG9vc2UgW0VudGVyIGtlZXBzICcrY2ZnLmdldCgnZGVmYXVsdCcsJ25hdGl2ZScpKyddOiAnKTt0dHkuZmx1c2goKTthbnN3ZXI9cmVhZGVyLnJlYWRsaW5lKCkuc3RyaXAoKQogICAgICAgICAgICAgICAgaWYgYW5zd2VyOgogICAgICAgICAgICAgICAgICAgIGlmIG5vdCBhbnN3ZXIuaXNkaWdpdCgpIG9yIG5vdCAxPD1pbnQoYW5zd2VyKTw9bGVuKGNob2ljZXMpKzI6cmFpc2UgUnVudGltZUVycm9yKCdJbnZhbGlkIGRlZmF1bHQgSVB2NiBzZWxlY3Rpb24uJykKICAgICAgICAgICAgICAgICAgICBzZWxlY3Rpb249J25hdGl2ZScgaWYgYW5zd2VyPT0nMScgZWxzZSAnbGVhc2VkJyBpZiBhbnN3ZXI9PScyJyBlbHNlIGNob2ljZXNbaW50KGFuc3dlciktM11bJ2lwdjYnXQogICAgICAgIGlmIHNlbGVjdGlvbiBpcyBub3QgTm9uZToKICAgICAgICAgICAgaWYgc2VsZWN0aW9uPT0nbmF0aXZlJzoKICAgICAgICAgICAgICAgIGNmZ1snZGVmYXVsdCddPSduYXRpdmUnCiAgICAgICAgICAgICAgICBmb3IgayBpbiBbJ2RlZmF1bHRfcG9vbF9pZCcsJ2RlZmF1bHRfc2xvdF9pbmRleCcsJ2RlZmF1bHRfZmFsbGJhY2snXTpjZmcucG9wKGssTm9uZSkKICAgICAgICAgICAgZWxpZiBzZWxlY3Rpb249PSdsZWFzZWQnOgogICAgICAgICAgICAgICAgY2ZnWydkZWZhdWx0J109J2xlYXNlZCc7Y2ZnLnBvcCgnZGVmYXVsdF9wb29sX2lkJyxOb25lKTtjZmdbJ2RlZmF1bHRfc2xvdF9pbmRleCddPTAKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIGFkZHJlc3M9c3RyKGlwYWRkcmVzcy5JUHY2QWRkcmVzcyhzZWxlY3Rpb24pKTtsZWFzZT1uZXh0KChsIGZvciBsIGluIGNob2ljZXMgaWYgbFsnaXB2NiddPT1hZGRyZXNzKSxOb25lKQogICAgICAgICAgICAgICAgaWYgbm90IGxlYXNlOnJhaXNlIFJ1bnRpbWVFcnJvcignQ2hvb3NlIGFuIElQdjYgYWRkcmVzcyBjdXJyZW50bHkgbGVhc2VkIHRvIHRoaXMgVk0sIG9yIHVzZSAtLWRlZmF1bHQgbGVhc2VkLicpCiAgICAgICAgICAgICAgICBjZmcudXBkYXRlKHsnZGVmYXVsdCc6J2xlYXNlZCcsJ2RlZmF1bHRfcG9vbF9pZCc6aW50KGxlYXNlWydwb29sX2lkJ10pLCdkZWZhdWx0X3Nsb3RfaW5kZXgnOmludChsZWFzZVsnc2xvdF9pbmRleCddKX0pCiAgICAgICAgcmV0dXJuIGNmZwoKICAgIGRlZiBpbnN0YWxsKHNlbGYsY29uZmlnX3BhdGg9Tm9uZSxpbnRlcmZhY2U9Tm9uZSxkZWZhdWx0PU5vbmUsY2hvb3NlX2RlZmF1bHQ9RmFsc2UpOgogICAgICAgIGNmZz1zZWxmLmNvbmZpZ3VyYXRpb24oY29uZmlnX3BhdGgsaW50ZXJmYWNlLFRydWUpO3NlbGYuc2V0dXBfaW5pdCgpCiAgICAgICAgaWYgbm90IHNodXRpbC53aGljaCgnaXAnKTpyYWlzZSBSdW50aW1lRXJyb3IoJ0Z1bGwgaXByb3V0ZTIgaXMgcmVxdWlyZWQuJykKICAgICAgICB0cnk6ZGF0YT1zZWxmLmZldGNoKGNmZykKICAgICAgICBleGNlcHQgRW5yb2xsbWVudFJlcXVpcmVkOgogICAgICAgICAgICBmcmVzaD1zZWxmLmJvb3RzdHJhcF9jb25maWd1cmF0aW9uKFRydWUpCiAgICAgICAgICAgIGNmZz17KipmcmVzaCwqKntrOnYgZm9yIGssdiBpbiBjZmcuaXRlbXMoKSBpZiBrIGluICgnaW50ZXJmYWNlJywnZGVmYXVsdCcsJ2ludGVydmFsJywnbmF0aXZlX3NvdXJjZScsJ2RlZmF1bHRfcG9vbF9pZCcsJ2RlZmF1bHRfc2xvdF9pbmRleCcpfX0KICAgICAgICAgICAgZGF0YT1zZWxmLmZldGNoKGNmZykgICMgQXV0aGVudGljYXRlIGJlZm9yZSBjaGFuZ2luZyBmaWxlcyBvciByZXN0YXJ0aW5nIGEgY2xpZW50LgogICAgICAgIGNmZz1zZWxmLmRlZmF1bHRfY2hvaWNlKGNmZyxkYXRhLGRlZmF1bHQsY2hvb3NlX2RlZmF1bHQpCiAgICAgICAgcHJvYmVfY2ZnPWRpY3QoY2ZnLHN0YXRlX2Rpcj1zdHIoc2VsZi5zdGF0ZSkpO2c9R3Vlc3QocHJvYmVfY2ZnKTtnLmRpc2NvdmVyX25hdGl2ZSgpCiAgICAgICAgd2FzX2FjdGl2ZT1zZWxmLnNlcnZpY2Vfc3RhdGUoKT09J2FjdGl2ZScKICAgICAgICBvbGRfZW5hYmxlZD1zZWxmLnNlcnZpY2VfZW5hYmxlZCgpCiAgICAgICAgZGVzdGluYXRpb25zPXtzZWxmLmNvZGUvbmFtZTooc2VsZi5idW5kbGUvbmFtZSkucmVhZF9ieXRlcygpIGZvciBuYW1lIGluIEZJTEVTfQogICAgICAgIGRlc3RpbmF0aW9uc1tzZWxmLmNmZ2ZpbGVdPWpzb24uZHVtcHMoY2ZnLHNvcnRfa2V5cz1UcnVlKS5lbmNvZGUoKQogICAgICAgIHVuaXRfdGV4dD0oc2VsZi5idW5kbGUvKFVOSVQgaWYgc2VsZi5pbml0PT0nc3lzdGVtZCcgZWxzZSAnZHluYW1pY3Y2LW5leHQtZ3Vlc3Qub3BlbnJjJykpLnJlYWRfdGV4dCgpCiAgICAgICAgdW5pdF90ZXh0PXVuaXRfdGV4dC5yZXBsYWNlKCdFeGVjU3RhcnQ9L3Vzci9iaW4vcHl0aG9uMyAnLCAnRXhlY1N0YXJ0PScrc2hsZXgucXVvdGUoc3lzLmV4ZWN1dGFibGUpKycgJykucmVwbGFjZSgnY29tbWFuZD0iL3Vzci9iaW4vcHl0aG9uMyInLCdjb21tYW5kPScrc2hsZXgucXVvdGUoc3lzLmV4ZWN1dGFibGUpKQogICAgICAgIGRlc3RpbmF0aW9uc1tzZWxmLnVuaXRdPXVuaXRfdGV4dC5lbmNvZGUoKQogICAgICAgIGJlZm9yZT17cDoocC5yZWFkX2J5dGVzKCkscC5zdGF0KCkuc3RfbW9kZSYwbzc3NykgaWYgcC5leGlzdHMoKSBlbHNlIE5vbmUgZm9yIHAgaW4gWypkZXN0aW5hdGlvbnMsc2VsZi5zdGF0ZS8naW5zdGFsbGVyLmpzb24nLHNlbGYuY2FjaGUsc2VsZi5iYXNlbGluZV19CiAgICAgICAgaWYgd2FzX2FjdGl2ZTpzZWxmLnNlcnZpY2Vfc3RvcCgpCiAgICAgICAgdHJ5OgogICAgICAgICAgICAjIFRoZSByZWNvbmNpbGVyJ3MgbG9jayBhbHNvIHNlcmlhbGl6ZXMgcmVjb3ZlcnkvY2xlYW51cCB3aXRoIGNsaWVudCBzdGFydHVwLgogICAgICAgICAgICB3aXRoIGxvY2soc2VsZi5zdGF0ZS8nYWdlbnQubG9jaycpOgogICAgICAgICAgICAgICAgZnJvbSBkdm5fbGVnYWN5IGltcG9ydCBtaWdyYXRlCiAgICAgICAgICAgICAgICBtaWdyYXRlKHNlbGYsY2ZnLGRhdGEpCiAgICAgICAgICAgICAgICBnPUd1ZXN0KHByb2JlX2NmZykKICAgICAgICAgICAgICAgIHdpdGggY29udGV4dGxpYi5yZWRpcmVjdF9zdGRvdXQoc3lzLnN0ZGVycik6Zy5yZWNvdmVyKCkKICAgICAgICAgICAgICAgIGlmIG5vdCBzZWxmLmJhc2VsaW5lLmV4aXN0cygpOnNhdmUoc2VsZi5iYXNlbGluZSx7J3ZlcnNpb24nOjEsJ3V1aWQnOmNmZ1sndXVpZCddLCdpbnRlcmZhY2UnOmcuaWZhY2UsJ25hdGl2ZSc6Zy5kaXNjb3Zlcl9uYXRpdmUoKSwnY2FwdHVyZWRfYXQnOnRpbWUudGltZSgpfSkKICAgICAgICAgICAgICAgIGZvciBwYXRoLGNvbnRlbnQgaW4gZGVzdGluYXRpb25zLml0ZW1zKCk6CiAgICAgICAgICAgICAgICAgICAgcGF0aC5wYXJlbnQubWtkaXIocGFyZW50cz1UcnVlLGV4aXN0X29rPVRydWUpO3RtcD1wYXRoLndpdGhfbmFtZSgnLicrcGF0aC5uYW1lKycuaW5zdGFsbCcpCiAgICAgICAgICAgICAgICAgICAgdG1wLndyaXRlX2J5dGVzKGNvbnRlbnQpO3RtcC5jaG1vZCgwbzYwMCBpZiBwYXRoPT1zZWxmLmNmZ2ZpbGUgZWxzZSAwbzc1NSBpZiBwYXRoPT1zZWxmLnVuaXQgYW5kIHNlbGYuaW5pdD09J29wZW5yYycgZWxzZSAwbzY0NCk7b3MucmVwbGFjZSh0bXAscGF0aCkKICAgICAgICAgICAgICAgIHNhdmUoc2VsZi5zdGF0ZS8naW5zdGFsbGVyLmpzb24nLHsndmVyc2lvbic6MSwnZmlsZXMnOntwLm5hbWU6aGFzaGxpYi5zaGEyNTYoY29udGVudCkuaGV4ZGlnZXN0KCkgZm9yIHAsY29udGVudCBpbiBkZXN0aW5hdGlvbnMuaXRlbXMoKSBpZiBwLnBhcmVudD09c2VsZi5jb2RlfX0pCiAgICAgICAgICAgICAgICBzYXZlKHNlbGYuY2FjaGUseyd1dWlkJzpjZmdbJ3V1aWQnXSwnZmV0Y2hlZF9hdCc6dGltZS50aW1lKCksJ2RhdGEnOmRhdGF9KQogICAgICAgICAgICBzZWxmLnNlcnZpY2VfcmVsb2FkKCk7c2VsZi5zZXJ2aWNlX2VuYWJsZV9zdGFydCgpCiAgICAgICAgICAgIGlmIHNlbGYuc2VydmljZV9zdGF0ZSgpIT0nYWN0aXZlJzpyYWlzZSBSdW50aW1lRXJyb3IoJ0NsaWVudCBzZXJ2aWNlIGRpZCBub3Qgc3RhcnQuJykKICAgICAgICBleGNlcHQgRXhjZXB0aW9uOgogICAgICAgICAgICBzZWxmLnNlcnZpY2Vfc3RvcChGYWxzZSkKICAgICAgICAgICAgaWYgbm90IG9sZF9lbmFibGVkOnNlbGYuc2VydmljZV9kaXNhYmxlKEZhbHNlKQogICAgICAgICAgICBmb3IgcGF0aCxvcmlnaW5hbCBpbiBiZWZvcmUuaXRlbXMoKToKICAgICAgICAgICAgICAgIGlmIG9yaWdpbmFsIGlzIE5vbmU6cGF0aC51bmxpbmsobWlzc2luZ19vaz1UcnVlKQogICAgICAgICAgICAgICAgZWxzZTpwYXRoLndyaXRlX2J5dGVzKG9yaWdpbmFsWzBdKTtwYXRoLmNobW9kKG9yaWdpbmFsWzFdKQogICAgICAgICAgICBzZWxmLnNlcnZpY2VfcmVsb2FkKEZhbHNlKQogICAgICAgICAgICBpZiB3YXNfYWN0aXZlOnNlbGYuc2VydmljZV9zdGFydChGYWxzZSkKICAgICAgICAgICAgcmFpc2UKICAgICAgICByZXR1cm4geydpbnN0YWxsZWQnOlRydWUsJ3V1aWQnOmNmZ1sndXVpZCddLCdtZXNzYWdlJzonQ2xpZW50IGluc3RhbGxlZC4gTmV0d29ya2luZyB1cGRhdGVzIHdoZW4gdGhlIGhvc3QgcG9saWN5IGlzIHJlYWR5Lid9CiAgICBkZWYgdW5pbnN0YWxsKHNlbGYpOgogICAgICAgIGlkZW50aXR5PXNlbGYuaGFyZHdhcmVfdXVpZCgpCiAgICAgICAgaWYgbm90IHNlbGYuaW5zdGFsbGVkKCk6cmV0dXJuIHsnaW5zdGFsbGVkJzpGYWxzZSwndXVpZCc6aWRlbnRpdHksJ21lc3NhZ2UnOidDbGllbnQgaXMgbm90IGluc3RhbGxlZC4nfQogICAgICAgIGNmZz1zZWxmLmNvbmZpZ3VyYXRpb24oKTtleHBlY3RlZD1yZWFkKHNlbGYuc3RhdGUvJ2luc3RhbGxlci5qc29uJykuZ2V0KCdmaWxlcycse30pCiAgICAgICAgZm9yIG5hbWUgaW4gRklMRVM6CiAgICAgICAgICAgIHBhdGg9c2VsZi5jb2RlL25hbWUKICAgICAgICAgICAgd2FudGVkPWV4cGVjdGVkLmdldChuYW1lKSBvciBoYXNobGliLnNoYTI1Nigoc2VsZi5idW5kbGUvbmFtZSkucmVhZF9ieXRlcygpKS5oZXhkaWdlc3QoKQogICAgICAgICAgICBpZiBwYXRoLmV4aXN0cygpIGFuZCBoYXNobGliLnNoYTI1NihwYXRoLnJlYWRfYnl0ZXMoKSkuaGV4ZGlnZXN0KCkhPXdhbnRlZDpyYWlzZSBSdW50aW1lRXJyb3IoJ0luc3RhbGxlZCAnK25hbWUrJyBjaGFuZ2VkOyByZWluc3RhbGwgdGhlIGN1cnJlbnQgd3JhcHBlciBiZWZvcmUgdW5pbnN0YWxsaW5nLicpCiAgICAgICAgd2FzX2FjdGl2ZT1zZWxmLnNlcnZpY2Vfc3RhdGUoKT09J2FjdGl2ZScKICAgICAgICB0aW1lcl93YXNfYWN0aXZlPXNlbGYuc3RvcF90aW1lcigpCiAgICAgICAgc2VsZi5zZXJ2aWNlX3N0b3AoKQogICAgICAgIHRyeToKICAgICAgICAgICAgd2l0aCBsb2NrKHNlbGYuc3RhdGUvJ2FnZW50LmxvY2snKToKICAgICAgICAgICAgICAgIHdpdGggY29udGV4dGxpYi5yZWRpcmVjdF9zdGRvdXQoc3lzLnN0ZGVycik6CiAgICAgICAgICAgICAgICAgICAgZz1HdWVzdChkaWN0KGNmZyxzdGF0ZV9kaXI9c3RyKHNlbGYuc3RhdGUpKSk7Zy5yZWNvdmVyKCk7YmVmb3JlX25hdGl2ZT1nLmRpc2NvdmVyX25hdGl2ZSgpCiAgICAgICAgICAgICAgICAgICAgcmVzdG9yZWQ9c2VsZi5yZXN0b3JlX25hdGl2ZShnLGJlZm9yZV9uYXRpdmUpCiAgICAgICAgZXhjZXB0IEV4Y2VwdGlvbjoKICAgICAgICAgICAgaWYgd2FzX2FjdGl2ZTpzZWxmLnNlcnZpY2Vfc3RhcnQoRmFsc2UpCiAgICAgICAgICAgIGlmIHRpbWVyX3dhc19hY3RpdmU6c2VsZi5jb21tYW5kKFsnc3lzdGVtY3RsJywnc3RhcnQnLCdkeW5hbWljdjYtbmV4dC1ndWVzdC50aW1lciddLEZhbHNlKQogICAgICAgICAgICByYWlzZQogICAgICAgIHNlbGYuc2VydmljZV9kaXNhYmxlKCkKICAgICAgICBpZiBzZWxmLnNldHVwX2luaXQoKT09J3N5c3RlbWQnOnNlbGYuY29tbWFuZChbJ3N5c3RlbWN0bCcsJ2Rpc2FibGUnLCdkeW5hbWljdjYtbmV4dC1ndWVzdC50aW1lciddLEZhbHNlKQogICAgICAgIGZvciBuYW1lIGluIEZJTEVTOgogICAgICAgICAgICBpZiBuYW1lPT0nZHZuX2NvbW1vbi5weScgYW5kIChzZWxmLmNvZGUvJ2R2bl9ob3N0LnB5JykuZXhpc3RzKCk6Y29udGludWUKICAgICAgICAgICAgKHNlbGYuY29kZS9uYW1lKS51bmxpbmsobWlzc2luZ19vaz1UcnVlKQogICAgICAgIHNlbGYudW5pdC51bmxpbmsobWlzc2luZ19vaz1UcnVlKTtzZWxmLmNmZ2ZpbGUudW5saW5rKG1pc3Npbmdfb2s9VHJ1ZSkKICAgICAgICBzYXZlKHNlbGYuc3RhdGUvJ2xhc3QtdW5pbnN0YWxsLmpzb24nLHsndXVpZCc6aWRlbnRpdHksJ2Jhc2VsaW5lX3Jlc3RvcmVkJzpyZXN0b3JlZCwnY29tcGxldGVkX2F0Jzp0aW1lLnRpbWUoKX0pO3NlbGYuYmFzZWxpbmUudW5saW5rKG1pc3Npbmdfb2s9VHJ1ZSkKICAgICAgICAoc2VsZi5zdGF0ZS8naW5zdGFsbGVyLmpzb24nKS51bmxpbmsobWlzc2luZ19vaz1UcnVlKTtzZWxmLmNhY2hlLnVubGluayhtaXNzaW5nX29rPVRydWUpCiAgICAgICAgc2VsZi5zZXJ2aWNlX3JlbG9hZCgpCiAgICAgICAgcmV0dXJuIHsnaW5zdGFsbGVkJzpGYWxzZSwndXVpZCc6aWRlbnRpdHksJ2Jhc2VsaW5lX3Jlc3RvcmVkJzpyZXN0b3JlZCwnbWVzc2FnZSc6J0NsaWVudCBwb2xsaW5nIHN0b3BwZWQgYW5kIG1hbmFnZWQgSVB2NiBzZXR0aW5ncyByZW1vdmVkLiBQcmV2aW91cyBuYXRpdmUgcm91dGluZyBpcyByZXN0b3JlZCB3aGVuIHN0aWxsIGFwcGxpY2FibGU7IGNvbnRyb2xsZXIgdXNhZ2UgaGlzdG9yeSBpcyBwcmVzZXJ2ZWQuJ30KCmRlZiByZWFkYWJsZShkYXRhKToKICAgIGlmICdtZXNzYWdlJyBpbiBkYXRhOnJldHVybiBkYXRhWydtZXNzYWdlJ10rJ1xuVVVJRDogJytkYXRhWyd1dWlkJ10KICAgIGxpbmVzPVsnVVVJRDogJytkYXRhWyd1dWlkJ10sJ0NsaWVudDogJytkYXRhWydjbGllbnRfc3RhdGUnXSwnQ29uZmlndXJlZCBJUHY2OiAnKygnLCAnLmpvaW4oZGF0YVsnYWRkcmVzc2VzJ10pIG9yICdub25lJyldCiAgICBpZiBkYXRhLmdldCgnZGVmYXVsdF9wcmVmZXJlbmNlJyk6bGluZXMuYXBwZW5kKCdEZWZhdWx0IHByZWZlcmVuY2U6ICcrZGF0YVsnZGVmYXVsdF9wcmVmZXJlbmNlJ10rKCc7IGZhbGxiYWNrOiAnK2RhdGFbJ2RlZmF1bHRfZmFsbGJhY2snXSBpZiBkYXRhLmdldCgnZGVmYXVsdF9mYWxsYmFjaycpIGVsc2UgJycpKQogICAgbGluZXMuYXBwZW5kKCdDdXJyZW50IG91dGJvdW5kIElQdjY6ICcrKGRhdGEuZ2V0KCdvdXRib3VuZF9pcHY2Jykgb3IgJ3VuYXZhaWxhYmxlJykpCiAgICBpZiBkYXRhWydhc3NpZ25lZF9hZGRyZXNzZXMnXSE9ZGF0YVsnYWRkcmVzc2VzJ106bGluZXMuYXBwZW5kKCdBc3NpZ25lZCBJUHY2OiAnKygnLCAnLmpvaW4oZGF0YVsnYXNzaWduZWRfYWRkcmVzc2VzJ10pIG9yICdub25lJykpCiAgICBpZiBkYXRhWyd1c2FnZSddOgogICAgICAgIHU9ZGF0YVsndXNhZ2UnXTtsaW1pdD1zdHIodVsnbGltaXRfYnl0ZXMnXSkrJyBieXRlcycgaWYgdVsnbGltaXRfYnl0ZXMnXSBlbHNlICd1bmxpbWl0ZWQnCiAgICAgICAgbGluZXMrPVsnVHJhbnNmZXI6ICcrc3RyKHVbJ2NoYXJnZWRfYnl0ZXMnXSkrJyBieXRlcyAvICcrbGltaXQsJ1VwbG9hZDogJytzdHIodVsndXBsb2FkX2J5dGVzJ10pKycgYnl0ZXM7IGRvd25sb2FkOiAnK3N0cih1Wydkb3dubG9hZF9ieXRlcyddKSsnIGJ5dGVzJywKICAgICAgICAgICAgJ0Nvbm5lY3Rpb24gbGltaXQ6ICcrc3RyKGRhdGFbJ2Nvbm5lY3Rpb25fbGltaXQnXSksJ1JlcG9ydDogJytzdHIoZGF0YVsncmVwb3J0X3NvdXJjZSddKSsoJyAoc3RhbGUpJyBpZiBkYXRhWydzdGFsZSddIGVsc2UgJycpXQogICAgZWxzZTpsaW5lcy5hcHBlbmQoJ1RyYW5zZmVyIHVzYWdlOiB1bmF2YWlsYWJsZScpCiAgICBpZiBkYXRhWyd3YXJuaW5nJ106bGluZXMuYXBwZW5kKGRhdGFbJ3dhcm5pbmcnXSkKICAgIHJldHVybiAnXG4nLmpvaW4obGluZXMpCgpkZWYgbWFpbihidW5kbGUsYnVuZGxlZF9jb25maWcpOgogICAgcGFyc2VyPWFyZ3BhcnNlLkFyZ3VtZW50UGFyc2VyKGRlc2NyaXB0aW9uPSdEeW5hbWljVjYgY2xpZW50OiBpbnN0YWxsLCB1bmluc3RhbGwsIHN0YXR1cycpCiAgICBwYXJzZXIuYWRkX2FyZ3VtZW50KCdhY3Rpb24nLGNob2ljZXM9WydpbnN0YWxsJywndW5pbnN0YWxsJywnc3RhdHVzJ10pO3BhcnNlci5hZGRfYXJndW1lbnQoJy0tY29uZmlnJyxoZWxwPSdQcm90ZWN0ZWQgSlNPTiBjb25maWd1cmF0aW9uIGZvciBpbnN0YWxsJykKICAgIHBhcnNlci5hZGRfYXJndW1lbnQoJy0taW50ZXJmYWNlJyxoZWxwPSdOYXRpdmUgSVB2NiBpbnRlcmZhY2UgZm9yIGluc3RhbGw7IGRldGVjdGVkIGF1dG9tYXRpY2FsbHkgYnkgZGVmYXVsdCcpO3BhcnNlci5hZGRfYXJndW1lbnQoJy0tanNvbicsYWN0aW9uPSdzdG9yZV90cnVlJyk7cGFyc2VyLmFkZF9hcmd1bWVudCgnLS1mb3JtYXQnLGNob2ljZXM9Wydqc29uJywncmVhZGFibGUnXSxkZWZhdWx0PSdyZWFkYWJsZScpO3BhcnNlci5hZGRfYXJndW1lbnQoJy0tb2ZmbGluZScsYWN0aW9uPSdzdG9yZV90cnVlJykKICAgIHBhcnNlci5hZGRfYXJndW1lbnQoJy0tZGVmYXVsdCcsaGVscD0nRGVmYXVsdCBvdXRib3VuZCBJUHY2OiBuYXRpdmUsIGxlYXNlZCwgb3IgYW4gYXNzaWduZWQgSVB2NiBhZGRyZXNzJykKICAgIHBhcnNlci5hZGRfYXJndW1lbnQoJy0tY2hvb3NlLWRlZmF1bHQnLGFjdGlvbj0nc3RvcmVfdHJ1ZScsaGVscD1hcmdwYXJzZS5TVVBQUkVTUykKICAgIGFyZ3M9cGFyc2VyLnBhcnNlX2FyZ3MoKTthc19qc29uPWFyZ3MuanNvbiBvciBhcmdzLmZvcm1hdD09J2pzb24nCiAgICB0cnk6CiAgICAgICAgaWYgb3MuZ2V0ZXVpZCgpIT0wOnJhaXNlIFJ1bnRpbWVFcnJvcignUnVuIHRoaXMgY29tbWFuZCB3aXRoIHN1ZG8gb3IgYXMgcm9vdC4nKQogICAgICAgIGlmIChhcmdzLmRlZmF1bHQgaXMgbm90IE5vbmUgb3IgYXJncy5jaG9vc2VfZGVmYXVsdCkgYW5kIGFyZ3MuYWN0aW9uIT0naW5zdGFsbCc6cmFpc2UgUnVudGltZUVycm9yKCdEZWZhdWx0IElQdjYgc2VsZWN0aW9uIGlzIG9ubHkgdXNlZCB3aXRoIGluc3RhbGwuJykKICAgICAgICBpZiBhcmdzLmludGVyZmFjZSBhbmQgYXJncy5hY3Rpb24hPSdpbnN0YWxsJzpyYWlzZSBSdW50aW1lRXJyb3IoJy0taW50ZXJmYWNlIGlzIG9ubHkgdXNlZCB3aXRoIGluc3RhbGwuJykKICAgICAgICBpZiBhcmdzLmNvbmZpZyBhbmQgYXJncy5hY3Rpb24hPSdpbnN0YWxsJzpyYWlzZSBSdW50aW1lRXJyb3IoJy0tY29uZmlnIGlzIG9ubHkgdXNlZCB3aXRoIGluc3RhbGwuJykKICAgICAgICBpZiBhcmdzLm9mZmxpbmUgYW5kIGFyZ3MuYWN0aW9uIT0nc3RhdHVzJzpyYWlzZSBSdW50aW1lRXJyb3IoJy0tb2ZmbGluZSBpcyBvbmx5IHVzZWQgd2l0aCBzdGF0dXMuJykKICAgICAgICBjbGllbnQ9Q2xpZW50KGJ1bmRsZSxidW5kbGVkX2NvbmZpZykKICAgICAgICAjIE9wZXJhdGlvbiBsb2NrIGlzIHNlcGFyYXRlIGZyb20gdGhlIGRhZW1vbidzIGxpZmV0aW1lIGxvY2suIFN0YXR1cyByZW1haW5zIGF2YWlsYWJsZS4KICAgICAgICB3aXRoIGxvY2soJy9ydW4vbG9jay9keW5hbWljdjYtbmV4dC1jbGllbnQubG9jaycpOgogICAgICAgICAgICBkYXRhPWNsaWVudC5pbnN0YWxsKGFyZ3MuY29uZmlnLGFyZ3MuaW50ZXJmYWNlLGFyZ3MuZGVmYXVsdCxhcmdzLmNob29zZV9kZWZhdWx0KSBpZiBhcmdzLmFjdGlvbj09J2luc3RhbGwnIGVsc2UgY2xpZW50LnVuaW5zdGFsbCgpIGlmIGFyZ3MuYWN0aW9uPT0ndW5pbnN0YWxsJyBlbHNlIGNsaWVudC5zdGF0dXMoYXJncy5vZmZsaW5lKQogICAgICAgIHByaW50KGpzb24uZHVtcHMoZGF0YSxzb3J0X2tleXM9VHJ1ZSkgaWYgYXNfanNvbiBlbHNlIHJlYWRhYmxlKGRhdGEpKQogICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOgogICAgICAgIHByaW50KGpzb24uZHVtcHMoeydlcnJvcic6c3RyKGUpfSkgaWYgYXNfanNvbiBlbHNlICdFcnJvcjogJytzdHIoZSksZmlsZT1zeXMuc3Rkb3V0IGlmIGFzX2pzb24gZWxzZSBzeXMuc3RkZXJyKQogICAgICAgIHJldHVybiAxCiAgICByZXR1cm4gMAo=', 'dvn_legacy.py': 'IiIiT25lLXdheSwgcmV0cnlhYmxlIGNsZWFudXAgb2YgYXV0aGVudGljYXRlZCBsZWdhY3kgbGVhc2Ugb3duZXJzaGlwIGR1cmluZyBpbnN0YWxsLiIiIgppbXBvcnQgYmFzZTY0LCBpcGFkZHJlc3MsIGpzb24sIG9zLCBwYXRobGliLCByZSwgc2hsZXgsIHRpbWUKZnJvbSBkdm5fY29tbW9uIGltcG9ydCByZWFkLCBzYXZlCmZyb20gZHZuX3RyYW5zYWN0aW9uIGltcG9ydCBLZXJuZWwsIG1ha2Vfcm91dGUKCmRlZiBtaWdyYXRlKGNsaWVudCxjZmcsZGF0YSk6CiAgICBoaXN0b3J5PWRhdGEuZ2V0KCdsZWdhY3lfaGFuZG9mZicsW10pCiAgICBhZGRyZXNzZXM9e3N0cihpcGFkZHJlc3MuSVB2NkFkZHJlc3Mocm93WydpcHY2J10pKSBmb3Igcm93IGluIGhpc3Rvcnl9CiAgICBnYXRld2F5cz17c3RyKGlwYWRkcmVzcy5JUHY2QWRkcmVzcyhyb3dbJ2dhdGV3YXknXSkpIGZvciByb3cgaW4gaGlzdG9yeSBpZiByb3cuZ2V0KCdnYXRld2F5Jyl9CiAgICBvYnNvbGV0ZT1hZGRyZXNzZXMtc2V0KGRhdGEuZ2V0KCdhZGRyZXNzZXMnLFtdKSkKICAgIGRlZiByb290ZWQodmFsdWUpOgogICAgICAgIHBhdGg9cGF0aGxpYi5QYXRoKHZhbHVlKQogICAgICAgIGlmIG5vdCBwYXRoLmlzX2Fic29sdXRlKCkgb3IgJy4uJyBpbiBwYXRoLnBhcnRzOnJhaXNlIFJ1bnRpbWVFcnJvcignSW52YWxpZCBsZWdhY3kgYXJ0aWZhY3QgcGF0aCcpCiAgICAgICAgcmV0dXJuIGNsaWVudC5yb290L3N0cihwYXRoKS5sc3RyaXAoJy8nKQogICAgc3RhdGVmaWxlPXJvb3RlZChvcy5lbnZpcm9uLmdldCgnRFlOQU1JQ1Y2X1NUQVRFX0RJUicsJy92YXIvbGliL2R5bmFtaWN2NicpKS8oJ2NsaWVudC0nK2NmZ1snaW50ZXJmYWNlJ10rJy5zdGF0ZScpCiAgICBhcnRpZmFjdHM9W2NsaWVudC5yb290LygnZXRjL3N5c3RlbWQvc3lzdGVtL2R5bmFtaWN2Ni1jbGllbnQuJytraW5kKSBmb3Iga2luZCBpbiBbJ3NlcnZpY2UnLCd0aW1lciddXQogICAgYXJ0aWZhY3RzLmFwcGVuZChjbGllbnQucm9vdC8nZXRjL2luaXQuZC9keW5hbWljdjYtY2xpZW50JykKICAgIGJpbmFyaWVzPVtyb290ZWQob3MuZW52aXJvbi5nZXQoJ0RZTkFNSUNWNl9DTElFTlRfQklOX1BBVEgnLCcvdXNyL2xvY2FsL2Jpbi9keW5hbWljdjYtY2xpZW50LnNoJykpXQogICAgc2VydmljZT1hcnRpZmFjdHNbMF0KICAgIGlmIHNlcnZpY2UuaXNfZmlsZSgpOgogICAgICAgIGZvciBsaW5lIGluIHNlcnZpY2UucmVhZF90ZXh0KCkuc3BsaXRsaW5lcygpOgogICAgICAgICAgICBpZiBsaW5lLnN0YXJ0c3dpdGgoJ0V4ZWNTdGFydD0nKToKICAgICAgICAgICAgICAgIGZvciBhcmcgaW4gc2hsZXguc3BsaXQobGluZS5zcGxpdCgnPScsMSlbMV0pOgogICAgICAgICAgICAgICAgICAgIGlmIGFyZy5zdGFydHN3aXRoKCcvJykgYW5kIGFyZy5lbmRzd2l0aCgnLnNoJyk6YmluYXJpZXMuYXBwZW5kKHJvb3RlZChhcmcpKQogICAgZm9yIHBhdGggaW4gYmluYXJpZXM6CiAgICAgICAgaWYgcGF0aC5pc19maWxlKCkgYW5kIG5vdCBwYXRoLmlzX3N5bWxpbmsoKToKICAgICAgICAgICAgdGV4dD1wYXRoLnJlYWRfdGV4dChlcnJvcnM9J3JlcGxhY2UnKQogICAgICAgICAgICBpZiAnRFlOQU1JQ1Y2X1NUQVRFX0RJUicgaW4gdGV4dCBvciAnbGVnYWN5IER5bmFtaWNWNiByZWRpcmVjdC1jb21wYXRpYmxlJyBpbiB0ZXh0OmFydGlmYWN0cy5hcHBlbmQocGF0aCkKICAgIGFydGlmYWN0cz1saXN0KGRpY3QuZnJvbWtleXMoYXJ0aWZhY3RzKSkKICAgIGlmIG5vdCBzdGF0ZWZpbGUuZXhpc3RzKCkgYW5kIG5vdCBhbnkocC5leGlzdHMoKSBmb3IgcCBpbiBhcnRpZmFjdHMpOgogICAgICAgIGlmIG5vdCBoaXN0b3J5IG9yIHJlYWQoY2xpZW50LnN0YXRlLydsZWdhY3ktaGFuZG9mZi5qc29uJykuZ2V0KCdjb21wbGV0ZScpOnJldHVybgogICAgb2xkPXJlYWQoc3RhdGVmaWxlKTtyZWNvcmRlZD17c3RyKGlwYWRkcmVzcy5JUHY2SW50ZXJmYWNlKGEpLmlwKSBmb3IgYSBpbiBvbGQuZ2V0KCdpcHY2X2NpZHJzJyxbXSl9CiAgICBpZiByZWNvcmRlZCBhbmQgcmVjb3JkZWQ8PWFkZHJlc3NlczoKICAgICAgICBnYXRld2F5cy51cGRhdGUoc3RyKGlwYWRkcmVzcy5JUHY2QWRkcmVzcyhnKSkgZm9yIGcgaW4gb2xkLmdldCgnZ2F0ZXdheXMnLFtdKSkKICAgIGtlcm5lbD1LZXJuZWwoY2ZnWydpbnRlcmZhY2UnXSk7cm91dGVzPWtlcm5lbC5yb3V0ZXMoKTthY3R1YWw9a2VybmVsLmFkZHJlc3NlcygpCiAgICBuYXRpdmU9W2EgZm9yIGEsciBpbiBhY3R1YWwuaXRlbXMoKSBpZiByLmdldCgnc2NvcGUnKT09J2dsb2JhbCcgYW5kIHJbJ3ByZWZpeGxlbiddIT0xMjhdCiAgICBkZWZhdWx0cz1bciBmb3IgciBpbiByb3V0ZXMgaWYgclsndGFibGUnXT09MjU0IGFuZCByWydkc3QnXT09Jzo6LzAnIGFuZCByLmdldCgnZGV2Jyk9PWNmZ1snaW50ZXJmYWNlJ10gYW5kIHIuZ2V0KCdnYXRld2F5Jykgbm90IGluIGdhdGV3YXlzIGFuZCByLmdldCgnZ2F0ZXdheScpXQogICAgcmVzdG9yZT1Ob25lCiAgICBpZiBub3QgZGVmYXVsdHMgYW5kIG5hdGl2ZToKICAgICAgICBzYXZlZD1vbGQuZ2V0KCduYXRpdmVfZGVmYXVsdCcse30pCiAgICAgICAgZ2F0ZXdheT1zdHIoaXBhZGRyZXNzLklQdjZBZGRyZXNzKHNhdmVkWydnYXRld2F5J10pKSBpZiBzYXZlZC5nZXQoJ2dhdGV3YXknKSBlbHNlIE5vbmUKICAgICAgICBzb3VyY2U9c2F2ZWQuZ2V0KCdzcmMnKSBvciAobmF0aXZlWzBdIGlmIG5hdGl2ZSBlbHNlIE5vbmUpCiAgICAgICAgaWYgZ2F0ZXdheSBhbmQgZ2F0ZXdheSBub3QgaW4gZ2F0ZXdheXMgYW5kIHNvdXJjZSBpbiBuYXRpdmU6CiAgICAgICAgICAgIHJlc3RvcmU9bWFrZV9yb3V0ZSgyNTQsJ2RlZmF1bHQnLGNmZ1snaW50ZXJmYWNlJ10sZ2F0ZXdheT1nYXRld2F5LHByZWZzcmM9c291cmNlLG1ldHJpYz1pbnQoc2F2ZWQuZ2V0KCdtZXRyaWMnKSBvciAxMDI0KSxvbmxpbms9c3RyKHNhdmVkLmdldCgnb25saW5rJykpPT0nMScpCiAgICAgICAgIyBXaXRob3V0IGEgcmVjb3ZlcmFibGUgbmF0aXZlIGdhdGV3YXksIHRoZSBuZXcgbGVhc2Ugc3VwcGxpZXMgSVB2NiByb3V0aW5nLgogICAgIyBDYXB0dXJlIGZpbGVzIGFuZCBwbGFuIGJlZm9yZSBzdG9wcGluZyBhbnl0aGluZy4gVGhlIHJlY29yZCBzdXJ2aXZlcyBwYXJ0aWFsIGNsZWFudXAuCiAgICBqb3VybmFsPWNsaWVudC5zdGF0ZS8nbGVnYWN5LWhhbmRvZmYuanNvbic7cmVjb3JkPXJlYWQoam91cm5hbCkKICAgIGlmIHJlY29yZCBhbmQgcmVjb3JkLmdldCgndXVpZCcpIT1jZmdbJ3V1aWQnXTpyYWlzZSBSdW50aW1lRXJyb3IoJ0xlZ2FjeSBoYW5kb2ZmIHJlY29yZCBiZWxvbmdzIHRvIGFub3RoZXIgVk0uJykKICAgIHJlY29yZC5zZXRkZWZhdWx0KCd1dWlkJyxjZmdbJ3V1aWQnXSk7cmVjb3JkLnNldGRlZmF1bHQoJ2ZpbGVzJyx7fSk7cmVjb3JkWydhZGRyZXNzZXMnXT1zb3J0ZWQoYWRkcmVzc2VzKTtyZWNvcmRbJ29ic29sZXRlX2FkZHJlc3NlcyddPXNvcnRlZChvYnNvbGV0ZSk7cmVjb3JkWydjb21wbGV0ZSddPUZhbHNlCiAgICBwYXRocz1bc3RhdGVmaWxlLGNsaWVudC5yb290LydldGMvbmV0cGxhbi85OS1keW5hbWljdjYueWFtbCcsY2xpZW50LnJvb3QvKCdldGMvbmV0d29yay9pbnRlcmZhY2VzLmQvOTktZHluYW1pY3Y2LScrY2ZnWydpbnRlcmZhY2UnXSsnLmNmZycpLGNsaWVudC5yb290LygnZXRjL3N5c2NvbmZpZy9uZXR3b3JrLXNjcmlwdHMvaWZjZmctJytjZmdbJ2ludGVyZmFjZSddKV0KICAgIGZvciBwYXRoIGluIFsqcGF0aHMsKmFydGlmYWN0c106CiAgICAgICAgaWYgcGF0aC5pc19maWxlKCk6cmVjb3JkWydmaWxlcyddLnNldGRlZmF1bHQoc3RyKHBhdGgucmVsYXRpdmVfdG8oY2xpZW50LnJvb3QpKSx7J2RhdGEnOmJhc2U2NC5iNjRlbmNvZGUocGF0aC5yZWFkX2J5dGVzKCkpLmRlY29kZSgpLCdtb2RlJzpwYXRoLnN0YXQoKS5zdF9tb2RlJjBvNzc3fSkKICAgIGlmIHJlc3RvcmU6cmVjb3JkWyduYXRpdmVfcmVzdG9yZSddPXJlc3RvcmUKICAgIHNhdmUoam91cm5hbCxyZWNvcmQpCiAgICBpZiBjbGllbnQuc2V0dXBfaW5pdCgpPT0nc3lzdGVtZCc6CiAgICAgICAgZm9yIHVuaXQgaW4gWydkeW5hbWljdjYtY2xpZW50LnRpbWVyJywnZHluYW1pY3Y2LWNsaWVudC5zZXJ2aWNlJ106CiAgICAgICAgICAgIGNsaWVudC5jb21tYW5kKFsnc3lzdGVtY3RsJywnc3RvcCcsdW5pdF0sRmFsc2UpCiAgICAgICAgICAgIGlmIGNsaWVudC5jb21tYW5kKFsnc3lzdGVtY3RsJywnaXMtYWN0aXZlJyx1bml0XSxGYWxzZSkgaW4gKCdhY3RpdmUnLCdhY3RpdmF0aW5nJywnZGVhY3RpdmF0aW5nJywncmVsb2FkaW5nJyk6CiAgICAgICAgICAgICAgICByYWlzZSBSdW50aW1lRXJyb3IoJ0NvdWxkIG5vdCBzdG9wIHRoZSBsZWdhY3kgSVB2NiBjbGllbnQ7IHJldHJ5IGluc3RhbGwuJykKICAgICAgICAgICAgY2xpZW50LmNvbW1hbmQoWydzeXN0ZW1jdGwnLCdkaXNhYmxlJyx1bml0XSxGYWxzZSkKICAgIGVsaWYgKGNsaWVudC5yb290LydldGMvaW5pdC5kL2R5bmFtaWN2Ni1jbGllbnQnKS5leGlzdHMoKToKICAgICAgICBjbGllbnQuY29tbWFuZChbJ3JjLXNlcnZpY2UnLCdkeW5hbWljdjYtY2xpZW50Jywnc3RvcCddKQogICAgICAgIGNsaWVudC5jb21tYW5kKFsncmMtdXBkYXRlJywnZGVsJywnZHluYW1pY3Y2LWNsaWVudCcsJ2RlZmF1bHQnXSxGYWxzZSkKICAgIGlmIHJlc3RvcmU6a2VybmVsLnB1dF9yb3V0ZShyZXN0b3JlKQogICAgIyBNYXRjaCBhIGZ1bGwgc291cmNlIC8xMjggYW5kIGl0cyBsZWdhY3kgdGFibGU7IGxlYXZlIGFsbCBvdGhlciBydWxlcyBhbG9uZS4KICAgIHJ1bGVzPVtyIGZvciByIGluIGtlcm5lbC5ydWxlcygpIGlmIG5vdCByLmdldCgndW5zdXBwb3J0ZWQnKSBhbmQgclsnc291cmNlJ10gaW4ge2ErJy8xMjgnIGZvciBhIGluIGFkZHJlc3Nlc30gYW5kIHJbJ3RhYmxlJ10uaXNkaWdpdCgpIGFuZCAxNjAwMDw9aW50KHJbJ3RhYmxlJ10pPDE2MTI4XQogICAgdGFibGVzPXtpbnQoclsndGFibGUnXSkgZm9yIHIgaW4gcnVsZXN9fHNldChyZWNvcmQuZ2V0KCd0YWJsZXMnLFtdKSkKICAgIHJlY29yZFsndGFibGVzJ109c29ydGVkKHRhYmxlcyk7c2F2ZShqb3VybmFsLHJlY29yZCkKICAgIGZvciByIGluIHJ1bGVzOmtlcm5lbC5kZWxfcnVsZShyKQogICAgZm9yIHIgaW4ga2VybmVsLnJvdXRlcygpOgogICAgICAgIGlmIHIuZ2V0KCd1bnN1cHBvcnRlZCcpIG9yIHIuZ2V0KCdkZXYnKSE9Y2ZnWydpbnRlcmZhY2UnXTpjb250aW51ZQogICAgICAgIGdhdGV3YXk9ci5nZXQoJ2dhdGV3YXknKTtkZXN0aW5hdGlvbj0oclsnZHN0J11bOi00XSBpZiByWydkc3QnXS5lbmRzd2l0aCgnLzEyOCcpIGVsc2UgclsnZHN0J10pCiAgICAgICAgb3duZWQ9KHJbJ3RhYmxlJ10gaW4gdGFibGVzIGFuZCAoZ2F0ZXdheSBpbiBnYXRld2F5cyBvciBkZXN0aW5hdGlvbiBpbiBnYXRld2F5cykpIG9yIChyWyd0YWJsZSddPT0yNTQgYW5kICgoclsnZHN0J109PSc6Oi8wJyBhbmQgZ2F0ZXdheSBpbiBnYXRld2F5cyBhbmQgclsnbWV0cmljJ10hPTk5KSBvciAoZGVzdGluYXRpb24gaW4gZ2F0ZXdheXMgYW5kIHJbJ21ldHJpYyddPT0xMDIzKSkpCiAgICAgICAgaWYgb3duZWQ6a2VybmVsLmRlbF9yb3V0ZShyKQogICAgZm9yIGEgaW4gb2Jzb2xldGU6CiAgICAgICAgaWYgYWN0dWFsLmdldChhLHt9KS5nZXQoJ3ByZWZpeGxlbicpPT0xMjg6a2VybmVsLmRlbF9hZGRyZXNzKGEpCiAgICAjIERlZGljYXRlZCBnZW5lcmF0ZWQgZmlsZXMgY29udGFpbiBvbmx5IHRoZSBsZWdhY3kgb3ZlcmxheS4gRG8gbm90IHJlbG9hZCB0aGUgTklDLgogICAgY2hhbmdlZF9uZXRwbGFuPUZhbHNlCiAgICBmb3IgcGF0aCBpbiBwYXRoc1sxOjNdOgogICAgICAgIGlmIHBhdGguaXNfZmlsZSgpIGFuZCBhbnkoYSBpbiBwYXRoLnJlYWRfdGV4dCgpIGZvciBhIGluIGFkZHJlc3Nlcyk6CiAgICAgICAgICAgIGlmIHBhdGguc3VmZml4PT0nLnlhbWwnOnJlY29yZFsnbmV0cGxhbl9nZW5lcmF0ZV9wZW5kaW5nJ109VHJ1ZTtzYXZlKGpvdXJuYWwscmVjb3JkKQogICAgICAgICAgICBwYXRoLnVubGluaygpO2NoYW5nZWRfbmV0cGxhbiB8PSBwYXRoLnN1ZmZpeD09Jy55YW1sJwogICAgcGF0aD1wYXRoc1szXQogICAgaWYgcGF0aC5pc19maWxlKCk6CiAgICAgICAgbGluZXM9W10KICAgICAgICBmb3IgbGluZSBpbiBwYXRoLnJlYWRfdGV4dCgpLnNwbGl0bGluZXMoa2VlcGVuZHM9VHJ1ZSk6CiAgICAgICAgICAgIG09cmUubWF0Y2gocideKElQVjZBRERSfElQVjZBRERSX1NFQ09OREFSSUVTKT0oLio/KShcbj8pJCcsbGluZSkKICAgICAgICAgICAgaWYgbm90IG06bGluZXMuYXBwZW5kKGxpbmUpO2NvbnRpbnVlCiAgICAgICAgICAgIHZhbHVlcz1tWzJdLnN0cmlwKCkuc3RyaXAoJ1wiXCcnKS5zcGxpdCgpO2tlcHQ9W10KICAgICAgICAgICAgZm9yIHZhbHVlIGluIHZhbHVlczoKICAgICAgICAgICAgICAgIHRyeTpvYnNvbGV0ZT1zdHIoaXBhZGRyZXNzLklQdjZJbnRlcmZhY2UodmFsdWUpLmlwKSBpbiBhZGRyZXNzZXMKICAgICAgICAgICAgICAgIGV4Y2VwdCBWYWx1ZUVycm9yOm9ic29sZXRlPUZhbHNlCiAgICAgICAgICAgICAgICBpZiBub3Qgb2Jzb2xldGU6a2VwdC5hcHBlbmQodmFsdWUpCiAgICAgICAgICAgIGlmIGxlbihrZXB0KT09bGVuKHZhbHVlcyk6bGluZXMuYXBwZW5kKGxpbmUpCiAgICAgICAgICAgIGVsaWYga2VwdDpsaW5lcy5hcHBlbmQobVsxXSsnPSInKycgJy5qb2luKGtlcHQpKyciXG4nKQogICAgICAgIGNvbnRlbnQ9Jycuam9pbihsaW5lcykKICAgICAgICBpZiBjb250ZW50IT1wYXRoLnJlYWRfdGV4dCgpOnBhdGgud3JpdGVfdGV4dChjb250ZW50KQogICAgaWYgY2hhbmdlZF9uZXRwbGFuIG9yIHJlY29yZC5nZXQoJ25ldHBsYW5fZ2VuZXJhdGVfcGVuZGluZycpOgogICAgICAgIGNsaWVudC5jb21tYW5kKFsnbmV0cGxhbicsJ2dlbmVyYXRlJ10pO3JlY29yZFsnbmV0cGxhbl9nZW5lcmF0ZV9wZW5kaW5nJ109RmFsc2UKICAgICMgUmVtb3ZlIG9ubHkgaWRlbnRpZmllZCBsZWdhY3kgZmlsZXMsIGFmdGVyIHRoZSBvbGQgcmVjb25jaWxlciBpcyBkaXNhYmxlZCBhbmQgY2xlYW51cCBzdWNjZWVkcy4KICAgIGZvciBwYXRoIGluIFtzdGF0ZWZpbGUsKmFydGlmYWN0c106CiAgICAgICAgaWYgcGF0aC5pc19maWxlKCkgb3IgcGF0aC5pc19zeW1saW5rKCk6cGF0aC51bmxpbmsoKQogICAgY2xpZW50LnNlcnZpY2VfcmVsb2FkKCkKICAgIHJlY29yZFsnY29tcGxldGUnXT1UcnVlO3JlY29yZFsnY29tcGxldGVkX2F0J109dGltZS50aW1lKCk7c2F2ZShqb3VybmFsLHJlY29yZCkK'}
with tempfile.TemporaryDirectory(prefix='dynamicv6-client-') as directory:
    for name,content in payload.items():(pathlib.Path(directory)/name).write_bytes(base64.b64decode(content))
    sys.path.insert(0,directory)
    from dvn_cli import main
    code=main(directory,config)
sys.exit(code)
DVN_EMBEDDED_PYTHON
