M.tuberculosis 20180913: Preprocessing DIA data with two libraries.

OpenSwathWorkflow against the Tuberculist transitions

The following invocations of OpenMS/pyprophet/tric are included in:

dia_invocation_20180913.sh

This script includes the process for generating a local, comet-based transition library from DDA samples generated locally as well as the steps used when processing the downloaded transition libraries.

Gathering parameters

In this first block, I will set a couple of variables and source a file containing the parameters for the rest of the script.

Plotting metrics of the raw data

The raw data files provide opportunities to make sure that the later invocations of openMS/etc will actually work; for example, if there are too few transitions observed here, one should not be surprised if pyprophet and tric fail later.

sampleid TubeID tubelabel FigureReplicate Figure.Name Sample.Description Bio.Replicate LC.Run.(tentative.certainly.wrong.until.I.bug.Yan) MS.Run.(tentative.wrong.until.I.bug.Yan) Technical.Replicate Replicate.State Run expt_id Genotype Collection.Type Condition batch windowsize enzyme harvestdate prepdate rundate runinfo rawfile Filename dia_scored tuberculist_scored include_exclude Run_note
2018_0817BrikenTrypsinDIA01 20180404.07 4.4.18 07-7 01 delta_filtrate_01 H37Rv ΔEsx-5A; Culture Filtrate br01 20180828 01 tr06 br01_tr06 2018_0817BrikenTrypsinDIA01 aug2018 delta filtrate delta_filtrate aug2018 8 Trypsin 20171019 20180828 20180717 8 m/z SWATH windows results/00raw/20180828/2018_0817BrikenTrypsinDIA01.raw results/01mzXML/dia/20180817/2018_0817BrikenTrypsinDIA01.mzXML results/08pyprophet/20180817/whole_8mz/2018_0817BrikenTrypsinDIA01_vs_20180817_whole_HCD_dia_scored.tsv results/08pyprophet/20180817/whole_8mz_tuberculist/2018_0817BrikenTrypsinDIA01_vs_20180817_whole_HCD_dia_scored.tsv NA NA
2018_0817BrikenTrypsinDIA02 20180404.08 4.4.18 07-8 02 delta_filtrate_02 H37Rv ΔEsx-5A; Culture Filtrate br02 20180828 01 tr06 br02_tr06 2018_0817BrikenTrypsinDIA02 aug2018 delta filtrate delta_filtrate aug2018 8 Trypsin 20171019 20180828 20180717 8 m/z SWATH windows results/00raw/20180828/2018_0817BrikenTrypsinDIA02.raw results/01mzXML/dia/20180817/2018_0817BrikenTrypsinDIA02.mzXML results/08pyprophet/20180817/whole_8mz/2018_0817BrikenTrypsinDIA02_vs_20180817_whole_HCD_dia_scored.tsv results/08pyprophet/20180817/whole_8mz_tuberculist/2018_0817BrikenTrypsinDIA02_vs_20180817_whole_HCD_dia_scored.tsv NA NA
2018_0817BrikenTrypsinDIA03 20180404.09 4.4.18 07-9 03 delta_filtrate_03 H37Rv ΔEsx-5A; Culture Filtrate br03 20180828 01 tr06 br03_tr06 2018_0817BrikenTrypsinDIA03 aug2018 delta filtrate delta_filtrate aug2018 8 Trypsin 20171019 20180828 20180717 8 m/z SWATH windows results/00raw/20180828/2018_0817BrikenTrypsinDIA03.raw results/01mzXML/dia/20180817/2018_0817BrikenTrypsinDIA03.mzXML NA results/08pyprophet/20180817/whole_8mz_tuberculist/2018_0817BrikenTrypsinDIA03_vs_20180817_whole_HCD_dia_scored.tsv NA NA
2018_0817BrikenTrypsinDIA07 20180215.04 2.15.18-4 01 wt_filtrate_01 WT H37Rv Culture Filtrate br07 20180828 01 tr06 br07_tr06 2018_0817BrikenTrypsinDIA07 aug2018 wt filtrate wt_filtrate aug2018 8 Trypsin 20171019 20180828 20180717 8 m/z SWATH windows results/00raw/20180828/2018_0817BrikenTrypsinDIA07.raw results/01mzXML/dia/20180817/2018_0817BrikenTrypsinDIA07.mzXML results/08pyprophet/20180817/whole_8mz/2018_0817BrikenTrypsinDIA07_vs_20180817_whole_HCD_dia_scored.tsv results/08pyprophet/20180817/whole_8mz_tuberculist/2018_0817BrikenTrypsinDIA07_vs_20180817_whole_HCD_dia_scored.tsv NA NA
2018_0817BrikenTrypsinDIA08 20180215.05 2.15.18-5 02 wt_filtrate_02 WT H37Rv Culture Filtrate br08 20180828 01 tr06 br08_tr06 2018_0817BrikenTrypsinDIA08 aug2018 wt filtrate wt_filtrate aug2018 8 Trypsin 20171019 20180828 20180717 8 m/z SWATH windows results/00raw/20180828/2018_0817BrikenTrypsinDIA08.raw results/01mzXML/dia/20180817/2018_0817BrikenTrypsinDIA08.mzXML results/08pyprophet/20180817/whole_8mz/2018_0817BrikenTrypsinDIA08_vs_20180817_whole_HCD_dia_scored.tsv results/08pyprophet/20180817/whole_8mz_tuberculist/2018_0817BrikenTrypsinDIA08_vs_20180817_whole_HCD_dia_scored.tsv NA NA
2018_0817BrikenTrypsinDIA09 20180215.06 2.15.18-6 03 wt_filtrate_03 WT H37Rv Culture Filtrate br09 20180828 01 tr06 br09_tr06 2018_0817BrikenTrypsinDIA09 aug2018 wt filtrate wt_filtrate aug2018 8 Trypsin 20171019 20180828 20180717 8 m/z SWATH windows results/00raw/20180828/2018_0817BrikenTrypsinDIA09.raw results/01mzXML/dia/20180817/2018_0817BrikenTrypsinDIA09.mzXML results/08pyprophet/20180817/whole_8mz/2018_0817BrikenTrypsinDIA09_vs_20180817_whole_HCD_dia_scored.tsv results/08pyprophet/20180817/whole_8mz_tuberculist/2018_0817BrikenTrypsinDIA09_vs_20180817_whole_HCD_dia_scored.tsv NA NA
2018_0817BrikenTrypsinDIA11 20180404.01 4.4.18 07-1 01 delta_whole_01 H37Rv ΔEsx-5A; Whole Cell Lysate br10 20180828 01 tr06 br10_tr06 2018_0817BrikenTrypsinDIA11 aug2018 delta whole delta_whole aug2018 8 Trypsin 20171019 20180828 20180717 8 m/z SWATH windows results/00raw/20180828/2018_0817BrikenTrypsinDIA11.raw results/01mzXML/dia/20180817/2018_0817BrikenTrypsinDIA11.mzXML results/08pyprophet/20180817/whole_8mz/2018_0817BrikenTrypsinDIA11_vs_20180817_whole_HCD_dia_scored.tsv results/08pyprophet/20180817/whole_8mz_tuberculist/2018_0817BrikenTrypsinDIA11_vs_20180817_whole_HCD_dia_scored.tsv NA NA
2018_0817BrikenTrypsinDIA12 20180404.02 4.4.18 07-2 02 delta_whole_02 H37Rv ΔEsx-5A; Whole Cell Lysate br11 20180828 01 tr06 br11_tr06 2018_0817BrikenTrypsinDIA12 aug2018 delta whole delta_whole aug2018 8 Trypsin 20171019 20180828 20180717 8 m/z SWATH windows results/00raw/20180828/2018_0817BrikenTrypsinDIA12.raw results/01mzXML/dia/20180817/2018_0817BrikenTrypsinDIA12.mzXML results/08pyprophet/20180817/whole_8mz/2018_0817BrikenTrypsinDIA12_vs_20180817_whole_HCD_dia_scored.tsv results/08pyprophet/20180817/whole_8mz_tuberculist/2018_0817BrikenTrypsinDIA12_vs_20180817_whole_HCD_dia_scored.tsv NA NA
2018_0817BrikenTrypsinDIA13 20180404.03 4.4.18 07-3 03 delta_whole_03 H37Rv ΔEsx-5A; Whole Cell Lysate br12 20180828 01 tr06 br12_tr06 2018_0817BrikenTrypsinDIA13 aug2018 delta whole delta_whole aug2018 8 Trypsin 20171019 20180828 20180717 8 m/z SWATH windows results/00raw/20180828/2018_0817BrikenTrypsinDIA13.raw results/01mzXML/dia/20180817/2018_0817BrikenTrypsinDIA13.mzXML results/08pyprophet/20180817/whole_8mz/2018_0817BrikenTrypsinDIA13_vs_20180817_whole_HCD_dia_scored.tsv results/08pyprophet/20180817/whole_8mz_tuberculist/2018_0817BrikenTrypsinDIA13_vs_20180817_whole_HCD_dia_scored.tsv NA NA
2018_0817BrikenTrypsinDIA17 20180215.01 2.15.18-1 01 wt_whole_01 WT H37Rv Whole Cell Lysate br16 20180828 01 tr06 br16_tr06 2018_0817BrikenTrypsinDIA17 aug2018 wt whole wt_whole aug2018 8 Trypsin 20171019 20180828 20180717 8 m/z SWATH windows results/00raw/20180828/2018_0817BrikenTrypsinDIA17.raw results/01mzXML/dia/20180817/2018_0817BrikenTrypsinDIA17.mzXML results/08pyprophet/20180817/whole_8mz/2018_0817BrikenTrypsinDIA17_vs_20180817_whole_HCD_dia_scored.tsv results/08pyprophet/20180817/whole_8mz_tuberculist/2018_0817BrikenTrypsinDIA17_vs_20180817_whole_HCD_dia_scored.tsv NA NA
2018_0817BrikenTrypsinDIA18 20180215.02 2.15.18-2 02 wt_whole_02 WT H37Rv Whole Cell Lysate br17 20180828 01 tr06 br17_tr06 2018_0817BrikenTrypsinDIA18 aug2018 wt whole wt_whole aug2018 8 Trypsin 20171019 20180828 20180717 8 m/z SWATH windows results/00raw/20180828/2018_0817BrikenTrypsinDIA18.raw results/01mzXML/dia/20180817/2018_0817BrikenTrypsinDIA18.mzXML results/08pyprophet/20180817/whole_8mz/2018_0817BrikenTrypsinDIA18_vs_20180817_whole_HCD_dia_scored.tsv results/08pyprophet/20180817/whole_8mz_tuberculist/2018_0817BrikenTrypsinDIA18_vs_20180817_whole_HCD_dia_scored.tsv NA NA
2018_0817BrikenTrypsinDIA19 20180215.03 2.15.18-3 03 wt_whole_03 WT H37Rv Whole Cell Lysate br18 20180828 01 tr06 br18_tr06 2018_0817BrikenTrypsinDIA19 aug2018 wt whole wt_whole aug2018 8 Trypsin 20171019 20180828 20180717 8 m/z SWATH windows results/00raw/20180828/2018_0817BrikenTrypsinDIA19.raw results/01mzXML/dia/20180817/2018_0817BrikenTrypsinDIA19.mzXML results/08pyprophet/20180817/whole_8mz/2018_0817BrikenTrypsinDIA19_vs_20180817_whole_HCD_dia_scored.tsv results/08pyprophet/20180817/whole_8mz_tuberculist/2018_0817BrikenTrypsinDIA19_vs_20180817_whole_HCD_dia_scored.tsv NA NA
## Adding 2018_0817BrikenTrypsinDIA01
## Adding 2018_0817BrikenTrypsinDIA02
## Adding 2018_0817BrikenTrypsinDIA03
## Adding 2018_0817BrikenTrypsinDIA07
## Adding 2018_0817BrikenTrypsinDIA08
## Adding 2018_0817BrikenTrypsinDIA09
## Adding 2018_0817BrikenTrypsinDIA11
## Adding 2018_0817BrikenTrypsinDIA12
## Adding 2018_0817BrikenTrypsinDIA13
## Adding 2018_0817BrikenTrypsinDIA17
## Adding 2018_0817BrikenTrypsinDIA18
## Adding 2018_0817BrikenTrypsinDIA19
## This data will benefit from being displayed on the log scale.
## If this is not desired, set scale='raw'
## Some entries are 0.  We are on log scale, adding 1 to the data.
## Changed 176131 zero count features.
## Writing the image to: images/20180913_dia_mzxml_intensities-v20180913.png and calling dev.off().

## Adding 2018_0817BrikenTrypsinDIA01
## Adding 2018_0817BrikenTrypsinDIA02
## Adding 2018_0817BrikenTrypsinDIA03
## Adding 2018_0817BrikenTrypsinDIA07
## Adding 2018_0817BrikenTrypsinDIA08
## Adding 2018_0817BrikenTrypsinDIA09
## Adding 2018_0817BrikenTrypsinDIA11
## Adding 2018_0817BrikenTrypsinDIA12
## Adding 2018_0817BrikenTrypsinDIA13
## Adding 2018_0817BrikenTrypsinDIA17
## Adding 2018_0817BrikenTrypsinDIA18
## Adding 2018_0817BrikenTrypsinDIA19
## Writing the image to: images/20180913_dia_mzxml_retention-v20180913.png and calling dev.off().

## Adding 2018_0817BrikenTrypsinDIA01
## Adding 2018_0817BrikenTrypsinDIA02
## Adding 2018_0817BrikenTrypsinDIA03
## Adding 2018_0817BrikenTrypsinDIA07
## Adding 2018_0817BrikenTrypsinDIA08
## Adding 2018_0817BrikenTrypsinDIA09
## Adding 2018_0817BrikenTrypsinDIA11
## Adding 2018_0817BrikenTrypsinDIA12
## Adding 2018_0817BrikenTrypsinDIA13
## Adding 2018_0817BrikenTrypsinDIA17
## Adding 2018_0817BrikenTrypsinDIA18
## Adding 2018_0817BrikenTrypsinDIA19
## Writing the image to: images/20180913_dia_mzxml_mzbase-v20180913.png and calling dev.off().

## Adding 2018_0817BrikenTrypsinDIA01
## Adding 2018_0817BrikenTrypsinDIA02
## Adding 2018_0817BrikenTrypsinDIA03
## Adding 2018_0817BrikenTrypsinDIA07
## Adding 2018_0817BrikenTrypsinDIA08
## Adding 2018_0817BrikenTrypsinDIA09
## Adding 2018_0817BrikenTrypsinDIA11
## Adding 2018_0817BrikenTrypsinDIA12
## Adding 2018_0817BrikenTrypsinDIA13
## Adding 2018_0817BrikenTrypsinDIA17
## Adding 2018_0817BrikenTrypsinDIA18
## Adding 2018_0817BrikenTrypsinDIA19
## Writing the image to: images/20180913_dia_mzxml_scanintensity-v20180913.png and calling dev.off().

OpenSwathWorkflow invocation

block 16 contains the commands used to run openswathworkflow and pyprophet. Those are repeated here in order to test them interactively when needed.

echo "Invoking the OpenSwathWorkflow using the tuberculist transitions."
base_mzxmldir="results/01mzXML/dia/${VERSION}"
swath_inputs=$(/bin/ls "${base_mzxmldir}")
echo "Checking in, the inputs are: ${swath_inputs}"
mkdir -p "${TUBERCULIST_OUTDIR}"
pypdir="${PYPROPHET_OUTDIR}_tuberculist"
mkdir -p "${pypdir}"
for input in ${swath_inputs}
do
    in_mzxml="${base_mzxmldir}/${input}"
    name=$(basename "${input}" .mzXML)
    echo "Starting openswath run of ${name} using ${MZ_WINDOWS} windows at $(date)."
    tb_output_prefix="${TUBERCULIST_OUTDIR}/${name}_vs_${VERSION}_${TYPE}_${DDA_METHOD}_dia"
    pyprophet_output_prefix="${pypdir}/${name}_vs_${VERSION}_${TYPE}_${DDA_METHOD}_dia"
    echo "Deleting previous swath output file: ${tb_output_prefix}.osw"
    rm -f "${tb_output_prefix}.osw"
    OpenSwathWorkflow \
        -ini "parameters/openms_${VERSION}.ini" \
        -in "${in_mzxml}" \
        -swath_windows_file "windows/openswath_${name}.txt" \
        -tr "${TUBERCULIST_PQP}" \
        -out_osw "${tb_output_prefix}.osw" \
        2>"${tb_output_prefix}_osw.log" 1>&2
    if [[ "$?" -ne "0" ]]; then
        echo "OpenSwathWorkflow for ${name} failed."
    fi

    rm -f "${tb_output_prefix}_scored.osw"
    echo "Scoring individual swath run: ${tb_output_prefix}"
    pyprophet \
        score \
        --level ms1 \
        --in "${tb_output_prefix}.osw" \
        --out "${pyprophet_output_prefix}_scored.osw" \
        2>>"${pyprophet_output_prefix}_pyprophet_ms1.log" 1>&2
    if [[ "$?" -ne "0" ]]; then
        echo "MS1 scoring ${pyprophet_output_prefix}_scored.osw failed."
    fi

    pyprophet \
        score \
        --level ms2 \
        --in "${pyprophet_output_prefix}_scored.osw" \
        --out "${pyprophet_output_prefix}_scored.osw" \
        2>>"${pyprophet_output_prefix}_pyprophet_ms2.log" 1>&2
    if [[ "$?" -ne "0" ]]; then
        echo "MS2 scoring ${pyprophet_output_prefix}_scored.osw failed."
    fi

    pyprophet \
        protein \
        --in "${pyprophet_output_prefix}_scored.osw" \
        --context run-specific \
        2>>"${pyprophet_output_prefix}_pyprophet_protein.log" 1>&2
    if [[ "$?" -ne "0" ]]; then
        echo "Protein scoring ${pyprophet_output_prefix}_scored.osw failed."
    fi

    rm -f "${pyprophet_output_prefix}_scored.tsv"
    echo "Exporting individual swath run: to ${pyprophet_output_prefix}_scored.tsv"
    pyprophet \
        export \
        --in "${pyprophet_output_prefix}_scored.osw" \
        --out "${pyprophet_output_prefix}_scored.tsv" \
        2>>"${pyprophet_output_prefix}_pyprophet_export.log" 1>&2
    ## ok something is fubar, the stupid tsv files are being written in the cwd as run_filename.tsv
    ## No matter what I do!
    mv "${input}.tsv" "${pyprophet_output_prefix}_scored.tsv"
    if [[ "$?" -ne "0" ]]; then
        echo "Exporting ${pyprophet_output_prefix}_scored.tsv failed."
    fi
done

Merging the Tuberculist-derived data with TRIC

Finally, block 17 of the invocation script provides the command used to make the final, feature-aligned data which is used by SWATH2stats and friends. In addition, it generates a matrix of intensities by sample and some metadata. Once again, it is copy/pasted here to allow interactive testing.

Index version: 20180913

TODO

  • 2017-06-14:
## If you wish to reproduce this exact build of hpgltools, invoke the following:
## > git clone http://github.com/abelew/hpgltools.git
## > git reset f791b304824ce2290b018f28c7495bc9b4af9b38
## This is hpgltools commit: Thu Oct 25 15:57:52 2018 -0400: f791b304824ce2290b018f28c7495bc9b4af9b38
## Saving to 01_preprocessing_comet_20180806-v20180913.rda.xz

R version 3.5.1 (2018-07-02)

Platform: x86_64-pc-linux-gnu (64-bit)

locale: LC_CTYPE=en_US.utf8, LC_NUMERIC=C, LC_TIME=en_US.utf8, LC_COLLATE=en_US.utf8, LC_MONETARY=en_US.utf8, LC_MESSAGES=en_US.utf8, LC_PAPER=en_US.utf8, LC_NAME=C, LC_ADDRESS=C, LC_TELEPHONE=C, LC_MEASUREMENT=en_US.utf8 and LC_IDENTIFICATION=C

attached base packages: stats, graphics, grDevices, utils, datasets, methods and base

other attached packages: foreach(v.1.4.4) and hpgltools(v.2018.03)

loaded via a namespace (and not attached): tidyselect(v.0.2.5), xfun(v.0.3), pander(v.0.6.2), purrr(v.0.2.5), doSNOW(v.1.0.16), colorspace(v.1.3-2), snow(v.0.4-3), miniUI(v.0.1.1.1), htmltools(v.0.3.6), yaml(v.2.2.0), base64enc(v.0.1-3), rlang(v.0.3.0), later(v.0.7.5), pillar(v.1.3.0), glue(v.1.3.0), withr(v.2.1.2), RColorBrewer(v.1.1-2), BiocGenerics(v.0.26.0), bindrcpp(v.0.2.2), questionr(v.0.6.3), plyr(v.1.8.4), bindr(v.0.1.1), stringr(v.1.3.1), munsell(v.0.5.0), commonmark(v.1.6), gtable(v.0.2.0), zip(v.1.0.0), devtools(v.1.13.6), codetools(v.0.2-15), evaluate(v.0.12), memoise(v.1.1.0), Biobase(v.2.40.0), knitr(v.1.20), rmdformats(v.0.3.3), doParallel(v.1.0.14), httpuv(v.1.4.5), parallel(v.3.5.1), highr(v.0.7), Rcpp(v.0.12.19), xtable(v.1.8-3), promises(v.1.0.1), scales(v.1.0.0), backports(v.1.1.2), mime(v.0.6), ggplot2(v.3.0.0), digest(v.0.6.18), openxlsx(v.4.1.0), stringi(v.1.2.4), bookdown(v.0.7), dplyr(v.0.7.7), shiny(v.1.1.0), grid(v.3.5.1), rprojroot(v.1.3-2), tools(v.3.5.1), magrittr(v.1.5), lazyeval(v.0.2.1), tibble(v.1.4.2), crayon(v.1.3.4), pkgconfig(v.2.0.2), xml2(v.1.2.0), data.table(v.1.11.8), assertthat(v.0.2.0), rmarkdown(v.1.10), roxygen2(v.6.1.0), rstudioapi(v.0.8), iterators(v.1.0.10), R6(v.2.3.0) and compiler(v.3.5.1)

atb abelew@gmail.com

2018-10-26

LS0tCnRpdGxlOiAiTS50dWJlcmN1bG9zaXMgMjAxODA5MTM6IFByZXByb2Nlc3NpbmcgRElBIGRhdGEgd2l0aCB0d28gbGlicmFyaWVzLiIKYXV0aG9yOiAiYXRiIGFiZWxld0BnbWFpbC5jb20iCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCIKb3V0cHV0OgogIHJtZGZvcm1hdHM6OnJlYWR0aGVkb3duOgogICAgY29kZV9kb3dubG9hZDogdHJ1ZQogICAgY29kZV9mb2xkaW5nOiBzaG93CiAgICBkZl9wcmludDogcGFnZWQKICAgIGZpZ19jYXB0aW9uOiB0cnVlCiAgICBmaWdfaGVpZ2h0OiA3CiAgICBmaWdfd2lkdGg6IDcKICAgIGhpZ2hsaWdodDogdGFuZ28KICAgIHdpZHRoOiAzMDAKICAgIGtlZXBfbWQ6IGZhbHNlCiAgICBtb2RlOiBzZWxmY29udGFpbmVkCiAgICB0b2NfZmxvYXQ6IHRydWUKICBCaW9jU3R5bGU6Omh0bWxfZG9jdW1lbnQ6CiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICBjb2RlX2ZvbGRpbmc6IHNob3cKICAgIGZpZ19jYXB0aW9uOiB0cnVlCiAgICBmaWdfaGVpZ2h0OiA3CiAgICBmaWdfd2lkdGg6IDcKICAgIGhpZ2hsaWdodDogdGFuZ28KICAgIGtlZXBfbWQ6IGZhbHNlCiAgICBtb2RlOiBzZWxmY29udGFpbmVkCiAgICB0b2NfZmxvYXQ6IHRydWUKICBodG1sX2RvY3VtZW50OgogICAgY29kZV9kb3dubG9hZDogdHJ1ZQogICAgY29kZV9mb2xkaW5nOiBzaG93CiAgICBmaWdfY2FwdGlvbjogdHJ1ZQogICAgZmlnX2hlaWdodDogNwogICAgZmlnX3dpZHRoOiA3CiAgICBoaWdobGlnaHQ6IHRhbmdvCiAgICBrZWVwX21kOiBmYWxzZQogICAgbW9kZTogc2VsZmNvbnRhaW5lZAogICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlCiAgICBzZWxmX2NvbnRhaW5lZDogdHJ1ZQogICAgdGhlbWU6IHJlYWRhYmxlCiAgICB0b2M6IHRydWUKICAgIHRvY19mbG9hdDoKICAgICAgY29sbGFwc2VkOiBmYWxzZQogICAgICBzbW9vdGhfc2Nyb2xsOiBmYWxzZQotLS0KCjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+CmJvZHksIHRkIHsKICBmb250LXNpemU6IDE2cHg7Cn0KY29kZS5yewogIGZvbnQtc2l6ZTogMTZweDsKfQpwcmUgewogZm9udC1zaXplOiAxNnB4Cn0KPC9zdHlsZT4KCmBgYHtyIG9wdGlvbnMsIGluY2x1ZGU9RkFMU0V9CmxpYnJhcnkoImhwZ2x0b29scyIpCnR0IDwtIGRldnRvb2xzOjpsb2FkX2FsbCgifi9ocGdsdG9vbHMiKQprbml0cjo6b3B0c19rbml0JHNldCh3aWR0aD0xMjAsCiAgICAgICAgICAgICAgICAgICAgIHByb2dyZXNzPVRSVUUsCiAgICAgICAgICAgICAgICAgICAgIHZlcmJvc2U9VFJVRSwKICAgICAgICAgICAgICAgICAgICAgZWNobz1UUlVFKQprbml0cjo6b3B0c19jaHVuayRzZXQoZXJyb3I9VFJVRSwKICAgICAgICAgICAgICAgICAgICAgIGRwaT05NikKb2xkX29wdGlvbnMgPC0gb3B0aW9ucyhkaWdpdHM9NCwKICAgICAgICAgICAgICAgICAgICAgICBtYXgucHJpbnQ9MTIwLAogICAgICAgICAgICAgICAgICAgICAgIHN0cmluZ3NBc0ZhY3RvcnM9RkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICAga25pdHIuZHVwbGljYXRlLmxhYmVsPSJhbGxvdyIpCmdncGxvdDI6OnRoZW1lX3NldChnZ3Bsb3QyOjp0aGVtZV9idyhiYXNlX3NpemU9MTApKQp2ZXIgPC0gIjIwMTgwOTEzIgpwcmV2aW91c19maWxlIDwtICIwMV9hbm5vdGF0aW9uXzIwMTgwOTEzLlJtZCIKCnRtcCA8LSB0cnkoc20obG9hZG1lKGZpbGVuYW1lPXBhc3RlMChnc3ViKHBhdHRlcm49IlxcLlJtZCIsIHJlcGxhY2U9IiIsIHg9cHJldmlvdXNfZmlsZSksICItdiIsIHZlciwgIi5yZGEueHoiKSkpKQpybWRfZmlsZSA8LSAiMDFfcHJlcHJvY2Vzc2luZ19jb21ldF8yMDE4MDgwNi5SbWQiCmBgYAoKIyBPcGVuU3dhdGhXb3JrZmxvdyBhZ2FpbnN0IHRoZSBUdWJlcmN1bGlzdCB0cmFuc2l0aW9ucwoKVGhlIGZvbGxvd2luZyBpbnZvY2F0aW9ucyBvZiBPcGVuTVMvcHlwcm9waGV0L3RyaWMgYXJlIGluY2x1ZGVkIGluOgoKW2RpYV9pbnZvY2F0aW9uXzIwMTgwOTEzLnNoXShkaWFfaW52b2NhdGlvbl8yMDE4MDkxMy5zaCkKClRoaXMgc2NyaXB0IGluY2x1ZGVzIHRoZSBwcm9jZXNzIGZvciBnZW5lcmF0aW5nIGEgbG9jYWwsIGNvbWV0LWJhc2VkIHRyYW5zaXRpb24KbGlicmFyeSBmcm9tIEREQSBzYW1wbGVzIGdlbmVyYXRlZCBsb2NhbGx5IGFzIHdlbGwgYXMgdGhlIHN0ZXBzIHVzZWQgd2hlbgpwcm9jZXNzaW5nIHRoZSBkb3dubG9hZGVkIHRyYW5zaXRpb24gbGlicmFyaWVzLgoKIyBHYXRoZXJpbmcgcGFyYW1ldGVycwoKSW4gdGhpcyBmaXJzdCBibG9jaywgSSB3aWxsIHNldCBhIGNvdXBsZSBvZiB2YXJpYWJsZXMgYW5kIHNvdXJjZSBhIGZpbGUKY29udGFpbmluZyB0aGUgcGFyYW1ldGVycyBmb3IgdGhlIHJlc3Qgb2YgdGhlIHNjcmlwdC4KCmBgYHtiYXNoIHBhcmFtZXRlcnMsIGV2YWw9RkFMU0V9CmV4cG9ydCBWRVJTSU9OPSIyMDE4MDkxMyIKc291cmNlIHBhcmFtZXRlcnMvMjAxODA5MTNfc2V0dGluZ3Muc2gKYGBgCgojIFBsb3R0aW5nIG1ldHJpY3Mgb2YgdGhlIHJhdyBkYXRhCgpUaGUgcmF3IGRhdGEgZmlsZXMgcHJvdmlkZSBvcHBvcnR1bml0aWVzIHRvIG1ha2Ugc3VyZSB0aGF0IHRoZSBsYXRlciBpbnZvY2F0aW9ucwpvZiBvcGVuTVMvZXRjIHdpbGwgYWN0dWFsbHkgd29yazsgZm9yIGV4YW1wbGUsIGlmIHRoZXJlIGFyZSB0b28gZmV3IHRyYW5zaXRpb25zCm9ic2VydmVkIGhlcmUsIG9uZSBzaG91bGQgbm90IGJlIHN1cnByaXNlZCBpZiBweXByb3BoZXQgYW5kIHRyaWMgZmFpbCBsYXRlci4KCmBgYHtyIGRpYV9tZXRyaWNzfQpzYW1wbGVfc2hlZXQgPC0gInNhbXBsZV9zaGVldHMvTXRiX2RpYV9zYW1wbGVzXzIwMTgwOTEzLnhsc3giCnNhdmVmaWxlIDwtICJtenhtbF9kaWFfZGF0YV8yMDE4MDkxMy5yZGEiCgptZXRhZGF0YSA8LSBvcGVueGxzeDo6cmVhZC54bHN4KHNhbXBsZV9zaGVldCkKa2VlcGVyX2lkeCA8LSAhZ3JlcGwocGF0dGVybj0iXiMiLCB4PW1ldGFkYXRhW1sic2FtcGxlaWQiXV0pCm1ldGFkYXRhIDwtIG1ldGFkYXRhW2tlZXBlcl9pZHgsIF0Ka25pdHI6OmthYmxlKG1ldGFkYXRhKQoKdG1waWR4IDwtIGdyZXAocGF0dGVybj0iMjAxOF8wODE3IiwgeD1tZXRhZGF0YVtbInNhbXBsZWlkIl1dKQptZXRhZGF0YSA8LSBtZXRhZGF0YVt0bXBpZHgsIF0KCmlmIChmaWxlLmV4aXN0cyhzYXZlZmlsZSkpIHsKICBsb2FkKHNhdmVmaWxlKQp9IGVsc2UgewogIG16eG1sX2RhdGEgPC0gZXh0cmFjdF9tenhtbF9kYXRhKG1ldGFkYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVfY29sdW1uPSJGaWxlbmFtZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2F2ZWZpbGU9c2F2ZWZpbGUpCn0KCmludGVuc2l0eV9ib3hwbG90IDwtIHBsb3RfbXp4bWxfYm94cGxvdChtenhtbF9kYXRhKQpwcChmaWxlPXBhc3RlMCgiaW1hZ2VzLzIwMTgwOTEzX2RpYV9tenhtbF9pbnRlbnNpdGllcy12IiwgdmVyLCAiLnBuZyIpLCBpbWFnZT1pbnRlbnNpdHlfYm94cGxvdCkKCnJldGVudGlvbl9ib3hwbG90IDwtIHBsb3RfbXp4bWxfYm94cGxvdChtenhtbF9kYXRhLCB0YWJsZT0ic2NhbnMiLCBjb2x1bW49InBlYWtzY291bnQiKQpwcChmaWxlPXBhc3RlMCgiaW1hZ2VzLzIwMTgwOTEzX2RpYV9tenhtbF9yZXRlbnRpb24tdiIsIHZlciwgIi5wbmciKSwgaW1hZ2U9cmV0ZW50aW9uX2JveHBsb3QpCgptel9ib3hwbG90IDwtIHBsb3RfbXp4bWxfYm94cGxvdChtenhtbF9kYXRhLCB0YWJsZT0ic2NhbnMiLCBjb2x1bW49ImJhc2VwZWFrbXoiKQpwcChmaWxlPXBhc3RlMCgiaW1hZ2VzLzIwMTgwOTEzX2RpYV9tenhtbF9temJhc2UtdiIsIHZlciwgIi5wbmciKSwgaW1hZ2U9bXpfYm94cGxvdCkKCnNjYW5pbnRlbnNpdHlfYm94cGxvdCA8LSBwbG90X216eG1sX2JveHBsb3QobXp4bWxfZGF0YSwgdGFibGU9InNjYW5zIiwgY29sdW1uPSJiYXNlcGVha2ludGVuc2l0eSIpCnBwKGZpbGU9cGFzdGUwKCJpbWFnZXMvMjAxODA5MTNfZGlhX216eG1sX3NjYW5pbnRlbnNpdHktdiIsIHZlciwgIi5wbmciKSwgaW1hZ2U9c2NhbmludGVuc2l0eV9ib3hwbG90KQoKIyNpbnRlbnNpdHlfd3J0X216IDwtIHBsb3RfaW50ZW5zaXR5X216KG16eG1sX2RhdGEsIHhfc2NhbGU9ImxvZyIsIHlfc2NhbGU9ImxvZyIpCiMjcHAoZmlsZT1wYXN0ZTAoImltYWdlcy8yMDE4MDVfZGlhX2ludGVuc2l0eV93cnRfbXpfZGlhLXYiLCB2ZXIsICIucG5nIiksIGltYWdlPWludGVuc2l0eV93cnRfbXopCmBgYAoKIyBDb252ZXJ0aW5nIGRvd25sb2FkZWQgdHJhbnNpdGlvbnMKCkluIGJsb2NrIDE1IG9mIGRpYV9pbnZvY2F0aW9uXzIwMTgwOTEzLnNoIHRoZSBjb21tYW5kIHVzZWQgaXMgcHJlc3RlZCBhbmQgY29waWVkCmhlcmUgZm9yIGludGVyYWN0aXZlIHJ1bm5pbmcuCgpgYGB7YmFzaCB0dWJlcmN1bGlzdF9jb252ZXJzaW9uLCBldmFsPUZBTFNFfQplY2hvICJDb252ZXJ0aW5nIHRoZSBUdWJlcmN1bGlzdCBsaWJyYXJpZXMgdG8gcHFwLiIKVFVCRVJDVUxJU1RfVFJBTUw9InJlc3VsdHMvMDVzcGVjdHJhbF9saWJyYXJpZXMvTXRiX1R1YmVyY3VMaXN0LVIyN19pUlRfVVBTX25vTW94X25vTUNfc2FsbF9vc3dfZGVjb3kuVHJhTUwiCmVjaG8gIlRoZSBpbnB1dCBpczogJHtUVUJFUkNVTElTVF9UUkFNTH0iCmVjaG8gIlRoZSBvdXRwdXQgaXM6ICR7VFVCRVJDVUxJU1RfUFFQfSIKVGFyZ2V0ZWRGaWxlQ29udmVydGVyIFwKICAgIC1pbiAiJHtUVUJFUkNVTElTVF9UUkFNTH0iIFwKICAgIC1pbl90eXBlIFRyYU1MIFwKICAgIC1vdXQgIiR7VFVCRVJDVUxJU1RfUFFQfSIgXAogICAgLW91dF90eXBlIHBxcCBcCiAgICAyPiIke1RVQkVSQ1VMSVNUX1BRUH1fY29udmVydC5sb2ciIDE+JjIKYGBgCgojIE9wZW5Td2F0aFdvcmtmbG93IGludm9jYXRpb24KCmJsb2NrIDE2IGNvbnRhaW5zIHRoZSBjb21tYW5kcyB1c2VkIHRvIHJ1biBvcGVuc3dhdGh3b3JrZmxvdyBhbmQgcHlwcm9waGV0LgpUaG9zZSBhcmUgcmVwZWF0ZWQgaGVyZSBpbiBvcmRlciB0byB0ZXN0IHRoZW0gaW50ZXJhY3RpdmVseSB3aGVuIG5lZWRlZC4KCmBgYHtiYXNoIG9wZW5zd2F0aF90dWJlcmN1bGlzdCwgZXZhbD1GQUxTRX0KZWNobyAiSW52b2tpbmcgdGhlIE9wZW5Td2F0aFdvcmtmbG93IHVzaW5nIHRoZSB0dWJlcmN1bGlzdCB0cmFuc2l0aW9ucy4iCmJhc2VfbXp4bWxkaXI9InJlc3VsdHMvMDFtelhNTC9kaWEvJHtWRVJTSU9OfSIKc3dhdGhfaW5wdXRzPSQoL2Jpbi9scyAiJHtiYXNlX216eG1sZGlyfSIpCmVjaG8gIkNoZWNraW5nIGluLCB0aGUgaW5wdXRzIGFyZTogJHtzd2F0aF9pbnB1dHN9Igpta2RpciAtcCAiJHtUVUJFUkNVTElTVF9PVVRESVJ9IgpweXBkaXI9IiR7UFlQUk9QSEVUX09VVERJUn1fdHViZXJjdWxpc3QiCm1rZGlyIC1wICIke3B5cGRpcn0iCmZvciBpbnB1dCBpbiAke3N3YXRoX2lucHV0c30KZG8KICAgIGluX216eG1sPSIke2Jhc2VfbXp4bWxkaXJ9LyR7aW5wdXR9IgogICAgbmFtZT0kKGJhc2VuYW1lICIke2lucHV0fSIgLm16WE1MKQogICAgZWNobyAiU3RhcnRpbmcgb3BlbnN3YXRoIHJ1biBvZiAke25hbWV9IHVzaW5nICR7TVpfV0lORE9XU30gd2luZG93cyBhdCAkKGRhdGUpLiIKICAgIHRiX291dHB1dF9wcmVmaXg9IiR7VFVCRVJDVUxJU1RfT1VURElSfS8ke25hbWV9X3ZzXyR7VkVSU0lPTn1fJHtUWVBFfV8ke0REQV9NRVRIT0R9X2RpYSIKICAgIHB5cHJvcGhldF9vdXRwdXRfcHJlZml4PSIke3B5cGRpcn0vJHtuYW1lfV92c18ke1ZFUlNJT059XyR7VFlQRX1fJHtEREFfTUVUSE9EfV9kaWEiCiAgICBlY2hvICJEZWxldGluZyBwcmV2aW91cyBzd2F0aCBvdXRwdXQgZmlsZTogJHt0Yl9vdXRwdXRfcHJlZml4fS5vc3ciCiAgICBybSAtZiAiJHt0Yl9vdXRwdXRfcHJlZml4fS5vc3ciCiAgICBPcGVuU3dhdGhXb3JrZmxvdyBcCiAgICAgICAgLWluaSAicGFyYW1ldGVycy9vcGVubXNfJHtWRVJTSU9OfS5pbmkiIFwKICAgICAgICAtaW4gIiR7aW5fbXp4bWx9IiBcCiAgICAgICAgLXN3YXRoX3dpbmRvd3NfZmlsZSAid2luZG93cy9vcGVuc3dhdGhfJHtuYW1lfS50eHQiIFwKICAgICAgICAtdHIgIiR7VFVCRVJDVUxJU1RfUFFQfSIgXAogICAgICAgIC1vdXRfb3N3ICIke3RiX291dHB1dF9wcmVmaXh9Lm9zdyIgXAogICAgICAgIDI+IiR7dGJfb3V0cHV0X3ByZWZpeH1fb3N3LmxvZyIgMT4mMgogICAgaWYgW1sgIiQ/IiAtbmUgIjAiIF1dOyB0aGVuCiAgICAgICAgZWNobyAiT3BlblN3YXRoV29ya2Zsb3cgZm9yICR7bmFtZX0gZmFpbGVkLiIKICAgIGZpCgogICAgcm0gLWYgIiR7dGJfb3V0cHV0X3ByZWZpeH1fc2NvcmVkLm9zdyIKICAgIGVjaG8gIlNjb3JpbmcgaW5kaXZpZHVhbCBzd2F0aCBydW46ICR7dGJfb3V0cHV0X3ByZWZpeH0iCiAgICBweXByb3BoZXQgXAogICAgICAgIHNjb3JlIFwKICAgICAgICAtLWxldmVsIG1zMSBcCiAgICAgICAgLS1pbiAiJHt0Yl9vdXRwdXRfcHJlZml4fS5vc3ciIFwKICAgICAgICAtLW91dCAiJHtweXByb3BoZXRfb3V0cHV0X3ByZWZpeH1fc2NvcmVkLm9zdyIgXAogICAgICAgIDI+PiIke3B5cHJvcGhldF9vdXRwdXRfcHJlZml4fV9weXByb3BoZXRfbXMxLmxvZyIgMT4mMgogICAgaWYgW1sgIiQ/IiAtbmUgIjAiIF1dOyB0aGVuCiAgICAgICAgZWNobyAiTVMxIHNjb3JpbmcgJHtweXByb3BoZXRfb3V0cHV0X3ByZWZpeH1fc2NvcmVkLm9zdyBmYWlsZWQuIgogICAgZmkKCiAgICBweXByb3BoZXQgXAogICAgICAgIHNjb3JlIFwKICAgICAgICAtLWxldmVsIG1zMiBcCiAgICAgICAgLS1pbiAiJHtweXByb3BoZXRfb3V0cHV0X3ByZWZpeH1fc2NvcmVkLm9zdyIgXAogICAgICAgIC0tb3V0ICIke3B5cHJvcGhldF9vdXRwdXRfcHJlZml4fV9zY29yZWQub3N3IiBcCiAgICAgICAgMj4+IiR7cHlwcm9waGV0X291dHB1dF9wcmVmaXh9X3B5cHJvcGhldF9tczIubG9nIiAxPiYyCiAgICBpZiBbWyAiJD8iIC1uZSAiMCIgXV07IHRoZW4KICAgICAgICBlY2hvICJNUzIgc2NvcmluZyAke3B5cHJvcGhldF9vdXRwdXRfcHJlZml4fV9zY29yZWQub3N3IGZhaWxlZC4iCiAgICBmaQoKICAgIHB5cHJvcGhldCBcCiAgICAgICAgcHJvdGVpbiBcCiAgICAgICAgLS1pbiAiJHtweXByb3BoZXRfb3V0cHV0X3ByZWZpeH1fc2NvcmVkLm9zdyIgXAogICAgICAgIC0tY29udGV4dCBydW4tc3BlY2lmaWMgXAogICAgICAgIDI+PiIke3B5cHJvcGhldF9vdXRwdXRfcHJlZml4fV9weXByb3BoZXRfcHJvdGVpbi5sb2ciIDE+JjIKICAgIGlmIFtbICIkPyIgLW5lICIwIiBdXTsgdGhlbgogICAgICAgIGVjaG8gIlByb3RlaW4gc2NvcmluZyAke3B5cHJvcGhldF9vdXRwdXRfcHJlZml4fV9zY29yZWQub3N3IGZhaWxlZC4iCiAgICBmaQoKICAgIHJtIC1mICIke3B5cHJvcGhldF9vdXRwdXRfcHJlZml4fV9zY29yZWQudHN2IgogICAgZWNobyAiRXhwb3J0aW5nIGluZGl2aWR1YWwgc3dhdGggcnVuOiB0byAke3B5cHJvcGhldF9vdXRwdXRfcHJlZml4fV9zY29yZWQudHN2IgogICAgcHlwcm9waGV0IFwKICAgICAgICBleHBvcnQgXAogICAgICAgIC0taW4gIiR7cHlwcm9waGV0X291dHB1dF9wcmVmaXh9X3Njb3JlZC5vc3ciIFwKICAgICAgICAtLW91dCAiJHtweXByb3BoZXRfb3V0cHV0X3ByZWZpeH1fc2NvcmVkLnRzdiIgXAogICAgICAgIDI+PiIke3B5cHJvcGhldF9vdXRwdXRfcHJlZml4fV9weXByb3BoZXRfZXhwb3J0LmxvZyIgMT4mMgogICAgIyMgb2sgc29tZXRoaW5nIGlzIGZ1YmFyLCB0aGUgc3R1cGlkIHRzdiBmaWxlcyBhcmUgYmVpbmcgd3JpdHRlbiBpbiB0aGUgY3dkIGFzIHJ1bl9maWxlbmFtZS50c3YKICAgICMjIE5vIG1hdHRlciB3aGF0IEkgZG8hCiAgICBtdiAiJHtpbnB1dH0udHN2IiAiJHtweXByb3BoZXRfb3V0cHV0X3ByZWZpeH1fc2NvcmVkLnRzdiIKICAgIGlmIFtbICIkPyIgLW5lICIwIiBdXTsgdGhlbgogICAgICAgIGVjaG8gIkV4cG9ydGluZyAke3B5cHJvcGhldF9vdXRwdXRfcHJlZml4fV9zY29yZWQudHN2IGZhaWxlZC4iCiAgICBmaQpkb25lCmBgYAoKIyBNZXJnaW5nIHRoZSBUdWJlcmN1bGlzdC1kZXJpdmVkIGRhdGEgd2l0aCBUUklDCgpGaW5hbGx5LCBibG9jayAxNyBvZiB0aGUgaW52b2NhdGlvbiBzY3JpcHQgcHJvdmlkZXMgdGhlIGNvbW1hbmQgdXNlZCB0byBtYWtlIHRoZQpmaW5hbCwgZmVhdHVyZS1hbGlnbmVkIGRhdGEgd2hpY2ggaXMgdXNlZCBieSBTV0FUSDJzdGF0cyBhbmQgZnJpZW5kcy4gIEluCmFkZGl0aW9uLCBpdCBnZW5lcmF0ZXMgYSBtYXRyaXggb2YgaW50ZW5zaXRpZXMgYnkgc2FtcGxlIGFuZCBzb21lIG1ldGFkYXRhLgpPbmNlIGFnYWluLCBpdCBpcyBjb3B5L3Bhc3RlZCBoZXJlIHRvIGFsbG93IGludGVyYWN0aXZlIHRlc3RpbmcuCgpgYGB7YmFzaCB0dWJfdHJpYywgZXZhbD1GQUxTRX0KdHJpY190Yj0iJHtUUklDX09VVERJUn1fdHViZXJjdWxpc3QiCm1rZGlyIC1wICIke3RyaWNfdGJ9IgpmZWF0dXJlX2FsaWdubWVudC5weSBcCiAgICAtLWZvcmNlIFwKICAgIC0taW4gIi4vJHtweXBkaXJ9LyIqLnRzdiBcCiAgICAtLW91dCAiJHt0cmljX3RifS8ke1NFQVJDSF9NRVRIT0R9XyR7RERBX01FVEhPRH0udHN2IiBcCiAgICAtLW91dF9tYXRyaXggIiR7dHJpY190Yn0vJHtEREFfTUVUSE9EfV9vdXRtYXRyaXgudHN2IiBcCiAgICAtLW91dF9tZXRhICIke3RyaWNfdGJ9LyR7RERBX01FVEhPRH1fbWV0YS50c3YiCjI+IiR7dHJpY190Yn0vZmVhdHVyZV9hbGlnbm1lbnQuZXJyIiBcCiAxPiIke3RyaWNfdGJ9L2ZlYXR1cmVfYWxpZ25tZW50Lm91dCIKZWNobyAiV3JvdGUgZmluYWwgb3V0cHV0IHRvICR7dHJpY190Yn0vJHtTRUFSQ0hfTUVUSE9EfV8ke0REQV9NRVRIT0R9LnRzdiIKYGBgCgoKIyBJbmRleCB2ZXJzaW9uOiBgciB2ZXJgCgojIFRPRE8KCiogMjAxNy0wNi0xNDoKCmBgYHtyIHNhdmVtZX0KaWYgKCFpc1RSVUUoZ2V0MCgic2tpcF9sb2FkIikpKSB7CiAgbWVzc2FnZShwYXN0ZTAoIlRoaXMgaXMgaHBnbHRvb2xzIGNvbW1pdDogIiwgZ2V0X2dpdF9jb21taXQoKSkpCiAgdGhpc19zYXZlIDwtIHBhc3RlMChnc3ViKHBhdHRlcm49IlxcLlJtZCIsIHJlcGxhY2U9IiIsIHg9cm1kX2ZpbGUpLCAiLXYiLCB2ZXIsICIucmRhLnh6IikKICBtZXNzYWdlKHBhc3RlMCgiU2F2aW5nIHRvICIsIHRoaXNfc2F2ZSkpCiAgdG1wIDwtIHNtKHNhdmVtZShmaWxlbmFtZT10aGlzX3NhdmUpKQogIHBhbmRlcjo6cGFuZGVyKHNlc3Npb25JbmZvKCkpCn0KYGBgCg==