1. load libraries

#Differential Expression Analysis # 2. load seurat object

#Load Seurat Object L7
load("../../../0-IMP-OBJECTS/Harmony_integrated_All_samples_Merged_with_PBMC10x_with_harmony_clustering.Robj")


All_samples_Merged
An object of class Seurat 
64169 features across 59355 samples within 6 assays 
Active assay: SCT (27417 features, 3000 variable features)
 3 layers present: counts, data, scale.data
 5 other assays present: RNA, ADT, prediction.score.celltype.l1, prediction.score.celltype.l2, prediction.score.celltype.l3
 6 dimensional reductions calculated: integrated_dr, ref.umap, pca, umap, harmony, umap.harmony
DimPlot(All_samples_Merged, reduction = "umap.harmony", group.by = "cell_line",label = T, label.box = T)

DimPlot(All_samples_Merged, reduction = "umap.harmony", group.by = "Harmony_snn_res.0.9",label = T, label.box = T)

#Differential Expression Analysis

3. L1 vs PBMC


DefaultAssay(All_samples_Merged) <- "SCT"
Idents(All_samples_Merged) <- "cell_line"

# P1 vs PBMC-Tcells
L1_vs_PBMC <- FindMarkers(All_samples_Merged, 
                        ident.1 = "L1",  
                        ident.2 = c("PBMC","PBMC_10x"),      
                        assay = "SCT")

write.csv(L1_vs_PBMC, "New_comparison_L1_vs_PBMC.csv")

# Convert to data frame and add gene names as a new column
L1_vs_PBMC <- as.data.frame(L1_vs_PBMC)
L1_vs_PBMC$gene <- rownames(L1_vs_PBMC)


# Rearranging the columns for better readability (optional)
L1_vs_PBMC  <- L1_vs_PBMC[, 
    c("gene", "p_val", "avg_log2FC", "pct.1", "pct.2", "p_val_adj")]



# Create volcano plot for P1 vs PBMC-Tcells
volcano_L1_vs_PBMC <- EnhancedVolcano(L1_vs_PBMC, 
                                    lab = rownames(L1_vs_PBMC),
                                    x = 'avg_log2FC',
                                    y = 'p_val_adj',
                                    title = 'L1_vs_PBMC',
                                    xlab = bquote(~Log[2]~ 'fold change'),
                                    pCutoff = 1e-100,
                                    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...
print(volcano_L1_vs_PBMC)
png("volcano_L1_vs_PBMC.png", width = 12, height = 10, units = "in", res = 300)
print(volcano_L1_vs_PBMC)
dev.off()
png 
  2 

volcano2_L1_vs_PBMC <- EnhancedVolcano(L1_vs_PBMC, 
                lab = rownames(L1_vs_PBMC),
                x = "avg_log2FC", 
                y = "p_val_adj",
                selectLab = c('EPCAM', 'KIR3DL2', 'FOXM1', 'TWIST1', 'TNFSF9', 
                              'CD80', 'FOS','PTPN6','NCR1','NCR2',
                              'PCLAF', 'KIR3DL1', 'IL4','ITGA6','CCL5',
                              'IL7R', 'TCF7', 'PTTG1', 'RRM2', 'MKI67', 'CD70', 
                              'IL2RA', 'FCGR3A', 'GNLY', 'FOXP3', 'SELL',  'LEF1',
                              'CCL17', 'THY1', 'CD27', 'CD28', 'CD7',
                              # Key Sézary syndrome genes
                              'PRF1', 'GZMB', 'NCR1', 'NFATC3', 
                              'KLRK1', 'LCK', 'KLRC1', 'KLRC2', 'TNF', 
                              'KIR3DL1','KIR3DL3','KIR3DL4', 'IFNG', 'IFNGR1', 'CD244', 'FASLG'),
                title = "L1_vs_PBMC",
                subtitle = "Sézary Syndrome Cell Lines",
                xlab = bquote(~Log[2]~ 'fold change'),
                pCutoff = 0.05,
                FCcutoff = 1.5, 
                pointSize = 3.0,
                labSize = 4.0,
                labFace = 'bold',
                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...
print(volcano2_L1_vs_PBMC)
png("volcano2_L1_vs_PBMC.png", width = 12, height = 10, units = "in", res = 300)
print(volcano2_L1_vs_PBMC)
dev.off()
png 
  2 

# Display top differentially expressed genes for each comparison
head(L1_vs_PBMC)
NA
NA

4. L2_vs_PBMC


DefaultAssay(All_samples_Merged) <- "SCT"
Idents(All_samples_Merged) <- "cell_line"

# P1 vs PBMC-Tcells
L2_vs_PBMC <- FindMarkers(All_samples_Merged, 
                        ident.1 = "L2",  
                        ident.2 = c("PBMC","PBMC_10x"),      
                        assay = "SCT")

write.csv(L2_vs_PBMC, "New_comparison_L2_vs_PBMC.csv")

# Convert to data frame and add gene names as a new column
L2_vs_PBMC <- as.data.frame(L2_vs_PBMC)
L2_vs_PBMC$gene <- rownames(L2_vs_PBMC)


# Rearranging the columns for better readability (optional)
L2_vs_PBMC  <- L2_vs_PBMC[, 
    c("gene", "p_val", "avg_log2FC", "pct.1", "pct.2", "p_val_adj")]



# Create volcano plot for P1 vs PBMC-Tcells
volcano_L2_vs_PBMC <- EnhancedVolcano(L2_vs_PBMC, 
                                    lab = rownames(L2_vs_PBMC),
                                    x = 'avg_log2FC',
                                    y = 'p_val_adj',
                                    title = 'L2_vs_PBMC',
                                    xlab = bquote(~Log[2]~ 'fold change'),
                                    pCutoff = 1e-100,
                                    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...
print(volcano_L2_vs_PBMC)
png("volcano_L2_vs_PBMC.png", width = 12, height = 10, units = "in", res = 300)
print(volcano_L2_vs_PBMC)
dev.off()
png 
  2 

volcano2_L2_vs_PBMC <- EnhancedVolcano(L2_vs_PBMC, 
                lab = rownames(L2_vs_PBMC),
                x = "avg_log2FC", 
                y = "p_val_adj",
                selectLab = c('EPCAM', 'KIR3DL2', 'FOXM1', 'TWIST1', 'TNFSF9', 
                              'CD80', 'FOS','PTPN6','NCR1','NCR2',
                              'PCLAF', 'KIR3DL1', 'IL4','ITGA6','CCL5',
                              'IL7R', 'TCF7', 'PTTG1', 'RRM2', 'MKI67', 'CD70', 
                              'IL2RA', 'FCGR3A', 'GNLY', 'FOXP3', 'SELL',  'LEF1',
                              'CCL17', 'THY1', 'CD27', 'CD28', 'CD7',
                              # Key Sézary syndrome genes
                              'PRF1', 'GZMB', 'NCR1', 'NFATC3', 
                              'KLRK1', 'LCK', 'KLRC1', 'KLRC2', 'TNF', 
                              'KIR3DL1','KIR3DL3','KIR3DL4', 'IFNG', 'IFNGR1', 'CD244', 'FASLG'),
                title = "L2_vs_PBMC",
                subtitle = "Sézary Syndrome Cell Lines",
                xlab = bquote(~Log[2]~ 'fold change'),
                pCutoff = 0.05,
                FCcutoff = 1.5, 
                pointSize = 3.0,
                labSize = 4.0,
                labFace = 'bold',
                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...
print(volcano2_L2_vs_PBMC)
png("volcano2_L2_vs_PBMC.png", width = 12, height = 10, units = "in", res = 300)
print(volcano2_L2_vs_PBMC)
dev.off()
png 
  2 

# Display top differentially expressed genes for each comparison
head(L2_vs_PBMC)
NA
NA

5. L3_vs_PBMC


DefaultAssay(All_samples_Merged) <- "SCT"
Idents(All_samples_Merged) <- "cell_line"

# P1 vs PBMC-Tcells
L3_vs_PBMC <- FindMarkers(All_samples_Merged, 
                        ident.1 = "L3",  
                        ident.2 = c("PBMC","PBMC_10x"),      
                        assay = "SCT")

write.csv(L3_vs_PBMC, "New_comparison_L3_vs_PBMC.csv")

# Convert to data frame and add gene names as a new column
L3_vs_PBMC <- as.data.frame(L3_vs_PBMC)
L3_vs_PBMC$gene <- rownames(L3_vs_PBMC)


# Rearranging the columns for better readability (optional)
L3_vs_PBMC  <- L3_vs_PBMC[, 
    c("gene", "p_val", "avg_log2FC", "pct.1", "pct.2", "p_val_adj")]



# Create volcano plot for P1 vs PBMC-Tcells
volcano_L3_vs_PBMC <- EnhancedVolcano(L3_vs_PBMC, 
                                    lab = rownames(L3_vs_PBMC),
                                    x = 'avg_log2FC',
                                    y = 'p_val_adj',
                                    title = 'L3_vs_PBMC',
                                    xlab = bquote(~Log[2]~ 'fold change'),
                                    pCutoff = 1e-100,
                                    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...
print(volcano_L3_vs_PBMC)
png("volcano_L3_vs_PBMC.png", width = 12, height = 10, units = "in", res = 300)
print(volcano_L3_vs_PBMC)
dev.off()
png 
  2 

volcano2_L3_vs_PBMC <- EnhancedVolcano(L3_vs_PBMC, 
                lab = rownames(L3_vs_PBMC),
                x = "avg_log2FC", 
                y = "p_val_adj",
                selectLab = c('EPCAM', 'KIR3DL2', 'FOXM1', 'TWIST1', 'TNFSF9', 
                              'CD80', 'FOS','PTPN6','NCR1','NCR2',
                              'PCLAF', 'KIR3DL1', 'IL4','ITGA6','CCL5',
                              'IL7R', 'TCF7', 'PTTG1', 'RRM2', 'MKI67', 'CD70', 
                              'IL2RA', 'FCGR3A', 'GNLY', 'FOXP3', 'SELL',  'LEF1',
                              'CCL17', 'THY1', 'CD27', 'CD28', 'CD7',
                              # Key Sézary syndrome genes
                              'PRF1', 'GZMB', 'NCR1', 'NFATC3', 
                              'KLRK1', 'LCK', 'KLRC1', 'KLRC2', 'TNF', 
                              'KIR3DL1','KIR3DL3','KIR3DL4', 'IFNG', 'IFNGR1', 'CD244', 'FASLG'),
                title = "L3_vs_PBMC",
                subtitle = "Sézary Syndrome Cell Lines",
                xlab = bquote(~Log[2]~ 'fold change'),
                pCutoff = 0.05,
                FCcutoff = 1.5, 
                pointSize = 3.0,
                labSize = 4.0,
                labFace = 'bold',
                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...
print(volcano2_L3_vs_PBMC)
png("volcano2_L3_vs_PBMC.png", width = 12, height = 10, units = "in", res = 300)
print(volcano2_L3_vs_PBMC)
dev.off()
png 
  2 

# Display top differentially expressed genes for each comparison
head(L3_vs_PBMC)
NA
NA

6. L4_vs_PBMC


DefaultAssay(All_samples_Merged) <- "SCT"
Idents(All_samples_Merged) <- "cell_line"

# P1 vs PBMC-Tcells
L4_vs_PBMC <- FindMarkers(All_samples_Merged, 
                        ident.1 = "L4",  
                        ident.2 = c("PBMC","PBMC_10x"),      
                        assay = "SCT")

write.csv(L4_vs_PBMC, "New_comparison_L4_vs_PBMC.csv")

# Convert to data frame and add gene names as a new column
L4_vs_PBMC <- as.data.frame(L4_vs_PBMC)
L4_vs_PBMC$gene <- rownames(L4_vs_PBMC)


# Rearranging the columns for better readability (optional)
L4_vs_PBMC  <- L4_vs_PBMC[, 
    c("gene", "p_val", "avg_log2FC", "pct.1", "pct.2", "p_val_adj")]



# Create volcano plot for P1 vs PBMC-Tcells
volcano_L4_vs_PBMC <- EnhancedVolcano(L4_vs_PBMC, 
                                    lab = rownames(L4_vs_PBMC),
                                    x = 'avg_log2FC',
                                    y = 'p_val_adj',
                                    title = 'L4_vs_PBMC',
                                    xlab = bquote(~Log[2]~ 'fold change'),
                                    pCutoff = 1e-100,
                                    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...
print(volcano_L4_vs_PBMC)
Registered S3 method overwritten by 'rmarkdown':
  method         from
  print.paged_df     
png("volcano_L4_vs_PBMC.png", width = 12, height = 10, units = "in", res = 300)
print(volcano_L4_vs_PBMC)
dev.off()
png 
  2 

volcano2_L4_vs_PBMC <- EnhancedVolcano(L4_vs_PBMC, 
                lab = rownames(L4_vs_PBMC),
                x = "avg_log2FC", 
                y = "p_val_adj",
                selectLab = c('EPCAM', 'KIR3DL2', 'FOXM1', 'TWIST1', 'TNFSF9', 
                              'CD80', 'FOS','PTPN6','NCR1','NCR2',
                              'PCLAF', 'KIR3DL1', 'IL4','ITGA6','CCL5',
                              'IL7R', 'TCF7', 'PTTG1', 'RRM2', 'MKI67', 'CD70', 
                              'IL2RA', 'FCGR3A', 'GNLY', 'FOXP3', 'SELL',  'LEF1',
                              'CCL17', 'THY1', 'CD27', 'CD28', 'CD7',
                              # Key Sézary syndrome genes
                              'PRF1', 'GZMB', 'NCR1', 'NFATC3', 
                              'KLRK1', 'LCK', 'KLRC1', 'KLRC2', 'TNF', 
                              'KIR3DL1','KIR3DL3','KIR3DL4', 'IFNG', 'IFNGR1', 'CD244', 'FASLG'),
                title = "L4_vs_PBMC",
                subtitle = "Sézary Syndrome Cell Lines",
                xlab = bquote(~Log[2]~ 'fold change'),
                pCutoff = 0.05,
                FCcutoff = 1.5, 
                pointSize = 3.0,
                labSize = 4.0,
                labFace = 'bold',
                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...
print(volcano2_L4_vs_PBMC)
png("volcano2_L4_vs_PBMC.png", width = 12, height = 10, units = "in", res = 300)
print(volcano2_L4_vs_PBMC)
dev.off()
png 
  2 

# Display top differentially expressed genes for each comparison
head(L4_vs_PBMC)
NA
NA

7. L5_vs_PBMC


DefaultAssay(All_samples_Merged) <- "SCT"
Idents(All_samples_Merged) <- "cell_line"

# P1 vs PBMC-Tcells
L5_vs_PBMC <- FindMarkers(All_samples_Merged, 
                        ident.1 = "L5",  
                        ident.2 = c("PBMC","PBMC_10x"),      
                        assay = "SCT")

write.csv(L5_vs_PBMC, "New_comparison_L5_vs_PBMC.csv")

# Convert to data frame and add gene names as a new column
L5_vs_PBMC <- as.data.frame(L5_vs_PBMC)
L5_vs_PBMC$gene <- rownames(L5_vs_PBMC)


# Rearranging the columns for better readability (optional)
L5_vs_PBMC  <- L5_vs_PBMC[, 
    c("gene", "p_val", "avg_log2FC", "pct.1", "pct.2", "p_val_adj")]



# Create volcano plot for P1 vs PBMC-Tcells
volcano_L5_vs_PBMC <- EnhancedVolcano(L5_vs_PBMC, 
                                    lab = rownames(L5_vs_PBMC),
                                    x = 'avg_log2FC',
                                    y = 'p_val_adj',
                                    title = 'L5_vs_PBMC',
                                    xlab = bquote(~Log[2]~ 'fold change'),
                                    pCutoff = 1e-100,
                                    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...
print(volcano_L5_vs_PBMC)
png("volcano_L5_vs_PBMC.png", width = 12, height = 10, units = "in", res = 300)
print(volcano_L5_vs_PBMC)
dev.off()
png 
  2 

volcano2_L5_vs_PBMC <- EnhancedVolcano(L5_vs_PBMC, 
                lab = rownames(L5_vs_PBMC),
                x = "avg_log2FC", 
                y = "p_val_adj",
                selectLab = c('EPCAM', 'KIR3DL2', 'FOXM1', 'TWIST1', 'TNFSF9', 
                              'CD80', 'FOS','PTPN6','NCR1','NCR2',
                              'PCLAF', 'KIR3DL1', 'IL4','ITGA6','CCL5',
                              'IL7R', 'TCF7', 'PTTG1', 'RRM2', 'MKI67', 'CD70', 
                              'IL2RA', 'FCGR3A', 'GNLY', 'FOXP3', 'SELL',  'LEF1',
                              'CCL17', 'THY1', 'CD27', 'CD28', 'CD7',
                              # Key Sézary syndrome genes
                              'PRF1', 'GZMB', 'NCR1', 'NFATC3', 
                              'KLRK1', 'LCK', 'KLRC1', 'KLRC2', 'TNF', 
                              'KIR3DL1','KIR3DL3','KIR3DL4', 'IFNG', 'IFNGR1', 'CD244', 'FASLG'),
                title = "L5_vs_PBMC",
                subtitle = "Sézary Syndrome Cell Lines",
                xlab = bquote(~Log[2]~ 'fold change'),
                pCutoff = 0.05,
                FCcutoff = 1.5, 
                pointSize = 3.0,
                labSize = 4.0,
                labFace = 'bold',
                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...
print(volcano2_L5_vs_PBMC)
png("volcano2_L5_vs_PBMC.png", width = 12, height = 10, units = "in", res = 300)
print(volcano2_L5_vs_PBMC)
dev.off()
png 
  2 

# Display top differentially expressed genes for each comparison
head(L5_vs_PBMC)
NA
NA

8. L6_vs_PBMC


DefaultAssay(All_samples_Merged) <- "SCT"
Idents(All_samples_Merged) <- "cell_line"

# P1 vs PBMC-Tcells
L6_vs_PBMC <- FindMarkers(All_samples_Merged, 
                        ident.1 = "L6",  
                        ident.2 = c("PBMC","PBMC_10x"),      
                        assay = "SCT")

write.csv(L6_vs_PBMC, "New_comparison_L6_vs_PBMC.csv")

# Convert to data frame and add gene names as a new column
L6_vs_PBMC <- as.data.frame(L6_vs_PBMC)
L6_vs_PBMC$gene <- rownames(L6_vs_PBMC)


# Rearranging the columns for better readability (optional)
L6_vs_PBMC  <- L6_vs_PBMC[, 
    c("gene", "p_val", "avg_log2FC", "pct.1", "pct.2", "p_val_adj")]



# Create volcano plot for P1 vs PBMC-Tcells
volcano_L6_vs_PBMC <- EnhancedVolcano(L6_vs_PBMC, 
                                    lab = rownames(L6_vs_PBMC),
                                    x = 'avg_log2FC',
                                    y = 'p_val_adj',
                                    title = 'L6_vs_PBMC',
                                    xlab = bquote(~Log[2]~ 'fold change'),
                                    pCutoff = 1e-100,
                                    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...
print(volcano_L6_vs_PBMC)
png("volcano_L6_vs_PBMC.png", width = 12, height = 10, units = "in", res = 300)
print(volcano_L6_vs_PBMC)
dev.off()
png 
  2 

volcano2_L6_vs_PBMC <- EnhancedVolcano(L6_vs_PBMC, 
                lab = rownames(L6_vs_PBMC),
                x = "avg_log2FC", 
                y = "p_val_adj",
                selectLab = c('EPCAM', 'KIR3DL2', 'FOXM1', 'TWIST1', 'TNFSF9', 
                              'CD80', 'FOS','PTPN6','NCR1','NCR2',
                              'PCLAF', 'KIR3DL1', 'IL4','ITGA6','CCL5',
                              'IL7R', 'TCF7', 'PTTG1', 'RRM2', 'MKI67', 'CD70', 
                              'IL2RA', 'FCGR3A', 'GNLY', 'FOXP3', 'SELL',  'LEF1',
                              'CCL17', 'THY1', 'CD27', 'CD28', 'CD7',
                              # Key Sézary syndrome genes
                              'PRF1', 'GZMB', 'NCR1', 'NFATC3', 
                              'KLRK1', 'LCK', 'KLRC1', 'KLRC2', 'TNF', 
                              'KIR3DL1','KIR3DL3','KIR3DL4', 'IFNG', 'IFNGR1', 'CD244', 'FASLG'),
                title = "L6_vs_PBMC",
                subtitle = "Sézary Syndrome Cell Lines",
                xlab = bquote(~Log[2]~ 'fold change'),
                pCutoff = 0.05,
                FCcutoff = 1.5, 
                pointSize = 3.0,
                labSize = 4.0,
                labFace = 'bold',
                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...
print(volcano2_L6_vs_PBMC)
png("volcano2_L6_vs_PBMC.png", width = 12, height = 10, units = "in", res = 300)
print(volcano2_L6_vs_PBMC)
dev.off()
png 
  2 

# Display top differentially expressed genes for each comparison
head(L6_vs_PBMC)
NA
NA

9. L7_vs_PBMC


DefaultAssay(All_samples_Merged) <- "SCT"
Idents(All_samples_Merged) <- "cell_line"

# P1 vs PBMC-Tcells
L7_vs_PBMC <- FindMarkers(All_samples_Merged, 
                        ident.1 = "L7",  
                        ident.2 = c("PBMC","PBMC_10x"),      
                        assay = "SCT")

write.csv(L7_vs_PBMC, "New_comparison_L7_vs_PBMC.csv")

# Convert to data frame and add gene names as a new column
L7_vs_PBMC <- as.data.frame(L7_vs_PBMC)
L7_vs_PBMC$gene <- rownames(L7_vs_PBMC)


# Rearranging the columns for better readability (optional)
L7_vs_PBMC  <- L7_vs_PBMC[, 
    c("gene", "p_val", "avg_log2FC", "pct.1", "pct.2", "p_val_adj")]



# Create volcano plot for P1 vs PBMC-Tcells
volcano_L7_vs_PBMC <- EnhancedVolcano(L7_vs_PBMC, 
                                    lab = rownames(L7_vs_PBMC),
                                    x = 'avg_log2FC',
                                    y = 'p_val_adj',
                                    title = 'L7_vs_PBMC',
                                    xlab = bquote(~Log[2]~ 'fold change'),
                                    pCutoff = 1e-100,
                                    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...
print(volcano_L7_vs_PBMC)
png("volcano_L7_vs_PBMC.png", width = 12, height = 10, units = "in", res = 300)
print(volcano_L7_vs_PBMC)
dev.off()
png 
  2 

volcano2_L7_vs_PBMC <- EnhancedVolcano(L7_vs_PBMC, 
                lab = rownames(L7_vs_PBMC),
                x = "avg_log2FC", 
                y = "p_val_adj",
                selectLab = c('EPCAM', 'KIR3DL2', 'FOXM1', 'TWIST1', 'TNFSF9', 
                              'CD80', 'FOS','PTPN6','NCR1','NCR2',
                              'PCLAF', 'KIR3DL1', 'IL4','ITGA6','CCL5',
                              'IL7R', 'TCF7', 'PTTG1', 'RRM2', 'MKI67', 'CD70', 
                              'IL2RA', 'FCGR3A', 'GNLY', 'FOXP3', 'SELL',  'LEF1',
                              'CCL17', 'THY1', 'CD27', 'CD28', 'CD7',
                              # Key Sézary syndrome genes
                              'PRF1', 'GZMB', 'NCR1', 'NFATC3', 
                              'KLRK1', 'LCK', 'KLRC1', 'KLRC2', 'TNF', 
                              'KIR3DL1','KIR3DL3','KIR3DL4', 'IFNG', 'IFNGR1', 'CD244', 'FASLG'),
                title = "L7_vs_PBMC",
                subtitle = "Sézary Syndrome Cell Lines",
                xlab = bquote(~Log[2]~ 'fold change'),
                pCutoff = 0.05,
                FCcutoff = 1.5, 
                pointSize = 3.0,
                labSize = 4.0,
                labFace = 'bold',
                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...
print(volcano2_L7_vs_PBMC)
png("volcano2_L7_vs_PBMC.png", width = 12, height = 10, units = "in", res = 300)
print(volcano2_L7_vs_PBMC)
dev.off()
png 
  2 

# Display top differentially expressed genes for each comparison
head(L7_vs_PBMC)
NA
NA

6. Enrichment Analysis

library(clusterProfiler)
library(org.Hs.eg.db)
library(enrichplot)

perform_go_enrichment <- function(gene_list, gene_universe, title) {
  ego <- enrichGO(gene = gene_list,
                  universe = gene_universe,
                  OrgDb = org.Hs.eg.db,
                  keyType = "SYMBOL",
                  ont = "BP",
                  pAdjustMethod = "BH",
                  qvalueCutoff = 0.05,
                  readable = TRUE)
  
  if (nrow(ego@result) == 0) {
    warning(paste("No enriched GO terms found for", title))
    return(NULL)
  }
  
  p <- dotplot(ego, showCategory = 10, title = paste("GO -", title)) +
    theme(axis.text.y = element_text(size = 8))
  
  print(p)
  png(paste0("GO_enrichment_", gsub(" ", "_", title), ".png"), width = 12, height = 8, units = "in", res = 300)
  print(p)
  dev.off()
  
  return(ego)
}

perform_kegg_enrichment <- function(gene_list, gene_universe, title) {
  # Convert gene symbols to Entrez IDs
  entrez_ids <- bitr(gene_list, fromType = "SYMBOL", toType = "ENTREZID", OrgDb = org.Hs.eg.db)
  universe_entrez <- bitr(gene_universe, fromType = "SYMBOL", toType = "ENTREZID", OrgDb = org.Hs.eg.db)
  
  print(paste("Number of input genes:", length(gene_list)))
  print(paste("Number of input genes mapped to Entrez IDs:", nrow(entrez_ids)))
  print(paste("Number of universe genes:", length(gene_universe)))
  print(paste("Number of universe genes mapped to Entrez IDs:", nrow(universe_entrez)))
  
  if(nrow(entrez_ids) == 0) {
    warning(paste("No genes could be mapped for", title))
    return(NULL)
  }
  
  tryCatch({
    ekegg <- enrichKEGG(gene = entrez_ids$ENTREZID,
                        universe = universe_entrez$ENTREZID,
                        organism = 'hsa',
                        keyType = "kegg",
                        pvalueCutoff = 0.05,
                        pAdjustMethod = "BH")
    
    if(nrow(ekegg@result) == 0) {
      warning(paste("No enriched KEGG pathways found for", title))
      return(NULL)
    }
    
    p <- dotplot(ekegg, showCategory = 10, title = paste("KEGG -", title)) +
      theme(axis.text.y = element_text(size = 8))
    
    print(p)
    png(paste0("KEGG_enrichment_", gsub(" ", "_", title), ".png"), width = 12, height = 8, units = "in", res = 300)
    print(p)
    dev.off()
    
    return(ekegg)
  }, error = function(e) {
    warning(paste("Error in KEGG enrichment for", title, ":", e$message))
    return(NULL)
  })
}

gene_universe <- rownames(All_samples_Merged)

# L1_vs_PBMC comparison
upregulated_genes_L1_vs_PBMC <- rownames(L1_vs_PBMC[L1_vs_PBMC$avg_log2FC > 2.5 & L1_vs_PBMC$p_val_adj < 0.05, ])
downregulated_genes_L1_vs_PBMC <- rownames(L1_vs_PBMC[L1_vs_PBMC$avg_log2FC < -2.5 & L1_vs_PBMC$p_val_adj < 0.05, ])

go_up_L1_vs_PBMC <- perform_go_enrichment(upregulated_genes_L1_vs_PBMC, gene_universe, "Upregulated Genes in L1_vs_PBMC")

go_down_L1_vs_PBMC <- perform_go_enrichment(downregulated_genes_L1_vs_PBMC, gene_universe, "Downregulated Genes in L1_vs_PBMC")

kegg_up_L1_vs_PBMC <- perform_kegg_enrichment(upregulated_genes_L1_vs_PBMC, gene_universe, "Upregulated Genes in L1_vs_PBMC")
'select()' returned 1:1 mapping between keys and columns
Avis : 11.82% of input gene IDs are fail to map...'select()' returned 1:many mapping between keys and columns
Avis : 28.75% of input gene IDs are fail to map...
[1] "Number of input genes: 1743"
[1] "Number of input genes mapped to Entrez IDs: 1537"
[1] "Number of universe genes: 27417"
[1] "Number of universe genes mapped to Entrez IDs: 19538"
Reading KEGG annotation online: "https://rest.kegg.jp/link/hsa/pathway"...
Reading KEGG annotation online: "https://rest.kegg.jp/list/pathway/hsa"...

kegg_down_L1_vs_PBMC <- perform_kegg_enrichment(downregulated_genes_L1_vs_PBMC, gene_universe, "Downregulated Genes in L1_vs_PBMC")
'select()' returned 1:1 mapping between keys and columns
Avis : 9.6% of input gene IDs are fail to map...'select()' returned 1:many mapping between keys and columns
Avis : 28.75% of input gene IDs are fail to map...
[1] "Number of input genes: 1531"
[1] "Number of input genes mapped to Entrez IDs: 1384"
[1] "Number of universe genes: 27417"
[1] "Number of universe genes mapped to Entrez IDs: 19538"

# L2_vs_PBMC comparison
upregulated_genes_L2_vs_PBMC <- rownames(L2_vs_PBMC[L2_vs_PBMC$avg_log2FC > 2.5 & L2_vs_PBMC$p_val_adj < 0.05, ])
downregulated_genes_L2_vs_PBMC <- rownames(L2_vs_PBMC[L2_vs_PBMC$avg_log2FC < -2.5 & L2_vs_PBMC$p_val_adj < 0.05, ])

go_up_L2_vs_PBMC <- perform_go_enrichment(upregulated_genes_L2_vs_PBMC, gene_universe, "Upregulated Genes in L2_vs_PBMC")

go_down_L2_vs_PBMC <- perform_go_enrichment(downregulated_genes_L2_vs_PBMC, gene_universe, "Downregulated Genes in L2_vs_PBMC")

kegg_up_L2_vs_PBMC <- perform_kegg_enrichment(upregulated_genes_L2_vs_PBMC, gene_universe, "Upregulated Genes in L2_vs_PBMC")
'select()' returned 1:1 mapping between keys and columns
Avis : 11.16% of input gene IDs are fail to map...'select()' returned 1:many mapping between keys and columns
Avis : 28.75% of input gene IDs are fail to map...
[1] "Number of input genes: 3046"
[1] "Number of input genes mapped to Entrez IDs: 2706"
[1] "Number of universe genes: 27417"
[1] "Number of universe genes mapped to Entrez IDs: 19538"

kegg_down_L2_vs_PBMC <- perform_kegg_enrichment(downregulated_genes_L2_vs_PBMC, gene_universe, "Downregulated Genes in L2_vs_PBMC")
'select()' returned 1:1 mapping between keys and columns
Avis : 10.25% of input gene IDs are fail to map...'select()' returned 1:many mapping between keys and columns
Avis : 28.75% of input gene IDs are fail to map...
[1] "Number of input genes: 1395"
[1] "Number of input genes mapped to Entrez IDs: 1252"
[1] "Number of universe genes: 27417"
[1] "Number of universe genes mapped to Entrez IDs: 19538"

# L3_vs_PBMC comparison
upregulated_genes_L3_vs_PBMC <- rownames(L3_vs_PBMC[L3_vs_PBMC$avg_log2FC > 2.5 & L3_vs_PBMC$p_val_adj < 0.05, ])
downregulated_genes_L3_vs_PBMC <- rownames(L3_vs_PBMC[L3_vs_PBMC$avg_log2FC < -2.5 & L3_vs_PBMC$p_val_adj < 0.05, ])

go_up_L3_vs_PBMC <- perform_go_enrichment(upregulated_genes_L3_vs_PBMC, gene_universe, "Upregulated Genes in L3_vs_PBMC")

go_down_L3_vs_PBMC <- perform_go_enrichment(downregulated_genes_L3_vs_PBMC, gene_universe, "Downregulated Genes in L3_vs_PBMC")

kegg_up_L3_vs_PBMC <- perform_kegg_enrichment(upregulated_genes_L3_vs_PBMC, gene_universe, "Upregulated Genes in L3_vs_PBMC")
'select()' returned 1:1 mapping between keys and columns
Avis : 14.05% of input gene IDs are fail to map...'select()' returned 1:many mapping between keys and columns
Avis : 28.75% of input gene IDs are fail to map...
[1] "Number of input genes: 2455"
[1] "Number of input genes mapped to Entrez IDs: 2110"
[1] "Number of universe genes: 27417"
[1] "Number of universe genes mapped to Entrez IDs: 19538"

kegg_down_L3_vs_PBMC <- perform_kegg_enrichment(downregulated_genes_L3_vs_PBMC, gene_universe, "Downregulated Genes in L3_vs_PBMC")
'select()' returned 1:1 mapping between keys and columns
Avis : 11.72% of input gene IDs are fail to map...'select()' returned 1:many mapping between keys and columns
Avis : 28.75% of input gene IDs are fail to map...
[1] "Number of input genes: 1629"
[1] "Number of input genes mapped to Entrez IDs: 1438"
[1] "Number of universe genes: 27417"
[1] "Number of universe genes mapped to Entrez IDs: 19538"

# L4_vs_PBMC comparison
upregulated_genes_L4_vs_PBMC <- rownames(L4_vs_PBMC[L4_vs_PBMC$avg_log2FC > 2.5 & L4_vs_PBMC$p_val_adj < 0.05, ])
downregulated_genes_L4_vs_PBMC <- rownames(L4_vs_PBMC[L4_vs_PBMC$avg_log2FC < -2.5 & L4_vs_PBMC$p_val_adj < 0.05, ])

go_up_L4_vs_PBMC <- perform_go_enrichment(upregulated_genes_L4_vs_PBMC, gene_universe, "Upregulated Genes in L4_vs_PBMC")

go_down_L4_vs_PBMC <- perform_go_enrichment(downregulated_genes_L4_vs_PBMC, gene_universe, "Downregulated Genes in L4_vs_PBMC")

kegg_up_L4_vs_PBMC <- perform_kegg_enrichment(upregulated_genes_L4_vs_PBMC, gene_universe, "Upregulated Genes in L4_vs_PBMC")
'select()' returned 1:many mapping between keys and columns
Avis : 13.85% of input gene IDs are fail to map...'select()' returned 1:many mapping between keys and columns
Avis : 28.75% of input gene IDs are fail to map...
[1] "Number of input genes: 3862"
[1] "Number of input genes mapped to Entrez IDs: 3328"
[1] "Number of universe genes: 27417"
[1] "Number of universe genes mapped to Entrez IDs: 19538"

kegg_down_L4_vs_PBMC <- perform_kegg_enrichment(downregulated_genes_L4_vs_PBMC, gene_universe, "Downregulated Genes in L4_vs_PBMC")
'select()' returned 1:1 mapping between keys and columns
Avis : 11.95% of input gene IDs are fail to map...'select()' returned 1:many mapping between keys and columns
Avis : 28.75% of input gene IDs are fail to map...
[1] "Number of input genes: 1155"
[1] "Number of input genes mapped to Entrez IDs: 1017"
[1] "Number of universe genes: 27417"
[1] "Number of universe genes mapped to Entrez IDs: 19538"

# L5_vs_PBMC comparison
upregulated_genes_L5_vs_PBMC <- rownames(L5_vs_PBMC[L5_vs_PBMC$avg_log2FC > 2.5 & L5_vs_PBMC$p_val_adj < 0.05, ])
downregulated_genes_L5_vs_PBMC <- rownames(L5_vs_PBMC[L5_vs_PBMC$avg_log2FC < -2.5 & L5_vs_PBMC$p_val_adj < 0.05, ])

go_up_L5_vs_PBMC <- perform_go_enrichment(upregulated_genes_L5_vs_PBMC, gene_universe, "Upregulated Genes in L5_vs_PBMC")

go_down_L5_vs_PBMC <- perform_go_enrichment(downregulated_genes_L5_vs_PBMC, gene_universe, "Downregulated Genes in L5_vs_PBMC")

kegg_up_L5_vs_PBMC <- perform_kegg_enrichment(upregulated_genes_L5_vs_PBMC, gene_universe, "Upregulated Genes in L5_vs_PBMC")
'select()' returned 1:1 mapping between keys and columns
Avis : 13.01% of input gene IDs are fail to map...'select()' returned 1:many mapping between keys and columns
Avis : 28.75% of input gene IDs are fail to map...
[1] "Number of input genes: 2974"
[1] "Number of input genes mapped to Entrez IDs: 2587"
[1] "Number of universe genes: 27417"
[1] "Number of universe genes mapped to Entrez IDs: 19538"

kegg_down_L5_vs_PBMC <- perform_kegg_enrichment(downregulated_genes_L5_vs_PBMC, gene_universe, "Downregulated Genes in L5_vs_PBMC")
'select()' returned 1:1 mapping between keys and columns
Avis : 11.37% of input gene IDs are fail to map...'select()' returned 1:many mapping between keys and columns
Avis : 28.75% of input gene IDs are fail to map...
[1] "Number of input genes: 1521"
[1] "Number of input genes mapped to Entrez IDs: 1348"
[1] "Number of universe genes: 27417"
[1] "Number of universe genes mapped to Entrez IDs: 19538"

# L6_vs_PBMC comparison
upregulated_genes_L6_vs_PBMC <- rownames(L6_vs_PBMC[L6_vs_PBMC$avg_log2FC > 2.5 & L6_vs_PBMC$p_val_adj < 0.05, ])
downregulated_genes_L6_vs_PBMC <- rownames(L6_vs_PBMC[L6_vs_PBMC$avg_log2FC < -2.5 & L6_vs_PBMC$p_val_adj < 0.05, ])

go_up_L6_vs_PBMC <- perform_go_enrichment(upregulated_genes_L6_vs_PBMC, gene_universe, "Upregulated Genes in L6_vs_PBMC")

go_down_L6_vs_PBMC <- perform_go_enrichment(downregulated_genes_L6_vs_PBMC, gene_universe, "Downregulated Genes in L6_vs_PBMC")

kegg_up_L6_vs_PBMC <- perform_kegg_enrichment(upregulated_genes_L6_vs_PBMC, gene_universe, "Upregulated Genes in L6_vs_PBMC")
'select()' returned 1:1 mapping between keys and columns
Avis : 16.56% of input gene IDs are fail to map...'select()' returned 1:many mapping between keys and columns
Avis : 28.75% of input gene IDs are fail to map...
[1] "Number of input genes: 2271"
[1] "Number of input genes mapped to Entrez IDs: 1895"
[1] "Number of universe genes: 27417"
[1] "Number of universe genes mapped to Entrez IDs: 19538"

kegg_down_L6_vs_PBMC <- perform_kegg_enrichment(downregulated_genes_L6_vs_PBMC, gene_universe, "Downregulated Genes in L6_vs_PBMC")
'select()' returned 1:1 mapping between keys and columns
Avis : 9.8% of input gene IDs are fail to map...'select()' returned 1:many mapping between keys and columns
Avis : 28.75% of input gene IDs are fail to map...
[1] "Number of input genes: 1429"
[1] "Number of input genes mapped to Entrez IDs: 1289"
[1] "Number of universe genes: 27417"
[1] "Number of universe genes mapped to Entrez IDs: 19538"

# L7_vs_PBMC comparison
upregulated_genes_L7_vs_PBMC <- rownames(L7_vs_PBMC[L7_vs_PBMC$avg_log2FC > 2.5 & L7_vs_PBMC$p_val_adj < 0.05, ])
downregulated_genes_L7_vs_PBMC <- rownames(L7_vs_PBMC[L7_vs_PBMC$avg_log2FC < -2.5 & L7_vs_PBMC$p_val_adj < 0.05, ])

go_up_L7_vs_PBMC <- perform_go_enrichment(upregulated_genes_L7_vs_PBMC, gene_universe, "Upregulated Genes in L7_vs_PBMC")

go_down_L7_vs_PBMC <- perform_go_enrichment(downregulated_genes_L7_vs_PBMC, gene_universe, "Downregulated Genes in L7_vs_PBMC")

kegg_up_L7_vs_PBMC <- perform_kegg_enrichment(upregulated_genes_L7_vs_PBMC, gene_universe, "Upregulated Genes in L7_vs_PBMC")
'select()' returned 1:1 mapping between keys and columns
Avis : 13.01% of input gene IDs are fail to map...'select()' returned 1:many mapping between keys and columns
Avis : 28.75% of input gene IDs are fail to map...
[1] "Number of input genes: 2605"
[1] "Number of input genes mapped to Entrez IDs: 2266"
[1] "Number of universe genes: 27417"
[1] "Number of universe genes mapped to Entrez IDs: 19538"

kegg_down_L7_vs_PBMC <- perform_kegg_enrichment(downregulated_genes_L7_vs_PBMC, gene_universe, "Downregulated Genes in L7_vs_PBMC")
'select()' returned 1:1 mapping between keys and columns
Avis : 10.73% of input gene IDs are fail to map...'select()' returned 1:many mapping between keys and columns
Avis : 28.75% of input gene IDs are fail to map...
[1] "Number of input genes: 1510"
[1] "Number of input genes mapped to Entrez IDs: 1348"
[1] "Number of universe genes: 27417"
[1] "Number of universe genes mapped to Entrez IDs: 19538"

LS0tCnRpdGxlOiAiQ2VsbF9saW5lcyB2cyBQQk1DIgphdXRob3I6IE5hc2lyIE1haG1vb2QgQWJiYXNpCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCIKb3V0cHV0OgogICMgcGRmX2RvY3VtZW50OiBkZWZhdWx0CiAgIyB3b3JkX2RvY3VtZW50OiBkZWZhdWx0CiAgIyBodG1sX2RvY3VtZW50OiBkZWZhdWx0CiAgI3JtZGZvcm1hdHM6OnJlYWR0aGVkb3duCiAgaHRtbF9ub3RlYm9vazoKICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OiB0cnVlCiAgICB0b2NfY29sbGFwc2VkOiB0cnVlCi0tLQoKIyAxLiBsb2FkIGxpYnJhcmllcwpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0KCmxpYnJhcnkoU2V1cmF0KQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkocGhlYXRtYXApCmxpYnJhcnkoY2x1c3RlclByb2ZpbGVyKQpsaWJyYXJ5KG9yZy5Icy5lZy5kYikKbGlicmFyeShlbnJpY2hwbG90KQpsaWJyYXJ5KGVucmljaHBsb3QpCmxpYnJhcnkoRW5oYW5jZWRWb2xjYW5vKQoKYGBgCgojRGlmZmVyZW50aWFsIEV4cHJlc3Npb24gQW5hbHlzaXMKIyAyLiBsb2FkIHNldXJhdCBvYmplY3QKYGBge3IgbG9hZF9zZXVyYXR9CiNMb2FkIFNldXJhdCBPYmplY3QgTDcKbG9hZCgiLi4vLi4vLi4vMC1JTVAtT0JKRUNUUy9IYXJtb255X2ludGVncmF0ZWRfQWxsX3NhbXBsZXNfTWVyZ2VkX3dpdGhfUEJNQzEweF93aXRoX2hhcm1vbnlfY2x1c3RlcmluZy5Sb2JqIikKCgpBbGxfc2FtcGxlc19NZXJnZWQKCkRpbVBsb3QoQWxsX3NhbXBsZXNfTWVyZ2VkLCByZWR1Y3Rpb24gPSAidW1hcC5oYXJtb255IiwgZ3JvdXAuYnkgPSAiY2VsbF9saW5lIixsYWJlbCA9IFQsIGxhYmVsLmJveCA9IFQpCkRpbVBsb3QoQWxsX3NhbXBsZXNfTWVyZ2VkLCByZWR1Y3Rpb24gPSAidW1hcC5oYXJtb255IiwgZ3JvdXAuYnkgPSAiSGFybW9ueV9zbm5fcmVzLjAuOSIsbGFiZWwgPSBULCBsYWJlbC5ib3ggPSBUKQoKYGBgCgojRGlmZmVyZW50aWFsIEV4cHJlc3Npb24gQW5hbHlzaXMKCiMgMy4gTDEgdnMgUEJNQwpgYGB7ciBmaW5kbWFya2VyczEsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTEyfQoKRGVmYXVsdEFzc2F5KEFsbF9zYW1wbGVzX01lcmdlZCkgPC0gIlNDVCIKSWRlbnRzKEFsbF9zYW1wbGVzX01lcmdlZCkgPC0gImNlbGxfbGluZSIKCiMgUDEgdnMgUEJNQy1UY2VsbHMKTDFfdnNfUEJNQyA8LSBGaW5kTWFya2VycyhBbGxfc2FtcGxlc19NZXJnZWQsIAogICAgICAgICAgICAgICAgICAgICAgICBpZGVudC4xID0gIkwxIiwgIAogICAgICAgICAgICAgICAgICAgICAgICBpZGVudC4yID0gYygiUEJNQyIsIlBCTUNfMTB4IiksICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgIGFzc2F5ID0gIlNDVCIpCgp3cml0ZS5jc3YoTDFfdnNfUEJNQywgIk5ld19jb21wYXJpc29uX0wxX3ZzX1BCTUMuY3N2IikKCiMgQ29udmVydCB0byBkYXRhIGZyYW1lIGFuZCBhZGQgZ2VuZSBuYW1lcyBhcyBhIG5ldyBjb2x1bW4KTDFfdnNfUEJNQyA8LSBhcy5kYXRhLmZyYW1lKEwxX3ZzX1BCTUMpCkwxX3ZzX1BCTUMkZ2VuZSA8LSByb3duYW1lcyhMMV92c19QQk1DKQoKCiMgUmVhcnJhbmdpbmcgdGhlIGNvbHVtbnMgZm9yIGJldHRlciByZWFkYWJpbGl0eSAob3B0aW9uYWwpCkwxX3ZzX1BCTUMgIDwtIEwxX3ZzX1BCTUNbLCAKICAgIGMoImdlbmUiLCAicF92YWwiLCAiYXZnX2xvZzJGQyIsICJwY3QuMSIsICJwY3QuMiIsICJwX3ZhbF9hZGoiKV0KCgoKIyBDcmVhdGUgdm9sY2FubyBwbG90IGZvciBQMSB2cyBQQk1DLVRjZWxscwp2b2xjYW5vX0wxX3ZzX1BCTUMgPC0gRW5oYW5jZWRWb2xjYW5vKEwxX3ZzX1BCTUMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWIgPSByb3duYW1lcyhMMV92c19QQk1DKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeCA9ICdhdmdfbG9nMkZDJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeSA9ICdwX3ZhbF9hZGonLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aXRsZSA9ICdMMV92c19QQk1DJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeGxhYiA9IGJxdW90ZSh+TG9nWzJdfiAnZm9sZCBjaGFuZ2UnKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcEN1dG9mZiA9IDFlLTEwMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRkNjdXRvZmYgPSAxLjUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb2ludFNpemUgPSAzLjAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYlNpemUgPSA1LjAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJveGVkTGFiZWxzID0gVFJVRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sQWxwaGEgPSAwLjUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlZ2VuZFBvc2l0aW9uID0gJ3JpZ2h0JywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVnZW5kTGFiU2l6ZSA9IDEwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZWdlbmRJY29uU2l6ZSA9IDQuMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHJhd0Nvbm5lY3RvcnMgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWR0aENvbm5lY3RvcnMgPSAwLjUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbENvbm5lY3RvcnMgPSAnZ3JleTUwJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJyb3doZWFkcyA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXgub3ZlcmxhcHMgPSAzMCkKcHJpbnQodm9sY2Fub19MMV92c19QQk1DKQpwbmcoInZvbGNhbm9fTDFfdnNfUEJNQy5wbmciLCB3aWR0aCA9IDEyLCBoZWlnaHQgPSAxMCwgdW5pdHMgPSAiaW4iLCByZXMgPSAzMDApCnByaW50KHZvbGNhbm9fTDFfdnNfUEJNQykKZGV2Lm9mZigpCgoKdm9sY2FubzJfTDFfdnNfUEJNQyA8LSBFbmhhbmNlZFZvbGNhbm8oTDFfdnNfUEJNQywgCiAgICAgICAgICAgICAgICBsYWIgPSByb3duYW1lcyhMMV92c19QQk1DKSwKICAgICAgICAgICAgICAgIHggPSAiYXZnX2xvZzJGQyIsIAogICAgICAgICAgICAgICAgeSA9ICJwX3ZhbF9hZGoiLAogICAgICAgICAgICAgICAgc2VsZWN0TGFiID0gYygnRVBDQU0nLCAnS0lSM0RMMicsICdGT1hNMScsICdUV0lTVDEnLCAnVE5GU0Y5JywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdDRDgwJywgJ0ZPUycsJ1BUUE42JywnTkNSMScsJ05DUjInLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnUENMQUYnLCAnS0lSM0RMMScsICdJTDQnLCdJVEdBNicsJ0NDTDUnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnSUw3UicsICdUQ0Y3JywgJ1BUVEcxJywgJ1JSTTInLCAnTUtJNjcnLCAnQ0Q3MCcsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnSUwyUkEnLCAnRkNHUjNBJywgJ0dOTFknLCAnRk9YUDMnLCAnU0VMTCcsICAnTEVGMScsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdDQ0wxNycsICdUSFkxJywgJ0NEMjcnLCAnQ0QyOCcsICdDRDcnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIEtleSBTw6l6YXJ5IHN5bmRyb21lIGdlbmVzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdQUkYxJywgJ0daTUInLCAnTkNSMScsICdORkFUQzMnLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0tMUksxJywgJ0xDSycsICdLTFJDMScsICdLTFJDMicsICdUTkYnLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0tJUjNETDEnLCdLSVIzREwzJywnS0lSM0RMNCcsICdJRk5HJywgJ0lGTkdSMScsICdDRDI0NCcsICdGQVNMRycpLAogICAgICAgICAgICAgICAgdGl0bGUgPSAiTDFfdnNfUEJNQyIsCiAgICAgICAgICAgICAgICBzdWJ0aXRsZSA9ICJTw6l6YXJ5IFN5bmRyb21lIENlbGwgTGluZXMiLAogICAgICAgICAgICAgICAgeGxhYiA9IGJxdW90ZSh+TG9nWzJdfiAnZm9sZCBjaGFuZ2UnKSwKICAgICAgICAgICAgICAgIHBDdXRvZmYgPSAwLjA1LAogICAgICAgICAgICAgICAgRkNjdXRvZmYgPSAxLjUsIAogICAgICAgICAgICAgICAgcG9pbnRTaXplID0gMy4wLAogICAgICAgICAgICAgICAgbGFiU2l6ZSA9IDQuMCwKICAgICAgICAgICAgICAgIGxhYkZhY2UgPSAnYm9sZCcsCiAgICAgICAgICAgICAgICBib3hlZExhYmVscyA9IFRSVUUsCiAgICAgICAgICAgICAgICBjb2xBbHBoYSA9IDAuNSwKICAgICAgICAgICAgICAgIGxlZ2VuZFBvc2l0aW9uID0gJ3JpZ2h0JywKICAgICAgICAgICAgICAgIGxlZ2VuZExhYlNpemUgPSAxMCwKICAgICAgICAgICAgICAgIGxlZ2VuZEljb25TaXplID0gNC4wLAogICAgICAgICAgICAgICAgZHJhd0Nvbm5lY3RvcnMgPSBUUlVFLAogICAgICAgICAgICAgICAgd2lkdGhDb25uZWN0b3JzID0gMC41LAogICAgICAgICAgICAgICAgY29sQ29ubmVjdG9ycyA9ICdncmV5NTAnLAogICAgICAgICAgICAgICAgYXJyb3doZWFkcyA9IEZBTFNFLAogICAgICAgICAgICAgICAgbWF4Lm92ZXJsYXBzID0gMzApCnByaW50KHZvbGNhbm8yX0wxX3ZzX1BCTUMpCnBuZygidm9sY2FubzJfTDFfdnNfUEJNQy5wbmciLCB3aWR0aCA9IDEyLCBoZWlnaHQgPSAxMCwgdW5pdHMgPSAiaW4iLCByZXMgPSAzMDApCnByaW50KHZvbGNhbm8yX0wxX3ZzX1BCTUMpCmRldi5vZmYoKQoKIyBEaXNwbGF5IHRvcCBkaWZmZXJlbnRpYWxseSBleHByZXNzZWQgZ2VuZXMgZm9yIGVhY2ggY29tcGFyaXNvbgpoZWFkKEwxX3ZzX1BCTUMpCgoKYGBgCgoKCgojIDQuIEwyX3ZzX1BCTUMKYGBge3IgZmluZG1hcmtlcnMyLCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD0xMn0KCkRlZmF1bHRBc3NheShBbGxfc2FtcGxlc19NZXJnZWQpIDwtICJTQ1QiCklkZW50cyhBbGxfc2FtcGxlc19NZXJnZWQpIDwtICJjZWxsX2xpbmUiCgojIFAxIHZzIFBCTUMtVGNlbGxzCkwyX3ZzX1BCTUMgPC0gRmluZE1hcmtlcnMoQWxsX3NhbXBsZXNfTWVyZ2VkLCAKICAgICAgICAgICAgICAgICAgICAgICAgaWRlbnQuMSA9ICJMMiIsICAKICAgICAgICAgICAgICAgICAgICAgICAgaWRlbnQuMiA9IGMoIlBCTUMiLCJQQk1DXzEweCIpLCAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICBhc3NheSA9ICJTQ1QiKQoKd3JpdGUuY3N2KEwyX3ZzX1BCTUMsICJOZXdfY29tcGFyaXNvbl9MMl92c19QQk1DLmNzdiIpCgojIENvbnZlcnQgdG8gZGF0YSBmcmFtZSBhbmQgYWRkIGdlbmUgbmFtZXMgYXMgYSBuZXcgY29sdW1uCkwyX3ZzX1BCTUMgPC0gYXMuZGF0YS5mcmFtZShMMl92c19QQk1DKQpMMl92c19QQk1DJGdlbmUgPC0gcm93bmFtZXMoTDJfdnNfUEJNQykKCgojIFJlYXJyYW5naW5nIHRoZSBjb2x1bW5zIGZvciBiZXR0ZXIgcmVhZGFiaWxpdHkgKG9wdGlvbmFsKQpMMl92c19QQk1DICA8LSBMMl92c19QQk1DWywgCiAgICBjKCJnZW5lIiwgInBfdmFsIiwgImF2Z19sb2cyRkMiLCAicGN0LjEiLCAicGN0LjIiLCAicF92YWxfYWRqIildCgoKCiMgQ3JlYXRlIHZvbGNhbm8gcGxvdCBmb3IgUDEgdnMgUEJNQy1UY2VsbHMKdm9sY2Fub19MMl92c19QQk1DIDwtIEVuaGFuY2VkVm9sY2FubyhMMl92c19QQk1DLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiID0gcm93bmFtZXMoTDJfdnNfUEJNQyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHggPSAnYXZnX2xvZzJGQycsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkgPSAncF92YWxfYWRqJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGUgPSAnTDJfdnNfUEJNQycsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhsYWIgPSBicXVvdGUofkxvZ1syXX4gJ2ZvbGQgY2hhbmdlJyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBDdXRvZmYgPSAxZS0xMDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZDY3V0b2ZmID0gMS41LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9pbnRTaXplID0gMy4wLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJTaXplID0gNS4wLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib3hlZExhYmVscyA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbEFscGhhID0gMC41LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZWdlbmRQb3NpdGlvbiA9ICdyaWdodCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlZ2VuZExhYlNpemUgPSAxMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVnZW5kSWNvblNpemUgPSA0LjAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRyYXdDb25uZWN0b3JzID0gVFJVRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGhDb25uZWN0b3JzID0gMC41LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xDb25uZWN0b3JzID0gJ2dyZXk1MCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFycm93aGVhZHMgPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF4Lm92ZXJsYXBzID0gMzApCnByaW50KHZvbGNhbm9fTDJfdnNfUEJNQykKcG5nKCJ2b2xjYW5vX0wyX3ZzX1BCTUMucG5nIiwgd2lkdGggPSAxMiwgaGVpZ2h0ID0gMTAsIHVuaXRzID0gImluIiwgcmVzID0gMzAwKQpwcmludCh2b2xjYW5vX0wyX3ZzX1BCTUMpCmRldi5vZmYoKQoKCnZvbGNhbm8yX0wyX3ZzX1BCTUMgPC0gRW5oYW5jZWRWb2xjYW5vKEwyX3ZzX1BCTUMsIAogICAgICAgICAgICAgICAgbGFiID0gcm93bmFtZXMoTDJfdnNfUEJNQyksCiAgICAgICAgICAgICAgICB4ID0gImF2Z19sb2cyRkMiLCAKICAgICAgICAgICAgICAgIHkgPSAicF92YWxfYWRqIiwKICAgICAgICAgICAgICAgIHNlbGVjdExhYiA9IGMoJ0VQQ0FNJywgJ0tJUjNETDInLCAnRk9YTTEnLCAnVFdJU1QxJywgJ1RORlNGOScsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnQ0Q4MCcsICdGT1MnLCdQVFBONicsJ05DUjEnLCdOQ1IyJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1BDTEFGJywgJ0tJUjNETDEnLCAnSUw0JywnSVRHQTYnLCdDQ0w1JywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0lMN1InLCAnVENGNycsICdQVFRHMScsICdSUk0yJywgJ01LSTY3JywgJ0NENzAnLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0lMMlJBJywgJ0ZDR1IzQScsICdHTkxZJywgJ0ZPWFAzJywgJ1NFTEwnLCAgJ0xFRjEnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnQ0NMMTcnLCAnVEhZMScsICdDRDI3JywgJ0NEMjgnLCAnQ0Q3JywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBLZXkgU8OpemFyeSBzeW5kcm9tZSBnZW5lcwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnUFJGMScsICdHWk1CJywgJ05DUjEnLCAnTkZBVEMzJywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdLTFJLMScsICdMQ0snLCAnS0xSQzEnLCAnS0xSQzInLCAnVE5GJywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdLSVIzREwxJywnS0lSM0RMMycsJ0tJUjNETDQnLCAnSUZORycsICdJRk5HUjEnLCAnQ0QyNDQnLCAnRkFTTEcnKSwKICAgICAgICAgICAgICAgIHRpdGxlID0gIkwyX3ZzX1BCTUMiLAogICAgICAgICAgICAgICAgc3VidGl0bGUgPSAiU8OpemFyeSBTeW5kcm9tZSBDZWxsIExpbmVzIiwKICAgICAgICAgICAgICAgIHhsYWIgPSBicXVvdGUofkxvZ1syXX4gJ2ZvbGQgY2hhbmdlJyksCiAgICAgICAgICAgICAgICBwQ3V0b2ZmID0gMC4wNSwKICAgICAgICAgICAgICAgIEZDY3V0b2ZmID0gMS41LCAKICAgICAgICAgICAgICAgIHBvaW50U2l6ZSA9IDMuMCwKICAgICAgICAgICAgICAgIGxhYlNpemUgPSA0LjAsCiAgICAgICAgICAgICAgICBsYWJGYWNlID0gJ2JvbGQnLAogICAgICAgICAgICAgICAgYm94ZWRMYWJlbHMgPSBUUlVFLAogICAgICAgICAgICAgICAgY29sQWxwaGEgPSAwLjUsCiAgICAgICAgICAgICAgICBsZWdlbmRQb3NpdGlvbiA9ICdyaWdodCcsCiAgICAgICAgICAgICAgICBsZWdlbmRMYWJTaXplID0gMTAsCiAgICAgICAgICAgICAgICBsZWdlbmRJY29uU2l6ZSA9IDQuMCwKICAgICAgICAgICAgICAgIGRyYXdDb25uZWN0b3JzID0gVFJVRSwKICAgICAgICAgICAgICAgIHdpZHRoQ29ubmVjdG9ycyA9IDAuNSwKICAgICAgICAgICAgICAgIGNvbENvbm5lY3RvcnMgPSAnZ3JleTUwJywKICAgICAgICAgICAgICAgIGFycm93aGVhZHMgPSBGQUxTRSwKICAgICAgICAgICAgICAgIG1heC5vdmVybGFwcyA9IDMwKQpwcmludCh2b2xjYW5vMl9MMl92c19QQk1DKQpwbmcoInZvbGNhbm8yX0wyX3ZzX1BCTUMucG5nIiwgd2lkdGggPSAxMiwgaGVpZ2h0ID0gMTAsIHVuaXRzID0gImluIiwgcmVzID0gMzAwKQpwcmludCh2b2xjYW5vMl9MMl92c19QQk1DKQpkZXYub2ZmKCkKCiMgRGlzcGxheSB0b3AgZGlmZmVyZW50aWFsbHkgZXhwcmVzc2VkIGdlbmVzIGZvciBlYWNoIGNvbXBhcmlzb24KaGVhZChMMl92c19QQk1DKQoKCmBgYAoKCiMgNS4gTDNfdnNfUEJNQwpgYGB7ciBmaW5kbWFya2VyczMsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTEyfQoKRGVmYXVsdEFzc2F5KEFsbF9zYW1wbGVzX01lcmdlZCkgPC0gIlNDVCIKSWRlbnRzKEFsbF9zYW1wbGVzX01lcmdlZCkgPC0gImNlbGxfbGluZSIKCiMgUDEgdnMgUEJNQy1UY2VsbHMKTDNfdnNfUEJNQyA8LSBGaW5kTWFya2VycyhBbGxfc2FtcGxlc19NZXJnZWQsIAogICAgICAgICAgICAgICAgICAgICAgICBpZGVudC4xID0gIkwzIiwgIAogICAgICAgICAgICAgICAgICAgICAgICBpZGVudC4yID0gYygiUEJNQyIsIlBCTUNfMTB4IiksICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgIGFzc2F5ID0gIlNDVCIpCgp3cml0ZS5jc3YoTDNfdnNfUEJNQywgIk5ld19jb21wYXJpc29uX0wzX3ZzX1BCTUMuY3N2IikKCiMgQ29udmVydCB0byBkYXRhIGZyYW1lIGFuZCBhZGQgZ2VuZSBuYW1lcyBhcyBhIG5ldyBjb2x1bW4KTDNfdnNfUEJNQyA8LSBhcy5kYXRhLmZyYW1lKEwzX3ZzX1BCTUMpCkwzX3ZzX1BCTUMkZ2VuZSA8LSByb3duYW1lcyhMM192c19QQk1DKQoKCiMgUmVhcnJhbmdpbmcgdGhlIGNvbHVtbnMgZm9yIGJldHRlciByZWFkYWJpbGl0eSAob3B0aW9uYWwpCkwzX3ZzX1BCTUMgIDwtIEwzX3ZzX1BCTUNbLCAKICAgIGMoImdlbmUiLCAicF92YWwiLCAiYXZnX2xvZzJGQyIsICJwY3QuMSIsICJwY3QuMiIsICJwX3ZhbF9hZGoiKV0KCgoKIyBDcmVhdGUgdm9sY2FubyBwbG90IGZvciBQMSB2cyBQQk1DLVRjZWxscwp2b2xjYW5vX0wzX3ZzX1BCTUMgPC0gRW5oYW5jZWRWb2xjYW5vKEwzX3ZzX1BCTUMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWIgPSByb3duYW1lcyhMM192c19QQk1DKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeCA9ICdhdmdfbG9nMkZDJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeSA9ICdwX3ZhbF9hZGonLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aXRsZSA9ICdMM192c19QQk1DJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeGxhYiA9IGJxdW90ZSh+TG9nWzJdfiAnZm9sZCBjaGFuZ2UnKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcEN1dG9mZiA9IDFlLTEwMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRkNjdXRvZmYgPSAxLjUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb2ludFNpemUgPSAzLjAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYlNpemUgPSA1LjAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJveGVkTGFiZWxzID0gVFJVRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sQWxwaGEgPSAwLjUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlZ2VuZFBvc2l0aW9uID0gJ3JpZ2h0JywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVnZW5kTGFiU2l6ZSA9IDEwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZWdlbmRJY29uU2l6ZSA9IDQuMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHJhd0Nvbm5lY3RvcnMgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWR0aENvbm5lY3RvcnMgPSAwLjUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbENvbm5lY3RvcnMgPSAnZ3JleTUwJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJyb3doZWFkcyA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXgub3ZlcmxhcHMgPSAzMCkKcHJpbnQodm9sY2Fub19MM192c19QQk1DKQpwbmcoInZvbGNhbm9fTDNfdnNfUEJNQy5wbmciLCB3aWR0aCA9IDEyLCBoZWlnaHQgPSAxMCwgdW5pdHMgPSAiaW4iLCByZXMgPSAzMDApCnByaW50KHZvbGNhbm9fTDNfdnNfUEJNQykKZGV2Lm9mZigpCgoKdm9sY2FubzJfTDNfdnNfUEJNQyA8LSBFbmhhbmNlZFZvbGNhbm8oTDNfdnNfUEJNQywgCiAgICAgICAgICAgICAgICBsYWIgPSByb3duYW1lcyhMM192c19QQk1DKSwKICAgICAgICAgICAgICAgIHggPSAiYXZnX2xvZzJGQyIsIAogICAgICAgICAgICAgICAgeSA9ICJwX3ZhbF9hZGoiLAogICAgICAgICAgICAgICAgc2VsZWN0TGFiID0gYygnRVBDQU0nLCAnS0lSM0RMMicsICdGT1hNMScsICdUV0lTVDEnLCAnVE5GU0Y5JywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdDRDgwJywgJ0ZPUycsJ1BUUE42JywnTkNSMScsJ05DUjInLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnUENMQUYnLCAnS0lSM0RMMScsICdJTDQnLCdJVEdBNicsJ0NDTDUnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnSUw3UicsICdUQ0Y3JywgJ1BUVEcxJywgJ1JSTTInLCAnTUtJNjcnLCAnQ0Q3MCcsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnSUwyUkEnLCAnRkNHUjNBJywgJ0dOTFknLCAnRk9YUDMnLCAnU0VMTCcsICAnTEVGMScsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdDQ0wxNycsICdUSFkxJywgJ0NEMjcnLCAnQ0QyOCcsICdDRDcnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIEtleSBTw6l6YXJ5IHN5bmRyb21lIGdlbmVzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdQUkYxJywgJ0daTUInLCAnTkNSMScsICdORkFUQzMnLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0tMUksxJywgJ0xDSycsICdLTFJDMScsICdLTFJDMicsICdUTkYnLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0tJUjNETDEnLCdLSVIzREwzJywnS0lSM0RMNCcsICdJRk5HJywgJ0lGTkdSMScsICdDRDI0NCcsICdGQVNMRycpLAogICAgICAgICAgICAgICAgdGl0bGUgPSAiTDNfdnNfUEJNQyIsCiAgICAgICAgICAgICAgICBzdWJ0aXRsZSA9ICJTw6l6YXJ5IFN5bmRyb21lIENlbGwgTGluZXMiLAogICAgICAgICAgICAgICAgeGxhYiA9IGJxdW90ZSh+TG9nWzJdfiAnZm9sZCBjaGFuZ2UnKSwKICAgICAgICAgICAgICAgIHBDdXRvZmYgPSAwLjA1LAogICAgICAgICAgICAgICAgRkNjdXRvZmYgPSAxLjUsIAogICAgICAgICAgICAgICAgcG9pbnRTaXplID0gMy4wLAogICAgICAgICAgICAgICAgbGFiU2l6ZSA9IDQuMCwKICAgICAgICAgICAgICAgIGxhYkZhY2UgPSAnYm9sZCcsCiAgICAgICAgICAgICAgICBib3hlZExhYmVscyA9IFRSVUUsCiAgICAgICAgICAgICAgICBjb2xBbHBoYSA9IDAuNSwKICAgICAgICAgICAgICAgIGxlZ2VuZFBvc2l0aW9uID0gJ3JpZ2h0JywKICAgICAgICAgICAgICAgIGxlZ2VuZExhYlNpemUgPSAxMCwKICAgICAgICAgICAgICAgIGxlZ2VuZEljb25TaXplID0gNC4wLAogICAgICAgICAgICAgICAgZHJhd0Nvbm5lY3RvcnMgPSBUUlVFLAogICAgICAgICAgICAgICAgd2lkdGhDb25uZWN0b3JzID0gMC41LAogICAgICAgICAgICAgICAgY29sQ29ubmVjdG9ycyA9ICdncmV5NTAnLAogICAgICAgICAgICAgICAgYXJyb3doZWFkcyA9IEZBTFNFLAogICAgICAgICAgICAgICAgbWF4Lm92ZXJsYXBzID0gMzApCnByaW50KHZvbGNhbm8yX0wzX3ZzX1BCTUMpCnBuZygidm9sY2FubzJfTDNfdnNfUEJNQy5wbmciLCB3aWR0aCA9IDEyLCBoZWlnaHQgPSAxMCwgdW5pdHMgPSAiaW4iLCByZXMgPSAzMDApCnByaW50KHZvbGNhbm8yX0wzX3ZzX1BCTUMpCmRldi5vZmYoKQoKIyBEaXNwbGF5IHRvcCBkaWZmZXJlbnRpYWxseSBleHByZXNzZWQgZ2VuZXMgZm9yIGVhY2ggY29tcGFyaXNvbgpoZWFkKEwzX3ZzX1BCTUMpCgoKYGBgCgoKIyA2LiBMNF92c19QQk1DCmBgYHtyIGZpbmRtYXJrZXJzNCwgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9MTJ9CgpEZWZhdWx0QXNzYXkoQWxsX3NhbXBsZXNfTWVyZ2VkKSA8LSAiU0NUIgpJZGVudHMoQWxsX3NhbXBsZXNfTWVyZ2VkKSA8LSAiY2VsbF9saW5lIgoKIyBQMSB2cyBQQk1DLVRjZWxscwpMNF92c19QQk1DIDwtIEZpbmRNYXJrZXJzKEFsbF9zYW1wbGVzX01lcmdlZCwgCiAgICAgICAgICAgICAgICAgICAgICAgIGlkZW50LjEgPSAiTDQiLCAgCiAgICAgICAgICAgICAgICAgICAgICAgIGlkZW50LjIgPSBjKCJQQk1DIiwiUEJNQ18xMHgiKSwgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgYXNzYXkgPSAiU0NUIikKCndyaXRlLmNzdihMNF92c19QQk1DLCAiTmV3X2NvbXBhcmlzb25fTDRfdnNfUEJNQy5jc3YiKQoKIyBDb252ZXJ0IHRvIGRhdGEgZnJhbWUgYW5kIGFkZCBnZW5lIG5hbWVzIGFzIGEgbmV3IGNvbHVtbgpMNF92c19QQk1DIDwtIGFzLmRhdGEuZnJhbWUoTDRfdnNfUEJNQykKTDRfdnNfUEJNQyRnZW5lIDwtIHJvd25hbWVzKEw0X3ZzX1BCTUMpCgoKIyBSZWFycmFuZ2luZyB0aGUgY29sdW1ucyBmb3IgYmV0dGVyIHJlYWRhYmlsaXR5IChvcHRpb25hbCkKTDRfdnNfUEJNQyAgPC0gTDRfdnNfUEJNQ1ssIAogICAgYygiZ2VuZSIsICJwX3ZhbCIsICJhdmdfbG9nMkZDIiwgInBjdC4xIiwgInBjdC4yIiwgInBfdmFsX2FkaiIpXQoKCgojIENyZWF0ZSB2b2xjYW5vIHBsb3QgZm9yIFAxIHZzIFBCTUMtVGNlbGxzCnZvbGNhbm9fTDRfdnNfUEJNQyA8LSBFbmhhbmNlZFZvbGNhbm8oTDRfdnNfUEJNQywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYiA9IHJvd25hbWVzKEw0X3ZzX1BCTUMpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4ID0gJ2F2Z19sb2cyRkMnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ID0gJ3BfdmFsX2FkaicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlID0gJ0w0X3ZzX1BCTUMnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bGFiID0gYnF1b3RlKH5Mb2dbMl1+ICdmb2xkIGNoYW5nZScpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwQ3V0b2ZmID0gMWUtMTAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGQ2N1dG9mZiA9IDEuNSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvaW50U2l6ZSA9IDMuMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiU2l6ZSA9IDUuMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm94ZWRMYWJlbHMgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xBbHBoYSA9IDAuNSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVnZW5kUG9zaXRpb24gPSAncmlnaHQnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZWdlbmRMYWJTaXplID0gMTAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlZ2VuZEljb25TaXplID0gNC4wLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkcmF3Q29ubmVjdG9ycyA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpZHRoQ29ubmVjdG9ycyA9IDAuNSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sQ29ubmVjdG9ycyA9ICdncmV5NTAnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnJvd2hlYWRzID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1heC5vdmVybGFwcyA9IDMwKQpwcmludCh2b2xjYW5vX0w0X3ZzX1BCTUMpCnBuZygidm9sY2Fub19MNF92c19QQk1DLnBuZyIsIHdpZHRoID0gMTIsIGhlaWdodCA9IDEwLCB1bml0cyA9ICJpbiIsIHJlcyA9IDMwMCkKcHJpbnQodm9sY2Fub19MNF92c19QQk1DKQpkZXYub2ZmKCkKCgp2b2xjYW5vMl9MNF92c19QQk1DIDwtIEVuaGFuY2VkVm9sY2FubyhMNF92c19QQk1DLCAKICAgICAgICAgICAgICAgIGxhYiA9IHJvd25hbWVzKEw0X3ZzX1BCTUMpLAogICAgICAgICAgICAgICAgeCA9ICJhdmdfbG9nMkZDIiwgCiAgICAgICAgICAgICAgICB5ID0gInBfdmFsX2FkaiIsCiAgICAgICAgICAgICAgICBzZWxlY3RMYWIgPSBjKCdFUENBTScsICdLSVIzREwyJywgJ0ZPWE0xJywgJ1RXSVNUMScsICdUTkZTRjknLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0NEODAnLCAnRk9TJywnUFRQTjYnLCdOQ1IxJywnTkNSMicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdQQ0xBRicsICdLSVIzREwxJywgJ0lMNCcsJ0lUR0E2JywnQ0NMNScsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdJTDdSJywgJ1RDRjcnLCAnUFRURzEnLCAnUlJNMicsICdNS0k2NycsICdDRDcwJywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdJTDJSQScsICdGQ0dSM0EnLCAnR05MWScsICdGT1hQMycsICdTRUxMJywgICdMRUYxJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0NDTDE3JywgJ1RIWTEnLCAnQ0QyNycsICdDRDI4JywgJ0NENycsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgS2V5IFPDqXphcnkgc3luZHJvbWUgZ2VuZXMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1BSRjEnLCAnR1pNQicsICdOQ1IxJywgJ05GQVRDMycsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnS0xSSzEnLCAnTENLJywgJ0tMUkMxJywgJ0tMUkMyJywgJ1RORicsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnS0lSM0RMMScsJ0tJUjNETDMnLCdLSVIzREw0JywgJ0lGTkcnLCAnSUZOR1IxJywgJ0NEMjQ0JywgJ0ZBU0xHJyksCiAgICAgICAgICAgICAgICB0aXRsZSA9ICJMNF92c19QQk1DIiwKICAgICAgICAgICAgICAgIHN1YnRpdGxlID0gIlPDqXphcnkgU3luZHJvbWUgQ2VsbCBMaW5lcyIsCiAgICAgICAgICAgICAgICB4bGFiID0gYnF1b3RlKH5Mb2dbMl1+ICdmb2xkIGNoYW5nZScpLAogICAgICAgICAgICAgICAgcEN1dG9mZiA9IDAuMDUsCiAgICAgICAgICAgICAgICBGQ2N1dG9mZiA9IDEuNSwgCiAgICAgICAgICAgICAgICBwb2ludFNpemUgPSAzLjAsCiAgICAgICAgICAgICAgICBsYWJTaXplID0gNC4wLAogICAgICAgICAgICAgICAgbGFiRmFjZSA9ICdib2xkJywKICAgICAgICAgICAgICAgIGJveGVkTGFiZWxzID0gVFJVRSwKICAgICAgICAgICAgICAgIGNvbEFscGhhID0gMC41LAogICAgICAgICAgICAgICAgbGVnZW5kUG9zaXRpb24gPSAncmlnaHQnLAogICAgICAgICAgICAgICAgbGVnZW5kTGFiU2l6ZSA9IDEwLAogICAgICAgICAgICAgICAgbGVnZW5kSWNvblNpemUgPSA0LjAsCiAgICAgICAgICAgICAgICBkcmF3Q29ubmVjdG9ycyA9IFRSVUUsCiAgICAgICAgICAgICAgICB3aWR0aENvbm5lY3RvcnMgPSAwLjUsCiAgICAgICAgICAgICAgICBjb2xDb25uZWN0b3JzID0gJ2dyZXk1MCcsCiAgICAgICAgICAgICAgICBhcnJvd2hlYWRzID0gRkFMU0UsCiAgICAgICAgICAgICAgICBtYXgub3ZlcmxhcHMgPSAzMCkKcHJpbnQodm9sY2FubzJfTDRfdnNfUEJNQykKcG5nKCJ2b2xjYW5vMl9MNF92c19QQk1DLnBuZyIsIHdpZHRoID0gMTIsIGhlaWdodCA9IDEwLCB1bml0cyA9ICJpbiIsIHJlcyA9IDMwMCkKcHJpbnQodm9sY2FubzJfTDRfdnNfUEJNQykKZGV2Lm9mZigpCgojIERpc3BsYXkgdG9wIGRpZmZlcmVudGlhbGx5IGV4cHJlc3NlZCBnZW5lcyBmb3IgZWFjaCBjb21wYXJpc29uCmhlYWQoTDRfdnNfUEJNQykKCgpgYGAKCgojIDcuIEw1X3ZzX1BCTUMKYGBge3IgZmluZG1hcmtlcnM1LCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD0xMn0KCkRlZmF1bHRBc3NheShBbGxfc2FtcGxlc19NZXJnZWQpIDwtICJTQ1QiCklkZW50cyhBbGxfc2FtcGxlc19NZXJnZWQpIDwtICJjZWxsX2xpbmUiCgojIFAxIHZzIFBCTUMtVGNlbGxzCkw1X3ZzX1BCTUMgPC0gRmluZE1hcmtlcnMoQWxsX3NhbXBsZXNfTWVyZ2VkLCAKICAgICAgICAgICAgICAgICAgICAgICAgaWRlbnQuMSA9ICJMNSIsICAKICAgICAgICAgICAgICAgICAgICAgICAgaWRlbnQuMiA9IGMoIlBCTUMiLCJQQk1DXzEweCIpLCAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICBhc3NheSA9ICJTQ1QiKQoKd3JpdGUuY3N2KEw1X3ZzX1BCTUMsICJOZXdfY29tcGFyaXNvbl9MNV92c19QQk1DLmNzdiIpCgojIENvbnZlcnQgdG8gZGF0YSBmcmFtZSBhbmQgYWRkIGdlbmUgbmFtZXMgYXMgYSBuZXcgY29sdW1uCkw1X3ZzX1BCTUMgPC0gYXMuZGF0YS5mcmFtZShMNV92c19QQk1DKQpMNV92c19QQk1DJGdlbmUgPC0gcm93bmFtZXMoTDVfdnNfUEJNQykKCgojIFJlYXJyYW5naW5nIHRoZSBjb2x1bW5zIGZvciBiZXR0ZXIgcmVhZGFiaWxpdHkgKG9wdGlvbmFsKQpMNV92c19QQk1DICA8LSBMNV92c19QQk1DWywgCiAgICBjKCJnZW5lIiwgInBfdmFsIiwgImF2Z19sb2cyRkMiLCAicGN0LjEiLCAicGN0LjIiLCAicF92YWxfYWRqIildCgoKCiMgQ3JlYXRlIHZvbGNhbm8gcGxvdCBmb3IgUDEgdnMgUEJNQy1UY2VsbHMKdm9sY2Fub19MNV92c19QQk1DIDwtIEVuaGFuY2VkVm9sY2FubyhMNV92c19QQk1DLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiID0gcm93bmFtZXMoTDVfdnNfUEJNQyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHggPSAnYXZnX2xvZzJGQycsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkgPSAncF92YWxfYWRqJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGUgPSAnTDVfdnNfUEJNQycsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhsYWIgPSBicXVvdGUofkxvZ1syXX4gJ2ZvbGQgY2hhbmdlJyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBDdXRvZmYgPSAxZS0xMDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZDY3V0b2ZmID0gMS41LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9pbnRTaXplID0gMy4wLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJTaXplID0gNS4wLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib3hlZExhYmVscyA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbEFscGhhID0gMC41LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZWdlbmRQb3NpdGlvbiA9ICdyaWdodCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlZ2VuZExhYlNpemUgPSAxMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVnZW5kSWNvblNpemUgPSA0LjAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRyYXdDb25uZWN0b3JzID0gVFJVRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGhDb25uZWN0b3JzID0gMC41LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xDb25uZWN0b3JzID0gJ2dyZXk1MCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFycm93aGVhZHMgPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF4Lm92ZXJsYXBzID0gMzApCnByaW50KHZvbGNhbm9fTDVfdnNfUEJNQykKcG5nKCJ2b2xjYW5vX0w1X3ZzX1BCTUMucG5nIiwgd2lkdGggPSAxMiwgaGVpZ2h0ID0gMTAsIHVuaXRzID0gImluIiwgcmVzID0gMzAwKQpwcmludCh2b2xjYW5vX0w1X3ZzX1BCTUMpCmRldi5vZmYoKQoKCnZvbGNhbm8yX0w1X3ZzX1BCTUMgPC0gRW5oYW5jZWRWb2xjYW5vKEw1X3ZzX1BCTUMsIAogICAgICAgICAgICAgICAgbGFiID0gcm93bmFtZXMoTDVfdnNfUEJNQyksCiAgICAgICAgICAgICAgICB4ID0gImF2Z19sb2cyRkMiLCAKICAgICAgICAgICAgICAgIHkgPSAicF92YWxfYWRqIiwKICAgICAgICAgICAgICAgIHNlbGVjdExhYiA9IGMoJ0VQQ0FNJywgJ0tJUjNETDInLCAnRk9YTTEnLCAnVFdJU1QxJywgJ1RORlNGOScsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnQ0Q4MCcsICdGT1MnLCdQVFBONicsJ05DUjEnLCdOQ1IyJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1BDTEFGJywgJ0tJUjNETDEnLCAnSUw0JywnSVRHQTYnLCdDQ0w1JywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0lMN1InLCAnVENGNycsICdQVFRHMScsICdSUk0yJywgJ01LSTY3JywgJ0NENzAnLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0lMMlJBJywgJ0ZDR1IzQScsICdHTkxZJywgJ0ZPWFAzJywgJ1NFTEwnLCAgJ0xFRjEnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnQ0NMMTcnLCAnVEhZMScsICdDRDI3JywgJ0NEMjgnLCAnQ0Q3JywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBLZXkgU8OpemFyeSBzeW5kcm9tZSBnZW5lcwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnUFJGMScsICdHWk1CJywgJ05DUjEnLCAnTkZBVEMzJywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdLTFJLMScsICdMQ0snLCAnS0xSQzEnLCAnS0xSQzInLCAnVE5GJywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdLSVIzREwxJywnS0lSM0RMMycsJ0tJUjNETDQnLCAnSUZORycsICdJRk5HUjEnLCAnQ0QyNDQnLCAnRkFTTEcnKSwKICAgICAgICAgICAgICAgIHRpdGxlID0gIkw1X3ZzX1BCTUMiLAogICAgICAgICAgICAgICAgc3VidGl0bGUgPSAiU8OpemFyeSBTeW5kcm9tZSBDZWxsIExpbmVzIiwKICAgICAgICAgICAgICAgIHhsYWIgPSBicXVvdGUofkxvZ1syXX4gJ2ZvbGQgY2hhbmdlJyksCiAgICAgICAgICAgICAgICBwQ3V0b2ZmID0gMC4wNSwKICAgICAgICAgICAgICAgIEZDY3V0b2ZmID0gMS41LCAKICAgICAgICAgICAgICAgIHBvaW50U2l6ZSA9IDMuMCwKICAgICAgICAgICAgICAgIGxhYlNpemUgPSA0LjAsCiAgICAgICAgICAgICAgICBsYWJGYWNlID0gJ2JvbGQnLAogICAgICAgICAgICAgICAgYm94ZWRMYWJlbHMgPSBUUlVFLAogICAgICAgICAgICAgICAgY29sQWxwaGEgPSAwLjUsCiAgICAgICAgICAgICAgICBsZWdlbmRQb3NpdGlvbiA9ICdyaWdodCcsCiAgICAgICAgICAgICAgICBsZWdlbmRMYWJTaXplID0gMTAsCiAgICAgICAgICAgICAgICBsZWdlbmRJY29uU2l6ZSA9IDQuMCwKICAgICAgICAgICAgICAgIGRyYXdDb25uZWN0b3JzID0gVFJVRSwKICAgICAgICAgICAgICAgIHdpZHRoQ29ubmVjdG9ycyA9IDAuNSwKICAgICAgICAgICAgICAgIGNvbENvbm5lY3RvcnMgPSAnZ3JleTUwJywKICAgICAgICAgICAgICAgIGFycm93aGVhZHMgPSBGQUxTRSwKICAgICAgICAgICAgICAgIG1heC5vdmVybGFwcyA9IDMwKQpwcmludCh2b2xjYW5vMl9MNV92c19QQk1DKQpwbmcoInZvbGNhbm8yX0w1X3ZzX1BCTUMucG5nIiwgd2lkdGggPSAxMiwgaGVpZ2h0ID0gMTAsIHVuaXRzID0gImluIiwgcmVzID0gMzAwKQpwcmludCh2b2xjYW5vMl9MNV92c19QQk1DKQpkZXYub2ZmKCkKCiMgRGlzcGxheSB0b3AgZGlmZmVyZW50aWFsbHkgZXhwcmVzc2VkIGdlbmVzIGZvciBlYWNoIGNvbXBhcmlzb24KaGVhZChMNV92c19QQk1DKQoKCmBgYAoKCgojIDguIEw2X3ZzX1BCTUMKYGBge3IgZmluZG1hcmtlcnM2LCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD0xMn0KCkRlZmF1bHRBc3NheShBbGxfc2FtcGxlc19NZXJnZWQpIDwtICJTQ1QiCklkZW50cyhBbGxfc2FtcGxlc19NZXJnZWQpIDwtICJjZWxsX2xpbmUiCgojIFAxIHZzIFBCTUMtVGNlbGxzCkw2X3ZzX1BCTUMgPC0gRmluZE1hcmtlcnMoQWxsX3NhbXBsZXNfTWVyZ2VkLCAKICAgICAgICAgICAgICAgICAgICAgICAgaWRlbnQuMSA9ICJMNiIsICAKICAgICAgICAgICAgICAgICAgICAgICAgaWRlbnQuMiA9IGMoIlBCTUMiLCJQQk1DXzEweCIpLCAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICBhc3NheSA9ICJTQ1QiKQoKd3JpdGUuY3N2KEw2X3ZzX1BCTUMsICJOZXdfY29tcGFyaXNvbl9MNl92c19QQk1DLmNzdiIpCgojIENvbnZlcnQgdG8gZGF0YSBmcmFtZSBhbmQgYWRkIGdlbmUgbmFtZXMgYXMgYSBuZXcgY29sdW1uCkw2X3ZzX1BCTUMgPC0gYXMuZGF0YS5mcmFtZShMNl92c19QQk1DKQpMNl92c19QQk1DJGdlbmUgPC0gcm93bmFtZXMoTDZfdnNfUEJNQykKCgojIFJlYXJyYW5naW5nIHRoZSBjb2x1bW5zIGZvciBiZXR0ZXIgcmVhZGFiaWxpdHkgKG9wdGlvbmFsKQpMNl92c19QQk1DICA8LSBMNl92c19QQk1DWywgCiAgICBjKCJnZW5lIiwgInBfdmFsIiwgImF2Z19sb2cyRkMiLCAicGN0LjEiLCAicGN0LjIiLCAicF92YWxfYWRqIildCgoKCiMgQ3JlYXRlIHZvbGNhbm8gcGxvdCBmb3IgUDEgdnMgUEJNQy1UY2VsbHMKdm9sY2Fub19MNl92c19QQk1DIDwtIEVuaGFuY2VkVm9sY2FubyhMNl92c19QQk1DLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiID0gcm93bmFtZXMoTDZfdnNfUEJNQyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHggPSAnYXZnX2xvZzJGQycsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkgPSAncF92YWxfYWRqJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGUgPSAnTDZfdnNfUEJNQycsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhsYWIgPSBicXVvdGUofkxvZ1syXX4gJ2ZvbGQgY2hhbmdlJyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBDdXRvZmYgPSAxZS0xMDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZDY3V0b2ZmID0gMS41LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9pbnRTaXplID0gMy4wLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJTaXplID0gNS4wLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib3hlZExhYmVscyA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbEFscGhhID0gMC41LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZWdlbmRQb3NpdGlvbiA9ICdyaWdodCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlZ2VuZExhYlNpemUgPSAxMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVnZW5kSWNvblNpemUgPSA0LjAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRyYXdDb25uZWN0b3JzID0gVFJVRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGhDb25uZWN0b3JzID0gMC41LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xDb25uZWN0b3JzID0gJ2dyZXk1MCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFycm93aGVhZHMgPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF4Lm92ZXJsYXBzID0gMzApCnByaW50KHZvbGNhbm9fTDZfdnNfUEJNQykKcG5nKCJ2b2xjYW5vX0w2X3ZzX1BCTUMucG5nIiwgd2lkdGggPSAxMiwgaGVpZ2h0ID0gMTAsIHVuaXRzID0gImluIiwgcmVzID0gMzAwKQpwcmludCh2b2xjYW5vX0w2X3ZzX1BCTUMpCmRldi5vZmYoKQoKCnZvbGNhbm8yX0w2X3ZzX1BCTUMgPC0gRW5oYW5jZWRWb2xjYW5vKEw2X3ZzX1BCTUMsIAogICAgICAgICAgICAgICAgbGFiID0gcm93bmFtZXMoTDZfdnNfUEJNQyksCiAgICAgICAgICAgICAgICB4ID0gImF2Z19sb2cyRkMiLCAKICAgICAgICAgICAgICAgIHkgPSAicF92YWxfYWRqIiwKICAgICAgICAgICAgICAgIHNlbGVjdExhYiA9IGMoJ0VQQ0FNJywgJ0tJUjNETDInLCAnRk9YTTEnLCAnVFdJU1QxJywgJ1RORlNGOScsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnQ0Q4MCcsICdGT1MnLCdQVFBONicsJ05DUjEnLCdOQ1IyJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1BDTEFGJywgJ0tJUjNETDEnLCAnSUw0JywnSVRHQTYnLCdDQ0w1JywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0lMN1InLCAnVENGNycsICdQVFRHMScsICdSUk0yJywgJ01LSTY3JywgJ0NENzAnLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0lMMlJBJywgJ0ZDR1IzQScsICdHTkxZJywgJ0ZPWFAzJywgJ1NFTEwnLCAgJ0xFRjEnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnQ0NMMTcnLCAnVEhZMScsICdDRDI3JywgJ0NEMjgnLCAnQ0Q3JywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBLZXkgU8OpemFyeSBzeW5kcm9tZSBnZW5lcwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnUFJGMScsICdHWk1CJywgJ05DUjEnLCAnTkZBVEMzJywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdLTFJLMScsICdMQ0snLCAnS0xSQzEnLCAnS0xSQzInLCAnVE5GJywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdLSVIzREwxJywnS0lSM0RMMycsJ0tJUjNETDQnLCAnSUZORycsICdJRk5HUjEnLCAnQ0QyNDQnLCAnRkFTTEcnKSwKICAgICAgICAgICAgICAgIHRpdGxlID0gIkw2X3ZzX1BCTUMiLAogICAgICAgICAgICAgICAgc3VidGl0bGUgPSAiU8OpemFyeSBTeW5kcm9tZSBDZWxsIExpbmVzIiwKICAgICAgICAgICAgICAgIHhsYWIgPSBicXVvdGUofkxvZ1syXX4gJ2ZvbGQgY2hhbmdlJyksCiAgICAgICAgICAgICAgICBwQ3V0b2ZmID0gMC4wNSwKICAgICAgICAgICAgICAgIEZDY3V0b2ZmID0gMS41LCAKICAgICAgICAgICAgICAgIHBvaW50U2l6ZSA9IDMuMCwKICAgICAgICAgICAgICAgIGxhYlNpemUgPSA0LjAsCiAgICAgICAgICAgICAgICBsYWJGYWNlID0gJ2JvbGQnLAogICAgICAgICAgICAgICAgYm94ZWRMYWJlbHMgPSBUUlVFLAogICAgICAgICAgICAgICAgY29sQWxwaGEgPSAwLjUsCiAgICAgICAgICAgICAgICBsZWdlbmRQb3NpdGlvbiA9ICdyaWdodCcsCiAgICAgICAgICAgICAgICBsZWdlbmRMYWJTaXplID0gMTAsCiAgICAgICAgICAgICAgICBsZWdlbmRJY29uU2l6ZSA9IDQuMCwKICAgICAgICAgICAgICAgIGRyYXdDb25uZWN0b3JzID0gVFJVRSwKICAgICAgICAgICAgICAgIHdpZHRoQ29ubmVjdG9ycyA9IDAuNSwKICAgICAgICAgICAgICAgIGNvbENvbm5lY3RvcnMgPSAnZ3JleTUwJywKICAgICAgICAgICAgICAgIGFycm93aGVhZHMgPSBGQUxTRSwKICAgICAgICAgICAgICAgIG1heC5vdmVybGFwcyA9IDMwKQpwcmludCh2b2xjYW5vMl9MNl92c19QQk1DKQpwbmcoInZvbGNhbm8yX0w2X3ZzX1BCTUMucG5nIiwgd2lkdGggPSAxMiwgaGVpZ2h0ID0gMTAsIHVuaXRzID0gImluIiwgcmVzID0gMzAwKQpwcmludCh2b2xjYW5vMl9MNl92c19QQk1DKQpkZXYub2ZmKCkKCiMgRGlzcGxheSB0b3AgZGlmZmVyZW50aWFsbHkgZXhwcmVzc2VkIGdlbmVzIGZvciBlYWNoIGNvbXBhcmlzb24KaGVhZChMNl92c19QQk1DKQoKCmBgYAoKCiMgOS4gTDdfdnNfUEJNQwpgYGB7ciBmaW5kbWFya2VyczcsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTEyfQoKRGVmYXVsdEFzc2F5KEFsbF9zYW1wbGVzX01lcmdlZCkgPC0gIlNDVCIKSWRlbnRzKEFsbF9zYW1wbGVzX01lcmdlZCkgPC0gImNlbGxfbGluZSIKCiMgUDEgdnMgUEJNQy1UY2VsbHMKTDdfdnNfUEJNQyA8LSBGaW5kTWFya2VycyhBbGxfc2FtcGxlc19NZXJnZWQsIAogICAgICAgICAgICAgICAgICAgICAgICBpZGVudC4xID0gIkw3IiwgIAogICAgICAgICAgICAgICAgICAgICAgICBpZGVudC4yID0gYygiUEJNQyIsIlBCTUNfMTB4IiksICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgIGFzc2F5ID0gIlNDVCIpCgp3cml0ZS5jc3YoTDdfdnNfUEJNQywgIk5ld19jb21wYXJpc29uX0w3X3ZzX1BCTUMuY3N2IikKCiMgQ29udmVydCB0byBkYXRhIGZyYW1lIGFuZCBhZGQgZ2VuZSBuYW1lcyBhcyBhIG5ldyBjb2x1bW4KTDdfdnNfUEJNQyA8LSBhcy5kYXRhLmZyYW1lKEw3X3ZzX1BCTUMpCkw3X3ZzX1BCTUMkZ2VuZSA8LSByb3duYW1lcyhMN192c19QQk1DKQoKCiMgUmVhcnJhbmdpbmcgdGhlIGNvbHVtbnMgZm9yIGJldHRlciByZWFkYWJpbGl0eSAob3B0aW9uYWwpCkw3X3ZzX1BCTUMgIDwtIEw3X3ZzX1BCTUNbLCAKICAgIGMoImdlbmUiLCAicF92YWwiLCAiYXZnX2xvZzJGQyIsICJwY3QuMSIsICJwY3QuMiIsICJwX3ZhbF9hZGoiKV0KCgoKIyBDcmVhdGUgdm9sY2FubyBwbG90IGZvciBQMSB2cyBQQk1DLVRjZWxscwp2b2xjYW5vX0w3X3ZzX1BCTUMgPC0gRW5oYW5jZWRWb2xjYW5vKEw3X3ZzX1BCTUMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWIgPSByb3duYW1lcyhMN192c19QQk1DKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeCA9ICdhdmdfbG9nMkZDJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeSA9ICdwX3ZhbF9hZGonLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aXRsZSA9ICdMN192c19QQk1DJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeGxhYiA9IGJxdW90ZSh+TG9nWzJdfiAnZm9sZCBjaGFuZ2UnKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcEN1dG9mZiA9IDFlLTEwMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRkNjdXRvZmYgPSAxLjUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb2ludFNpemUgPSAzLjAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYlNpemUgPSA1LjAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJveGVkTGFiZWxzID0gVFJVRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sQWxwaGEgPSAwLjUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlZ2VuZFBvc2l0aW9uID0gJ3JpZ2h0JywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVnZW5kTGFiU2l6ZSA9IDEwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZWdlbmRJY29uU2l6ZSA9IDQuMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHJhd0Nvbm5lY3RvcnMgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWR0aENvbm5lY3RvcnMgPSAwLjUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbENvbm5lY3RvcnMgPSAnZ3JleTUwJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJyb3doZWFkcyA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXgub3ZlcmxhcHMgPSAzMCkKcHJpbnQodm9sY2Fub19MN192c19QQk1DKQpwbmcoInZvbGNhbm9fTDdfdnNfUEJNQy5wbmciLCB3aWR0aCA9IDEyLCBoZWlnaHQgPSAxMCwgdW5pdHMgPSAiaW4iLCByZXMgPSAzMDApCnByaW50KHZvbGNhbm9fTDdfdnNfUEJNQykKZGV2Lm9mZigpCgoKdm9sY2FubzJfTDdfdnNfUEJNQyA8LSBFbmhhbmNlZFZvbGNhbm8oTDdfdnNfUEJNQywgCiAgICAgICAgICAgICAgICBsYWIgPSByb3duYW1lcyhMN192c19QQk1DKSwKICAgICAgICAgICAgICAgIHggPSAiYXZnX2xvZzJGQyIsIAogICAgICAgICAgICAgICAgeSA9ICJwX3ZhbF9hZGoiLAogICAgICAgICAgICAgICAgc2VsZWN0TGFiID0gYygnRVBDQU0nLCAnS0lSM0RMMicsICdGT1hNMScsICdUV0lTVDEnLCAnVE5GU0Y5JywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdDRDgwJywgJ0ZPUycsJ1BUUE42JywnTkNSMScsJ05DUjInLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnUENMQUYnLCAnS0lSM0RMMScsICdJTDQnLCdJVEdBNicsJ0NDTDUnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnSUw3UicsICdUQ0Y3JywgJ1BUVEcxJywgJ1JSTTInLCAnTUtJNjcnLCAnQ0Q3MCcsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnSUwyUkEnLCAnRkNHUjNBJywgJ0dOTFknLCAnRk9YUDMnLCAnU0VMTCcsICAnTEVGMScsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdDQ0wxNycsICdUSFkxJywgJ0NEMjcnLCAnQ0QyOCcsICdDRDcnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIEtleSBTw6l6YXJ5IHN5bmRyb21lIGdlbmVzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdQUkYxJywgJ0daTUInLCAnTkNSMScsICdORkFUQzMnLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0tMUksxJywgJ0xDSycsICdLTFJDMScsICdLTFJDMicsICdUTkYnLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0tJUjNETDEnLCdLSVIzREwzJywnS0lSM0RMNCcsICdJRk5HJywgJ0lGTkdSMScsICdDRDI0NCcsICdGQVNMRycpLAogICAgICAgICAgICAgICAgdGl0bGUgPSAiTDdfdnNfUEJNQyIsCiAgICAgICAgICAgICAgICBzdWJ0aXRsZSA9ICJTw6l6YXJ5IFN5bmRyb21lIENlbGwgTGluZXMiLAogICAgICAgICAgICAgICAgeGxhYiA9IGJxdW90ZSh+TG9nWzJdfiAnZm9sZCBjaGFuZ2UnKSwKICAgICAgICAgICAgICAgIHBDdXRvZmYgPSAwLjA1LAogICAgICAgICAgICAgICAgRkNjdXRvZmYgPSAxLjUsIAogICAgICAgICAgICAgICAgcG9pbnRTaXplID0gMy4wLAogICAgICAgICAgICAgICAgbGFiU2l6ZSA9IDQuMCwKICAgICAgICAgICAgICAgIGxhYkZhY2UgPSAnYm9sZCcsCiAgICAgICAgICAgICAgICBib3hlZExhYmVscyA9IFRSVUUsCiAgICAgICAgICAgICAgICBjb2xBbHBoYSA9IDAuNSwKICAgICAgICAgICAgICAgIGxlZ2VuZFBvc2l0aW9uID0gJ3JpZ2h0JywKICAgICAgICAgICAgICAgIGxlZ2VuZExhYlNpemUgPSAxMCwKICAgICAgICAgICAgICAgIGxlZ2VuZEljb25TaXplID0gNC4wLAogICAgICAgICAgICAgICAgZHJhd0Nvbm5lY3RvcnMgPSBUUlVFLAogICAgICAgICAgICAgICAgd2lkdGhDb25uZWN0b3JzID0gMC41LAogICAgICAgICAgICAgICAgY29sQ29ubmVjdG9ycyA9ICdncmV5NTAnLAogICAgICAgICAgICAgICAgYXJyb3doZWFkcyA9IEZBTFNFLAogICAgICAgICAgICAgICAgbWF4Lm92ZXJsYXBzID0gMzApCnByaW50KHZvbGNhbm8yX0w3X3ZzX1BCTUMpCnBuZygidm9sY2FubzJfTDdfdnNfUEJNQy5wbmciLCB3aWR0aCA9IDEyLCBoZWlnaHQgPSAxMCwgdW5pdHMgPSAiaW4iLCByZXMgPSAzMDApCnByaW50KHZvbGNhbm8yX0w3X3ZzX1BCTUMpCmRldi5vZmYoKQoKIyBEaXNwbGF5IHRvcCBkaWZmZXJlbnRpYWxseSBleHByZXNzZWQgZ2VuZXMgZm9yIGVhY2ggY29tcGFyaXNvbgpoZWFkKEw3X3ZzX1BCTUMpCgoKYGBgCgoKCgoKCgoKCiMgNi4gRW5yaWNobWVudCBBbmFseXNpcwpgYGB7ciBlbnJpY2htZW50MiwgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9MTJ9CmxpYnJhcnkoY2x1c3RlclByb2ZpbGVyKQpsaWJyYXJ5KG9yZy5Icy5lZy5kYikKbGlicmFyeShlbnJpY2hwbG90KQoKcGVyZm9ybV9nb19lbnJpY2htZW50IDwtIGZ1bmN0aW9uKGdlbmVfbGlzdCwgZ2VuZV91bml2ZXJzZSwgdGl0bGUpIHsKICBlZ28gPC0gZW5yaWNoR08oZ2VuZSA9IGdlbmVfbGlzdCwKICAgICAgICAgICAgICAgICAgdW5pdmVyc2UgPSBnZW5lX3VuaXZlcnNlLAogICAgICAgICAgICAgICAgICBPcmdEYiA9IG9yZy5Icy5lZy5kYiwKICAgICAgICAgICAgICAgICAga2V5VHlwZSA9ICJTWU1CT0wiLAogICAgICAgICAgICAgICAgICBvbnQgPSAiQlAiLAogICAgICAgICAgICAgICAgICBwQWRqdXN0TWV0aG9kID0gIkJIIiwKICAgICAgICAgICAgICAgICAgcXZhbHVlQ3V0b2ZmID0gMC4wNSwKICAgICAgICAgICAgICAgICAgcmVhZGFibGUgPSBUUlVFKQogIAogIGlmIChucm93KGVnb0ByZXN1bHQpID09IDApIHsKICAgIHdhcm5pbmcocGFzdGUoIk5vIGVucmljaGVkIEdPIHRlcm1zIGZvdW5kIGZvciIsIHRpdGxlKSkKICAgIHJldHVybihOVUxMKQogIH0KICAKICBwIDwtIGRvdHBsb3QoZWdvLCBzaG93Q2F0ZWdvcnkgPSAxMCwgdGl0bGUgPSBwYXN0ZSgiR08gLSIsIHRpdGxlKSkgKwogICAgdGhlbWUoYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgpKQogIAogIHByaW50KHApCiAgcG5nKHBhc3RlMCgiR09fZW5yaWNobWVudF8iLCBnc3ViKCIgIiwgIl8iLCB0aXRsZSksICIucG5nIiksIHdpZHRoID0gMTIsIGhlaWdodCA9IDgsIHVuaXRzID0gImluIiwgcmVzID0gMzAwKQogIHByaW50KHApCiAgZGV2Lm9mZigpCiAgCiAgcmV0dXJuKGVnbykKfQoKcGVyZm9ybV9rZWdnX2VucmljaG1lbnQgPC0gZnVuY3Rpb24oZ2VuZV9saXN0LCBnZW5lX3VuaXZlcnNlLCB0aXRsZSkgewogICMgQ29udmVydCBnZW5lIHN5bWJvbHMgdG8gRW50cmV6IElEcwogIGVudHJlel9pZHMgPC0gYml0cihnZW5lX2xpc3QsIGZyb21UeXBlID0gIlNZTUJPTCIsIHRvVHlwZSA9ICJFTlRSRVpJRCIsIE9yZ0RiID0gb3JnLkhzLmVnLmRiKQogIHVuaXZlcnNlX2VudHJleiA8LSBiaXRyKGdlbmVfdW5pdmVyc2UsIGZyb21UeXBlID0gIlNZTUJPTCIsIHRvVHlwZSA9ICJFTlRSRVpJRCIsIE9yZ0RiID0gb3JnLkhzLmVnLmRiKQogIAogIHByaW50KHBhc3RlKCJOdW1iZXIgb2YgaW5wdXQgZ2VuZXM6IiwgbGVuZ3RoKGdlbmVfbGlzdCkpKQogIHByaW50KHBhc3RlKCJOdW1iZXIgb2YgaW5wdXQgZ2VuZXMgbWFwcGVkIHRvIEVudHJleiBJRHM6IiwgbnJvdyhlbnRyZXpfaWRzKSkpCiAgcHJpbnQocGFzdGUoIk51bWJlciBvZiB1bml2ZXJzZSBnZW5lczoiLCBsZW5ndGgoZ2VuZV91bml2ZXJzZSkpKQogIHByaW50KHBhc3RlKCJOdW1iZXIgb2YgdW5pdmVyc2UgZ2VuZXMgbWFwcGVkIHRvIEVudHJleiBJRHM6IiwgbnJvdyh1bml2ZXJzZV9lbnRyZXopKSkKICAKICBpZihucm93KGVudHJlel9pZHMpID09IDApIHsKICAgIHdhcm5pbmcocGFzdGUoIk5vIGdlbmVzIGNvdWxkIGJlIG1hcHBlZCBmb3IiLCB0aXRsZSkpCiAgICByZXR1cm4oTlVMTCkKICB9CiAgCiAgdHJ5Q2F0Y2goewogICAgZWtlZ2cgPC0gZW5yaWNoS0VHRyhnZW5lID0gZW50cmV6X2lkcyRFTlRSRVpJRCwKICAgICAgICAgICAgICAgICAgICAgICAgdW5pdmVyc2UgPSB1bml2ZXJzZV9lbnRyZXokRU5UUkVaSUQsCiAgICAgICAgICAgICAgICAgICAgICAgIG9yZ2FuaXNtID0gJ2hzYScsCiAgICAgICAgICAgICAgICAgICAgICAgIGtleVR5cGUgPSAia2VnZyIsCiAgICAgICAgICAgICAgICAgICAgICAgIHB2YWx1ZUN1dG9mZiA9IDAuMDUsCiAgICAgICAgICAgICAgICAgICAgICAgIHBBZGp1c3RNZXRob2QgPSAiQkgiKQogICAgCiAgICBpZihucm93KGVrZWdnQHJlc3VsdCkgPT0gMCkgewogICAgICB3YXJuaW5nKHBhc3RlKCJObyBlbnJpY2hlZCBLRUdHIHBhdGh3YXlzIGZvdW5kIGZvciIsIHRpdGxlKSkKICAgICAgcmV0dXJuKE5VTEwpCiAgICB9CiAgICAKICAgIHAgPC0gZG90cGxvdChla2VnZywgc2hvd0NhdGVnb3J5ID0gMTAsIHRpdGxlID0gcGFzdGUoIktFR0cgLSIsIHRpdGxlKSkgKwogICAgICB0aGVtZShheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gOCkpCiAgICAKICAgIHByaW50KHApCiAgICBwbmcocGFzdGUwKCJLRUdHX2VucmljaG1lbnRfIiwgZ3N1YigiICIsICJfIiwgdGl0bGUpLCAiLnBuZyIpLCB3aWR0aCA9IDEyLCBoZWlnaHQgPSA4LCB1bml0cyA9ICJpbiIsIHJlcyA9IDMwMCkKICAgIHByaW50KHApCiAgICBkZXYub2ZmKCkKICAgIAogICAgcmV0dXJuKGVrZWdnKQogIH0sIGVycm9yID0gZnVuY3Rpb24oZSkgewogICAgd2FybmluZyhwYXN0ZSgiRXJyb3IgaW4gS0VHRyBlbnJpY2htZW50IGZvciIsIHRpdGxlLCAiOiIsIGUkbWVzc2FnZSkpCiAgICByZXR1cm4oTlVMTCkKICB9KQp9CgpnZW5lX3VuaXZlcnNlIDwtIHJvd25hbWVzKEFsbF9zYW1wbGVzX01lcmdlZCkKCiMgTDFfdnNfUEJNQyBjb21wYXJpc29uCnVwcmVndWxhdGVkX2dlbmVzX0wxX3ZzX1BCTUMgPC0gcm93bmFtZXMoTDFfdnNfUEJNQ1tMMV92c19QQk1DJGF2Z19sb2cyRkMgPiAyLjUgJiBMMV92c19QQk1DJHBfdmFsX2FkaiA8IDAuMDUsIF0pCmRvd25yZWd1bGF0ZWRfZ2VuZXNfTDFfdnNfUEJNQyA8LSByb3duYW1lcyhMMV92c19QQk1DW0wxX3ZzX1BCTUMkYXZnX2xvZzJGQyA8IC0yLjUgJiBMMV92c19QQk1DJHBfdmFsX2FkaiA8IDAuMDUsIF0pCgpnb191cF9MMV92c19QQk1DIDwtIHBlcmZvcm1fZ29fZW5yaWNobWVudCh1cHJlZ3VsYXRlZF9nZW5lc19MMV92c19QQk1DLCBnZW5lX3VuaXZlcnNlLCAiVXByZWd1bGF0ZWQgR2VuZXMgaW4gTDFfdnNfUEJNQyIpCmdvX2Rvd25fTDFfdnNfUEJNQyA8LSBwZXJmb3JtX2dvX2VucmljaG1lbnQoZG93bnJlZ3VsYXRlZF9nZW5lc19MMV92c19QQk1DLCBnZW5lX3VuaXZlcnNlLCAiRG93bnJlZ3VsYXRlZCBHZW5lcyBpbiBMMV92c19QQk1DIikKa2VnZ191cF9MMV92c19QQk1DIDwtIHBlcmZvcm1fa2VnZ19lbnJpY2htZW50KHVwcmVndWxhdGVkX2dlbmVzX0wxX3ZzX1BCTUMsIGdlbmVfdW5pdmVyc2UsICJVcHJlZ3VsYXRlZCBHZW5lcyBpbiBMMV92c19QQk1DIikKa2VnZ19kb3duX0wxX3ZzX1BCTUMgPC0gcGVyZm9ybV9rZWdnX2VucmljaG1lbnQoZG93bnJlZ3VsYXRlZF9nZW5lc19MMV92c19QQk1DLCBnZW5lX3VuaXZlcnNlLCAiRG93bnJlZ3VsYXRlZCBHZW5lcyBpbiBMMV92c19QQk1DIikKCiMgTDJfdnNfUEJNQyBjb21wYXJpc29uCnVwcmVndWxhdGVkX2dlbmVzX0wyX3ZzX1BCTUMgPC0gcm93bmFtZXMoTDJfdnNfUEJNQ1tMMl92c19QQk1DJGF2Z19sb2cyRkMgPiAyLjUgJiBMMl92c19QQk1DJHBfdmFsX2FkaiA8IDAuMDUsIF0pCmRvd25yZWd1bGF0ZWRfZ2VuZXNfTDJfdnNfUEJNQyA8LSByb3duYW1lcyhMMl92c19QQk1DW0wyX3ZzX1BCTUMkYXZnX2xvZzJGQyA8IC0yLjUgJiBMMl92c19QQk1DJHBfdmFsX2FkaiA8IDAuMDUsIF0pCgpnb191cF9MMl92c19QQk1DIDwtIHBlcmZvcm1fZ29fZW5yaWNobWVudCh1cHJlZ3VsYXRlZF9nZW5lc19MMl92c19QQk1DLCBnZW5lX3VuaXZlcnNlLCAiVXByZWd1bGF0ZWQgR2VuZXMgaW4gTDJfdnNfUEJNQyIpCmdvX2Rvd25fTDJfdnNfUEJNQyA8LSBwZXJmb3JtX2dvX2VucmljaG1lbnQoZG93bnJlZ3VsYXRlZF9nZW5lc19MMl92c19QQk1DLCBnZW5lX3VuaXZlcnNlLCAiRG93bnJlZ3VsYXRlZCBHZW5lcyBpbiBMMl92c19QQk1DIikKa2VnZ191cF9MMl92c19QQk1DIDwtIHBlcmZvcm1fa2VnZ19lbnJpY2htZW50KHVwcmVndWxhdGVkX2dlbmVzX0wyX3ZzX1BCTUMsIGdlbmVfdW5pdmVyc2UsICJVcHJlZ3VsYXRlZCBHZW5lcyBpbiBMMl92c19QQk1DIikKa2VnZ19kb3duX0wyX3ZzX1BCTUMgPC0gcGVyZm9ybV9rZWdnX2VucmljaG1lbnQoZG93bnJlZ3VsYXRlZF9nZW5lc19MMl92c19QQk1DLCBnZW5lX3VuaXZlcnNlLCAiRG93bnJlZ3VsYXRlZCBHZW5lcyBpbiBMMl92c19QQk1DIikKCiMgTDNfdnNfUEJNQyBjb21wYXJpc29uCnVwcmVndWxhdGVkX2dlbmVzX0wzX3ZzX1BCTUMgPC0gcm93bmFtZXMoTDNfdnNfUEJNQ1tMM192c19QQk1DJGF2Z19sb2cyRkMgPiAyLjUgJiBMM192c19QQk1DJHBfdmFsX2FkaiA8IDAuMDUsIF0pCmRvd25yZWd1bGF0ZWRfZ2VuZXNfTDNfdnNfUEJNQyA8LSByb3duYW1lcyhMM192c19QQk1DW0wzX3ZzX1BCTUMkYXZnX2xvZzJGQyA8IC0yLjUgJiBMM192c19QQk1DJHBfdmFsX2FkaiA8IDAuMDUsIF0pCgpnb191cF9MM192c19QQk1DIDwtIHBlcmZvcm1fZ29fZW5yaWNobWVudCh1cHJlZ3VsYXRlZF9nZW5lc19MM192c19QQk1DLCBnZW5lX3VuaXZlcnNlLCAiVXByZWd1bGF0ZWQgR2VuZXMgaW4gTDNfdnNfUEJNQyIpCmdvX2Rvd25fTDNfdnNfUEJNQyA8LSBwZXJmb3JtX2dvX2VucmljaG1lbnQoZG93bnJlZ3VsYXRlZF9nZW5lc19MM192c19QQk1DLCBnZW5lX3VuaXZlcnNlLCAiRG93bnJlZ3VsYXRlZCBHZW5lcyBpbiBMM192c19QQk1DIikKa2VnZ191cF9MM192c19QQk1DIDwtIHBlcmZvcm1fa2VnZ19lbnJpY2htZW50KHVwcmVndWxhdGVkX2dlbmVzX0wzX3ZzX1BCTUMsIGdlbmVfdW5pdmVyc2UsICJVcHJlZ3VsYXRlZCBHZW5lcyBpbiBMM192c19QQk1DIikKa2VnZ19kb3duX0wzX3ZzX1BCTUMgPC0gcGVyZm9ybV9rZWdnX2VucmljaG1lbnQoZG93bnJlZ3VsYXRlZF9nZW5lc19MM192c19QQk1DLCBnZW5lX3VuaXZlcnNlLCAiRG93bnJlZ3VsYXRlZCBHZW5lcyBpbiBMM192c19QQk1DIikKCiMgTDRfdnNfUEJNQyBjb21wYXJpc29uCnVwcmVndWxhdGVkX2dlbmVzX0w0X3ZzX1BCTUMgPC0gcm93bmFtZXMoTDRfdnNfUEJNQ1tMNF92c19QQk1DJGF2Z19sb2cyRkMgPiAyLjUgJiBMNF92c19QQk1DJHBfdmFsX2FkaiA8IDAuMDUsIF0pCmRvd25yZWd1bGF0ZWRfZ2VuZXNfTDRfdnNfUEJNQyA8LSByb3duYW1lcyhMNF92c19QQk1DW0w0X3ZzX1BCTUMkYXZnX2xvZzJGQyA8IC0yLjUgJiBMNF92c19QQk1DJHBfdmFsX2FkaiA8IDAuMDUsIF0pCgpnb191cF9MNF92c19QQk1DIDwtIHBlcmZvcm1fZ29fZW5yaWNobWVudCh1cHJlZ3VsYXRlZF9nZW5lc19MNF92c19QQk1DLCBnZW5lX3VuaXZlcnNlLCAiVXByZWd1bGF0ZWQgR2VuZXMgaW4gTDRfdnNfUEJNQyIpCmdvX2Rvd25fTDRfdnNfUEJNQyA8LSBwZXJmb3JtX2dvX2VucmljaG1lbnQoZG93bnJlZ3VsYXRlZF9nZW5lc19MNF92c19QQk1DLCBnZW5lX3VuaXZlcnNlLCAiRG93bnJlZ3VsYXRlZCBHZW5lcyBpbiBMNF92c19QQk1DIikKa2VnZ191cF9MNF92c19QQk1DIDwtIHBlcmZvcm1fa2VnZ19lbnJpY2htZW50KHVwcmVndWxhdGVkX2dlbmVzX0w0X3ZzX1BCTUMsIGdlbmVfdW5pdmVyc2UsICJVcHJlZ3VsYXRlZCBHZW5lcyBpbiBMNF92c19QQk1DIikKa2VnZ19kb3duX0w0X3ZzX1BCTUMgPC0gcGVyZm9ybV9rZWdnX2VucmljaG1lbnQoZG93bnJlZ3VsYXRlZF9nZW5lc19MNF92c19QQk1DLCBnZW5lX3VuaXZlcnNlLCAiRG93bnJlZ3VsYXRlZCBHZW5lcyBpbiBMNF92c19QQk1DIikKCiMgTDVfdnNfUEJNQyBjb21wYXJpc29uCnVwcmVndWxhdGVkX2dlbmVzX0w1X3ZzX1BCTUMgPC0gcm93bmFtZXMoTDVfdnNfUEJNQ1tMNV92c19QQk1DJGF2Z19sb2cyRkMgPiAyLjUgJiBMNV92c19QQk1DJHBfdmFsX2FkaiA8IDAuMDUsIF0pCmRvd25yZWd1bGF0ZWRfZ2VuZXNfTDVfdnNfUEJNQyA8LSByb3duYW1lcyhMNV92c19QQk1DW0w1X3ZzX1BCTUMkYXZnX2xvZzJGQyA8IC0yLjUgJiBMNV92c19QQk1DJHBfdmFsX2FkaiA8IDAuMDUsIF0pCgpnb191cF9MNV92c19QQk1DIDwtIHBlcmZvcm1fZ29fZW5yaWNobWVudCh1cHJlZ3VsYXRlZF9nZW5lc19MNV92c19QQk1DLCBnZW5lX3VuaXZlcnNlLCAiVXByZWd1bGF0ZWQgR2VuZXMgaW4gTDVfdnNfUEJNQyIpCmdvX2Rvd25fTDVfdnNfUEJNQyA8LSBwZXJmb3JtX2dvX2VucmljaG1lbnQoZG93bnJlZ3VsYXRlZF9nZW5lc19MNV92c19QQk1DLCBnZW5lX3VuaXZlcnNlLCAiRG93bnJlZ3VsYXRlZCBHZW5lcyBpbiBMNV92c19QQk1DIikKa2VnZ191cF9MNV92c19QQk1DIDwtIHBlcmZvcm1fa2VnZ19lbnJpY2htZW50KHVwcmVndWxhdGVkX2dlbmVzX0w1X3ZzX1BCTUMsIGdlbmVfdW5pdmVyc2UsICJVcHJlZ3VsYXRlZCBHZW5lcyBpbiBMNV92c19QQk1DIikKa2VnZ19kb3duX0w1X3ZzX1BCTUMgPC0gcGVyZm9ybV9rZWdnX2VucmljaG1lbnQoZG93bnJlZ3VsYXRlZF9nZW5lc19MNV92c19QQk1DLCBnZW5lX3VuaXZlcnNlLCAiRG93bnJlZ3VsYXRlZCBHZW5lcyBpbiBMNV92c19QQk1DIikKCiMgTDZfdnNfUEJNQyBjb21wYXJpc29uCnVwcmVndWxhdGVkX2dlbmVzX0w2X3ZzX1BCTUMgPC0gcm93bmFtZXMoTDZfdnNfUEJNQ1tMNl92c19QQk1DJGF2Z19sb2cyRkMgPiAyLjUgJiBMNl92c19QQk1DJHBfdmFsX2FkaiA8IDAuMDUsIF0pCmRvd25yZWd1bGF0ZWRfZ2VuZXNfTDZfdnNfUEJNQyA8LSByb3duYW1lcyhMNl92c19QQk1DW0w2X3ZzX1BCTUMkYXZnX2xvZzJGQyA8IC0yLjUgJiBMNl92c19QQk1DJHBfdmFsX2FkaiA8IDAuMDUsIF0pCgpnb191cF9MNl92c19QQk1DIDwtIHBlcmZvcm1fZ29fZW5yaWNobWVudCh1cHJlZ3VsYXRlZF9nZW5lc19MNl92c19QQk1DLCBnZW5lX3VuaXZlcnNlLCAiVXByZWd1bGF0ZWQgR2VuZXMgaW4gTDZfdnNfUEJNQyIpCmdvX2Rvd25fTDZfdnNfUEJNQyA8LSBwZXJmb3JtX2dvX2VucmljaG1lbnQoZG93bnJlZ3VsYXRlZF9nZW5lc19MNl92c19QQk1DLCBnZW5lX3VuaXZlcnNlLCAiRG93bnJlZ3VsYXRlZCBHZW5lcyBpbiBMNl92c19QQk1DIikKa2VnZ191cF9MNl92c19QQk1DIDwtIHBlcmZvcm1fa2VnZ19lbnJpY2htZW50KHVwcmVndWxhdGVkX2dlbmVzX0w2X3ZzX1BCTUMsIGdlbmVfdW5pdmVyc2UsICJVcHJlZ3VsYXRlZCBHZW5lcyBpbiBMNl92c19QQk1DIikKa2VnZ19kb3duX0w2X3ZzX1BCTUMgPC0gcGVyZm9ybV9rZWdnX2VucmljaG1lbnQoZG93bnJlZ3VsYXRlZF9nZW5lc19MNl92c19QQk1DLCBnZW5lX3VuaXZlcnNlLCAiRG93bnJlZ3VsYXRlZCBHZW5lcyBpbiBMNl92c19QQk1DIikKCiMgTDdfdnNfUEJNQyBjb21wYXJpc29uCnVwcmVndWxhdGVkX2dlbmVzX0w3X3ZzX1BCTUMgPC0gcm93bmFtZXMoTDdfdnNfUEJNQ1tMN192c19QQk1DJGF2Z19sb2cyRkMgPiAyLjUgJiBMN192c19QQk1DJHBfdmFsX2FkaiA8IDAuMDUsIF0pCmRvd25yZWd1bGF0ZWRfZ2VuZXNfTDdfdnNfUEJNQyA8LSByb3duYW1lcyhMN192c19QQk1DW0w3X3ZzX1BCTUMkYXZnX2xvZzJGQyA8IC0yLjUgJiBMN192c19QQk1DJHBfdmFsX2FkaiA8IDAuMDUsIF0pCgpnb191cF9MN192c19QQk1DIDwtIHBlcmZvcm1fZ29fZW5yaWNobWVudCh1cHJlZ3VsYXRlZF9nZW5lc19MN192c19QQk1DLCBnZW5lX3VuaXZlcnNlLCAiVXByZWd1bGF0ZWQgR2VuZXMgaW4gTDdfdnNfUEJNQyIpCmdvX2Rvd25fTDdfdnNfUEJNQyA8LSBwZXJmb3JtX2dvX2VucmljaG1lbnQoZG93bnJlZ3VsYXRlZF9nZW5lc19MN192c19QQk1DLCBnZW5lX3VuaXZlcnNlLCAiRG93bnJlZ3VsYXRlZCBHZW5lcyBpbiBMN192c19QQk1DIikKa2VnZ191cF9MN192c19QQk1DIDwtIHBlcmZvcm1fa2VnZ19lbnJpY2htZW50KHVwcmVndWxhdGVkX2dlbmVzX0w3X3ZzX1BCTUMsIGdlbmVfdW5pdmVyc2UsICJVcHJlZ3VsYXRlZCBHZW5lcyBpbiBMN192c19QQk1DIikKa2VnZ19kb3duX0w3X3ZzX1BCTUMgPC0gcGVyZm9ybV9rZWdnX2VucmljaG1lbnQoZG93bnJlZ3VsYXRlZF9nZW5lc19MN192c19QQk1DLCBnZW5lX3VuaXZlcnNlLCAiRG93bnJlZ3VsYXRlZCBHZW5lcyBpbiBMN192c19QQk1DIikKCgpgYGAKCgoKCg==