This is an R Markdown Notebook. When you execute code within the notebook, the results appear beneath the code.
Try executing this chunk by clicking the Run button within the chunk or by placing your cursor inside it and pressing Ctrl+Shift+Enter.
rm(list = ls())
gc()
used (Mb) gc trigger (Mb) max used (Mb)
Ncells 585283 31.3 1238594 66.2 1238594 66.2
Vcells 1457144 11.2 8388608 64.0 7583308 57.9
# si no andan los paths, setear esa siguiente linea
#setwd("acá va el path hasta el directorio 'neuro'")
library(brainGraph)
Loading required package: igraph
Attaching package: 㤼㸱igraph㤼㸲
The following objects are masked from 㤼㸱package:stats㤼㸲:
decompose, spectrum
The following object is masked from 㤼㸱package:base㤼㸲:
union
Registered S3 method overwritten by 'dplyr':
method from
print.rowwise_df
Registered S3 methods overwritten by 'htmltools':
method from
print.html tools:rstudio
print.shiny.tag tools:rstudio
print.shiny.tag.list tools:rstudio
Registered S3 method overwritten by 'htmlwidgets':
method from
print.htmlwidget tools:rstudio
Registered S3 method overwritten by 'data.table':
method from
print.data.table
library(igraph)
library(ggplot2)
library(tidyr)
Attaching package: 㤼㸱tidyr㤼㸲
The following object is masked from 㤼㸱package:igraph㤼㸲:
crossing
source(paste0(getwd(),"/red_por_densidad.R"))
# se generan todos los grafos individuales para cada sujeto en cada estadio de sue?o para cada delta
seq <- seq(from = 0.025, to = 0.15, by = 0.005)
suj.count <- 18
N1 <- array(dim = length(seq))
N2 <- array(dim = length(seq))
N3 <- array(dim = length(seq))
W <- array(dim = length(seq))
for(i in 1:length(seq)) {
tmpN1 <- array(dim = suj.count)
tmpN2 <- array(dim = suj.count)
tmpN3 <- array(dim = suj.count)
tmpW <- array(dim = suj.count)
for (j in 1:18) {
tmp <- read.table( paste0(getwd(),paste0("/datasets/DataSujetos/N1_suj",j,".csv")), header=F, sep = ",")
result <- red.por.densidad(tmp, seq[i])
tmpN1[j] <- list(grafo = result$red)
tmp <- read.table( paste0(getwd(),paste0("/datasets/DataSujetos/N2_suj",j,".csv")), header=F, sep = ",")
result <- red.por.densidad(tmp, seq[i])
tmpN2[j] <- list(grafo = result$red)
tmp <- read.table( paste0(getwd(),paste0("/datasets/DataSujetos/N3_suj",j,".csv")), header=F, sep = ",")
result <- red.por.densidad(tmp, seq[i])
tmpN3[j] <- list(grafo = result$red)
tmp <- read.table( paste0(getwd(),paste0("/datasets/DataSujetos/W_suj",j,".csv")), header=F, sep = ",")
result <- red.por.densidad(tmp, seq[i])
tmpW[j] <- list(grafo = result$red)
}
N1[i] <- list(tmpN1)
N2[i] <- list(tmpN2)
N3[i] <- list(tmpN3)
W[i] <- list(tmpW)
}
[1] "Warning!, density 0.025 aproximada con error -0.000187406296851572"
[1] "Warning!, density 0.025 aproximada con error -0.000187406296851572"
[1] "Warning!, density 0.03 aproximada con error 0.000164917541229388"
[1] "Warning!, density 0.03 aproximada con error 0.000164917541229388"
[1] "Warning!, density 0.04 aproximada con error 0.000119940029985006"
[1] "Warning!, density 0.04 aproximada con error -0.000179910044977506"
[1] "Warning!, density 0.055 aproximada con error -0.000172413793103447"
[1] "Warning!, density 0.06 aproximada con error 0.000179910044977513"
[1] "Warning!, density 0.07 aproximada con error -0.000164917541229381"
[1] "Warning!, density 0.07 aproximada con error 0.000134932533733131"
[1] "Warning!, density 0.07 aproximada con error 0.000134932533733131"
[1] "Warning!, density 0.075 aproximada con error 0.000187406296851586"
[1] "Warning!, density 0.075 aproximada con error -0.000112443778110927"
[1] "Warning!, density 0.085 aproximada con error 0.00014242878560719"
[1] "Warning!, density 0.085 aproximada con error -0.000157421289355322"
[1] "Warning!, density 0.085 aproximada con error -0.000157421289355322"
[1] "Warning!, density 0.085 aproximada con error -0.000157421289355322"
[1] "Warning!, density 0.085 aproximada con error 0.00014242878560719"
[1] "Warning!, density 0.085 aproximada con error 0.000292353823088454"
[1] "Warning!, density 0.085 aproximada con error -0.000157421289355322"
[1] "Warning!, density 0.09 aproximada con error 0.000194902548725631"
[1] "Warning!, density 0.1 aproximada con error 0.000149925037481263"
[1] "Warning!, density 0.1 aproximada con error 0.000149925037481263"
[1] "Warning!, density 0.1 aproximada con error 0.000149925037481263"
[1] "Warning!, density 0.1 aproximada con error -0.000149925037481263"
[1] "Warning!, density 0.11 aproximada con error 0.000104947526236895"
[1] "Warning!, density 0.11 aproximada con error 0.000104947526236895"
[1] "Warning!, density 0.125 aproximada con error 0.000112443778110941"
[1] "Warning!, density 0.125 aproximada con error 0.000112443778110941"
[1] "Warning!, density 0.125 aproximada con error -0.000337331334332835"
[1] "Warning!, density 0.125 aproximada con error 0.000112443778110941"
[1] "Warning!, density 0.13 aproximada con error -0.000284857571214381"
[1] "Warning!, density 0.13 aproximada con error -0.000134932533733118"
[1] "Warning!, density 0.13 aproximada con error -0.000134932533733118"
[1] "Warning!, density 0.14 aproximada con error -0.000179910044977499"
[1] "Warning!, density 0.14 aproximada con error 0.000119940029985027"
[1] "Warning!, density 0.14 aproximada con error 0.000119940029985027"
[1] "Warning!, density 0.14 aproximada con error -0.000179910044977499"
[1] "Warning!, density 0.14 aproximada con error -0.000179910044977499"
[1] "Warning!, density 0.14 aproximada con error 0.000119940029985027"
[1] "Warning!, density 0.145 aproximada con error -0.000127436281859072"
[1] "Warning!, density 0.145 aproximada con error 0.000172413793103454"
louvain_n1<-louvain_n2<-louvain_n3<-louvain_w<-list()
degree_n1<-degree_n2<-degree_n3<-degree_w<-list()
z_score_n1<-z_score_n2<-z_score_n3<-z_score_w<-list()
p_factor_n1<-p_factor_n2<-p_factor_n3<-p_factor_w<-list()
for(i in 1:length(seq)){ # itero sobre los deltas
louvain_n1[[i]] <- louvain_n2[[i]] <- louvain_n3[[i]] <- louvain_w[[i]] <- list()
degree_n1[[i]] <- degree_n2[[i]] <- degree_n3[[i]] <- degree_w[[i]] <- list()
z_score_n1[[i]] <- z_score_n2[[i]] <- z_score_n3[[i]] <- z_score_w[[i]] <- list()
p_factor_n1[[i]] <- p_factor_n2[[i]] <- p_factor_n3[[i]] <- p_factor_w[[i]]<-list()
for (j in 1:suj.count) {#itero sobre los sujetos
louvain_n1[[i]][[j]] <- cluster_louvain(graph = N1[[i]][[j]], weights = NULL)
louvain_n2[[i]][[j]] <- cluster_louvain(graph = N2[[i]][[j]], weights = NULL)
louvain_n3[[i]][[j]] <- cluster_louvain(graph = N3[[i]][[j]], weights = NULL)
louvain_w[[i]][[j]] <- cluster_louvain(graph = W[[i]][[j]], weights = NULL)
degree_n1[[i]][[j]] <- degree(N1[[i]][[j]])
degree_n2[[i]][[j]]<- degree(N3[[i]][[j]])
degree_n3[[i]][[j]]<- degree(N3[[i]][[j]])
degree_w[[i]][[j]] <- degree(W[[i]][[j]])
z_score_n1[[i]][[j]] <- within_module_deg_z_score(N1[[i]][[j]], louvain_n1[[i]][[j]]$membership)
z_score_n2[[i]][[j]] <- within_module_deg_z_score(N2[[i]][[j]], louvain_n2[[i]][[j]]$membership)
z_score_n3[[i]][[j]] <- within_module_deg_z_score(N3[[i]][[j]], louvain_n3[[i]][[j]]$membership)
z_score_w[[i]][[j]] <- within_module_deg_z_score(W[[i]][[j]], louvain_w[[i]][[j]]$membership)
p_factor_n1[[i]][[j]] <- part_coeff(N1[[i]][[j]], louvain_n1[[i]][[j]]$membership)
p_factor_n2[[i]][[j]] <- part_coeff(N2[[i]][[j]], louvain_n2[[i]][[j]]$membership)
p_factor_n3[[i]][[j]] <- part_coeff(N3[[i]][[j]], louvain_n3[[i]][[j]]$membership)
p_factor_w[[i]][[j]] <- part_coeff(W[[i]][[j]], louvain_w[[i]][[j]]$membership)
}
}
# conversion de z_score y part_coef en rol
z0<- 1
p0 <- 0.05
node_rol <- function(z,p){
result<- array(dim = length(z))
for(i in 1:length(z)){
#print(result)
#print(i)
if (is.na(z[i]) | is.na(p[i])){}
else if (z[i]>z0 & p[i]>p0 ){result[i] <- 'Hub'}
else if (z[i]>z0 & p[i]<p0 ) {result[i] <- 'Provincial Hub'}
else if (z[i]<z0 & p[i]<p0 ) {result[i] <- 'Provincial Node'}
else if (z[i]<z0 & p[i]>p0 ) {result[i] <- 'Connector Node'}
}
return(result)
}
role_count_n1 <- list()
role_count_n2 <- list()
role_count_n3 <- list()
role_count_w <- list()
for(i in 1:length(seq)){ # itero sobre los deltas
role_count_n1_temp_H <- role_count_n2_temp_H <- role_count_n3_temp_H <- role_count_w_temp_H <- NA
role_count_n1_temp_PH <- role_count_n2_temp_PH <- role_count_n3_temp_PH <- role_count_w_temp_PH <- NA
role_count_n1_temp_PN <- role_count_n2_temp_PN <- role_count_n3_temp_PN <- role_count_w_temp_PN <- NA
role_count_n1_temp_CN <- role_count_n2_temp_CN <- role_count_n3_temp_CN <- role_count_w_temp_CN <- NA
for (j in 1:suj.count) {#itero sobre los sujetos
temp <- node_rol(z_score_n1[[i]][[j]] , p_factor_n1[[i]][[j]])
role_count_n1_temp_H[[j]] <- length(which(temp == "Hub"))
role_count_n1_temp_PH[[j]] <- length(which(temp == "Provincial Hub"))
role_count_n1_temp_PN[[j]] <- length(which(temp == "Provincial Node"))
role_count_n1_temp_CN[[j]] <- length(which(temp == "Connector Node"))
temp <- node_rol(z_score_n2[[i]][[j]] , p_factor_n2[[i]][[j]])
role_count_n2_temp_H[[j]] <- length(which(temp == "Hub"))
role_count_n2_temp_PH[[j]] <- length(which(temp == "Provincial Hub"))
role_count_n2_temp_PN[[j]] <- length(which(temp == "Provincial Node"))
role_count_n2_temp_CN[[j]] <- length(which(temp == "Connector Node"))
temp <- node_rol(z_score_n3[[i]][[j]] , p_factor_n3[[i]][[j]])
role_count_n3_temp_H[[j]] <- length(which(temp == "Hub"))
role_count_n3_temp_PH[[j]] <- length(which(temp == "Provincial Hub"))
role_count_n3_temp_PN[[j]] <- length(which(temp == "Provincial Node"))
role_count_n3_temp_CN[[j]] <- length(which(temp == "Connector Node"))
temp <- node_rol(z_score_w[[i]][[j]] , p_factor_w[[i]][[j]])
role_count_w_temp_H[[j]] <- length(which(temp == "Hub"))
role_count_w_temp_PH[[j]] <- length(which(temp == "Provincial Hub"))
role_count_w_temp_PN[[j]] <- length(which(temp == "Provincial Node"))
role_count_w_temp_CN[[j]] <- length(which(temp == "Connector Node"))
}
role_count_n1[[i]] <- data.frame(H =role_count_n1_temp_H,
PH =role_count_n1_temp_PH,
PN =role_count_n1_temp_PN,
CN =role_count_n1_temp_CN)
role_count_n2[[i]] <- data.frame(H =role_count_n2_temp_H,
PH =role_count_n2_temp_PH,
PN =role_count_n2_temp_PN,
CN =role_count_n2_temp_CN)
role_count_n3[[i]] <- data.frame(H =role_count_n3_temp_H,
PH =role_count_n3_temp_PH,
PN =role_count_n3_temp_PN,
CN =role_count_n3_temp_CN)
role_count_w[[i]] <- data.frame(H =role_count_w_temp_H,
PH =role_count_w_temp_PH,
PN =role_count_w_temp_PN,
CN =role_count_w_temp_CN)
}
#### Creacion de Dataframe con comparaciones
rol_vector<- c("H","PH", "PN", "CN")
comparison_results_df <- NULL
for(i in 1:length(seq)){ # itero sobre los deltas
for(r in 1:length(rol_vector)){# itero sobre los roles H, PH, PN, CN
rol <- rol_vector[r]
# t.test
#p.valor.n1 <- t.test(role_count_n1[[i]][,rol],role_count_w[[i]][,rol])$p.value
#p.valor.n2 <- t.test(role_count_n2[[i]][,rol],role_count_w[[i]][,rol])$p.value
#p.valor.n3 <- t.test(role_count_n3[[i]][,rol],role_count_w[[i]][,rol])$p.value
#p.valor.w <- NA
#ANOVA
p.valor.n1 <- unlist(summary(aov(role_count_n1[[i]][,rol]~role_count_w[[i]][,rol]))[[1]])[[9]]
p.valor.n2 <- unlist(summary(aov(role_count_n2[[i]][,rol]~role_count_w[[i]][,rol]))[[1]])[[9]]
p.valor.n3 <- unlist(summary(aov(role_count_n3[[i]][,rol]~role_count_w[[i]][,rol]))[[1]])[[9]]
p.valor.w <- NA
#Wilcoxon
#p.valor.n1 <- wilcox.test(role_count_n1[[i]][,rol],role_count_w[[i]][,rol], conf.level = 0.95)$p.value
#p.valor.n2 <- wilcox.test(role_count_n2[[i]][,rol],role_count_w[[i]][,rol], conf.level = 0.95)$p.value
#p.valor.n3 <- wilcox.test(role_count_n3[[i]][,rol],role_count_w[[i]][,rol], conf.level = 0.95)$p.value
#p.valor.w <- NA
N1_mean_temp <- mean(role_count_n1[[i]][,rol])
N2_mean_temp <- mean(role_count_n2[[i]][,rol])
N3_mean_temp <- mean(role_count_n3[[i]][,rol])
W_mean_temp <- mean(role_count_w[[i]][,rol])
N1_se_temp <- sd(role_count_n1[[i]][,rol])/sqrt(length(role_count_n1[[i]][,rol]))
N2_se_temp <- sd(role_count_n2[[i]][,rol])/sqrt(length(role_count_n2[[i]][,rol]))
N3_se_temp <- sd(role_count_n3[[i]][,rol])/sqrt(length(role_count_n3[[i]][,rol]))
W_se_temp <- sd(role_count_w[[i]][,rol])/sqrt(length(role_count_w[[i]][,rol]))
comparison_results_df <- rbind(comparison_results_df,
data.frame(estadio = "N1",
rol = rol,
delta=seq[i],
mean=N1_mean_temp,
se= N1_se_temp,
p_valor = p.valor.n1) )
comparison_results_df <- rbind(comparison_results_df,
data.frame(estadio = "N2",
rol = rol,
delta=seq[i],
mean=N2_mean_temp,
se= N2_se_temp,
p_valor = p.valor.n2) )
comparison_results_df <- rbind(comparison_results_df,
data.frame(estadio = "N3",
rol = rol,
delta=seq[i],
mean=N3_mean_temp,
se= N3_se_temp,
p_valor = p.valor.n3) )
comparison_results_df <- rbind(comparison_results_df,
data.frame(estadio = "W",
rol = rol,
delta=seq[i],
mean=W_mean_temp,
se= W_se_temp,
p_valor = p.valor.w) )
}
}
#### graficos
pv_ref <- 0.05 #significancia
i<- 1
j<- 2
estadio_ref_vector<- c("N1","N2","N3")
role_ref_vector <- c("H","PH","PN", "CN")
role_name_ref_vector <- c("Hubs","Provincial Hubs","Povincial Nodes", "Connection Nodes")
for(i in 1:length(role_ref_vector)){
for(j in 1:length(estadio_ref_vector)){
estadio_ref<- estadio_ref_vector[j]
role_ref <- role_ref_vector[i]
role_name_ref <-role_name_ref_vector[i]
y_label <- paste(role_name_ref)
title_label <- paste("WAKE vs.",estadio_ref)
#title_label <- paste(role_ref,"mean count")
#y_label <- role_ref
test_df <- comparison_results_df[comparison_results_df$estadio %in% c(estadio_ref,"W") &
comparison_results_df$rol %in% c(role_ref),]
test_df<- transform(test_df, p_valor = ifelse(p_valor < pv_ref, 0, NA))
pd <- position_dodge(0.001) # move them .05 to the left and right
if (all(is.na(test_df$p_valor))) {
p<- ggplot(test_df, aes(x=delta, y=mean, colour=estadio)) +
geom_errorbar(aes(ymin=mean-se, ymax=mean+se), width=.005,position=pd) +
geom_line(position=pd) +
geom_point(position=pd) +
#geom_point(aes(y=p_valor),position=pd) +
labs(title=title_label, x = "delta", y=y_label)
} else {
p<-ggplot(test_df, aes(x=delta, y=mean, colour=estadio)) +
geom_errorbar(aes(ymin=mean-se, ymax=mean+se), width=.005,position=pd) +
geom_line(position=pd) +
geom_point(position=pd) +
geom_point(aes(y=p_valor),position=pd) +
labs(title=title_label, x = "delta", y=y_label)
}
print(p)
}
}












#grid plot
library("cowplot")
plot_grid(plots[[1]],
plots[[2]],
plots[[3]],
plots[[4]],
plots[[5]],
plots[[6]],
plots[[7]],
plots[[8]],
plots[[9]],
plots[[10]],
plots[[11]],
plots[[12]],ncol = 3)
Cannot convert object of class logical into a grob.Removed 49 rows containing missing values (geom_point).Removed 51 rows containing missing values (geom_point).Removed 47 rows containing missing values (geom_point).Removed 40 rows containing missing values (geom_point).Removed 50 rows containing missing values (geom_point).Removed 51 rows containing missing values (geom_point).

### Graficos interesantes
#forma copara de dibujar los clusters
#clp <- cluster_louvain(graph = N2_no_pesados[[1]], weights = NULL)
i<-1 # delta
j<-1 # sujeto
g<- N1[[i]][[j]]
roles <- as.factor(node_rol(z_score_n1[[i]][[j]] , p_factor_n1[[i]][[j]]))
colrs <- c("olivedrab3", "tomato","darkcyan", "gold")
V(g)$color <- colrs[roles]
clp <- cluster_louvain(graph = g, weights = NULL)
l <- layout_with_fr(g)
plot(g, layout=l,vertex.label = "" , vertex.size = 7 )
legend(x=1.2, y=0.5, levels(as.factor(roles)), pch=21,col="#777777", pt.cex=2, cex=.8, bty="n", ncol=1, pt.bg=colrs)
title("Roles en N1 - sujeto 1 - delta = 0.025", cex.main=.8)

NA
NA
NA
#Cambio de roles de los nodos
i<-1 # delta
j<-1 # sujeto
delta <- 0.065
i <- which(seq == delta)
g<- N1[[i]][[j]]
roles_n1 <- node_rol(z_score_n1[[i]][[j]] , p_factor_n1[[i]][[j]])
roles_n2 <- node_rol(z_score_n2[[i]][[j]] , p_factor_n2[[i]][[j]])
roles_n3 <-node_rol(z_score_n3[[i]][[j]] , p_factor_n3[[i]][[j]])
roles_w <- node_rol(z_score_w[[i]][[j]] , p_factor_w[[i]][[j]])
roles <- rbind(roles_n1, roles_n2)
roles <- rbind(roles, roles_n3)
roles <- rbind(roles, roles_w)
roles <- as.data.frame(roles)
rownames(roles) <- c("N1","N2","N3","W")
regions <- read.table( paste0(getwd(),"/datasets/aal_no_rep.csv"), header=F, sep = ",")
colnames(roles) <- regions[,1]
#roles[is.na(roles)] <- ""
roles <-as.data.frame(t(roles))
str(roles)
'data.frame': 116 obs. of 4 variables:
$ N1: Factor w/ 4 levels "Connector Node",..: 1 2 2 2 4 4 2 2 4 4 ...
..- attr(*, "names")= chr "Precentral_L" "Precentral_R" "Frontal_Sup_L" "Frontal_Sup_R" ...
$ N2: Factor w/ 4 levels "Connector Node",..: 1 1 2 2 4 4 2 2 4 3 ...
..- attr(*, "names")= chr "Precentral_L" "Precentral_R" "Frontal_Sup_L" "Frontal_Sup_R" ...
$ N3: Factor w/ 4 levels "Connector Node",..: 1 2 2 2 4 1 2 1 4 1 ...
..- attr(*, "names")= chr "Precentral_L" "Precentral_R" "Frontal_Sup_L" "Frontal_Sup_R" ...
$ W : Factor w/ 4 levels "Connector Node",..: 1 4 3 2 4 1 2 1 4 NA ...
..- attr(*, "names")= chr "Precentral_L" "Precentral_R" "Frontal_Sup_L" "Frontal_Sup_R" ...
plot(roles)

View(roles)
roles_sin_nas <- roles[(!is.na(roles$N1) & !is.na(roles$N2) & !is.na(roles$N3) & !is.na(roles$W)),]
roles_sin_repetidos <- roles[(roles$N1 != roles$N2)
| (roles$N1 != roles$N3)
| (roles$N1 != roles$W)
| (roles$N2 != roles$N3)
| (roles$N2 != roles$W)
| (roles$N3 != roles$W),]
roles_sin_repetidos <- na.omit(roles_sin_repetidos)
roles_sin_repetidos$region<-rownames(roles_sin_repetidos)
View(roles_sin_repetidos)
roles_sin_repetidos <- as.data.frame(roles_sin_repetidos)
# separamos en 3 porque no se ven bien todos en 1 gráfico
roles_sin_repetidos_1 <- roles_sin_repetidos[1:26,]
roles_sin_repetidos_2 <- roles_sin_repetidos[27:52,]
roles_sin_repetidos_3 <- roles_sin_repetidos[53:78,]
roles_sin_repetidos_1 %>% gather(delta,value, N1,N2,N3,W) %>%
ggplot() +
geom_point(aes(x=delta, y=region, colour=value), size=3) +
ylab(label="Región del cerebro") +
xlab(label = "Estadío del sueño")

roles_sin_repetidos_2 %>% gather(delta,value, N1,N2,N3,W) %>%
ggplot() +
geom_point(aes(x=delta, y=region, colour=value), size=3) +
ylab(label="Región del cerebro") +
xlab(label = "Estadío del sueño")

roles_sin_repetidos_3 %>% gather(delta,value, N1,N2,N3,W) %>%
ggplot() +
geom_point(aes(x=delta, y=region, colour=value), size=3) +
ylab(label="Región del cerebro") +
xlab(label = "Estadío del sueño")

NA
NA
IGNORAR CODIGO A PARTIR DE ACA
#### graficos
pv_ref <- 0.05 #significancia
plots <- NA
i<- 1
j<- 2
estadio_ref_vector<- c("N1","N2","N3")
role_ref_vector <- c("H","PH","PN", "CN")
role_name_ref_vector <- c("Hubs","Provincial Hubs","Povincial Nodes", "Connection Nodes")
for(i in 1:length(role_ref_vector)){
for(j in 1:length(estadio_ref_vector)){
estadio_ref<- estadio_ref_vector[j]
role_ref <- role_ref_vector[i]
role_name_ref <-role_name_ref_vector[i]
y_label <- paste(role_name_ref)
title_label <- paste("WAKE vs.",estadio_ref)
#title_label <- paste(role_ref,"mean count")
#y_label <- role_ref
test_df <- comparison_results_df[comparison_results_df$estadio %in% c(estadio_ref,"W") &
comparison_results_df$rol %in% c(role_ref),]
test_df<- transform(test_df, p_valor = ifelse(p_valor < pv_ref, 0, NA))
pd <- position_dodge(0.001) # move them .05 to the left and right
if (all(is.na(test_df$p_valor))) {
p<- ggplot(test_df, aes(x=delta, y=mean, colour=estadio)) +
geom_errorbar(aes(ymin=mean-se, ymax=mean+se), width=.005,position=pd) +
geom_line(position=pd) +
geom_point(position=pd) +
#geom_point(aes(y=p_valor),position=pd) +
labs(title=title_label, x = "delta", y=y_label)
} else {
p<-ggplot(test_df, aes(x=delta, y=mean, colour=estadio)) +
geom_errorbar(aes(ymin=mean-se, ymax=mean+se), width=.005,position=pd) +
geom_line(position=pd) +
geom_point(position=pd) +
geom_point(aes(y=p_valor),position=pd) +
labs(title=title_label, x = "delta", y=y_label)
}
plots <-cbind(plots,list(p))
}
}
<!-- rnb-text-end -->
<!-- rnb-chunk-begin -->
<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuXG5cblxuXG5wbG90X3JvbGVzKHNlcSwgTjFfbWVhbl9zZXJpZSAsIE4xX3N0ZF9zZXJpZSwgV19tZWFuX3NlcmllICwgV19zdGRfc2VyaWUsIGVzdGFkaW89IFwiTjFcIiwgcm9sID1yb2xfbmFtZSlcbnBsb3Rfcm9sZXMoc2VxLCBOMl9tZWFuX3NlcmllICwgTjJfc3RkX3NlcmllLCBXX21lYW5fc2VyaWUgLCBXX3N0ZF9zZXJpZSwgZXN0YWRpbz0gXCJOMlwiLCByb2wgPXJvbF9uYW1lKVxucGxvdF9yb2xlcyhzZXEsIE4zX21lYW5fc2VyaWUgLCBOM19zdGRfc2VyaWUsIFdfbWVhbl9zZXJpZSAsIFdfc3RkX3NlcmllLCBlc3RhZGlvPSBcIk4zXCIsIHJvbCA9cm9sX25hbWUpXG5gYGAifQ== -->
```r
plot_roles(seq, N1_mean_serie , N1_std_serie, W_mean_serie , W_std_serie, estadio= "N1", rol =rol_name)
plot_roles(seq, N2_mean_serie , N2_std_serie, W_mean_serie , W_std_serie, estadio= "N2", rol =rol_name)
plot_roles(seq, N3_mean_serie , N3_std_serie, W_mean_serie , W_std_serie, estadio= "N3", rol =rol_name)
for(i in 1:length(seq)){ # itero sobre los deltas
df <- role_count_n1[[i]]
plot(df)
}
for(i in 1:length(seq)){ # itero sobre los deltas
df <- role_count_n2[[i]]
plot(df)
}
for(i in 1:length(seq)){ # itero sobre los deltas
df <- role_count_n3[[i]]
print(paste0("Delta ",seq[i]," - Mean H ",mean(df$H)))
print(paste0("Delta ",seq[i]," - Mean PH ",mean(df$PH)))
print(paste0("Delta ",seq[i]," - Mean PN ",mean(df$PN)))
print(paste0("Delta ",seq[i]," - Mean CN ",mean(df$CN)))
plot(df)
}
for(i in 1:length(seq)){ # itero sobre los deltas
df <- role_count_w[[i]]
plot(df)
}
role_count_n1_temp_H <- NA
role_count_n2_temp_H <- NA
role_count_n3_temp_H <- NA
role_count_w_temp_H <- NA
role_count_n1_temp_PH <- NA
role_count_n2_temp_PH <- NA
role_count_n3_temp_PH <- NA
role_count_w_temp_PH <- NA
role_count_n1_temp_PN <- NA
role_count_n2_temp_PN <- NA
role_count_n3_temp_PN <- NA
role_count_w_temp_PN <- NA
role_count_n1_temp_CN <- NA
role_count_n2_temp_CN <- NA
role_count_n3_temp_CN <- NA
role_count_w_temp_CN <- NA
role_count_n1 <- list()
role_count_n2 <- list()
role_count_n3 <- list()
role_count_w <- list()
louvain_n1<-list()
louvain_n2<-list()
louvain_n3<-list()
louvain_w<-list()
degree_n1<-list()
degree_n2<-list()
degree_n3<-list()
degree_w<-list()
z_score_n1<-list()
z_score_n2<-list()
z_score_n3<-list()
z_score_w<-list()
p_factor_n1<-list()
p_factor_n2<-list()
p_factor_n3<-list()
p_factor_w<-list()
LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQpUaGlzIGlzIGFuIFtSIE1hcmtkb3duXShodHRwOi8vcm1hcmtkb3duLnJzdHVkaW8uY29tKSBOb3RlYm9vay4gV2hlbiB5b3UgZXhlY3V0ZSBjb2RlIHdpdGhpbiB0aGUgbm90ZWJvb2ssIHRoZSByZXN1bHRzIGFwcGVhciBiZW5lYXRoIHRoZSBjb2RlLiANCg0KVHJ5IGV4ZWN1dGluZyB0aGlzIGNodW5rIGJ5IGNsaWNraW5nIHRoZSAqUnVuKiBidXR0b24gd2l0aGluIHRoZSBjaHVuayBvciBieSBwbGFjaW5nIHlvdXIgY3Vyc29yIGluc2lkZSBpdCBhbmQgcHJlc3NpbmcgKkN0cmwrU2hpZnQrRW50ZXIqLiANCmBgYHtyfQ0Kcm0obGlzdCA9IGxzKCkpDQpnYygpDQoNCiMgc2kgbm8gYW5kYW4gbG9zIHBhdGhzLCBzZXRlYXIgZXNhIHNpZ3VpZW50ZSBsaW5lYQ0KI3NldHdkKCJhY8OhIHZhIGVsIHBhdGggaGFzdGEgZWwgZGlyZWN0b3JpbyAnbmV1cm8nIikNCg0KbGlicmFyeShicmFpbkdyYXBoKQ0KbGlicmFyeShpZ3JhcGgpDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KHRpZHlyKQ0Kc291cmNlKHBhc3RlMChnZXR3ZCgpLCIvcmVkX3Bvcl9kZW5zaWRhZC5SIikpDQpgYGANCg0KDQpgYGB7cn0NCg0KIyBzZSBnZW5lcmFuIHRvZG9zIGxvcyBncmFmb3MgaW5kaXZpZHVhbGVzIHBhcmEgY2FkYSBzdWpldG8gZW4gY2FkYSBlc3RhZGlvIGRlIHN1ZT9vIHBhcmEgY2FkYSBkZWx0YQ0KDQpzZXEgPC0gc2VxKGZyb20gPSAwLjAyNSwgdG8gPSAwLjE1LCBieSA9IDAuMDA1KQ0Kc3VqLmNvdW50IDwtIDE4DQoNCk4xIDwtIGFycmF5KGRpbSA9IGxlbmd0aChzZXEpKQ0KTjIgPC0gYXJyYXkoZGltID0gbGVuZ3RoKHNlcSkpDQpOMyA8LSBhcnJheShkaW0gPSBsZW5ndGgoc2VxKSkNClcgPC0gYXJyYXkoZGltID0gbGVuZ3RoKHNlcSkpDQoNCmZvcihpIGluIDE6bGVuZ3RoKHNlcSkpIHsNCiAgdG1wTjEgPC0gYXJyYXkoZGltID0gc3VqLmNvdW50KQ0KICB0bXBOMiA8LSBhcnJheShkaW0gPSBzdWouY291bnQpDQogIHRtcE4zIDwtIGFycmF5KGRpbSA9IHN1ai5jb3VudCkNCiAgdG1wVyA8LSBhcnJheShkaW0gPSBzdWouY291bnQpDQogIGZvciAoaiBpbiAxOjE4KSB7DQogICAgdG1wIDwtIHJlYWQudGFibGUoIHBhc3RlMChnZXR3ZCgpLHBhc3RlMCgiL2RhdGFzZXRzL0RhdGFTdWpldG9zL04xX3N1aiIsaiwiLmNzdiIpKSwgaGVhZGVyPUYsIHNlcCA9ICIsIikNCiAgICByZXN1bHQgPC0gcmVkLnBvci5kZW5zaWRhZCh0bXAsIHNlcVtpXSkNCiAgICB0bXBOMVtqXSA8LSBsaXN0KGdyYWZvID0gcmVzdWx0JHJlZCkNCiAgICANCiAgICB0bXAgPC0gcmVhZC50YWJsZSggcGFzdGUwKGdldHdkKCkscGFzdGUwKCIvZGF0YXNldHMvRGF0YVN1amV0b3MvTjJfc3VqIixqLCIuY3N2IikpLCBoZWFkZXI9Riwgc2VwID0gIiwiKQ0KICAgIHJlc3VsdCA8LSByZWQucG9yLmRlbnNpZGFkKHRtcCwgc2VxW2ldKQ0KICAgIHRtcE4yW2pdIDwtIGxpc3QoZ3JhZm8gPSByZXN1bHQkcmVkKQ0KICAgIA0KICAgIHRtcCA8LSByZWFkLnRhYmxlKCBwYXN0ZTAoZ2V0d2QoKSxwYXN0ZTAoIi9kYXRhc2V0cy9EYXRhU3VqZXRvcy9OM19zdWoiLGosIi5jc3YiKSksIGhlYWRlcj1GLCBzZXAgPSAiLCIpDQogICAgcmVzdWx0IDwtIHJlZC5wb3IuZGVuc2lkYWQodG1wLCBzZXFbaV0pDQogICAgdG1wTjNbal0gPC0gbGlzdChncmFmbyA9IHJlc3VsdCRyZWQpDQoNCiAgICB0bXAgPC0gcmVhZC50YWJsZSggcGFzdGUwKGdldHdkKCkscGFzdGUwKCIvZGF0YXNldHMvRGF0YVN1amV0b3MvV19zdWoiLGosIi5jc3YiKSksIGhlYWRlcj1GLCBzZXAgPSAiLCIpDQogICAgcmVzdWx0IDwtIHJlZC5wb3IuZGVuc2lkYWQodG1wLCBzZXFbaV0pDQogICAgdG1wV1tqXSA8LSBsaXN0KGdyYWZvID0gcmVzdWx0JHJlZCkNCg0KICB9DQogIE4xW2ldIDwtIGxpc3QodG1wTjEpDQogIE4yW2ldIDwtIGxpc3QodG1wTjIpDQogIE4zW2ldIDwtIGxpc3QodG1wTjMpDQogIFdbaV0gPC0gbGlzdCh0bXBXKQ0KfQ0KYGBgDQoNCmBgYHtyfQ0KDQoNCmxvdXZhaW5fbjE8LWxvdXZhaW5fbjI8LWxvdXZhaW5fbjM8LWxvdXZhaW5fdzwtbGlzdCgpDQpkZWdyZWVfbjE8LWRlZ3JlZV9uMjwtZGVncmVlX24zPC1kZWdyZWVfdzwtbGlzdCgpDQp6X3Njb3JlX24xPC16X3Njb3JlX24yPC16X3Njb3JlX24zPC16X3Njb3JlX3c8LWxpc3QoKQ0KcF9mYWN0b3JfbjE8LXBfZmFjdG9yX24yPC1wX2ZhY3Rvcl9uMzwtcF9mYWN0b3JfdzwtbGlzdCgpDQoNCg0KDQpmb3IoaSBpbiAxOmxlbmd0aChzZXEpKXsgIyBpdGVybyBzb2JyZSBsb3MgZGVsdGFzDQogIA0KICBsb3V2YWluX24xW1tpXV0gPC0gbG91dmFpbl9uMltbaV1dIDwtIGxvdXZhaW5fbjNbW2ldXSA8LSBsb3V2YWluX3dbW2ldXSA8LSBsaXN0KCkNCiAgZGVncmVlX24xW1tpXV0gPC0gZGVncmVlX24yW1tpXV0gPC0gZGVncmVlX24zW1tpXV0gPC0gZGVncmVlX3dbW2ldXSA8LSAgbGlzdCgpDQogIHpfc2NvcmVfbjFbW2ldXSA8LSB6X3Njb3JlX24yW1tpXV0gPC0gel9zY29yZV9uM1tbaV1dIDwtIHpfc2NvcmVfd1tbaV1dIDwtIGxpc3QoKQ0KICBwX2ZhY3Rvcl9uMVtbaV1dIDwtIHBfZmFjdG9yX24yW1tpXV0gPC0gcF9mYWN0b3JfbjNbW2ldXSA8LSBwX2ZhY3Rvcl93W1tpXV08LWxpc3QoKQ0KDQogIGZvciAoaiBpbiAxOnN1ai5jb3VudCkgeyNpdGVybyBzb2JyZSBsb3Mgc3VqZXRvcw0KICAgIGxvdXZhaW5fbjFbW2ldXVtbal1dIDwtIGNsdXN0ZXJfbG91dmFpbihncmFwaCA9IE4xW1tpXV1bW2pdXSwgd2VpZ2h0cyA9IE5VTEwpDQogICAgbG91dmFpbl9uMltbaV1dW1tqXV0gPC0gY2x1c3Rlcl9sb3V2YWluKGdyYXBoID0gTjJbW2ldXVtbal1dLCB3ZWlnaHRzID0gTlVMTCkNCiAgICBsb3V2YWluX24zW1tpXV1bW2pdXSA8LSBjbHVzdGVyX2xvdXZhaW4oZ3JhcGggPSBOM1tbaV1dW1tqXV0sIHdlaWdodHMgPSBOVUxMKQ0KICAgIGxvdXZhaW5fd1tbaV1dW1tqXV0gPC0gY2x1c3Rlcl9sb3V2YWluKGdyYXBoID0gV1tbaV1dW1tqXV0sIHdlaWdodHMgPSBOVUxMKQ0KICANCiAgICBkZWdyZWVfbjFbW2ldXVtbal1dIDwtIGRlZ3JlZShOMVtbaV1dW1tqXV0pDQogICAgZGVncmVlX24yW1tpXV1bW2pdXTwtIGRlZ3JlZShOM1tbaV1dW1tqXV0pDQogICAgZGVncmVlX24zW1tpXV1bW2pdXTwtIGRlZ3JlZShOM1tbaV1dW1tqXV0pDQogICAgZGVncmVlX3dbW2ldXVtbal1dIDwtIGRlZ3JlZShXW1tpXV1bW2pdXSkNCiAgDQogICAgel9zY29yZV9uMVtbaV1dW1tqXV0gPC0gd2l0aGluX21vZHVsZV9kZWdfel9zY29yZShOMVtbaV1dW1tqXV0sIGxvdXZhaW5fbjFbW2ldXVtbal1dJG1lbWJlcnNoaXApDQogICAgel9zY29yZV9uMltbaV1dW1tqXV0gPC0gd2l0aGluX21vZHVsZV9kZWdfel9zY29yZShOMltbaV1dW1tqXV0sIGxvdXZhaW5fbjJbW2ldXVtbal1dJG1lbWJlcnNoaXApDQogICAgel9zY29yZV9uM1tbaV1dW1tqXV0gPC0gd2l0aGluX21vZHVsZV9kZWdfel9zY29yZShOM1tbaV1dW1tqXV0sIGxvdXZhaW5fbjNbW2ldXVtbal1dJG1lbWJlcnNoaXApDQogICAgel9zY29yZV93W1tpXV1bW2pdXSA8LSB3aXRoaW5fbW9kdWxlX2RlZ196X3Njb3JlKFdbW2ldXVtbal1dLCBsb3V2YWluX3dbW2ldXVtbal1dJG1lbWJlcnNoaXApDQogIA0KICAgIHBfZmFjdG9yX24xW1tpXV1bW2pdXSA8LSBwYXJ0X2NvZWZmKE4xW1tpXV1bW2pdXSwgbG91dmFpbl9uMVtbaV1dW1tqXV0kbWVtYmVyc2hpcCkNCiAgICBwX2ZhY3Rvcl9uMltbaV1dW1tqXV0gPC0gcGFydF9jb2VmZihOMltbaV1dW1tqXV0sIGxvdXZhaW5fbjJbW2ldXVtbal1dJG1lbWJlcnNoaXApDQogICAgcF9mYWN0b3JfbjNbW2ldXVtbal1dIDwtIHBhcnRfY29lZmYoTjNbW2ldXVtbal1dLCBsb3V2YWluX24zW1tpXV1bW2pdXSRtZW1iZXJzaGlwKQ0KICAgIHBfZmFjdG9yX3dbW2ldXVtbal1dIDwtIHBhcnRfY29lZmYoV1tbaV1dW1tqXV0sIGxvdXZhaW5fd1tbaV1dW1tqXV0kbWVtYmVyc2hpcCkNCiAgDQogIH0NCn0NCg0KDQpgYGANCg0KDQpgYGB7cn0NCiMgY29udmVyc2lvbiBkZSB6X3Njb3JlIHkgcGFydF9jb2VmIGVuIHJvbA0KDQp6MDwtIDENCnAwIDwtIDAuMDUNCg0KDQpub2RlX3JvbCA8LSBmdW5jdGlvbih6LHApew0KICANCiAgcmVzdWx0PC0gYXJyYXkoZGltID0gbGVuZ3RoKHopKSANCiAgDQogIGZvcihpIGluIDE6bGVuZ3RoKHopKXsNCiAgICAjcHJpbnQocmVzdWx0KQ0KICAgICNwcmludChpKQ0KICAgIGlmIChpcy5uYSh6W2ldKSB8IGlzLm5hKHBbaV0pKXt9DQogICAgZWxzZSBpZiAoeltpXT56MCAmIHBbaV0+cDAgKXtyZXN1bHRbaV0gPC0gJ0h1Yid9DQogICAgZWxzZSBpZiAoeltpXT56MCAmIHBbaV08cDAgKSB7cmVzdWx0W2ldIDwtICdQcm92aW5jaWFsIEh1Yid9DQogICAgZWxzZSBpZiAoeltpXTx6MCAmIHBbaV08cDAgKSB7cmVzdWx0W2ldIDwtICdQcm92aW5jaWFsIE5vZGUnfQ0KICAgIGVsc2UgaWYgKHpbaV08ejAgJiBwW2ldPnAwICkge3Jlc3VsdFtpXSA8LSAnQ29ubmVjdG9yIE5vZGUnfQ0KICAgIA0KICB9DQogIHJldHVybihyZXN1bHQpDQp9DQoNCnJvbGVfY291bnRfbjEgPC0gbGlzdCgpDQpyb2xlX2NvdW50X24yIDwtIGxpc3QoKQ0Kcm9sZV9jb3VudF9uMyA8LSBsaXN0KCkNCnJvbGVfY291bnRfdyA8LSBsaXN0KCkNCg0KDQpmb3IoaSBpbiAxOmxlbmd0aChzZXEpKXsgIyBpdGVybyBzb2JyZSBsb3MgZGVsdGFzDQogIHJvbGVfY291bnRfbjFfdGVtcF9IIDwtIHJvbGVfY291bnRfbjJfdGVtcF9IIDwtIHJvbGVfY291bnRfbjNfdGVtcF9IIDwtIHJvbGVfY291bnRfd190ZW1wX0ggPC0gTkENCiAgcm9sZV9jb3VudF9uMV90ZW1wX1BIIDwtIHJvbGVfY291bnRfbjJfdGVtcF9QSCA8LSByb2xlX2NvdW50X24zX3RlbXBfUEggPC0gcm9sZV9jb3VudF93X3RlbXBfUEggPC0gTkENCiAgcm9sZV9jb3VudF9uMV90ZW1wX1BOIDwtIHJvbGVfY291bnRfbjJfdGVtcF9QTiA8LSByb2xlX2NvdW50X24zX3RlbXBfUE4gPC0gcm9sZV9jb3VudF93X3RlbXBfUE4gPC0gTkENCiAgcm9sZV9jb3VudF9uMV90ZW1wX0NOIDwtIHJvbGVfY291bnRfbjJfdGVtcF9DTiA8LSByb2xlX2NvdW50X24zX3RlbXBfQ04gPC0gcm9sZV9jb3VudF93X3RlbXBfQ04gPC0gTkENCg0KICBmb3IgKGogaW4gMTpzdWouY291bnQpIHsjaXRlcm8gc29icmUgbG9zIHN1amV0b3MNCiAgICAgDQogICAgdGVtcCA8LSBub2RlX3JvbCh6X3Njb3JlX24xW1tpXV1bW2pdXSAsIHBfZmFjdG9yX24xW1tpXV1bW2pdXSkNCiAgICByb2xlX2NvdW50X24xX3RlbXBfSFtbal1dIDwtIGxlbmd0aCh3aGljaCh0ZW1wID09ICJIdWIiKSkNCiAgICByb2xlX2NvdW50X24xX3RlbXBfUEhbW2pdXSA8LSBsZW5ndGgod2hpY2godGVtcCA9PSAiUHJvdmluY2lhbCBIdWIiKSkNCiAgICByb2xlX2NvdW50X24xX3RlbXBfUE5bW2pdXSA8LSBsZW5ndGgod2hpY2godGVtcCA9PSAiUHJvdmluY2lhbCBOb2RlIikpDQogICAgcm9sZV9jb3VudF9uMV90ZW1wX0NOW1tqXV0gPC0gbGVuZ3RoKHdoaWNoKHRlbXAgPT0gIkNvbm5lY3RvciBOb2RlIikpDQogICAgDQogICAgdGVtcCA8LSBub2RlX3JvbCh6X3Njb3JlX24yW1tpXV1bW2pdXSAsIHBfZmFjdG9yX24yW1tpXV1bW2pdXSkNCiAgICByb2xlX2NvdW50X24yX3RlbXBfSFtbal1dIDwtIGxlbmd0aCh3aGljaCh0ZW1wID09ICJIdWIiKSkNCiAgICByb2xlX2NvdW50X24yX3RlbXBfUEhbW2pdXSA8LSBsZW5ndGgod2hpY2godGVtcCA9PSAiUHJvdmluY2lhbCBIdWIiKSkNCiAgICByb2xlX2NvdW50X24yX3RlbXBfUE5bW2pdXSA8LSBsZW5ndGgod2hpY2godGVtcCA9PSAiUHJvdmluY2lhbCBOb2RlIikpDQogICAgcm9sZV9jb3VudF9uMl90ZW1wX0NOW1tqXV0gPC0gbGVuZ3RoKHdoaWNoKHRlbXAgPT0gIkNvbm5lY3RvciBOb2RlIikpDQogICAgDQogICAgdGVtcCA8LSBub2RlX3JvbCh6X3Njb3JlX24zW1tpXV1bW2pdXSAsIHBfZmFjdG9yX24zW1tpXV1bW2pdXSkNCiAgICByb2xlX2NvdW50X24zX3RlbXBfSFtbal1dIDwtIGxlbmd0aCh3aGljaCh0ZW1wID09ICJIdWIiKSkNCiAgICByb2xlX2NvdW50X24zX3RlbXBfUEhbW2pdXSA8LSBsZW5ndGgod2hpY2godGVtcCA9PSAiUHJvdmluY2lhbCBIdWIiKSkNCiAgICByb2xlX2NvdW50X24zX3RlbXBfUE5bW2pdXSA8LSBsZW5ndGgod2hpY2godGVtcCA9PSAiUHJvdmluY2lhbCBOb2RlIikpDQogICAgcm9sZV9jb3VudF9uM190ZW1wX0NOW1tqXV0gPC0gbGVuZ3RoKHdoaWNoKHRlbXAgPT0gIkNvbm5lY3RvciBOb2RlIikpDQogICAgDQogICAgdGVtcCA8LSBub2RlX3JvbCh6X3Njb3JlX3dbW2ldXVtbal1dICwgcF9mYWN0b3Jfd1tbaV1dW1tqXV0pDQogICAgcm9sZV9jb3VudF93X3RlbXBfSFtbal1dIDwtIGxlbmd0aCh3aGljaCh0ZW1wID09ICJIdWIiKSkNCiAgICByb2xlX2NvdW50X3dfdGVtcF9QSFtbal1dIDwtIGxlbmd0aCh3aGljaCh0ZW1wID09ICJQcm92aW5jaWFsIEh1YiIpKQ0KICAgIHJvbGVfY291bnRfd190ZW1wX1BOW1tqXV0gPC0gbGVuZ3RoKHdoaWNoKHRlbXAgPT0gIlByb3ZpbmNpYWwgTm9kZSIpKQ0KICAgIHJvbGVfY291bnRfd190ZW1wX0NOW1tqXV0gPC0gbGVuZ3RoKHdoaWNoKHRlbXAgPT0gIkNvbm5lY3RvciBOb2RlIikpDQogICAgDQogICAgIA0KICAgfQ0KDQogIHJvbGVfY291bnRfbjFbW2ldXSA8LSBkYXRhLmZyYW1lKEggPXJvbGVfY291bnRfbjFfdGVtcF9ILCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUEggPXJvbGVfY291bnRfbjFfdGVtcF9QSCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUE4gPXJvbGVfY291bnRfbjFfdGVtcF9QTiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENOID1yb2xlX2NvdW50X24xX3RlbXBfQ04pDQogIHJvbGVfY291bnRfbjJbW2ldXSA8LSBkYXRhLmZyYW1lKEggPXJvbGVfY291bnRfbjJfdGVtcF9ILCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUEggPXJvbGVfY291bnRfbjJfdGVtcF9QSCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUE4gPXJvbGVfY291bnRfbjJfdGVtcF9QTiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENOID1yb2xlX2NvdW50X24yX3RlbXBfQ04pDQogIHJvbGVfY291bnRfbjNbW2ldXSA8LSBkYXRhLmZyYW1lKEggPXJvbGVfY291bnRfbjNfdGVtcF9ILCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUEggPXJvbGVfY291bnRfbjNfdGVtcF9QSCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUE4gPXJvbGVfY291bnRfbjNfdGVtcF9QTiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENOID1yb2xlX2NvdW50X24zX3RlbXBfQ04pDQogIHJvbGVfY291bnRfd1tbaV1dIDwtIGRhdGEuZnJhbWUoSCA9cm9sZV9jb3VudF93X3RlbXBfSCwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUEggPXJvbGVfY291bnRfd190ZW1wX1BILA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBOID1yb2xlX2NvdW50X3dfdGVtcF9QTiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ04gPXJvbGVfY291bnRfd190ZW1wX0NOKQ0KICANCiAgDQp9DQoNCmBgYA0KDQoNCg0KYGBge3J9DQojIyMjIENyZWFjaW9uIGRlIERhdGFmcmFtZSBjb24gY29tcGFyYWNpb25lcw0KDQoNCnJvbF92ZWN0b3I8LSBjKCJIIiwiUEgiLCAiUE4iLCAiQ04iKQ0KY29tcGFyaXNvbl9yZXN1bHRzX2RmIDwtIE5VTEwNCg0KDQoNCg0KDQoNCg0KZm9yKGkgaW4gMTpsZW5ndGgoc2VxKSl7ICMgaXRlcm8gc29icmUgbG9zIGRlbHRhcw0KIA0KICANCiAgDQogIA0KICBmb3IociBpbiAxOmxlbmd0aChyb2xfdmVjdG9yKSl7IyBpdGVybyBzb2JyZSBsb3Mgcm9sZXMgSCwgUEgsIFBOLCBDTg0KICByb2wgPC0gcm9sX3ZlY3RvcltyXQ0KICAjIHQudGVzdA0KICAjcC52YWxvci5uMSA8LSB0LnRlc3Qocm9sZV9jb3VudF9uMVtbaV1dWyxyb2xdLHJvbGVfY291bnRfd1tbaV1dWyxyb2xdKSRwLnZhbHVlDQogICNwLnZhbG9yLm4yIDwtIHQudGVzdChyb2xlX2NvdW50X24yW1tpXV1bLHJvbF0scm9sZV9jb3VudF93W1tpXV1bLHJvbF0pJHAudmFsdWUNCiAgI3AudmFsb3IubjMgPC0gdC50ZXN0KHJvbGVfY291bnRfbjNbW2ldXVsscm9sXSxyb2xlX2NvdW50X3dbW2ldXVsscm9sXSkkcC52YWx1ZQ0KICAjcC52YWxvci53IDwtIE5BDQogIA0KICANCiAgI0FOT1ZBDQogIHAudmFsb3IubjEgPC0gdW5saXN0KHN1bW1hcnkoYW92KHJvbGVfY291bnRfbjFbW2ldXVsscm9sXX5yb2xlX2NvdW50X3dbW2ldXVsscm9sXSkpW1sxXV0pW1s5XV0NCiAgcC52YWxvci5uMiA8LSB1bmxpc3Qoc3VtbWFyeShhb3Yocm9sZV9jb3VudF9uMltbaV1dWyxyb2xdfnJvbGVfY291bnRfd1tbaV1dWyxyb2xdKSlbWzFdXSlbWzldXQ0KICBwLnZhbG9yLm4zIDwtIHVubGlzdChzdW1tYXJ5KGFvdihyb2xlX2NvdW50X24zW1tpXV1bLHJvbF1+cm9sZV9jb3VudF93W1tpXV1bLHJvbF0pKVtbMV1dKVtbOV1dDQogIHAudmFsb3IudyA8LSBOQQ0KICANCiAgI1dpbGNveG9uDQogICNwLnZhbG9yLm4xIDwtIHdpbGNveC50ZXN0KHJvbGVfY291bnRfbjFbW2ldXVsscm9sXSxyb2xlX2NvdW50X3dbW2ldXVsscm9sXSwgY29uZi5sZXZlbCA9IDAuOTUpJHAudmFsdWUNCiAgI3AudmFsb3IubjIgPC0gd2lsY294LnRlc3Qocm9sZV9jb3VudF9uMltbaV1dWyxyb2xdLHJvbGVfY291bnRfd1tbaV1dWyxyb2xdLCBjb25mLmxldmVsID0gMC45NSkkcC52YWx1ZQ0KICAjcC52YWxvci5uMyA8LSB3aWxjb3gudGVzdChyb2xlX2NvdW50X24zW1tpXV1bLHJvbF0scm9sZV9jb3VudF93W1tpXV1bLHJvbF0sIGNvbmYubGV2ZWwgPSAwLjk1KSRwLnZhbHVlDQogICNwLnZhbG9yLncgPC0gTkENCiAgDQogIA0KICBOMV9tZWFuX3RlbXAgPC0gbWVhbihyb2xlX2NvdW50X24xW1tpXV1bLHJvbF0pDQogIE4yX21lYW5fdGVtcCA8LSBtZWFuKHJvbGVfY291bnRfbjJbW2ldXVsscm9sXSkNCiAgTjNfbWVhbl90ZW1wIDwtIG1lYW4ocm9sZV9jb3VudF9uM1tbaV1dWyxyb2xdKQ0KICBXX21lYW5fdGVtcCA8LSBtZWFuKHJvbGVfY291bnRfd1tbaV1dWyxyb2xdKQ0KICBOMV9zZV90ZW1wIDwtIHNkKHJvbGVfY291bnRfbjFbW2ldXVsscm9sXSkvc3FydChsZW5ndGgocm9sZV9jb3VudF9uMVtbaV1dWyxyb2xdKSkNCiAgTjJfc2VfdGVtcCA8LSBzZChyb2xlX2NvdW50X24yW1tpXV1bLHJvbF0pL3NxcnQobGVuZ3RoKHJvbGVfY291bnRfbjJbW2ldXVsscm9sXSkpDQogIE4zX3NlX3RlbXAgPC0gc2Qocm9sZV9jb3VudF9uM1tbaV1dWyxyb2xdKS9zcXJ0KGxlbmd0aChyb2xlX2NvdW50X24zW1tpXV1bLHJvbF0pKQ0KICBXX3NlX3RlbXAgPC0gc2Qocm9sZV9jb3VudF93W1tpXV1bLHJvbF0pL3NxcnQobGVuZ3RoKHJvbGVfY291bnRfd1tbaV1dWyxyb2xdKSkNCiAgDQogIA0KICANCiAgDQogIA0KICBjb21wYXJpc29uX3Jlc3VsdHNfZGYgPC0gcmJpbmQoY29tcGFyaXNvbl9yZXN1bHRzX2RmLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhLmZyYW1lKGVzdGFkaW8gPSAiTjEiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJvbCA9IHJvbCwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsdGE9c2VxW2ldLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lYW49TjFfbWVhbl90ZW1wLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZT0gTjFfc2VfdGVtcCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwX3ZhbG9yID0gcC52YWxvci5uMSkgKQ0KICANCiAgY29tcGFyaXNvbl9yZXN1bHRzX2RmIDwtIHJiaW5kKGNvbXBhcmlzb25fcmVzdWx0c19kZiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YS5mcmFtZShlc3RhZGlvID0gIk4yIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByb2wgPSByb2wsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbHRhPXNlcVtpXSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZWFuPU4yX21lYW5fdGVtcCwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2U9IE4yX3NlX3RlbXAsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcF92YWxvciA9IHAudmFsb3IubjIpICkNCiAgY29tcGFyaXNvbl9yZXN1bHRzX2RmIDwtIHJiaW5kKGNvbXBhcmlzb25fcmVzdWx0c19kZiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YS5mcmFtZShlc3RhZGlvID0gIk4zIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByb2wgPSByb2wsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbHRhPXNlcVtpXSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZWFuPU4zX21lYW5fdGVtcCwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2U9IE4zX3NlX3RlbXAsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcF92YWxvciA9IHAudmFsb3IubjMpICkNCiAgY29tcGFyaXNvbl9yZXN1bHRzX2RmIDwtIHJiaW5kKGNvbXBhcmlzb25fcmVzdWx0c19kZiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YS5mcmFtZShlc3RhZGlvID0gIlciLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJvbCA9IHJvbCwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsdGE9c2VxW2ldLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lYW49V19tZWFuX3RlbXAsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlPSBXX3NlX3RlbXAsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcF92YWxvciA9IHAudmFsb3IudykgKQ0KICANCiAgDQoNCn0NCn0NCg0KDQoNCg0KDQoNCmBgYA0KDQoNCg0KDQoNCmBgYHtyfQ0KIyMjIyBncmFmaWNvcw0KcHZfcmVmIDwtIDAuMDUgI3NpZ25pZmljYW5jaWENCg0KDQoNCmk8LSAxDQpqPC0gMg0KDQplc3RhZGlvX3JlZl92ZWN0b3I8LSBjKCJOMSIsIk4yIiwiTjMiKQ0Kcm9sZV9yZWZfdmVjdG9yIDwtIGMoIkgiLCJQSCIsIlBOIiwgIkNOIikNCnJvbGVfbmFtZV9yZWZfdmVjdG9yIDwtIGMoIkh1YnMiLCJQcm92aW5jaWFsIEh1YnMiLCJQb3ZpbmNpYWwgTm9kZXMiLCAiQ29ubmVjdGlvbiBOb2RlcyIpDQoNCg0KZm9yKGkgaW4gMTpsZW5ndGgocm9sZV9yZWZfdmVjdG9yKSl7DQogIGZvcihqIGluIDE6bGVuZ3RoKGVzdGFkaW9fcmVmX3ZlY3Rvcikpew0KDQoNCg0KZXN0YWRpb19yZWY8LSBlc3RhZGlvX3JlZl92ZWN0b3Jbal0NCnJvbGVfcmVmIDwtIHJvbGVfcmVmX3ZlY3RvcltpXQ0Kcm9sZV9uYW1lX3JlZiA8LXJvbGVfbmFtZV9yZWZfdmVjdG9yW2ldDQp5X2xhYmVsIDwtIHBhc3RlKHJvbGVfbmFtZV9yZWYpDQp0aXRsZV9sYWJlbCA8LSBwYXN0ZSgiV0FLRSB2cy4iLGVzdGFkaW9fcmVmKQ0KDQojdGl0bGVfbGFiZWwgPC0gcGFzdGUocm9sZV9yZWYsIm1lYW4gY291bnQiKQ0KI3lfbGFiZWwgPC0gcm9sZV9yZWYNCg0KDQoNCnRlc3RfZGYgPC0gY29tcGFyaXNvbl9yZXN1bHRzX2RmW2NvbXBhcmlzb25fcmVzdWx0c19kZiRlc3RhZGlvICVpbiUgYyhlc3RhZGlvX3JlZiwiVyIpICYNCmNvbXBhcmlzb25fcmVzdWx0c19kZiRyb2wgJWluJSBjKHJvbGVfcmVmKSxdDQp0ZXN0X2RmPC0gdHJhbnNmb3JtKHRlc3RfZGYsIHBfdmFsb3IgPSBpZmVsc2UocF92YWxvciA8IHB2X3JlZiwgMCwgTkEpKQ0KDQpwZCA8LSBwb3NpdGlvbl9kb2RnZSgwLjAwMSkgIyBtb3ZlIHRoZW0gLjA1IHRvIHRoZSBsZWZ0IGFuZCByaWdodA0KDQoNCmlmIChhbGwoaXMubmEodGVzdF9kZiRwX3ZhbG9yKSkpIHsNCiAgIHA8LSBnZ3Bsb3QodGVzdF9kZiwgYWVzKHg9ZGVsdGEsIHk9bWVhbiwgY29sb3VyPWVzdGFkaW8pKSArIA0KICAgICAgICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluPW1lYW4tc2UsIHltYXg9bWVhbitzZSksIHdpZHRoPS4wMDUscG9zaXRpb249cGQpICsNCiAgICAgICAgZ2VvbV9saW5lKHBvc2l0aW9uPXBkKSArDQogICAgICAgIGdlb21fcG9pbnQocG9zaXRpb249cGQpICsNCiAgICAgICAgI2dlb21fcG9pbnQoYWVzKHk9cF92YWxvcikscG9zaXRpb249cGQpICsNCiAgICAgICAgbGFicyh0aXRsZT10aXRsZV9sYWJlbCwgeCA9ICJkZWx0YSIsIHk9eV9sYWJlbCkNCn0gZWxzZSB7DQogICBwPC1nZ3Bsb3QodGVzdF9kZiwgYWVzKHg9ZGVsdGEsIHk9bWVhbiwgY29sb3VyPWVzdGFkaW8pKSArIA0KICAgICAgICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluPW1lYW4tc2UsIHltYXg9bWVhbitzZSksIHdpZHRoPS4wMDUscG9zaXRpb249cGQpICsNCiAgICAgICAgZ2VvbV9saW5lKHBvc2l0aW9uPXBkKSArDQogICAgICAgIGdlb21fcG9pbnQocG9zaXRpb249cGQpICsNCiAgICAgICAgZ2VvbV9wb2ludChhZXMoeT1wX3ZhbG9yKSxwb3NpdGlvbj1wZCkgKw0KICAgICAgICBsYWJzKHRpdGxlPXRpdGxlX2xhYmVsLCB4ID0gImRlbHRhIiwgeT15X2xhYmVsKQ0KfQ0KcHJpbnQocCkNCn0NCn0NCg0KYGBgDQoNCmBgYHtyfQ0KI2dyaWQgcGxvdA0KDQpsaWJyYXJ5KCJjb3dwbG90IikNCg0KcGxvdF9ncmlkKHBsb3RzW1sxXV0sDQogICAgICAgICAgcGxvdHNbWzJdXSwNCiAgICAgICAgICBwbG90c1tbM11dLA0KICAgICAgICAgIHBsb3RzW1s0XV0sDQogICAgICAgICAgcGxvdHNbWzVdXSwNCiAgICAgICAgICBwbG90c1tbNl1dLA0KICAgICAgICAgIHBsb3RzW1s3XV0sDQogICAgICAgICAgcGxvdHNbWzhdXSwNCiAgICAgICAgICBwbG90c1tbOV1dLA0KICAgICAgICAgIHBsb3RzW1sxMF1dLA0KICAgICAgICAgIHBsb3RzW1sxMV1dLA0KICAgICAgICAgIHBsb3RzW1sxMl1dLG5jb2wgPSAzKQ0KYGBgDQoNCg0KYGBge3J9DQojIyMgR3JhZmljb3MgaW50ZXJlc2FudGVzDQoNCiNmb3JtYSBjb3BhcmEgZGUgZGlidWphciBsb3MgY2x1c3RlcnMNCiNjbHAgPC0gY2x1c3Rlcl9sb3V2YWluKGdyYXBoID0gTjJfbm9fcGVzYWRvc1tbMV1dLCB3ZWlnaHRzID0gTlVMTCkNCmk8LTEgIyBkZWx0YQ0KajwtMSAjIHN1amV0bw0KDQogICAgZzwtIE4xW1tpXV1bW2pdXSANCiAgICByb2xlcyA8LSBhcy5mYWN0b3Iobm9kZV9yb2woel9zY29yZV9uMVtbaV1dW1tqXV0gLCBwX2ZhY3Rvcl9uMVtbaV1dW1tqXV0pKQ0KICAgIGNvbHJzIDwtIGMoIm9saXZlZHJhYjMiLCAidG9tYXRvIiwiZGFya2N5YW4iLCAiZ29sZCIpDQogICAgVihnKSRjb2xvciA8LSBjb2xyc1tyb2xlc10NCiAgICBjbHAgPC0gY2x1c3Rlcl9sb3V2YWluKGdyYXBoID0gZywgd2VpZ2h0cyA9IE5VTEwpDQogICAgDQogICAgbCA8LSBsYXlvdXRfd2l0aF9mcihnKQ0KICAgIA0KICAgIHBsb3QoZywgbGF5b3V0PWwsdmVydGV4LmxhYmVsID0gIiIgLCB2ZXJ0ZXguc2l6ZSA9IDcgKQ0KbGVnZW5kKHg9MS4yLCB5PTAuNSwgbGV2ZWxzKGFzLmZhY3Rvcihyb2xlcykpLCBwY2g9MjEsY29sPSIjNzc3Nzc3IiwgcHQuY2V4PTIsIGNleD0uOCwgYnR5PSJuIiwgbmNvbD0xLCBwdC5iZz1jb2xycykNCnRpdGxlKCJSb2xlcyBlbiBOMSAtIHN1amV0byAxIC0gIGRlbHRhID0gMC4wMjUiLCBjZXgubWFpbj0uOCkNCg0KDQoNCmBgYA0KDQoNCiNDYW1iaW8gZGUgcm9sZXMgZGUgbG9zIG5vZG9zDQpgYGB7cn0NCg0KaTwtMSAjIGRlbHRhDQpqPC0xICMgc3VqZXRvDQpkZWx0YSA8LSAwLjA2NQ0KaSA8LSB3aGljaChzZXEgPT0gZGVsdGEpDQoNCiAgICBnPC0gTjFbW2ldXVtbal1dIA0KICAgIHJvbGVzX24xIDwtIG5vZGVfcm9sKHpfc2NvcmVfbjFbW2ldXVtbal1dICwgcF9mYWN0b3JfbjFbW2ldXVtbal1dKQ0KICAgIHJvbGVzX24yIDwtIG5vZGVfcm9sKHpfc2NvcmVfbjJbW2ldXVtbal1dICwgcF9mYWN0b3JfbjJbW2ldXVtbal1dKQ0KICAgIHJvbGVzX24zIDwtbm9kZV9yb2woel9zY29yZV9uM1tbaV1dW1tqXV0gLCBwX2ZhY3Rvcl9uM1tbaV1dW1tqXV0pDQogICAgcm9sZXNfdyA8LSBub2RlX3JvbCh6X3Njb3JlX3dbW2ldXVtbal1dICwgcF9mYWN0b3Jfd1tbaV1dW1tqXV0pDQogICAgDQogICAgcm9sZXMgPC0gcmJpbmQocm9sZXNfbjEsIHJvbGVzX24yKQ0KICAgIHJvbGVzIDwtIHJiaW5kKHJvbGVzLCByb2xlc19uMykNCiAgICByb2xlcyA8LSByYmluZChyb2xlcywgcm9sZXNfdykNCiAgICByb2xlcyA8LSBhcy5kYXRhLmZyYW1lKHJvbGVzKQ0KICAgIHJvd25hbWVzKHJvbGVzKSA8LSBjKCJOMSIsIk4yIiwiTjMiLCJXIikNCiAgICByZWdpb25zIDwtIHJlYWQudGFibGUoIHBhc3RlMChnZXR3ZCgpLCIvZGF0YXNldHMvYWFsX25vX3JlcC5jc3YiKSwgaGVhZGVyPUYsIHNlcCA9ICIsIikNCiAgICBjb2xuYW1lcyhyb2xlcykgPC0gcmVnaW9uc1ssMV0NCiAgICAjcm9sZXNbaXMubmEocm9sZXMpXSA8LSAiIg0KICAgIHJvbGVzIDwtYXMuZGF0YS5mcmFtZSh0KHJvbGVzKSkNCiAgICBzdHIocm9sZXMpDQogICAgcGxvdChyb2xlcykNCiAgICBWaWV3KHJvbGVzKQ0KICAgIHJvbGVzX3Npbl9uYXMgPC0gcm9sZXNbKCFpcy5uYShyb2xlcyROMSkgJiAhaXMubmEocm9sZXMkTjIpICYgIWlzLm5hKHJvbGVzJE4zKSAmICFpcy5uYShyb2xlcyRXKSksXQ0KICAgIHJvbGVzX3Npbl9yZXBldGlkb3MgPC0gcm9sZXNbKHJvbGVzJE4xICE9IHJvbGVzJE4yKSANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgKHJvbGVzJE4xICE9IHJvbGVzJE4zKSANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgKHJvbGVzJE4xICE9IHJvbGVzJFcpIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAocm9sZXMkTjIgIT0gcm9sZXMkTjMpIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAocm9sZXMkTjIgIT0gcm9sZXMkVykgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IChyb2xlcyROMyAhPSByb2xlcyRXKSxdDQogICAgcm9sZXNfc2luX3JlcGV0aWRvcyA8LSBuYS5vbWl0KHJvbGVzX3Npbl9yZXBldGlkb3MpDQogICAgcm9sZXNfc2luX3JlcGV0aWRvcyRyZWdpb248LXJvd25hbWVzKHJvbGVzX3Npbl9yZXBldGlkb3MpDQogICAgVmlldyhyb2xlc19zaW5fcmVwZXRpZG9zKQ0KDQogICAgcm9sZXNfc2luX3JlcGV0aWRvcyA8LSBhcy5kYXRhLmZyYW1lKHJvbGVzX3Npbl9yZXBldGlkb3MpDQoNCiAgICAjIHNlcGFyYW1vcyBlbiAzIHBvcnF1ZSBubyBzZSB2ZW4gYmllbiB0b2RvcyBlbiAxIGdyw6FmaWNvDQogICAgcm9sZXNfc2luX3JlcGV0aWRvc18xIDwtIHJvbGVzX3Npbl9yZXBldGlkb3NbMToyNixdDQogICAgcm9sZXNfc2luX3JlcGV0aWRvc18yIDwtIHJvbGVzX3Npbl9yZXBldGlkb3NbMjc6NTIsXQ0KICAgIHJvbGVzX3Npbl9yZXBldGlkb3NfMyA8LSByb2xlc19zaW5fcmVwZXRpZG9zWzUzOjc4LF0NCiAgICANCiAgICByb2xlc19zaW5fcmVwZXRpZG9zXzEgJT4lIGdhdGhlcihkZWx0YSx2YWx1ZSwgTjEsTjIsTjMsVykgJT4lDQogICAgICBnZ3Bsb3QoKSArDQogICAgICBnZW9tX3BvaW50KGFlcyh4PWRlbHRhLCB5PXJlZ2lvbiwgY29sb3VyPXZhbHVlKSwgc2l6ZT0zKSArDQogICAgICB5bGFiKGxhYmVsPSJSZWdpw7NuIGRlbCBjZXJlYnJvIikgKw0KICAgICAgeGxhYihsYWJlbCA9ICJFc3RhZMOtbyBkZWwgc3Vlw7FvIikNCg0KICAgIHJvbGVzX3Npbl9yZXBldGlkb3NfMiAlPiUgZ2F0aGVyKGRlbHRhLHZhbHVlLCBOMSxOMixOMyxXKSAlPiUNCiAgICAgIGdncGxvdCgpICsNCiAgICAgIGdlb21fcG9pbnQoYWVzKHg9ZGVsdGEsIHk9cmVnaW9uLCBjb2xvdXI9dmFsdWUpLCBzaXplPTMpICsNCiAgICAgIHlsYWIobGFiZWw9IlJlZ2nDs24gZGVsIGNlcmVicm8iKSArDQogICAgICB4bGFiKGxhYmVsID0gIkVzdGFkw61vIGRlbCBzdWXDsW8iKQ0KDQogICAgcm9sZXNfc2luX3JlcGV0aWRvc18zICU+JSBnYXRoZXIoZGVsdGEsdmFsdWUsIE4xLE4yLE4zLFcpICU+JQ0KICAgICAgZ2dwbG90KCkgKw0KICAgICAgZ2VvbV9wb2ludChhZXMoeD1kZWx0YSwgeT1yZWdpb24sIGNvbG91cj12YWx1ZSksIHNpemU9MykgKw0KICAgICAgeWxhYihsYWJlbD0iUmVnacOzbiBkZWwgY2VyZWJybyIpICsNCiAgICAgIHhsYWIobGFiZWwgPSAiRXN0YWTDrW8gZGVsIHN1ZcOxbyIpDQogICAgDQoNCmBgYA0KDQoNCg0KIyMjIyMjIElHTk9SQVIgQ09ESUdPIEEgUEFSVElSIERFIEFDQQ0KIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQoNCg0KDQoNCmBgYHtyfQ0KDQojIGRlZmlubyBmdW5jaW9uZXMgZGUgcGxvdGVvDQoNCg0KcGxvdF9yb2xlczwtIGZ1bmN0aW9uKGRlbHRhLCBOeF9tZWFuICwgTnhfc2QsV19tZWFuICwgV19zZCwgZXN0YWRpbywgcm9sKXsNCiAgDQogIHRoZW1lX3VwZGF0ZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkNCiAgTnhfZGYgPC0gZGF0YS5mcmFtZShkZWx0YSA9IGRlbHRhICwgbWVhbj1OeF9tZWFuICwgc2Q9Tnhfc2QpDQogIFdfZGYgPC0gZGF0YS5mcmFtZShkZWx0YSA9IGRlbHRhICwgbWVhbj1XX21lYW4gLCBzZD0gV19zZCkNCg0KICBOeF9kZiRyb2wgPC0gZXN0YWRpbw0KICBXX2RmJHJvbCA8LSAnVycNCiAgDQogIHlfbGFiZWwgPC0gcGFzdGUocm9sLCAiTWVhbiBjb3VudCIpDQogIHRpdGxlX2xhYmVsIDwtIHBhc3RlKGVzdGFkaW8scm9sLCJNZWFuIGNvdW50IikNCiAgDQogIHRlc3RzYW1wbGVzIDwtIHJiaW5kKE54X2RmLCBXX2RmKQ0KICANCiAgDQogIHBkIDwtIHBvc2l0aW9uX2RvZGdlKDAuMDAxKSAjIG1vdmUgdGhlbSAuMDUgdG8gdGhlIGxlZnQgYW5kIHJpZ2h0DQogICAgDQogIGdncGxvdCh0ZXN0c2FtcGxlcywgYWVzKHg9ZGVsdGEsIHk9bWVhbiwgY29sb3VyPXJvbCkpICsgDQogICAgICAgIGdlb21fZXJyb3JiYXIoYWVzKHltaW49bWVhbi1zZCwgeW1heD1tZWFuK3NkKSwgd2lkdGg9LjAwNSxwb3NpdGlvbj1wZCkgKw0KICAgICAgICBnZW9tX2xpbmUocG9zaXRpb249cGQpICsNCiAgICAgICAgZ2VvbV9wb2ludChwb3NpdGlvbj1wZCkgKw0KICAgICAgICBsYWJzKHRpdGxlPXRpdGxlX2xhYmVsLCB4ID0gImRlbHRhIiwgeT15X2xhYmVsKQ0KICAgICAgICANCiAgDQp9DQoNCmdyYWZpY2FyX3JvbGVzPC0gZnVuY3Rpb24ocm9sLHJvbF9uYW1lKXsNCg0KDQpOMV9tZWFuX3NlcmllIDwtIHJlcChOQSwgbGVuZ3RoKHNlcSkpDQpOMl9tZWFuX3NlcmllIDwtIHJlcChOQSwgbGVuZ3RoKHNlcSkpDQpOM19tZWFuX3NlcmllIDwtIHJlcChOQSwgbGVuZ3RoKHNlcSkpDQpXX21lYW5fc2VyaWUgPC0gcmVwKE5BLCBsZW5ndGgoc2VxKSkNCk4xX3N0ZF9zZXJpZSA8LSByZXAoTkEsIGxlbmd0aChzZXEpKQ0KTjJfc3RkX3NlcmllIDwtIHJlcChOQSwgbGVuZ3RoKHNlcSkpDQpOM19zdGRfc2VyaWUgPC0gcmVwKE5BLCBsZW5ndGgoc2VxKSkNCldfc3RkX3NlcmllIDwtIHJlcChOQSwgbGVuZ3RoKHNlcSkpDQoNCg0KDQpmb3IoaSBpbiAxOmxlbmd0aChzZXEpKXsgIyBpdGVybyBzb2JyZSBsb3MgZGVsdGFzDQogIGRmX24xIDwtIHJvbGVfY291bnRfbjFbW2ldXQ0KICBkZl9uMiA8LSByb2xlX2NvdW50X24yW1tpXV0NCiAgZGZfbjMgPC0gcm9sZV9jb3VudF9uM1tbaV1dDQogIGRmX3cgPC0gcm9sZV9jb3VudF93W1tpXV0NCiAgTjFfbWVhbl9zZXJpZVtbaV1dIDwtIG1lYW4oZGZfbjFbLHJvbF0pDQogIE4yX21lYW5fc2VyaWVbW2ldXSA8LSBtZWFuKGRmX24yWyxyb2xdKQ0KICBOM19tZWFuX3NlcmllW1tpXV0gPC0gbWVhbihkZl9uM1sscm9sXSkNCiAgV19tZWFuX3NlcmllW1tpXV0gPC0gbWVhbihkZl93Wyxyb2xdKQ0KICBOMV9zdGRfc2VyaWVbW2ldXSA8LSBzZChkZl9uMVsscm9sXSkvc3FydChsZW5ndGgoZGZfbjFbLHJvbF0pKQ0KICBOMl9zdGRfc2VyaWVbW2ldXSA8LSBzZChkZl9uMlsscm9sXSkvc3FydChsZW5ndGgoZGZfbjJbLHJvbF0pKQ0KICBOM19zdGRfc2VyaWVbW2ldXSA8LSBzZChkZl9uM1sscm9sXSkvc3FydChsZW5ndGgoZGZfbjNbLHJvbF0pKQ0KICBXX3N0ZF9zZXJpZVtbaV1dIDwtIHNkKGRmX3dbLHJvbF0pL3NxcnQobGVuZ3RoKGRmX3dbLHJvbF0pKQ0KICANCiAgfQ0KICANCiAgDQogIHByaW50KHBsb3Rfcm9sZXMoc2VxLCBOMV9tZWFuX3NlcmllICwgTjFfc3RkX3NlcmllLCBXX21lYW5fc2VyaWUgLCBXX3N0ZF9zZXJpZSwgZXN0YWRpbz0gIk4xIiwgcm9sID1yb2xfbmFtZSkpDQogIHByaW50KHBsb3Rfcm9sZXMoc2VxLCBOMl9tZWFuX3NlcmllICwgTjJfc3RkX3NlcmllLCBXX21lYW5fc2VyaWUgLCBXX3N0ZF9zZXJpZSwgZXN0YWRpbz0gIk4yIiwgcm9sID1yb2xfbmFtZSkpDQogIHByaW50KHBsb3Rfcm9sZXMoc2VxLCBOM19tZWFuX3NlcmllICwgTjNfc3RkX3NlcmllLCBXX21lYW5fc2VyaWUgLCBXX3N0ZF9zZXJpZSwgZXN0YWRpbz0gIk4zIiwgcm9sID1yb2xfbmFtZSkpDQogIA0KfQ0KDQoNCg0KYGBgDQoNCg0KYGBge3J9DQoNCiMjIyBMbyBJbXBvcnRhbnRlDQoNCmdyYWZpY2FyX3JvbGVzKHJvbD0iSCIscm9sX25hbWU9Ikh1YnMiKQ0KZ3JhZmljYXJfcm9sZXMocm9sPSJQSCIscm9sX25hbWU9IlByb3ZpbnRpYWwgSHVicyIpDQpncmFmaWNhcl9yb2xlcyhyb2w9IlBOIixyb2xfbmFtZT0iUHJvdmludGlhbCBOb2RlcyIpDQpncmFmaWNhcl9yb2xlcyhyb2w9IkNOIixyb2xfbmFtZT0iQ29uZWN0ZWQgTm9kZXMiKQ0KYGBgDQoNCg0KDQpgYGB7cn0NCg0KIyMjIHQgdGVzdA0KDQoNCnJvbF92ZWN0b3I8LSBjKCJIIiwiUEgiLCAiUE4iLCAiQ04iKQ0KDQoNCg0KdF90ZXN0X3Jlc3VsdHNfZGYgPC0gTlVMTA0KDQoNCmZvcihpIGluIDE6bGVuZ3RoKHNlcSkpeyAjIGl0ZXJvIHNvYnJlIGxvcyBkZWx0YXMNCiAgDQogIGZvcihyIGluIDE6bGVuZ3RoKHJvbF92ZWN0b3IpKXsjIGl0ZXJvIHNvYnJlIGxvcyByb2xlcyBILCBQSCwgUE4sIENODQogIHJvbCA8LSByb2xfdmVjdG9yW3JdDQogIHAudmFsb3IubjEgPC0gdC50ZXN0KHJvbGVfY291bnRfbjFbW2ldXVsscm9sXSxyb2xlX2NvdW50X3dbW2ldXVsscm9sXSkkcC52YWx1ZQ0KICBwLnZhbG9yLm4yIDwtIHQudGVzdChyb2xlX2NvdW50X24yW1tpXV1bLHJvbF0scm9sZV9jb3VudF93W1tpXV1bLHJvbF0pJHAudmFsdWUNCiAgcC52YWxvci5uMyA8LSB0LnRlc3Qocm9sZV9jb3VudF9uM1tbaV1dWyxyb2xdLHJvbGVfY291bnRfd1tbaV1dWyxyb2xdKSRwLnZhbHVlDQogIA0KICANCiAgDQogIHRfdGVzdF9yZXN1bHRzX2RmIDwtIHJiaW5kKHRfdGVzdF9yZXN1bHRzX2RmLGRhdGEuZnJhbWUoZXN0YWRpbyA9ICJOMSIscm9sID0gcm9sLCBkZWx0YT1zZXFbaV0sIHBfdmFsb3IgPSBwLnZhbG9yLm4xKSApDQogIHRfdGVzdF9yZXN1bHRzX2RmIDwtIHJiaW5kKHRfdGVzdF9yZXN1bHRzX2RmLGRhdGEuZnJhbWUoZXN0YWRpbyA9ICJOMiIscm9sID0gcm9sLCBkZWx0YT1zZXFbaV0sIHBfdmFsb3IgPSBwLnZhbG9yLm4yKSApDQogIHRfdGVzdF9yZXN1bHRzX2RmIDwtIHJiaW5kKHRfdGVzdF9yZXN1bHRzX2RmLGRhdGEuZnJhbWUoZXN0YWRpbyA9ICJOMyIscm9sID0gcm9sLCBkZWx0YT1zZXFbaV0sIHBfdmFsb3IgPSBwLnZhbG9yLm4zKSApDQogIA0KICANCg0KfQ0KfQ0KDQoNCg0KYGBgDQoNCmBgYHtyfQ0KIyMjIyBDcmVhY2lvbiBkZSBEYXRhZnJhbWUgY29uIGNvbXBhcmFjaW9uZXMNCg0KDQpyb2xfdmVjdG9yPC0gYygiSCIsIlBIIiwgIlBOIiwgIkNOIikNCmNvbXBhcmlzb25fcmVzdWx0c19kZiA8LSBOVUxMDQoNCg0KDQoNCg0KDQoNCmZvcihpIGluIDE6bGVuZ3RoKHNlcSkpeyAjIGl0ZXJvIHNvYnJlIGxvcyBkZWx0YXMNCiANCiAgDQogIA0KICANCiAgZm9yKHIgaW4gMTpsZW5ndGgocm9sX3ZlY3RvcikpeyMgaXRlcm8gc29icmUgbG9zIHJvbGVzIEgsIFBILCBQTiwgQ04NCiAgcm9sIDwtIHJvbF92ZWN0b3Jbcl0NCiAgDQogICNwLnZhbG9yLm4xIDwtIHQudGVzdChyb2xlX2NvdW50X24xW1tpXV1bLHJvbF0scm9sZV9jb3VudF93W1tpXV1bLHJvbF0pJHAudmFsdWUNCiAgI3AudmFsb3IubjIgPC0gdC50ZXN0KHJvbGVfY291bnRfbjJbW2ldXVsscm9sXSxyb2xlX2NvdW50X3dbW2ldXVsscm9sXSkkcC52YWx1ZQ0KICAjcC52YWxvci5uMyA8LSB0LnRlc3Qocm9sZV9jb3VudF9uM1tbaV1dWyxyb2xdLHJvbGVfY291bnRfd1tbaV1dWyxyb2xdKSRwLnZhbHVlDQogICNwLnZhbG9yLncgPC0gTkENCiAgDQogICNwLnZhbG9yLm4xIDwtIHVubGlzdChzdW1tYXJ5KGFvdihyb2xlX2NvdW50X24xW1tpXV1bLHJvbF1+cm9sZV9jb3VudF93W1tpXV1bLHJvbF0pKVtbMV1dKVtbOV1dDQogICNwLnZhbG9yLm4yIDwtIHVubGlzdChzdW1tYXJ5KGFvdihyb2xlX2NvdW50X24yW1tpXV1bLHJvbF1+cm9sZV9jb3VudF93W1tpXV1bLHJvbF0pKVtbMV1dKVtbOV1dDQogICNwLnZhbG9yLm4zIDwtIHVubGlzdChzdW1tYXJ5KGFvdihyb2xlX2NvdW50X24zW1tpXV1bLHJvbF1+cm9sZV9jb3VudF93W1tpXV1bLHJvbF0pKVtbMV1dKVtbOV1dDQogICNwLnZhbG9yLncgPC0gTkENCiAgDQogIHAudmFsb3IubjEgPC0gd2lsY294LnRlc3Qocm9sZV9jb3VudF9uMVtbaV1dWyxyb2xdLHJvbGVfY291bnRfd1tbaV1dWyxyb2xdLCBjb25mLmxldmVsID0gMC45NSkkcC52YWx1ZQ0KICBwLnZhbG9yLm4yIDwtIHdpbGNveC50ZXN0KHJvbGVfY291bnRfbjJbW2ldXVsscm9sXSxyb2xlX2NvdW50X3dbW2ldXVsscm9sXSwgY29uZi5sZXZlbCA9IDAuOTUpJHAudmFsdWUNCiAgcC52YWxvci5uMyA8LSB3aWxjb3gudGVzdChyb2xlX2NvdW50X24zW1tpXV1bLHJvbF0scm9sZV9jb3VudF93W1tpXV1bLHJvbF0sIGNvbmYubGV2ZWwgPSAwLjk1KSRwLnZhbHVlDQogIHAudmFsb3IudyA8LSBOQQ0KICANCiAgTjFfbWVhbl90ZW1wIDwtIG1lYW4ocm9sZV9jb3VudF9uMVtbaV1dWyxyb2xdKQ0KICBOMl9tZWFuX3RlbXAgPC0gbWVhbihyb2xlX2NvdW50X24yW1tpXV1bLHJvbF0pDQogIE4zX21lYW5fdGVtcCA8LSBtZWFuKHJvbGVfY291bnRfbjNbW2ldXVsscm9sXSkNCiAgV19tZWFuX3RlbXAgPC0gbWVhbihyb2xlX2NvdW50X3dbW2ldXVsscm9sXSkNCiAgTjFfc2VfdGVtcCA8LSBzZChyb2xlX2NvdW50X24xW1tpXV1bLHJvbF0pL3NxcnQobGVuZ3RoKHJvbGVfY291bnRfbjFbW2ldXVsscm9sXSkpDQogIE4yX3NlX3RlbXAgPC0gc2Qocm9sZV9jb3VudF9uMltbaV1dWyxyb2xdKS9zcXJ0KGxlbmd0aChyb2xlX2NvdW50X24yW1tpXV1bLHJvbF0pKQ0KICBOM19zZV90ZW1wIDwtIHNkKHJvbGVfY291bnRfbjNbW2ldXVsscm9sXSkvc3FydChsZW5ndGgocm9sZV9jb3VudF9uM1tbaV1dWyxyb2xdKSkNCiAgV19zZV90ZW1wIDwtIHNkKHJvbGVfY291bnRfd1tbaV1dWyxyb2xdKS9zcXJ0KGxlbmd0aChyb2xlX2NvdW50X3dbW2ldXVsscm9sXSkpDQogIA0KICANCiAgDQogIA0KICANCiAgY29tcGFyaXNvbl9yZXN1bHRzX2RmIDwtIHJiaW5kKGNvbXBhcmlzb25fcmVzdWx0c19kZiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YS5mcmFtZShlc3RhZGlvID0gIk4xIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByb2wgPSByb2wsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbHRhPXNlcVtpXSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZWFuPU4xX21lYW5fdGVtcCwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2U9IE4xX3NlX3RlbXAsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcF92YWxvciA9IHAudmFsb3IubjEpICkNCiAgDQogIGNvbXBhcmlzb25fcmVzdWx0c19kZiA8LSByYmluZChjb21wYXJpc29uX3Jlc3VsdHNfZGYsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEuZnJhbWUoZXN0YWRpbyA9ICJOMiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcm9sID0gcm9sLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWx0YT1zZXFbaV0sDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVhbj1OMl9tZWFuX3RlbXAsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlPSBOMl9zZV90ZW1wLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBfdmFsb3IgPSBwLnZhbG9yLm4yKSApDQogIGNvbXBhcmlzb25fcmVzdWx0c19kZiA8LSByYmluZChjb21wYXJpc29uX3Jlc3VsdHNfZGYsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEuZnJhbWUoZXN0YWRpbyA9ICJOMyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcm9sID0gcm9sLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWx0YT1zZXFbaV0sDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVhbj1OM19tZWFuX3RlbXAsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlPSBOM19zZV90ZW1wLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBfdmFsb3IgPSBwLnZhbG9yLm4zKSApDQogIGNvbXBhcmlzb25fcmVzdWx0c19kZiA8LSByYmluZChjb21wYXJpc29uX3Jlc3VsdHNfZGYsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEuZnJhbWUoZXN0YWRpbyA9ICJXIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByb2wgPSByb2wsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbHRhPXNlcVtpXSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZWFuPVdfbWVhbl90ZW1wLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZT0gV19zZV90ZW1wLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBfdmFsb3IgPSBwLnZhbG9yLncpICkNCiAgDQogIA0KDQp9DQp9DQoNCg0KDQoNCg0KDQpgYGANCg0KDQpgYGB7cn0NCiMjIyMgZ3JhZmljb3MNCnB2X3JlZiA8LSAwLjA1ICNzaWduaWZpY2FuY2lhDQoNCnBsb3RzIDwtIE5BDQoNCmk8LSAxDQpqPC0gMg0KDQplc3RhZGlvX3JlZl92ZWN0b3I8LSBjKCJOMSIsIk4yIiwiTjMiKQ0Kcm9sZV9yZWZfdmVjdG9yIDwtIGMoIkgiLCJQSCIsIlBOIiwgIkNOIikNCnJvbGVfbmFtZV9yZWZfdmVjdG9yIDwtIGMoIkh1YnMiLCJQcm92aW5jaWFsIEh1YnMiLCJQb3ZpbmNpYWwgTm9kZXMiLCAiQ29ubmVjdGlvbiBOb2RlcyIpDQoNCg0KZm9yKGkgaW4gMTpsZW5ndGgocm9sZV9yZWZfdmVjdG9yKSl7DQogIGZvcihqIGluIDE6bGVuZ3RoKGVzdGFkaW9fcmVmX3ZlY3Rvcikpew0KDQoNCg0KZXN0YWRpb19yZWY8LSBlc3RhZGlvX3JlZl92ZWN0b3Jbal0NCnJvbGVfcmVmIDwtIHJvbGVfcmVmX3ZlY3RvcltpXQ0Kcm9sZV9uYW1lX3JlZiA8LXJvbGVfbmFtZV9yZWZfdmVjdG9yW2ldDQp5X2xhYmVsIDwtIHBhc3RlKHJvbGVfbmFtZV9yZWYpDQp0aXRsZV9sYWJlbCA8LSBwYXN0ZSgiV0FLRSB2cy4iLGVzdGFkaW9fcmVmKQ0KDQojdGl0bGVfbGFiZWwgPC0gcGFzdGUocm9sZV9yZWYsIm1lYW4gY291bnQiKQ0KI3lfbGFiZWwgPC0gcm9sZV9yZWYNCg0KDQoNCnRlc3RfZGYgPC0gY29tcGFyaXNvbl9yZXN1bHRzX2RmW2NvbXBhcmlzb25fcmVzdWx0c19kZiRlc3RhZGlvICVpbiUgYyhlc3RhZGlvX3JlZiwiVyIpICYNCmNvbXBhcmlzb25fcmVzdWx0c19kZiRyb2wgJWluJSBjKHJvbGVfcmVmKSxdDQp0ZXN0X2RmPC0gdHJhbnNmb3JtKHRlc3RfZGYsIHBfdmFsb3IgPSBpZmVsc2UocF92YWxvciA8IHB2X3JlZiwgMCwgTkEpKQ0KDQpwZCA8LSBwb3NpdGlvbl9kb2RnZSgwLjAwMSkgIyBtb3ZlIHRoZW0gLjA1IHRvIHRoZSBsZWZ0IGFuZCByaWdodA0KDQoNCmlmIChhbGwoaXMubmEodGVzdF9kZiRwX3ZhbG9yKSkpIHsNCiAgIHA8LSBnZ3Bsb3QodGVzdF9kZiwgYWVzKHg9ZGVsdGEsIHk9bWVhbiwgY29sb3VyPWVzdGFkaW8pKSArIA0KICAgICAgICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluPW1lYW4tc2UsIHltYXg9bWVhbitzZSksIHdpZHRoPS4wMDUscG9zaXRpb249cGQpICsNCiAgICAgICAgZ2VvbV9saW5lKHBvc2l0aW9uPXBkKSArDQogICAgICAgIGdlb21fcG9pbnQocG9zaXRpb249cGQpICsNCiAgICAgICAgI2dlb21fcG9pbnQoYWVzKHk9cF92YWxvcikscG9zaXRpb249cGQpICsNCiAgICAgICAgbGFicyh0aXRsZT10aXRsZV9sYWJlbCwgeCA9ICJkZWx0YSIsIHk9eV9sYWJlbCkNCn0gZWxzZSB7DQogICBwPC1nZ3Bsb3QodGVzdF9kZiwgYWVzKHg9ZGVsdGEsIHk9bWVhbiwgY29sb3VyPWVzdGFkaW8pKSArIA0KICAgICAgICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluPW1lYW4tc2UsIHltYXg9bWVhbitzZSksIHdpZHRoPS4wMDUscG9zaXRpb249cGQpICsNCiAgICAgICAgZ2VvbV9saW5lKHBvc2l0aW9uPXBkKSArDQogICAgICAgIGdlb21fcG9pbnQocG9zaXRpb249cGQpICsNCiAgICAgICAgZ2VvbV9wb2ludChhZXMoeT1wX3ZhbG9yKSxwb3NpdGlvbj1wZCkgKw0KICAgICAgICBsYWJzKHRpdGxlPXRpdGxlX2xhYmVsLCB4ID0gImRlbHRhIiwgeT15X2xhYmVsKQ0KfQ0KcGxvdHMgPC1jYmluZChwbG90cyxsaXN0KHApKQ0KfQ0KfQ0KDQpgYGANCg0KDQpgYGB7cn0NCg0KbGlicmFyeSgiY293cGxvdCIpDQoNCnBsb3RzIDwtIHBsb3RzWy0xXQ0KDQpwbG90X2dyaWQocGxvdHNbWzFdXSwNCiAgICAgICAgICBwbG90c1tbMl1dLA0KICAgICAgICAgIHBsb3RzW1szXV0sDQogICAgICAgICAgcGxvdHNbWzRdXSwNCiAgICAgICAgICBwbG90c1tbNV1dLA0KICAgICAgICAgIHBsb3RzW1s2XV0sDQogICAgICAgICAgcGxvdHNbWzddXSwNCiAgICAgICAgICBwbG90c1tbOF1dLA0KICAgICAgICAgIHBsb3RzW1s5XV0sDQogICAgICAgICAgcGxvdHNbWzEwXV0sDQogICAgICAgICAgcGxvdHNbWzExXV0sDQogICAgICAgICAgcGxvdHNbWzEyXV0sbmNvbCA9IDMpDQoNCg0KYGBgDQoNCg0KDQpgYGB7cn0NCg0KIyBzZSBjYWxjdWxhIGVsIHByb21lZGlvL3NkICBkZSByb2xlcyBwb3IgZXN0YWRpYSBkZSBzdWU/bw0KDQpyb2wgPC0gIkgiDQpyb2xfbmFtZSA8LSAiSHVicyINCg0KDQpOMV9tZWFuX3NlcmllIDwtIHJlcChOQSwgbGVuZ3RoKHNlcSkpDQpOMl9tZWFuX3NlcmllIDwtIHJlcChOQSwgbGVuZ3RoKHNlcSkpDQpOM19tZWFuX3NlcmllIDwtIHJlcChOQSwgbGVuZ3RoKHNlcSkpDQpXX21lYW5fc2VyaWUgPC0gcmVwKE5BLCBsZW5ndGgoc2VxKSkNCk4xX3N0ZF9zZXJpZSA8LSByZXAoTkEsIGxlbmd0aChzZXEpKQ0KTjJfc3RkX3NlcmllIDwtIHJlcChOQSwgbGVuZ3RoKHNlcSkpDQpOM19zdGRfc2VyaWUgPC0gcmVwKE5BLCBsZW5ndGgoc2VxKSkNCldfc3RkX3NlcmllIDwtIHJlcChOQSwgbGVuZ3RoKHNlcSkpDQoNCg0KDQpmb3IoaSBpbiAxOmxlbmd0aChzZXEpKXsgIyBpdGVybyBzb2JyZSBsb3MgZGVsdGFzDQogIGRmX24xIDwtIHJvbGVfY291bnRfbjFbW2ldXQ0KICBkZl9uMiA8LSByb2xlX2NvdW50X24yW1tpXV0NCiAgZGZfbjMgPC0gcm9sZV9jb3VudF9uM1tbaV1dDQogIGRmX3cgPC0gcm9sZV9jb3VudF93W1tpXV0NCiAgTjFfbWVhbl9zZXJpZVtbaV1dIDwtIG1lYW4oZGZfbjFbLHJvbF0pDQogIE4yX21lYW5fc2VyaWVbW2ldXSA8LSBtZWFuKGRmX24yWyxyb2xdKQ0KICBOM19tZWFuX3NlcmllW1tpXV0gPC0gbWVhbihkZl9uM1sscm9sXSkNCiAgV19tZWFuX3NlcmllW1tpXV0gPC0gbWVhbihkZl93Wyxyb2xdKQ0KICBOMV9zdGRfc2VyaWVbW2ldXSA8LSBzZChkZl9uMVsscm9sXSkNCiAgTjJfc3RkX3NlcmllW1tpXV0gPC0gc2QoZGZfbjJbLHJvbF0pDQogIE4zX3N0ZF9zZXJpZVtbaV1dIDwtIHNkKGRmX24zWyxyb2xdKQ0KICBXX3N0ZF9zZXJpZVtbaV1dIDwtIHNkKGRmX3dbLHJvbF0pDQogIA0KICANCiAgDQogIA0KfQ0KDQoNCg0KYGBgDQpgYGANCg0KDQpgYGB7cn0NCg0KDQoNCg0KcGxvdF9yb2xlcyhzZXEsIE4xX21lYW5fc2VyaWUgLCBOMV9zdGRfc2VyaWUsIFdfbWVhbl9zZXJpZSAsIFdfc3RkX3NlcmllLCBlc3RhZGlvPSAiTjEiLCByb2wgPXJvbF9uYW1lKQ0KcGxvdF9yb2xlcyhzZXEsIE4yX21lYW5fc2VyaWUgLCBOMl9zdGRfc2VyaWUsIFdfbWVhbl9zZXJpZSAsIFdfc3RkX3NlcmllLCBlc3RhZGlvPSAiTjIiLCByb2wgPXJvbF9uYW1lKQ0KcGxvdF9yb2xlcyhzZXEsIE4zX21lYW5fc2VyaWUgLCBOM19zdGRfc2VyaWUsIFdfbWVhbl9zZXJpZSAsIFdfc3RkX3NlcmllLCBlc3RhZGlvPSAiTjMiLCByb2wgPXJvbF9uYW1lKQ0KYGBgDQoNCg0KYGBge3J9DQoNCmZvcihpIGluIDE6bGVuZ3RoKHNlcSkpeyAjIGl0ZXJvIHNvYnJlIGxvcyBkZWx0YXMNCiAgZGYgPC0gcm9sZV9jb3VudF9uMVtbaV1dDQogIHBsb3QoZGYpDQp9DQoNCmBgYA0KDQpgYGB7cn0NCg0KZm9yKGkgaW4gMTpsZW5ndGgoc2VxKSl7ICMgaXRlcm8gc29icmUgbG9zIGRlbHRhcw0KICBkZiA8LSByb2xlX2NvdW50X24yW1tpXV0NCiAgcGxvdChkZikNCn0NCg0KYGBgDQoNCmBgYHtyfQ0KDQpmb3IoaSBpbiAxOmxlbmd0aChzZXEpKXsgIyBpdGVybyBzb2JyZSBsb3MgZGVsdGFzDQogIGRmIDwtIHJvbGVfY291bnRfbjNbW2ldXQ0KICBwcmludChwYXN0ZTAoIkRlbHRhICIsc2VxW2ldLCIgLSBNZWFuIEggIixtZWFuKGRmJEgpKSkNCiAgcHJpbnQocGFzdGUwKCJEZWx0YSAiLHNlcVtpXSwiIC0gTWVhbiBQSCAiLG1lYW4oZGYkUEgpKSkNCiAgcHJpbnQocGFzdGUwKCJEZWx0YSAiLHNlcVtpXSwiIC0gTWVhbiBQTiAiLG1lYW4oZGYkUE4pKSkNCiAgcHJpbnQocGFzdGUwKCJEZWx0YSAiLHNlcVtpXSwiIC0gTWVhbiBDTiAiLG1lYW4oZGYkQ04pKSkNCiAgcGxvdChkZikNCn0NCg0KYGBgDQoNCmBgYHtyfQ0KDQpmb3IoaSBpbiAxOmxlbmd0aChzZXEpKXsgIyBpdGVybyBzb2JyZSBsb3MgZGVsdGFzDQogIGRmIDwtIHJvbGVfY291bnRfd1tbaV1dDQogIHBsb3QoZGYpDQp9DQoNCmBgYA0KDQoNCmBgYHtyfQ0Kcm9sZV9jb3VudF9uMV90ZW1wX0ggPC0gTkENCiAgcm9sZV9jb3VudF9uMl90ZW1wX0ggPC0gTkENCiAgcm9sZV9jb3VudF9uM190ZW1wX0ggPC0gTkENCiAgcm9sZV9jb3VudF93X3RlbXBfSCA8LSBOQQ0KICANCiAgcm9sZV9jb3VudF9uMV90ZW1wX1BIIDwtIE5BDQogIHJvbGVfY291bnRfbjJfdGVtcF9QSCA8LSBOQQ0KICByb2xlX2NvdW50X24zX3RlbXBfUEggPC0gTkENCiAgcm9sZV9jb3VudF93X3RlbXBfUEggPC0gTkENCiAgDQogIHJvbGVfY291bnRfbjFfdGVtcF9QTiA8LSBOQQ0KICByb2xlX2NvdW50X24yX3RlbXBfUE4gPC0gTkENCiAgcm9sZV9jb3VudF9uM190ZW1wX1BOIDwtIE5BDQogIHJvbGVfY291bnRfd190ZW1wX1BOIDwtIE5BDQogIA0KICByb2xlX2NvdW50X24xX3RlbXBfQ04gPC0gTkENCiAgcm9sZV9jb3VudF9uMl90ZW1wX0NOIDwtIE5BDQogIHJvbGVfY291bnRfbjNfdGVtcF9DTiA8LSBOQQ0KICByb2xlX2NvdW50X3dfdGVtcF9DTiA8LSBOQQ0KICANCiAgDQogIA0Kcm9sZV9jb3VudF9uMSA8LSBsaXN0KCkNCnJvbGVfY291bnRfbjIgPC0gbGlzdCgpDQpyb2xlX2NvdW50X24zIDwtIGxpc3QoKQ0Kcm9sZV9jb3VudF93IDwtIGxpc3QoKQ0KDQpsb3V2YWluX24xPC1saXN0KCkNCmxvdXZhaW5fbjI8LWxpc3QoKQ0KbG91dmFpbl9uMzwtbGlzdCgpDQpsb3V2YWluX3c8LWxpc3QoKQ0KDQpkZWdyZWVfbjE8LWxpc3QoKQ0KZGVncmVlX24yPC1saXN0KCkNCmRlZ3JlZV9uMzwtbGlzdCgpDQpkZWdyZWVfdzwtbGlzdCgpDQoNCnpfc2NvcmVfbjE8LWxpc3QoKQ0Kel9zY29yZV9uMjwtbGlzdCgpDQp6X3Njb3JlX24zPC1saXN0KCkNCnpfc2NvcmVfdzwtbGlzdCgpDQoNCnBfZmFjdG9yX24xPC1saXN0KCkNCnBfZmFjdG9yX24yPC1saXN0KCkNCnBfZmFjdG9yX24zPC1saXN0KCkNCnBfZmFjdG9yX3c8LWxpc3QoKQ0KDQpgYGANCg0KDQpgYGB7cn0NCg0KYGBgDQoNCg==