ENTREGABLE 2.4

a. FORM – Producción

Importar base de datos

#file.choose()

prod<-read.csv("/Users/elenavela/Downloads/produccion.csv")

1) ¿Cuántas variables y cuantos registros tiene la base de datos INICIALMENTE?

str(prod)
## 'data.frame':    2568 obs. of  13 variables:
##  $ CLIENTE             : chr  "VARROC" "VARROC" "VARROC" "DENSO" ...
##  $ ID.FORM             : chr  "VL-017-13938" "VL-017-13936" "VL-017-14729" "" ...
##  $ PRODUCTO            : chr  "763 . KIT. CAJA." "747 KIT. CAJA HSC. ( 2 Partes)" "747 KIT. TAPA." "TOYOTA. MCV. Insterto D 2R. CORTE. 1 Golpe = 12 piezas. ( 9 Pza. / Celda)." ...
##  $ PIEZAS.PROG.        : chr  "199" "57" "68" "192" ...
##  $ TMO..MIN.           : chr  "15" "10" "10" "15" ...
##  $ HR..FIN             : chr  "9:15" "9:25" "9:35" "9:50" ...
##  $ ESTACION.ARRANQUE   : chr  "C1" "C1Y2" "C1Y2" "C1" ...
##  $ Laminas.procesadas  : chr  "201" "116" "69" "49" ...
##  $ INICIO.SEP.UP       : chr  "9:00" "9:26" "10:02" "10:12" ...
##  $ FIN.INICIO.DE.SEP.UP: chr  "9:12" "9:31" "10:09" "10.17" ...
##  $ INICIO.de.PROCESO   : chr  "9:13" "9:32" "10:09" "10:18" ...
##  $ FIN.de.PROCESO      : chr  "9:26" "9:53" "10.12" "10:20" ...
##  $ TIEMPO.CALIDAD      : chr  "1" "1" "1" "1" ...

Se obtienen 13 variables y 2,568 registros del mes de agosto de la base de datos “Producción de Cartón”, específicamente de Tiempo de Máquinas.

4) Aplica al menos 2 técnicas de limpieza de bases de datos y explícalas brevemente, ¿por qué realizaste esas técnicas?

Se hace el paso 4 primero, antes de clasificar.

Técnica 1, REMOVER DATOS IRRELEVANTES
No todas las variables nos interesan, o aportan mucho, al análisis que se pretende hacer. Se ha definido que las variables con las que se desea quedar son las siguientes: cliente, piezas programadas, tiempo mínimo, láminas procesadas y tiempo de calidad.

Se eliminan columnas

prod2<-prod
prod2<-subset(prod2,select=-c(ID.FORM,PRODUCTO,HR..FIN,ESTACION.ARRANQUE,INICIO.SEP.UP,FIN.INICIO.DE.SEP.UP,INICIO.de.PROCESO,FIN.de.PROCESO))
summary(prod2)
##    CLIENTE          PIEZAS.PROG.        TMO..MIN.         Laminas.procesadas
##  Length:2568        Length:2568        Length:2568        Length:2568       
##  Class :character   Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character   Mode  :character  
##  TIEMPO.CALIDAD    
##  Length:2568       
##  Class :character  
##  Mode  :character

Técnica 4, CONVERTIR TIPO DE DATOS

Para poder determinar los valores faltantes, es necesario convertir los valores de carácter a enteros/hora/fecha.

Carácter a entero

prod3<-prod2
prod3$PIEZAS.PROG.<-as.integer(prod3$PIEZAS.PROG.)
## Warning: NAs introduced by coercion
str(prod3)
## 'data.frame':    2568 obs. of  5 variables:
##  $ CLIENTE           : chr  "VARROC" "VARROC" "VARROC" "DENSO" ...
##  $ PIEZAS.PROG.      : int  199 57 68 192 192 400 80 104 104 160 ...
##  $ TMO..MIN.         : chr  "15" "10" "10" "15" ...
##  $ Laminas.procesadas: chr  "201" "116" "69" "49" ...
##  $ TIEMPO.CALIDAD    : chr  "1" "1" "1" "1" ...
summary(prod3)
##    CLIENTE           PIEZAS.PROG.     TMO..MIN.         Laminas.procesadas
##  Length:2568        Min.   :   1.0   Length:2568        Length:2568       
##  Class :character   1st Qu.: 100.0   Class :character   Class :character  
##  Mode  :character   Median : 176.0   Mode  :character   Mode  :character  
##                     Mean   : 183.5                                        
##                     3rd Qu.: 201.0                                        
##                     Max.   :1280.0                                        
##                     NA's   :164                                           
##  TIEMPO.CALIDAD    
##  Length:2568       
##  Class :character  
##  Mode  :character  
##                    
##                    
##                    
## 

Carácter a hora

prod4<-prod3
prod4$TMO..MIN.<-as.integer(prod4$TMO..MIN.)
## Warning: NAs introduced by coercion
str(prod4)
## 'data.frame':    2568 obs. of  5 variables:
##  $ CLIENTE           : chr  "VARROC" "VARROC" "VARROC" "DENSO" ...
##  $ PIEZAS.PROG.      : int  199 57 68 192 192 400 80 104 104 160 ...
##  $ TMO..MIN.         : int  15 10 10 15 15 30 15 15 15 20 ...
##  $ Laminas.procesadas: chr  "201" "116" "69" "49" ...
##  $ TIEMPO.CALIDAD    : chr  "1" "1" "1" "1" ...
summary(prod4)
##    CLIENTE           PIEZAS.PROG.      TMO..MIN.      Laminas.procesadas
##  Length:2568        Min.   :   1.0   Min.   :  0.00   Length:2568       
##  Class :character   1st Qu.: 100.0   1st Qu.: 15.00   Class :character  
##  Mode  :character   Median : 176.0   Median : 20.00   Mode  :character  
##                     Mean   : 183.5   Mean   : 22.59                     
##                     3rd Qu.: 201.0   3rd Qu.: 25.00                     
##                     Max.   :1280.0   Max.   :150.00                     
##                     NA's   :164      NA's   :706                        
##  TIEMPO.CALIDAD    
##  Length:2568       
##  Class :character  
##  Mode  :character  
##                    
##                    
##                    
## 

Carácter a entero

prod5<-prod4
prod5$Laminas.procesadas<-as.integer(prod5$Laminas.procesadas)
## Warning: NAs introduced by coercion
str(prod5)
## 'data.frame':    2568 obs. of  5 variables:
##  $ CLIENTE           : chr  "VARROC" "VARROC" "VARROC" "DENSO" ...
##  $ PIEZAS.PROG.      : int  199 57 68 192 192 400 80 104 104 160 ...
##  $ TMO..MIN.         : int  15 10 10 15 15 30 15 15 15 20 ...
##  $ Laminas.procesadas: int  201 116 69 49 49 801 41 53 53 55 ...
##  $ TIEMPO.CALIDAD    : chr  "1" "1" "1" "1" ...
summary(prod5)
##    CLIENTE           PIEZAS.PROG.      TMO..MIN.      Laminas.procesadas
##  Length:2568        Min.   :   1.0   Min.   :  0.00   Min.   :   0.0    
##  Class :character   1st Qu.: 100.0   1st Qu.: 15.00   1st Qu.:   0.0    
##  Mode  :character   Median : 176.0   Median : 20.00   Median :  54.0    
##                     Mean   : 183.5   Mean   : 22.59   Mean   : 108.5    
##                     3rd Qu.: 201.0   3rd Qu.: 25.00   3rd Qu.: 200.0    
##                     Max.   :1280.0   Max.   :150.00   Max.   :1125.0    
##                     NA's   :164      NA's   :706      NA's   :649       
##  TIEMPO.CALIDAD    
##  Length:2568       
##  Class :character  
##  Mode  :character  
##                    
##                    
##                    
## 

Carácter a hora

prod6<-prod5
prod6$TIEMPO.CALIDAD<-as.integer(prod6$TIEMPO.CALIDAD)
## Warning: NAs introduced by coercion
str(prod6)
## 'data.frame':    2568 obs. of  5 variables:
##  $ CLIENTE           : chr  "VARROC" "VARROC" "VARROC" "DENSO" ...
##  $ PIEZAS.PROG.      : int  199 57 68 192 192 400 80 104 104 160 ...
##  $ TMO..MIN.         : int  15 10 10 15 15 30 15 15 15 20 ...
##  $ Laminas.procesadas: int  201 116 69 49 49 801 41 53 53 55 ...
##  $ TIEMPO.CALIDAD    : int  1 1 1 1 1 1 1 1 1 1 ...
summary(prod6)
##    CLIENTE           PIEZAS.PROG.      TMO..MIN.      Laminas.procesadas
##  Length:2568        Min.   :   1.0   Min.   :  0.00   Min.   :   0.0    
##  Class :character   1st Qu.: 100.0   1st Qu.: 15.00   1st Qu.:   0.0    
##  Mode  :character   Median : 176.0   Median : 20.00   Median :  54.0    
##                     Mean   : 183.5   Mean   : 22.59   Mean   : 108.5    
##                     3rd Qu.: 201.0   3rd Qu.: 25.00   3rd Qu.: 200.0    
##                     Max.   :1280.0   Max.   :150.00   Max.   :1125.0    
##                     NA's   :164      NA's   :706      NA's   :649       
##  TIEMPO.CALIDAD  
##  Min.   : 0.000  
##  1st Qu.: 1.000  
##  Median : 1.000  
##  Mean   : 0.927  
##  3rd Qu.: 1.000  
##  Max.   :25.000  
##  NA's   :608

Técnica 5, VALORES FALTANTES

Al haber cambiado ya los valores a su forma correspondiente, observamos que existe una gran cantidad de valores faltantes (aprox. la mitad). Se ha optado por eliminar estos registros, debido a que al poner un cero o un promedio, se podría no tener un análisis ilustrativo.

¿Cuántos NA tengo por variables?

sapply(prod6,function(x) sum(is.na(x)))
##            CLIENTE       PIEZAS.PROG.          TMO..MIN. Laminas.procesadas 
##                  0                164                706                649 
##     TIEMPO.CALIDAD 
##                608

Borrar registros de valores faltantes

prod7<-prod6
prod7<-na.omit(prod7)

summary(prod7)
##    CLIENTE           PIEZAS.PROG.      TMO..MIN.      Laminas.procesadas
##  Length:1475        Min.   :   1.0   Min.   :  0.00   Min.   :   0.0    
##  Class :character   1st Qu.: 100.0   1st Qu.: 15.00   1st Qu.:  37.0    
##  Mode  :character   Median : 192.0   Median : 20.00   Median : 100.0    
##                     Mean   : 173.5   Mean   : 22.23   Mean   : 133.9    
##                     3rd Qu.: 200.0   3rd Qu.: 25.00   3rd Qu.: 202.0    
##                     Max.   :1200.0   Max.   :120.00   Max.   :1125.0    
##  TIEMPO.CALIDAD  
##  Min.   : 0.000  
##  1st Qu.: 1.000  
##  Median : 1.000  
##  Mean   : 1.064  
##  3rd Qu.: 1.000  
##  Max.   :22.000

¿Cuántos NA tengo por variables?

sapply(prod7,function(x) sum(is.na(x)))
##            CLIENTE       PIEZAS.PROG.          TMO..MIN. Laminas.procesadas 
##                  0                  0                  0                  0 
##     TIEMPO.CALIDAD 
##                  0
str(prod7)
## 'data.frame':    1475 obs. of  5 variables:
##  $ CLIENTE           : chr  "VARROC" "VARROC" "VARROC" "DENSO" ...
##  $ PIEZAS.PROG.      : int  199 57 68 192 192 400 80 104 104 160 ...
##  $ TMO..MIN.         : int  15 10 10 15 15 30 15 15 15 20 ...
##  $ Laminas.procesadas: int  201 116 69 49 49 801 41 53 53 55 ...
##  $ TIEMPO.CALIDAD    : int  1 1 1 1 1 1 1 1 1 1 ...
##  - attr(*, "na.action")= 'omit' Named int [1:1093] 18 22 23 29 30 31 32 33 34 35 ...
##   ..- attr(*, "names")= chr [1:1093] "18" "22" "23" "29" ...

Ya se han eliminado los registros con NAs

Exportar nueva base de datos (limpia)

produccion_limpia <-prod7
write.csv(produccion_limpia, file ="produccion_limpia.csv", row.names = FALSE)

1.2) ¿Cuántas variables y cuantos registros tiene la base de datos DESPUÉS de la limpieza?

str(prod7)
## 'data.frame':    1475 obs. of  5 variables:
##  $ CLIENTE           : chr  "VARROC" "VARROC" "VARROC" "DENSO" ...
##  $ PIEZAS.PROG.      : int  199 57 68 192 192 400 80 104 104 160 ...
##  $ TMO..MIN.         : int  15 10 10 15 15 30 15 15 15 20 ...
##  $ Laminas.procesadas: int  201 116 69 49 49 801 41 53 53 55 ...
##  $ TIEMPO.CALIDAD    : int  1 1 1 1 1 1 1 1 1 1 ...
##  - attr(*, "na.action")= 'omit' Named int [1:1093] 18 22 23 29 30 31 32 33 34 35 ...
##   ..- attr(*, "names")= chr [1:1093] "18" "22" "23" "29" ...

Se tienen 5 variables y 1,475 registros.

2) Clasifica cada variable en cualitativa, cuantitativa discreta o cuantitativa continua.

Las cinco variables son clasificadas correspondiendo a lo que dan a conocer.

Variable Type
Cliente Cualitativa
Piezas programadas Cuantitativa (discreta)
Tiempo mínimo Cuantitativa (continua)
Láminas procesadas Cuantitativa (discreta)
Tiempo calidad Cuantitativa (continua)

3) Elige la escala de medición de cada variable.

Las cinco variables son clasificadas correspondiendo a como se miden.

Variable Medicion
Cliente No aplica
Piezas programadas Unidades de producción
Tiempo mínimo Minutos
Láminas procesadas Unidades de producción
Tiempo calidad Horas

5) Análisis estadístico descriptivo.

#install.packages("epiDisplay")
library(epiDisplay)
## Loading required package: foreign
## Loading required package: survival
## Loading required package: MASS
## Loading required package: nnet

Tabla de frecuencia y gráfica de datos CUANTITATIVOS: Tiempo de Calidad

Primeramente, se analiza el tiempo de calidad. A partir de la tabla de frecuencia y de su gráfica, observamos que la gran parte de la producción analizada toma un valor de tiempo de calidad de una hora.

tiempo_de_calidad<-table(prod7$TIEMPO.CALIDAD)
knitr::kable(tiempo_de_calidad)
Var1 Freq
0 141
1 1271
2 34
3 8
4 1
5 4
7 2
8 1
9 2
10 6
11 2
17 1
21 1
22 1
?tab1
tab1(prod7$TIEMPO.CALIDAD,sort.group = FALSE,graph=TRUE)

## prod7$TIEMPO.CALIDAD : 
##         Frequency Percent Cum. percent
## 0             141     9.6          9.6
## 1            1271    86.2         95.7
## 2              34     2.3         98.0
## 3               8     0.5         98.6
## 4               1     0.1         98.6
## 5               4     0.3         98.9
## 7               2     0.1         99.1
## 8               1     0.1         99.1
## 9               2     0.1         99.3
## 10              6     0.4         99.7
## 11              2     0.1         99.8
## 17              1     0.1         99.9
## 21              1     0.1         99.9
## 22              1     0.1        100.0
##   Total      1475   100.0        100.0

No aplican las tablas cruzadas

Gráfica de datos CUANTITATIVOS: Tiempo Mínimo
Siguientemente, observamos el tiempo mínimo (por minutos) de la producción. La gran parte se encuentrra entre los 0 y los 30 minutos.

hist((prod7$TMO..MIN.),col=c("orange"),main="Tiempo Mínimo",xlab="Minutos")

Gráfica de datos CUANTITATIVOS: Piezas Programadas
Continuando con las piezas programadas, vemos que la gran parte de las piezas programadas rondan entre 0 y 200 unidades.

hist((prod7$PIEZAS.PROG.),col=c("yellow"),main="Piezas Programadas",xlab="Unidades")

Gráfica de datos CUANTITATIVOS: Láminas Procesadas
Con las láminas procesadas, vemos que la mayor frecuencia es está entre el 0 y 100, con un importante número también visto entre 100 y 300.

hist((prod7$Laminas.procesadas),col=c("darkgreen"),main="Láminas Procesadas",xlab="Unidades")

Gráfica de dispersión: Piezas programadas
Tal como lo vimos en el histograma, vemos que la mayor concentración de datos está entre el 100 y 200. No resulta demasiado disperso, sin embargo hay un dato que se sale de lo “normal”, puesto que lo encontramos arriba de los miles.

boxplot(prod7$PIEZAS.PROG.,col=c("orange"))

b. FORM – Scrap

Importar base de datos

#file.choose()
scrap<-read.csv("/Users/elenavela/Downloads/scrap.csv")

1) ¿Cuántas variables y cuantos registros tiene la base de datos INICIALMENTE?

str(scrap)
## 'data.frame':    250 obs. of  9 variables:
##  $ Referencia          : chr  "SP/08731" "SP/08730" "SP/08729" "SP/08728" ...
##  $ Fecha               : chr  "31/08/22" "31/08/22" "31/08/22" "31/08/22" ...
##  $ Hora                : chr  "14:55:40" "14:49:25" "13:49:29" "09:30:07" ...
##  $ Producto            : chr  "[BACKFRAME 60% CUELLO ARMADO] 18805. 60% Backframe. Cuello Armado." "[N61506747 CAJA] N61506747. Kit. Caja." "[N61506729 SEPARADOR] N61506729. Kit. Separador." "[341332 DIVISOR - U611 & U625] 341332. U611. U625. Divisor Troquelado." ...
##  $ Cantidad            : num  2 1 1 31 1 1 1 9 2 1 ...
##  $ Unidad.de.medida    : chr  "Unidad(es)" "Unidad(es)" "Unidad(es)" "Unidad(es)" ...
##  $ Ubicación.de.origen : chr  "SAB/Calidad/Entrega de PT" "SAB/Calidad/Entrega de PT" "SAB/Calidad/Entrega de PT" "SAB/Pre-Production" ...
##  $ Ubicación.de.desecho: chr  "Virtual Locations/Scrapped" "Virtual Locations/Scrapped" "Virtual Locations/Scrapped" "Virtual Locations/Scrapped" ...
##  $ Estado              : chr  "Hecho" "Hecho" "Hecho" "Hecho" ...

Existen 9 variables, con 250 registros en total.

4) Aplica al menos 2 técnicas de limpieza de bases de datos y explícalas brevemente, ¿por qué realizaste esas técnicas?

Técnica 1, REMOVER DATOS IRRELEVANTES
No todas las variables no interesan, o aportan mucho, al análisis que se pretende hacer. Se ha definido que las variables con las que se desea quedar son las siguientes: fecha, cantidad, y ubicación de origen.

Se eliminan columnas

scrap2<-scrap
scrap2<-subset(scrap2,select=-c(Referencia,Hora,Producto,Unidad.de.medida,Ubicación.de.desecho,Estado))

summary(scrap2)
##     Fecha              Cantidad      Ubicación.de.origen
##  Length:250         Min.   : 0.000   Length:250         
##  Class :character   1st Qu.: 1.000   Class :character   
##  Mode  :character   Median : 2.000   Mode  :character   
##                     Mean   : 6.696                      
##                     3rd Qu.: 7.000                      
##                     Max.   :96.000

Técnica 4, CONVERTIR TIPO DE DATOS

Para poder determinar los valores faltantes, es necesario convertir los valores de carácter a enteros/hora/fecha.

Carácter a fecha

scrap3<-scrap2
scrap3$Fecha<-as.Date(scrap3$Fecha,format="%d/%m/%Y")  
str(scrap3)
## 'data.frame':    250 obs. of  3 variables:
##  $ Fecha              : Date, format: "0022-08-31" "0022-08-31" ...
##  $ Cantidad           : num  2 1 1 31 1 1 1 9 2 1 ...
##  $ Ubicación.de.origen: chr  "SAB/Calidad/Entrega de PT" "SAB/Calidad/Entrega de PT" "SAB/Calidad/Entrega de PT" "SAB/Pre-Production" ...
summary(scrap3)
##      Fecha               Cantidad      Ubicación.de.origen
##  Min.   :0022-08-01   Min.   : 0.000   Length:250         
##  1st Qu.:0022-08-11   1st Qu.: 1.000   Class :character   
##  Median :0022-08-19   Median : 2.000   Mode  :character   
##  Mean   :0022-08-17   Mean   : 6.696                      
##  3rd Qu.:0022-08-25   3rd Qu.: 7.000                      
##  Max.   :0022-08-31   Max.   :96.000

¿Cuántos NA tengo por variable?

sapply(scrap3,function(x) sum(is.na(x)))
##               Fecha            Cantidad Ubicación.de.origen 
##                   0                   0                   0

No se elimina ningún registro.

Exportar nueva base de datos (limpia)

scrap_limpia <-scrap3
write.csv(scrap_limpia, file ="scrap_limpia.csv", row.names = FALSE)

1.2) ¿Cuántas variables y cuantos registros tiene la base de datos DESPUÉS de la limpia?

str(scrap3)
## 'data.frame':    250 obs. of  3 variables:
##  $ Fecha              : Date, format: "0022-08-31" "0022-08-31" ...
##  $ Cantidad           : num  2 1 1 31 1 1 1 9 2 1 ...
##  $ Ubicación.de.origen: chr  "SAB/Calidad/Entrega de PT" "SAB/Calidad/Entrega de PT" "SAB/Calidad/Entrega de PT" "SAB/Pre-Production" ...

Se tienen, finalmente, 250 registros y 3 variables.

2) Clasifica cada variable en cualitativa, cuantitativa discreta o cuantitativa continua

Las tres variables son clasificadas correspondiendo a lo que dan a conocer.

Variable Type
Fecha Cuantitativa (continua)
Cantidad Cuantitativa (discreta)
Ubicación de origen Cualitativa

3) Elige la escala de medición de cada variable.

Las tres variables son clasificadas correspondiendo a como se miden.

Variable Type
Fecha Días
Cantidad Unidades
Ubicación de origen No aplica

5) Análisis estadístico descriptivo

Tabla de frecuencia y gráfica de datos CUALITATIVOS: Ubicación de origen

En este caso, observamos que la gran parte del scrap se encuentra en pre-producción, siguiendo por la verificación de calidad y la entrega, y muy pocas están en post-producción.

knitr::kable(table(scrap3$Ubicación.de.origen))
Var1 Freq
SAB/Calidad/Entrega de PT 58
SAB/Post-Production 13
SAB/Pre-Production 179
tab1(scrap3$Ubicación.de.origen,sort.group = FALSE,graph=TRUE)

## scrap3$Ubicación.de.origen : 
##                           Frequency Percent Cum. percent
## SAB/Calidad/Entrega de PT        58    23.2         23.2
## SAB/Post-Production              13     5.2         28.4
## SAB/Pre-Production              179    71.6        100.0
##   Total                         250   100.0        100.0

Gráfica de datos CUANTITATIVOS: Cantidad

Observando la variable cantidad del scrap, vemos que la gran parte está entre las 0 y 10 unidades, sobrepasando solo muy pocas del total.

hist((scrap3$Cantidad),col=c("lightgreen"),main="Cantidad",xlab="Unidades")

Gráfica de dispersión: Fecha y cantidad

Continuando con un análisis de dispersión, comparamos la fecha y las unidades. Vemos que la mayoría del scrap de agosto fue trabajado en pocas unidades, con muy pocas siendo altas. Todo el mes presenta trabajo.

plot(scrap3$Fecha,scrap3$Cantidad, main = "Dispersión de fecha y unidades",
     pch = 19, frame = FALSE,col=c("orange"))

c. FORM – Merma

#file.choose()
merma<-read.csv("/Users/elenavela/Downloads/merma.csv")
summary(merma)
##     Fecha               Mes                Kilos     
##  Length:50          Length:50          Min.   : 790  
##  Class :character   Class :character   1st Qu.:3178  
##  Mode  :character   Mode  :character   Median :3925  
##                                        Mean   :3709  
##                                        3rd Qu.:4232  
##                                        Max.   :6140

1) ¿Cuántas variables y cuantos registros tiene la base de datos?

str(merma)
## 'data.frame':    50 obs. of  3 variables:
##  $ Fecha: chr  "11/01/22" "11/01/22" "22/01/22" "22/01/22" ...
##  $ Mes  : chr  "ENERO" "ENERO" "ENERO" "ENERO" ...
##  $ Kilos: int  5080 3810 2990 2680 3650 4380 3870 3590 3410 3930 ...

Se obtienen 50 registros y 3 variables.

4) Aplica al menos 2 técnicas de limpieza de bases de datos y explícalas brevemente, ¿por qué realizaste esas técnicas?

Técnica 1, REMOVER DATOS IRRELEVANTES
Desde el excel se han eliminado las filas de “total mes”.

Técnica 4, CONVERTIR TIPO DE DATOS

Para poder determinar los valores faltantes, es necesario convertir los valores de carácter a enteros/hora/fecha.

Carácter a entero

merma2<-merma
merma2$Fecha<-as.Date(merma2$Fecha,format="%d/%m/%Y")  
str(merma2)
## 'data.frame':    50 obs. of  3 variables:
##  $ Fecha: Date, format: "0022-01-11" "0022-01-11" ...
##  $ Mes  : chr  "ENERO" "ENERO" "ENERO" "ENERO" ...
##  $ Kilos: int  5080 3810 2990 2680 3650 4380 3870 3590 3410 3930 ...
summary(merma2)
##      Fecha                Mes                Kilos     
##  Min.   :0022-01-11   Length:50          Min.   : 790  
##  1st Qu.:0022-03-12   Class :character   1st Qu.:3178  
##  Median :0022-05-24   Mode  :character   Median :3925  
##  Mean   :0022-05-25                      Mean   :3709  
##  3rd Qu.:0022-08-10                      3rd Qu.:4232  
##  Max.   :0022-09-21                      Max.   :6140

¿Cuántos NA tengo por variable?

sapply(merma2,function(x) sum(is.na(x)))
## Fecha   Mes Kilos 
##     0     0     0

No existen valores faltantes por variables.

Exportar nueva base de datos (limpia)

merma_limpia <-merma2
write.csv(merma_limpia, file ="mermaa_limpia.csv", row.names = FALSE)

2) Clasifica cada variable en cualitativa, cuantitativa discreta o cuantitativa continua

Las tres variables son clasificadas correspondiendo a lo que dan a conocer.

Variable Type
Fecha Cuantitativa (continua)
Mes Cualitativa
Kilos Cuantitativa (continua

3) Elige la escala de medición de cada variable.

Las tres variables son clasificadas correspondiendo a como se miden.

Variable Medicion
Fecha Día/Mes/Año
Mes No aplica
Kilos Kgs

5) Análisis descriptivo.

Tabla de frecuencia y gráfica de datos CUALITATIVOS: Mes

Viendo los desperdicios por kilos, por mes, vemos que agosto fue un mes que tuvo una gran cantidad de desperdicios, sobre todo al compararla con los otros meses.

knitr::kable(table(merma$Mes))
Var1 Freq
ABRIL 5
AGOSTO 11
ENERO 4
FEBRERO 6
JULIO 5
JUNIO 4
MARZO 6
MAYO 5
SEPTIEMBRE 4
tab1(merma$Mes,sort.group = FALSE,graph=TRUE)

## merma$Mes : 
##            Frequency Percent Cum. percent
## ABRIL              5      10           10
## AGOSTO            11      22           32
## ENERO              4       8           40
## FEBRERO            6      12           52
## JULIO              5      10           62
## JUNIO              4       8           70
## MARZO              6      12           82
## MAYO               5      10           92
## SEPTIEMBRE         4       8          100
##   Total           50     100          100

Gráfica de datos CUANTITATIVOS: Kilos

Viendo la cantidad de kilos, observamos que la gran cantidad se encuentra entre los 3000 y 5000 kilos.

hist((merma$Kilos),col=c("lightgreen"),main="Cantidad",xlab="Kilogramos")

Gráfica de datos CUALITATIVOS: Mes

Diferente presentación de los meses.

pie(prop.table(table(merma$Mes)),col=c("red","blue","green","lightpink","lightblue","lightgreen","yellow","orange","darkred"),main="Meses", ylab ="Frecuencias",las=1)

Gráfica de dispersión: Kilos

En este boxplot que describe la dispersión de los kilos por los meses, vemos que no hay muchos datos que se salgan de lo “normal”

boxplot(merma$Kilos,col=c("yellow"))

Propuestas

  1. Si bien, la gran parte del scrap se encuentra en la pre-producción, encontramos que aproximadamente el 23% del desperdicio puede ser visto en la entrega o en la verificación de calidad. Por lo tanto, lo que se propone a la empresa es tomar acciones para mantener la mayoría del scrap en la pre-producción, con el fin de no “entorpecer” la calidad o el proceso de entrega los clientes de Form.
  2. A partir de la base dee datos de “Producción”, hemos podido notar que el tiempo de calidad es por lo general 1 (se asume que hora), no obstante, existen 63 casos en el que ha excedido este número, en un rango de 2 a 22. Lo que se propone a Form es tomar medidas que aseguren que el tiiempo de calidad no será mayor a 2 (se asume que hora) en ningún caso. Se recomienda usar esto como métrica en su política de calidad.
  3. Al notar que existe una diferencia de la cantidad de merma del mes de agosto a los otros, se propone a Form buscar los motivos o lo que pude haber afectado que produjo esos “extra” kilos de merma en su inventario. Se propone revisar estas razones y determinar que cosas se quisieran seguir llevando, y que cosas se quisiera cambiar en los próximos meses. Igualmente, se recomienda altamente llevar un conteo real y registrado, con el fin de observar avances en este tema (y los demás).

Reflexión de la actividad

Estas bases de datos, otorgados por Form, nos hablan de su producción y desperdicios (uno de desperdicio general y otro enfocado en desperdicio de cartón). De la base de datos conocemos, en producción, los siguientes datos: (1) la gran parte de la producción analizada toma un valor de tiempo de calidad de una hora, (2) el tiempo mínimo (por minutos) de la producción se encuentra entre los 0 y los 30 minutos, (3) la gran parte de las piezas programadas rondan entre 0 y 200 unidades, (4) con las láminas procesadas, vemos que la mayor frecuencia es está entre el 0 y 100.

Siguiendo con la base de deatos de scrap: (1) la gran parte del scrap se encuentra en pre-producción, (2) la gran parte del scrap está entre las 0 y 10 unidades, (3) a mayoría del scrap de agosto fue trabajado en pocas unidades, con muy pocas siendo altas. Todo el mes presenta trabajo.

Finalmente, con la base de datos de merma: (1) agosto fue un mes que tuvo una gran cantidad de desperdicios de cartón, sobre todo al compararla con los otros meses, (2) la gran cantidad se encuentra entre los 3000 y 5000 kilos.

Al reflexionar específicamente de los retos que pude encontrar en esta actividad, fue pprincipalmente el tener que trabajar con bases de datos “reales”, es decir, que no son de lo más ideales y que no todos los datos registrados resultan muy útiles o bien clasificados para su análisis.

Una importante reflexión de esta actividad fue como R me puede ayudar a preparar una base de datos de manera que tengamos menos errores y hacer el proceso más eficiente; así como entregar al socio formador la información más relevante y un análisis preciso. Igualmente, me pude dar cuenta que ahora soy capaz de hacer una limpia de bases de datos yo misma y tomar las decisiones que me parecen más pertinentes. Confío en que estas nuevas bases de datos, su análisis descriptivo y las propuestas que van conforme a, podrán ser de gran utilidad para la resolución del reto y una buena experiencia del socio formador.

LS0tCnRpdGxlOiA8c3BhbiBzdHlsZT0iY29sb3I6b3JhbmdlIj4qKkV0YXBhMl9pbmRpdmlkdWFsKioKYXV0aG9yOiAiRWxlbmFWZWxhX0EwMTI4MzUzNSIKZGF0ZTogIjIwMjItMDktMjMiCm91dHB1dDogCiAgaHRtbF9kb2N1bWVudDoKICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OiB0cnVlCiAgICB0aGVtZTogdW5pdGVkCiAgICBoaWdobGlnaHQ6IHRhbmdvCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCi0tLQojIDxzcGFuIHN0eWxlPSJjb2xvcjpvcmFuZ2UiPioqRU5UUkVHQUJMRSAyLjQqKjwvc3Bhbj4KCgoKPGltZyBzcmM9Ii9Vc2Vycy9lbGVuYXZlbGEvL0Rvd25sb2Fkcy9mb3JtLnBuZyI+ICAKCgojIyA8c3BhbiBzdHlsZT0iY29sb3I6ZGFya3JlZCI+KiphLiBGT1JNIOKAkyBQcm9kdWNjacOzbioqPC9zcGFuPgoKCgpJbXBvcnRhciBiYXNlIGRlIGRhdG9zCmBgYHtyfQojZmlsZS5jaG9vc2UoKQoKcHJvZDwtcmVhZC5jc3YoIi9Vc2Vycy9lbGVuYXZlbGEvRG93bmxvYWRzL3Byb2R1Y2Npb24uY3N2IikKYGBgCgoKIyMjIDEpIMK/Q3XDoW50YXMgdmFyaWFibGVzIHkgY3VhbnRvcyByZWdpc3Ryb3MgdGllbmUgbGEgYmFzZSBkZSBkYXRvcyBJTklDSUFMTUVOVEU/IAoKYGBge3J9CnN0cihwcm9kKQpgYGAKClNlIG9idGllbmVuIDEzIHZhcmlhYmxlcyB5IDIsNTY4IHJlZ2lzdHJvcyBkZWwgbWVzIGRlICphZ29zdG8qIGRlIGxhIGJhc2UgZGUgZGF0b3MgIlByb2R1Y2Npw7NuIGRlIENhcnTDs24iLCBlc3BlY8OtZmljYW1lbnRlIGRlIFRpZW1wbyBkZSBNw6FxdWluYXMuIAoKIyMjIDQpIEFwbGljYSBhbCBtZW5vcyAyIHTDqWNuaWNhcyBkZSBsaW1waWV6YSBkZSBiYXNlcyBkZSBkYXRvcyB5IGV4cGzDrWNhbGFzIGJyZXZlbWVudGUsIMK/cG9yIHF1w6kgcmVhbGl6YXN0ZSBlc2FzIHTDqWNuaWNhcz8KU2UgaGFjZSBlbCBwYXNvIDQgcHJpbWVybywgYW50ZXMgZGUgY2xhc2lmaWNhci4KCioqVMOpY25pY2EgMSwgKlJFTU9WRVIgREFUT1MgSVJSRUxFVkFOVEVTKioqICAKTm8gdG9kYXMgbGFzIHZhcmlhYmxlcyBub3MgaW50ZXJlc2FuLCBvIGFwb3J0YW4gbXVjaG8sIGFsIGFuw6FsaXNpcyBxdWUgc2UgcHJldGVuZGUgaGFjZXIuIFNlIGhhIGRlZmluaWRvIHF1ZSBsYXMgdmFyaWFibGVzIGNvbiAgbGFzIHF1ZSBzZSBkZXNlYSBxdWVkYXIgc29uIGxhcyBzaWd1aWVudGVzOiBjbGllbnRlLCBwaWV6YXMgcHJvZ3JhbWFkYXMsIHRpZW1wbyBtw61uaW1vLCBsw6FtaW5hcyBwcm9jZXNhZGFzIHkgdGllbXBvIGRlIGNhbGlkYWQuICAKClNlIGVsaW1pbmFuIGNvbHVtbmFzCmBgYHtyfQpwcm9kMjwtcHJvZApwcm9kMjwtc3Vic2V0KHByb2QyLHNlbGVjdD0tYyhJRC5GT1JNLFBST0RVQ1RPLEhSLi5GSU4sRVNUQUNJT04uQVJSQU5RVUUsSU5JQ0lPLlNFUC5VUCxGSU4uSU5JQ0lPLkRFLlNFUC5VUCxJTklDSU8uZGUuUFJPQ0VTTyxGSU4uZGUuUFJPQ0VTTykpCnN1bW1hcnkocHJvZDIpCmBgYAoKCiMjIyMgKipUw6ljbmljYSA0LCAqQ09OVkVSVElSIFRJUE8gREUgREFUT1MqKiogICAKClBhcmEgcG9kZXIgZGV0ZXJtaW5hciBsb3MgdmFsb3JlcyBmYWx0YW50ZXMsIGVzIG5lY2VzYXJpbyBjb252ZXJ0aXIgbG9zIHZhbG9yZXMgZGUgY2Fyw6FjdGVyIGEgZW50ZXJvcy9ob3JhL2ZlY2hhLgoKKkNhcsOhY3RlciBhIGVudGVybyoKYGBge3J9CnByb2QzPC1wcm9kMgpwcm9kMyRQSUVaQVMuUFJPRy48LWFzLmludGVnZXIocHJvZDMkUElFWkFTLlBST0cuKQpzdHIocHJvZDMpCgpzdW1tYXJ5KHByb2QzKQpgYGAKCipDYXLDoWN0ZXIgYSBob3JhKgpgYGB7cn0KcHJvZDQ8LXByb2QzCnByb2Q0JFRNTy4uTUlOLjwtYXMuaW50ZWdlcihwcm9kNCRUTU8uLk1JTi4pCnN0cihwcm9kNCkKCnN1bW1hcnkocHJvZDQpCmBgYAoKKkNhcsOhY3RlciBhIGVudGVybyoKYGBge3J9CnByb2Q1PC1wcm9kNApwcm9kNSRMYW1pbmFzLnByb2Nlc2FkYXM8LWFzLmludGVnZXIocHJvZDUkTGFtaW5hcy5wcm9jZXNhZGFzKQpzdHIocHJvZDUpCgpzdW1tYXJ5KHByb2Q1KQpgYGAKCipDYXLDoWN0ZXIgYSBob3JhKgpgYGB7cn0KcHJvZDY8LXByb2Q1CnByb2Q2JFRJRU1QTy5DQUxJREFEPC1hcy5pbnRlZ2VyKHByb2Q2JFRJRU1QTy5DQUxJREFEKQpzdHIocHJvZDYpCgpzdW1tYXJ5KHByb2Q2KQpgYGAKCgoKKipUw6ljbmljYSA1LCAqVkFMT1JFUyBGQUxUQU5URVMqKiogIAoKQWwgaGFiZXIgY2FtYmlhZG8geWEgbG9zIHZhbG9yZXMgYSBzdSBmb3JtYSBjb3JyZXNwb25kaWVudGUsIG9ic2VydmFtb3MgcXVlIGV4aXN0ZSB1bmEgZ3JhbiBjYW50aWRhZCBkZSB2YWxvcmVzIGZhbHRhbnRlcyAoYXByb3guIGxhIG1pdGFkKS4gU2UgaGEgb3B0YWRvIHBvciAqKmVsaW1pbmFyKiogZXN0b3MgcmVnaXN0cm9zLCBkZWJpZG8gYSBxdWUgYWwgcG9uZXIgdW4gY2VybyBvIHVuIHByb21lZGlvLCBzZSBwb2Ryw61hIG5vIHRlbmVyIHVuIGFuw6FsaXNpcyBpbHVzdHJhdGl2by4gCgrCv0N1w6FudG9zIE5BICB0ZW5nbyBwb3IgdmFyaWFibGVzPwpgYGB7cn0Kc2FwcGx5KHByb2Q2LGZ1bmN0aW9uKHgpIHN1bShpcy5uYSh4KSkpCmBgYAoKQm9ycmFyIHJlZ2lzdHJvcyBkZSB2YWxvcmVzIGZhbHRhbnRlcwpgYGB7cn0KcHJvZDc8LXByb2Q2CnByb2Q3PC1uYS5vbWl0KHByb2Q3KQoKc3VtbWFyeShwcm9kNykKYGBgCgrCv0N1w6FudG9zIE5BICB0ZW5nbyBwb3IgdmFyaWFibGVzPwpgYGB7cn0Kc2FwcGx5KHByb2Q3LGZ1bmN0aW9uKHgpIHN1bShpcy5uYSh4KSkpCnN0cihwcm9kNykKYGBgCgpZYSBzZSBoYW4gZWxpbWluYWRvIGxvcyByZWdpc3Ryb3MgY29uIE5BcyAgCgoKKipFeHBvcnRhciBudWV2YSBiYXNlIGRlIGRhdG9zIChsaW1waWEpKioKCmBgYHtyfQpwcm9kdWNjaW9uX2xpbXBpYSA8LXByb2Q3CndyaXRlLmNzdihwcm9kdWNjaW9uX2xpbXBpYSwgZmlsZSA9InByb2R1Y2Npb25fbGltcGlhLmNzdiIsIHJvdy5uYW1lcyA9IEZBTFNFKQpgYGAKCiMjIyAxLjIpIMK/Q3XDoW50YXMgdmFyaWFibGVzIHkgY3VhbnRvcyByZWdpc3Ryb3MgdGllbmUgbGEgYmFzZSBkZSBkYXRvcyBERVNQVcOJUyBkZSBsYSBsaW1waWV6YT8gCgpgYGB7cn0Kc3RyKHByb2Q3KQpgYGAKClNlIHRpZW5lbiA1IHZhcmlhYmxlcyB5IDEsNDc1IHJlZ2lzdHJvcy4gCgoKIyMjIDIpIENsYXNpZmljYSBjYWRhIHZhcmlhYmxlIGVuIGN1YWxpdGF0aXZhLCBjdWFudGl0YXRpdmEgZGlzY3JldGEgbyBjdWFudGl0YXRpdmEgY29udGludWEuIAoKTGFzIGNpbmNvIHZhcmlhYmxlcyBzb24gY2xhc2lmaWNhZGFzIGNvcnJlc3BvbmRpZW5kbyBhIGxvIHF1ZSBkYW4gYSBjb25vY2VyLiAKCmBgYHtyIGVjaG8gPSBGQUxTRSwgcmVzdWx0cyA9IFRSVUV9ClZhcmlhYmxlPC1jKCJgQ2xpZW50ZWAiLCJgUGllemFzIHByb2dyYW1hZGFzYCIsImBUaWVtcG8gbcOtbmltb2AiLCJgTMOhbWluYXMgcHJvY2VzYWRhc2AiLCJgVGllbXBvIGNhbGlkYWRgIikKVHlwZTwtYygiQ3VhbGl0YXRpdmEiLCAiQ3VhbnRpdGF0aXZhIChkaXNjcmV0YSkiLCAiQ3VhbnRpdGF0aXZhIChjb250aW51YSkiLCAiQ3VhbnRpdGF0aXZhIChkaXNjcmV0YSkiLCJDdWFudGl0YXRpdmEgKGNvbnRpbnVhKSIpCnRhYmxlPC1kYXRhLmZyYW1lKFZhcmlhYmxlLFR5cGUpCmtuaXRyOjprYWJsZSh0YWJsZSkKYGBgCgoKCiMjIyAzKSBFbGlnZSBsYSBlc2NhbGEgZGUgbWVkaWNpw7NuIGRlIGNhZGEgdmFyaWFibGUuCkxhcyBjaW5jbyB2YXJpYWJsZXMgc29uIGNsYXNpZmljYWRhcyBjb3JyZXNwb25kaWVuZG8gYSBjb21vIHNlIG1pZGVuLiAgCgoKYGBge3IgZWNobyA9IEZBTFNFLCByZXN1bHRzID0gVFJVRX0KVmFyaWFibGU8LWMoImBDbGllbnRlYCIsImBQaWV6YXMgcHJvZ3JhbWFkYXNgIiwiYFRpZW1wbyBtw61uaW1vYCIsImBMw6FtaW5hcyBwcm9jZXNhZGFzYCIsImBUaWVtcG8gY2FsaWRhZGAiKQpNZWRpY2lvbjwtYygiTm8gYXBsaWNhIiwiVW5pZGFkZXMgZGUgcHJvZHVjY2nDs24iLCJNaW51dG9zIiwiVW5pZGFkZXMgZGUgcHJvZHVjY2nDs24iLCJIb3JhcyIpCnRhYmxlMjwtZGF0YS5mcmFtZShWYXJpYWJsZSxNZWRpY2lvbikKa25pdHI6OmthYmxlKHRhYmxlMikKYGBgCgojIyMgNSkgQW7DoWxpc2lzIGVzdGFkw61zdGljbyBkZXNjcmlwdGl2by4KCgpgYGB7cn0KI2luc3RhbGwucGFja2FnZXMoImVwaURpc3BsYXkiKQpsaWJyYXJ5KGVwaURpc3BsYXkpCmBgYAoKKipUYWJsYSBkZSBmcmVjdWVuY2lhIHkgZ3LDoWZpY2EgZGUgZGF0b3MgQ1VBTlRJVEFUSVZPUzogKlRpZW1wbyBkZSBDYWxpZGFkKioqICAKClByaW1lcmFtZW50ZSwgc2UgYW5hbGl6YSBlbCB0aWVtcG8gZGUgY2FsaWRhZC4gQSAgcGFydGlyIGRlIGxhIHRhYmxhIGRlIGZyZWN1ZW5jaWEgeSBkZSBzdSBncsOhZmljYSwgb2JzZXJ2YW1vcyBxdWUgbGEgZ3JhbiBwYXJ0ZSBkZSBsYSBwcm9kdWNjacOzbiBhbmFsaXphZGEgdG9tYSB1biB2YWxvciBkZSB0aWVtcG8gZGUgY2FsaWRhZCBkZSB1bmEgaG9yYS4gCmBgYHtyfQp0aWVtcG9fZGVfY2FsaWRhZDwtdGFibGUocHJvZDckVElFTVBPLkNBTElEQUQpCmtuaXRyOjprYWJsZSh0aWVtcG9fZGVfY2FsaWRhZCkKCgo/dGFiMQp0YWIxKHByb2Q3JFRJRU1QTy5DQUxJREFELHNvcnQuZ3JvdXAgPSBGQUxTRSxncmFwaD1UUlVFKQpgYGAKCk5vIGFwbGljYW4gbGFzIHRhYmxhcyBjcnV6YWRhcwoKKipHcsOhZmljYSBkZSBkYXRvcyBDVUFOVElUQVRJVk9TOiAqVGllbXBvIE3DrW5pbW8qKiogIApTaWd1aWVudGVtZW50ZSwgb2JzZXJ2YW1vcyBlbCB0aWVtcG8gbcOtbmltbyAocG9yIG1pbnV0b3MpIGRlIGxhIHByb2R1Y2Npw7NuLiBMYSBncmFuIHBhcnRlIHNlIGVuY3VlbnRycmEgZW50cmUgbG9zIDAgeSBsb3MgMzAgbWludXRvcy4gCgpgYGB7cn0KaGlzdCgocHJvZDckVE1PLi5NSU4uKSxjb2w9Yygib3JhbmdlIiksbWFpbj0iVGllbXBvIE3DrW5pbW8iLHhsYWI9Ik1pbnV0b3MiKQpgYGAKCioqR3LDoWZpY2EgZGUgZGF0b3MgQ1VBTlRJVEFUSVZPUzogKlBpZXphcyBQcm9ncmFtYWRhcyoqKiAgCkNvbnRpbnVhbmRvIGNvbiBsYXMgcGllemFzIHByb2dyYW1hZGFzLCB2ZW1vcyBxdWUgbGEgZ3JhbiBwYXJ0ZSBkZSBsYXMgcGllemFzIHByb2dyYW1hZGFzIHJvbmRhbiBlbnRyZSAwIHkgMjAwIHVuaWRhZGVzLgoKYGBge3J9Cmhpc3QoKHByb2Q3JFBJRVpBUy5QUk9HLiksY29sPWMoInllbGxvdyIpLG1haW49IlBpZXphcyBQcm9ncmFtYWRhcyIseGxhYj0iVW5pZGFkZXMiKQpgYGAKCioqR3LDoWZpY2EgZGUgZGF0b3MgQ1VBTlRJVEFUSVZPUzogTMOhbWluYXMgUHJvY2VzYWRhcyoqICAKQ29uIGxhcyBsw6FtaW5hcyBwcm9jZXNhZGFzLCB2ZW1vcyBxdWUgbGEgbWF5b3IgZnJlY3VlbmNpYSBlcyBlc3TDoSBlbnRyZSBlbCAwIHkgMTAwLCBjb24gdW4gaW1wb3J0YW50ZSBuw7ptZXJvIHRhbWJpw6luIHZpc3RvIGVudHJlIDEwMCB5IDMwMC4gCgpgYGB7cn0KaGlzdCgocHJvZDckTGFtaW5hcy5wcm9jZXNhZGFzKSxjb2w9YygiZGFya2dyZWVuIiksbWFpbj0iTMOhbWluYXMgUHJvY2VzYWRhcyIseGxhYj0iVW5pZGFkZXMiKQpgYGAKCioqR3LDoWZpY2EgZGUgZGlzcGVyc2nDs246ICpQaWV6YXMgcHJvZ3JhbWFkYXMqKiogIApUYWwgY29tbyBsbyB2aW1vcyBlbiBlbCBoaXN0b2dyYW1hLCB2ZW1vcyBxdWUgbGEgbWF5b3IgY29uY2VudHJhY2nDs24gZGUgZGF0b3MgZXN0w6EgZW50cmUgZWwgMTAwIHkgMjAwLiBObyByZXN1bHRhIGRlbWFzaWFkbyBkaXNwZXJzbywgc2luIGVtYmFyZ28gaGF5IHVuIGRhdG8gcXVlIHNlIHNhbGUgZGUgbG8gIm5vcm1hbCIsIHB1ZXN0byBxdWUgbG8gZW5jb250cmFtb3MgYXJyaWJhIGRlIGxvcyBtaWxlcy4gCgpgYGB7cn0KYm94cGxvdChwcm9kNyRQSUVaQVMuUFJPRy4sY29sPWMoIm9yYW5nZSIpKQpgYGAKCiMjIDxzcGFuIHN0eWxlPSJjb2xvcjpkYXJrcmVkIj4qKmIuIEZPUk0g4oCTIFNjcmFwKio8L3NwYW4+CgpJbXBvcnRhciBiYXNlIGRlIGRhdG9zCmBgYHtyfQojZmlsZS5jaG9vc2UoKQpzY3JhcDwtcmVhZC5jc3YoIi9Vc2Vycy9lbGVuYXZlbGEvRG93bmxvYWRzL3NjcmFwLmNzdiIpCmBgYAoKCiMjIyAxKSDCv0N1w6FudGFzIHZhcmlhYmxlcyB5IGN1YW50b3MgcmVnaXN0cm9zIHRpZW5lIGxhIGJhc2UgZGUgZGF0b3MgSU5JQ0lBTE1FTlRFPyAKCmBgYHtyfQpzdHIoc2NyYXApCmBgYAoKRXhpc3RlbiA5IHZhcmlhYmxlcywgY29uIDI1MCByZWdpc3Ryb3MgZW4gdG90YWwuCgoKIyMjIDQpIEFwbGljYSBhbCBtZW5vcyAyIHTDqWNuaWNhcyBkZSBsaW1waWV6YSBkZSBiYXNlcyBkZSBkYXRvcyB5IGV4cGzDrWNhbGFzIGJyZXZlbWVudGUsIMK/cG9yIHF1w6kgcmVhbGl6YXN0ZSBlc2FzIHTDqWNuaWNhcz8KCioqVMOpY25pY2EgMSwgKlJFTU9WRVIgREFUT1MgSVJSRUxFVkFOVEVTKioqICAKTm8gdG9kYXMgbGFzIHZhcmlhYmxlcyBubyBpbnRlcmVzYW4sIG8gYXBvcnRhbiBtdWNobywgYWwgYW7DoWxpc2lzIHF1ZSBzZSBwcmV0ZW5kZSBoYWNlci4gU2UgaGEgZGVmaW5pZG8gcXVlIGxhcyB2YXJpYWJsZXMgY29uICBsYXMgcXVlIHNlIGRlc2VhIHF1ZWRhciBzb24gbGFzIHNpZ3VpZW50ZXM6IGZlY2hhLCBjYW50aWRhZCwgeSAgdWJpY2FjacOzbiBkZSBvcmlnZW4uCgpTZSBlbGltaW5hbiBjb2x1bW5hcwpgYGB7cn0Kc2NyYXAyPC1zY3JhcApzY3JhcDI8LXN1YnNldChzY3JhcDIsc2VsZWN0PS1jKFJlZmVyZW5jaWEsSG9yYSxQcm9kdWN0byxVbmlkYWQuZGUubWVkaWRhLFViaWNhY2nDs24uZGUuZGVzZWNobyxFc3RhZG8pKQoKc3VtbWFyeShzY3JhcDIpCmBgYAoKIyMjIyAqKlTDqWNuaWNhIDQsICpDT05WRVJUSVIgVElQTyBERSBEQVRPUyoqKiAgIAoKUGFyYSBwb2RlciBkZXRlcm1pbmFyIGxvcyB2YWxvcmVzIGZhbHRhbnRlcywgZXMgbmVjZXNhcmlvIGNvbnZlcnRpciBsb3MgdmFsb3JlcyBkZSBjYXLDoWN0ZXIgYSBlbnRlcm9zL2hvcmEvZmVjaGEuCgoKQ2Fyw6FjdGVyIGEgZmVjaGEKYGBge3J9CnNjcmFwMzwtc2NyYXAyCnNjcmFwMyRGZWNoYTwtYXMuRGF0ZShzY3JhcDMkRmVjaGEsZm9ybWF0PSIlZC8lbS8lWSIpICAKc3RyKHNjcmFwMykKc3VtbWFyeShzY3JhcDMpCmBgYAoKCsK/Q3XDoW50b3MgTkEgdGVuZ28gcG9yIHZhcmlhYmxlPwpgYGB7cn0Kc2FwcGx5KHNjcmFwMyxmdW5jdGlvbih4KSBzdW0oaXMubmEoeCkpKQpgYGAKCgpObyBzZSBlbGltaW5hIG5pbmfDum4gcmVnaXN0cm8uIAoKCioqRXhwb3J0YXIgbnVldmEgYmFzZSBkZSBkYXRvcyAobGltcGlhKSoqCgpgYGB7cn0Kc2NyYXBfbGltcGlhIDwtc2NyYXAzCndyaXRlLmNzdihzY3JhcF9saW1waWEsIGZpbGUgPSJzY3JhcF9saW1waWEuY3N2Iiwgcm93Lm5hbWVzID0gRkFMU0UpCmBgYAoKCiMjIyAxLjIpIMK/Q3XDoW50YXMgdmFyaWFibGVzIHkgY3VhbnRvcyByZWdpc3Ryb3MgdGllbmUgbGEgYmFzZSBkZSBkYXRvcyBERVNQVcOJUyBkZSBsYSBsaW1waWE/CgpgYGB7cn0Kc3RyKHNjcmFwMykKYGBgCgpTZSB0aWVuZW4sIGZpbmFsbWVudGUsIDI1MCByZWdpc3Ryb3MgeSAzIHZhcmlhYmxlcy4gCgoKCiMjIyAyKSBDbGFzaWZpY2EgY2FkYSB2YXJpYWJsZSBlbiBjdWFsaXRhdGl2YSwgY3VhbnRpdGF0aXZhIGRpc2NyZXRhIG8gY3VhbnRpdGF0aXZhIGNvbnRpbnVhCgpMYXMgdHJlcyB2YXJpYWJsZXMgc29uIGNsYXNpZmljYWRhcyBjb3JyZXNwb25kaWVuZG8gYSBsbyBxdWUgZGFuIGEgY29ub2Nlci4gCgoKYGBge3IgZWNobyA9IEZBTFNFLCByZXN1bHRzID0gVFJVRX0KVmFyaWFibGU8LWMoImBGZWNoYWAiLCJgQ2FudGlkYWRgIiwiYFViaWNhY2nDs24gZGUgb3JpZ2VuYCIpClR5cGU8LWMoIkN1YW50aXRhdGl2YSAoY29udGludWEpIiwgIkN1YW50aXRhdGl2YSAoZGlzY3JldGEpIiwgIkN1YWxpdGF0aXZhIikKdGFibGUzPC1kYXRhLmZyYW1lKFZhcmlhYmxlLFR5cGUpCmtuaXRyOjprYWJsZSh0YWJsZTMpCmBgYAoKCiMjIyAzKSBFbGlnZSBsYSBlc2NhbGEgZGUgbWVkaWNpw7NuIGRlIGNhZGEgdmFyaWFibGUuCkxhcyB0cmVzIHZhcmlhYmxlcyBzb24gY2xhc2lmaWNhZGFzIGNvcnJlc3BvbmRpZW5kbyBhIGNvbW8gc2UgbWlkZW4uIAoKCmBgYHtyIGVjaG8gPSBGQUxTRSwgcmVzdWx0cyA9IFRSVUV9ClZhcmlhYmxlPC1jKCJgRmVjaGFgIiwiYENhbnRpZGFkYCIsImBVYmljYWNpw7NuIGRlIG9yaWdlbmAiKQpUeXBlPC1jKCJEw61hcyIsICJVbmlkYWRlcyIsICJObyBhcGxpY2EiKQp0YWJsZTQ8LWRhdGEuZnJhbWUoVmFyaWFibGUsVHlwZSkKa25pdHI6OmthYmxlKHRhYmxlNCkKYGBgCgojIyMgNSkgQW7DoWxpc2lzIGVzdGFkw61zdGljbyBkZXNjcmlwdGl2bwoKKipUYWJsYSBkZSBmcmVjdWVuY2lhIHkgZ3LDoWZpY2EgZGUgZGF0b3MgQ1VBTElUQVRJVk9TOiAqVWJpY2FjacOzbiBkZSBvcmlnZW4qKiogIAoKRW4gZXN0ZSBjYXNvLCBvYnNlcnZhbW9zIHF1ZSBsYSBncmFuIHBhcnRlIGRlbCAqc2NyYXAqIHNlIGVuY3VlbnRyYSBlbiBwcmUtcHJvZHVjY2nDs24sIHNpZ3VpZW5kbyBwb3IgbGEgdmVyaWZpY2FjacOzbiBkZSBjYWxpZGFkIHkgbGEgZW50cmVnYSwgeSBtdXkgcG9jYXMgZXN0w6FuIGVuIHBvc3QtcHJvZHVjY2nDs24uICAKYGBge3J9CmtuaXRyOjprYWJsZSh0YWJsZShzY3JhcDMkVWJpY2FjacOzbi5kZS5vcmlnZW4pKQp0YWIxKHNjcmFwMyRVYmljYWNpw7NuLmRlLm9yaWdlbixzb3J0Lmdyb3VwID0gRkFMU0UsZ3JhcGg9VFJVRSkKYGBgCioqR3LDoWZpY2EgZGUgZGF0b3MgQ1VBTlRJVEFUSVZPUzogKkNhbnRpZGFkKioqICAKCk9ic2VydmFuZG8gbGEgdmFyaWFibGUgY2FudGlkYWQgZGVsICpzY3JhcCosIHZlbW9zIHF1ZSBsYSBncmFuIHBhcnRlIGVzdMOhIGVudHJlIGxhcyAwICB5IDEwIHVuaWRhZGVzLCBzb2JyZXBhc2FuZG8gc29sbyBtdXkgcG9jYXMgZGVsIHRvdGFsLgoKYGBge3J9Cmhpc3QoKHNjcmFwMyRDYW50aWRhZCksY29sPWMoImxpZ2h0Z3JlZW4iKSxtYWluPSJDYW50aWRhZCIseGxhYj0iVW5pZGFkZXMiKQpgYGAKCgoKKipHcsOhZmljYSBkZSBkaXNwZXJzacOzbjogKkZlY2hhIHkgY2FudGlkYWQqKiogIAoKQ29udGludWFuZG8gY29uIHVuIGFuw6FsaXNpcyBkZSBkaXNwZXJzacOzbiwgY29tcGFyYW1vcyBsYSBmZWNoYSB5IGxhcyB1bmlkYWRlcy4gVmVtb3MgcXVlIGxhIG1heW9yw61hIGRlbCAqc2NyYXAqIGRlIGFnb3N0byBmdWUgdHJhYmFqYWRvIGVuIHBvY2FzIHVuaWRhZGVzLCBjb24gbXV5IHBvY2FzIHNpZW5kbyBhbHRhcy4gVG9kbyBlbCBtZXMgcHJlc2VudGEgdHJhYmFqby4gCmBgYHtyfQpwbG90KHNjcmFwMyRGZWNoYSxzY3JhcDMkQ2FudGlkYWQsIG1haW4gPSAiRGlzcGVyc2nDs24gZGUgZmVjaGEgeSB1bmlkYWRlcyIsCiAgICAgcGNoID0gMTksIGZyYW1lID0gRkFMU0UsY29sPWMoIm9yYW5nZSIpKQpgYGAKCiMjIDxzcGFuIHN0eWxlPSJjb2xvcjpkYXJrcmVkIj4qKmMuIEZPUk0g4oCTIE1lcm1hKio8L3NwYW4+CgoKYGBge3J9CiNmaWxlLmNob29zZSgpCm1lcm1hPC1yZWFkLmNzdigiL1VzZXJzL2VsZW5hdmVsYS9Eb3dubG9hZHMvbWVybWEuY3N2IikKc3VtbWFyeShtZXJtYSkKYGBgCgojIyMgMSkgwr9DdcOhbnRhcyB2YXJpYWJsZXMgeSBjdWFudG9zIHJlZ2lzdHJvcyB0aWVuZSBsYSBiYXNlIGRlIGRhdG9zPyAKYGBge3J9CnN0cihtZXJtYSkKYGBgCgpTZSBvYnRpZW5lbiA1MCAgcmVnaXN0cm9zIHkgMyB2YXJpYWJsZXMuCgojIyMgNCkgQXBsaWNhIGFsIG1lbm9zIDIgdMOpY25pY2FzIGRlIGxpbXBpZXphIGRlIGJhc2VzIGRlIGRhdG9zIHkgZXhwbMOtY2FsYXMgYnJldmVtZW50ZSwgwr9wb3IgcXXDqSByZWFsaXphc3RlIGVzYXMgdMOpY25pY2FzPwoKKipUw6ljbmljYSAxLCAqUkVNT1ZFUiBEQVRPUyBJUlJFTEVWQU5URVMqKiogIApEZXNkZSBlbCBleGNlbCBzZSBoYW4gZWxpbWluYWRvIGxhcyBmaWxhcyBkZSAidG90YWwgKm1lcyoiLgoKCiMjIyMgKipUw6ljbmljYSA0LCAqQ09OVkVSVElSIFRJUE8gREUgREFUT1MqKiogICAKClBhcmEgcG9kZXIgZGV0ZXJtaW5hciBsb3MgdmFsb3JlcyBmYWx0YW50ZXMsIGVzIG5lY2VzYXJpbyBjb252ZXJ0aXIgbG9zIHZhbG9yZXMgZGUgY2Fyw6FjdGVyIGEgZW50ZXJvcy9ob3JhL2ZlY2hhLgoKCkNhcsOhY3RlciBhIGVudGVybwpgYGB7cn0KbWVybWEyPC1tZXJtYQptZXJtYTIkRmVjaGE8LWFzLkRhdGUobWVybWEyJEZlY2hhLGZvcm1hdD0iJWQvJW0vJVkiKSAgCnN0cihtZXJtYTIpCnN1bW1hcnkobWVybWEyKQpgYGAKCsK/Q3XDoW50b3MgTkEgdGVuZ28gcG9yIHZhcmlhYmxlPwpgYGB7cn0Kc2FwcGx5KG1lcm1hMixmdW5jdGlvbih4KSBzdW0oaXMubmEoeCkpKQpgYGAKCk5vIGV4aXN0ZW4gdmFsb3JlcyBmYWx0YW50ZXMgcG9yIHZhcmlhYmxlcy4KCioqRXhwb3J0YXIgbnVldmEgYmFzZSBkZSBkYXRvcyAobGltcGlhKSoqCgpgYGB7cn0KbWVybWFfbGltcGlhIDwtbWVybWEyCndyaXRlLmNzdihtZXJtYV9saW1waWEsIGZpbGUgPSJtZXJtYWFfbGltcGlhLmNzdiIsIHJvdy5uYW1lcyA9IEZBTFNFKQpgYGAKCgoKIyMjIDIpIENsYXNpZmljYSBjYWRhIHZhcmlhYmxlIGVuIGN1YWxpdGF0aXZhLCBjdWFudGl0YXRpdmEgZGlzY3JldGEgbyBjdWFudGl0YXRpdmEgY29udGludWEKCkxhcyB0cmVzIHZhcmlhYmxlcyBzb24gY2xhc2lmaWNhZGFzIGNvcnJlc3BvbmRpZW5kbyBhIGxvIHF1ZSBkYW4gYSBjb25vY2VyLiAKCgpgYGB7ciBlY2hvID0gRkFMU0UsIHJlc3VsdHMgPSBUUlVFfQpWYXJpYWJsZTwtYygiYEZlY2hhYCIsImBNZXNgIiwiYEtpbG9zYCIpClR5cGU8LWMoIkN1YW50aXRhdGl2YSAoY29udGludWEpIiwgIkN1YWxpdGF0aXZhIiwgIkN1YW50aXRhdGl2YSAoY29udGludWEiKQp0YWJsZTQ8LWRhdGEuZnJhbWUoVmFyaWFibGUsVHlwZSkKa25pdHI6OmthYmxlKHRhYmxlNCkKYGBgCgoKIyMjIDMpIEVsaWdlIGxhIGVzY2FsYSBkZSBtZWRpY2nDs24gZGUgY2FkYSB2YXJpYWJsZS4KCkxhcyB0cmVzIHZhcmlhYmxlcyBzb24gY2xhc2lmaWNhZGFzIGNvcnJlc3BvbmRpZW5kbyBhIGNvbW8gc2UgbWlkZW4uIAoKCmBgYHtyIGVjaG8gPSBGQUxTRSwgcmVzdWx0cyA9IFRSVUV9ClZhcmlhYmxlPC1jKCJgRmVjaGFgIiwiYE1lc2AiLCJgS2lsb3NgIikKTWVkaWNpb248LWMoIkTDrWEvTWVzL0HDsW8iLCAiTm8gIGFwbGljYSIsICJLZ3MiKQp0YWJsZTU8LWRhdGEuZnJhbWUoVmFyaWFibGUsTWVkaWNpb24pCmtuaXRyOjprYWJsZSh0YWJsZTUpCmBgYAoKCiMjIyA1KSBBbsOhbGlzaXMgZGVzY3JpcHRpdm8uIAoKKipUYWJsYSBkZSBmcmVjdWVuY2lhIHkgZ3LDoWZpY2EgZGUgZGF0b3MgQ1VBTElUQVRJVk9TOiAqTWVzKioqICAKClZpZW5kbyBsb3MgZGVzcGVyZGljaW9zIHBvciBraWxvcywgcG9yIG1lcywgdmVtb3MgcXVlIGFnb3N0byBmdWUgdW4gbWVzIHF1ZSB0dXZvIHVuYSBncmFuIGNhbnRpZGFkIGRlIGRlc3BlcmRpY2lvcywgc29icmUgdG9kbyBhbCBjb21wYXJhcmxhIGNvbiBsb3Mgb3Ryb3MgbWVzZXMuIAoKCmBgYHtyfQprbml0cjo6a2FibGUodGFibGUobWVybWEkTWVzKSkKdGFiMShtZXJtYSRNZXMsc29ydC5ncm91cCA9IEZBTFNFLGdyYXBoPVRSVUUpCmBgYAoKKipHcsOhZmljYSBkZSBkYXRvcyBDVUFOVElUQVRJVk9TOiAqS2lsb3MqKiogIAoKVmllbmRvIGxhIGNhbnRpZGFkIGRlIGtpbG9zLCBvYnNlcnZhbW9zIHF1ZSBsYSBncmFuIGNhbnRpZGFkIHNlIGVuY3VlbnRyYSBlbnRyZSBsb3MgMzAwMCB5IDUwMDAga2lsb3MuIApgYGB7cn0KaGlzdCgobWVybWEkS2lsb3MpLGNvbD1jKCJsaWdodGdyZWVuIiksbWFpbj0iQ2FudGlkYWQiLHhsYWI9IktpbG9ncmFtb3MiKQpgYGAKCioqR3LDoWZpY2EgZGUgZGF0b3MgQ1VBTElUQVRJVk9TOiAqTWVzKioqICAKCkRpZmVyZW50ZSBwcmVzZW50YWNpw7NuIGRlIGxvcyBtZXNlcy4gCmBgYHtyfQpwaWUocHJvcC50YWJsZSh0YWJsZShtZXJtYSRNZXMpKSxjb2w9YygicmVkIiwiYmx1ZSIsImdyZWVuIiwibGlnaHRwaW5rIiwibGlnaHRibHVlIiwibGlnaHRncmVlbiIsInllbGxvdyIsIm9yYW5nZSIsImRhcmtyZWQiKSxtYWluPSJNZXNlcyIsIHlsYWIgPSJGcmVjdWVuY2lhcyIsbGFzPTEpCmBgYAoKKipHcsOhZmljYSBkZSBkaXNwZXJzacOzbjogKktpbG9zKioqICAKCkVuIGVzdGUgYm94cGxvdCBxdWUgZGVzY3JpYmUgbGEgZGlzcGVyc2nDs24gZGUgbG9zIGtpbG9zIHBvciBsb3MgbWVzZXMsIHZlbW9zIHF1ZSBubyBoYXkgbXVjaG9zIGRhdG9zIHF1ZSBzZSBzYWxnYW4gZGUgbG8gIm5vcm1hbCIKYGBge3J9CmJveHBsb3QobWVybWEkS2lsb3MsY29sPWMoInllbGxvdyIpKQpgYGAKCiMjIDxzcGFuIHN0eWxlPSJjb2xvcjpkYXJrcmVkIj4qKlByb3B1ZXN0YXMqKjwvc3Bhbj4KCjEuIFNpIGJpZW4sIGxhIGdyYW4gcGFydGUgZGVsICpzY3JhcCogc2UgZW5jdWVudHJhIGVuIGxhIHByZS1wcm9kdWNjacOzbiwgZW5jb250cmFtb3MgcXVlIGFwcm94aW1hZGFtZW50ZSBlbCAyMyUgZGVsIGRlc3BlcmRpY2lvIHB1ZWRlIHNlciB2aXN0byBlbiBsYSBlbnRyZWdhIG8gZW4gbGEgdmVyaWZpY2FjacOzbiBkZSBjYWxpZGFkLiBQb3IgbG8gdGFudG8sIGxvIHF1ZSBzZSBwcm9wb25lIGEgbGEgZW1wcmVzYSBlcyB0b21hciBhY2Npb25lcyBwYXJhIG1hbnRlbmVyIGxhIG1heW9yw61hIGRlbCAqc2NyYXAqIGVuIGxhIHByZS1wcm9kdWNjacOzbiwgY29uIGVsIGZpbiBkZSBubyAiZW50b3JwZWNlciIgbGEgY2FsaWRhZCBvIGVsIHByb2Nlc28gZGUgZW50cmVnYSBsb3MgY2xpZW50ZXMgZGUgRm9ybS4gIAoyLiBBIHBhcnRpciBkZSBsYSBiYXNlIGRlZSBkYXRvcyBkZSAiUHJvZHVjY2nDs24iLCBoZW1vcyBwb2RpZG8gbm90YXIgcXVlIGVsIHRpZW1wbyBkZSBjYWxpZGFkIGVzIHBvciBsbyBnZW5lcmFsIDEgKHNlIGFzdW1lIHF1ZSBob3JhKSwgbm8gb2JzdGFudGUsIGV4aXN0ZW4gNjMgY2Fzb3MgZW4gZWwgcXVlIGhhIGV4Y2VkaWRvIGVzdGUgbsO6bWVybywgZW4gdW4gcmFuZ28gZGUgMiBhIDIyLiBMbyBxdWUgc2UgcHJvcG9uZSBhIEZvcm0gZXMgdG9tYXIgbWVkaWRhcyBxdWUgYXNlZ3VyZW4gcXVlIGVsIHRpaWVtcG8gZGUgY2FsaWRhZCBubyBzZXLDoSBtYXlvciBhIDIgKHNlIGFzdW1lIHF1ZSBob3JhKSBlbiBuaW5nw7puIGNhc28uIFNlIHJlY29taWVuZGEgdXNhciBlc3RvIGNvbW8gbcOpdHJpY2EgZW4gc3UgcG9sw610aWNhIGRlIGNhbGlkYWQuICAKMy4gQWwgbm90YXIgcXVlIGV4aXN0ZSB1bmEgZGlmZXJlbmNpYSBkZSBsYSBjYW50aWRhZCBkZSBtZXJtYSBkZWwgbWVzIGRlIGFnb3N0byBhIGxvcyBvdHJvcywgc2UgcHJvcG9uZSBhIEZvcm0gYnVzY2FyIGxvcyBtb3Rpdm9zIG8gbG8gcXVlIHB1ZGUgaGFiZXIgYWZlY3RhZG8gcXVlIHByb2R1am8gZXNvcyAiZXh0cmEiIGtpbG9zIGRlIG1lcm1hIGVuIHN1IGludmVudGFyaW8uIFNlIHByb3BvbmUgcmV2aXNhciBlc3RhcyByYXpvbmVzIHkgZGV0ZXJtaW5hciBxdWUgY29zYXMgc2UgcXVpc2llcmFuIHNlZ3VpciBsbGV2YW5kbywgeSBxdWUgY29zYXMgc2UgcXVpc2llcmEgY2FtYmlhciBlbiBsb3MgcHLDs3hpbW9zIG1lc2VzLiBJZ3VhbG1lbnRlLCBzZSByZWNvbWllbmRhIGFsdGFtZW50ZSBsbGV2YXIgdW4gY29udGVvIHJlYWwgeSByZWdpc3RyYWRvLCBjb24gZWwgZmluIGRlIG9ic2VydmFyIGF2YW5jZXMgZW4gZXN0ZSB0ZW1hICh5IGxvcyBkZW3DoXMpLiAKCgojIyA8c3BhbiBzdHlsZT0iY29sb3I6ZGFya3JlZCI+KipSZWZsZXhpw7NuIGRlIGxhIGFjdGl2aWRhZCoqPC9zcGFuPgoKRXN0YXMgYmFzZXMgZGUgZGF0b3MsIG90b3JnYWRvcyBwb3IgRm9ybSwgbm9zIGhhYmxhbiBkZSBzdSBwcm9kdWNjacOzbiAgeSBkZXNwZXJkaWNpb3MgKHVubyBkZSBkZXNwZXJkaWNpbyBnZW5lcmFsIHkgb3RybyBlbmZvY2FkbyBlbiBkZXNwZXJkaWNpbyBkZSBjYXJ0w7NuKS4gRGUgbGEgYmFzZSBkZSBkYXRvcyBjb25vY2Vtb3MsIGVuIHByb2R1Y2Npw7NuLCBsb3Mgc2lndWllbnRlcyBkYXRvczogKDEpIGxhIGdyYW4gcGFydGUgZGUgbGEgcHJvZHVjY2nDs24gYW5hbGl6YWRhIHRvbWEgdW4gdmFsb3IgZGUgdGllbXBvIGRlIGNhbGlkYWQgZGUgdW5hIGhvcmEsICgyKSBlbCB0aWVtcG8gbcOtbmltbyAocG9yIG1pbnV0b3MpIGRlIGxhIHByb2R1Y2Npw7NuIHNlIGVuY3VlbnRyYSBlbnRyZSBsb3MgMCB5IGxvcyAzMCBtaW51dG9zLCAoMykgIGxhIGdyYW4gcGFydGUgZGUgbGFzIHBpZXphcyBwcm9ncmFtYWRhcyByb25kYW4gZW50cmUgMCB5IDIwMCB1bmlkYWRlcywgKDQpIGNvbiBsYXMgbMOhbWluYXMgcHJvY2VzYWRhcywgdmVtb3MgcXVlIGxhIG1heW9yIGZyZWN1ZW5jaWEgZXMgZXN0w6EgZW50cmUgZWwgMCB5IDEwMC4gICAKClNpZ3VpZW5kbyBjb24gbGEgYmFzZSBkZSBkZWF0b3MgZGUgKnNjcmFwKjogKDEpIGxhIGdyYW4gcGFydGUgZGVsIHNjcmFwIHNlIGVuY3VlbnRyYSBlbiBwcmUtcHJvZHVjY2nDs24sICgyKSBsYSBncmFuIHBhcnRlIGRlbCBzY3JhcCBlc3TDoSBlbnRyZSBsYXMgMCB5IDEwIHVuaWRhZGVzLCAoMykgYSBtYXlvcsOtYSBkZWwgc2NyYXAgZGUgYWdvc3RvIGZ1ZSB0cmFiYWphZG8gZW4gcG9jYXMgdW5pZGFkZXMsIGNvbiBtdXkgcG9jYXMgc2llbmRvIGFsdGFzLiBUb2RvIGVsIG1lcyBwcmVzZW50YSB0cmFiYWpvLiAgCgpGaW5hbG1lbnRlLCBjb24gbGEgYmFzZSBkZSBkYXRvcyBkZSBtZXJtYTogKDEpIGFnb3N0byBmdWUgdW4gbWVzIHF1ZSB0dXZvIHVuYSBncmFuIGNhbnRpZGFkIGRlIGRlc3BlcmRpY2lvcyBkZSBjYXJ0w7NuLCBzb2JyZSB0b2RvIGFsIGNvbXBhcmFybGEgY29uIGxvcyBvdHJvcyBtZXNlcywgKDIpICBsYSBncmFuIGNhbnRpZGFkIHNlIGVuY3VlbnRyYSBlbnRyZSBsb3MgMzAwMCB5IDUwMDAga2lsb3MuCgpBbCByZWZsZXhpb25hciBlc3BlY8OtZmljYW1lbnRlIGRlIGxvcyByZXRvcyBxdWUgcHVkZSBlbmNvbnRyYXIgZW4gZXN0YSBhY3RpdmlkYWQsIGZ1ZSBwcHJpbmNpcGFsbWVudGUgZWwgdGVuZXIgcXVlIHRyYWJhamFyIGNvbiBiYXNlcyBkZSBkYXRvcyAicmVhbGVzIiwgZXMgZGVjaXIsIHF1ZSBubyBzb24gZGUgbG8gbcOhcyBpZGVhbGVzIHkgcXVlIG5vIHRvZG9zIGxvcyBkYXRvcyByZWdpc3RyYWRvcyByZXN1bHRhbiBtdXkgw7p0aWxlcyBvIGJpZW4gY2xhc2lmaWNhZG9zIHBhcmEgc3UgYW7DoWxpc2lzLiAgCgpVbmEgaW1wb3J0YW50ZSByZWZsZXhpw7NuIGRlIGVzdGEgYWN0aXZpZGFkIGZ1ZSBjb21vIFIgbWUgcHVlZGUgYXl1ZGFyIGEgcHJlcGFyYXIgdW5hIGJhc2UgZGUgZGF0b3MgZGUgbWFuZXJhIHF1ZSB0ZW5nYW1vcyBtZW5vcyBlcnJvcmVzIHkgaGFjZXIgZWwgcHJvY2VzbyBtw6FzIGVmaWNpZW50ZTsgYXPDrSBjb21vIGVudHJlZ2FyIGFsIHNvY2lvIGZvcm1hZG9yIGxhIGluZm9ybWFjacOzbiBtw6FzIHJlbGV2YW50ZSB5IHVuIGFuw6FsaXNpcyBwcmVjaXNvLiBJZ3VhbG1lbnRlLCBtZSBwdWRlIGRhciBjdWVudGEgcXVlIGFob3JhIHNveSBjYXBheiBkZSBoYWNlciB1bmEgbGltcGlhIGRlIGJhc2VzIGRlIGRhdG9zIHlvIG1pc21hIHkgdG9tYXIgbGFzIGRlY2lzaW9uZXMgcXVlIG1lIHBhcmVjZW4gbcOhcyBwZXJ0aW5lbnRlcy4gQ29uZsOtbyBlbiBxdWUgZXN0YXMgbnVldmFzIGJhc2VzIGRlIGRhdG9zLCBzdSBhbsOhbGlzaXMgZGVzY3JpcHRpdm8geSBsYXMgcHJvcHVlc3RhcyBxdWUgdmFuIGNvbmZvcm1lIGEsIHBvZHLDoW4gc2VyIGRlIGdyYW4gdXRpbGlkYWQgcGFyYSBsYSByZXNvbHVjacOzbiBkZWwgcmV0byB5IHVuYSBidWVuYSBleHBlcmllbmNpYSBkZWwgc29jaW8gZm9ybWFkb3IuIAoKCgo=