ALL IMPORTED FILES MUST BE IN THE SAME DIRECTORY AS THIS SCRIPT
Load tidyverse package
library("tidyverse")
Import raw vcf data from “masterfile” and exclude variants with GnomAD non-cancer AF > 0.005
masterfile <- read.delim("masterfile.tsv", header=TRUE, row.names=NULL, na.strings = ".", stringsAsFactors=FALSE) %>%
rename("Sample"="X.Sample") %>%
filter(GnomAD_v2.1_non_cancer_AF<=0.005)
Exclude non-epithelial, uterine-only and BRCA +ve samples
ViP_Complete_Cohort <- read.delim("ViP_LoF_Complete_Cohort.txt", stringsAsFactors=FALSE)
ViP_Complete_Cohort_list <- ViP_Complete_Cohort[,1]
masterfile_eoc <- filter(masterfile,Sample%in%c(ViP_Complete_Cohort_list))
Append patient path data
ViP_OvCa_Path_Data <- read.delim("ViP_OvCa_Path_Data.txt", header=TRUE, row.names=NULL, stringsAsFactors=FALSE) %>%
dplyr::rename("Sample"=Exome.ID)
masterfile_eoc_withPath <- left_join(masterfile_eoc,ViP_OvCa_Path_Data,by="Sample",copy=FALSE)
rm(ViP_OvCa_Path_Data)
Exclude low-grade tumour samples
masterfile_eoc2 <- filter(masterfile_eoc_withPath,(!Histopath.Type%in%c("Borderline tumour",
"Mucinous",
"Clear cell",
"Low-grade serous",
"Low-grade endometrioid",
"Serous (?low-grade/borderline)",
"Mixed Mullerian",
"Mixed EAOC")))
Exclude samples from women aged below/above 60 years
masterfile_eoc_ageUnder60 <- filter(masterfile_eoc2,Reported.Age.Dx<60)
masterfile_eoc_ageOver60 <- filter(masterfile_eoc2,Reported.Age.Dx>=60)
Exclude low-quality variants and GnomAD RF/InbreedingCoeff-flagged variants
masterfile_eoc_ageUnder60_goodQ <- filter(masterfile_eoc_ageUnder60, (QUAL>=30)&
(Identified!="FilteredInAll")&
(Sample.PMCDP>=10)&
(Sample.PMCFREQ>=0.25)) %>%
filter((!str_detect(GnomAD_v2.1_FILTER_exome,"InbreedingCoeff")&
!str_detect(GnomAD_v2.1_FILTER_exome,"RF"))|
is.na(GnomAD_v2.1_FILTER_exome)) %>%
filter((!str_detect(GnomAD_v2.1_FILTER_genome,"InbreedingCoeff")&
!str_detect(GnomAD_v2.1_FILTER_genome,"RF"))|
is.na(GnomAD_v2.1_FILTER_genome))
masterfile_eoc_ageOver60_goodQ <- filter(masterfile_eoc_ageOver60, (QUAL>=30)&
(Identified!="FilteredInAll")&
(Sample.PMCDP>=10)&
(Sample.PMCFREQ>=0.25)) %>%
filter((!str_detect(GnomAD_v2.1_FILTER_exome,"InbreedingCoeff")&
!str_detect(GnomAD_v2.1_FILTER_exome,"RF"))|
is.na(GnomAD_v2.1_FILTER_exome)) %>%
filter((!str_detect(GnomAD_v2.1_FILTER_genome,"InbreedingCoeff")&
!str_detect(GnomAD_v2.1_FILTER_genome,"RF"))|
is.na(GnomAD_v2.1_FILTER_genome))
Exclude other mutation +ve samples (MLH1/MSH2/MSH6/PMS2, TP53, RAD51C/D, BRIP1)
ViP_Discovery_Cohort <- read.delim("ViP_LoF_Discovery_Cohort.txt", stringsAsFactors=FALSE)
ViP_Discovery_Cohort_list <- ViP_Discovery_Cohort[,1]
masterfile_eoc_ageUnder60_goodQ2 <- filter(masterfile_eoc_ageUnder60_goodQ,Sample%in%c(ViP_Discovery_Cohort_list))
Total_Sample_Alleles_ageUnder60 <- (n_distinct(masterfile_eoc_ageUnder60_goodQ2$Sample)*2)
masterfile_eoc_ageOver60_goodQ2 <- filter(masterfile_eoc_ageOver60_goodQ,Sample%in%c(ViP_Discovery_Cohort_list))
Total_Sample_Alleles_ageOver60 <- (n_distinct(masterfile_eoc_ageOver60_goodQ2$Sample)*2)
Exclude MODERATE impact variants
masterfile_eoc_ageUnder60_goodQ_HIGH <- filter(masterfile_eoc_ageUnder60_goodQ, IMPACT=="HIGH")
masterfile_eoc_ageUnder60_goodQ2_HIGH <- filter(masterfile_eoc_ageUnder60_goodQ2, IMPACT=="HIGH")
masterfile_eoc_ageOver60_goodQ_HIGH <- filter(masterfile_eoc_ageOver60_goodQ, IMPACT=="HIGH")
masterfile_eoc_ageOver60_goodQ2_HIGH <- filter(masterfile_eoc_ageOver60_goodQ2, IMPACT=="HIGH")
Separate Ensembl canonical and RefSeq canonical variants
masterfile_eoc_ageUnder60_goodQ_HIGH_ENSTcanonical <- filter(masterfile_eoc_ageUnder60_goodQ_HIGH,CANONICAL=="YES")
masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical <- filter(masterfile_eoc_ageUnder60_goodQ2_HIGH,CANONICAL=="YES")
masterfile_eoc_ageUnder60_goodQ2_HIGH_NMcanonical <- filter(masterfile_eoc_ageUnder60_goodQ2_HIGH,Ensembl94_refseq_mrna!="is.na") %>%
filter(!Ensembl94_refseq_mrna_STATUS%in%c(".|.",
".|.|.",
"MODEL",
"INFERRED",
"PREDICTED",
"PROVISIONAL",
"WGS"))
masterfile_eoc_ageOver60_goodQ_HIGH_ENSTcanonical <- filter(masterfile_eoc_ageOver60_goodQ_HIGH,CANONICAL=="YES")
masterfile_eoc_ageOver60_goodQ2_HIGH_ENSTcanonical <- filter(masterfile_eoc_ageOver60_goodQ2_HIGH,CANONICAL=="YES")
masterfile_eoc_ageOver60_goodQ2_HIGH_NMcanonical <- filter(masterfile_eoc_ageOver60_goodQ2_HIGH,Ensembl94_refseq_mrna!="is.na") %>%
filter(!Ensembl94_refseq_mrna_STATUS%in%c(".|.",
".|.|.",
"MODEL",
"INFERRED",
"PREDICTED",
"PROVISIONAL",
"WGS"))
Sample variant counts and AFs
variant_counts_AFs <- function(vcf,Total_Sample_Alleles){
variants_heterozygous <- vcf %>%
select(HGVSc,Sample.GT) %>%
group_by(HGVSc,Sample.GT) %>%
summarise(n()) %>%
filter((Sample.GT%in%c("'0/1","'1/0"))) %>%
dplyr::rename(alleles = "n()") %>%
group_by(HGVSc) %>%
summarise(sum(alleles))
variants_homozygous <- vcf %>%
select(HGVSc,Sample.GT) %>%
group_by(HGVSc,Sample.GT) %>%
summarise(n()) %>%
filter((Sample.GT!="'0/1")&(Sample.GT!="'1/0")) %>%
mutate(alleles = `n()`*2) %>%
select(-`n()`) %>%
group_by(HGVSc) %>%
summarise(sum(alleles))
variants <- full_join(variants_heterozygous,variants_homozygous,by="HGVSc",copy=FALSE,suffix=c(".x",".y")) %>%
mutate_all(funs(replace(., is.na(.), 0))) %>%
mutate(Total_Allele_Count=`sum(alleles).x`+`sum(alleles).y`) %>%
mutate(Sample_AF=Total_Allele_Count/Total_Sample_Alleles)
vcf <- left_join(vcf, variants[,c(1,4:5)],by="HGVSc",copy=FALSE)
}
masterfile_eoc_ageUnder60_goodQ_HIGH_ENSTcanonical_2 <- variant_counts_AFs(masterfile_eoc_ageUnder60_goodQ_HIGH_ENSTcanonical,Total_Sample_Alleles_ageUnder60)
masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_2 <- variant_counts_AFs(masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical,Total_Sample_Alleles_ageUnder60)
masterfile_eoc_ageUnder60_goodQ2_HIGH_NMcanonical_2 <- variant_counts_AFs(masterfile_eoc_ageUnder60_goodQ2_HIGH_NMcanonical,Total_Sample_Alleles_ageUnder60)
masterfile_eoc_ageOver60_goodQ_HIGH_ENSTcanonical_2 <- variant_counts_AFs(masterfile_eoc_ageOver60_goodQ_HIGH_ENSTcanonical,Total_Sample_Alleles_ageOver60)
masterfile_eoc_ageOver60_goodQ2_HIGH_ENSTcanonical_2 <- variant_counts_AFs(masterfile_eoc_ageOver60_goodQ2_HIGH_ENSTcanonical,Total_Sample_Alleles_ageOver60)
masterfile_eoc_ageOver60_goodQ2_HIGH_NMcanonical_2 <- variant_counts_AFs(masterfile_eoc_ageOver60_goodQ2_HIGH_NMcanonical,Total_Sample_Alleles_ageOver60)
Exclude variants with sample AF >0.01̛
masterfile_eoc_ageUnder60_goodQ_HIGH_ENSTcanonical_sampleAF0.01 <- filter(masterfile_eoc_ageUnder60_goodQ_HIGH_ENSTcanonical_2,Sample_AF < 0.01)
masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01 <- filter(masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_2,Sample_AF < 0.01)
masterfile_eoc_ageUnder60_goodQ2_HIGH_NMcanonical_sampleAF0.01 <- filter(masterfile_eoc_ageUnder60_goodQ2_HIGH_NMcanonical_2,Sample_AF < 0.01)
masterfile_eoc_ageOver60_goodQ_HIGH_ENSTcanonical_sampleAF0.01 <- filter(masterfile_eoc_ageOver60_goodQ_HIGH_ENSTcanonical_2,Sample_AF < 0.01)
masterfile_eoc_ageOver60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01 <- filter(masterfile_eoc_ageOver60_goodQ2_HIGH_ENSTcanonical_2,Sample_AF < 0.01)
masterfile_eoc_ageOver60_goodQ2_HIGH_NMcanonical_sampleAF0.01 <- filter(masterfile_eoc_ageOver60_goodQ2_HIGH_NMcanonical_2,Sample_AF < 0.01)
Output list of genes and variants with sample AF >0.01
masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_genesandvariants0.01 <- filter(masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_2,Sample_AF > 0.01)
masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_genesandvariants0.01[,c(2:6,25:54)] %>%
distinct(.keep_all = FALSE) %>%
write_excel_csv(path="masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_genesandvariants0.01.csv",na=".",append=FALSE,col_names=TRUE)
masterfile_eoc_ageUnder60_goodQ2_HIGH_NMcanonical_genesandvariants0.01 <- filter(masterfile_eoc_ageUnder60_goodQ2_HIGH_NMcanonical_2,Sample_AF > 0.01)
masterfile_eoc_ageUnder60_goodQ2_HIGH_NMcanonical_genesandvariants0.01[,c(2:6,25:54)] %>%
distinct(.keep_all = FALSE) %>%
write_excel_csv(path="masterfile_eoc_ageUnder60_goodQ2_HIGH_NMcanonical_genesandvariants0.01.csv",na=".",append=FALSE,col_names=TRUE)
masterfile_eoc_ageOver60_goodQ2_HIGH_ENSTcanonical_genesandvariants0.01 <- filter(masterfile_eoc_ageOver60_goodQ2_HIGH_ENSTcanonical_2,Sample_AF > 0.01)
masterfile_eoc_ageOver60_goodQ2_HIGH_ENSTcanonical_genesandvariants0.01[,c(2:6,25:54)] %>%
distinct(.keep_all = FALSE) %>%
write_excel_csv(path="masterfile_eoc_ageOver60_goodQ2_HIGH_ENSTcanonical_genesandvariants0.01.csv",na=".",append=FALSE,col_names=TRUE)
masterfile_eoc_ageOver60_goodQ2_HIGH_NMcanonical_genesandvariants0.01 <- filter(masterfile_eoc_ageOver60_goodQ2_HIGH_NMcanonical_2,Sample_AF > 0.01)
masterfile_eoc_ageOver60_goodQ2_HIGH_NMcanonical_genesandvariants0.01[,c(2:6,25:54)] %>%
distinct(.keep_all = FALSE) %>%
write_excel_csv(path="masterfile_eoc_ageOver60_goodQ2_HIGH_NMcanonical_genesandvariants0.01.csv",na=".",append=FALSE,col_names=TRUE)
Sample gene counts and frequencies
gene_counts_AFs <- function(vcf,Total_Sample_Alleles){
genes_oneVarAllele <- vcf %>% select(SYMBOL,Sample.GT) %>%
select(SYMBOL,Sample.GT) %>%
group_by(SYMBOL,Sample.GT) %>%
summarise(n()) %>%
filter((Sample.GT%in%c("'0/1","'1/0"))) %>%
dplyr::rename(gene_Var = "n()") %>%
group_by(SYMBOL) %>%
summarise(sum(gene_Var))
genes_twoVarAllele <- vcf %>% select(SYMBOL,Sample.GT) %>%
select(SYMBOL,Sample.GT) %>%
group_by(SYMBOL,Sample.GT) %>%
summarise(n()) %>%
filter((Sample.GT!="'0/1")&(Sample.GT!="'1/0")) %>%
mutate(gene_Var = `n()`*2) %>%
select(-`n()`) %>%
group_by(SYMBOL) %>%
summarise(sum(gene_Var))
genes <- full_join(genes_oneVarAllele,genes_twoVarAllele,by="SYMBOL",copy=FALSE,suffix=c(".x",".y")) %>%
mutate_all(funs(replace(., is.na(.), 0))) %>%
mutate(Total_Gene_Count=`sum(gene_Var).x`+`sum(gene_Var).y`) %>%
mutate(Sample_Gene_Freq=Total_Gene_Count/Total_Sample_Alleles)
vcf <- left_join(vcf, genes[,c(1,4:5)],by="SYMBOL",copy=FALSE)
}
masterfile_eoc_ageUnder60_goodQ_HIGH_ENSTcanonical_sampleAF0.01_2 <- gene_counts_AFs(masterfile_eoc_ageUnder60_goodQ_HIGH_ENSTcanonical_sampleAF0.01,Total_Sample_Alleles_ageUnder60)
masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_2 <- gene_counts_AFs(masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01,Total_Sample_Alleles_ageUnder60)
masterfile_eoc_ageUnder60_goodQ2_HIGH_NMcanonical_sampleAF0.01_2 <- gene_counts_AFs(masterfile_eoc_ageUnder60_goodQ2_HIGH_NMcanonical_sampleAF0.01,Total_Sample_Alleles_ageUnder60)
masterfile_eoc_ageOver60_goodQ_HIGH_ENSTcanonical_sampleAF0.01_2 <- gene_counts_AFs(masterfile_eoc_ageOver60_goodQ_HIGH_ENSTcanonical_sampleAF0.01,Total_Sample_Alleles_ageOver60)
masterfile_eoc_ageOver60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_2 <- gene_counts_AFs(masterfile_eoc_ageOver60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01,Total_Sample_Alleles_ageOver60)
masterfile_eoc_ageOver60_goodQ2_HIGH_NMcanonical_sampleAF0.01_2 <- gene_counts_AFs(masterfile_eoc_ageOver60_goodQ2_HIGH_NMcanonical_sampleAF0.01,Total_Sample_Alleles_ageOver60)
Add GnomAD gene-level data
GnomAD_stats_LOF_VEP <- read.delim("GnomAD_stats_LOF_VEP.tsv", header=TRUE, row.names=NULL, stringsAsFactors=FALSE)
GnomADD <- function(vcf,GnomAD){
vcf <- left_join(vcf, GnomAD[,c(2,30:41)],by="Feature",copy=FALSE)
vcf <- mutate_at(vcf,vars(starts_with("FILTER_")),funs(replace(., is.na(.), 0))) %>%
mutate_if(grepl("popmax$", names(.)),funs(ifelse(. == "NA", 0, as.numeric(.)))) %>%
mutate_at(vars(ends_with("popmax")),funs(replace(., is.na(.), 0)))
}
masterfile_eoc_ageUnder60_goodQ_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats <- GnomADD(masterfile_eoc_ageUnder60_goodQ_HIGH_ENSTcanonical_sampleAF0.01_2,GnomAD_stats_LOF_VEP)
masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats <- GnomADD(masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_2,GnomAD_stats_LOF_VEP)
masterfile_eoc_ageUnder60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats <- GnomADD(masterfile_eoc_ageUnder60_goodQ2_HIGH_NMcanonical_sampleAF0.01_2,GnomAD_stats_LOF_VEP)
masterfile_eoc_ageOver60_goodQ_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats <- GnomADD(masterfile_eoc_ageOver60_goodQ_HIGH_ENSTcanonical_sampleAF0.01_2,GnomAD_stats_LOF_VEP)
masterfile_eoc_ageOver60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats <- GnomADD(masterfile_eoc_ageOver60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_2,GnomAD_stats_LOF_VEP)
masterfile_eoc_ageOver60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats <- GnomADD(masterfile_eoc_ageOver60_goodQ2_HIGH_NMcanonical_sampleAF0.01_2,GnomAD_stats_LOF_VEP)
Calculate Sample/GnomAD gene freq ratios for total and NFE GnomAD figures (including and excluding variants with AF > 0.005), as well as allele freq ratios
ratios <- function(vcf){
mutate(vcf,
"Sample_Gene_LOF_Freq_Ratio_GnomAD"=Sample_Gene_Freq/FILTER_RF_LOF_HIGHIMPACT_AF_1.0_ADJ,
"Sample_Gene_LOF_Freq_Ratio_GnomAD_0.005"=Sample_Gene_Freq/FILTER_RF_LOF_HIGHIMPACT_AF_0.005_ADJ,
"Ratio_Difference"=Sample_Gene_LOF_Freq_Ratio_GnomAD_0.005-Sample_Gene_LOF_Freq_Ratio_GnomAD,
"Sample_Gene_LOF_Freq_Ratio_GnomAD_NFE"=Sample_Gene_Freq/FILTER_RF_LOF_HIGHIMPACT_AF_1.0_NFE_ADJ,
"Sample_Gene_LOF_Freq_Ratio_GnomAD_NFE_0.005"=Sample_Gene_Freq/FILTER_RF_LOF_HIGHIMPACT_AF_0.005_NFE_ADJ,
"Ratio_Difference_NFE"=Sample_Gene_LOF_Freq_Ratio_GnomAD_NFE_0.005-Sample_Gene_LOF_Freq_Ratio_GnomAD_NFE,
"Sample_Gene_LOF_AF_Ratio"=Sample_AF/GnomAD_v2.1_non_cancer_AF,
"Sample_Gene_LOF_AF_Ratio_NFE"=Sample_AF/GnomAD_v2.1_non_cancer_AF_nfe)
}
masterfile_eoc_ageUnder60_goodQ_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios <-
ratios(masterfile_eoc_ageUnder60_goodQ_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats)
masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios <-
ratios(masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats)
masterfile_eoc_ageUnder60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios <-
ratios(masterfile_eoc_ageUnder60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats)
masterfile_eoc_ageOver60_goodQ_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios <-
ratios(masterfile_eoc_ageOver60_goodQ_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats)
masterfile_eoc_ageOver60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios <-
ratios(masterfile_eoc_ageOver60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats)
masterfile_eoc_ageOver60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios <-
ratios(masterfile_eoc_ageOver60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats)
Create data frames with Agilent SureSelect whole exome genes (all ENST, protein-coding only and non-protein-coding) for volcano plot
ensembl_biotypes <- read.delim("ensembl_biotypes.tsv", stringsAsFactors=FALSE) %>%
select(ensembl_transcript_id,transcript_biotype) %>%
dplyr::rename("Feature"="ensembl_transcript_id","BIOTYPE"="transcript_biotype")
GnomAD_stats_AgilentSSv6_LOF_VEP_ENSTcanonical_all <- read.delim("GnomAD.gene.stats.v2.RF.only.agilent.v6.only.tsv", header=TRUE, row.names=NULL, stringsAsFactors=FALSE) %>%
filter(CANONICAL=="YES") %>%
dplyr::rename("SYMBOL"="X.Symbol") %>%
dplyr::rename("Gene"="ENSG") %>%
left_join(ensembl_biotypes,by="Feature",copy=FALSE)
GnomAD_stats_AgilentSSv6_LOF_VEP_ENSTcanonical_protein_coding <- read.delim("GnomAD.gene.stats.v2.RF.only.agilent.v6.only.tsv", header=TRUE, row.names=NULL, stringsAsFactors=FALSE) %>%
filter(CANONICAL=="YES") %>%
dplyr::rename("SYMBOL"="X.Symbol") %>%
dplyr::rename("Gene"="ENSG") %>%
left_join(ensembl_biotypes,by="Feature",copy=FALSE) %>%
filter(BIOTYPE%in%c("protein_coding"))
GnomAD_stats_AgilentSSv6_LOF_VEP_ENSTcanonical_non_protein_coding <- read.delim("GnomAD.gene.stats.v2.RF.only.agilent.v6.only.tsv", header=TRUE, row.names=NULL, stringsAsFactors=FALSE) %>%
filter(CANONICAL=="YES") %>%
dplyr::rename("SYMBOL"="X.Symbol") %>%
dplyr::rename("Gene"="ENSG") %>%
left_join(ensembl_biotypes,by="Feature",copy=FALSE) %>%
filter(!BIOTYPE%in%c("protein_coding"))
allGenes_AgilentSSv6_list <- tibble("SYMBOL"=GnomAD_stats_AgilentSSv6_LOF_VEP_ENSTcanonical_all$SYMBOL,"Gene"=GnomAD_stats_AgilentSSv6_LOF_VEP_ENSTcanonical_all$Gene,"Feature"=GnomAD_stats_AgilentSSv6_LOF_VEP_ENSTcanonical_all$Feature) %>%
distinct(.keep_all=TRUE) %>%
arrange(SYMBOL)
allGenes_AgilentSSv6_list_protein_coding_only <- tibble("SYMBOL"=GnomAD_stats_AgilentSSv6_LOF_VEP_ENSTcanonical_protein_coding$SYMBOL,"Gene"=GnomAD_stats_AgilentSSv6_LOF_VEP_ENSTcanonical_protein_coding$Gene,"Feature"=GnomAD_stats_AgilentSSv6_LOF_VEP_ENSTcanonical_protein_coding$Feature) %>%
distinct(.keep_all=TRUE) %>%
arrange(SYMBOL)
allGenes_AgilentSSv6_list_non_protein_coding_only <- tibble("SYMBOL"=GnomAD_stats_AgilentSSv6_LOF_VEP_ENSTcanonical_non_protein_coding$SYMBOL,"Gene"=GnomAD_stats_AgilentSSv6_LOF_VEP_ENSTcanonical_non_protein_coding$Gene,"Feature"=GnomAD_stats_AgilentSSv6_LOF_VEP_ENSTcanonical_non_protein_coding$Feature) %>%
distinct(.keep_all=TRUE) %>%
arrange(SYMBOL)
allGenes_masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_list <- tibble("SYMBOL"=masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios$SYMBOL,"Gene"=masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios$Gene,"BIOTYPE"=masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios$BIOTYPE) %>%
distinct(.keep_all=TRUE) %>%
arrange(SYMBOL)
allGenes_masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_biotype_list <- tibble("SYMBOL"=masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios$SYMBOL,"Gene"=masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios$Gene,"BIOTYPE"=masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios$BIOTYPE) %>%
distinct(.keep_all=TRUE) %>%
filter(BIOTYPE%in%c("protein_coding")) %>%
arrange(SYMBOL)
allGenes_masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_biotype2_list <- tibble("SYMBOL"=masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios$SYMBOL,"Gene"=masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios$Gene,"BIOTYPE"=masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios$BIOTYPE) %>%
distinct(.keep_all=TRUE) %>%
filter(!BIOTYPE%in%c("protein_coding")) %>%
arrange(SYMBOL)
volcano <- function(vcf,gene_list,GnomAD,Total_Sample_Alleles){
water <- vcf %>%
mutate(Total_Case_Alleles=Total_Sample_Alleles) %>%
select(SYMBOL,Gene,Total_Gene_Count,Total_Case_Alleles) %>%
distinct(SYMBOL,Gene,Total_Gene_Count,Total_Case_Alleles)
water2 <- bind_rows(water, anti_join(gene_list,water,by="Gene")) %>%
mutate_at(vars("Total_Gene_Count"),funs(replace(., is.na(.), 0))) %>%
mutate_at(vars("Total_Case_Alleles"),funs(replace(., is.na(.), Total_Sample_Alleles)))
water3 <- right_join(water2,GnomAD,by="Gene",copy=FALSE) %>%
select("SYMBOL.x","Gene","Total_Gene_Count","Total_Case_Alleles","FILTER_RF_LOF_HIGHIMPACT_AC_0.005","FILTER_RF_LOF_HIGHIMPACT_AC_0.005_NFE","MAX_AN","MAX_AN_NFE","FILTER_RF_LOF_HIGHIMPACT_AF_0.005_ADJ","FILTER_RF_LOF_HIGHIMPACT_AF_0.005_NFE_ADJ") %>%
dplyr::rename("SYMBOL"="SYMBOL.x") %>%
mutate(FILTER_RF_LOF_HIGHIMPACT_AC_0.005_ADJ=round((MAX_AN*FILTER_RF_LOF_HIGHIMPACT_AF_0.005_ADJ))) %>%
mutate(FILTER_RF_LOF_HIGHIMPACT_AC_0.005_NFE_ADJ=round((MAX_AN_NFE*FILTER_RF_LOF_HIGHIMPACT_AF_0.005_NFE_ADJ))) %>%
distinct(.keep_all=TRUE)
return(water3)
}
volcano_ageUnder60_sampleAF0.01_allGenes <- volcano(masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios,allGenes_AgilentSSv6_list,GnomAD_stats_AgilentSSv6_LOF_VEP_ENSTcanonical_all,Total_Sample_Alleles_ageUnder60)
volcano_ageUnder60_sampleAF0.01_biotype_allGenes <- volcano(masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios,allGenes_AgilentSSv6_list_protein_coding_only,GnomAD_stats_AgilentSSv6_LOF_VEP_ENSTcanonical_protein_coding,Total_Sample_Alleles_ageUnder60)
volcano_ageUnder60_sampleAF0.01_biotype2_allGenes <- volcano(masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios,allGenes_AgilentSSv6_list_non_protein_coding_only,GnomAD_stats_AgilentSSv6_LOF_VEP_ENSTcanonical_non_protein_coding,Total_Sample_Alleles_ageUnder60)
volcano_ageOver60_sampleAF0.01_allGenes <- volcano(masterfile_eoc_ageOver60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios,allGenes_AgilentSSv6_list,GnomAD_stats_AgilentSSv6_LOF_VEP_ENSTcanonical_all,Total_Sample_Alleles_ageOver60)
volcano_ageOver60_sampleAF0.01_biotype_allGenes <- volcano(masterfile_eoc_ageOver60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios,allGenes_AgilentSSv6_list_protein_coding_only,GnomAD_stats_AgilentSSv6_LOF_VEP_ENSTcanonical_protein_coding,Total_Sample_Alleles_ageOver60)
volcano_ageOver60_sampleAF0.01_biotype2_allGenes <- volcano(masterfile_eoc_ageOver60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios,allGenes_AgilentSSv6_list_non_protein_coding_only,GnomAD_stats_AgilentSSv6_LOF_VEP_ENSTcanonical_non_protein_coding,Total_Sample_Alleles_ageOver60)
Calculate Fisher’s test values (Ensembl Canonical)
masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults <- mutate(masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios,Total_Case_Alleles=Total_Sample_Alleles_ageUnder60) %>%
left_join(GnomAD_stats_LOF_VEP[,c(2,6,10,14:29)],by="Feature",copy=FALSE)
masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults2 <- mutate(masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults, MAX_AN=replace(masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults$MAX_AN, is.na(masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults$MAX_AN), max(masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults$MAX_AN, na.rm=TRUE))) %>%
mutate(MAX_AN_NFE=replace(.$MAX_AN_NFE, is.na(.$MAX_AN_NFE), max(masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults$MAX_AN_NFE, na.rm=TRUE)))
fisherresults_ENST <- apply(masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults2[,c(221,229,243,244)],1,function(x) {fisher.test(rbind(x[1:2],c(x[3]-x[1],x[4]-x[2])))})
masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults2$P_value_Fisher_0.005 = sapply(fisherresults_ENST,function(x) round(x$p.value,12))
masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults2$OR_0.005 = sapply(fisherresults_ENST,function(x) round(x$estimate,4))
masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults2$`95%CI_0.005` = sapply(fisherresults_ENST,function(x) paste(round(x$conf.int[1:2],2),collapse="~"))
masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults2$BH_0.005 = p.adjust(masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults2$P_value_Fisher_0.005,method = "BH")
fisherresults2_ENST <- apply(masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults2[,c(221,232,243,245)],1,function(x) {fisher.test(rbind(x[1:2],c(x[3]-x[1],x[4]-x[2])))})
masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults2$P_value_Fisher_0.005_NFE = sapply(fisherresults2_ENST,function(x) round(x$p.value,12))
masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults2$OR_0.005_NFE = sapply(fisherresults2_ENST,function(x) round(x$estimate,4))
masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults2$`95%CI_0.005_NFE` = sapply(fisherresults2_ENST,function(x) paste(round(x$conf.int[1:2],2),collapse="~"))
masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults2$BH_0.005_NFE = p.adjust(masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults2$P_value_Fisher_0.005_NFE,method = "BH")
masterfile_eoc_ageOver60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults <- mutate(masterfile_eoc_ageOver60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios,Total_Case_Alleles=Total_Sample_Alleles_ageOver60) %>%
left_join(GnomAD_stats_LOF_VEP[,c(2,6,10,14:29)],by="Feature",copy=FALSE)
masterfile_eoc_ageOver60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults2 <- mutate(masterfile_eoc_ageOver60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults, MAX_AN=replace(masterfile_eoc_ageOver60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults$MAX_AN, is.na(masterfile_eoc_ageOver60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults$MAX_AN), max(masterfile_eoc_ageOver60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults$MAX_AN, na.rm=TRUE))) %>%
mutate(MAX_AN_NFE=replace(.$MAX_AN_NFE, is.na(.$MAX_AN_NFE), max(masterfile_eoc_ageOver60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults$MAX_AN_NFE, na.rm=TRUE)))
fisherresults_ENST <- apply(masterfile_eoc_ageOver60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults2[,c(221,229,243,244)],1,function(x) {fisher.test(rbind(x[1:2],c(x[3]-x[1],x[4]-x[2])))})
masterfile_eoc_ageOver60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults2$P_value_Fisher_0.005 = sapply(fisherresults_ENST,function(x) round(x$p.value,12))
masterfile_eoc_ageOver60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults2$OR_0.005 = sapply(fisherresults_ENST,function(x) round(x$estimate,4))
masterfile_eoc_ageOver60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults2$`95%CI_0.005` = sapply(fisherresults_ENST,function(x) paste(round(x$conf.int[1:2],2),collapse="~"))
masterfile_eoc_ageOver60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults2$BH_0.005 = p.adjust(masterfile_eoc_ageOver60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults2$P_value_Fisher_0.005,method = "BH")
fisherresults2_ENST <- apply(masterfile_eoc_ageOver60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults2[,c(221,232,243,245)],1,function(x) {fisher.test(rbind(x[1:2],c(x[3]-x[1],x[4]-x[2])))})
masterfile_eoc_ageOver60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults2$P_value_Fisher_0.005_NFE = sapply(fisherresults2_ENST,function(x) round(x$p.value,12))
masterfile_eoc_ageOver60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults2$OR_0.005_NFE = sapply(fisherresults2_ENST,function(x) round(x$estimate,4))
masterfile_eoc_ageOver60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults2$`95%CI_0.005_NFE` = sapply(fisherresults2_ENST,function(x) paste(round(x$conf.int[1:2],2),collapse="~"))
masterfile_eoc_ageOver60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults2$BH_0.005_NFE = p.adjust(masterfile_eoc_ageOver60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults2$P_value_Fisher_0.005_NFE,method = "BH")
Calculate Fisher’s test values (RefSeq Canonical)
masterfile_eoc_ageUnder60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults <- mutate(masterfile_eoc_ageUnder60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios,Total_Case_Alleles=Total_Sample_Alleles_ageUnder60) %>%
left_join(GnomAD_stats_LOF_VEP[,c(2,6,10,14:29)],by="Feature",copy=FALSE)
masterfile_eoc_ageUnder60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults2 <- mutate(masterfile_eoc_ageUnder60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults, MAX_AN=replace(masterfile_eoc_ageUnder60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults$MAX_AN, is.na(masterfile_eoc_ageUnder60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults$MAX_AN), max(masterfile_eoc_ageUnder60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults$MAX_AN, na.rm=TRUE))) %>%
mutate(MAX_AN_NFE=replace(.$MAX_AN_NFE, is.na(.$MAX_AN_NFE), max(masterfile_eoc_ageUnder60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults$MAX_AN_NFE, na.rm=TRUE)))
fisherresults_NM <- apply(masterfile_eoc_ageUnder60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults2[,c(221,229,243,244)],1,function(x) {fisher.test(rbind(x[1:2],c(x[3]-x[1],x[4]-x[2])))})
masterfile_eoc_ageUnder60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults2$P_value_Fisher_0.005 = sapply(fisherresults_NM,function(x) round(x$p.value,12))
masterfile_eoc_ageUnder60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults2$OR_0.005 = sapply(fisherresults_NM,function(x) round(x$estimate,4))
masterfile_eoc_ageUnder60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults2$`95%CI_0.005` = sapply(fisherresults_NM,function(x) paste(round(x$conf.int[1:2],2),collapse="~"))
masterfile_eoc_ageUnder60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults2$BH_0.005 = p.adjust(masterfile_eoc_ageUnder60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults2$P_value_Fisher_0.005,method = "BH")
fisherresults2_NM <- apply(masterfile_eoc_ageUnder60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults2[,c(221,232,243,245)],1,function(x) {fisher.test(rbind(x[1:2],c(x[3]-x[1],x[4]-x[2])))})
masterfile_eoc_ageUnder60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults2$P_value_Fisher_0.005_NFE = sapply(fisherresults2_NM,function(x) round(x$p.value,12))
masterfile_eoc_ageUnder60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults2$OR_0.005_NFE = sapply(fisherresults2_NM,function(x) round(x$estimate,4))
masterfile_eoc_ageUnder60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults2$`95%CI_0.005_NFE` = sapply(fisherresults2_NM,function(x) paste(round(x$conf.int[1:2],2),collapse="~"))
masterfile_eoc_ageUnder60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults2$BH_0.005_NFE = p.adjust(masterfile_eoc_ageUnder60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults2$P_value_Fisher_0.005_NFE,method = "BH")
masterfile_eoc_ageOver60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults <- mutate(masterfile_eoc_ageOver60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios,Total_Case_Alleles=Total_Sample_Alleles_ageOver60) %>%
left_join(GnomAD_stats_LOF_VEP[,c(2,6,10,14:29)],by="Feature",copy=FALSE)
masterfile_eoc_ageOver60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults2 <- mutate(masterfile_eoc_ageOver60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults, MAX_AN=replace(masterfile_eoc_ageOver60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults$MAX_AN, is.na(masterfile_eoc_ageOver60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults$MAX_AN), max(masterfile_eoc_ageOver60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults$MAX_AN, na.rm=TRUE))) %>%
mutate(MAX_AN_NFE=replace(.$MAX_AN_NFE, is.na(.$MAX_AN_NFE), max(masterfile_eoc_ageOver60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults$MAX_AN_NFE, na.rm=TRUE)))
fisherresults_NM <- apply(masterfile_eoc_ageOver60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults2[,c(221,229,243,244)],1,function(x) {fisher.test(rbind(x[1:2],c(x[3]-x[1],x[4]-x[2])))})
masterfile_eoc_ageOver60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults2$P_value_Fisher_0.005 = sapply(fisherresults_NM,function(x) round(x$p.value,12))
masterfile_eoc_ageOver60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults2$OR_0.005 = sapply(fisherresults_NM,function(x) round(x$estimate,4))
masterfile_eoc_ageOver60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults2$`95%CI_0.005` = sapply(fisherresults_NM,function(x) paste(round(x$conf.int[1:2],2),collapse="~"))
masterfile_eoc_ageOver60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults2$BH_0.005 = p.adjust(masterfile_eoc_ageOver60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults2$P_value_Fisher_0.005,method = "BH")
fisherresults2_NM <- apply(masterfile_eoc_ageOver60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults2[,c(221,232,243,245)],1,function(x) {fisher.test(rbind(x[1:2],c(x[3]-x[1],x[4]-x[2])))})
masterfile_eoc_ageOver60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults2$P_value_Fisher_0.005_NFE = sapply(fisherresults2_NM,function(x) round(x$p.value,12))
masterfile_eoc_ageOver60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults2$OR_0.005_NFE = sapply(fisherresults2_NM,function(x) round(x$estimate,4))
masterfile_eoc_ageOver60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults2$`95%CI_0.005_NFE` = sapply(fisherresults2_NM,function(x) paste(round(x$conf.int[1:2],2),collapse="~"))
masterfile_eoc_ageOver60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults2$BH_0.005_NFE = p.adjust(masterfile_eoc_ageOver60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults2$P_value_Fisher_0.005_NFE,method = "BH")
Calculate Fisher’s test values (volcano plot)
fisherresults_allGenes_volcano <- apply(volcano_ageUnder60_sampleAF0.01_allGenes[,c(3,5,4,7)],1,function(x) {fisher.test(rbind(x[1:2],c(abs(x[3]-x[1]),abs(x[4]-x[2]))))})
volcano_ageUnder60_sampleAF0.01_allGenes$P_value_Fisher_0.005 = sapply(fisherresults_allGenes_volcano,function(x) round(x$p.value,15))
volcano_ageUnder60_sampleAF0.01_allGenes$OR_0.005 = sapply(fisherresults_allGenes_volcano,function(x) round(x$estimate,15))
volcano_ageUnder60_sampleAF0.01_allGenes$`95%CI_0.005` = sapply(fisherresults_allGenes_volcano,function(x) paste(round(x$conf.int[1:2],2),collapse="~"))
volcano_ageUnder60_sampleAF0.01_allGenes$BH_0.005 = p.adjust(volcano_ageUnder60_sampleAF0.01_allGenes$P_value_Fisher_0.005,method = "BH")
fisherresults_NFE_volcano <- apply(volcano_ageUnder60_sampleAF0.01_allGenes[,c(3,6,4,8)],1,function(x) {fisher.test(rbind(x[1:2],c(abs(x[3]-x[1]),abs(x[4]-x[2]))))})
volcano_ageUnder60_sampleAF0.01_allGenes$P_value_Fisher_0.005_NFE = sapply(fisherresults_NFE_volcano,function(x) round(x$p.value,15))
volcano_ageUnder60_sampleAF0.01_allGenes$OR_0.005_NFE = sapply(fisherresults_NFE_volcano,function(x) round(x$estimate,15))
volcano_ageUnder60_sampleAF0.01_allGenes$`95%CI_0.005_NFE` = sapply(fisherresults_NFE_volcano,function(x) paste(round(x$conf.int[1:2],2),collapse="~"))
volcano_ageUnder60_sampleAF0.01_allGenes$BH_0.005_NFE = p.adjust(volcano_ageUnder60_sampleAF0.01_allGenes$P_value_Fisher_0.005_NFE,method = "BH")
fisherresults_biotype_allGenes_volcano <- apply(volcano_ageUnder60_sampleAF0.01_biotype_allGenes[,c(3,5,4,7)],1,function(x) {fisher.test(rbind(x[1:2],c(abs(x[3]-x[1]),abs(x[4]-x[2]))))})
volcano_ageUnder60_sampleAF0.01_biotype_allGenes$P_value_Fisher_0.005 = sapply(fisherresults_biotype_allGenes_volcano,function(x) round(x$p.value,15))
volcano_ageUnder60_sampleAF0.01_biotype_allGenes$OR_0.005 = sapply(fisherresults_biotype_allGenes_volcano,function(x) round(x$estimate,15))
volcano_ageUnder60_sampleAF0.01_biotype_allGenes$`95%CI_0.005` = sapply(fisherresults_biotype_allGenes_volcano,function(x) paste(round(x$conf.int[1:2],2),collapse="~"))
volcano_ageUnder60_sampleAF0.01_biotype_allGenes$BH_0.005 = p.adjust(volcano_ageUnder60_sampleAF0.01_biotype_allGenes$P_value_Fisher_0.005,method = "BH")
fisherresults_biotype_NFE_volcano <- apply(volcano_ageUnder60_sampleAF0.01_biotype_allGenes[,c(3,6,4,8)],1,function(x) {fisher.test(rbind(x[1:2],c(abs(x[3]-x[1]),abs(x[4]-x[2]))))})
volcano_ageUnder60_sampleAF0.01_biotype_allGenes$P_value_Fisher_0.005_NFE = sapply(fisherresults_biotype_NFE_volcano,function(x) round(x$p.value,15))
volcano_ageUnder60_sampleAF0.01_biotype_allGenes$OR_0.005_NFE = sapply(fisherresults_biotype_NFE_volcano,function(x) round(x$estimate,15))
volcano_ageUnder60_sampleAF0.01_biotype_allGenes$`95%CI_0.005_NFE` = sapply(fisherresults_biotype_NFE_volcano,function(x) paste(round(x$conf.int[1:2],2),collapse="~"))
volcano_ageUnder60_sampleAF0.01_biotype_allGenes$BH_0.005_NFE = p.adjust(volcano_ageUnder60_sampleAF0.01_biotype_allGenes$P_value_Fisher_0.005_NFE,method = "BH")
fisherresults_biotype2_allGenes_volcano <- apply(volcano_ageUnder60_sampleAF0.01_biotype2_allGenes[,c(3,5,4,7)],1,function(x) {fisher.test(rbind(x[1:2],c(abs(x[3]-x[1]),abs(x[4]-x[2]))))})
volcano_ageUnder60_sampleAF0.01_biotype2_allGenes$P_value_Fisher_0.005 = sapply(fisherresults_biotype2_allGenes_volcano,function(x) round(x$p.value,15))
volcano_ageUnder60_sampleAF0.01_biotype2_allGenes$OR_0.005 = sapply(fisherresults_biotype2_allGenes_volcano,function(x) round(x$estimate,15))
volcano_ageUnder60_sampleAF0.01_biotype2_allGenes$`95%CI_0.005` = sapply(fisherresults_biotype2_allGenes_volcano,function(x) paste(round(x$conf.int[1:2],2),collapse="~"))
volcano_ageUnder60_sampleAF0.01_biotype2_allGenes$BH_0.005 = p.adjust(volcano_ageUnder60_sampleAF0.01_biotype2_allGenes$P_value_Fisher_0.005,method = "BH")
fisherresults_biotype2_NFE_volcano <- apply(volcano_ageUnder60_sampleAF0.01_biotype2_allGenes[,c(3,6,4,8)],1,function(x) {fisher.test(rbind(x[1:2],c(abs(x[3]-x[1]),abs(x[4]-x[2]))))})
volcano_ageUnder60_sampleAF0.01_biotype2_allGenes$P_value_Fisher_0.005_NFE = sapply(fisherresults_biotype2_NFE_volcano,function(x) round(x$p.value,15))
volcano_ageUnder60_sampleAF0.01_biotype2_allGenes$OR_0.005_NFE = sapply(fisherresults_biotype2_NFE_volcano,function(x) round(x$estimate,15))
volcano_ageUnder60_sampleAF0.01_biotype2_allGenes$`95%CI_0.005_NFE` = sapply(fisherresults_biotype2_NFE_volcano,function(x) paste(round(x$conf.int[1:2],2),collapse="~"))
volcano_ageUnder60_sampleAF0.01_biotype2_allGenes$BH_0.005_NFE = p.adjust(volcano_ageUnder60_sampleAF0.01_biotype2_allGenes$P_value_Fisher_0.005_NFE,method = "BH")
fisherresults_allGenes_volcano <- apply(volcano_ageOver60_sampleAF0.01_allGenes[,c(3,5,4,7)],1,function(x) {fisher.test(rbind(x[1:2],c(abs(x[3]-x[1]),abs(x[4]-x[2]))))})
volcano_ageOver60_sampleAF0.01_allGenes$P_value_Fisher_0.005 = sapply(fisherresults_allGenes_volcano,function(x) round(x$p.value,15))
volcano_ageOver60_sampleAF0.01_allGenes$OR_0.005 = sapply(fisherresults_allGenes_volcano,function(x) round(x$estimate,15))
volcano_ageOver60_sampleAF0.01_allGenes$`95%CI_0.005` = sapply(fisherresults_allGenes_volcano,function(x) paste(round(x$conf.int[1:2],2),collapse="~"))
volcano_ageOver60_sampleAF0.01_allGenes$BH_0.005 = p.adjust(volcano_ageOver60_sampleAF0.01_allGenes$P_value_Fisher_0.005,method = "BH")
fisherresults_NFE_volcano <- apply(volcano_ageOver60_sampleAF0.01_allGenes[,c(3,6,4,8)],1,function(x) {fisher.test(rbind(x[1:2],c(abs(x[3]-x[1]),abs(x[4]-x[2]))))})
volcano_ageOver60_sampleAF0.01_allGenes$P_value_Fisher_0.005_NFE = sapply(fisherresults_NFE_volcano,function(x) round(x$p.value,15))
volcano_ageOver60_sampleAF0.01_allGenes$OR_0.005_NFE = sapply(fisherresults_NFE_volcano,function(x) round(x$estimate,15))
volcano_ageOver60_sampleAF0.01_allGenes$`95%CI_0.005_NFE` = sapply(fisherresults_NFE_volcano,function(x) paste(round(x$conf.int[1:2],2),collapse="~"))
volcano_ageOver60_sampleAF0.01_allGenes$BH_0.005_NFE = p.adjust(volcano_ageOver60_sampleAF0.01_allGenes$P_value_Fisher_0.005_NFE,method = "BH")
fisherresults_biotype_allGenes_volcano <- apply(volcano_ageOver60_sampleAF0.01_biotype_allGenes[,c(3,5,4,7)],1,function(x) {fisher.test(rbind(x[1:2],c(abs(x[3]-x[1]),abs(x[4]-x[2]))))})
volcano_ageOver60_sampleAF0.01_biotype_allGenes$P_value_Fisher_0.005 = sapply(fisherresults_biotype_allGenes_volcano,function(x) round(x$p.value,15))
volcano_ageOver60_sampleAF0.01_biotype_allGenes$OR_0.005 = sapply(fisherresults_biotype_allGenes_volcano,function(x) round(x$estimate,15))
volcano_ageOver60_sampleAF0.01_biotype_allGenes$`95%CI_0.005` = sapply(fisherresults_biotype_allGenes_volcano,function(x) paste(round(x$conf.int[1:2],2),collapse="~"))
volcano_ageOver60_sampleAF0.01_biotype_allGenes$BH_0.005 = p.adjust(volcano_ageOver60_sampleAF0.01_biotype_allGenes$P_value_Fisher_0.005,method = "BH")
fisherresults_biotype_NFE_volcano <- apply(volcano_ageOver60_sampleAF0.01_biotype_allGenes[,c(3,6,4,8)],1,function(x) {fisher.test(rbind(x[1:2],c(abs(x[3]-x[1]),abs(x[4]-x[2]))))})
volcano_ageOver60_sampleAF0.01_biotype_allGenes$P_value_Fisher_0.005_NFE = sapply(fisherresults_biotype_NFE_volcano,function(x) round(x$p.value,15))
volcano_ageOver60_sampleAF0.01_biotype_allGenes$OR_0.005_NFE = sapply(fisherresults_biotype_NFE_volcano,function(x) round(x$estimate,15))
volcano_ageOver60_sampleAF0.01_biotype_allGenes$`95%CI_0.005_NFE` = sapply(fisherresults_biotype_NFE_volcano,function(x) paste(round(x$conf.int[1:2],2),collapse="~"))
volcano_ageOver60_sampleAF0.01_biotype_allGenes$BH_0.005_NFE = p.adjust(volcano_ageOver60_sampleAF0.01_biotype_allGenes$P_value_Fisher_0.005_NFE,method = "BH")
fisherresults_biotype2_allGenes_volcano <- apply(volcano_ageOver60_sampleAF0.01_biotype2_allGenes[,c(3,5,4,7)],1,function(x) {fisher.test(rbind(x[1:2],c(abs(x[3]-x[1]),abs(x[4]-x[2]))))})
volcano_ageOver60_sampleAF0.01_biotype2_allGenes$P_value_Fisher_0.005 = sapply(fisherresults_biotype2_allGenes_volcano,function(x) round(x$p.value,15))
volcano_ageOver60_sampleAF0.01_biotype2_allGenes$OR_0.005 = sapply(fisherresults_biotype2_allGenes_volcano,function(x) round(x$estimate,15))
volcano_ageOver60_sampleAF0.01_biotype2_allGenes$`95%CI_0.005` = sapply(fisherresults_biotype2_allGenes_volcano,function(x) paste(round(x$conf.int[1:2],2),collapse="~"))
volcano_ageOver60_sampleAF0.01_biotype2_allGenes$BH_0.005 = p.adjust(volcano_ageOver60_sampleAF0.01_biotype2_allGenes$P_value_Fisher_0.005,method = "BH")
fisherresults_biotype2_NFE_volcano <- apply(volcano_ageOver60_sampleAF0.01_biotype2_allGenes[,c(3,6,4,8)],1,function(x) {fisher.test(rbind(x[1:2],c(abs(x[3]-x[1]),abs(x[4]-x[2]))))})
volcano_ageOver60_sampleAF0.01_biotype2_allGenes$P_value_Fisher_0.005_NFE = sapply(fisherresults_biotype2_NFE_volcano,function(x) round(x$p.value,15))
volcano_ageOver60_sampleAF0.01_biotype2_allGenes$OR_0.005_NFE = sapply(fisherresults_biotype2_NFE_volcano,function(x) round(x$estimate,15))
volcano_ageOver60_sampleAF0.01_biotype2_allGenes$`95%CI_0.005_NFE` = sapply(fisherresults_biotype2_NFE_volcano,function(x) paste(round(x$conf.int[1:2],2),collapse="~"))
volcano_ageOver60_sampleAF0.01_biotype2_allGenes$BH_0.005_NFE = p.adjust(volcano_ageOver60_sampleAF0.01_biotype2_allGenes$P_value_Fisher_0.005_NFE,method = "BH")
Identify variants with filtering AF > maximum credible population AF in GnomAD for hereditary EOC (0.000181)
masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults3 <- mutate(masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults2, FilteringAF_95_Exceeds_MaxCredPopAF=((GnomAD_v2.1_non_cancer_Filtering_AF_95)>0.000181)) %>%
mutate(FilteringAF_95_NFE_Exceeds_MaxCredPopAF=((GnomAD_v2.1_non_cancer_Filtering_AF_95_nfe)>0.000181))
masterfile_eoc_ageUnder60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults3 <- mutate(masterfile_eoc_ageUnder60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults2, FilteringAF_95_Exceeds_MaxCredPopAF=((GnomAD_v2.1_non_cancer_Filtering_AF_95)>0.000181)) %>%
mutate(FilteringAF_95_NFE_Exceeds_MaxCredPopAF=((GnomAD_v2.1_non_cancer_Filtering_AF_95_nfe)>0.000181))
masterfile_eoc_ageOver60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults3 <- mutate(masterfile_eoc_ageOver60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults2, FilteringAF_95_Exceeds_MaxCredPopAF=((GnomAD_v2.1_non_cancer_Filtering_AF_95)>0.000181)) %>%
mutate(FilteringAF_95_NFE_Exceeds_MaxCredPopAF=((GnomAD_v2.1_non_cancer_Filtering_AF_95_nfe)>0.000181))
masterfile_eoc_ageOver60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults3 <- mutate(masterfile_eoc_ageOver60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults2, FilteringAF_95_Exceeds_MaxCredPopAF=((GnomAD_v2.1_non_cancer_Filtering_AF_95)>0.000181)) %>%
mutate(FilteringAF_95_NFE_Exceeds_MaxCredPopAF=((GnomAD_v2.1_non_cancer_Filtering_AF_95_nfe)>0.000181))
Identify variants that PASS/FAIL the LOFTEE 50bp rule
masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults4 <- mutate(masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults3,LoF_50_BP_RULE = ifelse(grepl("50_BP_RULE:PASS", LoF_info), TRUE, ifelse(grepl("50_BP_RULE:FAIL", LoF_info), FALSE, NA)))
masterfile_eoc_ageUnder60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults4 <- mutate(masterfile_eoc_ageUnder60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults3,LoF_50_BP_RULE = ifelse(grepl("50_BP_RULE:PASS", LoF_info), TRUE, ifelse(grepl("50_BP_RULE:FAIL", LoF_info), FALSE, NA)))
masterfile_eoc_ageOver60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults4 <- mutate(masterfile_eoc_ageOver60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults3,LoF_50_BP_RULE = ifelse(grepl("50_BP_RULE:PASS", LoF_info), TRUE, ifelse(grepl("50_BP_RULE:FAIL", LoF_info), FALSE, NA)))
masterfile_eoc_ageOver60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults4 <- mutate(masterfile_eoc_ageOver60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults3,LoF_50_BP_RULE = ifelse(grepl("50_BP_RULE:PASS", LoF_info), TRUE, ifelse(grepl("50_BP_RULE:FAIL", LoF_info), FALSE, NA)))
Import NMD depleted gene list and annotate variants accordingly
NMD_depleted_gene_list <- read.csv("NMD_depleted_gene_list.csv", stringsAsFactors=FALSE) %>%
dplyr::rename("SYMBOL" = gene) %>%
dplyr::rename("Feature" = txnames) %>%
dplyr::rename("NMD_predictor_rank" = min.rank)
masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults5 <- left_join(masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults4, NMD_depleted_gene_list[,c(2:3)],by="Feature",copy=FALSE)
masterfile_eoc_ageUnder60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults5 <- left_join(masterfile_eoc_ageUnder60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults4, NMD_depleted_gene_list[,c(1:3)],by="SYMBOL",copy=FALSE)
masterfile_eoc_ageOver60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults5 <- left_join(masterfile_eoc_ageOver60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults4, NMD_depleted_gene_list[,c(2:3)],by="Feature",copy=FALSE)
masterfile_eoc_ageOver60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults5 <- left_join(masterfile_eoc_ageOver60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults4, NMD_depleted_gene_list[,c(1:3)],by="SYMBOL",copy=FALSE)
Remove redundant objects and output data
rm(list=(ls(pattern="^genes")))
rm(list=(ls(pattern="^variants")))
rm(list=(ls(pattern="^fisherresults")))
write_excel_csv(masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults5,path="masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01.csv",na=".",append=FALSE,col_names=TRUE)
select(masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults5,SYMBOL,Gene,P_value_Fisher_0.005_NFE) %>%
arrange(P_value_Fisher_0.005_NFE) %>%
unique() %>%
write_tsv(path="FHx_HIGH_ENSTcanonical_BH_p_values.tsv")
write_excel_csv(masterfile_eoc_ageUnder60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults5,path="masterfile_eoc_ageUnder60_goodQ2_HIGH_NMcanonical_sampleAF0.01.csv",na=".",append=FALSE,col_names=TRUE)
select(masterfile_eoc_ageUnder60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults5,SYMBOL,Gene,P_value_Fisher_0.005_NFE) %>%
arrange(P_value_Fisher_0.005_NFE) %>%
unique() %>%
write_tsv(path="FHx_HIGH_NMcanonical_BH_p_values.tsv")
write_excel_csv(masterfile_eoc_ageOver60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults5,path="masterfile_eoc_ageOver60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01.csv",na=".",append=FALSE,col_names=TRUE)
select(masterfile_eoc_ageOver60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults5,SYMBOL,Gene,P_value_Fisher_0.005_NFE) %>%
arrange(P_value_Fisher_0.005_NFE) %>%
unique() %>%
write_tsv(path="FHx_HIGH_ENSTcanonical_BH_p_values.tsv")
write_excel_csv(masterfile_eoc_ageOver60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults5,path="masterfile_eoc_ageOver60_goodQ2_HIGH_NMcanonical_sampleAF0.01.csv",na=".",append=FALSE,col_names=TRUE)
select(masterfile_eoc_ageOver60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults5,SYMBOL,Gene,P_value_Fisher_0.005_NFE) %>%
arrange(P_value_Fisher_0.005_NFE) %>%
unique() %>%
write_tsv(path="FHx_HIGH_NMcanonical_BH_p_values.tsv")
Calculate total LoF variants in sample vs total LoF variants in GnomAD non-cancer NFE and use for chi-squared test
oddsratio <- function (a, b = NULL, c = NULL, d = NULL, conf.level = 0.95,
p.calc.by.independence = TRUE)
{
if (is.matrix(a)) {
if ((dim(a)[1] != 2L) | (dim(a)[2] != 2L)) {
stop("Input matrix must be a 2x2 table.")
}
.a <- a[1, 1]
.b <- a[1, 2]
.c <- a[2, 1]
.d <- a[2, 2]
.data.name <- deparse(substitute(a))
}
else {
.a <- a
.b <- b
.c <- c
.d <- d
.data.name <- paste(deparse(substitute(a)), deparse(substitute(b)),
deparse(substitute(c)), deparse(substitute(d)))
}
.MAT <- matrix(c(.a, .b, M1 <- .a + .b, .c, .d, M0 <- .c +
.d, N1 <- .a + .c, N0 <- .b + .d, Total <- .a + .b +
.c + .d), 3, 3)
colnames(.MAT) <- c("Sample", "GnomAD", "Total") #("Disease", "Nondisease", "Total")
rownames(.MAT) <- c("LoF", "No LoF", "Total") #("Exposed", "Nonexposed", "Total")
class(.MAT) <- "table"
print(.MAT)
ESTIMATE <- (.a /.b)/(.c/.d)
norm.pp <- qnorm(1 - (1 - conf.level)/2)
if (p.calc.by.independence) {
p.v <- 2 * (1 - pnorm(abs((.a - N1 * M1/Total)/sqrt(N1 *
N0 * M1 * M0/Total/Total/(Total - 1)))))
}
else {
p.v <- 2 * (1 - pnorm(log(ifelse(ESTIMATE > 1, ESTIMATE,
1/ESTIMATE))/sqrt(1/.a + 1/.b + 1/.c + 1/.d)))
}
ORL <- ESTIMATE * exp(-norm.pp * sqrt(1/.a + 1/.b + 1/.c +
1/.d))
ORU <- ESTIMATE * exp(norm.pp * sqrt(1/.a + 1/.b + 1/.c +
1/.d)) %>% signif(digits=7)
CINT <- paste(signif(ORL,digits = 7),signif(ORU,digits = 7),sep="~")
attr(CINT, "conf.level") <- conf.level
RVAL <- list(p.value = p.v, conf.int = CINT, estimate = ESTIMATE,
method = "Odds ratio estimate and its significance probability",
data.name = .data.name)
class(RVAL) <- "htest"
return(RVAL)
}
a <- sum(volcano_ageUnder60_sampleAF0.01_allGenes$Total_Gene_Count) %>% as.numeric()
b <- Total_Sample_Alleles_ageUnder60*(nrow(allGenes_AgilentSSv6_list)) %>% as.numeric()
b1 <- b-a %>% as.numeric()
c <- sum(volcano_ageUnder60_sampleAF0.01_allGenes$FILTER_RF_LOF_HIGHIMPACT_AC_0.005) %>% as.numeric()
d <- (max(volcano_ageUnder60_sampleAF0.01_allGenes$MAX_AN))*nrow(allGenes_AgilentSSv6_list) %>% as.numeric()
d1 <- d-c %>% as.numeric()
e <- sum(volcano_ageUnder60_sampleAF0.01_allGenes$FILTER_RF_LOF_HIGHIMPACT_AC_0.005_NFE) %>% as.numeric()
f <- (max(volcano_ageUnder60_sampleAF0.01_allGenes$MAX_AN_NFE))*nrow(allGenes_AgilentSSv6_list) %>% as.numeric()
f1 <- f-e %>% as.numeric()
g <- sum(volcano_ageUnder60_sampleAF0.01_biotype_allGenes$Total_Gene_Count) %>% as.numeric()
h <- Total_Sample_Alleles_ageUnder60*(nrow(allGenes_AgilentSSv6_list_protein_coding_only)) %>% as.numeric()
h1 <- h-g %>% as.numeric()
i <- sum(volcano_ageUnder60_sampleAF0.01_biotype_allGenes$FILTER_RF_LOF_HIGHIMPACT_AC_0.005) %>% as.numeric()
j <- (max(volcano_ageUnder60_sampleAF0.01_biotype_allGenes$MAX_AN))*nrow(allGenes_AgilentSSv6_list_protein_coding_only) %>% as.numeric()
j1 <- j-i %>% as.numeric()
k <- sum(volcano_ageUnder60_sampleAF0.01_biotype_allGenes$FILTER_RF_LOF_HIGHIMPACT_AC_0.005_NFE) %>% as.numeric()
l <- (max(volcano_ageUnder60_sampleAF0.01_biotype_allGenes$MAX_AN_NFE))*nrow(allGenes_AgilentSSv6_list_protein_coding_only) %>% as.numeric()
l1 <- l-k %>% as.numeric()
chiX2_0.005_ageUnder60 <- matrix(c(a,b1,c,d1),nrow=2,byrow=TRUE)
chiX2_0.005_NFE_ageUnder60 <- matrix(c(a,b1,e,f1),nrow=2,byrow=TRUE)
chiX2_0.005_biotype_ageUnder60 <- matrix(c(g,h1,i,j1),nrow=2,byrow=TRUE)
chiX2_0.005_NFE_biotype_ageUnder60 <- matrix(c(g,h1,k,l1),nrow=2,byrow=TRUE)
m <- sum(volcano_ageOver60_sampleAF0.01_allGenes$Total_Gene_Count) %>% as.numeric()
n <- Total_Sample_Alleles_ageOver60*(nrow(allGenes_AgilentSSv6_list)) %>% as.numeric()
n1 <- n-m %>% as.numeric()
o <- sum(volcano_ageOver60_sampleAF0.01_allGenes$FILTER_RF_LOF_HIGHIMPACT_AC_0.005) %>% as.numeric()
p <- (max(volcano_ageOver60_sampleAF0.01_allGenes$MAX_AN))*nrow(allGenes_AgilentSSv6_list) %>% as.numeric()
p1 <- p-o %>% as.numeric()
q <- sum(volcano_ageOver60_sampleAF0.01_allGenes$FILTER_RF_LOF_HIGHIMPACT_AC_0.005_NFE) %>% as.numeric()
r <- (max(volcano_ageOver60_sampleAF0.01_allGenes$MAX_AN_NFE))*nrow(allGenes_AgilentSSv6_list) %>% as.numeric()
r1 <- r-q %>% as.numeric()
s <- sum(volcano_ageOver60_sampleAF0.01_biotype_allGenes$Total_Gene_Count) %>% as.numeric()
t <- Total_Sample_Alleles_ageOver60*(nrow(allGenes_AgilentSSv6_list_protein_coding_only)) %>% as.numeric()
t1 <- t-s %>% as.numeric()
u <- sum(volcano_ageOver60_sampleAF0.01_biotype_allGenes$FILTER_RF_LOF_HIGHIMPACT_AC_0.005) %>% as.numeric()
v <- (max(volcano_ageOver60_sampleAF0.01_biotype_allGenes$MAX_AN))*nrow(allGenes_AgilentSSv6_list_protein_coding_only) %>% as.numeric()
v1 <- v-u %>% as.numeric()
w <- sum(volcano_ageOver60_sampleAF0.01_biotype_allGenes$FILTER_RF_LOF_HIGHIMPACT_AC_0.005_NFE) %>% as.numeric()
x <- (max(volcano_ageOver60_sampleAF0.01_biotype_allGenes$MAX_AN_NFE))*nrow(allGenes_AgilentSSv6_list_protein_coding_only) %>% as.numeric()
x1 <- x-w %>% as.numeric()
chiX2_0.005_ageOver60 <- matrix(c(m,n1,o,p1),nrow=2,byrow=TRUE)
chiX2_0.005_NFE_ageOver60 <- matrix(c(m,n1,q,r1),nrow=2,byrow=TRUE)
chiX2_0.005_biotype_ageOver60 <- matrix(c(s,t1,u,v1),nrow=2,byrow=TRUE)
chiX2_0.005_NFE_biotype_ageOver60 <- matrix(c(s,t1,w,x1),nrow=2,byrow=TRUE)
chiX2_0.005_NFE_ageUnder60_ageOver60 <- matrix(c(chiX2_0.005_NFE_ageUnder60[1,],chiX2_0.005_NFE_ageOver60[1,]),nrow=2,byrow=TRUE)
chiX2_0.005_NFE_biotype_ageUnder60_ageOver60 <- matrix(c(chiX2_0.005_NFE_biotype_ageUnder60[1,],chiX2_0.005_NFE_biotype_ageOver60[1,]),nrow=2,byrow=TRUE)
setwd("~/OneDrive - The University of Melbourne/R data")
sink(file="masterfile_eoc_LOF_volcano_chiX2_results.txt",append=TRUE)
chisq.test(chiX2_0.005_ageUnder60,correct=FALSE)
oddsratio(chiX2_0.005_ageUnder60)
chisq.test(chiX2_0.005_NFE_ageUnder60,correct=FALSE)
oddsratio(chiX2_0.005_NFE_ageUnder60)
chisq.test(chiX2_0.005_biotype_ageUnder60,correct=FALSE)
oddsratio(chiX2_0.005_biotype_ageUnder60)
chisq.test(chiX2_0.005_NFE_biotype_ageUnder60,correct=FALSE)
oddsratio(chiX2_0.005_NFE_biotype_ageUnder60)
chisq.test(chiX2_0.005_ageOver60,correct=FALSE)
oddsratio(chiX2_0.005_ageOver60)
chisq.test(chiX2_0.005_NFE_ageOver60,correct=FALSE)
oddsratio(chiX2_0.005_NFE_ageOver60)
chisq.test(chiX2_0.005_biotype_ageOver60,correct=FALSE)
oddsratio(chiX2_0.005_biotype_ageOver60)
chisq.test(chiX2_0.005_NFE_biotype_ageOver60,correct=FALSE)
oddsratio(chiX2_0.005_NFE_biotype_ageOver60)
chisq.test(chiX2_0.005_NFE_ageUnder60_ageOver60,correct=FALSE)
chisq.test(chiX2_0.005_NFE_biotype_ageUnder60_ageOver60,correct=FALSE)
sink()
Remove variants with non-protein-coding biotypes
masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_biotype <- filter(masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults5,BIOTYPE%in%c("protein_coding"))
masterfile_eoc_ageUnder60_goodQ2_HIGH_NMcanonical_sampleAF0.01_biotype <- filter(masterfile_eoc_ageUnder60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults5,BIOTYPE%in%c("protein_coding"))
masterfile_eoc_ageOver60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_biotype <- filter(masterfile_eoc_ageOver60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults5,BIOTYPE%in%c("protein_coding"))
masterfile_eoc_ageOver60_goodQ2_HIGH_NMcanonical_sampleAF0.01_biotype <- filter(masterfile_eoc_ageOver60_goodQ2_HIGH_NMcanonical_sampleAF0.01_withGnomADstats_ratios_fisherresults5,BIOTYPE%in%c("protein_coding"))
Calculate number of retained protein-coding LoF variants per individual in under 60/over 60 cohorts, and output results.
masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_biotype_variantsPerPerson <- select(masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_biotype,Sample,CHROM,POS,REF,ALT,Sample.GT,SYMBOL,Gene,Feature,HGVSc)
samples_ageUnder60 <- masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_biotype_variantsPerPerson[,1] %>% unique()
samples_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_biotype_variantsPerPerson <- data.frame(Sample=factor(),No_of_Variants=double())
for(sample in samples_ageUnder60){
sample_data <- filter(masterfile_eoc_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_biotype_variantsPerPerson,Sample%in%c(sample))
sample_variants <- variant_counts_AFs(sample_data,Total_Sample_Alleles_ageUnder60)
no_of_variants <- sum(sample_variants$Total_Allele_Count)
samples_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_biotype_variantsPerPerson <- add_row(samples_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_biotype_variantsPerPerson,Sample=sample,No_of_Variants=no_of_variants)
}
write_tsv(samples_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_biotype_variantsPerPerson,path="samples_ageUnder60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_biotype_variantsPerPerson.tsv")
masterfile_eoc_ageOver60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_biotype_variantsPerPerson <- select(masterfile_eoc_ageOver60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_biotype,Sample,CHROM,POS,REF,ALT,Sample.GT,SYMBOL,Gene,Feature,HGVSc)
samples_ageOver60 <- masterfile_eoc_ageOver60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_biotype_variantsPerPerson[,1] %>% unique()
samples_ageOver60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_biotype_variantsPerPerson <- data.frame(Sample=factor(),No_of_Variants=double())
for(sample in samples_ageOver60){
sample_data <- filter(masterfile_eoc_ageOver60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_biotype_variantsPerPerson,Sample%in%c(sample))
sample_variants <- variant_counts_AFs(sample_data,Total_Sample_Alleles_ageOver60)
no_of_variants <- sum(sample_variants$Total_Allele_Count)
samples_ageOver60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_biotype_variantsPerPerson <- add_row(samples_ageOver60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_biotype_variantsPerPerson,Sample=sample,No_of_Variants=no_of_variants)
}
write_tsv(samples_ageOver60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_biotype_variantsPerPerson,path="samples_ageOver60_goodQ2_HIGH_ENSTcanonical_sampleAF0.01_biotype_variantsPerPerson.tsv")
Output data for log p-value volcano plots
volcano_ageUnder60_sampleAF0.01_allGenes2 <- mutate(volcano_ageUnder60_sampleAF0.01_allGenes,"Log10_P-value_Fisher_0.05_NFE" = log10(P_value_Fisher_0.005_NFE)) %>%
arrange(desc(OR_0.005_NFE)) %>%
mutate("Plotted_Log10_P-value_Fisher_0.05_NFE"=
if_else (OR_0.005_NFE>=1, `Log10_P-value_Fisher_0.05_NFE`*-1, `Log10_P-value_Fisher_0.05_NFE`, missing=NULL)) %>%
arrange(desc(`Plotted_Log10_P-value_Fisher_0.05_NFE`),desc(OR_0.005_NFE)) %>%
write_excel_csv(path="volcano_ageUnder60_sampleAF0.01_allGenes_v6.csv",na=".",append=FALSE,col_names=TRUE)
volcano_ageUnder60_sampleAF0.01_biotype_allGenes2 <- mutate(volcano_ageUnder60_sampleAF0.01_biotype_allGenes,"Log10_P-value_Fisher_0.05_NFE" = log10(P_value_Fisher_0.005_NFE)) %>%
arrange(desc(OR_0.005_NFE)) %>%
mutate("Plotted_Log10_P-value_Fisher_0.05_NFE"=
if_else (OR_0.005_NFE>=1, `Log10_P-value_Fisher_0.05_NFE`*-1, `Log10_P-value_Fisher_0.05_NFE`, missing=NULL)) %>%
arrange(desc(`Plotted_Log10_P-value_Fisher_0.05_NFE`),desc(OR_0.005_NFE)) %>%
write_excel_csv(path="volcano_ageUnder60_sampleAF0.01_biotype_allGenes_v6.csv",na=".",append=FALSE,col_names=TRUE)
volcano_ageUnder60_sampleAF0.01_biotype2_allGenes2 <- mutate(volcano_ageUnder60_sampleAF0.01_biotype2_allGenes,"Log10_P-value_Fisher_0.05_NFE" = log10(P_value_Fisher_0.005_NFE)) %>%
arrange(desc(OR_0.005_NFE)) %>%
mutate("Plotted_Log10_P-value_Fisher_0.05_NFE"=
if_else (OR_0.005_NFE>=1, `Log10_P-value_Fisher_0.05_NFE`*-1, `Log10_P-value_Fisher_0.05_NFE`, missing=NULL)) %>%
arrange(desc(`Plotted_Log10_P-value_Fisher_0.05_NFE`),desc(OR_0.005_NFE)) %>%
write_excel_csv(path="volcano_ageUnder60_sampleAF0.01_biotype2_allGenes_v6.csv",na=".",append=FALSE,col_names=TRUE)
volcano_ageOver60_sampleAF0.01_allGenes2 <- mutate(volcano_ageOver60_sampleAF0.01_allGenes,"Log10_P-value_Fisher_0.05_NFE" = log10(P_value_Fisher_0.005_NFE)) %>%
arrange(desc(OR_0.005_NFE)) %>%
mutate("Plotted_Log10_P-value_Fisher_0.05_NFE"=
if_else (OR_0.005_NFE>=1, `Log10_P-value_Fisher_0.05_NFE`*-1, `Log10_P-value_Fisher_0.05_NFE`, missing=NULL)) %>%
arrange(desc(`Plotted_Log10_P-value_Fisher_0.05_NFE`),desc(OR_0.005_NFE)) %>%
write_excel_csv(path="volcano_ageOver60_sampleAF0.01_allGenes_v6.csv",na=".",append=FALSE,col_names=TRUE)
volcano_ageOver60_sampleAF0.01_biotype_allGenes2 <- mutate(volcano_ageOver60_sampleAF0.01_biotype_allGenes,"Log10_P-value_Fisher_0.05_NFE" = log10(P_value_Fisher_0.005_NFE)) %>%
arrange(desc(OR_0.005_NFE)) %>%
mutate("Plotted_Log10_P-value_Fisher_0.05_NFE"=
if_else (OR_0.005_NFE>=1, `Log10_P-value_Fisher_0.05_NFE`*-1, `Log10_P-value_Fisher_0.05_NFE`, missing=NULL)) %>%
arrange(desc(`Plotted_Log10_P-value_Fisher_0.05_NFE`),desc(OR_0.005_NFE)) %>%
write_excel_csv(path="volcano_ageOver60_sampleAF0.01_biotype_allGenes_v6.csv",na=".",append=FALSE,col_names=TRUE)
volcano_ageOver60_sampleAF0.01_biotype2_allGenes2 <- mutate(volcano_ageOver60_sampleAF0.01_biotype2_allGenes,"Log10_P-value_Fisher_0.05_NFE" = log10(P_value_Fisher_0.005_NFE)) %>%
arrange(desc(OR_0.005_NFE)) %>%
mutate("Plotted_Log10_P-value_Fisher_0.05_NFE"=
if_else (OR_0.005_NFE>=1, `Log10_P-value_Fisher_0.05_NFE`*-1, `Log10_P-value_Fisher_0.05_NFE`, missing=NULL)) %>%
arrange(desc(`Plotted_Log10_P-value_Fisher_0.05_NFE`),desc(OR_0.005_NFE)) %>%
write_excel_csv(path="volcano_ageOver60_sampleAF0.01_biotype2_allGenes_v6.csv",na=".",append=FALSE,col_names=TRUE)
LS0tCnRpdGxlOiAiVGhlc2lzIExvRiBWYXJpYW50cyBGaWx0ZXJpbmcgYW5kIEFuYWx5c2lzIGJ5IEFnZSBTY3JpcHQiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCkFMTCBJTVBPUlRFRCBGSUxFUyBNVVNUIEJFIElOIFRIRSBTQU1FIERJUkVDVE9SWSBBUyBUSElTIFNDUklQVAoKTG9hZCB0aWR5dmVyc2UgcGFja2FnZQpgYGB7cn0KbGlicmFyeSgidGlkeXZlcnNlIikKYGBgCgpJbXBvcnQgcmF3IHZjZiBkYXRhIGZyb20gIm1hc3RlcmZpbGUiIGFuZCBleGNsdWRlIHZhcmlhbnRzIHdpdGggR25vbUFEIG5vbi1jYW5jZXIgQUYgPiAwLjAwNQpgYGB7cn0KbWFzdGVyZmlsZSA8LSByZWFkLmRlbGltKCJtYXN0ZXJmaWxlLnRzdiIsIGhlYWRlcj1UUlVFLCByb3cubmFtZXM9TlVMTCwgbmEuc3RyaW5ncyA9ICIuIiwgc3RyaW5nc0FzRmFjdG9ycz1GQUxTRSkgJT4lIAogIHJlbmFtZSgiU2FtcGxlIj0iWC5TYW1wbGUiKSAlPiUgCiAgZmlsdGVyKEdub21BRF92Mi4xX25vbl9jYW5jZXJfQUY8PTAuMDA1KQpgYGAKCkV4Y2x1ZGUgbm9uLWVwaXRoZWxpYWwsIHV0ZXJpbmUtb25seSBhbmQgQlJDQSArdmUgc2FtcGxlcwpgYGB7cn0KVmlQX0NvbXBsZXRlX0NvaG9ydCA8LSByZWFkLmRlbGltKCJWaVBfTG9GX0NvbXBsZXRlX0NvaG9ydC50eHQiLCBzdHJpbmdzQXNGYWN0b3JzPUZBTFNFKQpWaVBfQ29tcGxldGVfQ29ob3J0X2xpc3QgPC0gVmlQX0NvbXBsZXRlX0NvaG9ydFssMV0KCm1hc3RlcmZpbGVfZW9jIDwtIGZpbHRlcihtYXN0ZXJmaWxlLFNhbXBsZSVpbiVjKFZpUF9Db21wbGV0ZV9Db2hvcnRfbGlzdCkpCmBgYAoKQXBwZW5kIHBhdGllbnQgcGF0aCBkYXRhCmBgYHtyfQpWaVBfT3ZDYV9QYXRoX0RhdGEgPC0gcmVhZC5kZWxpbSgiVmlQX092Q2FfUGF0aF9EYXRhLnR4dCIsIGhlYWRlcj1UUlVFLCByb3cubmFtZXM9TlVMTCwgc3RyaW5nc0FzRmFjdG9ycz1GQUxTRSkgJT4lIAogIGRwbHlyOjpyZW5hbWUoIlNhbXBsZSI9RXhvbWUuSUQpCm1hc3RlcmZpbGVfZW9jX3dpdGhQYXRoIDwtIGxlZnRfam9pbihtYXN0ZXJmaWxlX2VvYyxWaVBfT3ZDYV9QYXRoX0RhdGEsYnk9IlNhbXBsZSIsY29weT1GQUxTRSkKcm0oVmlQX092Q2FfUGF0aF9EYXRhKQpgYGAKCkV4Y2x1ZGUgbG93LWdyYWRlIHR1bW91ciBzYW1wbGVzCmBgYHtyfQptYXN0ZXJmaWxlX2VvYzIgPC0gZmlsdGVyKG1hc3RlcmZpbGVfZW9jX3dpdGhQYXRoLCghSGlzdG9wYXRoLlR5cGUlaW4lYygiQm9yZGVybGluZSB0dW1vdXIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk11Y2lub3VzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDbGVhciBjZWxsIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJMb3ctZ3JhZGUgc2Vyb3VzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJMb3ctZ3JhZGUgZW5kb21ldHJpb2lkIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTZXJvdXMgKD9sb3ctZ3JhZGUvYm9yZGVybGluZSkiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1peGVkIE11bGxlcmlhbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTWl4ZWQgRUFPQyIpKSkKYGBgCgpFeGNsdWRlIHNhbXBsZXMgZnJvbSB3b21lbiBhZ2VkIGJlbG93L2Fib3ZlIDYwIHllYXJzCmBgYHtyfQptYXN0ZXJmaWxlX2VvY19hZ2VVbmRlcjYwIDwtIGZpbHRlcihtYXN0ZXJmaWxlX2VvYzIsUmVwb3J0ZWQuQWdlLkR4PDYwKQoKbWFzdGVyZmlsZV9lb2NfYWdlT3ZlcjYwIDwtIGZpbHRlcihtYXN0ZXJmaWxlX2VvYzIsUmVwb3J0ZWQuQWdlLkR4Pj02MCkKYGBgCgpFeGNsdWRlIGxvdy1xdWFsaXR5IHZhcmlhbnRzIGFuZCBHbm9tQUQgUkYvSW5icmVlZGluZ0NvZWZmLWZsYWdnZWQgdmFyaWFudHMKYGBge3J9Cm1hc3RlcmZpbGVfZW9jX2FnZVVuZGVyNjBfZ29vZFEgPC0gZmlsdGVyKG1hc3RlcmZpbGVfZW9jX2FnZVVuZGVyNjAsIChRVUFMPj0zMCkmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChJZGVudGlmaWVkIT0iRmlsdGVyZWRJbkFsbCIpJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoU2FtcGxlLlBNQ0RQPj0xMCkmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChTYW1wbGUuUE1DRlJFUT49MC4yNSkpICU+JSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKCghc3RyX2RldGVjdChHbm9tQURfdjIuMV9GSUxURVJfZXhvbWUsIkluYnJlZWRpbmdDb2VmZiIpJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIXN0cl9kZXRlY3QoR25vbUFEX3YyLjFfRklMVEVSX2V4b21lLCJSRiIpKXwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXMubmEoR25vbUFEX3YyLjFfRklMVEVSX2V4b21lKSkgJT4lIAogIGZpbHRlcigoIXN0cl9kZXRlY3QoR25vbUFEX3YyLjFfRklMVEVSX2dlbm9tZSwiSW5icmVlZGluZ0NvZWZmIikmCiAgICAgICAgICAgICFzdHJfZGV0ZWN0KEdub21BRF92Mi4xX0ZJTFRFUl9nZW5vbWUsIlJGIikpfAogICAgICAgICAgIGlzLm5hKEdub21BRF92Mi4xX0ZJTFRFUl9nZW5vbWUpKQoKbWFzdGVyZmlsZV9lb2NfYWdlT3ZlcjYwX2dvb2RRIDwtIGZpbHRlcihtYXN0ZXJmaWxlX2VvY19hZ2VPdmVyNjAsIChRVUFMPj0zMCkmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChJZGVudGlmaWVkIT0iRmlsdGVyZWRJbkFsbCIpJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoU2FtcGxlLlBNQ0RQPj0xMCkmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChTYW1wbGUuUE1DRlJFUT49MC4yNSkpICU+JSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKCghc3RyX2RldGVjdChHbm9tQURfdjIuMV9GSUxURVJfZXhvbWUsIkluYnJlZWRpbmdDb2VmZiIpJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIXN0cl9kZXRlY3QoR25vbUFEX3YyLjFfRklMVEVSX2V4b21lLCJSRiIpKXwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXMubmEoR25vbUFEX3YyLjFfRklMVEVSX2V4b21lKSkgJT4lIAogIGZpbHRlcigoIXN0cl9kZXRlY3QoR25vbUFEX3YyLjFfRklMVEVSX2dlbm9tZSwiSW5icmVlZGluZ0NvZWZmIikmCiAgICAgICAgICAgICFzdHJfZGV0ZWN0KEdub21BRF92Mi4xX0ZJTFRFUl9nZW5vbWUsIlJGIikpfAogICAgICAgICAgIGlzLm5hKEdub21BRF92Mi4xX0ZJTFRFUl9nZW5vbWUpKQpgYGAKCkV4Y2x1ZGUgb3RoZXIgbXV0YXRpb24gK3ZlIHNhbXBsZXMgKE1MSDEvTVNIMi9NU0g2L1BNUzIsIFRQNTMsIFJBRDUxQy9ELCBCUklQMSkKYGBge3J9ClZpUF9EaXNjb3ZlcnlfQ29ob3J0IDwtIHJlYWQuZGVsaW0oIlZpUF9Mb0ZfRGlzY292ZXJ5X0NvaG9ydC50eHQiLCBzdHJpbmdzQXNGYWN0b3JzPUZBTFNFKQpWaVBfRGlzY292ZXJ5X0NvaG9ydF9saXN0IDwtIFZpUF9EaXNjb3ZlcnlfQ29ob3J0WywxXQoKbWFzdGVyZmlsZV9lb2NfYWdlVW5kZXI2MF9nb29kUTIgPC0gZmlsdGVyKG1hc3RlcmZpbGVfZW9jX2FnZVVuZGVyNjBfZ29vZFEsU2FtcGxlJWluJWMoVmlQX0Rpc2NvdmVyeV9Db2hvcnRfbGlzdCkpClRvdGFsX1NhbXBsZV9BbGxlbGVzX2FnZVVuZGVyNjAgPC0gKG5fZGlzdGluY3QobWFzdGVyZmlsZV9lb2NfYWdlVW5kZXI2MF9nb29kUTIkU2FtcGxlKSoyKQoKbWFzdGVyZmlsZV9lb2NfYWdlT3ZlcjYwX2dvb2RRMiA8LSBmaWx0ZXIobWFzdGVyZmlsZV9lb2NfYWdlT3ZlcjYwX2dvb2RRLFNhbXBsZSVpbiVjKFZpUF9EaXNjb3ZlcnlfQ29ob3J0X2xpc3QpKQpUb3RhbF9TYW1wbGVfQWxsZWxlc19hZ2VPdmVyNjAgPC0gKG5fZGlzdGluY3QobWFzdGVyZmlsZV9lb2NfYWdlT3ZlcjYwX2dvb2RRMiRTYW1wbGUpKjIpCmBgYAoKRXhjbHVkZSBNT0RFUkFURSBpbXBhY3QgdmFyaWFudHMKYGBge3J9Cm1hc3RlcmZpbGVfZW9jX2FnZVVuZGVyNjBfZ29vZFFfSElHSCA8LSBmaWx0ZXIobWFzdGVyZmlsZV9lb2NfYWdlVW5kZXI2MF9nb29kUSwgSU1QQUNUPT0iSElHSCIpCgptYXN0ZXJmaWxlX2VvY19hZ2VVbmRlcjYwX2dvb2RRMl9ISUdIIDwtIGZpbHRlcihtYXN0ZXJmaWxlX2VvY19hZ2VVbmRlcjYwX2dvb2RRMiwgSU1QQUNUPT0iSElHSCIpCgptYXN0ZXJmaWxlX2VvY19hZ2VPdmVyNjBfZ29vZFFfSElHSCA8LSBmaWx0ZXIobWFzdGVyZmlsZV9lb2NfYWdlT3ZlcjYwX2dvb2RRLCBJTVBBQ1Q9PSJISUdIIikKCm1hc3RlcmZpbGVfZW9jX2FnZU92ZXI2MF9nb29kUTJfSElHSCA8LSBmaWx0ZXIobWFzdGVyZmlsZV9lb2NfYWdlT3ZlcjYwX2dvb2RRMiwgSU1QQUNUPT0iSElHSCIpCmBgYAoKU2VwYXJhdGUgRW5zZW1ibCBjYW5vbmljYWwgYW5kIFJlZlNlcSBjYW5vbmljYWwgdmFyaWFudHMKYGBge3J9Cm1hc3RlcmZpbGVfZW9jX2FnZVVuZGVyNjBfZ29vZFFfSElHSF9FTlNUY2Fub25pY2FsIDwtIGZpbHRlcihtYXN0ZXJmaWxlX2VvY19hZ2VVbmRlcjYwX2dvb2RRX0hJR0gsQ0FOT05JQ0FMPT0iWUVTIikgCgptYXN0ZXJmaWxlX2VvY19hZ2VVbmRlcjYwX2dvb2RRMl9ISUdIX0VOU1RjYW5vbmljYWwgPC0gZmlsdGVyKG1hc3RlcmZpbGVfZW9jX2FnZVVuZGVyNjBfZ29vZFEyX0hJR0gsQ0FOT05JQ0FMPT0iWUVTIikgCgptYXN0ZXJmaWxlX2VvY19hZ2VVbmRlcjYwX2dvb2RRMl9ISUdIX05NY2Fub25pY2FsIDwtIGZpbHRlcihtYXN0ZXJmaWxlX2VvY19hZ2VVbmRlcjYwX2dvb2RRMl9ISUdILEVuc2VtYmw5NF9yZWZzZXFfbXJuYSE9ImlzLm5hIikgJT4lIAogIGZpbHRlcighRW5zZW1ibDk0X3JlZnNlcV9tcm5hX1NUQVRVUyVpbiVjKCIufC4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIufC58LiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1PREVMIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiSU5GRVJSRUQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJQUkVESUNURUQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJQUk9WSVNJT05BTCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIldHUyIpKQoKbWFzdGVyZmlsZV9lb2NfYWdlT3ZlcjYwX2dvb2RRX0hJR0hfRU5TVGNhbm9uaWNhbCA8LSBmaWx0ZXIobWFzdGVyZmlsZV9lb2NfYWdlT3ZlcjYwX2dvb2RRX0hJR0gsQ0FOT05JQ0FMPT0iWUVTIikgCgptYXN0ZXJmaWxlX2VvY19hZ2VPdmVyNjBfZ29vZFEyX0hJR0hfRU5TVGNhbm9uaWNhbCA8LSBmaWx0ZXIobWFzdGVyZmlsZV9lb2NfYWdlT3ZlcjYwX2dvb2RRMl9ISUdILENBTk9OSUNBTD09IllFUyIpIAoKbWFzdGVyZmlsZV9lb2NfYWdlT3ZlcjYwX2dvb2RRMl9ISUdIX05NY2Fub25pY2FsIDwtIGZpbHRlcihtYXN0ZXJmaWxlX2VvY19hZ2VPdmVyNjBfZ29vZFEyX0hJR0gsRW5zZW1ibDk0X3JlZnNlcV9tcm5hIT0iaXMubmEiKSAlPiUgCiAgZmlsdGVyKCFFbnNlbWJsOTRfcmVmc2VxX21ybmFfU1RBVFVTJWluJWMoIi58LiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIi58LnwuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTU9ERUwiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJJTkZFUlJFRCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlBSRURJQ1RFRCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlBST1ZJU0lPTkFMIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiV0dTIikpCmBgYAoKU2FtcGxlIHZhcmlhbnQgY291bnRzIGFuZCBBRnMKYGBge3J9CnZhcmlhbnRfY291bnRzX0FGcyA8LSBmdW5jdGlvbih2Y2YsVG90YWxfU2FtcGxlX0FsbGVsZXMpewp2YXJpYW50c19oZXRlcm96eWdvdXMgPC0gdmNmICU+JSAKICBzZWxlY3QoSEdWU2MsU2FtcGxlLkdUKSAlPiUgCiAgZ3JvdXBfYnkoSEdWU2MsU2FtcGxlLkdUKSAlPiUgCiAgc3VtbWFyaXNlKG4oKSkgJT4lIAogIGZpbHRlcigoU2FtcGxlLkdUJWluJWMoIicwLzEiLCInMS8wIikpKSAlPiUgCiAgZHBseXI6OnJlbmFtZShhbGxlbGVzID0gIm4oKSIpICU+JSAKICBncm91cF9ieShIR1ZTYykgJT4lIAogIHN1bW1hcmlzZShzdW0oYWxsZWxlcykpCnZhcmlhbnRzX2hvbW96eWdvdXMgPC0gdmNmICU+JSAKICBzZWxlY3QoSEdWU2MsU2FtcGxlLkdUKSAlPiUgCiAgZ3JvdXBfYnkoSEdWU2MsU2FtcGxlLkdUKSAlPiUgCiAgc3VtbWFyaXNlKG4oKSkgJT4lIAogIGZpbHRlcigoU2FtcGxlLkdUIT0iJzAvMSIpJihTYW1wbGUuR1QhPSInMS8wIikpICU+JSAKICBtdXRhdGUoYWxsZWxlcyA9IGBuKClgKjIpICU+JSAKICBzZWxlY3QoLWBuKClgKSAlPiUgCiAgZ3JvdXBfYnkoSEdWU2MpICU+JSAKICBzdW1tYXJpc2Uoc3VtKGFsbGVsZXMpKQp2YXJpYW50cyA8LSBmdWxsX2pvaW4odmFyaWFudHNfaGV0ZXJvenlnb3VzLHZhcmlhbnRzX2hvbW96eWdvdXMsYnk9IkhHVlNjIixjb3B5PUZBTFNFLHN1ZmZpeD1jKCIueCIsIi55IikpICU+JQogIG11dGF0ZV9hbGwoZnVucyhyZXBsYWNlKC4sIGlzLm5hKC4pLCAwKSkpICU+JSAKICBtdXRhdGUoVG90YWxfQWxsZWxlX0NvdW50PWBzdW0oYWxsZWxlcykueGArYHN1bShhbGxlbGVzKS55YCkgJT4lIAogIG11dGF0ZShTYW1wbGVfQUY9VG90YWxfQWxsZWxlX0NvdW50L1RvdGFsX1NhbXBsZV9BbGxlbGVzKQp2Y2YgPC0gbGVmdF9qb2luKHZjZiwgdmFyaWFudHNbLGMoMSw0OjUpXSxieT0iSEdWU2MiLGNvcHk9RkFMU0UpCn0KCm1hc3RlcmZpbGVfZW9jX2FnZVVuZGVyNjBfZ29vZFFfSElHSF9FTlNUY2Fub25pY2FsXzIgPC0gdmFyaWFudF9jb3VudHNfQUZzKG1hc3RlcmZpbGVfZW9jX2FnZVVuZGVyNjBfZ29vZFFfSElHSF9FTlNUY2Fub25pY2FsLFRvdGFsX1NhbXBsZV9BbGxlbGVzX2FnZVVuZGVyNjApCgptYXN0ZXJmaWxlX2VvY19hZ2VVbmRlcjYwX2dvb2RRMl9ISUdIX0VOU1RjYW5vbmljYWxfMiA8LSB2YXJpYW50X2NvdW50c19BRnMobWFzdGVyZmlsZV9lb2NfYWdlVW5kZXI2MF9nb29kUTJfSElHSF9FTlNUY2Fub25pY2FsLFRvdGFsX1NhbXBsZV9BbGxlbGVzX2FnZVVuZGVyNjApCgptYXN0ZXJmaWxlX2VvY19hZ2VVbmRlcjYwX2dvb2RRMl9ISUdIX05NY2Fub25pY2FsXzIgPC0gdmFyaWFudF9jb3VudHNfQUZzKG1hc3RlcmZpbGVfZW9jX2FnZVVuZGVyNjBfZ29vZFEyX0hJR0hfTk1jYW5vbmljYWwsVG90YWxfU2FtcGxlX0FsbGVsZXNfYWdlVW5kZXI2MCkKCm1hc3RlcmZpbGVfZW9jX2FnZU92ZXI2MF9nb29kUV9ISUdIX0VOU1RjYW5vbmljYWxfMiA8LSB2YXJpYW50X2NvdW50c19BRnMobWFzdGVyZmlsZV9lb2NfYWdlT3ZlcjYwX2dvb2RRX0hJR0hfRU5TVGNhbm9uaWNhbCxUb3RhbF9TYW1wbGVfQWxsZWxlc19hZ2VPdmVyNjApCgptYXN0ZXJmaWxlX2VvY19hZ2VPdmVyNjBfZ29vZFEyX0hJR0hfRU5TVGNhbm9uaWNhbF8yIDwtIHZhcmlhbnRfY291bnRzX0FGcyhtYXN0ZXJmaWxlX2VvY19hZ2VPdmVyNjBfZ29vZFEyX0hJR0hfRU5TVGNhbm9uaWNhbCxUb3RhbF9TYW1wbGVfQWxsZWxlc19hZ2VPdmVyNjApCgptYXN0ZXJmaWxlX2VvY19hZ2VPdmVyNjBfZ29vZFEyX0hJR0hfTk1jYW5vbmljYWxfMiA8LSB2YXJpYW50X2NvdW50c19BRnMobWFzdGVyZmlsZV9lb2NfYWdlT3ZlcjYwX2dvb2RRMl9ISUdIX05NY2Fub25pY2FsLFRvdGFsX1NhbXBsZV9BbGxlbGVzX2FnZU92ZXI2MCkKYGBgCgpFeGNsdWRlIHZhcmlhbnRzIHdpdGggc2FtcGxlIEFGID4wLjAxzJsKYGBge3J9Cm1hc3RlcmZpbGVfZW9jX2FnZVVuZGVyNjBfZ29vZFFfSElHSF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMSA8LSBmaWx0ZXIobWFzdGVyZmlsZV9lb2NfYWdlVW5kZXI2MF9nb29kUV9ISUdIX0VOU1RjYW5vbmljYWxfMixTYW1wbGVfQUYgPCAwLjAxKQoKbWFzdGVyZmlsZV9lb2NfYWdlVW5kZXI2MF9nb29kUTJfSElHSF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMSA8LSBmaWx0ZXIobWFzdGVyZmlsZV9lb2NfYWdlVW5kZXI2MF9nb29kUTJfSElHSF9FTlNUY2Fub25pY2FsXzIsU2FtcGxlX0FGIDwgMC4wMSkKCm1hc3RlcmZpbGVfZW9jX2FnZVVuZGVyNjBfZ29vZFEyX0hJR0hfTk1jYW5vbmljYWxfc2FtcGxlQUYwLjAxIDwtIGZpbHRlcihtYXN0ZXJmaWxlX2VvY19hZ2VVbmRlcjYwX2dvb2RRMl9ISUdIX05NY2Fub25pY2FsXzIsU2FtcGxlX0FGIDwgMC4wMSkKCm1hc3RlcmZpbGVfZW9jX2FnZU92ZXI2MF9nb29kUV9ISUdIX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxIDwtIGZpbHRlcihtYXN0ZXJmaWxlX2VvY19hZ2VPdmVyNjBfZ29vZFFfSElHSF9FTlNUY2Fub25pY2FsXzIsU2FtcGxlX0FGIDwgMC4wMSkKCm1hc3RlcmZpbGVfZW9jX2FnZU92ZXI2MF9nb29kUTJfSElHSF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMSA8LSBmaWx0ZXIobWFzdGVyZmlsZV9lb2NfYWdlT3ZlcjYwX2dvb2RRMl9ISUdIX0VOU1RjYW5vbmljYWxfMixTYW1wbGVfQUYgPCAwLjAxKQoKbWFzdGVyZmlsZV9lb2NfYWdlT3ZlcjYwX2dvb2RRMl9ISUdIX05NY2Fub25pY2FsX3NhbXBsZUFGMC4wMSA8LSBmaWx0ZXIobWFzdGVyZmlsZV9lb2NfYWdlT3ZlcjYwX2dvb2RRMl9ISUdIX05NY2Fub25pY2FsXzIsU2FtcGxlX0FGIDwgMC4wMSkKYGBgCgpPdXRwdXQgbGlzdCBvZiBnZW5lcyBhbmQgdmFyaWFudHMgd2l0aCBzYW1wbGUgQUYgPjAuMDEKYGBge3J9Cm1hc3RlcmZpbGVfZW9jX2FnZVVuZGVyNjBfZ29vZFEyX0hJR0hfRU5TVGNhbm9uaWNhbF9nZW5lc2FuZHZhcmlhbnRzMC4wMSA8LSBmaWx0ZXIobWFzdGVyZmlsZV9lb2NfYWdlVW5kZXI2MF9nb29kUTJfSElHSF9FTlNUY2Fub25pY2FsXzIsU2FtcGxlX0FGID4gMC4wMSkKbWFzdGVyZmlsZV9lb2NfYWdlVW5kZXI2MF9nb29kUTJfSElHSF9FTlNUY2Fub25pY2FsX2dlbmVzYW5kdmFyaWFudHMwLjAxWyxjKDI6NiwyNTo1NCldICU+JSAKICBkaXN0aW5jdCgua2VlcF9hbGwgPSBGQUxTRSkgJT4lIAogIHdyaXRlX2V4Y2VsX2NzdihwYXRoPSJtYXN0ZXJmaWxlX2VvY19hZ2VVbmRlcjYwX2dvb2RRMl9ISUdIX0VOU1RjYW5vbmljYWxfZ2VuZXNhbmR2YXJpYW50czAuMDEuY3N2IixuYT0iLiIsYXBwZW5kPUZBTFNFLGNvbF9uYW1lcz1UUlVFKQoKbWFzdGVyZmlsZV9lb2NfYWdlVW5kZXI2MF9nb29kUTJfSElHSF9OTWNhbm9uaWNhbF9nZW5lc2FuZHZhcmlhbnRzMC4wMSA8LSBmaWx0ZXIobWFzdGVyZmlsZV9lb2NfYWdlVW5kZXI2MF9nb29kUTJfSElHSF9OTWNhbm9uaWNhbF8yLFNhbXBsZV9BRiA+IDAuMDEpCm1hc3RlcmZpbGVfZW9jX2FnZVVuZGVyNjBfZ29vZFEyX0hJR0hfTk1jYW5vbmljYWxfZ2VuZXNhbmR2YXJpYW50czAuMDFbLGMoMjo2LDI1OjU0KV0gJT4lIAogIGRpc3RpbmN0KC5rZWVwX2FsbCA9IEZBTFNFKSAlPiUgCiAgd3JpdGVfZXhjZWxfY3N2KHBhdGg9Im1hc3RlcmZpbGVfZW9jX2FnZVVuZGVyNjBfZ29vZFEyX0hJR0hfTk1jYW5vbmljYWxfZ2VuZXNhbmR2YXJpYW50czAuMDEuY3N2IixuYT0iLiIsYXBwZW5kPUZBTFNFLGNvbF9uYW1lcz1UUlVFKQoKbWFzdGVyZmlsZV9lb2NfYWdlT3ZlcjYwX2dvb2RRMl9ISUdIX0VOU1RjYW5vbmljYWxfZ2VuZXNhbmR2YXJpYW50czAuMDEgPC0gZmlsdGVyKG1hc3RlcmZpbGVfZW9jX2FnZU92ZXI2MF9nb29kUTJfSElHSF9FTlNUY2Fub25pY2FsXzIsU2FtcGxlX0FGID4gMC4wMSkKbWFzdGVyZmlsZV9lb2NfYWdlT3ZlcjYwX2dvb2RRMl9ISUdIX0VOU1RjYW5vbmljYWxfZ2VuZXNhbmR2YXJpYW50czAuMDFbLGMoMjo2LDI1OjU0KV0gJT4lIAogIGRpc3RpbmN0KC5rZWVwX2FsbCA9IEZBTFNFKSAlPiUgCiAgd3JpdGVfZXhjZWxfY3N2KHBhdGg9Im1hc3RlcmZpbGVfZW9jX2FnZU92ZXI2MF9nb29kUTJfSElHSF9FTlNUY2Fub25pY2FsX2dlbmVzYW5kdmFyaWFudHMwLjAxLmNzdiIsbmE9Ii4iLGFwcGVuZD1GQUxTRSxjb2xfbmFtZXM9VFJVRSkKCm1hc3RlcmZpbGVfZW9jX2FnZU92ZXI2MF9nb29kUTJfSElHSF9OTWNhbm9uaWNhbF9nZW5lc2FuZHZhcmlhbnRzMC4wMSA8LSBmaWx0ZXIobWFzdGVyZmlsZV9lb2NfYWdlT3ZlcjYwX2dvb2RRMl9ISUdIX05NY2Fub25pY2FsXzIsU2FtcGxlX0FGID4gMC4wMSkKbWFzdGVyZmlsZV9lb2NfYWdlT3ZlcjYwX2dvb2RRMl9ISUdIX05NY2Fub25pY2FsX2dlbmVzYW5kdmFyaWFudHMwLjAxWyxjKDI6NiwyNTo1NCldICU+JSAKICBkaXN0aW5jdCgua2VlcF9hbGwgPSBGQUxTRSkgJT4lIAogIHdyaXRlX2V4Y2VsX2NzdihwYXRoPSJtYXN0ZXJmaWxlX2VvY19hZ2VPdmVyNjBfZ29vZFEyX0hJR0hfTk1jYW5vbmljYWxfZ2VuZXNhbmR2YXJpYW50czAuMDEuY3N2IixuYT0iLiIsYXBwZW5kPUZBTFNFLGNvbF9uYW1lcz1UUlVFKQpgYGAKClNhbXBsZSBnZW5lIGNvdW50cyBhbmQgZnJlcXVlbmNpZXMKYGBge3J9CmdlbmVfY291bnRzX0FGcyA8LSBmdW5jdGlvbih2Y2YsVG90YWxfU2FtcGxlX0FsbGVsZXMpewpnZW5lc19vbmVWYXJBbGxlbGUgPC0gdmNmICU+JSBzZWxlY3QoU1lNQk9MLFNhbXBsZS5HVCkgJT4lIAogIHNlbGVjdChTWU1CT0wsU2FtcGxlLkdUKSAlPiUgCiAgZ3JvdXBfYnkoU1lNQk9MLFNhbXBsZS5HVCkgJT4lIAogIHN1bW1hcmlzZShuKCkpICU+JSAKICBmaWx0ZXIoKFNhbXBsZS5HVCVpbiVjKCInMC8xIiwiJzEvMCIpKSkgJT4lIAogIGRwbHlyOjpyZW5hbWUoZ2VuZV9WYXIgPSAibigpIikgJT4lIAogIGdyb3VwX2J5KFNZTUJPTCkgJT4lIAogIHN1bW1hcmlzZShzdW0oZ2VuZV9WYXIpKQpnZW5lc190d29WYXJBbGxlbGUgPC0gdmNmICU+JSBzZWxlY3QoU1lNQk9MLFNhbXBsZS5HVCkgJT4lIAogIHNlbGVjdChTWU1CT0wsU2FtcGxlLkdUKSAlPiUgCiAgZ3JvdXBfYnkoU1lNQk9MLFNhbXBsZS5HVCkgJT4lIAogIHN1bW1hcmlzZShuKCkpICU+JSAKICBmaWx0ZXIoKFNhbXBsZS5HVCE9IicwLzEiKSYoU2FtcGxlLkdUIT0iJzEvMCIpKSAlPiUgCiAgbXV0YXRlKGdlbmVfVmFyID0gYG4oKWAqMikgJT4lIAogIHNlbGVjdCgtYG4oKWApICU+JSAKICBncm91cF9ieShTWU1CT0wpICU+JSAKICBzdW1tYXJpc2Uoc3VtKGdlbmVfVmFyKSkKZ2VuZXMgPC0gZnVsbF9qb2luKGdlbmVzX29uZVZhckFsbGVsZSxnZW5lc190d29WYXJBbGxlbGUsYnk9IlNZTUJPTCIsY29weT1GQUxTRSxzdWZmaXg9YygiLngiLCIueSIpKSAlPiUgCiAgbXV0YXRlX2FsbChmdW5zKHJlcGxhY2UoLiwgaXMubmEoLiksIDApKSkgJT4lIAogIG11dGF0ZShUb3RhbF9HZW5lX0NvdW50PWBzdW0oZ2VuZV9WYXIpLnhgK2BzdW0oZ2VuZV9WYXIpLnlgKSAlPiUgCiAgbXV0YXRlKFNhbXBsZV9HZW5lX0ZyZXE9VG90YWxfR2VuZV9Db3VudC9Ub3RhbF9TYW1wbGVfQWxsZWxlcykKdmNmIDwtIGxlZnRfam9pbih2Y2YsIGdlbmVzWyxjKDEsNDo1KV0sYnk9IlNZTUJPTCIsY29weT1GQUxTRSkKfQoKbWFzdGVyZmlsZV9lb2NfYWdlVW5kZXI2MF9nb29kUV9ISUdIX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxXzIgPC0gZ2VuZV9jb3VudHNfQUZzKG1hc3RlcmZpbGVfZW9jX2FnZVVuZGVyNjBfZ29vZFFfSElHSF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMSxUb3RhbF9TYW1wbGVfQWxsZWxlc19hZ2VVbmRlcjYwKQoKbWFzdGVyZmlsZV9lb2NfYWdlVW5kZXI2MF9nb29kUTJfSElHSF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV8yIDwtIGdlbmVfY291bnRzX0FGcyhtYXN0ZXJmaWxlX2VvY19hZ2VVbmRlcjYwX2dvb2RRMl9ISUdIX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxLFRvdGFsX1NhbXBsZV9BbGxlbGVzX2FnZVVuZGVyNjApCgptYXN0ZXJmaWxlX2VvY19hZ2VVbmRlcjYwX2dvb2RRMl9ISUdIX05NY2Fub25pY2FsX3NhbXBsZUFGMC4wMV8yIDwtIGdlbmVfY291bnRzX0FGcyhtYXN0ZXJmaWxlX2VvY19hZ2VVbmRlcjYwX2dvb2RRMl9ISUdIX05NY2Fub25pY2FsX3NhbXBsZUFGMC4wMSxUb3RhbF9TYW1wbGVfQWxsZWxlc19hZ2VVbmRlcjYwKQoKbWFzdGVyZmlsZV9lb2NfYWdlT3ZlcjYwX2dvb2RRX0hJR0hfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfMiA8LSBnZW5lX2NvdW50c19BRnMobWFzdGVyZmlsZV9lb2NfYWdlT3ZlcjYwX2dvb2RRX0hJR0hfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDEsVG90YWxfU2FtcGxlX0FsbGVsZXNfYWdlT3ZlcjYwKQoKbWFzdGVyZmlsZV9lb2NfYWdlT3ZlcjYwX2dvb2RRMl9ISUdIX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxXzIgPC0gZ2VuZV9jb3VudHNfQUZzKG1hc3RlcmZpbGVfZW9jX2FnZU92ZXI2MF9nb29kUTJfSElHSF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMSxUb3RhbF9TYW1wbGVfQWxsZWxlc19hZ2VPdmVyNjApCgptYXN0ZXJmaWxlX2VvY19hZ2VPdmVyNjBfZ29vZFEyX0hJR0hfTk1jYW5vbmljYWxfc2FtcGxlQUYwLjAxXzIgPC0gZ2VuZV9jb3VudHNfQUZzKG1hc3RlcmZpbGVfZW9jX2FnZU92ZXI2MF9nb29kUTJfSElHSF9OTWNhbm9uaWNhbF9zYW1wbGVBRjAuMDEsVG90YWxfU2FtcGxlX0FsbGVsZXNfYWdlT3ZlcjYwKQpgYGAKCkFkZCBHbm9tQUQgZ2VuZS1sZXZlbCBkYXRhCmBgYHtyfQpHbm9tQURfc3RhdHNfTE9GX1ZFUCA8LSByZWFkLmRlbGltKCJHbm9tQURfc3RhdHNfTE9GX1ZFUC50c3YiLCBoZWFkZXI9VFJVRSwgcm93Lm5hbWVzPU5VTEwsIHN0cmluZ3NBc0ZhY3RvcnM9RkFMU0UpCgpHbm9tQUREIDwtIGZ1bmN0aW9uKHZjZixHbm9tQUQpewogIHZjZiA8LSBsZWZ0X2pvaW4odmNmLCBHbm9tQURbLGMoMiwzMDo0MSldLGJ5PSJGZWF0dXJlIixjb3B5PUZBTFNFKSAKICB2Y2YgPC0gbXV0YXRlX2F0KHZjZix2YXJzKHN0YXJ0c193aXRoKCJGSUxURVJfIikpLGZ1bnMocmVwbGFjZSguLCBpcy5uYSguKSwgMCkpKSAlPiUKICBtdXRhdGVfaWYoZ3JlcGwoInBvcG1heCQiLCBuYW1lcyguKSksZnVucyhpZmVsc2UoLiA9PSAiTkEiLCAwLCBhcy5udW1lcmljKC4pKSkpICU+JSAKICBtdXRhdGVfYXQodmFycyhlbmRzX3dpdGgoInBvcG1heCIpKSxmdW5zKHJlcGxhY2UoLiwgaXMubmEoLiksIDApKSkKfQoKbWFzdGVyZmlsZV9lb2NfYWdlVW5kZXI2MF9nb29kUV9ISUdIX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0cyA8LSBHbm9tQUREKG1hc3RlcmZpbGVfZW9jX2FnZVVuZGVyNjBfZ29vZFFfSElHSF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV8yLEdub21BRF9zdGF0c19MT0ZfVkVQKQoKbWFzdGVyZmlsZV9lb2NfYWdlVW5kZXI2MF9nb29kUTJfSElHSF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHMgPC0gR25vbUFERChtYXN0ZXJmaWxlX2VvY19hZ2VVbmRlcjYwX2dvb2RRMl9ISUdIX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxXzIsR25vbUFEX3N0YXRzX0xPRl9WRVApCgptYXN0ZXJmaWxlX2VvY19hZ2VVbmRlcjYwX2dvb2RRMl9ISUdIX05NY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHMgPC0gR25vbUFERChtYXN0ZXJmaWxlX2VvY19hZ2VVbmRlcjYwX2dvb2RRMl9ISUdIX05NY2Fub25pY2FsX3NhbXBsZUFGMC4wMV8yLEdub21BRF9zdGF0c19MT0ZfVkVQKQoKbWFzdGVyZmlsZV9lb2NfYWdlT3ZlcjYwX2dvb2RRX0hJR0hfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzIDwtIEdub21BREQobWFzdGVyZmlsZV9lb2NfYWdlT3ZlcjYwX2dvb2RRX0hJR0hfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfMixHbm9tQURfc3RhdHNfTE9GX1ZFUCkKCm1hc3RlcmZpbGVfZW9jX2FnZU92ZXI2MF9nb29kUTJfSElHSF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHMgPC0gR25vbUFERChtYXN0ZXJmaWxlX2VvY19hZ2VPdmVyNjBfZ29vZFEyX0hJR0hfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfMixHbm9tQURfc3RhdHNfTE9GX1ZFUCkKCm1hc3RlcmZpbGVfZW9jX2FnZU92ZXI2MF9nb29kUTJfSElHSF9OTWNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzIDwtIEdub21BREQobWFzdGVyZmlsZV9lb2NfYWdlT3ZlcjYwX2dvb2RRMl9ISUdIX05NY2Fub25pY2FsX3NhbXBsZUFGMC4wMV8yLEdub21BRF9zdGF0c19MT0ZfVkVQKQpgYGAKCkNhbGN1bGF0ZSBTYW1wbGUvR25vbUFEIGdlbmUgZnJlcSByYXRpb3MgZm9yIHRvdGFsIGFuZCBORkUgR25vbUFEIGZpZ3VyZXMgKGluY2x1ZGluZyBhbmQgZXhjbHVkaW5nIHZhcmlhbnRzIHdpdGggQUYgPiAwLjAwNSksIGFzIHdlbGwgYXMgYWxsZWxlIGZyZXEgcmF0aW9zCmBgYHtyfQpyYXRpb3MgPC0gZnVuY3Rpb24odmNmKXsKICBtdXRhdGUodmNmLCAKICAgICAgICAgIlNhbXBsZV9HZW5lX0xPRl9GcmVxX1JhdGlvX0dub21BRCI9U2FtcGxlX0dlbmVfRnJlcS9GSUxURVJfUkZfTE9GX0hJR0hJTVBBQ1RfQUZfMS4wX0FESiwKICAgICAgICAgIlNhbXBsZV9HZW5lX0xPRl9GcmVxX1JhdGlvX0dub21BRF8wLjAwNSI9U2FtcGxlX0dlbmVfRnJlcS9GSUxURVJfUkZfTE9GX0hJR0hJTVBBQ1RfQUZfMC4wMDVfQURKLAogICAgICAgICAiUmF0aW9fRGlmZmVyZW5jZSI9U2FtcGxlX0dlbmVfTE9GX0ZyZXFfUmF0aW9fR25vbUFEXzAuMDA1LVNhbXBsZV9HZW5lX0xPRl9GcmVxX1JhdGlvX0dub21BRCwgCiAgICAgICAgICJTYW1wbGVfR2VuZV9MT0ZfRnJlcV9SYXRpb19Hbm9tQURfTkZFIj1TYW1wbGVfR2VuZV9GcmVxL0ZJTFRFUl9SRl9MT0ZfSElHSElNUEFDVF9BRl8xLjBfTkZFX0FESiwKICAgICAgICAgIlNhbXBsZV9HZW5lX0xPRl9GcmVxX1JhdGlvX0dub21BRF9ORkVfMC4wMDUiPVNhbXBsZV9HZW5lX0ZyZXEvRklMVEVSX1JGX0xPRl9ISUdISU1QQUNUX0FGXzAuMDA1X05GRV9BREosCiAgICAgICAgICJSYXRpb19EaWZmZXJlbmNlX05GRSI9U2FtcGxlX0dlbmVfTE9GX0ZyZXFfUmF0aW9fR25vbUFEX05GRV8wLjAwNS1TYW1wbGVfR2VuZV9MT0ZfRnJlcV9SYXRpb19Hbm9tQURfTkZFLAogICAgICAgICAiU2FtcGxlX0dlbmVfTE9GX0FGX1JhdGlvIj1TYW1wbGVfQUYvR25vbUFEX3YyLjFfbm9uX2NhbmNlcl9BRiwgCiAgICAgICAgICJTYW1wbGVfR2VuZV9MT0ZfQUZfUmF0aW9fTkZFIj1TYW1wbGVfQUYvR25vbUFEX3YyLjFfbm9uX2NhbmNlcl9BRl9uZmUpCn0KCm1hc3RlcmZpbGVfZW9jX2FnZVVuZGVyNjBfZ29vZFFfSElHSF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfcmF0aW9zIDwtIAogIHJhdGlvcyhtYXN0ZXJmaWxlX2VvY19hZ2VVbmRlcjYwX2dvb2RRX0hJR0hfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzKQoKbWFzdGVyZmlsZV9lb2NfYWdlVW5kZXI2MF9nb29kUTJfSElHSF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfcmF0aW9zIDwtIAogIHJhdGlvcyhtYXN0ZXJmaWxlX2VvY19hZ2VVbmRlcjYwX2dvb2RRMl9ISUdIX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0cykKCm1hc3RlcmZpbGVfZW9jX2FnZVVuZGVyNjBfZ29vZFEyX0hJR0hfTk1jYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19yYXRpb3MgPC0gCiAgcmF0aW9zKG1hc3RlcmZpbGVfZW9jX2FnZVVuZGVyNjBfZ29vZFEyX0hJR0hfTk1jYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0cykKCm1hc3RlcmZpbGVfZW9jX2FnZU92ZXI2MF9nb29kUV9ISUdIX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19yYXRpb3MgPC0gCiAgcmF0aW9zKG1hc3RlcmZpbGVfZW9jX2FnZU92ZXI2MF9nb29kUV9ISUdIX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0cykKCm1hc3RlcmZpbGVfZW9jX2FnZU92ZXI2MF9nb29kUTJfSElHSF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfcmF0aW9zIDwtIAogIHJhdGlvcyhtYXN0ZXJmaWxlX2VvY19hZ2VPdmVyNjBfZ29vZFEyX0hJR0hfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzKQoKbWFzdGVyZmlsZV9lb2NfYWdlT3ZlcjYwX2dvb2RRMl9ISUdIX05NY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfcmF0aW9zIDwtIAogIHJhdGlvcyhtYXN0ZXJmaWxlX2VvY19hZ2VPdmVyNjBfZ29vZFEyX0hJR0hfTk1jYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0cykKYGBgCgpDcmVhdGUgZGF0YSBmcmFtZXMgd2l0aCBBZ2lsZW50IFN1cmVTZWxlY3Qgd2hvbGUgZXhvbWUgZ2VuZXMgKGFsbCBFTlNULCBwcm90ZWluLWNvZGluZyBvbmx5IGFuZCBub24tcHJvdGVpbi1jb2RpbmcpIGZvciB2b2xjYW5vIHBsb3QKYGBge3J9CmVuc2VtYmxfYmlvdHlwZXMgPC0gcmVhZC5kZWxpbSgiZW5zZW1ibF9iaW90eXBlcy50c3YiLCBzdHJpbmdzQXNGYWN0b3JzPUZBTFNFKSAlPiUgCiAgc2VsZWN0KGVuc2VtYmxfdHJhbnNjcmlwdF9pZCx0cmFuc2NyaXB0X2Jpb3R5cGUpICU+JSAKICBkcGx5cjo6cmVuYW1lKCJGZWF0dXJlIj0iZW5zZW1ibF90cmFuc2NyaXB0X2lkIiwiQklPVFlQRSI9InRyYW5zY3JpcHRfYmlvdHlwZSIpCkdub21BRF9zdGF0c19BZ2lsZW50U1N2Nl9MT0ZfVkVQX0VOU1RjYW5vbmljYWxfYWxsIDwtIHJlYWQuZGVsaW0oIkdub21BRC5nZW5lLnN0YXRzLnYyLlJGLm9ubHkuYWdpbGVudC52Ni5vbmx5LnRzdiIsIGhlYWRlcj1UUlVFLCByb3cubmFtZXM9TlVMTCwgc3RyaW5nc0FzRmFjdG9ycz1GQUxTRSkgJT4lIAogIGZpbHRlcihDQU5PTklDQUw9PSJZRVMiKSAlPiUgCiAgZHBseXI6OnJlbmFtZSgiU1lNQk9MIj0iWC5TeW1ib2wiKSAlPiUgCiAgZHBseXI6OnJlbmFtZSgiR2VuZSI9IkVOU0ciKSAlPiUgCiAgbGVmdF9qb2luKGVuc2VtYmxfYmlvdHlwZXMsYnk9IkZlYXR1cmUiLGNvcHk9RkFMU0UpCkdub21BRF9zdGF0c19BZ2lsZW50U1N2Nl9MT0ZfVkVQX0VOU1RjYW5vbmljYWxfcHJvdGVpbl9jb2RpbmcgPC0gcmVhZC5kZWxpbSgiR25vbUFELmdlbmUuc3RhdHMudjIuUkYub25seS5hZ2lsZW50LnY2Lm9ubHkudHN2IiwgaGVhZGVyPVRSVUUsIHJvdy5uYW1lcz1OVUxMLCBzdHJpbmdzQXNGYWN0b3JzPUZBTFNFKSAlPiUgCiAgZmlsdGVyKENBTk9OSUNBTD09IllFUyIpICU+JSAKICBkcGx5cjo6cmVuYW1lKCJTWU1CT0wiPSJYLlN5bWJvbCIpICU+JSAKICBkcGx5cjo6cmVuYW1lKCJHZW5lIj0iRU5TRyIpICU+JSAKICBsZWZ0X2pvaW4oZW5zZW1ibF9iaW90eXBlcyxieT0iRmVhdHVyZSIsY29weT1GQUxTRSkgJT4lIAogIGZpbHRlcihCSU9UWVBFJWluJWMoInByb3RlaW5fY29kaW5nIikpCkdub21BRF9zdGF0c19BZ2lsZW50U1N2Nl9MT0ZfVkVQX0VOU1RjYW5vbmljYWxfbm9uX3Byb3RlaW5fY29kaW5nIDwtIHJlYWQuZGVsaW0oIkdub21BRC5nZW5lLnN0YXRzLnYyLlJGLm9ubHkuYWdpbGVudC52Ni5vbmx5LnRzdiIsIGhlYWRlcj1UUlVFLCByb3cubmFtZXM9TlVMTCwgc3RyaW5nc0FzRmFjdG9ycz1GQUxTRSkgJT4lIAogIGZpbHRlcihDQU5PTklDQUw9PSJZRVMiKSAlPiUgCiAgZHBseXI6OnJlbmFtZSgiU1lNQk9MIj0iWC5TeW1ib2wiKSAlPiUgCiAgZHBseXI6OnJlbmFtZSgiR2VuZSI9IkVOU0ciKSAlPiUgCiAgbGVmdF9qb2luKGVuc2VtYmxfYmlvdHlwZXMsYnk9IkZlYXR1cmUiLGNvcHk9RkFMU0UpICU+JSAKICBmaWx0ZXIoIUJJT1RZUEUlaW4lYygicHJvdGVpbl9jb2RpbmciKSkKCmFsbEdlbmVzX0FnaWxlbnRTU3Y2X2xpc3QgPC0gdGliYmxlKCJTWU1CT0wiPUdub21BRF9zdGF0c19BZ2lsZW50U1N2Nl9MT0ZfVkVQX0VOU1RjYW5vbmljYWxfYWxsJFNZTUJPTCwiR2VuZSI9R25vbUFEX3N0YXRzX0FnaWxlbnRTU3Y2X0xPRl9WRVBfRU5TVGNhbm9uaWNhbF9hbGwkR2VuZSwiRmVhdHVyZSI9R25vbUFEX3N0YXRzX0FnaWxlbnRTU3Y2X0xPRl9WRVBfRU5TVGNhbm9uaWNhbF9hbGwkRmVhdHVyZSkgJT4lIAogIGRpc3RpbmN0KC5rZWVwX2FsbD1UUlVFKSAlPiUgCiAgYXJyYW5nZShTWU1CT0wpCmFsbEdlbmVzX0FnaWxlbnRTU3Y2X2xpc3RfcHJvdGVpbl9jb2Rpbmdfb25seSA8LSB0aWJibGUoIlNZTUJPTCI9R25vbUFEX3N0YXRzX0FnaWxlbnRTU3Y2X0xPRl9WRVBfRU5TVGNhbm9uaWNhbF9wcm90ZWluX2NvZGluZyRTWU1CT0wsIkdlbmUiPUdub21BRF9zdGF0c19BZ2lsZW50U1N2Nl9MT0ZfVkVQX0VOU1RjYW5vbmljYWxfcHJvdGVpbl9jb2RpbmckR2VuZSwiRmVhdHVyZSI9R25vbUFEX3N0YXRzX0FnaWxlbnRTU3Y2X0xPRl9WRVBfRU5TVGNhbm9uaWNhbF9wcm90ZWluX2NvZGluZyRGZWF0dXJlKSAlPiUgCiAgZGlzdGluY3QoLmtlZXBfYWxsPVRSVUUpICU+JSAKICBhcnJhbmdlKFNZTUJPTCkKYWxsR2VuZXNfQWdpbGVudFNTdjZfbGlzdF9ub25fcHJvdGVpbl9jb2Rpbmdfb25seSA8LSB0aWJibGUoIlNZTUJPTCI9R25vbUFEX3N0YXRzX0FnaWxlbnRTU3Y2X0xPRl9WRVBfRU5TVGNhbm9uaWNhbF9ub25fcHJvdGVpbl9jb2RpbmckU1lNQk9MLCJHZW5lIj1Hbm9tQURfc3RhdHNfQWdpbGVudFNTdjZfTE9GX1ZFUF9FTlNUY2Fub25pY2FsX25vbl9wcm90ZWluX2NvZGluZyRHZW5lLCJGZWF0dXJlIj1Hbm9tQURfc3RhdHNfQWdpbGVudFNTdjZfTE9GX1ZFUF9FTlNUY2Fub25pY2FsX25vbl9wcm90ZWluX2NvZGluZyRGZWF0dXJlKSAlPiUgCiAgZGlzdGluY3QoLmtlZXBfYWxsPVRSVUUpICU+JSAKICBhcnJhbmdlKFNZTUJPTCkKCmFsbEdlbmVzX21hc3RlcmZpbGVfZW9jX2FnZVVuZGVyNjBfZ29vZFEyX0hJR0hfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfbGlzdCA8LSB0aWJibGUoIlNZTUJPTCI9bWFzdGVyZmlsZV9lb2NfYWdlVW5kZXI2MF9nb29kUTJfSElHSF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfcmF0aW9zJFNZTUJPTCwiR2VuZSI9bWFzdGVyZmlsZV9lb2NfYWdlVW5kZXI2MF9nb29kUTJfSElHSF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfcmF0aW9zJEdlbmUsIkJJT1RZUEUiPW1hc3RlcmZpbGVfZW9jX2FnZVVuZGVyNjBfZ29vZFEyX0hJR0hfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX3JhdGlvcyRCSU9UWVBFKSAlPiUgCiAgZGlzdGluY3QoLmtlZXBfYWxsPVRSVUUpICU+JSAKICBhcnJhbmdlKFNZTUJPTCkKYWxsR2VuZXNfbWFzdGVyZmlsZV9lb2NfYWdlVW5kZXI2MF9nb29kUTJfSElHSF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV9iaW90eXBlX2xpc3QgPC0gdGliYmxlKCJTWU1CT0wiPW1hc3RlcmZpbGVfZW9jX2FnZVVuZGVyNjBfZ29vZFEyX0hJR0hfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX3JhdGlvcyRTWU1CT0wsIkdlbmUiPW1hc3RlcmZpbGVfZW9jX2FnZVVuZGVyNjBfZ29vZFEyX0hJR0hfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX3JhdGlvcyRHZW5lLCJCSU9UWVBFIj1tYXN0ZXJmaWxlX2VvY19hZ2VVbmRlcjYwX2dvb2RRMl9ISUdIX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19yYXRpb3MkQklPVFlQRSkgJT4lIAogIGRpc3RpbmN0KC5rZWVwX2FsbD1UUlVFKSAlPiUgCiAgZmlsdGVyKEJJT1RZUEUlaW4lYygicHJvdGVpbl9jb2RpbmciKSkgJT4lIAogIGFycmFuZ2UoU1lNQk9MKQphbGxHZW5lc19tYXN0ZXJmaWxlX2VvY19hZ2VVbmRlcjYwX2dvb2RRMl9ISUdIX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX2Jpb3R5cGUyX2xpc3QgPC0gdGliYmxlKCJTWU1CT0wiPW1hc3RlcmZpbGVfZW9jX2FnZVVuZGVyNjBfZ29vZFEyX0hJR0hfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX3JhdGlvcyRTWU1CT0wsIkdlbmUiPW1hc3RlcmZpbGVfZW9jX2FnZVVuZGVyNjBfZ29vZFEyX0hJR0hfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX3JhdGlvcyRHZW5lLCJCSU9UWVBFIj1tYXN0ZXJmaWxlX2VvY19hZ2VVbmRlcjYwX2dvb2RRMl9ISUdIX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19yYXRpb3MkQklPVFlQRSkgJT4lIAogIGRpc3RpbmN0KC5rZWVwX2FsbD1UUlVFKSAlPiUgCiAgZmlsdGVyKCFCSU9UWVBFJWluJWMoInByb3RlaW5fY29kaW5nIikpICU+JSAKICBhcnJhbmdlKFNZTUJPTCkKCnZvbGNhbm8gPC0gZnVuY3Rpb24odmNmLGdlbmVfbGlzdCxHbm9tQUQsVG90YWxfU2FtcGxlX0FsbGVsZXMpewogIHdhdGVyIDwtIHZjZiAlPiUgCiAgbXV0YXRlKFRvdGFsX0Nhc2VfQWxsZWxlcz1Ub3RhbF9TYW1wbGVfQWxsZWxlcykgJT4lIAogIHNlbGVjdChTWU1CT0wsR2VuZSxUb3RhbF9HZW5lX0NvdW50LFRvdGFsX0Nhc2VfQWxsZWxlcykgJT4lIAogIGRpc3RpbmN0KFNZTUJPTCxHZW5lLFRvdGFsX0dlbmVfQ291bnQsVG90YWxfQ2FzZV9BbGxlbGVzKSAKICB3YXRlcjIgPC0gYmluZF9yb3dzKHdhdGVyLCBhbnRpX2pvaW4oZ2VuZV9saXN0LHdhdGVyLGJ5PSJHZW5lIikpICU+JSAKICBtdXRhdGVfYXQodmFycygiVG90YWxfR2VuZV9Db3VudCIpLGZ1bnMocmVwbGFjZSguLCBpcy5uYSguKSwgMCkpKSAlPiUgCiAgbXV0YXRlX2F0KHZhcnMoIlRvdGFsX0Nhc2VfQWxsZWxlcyIpLGZ1bnMocmVwbGFjZSguLCBpcy5uYSguKSwgVG90YWxfU2FtcGxlX0FsbGVsZXMpKSkKICB3YXRlcjMgPC0gcmlnaHRfam9pbih3YXRlcjIsR25vbUFELGJ5PSJHZW5lIixjb3B5PUZBTFNFKSAlPiUgCiAgc2VsZWN0KCJTWU1CT0wueCIsIkdlbmUiLCJUb3RhbF9HZW5lX0NvdW50IiwiVG90YWxfQ2FzZV9BbGxlbGVzIiwiRklMVEVSX1JGX0xPRl9ISUdISU1QQUNUX0FDXzAuMDA1IiwiRklMVEVSX1JGX0xPRl9ISUdISU1QQUNUX0FDXzAuMDA1X05GRSIsIk1BWF9BTiIsIk1BWF9BTl9ORkUiLCJGSUxURVJfUkZfTE9GX0hJR0hJTVBBQ1RfQUZfMC4wMDVfQURKIiwiRklMVEVSX1JGX0xPRl9ISUdISU1QQUNUX0FGXzAuMDA1X05GRV9BREoiKSAlPiUgCiAgZHBseXI6OnJlbmFtZSgiU1lNQk9MIj0iU1lNQk9MLngiKSAlPiUKICBtdXRhdGUoRklMVEVSX1JGX0xPRl9ISUdISU1QQUNUX0FDXzAuMDA1X0FESj1yb3VuZCgoTUFYX0FOKkZJTFRFUl9SRl9MT0ZfSElHSElNUEFDVF9BRl8wLjAwNV9BREopKSkgJT4lIAogIG11dGF0ZShGSUxURVJfUkZfTE9GX0hJR0hJTVBBQ1RfQUNfMC4wMDVfTkZFX0FESj1yb3VuZCgoTUFYX0FOX05GRSpGSUxURVJfUkZfTE9GX0hJR0hJTVBBQ1RfQUZfMC4wMDVfTkZFX0FESikpKSAlPiUgCiAgZGlzdGluY3QoLmtlZXBfYWxsPVRSVUUpCiAgcmV0dXJuKHdhdGVyMykKfQoKdm9sY2Fub19hZ2VVbmRlcjYwX3NhbXBsZUFGMC4wMV9hbGxHZW5lcyA8LSB2b2xjYW5vKG1hc3RlcmZpbGVfZW9jX2FnZVVuZGVyNjBfZ29vZFEyX0hJR0hfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX3JhdGlvcyxhbGxHZW5lc19BZ2lsZW50U1N2Nl9saXN0LEdub21BRF9zdGF0c19BZ2lsZW50U1N2Nl9MT0ZfVkVQX0VOU1RjYW5vbmljYWxfYWxsLFRvdGFsX1NhbXBsZV9BbGxlbGVzX2FnZVVuZGVyNjApCgp2b2xjYW5vX2FnZVVuZGVyNjBfc2FtcGxlQUYwLjAxX2Jpb3R5cGVfYWxsR2VuZXMgPC0gdm9sY2FubyhtYXN0ZXJmaWxlX2VvY19hZ2VVbmRlcjYwX2dvb2RRMl9ISUdIX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19yYXRpb3MsYWxsR2VuZXNfQWdpbGVudFNTdjZfbGlzdF9wcm90ZWluX2NvZGluZ19vbmx5LEdub21BRF9zdGF0c19BZ2lsZW50U1N2Nl9MT0ZfVkVQX0VOU1RjYW5vbmljYWxfcHJvdGVpbl9jb2RpbmcsVG90YWxfU2FtcGxlX0FsbGVsZXNfYWdlVW5kZXI2MCkKCnZvbGNhbm9fYWdlVW5kZXI2MF9zYW1wbGVBRjAuMDFfYmlvdHlwZTJfYWxsR2VuZXMgPC0gdm9sY2FubyhtYXN0ZXJmaWxlX2VvY19hZ2VVbmRlcjYwX2dvb2RRMl9ISUdIX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19yYXRpb3MsYWxsR2VuZXNfQWdpbGVudFNTdjZfbGlzdF9ub25fcHJvdGVpbl9jb2Rpbmdfb25seSxHbm9tQURfc3RhdHNfQWdpbGVudFNTdjZfTE9GX1ZFUF9FTlNUY2Fub25pY2FsX25vbl9wcm90ZWluX2NvZGluZyxUb3RhbF9TYW1wbGVfQWxsZWxlc19hZ2VVbmRlcjYwKQoKdm9sY2Fub19hZ2VPdmVyNjBfc2FtcGxlQUYwLjAxX2FsbEdlbmVzIDwtIHZvbGNhbm8obWFzdGVyZmlsZV9lb2NfYWdlT3ZlcjYwX2dvb2RRMl9ISUdIX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19yYXRpb3MsYWxsR2VuZXNfQWdpbGVudFNTdjZfbGlzdCxHbm9tQURfc3RhdHNfQWdpbGVudFNTdjZfTE9GX1ZFUF9FTlNUY2Fub25pY2FsX2FsbCxUb3RhbF9TYW1wbGVfQWxsZWxlc19hZ2VPdmVyNjApCgp2b2xjYW5vX2FnZU92ZXI2MF9zYW1wbGVBRjAuMDFfYmlvdHlwZV9hbGxHZW5lcyA8LSB2b2xjYW5vKG1hc3RlcmZpbGVfZW9jX2FnZU92ZXI2MF9nb29kUTJfSElHSF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfcmF0aW9zLGFsbEdlbmVzX0FnaWxlbnRTU3Y2X2xpc3RfcHJvdGVpbl9jb2Rpbmdfb25seSxHbm9tQURfc3RhdHNfQWdpbGVudFNTdjZfTE9GX1ZFUF9FTlNUY2Fub25pY2FsX3Byb3RlaW5fY29kaW5nLFRvdGFsX1NhbXBsZV9BbGxlbGVzX2FnZU92ZXI2MCkKCnZvbGNhbm9fYWdlT3ZlcjYwX3NhbXBsZUFGMC4wMV9iaW90eXBlMl9hbGxHZW5lcyA8LSB2b2xjYW5vKG1hc3RlcmZpbGVfZW9jX2FnZU92ZXI2MF9nb29kUTJfSElHSF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfcmF0aW9zLGFsbEdlbmVzX0FnaWxlbnRTU3Y2X2xpc3Rfbm9uX3Byb3RlaW5fY29kaW5nX29ubHksR25vbUFEX3N0YXRzX0FnaWxlbnRTU3Y2X0xPRl9WRVBfRU5TVGNhbm9uaWNhbF9ub25fcHJvdGVpbl9jb2RpbmcsVG90YWxfU2FtcGxlX0FsbGVsZXNfYWdlT3ZlcjYwKQpgYGAKCkNhbGN1bGF0ZSBGaXNoZXIncyB0ZXN0IHZhbHVlcyAoRW5zZW1ibCBDYW5vbmljYWwpCmBgYHtyfQptYXN0ZXJmaWxlX2VvY19hZ2VVbmRlcjYwX2dvb2RRMl9ISUdIX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19yYXRpb3NfZmlzaGVycmVzdWx0cyA8LSBtdXRhdGUobWFzdGVyZmlsZV9lb2NfYWdlVW5kZXI2MF9nb29kUTJfSElHSF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfcmF0aW9zLFRvdGFsX0Nhc2VfQWxsZWxlcz1Ub3RhbF9TYW1wbGVfQWxsZWxlc19hZ2VVbmRlcjYwKSAlPiUgCiAgbGVmdF9qb2luKEdub21BRF9zdGF0c19MT0ZfVkVQWyxjKDIsNiwxMCwxNDoyOSldLGJ5PSJGZWF0dXJlIixjb3B5PUZBTFNFKSAKbWFzdGVyZmlsZV9lb2NfYWdlVW5kZXI2MF9nb29kUTJfSElHSF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfcmF0aW9zX2Zpc2hlcnJlc3VsdHMyIDwtIG11dGF0ZShtYXN0ZXJmaWxlX2VvY19hZ2VVbmRlcjYwX2dvb2RRMl9ISUdIX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19yYXRpb3NfZmlzaGVycmVzdWx0cywgTUFYX0FOPXJlcGxhY2UobWFzdGVyZmlsZV9lb2NfYWdlVW5kZXI2MF9nb29kUTJfSElHSF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfcmF0aW9zX2Zpc2hlcnJlc3VsdHMkTUFYX0FOLCBpcy5uYShtYXN0ZXJmaWxlX2VvY19hZ2VVbmRlcjYwX2dvb2RRMl9ISUdIX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19yYXRpb3NfZmlzaGVycmVzdWx0cyRNQVhfQU4pLCBtYXgobWFzdGVyZmlsZV9lb2NfYWdlVW5kZXI2MF9nb29kUTJfSElHSF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfcmF0aW9zX2Zpc2hlcnJlc3VsdHMkTUFYX0FOLCBuYS5ybT1UUlVFKSkpICU+JSAKICBtdXRhdGUoTUFYX0FOX05GRT1yZXBsYWNlKC4kTUFYX0FOX05GRSwgaXMubmEoLiRNQVhfQU5fTkZFKSwgbWF4KG1hc3RlcmZpbGVfZW9jX2FnZVVuZGVyNjBfZ29vZFEyX0hJR0hfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX3JhdGlvc19maXNoZXJyZXN1bHRzJE1BWF9BTl9ORkUsIG5hLnJtPVRSVUUpKSkKCmZpc2hlcnJlc3VsdHNfRU5TVCA8LSBhcHBseShtYXN0ZXJmaWxlX2VvY19hZ2VVbmRlcjYwX2dvb2RRMl9ISUdIX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19yYXRpb3NfZmlzaGVycmVzdWx0czJbLGMoMjIxLDIyOSwyNDMsMjQ0KV0sMSxmdW5jdGlvbih4KSB7ZmlzaGVyLnRlc3QocmJpbmQoeFsxOjJdLGMoeFszXS14WzFdLHhbNF0teFsyXSkpKX0pCgptYXN0ZXJmaWxlX2VvY19hZ2VVbmRlcjYwX2dvb2RRMl9ISUdIX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19yYXRpb3NfZmlzaGVycmVzdWx0czIkUF92YWx1ZV9GaXNoZXJfMC4wMDUgPSBzYXBwbHkoZmlzaGVycmVzdWx0c19FTlNULGZ1bmN0aW9uKHgpIHJvdW5kKHgkcC52YWx1ZSwxMikpCm1hc3RlcmZpbGVfZW9jX2FnZVVuZGVyNjBfZ29vZFEyX0hJR0hfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX3JhdGlvc19maXNoZXJyZXN1bHRzMiRPUl8wLjAwNSA9IHNhcHBseShmaXNoZXJyZXN1bHRzX0VOU1QsZnVuY3Rpb24oeCkgcm91bmQoeCRlc3RpbWF0ZSw0KSkKbWFzdGVyZmlsZV9lb2NfYWdlVW5kZXI2MF9nb29kUTJfSElHSF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfcmF0aW9zX2Zpc2hlcnJlc3VsdHMyJGA5NSVDSV8wLjAwNWAgPSBzYXBwbHkoZmlzaGVycmVzdWx0c19FTlNULGZ1bmN0aW9uKHgpIHBhc3RlKHJvdW5kKHgkY29uZi5pbnRbMToyXSwyKSxjb2xsYXBzZT0ifiIpKQptYXN0ZXJmaWxlX2VvY19hZ2VVbmRlcjYwX2dvb2RRMl9ISUdIX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19yYXRpb3NfZmlzaGVycmVzdWx0czIkQkhfMC4wMDUgPSBwLmFkanVzdChtYXN0ZXJmaWxlX2VvY19hZ2VVbmRlcjYwX2dvb2RRMl9ISUdIX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19yYXRpb3NfZmlzaGVycmVzdWx0czIkUF92YWx1ZV9GaXNoZXJfMC4wMDUsbWV0aG9kID0gIkJIIikKCmZpc2hlcnJlc3VsdHMyX0VOU1QgPC0gYXBwbHkobWFzdGVyZmlsZV9lb2NfYWdlVW5kZXI2MF9nb29kUTJfSElHSF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfcmF0aW9zX2Zpc2hlcnJlc3VsdHMyWyxjKDIyMSwyMzIsMjQzLDI0NSldLDEsZnVuY3Rpb24oeCkge2Zpc2hlci50ZXN0KHJiaW5kKHhbMToyXSxjKHhbM10teFsxXSx4WzRdLXhbMl0pKSl9KQoKbWFzdGVyZmlsZV9lb2NfYWdlVW5kZXI2MF9nb29kUTJfSElHSF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfcmF0aW9zX2Zpc2hlcnJlc3VsdHMyJFBfdmFsdWVfRmlzaGVyXzAuMDA1X05GRSA9IHNhcHBseShmaXNoZXJyZXN1bHRzMl9FTlNULGZ1bmN0aW9uKHgpIHJvdW5kKHgkcC52YWx1ZSwxMikpCm1hc3RlcmZpbGVfZW9jX2FnZVVuZGVyNjBfZ29vZFEyX0hJR0hfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX3JhdGlvc19maXNoZXJyZXN1bHRzMiRPUl8wLjAwNV9ORkUgPSBzYXBwbHkoZmlzaGVycmVzdWx0czJfRU5TVCxmdW5jdGlvbih4KSByb3VuZCh4JGVzdGltYXRlLDQpKQptYXN0ZXJmaWxlX2VvY19hZ2VVbmRlcjYwX2dvb2RRMl9ISUdIX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19yYXRpb3NfZmlzaGVycmVzdWx0czIkYDk1JUNJXzAuMDA1X05GRWAgPSBzYXBwbHkoZmlzaGVycmVzdWx0czJfRU5TVCxmdW5jdGlvbih4KSBwYXN0ZShyb3VuZCh4JGNvbmYuaW50WzE6Ml0sMiksY29sbGFwc2U9In4iKSkKbWFzdGVyZmlsZV9lb2NfYWdlVW5kZXI2MF9nb29kUTJfSElHSF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfcmF0aW9zX2Zpc2hlcnJlc3VsdHMyJEJIXzAuMDA1X05GRSA9IHAuYWRqdXN0KG1hc3RlcmZpbGVfZW9jX2FnZVVuZGVyNjBfZ29vZFEyX0hJR0hfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX3JhdGlvc19maXNoZXJyZXN1bHRzMiRQX3ZhbHVlX0Zpc2hlcl8wLjAwNV9ORkUsbWV0aG9kID0gIkJIIikKCm1hc3RlcmZpbGVfZW9jX2FnZU92ZXI2MF9nb29kUTJfSElHSF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfcmF0aW9zX2Zpc2hlcnJlc3VsdHMgPC0gbXV0YXRlKG1hc3RlcmZpbGVfZW9jX2FnZU92ZXI2MF9nb29kUTJfSElHSF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfcmF0aW9zLFRvdGFsX0Nhc2VfQWxsZWxlcz1Ub3RhbF9TYW1wbGVfQWxsZWxlc19hZ2VPdmVyNjApICU+JSAKICBsZWZ0X2pvaW4oR25vbUFEX3N0YXRzX0xPRl9WRVBbLGMoMiw2LDEwLDE0OjI5KV0sYnk9IkZlYXR1cmUiLGNvcHk9RkFMU0UpIAptYXN0ZXJmaWxlX2VvY19hZ2VPdmVyNjBfZ29vZFEyX0hJR0hfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX3JhdGlvc19maXNoZXJyZXN1bHRzMiA8LSBtdXRhdGUobWFzdGVyZmlsZV9lb2NfYWdlT3ZlcjYwX2dvb2RRMl9ISUdIX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19yYXRpb3NfZmlzaGVycmVzdWx0cywgTUFYX0FOPXJlcGxhY2UobWFzdGVyZmlsZV9lb2NfYWdlT3ZlcjYwX2dvb2RRMl9ISUdIX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19yYXRpb3NfZmlzaGVycmVzdWx0cyRNQVhfQU4sIGlzLm5hKG1hc3RlcmZpbGVfZW9jX2FnZU92ZXI2MF9nb29kUTJfSElHSF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfcmF0aW9zX2Zpc2hlcnJlc3VsdHMkTUFYX0FOKSwgbWF4KG1hc3RlcmZpbGVfZW9jX2FnZU92ZXI2MF9nb29kUTJfSElHSF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfcmF0aW9zX2Zpc2hlcnJlc3VsdHMkTUFYX0FOLCBuYS5ybT1UUlVFKSkpICU+JSAKICBtdXRhdGUoTUFYX0FOX05GRT1yZXBsYWNlKC4kTUFYX0FOX05GRSwgaXMubmEoLiRNQVhfQU5fTkZFKSwgbWF4KG1hc3RlcmZpbGVfZW9jX2FnZU92ZXI2MF9nb29kUTJfSElHSF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfcmF0aW9zX2Zpc2hlcnJlc3VsdHMkTUFYX0FOX05GRSwgbmEucm09VFJVRSkpKQoKZmlzaGVycmVzdWx0c19FTlNUIDwtIGFwcGx5KG1hc3RlcmZpbGVfZW9jX2FnZU92ZXI2MF9nb29kUTJfSElHSF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfcmF0aW9zX2Zpc2hlcnJlc3VsdHMyWyxjKDIyMSwyMjksMjQzLDI0NCldLDEsZnVuY3Rpb24oeCkge2Zpc2hlci50ZXN0KHJiaW5kKHhbMToyXSxjKHhbM10teFsxXSx4WzRdLXhbMl0pKSl9KQoKbWFzdGVyZmlsZV9lb2NfYWdlT3ZlcjYwX2dvb2RRMl9ISUdIX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19yYXRpb3NfZmlzaGVycmVzdWx0czIkUF92YWx1ZV9GaXNoZXJfMC4wMDUgPSBzYXBwbHkoZmlzaGVycmVzdWx0c19FTlNULGZ1bmN0aW9uKHgpIHJvdW5kKHgkcC52YWx1ZSwxMikpCm1hc3RlcmZpbGVfZW9jX2FnZU92ZXI2MF9nb29kUTJfSElHSF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfcmF0aW9zX2Zpc2hlcnJlc3VsdHMyJE9SXzAuMDA1ID0gc2FwcGx5KGZpc2hlcnJlc3VsdHNfRU5TVCxmdW5jdGlvbih4KSByb3VuZCh4JGVzdGltYXRlLDQpKQptYXN0ZXJmaWxlX2VvY19hZ2VPdmVyNjBfZ29vZFEyX0hJR0hfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX3JhdGlvc19maXNoZXJyZXN1bHRzMiRgOTUlQ0lfMC4wMDVgID0gc2FwcGx5KGZpc2hlcnJlc3VsdHNfRU5TVCxmdW5jdGlvbih4KSBwYXN0ZShyb3VuZCh4JGNvbmYuaW50WzE6Ml0sMiksY29sbGFwc2U9In4iKSkKbWFzdGVyZmlsZV9lb2NfYWdlT3ZlcjYwX2dvb2RRMl9ISUdIX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19yYXRpb3NfZmlzaGVycmVzdWx0czIkQkhfMC4wMDUgPSBwLmFkanVzdChtYXN0ZXJmaWxlX2VvY19hZ2VPdmVyNjBfZ29vZFEyX0hJR0hfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX3JhdGlvc19maXNoZXJyZXN1bHRzMiRQX3ZhbHVlX0Zpc2hlcl8wLjAwNSxtZXRob2QgPSAiQkgiKQoKZmlzaGVycmVzdWx0czJfRU5TVCA8LSBhcHBseShtYXN0ZXJmaWxlX2VvY19hZ2VPdmVyNjBfZ29vZFEyX0hJR0hfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX3JhdGlvc19maXNoZXJyZXN1bHRzMlssYygyMjEsMjMyLDI0MywyNDUpXSwxLGZ1bmN0aW9uKHgpIHtmaXNoZXIudGVzdChyYmluZCh4WzE6Ml0sYyh4WzNdLXhbMV0seFs0XS14WzJdKSkpfSkKCm1hc3RlcmZpbGVfZW9jX2FnZU92ZXI2MF9nb29kUTJfSElHSF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfcmF0aW9zX2Zpc2hlcnJlc3VsdHMyJFBfdmFsdWVfRmlzaGVyXzAuMDA1X05GRSA9IHNhcHBseShmaXNoZXJyZXN1bHRzMl9FTlNULGZ1bmN0aW9uKHgpIHJvdW5kKHgkcC52YWx1ZSwxMikpCm1hc3RlcmZpbGVfZW9jX2FnZU92ZXI2MF9nb29kUTJfSElHSF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfcmF0aW9zX2Zpc2hlcnJlc3VsdHMyJE9SXzAuMDA1X05GRSA9IHNhcHBseShmaXNoZXJyZXN1bHRzMl9FTlNULGZ1bmN0aW9uKHgpIHJvdW5kKHgkZXN0aW1hdGUsNCkpCm1hc3RlcmZpbGVfZW9jX2FnZU92ZXI2MF9nb29kUTJfSElHSF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfcmF0aW9zX2Zpc2hlcnJlc3VsdHMyJGA5NSVDSV8wLjAwNV9ORkVgID0gc2FwcGx5KGZpc2hlcnJlc3VsdHMyX0VOU1QsZnVuY3Rpb24oeCkgcGFzdGUocm91bmQoeCRjb25mLmludFsxOjJdLDIpLGNvbGxhcHNlPSJ+IikpCm1hc3RlcmZpbGVfZW9jX2FnZU92ZXI2MF9nb29kUTJfSElHSF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfcmF0aW9zX2Zpc2hlcnJlc3VsdHMyJEJIXzAuMDA1X05GRSA9IHAuYWRqdXN0KG1hc3RlcmZpbGVfZW9jX2FnZU92ZXI2MF9nb29kUTJfSElHSF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfcmF0aW9zX2Zpc2hlcnJlc3VsdHMyJFBfdmFsdWVfRmlzaGVyXzAuMDA1X05GRSxtZXRob2QgPSAiQkgiKQpgYGAKCkNhbGN1bGF0ZSBGaXNoZXIncyB0ZXN0IHZhbHVlcyAoUmVmU2VxIENhbm9uaWNhbCkKYGBge3J9Cm1hc3RlcmZpbGVfZW9jX2FnZVVuZGVyNjBfZ29vZFEyX0hJR0hfTk1jYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19yYXRpb3NfZmlzaGVycmVzdWx0cyA8LSBtdXRhdGUobWFzdGVyZmlsZV9lb2NfYWdlVW5kZXI2MF9nb29kUTJfSElHSF9OTWNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX3JhdGlvcyxUb3RhbF9DYXNlX0FsbGVsZXM9VG90YWxfU2FtcGxlX0FsbGVsZXNfYWdlVW5kZXI2MCkgJT4lIAogIGxlZnRfam9pbihHbm9tQURfc3RhdHNfTE9GX1ZFUFssYygyLDYsMTAsMTQ6MjkpXSxieT0iRmVhdHVyZSIsY29weT1GQUxTRSkgCm1hc3RlcmZpbGVfZW9jX2FnZVVuZGVyNjBfZ29vZFEyX0hJR0hfTk1jYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19yYXRpb3NfZmlzaGVycmVzdWx0czIgPC0gbXV0YXRlKG1hc3RlcmZpbGVfZW9jX2FnZVVuZGVyNjBfZ29vZFEyX0hJR0hfTk1jYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19yYXRpb3NfZmlzaGVycmVzdWx0cywgTUFYX0FOPXJlcGxhY2UobWFzdGVyZmlsZV9lb2NfYWdlVW5kZXI2MF9nb29kUTJfSElHSF9OTWNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX3JhdGlvc19maXNoZXJyZXN1bHRzJE1BWF9BTiwgaXMubmEobWFzdGVyZmlsZV9lb2NfYWdlVW5kZXI2MF9nb29kUTJfSElHSF9OTWNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX3JhdGlvc19maXNoZXJyZXN1bHRzJE1BWF9BTiksIG1heChtYXN0ZXJmaWxlX2VvY19hZ2VVbmRlcjYwX2dvb2RRMl9ISUdIX05NY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfcmF0aW9zX2Zpc2hlcnJlc3VsdHMkTUFYX0FOLCBuYS5ybT1UUlVFKSkpICU+JSAKICBtdXRhdGUoTUFYX0FOX05GRT1yZXBsYWNlKC4kTUFYX0FOX05GRSwgaXMubmEoLiRNQVhfQU5fTkZFKSwgbWF4KG1hc3RlcmZpbGVfZW9jX2FnZVVuZGVyNjBfZ29vZFEyX0hJR0hfTk1jYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19yYXRpb3NfZmlzaGVycmVzdWx0cyRNQVhfQU5fTkZFLCBuYS5ybT1UUlVFKSkpCgpmaXNoZXJyZXN1bHRzX05NIDwtIGFwcGx5KG1hc3RlcmZpbGVfZW9jX2FnZVVuZGVyNjBfZ29vZFEyX0hJR0hfTk1jYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19yYXRpb3NfZmlzaGVycmVzdWx0czJbLGMoMjIxLDIyOSwyNDMsMjQ0KV0sMSxmdW5jdGlvbih4KSB7ZmlzaGVyLnRlc3QocmJpbmQoeFsxOjJdLGMoeFszXS14WzFdLHhbNF0teFsyXSkpKX0pCgptYXN0ZXJmaWxlX2VvY19hZ2VVbmRlcjYwX2dvb2RRMl9ISUdIX05NY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfcmF0aW9zX2Zpc2hlcnJlc3VsdHMyJFBfdmFsdWVfRmlzaGVyXzAuMDA1ID0gc2FwcGx5KGZpc2hlcnJlc3VsdHNfTk0sZnVuY3Rpb24oeCkgcm91bmQoeCRwLnZhbHVlLDEyKSkKbWFzdGVyZmlsZV9lb2NfYWdlVW5kZXI2MF9nb29kUTJfSElHSF9OTWNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX3JhdGlvc19maXNoZXJyZXN1bHRzMiRPUl8wLjAwNSA9IHNhcHBseShmaXNoZXJyZXN1bHRzX05NLGZ1bmN0aW9uKHgpIHJvdW5kKHgkZXN0aW1hdGUsNCkpCm1hc3RlcmZpbGVfZW9jX2FnZVVuZGVyNjBfZ29vZFEyX0hJR0hfTk1jYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19yYXRpb3NfZmlzaGVycmVzdWx0czIkYDk1JUNJXzAuMDA1YCA9IHNhcHBseShmaXNoZXJyZXN1bHRzX05NLGZ1bmN0aW9uKHgpIHBhc3RlKHJvdW5kKHgkY29uZi5pbnRbMToyXSwyKSxjb2xsYXBzZT0ifiIpKQptYXN0ZXJmaWxlX2VvY19hZ2VVbmRlcjYwX2dvb2RRMl9ISUdIX05NY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfcmF0aW9zX2Zpc2hlcnJlc3VsdHMyJEJIXzAuMDA1ID0gcC5hZGp1c3QobWFzdGVyZmlsZV9lb2NfYWdlVW5kZXI2MF9nb29kUTJfSElHSF9OTWNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX3JhdGlvc19maXNoZXJyZXN1bHRzMiRQX3ZhbHVlX0Zpc2hlcl8wLjAwNSxtZXRob2QgPSAiQkgiKQoKZmlzaGVycmVzdWx0czJfTk0gPC0gYXBwbHkobWFzdGVyZmlsZV9lb2NfYWdlVW5kZXI2MF9nb29kUTJfSElHSF9OTWNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX3JhdGlvc19maXNoZXJyZXN1bHRzMlssYygyMjEsMjMyLDI0MywyNDUpXSwxLGZ1bmN0aW9uKHgpIHtmaXNoZXIudGVzdChyYmluZCh4WzE6Ml0sYyh4WzNdLXhbMV0seFs0XS14WzJdKSkpfSkKCm1hc3RlcmZpbGVfZW9jX2FnZVVuZGVyNjBfZ29vZFEyX0hJR0hfTk1jYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19yYXRpb3NfZmlzaGVycmVzdWx0czIkUF92YWx1ZV9GaXNoZXJfMC4wMDVfTkZFID0gc2FwcGx5KGZpc2hlcnJlc3VsdHMyX05NLGZ1bmN0aW9uKHgpIHJvdW5kKHgkcC52YWx1ZSwxMikpCm1hc3RlcmZpbGVfZW9jX2FnZVVuZGVyNjBfZ29vZFEyX0hJR0hfTk1jYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19yYXRpb3NfZmlzaGVycmVzdWx0czIkT1JfMC4wMDVfTkZFID0gc2FwcGx5KGZpc2hlcnJlc3VsdHMyX05NLGZ1bmN0aW9uKHgpIHJvdW5kKHgkZXN0aW1hdGUsNCkpCm1hc3RlcmZpbGVfZW9jX2FnZVVuZGVyNjBfZ29vZFEyX0hJR0hfTk1jYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19yYXRpb3NfZmlzaGVycmVzdWx0czIkYDk1JUNJXzAuMDA1X05GRWAgPSBzYXBwbHkoZmlzaGVycmVzdWx0czJfTk0sZnVuY3Rpb24oeCkgcGFzdGUocm91bmQoeCRjb25mLmludFsxOjJdLDIpLGNvbGxhcHNlPSJ+IikpCm1hc3RlcmZpbGVfZW9jX2FnZVVuZGVyNjBfZ29vZFEyX0hJR0hfTk1jYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19yYXRpb3NfZmlzaGVycmVzdWx0czIkQkhfMC4wMDVfTkZFID0gcC5hZGp1c3QobWFzdGVyZmlsZV9lb2NfYWdlVW5kZXI2MF9nb29kUTJfSElHSF9OTWNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX3JhdGlvc19maXNoZXJyZXN1bHRzMiRQX3ZhbHVlX0Zpc2hlcl8wLjAwNV9ORkUsbWV0aG9kID0gIkJIIikKCm1hc3RlcmZpbGVfZW9jX2FnZU92ZXI2MF9nb29kUTJfSElHSF9OTWNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX3JhdGlvc19maXNoZXJyZXN1bHRzIDwtIG11dGF0ZShtYXN0ZXJmaWxlX2VvY19hZ2VPdmVyNjBfZ29vZFEyX0hJR0hfTk1jYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19yYXRpb3MsVG90YWxfQ2FzZV9BbGxlbGVzPVRvdGFsX1NhbXBsZV9BbGxlbGVzX2FnZU92ZXI2MCkgJT4lIAogIGxlZnRfam9pbihHbm9tQURfc3RhdHNfTE9GX1ZFUFssYygyLDYsMTAsMTQ6MjkpXSxieT0iRmVhdHVyZSIsY29weT1GQUxTRSkgCm1hc3RlcmZpbGVfZW9jX2FnZU92ZXI2MF9nb29kUTJfSElHSF9OTWNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX3JhdGlvc19maXNoZXJyZXN1bHRzMiA8LSBtdXRhdGUobWFzdGVyZmlsZV9lb2NfYWdlT3ZlcjYwX2dvb2RRMl9ISUdIX05NY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfcmF0aW9zX2Zpc2hlcnJlc3VsdHMsIE1BWF9BTj1yZXBsYWNlKG1hc3RlcmZpbGVfZW9jX2FnZU92ZXI2MF9nb29kUTJfSElHSF9OTWNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX3JhdGlvc19maXNoZXJyZXN1bHRzJE1BWF9BTiwgaXMubmEobWFzdGVyZmlsZV9lb2NfYWdlT3ZlcjYwX2dvb2RRMl9ISUdIX05NY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfcmF0aW9zX2Zpc2hlcnJlc3VsdHMkTUFYX0FOKSwgbWF4KG1hc3RlcmZpbGVfZW9jX2FnZU92ZXI2MF9nb29kUTJfSElHSF9OTWNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX3JhdGlvc19maXNoZXJyZXN1bHRzJE1BWF9BTiwgbmEucm09VFJVRSkpKSAlPiUgCiAgbXV0YXRlKE1BWF9BTl9ORkU9cmVwbGFjZSguJE1BWF9BTl9ORkUsIGlzLm5hKC4kTUFYX0FOX05GRSksIG1heChtYXN0ZXJmaWxlX2VvY19hZ2VPdmVyNjBfZ29vZFEyX0hJR0hfTk1jYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19yYXRpb3NfZmlzaGVycmVzdWx0cyRNQVhfQU5fTkZFLCBuYS5ybT1UUlVFKSkpCgpmaXNoZXJyZXN1bHRzX05NIDwtIGFwcGx5KG1hc3RlcmZpbGVfZW9jX2FnZU92ZXI2MF9nb29kUTJfSElHSF9OTWNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX3JhdGlvc19maXNoZXJyZXN1bHRzMlssYygyMjEsMjI5LDI0MywyNDQpXSwxLGZ1bmN0aW9uKHgpIHtmaXNoZXIudGVzdChyYmluZCh4WzE6Ml0sYyh4WzNdLXhbMV0seFs0XS14WzJdKSkpfSkKCm1hc3RlcmZpbGVfZW9jX2FnZU92ZXI2MF9nb29kUTJfSElHSF9OTWNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX3JhdGlvc19maXNoZXJyZXN1bHRzMiRQX3ZhbHVlX0Zpc2hlcl8wLjAwNSA9IHNhcHBseShmaXNoZXJyZXN1bHRzX05NLGZ1bmN0aW9uKHgpIHJvdW5kKHgkcC52YWx1ZSwxMikpCm1hc3RlcmZpbGVfZW9jX2FnZU92ZXI2MF9nb29kUTJfSElHSF9OTWNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX3JhdGlvc19maXNoZXJyZXN1bHRzMiRPUl8wLjAwNSA9IHNhcHBseShmaXNoZXJyZXN1bHRzX05NLGZ1bmN0aW9uKHgpIHJvdW5kKHgkZXN0aW1hdGUsNCkpCm1hc3RlcmZpbGVfZW9jX2FnZU92ZXI2MF9nb29kUTJfSElHSF9OTWNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX3JhdGlvc19maXNoZXJyZXN1bHRzMiRgOTUlQ0lfMC4wMDVgID0gc2FwcGx5KGZpc2hlcnJlc3VsdHNfTk0sZnVuY3Rpb24oeCkgcGFzdGUocm91bmQoeCRjb25mLmludFsxOjJdLDIpLGNvbGxhcHNlPSJ+IikpCm1hc3RlcmZpbGVfZW9jX2FnZU92ZXI2MF9nb29kUTJfSElHSF9OTWNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX3JhdGlvc19maXNoZXJyZXN1bHRzMiRCSF8wLjAwNSA9IHAuYWRqdXN0KG1hc3RlcmZpbGVfZW9jX2FnZU92ZXI2MF9nb29kUTJfSElHSF9OTWNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX3JhdGlvc19maXNoZXJyZXN1bHRzMiRQX3ZhbHVlX0Zpc2hlcl8wLjAwNSxtZXRob2QgPSAiQkgiKQoKZmlzaGVycmVzdWx0czJfTk0gPC0gYXBwbHkobWFzdGVyZmlsZV9lb2NfYWdlT3ZlcjYwX2dvb2RRMl9ISUdIX05NY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfcmF0aW9zX2Zpc2hlcnJlc3VsdHMyWyxjKDIyMSwyMzIsMjQzLDI0NSldLDEsZnVuY3Rpb24oeCkge2Zpc2hlci50ZXN0KHJiaW5kKHhbMToyXSxjKHhbM10teFsxXSx4WzRdLXhbMl0pKSl9KQoKbWFzdGVyZmlsZV9lb2NfYWdlT3ZlcjYwX2dvb2RRMl9ISUdIX05NY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfcmF0aW9zX2Zpc2hlcnJlc3VsdHMyJFBfdmFsdWVfRmlzaGVyXzAuMDA1X05GRSA9IHNhcHBseShmaXNoZXJyZXN1bHRzMl9OTSxmdW5jdGlvbih4KSByb3VuZCh4JHAudmFsdWUsMTIpKQptYXN0ZXJmaWxlX2VvY19hZ2VPdmVyNjBfZ29vZFEyX0hJR0hfTk1jYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19yYXRpb3NfZmlzaGVycmVzdWx0czIkT1JfMC4wMDVfTkZFID0gc2FwcGx5KGZpc2hlcnJlc3VsdHMyX05NLGZ1bmN0aW9uKHgpIHJvdW5kKHgkZXN0aW1hdGUsNCkpCm1hc3RlcmZpbGVfZW9jX2FnZU92ZXI2MF9nb29kUTJfSElHSF9OTWNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX3JhdGlvc19maXNoZXJyZXN1bHRzMiRgOTUlQ0lfMC4wMDVfTkZFYCA9IHNhcHBseShmaXNoZXJyZXN1bHRzMl9OTSxmdW5jdGlvbih4KSBwYXN0ZShyb3VuZCh4JGNvbmYuaW50WzE6Ml0sMiksY29sbGFwc2U9In4iKSkKbWFzdGVyZmlsZV9lb2NfYWdlT3ZlcjYwX2dvb2RRMl9ISUdIX05NY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfcmF0aW9zX2Zpc2hlcnJlc3VsdHMyJEJIXzAuMDA1X05GRSA9IHAuYWRqdXN0KG1hc3RlcmZpbGVfZW9jX2FnZU92ZXI2MF9nb29kUTJfSElHSF9OTWNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX3JhdGlvc19maXNoZXJyZXN1bHRzMiRQX3ZhbHVlX0Zpc2hlcl8wLjAwNV9ORkUsbWV0aG9kID0gIkJIIikKYGBgCgpDYWxjdWxhdGUgRmlzaGVyJ3MgdGVzdCB2YWx1ZXMgKHZvbGNhbm8gcGxvdCkKYGBge3J9CmZpc2hlcnJlc3VsdHNfYWxsR2VuZXNfdm9sY2FubyA8LSBhcHBseSh2b2xjYW5vX2FnZVVuZGVyNjBfc2FtcGxlQUYwLjAxX2FsbEdlbmVzWyxjKDMsNSw0LDcpXSwxLGZ1bmN0aW9uKHgpIHtmaXNoZXIudGVzdChyYmluZCh4WzE6Ml0sYyhhYnMoeFszXS14WzFdKSxhYnMoeFs0XS14WzJdKSkpKX0pCgp2b2xjYW5vX2FnZVVuZGVyNjBfc2FtcGxlQUYwLjAxX2FsbEdlbmVzJFBfdmFsdWVfRmlzaGVyXzAuMDA1ID0gc2FwcGx5KGZpc2hlcnJlc3VsdHNfYWxsR2VuZXNfdm9sY2FubyxmdW5jdGlvbih4KSByb3VuZCh4JHAudmFsdWUsMTUpKQp2b2xjYW5vX2FnZVVuZGVyNjBfc2FtcGxlQUYwLjAxX2FsbEdlbmVzJE9SXzAuMDA1ID0gc2FwcGx5KGZpc2hlcnJlc3VsdHNfYWxsR2VuZXNfdm9sY2FubyxmdW5jdGlvbih4KSByb3VuZCh4JGVzdGltYXRlLDE1KSkKdm9sY2Fub19hZ2VVbmRlcjYwX3NhbXBsZUFGMC4wMV9hbGxHZW5lcyRgOTUlQ0lfMC4wMDVgID0gc2FwcGx5KGZpc2hlcnJlc3VsdHNfYWxsR2VuZXNfdm9sY2FubyxmdW5jdGlvbih4KSBwYXN0ZShyb3VuZCh4JGNvbmYuaW50WzE6Ml0sMiksY29sbGFwc2U9In4iKSkKdm9sY2Fub19hZ2VVbmRlcjYwX3NhbXBsZUFGMC4wMV9hbGxHZW5lcyRCSF8wLjAwNSA9IHAuYWRqdXN0KHZvbGNhbm9fYWdlVW5kZXI2MF9zYW1wbGVBRjAuMDFfYWxsR2VuZXMkUF92YWx1ZV9GaXNoZXJfMC4wMDUsbWV0aG9kID0gIkJIIikKCmZpc2hlcnJlc3VsdHNfTkZFX3ZvbGNhbm8gPC0gYXBwbHkodm9sY2Fub19hZ2VVbmRlcjYwX3NhbXBsZUFGMC4wMV9hbGxHZW5lc1ssYygzLDYsNCw4KV0sMSxmdW5jdGlvbih4KSB7ZmlzaGVyLnRlc3QocmJpbmQoeFsxOjJdLGMoYWJzKHhbM10teFsxXSksYWJzKHhbNF0teFsyXSkpKSl9KQoKdm9sY2Fub19hZ2VVbmRlcjYwX3NhbXBsZUFGMC4wMV9hbGxHZW5lcyRQX3ZhbHVlX0Zpc2hlcl8wLjAwNV9ORkUgPSBzYXBwbHkoZmlzaGVycmVzdWx0c19ORkVfdm9sY2FubyxmdW5jdGlvbih4KSByb3VuZCh4JHAudmFsdWUsMTUpKQp2b2xjYW5vX2FnZVVuZGVyNjBfc2FtcGxlQUYwLjAxX2FsbEdlbmVzJE9SXzAuMDA1X05GRSA9IHNhcHBseShmaXNoZXJyZXN1bHRzX05GRV92b2xjYW5vLGZ1bmN0aW9uKHgpIHJvdW5kKHgkZXN0aW1hdGUsMTUpKQp2b2xjYW5vX2FnZVVuZGVyNjBfc2FtcGxlQUYwLjAxX2FsbEdlbmVzJGA5NSVDSV8wLjAwNV9ORkVgID0gc2FwcGx5KGZpc2hlcnJlc3VsdHNfTkZFX3ZvbGNhbm8sZnVuY3Rpb24oeCkgcGFzdGUocm91bmQoeCRjb25mLmludFsxOjJdLDIpLGNvbGxhcHNlPSJ+IikpCnZvbGNhbm9fYWdlVW5kZXI2MF9zYW1wbGVBRjAuMDFfYWxsR2VuZXMkQkhfMC4wMDVfTkZFID0gcC5hZGp1c3Qodm9sY2Fub19hZ2VVbmRlcjYwX3NhbXBsZUFGMC4wMV9hbGxHZW5lcyRQX3ZhbHVlX0Zpc2hlcl8wLjAwNV9ORkUsbWV0aG9kID0gIkJIIikKCmZpc2hlcnJlc3VsdHNfYmlvdHlwZV9hbGxHZW5lc192b2xjYW5vIDwtIGFwcGx5KHZvbGNhbm9fYWdlVW5kZXI2MF9zYW1wbGVBRjAuMDFfYmlvdHlwZV9hbGxHZW5lc1ssYygzLDUsNCw3KV0sMSxmdW5jdGlvbih4KSB7ZmlzaGVyLnRlc3QocmJpbmQoeFsxOjJdLGMoYWJzKHhbM10teFsxXSksYWJzKHhbNF0teFsyXSkpKSl9KQoKdm9sY2Fub19hZ2VVbmRlcjYwX3NhbXBsZUFGMC4wMV9iaW90eXBlX2FsbEdlbmVzJFBfdmFsdWVfRmlzaGVyXzAuMDA1ID0gc2FwcGx5KGZpc2hlcnJlc3VsdHNfYmlvdHlwZV9hbGxHZW5lc192b2xjYW5vLGZ1bmN0aW9uKHgpIHJvdW5kKHgkcC52YWx1ZSwxNSkpCnZvbGNhbm9fYWdlVW5kZXI2MF9zYW1wbGVBRjAuMDFfYmlvdHlwZV9hbGxHZW5lcyRPUl8wLjAwNSA9IHNhcHBseShmaXNoZXJyZXN1bHRzX2Jpb3R5cGVfYWxsR2VuZXNfdm9sY2FubyxmdW5jdGlvbih4KSByb3VuZCh4JGVzdGltYXRlLDE1KSkKdm9sY2Fub19hZ2VVbmRlcjYwX3NhbXBsZUFGMC4wMV9iaW90eXBlX2FsbEdlbmVzJGA5NSVDSV8wLjAwNWAgPSBzYXBwbHkoZmlzaGVycmVzdWx0c19iaW90eXBlX2FsbEdlbmVzX3ZvbGNhbm8sZnVuY3Rpb24oeCkgcGFzdGUocm91bmQoeCRjb25mLmludFsxOjJdLDIpLGNvbGxhcHNlPSJ+IikpCnZvbGNhbm9fYWdlVW5kZXI2MF9zYW1wbGVBRjAuMDFfYmlvdHlwZV9hbGxHZW5lcyRCSF8wLjAwNSA9IHAuYWRqdXN0KHZvbGNhbm9fYWdlVW5kZXI2MF9zYW1wbGVBRjAuMDFfYmlvdHlwZV9hbGxHZW5lcyRQX3ZhbHVlX0Zpc2hlcl8wLjAwNSxtZXRob2QgPSAiQkgiKQoKZmlzaGVycmVzdWx0c19iaW90eXBlX05GRV92b2xjYW5vIDwtIGFwcGx5KHZvbGNhbm9fYWdlVW5kZXI2MF9zYW1wbGVBRjAuMDFfYmlvdHlwZV9hbGxHZW5lc1ssYygzLDYsNCw4KV0sMSxmdW5jdGlvbih4KSB7ZmlzaGVyLnRlc3QocmJpbmQoeFsxOjJdLGMoYWJzKHhbM10teFsxXSksYWJzKHhbNF0teFsyXSkpKSl9KQoKdm9sY2Fub19hZ2VVbmRlcjYwX3NhbXBsZUFGMC4wMV9iaW90eXBlX2FsbEdlbmVzJFBfdmFsdWVfRmlzaGVyXzAuMDA1X05GRSA9IHNhcHBseShmaXNoZXJyZXN1bHRzX2Jpb3R5cGVfTkZFX3ZvbGNhbm8sZnVuY3Rpb24oeCkgcm91bmQoeCRwLnZhbHVlLDE1KSkKdm9sY2Fub19hZ2VVbmRlcjYwX3NhbXBsZUFGMC4wMV9iaW90eXBlX2FsbEdlbmVzJE9SXzAuMDA1X05GRSA9IHNhcHBseShmaXNoZXJyZXN1bHRzX2Jpb3R5cGVfTkZFX3ZvbGNhbm8sZnVuY3Rpb24oeCkgcm91bmQoeCRlc3RpbWF0ZSwxNSkpCnZvbGNhbm9fYWdlVW5kZXI2MF9zYW1wbGVBRjAuMDFfYmlvdHlwZV9hbGxHZW5lcyRgOTUlQ0lfMC4wMDVfTkZFYCA9IHNhcHBseShmaXNoZXJyZXN1bHRzX2Jpb3R5cGVfTkZFX3ZvbGNhbm8sZnVuY3Rpb24oeCkgcGFzdGUocm91bmQoeCRjb25mLmludFsxOjJdLDIpLGNvbGxhcHNlPSJ+IikpCnZvbGNhbm9fYWdlVW5kZXI2MF9zYW1wbGVBRjAuMDFfYmlvdHlwZV9hbGxHZW5lcyRCSF8wLjAwNV9ORkUgPSBwLmFkanVzdCh2b2xjYW5vX2FnZVVuZGVyNjBfc2FtcGxlQUYwLjAxX2Jpb3R5cGVfYWxsR2VuZXMkUF92YWx1ZV9GaXNoZXJfMC4wMDVfTkZFLG1ldGhvZCA9ICJCSCIpCgpmaXNoZXJyZXN1bHRzX2Jpb3R5cGUyX2FsbEdlbmVzX3ZvbGNhbm8gPC0gYXBwbHkodm9sY2Fub19hZ2VVbmRlcjYwX3NhbXBsZUFGMC4wMV9iaW90eXBlMl9hbGxHZW5lc1ssYygzLDUsNCw3KV0sMSxmdW5jdGlvbih4KSB7ZmlzaGVyLnRlc3QocmJpbmQoeFsxOjJdLGMoYWJzKHhbM10teFsxXSksYWJzKHhbNF0teFsyXSkpKSl9KQoKdm9sY2Fub19hZ2VVbmRlcjYwX3NhbXBsZUFGMC4wMV9iaW90eXBlMl9hbGxHZW5lcyRQX3ZhbHVlX0Zpc2hlcl8wLjAwNSA9IHNhcHBseShmaXNoZXJyZXN1bHRzX2Jpb3R5cGUyX2FsbEdlbmVzX3ZvbGNhbm8sZnVuY3Rpb24oeCkgcm91bmQoeCRwLnZhbHVlLDE1KSkKdm9sY2Fub19hZ2VVbmRlcjYwX3NhbXBsZUFGMC4wMV9iaW90eXBlMl9hbGxHZW5lcyRPUl8wLjAwNSA9IHNhcHBseShmaXNoZXJyZXN1bHRzX2Jpb3R5cGUyX2FsbEdlbmVzX3ZvbGNhbm8sZnVuY3Rpb24oeCkgcm91bmQoeCRlc3RpbWF0ZSwxNSkpCnZvbGNhbm9fYWdlVW5kZXI2MF9zYW1wbGVBRjAuMDFfYmlvdHlwZTJfYWxsR2VuZXMkYDk1JUNJXzAuMDA1YCA9IHNhcHBseShmaXNoZXJyZXN1bHRzX2Jpb3R5cGUyX2FsbEdlbmVzX3ZvbGNhbm8sZnVuY3Rpb24oeCkgcGFzdGUocm91bmQoeCRjb25mLmludFsxOjJdLDIpLGNvbGxhcHNlPSJ+IikpCnZvbGNhbm9fYWdlVW5kZXI2MF9zYW1wbGVBRjAuMDFfYmlvdHlwZTJfYWxsR2VuZXMkQkhfMC4wMDUgPSBwLmFkanVzdCh2b2xjYW5vX2FnZVVuZGVyNjBfc2FtcGxlQUYwLjAxX2Jpb3R5cGUyX2FsbEdlbmVzJFBfdmFsdWVfRmlzaGVyXzAuMDA1LG1ldGhvZCA9ICJCSCIpCgpmaXNoZXJyZXN1bHRzX2Jpb3R5cGUyX05GRV92b2xjYW5vIDwtIGFwcGx5KHZvbGNhbm9fYWdlVW5kZXI2MF9zYW1wbGVBRjAuMDFfYmlvdHlwZTJfYWxsR2VuZXNbLGMoMyw2LDQsOCldLDEsZnVuY3Rpb24oeCkge2Zpc2hlci50ZXN0KHJiaW5kKHhbMToyXSxjKGFicyh4WzNdLXhbMV0pLGFicyh4WzRdLXhbMl0pKSkpfSkKCnZvbGNhbm9fYWdlVW5kZXI2MF9zYW1wbGVBRjAuMDFfYmlvdHlwZTJfYWxsR2VuZXMkUF92YWx1ZV9GaXNoZXJfMC4wMDVfTkZFID0gc2FwcGx5KGZpc2hlcnJlc3VsdHNfYmlvdHlwZTJfTkZFX3ZvbGNhbm8sZnVuY3Rpb24oeCkgcm91bmQoeCRwLnZhbHVlLDE1KSkKdm9sY2Fub19hZ2VVbmRlcjYwX3NhbXBsZUFGMC4wMV9iaW90eXBlMl9hbGxHZW5lcyRPUl8wLjAwNV9ORkUgPSBzYXBwbHkoZmlzaGVycmVzdWx0c19iaW90eXBlMl9ORkVfdm9sY2FubyxmdW5jdGlvbih4KSByb3VuZCh4JGVzdGltYXRlLDE1KSkKdm9sY2Fub19hZ2VVbmRlcjYwX3NhbXBsZUFGMC4wMV9iaW90eXBlMl9hbGxHZW5lcyRgOTUlQ0lfMC4wMDVfTkZFYCA9IHNhcHBseShmaXNoZXJyZXN1bHRzX2Jpb3R5cGUyX05GRV92b2xjYW5vLGZ1bmN0aW9uKHgpIHBhc3RlKHJvdW5kKHgkY29uZi5pbnRbMToyXSwyKSxjb2xsYXBzZT0ifiIpKQp2b2xjYW5vX2FnZVVuZGVyNjBfc2FtcGxlQUYwLjAxX2Jpb3R5cGUyX2FsbEdlbmVzJEJIXzAuMDA1X05GRSA9IHAuYWRqdXN0KHZvbGNhbm9fYWdlVW5kZXI2MF9zYW1wbGVBRjAuMDFfYmlvdHlwZTJfYWxsR2VuZXMkUF92YWx1ZV9GaXNoZXJfMC4wMDVfTkZFLG1ldGhvZCA9ICJCSCIpCgpmaXNoZXJyZXN1bHRzX2FsbEdlbmVzX3ZvbGNhbm8gPC0gYXBwbHkodm9sY2Fub19hZ2VPdmVyNjBfc2FtcGxlQUYwLjAxX2FsbEdlbmVzWyxjKDMsNSw0LDcpXSwxLGZ1bmN0aW9uKHgpIHtmaXNoZXIudGVzdChyYmluZCh4WzE6Ml0sYyhhYnMoeFszXS14WzFdKSxhYnMoeFs0XS14WzJdKSkpKX0pCgp2b2xjYW5vX2FnZU92ZXI2MF9zYW1wbGVBRjAuMDFfYWxsR2VuZXMkUF92YWx1ZV9GaXNoZXJfMC4wMDUgPSBzYXBwbHkoZmlzaGVycmVzdWx0c19hbGxHZW5lc192b2xjYW5vLGZ1bmN0aW9uKHgpIHJvdW5kKHgkcC52YWx1ZSwxNSkpCnZvbGNhbm9fYWdlT3ZlcjYwX3NhbXBsZUFGMC4wMV9hbGxHZW5lcyRPUl8wLjAwNSA9IHNhcHBseShmaXNoZXJyZXN1bHRzX2FsbEdlbmVzX3ZvbGNhbm8sZnVuY3Rpb24oeCkgcm91bmQoeCRlc3RpbWF0ZSwxNSkpCnZvbGNhbm9fYWdlT3ZlcjYwX3NhbXBsZUFGMC4wMV9hbGxHZW5lcyRgOTUlQ0lfMC4wMDVgID0gc2FwcGx5KGZpc2hlcnJlc3VsdHNfYWxsR2VuZXNfdm9sY2FubyxmdW5jdGlvbih4KSBwYXN0ZShyb3VuZCh4JGNvbmYuaW50WzE6Ml0sMiksY29sbGFwc2U9In4iKSkKdm9sY2Fub19hZ2VPdmVyNjBfc2FtcGxlQUYwLjAxX2FsbEdlbmVzJEJIXzAuMDA1ID0gcC5hZGp1c3Qodm9sY2Fub19hZ2VPdmVyNjBfc2FtcGxlQUYwLjAxX2FsbEdlbmVzJFBfdmFsdWVfRmlzaGVyXzAuMDA1LG1ldGhvZCA9ICJCSCIpCgpmaXNoZXJyZXN1bHRzX05GRV92b2xjYW5vIDwtIGFwcGx5KHZvbGNhbm9fYWdlT3ZlcjYwX3NhbXBsZUFGMC4wMV9hbGxHZW5lc1ssYygzLDYsNCw4KV0sMSxmdW5jdGlvbih4KSB7ZmlzaGVyLnRlc3QocmJpbmQoeFsxOjJdLGMoYWJzKHhbM10teFsxXSksYWJzKHhbNF0teFsyXSkpKSl9KQoKdm9sY2Fub19hZ2VPdmVyNjBfc2FtcGxlQUYwLjAxX2FsbEdlbmVzJFBfdmFsdWVfRmlzaGVyXzAuMDA1X05GRSA9IHNhcHBseShmaXNoZXJyZXN1bHRzX05GRV92b2xjYW5vLGZ1bmN0aW9uKHgpIHJvdW5kKHgkcC52YWx1ZSwxNSkpCnZvbGNhbm9fYWdlT3ZlcjYwX3NhbXBsZUFGMC4wMV9hbGxHZW5lcyRPUl8wLjAwNV9ORkUgPSBzYXBwbHkoZmlzaGVycmVzdWx0c19ORkVfdm9sY2FubyxmdW5jdGlvbih4KSByb3VuZCh4JGVzdGltYXRlLDE1KSkKdm9sY2Fub19hZ2VPdmVyNjBfc2FtcGxlQUYwLjAxX2FsbEdlbmVzJGA5NSVDSV8wLjAwNV9ORkVgID0gc2FwcGx5KGZpc2hlcnJlc3VsdHNfTkZFX3ZvbGNhbm8sZnVuY3Rpb24oeCkgcGFzdGUocm91bmQoeCRjb25mLmludFsxOjJdLDIpLGNvbGxhcHNlPSJ+IikpCnZvbGNhbm9fYWdlT3ZlcjYwX3NhbXBsZUFGMC4wMV9hbGxHZW5lcyRCSF8wLjAwNV9ORkUgPSBwLmFkanVzdCh2b2xjYW5vX2FnZU92ZXI2MF9zYW1wbGVBRjAuMDFfYWxsR2VuZXMkUF92YWx1ZV9GaXNoZXJfMC4wMDVfTkZFLG1ldGhvZCA9ICJCSCIpCgpmaXNoZXJyZXN1bHRzX2Jpb3R5cGVfYWxsR2VuZXNfdm9sY2FubyA8LSBhcHBseSh2b2xjYW5vX2FnZU92ZXI2MF9zYW1wbGVBRjAuMDFfYmlvdHlwZV9hbGxHZW5lc1ssYygzLDUsNCw3KV0sMSxmdW5jdGlvbih4KSB7ZmlzaGVyLnRlc3QocmJpbmQoeFsxOjJdLGMoYWJzKHhbM10teFsxXSksYWJzKHhbNF0teFsyXSkpKSl9KQoKdm9sY2Fub19hZ2VPdmVyNjBfc2FtcGxlQUYwLjAxX2Jpb3R5cGVfYWxsR2VuZXMkUF92YWx1ZV9GaXNoZXJfMC4wMDUgPSBzYXBwbHkoZmlzaGVycmVzdWx0c19iaW90eXBlX2FsbEdlbmVzX3ZvbGNhbm8sZnVuY3Rpb24oeCkgcm91bmQoeCRwLnZhbHVlLDE1KSkKdm9sY2Fub19hZ2VPdmVyNjBfc2FtcGxlQUYwLjAxX2Jpb3R5cGVfYWxsR2VuZXMkT1JfMC4wMDUgPSBzYXBwbHkoZmlzaGVycmVzdWx0c19iaW90eXBlX2FsbEdlbmVzX3ZvbGNhbm8sZnVuY3Rpb24oeCkgcm91bmQoeCRlc3RpbWF0ZSwxNSkpCnZvbGNhbm9fYWdlT3ZlcjYwX3NhbXBsZUFGMC4wMV9iaW90eXBlX2FsbEdlbmVzJGA5NSVDSV8wLjAwNWAgPSBzYXBwbHkoZmlzaGVycmVzdWx0c19iaW90eXBlX2FsbEdlbmVzX3ZvbGNhbm8sZnVuY3Rpb24oeCkgcGFzdGUocm91bmQoeCRjb25mLmludFsxOjJdLDIpLGNvbGxhcHNlPSJ+IikpCnZvbGNhbm9fYWdlT3ZlcjYwX3NhbXBsZUFGMC4wMV9iaW90eXBlX2FsbEdlbmVzJEJIXzAuMDA1ID0gcC5hZGp1c3Qodm9sY2Fub19hZ2VPdmVyNjBfc2FtcGxlQUYwLjAxX2Jpb3R5cGVfYWxsR2VuZXMkUF92YWx1ZV9GaXNoZXJfMC4wMDUsbWV0aG9kID0gIkJIIikKCmZpc2hlcnJlc3VsdHNfYmlvdHlwZV9ORkVfdm9sY2FubyA8LSBhcHBseSh2b2xjYW5vX2FnZU92ZXI2MF9zYW1wbGVBRjAuMDFfYmlvdHlwZV9hbGxHZW5lc1ssYygzLDYsNCw4KV0sMSxmdW5jdGlvbih4KSB7ZmlzaGVyLnRlc3QocmJpbmQoeFsxOjJdLGMoYWJzKHhbM10teFsxXSksYWJzKHhbNF0teFsyXSkpKSl9KQoKdm9sY2Fub19hZ2VPdmVyNjBfc2FtcGxlQUYwLjAxX2Jpb3R5cGVfYWxsR2VuZXMkUF92YWx1ZV9GaXNoZXJfMC4wMDVfTkZFID0gc2FwcGx5KGZpc2hlcnJlc3VsdHNfYmlvdHlwZV9ORkVfdm9sY2FubyxmdW5jdGlvbih4KSByb3VuZCh4JHAudmFsdWUsMTUpKQp2b2xjYW5vX2FnZU92ZXI2MF9zYW1wbGVBRjAuMDFfYmlvdHlwZV9hbGxHZW5lcyRPUl8wLjAwNV9ORkUgPSBzYXBwbHkoZmlzaGVycmVzdWx0c19iaW90eXBlX05GRV92b2xjYW5vLGZ1bmN0aW9uKHgpIHJvdW5kKHgkZXN0aW1hdGUsMTUpKQp2b2xjYW5vX2FnZU92ZXI2MF9zYW1wbGVBRjAuMDFfYmlvdHlwZV9hbGxHZW5lcyRgOTUlQ0lfMC4wMDVfTkZFYCA9IHNhcHBseShmaXNoZXJyZXN1bHRzX2Jpb3R5cGVfTkZFX3ZvbGNhbm8sZnVuY3Rpb24oeCkgcGFzdGUocm91bmQoeCRjb25mLmludFsxOjJdLDIpLGNvbGxhcHNlPSJ+IikpCnZvbGNhbm9fYWdlT3ZlcjYwX3NhbXBsZUFGMC4wMV9iaW90eXBlX2FsbEdlbmVzJEJIXzAuMDA1X05GRSA9IHAuYWRqdXN0KHZvbGNhbm9fYWdlT3ZlcjYwX3NhbXBsZUFGMC4wMV9iaW90eXBlX2FsbEdlbmVzJFBfdmFsdWVfRmlzaGVyXzAuMDA1X05GRSxtZXRob2QgPSAiQkgiKQoKZmlzaGVycmVzdWx0c19iaW90eXBlMl9hbGxHZW5lc192b2xjYW5vIDwtIGFwcGx5KHZvbGNhbm9fYWdlT3ZlcjYwX3NhbXBsZUFGMC4wMV9iaW90eXBlMl9hbGxHZW5lc1ssYygzLDUsNCw3KV0sMSxmdW5jdGlvbih4KSB7ZmlzaGVyLnRlc3QocmJpbmQoeFsxOjJdLGMoYWJzKHhbM10teFsxXSksYWJzKHhbNF0teFsyXSkpKSl9KQoKdm9sY2Fub19hZ2VPdmVyNjBfc2FtcGxlQUYwLjAxX2Jpb3R5cGUyX2FsbEdlbmVzJFBfdmFsdWVfRmlzaGVyXzAuMDA1ID0gc2FwcGx5KGZpc2hlcnJlc3VsdHNfYmlvdHlwZTJfYWxsR2VuZXNfdm9sY2FubyxmdW5jdGlvbih4KSByb3VuZCh4JHAudmFsdWUsMTUpKQp2b2xjYW5vX2FnZU92ZXI2MF9zYW1wbGVBRjAuMDFfYmlvdHlwZTJfYWxsR2VuZXMkT1JfMC4wMDUgPSBzYXBwbHkoZmlzaGVycmVzdWx0c19iaW90eXBlMl9hbGxHZW5lc192b2xjYW5vLGZ1bmN0aW9uKHgpIHJvdW5kKHgkZXN0aW1hdGUsMTUpKQp2b2xjYW5vX2FnZU92ZXI2MF9zYW1wbGVBRjAuMDFfYmlvdHlwZTJfYWxsR2VuZXMkYDk1JUNJXzAuMDA1YCA9IHNhcHBseShmaXNoZXJyZXN1bHRzX2Jpb3R5cGUyX2FsbEdlbmVzX3ZvbGNhbm8sZnVuY3Rpb24oeCkgcGFzdGUocm91bmQoeCRjb25mLmludFsxOjJdLDIpLGNvbGxhcHNlPSJ+IikpCnZvbGNhbm9fYWdlT3ZlcjYwX3NhbXBsZUFGMC4wMV9iaW90eXBlMl9hbGxHZW5lcyRCSF8wLjAwNSA9IHAuYWRqdXN0KHZvbGNhbm9fYWdlT3ZlcjYwX3NhbXBsZUFGMC4wMV9iaW90eXBlMl9hbGxHZW5lcyRQX3ZhbHVlX0Zpc2hlcl8wLjAwNSxtZXRob2QgPSAiQkgiKQoKZmlzaGVycmVzdWx0c19iaW90eXBlMl9ORkVfdm9sY2FubyA8LSBhcHBseSh2b2xjYW5vX2FnZU92ZXI2MF9zYW1wbGVBRjAuMDFfYmlvdHlwZTJfYWxsR2VuZXNbLGMoMyw2LDQsOCldLDEsZnVuY3Rpb24oeCkge2Zpc2hlci50ZXN0KHJiaW5kKHhbMToyXSxjKGFicyh4WzNdLXhbMV0pLGFicyh4WzRdLXhbMl0pKSkpfSkKCnZvbGNhbm9fYWdlT3ZlcjYwX3NhbXBsZUFGMC4wMV9iaW90eXBlMl9hbGxHZW5lcyRQX3ZhbHVlX0Zpc2hlcl8wLjAwNV9ORkUgPSBzYXBwbHkoZmlzaGVycmVzdWx0c19iaW90eXBlMl9ORkVfdm9sY2FubyxmdW5jdGlvbih4KSByb3VuZCh4JHAudmFsdWUsMTUpKQp2b2xjYW5vX2FnZU92ZXI2MF9zYW1wbGVBRjAuMDFfYmlvdHlwZTJfYWxsR2VuZXMkT1JfMC4wMDVfTkZFID0gc2FwcGx5KGZpc2hlcnJlc3VsdHNfYmlvdHlwZTJfTkZFX3ZvbGNhbm8sZnVuY3Rpb24oeCkgcm91bmQoeCRlc3RpbWF0ZSwxNSkpCnZvbGNhbm9fYWdlT3ZlcjYwX3NhbXBsZUFGMC4wMV9iaW90eXBlMl9hbGxHZW5lcyRgOTUlQ0lfMC4wMDVfTkZFYCA9IHNhcHBseShmaXNoZXJyZXN1bHRzX2Jpb3R5cGUyX05GRV92b2xjYW5vLGZ1bmN0aW9uKHgpIHBhc3RlKHJvdW5kKHgkY29uZi5pbnRbMToyXSwyKSxjb2xsYXBzZT0ifiIpKQp2b2xjYW5vX2FnZU92ZXI2MF9zYW1wbGVBRjAuMDFfYmlvdHlwZTJfYWxsR2VuZXMkQkhfMC4wMDVfTkZFID0gcC5hZGp1c3Qodm9sY2Fub19hZ2VPdmVyNjBfc2FtcGxlQUYwLjAxX2Jpb3R5cGUyX2FsbEdlbmVzJFBfdmFsdWVfRmlzaGVyXzAuMDA1X05GRSxtZXRob2QgPSAiQkgiKQpgYGAKCklkZW50aWZ5IHZhcmlhbnRzIHdpdGggZmlsdGVyaW5nIEFGID4gbWF4aW11bSBjcmVkaWJsZSBwb3B1bGF0aW9uIEFGIGluIEdub21BRCBmb3IgaGVyZWRpdGFyeSBFT0MgKDAuMDAwMTgxKQpgYGB7cn0KbWFzdGVyZmlsZV9lb2NfYWdlVW5kZXI2MF9nb29kUTJfSElHSF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfcmF0aW9zX2Zpc2hlcnJlc3VsdHMzIDwtIG11dGF0ZShtYXN0ZXJmaWxlX2VvY19hZ2VVbmRlcjYwX2dvb2RRMl9ISUdIX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19yYXRpb3NfZmlzaGVycmVzdWx0czIsIEZpbHRlcmluZ0FGXzk1X0V4Y2VlZHNfTWF4Q3JlZFBvcEFGPSgoR25vbUFEX3YyLjFfbm9uX2NhbmNlcl9GaWx0ZXJpbmdfQUZfOTUpPjAuMDAwMTgxKSkgJT4lIAogIG11dGF0ZShGaWx0ZXJpbmdBRl85NV9ORkVfRXhjZWVkc19NYXhDcmVkUG9wQUY9KChHbm9tQURfdjIuMV9ub25fY2FuY2VyX0ZpbHRlcmluZ19BRl85NV9uZmUpPjAuMDAwMTgxKSkKCm1hc3RlcmZpbGVfZW9jX2FnZVVuZGVyNjBfZ29vZFEyX0hJR0hfTk1jYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19yYXRpb3NfZmlzaGVycmVzdWx0czMgPC0gbXV0YXRlKG1hc3RlcmZpbGVfZW9jX2FnZVVuZGVyNjBfZ29vZFEyX0hJR0hfTk1jYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19yYXRpb3NfZmlzaGVycmVzdWx0czIsIEZpbHRlcmluZ0FGXzk1X0V4Y2VlZHNfTWF4Q3JlZFBvcEFGPSgoR25vbUFEX3YyLjFfbm9uX2NhbmNlcl9GaWx0ZXJpbmdfQUZfOTUpPjAuMDAwMTgxKSkgJT4lIAogIG11dGF0ZShGaWx0ZXJpbmdBRl85NV9ORkVfRXhjZWVkc19NYXhDcmVkUG9wQUY9KChHbm9tQURfdjIuMV9ub25fY2FuY2VyX0ZpbHRlcmluZ19BRl85NV9uZmUpPjAuMDAwMTgxKSkKCm1hc3RlcmZpbGVfZW9jX2FnZU92ZXI2MF9nb29kUTJfSElHSF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfcmF0aW9zX2Zpc2hlcnJlc3VsdHMzIDwtIG11dGF0ZShtYXN0ZXJmaWxlX2VvY19hZ2VPdmVyNjBfZ29vZFEyX0hJR0hfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX3JhdGlvc19maXNoZXJyZXN1bHRzMiwgRmlsdGVyaW5nQUZfOTVfRXhjZWVkc19NYXhDcmVkUG9wQUY9KChHbm9tQURfdjIuMV9ub25fY2FuY2VyX0ZpbHRlcmluZ19BRl85NSk+MC4wMDAxODEpKSAlPiUgCiAgbXV0YXRlKEZpbHRlcmluZ0FGXzk1X05GRV9FeGNlZWRzX01heENyZWRQb3BBRj0oKEdub21BRF92Mi4xX25vbl9jYW5jZXJfRmlsdGVyaW5nX0FGXzk1X25mZSk+MC4wMDAxODEpKQoKbWFzdGVyZmlsZV9lb2NfYWdlT3ZlcjYwX2dvb2RRMl9ISUdIX05NY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfcmF0aW9zX2Zpc2hlcnJlc3VsdHMzIDwtIG11dGF0ZShtYXN0ZXJmaWxlX2VvY19hZ2VPdmVyNjBfZ29vZFEyX0hJR0hfTk1jYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19yYXRpb3NfZmlzaGVycmVzdWx0czIsIEZpbHRlcmluZ0FGXzk1X0V4Y2VlZHNfTWF4Q3JlZFBvcEFGPSgoR25vbUFEX3YyLjFfbm9uX2NhbmNlcl9GaWx0ZXJpbmdfQUZfOTUpPjAuMDAwMTgxKSkgJT4lIAogIG11dGF0ZShGaWx0ZXJpbmdBRl85NV9ORkVfRXhjZWVkc19NYXhDcmVkUG9wQUY9KChHbm9tQURfdjIuMV9ub25fY2FuY2VyX0ZpbHRlcmluZ19BRl85NV9uZmUpPjAuMDAwMTgxKSkKYGBgCgpJZGVudGlmeSB2YXJpYW50cyB0aGF0IFBBU1MvRkFJTCB0aGUgTE9GVEVFIDUwYnAgcnVsZQpgYGB7cn0KbWFzdGVyZmlsZV9lb2NfYWdlVW5kZXI2MF9nb29kUTJfSElHSF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfcmF0aW9zX2Zpc2hlcnJlc3VsdHM0IDwtIG11dGF0ZShtYXN0ZXJmaWxlX2VvY19hZ2VVbmRlcjYwX2dvb2RRMl9ISUdIX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19yYXRpb3NfZmlzaGVycmVzdWx0czMsTG9GXzUwX0JQX1JVTEUgPSBpZmVsc2UoZ3JlcGwoIjUwX0JQX1JVTEU6UEFTUyIsIExvRl9pbmZvKSwgVFJVRSwgaWZlbHNlKGdyZXBsKCI1MF9CUF9SVUxFOkZBSUwiLCBMb0ZfaW5mbyksIEZBTFNFLCBOQSkpKQoKbWFzdGVyZmlsZV9lb2NfYWdlVW5kZXI2MF9nb29kUTJfSElHSF9OTWNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX3JhdGlvc19maXNoZXJyZXN1bHRzNCA8LSBtdXRhdGUobWFzdGVyZmlsZV9lb2NfYWdlVW5kZXI2MF9nb29kUTJfSElHSF9OTWNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX3JhdGlvc19maXNoZXJyZXN1bHRzMyxMb0ZfNTBfQlBfUlVMRSA9IGlmZWxzZShncmVwbCgiNTBfQlBfUlVMRTpQQVNTIiwgTG9GX2luZm8pLCBUUlVFLCBpZmVsc2UoZ3JlcGwoIjUwX0JQX1JVTEU6RkFJTCIsIExvRl9pbmZvKSwgRkFMU0UsIE5BKSkpCgptYXN0ZXJmaWxlX2VvY19hZ2VPdmVyNjBfZ29vZFEyX0hJR0hfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX3JhdGlvc19maXNoZXJyZXN1bHRzNCA8LSBtdXRhdGUobWFzdGVyZmlsZV9lb2NfYWdlT3ZlcjYwX2dvb2RRMl9ISUdIX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19yYXRpb3NfZmlzaGVycmVzdWx0czMsTG9GXzUwX0JQX1JVTEUgPSBpZmVsc2UoZ3JlcGwoIjUwX0JQX1JVTEU6UEFTUyIsIExvRl9pbmZvKSwgVFJVRSwgaWZlbHNlKGdyZXBsKCI1MF9CUF9SVUxFOkZBSUwiLCBMb0ZfaW5mbyksIEZBTFNFLCBOQSkpKQoKbWFzdGVyZmlsZV9lb2NfYWdlT3ZlcjYwX2dvb2RRMl9ISUdIX05NY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfcmF0aW9zX2Zpc2hlcnJlc3VsdHM0IDwtIG11dGF0ZShtYXN0ZXJmaWxlX2VvY19hZ2VPdmVyNjBfZ29vZFEyX0hJR0hfTk1jYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19yYXRpb3NfZmlzaGVycmVzdWx0czMsTG9GXzUwX0JQX1JVTEUgPSBpZmVsc2UoZ3JlcGwoIjUwX0JQX1JVTEU6UEFTUyIsIExvRl9pbmZvKSwgVFJVRSwgaWZlbHNlKGdyZXBsKCI1MF9CUF9SVUxFOkZBSUwiLCBMb0ZfaW5mbyksIEZBTFNFLCBOQSkpKQpgYGAKCkltcG9ydCBOTUQgZGVwbGV0ZWQgZ2VuZSBsaXN0IGFuZCBhbm5vdGF0ZSB2YXJpYW50cyBhY2NvcmRpbmdseQpgYGB7cn0KTk1EX2RlcGxldGVkX2dlbmVfbGlzdCA8LSByZWFkLmNzdigiTk1EX2RlcGxldGVkX2dlbmVfbGlzdC5jc3YiLCBzdHJpbmdzQXNGYWN0b3JzPUZBTFNFKSAlPiUgCiAgZHBseXI6OnJlbmFtZSgiU1lNQk9MIiA9IGdlbmUpICU+JSAKICBkcGx5cjo6cmVuYW1lKCJGZWF0dXJlIiA9IHR4bmFtZXMpICU+JSAKICBkcGx5cjo6cmVuYW1lKCJOTURfcHJlZGljdG9yX3JhbmsiID0gbWluLnJhbmspCgptYXN0ZXJmaWxlX2VvY19hZ2VVbmRlcjYwX2dvb2RRMl9ISUdIX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19yYXRpb3NfZmlzaGVycmVzdWx0czUgPC0gbGVmdF9qb2luKG1hc3RlcmZpbGVfZW9jX2FnZVVuZGVyNjBfZ29vZFEyX0hJR0hfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX3JhdGlvc19maXNoZXJyZXN1bHRzNCwgTk1EX2RlcGxldGVkX2dlbmVfbGlzdFssYygyOjMpXSxieT0iRmVhdHVyZSIsY29weT1GQUxTRSkgCm1hc3RlcmZpbGVfZW9jX2FnZVVuZGVyNjBfZ29vZFEyX0hJR0hfTk1jYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19yYXRpb3NfZmlzaGVycmVzdWx0czUgPC0gbGVmdF9qb2luKG1hc3RlcmZpbGVfZW9jX2FnZVVuZGVyNjBfZ29vZFEyX0hJR0hfTk1jYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19yYXRpb3NfZmlzaGVycmVzdWx0czQsIE5NRF9kZXBsZXRlZF9nZW5lX2xpc3RbLGMoMTozKV0sYnk9IlNZTUJPTCIsY29weT1GQUxTRSkgCgptYXN0ZXJmaWxlX2VvY19hZ2VPdmVyNjBfZ29vZFEyX0hJR0hfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX3JhdGlvc19maXNoZXJyZXN1bHRzNSA8LSBsZWZ0X2pvaW4obWFzdGVyZmlsZV9lb2NfYWdlT3ZlcjYwX2dvb2RRMl9ISUdIX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19yYXRpb3NfZmlzaGVycmVzdWx0czQsIE5NRF9kZXBsZXRlZF9nZW5lX2xpc3RbLGMoMjozKV0sYnk9IkZlYXR1cmUiLGNvcHk9RkFMU0UpIAptYXN0ZXJmaWxlX2VvY19hZ2VPdmVyNjBfZ29vZFEyX0hJR0hfTk1jYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19yYXRpb3NfZmlzaGVycmVzdWx0czUgPC0gbGVmdF9qb2luKG1hc3RlcmZpbGVfZW9jX2FnZU92ZXI2MF9nb29kUTJfSElHSF9OTWNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX3JhdGlvc19maXNoZXJyZXN1bHRzNCwgTk1EX2RlcGxldGVkX2dlbmVfbGlzdFssYygxOjMpXSxieT0iU1lNQk9MIixjb3B5PUZBTFNFKSAKYGBgCgpSZW1vdmUgcmVkdW5kYW50IG9iamVjdHMgYW5kIG91dHB1dCBkYXRhCmBgYHtyfQpybShsaXN0PShscyhwYXR0ZXJuPSJeZ2VuZXMiKSkpCnJtKGxpc3Q9KGxzKHBhdHRlcm49Il52YXJpYW50cyIpKSkKcm0obGlzdD0obHMocGF0dGVybj0iXmZpc2hlcnJlc3VsdHMiKSkpCgp3cml0ZV9leGNlbF9jc3YobWFzdGVyZmlsZV9lb2NfYWdlVW5kZXI2MF9nb29kUTJfSElHSF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfcmF0aW9zX2Zpc2hlcnJlc3VsdHM1LHBhdGg9Im1hc3RlcmZpbGVfZW9jX2FnZVVuZGVyNjBfZ29vZFEyX0hJR0hfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDEuY3N2IixuYT0iLiIsYXBwZW5kPUZBTFNFLGNvbF9uYW1lcz1UUlVFKQoKc2VsZWN0KG1hc3RlcmZpbGVfZW9jX2FnZVVuZGVyNjBfZ29vZFEyX0hJR0hfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX3JhdGlvc19maXNoZXJyZXN1bHRzNSxTWU1CT0wsR2VuZSxQX3ZhbHVlX0Zpc2hlcl8wLjAwNV9ORkUpICU+JSAKICBhcnJhbmdlKFBfdmFsdWVfRmlzaGVyXzAuMDA1X05GRSkgJT4lIAogIHVuaXF1ZSgpICU+JSAKICB3cml0ZV90c3YocGF0aD0iRkh4X0hJR0hfRU5TVGNhbm9uaWNhbF9CSF9wX3ZhbHVlcy50c3YiKQoKd3JpdGVfZXhjZWxfY3N2KG1hc3RlcmZpbGVfZW9jX2FnZVVuZGVyNjBfZ29vZFEyX0hJR0hfTk1jYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19yYXRpb3NfZmlzaGVycmVzdWx0czUscGF0aD0ibWFzdGVyZmlsZV9lb2NfYWdlVW5kZXI2MF9nb29kUTJfSElHSF9OTWNhbm9uaWNhbF9zYW1wbGVBRjAuMDEuY3N2IixuYT0iLiIsYXBwZW5kPUZBTFNFLGNvbF9uYW1lcz1UUlVFKQoKc2VsZWN0KG1hc3RlcmZpbGVfZW9jX2FnZVVuZGVyNjBfZ29vZFEyX0hJR0hfTk1jYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19yYXRpb3NfZmlzaGVycmVzdWx0czUsU1lNQk9MLEdlbmUsUF92YWx1ZV9GaXNoZXJfMC4wMDVfTkZFKSAlPiUgCiAgYXJyYW5nZShQX3ZhbHVlX0Zpc2hlcl8wLjAwNV9ORkUpICU+JSAKICB1bmlxdWUoKSAlPiUgCiAgd3JpdGVfdHN2KHBhdGg9IkZIeF9ISUdIX05NY2Fub25pY2FsX0JIX3BfdmFsdWVzLnRzdiIpCgp3cml0ZV9leGNlbF9jc3YobWFzdGVyZmlsZV9lb2NfYWdlT3ZlcjYwX2dvb2RRMl9ISUdIX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19yYXRpb3NfZmlzaGVycmVzdWx0czUscGF0aD0ibWFzdGVyZmlsZV9lb2NfYWdlT3ZlcjYwX2dvb2RRMl9ISUdIX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxLmNzdiIsbmE9Ii4iLGFwcGVuZD1GQUxTRSxjb2xfbmFtZXM9VFJVRSkKCnNlbGVjdChtYXN0ZXJmaWxlX2VvY19hZ2VPdmVyNjBfZ29vZFEyX0hJR0hfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX3JhdGlvc19maXNoZXJyZXN1bHRzNSxTWU1CT0wsR2VuZSxQX3ZhbHVlX0Zpc2hlcl8wLjAwNV9ORkUpICU+JSAKICBhcnJhbmdlKFBfdmFsdWVfRmlzaGVyXzAuMDA1X05GRSkgJT4lIAogIHVuaXF1ZSgpICU+JSAKICB3cml0ZV90c3YocGF0aD0iRkh4X0hJR0hfRU5TVGNhbm9uaWNhbF9CSF9wX3ZhbHVlcy50c3YiKQoKd3JpdGVfZXhjZWxfY3N2KG1hc3RlcmZpbGVfZW9jX2FnZU92ZXI2MF9nb29kUTJfSElHSF9OTWNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX3JhdGlvc19maXNoZXJyZXN1bHRzNSxwYXRoPSJtYXN0ZXJmaWxlX2VvY19hZ2VPdmVyNjBfZ29vZFEyX0hJR0hfTk1jYW5vbmljYWxfc2FtcGxlQUYwLjAxLmNzdiIsbmE9Ii4iLGFwcGVuZD1GQUxTRSxjb2xfbmFtZXM9VFJVRSkKCnNlbGVjdChtYXN0ZXJmaWxlX2VvY19hZ2VPdmVyNjBfZ29vZFEyX0hJR0hfTk1jYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19yYXRpb3NfZmlzaGVycmVzdWx0czUsU1lNQk9MLEdlbmUsUF92YWx1ZV9GaXNoZXJfMC4wMDVfTkZFKSAlPiUgCiAgYXJyYW5nZShQX3ZhbHVlX0Zpc2hlcl8wLjAwNV9ORkUpICU+JSAKICB1bmlxdWUoKSAlPiUgCiAgd3JpdGVfdHN2KHBhdGg9IkZIeF9ISUdIX05NY2Fub25pY2FsX0JIX3BfdmFsdWVzLnRzdiIpCmBgYAoKQ2FsY3VsYXRlIHRvdGFsIExvRiB2YXJpYW50cyBpbiBzYW1wbGUgdnMgdG90YWwgTG9GIHZhcmlhbnRzIGluIEdub21BRCBub24tY2FuY2VyIE5GRSBhbmQgdXNlIGZvciBjaGktc3F1YXJlZCB0ZXN0CmBgYHtyfQpvZGRzcmF0aW8gPC0gZnVuY3Rpb24gKGEsIGIgPSBOVUxMLCBjID0gTlVMTCwgZCA9IE5VTEwsIGNvbmYubGV2ZWwgPSAwLjk1LCAKICAgIHAuY2FsYy5ieS5pbmRlcGVuZGVuY2UgPSBUUlVFKSAKewogICAgaWYgKGlzLm1hdHJpeChhKSkgewogICAgICAgIGlmICgoZGltKGEpWzFdICE9IDJMKSB8IChkaW0oYSlbMl0gIT0gMkwpKSB7CiAgICAgICAgICAgIHN0b3AoIklucHV0IG1hdHJpeCBtdXN0IGJlIGEgMngyIHRhYmxlLiIpCiAgICAgICAgfQogICAgICAgIC5hIDwtIGFbMSwgMV0KICAgICAgICAuYiA8LSBhWzEsIDJdCiAgICAgICAgLmMgPC0gYVsyLCAxXQogICAgICAgIC5kIDwtIGFbMiwgMl0KICAgICAgICAuZGF0YS5uYW1lIDwtIGRlcGFyc2Uoc3Vic3RpdHV0ZShhKSkKICAgIH0KICAgIGVsc2UgewogICAgICAgIC5hIDwtIGEKICAgICAgICAuYiA8LSBiCiAgICAgICAgLmMgPC0gYwogICAgICAgIC5kIDwtIGQKICAgICAgICAuZGF0YS5uYW1lIDwtIHBhc3RlKGRlcGFyc2Uoc3Vic3RpdHV0ZShhKSksIGRlcGFyc2Uoc3Vic3RpdHV0ZShiKSksIAogICAgICAgICAgICBkZXBhcnNlKHN1YnN0aXR1dGUoYykpLCBkZXBhcnNlKHN1YnN0aXR1dGUoZCkpKQogICAgfQogICAgLk1BVCA8LSBtYXRyaXgoYyguYSwgLmIsIE0xIDwtIC5hICsgLmIsIC5jLCAuZCwgTTAgPC0gLmMgKyAKICAgICAgICAuZCwgTjEgPC0gLmEgKyAuYywgTjAgPC0gLmIgKyAuZCwgVG90YWwgPC0gLmEgKyAuYiArIAogICAgICAgIC5jICsgLmQpLCAzLCAzKQogICAgY29sbmFtZXMoLk1BVCkgPC0gYygiU2FtcGxlIiwgIkdub21BRCIsICJUb3RhbCIpICMoIkRpc2Vhc2UiLCAiTm9uZGlzZWFzZSIsICJUb3RhbCIpCiAgICByb3duYW1lcyguTUFUKSA8LSBjKCJMb0YiLCAiTm8gTG9GIiwgIlRvdGFsIikgIygiRXhwb3NlZCIsICJOb25leHBvc2VkIiwgIlRvdGFsIikKICAgIGNsYXNzKC5NQVQpIDwtICJ0YWJsZSIKICAgIHByaW50KC5NQVQpCiAgICBFU1RJTUFURSA8LSAoLmEgLy5iKS8oLmMvLmQpCiAgICBub3JtLnBwIDwtIHFub3JtKDEgLSAoMSAtIGNvbmYubGV2ZWwpLzIpCiAgICBpZiAocC5jYWxjLmJ5LmluZGVwZW5kZW5jZSkgewogICAgICAgIHAudiA8LSAyICogKDEgLSBwbm9ybShhYnMoKC5hIC0gTjEgKiBNMS9Ub3RhbCkvc3FydChOMSAqIAogICAgICAgICAgICBOMCAqIE0xICogTTAvVG90YWwvVG90YWwvKFRvdGFsIC0gMSkpKSkpCiAgICB9CiAgICBlbHNlIHsKICAgICAgICBwLnYgPC0gMiAqICgxIC0gcG5vcm0obG9nKGlmZWxzZShFU1RJTUFURSA+IDEsIEVTVElNQVRFLCAKICAgICAgICAgICAgMS9FU1RJTUFURSkpL3NxcnQoMS8uYSArIDEvLmIgKyAxLy5jICsgMS8uZCkpKQogICAgfQogICAgT1JMIDwtIEVTVElNQVRFICogZXhwKC1ub3JtLnBwICogc3FydCgxLy5hICsgMS8uYiArIDEvLmMgKyAKICAgICAgICAxLy5kKSkKICAgIE9SVSA8LSBFU1RJTUFURSAqIGV4cChub3JtLnBwICogc3FydCgxLy5hICsgMS8uYiArIDEvLmMgKyAKICAgICAgICAxLy5kKSkgJT4lIHNpZ25pZihkaWdpdHM9NykKICAgIENJTlQgPC0gcGFzdGUoc2lnbmlmKE9STCxkaWdpdHMgPSA3KSxzaWduaWYoT1JVLGRpZ2l0cyA9IDcpLHNlcD0ifiIpCiAgICBhdHRyKENJTlQsICJjb25mLmxldmVsIikgPC0gY29uZi5sZXZlbAogICAgUlZBTCA8LSBsaXN0KHAudmFsdWUgPSBwLnYsIGNvbmYuaW50ID0gQ0lOVCwgZXN0aW1hdGUgPSBFU1RJTUFURSwgCiAgICAgICAgbWV0aG9kID0gIk9kZHMgcmF0aW8gZXN0aW1hdGUgYW5kIGl0cyBzaWduaWZpY2FuY2UgcHJvYmFiaWxpdHkiLCAKICAgICAgICBkYXRhLm5hbWUgPSAuZGF0YS5uYW1lKQogICAgY2xhc3MoUlZBTCkgPC0gImh0ZXN0IgogICAgcmV0dXJuKFJWQUwpCn0KCmEgPC0gc3VtKHZvbGNhbm9fYWdlVW5kZXI2MF9zYW1wbGVBRjAuMDFfYWxsR2VuZXMkVG90YWxfR2VuZV9Db3VudCkgJT4lIGFzLm51bWVyaWMoKQpiIDwtIFRvdGFsX1NhbXBsZV9BbGxlbGVzX2FnZVVuZGVyNjAqKG5yb3coYWxsR2VuZXNfQWdpbGVudFNTdjZfbGlzdCkpICU+JSBhcy5udW1lcmljKCkKYjEgPC0gYi1hICU+JSBhcy5udW1lcmljKCkKYyA8LSBzdW0odm9sY2Fub19hZ2VVbmRlcjYwX3NhbXBsZUFGMC4wMV9hbGxHZW5lcyRGSUxURVJfUkZfTE9GX0hJR0hJTVBBQ1RfQUNfMC4wMDUpICU+JSBhcy5udW1lcmljKCkKZCA8LSAobWF4KHZvbGNhbm9fYWdlVW5kZXI2MF9zYW1wbGVBRjAuMDFfYWxsR2VuZXMkTUFYX0FOKSkqbnJvdyhhbGxHZW5lc19BZ2lsZW50U1N2Nl9saXN0KSAlPiUgYXMubnVtZXJpYygpCmQxIDwtIGQtYyAlPiUgYXMubnVtZXJpYygpCmUgPC0gc3VtKHZvbGNhbm9fYWdlVW5kZXI2MF9zYW1wbGVBRjAuMDFfYWxsR2VuZXMkRklMVEVSX1JGX0xPRl9ISUdISU1QQUNUX0FDXzAuMDA1X05GRSkgJT4lIGFzLm51bWVyaWMoKQpmIDwtIChtYXgodm9sY2Fub19hZ2VVbmRlcjYwX3NhbXBsZUFGMC4wMV9hbGxHZW5lcyRNQVhfQU5fTkZFKSkqbnJvdyhhbGxHZW5lc19BZ2lsZW50U1N2Nl9saXN0KSAlPiUgYXMubnVtZXJpYygpCmYxIDwtIGYtZSAlPiUgYXMubnVtZXJpYygpCgpnIDwtIHN1bSh2b2xjYW5vX2FnZVVuZGVyNjBfc2FtcGxlQUYwLjAxX2Jpb3R5cGVfYWxsR2VuZXMkVG90YWxfR2VuZV9Db3VudCkgJT4lIGFzLm51bWVyaWMoKQpoIDwtIFRvdGFsX1NhbXBsZV9BbGxlbGVzX2FnZVVuZGVyNjAqKG5yb3coYWxsR2VuZXNfQWdpbGVudFNTdjZfbGlzdF9wcm90ZWluX2NvZGluZ19vbmx5KSkgJT4lIGFzLm51bWVyaWMoKQpoMSA8LSBoLWcgJT4lIGFzLm51bWVyaWMoKQppIDwtIHN1bSh2b2xjYW5vX2FnZVVuZGVyNjBfc2FtcGxlQUYwLjAxX2Jpb3R5cGVfYWxsR2VuZXMkRklMVEVSX1JGX0xPRl9ISUdISU1QQUNUX0FDXzAuMDA1KSAlPiUgYXMubnVtZXJpYygpCmogPC0gKG1heCh2b2xjYW5vX2FnZVVuZGVyNjBfc2FtcGxlQUYwLjAxX2Jpb3R5cGVfYWxsR2VuZXMkTUFYX0FOKSkqbnJvdyhhbGxHZW5lc19BZ2lsZW50U1N2Nl9saXN0X3Byb3RlaW5fY29kaW5nX29ubHkpICU+JSBhcy5udW1lcmljKCkKajEgPC0gai1pICU+JSBhcy5udW1lcmljKCkKayA8LSBzdW0odm9sY2Fub19hZ2VVbmRlcjYwX3NhbXBsZUFGMC4wMV9iaW90eXBlX2FsbEdlbmVzJEZJTFRFUl9SRl9MT0ZfSElHSElNUEFDVF9BQ18wLjAwNV9ORkUpICU+JSBhcy5udW1lcmljKCkKbCA8LSAobWF4KHZvbGNhbm9fYWdlVW5kZXI2MF9zYW1wbGVBRjAuMDFfYmlvdHlwZV9hbGxHZW5lcyRNQVhfQU5fTkZFKSkqbnJvdyhhbGxHZW5lc19BZ2lsZW50U1N2Nl9saXN0X3Byb3RlaW5fY29kaW5nX29ubHkpICU+JSBhcy5udW1lcmljKCkKbDEgPC0gbC1rICU+JSBhcy5udW1lcmljKCkKCmNoaVgyXzAuMDA1X2FnZVVuZGVyNjAgPC0gbWF0cml4KGMoYSxiMSxjLGQxKSxucm93PTIsYnlyb3c9VFJVRSkKY2hpWDJfMC4wMDVfTkZFX2FnZVVuZGVyNjAgPC0gbWF0cml4KGMoYSxiMSxlLGYxKSxucm93PTIsYnlyb3c9VFJVRSkKY2hpWDJfMC4wMDVfYmlvdHlwZV9hZ2VVbmRlcjYwIDwtIG1hdHJpeChjKGcsaDEsaSxqMSksbnJvdz0yLGJ5cm93PVRSVUUpCmNoaVgyXzAuMDA1X05GRV9iaW90eXBlX2FnZVVuZGVyNjAgPC0gbWF0cml4KGMoZyxoMSxrLGwxKSxucm93PTIsYnlyb3c9VFJVRSkKCm0gPC0gc3VtKHZvbGNhbm9fYWdlT3ZlcjYwX3NhbXBsZUFGMC4wMV9hbGxHZW5lcyRUb3RhbF9HZW5lX0NvdW50KSAlPiUgYXMubnVtZXJpYygpCm4gPC0gVG90YWxfU2FtcGxlX0FsbGVsZXNfYWdlT3ZlcjYwKihucm93KGFsbEdlbmVzX0FnaWxlbnRTU3Y2X2xpc3QpKSAlPiUgYXMubnVtZXJpYygpCm4xIDwtIG4tbSAlPiUgYXMubnVtZXJpYygpCm8gPC0gc3VtKHZvbGNhbm9fYWdlT3ZlcjYwX3NhbXBsZUFGMC4wMV9hbGxHZW5lcyRGSUxURVJfUkZfTE9GX0hJR0hJTVBBQ1RfQUNfMC4wMDUpICU+JSBhcy5udW1lcmljKCkKcCA8LSAobWF4KHZvbGNhbm9fYWdlT3ZlcjYwX3NhbXBsZUFGMC4wMV9hbGxHZW5lcyRNQVhfQU4pKSpucm93KGFsbEdlbmVzX0FnaWxlbnRTU3Y2X2xpc3QpICU+JSBhcy5udW1lcmljKCkKcDEgPC0gcC1vICU+JSBhcy5udW1lcmljKCkKcSA8LSBzdW0odm9sY2Fub19hZ2VPdmVyNjBfc2FtcGxlQUYwLjAxX2FsbEdlbmVzJEZJTFRFUl9SRl9MT0ZfSElHSElNUEFDVF9BQ18wLjAwNV9ORkUpICU+JSBhcy5udW1lcmljKCkKciA8LSAobWF4KHZvbGNhbm9fYWdlT3ZlcjYwX3NhbXBsZUFGMC4wMV9hbGxHZW5lcyRNQVhfQU5fTkZFKSkqbnJvdyhhbGxHZW5lc19BZ2lsZW50U1N2Nl9saXN0KSAlPiUgYXMubnVtZXJpYygpCnIxIDwtIHItcSAlPiUgYXMubnVtZXJpYygpCgpzIDwtIHN1bSh2b2xjYW5vX2FnZU92ZXI2MF9zYW1wbGVBRjAuMDFfYmlvdHlwZV9hbGxHZW5lcyRUb3RhbF9HZW5lX0NvdW50KSAlPiUgYXMubnVtZXJpYygpCnQgPC0gVG90YWxfU2FtcGxlX0FsbGVsZXNfYWdlT3ZlcjYwKihucm93KGFsbEdlbmVzX0FnaWxlbnRTU3Y2X2xpc3RfcHJvdGVpbl9jb2Rpbmdfb25seSkpICU+JSBhcy5udW1lcmljKCkKdDEgPC0gdC1zICU+JSBhcy5udW1lcmljKCkKdSA8LSBzdW0odm9sY2Fub19hZ2VPdmVyNjBfc2FtcGxlQUYwLjAxX2Jpb3R5cGVfYWxsR2VuZXMkRklMVEVSX1JGX0xPRl9ISUdISU1QQUNUX0FDXzAuMDA1KSAlPiUgYXMubnVtZXJpYygpCnYgPC0gKG1heCh2b2xjYW5vX2FnZU92ZXI2MF9zYW1wbGVBRjAuMDFfYmlvdHlwZV9hbGxHZW5lcyRNQVhfQU4pKSpucm93KGFsbEdlbmVzX0FnaWxlbnRTU3Y2X2xpc3RfcHJvdGVpbl9jb2Rpbmdfb25seSkgJT4lIGFzLm51bWVyaWMoKQp2MSA8LSB2LXUgJT4lIGFzLm51bWVyaWMoKQp3IDwtIHN1bSh2b2xjYW5vX2FnZU92ZXI2MF9zYW1wbGVBRjAuMDFfYmlvdHlwZV9hbGxHZW5lcyRGSUxURVJfUkZfTE9GX0hJR0hJTVBBQ1RfQUNfMC4wMDVfTkZFKSAlPiUgYXMubnVtZXJpYygpCnggPC0gKG1heCh2b2xjYW5vX2FnZU92ZXI2MF9zYW1wbGVBRjAuMDFfYmlvdHlwZV9hbGxHZW5lcyRNQVhfQU5fTkZFKSkqbnJvdyhhbGxHZW5lc19BZ2lsZW50U1N2Nl9saXN0X3Byb3RlaW5fY29kaW5nX29ubHkpICU+JSBhcy5udW1lcmljKCkKeDEgPC0geC13ICU+JSBhcy5udW1lcmljKCkKCmNoaVgyXzAuMDA1X2FnZU92ZXI2MCA8LSBtYXRyaXgoYyhtLG4xLG8scDEpLG5yb3c9MixieXJvdz1UUlVFKQpjaGlYMl8wLjAwNV9ORkVfYWdlT3ZlcjYwIDwtIG1hdHJpeChjKG0sbjEscSxyMSksbnJvdz0yLGJ5cm93PVRSVUUpCmNoaVgyXzAuMDA1X2Jpb3R5cGVfYWdlT3ZlcjYwIDwtIG1hdHJpeChjKHMsdDEsdSx2MSksbnJvdz0yLGJ5cm93PVRSVUUpCmNoaVgyXzAuMDA1X05GRV9iaW90eXBlX2FnZU92ZXI2MCA8LSBtYXRyaXgoYyhzLHQxLHcseDEpLG5yb3c9MixieXJvdz1UUlVFKQoKY2hpWDJfMC4wMDVfTkZFX2FnZVVuZGVyNjBfYWdlT3ZlcjYwIDwtIG1hdHJpeChjKGNoaVgyXzAuMDA1X05GRV9hZ2VVbmRlcjYwWzEsXSxjaGlYMl8wLjAwNV9ORkVfYWdlT3ZlcjYwWzEsXSksbnJvdz0yLGJ5cm93PVRSVUUpCmNoaVgyXzAuMDA1X05GRV9iaW90eXBlX2FnZVVuZGVyNjBfYWdlT3ZlcjYwIDwtIG1hdHJpeChjKGNoaVgyXzAuMDA1X05GRV9iaW90eXBlX2FnZVVuZGVyNjBbMSxdLGNoaVgyXzAuMDA1X05GRV9iaW90eXBlX2FnZU92ZXI2MFsxLF0pLG5yb3c9MixieXJvdz1UUlVFKQoKc2V0d2QoIn4vT25lRHJpdmUgLSBUaGUgVW5pdmVyc2l0eSBvZiBNZWxib3VybmUvUiBkYXRhIikKc2luayhmaWxlPSJtYXN0ZXJmaWxlX2VvY19MT0Zfdm9sY2Fub19jaGlYMl9yZXN1bHRzLnR4dCIsYXBwZW5kPVRSVUUpCgpjaGlzcS50ZXN0KGNoaVgyXzAuMDA1X2FnZVVuZGVyNjAsY29ycmVjdD1GQUxTRSkKb2Rkc3JhdGlvKGNoaVgyXzAuMDA1X2FnZVVuZGVyNjApCmNoaXNxLnRlc3QoY2hpWDJfMC4wMDVfTkZFX2FnZVVuZGVyNjAsY29ycmVjdD1GQUxTRSkKb2Rkc3JhdGlvKGNoaVgyXzAuMDA1X05GRV9hZ2VVbmRlcjYwKQpjaGlzcS50ZXN0KGNoaVgyXzAuMDA1X2Jpb3R5cGVfYWdlVW5kZXI2MCxjb3JyZWN0PUZBTFNFKQpvZGRzcmF0aW8oY2hpWDJfMC4wMDVfYmlvdHlwZV9hZ2VVbmRlcjYwKQpjaGlzcS50ZXN0KGNoaVgyXzAuMDA1X05GRV9iaW90eXBlX2FnZVVuZGVyNjAsY29ycmVjdD1GQUxTRSkKb2Rkc3JhdGlvKGNoaVgyXzAuMDA1X05GRV9iaW90eXBlX2FnZVVuZGVyNjApCgpjaGlzcS50ZXN0KGNoaVgyXzAuMDA1X2FnZU92ZXI2MCxjb3JyZWN0PUZBTFNFKQpvZGRzcmF0aW8oY2hpWDJfMC4wMDVfYWdlT3ZlcjYwKQpjaGlzcS50ZXN0KGNoaVgyXzAuMDA1X05GRV9hZ2VPdmVyNjAsY29ycmVjdD1GQUxTRSkKb2Rkc3JhdGlvKGNoaVgyXzAuMDA1X05GRV9hZ2VPdmVyNjApCmNoaXNxLnRlc3QoY2hpWDJfMC4wMDVfYmlvdHlwZV9hZ2VPdmVyNjAsY29ycmVjdD1GQUxTRSkKb2Rkc3JhdGlvKGNoaVgyXzAuMDA1X2Jpb3R5cGVfYWdlT3ZlcjYwKQpjaGlzcS50ZXN0KGNoaVgyXzAuMDA1X05GRV9iaW90eXBlX2FnZU92ZXI2MCxjb3JyZWN0PUZBTFNFKQpvZGRzcmF0aW8oY2hpWDJfMC4wMDVfTkZFX2Jpb3R5cGVfYWdlT3ZlcjYwKQoKY2hpc3EudGVzdChjaGlYMl8wLjAwNV9ORkVfYWdlVW5kZXI2MF9hZ2VPdmVyNjAsY29ycmVjdD1GQUxTRSkKY2hpc3EudGVzdChjaGlYMl8wLjAwNV9ORkVfYmlvdHlwZV9hZ2VVbmRlcjYwX2FnZU92ZXI2MCxjb3JyZWN0PUZBTFNFKQoKc2luaygpCmBgYAoKUmVtb3ZlIHZhcmlhbnRzIHdpdGggbm9uLXByb3RlaW4tY29kaW5nIGJpb3R5cGVzCmBgYHtyfQptYXN0ZXJmaWxlX2VvY19hZ2VVbmRlcjYwX2dvb2RRMl9ISUdIX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX2Jpb3R5cGUgPC0gZmlsdGVyKG1hc3RlcmZpbGVfZW9jX2FnZVVuZGVyNjBfZ29vZFEyX0hJR0hfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX3JhdGlvc19maXNoZXJyZXN1bHRzNSxCSU9UWVBFJWluJWMoInByb3RlaW5fY29kaW5nIikpCgptYXN0ZXJmaWxlX2VvY19hZ2VVbmRlcjYwX2dvb2RRMl9ISUdIX05NY2Fub25pY2FsX3NhbXBsZUFGMC4wMV9iaW90eXBlIDwtIGZpbHRlcihtYXN0ZXJmaWxlX2VvY19hZ2VVbmRlcjYwX2dvb2RRMl9ISUdIX05NY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfcmF0aW9zX2Zpc2hlcnJlc3VsdHM1LEJJT1RZUEUlaW4lYygicHJvdGVpbl9jb2RpbmciKSkKCm1hc3RlcmZpbGVfZW9jX2FnZU92ZXI2MF9nb29kUTJfSElHSF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV9iaW90eXBlIDwtIGZpbHRlcihtYXN0ZXJmaWxlX2VvY19hZ2VPdmVyNjBfZ29vZFEyX0hJR0hfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX3JhdGlvc19maXNoZXJyZXN1bHRzNSxCSU9UWVBFJWluJWMoInByb3RlaW5fY29kaW5nIikpCgptYXN0ZXJmaWxlX2VvY19hZ2VPdmVyNjBfZ29vZFEyX0hJR0hfTk1jYW5vbmljYWxfc2FtcGxlQUYwLjAxX2Jpb3R5cGUgPC0gZmlsdGVyKG1hc3RlcmZpbGVfZW9jX2FnZU92ZXI2MF9nb29kUTJfSElHSF9OTWNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX3JhdGlvc19maXNoZXJyZXN1bHRzNSxCSU9UWVBFJWluJWMoInByb3RlaW5fY29kaW5nIikpCmBgYAoKQ2FsY3VsYXRlIG51bWJlciBvZiByZXRhaW5lZCBwcm90ZWluLWNvZGluZyBMb0YgdmFyaWFudHMgcGVyIGluZGl2aWR1YWwgaW4gdW5kZXIgNjAvb3ZlciA2MCBjb2hvcnRzLCBhbmQgb3V0cHV0IHJlc3VsdHMuCmBgYHtyfQptYXN0ZXJmaWxlX2VvY19hZ2VVbmRlcjYwX2dvb2RRMl9ISUdIX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX2Jpb3R5cGVfdmFyaWFudHNQZXJQZXJzb24gPC0gc2VsZWN0KG1hc3RlcmZpbGVfZW9jX2FnZVVuZGVyNjBfZ29vZFEyX0hJR0hfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfYmlvdHlwZSxTYW1wbGUsQ0hST00sUE9TLFJFRixBTFQsU2FtcGxlLkdULFNZTUJPTCxHZW5lLEZlYXR1cmUsSEdWU2MpCnNhbXBsZXNfYWdlVW5kZXI2MCA8LSBtYXN0ZXJmaWxlX2VvY19hZ2VVbmRlcjYwX2dvb2RRMl9ISUdIX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX2Jpb3R5cGVfdmFyaWFudHNQZXJQZXJzb25bLDFdICU+JSB1bmlxdWUoKQpzYW1wbGVzX2FnZVVuZGVyNjBfZ29vZFEyX0hJR0hfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfYmlvdHlwZV92YXJpYW50c1BlclBlcnNvbiA8LSBkYXRhLmZyYW1lKFNhbXBsZT1mYWN0b3IoKSxOb19vZl9WYXJpYW50cz1kb3VibGUoKSkKZm9yKHNhbXBsZSBpbiBzYW1wbGVzX2FnZVVuZGVyNjApewogIHNhbXBsZV9kYXRhIDwtIGZpbHRlcihtYXN0ZXJmaWxlX2VvY19hZ2VVbmRlcjYwX2dvb2RRMl9ISUdIX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX2Jpb3R5cGVfdmFyaWFudHNQZXJQZXJzb24sU2FtcGxlJWluJWMoc2FtcGxlKSkKICBzYW1wbGVfdmFyaWFudHMgPC0gdmFyaWFudF9jb3VudHNfQUZzKHNhbXBsZV9kYXRhLFRvdGFsX1NhbXBsZV9BbGxlbGVzX2FnZVVuZGVyNjApCiAgbm9fb2ZfdmFyaWFudHMgPC0gc3VtKHNhbXBsZV92YXJpYW50cyRUb3RhbF9BbGxlbGVfQ291bnQpCiAgc2FtcGxlc19hZ2VVbmRlcjYwX2dvb2RRMl9ISUdIX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX2Jpb3R5cGVfdmFyaWFudHNQZXJQZXJzb24gPC0gYWRkX3JvdyhzYW1wbGVzX2FnZVVuZGVyNjBfZ29vZFEyX0hJR0hfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfYmlvdHlwZV92YXJpYW50c1BlclBlcnNvbixTYW1wbGU9c2FtcGxlLE5vX29mX1ZhcmlhbnRzPW5vX29mX3ZhcmlhbnRzKQp9CndyaXRlX3RzdihzYW1wbGVzX2FnZVVuZGVyNjBfZ29vZFEyX0hJR0hfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfYmlvdHlwZV92YXJpYW50c1BlclBlcnNvbixwYXRoPSJzYW1wbGVzX2FnZVVuZGVyNjBfZ29vZFEyX0hJR0hfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfYmlvdHlwZV92YXJpYW50c1BlclBlcnNvbi50c3YiKQoKbWFzdGVyZmlsZV9lb2NfYWdlT3ZlcjYwX2dvb2RRMl9ISUdIX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX2Jpb3R5cGVfdmFyaWFudHNQZXJQZXJzb24gPC0gc2VsZWN0KG1hc3RlcmZpbGVfZW9jX2FnZU92ZXI2MF9nb29kUTJfSElHSF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV9iaW90eXBlLFNhbXBsZSxDSFJPTSxQT1MsUkVGLEFMVCxTYW1wbGUuR1QsU1lNQk9MLEdlbmUsRmVhdHVyZSxIR1ZTYykKc2FtcGxlc19hZ2VPdmVyNjAgPC0gbWFzdGVyZmlsZV9lb2NfYWdlT3ZlcjYwX2dvb2RRMl9ISUdIX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX2Jpb3R5cGVfdmFyaWFudHNQZXJQZXJzb25bLDFdICU+JSB1bmlxdWUoKQpzYW1wbGVzX2FnZU92ZXI2MF9nb29kUTJfSElHSF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV9iaW90eXBlX3ZhcmlhbnRzUGVyUGVyc29uIDwtIGRhdGEuZnJhbWUoU2FtcGxlPWZhY3RvcigpLE5vX29mX1ZhcmlhbnRzPWRvdWJsZSgpKQpmb3Ioc2FtcGxlIGluIHNhbXBsZXNfYWdlT3ZlcjYwKXsKICBzYW1wbGVfZGF0YSA8LSBmaWx0ZXIobWFzdGVyZmlsZV9lb2NfYWdlT3ZlcjYwX2dvb2RRMl9ISUdIX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX2Jpb3R5cGVfdmFyaWFudHNQZXJQZXJzb24sU2FtcGxlJWluJWMoc2FtcGxlKSkKICBzYW1wbGVfdmFyaWFudHMgPC0gdmFyaWFudF9jb3VudHNfQUZzKHNhbXBsZV9kYXRhLFRvdGFsX1NhbXBsZV9BbGxlbGVzX2FnZU92ZXI2MCkKICBub19vZl92YXJpYW50cyA8LSBzdW0oc2FtcGxlX3ZhcmlhbnRzJFRvdGFsX0FsbGVsZV9Db3VudCkKICBzYW1wbGVzX2FnZU92ZXI2MF9nb29kUTJfSElHSF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV9iaW90eXBlX3ZhcmlhbnRzUGVyUGVyc29uIDwtIGFkZF9yb3coc2FtcGxlc19hZ2VPdmVyNjBfZ29vZFEyX0hJR0hfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfYmlvdHlwZV92YXJpYW50c1BlclBlcnNvbixTYW1wbGU9c2FtcGxlLE5vX29mX1ZhcmlhbnRzPW5vX29mX3ZhcmlhbnRzKQp9CndyaXRlX3RzdihzYW1wbGVzX2FnZU92ZXI2MF9nb29kUTJfSElHSF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV9iaW90eXBlX3ZhcmlhbnRzUGVyUGVyc29uLHBhdGg9InNhbXBsZXNfYWdlT3ZlcjYwX2dvb2RRMl9ISUdIX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX2Jpb3R5cGVfdmFyaWFudHNQZXJQZXJzb24udHN2IikKYGBgCgpPdXRwdXQgZGF0YSBmb3IgbG9nIHAtdmFsdWUgdm9sY2FubyBwbG90cwpgYGB7cn0Kdm9sY2Fub19hZ2VVbmRlcjYwX3NhbXBsZUFGMC4wMV9hbGxHZW5lczIgPC0gbXV0YXRlKHZvbGNhbm9fYWdlVW5kZXI2MF9zYW1wbGVBRjAuMDFfYWxsR2VuZXMsIkxvZzEwX1AtdmFsdWVfRmlzaGVyXzAuMDVfTkZFIiA9IGxvZzEwKFBfdmFsdWVfRmlzaGVyXzAuMDA1X05GRSkpICU+JSAKICBhcnJhbmdlKGRlc2MoT1JfMC4wMDVfTkZFKSkgJT4lIAogIG11dGF0ZSgiUGxvdHRlZF9Mb2cxMF9QLXZhbHVlX0Zpc2hlcl8wLjA1X05GRSI9IAogIGlmX2Vsc2UgKE9SXzAuMDA1X05GRT49MSwgYExvZzEwX1AtdmFsdWVfRmlzaGVyXzAuMDVfTkZFYCotMSwgYExvZzEwX1AtdmFsdWVfRmlzaGVyXzAuMDVfTkZFYCwgbWlzc2luZz1OVUxMKSkgJT4lIAogIGFycmFuZ2UoZGVzYyhgUGxvdHRlZF9Mb2cxMF9QLXZhbHVlX0Zpc2hlcl8wLjA1X05GRWApLGRlc2MoT1JfMC4wMDVfTkZFKSkgJT4lIAogIHdyaXRlX2V4Y2VsX2NzdihwYXRoPSJ2b2xjYW5vX2FnZVVuZGVyNjBfc2FtcGxlQUYwLjAxX2FsbEdlbmVzX3Y2LmNzdiIsbmE9Ii4iLGFwcGVuZD1GQUxTRSxjb2xfbmFtZXM9VFJVRSkKCnZvbGNhbm9fYWdlVW5kZXI2MF9zYW1wbGVBRjAuMDFfYmlvdHlwZV9hbGxHZW5lczIgPC0gbXV0YXRlKHZvbGNhbm9fYWdlVW5kZXI2MF9zYW1wbGVBRjAuMDFfYmlvdHlwZV9hbGxHZW5lcywiTG9nMTBfUC12YWx1ZV9GaXNoZXJfMC4wNV9ORkUiID0gbG9nMTAoUF92YWx1ZV9GaXNoZXJfMC4wMDVfTkZFKSkgJT4lIAogIGFycmFuZ2UoZGVzYyhPUl8wLjAwNV9ORkUpKSAlPiUgCiAgbXV0YXRlKCJQbG90dGVkX0xvZzEwX1AtdmFsdWVfRmlzaGVyXzAuMDVfTkZFIj0gCiAgaWZfZWxzZSAoT1JfMC4wMDVfTkZFPj0xLCBgTG9nMTBfUC12YWx1ZV9GaXNoZXJfMC4wNV9ORkVgKi0xLCBgTG9nMTBfUC12YWx1ZV9GaXNoZXJfMC4wNV9ORkVgLCBtaXNzaW5nPU5VTEwpKSAlPiUgCiAgYXJyYW5nZShkZXNjKGBQbG90dGVkX0xvZzEwX1AtdmFsdWVfRmlzaGVyXzAuMDVfTkZFYCksZGVzYyhPUl8wLjAwNV9ORkUpKSAlPiUgCiAgd3JpdGVfZXhjZWxfY3N2KHBhdGg9InZvbGNhbm9fYWdlVW5kZXI2MF9zYW1wbGVBRjAuMDFfYmlvdHlwZV9hbGxHZW5lc192Ni5jc3YiLG5hPSIuIixhcHBlbmQ9RkFMU0UsY29sX25hbWVzPVRSVUUpCgp2b2xjYW5vX2FnZVVuZGVyNjBfc2FtcGxlQUYwLjAxX2Jpb3R5cGUyX2FsbEdlbmVzMiA8LSBtdXRhdGUodm9sY2Fub19hZ2VVbmRlcjYwX3NhbXBsZUFGMC4wMV9iaW90eXBlMl9hbGxHZW5lcywiTG9nMTBfUC12YWx1ZV9GaXNoZXJfMC4wNV9ORkUiID0gbG9nMTAoUF92YWx1ZV9GaXNoZXJfMC4wMDVfTkZFKSkgJT4lIAogIGFycmFuZ2UoZGVzYyhPUl8wLjAwNV9ORkUpKSAlPiUgCiAgbXV0YXRlKCJQbG90dGVkX0xvZzEwX1AtdmFsdWVfRmlzaGVyXzAuMDVfTkZFIj0gCiAgaWZfZWxzZSAoT1JfMC4wMDVfTkZFPj0xLCBgTG9nMTBfUC12YWx1ZV9GaXNoZXJfMC4wNV9ORkVgKi0xLCBgTG9nMTBfUC12YWx1ZV9GaXNoZXJfMC4wNV9ORkVgLCBtaXNzaW5nPU5VTEwpKSAlPiUgCiAgYXJyYW5nZShkZXNjKGBQbG90dGVkX0xvZzEwX1AtdmFsdWVfRmlzaGVyXzAuMDVfTkZFYCksZGVzYyhPUl8wLjAwNV9ORkUpKSAlPiUgCiAgd3JpdGVfZXhjZWxfY3N2KHBhdGg9InZvbGNhbm9fYWdlVW5kZXI2MF9zYW1wbGVBRjAuMDFfYmlvdHlwZTJfYWxsR2VuZXNfdjYuY3N2IixuYT0iLiIsYXBwZW5kPUZBTFNFLGNvbF9uYW1lcz1UUlVFKQoKdm9sY2Fub19hZ2VPdmVyNjBfc2FtcGxlQUYwLjAxX2FsbEdlbmVzMiA8LSBtdXRhdGUodm9sY2Fub19hZ2VPdmVyNjBfc2FtcGxlQUYwLjAxX2FsbEdlbmVzLCJMb2cxMF9QLXZhbHVlX0Zpc2hlcl8wLjA1X05GRSIgPSBsb2cxMChQX3ZhbHVlX0Zpc2hlcl8wLjAwNV9ORkUpKSAlPiUgCiAgYXJyYW5nZShkZXNjKE9SXzAuMDA1X05GRSkpICU+JSAKICBtdXRhdGUoIlBsb3R0ZWRfTG9nMTBfUC12YWx1ZV9GaXNoZXJfMC4wNV9ORkUiPSAKICBpZl9lbHNlIChPUl8wLjAwNV9ORkU+PTEsIGBMb2cxMF9QLXZhbHVlX0Zpc2hlcl8wLjA1X05GRWAqLTEsIGBMb2cxMF9QLXZhbHVlX0Zpc2hlcl8wLjA1X05GRWAsIG1pc3Npbmc9TlVMTCkpICU+JSAKICBhcnJhbmdlKGRlc2MoYFBsb3R0ZWRfTG9nMTBfUC12YWx1ZV9GaXNoZXJfMC4wNV9ORkVgKSxkZXNjKE9SXzAuMDA1X05GRSkpICU+JSAKICB3cml0ZV9leGNlbF9jc3YocGF0aD0idm9sY2Fub19hZ2VPdmVyNjBfc2FtcGxlQUYwLjAxX2FsbEdlbmVzX3Y2LmNzdiIsbmE9Ii4iLGFwcGVuZD1GQUxTRSxjb2xfbmFtZXM9VFJVRSkKCnZvbGNhbm9fYWdlT3ZlcjYwX3NhbXBsZUFGMC4wMV9iaW90eXBlX2FsbEdlbmVzMiA8LSBtdXRhdGUodm9sY2Fub19hZ2VPdmVyNjBfc2FtcGxlQUYwLjAxX2Jpb3R5cGVfYWxsR2VuZXMsIkxvZzEwX1AtdmFsdWVfRmlzaGVyXzAuMDVfTkZFIiA9IGxvZzEwKFBfdmFsdWVfRmlzaGVyXzAuMDA1X05GRSkpICU+JSAKICBhcnJhbmdlKGRlc2MoT1JfMC4wMDVfTkZFKSkgJT4lIAogIG11dGF0ZSgiUGxvdHRlZF9Mb2cxMF9QLXZhbHVlX0Zpc2hlcl8wLjA1X05GRSI9IAogIGlmX2Vsc2UgKE9SXzAuMDA1X05GRT49MSwgYExvZzEwX1AtdmFsdWVfRmlzaGVyXzAuMDVfTkZFYCotMSwgYExvZzEwX1AtdmFsdWVfRmlzaGVyXzAuMDVfTkZFYCwgbWlzc2luZz1OVUxMKSkgJT4lIAogIGFycmFuZ2UoZGVzYyhgUGxvdHRlZF9Mb2cxMF9QLXZhbHVlX0Zpc2hlcl8wLjA1X05GRWApLGRlc2MoT1JfMC4wMDVfTkZFKSkgJT4lIAogIHdyaXRlX2V4Y2VsX2NzdihwYXRoPSJ2b2xjYW5vX2FnZU92ZXI2MF9zYW1wbGVBRjAuMDFfYmlvdHlwZV9hbGxHZW5lc192Ni5jc3YiLG5hPSIuIixhcHBlbmQ9RkFMU0UsY29sX25hbWVzPVRSVUUpCgp2b2xjYW5vX2FnZU92ZXI2MF9zYW1wbGVBRjAuMDFfYmlvdHlwZTJfYWxsR2VuZXMyIDwtIG11dGF0ZSh2b2xjYW5vX2FnZU92ZXI2MF9zYW1wbGVBRjAuMDFfYmlvdHlwZTJfYWxsR2VuZXMsIkxvZzEwX1AtdmFsdWVfRmlzaGVyXzAuMDVfTkZFIiA9IGxvZzEwKFBfdmFsdWVfRmlzaGVyXzAuMDA1X05GRSkpICU+JSAKICBhcnJhbmdlKGRlc2MoT1JfMC4wMDVfTkZFKSkgJT4lIAogIG11dGF0ZSgiUGxvdHRlZF9Mb2cxMF9QLXZhbHVlX0Zpc2hlcl8wLjA1X05GRSI9IAogIGlmX2Vsc2UgKE9SXzAuMDA1X05GRT49MSwgYExvZzEwX1AtdmFsdWVfRmlzaGVyXzAuMDVfTkZFYCotMSwgYExvZzEwX1AtdmFsdWVfRmlzaGVyXzAuMDVfTkZFYCwgbWlzc2luZz1OVUxMKSkgJT4lIAogIGFycmFuZ2UoZGVzYyhgUGxvdHRlZF9Mb2cxMF9QLXZhbHVlX0Zpc2hlcl8wLjA1X05GRWApLGRlc2MoT1JfMC4wMDVfTkZFKSkgJT4lIAogIHdyaXRlX2V4Y2VsX2NzdihwYXRoPSJ2b2xjYW5vX2FnZU92ZXI2MF9zYW1wbGVBRjAuMDFfYmlvdHlwZTJfYWxsR2VuZXNfdjYuY3N2IixuYT0iLiIsYXBwZW5kPUZBTFNFLGNvbF9uYW1lcz1UUlVFKQpgYGA=