The purpose of this notebook is to clean copy number data related to C19MC amplifications in non-MB, non-ATRT embryonal tumors (AlexsLemonade/OpenPBTA-analysis#251).
Specifically, we are trying to identify Embryonal tumor with multilayered rosettes (ETMR), C19MC-altered tumors.
Usage
This notebook can be run via the command line from the root directory of the repository with:
Rscript -e "rmarkdown::render('analyses/molecular-subtyping-embryonal/03-clean-c19mc-data.Rmd', clean = TRUE)"
Set up
Libraries and functions
suppressPackageStartupMessages(library(tidyverse))
suppressPackageStartupMessages(library(ggbio))
We’re going to adapt code from the cnv-chrom-plot module to plot chromosome 19.
plot_chr19 <- function(cn_df, biospecimen_id) {
# This function takes a seg data.frame and a biospecimen identifier and
# returns a plot of the chromosome 19 segment mean for that biospecimen.
# It fills missing seg.mean values with zeroes.
#
# Args:
# cn_df: data.frame in SEG format
# biospecimen_id: A Kids First Biospecimen ID used to filter cn_df
#
# Returns: essentially a barplot of the non-neutral segment means
bsid_data <- cn_df %>%
# For visualization purposes fill the missing seg.mean values with zeroes
tidyr::replace_na(list(seg.mean = 0)) %>%
# Reformat the chromosome variable to drop the "chr"
dplyr::mutate(chrom = factor(gsub("chr", "", chrom),
levels = c(1:22, "X", "Y"))) %>%
# Only look at chr19 in the relevant sample
filter(ID == biospecimen_id,
chrom == 19) %>%
# Make Del/Amp variable
dplyr::mutate(Type = dplyr::case_when(
seg.mean < 0 ~ "Del",
seg.mean > 0 ~ "Amp",
seg.mean == 0 ~ "Neutral"
))
# Turn into a GRanges for easier mapping
bsid_ranges <- GenomicRanges::GRanges(
seqnames = bsid_data$chrom,
ranges = IRanges::IRanges(
start = bsid_data$loc.start,
end = bsid_data$loc.end
),
score = bsid_data$seg.mean,
mcols = bsid_data$Type
)
# Map this on a plot
bsid_plot <-
ggbio::autoplot(bsid_ranges,
ggplot2::aes(y = score, fill = mcols),
geom = "bar") +
ggplot2::theme_bw() +
ggplot2::ylim(c(-2, 2)) +
colorblindr::scale_fill_OkabeIto(name = "Type") +
ggplot2::labs(
title = paste(biospecimen_id, "chr19"),
y = "segment mean"
)
return(bsid_plot)
}
Directories
results_dir <- "results"
data_dir <- file.path("..", "..", "data")
Read in Files
# full clinical file
histologies_file <- file.path(data_dir, "pbta-histologies.tsv")
histologies_df <- read_tsv(histologies_file,
col_types = cols(
molecular_subtype = col_character()
))
# copy number consensus file (analysis file)
# TODO: get this from data download
cn_consensus_seg <- file.path("..", "copy_number_consensus_call", "results",
"pbta-cnv-consensus.seg.gz")
# file that contains the biospecimen IDs that met criteria for subtyping
biospecimen_file <- file.path(results_dir,
"biospecimen_ids_embryonal_subtyping.tsv")
# get biospecimen ids as a vector rather than data frame
biospecimen_ids <- read_tsv(biospecimen_file) %>%
pull(Kids_First_Biospecimen_ID)
# we'll filter to only the relevant biospecimens for the copy number alteration
# data that is committed to the repository
cn_consensus <- read_tsv(cn_consensus_seg) %>%
filter(ID %in% biospecimen_ids)
Output file
output_file <- file.path(results_dir, "cleaned_chr19_cn.tsv")
Look at copy number alterations on chr 19
We’re interested in focal amplification of C19MC (miRNA cluster on chr19) for the ETMR, C19MC-altered subtype.
chr19_cn_df <- cn_consensus %>%
filter(chrom == "chr19",
seg.mean > 0)
chr19_cn_df
These are not within the ranges from @sjspielman provided here:
## From UCSC Genome Brower, these are positions corresponding to 19q13.41 (C19MC region)
c19mc_region <- "19q13.41"
c19mc_start <- 51400001
c19mc_end <- 53600000
But they do overlap with coordinates from other papers. These are from Jo Lynne Rokita in this comment.
From Bentwich et al. Nature Genetics. 2005.:
Cluster on chromosome 19 located at positions 58,861,745–58,961,404 (HG17) and comprising 54 microRNA genes grouped into four families on the basis of hairpin sequence similarity.
| hg17 |
chr19 |
58861745 |
58961404 |
| hg19 |
chr19 |
54169933 |
54269592 |
| hg38 |
chr19 |
53666679 |
53766338 |
and from Bortolin-Cavaillé et al. NAR. 2009.:
Schematic representation of the ∼100-kb long C19MC (HG18: 58 860 000–58 962 300) mapping at human chromosome 19q13.41
| hg18 |
chr19 |
58860000 |
58962300 |
| hg38 |
chr19 |
53664934 |
53767234 |
Visualization
For visualization purposes, we are filling in the missing seg.mean values with zeroes.
plot_chr19(cn_df = cn_consensus,
biospecimen_id = "BS_69VS8PS1")

plot_chr19(cn_df = cn_consensus,
biospecimen_id = "BS_K07KNTFY")

plot_chr19(cn_df = cn_consensus,
biospecimen_id = "BS_TE8QFF7T")

Generate cleaned table for joining to fusion and expression data
The copy numbers in all of the above cases are high - we’ll simplify the column name to chr19_amplification.
# get a data.frame of the relevant WGS biospecimen_ids
wgs_ids <- intersect(histologies_df %>%
filter(experimental_strategy == "WGS") %>%
pull(Kids_First_Biospecimen_ID),
biospecimen_ids) %>%
as.data.frame(stringsAsFactors = FALSE) %>%
rename(Kids_First_Biospecimen_ID = ".")
chr19_cn_df <- chr19_cn_df %>%
mutate(chr19_amplification = "Yes") %>%
select(ID, chr19_amplification) %>%
right_join(wgs_ids, by = c("ID" = "Kids_First_Biospecimen_ID")) %>%
replace(is.na(.), "No")
Write to file.
chr19_cn_df %>%
rename(Kids_First_Biospecimen_ID = ID) %>%
write_tsv(output_file)
LS0tCnRpdGxlOiAiTW9sZWN1bGFybHkgU3VidHlwaW5nIEVtYnJ5b25hbCBUdW1vcnMgLSBDMTlNQyBhbXBsaWZpY2F0aW9ucyIKb3V0cHV0OiAKICBodG1sX25vdGVib29rOgogICAgdG9jOiBUUlVFCiAgICB0b2NfZmxvYXQ6IFRSVUUKYXV0aG9yOiBKbyBMeW5uZSBSb2tpdGEsIFN0ZXBoYW5pZSBKLiBTcGllbG1hbiwgYW5kIEphY2x5biBOLiBUYXJvbmkKZGF0ZTogMjAyMAotLS0KClRoZSBwdXJwb3NlIG9mIHRoaXMgbm90ZWJvb2sgaXMgdG8gY2xlYW4gY29weSBudW1iZXIgZGF0YSByZWxhdGVkIHRvIEMxOU1DIGFtcGxpZmljYXRpb25zIGluIG5vbi1NQiwgbm9uLUFUUlQgZW1icnlvbmFsIHR1bW9ycyAoW2BBbGV4c0xlbW9uYWRlL09wZW5QQlRBLWFuYWx5c2lzIzI1MWBdKGh0dHBzOi8vZ2l0aHViLmNvbS9BbGV4c0xlbW9uYWRlL09wZW5QQlRBLWFuYWx5c2lzL2lzc3Vlcy8yNTEpKS4KClNwZWNpZmljYWxseSwgd2UgYXJlIHRyeWluZyB0byBpZGVudGlmeSBFbWJyeW9uYWwgdHVtb3Igd2l0aCBtdWx0aWxheWVyZWQgcm9zZXR0ZXMgKEVUTVIpLCBDMTlNQy1hbHRlcmVkIHR1bW9ycy4KCiMjIFVzYWdlCgpUaGlzIG5vdGVib29rIGNhbiBiZSBydW4gdmlhIHRoZSBjb21tYW5kIGxpbmUgZnJvbSB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhlIHJlcG9zaXRvcnkgd2l0aDoKCmBgYApSc2NyaXB0IC1lICJybWFya2Rvd246OnJlbmRlcignYW5hbHlzZXMvbW9sZWN1bGFyLXN1YnR5cGluZy1lbWJyeW9uYWwvMDMtY2xlYW4tYzE5bWMtZGF0YS5SbWQnLCBjbGVhbiA9IFRSVUUpIgpgYGAKCiMjIFNldCB1cAoKIyMjIExpYnJhcmllcyBhbmQgZnVuY3Rpb25zCgpgYGB7cn0Kc3VwcHJlc3NQYWNrYWdlU3RhcnR1cE1lc3NhZ2VzKGxpYnJhcnkodGlkeXZlcnNlKSkKc3VwcHJlc3NQYWNrYWdlU3RhcnR1cE1lc3NhZ2VzKGxpYnJhcnkoZ2diaW8pKQpgYGAKCldlJ3JlIGdvaW5nIHRvIGFkYXB0IGNvZGUgZnJvbSB0aGUgW2BjbnYtY2hyb20tcGxvdGBdKGh0dHBzOi8vZ2l0aHViLmNvbS9BbGV4c0xlbW9uYWRlL09wZW5QQlRBLWFuYWx5c2lzL3RyZWUvZWFkYjc4ZDllZjAyZDM1YWUwNmE4ODEwNGIyOWI0ZDAzMjU0OTlhNi9hbmFseXNlcy9jbnYtY2hyb20tcGxvdCkgbW9kdWxlIHRvIHBsb3QgY2hyb21vc29tZSAxOS4KCmBgYHtyfQpwbG90X2NocjE5IDwtIGZ1bmN0aW9uKGNuX2RmLCBiaW9zcGVjaW1lbl9pZCkgewogIyBUaGlzIGZ1bmN0aW9uIHRha2VzIGEgc2VnIGRhdGEuZnJhbWUgYW5kIGEgYmlvc3BlY2ltZW4gaWRlbnRpZmllciBhbmQgCiAjIHJldHVybnMgYSBwbG90IG9mIHRoZSBjaHJvbW9zb21lIDE5IHNlZ21lbnQgbWVhbiBmb3IgdGhhdCBiaW9zcGVjaW1lbi4KICMgSXQgZmlsbHMgbWlzc2luZyBzZWcubWVhbiB2YWx1ZXMgd2l0aCB6ZXJvZXMuCiAjIAogIyBBcmdzOgogIyAgIGNuX2RmOiBkYXRhLmZyYW1lIGluIFNFRyBmb3JtYXQKICMgICBiaW9zcGVjaW1lbl9pZDogQSBLaWRzIEZpcnN0IEJpb3NwZWNpbWVuIElEIHVzZWQgdG8gZmlsdGVyIGNuX2RmCiAjIAogIyBSZXR1cm5zOiBlc3NlbnRpYWxseSBhIGJhcnBsb3Qgb2YgdGhlIG5vbi1uZXV0cmFsIHNlZ21lbnQgbWVhbnMKICAKICBic2lkX2RhdGEgPC0gY25fZGYgJT4lICAKICAgICMgRm9yIHZpc3VhbGl6YXRpb24gcHVycG9zZXMgZmlsbCB0aGUgbWlzc2luZyBzZWcubWVhbiB2YWx1ZXMgd2l0aCB6ZXJvZXMKICAgIHRpZHlyOjpyZXBsYWNlX25hKGxpc3Qoc2VnLm1lYW4gPSAwKSkgJT4lCiAgICAjIFJlZm9ybWF0IHRoZSBjaHJvbW9zb21lIHZhcmlhYmxlIHRvIGRyb3AgdGhlICJjaHIiCiAgICBkcGx5cjo6bXV0YXRlKGNocm9tID0gZmFjdG9yKGdzdWIoImNociIsICIiLCBjaHJvbSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKDE6MjIsICJYIiwgIlkiKSkpICU+JQogICAgIyBPbmx5IGxvb2sgYXQgY2hyMTkgaW4gdGhlIHJlbGV2YW50IHNhbXBsZQogICAgZmlsdGVyKElEID09IGJpb3NwZWNpbWVuX2lkLAogICAgICAgICAgIGNocm9tID09IDE5KSAlPiUKICAgICMgTWFrZSBEZWwvQW1wIHZhcmlhYmxlCiAgICBkcGx5cjo6bXV0YXRlKFR5cGUgPSBkcGx5cjo6Y2FzZV93aGVuKAogICAgICBzZWcubWVhbiA8IDAgfiAiRGVsIiwKICAgICAgc2VnLm1lYW4gPiAwIH4gIkFtcCIsCiAgICAgIHNlZy5tZWFuID09IDAgfiAiTmV1dHJhbCIKICAgICkpCiAgCiAgIyBUdXJuIGludG8gYSBHUmFuZ2VzIGZvciBlYXNpZXIgbWFwcGluZwogIGJzaWRfcmFuZ2VzIDwtIEdlbm9taWNSYW5nZXM6OkdSYW5nZXMoCiAgICBzZXFuYW1lcyA9IGJzaWRfZGF0YSRjaHJvbSwKICAgIHJhbmdlcyA9IElSYW5nZXM6OklSYW5nZXMoCiAgICAgIHN0YXJ0ID0gYnNpZF9kYXRhJGxvYy5zdGFydCwKICAgICAgZW5kID0gYnNpZF9kYXRhJGxvYy5lbmQKICAgICksCiAgICBzY29yZSA9IGJzaWRfZGF0YSRzZWcubWVhbiwKICAgIG1jb2xzID0gYnNpZF9kYXRhJFR5cGUKICApCiAgCiAgIyBNYXAgdGhpcyBvbiBhIHBsb3QKICBic2lkX3Bsb3QgPC0gCiAgICBnZ2Jpbzo6YXV0b3Bsb3QoYnNpZF9yYW5nZXMsCiAgICAgICAgICAgICAgICAgICAgZ2dwbG90Mjo6YWVzKHkgPSBzY29yZSwgZmlsbCA9IG1jb2xzKSwKICAgICAgICAgICAgICAgICAgICBnZW9tID0gImJhciIpICsKICAgIGdncGxvdDI6OnRoZW1lX2J3KCkgKwogICAgZ2dwbG90Mjo6eWxpbShjKC0yLCAyKSkgKwogICAgY29sb3JibGluZHI6OnNjYWxlX2ZpbGxfT2thYmVJdG8obmFtZSA9ICJUeXBlIikgKwogICAgZ2dwbG90Mjo6bGFicygKICAgICAgdGl0bGUgPSBwYXN0ZShiaW9zcGVjaW1lbl9pZCwgImNocjE5IiksCiAgICAgIHkgPSAic2VnbWVudCBtZWFuIgogICAgKQogIAogIHJldHVybihic2lkX3Bsb3QpCn0KYGBgCgojIyMgRGlyZWN0b3JpZXMKCmBgYHtyfQpyZXN1bHRzX2RpciA8LSAicmVzdWx0cyIKZGF0YV9kaXIgPC0gZmlsZS5wYXRoKCIuLiIsICIuLiIsICJkYXRhIikKYGBgCgojIyMgUmVhZCBpbiBGaWxlcwoKYGBge3IgbWVzc2FnZT1GQUxTRX0KIyBmdWxsIGNsaW5pY2FsIGZpbGUKaGlzdG9sb2dpZXNfZmlsZSA8LSBmaWxlLnBhdGgoZGF0YV9kaXIsICJwYnRhLWhpc3RvbG9naWVzLnRzdiIpCmhpc3RvbG9naWVzX2RmIDwtIHJlYWRfdHN2KGhpc3RvbG9naWVzX2ZpbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbF90eXBlcyA9IGNvbHMoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9sZWN1bGFyX3N1YnR5cGUgPSBjb2xfY2hhcmFjdGVyKCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgKSkKCiMgY29weSBudW1iZXIgY29uc2Vuc3VzIGZpbGUgKGFuYWx5c2lzIGZpbGUpCiMgVE9ETzogZ2V0IHRoaXMgZnJvbSBkYXRhIGRvd25sb2FkCmNuX2NvbnNlbnN1c19zZWcgPC0gZmlsZS5wYXRoKCIuLiIsICJjb3B5X251bWJlcl9jb25zZW5zdXNfY2FsbCIsICJyZXN1bHRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInBidGEtY252LWNvbnNlbnN1cy5zZWcuZ3oiKQojIGZpbGUgdGhhdCBjb250YWlucyB0aGUgYmlvc3BlY2ltZW4gSURzIHRoYXQgbWV0IGNyaXRlcmlhIGZvciBzdWJ0eXBpbmcKYmlvc3BlY2ltZW5fZmlsZSA8LSBmaWxlLnBhdGgocmVzdWx0c19kaXIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYmlvc3BlY2ltZW5faWRzX2VtYnJ5b25hbF9zdWJ0eXBpbmcudHN2IikKCiMgZ2V0IGJpb3NwZWNpbWVuIGlkcyBhcyBhIHZlY3RvciByYXRoZXIgdGhhbiBkYXRhIGZyYW1lCmJpb3NwZWNpbWVuX2lkcyA8LSByZWFkX3RzdihiaW9zcGVjaW1lbl9maWxlKSAlPiUKICBwdWxsKEtpZHNfRmlyc3RfQmlvc3BlY2ltZW5fSUQpCgojIHdlJ2xsIGZpbHRlciB0byBvbmx5IHRoZSByZWxldmFudCBiaW9zcGVjaW1lbnMgZm9yIHRoZSBjb3B5IG51bWJlciBhbHRlcmF0aW9uCiMgZGF0YSB0aGF0IGlzIGNvbW1pdHRlZCB0byB0aGUgcmVwb3NpdG9yeQpjbl9jb25zZW5zdXMgPC0gcmVhZF90c3YoY25fY29uc2Vuc3VzX3NlZykgJT4lCiAgZmlsdGVyKElEICVpbiUgYmlvc3BlY2ltZW5faWRzKQpgYGAKCiMjIyBPdXRwdXQgZmlsZQoKYGBge3J9Cm91dHB1dF9maWxlIDwtIGZpbGUucGF0aChyZXN1bHRzX2RpciwgImNsZWFuZWRfY2hyMTlfY24udHN2IikKYGBgCgojIyBMb29rIGF0IGNvcHkgbnVtYmVyIGFsdGVyYXRpb25zIG9uIGNociAxOQoKV2UncmUgaW50ZXJlc3RlZCBpbiBmb2NhbCBhbXBsaWZpY2F0aW9uIG9mIEMxOU1DIChtaVJOQSBjbHVzdGVyIG9uIGNocjE5KSBmb3IgdGhlICoqRVRNUiwgQzE5TUMtYWx0ZXJlZCoqIHN1YnR5cGUuCgpgYGB7cn0KY2hyMTlfY25fZGYgPC0gY25fY29uc2Vuc3VzICU+JSAKICBmaWx0ZXIoY2hyb20gPT0gImNocjE5IiwKICAgICAgICAgc2VnLm1lYW4gPiAwKQoKY2hyMTlfY25fZGYKYGBgCgpUaGVzZSBhcmUgbm90IHdpdGhpbiB0aGUgcmFuZ2VzIGZyb20gQHNqc3BpZWxtYW4gcHJvdmlkZWQgW2hlcmVdKGh0dHBzOi8vZ2l0aHViLmNvbS9BbGV4c0xlbW9uYWRlL09wZW5QQlRBLWFuYWx5c2lzL3B1bGwvNDAxL2ZpbGVzI2RpZmYtNzdlOTYxNzdmODliOTlhZDJiMWYwZmU1MWVjNWMyMmVSMTEwKToKCmBgYAojIyBGcm9tIFVDU0MgR2Vub21lIEJyb3dlciwgdGhlc2UgYXJlIHBvc2l0aW9ucyBjb3JyZXNwb25kaW5nIHRvIDE5cTEzLjQxIChDMTlNQyByZWdpb24pCmMxOW1jX3JlZ2lvbiA8LSAiMTlxMTMuNDEiCmMxOW1jX3N0YXJ0ICA8LSA1MTQwMDAwMQpjMTltY19lbmQgICAgPC0gNTM2MDAwMDAKYGBgCgpCdXQgdGhleSBkbyBvdmVybGFwIHdpdGggY29vcmRpbmF0ZXMgZnJvbSBvdGhlciBwYXBlcnMuClRoZXNlIGFyZSBmcm9tIEpvIEx5bm5lIFJva2l0YSBpbiBbdGhpcyBjb21tZW50XShodHRwczovL2dpdGh1Yi5jb20vQWxleHNMZW1vbmFkZS9PcGVuUEJUQS1hbmFseXNpcy9wdWxsLzQ1OCNpc3N1ZWNvbW1lbnQtNTgxMDUwMDUxKS4KCkZyb20gW0JlbnR3aWNoIGV0IGFsLiBfTmF0dXJlIEdlbmV0aWNzLl8gMjAwNS5dKGh0dHBzOi8vZG9pLm9yZy8xMC4xMDM4L25nMTU5MCk6Cgo+IENsdXN0ZXIgb24gY2hyb21vc29tZSAxOSBsb2NhdGVkIGF0IHBvc2l0aW9ucyA1OCw4NjEsNzQ14oCTNTgsOTYxLDQwNCAoSEcxNykgYW5kIGNvbXByaXNpbmcgNTQgbWljcm9STkEgZ2VuZXMgZ3JvdXBlZCBpbnRvIGZvdXIgZmFtaWxpZXMgb24gdGhlIGJhc2lzIG9mIGhhaXJwaW4gc2VxdWVuY2Ugc2ltaWxhcml0eS4KCnwgdmVyc2lvbiB8IGNociB8IHN0YXJ0IHwgZW5kIHwKfC0tLS0tLS0tLXwtLS0tLS0tfC0tLS0tLS0tLS18LS0tLS0tLS0tLXwKfCBoZzE3IHwgY2hyMTkgfCA1ODg2MTc0NSB8IDU4OTYxNDA0IHwKfCBoZzE5IHwgY2hyMTkgfCA1NDE2OTkzMyB8IDU0MjY5NTkyIHwKfCBoZzM4IHwgY2hyMTkgfCA1MzY2NjY3OSB8IDUzNzY2MzM4IHwKCmFuZCBmcm9tIFtCb3J0b2xpbi1DYXZhaWxsw6kgZXQgYWwuIF9OQVIuXyAyMDA5Ll0oaHR0cHM6Ly9keC5kb2kub3JnLzEwLjEwOTMlMkZuYXIlMkZna3AyMDUpOgoKPiBTY2hlbWF0aWMgcmVwcmVzZW50YXRpb24gb2YgdGhlIOKIvDEwMC1rYiBsb25nIEMxOU1DIChIRzE4OiA1OOKAiTg2MOKAiTAwMOKAkzU44oCJOTYy4oCJMzAwKSBtYXBwaW5nIGF0IGh1bWFuIGNocm9tb3NvbWUgMTlxMTMuNDEKCnwgdmVyc2lvbiB8IGNociB8IHN0YXJ0IHwgZW5kIHwKfC0tLS0tLS0tLXwtLS0tLS0tfC0tLS0tLS0tLS18LS0tLS0tLS0tLXwKfCBoZzE4IHwgY2hyMTkgfCA1ODg2MDAwMCB8IDU4OTYyMzAwIHwKfCBoZzM4IHwgY2hyMTkgfCA1MzY2NDkzNCB8IDUzNzY3MjM0IHwKCiMjIyBWaXN1YWxpemF0aW9uCgpGb3IgdmlzdWFsaXphdGlvbiBwdXJwb3Nlcywgd2UgYXJlIGZpbGxpbmcgaW4gdGhlIG1pc3NpbmcgYHNlZy5tZWFuYCB2YWx1ZXMgd2l0aCB6ZXJvZXMuCgpgYGB7cn0KcGxvdF9jaHIxOShjbl9kZiA9IGNuX2NvbnNlbnN1cywKICAgICAgICAgICBiaW9zcGVjaW1lbl9pZCA9ICJCU182OVZTOFBTMSIpCmBgYAoKCmBgYHtyfQpwbG90X2NocjE5KGNuX2RmID0gY25fY29uc2Vuc3VzLAogICAgICAgICAgIGJpb3NwZWNpbWVuX2lkID0gIkJTX0swN0tOVEZZIikKYGBgCgpgYGB7cn0KcGxvdF9jaHIxOShjbl9kZiA9IGNuX2NvbnNlbnN1cywKICAgICAgICAgICBiaW9zcGVjaW1lbl9pZCA9ICJCU19URThRRkY3VCIpCmBgYAoKIyMjIEdlbmVyYXRlIGNsZWFuZWQgdGFibGUgZm9yIGpvaW5pbmcgdG8gZnVzaW9uIGFuZCBleHByZXNzaW9uIGRhdGEKClRoZSBjb3B5IG51bWJlcnMgaW4gYWxsIG9mIHRoZSBhYm92ZSBjYXNlcyBhcmUgaGlnaCAtIHdlJ2xsIHNpbXBsaWZ5IHRoZSBjb2x1bW4gbmFtZSB0byBgY2hyMTlfYW1wbGlmaWNhdGlvbmAuCgpgYGB7cn0KIyBnZXQgYSBkYXRhLmZyYW1lIG9mIHRoZSByZWxldmFudCBXR1MgYmlvc3BlY2ltZW5faWRzCndnc19pZHMgPC0gaW50ZXJzZWN0KGhpc3RvbG9naWVzX2RmICU+JQogICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcihleHBlcmltZW50YWxfc3RyYXRlZ3kgPT0gIldHUyIpICU+JQogICAgICAgICAgICAgICAgICAgICAgIHB1bGwoS2lkc19GaXJzdF9CaW9zcGVjaW1lbl9JRCksCiAgICAgICAgICAgICAgICAgICAgIGJpb3NwZWNpbWVuX2lkcykgJT4lCiAgYXMuZGF0YS5mcmFtZShzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UpICU+JQogIHJlbmFtZShLaWRzX0ZpcnN0X0Jpb3NwZWNpbWVuX0lEID0gIi4iKQogICAgICAgICAgCmNocjE5X2NuX2RmIDwtIGNocjE5X2NuX2RmICU+JQogIG11dGF0ZShjaHIxOV9hbXBsaWZpY2F0aW9uID0gIlllcyIpICU+JQogIHNlbGVjdChJRCwgY2hyMTlfYW1wbGlmaWNhdGlvbikgJT4lCiAgcmlnaHRfam9pbih3Z3NfaWRzLCBieSA9IGMoIklEIiA9ICJLaWRzX0ZpcnN0X0Jpb3NwZWNpbWVuX0lEIikpICU+JQogIHJlcGxhY2UoaXMubmEoLiksICJObyIpCmBgYAoKV3JpdGUgdG8gZmlsZS4KCmBgYHtyfQpjaHIxOV9jbl9kZiAlPiUgCiAgcmVuYW1lKEtpZHNfRmlyc3RfQmlvc3BlY2ltZW5fSUQgPSBJRCkgJT4lCiAgd3JpdGVfdHN2KG91dHB1dF9maWxlKQpgYGAKCg==