Sequence Quality
Introduction
We will use two sets of Bone Marrow Mononuclear Cells (BMMC):
- ‘CaronBourque2020’: pediatric samples
- ‘Hca’: HCA Census of Immune Cells for adult BMMCs
Fastq files were retrieved from publicly available archive (SRA and HCA).
Sequencing quality was assessed and visualised using fastQC and MultiQC.
Library structure reminder:
- The sample index identifies the library, with one I7 index per sample
- The 10X cell barcode (or cell index) identifies the droplet in the library
- The UMI identifies the transcript molecule within a cell and gene
- The insert is the transcript molecule, ie the cDNA sequence
Each sample is described with three sets of fastq files:
- I1: sample index
- R1: 10x barcode + UMI
- R2: insert sequence
The sample index is actually a set of four 8-ntd oligo. For example SIGAB8 is ‘AAAGTGCT-GCTACCTG-TGCTGTAA-CTGCAAGC’. All four are used and identified by a digit, eg 1-4. Depending on the processing pipeline, fastq files may be returned for each 8-ntd index, or combined into a single file.
For the Caron data set they are combined in a single file, and files for separate lanes were also combined into a single fastq file.
Each sample is identified by three fastq files, one per read type:
- sample _ S0 _ L001 _ I1 _ 001 _ .fastq.gz: contains sample index
- sample _ S0 _ L001 _ R1 _ 001 _ .fastq.gz: contains 10x barcode + UMI
- sample _ S0 _ L001 _ R2 _ 001 _ .fastq.gz: contains insert sequence
We kept the same names for the fastqc output. With for example sample ‘SRR9264343’:
- SRR9264343 _ S0 _ L001 _ I1 _ 001 _ fastqc.html
- SRR9264343 _ S0 _ L001 _ R1 _ 001 _ fastqc.html
- SRR9264343 _ S0 _ L001 _ R2 _ 001 _ fastqc.html
#wrkDir <- "/mnt/scratchb/bioinformatics/baller01/20200511_FernandesM_ME_crukBiSs2020/CaronBourque2020/grch38300"
#setwd(wrkDir)
outDirBit <- "AnaWiSeurat/Attempt1" # params$outDirBit # "AnaWiSeurat/Attempt1"
fastqcDir <- sprintf("%s/Data/%s/fastqc", projDir, "CaronBourque2020")
#fastqcDirOsx <- sprintf("%s/Data/%s/fastqc", projDirOsx, "CaronBourque2020")
CaronBourque2020 - fastqc
Sample sheet:
# CaronBourque2020
cb_sampleSheetFn <- file.path(projDir, "Data/CaronBourque2020/SraRunTable.txt")
cb_sampleSheet <- read.table(cb_sampleSheetFn, header=T, sep=",")
#cb_sampleSheet <- cb_sampleSheet %>% filter(!Run == "SRR9264351")
cb_sampleSheet
htmlVec <- list.files(fastqcDir)
htmlVec <- grep("\\.html$", htmlVec, value=TRUE)
filesDf <- data.frame(
"I1" = sprintf("%s_S0_L001_%s_001_fastqc.html", cb_sampleSheet$Run, "I1"),
"R1" = sprintf("%s_S0_L001_%s_001_fastqc.html", cb_sampleSheet$Run, "R1"),
"R2" = sprintf("%s_S0_L001_%s_001_fastqc.html", cb_sampleSheet$Run, "R2")
)
rownames(filesDf) <- cb_sampleSheet$Run
for (runx in cb_sampleSheet$Run)
{
cat("Run ", runx, ":\n\n")
for(i in c("I1", "R1", "R2"))
{
filepath <- file.path(fastqcDir, filesDf[runx,i])
cat(i, ": [", filesDf[runx,i], "](",filepath,")\n\n")
}
}
Links to reports (on the student machine):
Run SRR9264343 :
I1 : SRR9264343_S0_L001_I1_001_fastqc.html
R1 : SRR9264343_S0_L001_R1_001_fastqc.html
R2 : SRR9264343_S0_L001_R2_001_fastqc.html
Run SRR9264344 :
I1 : SRR9264344_S0_L001_I1_001_fastqc.html
R1 : SRR9264344_S0_L001_R1_001_fastqc.html
R2 : SRR9264344_S0_L001_R2_001_fastqc.html
Run SRR9264345 :
I1 : SRR9264345_S0_L001_I1_001_fastqc.html
R1 : SRR9264345_S0_L001_R1_001_fastqc.html
R2 : SRR9264345_S0_L001_R2_001_fastqc.html
Run SRR9264346 :
I1 : SRR9264346_S0_L001_I1_001_fastqc.html
R1 : SRR9264346_S0_L001_R1_001_fastqc.html
R2 : SRR9264346_S0_L001_R2_001_fastqc.html
Run SRR9264347 :
I1 : SRR9264347_S0_L001_I1_001_fastqc.html
R1 : SRR9264347_S0_L001_R1_001_fastqc.html
R2 : SRR9264347_S0_L001_R2_001_fastqc.html
Run SRR9264348 :
I1 : SRR9264348_S0_L001_I1_001_fastqc.html
R1 : SRR9264348_S0_L001_R1_001_fastqc.html
R2 : SRR9264348_S0_L001_R2_001_fastqc.html
Run SRR9264349 :
I1 : SRR9264349_S0_L001_I1_001_fastqc.html
R1 : SRR9264349_S0_L001_R1_001_fastqc.html
R2 : SRR9264349_S0_L001_R2_001_fastqc.html
Run SRR9264350 :
I1 : SRR9264350_S0_L001_I1_001_fastqc.html
R1 : SRR9264350_S0_L001_R1_001_fastqc.html
R2 : SRR9264350_S0_L001_R2_001_fastqc.html
Run SRR9264351 :
I1 : SRR9264351_S0_L001_I1_001_fastqc.html
R1 : SRR9264351_S0_L001_R1_001_fastqc.html
R2 : SRR9264351_S0_L001_R2_001_fastqc.html
Run SRR9264352 :
I1 : SRR9264352_S0_L001_I1_001_fastqc.html
R1 : SRR9264352_S0_L001_R1_001_fastqc.html
R2 : SRR9264352_S0_L001_R2_001_fastqc.html
Run SRR9264353 :
I1 : SRR9264353_S0_L001_I1_001_fastqc.html
R1 : SRR9264353_S0_L001_R1_001_fastqc.html
R2 : SRR9264353_S0_L001_R2_001_fastqc.html
Run SRR9264354 :
I1 : SRR9264354_S0_L001_I1_001_fastqc.html
R1 : SRR9264354_S0_L001_R1_001_fastqc.html
R2 : SRR9264354_S0_L001_R2_001_fastqc.html
CaronBourque2020 - MultiQC
sample index: I1
htmlVec <- list.files(paste0(fastqcDir, "/Multiqc/I1"))
htmlVec <- grep("\\.html$", htmlVec, value=TRUE)
for(i in htmlVec){
filename <- file.path(fastqcDir, "/Multiqc/I1", i)
cat("[", i, "](",filename,")\n\n")
}
multiqc_report.html
cell barcode + UMI: R1
htmlVec <- list.files(paste0(fastqcDir, "/Multiqc/R1"))
htmlVec <- grep("\\.html$", htmlVec, value=TRUE)
for(i in htmlVec){
filename <- file.path(fastqcDir, "/Multiqc/R1", i)
cat("[", i, "](",filename,")\n\n")
}
multiqc_report.html
insert: R2
htmlVec <- list.files(paste0(fastqcDir, "/Multiqc/R2"))
htmlVec <- grep("\\.html$", htmlVec, value=TRUE)
for(i in htmlVec){
filename <- file.path(fastqcDir, "/Multiqc/R2", i)
cat("[", i, "](",filename,")\n\n")
}
multiqc_report.html
HCA adult BMMC - fastqc
For the HCA adult BMMC fastq files were provided for each 8-ntd sample index and lane. We ran fastqc on each separately. We are therefore not listing links to the fastqc reports but only to the MultiQC reports.
Sample sheet:
fastqcDir <- sprintf("%s/Data/%s/fastqc", projDir, "Hca")
# HCA
hca_sampleSheetFn <- file.path(projDir, "Data/Hca/accList_Hca.txt")
hca_sampleSheet <- read.table(hca_sampleSheetFn, header=F, sep=",")
colnames(hca_sampleSheet) <- "Run"
hca_sampleSheet
htmlVec <- list.files(fastqcDir)
htmlVec <- grep("\\.html$", htmlVec, value=TRUE)
378 fastqc reports were compiled in the multiQC reports below.
HCA adult BMMC - MultiQC
sample index: I1
htmlVec <- list.files(paste0(fastqcDir, "/Multiqc/I1"))
htmlVec <- grep("\\.html$", htmlVec, value=TRUE)
for(i in htmlVec){
filename <- file.path(fastqcDir, "/Multiqc/I1", i)
cat("[", i, "](",filename,")\n\n")
}
multiqc_report.html
cell barcode + UMI: R1
htmlVec <- list.files(paste0(fastqcDir, "/Multiqc/R1"))
htmlVec <- grep("\\.html$", htmlVec, value=TRUE)
for(i in htmlVec){
filename <- file.path(fastqcDir, "/Multiqc/R1", i)
cat("[", i, "](",filename,")\n\n")
}
multiqc_report.html
insert: R2
htmlVec <- list.files(paste0(fastqcDir, "/Multiqc/R2"))
htmlVec <- grep("\\.html$", htmlVec, value=TRUE)
for(i in htmlVec){
filename <- file.path(fastqcDir, "/Multiqc/R2", i)
cat("[", i, "](",filename,")\n\n")
}
multiqc_report.html
LS0tCnRpdGxlOiAiQ1JVSyBDSSBTdW1tZXIgU2Nob29sIDIwMjAgLSBpbnRyb2R1Y3Rpb24gdG8gc2luZ2xlLWNlbGwgUk5BLXNlcSBhbmFseXNpcyIKc3VidGl0bGU6ICdTZXF1ZW5jZSBxdWFsaXR5JwoKYXV0aG9yOiAiU3RlcGhhbmUgQmFsbGVyZWF1IgpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazoKICAgIGNvZGVfZm9sZGluZzogaGlkZQogICAgdG9jOiB5ZXMKICAgIHRvY19mbG9hdDogeWVzCiAgICBudW1iZXJfc2VjdGlvbnM6IHRydWUKICBodG1sX2RvY3VtZW50OgogICAgZGZfcHJpbnQ6IHBhZ2VkCiAgICB0b2M6IHllcwogICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUKICBodG1sX2Jvb2s6CiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUKcGFyYW1zOgogIG91dERpckJpdDogIkFuYVdpU2NlL0F0dGVtcHQxIgotLS0KCjwhLS0KVE9ETzoKLS0+CgpgYGB7ciBzZXFRdWFsLmtuaXRyX29wdGlvbnMsIGVjaG89RkFMU0UsIHJlc3VsdHM9ImhpZGUiLCBtZXNzYWdlPUZBTFNFfQpyZXF1aXJlKGtuaXRyKQojb3B0c19jaHVuayRzZXQoZXJyb3I9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGNhY2hlPVRSVUUpCm9wdHNfY2h1bmskc2V0KGVycm9yPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBjYWNoZT1GQUxTRSkKb3B0c19jaHVuayRzZXQoZmlnLndpZHRoPTcsIGZpZy5oZWlnaHQ9NykgCmBgYAoKYGBge3J9CiNwcm9qRGlyT3N4IDwtICIvVXNlcnMvYmFsbGVyMDEvTXlNb3VudC9jbHVzdDFhLzIwMjAwNTExX0Zlcm5hbmRlc01fTUVfY3J1a0JpU3MyMDIwIgojcHJvakRpciA8LSAiL21udC9zY3JhdGNoYS9iaW9pbmZvcm1hdGljcy9iYWxsZXIwMS8yMDIwMDUxMV9GZXJuYW5kZXNNX01FX2NydWtCaVNzMjAyMCIKcHJvakRpciA8LSAiL2hvbWUvdWJ1bnR1L0NvdXJzZV9NYXRlcmlhbHMvc2NSTkFzZXEiCm91dERpckJpdCA8LSAiQW5hV2lTY2UvQXR0ZW1wdDEiCmBgYAoKYGBge3J9CmxpYnJhcnkoRFQpCmBgYAoKIyBTZXF1ZW5jZSBRdWFsaXR5IHsjU2VxUXVhbFRvcH0KCioqV09SS0lORyBET0NVTUVOVCAtIElOIFBST0dSRVNTKioKCiMjIEludHJvZHVjdGlvbgoKV2Ugd2lsbCB1c2UgdHdvIHNldHMgb2YgQm9uZSBNYXJyb3cgTW9ub251Y2xlYXIgQ2VsbHMgKEJNTUMpOgoKKiAnQ2Fyb25Cb3VycXVlMjAyMCc6IHBlZGlhdHJpYyBzYW1wbGVzCiogJ0hjYSc6IEhDQSBDZW5zdXMgb2YgSW1tdW5lIENlbGxzIGZvciBhZHVsdCBCTU1DcwoKRmFzdHEgZmlsZXMgd2VyZSByZXRyaWV2ZWQgZnJvbSBwdWJsaWNseSBhdmFpbGFibGUgYXJjaGl2ZSAoU1JBIGFuZCBIQ0EpLiAKClNlcXVlbmNpbmcgcXVhbGl0eSB3YXMgYXNzZXNzZWQgYW5kIHZpc3VhbGlzZWQgdXNpbmcgZmFzdFFDIGFuZCBNdWx0aVFDLgoKTGlicmFyeSBzdHJ1Y3R1cmUgcmVtaW5kZXI6Cgo8IS0tCiFbXShgciBzcHJpbnRmKCIlcy9JbWFnZXMvdGVueExpYlN0cnVjdHVyZVYzLnBuZyIsIHByb2pEaXIpYCkKLS0+CgoqIFRoZSAqKnNhbXBsZSBpbmRleCoqIGlkZW50aWZpZXMgdGhlIGxpYnJhcnksIHdpdGggb25lIEk3IGluZGV4IHBlciBzYW1wbGUKKiBUaGUgMTBYICoqY2VsbCBiYXJjb2RlKiogKG9yIGNlbGwgaW5kZXgpIGlkZW50aWZpZXMgdGhlIGRyb3BsZXQgaW4gdGhlIGxpYnJhcnkKKiBUaGUgKipVTUkqKiBpZGVudGlmaWVzIHRoZSB0cmFuc2NyaXB0IG1vbGVjdWxlIHdpdGhpbiBhIGNlbGwgYW5kIGdlbmUKKiBUaGUgKippbnNlcnQqKiBpcyB0aGUgdHJhbnNjcmlwdCBtb2xlY3VsZSwgaWUgdGhlIGNETkEgc2VxdWVuY2UKCkVhY2ggc2FtcGxlIGlzIGRlc2NyaWJlZCB3aXRoIHRocmVlIHNldHMgb2YgZmFzdHEgZmlsZXM6CgoqICoqSTEqKjogc2FtcGxlIGluZGV4CiogKipSMSoqOiAxMHggYmFyY29kZSArIFVNSQoqICoqUjIqKjogaW5zZXJ0IHNlcXVlbmNlCgpUaGUgc2FtcGxlIGluZGV4IGlzIGFjdHVhbGx5IGEgc2V0IG9mIGZvdXIgOC1udGQgb2xpZ28uCkZvciBleGFtcGxlIFNJR0FCOCBpcyAnQUFBR1RHQ1QtR0NUQUNDVEctVEdDVEdUQUEtQ1RHQ0FBR0MnLgpBbGwgZm91ciBhcmUgdXNlZCBhbmQgaWRlbnRpZmllZCBieSBhIGRpZ2l0LCBlZyAxLTQuCkRlcGVuZGluZyBvbiB0aGUgcHJvY2Vzc2luZyBwaXBlbGluZSwgZmFzdHEgZmlsZXMgbWF5IGJlIHJldHVybmVkIGZvciBlYWNoIDgtbnRkIGluZGV4LCBvciBjb21iaW5lZCBpbnRvIGEgc2luZ2xlIGZpbGUuCgpGb3IgdGhlIENhcm9uIGRhdGEgc2V0IHRoZXkgYXJlIGNvbWJpbmVkIGluIGEgc2luZ2xlIGZpbGUsIGFuZCBmaWxlcyBmb3Igc2VwYXJhdGUgbGFuZXMgd2VyZSBhbHNvIGNvbWJpbmVkIGludG8gYSBzaW5nbGUgZmFzdHEgZmlsZS4KCkVhY2ggc2FtcGxlIGlzIGlkZW50aWZpZWQgYnkgdGhyZWUgZmFzdHEgZmlsZXMsIG9uZSBwZXIgcmVhZCB0eXBlOgoKKiAqKnNhbXBsZSoqIF8gUzAgXyBMMDAxIF8gKipJMSoqIF8gMDAxIF8gLmZhc3RxLmd6OiBjb250YWlucyBzYW1wbGUgaW5kZXgKKiAqKnNhbXBsZSoqIF8gUzAgXyBMMDAxIF8gKipSMSoqIF8gMDAxIF8gLmZhc3RxLmd6OiBjb250YWlucyAxMHggYmFyY29kZSArIFVNSQoqICoqc2FtcGxlKiogXyBTMCBfIEwwMDEgXyAqKlIyKiogXyAwMDEgXyAuZmFzdHEuZ3o6IGNvbnRhaW5zIGluc2VydCBzZXF1ZW5jZQoKV2Uga2VwdCB0aGUgc2FtZSBuYW1lcyBmb3IgdGhlIGZhc3RxYyBvdXRwdXQuIFdpdGggZm9yIGV4YW1wbGUgc2FtcGxlICdTUlI5MjY0MzQzJzoKCiogKipTUlI5MjY0MzQzKiogXyBTMCBfIEwwMDEgXyAqKkkxKiogXyAwMDEgXyBmYXN0cWMuaHRtbAoqICoqU1JSOTI2NDM0MyoqIF8gUzAgXyBMMDAxIF8gKipSMSoqIF8gMDAxIF8gZmFzdHFjLmh0bWwKKiAqKlNSUjkyNjQzNDMqKiBfIFMwIF8gTDAwMSBfICoqUjIqKiBfIDAwMSBfIGZhc3RxYy5odG1sCgpgYGB7cn0KI3dya0RpciA8LSAiL21udC9zY3JhdGNoYi9iaW9pbmZvcm1hdGljcy9iYWxsZXIwMS8yMDIwMDUxMV9GZXJuYW5kZXNNX01FX2NydWtCaVNzMjAyMC9DYXJvbkJvdXJxdWUyMDIwL2dyY2gzODMwMCIKI3NldHdkKHdya0RpcikKb3V0RGlyQml0IDwtICJBbmFXaVNldXJhdC9BdHRlbXB0MSIgIyBwYXJhbXMkb3V0RGlyQml0ICPCoCJBbmFXaVNldXJhdC9BdHRlbXB0MSIKYGBgCgpgYGB7cn0KZmFzdHFjRGlyIDwtIHNwcmludGYoIiVzL0RhdGEvJXMvZmFzdHFjIiwgcHJvakRpciwgIkNhcm9uQm91cnF1ZTIwMjAiKQojZmFzdHFjRGlyT3N4IDwtIHNwcmludGYoIiVzL0RhdGEvJXMvZmFzdHFjIiwgcHJvakRpck9zeCwgIkNhcm9uQm91cnF1ZTIwMjAiKQpgYGAKCiMjIENhcm9uQm91cnF1ZTIwMjAgLSBmYXN0cWMKCmBgYHtyfQojwqBDYXJvbkJvdXJxdWUyMDIwCmNiX3NhbXBsZVNoZWV0Rm4gPC0gZmlsZS5wYXRoKHByb2pEaXIsICJEYXRhL0Nhcm9uQm91cnF1ZTIwMjAvU3JhUnVuVGFibGUudHh0IikKY2Jfc2FtcGxlU2hlZXQgPC0gcmVhZC50YWJsZShjYl9zYW1wbGVTaGVldEZuLCBoZWFkZXI9VCwgc2VwPSIsIikKI2NiX3NhbXBsZVNoZWV0IDwtICBjYl9zYW1wbGVTaGVldCAlPiUgZmlsdGVyKCFSdW4gPT0gIlNSUjkyNjQzNTEiKQpjYl9zYW1wbGVTaGVldApgYGAKCmBgYHtyLCByZXN1bHRzID0gJ2FzaXMnfQpodG1sVmVjIDwtIGxpc3QuZmlsZXMoZmFzdHFjRGlyKQpodG1sVmVjIDwtIGdyZXAoIlxcLmh0bWwkIiwgaHRtbFZlYywgdmFsdWU9VFJVRSkKYGBgCgpgYGB7cn0KZmlsZXNEZiA8LSBkYXRhLmZyYW1lKAoJCSAgICAgICJJMSIgPSBzcHJpbnRmKCIlc19TMF9MMDAxXyVzXzAwMV9mYXN0cWMuaHRtbCIsIGNiX3NhbXBsZVNoZWV0JFJ1biwgIkkxIiksCgkJICAgICAgIlIxIiA9IHNwcmludGYoIiVzX1MwX0wwMDFfJXNfMDAxX2Zhc3RxYy5odG1sIiwgY2Jfc2FtcGxlU2hlZXQkUnVuLCAiUjEiKSwKCQkgICAgICAiUjIiID0gc3ByaW50ZigiJXNfUzBfTDAwMV8lc18wMDFfZmFzdHFjLmh0bWwiLCBjYl9zYW1wbGVTaGVldCRSdW4sICJSMiIpCikKcm93bmFtZXMoZmlsZXNEZikgPC0gY2Jfc2FtcGxlU2hlZXQkUnVuCmBgYAoKYGBge3IsIHJlc3VsdHMgPSAnYXNpcyd9CmZvciAocnVueCBpbiBjYl9zYW1wbGVTaGVldCRSdW4pCnsKCWNhdCgiUnVuICIsIHJ1bngsICI6XG5cbiIpCglmb3IoaSBpbiBjKCJJMSIsICJSMSIsICJSMiIpKQoJewoJCWZpbGVwYXRoIDwtIGZpbGUucGF0aChmYXN0cWNEaXIsIGZpbGVzRGZbcnVueCxpXSkKCQljYXQoaSwgIjogWyIsIGZpbGVzRGZbcnVueCxpXSwgIl0oIixmaWxlcGF0aCwiKVxuXG4iKQoJfQp9CmBgYAoKIyMgQ2Fyb25Cb3VycXVlMjAyMCAtIE11bHRpUUMKCiMjIyBzYW1wbGUgaW5kZXg6IEkxCgpgYGB7ciwgcmVzdWx0cyA9ICdhc2lzJ30KaHRtbFZlYyA8LSBsaXN0LmZpbGVzKHBhc3RlMChmYXN0cWNEaXIsICIvTXVsdGlxYy9JMSIpKQpodG1sVmVjIDwtIGdyZXAoIlxcLmh0bWwkIiwgaHRtbFZlYywgdmFsdWU9VFJVRSkKZm9yKGkgaW4gaHRtbFZlYyl7CglmaWxlbmFtZSA8LSBmaWxlLnBhdGgoZmFzdHFjRGlyLCAiL011bHRpcWMvSTEiLCBpKQoJY2F0KCJbIiwgaSwgIl0oIixmaWxlbmFtZSwiKVxuXG4iKQp9CmBgYAoKIyMjIGNlbGwgYmFyY29kZSArIFVNSTogUjEKCmBgYHtyLCByZXN1bHRzID0gJ2FzaXMnfQpodG1sVmVjIDwtIGxpc3QuZmlsZXMocGFzdGUwKGZhc3RxY0RpciwgIi9NdWx0aXFjL1IxIikpCmh0bWxWZWMgPC0gZ3JlcCgiXFwuaHRtbCQiLCBodG1sVmVjLCB2YWx1ZT1UUlVFKQpmb3IoaSBpbiBodG1sVmVjKXsKCWZpbGVuYW1lIDwtIGZpbGUucGF0aChmYXN0cWNEaXIsICIvTXVsdGlxYy9SMSIsIGkpCgljYXQoIlsiLCBpLCAiXSgiLGZpbGVuYW1lLCIpXG5cbiIpCn0KYGBgCgojIyMgaW5zZXJ0OiBSMgoKYGBge3IsIHJlc3VsdHMgPSAnYXNpcyd9Cmh0bWxWZWMgPC0gbGlzdC5maWxlcyhwYXN0ZTAoZmFzdHFjRGlyLCAiL011bHRpcWMvUjIiKSkKaHRtbFZlYyA8LSBncmVwKCJcXC5odG1sJCIsIGh0bWxWZWMsIHZhbHVlPVRSVUUpCmZvcihpIGluIGh0bWxWZWMpewoJZmlsZW5hbWUgPC0gZmlsZS5wYXRoKGZhc3RxY0RpciwgIi9NdWx0aXFjL1IyIiwgaSkKCWNhdCgiWyIsIGksICJdKCIsZmlsZW5hbWUsIilcblxuIikKfQpgYGAKCiMjIEhDQSBhZHVsdCBCTU1DIC0gZmFzdHFjCgpGb3IgdGhlIEhDQSBhZHVsdCBCTU1DIGZhc3RxIGZpbGVzIHdlcmUgcHJvdmlkZWQgZm9yIGVhY2ggOC1udGQgc2FtcGxlIGluZGV4IGFuZCBsYW5lLiBXZSByYW4gZmFzdHFjIG9uIGVhY2ggc2VwYXJhdGVseS4gV2UgYXJlIHRoZXJlZm9yZSBub3QgbGlzdGluZyBsaW5rcyB0byB0aGUgZmFzdHFjIHJlcG9ydHMgYnV0IG9ubHkgdG8gdGhlIE11bHRpUUMgcmVwb3J0cy4KCmBgYHtyfQpmYXN0cWNEaXIgPC0gc3ByaW50ZigiJXMvRGF0YS8lcy9mYXN0cWMiLCBwcm9qRGlyLCAiSGNhIikKCiPCoEhDQQpoY2Ffc2FtcGxlU2hlZXRGbiA8LSBmaWxlLnBhdGgocHJvakRpciwgIkRhdGEvSGNhL2FjY0xpc3RfSGNhLnR4dCIpCgpoY2Ffc2FtcGxlU2hlZXQgPC0gcmVhZC50YWJsZShoY2Ffc2FtcGxlU2hlZXRGbiwgaGVhZGVyPUYsIHNlcD0iLCIpCmNvbG5hbWVzKGhjYV9zYW1wbGVTaGVldCkgPC0gIlJ1biIKaGNhX3NhbXBsZVNoZWV0CmBgYAoKYGBge3IsIHJlc3VsdHMgPSAnYXNpcyd9Cmh0bWxWZWMgPC0gbGlzdC5maWxlcyhmYXN0cWNEaXIpCmh0bWxWZWMgPC0gZ3JlcCgiXFwuaHRtbCQiLCBodG1sVmVjLCB2YWx1ZT1UUlVFKQpgYGAKCmByICNsZW5ndGgoaHRtbFZlYylgCjM3OCBmYXN0cWMgcmVwb3J0cyB3ZXJlIGNvbXBpbGVkIGluIHRoZSBtdWx0aVFDIHJlcG9ydHMgYmVsb3cuCgojIyAgSENBIGFkdWx0IEJNTUMgLSBNdWx0aVFDCgojIyMgc2FtcGxlIGluZGV4OiBJMQoKYGBge3IsIHJlc3VsdHMgPSAnYXNpcyd9Cmh0bWxWZWMgPC0gbGlzdC5maWxlcyhwYXN0ZTAoZmFzdHFjRGlyLCAiL011bHRpcWMvSTEiKSkKaHRtbFZlYyA8LSBncmVwKCJcXC5odG1sJCIsIGh0bWxWZWMsIHZhbHVlPVRSVUUpCmZvcihpIGluIGh0bWxWZWMpewoJZmlsZW5hbWUgPC0gZmlsZS5wYXRoKGZhc3RxY0RpciwgIi9NdWx0aXFjL0kxIiwgaSkKCWNhdCgiWyIsIGksICJdKCIsZmlsZW5hbWUsIilcblxuIikKfQpgYGAKCiMjIyBjZWxsIGJhcmNvZGUgKyBVTUk6IFIxCgpgYGB7ciwgcmVzdWx0cyA9ICdhc2lzJ30KaHRtbFZlYyA8LSBsaXN0LmZpbGVzKHBhc3RlMChmYXN0cWNEaXIsICIvTXVsdGlxYy9SMSIpKQpodG1sVmVjIDwtIGdyZXAoIlxcLmh0bWwkIiwgaHRtbFZlYywgdmFsdWU9VFJVRSkKZm9yKGkgaW4gaHRtbFZlYyl7CglmaWxlbmFtZSA8LSBmaWxlLnBhdGgoZmFzdHFjRGlyLCAiL011bHRpcWMvUjEiLCBpKQoJY2F0KCJbIiwgaSwgIl0oIixmaWxlbmFtZSwiKVxuXG4iKQp9CmBgYAoKIyMjIGluc2VydDogUjIKCmBgYHtyLCByZXN1bHRzID0gJ2FzaXMnfQpodG1sVmVjIDwtIGxpc3QuZmlsZXMocGFzdGUwKGZhc3RxY0RpciwgIi9NdWx0aXFjL1IyIikpCmh0bWxWZWMgPC0gZ3JlcCgiXFwuaHRtbCQiLCBodG1sVmVjLCB2YWx1ZT1UUlVFKQpmb3IoaSBpbiBodG1sVmVjKXsKCWZpbGVuYW1lIDwtIGZpbGUucGF0aChmYXN0cWNEaXIsICIvTXVsdGlxYy9SMiIsIGkpCgljYXQoIlsiLCBpLCAiXSgiLGZpbGVuYW1lLCIpXG5cbiIpCn0KYGBgCgoK