Overall observations

Any associations with dieldrin loss?

Which microorganisms can be associated with this?

Is this associated with Soil organic matter decomposition?

How does this relate to known xenobiotic degradation pathways/enzymes?

What are the limitations of picrust predictions?

Metadata

[1] 11313798
`set.seed(TRUE)` was used to initialize repeatable random subsampling.
Please record this for your records so others can reproduce.
Try `set.seed(TRUE); .Random.seed` for the full vector
...
1OTUs were removed because they are no longer 
present in any sample after random subsampling

...

Phyloseq objects

ps object for KO metagenome

physeq
phyloseq-class experiment-level object
otu_table()   OTU Table:         [ 6728 taxa and 36 samples ]
sample_data() Sample Data:       [ 36 samples by 77 sample variables ]

ps object for the pathway file

phyloseq-class experiment-level object
otu_table()   OTU Table:         [ 168 taxa and 36 samples ]
sample_data() Sample Data:       [ 36 samples by 77 sample variables ]

KO_METAGENOME PCA plots and correlation tables.

PCA Aitchison biplot on KO predictions and correlations of axis-scores with environmental variables and significant features

PCA will reduce the noise and spits out only relevant variation into independant axes. The question then is what drives the variation of these axis, i.e. the variation in enzymes as predicted by picrust2 and which enzyme are driven more or less in these axis.

clr tranform of metagenome predictions

(ps_clr <- microbiome::transform(physeq, "clr"))  
phyloseq-class experiment-level object
otu_table()   OTU Table:         [ 6728 taxa and 36 samples ]
sample_data() Sample Data:       [ 36 samples by 77 sample variables ]
phyloseq::otu_table(ps_clr)[1:5, 1:6]
OTU Table:          [5 taxa and 6 samples]
                     taxa are rows
               C-1       C-10       C-11       C-12       C-13       C-14
K00001  3.08232112  3.4835033  3.1461450  3.4613316  3.5909267  3.5909645
K00002 -0.66688751 -1.7160013 -6.9421413 -6.7524959 -6.6424699 -6.6426013
K00003  3.73985162  4.2517402  4.0085975  4.1580456  4.2861852  4.2783313
K00004  0.03585803 -0.2907328 -0.3148322  0.2894002 -0.1249358 -0.2936201
K00005 -0.61196184 -3.7181646 -1.0426408 -2.7843547 -2.0381677 -1.5851315

PCA via phyloseq

ord_clr <- phyloseq::ordinate(ps_clr, "RDA")
#Examine eigenvalues and % prop. variance explained
  head(ord_clr$CA$eig)
      PC1       PC2       PC3       PC4       PC5       PC6 
1182.4395  905.7623  579.1140  454.5662  412.6621  390.8011 
sapply(ord_clr$CA$eig[1:8], function(x) x / sum(ord_clr$CA$eig))
       PC1        PC2        PC3        PC4        PC5        PC6        PC7        PC8 
0.16245723 0.12444411 0.07956539 0.06245356 0.05669630 0.05369278 0.04501448 0.03858885 

Correlations to PC1, PC2 and PC3 (with BH corrected p-values)

adding the pc scores to metadata

Correlations with psych package, selecting the relevant variables

Filtering of significant correlations

KOs contributing to the variation in PC1, PC2 and PC3

ind.coord <- data.frame(ord_clr$CA$v)
sdev_ind <- apply(ind.coord, 1, sd)
ind_cont_PCA1 <- data.frame(PCA = (100*(1 / nrow(ind.coord)*(ind.coord$PC1^2 /sdev_ind))))
ind_cont_PCA1_top <- ind_cont_PCA1 %>% 
  rownames_to_column("otu") %>% 
  filter(PCA >= 0.001803355)%>% 
  column_to_rownames("otu")
ind_cont_PCA2 <- data.frame(PCA = (100*(1 / nrow(ind.coord)*(ind.coord$PC2^2 /sdev_ind))))
ind_cont_PCA2_top <- ind_cont_PCA2 %>% 
  rownames_to_column("otu") %>% 
  filter(PCA >= 0.002)%>% 
  column_to_rownames("otu")
ind_cont_PCA3 <- data.frame(PCA = (100*(1 / nrow(ind.coord)*(ind.coord$PC3^2 / sdev_ind))))
ind_cont_PCA3_top <- ind_cont_PCA3 %>% 
  rownames_to_column("otu") %>% 
  filter(PCA >= 0.002)%>% 
  column_to_rownames("otu")
ind_cont_PCA_top <- rbind(ind_cont_PCA1_top, ind_cont_PCA2_top, ind_cont_PCA3_top)

Visualisation of PCA for KO metagenome

sum(ind_cont_PCA1_top$PCA) / sum(ind_cont_PCA1$PCA)
[1] 0.01260249
nrow(ind_cont_PCA1_top)
[1] 8
ind_cont_PCA1_top %>% rownames_to_column() %>% arrange(desc(PCA))

The top 8 KOs contribute 1.2% of the total variation of PC1

sum(ind_cont_PCA2_top$PCA) / sum(ind_cont_PCA2$PCA)
[1] 0.03741334
nrow(ind_cont_PCA2_top)
[1] 17
ind_cont_PCA2_top  %>% rownames_to_column() %>% arrange(desc(PCA))

17 KOs contributed 3.7% of the variation of PC2

sum(ind_cont_PCA3_top$PCA) / sum(ind_cont_PCA3$PCA)
[1] 0.1691838
nrow(ind_cont_PCA3_top)
[1] 49
ind_cont_PCA3_top  %>% rownames_to_column() %>% arrange(desc(PCA))

49 KOs contribute 17% of the variation

One more: Lets test which KO-predictions (clr transformed) signicantly correlate to dieldrin loss - and graph those

pre-filtering the clr-transformed KO predictions that correlate with Dloss
(Spearman, bonferroni corrected p-values)

There were 55 significantly correlated KOs when running aldex.cor with Dloss as variable (BH p <= 0.02)?

Why Aldex? Anova-Like Differential Expression for high throughput data (Aldex), taking sample variation into account.

How many of those were also top contributers to PC1, PC2 or PC3?

ind_cont_PCA_top  %>% rownames_to_column(var = "pathway") %>% 
  subset(pathway %in% as.vector(alx.cor.sig_KO_metagenome_dloss$rowname))
NA

How many of those match the spearman correlations?

spearman.corr scatterplots

Aldex.corr scatterplots

KEGG pathway PCA plot (from KO metagenome mapping)

latest openly available KEGG mapping file is from 2011

clr transform

(ps_clr.pw <- microbiome::transform(physeq.pw, "clr"))  
phyloseq-class experiment-level object
otu_table()   OTU Table:         [ 168 taxa and 36 samples ]
sample_data() Sample Data:       [ 36 samples by 77 sample variables ]
phyloseq::otu_table(ps_clr.pw)[1:6, 1:6]
OTU Table:          [6 taxa and 6 samples]
                     taxa are rows
                                              C-1     C-10     C-11     C-12     C-13     C-14
Glycolysis / Gluconeogenesis             1.984978 1.893012 1.909584 2.007376 1.977939 1.898468
Citrate cycle (TCA cycle)                2.271239 2.216183 2.238249 2.327457 2.284068 2.204037
Pentose phosphate pathway                2.226468 2.125080 2.168618 2.247038 2.247256 2.171432
Pentose and glucuronate interconversions 1.485162 1.389241 1.403059 1.496271 1.499278 1.431174
Fructose and mannose metabolism          1.414391 1.318097 1.352803 1.423055 1.410451 1.326772
Galactose metabolism                     1.573259 1.435351 1.469676 1.567618 1.576223 1.505246

PCA via phyloseq


ord_clr.pw <- phyloseq::ordinate(ps_clr.pw, "RDA")
#Examine eigenvalues and % prop. variance explained
  head(ord_clr.pw$CA$eig)
     PC1      PC2      PC3      PC4      PC5      PC6 
36.15911 24.84179 20.38784 17.94773 15.36852 10.85460 
sapply(ord_clr.pw$CA$eig[1:8], function(x) x / sum(ord_clr.pw$CA$eig))
       PC1        PC2        PC3        PC4        PC5        PC6        PC7        PC8 
0.20981354 0.14414472 0.11830063 0.10414188 0.08917596 0.06298389 0.04099468 0.03906864 

Correlations of soil variables to PC1, PC2 and PC3 (with BH corrected p-values)

Joining, by = "#SampleID"

CN correlations with other soil variables (comparing 36 soil variables, BH p < 0.05)

r_table.Var1 r_table.Var2 r_table.value p_table.value
CN Dloss -0.9207945 0.0000000
CN ParticulateC -0.8295257 0.0000003
CN Delta.C.Frac 0.8243774 0.0000004
CN Gibbsite% 0.7344102 0.0002205
CN ResistantC 0.7300341 0.0002795
TC CN 0.7284896 0.0003034
CN Illite% -0.7277174 0.0003158
D1517 CN 0.7260847 0.0003442
CN CP 0.6827981 0.0028120
CN Organic Matter 0.6824120 0.0028520
CN Silt_1 -0.6808675 0.0030456
TN CN 0.6269714 0.0257867
pc1 CN 0.6228200 0.0297277
CN C_Sand 0.6102066 0.0458238

PCA plot for KEGG pathways

Pathways contributing to the variation in PC1, PC2 and PC3



ind.coord.pw <- data.frame(ord_clr.pw$CA$v)
sdev_ind.pw <- apply(ind.coord.pw, 1, sd)
ind_cont_PCA1.pw <- data.frame(PCA = (100*(1 / nrow(ind.coord.pw)*(ind.coord.pw$PC1^2 /sdev_ind.pw))))
ind_cont_PCA1_top.pw <- ind_cont_PCA1.pw %>% 
  rownames_to_column("otu") %>% 
  filter(PCA >= 0.008)%>% 
  column_to_rownames("otu")
ind_cont_PCA2.pw <- data.frame(PCA = (100*(1 / nrow(ind.coord.pw)*(ind.coord.pw$PC2^2 /sdev_ind.pw))))
ind_cont_PCA2_top.pw <- ind_cont_PCA2.pw %>% 
  rownames_to_column("otu") %>% 
  filter(PCA >= 0.02)%>% 
  column_to_rownames("otu")
ind_cont_PCA3.pw <- data.frame(PCA = (100*(1 / nrow(ind.coord.pw)*(ind.coord.pw$PC3^2 / sdev_ind.pw))))
ind_cont_PCA3_top.pw <- ind_cont_PCA3.pw %>% 
  rownames_to_column("otu") %>% 
  filter(PCA >= 0.03)%>% 
  column_to_rownames("otu")
ind_cont_PCA_top.pw <- rbind(ind_cont_PCA1_top.pw, ind_cont_PCA2_top.pw, ind_cont_PCA3_top.pw)
# plot showing pathways that are contributing the most
clr1.pw <- ord_clr.pw$CA$eig[1] / sum(ord_clr.pw$CA$eig)
clr2.pw <- ord_clr.pw$CA$eig[2] / sum(ord_clr.pw$CA$eig)
p1.2 <- phyloseq::plot_ordination(ps_clr.pw, ord_clr.pw, type="taxa") +
    coord_fixed(clr2.pw / clr1.pw) +
  ggtitle("PCA on picrust predictions", subtitle = "(centred-log ratio)")
No available covariate data to map on the points for this plot `type`
p1.2$data <-  p1.2$data  %>% rownames_to_column(var = "OTU") %>%  filter(OTU %in% rownames(ind_cont_PCA_top.pw))
require(ggrepel)
p1.2 + geom_text_repel(label = p1.2$data$OTU) +
    coord_fixed(xlim = c(-2.5,2.5)) 
Coordinate system already present. Adding new coordinate system, which will replace the existing one.

sum(ind_cont_PCA1_top.pw$PCA) / sum(ind_cont_PCA1.pw$PCA)
[1] 0.8614549
nrow(ind_cont_PCA1_top.pw)
[1] 30
ind_cont_PCA1_top.pw %>% rownames_to_column() %>% arrange(desc(PCA))

30 pathways contribute 86% of the variation to PC1

sum(ind_cont_PCA2_top.pw$PCA) / sum(ind_cont_PCA2.pw$PCA)
[1] 0.9238069
nrow(ind_cont_PCA2_top.pw)
[1] 14
ind_cont_PCA2_top.pw  %>% rownames_to_column() %>% arrange(desc(PCA))

14 pathways contribute 92% of the variation to PC2

sum(ind_cont_PCA3_top.pw$PCA) / sum(ind_cont_PCA3.pw$PCA)
[1] 0.9430541
nrow(ind_cont_PCA3_top.pw)
[1] 12
ind_cont_PCA3_top.pw %>% rownames_to_column() %>% arrange(desc(PCA))

12 pathways contribute 94% of variation of PC3

Pathway (clr transformed) correlations with dieldrin loss

pre-filtering the clr-transformed pathway predictions that correlate with Dloss
(Spearman, bonferroni corrected p-values)

The novobiocin biosynthesis and the pathway for x-membered macrolides were also identified as signifiant using the aldex package with function aldex.corr

In total there were 17 significant pathways (BH < 0.1) based on aldex.corr

(Dieldrin concentrations were not significantly associated with any pathways (aldex.corr), only dieldrin loss)

X1 rowname r p BH
10 Nitrotoluene degradation -3.939458 0.0007508 0.0282023
13 Caprolactam degradation -3.882228 0.0010714 0.0308874
5 Novobiocin biosynthesis 3.571833 0.0019547 0.0346315
14 Isoflavonoid biosynthesis 3.585446 0.0025726 0.0351884
9 Aminobenzoate degradation -3.650042 0.0020745 0.0383916
11 Styrene degradation -3.585659 0.0022433 0.0397478
7 Xylene degradation -3.407035 0.0026174 0.0421643
4 Bisphenol degradation -3.351442 0.0034821 0.0483770
8 Polycyclic aromatic hydrocarbon degradation -3.271920 0.0049180 0.0554459
1 Geraniol degradation -3.283802 0.0049243 0.0576555
3 Benzoate degradation -3.121054 0.0076213 0.0714633
16 Basal transcription factors 2.912020 0.0087980 0.0718041
12 Limonene and pinene degradation -3.058269 0.0079924 0.0741012
6 Biosynthesis of 12-, 14- and 16-membered macrolides 3.228308 0.0121400 0.0759852
2 Chlorocyclohexane and chlorobenzene degradation -2.934814 0.0116668 0.0900326
15 ABC transporters -2.877058 0.0126350 0.0949811
17 Spliceosome 3.330436 0.0246215 0.0952889

boxplots of degradation pathways

boxplots of remaining pathways

How many of those pathways are also associated with PC1, PC2 or PC3?

ind_cont_PCA_top.pw  %>% rownames_to_column(var = "pathway") %>% 
  subset(pathway %in% as.vector(alx.cor.sig$rowname))

Ancom significant different pathways by soil

Ancom

Aldex (aldex.clr(aldex.df, cond, mc.samples=10000, denom=“iqlr”, verbose=F) to find significant different pathways for each soil (29 pathways p <= 0.01 BH corrected)

LS0tCnRpdGxlOiAiUGljcnVzdDIgZG93bnN0cmVhbSBzdHVmZiIKc3VidGl0bGU6ICJLTyBtZXRhZ2Vub21lIGFuZCBLRUdHIHBhdGh3YXlzLiBQb29sIG9mIHJlc3VsdHMgYW5kIHNvbWUgb3ZlcmFsbCBvYnNlcnZhdGlvbnMgKHRoaXMgaXMgZm9yIG1lIG9ubHkgc28geW91IG1pZ2h0IGJlIGJvcmVkIHJlYWRpbmcgdGhpcykuIgpvdXRwdXQ6IAogIGh0bWxfbm90ZWJvb2s6CiAgICB0b2M6IHllcwotLS0KCgojIE92ZXJhbGwgb2JzZXJ2YXRpb25zCgoqKkFueSBhc3NvY2lhdGlvbnMgd2l0aCAgZGllbGRyaW4gbG9zcz8qKgoKLSBJc29mbGF2b25vaWQgIGFuZCBOb3ZvYmlvY2luIGJpb3N5bnRoZXNpcyAoS0VHRyBwYXRod2F5cykKLSBQV1ktNTUzMSwgUFdZLTcxNTkgKGNobG9yb3BoeWxsaWRlIGJpb3N5bnRoZXNpcywgYWVyb2JpYyBvciBhbmFlcm9iaWMgTWV0YWN5YykKLSBBbGwgb3RoZXIgcGF0aHdheXMgYXJlIGFzc29jaWF0ZWQgd2l0aCBsb3dlciBkaWVsZHJpbiBsb3NzIGluY2x1ZGluZyB4ZW5vYmlvdGljIGRlZ3JhZGF0aW9uIHBhdGh3YXlzIChOaXRyb3RvbHVlbmUsIGNhcHJvbGFjdGFtLCBhbWlub2JlbnpvYXRlLCBzdHlyZW5lLCB4eWxlbmUsIGJpc3BoZW5vbCBhbmQgUEFIIGRlZ3JhZGF0aW9uCiAgLSBXaHkgaXMgdGhlcmUgYSBoaWdoZXIgeGVub2Jpb3RpYyBkZWdyYWRhdGlvbiBwb3RlbnRpYWwgaW4gc29pbHMgdGhhdCBoYWQgbG93ZXIgbG9zc2VzPwogIC0gQUJDIHRyYW5zcG9ydGVycyAoY29tcGV0aXRpdmUgdHJhaW50IEBXb29kMjAxOCkgYXJlIGFsc28gaGlnaCBpbiB0aGUgc29pbCB3aXRoIGxvd2VzdCBkaWVsZHJpbiBsb3NzLCB0b2dldGhlciB3aXRoIAotIE5PIEREVCBtZXRhYm9saXNtIChlaXRoZXIgYXMgS09zIG9yIHBhdGh3YXlzKSB3YXMgcHJlc2VudAotIE5PIE5hcGh0YWxlbmUgbWV0YWJvbGlzbSB3YXMgcHJlc2VudCAtIGFsdGhvdWdoIHRocmVlIHJlbGF0ZWQgZW56eW1lcyB3ZXJlIHByZXNlbnQgKEswMDQ4MCBTYWxpY3lsYXRlIGh5ZHJveHlsYXNlICwgSzE4MjQyIHNhbGljeWxhdGUgNS1oeWRyb3h5bGFzZSBsYXJnZSBzdWJ1bml0IGFuZCBLMTM5NTNhbGNvaG9sIGRlaHlkcm9nZW5hc2UsIHByb3Bhbm9sLXByZWZlcnJpbmcpLiBUaGVzZSBlbnp5bWVzIGNhbiBiZSBwYXJ0IG9mIG90aGVyIGJpb2RlZ3JhZGF0aW9uIHBhdGh3YXlzIHRvby4gSG93ZXZlciwgdGhleSB3ZXJlIG5vdCBjb3JyZWxhdGVkIHdpdGggbGV2ZWxzIG9mIGRpZWxkcmluIGxvc3MgKG5vIGVuenltZSB3YXMgZm91bmQgdG8gYmUgYXNzb2NpYXRlZCB0byBkaWVsZHJpbiBjb25jZW50cmF0aW9ucyBlaXRoZXIpLgoKCioqV2hpY2ggbWljcm9vcmdhbmlzbXMgY2FuIGJlIGFzc29jaWF0ZWQgd2l0aCB0aGlzPyoqIAogIAoqKklzIHRoaXMgYXNzb2NpYXRlZCB3aXRoIFNvaWwgb3JnYW5pYyBtYXR0ZXIgZGVjb21wb3NpdGlvbj8qKgogIAotIFBDQTEgKGFsbCAxNjggS0VHRyBwYXRod2F5cykgd2FzIGNvcnJlbGF0ZWQgdG8gQ04gcmF0aW8KLSBQQ0ExIChhbGwgNDEwIE1ldGFjeWMgcGF0aHdheXMpIHdhcyBjb3JyZWxhdGVkIHRvIEh1bXVzJSAoY2xyKQogIAoqKkhvdyBkb2VzIHRoaXMgcmVsYXRlIHRvIGtub3duIHhlbm9iaW90aWMgZGVncmFkYXRpb24gcGF0aHdheXMvZW56eW1lcz8qKgoKLSBleGFtcGxlIHhlbm9iaW90aWMgZHJ1ZyBtZXRhYm9saXNtIGluIGd1dAogIAoqKldoYXQgYXJlIHRoZSBsaW1pdGF0aW9ucyBvZiBwaWNydXN0IHByZWRpY3Rpb25zPyoqICAKCgoKCgoKYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZWNobz1GQUxTRX0KI215d2QKc2V0d2QoIn4vRG9jdW1lbnRzL1N0dWR5L0xhVHJvYmUvUmVzZWFyY2gvcGhEL01pbGVzdG9uZTJfRmllbGRfU3VydmV5L00yX0JhY3RlcmlhL1BpY3J1c3QiKQojbXlwYWNrYWdlcwpsaWJyYXJ5KGdncmVwZWwpCmxpYnJhcnkocWlpbWUyUikKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoc3RyaW5ncikKbGlicmFyeShnZ3Bsb3QyKQp0aGVtZV9zZXQodGhlbWVfYncoKSkgIApsaWJyYXJ5KHZlZ2FuKQpsaWJyYXJ5KGdncHVicikKbGlicmFyeShSQ29sb3JCcmV3ZXIpCmxpYnJhcnkocGh5bG9zZXEpCmxpYnJhcnkocHN5Y2gpCmxpYnJhcnkocmVzaGFwZTIpCmxpYnJhcnkoZ2dmb3J0aWZ5KQpsaWJyYXJ5KGZhY3RvZXh0cmEpCmxpYnJhcnkoRmFjdG9NaW5lUikKbGlicmFyeShtYWlnZXNQYWNrKQpsaWJyYXJ5KGtuaXRyKQojZmlsZXMgZnJvbSBwaWNydXN0MiBvdXRwdXQKI01ldGFjeWMgcGF0aHdheXMgcHJlZGljdGlvbnMgd2l0aCBOU1RJIHNldCB0byAwLjY1CmBgYAoKCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGVjaG89RkFMU0V9CktFR0dwd2Rlc2MgPC0gcmVhZF90c3YoIn4vbWluaWNvbmRhMy9lbnZzL3BpY3J1c3QyL2xpYi9weXRob24zLjYvc2l0ZS1wYWNrYWdlcy9waWNydXN0Mi9kZWZhdWx0X2ZpbGVzL2Rlc2NyaXB0aW9uX21hcGZpbGVzL0tFR0dfcGF0aHdheXNfaW5mby50c3YiKQoKS0VHR19wd2FidSA8LSByZWFkX3Rzdigifi9Eb2N1bWVudHMvU3R1ZHkvTGFUcm9iZS9SZXNlYXJjaC9waEQvTWlsZXN0b25lMl9GaWVsZF9TdXJ2ZXkvTTJfQmFjdGVyaWEvUGljcnVzdC8yMDIwXzAxMTNfcGljcnVzdF9BU1ZtaW5mcmVxMTBtaW5zcGwyXzI1NTFBU1ZfMC42NW1pbk5TVEkvcGljcnVzdDJfb3V0X3BpcGVsaW5lL0tFR0dfcGF0aHdheXNfb3V0L3BhdGhfYWJ1bl91bnN0cmF0LnRzdiIpICU+JSByZW5hbWUoImtvX251bWJlciIgPSAicGF0aHdheSIpCgpwYXRod2F5LnByZWQgPC0gaW5uZXJfam9pbihLRUdHX3B3YWJ1LEtFR0dwd2Rlc2MsIGJ5ID0gJ2tvX251bWJlcicpICU+JSAKICBzZWxlY3QocGF0aHdheSwgZXZlcnl0aGluZygpKSAlPiUgc2VsZWN0KGMoLWtvX251bWJlcikpICU+JSBhc190aWJibGUoKSAlPiUgY29sdW1uX3RvX3Jvd25hbWVzKCJwYXRod2F5IikKCgpLT19tZXRhZ2Vub21lIDwtIHJlYWRfdHN2KCJ+L0RvY3VtZW50cy9TdHVkeS9MYVRyb2JlL1Jlc2VhcmNoL3BoRC9NaWxlc3RvbmUyX0ZpZWxkX1N1cnZleS9NMl9CYWN0ZXJpYS9QaWNydXN0LzIwMjBfMDExM19waWNydXN0X0FTVm1pbmZyZXExMG1pbnNwbDJfMjU1MUFTVl8wLjY1bWluTlNUSS9waWNydXN0Ml9vdXRfcGlwZWxpbmUvS09fbWV0YWdlbm9tZV9vdXQvcHJlZF9tZXRhZ2Vub21lX3Vuc3RyYXQudHN2IikgJT4lIAogICAgICAgICAgY29sdW1uX3RvX3Jvd25hbWVzKCJmdW5jdGlvbiIpCmBgYAoKIyBNZXRhZGF0YQpgYGB7ciByZXN1bHRzID0gJ2hpZGUnLCBlY2hvPUZBTFNFfQptZXRhZGF0YTwtcmVhZF90c3YoIn4vRG9jdW1lbnRzL1N0dWR5L0xhVHJvYmUvUmVzZWFyY2gvcGhEL01pbGVzdG9uZTJfRmllbGRfU3VydmV5L00yX0JhY3RlcmlhL00yX1FpaW1lX0JhY3RlcmlhL21ldGFkYXRhLnRzdiIpICNyZXF1aXJlcyB0aWR5dmVyc2UKbWV0YWRhdGEyIDwtIG1ldGFkYXRhW2MoMjozNyksXQojIENvbnZlcnRpbmcgY29sdW1ucyB0byBudW1lcmljIHVzaW5nICJ0aWR5dmVyc2UiCm1ldGFkYXRhMiA8LSBtZXRhZGF0YVtjKDI6MzcpLF0gJT4lCiAgcm93bmFtZXNfdG9fY29sdW1uKCJzcGwiKSU+JQogIG11dGF0ZV9hbGwodHlwZS5jb252ZXJ0KSAlPiUKICBtdXRhdGVfaWYoaXMuZmFjdG9yLCBhcy5jaGFyYWN0ZXIpJT4lCiAgY29sdW1uX3RvX3Jvd25hbWVzKCJzcGwiKQpzYW1wbGVfZGF0YShtZXRhZGF0YVtjKDI6MzcpLF0gJT4lIGFzLmRhdGEuZnJhbWUoKSAlPiUgY29sdW1uX3RvX3Jvd25hbWVzKCIjU2FtcGxlSUQiKSkKIyBBZGQgY2xyIHRyYW5mb3JtZWQgY2FyYm9uIGNvbXBvc2l0aW9uCiNDb21wdXRlIHBlcmNlbnRhZ2UgZnJlcXVlbmNpZXMKcGVyY2VudERhdGEgPC0gZGF0YS5mcmFtZShtZXRhZGF0YTJbYygzNzozOSw0MSldKQpzdW1fYyA8LSBhcHBseShwZXJjZW50RGF0YSwgMSwgc3VtKSAjRXF1YXRlcyB0byBUT0MKcGVyY2VudERhdGEgPC0gMTAwKnBlcmNlbnREYXRhL3N1bV9jIApwZXJjZW50RGF0YSA8LSByb3VuZChwZXJjZW50RGF0YSwgMikgIyBSb3VuZCB0aGUgc29ydGVkIG91dHB1dCB0byAxIGRpZ2l0CnJlcXVpcmUoY29tcG9zaXRpb25zKQpjX2NvbXAgPC0gZGF0YS5mcmFtZShjbHIocGVyY2VudERhdGEpKQpjX2NvbXAkYCNTYW1wbGVJRGAgPC0gbWV0YWRhdGEyJGAjU2FtcGxlSURgCm1ldGFkYXRhMiA8LSBtZXRhZGF0YTIgJT4lIGxlZnRfam9pbihjX2NvbXAsIGJ5ID0gIiNTYW1wbGVJRCIpCm1ldGFkYXRhMiA8LSBtZXRhZGF0YTIgJT4lIHJlbmFtZShIdW11cyA9IEhVTS55KSAlPiUgcmVuYW1lKFBhcnRpY3VsYXRlQyA9IFBPQy55ICkgJT4lIHJlbmFtZShSZXNpc3RhbnRDID0gUk9DLnkgKQojZGVmaW5pbmcgZmFjdG9ycwptZXRhZGF0YTIkU29pbCA8LSBmYWN0b3IobWV0YWRhdGEyJFNvaWwsIGxldmVscz1jKCJLdXJvc29sIiwgIkNocm9tb3NvbCIpKQptZXRhZGF0YTIkUGFkZG9jayA8LSBmYWN0b3IobWV0YWRhdGEyJFBhZGRvY2ssIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzPWMoIjEiLCAiMiIsICIzIiwgIjQiLCI1IiwgIjYiLCI3IiwgIjgiLCI5IiwgIjEwIiwiMTEiLCAiMTIiKSkKbWV0YWRhdGEyJERsb3NzX2ZjdCA8LSAgZmFjdG9yKG1ldGFkYXRhMiREbG9zc19mY3QsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzPWMoIm92ZXIyMCIsICJvdmVyNDAiLCAib3ZlcjYwIiwgIm92ZXI3MCIsIm92ZXI4MCIpKQpgYGAKCgpgYGB7ciB3YXJuaW5nPUZBTFNFLGVjaG89RkFMU0V9CiMjIyBjcmVhdGUgcHMgb2JqZWN0ICMjIyMKcGh5c2VxIDwtcGh5bG9zZXEoCiAgICAgICAgb3R1X3RhYmxlKEtPX21ldGFnZW5vbWUsIHRheGFfYXJlX3Jvd3MgPSBUKSwgCiAgICAgICAgc2FtcGxlX2RhdGEobWV0YWRhdGEyICU+JSBhcy5kYXRhLmZyYW1lKCkgJT4lIGNvbHVtbl90b19yb3duYW1lcygiI1NhbXBsZUlEIikpCikKCiNhZGRpbmcgS08gZGl2ZXJzaXR5IG1lYXN1cmVzICh3aXRoIHBzIG9iamVjdCkgdG8gbWV0YWRhdGEgYW5kIHJlLWNyZWF0ZSBwcyBvYmplY3QgCm1pbihjb2xTdW1zKG90dV90YWJsZShwaHlzZXEpKSkKcmFyZV9CYWMgPC0gcmFyZWZ5X2V2ZW5fZGVwdGgocGh5c2VxLCBzYW1wbGUuc2l6ZSA9IG1pbihjb2xTdW1zKG90dV90YWJsZShwaHlzZXEpKSksICBybmdzZWVkID0gVFJVRSwgcmVwbGFjZSA9IFRSVUUsIHRyaW1PVFVzID0gVFJVRSkKcHMuZGl2IDwtIGVzdGltYXRlX3JpY2huZXNzKHJhcmVfQmFjKQpwcy5kaXYkYCNTYW1wbGVJRGAgPC0gc2FtcGxlX25hbWVzKHBoeXNlcSkKbWV0YWRhdGEyIDwtIG1ldGFkYXRhMiAlPiUgCiAgbGVmdF9qb2luKHBzLmRpdiwgYnkgPSAiI1NhbXBsZUlEIikKbWV0YWRhdGEyJHBpZWxvdV9ldiA8LSBwcy5kaXYkU2hhbm5vbi9sb2cocHMuZGl2JE9ic2VydmVkKSAgICAgICNQaWVsb3UgZXZlbmVzcwojYWRkaW5nIGNhcmJvbiByYXRpb3MKbWV0YWRhdGEyIDwtIG1ldGFkYXRhMiAlPiUgCiAgbXV0YXRlKHNoYW5ub25fQyA9IFNoYW5ub24gLyBUQykgJT4lCiAgbXV0YXRlKHNpbXBzb25fQyA9IEludlNpbXBzb24gLyBUQykgJT4lIAogIG11dGF0ZShldmVubmVzc19DID0gcGllbG91X2V2IC8gVEMpICU+JSAKICBtdXRhdGUoYmNvcF9DID0gYl9jb3BpZXNfbmdETkEgLyBUQykgJT4lIAogIG11dGF0ZShmY29wX0MgID0gZl9jb3BpZXNfbmdETkEgLyBUQykgCnBoeXNlcTwtcGh5bG9zZXEoCiAgb3R1X3RhYmxlKEtPX21ldGFnZW5vbWUsIHRheGFfYXJlX3Jvd3MgPSBUKSwgCiAgc2FtcGxlX2RhdGEobWV0YWRhdGEyICU+JSBhcy5kYXRhLmZyYW1lKCkgJT4lIGNvbHVtbl90b19yb3duYW1lcygiI1NhbXBsZUlEIikpCikKYGBgCiMgUGh5bG9zZXEgb2JqZWN0cwpwcyBvYmplY3QgZm9yIEtPIG1ldGFnZW5vbWUKYGBge3J9CnBoeXNlcQpgYGAKCnBzIG9iamVjdCAgZm9yIHRoZSBwYXRod2F5IGZpbGUKYGBge3IsIGVjaG89RkFMU0V9CiMgbm93IGZvciB0aGUgcGF0aHdheSBmaWxlCnBoeXNlcS5wdyA8LSBwaHlsb3NlcShvdHVfdGFibGUoCiAgICAgICAgICAgICBwYXRod2F5LnByZWQsIHRheGFfYXJlX3Jvd3MgPSBUKSwgCiAgICAgICAgICAgICBzYW1wbGVfZGF0YShtZXRhZGF0YTIgJT4lIGFzLmRhdGEuZnJhbWUoKSAlPiUgY29sdW1uX3RvX3Jvd25hbWVzKCIjU2FtcGxlSUQiKSkKKQpwaHlzZXEucHcKYGBgCgoKYGBge3IgcmVzdWx0cyA9ICdoaWRlJyxlY2hvPUZBTFNFfQojYWRkaW5nIHBhdGh3YXkgZGl2ZXJzaXR5IG1lYXN1cmVzIHRvIG1ldGFkYXRhIAojYW5kIHRoaXMgdGltZSBubyBuZWVkIHRvIGFkZCBjYXJib24gcmF0aW9zIGZvciB0aGUgcGF0aHdheXMKbWluKGNvbFN1bXMob3R1X3RhYmxlKHBoeXNlcS5wdykpKQpyYXJlX0JhYy5wdyA8LSByYXJlZnlfZXZlbl9kZXB0aChwaHlzZXEucHcsIHNhbXBsZS5zaXplID0gbWluKGNvbFN1bXMob3R1X3RhYmxlKHBoeXNlcS5wdykpKSwgIHJuZ3NlZWQgPSBUUlVFLCByZXBsYWNlID0gVFJVRSwgdHJpbU9UVXMgPSBUUlVFKQpwcy5kaXYucHcgPC0gZXN0aW1hdGVfcmljaG5lc3MocmFyZV9CYWMucHcpCnBzLmRpdi5wdyRgI1NhbXBsZUlEYCA8LSBzYW1wbGVfbmFtZXMocGh5c2VxLnB3KQptZXRhZGF0YTMgPC0gbWV0YWRhdGEyICU+JSAKICBsZWZ0X2pvaW4ocHMuZGl2LnB3LCBieSA9ICIjU2FtcGxlSUQiKQptZXRhZGF0YTMkcGllbG91X2V2IDwtIHBzLmRpdi5wdyRTaGFubm9uL2xvZyhwcy5kaXYucHckT2JzZXJ2ZWQpICAgICAgI1BpZWxvdSBldmVuZXNzCnBoeXNlcS5wdyA8LXBoeWxvc2VxKAogIG90dV90YWJsZShwYXRod2F5LnByZWQsIHRheGFfYXJlX3Jvd3MgPSBUKSwgCiAgc2FtcGxlX2RhdGEobWV0YWRhdGEyICU+JSBhcy5kYXRhLmZyYW1lKCkgJT4lIGNvbHVtbl90b19yb3duYW1lcygiI1NhbXBsZUlEIikpCikKcGh5c2VxLnB3CmBgYAojIEtPX01FVEFHRU5PTUUgUENBIHBsb3RzIGFuZCBjb3JyZWxhdGlvbiB0YWJsZXMuIAojIyBQQ0EgQWl0Y2hpc29uIGJpcGxvdCBvbiBLTyBwcmVkaWN0aW9ucyBhbmQgY29ycmVsYXRpb25zIG9mIGF4aXMtc2NvcmVzIHdpdGggZW52aXJvbm1lbnRhbCB2YXJpYWJsZXMgYW5kIHNpZ25pZmljYW50IGZlYXR1cmVzClBDQSB3aWxsIHJlZHVjZSB0aGUgbm9pc2UgYW5kIHNwaXRzIG91dCBvbmx5IHJlbGV2YW50IHZhcmlhdGlvbiBpbnRvIGluZGVwZW5kYW50IGF4ZXMuClRoZSBxdWVzdGlvbiB0aGVuIGlzIHdoYXQgZHJpdmVzIHRoZSB2YXJpYXRpb24gb2YgdGhlc2UgYXhpcywgaS5lLiB0aGUgdmFyaWF0aW9uIGluIGVuenltZXMgYXMgcHJlZGljdGVkIGJ5IHBpY3J1c3QyIGFuZCB3aGljaCBlbnp5bWUgYXJlIGRyaXZlbiBtb3JlIG9yIGxlc3MgaW4gdGhlc2UgYXhpcy4gIAogIAojIyMgY2xyIHRyYW5mb3JtIG9mIG1ldGFnZW5vbWUgcHJlZGljdGlvbnMKYGBge3J9Cihwc19jbHIgPC0gbWljcm9iaW9tZTo6dHJhbnNmb3JtKHBoeXNlcSwgImNsciIpKSAgCnBoeWxvc2VxOjpvdHVfdGFibGUocHNfY2xyKVsxOjUsIDE6Nl0KYGBgCgoKCiMjIyBQQ0EgdmlhIHBoeWxvc2VxCmBgYHtyfQpvcmRfY2xyIDwtIHBoeWxvc2VxOjpvcmRpbmF0ZShwc19jbHIsICJSREEiKQojRXhhbWluZSBlaWdlbnZhbHVlcyBhbmQgJSBwcm9wLiB2YXJpYW5jZSBleHBsYWluZWQKICBoZWFkKG9yZF9jbHIkQ0EkZWlnKQpzYXBwbHkob3JkX2NsciRDQSRlaWdbMTo4XSwgZnVuY3Rpb24oeCkgeCAvIHN1bShvcmRfY2xyJENBJGVpZykpCmBgYAoKIyMjIENvcnJlbGF0aW9ucyB0byBQQzEsIFBDMiBhbmQgUEMzICh3aXRoIEJIIGNvcnJlY3RlZCAqcCotdmFsdWVzKQphZGRpbmcgdGhlIHBjIHNjb3JlcyB0byBtZXRhZGF0YSAgCmBgYHtyLGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CgpjbHJfcGNzIDwtIGRhdGEuZnJhbWUoCiAgInBjMSIgPSBvcmRfY2xyJENBJHVbLDFdLAogICJwYzIiID0gb3JkX2NsciRDQSR1WywyXSwKICAicGMzIiA9IG9yZF9jbHIkQ0EkdVssM10pICU+JSAKICByb3duYW1lc190b19jb2x1bW4oIiNTYW1wbGVJRCIpICU+JQogIGxlZnRfam9pbihtZXRhZGF0YTMpCmBgYAoKCkNvcnJlbGF0aW9ucyB3aXRoIHBzeWNoIHBhY2thZ2UsIHNlbGVjdGluZyB0aGUgcmVsZXZhbnQgdmFyaWFibGVzICAKYGBge3IsZWNobz1GQUxTRX0KcmVxdWlyZShwc3ljaCkKcmVxdWlyZShyZXNoYXBlMikKY29ycmVsYXRpb25fbWF0cml4PWNvcnIudGVzdChjbHJfcGNzWyxjKCJwYzEiLCJwYzIiLCAicGMzIiwiRDE1MTciLCJwcERERSIsICJwcEREVCIsICJERFQxNTE3IiwgIlRDIiwiVE4iLCJDTiIgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAsIkhDIiwgIlAiLCAgICJDUCIgLCJwSCIgLCJiX2NvcGllc19uZ0ROQSIgLCJmX2NvcGllc19uZ0ROQSIsIkRsb3NzIiAsIkREVGxvc3MiLCJDX1NhbmQiLCJGX1NhbmQiICwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVF9TYW5kIiwiU2lsdF8xIiwgIkNsYXlfMSIsIk9yZ2FuaWMgTWF0dGVyIiwgIkZpZWxkIENhcGFjaXR5IiwgIldpbHRpbmcgUG9pbnQiLCAiS2FvbGluaXRlJSIgLCJJbGxpdGUlIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU21lY3RpdGUlIiwgIkdpYmJzaXRlJSIgLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNsYXlfdG90YWwiLCJQYXJ0aWN1bGF0ZUMiLCJIdW11cyIgLCJSZXNpc3RhbnRDIiAsICJEZWx0YS5DLkZyYWMiLCJPYnNlcnZlZC54IiwgInBpZWxvdV9ldiIsIlNoYW5ub24ueCIpXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRob2Q9InNwZWFybWFuIiwgYWRqdXN0PSJob2xtIikKcl9tYXRyaXg9Y29ycmVsYXRpb25fbWF0cml4JHIKcl9tYXRyaXhbcm93KHJfbWF0cml4KT5jb2wocl9tYXRyaXgpXT0wCmRpYWcocl9tYXRyaXgpPTAKcF9tYXRyaXg9Y29ycmVsYXRpb25fbWF0cml4JHAKcF9tYXRyaXhbcm93KHBfbWF0cml4KT5jb2wocF9tYXRyaXgpXT0xCmRpYWcocF9tYXRyaXgpPTEKcl90YWJsZT1tZWx0KHJfbWF0cml4KQpwX3RhYmxlPW1lbHQocF9tYXRyaXgpCmNvcnRhYmxlIDwtIGRhdGEuZnJhbWUocl90YWJsZSRWYXIxLCByX3RhYmxlJFZhcjIsIHJfdGFibGUkdmFsdWUsIHBfdGFibGUkdmFsdWUpICNjcmVhdHMgdGhlIHRhYmxlIHdpdGggciBhbmQgcCB2YWx1ZXMKYGBgCgpGaWx0ZXJpbmcgb2Ygc2lnbmlmaWNhbnQgY29ycmVsYXRpb25zCmBgYHtyLGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiNmaWx0ZXIgb25seSBwYzEgcmVsYXRlZCBjb3JyZWxhdGlvbnMKcGMxX2NvciA8LSBjb3J0YWJsZSAlPiUgCiAgZmlsdGVyKHJfdGFibGUuVmFyMSA9PSAicGMxIiB8IAogICAgICAgICAgIHJfdGFibGUuVmFyMiA9PSAicGMxIikgJT4lIAogIGZpbHRlcihwX3RhYmxlLnZhbHVlIDw9IDAuMDYpICU+JQogIGFycmFuZ2UocF90YWJsZS52YWx1ZSkKP2FycmFuZ2UKI2ZpbHRlciBvbmx5IHBjMiByZWxhdGVkIGNvcnJlbGF0aW9ucwpwYzJfY29yIDwtIGNvcnRhYmxlICU+JSAKICBmaWx0ZXIocl90YWJsZS5WYXIxID09ICJwYzIiIHwgCiAgICAgICAgICAgcl90YWJsZS5WYXIyID09ICJwYzIiKSAlPiUgCiAgZmlsdGVyKHBfdGFibGUudmFsdWUgPD0gMC4wNikgJT4lCiAgYXJyYW5nZShwX3RhYmxlLnZhbHVlKQoKI2ZpbHRlciBvbmx5IHBjMyByZWxhdGVkIGNvcnJlbGF0aW9ucwpwYzNfY29yIDwtIGNvcnRhYmxlICU+JSAKICBmaWx0ZXIocl90YWJsZS5WYXIxID09ICJwYzMiIHwgCiAgICAgICAgICAgcl90YWJsZS5WYXIyID09ICJwYzMiKSU+JSAKICBmaWx0ZXIocF90YWJsZS52YWx1ZSA8PSAwLjA2KSAlPiUKICBhcnJhbmdlKHBfdGFibGUudmFsdWUpCnBjMV9jb3IKcGMyX2NvcgpwYzNfY29yCmBgYAoKCiMjIyBLT3MgY29udHJpYnV0aW5nIHRvIHRoZSB2YXJpYXRpb24gaW4gUEMxLCBQQzIgYW5kIFBDMwpgYGB7ciBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD04LCBlY2hvPVRSVUV9CmluZC5jb29yZCA8LSBkYXRhLmZyYW1lKG9yZF9jbHIkQ0EkdikKc2Rldl9pbmQgPC0gYXBwbHkoaW5kLmNvb3JkLCAxLCBzZCkKaW5kX2NvbnRfUENBMSA8LSBkYXRhLmZyYW1lKFBDQSA9ICgxMDAqKDEgLyBucm93KGluZC5jb29yZCkqKGluZC5jb29yZCRQQzFeMiAvc2Rldl9pbmQpKSkpCmluZF9jb250X1BDQTFfdG9wIDwtIGluZF9jb250X1BDQTEgJT4lIAogIHJvd25hbWVzX3RvX2NvbHVtbigib3R1IikgJT4lIAogIGZpbHRlcihQQ0EgPj0gMC4wMDE4MDMzNTUpJT4lIAogIGNvbHVtbl90b19yb3duYW1lcygib3R1IikKaW5kX2NvbnRfUENBMiA8LSBkYXRhLmZyYW1lKFBDQSA9ICgxMDAqKDEgLyBucm93KGluZC5jb29yZCkqKGluZC5jb29yZCRQQzJeMiAvc2Rldl9pbmQpKSkpCmluZF9jb250X1BDQTJfdG9wIDwtIGluZF9jb250X1BDQTIgJT4lIAogIHJvd25hbWVzX3RvX2NvbHVtbigib3R1IikgJT4lIAogIGZpbHRlcihQQ0EgPj0gMC4wMDIpJT4lIAogIGNvbHVtbl90b19yb3duYW1lcygib3R1IikKaW5kX2NvbnRfUENBMyA8LSBkYXRhLmZyYW1lKFBDQSA9ICgxMDAqKDEgLyBucm93KGluZC5jb29yZCkqKGluZC5jb29yZCRQQzNeMiAvIHNkZXZfaW5kKSkpKQppbmRfY29udF9QQ0EzX3RvcCA8LSBpbmRfY29udF9QQ0EzICU+JSAKICByb3duYW1lc190b19jb2x1bW4oIm90dSIpICU+JSAKICBmaWx0ZXIoUENBID49IDAuMDAyKSU+JSAKICBjb2x1bW5fdG9fcm93bmFtZXMoIm90dSIpCmluZF9jb250X1BDQV90b3AgPC0gcmJpbmQoaW5kX2NvbnRfUENBMV90b3AsIGluZF9jb250X1BDQTJfdG9wLCBpbmRfY29udF9QQ0EzX3RvcCkKYGBgCgojIyMgVmlzdWFsaXNhdGlvbiBvZiBQQ0EgZm9yIEtPIG1ldGFnZW5vbWUKYGBge3IsIGVjaG89RkFMU0V9CiMgcGxvdDEgc2hvd2luZyBSZXNpc3RhbnQgQ2FyYm9uIGFzIGNvbG91ciBncmFkaWVudAojIFNjYWxlIGF4ZXMgYW5kIHBsb3Qgb3JkaW5hdGlvbgpjbHIxIDwtIG9yZF9jbHIkQ0EkZWlnWzFdIC8gc3VtKG9yZF9jbHIkQ0EkZWlnKQpjbHIyIDwtIG9yZF9jbHIkQ0EkZWlnWzJdIC8gc3VtKG9yZF9jbHIkQ0EkZWlnKQpwMSA8LSBwaHlsb3NlcTo6cGxvdF9vcmRpbmF0aW9uKHBzX2Nsciwgb3JkX2NsciwgdHlwZT0ic2FtcGxlcyIsIGNvbG9yID0gIkNOIiwgc2hhcGUgPSAiU29pbCIpICsKICAgIGdlb21fcG9pbnQoYWVzKHNpemUgPSBEbG9zcykpICsKICAgc2NhbGVfc2l6ZShicmVha3MgPSBjKDMwLDUwLDgwKSkgKwogICAgY29vcmRfZml4ZWQoY2xyMiAvIGNscjEpICsKICAgIHNjYWxlX2NvbG91cl9ncmFkaWVudChsb3cgPSAiZ3JleSIsIGhpZ2ggPSAiYmxhY2siKSsKICBnZ3RpdGxlKCJQQ0Egb24gcGljcnVzdCBwcmVkaWN0aW9uIiwgc3VidGl0bGUgPSAiKGNlbnRyZWQtbG9nIHJhdGlvIEtPIG1ldGFnZW5vbWUpIikKcDEKYGBgCgpgYGB7ciwgZWNobz1GQUxTRSwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KIyBwbG90IHNob3dpbmcgcGF0aHdheXMgdGhhdCBhcmUgY29udHJpYnV0aW5nIHRoZSBtb3N0CmNscjEgPC0gb3JkX2NsciRDQSRlaWdbMV0gLyBzdW0ob3JkX2NsciRDQSRlaWcpCmNscjIgPC0gb3JkX2NsciRDQSRlaWdbMl0gLyBzdW0ob3JkX2NsciRDQSRlaWcpCnAxLjEyIDwtIHBoeWxvc2VxOjpwbG90X29yZGluYXRpb24ocHNfY2xyLCBvcmRfY2xyLCB0eXBlPSJ0YXhhIikgKwogICAgY29vcmRfZml4ZWQoY2xyMiAvIGNscjEpICsKICBnZ3RpdGxlKCJQQ0EsIHRvcCBjb250cmlidXRpbmcgS09zIikKCnAxLjEyJGRhdGEgPC0gIHAxLjEyJGRhdGEgICU+JSByb3duYW1lc190b19jb2x1bW4odmFyID0gIk9UVSIpICU+JSAgZmlsdGVyKE9UVSAlaW4lIHJvd25hbWVzKGluZF9jb250X1BDQV90b3ApKQpyZXF1aXJlKGdncmVwZWwpCnAxLjEyICA8LSBwMS4xMiArIGdlb21fdGV4dF9yZXBlbChsYWJlbCA9IHAxLjEyJGRhdGEkT1RVKSArIGNvb3JkX2ZpeGVkKHhsaW0gPSBjKC01LDUpLCB5bGltID0gYygtNSw1KSkgCgpwMS4xMgpgYGAKCgoKYGBge3IgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9OCwgZWNobz1UUlVFfQpzdW0oaW5kX2NvbnRfUENBMV90b3AkUENBKSAvIHN1bShpbmRfY29udF9QQ0ExJFBDQSkKbnJvdyhpbmRfY29udF9QQ0ExX3RvcCkKaW5kX2NvbnRfUENBMV90b3AgJT4lIHJvd25hbWVzX3RvX2NvbHVtbigpICU+JSBhcnJhbmdlKGRlc2MoUENBKSkKYGBgClRoZSB0b3AgOCBLT3MgY29udHJpYnV0ZSAxLjIlIG9mIHRoZSB0b3RhbCB2YXJpYXRpb24gb2YgUEMxCgoKYGBge3IgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9OCwgZWNobz1UUlVFfQpzdW0oaW5kX2NvbnRfUENBMl90b3AkUENBKSAvIHN1bShpbmRfY29udF9QQ0EyJFBDQSkKbnJvdyhpbmRfY29udF9QQ0EyX3RvcCkKaW5kX2NvbnRfUENBMl90b3AgICU+JSByb3duYW1lc190b19jb2x1bW4oKSAlPiUgYXJyYW5nZShkZXNjKFBDQSkpCmBgYAoxNyBLT3MgY29udHJpYnV0ZWQgMy43JSBvZiB0aGUgdmFyaWF0aW9uIG9mIFBDMgoKYGBge3IgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9OCwgZWNobz1UUlVFfQpzdW0oaW5kX2NvbnRfUENBM190b3AkUENBKSAvIHN1bShpbmRfY29udF9QQ0EzJFBDQSkKbnJvdyhpbmRfY29udF9QQ0EzX3RvcCkKaW5kX2NvbnRfUENBM190b3AgICU+JSByb3duYW1lc190b19jb2x1bW4oKSAlPiUgYXJyYW5nZShkZXNjKFBDQSkpCmBgYAo0OSBLT3MgY29udHJpYnV0ZSAxNyUgb2YgdGhlIHZhcmlhdGlvbgoKCiMjIE9uZSBtb3JlOiBMZXRzIHRlc3Qgd2hpY2ggS08tcHJlZGljdGlvbnMgKGNsciB0cmFuc2Zvcm1lZCkgc2lnbmljYW50bHkgY29ycmVsYXRlIHRvIGRpZWxkcmluIGxvc3MgLSBhbmQgZ3JhcGggdGhvc2UgCnByZS1maWx0ZXJpbmcgdGhlIGNsci10cmFuc2Zvcm1lZCBLTyBwcmVkaWN0aW9ucyB0aGF0IGNvcnJlbGF0ZSB3aXRoIERsb3NzICAKKFNwZWFybWFuLCBib25mZXJyb25pIGNvcnJlY3RlZCAqcCotdmFsdWVzKQoKYGBge3IsIGVjaG8gPSBGQUxTRSwgd2FybmluZz1GQUxTRX0KRGxvc3MgPC0gbWV0YWRhdGEyJERsb3NzCm90dXRhYmxlIDwtIGRhdGEuZnJhbWUodChwaHlsb3NlcTo6b3R1X3RhYmxlKHBzX2NscikpKQpvdHV0YWJsZSA8LSBvdHV0YWJsZVttYXRjaChtZXRhZGF0YTIkYCNTYW1wbGVJRGAsIHJvdy5uYW1lcyhvdHV0YWJsZSkpLF0gI21ha2Ugc3VyZSBpdHMgaW4gb3JkZXIgd2l0aCB2YXJpYWJsZQp0ZXN0IDwtIGFwcGx5KG90dXRhYmxlICwyLCBjb3IudGVzdCwgRGxvc3MsIG1ldGhvZCA9ICJzcGVhcm1hbiIpCnRlc3QucCA8LSBkYXRhLmZyYW1lKHB2YWxzID0gc2FwcGx5KHRlc3QsICJbWyIsICJwLnZhbHVlIikpCnRlc3QucCRwdmFsLmFkaiA8LSBwLmFkanVzdCh0ZXN0LnAkcHZhbHMsIG1ldGhvZCA9ICJib25mZXJyb25pIiwgbiA9IGxlbmd0aCh0ZXN0LnAkcHZhbHMpKQp0ZXN0LnAuc2lnIDwtICB0ZXN0LnAgJT4lIAogIHJvd25hbWVzX3RvX2NvbHVtbih2YXIgPSAiS08iKSU+JSAKICAgIGZpbHRlcihwdmFsLmFkaiA8PSAwLjA1KSU+JQogICAgYXJyYW5nZShwdmFsLmFkaikKdGVzdC5wLnNpZwpgYGAKCgoKCgojIyMgVGhlcmUgd2VyZSA1NSBzaWduaWZpY2FudGx5IGNvcnJlbGF0ZWQgS09zIHdoZW4gcnVubmluZyBhbGRleC5jb3Igd2l0aCBEbG9zcyBhcyB2YXJpYWJsZSAoQkggKnAqIDw9IDAuMDIpPwpXaHkgQWxkZXg/IEFub3ZhLUxpa2UgRGlmZmVyZW50aWFsIEV4cHJlc3Npb24gZm9yIGhpZ2ggdGhyb3VnaHB1dCBkYXRhIFsoQWxkZXgpXShodHRwczovL3JkcnIuaW8vYmlvYy9BTERFeDIvKSwgdGFraW5nIHNhbXBsZSB2YXJpYXRpb24gaW50byBhY2NvdW50LiAKCmBgYHtyIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmFseC5jb3Iuc2lnX0tPX21ldGFnZW5vbWVfZGxvc3MgPC0gcmVhZF9jc3YoIn4vRG9jdW1lbnRzL1N0dWR5L0xhVHJvYmUvUmVzZWFyY2gvcGhEL01pbGVzdG9uZTJfRmllbGRfU3VydmV5L00yX0JhY3RlcmlhL1BpY3J1c3QvYWx4LmNvci5zaWdfS09fbWV0YWdlbm9tZV9kbG9zc18yMDIwMDIxLmNzdiIpICU+JSBhcnJhbmdlKEJIKQoKYWx4LmNvci5zaWdfS09fbWV0YWdlbm9tZV9kbG9zcyAKYGBgCgojIyMgSG93IG1hbnkgb2YgdGhvc2Ugd2VyZSBhbHNvIHRvcCBjb250cmlidXRlcnMgdG8gUEMxLCBQQzIgb3IgUEMzPwpgYGB7cn0KaW5kX2NvbnRfUENBX3RvcCAgJT4lIHJvd25hbWVzX3RvX2NvbHVtbih2YXIgPSAicGF0aHdheSIpICU+JSAKICBzdWJzZXQocGF0aHdheSAlaW4lIGFzLnZlY3RvcihhbHguY29yLnNpZ19LT19tZXRhZ2Vub21lX2Rsb3NzJHJvd25hbWUpKQoKYGBgCgojIyMgSG93IG1hbnkgb2YgdGhvc2UgbWF0Y2ggdGhlIHNwZWFybWFuIGNvcnJlbGF0aW9ucz8gCmBgYHtyIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmFseC5jb3Iuc2lnX0tPX21ldGFnZW5vbWVfZGxvc3MgPC0gcmVhZF9jc3YoIn4vRG9jdW1lbnRzL1N0dWR5L0xhVHJvYmUvUmVzZWFyY2gvcGhEL01pbGVzdG9uZTJfRmllbGRfU3VydmV5L00yX0JhY3RlcmlhL1BpY3J1c3QvYWx4LmNvci5zaWdfS09fbWV0YWdlbm9tZV9kbG9zc18yMDIwMDIxLmNzdiIpICU+JSBhcnJhbmdlKEJIKQoKYWx4LmNvci5zaWdfS09fbWV0YWdlbm9tZV9kbG9zcyAlPiUgCiAgc3Vic2V0KHJvd25hbWUgJWluJSBhcy52ZWN0b3IodGVzdC5wLnNpZyRLTykpCmBgYAoKIyMjIHNwZWFybWFuLmNvcnIgc2NhdHRlcnBsb3RzCmBgYHtyIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTksIGVjaG89RkFMU0V9CmNscyA8LSBjKCJncmV5OCIsImJsdWUiKQpwc19jbHIubWx0IDwtIHBzbWVsdChwc19jbHIpICNtZWx0IGRhdGFmcmFtZSBmb3IgcGxvdHRpbmcKcHNfY2xyLm1sdCAgPC0gcHNfY2xyLm1sdCAgJT4lIHN1YnNldChPVFUgJWluJSBhcy52ZWN0b3IodGVzdC5wLnNpZyRLTykpICNmaWx0ZXIgdGhlIEVDcyB0aGF0IHNpZ25pZmljYW50IGNvcnJlbGF0ZSB3aXRoIFBDMSwyIGFuZCAzCnBzX2Nsci5tbHQgJT4lIAogIGdncGxvdChkYXRhID0gLiwgYWVzKHggPSBEbG9zcywgeSA9IEFidW5kYW5jZSkpKwogIGdlb21fcG9pbnQoYWVzKGNvbG9yID0gU29pbCwgc2hhcGUgPSBTb2lsKSkgKwogIGxhYnMoeCA9ICIiLCB5ID0gIkFidW5kYW5jZSAoY2xyKVxuIikgKwogIGZhY2V0X3dyYXAofiBPVFUsIHNjYWxlcyA9ICJmcmVlIikgKwogIGdndGl0bGUoIktPIHByZWRpY3Rpb25zIHZzIERsb3NzIChzcGVhcm1hbi5jb3JyIHAgPCAwLjA1LCBib25mZXJyb25pIGNvcnJlY3RlZCkiKSsgCiAgdGhlbWUoc3RyaXAudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCkpKwogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gY2xzKSArCiAgc3RhdF9jb3IobWV0aG9kID0gInNwZWFybWFuIixsYWJlbC55Lm5wYyA9ICJib3R0b20iKQpgYGAKCiMjIyBBbGRleC5jb3JyIHNjYXR0ZXJwbG90cwpgYGB7ciBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD0xMCwgZWNobz1GQUxTRX0KY2xzIDwtIGMoImdyZXk4IiwiYmx1ZSIpCnBzX2Nsci5tbHQgPC0gcHNtZWx0KHBzX2NscikgI21lbHQgZGF0YWZyYW1lIGZvciBwbG90dGluZwpwc19jbHIubWx0ICA8LSBwc19jbHIubWx0ICAlPiUgc3Vic2V0KE9UVSAlaW4lIGFzLnZlY3RvcihhbHguY29yLnNpZ19LT19tZXRhZ2Vub21lX2Rsb3NzJHJvd25hbWUpKSAjZmlsdGVyIHRoZSBFQ3MgdGhhdCBzaWduaWZpY2FudCBjb3JyZWxhdGUgd2l0aCBQQzEsMiBhbmQgMwpwc19jbHIubWx0ICU+JSAKICBnZ3Bsb3QoZGF0YSA9IC4sIGFlcyh4ID0gRGxvc3MsIHkgPSBBYnVuZGFuY2UpKSsKICBnZW9tX3BvaW50KGFlcyhjb2xvciA9IFNvaWwsIHNoYXBlID0gU29pbCkpICsKICBsYWJzKHggPSAiIiwgeSA9ICJBYnVuZGFuY2UgKGNscilcbiIpICsKICBmYWNldF93cmFwKH4gT1RVLCBzY2FsZXMgPSAiZnJlZSIpICsKICBnZ3RpdGxlKCJLTyBwcmVkaWN0aW9ucyB2cyBEbG9zcyAoYWxkZXguY29yciBwIDwgMC4wMiwgQkggY29ycmVjdGVkKSIpKyAKICB0aGVtZShzdHJpcC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4KSkrCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBjbHMpICsKICBzdGF0X2NvcihtZXRob2QgPSAic3BlYXJtYW4iLGxhYmVsLnkubnBjID0gImJvdHRvbSIpCmBgYAogIAogIAojIEtFR0cgcGF0aHdheSBQQ0EgcGxvdCAoZnJvbSBLTyBtZXRhZ2Vub21lIG1hcHBpbmcpCmxhdGVzdCBvcGVubHkgYXZhaWxhYmxlIEtFR0cgbWFwcGluZyBmaWxlIGlzIGZyb20gMjAxMQogCiMjIGNsciB0cmFuc2Zvcm0KYGBge3J9Cihwc19jbHIucHcgPC0gbWljcm9iaW9tZTo6dHJhbnNmb3JtKHBoeXNlcS5wdywgImNsciIpKSAgCnBoeWxvc2VxOjpvdHVfdGFibGUocHNfY2xyLnB3KVsxOjYsIDE6Nl0KYGBgCgojIyBQQ0EgdmlhIHBoeWxvc2VxCmBgYHtyfQoKb3JkX2Nsci5wdyA8LSBwaHlsb3NlcTo6b3JkaW5hdGUocHNfY2xyLnB3LCAiUkRBIikKI0V4YW1pbmUgZWlnZW52YWx1ZXMgYW5kICUgcHJvcC4gdmFyaWFuY2UgZXhwbGFpbmVkCiAgaGVhZChvcmRfY2xyLnB3JENBJGVpZykKc2FwcGx5KG9yZF9jbHIucHckQ0EkZWlnWzE6OF0sIGZ1bmN0aW9uKHgpIHggLyBzdW0ob3JkX2Nsci5wdyRDQSRlaWcpKQpgYGAKIAogCiMjICBDb3JyZWxhdGlvbnMgb2Ygc29pbCB2YXJpYWJsZXMgdG8gUEMxLCBQQzIgYW5kIFBDMyAod2l0aCBCSCBjb3JyZWN0ZWQgKnAqLXZhbHVlcykgCmBgYHtyLCBlY2hvPUZBTFNFfQpjbHJfcGNzLnB3IDwtIGRhdGEuZnJhbWUoCiAgInBjMSIgPSBvcmRfY2xyLnB3JENBJHVbLDFdLAogICJwYzIiID0gb3JkX2Nsci5wdyRDQSR1WywyXSwKICAicGMzIiA9IG9yZF9jbHIucHckQ0EkdVssM10pICU+JSAKICByb3duYW1lc190b19jb2x1bW4oIiNTYW1wbGVJRCIpICU+JQogIGxlZnRfam9pbihtZXRhZGF0YTMpCmBgYAogCmBgYHtyLCBlY2hvPUZBTFNFfQpyZXF1aXJlKHBzeWNoKQpyZXF1aXJlKHJlc2hhcGUyKQpjb3JyZWxhdGlvbl9tYXRyaXg9Y29yci50ZXN0KGNscl9wY3MucHcgWyxjKCJwYzEiLCJwYzIiLCAicGMzIiwiRDE1MTciLCJwcERERSIsICJwcEREVCIsICJERFQxNTE3IiwgIlRDIiwiVE4iLCJDTiIgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAsIkhDIiwgIlAiLCAgICJDUCIgLCJwSCIgLCJiX2NvcGllc19uZ0ROQSIgLCJmX2NvcGllc19uZ0ROQSIsIkRsb3NzIiAsIkREVGxvc3MiLCJDX1NhbmQiLCJGX1NhbmQiICwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVF9TYW5kIiwiU2lsdF8xIiwgIkNsYXlfMSIsIk9yZ2FuaWMgTWF0dGVyIiwgIkZpZWxkIENhcGFjaXR5IiwgIldpbHRpbmcgUG9pbnQiLCAiS2FvbGluaXRlJSIgLCJJbGxpdGUlIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU21lY3RpdGUlIiwgIkdpYmJzaXRlJSIgLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNsYXlfdG90YWwiLCJQYXJ0aWN1bGF0ZUMiLCJIdW11cyIgLCJSZXNpc3RhbnRDIiAsICJEZWx0YS5DLkZyYWMiLCJPYnNlcnZlZC54IiwgInBpZWxvdV9ldiIsIlNoYW5ub24ueCIpXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRob2Q9InNwZWFybWFuIiwgYWRqdXN0PSJob2xtIikKcl9tYXRyaXg9Y29ycmVsYXRpb25fbWF0cml4JHIKcl9tYXRyaXhbcm93KHJfbWF0cml4KT5jb2wocl9tYXRyaXgpXT0wCmRpYWcocl9tYXRyaXgpPTAKcF9tYXRyaXg9Y29ycmVsYXRpb25fbWF0cml4JHAKcF9tYXRyaXhbcm93KHBfbWF0cml4KT5jb2wocF9tYXRyaXgpXT0xCmRpYWcocF9tYXRyaXgpPTEKcl90YWJsZT1tZWx0KHJfbWF0cml4KQpwX3RhYmxlPW1lbHQocF9tYXRyaXgpCmNvcnRhYmxlLnB3IDwtIGRhdGEuZnJhbWUocl90YWJsZSRWYXIxLCByX3RhYmxlJFZhcjIsIHJfdGFibGUkdmFsdWUsIHBfdGFibGUkdmFsdWUpICNjcmVhdHMgdGhlIHRhYmxlIHdpdGggciBhbmQgcCB2YWx1ZXMKYGBgCgoKYGBge3IsIGVjaG89IEZBTFNFfQojZmlsdGVyIG9ubHkgcGMxIHJlbGF0ZWQgY29ycmVsYXRpb25zCnBjMV9jb3IucHcgPC0gY29ydGFibGUucHcgJT4lIAogIGZpbHRlcihyX3RhYmxlLlZhcjEgPT0gInBjMSIgfCAKICAgICAgICAgICByX3RhYmxlLlZhcjIgPT0gInBjMSIpICU+JSAKICBmaWx0ZXIocF90YWJsZS52YWx1ZSA8PSAwLjEpICU+JQogIGFycmFuZ2UocF90YWJsZS52YWx1ZSkKP2FycmFuZ2UKI2ZpbHRlciBvbmx5IHBjMiByZWxhdGVkIGNvcnJlbGF0aW9ucwpwYzJfY29yLnB3IDwtIGNvcnRhYmxlLnB3ICU+JSAKICBmaWx0ZXIocl90YWJsZS5WYXIxID09ICJwYzIiIHwgCiAgICAgICAgICAgcl90YWJsZS5WYXIyID09ICJwYzIiKSAlPiUgCiAgZmlsdGVyKHBfdGFibGUudmFsdWUgPD0gMC4xKSAlPiUKICBhcnJhbmdlKHBfdGFibGUudmFsdWUpCgojZmlsdGVyIG9ubHkgcGMzIHJlbGF0ZWQgY29ycmVsYXRpb25zCnBjM19jb3IucHcgPC0gY29ydGFibGUucHcgJT4lIAogIGZpbHRlcihyX3RhYmxlLlZhcjEgPT0gInBjMyIgfCAKICAgICAgICAgICByX3RhYmxlLlZhcjIgPT0gInBjMyIpJT4lIAogIGZpbHRlcihwX3RhYmxlLnZhbHVlIDw9IDAuMSkgJT4lCiAgYXJyYW5nZShwX3RhYmxlLnZhbHVlKQpwYzFfY29yLnB3CnBjMl9jb3IucHcKcGMzX2Nvci5wdwpgYGAKCiMjIyBDTiBjb3JyZWxhdGlvbnMgd2l0aCBvdGhlciBzb2lsIHZhcmlhYmxlcyAoY29tcGFyaW5nIDM2IHNvaWwgdmFyaWFibGVzLCBCSCAqcCogPCAwLjA1KQpgYGB7ciwgZWNobz0gRkFMU0V9CiNmaWx0ZXIgb25seSBwYzEgcmVsYXRlZCBjb3JyZWxhdGlvbnMKQ05fY29yLnB3IDwtIGNvcnRhYmxlLnB3ICU+JSAKICBmaWx0ZXIocl90YWJsZS5WYXIxID09ICJDTiIgfCAKICAgICAgICAgICByX3RhYmxlLlZhcjIgPT0gIkNOIikgJT4lIAogIGZpbHRlcihwX3RhYmxlLnZhbHVlIDw9IDAuMDUpICU+JQogIGFycmFuZ2UocF90YWJsZS52YWx1ZSkKa2FibGUoQ05fY29yLnB3KQpgYGAKCgojIyMgIFBDQSBwbG90IGZvciBLRUdHIHBhdGh3YXlzIApgYGB7ciBmaWcuaGVpZ2h0PTUsIGZpZy53aWR0aD02LCBlY2hvPUZBTFNFfQojIyMjIyBwbG90MSBzaG93aW5nIEh1bXVzIGFzIGNvbG91ciBncmFkaWVudAojIFNjYWxlIGF4ZXMgYW5kIHBsb3Qgb3JkaW5hdGlvbgpjbHIxLnB3IDwtIG9yZF9jbHIucHckQ0EkZWlnWzFdIC8gc3VtKG9yZF9jbHIucHckQ0EkZWlnKQpjbHIyLnB3IDwtIG9yZF9jbHIucHckQ0EkZWlnWzJdIC8gc3VtKG9yZF9jbHIucHckQ0EkZWlnKQpwMS4xIDwtIHBoeWxvc2VxOjpwbG90X29yZGluYXRpb24ocHNfY2xyLnB3LCBvcmRfY2xyLnB3LCB0eXBlPSJzYW1wbGVzIiwgY29sb3IgPSAiQ04iLCBzaGFwZT0gIlNvaWwiKSArCiAgICBnZW9tX3BvaW50KGFlcyhzaXplID0gRGxvc3MpKSArCiAgICBjb29yZF9maXhlZChjbHIyLnB3IC8gY2xyMS5wdykgKwogICAgc2NhbGVfc2l6ZShicmVha3MgPSBjKDMwLDUwLDgwKSkrCiAgICBzY2FsZV9jb2xvdXJfZ3JhZGllbnQobG93ID0gImdyZXkiLCBoaWdoID0gImJsYWNrIikrCiAgZ2d0aXRsZSgiUENBIG9uIHBpY3J1c3QgcHJlZGljdGlvbnMiLCBzdWJ0aXRsZSA9ICIoY2VudHJlZC1sb2cgcmF0aW8pIikKcDEuMQpgYGAKCiMjIyBQYXRod2F5cyBjb250cmlidXRpbmcgdG8gdGhlIHZhcmlhdGlvbiBpbiBQQzEsIFBDMiBhbmQgUEMzCmBgYHtyIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTgsIGVjaG89VFJVRX0KCgppbmQuY29vcmQucHcgPC0gZGF0YS5mcmFtZShvcmRfY2xyLnB3JENBJHYpCnNkZXZfaW5kLnB3IDwtIGFwcGx5KGluZC5jb29yZC5wdywgMSwgc2QpCmluZF9jb250X1BDQTEucHcgPC0gZGF0YS5mcmFtZShQQ0EgPSAoMTAwKigxIC8gbnJvdyhpbmQuY29vcmQucHcpKihpbmQuY29vcmQucHckUEMxXjIgL3NkZXZfaW5kLnB3KSkpKQppbmRfY29udF9QQ0ExX3RvcC5wdyA8LSBpbmRfY29udF9QQ0ExLnB3ICU+JSAKICByb3duYW1lc190b19jb2x1bW4oIm90dSIpICU+JSAKICBmaWx0ZXIoUENBID49IDAuMDA4KSU+JSAKICBjb2x1bW5fdG9fcm93bmFtZXMoIm90dSIpCmluZF9jb250X1BDQTIucHcgPC0gZGF0YS5mcmFtZShQQ0EgPSAoMTAwKigxIC8gbnJvdyhpbmQuY29vcmQucHcpKihpbmQuY29vcmQucHckUEMyXjIgL3NkZXZfaW5kLnB3KSkpKQppbmRfY29udF9QQ0EyX3RvcC5wdyA8LSBpbmRfY29udF9QQ0EyLnB3ICU+JSAKICByb3duYW1lc190b19jb2x1bW4oIm90dSIpICU+JSAKICBmaWx0ZXIoUENBID49IDAuMDIpJT4lIAogIGNvbHVtbl90b19yb3duYW1lcygib3R1IikKaW5kX2NvbnRfUENBMy5wdyA8LSBkYXRhLmZyYW1lKFBDQSA9ICgxMDAqKDEgLyBucm93KGluZC5jb29yZC5wdykqKGluZC5jb29yZC5wdyRQQzNeMiAvIHNkZXZfaW5kLnB3KSkpKQppbmRfY29udF9QQ0EzX3RvcC5wdyA8LSBpbmRfY29udF9QQ0EzLnB3ICU+JSAKICByb3duYW1lc190b19jb2x1bW4oIm90dSIpICU+JSAKICBmaWx0ZXIoUENBID49IDAuMDMpJT4lIAogIGNvbHVtbl90b19yb3duYW1lcygib3R1IikKaW5kX2NvbnRfUENBX3RvcC5wdyA8LSByYmluZChpbmRfY29udF9QQ0ExX3RvcC5wdywgaW5kX2NvbnRfUENBMl90b3AucHcsIGluZF9jb250X1BDQTNfdG9wLnB3KQpgYGAKCmBgYHtyIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTgsIGVjaG89VFJVRX0KIyBwbG90IHNob3dpbmcgcGF0aHdheXMgdGhhdCBhcmUgY29udHJpYnV0aW5nIHRoZSBtb3N0CmNscjEucHcgPC0gb3JkX2Nsci5wdyRDQSRlaWdbMV0gLyBzdW0ob3JkX2Nsci5wdyRDQSRlaWcpCmNscjIucHcgPC0gb3JkX2Nsci5wdyRDQSRlaWdbMl0gLyBzdW0ob3JkX2Nsci5wdyRDQSRlaWcpCnAxLjIgPC0gcGh5bG9zZXE6OnBsb3Rfb3JkaW5hdGlvbihwc19jbHIucHcsIG9yZF9jbHIucHcsIHR5cGU9InRheGEiKSArCiAgICBjb29yZF9maXhlZChjbHIyLnB3IC8gY2xyMS5wdykgKwogIGdndGl0bGUoIlBDQSBvbiBwaWNydXN0IHByZWRpY3Rpb25zIiwgc3VidGl0bGUgPSAiKGNlbnRyZWQtbG9nIHJhdGlvKSIpCgpwMS4yJGRhdGEgPC0gIHAxLjIkZGF0YSAgJT4lIHJvd25hbWVzX3RvX2NvbHVtbih2YXIgPSAiT1RVIikgJT4lICBmaWx0ZXIoT1RVICVpbiUgcm93bmFtZXMoaW5kX2NvbnRfUENBX3RvcC5wdykpCnJlcXVpcmUoZ2dyZXBlbCkKcDEuMiArIGdlb21fdGV4dF9yZXBlbChsYWJlbCA9IHAxLjIkZGF0YSRPVFUpICsKICAgIGNvb3JkX2ZpeGVkKHhsaW0gPSBjKC0yLjUsMi41KSkgCmBgYAoKYGBge3IgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9OCwgZWNobz1UUlVFfQpzdW0oaW5kX2NvbnRfUENBMV90b3AucHckUENBKSAvIHN1bShpbmRfY29udF9QQ0ExLnB3JFBDQSkKbnJvdyhpbmRfY29udF9QQ0ExX3RvcC5wdykKaW5kX2NvbnRfUENBMV90b3AucHcgJT4lIHJvd25hbWVzX3RvX2NvbHVtbigpICU+JSBhcnJhbmdlKGRlc2MoUENBKSkKYGBgCgozMCBwYXRod2F5cyBjb250cmlidXRlIDg2JSBvZiB0aGUgdmFyaWF0aW9uIHRvIFBDMQoKCgpgYGB7ciBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD04LCBlY2hvPVRSVUV9CnN1bShpbmRfY29udF9QQ0EyX3RvcC5wdyRQQ0EpIC8gc3VtKGluZF9jb250X1BDQTIucHckUENBKQpucm93KGluZF9jb250X1BDQTJfdG9wLnB3KQppbmRfY29udF9QQ0EyX3RvcC5wdyAgJT4lIHJvd25hbWVzX3RvX2NvbHVtbigpICU+JSBhcnJhbmdlKGRlc2MoUENBKSkKYGBgCjE0IHBhdGh3YXlzIGNvbnRyaWJ1dGUgOTIlIG9mIHRoZSB2YXJpYXRpb24gdG8gUEMyCgpgYGB7ciBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD04LCBlY2hvPVRSVUV9CnN1bShpbmRfY29udF9QQ0EzX3RvcC5wdyRQQ0EpIC8gc3VtKGluZF9jb250X1BDQTMucHckUENBKQpucm93KGluZF9jb250X1BDQTNfdG9wLnB3KQppbmRfY29udF9QQ0EzX3RvcC5wdyAlPiUgcm93bmFtZXNfdG9fY29sdW1uKCkgJT4lIGFycmFuZ2UoZGVzYyhQQ0EpKQpgYGAKMTIgcGF0aHdheXMgY29udHJpYnV0ZSA5NCUgb2YgdmFyaWF0aW9uIG9mIFBDMwoKCgojIyBQYXRod2F5IChjbHIgdHJhbnNmb3JtZWQpIGNvcnJlbGF0aW9ucyB3aXRoIGRpZWxkcmluIGxvc3MKcHJlLWZpbHRlcmluZyB0aGUgY2xyLXRyYW5zZm9ybWVkIHBhdGh3YXkgcHJlZGljdGlvbnMgdGhhdCBjb3JyZWxhdGUgd2l0aCBEbG9zcyAgCihTcGVhcm1hbiwgYm9uZmVycm9uaSBjb3JyZWN0ZWQgKnAqLXZhbHVlcykKCmBgYHtyLCBlY2hvID0gRkFMU0UsIHdhcm5pbmc9RkFMU0V9CkRsb3NzIDwtIG1ldGFkYXRhMiREbG9zcwpvdHV0YWJsZS5wdyA8LSBwaHlsb3NlcTo6b3R1X3RhYmxlKHBzX2Nsci5wdykgJT4lIHQgJT4lIGFzLmRhdGEuZnJhbWUoKSAKb3R1dGFibGUucHcgPC0gb3R1dGFibGUucHdbbWF0Y2gobWV0YWRhdGEyJGAjU2FtcGxlSURgLCByb3cubmFtZXMob3R1dGFibGUucHcpKSxdICNtYWtlIHN1cmUgaXRzIGluIG9yZGVyIHdpdGggdmFyaWFibGUKdGVzdC5wdyA8LSBhcHBseShvdHV0YWJsZS5wdyAsMiwgY29yLnRlc3QsIERsb3NzLCBtZXRob2QgPSAic3BlYXJtYW4iKQp0ZXN0LnB3LnAgPC0gZGF0YS5mcmFtZShwdmFscyA9IHNhcHBseSh0ZXN0LnB3LCAiW1siLCAicC52YWx1ZSIpKQp0ZXN0LnB3LnAkcHZhbC5hZGogPC0gcC5hZGp1c3QodGVzdC5wdy5wJHB2YWxzLCBtZXRob2QgPSAiYm9uZmVycm9uaSIsIG4gPSBsZW5ndGgodGVzdC5wdy5wJHB2YWxzKSkKdGVzdC5wdy5wLnNpZyA8LSAgdGVzdC5wdy5wICU+JSAKICByb3duYW1lc190b19jb2x1bW4odmFyID0gIktPIiklPiUgCiAgICBmaWx0ZXIocHZhbC5hZGogPD0gMC4wNSklPiUKICAgIGFycmFuZ2UocHZhbC5hZGopCnRlc3QucHcucC5zaWcKYGBgCgojIyMgVGhlIG5vdm9iaW9jaW4gYmlvc3ludGhlc2lzIGFuZCB0aGUgcGF0aHdheSBmb3IgeC1tZW1iZXJlZCBtYWNyb2xpZGVzIHdlcmUgYWxzbyBpZGVudGlmaWVkIGFzIHNpZ25pZmlhbnQgdXNpbmcgdGhlIGFsZGV4IHBhY2thZ2Ugd2l0aCBmdW5jdGlvbiBhbGRleC5jb3JyCiMjIyBJbiB0b3RhbCB0aGVyZSB3ZXJlIDE3IHNpZ25pZmljYW50IHBhdGh3YXlzIChCSCA8IDAuMSkgYmFzZWQgb24gYWxkZXguY29ycgojIyMjIChEaWVsZHJpbiBjb25jZW50cmF0aW9ucyB3ZXJlIG5vdCBzaWduaWZpY2FudGx5IGFzc29jaWF0ZWQgd2l0aCBhbnkgcGF0aHdheXMgKGFsZGV4LmNvcnIpLCBvbmx5IGRpZWxkcmluIGxvc3MpIAoKYGBge3IgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KYWx4LmNvci5zaWcgPC0gcmVhZF9jc3YoIn4vRG9jdW1lbnRzL1N0dWR5L0xhVHJvYmUvUmVzZWFyY2gvcGhEL01pbGVzdG9uZTJfRmllbGRfU3VydmV5L00yX0JhY3RlcmlhL1BpY3J1c3QvYWx4LmNvci5zaWdfS0VHR3BhdGh3YXlzX2Rsb3NzXzIwMjAwMTkuY3N2IikgJT4lIGFycmFuZ2UoQkgpCmthYmxlKGFseC5jb3Iuc2lnKQpgYGAKCgpgYGB7ciBmaWcuaGVpZ2h0PTcsIGZpZy53aWR0aD0xMCwgZWNobz1GQUxTRX0KY2xzIDwtIGMoImdyZXk4IiwiYmx1ZSIpCnBzX2Nsci5tbHQucHcgPC0gcHNtZWx0KHBzX2Nsci5wdykgI21lbHQgZGF0YWZyYW1lIGZvciBwbG90dGluZwpwc19jbHIubWx0LnB3ICA8LSBwc19jbHIubWx0LnB3ICAlPiUgc3Vic2V0KE9UVSAlaW4lIGFzLnZlY3RvcihhbHguY29yLnNpZyRyb3duYW1lKSkgI2ZpbHRlciB0aGUgRUNzIHRoYXQgc2lnbmlmaWNhbnQgY29ycmVsYXRlIHdpdGggUEMxLDIgYW5kIDMKcHNfY2xyLm1sdC5wdyAlPiUgCiAgZ2dwbG90KGRhdGEgPSAuLCBhZXMoeCA9IERsb3NzLCB5ID0gQWJ1bmRhbmNlKSkrCiAgZ2VvbV9wb2ludChhZXMoY29sb3IgPSBTb2lsLCBzaGFwZSA9IFNvaWwpKSArCiAgbGFicyh4ID0gIiIsIHkgPSAiQWJ1bmRhbmNlIChjbHIpXG4iKSArCiAgZmFjZXRfd3JhcCh+IE9UVSwgc2NhbGVzID0gImZyZWUiKSArCiAgZ2d0aXRsZSgiUGF0aHdheSBwcmVkaWN0aW9ucyB2cyBEbG9zcyAoYWxkZXguY29yciwgQkggPCAwLjEpIikrIAogIHRoZW1lKHN0cmlwLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgpKSsKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGNscykgCiAgI3N0YXRfY29yKG1ldGhvZCA9ICJzcGVhcm1hbiIsbGFiZWwueS5ucGMgPSAiYm90dG9tIikKYGBgCiMjIGJveHBsb3RzIG9mIGRlZ3JhZGF0aW9uIHBhdGh3YXlzCmBgYHtyIGVjaG89LCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD0xMH0KcHNfY2xyLm1sdC5wdyAlPiUgCiAgZmlsdGVyKHN0cl9kZXRlY3QoT1RVLCJkZWdyYWRhdGlvbiIpIHwKICAgICAgICAgICBzdHJfZGV0ZWN0KE9UVSwiQUJDIikpICU+JSAKICBnZ2JveHBsb3QoZGF0YSA9IC4sIHggPSAiRGxvc3NfZmN0IiwgeSA9ICJBYnVuZGFuY2UiLCAKICAgICAgICAgICAgZmFjZXQuYnkgPSAiT1RVIiwgY29sb3IgPSAiU29pbCIsIHNoYXBlID0gIlNvaWwiKSArIAogIGxhYnMoeCA9ICIiLCB5ID0gIkFidW5kYW5jZSAoY2xyKVxuIikgKwogIGdndGl0bGUoIlBhdGh3YXkgcHJlZGljdGlvbnMgdnMgRGxvc3MgKGFsZGV4LmNvcnIsIEJIIDwgMC4xKSIpKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGNscykKYGBgCiMjIGJveHBsb3RzIG9mIHJlbWFpbmluZyBwYXRod2F5cwpgYGB7ciBlY2hvPSwgZmlnLmhlaWdodD01LCBmaWcud2lkdGg9Nn0KcHNfY2xyLm1sdC5wdyAlPiUgCiAgZmlsdGVyKHN0cl9kZXRlY3QodG9sb3dlcihPVFUpLCJiaW9zeW50aGVzaXN8ZmFjdG9yIikpICU+JSAKICBnZ2JveHBsb3QoZGF0YSA9IC4sIHggPSAiRGxvc3NfZmN0IiwgeSA9ICJBYnVuZGFuY2UiLCAKICAgICAgICAgICAgZmFjZXQuYnkgPSAiT1RVIiwgY29sb3IgPSAiU29pbCIsIHNoYXBlID0gIlNvaWwiKSArIAogIGxhYnMoeCA9ICIiLCB5ID0gIkFidW5kYW5jZSAoY2xyKVxuIikgKwogIGdndGl0bGUoIlBhdGh3YXkgcHJlZGljdGlvbnMgdnMgRGxvc3MgKGFsZGV4LmNvcnIsIEJIIDwgMC4xKSIpKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGNscykKYGBgCgoKCiMjIyBIb3cgbWFueSBvZiB0aG9zZSBwYXRod2F5cyBhcmUgYWxzbyBhc3NvY2lhdGVkIHdpdGggUEMxLCBQQzIgb3IgUEMzPwpgYGB7cn0KaW5kX2NvbnRfUENBX3RvcC5wdyAgJT4lIHJvd25hbWVzX3RvX2NvbHVtbih2YXIgPSAicGF0aHdheSIpICU+JSAKICBzdWJzZXQocGF0aHdheSAlaW4lIGFzLnZlY3RvcihhbHguY29yLnNpZyRyb3duYW1lKSkKYGBgCgojIyBBbmNvbSBzaWduaWZpY2FudCBkaWZmZXJlbnQgcGF0aHdheXMgYnkgc29pbAoKIVtBbmNvbV0oL1VzZXJzL2NocmlzdGlhbmtyb2huL0FwcGxpY2F0aW9ucy9SU3R1ZGlvL1Jfbm90ZWJvb2tzL3Zpc3VhbGl6YXRpb24ucG5nKQoKYGBge3IsIGVjaG89IEZBTFNFLCB3YXJuaW5nPUZBTFNFLCAgbWVzc2FnZT1GQUxTRX0KI3BhdGh3YXkucHJlZCAgJT4lIHQgJT4lIGFzLmRhdGEuZnJhbWUoKSAlPiUgcm93bmFtZXNfdG9fY29sdW1uKHZhciA9ICIjU2FtcGxlSUQiKSAlPiUKIyAgbGVmdF9qb2luKG1ldGFkYXRhMywgYnkgPSAnI1NhbXBsZUlEJyklPiUgCiMgIHNlbGVjdChtYXRjaGVzKCdzYW1wbGV8U29pbHxlY218bWFjcm9saWRlcycpKSU+JSBncm91cF9ieShTb2lsKSAlPiUgc3VtbWFyaXNlX2FsbChsaXN0KG1lYW4pKQoKYnAxIDwtIHBhdGh3YXkucHJlZCAgJT4lIHQgJT4lIGFzLmRhdGEuZnJhbWUoKSAlPiUgcm93bmFtZXNfdG9fY29sdW1uKHZhciA9ICIjU2FtcGxlSUQiKSAlPiUKICBsZWZ0X2pvaW4obWV0YWRhdGEzLCBieSA9ICcjU2FtcGxlSUQnKSAlPiUgCiAgICBtZWx0KGRhdGEgPSAuKSAlPiUgCiAgICBmaWx0ZXIoc3RyX2RldGVjdCh0b2xvd2VyKHZhcmlhYmxlKSwiZWNtfG1hY3JvbGlkZXN8aXNvZmxhdm9ub2lkfGludmFzaW9uIikpICU+JSAKICAgIGdnYmFycGxvdChkYXRhID0gLiwgeCA9ICJ2YXJpYWJsZSIsIHkgPSAidmFsdWUiLCBhZGQgPSAibWVhbl9zZSIsIG9yaWVudGF0aW9uID0gImhvcml6IiwgZmlsbCA9ICJTb2lsIixwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuNyksIHdpZHRoID0gMC41LCB0aXRsZSA9ICJBYnNvbHV0ZSBwYXRod2F5IHByZWRpY3Rpb24iLCB4bGFiID0gIiIpICsgCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gY2xzKQoKYnAyIDwtICAgb3R1dGFibGUucHcgJT4lIHJvd25hbWVzX3RvX2NvbHVtbih2YXIgPSAiI1NhbXBsZUlEIikgICU+JQogIGxlZnRfam9pbihtZXRhZGF0YTMsIGJ5ID0gJyNTYW1wbGVJRCcpICU+JSAKICAgIG1lbHQoZGF0YSA9IC4pICU+JSAKICAgIGZpbHRlcihzdHJfZGV0ZWN0KHRvbG93ZXIodmFyaWFibGUpLCJlY218bWFjcm9saWRlc3xpc29mbGF2b25vaWR8aW52YXNpb24iKSkgJT4lIAogICAgZ2dib3hwbG90KGRhdGEgPSAuLCB4ID0gInZhcmlhYmxlIiwgeSA9ICJ2YWx1ZSIsIG9yaWVudGF0aW9uID0gImhvcml6IiwgZmlsbCA9ICJTb2lsIiwgdGl0bGUgPSAiY2xyIHJhdGlvcyIsIHhsYWIgPSAiIikgKyAKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjbHMpCgpicDEKYnAyCmBgYAoKIyMgQWxkZXggKGFsZGV4LmNscihhbGRleC5kZiwgY29uZCwgbWMuc2FtcGxlcz0xMDAwMCwgZGVub209ImlxbHIiLCB2ZXJib3NlPUYpIHRvIGZpbmQgc2lnbmlmaWNhbnQgZGlmZmVyZW50IHBhdGh3YXlzIGZvciBlYWNoIHNvaWwgKDI5IHBhdGh3YXlzICpwKiA8PSAwLjAxIEJIIGNvcnJlY3RlZCkKCmBgYHtyIGVjaG89RkFMU0UsIGZpZy5oZWlnaHQ9OCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KYWx4LnR0ZXN0X3B3X3NvaWwgPC0gcmVhZF9jc3YoIn4vRG9jdW1lbnRzL1N0dWR5L0xhVHJvYmUvUmVzZWFyY2gvcGhEL01pbGVzdG9uZTJfRmllbGRfU3VydmV5L00yX0JhY3RlcmlhL1BpY3J1c3QvYWxkZXgueC5hbGxfa2VnZ3B3X3NvaWwuY3N2IikgJT4lIGFycmFuZ2Uod2UuZUJIKSAlPiUgZmlsdGVyKHdlLmVCSCA8PSAwLjAxKQoKZmlsdC52YyA8LSBhbHgudHRlc3RfcHdfc29pbCRYMQpicDMgPC0gcGF0aHdheS5wcmVkICAlPiUgdCAlPiUgYXMuZGF0YS5mcmFtZSgpICU+JSByb3duYW1lc190b19jb2x1bW4odmFyID0gIiNTYW1wbGVJRCIpICU+JQogIGxlZnRfam9pbihtZXRhZGF0YTMsIGJ5ID0gJyNTYW1wbGVJRCcpICU+JSAKICAgIG1lbHQoZGF0YSA9IC4pICU+JSAKICAgIGZpbHRlcih2YXJpYWJsZSAlaW4lIGZpbHQudmMpICU+JSAKICAgIGdnYmFycGxvdChkYXRhID0gLiwgeCA9ICJ2YXJpYWJsZSIsIHkgPSAidmFsdWUiLCBhZGQgPSAibWVhbl9zZSIsIG9yaWVudGF0aW9uID0gImhvcml6IiwgZmlsbCA9ICJTb2lsIixwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuNyksIHdpZHRoID0gMC41LCB0aXRsZSA9ICJBYnNvbHV0ZSBwYXRod2F5IHByZWRpY3Rpb24iLCB4bGFiID0gIiIpICsgCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gY2xzKQoKCmJwNCA8LSBvdHV0YWJsZS5wdyAlPiUgcm93bmFtZXNfdG9fY29sdW1uKHZhciA9ICIjU2FtcGxlSUQiKSAgJT4lCiAgbGVmdF9qb2luKG1ldGFkYXRhMywgYnkgPSAnI1NhbXBsZUlEJykgJT4lIAogICAgbWVsdChkYXRhID0gLikgJT4lIAogICBmaWx0ZXIodmFyaWFibGUgICVpbiUgIGFzLnZlY3RvcihhbHgudHRlc3RfcHdfc29pbCRYMSkpICU+JSAKICAgIGdnYm94cGxvdChkYXRhID0gLiwgeCA9ICJ2YXJpYWJsZSIsIHkgPSAidmFsdWUiLCBvcmllbnRhdGlvbiA9ICJob3JpeiIsIGZpbGwgPSAiU29pbCIsIHRpdGxlID0gImNsciByYXRpb3MiLCB4bGFiID0gIiIpICsgCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gY2xzKQoKYnAzCmJwNApgYGAKCgoKCgoKCgoK