Analyse descriptive
L’analyse descriptive permet de comprendre la distribution et les
caractéristiques générales des données, offrant ainsi un aperçu
préliminaire des tendances et des associations potentielles entre les
variables étudiées.
Il est important de s’assurer que les niveaux des variables sont
assez équilibré, car sinon ils pourraient être sous-représentés dans les
analyses à venir, si c’est le cas il sera ainsi important de le prendre
en compte lors de l’interprétation.
Pour simplifier la création des graphiques, nous pouvons écrire une
fonction qui inclut tous les paramètres nécessaires. Cela nous permettra
de générer des ggplot plus rapidement.
fastggplot <- function(data, x_var, title, x_label, y_label) {
ggplot(data, aes(x = factor(data[[x_var]]), fill = factor(data[[x_var]]))) +
geom_bar(color = "black", alpha = 0.8) +
labs(title = title, x = x_label, y = y_label, fill = x_var) +
theme_minimal() +
theme(axis.text = element_text(size = 12),
axis.title = element_text(size = 14, face = "bold"),
plot.title = element_text(size = 16, face = "bold"))
}
CDR <- fastggplot(demence2, "CDR", "Répartition par score CDR", "Score CDR", "Nombre de cas")
CDR %>% plotly::ggplotly()
MMSE <- fastggplot(demence2, "MMSE", "Répartition par score MMSE", "Score MMSE", "Nombre de cas")
MMSE %>% plotly::ggplotly()
EDUC <- fastggplot(demence2, "EDUC", "Répartition par niveau d'éducation", "Niveau d'éducation", "Nombre de cas")
EDUC %>% plotly::ggplotly()
genre = fastggplot(demence2, "sexe", "Répartition par sexe", "Genre", "Nombre de cas")
genre %>% plotly::ggplotly()
Graphique des variables quantitatives
hist_age <- ggplot(demence2, aes(x = Age)) +
geom_histogram(binwidth = 0.01, fill = "green", color = "black", alpha = 0.8) +
labs(title = "Distribution de l'âge", x = "", y = "Fréquence") +
theme_minimal()
hist_age %>% plotly::ggplotly()
hist_nwbv <- ggplot(demence2, aes(x = Volume_substance_blanche)) +
geom_histogram(binwidth = 0.01, fill = "green", color = "black", alpha = 0.8) +
labs(title = "Distribution du volume de substance blanche", x = "Substance blanche", y = "Fréquence") +
theme_minimal()
hist_nwbv %>% plotly::ggplotly()
hist_etiv <- ggplot(demence2, aes(x = Volume_cérébral_total)) +
geom_histogram(binwidth = 100, fill = "orange", color = "black", alpha = 0.8) +
labs(title = "Distribution du volume cérébral", x = "eTIV", y = "Fréquence") +
theme_minimal()
hist_etiv %>% plotly::ggplotly()
hist_asf <- ggplot(demence2, aes(x = Indice_atrophie)) +
geom_histogram(binwidth = 0.1, fill = "blue", color = "black", alpha = 0.8) +
labs(title = "Distribution de l'indice d'atrophie", x = "Indice_atrophie", y = "Fréquence") +
theme_minimal()
hist_asf %>% plotly::ggplotly()
Pour aller plus loin dans l’analyse descriptive, on peut également
faire des graphiques qui associent notre variable dépendante, le CDR,
aux autres.
CDR + X
CDRSEXE = ggplot(data = demence2, aes(x = CDR, fill = sexe)) +
geom_bar(position = "dodge") +
labs(title = "Comparaison de CDR par sexe",
x = "CDR",
y = "Nombre de participants",
fill = "Sexe")
CDRSEXE %>% plotly::ggplotly()
CDREDUC = ggplot(data = demence2, aes(x = CDR, fill = EDUC)) +
geom_bar(position = "dodge") +
labs(title = "Comparaison de CDR par niveau d'éducation",
x = "CDR",
y = "Nombre de participants",
fill = "EDUC")
CDREDUC %>% plotly::ggplotly()
CDRSES = ggplot(data = demence2, aes(x = CDR, fill = SES)) +
geom_bar(position = "dodge") +
labs(title = "Comparaison de CDR par niveau socio-économique",
x = "CDR",
y = "Nombre de participants",
fill = "SES")
CDRSES %>% plotly::ggplotly()
CDRSES = ggplot(data = demence2, aes(x = CDR, fill = MMSE)) +
geom_bar(position = "dodge") +
labs(title = "Comparaison de CDR par MMSE",
x = "CDR",
y = "Nombre de participants",
fill = "MMSE")
CDRSES %>% plotly::ggplotly()
CDReTIV = ggplot(demence2, aes(x = CDR, y = Volume_cérébral_total)) +
geom_boxplot(fill = "lightgreen", color = "black") +
labs(x = "CDR", y = "Volume cérébral total", title = "Distribution du volume cérébral par CDR")
CDReTIV %>% plotly::ggplotly()
CDRASF = ggplot(demence2, aes(x = CDR, y = Indice_atrophie)) +
geom_boxplot(fill = "darkred", color = "black") +
labs(x = "CDR", y = "ASF", title = "Distribution de l'indice d'atrophie par CDR")
CDRASF %>% plotly::ggplotly()
Corrélation de Pearson
Les corrélations de Pearson permettent de mesurer la relation
linéaire entre deux variables continues. Elles permettent de quantifier
la force et la direction de cette relation, ce qui facilite la
compréhension des données et l’identification de tendances.
L’interprétation de la corrélation de Pearson se fait à travers son
coefficient, qui varie de -1 à 1 : une corrélation proche de 1 indique
une forte corrélation positive, proche de -1 une forte corrélation
négative, tandis qu’une valeur proche de 0 suggère une faible
corrélation entre les variables.
suppressMessages({
suppressWarnings({
get_upper_tri <- function(cormat){
cormat[lower.tri(cormat)] <- NA
return(cormat)
}
cormat <- round(cor(subset(demence2, select = c("Age", "Volume_cérébral_total", "Volume_substance_blanche", "Indice_atrophie")),
method = "spearman", use = "pairwise.complete.obs"), 2)
upper_tri <- get_upper_tri(cormat)
melted_cormat <- reshape2::melt(upper_tri, na.rm = TRUE)
CORR = ggplot(melted_cormat, aes(Var2, Var1, fill = value)) +
geom_tile(color = "white") +
scale_fill_gradient2(low = "blue", high = "red", mid = "white",
midpoint = 0, limit = c(-0.2, 1), space = "Lab",
name = "Spearman\nCorrelation") +
theme_minimal() +
coord_fixed() +
geom_text(aes(Var2, Var1, label = value), color = "black", size = 4) +
theme(
axis.text.x = element_text(angle = 45, vjust = 1, size = 12, hjust = 1),
axis.text.y = element_text(size = 12),
axis.title.x = element_blank(),
axis.title.y = element_blank(),
legend.position = c(0.3, 0.8),
legend.direction = "horizontal"
) +
guides(fill = guide_colorbar(barwidth = 12, barheight = 1,
title.position = "top", title.hjust = 0.5))
CORR %>% plotly::ggplotly()
})
})
Coefficient de Cramér
Le coefficient de Cramér mesure l’association entre deux variables
catégorielles. Calculé à partir des tables de contingence, il varie de 0
(aucune association) à 1 (association parfaite). Une valeur proche de 0
indique une faible relation, tandis que près de 1 indique une forte
association. Il sert à évaluer la dépendance entre les variables.
# on crée d'abord des tables de contingence pour chaque paire de variables
t1 = table(demence2$sexe, demence2$CDR)
t2 = table(demence2$MMSE,demence2$CDR)
t3 = table(demence2$EDUC,demence2$CDR)
t4 = table(demence2$SES,demence2$CDR)
# calcul des les statistiques d'association pour chaque table
ma1 = assocstats(t1)
ma2 = assocstats(t2)
ma3 = assocstats(t3)
ma4 = assocstats(t4)
data <- data.frame(
Variable = c("Sexe", "MMSE", "EDUC", "SES"),
CoefficientdeCramer = c(ma1$cramer, ma2$cramer, ma3$cramer, ma4$cramer)
)
Cramer_V = c(ma1$cramer, ma2$cramer, ma3$cramer, ma4$cramer)
# Créer le graphique à barres
GGCram = ggplot(data, aes(x = Variable, y = CoefficientdeCramer, fill = CoefficientdeCramer)) +
geom_bar(stat = "identity", position = "dodge", width = 0.7, color = "black") +
scale_fill_gradient2(low = "darkblue", mid = "white", high = "red",
midpoint = 0.5, limits = c(0, 1),
name = "Indice de Cramér") +
geom_hline(yintercept = 0.5, linetype = "dashed", color = "black") +
labs(title = "Coefficients de Cramer pour chaque variable en fonction de l'AVC",
x = "Variables",
y = "Cramér's V") +
theme_bw()
GGCram %>% plotly::ggplotly()
LS0tDQp0aXRsZTogInN1cGVyIHByb2pldCINCmF1dGhvcjogInZhbG91Ig0Kb3V0cHV0Og0KICBodG1sX25vdGVib29rOg0KICAgIHRvYzogdHJ1ZQ0KICAgIGRmX3ByaW50OiBwYWdlZA0KICAgIHRoZW1lOiBqb3VybmFsDQogICAgdG9jX2Zsb2F0OiB0cnVlDQotLS0NCg0KYGBgez1odG1sfQ0KPHN0eWxlPg0KYm9keXsNCiAgdGV4dC1hbGlnbjoganVzdGlmeX0NCjwvc3R5bGU+DQpgYGANCg0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKQ0KDQpsaWJyYXJ5KGRhdGEudGFibGUpDQpsaWJyYXJ5KGNhcmV0KQ0KbGlicmFyeShyYW5kb21Gb3Jlc3QpDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KHZjZCkNCmxpYnJhcnkocnBhcnQpDQpsaWJyYXJ5KHJwYXJ0LnBsb3QpDQpsaWJyYXJ5KGNhcikNCmxpYnJhcnkoTUFTUykNCmxpYnJhcnkoZ3JpZEV4dHJhKQ0KbGlicmFyeShwbG90bHkpDQpsaWJyYXJ5KHBST0MpDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeShGYWN0b01pbmVSKQ0KDQp0ZW1wIDwtIHRlbXBmaWxlKGZpbGVleHQgPSAiLmNzdiIpDQpkb3dubG9hZC5maWxlKCJodHRwczovL2RyaXZlLmdvb2dsZS5jb20vdWM/ZXhwb3J0PWRvd25sb2FkJmlkPTFlYWM1cUNIZDFfdzRLbUZueFhiUnJBNW1SUjRjOFhYdCIsIHRlbXApDQpkZW1lbmNlMiA8LSByZWFkLmNzdih0ZW1wKQ0KDQpkZW1lbmNlMiA8LSBkZW1lbmNlMlssIC1jKDEsIDIsIDMsIDQsIDUsIDcpXQ0KDQojIFLDqWR1Y3Rpb24gZHUgbm9tYnJlIGRlIG5pdmVhdXggZGUgbGEgdmFyaWFibGUgRURVQw0KZGVtZW5jZTIgPC0gZGVtZW5jZTIgJT4lDQogIG11dGF0ZShFRFVDID0gY2FzZV93aGVuKA0KICAgIEVEVUMgJWluJSA2OjggfiAiNi04IiwNCiAgICBFRFVDICVpbiUgMTE6MTMgfiAiMTEtMTMiLA0KICAgIEVEVUMgJWluJSAxNDoxNiB+ICIxNC0xNiIsDQogICAgRURVQyAlaW4lIDE3OjE4IH4gIjE3LTE4IiwNCiAgICBFRFVDICVpbiUgMjA6MjMgfiAiMjAtMjMiLA0KICAgIFRSVUUgfiBhcy5jaGFyYWN0ZXIoRURVQykgICMgVmFsZXVycyBxdWkgbmUgcmVudHJlbnQgZGFucyBhdWN1biBncm91cGUNCiAgKSkNCg0KDQpkZW1lbmNlMiRDRFIgPC0gaWZlbHNlKGRlbWVuY2UyJENEUiA9PSAwLCAiTm9uX2TDqW1lbnQiLCAiRMOpbWVudCIpDQoNCmludGVydmFscyA8LSBjdXQoZGVtZW5jZTIkTU1TRSwgYnJlYWtzID0gYygwLCAxNywgMjMsIDMwKSwgbGFiZWxzID0gYygiVHJvdWJsZV9zw6l2w6hyZSIsICJUcm91YmxlX2zDqWdlciIsICJBdWN1bl90cm91YmxlIiksIGluY2x1ZGUubG93ZXN0ID0gVFJVRSkNCg0KZGVtZW5jZTIkTU1TRSA8LSBhcy5jaGFyYWN0ZXIoaW50ZXJ2YWxzKQ0KdGFibGUoZGVtZW5jZTIkTU1TRSkNCnRhYmxlKGRlbWVuY2UyJENEUikNCg0KZGVtZW5jZTIkQ0RSIDwtIGFzLmZhY3RvcihkZW1lbmNlMiRDRFIpDQpkZW1lbmNlMiRzZXhlIDwtIGZhY3RvcihkZW1lbmNlMiRzZXhlKQ0KZGVtZW5jZTIkU0VTIDwtIGZhY3RvcihkZW1lbmNlMiRTRVMpDQpkZW1lbmNlMiRFRFVDIDwtIGZhY3RvcihkZW1lbmNlMiRFRFVDKQ0KZGVtZW5jZTIkTU1TRSA8LSBmYWN0b3IoZGVtZW5jZTIkTU1TRSkNCnRhYmxlKGRlbWVuY2UyJENEUikNCg0KIyBCb3VjbGUgcG91ciBjb252ZXJ0aXIgZGVzIGNvbG9ubmVzIHNww6ljaWZpcXVlcyBlbiBudW3DqXJpcXVlcw0KZm9yIChpIGluIGMoIkFnZSIsICJuV0JWIiwgIkFTRiIsICJlVElWIikpIHsNCiAgZGVtZW5jZTJbLCBpXSA8LSBhcy5udW1lcmljKGFzLmNoYXJhY3RlcihkZW1lbmNlMlssIGldKSkNCn0NCg0KIyBTdXBwcmltZXIgbGVzIHZhbGV1cnMgbWFucXVhbnRlcw0KZGVtZW5jZTIgPC0gbmEub21pdChkZW1lbmNlMikNCg0KY29sbmFtZXMoZGVtZW5jZTIpIDwtIGMoInNleGUiLCAiQWdlIiwgIkVEVUMiLCAiU0VTIiwgIk1NU0UiLCAiQ0RSIiwgIlZvbHVtZV9jw6lyw6licmFsX3RvdGFsIiwgIlZvbHVtZV9zdWJzdGFuY2VfYmxhbmNoZSIsICJJbmRpY2VfYXRyb3BoaWUiKQ0KDQoNCg0KZmFzdGdncGxvdCA8LSBmdW5jdGlvbihkYXRhLCB4X3ZhciwgdGl0bGUsIHhfbGFiZWwsIHlfbGFiZWwpIHsNCiAgZ2dwbG90KGRhdGEsIGFlcyh4ID0gZmFjdG9yKGRhdGFbW3hfdmFyXV0pLCBmaWxsID0gZmFjdG9yKGRhdGFbW3hfdmFyXV0pKSkgKw0KICAgIGdlb21fYmFyKGNvbG9yID0gImJsYWNrIiwgYWxwaGEgPSAwLjgpICsNCiAgICANCiAgICBsYWJzKHRpdGxlID0gdGl0bGUsIHggPSB4X2xhYmVsLCB5ID0geV9sYWJlbCwgZmlsbCA9IHhfdmFyKSArDQogICAgdGhlbWVfbWluaW1hbCgpICsNCiAgICB0aGVtZShheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwNCiAgICAgICAgICBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCwgZmFjZSA9ICJib2xkIiksDQogICAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTYsIGZhY2UgPSAiYm9sZCIpKQ0KfQ0KDQoNCmBgYA0KDQojIEludHJvZHVjdGlvbg0KDQp0ZXN0DQoNCk5vdHJlIHJlY2hlcmNoZSBzZSBjb25jZW50cmUgc3VyIGwnaWRlbnRpZmljYXRpb24gZGVzIGZhY3RldXJzIHByw6lkaWN0aWZzIGRlIGxhIGTDqW1lbmNlLiBOb3RyZSAqKnZhcmlhYmxlIGTDqXBlbmRhbnRlLCBsZSAiQ0RSIioqIChDbGluaWNhbCBEZW1lbnRpYSBSYXRlKSwgZXN0IHVuIGluZGljYXRldXIgbmV1cm9sb2dpcXVlIMOpdGFibGkgZW4gMTk5MyBwYXIgTW9ycmlzLiBDZXR0ZSB2YXJpYWJsZSBlc3QgaWNpIGJpbmFpcmUsIGF2ZWMgMCBwb3VyIGxlcyBpbmRpdmlkdXMgbm9uIGF0dGVpbnRzIGRlIGTDqW1lbmNlIGV0IDEgcG91ciBjZXV4IHF1aSBsZSBzb250LiBOb3VzIGV4YW1pbm9ucyDDqWdhbGVtZW50IHBsdXNpZXVycyBhdXRyZXMgdmFyaWFibGVzIHBvdGVudGllbGxlbWVudCBwZXJ0aW5lbnRlcywgbm90YW1tZW50ICoqbGUgc2V4ZSwgbCfDomdlLCBsZSBuaXZlYXUgZCfDqWR1Y2F0aW9uLCBsZSBuaXZlYXUgc29jaW8tY3VsdHVyZWwsIGxlIHZvbHVtZSBkZSBzdWJzdGFuY2UgYmxhbmNoZSwgbGUgdm9sdW1lIGPDqXLDqWJyYWwgdG90YWwsIGxlIG5pdmVhdSBkJ2F0cm9waGllLCBhaW5zaSBxdWUgbGUgTWluaSBNZW50YWwgU3RhdGUgRXhhbWluYXRpb24gKE1NU0UpKiouIEJpZW4gcXVlIGxlIE1NU0Ugc29pdCB1biB0ZXN0IG5ldXJvbG9naXF1ZSBsYXJnZW1lbnQgdXRpbGlzw6kgZW4gcmFpc29uIGRlIHNhIHJhcGlkaXTDqSwgaWwgZXN0IHRvdXRlZm9pcyBzb3V2ZW50IGNyaXRpcXXDqSBkYW5zIGxhIGxpdHTDqXJhdHVyZSBwb3VyIHNhIG1vaW5kcmUgcHLDqWNpc2lvbiBldCBzYSBmaWFiaWxpdMOpIHZhcmlhYmxlLiBOb3VzIGF2b25zIGwnb3Bwb3J0dW5pdMOpIGRlIHbDqXJpZmllciBjZXMgcG9pbnRzIGVuIGwnaW5jbHVhbnQgZGFucyBub3RyZSDDqXR1ZGUgcGFyYWxsw6hsZW1lbnQgYXUgQ0RSLg0KDQojIEFuYWx5c2UgZGVzY3JpcHRpdmUNCg0KTCdhbmFseXNlIGRlc2NyaXB0aXZlIHBlcm1ldCBkZSBjb21wcmVuZHJlIGxhIGRpc3RyaWJ1dGlvbiBldCBsZXMgY2FyYWN0w6lyaXN0aXF1ZXMgZ8OpbsOpcmFsZXMgZGVzIGRvbm7DqWVzLCBvZmZyYW50IGFpbnNpIHVuIGFwZXLDp3UgcHLDqWxpbWluYWlyZSBkZXMgdGVuZGFuY2VzIGV0IGRlcyBhc3NvY2lhdGlvbnMgcG90ZW50aWVsbGVzIGVudHJlIGxlcyB2YXJpYWJsZXMgw6l0dWRpw6llcy4NCg0KSWwgZXN0IGltcG9ydGFudCBkZSBzJ2Fzc3VyZXIgcXVlIGxlcyBuaXZlYXV4IGRlcyB2YXJpYWJsZXMgc29udCBhc3NleiDDqXF1aWxpYnLDqSwgY2FyIHNpbm9uIGlscyBwb3VycmFpZW50IMOqdHJlIHNvdXMtcmVwcsOpc2VudMOpcyBkYW5zIGxlcyBhbmFseXNlcyDDoCB2ZW5pciwgc2kgYydlc3QgbGUgY2FzIGlsIHNlcmEgYWluc2kgaW1wb3J0YW50IGRlIGxlIHByZW5kcmUgZW4gY29tcHRlIGxvcnMgZGUgbCdpbnRlcnByw6l0YXRpb24uDQoNClBvdXIgc2ltcGxpZmllciBsYSBjcsOpYXRpb24gZGVzIGdyYXBoaXF1ZXMsIG5vdXMgcG91dm9ucyDDqWNyaXJlIHVuZSBmb25jdGlvbiBxdWkgaW5jbHV0IHRvdXMgbGVzIHBhcmFtw6h0cmVzIG7DqWNlc3NhaXJlcy4gQ2VsYSBub3VzIHBlcm1ldHRyYSBkZSBnw6luw6lyZXIgZGVzIGdncGxvdCBwbHVzIHJhcGlkZW1lbnQuDQoNCmBgYHtyIGNhcnN9DQoNCmZhc3RnZ3Bsb3QgPC0gZnVuY3Rpb24oZGF0YSwgeF92YXIsIHRpdGxlLCB4X2xhYmVsLCB5X2xhYmVsKSB7DQogIGdncGxvdChkYXRhLCBhZXMoeCA9IGZhY3RvcihkYXRhW1t4X3Zhcl1dKSwgZmlsbCA9IGZhY3RvcihkYXRhW1t4X3Zhcl1dKSkpICsNCiAgICBnZW9tX2Jhcihjb2xvciA9ICJibGFjayIsIGFscGhhID0gMC44KSArDQogICAgDQogICAgbGFicyh0aXRsZSA9IHRpdGxlLCB4ID0geF9sYWJlbCwgeSA9IHlfbGFiZWwsIGZpbGwgPSB4X3ZhcikgKw0KICAgIHRoZW1lX21pbmltYWwoKSArDQogICAgdGhlbWUoYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksDQogICAgICAgICAgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQsIGZhY2UgPSAiYm9sZCIpLA0KICAgICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE2LCBmYWNlID0gImJvbGQiKSkNCn0NCg0KYGBgDQoNCmBgYHtyfQ0KQ0RSIDwtIGZhc3RnZ3Bsb3QoZGVtZW5jZTIsICJDRFIiLCAiUsOpcGFydGl0aW9uIHBhciBzY29yZSBDRFIiLCAiU2NvcmUgQ0RSIiwgIk5vbWJyZSBkZSBjYXMiKQ0KQ0RSICU+JSBwbG90bHk6OmdncGxvdGx5KCkNCmBgYA0KDQpgYGB7cn0NCk1NU0UgPC0gZmFzdGdncGxvdChkZW1lbmNlMiwgIk1NU0UiLCAiUsOpcGFydGl0aW9uIHBhciBzY29yZSBNTVNFIiwgIlNjb3JlIE1NU0UiLCAiTm9tYnJlIGRlIGNhcyIpDQpNTVNFICU+JSBwbG90bHk6OmdncGxvdGx5KCkNCmBgYA0KDQpgYGB7cn0NCkVEVUMgPC0gZmFzdGdncGxvdChkZW1lbmNlMiwgIkVEVUMiLCAiUsOpcGFydGl0aW9uIHBhciBuaXZlYXUgZCfDqWR1Y2F0aW9uIiwgIk5pdmVhdSBkJ8OpZHVjYXRpb24iLCAiTm9tYnJlIGRlIGNhcyIpDQpFRFVDICU+JSBwbG90bHk6OmdncGxvdGx5KCkNCmBgYA0KDQpgYGB7cn0NCmdlbnJlID0gZmFzdGdncGxvdChkZW1lbmNlMiwgInNleGUiLCAiUsOpcGFydGl0aW9uIHBhciBzZXhlIiwgIkdlbnJlIiwgIk5vbWJyZSBkZSBjYXMiKQ0KZ2VucmUgJT4lIHBsb3RseTo6Z2dwbG90bHkoKQ0KYGBgDQoNCiMjIEdyYXBoaXF1ZSBkZXMgdmFyaWFibGVzIHF1YW50aXRhdGl2ZXMNCg0KYGBge3J9DQpoaXN0X2FnZSA8LSBnZ3Bsb3QoZGVtZW5jZTIsIGFlcyh4ID0gQWdlKSkgKw0KICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDAuMDEsIGZpbGwgPSAiZ3JlZW4iLCBjb2xvciA9ICJibGFjayIsIGFscGhhID0gMC44KSArDQogIGxhYnModGl0bGUgPSAiRGlzdHJpYnV0aW9uIGRlIGwnw6JnZSIsIHggPSAiIiwgeSA9ICJGcsOpcXVlbmNlIikgKw0KICB0aGVtZV9taW5pbWFsKCkNCmhpc3RfYWdlICU+JSBwbG90bHk6OmdncGxvdGx5KCkNCmBgYA0KDQpgYGB7cn0NCmhpc3RfbndidiA8LSBnZ3Bsb3QoZGVtZW5jZTIsIGFlcyh4ID0gVm9sdW1lX3N1YnN0YW5jZV9ibGFuY2hlKSkgKw0KICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDAuMDEsIGZpbGwgPSAiZ3JlZW4iLCBjb2xvciA9ICJibGFjayIsIGFscGhhID0gMC44KSArDQogIGxhYnModGl0bGUgPSAiRGlzdHJpYnV0aW9uIGR1IHZvbHVtZSBkZSBzdWJzdGFuY2UgYmxhbmNoZSIsIHggPSAiU3Vic3RhbmNlIGJsYW5jaGUiLCB5ID0gIkZyw6lxdWVuY2UiKSArDQogIHRoZW1lX21pbmltYWwoKQ0KaGlzdF9ud2J2ICU+JSBwbG90bHk6OmdncGxvdGx5KCkNCmBgYA0KDQpgYGB7cn0NCmhpc3RfZXRpdiA8LSBnZ3Bsb3QoZGVtZW5jZTIsIGFlcyh4ID0gVm9sdW1lX2PDqXLDqWJyYWxfdG90YWwpKSArDQogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMTAwLCBmaWxsID0gIm9yYW5nZSIsIGNvbG9yID0gImJsYWNrIiwgYWxwaGEgPSAwLjgpICsNCiAgbGFicyh0aXRsZSA9ICJEaXN0cmlidXRpb24gZHUgdm9sdW1lIGPDqXLDqWJyYWwiLCB4ID0gImVUSVYiLCB5ID0gIkZyw6lxdWVuY2UiKSArDQogIHRoZW1lX21pbmltYWwoKQ0KaGlzdF9ldGl2ICU+JSBwbG90bHk6OmdncGxvdGx5KCkNCmBgYA0KDQpgYGB7cn0NCmhpc3RfYXNmIDwtIGdncGxvdChkZW1lbmNlMiwgYWVzKHggPSBJbmRpY2VfYXRyb3BoaWUpKSArDQogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMC4xLCBmaWxsID0gImJsdWUiLCBjb2xvciA9ICJibGFjayIsIGFscGhhID0gMC44KSArDQogIGxhYnModGl0bGUgPSAiRGlzdHJpYnV0aW9uIGRlIGwnaW5kaWNlIGQnYXRyb3BoaWUiLCB4ID0gIkluZGljZV9hdHJvcGhpZSIsIHkgPSAiRnLDqXF1ZW5jZSIpICsNCiAgdGhlbWVfbWluaW1hbCgpDQpoaXN0X2FzZiAlPiUgcGxvdGx5OjpnZ3Bsb3RseSgpDQpgYGANCg0KUG91ciBhbGxlciBwbHVzIGxvaW4gZGFucyBsJ2FuYWx5c2UgZGVzY3JpcHRpdmUsIG9uIHBldXQgw6lnYWxlbWVudCBmYWlyZSBkZXMgZ3JhcGhpcXVlcyBxdWkgYXNzb2NpZW50IG5vdHJlIHZhcmlhYmxlIGTDqXBlbmRhbnRlLCBsZSBDRFIsIGF1eCBhdXRyZXMuDQoNCiMjIENEUiArIFgNCg0KYGBge3J9DQpDRFJTRVhFID0gZ2dwbG90KGRhdGEgPSBkZW1lbmNlMiwgYWVzKHggPSBDRFIsIGZpbGwgPSBzZXhlKSkgKw0KICBnZW9tX2Jhcihwb3NpdGlvbiA9ICJkb2RnZSIpICsNCiAgbGFicyh0aXRsZSA9ICJDb21wYXJhaXNvbiBkZSBDRFIgcGFyIHNleGUiLA0KICAgICAgIHggPSAiQ0RSIiwNCiAgICAgICB5ID0gIk5vbWJyZSBkZSBwYXJ0aWNpcGFudHMiLA0KICAgICAgIGZpbGwgPSAiU2V4ZSIpDQpDRFJTRVhFICU+JSBwbG90bHk6OmdncGxvdGx5KCkNCmBgYA0KDQpgYGB7cn0NCkNEUkVEVUMgPSBnZ3Bsb3QoZGF0YSA9IGRlbWVuY2UyLCBhZXMoeCA9IENEUiwgZmlsbCA9IEVEVUMpKSArDQogIGdlb21fYmFyKHBvc2l0aW9uID0gImRvZGdlIikgKw0KICBsYWJzKHRpdGxlID0gIkNvbXBhcmFpc29uIGRlIENEUiBwYXIgbml2ZWF1IGQnw6lkdWNhdGlvbiIsDQogICAgICAgeCA9ICJDRFIiLA0KICAgICAgIHkgPSAiTm9tYnJlIGRlIHBhcnRpY2lwYW50cyIsDQogICAgICAgZmlsbCA9ICJFRFVDIikNCg0KQ0RSRURVQyAlPiUgcGxvdGx5OjpnZ3Bsb3RseSgpDQpgYGANCg0KYGBge3J9DQpDRFJTRVMgPSBnZ3Bsb3QoZGF0YSA9IGRlbWVuY2UyLCBhZXMoeCA9IENEUiwgZmlsbCA9IFNFUykpICsNCiAgZ2VvbV9iYXIocG9zaXRpb24gPSAiZG9kZ2UiKSArDQogIGxhYnModGl0bGUgPSAiQ29tcGFyYWlzb24gZGUgQ0RSIHBhciBuaXZlYXUgc29jaW8tw6ljb25vbWlxdWUiLA0KICAgICAgIHggPSAiQ0RSIiwNCiAgICAgICB5ID0gIk5vbWJyZSBkZSBwYXJ0aWNpcGFudHMiLA0KICAgICAgIGZpbGwgPSAiU0VTIikNCg0KQ0RSU0VTICU+JSBwbG90bHk6OmdncGxvdGx5KCkNCmBgYA0KDQpgYGB7cn0NCkNEUlNFUyA9IGdncGxvdChkYXRhID0gZGVtZW5jZTIsIGFlcyh4ID0gQ0RSLCBmaWxsID0gTU1TRSkpICsNCiAgZ2VvbV9iYXIocG9zaXRpb24gPSAiZG9kZ2UiKSArDQogIGxhYnModGl0bGUgPSAiQ29tcGFyYWlzb24gZGUgQ0RSIHBhciBNTVNFIiwNCiAgICAgICB4ID0gIkNEUiIsDQogICAgICAgeSA9ICJOb21icmUgZGUgcGFydGljaXBhbnRzIiwNCiAgICAgICBmaWxsID0gIk1NU0UiKQ0KDQpDRFJTRVMgJT4lIHBsb3RseTo6Z2dwbG90bHkoKQ0KYGBgDQoNCmBgYHtyfQ0KQ0RSZVRJViA9IGdncGxvdChkZW1lbmNlMiwgYWVzKHggPSBDRFIsIHkgPSBWb2x1bWVfY8OpcsOpYnJhbF90b3RhbCkpICsNCiAgZ2VvbV9ib3hwbG90KGZpbGwgPSAibGlnaHRncmVlbiIsIGNvbG9yID0gImJsYWNrIikgKw0KICBsYWJzKHggPSAiQ0RSIiwgeSA9ICJWb2x1bWUgY8OpcsOpYnJhbCB0b3RhbCIsIHRpdGxlID0gIkRpc3RyaWJ1dGlvbiBkdSB2b2x1bWUgY8OpcsOpYnJhbCBwYXIgQ0RSIikNCg0KQ0RSZVRJViAlPiUgcGxvdGx5OjpnZ3Bsb3RseSgpDQpgYGANCg0KYGBge3J9DQpDRFJBU0YgPSBnZ3Bsb3QoZGVtZW5jZTIsIGFlcyh4ID0gQ0RSLCB5ID0gSW5kaWNlX2F0cm9waGllKSkgKw0KICBnZW9tX2JveHBsb3QoZmlsbCA9ICJkYXJrcmVkIiwgY29sb3IgPSAiYmxhY2siKSArDQogIGxhYnMoeCA9ICJDRFIiLCB5ID0gIkFTRiIsIHRpdGxlID0gIkRpc3RyaWJ1dGlvbiBkZSBsJ2luZGljZSBkJ2F0cm9waGllIHBhciBDRFIiKQ0KQ0RSQVNGICU+JSBwbG90bHk6OmdncGxvdGx5KCkNCmBgYA0KDQojIyBDb3Jyw6lsYXRpb24gZGUgUGVhcnNvbg0KDQpMZXMgY29ycsOpbGF0aW9ucyBkZSBQZWFyc29uIHBlcm1ldHRlbnQgZGUgbWVzdXJlciBsYSByZWxhdGlvbiBsaW7DqWFpcmUgZW50cmUgZGV1eCB2YXJpYWJsZXMgY29udGludWVzLiBFbGxlcyBwZXJtZXR0ZW50IGRlIHF1YW50aWZpZXIgbGEgZm9yY2UgZXQgbGEgZGlyZWN0aW9uIGRlIGNldHRlIHJlbGF0aW9uLCBjZSBxdWkgZmFjaWxpdGUgbGEgY29tcHLDqWhlbnNpb24gZGVzIGRvbm7DqWVzIGV0IGwnaWRlbnRpZmljYXRpb24gZGUgdGVuZGFuY2VzLiBMJ2ludGVycHLDqXRhdGlvbiBkZSBsYSBjb3Jyw6lsYXRpb24gZGUgUGVhcnNvbiBzZSBmYWl0IMOgIHRyYXZlcnMgc29uIGNvZWZmaWNpZW50LCBxdWkgdmFyaWUgZGUgLTEgw6AgMSA6IHVuZSBjb3Jyw6lsYXRpb24gcHJvY2hlIGRlIDEgaW5kaXF1ZSB1bmUgZm9ydGUgY29ycsOpbGF0aW9uIHBvc2l0aXZlLCBwcm9jaGUgZGUgLTEgdW5lIGZvcnRlIGNvcnLDqWxhdGlvbiBuw6lnYXRpdmUsIHRhbmRpcyBxdSd1bmUgdmFsZXVyIHByb2NoZSBkZSAwIHN1Z2fDqHJlIHVuZSBmYWlibGUgY29ycsOpbGF0aW9uIGVudHJlIGxlcyB2YXJpYWJsZXMuDQoNCmBgYHtyfQ0KDQpzdXBwcmVzc01lc3NhZ2VzKHsNCiAgc3VwcHJlc3NXYXJuaW5ncyh7DQogICAgZ2V0X3VwcGVyX3RyaSA8LSBmdW5jdGlvbihjb3JtYXQpew0KICAgICAgY29ybWF0W2xvd2VyLnRyaShjb3JtYXQpXSA8LSBOQQ0KICAgICAgcmV0dXJuKGNvcm1hdCkNCiAgICB9DQogICAgY29ybWF0IDwtIHJvdW5kKGNvcihzdWJzZXQoZGVtZW5jZTIsIHNlbGVjdCA9IGMoIkFnZSIsICJWb2x1bWVfY8OpcsOpYnJhbF90b3RhbCIsICJWb2x1bWVfc3Vic3RhbmNlX2JsYW5jaGUiLCAiSW5kaWNlX2F0cm9waGllIikpLCANCiAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZCA9ICJzcGVhcm1hbiIsIHVzZSA9ICJwYWlyd2lzZS5jb21wbGV0ZS5vYnMiKSwgMikNCiAgICANCiAgICB1cHBlcl90cmkgPC0gZ2V0X3VwcGVyX3RyaShjb3JtYXQpDQogICAgbWVsdGVkX2Nvcm1hdCA8LSByZXNoYXBlMjo6bWVsdCh1cHBlcl90cmksIG5hLnJtID0gVFJVRSkNCiAgICANCiAgICBDT1JSID0gZ2dwbG90KG1lbHRlZF9jb3JtYXQsIGFlcyhWYXIyLCBWYXIxLCBmaWxsID0gdmFsdWUpKSArDQogICAgICBnZW9tX3RpbGUoY29sb3IgPSAid2hpdGUiKSArDQogICAgICBzY2FsZV9maWxsX2dyYWRpZW50Mihsb3cgPSAiYmx1ZSIsIGhpZ2ggPSAicmVkIiwgbWlkID0gIndoaXRlIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pZHBvaW50ID0gMCwgbGltaXQgPSBjKC0wLjIsIDEpLCBzcGFjZSA9ICJMYWIiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSA9ICJTcGVhcm1hblxuQ29ycmVsYXRpb24iKSArDQogICAgICB0aGVtZV9taW5pbWFsKCkgKw0KICAgICAgY29vcmRfZml4ZWQoKSArDQogICAgICBnZW9tX3RleHQoYWVzKFZhcjIsIFZhcjEsIGxhYmVsID0gdmFsdWUpLCBjb2xvciA9ICJibGFjayIsIHNpemUgPSA0KSArDQogICAgICB0aGVtZSgNCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgdmp1c3QgPSAxLCBzaXplID0gMTIsIGhqdXN0ID0gMSksDQogICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksDQogICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBsZWdlbmQucG9zaXRpb24gPSBjKDAuMywgMC44KSwNCiAgICAgICAgbGVnZW5kLmRpcmVjdGlvbiA9ICJob3Jpem9udGFsIg0KICAgICAgKSArDQogICAgICBndWlkZXMoZmlsbCA9IGd1aWRlX2NvbG9yYmFyKGJhcndpZHRoID0gMTIsIGJhcmhlaWdodCA9IDEsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlLnBvc2l0aW9uID0gInRvcCIsIHRpdGxlLmhqdXN0ID0gMC41KSkNCiAgICANCiAgICBDT1JSICU+JSBwbG90bHk6OmdncGxvdGx5KCkNCiAgfSkNCn0pDQpgYGANCg0KIyMgQ29lZmZpY2llbnQgZGUgQ3JhbcOpcg0KDQpMZSBjb2VmZmljaWVudCBkZSBDcmFtw6lyIG1lc3VyZSBsJ2Fzc29jaWF0aW9uIGVudHJlIGRldXggdmFyaWFibGVzIGNhdMOpZ29yaWVsbGVzLiBDYWxjdWzDqSDDoCBwYXJ0aXIgZGVzIHRhYmxlcyBkZSBjb250aW5nZW5jZSwgaWwgdmFyaWUgZGUgMCAoYXVjdW5lIGFzc29jaWF0aW9uKSDDoCAxIChhc3NvY2lhdGlvbiBwYXJmYWl0ZSkuIFVuZSB2YWxldXIgcHJvY2hlIGRlIDAgaW5kaXF1ZSB1bmUgZmFpYmxlIHJlbGF0aW9uLCB0YW5kaXMgcXVlIHByw6hzIGRlIDEgaW5kaXF1ZSB1bmUgZm9ydGUgYXNzb2NpYXRpb24uIElsIHNlcnQgw6Agw6l2YWx1ZXIgbGEgZMOpcGVuZGFuY2UgZW50cmUgbGVzIHZhcmlhYmxlcy4NCg0KYGBge3J9DQojIG9uIGNyw6llIGQnYWJvcmQgZGVzIHRhYmxlcyBkZSBjb250aW5nZW5jZSBwb3VyIGNoYXF1ZSBwYWlyZSBkZSB2YXJpYWJsZXMNCg0KdDEgPSB0YWJsZShkZW1lbmNlMiRzZXhlLCBkZW1lbmNlMiRDRFIpDQp0MiA9IHRhYmxlKGRlbWVuY2UyJE1NU0UsZGVtZW5jZTIkQ0RSKQ0KdDMgPSB0YWJsZShkZW1lbmNlMiRFRFVDLGRlbWVuY2UyJENEUikNCnQ0ID0gdGFibGUoZGVtZW5jZTIkU0VTLGRlbWVuY2UyJENEUikNCg0KIyBjYWxjdWwgZGVzIGxlcyBzdGF0aXN0aXF1ZXMgZCdhc3NvY2lhdGlvbiBwb3VyIGNoYXF1ZSB0YWJsZQ0KbWExID0gYXNzb2NzdGF0cyh0MSkNCm1hMiA9IGFzc29jc3RhdHModDIpDQptYTMgPSBhc3NvY3N0YXRzKHQzKQ0KbWE0ID0gYXNzb2NzdGF0cyh0NCkNCg0KZGF0YSA8LSBkYXRhLmZyYW1lKA0KICBWYXJpYWJsZSA9IGMoIlNleGUiLCAiTU1TRSIsICJFRFVDIiwgIlNFUyIpLA0KICBDb2VmZmljaWVudGRlQ3JhbWVyID0gYyhtYTEkY3JhbWVyLCBtYTIkY3JhbWVyLCBtYTMkY3JhbWVyLCBtYTQkY3JhbWVyKQ0KKQ0KQ3JhbWVyX1YgPSAgYyhtYTEkY3JhbWVyLCBtYTIkY3JhbWVyLCBtYTMkY3JhbWVyLCBtYTQkY3JhbWVyKQ0KDQojIENyw6llciBsZSBncmFwaGlxdWUgw6AgYmFycmVzDQpHR0NyYW0gPSBnZ3Bsb3QoZGF0YSwgYWVzKHggPSBWYXJpYWJsZSwgeSA9IENvZWZmaWNpZW50ZGVDcmFtZXIsIGZpbGwgPSBDb2VmZmljaWVudGRlQ3JhbWVyKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSAiZG9kZ2UiLCB3aWR0aCA9IDAuNywgY29sb3IgPSAiYmxhY2siKSArDQogIHNjYWxlX2ZpbGxfZ3JhZGllbnQyKGxvdyA9ICJkYXJrYmx1ZSIsIG1pZCA9ICJ3aGl0ZSIsIGhpZ2ggPSAicmVkIiwgDQogICAgICAgICAgICAgICAgICAgICAgIG1pZHBvaW50ID0gMC41LCBsaW1pdHMgPSBjKDAsIDEpLCANCiAgICAgICAgICAgICAgICAgICAgICAgbmFtZSA9ICJJbmRpY2UgZGUgQ3JhbcOpciIpICsNCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMC41LCBsaW5ldHlwZSA9ICJkYXNoZWQiLCBjb2xvciA9ICJibGFjayIpICsNCiAgbGFicyh0aXRsZSA9ICJDb2VmZmljaWVudHMgZGUgQ3JhbWVyIHBvdXIgY2hhcXVlIHZhcmlhYmxlIGVuIGZvbmN0aW9uIGRlIGwnQVZDIiwNCiAgICAgICB4ID0gIlZhcmlhYmxlcyIsDQogICAgICAgeSA9ICJDcmFtw6lyJ3MgViIpICsNCiAgdGhlbWVfYncoKQ0KDQoNCkdHQ3JhbSAlPiUgcGxvdGx5OjpnZ3Bsb3RseSgpDQpgYGANCg0KIyBWSUkuIEJpYmxpb2dyYXBoaWUNCg==