1. Introducción

El presente caso se analiza desde la perspectiva de Marie Daer, quien se encuentra interesada en llevar un programa de MBA. Ella espera responder algunas preguntas importantes para ayudar a decidir si se matricula en dicho programa, en base a una encuesta realizada a los estudiantes del programa tres meses luego de su graduación.

En particular, está interesada en conocer respecto al salario inicial de los estudiantes graduados, si el género o edad tienen relación con el salario, y si los estudiantes están satisfechos con el programa. Asimismo, desea conocer si su puntaje en el GMAT tiene alguna relación con el puntaje logrado en el curso, dado que su resultado GMAT fue relativamente bajo al no ser el inglés su lengua materna.


2. Objetivo del caso

  1. ¿Cuál es el objetivo de aspirantes a postulantes como Marie Daer?
  • Objetivo general: Decidir sobre la inscripción al programa de MBA en esta escuela en particular.

  • Objetivos específicos

    • Conocer el nivel de salario que los estudiantes esperarian ganar al graduarse.

    • Determinar si existen algunas otras variables que influyen en el nivel de salario que esperarian recibir.

    • Determinar si el programa es bien calificado por los graduados.


3. Análisis

Base1 <- read.xlsx("E:/OneDrive/2. PEDRO LAYZA/01. CURSOS/0. BI & BA/2. MODULO 2 - DATA ANALYSIS/DATA Analytics Introduction/3. Caso/W12513-XLS-ENG.xlsx", 
                   sheetName = "Base1")
attach(Base1)
glimpse(Base1)
## Rows: 274
## Columns: 9
## $ ID       <dbl> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18…
## $ age      <dbl> 23, 24, 24, 24, 24, 24, 25, 25, 25, 25, 26, 26, 26, 26, 26, 2…
## $ sex      <dbl> 2, 1, 1, 1, 2, 1, 1, 2, 1, 1, 1, 2, 1, 1, 2, 2, 2, 1, 1, 1, 2…
## $ gmat_tot <dbl> 620, 610, 670, 570, 710, 640, 610, 650, 630, 680, 740, 610, 7…
## $ gmat_qpc <dbl> 77, 90, 99, 56, 93, 82, 89, 88, 79, 99, 99, 75, 95, 97, 84, 6…
## $ gmat_vpc <dbl> 87, 71, 78, 81, 98, 89, 74, 89, 91, 81, 98, 87, 95, 97, 93, 9…
## $ gmat_tpc <dbl> 87, 87, 95, 75, 98, 91, 87, 92, 89, 96, 99, 86, 98, 99, 94, 9…
## $ s_avg    <dbl> 3.40, 3.50, 3.30, 3.30, 3.60, 3.90, 3.40, 3.30, 3.30, 3.45, 3…
## $ f_avg    <dbl> 3.00, 4.00, 3.25, 2.67, 3.75, 3.75, 3.50, 3.75, 3.25, 3.67, 4…
Base2 <- read.xlsx("E:/OneDrive/2. PEDRO LAYZA/01. CURSOS/0. BI & BA/2. MODULO 2 - DATA ANALYSIS/DATA Analytics Introduction/3. Caso/W12513-XLS-ENG.xlsx", 
                   sheetName = "Base2")
attach(Base2)
glimpse(Base2)
## Rows: 274
## Columns: 6
## $ ID       <dbl> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18…
## $ quarter  <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1…
## $ work_yrs <dbl> 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 4, 2, 4, 3, 2, 4, 4…
## $ frstlang <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1…
## $ salary   <dbl> 0, 0, 0, 0, 999, 0, 0, 0, 999, 998, 998, 998, 998, 998, 998, …
## $ satis    <dbl> 7, 6, 6, 7, 5, 6, 5, 6, 4, 998, 998, 998, 998, 998, 998, 998,…
Base<-inner_join(Base1,Base2, by = "ID") %>%glimpse()
## Rows: 274
## Columns: 14
## $ ID       <dbl> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18…
## $ age      <dbl> 23, 24, 24, 24, 24, 24, 25, 25, 25, 25, 26, 26, 26, 26, 26, 2…
## $ sex      <dbl> 2, 1, 1, 1, 2, 1, 1, 2, 1, 1, 1, 2, 1, 1, 2, 2, 2, 1, 1, 1, 2…
## $ gmat_tot <dbl> 620, 610, 670, 570, 710, 640, 610, 650, 630, 680, 740, 610, 7…
## $ gmat_qpc <dbl> 77, 90, 99, 56, 93, 82, 89, 88, 79, 99, 99, 75, 95, 97, 84, 6…
## $ gmat_vpc <dbl> 87, 71, 78, 81, 98, 89, 74, 89, 91, 81, 98, 87, 95, 97, 93, 9…
## $ gmat_tpc <dbl> 87, 87, 95, 75, 98, 91, 87, 92, 89, 96, 99, 86, 98, 99, 94, 9…
## $ s_avg    <dbl> 3.40, 3.50, 3.30, 3.30, 3.60, 3.90, 3.40, 3.30, 3.30, 3.45, 3…
## $ f_avg    <dbl> 3.00, 4.00, 3.25, 2.67, 3.75, 3.75, 3.50, 3.75, 3.25, 3.67, 4…
## $ quarter  <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1…
## $ work_yrs <dbl> 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 4, 2, 4, 3, 2, 4, 4…
## $ frstlang <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1…
## $ salary   <dbl> 0, 0, 0, 0, 999, 0, 0, 0, 999, 998, 998, 998, 998, 998, 998, …
## $ satis    <dbl> 7, 6, 6, 7, 5, 6, 5, 6, 4, 998, 998, 998, 998, 998, 998, 998,…
  • Cambio de nombres de columnas
names(Base)<-c("ID","Edad","Sexo","GMAT_Total","Perc_Cuant_GMAT",
                "Perc_Verbal_GMAT","Perc_Gral_GMAT","Prom_Primavera",
                "Prom_Otoño","QRanking","Exp_laboral","Lengua_materna",
                "Salario_Inicial","Grado_Satisfacción")
  • Validando la estructura y las estadísticas básicas
tibble(Base)
## # A tibble: 274 × 14
##       ID  Edad  Sexo GMAT_Total Perc_Cuant_GMAT Perc_Verbal_GMAT Perc_Gral_GMAT
##    <dbl> <dbl> <dbl>      <dbl>           <dbl>            <dbl>          <dbl>
##  1     1    23     2        620              77               87             87
##  2     2    24     1        610              90               71             87
##  3     3    24     1        670              99               78             95
##  4     4    24     1        570              56               81             75
##  5     5    24     2        710              93               98             98
##  6     6    24     1        640              82               89             91
##  7     7    25     1        610              89               74             87
##  8     8    25     2        650              88               89             92
##  9     9    25     1        630              79               91             89
## 10    10    25     1        680              99               81             96
## # ℹ 264 more rows
## # ℹ 7 more variables: Prom_Primavera <dbl>, Prom_Otoño <dbl>, QRanking <dbl>,
## #   Exp_laboral <dbl>, Lengua_materna <dbl>, Salario_Inicial <dbl>,
## #   Grado_Satisfacción <dbl>
df_status(Base)
##              variable q_zeros p_zeros q_na p_na q_inf p_inf    type unique
## 1                  ID       0    0.00    0    0     0     0 numeric    274
## 2                Edad       0    0.00    0    0     0     0 numeric     21
## 3                Sexo       0    0.00    0    0     0     0 numeric      2
## 4          GMAT_Total       0    0.00    0    0     0     0 numeric     31
## 5     Perc_Cuant_GMAT       0    0.00    0    0     0     0 numeric     48
## 6    Perc_Verbal_GMAT       0    0.00    0    0     0     0 numeric     34
## 7      Perc_Gral_GMAT       2    0.73    0    0     0     0 numeric     42
## 8      Prom_Primavera       0    0.00    0    0     0     0 numeric     36
## 9          Prom_Otoño       3    1.09    0    0     0     0 numeric     21
## 10           QRanking       0    0.00    0    0     0     0 numeric      4
## 11        Exp_laboral       3    1.09    0    0     0     0 numeric     18
## 12     Lengua_materna       0    0.00    0    0     0     0 numeric      2
## 13    Salario_Inicial      90   32.85    0    0     0     0 numeric     45
## 14 Grado_Satisfacción       0    0.00    0    0     0     0 numeric      8
  • Actualizando los tipos de variables
Base$Sexo<-as.factor(Base$Sexo)
levels(Base$Sexo)<-c("Hombre","Mujer")
attach(Base)
table(Sexo)
## Sexo
## Hombre  Mujer 
##    206     68
Base$QRanking<-as.factor(Base$QRanking)
levels(Base$QRanking)<-c("1°","2°","3°","4°")
attach(Base)
table(QRanking)
## QRanking
## 1° 2° 3° 4° 
## 69 70 70 65
Base$Lengua_materna<-as.factor(Base$Lengua_materna)
levels(Base$Lengua_materna)<-c("Inglés","Otro")
attach(Base)
table(Lengua_materna)
## Lengua_materna
## Inglés   Otro 
##    242     32
df_status(Base)
##              variable q_zeros p_zeros q_na p_na q_inf p_inf    type unique
## 1                  ID       0    0.00    0    0     0     0 numeric    274
## 2                Edad       0    0.00    0    0     0     0 numeric     21
## 3                Sexo       0    0.00    0    0     0     0  factor      2
## 4          GMAT_Total       0    0.00    0    0     0     0 numeric     31
## 5     Perc_Cuant_GMAT       0    0.00    0    0     0     0 numeric     48
## 6    Perc_Verbal_GMAT       0    0.00    0    0     0     0 numeric     34
## 7      Perc_Gral_GMAT       2    0.73    0    0     0     0 numeric     42
## 8      Prom_Primavera       0    0.00    0    0     0     0 numeric     36
## 9          Prom_Otoño       3    1.09    0    0     0     0 numeric     21
## 10           QRanking       0    0.00    0    0     0     0  factor      4
## 11        Exp_laboral       3    1.09    0    0     0     0 numeric     18
## 12     Lengua_materna       0    0.00    0    0     0     0  factor      2
## 13    Salario_Inicial      90   32.85    0    0     0     0 numeric     45
## 14 Grado_Satisfacción       0    0.00    0    0     0     0 numeric      8
summary(Base)
##        ID              Edad           Sexo       GMAT_Total    Perc_Cuant_GMAT
##  Min.   :  1.00   Min.   :22.00   Hombre:206   Min.   :450.0   Min.   :28.00  
##  1st Qu.: 69.25   1st Qu.:25.00   Mujer : 68   1st Qu.:580.0   1st Qu.:72.00  
##  Median :137.50   Median :27.00                Median :620.0   Median :83.00  
##  Mean   :137.50   Mean   :27.36                Mean   :619.5   Mean   :80.64  
##  3rd Qu.:205.75   3rd Qu.:29.00                3rd Qu.:660.0   3rd Qu.:93.00  
##  Max.   :274.00   Max.   :48.00                Max.   :790.0   Max.   :99.00  
##  Perc_Verbal_GMAT Perc_Gral_GMAT Prom_Primavera    Prom_Otoño    QRanking
##  Min.   :16.00    Min.   : 0.0   Min.   :2.000   Min.   :0.000   1°:69   
##  1st Qu.:71.00    1st Qu.:78.0   1st Qu.:2.708   1st Qu.:2.750   2°:70   
##  Median :81.00    Median :87.0   Median :3.000   Median :3.000   3°:70   
##  Mean   :78.32    Mean   :84.2   Mean   :3.025   Mean   :3.062   4°:65   
##  3rd Qu.:91.00    3rd Qu.:94.0   3rd Qu.:3.300   3rd Qu.:3.250           
##  Max.   :99.00    Max.   :99.0   Max.   :4.000   Max.   :4.000           
##   Exp_laboral     Lengua_materna Salario_Inicial  Grado_Satisfacción
##  Min.   : 0.000   Inglés:242     Min.   :     0   Min.   :  1.0     
##  1st Qu.: 2.000   Otro  : 32     1st Qu.:     0   1st Qu.:  5.0     
##  Median : 3.000                  Median :   999   Median :  6.0     
##  Mean   : 3.872                  Mean   : 39026   Mean   :172.2     
##  3rd Qu.: 4.000                  3rd Qu.: 97000   3rd Qu.:  7.0     
##  Max.   :22.000                  Max.   :220000   Max.   :998.0

3.1 Preguntas del caso

  1. ¿Cuánto pueden esperar ganar los estudiantes al graduarse?
attach(Base)

Base <- Base %>% 
mutate(CAT_Salario = case_when(Base$Salario_Inicial==998 |  Base$Salario_Inicial==999 ~ 1,
Base$Salario_Inicial==0 ~ 2,
Base$Salario_Inicial>0 & Base$Salario_Inicial<=100000 ~ 3,
                                      TRUE ~ 4))
Base$CAT_Salario <- as.factor(Base$CAT_Salario)
levels(Base$CAT_Salario) <- c("1. S.I.","2. Sin salario","3.<0 - 100k]","4.>100k")
table(Base$CAT_Salario)
## 
##        1. S.I. 2. Sin salario   3.<0 - 100k]        4.>100k 
##             81             90             55             48
attach(Base)
Base %>% 
  group_by(CAT_Salario) %>% 
  summarise(Mínimo=min(Salario_Inicial) , 
            Máximo=max(Salario_Inicial),
            Promedio=mean(Salario_Inicial),
            Mediana=median(Salario_Inicial))
## # A tibble: 4 × 5
##   CAT_Salario    Mínimo Máximo Promedio Mediana
##   <fct>           <dbl>  <dbl>    <dbl>   <dbl>
## 1 1. S.I.           998    999     998.     998
## 2 2. Sin salario      0      0       0        0
## 3 3.<0 - 100k]    64000 100000   93332.   95000
## 4 4.>100k        100400 220000  114144.  107150
Base %>% 
  group_by(CAT_Salario) %>% 
  summarise(SD=sd(Salario_Inicial),
            Ngraduados = n(),
            Pgraduados = n()/nrow(Base))
## # A tibble: 4 × 4
##   CAT_Salario           SD Ngraduados Pgraduados
##   <fct>              <dbl>      <int>      <dbl>
## 1 1. S.I.            0.498         81      0.296
## 2 2. Sin salario     0             90      0.328
## 3 3.<0 - 100k]    7063.            55      0.201
## 4 4.>100k        19985.            48      0.175
# Si filtramos a los graduados que no contestaron y a los que no pusieron su salario

BaseF<-Base%>%
       filter(Salario_Inicial!=998 & Salario_Inicial!=999)
attach(BaseF)


mean(Salario_Inicial)
## [1] 54985.32
median(Salario_Inicial)
## [1] 85000
sd(Salario_Inicial)
## [1] 53152.39
# Si filtramos a los graduados que no contestaron, no pusieron su salario y a los que no tienen salario inicial

BaseF<-Base%>%
       filter(Salario_Inicial!=0 & Salario_Inicial!=998 & Salario_Inicial!=999)
attach(BaseF)


mean(Salario_Inicial)
## [1] 103030.7
median(Salario_Inicial)
## [1] 1e+05
sd(Salario_Inicial)
## [1] 17868.8

Cuando la media es mayor que la mediana, esto quiere decir que la distribución presenta asimetría positiva.

  1. ¿Existe alguna variable (por ejemplo, edad, sexo, cuartil, idioma hablado, experiencia laboral) que afecte cuánto puede esperar ganar un estudiante?
  • Empezamos analizando los cuartiles: Variable QRanking
BaseF<-Base%>%
       filter(Salario_Inicial!=0 & Salario_Inicial!=998 & Salario_Inicial!=999)
attach(BaseF)
attach(BaseF)
BaseF %>% 
  group_by(QRanking) %>% 
  summarise(Mínimo=min(Salario_Inicial) , 
            Máximo=max(Salario_Inicial),
            Promedio=mean(Salario_Inicial),
            Mediana=median(Salario_Inicial))
## # A tibble: 4 × 5
##   QRanking Mínimo Máximo Promedio Mediana
##   <fct>     <dbl>  <dbl>    <dbl>   <dbl>
## 1 1°        85000 162000  106329.  105000
## 2 2°        82000 145800  103612   100000
## 3 3°        78256 112000   98319    98000
## 4 4°        64000 220000  102143.   98000
BaseF %>% 
  group_by(QRanking) %>% 
  summarise(SD=sd(Salario_Inicial),
            Rango=max(Salario_Inicial)-min(Salario_Inicial),
            Ngraduados = n(),
            Pgraduados = n()/nrow(BaseF))
## # A tibble: 4 × 5
##   QRanking     SD  Rango Ngraduados Pgraduados
##   <fct>     <dbl>  <dbl>      <int>      <dbl>
## 1 1°       15838.  77000         35      0.340
## 2 2°       12819.  63800         25      0.243
## 3 3°        7175.  33744         24      0.233
## 4 4°       31601. 156000         19      0.184
BaseF1<-BaseF %>% 
        filter(Salario_Inicial!=220000)

attach(BaseF1)
BaseF1 %>% 
  group_by(QRanking) %>% 
  summarise(Mínimo=min(Salario_Inicial) , 
            Máximo=max(Salario_Inicial),
            Promedio=mean(Salario_Inicial),
            Mediana=median(Salario_Inicial))
## # A tibble: 4 × 5
##   QRanking Mínimo Máximo Promedio Mediana
##   <fct>     <dbl>  <dbl>    <dbl>   <dbl>
## 1 1°        85000 162000  106329.  105000
## 2 2°        82000 145800  103612   100000
## 3 3°        78256 112000   98319    98000
## 4 4°        64000 126710   95595    97000
BaseF1 %>% 
  group_by(QRanking) %>% 
  summarise(SD=sd(Salario_Inicial),
            Rango=max(Salario_Inicial)-min(Salario_Inicial),
            Ngraduados = n(),
            Pgraduados = n()/nrow(BaseF1))
## # A tibble: 4 × 5
##   QRanking     SD Rango Ngraduados Pgraduados
##   <fct>     <dbl> <dbl>      <int>      <dbl>
## 1 1°       15838. 77000         35      0.343
## 2 2°       12819. 63800         25      0.245
## 3 3°        7175. 33744         24      0.235
## 4 4°       13960. 62710         18      0.176
  • Prueba de normalidad
attach(BaseF1)


by(data = BaseF1,INDICES = BaseF1$QRanking,FUN = function(x){ lillie.test(x$Salario_Inicial)})
## BaseF1$QRanking: 1°
## 
##  Lilliefors (Kolmogorov-Smirnov) normality test
## 
## data:  x$Salario_Inicial
## D = 0.14369, p-value = 0.06499
## 
## ------------------------------------------------------------ 
## BaseF1$QRanking: 2°
## 
##  Lilliefors (Kolmogorov-Smirnov) normality test
## 
## data:  x$Salario_Inicial
## D = 0.21689, p-value = 0.003701
## 
## ------------------------------------------------------------ 
## BaseF1$QRanking: 3°
## 
##  Lilliefors (Kolmogorov-Smirnov) normality test
## 
## data:  x$Salario_Inicial
## D = 0.17707, p-value = 0.04998
## 
## ------------------------------------------------------------ 
## BaseF1$QRanking: 4°
## 
##  Lilliefors (Kolmogorov-Smirnov) normality test
## 
## data:  x$Salario_Inicial
## D = 0.13913, p-value = 0.4719

El uno de los grupos se observa falta de normalidad

  • Varianza constante entre grupos
attach(BaseF1)
fligner.test(Salario_Inicial ~ QRanking,BaseF1)
## 
##  Fligner-Killeen test of homogeneity of variances
## 
## data:  Salario_Inicial by QRanking
## Fligner-Killeen:med chi-squared = 6.8768, df = 3, p-value = 0.07593
require(car)
leveneTest(Salario_Inicial ~ QRanking,BaseF1,center = "median")
## Levene's Test for Homogeneity of Variance (center = "median")
##       Df F value Pr(>F)
## group  3  1.8251 0.1476
##       98

No hay evidencias significativas de falta de homocedasticidad en ninguno de los dos test.

  • Prueba de medianas

  • Prueba de Kruskal Wallis

kruskal.test(Salario_Inicial ~ QRanking, data = BaseF1)
## 
##  Kruskal-Wallis rank sum test
## 
## data:  Salario_Inicial by QRanking
## Kruskal-Wallis chi-squared = 8.4092, df = 3, p-value = 0.03827

Pvalue<0.05. Existe diferencia significativa en las medianas de por lo menos dos grupos.

  • Comparaciones múltiples
pairwise.wilcox.test(BaseF1$Salario_Inicial, BaseF1$QRanking, p.adjust.method = "bonf", paired = F)
## Warning in wilcox.test.default(xi, xj, paired = paired, ...): cannot compute
## exact p-value with ties
## Warning in wilcox.test.default(xi, xj, paired = paired, ...): cannot compute
## exact p-value with ties
## Warning in wilcox.test.default(xi, xj, paired = paired, ...): cannot compute
## exact p-value with ties
## Warning in wilcox.test.default(xi, xj, paired = paired, ...): cannot compute
## exact p-value with ties
## Warning in wilcox.test.default(xi, xj, paired = paired, ...): cannot compute
## exact p-value with ties
## Warning in wilcox.test.default(xi, xj, paired = paired, ...): cannot compute
## exact p-value with ties
## 
##  Pairwise comparisons using Wilcoxon rank sum test with continuity correction 
## 
## data:  BaseF1$Salario_Inicial and BaseF1$QRanking 
## 
##    1°    2°    3°   
## 2° 1.000 -     -    
## 3° 0.262 1.000 -    
## 4° 0.091 0.455 1.000
## 
## P value adjustment method: bonferroni

No se encuentran diferencias significativas entre los grupos dos a dos (p-value>0.05).

** Preguntas:

  • ¿Existe diferencia significativa en cuánto puede esperar ganar un estudiante, por el género?

  • ¿Existe diferencia significativa en cuánto puede esperar ganar un estudiante, por la edad?

  • ¿Existe diferencia significativa en cuánto puede esperar ganar un estudiante, por la experiencia laboral?

  • ¿Existe diferencia significativa en cuánto puede esperar ganar un estudiante, por la lengua materna?

Nota: Si compara solo dos grupos y los datos no siguen una distribución normal utilizar la Prueba U de Mann-Whitney

4. Conclusiones

  • Conclusión general:

Decidir sobre la inscripción al programa de MBA en esta escuela en particular.

  • Conclusiones específicas

    • En general, cuando se analizan a los graduados que contestaron el dato del salario; observamos que los graduados pueden esperar ganar $85,000. Pero, si analizamos a los graduados que tienen un salario inicial, entonces pueden esperar ganar $100,000.

    • Cuando analizamos si existen diferencias en el salario por ranking. Si observamos los datos de manera descriptiva, vemos que hay diferencias entre los promedios de los salarios por ranking. Sin embargo, para poder tener hipótesis preliminares generalizando a la población, existe suficiente evidencia para decir que no hay diferencias significativas entre los grupos de ranking.

LS0tDQp0aXRsZTogIk3Ds2R1bG8gSUk6IERhdGEgQW5hbHlzaXMgSW50cm9kdWN0aW9uIg0KYXV0aG9yOiAiTWFnLiBTb2xhbmdlIEJhc3VhbGRvIE5hamVyYSINCm91dHB1dDogb2lsYWJzOjpsYWJfcmVwb3J0DQotLS0NCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKQ0KDQpsaWJyYXJ5KCJkZXZ0b29scyIpDQpsaWJyYXJ5KCJkcGx5ciIpDQojbGlicmFyeSgib2lsYWJzIikNCmxpYnJhcnkoInRpZHl2ZXJzZSIpDQpsaWJyYXJ5KCJSQ29sb3JCcmV3ZXIiKSANCmxpYnJhcnkoImdyaWRFeHRyYSIpICANCnJlcXVpcmUoImtuaXRyIikNCmxpYnJhcnkoInhsc3giKQ0KbGlicmFyeSgiZnVuTW9kZWxpbmciKQ0KbGlicmFyeSgibm9ydGVzdCIpIA0KcmVxdWlyZShub3J0ZXN0KQ0KYGBgDQoqICogKg0KIyMjICoqMS4gSW50cm9kdWNjacOzbiAqKg0KDQpFbCBwcmVzZW50ZSBjYXNvIHNlIGFuYWxpemEgZGVzZGUgbGEgcGVyc3BlY3RpdmEgZGUgTWFyaWUgRGFlciwgcXVpZW4gc2UgZW5jdWVudHJhIGludGVyZXNhZGEgZW4gbGxldmFyIHVuIHByb2dyYW1hIGRlIE1CQS4gRWxsYSBlc3BlcmEgcmVzcG9uZGVyIGFsZ3VuYXMgcHJlZ3VudGFzIGltcG9ydGFudGVzIHBhcmEgYXl1ZGFyIGEgZGVjaWRpciBzaSBzZSBtYXRyaWN1bGEgZW4gZGljaG8gcHJvZ3JhbWEsIGVuIGJhc2UgYSB1bmEgZW5jdWVzdGEgcmVhbGl6YWRhIGEgbG9zIGVzdHVkaWFudGVzIGRlbCBwcm9ncmFtYSB0cmVzIG1lc2VzIGx1ZWdvIGRlIHN1IGdyYWR1YWNpw7NuLg0KDQpFbiBwYXJ0aWN1bGFyLCBlc3TDoSBpbnRlcmVzYWRhIGVuIGNvbm9jZXIgcmVzcGVjdG8gYWwgc2FsYXJpbyBpbmljaWFsIGRlIGxvcyBlc3R1ZGlhbnRlcyBncmFkdWFkb3MsIHNpIGVsIGfDqW5lcm8gbyBlZGFkIHRpZW5lbiByZWxhY2nDs24gY29uIGVsIHNhbGFyaW8sIHkgc2kgbG9zIGVzdHVkaWFudGVzIGVzdMOhbiBzYXRpc2ZlY2hvcyBjb24gZWwgcHJvZ3JhbWEuIEFzaW1pc21vLCBkZXNlYSBjb25vY2VyIHNpIHN1IHB1bnRhamUgZW4gZWwgR01BVCB0aWVuZSBhbGd1bmEgcmVsYWNpw7NuIGNvbiBlbCBwdW50YWplIGxvZ3JhZG8gZW4gZWwgY3Vyc28sIGRhZG8gcXVlIHN1IHJlc3VsdGFkbyBHTUFUIGZ1ZSByZWxhdGl2YW1lbnRlIGJham8gYWwgbm8gc2VyIGVsIGluZ2zDqXMgc3UgbGVuZ3VhIG1hdGVybmEuDQoNCiogKiAqDQoNCiMjIyAqKjIuIE9iamV0aXZvIGRlbCBjYXNvICoqDQoNCg0KYS4gwr9DdcOhbCBlcyBlbCBvYmpldGl2byBkZSBhc3BpcmFudGVzIGEgcG9zdHVsYW50ZXMgY29tbyBNYXJpZSBEYWVyPw0KDQoqIE9iamV0aXZvIGdlbmVyYWw6DQpEZWNpZGlyIHNvYnJlIGxhIGluc2NyaXBjacOzbiBhbCBwcm9ncmFtYSBkZSBNQkEgZW4gZXN0YSBlc2N1ZWxhIGVuIHBhcnRpY3VsYXIuDQoNCiogT2JqZXRpdm9zIGVzcGVjw61maWNvcw0KDQogIC0gQ29ub2NlciBlbCBuaXZlbCBkZSBzYWxhcmlvIHF1ZSBsb3MgZXN0dWRpYW50ZXMgZXNwZXJhcmlhbiBnYW5hciBhbCAgICAgIGdyYWR1YXJzZS4NCiAgDQogIC0gRGV0ZXJtaW5hciBzaSBleGlzdGVuIGFsZ3VuYXMgb3RyYXMgdmFyaWFibGVzIHF1ZSBpbmZsdXllbiBlbiBlbCAgICAgICAgIG5pdmVsIGRlIHNhbGFyaW8gcXVlIGVzcGVyYXJpYW4gcmVjaWJpci4NCiAgDQogIC0gRGV0ZXJtaW5hciBzaSBlbCBwcm9ncmFtYSBlcyBiaWVuIGNhbGlmaWNhZG8gcG9yIGxvcyBncmFkdWFkb3MuDQoNCiogKiAqDQoNCiMjIyAqKjMuIEFuw6FsaXNpcyAqKg0KDQpgYGB7ciwgbWVzc2FnZT1GQUxTRX0NCkJhc2UxIDwtIHJlYWQueGxzeCgiRTovT25lRHJpdmUvMi4gUEVEUk8gTEFZWkEvMDEuIENVUlNPUy8wLiBCSSAmIEJBLzIuIE1PRFVMTyAyIC0gREFUQSBBTkFMWVNJUy9EQVRBIEFuYWx5dGljcyBJbnRyb2R1Y3Rpb24vMy4gQ2Fzby9XMTI1MTMtWExTLUVORy54bHN4IiwgDQogICAgICAgICAgICAgICAgICAgc2hlZXROYW1lID0gIkJhc2UxIikNCmF0dGFjaChCYXNlMSkNCmdsaW1wc2UoQmFzZTEpDQoNCkJhc2UyIDwtIHJlYWQueGxzeCgiRTovT25lRHJpdmUvMi4gUEVEUk8gTEFZWkEvMDEuIENVUlNPUy8wLiBCSSAmIEJBLzIuIE1PRFVMTyAyIC0gREFUQSBBTkFMWVNJUy9EQVRBIEFuYWx5dGljcyBJbnRyb2R1Y3Rpb24vMy4gQ2Fzby9XMTI1MTMtWExTLUVORy54bHN4IiwgDQogICAgICAgICAgICAgICAgICAgc2hlZXROYW1lID0gIkJhc2UyIikNCmF0dGFjaChCYXNlMikNCmdsaW1wc2UoQmFzZTIpDQoNCkJhc2U8LWlubmVyX2pvaW4oQmFzZTEsQmFzZTIsIGJ5ID0gIklEIikgJT4lZ2xpbXBzZSgpDQpgYGANCiogQ2FtYmlvIGRlIG5vbWJyZXMgZGUgY29sdW1uYXMNCg0KYGBge3IgZWNobz1UICxldmFsPVQsIHdhcm5pbmc9RixtZXNzYWdlPVR9DQpuYW1lcyhCYXNlKTwtYygiSUQiLCJFZGFkIiwiU2V4byIsIkdNQVRfVG90YWwiLCJQZXJjX0N1YW50X0dNQVQiLA0KICAgICAgICAgICAgICAgICJQZXJjX1ZlcmJhbF9HTUFUIiwiUGVyY19HcmFsX0dNQVQiLCJQcm9tX1ByaW1hdmVyYSIsDQogICAgICAgICAgICAgICAgIlByb21fT3Rvw7FvIiwiUVJhbmtpbmciLCJFeHBfbGFib3JhbCIsIkxlbmd1YV9tYXRlcm5hIiwNCiAgICAgICAgICAgICAgICAiU2FsYXJpb19JbmljaWFsIiwiR3JhZG9fU2F0aXNmYWNjacOzbiIpDQpgYGANCg0KKiBWYWxpZGFuZG8gbGEgZXN0cnVjdHVyYSB5IGxhcyBlc3RhZMOtc3RpY2FzIGLDoXNpY2FzDQoNCmBgYHtyLCBtZXNzYWdlPUZBTFNFfQ0KDQp0aWJibGUoQmFzZSkNCmRmX3N0YXR1cyhCYXNlKQ0KYGBgDQoNCiogQWN0dWFsaXphbmRvIGxvcyB0aXBvcyBkZSB2YXJpYWJsZXMNCmBgYHtyLCBtZXNzYWdlPUZBTFNFfQ0KDQpCYXNlJFNleG88LWFzLmZhY3RvcihCYXNlJFNleG8pDQpsZXZlbHMoQmFzZSRTZXhvKTwtYygiSG9tYnJlIiwiTXVqZXIiKQ0KYXR0YWNoKEJhc2UpDQp0YWJsZShTZXhvKQ0KDQpCYXNlJFFSYW5raW5nPC1hcy5mYWN0b3IoQmFzZSRRUmFua2luZykNCmxldmVscyhCYXNlJFFSYW5raW5nKTwtYygiMcKwIiwiMsKwIiwiM8KwIiwiNMKwIikNCmF0dGFjaChCYXNlKQ0KdGFibGUoUVJhbmtpbmcpDQoNCg0KQmFzZSRMZW5ndWFfbWF0ZXJuYTwtYXMuZmFjdG9yKEJhc2UkTGVuZ3VhX21hdGVybmEpDQpsZXZlbHMoQmFzZSRMZW5ndWFfbWF0ZXJuYSk8LWMoIkluZ2zDqXMiLCJPdHJvIikNCmF0dGFjaChCYXNlKQ0KdGFibGUoTGVuZ3VhX21hdGVybmEpDQoNCg0KZGZfc3RhdHVzKEJhc2UpDQpzdW1tYXJ5KEJhc2UpDQpgYGANCg0KKiAqICoNCg0KIyMjIyAqKjMuMSBQcmVndW50YXMgZGVsIGNhc28gKioNCg0KYS4gwr9DdcOhbnRvIHB1ZWRlbiBlc3BlcmFyIGdhbmFyIGxvcyBlc3R1ZGlhbnRlcyBhbCBncmFkdWFyc2U/IA0KDQpgYGB7ciwgbWVzc2FnZT1GQUxTRX0NCmF0dGFjaChCYXNlKQ0KDQpCYXNlIDwtIEJhc2UgJT4lIA0KbXV0YXRlKENBVF9TYWxhcmlvID0gY2FzZV93aGVuKEJhc2UkU2FsYXJpb19JbmljaWFsPT05OTggfCAgQmFzZSRTYWxhcmlvX0luaWNpYWw9PTk5OSB+IDEsDQpCYXNlJFNhbGFyaW9fSW5pY2lhbD09MCB+IDIsDQpCYXNlJFNhbGFyaW9fSW5pY2lhbD4wICYgQmFzZSRTYWxhcmlvX0luaWNpYWw8PTEwMDAwMCB+IDMsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRSVUUgfiA0KSkNCkJhc2UkQ0FUX1NhbGFyaW8gPC0gYXMuZmFjdG9yKEJhc2UkQ0FUX1NhbGFyaW8pDQpsZXZlbHMoQmFzZSRDQVRfU2FsYXJpbykgPC0gYygiMS4gUy5JLiIsIjIuIFNpbiBzYWxhcmlvIiwiMy48MCAtIDEwMGtdIiwiNC4+MTAwayIpDQp0YWJsZShCYXNlJENBVF9TYWxhcmlvKQ0KYXR0YWNoKEJhc2UpDQpCYXNlICU+JSANCiAgZ3JvdXBfYnkoQ0FUX1NhbGFyaW8pICU+JSANCiAgc3VtbWFyaXNlKE3DrW5pbW89bWluKFNhbGFyaW9fSW5pY2lhbCkgLCANCiAgICAgICAgICAgIE3DoXhpbW89bWF4KFNhbGFyaW9fSW5pY2lhbCksDQogICAgICAgICAgICBQcm9tZWRpbz1tZWFuKFNhbGFyaW9fSW5pY2lhbCksDQogICAgICAgICAgICBNZWRpYW5hPW1lZGlhbihTYWxhcmlvX0luaWNpYWwpKQ0KDQoNCg0KQmFzZSAlPiUgDQogIGdyb3VwX2J5KENBVF9TYWxhcmlvKSAlPiUgDQogIHN1bW1hcmlzZShTRD1zZChTYWxhcmlvX0luaWNpYWwpLA0KICAgICAgICAgICAgTmdyYWR1YWRvcyA9IG4oKSwNCiAgICAgICAgICAgIFBncmFkdWFkb3MgPSBuKCkvbnJvdyhCYXNlKSkNCg0KIyBTaSBmaWx0cmFtb3MgYSBsb3MgZ3JhZHVhZG9zIHF1ZSBubyBjb250ZXN0YXJvbiB5IGEgbG9zIHF1ZSBubyBwdXNpZXJvbiBzdSBzYWxhcmlvDQoNCkJhc2VGPC1CYXNlJT4lDQogICAgICAgZmlsdGVyKFNhbGFyaW9fSW5pY2lhbCE9OTk4ICYgU2FsYXJpb19JbmljaWFsIT05OTkpDQphdHRhY2goQmFzZUYpDQoNCg0KbWVhbihTYWxhcmlvX0luaWNpYWwpDQptZWRpYW4oU2FsYXJpb19JbmljaWFsKQ0Kc2QoU2FsYXJpb19JbmljaWFsKQ0KDQojIFNpIGZpbHRyYW1vcyBhIGxvcyBncmFkdWFkb3MgcXVlIG5vIGNvbnRlc3Rhcm9uLCBubyBwdXNpZXJvbiBzdSBzYWxhcmlvIHkgYSBsb3MgcXVlIG5vIHRpZW5lbiBzYWxhcmlvIGluaWNpYWwNCg0KQmFzZUY8LUJhc2UlPiUNCiAgICAgICBmaWx0ZXIoU2FsYXJpb19JbmljaWFsIT0wICYgU2FsYXJpb19JbmljaWFsIT05OTggJiBTYWxhcmlvX0luaWNpYWwhPTk5OSkNCmF0dGFjaChCYXNlRikNCg0KDQptZWFuKFNhbGFyaW9fSW5pY2lhbCkNCm1lZGlhbihTYWxhcmlvX0luaWNpYWwpDQpzZChTYWxhcmlvX0luaWNpYWwpDQoNCmBgYA0KQ3VhbmRvIGxhIG1lZGlhIGVzIG1heW9yIHF1ZSBsYSBtZWRpYW5hLCBlc3RvIHF1aWVyZSBkZWNpciBxdWUgbGEgZGlzdHJpYnVjacOzbiBwcmVzZW50YSBhc2ltZXRyw61hIHBvc2l0aXZhLg0KDQpiLiDCv0V4aXN0ZSBhbGd1bmEgdmFyaWFibGUgKHBvciBlamVtcGxvLCBlZGFkLCBzZXhvLCBjdWFydGlsLCBpZGlvbWEgICAgICAgaGFibGFkbywgZXhwZXJpZW5jaWEgbGFib3JhbCkgcXVlIGFmZWN0ZSBjdcOhbnRvIHB1ZWRlIGVzcGVyYXIgZ2FuYXIgICAgIHVuIGVzdHVkaWFudGU/IA0KDQogICogICBFbXBlemFtb3MgYW5hbGl6YW5kbyBsb3MgY3VhcnRpbGVzOiBWYXJpYWJsZSBRUmFua2luZw0KDQpgYGB7ciwgbWVzc2FnZT1GQUxTRX0NCkJhc2VGPC1CYXNlJT4lDQogICAgICAgZmlsdGVyKFNhbGFyaW9fSW5pY2lhbCE9MCAmIFNhbGFyaW9fSW5pY2lhbCE9OTk4ICYgU2FsYXJpb19JbmljaWFsIT05OTkpDQphdHRhY2goQmFzZUYpDQpgYGANCg0KYGBge3IsIG1lc3NhZ2U9RkFMU0V9DQphdHRhY2goQmFzZUYpDQpCYXNlRiAlPiUgDQogIGdyb3VwX2J5KFFSYW5raW5nKSAlPiUgDQogIHN1bW1hcmlzZShNw61uaW1vPW1pbihTYWxhcmlvX0luaWNpYWwpICwgDQogICAgICAgICAgICBNw6F4aW1vPW1heChTYWxhcmlvX0luaWNpYWwpLA0KICAgICAgICAgICAgUHJvbWVkaW89bWVhbihTYWxhcmlvX0luaWNpYWwpLA0KICAgICAgICAgICAgTWVkaWFuYT1tZWRpYW4oU2FsYXJpb19JbmljaWFsKSkNCg0KDQpCYXNlRiAlPiUgDQogIGdyb3VwX2J5KFFSYW5raW5nKSAlPiUgDQogIHN1bW1hcmlzZShTRD1zZChTYWxhcmlvX0luaWNpYWwpLA0KICAgICAgICAgICAgUmFuZ289bWF4KFNhbGFyaW9fSW5pY2lhbCktbWluKFNhbGFyaW9fSW5pY2lhbCksDQogICAgICAgICAgICBOZ3JhZHVhZG9zID0gbigpLA0KICAgICAgICAgICAgUGdyYWR1YWRvcyA9IG4oKS9ucm93KEJhc2VGKSkNCg0KQmFzZUYxPC1CYXNlRiAlPiUgDQogICAgICAgIGZpbHRlcihTYWxhcmlvX0luaWNpYWwhPTIyMDAwMCkNCg0KYXR0YWNoKEJhc2VGMSkNCkJhc2VGMSAlPiUgDQogIGdyb3VwX2J5KFFSYW5raW5nKSAlPiUgDQogIHN1bW1hcmlzZShNw61uaW1vPW1pbihTYWxhcmlvX0luaWNpYWwpICwgDQogICAgICAgICAgICBNw6F4aW1vPW1heChTYWxhcmlvX0luaWNpYWwpLA0KICAgICAgICAgICAgUHJvbWVkaW89bWVhbihTYWxhcmlvX0luaWNpYWwpLA0KICAgICAgICAgICAgTWVkaWFuYT1tZWRpYW4oU2FsYXJpb19JbmljaWFsKSkNCg0KQmFzZUYxICU+JSANCiAgZ3JvdXBfYnkoUVJhbmtpbmcpICU+JSANCiAgc3VtbWFyaXNlKFNEPXNkKFNhbGFyaW9fSW5pY2lhbCksDQogICAgICAgICAgICBSYW5nbz1tYXgoU2FsYXJpb19JbmljaWFsKS1taW4oU2FsYXJpb19JbmljaWFsKSwNCiAgICAgICAgICAgIE5ncmFkdWFkb3MgPSBuKCksDQogICAgICAgICAgICBQZ3JhZHVhZG9zID0gbigpL25yb3coQmFzZUYxKSkNCg0KYGBgDQoNCiogUHJ1ZWJhIGRlIG5vcm1hbGlkYWQNCg0KYGBge3IsIG1lc3NhZ2U9RkFMU0V9DQoNCg0KYXR0YWNoKEJhc2VGMSkNCg0KDQpieShkYXRhID0gQmFzZUYxLElORElDRVMgPSBCYXNlRjEkUVJhbmtpbmcsRlVOID0gZnVuY3Rpb24oeCl7IGxpbGxpZS50ZXN0KHgkU2FsYXJpb19JbmljaWFsKX0pDQoNCg0KYGBgDQpFbCB1bm8gZGUgbG9zIGdydXBvcyBzZSBvYnNlcnZhIGZhbHRhIGRlIG5vcm1hbGlkYWQNCg0KKiBWYXJpYW56YSBjb25zdGFudGUgZW50cmUgZ3J1cG9zDQoNCmBgYHtyLCBtZXNzYWdlPUZBTFNFfQ0KDQphdHRhY2goQmFzZUYxKQ0KZmxpZ25lci50ZXN0KFNhbGFyaW9fSW5pY2lhbCB+IFFSYW5raW5nLEJhc2VGMSkNCg0KcmVxdWlyZShjYXIpDQpsZXZlbmVUZXN0KFNhbGFyaW9fSW5pY2lhbCB+IFFSYW5raW5nLEJhc2VGMSxjZW50ZXIgPSAibWVkaWFuIikNCmBgYA0KTm8gaGF5IGV2aWRlbmNpYXMgc2lnbmlmaWNhdGl2YXMgZGUgZmFsdGEgZGUgaG9tb2NlZGFzdGljaWRhZCBlbiBuaW5ndW5vIGRlIGxvcyBkb3MgdGVzdC4NCg0KKiBQcnVlYmEgZGUgbWVkaWFuYXMNCg0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIGV2YWw9RkFMU0UsIGVjaG89RkFMU0V9DQojUGFyYSBkYXRvcyBjb24gZGlzdHJpYnVjacOzbiBub3JtYWwNCg0KYW5vdmEgPC0gYW92KEJhc2VGMSRTYWxhcmlvX0luaWNpYWwgfiBCYXNlRjEkUVJhbmtpbmcpDQpzdW1tYXJ5KGFub3ZhKQ0KDQpwbG90KGFub3ZhKQ0KDQojIERhZG8gcXVlIGVsIHAtdmFsdWUgZXMgaW5mZXJpb3IgYSAwLjA1IGV4aXN0ZW4gZXZpZGVuY2lhcyBzdWZpY2llbnRlcyBwYXJhIGNvbnNpZGVyYXIgcXVlIGFsIG1lbm9zIGRvcyBtZWRpYXMgc29uIGRpc3RpbnRhcy4gTGEgcmVwcmVzZW50YWNpw7NuIGdyw6FmaWNhIGRlIGxvcyByZXNpZHVvcyBubyBtdWVzdHJhIGZhbHRhIGRlIGhvbW9jZWRhc3RpY2lkYWQgKGdyw6FmaWNvIDEpIHkgZW4gZWwgcXFwbG90IGxvcyByZXNpZHVvcyBzZSBkaXN0cmlidXllbiBtdXkgY2VyY2Fub3MgYSBsYSBsaW5lYSBkZSBsYSBub3JtYWwgKGdyw6FmaWNvIDIpLg0KDQpgYGANCg0KDQoNCiogUHJ1ZWJhIGRlIEtydXNrYWwgV2FsbGlzDQoNCmBgYHtyLCBtZXNzYWdlPUZBTFNFfQ0Ka3J1c2thbC50ZXN0KFNhbGFyaW9fSW5pY2lhbCB+IFFSYW5raW5nLCBkYXRhID0gQmFzZUYxKQ0KDQpgYGANClB2YWx1ZTwwLjA1LiBFeGlzdGUgZGlmZXJlbmNpYSBzaWduaWZpY2F0aXZhIGVuIGxhcyBtZWRpYW5hcyBkZSBwb3IgbG8gbWVub3MgZG9zIGdydXBvcy4NCg0KKiBDb21wYXJhY2lvbmVzIG3Dumx0aXBsZXMNCg0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIGV2YWw9RkFMU0UsIGVjaG89RkFMU0V9DQojUGFyYSBkYXRvcyBjb24gZGlzdHJpYnVjacOzbiBub3JtYWwNCnBhaXJ3aXNlLnQudGVzdCh4ID0gQmFzZUYxJFNhbGFyaW9fSW5pY2lhbCwgZyA9IEJhc2VGMSRRUmFua2luZywgcC5hZGp1c3QubWV0aG9kID0gImhvbG0iLA0KICAgICAgICAgICAgICAgIHBvb2wuc2QgPSBUUlVFLCBwYWlyZWQgPSBGQUxTRSwgYWx0ZXJuYXRpdmUgPSAidHdvLnNpZGVkIikNCg0KVHVrZXlIU0QoYW5vdmEpDQoNCnBsb3QoVHVrZXlIU0QoYW5vdmEpKQ0KYGBgDQoNCmBgYHtyLCBtZXNzYWdlPUZBTFNFfQ0KcGFpcndpc2Uud2lsY294LnRlc3QoQmFzZUYxJFNhbGFyaW9fSW5pY2lhbCwgQmFzZUYxJFFSYW5raW5nLCBwLmFkanVzdC5tZXRob2QgPSAiYm9uZiIsIHBhaXJlZCA9IEYpDQpgYGANCk5vIHNlIGVuY3VlbnRyYW4gZGlmZXJlbmNpYXMgc2lnbmlmaWNhdGl2YXMgZW50cmUgbG9zIGdydXBvcyBkb3MgYSBkb3MgKHAtdmFsdWU+MC4wNSkuDQoNCioqIFByZWd1bnRhczoNCg0KICAqIMK/RXhpc3RlIGRpZmVyZW5jaWEgc2lnbmlmaWNhdGl2YSBlbiBjdcOhbnRvIHB1ZWRlIGVzcGVyYXIgZ2FuYXIgdW4gICAgICAgZXN0dWRpYW50ZSwgcG9yIGVsIGfDqW5lcm8/IA0KDQogICogwr9FeGlzdGUgZGlmZXJlbmNpYSBzaWduaWZpY2F0aXZhIGVuIGN1w6FudG8gcHVlZGUgZXNwZXJhciBnYW5hciB1biAgICAgICBlc3R1ZGlhbnRlLCBwb3IgbGEgZWRhZD8NCiAgDQogICogwr9FeGlzdGUgZGlmZXJlbmNpYSBzaWduaWZpY2F0aXZhIGVuIGN1w6FudG8gcHVlZGUgZXNwZXJhciBnYW5hciB1biAgICAgICBlc3R1ZGlhbnRlLCBwb3IgbGEgZXhwZXJpZW5jaWEgbGFib3JhbD8NCiAgDQogICogwr9FeGlzdGUgZGlmZXJlbmNpYSBzaWduaWZpY2F0aXZhIGVuIGN1w6FudG8gcHVlZGUgZXNwZXJhciBnYW5hciB1biAgICAgICBlc3R1ZGlhbnRlLCBwb3IgbGEgbGVuZ3VhIG1hdGVybmE/DQogIA0KICBOb3RhOiBTaSBjb21wYXJhIHNvbG8gZG9zIGdydXBvcyB5IGxvcyBkYXRvcyBubyBzaWd1ZW4gdW5hICAgICAgZGlzdHJpYnVjacOzbiBub3JtYWwgdXRpbGl6YXIgbGEgUHJ1ZWJhIFUgZGUgTWFubi1XaGl0bmV5DQogIA0KIyMjICoqNC4gQ29uY2x1c2lvbmVzICoqDQogIA0KKiBDb25jbHVzacOzbiBnZW5lcmFsOg0KDQpEZWNpZGlyIHNvYnJlIGxhIGluc2NyaXBjacOzbiBhbCBwcm9ncmFtYSBkZSBNQkEgZW4gZXN0YSBlc2N1ZWxhIGVuIHBhcnRpY3VsYXIuDQoNCiogQ29uY2x1c2lvbmVzIGVzcGVjw61maWNhcw0KDQogIC0gRW4gZ2VuZXJhbCwgY3VhbmRvIHNlIGFuYWxpemFuIGEgbG9zIGdyYWR1YWRvcyBxdWUgY29udGVzdGFyb24gZWwgICAgICAgZGF0byBkZWwgc2FsYXJpbzsgb2JzZXJ2YW1vcyBxdWUgbG9zIGdyYWR1YWRvcyBwdWVkZW4gZXNwZXJhciBnYW5hciAgICAgJDg1LDAwMC4gUGVybywgc2kgYW5hbGl6YW1vcyBhIGxvcyBncmFkdWFkb3MgcXVlIHRpZW5lbiB1biBzYWxhcmlvICAgICAgaW5pY2lhbCwgZW50b25jZXMgcHVlZGVuIGVzcGVyYXIgZ2FuYXIgJDEwMCwwMDAuDQogIA0KICAtIEN1YW5kbyBhbmFsaXphbW9zIHNpIGV4aXN0ZW4gZGlmZXJlbmNpYXMgZW4gZWwgc2FsYXJpbyBwb3IgcmFua2luZy4gICAgIFNpIG9ic2VydmFtb3MgbG9zIGRhdG9zIGRlIG1hbmVyYSBkZXNjcmlwdGl2YSwgdmVtb3MgcXVlIGhheSAgICAgICAgICAgIGRpZmVyZW5jaWFzIGVudHJlIGxvcyBwcm9tZWRpb3MgZGUgbG9zIHNhbGFyaW9zIHBvciByYW5raW5nLiBTaW4gICAgICAgIGVtYmFyZ28sIHBhcmEgcG9kZXIgdGVuZXIgaGlww7N0ZXNpcyBwcmVsaW1pbmFyZXMgZ2VuZXJhbGl6YW5kbyBhIGxhICAgICBwb2JsYWNpw7NuLCBleGlzdGUgc3VmaWNpZW50ZSBldmlkZW5jaWEgcGFyYSBkZWNpciBxdWUgbm8gaGF5ICAgICAgICAgICAgICAgZGlmZXJlbmNpYXMgc2lnbmlmaWNhdGl2YXMgZW50cmUgbG9zIGdydXBvcyBkZSByYW5raW5nLiAgICAgIA0KICANCiAgDQogIA0K