Contexto

Una empresa vendedora de productos de bebidas en Guadalajara, y desea ver como se han comportado las ventas en los años 2016-2019, y también desea ver como serían las ventas en el 2020 de acuerdo con los datos de estos años.

Leer Base de Datos

#file.choose()
bd <- read.csv("/Users/eduardogarza/Desktop/S7/BootcampProgramaciónST/Datos Arca Continental Original.csv")

¿Que hay en la base de datos?

summary(bd)
##        ID              Año        Territorio        Sub.Territorio    
##  Min.   :     1   Min.   :2016   Length:466509      Length:466509     
##  1st Qu.:116628   1st Qu.:2017   Class :character   Class :character  
##  Median :233255   Median :2018   Mode  :character   Mode  :character  
##  Mean   :233255   Mean   :2018                                        
##  3rd Qu.:349882   3rd Qu.:2019                                        
##  Max.   :466509   Max.   :2019                                        
##      CEDI             Cliente             Nombre          Tamaño.Cte.Industria
##  Length:466509      Length:466509      Length:466509      Length:466509       
##  Class :character   Class :character   Class :character   Class :character    
##  Mode  :character   Mode  :character   Mode  :character   Mode  :character    
##                                                                               
##                                                                               
##                                                                               
##  Segmento.Det          Marca           Presentacion          Tamaño         
##  Length:466509      Length:466509      Length:466509      Length:466509     
##  Class :character   Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character   Mode  :character  
##                                                                             
##                                                                             
##                                                                             
##  Retornable_NR         Enero             Febrero             Marzo          
##  Length:466509      Length:466509      Length:466509      Length:466509     
##  Class :character   Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character   Mode  :character  
##                                                                             
##                                                                             
##                                                                             
##     Abril               Mayo              Junio              Julio          
##  Length:466509      Length:466509      Length:466509      Length:466509     
##  Class :character   Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character   Mode  :character  
##                                                                             
##                                                                             
##                                                                             
##     Agosto           Septiembre          Octubre           Noviembre        
##  Length:466509      Length:466509      Length:466509      Length:466509     
##  Class :character   Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character   Mode  :character  
##                                                                             
##                                                                             
##                                                                             
##   Diciembre        
##  Length:466509     
##  Class :character  
##  Mode  :character  
##                    
##                    
## 

Limpieza de base

library(janitor)
## 
## Attaching package: 'janitor'
## The following objects are masked from 'package:stats':
## 
##     chisq.test, fisher.test
library(dplyr)
## 
## 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
#count(bd,ID,sort=TRUE)
#count(bd,Año,sort=TRUE)
count(bd,Territorio,sort=TRUE)
##    Territorio      n
## 1 Guadalajara 466508
## 2  Territorio      1
#count(bd,Sub.Territorio,sort=TRUE)
#count(bd,CEDI,sort=TRUE)
#count(bd,Cliente,sort=TRUE)
#count(bd,Nombre,sort=TRUE)
#count(bd,Tamaño.Cte.Industria,sort=TRUE)
#count(bd,Segmento.Det,sort=TRUE)
#count(bd,Marca,sort=TRUE)
#count(bd,Presentacion,sort=TRUE)
#count(bd,Tamaño,sort=TRUE)
#count(bd,Retornable_NR,sort=TRUE)
#count(bd,Enero,sort=TRUE)
#count(bd,Febrero,sort=TRUE)
#count(bd,Marzo,sort=TRUE)
#count(bd,Abril,sort=TRUE)
#count(bd,Mayo,sort=TRUE)
#count(bd,Junio,sort=TRUE)
##count(bd,Julio,sort=TRUE)
#count(bd,Agosto,sort=TRUE)
#count(bd,Septiembre,sort=TRUE)
#count(bd,Octubre,sort=TRUE)
#count(bd,Noviembre,sort=TRUE)
#count(bd,Diciembre,sort=TRUE)

# Existe un renglon duplicado en el 184065, y hay que eliminarlo.

bd<-bd[-184065,]
bd$Enero <- as.integer(bd$Enero)
## Warning: NAs introduced by coercion
bd$Febrero <- as.integer(bd$Febrero)
## Warning: NAs introduced by coercion
bd$Marzo <- as.integer(bd$Marzo)
## Warning: NAs introduced by coercion
bd$Abril <- as.integer(bd$Abril)
## Warning: NAs introduced by coercion
bd$Mayo <- as.integer(bd$Mayo)
## Warning: NAs introduced by coercion
bd$Junio <- as.integer(bd$Junio)
## Warning: NAs introduced by coercion
bd$Julio <- as.integer(bd$Julio)
## Warning: NAs introduced by coercion
bd$Agosto <- as.integer(bd$Agosto)
## Warning: NAs introduced by coercion
bd$Septiembre <- as.integer(bd$Septiembre)
## Warning: NAs introduced by coercion
bd$Octubre <- as.integer(bd$Octubre)
## Warning: NAs introduced by coercion
bd$Noviembre <- as.integer(bd$Noviembre)
## Warning: NAs introduced by coercion
bd$Diciembre <- as.integer(bd$Diciembre)
## Warning: NAs introduced by coercion
str(bd)
## 'data.frame':    466508 obs. of  25 variables:
##  $ ID                  : int  1 2 3 4 5 6 7 8 9 10 ...
##  $ Año                 : int  2016 2016 2016 2016 2016 2016 2016 2016 2016 2016 ...
##  $ Territorio          : chr  "Guadalajara" "Guadalajara" "Guadalajara" "Guadalajara" ...
##  $ Sub.Territorio      : chr  "Belenes" "Belenes" "Belenes" "Belenes" ...
##  $ CEDI                : chr  "Suc. Belenes" "Suc. Belenes" "Suc. Belenes" "Suc. Belenes" ...
##  $ Cliente             : chr  "77737" "77737" "77737" "77737" ...
##  $ Nombre              : chr  "ABARR" "ABARR" "ABARR" "ABARR" ...
##  $ Tamaño.Cte.Industria: chr  "Extra Grande" "Extra Grande" "Extra Grande" "Extra Grande" ...
##  $ Segmento.Det        : chr  "Agua Mineral" "Agua Purificada" "Agua Purificada" "Agua Saborizada" ...
##  $ Marca               : chr  "Topo Chico A.M." "Ciel Agua Purificada" "Ciel Agua Purificada" "Ciel Exprim" ...
##  $ Presentacion        : chr  "600 ml NR" "1 Ltro. N.R." "1.5 Lts. NR" "600 ml NR" ...
##  $ Tamaño              : chr  "Individual" "Individual" "Individual" "Individual" ...
##  $ Retornable_NR       : chr  "No Retornable" "No Retornable" "No Retornable" "No Retornable" ...
##  $ Enero               : int  NA NA NA NA NA NA 1 NA 3 NA ...
##  $ Febrero             : int  NA 2 NA NA NA NA NA 1 3 NA ...
##  $ Marzo               : int  NA 8 3 NA NA 1 NA NA 4 NA ...
##  $ Abril               : int  NA 4 6 NA NA NA NA 1 4 NA ...
##  $ Mayo                : int  NA 4 3 NA NA NA 0 NA 4 NA ...
##  $ Junio               : int  NA 2 3 NA NA NA NA 1 4 0 ...
##  $ Julio               : int  NA 2 3 NA NA NA 0 NA 4 NA ...
##  $ Agosto              : int  NA 2 3 NA NA NA NA 1 7 NA ...
##  $ Septiembre          : int  NA 2 3 NA NA NA NA 1 4 NA ...
##  $ Octubre             : int  NA 2 3 NA NA NA 0 NA 3 NA ...
##  $ Noviembre           : int  NA 4 3 NA 0 NA NA NA 1 NA ...
##  $ Diciembre           : int  1 2 3 1 NA NA NA NA 3 NA ...
# Si hay NA's
# Hay cantidades nega
# Identificar cuantos NA's hay y reemplazar por ceros.

sum(is.na(bd))
## [1] 3149791
bd[is.na(bd)] <- 0
summary(bd)
##        ID              Año        Territorio        Sub.Territorio    
##  Min.   :     1   Min.   :2016   Length:466508      Length:466508     
##  1st Qu.:116628   1st Qu.:2017   Class :character   Class :character  
##  Median :233256   Median :2018   Mode  :character   Mode  :character  
##  Mean   :233255   Mean   :2018                                        
##  3rd Qu.:349882   3rd Qu.:2019                                        
##  Max.   :466509   Max.   :2019                                        
##      CEDI             Cliente             Nombre          Tamaño.Cte.Industria
##  Length:466508      Length:466508      Length:466508      Length:466508       
##  Class :character   Class :character   Class :character   Class :character    
##  Mode  :character   Mode  :character   Mode  :character   Mode  :character    
##                                                                               
##                                                                               
##                                                                               
##  Segmento.Det          Marca           Presentacion          Tamaño         
##  Length:466508      Length:466508      Length:466508      Length:466508     
##  Class :character   Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character   Mode  :character  
##                                                                             
##                                                                             
##                                                                             
##  Retornable_NR          Enero           Febrero            Marzo        
##  Length:466508      Min.   :-19.00   Min.   :-11.000   Min.   :-32.000  
##  Class :character   1st Qu.:  0.00   1st Qu.:  0.000   1st Qu.:  0.000  
##  Mode  :character   Median :  0.00   Median :  0.000   Median :  0.000  
##                     Mean   :  4.69   Mean   :  4.581   Mean   :  5.401  
##                     3rd Qu.:  2.00   3rd Qu.:  2.000   3rd Qu.:  3.000  
##                     Max.   :999.00   Max.   :986.000   Max.   :986.000  
##      Abril              Mayo              Junio            Julio        
##  Min.   :-70.000   Min.   :-106.000   Min.   :-211.0   Min.   :-60.000  
##  1st Qu.:  0.000   1st Qu.:   0.000   1st Qu.:   0.0   1st Qu.:  0.000  
##  Median :  0.000   Median :   0.000   Median :   0.0   Median :  0.000  
##  Mean   :  5.519   Mean   :   6.117   Mean   :   5.9   Mean   :  5.583  
##  3rd Qu.:  3.000   3rd Qu.:   3.000   3rd Qu.:   3.0   3rd Qu.:  3.000  
##  Max.   :993.000   Max.   : 991.000   Max.   : 998.0   Max.   :993.000  
##      Agosto           Septiembre          Octubre          Noviembre      
##  Min.   :-211.000   Min.   :-527.000   Min.   :-38.000   Min.   :-25.000  
##  1st Qu.:   0.000   1st Qu.:   0.000   1st Qu.:  0.000   1st Qu.:  0.000  
##  Median :   0.000   Median :   0.000   Median :  0.000   Median :  0.000  
##  Mean   :   5.777   Mean   :   3.311   Mean   :  3.327   Mean   :  3.248  
##  3rd Qu.:   3.000   3rd Qu.:   1.000   3rd Qu.:  1.000   3rd Qu.:  1.000  
##  Max.   : 999.000   Max.   : 993.000   Max.   :998.000   Max.   :991.000  
##    Diciembre      
##  Min.   :-28.000  
##  1st Qu.:  0.000  
##  Median :  0.000  
##  Mean   :  3.477  
##  3rd Qu.:  0.000  
##  Max.   :997.000

Observaciones.
Hay NA’s
Cantidades Negativas
No hay ventas anuales Cambiar formato de meses a valores enteros Hay muchos valores extremos, se creará un boxplot para ver si son outliers o no.

P1: Hay crecimiento en ventas a través de los años?

# Crear ventas anuales (suma de ventas por mes)
bd$Ventas <- (bd$Enero + bd$Febrero +bd$Marzo + bd$Abril + bd$Mayo + bd$Junio + bd$Julio + bd$Septiembre + bd$Octubre + bd$Noviembre + bd$Diciembre)

library(ggplot2)
ggplot(bd, aes(x=Año, y = Ventas)) +
         geom_bar(stat="identity") +
  labs(
    title= "Ventas Por Año"
  )

Se encontraron variables negativos en ventas, pero se van a dejar como negativos ya que no hay interpretación para una venta negativa.

R1: Se observó que sí hay un crecimiento en las ventas a lo largo de los años 2016-2019.

P2: Cual es la relación entre los tipos de clientes y el crecimiento en ventas.

library(ggplot2)
ggplot(bd, aes(x=Año, y = Ventas, colour=Tamaño.Cte.Industria)) +
         geom_bar(stat="identity") +
  labs(
    title= "Ventas Por Tipo de Clientes"
  )

eg <- bd %>% filter(Tamaño.Cte.Industria =="Extra Grande")
ggplot(eg, aes(x=Año, y = Ventas, colour=Tamaño.Cte.Industria)) +
         geom_bar(stat="identity") +
  labs(
    title= "Ventas de Cliente Extra Grande"
  )

g <- bd %>% filter(Tamaño.Cte.Industria =="Grande")
ggplot(g, aes(x=Año, y = Ventas, colour=Tamaño.Cte.Industria)) +
         geom_bar(stat="identity") +
  labs(
    title= "Ventas de Cliente Grande"
  )

m <- bd %>% filter(Tamaño.Cte.Industria =="Micro")
ggplot(m, aes(x=Año, y = Ventas, colour=Tamaño.Cte.Industria)) +
         geom_bar(stat="identity") +
  labs(
    title= "Ventas de Cliente Micro"
  )

p <- bd %>% filter(Tamaño.Cte.Industria =="Pequeño")
ggplot(p, aes(x=Año, y = Ventas, colour=Tamaño.Cte.Industria)) +
         geom_bar(stat="identity") +
  labs(
    title= "Ventas de Cliente Pequeño"
  )

R2: A través de los años, hubo un incremento en las ventas a los clientes Extra Grande y Micro, y en el año 2019 se consiguieron clientes en las secciones de Grandes y Pequeños.

P3: Comportamiento de ventas por mes por marcas.

library(ggplot2)
coca<- bd %>% filter(Marca=="Coca-Cola")

ggplot(coca, aes(x= Año, y = Ventas, colour=Tamaño.Cte.Industria)) +
         geom_bar(stat="identity") +
  labs(
    title= "Ventas Anuales de Coca Cola"
)

sp<- bd %>% filter(Marca=="Sprite")

ggplot(sp, aes(x= Año, y = Ventas, colour=Tamaño.Cte.Industria)) +
         geom_bar(stat="identity") +
  labs(
    title= "Ventas Anuales de Sprite"
)

R3: Ha habido un incremento en las ventas de Sprite y Coca-Cola en los pasados cuatro años, Sprite y Coca-Cola son las marcas más vendidas

P4: Se ha incrementado la venta de productos en envases retornables en 2018 y 2019.

library(ggplot2)
ggplot(bd, aes(x= Año, y = Ventas, colour= Retornable_NR)) +
         geom_bar(stat="identity") +
  labs(
    title= "Ventas Por Año"
)

R4: Sí, se ha incrementado la venta de envases retornables de 2018-2019.

P5: Comportamiento de venta de agua vs refrescos o bebidas isotónicas.

#bd1<- bd %>% filter(Segmento.Det =="Agua Purificada" | Segmento.Det == "Isotónicos Regular"| Segmento.Det == "Isotónicos Light"| Segmento.Det == "Colas Light"| Segmento.Det == "Colas Regular")
library(ggplot2)
#ggplot(bd1, aes(x= Año, y = Ventas, colour= Segmento.Det)) +
#         geom_bar(stat="identity") +
#  labs(
#    title= "Ventas Por Año"
#)

ap <- bd %>% filter(Segmento.Det =="Agua Purificada")
ggplot(ap, aes(x= Año, y = Ventas,)) +
         geom_bar(stat="identity") +
  labs(
    title= "Ventas de Agua"
)

ir <- bd %>% filter(Segmento.Det =="Isotónicos Regular")
ggplot(ir, aes(x= Año, y = Ventas)) +
         geom_bar(stat="identity") +
  labs(
    title= "Ventas de Isotónicos Regular"
)

il <- bd %>% filter(Segmento.Det =="Isotónicos Light")
ggplot(il, aes(x= Año, y = Ventas,)) +
         geom_bar(stat="identity") +
  labs(
    title= "Ventas de Isotónico Light"
)

cl <- bd %>% filter(Segmento.Det =="Colas Light")
ggplot(cl, aes(x= Año, y = Ventas,)) +
         geom_bar(stat="identity") +
  labs(
    title= "Ventas de Colas Light"
)

cr <- bd %>% filter(Segmento.Det =="Colas Regular")
ggplot(cr, aes(x= Año, y = Ventas,)) +
         geom_bar(stat="identity") +
  labs(
    title= "Ventas de Colas Regular"
)

df9 <- bd %>% filter(Segmento.Det =="Agua Purificada"| Segmento.Det == "Isotónicos Regular"|Segmento.Det =="Colas Regular"|Segmento.Det =="Colas Light"|Segmento.Det =="Isotónicos Light")
ggplot(df9, aes(x= Año, y = Ventas, fill=Segmento.Det)) +
         geom_bar(stat="identity", position = "dodge") +
  labs(
    title= "Ventas de Agua, Refrescos y Isotónicos"
)

R5: Las ventas por año de agua purificada disminuyeron en el ultimo año, y también las ventas de refrescos, pero subieron las ventas de isotónicos regulares de 2018 - 2019.

P6: ¿Ventas mensuales de agua se relaciona con la venta mensual de refrescos?

acc <- bd %>% filter(Segmento.Det =="Agua Purificada"|Segmento.Det =="Colas Regular"|Segmento.Det =="Colas Light")
ggplot(acc, aes(x= Año, y = Ventas, fill=Segmento.Det)) +
         geom_bar(stat="identity", position = "dodge") +
  labs(
    title= "Ventas de Agua, Refrescos y Isotónicos"
)

R6: En esta gráfica, yo observo que están ligeramente relacionados los conmportamientos de las ventas de Agua y de refrescos. Ya que solamente de 2016-2017 se osbervan comportamientos diferentes.

P7: ¿A cuanto ascienden las ventas esperadas para 2020 de coca cola de 500 ml nr vidrio?

p7 <- bd %>% filter(Marca =="Coca-Cola" & Presentacion =="500 ml NR Vidrio")

sva <- aggregate(Ventas  ~ Año,p7, sum)
#sva$Año <- as.integer(sva$Año)
ventas2020 <- lm(Ventas ~ Año, data=sva)

summary(ventas2020)
## 
## Call:
## lm(formula = Ventas ~ Año, data = sva)
## 
## Residuals:
##      1      2      3      4 
## -25706  32140  12838 -19272 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)
## (Intercept) -38345512   30127807  -1.273    0.331
## Año             19174      14933   1.284    0.328
## 
## Residual standard error: 33390 on 2 degrees of freedom
## Multiple R-squared:  0.4518, Adjusted R-squared:  0.1778 
## F-statistic: 1.649 on 1 and 2 DF,  p-value: 0.3278
ventas2020
## 
## Call:
## lm(formula = Ventas ~ Año, data = sva)
## 
## Coefficients:
## (Intercept)          Año  
##   -38345512        19174
#Ecuación de regresión, -38345512 + 19174*Año

datos <- data.frame(Año = 2020)
predict(ventas2020, datos)
##        1 
## 385160.5

R7: De acuerdo al modelo predictivo usando regresión lineal, las ventas esperadas para coca cola de 500 ml nr de vidrio en 2020, serán de 385,160 unidades con una R^2 ajustada del 17.78%.

LS0tCnRpdGxlOiAiU1AyIgphdXRob3I6ICJFZHVhcmRvIC0gQTAwODMxNDQ3IgpkYXRlOiAnMjAyMy0wOS0xMycKb3V0cHV0OiAKICBodG1sX2RvY3VtZW50OiAKICAgIHRvYzogVFJVRQogICAgdG9jX2Zsb2F0OiBUUlVFCiAgICBjb2RlX2Rvd25sb2FkOiBUUlVFCiAgICB0aGVtZTogInNpbXBsZXgiCiAgICBoaWdobGlnaHQ6ICJ0YW5nbyIKLS0tCiFbXSgvVXNlcnMvZWR1YXJkb2dhcnphL0Rlc2t0b3AvQXJjYV9Db250aW5lbnRhbF9sb2dvLnN2Zy5wbmcpCgoKIyMgQ29udGV4dG8KClVuYSBlbXByZXNhIHZlbmRlZG9yYSBkZSBwcm9kdWN0b3MgZGUgYmViaWRhcyBlbiBHdWFkYWxhamFyYSwgeSBkZXNlYSB2ZXIgY29tbyBzZSBoYW4gY29tcG9ydGFkbyBsYXMgdmVudGFzIGVuIGxvcyBhw7FvcyAyMDE2LTIwMTksIHkgdGFtYmnDqW4gZGVzZWEgdmVyIGNvbW8gc2Vyw61hbiBsYXMgdmVudGFzIGVuIGVsIDIwMjAgZGUgYWN1ZXJkbyBjb24gbG9zIGRhdG9zIGRlIGVzdG9zIGHDsW9zLiAKCgojIyBMZWVyIEJhc2UgZGUgRGF0b3MKCmBgYHtyfQojZmlsZS5jaG9vc2UoKQpiZCA8LSByZWFkLmNzdigiL1VzZXJzL2VkdWFyZG9nYXJ6YS9EZXNrdG9wL1M3L0Jvb3RjYW1wUHJvZ3JhbWFjaW/MgW5TVC9EYXRvcyBBcmNhIENvbnRpbmVudGFsIE9yaWdpbmFsLmNzdiIpCmBgYAoKIyMjIMK/UXVlIGhheSBlbiBsYSBiYXNlIGRlIGRhdG9zPwoKYGBge3J9CnN1bW1hcnkoYmQpCmBgYAojIyMgTGltcGllemEgZGUgYmFzZQpgYGB7cn0KbGlicmFyeShqYW5pdG9yKQpsaWJyYXJ5KGRwbHlyKQoKI2NvdW50KGJkLElELHNvcnQ9VFJVRSkKI2NvdW50KGJkLEHDsW8sc29ydD1UUlVFKQpjb3VudChiZCxUZXJyaXRvcmlvLHNvcnQ9VFJVRSkKI2NvdW50KGJkLFN1Yi5UZXJyaXRvcmlvLHNvcnQ9VFJVRSkKI2NvdW50KGJkLENFREksc29ydD1UUlVFKQojY291bnQoYmQsQ2xpZW50ZSxzb3J0PVRSVUUpCiNjb3VudChiZCxOb21icmUsc29ydD1UUlVFKQojY291bnQoYmQsVGFtYcOxby5DdGUuSW5kdXN0cmlhLHNvcnQ9VFJVRSkKI2NvdW50KGJkLFNlZ21lbnRvLkRldCxzb3J0PVRSVUUpCiNjb3VudChiZCxNYXJjYSxzb3J0PVRSVUUpCiNjb3VudChiZCxQcmVzZW50YWNpb24sc29ydD1UUlVFKQojY291bnQoYmQsVGFtYcOxbyxzb3J0PVRSVUUpCiNjb3VudChiZCxSZXRvcm5hYmxlX05SLHNvcnQ9VFJVRSkKI2NvdW50KGJkLEVuZXJvLHNvcnQ9VFJVRSkKI2NvdW50KGJkLEZlYnJlcm8sc29ydD1UUlVFKQojY291bnQoYmQsTWFyem8sc29ydD1UUlVFKQojY291bnQoYmQsQWJyaWwsc29ydD1UUlVFKQojY291bnQoYmQsTWF5byxzb3J0PVRSVUUpCiNjb3VudChiZCxKdW5pbyxzb3J0PVRSVUUpCiMjY291bnQoYmQsSnVsaW8sc29ydD1UUlVFKQojY291bnQoYmQsQWdvc3RvLHNvcnQ9VFJVRSkKI2NvdW50KGJkLFNlcHRpZW1icmUsc29ydD1UUlVFKQojY291bnQoYmQsT2N0dWJyZSxzb3J0PVRSVUUpCiNjb3VudChiZCxOb3ZpZW1icmUsc29ydD1UUlVFKQojY291bnQoYmQsRGljaWVtYnJlLHNvcnQ9VFJVRSkKCiMgRXhpc3RlIHVuIHJlbmdsb24gZHVwbGljYWRvIGVuIGVsIDE4NDA2NSwgeSBoYXkgcXVlIGVsaW1pbmFybG8uCgpiZDwtYmRbLTE4NDA2NSxdCmJkJEVuZXJvIDwtIGFzLmludGVnZXIoYmQkRW5lcm8pCmJkJEZlYnJlcm8gPC0gYXMuaW50ZWdlcihiZCRGZWJyZXJvKQpiZCRNYXJ6byA8LSBhcy5pbnRlZ2VyKGJkJE1hcnpvKQpiZCRBYnJpbCA8LSBhcy5pbnRlZ2VyKGJkJEFicmlsKQpiZCRNYXlvIDwtIGFzLmludGVnZXIoYmQkTWF5bykKYmQkSnVuaW8gPC0gYXMuaW50ZWdlcihiZCRKdW5pbykKYmQkSnVsaW8gPC0gYXMuaW50ZWdlcihiZCRKdWxpbykKYmQkQWdvc3RvIDwtIGFzLmludGVnZXIoYmQkQWdvc3RvKQpiZCRTZXB0aWVtYnJlIDwtIGFzLmludGVnZXIoYmQkU2VwdGllbWJyZSkKYmQkT2N0dWJyZSA8LSBhcy5pbnRlZ2VyKGJkJE9jdHVicmUpCmJkJE5vdmllbWJyZSA8LSBhcy5pbnRlZ2VyKGJkJE5vdmllbWJyZSkKYmQkRGljaWVtYnJlIDwtIGFzLmludGVnZXIoYmQkRGljaWVtYnJlKQpzdHIoYmQpCgojIFNpIGhheSBOQSdzCiMgSGF5IGNhbnRpZGFkZXMgbmVnYQojIElkZW50aWZpY2FyIGN1YW50b3MgTkEncyBoYXkgeSByZWVtcGxhemFyIHBvciBjZXJvcy4KCnN1bShpcy5uYShiZCkpCmJkW2lzLm5hKGJkKV0gPC0gMApzdW1tYXJ5KGJkKQoKCgoKYGBgCgpPYnNlcnZhY2lvbmVzLiAgCkhheSBOQSdzICAgCkNhbnRpZGFkZXMgTmVnYXRpdmFzICAgCk5vIGhheSB2ZW50YXMgYW51YWxlcwpDYW1iaWFyIGZvcm1hdG8gZGUgbWVzZXMgYSB2YWxvcmVzIGVudGVyb3MKSGF5IG11Y2hvcyB2YWxvcmVzIGV4dHJlbW9zLCBzZSBjcmVhcsOhIHVuIGJveHBsb3QgcGFyYSB2ZXIgc2kgc29uIG91dGxpZXJzIG8gbm8uIAoKCiMjIFAxOiBIYXkgY3JlY2ltaWVudG8gZW4gdmVudGFzIGEgdHJhdsOpcyBkZSBsb3MgYcOxb3M/CmBgYHtyfQojIENyZWFyIHZlbnRhcyBhbnVhbGVzIChzdW1hIGRlIHZlbnRhcyBwb3IgbWVzKQpiZCRWZW50YXMgPC0gKGJkJEVuZXJvICsgYmQkRmVicmVybyArYmQkTWFyem8gKyBiZCRBYnJpbCArIGJkJE1heW8gKyBiZCRKdW5pbyArIGJkJEp1bGlvICsgYmQkU2VwdGllbWJyZSArIGJkJE9jdHVicmUgKyBiZCROb3ZpZW1icmUgKyBiZCREaWNpZW1icmUpCgpsaWJyYXJ5KGdncGxvdDIpCmdncGxvdChiZCwgYWVzKHg9QcOxbywgeSA9IFZlbnRhcykpICsKICAgICAgICAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiKSArCiAgbGFicygKICAgIHRpdGxlPSAiVmVudGFzIFBvciBBw7FvIgogICkKYGBgCgpTZSBlbmNvbnRyYXJvbiB2YXJpYWJsZXMgbmVnYXRpdm9zIGVuIHZlbnRhcywgcGVybyBzZSB2YW4gYSBkZWphciBjb21vIG5lZ2F0aXZvcyB5YSBxdWUgbm8gaGF5IGludGVycHJldGFjacOzbiBwYXJhIHVuYSB2ZW50YSBuZWdhdGl2YS4KCioqUjE6IFNlIG9ic2VydsOzIHF1ZSBzw60gaGF5IHVuIGNyZWNpbWllbnRvIGVuIGxhcyB2ZW50YXMgYSBsbyBsYXJnbyBkZSBsb3MgYcOxb3MgMjAxNi0yMDE5LioqCgoKIyMgUDI6IEN1YWwgZXMgbGEgcmVsYWNpw7NuIGVudHJlIGxvcyB0aXBvcyBkZSBjbGllbnRlcyB5IGVsIGNyZWNpbWllbnRvIGVuIHZlbnRhcy4KYGBge3J9CmxpYnJhcnkoZ2dwbG90MikKZ2dwbG90KGJkLCBhZXMoeD1Bw7FvLCB5ID0gVmVudGFzLCBjb2xvdXI9VGFtYcOxby5DdGUuSW5kdXN0cmlhKSkgKwogICAgICAgICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIpICsKICBsYWJzKAogICAgdGl0bGU9ICJWZW50YXMgUG9yIFRpcG8gZGUgQ2xpZW50ZXMiCiAgKQoKZWcgPC0gYmQgJT4lIGZpbHRlcihUYW1hw7FvLkN0ZS5JbmR1c3RyaWEgPT0iRXh0cmEgR3JhbmRlIikKZ2dwbG90KGVnLCBhZXMoeD1Bw7FvLCB5ID0gVmVudGFzLCBjb2xvdXI9VGFtYcOxby5DdGUuSW5kdXN0cmlhKSkgKwogICAgICAgICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIpICsKICBsYWJzKAogICAgdGl0bGU9ICJWZW50YXMgZGUgQ2xpZW50ZSBFeHRyYSBHcmFuZGUiCiAgKQpnIDwtIGJkICU+JSBmaWx0ZXIoVGFtYcOxby5DdGUuSW5kdXN0cmlhID09IkdyYW5kZSIpCmdncGxvdChnLCBhZXMoeD1Bw7FvLCB5ID0gVmVudGFzLCBjb2xvdXI9VGFtYcOxby5DdGUuSW5kdXN0cmlhKSkgKwogICAgICAgICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIpICsKICBsYWJzKAogICAgdGl0bGU9ICJWZW50YXMgZGUgQ2xpZW50ZSBHcmFuZGUiCiAgKQoKCm0gPC0gYmQgJT4lIGZpbHRlcihUYW1hw7FvLkN0ZS5JbmR1c3RyaWEgPT0iTWljcm8iKQpnZ3Bsb3QobSwgYWVzKHg9QcOxbywgeSA9IFZlbnRhcywgY29sb3VyPVRhbWHDsW8uQ3RlLkluZHVzdHJpYSkpICsKICAgICAgICAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiKSArCiAgbGFicygKICAgIHRpdGxlPSAiVmVudGFzIGRlIENsaWVudGUgTWljcm8iCiAgKQoKcCA8LSBiZCAlPiUgZmlsdGVyKFRhbWHDsW8uQ3RlLkluZHVzdHJpYSA9PSJQZXF1ZcOxbyIpCmdncGxvdChwLCBhZXMoeD1Bw7FvLCB5ID0gVmVudGFzLCBjb2xvdXI9VGFtYcOxby5DdGUuSW5kdXN0cmlhKSkgKwogICAgICAgICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIpICsKICBsYWJzKAogICAgdGl0bGU9ICJWZW50YXMgZGUgQ2xpZW50ZSBQZXF1ZcOxbyIKICApCgoKCmBgYAoqKlIyOiBBIHRyYXbDqXMgZGUgbG9zIGHDsW9zLCBodWJvIHVuIGluY3JlbWVudG8gZW4gbGFzIHZlbnRhcyBhIGxvcyBjbGllbnRlcyBFeHRyYSBHcmFuZGUgeSBNaWNybywgeSBlbiBlbCBhw7FvIDIwMTkgc2UgY29uc2lndWllcm9uIGNsaWVudGVzIGVuIGxhcyBzZWNjaW9uZXMgZGUgR3JhbmRlcyB5IFBlcXVlw7Fvcy4qKiAKCiMjIFAzOiBDb21wb3J0YW1pZW50byBkZSB2ZW50YXMgcG9yIG1lcyBwb3IgbWFyY2FzLgpgYGB7cn0KbGlicmFyeShnZ3Bsb3QyKQpjb2NhPC0gYmQgJT4lIGZpbHRlcihNYXJjYT09IkNvY2EtQ29sYSIpCgpnZ3Bsb3QoY29jYSwgYWVzKHg9IEHDsW8sIHkgPSBWZW50YXMsIGNvbG91cj1UYW1hw7FvLkN0ZS5JbmR1c3RyaWEpKSArCiAgICAgICAgIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IikgKwogIGxhYnMoCiAgICB0aXRsZT0gIlZlbnRhcyBBbnVhbGVzIGRlIENvY2EgQ29sYSIKKQoKc3A8LSBiZCAlPiUgZmlsdGVyKE1hcmNhPT0iU3ByaXRlIikKCmdncGxvdChzcCwgYWVzKHg9IEHDsW8sIHkgPSBWZW50YXMsIGNvbG91cj1UYW1hw7FvLkN0ZS5JbmR1c3RyaWEpKSArCiAgICAgICAgIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IikgKwogIGxhYnMoCiAgICB0aXRsZT0gIlZlbnRhcyBBbnVhbGVzIGRlIFNwcml0ZSIKKQoKYGBgCgoKKipSMzogSGEgaGFiaWRvIHVuIGluY3JlbWVudG8gZW4gbGFzIHZlbnRhcyBkZSBTcHJpdGUgeSBDb2NhLUNvbGEgZW4gbG9zIHBhc2Fkb3MgY3VhdHJvIGHDsW9zLCBTcHJpdGUgeSBDb2NhLUNvbGEgc29uIGxhcyBtYXJjYXMgbcOhcyB2ZW5kaWRhcyoqCgojIyBQNDogU2UgaGEgaW5jcmVtZW50YWRvIGxhIHZlbnRhIGRlIHByb2R1Y3RvcyBlbiBlbnZhc2VzIHJldG9ybmFibGVzIGVuIDIwMTggeSAyMDE5LgpgYGB7cn0KbGlicmFyeShnZ3Bsb3QyKQpnZ3Bsb3QoYmQsIGFlcyh4PSBBw7FvLCB5ID0gVmVudGFzLCBjb2xvdXI9IFJldG9ybmFibGVfTlIpKSArCiAgICAgICAgIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IikgKwogIGxhYnMoCiAgICB0aXRsZT0gIlZlbnRhcyBQb3IgQcOxbyIKKQpgYGAKCgoqKlI0OiBTw60sIHNlIGhhIGluY3JlbWVudGFkbyBsYSB2ZW50YSBkZSBlbnZhc2VzIHJldG9ybmFibGVzIGRlIDIwMTgtMjAxOS4qKiAKCiMjIFA1OiBDb21wb3J0YW1pZW50byBkZSB2ZW50YSBkZSBhZ3VhIHZzIHJlZnJlc2NvcyBvIGJlYmlkYXMgaXNvdMOzbmljYXMuCmBgYHtyfQojYmQxPC0gYmQgJT4lIGZpbHRlcihTZWdtZW50by5EZXQgPT0iQWd1YSBQdXJpZmljYWRhIiB8IFNlZ21lbnRvLkRldCA9PSAiSXNvdMOzbmljb3MgUmVndWxhciJ8IFNlZ21lbnRvLkRldCA9PSAiSXNvdMOzbmljb3MgTGlnaHQifCBTZWdtZW50by5EZXQgPT0gIkNvbGFzIExpZ2h0InwgU2VnbWVudG8uRGV0ID09ICJDb2xhcyBSZWd1bGFyIikKbGlicmFyeShnZ3Bsb3QyKQojZ2dwbG90KGJkMSwgYWVzKHg9IEHDsW8sIHkgPSBWZW50YXMsIGNvbG91cj0gU2VnbWVudG8uRGV0KSkgKwojICAgICAgICAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiKSArCiMgIGxhYnMoCiMgICAgdGl0bGU9ICJWZW50YXMgUG9yIEHDsW8iCiMpCgphcCA8LSBiZCAlPiUgZmlsdGVyKFNlZ21lbnRvLkRldCA9PSJBZ3VhIFB1cmlmaWNhZGEiKQpnZ3Bsb3QoYXAsIGFlcyh4PSBBw7FvLCB5ID0gVmVudGFzLCkpICsKICAgICAgICAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiKSArCiAgbGFicygKICAgIHRpdGxlPSAiVmVudGFzIGRlIEFndWEiCikKaXIgPC0gYmQgJT4lIGZpbHRlcihTZWdtZW50by5EZXQgPT0iSXNvdMOzbmljb3MgUmVndWxhciIpCmdncGxvdChpciwgYWVzKHg9IEHDsW8sIHkgPSBWZW50YXMpKSArCiAgICAgICAgIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IikgKwogIGxhYnMoCiAgICB0aXRsZT0gIlZlbnRhcyBkZSBJc290w7NuaWNvcyBSZWd1bGFyIgopCmlsIDwtIGJkICU+JSBmaWx0ZXIoU2VnbWVudG8uRGV0ID09Iklzb3TDs25pY29zIExpZ2h0IikKZ2dwbG90KGlsLCBhZXMoeD0gQcOxbywgeSA9IFZlbnRhcywpKSArCiAgICAgICAgIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IikgKwogIGxhYnMoCiAgICB0aXRsZT0gIlZlbnRhcyBkZSBJc290w7NuaWNvIExpZ2h0IgopCmNsIDwtIGJkICU+JSBmaWx0ZXIoU2VnbWVudG8uRGV0ID09IkNvbGFzIExpZ2h0IikKZ2dwbG90KGNsLCBhZXMoeD0gQcOxbywgeSA9IFZlbnRhcywpKSArCiAgICAgICAgIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IikgKwogIGxhYnMoCiAgICB0aXRsZT0gIlZlbnRhcyBkZSBDb2xhcyBMaWdodCIKKQpjciA8LSBiZCAlPiUgZmlsdGVyKFNlZ21lbnRvLkRldCA9PSJDb2xhcyBSZWd1bGFyIikKZ2dwbG90KGNyLCBhZXMoeD0gQcOxbywgeSA9IFZlbnRhcywpKSArCiAgICAgICAgIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IikgKwogIGxhYnMoCiAgICB0aXRsZT0gIlZlbnRhcyBkZSBDb2xhcyBSZWd1bGFyIgopCgpkZjkgPC0gYmQgJT4lIGZpbHRlcihTZWdtZW50by5EZXQgPT0iQWd1YSBQdXJpZmljYWRhInwgU2VnbWVudG8uRGV0ID09ICJJc290w7NuaWNvcyBSZWd1bGFyInxTZWdtZW50by5EZXQgPT0iQ29sYXMgUmVndWxhciJ8U2VnbWVudG8uRGV0ID09IkNvbGFzIExpZ2h0InxTZWdtZW50by5EZXQgPT0iSXNvdMOzbmljb3MgTGlnaHQiKQpnZ3Bsb3QoZGY5LCBhZXMoeD0gQcOxbywgeSA9IFZlbnRhcywgZmlsbD1TZWdtZW50by5EZXQpKSArCiAgICAgICAgIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IiwgcG9zaXRpb24gPSAiZG9kZ2UiKSArCiAgbGFicygKICAgIHRpdGxlPSAiVmVudGFzIGRlIEFndWEsIFJlZnJlc2NvcyB5IElzb3TDs25pY29zIgopCmBgYAoKCioqUjU6IExhcyB2ZW50YXMgcG9yIGHDsW8gZGUgYWd1YSBwdXJpZmljYWRhIGRpc21pbnV5ZXJvbiBlbiBlbCB1bHRpbW8gYcOxbywgeSB0YW1iacOpbiBsYXMgdmVudGFzIGRlIHJlZnJlc2NvcywgcGVybyBzdWJpZXJvbiBsYXMgdmVudGFzIGRlIGlzb3TDs25pY29zIHJlZ3VsYXJlcyBkZSAyMDE4IC0gMjAxOS4qKiAKCgojIyBQNjogwr9WZW50YXMgbWVuc3VhbGVzIGRlIGFndWEgc2UgcmVsYWNpb25hIGNvbiBsYSB2ZW50YSBtZW5zdWFsIGRlIHJlZnJlc2Nvcz8KCmBgYHtyfQphY2MgPC0gYmQgJT4lIGZpbHRlcihTZWdtZW50by5EZXQgPT0iQWd1YSBQdXJpZmljYWRhInxTZWdtZW50by5EZXQgPT0iQ29sYXMgUmVndWxhciJ8U2VnbWVudG8uRGV0ID09IkNvbGFzIExpZ2h0IikKZ2dwbG90KGFjYywgYWVzKHg9IEHDsW8sIHkgPSBWZW50YXMsIGZpbGw9U2VnbWVudG8uRGV0KSkgKwogICAgICAgICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIsIHBvc2l0aW9uID0gImRvZGdlIikgKwogIGxhYnMoCiAgICB0aXRsZT0gIlZlbnRhcyBkZSBBZ3VhLCBSZWZyZXNjb3MgeSBJc290w7NuaWNvcyIKKQoKCmBgYAoKCioqUjY6IEVuIGVzdGEgZ3LDoWZpY2EsIHlvIG9ic2Vydm8gcXVlIGVzdMOhbiBsaWdlcmFtZW50ZSByZWxhY2lvbmFkb3MgbG9zIGNvbm1wb3J0YW1pZW50b3MgZGUgbGFzIHZlbnRhcyBkZSBBZ3VhIHkgZGUgcmVmcmVzY29zLiBZYSBxdWUgc29sYW1lbnRlIGRlIDIwMTYtMjAxNyBzZSBvc2JlcnZhbiBjb21wb3J0YW1pZW50b3MgZGlmZXJlbnRlcy4qKgoKIyMgUDc6IMK/QSBjdWFudG8gYXNjaWVuZGVuIGxhcyB2ZW50YXMgZXNwZXJhZGFzIHBhcmEgMjAyMCBkZSBjb2NhIGNvbGEgZGUgNTAwIG1sIG5yIHZpZHJpbz8KCgpgYGB7cn0KcDcgPC0gYmQgJT4lIGZpbHRlcihNYXJjYSA9PSJDb2NhLUNvbGEiICYgUHJlc2VudGFjaW9uID09IjUwMCBtbCBOUiBWaWRyaW8iKQoKc3ZhIDwtIGFnZ3JlZ2F0ZShWZW50YXMgIH4gQcOxbyxwNywgc3VtKQojc3ZhJEHDsW8gPC0gYXMuaW50ZWdlcihzdmEkQcOxbykKdmVudGFzMjAyMCA8LSBsbShWZW50YXMgfiBBw7FvLCBkYXRhPXN2YSkKCnN1bW1hcnkodmVudGFzMjAyMCkKdmVudGFzMjAyMAoKI0VjdWFjacOzbiBkZSByZWdyZXNpw7NuLCAtMzgzNDU1MTIgKyAxOTE3NCpBw7FvCgpkYXRvcyA8LSBkYXRhLmZyYW1lKEHDsW8gPSAyMDIwKQpwcmVkaWN0KHZlbnRhczIwMjAsIGRhdG9zKQpgYGAKCioqUjc6IERlIGFjdWVyZG8gYWwgbW9kZWxvIHByZWRpY3Rpdm8gdXNhbmRvIHJlZ3Jlc2nDs24gbGluZWFsLCBsYXMgdmVudGFzIGVzcGVyYWRhcyBwYXJhIGNvY2EgY29sYSBkZSA1MDAgbWwgbnIgZGUgdmlkcmlvIGVuIDIwMjAsIHNlcsOhbiBkZSAzODUsMTYwIHVuaWRhZGVzIGNvbiB1bmEgUl4yIGFqdXN0YWRhIGRlbCAxNy43OCUuKioK