1. load libraries
3. Create the EnhancedVolcano plot
EnhancedVolcano(Malignant_CD4Tcells_vs_Normal_CD4Tcells,
lab = Malignant_CD4Tcells_vs_Normal_CD4Tcells$gene,
x = "avg_log2FC",
y = "p_val_adj",
title = "MAST with Batch Correction (All Genes)",
pCutoff = 0.05,
FCcutoff = 1.0)
Avis : One or more p-values is 0. Converting to 10^-1 * current lowest non-zero p-value...

EnhancedVolcano(Malignant_CD4Tcells_vs_Normal_CD4Tcells,
lab = Malignant_CD4Tcells_vs_Normal_CD4Tcells$gene,
x = "avg_log2FC",
y = "p_val_adj",
selectLab = c('EPCAM', 'BCAT1', 'KIR3DL2', 'FOXM1', 'TWIST1', 'TNFSF9',
'CD80', 'IL1B', 'RPS4Y1',
'IL7R', 'TCF7', 'MKI67', 'CD70',
'IL2RA','TRBV6-2', 'TRBV10-3', 'TRBV4-2', 'TRBV9', 'TRBV7-9',
'TRAV12-1', 'CD8B', 'FCGR3A', 'GNLY', 'FOXP3', 'SELL',
'GIMAP1', 'RIPOR2', 'LEF1', 'HOXC9', 'SP5',
'CCL17', 'ETV4', 'THY1', 'FOXA2', 'ITGAD', 'S100P', 'TBX4',
'ID1', 'XCL1', 'SOX2', 'CD27', 'CD28','PLS3','CD70','RAB25' , 'TRBV27', 'TRBV2'),
title = "Malignant CD4 T cells(cell lines) vs normal CD4 T cells",
xlab = bquote(~Log[2]~ 'fold change'),
pCutoff = 0.05,
FCcutoff = 1.5,
pointSize = 3.0,
labSize = 5.0,
boxedLabels = TRUE,
colAlpha = 0.5,
legendPosition = 'right',
legendLabSize = 10,
legendIconSize = 4.0,
drawConnectors = TRUE,
widthConnectors = 0.5,
colConnectors = 'grey50',
arrowheads = FALSE,
max.overlaps = 30)
Avis : One or more p-values is 0. Converting to 10^-1 * current lowest non-zero p-value...

library(dplyr)
library(EnhancedVolcano)
# Assuming you have a data frame named Malignant_CD4Tcells_vs_Normal_CD4Tcells
# Filter genes based on lowest p-values but include all genes
filtered_genes <- Malignant_CD4Tcells_vs_Normal_CD4Tcells %>%
arrange(p_val_adj, desc(abs(avg_log2FC)))
# Create the EnhancedVolcano plot with the filtered data
EnhancedVolcano(
filtered_genes,
lab = ifelse(filtered_genes$p_val_adj <= 0.05 & abs(filtered_genes$avg_log2FC) >= 1.0, filtered_genes$gene, NA),
x = "avg_log2FC",
y = "p_val_adj",
title = "Malignant CD4 T cells(cell lines) vs normal CD4 T cells",
pCutoff = 0.05,
FCcutoff = 1.0,
legendPosition = 'right',
labCol = 'black',
labFace = 'bold',
boxedLabels = FALSE, # Set to FALSE to remove boxed labels
pointSize = 3.0,
labSize = 5.0,
col = c('grey70', 'black', 'blue', 'red'), # Customize point colors
selectLab = filtered_genes$gene[filtered_genes$p_val_adj <= 0.05 & abs(filtered_genes$avg_log2FC) >= 1.0] # Only label significant genes
)
Avis : One or more p-values is 0. Converting to 10^-1 * current lowest non-zero p-value...

EnhancedVolcano(
filtered_genes,
lab = ifelse(filtered_genes$p_val_adj <= 0.05 & abs(filtered_genes$avg_log2FC) >= 1.0, filtered_genes$gene, NA),
x = "avg_log2FC",
y = "p_val_adj",
title = "Malignant CD4 T cells (cell lines) vs Normal CD4 T cells",
subtitle = "Highlighting differentially expressed genes",
pCutoff = 0.05,
FCcutoff = 1.0,
legendPosition = 'right',
colAlpha = 0.8, # Slight transparency for non-significant points
col = c('grey70', 'black', 'blue', 'red'), # Custom color scheme
gridlines.major = TRUE,
gridlines.minor = FALSE,
selectLab = filtered_genes$gene[filtered_genes$p_val_adj <= 0.05 & abs(filtered_genes$avg_log2FC) >= 1.0]
)
Avis : One or more p-values is 0. Converting to 10^-1 * current lowest non-zero p-value...

4. Enrichment Analysis-1
# Step-by-Step Guide for Gene Set Enrichment Analysis (GSEA) or Over-Representation Analysis (ORA)
# Load the necessary libraries
library(clusterProfiler)
Registered S3 methods overwritten by 'treeio':
method from
MRCA.phylo tidytree
MRCA.treedata tidytree
Nnode.treedata tidytree
Ntip.treedata tidytree
ancestor.phylo tidytree
ancestor.treedata tidytree
child.phylo tidytree
child.treedata tidytree
full_join.phylo tidytree
full_join.treedata tidytree
groupClade.phylo tidytree
groupClade.treedata tidytree
groupOTU.phylo tidytree
groupOTU.treedata tidytree
is.rooted.treedata tidytree
nodeid.phylo tidytree
nodeid.treedata tidytree
nodelab.phylo tidytree
nodelab.treedata tidytree
offspring.phylo tidytree
offspring.treedata tidytree
parent.phylo tidytree
parent.treedata tidytree
root.treedata tidytree
rootnode.phylo tidytree
sibling.phylo tidytree
clusterProfiler v4.6.2 For help: https://yulab-smu.top/biomedical-knowledge-mining-book/
If you use clusterProfiler in published research, please cite:
T Wu, E Hu, S Xu, M Chen, P Guo, Z Dai, T Feng, L Zhou, W Tang, L Zhan, X Fu, S Liu, X Bo, and G Yu. clusterProfiler 4.0: A universal enrichment tool for interpreting omics data. The Innovation. 2021, 2(3):100141
Attachement du package : 'clusterProfiler'
L'objet suivant est masqué depuis 'package:stats':
filter
library(org.Hs.eg.db)
Le chargement a nécessité le package : AnnotationDbi
Le chargement a nécessité le package : stats4
Le chargement a nécessité le package : BiocGenerics
Attachement du package : 'BiocGenerics'
L'objet suivant est masqué depuis 'package:gridExtra':
combine
Les objets suivants sont masqués depuis 'package:dplyr':
combine, intersect, setdiff, union
L'objet suivant est masqué depuis 'package:SeuratObject':
intersect
Les objets suivants sont masqués depuis 'package:stats':
IQR, mad, sd, var, xtabs
Les objets suivants sont masqués depuis 'package:base':
anyDuplicated, aperm, append, as.data.frame, basename, cbind, colnames, dirname, do.call,
duplicated, eval, evalq, Filter, Find, get, grep, grepl, intersect, is.unsorted, lapply,
Map, mapply, match, mget, order, paste, pmax, pmax.int, pmin, pmin.int, Position, rank,
rbind, Reduce, rownames, sapply, setdiff, sort, table, tapply, union, unique, unsplit,
which.max, which.min
Le chargement a nécessité le package : Biobase
Welcome to Bioconductor
Vignettes contain introductory material; view with 'browseVignettes()'. To cite
Bioconductor, see 'citation("Biobase")', and for packages 'citation("pkgname")'.
Le chargement a nécessité le package : IRanges
Le chargement a nécessité le package : S4Vectors
Attachement du package : 'S4Vectors'
L'objet suivant est masqué depuis 'package:clusterProfiler':
rename
Les objets suivants sont masqués depuis 'package:dplyr':
first, rename
Les objets suivants sont masqués depuis 'package:base':
expand.grid, I, unname
Attachement du package : 'IRanges'
L'objet suivant est masqué depuis 'package:clusterProfiler':
slice
Les objets suivants sont masqués depuis 'package:dplyr':
collapse, desc, slice
L'objet suivant est masqué depuis 'package:sp':
%over%
Attachement du package : 'AnnotationDbi'
L'objet suivant est masqué depuis 'package:clusterProfiler':
select
L'objet suivant est masqué depuis 'package:dplyr':
select
library(enrichplot)
library(ReactomePA)
ReactomePA v1.42.0 For help: https://yulab-smu.top/biomedical-knowledge-mining-book/
If you use ReactomePA in published research, please cite:
Guangchuang Yu, Qing-Yu He. ReactomePA: an R/Bioconductor package for reactome pathway analysis and visualization. Molecular BioSystems 2016, 12(2):477-479
# Get upregulated genes based on log2FC and p-value thresholds
upregulated_genes <- Malignant_CD4Tcells_vs_Normal_CD4Tcells[Malignant_CD4Tcells_vs_Normal_CD4Tcells$avg_log2FC > 0.5 & Malignant_CD4Tcells_vs_Normal_CD4Tcells$p_val_adj < 0.05, ]
# Get downregulated genes based on log2FC and p-value thresholds
downregulated_genes <- Malignant_CD4Tcells_vs_Normal_CD4Tcells[Malignant_CD4Tcells_vs_Normal_CD4Tcells$avg_log2FC < -0.5 & Malignant_CD4Tcells_vs_Normal_CD4Tcells$p_val_adj < 0.05, ]
# Gene Ontology (GO) Enrichment Analysis
# GO enrichment for upregulated genes
go_up <- enrichGO(gene = upregulated_genes$gene,
OrgDb = org.Hs.eg.db,
keyType = "SYMBOL",
ont = "BP", # Biological Process (BP), Molecular Function (MF), Cellular Component (CC)
pAdjustMethod = "BH",
pvalueCutoff = 0.05)
# GO enrichment for downregulated genes
go_down <- enrichGO(gene = downregulated_genes$gene,
OrgDb = org.Hs.eg.db,
keyType = "SYMBOL",
ont = "BP",
pAdjustMethod = "BH",
pvalueCutoff = 0.05)
# Visualize the top enriched GO terms
dotplot(go_up, showCategory = 10, title = "GO Enrichment for Upregulated Genes")

dotplot(go_down, showCategory = 10, title = "GO Enrichment for Downregulated Genes")

# KEGG Pathway Enrichment
# Convert gene symbols to Entrez IDs for KEGG analysis
upregulated_entrez <- bitr(upregulated_genes$gene, fromType = "SYMBOL", toType = "ENTREZID", OrgDb = org.Hs.eg.db)$ENTREZID
'select()' returned 1:1 mapping between keys and columns
Avis : 2.44% of input gene IDs are fail to map...
downregulated_entrez <- bitr(downregulated_genes$gene, fromType = "SYMBOL", toType = "ENTREZID", OrgDb = org.Hs.eg.db)$ENTREZID
'select()' returned 1:1 mapping between keys and columns
Avis : 3.45% of input gene IDs are fail to map...
# KEGG pathway enrichment for upregulated genes
kegg_up <- enrichKEGG(gene = upregulated_entrez,
organism = "hsa",
pvalueCutoff = 0.05)
Reading KEGG annotation online: "https://rest.kegg.jp/link/hsa/pathway"...
Reading KEGG annotation online: "https://rest.kegg.jp/list/pathway/hsa"...
# KEGG pathway enrichment for downregulated genes
kegg_down <- enrichKEGG(gene = downregulated_entrez,
organism = "hsa",
pvalueCutoff = 0.05)
# Visualize KEGG pathway results
dotplot(kegg_up, showCategory = 10, title = "KEGG Pathway Enrichment for Upregulated Genes")

dotplot(kegg_down, showCategory = 6, title = "KEGG Pathway Enrichment for Downregulated Genes")

# Reactome Pathway Enrichment
# Reactome pathway enrichment for upregulated genes
reactome_up <- enrichPathway(gene = upregulated_entrez,
organism = "human",
pvalueCutoff = 0.05)
# Reactome pathway enrichment for downregulated genes
reactome_down <- enrichPathway(gene = downregulated_entrez,
organism = "human",
pvalueCutoff = 0.05)
# Visualize Reactome pathways
dotplot(reactome_up, showCategory = 10, title = "Reactome Pathway Enrichment for Upregulated Genes")

#dotplot(reactome_down, showCategory = 10, title = "Reactome Pathway Enrichment for Downregulated Genes")
# Gene Set Enrichment Analysis (GSEA)
# Create a ranked list of genes (log2FC as ranking metric)
gene_list <- Malignant_CD4Tcells_vs_Normal_CD4Tcells$avg_log2FC
names(gene_list) <- Malignant_CD4Tcells_vs_Normal_CD4Tcells$gene # Use the $gene column for gene symbols
gene_list <- sort(gene_list, decreasing = TRUE)
# Convert gene symbols to Entrez IDs for GSEA
gene_df <- bitr(names(gene_list), fromType = "SYMBOL", toType = "ENTREZID", OrgDb = org.Hs.eg.db)
'select()' returned 1:1 mapping between keys and columns
Avis : 2.47% of input gene IDs are fail to map...
# Ensure the gene list matches the Entrez IDs
gene_list <- gene_list[names(gene_list) %in% gene_df$SYMBOL]
# Replace gene symbols with Entrez IDs
names(gene_list) <- gene_df$ENTREZID[match(names(gene_list), gene_df$SYMBOL)]
# Run GSEA using KEGG pathways
gsea_kegg <- gseKEGG(geneList = gene_list,
organism = "hsa",
pvalueCutoff = 0.05)
preparing geneSet collections...
GSEA analysis...
Avis : There are ties in the preranked stats (0.1% of the list).
The order of those tied genes will be arbitrary, which may produce unexpected results.Avis : There were 1 pathways for which P-values were not calculated properly due to unbalanced (positive and negative) gene-level statistic values. For such pathways pval, padj, NES, log2err are set to NA. You can try to increase the value of the argument nPermSimple (for example set it nPermSimple = 10000)Avis : For some of the pathways the P-values were likely overestimated. For such pathways log2err is set to NA.Avis : For some pathways, in reality P-values are less than 1e-10. You can set the `eps` argument to zero for better estimation.leading edge analysis...
done...
# Plot the GSEA results
gseaplot(gsea_kegg, geneSetID = 1, title = "Top KEGG Pathway")

# Extract the name of the top KEGG pathway
top_pathway <- gsea_kegg@result[1, "Description"]
# Plot GSEA with the top pathway's name as the title
gseaplot(gsea_kegg, geneSetID = 1, title = top_pathway)

NA
NA
4.2. Enrichment Analysis-2
# Load necessary libraries
library(clusterProfiler)
library(org.Hs.eg.db)
library(msigdbr)
library(enrichplot)
# Load Hallmark gene sets from msigdbr
hallmark_sets <- msigdbr(species = "Homo sapiens", category = "H") # "H" is for Hallmark gene sets
# Get upregulated and downregulated genes based on log2 fold change and adjusted p-value
upregulated_genes <- Malignant_CD4Tcells_vs_Normal_CD4Tcells[Malignant_CD4Tcells_vs_Normal_CD4Tcells$avg_log2FC > 0.5 & Malignant_CD4Tcells_vs_Normal_CD4Tcells$p_val_adj < 0.05, ]
downregulated_genes <- Malignant_CD4Tcells_vs_Normal_CD4Tcells[Malignant_CD4Tcells_vs_Normal_CD4Tcells$avg_log2FC < -0.5 & Malignant_CD4Tcells_vs_Normal_CD4Tcells$p_val_adj < 0.05, ]
# Convert gene symbols to uppercase for consistency
upregulated_genes$gene <- toupper(upregulated_genes$gene)
downregulated_genes$gene <- toupper(downregulated_genes$gene)
# Check for overlap between your upregulated/downregulated genes and Hallmark gene sets
upregulated_in_hallmark <- intersect(upregulated_genes$gene, hallmark_sets$gene_symbol)
downregulated_in_hallmark <- intersect(downregulated_genes$gene, hallmark_sets$gene_symbol)
# Print the number of overlapping genes for both upregulated and downregulated genes
cat("Number of upregulated genes in Hallmark gene sets:", length(upregulated_in_hallmark), "\n")
Number of upregulated genes in Hallmark gene sets: 1384
cat("Number of downregulated genes in Hallmark gene sets:", length(downregulated_in_hallmark), "\n")
Number of downregulated genes in Hallmark gene sets: 53
# If there are genes to analyze, proceed with enrichment analysis
if (length(upregulated_in_hallmark) > 0) {
# Perform enrichment analysis for upregulated genes using Hallmark gene sets
hallmark_up <- enricher(gene = upregulated_in_hallmark,
TERM2GENE = hallmark_sets[, c("gs_name", "gene_symbol")], # Ensure TERM2GENE uses correct columns
pvalueCutoff = 0.05)
# Check if results exist
if (!is.null(hallmark_up) && nrow(hallmark_up) > 0) {
# Visualize results if available
dotplot(hallmark_up, showCategory = 20, title = "Hallmark Pathway Enrichment for Upregulated Genes")
} else {
cat("No significant enrichment found for upregulated genes.\n")
}
} else {
cat("No upregulated genes overlap with Hallmark gene sets.\n")
}

if (length(downregulated_in_hallmark) > 0) {
# Perform enrichment analysis for downregulated genes using Hallmark gene sets
hallmark_down <- enricher(gene = downregulated_in_hallmark,
TERM2GENE = hallmark_sets[, c("gs_name", "gene_symbol")], # Ensure TERM2GENE uses correct columns
pvalueCutoff = 0.05)
# Check if results exist
if (!is.null(hallmark_down) && nrow(hallmark_down) > 0) {
# Visualize results if available
dotplot(hallmark_down, showCategory = 20, title = "Hallmark Pathway Enrichment for Downregulated Genes")
} else {
cat("No significant enrichment found for downregulated genes.\n")
}
} else {
cat("No downregulated genes overlap with Hallmark gene sets.\n")
}

NA
NA
NA
NA
NA
4.3. Hallmark-GSEA
# Gene Set Enrichment Analysis (GSEA) for Hallmark Pathways
# Create a ranked list of genes (log2FC as ranking metric)
gene_list <- Malignant_CD4Tcells_vs_Normal_CD4Tcells$avg_log2FC
names(gene_list) <- Malignant_CD4Tcells_vs_Normal_CD4Tcells$gene
gene_list <- sort(gene_list, decreasing = TRUE)
# Convert gene symbols to Entrez IDs for GSEA
gene_df <- bitr(names(gene_list),
fromType = "SYMBOL",
toType = "ENTREZID",
OrgDb = org.Hs.eg.db)
'select()' returned 1:1 mapping between keys and columns
Avis : 2.47% of input gene IDs are fail to map...
# Filter out genes without Entrez ID mappings
gene_list <- gene_list[names(gene_list) %in% gene_df$SYMBOL]
# Replace gene symbols with Entrez IDs in the gene list
names(gene_list) <- gene_df$ENTREZID[match(names(gene_list), gene_df$SYMBOL)]
# Run GSEA using Hallmark pathways
gsea_hallmark <- GSEA(geneList = gene_list,
TERM2GENE = hallmark_sets[, c("gs_name", "entrez_gene")],
pvalueCutoff = 0.05)
preparing geneSet collections...
GSEA analysis...
Avis : There are ties in the preranked stats (0.1% of the list).
The order of those tied genes will be arbitrary, which may produce unexpected results.Avis : For some pathways, in reality P-values are less than 1e-10. You can set the `eps` argument to zero for better estimation.leading edge analysis...
done...
# Check and visualize GSEA results
if (!is.null(gsea_hallmark) && nrow(gsea_hallmark) > 0) {
# Visualize top GSEA results for Hallmark pathways
dotplot(gsea_hallmark, showCategory = 20, title = "GSEA for Hallmark Pathways")
# Plot enrichment score for the top pathway
gseaplot(gsea_hallmark, geneSetID = 1, title = "Top Hallmark Pathway")
# Extract the name of the top Hallmark pathway
top_hallmark <- gsea_hallmark@result[1, "Description"]
# Plot GSEA with the top pathway's name as the title
gseaplot(gsea_hallmark, geneSetID = 1, title = top_hallmark)
} else {
cat("No significant GSEA results for Hallmark pathways.\n")
}

NA
NA
NA
5. ggplot2 for Volcano
library(ggplot2)
library(ggrepel)
# Identify top and bottom genes
top_genes <- Malignant_CD4Tcells_vs_Normal_CD4Tcells[Malignant_CD4Tcells_vs_Normal_CD4Tcells$p_val_adj < 0.05 & Malignant_CD4Tcells_vs_Normal_CD4Tcells$avg_log2FC > 0.5, ]
bottom_genes <- Malignant_CD4Tcells_vs_Normal_CD4Tcells[Malignant_CD4Tcells_vs_Normal_CD4Tcells$p_val_adj < 0.05 & Malignant_CD4Tcells_vs_Normal_CD4Tcells$avg_log2FC < -0.5, ]
# Create a new column for color based on significance
Malignant_CD4Tcells_vs_Normal_CD4Tcells$color <- ifelse(Malignant_CD4Tcells_vs_Normal_CD4Tcells$avg_log2FC > 0.5, "Upregulated genes",
ifelse(Malignant_CD4Tcells_vs_Normal_CD4Tcells$avg_log2FC < -0.5, "Downregulated genes", "Nonsignificant"))
# Create a volcano plot
ggplot(Malignant_CD4Tcells_vs_Normal_CD4Tcells, aes(x = avg_log2FC, y = -log10(p_val_adj))) +
geom_point(aes(color = color), alpha = 0.7, size = 2) +
# Add labels for top and bottom genes
geom_text_repel(data = top_genes, aes(label = gene), color = "black", vjust = 1, fontface = "bold") +
geom_text_repel(data = bottom_genes, aes(label = gene), color = "black", vjust = -1, fontface = "bold") +
# Customize labels and title
labs(title = "Volcano Plot",
x = "log2 Fold Change",
y = "-log10(p-value)") +
# # Add significance threshold lines
geom_hline(yintercept = -log10(0.00001), linetype = "dashed", color = "black") +
geom_vline(xintercept = c(-0.5, 0.5), linetype = "dashed", color = "black") +
# Set colors for top and bottom genes
scale_color_manual(values = c("Upregulated genes" = "red", "Downregulated genes" = "blue", "Nonsignificant" = "darkgrey")) +
# Customize theme if needed
theme_minimal()

NA
NA
NA
NA
NA
5. ggplot3 for Volcano
# Load necessary libraries
library(ggplot2)
library(ggrepel)
# Identify top and bottom genes
top_genes <- Malignant_CD4Tcells_vs_Normal_CD4Tcells[Malignant_CD4Tcells_vs_Normal_CD4Tcells$p_val_adj < 0.00001 & Malignant_CD4Tcells_vs_Normal_CD4Tcells$avg_log2FC > 4, ]
bottom_genes <- Malignant_CD4Tcells_vs_Normal_CD4Tcells[Malignant_CD4Tcells_vs_Normal_CD4Tcells$p_val_adj < 0.00001 & Malignant_CD4Tcells_vs_Normal_CD4Tcells$avg_log2FC < -4, ]
# Create a new column for color based on significance
Malignant_CD4Tcells_vs_Normal_CD4Tcells$color <- ifelse(Malignant_CD4Tcells_vs_Normal_CD4Tcells$avg_log2FC > 0.5,
"Upregulated genes",
ifelse(Malignant_CD4Tcells_vs_Normal_CD4Tcells$avg_log2FC < -0.5,
"Downregulated genes",
"Nonsignificant"))
# Create the volcano plot
ggplot(Malignant_CD4Tcells_vs_Normal_CD4Tcells, aes(x = avg_log2FC, y = -log10(p_val_adj))) +
geom_point(aes(color = color), alpha = 0.7, size = 2) +
# Add labels next to the dots without repel lines
geom_text(data = top_genes, aes(label = gene), hjust = -0.2, vjust = 0, size = 3, color = "black", fontface = "bold") +
geom_text(data = bottom_genes, aes(label = gene), hjust = 1.2, vjust = 0, size = 3, color = "black", fontface = "bold") +
# Customize labels and title
labs(title = "Volcano Plot",
x = "log2 Fold Change",
y = "-log10(p-value)") +
# Add significance threshold lines
geom_hline(yintercept = -log10(0.00001), linetype = "dashed", color = "black") +
geom_vline(xintercept = c(-0.5, 0.5), linetype = "dashed", color = "black") +
# Set colors for top and bottom genes
scale_color_manual(values = c("Upregulated genes" = "red",
"Downregulated genes" = "blue",
"Nonsignificant" = "darkgrey")) +
# Customize theme
theme_minimal()

NA
NA
LS0tCnRpdGxlOiAiRGlmZmVyZW50aWFsIEV4cHJlc3Npb24gQW5hbHlzaXMgb2YgTDEgdnMgQ29udHJvbChOb3JtYWwgQ0Q0IFRjZWxscyktR1NFQSIKYXV0aG9yOiBOYXNpciBNYWhtb29kIEFiYmFzaQpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiCm91dHB1dDoKICAjcm1kZm9ybWF0czo6cmVhZHRoZWRvd24KICBodG1sX25vdGVib29rOgogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6IHRydWUKICAgIHRvY19jb2xsYXBzZWQ6IHRydWUKLS0tCgojIDEuIGxvYWQgbGlicmFyaWVzCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQoKbGlicmFyeShTZXVyYXQpCmxpYnJhcnkoU2V1cmF0T2JqZWN0KQpsaWJyYXJ5KFNldXJhdERhdGEpCmxpYnJhcnkocGF0Y2h3b3JrKQpsaWJyYXJ5KGhhcm1vbnkpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShjb3dwbG90KQpsaWJyYXJ5KHJldGljdWxhdGUpCmxpYnJhcnkoQXppbXV0aCkKbGlicmFyeShkcGx5cikKbGlicmFyeShSdHNuZSkKbGlicmFyeShoYXJtb255KQpsaWJyYXJ5KGdyaWRFeHRyYSkKbGlicmFyeShFbmhhbmNlZFZvbGNhbm8pCiAgCgpgYGAKCiMgMi4gUGVyZm9ybSBERSBhbmFseXNpcyB1c2luZyBNYWxpZ25hbnRfQ0Q0VGNlbGxzX3ZzX05vcm1hbF9DRDRUY2VsbHMgZ2VuZXMKYGBge3IgZGF0YTEsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTEyfQoKTWFsaWduYW50X0NENFRjZWxsc192c19Ob3JtYWxfQ0Q0VGNlbGxzIDwtIHJlYWQuY3N2KCIuLi8uLi8yLURFX29uX0hhcm1vbnlfSW50ZWdyYXRpb24vRmlsdGVyZWRfREVfUmVzdWx0c19MMV93aXRoX01lYW5FeHByLmNzdiIsIGhlYWRlciA9IFQpCmBgYAoKIyAzLiBDcmVhdGUgdGhlIEVuaGFuY2VkVm9sY2FubyBwbG90CmBgYHtyIGVuaGFuY2VkViwgZmlnLmhlaWdodD0xMiwgZmlnLndpZHRoPTE2fQoKRW5oYW5jZWRWb2xjYW5vKE1hbGlnbmFudF9DRDRUY2VsbHNfdnNfTm9ybWFsX0NENFRjZWxscywKICAgICAgICAgICAgICAgIGxhYiA9IE1hbGlnbmFudF9DRDRUY2VsbHNfdnNfTm9ybWFsX0NENFRjZWxscyRnZW5lLAogICAgICAgICAgICAgICAgeCA9ICJhdmdfbG9nMkZDIiwKICAgICAgICAgICAgICAgIHkgPSAicF92YWxfYWRqIiwKICAgICAgICAgICAgICAgIHRpdGxlID0gIk1BU1Qgd2l0aCBCYXRjaCBDb3JyZWN0aW9uIChBbGwgR2VuZXMpIiwKICAgICAgICAgICAgICAgIHBDdXRvZmYgPSAwLjA1LAogICAgICAgICAgICAgICAgRkNjdXRvZmYgPSAxLjApCgoKRW5oYW5jZWRWb2xjYW5vKE1hbGlnbmFudF9DRDRUY2VsbHNfdnNfTm9ybWFsX0NENFRjZWxscywgCiAgICAgICAgICAgICAgICBsYWIgPSBNYWxpZ25hbnRfQ0Q0VGNlbGxzX3ZzX05vcm1hbF9DRDRUY2VsbHMkZ2VuZSwKICAgICAgICAgICAgICAgIHggPSAiYXZnX2xvZzJGQyIsIAogICAgICAgICAgICAgICAgeSA9ICJwX3ZhbF9hZGoiLAogICAgICAgICAgICAgICAgc2VsZWN0TGFiID0gYygnRVBDQU0nLCAnQkNBVDEnLCAnS0lSM0RMMicsICdGT1hNMScsICdUV0lTVDEnLCAnVE5GU0Y5JywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdDRDgwJywgICdJTDFCJywgJ1JQUzRZMScsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnSUw3UicsICdUQ0Y3JywgICdNS0k2NycsICdDRDcwJywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdJTDJSQScsJ1RSQlY2LTInLCAnVFJCVjEwLTMnLCAnVFJCVjQtMicsICdUUkJWOScsICdUUkJWNy05JywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdUUkFWMTItMScsICdDRDhCJywgJ0ZDR1IzQScsICdHTkxZJywgJ0ZPWFAzJywgJ1NFTEwnLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0dJTUFQMScsICdSSVBPUjInLCAnTEVGMScsICdIT1hDOScsICdTUDUnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnQ0NMMTcnLCAnRVRWNCcsICdUSFkxJywgJ0ZPWEEyJywgJ0lUR0FEJywgJ1MxMDBQJywgJ1RCWDQnLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0lEMScsICdYQ0wxJywgJ1NPWDInLCAnQ0QyNycsICdDRDI4JywnUExTMycsJ0NENzAnLCdSQUIyNScgLCAnVFJCVjI3JywgJ1RSQlYyJyksCiAgICAgICAgICAgICAgICB0aXRsZSA9ICJNYWxpZ25hbnQgQ0Q0IFQgY2VsbHMoY2VsbCBsaW5lcykgdnMgbm9ybWFsIENENCBUIGNlbGxzIiwKICAgICAgICAgICAgICAgIHhsYWIgPSBicXVvdGUofkxvZ1syXX4gJ2ZvbGQgY2hhbmdlJyksCiAgICAgICAgICAgICAgICBwQ3V0b2ZmID0gMC4wNSwKICAgICAgICAgICAgICAgIEZDY3V0b2ZmID0gMS41LCAKICAgICAgICAgICAgICAgIHBvaW50U2l6ZSA9IDMuMCwKICAgICAgICAgICAgICAgIGxhYlNpemUgPSA1LjAsCiAgICAgICAgICAgICAgICBib3hlZExhYmVscyA9IFRSVUUsCiAgICAgICAgICAgICAgICBjb2xBbHBoYSA9IDAuNSwKICAgICAgICAgICAgICAgIGxlZ2VuZFBvc2l0aW9uID0gJ3JpZ2h0JywKICAgICAgICAgICAgICAgIGxlZ2VuZExhYlNpemUgPSAxMCwKICAgICAgICAgICAgICAgIGxlZ2VuZEljb25TaXplID0gNC4wLAogICAgICAgICAgICAgICAgZHJhd0Nvbm5lY3RvcnMgPSBUUlVFLAogICAgICAgICAgICAgICAgd2lkdGhDb25uZWN0b3JzID0gMC41LAogICAgICAgICAgICAgICAgY29sQ29ubmVjdG9ycyA9ICdncmV5NTAnLAogICAgICAgICAgICAgICAgYXJyb3doZWFkcyA9IEZBTFNFLAogICAgICAgICAgICAgICAgbWF4Lm92ZXJsYXBzID0gMzApCgoKbGlicmFyeShkcGx5cikKbGlicmFyeShFbmhhbmNlZFZvbGNhbm8pCgojIEFzc3VtaW5nIHlvdSBoYXZlIGEgZGF0YSBmcmFtZSBuYW1lZCBNYWxpZ25hbnRfQ0Q0VGNlbGxzX3ZzX05vcm1hbF9DRDRUY2VsbHMKIyBGaWx0ZXIgZ2VuZXMgYmFzZWQgb24gbG93ZXN0IHAtdmFsdWVzIGJ1dCBpbmNsdWRlIGFsbCBnZW5lcwpmaWx0ZXJlZF9nZW5lcyA8LSBNYWxpZ25hbnRfQ0Q0VGNlbGxzX3ZzX05vcm1hbF9DRDRUY2VsbHMgJT4lCiAgYXJyYW5nZShwX3ZhbF9hZGosIGRlc2MoYWJzKGF2Z19sb2cyRkMpKSkKCiMgQ3JlYXRlIHRoZSBFbmhhbmNlZFZvbGNhbm8gcGxvdCB3aXRoIHRoZSBmaWx0ZXJlZCBkYXRhCkVuaGFuY2VkVm9sY2FubygKICBmaWx0ZXJlZF9nZW5lcywgCiAgbGFiID0gaWZlbHNlKGZpbHRlcmVkX2dlbmVzJHBfdmFsX2FkaiA8PSAwLjA1ICYgYWJzKGZpbHRlcmVkX2dlbmVzJGF2Z19sb2cyRkMpID49IDEuMCwgZmlsdGVyZWRfZ2VuZXMkZ2VuZSwgTkEpLAogIHggPSAiYXZnX2xvZzJGQyIsIAogIHkgPSAicF92YWxfYWRqIiwKICB0aXRsZSA9ICJNYWxpZ25hbnQgQ0Q0IFQgY2VsbHMoY2VsbCBsaW5lcykgdnMgbm9ybWFsIENENCBUIGNlbGxzIiwKICBwQ3V0b2ZmID0gMC4wNSwKICBGQ2N1dG9mZiA9IDEuMCwKICBsZWdlbmRQb3NpdGlvbiA9ICdyaWdodCcsIAogIGxhYkNvbCA9ICdibGFjaycsCiAgbGFiRmFjZSA9ICdib2xkJywKICBib3hlZExhYmVscyA9IEZBTFNFLCAgIyBTZXQgdG8gRkFMU0UgdG8gcmVtb3ZlIGJveGVkIGxhYmVscwogIHBvaW50U2l6ZSA9IDMuMCwKICBsYWJTaXplID0gNS4wLAogIGNvbCA9IGMoJ2dyZXk3MCcsICdibGFjaycsICdibHVlJywgJ3JlZCcpLCAgIyBDdXN0b21pemUgcG9pbnQgY29sb3JzCiAgc2VsZWN0TGFiID0gZmlsdGVyZWRfZ2VuZXMkZ2VuZVtmaWx0ZXJlZF9nZW5lcyRwX3ZhbF9hZGogPD0gMC4wNSAmIGFicyhmaWx0ZXJlZF9nZW5lcyRhdmdfbG9nMkZDKSA+PSAxLjBdICAjIE9ubHkgbGFiZWwgc2lnbmlmaWNhbnQgZ2VuZXMKKQoKCgpFbmhhbmNlZFZvbGNhbm8oCiAgZmlsdGVyZWRfZ2VuZXMsIAogIGxhYiA9IGlmZWxzZShmaWx0ZXJlZF9nZW5lcyRwX3ZhbF9hZGogPD0gMC4wNSAmIGFicyhmaWx0ZXJlZF9nZW5lcyRhdmdfbG9nMkZDKSA+PSAxLjAsIGZpbHRlcmVkX2dlbmVzJGdlbmUsIE5BKSwKICB4ID0gImF2Z19sb2cyRkMiLCAKICB5ID0gInBfdmFsX2FkaiIsCiAgdGl0bGUgPSAiTWFsaWduYW50IENENCBUIGNlbGxzIChjZWxsIGxpbmVzKSB2cyBOb3JtYWwgQ0Q0IFQgY2VsbHMiLAogIHN1YnRpdGxlID0gIkhpZ2hsaWdodGluZyBkaWZmZXJlbnRpYWxseSBleHByZXNzZWQgZ2VuZXMiLAogIHBDdXRvZmYgPSAwLjA1LAogIEZDY3V0b2ZmID0gMS4wLAogIGxlZ2VuZFBvc2l0aW9uID0gJ3JpZ2h0JywKICBjb2xBbHBoYSA9IDAuOCwgICMgU2xpZ2h0IHRyYW5zcGFyZW5jeSBmb3Igbm9uLXNpZ25pZmljYW50IHBvaW50cwogIGNvbCA9IGMoJ2dyZXk3MCcsICdibGFjaycsICdibHVlJywgJ3JlZCcpLCAgIyBDdXN0b20gY29sb3Igc2NoZW1lCiAgZ3JpZGxpbmVzLm1ham9yID0gVFJVRSwKICBncmlkbGluZXMubWlub3IgPSBGQUxTRSwKICBzZWxlY3RMYWIgPSBmaWx0ZXJlZF9nZW5lcyRnZW5lW2ZpbHRlcmVkX2dlbmVzJHBfdmFsX2FkaiA8PSAwLjA1ICYgYWJzKGZpbHRlcmVkX2dlbmVzJGF2Z19sb2cyRkMpID49IDEuMF0KKSAKCgpgYGAKCgojIDQuIEVucmljaG1lbnQgQW5hbHlzaXMtMQpgYGB7ciAsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTEyfQoKIyBTdGVwLWJ5LVN0ZXAgR3VpZGUgZm9yIEdlbmUgU2V0IEVucmljaG1lbnQgQW5hbHlzaXMgKEdTRUEpIG9yIE92ZXItUmVwcmVzZW50YXRpb24gQW5hbHlzaXMgKE9SQSkKCiMgTG9hZCB0aGUgbmVjZXNzYXJ5IGxpYnJhcmllcwpsaWJyYXJ5KGNsdXN0ZXJQcm9maWxlcikKbGlicmFyeShvcmcuSHMuZWcuZGIpCmxpYnJhcnkoZW5yaWNocGxvdCkKbGlicmFyeShSZWFjdG9tZVBBKQoKIyBHZXQgdXByZWd1bGF0ZWQgZ2VuZXMgYmFzZWQgb24gbG9nMkZDIGFuZCBwLXZhbHVlIHRocmVzaG9sZHMKdXByZWd1bGF0ZWRfZ2VuZXMgPC0gTWFsaWduYW50X0NENFRjZWxsc192c19Ob3JtYWxfQ0Q0VGNlbGxzW01hbGlnbmFudF9DRDRUY2VsbHNfdnNfTm9ybWFsX0NENFRjZWxscyRhdmdfbG9nMkZDID4gMC41ICYgTWFsaWduYW50X0NENFRjZWxsc192c19Ob3JtYWxfQ0Q0VGNlbGxzJHBfdmFsX2FkaiA8IDAuMDUsIF0KCiMgR2V0IGRvd25yZWd1bGF0ZWQgZ2VuZXMgYmFzZWQgb24gbG9nMkZDIGFuZCBwLXZhbHVlIHRocmVzaG9sZHMKZG93bnJlZ3VsYXRlZF9nZW5lcyA8LSBNYWxpZ25hbnRfQ0Q0VGNlbGxzX3ZzX05vcm1hbF9DRDRUY2VsbHNbTWFsaWduYW50X0NENFRjZWxsc192c19Ob3JtYWxfQ0Q0VGNlbGxzJGF2Z19sb2cyRkMgPCAtMC41ICYgTWFsaWduYW50X0NENFRjZWxsc192c19Ob3JtYWxfQ0Q0VGNlbGxzJHBfdmFsX2FkaiA8IDAuMDUsIF0KCiMgR2VuZSBPbnRvbG9neSAoR08pIEVucmljaG1lbnQgQW5hbHlzaXMKIyBHTyBlbnJpY2htZW50IGZvciB1cHJlZ3VsYXRlZCBnZW5lcwpnb191cCA8LSBlbnJpY2hHTyhnZW5lID0gdXByZWd1bGF0ZWRfZ2VuZXMkZ2VuZSwgCiAgICAgICAgICAgICAgICAgIE9yZ0RiID0gb3JnLkhzLmVnLmRiLCAKICAgICAgICAgICAgICAgICAga2V5VHlwZSA9ICJTWU1CT0wiLCAKICAgICAgICAgICAgICAgICAgb250ID0gIkJQIiwgICAjIEJpb2xvZ2ljYWwgUHJvY2VzcyAoQlApLCBNb2xlY3VsYXIgRnVuY3Rpb24gKE1GKSwgQ2VsbHVsYXIgQ29tcG9uZW50IChDQykKICAgICAgICAgICAgICAgICAgcEFkanVzdE1ldGhvZCA9ICJCSCIsIAogICAgICAgICAgICAgICAgICBwdmFsdWVDdXRvZmYgPSAwLjA1KQoKIyBHTyBlbnJpY2htZW50IGZvciBkb3ducmVndWxhdGVkIGdlbmVzCmdvX2Rvd24gPC0gZW5yaWNoR08oZ2VuZSA9IGRvd25yZWd1bGF0ZWRfZ2VuZXMkZ2VuZSwgCiAgICAgICAgICAgICAgICAgICAgT3JnRGIgPSBvcmcuSHMuZWcuZGIsIAogICAgICAgICAgICAgICAgICAgIGtleVR5cGUgPSAiU1lNQk9MIiwgCiAgICAgICAgICAgICAgICAgICAgb250ID0gIkJQIiwgCiAgICAgICAgICAgICAgICAgICAgcEFkanVzdE1ldGhvZCA9ICJCSCIsIAogICAgICAgICAgICAgICAgICAgIHB2YWx1ZUN1dG9mZiA9IDAuMDUpCgojIFZpc3VhbGl6ZSB0aGUgdG9wIGVucmljaGVkIEdPIHRlcm1zCmRvdHBsb3QoZ29fdXAsIHNob3dDYXRlZ29yeSA9IDEwLCB0aXRsZSA9ICJHTyBFbnJpY2htZW50IGZvciBVcHJlZ3VsYXRlZCBHZW5lcyIpCmRvdHBsb3QoZ29fZG93biwgc2hvd0NhdGVnb3J5ID0gMTAsIHRpdGxlID0gIkdPIEVucmljaG1lbnQgZm9yIERvd25yZWd1bGF0ZWQgR2VuZXMiKQoKIyBLRUdHIFBhdGh3YXkgRW5yaWNobWVudAojIENvbnZlcnQgZ2VuZSBzeW1ib2xzIHRvIEVudHJleiBJRHMgZm9yIEtFR0cgYW5hbHlzaXMKdXByZWd1bGF0ZWRfZW50cmV6IDwtIGJpdHIodXByZWd1bGF0ZWRfZ2VuZXMkZ2VuZSwgZnJvbVR5cGUgPSAiU1lNQk9MIiwgdG9UeXBlID0gIkVOVFJFWklEIiwgT3JnRGIgPSBvcmcuSHMuZWcuZGIpJEVOVFJFWklECmRvd25yZWd1bGF0ZWRfZW50cmV6IDwtIGJpdHIoZG93bnJlZ3VsYXRlZF9nZW5lcyRnZW5lLCBmcm9tVHlwZSA9ICJTWU1CT0wiLCB0b1R5cGUgPSAiRU5UUkVaSUQiLCBPcmdEYiA9IG9yZy5Icy5lZy5kYikkRU5UUkVaSUQKCiMgS0VHRyBwYXRod2F5IGVucmljaG1lbnQgZm9yIHVwcmVndWxhdGVkIGdlbmVzCmtlZ2dfdXAgPC0gZW5yaWNoS0VHRyhnZW5lID0gdXByZWd1bGF0ZWRfZW50cmV6LCAKICAgICAgICAgICAgICAgICAgICAgIG9yZ2FuaXNtID0gImhzYSIsIAogICAgICAgICAgICAgICAgICAgICAgcHZhbHVlQ3V0b2ZmID0gMC4wNSkKCiMgS0VHRyBwYXRod2F5IGVucmljaG1lbnQgZm9yIGRvd25yZWd1bGF0ZWQgZ2VuZXMKa2VnZ19kb3duIDwtIGVucmljaEtFR0coZ2VuZSA9IGRvd25yZWd1bGF0ZWRfZW50cmV6LCAKICAgICAgICAgICAgICAgICAgICAgICAgb3JnYW5pc20gPSAiaHNhIiwgCiAgICAgICAgICAgICAgICAgICAgICAgIHB2YWx1ZUN1dG9mZiA9IDAuMDUpCgojIFZpc3VhbGl6ZSBLRUdHIHBhdGh3YXkgcmVzdWx0cwpkb3RwbG90KGtlZ2dfdXAsIHNob3dDYXRlZ29yeSA9IDEwLCB0aXRsZSA9ICJLRUdHIFBhdGh3YXkgRW5yaWNobWVudCBmb3IgVXByZWd1bGF0ZWQgR2VuZXMiKQpkb3RwbG90KGtlZ2dfZG93biwgc2hvd0NhdGVnb3J5ID0gNiwgdGl0bGUgPSAiS0VHRyBQYXRod2F5IEVucmljaG1lbnQgZm9yIERvd25yZWd1bGF0ZWQgR2VuZXMiKQoKIyBSZWFjdG9tZSBQYXRod2F5IEVucmljaG1lbnQKIyBSZWFjdG9tZSBwYXRod2F5IGVucmljaG1lbnQgZm9yIHVwcmVndWxhdGVkIGdlbmVzCnJlYWN0b21lX3VwIDwtIGVucmljaFBhdGh3YXkoZ2VuZSA9IHVwcmVndWxhdGVkX2VudHJleiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JnYW5pc20gPSAiaHVtYW4iLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwdmFsdWVDdXRvZmYgPSAwLjA1KQoKIyBSZWFjdG9tZSBwYXRod2F5IGVucmljaG1lbnQgZm9yIGRvd25yZWd1bGF0ZWQgZ2VuZXMKcmVhY3RvbWVfZG93biA8LSBlbnJpY2hQYXRod2F5KGdlbmUgPSBkb3ducmVndWxhdGVkX2VudHJleiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmdhbmlzbSA9ICJodW1hbiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHZhbHVlQ3V0b2ZmID0gMC4wNSkKCiMgVmlzdWFsaXplIFJlYWN0b21lIHBhdGh3YXlzCmRvdHBsb3QocmVhY3RvbWVfdXAsIHNob3dDYXRlZ29yeSA9IDEwLCB0aXRsZSA9ICJSZWFjdG9tZSBQYXRod2F5IEVucmljaG1lbnQgZm9yIFVwcmVndWxhdGVkIEdlbmVzIikKI2RvdHBsb3QocmVhY3RvbWVfZG93biwgc2hvd0NhdGVnb3J5ID0gMTAsIHRpdGxlID0gIlJlYWN0b21lIFBhdGh3YXkgRW5yaWNobWVudCBmb3IgRG93bnJlZ3VsYXRlZCBHZW5lcyIpCgojIEdlbmUgU2V0IEVucmljaG1lbnQgQW5hbHlzaXMgKEdTRUEpCiMgQ3JlYXRlIGEgcmFua2VkIGxpc3Qgb2YgZ2VuZXMgKGxvZzJGQyBhcyByYW5raW5nIG1ldHJpYykKZ2VuZV9saXN0IDwtIE1hbGlnbmFudF9DRDRUY2VsbHNfdnNfTm9ybWFsX0NENFRjZWxscyRhdmdfbG9nMkZDCm5hbWVzKGdlbmVfbGlzdCkgPC0gTWFsaWduYW50X0NENFRjZWxsc192c19Ob3JtYWxfQ0Q0VGNlbGxzJGdlbmUgICMgVXNlIHRoZSAkZ2VuZSBjb2x1bW4gZm9yIGdlbmUgc3ltYm9scwpnZW5lX2xpc3QgPC0gc29ydChnZW5lX2xpc3QsIGRlY3JlYXNpbmcgPSBUUlVFKQoKIyBDb252ZXJ0IGdlbmUgc3ltYm9scyB0byBFbnRyZXogSURzIGZvciBHU0VBCmdlbmVfZGYgPC0gYml0cihuYW1lcyhnZW5lX2xpc3QpLCBmcm9tVHlwZSA9ICJTWU1CT0wiLCB0b1R5cGUgPSAiRU5UUkVaSUQiLCBPcmdEYiA9IG9yZy5Icy5lZy5kYikKCiMgRW5zdXJlIHRoZSBnZW5lIGxpc3QgbWF0Y2hlcyB0aGUgRW50cmV6IElEcwpnZW5lX2xpc3QgPC0gZ2VuZV9saXN0W25hbWVzKGdlbmVfbGlzdCkgJWluJSBnZW5lX2RmJFNZTUJPTF0KCiMgUmVwbGFjZSBnZW5lIHN5bWJvbHMgd2l0aCBFbnRyZXogSURzCm5hbWVzKGdlbmVfbGlzdCkgPC0gZ2VuZV9kZiRFTlRSRVpJRFttYXRjaChuYW1lcyhnZW5lX2xpc3QpLCBnZW5lX2RmJFNZTUJPTCldCgojIFJ1biBHU0VBIHVzaW5nIEtFR0cgcGF0aHdheXMKZ3NlYV9rZWdnIDwtIGdzZUtFR0coZ2VuZUxpc3QgPSBnZW5lX2xpc3QsIAogICAgICAgICAgICAgICAgICAgICBvcmdhbmlzbSA9ICJoc2EiLCAKICAgICAgICAgICAgICAgICAgICAgcHZhbHVlQ3V0b2ZmID0gMC4wNSkKCiMgUGxvdCB0aGUgR1NFQSByZXN1bHRzCmdzZWFwbG90KGdzZWFfa2VnZywgZ2VuZVNldElEID0gMSwgdGl0bGUgPSAiVG9wIEtFR0cgUGF0aHdheSIpCgojIEV4dHJhY3QgdGhlIG5hbWUgb2YgdGhlIHRvcCBLRUdHIHBhdGh3YXkKdG9wX3BhdGh3YXkgPC0gZ3NlYV9rZWdnQHJlc3VsdFsxLCAiRGVzY3JpcHRpb24iXQoKIyBQbG90IEdTRUEgd2l0aCB0aGUgdG9wIHBhdGh3YXkncyBuYW1lIGFzIHRoZSB0aXRsZQpnc2VhcGxvdChnc2VhX2tlZ2csIGdlbmVTZXRJRCA9IDEsIHRpdGxlID0gdG9wX3BhdGh3YXkpCgoKYGBgCgoKCgojIDQuMi4gRW5yaWNobWVudCBBbmFseXNpcy0yCmBgYHtyICwgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9OH0KCiMgTG9hZCBuZWNlc3NhcnkgbGlicmFyaWVzCmxpYnJhcnkoY2x1c3RlclByb2ZpbGVyKQpsaWJyYXJ5KG9yZy5Icy5lZy5kYikKbGlicmFyeShtc2lnZGJyKQpsaWJyYXJ5KGVucmljaHBsb3QpCgojIExvYWQgSGFsbG1hcmsgZ2VuZSBzZXRzIGZyb20gbXNpZ2RicgpoYWxsbWFya19zZXRzIDwtIG1zaWdkYnIoc3BlY2llcyA9ICJIb21vIHNhcGllbnMiLCBjYXRlZ29yeSA9ICJIIikgICMgIkgiIGlzIGZvciBIYWxsbWFyayBnZW5lIHNldHMKCiMgR2V0IHVwcmVndWxhdGVkIGFuZCBkb3ducmVndWxhdGVkIGdlbmVzIGJhc2VkIG9uIGxvZzIgZm9sZCBjaGFuZ2UgYW5kIGFkanVzdGVkIHAtdmFsdWUKdXByZWd1bGF0ZWRfZ2VuZXMgPC0gTWFsaWduYW50X0NENFRjZWxsc192c19Ob3JtYWxfQ0Q0VGNlbGxzW01hbGlnbmFudF9DRDRUY2VsbHNfdnNfTm9ybWFsX0NENFRjZWxscyRhdmdfbG9nMkZDID4gMC41ICYgTWFsaWduYW50X0NENFRjZWxsc192c19Ob3JtYWxfQ0Q0VGNlbGxzJHBfdmFsX2FkaiA8IDAuMDUsIF0KZG93bnJlZ3VsYXRlZF9nZW5lcyA8LSBNYWxpZ25hbnRfQ0Q0VGNlbGxzX3ZzX05vcm1hbF9DRDRUY2VsbHNbTWFsaWduYW50X0NENFRjZWxsc192c19Ob3JtYWxfQ0Q0VGNlbGxzJGF2Z19sb2cyRkMgPCAtMC41ICYgTWFsaWduYW50X0NENFRjZWxsc192c19Ob3JtYWxfQ0Q0VGNlbGxzJHBfdmFsX2FkaiA8IDAuMDUsIF0KCiMgQ29udmVydCBnZW5lIHN5bWJvbHMgdG8gdXBwZXJjYXNlIGZvciBjb25zaXN0ZW5jeQp1cHJlZ3VsYXRlZF9nZW5lcyRnZW5lIDwtIHRvdXBwZXIodXByZWd1bGF0ZWRfZ2VuZXMkZ2VuZSkKZG93bnJlZ3VsYXRlZF9nZW5lcyRnZW5lIDwtIHRvdXBwZXIoZG93bnJlZ3VsYXRlZF9nZW5lcyRnZW5lKQoKIyBDaGVjayBmb3Igb3ZlcmxhcCBiZXR3ZWVuIHlvdXIgdXByZWd1bGF0ZWQvZG93bnJlZ3VsYXRlZCBnZW5lcyBhbmQgSGFsbG1hcmsgZ2VuZSBzZXRzCnVwcmVndWxhdGVkX2luX2hhbGxtYXJrIDwtIGludGVyc2VjdCh1cHJlZ3VsYXRlZF9nZW5lcyRnZW5lLCBoYWxsbWFya19zZXRzJGdlbmVfc3ltYm9sKQpkb3ducmVndWxhdGVkX2luX2hhbGxtYXJrIDwtIGludGVyc2VjdChkb3ducmVndWxhdGVkX2dlbmVzJGdlbmUsIGhhbGxtYXJrX3NldHMkZ2VuZV9zeW1ib2wpCgojIFByaW50IHRoZSBudW1iZXIgb2Ygb3ZlcmxhcHBpbmcgZ2VuZXMgZm9yIGJvdGggdXByZWd1bGF0ZWQgYW5kIGRvd25yZWd1bGF0ZWQgZ2VuZXMKY2F0KCJOdW1iZXIgb2YgdXByZWd1bGF0ZWQgZ2VuZXMgaW4gSGFsbG1hcmsgZ2VuZSBzZXRzOiIsIGxlbmd0aCh1cHJlZ3VsYXRlZF9pbl9oYWxsbWFyayksICJcbiIpCmNhdCgiTnVtYmVyIG9mIGRvd25yZWd1bGF0ZWQgZ2VuZXMgaW4gSGFsbG1hcmsgZ2VuZSBzZXRzOiIsIGxlbmd0aChkb3ducmVndWxhdGVkX2luX2hhbGxtYXJrKSwgIlxuIikKCiMgSWYgdGhlcmUgYXJlIGdlbmVzIHRvIGFuYWx5emUsIHByb2NlZWQgd2l0aCBlbnJpY2htZW50IGFuYWx5c2lzCmlmIChsZW5ndGgodXByZWd1bGF0ZWRfaW5faGFsbG1hcmspID4gMCkgewogICMgUGVyZm9ybSBlbnJpY2htZW50IGFuYWx5c2lzIGZvciB1cHJlZ3VsYXRlZCBnZW5lcyB1c2luZyBIYWxsbWFyayBnZW5lIHNldHMKICBoYWxsbWFya191cCA8LSBlbnJpY2hlcihnZW5lID0gdXByZWd1bGF0ZWRfaW5faGFsbG1hcmssIAogICAgICAgICAgICAgICAgICAgICAgICAgIFRFUk0yR0VORSA9IGhhbGxtYXJrX3NldHNbLCBjKCJnc19uYW1lIiwgImdlbmVfc3ltYm9sIildLCAgIyBFbnN1cmUgVEVSTTJHRU5FIHVzZXMgY29ycmVjdCBjb2x1bW5zCiAgICAgICAgICAgICAgICAgICAgICAgICAgcHZhbHVlQ3V0b2ZmID0gMC4wNSkKICAjIENoZWNrIGlmIHJlc3VsdHMgZXhpc3QKICBpZiAoIWlzLm51bGwoaGFsbG1hcmtfdXApICYmIG5yb3coaGFsbG1hcmtfdXApID4gMCkgewogICAgIyBWaXN1YWxpemUgcmVzdWx0cyBpZiBhdmFpbGFibGUKICAgIGRvdHBsb3QoaGFsbG1hcmtfdXAsIHNob3dDYXRlZ29yeSA9IDIwLCB0aXRsZSA9ICJIYWxsbWFyayBQYXRod2F5IEVucmljaG1lbnQgZm9yIFVwcmVndWxhdGVkIEdlbmVzIikKICB9IGVsc2UgewogICAgY2F0KCJObyBzaWduaWZpY2FudCBlbnJpY2htZW50IGZvdW5kIGZvciB1cHJlZ3VsYXRlZCBnZW5lcy5cbiIpCiAgfQp9IGVsc2UgewogIGNhdCgiTm8gdXByZWd1bGF0ZWQgZ2VuZXMgb3ZlcmxhcCB3aXRoIEhhbGxtYXJrIGdlbmUgc2V0cy5cbiIpCn0KCmlmIChsZW5ndGgoZG93bnJlZ3VsYXRlZF9pbl9oYWxsbWFyaykgPiAwKSB7CiAgIyBQZXJmb3JtIGVucmljaG1lbnQgYW5hbHlzaXMgZm9yIGRvd25yZWd1bGF0ZWQgZ2VuZXMgdXNpbmcgSGFsbG1hcmsgZ2VuZSBzZXRzCiAgaGFsbG1hcmtfZG93biA8LSBlbnJpY2hlcihnZW5lID0gZG93bnJlZ3VsYXRlZF9pbl9oYWxsbWFyaywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBURVJNMkdFTkUgPSBoYWxsbWFya19zZXRzWywgYygiZ3NfbmFtZSIsICJnZW5lX3N5bWJvbCIpXSwgICMgRW5zdXJlIFRFUk0yR0VORSB1c2VzIGNvcnJlY3QgY29sdW1ucwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcHZhbHVlQ3V0b2ZmID0gMC4wNSkKICAjIENoZWNrIGlmIHJlc3VsdHMgZXhpc3QKICBpZiAoIWlzLm51bGwoaGFsbG1hcmtfZG93bikgJiYgbnJvdyhoYWxsbWFya19kb3duKSA+IDApIHsKICAgICMgVmlzdWFsaXplIHJlc3VsdHMgaWYgYXZhaWxhYmxlCiAgICBkb3RwbG90KGhhbGxtYXJrX2Rvd24sIHNob3dDYXRlZ29yeSA9IDIwLCB0aXRsZSA9ICJIYWxsbWFyayBQYXRod2F5IEVucmljaG1lbnQgZm9yIERvd25yZWd1bGF0ZWQgR2VuZXMiKQogIH0gZWxzZSB7CiAgICBjYXQoIk5vIHNpZ25pZmljYW50IGVucmljaG1lbnQgZm91bmQgZm9yIGRvd25yZWd1bGF0ZWQgZ2VuZXMuXG4iKQogIH0KfSBlbHNlIHsKICBjYXQoIk5vIGRvd25yZWd1bGF0ZWQgZ2VuZXMgb3ZlcmxhcCB3aXRoIEhhbGxtYXJrIGdlbmUgc2V0cy5cbiIpCn0KCgoKCgpgYGAKIyA0LjMuIEhhbGxtYXJrLUdTRUEKYGBge3IgLCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD0xMn0KIyBHZW5lIFNldCBFbnJpY2htZW50IEFuYWx5c2lzIChHU0VBKSBmb3IgSGFsbG1hcmsgUGF0aHdheXMKIyBDcmVhdGUgYSByYW5rZWQgbGlzdCBvZiBnZW5lcyAobG9nMkZDIGFzIHJhbmtpbmcgbWV0cmljKQpnZW5lX2xpc3QgPC0gTWFsaWduYW50X0NENFRjZWxsc192c19Ob3JtYWxfQ0Q0VGNlbGxzJGF2Z19sb2cyRkMKbmFtZXMoZ2VuZV9saXN0KSA8LSBNYWxpZ25hbnRfQ0Q0VGNlbGxzX3ZzX05vcm1hbF9DRDRUY2VsbHMkZ2VuZQpnZW5lX2xpc3QgPC0gc29ydChnZW5lX2xpc3QsIGRlY3JlYXNpbmcgPSBUUlVFKQoKIyBDb252ZXJ0IGdlbmUgc3ltYm9scyB0byBFbnRyZXogSURzIGZvciBHU0VBCmdlbmVfZGYgPC0gYml0cihuYW1lcyhnZW5lX2xpc3QpLCAKICAgICAgICAgICAgICAgIGZyb21UeXBlID0gIlNZTUJPTCIsIAogICAgICAgICAgICAgICAgdG9UeXBlID0gIkVOVFJFWklEIiwgCiAgICAgICAgICAgICAgICBPcmdEYiA9IG9yZy5Icy5lZy5kYikKCiMgRmlsdGVyIG91dCBnZW5lcyB3aXRob3V0IEVudHJleiBJRCBtYXBwaW5ncwpnZW5lX2xpc3QgPC0gZ2VuZV9saXN0W25hbWVzKGdlbmVfbGlzdCkgJWluJSBnZW5lX2RmJFNZTUJPTF0KCiMgUmVwbGFjZSBnZW5lIHN5bWJvbHMgd2l0aCBFbnRyZXogSURzIGluIHRoZSBnZW5lIGxpc3QKbmFtZXMoZ2VuZV9saXN0KSA8LSBnZW5lX2RmJEVOVFJFWklEW21hdGNoKG5hbWVzKGdlbmVfbGlzdCksIGdlbmVfZGYkU1lNQk9MKV0KCiMgUnVuIEdTRUEgdXNpbmcgSGFsbG1hcmsgcGF0aHdheXMKZ3NlYV9oYWxsbWFyayA8LSBHU0VBKGdlbmVMaXN0ID0gZ2VuZV9saXN0LCAKICAgICAgICAgICAgICAgICAgICAgIFRFUk0yR0VORSA9IGhhbGxtYXJrX3NldHNbLCBjKCJnc19uYW1lIiwgImVudHJlel9nZW5lIildLCAKICAgICAgICAgICAgICAgICAgICAgIHB2YWx1ZUN1dG9mZiA9IDAuMDUpCgojIENoZWNrIGFuZCB2aXN1YWxpemUgR1NFQSByZXN1bHRzCmlmICghaXMubnVsbChnc2VhX2hhbGxtYXJrKSAmJiBucm93KGdzZWFfaGFsbG1hcmspID4gMCkgewogICMgVmlzdWFsaXplIHRvcCBHU0VBIHJlc3VsdHMgZm9yIEhhbGxtYXJrIHBhdGh3YXlzCiAgZG90cGxvdChnc2VhX2hhbGxtYXJrLCBzaG93Q2F0ZWdvcnkgPSAyMCwgdGl0bGUgPSAiR1NFQSBmb3IgSGFsbG1hcmsgUGF0aHdheXMiKQogIAogICMgUGxvdCBlbnJpY2htZW50IHNjb3JlIGZvciB0aGUgdG9wIHBhdGh3YXkKICBnc2VhcGxvdChnc2VhX2hhbGxtYXJrLCBnZW5lU2V0SUQgPSAxLCB0aXRsZSA9ICJUb3AgSGFsbG1hcmsgUGF0aHdheSIpCiAgCiAgIyBFeHRyYWN0IHRoZSBuYW1lIG9mIHRoZSB0b3AgSGFsbG1hcmsgcGF0aHdheQogIHRvcF9oYWxsbWFyayA8LSBnc2VhX2hhbGxtYXJrQHJlc3VsdFsxLCAiRGVzY3JpcHRpb24iXQogIAogICMgUGxvdCBHU0VBIHdpdGggdGhlIHRvcCBwYXRod2F5J3MgbmFtZSBhcyB0aGUgdGl0bGUKICBnc2VhcGxvdChnc2VhX2hhbGxtYXJrLCBnZW5lU2V0SUQgPSAxLCB0aXRsZSA9IHRvcF9oYWxsbWFyaykKfSBlbHNlIHsKICBjYXQoIk5vIHNpZ25pZmljYW50IEdTRUEgcmVzdWx0cyBmb3IgSGFsbG1hcmsgcGF0aHdheXMuXG4iKQp9CgoKCmBgYAoKCgojIDUuIGdncGxvdDIgZm9yIFZvbGNhbm8KYGBge3IgLCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD0xMn0KbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGdncmVwZWwpCgojIElkZW50aWZ5IHRvcCBhbmQgYm90dG9tIGdlbmVzCnRvcF9nZW5lcyA8LSBNYWxpZ25hbnRfQ0Q0VGNlbGxzX3ZzX05vcm1hbF9DRDRUY2VsbHNbTWFsaWduYW50X0NENFRjZWxsc192c19Ob3JtYWxfQ0Q0VGNlbGxzJHBfdmFsX2FkaiA8IDAuMDUgJiBNYWxpZ25hbnRfQ0Q0VGNlbGxzX3ZzX05vcm1hbF9DRDRUY2VsbHMkYXZnX2xvZzJGQyA+IDAuNSwgXQpib3R0b21fZ2VuZXMgPC0gTWFsaWduYW50X0NENFRjZWxsc192c19Ob3JtYWxfQ0Q0VGNlbGxzW01hbGlnbmFudF9DRDRUY2VsbHNfdnNfTm9ybWFsX0NENFRjZWxscyRwX3ZhbF9hZGogPCAwLjA1ICYgTWFsaWduYW50X0NENFRjZWxsc192c19Ob3JtYWxfQ0Q0VGNlbGxzJGF2Z19sb2cyRkMgPCAtMC41LCBdCgojIENyZWF0ZSBhIG5ldyBjb2x1bW4gZm9yIGNvbG9yIGJhc2VkIG9uIHNpZ25pZmljYW5jZQpNYWxpZ25hbnRfQ0Q0VGNlbGxzX3ZzX05vcm1hbF9DRDRUY2VsbHMkY29sb3IgPC0gaWZlbHNlKE1hbGlnbmFudF9DRDRUY2VsbHNfdnNfTm9ybWFsX0NENFRjZWxscyRhdmdfbG9nMkZDID4gMC41LCAiVXByZWd1bGF0ZWQgZ2VuZXMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoTWFsaWduYW50X0NENFRjZWxsc192c19Ob3JtYWxfQ0Q0VGNlbGxzJGF2Z19sb2cyRkMgPCAtMC41LCAiRG93bnJlZ3VsYXRlZCBnZW5lcyIsICJOb25zaWduaWZpY2FudCIpKQoKIyBDcmVhdGUgYSB2b2xjYW5vIHBsb3QKZ2dwbG90KE1hbGlnbmFudF9DRDRUY2VsbHNfdnNfTm9ybWFsX0NENFRjZWxscywgYWVzKHggPSBhdmdfbG9nMkZDLCB5ID0gLWxvZzEwKHBfdmFsX2FkaikpKSArCiAgZ2VvbV9wb2ludChhZXMoY29sb3IgPSBjb2xvciksIGFscGhhID0gMC43LCBzaXplID0gMikgKwogIAogICMgQWRkIGxhYmVscyBmb3IgdG9wIGFuZCBib3R0b20gZ2VuZXMKICBnZW9tX3RleHRfcmVwZWwoZGF0YSA9IHRvcF9nZW5lcywgYWVzKGxhYmVsID0gZ2VuZSksIGNvbG9yID0gImJsYWNrIiwgdmp1c3QgPSAxLCBmb250ZmFjZSA9ICJib2xkIikgKwogIGdlb21fdGV4dF9yZXBlbChkYXRhID0gYm90dG9tX2dlbmVzLCBhZXMobGFiZWwgPSBnZW5lKSwgY29sb3IgPSAiYmxhY2siLCB2anVzdCA9IC0xLCBmb250ZmFjZSA9ICJib2xkIikgKwogIAogICMgQ3VzdG9taXplIGxhYmVscyBhbmQgdGl0bGUKICBsYWJzKHRpdGxlID0gIlZvbGNhbm8gUGxvdCIsCiAgICAgICB4ID0gImxvZzIgRm9sZCBDaGFuZ2UiLAogICAgICAgeSA9ICItbG9nMTAocC12YWx1ZSkiKSArCiAgCiAgIyAjIEFkZCBzaWduaWZpY2FuY2UgdGhyZXNob2xkIGxpbmVzCiAgIGdlb21faGxpbmUoeWludGVyY2VwdCA9IC1sb2cxMCgwLjAwMDAxKSwgbGluZXR5cGUgPSAiZGFzaGVkIiwgY29sb3IgPSAiYmxhY2siKSArCiAgIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGMoLTAuNSwgMC41KSwgbGluZXR5cGUgPSAiZGFzaGVkIiwgY29sb3IgPSAiYmxhY2siKSArCiAgCiAgIyBTZXQgY29sb3JzIGZvciB0b3AgYW5kIGJvdHRvbSBnZW5lcwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCJVcHJlZ3VsYXRlZCBnZW5lcyIgPSAicmVkIiwgIkRvd25yZWd1bGF0ZWQgZ2VuZXMiID0gImJsdWUiLCAiTm9uc2lnbmlmaWNhbnQiID0gImRhcmtncmV5IikpICsKICAKICAjIEN1c3RvbWl6ZSB0aGVtZSBpZiBuZWVkZWQKICB0aGVtZV9taW5pbWFsKCkKCgoKCgpgYGAKCgojIDUuIGdncGxvdDMgZm9yIFZvbGNhbm8KYGBge3IgLCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD0xMn0KIyBMb2FkIG5lY2Vzc2FyeSBsaWJyYXJpZXMKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGdncmVwZWwpCgojIElkZW50aWZ5IHRvcCBhbmQgYm90dG9tIGdlbmVzCnRvcF9nZW5lcyA8LSBNYWxpZ25hbnRfQ0Q0VGNlbGxzX3ZzX05vcm1hbF9DRDRUY2VsbHNbTWFsaWduYW50X0NENFRjZWxsc192c19Ob3JtYWxfQ0Q0VGNlbGxzJHBfdmFsX2FkaiA8IDAuMDAwMDEgJiBNYWxpZ25hbnRfQ0Q0VGNlbGxzX3ZzX05vcm1hbF9DRDRUY2VsbHMkYXZnX2xvZzJGQyA+IDQsIF0KYm90dG9tX2dlbmVzIDwtIE1hbGlnbmFudF9DRDRUY2VsbHNfdnNfTm9ybWFsX0NENFRjZWxsc1tNYWxpZ25hbnRfQ0Q0VGNlbGxzX3ZzX05vcm1hbF9DRDRUY2VsbHMkcF92YWxfYWRqIDwgMC4wMDAwMSAmIE1hbGlnbmFudF9DRDRUY2VsbHNfdnNfTm9ybWFsX0NENFRjZWxscyRhdmdfbG9nMkZDIDwgLTQsIF0KCiMgQ3JlYXRlIGEgbmV3IGNvbHVtbiBmb3IgY29sb3IgYmFzZWQgb24gc2lnbmlmaWNhbmNlCk1hbGlnbmFudF9DRDRUY2VsbHNfdnNfTm9ybWFsX0NENFRjZWxscyRjb2xvciA8LSBpZmVsc2UoTWFsaWduYW50X0NENFRjZWxsc192c19Ob3JtYWxfQ0Q0VGNlbGxzJGF2Z19sb2cyRkMgPiAwLjUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJVcHJlZ3VsYXRlZCBnZW5lcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKE1hbGlnbmFudF9DRDRUY2VsbHNfdnNfTm9ybWFsX0NENFRjZWxscyRhdmdfbG9nMkZDIDwgLTAuNSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJEb3ducmVndWxhdGVkIGdlbmVzIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOb25zaWduaWZpY2FudCIpKQoKIyBDcmVhdGUgdGhlIHZvbGNhbm8gcGxvdApnZ3Bsb3QoTWFsaWduYW50X0NENFRjZWxsc192c19Ob3JtYWxfQ0Q0VGNlbGxzLCBhZXMoeCA9IGF2Z19sb2cyRkMsIHkgPSAtbG9nMTAocF92YWxfYWRqKSkpICsKICBnZW9tX3BvaW50KGFlcyhjb2xvciA9IGNvbG9yKSwgYWxwaGEgPSAwLjcsIHNpemUgPSAyKSArCiAgCiAgIyBBZGQgbGFiZWxzIG5leHQgdG8gdGhlIGRvdHMgd2l0aG91dCByZXBlbCBsaW5lcwogIGdlb21fdGV4dChkYXRhID0gdG9wX2dlbmVzLCBhZXMobGFiZWwgPSBnZW5lKSwgaGp1c3QgPSAtMC4yLCB2anVzdCA9IDAsIHNpemUgPSAzLCBjb2xvciA9ICJibGFjayIsIGZvbnRmYWNlID0gImJvbGQiKSArCiAgZ2VvbV90ZXh0KGRhdGEgPSBib3R0b21fZ2VuZXMsIGFlcyhsYWJlbCA9IGdlbmUpLCBoanVzdCA9IDEuMiwgdmp1c3QgPSAwLCBzaXplID0gMywgY29sb3IgPSAiYmxhY2siLCBmb250ZmFjZSA9ICJib2xkIikgKwogIAogICMgQ3VzdG9taXplIGxhYmVscyBhbmQgdGl0bGUKICBsYWJzKHRpdGxlID0gIlZvbGNhbm8gUGxvdCIsCiAgICAgICB4ID0gImxvZzIgRm9sZCBDaGFuZ2UiLAogICAgICAgeSA9ICItbG9nMTAocC12YWx1ZSkiKSArCiAgCiAgIyBBZGQgc2lnbmlmaWNhbmNlIHRocmVzaG9sZCBsaW5lcwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IC1sb2cxMCgwLjAwMDAxKSwgbGluZXR5cGUgPSAiZGFzaGVkIiwgY29sb3IgPSAiYmxhY2siKSArCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYygtMC41LCAwLjUpLCBsaW5ldHlwZSA9ICJkYXNoZWQiLCBjb2xvciA9ICJibGFjayIpICsKICAKICAjIFNldCBjb2xvcnMgZm9yIHRvcCBhbmQgYm90dG9tIGdlbmVzCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoIlVwcmVndWxhdGVkIGdlbmVzIiA9ICJyZWQiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRG93bnJlZ3VsYXRlZCBnZW5lcyIgPSAiYmx1ZSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOb25zaWduaWZpY2FudCIgPSAiZGFya2dyZXkiKSkgKwogIAogICMgQ3VzdG9taXplIHRoZW1lCiAgdGhlbWVfbWluaW1hbCgpCgoKYGBgCgo=