index.html annotation.html sample_estimations.html differential_expression.html

In this document, we will perform a series of differential expression analyses using the data which survived sample estimation.

1 Gene Ontology searches

Lets set up some simple data sets for goseq/clusterProfiler/topGO

I think a bunch of the material in this sheet is actually now obsolete.

1.1 Extracting ontology annotations from the TriTrypDB

I need to extract the ontology/pFAM data from the Tcruzi annotation tables.

I have a perl script ‘dump_tritryp_GO.pl’ which can do this for me.

cd $LAB/ref_data/gene_ontology/
./dump_tritryp_GO.pl $LAB/ref_data/tritryp_text/Tcruzi.txt > tcruzi_go.tab
## The actual commands were slightly different, just because I didn't feel like copy/pasting the filenames.

1.2 Preparing to use goseq

I need a couple vectors before being able to use goseq I also need some rda files generated for clusterProfiler and topGO but I will do those later…

## goseq uses the gene lengths, clusterprofiler and topgo don't
## gene_lengths <- all_genes[,c("geneid","genesize")]
## colnames(gene_lengths) <- c("ID", "width")
colnames(all_lengths) <- c("ID", "width")
## go_ids needs to be a 2 column data frame with names 'ID', 'GO' which are
## gene names and GO names respectively.  I actually think I made my goseq() function
## smart enough that this is no longer needed, but nonetheless.

## go_ids <- read.table("reference/go/tcruzi_all_go.tab.gz", header=0, sep="\t")
## colnames(go_ids) <- c("ID","GO","ontology","term","source")
## Since there are multiple sources, I am doing a unique of the table...
## go_ids <- unique(go_ids[,c("ID","GO")])
## goid_file <- "reference/go/topgo_goids.tab.gz"

colnames(all_go) <- c("ID", "GO")
## First relax the input as perl the name of this file.
clbr_times_sigfiltv2 <- sm(extract_significant_genes(clbr_times_filtered, according_to="limma", p=0.1,
                                                excel=paste0("excel/clb_times_filtered_relaxedp-v", ver, ".xlsx")))
cl14_times_sigfiltv2 <- sm(extract_significant_genes(cl14_times_filtered, according_to="limma", p=0.1,
                                                excel=paste0("excel/cl14_times_filtered_relaxedp-v", ver, ".xlsx")))
strains_sigfiltv2 <- sm(extract_significant_genes(strains_filtered, according_to="limma", p=0.1,
                                               excel=paste0("excell/strain_comparisons_filtered_relaxedp-v", ver, ".xlsx")))

clbr_up_a96tryp_goseq <- sm(simple_goseq(sig_genes=clbr_times_sigfiltv2$limma$ups$clbr_a96_to_tryp,
                                         go_db=all_go, length_db=all_lengths))

clbr_up_a96tryp_goseq$pvalue_plots$bpp_plot_over

clbr_up_a96tryp_excel <- sm(write_goseq_data(clbr_up_a96tryp_goseq,
                                             excel=paste0("excel/clbr_up_a96tryp_goseq_relaxedp-v", ver, ".xlsx")))

clbr_down_a96tryp_goseq <- sm(simple_goseq(sig_genes=clbr_times_sigfiltv2$limma$downs$clbr_a96_to_tryp,
                                           go_db=all_go, length_db=all_lengths))

clbr_down_a96tryp_goseq$pvalue_plots$bpp_plot_over

clbr_down_a96tryp_excel <- sm(write_goseq_data(clbr_down_a96tryp_goseq,
                                               excel=paste0("excel/clbr_down_a96tryp_goseq_relaxedp-v", ver, ".xlsx")))

clbr_up_a60a96_goseq <- sm(simple_goseq(sig_genes=clbr_times_sigfiltv2$limma$ups$clbr_a60_to_a96,
                                        go_db=all_go, length_db=all_lengths))

clbr_up_a60a96_goseq$pvalue_plots$bpp_plot_over

clbr_up_a60a96_excel <- sm(write_goseq_data(clbr_up_a60a96_goseq,
                                            excel=paste0("excel/clbr_up_a60a96_goseq_relaxedp-v", ver, ".xlsx")))

clbr_down_a60a96_goseq <- sm(simple_goseq(sig_genes=clbr_times_sigfiltv2$limma$downs$clbr_a60_to_a96,
                                          go_db=all_go, length_db=all_lengths))

clbr_down_a60a96_goseq$pvalue_plots$bpp_plot_over

clbr_down_a60a96_excel <- sm(write_goseq_data(clbr_down_a60a96_goseq,
                                              excel=paste0("excel/clbr_down_a60a96_goseq_relaxedp-v", ver, ".xlsx")))

clbr_up_trypa60_goseq <- sm(simple_goseq(sig_genes=clbr_times_sigfiltv2$limma$ups$clbr_tryp_to_a60,
                                         go_db=all_go, length_db=all_lengths))

clbr_up_trypa60_goseq$pvalue_plots$bpp_plot_over

clbr_up_trypa60_excel <- sm(write_goseq_data(clbr_up_trypa60_goseq,
                                             excel=paste0("excel/clbr_up_trypa60_goseq_relaxedp-v", ver, ".xlsx")))

clbr_down_trypa60_goseq <- sm(simple_goseq(sig_genes=clbr_times_sigfiltv2$limma$downs$clbr_tryp_to_a60,
                                           go_db=all_go, length_db=all_lengths))

clbr_down_trypa60_goseq$pvalue_plots$bpp_plot_over

clbr_down_trypa60_excel <- sm(write_goseq_data(clbr_down_trypa60_goseq,
                                               excel=paste0("excel/clbr_down_trypa60_goseq_relaxedp-v", ver, ".xlsx")))

cl14_up_a96tryp_goseq <- sm(simple_goseq(sig_genes=cl14_times_sigfiltv2$limma$ups$cl14_a96_to_tryp,
                                         go_db=all_go, length_db=all_lengths))

cl14_up_a96tryp_goseq$pvalue_plots$bpp_plot_over

cl14_up_a96tryp_excel <- sm(write_goseq_data(cl14_up_a96tryp_goseq,
                                             excel=paste0("excel/cl14_up_a96tryp_goseq_relaxedp-v", ver, ".xlsx")))

cl14_down_a96tryp_goseq <- sm(simple_goseq(sig_genes=cl14_times_sigfiltv2$limma$downs$cl14_a96_to_tryp,
                                           go_db=all_go, length_db=all_lengths))

cl14_down_a96tryp_goseq$pvalue_plots$bpp_plot_over

cl14_down_a96tryp_excel <- sm(write_goseq_data(cl14_down_a96tryp_goseq,
                                               excel=paste0("excel/cl14_down_a96tryp_goseq_relaxedp-v", ver, ".xlsx")))

cl14_up_a60a96_goseq <- sm(simple_goseq(sig_genes=cl14_times_sigfiltv2$limma$ups$cl14_a60_to_a96,
                                        go_db=all_go, length_db=all_lengths))

cl14_up_a60a96_goseq$pvalue_plots$bpp_plot_over

cl14_up_a60a96_excel <- sm(write_goseq_data(cl14_up_a60a96_goseq,
                                            excel=paste0("excel/cl14_up_a60a96_goseq_relaxedp-v", ver, ".xlsx")))

cl14_down_a60a96_goseq <- sm(simple_goseq(sig_genes=cl14_times_sigfiltv2$limma$downs$cl14_a60_to_a96,
                                          go_db=all_go, length_db=all_lengths))

cl14_down_a60a96_goseq$pvalue_plots$bpp_plot_over

cl14_down_a60a96_excel <- sm(write_goseq_data(cl14_down_a60a96_goseq,
                                              excel=paste0("excel/cl14_down_a60a96_goseq_relaxedp-v", ver, ".xlsx")))

cl14_up_trypa60_goseq <- sm(simple_goseq(sig_genes=cl14_times_sigfiltv2$limma$ups$cl14_tryp_to_a60,
                                         go_db=all_go, length_db=all_lengths))

cl14_up_trypa60_goseq$pvalue_plots$bpp_plot_over

cl14_up_trypa60_excel <- sm(write_goseq_data(cl14_up_trypa60_goseq,
                                             excel=paste0("excel/cl14_up_trypa60_goseq_relaxedp-v", ver, ".xlsx")))

cl14_down_trypa60_goseq <- sm(simple_goseq(sig_genes=cl14_times_sigfiltv2$limma$downs$cl14_tryp_to_a60,
                                           go_db=all_go, length_db=all_lengths))

cl14_down_trypa60_goseq$pvalue_plots$bpp_plot_over

cl14_down_trypa60_excel <- sm(write_goseq_data(cl14_down_trypa60_goseq,
                                               excel=paste0("excel/cl14_down_trypa60_goseq_relaxedp-v", ver, ".xlsx")))

strains_up_a60_goseq <- sm(simple_goseq(sig_genes=strains_sigfiltv2$limma$ups$a60_clbr_over_cl14,
                                        go_db=all_go, length_db=all_lengths))

strains_up_a96_goseq <- sm(simple_goseq(sig_genes=strains_sigfiltv2$limma$ups$a96_clbr_over_cl14,
                                        go_db=all_go, length_db=all_lengths))

strains_up_tryp_goseq <- sm(simple_goseq(sig_genes=strains_sigfiltv2$limma$ups$tryp_clbr_over_cl14,
                                         go_db=all_go, length_db=all_lengths))

strains_up_a60_excel <- sm(write_goseq_data(strains_up_a60_goseq,
                                            excel=paste0("excel/strains_upa60_goseq_relaxedp-v", ver, ".xlsx")))

strains_up_a96_excel <- sm(write_goseq_data(strains_up_a96_goseq,
                                            excel=paste0("excel/strains_upa96_goseq_relaxedp-v", ver, ".xlsx")))

strains_up_tryp_excel <- sm(write_goseq_data(strains_up_tryp_goseq,
                                             excel=paste0("excel/strains_uptryp_goseq_relaxedp-v", ver, ".xlsx")))

strains_down_a60_goseq <- sm(simple_goseq(sig_genes=strains_sigfiltv2$limma$downs$a60_clbr_over_cl14,
                                          go_db=all_go, length_db=all_lengths))

strains_down_a96_goseq <- sm(simple_goseq(sig_genes=strains_sigfiltv2$limma$downs$a96_clbr_over_cl14,
                                          go_db=all_go, length_db=all_lengths))

strains_down_tryp_goseq <- sm(simple_goseq(sig_genes=strains_sigfiltv2$limma$downs$tryp_clbr_over_cl14,
                                           go_db=all_go, length_db=all_lengths))

strains_down_a60_excel <- sm(write_goseq_data(strains_down_a60_goseq,
                                            excel=paste0("excel/strains_downa60_goseq_relaxedp-v", ver, ".xlsx")))

strains_down_a96_excel <- sm(write_goseq_data(strains_down_a96_goseq,
                                            excel=paste0("excel/strains_downa96_goseq_relaxedp-v", ver, ".xlsx")))

strains_down_tryp_excel <- sm(write_goseq_data(strains_down_tryp_goseq,
                                             excel=paste0("excel/strains_downtryp_goseq_relaxedp-v", ver, ".xlsx")))

1.3 Compare Epimastigotes between CL14 and CLBr, high expression

One important note here, I needed to modify the data structure from readGff() in clusterProfiler before it was able to successfully generate the file ‘geneTable.rda’ Unfortunately, I was watching a movie at the time and didn’t properly write down what I did. However, I did write it out in the function myr::Gff2GeneTable() but in order to make it work one must load readGff() from clusterProfiler. I think the real solution is for me to grab a version of readGff() from clusterProfiler and make it exportable so that it will work consistently.

## Changes in epimastigotes from CLBrener to CL14
pval_thresh <- 0.0001
epi_cl14clbr_table <- all_tables$epi_cl14clbr
epi_cl14clbr_summary <- summary(epi_cl14clbr_table$logFC)
epi_cl14clbr_pvals <- epi_cl14clbr_table$adj.P.Val
names(epi_cl14clbr_pvals) <- rownames(epi_cl14clbr_table)
## Extract the genes with high expression in CL14 compared to Brener and very low pvalues
epi_cl14clbr_high <- subset(epi_cl14clbr_table, logFC >= epi_cl14clbr_summary[5] & adj.P.Val <= pval_thresh)
## Do a goseq comparison of the high genes
epi_cl14clbr_high_go <- simple_goseq(epi_cl14clbr_high, lengths=gene_lengths, goids=go_ids)
epi_cl14clbr_high_go$pvalue_histogram
epi_cl14clbr_high_go$bpp_plot

summary(epi_cl14clbr_high_go)
fun <- epi_cl14clbr_high_go$godata_interesting
goseq_annotation <- goseq_table(fun)
## Oh crap, I cannot make trees until I generate a id2go R mapping, I will need to check my previous script for how to do that (I think I do it automatically in simple_topgo()...
##epi_cl14clbr_high_trees = goseq_trees(degenes=epi_cl14clbr_high, epi_cl14clbr_high_go)
## I had to hack the geneTable() function in order to make it not take infinite memory because it was trying to do some stupid merge of every gff column against every other column...
## Once the geneTable.rda file exists and included real information, this seems to work fine, though.
epi_cl14clbr_high_cl <- simple_clusterprofiler(epi_cl14clbr_high)
epi_cl14clbr_high_cl$bp_all_barplot
## The first time this is run in a fresh directory, it needs to be run like this:
## simple_topgo(epi_cl14clbr_high, goids_df=go_ids)
## setting goids_df will tell it to generate a table of genes->GO<-genes in the format expected.
epi_cl14clbr_high_top <- simple_topgo(epi_cl14clbr_high, goids=goid_file, pvals=epi_cl14clbr_pvals)

topgo_pval <- topgo_pval_plot(epi_cl14clbr_high_top)
topgo_pval$BP
top_trees <- topgo_trees(epi_cl14clbr_high_top)
top_trees$bp_fisher_tree

1.4 Compare Epimastigotes between CL14 and CLBr, low expression

## Extract the genes with low expression in CL14 compared to Brener and very low pvalues
epi_cl14clbr_low = subset(epi_cl14clbr_table, logFC <= epi_cl14clbr_summary[2] & adj.P.Val <= pval_thresh)
epi_cl14clbr_low_go = simple_goseq(de_genes=epi_cl14clbr_low, lengths=gene_lengths, goids=go_ids)
epi_cl14clbr_low_go$pvalue_histogram
epi_cl14clbr_low_go$bpp_plot
##epi_cl14clbr_low_cl = simple_clusterprofiler(epi_cl14clbr_low, gff="reference/gff/clbrener_8.1_complete_genes.gff.gz")
##epi_cl14clbr_low_cl$bp_all_barplot
epi_cl14clbr_low_top = simple_topgo(epi_cl14clbr_low, goids=goid_file, pvals=epi_cl14clbr_pvals)
topgo_pval = topgo_pval_plot(epi_cl14clbr_high_top)
topgo_pval$BP
top_trees = topgo_trees(epi_cl14clbr_low_top)
top_trees$bp_fisher_tree

1.5 Compare trypo CL14/CLBr

## Changes in epimastigotes from CLBrener to CL14
tryp_cl14clbr_table = all_tables$tryp_cl14clbr
tryp_cl14clbr_summary = summary(tryp_cl14clbr_table$logFC)
tryp_cl14clbr_pvals = tryp_cl14clbr_table$adj.P.Val
names(tryp_cl14clbr_pvals) = rownames(tryp_cl14clbr_table)
## Extract the genes with high expression in CL14 compared to Brener and very low pvalues
tryp_cl14clbr_high = subset(tryp_cl14clbr_table, logFC >= tryp_cl14clbr_summary[5] & adj.P.Val <= pval_thresh)
## Do a goseq comparison of the high genes
tryp_cl14clbr_high_go = simple_goseq(tryp_cl14clbr_high, lengths=gene_lengths, goids=go_ids)
tryp_cl14clbr_high_go$pvalue_histogram
tryp_cl14clbr_high_go$bpp_plot
## Oh crap, I cannot make trees until I generate a id2go R mapping, I will need to check my previous script for how to do that (I think I do it automatically in simple_topgo()...
##tryp_cl14clbr_high_trees = goseq_trees(degenes=tryp_cl14clbr_high, tryp_cl14clbr_high_go)
## I had to hack the geneTable() function in order to make it not take infinite memory because it was trying to do some stupid merge of every gff column against every other column...
## Once the geneTable.rda file exists and included real information, this seems to work fine, though.
tryp_cl14clbr_high_cl = simple_clusterprofiler(tryp_cl14clbr_high)
tryp_cl14clbr_high_cl$bp_all_barplot
## The first time this is run in a fresh directory, it needs to be run like this:
## simple_topgo(tryp_cl14clbr_high, goids_df=go_ids)
## setting goids_df will tell it to generate a table of genes->GO<-genes in the format expected.
tryp_cl14clbr_high_top = simple_topgo(tryp_cl14clbr_high, goids=goid_file, pvals=tryp_cl14clbr_pvals)

topgo_pval = topgo_pval_plot(tryp_cl14clbr_high_top)
topgo_pval$BP
top_trees = topgo_trees(tryp_cl14clbr_high_top)
top_trees$bp_fisher_tree

1.6 Compare cl14/clbr tryp other side

## Changes in epimastigotes from CLBrener to CL14
tryp_cl14clbr_table = all_tables$tryp_cl14clbr
tryp_cl14clbr_summary = summary(tryp_cl14clbr_table$logFC)
tryp_cl14clbr_pvals = tryp_cl14clbr_table$adj.P.Val
names(tryp_cl14clbr_pvals) = rownames(tryp_cl14clbr_table)
## Extract the genes with low expression in CL14 compared to Brener and very low pvalues
tryp_cl14clbr_low = subset(tryp_cl14clbr_table, logFC <= tryp_cl14clbr_summary[2] & adj.P.Val <= pval_thresh)
## Do a goseq comparison of the low genes
tryp_cl14clbr_low_go = simple_goseq(tryp_cl14clbr_low, lengths=gene_lengths, goids=go_ids)
tryp_cl14clbr_low_go$pvalue_histogram
tryp_cl14clbr_low_go$bpp_plot
## Oh crap, I cannot make trees until I generate a id2go R mapping, I will need to check my previous script for how to do that (I think I do it automatically in simple_topgo()...
##tryp_cl14clbr_low_trees = goseq_trees(degenes=tryp_cl14clbr_low, tryp_cl14clbr_low_go)
## I had to hack the geneTable() function in order to make it not take infinite memory because it was trying to do some stupid merge of every gff column against every other column...
## Once the geneTable.rda file exists and included real information, this seems to work fine, though.
tryp_cl14clbr_low_cl = simple_clusterprofiler(tryp_cl14clbr_low)
tryp_cl14clbr_low_cl$bp_all_barplot
## The first time this is run in a fresh directory, it needs to be run like this:
## simple_topgo(tryp_cl14clbr_low, goids_df=go_ids)
## setting goids_df will tell it to generate a table of genes->GO<-genes in the format expected.
tryp_cl14clbr_low_top = simple_topgo(tryp_cl14clbr_low, goids=goid_file, pvals=tryp_cl14clbr_pvals)

topgo_pval = topgo_pval_plot(tryp_cl14clbr_low_top)
topgo_pval$BP
top_trees = topgo_trees(tryp_cl14clbr_low_top)
top_trees$bp_fisher_tree

1.7 Amastigote a96 cl14/clbr

## Changes in epimastigotes from CLBrener to CL14
a96_cl14clbr_table = all_tables$a96_cl14clbr
a96_cl14clbr_summary = summary(a96_cl14clbr_table$logFC)
a96_cl14clbr_pvals = a96_cl14clbr_table$adj.P.Val
names(a96_cl14clbr_pvals) = rownames(a96_cl14clbr_table)
## Extract the genes with low expression in CL14 compared to Brener and very low pvalues
a96_cl14clbr_low = subset(a96_cl14clbr_table, logFC >= a96_cl14clbr_summary[5] & adj.P.Val <= pval_thresh)
## Do a goseq comparison of the low genes
a96_cl14clbr_low_go = simple_goseq(a96_cl14clbr_low, lengths=gene_lengths, goids=go_ids)
a96_cl14clbr_low_go$pvalue_histogram
a96_cl14clbr_low_go$bpp_plot
## Oh crap, I cannot make trees until I generate a id2go R mapping, I will need to check my previous script for how to do that (I think I do it automatically in simple_topgo()...
##a96_cl14clbr_low_trees = goseq_trees(degenes=a96_cl14clbr_low, a96_cl14clbr_low_go)
## I had to hack the geneTable() function in order to make it not take infinite memory because it was trying to do some stupid merge of every gff column against every other column...
## Once the geneTable.rda file exists and included real information, this seems to work fine, though.
a96_cl14clbr_low_cl = simple_clusterprofiler(a96_cl14clbr_low)
a96_cl14clbr_low_cl$bp_all_barplot
## The first time this is run in a fresh directory, it needs to be run like this:
## simple_topgo(a96_cl14clbr_low, goids_df=go_ids)
## setting goids_df will tell it to generate a table of genes->GO<-genes in the format expected.
a96_cl14clbr_low_top = simple_topgo(a96_cl14clbr_low, goids=goid_file, pvals=a96_cl14clbr_pvals)

topgo_pval = topgo_pval_plot(a96_cl14clbr_low_top)
topgo_pval$BP
top_trees = topgo_trees(a96_cl14clbr_low_top)
top_trees$bp_fisher_tree
## Changes in epimastigotes from CLBrener to CL14
a96_cl14clbr_table = strain_comparisons$data$a96_clbr_over_cl14
a96_cl14clbr_summary = summary(a96_cl14clbr_table$logFC)
a96_cl14clbr_pvals = a96_cl14clbr_table$adj.P.Val
names(a96_cl14clbr_pvals) = rownames(a96_cl14clbr_table)
## Extract the genes with low expression in CL14 compared to Brener and very low pvalues
a96_cl14clbr_low = subset(a96_cl14clbr_table, logFC <= a96_cl14clbr_summary[2] & adj.P.Val <= pval_thresh)
## Do a goseq comparison of the low genes
a96_cl14clbr_low_go = simple_goseq(a96_cl14clbr_low, lengths=gene_lengths, goids=go_ids)
a96_cl14clbr_low_go$pvalue_histogram
a96_cl14clbr_low_go$bpp_plot
## Oh crap, I cannot make trees until I generate a id2go R mapping, I will need to check my previous script for how to do that (I think I do it automatically in simple_topgo()...
##a96_cl14clbr_low_trees = goseq_trees(degenes=a96_cl14clbr_low, a96_cl14clbr_low_go)
## I had to hack the geneTable() function in order to make it not take infinite memory because it was trying to do some stupid merge of every gff column against every other column...
## Once the geneTable.rda file exists and included real information, this seems to work fine, though.
a96_cl14clbr_low_cl = simple_clusterprofiler(a96_cl14clbr_low)
a96_cl14clbr_low_cl$bp_all_barplot
## The first time this is run in a fresh directory, it needs to be run like this:
##simple_topgo(a96_cl14clbr_low, goids_df=go_ids)
## setting goids_df will tell it to generate a table of genes->GO<-genes in the format expected.
a96_cl14clbr_low_top = simple_topgo(a96_cl14clbr_low, goids=goid_file, pvals=a96_cl14clbr_pvals)

topgo_pval = topgo_pval_plot(a96_cl14clbr_low_top)
topgo_pval$BP
top_trees = topgo_trees(a96_cl14clbr_low_top)
top_trees$bp_fisher_tree

## Ways to look
a60_cl14clbr_table = all_tables$a60_cl14clbr
tmp = merge(a60_cl14clbr_table, a96_cl14clbr_table, by="row.names")
tmp_b_t = data.frame(a60=tmp$B.x, a96=tmp$B.y)
tt = hpgl_linear_scatter(tmp_b_t)
tt$scatter
a60_cl14clbr_table = all_tables$a60_cl14clbr
tmp = merge(a60_cl14clbr_table, a96_cl14clbr_table, by="row.names")
tmp_b_t = data.frame(a60=tmp$t.x, a96=tmp$t.y)
tt = hpgl_scatter(tmp_b_t)
tt$scatter

2 KG

Oh yeah, I wrote a toy to wrap KEGG pathway stuff, lets try that. The KEGG abbreviation for t. cruzi is tcr

In theory, the _paths data structure returned by hpgl_pathview() should be a table of the numer of up/down genes observed in each KEGG path. However, there are some weird NAs getting returned. Effing hippies. – fixed.

kegg_list <- ""
##names(kegg_list) = rownames(epi_cl14clbr_table)
##epi_cl14clbr_paths = hpgl_pathview(kegg_list, species="tcr", indir="pathview_in", outdir="pathview_epi_cl14clbr", string_from="TcCLB.", string_to="")
##head(epi_cl14clbr_paths)


##a60_cl14clbr_table = all_tables$a60_cl14clbr
a60_cl14clbr_table <- strain_comparisons$data$a60_clbr_over_cl14
##kegg_list <- a60_cl14clbr_table$logFC
kegg_list <- a60_cl14clbr_table$limma_logfc
names(kegg_list) <- rownames(a60_cl14clbr_table)
a60_cl14clbr_paths <- hpgl_pathview(kegg_list, species="tcr",
                                    indir="pathview_in", outdir="pathview_a60_cl14clbr",
                                    from_list="TcCLB.", to_list="")
head(a60_cl14clbr_paths)

a96_cl14clbr_table = all_tables$a96_cl14clbr
kegg_list = a96_cl14clbr_table$logFC
names(kegg_list) = rownames(a96_cl14clbr_table)
a96_cl14clbr_paths = hpgl_pathview(kegg_list, species="tcr", indir="pathview_in", outdir="pathview_a96_cl14clbr", string_from="TcCLB.", string_to="")
head(a96_cl14clbr_paths)

tryp_cl14clbr_table = all_tables$a96_cl14clbr
kegg_list = tryp_cl14clbr_table$logFC
names(kegg_list) = rownames(tryp_cl14clbr_table)
tryp_cl14clbr_paths = hpgl_pathview(kegg_list, species="tcr", indir="pathview_in", outdir="pathview_tryp_cl14clbr", string_from="TcCLB.", string_to="")
head(tryp_cl14clbr_paths)
LS0tCnRpdGxlOiAiUk5Bc2VxIG9mIFQuY3J1emkgQ0wxNC9DTEJyOiBHZW5lIE9udG9sb2d5LiIKYXV0aG9yOiAiYXRiIGFiZWxld0BnbWFpbC5jb20iCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCIKb3V0cHV0OgogaHRtbF9kb2N1bWVudDoKICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgY29kZV9mb2xkaW5nOiBzaG93CiAgZmlnX2NhcHRpb246IHRydWUKICBmaWdfaGVpZ2h0OiA3CiAgZmlnX3dpZHRoOiA3CiAgaGlnaGxpZ2h0OiBkZWZhdWx0CiAga2VlcF9tZDogZmFsc2UKICBtb2RlOiBzZWxmY29udGFpbmVkCiAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlCiAgc2VsZl9jb250YWluZWQ6IHRydWUKICB0aGVtZTogcmVhZGFibGUKICB0b2M6IHRydWUKICB0b2NfZmxvYXQ6CiAgICBjb2xsYXBzZWQ6IGZhbHNlCiAgICBzbW9vdGhfc2Nyb2xsOiBmYWxzZQotLS0KCjxzdHlsZT4KICA8IS0tIERvY3VtZW50IHByZWx1ZGUgcmV2aXNpb24gMjAxNi0xMCAtLT4KYm9keSAubWFpbi1jb250YWluZXIgewptYXgtd2lkdGg6IDE2MDBweDsKfQo8L3N0eWxlPgoKYGBge3Igb3B0aW9ucywgaW5jbHVkZT1GQUxTRX0KIyMgVGhlc2UgYXJlIHRoZSBvcHRpb25zIEkgdGVuZCB0byBmYXZvcgpsaWJyYXJ5KCJocGdsdG9vbHMiKQp0dCA8LSBzbShkZXZ0b29sczo6bG9hZF9hbGwoIn4vaHBnbHRvb2xzIikpCmtuaXRyOjpvcHRzX2tuaXQkc2V0KAogICAgcHJvZ3Jlc3MgPSBUUlVFLAogICAgdmVyYm9zZSA9IFRSVUUsCiAgICB3aWR0aCA9IDkwLAogICAgZWNobyA9IE5VTEwpCmtuaXRyOjpvcHRzX2NodW5rJHNldCgKICAgIGVycm9yID0gVFJVRSwKICAgIGZpZy53aWR0aCA9IDgsCiAgICBmaWcuaGVpZ2h0ID0gOCwKICAgIGRwaSA9IDk2KQpvbGRfb3B0aW9ucyA8LSBvcHRpb25zKAogICAgZXJyb3IgPSBOVUxMLAogICAgZGlnaXRzID0gNCwKICAgIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRSwKICAgIGtuaXRyLmR1cGxpY2F0ZS5sYWJlbCA9ICJhbGxvdyIpCmdncGxvdDI6OnRoZW1lX3NldChnZ3Bsb3QyOjp0aGVtZV9idyhiYXNlX3NpemU9MTApKQpzZXQuc2VlZCgxKQpwcmV2aW91c19maWxlIDwtICJkaWZmZXJlbnRpYWxfZXhwcmVzc2lvbi5SbWQiCnJtZF9maWxlIDwtICJnZW5lX29udG9sb2d5X3JlbGF4ZWRfcF9pbnB1dC5SbWQiCnZlciA8LSAiMjAxNzAyMTYiCnByZXZpb3VzX3NhdmUgPC0gcGFzdGUwKGdzdWIocGF0dGVybj0iXFwuUm1kIiwgcmVwbGFjZT0iLnJkYS54eiIsIHg9cHJldmlvdXNfZmlsZSkpCnRoaXNfc2F2ZSA8LSBwYXN0ZTAoZ3N1YihwYXR0ZXJuPSJcXC5SbWQiLCByZXBsYWNlPSIucmRhLnh6IiwgeD1ybWRfZmlsZSkpCmBgYAoKW2luZGV4Lmh0bWxdKGluZGV4Lmh0bWwpIFthbm5vdGF0aW9uLmh0bWxdKGFubm90YXRpb24uaHRtbCkKW3NhbXBsZV9lc3RpbWF0aW9ucy5odG1sXShzYW1wbGVfZXN0aW1hdGlvbnMuaHRtbCkgW2RpZmZlcmVudGlhbF9leHByZXNzaW9uLmh0bWxdKGRpZmZlcmVudGlhbF9leHByZXNzaW9uLmh0bWwpCgpgYGB7ciByZW5kZXJpbmcsIGluY2x1ZGU9RkFMU0UsIGV2YWw9RkFMU0V9CiMjIFRoaXMgYmxvY2sgaXMgdXNlZCB0byByZW5kZXIgYSBkb2N1bWVudCBmcm9tIHdpdGhpbiBpdC4Kcm1hcmtkb3duOjpyZW5kZXIocm1kX2ZpbGUpCgojIyBBbiBleHRyYSByZW5kZXJlciBmb3IgcGRmIG91dHB1dApybWFya2Rvd246OnJlbmRlcihybWRfZmlsZSwgb3V0cHV0X2Zvcm1hdD0icGRmX2RvY3VtZW50Iiwgb3V0cHV0X29wdGlvbnM9Yygic2tpcF9odG1sIikpCiMjIE9yIHRvIHNhdmUvbG9hZCBsYXJnZSBSZGF0YSBmaWxlcy4KaHBnbHRvb2xzOjo6c2F2ZW1lKCkKaHBnbHRvb2xzOjo6bG9hZG1lKCkKcm0obGlzdD1scygpKQpgYGAKCkluIHRoaXMgZG9jdW1lbnQsIHdlIHdpbGwgcGVyZm9ybSBhIHNlcmllcyBvZiBkaWZmZXJlbnRpYWwgZXhwcmVzc2lvbiBhbmFseXNlcyB1c2luZyB0aGUgZGF0YSB3aGljaCBzdXJ2aXZlZCBzYW1wbGUgZXN0aW1hdGlvbi4KCmBgYHtyIGxvYWRtZSwgaW5jbHVkZT1GQUxTRX0KdG1wIDwtIHNtKGxvYWRtZShmaWxlbmFtZT1wcmV2aW91c19zYXZlKSkKYGBgCgojIEdlbmUgT250b2xvZ3kgc2VhcmNoZXMKCkxldHMgc2V0IHVwIHNvbWUgc2ltcGxlIGRhdGEgc2V0cyBmb3IgZ29zZXEvY2x1c3RlclByb2ZpbGVyL3RvcEdPCgpJIHRoaW5rIGEgYnVuY2ggb2YgdGhlIG1hdGVyaWFsIGluIHRoaXMgc2hlZXQgaXMgYWN0dWFsbHkgbm93IG9ic29sZXRlLgoKIyMgRXh0cmFjdGluZyBvbnRvbG9neSBhbm5vdGF0aW9ucyBmcm9tIHRoZSBUcmlUcnlwREIKCkkgbmVlZCB0byBleHRyYWN0IHRoZSBvbnRvbG9neS9wRkFNIGRhdGEgZnJvbSB0aGUgVGNydXppIGFubm90YXRpb24KdGFibGVzLgoKSSBoYXZlIGEgcGVybCBzY3JpcHQgJ2R1bXBfdHJpdHJ5cF9HTy5wbCcgd2hpY2ggY2FuIGRvIHRoaXMgZm9yIG1lLgoKYGBge3IgZW5naW5lPSdiYXNoJywgZXZhbD1GQUxTRX0KY2QgJExBQi9yZWZfZGF0YS9nZW5lX29udG9sb2d5LwouL2R1bXBfdHJpdHJ5cF9HTy5wbCAkTEFCL3JlZl9kYXRhL3RyaXRyeXBfdGV4dC9UY3J1emkudHh0ID4gdGNydXppX2dvLnRhYgojIyBUaGUgYWN0dWFsIGNvbW1hbmRzIHdlcmUgc2xpZ2h0bHkgZGlmZmVyZW50LCBqdXN0IGJlY2F1c2UgSSBkaWRuJ3QgZmVlbCBsaWtlIGNvcHkvcGFzdGluZyB0aGUgZmlsZW5hbWVzLgpgYGAKCiMjIFByZXBhcmluZyB0byB1c2UgZ29zZXEKCkkgbmVlZCBhIGNvdXBsZSB2ZWN0b3JzIGJlZm9yZSBiZWluZyBhYmxlIHRvIHVzZSBnb3NlcQpJIGFsc28gbmVlZCBzb21lIHJkYSBmaWxlcyBnZW5lcmF0ZWQgZm9yIGNsdXN0ZXJQcm9maWxlciBhbmQgdG9wR08KYnV0IEkgd2lsbCBkbyB0aG9zZSBsYXRlci4uLgoKYGBge3IgZ29zZXFfcHJlcGFyYXRpb259CiMjIGdvc2VxIHVzZXMgdGhlIGdlbmUgbGVuZ3RocywgY2x1c3RlcnByb2ZpbGVyIGFuZCB0b3BnbyBkb24ndAojIyBnZW5lX2xlbmd0aHMgPC0gYWxsX2dlbmVzWyxjKCJnZW5laWQiLCJnZW5lc2l6ZSIpXQojIyBjb2xuYW1lcyhnZW5lX2xlbmd0aHMpIDwtIGMoIklEIiwgIndpZHRoIikKY29sbmFtZXMoYWxsX2xlbmd0aHMpIDwtIGMoIklEIiwgIndpZHRoIikKIyMgZ29faWRzIG5lZWRzIHRvIGJlIGEgMiBjb2x1bW4gZGF0YSBmcmFtZSB3aXRoIG5hbWVzICdJRCcsICdHTycgd2hpY2ggYXJlCiMjIGdlbmUgbmFtZXMgYW5kIEdPIG5hbWVzIHJlc3BlY3RpdmVseS4gIEkgYWN0dWFsbHkgdGhpbmsgSSBtYWRlIG15IGdvc2VxKCkgZnVuY3Rpb24KIyMgc21hcnQgZW5vdWdoIHRoYXQgdGhpcyBpcyBubyBsb25nZXIgbmVlZGVkLCBidXQgbm9uZXRoZWxlc3MuCgojIyBnb19pZHMgPC0gcmVhZC50YWJsZSgicmVmZXJlbmNlL2dvL3RjcnV6aV9hbGxfZ28udGFiLmd6IiwgaGVhZGVyPTAsIHNlcD0iXHQiKQojIyBjb2xuYW1lcyhnb19pZHMpIDwtIGMoIklEIiwiR08iLCJvbnRvbG9neSIsInRlcm0iLCJzb3VyY2UiKQojIyBTaW5jZSB0aGVyZSBhcmUgbXVsdGlwbGUgc291cmNlcywgSSBhbSBkb2luZyBhIHVuaXF1ZSBvZiB0aGUgdGFibGUuLi4KIyMgZ29faWRzIDwtIHVuaXF1ZShnb19pZHNbLGMoIklEIiwiR08iKV0pCiMjIGdvaWRfZmlsZSA8LSAicmVmZXJlbmNlL2dvL3RvcGdvX2dvaWRzLnRhYi5neiIKCmNvbG5hbWVzKGFsbF9nbykgPC0gYygiSUQiLCAiR08iKQpgYGAKCmBgYHtyIGdvc2VxX2NsYnJfdGltZXMxfQojIyBGaXJzdCByZWxheCB0aGUgaW5wdXQgYXMgcGVybCB0aGUgbmFtZSBvZiB0aGlzIGZpbGUuCmNsYnJfdGltZXNfc2lnZmlsdHYyIDwtIHNtKGV4dHJhY3Rfc2lnbmlmaWNhbnRfZ2VuZXMoY2xicl90aW1lc19maWx0ZXJlZCwgYWNjb3JkaW5nX3RvPSJsaW1tYSIsIHA9MC4xLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleGNlbD1wYXN0ZTAoImV4Y2VsL2NsYl90aW1lc19maWx0ZXJlZF9yZWxheGVkcC12IiwgdmVyLCAiLnhsc3giKSkpCmNsMTRfdGltZXNfc2lnZmlsdHYyIDwtIHNtKGV4dHJhY3Rfc2lnbmlmaWNhbnRfZ2VuZXMoY2wxNF90aW1lc19maWx0ZXJlZCwgYWNjb3JkaW5nX3RvPSJsaW1tYSIsIHA9MC4xLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleGNlbD1wYXN0ZTAoImV4Y2VsL2NsMTRfdGltZXNfZmlsdGVyZWRfcmVsYXhlZHAtdiIsIHZlciwgIi54bHN4IikpKQpzdHJhaW5zX3NpZ2ZpbHR2MiA8LSBzbShleHRyYWN0X3NpZ25pZmljYW50X2dlbmVzKHN0cmFpbnNfZmlsdGVyZWQsIGFjY29yZGluZ190bz0ibGltbWEiLCBwPTAuMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleGNlbD1wYXN0ZTAoImV4Y2VsbC9zdHJhaW5fY29tcGFyaXNvbnNfZmlsdGVyZWRfcmVsYXhlZHAtdiIsIHZlciwgIi54bHN4IikpKQoKY2xicl91cF9hOTZ0cnlwX2dvc2VxIDwtIHNtKHNpbXBsZV9nb3NlcShzaWdfZ2VuZXM9Y2xicl90aW1lc19zaWdmaWx0djIkbGltbWEkdXBzJGNsYnJfYTk2X3RvX3RyeXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ29fZGI9YWxsX2dvLCBsZW5ndGhfZGI9YWxsX2xlbmd0aHMpKQpjbGJyX3VwX2E5NnRyeXBfZ29zZXEkcHZhbHVlX3Bsb3RzJGJwcF9wbG90X292ZXIKY2xicl91cF9hOTZ0cnlwX2V4Y2VsIDwtIHNtKHdyaXRlX2dvc2VxX2RhdGEoY2xicl91cF9hOTZ0cnlwX2dvc2VxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleGNlbD1wYXN0ZTAoImV4Y2VsL2NsYnJfdXBfYTk2dHJ5cF9nb3NlcV9yZWxheGVkcC12IiwgdmVyLCAiLnhsc3giKSkpCmNsYnJfZG93bl9hOTZ0cnlwX2dvc2VxIDwtIHNtKHNpbXBsZV9nb3NlcShzaWdfZ2VuZXM9Y2xicl90aW1lc19zaWdmaWx0djIkbGltbWEkZG93bnMkY2xicl9hOTZfdG9fdHJ5cCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdvX2RiPWFsbF9nbywgbGVuZ3RoX2RiPWFsbF9sZW5ndGhzKSkKY2xicl9kb3duX2E5NnRyeXBfZ29zZXEkcHZhbHVlX3Bsb3RzJGJwcF9wbG90X292ZXIKY2xicl9kb3duX2E5NnRyeXBfZXhjZWwgPC0gc20od3JpdGVfZ29zZXFfZGF0YShjbGJyX2Rvd25fYTk2dHJ5cF9nb3NlcSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleGNlbD1wYXN0ZTAoImV4Y2VsL2NsYnJfZG93bl9hOTZ0cnlwX2dvc2VxX3JlbGF4ZWRwLXYiLCB2ZXIsICIueGxzeCIpKSkKY2xicl91cF9hNjBhOTZfZ29zZXEgPC0gc20oc2ltcGxlX2dvc2VxKHNpZ19nZW5lcz1jbGJyX3RpbWVzX3NpZ2ZpbHR2MiRsaW1tYSR1cHMkY2xicl9hNjBfdG9fYTk2LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ29fZGI9YWxsX2dvLCBsZW5ndGhfZGI9YWxsX2xlbmd0aHMpKQpjbGJyX3VwX2E2MGE5Nl9nb3NlcSRwdmFsdWVfcGxvdHMkYnBwX3Bsb3Rfb3ZlcgpjbGJyX3VwX2E2MGE5Nl9leGNlbCA8LSBzbSh3cml0ZV9nb3NlcV9kYXRhKGNsYnJfdXBfYTYwYTk2X2dvc2VxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4Y2VsPXBhc3RlMCgiZXhjZWwvY2xicl91cF9hNjBhOTZfZ29zZXFfcmVsYXhlZHAtdiIsIHZlciwgIi54bHN4IikpKQpjbGJyX2Rvd25fYTYwYTk2X2dvc2VxIDwtIHNtKHNpbXBsZV9nb3NlcShzaWdfZ2VuZXM9Y2xicl90aW1lc19zaWdmaWx0djIkbGltbWEkZG93bnMkY2xicl9hNjBfdG9fYTk2LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnb19kYj1hbGxfZ28sIGxlbmd0aF9kYj1hbGxfbGVuZ3RocykpCmNsYnJfZG93bl9hNjBhOTZfZ29zZXEkcHZhbHVlX3Bsb3RzJGJwcF9wbG90X292ZXIKY2xicl9kb3duX2E2MGE5Nl9leGNlbCA8LSBzbSh3cml0ZV9nb3NlcV9kYXRhKGNsYnJfZG93bl9hNjBhOTZfZ29zZXEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleGNlbD1wYXN0ZTAoImV4Y2VsL2NsYnJfZG93bl9hNjBhOTZfZ29zZXFfcmVsYXhlZHAtdiIsIHZlciwgIi54bHN4IikpKQpjbGJyX3VwX3RyeXBhNjBfZ29zZXEgPC0gc20oc2ltcGxlX2dvc2VxKHNpZ19nZW5lcz1jbGJyX3RpbWVzX3NpZ2ZpbHR2MiRsaW1tYSR1cHMkY2xicl90cnlwX3RvX2E2MCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnb19kYj1hbGxfZ28sIGxlbmd0aF9kYj1hbGxfbGVuZ3RocykpCmNsYnJfdXBfdHJ5cGE2MF9nb3NlcSRwdmFsdWVfcGxvdHMkYnBwX3Bsb3Rfb3ZlcgpjbGJyX3VwX3RyeXBhNjBfZXhjZWwgPC0gc20od3JpdGVfZ29zZXFfZGF0YShjbGJyX3VwX3RyeXBhNjBfZ29zZXEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4Y2VsPXBhc3RlMCgiZXhjZWwvY2xicl91cF90cnlwYTYwX2dvc2VxX3JlbGF4ZWRwLXYiLCB2ZXIsICIueGxzeCIpKSkKY2xicl9kb3duX3RyeXBhNjBfZ29zZXEgPC0gc20oc2ltcGxlX2dvc2VxKHNpZ19nZW5lcz1jbGJyX3RpbWVzX3NpZ2ZpbHR2MiRsaW1tYSRkb3ducyRjbGJyX3RyeXBfdG9fYTYwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ29fZGI9YWxsX2dvLCBsZW5ndGhfZGI9YWxsX2xlbmd0aHMpKQpjbGJyX2Rvd25fdHJ5cGE2MF9nb3NlcSRwdmFsdWVfcGxvdHMkYnBwX3Bsb3Rfb3ZlcgpjbGJyX2Rvd25fdHJ5cGE2MF9leGNlbCA8LSBzbSh3cml0ZV9nb3NlcV9kYXRhKGNsYnJfZG93bl90cnlwYTYwX2dvc2VxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4Y2VsPXBhc3RlMCgiZXhjZWwvY2xicl9kb3duX3RyeXBhNjBfZ29zZXFfcmVsYXhlZHAtdiIsIHZlciwgIi54bHN4IikpKQpjbDE0X3VwX2E5NnRyeXBfZ29zZXEgPC0gc20oc2ltcGxlX2dvc2VxKHNpZ19nZW5lcz1jbDE0X3RpbWVzX3NpZ2ZpbHR2MiRsaW1tYSR1cHMkY2wxNF9hOTZfdG9fdHJ5cCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnb19kYj1hbGxfZ28sIGxlbmd0aF9kYj1hbGxfbGVuZ3RocykpCmNsMTRfdXBfYTk2dHJ5cF9nb3NlcSRwdmFsdWVfcGxvdHMkYnBwX3Bsb3Rfb3ZlcgpjbDE0X3VwX2E5NnRyeXBfZXhjZWwgPC0gc20od3JpdGVfZ29zZXFfZGF0YShjbDE0X3VwX2E5NnRyeXBfZ29zZXEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4Y2VsPXBhc3RlMCgiZXhjZWwvY2wxNF91cF9hOTZ0cnlwX2dvc2VxX3JlbGF4ZWRwLXYiLCB2ZXIsICIueGxzeCIpKSkKY2wxNF9kb3duX2E5NnRyeXBfZ29zZXEgPC0gc20oc2ltcGxlX2dvc2VxKHNpZ19nZW5lcz1jbDE0X3RpbWVzX3NpZ2ZpbHR2MiRsaW1tYSRkb3ducyRjbDE0X2E5Nl90b190cnlwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ29fZGI9YWxsX2dvLCBsZW5ndGhfZGI9YWxsX2xlbmd0aHMpKQpjbDE0X2Rvd25fYTk2dHJ5cF9nb3NlcSRwdmFsdWVfcGxvdHMkYnBwX3Bsb3Rfb3ZlcgpjbDE0X2Rvd25fYTk2dHJ5cF9leGNlbCA8LSBzbSh3cml0ZV9nb3NlcV9kYXRhKGNsMTRfZG93bl9hOTZ0cnlwX2dvc2VxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4Y2VsPXBhc3RlMCgiZXhjZWwvY2wxNF9kb3duX2E5NnRyeXBfZ29zZXFfcmVsYXhlZHAtdiIsIHZlciwgIi54bHN4IikpKQpjbDE0X3VwX2E2MGE5Nl9nb3NlcSA8LSBzbShzaW1wbGVfZ29zZXEoc2lnX2dlbmVzPWNsMTRfdGltZXNfc2lnZmlsdHYyJGxpbW1hJHVwcyRjbDE0X2E2MF90b19hOTYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnb19kYj1hbGxfZ28sIGxlbmd0aF9kYj1hbGxfbGVuZ3RocykpCmNsMTRfdXBfYTYwYTk2X2dvc2VxJHB2YWx1ZV9wbG90cyRicHBfcGxvdF9vdmVyCmNsMTRfdXBfYTYwYTk2X2V4Y2VsIDwtIHNtKHdyaXRlX2dvc2VxX2RhdGEoY2wxNF91cF9hNjBhOTZfZ29zZXEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhjZWw9cGFzdGUwKCJleGNlbC9jbDE0X3VwX2E2MGE5Nl9nb3NlcV9yZWxheGVkcC12IiwgdmVyLCAiLnhsc3giKSkpCmNsMTRfZG93bl9hNjBhOTZfZ29zZXEgPC0gc20oc2ltcGxlX2dvc2VxKHNpZ19nZW5lcz1jbDE0X3RpbWVzX3NpZ2ZpbHR2MiRsaW1tYSRkb3ducyRjbDE0X2E2MF90b19hOTYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdvX2RiPWFsbF9nbywgbGVuZ3RoX2RiPWFsbF9sZW5ndGhzKSkKY2wxNF9kb3duX2E2MGE5Nl9nb3NlcSRwdmFsdWVfcGxvdHMkYnBwX3Bsb3Rfb3ZlcgpjbDE0X2Rvd25fYTYwYTk2X2V4Y2VsIDwtIHNtKHdyaXRlX2dvc2VxX2RhdGEoY2wxNF9kb3duX2E2MGE5Nl9nb3NlcSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4Y2VsPXBhc3RlMCgiZXhjZWwvY2wxNF9kb3duX2E2MGE5Nl9nb3NlcV9yZWxheGVkcC12IiwgdmVyLCAiLnhsc3giKSkpCmNsMTRfdXBfdHJ5cGE2MF9nb3NlcSA8LSBzbShzaW1wbGVfZ29zZXEoc2lnX2dlbmVzPWNsMTRfdGltZXNfc2lnZmlsdHYyJGxpbW1hJHVwcyRjbDE0X3RyeXBfdG9fYTYwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdvX2RiPWFsbF9nbywgbGVuZ3RoX2RiPWFsbF9sZW5ndGhzKSkKY2wxNF91cF90cnlwYTYwX2dvc2VxJHB2YWx1ZV9wbG90cyRicHBfcGxvdF9vdmVyCmNsMTRfdXBfdHJ5cGE2MF9leGNlbCA8LSBzbSh3cml0ZV9nb3NlcV9kYXRhKGNsMTRfdXBfdHJ5cGE2MF9nb3NlcSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhjZWw9cGFzdGUwKCJleGNlbC9jbDE0X3VwX3RyeXBhNjBfZ29zZXFfcmVsYXhlZHAtdiIsIHZlciwgIi54bHN4IikpKQpjbDE0X2Rvd25fdHJ5cGE2MF9nb3NlcSA8LSBzbShzaW1wbGVfZ29zZXEoc2lnX2dlbmVzPWNsMTRfdGltZXNfc2lnZmlsdHYyJGxpbW1hJGRvd25zJGNsMTRfdHJ5cF90b19hNjAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnb19kYj1hbGxfZ28sIGxlbmd0aF9kYj1hbGxfbGVuZ3RocykpCmNsMTRfZG93bl90cnlwYTYwX2dvc2VxJHB2YWx1ZV9wbG90cyRicHBfcGxvdF9vdmVyCmNsMTRfZG93bl90cnlwYTYwX2V4Y2VsIDwtIHNtKHdyaXRlX2dvc2VxX2RhdGEoY2wxNF9kb3duX3RyeXBhNjBfZ29zZXEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhjZWw9cGFzdGUwKCJleGNlbC9jbDE0X2Rvd25fdHJ5cGE2MF9nb3NlcV9yZWxheGVkcC12IiwgdmVyLCAiLnhsc3giKSkpCgpzdHJhaW5zX3VwX2E2MF9nb3NlcSA8LSBzbShzaW1wbGVfZ29zZXEoc2lnX2dlbmVzPXN0cmFpbnNfc2lnZmlsdHYyJGxpbW1hJHVwcyRhNjBfY2xicl9vdmVyX2NsMTQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnb19kYj1hbGxfZ28sIGxlbmd0aF9kYj1hbGxfbGVuZ3RocykpCnN0cmFpbnNfdXBfYTk2X2dvc2VxIDwtIHNtKHNpbXBsZV9nb3NlcShzaWdfZ2VuZXM9c3RyYWluc19zaWdmaWx0djIkbGltbWEkdXBzJGE5Nl9jbGJyX292ZXJfY2wxNCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdvX2RiPWFsbF9nbywgbGVuZ3RoX2RiPWFsbF9sZW5ndGhzKSkKc3RyYWluc191cF90cnlwX2dvc2VxIDwtIHNtKHNpbXBsZV9nb3NlcShzaWdfZ2VuZXM9c3RyYWluc19zaWdmaWx0djIkbGltbWEkdXBzJHRyeXBfY2xicl9vdmVyX2NsMTQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ29fZGI9YWxsX2dvLCBsZW5ndGhfZGI9YWxsX2xlbmd0aHMpKQpzdHJhaW5zX3VwX2E2MF9leGNlbCA8LSBzbSh3cml0ZV9nb3NlcV9kYXRhKHN0cmFpbnNfdXBfYTYwX2dvc2VxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4Y2VsPXBhc3RlMCgiZXhjZWwvc3RyYWluc191cGE2MF9nb3NlcV9yZWxheGVkcC12IiwgdmVyLCAiLnhsc3giKSkpCnN0cmFpbnNfdXBfYTk2X2V4Y2VsIDwtIHNtKHdyaXRlX2dvc2VxX2RhdGEoc3RyYWluc191cF9hOTZfZ29zZXEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhjZWw9cGFzdGUwKCJleGNlbC9zdHJhaW5zX3VwYTk2X2dvc2VxX3JlbGF4ZWRwLXYiLCB2ZXIsICIueGxzeCIpKSkKc3RyYWluc191cF90cnlwX2V4Y2VsIDwtIHNtKHdyaXRlX2dvc2VxX2RhdGEoc3RyYWluc191cF90cnlwX2dvc2VxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleGNlbD1wYXN0ZTAoImV4Y2VsL3N0cmFpbnNfdXB0cnlwX2dvc2VxX3JlbGF4ZWRwLXYiLCB2ZXIsICIueGxzeCIpKSkKc3RyYWluc19kb3duX2E2MF9nb3NlcSA8LSBzbShzaW1wbGVfZ29zZXEoc2lnX2dlbmVzPXN0cmFpbnNfc2lnZmlsdHYyJGxpbW1hJGRvd25zJGE2MF9jbGJyX292ZXJfY2wxNCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ29fZGI9YWxsX2dvLCBsZW5ndGhfZGI9YWxsX2xlbmd0aHMpKQpzdHJhaW5zX2Rvd25fYTk2X2dvc2VxIDwtIHNtKHNpbXBsZV9nb3NlcShzaWdfZ2VuZXM9c3RyYWluc19zaWdmaWx0djIkbGltbWEkZG93bnMkYTk2X2NsYnJfb3Zlcl9jbDE0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnb19kYj1hbGxfZ28sIGxlbmd0aF9kYj1hbGxfbGVuZ3RocykpCnN0cmFpbnNfZG93bl90cnlwX2dvc2VxIDwtIHNtKHNpbXBsZV9nb3NlcShzaWdfZ2VuZXM9c3RyYWluc19zaWdmaWx0djIkbGltbWEkZG93bnMkdHJ5cF9jbGJyX292ZXJfY2wxNCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdvX2RiPWFsbF9nbywgbGVuZ3RoX2RiPWFsbF9sZW5ndGhzKSkKc3RyYWluc19kb3duX2E2MF9leGNlbCA8LSBzbSh3cml0ZV9nb3NlcV9kYXRhKHN0cmFpbnNfZG93bl9hNjBfZ29zZXEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhjZWw9cGFzdGUwKCJleGNlbC9zdHJhaW5zX2Rvd25hNjBfZ29zZXFfcmVsYXhlZHAtdiIsIHZlciwgIi54bHN4IikpKQpzdHJhaW5zX2Rvd25fYTk2X2V4Y2VsIDwtIHNtKHdyaXRlX2dvc2VxX2RhdGEoc3RyYWluc19kb3duX2E5Nl9nb3NlcSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleGNlbD1wYXN0ZTAoImV4Y2VsL3N0cmFpbnNfZG93bmE5Nl9nb3NlcV9yZWxheGVkcC12IiwgdmVyLCAiLnhsc3giKSkpCnN0cmFpbnNfZG93bl90cnlwX2V4Y2VsIDwtIHNtKHdyaXRlX2dvc2VxX2RhdGEoc3RyYWluc19kb3duX3RyeXBfZ29zZXEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4Y2VsPXBhc3RlMCgiZXhjZWwvc3RyYWluc19kb3dudHJ5cF9nb3NlcV9yZWxheGVkcC12IiwgdmVyLCAiLnhsc3giKSkpCmBgYAoKIyMgQ29tcGFyZSBFcGltYXN0aWdvdGVzIGJldHdlZW4gQ0wxNCBhbmQgQ0xCciwgaGlnaCBleHByZXNzaW9uCgpPbmUgaW1wb3J0YW50IG5vdGUgaGVyZSwgSSBuZWVkZWQgdG8gbW9kaWZ5IHRoZSBkYXRhIHN0cnVjdHVyZSBmcm9tIHJlYWRHZmYoKSBpbiBjbHVzdGVyUHJvZmlsZXIKYmVmb3JlIGl0IHdhcyBhYmxlIHRvIHN1Y2Nlc3NmdWxseSBnZW5lcmF0ZSB0aGUgZmlsZSAnZ2VuZVRhYmxlLnJkYScKVW5mb3J0dW5hdGVseSwgSSB3YXMgd2F0Y2hpbmcgYSBtb3ZpZSBhdCB0aGUgdGltZSBhbmQgZGlkbid0IHByb3Blcmx5IHdyaXRlIGRvd24gd2hhdCBJIGRpZC4KSG93ZXZlciwgSSBkaWQgd3JpdGUgaXQgb3V0IGluIHRoZSBmdW5jdGlvbiBteXI6OkdmZjJHZW5lVGFibGUoKQpidXQgaW4gb3JkZXIgdG8gbWFrZSBpdCB3b3JrIG9uZSBtdXN0IGxvYWQgcmVhZEdmZigpIGZyb20gY2x1c3RlclByb2ZpbGVyLgpJIHRoaW5rIHRoZSByZWFsIHNvbHV0aW9uIGlzIGZvciBtZSB0byBncmFiIGEgdmVyc2lvbiBvZiByZWFkR2ZmKCkgZnJvbSBjbHVzdGVyUHJvZmlsZXIKYW5kIG1ha2UgaXQgZXhwb3J0YWJsZSBzbyB0aGF0IGl0IHdpbGwgd29yayBjb25zaXN0ZW50bHkuCgpgYGB7ciBvbnRvbG9neV9lcGlfY2wxNGNscl9oaWdoLCBldmFsPUZBTFNFfQojIyBDaGFuZ2VzIGluIGVwaW1hc3RpZ290ZXMgZnJvbSBDTEJyZW5lciB0byBDTDE0CnB2YWxfdGhyZXNoIDwtIDAuMDAwMQplcGlfY2wxNGNsYnJfdGFibGUgPC0gYWxsX3RhYmxlcyRlcGlfY2wxNGNsYnIKZXBpX2NsMTRjbGJyX3N1bW1hcnkgPC0gc3VtbWFyeShlcGlfY2wxNGNsYnJfdGFibGUkbG9nRkMpCmVwaV9jbDE0Y2xicl9wdmFscyA8LSBlcGlfY2wxNGNsYnJfdGFibGUkYWRqLlAuVmFsCm5hbWVzKGVwaV9jbDE0Y2xicl9wdmFscykgPC0gcm93bmFtZXMoZXBpX2NsMTRjbGJyX3RhYmxlKQojIyBFeHRyYWN0IHRoZSBnZW5lcyB3aXRoIGhpZ2ggZXhwcmVzc2lvbiBpbiBDTDE0IGNvbXBhcmVkIHRvIEJyZW5lciBhbmQgdmVyeSBsb3cgcHZhbHVlcwplcGlfY2wxNGNsYnJfaGlnaCA8LSBzdWJzZXQoZXBpX2NsMTRjbGJyX3RhYmxlLCBsb2dGQyA+PSBlcGlfY2wxNGNsYnJfc3VtbWFyeVs1XSAmIGFkai5QLlZhbCA8PSBwdmFsX3RocmVzaCkKIyMgRG8gYSBnb3NlcSBjb21wYXJpc29uIG9mIHRoZSBoaWdoIGdlbmVzCmVwaV9jbDE0Y2xicl9oaWdoX2dvIDwtIHNpbXBsZV9nb3NlcShlcGlfY2wxNGNsYnJfaGlnaCwgbGVuZ3Rocz1nZW5lX2xlbmd0aHMsIGdvaWRzPWdvX2lkcykKZXBpX2NsMTRjbGJyX2hpZ2hfZ28kcHZhbHVlX2hpc3RvZ3JhbQplcGlfY2wxNGNsYnJfaGlnaF9nbyRicHBfcGxvdAoKc3VtbWFyeShlcGlfY2wxNGNsYnJfaGlnaF9nbykKZnVuIDwtIGVwaV9jbDE0Y2xicl9oaWdoX2dvJGdvZGF0YV9pbnRlcmVzdGluZwpnb3NlcV9hbm5vdGF0aW9uIDwtIGdvc2VxX3RhYmxlKGZ1bikKIyMgT2ggY3JhcCwgSSBjYW5ub3QgbWFrZSB0cmVlcyB1bnRpbCBJIGdlbmVyYXRlIGEgaWQyZ28gUiBtYXBwaW5nLCBJIHdpbGwgbmVlZCB0byBjaGVjayBteSBwcmV2aW91cyBzY3JpcHQgZm9yIGhvdyB0byBkbyB0aGF0IChJIHRoaW5rIEkgZG8gaXQgYXV0b21hdGljYWxseSBpbiBzaW1wbGVfdG9wZ28oKS4uLgojI2VwaV9jbDE0Y2xicl9oaWdoX3RyZWVzID0gZ29zZXFfdHJlZXMoZGVnZW5lcz1lcGlfY2wxNGNsYnJfaGlnaCwgZXBpX2NsMTRjbGJyX2hpZ2hfZ28pCiMjIEkgaGFkIHRvIGhhY2sgdGhlIGdlbmVUYWJsZSgpIGZ1bmN0aW9uIGluIG9yZGVyIHRvIG1ha2UgaXQgbm90IHRha2UgaW5maW5pdGUgbWVtb3J5IGJlY2F1c2UgaXQgd2FzIHRyeWluZyB0byBkbyBzb21lIHN0dXBpZCBtZXJnZSBvZiBldmVyeSBnZmYgY29sdW1uIGFnYWluc3QgZXZlcnkgb3RoZXIgY29sdW1uLi4uCiMjIE9uY2UgdGhlIGdlbmVUYWJsZS5yZGEgZmlsZSBleGlzdHMgYW5kIGluY2x1ZGVkIHJlYWwgaW5mb3JtYXRpb24sIHRoaXMgc2VlbXMgdG8gd29yayBmaW5lLCB0aG91Z2guCmVwaV9jbDE0Y2xicl9oaWdoX2NsIDwtIHNpbXBsZV9jbHVzdGVycHJvZmlsZXIoZXBpX2NsMTRjbGJyX2hpZ2gpCmVwaV9jbDE0Y2xicl9oaWdoX2NsJGJwX2FsbF9iYXJwbG90CiMjIFRoZSBmaXJzdCB0aW1lIHRoaXMgaXMgcnVuIGluIGEgZnJlc2ggZGlyZWN0b3J5LCBpdCBuZWVkcyB0byBiZSBydW4gbGlrZSB0aGlzOgojIyBzaW1wbGVfdG9wZ28oZXBpX2NsMTRjbGJyX2hpZ2gsIGdvaWRzX2RmPWdvX2lkcykKIyMgc2V0dGluZyBnb2lkc19kZiB3aWxsIHRlbGwgaXQgdG8gZ2VuZXJhdGUgYSB0YWJsZSBvZiBnZW5lcy0+R088LWdlbmVzIGluIHRoZSBmb3JtYXQgZXhwZWN0ZWQuCmVwaV9jbDE0Y2xicl9oaWdoX3RvcCA8LSBzaW1wbGVfdG9wZ28oZXBpX2NsMTRjbGJyX2hpZ2gsIGdvaWRzPWdvaWRfZmlsZSwgcHZhbHM9ZXBpX2NsMTRjbGJyX3B2YWxzKQoKdG9wZ29fcHZhbCA8LSB0b3Bnb19wdmFsX3Bsb3QoZXBpX2NsMTRjbGJyX2hpZ2hfdG9wKQp0b3Bnb19wdmFsJEJQCnRvcF90cmVlcyA8LSB0b3Bnb190cmVlcyhlcGlfY2wxNGNsYnJfaGlnaF90b3ApCnRvcF90cmVlcyRicF9maXNoZXJfdHJlZQpgYGAKCiMjIENvbXBhcmUgRXBpbWFzdGlnb3RlcyBiZXR3ZWVuIENMMTQgYW5kIENMQnIsIGxvdyBleHByZXNzaW9uCgpgYGB7ciBvbnRvbG9neV9lcGlfY2wxNGNsYnJfbG93LCBldmFsPUZBTFNFfQojIyBFeHRyYWN0IHRoZSBnZW5lcyB3aXRoIGxvdyBleHByZXNzaW9uIGluIENMMTQgY29tcGFyZWQgdG8gQnJlbmVyIGFuZCB2ZXJ5IGxvdyBwdmFsdWVzCmVwaV9jbDE0Y2xicl9sb3cgPSBzdWJzZXQoZXBpX2NsMTRjbGJyX3RhYmxlLCBsb2dGQyA8PSBlcGlfY2wxNGNsYnJfc3VtbWFyeVsyXSAmIGFkai5QLlZhbCA8PSBwdmFsX3RocmVzaCkKZXBpX2NsMTRjbGJyX2xvd19nbyA9IHNpbXBsZV9nb3NlcShkZV9nZW5lcz1lcGlfY2wxNGNsYnJfbG93LCBsZW5ndGhzPWdlbmVfbGVuZ3RocywgZ29pZHM9Z29faWRzKQplcGlfY2wxNGNsYnJfbG93X2dvJHB2YWx1ZV9oaXN0b2dyYW0KZXBpX2NsMTRjbGJyX2xvd19nbyRicHBfcGxvdAojI2VwaV9jbDE0Y2xicl9sb3dfY2wgPSBzaW1wbGVfY2x1c3RlcnByb2ZpbGVyKGVwaV9jbDE0Y2xicl9sb3csIGdmZj0icmVmZXJlbmNlL2dmZi9jbGJyZW5lcl84LjFfY29tcGxldGVfZ2VuZXMuZ2ZmLmd6IikKIyNlcGlfY2wxNGNsYnJfbG93X2NsJGJwX2FsbF9iYXJwbG90CmVwaV9jbDE0Y2xicl9sb3dfdG9wID0gc2ltcGxlX3RvcGdvKGVwaV9jbDE0Y2xicl9sb3csIGdvaWRzPWdvaWRfZmlsZSwgcHZhbHM9ZXBpX2NsMTRjbGJyX3B2YWxzKQp0b3Bnb19wdmFsID0gdG9wZ29fcHZhbF9wbG90KGVwaV9jbDE0Y2xicl9oaWdoX3RvcCkKdG9wZ29fcHZhbCRCUAp0b3BfdHJlZXMgPSB0b3Bnb190cmVlcyhlcGlfY2wxNGNsYnJfbG93X3RvcCkKdG9wX3RyZWVzJGJwX2Zpc2hlcl90cmVlCmBgYAoKIyMgQ29tcGFyZSB0cnlwbyBDTDE0L0NMQnIKCmBgYHtyIHRyeXBfY2wxNGNsYnJfaGlnaF9nb3NlcSwgZXZhbD1GQUxTRX0KIyMgQ2hhbmdlcyBpbiBlcGltYXN0aWdvdGVzIGZyb20gQ0xCcmVuZXIgdG8gQ0wxNAp0cnlwX2NsMTRjbGJyX3RhYmxlID0gYWxsX3RhYmxlcyR0cnlwX2NsMTRjbGJyCnRyeXBfY2wxNGNsYnJfc3VtbWFyeSA9IHN1bW1hcnkodHJ5cF9jbDE0Y2xicl90YWJsZSRsb2dGQykKdHJ5cF9jbDE0Y2xicl9wdmFscyA9IHRyeXBfY2wxNGNsYnJfdGFibGUkYWRqLlAuVmFsCm5hbWVzKHRyeXBfY2wxNGNsYnJfcHZhbHMpID0gcm93bmFtZXModHJ5cF9jbDE0Y2xicl90YWJsZSkKIyMgRXh0cmFjdCB0aGUgZ2VuZXMgd2l0aCBoaWdoIGV4cHJlc3Npb24gaW4gQ0wxNCBjb21wYXJlZCB0byBCcmVuZXIgYW5kIHZlcnkgbG93IHB2YWx1ZXMKdHJ5cF9jbDE0Y2xicl9oaWdoID0gc3Vic2V0KHRyeXBfY2wxNGNsYnJfdGFibGUsIGxvZ0ZDID49IHRyeXBfY2wxNGNsYnJfc3VtbWFyeVs1XSAmIGFkai5QLlZhbCA8PSBwdmFsX3RocmVzaCkKIyMgRG8gYSBnb3NlcSBjb21wYXJpc29uIG9mIHRoZSBoaWdoIGdlbmVzCnRyeXBfY2wxNGNsYnJfaGlnaF9nbyA9IHNpbXBsZV9nb3NlcSh0cnlwX2NsMTRjbGJyX2hpZ2gsIGxlbmd0aHM9Z2VuZV9sZW5ndGhzLCBnb2lkcz1nb19pZHMpCnRyeXBfY2wxNGNsYnJfaGlnaF9nbyRwdmFsdWVfaGlzdG9ncmFtCnRyeXBfY2wxNGNsYnJfaGlnaF9nbyRicHBfcGxvdAojIyBPaCBjcmFwLCBJIGNhbm5vdCBtYWtlIHRyZWVzIHVudGlsIEkgZ2VuZXJhdGUgYSBpZDJnbyBSIG1hcHBpbmcsIEkgd2lsbCBuZWVkIHRvIGNoZWNrIG15IHByZXZpb3VzIHNjcmlwdCBmb3IgaG93IHRvIGRvIHRoYXQgKEkgdGhpbmsgSSBkbyBpdCBhdXRvbWF0aWNhbGx5IGluIHNpbXBsZV90b3BnbygpLi4uCiMjdHJ5cF9jbDE0Y2xicl9oaWdoX3RyZWVzID0gZ29zZXFfdHJlZXMoZGVnZW5lcz10cnlwX2NsMTRjbGJyX2hpZ2gsIHRyeXBfY2wxNGNsYnJfaGlnaF9nbykKIyMgSSBoYWQgdG8gaGFjayB0aGUgZ2VuZVRhYmxlKCkgZnVuY3Rpb24gaW4gb3JkZXIgdG8gbWFrZSBpdCBub3QgdGFrZSBpbmZpbml0ZSBtZW1vcnkgYmVjYXVzZSBpdCB3YXMgdHJ5aW5nIHRvIGRvIHNvbWUgc3R1cGlkIG1lcmdlIG9mIGV2ZXJ5IGdmZiBjb2x1bW4gYWdhaW5zdCBldmVyeSBvdGhlciBjb2x1bW4uLi4KIyMgT25jZSB0aGUgZ2VuZVRhYmxlLnJkYSBmaWxlIGV4aXN0cyBhbmQgaW5jbHVkZWQgcmVhbCBpbmZvcm1hdGlvbiwgdGhpcyBzZWVtcyB0byB3b3JrIGZpbmUsIHRob3VnaC4KdHJ5cF9jbDE0Y2xicl9oaWdoX2NsID0gc2ltcGxlX2NsdXN0ZXJwcm9maWxlcih0cnlwX2NsMTRjbGJyX2hpZ2gpCnRyeXBfY2wxNGNsYnJfaGlnaF9jbCRicF9hbGxfYmFycGxvdAojIyBUaGUgZmlyc3QgdGltZSB0aGlzIGlzIHJ1biBpbiBhIGZyZXNoIGRpcmVjdG9yeSwgaXQgbmVlZHMgdG8gYmUgcnVuIGxpa2UgdGhpczoKIyMgc2ltcGxlX3RvcGdvKHRyeXBfY2wxNGNsYnJfaGlnaCwgZ29pZHNfZGY9Z29faWRzKQojIyBzZXR0aW5nIGdvaWRzX2RmIHdpbGwgdGVsbCBpdCB0byBnZW5lcmF0ZSBhIHRhYmxlIG9mIGdlbmVzLT5HTzwtZ2VuZXMgaW4gdGhlIGZvcm1hdCBleHBlY3RlZC4KdHJ5cF9jbDE0Y2xicl9oaWdoX3RvcCA9IHNpbXBsZV90b3Bnbyh0cnlwX2NsMTRjbGJyX2hpZ2gsIGdvaWRzPWdvaWRfZmlsZSwgcHZhbHM9dHJ5cF9jbDE0Y2xicl9wdmFscykKCnRvcGdvX3B2YWwgPSB0b3Bnb19wdmFsX3Bsb3QodHJ5cF9jbDE0Y2xicl9oaWdoX3RvcCkKdG9wZ29fcHZhbCRCUAp0b3BfdHJlZXMgPSB0b3Bnb190cmVlcyh0cnlwX2NsMTRjbGJyX2hpZ2hfdG9wKQp0b3BfdHJlZXMkYnBfZmlzaGVyX3RyZWUKYGBgCgojIyBDb21wYXJlIGNsMTQvY2xiciB0cnlwIG90aGVyIHNpZGUKCmBgYHtyIHRyeXBfY2wxNGNsYnJfbG93X2dvc2VxLCBldmFsPUZBTFNFfQojIyBDaGFuZ2VzIGluIGVwaW1hc3RpZ290ZXMgZnJvbSBDTEJyZW5lciB0byBDTDE0CnRyeXBfY2wxNGNsYnJfdGFibGUgPSBhbGxfdGFibGVzJHRyeXBfY2wxNGNsYnIKdHJ5cF9jbDE0Y2xicl9zdW1tYXJ5ID0gc3VtbWFyeSh0cnlwX2NsMTRjbGJyX3RhYmxlJGxvZ0ZDKQp0cnlwX2NsMTRjbGJyX3B2YWxzID0gdHJ5cF9jbDE0Y2xicl90YWJsZSRhZGouUC5WYWwKbmFtZXModHJ5cF9jbDE0Y2xicl9wdmFscykgPSByb3duYW1lcyh0cnlwX2NsMTRjbGJyX3RhYmxlKQojIyBFeHRyYWN0IHRoZSBnZW5lcyB3aXRoIGxvdyBleHByZXNzaW9uIGluIENMMTQgY29tcGFyZWQgdG8gQnJlbmVyIGFuZCB2ZXJ5IGxvdyBwdmFsdWVzCnRyeXBfY2wxNGNsYnJfbG93ID0gc3Vic2V0KHRyeXBfY2wxNGNsYnJfdGFibGUsIGxvZ0ZDIDw9IHRyeXBfY2wxNGNsYnJfc3VtbWFyeVsyXSAmIGFkai5QLlZhbCA8PSBwdmFsX3RocmVzaCkKIyMgRG8gYSBnb3NlcSBjb21wYXJpc29uIG9mIHRoZSBsb3cgZ2VuZXMKdHJ5cF9jbDE0Y2xicl9sb3dfZ28gPSBzaW1wbGVfZ29zZXEodHJ5cF9jbDE0Y2xicl9sb3csIGxlbmd0aHM9Z2VuZV9sZW5ndGhzLCBnb2lkcz1nb19pZHMpCnRyeXBfY2wxNGNsYnJfbG93X2dvJHB2YWx1ZV9oaXN0b2dyYW0KdHJ5cF9jbDE0Y2xicl9sb3dfZ28kYnBwX3Bsb3QKIyMgT2ggY3JhcCwgSSBjYW5ub3QgbWFrZSB0cmVlcyB1bnRpbCBJIGdlbmVyYXRlIGEgaWQyZ28gUiBtYXBwaW5nLCBJIHdpbGwgbmVlZCB0byBjaGVjayBteSBwcmV2aW91cyBzY3JpcHQgZm9yIGhvdyB0byBkbyB0aGF0IChJIHRoaW5rIEkgZG8gaXQgYXV0b21hdGljYWxseSBpbiBzaW1wbGVfdG9wZ28oKS4uLgojI3RyeXBfY2wxNGNsYnJfbG93X3RyZWVzID0gZ29zZXFfdHJlZXMoZGVnZW5lcz10cnlwX2NsMTRjbGJyX2xvdywgdHJ5cF9jbDE0Y2xicl9sb3dfZ28pCiMjIEkgaGFkIHRvIGhhY2sgdGhlIGdlbmVUYWJsZSgpIGZ1bmN0aW9uIGluIG9yZGVyIHRvIG1ha2UgaXQgbm90IHRha2UgaW5maW5pdGUgbWVtb3J5IGJlY2F1c2UgaXQgd2FzIHRyeWluZyB0byBkbyBzb21lIHN0dXBpZCBtZXJnZSBvZiBldmVyeSBnZmYgY29sdW1uIGFnYWluc3QgZXZlcnkgb3RoZXIgY29sdW1uLi4uCiMjIE9uY2UgdGhlIGdlbmVUYWJsZS5yZGEgZmlsZSBleGlzdHMgYW5kIGluY2x1ZGVkIHJlYWwgaW5mb3JtYXRpb24sIHRoaXMgc2VlbXMgdG8gd29yayBmaW5lLCB0aG91Z2guCnRyeXBfY2wxNGNsYnJfbG93X2NsID0gc2ltcGxlX2NsdXN0ZXJwcm9maWxlcih0cnlwX2NsMTRjbGJyX2xvdykKdHJ5cF9jbDE0Y2xicl9sb3dfY2wkYnBfYWxsX2JhcnBsb3QKIyMgVGhlIGZpcnN0IHRpbWUgdGhpcyBpcyBydW4gaW4gYSBmcmVzaCBkaXJlY3RvcnksIGl0IG5lZWRzIHRvIGJlIHJ1biBsaWtlIHRoaXM6CiMjIHNpbXBsZV90b3Bnbyh0cnlwX2NsMTRjbGJyX2xvdywgZ29pZHNfZGY9Z29faWRzKQojIyBzZXR0aW5nIGdvaWRzX2RmIHdpbGwgdGVsbCBpdCB0byBnZW5lcmF0ZSBhIHRhYmxlIG9mIGdlbmVzLT5HTzwtZ2VuZXMgaW4gdGhlIGZvcm1hdCBleHBlY3RlZC4KdHJ5cF9jbDE0Y2xicl9sb3dfdG9wID0gc2ltcGxlX3RvcGdvKHRyeXBfY2wxNGNsYnJfbG93LCBnb2lkcz1nb2lkX2ZpbGUsIHB2YWxzPXRyeXBfY2wxNGNsYnJfcHZhbHMpCgp0b3Bnb19wdmFsID0gdG9wZ29fcHZhbF9wbG90KHRyeXBfY2wxNGNsYnJfbG93X3RvcCkKdG9wZ29fcHZhbCRCUAp0b3BfdHJlZXMgPSB0b3Bnb190cmVlcyh0cnlwX2NsMTRjbGJyX2xvd190b3ApCnRvcF90cmVlcyRicF9maXNoZXJfdHJlZQpgYGAKCiMjIEFtYXN0aWdvdGUgYTk2IGNsMTQvY2xicgoKYGBge3Igb250b2xvZ3lfYTk2X2NsMTRjbGJyX2hpZ2gsIGV2YWw9RkFMU0V9CiMjIENoYW5nZXMgaW4gZXBpbWFzdGlnb3RlcyBmcm9tIENMQnJlbmVyIHRvIENMMTQKYTk2X2NsMTRjbGJyX3RhYmxlID0gYWxsX3RhYmxlcyRhOTZfY2wxNGNsYnIKYTk2X2NsMTRjbGJyX3N1bW1hcnkgPSBzdW1tYXJ5KGE5Nl9jbDE0Y2xicl90YWJsZSRsb2dGQykKYTk2X2NsMTRjbGJyX3B2YWxzID0gYTk2X2NsMTRjbGJyX3RhYmxlJGFkai5QLlZhbApuYW1lcyhhOTZfY2wxNGNsYnJfcHZhbHMpID0gcm93bmFtZXMoYTk2X2NsMTRjbGJyX3RhYmxlKQojIyBFeHRyYWN0IHRoZSBnZW5lcyB3aXRoIGxvdyBleHByZXNzaW9uIGluIENMMTQgY29tcGFyZWQgdG8gQnJlbmVyIGFuZCB2ZXJ5IGxvdyBwdmFsdWVzCmE5Nl9jbDE0Y2xicl9sb3cgPSBzdWJzZXQoYTk2X2NsMTRjbGJyX3RhYmxlLCBsb2dGQyA+PSBhOTZfY2wxNGNsYnJfc3VtbWFyeVs1XSAmIGFkai5QLlZhbCA8PSBwdmFsX3RocmVzaCkKIyMgRG8gYSBnb3NlcSBjb21wYXJpc29uIG9mIHRoZSBsb3cgZ2VuZXMKYTk2X2NsMTRjbGJyX2xvd19nbyA9IHNpbXBsZV9nb3NlcShhOTZfY2wxNGNsYnJfbG93LCBsZW5ndGhzPWdlbmVfbGVuZ3RocywgZ29pZHM9Z29faWRzKQphOTZfY2wxNGNsYnJfbG93X2dvJHB2YWx1ZV9oaXN0b2dyYW0KYTk2X2NsMTRjbGJyX2xvd19nbyRicHBfcGxvdAojIyBPaCBjcmFwLCBJIGNhbm5vdCBtYWtlIHRyZWVzIHVudGlsIEkgZ2VuZXJhdGUgYSBpZDJnbyBSIG1hcHBpbmcsIEkgd2lsbCBuZWVkIHRvIGNoZWNrIG15IHByZXZpb3VzIHNjcmlwdCBmb3IgaG93IHRvIGRvIHRoYXQgKEkgdGhpbmsgSSBkbyBpdCBhdXRvbWF0aWNhbGx5IGluIHNpbXBsZV90b3BnbygpLi4uCiMjYTk2X2NsMTRjbGJyX2xvd190cmVlcyA9IGdvc2VxX3RyZWVzKGRlZ2VuZXM9YTk2X2NsMTRjbGJyX2xvdywgYTk2X2NsMTRjbGJyX2xvd19nbykKIyMgSSBoYWQgdG8gaGFjayB0aGUgZ2VuZVRhYmxlKCkgZnVuY3Rpb24gaW4gb3JkZXIgdG8gbWFrZSBpdCBub3QgdGFrZSBpbmZpbml0ZSBtZW1vcnkgYmVjYXVzZSBpdCB3YXMgdHJ5aW5nIHRvIGRvIHNvbWUgc3R1cGlkIG1lcmdlIG9mIGV2ZXJ5IGdmZiBjb2x1bW4gYWdhaW5zdCBldmVyeSBvdGhlciBjb2x1bW4uLi4KIyMgT25jZSB0aGUgZ2VuZVRhYmxlLnJkYSBmaWxlIGV4aXN0cyBhbmQgaW5jbHVkZWQgcmVhbCBpbmZvcm1hdGlvbiwgdGhpcyBzZWVtcyB0byB3b3JrIGZpbmUsIHRob3VnaC4KYTk2X2NsMTRjbGJyX2xvd19jbCA9IHNpbXBsZV9jbHVzdGVycHJvZmlsZXIoYTk2X2NsMTRjbGJyX2xvdykKYTk2X2NsMTRjbGJyX2xvd19jbCRicF9hbGxfYmFycGxvdAojIyBUaGUgZmlyc3QgdGltZSB0aGlzIGlzIHJ1biBpbiBhIGZyZXNoIGRpcmVjdG9yeSwgaXQgbmVlZHMgdG8gYmUgcnVuIGxpa2UgdGhpczoKIyMgc2ltcGxlX3RvcGdvKGE5Nl9jbDE0Y2xicl9sb3csIGdvaWRzX2RmPWdvX2lkcykKIyMgc2V0dGluZyBnb2lkc19kZiB3aWxsIHRlbGwgaXQgdG8gZ2VuZXJhdGUgYSB0YWJsZSBvZiBnZW5lcy0+R088LWdlbmVzIGluIHRoZSBmb3JtYXQgZXhwZWN0ZWQuCmE5Nl9jbDE0Y2xicl9sb3dfdG9wID0gc2ltcGxlX3RvcGdvKGE5Nl9jbDE0Y2xicl9sb3csIGdvaWRzPWdvaWRfZmlsZSwgcHZhbHM9YTk2X2NsMTRjbGJyX3B2YWxzKQoKdG9wZ29fcHZhbCA9IHRvcGdvX3B2YWxfcGxvdChhOTZfY2wxNGNsYnJfbG93X3RvcCkKdG9wZ29fcHZhbCRCUAp0b3BfdHJlZXMgPSB0b3Bnb190cmVlcyhhOTZfY2wxNGNsYnJfbG93X3RvcCkKdG9wX3RyZWVzJGJwX2Zpc2hlcl90cmVlCmBgYAoKYGBge3Igb250b2xvZ3lfYTk2X2NsMTRjbGJyX2xvdywgZXZhbD1GQUxTRX0KIyMgQ2hhbmdlcyBpbiBlcGltYXN0aWdvdGVzIGZyb20gQ0xCcmVuZXIgdG8gQ0wxNAphOTZfY2wxNGNsYnJfdGFibGUgPSBzdHJhaW5fY29tcGFyaXNvbnMkZGF0YSRhOTZfY2xicl9vdmVyX2NsMTQKYTk2X2NsMTRjbGJyX3N1bW1hcnkgPSBzdW1tYXJ5KGE5Nl9jbDE0Y2xicl90YWJsZSRsb2dGQykKYTk2X2NsMTRjbGJyX3B2YWxzID0gYTk2X2NsMTRjbGJyX3RhYmxlJGFkai5QLlZhbApuYW1lcyhhOTZfY2wxNGNsYnJfcHZhbHMpID0gcm93bmFtZXMoYTk2X2NsMTRjbGJyX3RhYmxlKQojIyBFeHRyYWN0IHRoZSBnZW5lcyB3aXRoIGxvdyBleHByZXNzaW9uIGluIENMMTQgY29tcGFyZWQgdG8gQnJlbmVyIGFuZCB2ZXJ5IGxvdyBwdmFsdWVzCmE5Nl9jbDE0Y2xicl9sb3cgPSBzdWJzZXQoYTk2X2NsMTRjbGJyX3RhYmxlLCBsb2dGQyA8PSBhOTZfY2wxNGNsYnJfc3VtbWFyeVsyXSAmIGFkai5QLlZhbCA8PSBwdmFsX3RocmVzaCkKIyMgRG8gYSBnb3NlcSBjb21wYXJpc29uIG9mIHRoZSBsb3cgZ2VuZXMKYTk2X2NsMTRjbGJyX2xvd19nbyA9IHNpbXBsZV9nb3NlcShhOTZfY2wxNGNsYnJfbG93LCBsZW5ndGhzPWdlbmVfbGVuZ3RocywgZ29pZHM9Z29faWRzKQphOTZfY2wxNGNsYnJfbG93X2dvJHB2YWx1ZV9oaXN0b2dyYW0KYTk2X2NsMTRjbGJyX2xvd19nbyRicHBfcGxvdAojIyBPaCBjcmFwLCBJIGNhbm5vdCBtYWtlIHRyZWVzIHVudGlsIEkgZ2VuZXJhdGUgYSBpZDJnbyBSIG1hcHBpbmcsIEkgd2lsbCBuZWVkIHRvIGNoZWNrIG15IHByZXZpb3VzIHNjcmlwdCBmb3IgaG93IHRvIGRvIHRoYXQgKEkgdGhpbmsgSSBkbyBpdCBhdXRvbWF0aWNhbGx5IGluIHNpbXBsZV90b3BnbygpLi4uCiMjYTk2X2NsMTRjbGJyX2xvd190cmVlcyA9IGdvc2VxX3RyZWVzKGRlZ2VuZXM9YTk2X2NsMTRjbGJyX2xvdywgYTk2X2NsMTRjbGJyX2xvd19nbykKIyMgSSBoYWQgdG8gaGFjayB0aGUgZ2VuZVRhYmxlKCkgZnVuY3Rpb24gaW4gb3JkZXIgdG8gbWFrZSBpdCBub3QgdGFrZSBpbmZpbml0ZSBtZW1vcnkgYmVjYXVzZSBpdCB3YXMgdHJ5aW5nIHRvIGRvIHNvbWUgc3R1cGlkIG1lcmdlIG9mIGV2ZXJ5IGdmZiBjb2x1bW4gYWdhaW5zdCBldmVyeSBvdGhlciBjb2x1bW4uLi4KIyMgT25jZSB0aGUgZ2VuZVRhYmxlLnJkYSBmaWxlIGV4aXN0cyBhbmQgaW5jbHVkZWQgcmVhbCBpbmZvcm1hdGlvbiwgdGhpcyBzZWVtcyB0byB3b3JrIGZpbmUsIHRob3VnaC4KYTk2X2NsMTRjbGJyX2xvd19jbCA9IHNpbXBsZV9jbHVzdGVycHJvZmlsZXIoYTk2X2NsMTRjbGJyX2xvdykKYTk2X2NsMTRjbGJyX2xvd19jbCRicF9hbGxfYmFycGxvdAojIyBUaGUgZmlyc3QgdGltZSB0aGlzIGlzIHJ1biBpbiBhIGZyZXNoIGRpcmVjdG9yeSwgaXQgbmVlZHMgdG8gYmUgcnVuIGxpa2UgdGhpczoKIyNzaW1wbGVfdG9wZ28oYTk2X2NsMTRjbGJyX2xvdywgZ29pZHNfZGY9Z29faWRzKQojIyBzZXR0aW5nIGdvaWRzX2RmIHdpbGwgdGVsbCBpdCB0byBnZW5lcmF0ZSBhIHRhYmxlIG9mIGdlbmVzLT5HTzwtZ2VuZXMgaW4gdGhlIGZvcm1hdCBleHBlY3RlZC4KYTk2X2NsMTRjbGJyX2xvd190b3AgPSBzaW1wbGVfdG9wZ28oYTk2X2NsMTRjbGJyX2xvdywgZ29pZHM9Z29pZF9maWxlLCBwdmFscz1hOTZfY2wxNGNsYnJfcHZhbHMpCgp0b3Bnb19wdmFsID0gdG9wZ29fcHZhbF9wbG90KGE5Nl9jbDE0Y2xicl9sb3dfdG9wKQp0b3Bnb19wdmFsJEJQCnRvcF90cmVlcyA9IHRvcGdvX3RyZWVzKGE5Nl9jbDE0Y2xicl9sb3dfdG9wKQp0b3BfdHJlZXMkYnBfZmlzaGVyX3RyZWUKCiMjIFdheXMgdG8gbG9vawphNjBfY2wxNGNsYnJfdGFibGUgPSBhbGxfdGFibGVzJGE2MF9jbDE0Y2xicgp0bXAgPSBtZXJnZShhNjBfY2wxNGNsYnJfdGFibGUsIGE5Nl9jbDE0Y2xicl90YWJsZSwgYnk9InJvdy5uYW1lcyIpCnRtcF9iX3QgPSBkYXRhLmZyYW1lKGE2MD10bXAkQi54LCBhOTY9dG1wJEIueSkKdHQgPSBocGdsX2xpbmVhcl9zY2F0dGVyKHRtcF9iX3QpCnR0JHNjYXR0ZXIKYTYwX2NsMTRjbGJyX3RhYmxlID0gYWxsX3RhYmxlcyRhNjBfY2wxNGNsYnIKdG1wID0gbWVyZ2UoYTYwX2NsMTRjbGJyX3RhYmxlLCBhOTZfY2wxNGNsYnJfdGFibGUsIGJ5PSJyb3cubmFtZXMiKQp0bXBfYl90ID0gZGF0YS5mcmFtZShhNjA9dG1wJHQueCwgYTk2PXRtcCR0LnkpCnR0ID0gaHBnbF9zY2F0dGVyKHRtcF9iX3QpCnR0JHNjYXR0ZXIKYGBgCgojIEtHCgpPaCB5ZWFoLCBJIHdyb3RlIGEgdG95IHRvIHdyYXAgS0VHRyBwYXRod2F5IHN0dWZmLCBsZXRzIHRyeSB0aGF0LgpUaGUgS0VHRyBhYmJyZXZpYXRpb24gZm9yIHQuIGNydXppIGlzIHRjcgoKSW4gdGhlb3J5LCB0aGUgX3BhdGhzIGRhdGEgc3RydWN0dXJlIHJldHVybmVkIGJ5IGhwZ2xfcGF0aHZpZXcoKSBzaG91bGQgYmUgYSB0YWJsZQpvZiB0aGUgbnVtZXIgb2YgdXAvZG93biBnZW5lcyBvYnNlcnZlZCBpbiBlYWNoIEtFR0cgcGF0aC4gIEhvd2V2ZXIsIHRoZXJlIGFyZSBzb21lCndlaXJkIE5BcyBnZXR0aW5nIHJldHVybmVkLiAgIEVmZmluZyBoaXBwaWVzLiAtLSBmaXhlZC4KCmBgYHtyIGtlZ2dfZnVuX3YxfQprZWdnX2xpc3QgPC0gIiIKYGBgCgpgYGB7ciBrZWdnX2Z1bl92MiwgZXZhbD1GQUxTRX0KIyNuYW1lcyhrZWdnX2xpc3QpID0gcm93bmFtZXMoZXBpX2NsMTRjbGJyX3RhYmxlKQojI2VwaV9jbDE0Y2xicl9wYXRocyA9IGhwZ2xfcGF0aHZpZXcoa2VnZ19saXN0LCBzcGVjaWVzPSJ0Y3IiLCBpbmRpcj0icGF0aHZpZXdfaW4iLCBvdXRkaXI9InBhdGh2aWV3X2VwaV9jbDE0Y2xiciIsIHN0cmluZ19mcm9tPSJUY0NMQi4iLCBzdHJpbmdfdG89IiIpCiMjaGVhZChlcGlfY2wxNGNsYnJfcGF0aHMpCgoKIyNhNjBfY2wxNGNsYnJfdGFibGUgPSBhbGxfdGFibGVzJGE2MF9jbDE0Y2xicgphNjBfY2wxNGNsYnJfdGFibGUgPC0gc3RyYWluX2NvbXBhcmlzb25zJGRhdGEkYTYwX2NsYnJfb3Zlcl9jbDE0CiMja2VnZ19saXN0IDwtIGE2MF9jbDE0Y2xicl90YWJsZSRsb2dGQwprZWdnX2xpc3QgPC0gYTYwX2NsMTRjbGJyX3RhYmxlJGxpbW1hX2xvZ2ZjCm5hbWVzKGtlZ2dfbGlzdCkgPC0gcm93bmFtZXMoYTYwX2NsMTRjbGJyX3RhYmxlKQphNjBfY2wxNGNsYnJfcGF0aHMgPC0gaHBnbF9wYXRodmlldyhrZWdnX2xpc3QsIHNwZWNpZXM9InRjciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZGlyPSJwYXRodmlld19pbiIsIG91dGRpcj0icGF0aHZpZXdfYTYwX2NsMTRjbGJyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJvbV9saXN0PSJUY0NMQi4iLCB0b19saXN0PSIiKQpoZWFkKGE2MF9jbDE0Y2xicl9wYXRocykKCmE5Nl9jbDE0Y2xicl90YWJsZSA9IGFsbF90YWJsZXMkYTk2X2NsMTRjbGJyCmtlZ2dfbGlzdCA9IGE5Nl9jbDE0Y2xicl90YWJsZSRsb2dGQwpuYW1lcyhrZWdnX2xpc3QpID0gcm93bmFtZXMoYTk2X2NsMTRjbGJyX3RhYmxlKQphOTZfY2wxNGNsYnJfcGF0aHMgPSBocGdsX3BhdGh2aWV3KGtlZ2dfbGlzdCwgc3BlY2llcz0idGNyIiwgaW5kaXI9InBhdGh2aWV3X2luIiwgb3V0ZGlyPSJwYXRodmlld19hOTZfY2wxNGNsYnIiLCBzdHJpbmdfZnJvbT0iVGNDTEIuIiwgc3RyaW5nX3RvPSIiKQpoZWFkKGE5Nl9jbDE0Y2xicl9wYXRocykKCnRyeXBfY2wxNGNsYnJfdGFibGUgPSBhbGxfdGFibGVzJGE5Nl9jbDE0Y2xicgprZWdnX2xpc3QgPSB0cnlwX2NsMTRjbGJyX3RhYmxlJGxvZ0ZDCm5hbWVzKGtlZ2dfbGlzdCkgPSByb3duYW1lcyh0cnlwX2NsMTRjbGJyX3RhYmxlKQp0cnlwX2NsMTRjbGJyX3BhdGhzID0gaHBnbF9wYXRodmlldyhrZWdnX2xpc3QsIHNwZWNpZXM9InRjciIsIGluZGlyPSJwYXRodmlld19pbiIsIG91dGRpcj0icGF0aHZpZXdfdHJ5cF9jbDE0Y2xiciIsIHN0cmluZ19mcm9tPSJUY0NMQi4iLCBzdHJpbmdfdG89IiIpCmhlYWQodHJ5cF9jbDE0Y2xicl9wYXRocykKYGBgCg==