Contexto

Utilizar la informacion recolectada como los tickets de los consumidores en los puntos de ventas para permitir la implementacion de tecnicas de analitica avanzada de datos para diseñar estrategias que permitan ofrecer un mejor servicios y promociones a sus tenderos

Importar datos

#file.choose()
df <- read.csv("C:\\Users\\rtorr\\Downloads\\arca.csv")

Entender

resumen<-summary(df)
resumen
##        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  
##                    
##                    
## 
#count(df, Territorio, sort =TRUE)
#count(df, Sub.Territorio, sort =TRUE)
#count(df, CEDI, sort =TRUE)
#count(df, Cliente, sort =TRUE)
#count(df, Nombre, sort =TRUE)
#count(df, Tamaño.Cte.Industria, sort =TRUE)
#count(df, Segmento.Det, sort =TRUE)
#count(df, Marca, sort =TRUE)
#count(df, Presentacion, sort =TRUE)
#count(df, Tamaño, sort =TRUE)
#count(df, Retornable_NR, sort =TRUE)

Observaciones:
1. Eliminar reglon 184065 que tiene titulos en lugar de datos.
2. Cambiar formato (de Enero a Diciembre) de caracter a entero.

Limpieza

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(df,Territorio,sort=TRUE)
##    Territorio      n
## 1 Guadalajara 466508
## 2  Territorio      1
df<-df[-184065,]
df$Enero <- as.numeric(df$Enero)
## Warning: NAs introducidos por coerción
df$Febrero <- as.numeric(df$Febrero)
## Warning: NAs introducidos por coerción
df$Marzo <- as.numeric(df$Marzo)
## Warning: NAs introducidos por coerción
df$Abril <- as.numeric(df$Abril)
## Warning: NAs introducidos por coerción
df$Mayo <- as.numeric(df$Mayo)
## Warning: NAs introducidos por coerción
df$Junio <- as.numeric(df$Junio)
## Warning: NAs introducidos por coerción
df$Julio <- as.numeric(df$Julio)
## Warning: NAs introducidos por coerción
df$Agosto <- as.numeric(df$Agosto)
## Warning: NAs introducidos por coerción
df$Septiembre <- as.numeric(df$Septiembre)
## Warning: NAs introducidos por coerción
df$Octubre <- as.numeric(df$Octubre)
## Warning: NAs introducidos por coerción
df$Noviembre <- as.numeric(df$Noviembre)
## Warning: NAs introducidos por coerción
df$Diciembre <- as.numeric(df$Diciembre)
## Warning: NAs introducidos por coerción
df$Año<-as.character(df$Año)

df$Enero <- abs(df$Enero)
df$Febrero <- abs(df$Febrero)
df$Marzo <- abs(df$Marzo)
df$Abril <- abs(df$Abril)
df$Mayo <- abs(df$Mayo)
df$Junio <- abs(df$Junio)
df$Julio <- abs(df$Julio)
df$Agosto <- abs(df$Agosto)
df$Septiembre <- abs(df$Septiembre)
df$Octubre <- abs(df$Octubre)
df$Noviembre <- abs(df$Noviembre)
df$Diciembre <- abs(df$Diciembre)
df[is.na(df)]<-0
resumen<-summary(df)
resumen
##        ID             Año             Territorio        Sub.Territorio    
##  Min.   :     1   Length:466508      Length:466508      Length:466508     
##  1st Qu.:116628   Class :character   Class :character   Class :character  
##  Median :233256   Mode  :character   Mode  :character   Mode  :character  
##  Mean   :233255                                                           
##  3rd Qu.:349882                                                           
##  Max.   :466509                                                           
##      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.   :  0.000   Min.   :  0.000   Min.   :  0.000  
##  Class :character   1st Qu.:  0.000   1st Qu.:  0.000   1st Qu.:  0.000  
##  Mode  :character   Median :  0.000   Median :  0.000   Median :  0.000  
##                     Mean   :  4.691   Mean   :  4.582   Mean   :  5.402  
##                     3rd Qu.:  2.000   3rd Qu.:  2.000   3rd Qu.:  3.000  
##                     Max.   :999.000   Max.   :986.000   Max.   :986.000  
##      Abril              Mayo             Junio             Julio        
##  Min.   :  0.000   Min.   :  0.000   Min.   :  0.000   Min.   :  0.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.521   Mean   :  6.122   Mean   :  5.908   Mean   :  5.585  
##  3rd Qu.:  3.000   3rd Qu.:  3.000   3rd Qu.:  3.000   3rd Qu.:  3.000  
##  Max.   :993.000   Max.   :991.000   Max.   :998.000   Max.   :993.000  
##      Agosto          Septiembre         Octubre         Noviembre     
##  Min.   :  0.000   Min.   :  0.000   Min.   :  0.00   Min.   :  0.00  
##  1st Qu.:  0.000   1st Qu.:  0.000   1st Qu.:  0.00   1st Qu.:  0.00  
##  Median :  0.000   Median :  0.000   Median :  0.00   Median :  0.00  
##  Mean   :  5.781   Mean   :  3.316   Mean   :  3.33   Mean   :  3.25  
##  3rd Qu.:  3.000   3rd Qu.:  1.000   3rd Qu.:  1.00   3rd Qu.:  1.00  
##  Max.   :999.000   Max.   :993.000   Max.   :998.00   Max.   :991.00  
##    Diciembre      
##  Min.   :  0.000  
##  1st Qu.:  0.000  
##  Median :  0.000  
##  Mean   :  3.479  
##  3rd Qu.:  0.000  
##  Max.   :997.000

Observaciones: 3. Tenemos NA en las columnas en los meses. 4. Tenemos cantidades negativas.
5. Converti en absolutos porque se dificulta encontrar y hacer graficas al futuro.
6. No tenemos ventas por año. 7. Cantida maximas muy elevedads

#¿Cuantos NA tengo en la base de datos?
sum(is.na(df))
## [1] 0
# ¿Cuantos NA tengo por variable?
sapply(df,function(x) sum(is.na(x)))
##                   ID                  Año           Territorio 
##                    0                    0                    0 
##       Sub.Territorio                 CEDI              Cliente 
##                    0                    0                    0 
##               Nombre Tamaño.Cte.Industria         Segmento.Det 
##                    0                    0                    0 
##                Marca         Presentacion               Tamaño 
##                    0                    0                    0 
##        Retornable_NR                Enero              Febrero 
##                    0                    0                    0 
##                Marzo                Abril                 Mayo 
##                    0                    0                    0 
##                Junio                Julio               Agosto 
##                    0                    0                    0 
##           Septiembre              Octubre            Noviembre 
##                    0                    0                    0 
##            Diciembre 
##                    0
# Borrar todos los registros con NA de la tabla
#df <- na.omit(df)

# Reemplazar NA con CEROS
# df[is.na(df)] <- 0

#En la parte de arriba considere datos negativos como error de dedo

# Reemplazar NA con PROMEDIO
# df$PLU [is.na(df$PLU)] <- mean(df$PLU, na.rm=TRUE)
#Grafica de Caja y Bigotes
boxplot(df$Enero, horizontal = TRUE)

Pregunta 1

¿Puede observarse un crecimiento en las ventas de algunos de los segmentos de productos de la familia Coca Cola en las tiendas en las que se implementó el Proyecto Siglo XXI de Arca Continental?

df$Ventas <- df$Enero + df$Febrero + df$Marzo + df$Abril +df$Mayo + df$Junio + df$Julio+ df$Agosto + df$Septiembre + df$Octubre + df$Noviembre + df$Diciembre
#install.packages("ggplot2")
library(ggplot2)
ggplot(df, aes(x=Año, y=Ventas)) +
  geom_bar(stat="identity") +
  labs(
    title = "Ventas Anuales",
    subtitle = "Caso Arca Continental",
  )

Respuesta
En arca continental, si hubo un aumento de ventas del año 2016 al 2017, 2017 a 2018 se mantuvo y 2018 a 2019 aumentaron.

Pregunta 2

¿El incremento en las ventas es similar entre los diferentes tamaños de clientes?

library(ggplot2)
ggplot(df, aes(x=Año, y=Ventas, colour=Tamaño.Cte.Industria)) +
  geom_bar(stat="identity") +
  labs(
    title = "Ventas Anuales",
    subtitle = "Caso Arca Continental",
  )

df2 <- df %>% filter(Tamaño.Cte.Industria =="Extra Grande")  

ggplot(df2, aes(x=Año, y=Ventas, colour=Tamaño.Cte.Industria)) +
  geom_bar(stat="identity") +
  labs(
    title = "Ventas Anuales",
    subtitle = "Caso Arca Continental",
  )

df3 <- df %>% filter(Tamaño.Cte.Industria =="Grande")  

ggplot(df3, aes(x=Año, y=Ventas, colour=Tamaño.Cte.Industria)) +
  geom_bar(stat="identity") +
  labs(
    title = "Ventas Anuales",
    subtitle = "Caso Arca Continental",
  )

df4 <- df %>% filter(Tamaño.Cte.Industria =="Micro") 

ggplot(df4, aes(x=Año, y=Ventas, colour=Tamaño.Cte.Industria)) +
  geom_bar(stat="identity") +
  labs(
    title = "Ventas Anuales",
    subtitle = "Caso Arca Continental",
  )

df5 <- df %>% filter(Tamaño.Cte.Industria =="Pequeño")

ggplot(df5, aes(x=Año, y=Ventas, colour=Tamaño.Cte.Industria)) +
  geom_bar(stat="identity") +
  labs(
    title = "Ventas Anuales",
    subtitle = "Caso Arca Continental",
  )

Respuesta

No, basandonos en la grafica anterior, podemos observar que en 2016-2018 solo se consideraba extra grande donde se mantuvo las ventas y micro se redujo las ventas. Pero en 2019, se agregaron otros tamaños de clientes donde parece que el extra grande se redujo a los años anteriores, se agrego tamaño de cliente grande y se aumento un poco el tamaño micro y se agrego el tamaño de clientes pequeño. Si no tuvieramos filtrado esto pareceria que se aumento las ventas en 2019, pero no es del todo verdad.

Pregunta 3

¿Cuál es el comportamiento observado de las unidades vendidas por mes de cada una de las marcas, independientemente de sus respectivas presentaciones?

#install.packages("ggplot2")
#install.packages("dplyr")
library(ggplot2)
library(dplyr)
df6 <- df %>% filter(Marca =="Coca-Cola")

ggplot(df6, aes(x=Año, y= Ventas, colour = Tamaño.Cte.Industria)) +
  geom_bar(stat = "Identity") +
  labs(
    title = "Ventas por año de la marca de Coca Cola",
    subtitle = "Caso Arca Continental Ventas Anuales"
  )

df7 <- df%>% filter(Marca =="Sprite")

ggplot(df7, aes(x=Año, y= Ventas, colour = Tamaño.Cte.Industria)) +
  geom_bar(stat = "Identity") +
  labs(
    title = "Ventas por año de la marca de Sprite",
    subtitle = "Caso Arca Continental Ventas Anuales"
  )

Respuesta

La marca de Coca-Cola es la más vendida de todas, con incremento de ventas en 2019. La marca Sprite con incremento de ventas año con año

Pregunta 4

¿Se ha incrementado la venta de productos en envases retornables en los últimos dos años?

df8 <- df%>% filter(Retornable_NR =="Retornable")

ggplot(df7, aes(x=Año, y= Ventas, colour = Tamaño.Cte.Industria)) +
  geom_bar(stat = "Identity") +
  labs(
    title = "Ventas por año de envase retornables",
    subtitle = "Caso Arca Continental Ventas Anuales"
  )

Respuesta

No hubo un incremento en el ultimo año.

Pregunta 5

¿El comportamiento de la venta de agua ha incrementado en relación al de los refrescos o las bebidas isotónicas?

df9 <- df%>% filter(Segmento.Det =="Agua Purificada" | Segmento.Det=="Isotónicos Regular" | Segmento.Det=="Colas Regular")

ggplot(df9, aes(x=Año, y= Ventas, fill=Segmento.Det)) +
  geom_bar(position ="dodge", stat = "identity") +
  labs(
    title = "Ventas por año",
    subtitle = "Caso Arca Continental Ventas Anuales"
  )

Respuesta

Las ventas de Agua Purificada y Colas Regular bajaron en su ultimo año. Sin embargo, Isotonicos Regular aumento año con año.

Pregunta 6

¿Puede decirse que la venta mensual de agua está relacionada con la venta mensual de refrescos en los últimos 4 años?

df10 <- df%>% filter(Segmento.Det =="Agua Purificada" | Segmento.Det=="Colas Regular")

ggplot(df10, aes(x=Año, y= Ventas, fill=Segmento.Det)) +
  geom_bar(position ="dodge", stat = "identity") +
  labs(
    title = "Ventas por año",
    subtitle = "Caso Arca Continental Ventas Anuales"
  )

Respuesta

La venta de agua y refresco no esta relacionada.

Pregunta 7

¿A cuánto ascienden las ventas esperadas para el 2020 en la Coca Cola de 500 ml NR Vidrio?

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

df12 <- aggregate(Ventas ~ Año, df11, sum)
df12$Año <- as.integer(df12$Año)
regresion <- lm(Ventas ~ Año, data=df12)
summary(regresion)
## 
## Call:
## lm(formula = Ventas ~ Año, data = df12)
## 
## Residuals:
##        1        2        3        4 
## -23817.7  35330.1    792.9 -12305.3 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)
## (Intercept) -54985035   28299337  -1.943    0.191
## Año             27440      14027   1.956    0.190
## 
## Residual standard error: 31370 on 2 degrees of freedom
## Multiple R-squared:  0.6568, Adjusted R-squared:  0.4851 
## F-statistic: 3.827 on 1 and 2 DF,  p-value: 0.1896
#Ecuacion de la recta y = -54985035 +  27440 * Año
datos <- data.frame (Año=2020)
predict(regresion,datos)
##        1 
## 444169.5

Respuesta

Acorde a un modelo predictivo utilizando regresion lineal, las ventas esperadas para Coca Cola de 500 ml NR Vidrio en 2020 son de 444,169 unidades, con una R cuadrada ajustada del 48%.

LS0tDQp0aXRsZTogIkV2aWRlbmNpYSINCmF1dGhvcjogIlJvbGFuZG8gVG9ycmVzIEJlbmF2aWRlcyBBMDEyODYxNjAiDQpkYXRlOiAiMjAyMy0wOS0xMyINCm91dHB1dDogDQogIGh0bWxfZG9jdW1lbnQ6DQogICAgdG9jOiBUUlVFDQogICAgdG9jX2Zsb2F0OiBUUlVFDQogICAgY29kZV9kb3dubG9hZDogVFJVRQ0KICAgIHRoZW1lOiAiY29zbW8iDQogICAgaGlnaGxpZ2h0OiAidGFuZ28iDQotLS0NCiFbXShDOlxcVXNlcnNcXHJ0b3JyXFxEb3dubG9hZHNcXDE2NTI4OTgzNzk0NDEuZ2lmKQ0KDQojIyMgPHNwYW4gc3R5bGU9ImNvbG9yOnJlZDsiPkNvbnRleHRvPC9zcGFuPg0KVXRpbGl6YXIgbGEgaW5mb3JtYWNpb24gcmVjb2xlY3RhZGEgY29tbyBsb3MgdGlja2V0cyBkZSBsb3MgY29uc3VtaWRvcmVzIGVuIGxvcyBwdW50b3MgZGUgdmVudGFzIHBhcmEgcGVybWl0aXIgbGEgaW1wbGVtZW50YWNpb24gZGUgdGVjbmljYXMgZGUgYW5hbGl0aWNhIGF2YW56YWRhIGRlIGRhdG9zIHBhcmEgZGlzZcOxYXIgZXN0cmF0ZWdpYXMgcXVlIHBlcm1pdGFuIG9mcmVjZXIgdW4gbWVqb3Igc2VydmljaW9zIHkgcHJvbW9jaW9uZXMgYSBzdXMgdGVuZGVyb3MNCg0KIyMjIDxzcGFuIHN0eWxlPSJjb2xvcjpyZWQ7Ij5JbXBvcnRhciBkYXRvczwvc3Bhbj4NCmBgYHtyfQ0KI2ZpbGUuY2hvb3NlKCkNCmRmIDwtIHJlYWQuY3N2KCJDOlxcVXNlcnNcXHJ0b3JyXFxEb3dubG9hZHNcXGFyY2EuY3N2IikNCmBgYA0KIyMjIDxzcGFuIHN0eWxlPSJjb2xvcjpyZWQ7Ij5FbnRlbmRlcjwvc3Bhbj4NCmBgYHtyfQ0KcmVzdW1lbjwtc3VtbWFyeShkZikNCnJlc3VtZW4NCiNjb3VudChkZiwgVGVycml0b3Jpbywgc29ydCA9VFJVRSkNCiNjb3VudChkZiwgU3ViLlRlcnJpdG9yaW8sIHNvcnQgPVRSVUUpDQojY291bnQoZGYsIENFREksIHNvcnQgPVRSVUUpDQojY291bnQoZGYsIENsaWVudGUsIHNvcnQgPVRSVUUpDQojY291bnQoZGYsIE5vbWJyZSwgc29ydCA9VFJVRSkNCiNjb3VudChkZiwgVGFtYcOxby5DdGUuSW5kdXN0cmlhLCBzb3J0ID1UUlVFKQ0KI2NvdW50KGRmLCBTZWdtZW50by5EZXQsIHNvcnQgPVRSVUUpDQojY291bnQoZGYsIE1hcmNhLCBzb3J0ID1UUlVFKQ0KI2NvdW50KGRmLCBQcmVzZW50YWNpb24sIHNvcnQgPVRSVUUpDQojY291bnQoZGYsIFRhbWHDsW8sIHNvcnQgPVRSVUUpDQojY291bnQoZGYsIFJldG9ybmFibGVfTlIsIHNvcnQgPVRSVUUpDQpgYGANCk9ic2VydmFjaW9uZXM6ICANCjEuIEVsaW1pbmFyIHJlZ2xvbiAxODQwNjUgcXVlIHRpZW5lIHRpdHVsb3MgZW4gbHVnYXIgZGUgZGF0b3MuICANCjIuIENhbWJpYXIgZm9ybWF0byAoZGUgRW5lcm8gYSBEaWNpZW1icmUpIGRlIGNhcmFjdGVyIGEgZW50ZXJvLiAgDQoNCiMjIyA8c3BhbiBzdHlsZT0iY29sb3I6cmVkOyI+TGltcGllemE8L3NwYW4+DQpgYGB7cn0NCmxpYnJhcnkoZHBseXIpDQpjb3VudChkZixUZXJyaXRvcmlvLHNvcnQ9VFJVRSkNCmRmPC1kZlstMTg0MDY1LF0NCmRmJEVuZXJvIDwtIGFzLm51bWVyaWMoZGYkRW5lcm8pDQpkZiRGZWJyZXJvIDwtIGFzLm51bWVyaWMoZGYkRmVicmVybykNCmRmJE1hcnpvIDwtIGFzLm51bWVyaWMoZGYkTWFyem8pDQpkZiRBYnJpbCA8LSBhcy5udW1lcmljKGRmJEFicmlsKQ0KZGYkTWF5byA8LSBhcy5udW1lcmljKGRmJE1heW8pDQpkZiRKdW5pbyA8LSBhcy5udW1lcmljKGRmJEp1bmlvKQ0KZGYkSnVsaW8gPC0gYXMubnVtZXJpYyhkZiRKdWxpbykNCmRmJEFnb3N0byA8LSBhcy5udW1lcmljKGRmJEFnb3N0bykNCmRmJFNlcHRpZW1icmUgPC0gYXMubnVtZXJpYyhkZiRTZXB0aWVtYnJlKQ0KZGYkT2N0dWJyZSA8LSBhcy5udW1lcmljKGRmJE9jdHVicmUpDQpkZiROb3ZpZW1icmUgPC0gYXMubnVtZXJpYyhkZiROb3ZpZW1icmUpDQpkZiREaWNpZW1icmUgPC0gYXMubnVtZXJpYyhkZiREaWNpZW1icmUpDQpkZiRBw7FvPC1hcy5jaGFyYWN0ZXIoZGYkQcOxbykNCg0KZGYkRW5lcm8gPC0gYWJzKGRmJEVuZXJvKQ0KZGYkRmVicmVybyA8LSBhYnMoZGYkRmVicmVybykNCmRmJE1hcnpvIDwtIGFicyhkZiRNYXJ6bykNCmRmJEFicmlsIDwtIGFicyhkZiRBYnJpbCkNCmRmJE1heW8gPC0gYWJzKGRmJE1heW8pDQpkZiRKdW5pbyA8LSBhYnMoZGYkSnVuaW8pDQpkZiRKdWxpbyA8LSBhYnMoZGYkSnVsaW8pDQpkZiRBZ29zdG8gPC0gYWJzKGRmJEFnb3N0bykNCmRmJFNlcHRpZW1icmUgPC0gYWJzKGRmJFNlcHRpZW1icmUpDQpkZiRPY3R1YnJlIDwtIGFicyhkZiRPY3R1YnJlKQ0KZGYkTm92aWVtYnJlIDwtIGFicyhkZiROb3ZpZW1icmUpDQpkZiREaWNpZW1icmUgPC0gYWJzKGRmJERpY2llbWJyZSkNCmRmW2lzLm5hKGRmKV08LTANCnJlc3VtZW48LXN1bW1hcnkoZGYpDQpyZXN1bWVuDQpgYGANCk9ic2VydmFjaW9uZXM6DQozLiBUZW5lbW9zIE5BIGVuIGxhcyBjb2x1bW5hcyBlbiBsb3MgbWVzZXMuDQo0LiBUZW5lbW9zIGNhbnRpZGFkZXMgbmVnYXRpdmFzLiAgDQo1LiBDb252ZXJ0aSBlbiBhYnNvbHV0b3MgcG9ycXVlIHNlIGRpZmljdWx0YSBlbmNvbnRyYXIgeSBoYWNlciBncmFmaWNhcyBhbCBmdXR1cm8uICANCjYuIE5vIHRlbmVtb3MgdmVudGFzIHBvciBhw7FvLiANCjcuIENhbnRpZGEgbWF4aW1hcyBtdXkgZWxldmVkYWRzDQoNCmBgYHtyfQ0KI8K/Q3VhbnRvcyBOQSB0ZW5nbyBlbiBsYSBiYXNlIGRlIGRhdG9zPw0Kc3VtKGlzLm5hKGRmKSkNCg0KIyDCv0N1YW50b3MgTkEgdGVuZ28gcG9yIHZhcmlhYmxlPw0Kc2FwcGx5KGRmLGZ1bmN0aW9uKHgpIHN1bShpcy5uYSh4KSkpDQoNCiMgQm9ycmFyIHRvZG9zIGxvcyByZWdpc3Ryb3MgY29uIE5BIGRlIGxhIHRhYmxhDQojZGYgPC0gbmEub21pdChkZikNCg0KIyBSZWVtcGxhemFyIE5BIGNvbiBDRVJPUw0KIyBkZltpcy5uYShkZildIDwtIDANCg0KI0VuIGxhIHBhcnRlIGRlIGFycmliYSBjb25zaWRlcmUgZGF0b3MgbmVnYXRpdm9zIGNvbW8gZXJyb3IgZGUgZGVkbw0KDQojIFJlZW1wbGF6YXIgTkEgY29uIFBST01FRElPDQojIGRmJFBMVSBbaXMubmEoZGYkUExVKV0gPC0gbWVhbihkZiRQTFUsIG5hLnJtPVRSVUUpDQojR3JhZmljYSBkZSBDYWphIHkgQmlnb3Rlcw0KYm94cGxvdChkZiRFbmVybywgaG9yaXpvbnRhbCA9IFRSVUUpDQpgYGANCg0KDQojIyMgPHNwYW4gc3R5bGU9ImNvbG9yOnJlZDsiPlByZWd1bnRhIDE8L3NwYW4+ICAgICANCsK/UHVlZGUgb2JzZXJ2YXJzZSB1biBjcmVjaW1pZW50byBlbiBsYXMgdmVudGFzIGRlIGFsZ3Vub3MgZGUgbG9zIHNlZ21lbnRvcyBkZSBwcm9kdWN0b3MgZGUgbGEgZmFtaWxpYSBDb2NhIENvbGEgZW4gbGFzIHRpZW5kYXMgZW4gbGFzIHF1ZSBzZSBpbXBsZW1lbnTDsyBlbCBQcm95ZWN0byBTaWdsbyBYWEkgZGUgQXJjYSBDb250aW5lbnRhbD8gICAgIA0KDQpgYGB7cn0NCmRmJFZlbnRhcyA8LSBkZiRFbmVybyArIGRmJEZlYnJlcm8gKyBkZiRNYXJ6byArIGRmJEFicmlsICtkZiRNYXlvICsgZGYkSnVuaW8gKyBkZiRKdWxpbysgZGYkQWdvc3RvICsgZGYkU2VwdGllbWJyZSArIGRmJE9jdHVicmUgKyBkZiROb3ZpZW1icmUgKyBkZiREaWNpZW1icmUNCiNpbnN0YWxsLnBhY2thZ2VzKCJnZ3Bsb3QyIikNCmxpYnJhcnkoZ2dwbG90MikNCmdncGxvdChkZiwgYWVzKHg9QcOxbywgeT1WZW50YXMpKSArDQogIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IikgKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIlZlbnRhcyBBbnVhbGVzIiwNCiAgICBzdWJ0aXRsZSA9ICJDYXNvIEFyY2EgQ29udGluZW50YWwiLA0KICApDQpgYGANCg0KDQoqKjxzcGFuIHN0eWxlPSJjb2xvcjpyZWQ7Ij5SZXNwdWVzdGE8L3NwYW4+KiogICAgICAgICAgDQpFbiBhcmNhIGNvbnRpbmVudGFsLCBzaSBodWJvIHVuIGF1bWVudG8gZGUgdmVudGFzIGRlbCBhw7FvIDIwMTYgYWwgMjAxNywgMjAxNyBhIDIwMTggc2UgbWFudHV2byB5IDIwMTggYSAyMDE5IGF1bWVudGFyb24uDQoNCiMjIyA8c3BhbiBzdHlsZT0iY29sb3I6cmVkOyI+UHJlZ3VudGEgMjwvc3Bhbj4gICAgIA0Kwr9FbCBpbmNyZW1lbnRvIGVuIGxhcyB2ZW50YXMgZXMgc2ltaWxhciBlbnRyZSBsb3MgZGlmZXJlbnRlcyB0YW1hw7FvcyBkZSBjbGllbnRlcz8gICAgIA0KDQpgYGB7cn0NCmxpYnJhcnkoZ2dwbG90MikNCmdncGxvdChkZiwgYWVzKHg9QcOxbywgeT1WZW50YXMsIGNvbG91cj1UYW1hw7FvLkN0ZS5JbmR1c3RyaWEpKSArDQogIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IikgKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIlZlbnRhcyBBbnVhbGVzIiwNCiAgICBzdWJ0aXRsZSA9ICJDYXNvIEFyY2EgQ29udGluZW50YWwiLA0KICApDQoNCmRmMiA8LSBkZiAlPiUgZmlsdGVyKFRhbWHDsW8uQ3RlLkluZHVzdHJpYSA9PSJFeHRyYSBHcmFuZGUiKSAgDQoNCmdncGxvdChkZjIsIGFlcyh4PUHDsW8sIHk9VmVudGFzLCBjb2xvdXI9VGFtYcOxby5DdGUuSW5kdXN0cmlhKSkgKw0KICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIpICsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJWZW50YXMgQW51YWxlcyIsDQogICAgc3VidGl0bGUgPSAiQ2FzbyBBcmNhIENvbnRpbmVudGFsIiwNCiAgKQ0KDQpkZjMgPC0gZGYgJT4lIGZpbHRlcihUYW1hw7FvLkN0ZS5JbmR1c3RyaWEgPT0iR3JhbmRlIikgIA0KDQpnZ3Bsb3QoZGYzLCBhZXMoeD1Bw7FvLCB5PVZlbnRhcywgY29sb3VyPVRhbWHDsW8uQ3RlLkluZHVzdHJpYSkpICsNCiAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiKSArDQogIGxhYnMoDQogICAgdGl0bGUgPSAiVmVudGFzIEFudWFsZXMiLA0KICAgIHN1YnRpdGxlID0gIkNhc28gQXJjYSBDb250aW5lbnRhbCIsDQogICkNCg0KZGY0IDwtIGRmICU+JSBmaWx0ZXIoVGFtYcOxby5DdGUuSW5kdXN0cmlhID09Ik1pY3JvIikgDQoNCmdncGxvdChkZjQsIGFlcyh4PUHDsW8sIHk9VmVudGFzLCBjb2xvdXI9VGFtYcOxby5DdGUuSW5kdXN0cmlhKSkgKw0KICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIpICsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJWZW50YXMgQW51YWxlcyIsDQogICAgc3VidGl0bGUgPSAiQ2FzbyBBcmNhIENvbnRpbmVudGFsIiwNCiAgKQ0KDQpkZjUgPC0gZGYgJT4lIGZpbHRlcihUYW1hw7FvLkN0ZS5JbmR1c3RyaWEgPT0iUGVxdWXDsW8iKQ0KDQpnZ3Bsb3QoZGY1LCBhZXMoeD1Bw7FvLCB5PVZlbnRhcywgY29sb3VyPVRhbWHDsW8uQ3RlLkluZHVzdHJpYSkpICsNCiAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiKSArDQogIGxhYnMoDQogICAgdGl0bGUgPSAiVmVudGFzIEFudWFsZXMiLA0KICAgIHN1YnRpdGxlID0gIkNhc28gQXJjYSBDb250aW5lbnRhbCIsDQogICkNCmBgYA0KDQoNCg0KDQoqKjxzcGFuIHN0eWxlPSJjb2xvcjpyZWQ7Ij5SZXNwdWVzdGE8L3NwYW4+KiogICAgICAgICAgICAgICAgDQoNCk5vLCBiYXNhbmRvbm9zIGVuIGxhIGdyYWZpY2EgYW50ZXJpb3IsIHBvZGVtb3Mgb2JzZXJ2YXIgcXVlIGVuIDIwMTYtMjAxOCBzb2xvIHNlIGNvbnNpZGVyYWJhIGV4dHJhIGdyYW5kZSBkb25kZSBzZSBtYW50dXZvIGxhcyB2ZW50YXMgeSBtaWNybyBzZSByZWR1am8gbGFzIHZlbnRhcy4gUGVybyBlbiAyMDE5LCBzZSBhZ3JlZ2Fyb24gb3Ryb3MgdGFtYcOxb3MgZGUgY2xpZW50ZXMgZG9uZGUgcGFyZWNlIHF1ZSBlbCBleHRyYSBncmFuZGUgc2UgcmVkdWpvIGEgbG9zIGHDsW9zIGFudGVyaW9yZXMsIHNlIGFncmVnbyB0YW1hw7FvIGRlIGNsaWVudGUgZ3JhbmRlIHkgc2UgYXVtZW50byB1biBwb2NvIGVsIHRhbWHDsW8gbWljcm8geSBzZSBhZ3JlZ28gZWwgdGFtYcOxbyBkZSBjbGllbnRlcyBwZXF1ZcOxby4gU2kgbm8gdHV2aWVyYW1vcyBmaWx0cmFkbyBlc3RvIHBhcmVjZXJpYSBxdWUgc2UgYXVtZW50byBsYXMgdmVudGFzIGVuIDIwMTksIHBlcm8gbm8gZXMgZGVsIHRvZG8gdmVyZGFkLg0KDQojIyMgPHNwYW4gc3R5bGU9ImNvbG9yOnJlZDsiPlByZWd1bnRhIDM8L3NwYW4+ICAgICANCsK/Q3XDoWwgZXMgZWwgY29tcG9ydGFtaWVudG8gb2JzZXJ2YWRvIGRlIGxhcyB1bmlkYWRlcyB2ZW5kaWRhcyBwb3IgbWVzIGRlIGNhZGEgdW5hIGRlIGxhcyBtYXJjYXMsIGluZGVwZW5kaWVudGVtZW50ZSBkZSBzdXMgcmVzcGVjdGl2YXMgcHJlc2VudGFjaW9uZXM/ICAgICANCg0KYGBge3J9DQojaW5zdGFsbC5wYWNrYWdlcygiZ2dwbG90MiIpDQojaW5zdGFsbC5wYWNrYWdlcygiZHBseXIiKQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShkcGx5cikNCmRmNiA8LSBkZiAlPiUgZmlsdGVyKE1hcmNhID09IkNvY2EtQ29sYSIpDQoNCmdncGxvdChkZjYsIGFlcyh4PUHDsW8sIHk9IFZlbnRhcywgY29sb3VyID0gVGFtYcOxby5DdGUuSW5kdXN0cmlhKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gIklkZW50aXR5IikgKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIlZlbnRhcyBwb3IgYcOxbyBkZSBsYSBtYXJjYSBkZSBDb2NhIENvbGEiLA0KICAgIHN1YnRpdGxlID0gIkNhc28gQXJjYSBDb250aW5lbnRhbCBWZW50YXMgQW51YWxlcyINCiAgKQ0KZGY3IDwtIGRmJT4lIGZpbHRlcihNYXJjYSA9PSJTcHJpdGUiKQ0KDQpnZ3Bsb3QoZGY3LCBhZXMoeD1Bw7FvLCB5PSBWZW50YXMsIGNvbG91ciA9IFRhbWHDsW8uQ3RlLkluZHVzdHJpYSkpICsNCiAgZ2VvbV9iYXIoc3RhdCA9ICJJZGVudGl0eSIpICsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJWZW50YXMgcG9yIGHDsW8gZGUgbGEgbWFyY2EgZGUgU3ByaXRlIiwNCiAgICBzdWJ0aXRsZSA9ICJDYXNvIEFyY2EgQ29udGluZW50YWwgVmVudGFzIEFudWFsZXMiDQogICkNCg0KYGBgDQoNCg0KICANCioqPHNwYW4gc3R5bGU9ImNvbG9yOnJlZDsiPlJlc3B1ZXN0YTwvc3Bhbj4qKiAgICAgICAgICAgICAgICAgICAgICAgICANCg0KTGEgbWFyY2EgZGUgQ29jYS1Db2xhIGVzIGxhIG3DoXMgdmVuZGlkYSBkZSB0b2RhcywgY29uIGluY3JlbWVudG8gZGUgdmVudGFzIGVuIDIwMTkuIExhIG1hcmNhIFNwcml0ZSBjb24gaW5jcmVtZW50byBkZSB2ZW50YXMgYcOxbyBjb24gYcOxbw0KDQojIyMgPHNwYW4gc3R5bGU9ImNvbG9yOnJlZDsiPlByZWd1bnRhIDQ8L3NwYW4+ICAgDQrCv1NlIGhhIGluY3JlbWVudGFkbyBsYSB2ZW50YSBkZSBwcm9kdWN0b3MgZW4gZW52YXNlcyByZXRvcm5hYmxlcyBlbiBsb3Mgw7psdGltb3MgZG9zIGHDsW9zPw0KYGBge3J9DQpkZjggPC0gZGYlPiUgZmlsdGVyKFJldG9ybmFibGVfTlIgPT0iUmV0b3JuYWJsZSIpDQoNCmdncGxvdChkZjcsIGFlcyh4PUHDsW8sIHk9IFZlbnRhcywgY29sb3VyID0gVGFtYcOxby5DdGUuSW5kdXN0cmlhKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gIklkZW50aXR5IikgKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIlZlbnRhcyBwb3IgYcOxbyBkZSBlbnZhc2UgcmV0b3JuYWJsZXMiLA0KICAgIHN1YnRpdGxlID0gIkNhc28gQXJjYSBDb250aW5lbnRhbCBWZW50YXMgQW51YWxlcyINCiAgKQ0KYGBgDQoNCg0KDQoqKjxzcGFuIHN0eWxlPSJjb2xvcjpyZWQ7Ij5SZXNwdWVzdGE8L3NwYW4+KiogICAgICAgICAgICAgICAgICANCg0KTm8gaHVibyB1biBpbmNyZW1lbnRvIGVuIGVsIHVsdGltbyBhw7FvLiAgICANCg0KIyMjIDxzcGFuIHN0eWxlPSJjb2xvcjpyZWQ7Ij5QcmVndW50YSA1PC9zcGFuPiAgICANCsK/RWwgY29tcG9ydGFtaWVudG8gZGUgbGEgdmVudGEgZGUgYWd1YSBoYSBpbmNyZW1lbnRhZG8gZW4gcmVsYWNpw7NuIGFsIGRlIGxvcyByZWZyZXNjb3MgbyBsYXMgYmViaWRhcyBpc290w7NuaWNhcz8gDQoNCmBgYHtyfQ0KZGY5IDwtIGRmJT4lIGZpbHRlcihTZWdtZW50by5EZXQgPT0iQWd1YSBQdXJpZmljYWRhIiB8IFNlZ21lbnRvLkRldD09Iklzb3TDs25pY29zIFJlZ3VsYXIiIHwgU2VnbWVudG8uRGV0PT0iQ29sYXMgUmVndWxhciIpDQoNCmdncGxvdChkZjksIGFlcyh4PUHDsW8sIHk9IFZlbnRhcywgZmlsbD1TZWdtZW50by5EZXQpKSArDQogIGdlb21fYmFyKHBvc2l0aW9uID0iZG9kZ2UiLCBzdGF0ID0gImlkZW50aXR5IikgKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIlZlbnRhcyBwb3IgYcOxbyIsDQogICAgc3VidGl0bGUgPSAiQ2FzbyBBcmNhIENvbnRpbmVudGFsIFZlbnRhcyBBbnVhbGVzIg0KICApDQpgYGANCg0KDQoNCioqPHNwYW4gc3R5bGU9ImNvbG9yOnJlZDsiPlJlc3B1ZXN0YTwvc3Bhbj4qKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICANCg0KTGFzIHZlbnRhcyBkZSBBZ3VhIFB1cmlmaWNhZGEgeSBDb2xhcyBSZWd1bGFyIGJhamFyb24gZW4gc3UgdWx0aW1vIGHDsW8uIFNpbiBlbWJhcmdvLCBJc290b25pY29zIFJlZ3VsYXIgYXVtZW50byBhw7FvIGNvbiBhw7FvLiAgIA0KDQojIyMgPHNwYW4gc3R5bGU9ImNvbG9yOnJlZDsiPlByZWd1bnRhIDY8L3NwYW4+DQrCv1B1ZWRlIGRlY2lyc2UgcXVlIGxhIHZlbnRhIG1lbnN1YWwgZGUgYWd1YSBlc3TDoSByZWxhY2lvbmFkYSBjb24gbGEgdmVudGEgbWVuc3VhbCBkZSByZWZyZXNjb3MgZW4gbG9zIMO6bHRpbW9zIDQgYcOxb3M/DQoNCmBgYHtyfQ0KZGYxMCA8LSBkZiU+JSBmaWx0ZXIoU2VnbWVudG8uRGV0ID09IkFndWEgUHVyaWZpY2FkYSIgfCBTZWdtZW50by5EZXQ9PSJDb2xhcyBSZWd1bGFyIikNCg0KZ2dwbG90KGRmMTAsIGFlcyh4PUHDsW8sIHk9IFZlbnRhcywgZmlsbD1TZWdtZW50by5EZXQpKSArDQogIGdlb21fYmFyKHBvc2l0aW9uID0iZG9kZ2UiLCBzdGF0ID0gImlkZW50aXR5IikgKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIlZlbnRhcyBwb3IgYcOxbyIsDQogICAgc3VidGl0bGUgPSAiQ2FzbyBBcmNhIENvbnRpbmVudGFsIFZlbnRhcyBBbnVhbGVzIg0KICApDQpgYGANCiAgICANCioqPHNwYW4gc3R5bGU9ImNvbG9yOnJlZDsiPlJlc3B1ZXN0YTwvc3Bhbj4qKiAgICAgICANCg0KTGEgdmVudGEgZGUgYWd1YSB5IHJlZnJlc2NvIG5vIGVzdGEgcmVsYWNpb25hZGEuICAgICAgICANCg0KIyMjIDxzcGFuIHN0eWxlPSJjb2xvcjpyZWQ7Ij5QcmVndW50YSA3PC9zcGFuPg0Kwr9BIGN1w6FudG8gYXNjaWVuZGVuIGxhcyB2ZW50YXMgZXNwZXJhZGFzIHBhcmEgZWwgMjAyMCBlbiBsYSBDb2NhIENvbGEgZGUgNTAwIG1sIE5SIFZpZHJpbz8gICANCg0KYGBge3J9DQpkZjExIDwtIGRmJT4lIGZpbHRlcihNYXJjYSA9PSJDb2NhLUNvbGEiICYgUHJlc2VudGFjaW9uID09IjUwMCBtbCBOUiBWaWRyaW8iKQ0KDQpkZjEyIDwtIGFnZ3JlZ2F0ZShWZW50YXMgfiBBw7FvLCBkZjExLCBzdW0pDQpkZjEyJEHDsW8gPC0gYXMuaW50ZWdlcihkZjEyJEHDsW8pDQpyZWdyZXNpb24gPC0gbG0oVmVudGFzIH4gQcOxbywgZGF0YT1kZjEyKQ0Kc3VtbWFyeShyZWdyZXNpb24pDQojRWN1YWNpb24gZGUgbGEgcmVjdGEgeSA9IC01NDk4NTAzNSArICAyNzQ0MCAqIEHDsW8NCmRhdG9zIDwtIGRhdGEuZnJhbWUgKEHDsW89MjAyMCkNCnByZWRpY3QocmVncmVzaW9uLGRhdG9zKQ0KYGBgDQoqKjxzcGFuIHN0eWxlPSJjb2xvcjpyZWQ7Ij5SZXNwdWVzdGE8L3NwYW4+KiogICAgICAgICAgDQoNCkFjb3JkZSBhIHVuIG1vZGVsbyBwcmVkaWN0aXZvIHV0aWxpemFuZG8gcmVncmVzaW9uIGxpbmVhbCwgbGFzIHZlbnRhcyBlc3BlcmFkYXMgcGFyYSBDb2NhIENvbGEgZGUgNTAwIG1sIE5SIFZpZHJpbyBlbiAyMDIwIHNvbiBkZSA0NDQsMTY5IHVuaWRhZGVzLCBjb24gdW5hIFIgY3VhZHJhZGEgYWp1c3RhZGEgZGVsIDQ4JS4NCg==