1. Introducción

El trabajo actual ha sido realizado con fines de estudio, para poder ver el impacto que tienen los outliers sobre la media, mediana y moda.

2. Objetivos

3. Configuración

Instalamos los paquetes y cargamos las librerías necesarias.

# Install necessary packages and libraries

#install.packages("tidyverse")
#install.packages("ggplot2")
#install.packages("dplyr")
library(readr)
library(dplyr)
library(ggplot2)

4. Creación del data frame

# Read raw
mark <- c(6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 
             16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 
             27, 28, 30, 31, 32, 36, 37, 38, 40, 41, 
             42, 44, 46, 50, 51, 52, 53, 54)
freqs <- c(5, 3, 3, 4, 2, 4, 3, 4, 2, 1, 
                 3, 5, 4, 4, 5, 2, 2, 2, 6, 1, 
                 2, 2, 1, 3, 1, 1, 2, 2, 4, 3, 
                 2, 2, 1, 1, 3, 1, 3, 1)
mark <- rep(mark, freqs)

df <- data.frame(
  student = as.character(seq(1, 100)),
  mark = mark
)

5. Exploración inicial (EDA básico)

# First six lines of the df
head(df)
# Internal structure of the df
glimpse(df)
Rows: 100
Columns: 2
$ student <chr> "1", "2", "3", "4", "5", "6", "7", "8…
$ mark    <dbl> 6, 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9…
# Statistical summary
summary(df)
   student               mark      
 Length:100         Min.   : 6.00  
 Class :character   1st Qu.:13.00  
 Mode  :character   Median :20.00  
                    Mean   :24.08  
                    3rd Qu.:36.25  
                    Max.   :54.00  
# Test for NAs

anyNA(df)
[1] FALSE
sum(is.na(df))
[1] 0
# Freq by obs
table(df$mark)

 6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 
 5  3  3  4  2  4  3  4  2  1  3  5  4  4  5  2  2  2 
24 25 27 28 30 31 32 36 37 38 40 41 42 44 46 50 51 52 
 6  1  2  2  1  3  1  1  2  2  4  3  2  2  1  1  3  1 
53 54 
 3  1 
# Looking for outliers
boxplot(df$mark)

# How's the data
hist(df$mark)

# How's the data
plot(density(df$mark))

6. Medidas de localización

Cálculo de la media, mediana y moda respecto a la variable mark.

6.1 Media

# Calculate mean

media <- mean(df$mark, na.rm = TRUE)

print(round(media,1))
[1] 24.1

6.2 Mediana

# Calculate median

mediana <- median(df$mark, na.rm = TRUE)
print(round(mediana, 1))
[1] 20

6.3 Moda

# Calculate mode
# In a bimodal or multimodal situation, it only returns the lowest mode.

freq_table <- table(df$mark)
moda <- min(as.numeric(names(freq_table)[freq_table == max(freq_table)])) 
print(round(moda, 1))
[1] 24

6.4 Visualizamos la media, mediana y moda:

ggplot(df, aes(x = mark)) +
  geom_histogram(binwidth = 7, fill = "lightgray", color = "gray36") +
  # Media
  geom_vline(aes(xintercept = media), color = "#CD6090", linetype = "dashed", size = 1) +
  annotate("text", x = media + 2, y = 8, label = paste("Media = ", round(media, 1)), color = "#CD6090") +
  # Mediana
  geom_vline(aes(xintercept = mediana), color = "#008B45", linetype = "dashed", size = 1) +
  annotate("text", x = mediana + 2, y = 10, label = paste("Mediana = ", round(mediana, 1)), color = "#008B45") +
  # Moda
  geom_vline(aes(xintercept = moda), color = "#4169E1", linetype = "dashed", size = 1) +
  annotate("text", x = moda + 2, y = 12, label = paste("Moda = ", round(moda, 1)), color = "#4169E1") +
  # Etiquetas
  labs(title = "Frecuencia de puntajes con medidas de localización", x = "Puntaje", y = "Frecuencia") +
  # Fondo personalizado
  theme(
    panel.background = element_rect(fill = "#FFF8DC"),  # Fondo del panel
    plot.background = element_rect(fill = "#FFF8DC"),   # Fondo total del gráfico
    panel.grid.major = element_line(color = "#FFF8DC"),   # Líneas de cuadrícula principales
    panel.grid.minor = element_line(color = "#FFF8DC")    # Líneas de cuadrícula menores
  )

7. Impacto de outliers en las medidas de localización

7.1 Dataset con outliers en mark

# Copy the df

df_outliers <- df

# Add outliers

df_outliers <- rbind(df_outliers, data.frame(
                                              student = c("a", "b"),
                                              mark = c(100, 99)
)
)

# Show the changes
tail(df_outliers)

7.2 Media

# Calculate mean

media_out <- mean(df_outliers$mark, na.rm = TRUE)

print(round(media_out, 1))
[1] 25.6

7.3 Mediana

# Calculate median
mediana_out <- median(df_outliers$mark, na.rm = TRUE)
print(round(mediana_out, 1))
[1] 20

7.4 Moda

# Calculate mode
# In a bimodal or multimodal situation, it only returns the lowest mode.

freq_table_out <- table(df_outliers$mark)
moda_out <- min(as.numeric(names(freq_table_out)[freq_table_out == max(freq_table_out)])) 
print(round(moda_out, 1))
[1] 24

7.5 Visualizamos el impacto de los outliers sobre la media, mediana y moda :

ggplot(df_outliers, aes(x = mark)) +
  geom_histogram(binwidth = 5, fill = "lightgray", color = "gray36") +
  # Mean
  geom_vline(aes(xintercept = media_out), color = "#CD6090", linetype = "dashed", size = 1) +
  annotate("text", x = media_out + 2, y = 7, label = paste("Media_out = ", round(media_out, 1)), color = "#CD6090") +
  # Median
  geom_vline(aes(xintercept = mediana_out), color = "#008B45", linetype = "dashed", size = 1) +
  annotate("text", x = mediana_out + 2, y = 8, label = paste("Mediana_out = ", round(mediana_out, 1)), color = "#008B45") +
  # Mode
  geom_vline(aes(xintercept = moda_out), color = "#4169E1", linetype = "dashed", size = 1) +
  annotate("text", x = moda_out + 2, y = 9, label = paste("Moda_out = ", round(moda_out, 1)), color = "#4169E1") + 
  # Labels
  labs(title = "Frecuencia de puntajes con medidas de localización en presencia de outliers", x ="Puntaje", y ="Frecuencia")+
  # Fondo personalizado
  theme(
    panel.background = element_rect(fill = "#FFF8DC"),  # Fondo del panel
    plot.background = element_rect(fill = "#FFF8DC"),   # Fondo total del gráfico
    panel.grid.major = element_line(color = "#FFF8DC"),   # Líneas de cuadrícula principales
    panel.grid.minor = element_line(color = "#FFF8DC"),    # Líneas de cuadrícula menores
  )

8. Conclusiones:

LS0tDQp0aXRsZTogIkltcGFjdCBvZiBPdXRsaWVycyBvbiBNZWFzdXJlcyBvZiBMb2NhdGlvbiINCmF1dGhvcjogIkJhcmJhcmEgU8OhbmNoZXoiDQpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KIyAxLiBJbnRyb2R1Y2Npw7NuDQoNCkVsIHRyYWJham8gYWN0dWFsIGhhIHNpZG8gcmVhbGl6YWRvIGNvbiBmaW5lcyBkZSBlc3R1ZGlvLCBwYXJhIHBvZGVyIHZlciBlbCBpbXBhY3RvIHF1ZSB0aWVuZW4gbG9zIG91dGxpZXJzIHNvYnJlIGxhIG1lZGlhLCBtZWRpYW5hIHkgbW9kYS4NCg0KKiBOw7ptZXJvIGRlIHZhcmlhYmxlczogMg0KDQoqIE7Dum1lcm8gZGUgb2JzZXJ2YWNpb25lczogMTAwDQoNCiMgMi4gT2JqZXRpdm9zDQoNCiogQ2FsY3VsYXIgeSByZXByZXNlbnRhciBncsOhZmljYW1lbnRlIGxhIG1lZGlhLCBtZWRpYW5hIHkgbW9kYQ0KDQoqIFZpc3VhbGl6YXIgeSBjb21wcmVuZGVyIGVsIGltcGFjdG8gcXVlIHRpZW5lbiBsb3Mgb3V0bGllcnMgc29icmUgbGEgbWVkaWEsIG1lZGlhbmEgeSBtb2RhLg0KDQojIDMuIENvbmZpZ3VyYWNpw7NuDQoNCkluc3RhbGFtb3MgbG9zIHBhcXVldGVzIHkgY2FyZ2Ftb3MgbGFzIGxpYnJlcsOtYXMgbmVjZXNhcmlhcy4NCg0KYGBge3J9DQojIEluc3RhbGwgbmVjZXNzYXJ5IHBhY2thZ2VzIGFuZCBsaWJyYXJpZXMNCg0KI2luc3RhbGwucGFja2FnZXMoInRpZHl2ZXJzZSIpDQojaW5zdGFsbC5wYWNrYWdlcygiZ2dwbG90MiIpDQojaW5zdGFsbC5wYWNrYWdlcygiZHBseXIiKQ0KbGlicmFyeShyZWFkcikNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KGdncGxvdDIpDQpgYGANCg0KIyA0LiBDcmVhY2nDs24gZGVsIGRhdGEgZnJhbWUNCg0KYGBge3J9DQojIFJlYWQgcmF3DQptYXJrIDwtIGMoNiwgNywgOCwgOSwgMTAsIDExLCAxMiwgMTMsIDE0LCAxNSwgDQogICAgICAgICAgICAgMTYsIDE3LCAxOCwgMTksIDIwLCAyMSwgMjIsIDIzLCAyNCwgMjUsIA0KICAgICAgICAgICAgIDI3LCAyOCwgMzAsIDMxLCAzMiwgMzYsIDM3LCAzOCwgNDAsIDQxLCANCiAgICAgICAgICAgICA0MiwgNDQsIDQ2LCA1MCwgNTEsIDUyLCA1MywgNTQpDQpmcmVxcyA8LSBjKDUsIDMsIDMsIDQsIDIsIDQsIDMsIDQsIDIsIDEsIA0KICAgICAgICAgICAgICAgICAzLCA1LCA0LCA0LCA1LCAyLCAyLCAyLCA2LCAxLCANCiAgICAgICAgICAgICAgICAgMiwgMiwgMSwgMywgMSwgMSwgMiwgMiwgNCwgMywgDQogICAgICAgICAgICAgICAgIDIsIDIsIDEsIDEsIDMsIDEsIDMsIDEpDQptYXJrIDwtIHJlcChtYXJrLCBmcmVxcykNCg0KZGYgPC0gZGF0YS5mcmFtZSgNCiAgc3R1ZGVudCA9IGFzLmNoYXJhY3RlcihzZXEoMSwgMTAwKSksDQogIG1hcmsgPSBtYXJrDQopDQpgYGANCg0KIyA1LiBFeHBsb3JhY2nDs24gaW5pY2lhbCAoRURBIGLDoXNpY28pDQoNCmBgYHtyfQ0KIyBGaXJzdCBzaXggbGluZXMgb2YgdGhlIGRmDQpoZWFkKGRmKQ0KYGBgDQoNCmBgYHtyfQ0KIyBJbnRlcm5hbCBzdHJ1Y3R1cmUgb2YgdGhlIGRmDQpnbGltcHNlKGRmKQ0KYGBgDQoNCg0KYGBge3J9DQojIFN0YXRpc3RpY2FsIHN1bW1hcnkNCnN1bW1hcnkoZGYpDQpgYGANCmBgYHtyfQ0KIyBUZXN0IGZvciBOQXMNCg0KYW55TkEoZGYpDQpzdW0oaXMubmEoZGYpKQ0KYGBgDQpgYGB7cn0NCiMgRnJlcSBieSBvYnMNCnRhYmxlKGRmJG1hcmspDQpgYGANCg0KYGBge3J9DQojIExvb2tpbmcgZm9yIG91dGxpZXJzDQpib3hwbG90KGRmJG1hcmspDQpgYGANCmBgYHtyfQ0KIyBIb3cncyB0aGUgZGF0YQ0KaGlzdChkZiRtYXJrKQ0KYGBgDQpgYGB7cn0NCiMgSG93J3MgdGhlIGRhdGENCnBsb3QoZGVuc2l0eShkZiRtYXJrKSkNCmBgYA0KIyA2LiBNZWRpZGFzIGRlIGxvY2FsaXphY2nDs24NCg0KQ8OhbGN1bG8gZGUgbGEgbWVkaWEsIG1lZGlhbmEgeSBtb2RhIHJlc3BlY3RvIGEgbGEgdmFyaWFibGUgbWFyay4NCg0KIyMgNi4xIE1lZGlhDQoNCmBgYHtyfQ0KIyBDYWxjdWxhdGUgbWVhbg0KDQptZWRpYSA8LSBtZWFuKGRmJG1hcmssIG5hLnJtID0gVFJVRSkNCg0KcHJpbnQocm91bmQobWVkaWEsMSkpDQoNCmBgYA0KDQojIyA2LjIgTWVkaWFuYQ0KDQpgYGB7cn0NCiMgQ2FsY3VsYXRlIG1lZGlhbg0KDQptZWRpYW5hIDwtIG1lZGlhbihkZiRtYXJrLCBuYS5ybSA9IFRSVUUpDQpwcmludChyb3VuZChtZWRpYW5hLCAxKSkNCg0KYGBgDQoNCiMjIDYuMyBNb2RhDQoNCmBgYHtyfQ0KIyBDYWxjdWxhdGUgbW9kZQ0KIyBJbiBhIGJpbW9kYWwgb3IgbXVsdGltb2RhbCBzaXR1YXRpb24sIGl0IG9ubHkgcmV0dXJucyB0aGUgbG93ZXN0IG1vZGUuDQoNCmZyZXFfdGFibGUgPC0gdGFibGUoZGYkbWFyaykNCm1vZGEgPC0gbWluKGFzLm51bWVyaWMobmFtZXMoZnJlcV90YWJsZSlbZnJlcV90YWJsZSA9PSBtYXgoZnJlcV90YWJsZSldKSkgDQpwcmludChyb3VuZChtb2RhLCAxKSkNCmBgYA0KIyMgNi40IFZpc3VhbGl6YW1vcyBsYSBtZWRpYSwgbWVkaWFuYSB5IG1vZGE6DQoNCmBgYHtyfQ0KZ2dwbG90KGRmLCBhZXMoeCA9IG1hcmspKSArDQogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gNywgZmlsbCA9ICJsaWdodGdyYXkiLCBjb2xvciA9ICJncmF5MzYiKSArDQogICMgTWVkaWENCiAgZ2VvbV92bGluZShhZXMoeGludGVyY2VwdCA9IG1lZGlhKSwgY29sb3IgPSAiI0NENjA5MCIsIGxpbmV0eXBlID0gImRhc2hlZCIsIHNpemUgPSAxKSArDQogIGFubm90YXRlKCJ0ZXh0IiwgeCA9IG1lZGlhICsgMiwgeSA9IDgsIGxhYmVsID0gcGFzdGUoIk1lZGlhID0gIiwgcm91bmQobWVkaWEsIDEpKSwgY29sb3IgPSAiI0NENjA5MCIpICsNCiAgIyBNZWRpYW5hDQogIGdlb21fdmxpbmUoYWVzKHhpbnRlcmNlcHQgPSBtZWRpYW5hKSwgY29sb3IgPSAiIzAwOEI0NSIsIGxpbmV0eXBlID0gImRhc2hlZCIsIHNpemUgPSAxKSArDQogIGFubm90YXRlKCJ0ZXh0IiwgeCA9IG1lZGlhbmEgKyAyLCB5ID0gMTAsIGxhYmVsID0gcGFzdGUoIk1lZGlhbmEgPSAiLCByb3VuZChtZWRpYW5hLCAxKSksIGNvbG9yID0gIiMwMDhCNDUiKSArDQogICMgTW9kYQ0KICBnZW9tX3ZsaW5lKGFlcyh4aW50ZXJjZXB0ID0gbW9kYSksIGNvbG9yID0gIiM0MTY5RTEiLCBsaW5ldHlwZSA9ICJkYXNoZWQiLCBzaXplID0gMSkgKw0KICBhbm5vdGF0ZSgidGV4dCIsIHggPSBtb2RhICsgMiwgeSA9IDEyLCBsYWJlbCA9IHBhc3RlKCJNb2RhID0gIiwgcm91bmQobW9kYSwgMSkpLCBjb2xvciA9ICIjNDE2OUUxIikgKw0KICAjIEV0aXF1ZXRhcw0KICBsYWJzKHRpdGxlID0gIkZyZWN1ZW5jaWEgZGUgcHVudGFqZXMgY29uIG1lZGlkYXMgZGUgbG9jYWxpemFjacOzbiIsIHggPSAiUHVudGFqZSIsIHkgPSAiRnJlY3VlbmNpYSIpICsNCiAgIyBGb25kbyBwZXJzb25hbGl6YWRvDQogIHRoZW1lKA0KICAgIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICIjRkZGOERDIiksICAjIEZvbmRvIGRlbCBwYW5lbA0KICAgIHBsb3QuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gIiNGRkY4REMiKSwgICAjIEZvbmRvIHRvdGFsIGRlbCBncsOhZmljbw0KICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUoY29sb3IgPSAiI0ZGRjhEQyIpLCAgICMgTMOtbmVhcyBkZSBjdWFkcsOtY3VsYSBwcmluY2lwYWxlcw0KICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUoY29sb3IgPSAiI0ZGRjhEQyIpICAgICMgTMOtbmVhcyBkZSBjdWFkcsOtY3VsYSBtZW5vcmVzDQogICkNCmBgYA0KIyA3LiBJbXBhY3RvIGRlIG91dGxpZXJzIGVuIGxhcyBtZWRpZGFzIGRlIGxvY2FsaXphY2nDs24NCg0KIyMgNy4xIERhdGFzZXQgY29uIG91dGxpZXJzIGVuIG1hcmsNCmBgYHtyfQ0KIyBDb3B5IHRoZSBkZg0KDQpkZl9vdXRsaWVycyA8LSBkZg0KDQojIEFkZCBvdXRsaWVycw0KDQpkZl9vdXRsaWVycyA8LSByYmluZChkZl9vdXRsaWVycywgZGF0YS5mcmFtZSgNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHVkZW50ID0gYygiYSIsICJiIiksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFyayA9IGMoMTAwLCA5OSkNCikNCikNCg0KIyBTaG93IHRoZSBjaGFuZ2VzDQp0YWlsKGRmX291dGxpZXJzKQ0KYGBgDQoNCiMjIDcuMiBNZWRpYQ0KDQpgYGB7cn0NCiMgQ2FsY3VsYXRlIG1lYW4NCg0KbWVkaWFfb3V0IDwtIG1lYW4oZGZfb3V0bGllcnMkbWFyaywgbmEucm0gPSBUUlVFKQ0KDQpwcmludChyb3VuZChtZWRpYV9vdXQsIDEpKQ0KDQpgYGANCg0KIyMgNy4zIE1lZGlhbmENCg0KYGBge3J9DQojIENhbGN1bGF0ZSBtZWRpYW4NCm1lZGlhbmFfb3V0IDwtIG1lZGlhbihkZl9vdXRsaWVycyRtYXJrLCBuYS5ybSA9IFRSVUUpDQpwcmludChyb3VuZChtZWRpYW5hX291dCwgMSkpDQoNCmBgYA0KDQojIyA3LjQgTW9kYQ0KDQpgYGB7cn0NCiMgQ2FsY3VsYXRlIG1vZGUNCiMgSW4gYSBiaW1vZGFsIG9yIG11bHRpbW9kYWwgc2l0dWF0aW9uLCBpdCBvbmx5IHJldHVybnMgdGhlIGxvd2VzdCBtb2RlLg0KDQpmcmVxX3RhYmxlX291dCA8LSB0YWJsZShkZl9vdXRsaWVycyRtYXJrKQ0KbW9kYV9vdXQgPC0gbWluKGFzLm51bWVyaWMobmFtZXMoZnJlcV90YWJsZV9vdXQpW2ZyZXFfdGFibGVfb3V0ID09IG1heChmcmVxX3RhYmxlX291dCldKSkgDQpwcmludChyb3VuZChtb2RhX291dCwgMSkpDQpgYGANCg0KIyMgNy41IFZpc3VhbGl6YW1vcyBlbCBpbXBhY3RvIGRlIGxvcyBvdXRsaWVycyBzb2JyZSBsYSBtZWRpYSwgbWVkaWFuYSB5IG1vZGEgOg0KDQpgYGB7cn0NCmdncGxvdChkZl9vdXRsaWVycywgYWVzKHggPSBtYXJrKSkgKw0KICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDUsIGZpbGwgPSAibGlnaHRncmF5IiwgY29sb3IgPSAiZ3JheTM2IikgKw0KICAjIE1lYW4NCiAgZ2VvbV92bGluZShhZXMoeGludGVyY2VwdCA9IG1lZGlhX291dCksIGNvbG9yID0gIiNDRDYwOTAiLCBsaW5ldHlwZSA9ICJkYXNoZWQiLCBzaXplID0gMSkgKw0KICBhbm5vdGF0ZSgidGV4dCIsIHggPSBtZWRpYV9vdXQgKyAyLCB5ID0gNywgbGFiZWwgPSBwYXN0ZSgiTWVkaWFfb3V0ID0gIiwgcm91bmQobWVkaWFfb3V0LCAxKSksIGNvbG9yID0gIiNDRDYwOTAiKSArDQogICMgTWVkaWFuDQogIGdlb21fdmxpbmUoYWVzKHhpbnRlcmNlcHQgPSBtZWRpYW5hX291dCksIGNvbG9yID0gIiMwMDhCNDUiLCBsaW5ldHlwZSA9ICJkYXNoZWQiLCBzaXplID0gMSkgKw0KICBhbm5vdGF0ZSgidGV4dCIsIHggPSBtZWRpYW5hX291dCArIDIsIHkgPSA4LCBsYWJlbCA9IHBhc3RlKCJNZWRpYW5hX291dCA9ICIsIHJvdW5kKG1lZGlhbmFfb3V0LCAxKSksIGNvbG9yID0gIiMwMDhCNDUiKSArDQogICMgTW9kZQ0KICBnZW9tX3ZsaW5lKGFlcyh4aW50ZXJjZXB0ID0gbW9kYV9vdXQpLCBjb2xvciA9ICIjNDE2OUUxIiwgbGluZXR5cGUgPSAiZGFzaGVkIiwgc2l6ZSA9IDEpICsNCiAgYW5ub3RhdGUoInRleHQiLCB4ID0gbW9kYV9vdXQgKyAyLCB5ID0gOSwgbGFiZWwgPSBwYXN0ZSgiTW9kYV9vdXQgPSAiLCByb3VuZChtb2RhX291dCwgMSkpLCBjb2xvciA9ICIjNDE2OUUxIikgKyANCiAgIyBMYWJlbHMNCiAgbGFicyh0aXRsZSA9ICJGcmVjdWVuY2lhIGRlIHB1bnRhamVzIGNvbiBtZWRpZGFzIGRlIGxvY2FsaXphY2nDs24gZW4gcHJlc2VuY2lhIGRlIG91dGxpZXJzIiwgeCA9IlB1bnRhamUiLCB5ID0iRnJlY3VlbmNpYSIpKw0KICAjIEZvbmRvIHBlcnNvbmFsaXphZG8NCiAgdGhlbWUoDQogICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gIiNGRkY4REMiKSwgICMgRm9uZG8gZGVsIHBhbmVsDQogICAgcGxvdC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAiI0ZGRjhEQyIpLCAgICMgRm9uZG8gdG90YWwgZGVsIGdyw6FmaWNvDQogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShjb2xvciA9ICIjRkZGOERDIiksICAgIyBMw61uZWFzIGRlIGN1YWRyw61jdWxhIHByaW5jaXBhbGVzDQogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShjb2xvciA9ICIjRkZGOERDIiksICAgICMgTMOtbmVhcyBkZSBjdWFkcsOtY3VsYSBtZW5vcmVzDQogICkNCmBgYA0KIyA4LiBDb25jbHVzaW9uZXM6DQoNCiogTGEgbWVkaWEgZXMgbGEgbWVkaWRhIG3DoXMgYWZlY3RhZGEgcG9yIGxhIHByZXNlbmNpYSBkZSBvdXRsaWVycywgZGVzcGxhesOhbmRvc2UgY29uc2lkZXJhYmxlbWVudGUgaGFjaWEgZWwgZXh0cmVtbyAoZG9uZGUgc2UgZW5jdWVudHJhbiBlc3RvcyBvdXRsaWVycykuDQoNCiogTGEgbWVkaWFuYSBwcmVzZW50YSB1bmEgYWZlY3RhY2nDs24gbcOtbmltYSBwb3IgbGEgcHJlc2VuY2lhIGRlIG91dGxpZXJzLCBsbyBjdWFsIHBvZHLDrWFtb3MgaW50ZXJwcmV0YXIgY29tbyBxdWUgZXMgbcOhcyByZXNpc3RlbnRlIGEgdmFsb3JlcyBleHRyZW1vczsgcG9yIGxvIHF1ZSBlcyBsYSBtZWRpZGEgbcOhcyByb2J1c3RhIGFudGUgb3V0bGllcnMuDQoNCiogTGEgbW9kYSBubyBzZSBhZmVjdGEgcG9yIGxvcyBvdXRsaWVycywgeWEgcXVlIGFwYXJlY2VuIGVuIG1lbm9yIGNhbnRpZGFkIHF1ZSBsb3MgdmFsb3JlcyBjb24gZnJlY3VlbmNpYSBtw6F4aW1hIChtb2RhcykuDQoNCiogRW4gYW7DoWxpc2lzIGRlIGRhdG9zIHJlYWxlcywgZXNwZWNpYWxtZW50ZSBjb24gcHJlc2VuY2lhIGRlIG91dGxpZXJzLCBsYSBtZWRpYW5hIHkgb3RyYXMgbWVkaWRhcyByb2J1c3RhcyBzdWVsZW4gcHJvcG9yY2lvbmFyIHVuYSBkZXNjcmlwY2nDs24gbcOhcyByZXByZXNlbnRhdGl2YSBxdWUgbGEgbWVkaWEuDQoNCiogRXN0ZSBhbsOhbGlzaXMgZXZpZGVuY2lhIGxhIGltcG9ydGFuY2lhIGRlIGlkZW50aWZpY2FyIHkgbWFuZWphciBsb3Mgb3V0bGllcnMgYW50ZXMgZGUgaW50ZXJwcmV0YXIgbGFzIG1lZGlkYXMgZGUgdGVuZGVuY2lhIGNlbnRyYWwsIGVzcGVjaWFsbWVudGUgY3VhbmRvIGxhIG1lZGlhIHNlIHV0aWxpemEgY29tbyBpbmRpY2Fkb3IgcHJpbmNpcGFsIGVuIGNvbnRleHRvcyBlZHVjYXRpdm9zIG8gZGUgcmVuZGltaWVudG8gYWNhZMOpbWljby4=