Créer des vecteurs

a <- 3+3 # créer un vecteur "a" qui est égale à 3+3
print(a) # afficher le vecteur
## [1] 6
b <- c(1, 5, 10)
c <- c(1:10)
d <- c("rouge", "bleu", "vert")
print(b)
## [1]  1  5 10
print(c)
##  [1]  1  2  3  4  5  6  7  8  9 10
print(d)
## [1] "rouge" "bleu"  "vert"
c <- as.data.frame(c) # convertir le vecteur en tableau
print(c)
##     c
## 1   1
## 2   2
## 3   3
## 4   4
## 5   5
## 6   6
## 7   7
## 8   8
## 9   9
## 10 10

Installer un package et charger sa bibliothèque de packages

installed.packages("dplyr") # télécharger un package
##      Package LibPath Version Priority Depends Imports LinkingTo Suggests
##      Enhances License License_is_FOSS License_restricts_use OS_type Archs
##      MD5sum NeedsCompilation Built
installed.packages("readxl") # télécharger un package
##      Package LibPath Version Priority Depends Imports LinkingTo Suggests
##      Enhances License License_is_FOSS License_restricts_use OS_type Archs
##      MD5sum NeedsCompilation Built
installed.packages("psych") # télécharger un package
##      Package LibPath Version Priority Depends Imports LinkingTo Suggests
##      Enhances License License_is_FOSS License_restricts_use OS_type Archs
##      MD5sum NeedsCompilation Built
library(dplyr) # "appeler" le package
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(psych) # "appeler" le package
library(readxl) # "appeler" le package
Les athlètes français pour les JO 2024 ont noté leurs patisseries préférées de 0 à 10. Ces notes seront utilisées par les nutritionnistes de l’équipe de France pour sélectionner les pâtisseries à réaliser pour la fin des JO, en fonction de la spécialité sportive et du sexe.

Localiser et définir son working directory

# working directory
setwd("/Users/layanfessler/Library/CloudStorage/OneDrive-UniversitéGrenobleAlpes/ENCADREMENT/STAGE D'EXCELLENCE/2024/Atelier R") # repporter l'emplacement lié au fichier que l'on veut importer
data <- read_excel("patisseries_JO_2024.xlsx") # Charger son jeu de données

Inspecter son jeu de données

# nom des variables
names(data)
## [1] "Code_participant"    "Specialite_sportive" "Sexe"               
## [4] "Age"                 "Tiramisu"            "Flan"               
## [7] "Moelleux"
# nombre de lignes et de colonnes 
nrow(data); ncol(data); dim(data)
## [1] 29
## [1] 7
## [1] 29  7
# Visualiser les données
View(data)
# Visualiser les premières colonnes 
head(data)
## # A tibble: 6 × 7
##   Code_participant Specialite_sportive Sexe    Age Tiramisu  Flan Moelleux
##              <dbl> <chr>               <chr> <dbl>    <dbl> <dbl>    <dbl>
## 1                1 Volleyball          Homme    19        6     6        6
## 2                2 Volleyball          Homme    19        7     4        6
## 3                3 Volleyball          Femme    18        5     3        7
## 4                4 Volleyball          Femme    18        5     2        7
## 5                5 Volleyball          Homme    20        5     3        5
## 6                6 Volleyball          Femme    24        6     3        6
# Type de variables
glimpse(data)
## Rows: 29
## Columns: 7
## $ Code_participant    <dbl> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,…
## $ Specialite_sportive <chr> "Volleyball", "Volleyball", "Volleyball", "Volleyb…
## $ Sexe                <chr> "Homme", "Homme", "Femme", "Femme", "Homme", "Femm…
## $ Age                 <dbl> 19, 19, 18, 18, 20, 24, 28, 23, 24, 24, 24, 23, 30…
## $ Tiramisu            <dbl> 6, 7, 5, 5, 5, 6, 2, 2, 4, 4, 4, 7, 5, 5, 5, 1, 1,…
## $ Flan                <dbl> 6, 4, 3, 2, 3, 3, 4, 2, 6, 5, 6, 7, 6, 7, 4, 2, 1,…
## $ Moelleux            <dbl> 6, 6, 7, 7, 5, 6, 6, 6, 6, 3, 5, 5, 6, 6, 7, 6, 2,…

Obtenir nos premiers indicateurs sur les variables

# Vérifier s'il y a des données manquantes
missing_rows <- apply(is.na(data), 1, any)

# Nombre de données manquantes
sum(missing_rows)
## [1] 1
# Localisation des données manquantes
print(data[missing_rows, ])
## # A tibble: 1 × 7
##   Code_participant Specialite_sportive Sexe    Age Tiramisu  Flan Moelleux
##              <dbl> <chr>               <chr> <dbl>    <dbl> <dbl>    <dbl>
## 1               25 Natation            Femme    21        1    NA        5
# résumé global
summary(data)
##  Code_participant Specialite_sportive     Sexe                Age       
##  Min.   : 1       Length:29           Length:29          Min.   :18.00  
##  1st Qu.: 8       Class :character    Class :character   1st Qu.:21.00  
##  Median :15       Mode  :character    Mode  :character   Median :24.00  
##  Mean   :15                                              Mean   :23.03  
##  3rd Qu.:22                                              3rd Qu.:24.00  
##  Max.   :29                                              Max.   :30.00  
##                                                                         
##     Tiramisu          Flan          Moelleux    
##  Min.   :1.000   Min.   :1.000   Min.   :2.000  
##  1st Qu.:4.000   1st Qu.:3.000   1st Qu.:5.000  
##  Median :5.000   Median :4.000   Median :6.000  
##  Mean   :4.724   Mean   :4.357   Mean   :5.345  
##  3rd Qu.:6.000   3rd Qu.:6.000   3rd Qu.:6.000  
##  Max.   :7.000   Max.   :7.000   Max.   :7.000  
##                  NA's   :1
summary(data)
##  Code_participant Specialite_sportive     Sexe                Age       
##  Min.   : 1       Length:29           Length:29          Min.   :18.00  
##  1st Qu.: 8       Class :character    Class :character   1st Qu.:21.00  
##  Median :15       Mode  :character    Mode  :character   Median :24.00  
##  Mean   :15                                              Mean   :23.03  
##  3rd Qu.:22                                              3rd Qu.:24.00  
##  Max.   :29                                              Max.   :30.00  
##                                                                         
##     Tiramisu          Flan          Moelleux    
##  Min.   :1.000   Min.   :1.000   Min.   :2.000  
##  1st Qu.:4.000   1st Qu.:3.000   1st Qu.:5.000  
##  Median :5.000   Median :4.000   Median :6.000  
##  Mean   :4.724   Mean   :4.357   Mean   :5.345  
##  3rd Qu.:6.000   3rd Qu.:6.000   3rd Qu.:6.000  
##  Max.   :7.000   Max.   :7.000   Max.   :7.000  
##                  NA's   :1
describe(data) # tout le jeu de données
##                      vars  n  mean   sd median trimmed   mad min max range
## Code_participant        1 29 15.00 8.51     15   15.00 10.38   1  29    28
## Specialite_sportive*    2 29  2.00 0.89      2    2.00  1.48   1   3     2
## Sexe*                   3 29  1.55 0.51      2    1.56  0.00   1   2     1
## Age                     4 29 23.03 3.06     24   22.96  2.97  18  30    12
## Tiramisu                5 29  4.72 1.85      5    4.84  1.48   1   7     6
## Flan                    6 28  4.36 1.81      4    4.38  2.97   1   7     6
## Moelleux                7 29  5.34 1.29      6    5.44  1.48   2   7     5
##                       skew kurtosis   se
## Code_participant      0.00    -1.32 1.58
## Specialite_sportive*  0.00    -1.77 0.16
## Sexe*                -0.20    -2.03 0.09
## Age                   0.15    -0.69 0.57
## Tiramisu             -0.75    -0.57 0.34
## Flan                 -0.12    -1.35 0.34
## Moelleux             -0.83    -0.12 0.24
describe(data$Flan) # Une seule variable
##    vars  n mean   sd median trimmed  mad min max range  skew kurtosis   se
## X1    1 28 4.36 1.81      4    4.38 2.97   1   7     6 -0.12    -1.35 0.34
table(data$Specialite_sportive) # variable non numérique
## 
## Athletisme   Natation Volleyball 
##         11          7         11

Obtenir des indicateurs par groupe

describeBy(data$Flan, data$Specialite_sportive)
## 
##  Descriptive statistics by group 
## group: Athletisme
##    vars  n mean   sd median trimmed  mad min max range skew kurtosis  se
## X1    1 11 4.82 1.99      6       5 1.48   1   7     6 -0.6    -1.09 0.6
## ------------------------------------------------------------ 
## group: Natation
##    vars n mean   sd median trimmed  mad min max range skew kurtosis   se
## X1    1 6 4.17 2.04      4    4.17 2.97   2   7     5 0.17    -1.85 0.83
## ------------------------------------------------------------ 
## group: Volleyball
##    vars  n mean   sd median trimmed  mad min max range skew kurtosis   se
## X1    1 11    4 1.55      4       4 1.48   2   6     4 0.15    -1.67 0.47
data %>%
  group_by(Specialite_sportive, Sexe) %>%
  summarise(mean = mean(Flan, na.rm = TRUE), sd = sd(Flan, na.rm = TRUE))
## `summarise()` has grouped output by 'Specialite_sportive'. You can override
## using the `.groups` argument.
## # A tibble: 6 × 4
## # Groups:   Specialite_sportive [3]
##   Specialite_sportive Sexe   mean    sd
##   <chr>               <chr> <dbl> <dbl>
## 1 Athletisme          Femme  4.67  3.21
## 2 Athletisme          Homme  4.88  1.64
## 3 Natation            Femme  3.67  2.89
## 4 Natation            Homme  4.67  1.15
## 5 Volleyball          Femme  3.83  1.47
## 6 Volleyball          Homme  4.2   1.79
Les athlètes français pour les JO 2024 ont noté leurs patisseries préférées de 0 à 10. Ces notes seront utilisées par les nutritionnistes de l’équipe de France pour sélectionner les pâtisseries à réaliser pour la fin des JO, en fonction de la spécialité sportive et du sexe.
# Intégrer toutes les pâtisseries
data %>%
  group_by(Specialite_sportive, Sexe) %>%
  summarise(
    mean_Flan = mean(Flan, na.rm = TRUE),
    sd_Flan = sd(Flan, na.rm = TRUE),
    mean_Tiramisu = mean(Tiramisu, na.rm = TRUE),
    sd_Tiramisu = sd(Tiramisu, na.rm = TRUE),
    mean_Moelleux = mean(Moelleux, na.rm = TRUE),
    sd_Moelleux = sd(Moelleux, na.rm = TRUE)
  )
## `summarise()` has grouped output by 'Specialite_sportive'. You can override
## using the `.groups` argument.
## # A tibble: 6 × 8
## # Groups:   Specialite_sportive [3]
##   Specialite_sportive Sexe  mean_Flan sd_Flan mean_Tiramisu sd_Tiramisu
##   <chr>               <chr>     <dbl>   <dbl>         <dbl>       <dbl>
## 1 Athletisme          Femme      4.67    3.21          3.67        2.31
## 2 Athletisme          Homme      4.88    1.64          5.12        1.96
## 3 Natation            Femme      3.67    2.89          4.25        2.75
## 4 Natation            Homme      4.67    1.15          6           0   
## 5 Volleyball          Femme      3.83    1.47          4.33        1.37
## 6 Volleyball          Homme      4.2     1.79          4.8         1.92
## # ℹ 2 more variables: mean_Moelleux <dbl>, sd_Moelleux <dbl>

Trier des données à partir d’une variable “catégorielle”

Athletisme <- subset(data, Specialite_sportive == "Athletisme")
print(Athletisme)
## # A tibble: 11 × 7
##    Code_participant Specialite_sportive Sexe    Age Tiramisu  Flan Moelleux
##               <dbl> <chr>               <chr> <dbl>    <dbl> <dbl>    <dbl>
##  1               12 Athletisme          Homme    23        7     7        5
##  2               13 Athletisme          Femme    30        5     6        6
##  3               14 Athletisme          Femme    19        5     7        6
##  4               15 Athletisme          Homme    20        5     4        7
##  5               16 Athletisme          Homme    26        1     2        6
##  6               17 Athletisme          Femme    25        1     1        2
##  7               18 Athletisme          Homme    27        7     6        6
##  8               19 Athletisme          Homme    21        6     6        4
##  9               20 Athletisme          Homme    24        5     4        3
## 10               21 Athletisme          Homme    22        4     4        4
## 11               22 Athletisme          Homme    22        6     6        4

Trier des données à partir d’une variable “numérique”

scores_hauts_tiramisu <- subset(data, Tiramisu > 5)
print(scores_hauts_tiramisu)
## # A tibble: 12 × 7
##    Code_participant Specialite_sportive Sexe    Age Tiramisu  Flan Moelleux
##               <dbl> <chr>               <chr> <dbl>    <dbl> <dbl>    <dbl>
##  1                1 Volleyball          Homme    19        6     6        6
##  2                2 Volleyball          Homme    19        7     4        6
##  3                6 Volleyball          Femme    24        6     3        6
##  4               12 Athletisme          Homme    23        7     7        5
##  5               18 Athletisme          Homme    27        7     6        6
##  6               19 Athletisme          Homme    21        6     6        4
##  7               22 Athletisme          Homme    22        6     6        4
##  8               24 Natation            Femme    24        7     7        6
##  9               26 Natation            Femme    27        6     2        4
## 10               27 Natation            Homme    22        6     4        7
## 11               28 Natation            Homme    24        6     6        5
## 12               29 Natation            Homme    26        6     4        6

Pour les athlètes de ≤ 24 ans

age_inf24 <- subset(data, Age <= 24, )
print(age_inf24)
## # A tibble: 22 × 7
##    Code_participant Specialite_sportive Sexe    Age Tiramisu  Flan Moelleux
##               <dbl> <chr>               <chr> <dbl>    <dbl> <dbl>    <dbl>
##  1                1 Volleyball          Homme    19        6     6        6
##  2                2 Volleyball          Homme    19        7     4        6
##  3                3 Volleyball          Femme    18        5     3        7
##  4                4 Volleyball          Femme    18        5     2        7
##  5                5 Volleyball          Homme    20        5     3        5
##  6                6 Volleyball          Femme    24        6     3        6
##  7                8 Volleyball          Homme    23        2     2        6
##  8                9 Volleyball          Femme    24        4     6        6
##  9               10 Volleyball          Femme    24        4     5        3
## 10               11 Volleyball          Homme    24        4     6        5
## # ℹ 12 more rows

Ne garder uniquement les données non manquantes

age_inf24 <- na.omit(age_inf24)
age_inf24 %>%
  group_by(Specialite_sportive, Sexe) %>%
  summarise(
    mean_Flan = mean(Flan, na.rm = TRUE),
    sd_Flan = sd(Flan, na.rm = TRUE),
    mean_Tiramisu = mean(Tiramisu, na.rm = TRUE),
    sd_Tiramisu = sd(Tiramisu, na.rm = TRUE),
    mean_Moelleux = mean(Moelleux, na.rm = TRUE),
    sd_Moelleux = sd(Moelleux, na.rm = TRUE)
  )
## `summarise()` has grouped output by 'Specialite_sportive'. You can override
## using the `.groups` argument.
## # A tibble: 6 × 8
## # Groups:   Specialite_sportive [3]
##   Specialite_sportive Sexe  mean_Flan sd_Flan mean_Tiramisu sd_Tiramisu
##   <chr>               <chr>     <dbl>   <dbl>         <dbl>       <dbl>
## 1 Athletisme          Femme      7      NA              5        NA    
## 2 Athletisme          Homme      5.17    1.33           5.5       1.05 
## 3 Natation            Femme      4.5     3.54           5         2.83 
## 4 Natation            Homme      5       1.41           6         0    
## 5 Volleyball          Femme      3.8     1.64           4.8       0.837
## 6 Volleyball          Homme      4.2     1.79           4.8       1.92 
## # ℹ 2 more variables: mean_Moelleux <dbl>, sd_Moelleux <dbl>

Pour les athlètes de > 24 ans

age_sup24 <- subset(data, Age > 24, )
print(age_sup24)
## # A tibble: 7 × 7
##   Code_participant Specialite_sportive Sexe    Age Tiramisu  Flan Moelleux
##              <dbl> <chr>               <chr> <dbl>    <dbl> <dbl>    <dbl>
## 1                7 Volleyball          Femme    28        2     4        6
## 2               13 Athletisme          Femme    30        5     6        6
## 3               16 Athletisme          Homme    26        1     2        6
## 4               17 Athletisme          Femme    25        1     1        2
## 5               18 Athletisme          Homme    27        7     6        6
## 6               26 Natation            Femme    27        6     2        4
## 7               29 Natation            Homme    26        6     4        6

Ne garder uniquement les données non manquantes

age_sup24 <- na.omit(age_sup24)
age_sup24 %>%
  group_by(Specialite_sportive, Sexe) %>%
  summarise(
    mean_Flan = mean(Flan, na.rm = TRUE),
    sd_Flan = sd(Flan, na.rm = TRUE),
    mean_Tiramisu = mean(Tiramisu, na.rm = TRUE),
    sd_Tiramisu = sd(Tiramisu, na.rm = TRUE),
    mean_Moelleux = mean(Moelleux, na.rm = TRUE),
    sd_Moelleux = sd(Moelleux, na.rm = TRUE)
  )
## `summarise()` has grouped output by 'Specialite_sportive'. You can override
## using the `.groups` argument.
## # A tibble: 5 × 8
## # Groups:   Specialite_sportive [3]
##   Specialite_sportive Sexe  mean_Flan sd_Flan mean_Tiramisu sd_Tiramisu
##   <chr>               <chr>     <dbl>   <dbl>         <dbl>       <dbl>
## 1 Athletisme          Femme       3.5    3.54             3        2.83
## 2 Athletisme          Homme       4      2.83             4        4.24
## 3 Natation            Femme       2     NA                6       NA   
## 4 Natation            Homme       4     NA                6       NA   
## 5 Volleyball          Femme       4     NA                2       NA   
## # ℹ 2 more variables: mean_Moelleux <dbl>, sd_Moelleux <dbl>

Visualisation graphique

# Charger les packages nécessaires (installer si besoin)
#installed.packages("")
library(ggdist)
library(ggplot2)
## 
## Attaching package: 'ggplot2'
## The following objects are masked from 'package:psych':
## 
##     %+%, alpha
library(PupillometryR)
## Loading required package: rlang
## 
## Attaching package: 'rlang'
## The following object is masked from 'package:ggdist':
## 
##     ll
library(reshape2)


# Calculer les statistiques descriptives
summary_stats <- data %>%
  group_by(Specialite_sportive, Sexe) %>%
  summarise(
    mean_Flan = mean(Flan, na.rm = TRUE),
    sd_Flan = sd(Flan, na.rm = TRUE),
    mean_Tiramisu = mean(Tiramisu, na.rm = TRUE),
    sd_Tiramisu = sd(Tiramisu, na.rm = TRUE),
    mean_Moelleux = mean(Moelleux, na.rm = TRUE),
    sd_Moelleux = sd(Moelleux, na.rm = TRUE),
    .groups = "drop"  # Permet de supprimer l'avertissement en spécifiant .groups
  ) %>%
  na.omit()  # Exclure les lignes avec des NA

# Reformater les données pour le graphique (melt pour ggplot2)
summary_stats_melted <- melt(summary_stats, id.vars = c("Specialite_sportive", "Sexe"),
                            measure.vars = c("mean_Flan", "mean_Tiramisu", "mean_Moelleux"),
                            variable.name = "Patisserie", value.name = "Moyenne")

# Ajouter les écarts-types à summary_stats_melted
summary_stats_melted <- summary_stats_melted %>%
  mutate(
    sd = ifelse(Patisserie == "mean_Flan", summary_stats$sd_Flan,
                ifelse(Patisserie == "mean_Tiramisu", summary_stats$sd_Tiramisu,
                       summary_stats$sd_Moelleux))
  )

# Créer le graphique : Barres d'erreur des moyennes avec ggplot2
ggplot(summary_stats_melted, aes(x = Specialite_sportive, y = Moyenne, fill = Sexe)) +
  geom_bar(stat = "identity", position = "dodge") +
  facet_wrap(~ Patisserie, scales = "free_y", nrow = 1) +
  geom_errorbar(aes(ymin = Moyenne - sd, ymax = Moyenne + sd), width = 0.2, position = position_dodge(width = 0.9)) +
  labs(title = "Moyenne et écart-type des notes des pâtisseries par spécialité sportive et sexe",
       x = "Spécialité sportive", y = "Moyenne") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  scale_fill_manual(values = c("Femme" = "#00AFBB", "Homme" = "#E7B800"))  # Couleurs par sexe (F et H)

Graphique de densité

library(ggpubr)
ggscatterhist(
  data, x = "Moelleux", y = "Tiramisu",
  color = "Specialite_sportive", size = 3, alpha = 0.6,
  palette = c("#00AFBB", "#E7B800", "#FC4E07"),
  margin.params = list(fill = "Specialite_sportive", color = "black", size = 0.2)
)

LS0tCnRpdGxlOiAiSW5pdGlhdGlvbiDDoCBSIFN0dWRpbyIKYXV0aG9yOiAiTGF5YW4gRmVzc2xlciBldCBTaWx2aW8gTWFsdGFnbGlhdGkiCmRhdGU6ICIyMDI0LTA3LTA0IgpvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDoKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUgIyBwb3VyIHBvdXZvaXIgdMOpbMOpY2hhcmdlciBsZSBzY3JpcHQgUiBkZXB1aXMgbGUgZmljaGllciAuaHRtbAogICAgdG9jOiB0cnVlICMgYWpvdXRlciB1biBzb21tYWlyZQogICAgdG9jX2Zsb2F0OiB0cnVlICMgcmVuZHJlIGxlIHNvbW1haXJlIGZsb3R0YW50CiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUgIyBjYWNoZXIgbGUgY29kZSAKICAgIGVkaXRvcl9vcHRpb25zOiBudWxsCiAgbWFya2Rvd246CiAgICB3cmFwOiBzZW50ZW5jZQogIHdvcmRfZG9jdW1lbnQ6CiAgICB0b2M6IHRydWUKLS0tCiMgQ3LDqWVyIGRlcyB2ZWN0ZXVycwpgYGB7cn0KYSA8LSAzKzMgIyBjcsOpZXIgdW4gdmVjdGV1ciAiYSIgcXVpIGVzdCDDqWdhbGUgw6AgMyszCnByaW50KGEpICMgYWZmaWNoZXIgbGUgdmVjdGV1cgpgYGAKCmBgYHtyfQpiIDwtIGMoMSwgNSwgMTApCmMgPC0gYygxOjEwKQpkIDwtIGMoInJvdWdlIiwgImJsZXUiLCAidmVydCIpCnByaW50KGIpCnByaW50KGMpCnByaW50KGQpCmBgYAoKYGBge3J9CmMgPC0gYXMuZGF0YS5mcmFtZShjKSAjIGNvbnZlcnRpciBsZSB2ZWN0ZXVyIGVuIHRhYmxlYXUKcHJpbnQoYykKYGBgCgojIEluc3RhbGxlciB1biBwYWNrYWdlIGV0IGNoYXJnZXIgc2EgYmlibGlvdGjDqHF1ZSBkZSBwYWNrYWdlcwpgYGB7cn0KaW5zdGFsbGVkLnBhY2thZ2VzKCJkcGx5ciIpICMgdMOpbMOpY2hhcmdlciB1biBwYWNrYWdlCmluc3RhbGxlZC5wYWNrYWdlcygicmVhZHhsIikgIyB0w6lsw6ljaGFyZ2VyIHVuIHBhY2thZ2UKaW5zdGFsbGVkLnBhY2thZ2VzKCJwc3ljaCIpICMgdMOpbMOpY2hhcmdlciB1biBwYWNrYWdlCgpsaWJyYXJ5KGRwbHlyKSAjICJhcHBlbGVyIiBsZSBwYWNrYWdlCmxpYnJhcnkocHN5Y2gpICMgImFwcGVsZXIiIGxlIHBhY2thZ2UKbGlicmFyeShyZWFkeGwpICMgImFwcGVsZXIiIGxlIHBhY2thZ2UKYGBgCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KTGVzIGF0aGzDqHRlcyBmcmFuw6dhaXMgcG91ciBsZXMgSk8gMjAyNCBvbnQgbm90w6kgbGV1cnMgcGF0aXNzZXJpZXMgcHLDqWbDqXLDqWVzIGRlIDAgw6AgMTAuIENlcyBub3RlcyBzZXJvbnQgdXRpbGlzw6llcyBwYXIgbGVzIG51dHJpdGlvbm5pc3RlcyBkZSBsJ8OpcXVpcGUgZGUgRnJhbmNlIHBvdXIgc8OpbGVjdGlvbm5lciBsZXMgcMOidGlzc2VyaWVzIMOgIHLDqWFsaXNlciBwb3VyIGxhIGZpbiBkZXMgSk8sIGVuIGZvbmN0aW9uIGRlIGxhIHNww6ljaWFsaXTDqSBzcG9ydGl2ZSBldCBkdSBzZXhlLgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMgTG9jYWxpc2VyIGV0IGTDqWZpbmlyIHNvbiB3b3JraW5nIGRpcmVjdG9yeQpgYGB7cn0KIyB3b3JraW5nIGRpcmVjdG9yeQpzZXR3ZCgiL1VzZXJzL2xheWFuZmVzc2xlci9MaWJyYXJ5L0Nsb3VkU3RvcmFnZS9PbmVEcml2ZS1Vbml2ZXJzaXRlzIFHcmVub2JsZUFscGVzL0VOQ0FEUkVNRU5UL1NUQUdFIEQnRVhDRUxMRU5DRS8yMDI0L0F0ZWxpZXIgUiIpICMgcmVwcG9ydGVyIGwnZW1wbGFjZW1lbnQgbGnDqSBhdSBmaWNoaWVyIHF1ZSBsJ29uIHZldXQgaW1wb3J0ZXIKZGF0YSA8LSByZWFkX2V4Y2VsKCJwYXRpc3Nlcmllc19KT18yMDI0Lnhsc3giKSAjIENoYXJnZXIgc29uIGpldSBkZSBkb25uw6llcwpgYGAKCiMgSW5zcGVjdGVyIHNvbiBqZXUgZGUgZG9ubsOpZXMKYGBge3J9CiMgbm9tIGRlcyB2YXJpYWJsZXMKbmFtZXMoZGF0YSkKYGBgCgpgYGB7cn0KIyBub21icmUgZGUgbGlnbmVzIGV0IGRlIGNvbG9ubmVzIApucm93KGRhdGEpOyBuY29sKGRhdGEpOyBkaW0oZGF0YSkKYGBgCgpgYGB7cn0KIyBWaXN1YWxpc2VyIGxlcyBkb25uw6llcwpWaWV3KGRhdGEpCmBgYAoKYGBge3J9CiMgVmlzdWFsaXNlciBsZXMgcHJlbWnDqHJlcyBjb2xvbm5lcyAKaGVhZChkYXRhKQpgYGAKCmBgYHtyfQojIFR5cGUgZGUgdmFyaWFibGVzCmdsaW1wc2UoZGF0YSkKYGBgCgojIE9idGVuaXIgbm9zIHByZW1pZXJzIGluZGljYXRldXJzIHN1ciBsZXMgdmFyaWFibGVzCmBgYHtyfQojIFbDqXJpZmllciBzJ2lsIHkgYSBkZXMgZG9ubsOpZXMgbWFucXVhbnRlcwptaXNzaW5nX3Jvd3MgPC0gYXBwbHkoaXMubmEoZGF0YSksIDEsIGFueSkKCiMgTm9tYnJlIGRlIGRvbm7DqWVzIG1hbnF1YW50ZXMKc3VtKG1pc3Npbmdfcm93cykKCiMgTG9jYWxpc2F0aW9uIGRlcyBkb25uw6llcyBtYW5xdWFudGVzCnByaW50KGRhdGFbbWlzc2luZ19yb3dzLCBdKQpgYGAKCmBgYHtyfQojIHLDqXN1bcOpIGdsb2JhbApzdW1tYXJ5KGRhdGEpCmBgYAoKYGBge3J9CnN1bW1hcnkoZGF0YSkKYGBgCgpgYGB7cn0KZGVzY3JpYmUoZGF0YSkgIyB0b3V0IGxlIGpldSBkZSBkb25uw6llcwpkZXNjcmliZShkYXRhJEZsYW4pICMgVW5lIHNldWxlIHZhcmlhYmxlCmBgYAoKYGBge3J9CnRhYmxlKGRhdGEkU3BlY2lhbGl0ZV9zcG9ydGl2ZSkgIyB2YXJpYWJsZSBub24gbnVtw6lyaXF1ZQpgYGAKCiMgT2J0ZW5pciBkZXMgaW5kaWNhdGV1cnMgcGFyIGdyb3VwZQpgYGB7cn0KZGVzY3JpYmVCeShkYXRhJEZsYW4sIGRhdGEkU3BlY2lhbGl0ZV9zcG9ydGl2ZSkKYGBgCgpgYGB7cn0KZGF0YSAlPiUKICBncm91cF9ieShTcGVjaWFsaXRlX3Nwb3J0aXZlLCBTZXhlKSAlPiUKICBzdW1tYXJpc2UobWVhbiA9IG1lYW4oRmxhbiwgbmEucm0gPSBUUlVFKSwgc2QgPSBzZChGbGFuLCBuYS5ybSA9IFRSVUUpKQpgYGAKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpMZXMgYXRobMOodGVzIGZyYW7Dp2FpcyBwb3VyIGxlcyBKTyAyMDI0IG9udCBub3TDqSBsZXVycyBwYXRpc3NlcmllcyBwcsOpZsOpcsOpZXMgZGUgMCDDoCAxMC4gQ2VzIG5vdGVzIHNlcm9udCB1dGlsaXPDqWVzIHBhciBsZXMgbnV0cml0aW9ubmlzdGVzIGRlIGwnw6lxdWlwZSBkZSBGcmFuY2UgcG91ciBzw6lsZWN0aW9ubmVyIGxlcyBww6J0aXNzZXJpZXMgw6AgcsOpYWxpc2VyIHBvdXIgbGEgZmluIGRlcyBKTywgZW4gZm9uY3Rpb24gZGUgbGEgc3DDqWNpYWxpdMOpIHNwb3J0aXZlIGV0IGR1IHNleGUuCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKYGBge3J9CiMgSW50w6lncmVyIHRvdXRlcyBsZXMgcMOidGlzc2VyaWVzCmRhdGEgJT4lCiAgZ3JvdXBfYnkoU3BlY2lhbGl0ZV9zcG9ydGl2ZSwgU2V4ZSkgJT4lCiAgc3VtbWFyaXNlKAogICAgbWVhbl9GbGFuID0gbWVhbihGbGFuLCBuYS5ybSA9IFRSVUUpLAogICAgc2RfRmxhbiA9IHNkKEZsYW4sIG5hLnJtID0gVFJVRSksCiAgICBtZWFuX1RpcmFtaXN1ID0gbWVhbihUaXJhbWlzdSwgbmEucm0gPSBUUlVFKSwKICAgIHNkX1RpcmFtaXN1ID0gc2QoVGlyYW1pc3UsIG5hLnJtID0gVFJVRSksCiAgICBtZWFuX01vZWxsZXV4ID0gbWVhbihNb2VsbGV1eCwgbmEucm0gPSBUUlVFKSwKICAgIHNkX01vZWxsZXV4ID0gc2QoTW9lbGxldXgsIG5hLnJtID0gVFJVRSkKICApCgpgYGAKCiMgVHJpZXIgZGVzIGRvbm7DqWVzIMOgIHBhcnRpciBk4oCZdW5lIHZhcmlhYmxlICJjYXTDqWdvcmllbGxlIgpgYGB7cn0KQXRobGV0aXNtZSA8LSBzdWJzZXQoZGF0YSwgU3BlY2lhbGl0ZV9zcG9ydGl2ZSA9PSAiQXRobGV0aXNtZSIpCnByaW50KEF0aGxldGlzbWUpCmBgYAoKIyBUcmllciBkZXMgZG9ubsOpZXMgw6AgcGFydGlyIGTigJl1bmUgdmFyaWFibGUgIm51bcOpcmlxdWUiCmBgYHtyfQpzY29yZXNfaGF1dHNfdGlyYW1pc3UgPC0gc3Vic2V0KGRhdGEsIFRpcmFtaXN1ID4gNSkKcHJpbnQoc2NvcmVzX2hhdXRzX3RpcmFtaXN1KQpgYGAKIyBQb3VyIGxlcyBhdGhsw6h0ZXMgZGUg4omkIDI0IGFucwpgYGB7cn0KYWdlX2luZjI0IDwtIHN1YnNldChkYXRhLCBBZ2UgPD0gMjQsICkKcHJpbnQoYWdlX2luZjI0KQpgYGAKCiMgTmUgZ2FyZGVyIHVuaXF1ZW1lbnQgbGVzIGRvbm7DqWVzIG5vbiBtYW5xdWFudGVzCmBgYHtyfQphZ2VfaW5mMjQgPC0gbmEub21pdChhZ2VfaW5mMjQpCmBgYAoKCmBgYHtyfQphZ2VfaW5mMjQgJT4lCiAgZ3JvdXBfYnkoU3BlY2lhbGl0ZV9zcG9ydGl2ZSwgU2V4ZSkgJT4lCiAgc3VtbWFyaXNlKAogICAgbWVhbl9GbGFuID0gbWVhbihGbGFuLCBuYS5ybSA9IFRSVUUpLAogICAgc2RfRmxhbiA9IHNkKEZsYW4sIG5hLnJtID0gVFJVRSksCiAgICBtZWFuX1RpcmFtaXN1ID0gbWVhbihUaXJhbWlzdSwgbmEucm0gPSBUUlVFKSwKICAgIHNkX1RpcmFtaXN1ID0gc2QoVGlyYW1pc3UsIG5hLnJtID0gVFJVRSksCiAgICBtZWFuX01vZWxsZXV4ID0gbWVhbihNb2VsbGV1eCwgbmEucm0gPSBUUlVFKSwKICAgIHNkX01vZWxsZXV4ID0gc2QoTW9lbGxldXgsIG5hLnJtID0gVFJVRSkKICApCgpgYGAKCiMgUG91ciBsZXMgYXRobMOodGVzIGRlID4gMjQgYW5zCmBgYHtyfQphZ2Vfc3VwMjQgPC0gc3Vic2V0KGRhdGEsIEFnZSA+IDI0LCApCnByaW50KGFnZV9zdXAyNCkKYGBgCiMgTmUgZ2FyZGVyIHVuaXF1ZW1lbnQgbGVzIGRvbm7DqWVzIG5vbiBtYW5xdWFudGVzCmBgYHtyfQphZ2Vfc3VwMjQgPC0gbmEub21pdChhZ2Vfc3VwMjQpCmBgYAoKYGBge3J9CmFnZV9zdXAyNCAlPiUKICBncm91cF9ieShTcGVjaWFsaXRlX3Nwb3J0aXZlLCBTZXhlKSAlPiUKICBzdW1tYXJpc2UoCiAgICBtZWFuX0ZsYW4gPSBtZWFuKEZsYW4sIG5hLnJtID0gVFJVRSksCiAgICBzZF9GbGFuID0gc2QoRmxhbiwgbmEucm0gPSBUUlVFKSwKICAgIG1lYW5fVGlyYW1pc3UgPSBtZWFuKFRpcmFtaXN1LCBuYS5ybSA9IFRSVUUpLAogICAgc2RfVGlyYW1pc3UgPSBzZChUaXJhbWlzdSwgbmEucm0gPSBUUlVFKSwKICAgIG1lYW5fTW9lbGxldXggPSBtZWFuKE1vZWxsZXV4LCBuYS5ybSA9IFRSVUUpLAogICAgc2RfTW9lbGxldXggPSBzZChNb2VsbGV1eCwgbmEucm0gPSBUUlVFKQogICkKCmBgYAoKIyBWaXN1YWxpc2F0aW9uIGdyYXBoaXF1ZQpgYGB7cn0KIyBDaGFyZ2VyIGxlcyBwYWNrYWdlcyBuw6ljZXNzYWlyZXMgKGluc3RhbGxlciBzaSBiZXNvaW4pCiNpbnN0YWxsZWQucGFja2FnZXMoIiIpCmxpYnJhcnkoZ2dkaXN0KQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoUHVwaWxsb21ldHJ5UikKbGlicmFyeShyZXNoYXBlMikKCgojIENhbGN1bGVyIGxlcyBzdGF0aXN0aXF1ZXMgZGVzY3JpcHRpdmVzCnN1bW1hcnlfc3RhdHMgPC0gZGF0YSAlPiUKICBncm91cF9ieShTcGVjaWFsaXRlX3Nwb3J0aXZlLCBTZXhlKSAlPiUKICBzdW1tYXJpc2UoCiAgICBtZWFuX0ZsYW4gPSBtZWFuKEZsYW4sIG5hLnJtID0gVFJVRSksCiAgICBzZF9GbGFuID0gc2QoRmxhbiwgbmEucm0gPSBUUlVFKSwKICAgIG1lYW5fVGlyYW1pc3UgPSBtZWFuKFRpcmFtaXN1LCBuYS5ybSA9IFRSVUUpLAogICAgc2RfVGlyYW1pc3UgPSBzZChUaXJhbWlzdSwgbmEucm0gPSBUUlVFKSwKICAgIG1lYW5fTW9lbGxldXggPSBtZWFuKE1vZWxsZXV4LCBuYS5ybSA9IFRSVUUpLAogICAgc2RfTW9lbGxldXggPSBzZChNb2VsbGV1eCwgbmEucm0gPSBUUlVFKSwKICAgIC5ncm91cHMgPSAiZHJvcCIgICMgUGVybWV0IGRlIHN1cHByaW1lciBsJ2F2ZXJ0aXNzZW1lbnQgZW4gc3DDqWNpZmlhbnQgLmdyb3VwcwogICkgJT4lCiAgbmEub21pdCgpICAjIEV4Y2x1cmUgbGVzIGxpZ25lcyBhdmVjIGRlcyBOQQoKIyBSZWZvcm1hdGVyIGxlcyBkb25uw6llcyBwb3VyIGxlIGdyYXBoaXF1ZSAobWVsdCBwb3VyIGdncGxvdDIpCnN1bW1hcnlfc3RhdHNfbWVsdGVkIDwtIG1lbHQoc3VtbWFyeV9zdGF0cywgaWQudmFycyA9IGMoIlNwZWNpYWxpdGVfc3BvcnRpdmUiLCAiU2V4ZSIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVhc3VyZS52YXJzID0gYygibWVhbl9GbGFuIiwgIm1lYW5fVGlyYW1pc3UiLCAibWVhbl9Nb2VsbGV1eCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyaWFibGUubmFtZSA9ICJQYXRpc3NlcmllIiwgdmFsdWUubmFtZSA9ICJNb3llbm5lIikKCiMgQWpvdXRlciBsZXMgw6ljYXJ0cy10eXBlcyDDoCBzdW1tYXJ5X3N0YXRzX21lbHRlZApzdW1tYXJ5X3N0YXRzX21lbHRlZCA8LSBzdW1tYXJ5X3N0YXRzX21lbHRlZCAlPiUKICBtdXRhdGUoCiAgICBzZCA9IGlmZWxzZShQYXRpc3NlcmllID09ICJtZWFuX0ZsYW4iLCBzdW1tYXJ5X3N0YXRzJHNkX0ZsYW4sCiAgICAgICAgICAgICAgICBpZmVsc2UoUGF0aXNzZXJpZSA9PSAibWVhbl9UaXJhbWlzdSIsIHN1bW1hcnlfc3RhdHMkc2RfVGlyYW1pc3UsCiAgICAgICAgICAgICAgICAgICAgICAgc3VtbWFyeV9zdGF0cyRzZF9Nb2VsbGV1eCkpCiAgKQoKIyBDcsOpZXIgbGUgZ3JhcGhpcXVlIDogQmFycmVzIGQnZXJyZXVyIGRlcyBtb3llbm5lcyBhdmVjIGdncGxvdDIKZ2dwbG90KHN1bW1hcnlfc3RhdHNfbWVsdGVkLCBhZXMoeCA9IFNwZWNpYWxpdGVfc3BvcnRpdmUsIHkgPSBNb3llbm5lLCBmaWxsID0gU2V4ZSkpICsKICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSAiZG9kZ2UiKSArCiAgZmFjZXRfd3JhcCh+IFBhdGlzc2VyaWUsIHNjYWxlcyA9ICJmcmVlX3kiLCBucm93ID0gMSkgKwogIGdlb21fZXJyb3JiYXIoYWVzKHltaW4gPSBNb3llbm5lIC0gc2QsIHltYXggPSBNb3llbm5lICsgc2QpLCB3aWR0aCA9IDAuMiwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDAuOSkpICsKICBsYWJzKHRpdGxlID0gIk1veWVubmUgZXQgw6ljYXJ0LXR5cGUgZGVzIG5vdGVzIGRlcyBww6J0aXNzZXJpZXMgcGFyIHNww6ljaWFsaXTDqSBzcG9ydGl2ZSBldCBzZXhlIiwKICAgICAgIHggPSAiU3DDqWNpYWxpdMOpIHNwb3J0aXZlIiwgeSA9ICJNb3llbm5lIikgKwogIHRoZW1lX21pbmltYWwoKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIkZlbW1lIiA9ICIjMDBBRkJCIiwgIkhvbW1lIiA9ICIjRTdCODAwIikpICAjIENvdWxldXJzIHBhciBzZXhlIChGIGV0IEgpCmBgYAoKIyBHcmFwaGlxdWUgZGUgZGVuc2l0w6kKYGBge3J9CmxpYnJhcnkoZ2dwdWJyKQpnZ3NjYXR0ZXJoaXN0KAogIGRhdGEsIHggPSAiTW9lbGxldXgiLCB5ID0gIlRpcmFtaXN1IiwKICBjb2xvciA9ICJTcGVjaWFsaXRlX3Nwb3J0aXZlIiwgc2l6ZSA9IDMsIGFscGhhID0gMC42LAogIHBhbGV0dGUgPSBjKCIjMDBBRkJCIiwgIiNFN0I4MDAiLCAiI0ZDNEUwNyIpLAogIG1hcmdpbi5wYXJhbXMgPSBsaXN0KGZpbGwgPSAiU3BlY2lhbGl0ZV9zcG9ydGl2ZSIsIGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDAuMikKKQpgYGAKCgo=