Figure S3F - GO Enrichment for AI peaks
for (cond in c(ab_tp_list, list(ab_tp_list))) {
test_geneID = get_test_geneID(cht, cond, 1000)
background_geneID = get_background_geneID(cht, cond, 1000, test_geneID)
out = create_GOdata(test_geneID, background_geneID, "BP")
GOdata = out[[1]]
test = out[[2]]
n_nodes = length(attributes(GOdata)$graph@nodes)
# Classic Fisher test
test.stat <- new("classicCount", testStatistic = GOFisherTest, name = "Fisher test")
resultFisher <- getSigGroups(GOdata, test.stat)
# KS test
test.stat <- new("classicScore", testStatistic = GOKSTest, name = "KS tests")
resultKS <- getSigGroups(GOdata, test.stat)
# Weight algorithm
test.stat <- new("weightCount", testStatistic = GOFisherTest, name = "Fisher test", sigRatio = "ratio")
resultWeight <- getSigGroups(GOdata, test.stat)
allRes <- GenTable(GOdata, classic = resultFisher,
KS = resultKS, weight = resultWeight,
orderBy = "weight", ranksOf = "classic", topNodes = n_nodes)
allRes$Fold_Enrichment = allRes$Significant / allRes$Expected
allRes$FDR = allRes$weight
top_results = select_top_GO(allRes, 500, 10, 0.05, 10)
p = ggplot_GO_enrichment(top_results, nrow(as.data.frame(test)), length(as.data.frame(test)[as.data.frame(test)[,1] == 1, ]), cond)
print(p)
out_filename = paste0("FigS3F_GO_enrichment_AI_peaks_", gsub("/", "_", paste(cond, collapse = '_')) ,".pdf")
ggsave(file.path(outdir_fig_suppl, out_filename), p, width = 6, height = 6)
}
>> preparing features information... 2024-11-29 01:49:24 PM
>> identifying nearest features... 2024-11-29 01:49:24 PM
>> calculating distance from peak to TSS... 2024-11-29 01:49:24 PM
>> assigning genomic annotation... 2024-11-29 01:49:24 PM
>> adding gene annotation... 2024-11-29 01:49:29 PM
'select()' returned 1:1 mapping between keys and columns
>> assigning chromosome lengths 2024-11-29 01:49:29 PM
>> done... 2024-11-29 01:49:29 PM
>> preparing features information... 2024-11-29 01:49:30 PM
>> identifying nearest features... 2024-11-29 01:49:30 PM
>> calculating distance from peak to TSS... 2024-11-29 01:49:30 PM
>> assigning genomic annotation... 2024-11-29 01:49:30 PM
>> adding gene annotation... 2024-11-29 01:49:31 PM
'select()' returned 1:many mapping between keys and columns
>> assigning chromosome lengths 2024-11-29 01:49:31 PM
>> done... 2024-11-29 01:49:31 PM
'select()' returned 1:1 mapping between keys and columns
'select()' returned 1:many mapping between keys and columns
Building most specific GOs .....
( 3583 GO terms found. )
Build GO DAG topology ..........
( 6174 GO terms and 13460 relations. )
Annotating nodes ...............
( 3270 genes annotated to the GO terms. )
-- Classic Algorithm --
the algorithm is scoring 3229 nontrivial nodes
parameters:
test statistic: Fisher test
-- Classic Algorithm --
the algorithm is scoring 6174 nontrivial nodes
parameters:
test statistic: KS tests
score order: increasing
-- Weight Algorithm --
The algorithm is scoring 3229 nontrivial nodes
parameters:
test statistic: Fisher test : ratio
Level 17: 4 nodes to be scored.
Level 16: 11 nodes to be scored.
Level 15: 20 nodes to be scored.
Level 14: 37 nodes to be scored.
Level 13: 74 nodes to be scored.
Level 12: 130 nodes to be scored.
Level 11: 226 nodes to be scored.
Level 10: 319 nodes to be scored.
Level 9: 452 nodes to be scored.
Level 8: 450 nodes to be scored.
Level 7: 494 nodes to be scored.
Level 6: 449 nodes to be scored.
Level 5: 312 nodes to be scored.
Level 4: 162 nodes to be scored.
Level 3: 72 nodes to be scored.
Level 2: 16 nodes to be scored.
Level 1: 1 nodes to be scored.
Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
ℹ Please use `linewidth` instead.
This warning is displayed once every 8 hours.
Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
generated.
Warning: The `size` argument of `element_line()` is deprecated as of ggplot2 3.4.0.
ℹ Please use the `linewidth` argument instead.
This warning is displayed once every 8 hours.
Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
generated.
>> preparing features information... 2024-11-29 01:51:02 PM
>> identifying nearest features... 2024-11-29 01:51:02 PM
>> calculating distance from peak to TSS... 2024-11-29 01:51:02 PM
>> assigning genomic annotation... 2024-11-29 01:51:02 PM
>> adding gene annotation... 2024-11-29 01:51:03 PM
'select()' returned 1:1 mapping between keys and columns
>> assigning chromosome lengths 2024-11-29 01:51:03 PM
>> done... 2024-11-29 01:51:03 PM
>> preparing features information... 2024-11-29 01:51:04 PM
>> identifying nearest features... 2024-11-29 01:51:04 PM
>> calculating distance from peak to TSS... 2024-11-29 01:51:04 PM
>> assigning genomic annotation... 2024-11-29 01:51:04 PM
>> adding gene annotation... 2024-11-29 01:51:05 PM
'select()' returned 1:many mapping between keys and columns
>> assigning chromosome lengths 2024-11-29 01:51:05 PM
>> done... 2024-11-29 01:51:05 PM
'select()' returned 1:1 mapping between keys and columns
'select()' returned 1:many mapping between keys and columns
Building most specific GOs .....
( 3072 GO terms found. )
Build GO DAG topology ..........
( 5653 GO terms and 12291 relations. )
Annotating nodes ...............
( 2339 genes annotated to the GO terms. )
-- Classic Algorithm --
the algorithm is scoring 2911 nontrivial nodes
parameters:
test statistic: Fisher test
-- Classic Algorithm --
the algorithm is scoring 5653 nontrivial nodes
parameters:
test statistic: KS tests
score order: increasing
-- Weight Algorithm --
The algorithm is scoring 2911 nontrivial nodes
parameters:
test statistic: Fisher test : ratio
Level 17: 1 nodes to be scored.
Level 16: 7 nodes to be scored.
Level 15: 17 nodes to be scored.
Level 14: 25 nodes to be scored.
Level 13: 58 nodes to be scored.
Level 12: 102 nodes to be scored.
Level 11: 193 nodes to be scored.
Level 10: 272 nodes to be scored.
Level 9: 384 nodes to be scored.
Level 8: 408 nodes to be scored.
Level 7: 467 nodes to be scored.
Level 6: 425 nodes to be scored.
Level 5: 297 nodes to be scored.
Level 4: 164 nodes to be scored.
Level 3: 74 nodes to be scored.
Level 2: 16 nodes to be scored.
Level 1: 1 nodes to be scored.

>> preparing features information... 2024-11-29 01:52:18 PM
>> identifying nearest features... 2024-11-29 01:52:18 PM
>> calculating distance from peak to TSS... 2024-11-29 01:52:19 PM
>> assigning genomic annotation... 2024-11-29 01:52:19 PM
>> adding gene annotation... 2024-11-29 01:52:20 PM
'select()' returned 1:many mapping between keys and columns
>> assigning chromosome lengths 2024-11-29 01:52:20 PM
>> done... 2024-11-29 01:52:20 PM
>> preparing features information... 2024-11-29 01:52:20 PM
>> identifying nearest features... 2024-11-29 01:52:20 PM
>> calculating distance from peak to TSS... 2024-11-29 01:52:21 PM
>> assigning genomic annotation... 2024-11-29 01:52:21 PM
>> adding gene annotation... 2024-11-29 01:52:22 PM
'select()' returned 1:many mapping between keys and columns
>> assigning chromosome lengths 2024-11-29 01:52:22 PM
>> done... 2024-11-29 01:52:22 PM
'select()' returned 1:many mapping between keys and columns
'select()' returned 1:many mapping between keys and columns
Building most specific GOs .....
( 3547 GO terms found. )
Build GO DAG topology ..........
( 6132 GO terms and 13320 relations. )
Annotating nodes ...............
( 3147 genes annotated to the GO terms. )
-- Classic Algorithm --
the algorithm is scoring 3047 nontrivial nodes
parameters:
test statistic: Fisher test
-- Classic Algorithm --
the algorithm is scoring 6132 nontrivial nodes
parameters:
test statistic: KS tests
score order: increasing
-- Weight Algorithm --
The algorithm is scoring 3047 nontrivial nodes
parameters:
test statistic: Fisher test : ratio
Level 17: 2 nodes to be scored.
Level 16: 11 nodes to be scored.
Level 15: 20 nodes to be scored.
Level 14: 44 nodes to be scored.
Level 13: 60 nodes to be scored.
Level 12: 108 nodes to be scored.
Level 11: 202 nodes to be scored.
Level 10: 290 nodes to be scored.
Level 9: 417 nodes to be scored.
Level 8: 431 nodes to be scored.
Level 7: 480 nodes to be scored.
Level 6: 422 nodes to be scored.
Level 5: 306 nodes to be scored.
Level 4: 165 nodes to be scored.
Level 3: 71 nodes to be scored.
Level 2: 17 nodes to be scored.
Level 1: 1 nodes to be scored.

>> preparing features information... 2024-11-29 01:53:49 PM
>> identifying nearest features... 2024-11-29 01:53:49 PM
>> calculating distance from peak to TSS... 2024-11-29 01:53:49 PM
>> assigning genomic annotation... 2024-11-29 01:53:49 PM
>> adding gene annotation... 2024-11-29 01:53:50 PM
'select()' returned 1:1 mapping between keys and columns
>> assigning chromosome lengths 2024-11-29 01:53:50 PM
>> done... 2024-11-29 01:53:50 PM
>> preparing features information... 2024-11-29 01:53:51 PM
>> identifying nearest features... 2024-11-29 01:53:51 PM
>> calculating distance from peak to TSS... 2024-11-29 01:53:52 PM
>> assigning genomic annotation... 2024-11-29 01:53:52 PM
>> adding gene annotation... 2024-11-29 01:53:53 PM
'select()' returned 1:many mapping between keys and columns
>> assigning chromosome lengths 2024-11-29 01:53:53 PM
>> done... 2024-11-29 01:53:53 PM
'select()' returned 1:1 mapping between keys and columns
'select()' returned 1:many mapping between keys and columns
Building most specific GOs .....
( 3712 GO terms found. )
Build GO DAG topology ..........
( 6316 GO terms and 13779 relations. )
Annotating nodes ...............
( 3568 genes annotated to the GO terms. )
-- Classic Algorithm --
the algorithm is scoring 3142 nontrivial nodes
parameters:
test statistic: Fisher test
-- Classic Algorithm --
the algorithm is scoring 6316 nontrivial nodes
parameters:
test statistic: KS tests
score order: increasing
-- Weight Algorithm --
The algorithm is scoring 3142 nontrivial nodes
parameters:
test statistic: Fisher test : ratio
Level 18: 2 nodes to be scored.
Level 17: 4 nodes to be scored.
Level 16: 9 nodes to be scored.
Level 15: 20 nodes to be scored.
Level 14: 40 nodes to be scored.
Level 13: 58 nodes to be scored.
Level 12: 108 nodes to be scored.
Level 11: 202 nodes to be scored.
Level 10: 291 nodes to be scored.
Level 9: 418 nodes to be scored.
Level 8: 466 nodes to be scored.
Level 7: 523 nodes to be scored.
Level 6: 445 nodes to be scored.
Level 5: 303 nodes to be scored.
Level 4: 164 nodes to be scored.
Level 3: 72 nodes to be scored.
Level 2: 16 nodes to be scored.
Level 1: 1 nodes to be scored.

>> preparing features information... 2024-11-29 01:55:21 PM
>> identifying nearest features... 2024-11-29 01:55:21 PM
>> calculating distance from peak to TSS... 2024-11-29 01:55:21 PM
>> assigning genomic annotation... 2024-11-29 01:55:21 PM
>> adding gene annotation... 2024-11-29 01:55:22 PM
'select()' returned 1:1 mapping between keys and columns
>> assigning chromosome lengths 2024-11-29 01:55:22 PM
>> done... 2024-11-29 01:55:22 PM
>> preparing features information... 2024-11-29 01:55:22 PM
>> identifying nearest features... 2024-11-29 01:55:22 PM
>> calculating distance from peak to TSS... 2024-11-29 01:55:23 PM
>> assigning genomic annotation... 2024-11-29 01:55:23 PM
>> adding gene annotation... 2024-11-29 01:55:24 PM
'select()' returned 1:many mapping between keys and columns
>> assigning chromosome lengths 2024-11-29 01:55:24 PM
>> done... 2024-11-29 01:55:24 PM
'select()' returned 1:1 mapping between keys and columns
'select()' returned 1:many mapping between keys and columns
Building most specific GOs .....
( 3159 GO terms found. )
Build GO DAG topology ..........
( 5697 GO terms and 12408 relations. )
Annotating nodes ...............
( 2450 genes annotated to the GO terms. )
-- Classic Algorithm --
the algorithm is scoring 2594 nontrivial nodes
parameters:
test statistic: Fisher test
-- Classic Algorithm --
the algorithm is scoring 5697 nontrivial nodes
parameters:
test statistic: KS tests
score order: increasing
-- Weight Algorithm --
The algorithm is scoring 2594 nontrivial nodes
parameters:
test statistic: Fisher test : ratio
Level 18: 1 nodes to be scored.
Level 17: 2 nodes to be scored.
Level 16: 5 nodes to be scored.
Level 15: 17 nodes to be scored.
Level 14: 35 nodes to be scored.
Level 13: 55 nodes to be scored.
Level 12: 87 nodes to be scored.
Level 11: 153 nodes to be scored.
Level 10: 240 nodes to be scored.
Level 9: 341 nodes to be scored.
Level 8: 369 nodes to be scored.
Level 7: 409 nodes to be scored.
Level 6: 374 nodes to be scored.
Level 5: 275 nodes to be scored.
Level 4: 150 nodes to be scored.
Level 3: 66 nodes to be scored.
Level 2: 14 nodes to be scored.
Level 1: 1 nodes to be scored.

>> preparing features information... 2024-11-29 01:56:38 PM
>> identifying nearest features... 2024-11-29 01:56:38 PM
>> calculating distance from peak to TSS... 2024-11-29 01:56:38 PM
>> assigning genomic annotation... 2024-11-29 01:56:38 PM
>> adding gene annotation... 2024-11-29 01:56:39 PM
'select()' returned 1:1 mapping between keys and columns
>> assigning chromosome lengths 2024-11-29 01:56:39 PM
>> done... 2024-11-29 01:56:39 PM
>> preparing features information... 2024-11-29 01:56:39 PM
>> identifying nearest features... 2024-11-29 01:56:39 PM
>> calculating distance from peak to TSS... 2024-11-29 01:56:40 PM
>> assigning genomic annotation... 2024-11-29 01:56:40 PM
>> adding gene annotation... 2024-11-29 01:56:40 PM
'select()' returned 1:many mapping between keys and columns
>> assigning chromosome lengths 2024-11-29 01:56:41 PM
>> done... 2024-11-29 01:56:41 PM
'select()' returned 1:1 mapping between keys and columns
'select()' returned 1:many mapping between keys and columns
Building most specific GOs .....
( 3202 GO terms found. )
Build GO DAG topology ..........
( 5756 GO terms and 12564 relations. )
Annotating nodes ...............
( 2358 genes annotated to the GO terms. )
-- Classic Algorithm --
the algorithm is scoring 2484 nontrivial nodes
parameters:
test statistic: Fisher test
-- Classic Algorithm --
the algorithm is scoring 5756 nontrivial nodes
parameters:
test statistic: KS tests
score order: increasing
-- Weight Algorithm --
The algorithm is scoring 2484 nontrivial nodes
parameters:
test statistic: Fisher test : ratio
Level 18: 1 nodes to be scored.
Level 17: 3 nodes to be scored.
Level 16: 7 nodes to be scored.
Level 15: 14 nodes to be scored.
Level 14: 24 nodes to be scored.
Level 13: 42 nodes to be scored.
Level 12: 71 nodes to be scored.
Level 11: 131 nodes to be scored.
Level 10: 223 nodes to be scored.
Level 9: 327 nodes to be scored.
Level 8: 365 nodes to be scored.
Level 7: 408 nodes to be scored.
Level 6: 370 nodes to be scored.
Level 5: 267 nodes to be scored.
Level 4: 144 nodes to be scored.
Level 3: 70 nodes to be scored.
Level 2: 16 nodes to be scored.
Level 1: 1 nodes to be scored.

>> preparing features information... 2024-11-29 01:57:55 PM
>> identifying nearest features... 2024-11-29 01:57:55 PM
>> calculating distance from peak to TSS... 2024-11-29 01:57:55 PM
>> assigning genomic annotation... 2024-11-29 01:57:55 PM
>> adding gene annotation... 2024-11-29 01:57:56 PM
'select()' returned 1:many mapping between keys and columns
>> assigning chromosome lengths 2024-11-29 01:57:56 PM
>> done... 2024-11-29 01:57:56 PM
>> preparing features information... 2024-11-29 01:58:01 PM
>> identifying nearest features... 2024-11-29 01:58:01 PM
>> calculating distance from peak to TSS... 2024-11-29 01:58:02 PM
>> assigning genomic annotation... 2024-11-29 01:58:02 PM
>> adding gene annotation... 2024-11-29 01:58:04 PM
'select()' returned 1:many mapping between keys and columns
>> assigning chromosome lengths 2024-11-29 01:58:05 PM
>> done... 2024-11-29 01:58:05 PM
'select()' returned 1:many mapping between keys and columns
'select()' returned 1:many mapping between keys and columns
Building most specific GOs .....
( 4188 GO terms found. )
Build GO DAG topology ..........
( 6851 GO terms and 14972 relations. )
Annotating nodes ...............
( 5165 genes annotated to the GO terms. )
-- Classic Algorithm --
the algorithm is scoring 4850 nontrivial nodes
parameters:
test statistic: Fisher test
-- Classic Algorithm --
the algorithm is scoring 6851 nontrivial nodes
parameters:
test statistic: KS tests
score order: increasing
-- Weight Algorithm --
The algorithm is scoring 4850 nontrivial nodes
parameters:
test statistic: Fisher test : ratio
Level 18: 2 nodes to be scored.
Level 17: 6 nodes to be scored.
Level 16: 15 nodes to be scored.
Level 15: 34 nodes to be scored.
Level 14: 73 nodes to be scored.
Level 13: 121 nodes to be scored.
Level 12: 221 nodes to be scored.
Level 11: 388 nodes to be scored.
Level 10: 552 nodes to be scored.
Level 9: 700 nodes to be scored.
Level 8: 714 nodes to be scored.
Level 7: 733 nodes to be scored.
Level 6: 598 nodes to be scored.
Level 5: 387 nodes to be scored.
Level 4: 204 nodes to be scored.
Level 3: 84 nodes to be scored.
Level 2: 17 nodes to be scored.
Level 1: 1 nodes to be scored.


LS0tCnRpdGxlOiAiRmlndXJlX1MzIgpvdXRwdXQ6CiAgIEJpb2NTdHlsZTo6aHRtbF9kb2N1bWVudDoKICAgICAgdG9jOiB0cnVlCiAgICAgIGRmX3ByaW50OiBwYWdlZAogICAgICBzZWxmX2NvbnRhaW5lZDogdHJ1ZQogICAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICAgIGhpZ2hsaWdodDogdGFuZ28KI2JpYmxpb2dyYXBoeToga25uX21sX2ludHJvLmJpYgplZGl0b3Jfb3B0aW9uczogCiAgY2h1bmtfb3V0cHV0X3R5cGU6IGlubGluZQotLS0KCmBgYHtyIHN0eWxlLCBlY2hvPUZBTFNFLCByZXN1bHRzPSJhc2lzIn0KbGlicmFyeSgia25pdHIiKQpvcHRpb25zKGRpZ2l0cyA9IDIsIHdpZHRoID0gODApCm9wdGlvbnMoYml0bWFwVHlwZSA9ICdjYWlybycpCmdvbGRlbl9yYXRpbyA8LSAoMSArIHNxcnQoNSkpIC8gMgpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSwgdGlkeSA9IEZBTFNFLCBpbmNsdWRlID0gVFJVRSwgY2FjaGUgPSBGQUxTRSwKICAgICAgICAgICAgICAgZGV2PWMoJ3BuZycsICdwZGYnKSwgY29tbWVudCA9ICcgICcsIGRwaSA9IDMwMCkKCm9wdGlvbnMoc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFKQprbml0cjo6b3B0c19jaHVuayRzZXQoY2FjaGU9RkFMU0UpCm9wdGlvbnMoZGlnaXRzID0gNSkgICAgICAgICAKYGBgCgojIFNldHVwIGFuZCBkYXRhCgpgYGB7cn0Kc291cmNlKCIuLi91dGlscy91dGlscy5SIikKY29uZmlnID0gbG9hZF9jb25maWcoKQoKIyBsb2FkIENIVCByZXN1bHRzCmNodF9mdWxsID0gbGFwcGx5KGFiX3RwX2xpc3QsIGZ1bmN0aW9uKGFiX3RwKSBsb2FkX2NodF9yZXN1bHRzKGFiX3RwLCByZW1vdmVfY2hyID0gRikpICU+JSBiaW5kX3Jvd3MoKQpjaHQgPSBjaHRfZnVsbCAlPiUgZmlsdGVyKCFURVNULlNOUC5DSFJPTSAlaW4lIGMoImNoclgiLCAiY2hyWSIsICJjaHJNIikpCmNodF9zaWduID0gY2h0ICU+JSBmaWx0ZXIoc2lnbmlmX3N0cm9uZ0FJKSAKCiMgZ2VuZXMgYW5kIHByb21vdGVycwpnZW5lcyA9IGxvYWRfZ2VuZXMoKQpwcm9tb3RlcnMgPSByZXNpemUoZ2VuZXMsIHdpZHRoID0gMTAwMCwgZml4ID0gInN0YXJ0IikKCiMgY29tYmluZWQgbW90aWYgc2V0IChhbGwgVEZzLCBwZWFrcyArIGFsbGVsZXMpCmZpbW8gPSBnZXRfZnVsbF9tb3RpZl9zZXRzKGNodCwgYWJfdHBfbGlzdCkKIyBvbmx5IGFsbGVsZXMKZmltb19hbGxlbGVzICA9IGxhcHBseShhYl90cF9saXN0LCBmdW5jdGlvbihhYl90cCkgcGFyc2VfbW90aWZzX2luX3R3b19hbGxlbGVzKGFiX3RwLCBjaHQpKSAlPiUgYmluZF9yb3dzKCkgCgpgYGAKCiMgRmlndXJlIFMzQjogSW5kZWxzIGxlbmd0aAoKYGBge3J9CmNodF9zZWwgPSBjaHQgJT4lCiAgZmlsdGVyKHNpZ25pZl9zdHJvbmdBSSkgJT4lCiAgZ3JvdXBfYnkocGVha19pZCkgJT4lCiAgI211dGF0ZShtaW5fcHZhbCA9IG1pbihQLlZBTFVFKSkgJT4lCiAgI2ZpbHRlcihQLlZBTFVFID09IG1pbl9wdmFsKSAlPiUKICBtdXRhdGUobWF4X2luZGVsID0gbWF4KGluZGVsX2xlbmd0aCksIG1pbl9pbmRlbCA9IG1pbihpbmRlbF9sZW5ndGgpKSAlPiUKICBmaWx0ZXIoaW5kZWxfbGVuZ3RoID09IG1heF9pbmRlbCkgJT4lCiMgIG11dGF0ZShtYXhfQUkgPSBtYXgoQUlfYWJzKSkgJT4lCiMgIGZpbHRlcihBSV9hYnMgPT0gbWF4X0FJKSAlPiUKICBzZWxlY3QoY29uZGl0aW9uLCBwZWFrX2lkLCBpbmRlbF9sZW5ndGgsIEFJX2FicykgJT4lCiAgdW5pcXVlKCkgJT4lCiAgbXV0YXRlKGJpbl9pbmRlbCA9IGN1dChpbmRlbF9sZW5ndGgsIGJyZWFrcyA9IGMoMCwgMSwgMTAsIEluZiksIGxhYmVscyA9IGMoIlNOUCIsICIyLTEwIiwgIj4xMCIpLCBpbmNsdWRlLmxvd2VzdCA9IFQpKQoKCmNodF9zZWwkbGFiZWwgPSBmYWN0b3IoYWJfdHBfbGFiZWxzW2NodF9zZWwkY29uZGl0aW9uXSwgbGV2ZWxzID0gYWJfdHBfbGFiZWxzKQoKCnAgPSBnZ3Bsb3QoY2h0X3NlbCwgYWVzKHggPSBiaW5faW5kZWwsIHkgPSBBSV9hYnMsIGZpbGwgPSBiaW5faW5kZWwpKSArIAogIGdlb21fYm94cGxvdCh3aWR0aCA9IDAuNiwgb3V0bGllci5zaXplID0gMC4xKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gY2JQYWxldHRlLCBuYW1lID0gIkluZGVsIGxlbmd0aCIpICsKICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAibG9nMiIsIGxpbWl0cyA9IGMoMC4xLCAwLjcpKSArCiAgc3RhdF9jb21wYXJlX21lYW5zKGNvbXBhcmlzb25zID0gbGlzdChjKCJTTlAiLCAiPjEwIiksIGMoIlNOUCIsICIyLTEwIikpKSArCiAgc3RhdF9jb21wYXJlX21lYW5zKCkgKwogIHhsYWIoIiIpICsKICB5bGFiKCJBbGxlbGUgaW1iYWxhbmNlIikgKwogIHRoZW1lX2J3KCkgKwogIGZhY2V0X2dyaWQofmxhYmVsKSArCiAgc3RhdF9zdW1tYXJ5KGZ1bi5kYXRhID0gZnVuY3Rpb24oeCkgYyh5ID0gbWVkaWFuKHgpICsgMC4xLCBsYWJlbCA9IGxlbmd0aCh4KSksIGdlb20gPSAidGV4dCIsIHNpemUgPSA0KSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X2JsYW5rKCksIAogICAgICAgICNheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplPTE2LCBhbmdsZSA9IDQ1LCBoanVzdCA9IDEsIGNvbG9yID0gVEZjb2xzKSwgCiAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZT0xNiksIAogICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplPTE4KSwgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemU9MTYpLAogICAgICAgIHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQpLCBzdHJpcC50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0KSwKICAgICAgICBsZWdlbmQudGV4dD1lbGVtZW50X3RleHQoc2l6ZT0xNiksIGxlZ2VuZC50aXRsZT1lbGVtZW50X3RleHQoc2l6ZT0xNikpCgoKY2h0X3NlbCAlPiUgCiAgZ3JvdXBfYnkoY29uZGl0aW9uKSAlPiUKICBtdXRhdGUoTiA9IG4oKSkgJT4lCiAgZ3JvdXBfYnkoY29uZGl0aW9uLCBiaW5faW5kZWwpICU+JQogIGRwbHlyOjpzdW1tYXJpemUobiA9IG4oKSwgc2hhcmUgPSBuIC8gbWVhbihOKSwgcmVzX3NoYXJlID0gMSAtIHNoYXJlKQoKcAoKb3V0ZiA9IGZpbGUucGF0aChvdXRkaXJfZmlnX3N1cHBsLCBwYXN0ZTAoIkZpZ1MzQl9pbmRlbHNfQUkucGRmIikpCmdnc2F2ZShvdXRmLCBwLCB3aWR0aCA9IDE4LCBoZWlnaHQgPSA1KQoKCmBgYAoKCiMgRmlndXJlIFMzQzogSW5kZWxzIGxlbmd0aAoKYGBge3J9CgpjaHQgPSBsYXBwbHkoYWJfdHBfbGlzdCwgZnVuY3Rpb24oYWJfdHApIGxvYWRfY2h0X3Jlc3VsdHMoYWJfdHApKSAlPiUgYmluZF9yb3dzKCkKY2h0X2dyID0gY2h0ICU+JSBtdXRhdGUoY2hyID0gVEVTVC5TTlAuQ0hST00sIHN0YXJ0ID0gVEVTVC5TTlAuUE9TLCBlbmQgPSBURVNULlNOUC5QT1MpICU+JSBHUmFuZ2VzKCkKCiMgRjEgQVRBQy1zZXEgcmVzdWx0cwoKIyBjb29yZGluYXRlcyBvZiBBVEFDIHBlYWtzCmF0YWNfcmVnaW9uc19wYXRoID0gIi9nL2Z1cmxvbmcvcHJvamVjdC82OF9GMV9jaXNyZWdfaWNoaXAvZGF0YS9GMV9wYXBlcl9tdWx0aW9tL0FUQUNfZmVhdHVyZV9sb2NhdGlvbl9kbTYuYmVkIgphdGFjX3JlZ2lvbnMgPSBpbXBvcnQoYXRhY19yZWdpb25zX3BhdGgsIGZvcm1hdCA9ICJiZWQiKQoKIyBpbWJhbGFuY2UgaW5mbyBmb3IgQVRBQyBwZWFrcwphdGFjX2FpX3BhdGggPSAiL2cvZnVybG9uZy9wcm9qZWN0LzY4X0YxX2Npc3JlZ19pY2hpcC9kYXRhL0YxX3BhcGVyX211bHRpb20vQVRBQ19hbGxfcGVha3NfYXRhY19YLnR4dCIKYXRhY19haSA9IHJlYWQuZGVsaW0oYXRhY19haV9wYXRoKQoKIyBhZGRpdGlvbmFsIGFubm90YXRpb25zIGZvciBhbGxlbGUgaW1iYWxhbmNlCmF0YWNfYWlfc3VtID0gYXRhY19haSAlPiUgCiAgbXV0YXRlKEFJID0gcGFkaiA8IDAuMDEgJiBhYnMoMC41IC0gbWVhbnByb3ApID4gMC4xKSAlPiUKICBncm91cF9ieShmZWF0dXJlLCB0aW1lKSAlPiUgCiAgc3VtbWFyaXplKG5fQUkgPSBzdW0oQUkpLCAKICAgICAgICAgICAgQUlfcGVhayA9IGFueShBSSksCiAgICAgICAgICAgIG1lYW5fQUkgPSBhYnMoMC41IC0gbWVhbihtZWFucHJvcCkpLCAKICAgICAgICAgICAgbWF4X0FJID0gbWF4KGFicygwLjUgLSBtZWFucHJvcCkpLAogICAgICAgICAgICBuX2hldF9saW5lcyA9bigpKQoKIyBjb21iaW5lIEFJSSBpbmZvIHdpdGggcGVhayBjb29yZGluYXRlcwphdGFjX2YxX2RmID0gbWVyZ2UoZGF0YS5mcmFtZShhdGFjX3JlZ2lvbnMpLCBhdGFjX2FpX3N1bSwgYnkueCA9ICJuYW1lIiwgYnkueSA9ICJmZWF0dXJlIikgJT4lIGZpbHRlcighc2VxbmFtZXMgJWluJSBjKCJjaHJYIiwgImNoclkiKSkKYXRhY19haV9nciA9IEdSYW5nZXMoYXRhY19mMV9kZikKCgojIERvIHRoZSBhbmFseXNpcyBwZXIgVEYgYW5kIEFUQUMgdGltZS1wb2ludAoKCmRmID0gZGF0YS5mcmFtZSgpCgpmb3IgKGFiX3RwIGluIGFiX3RwX2xpc3QpIHsKICAKICB0cCA9IGdzdWIoIi0iLCAiIiwgdGltZXBvaW50c1thYl90cF0pCiAgCiAgIyBnZXQgVEYgcGVha3MKICBBSV9wZWFrcyA9IGdldF9wZWFrc19mcm9tX2NodChhYl90cCwgY2h0KQogIG5hbWVzKG1jb2xzKEFJX3BlYWtzKSkgPSBwYXN0ZTAobmFtZXMobWNvbHMoQUlfcGVha3MpKSwgIi50ZiIpCiAgCiAgIyBnZXQgQVRBQyBwZWFrcyBmb3Igc2VsZWN0ZWQgdGltZS1wb2ludAogIEFJX2F0YWMgPSBhdGFjX2FpX2dyW2F0YWNfYWlfZ3IkdGltZSA9PSB0cF0KICBuYW1lcyhtY29scyhBSV9hdGFjKSkgPSBwYXN0ZTAobmFtZXMobWNvbHMoQUlfYXRhYykpLCAiLmF0YWMiKQogIAogIG92ID0gZmluZE92ZXJsYXBzKEFJX3BlYWtzLCBBSV9hdGFjKQogIAogIAogIHJlcyA9IGNiaW5kLmRhdGEuZnJhbWUobWNvbHMoQUlfcGVha3NbcXVlcnlIaXRzKG92KV0pLCBtY29scyhBSV9hdGFjW3N1YmplY3RIaXRzKG92KV0pKQogIAogIHByaW50KGFiX3RwKQogIHd0ID0gd2lsY294LnRlc3QobWVhbl9BSS5hdGFjIH4gQUlfcGVhay50ZiwgcmVzLCBhbHRlcm5hdGl2ZSA9ICJsZXNzIikKICBwcmludCh3dCkKICB3dCA9IHdpbGNveC50ZXN0KG1heF9BSS5hdGFjIH4gQUlfcGVhay50ZiwgcmVzLCBhbHRlcm5hdGl2ZSA9ICJsZXNzIikKICBwcmludCh3dCkKICAKICBkZiA9IHJiaW5kLmRhdGEuZnJhbWUoZGYsIHJlcykKICAKfQoKZGYgJTw+JSAKICBtdXRhdGUobGFiZWwgPSBmYWN0b3IoYWJfdHBfbGFiZWxzW2NvbmRpdGlvbi50Zl0sIGxldmVscyA9IGFiX3RwX2xhYmVscykpCgpkZiAlPiUgZ3JvdXBfYnkoY29uZGl0aW9uLnRmLCBBSV9wZWFrLnRmKSAlPiUKICBzdW1tYXJpemUobWVhbihtZWFuX0FJLmF0YWMsIG1lYW4obWF4X0FJLmF0YWMpKSkKCnAgPSBnZ3Bsb3QoZGYsIGFlcyh4ID0gQUlfcGVhay50ZiwgIHkgPSBtYXhfQUkuYXRhYykpICsKICBnZW9tX3Zpb2xpbihmaWxsID0gImRhcmtibHVlIiwgYWxwaGEgPSAwLjMpICsKICBnZW9tX2JveHBsb3Qod2lkdGggPSAwLjQsIG91dGxpZXIuc2l6ZSA9IDAuMSwgZmlsbCA9ICJkYXJrYmx1ZSIsIGFscGhhID0gMC43KSArCiAgZmFjZXRfd3JhcCh+IGxhYmVsLCBuY29sID0gMykgKwogIHRoZW1lX2J3KCkgKwogIHN0YXRfY29tcGFyZV9tZWFucygpICsKICB4bGFiKCJBSSBURiBwZWFrcyAoRjEpIikgKwogIHlsYWIoIkFsbGVsZSBpbWJhbGFuY2Ugb2YgQVRBQyBwZWFrcyAoRjEpIikgKwogIHRoZW1lKGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemU9MTIpLCBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplPTEyKSwgCiAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemU9MTYpLCBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZT0xNiksCiAgICAgICAgc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCksIHN0cmlwLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQpKQoKcHJpbnQocCkKZ2dzYXZlKGZpbGUucGF0aChvdXRkaXJfZmlnX3N1cHBsLCAiRmlnUzNDX0FJX0FUQUNfYnlfVEYucGRmIiksIHAsIHdpZHRoID0gOSwgaGVpZ2h0ID0gNikKCmBgYAoKCgoKIyBGaWd1cmUgUzNECgpgYGB7cn0KCiMgb25seSBxdWFudGlmaWVkIHBlYWtzIGZvciBDSFQKI3BlYWtzID0gbGFwcGx5KGFiX3RwX2xpc3QsIGZ1bmN0aW9uKGFiX3RwKSBnZXRfcGVha3NfZnJvbV9jaHQoYWJfdHAsIGNodCwgYXNfZ3JhbmdlcyA9IFQpKQojbmFtZXMocGVha3MpID0gYWJfdHBfbGlzdAoKcGVha3MgPSBnZXRfY29uc2Vuc3VzX3BlYWtzZXRzX3dpdGhfQUkoYWJfdHBfbGlzdCwgY2h0LCBmaWx0ZXIgPSBGKQoKZGhzID0gbG9hZF9kaHMoKSAlPiUgR1JhbmdlcygpCmRocyRESFNjb25kID0gY3V0KGRocyRudW1fY29uZGl0aW9ucywgYnJlYWtzID0gYygxLCAyLCAxNywgMTkpLCBpbmNsdWRlLmxvd2VzdCA9IFQpCmRocyRESFNfbW9kRVJOID0gY3V0KGRocyRudW1fbW9kRVJOLGJyZWFrcyA9IGMoMCwgOSwgMjUxKSwgaW5jbHVkZS5sb3dlc3QgPSBUKQoKCnJlcyA9IGxhcHBseShjKCJkaXN0YWwiLCAicHJveGltYWwiKSwgZnVuY3Rpb24oVFNTX3R5cGUpIHsKCiAgZGhzX2dyID0gZGhzICU+JSBhcy5kYXRhLmZyYW1lKCkgJT4lIGZpbHRlcihUU1MgPT0gVFNTX3R5cGUpICU+JSBHUmFuZ2VzKCkKICAKICAjIERIUyBjb25kaXRpb25zCiAgZGYgPSBsYXBwbHkocGVha3MsIGZ1bmN0aW9uKHgpIHtvdiA9IGZpbmRPdmVybGFwcyh4LCBkaHNfZ3IpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2JpbmQuZGF0YS5mcmFtZShhcy5kYXRhLmZyYW1lKHhbcXVlcnlIaXRzKG92KV0pLCBhcy5kYXRhLmZyYW1lKGRoc19ncltzdWJqZWN0SGl0cyhvdildKSkgfSkgJT4lCiAgICAgICAgICAgIGJpbmRfcm93cygpCiAgCiAgZnRzMSA9IGxhcHBseShhYl90cF9saXN0LCBmdW5jdGlvbihhYl90cCkge2Zpc2hlcl90ZXN0X3R3b19ncm91cHMoZGYsIGFiX3RwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwMSA9ICJpc0FJIiwgZ3JvdXAxX3ZhbCA9IGMoVFJVRSwgRkFMU0UpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncm91cDIgPSAiREhTY29uZCIsIGdyb3VwMl92YWwgPSBjKCJbMSwyXSIsICIoMTcsMTldIikpfSkgJT4lCiAgICAgICAgICAgIGJpbmRfcm93cygpICU+JSBtdXRhdGUoY29tcCA9ICJESFMgY29uZGl0aW9uc1xuKDEtMiB2cy4gMTgtMTkpIiwgbGFiZWxzID0gYWJfdHBfbGFiZWxzKQogIAogICMgbW9kRVJOIFRGcwogIGZ0czIgPSBsYXBwbHkoYWJfdHBfbGlzdCwgZnVuY3Rpb24oYWJfdHApIHtmaXNoZXJfdGVzdF90d29fZ3JvdXBzKGRmLCBhYl90cCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncm91cDEgPSAiaXNBSSIsIGdyb3VwMV92YWwgPSBjKFRSVUUsIEZBTFNFKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXAyID0gIkRIU19tb2RFUk4iLCBncm91cDJfdmFsID0gYygiKDksMjUxXSIsICJbMCw5XSIpKX0pICU+JQogICAgICAgICAgICBiaW5kX3Jvd3MoKSAlPiUgbXV0YXRlKGNvbXAgPSAibW9kRVJOIFRGc1xuKDMxLTI1MSB2cy4gMC01KSIsIGxhYmVscyA9IGFiX3RwX2xhYmVscykKICAKICAKICByZXMgPSByYmluZC5kYXRhLmZyYW1lKGZ0czEsIGZ0czIpICU+JSBtdXRhdGUoVFNTX3R5cGUgPSBwYXN0ZSgiVFNTIiwgVFNTX3R5cGUpKSAKICAKICAKfSkgJT4lIGJpbmRfcm93cygpCgoKIyBNb2RFUk4gVEZzCgpkZiA9IHJlcyAlPiUgZmlsdGVyKGNvbXAyID09ICJESFNfbW9kRVJOXyg5LDI1MV1fdnNfWzAsOV0iKSAKZGYkbGFiZWwgPSBhYl90cF9sYWJlbHMKZGYkbGFiZWwgPSBmYWN0b3IoZGYkbGFiZWwsIGxldmVscyA9IGFiX3RwX2xhYmVscykKCnAgPSBnZ3Bsb3QoZGYsIGFlcyh4ID0gbGFiZWwsIHkgPSBvZGRzX3JhdGlvKSkgKwogIGZhY2V0X3dyYXAoflRTU190eXBlKSArCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMSwgY29sb3IgPSAiZGFya3JlZCIpICsKICBnZW9tX2JhcihhZXMoZmlsbCA9IC1sb2cxMChwdmFsKSksIGNvbG9yID0gImRhcmtibHVlIiwgc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gImRvZGdlIiwgd2lkdGggPSAwLjUpICsKICAjc2NhbGVfZmlsbF9tYW51YWwobmFtZSA9ICIiLCB2YWx1ZXMgPSBjKCJkYXJrYmx1ZSIsICJkYXJrZ3JleSIpLCBsYWJlbHMgPSBjKCJBSSBwZWFrcyIsICJub24tQUkgcGVha3MiKSkgKwogIGdlb21fdGV4dChhZXMobGFiZWwgPSByb3VuZChyMSwgMiksIHggPSBsYWJlbCwgeSA9IG9kZHNfcmF0aW8gKyAwLjA1KSwgZGF0YSA9IGRmLCBzaXplID0gNikgKwogIHlsYWIoIkRlcGxldGlvaW4gaW4gdWJpcXVpdG91c2x5IGJvdW5kIHJlZ2lvbnMgKD4xMCBtb2RFUk4gVEZzKSBcbkZpc2hlcidzIFRlc3QgT2RkcyBSYXRpbyIpICsKICB0aGVtZV9idygpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQsIGFuZ2xlID0gNDUsIGhqdXN0ID0gMSwgY29sb3VyID0gVEZjb2xzKSwKICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLCAKICAgICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCksCiAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xNCksCiAgICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MTQpKQoKCnAKCm91dGYgPSBmaWxlLnBhdGgob3V0ZGlyX2ZpZ19zdXBwbCwgcGFzdGUwKCJGaWdTM0RfbW9kRVJOX2Zpc2hlci5wZGYiKSkKZ2dzYXZlKG91dGYsIHAsIHdpZHRoID0gMTAsIGhlaWdodCA9IDYpCgpgYGAKCgoKIyBGaWd1cmUgUzNFCgoKYGBge3J9CmRmID0gcmVzICU+JSBmaWx0ZXIoY29tcDIgPT0gIkRIU2NvbmRfWzEsMl1fdnNfKDE3LDE5XSIpIApkZiRsYWJlbCA9IGFiX3RwX2xhYmVscwpkZiRsYWJlbCA9IGZhY3RvcihkZiRsYWJlbCwgbGV2ZWxzID0gYWJfdHBfbGFiZWxzKQoKCgpwID0gZ2dwbG90KGRmLCBhZXMoeCA9IGxhYmVsLCB5ID0gb2Rkc19yYXRpbykpICsKICBmYWNldF93cmFwKH5UU1NfdHlwZSkgKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDEsIGNvbG9yID0gImRhcmtyZWQiKSArCiAgZ2VvbV9iYXIoYWVzKGZpbGwgPSAtbG9nMTAocHZhbCkpLCBjb2xvciA9ICJkYXJrYmx1ZSIsIHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJkb2RnZSIsIHdpZHRoID0gMC41KSArCiAgI3NjYWxlX2ZpbGxfbWFudWFsKG5hbWUgPSAiIiwgdmFsdWVzID0gYygiZGFya2JsdWUiLCAiZGFya2dyZXkiKSwgbGFiZWxzID0gYygiQUkgcGVha3MiLCAibm9uLUFJIHBlYWtzIikpICsKICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcm91bmQocjEsIDIpLCB4ID0gbGFiZWwsIHkgPSBvZGRzX3JhdGlvICsgMC4wNyksIGRhdGEgPSBkZiwgc2l6ZSA9IDYpICsKICB5bGFiKCJFbnJpY2htZW50IGluIGNvbmRpdGlvbi1zcGVjaWZpYyBESFMgXG5GaXNoZXIncyBUZXN0IE9kZHMgUmF0aW8iKSArCiAgdGhlbWVfYncoKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0LCBhbmdsZSA9IDQ1LCBoanVzdCA9IDEsIGNvbG91ciA9IFRGY29scyksCiAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwgCiAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTYpLAogICAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTQpLAogICAgICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTE0KSkKCgpwCgpvdXRmID0gZmlsZS5wYXRoKG91dGRpcl9maWdfc3VwcGwsIHBhc3RlMCgiRmlnUzNFX25vbnViaXFESFNfZmlzaGVyLnBkZiIpKQpnZ3NhdmUob3V0ZiwgcCwgd2lkdGggPSAxMCwgaGVpZ2h0ID0gNikKCgoKYGBgCgoKCiMgRmlndXJlIFMzRiAtIEdPIEVucmljaG1lbnQgZm9yIEFJIHBlYWtzCgpgYGB7cn0KZm9yIChjb25kIGluIGMoYWJfdHBfbGlzdCwgbGlzdChhYl90cF9saXN0KSkpIHsKICAKICAgIHRlc3RfZ2VuZUlEID0gZ2V0X3Rlc3RfZ2VuZUlEKGNodCwgY29uZCwgMTAwMCkKICAgIGJhY2tncm91bmRfZ2VuZUlEID0gZ2V0X2JhY2tncm91bmRfZ2VuZUlEKGNodCwgY29uZCwgMTAwMCwgdGVzdF9nZW5lSUQpCgogICAgb3V0ID0gY3JlYXRlX0dPZGF0YSh0ZXN0X2dlbmVJRCwgYmFja2dyb3VuZF9nZW5lSUQsICJCUCIpCiAgICBHT2RhdGEgPSBvdXRbWzFdXQogICAgdGVzdCA9IG91dFtbMl1dCiAgICBuX25vZGVzID0gbGVuZ3RoKGF0dHJpYnV0ZXMoR09kYXRhKSRncmFwaEBub2RlcykKCiAgICAjIENsYXNzaWMgRmlzaGVyIHRlc3QKICAgIHRlc3Quc3RhdCA8LSBuZXcoImNsYXNzaWNDb3VudCIsIHRlc3RTdGF0aXN0aWMgPSBHT0Zpc2hlclRlc3QsIG5hbWUgPSAiRmlzaGVyIHRlc3QiKQogICAgcmVzdWx0RmlzaGVyIDwtIGdldFNpZ0dyb3VwcyhHT2RhdGEsIHRlc3Quc3RhdCkKCiAgICAjIEtTIHRlc3QKICAgIHRlc3Quc3RhdCA8LSBuZXcoImNsYXNzaWNTY29yZSIsIHRlc3RTdGF0aXN0aWMgPSBHT0tTVGVzdCwgbmFtZSA9ICJLUyB0ZXN0cyIpCiAgICByZXN1bHRLUyA8LSBnZXRTaWdHcm91cHMoR09kYXRhLCB0ZXN0LnN0YXQpCgogICAgIyBXZWlnaHQgYWxnb3JpdGhtCiAgICB0ZXN0LnN0YXQgPC0gbmV3KCJ3ZWlnaHRDb3VudCIsIHRlc3RTdGF0aXN0aWMgPSBHT0Zpc2hlclRlc3QsIG5hbWUgPSAiRmlzaGVyIHRlc3QiLCBzaWdSYXRpbyA9ICJyYXRpbyIpCiAgICByZXN1bHRXZWlnaHQgPC0gZ2V0U2lnR3JvdXBzKEdPZGF0YSwgdGVzdC5zdGF0KQogICAgCiAgICBhbGxSZXMgPC0gR2VuVGFibGUoR09kYXRhLCBjbGFzc2ljID0gcmVzdWx0RmlzaGVyLCAKICAgICAgICAgICBLUyA9IHJlc3VsdEtTLCB3ZWlnaHQgPSByZXN1bHRXZWlnaHQsCiAgICAgICAgICAgb3JkZXJCeSA9ICJ3ZWlnaHQiLCByYW5rc09mID0gImNsYXNzaWMiLCB0b3BOb2RlcyA9IG5fbm9kZXMpCiAgICBhbGxSZXMkRm9sZF9FbnJpY2htZW50ID0gYWxsUmVzJFNpZ25pZmljYW50IC8gYWxsUmVzJEV4cGVjdGVkCiAgICBhbGxSZXMkRkRSID0gYWxsUmVzJHdlaWdodAogICAgCiAgICB0b3BfcmVzdWx0cyA9IHNlbGVjdF90b3BfR08oYWxsUmVzLCA1MDAsIDEwLCAwLjA1LCAxMCkgCgogICAgcCA9IGdncGxvdF9HT19lbnJpY2htZW50KHRvcF9yZXN1bHRzLCBucm93KGFzLmRhdGEuZnJhbWUodGVzdCkpLCBsZW5ndGgoYXMuZGF0YS5mcmFtZSh0ZXN0KVthcy5kYXRhLmZyYW1lKHRlc3QpWywxXSA9PSAxLCBdKSwgY29uZCkKICAgIHByaW50KHApCiAgICBvdXRfZmlsZW5hbWUgPSBwYXN0ZTAoIkZpZ1MzRl9HT19lbnJpY2htZW50X0FJX3BlYWtzXyIsIGdzdWIoIi8iLCAiXyIsIHBhc3RlKGNvbmQsIGNvbGxhcHNlID0gJ18nKSkgLCIucGRmIikKICAgIGdnc2F2ZShmaWxlLnBhdGgob3V0ZGlyX2ZpZ19zdXBwbCwgb3V0X2ZpbGVuYW1lKSwgcCwgd2lkdGggPSA2LCBoZWlnaHQgPSA2KQp9CmBgYAoKCiMgRmlndXJlIFMzRyAtIFBoeWxvUCBlbnJpY2htZW50IAoKCmBgYHtyfQoKcGh5bG9QID0gaW1wb3J0LmJ3KGNvbmZpZyRkYXRhJGdlbm9tZSRkbTYkcGh5bG9QMTI0KQpwZWFrc19jaHQgPSB1bmlxdWUoZGF0YS5mcmFtZSgiY2hyIj1jaHQkVEVTVC5TTlAuQ0hST00sICJzdGFydCI9Y2h0JFJFR0lPTi5TVEFSVCwgImVuZCI9Y2h0JFJFR0lPTi5FTkQsICJzZXFpbmZvIj1jaHQkcGVha19pZCwgInNpZ25pZiI9Y2h0JHNpZ25pZl9zdHJvbmdBSSwgImNvbmQiPWNodCRjb25kKSkKcGVha3NfY2h0X0dSYW5nZSA9IEdSYW5nZXMocGVha3NfY2h0KQpvdiA9IGZpbmRPdmVybGFwcyhwZWFrc19jaHRfR1JhbmdlLCBwaHlsb1ApCmNodF9wZWFrc19waHlsbyA9ICBjYmluZChhcy5kYXRhLmZyYW1lKHBlYWtzX2NodF9HUmFuZ2UpW2FzLmRhdGEuZnJhbWUob3YpJHF1ZXJ5SGl0cywgXSwgYXMuZGF0YS5mcmFtZShwaHlsb1ApW2FzLmRhdGEuZnJhbWUob3YpJHN1YmplY3RIaXRzLCBdKQpjb2xuYW1lcyhjaHRfcGVha3NfcGh5bG8pID0gYygicGVha19jaHIiLCAicGVha3Nfc3RhcnQiLCAicGVha19lbmQiLCAicGVha3Nfd2lkdGgiLCAicGVha19zdHJhbmQiLCAic2VxaW5mbyIsICAic2lnbmlmIiwgImNvbmQiLCAic2VxbmFtZXMiLCAic3RhcnQiLCAgImVuZCIsICJ3aWR0aCIsICJzdHJhbmQiLCAic2NvcmUiKQoKY2h0X3BlYWtzX3BoeWxvX21lYW4gPSBjaHRfcGVha3NfcGh5bG8gJT4lCiAgZHBseXI6Om11dGF0ZSh3ZWlnaHRlZF9waHlsb3AgPSBzY29yZSAqIHdpZHRoKSAlPiUKICBkcGx5cjo6c2VsZWN0KHNlcWluZm8sIHNjb3JlLCB3ZWlnaHRlZF9waHlsb3AsIHBlYWtzX3dpZHRoLCBzaWduaWYsIGNvbmQpICU+JQogIGRwbHlyOjpncm91cF9ieShzZXFpbmZvLCBzaWduaWYsIGNvbmQpICU+JQogIGRwbHlyOjpzdW1tYXJpemUocGh5bG9wID0gc3VtKHdlaWdodGVkX3BoeWxvcCkgLyBtZWFuKHBlYWtzX3dpZHRoKSkKICAgICAgICAgICAgICAKCmNodF9wZWFrc19waHlsb19tZWFuJHNpZ25pZiA9IGZhY3Rvcihnc3ViKFRSVUUsICJBSSBwZWFrIiwgZ3N1YihGQUxTRSwgIm5vIEFJIiwgY2h0X3BlYWtzX3BoeWxvX21lYW4kc2lnbmlmKSksIGxldmVscz1jKCJBSSBwZWFrIiwgIm5vIEFJIikpCmNodF9wZWFrc19waHlsb19tZWFuJGNvbmQgPSBmYWN0b3IoY2h0X3BlYWtzX3BoeWxvX21lYW4kY29uZCwgbGV2ZWxzPWMoInR3aS8yNCIsICJjdGNmLzY4IiwgIm1lZjIvNjgiLCAibWVmMi8xMDEyIiwgImJpbi82OCIsICAiYmluLzEwMTIiKSkKClN1bW1hcnlfZGF0YSA9IGNodF9wZWFrc19waHlsb19tZWFuICU+JSAgZ3JvdXBfYnkoc2lnbmlmKSAlPiUgc3VtbWFyaXNlKG49bigpKSAKCnAgPSBnZ3Bsb3QoY2h0X3BlYWtzX3BoeWxvX21lYW4sIGFlcyh4PXNpZ25pZiwgeT1waHlsb3AsIGZpbGw9c2lnbmlmKSkgKwogICAgZ2VvbV92aW9saW4oKSArCiAgICBnZW9tX2JveHBsb3Qod2lkdGg9MC4xLCBmaWxsPSJ3aGl0ZSIsIGFscGhhPTAuNSkgKwogICAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygib3JhbmdlMiIsICJncmV5NDAiKSkgKwogICAgc3RhdF9jb21wYXJlX21lYW5zKGNvbXBhcmlzb25zID0gbGlzdChjKCJBSSBwZWFrIiwgIm5vIEFJIikpLCBsYWJlbC55PTUpICsKICAgIGdlb21fdGV4dChkYXRhPVN1bW1hcnlfZGF0YSAsYWVzKHggPSBzaWduaWYsIHkgPSAtMC42LCBsYWJlbD1uKSxjb2xvcj0iZ3JleTI1IiwgZm9udGZhY2UgPSAyLCBzaXplID0gMy41KSArCiAgICB5bGltKC0xLDYpICsKICAgIHhsYWIoIkFJIFBlYWtzIHZzIG5vbiBBSSBwZWFrcyIpICsKICAgIHlsYWIoIlBoeWxvUCBhdmVyYWdlIHNjb3JlIG9uIHBlYWsiKSArCiAgICB0aGVtZV9idygpICsgCiAgICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSArCiAgICB0aGVtZShwYW5lbC5ncmlkID0gZWxlbWVudF9saW5lKGNvbG91ciA9ICJncmV5ODAiLCBsaW5ld2lkdGggPSAxKSwgYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSA5KSkgKwogICAgdGhlbWUoYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gOSksIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT05KSkgKwogICAgdGhlbWUoc3RyaXAudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTkpKSArCiAgICB0aGVtZShwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aCA9IDAuMjUpLCBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aCA9IDAuNSkpIAojICAgICBmYWNldF93cmFwKH5jb25kKSsKCnByaW50KHApCmdnc2F2ZShmaWxlLnBhdGgob3V0ZGlyX2ZpZ19zdXBwbCwgIkZpZ1MzR19waHlsb1BfY29uc2VydmF0aW9uX3NpZ25fcGVha3MucGRmIiksIHAsIHdpZHRoID0gNiwgaGVpZ2h0ID0gNikKYGBgCgoKCgoKCg==