Load packages

suppressMessages(library(emo))

Directories and Files

Directories

# Data directory
new_data_dir <- file.path("~/Documents/GitHub/jharenza.github.io/openPBTA-notebooks/V17-histologies-QC/data/")
pbta_data_dir <- file.path("~/OpenPBTA-analysis/data/release-v16-20200320/")

Input Filepaths

pbta_hist_file <- file.path(pbta_data_dir, "pbta-histologies.tsv")
v17_hist_file <- file.path(new_data_dir, "Open PBTA v17 Candidate - v2.tsv")

Read in files

v16_hist <- read.delim(pbta_hist_file, sep = "\t", header = T)
v17_hist <- read.delim(v17_hist_file, sep = "\t", header = T)

First, assess dimensions whether new column names match the old

New columns: pathology_free_text_diagnosis and cohort_participant_id and glioma_brain_region -> CNS_region ✅

dim(v16_hist)
[1] 2833   33
dim(v17_hist)
[1] 2833   35
setdiff(names(v16_hist), names(v17_hist))
[1] "glioma_brain_region"
setdiff(names(v17_hist), names(v16_hist))
[1] "CNS_region"                    "pathology_free_text_diagnosis" "cohort_participant_id"        

Check levels of histology columns

These levels look as expected ✅

as.data.frame(table(v17_hist$pathology_diagnosis))
as.data.frame(table(v17_hist$integrated_diagnosis))
as.data.frame(table(v17_hist$broad_histology))
as.data.frame(table(v17_hist$short_histology))

Check tables from v16 -> v17 for fields not expected to change (quick overview)

Experimental strategy ✅

table(v16_hist$experimental_strategy)

  Panel RNA-Seq     WGS     WXS 
      2    1028    1741      62 
table(v17_hist$experimental_strategy)

  Panel RNA-Seq     WGS     WXS 
      2    1028    1741      62 

Sample Type ✅

table(v16_hist$sample_type)

Normal  Tumor 
   833   2000 
table(v17_hist$sample_type)

Normal  Tumor 
   833   2000 

Composition ✅

as.data.frame(table(v16_hist$composition))
as.data.frame(table(v17_hist$composition))

Broad composition ✅

as.data.frame(table(v16_hist$broad_composition))
as.data.frame(table(v17_hist$broad_composition))

Germline sex estimate ✅

as.data.frame(table(v16_hist$germline_sex_estimate))
as.data.frame(table(v17_hist$germline_sex_estimate))

RNA library ✅

as.data.frame(table(v16_hist$RNA_library))
as.data.frame(table(v17_hist$RNA_library))

Cohort ✅

as.data.frame(table(v16_hist$cohort))
as.data.frame(table(v17_hist$cohort))

Sample and aliquot IDs ❌ - Aliquot ID for PNOC003 BS_MVYA262V sample 7316-3213 was changed from A05265 to A05233. Is this correct? ❗

setdiff(v16_hist[, c("Kids_First_Biospecimen_ID", "sample_id", "aliquot_id", "cohort")],
        v17_hist[, c("Kids_First_Biospecimen_ID", "sample_id", "aliquot_id", "cohort")])
setdiff(v17_hist[, c("Kids_First_Biospecimen_ID", "sample_id", "aliquot_id", "cohort")],
        v16_hist[, c("Kids_First_Biospecimen_ID", "sample_id", "aliquot_id", "cohort")])

Sequencing Center - looks like BS_QB84TBA3 and BS_S2TA8R29 previously NA were updated to NantOmics. Is this correct? ❗

as.data.frame(table(v16_hist$seq_center))
as.data.frame(table(v17_hist$seq_center))
setdiff(v16_hist[, c("Kids_First_Biospecimen_ID", "seq_center")],
        v17_hist[, c("Kids_First_Biospecimen_ID", "seq_center")])
setdiff(v17_hist[, c("Kids_First_Biospecimen_ID", "seq_center")],
        v16_hist[, c("Kids_First_Biospecimen_ID", "seq_center")])

Tumor/Normal Fraction and Ploidy ✅

setdiff(v16_hist[, c("Kids_First_Biospecimen_ID", "normal_fraction", "tumor_fraction", "tumor_ploidy")],
        v17_hist[, c("Kids_First_Biospecimen_ID", "normal_fraction", "tumor_fraction", "tumor_ploidy")])
setdiff(v17_hist[, c("Kids_First_Biospecimen_ID", "normal_fraction", "tumor_fraction", "tumor_ploidy")],
        v16_hist[, c("Kids_First_Biospecimen_ID", "normal_fraction", "tumor_fraction", "tumor_ploidy")]) 

Tumor Descriptor ❌

as.data.frame(table(v16_hist$tumor_descriptor))
sum(as.data.frame(table(v16_hist$tumor_descriptor))$Freq)
[1] 2000
as.data.frame(table(v17_hist$tumor_descriptor))
sum(as.data.frame(table(v17_hist$tumor_descriptor))$Freq)
[1] 2000

Which are the samples that have had Tumor Descriptor changes?

105 samples, mostly CBTTC - Seems like a lot, but could be reasonable with the refresh. Is this correct? ❗

setdiff(v17_hist[,c("Kids_First_Biospecimen_ID", "tumor_descriptor", "cohort")], v16_hist[,c("Kids_First_Biospecimen_ID", "tumor_descriptor", "cohort")])

Did new subtypes get captured?

Went from 493 to 1015 subtypes, BRAF subtypes look to be updated, LGG subtypes added. ✅

as.data.frame(table(v16_hist$molecular_subtype))
sum(as.data.frame(table(v16_hist$molecular_subtype))$Freq)
[1] 493
as.data.frame(table(v17_hist$molecular_subtype))
sum(as.data.frame(table(v17_hist$molecular_subtype))$Freq)
[1] 1015

How many biospecimen pathology diagnoses were changed?

33

setdiff(v17_hist[,c("Kids_First_Biospecimen_ID", "pathology_diagnosis", "cohort")], v16_hist[,c("Kids_First_Biospecimen_ID", "pathology_diagnosis", "cohort")])
Column `pathology_diagnosis` joining factors with different levels, coercing to character vector
# Add to df
path_diff <- as.data.frame(setdiff(v17_hist[,c("Kids_First_Biospecimen_ID", "pathology_diagnosis", "cohort")], v16_hist[,c("Kids_First_Biospecimen_ID", "pathology_diagnosis", "cohort")]))
Column `pathology_diagnosis` joining factors with different levels, coercing to character vector
# How many per cohort?
table(path_diff$cohort)

  CBTTC PNOC003 
     12      21 

Are the integrated_diagnosis, broad_histology, and short_histology NA for these samples? Looks like yes for CBTTC, but no for PNOC0003 ❗

v17_hist[v17_hist$Kids_First_Biospecimen_ID %in% path_diff$Kids_First_Biospecimen_ID,c("Kids_First_Biospecimen_ID", "pathology_diagnosis", "integrated_diagnosis", "broad_histology", "short_histology", "cohort")]

Note: For consistency of the process, we could make these NA for the PNOC003 samples for which pathology_diagnosis changed, however, the argument against this could be that we know all PNOC003 samples are DMGs and thus would not have integrated_diagnosis, broad_histology, and short_histology changes, so keeping these values and subtyping them from those values would be fine.

LS0tCnRpdGxlOiAiVjE3IE9wZW5QQlRBIEhpc3RvbG9naWVzIEZpbGUgUUMiCm91dHB1dDogaHRtbF9ub3RlYm9vayAgICAKdG9jOiBUUlVFCnRvY19mbG9hdDogVFJVRQplZGl0b3Jfb3B0aW9uczogCiAgY2h1bmtfb3V0cHV0X3R5cGU6IGlubGluZQotLS0KYGBge3IgZ2xvYmFsX29wdGlvbnMsIGluY2x1ZGU9Rn0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVycm9yID0gRiwgZWNobyA9IFQsIHdhcm5pbmcgPSBULCBtZXNzYWdlID0gVCkKYGBgCgoKIyBMb2FkIHBhY2thZ2VzCmBgYHtyfQpzdXBwcmVzc01lc3NhZ2VzKGxpYnJhcnkoZW1vKSkKYGBgCgojIERpcmVjdG9yaWVzIGFuZCBGaWxlcwojIyBEaXJlY3RvcmllcwpgYGB7cn0KIyBEYXRhIGRpcmVjdG9yeQpuZXdfZGF0YV9kaXIgPC0gZmlsZS5wYXRoKCJ+L0RvY3VtZW50cy9HaXRIdWIvamhhcmVuemEuZ2l0aHViLmlvL29wZW5QQlRBLW5vdGVib29rcy9WMTctaGlzdG9sb2dpZXMtUUMvZGF0YS8iKQpwYnRhX2RhdGFfZGlyIDwtIGZpbGUucGF0aCgifi9PcGVuUEJUQS1hbmFseXNpcy9kYXRhL3JlbGVhc2UtdjE2LTIwMjAwMzIwLyIpCmBgYAoKIyMgSW5wdXQgRmlsZXBhdGhzCmBgYHtyfQpwYnRhX2hpc3RfZmlsZSA8LSBmaWxlLnBhdGgocGJ0YV9kYXRhX2RpciwgInBidGEtaGlzdG9sb2dpZXMudHN2IikKdjE3X2hpc3RfZmlsZSA8LSBmaWxlLnBhdGgobmV3X2RhdGFfZGlyLCAiT3BlbiBQQlRBIHYxNyBDYW5kaWRhdGUgLSB2Mi50c3YiKQpgYGAKIyMgUmVhZCBpbiBmaWxlcwpgYGB7cn0KdjE2X2hpc3QgPC0gcmVhZC5kZWxpbShwYnRhX2hpc3RfZmlsZSwgc2VwID0gIlx0IiwgaGVhZGVyID0gVCkKdjE3X2hpc3QgPC0gcmVhZC5kZWxpbSh2MTdfaGlzdF9maWxlLCBzZXAgPSAiXHQiLCBoZWFkZXIgPSBUKQpgYGAKIyMgRmlyc3QsIGFzc2VzcyBkaW1lbnNpb25zIHdoZXRoZXIgbmV3IGNvbHVtbiBuYW1lcyBtYXRjaCB0aGUgb2xkCiMjIyMgTmV3IGNvbHVtbnM6IGBwYXRob2xvZ3lfZnJlZV90ZXh0X2RpYWdub3Npc2AgYW5kIGBjb2hvcnRfcGFydGljaXBhbnRfaWRgIGFuZCBgZ2xpb21hX2JyYWluX3JlZ2lvbmAgLT4gYENOU19yZWdpb25gIGByIGVtbzo6amkoIndoaXRlX2NoZWNrX21hcmsiKWAKYGBge3J9CmRpbSh2MTZfaGlzdCkKZGltKHYxN19oaXN0KQpzZXRkaWZmKG5hbWVzKHYxNl9oaXN0KSwgbmFtZXModjE3X2hpc3QpKQpzZXRkaWZmKG5hbWVzKHYxN19oaXN0KSwgbmFtZXModjE2X2hpc3QpKQpgYGAKIyMgQ2hlY2sgbGV2ZWxzIG9mIGhpc3RvbG9neSBjb2x1bW5zCiMjIyMgVGhlc2UgbGV2ZWxzIGxvb2sgYXMgZXhwZWN0ZWQgYHIgZW1vOjpqaSgid2hpdGVfY2hlY2tfbWFyayIpYApgYGB7cn0KYXMuZGF0YS5mcmFtZSh0YWJsZSh2MTdfaGlzdCRwYXRob2xvZ3lfZGlhZ25vc2lzKSkKYXMuZGF0YS5mcmFtZSh0YWJsZSh2MTdfaGlzdCRpbnRlZ3JhdGVkX2RpYWdub3NpcykpCmFzLmRhdGEuZnJhbWUodGFibGUodjE3X2hpc3QkYnJvYWRfaGlzdG9sb2d5KSkKYXMuZGF0YS5mcmFtZSh0YWJsZSh2MTdfaGlzdCRzaG9ydF9oaXN0b2xvZ3kpKQpgYGAKIyMgQ2hlY2sgdGFibGVzIGZyb20gdjE2IC0+IHYxNyBmb3IgZmllbGRzIG5vdCBleHBlY3RlZCB0byBjaGFuZ2UgKHF1aWNrIG92ZXJ2aWV3KQojIyMjIEV4cGVyaW1lbnRhbCBzdHJhdGVneSBgciBlbW86OmppKCJ3aGl0ZV9jaGVja19tYXJrIilgCmBgYHtyfQp0YWJsZSh2MTZfaGlzdCRleHBlcmltZW50YWxfc3RyYXRlZ3kpCnRhYmxlKHYxN19oaXN0JGV4cGVyaW1lbnRhbF9zdHJhdGVneSkKYGBgCiMjIyMgU2FtcGxlIFR5cGUgYHIgZW1vOjpqaSgid2hpdGVfY2hlY2tfbWFyayIpYApgYGB7cn0KdGFibGUodjE2X2hpc3Qkc2FtcGxlX3R5cGUpCnRhYmxlKHYxN19oaXN0JHNhbXBsZV90eXBlKQpgYGAKIyMjIyBDb21wb3NpdGlvbiBgciBlbW86OmppKCJ3aGl0ZV9jaGVja19tYXJrIilgCmBgYHtyfQphcy5kYXRhLmZyYW1lKHRhYmxlKHYxNl9oaXN0JGNvbXBvc2l0aW9uKSkKYXMuZGF0YS5mcmFtZSh0YWJsZSh2MTdfaGlzdCRjb21wb3NpdGlvbikpCmBgYAojIyMjIEJyb2FkIGNvbXBvc2l0aW9uIGByIGVtbzo6amkoIndoaXRlX2NoZWNrX21hcmsiKWAKYGBge3J9CmFzLmRhdGEuZnJhbWUodGFibGUodjE2X2hpc3QkYnJvYWRfY29tcG9zaXRpb24pKQphcy5kYXRhLmZyYW1lKHRhYmxlKHYxN19oaXN0JGJyb2FkX2NvbXBvc2l0aW9uKSkKYGBgCiMjIyMgR2VybWxpbmUgc2V4IGVzdGltYXRlIGByIGVtbzo6amkoIndoaXRlX2NoZWNrX21hcmsiKWAKYGBge3J9CmFzLmRhdGEuZnJhbWUodGFibGUodjE2X2hpc3QkZ2VybWxpbmVfc2V4X2VzdGltYXRlKSkKYXMuZGF0YS5mcmFtZSh0YWJsZSh2MTdfaGlzdCRnZXJtbGluZV9zZXhfZXN0aW1hdGUpKQpgYGAKIyMjIyBSTkEgbGlicmFyeSBgciBlbW86OmppKCJ3aGl0ZV9jaGVja19tYXJrIilgCmBgYHtyfQphcy5kYXRhLmZyYW1lKHRhYmxlKHYxNl9oaXN0JFJOQV9saWJyYXJ5KSkKYXMuZGF0YS5mcmFtZSh0YWJsZSh2MTdfaGlzdCRSTkFfbGlicmFyeSkpCmBgYAojIyMjIENvaG9ydCBgciBlbW86OmppKCJ3aGl0ZV9jaGVja19tYXJrIilgCmBgYHtyfQphcy5kYXRhLmZyYW1lKHRhYmxlKHYxNl9oaXN0JGNvaG9ydCkpCmFzLmRhdGEuZnJhbWUodGFibGUodjE3X2hpc3QkY29ob3J0KSkKYGBgCiMjIyMgU2FtcGxlIGFuZCBhbGlxdW90IElEcyBgciBlbW86OmppKCJ4IilgIC0gQWxpcXVvdCBJRCBmb3IgUE5PQzAwMyBgQlNfTVZZQTI2MlZgIHNhbXBsZSBgNzMxNi0zMjEzYCB3YXMgY2hhbmdlZCBmcm9tIGBBMDUyNjVgIHRvIGBBMDUyMzNgLiBJcyB0aGlzIGNvcnJlY3Q/IGByIGVtbzo6amkoImV4Y2xhbWF0aW9uIilgCmBgYHtyfQpzZXRkaWZmKHYxNl9oaXN0WywgYygiS2lkc19GaXJzdF9CaW9zcGVjaW1lbl9JRCIsICJzYW1wbGVfaWQiLCAiYWxpcXVvdF9pZCIsICJjb2hvcnQiKV0sCiAgICAgICAgdjE3X2hpc3RbLCBjKCJLaWRzX0ZpcnN0X0Jpb3NwZWNpbWVuX0lEIiwgInNhbXBsZV9pZCIsICJhbGlxdW90X2lkIiwgImNvaG9ydCIpXSkKc2V0ZGlmZih2MTdfaGlzdFssIGMoIktpZHNfRmlyc3RfQmlvc3BlY2ltZW5fSUQiLCAic2FtcGxlX2lkIiwgImFsaXF1b3RfaWQiLCAiY29ob3J0IildLAogICAgICAgIHYxNl9oaXN0WywgYygiS2lkc19GaXJzdF9CaW9zcGVjaW1lbl9JRCIsICJzYW1wbGVfaWQiLCAiYWxpcXVvdF9pZCIsICJjb2hvcnQiKV0pCmBgYAojIyMjIFNlcXVlbmNpbmcgQ2VudGVyIC0gbG9va3MgbGlrZSBgQlNfUUI4NFRCQTNgIGFuZCBgQlNfUzJUQThSMjlgIHByZXZpb3VzbHkgTkEgd2VyZSB1cGRhdGVkIHRvIGBOYW50T21pY3NgLiBJcyB0aGlzIGNvcnJlY3Q/IGByIGVtbzo6amkoImV4Y2xhbWF0aW9uIilgCmBgYHtyfQphcy5kYXRhLmZyYW1lKHRhYmxlKHYxNl9oaXN0JHNlcV9jZW50ZXIpKQphcy5kYXRhLmZyYW1lKHRhYmxlKHYxN19oaXN0JHNlcV9jZW50ZXIpKQpzZXRkaWZmKHYxNl9oaXN0WywgYygiS2lkc19GaXJzdF9CaW9zcGVjaW1lbl9JRCIsICJzZXFfY2VudGVyIildLAogICAgICAgIHYxN19oaXN0WywgYygiS2lkc19GaXJzdF9CaW9zcGVjaW1lbl9JRCIsICJzZXFfY2VudGVyIildKQpzZXRkaWZmKHYxN19oaXN0WywgYygiS2lkc19GaXJzdF9CaW9zcGVjaW1lbl9JRCIsICJzZXFfY2VudGVyIildLAogICAgICAgIHYxNl9oaXN0WywgYygiS2lkc19GaXJzdF9CaW9zcGVjaW1lbl9JRCIsICJzZXFfY2VudGVyIildKQpgYGAKIyMjIyBUdW1vci9Ob3JtYWwgRnJhY3Rpb24gYW5kIFBsb2lkeSBgciBlbW86OmppKCJ3aGl0ZV9jaGVja19tYXJrIilgCmBgYHtyfQpzZXRkaWZmKHYxNl9oaXN0WywgYygiS2lkc19GaXJzdF9CaW9zcGVjaW1lbl9JRCIsICJub3JtYWxfZnJhY3Rpb24iLCAidHVtb3JfZnJhY3Rpb24iLCAidHVtb3JfcGxvaWR5IildLAogICAgICAgIHYxN19oaXN0WywgYygiS2lkc19GaXJzdF9CaW9zcGVjaW1lbl9JRCIsICJub3JtYWxfZnJhY3Rpb24iLCAidHVtb3JfZnJhY3Rpb24iLCAidHVtb3JfcGxvaWR5IildKQpzZXRkaWZmKHYxN19oaXN0WywgYygiS2lkc19GaXJzdF9CaW9zcGVjaW1lbl9JRCIsICJub3JtYWxfZnJhY3Rpb24iLCAidHVtb3JfZnJhY3Rpb24iLCAidHVtb3JfcGxvaWR5IildLAogICAgICAgIHYxNl9oaXN0WywgYygiS2lkc19GaXJzdF9CaW9zcGVjaW1lbl9JRCIsICJub3JtYWxfZnJhY3Rpb24iLCAidHVtb3JfZnJhY3Rpb24iLCAidHVtb3JfcGxvaWR5IildKSAKYGBgCiMjIyMgVHVtb3IgRGVzY3JpcHRvciBgciBlbW86OmppKCJ4IilgCmBgYHtyfQphcy5kYXRhLmZyYW1lKHRhYmxlKHYxNl9oaXN0JHR1bW9yX2Rlc2NyaXB0b3IpKQpzdW0oYXMuZGF0YS5mcmFtZSh0YWJsZSh2MTZfaGlzdCR0dW1vcl9kZXNjcmlwdG9yKSkkRnJlcSkKYXMuZGF0YS5mcmFtZSh0YWJsZSh2MTdfaGlzdCR0dW1vcl9kZXNjcmlwdG9yKSkKc3VtKGFzLmRhdGEuZnJhbWUodGFibGUodjE3X2hpc3QkdHVtb3JfZGVzY3JpcHRvcikpJEZyZXEpCmBgYAojIyBXaGljaCBhcmUgdGhlIHNhbXBsZXMgdGhhdCBoYXZlIGhhZCBUdW1vciBEZXNjcmlwdG9yIGNoYW5nZXM/CiMjIyMgMTA1IHNhbXBsZXMsIG1vc3RseSBDQlRUQyAtIFNlZW1zIGxpa2UgYSBsb3QsIGJ1dCBjb3VsZCBiZSByZWFzb25hYmxlIHdpdGggdGhlIHJlZnJlc2guIElzIHRoaXMgY29ycmVjdD8gYHIgZW1vOjpqaSgiZXhjbGFtYXRpb24iKWAKYGBge3J9CnNldGRpZmYodjE3X2hpc3RbLGMoIktpZHNfRmlyc3RfQmlvc3BlY2ltZW5fSUQiLCAidHVtb3JfZGVzY3JpcHRvciIsICJjb2hvcnQiKV0sIHYxNl9oaXN0WyxjKCJLaWRzX0ZpcnN0X0Jpb3NwZWNpbWVuX0lEIiwgInR1bW9yX2Rlc2NyaXB0b3IiLCAiY29ob3J0IildKQpgYGAKIyMgRGlkIG5ldyBzdWJ0eXBlcyBnZXQgY2FwdHVyZWQ/CiMjIyMgV2VudCBmcm9tIDQ5MyB0byAxMDE1IHN1YnR5cGVzLCBgQlJBRmAgc3VidHlwZXMgbG9vayB0byBiZSB1cGRhdGVkLCBMR0cgc3VidHlwZXMgYWRkZWQuIGByIGVtbzo6amkoIndoaXRlX2NoZWNrX21hcmsiKWAKYGBge3J9CmFzLmRhdGEuZnJhbWUodGFibGUodjE2X2hpc3QkbW9sZWN1bGFyX3N1YnR5cGUpKQpzdW0oYXMuZGF0YS5mcmFtZSh0YWJsZSh2MTZfaGlzdCRtb2xlY3VsYXJfc3VidHlwZSkpJEZyZXEpCmFzLmRhdGEuZnJhbWUodGFibGUodjE3X2hpc3QkbW9sZWN1bGFyX3N1YnR5cGUpKQpzdW0oYXMuZGF0YS5mcmFtZSh0YWJsZSh2MTdfaGlzdCRtb2xlY3VsYXJfc3VidHlwZSkpJEZyZXEpCmBgYAojIyBIb3cgbWFueSBiaW9zcGVjaW1lbiBwYXRob2xvZ3kgZGlhZ25vc2VzIHdlcmUgY2hhbmdlZD8KIyMjIyAzMwpgYGB7cn0Kc2V0ZGlmZih2MTdfaGlzdFssYygiS2lkc19GaXJzdF9CaW9zcGVjaW1lbl9JRCIsICJwYXRob2xvZ3lfZGlhZ25vc2lzIiwgImNvaG9ydCIpXSwgdjE2X2hpc3RbLGMoIktpZHNfRmlyc3RfQmlvc3BlY2ltZW5fSUQiLCAicGF0aG9sb2d5X2RpYWdub3NpcyIsICJjb2hvcnQiKV0pCiMgQWRkIHRvIGRmCnBhdGhfZGlmZiA8LSBhcy5kYXRhLmZyYW1lKHNldGRpZmYodjE3X2hpc3RbLGMoIktpZHNfRmlyc3RfQmlvc3BlY2ltZW5fSUQiLCAicGF0aG9sb2d5X2RpYWdub3NpcyIsICJjb2hvcnQiKV0sIHYxNl9oaXN0WyxjKCJLaWRzX0ZpcnN0X0Jpb3NwZWNpbWVuX0lEIiwgInBhdGhvbG9neV9kaWFnbm9zaXMiLCAiY29ob3J0IildKSkKIyBIb3cgbWFueSBwZXIgY29ob3J0Pwp0YWJsZShwYXRoX2RpZmYkY29ob3J0KQpgYGAKIyMjIyBBcmUgdGhlIGBpbnRlZ3JhdGVkX2RpYWdub3Npc2AsIGBicm9hZF9oaXN0b2xvZ3lgLCBhbmQgYHNob3J0X2hpc3RvbG9neWAgTkEgZm9yIHRoZXNlIHNhbXBsZXM/IExvb2tzIGxpa2UgeWVzIGZvciBDQlRUQywgYnV0IG5vIGZvciBQTk9DMDAwMyBgciBlbW86OmppKCJleGNsYW1hdGlvbiIpYApgYGB7cn0KdjE3X2hpc3RbdjE3X2hpc3QkS2lkc19GaXJzdF9CaW9zcGVjaW1lbl9JRCAlaW4lIHBhdGhfZGlmZiRLaWRzX0ZpcnN0X0Jpb3NwZWNpbWVuX0lELGMoIktpZHNfRmlyc3RfQmlvc3BlY2ltZW5fSUQiLCAicGF0aG9sb2d5X2RpYWdub3NpcyIsICJpbnRlZ3JhdGVkX2RpYWdub3NpcyIsICJicm9hZF9oaXN0b2xvZ3kiLCAic2hvcnRfaGlzdG9sb2d5IiwgImNvaG9ydCIpXQpgYGAKIyMjIyBOb3RlOiBGb3IgY29uc2lzdGVuY3kgb2YgdGhlIHByb2Nlc3MsIHdlIGNvdWxkIG1ha2UgdGhlc2UgTkEgZm9yIHRoZSBQTk9DMDAzIHNhbXBsZXMgZm9yIHdoaWNoIGBwYXRob2xvZ3lfZGlhZ25vc2lzYCBjaGFuZ2VkLCBob3dldmVyLCB0aGUgYXJndW1lbnQgYWdhaW5zdCB0aGlzIGNvdWxkIGJlIHRoYXQgd2Uga25vdyBhbGwgUE5PQzAwMyBzYW1wbGVzIGFyZSBETUdzIGFuZCB0aHVzIHdvdWxkIG5vdCBoYXZlIGBpbnRlZ3JhdGVkX2RpYWdub3Npc2AsIGBicm9hZF9oaXN0b2xvZ3lgLCBhbmQgYHNob3J0X2hpc3RvbG9neWAgY2hhbmdlcywgc28ga2VlcGluZyB0aGVzZSB2YWx1ZXMgYW5kIHN1YnR5cGluZyB0aGVtIGZyb20gdGhvc2UgdmFsdWVzIHdvdWxkIGJlIGZpbmUuCgoKCgoKCgoKCgoKCgoKCgoK