1 Quick caveat: This was one of my earliest analyses and it therefore is… bad.

I am therefore doing to bare minimum required to be able to once again glean useful information from it.

last, go back index, next

2 Essentiality

This is run with the following command line and prints out a table of z scores. This requires a file TA_data.txt which in turn comes from a small perl script which reads over the bam files and prints the # of insertions which fall exactly in the correct orientation at each TA position in the genome.

for dir in t0 t1 t2 t3; do
  perl tnseq_TAs.pl -i ../run3/libs/random_1mismatch/lib1_${dir}_sorted.bam 2>${dir}/tnseq_TAs.err 1>${dir}/tnseq_TAs.out
  python gumbelMH.py -f ${dir}/tnseq_TAs.out -m 1 -s 1000 2>${dir}/essentiality.err 1>${dir}/essentiality.out
done

Upon completion, I have 4 directories containing the essentiality.out files. These are copied into data/essentiality/.

3 Load essentiality data

Note I edited the headers of the tables before loading them. They now look like: “Orf t3_k t3_n t3_r t3_s t3_zbar”

t0 = read.table("data/essentiality/old/t0_essentiality.txt", skip=7)
colnames(t0) = c("Orf","t0_k","t0_n","t0_r","t0_s","t0_zbar")
t1 = read.table("data/essentiality/old/t1_essentiality.txt", skip=7)
colnames(t1) = c("Orf","t1_k","t1_n","t1_r","t1_s","t1_zbar")
t2 = read.table("data/essentiality/old/t2_essentiality.txt")
colnames(t2) = c("Orf","t2_k","t2_n","t2_r","t2_s","t2_zbar")
t3 = read.table("data/essentiality/old/t3_essentiality.txt")
colnames(t3) = c("Orf","t3_k","t3_n","t3_r","t3_s","t3_zbar")
essentiality_data = merge(t0, t1, by.x="Orf", by.y="Orf")
essentiality_data = merge(essentiality_data, t2, by.x="Orf", by.y="Orf")
essentiality_data = merge(essentiality_data, t3, by.x="Orf", by.y="Orf")

XLConnect::createSheet(workbook, name="essentiality_all")
XLConnect::writeWorksheet(workbook, essentiality_data, sheet="essentiality_all")
XLConnect::saveWorkbook(workbook)

Yoann asked about a venn diagram of this data. Here are 3 methods, one including a size-weighted which is completely silly because most of the hits are in the intersection of all 3.

t0_essential = t0
t1_essential = t1
t2_essential = t2
t0_essential$answer = ifelse(t0$t0_zbar > 0.99, 1, 0)
t1_essential$answer = ifelse(t1$t1_zbar > 0.99, 1, 0)
t2_essential$answer = ifelse(t2$t2_zbar > 0.99, 1, 0)
t0_essential = t0_essential[, c(1, 7)]
t1_essential = t1_essential[, c(1, 7)]
t2_essential = t2_essential[, c(1, 7)]
rownames(t0_essential) = t0_essential$Orf
##t0_essential = t0_essential[, -1]
rownames(t1_essential) = t1_essential$Orf
##t1_essential = t1_essential[, -1]
rownames(t2_essential) = t2_essential$Orf
##t2_essential = t2_essential[, -1]
essential_results = merge(t0_essential, t1_essential, by='row.names')
rownames(essential_results) = essential_results$Row.names
essential_results = essential_results[,-1]
essential_results = merge(essential_results, t2_essential, by='row.names')
rownames(essential_results) = essential_results$Row.names
essential_results = essential_results[, -1]
essential_results <- essential_results[, c("answer.x", "answer.y", "answer")]
## This is using limma's vennDiagram function
colnames(essential_results) = c("t0", "t1", "t2")
essential_counts = limma::vennCounts(essential_results)
limma::vennDiagram(essential_counts,
                   counts.col = c("blue", "red", "green"))

## I can use that to easily make the variables for the VennDiagram library...

i1 = 1
i2 = 8
i3 = 61
i12 = 1
i13 = 4
i23 = 85
i123 = 230

area1 = i1 + i12 + i13 + i123
area2 = i2 + i12 + i23 + i123
area3 = i3 + i13 + i23 + i123

n123 = i123
n12 = i12 + i123
n13 = i13 + i123
n23 = i23 + i123

test = Vennerable::Venn(SetNames = c("t0","t1","t2"), Weight =
    c('100' = i1, '010' = i2, '001' = i3, ## The loners
      '110' = i12, '011' = i23, '101' = i13,  ## The doubles
      '111' = i123))
Vennerable::plot(test, doWeights = TRUE, type = "circles")

Vennerable::plot(test, doWeights = FALSE, type = "circles")

draw.triple.venn(area1, area2, area3, n12, n23, n13, n123,
                 category = rep("", 3), rotation = 1, reverse = FALSE, euler.d = TRUE,
                 scaled = TRUE, lwd = rep(2, 3), lty = rep("solid", 3),
                 col = rep("black", 3), fill = NULL, alpha = rep(0.5, 3),
                 label.col = rep("black", 7), cex = rep(1, 7), fontface = rep("plain", 7),
                 fontfamily = rep("serif", 7), cat.pos = c(-40, 40, 180),
                 cat.dist = c(0.05, 0.05, 0.025), cat.col = rep("black", 3),
                 cat.cex = rep(1, 3), cat.fontface = rep("plain", 3),
                 cat.fontfamily = rep("serif", 3),
                 cat.just = list(c(0.5, 1), c(0.5, 1), c(0.5, 0)), cat.default.pos = "outer",
                 cat.prompts = FALSE, rotation.degree = 0, rotation.centre = c(0.5, 0.5),
                 ind = TRUE, sep.dist = 0.05, offset = 0)

## (polygon[GRID.polygon.702], polygon[GRID.polygon.703], polygon[GRID.polygon.704], polygon[GRID.polygon.705], polygon[GRID.polygon.706], polygon[GRID.polygon.707], text[GRID.text.708], text[GRID.text.709], text[GRID.text.710], text[GRID.text.711], text[GRID.text.712], text[GRID.text.713], text[GRID.text.714], text[GRID.text.715], text[GRID.text.716], text[GRID.text.717])

4 Repeat for the Alabama and NZ131 strains.

4.1 Add annotation information for Alabama and NZ131 into the excel workbook

4.2 Run essentiality and add the essentiality output to the excel workbook…

I created an alabama directory inside the essentiality directory. It took me a few tries to get it correct, and I had to make some small edits to the perl script tnseq_TAs to accomodate the new strains, but I ran the perlscript in the same fashion. (Caveat: The perl script needs to be able to cross reference the name of the fasta sequence against the bam sequence name. This tripped me up terribly.

Upon completion, I wrote a tiny shell script to run the python essentiality package for each output file.

cd essentiality/alabama/
./README.sh
## This prints out the appropriate command lines for the TNseq_TAs.pl and gumbelMH.py commands.

That completed in some hours, providing the raw outputs from essentiality, which I again edited slightly to include the timepoint values. Let us load them into the excel spreadsheet.

alabama_t0 = read.table("data/essentiality/old/Alab49_t0_essentiality.out", skip=7, header=TRUE)
alabama_t1 = read.table("data/essentiality/old/Alab49_t1_essentiality.out", skip=7, header=TRUE)
alabama_t2 = read.table("data/essentiality/old/Alab49_t2_essentiality.out", skip=7, header=TRUE)
alabama_t3 = read.table("data/essentiality/old/Alab49_t3_essentiality.out", skip=7, header=TRUE)
nz_t0 = read.table("data/essentiality/old/NZ131_t0_essentiality.out", skip=7, header=TRUE)
nz_t1 = read.table("data/essentiality/old/NZ131_t1_essentiality.out", skip=7, header=TRUE)
nz_t2 = read.table("data/essentiality/old/NZ131_t2_essentiality.out", skip=7, header=TRUE)
nz_t3 = read.table("data/essentiality/old/NZ131_t3_essentiality.out", skip=7, header=TRUE)
alabama_essentials = merge(alabama_t0, alabama_t1, by.x="Orf", by.y="Orf")
alabama_essentials = merge(alabama_essentials, alabama_t2, by.x="Orf", by.y="Orf")
alabama_essentials = merge(alabama_essentials, alabama_t3, by.x="Orf", by.y="Orf")
nz_essentials = merge(nz_t0, nz_t1, by.x="Orf", by.y="Orf")
nz_essentials = merge(nz_essentials, nz_t2, by.x="Orf", by.y="Orf")
nz_essentials = merge(nz_essentials, nz_t3, by.x="Orf", by.y="Orf")
head(nz_essentials)
##          Orf t0_k t0_n t0_r t0_s t0_zbar t1_k t1_n t1_r t1_s t1_zbar t2_k
## 1 Spy49_0001    1  105   56  657   1.000   14  105   13  150   0.001    3
## 2 Spy49_0002    2   99   97 1100   1.000    9   99   28  311   1.000    1
## 3 Spy49_0003    3   15    5   73   0.000   12   15    1    2   0.000   12
## 4 Spy49_0004   21   80   11   97   0.001   65   80    2    9   0.000   54
## 5 Spy49_0005    1   56   43  414   0.999   12   56   14  161   0.034    2
## 6 Spy49_0006   74  256   14  179   0.001  191  256    4   42   0.000  111
##   t2_n t2_r t2_s t2_zbar t3_k t3_n t3_r t3_s t3_zbar
## 1  105   39  537   0.998    4  105   39  537   0.102
## 2   99   78  910   1.000    6   99   24  255   0.002
## 3   15    1    2   0.000    4   15    6   51   0.001
## 4   80    2    9   0.000   28   80   11   97   0.001
## 5   56   28  240   0.189    5   56   22  252   0.003
## 6  256   10  141   0.000   61  256   21  311   0.024
XLConnect::createSheet(workbook, name="alabama_essentiality")
XLConnect::writeWorksheet(workbook, alabama_essentials, sheet="alabama_essentiality")
XLConnect::saveWorkbook(workbook)
XLConnect::createSheet(workbook, name="nz131_essentiality")
XLConnect::writeWorksheet(workbook, nz_essentials, sheet="nz131_essentiality")
XLConnect::saveWorkbook(workbook)

5 Return

last, go back, index, next

Ashton Trey Belew ()

LS0tCnRpdGxlOiAiMjAxNTogVGhlIGZpcnN0IFROU2VxIG9mIFMucHlvZ2VuZXMiCmF1dGhvcjogImF0YiBhYmVsZXdAZ21haWwuY29tIgpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiCm91dHB1dDoKIGh0bWxfZG9jdW1lbnQ6CiAgY29kZV9kb3dubG9hZDogdHJ1ZQogIGNvZGVfZm9sZGluZzogc2hvdwogIGZpZ19jYXB0aW9uOiB0cnVlCiAgZmlnX2hlaWdodDogNwogIGZpZ193aWR0aDogNwogIGhpZ2hsaWdodDogZGVmYXVsdAogIGtlZXBfbWQ6IGZhbHNlCiAgbW9kZTogc2VsZmNvbnRhaW5lZAogIG51bWJlcl9zZWN0aW9uczogdHJ1ZQogIHNlbGZfY29udGFpbmVkOiB0cnVlCiAgdGhlbWU6IHJlYWRhYmxlCiAgdG9jOiB0cnVlCiAgdG9jX2Zsb2F0OgogICAgY29sbGFwc2VkOiBmYWxzZQogICAgc21vb3RoX3Njcm9sbDogZmFsc2UKLS0tCgo8c3R5bGU+CiAgYm9keSAubWFpbi1jb250YWluZXIgewogICAgbWF4LXdpZHRoOiAxNjAwcHg7CiAgfQo8L3N0eWxlPgoKYGBge3Igb3B0aW9ucywgaW5jbHVkZT1GQUxTRX0KaWYgKCFpc1RSVUUoZ2V0MCgic2tpcF9sb2FkIikpKSB7CiAgbGlicmFyeShocGdsdG9vbHMpCiAgdHQgPC0gZGV2dG9vbHM6OmxvYWRfYWxsKCJ+L2hwZ2x0b29scyIpCiAga25pdHI6Om9wdHNfa25pdCRzZXQocHJvZ3Jlc3M9VFJVRSwKICAgICAgICAgICAgICAgICAgICAgICB2ZXJib3NlPVRSVUUsCiAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg9OTAsCiAgICAgICAgICAgICAgICAgICAgICAgZWNobz1UUlVFKQogIGtuaXRyOjpvcHRzX2NodW5rJHNldChlcnJvcj1UUlVFLAogICAgICAgICAgICAgICAgICAgICAgICBmaWcud2lkdGg9OCwKICAgICAgICAgICAgICAgICAgICAgICAgZmlnLmhlaWdodD04LAogICAgICAgICAgICAgICAgICAgICAgICBkcGk9OTYpCiAgb2xkX29wdGlvbnMgPC0gb3B0aW9ucyhkaWdpdHM9NCwKICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZ3NBc0ZhY3RvcnM9RkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICAgICBrbml0ci5kdXBsaWNhdGUubGFiZWw9ImFsbG93IikKICBnZ3Bsb3QyOjp0aGVtZV9zZXQoZ2dwbG90Mjo6dGhlbWVfYncoYmFzZV9zaXplPTEwKSkKICB2ZXIgPC0gIjIwMTcxMTAyIgogIHByZXZpb3VzX2ZpbGUgPC0gImluZGV4LlJtZCIKCiAgdG1wIDwtIHRyeShzbShsb2FkbWUoZmlsZW5hbWU9cGFzdGUwKGdzdWIocGF0dGVybj0iXFwuUm1kIiwgcmVwbGFjZT0iIiwgeD1wcmV2aW91c19maWxlKSwgIi12IiwgdmVyLCAiLnJkYS54eiIpKSkpCiAgcm1kX2ZpbGUgPC0gImVzc2VudGlhbGl0eS5SbWQiCn0KYGBgCgojIFF1aWNrIGNhdmVhdDogIFRoaXMgd2FzIG9uZSBvZiBteSBlYXJsaWVzdCBhbmFseXNlcyBhbmQgaXQgdGhlcmVmb3JlIGlzLi4uIGJhZC4KCkkgYW0gdGhlcmVmb3JlIGRvaW5nIHRvIGJhcmUgbWluaW11bSByZXF1aXJlZCB0byBiZSBhYmxlIHRvIG9uY2UgYWdhaW4gZ2xlYW4KdXNlZnVsIGluZm9ybWF0aW9uIGZyb20gaXQuCgpgYGB7ciBsb2FkLCBpbmNsdWRlPUZBTFNFfQpsaWJyYXJ5KGhwZ2x0b29scykKcGxlYXNlX2luc3RhbGwoIlZlbm5EaWFncmFtIikKbG9hZCgiUkRhdGEiKQp3b3JrYm9vayA9IFhMQ29ubmVjdDo6bG9hZFdvcmtib29rKCJleGNlbC90bnNlcV93b3JrYm9vay54bHMiLCBjcmVhdGU9VFJVRSkKYGBgCgpbbGFzdF0oY2JjYlNFUS5odG1sKSwKPGEgaHJlZj0iIyIgb25jbGljaz0iaGlzdG9yeS5nbygtMSkiPmdvIGJhY2s8L2E+CltpbmRleF0oaW5kZXguaHRtbCksIFtuZXh0XShlc3NlbnRpYWxpdHkuaHRtbCkKCgojIEVzc2VudGlhbGl0eQoKVGhpcyBpcyBydW4gd2l0aCB0aGUgZm9sbG93aW5nIGNvbW1hbmQgbGluZSBhbmQgcHJpbnRzIG91dCBhIHRhYmxlIG9mIHogc2NvcmVzLgpUaGlzIHJlcXVpcmVzIGEgZmlsZSBUQV9kYXRhLnR4dCB3aGljaCBpbiB0dXJuIGNvbWVzIGZyb20gYSBzbWFsbCBwZXJsIHNjcmlwdAp3aGljaCByZWFkcyBvdmVyIHRoZSBiYW0gZmlsZXMgYW5kIHByaW50cyB0aGUgIyBvZiBpbnNlcnRpb25zIHdoaWNoIGZhbGwgZXhhY3RseQppbiB0aGUgY29ycmVjdCBvcmllbnRhdGlvbiBhdCBlYWNoIFRBIHBvc2l0aW9uIGluIHRoZSBnZW5vbWUuCgpgYGB7ciBlc3NlbnRpYWxpdHlfcnVubmluZywgZW5naW5lPSdiYXNoJywgZXZhbD1GQUxTRX0KZm9yIGRpciBpbiB0MCB0MSB0MiB0MzsgZG8KICBwZXJsIHRuc2VxX1RBcy5wbCAtaSAuLi9ydW4zL2xpYnMvcmFuZG9tXzFtaXNtYXRjaC9saWIxXyR7ZGlyfV9zb3J0ZWQuYmFtIDI+JHtkaXJ9L3Ruc2VxX1RBcy5lcnIgMT4ke2Rpcn0vdG5zZXFfVEFzLm91dAogIHB5dGhvbiBndW1iZWxNSC5weSAtZiAke2Rpcn0vdG5zZXFfVEFzLm91dCAtbSAxIC1zIDEwMDAgMj4ke2Rpcn0vZXNzZW50aWFsaXR5LmVyciAxPiR7ZGlyfS9lc3NlbnRpYWxpdHkub3V0CmRvbmUKYGBgCgpVcG9uIGNvbXBsZXRpb24sIEkgaGF2ZSA0IGRpcmVjdG9yaWVzIGNvbnRhaW5pbmcgdGhlIGVzc2VudGlhbGl0eS5vdXQgZmlsZXMuClRoZXNlIGFyZSBjb3BpZWQgaW50byBbZGF0YS9lc3NlbnRpYWxpdHkvXShkYXRhL2Vzc2VudGlhbGl0eS8pLgoKIyBMb2FkIGVzc2VudGlhbGl0eSBkYXRhCgpOb3RlIEkgZWRpdGVkIHRoZSBoZWFkZXJzIG9mIHRoZSB0YWJsZXMgYmVmb3JlIGxvYWRpbmcgdGhlbS4gIFRoZXkgbm93IGxvb2sgbGlrZToKIk9yZgl0M19rCXQzX24JdDNfcgl0M19zCXQzX3piYXIiCgpgYGB7ciBsb2FkX2Vzc2VudGlhbGl0eX0KdDAgPSByZWFkLnRhYmxlKCJkYXRhL2Vzc2VudGlhbGl0eS9vbGQvdDBfZXNzZW50aWFsaXR5LnR4dCIsIHNraXA9NykKY29sbmFtZXModDApID0gYygiT3JmIiwidDBfayIsInQwX24iLCJ0MF9yIiwidDBfcyIsInQwX3piYXIiKQp0MSA9IHJlYWQudGFibGUoImRhdGEvZXNzZW50aWFsaXR5L29sZC90MV9lc3NlbnRpYWxpdHkudHh0Iiwgc2tpcD03KQpjb2xuYW1lcyh0MSkgPSBjKCJPcmYiLCJ0MV9rIiwidDFfbiIsInQxX3IiLCJ0MV9zIiwidDFfemJhciIpCnQyID0gcmVhZC50YWJsZSgiZGF0YS9lc3NlbnRpYWxpdHkvb2xkL3QyX2Vzc2VudGlhbGl0eS50eHQiKQpjb2xuYW1lcyh0MikgPSBjKCJPcmYiLCJ0Ml9rIiwidDJfbiIsInQyX3IiLCJ0Ml9zIiwidDJfemJhciIpCnQzID0gcmVhZC50YWJsZSgiZGF0YS9lc3NlbnRpYWxpdHkvb2xkL3QzX2Vzc2VudGlhbGl0eS50eHQiKQpjb2xuYW1lcyh0MykgPSBjKCJPcmYiLCJ0M19rIiwidDNfbiIsInQzX3IiLCJ0M19zIiwidDNfemJhciIpCmVzc2VudGlhbGl0eV9kYXRhID0gbWVyZ2UodDAsIHQxLCBieS54PSJPcmYiLCBieS55PSJPcmYiKQplc3NlbnRpYWxpdHlfZGF0YSA9IG1lcmdlKGVzc2VudGlhbGl0eV9kYXRhLCB0MiwgYnkueD0iT3JmIiwgYnkueT0iT3JmIikKZXNzZW50aWFsaXR5X2RhdGEgPSBtZXJnZShlc3NlbnRpYWxpdHlfZGF0YSwgdDMsIGJ5Lng9Ik9yZiIsIGJ5Lnk9Ik9yZiIpCgpYTENvbm5lY3Q6OmNyZWF0ZVNoZWV0KHdvcmtib29rLCBuYW1lPSJlc3NlbnRpYWxpdHlfYWxsIikKWExDb25uZWN0Ojp3cml0ZVdvcmtzaGVldCh3b3JrYm9vaywgZXNzZW50aWFsaXR5X2RhdGEsIHNoZWV0PSJlc3NlbnRpYWxpdHlfYWxsIikKWExDb25uZWN0OjpzYXZlV29ya2Jvb2sod29ya2Jvb2spCmBgYAoKWW9hbm4gYXNrZWQgYWJvdXQgYSB2ZW5uIGRpYWdyYW0gb2YgdGhpcyBkYXRhLiAgSGVyZSBhcmUgMyBtZXRob2RzLCBvbmUKaW5jbHVkaW5nIGEgc2l6ZS13ZWlnaHRlZCB3aGljaCBpcyBjb21wbGV0ZWx5IHNpbGx5IGJlY2F1c2UgbW9zdCBvZiB0aGUgaGl0cyBhcmUKaW4gdGhlIGludGVyc2VjdGlvbiBvZiBhbGwgMy4KCmBgYHtyIGVzc2VudGlhbGl0eV92ZW5ufQp0MF9lc3NlbnRpYWwgPSB0MAp0MV9lc3NlbnRpYWwgPSB0MQp0Ml9lc3NlbnRpYWwgPSB0Mgp0MF9lc3NlbnRpYWwkYW5zd2VyID0gaWZlbHNlKHQwJHQwX3piYXIgPiAwLjk5LCAxLCAwKQp0MV9lc3NlbnRpYWwkYW5zd2VyID0gaWZlbHNlKHQxJHQxX3piYXIgPiAwLjk5LCAxLCAwKQp0Ml9lc3NlbnRpYWwkYW5zd2VyID0gaWZlbHNlKHQyJHQyX3piYXIgPiAwLjk5LCAxLCAwKQp0MF9lc3NlbnRpYWwgPSB0MF9lc3NlbnRpYWxbLCBjKDEsIDcpXQp0MV9lc3NlbnRpYWwgPSB0MV9lc3NlbnRpYWxbLCBjKDEsIDcpXQp0Ml9lc3NlbnRpYWwgPSB0Ml9lc3NlbnRpYWxbLCBjKDEsIDcpXQpyb3duYW1lcyh0MF9lc3NlbnRpYWwpID0gdDBfZXNzZW50aWFsJE9yZgojI3QwX2Vzc2VudGlhbCA9IHQwX2Vzc2VudGlhbFssIC0xXQpyb3duYW1lcyh0MV9lc3NlbnRpYWwpID0gdDFfZXNzZW50aWFsJE9yZgojI3QxX2Vzc2VudGlhbCA9IHQxX2Vzc2VudGlhbFssIC0xXQpyb3duYW1lcyh0Ml9lc3NlbnRpYWwpID0gdDJfZXNzZW50aWFsJE9yZgojI3QyX2Vzc2VudGlhbCA9IHQyX2Vzc2VudGlhbFssIC0xXQplc3NlbnRpYWxfcmVzdWx0cyA9IG1lcmdlKHQwX2Vzc2VudGlhbCwgdDFfZXNzZW50aWFsLCBieT0ncm93Lm5hbWVzJykKcm93bmFtZXMoZXNzZW50aWFsX3Jlc3VsdHMpID0gZXNzZW50aWFsX3Jlc3VsdHMkUm93Lm5hbWVzCmVzc2VudGlhbF9yZXN1bHRzID0gZXNzZW50aWFsX3Jlc3VsdHNbLC0xXQplc3NlbnRpYWxfcmVzdWx0cyA9IG1lcmdlKGVzc2VudGlhbF9yZXN1bHRzLCB0Ml9lc3NlbnRpYWwsIGJ5PSdyb3cubmFtZXMnKQpyb3duYW1lcyhlc3NlbnRpYWxfcmVzdWx0cykgPSBlc3NlbnRpYWxfcmVzdWx0cyRSb3cubmFtZXMKZXNzZW50aWFsX3Jlc3VsdHMgPSBlc3NlbnRpYWxfcmVzdWx0c1ssIC0xXQplc3NlbnRpYWxfcmVzdWx0cyA8LSBlc3NlbnRpYWxfcmVzdWx0c1ssIGMoImFuc3dlci54IiwgImFuc3dlci55IiwgImFuc3dlciIpXQojIyBUaGlzIGlzIHVzaW5nIGxpbW1hJ3MgdmVubkRpYWdyYW0gZnVuY3Rpb24KY29sbmFtZXMoZXNzZW50aWFsX3Jlc3VsdHMpID0gYygidDAiLCAidDEiLCAidDIiKQplc3NlbnRpYWxfY291bnRzID0gbGltbWE6OnZlbm5Db3VudHMoZXNzZW50aWFsX3Jlc3VsdHMpCmxpbW1hOjp2ZW5uRGlhZ3JhbShlc3NlbnRpYWxfY291bnRzLAogICAgICAgICAgICAgICAgICAgY291bnRzLmNvbCA9IGMoImJsdWUiLCAicmVkIiwgImdyZWVuIikpCiMjIEkgY2FuIHVzZSB0aGF0IHRvIGVhc2lseSBtYWtlIHRoZSB2YXJpYWJsZXMgZm9yIHRoZSBWZW5uRGlhZ3JhbSBsaWJyYXJ5Li4uCgppMSA9IDEKaTIgPSA4CmkzID0gNjEKaTEyID0gMQppMTMgPSA0CmkyMyA9IDg1CmkxMjMgPSAyMzAKCmFyZWExID0gaTEgKyBpMTIgKyBpMTMgKyBpMTIzCmFyZWEyID0gaTIgKyBpMTIgKyBpMjMgKyBpMTIzCmFyZWEzID0gaTMgKyBpMTMgKyBpMjMgKyBpMTIzCgpuMTIzID0gaTEyMwpuMTIgPSBpMTIgKyBpMTIzCm4xMyA9IGkxMyArIGkxMjMKbjIzID0gaTIzICsgaTEyMwoKdGVzdCA9IFZlbm5lcmFibGU6OlZlbm4oU2V0TmFtZXMgPSBjKCJ0MCIsInQxIiwidDIiKSwgV2VpZ2h0ID0KICAgIGMoJzEwMCcgPSBpMSwgJzAxMCcgPSBpMiwgJzAwMScgPSBpMywgIyMgVGhlIGxvbmVycwogICAgICAnMTEwJyA9IGkxMiwgJzAxMScgPSBpMjMsICcxMDEnID0gaTEzLCAgIyMgVGhlIGRvdWJsZXMKICAgICAgJzExMScgPSBpMTIzKSkKVmVubmVyYWJsZTo6cGxvdCh0ZXN0LCBkb1dlaWdodHMgPSBUUlVFLCB0eXBlID0gImNpcmNsZXMiKQpWZW5uZXJhYmxlOjpwbG90KHRlc3QsIGRvV2VpZ2h0cyA9IEZBTFNFLCB0eXBlID0gImNpcmNsZXMiKQoKZHJhdy50cmlwbGUudmVubihhcmVhMSwgYXJlYTIsIGFyZWEzLCBuMTIsIG4yMywgbjEzLCBuMTIzLAogICAgICAgICAgICAgICAgIGNhdGVnb3J5ID0gcmVwKCIiLCAzKSwgcm90YXRpb24gPSAxLCByZXZlcnNlID0gRkFMU0UsIGV1bGVyLmQgPSBUUlVFLAogICAgICAgICAgICAgICAgIHNjYWxlZCA9IFRSVUUsIGx3ZCA9IHJlcCgyLCAzKSwgbHR5ID0gcmVwKCJzb2xpZCIsIDMpLAogICAgICAgICAgICAgICAgIGNvbCA9IHJlcCgiYmxhY2siLCAzKSwgZmlsbCA9IE5VTEwsIGFscGhhID0gcmVwKDAuNSwgMyksCiAgICAgICAgICAgICAgICAgbGFiZWwuY29sID0gcmVwKCJibGFjayIsIDcpLCBjZXggPSByZXAoMSwgNyksIGZvbnRmYWNlID0gcmVwKCJwbGFpbiIsIDcpLAogICAgICAgICAgICAgICAgIGZvbnRmYW1pbHkgPSByZXAoInNlcmlmIiwgNyksIGNhdC5wb3MgPSBjKC00MCwgNDAsIDE4MCksCiAgICAgICAgICAgICAgICAgY2F0LmRpc3QgPSBjKDAuMDUsIDAuMDUsIDAuMDI1KSwgY2F0LmNvbCA9IHJlcCgiYmxhY2siLCAzKSwKICAgICAgICAgICAgICAgICBjYXQuY2V4ID0gcmVwKDEsIDMpLCBjYXQuZm9udGZhY2UgPSByZXAoInBsYWluIiwgMyksCiAgICAgICAgICAgICAgICAgY2F0LmZvbnRmYW1pbHkgPSByZXAoInNlcmlmIiwgMyksCiAgICAgICAgICAgICAgICAgY2F0Lmp1c3QgPSBsaXN0KGMoMC41LCAxKSwgYygwLjUsIDEpLCBjKDAuNSwgMCkpLCBjYXQuZGVmYXVsdC5wb3MgPSAib3V0ZXIiLAogICAgICAgICAgICAgICAgIGNhdC5wcm9tcHRzID0gRkFMU0UsIHJvdGF0aW9uLmRlZ3JlZSA9IDAsIHJvdGF0aW9uLmNlbnRyZSA9IGMoMC41LCAwLjUpLAogICAgICAgICAgICAgICAgIGluZCA9IFRSVUUsIHNlcC5kaXN0ID0gMC4wNSwgb2Zmc2V0ID0gMCkKYGBgCgojIFJlcGVhdCBmb3IgdGhlIEFsYWJhbWEgYW5kIE5aMTMxIHN0cmFpbnMuCgojIyBBZGQgYW5ub3RhdGlvbiBpbmZvcm1hdGlvbiBmb3IgQWxhYmFtYSBhbmQgTloxMzEgaW50byB0aGUgZXhjZWwgd29ya2Jvb2sKCiMjIFJ1biBlc3NlbnRpYWxpdHkgYW5kIGFkZCB0aGUgZXNzZW50aWFsaXR5IG91dHB1dCB0byB0aGUgZXhjZWwgd29ya2Jvb2suLi4KCkkgY3JlYXRlZCBhbiBhbGFiYW1hIGRpcmVjdG9yeSBpbnNpZGUgdGhlIGVzc2VudGlhbGl0eSBkaXJlY3RvcnkuICBJdCB0b29rIG1lIGEgZmV3IHRyaWVzIHRvIGdldCBpdCBjb3JyZWN0LCBhbmQgSSBoYWQgdG8gbWFrZSBzb21lIHNtYWxsIGVkaXRzIHRvIHRoZSBwZXJsIHNjcmlwdCB0bnNlcV9UQXMgdG8gYWNjb21vZGF0ZSB0aGUgbmV3IHN0cmFpbnMsIGJ1dCBJIHJhbiB0aGUgcGVybHNjcmlwdCBpbiB0aGUgc2FtZSBmYXNoaW9uLiAgKENhdmVhdDogIFRoZSBwZXJsIHNjcmlwdCBuZWVkcyB0byBiZSBhYmxlIHRvIGNyb3NzIHJlZmVyZW5jZSB0aGUgbmFtZSBvZiB0aGUgX2Zhc3RhXyBzZXF1ZW5jZSBhZ2FpbnN0IHRoZSBiYW0gc2VxdWVuY2UgbmFtZS4gIFRoaXMgdHJpcHBlZCBtZSB1cCB0ZXJyaWJseS4KClVwb24gY29tcGxldGlvbiwgSSB3cm90ZSBhIHRpbnkgc2hlbGwgc2NyaXB0IHRvIHJ1biB0aGUgcHl0aG9uIGVzc2VudGlhbGl0eSBwYWNrYWdlIGZvciBlYWNoIG91dHB1dCBmaWxlLgoKYGBge3IgYWxhYmFtYV9lc3NlbnRpYWxpdHksIGVuZ2luZz0nYmFzaCcsIGV2YWw9RkFMU0V9CmNkIGVzc2VudGlhbGl0eS9hbGFiYW1hLwouL1JFQURNRS5zaAojIyBUaGlzIHByaW50cyBvdXQgdGhlIGFwcHJvcHJpYXRlIGNvbW1hbmQgbGluZXMgZm9yIHRoZSBUTnNlcV9UQXMucGwgYW5kIGd1bWJlbE1ILnB5IGNvbW1hbmRzLgpgYGAKClRoYXQgY29tcGxldGVkIGluIHNvbWUgaG91cnMsIHByb3ZpZGluZyB0aGUgcmF3IG91dHB1dHMgZnJvbSBlc3NlbnRpYWxpdHksIHdoaWNoIEkgYWdhaW4gZWRpdGVkIHNsaWdodGx5IHRvIGluY2x1ZGUgdGhlIHRpbWVwb2ludCB2YWx1ZXMuICBMZXQgdXMgbG9hZCB0aGVtIGludG8gdGhlIGV4Y2VsIHNwcmVhZHNoZWV0LgoKYGBge3IgbG9hZF9hbGFiYW1hX2Vzc2VudGlhbGl0eX0KYWxhYmFtYV90MCA9IHJlYWQudGFibGUoImRhdGEvZXNzZW50aWFsaXR5L29sZC9BbGFiNDlfdDBfZXNzZW50aWFsaXR5Lm91dCIsIHNraXA9NywgaGVhZGVyPVRSVUUpCmFsYWJhbWFfdDEgPSByZWFkLnRhYmxlKCJkYXRhL2Vzc2VudGlhbGl0eS9vbGQvQWxhYjQ5X3QxX2Vzc2VudGlhbGl0eS5vdXQiLCBza2lwPTcsIGhlYWRlcj1UUlVFKQphbGFiYW1hX3QyID0gcmVhZC50YWJsZSgiZGF0YS9lc3NlbnRpYWxpdHkvb2xkL0FsYWI0OV90Ml9lc3NlbnRpYWxpdHkub3V0Iiwgc2tpcD03LCBoZWFkZXI9VFJVRSkKYWxhYmFtYV90MyA9IHJlYWQudGFibGUoImRhdGEvZXNzZW50aWFsaXR5L29sZC9BbGFiNDlfdDNfZXNzZW50aWFsaXR5Lm91dCIsIHNraXA9NywgaGVhZGVyPVRSVUUpCm56X3QwID0gcmVhZC50YWJsZSgiZGF0YS9lc3NlbnRpYWxpdHkvb2xkL05aMTMxX3QwX2Vzc2VudGlhbGl0eS5vdXQiLCBza2lwPTcsIGhlYWRlcj1UUlVFKQpuel90MSA9IHJlYWQudGFibGUoImRhdGEvZXNzZW50aWFsaXR5L29sZC9OWjEzMV90MV9lc3NlbnRpYWxpdHkub3V0Iiwgc2tpcD03LCBoZWFkZXI9VFJVRSkKbnpfdDIgPSByZWFkLnRhYmxlKCJkYXRhL2Vzc2VudGlhbGl0eS9vbGQvTloxMzFfdDJfZXNzZW50aWFsaXR5Lm91dCIsIHNraXA9NywgaGVhZGVyPVRSVUUpCm56X3QzID0gcmVhZC50YWJsZSgiZGF0YS9lc3NlbnRpYWxpdHkvb2xkL05aMTMxX3QzX2Vzc2VudGlhbGl0eS5vdXQiLCBza2lwPTcsIGhlYWRlcj1UUlVFKQphbGFiYW1hX2Vzc2VudGlhbHMgPSBtZXJnZShhbGFiYW1hX3QwLCBhbGFiYW1hX3QxLCBieS54PSJPcmYiLCBieS55PSJPcmYiKQphbGFiYW1hX2Vzc2VudGlhbHMgPSBtZXJnZShhbGFiYW1hX2Vzc2VudGlhbHMsIGFsYWJhbWFfdDIsIGJ5Lng9Ik9yZiIsIGJ5Lnk9Ik9yZiIpCmFsYWJhbWFfZXNzZW50aWFscyA9IG1lcmdlKGFsYWJhbWFfZXNzZW50aWFscywgYWxhYmFtYV90MywgYnkueD0iT3JmIiwgYnkueT0iT3JmIikKbnpfZXNzZW50aWFscyA9IG1lcmdlKG56X3QwLCBuel90MSwgYnkueD0iT3JmIiwgYnkueT0iT3JmIikKbnpfZXNzZW50aWFscyA9IG1lcmdlKG56X2Vzc2VudGlhbHMsIG56X3QyLCBieS54PSJPcmYiLCBieS55PSJPcmYiKQpuel9lc3NlbnRpYWxzID0gbWVyZ2UobnpfZXNzZW50aWFscywgbnpfdDMsIGJ5Lng9Ik9yZiIsIGJ5Lnk9Ik9yZiIpCmhlYWQobnpfZXNzZW50aWFscykKClhMQ29ubmVjdDo6Y3JlYXRlU2hlZXQod29ya2Jvb2ssIG5hbWU9ImFsYWJhbWFfZXNzZW50aWFsaXR5IikKWExDb25uZWN0Ojp3cml0ZVdvcmtzaGVldCh3b3JrYm9vaywgYWxhYmFtYV9lc3NlbnRpYWxzLCBzaGVldD0iYWxhYmFtYV9lc3NlbnRpYWxpdHkiKQpYTENvbm5lY3Q6OnNhdmVXb3JrYm9vayh3b3JrYm9vaykKWExDb25uZWN0OjpjcmVhdGVTaGVldCh3b3JrYm9vaywgbmFtZT0ibnoxMzFfZXNzZW50aWFsaXR5IikKWExDb25uZWN0Ojp3cml0ZVdvcmtzaGVldCh3b3JrYm9vaywgbnpfZXNzZW50aWFscywgc2hlZXQ9Im56MTMxX2Vzc2VudGlhbGl0eSIpClhMQ29ubmVjdDo6c2F2ZVdvcmtib29rKHdvcmtib29rKQpgYGAKCiMgUmV0dXJuCgpbbGFzdF0oY2JjYlNFUS5odG1sKSwKPGEgaHJlZj0iIyIgb25jbGljaz0iaGlzdG9yeS5nbygtMSkiPmdvIGJhY2s8L2E+LApbaW5kZXhdKGluZGV4Lmh0bWwpLCBbbmV4dF0oZXNzZW50aWFsaXR5Lmh0bWwpCgpgYGB7ciBydW5fZGF0ZSwgcmVzdWx0cz0nYXNpcycsIGVjaG89RkFMU0V9CmVtYWlsID0gIjxhIGhyZWY9J21haWx0bzphYmVsZXdAdW1kLmVkdSc+QXNodG9uIFRyZXkgQmVsZXc8L2E+IgpsYXN0X3VwZGF0ZSA9IGZvcm1hdChTeXMudGltZSgpLCAiKDx0aW1lPiVZLSVtLSVkPC90aW1lPikiKQpjYXQocGFzdGUoZW1haWwsIGxhc3RfdXBkYXRlKSkKYGBgCgpgYGB7ciBzYXZlLCBpbmNsdWRlPUZBTFNFfQpzYXZlKGxpc3QgPSBscyhhbGw9VFJVRSksIGZpbGUgPSAiUkRhdGEiKQpgYGAK