Load data and libraries

##################
# LOAD LIBRARIES #
##################
library(tidyverse)
library(Seurat)
library(SeuratObject)
library(tidyseurat)
library(cowplot)
library(patchwork)
library(openxlsx)

source("../../bin/spatial_visualization.R")
source("../../bin/plotting_functions.R")

#########
# PATHS #
#########
input_dir <- "../../results/06_DGE_condition_st_data/"
result_dir <- "./Figures/05/"
if( isFALSE(dir.exists(result_dir)) ) { dir.create(result_dir,recursive = TRUE) }
epi_clus <- "^5$|^6$|^7|^8" # res 0.7

ord <- c("Superficial", "Upper IM", "Lower IM", "Basal","1","4","0","3","2","9","10","11","12")
ord1 <- c("5", "6", "7", "8","1","4","0","3","2","9","10","11","12")
sample_id <- c("P020", "P045", "P050", "P057",
               "P008", "P031", "P044","P080", "P026", "P105", 
               "P001", "P004", "P014", "P018", "P087", "P118",
               "P021", "P024", "P067", "P081", "P117" ) %>% set_names()

#############
# LOAD DATA #
#############
DATA <- readRDS(paste0("../../results/03_clustering_st_data/","seuratObj_clustered.RDS"))
DEGs_table <- read_csv(paste0(input_dir,"DGEs_condition_wilcox.0.7.csv"))
pseudo_DEGs <- readRDS(paste0(input_dir,"Pseudobulk_across_DEGs.RDS"))
D <- DEGs_table %>%
  filter(., p_val_adj < 0.05) %>%
  filter(., !(grepl("0|^3|9|10|11|12", .$subgroup))) %>%
  filter(., cluster == "L4") %>%
  mutate(sp_annot = ifelse(grepl("\\d", .$layers), "SubMuc", "epi")) %>%
  split(~sp_annot) 

# knitr::kable(D$epi)
# NOT USED
#################
# PLOT FUNCTION #
#################
morf_DEGs_plot <- function(genes = genes_epi, clus="^5$|^6$|^7|^8"){
  df <- DATA %>%
    mutate(., FetchData(., vars = c(names(genes)), slot = "counts")) %>%
    filter(., grepl(clus, .$Clusters)) %>%
    as_tibble() %>%
    select(1:5, layers, all_of(names(genes))) %>%
    pivot_longer(cols = any_of(names(genes)), names_to = "gene", values_to = "values") %>%
    # filter(gene == "LGALS7") %>%
    group_by( groups, gene, layers) %>%
    summarize(sum_counts = sum(values), .groups="drop") %>%
    mutate("Sum counts(log10)" = log10(.$sum_counts)) %>%
    arrange(`Sum counts(log10)`) %>%
    mutate(type = genes[.$gene])
  
  absmax <- function(x) { x[which.max( abs(x) )]}
  ord <<- df %>%
    #pivot_wider(id_cols = -`Sum counts(log10)`,names_from = "groups", values_from = "sum_counts") %>%
    pivot_wider(id_cols = -sum_counts, names_from = "groups", values_from = `Sum counts(log10)`) %>%
    mutate(diff_L1_L4 = L4-L1, 
           diff_L2_L4 = L4-L2, 
           diff_L3_L4 = L4-L3, .by = "gene") %>%
    rowwise() %>% 
    # Identifies the larges value of eah row among the L1-L4 columns:
    mutate(Regulation = sum(c_across(starts_with("diff")) ),
           max = paste0(names(.[4:7])[c_across(starts_with("L",ignore.case=F)) == 
                                        absmax(c_across(starts_with("L",ignore.case=F)))], collapse = '_') ) %>%
    ungroup() %>%
    mutate(Regulation = ifelse(.$Regulation < 0, "DOWN", "UP"),
           max = str_extract(.$max, "L\\d"))
  
  m <- ifelse(clus == "^5$|^6$|^7|^8", "Epithelial", "Submucosal")
  #write.xlsx(ord, paste0(result_dir, "Selected_DEGs_FIG2-3_", m, ".xlsx"))
  #####################
  # TOP DEGs PLOTTING #
  #####################
  g_ord <- arrange(ord, diff_L1_L4) %>% pull("gene") %>% unique()
  
  col <- c("L1"="#FF7F00", "L2"="#FED9A6", "L3"="#6A51A3", "L4"="#9E9AC8" ) # "#FFFFB3", "#BEBADA","#8DD3C7", "#FB8072",
  col <- c("L1"="#56B4E9","L2"="#009E73","L3"="#CC79A7", "L4"="#FC8D62")
  
  (B <- left_join(df, select(ord, Regulation, max, gene), by="gene") %>%
      #mutate(., gene = factor(gene, levels=g_ord)) %>%
      ggplot2::ggplot(data=., aes(x=fct_reorder2(gene, Regulation,`Sum counts(log10)`), y=`Sum counts(log10)`)) +
    geom_point(aes(col=groups), size = 2) +
    scale_colour_manual(values = col) +
    facet_grid(cols=vars(), rows = vars(layers), scales = "free_x", space = "free_x") +
    #facet_wrap("max", ncol = 2, strip.position = "top", scales = "free_x", shrink = F) +
    theme_minimal() +
    theme(legend.position = "bottom",
          plot.margin = unit(c(5,-1,5,1),units = "pt"),
          legend.margin = margin(-15,2,-8,2), # moves the legend box
          legend.title = element_blank(),
          legend.text = element_text(size = 8),
          legend.spacing.x = unit(4, 'pt'),
          axis.title = element_text(size=8),
          axis.text.x = element_text(size=8, angle=45, hjust=1, color="black"),
          axis.title.x = element_blank(),
          #text = element_text(size = 10),
    ) )
}
geneid  <- c("IGHG4", "IGLC2", "IGHG1", "IGHA2", "IGHA1")
genes <- DEGs_table %>% filter(gene %in% geneid) %>% filter(grepl("^1$|Basal", .$layers)) %>% distinct(gene, layers) %>% deframe()
(Immuno <- morf_DEGs_plot(genes = genes, clus="^1$|8"))
###############
# VIOLIN PLOT #
###############
# https://stackoverflow.com/questions/35717353/split-violin-plot-with-ggplot2

feature <- c("IGHG4", "IGLC2", "IGHG1","IGHG2", "IGHA2", "IGHA1","IGHG3", "CD81", "IGKC", "JCHAIN")
col <- c("L1"="#56B4E9","L2"="#009E73","L3"="#CC79A7", "L4"="#FC8D62")
facet <- "layers"
group.by <- "groups"
ncol <- 1

DEGs_df <- DATA %>%
  #filter(!(grepl("\\d", .$layers))) %>%
  filter(!(grepl("^11$|^12$", .$layers))) %>%
  #filter((grepl("L1|L2", .$groups))) %>%
  mutate(., FetchData(., vars = c(feature)) ) %>%
  #mutate(across(any_of(feature), na_if, 0)) %>% # NB! removes zero values 
  select(orig.ident, any_of(c(feature, facet, group.by, "layers"))) %>%
  pivot_longer(cols = any_of(feature), names_to = "feature", values_to = "val") %>%
  mutate(comb = paste0(.$groups, "_",.$layers)) %>%
  mutate(groups = factor(.$groups, levels = rev(names(col))))
violin_mean_plot <- function(DEGs_df){
  m <- max(na.omit(DEGs_df[["val"]]))/1 # try e.g 2
  DEGs_df %>%
    ggplot(aes(x=.data[[group.by]], y=.data[["val"]], col=.data[[group.by]])) +
    #ggplot(aes(x=groups, y=val, col=groups)) +
    #geom_violin() + # {if(length(feature == 1)) ggtitle(feature)} +
    #geom_boxplot(fill = "transparent", notch = T, outlier.size = .5, outlier.colour = "red") +
    geom_jitter(width = 0.3, height = 0.2, alpha = 0.2, size=.01) +
    stat_summary(aes(y = val), fun=median, geom="crossbar", linewidth=.2, color="black") +
    scale_color_manual(values = col) + ylab("Expression") +
    my_theme + NoLegend() + #xlim(c(0, m)) +
    theme(text = element_text(size = 12),
          axis.line = element_blank(),
          #panel.border = element_rect(colour = "gray") 
          ) +
    #       axis.text.x = element_text(angle = 30, hjust=1),
    #       plot.title = element_text(hjust = 0.5),
    #       axis.title.y = element_blank(),
    #       axis.title.x = element_blank()) +
    #facet_wrap(~.data[[facet]], ncol = ncol, strip.position = c("right", "bottom", "left", "top"))
    facet_grid(rows = vars(layers), cols = vars(feature)) #, strip.position = c("right", "bottom", "left", "top"))
}
feature_ <- c("IGHG4", "IGHG1", "IGHG2", "IGHA2", "IGHA1","IGHG3")
P <- DEGs_df %>%
    filter(feature %in% feature_) %>%
    #filter(!grepl("^11$|^12$|^10$|9|^2|^0|^3|4", layers)) %>%
    filter(!grepl("^11$|^12$", layers)) %>%
    mutate(layers = factor(.$layers, levels = ord )) %>%
    #filter(grepl(.x, groups)) %>%
    {. ->> temp} %>%
    violin_mean_plot() + theme_minimal() +
    NoLegend()

P <- P + coord_flip(clip = F)

################################
# VIOLIN PLOT WITH SIG. VALUES #
################################
library(ggpubr)
features <- c("IGHG4", "IGHG1", "IGHG2", "IGHA2", "IGHA1","IGHG3")

# feature_list <- list(features, features)
# feature_list <- list(c("IGHG1", "IGHA2", "IGHA1","IGHG3"), c("IGHG4"))
# gr <- set_names(c("L1","L4"))
# 
# D <- map2(gr, feature_list, ~ {
#   D <- DEGs_table %>%
#   filter(gene %in% .y) %>%
#   filter(., !(grepl("0|^3|9|^10$|^11$|^12$|^4|^2", .$subgroup))) %>%
#    filter(., (grepl(.x, .$comb))) 
# })
# 
# D <- bind_rows(D)
# D <- D$L1
# D <- D$L4

D <- DEGs_table %>%
    filter(gene %in% features) %>%
    #filter(., !(grepl("0|^3|9|^10$|^11$|^12$|^4|^2", .$subgroup))) #%>%
    filter(!grepl("^11$|^12$", layers))
    #filter(., (grepl("L1|L4", .$comb))) 

sig_df <- D %>%
  select(comb, p_val_adj, cluster, gene, layers) %>%
  mutate(layers = factor(.$layers, levels = ord )) %>%
  separate(comb, into = c("group1", "group2"), sep = "-") %>%
  rename(feature = gene) %>%  # align names
  mutate(step = paste0(feature, "_", layers)) %>%
  mutate(p.adj.signif = case_when(
    p_val_adj < 0.001 ~ "***",
    p_val_adj < 0.01  ~ "**",
    p_val_adj < 0.05  ~ "*",
    TRUE              ~ "ns"
  )) %>%
  left_join(
    temp %>%
      group_by(feature, layers, groups) %>%
      summarise(ymax = max(val, na.rm = TRUE), .groups = "drop"),
    by = c("feature", "layers" = "layers", "group2" = "groups")
  ) %>%
  mutate(y.position = ymax + 0) %>%  # 0.5 above max point
  filter(p.adj.signif != "ns")

# dev.new(width=6.7, height=4.5, noRStudioGD = TRUE) 
# dev.new(width=9, height=9, noRStudioGD = TRUE) 
(plot <- P + ggpubr::stat_pvalue_manual(
    sig_df,
    step.group.by = "step",
    step.increase = 0.09,
    label = "p.adj.signif",
    y.position = sig_df$y.position,   # use computed y
    xmin = "group1",
    xmax = "group2",
    tip.length = 0.01,
    coord.flip = TRUE
    ))

# ggsave("./Figures/04/sig_all_level_comp_IgG_IgA.png", plot, width = 9, height = 4.5)
features <- c("IGHA1","IGHG1", "CD81", "IGKC", "JCHAIN")
# dev.new(width=6.5, height=4, noRStudioGD = TRUE) 
A1 <- DEGs_df %>%
  filter((grepl("Basal|^1$", .$layers))) %>%
  filter((grepl("L1|L2", .$groups))) %>%
  filter(feature %in% features) %>%
  violin_mean_plot() + geom_violin(fill = "transparent")
features <- c("IGHG4", "IGHG1", "IGHG2", "IGHA2", "IGHA1","IGHG3")
# dev.new(width=9, height=4.5, noRStudioGD = TRUE) 
B <- DEGs_df %>%
  filter(., !(grepl("0|^3|9|^10$|^11$|^12$|^4|^2", .$layers))) %>%
  filter(feature %in% features) %>%
  violin_mean_plot() + coord_flip(clip = F) +
  theme_minimal() + NoLegend() 

sig_filt <- filter(sig_df, !(grepl("0|^3|9|^10$|^11$|^12$|^4|^2", sig_df$layers)))

(B <- B + ggpubr::stat_pvalue_manual(
    sig_filt,
    step.group.by = "step",
    step.increase = 0.09,
    label = "p.adj.signif",
    y.position = sig_filt$y.position,   # use computed y
    xmin = "group1",
    xmax = "group2",
    tip.length = 0.01,
    coord.flip = TRUE
    ))

######################
# PLOTTING ON TISSUE #
######################
col = c("#EFEDF5", "#DADAEB", "#BCBDDC", "#9E9AC8", "#807DBA", "#6A51A3", "#54278F", "#3F007D")
geneid <- c("IGHG4", "IGLC2", "IGHG1", "IGHA2", "IGHA1", "CD81", "IGKC", "JCHAIN")

# ggsave("./Figures/02&03/Tissue_Immuno.png", p, width = 12.5, height = 12.5, bg = "white") #, dpi = 300
# dev.new(height=3, width=7, noRStudioGD = TRUE)
plots_all <- geneid %>%
  map(., ~plot_spatial.fun(
      DATA,
      sampleid = sample_id,
      save_space = T,
      colors = col, 
      geneid = .x,
      zoom = "zoom",
      ncol = 4,
      img_alpha = 0,
      point_size = .5)
    )

# dev.new(width=8, height=8, noRStudioGD = TRUE)
plots_all[[1]]

################
# SAVE RESULTS #
################
pdf(file=paste0("./Figures/04/Tissue_Immuno_all.pdf"), 
    #width = 8.5, height = 10 # Epi
    width = 8, height = 8 # Sub
)
plots_all
## [[1]]
## 
## [[2]]
## 
## [[3]]
## 
## [[4]]
## 
## [[5]]
## 
## [[6]]
## 
## [[7]]
## 
## [[8]]
dev.off()
## quartz_off_screen 
##                 2
######################
# PLOTTING ON TISSUE #
######################
sample_id_ <- c("P057","P044")


plots_rep <- geneid %>%
  map(., ~plot_spatial.fun(
      DATA,
      sampleid = sample_id_,
      save_space = F,
      colors = col, 
      geneid = .x,
      zoom = "zoom",
      ncol = 4,
      img_alpha = 0,
      point_size = .5)
    )
# dev.new(width=3.3, height=2, noRStudioGD = TRUE)
plots_rep[[1]]

A2 <- plot_grid(plots_rep[[8]], plots_rep[[5]], ncol = 1)
# ggsave("./Figures/04/on_tissue.png", B, width = 4, height = 3.3, bg = "white", dpi = 500) #, dpi = 300
#########################
# COMBINE PANEL A AND B #
#########################
# dev.new(width=6.7, height=3, noRStudioGD = TRUE) 
(A <- plot_grid(A1, A2, rel_widths = c(1, 1))) # labels = c("a", "b")

# ggsave("./Figures/04/Figure_4.png", p, width = 6.7, height = 3.3, bg = "white") #, dpi = 300
# checks if the mean difference in expression is reflected in each sample
# or biased by a single sample, by plotting on sample level

violin_sample_plot <- function(DEGs_df){
  m <- max(na.omit(DEGs_df[["val"]]))/1 # try e.g 2
  DEGs_df %>%
    ggplot(aes(x=orig.ident, y=val, col=groups)) +
    geom_violin() + # {if(length(feature == 1)) ggtitle(feature)} +
    #geom_boxplot(fill = "transparent", notch = T, outlier.size = .5, outlier.colour = "red") +
    #geom_jitter(width = 0.3, height = 0.2, alpha = 0.2, size=.01) +
    stat_summary(aes(y = val), fun=median, geom="crossbar", linewidth=.2, color="black") +
    scale_color_manual(values = col) + ylab("Expression") +
    my_theme + NoLegend() + #xlim(c(0, m)) +
    theme(text = element_text(size = 9),
          plot.margin = unit(c(-0,-2,1,-6),units = "pt"),
          plot.title = element_text(size = 8, hjust = 0.5, margin = margin(b = 0)),
          axis.line = element_blank(),
          axis.title.x = element_blank(),
          axis.text.x = element_text(angle = 30, hjust=1)
          #panel.border = element_rect(colour = "gray")
          ) +
    #       axis.title.y = element_blank(),
    #       ) +
    #facet_wrap(~.data[[facet]], ncol = ncol, strip.position = c("right", "bottom", "left", "top"))
    facet_grid(rows = vars(layers), cols = vars(groups), scale ="free", space ="free" ) #, strip.position = c("right", "bottom", "left", "top"))
}
feature <- c("IGHG4", "IGHG1", "IGHA2", "IGHA1","IGHG3")
feature_ <- c("IGHG1")
col <- c("L1"="#56B4E9","L2"="#009E73","L3"="#CC79A7", "L4"="#FC8D62")
facet <- "layers"
group.by <- "orig.ident"
ncol <- 1
# dev.new(width=15, height=9, noRStudioGD = TRUE) 
# plots individual groups (L1-L4) at sample level
plots <- map(set_names(feature), ~ {
  P <- DEGs_df %>%
    filter(feature %in% .x) %>%
    filter(!grepl("^11$|^12$|^10$|9|^2|^0|^3|4", layers)) %>%
    #filter(grepl(.x, groups)) %>%
    violin_sample_plot() + geom_violin(fill = "transparent") +
    ggtitle(paste0(.x))
})
plots$IGHG1

P <- plot_grid(plotlist = plots, ncol = 1)
# ggsave("./Figures/04/sample_level_comp_.png", P, width = 6.7, height = 20) #, dpi = 300
# dev.new(width=8, height=9, noRStudioGD = TRUE) 
# all groups (L1-L4) across all layers
p <- DEGs_df %>%
  # filter(!(feature %in% c("CD81")))  %>%
  violin_mean_plot()
# ggsave("./Figures/04/Fig_viol.png", A, width = 6.7, height = 3) #, dpi = 300
# dev.new(width=8, height=7, noRStudioGD = TRUE) 
# L1 and L2 only across all layers
p <- DEGs_df %>% 
  filter((grepl("L1|L2", .$groups))) %>% 
  violin_mean_plot()
feature <- c("IGHA1","IGHG1", "CD81", "IGKC", "JCHAIN")
feature <- c("IGHA1","IGHG1", "IGHG3", "IGKC", "IGHG4")

DEGs_df <- DEGs_df %>%
  filter((grepl("L1|L2", .$groups))) %>% 
  filter((grepl("Basal|^1$", .$layers))) %>%
  filter(feature %in% feature) 

# groups on x-axis, genes on x axis
# used for figure 4
violin_mean_plot <- function(DEGs_df){
  m <- max(na.omit(DEGs_df[["val"]]))/1 # try e.g 2
  DEGs_df %>%
    ggplot(aes(x=.data[[group.by]], y=.data[["val"]], col=.data[[group.by]])) +
    geom_violin() + # {if(length(feature == 1)) ggtitle(feature)} +
    stat_summary(aes(y = val), fun=median, geom="crossbar", linewidth=.3, color="black") +
    #geom_boxplot(fill = "transparent", notch = T, outlier.size = .5, outlier.colour = "red") +
    geom_jitter(width = 0.3, height = 0.2, alpha = 0.2, size=.01) +
    scale_color_manual(values = col) + ylab("Expression") +
    my_theme + NoLegend() + #xlim(c(0, m)) +
    theme(text = element_text(size = 12),
          axis.line = element_blank(),
          panel.border = element_rect(colour = "gray") ) +
    #       axis.text.x = element_text(angle = 30, hjust=1),
    #       plot.title = element_text(hjust = 0.5),
    #       axis.title.y = element_blank(),
    #       axis.title.x = element_blank()) +
    #facet_wrap(~.data[[facet]], ncol = ncol, strip.position = c("right", "bottom", "left", "top"))
    facet_grid(rows = vars(layers), cols = vars(feature)) #, strip.position = c("right", "bottom", "left", "top"))
}

# dev.new(width=3.3, height=3, noRStudioGD = TRUE) 
A <- violin_mean_plot(DEGs_df)
# ggsave("./Figures/04/Fig_L1_L2_viol.png", A, width = 4, height = 4, dpi = 500) #, dpi = 300
A
#########################
# COMBINE PANEL A AND B #
#########################
# dev.new(width=6.7, height=7, noRStudioGD = TRUE) 
(FIGURE4 <- plot_grid(A, B, ncol = 1, rel_heights = c(3, 4))) # labels = c("a", "b")

# ggsave("./Figures/04/Figure_4.png", p, width = 6.7, height = 3.3, bg = "white") #, dpi = 300
LS0tCnRpdGxlOiAiRmlndXJlIDQiCnN1YnRpdGxlOiAiSW1tdW5vZ2xvYnVsaW4gcGxvdHMiCmRhdGU6ICJgciBmb3JtYXQoU3lzLnRpbWUoKSwgJyVkLSVtLSVZJylgIgpmb3JtYXQ6CiAgaHRtbDoKICAgIGVtYmVkLXJlc291cmNlczogdHJ1ZQogICAgY29kZS1mb2xkOiBzaG93CnBhcmFtczoKICBmaWcucGF0aDogImByIHBhc3RlMChwYXJhbXMkZmlnLnBhdGgpYCIgIy4vRmlndXJlcy8KZWRpdG9yX29wdGlvbnM6IAogIGNodW5rX291dHB1dF90eXBlOiBjb25zb2xlCi0tLQoKCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoCiAgZmlnLndpZHRoICAgICA9IDYuNjkyOTEzMzg1OCwKICBmaWcucGF0aCAgICAgID0gcGFyYW1zJGZpZy5wYXRoLCMiLi4vRmlndXJlcy8iLAogIGZpZy5hbGlnbiAgICAgPSAiY2VudGVyIiwKICBtZXNzYWdlICAgICAgID0gRkFMU0UsCiAgd2FybmluZyAgICAgICA9IEZBTFNFLAogIGRldiAgICAgICAgICAgPSBjKCJwbmciKSwKICBkcGkgICAgICAgICAgID0gMzAwLAogIGZpZy5wcm9jZXNzID0gZnVuY3Rpb24oZmlsZW5hbWUpewogICAgbmV3X2ZpbGVuYW1lIDwtIHN0cmluZ3I6OnN0cl9yZW1vdmUoc3RyaW5nID0gZmlsZW5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXR0ZXJuID0gIi0xIikKICAgIGZzOjpmaWxlX21vdmUocGF0aCA9IGZpbGVuYW1lLCBuZXdfcGF0aCA9IG5ld19maWxlbmFtZSkKICAgIGlmZWxzZShmczo6ZmlsZV9leGlzdHMobmV3X2ZpbGVuYW1lKSwgbmV3X2ZpbGVuYW1lLCBmaWxlbmFtZSkKICB9CiAgKQojICBzZXR3ZCgifi93b3JrL0Jyb2xpZGVuc193b3JrL1Byb2plY3RzL1NwYXRpYWxfTWljcm9iaW90YS9zcmMvTWFudXNjcmlwdCIpCmBgYAoKYGBge3IgYmFja2dyb3VuZF9qb2IsIGV2YWw9RkFMU0UsIGluY2x1ZGU9RkFMU0V9CnNvdXJjZSgiLi4vLi4vYmluL3JlbmRlcl93aXRoX2pvYnMuUiIpCgojIHF1YXJ0bwojIHJlbmRlcl9odG1sX3dpdGhfam9iKG91dF9kaXIgPSBsYWJfZGlyKQojIGZzOjpmaWxlX21vdmUocGF0aCA9IGZpbGUsIG5ld19wYXRoID0gcGFzdGUwKGxhYl9kaXIsIGZpbGUpKQoKIyBjdXJyZW50bHkgdXNpbmcgcXVhcnRvIGZvciBnaXRodWIgYW5kIGtuaXRlciBmb3IgaHRtbCBkdWUgdG8gc291cmNlIGNvZGUgb3B0aW9uIApyZW5kZXJfZ2l0X3dpdGhfam9iKGZpZ19wYXRoID0gIi4vRmlndXJlcy8wNC8iKQpzeXN0ZW0yKGNvbW1hbmQgPSAic2VkIiwgc3Rkb3V0ID0gVFJVRSwKICAgICAgICBhcmdzID0gYygiLWkiLCAiJyciLCItZSIsICdzL3NyYz1cXCJcXC4vc3JjPVxcIlxcLlxcLi9nJywKICAgICAgICAgICAgICAgICBwYXN0ZTAoIi4vbWRfZmlsZXMvIiwgYmFzZW5hbWUoIi4vMDRfZmlndXJlcy5tZCIpKSkpCgojIGtuaXRlcgprbml0X2h0bWxfd2l0aF9qb2Iob3V0X2RpciA9ICIuLi8uLi9sYWJfYm9vay9maWd1cmVfMDQiLCBmaWdfcGF0aCA9ICIuL0ZpZ3VyZXMvMDQvIikKYGBgCgojIyMgTG9hZCBkYXRhIGFuZCBsaWJyYXJpZXMKYGBge3IgTG9hZF9kYXRhfQojIyMjIyMjIyMjIyMjIyMjIyMKIyBMT0FEIExJQlJBUklFUyAjCiMjIyMjIyMjIyMjIyMjIyMjIwpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShTZXVyYXQpCmxpYnJhcnkoU2V1cmF0T2JqZWN0KQpsaWJyYXJ5KHRpZHlzZXVyYXQpCmxpYnJhcnkoY293cGxvdCkKbGlicmFyeShwYXRjaHdvcmspCmxpYnJhcnkob3Blbnhsc3gpCgpzb3VyY2UoIi4uLy4uL2Jpbi9zcGF0aWFsX3Zpc3VhbGl6YXRpb24uUiIpCnNvdXJjZSgiLi4vLi4vYmluL3Bsb3R0aW5nX2Z1bmN0aW9ucy5SIikKCiMjIyMjIyMjIwojIFBBVEhTICMKIyMjIyMjIyMjCmlucHV0X2RpciA8LSAiLi4vLi4vcmVzdWx0cy8wNl9ER0VfY29uZGl0aW9uX3N0X2RhdGEvIgpyZXN1bHRfZGlyIDwtICIuL0ZpZ3VyZXMvMDUvIgppZiggaXNGQUxTRShkaXIuZXhpc3RzKHJlc3VsdF9kaXIpKSApIHsgZGlyLmNyZWF0ZShyZXN1bHRfZGlyLHJlY3Vyc2l2ZSA9IFRSVUUpIH0KZXBpX2NsdXMgPC0gIl41JHxeNiR8Xjd8XjgiICMgcmVzIDAuNwoKb3JkIDwtIGMoIlN1cGVyZmljaWFsIiwgIlVwcGVyIElNIiwgIkxvd2VyIElNIiwgIkJhc2FsIiwiMSIsIjQiLCIwIiwiMyIsIjIiLCI5IiwiMTAiLCIxMSIsIjEyIikKb3JkMSA8LSBjKCI1IiwgIjYiLCAiNyIsICI4IiwiMSIsIjQiLCIwIiwiMyIsIjIiLCI5IiwiMTAiLCIxMSIsIjEyIikKc2FtcGxlX2lkIDwtIGMoIlAwMjAiLCAiUDA0NSIsICJQMDUwIiwgIlAwNTciLAogICAgICAgICAgICAgICAiUDAwOCIsICJQMDMxIiwgIlAwNDQiLCJQMDgwIiwgIlAwMjYiLCAiUDEwNSIsIAogICAgICAgICAgICAgICAiUDAwMSIsICJQMDA0IiwgIlAwMTQiLCAiUDAxOCIsICJQMDg3IiwgIlAxMTgiLAogICAgICAgICAgICAgICAiUDAyMSIsICJQMDI0IiwgIlAwNjciLCAiUDA4MSIsICJQMTE3IiApICU+JSBzZXRfbmFtZXMoKQoKIyMjIyMjIyMjIyMjIwojIExPQUQgREFUQSAjCiMjIyMjIyMjIyMjIyMKREFUQSA8LSByZWFkUkRTKHBhc3RlMCgiLi4vLi4vcmVzdWx0cy8wM19jbHVzdGVyaW5nX3N0X2RhdGEvIiwic2V1cmF0T2JqX2NsdXN0ZXJlZC5SRFMiKSkKREVHc190YWJsZSA8LSByZWFkX2NzdihwYXN0ZTAoaW5wdXRfZGlyLCJER0VzX2NvbmRpdGlvbl93aWxjb3guMC43LmNzdiIpKQpwc2V1ZG9fREVHcyA8LSByZWFkUkRTKHBhc3RlMChpbnB1dF9kaXIsIlBzZXVkb2J1bGtfYWNyb3NzX0RFR3MuUkRTIikpCgpgYGAKCmBgYHtyfQpEIDwtIERFR3NfdGFibGUgJT4lCiAgZmlsdGVyKC4sIHBfdmFsX2FkaiA8IDAuMDUpICU+JQogIGZpbHRlciguLCAhKGdyZXBsKCIwfF4zfDl8MTB8MTF8MTIiLCAuJHN1Ymdyb3VwKSkpICU+JQogIGZpbHRlciguLCBjbHVzdGVyID09ICJMNCIpICU+JQogIG11dGF0ZShzcF9hbm5vdCA9IGlmZWxzZShncmVwbCgiXFxkIiwgLiRsYXllcnMpLCAiU3ViTXVjIiwgImVwaSIpKSAlPiUKICBzcGxpdCh+c3BfYW5ub3QpIAoKIyBrbml0cjo6a2FibGUoRCRlcGkpCmBgYAoKYGBge3IgZG90LXBsb3QsIGV2YWw9RkFMU0V9CiMgTk9UIFVTRUQKIyMjIyMjIyMjIyMjIyMjIyMKIyBQTE9UIEZVTkNUSU9OICMKIyMjIyMjIyMjIyMjIyMjIyMKbW9yZl9ERUdzX3Bsb3QgPC0gZnVuY3Rpb24oZ2VuZXMgPSBnZW5lc19lcGksIGNsdXM9Il41JHxeNiR8Xjd8XjgiKXsKICBkZiA8LSBEQVRBICU+JQogICAgbXV0YXRlKC4sIEZldGNoRGF0YSguLCB2YXJzID0gYyhuYW1lcyhnZW5lcykpLCBzbG90ID0gImNvdW50cyIpKSAlPiUKICAgIGZpbHRlciguLCBncmVwbChjbHVzLCAuJENsdXN0ZXJzKSkgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNlbGVjdCgxOjUsIGxheWVycywgYWxsX29mKG5hbWVzKGdlbmVzKSkpICU+JQogICAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBhbnlfb2YobmFtZXMoZ2VuZXMpKSwgbmFtZXNfdG8gPSAiZ2VuZSIsIHZhbHVlc190byA9ICJ2YWx1ZXMiKSAlPiUKICAgICMgZmlsdGVyKGdlbmUgPT0gIkxHQUxTNyIpICU+JQogICAgZ3JvdXBfYnkoIGdyb3VwcywgZ2VuZSwgbGF5ZXJzKSAlPiUKICAgIHN1bW1hcml6ZShzdW1fY291bnRzID0gc3VtKHZhbHVlcyksIC5ncm91cHM9ImRyb3AiKSAlPiUKICAgIG11dGF0ZSgiU3VtIGNvdW50cyhsb2cxMCkiID0gbG9nMTAoLiRzdW1fY291bnRzKSkgJT4lCiAgICBhcnJhbmdlKGBTdW0gY291bnRzKGxvZzEwKWApICU+JQogICAgbXV0YXRlKHR5cGUgPSBnZW5lc1suJGdlbmVdKQogIAogIGFic21heCA8LSBmdW5jdGlvbih4KSB7IHhbd2hpY2gubWF4KCBhYnMoeCkgKV19CiAgb3JkIDw8LSBkZiAlPiUKICAgICNwaXZvdF93aWRlcihpZF9jb2xzID0gLWBTdW0gY291bnRzKGxvZzEwKWAsbmFtZXNfZnJvbSA9ICJncm91cHMiLCB2YWx1ZXNfZnJvbSA9ICJzdW1fY291bnRzIikgJT4lCiAgICBwaXZvdF93aWRlcihpZF9jb2xzID0gLXN1bV9jb3VudHMsIG5hbWVzX2Zyb20gPSAiZ3JvdXBzIiwgdmFsdWVzX2Zyb20gPSBgU3VtIGNvdW50cyhsb2cxMClgKSAlPiUKICAgIG11dGF0ZShkaWZmX0wxX0w0ID0gTDQtTDEsIAogICAgICAgICAgIGRpZmZfTDJfTDQgPSBMNC1MMiwgCiAgICAgICAgICAgZGlmZl9MM19MNCA9IEw0LUwzLCAuYnkgPSAiZ2VuZSIpICU+JQogICAgcm93d2lzZSgpICU+JSAKICAgICMgSWRlbnRpZmllcyB0aGUgbGFyZ2VzIHZhbHVlIG9mIGVhaCByb3cgYW1vbmcgdGhlIEwxLUw0IGNvbHVtbnM6CiAgICBtdXRhdGUoUmVndWxhdGlvbiA9IHN1bShjX2Fjcm9zcyhzdGFydHNfd2l0aCgiZGlmZiIpKSApLAogICAgICAgICAgIG1heCA9IHBhc3RlMChuYW1lcyguWzQ6N10pW2NfYWNyb3NzKHN0YXJ0c193aXRoKCJMIixpZ25vcmUuY2FzZT1GKSkgPT0gCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhYnNtYXgoY19hY3Jvc3Moc3RhcnRzX3dpdGgoIkwiLGlnbm9yZS5jYXNlPUYpKSldLCBjb2xsYXBzZSA9ICdfJykgKSAlPiUKICAgIHVuZ3JvdXAoKSAlPiUKICAgIG11dGF0ZShSZWd1bGF0aW9uID0gaWZlbHNlKC4kUmVndWxhdGlvbiA8IDAsICJET1dOIiwgIlVQIiksCiAgICAgICAgICAgbWF4ID0gc3RyX2V4dHJhY3QoLiRtYXgsICJMXFxkIikpCiAgCiAgbSA8LSBpZmVsc2UoY2x1cyA9PSAiXjUkfF42JHxeN3xeOCIsICJFcGl0aGVsaWFsIiwgIlN1Ym11Y29zYWwiKQogICN3cml0ZS54bHN4KG9yZCwgcGFzdGUwKHJlc3VsdF9kaXIsICJTZWxlY3RlZF9ERUdzX0ZJRzItM18iLCBtLCAiLnhsc3giKSkKICAjIyMjIyMjIyMjIyMjIyMjIyMjIyMKICAjIFRPUCBERUdzIFBMT1RUSU5HICMKICAjIyMjIyMjIyMjIyMjIyMjIyMjIyMKICBnX29yZCA8LSBhcnJhbmdlKG9yZCwgZGlmZl9MMV9MNCkgJT4lIHB1bGwoImdlbmUiKSAlPiUgdW5pcXVlKCkKICAKICBjb2wgPC0gYygiTDEiPSIjRkY3RjAwIiwgIkwyIj0iI0ZFRDlBNiIsICJMMyI9IiM2QTUxQTMiLCAiTDQiPSIjOUU5QUM4IiApICMgIiNGRkZGQjMiLCAiI0JFQkFEQSIsIiM4REQzQzciLCAiI0ZCODA3MiIsCiAgY29sIDwtIGMoIkwxIj0iIzU2QjRFOSIsIkwyIj0iIzAwOUU3MyIsIkwzIj0iI0NDNzlBNyIsICJMNCI9IiNGQzhENjIiKQogIAogIChCIDwtIGxlZnRfam9pbihkZiwgc2VsZWN0KG9yZCwgUmVndWxhdGlvbiwgbWF4LCBnZW5lKSwgYnk9ImdlbmUiKSAlPiUKICAgICAgI211dGF0ZSguLCBnZW5lID0gZmFjdG9yKGdlbmUsIGxldmVscz1nX29yZCkpICU+JQogICAgICBnZ3Bsb3QyOjpnZ3Bsb3QoZGF0YT0uLCBhZXMoeD1mY3RfcmVvcmRlcjIoZ2VuZSwgUmVndWxhdGlvbixgU3VtIGNvdW50cyhsb2cxMClgKSwgeT1gU3VtIGNvdW50cyhsb2cxMClgKSkgKwogICAgZ2VvbV9wb2ludChhZXMoY29sPWdyb3VwcyksIHNpemUgPSAyKSArCiAgICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGNvbCkgKwogICAgZmFjZXRfZ3JpZChjb2xzPXZhcnMoKSwgcm93cyA9IHZhcnMobGF5ZXJzKSwgc2NhbGVzID0gImZyZWVfeCIsIHNwYWNlID0gImZyZWVfeCIpICsKICAgICNmYWNldF93cmFwKCJtYXgiLCBuY29sID0gMiwgc3RyaXAucG9zaXRpb24gPSAidG9wIiwgc2NhbGVzID0gImZyZWVfeCIsIHNocmluayA9IEYpICsKICAgIHRoZW1lX21pbmltYWwoKSArCiAgICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwKICAgICAgICAgIHBsb3QubWFyZ2luID0gdW5pdChjKDUsLTEsNSwxKSx1bml0cyA9ICJwdCIpLAogICAgICAgICAgbGVnZW5kLm1hcmdpbiA9IG1hcmdpbigtMTUsMiwtOCwyKSwgIyBtb3ZlcyB0aGUgbGVnZW5kIGJveAogICAgICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgpLAogICAgICAgICAgbGVnZW5kLnNwYWNpbmcueCA9IHVuaXQoNCwgJ3B0JyksCiAgICAgICAgICBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9OCksCiAgICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplPTgsIGFuZ2xlPTQ1LCBoanVzdD0xLCBjb2xvcj0iYmxhY2siKSwKICAgICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICAgICN0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCksCiAgICApICkKfQpnZW5laWQgIDwtIGMoIklHSEc0IiwgIklHTEMyIiwgIklHSEcxIiwgIklHSEEyIiwgIklHSEExIikKZ2VuZXMgPC0gREVHc190YWJsZSAlPiUgZmlsdGVyKGdlbmUgJWluJSBnZW5laWQpICU+JSBmaWx0ZXIoZ3JlcGwoIl4xJHxCYXNhbCIsIC4kbGF5ZXJzKSkgJT4lIGRpc3RpbmN0KGdlbmUsIGxheWVycykgJT4lIGRlZnJhbWUoKQooSW1tdW5vIDwtIG1vcmZfREVHc19wbG90KGdlbmVzID0gZ2VuZXMsIGNsdXM9Il4xJHw4IikpCmBgYAoKYGBge3IgdmlvbGluLXBsb3QtZGF0YX0KIyMjIyMjIyMjIyMjIyMjCiMgVklPTElOIFBMT1QgIwojIyMjIyMjIyMjIyMjIyMKIyBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8zNTcxNzM1My9zcGxpdC12aW9saW4tcGxvdC13aXRoLWdncGxvdDIKCmZlYXR1cmUgPC0gYygiSUdIRzQiLCAiSUdMQzIiLCAiSUdIRzEiLCJJR0hHMiIsICJJR0hBMiIsICJJR0hBMSIsIklHSEczIiwgIkNEODEiLCAiSUdLQyIsICJKQ0hBSU4iKQpjb2wgPC0gYygiTDEiPSIjNTZCNEU5IiwiTDIiPSIjMDA5RTczIiwiTDMiPSIjQ0M3OUE3IiwgIkw0Ij0iI0ZDOEQ2MiIpCmZhY2V0IDwtICJsYXllcnMiCmdyb3VwLmJ5IDwtICJncm91cHMiCm5jb2wgPC0gMQoKREVHc19kZiA8LSBEQVRBICU+JQogICNmaWx0ZXIoIShncmVwbCgiXFxkIiwgLiRsYXllcnMpKSkgJT4lCiAgZmlsdGVyKCEoZ3JlcGwoIl4xMSR8XjEyJCIsIC4kbGF5ZXJzKSkpICU+JQogICNmaWx0ZXIoKGdyZXBsKCJMMXxMMiIsIC4kZ3JvdXBzKSkpICU+JQogIG11dGF0ZSguLCBGZXRjaERhdGEoLiwgdmFycyA9IGMoZmVhdHVyZSkpICkgJT4lCiAgI211dGF0ZShhY3Jvc3MoYW55X29mKGZlYXR1cmUpLCBuYV9pZiwgMCkpICU+JSAjIE5CISByZW1vdmVzIHplcm8gdmFsdWVzIAogIHNlbGVjdChvcmlnLmlkZW50LCBhbnlfb2YoYyhmZWF0dXJlLCBmYWNldCwgZ3JvdXAuYnksICJsYXllcnMiKSkpICU+JQogIHBpdm90X2xvbmdlcihjb2xzID0gYW55X29mKGZlYXR1cmUpLCBuYW1lc190byA9ICJmZWF0dXJlIiwgdmFsdWVzX3RvID0gInZhbCIpICU+JQogIG11dGF0ZShjb21iID0gcGFzdGUwKC4kZ3JvdXBzLCAiXyIsLiRsYXllcnMpKSAlPiUKICBtdXRhdGUoZ3JvdXBzID0gZmFjdG9yKC4kZ3JvdXBzLCBsZXZlbHMgPSByZXYobmFtZXMoY29sKSkpKQoKYGBgCgpgYGB7ciB2aW9saW4tZnVuY3Rpb259CnZpb2xpbl9tZWFuX3Bsb3QgPC0gZnVuY3Rpb24oREVHc19kZil7CiAgbSA8LSBtYXgobmEub21pdChERUdzX2RmW1sidmFsIl1dKSkvMSAjIHRyeSBlLmcgMgogIERFR3NfZGYgJT4lCiAgICBnZ3Bsb3QoYWVzKHg9LmRhdGFbW2dyb3VwLmJ5XV0sIHk9LmRhdGFbWyJ2YWwiXV0sIGNvbD0uZGF0YVtbZ3JvdXAuYnldXSkpICsKICAgICNnZ3Bsb3QoYWVzKHg9Z3JvdXBzLCB5PXZhbCwgY29sPWdyb3VwcykpICsKICAgICNnZW9tX3Zpb2xpbigpICsgIyB7aWYobGVuZ3RoKGZlYXR1cmUgPT0gMSkpIGdndGl0bGUoZmVhdHVyZSl9ICsKICAgICNnZW9tX2JveHBsb3QoZmlsbCA9ICJ0cmFuc3BhcmVudCIsIG5vdGNoID0gVCwgb3V0bGllci5zaXplID0gLjUsIG91dGxpZXIuY29sb3VyID0gInJlZCIpICsKICAgIGdlb21faml0dGVyKHdpZHRoID0gMC4zLCBoZWlnaHQgPSAwLjIsIGFscGhhID0gMC4yLCBzaXplPS4wMSkgKwogICAgc3RhdF9zdW1tYXJ5KGFlcyh5ID0gdmFsKSwgZnVuPW1lZGlhbiwgZ2VvbT0iY3Jvc3NiYXIiLCBsaW5ld2lkdGg9LjIsIGNvbG9yPSJibGFjayIpICsKICAgIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjb2wpICsgeWxhYigiRXhwcmVzc2lvbiIpICsKICAgIG15X3RoZW1lICsgTm9MZWdlbmQoKSArICN4bGltKGMoMCwgbSkpICsKICAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgICAgICAgIGF4aXMubGluZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICAgICNwYW5lbC5ib3JkZXIgPSBlbGVtZW50X3JlY3QoY29sb3VyID0gImdyYXkiKSAKICAgICAgICAgICkgKwogICAgIyAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDMwLCBoanVzdD0xKSwKICAgICMgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSksCiAgICAjICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICMgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpKSArCiAgICAjZmFjZXRfd3JhcCh+LmRhdGFbW2ZhY2V0XV0sIG5jb2wgPSBuY29sLCBzdHJpcC5wb3NpdGlvbiA9IGMoInJpZ2h0IiwgImJvdHRvbSIsICJsZWZ0IiwgInRvcCIpKQogICAgZmFjZXRfZ3JpZChyb3dzID0gdmFycyhsYXllcnMpLCBjb2xzID0gdmFycyhmZWF0dXJlKSkgIywgc3RyaXAucG9zaXRpb24gPSBjKCJyaWdodCIsICJib3R0b20iLCAibGVmdCIsICJ0b3AiKSkKfQpgYGAKCmBgYHtyIHBsb3QtYWxsLWxheWVycywgZmlnLndpZHRoPTgsZmlnLmhlaWdodD03fQpmZWF0dXJlXyA8LSBjKCJJR0hHNCIsICJJR0hHMSIsICJJR0hHMiIsICJJR0hBMiIsICJJR0hBMSIsIklHSEczIikKUCA8LSBERUdzX2RmICU+JQogICAgZmlsdGVyKGZlYXR1cmUgJWluJSBmZWF0dXJlXykgJT4lCiAgICAjZmlsdGVyKCFncmVwbCgiXjExJHxeMTIkfF4xMCR8OXxeMnxeMHxeM3w0IiwgbGF5ZXJzKSkgJT4lCiAgICBmaWx0ZXIoIWdyZXBsKCJeMTEkfF4xMiQiLCBsYXllcnMpKSAlPiUKICAgIG11dGF0ZShsYXllcnMgPSBmYWN0b3IoLiRsYXllcnMsIGxldmVscyA9IG9yZCApKSAlPiUKICAgICNmaWx0ZXIoZ3JlcGwoLngsIGdyb3VwcykpICU+JQogICAgey4gLT4+IHRlbXB9ICU+JQogICAgdmlvbGluX21lYW5fcGxvdCgpICsgdGhlbWVfbWluaW1hbCgpICsKICAgIE5vTGVnZW5kKCkKClAgPC0gUCArIGNvb3JkX2ZsaXAoY2xpcCA9IEYpCgojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwojIFZJT0xJTiBQTE9UIFdJVEggU0lHLiBWQUxVRVMgIwojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwpsaWJyYXJ5KGdncHVicikKZmVhdHVyZXMgPC0gYygiSUdIRzQiLCAiSUdIRzEiLCAiSUdIRzIiLCAiSUdIQTIiLCAiSUdIQTEiLCJJR0hHMyIpCgojIGZlYXR1cmVfbGlzdCA8LSBsaXN0KGZlYXR1cmVzLCBmZWF0dXJlcykKIyBmZWF0dXJlX2xpc3QgPC0gbGlzdChjKCJJR0hHMSIsICJJR0hBMiIsICJJR0hBMSIsIklHSEczIiksIGMoIklHSEc0IikpCiMgZ3IgPC0gc2V0X25hbWVzKGMoIkwxIiwiTDQiKSkKIyAKIyBEIDwtIG1hcDIoZ3IsIGZlYXR1cmVfbGlzdCwgfiB7CiMgICBEIDwtIERFR3NfdGFibGUgJT4lCiMgICBmaWx0ZXIoZ2VuZSAlaW4lIC55KSAlPiUKIyAgIGZpbHRlciguLCAhKGdyZXBsKCIwfF4zfDl8XjEwJHxeMTEkfF4xMiR8XjR8XjIiLCAuJHN1Ymdyb3VwKSkpICU+JQojICAgIGZpbHRlciguLCAoZ3JlcGwoLngsIC4kY29tYikpKSAKIyB9KQojIAojIEQgPC0gYmluZF9yb3dzKEQpCiMgRCA8LSBEJEwxCiMgRCA8LSBEJEw0CgpEIDwtIERFR3NfdGFibGUgJT4lCiAgICBmaWx0ZXIoZ2VuZSAlaW4lIGZlYXR1cmVzKSAlPiUKICAgICNmaWx0ZXIoLiwgIShncmVwbCgiMHxeM3w5fF4xMCR8XjExJHxeMTIkfF40fF4yIiwgLiRzdWJncm91cCkpKSAjJT4lCiAgICBmaWx0ZXIoIWdyZXBsKCJeMTEkfF4xMiQiLCBsYXllcnMpKQogICAgI2ZpbHRlciguLCAoZ3JlcGwoIkwxfEw0IiwgLiRjb21iKSkpIAoKc2lnX2RmIDwtIEQgJT4lCiAgc2VsZWN0KGNvbWIsIHBfdmFsX2FkaiwgY2x1c3RlciwgZ2VuZSwgbGF5ZXJzKSAlPiUKICBtdXRhdGUobGF5ZXJzID0gZmFjdG9yKC4kbGF5ZXJzLCBsZXZlbHMgPSBvcmQgKSkgJT4lCiAgc2VwYXJhdGUoY29tYiwgaW50byA9IGMoImdyb3VwMSIsICJncm91cDIiKSwgc2VwID0gIi0iKSAlPiUKICByZW5hbWUoZmVhdHVyZSA9IGdlbmUpICU+JSAgIyBhbGlnbiBuYW1lcwogIG11dGF0ZShzdGVwID0gcGFzdGUwKGZlYXR1cmUsICJfIiwgbGF5ZXJzKSkgJT4lCiAgbXV0YXRlKHAuYWRqLnNpZ25pZiA9IGNhc2Vfd2hlbigKICAgIHBfdmFsX2FkaiA8IDAuMDAxIH4gIioqKiIsCiAgICBwX3ZhbF9hZGogPCAwLjAxICB+ICIqKiIsCiAgICBwX3ZhbF9hZGogPCAwLjA1ICB+ICIqIiwKICAgIFRSVUUgICAgICAgICAgICAgIH4gIm5zIgogICkpICU+JQogIGxlZnRfam9pbigKICAgIHRlbXAgJT4lCiAgICAgIGdyb3VwX2J5KGZlYXR1cmUsIGxheWVycywgZ3JvdXBzKSAlPiUKICAgICAgc3VtbWFyaXNlKHltYXggPSBtYXgodmFsLCBuYS5ybSA9IFRSVUUpLCAuZ3JvdXBzID0gImRyb3AiKSwKICAgIGJ5ID0gYygiZmVhdHVyZSIsICJsYXllcnMiID0gImxheWVycyIsICJncm91cDIiID0gImdyb3VwcyIpCiAgKSAlPiUKICBtdXRhdGUoeS5wb3NpdGlvbiA9IHltYXggKyAwKSAlPiUgICMgMC41IGFib3ZlIG1heCBwb2ludAogIGZpbHRlcihwLmFkai5zaWduaWYgIT0gIm5zIikKCiMgZGV2Lm5ldyh3aWR0aD02LjcsIGhlaWdodD00LjUsIG5vUlN0dWRpb0dEID0gVFJVRSkgCiMgZGV2Lm5ldyh3aWR0aD05LCBoZWlnaHQ9OSwgbm9SU3R1ZGlvR0QgPSBUUlVFKSAKKHBsb3QgPC0gUCArIGdncHVicjo6c3RhdF9wdmFsdWVfbWFudWFsKAogICAgc2lnX2RmLAogICAgc3RlcC5ncm91cC5ieSA9ICJzdGVwIiwKICAgIHN0ZXAuaW5jcmVhc2UgPSAwLjA5LAogICAgbGFiZWwgPSAicC5hZGouc2lnbmlmIiwKICAgIHkucG9zaXRpb24gPSBzaWdfZGYkeS5wb3NpdGlvbiwgICAjIHVzZSBjb21wdXRlZCB5CiAgICB4bWluID0gImdyb3VwMSIsCiAgICB4bWF4ID0gImdyb3VwMiIsCiAgICB0aXAubGVuZ3RoID0gMC4wMSwKICAgIGNvb3JkLmZsaXAgPSBUUlVFCiAgICApKQojIGdnc2F2ZSgiLi9GaWd1cmVzLzA0L3NpZ19hbGxfbGV2ZWxfY29tcF9JZ0dfSWdBLnBuZyIsIHBsb3QsIHdpZHRoID0gOSwgaGVpZ2h0ID0gNC41KQpgYGAKCmBgYHtyIGZpZy53aWR0aD02LjUsZmlnLmhlaWdodD00fQpmZWF0dXJlcyA8LSBjKCJJR0hBMSIsIklHSEcxIiwgIkNEODEiLCAiSUdLQyIsICJKQ0hBSU4iKQojIGRldi5uZXcod2lkdGg9Ni41LCBoZWlnaHQ9NCwgbm9SU3R1ZGlvR0QgPSBUUlVFKSAKQTEgPC0gREVHc19kZiAlPiUKICBmaWx0ZXIoKGdyZXBsKCJCYXNhbHxeMSQiLCAuJGxheWVycykpKSAlPiUKICBmaWx0ZXIoKGdyZXBsKCJMMXxMMiIsIC4kZ3JvdXBzKSkpICU+JQogIGZpbHRlcihmZWF0dXJlICVpbiUgZmVhdHVyZXMpICU+JQogIHZpb2xpbl9tZWFuX3Bsb3QoKSArIGdlb21fdmlvbGluKGZpbGwgPSAidHJhbnNwYXJlbnQiKQpgYGAKCmBgYHtyIGZpZy53aWR0aD05LGZpZy5oZWlnaHQ9NC41fQpmZWF0dXJlcyA8LSBjKCJJR0hHNCIsICJJR0hHMSIsICJJR0hHMiIsICJJR0hBMiIsICJJR0hBMSIsIklHSEczIikKIyBkZXYubmV3KHdpZHRoPTksIGhlaWdodD00LjUsIG5vUlN0dWRpb0dEID0gVFJVRSkgCkIgPC0gREVHc19kZiAlPiUKICBmaWx0ZXIoLiwgIShncmVwbCgiMHxeM3w5fF4xMCR8XjExJHxeMTIkfF40fF4yIiwgLiRsYXllcnMpKSkgJT4lCiAgZmlsdGVyKGZlYXR1cmUgJWluJSBmZWF0dXJlcykgJT4lCiAgdmlvbGluX21lYW5fcGxvdCgpICsgY29vcmRfZmxpcChjbGlwID0gRikgKwogIHRoZW1lX21pbmltYWwoKSArIE5vTGVnZW5kKCkgCgpzaWdfZmlsdCA8LSBmaWx0ZXIoc2lnX2RmLCAhKGdyZXBsKCIwfF4zfDl8XjEwJHxeMTEkfF4xMiR8XjR8XjIiLCBzaWdfZGYkbGF5ZXJzKSkpCgooQiA8LSBCICsgZ2dwdWJyOjpzdGF0X3B2YWx1ZV9tYW51YWwoCiAgICBzaWdfZmlsdCwKICAgIHN0ZXAuZ3JvdXAuYnkgPSAic3RlcCIsCiAgICBzdGVwLmluY3JlYXNlID0gMC4wOSwKICAgIGxhYmVsID0gInAuYWRqLnNpZ25pZiIsCiAgICB5LnBvc2l0aW9uID0gc2lnX2ZpbHQkeS5wb3NpdGlvbiwgICAjIHVzZSBjb21wdXRlZCB5CiAgICB4bWluID0gImdyb3VwMSIsCiAgICB4bWF4ID0gImdyb3VwMiIsCiAgICB0aXAubGVuZ3RoID0gMC4wMSwKICAgIGNvb3JkLmZsaXAgPSBUUlVFCiAgICApKQpgYGAKCmBgYHtyIGdlbmVzLW9uLXRpc3N1ZV9hbGxfSUQsIGZpZy53aWR0aD04LGZpZy5oZWlnaHQ9OH0KIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwojIFBMT1RUSU5HIE9OIFRJU1NVRSAjCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKY29sID0gYygiI0VGRURGNSIsICIjREFEQUVCIiwgIiNCQ0JEREMiLCAiIzlFOUFDOCIsICIjODA3REJBIiwgIiM2QTUxQTMiLCAiIzU0Mjc4RiIsICIjM0YwMDdEIikKZ2VuZWlkIDwtIGMoIklHSEc0IiwgIklHTEMyIiwgIklHSEcxIiwgIklHSEEyIiwgIklHSEExIiwgIkNEODEiLCAiSUdLQyIsICJKQ0hBSU4iKQoKIyBnZ3NhdmUoIi4vRmlndXJlcy8wMiYwMy9UaXNzdWVfSW1tdW5vLnBuZyIsIHAsIHdpZHRoID0gMTIuNSwgaGVpZ2h0ID0gMTIuNSwgYmcgPSAid2hpdGUiKSAjLCBkcGkgPSAzMDAKIyBkZXYubmV3KGhlaWdodD0zLCB3aWR0aD03LCBub1JTdHVkaW9HRCA9IFRSVUUpCnBsb3RzX2FsbCA8LSBnZW5laWQgJT4lCiAgbWFwKC4sIH5wbG90X3NwYXRpYWwuZnVuKAogICAgICBEQVRBLAogICAgICBzYW1wbGVpZCA9IHNhbXBsZV9pZCwKICAgICAgc2F2ZV9zcGFjZSA9IFQsCiAgICAgIGNvbG9ycyA9IGNvbCwgCiAgICAgIGdlbmVpZCA9IC54LAogICAgICB6b29tID0gInpvb20iLAogICAgICBuY29sID0gNCwKICAgICAgaW1nX2FscGhhID0gMCwKICAgICAgcG9pbnRfc2l6ZSA9IC41KQogICAgKQoKIyBkZXYubmV3KHdpZHRoPTgsIGhlaWdodD04LCBub1JTdHVkaW9HRCA9IFRSVUUpCnBsb3RzX2FsbFtbMV1dCgojIyMjIyMjIyMjIyMjIyMjCiMgU0FWRSBSRVNVTFRTICMKIyMjIyMjIyMjIyMjIyMjIwpwZGYoZmlsZT1wYXN0ZTAoIi4vRmlndXJlcy8wNC9UaXNzdWVfSW1tdW5vX2FsbC5wZGYiKSwgCiAgICAjd2lkdGggPSA4LjUsIGhlaWdodCA9IDEwICMgRXBpCiAgICB3aWR0aCA9IDgsIGhlaWdodCA9IDggIyBTdWIKKQpwbG90c19hbGwKZGV2Lm9mZigpCgpgYGAKCmBgYHtyIG9uX3Rpc3N1ZSwgZmlnLndpZHRoPTQsZmlnLmhlaWdodD0zLjN9CiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKIyBQTE9UVElORyBPTiBUSVNTVUUgIwojIyMjIyMjIyMjIyMjIyMjIyMjIyMjCnNhbXBsZV9pZF8gPC0gYygiUDA1NyIsIlAwNDQiKQoKCnBsb3RzX3JlcCA8LSBnZW5laWQgJT4lCiAgbWFwKC4sIH5wbG90X3NwYXRpYWwuZnVuKAogICAgICBEQVRBLAogICAgICBzYW1wbGVpZCA9IHNhbXBsZV9pZF8sCiAgICAgIHNhdmVfc3BhY2UgPSBGLAogICAgICBjb2xvcnMgPSBjb2wsIAogICAgICBnZW5laWQgPSAueCwKICAgICAgem9vbSA9ICJ6b29tIiwKICAgICAgbmNvbCA9IDQsCiAgICAgIGltZ19hbHBoYSA9IDAsCiAgICAgIHBvaW50X3NpemUgPSAuNSkKICAgICkKIyBkZXYubmV3KHdpZHRoPTMuMywgaGVpZ2h0PTIsIG5vUlN0dWRpb0dEID0gVFJVRSkKcGxvdHNfcmVwW1sxXV0KCkEyIDwtIHBsb3RfZ3JpZChwbG90c19yZXBbWzhdXSwgcGxvdHNfcmVwW1s1XV0sIG5jb2wgPSAxKQojIGdnc2F2ZSgiLi9GaWd1cmVzLzA0L29uX3Rpc3N1ZS5wbmciLCBCLCB3aWR0aCA9IDQsIGhlaWdodCA9IDMuMywgYmcgPSAid2hpdGUiLCBkcGkgPSA1MDApICMsIGRwaSA9IDMwMApgYGAKCmBgYHtyIEZpZ3VyZTRBLCBmaWcud2lkdGg9Ni43LGZpZy5oZWlnaHQ9M30KIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwojIENPTUJJTkUgUEFORUwgQSBBTkQgQiAjCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKIyBkZXYubmV3KHdpZHRoPTYuNywgaGVpZ2h0PTMsIG5vUlN0dWRpb0dEID0gVFJVRSkgCihBIDwtIHBsb3RfZ3JpZChBMSwgQTIsIHJlbF93aWR0aHMgPSBjKDEsIDEpKSkgIyBsYWJlbHMgPSBjKCJhIiwgImIiKQojIGdnc2F2ZSgiLi9GaWd1cmVzLzA0L0ZpZ3VyZV80LnBuZyIsIHAsIHdpZHRoID0gNi43LCBoZWlnaHQgPSAzLjMsIGJnID0gIndoaXRlIikgIywgZHBpID0gMzAwCmBgYAoKYGBge3IgZmlnLndpZHRoPTgsZmlnLmhlaWdodD05fQojIGNoZWNrcyBpZiB0aGUgbWVhbiBkaWZmZXJlbmNlIGluIGV4cHJlc3Npb24gaXMgcmVmbGVjdGVkIGluIGVhY2ggc2FtcGxlCiMgb3IgYmlhc2VkIGJ5IGEgc2luZ2xlIHNhbXBsZSwgYnkgcGxvdHRpbmcgb24gc2FtcGxlIGxldmVsCgp2aW9saW5fc2FtcGxlX3Bsb3QgPC0gZnVuY3Rpb24oREVHc19kZil7CiAgbSA8LSBtYXgobmEub21pdChERUdzX2RmW1sidmFsIl1dKSkvMSAjIHRyeSBlLmcgMgogIERFR3NfZGYgJT4lCiAgICBnZ3Bsb3QoYWVzKHg9b3JpZy5pZGVudCwgeT12YWwsIGNvbD1ncm91cHMpKSArCiAgICBnZW9tX3Zpb2xpbigpICsgIyB7aWYobGVuZ3RoKGZlYXR1cmUgPT0gMSkpIGdndGl0bGUoZmVhdHVyZSl9ICsKICAgICNnZW9tX2JveHBsb3QoZmlsbCA9ICJ0cmFuc3BhcmVudCIsIG5vdGNoID0gVCwgb3V0bGllci5zaXplID0gLjUsIG91dGxpZXIuY29sb3VyID0gInJlZCIpICsKICAgICNnZW9tX2ppdHRlcih3aWR0aCA9IDAuMywgaGVpZ2h0ID0gMC4yLCBhbHBoYSA9IDAuMiwgc2l6ZT0uMDEpICsKICAgIHN0YXRfc3VtbWFyeShhZXMoeSA9IHZhbCksIGZ1bj1tZWRpYW4sIGdlb209ImNyb3NzYmFyIiwgbGluZXdpZHRoPS4yLCBjb2xvcj0iYmxhY2siKSArCiAgICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gY29sKSArIHlsYWIoIkV4cHJlc3Npb24iKSArCiAgICBteV90aGVtZSArIE5vTGVnZW5kKCkgKyAjeGxpbShjKDAsIG0pKSArCiAgICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSA5KSwKICAgICAgICAgIHBsb3QubWFyZ2luID0gdW5pdChjKC0wLC0yLDEsLTYpLHVuaXRzID0gInB0IiksCiAgICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBoanVzdCA9IDAuNSwgbWFyZ2luID0gbWFyZ2luKGIgPSAwKSksCiAgICAgICAgICBheGlzLmxpbmUgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDMwLCBoanVzdD0xKQogICAgICAgICAgI3BhbmVsLmJvcmRlciA9IGVsZW1lbnRfcmVjdChjb2xvdXIgPSAiZ3JheSIpCiAgICAgICAgICApICsKICAgICMgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF9ibGFuaygpLAogICAgIyAgICAgICApICsKICAgICNmYWNldF93cmFwKH4uZGF0YVtbZmFjZXRdXSwgbmNvbCA9IG5jb2wsIHN0cmlwLnBvc2l0aW9uID0gYygicmlnaHQiLCAiYm90dG9tIiwgImxlZnQiLCAidG9wIikpCiAgICBmYWNldF9ncmlkKHJvd3MgPSB2YXJzKGxheWVycyksIGNvbHMgPSB2YXJzKGdyb3VwcyksIHNjYWxlID0iZnJlZSIsIHNwYWNlID0iZnJlZSIgKSAjLCBzdHJpcC5wb3NpdGlvbiA9IGMoInJpZ2h0IiwgImJvdHRvbSIsICJsZWZ0IiwgInRvcCIpKQp9CmZlYXR1cmUgPC0gYygiSUdIRzQiLCAiSUdIRzEiLCAiSUdIQTIiLCAiSUdIQTEiLCJJR0hHMyIpCmZlYXR1cmVfIDwtIGMoIklHSEcxIikKY29sIDwtIGMoIkwxIj0iIzU2QjRFOSIsIkwyIj0iIzAwOUU3MyIsIkwzIj0iI0NDNzlBNyIsICJMNCI9IiNGQzhENjIiKQpmYWNldCA8LSAibGF5ZXJzIgpncm91cC5ieSA8LSAib3JpZy5pZGVudCIKbmNvbCA8LSAxCiMgZGV2Lm5ldyh3aWR0aD0xNSwgaGVpZ2h0PTksIG5vUlN0dWRpb0dEID0gVFJVRSkgCiMgcGxvdHMgaW5kaXZpZHVhbCBncm91cHMgKEwxLUw0KSBhdCBzYW1wbGUgbGV2ZWwKcGxvdHMgPC0gbWFwKHNldF9uYW1lcyhmZWF0dXJlKSwgfiB7CiAgUCA8LSBERUdzX2RmICU+JQogICAgZmlsdGVyKGZlYXR1cmUgJWluJSAueCkgJT4lCiAgICBmaWx0ZXIoIWdyZXBsKCJeMTEkfF4xMiR8XjEwJHw5fF4yfF4wfF4zfDQiLCBsYXllcnMpKSAlPiUKICAgICNmaWx0ZXIoZ3JlcGwoLngsIGdyb3VwcykpICU+JQogICAgdmlvbGluX3NhbXBsZV9wbG90KCkgKyBnZW9tX3Zpb2xpbihmaWxsID0gInRyYW5zcGFyZW50IikgKwogICAgZ2d0aXRsZShwYXN0ZTAoLngpKQp9KQpwbG90cyRJR0hHMQpQIDwtIHBsb3RfZ3JpZChwbG90bGlzdCA9IHBsb3RzLCBuY29sID0gMSkKIyBnZ3NhdmUoIi4vRmlndXJlcy8wNC9zYW1wbGVfbGV2ZWxfY29tcF8ucG5nIiwgUCwgd2lkdGggPSA2LjcsIGhlaWdodCA9IDIwKSAjLCBkcGkgPSAzMDAKYGBgCgpgYGB7ciBmaWcud2lkdGg9OCxmaWcuaGVpZ2h0PTl9CiMgZGV2Lm5ldyh3aWR0aD04LCBoZWlnaHQ9OSwgbm9SU3R1ZGlvR0QgPSBUUlVFKSAKIyBhbGwgZ3JvdXBzIChMMS1MNCkgYWNyb3NzIGFsbCBsYXllcnMKcCA8LSBERUdzX2RmICU+JQogICMgZmlsdGVyKCEoZmVhdHVyZSAlaW4lIGMoIkNEODEiKSkpICAlPiUKICB2aW9saW5fbWVhbl9wbG90KCkKIyBnZ3NhdmUoIi4vRmlndXJlcy8wNC9GaWdfdmlvbC5wbmciLCBBLCB3aWR0aCA9IDYuNywgaGVpZ2h0ID0gMykgIywgZHBpID0gMzAwCgpgYGAKCmBgYHtyIGZpZy53aWR0aD04LGZpZy5oZWlnaHQ9N30KIyBkZXYubmV3KHdpZHRoPTgsIGhlaWdodD03LCBub1JTdHVkaW9HRCA9IFRSVUUpIAojIEwxIGFuZCBMMiBvbmx5IGFjcm9zcyBhbGwgbGF5ZXJzCnAgPC0gREVHc19kZiAlPiUgCiAgZmlsdGVyKChncmVwbCgiTDF8TDIiLCAuJGdyb3VwcykpKSAlPiUgCiAgdmlvbGluX21lYW5fcGxvdCgpCmBgYAoKYGBge3IgcGxvdC1zZWxlY3RlZC1sYXllcnMsIGZpZy53aWR0aD00LGZpZy5oZWlnaHQ9NCwgZXZhbD1GQUxTRX0KZmVhdHVyZSA8LSBjKCJJR0hBMSIsIklHSEcxIiwgIkNEODEiLCAiSUdLQyIsICJKQ0hBSU4iKQpmZWF0dXJlIDwtIGMoIklHSEExIiwiSUdIRzEiLCAiSUdIRzMiLCAiSUdLQyIsICJJR0hHNCIpCgpERUdzX2RmIDwtIERFR3NfZGYgJT4lCiAgZmlsdGVyKChncmVwbCgiTDF8TDIiLCAuJGdyb3VwcykpKSAlPiUgCiAgZmlsdGVyKChncmVwbCgiQmFzYWx8XjEkIiwgLiRsYXllcnMpKSkgJT4lCiAgZmlsdGVyKGZlYXR1cmUgJWluJSBmZWF0dXJlKSAKCiMgZ3JvdXBzIG9uIHgtYXhpcywgZ2VuZXMgb24geCBheGlzCiMgdXNlZCBmb3IgZmlndXJlIDQKdmlvbGluX21lYW5fcGxvdCA8LSBmdW5jdGlvbihERUdzX2RmKXsKICBtIDwtIG1heChuYS5vbWl0KERFR3NfZGZbWyJ2YWwiXV0pKS8xICMgdHJ5IGUuZyAyCiAgREVHc19kZiAlPiUKICAgIGdncGxvdChhZXMoeD0uZGF0YVtbZ3JvdXAuYnldXSwgeT0uZGF0YVtbInZhbCJdXSwgY29sPS5kYXRhW1tncm91cC5ieV1dKSkgKwogICAgZ2VvbV92aW9saW4oKSArICMge2lmKGxlbmd0aChmZWF0dXJlID09IDEpKSBnZ3RpdGxlKGZlYXR1cmUpfSArCiAgICBzdGF0X3N1bW1hcnkoYWVzKHkgPSB2YWwpLCBmdW49bWVkaWFuLCBnZW9tPSJjcm9zc2JhciIsIGxpbmV3aWR0aD0uMywgY29sb3I9ImJsYWNrIikgKwogICAgI2dlb21fYm94cGxvdChmaWxsID0gInRyYW5zcGFyZW50Iiwgbm90Y2ggPSBULCBvdXRsaWVyLnNpemUgPSAuNSwgb3V0bGllci5jb2xvdXIgPSAicmVkIikgKwogICAgZ2VvbV9qaXR0ZXIod2lkdGggPSAwLjMsIGhlaWdodCA9IDAuMiwgYWxwaGEgPSAwLjIsIHNpemU9LjAxKSArCiAgICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gY29sKSArIHlsYWIoIkV4cHJlc3Npb24iKSArCiAgICBteV90aGVtZSArIE5vTGVnZW5kKCkgKyAjeGxpbShjKDAsIG0pKSArCiAgICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICAgICAgICBheGlzLmxpbmUgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgICBwYW5lbC5ib3JkZXIgPSBlbGVtZW50X3JlY3QoY29sb3VyID0gImdyYXkiKSApICsKICAgICMgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAzMCwgaGp1c3Q9MSksCiAgICAjICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpLAogICAgIyAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X2JsYW5rKCksCiAgICAjICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfYmxhbmsoKSkgKwogICAgI2ZhY2V0X3dyYXAofi5kYXRhW1tmYWNldF1dLCBuY29sID0gbmNvbCwgc3RyaXAucG9zaXRpb24gPSBjKCJyaWdodCIsICJib3R0b20iLCAibGVmdCIsICJ0b3AiKSkKICAgIGZhY2V0X2dyaWQocm93cyA9IHZhcnMobGF5ZXJzKSwgY29scyA9IHZhcnMoZmVhdHVyZSkpICMsIHN0cmlwLnBvc2l0aW9uID0gYygicmlnaHQiLCAiYm90dG9tIiwgImxlZnQiLCAidG9wIikpCn0KCiMgZGV2Lm5ldyh3aWR0aD0zLjMsIGhlaWdodD0zLCBub1JTdHVkaW9HRCA9IFRSVUUpIApBIDwtIHZpb2xpbl9tZWFuX3Bsb3QoREVHc19kZikKIyBnZ3NhdmUoIi4vRmlndXJlcy8wNC9GaWdfTDFfTDJfdmlvbC5wbmciLCBBLCB3aWR0aCA9IDQsIGhlaWdodCA9IDQsIGRwaSA9IDUwMCkgIywgZHBpID0gMzAwCkEKYGBgCgoKCmBgYHtyIEZJR1VSRTQsIGZpZy53aWR0aD02LjcsZmlnLmhlaWdodD03fQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCiMgQ09NQklORSBQQU5FTCBBIEFORCBCICMKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwojIGRldi5uZXcod2lkdGg9Ni43LCBoZWlnaHQ9Nywgbm9SU3R1ZGlvR0QgPSBUUlVFKSAKKEZJR1VSRTQgPC0gcGxvdF9ncmlkKEEsIEIsIG5jb2wgPSAxLCByZWxfaGVpZ2h0cyA9IGMoMywgNCkpKSAjIGxhYmVscyA9IGMoImEiLCAiYiIpCiMgZ2dzYXZlKCIuL0ZpZ3VyZXMvMDQvRmlndXJlXzQucG5nIiwgcCwgd2lkdGggPSA2LjcsIGhlaWdodCA9IDMuMywgYmcgPSAid2hpdGUiKSAjLCBkcGkgPSAzMDAKYGBgCgo=