rm(list = ls())

#Wczytanie danych
dane_pretest_dzieci <- read.csv("AnkietyPotrafie_Pretest_Dzieci.csv", sep = ";", encoding = "ASCII", stringsAsFactors = FALSE)
dane_pretest_rodzice <- read.csv("AnkietyPotrafie_Pretest_Rodzice.csv", sep = ";", encoding = "ASCII", stringsAsFactors = FALSE)
dane_posttest_dzieci <- read.csv("AnkietyPotrafie_Posttest_Dzieci.csv", sep = ";", encoding = "ASCII", stringsAsFactors = FALSE)
dane_posttest_rodzice <- read.csv("AnkietyPotrafie_Posttest_Rodzice.csv", sep = ";", encoding = "ASCII", stringsAsFactors = FALSE)

nrow(dane_pretest_dzieci)
nrow(dane_pretest_rodzice)
nrow(dane_posttest_dzieci)
nrow(dane_posttest_rodzice)

head(dane_pretest_dzieci) #podgląd pojawi się pod chunkiem
print.data.frame(head(dane_pretest_dzieci, n = 3))

#przydzial_grup <- dane_pretest_dzieci[1,]
#przydzial_grup[['B3']]
#przydzial_grup$B3

#levels(dane_pretest_dzieci$N4)
#dane_pretest_dzieci <- dane_pretest_dzieci[-c(1),]
#levels(dane_pretest_dzieci$N4)
#dane_pretest_dzieci <- droplevels(dane_pretest_dzieci)
#levels(dane_pretest_dzieci$N4)

nrow(dane_pretest_dzieci)
nrow(dane_pretest_rodzice)
nrow(dane_posttest_dzieci)
nrow(dane_posttest_rodzice)

########WYBRANIE PYTAŃ NIEZWIĄZANYCH Z ĆWICZENIAMI W GRZE
#To zakomentować, jeżeli wyniki dla całej ankiety
pytania_z_gry <- c(12:15, 23:26, 35:43, 45, 48:63)
pytania_z_gry
dane_pretest_dzieci <- dane_pretest_dzieci[pytania_z_gry,]
dane_pretest_rodzice <- dane_pretest_rodzice[pytania_z_gry,]
dane_posttest_dzieci <- dane_posttest_dzieci[pytania_z_gry,]
dane_posttest_rodzice <- dane_posttest_rodzice[pytania_z_gry,]
#stopifnot(FALSE)

nrow(dane_pretest_dzieci)
nrow(dane_pretest_rodzice)
nrow(dane_posttest_dzieci)
nrow(dane_posttest_rodzice)

#usunięcie całych pustych kolumn (nie mają NA, a "", bo łańcuchy)
#np. kolumna N4 w dane_pretest_dzieci

dane_pretest_dzieci$B3
dane_pretest_dzieci$N4

#puste_kolumny <- apply(dane_pretest_dzieci=="",2,all)
#puste_kolumny
#dane_pretest_dzieci <- dane_pretest_dzieci[,!puste_kolumny]

usunPusteKolumny <- function(df)
{
  puste_kolumny <- apply(df=="" | is.na(df),2,all) #is.na w przypadku gdy nie ma nawet nagłówka
  puste_kolumny
  result <- df[,!puste_kolumny]
  return(result)
}

dane_pretest_dzieci <- usunPusteKolumny(dane_pretest_dzieci)
dane_pretest_rodzice <- usunPusteKolumny(dane_pretest_rodzice)
dane_posttest_dzieci <- usunPusteKolumny(dane_posttest_dzieci)
dane_posttest_rodzice <- usunPusteKolumny(dane_posttest_rodzice)

#można też przy czytaniu użyć parametru na.strings=c("","NA")
dane_pretest_dzieci[dane_pretest_dzieci == ""] <- NA 
dane_pretest_rodzice[dane_pretest_rodzice == ""] <- NA
dane_posttest_dzieci[dane_posttest_dzieci == ""] <- NA
dane_posttest_rodzice[dane_posttest_rodzice == ""] <- NA

#obliczanie wyników dla poszczególnych badanych (średnia z wypełnionych komórek)

#gdyby nie strinAsFactors, zmieniałby na liczby czynniki (łańcuchy są zmieniane na warości czynników; NA = 1, 1 = 2 itd)
dane_pretest_dzieci$B2
as.numeric(dane_pretest_dzieci$B2)
as.integer(dane_pretest_dzieci$B2)

#dane_pretest_dzieci <- dane_pretest_dzieci[,-c(1)]
dane_pretest_dzieci_n = as.data.frame(sapply(dane_pretest_dzieci[,-c(1)], as.numeric))
dane_pretest_rodzice_n = as.data.frame(sapply(dane_pretest_rodzice[,-c(1)], as.numeric))
dane_posttest_dzieci_n = as.data.frame(sapply(dane_posttest_dzieci[,-c(1)], as.numeric))
dane_posttest_rodzice_n = as.data.frame(sapply(dane_posttest_rodzice[,-c(1)], as.numeric))

min(dane_pretest_dzieci_n, na.rm = TRUE)
max(dane_pretest_dzieci_n, na.rm = TRUE)

#obliczanie średnich dla poszczególnych badanych
dane_pretest_dzieci_means <- colMeans(dane_pretest_dzieci_n, na.rm = TRUE)
dane_pretest_rodzice_means <- colMeans(dane_pretest_rodzice_n, na.rm = TRUE)
dane_posttest_dzieci_means <- colMeans(dane_posttest_dzieci_n, na.rm = TRUE)
dane_posttest_rodzice_means <- colMeans(dane_posttest_rodzice_n, na.rm = TRUE)
dane_pretest_dzieci_means
dane_pretest_rodzice_means
dane_posttest_dzieci_means
dane_posttest_rodzice_means

mean(dane_pretest_dzieci_means);sd(dane_pretest_dzieci_means)
mean(dane_pretest_rodzice_means);sd(dane_pretest_rodzice_means)
mean(dane_posttest_dzieci_means);sd(dane_posttest_dzieci_means)
mean(dane_posttest_rodzice_means);sd(dane_posttest_rodzice_means)

#porównanie średnich z pre- i posttestów

#podział na grupy
przydzial_grup <- read.csv("Grupy.csv", sep = ";", encoding = "ASCII", stringsAsFactors = FALSE)
przydzial_grup
grupa_B <- przydzial_grup[przydzial_grup$Grupa == "B",]$Kod.badanego
grupa_K <- przydzial_grup[przydzial_grup$Grupa == "K",]$Kod.badanego
grupa_B
grupa_K

#wykluczenie dzieci, które nie grały (osobny chunk, który trzeba wcześniej uruchomić)
#grupa_B <- grupa_B_wspolna_dzieci_bez_zer
#grupa_B

#pretest-dzieci
names(dane_pretest_dzieci_means)
dane_pretest_dzieci_means_B <- dane_pretest_dzieci_means[grupa_B]
dane_pretest_dzieci_means_B <- dane_pretest_dzieci_means_B[!is.na(dane_pretest_dzieci_means_B)]

dane_pretest_dzieci_means_K <- dane_pretest_dzieci_means[grupa_K]
dane_pretest_dzieci_means_K <- dane_pretest_dzieci_means_K[!is.na(dane_pretest_dzieci_means_K)]

#dane_pretest_dzieci_mean_B <- mean(dane_pretest_dzieci_means_B)
#dane_pretest_dzieci_mean_B

#dane_pretest_dzieci_mean_K <- mean(dane_pretest_dzieci_means_K)
#dane_pretest_dzieci_mean_K

#posttest-dzieci
names(dane_pretest_dzieci_means)
dane_posttest_dzieci_means_B <- dane_posttest_dzieci_means[grupa_B]
dane_posttest_dzieci_means_B <- dane_posttest_dzieci_means_B[!is.na(dane_posttest_dzieci_means_B)]

dane_posttest_dzieci_means_K <- dane_posttest_dzieci_means[grupa_K]
dane_posttest_dzieci_means_K <- dane_posttest_dzieci_means_K[!is.na(dane_posttest_dzieci_means_K)]

#dane_posttest_dzieci_mean_B <- mean(dane_posttest_dzieci_means_B)
#dane_posttest_dzieci_mean_B

#dane_posttest_dzieci_mean_K <- mean(dane_posttest_dzieci_means_K)
#dane_posttest_dzieci_mean_K

#pretest-rodzice
names(dane_pretest_rodzice_means)
dane_pretest_rodzice_means_B <- dane_pretest_rodzice_means[grupa_B]
dane_pretest_rodzice_means_B <- dane_pretest_rodzice_means_B[!is.na(dane_pretest_rodzice_means_B)]

dane_pretest_rodzice_means_K <- dane_pretest_rodzice_means[grupa_K]
dane_pretest_rodzice_means_K <- dane_pretest_rodzice_means_K[!is.na(dane_pretest_rodzice_means_K)]

#dane_pretest_rodzice_mean_B <- mean(dane_pretest_rodzice_means_B)
#dane_pretest_rodzice_mean_B

#dane_pretest_rodzice_mean_K <- mean(dane_pretest_rodzice_means_K)
#dane_pretest_rodzice_mean_K

#posttest-rodzice
names(dane_pretest_rodzice_means)
dane_posttest_rodzice_means_B <- dane_posttest_rodzice_means[grupa_B]
dane_posttest_rodzice_means_B <- dane_posttest_rodzice_means_B[!is.na(dane_posttest_rodzice_means_B)]

dane_posttest_rodzice_means_K <- dane_posttest_rodzice_means[grupa_K]
dane_posttest_rodzice_means_K <- dane_posttest_rodzice_means_K[!is.na(dane_posttest_rodzice_means_K)]

#dane_posttest_rodzice_mean_B <- mean(dane_posttest_rodzice_means_B)
#dane_posttest_rodzice_mean_B

#dane_posttest_rodzice_mean_K <- mean(dane_posttest_rodzice_means_K)
#dane_posttest_rodzice_mean_K

#==== DZIECI ====
#prettest-posttest - powtórzony pomiar -> próby zależne
#B-K - próby niezależne

#PORÓWNANIE GRUP B i K W PRETEŚCIE (próby niezaleźne)
length(dane_pretest_dzieci_means_B)
length(dane_pretest_dzieci_means_K)
shapiro.test(dane_pretest_dzieci_means_B)$p.value #> 0.05
shapiro.test(dane_pretest_dzieci_means_K)$p.value
#oba rozkłady są normalne
t.test(dane_pretest_dzieci_means_B,dane_pretest_dzieci_means_K,paired = FALSE) #p = 0.49 - próby nie są różne

#Porównanie grup B i K w postteście
length(dane_posttest_dzieci_means_B)
length(dane_posttest_dzieci_means_K)
shapiro.test(dane_posttest_dzieci_means_B)$p.value #> 0.05
shapiro.test(dane_posttest_dzieci_means_K)$p.value
#oba rozkłady są normalne, choć p jest wyraźnie mniejsze
t.test(dane_posttest_dzieci_means_B,dane_posttest_dzieci_means_K,paired = FALSE) #p = 0.1 - tendencja
wilcox.test(dane_posttest_dzieci_means_B,dane_posttest_dzieci_means_K,paired = FALSE) #p = 0.1 - tendencja
#stopifnot(FALSE)

#PORÓWNANIE PRETESTÓW I POSTTESTÓW DLA OBU GRUP (próby zależne)

#trzeba znaleźć wspólny podzbiór
grupa_B_wspolna_dzieci <- intersect(names(dane_pretest_dzieci_means_B),names(dane_posttest_dzieci_means_B))
grupa_B_wspolna_dzieci
length(grupa_B_wspolna_dzieci)
t.test(dane_pretest_dzieci_means_B[grupa_B_wspolna_dzieci],dane_posttest_dzieci_means_B[grupa_B_wspolna_dzieci],paired = TRUE)
wilcox.test(dane_pretest_dzieci_means_B[grupa_B_wspolna_dzieci],dane_posttest_dzieci_means_B[grupa_B_wspolna_dzieci],paired = TRUE)

#sprawdzenie kolejności
dane_pretest_dzieci_means_B[grupa_B_wspolna_dzieci]
dane_posttest_dzieci_means_B[grupa_B_wspolna_dzieci]

grupa_K_wspolna_dzieci <- intersect(names(dane_pretest_dzieci_means_K),names(dane_posttest_dzieci_means_K))
grupa_K_wspolna_dzieci
length(grupa_K_wspolna_dzieci)
t.test(dane_pretest_dzieci_means_K[grupa_K_wspolna_dzieci],dane_posttest_dzieci_means_K[grupa_K_wspolna_dzieci],paired = TRUE)

#Sprawdzenie jak obliczana jest różnica
grupa_B_wspolna_dzieci
dane_pretest_dzieci_means_B
dane_pretest_dzieci_means_B[grupa_B_wspolna_dzieci]
mean(dane_pretest_dzieci_means_B[grupa_B_wspolna_dzieci],na.rm = FALSE)
mean(dane_posttest_dzieci_means_B[grupa_B_wspolna_dzieci],na.rm = FALSE)
mean(dane_posttest_dzieci_means_B[grupa_B_wspolna_dzieci],na.rm = FALSE)-mean(dane_pretest_dzieci_means_B[grupa_B_wspolna_dzieci],na.rm = FALSE)

#==== RODZICE ====
#prettest-posttest - powtórzony pomiar -> próby zależne
#B-K - próby niezależne

#PORÓWNANIE GRUP B i K W PRETEŚCIE (próby niezaleźne)
length(dane_pretest_rodzice_means_B)
length(dane_pretest_rodzice_means_K)
shapiro.test(dane_pretest_rodzice_means_B)$p.value #> 0.05
shapiro.test(dane_pretest_rodzice_means_K)$p.value
#oba rozkłady są normalne
t.test(dane_pretest_rodzice_means_B,dane_pretest_rodzice_means_K,paired = FALSE) #p = 0.49 - próby nie są różne

#Porównanie grup B i K w postteście
length(dane_posttest_rodzice_means_B)
length(dane_posttest_rodzice_means_K)
shapiro.test(dane_posttest_rodzice_means_B)$p.value #> 0.05
shapiro.test(dane_posttest_rodzice_means_K)$p.value
#oba rozkłady są normalne, choć p jest wyraźnie mniejsze
t.test(dane_posttest_rodzice_means_B,dane_posttest_rodzice_means_K,paired = FALSE) #p = 0.1 - tendencja
wilcox.test(dane_posttest_rodzice_means_B,dane_posttest_rodzice_means_K,paired = FALSE)
#stopifnot(FALSE)

#PORÓWNANIE PRETESTÓW I POSTTESTÓW DLA OBU GRUP (próby zależne)

#trzeba znaleźć wspólny podzbiór
grupa_B_wspolna_rodzice <- intersect(names(dane_pretest_rodzice_means_B),names(dane_posttest_rodzice_means_B))
#####!!!!!!!!!!!!!UWAGA! Ta sama zmienna wykorzystywana w różnych kontekstach. Wyrywkowe uruchamianie może być bez sensu
grupa_B_wspolna_rodzice
length(grupa_B_wspolna_rodzice)
t.test(dane_pretest_rodzice_means_B[grupa_B_wspolna_rodzice],dane_posttest_rodzice_means_B[grupa_B_wspolna_rodzice],paired = TRUE)
wilcox.test(dane_pretest_rodzice_means_B[grupa_B_wspolna_rodzice],dane_posttest_rodzice_means_B[grupa_B_wspolna_rodzice],paired = TRUE)

grupa_K_wspolna_rodzice <- intersect(names(dane_pretest_rodzice_means_K),names(dane_posttest_rodzice_means_K))
grupa_K_wspolna_rodzice
length(grupa_K_wspolna_rodzice)
t.test(dane_pretest_rodzice_means_K[grupa_K_wspolna_rodzice],dane_posttest_rodzice_means_K[grupa_K_wspolna_rodzice],paired = TRUE)

#==== DZIECI vs RODZICE ====

#PRETEST, B
grupa_B_wspolna_pretest_dr <- intersect(names(dane_pretest_dzieci_means_B),names(dane_pretest_rodzice_means_B))
grupa_B_wspolna_pretest_dr
length(grupa_B_wspolna_pretest_dr)
t.test(dane_pretest_dzieci_means_B[grupa_B_wspolna_pretest_dr],dane_pretest_rodzice_means_B[grupa_B_wspolna_pretest_dr],paired = TRUE)

#PRETEST, K
grupa_K_wspolna_pretest_dr <- intersect(names(dane_pretest_dzieci_means_K),names(dane_pretest_rodzice_means_K))
grupa_K_wspolna_pretest_dr
length(grupa_K_wspolna_pretest_dr)
t.test(dane_pretest_dzieci_means_K[grupa_K_wspolna_pretest_dr],dane_pretest_rodzice_means_K[grupa_K_wspolna_pretest_dr],paired = TRUE)

#POSTTEST, B
grupa_B_wspolna_posttest_dr <- intersect(names(dane_posttest_dzieci_means_B),names(dane_posttest_rodzice_means_B))
grupa_B_wspolna_posttest_dr
length(grupa_B_wspolna_posttest_dr)
t.test(dane_posttest_dzieci_means_B[grupa_B_wspolna_posttest_dr],dane_posttest_rodzice_means_B[grupa_B_wspolna_posttest_dr],paired = TRUE)
wilcox.test(dane_posttest_dzieci_means_B[grupa_B_wspolna_posttest_dr],dane_posttest_rodzice_means_B[grupa_B_wspolna_posttest_dr],paired = TRUE)

#POSTTEST, K
grupa_K_wspolna_posttest_dr <- intersect(names(dane_posttest_dzieci_means_K),names(dane_posttest_rodzice_means_K))
grupa_K_wspolna_posttest_dr
length(grupa_K_wspolna_posttest_dr)
t.test(dane_posttest_dzieci_means_K[grupa_K_wspolna_posttest_dr],dane_posttest_rodzice_means_K[grupa_K_wspolna_posttest_dr],paired = TRUE)

#Wykres dzieci
plotDaneB <- c("pretest" = mean(dane_pretest_dzieci_means_B), "posttest" = mean(dane_posttest_dzieci_means_B))
plotDaneB
names(plotDaneB)
plotDaneK <- c("pretest" = mean(dane_pretest_dzieci_means_K),"posttest" = mean(dane_posttest_dzieci_means_K))
plotDaneK

par(oma = c(1, 0, 0, 0), mar = c(3, 7, 2, 2)) 
plot(plotDaneB, type="b", xlab = "", ylab = "poziom umiejętności", xlim=c(0.75,2.25), ylim=c(2.9,3.6), xaxt="n", pch=19)
#lines(plotDaneB, type = "l")
points(plotDaneK, type = "b", pch=1)
#lines(plotDaneK, type = "l")
axis(1, at=1:2, tick=1, labels=names(plotDaneB))

#Wykres rodzice
plotDaneB <- c("pretest" = mean(dane_pretest_rodzice_means_B), "posttest" = mean(dane_posttest_rodzice_means_B))
plotDaneB
names(plotDaneB)
plotDaneK <- c("pretest" = mean(dane_pretest_rodzice_means_K),"posttest" = mean(dane_posttest_rodzice_means_K))
plotDaneK

par(oma = c(1, 0, 0, 0), mar = c(3, 7, 2, 2)) 
plot(plotDaneB, type="b", xlab = "", ylab = "poziom umiejętności", xlim=c(0.75,2.25), ylim=c(2.5,3.5), xaxt="n", pch=19)
#lines(plotDaneB, type = "l")
points(plotDaneK, type = "b", pch=1)
#lines(plotDaneK, type = "l")
axis(1, at=1:2, tick=1, labels=names(plotDaneB))

#Rodzice vs dzieci

#cały pretest (niezależne)
shapiro.test(dane_pretest_dzieci_means)
shapiro.test(dane_pretest_rodzice_means)
t.test(dane_pretest_dzieci_means, dane_pretest_rodzice_means, paired = FALSE)
plotDanePretest <- c("dzieci" = mean(dane_pretest_dzieci_means), "rodzice" = mean(dane_pretest_rodzice_means))
barplot(plotDanePretest)

#pretest, B - zależna
plotDanePretestB <- c(
  "dzieci" = mean(dane_pretest_dzieci_means_B[grupa_B_wspolna_pretest_dr]),
  "rodzice" = mean(dane_pretest_rodzice_means_B[grupa_B_wspolna_pretest_dr]))
barplot(plotDanePretestB)


#posttest, B - zależna
plotDanePosttestB <- c(
  "dzieci" = mean(dane_posttest_dzieci_means_B[grupa_B_wspolna_posttest_dr]),
  "rodzice" = mean(dane_posttest_rodzice_means_B[grupa_B_wspolna_posttest_dr]))
barplot(plotDanePosttestB)

#pretest, K - zależna
plotDanePretestK <- c(
  "dzieci" = mean(dane_pretest_dzieci_means_K[grupa_K_wspolna_pretest_dr]),
  "rodzice" = mean(dane_pretest_rodzice_means_K[grupa_K_wspolna_pretest_dr]))
plotDanePretestK
barplot(plotDanePretestK)

#posttest, K - zależna
plotDanePosttestK <- c(
  "dzieci" = mean(dane_posttest_dzieci_means_K[grupa_K_wspolna_posttest_dr]),
  "rodzice" = mean(dane_posttest_rodzice_means_K[grupa_K_wspolna_posttest_dr]))
barplot(plotDanePosttestK)
LS0tDQp0aXRsZTogIkt1cnNSIFRHUFAiDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQoNCmBgYHtyIEFua2lldGEgUG90cmFmacSZL05pZSBwb3RyYWZpxJl9DQpybShsaXN0ID0gbHMoKSkNCg0KI1djenl0YW5pZSBkYW55Y2gNCmRhbmVfcHJldGVzdF9kemllY2kgPC0gcmVhZC5jc3YoIkFua2lldHlQb3RyYWZpZV9QcmV0ZXN0X0R6aWVjaS5jc3YiLCBzZXAgPSAiOyIsIGVuY29kaW5nID0gIkFTQ0lJIiwgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFKQ0KZGFuZV9wcmV0ZXN0X3JvZHppY2UgPC0gcmVhZC5jc3YoIkFua2lldHlQb3RyYWZpZV9QcmV0ZXN0X1JvZHppY2UuY3N2Iiwgc2VwID0gIjsiLCBlbmNvZGluZyA9ICJBU0NJSSIsIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRSkNCmRhbmVfcG9zdHRlc3RfZHppZWNpIDwtIHJlYWQuY3N2KCJBbmtpZXR5UG90cmFmaWVfUG9zdHRlc3RfRHppZWNpLmNzdiIsIHNlcCA9ICI7IiwgZW5jb2RpbmcgPSAiQVNDSUkiLCBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UpDQpkYW5lX3Bvc3R0ZXN0X3JvZHppY2UgPC0gcmVhZC5jc3YoIkFua2lldHlQb3RyYWZpZV9Qb3N0dGVzdF9Sb2R6aWNlLmNzdiIsIHNlcCA9ICI7IiwgZW5jb2RpbmcgPSAiQVNDSUkiLCBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UpDQoNCm5yb3coZGFuZV9wcmV0ZXN0X2R6aWVjaSkNCm5yb3coZGFuZV9wcmV0ZXN0X3JvZHppY2UpDQpucm93KGRhbmVfcG9zdHRlc3RfZHppZWNpKQ0KbnJvdyhkYW5lX3Bvc3R0ZXN0X3JvZHppY2UpDQoNCmhlYWQoZGFuZV9wcmV0ZXN0X2R6aWVjaSkgI3BvZGdsxIVkIHBvamF3aSBzacSZIHBvZCBjaHVua2llbQ0KcHJpbnQuZGF0YS5mcmFtZShoZWFkKGRhbmVfcHJldGVzdF9kemllY2ksIG4gPSAzKSkNCg0KI3ByenlkemlhbF9ncnVwIDwtIGRhbmVfcHJldGVzdF9kemllY2lbMSxdDQojcHJ6eWR6aWFsX2dydXBbWydCMyddXQ0KI3ByenlkemlhbF9ncnVwJEIzDQoNCiNsZXZlbHMoZGFuZV9wcmV0ZXN0X2R6aWVjaSRONCkNCiNkYW5lX3ByZXRlc3RfZHppZWNpIDwtIGRhbmVfcHJldGVzdF9kemllY2lbLWMoMSksXQ0KI2xldmVscyhkYW5lX3ByZXRlc3RfZHppZWNpJE40KQ0KI2RhbmVfcHJldGVzdF9kemllY2kgPC0gZHJvcGxldmVscyhkYW5lX3ByZXRlc3RfZHppZWNpKQ0KI2xldmVscyhkYW5lX3ByZXRlc3RfZHppZWNpJE40KQ0KDQpucm93KGRhbmVfcHJldGVzdF9kemllY2kpDQpucm93KGRhbmVfcHJldGVzdF9yb2R6aWNlKQ0KbnJvdyhkYW5lX3Bvc3R0ZXN0X2R6aWVjaSkNCm5yb3coZGFuZV9wb3N0dGVzdF9yb2R6aWNlKQ0KDQojIyMjIyMjI1dZQlJBTklFIFBZVEHFgyBOSUVaV0nEhFpBTllDSCBaIMSGV0lDWkVOSUFNSSBXIEdSWkUNCiNUbyB6YWtvbWVudG93YcSHLCBqZcW8ZWxpIHd5bmlraSBkbGEgY2HFgmVqIGFua2lldHkNCnB5dGFuaWFfel9ncnkgPC0gYygxMjoxNSwgMjM6MjYsIDM1OjQzLCA0NSwgNDg6NjMpDQpweXRhbmlhX3pfZ3J5DQpkYW5lX3ByZXRlc3RfZHppZWNpIDwtIGRhbmVfcHJldGVzdF9kemllY2lbcHl0YW5pYV96X2dyeSxdDQpkYW5lX3ByZXRlc3Rfcm9kemljZSA8LSBkYW5lX3ByZXRlc3Rfcm9kemljZVtweXRhbmlhX3pfZ3J5LF0NCmRhbmVfcG9zdHRlc3RfZHppZWNpIDwtIGRhbmVfcG9zdHRlc3RfZHppZWNpW3B5dGFuaWFfel9ncnksXQ0KZGFuZV9wb3N0dGVzdF9yb2R6aWNlIDwtIGRhbmVfcG9zdHRlc3Rfcm9kemljZVtweXRhbmlhX3pfZ3J5LF0NCiNzdG9waWZub3QoRkFMU0UpDQoNCm5yb3coZGFuZV9wcmV0ZXN0X2R6aWVjaSkNCm5yb3coZGFuZV9wcmV0ZXN0X3JvZHppY2UpDQpucm93KGRhbmVfcG9zdHRlc3RfZHppZWNpKQ0KbnJvdyhkYW5lX3Bvc3R0ZXN0X3JvZHppY2UpDQoNCiN1c3VuacSZY2llIGNhxYJ5Y2ggcHVzdHljaCBrb2x1bW4gKG5pZSBtYWrEhSBOQSwgYSAiIiwgYm8gxYJhxYRjdWNoeSkNCiNucC4ga29sdW1uYSBONCB3IGRhbmVfcHJldGVzdF9kemllY2kNCg0KZGFuZV9wcmV0ZXN0X2R6aWVjaSRCMw0KZGFuZV9wcmV0ZXN0X2R6aWVjaSRONA0KDQojcHVzdGVfa29sdW1ueSA8LSBhcHBseShkYW5lX3ByZXRlc3RfZHppZWNpPT0iIiwyLGFsbCkNCiNwdXN0ZV9rb2x1bW55DQojZGFuZV9wcmV0ZXN0X2R6aWVjaSA8LSBkYW5lX3ByZXRlc3RfZHppZWNpWywhcHVzdGVfa29sdW1ueV0NCg0KdXN1blB1c3RlS29sdW1ueSA8LSBmdW5jdGlvbihkZikNCnsNCiAgcHVzdGVfa29sdW1ueSA8LSBhcHBseShkZj09IiIgfCBpcy5uYShkZiksMixhbGwpICNpcy5uYSB3IHByenlwYWRrdSBnZHkgbmllIG1hIG5hd2V0IG5hZ8WCw7N3a2ENCiAgcHVzdGVfa29sdW1ueQ0KICByZXN1bHQgPC0gZGZbLCFwdXN0ZV9rb2x1bW55XQ0KICByZXR1cm4ocmVzdWx0KQ0KfQ0KDQpkYW5lX3ByZXRlc3RfZHppZWNpIDwtIHVzdW5QdXN0ZUtvbHVtbnkoZGFuZV9wcmV0ZXN0X2R6aWVjaSkNCmRhbmVfcHJldGVzdF9yb2R6aWNlIDwtIHVzdW5QdXN0ZUtvbHVtbnkoZGFuZV9wcmV0ZXN0X3JvZHppY2UpDQpkYW5lX3Bvc3R0ZXN0X2R6aWVjaSA8LSB1c3VuUHVzdGVLb2x1bW55KGRhbmVfcG9zdHRlc3RfZHppZWNpKQ0KZGFuZV9wb3N0dGVzdF9yb2R6aWNlIDwtIHVzdW5QdXN0ZUtvbHVtbnkoZGFuZV9wb3N0dGVzdF9yb2R6aWNlKQ0KDQojbW/FvG5hIHRlxbwgcHJ6eSBjenl0YW5pdSB1xbx5xIcgcGFyYW1ldHJ1IG5hLnN0cmluZ3M9YygiIiwiTkEiKQ0KZGFuZV9wcmV0ZXN0X2R6aWVjaVtkYW5lX3ByZXRlc3RfZHppZWNpID09ICIiXSA8LSBOQSANCmRhbmVfcHJldGVzdF9yb2R6aWNlW2RhbmVfcHJldGVzdF9yb2R6aWNlID09ICIiXSA8LSBOQQ0KZGFuZV9wb3N0dGVzdF9kemllY2lbZGFuZV9wb3N0dGVzdF9kemllY2kgPT0gIiJdIDwtIE5BDQpkYW5lX3Bvc3R0ZXN0X3JvZHppY2VbZGFuZV9wb3N0dGVzdF9yb2R6aWNlID09ICIiXSA8LSBOQQ0KDQojb2JsaWN6YW5pZSB3eW5pa8OzdyBkbGEgcG9zemN6ZWfDs2xueWNoIGJhZGFueWNoICjFm3JlZG5pYSB6IHd5cGXFgm5pb255Y2gga29tw7NyZWspDQoNCiNnZHlieSBuaWUgc3RyaW5Bc0ZhY3RvcnMsIHptaWVuaWHFgmJ5IG5hIGxpY3pieSBjenlubmlraSAoxYJhxYRjdWNoeSBzxIUgem1pZW5pYW5lIG5hIHdhcm/Fm2NpIGN6eW5uaWvDs3c7IE5BID0gMSwgMSA9IDIgaXRkKQ0KZGFuZV9wcmV0ZXN0X2R6aWVjaSRCMg0KYXMubnVtZXJpYyhkYW5lX3ByZXRlc3RfZHppZWNpJEIyKQ0KYXMuaW50ZWdlcihkYW5lX3ByZXRlc3RfZHppZWNpJEIyKQ0KDQojZGFuZV9wcmV0ZXN0X2R6aWVjaSA8LSBkYW5lX3ByZXRlc3RfZHppZWNpWywtYygxKV0NCmRhbmVfcHJldGVzdF9kemllY2lfbiA9IGFzLmRhdGEuZnJhbWUoc2FwcGx5KGRhbmVfcHJldGVzdF9kemllY2lbLC1jKDEpXSwgYXMubnVtZXJpYykpDQpkYW5lX3ByZXRlc3Rfcm9kemljZV9uID0gYXMuZGF0YS5mcmFtZShzYXBwbHkoZGFuZV9wcmV0ZXN0X3JvZHppY2VbLC1jKDEpXSwgYXMubnVtZXJpYykpDQpkYW5lX3Bvc3R0ZXN0X2R6aWVjaV9uID0gYXMuZGF0YS5mcmFtZShzYXBwbHkoZGFuZV9wb3N0dGVzdF9kemllY2lbLC1jKDEpXSwgYXMubnVtZXJpYykpDQpkYW5lX3Bvc3R0ZXN0X3JvZHppY2VfbiA9IGFzLmRhdGEuZnJhbWUoc2FwcGx5KGRhbmVfcG9zdHRlc3Rfcm9kemljZVssLWMoMSldLCBhcy5udW1lcmljKSkNCg0KbWluKGRhbmVfcHJldGVzdF9kemllY2lfbiwgbmEucm0gPSBUUlVFKQ0KbWF4KGRhbmVfcHJldGVzdF9kemllY2lfbiwgbmEucm0gPSBUUlVFKQ0KDQojb2JsaWN6YW5pZSDFm3JlZG5pY2ggZGxhIHBvc3pjemVnw7NsbnljaCBiYWRhbnljaA0KZGFuZV9wcmV0ZXN0X2R6aWVjaV9tZWFucyA8LSBjb2xNZWFucyhkYW5lX3ByZXRlc3RfZHppZWNpX24sIG5hLnJtID0gVFJVRSkNCmRhbmVfcHJldGVzdF9yb2R6aWNlX21lYW5zIDwtIGNvbE1lYW5zKGRhbmVfcHJldGVzdF9yb2R6aWNlX24sIG5hLnJtID0gVFJVRSkNCmRhbmVfcG9zdHRlc3RfZHppZWNpX21lYW5zIDwtIGNvbE1lYW5zKGRhbmVfcG9zdHRlc3RfZHppZWNpX24sIG5hLnJtID0gVFJVRSkNCmRhbmVfcG9zdHRlc3Rfcm9kemljZV9tZWFucyA8LSBjb2xNZWFucyhkYW5lX3Bvc3R0ZXN0X3JvZHppY2VfbiwgbmEucm0gPSBUUlVFKQ0KZGFuZV9wcmV0ZXN0X2R6aWVjaV9tZWFucw0KZGFuZV9wcmV0ZXN0X3JvZHppY2VfbWVhbnMNCmRhbmVfcG9zdHRlc3RfZHppZWNpX21lYW5zDQpkYW5lX3Bvc3R0ZXN0X3JvZHppY2VfbWVhbnMNCg0KbWVhbihkYW5lX3ByZXRlc3RfZHppZWNpX21lYW5zKTtzZChkYW5lX3ByZXRlc3RfZHppZWNpX21lYW5zKQ0KbWVhbihkYW5lX3ByZXRlc3Rfcm9kemljZV9tZWFucyk7c2QoZGFuZV9wcmV0ZXN0X3JvZHppY2VfbWVhbnMpDQptZWFuKGRhbmVfcG9zdHRlc3RfZHppZWNpX21lYW5zKTtzZChkYW5lX3Bvc3R0ZXN0X2R6aWVjaV9tZWFucykNCm1lYW4oZGFuZV9wb3N0dGVzdF9yb2R6aWNlX21lYW5zKTtzZChkYW5lX3Bvc3R0ZXN0X3JvZHppY2VfbWVhbnMpDQoNCiNwb3LDs3duYW5pZSDFm3JlZG5pY2ggeiBwcmUtIGkgcG9zdHRlc3TDs3cNCg0KI3BvZHppYcWCIG5hIGdydXB5DQpwcnp5ZHppYWxfZ3J1cCA8LSByZWFkLmNzdigiR3J1cHkuY3N2Iiwgc2VwID0gIjsiLCBlbmNvZGluZyA9ICJBU0NJSSIsIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRSkNCnByenlkemlhbF9ncnVwDQpncnVwYV9CIDwtIHByenlkemlhbF9ncnVwW3ByenlkemlhbF9ncnVwJEdydXBhID09ICJCIixdJEtvZC5iYWRhbmVnbw0KZ3J1cGFfSyA8LSBwcnp5ZHppYWxfZ3J1cFtwcnp5ZHppYWxfZ3J1cCRHcnVwYSA9PSAiSyIsXSRLb2QuYmFkYW5lZ28NCmdydXBhX0INCmdydXBhX0sNCg0KI3d5a2x1Y3plbmllIGR6aWVjaSwga3TDs3JlIG5pZSBncmHFgnkgKG9zb2JueSBjaHVuaywga3TDs3J5IHRyemViYSB3Y3plxZtuaWVqIHVydWNob21pxIcpDQojZ3J1cGFfQiA8LSBncnVwYV9CX3dzcG9sbmFfZHppZWNpX2Jlel96ZXINCiNncnVwYV9CDQoNCiNwcmV0ZXN0LWR6aWVjaQ0KbmFtZXMoZGFuZV9wcmV0ZXN0X2R6aWVjaV9tZWFucykNCmRhbmVfcHJldGVzdF9kemllY2lfbWVhbnNfQiA8LSBkYW5lX3ByZXRlc3RfZHppZWNpX21lYW5zW2dydXBhX0JdDQpkYW5lX3ByZXRlc3RfZHppZWNpX21lYW5zX0IgPC0gZGFuZV9wcmV0ZXN0X2R6aWVjaV9tZWFuc19CWyFpcy5uYShkYW5lX3ByZXRlc3RfZHppZWNpX21lYW5zX0IpXQ0KDQpkYW5lX3ByZXRlc3RfZHppZWNpX21lYW5zX0sgPC0gZGFuZV9wcmV0ZXN0X2R6aWVjaV9tZWFuc1tncnVwYV9LXQ0KZGFuZV9wcmV0ZXN0X2R6aWVjaV9tZWFuc19LIDwtIGRhbmVfcHJldGVzdF9kemllY2lfbWVhbnNfS1shaXMubmEoZGFuZV9wcmV0ZXN0X2R6aWVjaV9tZWFuc19LKV0NCg0KI2RhbmVfcHJldGVzdF9kemllY2lfbWVhbl9CIDwtIG1lYW4oZGFuZV9wcmV0ZXN0X2R6aWVjaV9tZWFuc19CKQ0KI2RhbmVfcHJldGVzdF9kemllY2lfbWVhbl9CDQoNCiNkYW5lX3ByZXRlc3RfZHppZWNpX21lYW5fSyA8LSBtZWFuKGRhbmVfcHJldGVzdF9kemllY2lfbWVhbnNfSykNCiNkYW5lX3ByZXRlc3RfZHppZWNpX21lYW5fSw0KDQojcG9zdHRlc3QtZHppZWNpDQpuYW1lcyhkYW5lX3ByZXRlc3RfZHppZWNpX21lYW5zKQ0KZGFuZV9wb3N0dGVzdF9kemllY2lfbWVhbnNfQiA8LSBkYW5lX3Bvc3R0ZXN0X2R6aWVjaV9tZWFuc1tncnVwYV9CXQ0KZGFuZV9wb3N0dGVzdF9kemllY2lfbWVhbnNfQiA8LSBkYW5lX3Bvc3R0ZXN0X2R6aWVjaV9tZWFuc19CWyFpcy5uYShkYW5lX3Bvc3R0ZXN0X2R6aWVjaV9tZWFuc19CKV0NCg0KZGFuZV9wb3N0dGVzdF9kemllY2lfbWVhbnNfSyA8LSBkYW5lX3Bvc3R0ZXN0X2R6aWVjaV9tZWFuc1tncnVwYV9LXQ0KZGFuZV9wb3N0dGVzdF9kemllY2lfbWVhbnNfSyA8LSBkYW5lX3Bvc3R0ZXN0X2R6aWVjaV9tZWFuc19LWyFpcy5uYShkYW5lX3Bvc3R0ZXN0X2R6aWVjaV9tZWFuc19LKV0NCg0KI2RhbmVfcG9zdHRlc3RfZHppZWNpX21lYW5fQiA8LSBtZWFuKGRhbmVfcG9zdHRlc3RfZHppZWNpX21lYW5zX0IpDQojZGFuZV9wb3N0dGVzdF9kemllY2lfbWVhbl9CDQoNCiNkYW5lX3Bvc3R0ZXN0X2R6aWVjaV9tZWFuX0sgPC0gbWVhbihkYW5lX3Bvc3R0ZXN0X2R6aWVjaV9tZWFuc19LKQ0KI2RhbmVfcG9zdHRlc3RfZHppZWNpX21lYW5fSw0KDQojcHJldGVzdC1yb2R6aWNlDQpuYW1lcyhkYW5lX3ByZXRlc3Rfcm9kemljZV9tZWFucykNCmRhbmVfcHJldGVzdF9yb2R6aWNlX21lYW5zX0IgPC0gZGFuZV9wcmV0ZXN0X3JvZHppY2VfbWVhbnNbZ3J1cGFfQl0NCmRhbmVfcHJldGVzdF9yb2R6aWNlX21lYW5zX0IgPC0gZGFuZV9wcmV0ZXN0X3JvZHppY2VfbWVhbnNfQlshaXMubmEoZGFuZV9wcmV0ZXN0X3JvZHppY2VfbWVhbnNfQildDQoNCmRhbmVfcHJldGVzdF9yb2R6aWNlX21lYW5zX0sgPC0gZGFuZV9wcmV0ZXN0X3JvZHppY2VfbWVhbnNbZ3J1cGFfS10NCmRhbmVfcHJldGVzdF9yb2R6aWNlX21lYW5zX0sgPC0gZGFuZV9wcmV0ZXN0X3JvZHppY2VfbWVhbnNfS1shaXMubmEoZGFuZV9wcmV0ZXN0X3JvZHppY2VfbWVhbnNfSyldDQoNCiNkYW5lX3ByZXRlc3Rfcm9kemljZV9tZWFuX0IgPC0gbWVhbihkYW5lX3ByZXRlc3Rfcm9kemljZV9tZWFuc19CKQ0KI2RhbmVfcHJldGVzdF9yb2R6aWNlX21lYW5fQg0KDQojZGFuZV9wcmV0ZXN0X3JvZHppY2VfbWVhbl9LIDwtIG1lYW4oZGFuZV9wcmV0ZXN0X3JvZHppY2VfbWVhbnNfSykNCiNkYW5lX3ByZXRlc3Rfcm9kemljZV9tZWFuX0sNCg0KI3Bvc3R0ZXN0LXJvZHppY2UNCm5hbWVzKGRhbmVfcHJldGVzdF9yb2R6aWNlX21lYW5zKQ0KZGFuZV9wb3N0dGVzdF9yb2R6aWNlX21lYW5zX0IgPC0gZGFuZV9wb3N0dGVzdF9yb2R6aWNlX21lYW5zW2dydXBhX0JdDQpkYW5lX3Bvc3R0ZXN0X3JvZHppY2VfbWVhbnNfQiA8LSBkYW5lX3Bvc3R0ZXN0X3JvZHppY2VfbWVhbnNfQlshaXMubmEoZGFuZV9wb3N0dGVzdF9yb2R6aWNlX21lYW5zX0IpXQ0KDQpkYW5lX3Bvc3R0ZXN0X3JvZHppY2VfbWVhbnNfSyA8LSBkYW5lX3Bvc3R0ZXN0X3JvZHppY2VfbWVhbnNbZ3J1cGFfS10NCmRhbmVfcG9zdHRlc3Rfcm9kemljZV9tZWFuc19LIDwtIGRhbmVfcG9zdHRlc3Rfcm9kemljZV9tZWFuc19LWyFpcy5uYShkYW5lX3Bvc3R0ZXN0X3JvZHppY2VfbWVhbnNfSyldDQoNCiNkYW5lX3Bvc3R0ZXN0X3JvZHppY2VfbWVhbl9CIDwtIG1lYW4oZGFuZV9wb3N0dGVzdF9yb2R6aWNlX21lYW5zX0IpDQojZGFuZV9wb3N0dGVzdF9yb2R6aWNlX21lYW5fQg0KDQojZGFuZV9wb3N0dGVzdF9yb2R6aWNlX21lYW5fSyA8LSBtZWFuKGRhbmVfcG9zdHRlc3Rfcm9kemljZV9tZWFuc19LKQ0KI2RhbmVfcG9zdHRlc3Rfcm9kemljZV9tZWFuX0sNCg0KIz09PT0gRFpJRUNJID09PT0NCiNwcmV0dGVzdC1wb3N0dGVzdCAtIHBvd3TDs3J6b255IHBvbWlhciAtPiBwcsOzYnkgemFsZcW8bmUNCiNCLUsgLSBwcsOzYnkgbmllemFsZcW8bmUNCg0KI1BPUsOTV05BTklFIEdSVVAgQiBpIEsgVyBQUkVURcWaQ0lFIChwcsOzYnkgbmllemFsZcW6bmUpDQpsZW5ndGgoZGFuZV9wcmV0ZXN0X2R6aWVjaV9tZWFuc19CKQ0KbGVuZ3RoKGRhbmVfcHJldGVzdF9kemllY2lfbWVhbnNfSykNCnNoYXBpcm8udGVzdChkYW5lX3ByZXRlc3RfZHppZWNpX21lYW5zX0IpJHAudmFsdWUgIz4gMC4wNQ0Kc2hhcGlyby50ZXN0KGRhbmVfcHJldGVzdF9kemllY2lfbWVhbnNfSykkcC52YWx1ZQ0KI29iYSByb3prxYJhZHkgc8SFIG5vcm1hbG5lDQp0LnRlc3QoZGFuZV9wcmV0ZXN0X2R6aWVjaV9tZWFuc19CLGRhbmVfcHJldGVzdF9kemllY2lfbWVhbnNfSyxwYWlyZWQgPSBGQUxTRSkgI3AgPSAwLjQ5IC0gcHLDs2J5IG5pZSBzxIUgcsOzxbxuZQ0KDQojUG9yw7N3bmFuaWUgZ3J1cCBCIGkgSyB3IHBvc3R0ZcWbY2llDQpsZW5ndGgoZGFuZV9wb3N0dGVzdF9kemllY2lfbWVhbnNfQikNCmxlbmd0aChkYW5lX3Bvc3R0ZXN0X2R6aWVjaV9tZWFuc19LKQ0Kc2hhcGlyby50ZXN0KGRhbmVfcG9zdHRlc3RfZHppZWNpX21lYW5zX0IpJHAudmFsdWUgIz4gMC4wNQ0Kc2hhcGlyby50ZXN0KGRhbmVfcG9zdHRlc3RfZHppZWNpX21lYW5zX0spJHAudmFsdWUNCiNvYmEgcm96a8WCYWR5IHPEhSBub3JtYWxuZSwgY2hvxIcgcCBqZXN0IHd5cmHFum5pZSBtbmllanN6ZQ0KdC50ZXN0KGRhbmVfcG9zdHRlc3RfZHppZWNpX21lYW5zX0IsZGFuZV9wb3N0dGVzdF9kemllY2lfbWVhbnNfSyxwYWlyZWQgPSBGQUxTRSkgI3AgPSAwLjEgLSB0ZW5kZW5jamENCndpbGNveC50ZXN0KGRhbmVfcG9zdHRlc3RfZHppZWNpX21lYW5zX0IsZGFuZV9wb3N0dGVzdF9kemllY2lfbWVhbnNfSyxwYWlyZWQgPSBGQUxTRSkgI3AgPSAwLjEgLSB0ZW5kZW5jamENCiNzdG9waWZub3QoRkFMU0UpDQoNCiNQT1LDk1dOQU5JRSBQUkVURVNUw5NXIEkgUE9TVFRFU1TDk1cgRExBIE9CVSBHUlVQIChwcsOzYnkgemFsZcW8bmUpDQoNCiN0cnplYmEgem5hbGXFusSHIHdzcMOzbG55IHBvZHpiacOzcg0KZ3J1cGFfQl93c3BvbG5hX2R6aWVjaSA8LSBpbnRlcnNlY3QobmFtZXMoZGFuZV9wcmV0ZXN0X2R6aWVjaV9tZWFuc19CKSxuYW1lcyhkYW5lX3Bvc3R0ZXN0X2R6aWVjaV9tZWFuc19CKSkNCmdydXBhX0Jfd3Nwb2xuYV9kemllY2kNCmxlbmd0aChncnVwYV9CX3dzcG9sbmFfZHppZWNpKQ0KdC50ZXN0KGRhbmVfcHJldGVzdF9kemllY2lfbWVhbnNfQltncnVwYV9CX3dzcG9sbmFfZHppZWNpXSxkYW5lX3Bvc3R0ZXN0X2R6aWVjaV9tZWFuc19CW2dydXBhX0Jfd3Nwb2xuYV9kemllY2ldLHBhaXJlZCA9IFRSVUUpDQp3aWxjb3gudGVzdChkYW5lX3ByZXRlc3RfZHppZWNpX21lYW5zX0JbZ3J1cGFfQl93c3BvbG5hX2R6aWVjaV0sZGFuZV9wb3N0dGVzdF9kemllY2lfbWVhbnNfQltncnVwYV9CX3dzcG9sbmFfZHppZWNpXSxwYWlyZWQgPSBUUlVFKQ0KDQojc3ByYXdkemVuaWUga29sZWpub8WbY2kNCmRhbmVfcHJldGVzdF9kemllY2lfbWVhbnNfQltncnVwYV9CX3dzcG9sbmFfZHppZWNpXQ0KZGFuZV9wb3N0dGVzdF9kemllY2lfbWVhbnNfQltncnVwYV9CX3dzcG9sbmFfZHppZWNpXQ0KDQpncnVwYV9LX3dzcG9sbmFfZHppZWNpIDwtIGludGVyc2VjdChuYW1lcyhkYW5lX3ByZXRlc3RfZHppZWNpX21lYW5zX0spLG5hbWVzKGRhbmVfcG9zdHRlc3RfZHppZWNpX21lYW5zX0spKQ0KZ3J1cGFfS193c3BvbG5hX2R6aWVjaQ0KbGVuZ3RoKGdydXBhX0tfd3Nwb2xuYV9kemllY2kpDQp0LnRlc3QoZGFuZV9wcmV0ZXN0X2R6aWVjaV9tZWFuc19LW2dydXBhX0tfd3Nwb2xuYV9kemllY2ldLGRhbmVfcG9zdHRlc3RfZHppZWNpX21lYW5zX0tbZ3J1cGFfS193c3BvbG5hX2R6aWVjaV0scGFpcmVkID0gVFJVRSkNCg0KI1NwcmF3ZHplbmllIGphayBvYmxpY3phbmEgamVzdCByw7PFvG5pY2ENCmdydXBhX0Jfd3Nwb2xuYV9kemllY2kNCmRhbmVfcHJldGVzdF9kemllY2lfbWVhbnNfQg0KZGFuZV9wcmV0ZXN0X2R6aWVjaV9tZWFuc19CW2dydXBhX0Jfd3Nwb2xuYV9kemllY2ldDQptZWFuKGRhbmVfcHJldGVzdF9kemllY2lfbWVhbnNfQltncnVwYV9CX3dzcG9sbmFfZHppZWNpXSxuYS5ybSA9IEZBTFNFKQ0KbWVhbihkYW5lX3Bvc3R0ZXN0X2R6aWVjaV9tZWFuc19CW2dydXBhX0Jfd3Nwb2xuYV9kemllY2ldLG5hLnJtID0gRkFMU0UpDQptZWFuKGRhbmVfcG9zdHRlc3RfZHppZWNpX21lYW5zX0JbZ3J1cGFfQl93c3BvbG5hX2R6aWVjaV0sbmEucm0gPSBGQUxTRSktbWVhbihkYW5lX3ByZXRlc3RfZHppZWNpX21lYW5zX0JbZ3J1cGFfQl93c3BvbG5hX2R6aWVjaV0sbmEucm0gPSBGQUxTRSkNCg0KIz09PT0gUk9EWklDRSA9PT09DQojcHJldHRlc3QtcG9zdHRlc3QgLSBwb3d0w7Nyem9ueSBwb21pYXIgLT4gcHLDs2J5IHphbGXFvG5lDQojQi1LIC0gcHLDs2J5IG5pZXphbGXFvG5lDQoNCiNQT1LDk1dOQU5JRSBHUlVQIEIgaSBLIFcgUFJFVEXFmkNJRSAocHLDs2J5IG5pZXphbGXFum5lKQ0KbGVuZ3RoKGRhbmVfcHJldGVzdF9yb2R6aWNlX21lYW5zX0IpDQpsZW5ndGgoZGFuZV9wcmV0ZXN0X3JvZHppY2VfbWVhbnNfSykNCnNoYXBpcm8udGVzdChkYW5lX3ByZXRlc3Rfcm9kemljZV9tZWFuc19CKSRwLnZhbHVlICM+IDAuMDUNCnNoYXBpcm8udGVzdChkYW5lX3ByZXRlc3Rfcm9kemljZV9tZWFuc19LKSRwLnZhbHVlDQojb2JhIHJvemvFgmFkeSBzxIUgbm9ybWFsbmUNCnQudGVzdChkYW5lX3ByZXRlc3Rfcm9kemljZV9tZWFuc19CLGRhbmVfcHJldGVzdF9yb2R6aWNlX21lYW5zX0sscGFpcmVkID0gRkFMU0UpICNwID0gMC40OSAtIHByw7NieSBuaWUgc8SFIHLDs8W8bmUNCg0KI1BvcsOzd25hbmllIGdydXAgQiBpIEsgdyBwb3N0dGXFm2NpZQ0KbGVuZ3RoKGRhbmVfcG9zdHRlc3Rfcm9kemljZV9tZWFuc19CKQ0KbGVuZ3RoKGRhbmVfcG9zdHRlc3Rfcm9kemljZV9tZWFuc19LKQ0Kc2hhcGlyby50ZXN0KGRhbmVfcG9zdHRlc3Rfcm9kemljZV9tZWFuc19CKSRwLnZhbHVlICM+IDAuMDUNCnNoYXBpcm8udGVzdChkYW5lX3Bvc3R0ZXN0X3JvZHppY2VfbWVhbnNfSykkcC52YWx1ZQ0KI29iYSByb3prxYJhZHkgc8SFIG5vcm1hbG5lLCBjaG/EhyBwIGplc3Qgd3lyYcW6bmllIG1uaWVqc3plDQp0LnRlc3QoZGFuZV9wb3N0dGVzdF9yb2R6aWNlX21lYW5zX0IsZGFuZV9wb3N0dGVzdF9yb2R6aWNlX21lYW5zX0sscGFpcmVkID0gRkFMU0UpICNwID0gMC4xIC0gdGVuZGVuY2phDQp3aWxjb3gudGVzdChkYW5lX3Bvc3R0ZXN0X3JvZHppY2VfbWVhbnNfQixkYW5lX3Bvc3R0ZXN0X3JvZHppY2VfbWVhbnNfSyxwYWlyZWQgPSBGQUxTRSkNCiNzdG9waWZub3QoRkFMU0UpDQoNCiNQT1LDk1dOQU5JRSBQUkVURVNUw5NXIEkgUE9TVFRFU1TDk1cgRExBIE9CVSBHUlVQIChwcsOzYnkgemFsZcW8bmUpDQoNCiN0cnplYmEgem5hbGXFusSHIHdzcMOzbG55IHBvZHpiacOzcg0KZ3J1cGFfQl93c3BvbG5hX3JvZHppY2UgPC0gaW50ZXJzZWN0KG5hbWVzKGRhbmVfcHJldGVzdF9yb2R6aWNlX21lYW5zX0IpLG5hbWVzKGRhbmVfcG9zdHRlc3Rfcm9kemljZV9tZWFuc19CKSkNCiMjIyMjISEhISEhISEhISEhIVVXQUdBISBUYSBzYW1hIHptaWVubmEgd3lrb3J6eXN0eXdhbmEgdyByw7PFvG55Y2gga29udGVrc3RhY2guIFd5cnl3a293ZSB1cnVjaGFtaWFuaWUgbW/FvGUgYnnEhyBiZXogc2Vuc3UNCmdydXBhX0Jfd3Nwb2xuYV9yb2R6aWNlDQpsZW5ndGgoZ3J1cGFfQl93c3BvbG5hX3JvZHppY2UpDQp0LnRlc3QoZGFuZV9wcmV0ZXN0X3JvZHppY2VfbWVhbnNfQltncnVwYV9CX3dzcG9sbmFfcm9kemljZV0sZGFuZV9wb3N0dGVzdF9yb2R6aWNlX21lYW5zX0JbZ3J1cGFfQl93c3BvbG5hX3JvZHppY2VdLHBhaXJlZCA9IFRSVUUpDQp3aWxjb3gudGVzdChkYW5lX3ByZXRlc3Rfcm9kemljZV9tZWFuc19CW2dydXBhX0Jfd3Nwb2xuYV9yb2R6aWNlXSxkYW5lX3Bvc3R0ZXN0X3JvZHppY2VfbWVhbnNfQltncnVwYV9CX3dzcG9sbmFfcm9kemljZV0scGFpcmVkID0gVFJVRSkNCg0KZ3J1cGFfS193c3BvbG5hX3JvZHppY2UgPC0gaW50ZXJzZWN0KG5hbWVzKGRhbmVfcHJldGVzdF9yb2R6aWNlX21lYW5zX0spLG5hbWVzKGRhbmVfcG9zdHRlc3Rfcm9kemljZV9tZWFuc19LKSkNCmdydXBhX0tfd3Nwb2xuYV9yb2R6aWNlDQpsZW5ndGgoZ3J1cGFfS193c3BvbG5hX3JvZHppY2UpDQp0LnRlc3QoZGFuZV9wcmV0ZXN0X3JvZHppY2VfbWVhbnNfS1tncnVwYV9LX3dzcG9sbmFfcm9kemljZV0sZGFuZV9wb3N0dGVzdF9yb2R6aWNlX21lYW5zX0tbZ3J1cGFfS193c3BvbG5hX3JvZHppY2VdLHBhaXJlZCA9IFRSVUUpDQoNCiM9PT09IERaSUVDSSB2cyBST0RaSUNFID09PT0NCg0KI1BSRVRFU1QsIEINCmdydXBhX0Jfd3Nwb2xuYV9wcmV0ZXN0X2RyIDwtIGludGVyc2VjdChuYW1lcyhkYW5lX3ByZXRlc3RfZHppZWNpX21lYW5zX0IpLG5hbWVzKGRhbmVfcHJldGVzdF9yb2R6aWNlX21lYW5zX0IpKQ0KZ3J1cGFfQl93c3BvbG5hX3ByZXRlc3RfZHINCmxlbmd0aChncnVwYV9CX3dzcG9sbmFfcHJldGVzdF9kcikNCnQudGVzdChkYW5lX3ByZXRlc3RfZHppZWNpX21lYW5zX0JbZ3J1cGFfQl93c3BvbG5hX3ByZXRlc3RfZHJdLGRhbmVfcHJldGVzdF9yb2R6aWNlX21lYW5zX0JbZ3J1cGFfQl93c3BvbG5hX3ByZXRlc3RfZHJdLHBhaXJlZCA9IFRSVUUpDQoNCiNQUkVURVNULCBLDQpncnVwYV9LX3dzcG9sbmFfcHJldGVzdF9kciA8LSBpbnRlcnNlY3QobmFtZXMoZGFuZV9wcmV0ZXN0X2R6aWVjaV9tZWFuc19LKSxuYW1lcyhkYW5lX3ByZXRlc3Rfcm9kemljZV9tZWFuc19LKSkNCmdydXBhX0tfd3Nwb2xuYV9wcmV0ZXN0X2RyDQpsZW5ndGgoZ3J1cGFfS193c3BvbG5hX3ByZXRlc3RfZHIpDQp0LnRlc3QoZGFuZV9wcmV0ZXN0X2R6aWVjaV9tZWFuc19LW2dydXBhX0tfd3Nwb2xuYV9wcmV0ZXN0X2RyXSxkYW5lX3ByZXRlc3Rfcm9kemljZV9tZWFuc19LW2dydXBhX0tfd3Nwb2xuYV9wcmV0ZXN0X2RyXSxwYWlyZWQgPSBUUlVFKQ0KDQojUE9TVFRFU1QsIEINCmdydXBhX0Jfd3Nwb2xuYV9wb3N0dGVzdF9kciA8LSBpbnRlcnNlY3QobmFtZXMoZGFuZV9wb3N0dGVzdF9kemllY2lfbWVhbnNfQiksbmFtZXMoZGFuZV9wb3N0dGVzdF9yb2R6aWNlX21lYW5zX0IpKQ0KZ3J1cGFfQl93c3BvbG5hX3Bvc3R0ZXN0X2RyDQpsZW5ndGgoZ3J1cGFfQl93c3BvbG5hX3Bvc3R0ZXN0X2RyKQ0KdC50ZXN0KGRhbmVfcG9zdHRlc3RfZHppZWNpX21lYW5zX0JbZ3J1cGFfQl93c3BvbG5hX3Bvc3R0ZXN0X2RyXSxkYW5lX3Bvc3R0ZXN0X3JvZHppY2VfbWVhbnNfQltncnVwYV9CX3dzcG9sbmFfcG9zdHRlc3RfZHJdLHBhaXJlZCA9IFRSVUUpDQp3aWxjb3gudGVzdChkYW5lX3Bvc3R0ZXN0X2R6aWVjaV9tZWFuc19CW2dydXBhX0Jfd3Nwb2xuYV9wb3N0dGVzdF9kcl0sZGFuZV9wb3N0dGVzdF9yb2R6aWNlX21lYW5zX0JbZ3J1cGFfQl93c3BvbG5hX3Bvc3R0ZXN0X2RyXSxwYWlyZWQgPSBUUlVFKQ0KDQojUE9TVFRFU1QsIEsNCmdydXBhX0tfd3Nwb2xuYV9wb3N0dGVzdF9kciA8LSBpbnRlcnNlY3QobmFtZXMoZGFuZV9wb3N0dGVzdF9kemllY2lfbWVhbnNfSyksbmFtZXMoZGFuZV9wb3N0dGVzdF9yb2R6aWNlX21lYW5zX0spKQ0KZ3J1cGFfS193c3BvbG5hX3Bvc3R0ZXN0X2RyDQpsZW5ndGgoZ3J1cGFfS193c3BvbG5hX3Bvc3R0ZXN0X2RyKQ0KdC50ZXN0KGRhbmVfcG9zdHRlc3RfZHppZWNpX21lYW5zX0tbZ3J1cGFfS193c3BvbG5hX3Bvc3R0ZXN0X2RyXSxkYW5lX3Bvc3R0ZXN0X3JvZHppY2VfbWVhbnNfS1tncnVwYV9LX3dzcG9sbmFfcG9zdHRlc3RfZHJdLHBhaXJlZCA9IFRSVUUpDQoNCmBgYA0KYGBge3IgV1lLUkVTWX0NCg0KI1d5a3JlcyBkemllY2kNCnBsb3REYW5lQiA8LSBjKCJwcmV0ZXN0IiA9IG1lYW4oZGFuZV9wcmV0ZXN0X2R6aWVjaV9tZWFuc19CKSwgInBvc3R0ZXN0IiA9IG1lYW4oZGFuZV9wb3N0dGVzdF9kemllY2lfbWVhbnNfQikpDQpwbG90RGFuZUINCm5hbWVzKHBsb3REYW5lQikNCnBsb3REYW5lSyA8LSBjKCJwcmV0ZXN0IiA9IG1lYW4oZGFuZV9wcmV0ZXN0X2R6aWVjaV9tZWFuc19LKSwicG9zdHRlc3QiID0gbWVhbihkYW5lX3Bvc3R0ZXN0X2R6aWVjaV9tZWFuc19LKSkNCnBsb3REYW5lSw0KDQpwYXIob21hID0gYygxLCAwLCAwLCAwKSwgbWFyID0gYygzLCA3LCAyLCAyKSkgDQpwbG90KHBsb3REYW5lQiwgdHlwZT0iYiIsIHhsYWIgPSAiIiwgeWxhYiA9ICJwb3ppb20gdW1pZWrEmXRub8WbY2kiLCB4bGltPWMoMC43NSwyLjI1KSwgeWxpbT1jKDIuOSwzLjYpLCB4YXh0PSJuIiwgcGNoPTE5KQ0KI2xpbmVzKHBsb3REYW5lQiwgdHlwZSA9ICJsIikNCnBvaW50cyhwbG90RGFuZUssIHR5cGUgPSAiYiIsIHBjaD0xKQ0KI2xpbmVzKHBsb3REYW5lSywgdHlwZSA9ICJsIikNCmF4aXMoMSwgYXQ9MToyLCB0aWNrPTEsIGxhYmVscz1uYW1lcyhwbG90RGFuZUIpKQ0KDQojV3lrcmVzIHJvZHppY2UNCnBsb3REYW5lQiA8LSBjKCJwcmV0ZXN0IiA9IG1lYW4oZGFuZV9wcmV0ZXN0X3JvZHppY2VfbWVhbnNfQiksICJwb3N0dGVzdCIgPSBtZWFuKGRhbmVfcG9zdHRlc3Rfcm9kemljZV9tZWFuc19CKSkNCnBsb3REYW5lQg0KbmFtZXMocGxvdERhbmVCKQ0KcGxvdERhbmVLIDwtIGMoInByZXRlc3QiID0gbWVhbihkYW5lX3ByZXRlc3Rfcm9kemljZV9tZWFuc19LKSwicG9zdHRlc3QiID0gbWVhbihkYW5lX3Bvc3R0ZXN0X3JvZHppY2VfbWVhbnNfSykpDQpwbG90RGFuZUsNCg0KcGFyKG9tYSA9IGMoMSwgMCwgMCwgMCksIG1hciA9IGMoMywgNywgMiwgMikpIA0KcGxvdChwbG90RGFuZUIsIHR5cGU9ImIiLCB4bGFiID0gIiIsIHlsYWIgPSAicG96aW9tIHVtaWVqxJl0bm/Fm2NpIiwgeGxpbT1jKDAuNzUsMi4yNSksIHlsaW09YygyLjUsMy41KSwgeGF4dD0ibiIsIHBjaD0xOSkNCiNsaW5lcyhwbG90RGFuZUIsIHR5cGUgPSAibCIpDQpwb2ludHMocGxvdERhbmVLLCB0eXBlID0gImIiLCBwY2g9MSkNCiNsaW5lcyhwbG90RGFuZUssIHR5cGUgPSAibCIpDQpheGlzKDEsIGF0PTE6MiwgdGljaz0xLCBsYWJlbHM9bmFtZXMocGxvdERhbmVCKSkNCg0KI1JvZHppY2UgdnMgZHppZWNpDQoNCiNjYcWCeSBwcmV0ZXN0IChuaWV6YWxlxbxuZSkNCnNoYXBpcm8udGVzdChkYW5lX3ByZXRlc3RfZHppZWNpX21lYW5zKQ0Kc2hhcGlyby50ZXN0KGRhbmVfcHJldGVzdF9yb2R6aWNlX21lYW5zKQ0KdC50ZXN0KGRhbmVfcHJldGVzdF9kemllY2lfbWVhbnMsIGRhbmVfcHJldGVzdF9yb2R6aWNlX21lYW5zLCBwYWlyZWQgPSBGQUxTRSkNCnBsb3REYW5lUHJldGVzdCA8LSBjKCJkemllY2kiID0gbWVhbihkYW5lX3ByZXRlc3RfZHppZWNpX21lYW5zKSwgInJvZHppY2UiID0gbWVhbihkYW5lX3ByZXRlc3Rfcm9kemljZV9tZWFucykpDQpiYXJwbG90KHBsb3REYW5lUHJldGVzdCkNCg0KI3ByZXRlc3QsIEIgLSB6YWxlxbxuYQ0KcGxvdERhbmVQcmV0ZXN0QiA8LSBjKA0KICAiZHppZWNpIiA9IG1lYW4oZGFuZV9wcmV0ZXN0X2R6aWVjaV9tZWFuc19CW2dydXBhX0Jfd3Nwb2xuYV9wcmV0ZXN0X2RyXSksDQogICJyb2R6aWNlIiA9IG1lYW4oZGFuZV9wcmV0ZXN0X3JvZHppY2VfbWVhbnNfQltncnVwYV9CX3dzcG9sbmFfcHJldGVzdF9kcl0pKQ0KYmFycGxvdChwbG90RGFuZVByZXRlc3RCKQ0KDQoNCiNwb3N0dGVzdCwgQiAtIHphbGXFvG5hDQpwbG90RGFuZVBvc3R0ZXN0QiA8LSBjKA0KICAiZHppZWNpIiA9IG1lYW4oZGFuZV9wb3N0dGVzdF9kemllY2lfbWVhbnNfQltncnVwYV9CX3dzcG9sbmFfcG9zdHRlc3RfZHJdKSwNCiAgInJvZHppY2UiID0gbWVhbihkYW5lX3Bvc3R0ZXN0X3JvZHppY2VfbWVhbnNfQltncnVwYV9CX3dzcG9sbmFfcG9zdHRlc3RfZHJdKSkNCmJhcnBsb3QocGxvdERhbmVQb3N0dGVzdEIpDQoNCiNwcmV0ZXN0LCBLIC0gemFsZcW8bmENCnBsb3REYW5lUHJldGVzdEsgPC0gYygNCiAgImR6aWVjaSIgPSBtZWFuKGRhbmVfcHJldGVzdF9kemllY2lfbWVhbnNfS1tncnVwYV9LX3dzcG9sbmFfcHJldGVzdF9kcl0pLA0KICAicm9kemljZSIgPSBtZWFuKGRhbmVfcHJldGVzdF9yb2R6aWNlX21lYW5zX0tbZ3J1cGFfS193c3BvbG5hX3ByZXRlc3RfZHJdKSkNCnBsb3REYW5lUHJldGVzdEsNCmJhcnBsb3QocGxvdERhbmVQcmV0ZXN0SykNCg0KI3Bvc3R0ZXN0LCBLIC0gemFsZcW8bmENCnBsb3REYW5lUG9zdHRlc3RLIDwtIGMoDQogICJkemllY2kiID0gbWVhbihkYW5lX3Bvc3R0ZXN0X2R6aWVjaV9tZWFuc19LW2dydXBhX0tfd3Nwb2xuYV9wb3N0dGVzdF9kcl0pLA0KICAicm9kemljZSIgPSBtZWFuKGRhbmVfcG9zdHRlc3Rfcm9kemljZV9tZWFuc19LW2dydXBhX0tfd3Nwb2xuYV9wb3N0dGVzdF9kcl0pKQ0KYmFycGxvdChwbG90RGFuZVBvc3R0ZXN0SykNCg0KYGBgDQo=