Cargar Base de Datos

df <- read.csv("/Users/eduardogarza/Desktop/S7/BootcampProgramaciónST/abarrotes.csv")

Entender base de datos

resumen <- summary(df)
resumen
##  vcClaveTienda        DescGiro         Codigo.Barras            PLU        
##  Length:200625      Length:200625      Min.   :8.347e+05   Min.   : 1.00   
##  Class :character   Class :character   1st Qu.:7.501e+12   1st Qu.: 1.00   
##  Mode  :character   Mode  :character   Median :7.501e+12   Median : 1.00   
##                                        Mean   :5.950e+12   Mean   : 2.11   
##                                        3rd Qu.:7.501e+12   3rd Qu.: 1.00   
##                                        Max.   :1.750e+13   Max.   :30.00   
##                                                            NA's   :199188  
##     Fecha               Hora              Marca            Fabricante       
##  Length:200625      Length:200625      Length:200625      Length:200625     
##  Class :character   Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character   Mode  :character  
##                                                                             
##                                                                             
##                                                                             
##                                                                             
##    Producto             Precio          Ult.Costo         Unidades     
##  Length:200625      Min.   :-147.00   Min.   :  0.38   Min.   : 0.200  
##  Class :character   1st Qu.:  11.00   1st Qu.:  8.46   1st Qu.: 1.000  
##  Mode  :character   Median :  16.00   Median : 12.31   Median : 1.000  
##                     Mean   :  19.42   Mean   : 15.31   Mean   : 1.262  
##                     3rd Qu.:  25.00   3rd Qu.: 19.23   3rd Qu.: 1.000  
##                     Max.   :1000.00   Max.   :769.23   Max.   :96.000  
##                                                                        
##     F.Ticket      NombreDepartamento NombreFamilia      NombreCategoria   
##  Min.   :     1   Length:200625      Length:200625      Length:200625     
##  1st Qu.: 33964   Class :character   Class :character   Class :character  
##  Median :105993   Mode  :character   Mode  :character   Mode  :character  
##  Mean   :193990                                                           
##  3rd Qu.:383005                                                           
##  Max.   :450040                                                           
##                                                                           
##     Estado              Mts.2      Tipo.ubicación         Giro          
##  Length:200625      Min.   :47.0   Length:200625      Length:200625     
##  Class :character   1st Qu.:53.0   Class :character   Class :character  
##  Mode  :character   Median :60.0   Mode  :character   Mode  :character  
##                     Mean   :56.6                                        
##                     3rd Qu.:60.0                                        
##                     Max.   :62.0                                        
##                                                                         
##  Hora.inicio        Hora.cierre       
##  Length:200625      Length:200625     
##  Class :character   Class :character  
##  Mode  :character   Mode  :character  
##                                       
##                                       
##                                       
## 
str(df) #visualiza en texto las variables, su tipo y ejemplos
## 'data.frame':    200625 obs. of  22 variables:
##  $ vcClaveTienda     : chr  "MX001" "MX001" "MX001" "MX001" ...
##  $ DescGiro          : chr  "Abarrotes" "Abarrotes" "Abarrotes" "Abarrotes" ...
##  $ Codigo.Barras     : num  7.5e+12 7.5e+12 7.5e+12 7.5e+12 7.5e+12 ...
##  $ PLU               : int  NA NA NA NA NA NA NA NA NA NA ...
##  $ Fecha             : chr  "19/06/2020" "19/06/2020" "19/06/2020" "19/06/2020" ...
##  $ Hora              : chr  "08:16:21" "08:23:33" "08:24:33" "08:24:33" ...
##  $ Marca             : chr  "NUTRI LECHE" "DAN UP" "BIMBO" "PEPSI" ...
##  $ Fabricante        : chr  "MEXILAC" "DANONE DE MEXICO" "GRUPO BIMBO" "PEPSI-COLA MEXICANA" ...
##  $ Producto          : chr  "Nutri Leche 1 Litro" "DANUP STRAWBERRY P/BEBER 350GR NAL" "Rebanadas Bimbo 2Pz" "Pepsi N.R. 400Ml" ...
##  $ Precio            : num  16 14 5 8 19.5 16 14 5 8 19.5 ...
##  $ Ult.Costo         : num  12.3 14 5 8 15 ...
##  $ Unidades          : num  1 1 1 1 1 1 1 1 1 1 ...
##  $ F.Ticket          : int  1 2 3 3 4 1 2 3 3 4 ...
##  $ NombreDepartamento: chr  "Abarrotes" "Abarrotes" "Abarrotes" "Abarrotes" ...
##  $ NombreFamilia     : chr  "Lacteos y Refrigerados" "Lacteos y Refrigerados" "Pan y Tortilla" "Bebidas" ...
##  $ NombreCategoria   : chr  "Leche" "Yogurt" "Pan Dulce Empaquetado" "Refrescos Plástico (N.R.)" ...
##  $ Estado            : chr  "Nuevo León" "Nuevo León" "Nuevo León" "Nuevo León" ...
##  $ Mts.2             : int  60 60 60 60 60 60 60 60 60 60 ...
##  $ Tipo.ubicación    : chr  "Esquina" "Esquina" "Esquina" "Esquina" ...
##  $ Giro              : chr  "Abarrotes" "Abarrotes" "Abarrotes" "Abarrotes" ...
##  $ Hora.inicio       : chr  "08:00" "08:00" "08:00" "08:00" ...
##  $ Hora.cierre       : chr  "22:00" "22:00" "22:00" "22:00" ...
head(df,10) # Muestra primeros 10 renglones de la tabla
##    vcClaveTienda  DescGiro Codigo.Barras PLU      Fecha     Hora
## 1          MX001 Abarrotes  7.501021e+12  NA 19/06/2020 08:16:21
## 2          MX001 Abarrotes  7.501032e+12  NA 19/06/2020 08:23:33
## 3          MX001 Abarrotes  7.501000e+12  NA 19/06/2020 08:24:33
## 4          MX001 Abarrotes  7.501031e+12  NA 19/06/2020 08:24:33
## 5          MX001 Abarrotes  7.501026e+12  NA 19/06/2020 08:26:28
## 6          MX001 Abarrotes  7.501021e+12  NA 19/06/2020 08:16:21
## 7          MX001 Abarrotes  7.501032e+12  NA 19/06/2020 08:23:33
## 8          MX001 Abarrotes  7.501000e+12  NA 19/06/2020 08:24:33
## 9          MX001 Abarrotes  7.501031e+12  NA 19/06/2020 08:24:33
## 10         MX001 Abarrotes  7.501026e+12  NA 19/06/2020 08:26:28
##                         Marca                 Fabricante
## 1                 NUTRI LECHE                    MEXILAC
## 2                      DAN UP           DANONE DE MEXICO
## 3                       BIMBO                GRUPO BIMBO
## 4                       PEPSI        PEPSI-COLA MEXICANA
## 5  BLANCA NIEVES (DETERGENTE) FABRICA DE JABON LA CORONA
## 6                 NUTRI LECHE                    MEXILAC
## 7                      DAN UP           DANONE DE MEXICO
## 8                       BIMBO                GRUPO BIMBO
## 9                       PEPSI        PEPSI-COLA MEXICANA
## 10 BLANCA NIEVES (DETERGENTE) FABRICA DE JABON LA CORONA
##                              Producto Precio Ult.Costo Unidades F.Ticket
## 1                 Nutri Leche 1 Litro   16.0     12.31        1        1
## 2  DANUP STRAWBERRY P/BEBER 350GR NAL   14.0     14.00        1        2
## 3                 Rebanadas Bimbo 2Pz    5.0      5.00        1        3
## 4                    Pepsi N.R. 400Ml    8.0      8.00        1        3
## 5       Detergente Blanca Nieves 500G   19.5     15.00        1        4
## 6                 Nutri Leche 1 Litro   16.0     12.31        1        1
## 7  DANUP STRAWBERRY P/BEBER 350GR NAL   14.0     14.00        1        2
## 8                 Rebanadas Bimbo 2Pz    5.0      5.00        1        3
## 9                    Pepsi N.R. 400Ml    8.0      8.00        1        3
## 10      Detergente Blanca Nieves 500G   19.5     15.00        1        4
##    NombreDepartamento          NombreFamilia           NombreCategoria
## 1           Abarrotes Lacteos y Refrigerados                     Leche
## 2           Abarrotes Lacteos y Refrigerados                    Yogurt
## 3           Abarrotes         Pan y Tortilla     Pan Dulce Empaquetado
## 4           Abarrotes                Bebidas Refrescos Plástico (N.R.)
## 5           Abarrotes     Limpieza del Hogar                Lavandería
## 6           Abarrotes Lacteos y Refrigerados                     Leche
## 7           Abarrotes Lacteos y Refrigerados                    Yogurt
## 8           Abarrotes         Pan y Tortilla     Pan Dulce Empaquetado
## 9           Abarrotes                Bebidas Refrescos Plástico (N.R.)
## 10          Abarrotes     Limpieza del Hogar                Lavandería
##        Estado Mts.2 Tipo.ubicación      Giro Hora.inicio Hora.cierre
## 1  Nuevo León    60        Esquina Abarrotes       08:00       22:00
## 2  Nuevo León    60        Esquina Abarrotes       08:00       22:00
## 3  Nuevo León    60        Esquina Abarrotes       08:00       22:00
## 4  Nuevo León    60        Esquina Abarrotes       08:00       22:00
## 5  Nuevo León    60        Esquina Abarrotes       08:00       22:00
## 6  Nuevo León    60        Esquina Abarrotes       08:00       22:00
## 7  Nuevo León    60        Esquina Abarrotes       08:00       22:00
## 8  Nuevo León    60        Esquina Abarrotes       08:00       22:00
## 9  Nuevo León    60        Esquina Abarrotes       08:00       22:00
## 10 Nuevo León    60        Esquina Abarrotes       08:00       22:00
tail(df)# ultimos 6 renglones de tabla.
##        vcClaveTienda DescGiro Codigo.Barras PLU      Fecha     Hora
## 200620         MX005 Depósito   7.62221e+12  NA 12/07/2020 01:08:25
## 200621         MX005 Depósito   7.62221e+12  NA 23/10/2020 22:17:37
## 200622         MX005 Depósito   7.62221e+12  NA 10/10/2020 20:30:20
## 200623         MX005 Depósito   7.62221e+12  NA 10/10/2020 22:40:43
## 200624         MX005 Depósito   7.62221e+12  NA 27/06/2020 22:30:19
## 200625         MX005 Depósito   7.62221e+12  NA 26/06/2020 23:43:34
##                    Marca    Fabricante                          Producto Precio
## 200620 TRIDENT XTRA CARE CADBURY ADAMS Trident Xtracare Freshmint 16.32G      9
## 200621 TRIDENT XTRA CARE CADBURY ADAMS Trident Xtracare Freshmint 16.32G      9
## 200622 TRIDENT XTRA CARE CADBURY ADAMS Trident Xtracare Freshmint 16.32G      9
## 200623 TRIDENT XTRA CARE CADBURY ADAMS Trident Xtracare Freshmint 16.32G      9
## 200624 TRIDENT XTRA CARE CADBURY ADAMS Trident Xtracare Freshmint 16.32G      9
## 200625 TRIDENT XTRA CARE CADBURY ADAMS Trident Xtracare Freshmint 16.32G      9
##        Ult.Costo Unidades F.Ticket NombreDepartamento NombreFamilia
## 200620      6.92        1   103100          Abarrotes      Dulcería
## 200621      6.92        1   116598          Abarrotes      Dulcería
## 200622      6.92        1   114886          Abarrotes      Dulcería
## 200623      6.92        1   114955          Abarrotes      Dulcería
## 200624      6.92        1   101121          Abarrotes      Dulcería
## 200625      6.92        1   100879          Abarrotes      Dulcería
##        NombreCategoria       Estado Mts.2 Tipo.ubicación       Giro Hora.inicio
## 200620 Gomas de Mazcar Quintana Roo    58        Esquina Mini súper       08:00
## 200621 Gomas de Mazcar Quintana Roo    58        Esquina Mini súper       08:00
## 200622 Gomas de Mazcar Quintana Roo    58        Esquina Mini súper       08:00
## 200623 Gomas de Mazcar Quintana Roo    58        Esquina Mini súper       08:00
## 200624 Gomas de Mazcar Quintana Roo    58        Esquina Mini súper       08:00
## 200625 Gomas de Mazcar Quintana Roo    58        Esquina Mini súper       08:00
##        Hora.cierre
## 200620       21:00
## 200621       21:00
## 200622       21:00
## 200623       21:00
## 200624       21:00
## 200625       21:00
#instalar paquetes janitor

library(janitor) 
## 
## Attaching package: 'janitor'
## The following objects are masked from 'package:stats':
## 
##     chisq.test, fisher.test
#library(dplyr) 

#count(df,vcClaveTienda, sort = TRUE)
#count(df,DescGiro, sort = TRUE)
#count(df,Fecha, sort = TRUE)
#count(df,Hora, sort = TRUE)
#count(df,Marca, sort = TRUE)
#count(df,Fabricante, sort = TRUE)
#count(df,Producto, sort = TRUE)
##count(df,NombreDepartamento, sort = TRUE)
#count(df,NombreFamilia, sort = TRUE)
#count(df,NombreCategoria, sort = TRUE)
#count(df,Estado, sort = TRUE)
#count(df,Tipo.ubicación, sort = TRUE)
#count(df,Giro, sort = TRUE)
#count(df,Hora.inicio, sort = TRUE)
#count(df,Hora.cierre, sort = TRUE)

#tabyl(df,vcClaveTienda,NombreDepartamento)

Con lo antorerior se encontraron las siguientes observaciones: 1. La variable PLU tiene mas de 190000 NA’s. 2. Las variables fecha, hora, hora.inicio y hora.cierre no tienen formato correcto. 3. Existen precios negativos 4. No se observo variable ventas o subtotal

Tecnincas para limpieza de datos

Tecnica 1. Remover valores irrelevantes

# Eliminar columnas

df <- subset(df, select = -c(PLU, Codigo.Barras))

#Eliminar renglones

df <- df[df$Precio > 0,]

Tecninca dos. Eliminar valores duplicados

#df <- distinct(df)

Tecnica tres. Corregir errores

df$Unidades<- ceiling(df$Unidades)
summary(df)
##  vcClaveTienda        DescGiro            Fecha               Hora          
##  Length:200478      Length:200478      Length:200478      Length:200478     
##  Class :character   Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character   Mode  :character  
##                                                                             
##                                                                             
##                                                                             
##     Marca            Fabricante          Producto             Precio       
##  Length:200478      Length:200478      Length:200478      Min.   :   0.50  
##  Class :character   Class :character   Class :character   1st Qu.:  11.00  
##  Mode  :character   Mode  :character   Mode  :character   Median :  16.00  
##                                                           Mean   :  19.45  
##                                                           3rd Qu.:  25.00  
##                                                           Max.   :1000.00  
##    Ult.Costo         Unidades         F.Ticket      NombreDepartamento
##  Min.   :  0.38   Min.   : 1.000   Min.   :     1   Length:200478     
##  1st Qu.:  8.46   1st Qu.: 1.000   1st Qu.: 33977   Class :character  
##  Median : 12.31   Median : 1.000   Median :106034   Mode  :character  
##  Mean   : 15.31   Mean   : 1.261   Mean   :194096                     
##  3rd Qu.: 19.23   3rd Qu.: 1.000   3rd Qu.:383062                     
##  Max.   :769.23   Max.   :96.000   Max.   :450040                     
##  NombreFamilia      NombreCategoria       Estado              Mts.2     
##  Length:200478      Length:200478      Length:200478      Min.   :47.0  
##  Class :character   Class :character   Class :character   1st Qu.:53.0  
##  Mode  :character   Mode  :character   Mode  :character   Median :60.0  
##                                                           Mean   :56.6  
##                                                           3rd Qu.:60.0  
##                                                           Max.   :62.0  
##  Tipo.ubicación         Giro           Hora.inicio        Hora.cierre       
##  Length:200478      Length:200478      Length:200478      Length:200478     
##  Class :character   Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character   Mode  :character  
##                                                                             
##                                                                             
## 

####Tecnica cuatro. Cambiar tipo de variable.

df$Fecha <- as.Date(df$Fecha, format = "%d/%m/%Y" )
# si en la fecha el año esta en formato de yyyy, se usa Y, pero si tienes namas en yy, se usa y. 
str(df)
## 'data.frame':    200478 obs. of  20 variables:
##  $ vcClaveTienda     : chr  "MX001" "MX001" "MX001" "MX001" ...
##  $ DescGiro          : chr  "Abarrotes" "Abarrotes" "Abarrotes" "Abarrotes" ...
##  $ Fecha             : Date, format: "2020-06-19" "2020-06-19" ...
##  $ Hora              : chr  "08:16:21" "08:23:33" "08:24:33" "08:24:33" ...
##  $ Marca             : chr  "NUTRI LECHE" "DAN UP" "BIMBO" "PEPSI" ...
##  $ Fabricante        : chr  "MEXILAC" "DANONE DE MEXICO" "GRUPO BIMBO" "PEPSI-COLA MEXICANA" ...
##  $ Producto          : chr  "Nutri Leche 1 Litro" "DANUP STRAWBERRY P/BEBER 350GR NAL" "Rebanadas Bimbo 2Pz" "Pepsi N.R. 400Ml" ...
##  $ Precio            : num  16 14 5 8 19.5 16 14 5 8 19.5 ...
##  $ Ult.Costo         : num  12.3 14 5 8 15 ...
##  $ Unidades          : num  1 1 1 1 1 1 1 1 1 1 ...
##  $ F.Ticket          : int  1 2 3 3 4 1 2 3 3 4 ...
##  $ NombreDepartamento: chr  "Abarrotes" "Abarrotes" "Abarrotes" "Abarrotes" ...
##  $ NombreFamilia     : chr  "Lacteos y Refrigerados" "Lacteos y Refrigerados" "Pan y Tortilla" "Bebidas" ...
##  $ NombreCategoria   : chr  "Leche" "Yogurt" "Pan Dulce Empaquetado" "Refrescos Plástico (N.R.)" ...
##  $ Estado            : chr  "Nuevo León" "Nuevo León" "Nuevo León" "Nuevo León" ...
##  $ Mts.2             : int  60 60 60 60 60 60 60 60 60 60 ...
##  $ Tipo.ubicación    : chr  "Esquina" "Esquina" "Esquina" "Esquina" ...
##  $ Giro              : chr  "Abarrotes" "Abarrotes" "Abarrotes" "Abarrotes" ...
##  $ Hora.inicio       : chr  "08:00" "08:00" "08:00" "08:00" ...
##  $ Hora.cierre       : chr  "22:00" "22:00" "22:00" "22:00" ...

Tecnica 5. Tratamiento de valores faltantes (NA)

# 1. cuantos nas hay?

sum(is.na(df))
## [1] 0
# cuantos na hay por variable

sapply(df, function(x) sum(is.na(x)))
##      vcClaveTienda           DescGiro              Fecha               Hora 
##                  0                  0                  0                  0 
##              Marca         Fabricante           Producto             Precio 
##                  0                  0                  0                  0 
##          Ult.Costo           Unidades           F.Ticket NombreDepartamento 
##                  0                  0                  0                  0 
##      NombreFamilia    NombreCategoria             Estado              Mts.2 
##                  0                  0                  0                  0 
##     Tipo.ubicación               Giro        Hora.inicio        Hora.cierre 
##                  0                  0                  0                  0
# Birrar registros con na de tabla

# df <- na.omit(df)

# Reemplazar na con ceros

# df[is.na(df)] <- 0

# reemplazar nas con promedio
# df$PLU[is.na(df$PLU)] <- mean(df$PLU, na.rm=TRUE)

Tecnica 6. Metodos estadisticos.

boxplot(df$Precio, horizontal = TRUE)

boxplot(df$Unidades, horizontal = TRUE)

Agregar columnas a base de datos

df$Subtotal <- df$Ult.Costo * df$Unidades

Exporar base de datos limpia

# write.csv(df, file = "abarrotes_bd_limpia.csv", row.names = FALSE)
LS0tCnRpdGxlOiAiTGltcGllemEgZGUgZGF0b3MiCmF1dGhvcjogIkVkdWFyZG8gLSBBMDA4MzE0NDciCmRhdGU6ICcyMDIzLTA5LTEyJwpvdXRwdXQ6IAogIGh0bWxfZG9jdW1lbnQ6IAogICAgdG9jOiBUUlVFCiAgICB0b2NfZmxvYXQ6IFRSVUUKICAgIGNvZGVfZG93bmxvYWQ6IFRSVUUKICAgIHRoZW1lOiAic2ltcGxleCIKICAgIGhpZ2hsaWdodDogInRhbmdvIgotLS0KCiFbXSgvVXNlcnMvZWR1YXJkb2dhcnphL0Rlc2t0b3AvU2NyZWVuc2hvdCAyMDIzLTA5LTEyIGF0IDA5LjE2LjUzLnBuZykKCiMjIENhcmdhciBCYXNlIGRlIERhdG9zCmBgYHtyfQpkZiA8LSByZWFkLmNzdigiL1VzZXJzL2VkdWFyZG9nYXJ6YS9EZXNrdG9wL1M3L0Jvb3RjYW1wUHJvZ3JhbWFjaW/MgW5TVC9hYmFycm90ZXMuY3N2IikKYGBgCgojIyBFbnRlbmRlciBiYXNlIGRlIGRhdG9zCmBgYHtyfQpyZXN1bWVuIDwtIHN1bW1hcnkoZGYpCnJlc3VtZW4KCnN0cihkZikgI3Zpc3VhbGl6YSBlbiB0ZXh0byBsYXMgdmFyaWFibGVzLCBzdSB0aXBvIHkgZWplbXBsb3MKCmhlYWQoZGYsMTApICMgTXVlc3RyYSBwcmltZXJvcyAxMCByZW5nbG9uZXMgZGUgbGEgdGFibGEKCnRhaWwoZGYpIyB1bHRpbW9zIDYgcmVuZ2xvbmVzIGRlIHRhYmxhLgoKI2luc3RhbGFyIHBhcXVldGVzIGphbml0b3IKCmxpYnJhcnkoamFuaXRvcikgCiNsaWJyYXJ5KGRwbHlyKSAKCiNjb3VudChkZix2Y0NsYXZlVGllbmRhLCBzb3J0ID0gVFJVRSkKI2NvdW50KGRmLERlc2NHaXJvLCBzb3J0ID0gVFJVRSkKI2NvdW50KGRmLEZlY2hhLCBzb3J0ID0gVFJVRSkKI2NvdW50KGRmLEhvcmEsIHNvcnQgPSBUUlVFKQojY291bnQoZGYsTWFyY2EsIHNvcnQgPSBUUlVFKQojY291bnQoZGYsRmFicmljYW50ZSwgc29ydCA9IFRSVUUpCiNjb3VudChkZixQcm9kdWN0bywgc29ydCA9IFRSVUUpCiMjY291bnQoZGYsTm9tYnJlRGVwYXJ0YW1lbnRvLCBzb3J0ID0gVFJVRSkKI2NvdW50KGRmLE5vbWJyZUZhbWlsaWEsIHNvcnQgPSBUUlVFKQojY291bnQoZGYsTm9tYnJlQ2F0ZWdvcmlhLCBzb3J0ID0gVFJVRSkKI2NvdW50KGRmLEVzdGFkbywgc29ydCA9IFRSVUUpCiNjb3VudChkZixUaXBvLnViaWNhY2nDs24sIHNvcnQgPSBUUlVFKQojY291bnQoZGYsR2lybywgc29ydCA9IFRSVUUpCiNjb3VudChkZixIb3JhLmluaWNpbywgc29ydCA9IFRSVUUpCiNjb3VudChkZixIb3JhLmNpZXJyZSwgc29ydCA9IFRSVUUpCgojdGFieWwoZGYsdmNDbGF2ZVRpZW5kYSxOb21icmVEZXBhcnRhbWVudG8pCmBgYAoKQ29uIGxvIGFudG9yZXJpb3Igc2UgZW5jb250cmFyb24gbGFzIHNpZ3VpZW50ZXMgb2JzZXJ2YWNpb25lczoKMS4gTGEgdmFyaWFibGUgUExVIHRpZW5lIG1hcyBkZSAxOTAwMDAgTkEncy4KMi4gTGFzIHZhcmlhYmxlcyBmZWNoYSwgaG9yYSwgaG9yYS5pbmljaW8geSBob3JhLmNpZXJyZSBubyB0aWVuZW4gZm9ybWF0byBjb3JyZWN0by4gCjMuIEV4aXN0ZW4gcHJlY2lvcyBuZWdhdGl2b3MKNC4gTm8gc2Ugb2JzZXJ2byB2YXJpYWJsZSB2ZW50YXMgbyBzdWJ0b3RhbAoKIyMgVGVjbmluY2FzIHBhcmEgbGltcGllemEgZGUgZGF0b3MKIyMjIyBUZWNuaWNhIDEuIFJlbW92ZXIgdmFsb3JlcyBpcnJlbGV2YW50ZXMKCgpgYGB7cn0KIyBFbGltaW5hciBjb2x1bW5hcwoKZGYgPC0gc3Vic2V0KGRmLCBzZWxlY3QgPSAtYyhQTFUsIENvZGlnby5CYXJyYXMpKQoKI0VsaW1pbmFyIHJlbmdsb25lcwoKZGYgPC0gZGZbZGYkUHJlY2lvID4gMCxdCmBgYAoKIyMjIyBUZWNuaW5jYSBkb3MuIEVsaW1pbmFyIHZhbG9yZXMgZHVwbGljYWRvcwoKYGBge3J9CgojZGYgPC0gZGlzdGluY3QoZGYpCgpgYGAKCiMjIyMgVGVjbmljYSB0cmVzLiBDb3JyZWdpciBlcnJvcmVzCmBgYHtyfQpkZiRVbmlkYWRlczwtIGNlaWxpbmcoZGYkVW5pZGFkZXMpCnN1bW1hcnkoZGYpCmBgYAoKIyMjI1RlY25pY2EgY3VhdHJvLiBDYW1iaWFyIHRpcG8gZGUgdmFyaWFibGUuCgpgYGB7cn0KZGYkRmVjaGEgPC0gYXMuRGF0ZShkZiRGZWNoYSwgZm9ybWF0ID0gIiVkLyVtLyVZIiApCiMgc2kgZW4gbGEgZmVjaGEgZWwgYcOxbyBlc3RhIGVuIGZvcm1hdG8gZGUgeXl5eSwgc2UgdXNhIFksIHBlcm8gc2kgdGllbmVzIG5hbWFzIGVuIHl5LCBzZSB1c2EgeS4gCnN0cihkZikKYGBgCgojIyMjIFRlY25pY2EgNS4gVHJhdGFtaWVudG8gZGUgdmFsb3JlcyBmYWx0YW50ZXMgKE5BKQpgYGB7cn0KIyAxLiBjdWFudG9zIG5hcyBoYXk/CgpzdW0oaXMubmEoZGYpKQojIGN1YW50b3MgbmEgaGF5IHBvciB2YXJpYWJsZQoKc2FwcGx5KGRmLCBmdW5jdGlvbih4KSBzdW0oaXMubmEoeCkpKQoKIyBCaXJyYXIgcmVnaXN0cm9zIGNvbiBuYSBkZSB0YWJsYQoKIyBkZiA8LSBuYS5vbWl0KGRmKQoKIyBSZWVtcGxhemFyIG5hIGNvbiBjZXJvcwoKIyBkZltpcy5uYShkZildIDwtIDAKCiMgcmVlbXBsYXphciBuYXMgY29uIHByb21lZGlvCiMgZGYkUExVW2lzLm5hKGRmJFBMVSldIDwtIG1lYW4oZGYkUExVLCBuYS5ybT1UUlVFKQpgYGAKIyMjIyBUZWNuaWNhIDYuIE1ldG9kb3MgZXN0YWRpc3RpY29zLgpgYGB7cn0KYm94cGxvdChkZiRQcmVjaW8sIGhvcml6b250YWwgPSBUUlVFKQpib3hwbG90KGRmJFVuaWRhZGVzLCBob3Jpem9udGFsID0gVFJVRSkKYGBgCgoKIyMgQWdyZWdhciBjb2x1bW5hcyBhIGJhc2UgZGUgZGF0b3MKYGBge3J9CmRmJFN1YnRvdGFsIDwtIGRmJFVsdC5Db3N0byAqIGRmJFVuaWRhZGVzCmBgYAoKIyMgRXhwb3JhciBiYXNlIGRlIGRhdG9zIGxpbXBpYQoKYGBge3J9CiMgd3JpdGUuY3N2KGRmLCBmaWxlID0gImFiYXJyb3Rlc19iZF9saW1waWEuY3N2Iiwgcm93Lm5hbWVzID0gRkFMU0UpCmBgYAoKCg==