Introduction

Notre recherche se concentre sur l’identification des facteurs prédictifs de la démence. Notre variable dépendante, le “CDR” (Clinical Dementia Rate), est un indicateur neurologique établi en 1993 par Morris. Cette variable est ici binaire, avec 0 pour les individus non atteints de démence et 1 pour ceux qui le sont. Nous examinons également plusieurs autres variables potentiellement pertinentes, notamment le sexe, l’âge, le niveau d’éducation, le niveau socio-culturel, le volume de substance blanche, le volume cérébral total, le niveau d’atrophie, ainsi que le Mini Mental State Examination (MMSE). Bien que le MMSE soit un test neurologique largement utilisé en raison de sa rapidité, il est toutefois souvent critiqué dans la littérature pour sa moindre précision et sa fiabilité variable. Nous avons l’opportunité de vérifier ces points en l’incluant dans notre étude parallèlement au CDR.

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()

VII. Bibliographie

LS0tDQp0aXRsZTogInN1cGVyIHByb2pldCINCmF1dGhvcjogInZhbG91Ig0Kb3V0cHV0Og0KICBodG1sX25vdGVib29rOg0KICAgIHRvYzogdHJ1ZQ0KICAgIGRmX3ByaW50OiBwYWdlZA0KICAgIHRoZW1lOiBqb3VybmFsDQogICAgdG9jX2Zsb2F0OiB0cnVlDQotLS0NCg0KYGBgez1odG1sfQ0KPHN0eWxlPg0KYm9keXsNCiAgdGV4dC1hbGlnbjoganVzdGlmeX0NCjwvc3R5bGU+DQpgYGANCg0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKQ0KDQpsaWJyYXJ5KGRhdGEudGFibGUpDQpsaWJyYXJ5KGNhcmV0KQ0KbGlicmFyeShyYW5kb21Gb3Jlc3QpDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KHZjZCkNCmxpYnJhcnkocnBhcnQpDQpsaWJyYXJ5KHJwYXJ0LnBsb3QpDQpsaWJyYXJ5KGNhcikNCmxpYnJhcnkoTUFTUykNCmxpYnJhcnkoZ3JpZEV4dHJhKQ0KbGlicmFyeShwbG90bHkpDQpsaWJyYXJ5KHBST0MpDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeShGYWN0b01pbmVSKQ0KDQp0ZW1wIDwtIHRlbXBmaWxlKGZpbGVleHQgPSAiLmNzdiIpDQpkb3dubG9hZC5maWxlKCJodHRwczovL2RyaXZlLmdvb2dsZS5jb20vdWM/ZXhwb3J0PWRvd25sb2FkJmlkPTFlYWM1cUNIZDFfdzRLbUZueFhiUnJBNW1SUjRjOFhYdCIsIHRlbXApDQpkZW1lbmNlMiA8LSByZWFkLmNzdih0ZW1wKQ0KDQpkZW1lbmNlMiA8LSBkZW1lbmNlMlssIC1jKDEsIDIsIDMsIDQsIDUsIDcpXQ0KDQojIFLDqWR1Y3Rpb24gZHUgbm9tYnJlIGRlIG5pdmVhdXggZGUgbGEgdmFyaWFibGUgRURVQw0KZGVtZW5jZTIgPC0gZGVtZW5jZTIgJT4lDQogIG11dGF0ZShFRFVDID0gY2FzZV93aGVuKA0KICAgIEVEVUMgJWluJSA2OjggfiAiNi04IiwNCiAgICBFRFVDICVpbiUgMTE6MTMgfiAiMTEtMTMiLA0KICAgIEVEVUMgJWluJSAxNDoxNiB+ICIxNC0xNiIsDQogICAgRURVQyAlaW4lIDE3OjE4IH4gIjE3LTE4IiwNCiAgICBFRFVDICVpbiUgMjA6MjMgfiAiMjAtMjMiLA0KICAgIFRSVUUgfiBhcy5jaGFyYWN0ZXIoRURVQykgICMgVmFsZXVycyBxdWkgbmUgcmVudHJlbnQgZGFucyBhdWN1biBncm91cGUNCiAgKSkNCg0KDQpkZW1lbmNlMiRDRFIgPC0gaWZlbHNlKGRlbWVuY2UyJENEUiA9PSAwLCAiTm9uX2TDqW1lbnQiLCAiRMOpbWVudCIpDQoNCmludGVydmFscyA8LSBjdXQoZGVtZW5jZTIkTU1TRSwgYnJlYWtzID0gYygwLCAxNywgMjMsIDMwKSwgbGFiZWxzID0gYygiVHJvdWJsZV9zw6l2w6hyZSIsICJUcm91YmxlX2zDqWdlciIsICJBdWN1bl90cm91YmxlIiksIGluY2x1ZGUubG93ZXN0ID0gVFJVRSkNCg0KZGVtZW5jZTIkTU1TRSA8LSBhcy5jaGFyYWN0ZXIoaW50ZXJ2YWxzKQ0KdGFibGUoZGVtZW5jZTIkTU1TRSkNCnRhYmxlKGRlbWVuY2UyJENEUikNCg0KZGVtZW5jZTIkQ0RSIDwtIGFzLmZhY3RvcihkZW1lbmNlMiRDRFIpDQpkZW1lbmNlMiRzZXhlIDwtIGZhY3RvcihkZW1lbmNlMiRzZXhlKQ0KZGVtZW5jZTIkU0VTIDwtIGZhY3RvcihkZW1lbmNlMiRTRVMpDQpkZW1lbmNlMiRFRFVDIDwtIGZhY3RvcihkZW1lbmNlMiRFRFVDKQ0KZGVtZW5jZTIkTU1TRSA8LSBmYWN0b3IoZGVtZW5jZTIkTU1TRSkNCnRhYmxlKGRlbWVuY2UyJENEUikNCg0KIyBCb3VjbGUgcG91ciBjb252ZXJ0aXIgZGVzIGNvbG9ubmVzIHNww6ljaWZpcXVlcyBlbiBudW3DqXJpcXVlcw0KZm9yIChpIGluIGMoIkFnZSIsICJuV0JWIiwgIkFTRiIsICJlVElWIikpIHsNCiAgZGVtZW5jZTJbLCBpXSA8LSBhcy5udW1lcmljKGFzLmNoYXJhY3RlcihkZW1lbmNlMlssIGldKSkNCn0NCg0KIyBTdXBwcmltZXIgbGVzIHZhbGV1cnMgbWFucXVhbnRlcw0KZGVtZW5jZTIgPC0gbmEub21pdChkZW1lbmNlMikNCg0KY29sbmFtZXMoZGVtZW5jZTIpIDwtIGMoInNleGUiLCAiQWdlIiwgIkVEVUMiLCAiU0VTIiwgIk1NU0UiLCAiQ0RSIiwgIlZvbHVtZV9jw6lyw6licmFsX3RvdGFsIiwgIlZvbHVtZV9zdWJzdGFuY2VfYmxhbmNoZSIsICJJbmRpY2VfYXRyb3BoaWUiKQ0KDQoNCg0KZmFzdGdncGxvdCA8LSBmdW5jdGlvbihkYXRhLCB4X3ZhciwgdGl0bGUsIHhfbGFiZWwsIHlfbGFiZWwpIHsNCiAgZ2dwbG90KGRhdGEsIGFlcyh4ID0gZmFjdG9yKGRhdGFbW3hfdmFyXV0pLCBmaWxsID0gZmFjdG9yKGRhdGFbW3hfdmFyXV0pKSkgKw0KICAgIGdlb21fYmFyKGNvbG9yID0gImJsYWNrIiwgYWxwaGEgPSAwLjgpICsNCiAgICANCiAgICBsYWJzKHRpdGxlID0gdGl0bGUsIHggPSB4X2xhYmVsLCB5ID0geV9sYWJlbCwgZmlsbCA9IHhfdmFyKSArDQogICAgdGhlbWVfbWluaW1hbCgpICsNCiAgICB0aGVtZShheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwNCiAgICAgICAgICBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCwgZmFjZSA9ICJib2xkIiksDQogICAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTYsIGZhY2UgPSAiYm9sZCIpKQ0KfQ0KDQoNCmBgYA0KDQojIEludHJvZHVjdGlvbg0KDQpOb3RyZSByZWNoZXJjaGUgc2UgY29uY2VudHJlIHN1ciBsJ2lkZW50aWZpY2F0aW9uIGRlcyBmYWN0ZXVycyBwcsOpZGljdGlmcyBkZSBsYSBkw6ltZW5jZS4gTm90cmUgKip2YXJpYWJsZSBkw6lwZW5kYW50ZSwgbGUgIkNEUiIqKiAoQ2xpbmljYWwgRGVtZW50aWEgUmF0ZSksIGVzdCB1biBpbmRpY2F0ZXVyIG5ldXJvbG9naXF1ZSDDqXRhYmxpIGVuIDE5OTMgcGFyIE1vcnJpcy4gQ2V0dGUgdmFyaWFibGUgZXN0IGljaSBiaW5haXJlLCBhdmVjIDAgcG91ciBsZXMgaW5kaXZpZHVzIG5vbiBhdHRlaW50cyBkZSBkw6ltZW5jZSBldCAxIHBvdXIgY2V1eCBxdWkgbGUgc29udC4gTm91cyBleGFtaW5vbnMgw6lnYWxlbWVudCBwbHVzaWV1cnMgYXV0cmVzIHZhcmlhYmxlcyBwb3RlbnRpZWxsZW1lbnQgcGVydGluZW50ZXMsIG5vdGFtbWVudCAqKmxlIHNleGUsIGwnw6JnZSwgbGUgbml2ZWF1IGQnw6lkdWNhdGlvbiwgbGUgbml2ZWF1IHNvY2lvLWN1bHR1cmVsLCBsZSB2b2x1bWUgZGUgc3Vic3RhbmNlIGJsYW5jaGUsIGxlIHZvbHVtZSBjw6lyw6licmFsIHRvdGFsLCBsZSBuaXZlYXUgZCdhdHJvcGhpZSwgYWluc2kgcXVlIGxlIE1pbmkgTWVudGFsIFN0YXRlIEV4YW1pbmF0aW9uIChNTVNFKSoqLiBCaWVuIHF1ZSBsZSBNTVNFIHNvaXQgdW4gdGVzdCBuZXVyb2xvZ2lxdWUgbGFyZ2VtZW50IHV0aWxpc8OpIGVuIHJhaXNvbiBkZSBzYSByYXBpZGl0w6ksIGlsIGVzdCB0b3V0ZWZvaXMgc291dmVudCBjcml0aXF1w6kgZGFucyBsYSBsaXR0w6lyYXR1cmUgcG91ciBzYSBtb2luZHJlIHByw6ljaXNpb24gZXQgc2EgZmlhYmlsaXTDqSB2YXJpYWJsZS4gTm91cyBhdm9ucyBsJ29wcG9ydHVuaXTDqSBkZSB2w6lyaWZpZXIgY2VzIHBvaW50cyBlbiBsJ2luY2x1YW50IGRhbnMgbm90cmUgw6l0dWRlIHBhcmFsbMOobGVtZW50IGF1IENEUi4NCg0KIyBBbmFseXNlIGRlc2NyaXB0aXZlDQoNCkwnYW5hbHlzZSBkZXNjcmlwdGl2ZSBwZXJtZXQgZGUgY29tcHJlbmRyZSBsYSBkaXN0cmlidXRpb24gZXQgbGVzIGNhcmFjdMOpcmlzdGlxdWVzIGfDqW7DqXJhbGVzIGRlcyBkb25uw6llcywgb2ZmcmFudCBhaW5zaSB1biBhcGVyw6d1IHByw6lsaW1pbmFpcmUgZGVzIHRlbmRhbmNlcyBldCBkZXMgYXNzb2NpYXRpb25zIHBvdGVudGllbGxlcyBlbnRyZSBsZXMgdmFyaWFibGVzIMOpdHVkacOpZXMuDQoNCklsIGVzdCBpbXBvcnRhbnQgZGUgcydhc3N1cmVyIHF1ZSBsZXMgbml2ZWF1eCBkZXMgdmFyaWFibGVzIHNvbnQgYXNzZXogw6lxdWlsaWJyw6ksIGNhciBzaW5vbiBpbHMgcG91cnJhaWVudCDDqnRyZSBzb3VzLXJlcHLDqXNlbnTDqXMgZGFucyBsZXMgYW5hbHlzZXMgw6AgdmVuaXIsIHNpIGMnZXN0IGxlIGNhcyBpbCBzZXJhIGFpbnNpIGltcG9ydGFudCBkZSBsZSBwcmVuZHJlIGVuIGNvbXB0ZSBsb3JzIGRlIGwnaW50ZXJwcsOpdGF0aW9uLg0KDQpQb3VyIHNpbXBsaWZpZXIgbGEgY3LDqWF0aW9uIGRlcyBncmFwaGlxdWVzLCBub3VzIHBvdXZvbnMgw6ljcmlyZSB1bmUgZm9uY3Rpb24gcXVpIGluY2x1dCB0b3VzIGxlcyBwYXJhbcOodHJlcyBuw6ljZXNzYWlyZXMuIENlbGEgbm91cyBwZXJtZXR0cmEgZGUgZ8OpbsOpcmVyIGRlcyBnZ3Bsb3QgcGx1cyByYXBpZGVtZW50Lg0KDQpgYGB7ciBjYXJzfQ0KDQpmYXN0Z2dwbG90IDwtIGZ1bmN0aW9uKGRhdGEsIHhfdmFyLCB0aXRsZSwgeF9sYWJlbCwgeV9sYWJlbCkgew0KICBnZ3Bsb3QoZGF0YSwgYWVzKHggPSBmYWN0b3IoZGF0YVtbeF92YXJdXSksIGZpbGwgPSBmYWN0b3IoZGF0YVtbeF92YXJdXSkpKSArDQogICAgZ2VvbV9iYXIoY29sb3IgPSAiYmxhY2siLCBhbHBoYSA9IDAuOCkgKw0KICAgIA0KICAgIGxhYnModGl0bGUgPSB0aXRsZSwgeCA9IHhfbGFiZWwsIHkgPSB5X2xhYmVsLCBmaWxsID0geF92YXIpICsNCiAgICB0aGVtZV9taW5pbWFsKCkgKw0KICAgIHRoZW1lKGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLA0KICAgICAgICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0LCBmYWNlID0gImJvbGQiKSwNCiAgICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNiwgZmFjZSA9ICJib2xkIikpDQp9DQoNCmBgYA0KDQpgYGB7cn0NCkNEUiA8LSBmYXN0Z2dwbG90KGRlbWVuY2UyLCAiQ0RSIiwgIlLDqXBhcnRpdGlvbiBwYXIgc2NvcmUgQ0RSIiwgIlNjb3JlIENEUiIsICJOb21icmUgZGUgY2FzIikNCkNEUiAlPiUgcGxvdGx5OjpnZ3Bsb3RseSgpDQpgYGANCg0KYGBge3J9DQpNTVNFIDwtIGZhc3RnZ3Bsb3QoZGVtZW5jZTIsICJNTVNFIiwgIlLDqXBhcnRpdGlvbiBwYXIgc2NvcmUgTU1TRSIsICJTY29yZSBNTVNFIiwgIk5vbWJyZSBkZSBjYXMiKQ0KTU1TRSAlPiUgcGxvdGx5OjpnZ3Bsb3RseSgpDQpgYGANCg0KYGBge3J9DQpFRFVDIDwtIGZhc3RnZ3Bsb3QoZGVtZW5jZTIsICJFRFVDIiwgIlLDqXBhcnRpdGlvbiBwYXIgbml2ZWF1IGQnw6lkdWNhdGlvbiIsICJOaXZlYXUgZCfDqWR1Y2F0aW9uIiwgIk5vbWJyZSBkZSBjYXMiKQ0KRURVQyAlPiUgcGxvdGx5OjpnZ3Bsb3RseSgpDQpgYGANCg0KYGBge3J9DQpnZW5yZSA9IGZhc3RnZ3Bsb3QoZGVtZW5jZTIsICJzZXhlIiwgIlLDqXBhcnRpdGlvbiBwYXIgc2V4ZSIsICJHZW5yZSIsICJOb21icmUgZGUgY2FzIikNCmdlbnJlICU+JSBwbG90bHk6OmdncGxvdGx5KCkNCmBgYA0KDQojIyBHcmFwaGlxdWUgZGVzIHZhcmlhYmxlcyBxdWFudGl0YXRpdmVzDQoNCmBgYHtyfQ0KaGlzdF9hZ2UgPC0gZ2dwbG90KGRlbWVuY2UyLCBhZXMoeCA9IEFnZSkpICsNCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAwLjAxLCBmaWxsID0gImdyZWVuIiwgY29sb3IgPSAiYmxhY2siLCBhbHBoYSA9IDAuOCkgKw0KICBsYWJzKHRpdGxlID0gIkRpc3RyaWJ1dGlvbiBkZSBsJ8OiZ2UiLCB4ID0gIiIsIHkgPSAiRnLDqXF1ZW5jZSIpICsNCiAgdGhlbWVfbWluaW1hbCgpDQpoaXN0X2FnZSAlPiUgcGxvdGx5OjpnZ3Bsb3RseSgpDQpgYGANCg0KYGBge3J9DQpoaXN0X253YnYgPC0gZ2dwbG90KGRlbWVuY2UyLCBhZXMoeCA9IFZvbHVtZV9zdWJzdGFuY2VfYmxhbmNoZSkpICsNCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAwLjAxLCBmaWxsID0gImdyZWVuIiwgY29sb3IgPSAiYmxhY2siLCBhbHBoYSA9IDAuOCkgKw0KICBsYWJzKHRpdGxlID0gIkRpc3RyaWJ1dGlvbiBkdSB2b2x1bWUgZGUgc3Vic3RhbmNlIGJsYW5jaGUiLCB4ID0gIlN1YnN0YW5jZSBibGFuY2hlIiwgeSA9ICJGcsOpcXVlbmNlIikgKw0KICB0aGVtZV9taW5pbWFsKCkNCmhpc3RfbndidiAlPiUgcGxvdGx5OjpnZ3Bsb3RseSgpDQpgYGANCg0KYGBge3J9DQpoaXN0X2V0aXYgPC0gZ2dwbG90KGRlbWVuY2UyLCBhZXMoeCA9IFZvbHVtZV9jw6lyw6licmFsX3RvdGFsKSkgKw0KICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDEwMCwgZmlsbCA9ICJvcmFuZ2UiLCBjb2xvciA9ICJibGFjayIsIGFscGhhID0gMC44KSArDQogIGxhYnModGl0bGUgPSAiRGlzdHJpYnV0aW9uIGR1IHZvbHVtZSBjw6lyw6licmFsIiwgeCA9ICJlVElWIiwgeSA9ICJGcsOpcXVlbmNlIikgKw0KICB0aGVtZV9taW5pbWFsKCkNCmhpc3RfZXRpdiAlPiUgcGxvdGx5OjpnZ3Bsb3RseSgpDQpgYGANCg0KYGBge3J9DQpoaXN0X2FzZiA8LSBnZ3Bsb3QoZGVtZW5jZTIsIGFlcyh4ID0gSW5kaWNlX2F0cm9waGllKSkgKw0KICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDAuMSwgZmlsbCA9ICJibHVlIiwgY29sb3IgPSAiYmxhY2siLCBhbHBoYSA9IDAuOCkgKw0KICBsYWJzKHRpdGxlID0gIkRpc3RyaWJ1dGlvbiBkZSBsJ2luZGljZSBkJ2F0cm9waGllIiwgeCA9ICJJbmRpY2VfYXRyb3BoaWUiLCB5ID0gIkZyw6lxdWVuY2UiKSArDQogIHRoZW1lX21pbmltYWwoKQ0KaGlzdF9hc2YgJT4lIHBsb3RseTo6Z2dwbG90bHkoKQ0KYGBgDQoNClBvdXIgYWxsZXIgcGx1cyBsb2luIGRhbnMgbCdhbmFseXNlIGRlc2NyaXB0aXZlLCBvbiBwZXV0IMOpZ2FsZW1lbnQgZmFpcmUgZGVzIGdyYXBoaXF1ZXMgcXVpIGFzc29jaWVudCBub3RyZSB2YXJpYWJsZSBkw6lwZW5kYW50ZSwgbGUgQ0RSLCBhdXggYXV0cmVzLg0KDQojIyBDRFIgKyBYDQoNCmBgYHtyfQ0KQ0RSU0VYRSA9IGdncGxvdChkYXRhID0gZGVtZW5jZTIsIGFlcyh4ID0gQ0RSLCBmaWxsID0gc2V4ZSkpICsNCiAgZ2VvbV9iYXIocG9zaXRpb24gPSAiZG9kZ2UiKSArDQogIGxhYnModGl0bGUgPSAiQ29tcGFyYWlzb24gZGUgQ0RSIHBhciBzZXhlIiwNCiAgICAgICB4ID0gIkNEUiIsDQogICAgICAgeSA9ICJOb21icmUgZGUgcGFydGljaXBhbnRzIiwNCiAgICAgICBmaWxsID0gIlNleGUiKQ0KQ0RSU0VYRSAlPiUgcGxvdGx5OjpnZ3Bsb3RseSgpDQpgYGANCg0KYGBge3J9DQpDRFJFRFVDID0gZ2dwbG90KGRhdGEgPSBkZW1lbmNlMiwgYWVzKHggPSBDRFIsIGZpbGwgPSBFRFVDKSkgKw0KICBnZW9tX2Jhcihwb3NpdGlvbiA9ICJkb2RnZSIpICsNCiAgbGFicyh0aXRsZSA9ICJDb21wYXJhaXNvbiBkZSBDRFIgcGFyIG5pdmVhdSBkJ8OpZHVjYXRpb24iLA0KICAgICAgIHggPSAiQ0RSIiwNCiAgICAgICB5ID0gIk5vbWJyZSBkZSBwYXJ0aWNpcGFudHMiLA0KICAgICAgIGZpbGwgPSAiRURVQyIpDQoNCkNEUkVEVUMgJT4lIHBsb3RseTo6Z2dwbG90bHkoKQ0KYGBgDQoNCmBgYHtyfQ0KQ0RSU0VTID0gZ2dwbG90KGRhdGEgPSBkZW1lbmNlMiwgYWVzKHggPSBDRFIsIGZpbGwgPSBTRVMpKSArDQogIGdlb21fYmFyKHBvc2l0aW9uID0gImRvZGdlIikgKw0KICBsYWJzKHRpdGxlID0gIkNvbXBhcmFpc29uIGRlIENEUiBwYXIgbml2ZWF1IHNvY2lvLcOpY29ub21pcXVlIiwNCiAgICAgICB4ID0gIkNEUiIsDQogICAgICAgeSA9ICJOb21icmUgZGUgcGFydGljaXBhbnRzIiwNCiAgICAgICBmaWxsID0gIlNFUyIpDQoNCkNEUlNFUyAlPiUgcGxvdGx5OjpnZ3Bsb3RseSgpDQpgYGANCg0KYGBge3J9DQpDRFJTRVMgPSBnZ3Bsb3QoZGF0YSA9IGRlbWVuY2UyLCBhZXMoeCA9IENEUiwgZmlsbCA9IE1NU0UpKSArDQogIGdlb21fYmFyKHBvc2l0aW9uID0gImRvZGdlIikgKw0KICBsYWJzKHRpdGxlID0gIkNvbXBhcmFpc29uIGRlIENEUiBwYXIgTU1TRSIsDQogICAgICAgeCA9ICJDRFIiLA0KICAgICAgIHkgPSAiTm9tYnJlIGRlIHBhcnRpY2lwYW50cyIsDQogICAgICAgZmlsbCA9ICJNTVNFIikNCg0KQ0RSU0VTICU+JSBwbG90bHk6OmdncGxvdGx5KCkNCmBgYA0KDQpgYGB7cn0NCkNEUmVUSVYgPSBnZ3Bsb3QoZGVtZW5jZTIsIGFlcyh4ID0gQ0RSLCB5ID0gVm9sdW1lX2PDqXLDqWJyYWxfdG90YWwpKSArDQogIGdlb21fYm94cGxvdChmaWxsID0gImxpZ2h0Z3JlZW4iLCBjb2xvciA9ICJibGFjayIpICsNCiAgbGFicyh4ID0gIkNEUiIsIHkgPSAiVm9sdW1lIGPDqXLDqWJyYWwgdG90YWwiLCB0aXRsZSA9ICJEaXN0cmlidXRpb24gZHUgdm9sdW1lIGPDqXLDqWJyYWwgcGFyIENEUiIpDQoNCkNEUmVUSVYgJT4lIHBsb3RseTo6Z2dwbG90bHkoKQ0KYGBgDQoNCmBgYHtyfQ0KQ0RSQVNGID0gZ2dwbG90KGRlbWVuY2UyLCBhZXMoeCA9IENEUiwgeSA9IEluZGljZV9hdHJvcGhpZSkpICsNCiAgZ2VvbV9ib3hwbG90KGZpbGwgPSAiZGFya3JlZCIsIGNvbG9yID0gImJsYWNrIikgKw0KICBsYWJzKHggPSAiQ0RSIiwgeSA9ICJBU0YiLCB0aXRsZSA9ICJEaXN0cmlidXRpb24gZGUgbCdpbmRpY2UgZCdhdHJvcGhpZSBwYXIgQ0RSIikNCkNEUkFTRiAlPiUgcGxvdGx5OjpnZ3Bsb3RseSgpDQpgYGANCg0KIyMgQ29ycsOpbGF0aW9uIGRlIFBlYXJzb24NCg0KTGVzIGNvcnLDqWxhdGlvbnMgZGUgUGVhcnNvbiBwZXJtZXR0ZW50IGRlIG1lc3VyZXIgbGEgcmVsYXRpb24gbGluw6lhaXJlIGVudHJlIGRldXggdmFyaWFibGVzIGNvbnRpbnVlcy4gRWxsZXMgcGVybWV0dGVudCBkZSBxdWFudGlmaWVyIGxhIGZvcmNlIGV0IGxhIGRpcmVjdGlvbiBkZSBjZXR0ZSByZWxhdGlvbiwgY2UgcXVpIGZhY2lsaXRlIGxhIGNvbXByw6loZW5zaW9uIGRlcyBkb25uw6llcyBldCBsJ2lkZW50aWZpY2F0aW9uIGRlIHRlbmRhbmNlcy4gTCdpbnRlcnByw6l0YXRpb24gZGUgbGEgY29ycsOpbGF0aW9uIGRlIFBlYXJzb24gc2UgZmFpdCDDoCB0cmF2ZXJzIHNvbiBjb2VmZmljaWVudCwgcXVpIHZhcmllIGRlIC0xIMOgIDEgOiB1bmUgY29ycsOpbGF0aW9uIHByb2NoZSBkZSAxIGluZGlxdWUgdW5lIGZvcnRlIGNvcnLDqWxhdGlvbiBwb3NpdGl2ZSwgcHJvY2hlIGRlIC0xIHVuZSBmb3J0ZSBjb3Jyw6lsYXRpb24gbsOpZ2F0aXZlLCB0YW5kaXMgcXUndW5lIHZhbGV1ciBwcm9jaGUgZGUgMCBzdWdnw6hyZSB1bmUgZmFpYmxlIGNvcnLDqWxhdGlvbiBlbnRyZSBsZXMgdmFyaWFibGVzLg0KDQpgYGB7cn0NCg0Kc3VwcHJlc3NNZXNzYWdlcyh7DQogIHN1cHByZXNzV2FybmluZ3Moew0KICAgIGdldF91cHBlcl90cmkgPC0gZnVuY3Rpb24oY29ybWF0KXsNCiAgICAgIGNvcm1hdFtsb3dlci50cmkoY29ybWF0KV0gPC0gTkENCiAgICAgIHJldHVybihjb3JtYXQpDQogICAgfQ0KICAgIGNvcm1hdCA8LSByb3VuZChjb3Ioc3Vic2V0KGRlbWVuY2UyLCBzZWxlY3QgPSBjKCJBZ2UiLCAiVm9sdW1lX2PDqXLDqWJyYWxfdG90YWwiLCAiVm9sdW1lX3N1YnN0YW5jZV9ibGFuY2hlIiwgIkluZGljZV9hdHJvcGhpZSIpKSwgDQogICAgICAgICAgICAgICAgICAgICAgICBtZXRob2QgPSAic3BlYXJtYW4iLCB1c2UgPSAicGFpcndpc2UuY29tcGxldGUub2JzIiksIDIpDQogICAgDQogICAgdXBwZXJfdHJpIDwtIGdldF91cHBlcl90cmkoY29ybWF0KQ0KICAgIG1lbHRlZF9jb3JtYXQgPC0gcmVzaGFwZTI6Om1lbHQodXBwZXJfdHJpLCBuYS5ybSA9IFRSVUUpDQogICAgDQogICAgQ09SUiA9IGdncGxvdChtZWx0ZWRfY29ybWF0LCBhZXMoVmFyMiwgVmFyMSwgZmlsbCA9IHZhbHVlKSkgKw0KICAgICAgZ2VvbV90aWxlKGNvbG9yID0gIndoaXRlIikgKw0KICAgICAgc2NhbGVfZmlsbF9ncmFkaWVudDIobG93ID0gImJsdWUiLCBoaWdoID0gInJlZCIsIG1pZCA9ICJ3aGl0ZSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICBtaWRwb2ludCA9IDAsIGxpbWl0ID0gYygtMC4yLCAxKSwgc3BhY2UgPSAiTGFiIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUgPSAiU3BlYXJtYW5cbkNvcnJlbGF0aW9uIikgKw0KICAgICAgdGhlbWVfbWluaW1hbCgpICsNCiAgICAgIGNvb3JkX2ZpeGVkKCkgKw0KICAgICAgZ2VvbV90ZXh0KGFlcyhWYXIyLCBWYXIxLCBsYWJlbCA9IHZhbHVlKSwgY29sb3IgPSAiYmxhY2siLCBzaXplID0gNCkgKw0KICAgICAgdGhlbWUoDQogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIHZqdXN0ID0gMSwgc2l6ZSA9IDEyLCBoanVzdCA9IDEpLA0KICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLA0KICAgICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gYygwLjMsIDAuOCksDQogICAgICAgIGxlZ2VuZC5kaXJlY3Rpb24gPSAiaG9yaXpvbnRhbCINCiAgICAgICkgKw0KICAgICAgZ3VpZGVzKGZpbGwgPSBndWlkZV9jb2xvcmJhcihiYXJ3aWR0aCA9IDEyLCBiYXJoZWlnaHQgPSAxLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aXRsZS5wb3NpdGlvbiA9ICJ0b3AiLCB0aXRsZS5oanVzdCA9IDAuNSkpDQogICAgDQogICAgQ09SUiAlPiUgcGxvdGx5OjpnZ3Bsb3RseSgpDQogIH0pDQp9KQ0KYGBgDQoNCiMjIENvZWZmaWNpZW50IGRlIENyYW3DqXINCg0KTGUgY29lZmZpY2llbnQgZGUgQ3JhbcOpciBtZXN1cmUgbCdhc3NvY2lhdGlvbiBlbnRyZSBkZXV4IHZhcmlhYmxlcyBjYXTDqWdvcmllbGxlcy4gQ2FsY3Vsw6kgw6AgcGFydGlyIGRlcyB0YWJsZXMgZGUgY29udGluZ2VuY2UsIGlsIHZhcmllIGRlIDAgKGF1Y3VuZSBhc3NvY2lhdGlvbikgw6AgMSAoYXNzb2NpYXRpb24gcGFyZmFpdGUpLiBVbmUgdmFsZXVyIHByb2NoZSBkZSAwIGluZGlxdWUgdW5lIGZhaWJsZSByZWxhdGlvbiwgdGFuZGlzIHF1ZSBwcsOocyBkZSAxIGluZGlxdWUgdW5lIGZvcnRlIGFzc29jaWF0aW9uLiBJbCBzZXJ0IMOgIMOpdmFsdWVyIGxhIGTDqXBlbmRhbmNlIGVudHJlIGxlcyB2YXJpYWJsZXMuDQoNCmBgYHtyfQ0KIyBvbiBjcsOpZSBkJ2Fib3JkIGRlcyB0YWJsZXMgZGUgY29udGluZ2VuY2UgcG91ciBjaGFxdWUgcGFpcmUgZGUgdmFyaWFibGVzDQoNCnQxID0gdGFibGUoZGVtZW5jZTIkc2V4ZSwgZGVtZW5jZTIkQ0RSKQ0KdDIgPSB0YWJsZShkZW1lbmNlMiRNTVNFLGRlbWVuY2UyJENEUikNCnQzID0gdGFibGUoZGVtZW5jZTIkRURVQyxkZW1lbmNlMiRDRFIpDQp0NCA9IHRhYmxlKGRlbWVuY2UyJFNFUyxkZW1lbmNlMiRDRFIpDQoNCiMgY2FsY3VsIGRlcyBsZXMgc3RhdGlzdGlxdWVzIGQnYXNzb2NpYXRpb24gcG91ciBjaGFxdWUgdGFibGUNCm1hMSA9IGFzc29jc3RhdHModDEpDQptYTIgPSBhc3NvY3N0YXRzKHQyKQ0KbWEzID0gYXNzb2NzdGF0cyh0MykNCm1hNCA9IGFzc29jc3RhdHModDQpDQoNCmRhdGEgPC0gZGF0YS5mcmFtZSgNCiAgVmFyaWFibGUgPSBjKCJTZXhlIiwgIk1NU0UiLCAiRURVQyIsICJTRVMiKSwNCiAgQ29lZmZpY2llbnRkZUNyYW1lciA9IGMobWExJGNyYW1lciwgbWEyJGNyYW1lciwgbWEzJGNyYW1lciwgbWE0JGNyYW1lcikNCikNCkNyYW1lcl9WID0gIGMobWExJGNyYW1lciwgbWEyJGNyYW1lciwgbWEzJGNyYW1lciwgbWE0JGNyYW1lcikNCg0KIyBDcsOpZXIgbGUgZ3JhcGhpcXVlIMOgIGJhcnJlcw0KR0dDcmFtID0gZ2dwbG90KGRhdGEsIGFlcyh4ID0gVmFyaWFibGUsIHkgPSBDb2VmZmljaWVudGRlQ3JhbWVyLCBmaWxsID0gQ29lZmZpY2llbnRkZUNyYW1lcikpICsNCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gImRvZGdlIiwgd2lkdGggPSAwLjcsIGNvbG9yID0gImJsYWNrIikgKw0KICBzY2FsZV9maWxsX2dyYWRpZW50Mihsb3cgPSAiZGFya2JsdWUiLCBtaWQgPSAid2hpdGUiLCBoaWdoID0gInJlZCIsIA0KICAgICAgICAgICAgICAgICAgICAgICBtaWRwb2ludCA9IDAuNSwgbGltaXRzID0gYygwLCAxKSwgDQogICAgICAgICAgICAgICAgICAgICAgIG5hbWUgPSAiSW5kaWNlIGRlIENyYW3DqXIiKSArDQogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAuNSwgbGluZXR5cGUgPSAiZGFzaGVkIiwgY29sb3IgPSAiYmxhY2siKSArDQogIGxhYnModGl0bGUgPSAiQ29lZmZpY2llbnRzIGRlIENyYW1lciBwb3VyIGNoYXF1ZSB2YXJpYWJsZSBlbiBmb25jdGlvbiBkZSBsJ0FWQyIsDQogICAgICAgeCA9ICJWYXJpYWJsZXMiLA0KICAgICAgIHkgPSAiQ3JhbcOpcidzIFYiKSArDQogIHRoZW1lX2J3KCkNCg0KDQpHR0NyYW0gJT4lIHBsb3RseTo6Z2dwbG90bHkoKQ0KYGBgDQoNCiMgVklJLiBCaWJsaW9ncmFwaGllDQo=