knitr::include_url("https://form.com.mx/")

RH Colaboradores

library(foreign)
library(dplyr)        # data manipulation 
library(forcats)      # to work with categorical variables
library(ggplot2)      # data visualization
library(readr)        # read specific csv files
library(janitor)      # data exploration and cleaning 
library(Hmisc)        # several useful functions for data analysis 
library(psych)        # functions for multivariate analysis 
library(naniar)       # summaries and visualization of missing values NAs
library(dlookr)       # summaries and visualization of missing values NAs
library(corrplot)     # correlation plots
library(jtools)       # presentation of regression analysis 
library(lmtest)       # diagnostic checks - linear regression analysis 
library(car)          # diagnostic checks - linear regression analysis
library(olsrr)        # diagnostic checks - linear regression analysis 
library(kableExtra)   # HTML table attributes
library(gmodels)
library(openxlsx)
library(crosstable)

Sección 1. Limpieza de datos, Transformación y Entendimiento (1-4)

colab <-read.csv("C:\\Users\\danyc\\Downloads\\hr csv 1.csv")
summary(colab)
##  No..De.Empleado   APELLIDOS            NOMBRE          FECHA.DE.NACIMIENTO
##  Min.   :  1.00   Length:113         Length:113         Length:113         
##  1st Qu.: 31.00   Class :character   Class :character   Class :character   
##  Median : 63.00   Mode  :character   Mode  :character   Mode  :character   
##  Mean   : 75.86                                                            
##  3rd Qu.:127.00                                                            
##  Max.   :169.00                                                            
##       EDAD          GENERO              RFC            FECHA.DE.ALTA     
##  Min.   : 0.00   Length:113         Length:113         Length:113        
##  1st Qu.:25.00   Class :character   Class :character   Class :character  
##  Median :33.00   Mode  :character   Mode  :character   Mode  :character  
##  Mean   :35.74                                                           
##  3rd Qu.:45.00                                                           
##  Max.   :73.00                                                           
##   PRIMER.MES         CUARTO.MES             BAJA           PUESTO         
##  Length:113         Length:113         Min.   :0.0000   Length:113        
##  Class :character   Class :character   1st Qu.:0.0000   Class :character  
##  Mode  :character   Mode  :character   Median :0.0000   Mode  :character  
##                                        Mean   :0.3451                     
##                                        3rd Qu.:0.0000                     
##                                        Max.   :3.0000                     
##  DEPARTAMENTO       SALARIO.DIARIO.IMSS FACTOR.CRED.INFONAVIT
##  Length:113         Min.   :144.4       Min.   :     0       
##  Class :character   1st Qu.:176.7       1st Qu.:     0       
##  Mode  :character   Median :180.7       Median :     0       
##                     Mean   :181.2       Mean   :  2244       
##                     3rd Qu.:180.7       3rd Qu.:     0       
##                     Max.   :441.4       Max.   :182096       
##  N..CREDITO.INFONAVIT LUGAR.DE.NACIMIENTO     CURP              CALLE          
##  Min.   :0.000e+00    Length:113          Length:113         Length:113        
##  1st Qu.:0.000e+00    Class :character    Class :character   Class :character  
##  Median :0.000e+00    Mode  :character    Mode  :character   Mode  :character  
##  Mean   :6.770e+07                                                             
##  3rd Qu.:0.000e+00                                                             
##  Max.   :1.922e+09                                                             
##  NUMERO.INTERNO       COLONIA           MUNICIPIO            ESTADO         
##  Length:113         Length:113         Length:113         Length:113        
##  Class :character   Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character   Mode  :character  
##                                                                             
##                                                                             
##                                                                             
##  CODIGO.POSTAL   ESTADO.CIVIL       TARJETA.CUENTA        X          
##  Min.   :25016   Length:113         Length:113         Mode:logical  
##  1st Qu.:66640   Class :character   Class :character   NA's:113      
##  Median :66646   Mode  :character   Mode  :character                 
##  Mean   :63365                                                       
##  3rd Qu.:66649                                                       
##  Max.   :67493                                                       
##    X.1         
##  Mode:logical  
##  NA's:113      
##                
##                
##                
## 
describe(colab)
## # A tibble: 7 × 26
##   described_v…¹     n    na    mean      sd se_mean   IQR skewn…² kurto…³    p00
##   <chr>         <int> <int>   <dbl>   <dbl>   <dbl> <dbl>   <dbl>   <dbl>  <dbl>
## 1 No..De.Emple…   113     0 7.59e+1 5.39e+1 5.07e+0 96      0.400  -1.24      1 
## 2 EDAD            113     0 3.57e+1 1.33e+1 1.25e+0 20      0.398  -0.310     0 
## 3 BAJA            113     0 3.45e-1 9.61e-1 9.04e-2  0      2.45    4.05      0 
## 4 SALARIO.DIAR…   113     0 1.81e+2 3.47e+1 3.27e+0  3.96   4.93   31.6     144.
## 5 FACTOR.CRED.…   113     0 2.24e+3 1.79e+4 1.68e+3  0      9.45   93.5       0 
## 6 N..CREDITO.I…   113     0 6.77e+7 3.55e+8 3.34e+7  0      5.10   24.4       0 
## 7 CODIGO.POSTAL   113     0 6.34e+4 1.12e+4 1.05e+3  9     -3.14    8.01  25016 
## # … with 16 more variables: p01 <dbl>, p05 <dbl>, p10 <dbl>, p20 <dbl>,
## #   p25 <dbl>, p30 <dbl>, p40 <dbl>, p50 <dbl>, p60 <dbl>, p70 <dbl>,
## #   p75 <dbl>, p80 <dbl>, p90 <dbl>, p95 <dbl>, p99 <dbl>, p100 <dbl>, and
## #   abbreviated variable names ¹​described_variables, ²​skewness, ³​kurtosis

Variables y Registros

R= 28 variables y 113 observaciones
str(colab)
## 'data.frame':    113 obs. of  28 variables:
##  $ No..De.Empleado      : int  1 2 3 4 5 6 7 8 9 10 ...
##  $ APELLIDOS            : chr  "MARTINEZ DE LOERA" "DE LEON MORENO" "HERNANDEZ CERVANTES" "CAZARES MORALES" ...
##  $ NOMBRE               : chr  "NICOLAS" "MARIANA" "JOSE LUIS" "MARIA" ...
##  $ FECHA.DE.NACIMIENTO  : chr  "10/09/1955" "14/05/1979" "21/11/1949" "01/05/1990" ...
##  $ EDAD                 : int  67 43 73 32 57 38 55 26 27 37 ...
##  $ GENERO               : chr  "MASCULINO" "FEMENINO" "MASCULINO" "FEMENINO" ...
##  $ RFC                  : chr  "MALN550910338" "LEMM7905148GA" "HECL4911213X3" "CAMM9005019S8" ...
##  $ FECHA.DE.ALTA        : chr  "01/07/2010" "01/07/2011" "22/11/2011" "30/01/2013" ...
##  $ PRIMER.MES           : chr  "31/07/2010" "31/07/2011" "22/12/2011" "01/03/2013" ...
##  $ CUARTO.MES           : chr  "29/10/2010" "29/10/2011" "22/04/2012" "30/05/2013" ...
##  $ BAJA                 : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ PUESTO               : chr  "SUPERVISOR/A" "SUPERVISOR/A" "EXTERNO" "SUPERVISOR/A" ...
##  $ DEPARTAMENTO         : chr  "PRODUCCION CARTON MDL" "PRODUCCION CARTON MDL" "EXTERNO" "PRODUCCION CARTON MC" ...
##  $ SALARIO.DIARIO.IMSS  : num  177 177 177 337 441 ...
##  $ FACTOR.CRED.INFONAVIT: num  0 0 0 0 0 0 0 0 0 0 ...
##  $ N..CREDITO.INFONAVIT : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ LUGAR.DE.NACIMIENTO  : chr  "NUEVO LEON" "NUEVO LEON" "NUEVO LEON" "NUEVO LEON" ...
##  $ CURP                 : chr  "MALN550910HZSRRC09" "LEMM790514MCLNRR09" "HECL491121HJCRRS04" "CAMM900501MVZZRR00" ...
##  $ CALLE                : chr  "JOSE I LUGO" "AGUSTIN LARA" "HACIENDA SAN CRISTOBAL" "RIO ACAPONETA" ...
##  $ NUMERO.INTERNO       : chr  "234" "115" "13" "234" ...
##  $ COLONIA              : chr  "UNIDAD LABORAL" "SANTA TERESITA" "VILLAS DE HUINALA" "PUEBLO NUEVO" ...
##  $ MUNICIPIO            : chr  "SAN NICOLAS DE LOS GARZA" "APODACA" "APODACA" "APODACA" ...
##  $ ESTADO               : chr  "NUEVO LEON" "NUEVO LEON" "NUEVO LEON" "NUEVO LEON" ...
##  $ CODIGO.POSTAL        : int  66440 66605 66634 66649 66620 25016 66633 66649 25290 66473 ...
##  $ ESTADO.CIVIL         : chr  "SOLTERO/A" "SOLTERO/A" "SOLTERO/A" "CASADO/A" ...
##  $ TARJETA.CUENTA       : chr  "BANORTE" "BANORTE" "BANORTE" "BANORTE" ...
##  $ X                    : logi  NA NA NA NA NA NA ...
##  $ X.1                  : logi  NA NA NA NA NA NA ...

Eliminar N/A´s

Se eliminan los N/A´s para evitar datos no precisos o erroneos.

sum(is.na(colab))
## [1] 226

Eliminar duplicados

Se eliminan valores duplicados para evitar no tener datos no organizados.

colab1<-colab
colab1<-distinct(colab1)

Eliminar Columnas

Se eliminan columnas para evitar tener información innecesaria en las bases de datos.

colab2<-colab1
colab2 <- subset(colab2, select =-c (NOMBRE))
colab2 <- subset(colab2, select =-c (APELLIDOS))
colab2 <- subset(colab2, select =-c (RFC))
colab2 <- subset(colab2, select =-c (CUARTO.MES))
colab2 <- subset(colab2, select =-c (FACTOR.CRED.INFONAVIT))
colab2 <- subset(colab2, select =-c (CURP))
colab2 <- subset(colab2, select =-c (CALLE))
colab2 <- subset(colab2, select =-c (NUMERO.INTERNO))
colab2 <- subset(colab2, select =-c (TARJETA.CUENTA))
summary(colab2)
##  No..De.Empleado  FECHA.DE.NACIMIENTO      EDAD          GENERO         
##  Min.   :  1.00   Length:113          Min.   : 0.00   Length:113        
##  1st Qu.: 31.00   Class :character    1st Qu.:25.00   Class :character  
##  Median : 63.00   Mode  :character    Median :33.00   Mode  :character  
##  Mean   : 75.86                       Mean   :35.74                     
##  3rd Qu.:127.00                       3rd Qu.:45.00                     
##  Max.   :169.00                       Max.   :73.00                     
##  FECHA.DE.ALTA       PRIMER.MES             BAJA           PUESTO         
##  Length:113         Length:113         Min.   :0.0000   Length:113        
##  Class :character   Class :character   1st Qu.:0.0000   Class :character  
##  Mode  :character   Mode  :character   Median :0.0000   Mode  :character  
##                                        Mean   :0.3451                     
##                                        3rd Qu.:0.0000                     
##                                        Max.   :3.0000                     
##  DEPARTAMENTO       SALARIO.DIARIO.IMSS N..CREDITO.INFONAVIT
##  Length:113         Min.   :144.4       Min.   :0.000e+00   
##  Class :character   1st Qu.:176.7       1st Qu.:0.000e+00   
##  Mode  :character   Median :180.7       Median :0.000e+00   
##                     Mean   :181.2       Mean   :6.770e+07   
##                     3rd Qu.:180.7       3rd Qu.:0.000e+00   
##                     Max.   :441.4       Max.   :1.922e+09   
##  LUGAR.DE.NACIMIENTO   COLONIA           MUNICIPIO            ESTADO         
##  Length:113          Length:113         Length:113         Length:113        
##  Class :character    Class :character   Class :character   Class :character  
##  Mode  :character    Mode  :character   Mode  :character   Mode  :character  
##                                                                              
##                                                                              
##                                                                              
##  CODIGO.POSTAL   ESTADO.CIVIL          X             X.1         
##  Min.   :25016   Length:113         Mode:logical   Mode:logical  
##  1st Qu.:66640   Class :character   NA's:113       NA's:113      
##  Median :66646   Mode  :character                                
##  Mean   :63365                                                   
##  3rd Qu.:66649                                                   
##  Max.   :67493

Escalas de variables

variables <- c(
  "No.De.Empleado",
  "APELLIDOS",
  "NOMBRE",
  "FECHA.DE.NACIMIENTO",
  "EDAD",
  "GENERO",
  "RFC",
  "FECHA.DE.ALTA",
  "PRIMER.MES",
  "CUARTO.MES",
  "BAJA",
  "PUESTO",
  "DEPARTAMENTO",
  "SALARIO.DIARIO.IMSS",
  "FACTOR.CRED.INFONAVIT",
  "N.CREDITO.INFONAVIT",
  "LUGAR.DE.NACIMIENTO",
  "CURP",
  "CALLE",
  "NUMERO.INTERNO",
  "COLONIA",
  "MUNICIPIO",
  "ESTADO",
  "CODIGO.POSTAL",
  "ESTADO.CIVIL",
  "TARJETA.CUENTA"
  )

tipos <- c(
              "Cuantitativo",
              "Cualitativo",
              "Cualitativo",
              "Cualitativo",
              "Cuantitativo",
              "Cualitativo",
              "Cualitativo",
              "Cuantitativo",
              "Cuantitativo",
              "Cuantitativo",
              "Cuantitativo",
              "Cualitativo",
              "Cualitativo",
              "Cuantitativo",
              "Cuantitativo",
              "Cualitativo",
              "Cualitativo",
              "Cualitativo",
              "Cualitativo",
              "Cuantitativo",
              "Cualitativo",
              "Cualitativo",
              "Cualitativo",
              "Cuantitativo",
              "Cualitativo",
              "Cualitativo"
              )

escalas <- c(
            "Intervalo",
             "Nominal",
             "Nominal",
             "Intervalo",
            "Intervalo",
             "Nominal",
            "Nominal",
            "Razón",
            "Razón",
            "Razón",
            "Razón",
            "Ordinal",
            "Nominal",
            "Razón",
            "Razón",
            "Nominal",
            "Nominal",
            "Nominal",
            "Nominal",
            "Razón",
            "Nominal",
            "Nominal",
            "Nominal",
            "Ordinal",
            "Nominal",
            "Nominal"
            )

tablecolaboradores <- data.frame (variables, tipos, escalas)
knitr::kable(tablecolaboradores)
variables tipos escalas
No.De.Empleado Cuantitativo Intervalo
APELLIDOS Cualitativo Nominal
NOMBRE Cualitativo Nominal
FECHA.DE.NACIMIENTO Cualitativo Intervalo
EDAD Cuantitativo Intervalo
GENERO Cualitativo Nominal
RFC Cualitativo Nominal
FECHA.DE.ALTA Cuantitativo Razón
PRIMER.MES Cuantitativo Razón
CUARTO.MES Cuantitativo Razón
BAJA Cuantitativo Razón
PUESTO Cualitativo Ordinal
DEPARTAMENTO Cualitativo Nominal
SALARIO.DIARIO.IMSS Cuantitativo Razón
FACTOR.CRED.INFONAVIT Cuantitativo Razón
N.CREDITO.INFONAVIT Cualitativo Nominal
LUGAR.DE.NACIMIENTO Cualitativo Nominal
CURP Cualitativo Nominal
CALLE Cualitativo Nominal
NUMERO.INTERNO Cuantitativo Razón
COLONIA Cualitativo Nominal
MUNICIPIO Cualitativo Nominal
ESTADO Cualitativo Nominal
CODIGO.POSTAL Cuantitativo Ordinal
ESTADO.CIVIL Cualitativo Nominal
TARJETA.CUENTA Cualitativo Nominal

Tabla de Frecuencia

Esta tabla de frecuencia representa el valor decimal del salario diario de acuerdo al género, es decir, la cantidad de empleados en valor decimal que reciben cierto salario diario de acuerdo a su género.

#install.packages('epiDisplay')
library(epiDisplay)
## Loading required package: MASS
## 
## Attaching package: 'MASS'
## The following object is masked from 'package:olsrr':
## 
##     cement
## The following object is masked from 'package:dplyr':
## 
##     select
## Loading required package: nnet
## 
## Attaching package: 'epiDisplay'
## The following object is masked from 'package:gmodels':
## 
##     ci
## The following object is masked from 'package:lmtest':
## 
##     lrtest
## The following object is masked from 'package:jtools':
## 
##     summ
## The following objects are masked from 'package:psych':
## 
##     alpha, cs, lookup
## The following object is masked from 'package:lattice':
## 
##     dotplot
## The following object is masked from 'package:ggplot2':
## 
##     alpha
tab1(colab2$GENERO, colab2$SALARIO.DIARIO.IMSS, sort.group = "decreasing", cum.percent = TRUE, main = "Distribución de Colaboradores por Genero")

## colab2$GENERO : 
##        Frequency  Percent Cum. percent
##   [1,]        61  53.9823      53.9823
##   [2,]        52  46.0177     100.0000
##   [3,]        61  53.9823      53.9823
##   [4,]        52  46.0177     100.0000
##   [5,]        61  53.9823      53.9823
##   [6,]        52  46.0177     100.0000
##   [7,]        61  53.9823      53.9823
##   [8,]        52  46.0177     100.0000
##   [9,]        61  53.9823      53.9823
##  [10,]        52  46.0177     100.0000
##  [11,]        61  53.9823      53.9823
##  [12,]        52  46.0177     100.0000
##  [13,]        61  53.9823      53.9823
##  [14,]        52  46.0177     100.0000
##  [15,]        61  53.9823      53.9823
##  [16,]        52  46.0177     100.0000
##  [17,]        61  53.9823      53.9823
##  [18,]        52  46.0177     100.0000
##  [19,]        61  53.9823      53.9823
##  [20,]        52  46.0177     100.0000
##  [21,]        61  53.9823      53.9823
##  [22,]        52  46.0177     100.0000
##  [23,]        61  53.9823      53.9823
##  [24,]        52  46.0177     100.0000
##  [25,]        61  53.9823      53.9823
##  [26,]        52  46.0177     100.0000
##  [27,]        61  53.9823      53.9823
##  [28,]        52  46.0177     100.0000
##  [29,]        61  53.9823      53.9823
##  [30,]        52  46.0177     100.0000
##  [31,]        61  53.9823      53.9823
##  [32,]        52  46.0177     100.0000
##  [33,]        61  53.9823      53.9823
##  [34,]        52  46.0177     100.0000
##  [35,]        61  53.9823      53.9823
##  [36,]        52  46.0177     100.0000
##  [37,]        61  53.9823      53.9823
##  [38,]        52  46.0177     100.0000
##  [39,]        61  53.9823      53.9823
##  [40,]        52  46.0177     100.0000
##  [41,]        61  53.9823      53.9823
##  [42,]        52  46.0177     100.0000
##  [43,]        61  53.9823      53.9823
##  [44,]        52  46.0177     100.0000
##  [45,]        61  53.9823      53.9823
##  [46,]        52  46.0177     100.0000
##  [47,]        61  53.9823      53.9823
##  [48,]        52  46.0177     100.0000
##  [49,]        61  53.9823      53.9823
##  [50,]        52  46.0177     100.0000
##  [51,]        61  53.9823      53.9823
##  [52,]        52  46.0177     100.0000
##  [53,]        61  53.9823      53.9823
##  [54,]        52  46.0177     100.0000
##  [55,]        61  53.9823      53.9823
##  [56,]        52  46.0177     100.0000
##  [57,]        61  53.9823      53.9823
##  [58,]        52  46.0177     100.0000
##  [59,]        61  53.9823      53.9823
##  [60,]        52  46.0177     100.0000
##  [61,]        61  53.9823      53.9823
##  [62,]        52  46.0177     100.0000
##  [63,]        61  53.9823      53.9823
##  [64,]        52  46.0177     100.0000
##  [65,]        61  53.9823      53.9823
##  [66,]        52  46.0177     100.0000
##  [67,]        61  53.9823      53.9823
##  [68,]        52  46.0177     100.0000
##  [69,]        61  53.9823      53.9823
##  [70,]        52  46.0177     100.0000
##  [71,]        61  53.9823      53.9823
##  [72,]        52  46.0177     100.0000
##  [73,]        61  53.9823      53.9823
##  [74,]        52  46.0177     100.0000
##  [75,]        61  53.9823      53.9823
##  [76,]        52  46.0177     100.0000
##  [77,]        61  53.9823      53.9823
##  [78,]        52  46.0177     100.0000
##  [79,]        61  53.9823      53.9823
##  [80,]        52  46.0177     100.0000
##  [81,]        61  53.9823      53.9823
##  [82,]        52  46.0177     100.0000
##  [83,]        61  53.9823      53.9823
##  [84,]        52  46.0177     100.0000
##  [85,]        61  53.9823      53.9823
##  [86,]        52  46.0177     100.0000
##  [87,]        61  53.9823      53.9823
##  [88,]        52  46.0177     100.0000
##  [89,]        61  53.9823      53.9823
##  [90,]        52  46.0177     100.0000
##  [91,]        61  53.9823      53.9823
##  [92,]        52  46.0177     100.0000
##  [93,]        61  53.9823      53.9823
##  [94,]        52  46.0177     100.0000
##  [95,]        61  53.9823      53.9823
##  [96,]        52  46.0177     100.0000
##  [97,]        61  53.9823      53.9823
##  [98,]        52  46.0177     100.0000
##  [99,]        61  53.9823      53.9823
## [100,]        52  46.0177     100.0000
## [101,]        61  53.9823      53.9823
## [102,]        52  46.0177     100.0000
## [103,]        61  53.9823      53.9823
## [104,]        52  46.0177     100.0000
## [105,]        61  53.9823      53.9823
## [106,]        52  46.0177     100.0000
## [107,]        61  53.9823      53.9823
## [108,]        52  46.0177     100.0000
## [109,]        61  53.9823      53.9823
## [110,]        52  46.0177     100.0000
## [111,]        61  53.9823      53.9823
## [112,]        52  46.0177     100.0000
## [113,]        61  53.9823      53.9823
## [114,]      6389 100.0000     100.0000

Sección 2. Análisis Exploratorio

Tabla Media, Mediana y Desviación Estandar

describe(colab2)
## # A tibble: 6 × 26
##   described_v…¹     n    na    mean      sd se_mean   IQR skewn…² kurto…³    p00
##   <chr>         <int> <int>   <dbl>   <dbl>   <dbl> <dbl>   <dbl>   <dbl>  <dbl>
## 1 No..De.Emple…   113     0 7.59e+1 5.39e+1 5.07e+0 96      0.400  -1.24      1 
## 2 EDAD            113     0 3.57e+1 1.33e+1 1.25e+0 20      0.398  -0.310     0 
## 3 BAJA            113     0 3.45e-1 9.61e-1 9.04e-2  0      2.45    4.05      0 
## 4 SALARIO.DIAR…   113     0 1.81e+2 3.47e+1 3.27e+0  3.96   4.93   31.6     144.
## 5 N..CREDITO.I…   113     0 6.77e+7 3.55e+8 3.34e+7  0      5.10   24.4       0 
## 6 CODIGO.POSTAL   113     0 6.34e+4 1.12e+4 1.05e+3  9     -3.14    8.01  25016 
## # … with 16 more variables: p01 <dbl>, p05 <dbl>, p10 <dbl>, p20 <dbl>,
## #   p25 <dbl>, p30 <dbl>, p40 <dbl>, p50 <dbl>, p60 <dbl>, p70 <dbl>,
## #   p75 <dbl>, p80 <dbl>, p90 <dbl>, p95 <dbl>, p99 <dbl>, p100 <dbl>, and
## #   abbreviated variable names ¹​described_variables, ²​skewness, ³​kurtosis
count(colab2, GENERO, sort = TRUE)
##      GENERO  n
## 1  FEMENINO 61
## 2 MASCULINO 52
count(colab2, PUESTO, sort = TRUE)
##                       PUESTO  n
## 1           AYUDANTE GENERAL 67
## 2                COSTURERO/A 10
## 3                     CHOFER  5
## 4                   SOLDADOR  5
## 5                  RESIDENTE  4
## 6               SUPERVISOR/A  4
## 7                    EXTERNO  2
## 8     INSPECTOR/A DE CALIDAD  2
## 9                   OPERADOR  2
## 10 AYUDANTE DE MANTENIMIENTO  1
## 11               ENFERMERO/A  1
## 12                    GESTOR  1
## 13      GUARDIA DE SEGURIDAD  1
## 14                     LIDER  1
## 15                  LIMPIEZA  1
## 16             MANTENIMIENTO  1
## 17            MONTACARGUISTA  1
## 18                      MOZO  1
## 19                    PINTOR  1
## 20                    RECIBO  1
## 21       SERVICIO AL CLIENTE  1
count(colab2, DEPARTAMENTO, sort = TRUE)
##             DEPARTAMENTO  n
## 1                 VARIOS 40
## 2      PRODUCCION RETORN 10
## 3                COSTURA  9
## 4                  CEDIS  8
## 5  PRODUCCION CARTON MDL  7
## 6               STABILUS  7
## 7   PRODUCCION CARTON MC  5
## 8              EMBARQUES  4
## 9               PAILERIA  4
## 10               TROQUEL  4
## 11                CELDAS  3
## 12                   EHS  3
## 13               CALIDAD  2
## 14               EXTERNO  2
## 15              AY FLEXO  1
## 16            CORTADORAS  1
## 17              LIMPIEZA  1
## 18            MATERIALES  1
## 19              ROTATIVA  1
count(colab2, SALARIO.DIARIO.IMSS, sort = TRUE)
##    SALARIO.DIARIO.IMSS  n
## 1               180.68 59
## 2               176.72 23
## 3               151.61 11
## 4               151.67  5
## 5               144.45  3
## 6               152.86  1
## 7               175.79  1
## 8               181.68  1
## 9               184.68  1
## 10              185.68  1
## 11              208.65  1
## 12              240.71  1
## 13              240.75  1
## 14              260.01  1
## 15              279.61  1
## 16              337.05  1
## 17              441.37  1
count(colab2, LUGAR.DE.NACIMIENTO, sort = TRUE)
##    LUGAR.DE.NACIMIENTO  n
## 1           NUEVO LEON 79
## 2             VERACRUZ 12
## 3             COAHUILA  5
## 4      SAN LUIS POTOSI  3
## 5           TAMAULIPAS  3
## 6              CHIAPAS  2
## 7     CIUDAD DE MEXICO  2
## 8              DURANGO  2
## 9           GUANAJUATO  1
## 10            HONDURAS  1
## 11        QUINTANA ROO  1
## 12             TABASCO  1
## 13           ZACATECAS  1
tibble(colab2)
## # A tibble: 113 × 19
##    No..De.Em…¹ FECHA…²  EDAD GENERO FECHA…³ PRIME…⁴  BAJA PUESTO DEPAR…⁵ SALAR…⁶
##          <int> <chr>   <int> <chr>  <chr>   <chr>   <int> <chr>  <chr>     <dbl>
##  1           1 10/09/…    67 MASCU… 01/07/… 31/07/…     0 SUPER… PRODUC…    177.
##  2           2 14/05/…    43 FEMEN… 01/07/… 31/07/…     0 SUPER… PRODUC…    177.
##  3           3 21/11/…    73 MASCU… 22/11/… 22/12/…     0 EXTER… EXTERNO    177.
##  4           4 01/05/…    32 FEMEN… 30/01/… 01/03/…     0 SUPER… PRODUC…    337.
##  5           5 06/09/…    57 FEMEN… 05/05/… 04/06/…     0 SUPER… COSTURA    441.
##  6           6 22/06/…    38 MASCU… 03/07/… 02/08/…     0 SERVI… CEDIS      177.
##  7           7 01/07/…    55 FEMEN… 06/08/… 05/09/…     0 COSTU… COSTURA    260.
##  8           8 10/12/…    26 MASCU… 23/08/… 22/09/…     0 AYUDA… PRODUC…    241.
##  9           9 03/11/…    27 MASCU… 11/01/… 10/02/…     0 AYUDA… CEDIS      177.
## 10          10 18/08/…    37 FEMEN… 20/02/… 22/03/…     0 COSTU… COSTURA    153.
## # … with 103 more rows, 9 more variables: N..CREDITO.INFONAVIT <int>,
## #   LUGAR.DE.NACIMIENTO <chr>, COLONIA <chr>, MUNICIPIO <chr>, ESTADO <chr>,
## #   CODIGO.POSTAL <int>, ESTADO.CIVIL <chr>, X <lgl>, X.1 <lgl>, and
## #   abbreviated variable names ¹​No..De.Empleado, ²​FECHA.DE.NACIMIENTO,
## #   ³​FECHA.DE.ALTA, ⁴​PRIMER.MES, ⁵​DEPARTAMENTO, ⁶​SALARIO.DIARIO.IMSS

En esta primera parte del análisis estadístico descriptivo, vemos que el conteo total de empleados actuales es de 113 y hay un mayor número de mujeres (54%) contra empleados que son hombres (46%).

En cuanto a los puestos, vemos que existe una gran cantidad de ayudantes generales, pues es el puesto que ocupa mayor capital humano, contra aquellos que ocupan menos que van desde servicio al cliente hasta operadores.

Entre los departamentos con mayor cantidad de empleados, vemos que está varios y producción retorno. El departamento de “Varios” fue creado para catalogar a aquellos empleados que en la base de datos no tenían definida un área en concreto.

Vemos que la mayoría de los empleados ganan $180.68 pesos de salario diario por el IMSS y de todos los empleados, se calcula que tienen un promedio de salario diario de $236.62 pesos.

En cuanto al lugar de origen, vemos que la mayoría de los empleados provienen del Estado de Nuevo León (70%) y Veracruz (11%), viendo que el 19% restante de los empleados son provenientes de Zona Centro o estados colidantes de Nuevo León.

Aqui la variable que más nos interesa es la media de las bajas totales que hay dentro de FORM.

tablecolaboradores<-describe(colab2)
knitr::kable(tablecolaboradores)
described_variables n na mean sd se_mean IQR skewness kurtosis p00 p01 p05 p10 p20 p25 p30 p40 p50 p60 p70 p75 p80 p90 p95 p99 p100
No..De.Empleado 113 0 7.585841e+01 5.387649e+01 5.068274e+00 96.00 0.3996039 -1.243295 1.00 2.12 6.60 12.20 24.40 31.00 36.60 47.80 63.00 79.40 110.20 127.00 143.20 157.80 163.400 1.678800e+02 1.69000e+02
EDAD 113 0 3.574336e+01 1.328585e+01 1.249828e+00 20.00 0.3976708 -0.310438 0.00 18.12 19.00 20.00 23.00 25.00 27.00 29.80 33.00 38.00 42.40 45.00 49.00 55.00 57.400 6.616000e+01 7.30000e+01
BAJA 113 0 3.451327e-01 9.614898e-01 9.044940e-02 0.00 2.4455291 4.052025 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 3.00 3.000 3.000000e+00 3.00000e+00
SALARIO.DIARIO.IMSS 113 0 1.811764e+02 3.473107e+01 3.267225e+00 3.96 4.9257214 31.555773 144.45 144.45 151.61 151.61 176.72 176.72 176.72 180.68 180.68 180.68 180.68 180.68 180.68 180.68 221.474 3.301572e+02 4.41370e+02
N..CREDITO.INFONAVIT 113 0 6.769777e+07 3.549686e+08 3.339264e+07 0.00 5.0965722 24.407079 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.000 1.912205e+09 1.92159e+09
CODIGO.POSTAL 113 0 6.336474e+04 1.120189e+04 1.053785e+03 9.00 -3.1379797 8.012458 25016.00 25091.24 25901.20 64845.60 66633.40 66640.00 66643.00 66646.00 66646.00 66646.00 66648.00 66649.00 66671.80 67117.00 67256.200 6.726700e+04 6.74930e+04

Gráficas de Dispersión

Dentro de esta gráfica de dispersión se ven en promedio que las edades no afectan en el parametro del salario diario, se muestran que hay algúnos datos fuera de la media pero se denota una estabilidad de los datos.

plot(x=colab2$SALARIO.DIARIO.IMSS , y=colab2$EDAD, 
     xlab= "Salario Diario", ylab="Edad",
     main="Dispersión de Edad con Salario")

RH Bajas

Sección 1. Limpieza de datos, Transformación y Entendimiento (1-4)

Para estas dos bases de datos, se utilizaron la eliminación de N/A´s, cambio de nombre y quitar columnas de nuestra base de datos para poder utilizarlas de la manera más adecuada.

### Importar base de datos

bajas <-read.csv("C:\\Users\\danyc\\Downloads\\HR_Bajas 2.csv")

Variables y Registros

R= 26 variables y 78 observaciones.
summary(bajas)
##   NO.DE.BAJAS      APELLIDOS            NOMBRE          FECHA.DE.NACIMIENTO
##  Min.   :  5.00   Length:78          Length:78          Min.   :25585      
##  1st Qu.: 49.75   Class :character   Class :character   1st Qu.:31751      
##  Median :167.50   Mode  :character   Mode  :character   Median :33797      
##  Mean   :139.60                                         Mean   :33611      
##  3rd Qu.:212.75                                         3rd Qu.:36519      
##  Max.   :238.00                                         Max.   :44632      
##       EDAD          GENERO          FECHA.DE.ALTA   MOTIVO.DE.BAJA    
##  Min.   : 0.00   Length:78          Min.   :43961   Length:78         
##  1st Qu.:22.25   Class :character   1st Qu.:44567   Class :character  
##  Median :30.00   Mode  :character   Median :44726   Mode  :character  
##  Mean   :30.50                      Mean   :44664                     
##  3rd Qu.:36.00                      3rd Qu.:44759                     
##  Max.   :52.00                      Max.   :44790                     
##  DIAS.TRABAJADOS       BAJA          PUESTO          DEPARTAMENTO      
##  Min.   :  0.00   Min.   :44569   Length:78          Length:78         
##  1st Qu.:  9.00   1st Qu.:44613   Class :character   Class :character  
##  Median : 19.00   Median :44741   Mode  :character   Mode  :character  
##  Mean   : 45.10   Mean   :44709                                        
##  3rd Qu.: 39.75   3rd Qu.:44784                                        
##  Max.   :730.00   Max.   :44814                                        
##  NO.SEGURO.SOCIAL   SALARIO.DIARIO.IMSS FACTOR.CRED.INFONAVIT
##  Length:78          Min.   :151.6       Min.   :   0.0       
##  Class :character   1st Qu.:180.7       1st Qu.:   0.0       
##  Mode  :character   Median :180.7       Median :   0.0       
##                     Mean   :174.3       Mean   : 130.4       
##                     3rd Qu.:180.7       3rd Qu.:   0.0       
##                     Max.   :183.7       Max.   :2795.3       
##  NO.CREDITO.INFONAVIT LUGAR.DE.NACIMIENTO     CURP              CALLE          
##  Min.   :0.000e+00    Length:78           Length:78          Length:78         
##  1st Qu.:0.000e+00    Class :character    Class :character   Class :character  
##  Median :0.000e+00    Mode  :character    Mode  :character   Mode  :character  
##  Mean   :1.871e+08                                                             
##  3rd Qu.:0.000e+00                                                             
##  Max.   :6.919e+09                                                             
##  NUMERO.INTERNO       COLONIA          CODIGO.POSTAL    MUNICIPIO        
##  Length:78          Length:78          Min.   :25019   Length:78         
##  Class :character   Class :character   1st Qu.:33604   Class :character  
##  Mode  :character   Mode  :character   Median :33604   Mode  :character  
##                                        Mean   :46508                     
##                                        3rd Qu.:66645                     
##                                        Max.   :67450                     
##     ESTADO          ESTADO.CIVIL       TARJETA.CUENTA    
##  Length:78          Length:78          Length:78         
##  Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character  
##                                                          
##                                                          
## 

¿Cuántos NA’s tengo en la base de datos?

sum(is.na(bajas))
## [1] 0

Borrar todos los registros NA’s de una tabla

bajas2<-bajas
bajas2<-na.omit(bajas2)
summary(bajas2)
##   NO.DE.BAJAS      APELLIDOS            NOMBRE          FECHA.DE.NACIMIENTO
##  Min.   :  5.00   Length:78          Length:78          Min.   :25585      
##  1st Qu.: 49.75   Class :character   Class :character   1st Qu.:31751      
##  Median :167.50   Mode  :character   Mode  :character   Median :33797      
##  Mean   :139.60                                         Mean   :33611      
##  3rd Qu.:212.75                                         3rd Qu.:36519      
##  Max.   :238.00                                         Max.   :44632      
##       EDAD          GENERO          FECHA.DE.ALTA   MOTIVO.DE.BAJA    
##  Min.   : 0.00   Length:78          Min.   :43961   Length:78         
##  1st Qu.:22.25   Class :character   1st Qu.:44567   Class :character  
##  Median :30.00   Mode  :character   Median :44726   Mode  :character  
##  Mean   :30.50                      Mean   :44664                     
##  3rd Qu.:36.00                      3rd Qu.:44759                     
##  Max.   :52.00                      Max.   :44790                     
##  DIAS.TRABAJADOS       BAJA          PUESTO          DEPARTAMENTO      
##  Min.   :  0.00   Min.   :44569   Length:78          Length:78         
##  1st Qu.:  9.00   1st Qu.:44613   Class :character   Class :character  
##  Median : 19.00   Median :44741   Mode  :character   Mode  :character  
##  Mean   : 45.10   Mean   :44709                                        
##  3rd Qu.: 39.75   3rd Qu.:44784                                        
##  Max.   :730.00   Max.   :44814                                        
##  NO.SEGURO.SOCIAL   SALARIO.DIARIO.IMSS FACTOR.CRED.INFONAVIT
##  Length:78          Min.   :151.6       Min.   :   0.0       
##  Class :character   1st Qu.:180.7       1st Qu.:   0.0       
##  Mode  :character   Median :180.7       Median :   0.0       
##                     Mean   :174.3       Mean   : 130.4       
##                     3rd Qu.:180.7       3rd Qu.:   0.0       
##                     Max.   :183.7       Max.   :2795.3       
##  NO.CREDITO.INFONAVIT LUGAR.DE.NACIMIENTO     CURP              CALLE          
##  Min.   :0.000e+00    Length:78           Length:78          Length:78         
##  1st Qu.:0.000e+00    Class :character    Class :character   Class :character  
##  Median :0.000e+00    Mode  :character    Mode  :character   Mode  :character  
##  Mean   :1.871e+08                                                             
##  3rd Qu.:0.000e+00                                                             
##  Max.   :6.919e+09                                                             
##  NUMERO.INTERNO       COLONIA          CODIGO.POSTAL    MUNICIPIO        
##  Length:78          Length:78          Min.   :25019   Length:78         
##  Class :character   Class :character   1st Qu.:33604   Class :character  
##  Mode  :character   Mode  :character   Median :33604   Mode  :character  
##                                        Mean   :46508                     
##                                        3rd Qu.:66645                     
##                                        Max.   :67450                     
##     ESTADO          ESTADO.CIVIL       TARJETA.CUENTA    
##  Length:78          Length:78          Length:78         
##  Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character  
##                                                          
##                                                          
## 

Eliminar columnas

bajas3<-bajas2
bajas3 <- subset(bajas3, select =-c (APELLIDOS))
bajas3 <- subset(bajas3, select =-c (NOMBRE))
bajas3 <- subset(bajas3, select =-c (FACTOR.CRED.INFONAVIT))
bajas3 <- subset(bajas3, select =-c (CURP))
bajas3 <- subset(bajas3, select =-c (CALLE))
bajas3 <- subset(bajas3, select =-c (NUMERO.INTERNO))
bajas3 <- subset(bajas3, select =-c (TARJETA.CUENTA))

¿Cuántos NA’s tengo en la base de datos?

sum(is.na(bajas3))
## [1] 0

Nota: Con los datos presentados anteriormente, vemos que la edad promedio de los colaboradores es de 35 años, además de que ganan un promedio de $180 pesos.

Clasificación de Variables

variables <- c("No de bajas",
  "FECHA.DE.NACIMIENTO",
  "EDAD",
  "GENERO",
  "FECHA.DE.ALTA",
  "Motivo de Baja",
  "Dias Trabajados",
  "BAJA",
  "PUESTO",
  "Departamento",
  "Seguro Social",
  "SALARIO.DIARIO.IMSS",
  "N..CREDITO.INFONAVIT",
  "LUGAR.DE.NACIMIENTO",
  "COLONIA",
  "CODIGO.POSTAL",
  "MUNICIPIO",
  "ESTADO",
  "ESTADO.CIVIL")

tipos <- c("Cuantitativo",
              "Cualitativo",
              "Cuantitativo",
              "Cualitativo",
              "Cuantitativo",
              "Cualitativo",
              "Cuantitativo",
              "Cuantitativo",
              "cualitativo",
              "Cualitativo",
              "Cualitativo",
              "Cuantitativo",
              "Cualitativo",
              "Cualitativo",
              "Cualitativo",
              "Cuantitativo",
              "Cualitativo",
              "Cualitativo",
              "Cualitativo")

escalas <- c("Intervalo",
             "Nominal",
             "Intervalo",
             "Nominal",
            "Razón",
            "Nominal",
            "Razón",
            "Razón",
            "Ordinal",
            "Nominal",
            "Nominal",
            "Razon",
            "Nominal",
            "Nominal",
            "Nominal",
            "Ordinaria",
            "Nominal",
            "Nominal",
            "Nominal")

tablebajas <- data.frame (variables, tipos, escalas)
knitr::kable(tablebajas)
variables tipos escalas
No de bajas Cuantitativo Intervalo
FECHA.DE.NACIMIENTO Cualitativo Nominal
EDAD Cuantitativo Intervalo
GENERO Cualitativo Nominal
FECHA.DE.ALTA Cuantitativo Razón
Motivo de Baja Cualitativo Nominal
Dias Trabajados Cuantitativo Razón
BAJA Cuantitativo Razón
PUESTO cualitativo Ordinal
Departamento Cualitativo Nominal
Seguro Social Cualitativo Nominal
SALARIO.DIARIO.IMSS Cuantitativo Razon
N..CREDITO.INFONAVIT Cualitativo Nominal
LUGAR.DE.NACIMIENTO Cualitativo Nominal
COLONIA Cualitativo Nominal
CODIGO.POSTAL Cuantitativo Ordinaria
MUNICIPIO Cualitativo Nominal
ESTADO Cualitativo Nominal
ESTADO.CIVIL Cualitativo Nominal

Sección 2. Análisis Exploratorio

Media, Mediana y Std. Deviation

median(bajas3$DIAS.TRABAJADOS, na.rm = TRUE)
## [1] 19
mean(bajas3$DIAS.TRABAJADOS, na.rm = TRUE)
## [1] 45.10256
sd(bajas3$DIAS.TRABAJADOS, na.rm = FALSE)
## [1] 90.92691
Variable<-c("Dias Trabajados")
Mediana<-c("19")
Media <- c("45")
Desviación_estandar<-c("90")
tablebaja <- tibble (Variable, Mediana , Media , Desviación_estandar)
knitr::kable(tablebaja)
Variable Mediana Media Desviación_estandar
Dias Trabajados 19 45 90

Graphs

Tabla Cruzada 1

En la tabla vemos que se destacan tres razones principales de bajas de empleados, las cuales son: bajas por faltas, renuncia voluntaria o término de contrato. En su mayoría, hubo una baja por faltas del puesto de ayudante general y renuncia voluntaria para el mismo puesto. Al igual que en la base de datos anterior, vemos que el puesto con mayor rotación a nivel histórico es de ayudante general. Esto sugiere que existe un alto número de contrataciones para el puesto debido a una mala gestión administrativa o bajo rendimiento de los empleados.

table(bajas3$PUESTO, bajas3$MOTIVO.DE.BAJA)
##                              
##                               BAJA POR FALTAS RENUNCIA VOLUNTARIA
##   AYUDANTE DE EMBARQUES                     0                   0
##   AYUDANTE GENERAL                         50                  18
##   COSTURERO/A                               1                   0
##   GUARDIA DE SEGURIDAD                      0                   1
##   INSPECTOR DE CALIDAD                      1                   0
##   JEFE DE SEGURIDAD E HIGIENE               0                   1
##   MONTACARGUISTA                            1                   1
##   RESIDENTE                                 1                   0
##   SOLDADOR                                  1                   0
##                              
##                               TERMINO DE CONTRATO
##   AYUDANTE DE EMBARQUES                         1
##   AYUDANTE GENERAL                              1
##   COSTURERO/A                                   0
##   GUARDIA DE SEGURIDAD                          0
##   INSPECTOR DE CALIDAD                          0
##   JEFE DE SEGURIDAD E HIGIENE                   0
##   MONTACARGUISTA                                0
##   RESIDENTE                                     0
##   SOLDADOR                                      0

Tabla Cruzada 2

La tabla cruzada anterior nos muestra la relación entre los motivos de baja contra el género, es decir, las principales razones de baja de acuerdo al género de cada empleado. Vemos que hubo un total de 53 bajas del género femenino, destacando las bajas por faltas (representa un 75% de las bajas femeninas). Para el género masculino, hubo un total de 25 faltas, destacando principalmente las bajas por faltas (representa un 60% de las bajas masculinas).

table(bajas3$GENERO, bajas3$MOTIVO.DE.BAJA)
##            
##             BAJA POR FALTAS RENUNCIA VOLUNTARIA TERMINO DE CONTRATO
##   FEMENINO               40                  12                   1
##   MASCULINO              15                   9                   1

Gráficos de datos cuantitativos y cualitativos

La gráfica nos muestra que hay un mayor número de ex-empleados que viven en el Estado de Nuevo León. Sin embargo, hay un porcentaje que reside en Coahuila. Esto se puede interpretar con que hay un alto nivel de rotación existente debido a la lejanía de residencia de los empleados.

pie(table(bajas3$ESTADO), col=c("orange","coral1"),
    main="Representación de bajas acorde al estado de residencia")

Gráfico de Pie

La anterior gráfica de pastel reafirma lo que mencionamos anteriormente. De acuerdo a las bajas realizadas, la mayoría de los ex-empleados son del género femenino.

pie(table(bajas3$GENERO), col=c("orange","coral1"),
    main="Representación de bajas acorde al género")

Gráfica de dispersión

La gráfica de dispersión nos muestra la intensidad de relación entre la variable de días trabajados y número de bajas. Esto nos dice que hubo un alto número de bajas de empleados que trabajaron menos de 200 días, es decir, la mayoría de los ex-empleados estuvieron en FORM menos de 1 año.

plot(x= bajas3$NO.DE.BAJAS,
     y=bajas3$DIAS.TRABAJADOS, main= "Numero de bajas en compración de los dias laborados", xlab= "Numero de Bajas", ylab= "Dias Trabajados")

Boxplot

La gráfica anterior nos muestra la correlación entre el género y el salario diario de los empleados. En este, entendemos que el género femenino tiene un salario diario total más alto que los de género masculino.

ggplot(bajas3, aes(GENERO,SALARIO.DIARIO.IMSS,fill=GENERO)) +
geom_bar(stat = "identity") +
  scale_fill_brewer(palette = "Set2") + ggtitle("Salario diario por género")

Conclusiónes, Propuestas y Hallazgos Colaboradores y Bajas

Primero que nada, es bueno especificar la utilización de una buena limpieza de datos, como especifique anteriormente, pudimos notar una mejora en las bases de datos y la manipulación de ellas al no tener valores vacios dentro de nuestras bases de recursos humanos, esto tambien nos permitió generar insights importantes como: 1. Las mujeres ganan mejor que los hombres dentro de la empresa FORM 2. Las mujeres son las que más renuncian 3.Los empleados con menos de 200 días se vieron menos leales a la empresa

De aquí también surgieron distintos tipos de propuestas como:
1. Desglosar si las mujeres que renunciaron tienen familias y si es así ver la manera en la cual se puedan dar banaficios para los hijos. 2. Implementar un plan de motivadores desde que llega el primer empleado. 3. Hacer un plan touchpoints internos con los empleados para disminuir la tasa de rotación.

Delivery Plan

Sección 1. Limpieza de datos, Transformación y Entendimiento (1-4)

Importar la base de datos

#file.choose()
delivery<-read.csv("C:\\Users\\danyc\\Downloads\\DELIVERY.csv")
summary(delivery)
##     ID_Fecha        Fecha             CLIENTE             Pedidos       
##  Min.   : 1.00   Length:228         Length:228         Min.   :    0.0  
##  1st Qu.: 3.75   Class :character   Class :character   1st Qu.:    0.0  
##  Median : 6.50   Mode  :character   Mode  :character   Median :    0.0  
##  Mean   : 6.50                                         Mean   : 1703.1  
##  3rd Qu.: 9.25                                         3rd Qu.:  233.8  
##  Max.   :12.00                                         Max.   :52779.0

Notas:

1.Se hizo limpieza manual de la base de datos para acomodar los clientes como variables y las fechas como registros.

2.Se sustituyeron NAs por cero.

3.Se eliminaron columnas no usadas y que no agreegan valor para el analisis que se busca hacer.

Descargar librerías y paquetes

library(foreign)
library(dplyr)
library(forcats)
library(ggplot2)
library(readr)
library(janitor)
library(naniar)
library(dlookr)

Variables y Registros

R= 3 variables y 380 observaciones.
str(delivery)
## 'data.frame':    228 obs. of  4 variables:
##  $ ID_Fecha: int  1 1 1 1 1 1 1 1 1 1 ...
##  $ Fecha   : chr  "31/01/22" "31/01/22" "31/01/22" "31/01/22" ...
##  $ CLIENTE : chr  "STB3" "STB 1" "YF RAMOS" "INOAC POLYTEC" ...
##  $ Pedidos : int  481 0 227 0 400 328 393 0 8975 449 ...

Contar total de pedidos por cliente

Contamos con 52,0281 pedidos

deliverySUM = colSums(delivery[4])

as.data.frame(deliverySUM)
##         deliverySUM
## Pedidos      388317

Importar Base Clientes form

Con este plot podemos ver que hay muchos clientes con muy pocos pedidos.

#file.choose()
deliveryCLIENTS<-read.csv("C:\\Users\\danyc\\Downloads\\DeliveryCLIENTS.xlsx - Sheet1.csv")
summary(deliveryCLIENTS)
##     Fecha                STB3            STB.1           YF.RAMOS   
##  Length:19          Min.   :   0.0   Min.   : 0.000   Min.   :   0  
##  Class :character   1st Qu.:  13.5   1st Qu.: 0.000   1st Qu.:  54  
##  Mode  :character   Median : 200.0   Median : 0.000   Median : 100  
##                     Mean   : 297.1   Mean   : 2.632   Mean   : 211  
##                     3rd Qu.: 460.5   3rd Qu.: 0.000   3rd Qu.: 230  
##                     Max.   :1015.0   Max.   :50.000   Max.   :1243  
##  INOAC.POLYTEC       MERIDIAN     YANFENG.sm          YFTO       
##  Min.   : 0.000   Min.   :  0   Min.   :  0.00   Min.   : 138.0  
##  1st Qu.: 0.000   1st Qu.:  0   1st Qu.:  0.00   1st Qu.: 358.5  
##  Median : 0.000   Median :  0   Median : 41.00   Median : 628.0  
##  Mean   : 2.684   Mean   : 33   Mean   : 95.05   Mean   : 869.6  
##  3rd Qu.: 0.000   3rd Qu.:  0   3rd Qu.:142.50   3rd Qu.: 871.5  
##  Max.   :40.000   Max.   :400   Max.   :328.00   Max.   :2556.0  
##      YF.QRO            TRMX           DENSO           SEGROVE      
##  Min.   : 0.000   Min.   :    0   Min.   :   0.0   Min.   :  0.00  
##  1st Qu.: 0.000   1st Qu.: 2822   1st Qu.: 150.5   1st Qu.:  0.00  
##  Median : 0.000   Median : 6240   Median : 372.0   Median :  0.00  
##  Mean   : 2.737   Mean   : 5796   Mean   :1241.3   Mean   : 38.74  
##  3rd Qu.: 0.000   3rd Qu.: 8374   3rd Qu.:1083.0   3rd Qu.:  0.00  
##  Max.   :36.000   Max.   :11833   Max.   :8834.0   Max.   :736.00  
##      HANON        ANTOLIN.TOLUCA ANTOLIN.ARTEAGA     HELLA      
##  Min.   :  0.00   Min.   :0      Mode:logical    Min.   :    0  
##  1st Qu.:  0.00   1st Qu.:0      NA's:19         1st Qu.: 4160  
##  Median :  0.00   Median :0                      Median : 8580  
##  Mean   : 21.58   Mean   :0                      Mean   :15013  
##  3rd Qu.:  0.00   3rd Qu.:0                      3rd Qu.:21191  
##  Max.   :360.00   Max.   :0                      Max.   :52779  
##       UFI              ISRI            TRMX.1  ABC.QUERETARO        VARROC    
##  Min.   :  0.00   Min.   :   0.0   Min.   :0   Min.   :0.0000   Min.   :   0  
##  1st Qu.:  0.00   1st Qu.:   0.0   1st Qu.:0   1st Qu.:0.0000   1st Qu.:2078  
##  Median :  0.00   Median :   0.0   Median :0   Median :0.0000   Median :3509  
##  Mean   : 45.74   Mean   : 157.9   Mean   :0   Mean   :0.4211   Mean   :3555  
##  3rd Qu.:  3.50   3rd Qu.:   0.0   3rd Qu.:0   3rd Qu.:0.0000   3rd Qu.:4974  
##  Max.   :492.00   Max.   :3000.0   Max.   :0   Max.   :8.0000   Max.   :8810  
##  Total.pedidos.mes 
##  Length:19         
##  Class :character  
##  Mode  :character  
##                    
##                    
## 
deliveryCLIENTS = colSums(deliveryCLIENTS[2:21])
as.data.frame(deliveryCLIENTS)
##                 deliveryCLIENTS
## STB3                       5644
## STB.1                        50
## YF.RAMOS                   4009
## INOAC.POLYTEC                51
## MERIDIAN                    627
## YANFENG.sm                 1806
## YFTO                      16522
## YF.QRO                       52
## TRMX                     110127
## DENSO                     23584
## SEGROVE                     736
## HANON                       410
## ANTOLIN.TOLUCA                0
## ANTOLIN.ARTEAGA              NA
## HELLA                    285238
## UFI                         869
## ISRI                       3000
## TRMX.1                        0
## ABC.QUERETARO                 8
## VARROC                    67548
barplot.default(deliveryCLIENTS)

Técnica 1: eliminar NAs

Se decidió realizar está técnica para asegurarnos de que no se tenga falta de datos y en caso de tenerlos evitar que estas eviten tener un analisis asertivo al no agregar valor a la base de datos.

¿Cuantos NA tengo en la base de datos?

sum(is.na(delivery))
## [1] 0

¿Cuantos NA tengo por variable

Sapply: Para contar los NA. Se encontró un solo NA

sapply(delivery, function(x) sum(is.na(x)))
## ID_Fecha    Fecha  CLIENTE  Pedidos 
##        0        0        0        0

Técnica 2: eliminar filas

Se decidó realizar está técnica para eliminar los clientes que tienen menos de 5,000 pedidos.

Eliminar filas con el nombre de los clientes que se desean eliminar.

#delivery1 <- subset (delivery1,  CLIENTE == "STB3") #Para conservar ciertas filas

delivery1<-delivery

delivery1<-delivery1[delivery1$CLIENTE!="STB 1", ]
delivery1<-delivery1[delivery1$CLIENTE!="YF RAMOS", ]
delivery1<-delivery1[delivery1$CLIENTE!="INOAC POLYTEC", ]
delivery1<-delivery1[delivery1$CLIENTE!="MERIDIAN", ]
delivery1<-delivery1[delivery1$CLIENTE!="YANFENG sm", ]
delivery1<-delivery1[delivery1$CLIENTE!="YF QRO", ]
delivery1<-delivery1[delivery1$CLIENTE!="SEGROVE", ]
delivery1<-delivery1[delivery1$CLIENTE!="HANON", ]
delivery1<-delivery1[delivery1$CLIENTE!="ANTOLIN TOLUCA", ]
delivery1<-delivery1[delivery1$CLIENTE!="ANTOLIN ARTEAGA", ]
delivery1<-delivery1[delivery1$CLIENTE!="ABC QUERETARO", ]
delivery1<-delivery1[delivery1$CLIENTE!="UFI", ]
delivery1<-delivery1[delivery1$CLIENTE!="ISRI", ]

summary(delivery1)
##     ID_Fecha        Fecha             CLIENTE             Pedidos     
##  Min.   : 1.00   Length:72          Length:72          Min.   :    0  
##  1st Qu.: 3.75   Class :character   Class :character   1st Qu.:   99  
##  Median : 6.50   Mode  :character   Mode  :character   Median : 1009  
##  Mean   : 6.50                                         Mean   : 5339  
##  3rd Qu.: 9.25                                         3rd Qu.: 5928  
##  Max.   :12.00                                         Max.   :52779

Clasificación de Variables

Variable<-c("Fecha","STB3","YFTO", "TRMX", "DENSO","HELLA","VARROC","Total.pedidos.mes")
Type<-c("Cuantitativa (discreta)", "Cualitativa", "Cualitativa", "Cualitativa","Cualitativa","Cualitativa","Cualitativa","Cuantitativa (discreta)")
Measurement<-c("Razón","Nominal","Nominal","Nominal","Nominal","Nominal","Nominal","Razón")
table2<-tibble(Variable,Type,Measurement)

knitr::kable(table2)
Variable Type Measurement
Fecha Cuantitativa (discreta) Razón
STB3 Cualitativa Nominal
YFTO Cualitativa Nominal
TRMX Cualitativa Nominal
DENSO Cualitativa Nominal
HELLA Cualitativa Nominal
VARROC Cualitativa Nominal
Total.pedidos.mes Cuantitativa (discreta) Razón

1. Análisis Estadístico Delivery Plan (5)

Graphs

Gráfica cualitativa

Con esta gráfica podemos darnos cuenta de los clientes que tienen mayores pedidos y en este caso es HELLA en primer lugar y TRMX en segundo lugar, lo cual nos indica que son los mejores clientes por inyectarle más flujo de compras a la empresa.

#install.packages("plyr")

library(plyr)
## ------------------------------------------------------------------------------
## You have loaded plyr after dplyr - this is likely to cause problems.
## If you need functions from both plyr and dplyr, please load plyr first, then dplyr:
## library(plyr); library(dplyr)
## ------------------------------------------------------------------------------
## 
## Attaching package: 'plyr'
## The following object is masked from 'package:crosstable':
## 
##     compact
## The following objects are masked from 'package:Hmisc':
## 
##     is.discrete, summarize
## The following objects are masked from 'package:dplyr':
## 
##     arrange, count, desc, failwith, id, mutate, rename, summarise,
##     summarize
delivery2<-delivery1
delivery2<- aggregate(delivery2$Pedidos, by=list(category=delivery2$CLIENTE), FUN=sum)

pie(delivery2$`sum.delivery2$Pedidos`, labels = delivery2$category)

Gráfica cuantitativa

Esta gráfica sirve para tener de manera más visual el impacto que tiene cada uno de los clientes en la empresa FORM. Podemos ver que HELLA es el cliente más significativo con casi el triple de pedidos que el siguiente cliente con mayores pedidos, TRMX. De lado derecho se tiene un legend que muestra la tonalidad de los plots para ver que tantos pedidos tiene, por ello HELLAS tiene un color azul claro, representando más de 250,000 pedidos.

delivery2<-delivery2 %>% dplyr::rename(pedidos="sum.delivery2$Pedidos")
delivery2<-delivery2 %>% dplyr::rename(Clientes="category")

delivery2$Clientes<-as.factor(delivery2$Clientes)
ggplot(delivery2, aes(x=Clientes, y=pedidos, fill=pedidos))+
         geom_bar(stat="identity")+
         theme_minimal()+
         labs(title="Pedidos por cliente")

Gráfica de líneas

Comportamiento de clientes por fecha Con esta gráfica utilizamos el ID Fecha para conocer los pedidos que se tiene por cliente cada mes y vemos un significativo incremento de pedidos en el mes de septiembre y octubre. contamos con un legend que indica cada línea con un color para nombrar la información de cada uno de los clientes.

summary(delivery1)
##     ID_Fecha        Fecha             CLIENTE             Pedidos     
##  Min.   : 1.00   Length:72          Length:72          Min.   :    0  
##  1st Qu.: 3.75   Class :character   Class :character   1st Qu.:   99  
##  Median : 6.50   Mode  :character   Mode  :character   Median : 1009  
##  Mean   : 6.50                                         Mean   : 5339  
##  3rd Qu.: 9.25                                         3rd Qu.: 5928  
##  Max.   :12.00                                         Max.   :52779
ggplot(delivery1,aes(x=ID_Fecha, y=Pedidos, group=CLIENTE,colour=CLIENTE))+
  geom_line()+
  ggtitle("Comportamiento de clientes por fecha")

Boxplot

En esta gráfica podemos visualizar cuantos pedidos tiene programados cada cliente y los clientes que sobre salen son HELLA y TRMX, algo muy relevante en esta gráfica es que se muestra la moda de cada uno, así como también la minima de pedidos y la máxima, y en este caso no se tiene una dispersión por ninguno de los clientes.

boxplot(delivery1$Pedidos, main= "Pedidos")

delivery3<-delivery1
delivery3$CLIENTE <-as.factor(delivery3$CLIENTE)
ggplot(delivery3, aes(x=CLIENTE, y=Pedidos))+
  geom_boxplot(color="blue", fill="purple")

Propuestas

  1. Hacer una predicción acerca de los pedidos mensuales por cliente para ver a cuales darles prioridades y beneficios que creen una lealtad hacía FORM.

Sección 2. Análisis Exploratorio

Tabla de Mediana, Media y St. Deviation

Dentro de Delivery, podemos ver una media de más de 5,000 lo cual nos indica una muy buena cantidad en promedio mensual y la desviación estandar de 10093 lo cual nos indica una dispersión igual a la mediana dentro del rango, no es muy significativo para este caso.

median(delivery1$Pedidos, na.rm = TRUE)
## [1] 1009
mean(delivery1$Pedidos, na.rm = TRUE)
## [1] 5339.167
sd(delivery1$Pedidos, na.rm = FALSE)
## [1] 10093.19
Variable<-c("Pedidos")
Mediana<-c("1009")
Media <- c("5339.16")
Desviación_estandar<-c("10093.19")
tableplan <- tibble (Variable, Mediana , Media , Desviación_estandar)
knitr::kable(tableplan)
Variable Mediana Media Desviación_estandar
Pedidos 1009 5339.16 10093.19

Graphs

Tabla de dispersión

Dentro de esta tabla podemos visualizar la cantidad de pedidos que se manejan mensualmente no tienen una variable tan amplia, por lo cual se mantiene estable durante el 2022, lo cual nos dice de un flujo siempre mayor a 0 durante los meses.

plot(x= delivery1$ID_Fecha, y= delivery1$Pedidos, col=delivery1$ID_Fecha)

Hallazgos

Para realizar el análisis de la base de datos de “Delivery Plan” fué necesario primero hacer un arreglo de la base de datos de manera manual en el excel. Estó para simplificar el uso de la base de datos y permitir que R pueda analizarla y extraer los datos para generar gráficas. Después aplicamos dos diferentes bases de datos, nos aseguramos de que no haya NAs y eliminamos filas que correspondían a los clientes que tenían menos de 5,000 pedidos. Nos quedamos con una base de datos con los 6 clientes más significativos para FORM. Continuamos identificando las variables en dónde 6 de 8 variables eran cualitativas al ser los clientes de FORM.

Graficamos una gráfica de Pie para identificar de manera visual los mayores clientes, los que vienen siendo HELLA y TRMX. También hicimos un “Barplot” para mostrar la cantidad de pedidos programados que tiene cada cliente, Hella siendo el cliente con mayor pedidos con más de 225,000 y TRMX siguiendo con 80,000. Decidimos también visualizar el comportamiento de los clientes según la fecha y nos dimos cuenta que entre el mes de septiembre y octubre hubo un incremento de pedidos establecidos. Y por último se realizó el “Boxplot” para de ese modo ver de manera precisa la moda de clos pedidos que suele hacer cada uno de los clientes.

Delivery Performance

library(foreign)
library(dplyr)        # data manipulation 
library(forcats)      # to work with categorical variables
library(ggplot2)      # data visualization 
library(janitor)      # data exploration and cleaning 
#install.packages("Hmisc")
#library(Hmisc)        # several useful functions for data analysis 
#install.packages("psych")
#library(psych)        # functions for multivariate analysis 
#install.packages("naniar")
#library(naniar)       # summaries and visualization of missing values NAs
#install.packages("dlookr")
#library(dlookr)  # summaries and visualization of missing values NAs
#install.packages("corrplot")
#library(corrplot)     # correlation plots
#install.packages("jtools")
#library(jtools)       # presentation of regression analysis 
#install.packages("lmtest")
#library(lmtest)       # diagnostic checks - linear regression analysis 
#install.packages("car")
#library(car)          # diagnostic checks - linear regression analysis
#install.packages("olsrr")
#library(olsrr)        # diagnostic checks - linear regression analysis 
#install.packages("kableExtra")
#library(kableExtra)   # HTML table attributes
library(tidyverse)

Sección 1: Limpieza de datos, Transformación y Entendimiento

Las técnicas elegidas en nuestra limpia de datos se eligieron por las necesidades que presentaba la base y la utilidad o no que tenían nuestras variables

#file.choose()
base_de_datos<-read.csv("C:\\Users\\danyc\\OneDrive - Instituto Tecnologico y de Estudios Superiores de Monterrey\\Desktop\\Form\\Formdeliveryfinal3.csv" )

Variables y Registros

R= 8 variables y 1440 registros

Entender la BD

bd<-base_de_datos
summary(bd)
##      Target    Cliente             Vueltas      Plan.arrival   
##  Min.   :1   Length:1440        Min.   :1.00   Min.   : 0.000  
##  1st Qu.:1   Class :character   1st Qu.:1.00   1st Qu.: 0.000  
##  Median :1   Mode  :character   Median :1.50   Median : 4.000  
##  Mean   :1                      Mean   :1.75   Mean   : 6.625  
##  3rd Qu.:1                      3rd Qu.:2.25   3rd Qu.:10.750  
##  Max.   :1                      Max.   :3.00   Max.   :20.000  
##   Real.arrival    Real.departure     Diference           Fecha          
##  Min.   : 0.000   Min.   : 0.000   Min.   :-14.3500   Length:1440       
##  1st Qu.: 0.000   1st Qu.: 0.000   1st Qu.:  0.0000   Class :character  
##  Median : 0.000   Median : 0.000   Median :  0.0000   Mode  :character  
##  Mean   : 3.823   Mean   : 4.142   Mean   :  0.3155                     
##  3rd Qu.: 8.000   3rd Qu.: 9.000   3rd Qu.:  0.8000                     
##  Max.   :23.500   Max.   :24.500   Max.   : 20.0000
str(bd)
## 'data.frame':    1440 obs. of  8 variables:
##  $ Target        : int  1 1 1 1 1 1 1 1 1 1 ...
##  $ Cliente       : chr  "PRINTEL " "MAHLE" "MAHLE" "MAHLE" ...
##  $ Vueltas       : int  1 1 2 3 1 1 2 3 1 1 ...
##  $ Plan.arrival  : int  16 8 9 20 0 0 0 0 16 8 ...
##  $ Real.arrival  : num  16 8 9 20 0 0 0 0 16 8 ...
##  $ Real.departure: num  19.3 8.55 10 21 0 0 0 0 18.1 9 ...
##  $ Diference     : num  3.3 0.55 1 1 0 0 0 0 2.1 1 ...
##  $ Fecha         : chr  "2/1/2022" "2/1/2022" "2/1/2022" "2/1/2022" ...

Escalas de Variables

variables <- c("`Target`","`Cliente`","`Vueltas`","`Plan.arrival`","`Real.arrival`","`Real.departure`","`Diference`","`Fecha`")
tipos <- c("cuantitativo (discreto)  ", "cualitativo  ", "cuantitativo (discreto)  ", "cuantitativo (continuo)  ", "cuantitativo (continuo)  ", "cuantitativo (continuo)  ", "cuantitativo (continuo)  ", "cualitativo  ")
escalas <- c("intervalo", "nominal", "razon", "razon", "razon", "razon", "razon", "ordinal")
table1 <- data.frame (variables, tipos, escalas)
knitr::kable(table1)
variables tipos escalas
Target cuantitativo (discreto) intervalo
Cliente cualitativo nominal
Vueltas cuantitativo (discreto) razon
Plan.arrival cuantitativo (continuo) razon
Real.arrival cuantitativo (continuo) razon
Real.departure cuantitativo (continuo) razon
Diference cuantitativo (continuo) razon
Fecha cualitativo ordinal

CONVERSION DE CARACTER A FECHA (TECNICA DE CONVERSION DE DATOS)

bd1<-bd
bd1$Fecha<- as.Date(bd1$Fecha, format= "%d/%m/%y")
summary(bd1)
##      Target    Cliente             Vueltas      Plan.arrival   
##  Min.   :1   Length:1440        Min.   :1.00   Min.   : 0.000  
##  1st Qu.:1   Class :character   1st Qu.:1.00   1st Qu.: 0.000  
##  Median :1   Mode  :character   Median :1.50   Median : 4.000  
##  Mean   :1                      Mean   :1.75   Mean   : 6.625  
##  3rd Qu.:1                      3rd Qu.:2.25   3rd Qu.:10.750  
##  Max.   :1                      Max.   :3.00   Max.   :20.000  
##   Real.arrival    Real.departure     Diference            Fecha           
##  Min.   : 0.000   Min.   : 0.000   Min.   :-14.3500   Min.   :2020-01-02  
##  1st Qu.: 0.000   1st Qu.: 0.000   1st Qu.:  0.0000   1st Qu.:2020-05-07  
##  Median : 0.000   Median : 0.000   Median :  0.0000   Median :2022-02-13  
##  Mean   : 3.823   Mean   : 4.142   Mean   :  0.3155   Mean   :2021-06-24  
##  3rd Qu.: 8.000   3rd Qu.: 9.000   3rd Qu.:  0.8000   3rd Qu.:2022-05-02  
##  Max.   :23.500   Max.   :24.500   Max.   : 20.0000   Max.   :2022-07-23
tibble(bd1)
## # A tibble: 1,440 × 8
##    Target Cliente    Vueltas Plan.arrival Real.arri…¹ Real.…² Difer…³ Fecha     
##     <int> <chr>        <int>        <int>       <dbl>   <dbl>   <dbl> <date>    
##  1      1 "PRINTEL "       1           16          16   19.3     3.3  2020-01-02
##  2      1 "MAHLE"          1            8           8    8.55    0.55 2020-01-02
##  3      1 "MAHLE"          2            9           9   10       1    2020-01-02
##  4      1 "MAHLE"          3           20          20   21       1    2020-01-02
##  5      1 "MAGNA"          1            0           0    0       0    2020-01-02
##  6      1 "VARROC"         1            0           0    0       0    2020-01-02
##  7      1 "VARROC"         2            0           0    0       0    2020-01-02
##  8      1 "VARROC"         3            0           0    0       0    2020-01-02
##  9      1 "PRINTEL "       1           16          16   18.1     2.1  2020-01-03
## 10      1 "MAHLE"          1            8           8    9       1    2020-01-03
## # … with 1,430 more rows, and abbreviated variable names ¹​Real.arrival,
## #   ²​Real.departure, ³​Diference

Eliminar columnas

bd2<-bd1
bd2 <- subset(bd2, select =-c (Target))

Nota: Se elimina el target ya que no nos muestra una información detallada al darnos datos nulos de tener un 1 en todos lados.

LIMPIEZA POR METODO ESTADISTICO

bd3<-bd2
boxplot(bd3$Plan.arrival, horizontal=TRUE)

boxplot(bd3$Real.arrival, horizontal=TRUE)

boxplot(bd3$Real.departure, horizontal=TRUE)

boxplot(bd3$Diference, horizontal=TRUE)

Agregar columna de promedio

bd3$Promedio_real_arrival<- mean(bd3$Real.arrival)

Convertir variables de caracter a numerico.

bd3$Vueltas<-as.numeric(bd3$Vueltas)     ### missing values are converted to NA's
bd3$Plan.arrival<-as.numeric(bd3$Plan.arrival)  
bd3$Real.arrival<-as.numeric(bd3$Real.arrival)  
bd3$Real.departure<-as.numeric(bd3$Real.departure)  
bd3$Diference<-as.numeric(bd3$Diference)  
bd3$Promedio_real_arrival<-as.numeric(bd3$Promedio_real_arrival) 

bd3<-as.data.frame(bd3) 
bd3$Fecha<-as.Date(bd3$Fecha,format="%m/%d/%Y") 
bd3$Cliente<-as.factor(bd3$Cliente) 

tibble(bd3)
## # A tibble: 1,440 × 8
##    Cliente    Vueltas Plan.arrival Real.arr…¹ Real.…² Difer…³ Fecha      Prome…⁴
##    <fct>        <dbl>        <dbl>      <dbl>   <dbl>   <dbl> <date>       <dbl>
##  1 "PRINTEL "       1           16         16   19.3     3.3  2020-01-02    3.82
##  2 "MAHLE"          1            8          8    8.55    0.55 2020-01-02    3.82
##  3 "MAHLE"          2            9          9   10       1    2020-01-02    3.82
##  4 "MAHLE"          3           20         20   21       1    2020-01-02    3.82
##  5 "MAGNA"          1            0          0    0       0    2020-01-02    3.82
##  6 "VARROC"         1            0          0    0       0    2020-01-02    3.82
##  7 "VARROC"         2            0          0    0       0    2020-01-02    3.82
##  8 "VARROC"         3            0          0    0       0    2020-01-02    3.82
##  9 "PRINTEL "       1           16         16   18.1     2.1  2020-01-03    3.82
## 10 "MAHLE"          1            8          8    9       1    2020-01-03    3.82
## # … with 1,430 more rows, and abbreviated variable names ¹​Real.arrival,
## #   ²​Real.departure, ³​Diference, ⁴​Promedio_real_arrival

Notas: Se muestra que la diferencia de nuestros arrivals no es mucha, pero habría que revisar si el promedio total nos ayudaría. se agrego una columna de promedio general de nuestros arrivals reales.

bd_limpia<-bd3
write.csv(bd_limpia, file="formbaselimpia.csv", row.names = FALSE)

Sección 2: Análisis Exploratorio

bd_limpia<-read.csv("C:\\Users\\danyc\\OneDrive - Instituto Tecnologico y de Estudios Superiores de Monterrey\\Desktop\\Form\\formbaselimpia.csv")

Tabla media, mediana y std. deviation

En esta parte de desviación estandar, podemos observar que son muy pocos los clientes que tienen retrasos, pero cuando se tienen estos retrasos son de bastante tiempo por lo cual se pueden ver afectados al no estar avanzando conforme a la demanda.

bd_limpia <- bd3
summary(bd_limpia)
##      Cliente       Vueltas      Plan.arrival     Real.arrival   
##  MAGNA   :180   Min.   :1.00   Min.   : 0.000   Min.   : 0.000  
##  MAHLE   :540   1st Qu.:1.00   1st Qu.: 0.000   1st Qu.: 0.000  
##  PRINTEL :180   Median :1.50   Median : 4.000   Median : 0.000  
##  VARROC  :540   Mean   :1.75   Mean   : 6.625   Mean   : 3.823  
##                 3rd Qu.:2.25   3rd Qu.:10.750   3rd Qu.: 8.000  
##                 Max.   :3.00   Max.   :20.000   Max.   :23.500  
##  Real.departure     Diference            Fecha            Promedio_real_arrival
##  Min.   : 0.000   Min.   :-14.3500   Min.   :2020-01-02   Min.   :3.823        
##  1st Qu.: 0.000   1st Qu.:  0.0000   1st Qu.:2020-05-07   1st Qu.:3.823        
##  Median : 0.000   Median :  0.0000   Median :2022-02-13   Median :3.823        
##  Mean   : 4.142   Mean   :  0.3155   Mean   :2021-06-24   Mean   :3.823        
##  3rd Qu.: 9.000   3rd Qu.:  0.8000   3rd Qu.:2022-05-02   3rd Qu.:3.823        
##  Max.   :24.500   Max.   : 20.0000   Max.   :2022-07-23   Max.   :3.823
sd(bd_limpia$Vueltas, na.rm = FALSE)
## [1] 0.8294442
sd(bd_limpia$P.arrival, na.rm = FALSE)
## [1] NA
sd(bd_limpia$R.arrival, na.rm = FALSE)
## [1] NA
sd(bd_limpia$R.dep, na.rm = FALSE)
## [1] NA
sd(bd_limpia$Dif, na.rm = FALSE)
## [1] 0.9218758
Variable<-c("Vueltas","P.arrival", "R.arrival", "R.dep", "Dif")
Mediana<-c("1.50 ","4.000","0.000 ","0.000 ","0.0000 ")
Media <- c("1.75","6.625","3.823","4.142","4.142")
Moda <- c("1","0","0","0","0")
Desviación_estandar<-c("0.8294442"," 7.501563","6.505902","6.948665","6.948665")
table1 <- data.frame (Variable, Mediana, Media, Moda, Desviación_estandar)
knitr::kable(table1)
Variable Mediana Media Moda Desviación_estandar
Vueltas 1.50 1.75 1 0.8294442
P.arrival 4.000 6.625 0 7.501563
R.arrival 0.000 3.823 0 6.505902
R.dep 0.000 4.142 0 6.948665
Dif 0.0000 4.142 0 6.948665

Graphs

Tabla de Frecuencia

#install.packages('epiDisplay')
library(epiDisplay)
tab1(bd_limpia$Diference, sort.group = "decreasing", cum.percent = TRUE) 

## bd_limpia$Diference : 
##         Frequency Percent Cum. percent
## 0            1014    70.4         70.4
## 1             192    13.3         83.8
## 1.1            20     1.4         85.1
## 1.05           17     1.2         86.3
## 1.2            16     1.1         87.4
## 0.5            14     1.0         88.4
## 1.15           11     0.8         89.2
## 0.9             8     0.6         89.7
## 0.4             8     0.6         90.3
## 1.5             7     0.5         90.8
## 0.8             7     0.5         91.2
## 0.55            7     0.5         91.7
## 2               6     0.4         92.2
## 1.8             6     0.4         92.6
## 1.3             6     0.4         93.0
## 0.3             6     0.4         93.4
## 1.4             5     0.3         93.8
## 1.25            5     0.3         94.1
## 0.95            5     0.3         94.4
## 0.2             5     0.3         94.8
## 1.45            4     0.3         95.1
## 1.35            3     0.2         95.3
## 0.45            3     0.2         95.5
## 0.35            3     0.2         95.7
## 0.1             3     0.2         95.9
## 3.1             2     0.1         96.0
## 2.6             2     0.1         96.2
## 2.38            2     0.1         96.3
## 2.15            2     0.1         96.5
## 1.6             2     0.1         96.6
## 1.03            2     0.1         96.7
## 0.85            2     0.1         96.9
## 0.7             2     0.1         97.0
## 0.6             2     0.1         97.2
## 0.15            2     0.1         97.3
## 4.4             1     0.1         97.4
## 4               1     0.1         97.4
## 3.3             1     0.1         97.5
## 3.05            1     0.1         97.6
## 20              1     0.1         97.6
## 2.85            1     0.1         97.7
## 2.52            1     0.1         97.8
## 2.5             1     0.1         97.8
## 2.4             1     0.1         97.9
## 2.35            1     0.1         98.0
## 2.3             1     0.1         98.1
## 2.27            1     0.1         98.1
## 2.2             1     0.1         98.2
## 2.1             1     0.1         98.3
## 2.05            1     0.1         98.3
## 1.95            1     0.1         98.4
## 1.9             1     0.1         98.5
## 1.88            1     0.1         98.5
## 1.85            1     0.1         98.6
## 1.74            1     0.1         98.7
## 1.73            1     0.1         98.8
## 1.7             1     0.1         98.8
## 1.66            1     0.1         98.9
## 1.65            1     0.1         99.0
## 1.55            1     0.1         99.0
## 1.14            1     0.1         99.1
## 1.13            1     0.1         99.2
## 1.07            1     0.1         99.2
## 1.04            1     0.1         99.3
## 1.01            1     0.1         99.4
## 0.99            1     0.1         99.4
## 0.98            1     0.1         99.5
## 0.75            1     0.1         99.6
## 0.47            1     0.1         99.7
## 0.43            1     0.1         99.7
## 0.34            1     0.1         99.8
## 0.25            1     0.1         99.9
## -14.35          1     0.1         99.9
## -12.15          1     0.1        100.0
##   Total      1440   100.0        100.0
tab1(bd_limpia$Real.arrival, sort.group = "decreasing", cum.percent = TRUE)

## bd_limpia$Real.arrival : 
##         Frequency Percent Cum. percent
## 0            1009    70.1         70.1
## 8             100     6.9         77.0
## 20             83     5.8         82.8
## 9              81     5.6         88.4
## 18             11     0.8         89.2
## 9.4            10     0.7         89.9
## 15              9     0.6         90.5
## 18.2            8     0.6         91.0
## 16              7     0.5         91.5
## 9.5             6     0.4         91.9
## 9.2             6     0.4         92.4
## 9.1             6     0.4         92.8
## 10              6     0.4         93.2
## 9.15            5     0.3         93.5
## 15.1            5     0.3         93.9
## 16.2            4     0.3         94.2
## 9.3             3     0.2         94.4
## 15.2            3     0.2         94.6
## 9.45            2     0.1         94.7
## 9.26            2     0.1         94.9
## 9.12            2     0.1         95.0
## 9.08            2     0.1         95.1
## 8.1             2     0.1         95.3
## 8.05            2     0.1         95.4
## 7.35            2     0.1         95.6
## 7.3             2     0.1         95.7
## 6               2     0.1         95.8
## 23.3            2     0.1         96.0
## 20.2            2     0.1         96.1
## 20.1            2     0.1         96.2
## 19.2            2     0.1         96.4
## 18.4            2     0.1         96.5
## 18.3            2     0.1         96.7
## 16.4            2     0.1         96.8
## 15.3            2     0.1         96.9
## 13              2     0.1         97.1
## 9.35            1     0.1         97.2
## 9.25            1     0.1         97.2
## 9.17            1     0.1         97.3
## 9.11            1     0.1         97.4
## 9.05            1     0.1         97.4
## 8.52            1     0.1         97.5
## 8.45            1     0.1         97.6
## 7.45            1     0.1         97.6
## 7.34            1     0.1         97.7
## 23.5            1     0.1         97.8
## 23.2            1     0.1         97.8
## 23.15           1     0.1         97.9
## 23              1     0.1         98.0
## 22.4            1     0.1         98.1
## 22.08           1     0.1         98.1
## 21.15           1     0.1         98.2
## 21.1            1     0.1         98.3
## 21.05           1     0.1         98.3
## 20.4            1     0.1         98.4
## 20.3            1     0.1         98.5
## 20.15           1     0.1         98.5
## 20.05           1     0.1         98.6
## 19.48           1     0.1         98.7
## 19.15           1     0.1         98.8
## 19.1            1     0.1         98.8
## 18.5            1     0.1         98.9
## 18.35           1     0.1         99.0
## 18.15           1     0.1         99.0
## 18.1            1     0.1         99.1
## 18.05           1     0.1         99.2
## 17.3            1     0.1         99.2
## 17              1     0.1         99.3
## 15.45           1     0.1         99.4
## 15.4            1     0.1         99.4
## 15.16           1     0.1         99.5
## 14              1     0.1         99.6
## 13.4            1     0.1         99.7
## 11.37           1     0.1         99.7
## 11              1     0.1         99.8
## 10.42           1     0.1         99.9
## 10.4            1     0.1         99.9
## 10.05           1     0.1        100.0
##   Total      1440   100.0        100.0

Notas: Viendo el gráfico de distribución se pueden ver las frecuencias en las diferencias, se ve una mayor parte en el número 0, lo cual nos indica un buen desarrollo en delivery.

Time series plots

#Checar que la base de datos esta estructurada y un resumen de la descripción estadistica
summary(bd_limpia)
##      Cliente       Vueltas      Plan.arrival     Real.arrival   
##  MAGNA   :180   Min.   :1.00   Min.   : 0.000   Min.   : 0.000  
##  MAHLE   :540   1st Qu.:1.00   1st Qu.: 0.000   1st Qu.: 0.000  
##  PRINTEL :180   Median :1.50   Median : 4.000   Median : 0.000  
##  VARROC  :540   Mean   :1.75   Mean   : 6.625   Mean   : 3.823  
##                 3rd Qu.:2.25   3rd Qu.:10.750   3rd Qu.: 8.000  
##                 Max.   :3.00   Max.   :20.000   Max.   :23.500  
##  Real.departure     Diference            Fecha            Promedio_real_arrival
##  Min.   : 0.000   Min.   :-14.3500   Min.   :2020-01-02   Min.   :3.823        
##  1st Qu.: 0.000   1st Qu.:  0.0000   1st Qu.:2020-05-07   1st Qu.:3.823        
##  Median : 0.000   Median :  0.0000   Median :2022-02-13   Median :3.823        
##  Mean   : 4.142   Mean   :  0.3155   Mean   :2021-06-24   Mean   :3.823        
##  3rd Qu.: 9.000   3rd Qu.:  0.8000   3rd Qu.:2022-05-02   3rd Qu.:3.823        
##  Max.   :24.500   Max.   : 20.0000   Max.   :2022-07-23   Max.   :3.823
#Graficar 
ggplot(bd_limpia,aes(x=Fecha, y=Diference,color=Cliente))+
  geom_line()+
  labs(x="Fecha",y="Delay in Minutes", color="Legend")+
  ggtitle("Delays in Performance by Client")

Checar la presencia de missing values

bd_limpia1 <- bd_limpia
bd_limpia1<-bd_limpia1[-c(300,292),] # Quitar las filas 300 y 292 por que presentan datos negativos y que no sirven para el analisis.
summary(bd_limpia1) # no missing values
##      Cliente       Vueltas       Plan.arrival     Real.arrival   
##  MAGNA   :180   Min.   :1.000   Min.   : 0.000   Min.   : 0.000  
##  MAHLE   :538   1st Qu.:1.000   1st Qu.: 0.000   1st Qu.: 0.000  
##  PRINTEL :180   Median :1.000   Median : 0.000   Median : 0.000  
##  VARROC  :540   Mean   :1.748   Mean   : 6.606   Mean   : 3.796  
##                 3rd Qu.:2.000   3rd Qu.: 9.000   3rd Qu.: 8.000  
##                 Max.   :3.000   Max.   :20.000   Max.   :23.500  
##  Real.departure     Diference           Fecha            Promedio_real_arrival
##  Min.   : 0.000   Min.   : 0.0000   Min.   :2020-01-02   Min.   :3.823        
##  1st Qu.: 0.000   1st Qu.: 0.0000   1st Qu.:2020-05-06   1st Qu.:3.823        
##  Median : 0.000   Median : 0.0000   Median :2022-02-13   Median :3.823        
##  Mean   : 4.134   Mean   : 0.3344   Mean   :2021-06-23   Mean   :3.823        
##  3rd Qu.: 9.000   3rd Qu.: 0.8000   3rd Qu.:2022-05-09   3rd Qu.:3.823        
##  Max.   :24.500   Max.   :20.0000   Max.   :2022-07-23   Max.   :3.823

Quitar clientes que tengan valor de 0 en la base de datos

bd_limpia1<-bd_limpia1[bd_limpia1$Cliente!="MAGNA",]
bd_limpia1<-bd_limpia1[bd_limpia1$Cliente!="VARROC",]
summary(bd_limpia1)
##      Cliente       Vueltas       Plan.arrival    Real.arrival   
##  MAGNA   :  0   Min.   :1.000   Min.   : 8.00   Min.   : 0.000  
##  MAHLE   :538   1st Qu.:1.000   1st Qu.: 8.25   1st Qu.: 0.000  
##  PRINTEL :180   Median :1.000   Median : 9.00   Median : 8.000  
##  VARROC  :  0   Mean   :1.747   Mean   :13.23   Mean   : 7.603  
##                 3rd Qu.:2.000   3rd Qu.:16.00   3rd Qu.:10.000  
##                 Max.   :3.000   Max.   :20.00   Max.   :23.500  
##  Real.departure    Diference           Fecha            Promedio_real_arrival
##  Min.   : 0.00   Min.   : 0.0000   Min.   :2020-01-02   Min.   :3.823        
##  1st Qu.: 0.00   1st Qu.: 0.0000   1st Qu.:2020-05-06   1st Qu.:3.823        
##  Median : 9.00   Median : 0.8000   Median :2022-02-13   Median :3.823        
##  Mean   : 8.28   Mean   : 0.6697   Mean   :2021-06-23   Mean   :3.823        
##  3rd Qu.:11.50   3rd Qu.: 1.0000   3rd Qu.:2022-05-09   3rd Qu.:3.823        
##  Max.   :24.50   Max.   :20.0000   Max.   :2022-07-23   Max.   :3.823

Realizar la grafica con los 2 clientes que eliminamos

ggplot(bd_limpia1,aes(x=Fecha, y=Diference,color=Cliente))+
  geom_line()+  geom_hline(yintercept=0.8000,linetype="dashed",color="black")+
  labs(x="Fecha",y="Diferencia por día", color="Legend")+
  ggtitle("Diferencia de entrega por Cliente")

Hallazgo y propuesta

Encontramos gracias a la grafica realizada de la Diferencia de tiempo en la entrega de producto por cliente, que los clientes con mayor Delay son MAHLE Y PRINTEL, al mismo tiempo encontramos que entre estos dos clientes, el que tiene mayor Delay es MAHLE, por lo que sería bueno para la empresa el tener un mayor enfoque, obvio en ambos, pero tambien un poco más en Mahle, para que tenga mejor referencia de este cliente y mayor confianza con la empresa en las entregas.

Producción

library(foreign)
library(dplyr)        # data manipulation 
library(forcats)      # to work with categorical variables
library(ggplot2)      # data visualization 
library(janitor)      # data exploration and cleaning 
#install.packages("Hmisc")
library(Hmisc)        # several useful functions for data analysis 
#install.packages("psych")
library(psych)        # functions for multivariate analysis 
#install.packages("naniar")
library(naniar)       # summaries and visualization of missing values NAs

#install.packages("dlookr")
library(dlookr)  # summaries and visualization of missing values NAs
#install.packages("corrplot")
library(corrplot)     # correlation plots
#install.packages("jtools")
library(jtools)       # presentation of regression analysis 
#install.packages("lmtest")
library(lmtest)       # diagnostic checks - linear regression analysis 
#install.packages("car")
library(car)          # diagnostic checks - linear regression analysis
#install.packages("olsrr")
library(olsrr)        # diagnostic checks - linear regression analysis 
#install.packages("kableExtra")
library(kableExtra)   # HTML table attributes
library(tidyverse)

Sección 1. Limpieza de datos, Transformación y Entendimiento (1-4)

Importar Base de Datos

#file.choose()
produccion<-read.csv("C:\\Users\\danyc\\Downloads\\Base produccion form - Base produccion form - Base produccion form - Base produccion form.csv.csv.csv" )

Variables y Registros

R= 3988 registros y 15 variables

Entender y limpiar la base de datos

describe(produccion)
## # A tibble: 2 × 26
##   describe…¹     n    na   mean     sd se_mean   IQR skewn…² kurto…³   p00   p01
##   <chr>      <int> <int>  <dbl>  <dbl>   <dbl> <dbl>   <dbl>   <dbl> <dbl> <dbl>
## 1 Laminas.p…  3985     0 102.   134.     2.13    184    2.70    13.1     0     0
## 2 TIEMPO.MA…   496  3489   3.17   7.57   0.340     1    3.72    17.5     0     0
## # … with 15 more variables: p05 <dbl>, p10 <dbl>, p20 <dbl>, p25 <dbl>,
## #   p30 <dbl>, p40 <dbl>, p50 <dbl>, p60 <dbl>, p70 <dbl>, p75 <dbl>,
## #   p80 <dbl>, p90 <dbl>, p95 <dbl>, p99 <dbl>, p100 <dbl>, and abbreviated
## #   variable names ¹​described_variables, ²​skewness, ³​kurtosis

Paso 1. De caracter a fecha (Tecnica 4. Convertir tipos de datos)

bdp<-produccion
bdp$Fecha<- as.Date(bdp$Fecha, format= "%d/%m/%Y")
summary(bdp)
##      Fecha              CLIENTE            ID.FORM            PRODUCTO        
##  Min.   :2022-07-15   Length:3985        Length:3985        Length:3985       
##  1st Qu.:2022-08-03   Class :character   Class :character   Class :character  
##  Median :2022-08-20   Mode  :character   Mode  :character   Mode  :character  
##  Mean   :2022-08-19                                                           
##  3rd Qu.:2022-09-06                                                           
##  Max.   :2022-09-21                                                           
##                                                                               
##  PIEZAS.PROG.        TMO..MIN.           HR..FIN          ESTACION.ARRANQUE 
##  Length:3985        Length:3985        Length:3985        Length:3985       
##  Class :character   Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character   Mode  :character  
##                                                                             
##                                                                             
##                                                                             
##                                                                             
##  Laminas.procesadas INICIO.SEP.UP      FIN.INICIO.DE.SEP.UP INICIO.de.PROCESO 
##  Min.   :   0.0     Length:3985        Length:3985          Length:3985       
##  1st Qu.:   0.0     Class :character   Class :character     Class :character  
##  Median :  51.0     Mode  :character   Mode  :character     Mode  :character  
##  Mean   : 102.1                                                               
##  3rd Qu.: 184.0                                                               
##  Max.   :1263.0                                                               
##                                                                               
##  FIN.de.PROCESO     TIEMPO.CALIDAD     TIEMPO.MATERIALES
##  Length:3985        Length:3985        Min.   : 0.000   
##  Class :character   Class :character   1st Qu.: 0.000   
##  Mode  :character   Mode  :character   Median : 0.000   
##                                        Mean   : 3.169   
##                                        3rd Qu.: 1.000   
##                                        Max.   :60.000   
##                                        NA's   :3489
tibble(bdp)
## # A tibble: 3,985 × 15
##    Fecha      CLIENTE    ID.FORM PRODU…¹ PIEZA…² TMO..…³ HR..FIN ESTAC…⁴ Lamin…⁵
##    <date>     <chr>      <chr>   <chr>   <chr>   <chr>   <chr>   <chr>     <int>
##  1 2022-07-16 TRMX       00-059… "TGTX.… 1       "10"    "9:05"  C1Y2          3
##  2 2022-07-22 STABILUS 3 00-00-… "MOTOR… 1       "10"    "10:40" C1Y2          2
##  3 2022-07-28 STABILUS 3 00-00-… "MOTOR… 1       "10"    "11:20" C1Y2          2
##  4 2022-08-12 TRMX       TR-059… "TR137… 1       "10"    "9:35"  C1            1
##  5 2022-08-12 TRMX       TR-059… "TR137… 1       "10"    "9:45"  C1            1
##  6 2022-09-10 DENSO      DN-034… "MCV. … 1       "10"    "8:45"  c1y2          1
##  7 2022-07-23 DENSO      DN-034… "TOYOT… 2       ""      ""      CELDAS        0
##  8 2022-08-05 HELLA      HE-073… "SUDAF… 2       "10"    "11:20" C1Y2          3
##  9 2022-08-05 HELLA      HE-073… "SUDAF… 2       "10"    "11:30" C1Y2          0
## 10 2022-08-05 HELLA      HE-073… "SUDAF… 2       "10"    "11:40" C1Y2          0
## # … with 3,975 more rows, 6 more variables: INICIO.SEP.UP <chr>,
## #   FIN.INICIO.DE.SEP.UP <chr>, INICIO.de.PROCESO <chr>, FIN.de.PROCESO <chr>,
## #   TIEMPO.CALIDAD <chr>, TIEMPO.MATERIALES <int>, and abbreviated variable
## #   names ¹​PRODUCTO, ²​PIEZAS.PROG., ³​TMO..MIN., ⁴​ESTACION.ARRANQUE,
## #   ⁵​Laminas.procesadas

Paso 2. Eliminar columnas inservibles(Tecnica 1. Remover valores irrelevantes)

bdp1<-bdp
bdp1 <- subset(bdp1, select =-c (ID.FORM))
bdp1 <- subset(bdp1, select =-c (INICIO.SEP.UP,FIN.INICIO.DE.SEP.UP, TIEMPO.MATERIALES))
bdp1 <- subset(bdp1, select =-c (HR..FIN, INICIO.de.PROCESO, FIN.de.PROCESO))

Cambiar nombres

colnames(bdp1)<-c('fecha','cliente','producto','piezas_prog','tiempo_min','esta_arranque','laminas_procesadas','tiempo_calidad')

Paso 3. Cambiar de caracter a Numerico (Tecnica 4. Convertir tipos de datos)

bdp1$piezas_prog<-as.numeric(bdp1$piezas_prog)               
## Warning: NAs introducidos por coerción
bdp1$tiempo_min<-as.numeric(bdp1$tiempo_min)                 
## Warning: NAs introducidos por coerción
bdp1$laminas_procesadas<-as.numeric(bdp1$laminas_procesadas) 
bdp1$tiempo_calidad<-as.numeric(bdp1$tiempo_calidad)         
## Warning: NAs introducidos por coerción
bdp2<-bdp1
bdp2$tiempo_min <- substr(bdp2$tiempo_min, start = 1, stop = 2)
tibble(bdp2)  
## # A tibble: 3,985 × 8
##    fecha      cliente    producto        pieza…¹ tiemp…² esta_…³ lamin…⁴ tiemp…⁵
##    <date>     <chr>      <chr>             <dbl> <chr>   <chr>     <dbl>   <dbl>
##  1 2022-07-16 TRMX       "TGTX. CAJA RS…       1 10      C1Y2          3       1
##  2 2022-07-22 STABILUS 3 "MOTORGEAR. KI…       1 10      C1Y2          2       1
##  3 2022-07-28 STABILUS 3 "MOTORGEAR. KI…       1 10      C1Y2          2       2
##  4 2022-08-12 TRMX       "TR13773. CAJA…       1 10      C1            1       1
##  5 2022-08-12 TRMX       "TR13776. CAJA…       1 10      C1            1       1
##  6 2022-09-10 DENSO      "MCV. VALVE. P…       1 10      c1y2          1      NA
##  7 2022-07-23 DENSO      "TOYOTA. MCV. …       2 <NA>    CELDAS        0       0
##  8 2022-08-05 HELLA      "SUDAFRICA. TA…       2 10      C1Y2          3       1
##  9 2022-08-05 HELLA      "SUDAFRICA. \"…       2 10      C1Y2          0       0
## 10 2022-08-05 HELLA      "SUDAFRICA. PA…       2 10      C1Y2          0       0
## # … with 3,975 more rows, and abbreviated variable names ¹​piezas_prog,
## #   ²​tiempo_min, ³​esta_arranque, ⁴​laminas_procesadas, ⁵​tiempo_calidad
bdp2$tiempo_min <- as.integer(bdp2$tiempo_min)
str(bdp2)  
## 'data.frame':    3985 obs. of  8 variables:
##  $ fecha             : Date, format: "2022-07-16" "2022-07-22" ...
##  $ cliente           : chr  "TRMX" "STABILUS 3" "STABILUS 3" "TRMX" ...
##  $ producto          : chr  "TGTX. CAJA RSC. ( 1 Pieza) con SOBRE. Kit: TR-059-19014" "MOTORGEAR. KIT. TAPA GRAL. Grapada. 1 Pza/ Kit. ( Kit 19211)" "MOTORGEAR. KIT. TAPA GRAL. Grapada. 1 Pza/ Kit. ( Kit 19211)" "TR13773. CAJA RSC Imp. Negra con SOBRE ( 2 Partes). PC0048." ...
##  $ piezas_prog       : num  1 1 1 1 1 1 2 2 2 2 ...
##  $ tiempo_min        : int  10 10 10 10 10 10 NA 10 10 10 ...
##  $ esta_arranque     : chr  "C1Y2" "C1Y2" "C1Y2" "C1" ...
##  $ laminas_procesadas: num  3 2 2 1 1 1 0 3 0 0 ...
##  $ tiempo_calidad    : num  1 1 2 1 1 NA 0 1 0 0 ...
bdp2$piezas_prog <- substr(bdp2$piezas_prog, start = 1, stop = 2)
tibble(bdp2)  
## # A tibble: 3,985 × 8
##    fecha      cliente    producto        pieza…¹ tiemp…² esta_…³ lamin…⁴ tiemp…⁵
##    <date>     <chr>      <chr>           <chr>     <int> <chr>     <dbl>   <dbl>
##  1 2022-07-16 TRMX       "TGTX. CAJA RS… 1            10 C1Y2          3       1
##  2 2022-07-22 STABILUS 3 "MOTORGEAR. KI… 1            10 C1Y2          2       1
##  3 2022-07-28 STABILUS 3 "MOTORGEAR. KI… 1            10 C1Y2          2       2
##  4 2022-08-12 TRMX       "TR13773. CAJA… 1            10 C1            1       1
##  5 2022-08-12 TRMX       "TR13776. CAJA… 1            10 C1            1       1
##  6 2022-09-10 DENSO      "MCV. VALVE. P… 1            10 c1y2          1      NA
##  7 2022-07-23 DENSO      "TOYOTA. MCV. … 2            NA CELDAS        0       0
##  8 2022-08-05 HELLA      "SUDAFRICA. TA… 2            10 C1Y2          3       1
##  9 2022-08-05 HELLA      "SUDAFRICA. \"… 2            10 C1Y2          0       0
## 10 2022-08-05 HELLA      "SUDAFRICA. PA… 2            10 C1Y2          0       0
## # … with 3,975 more rows, and abbreviated variable names ¹​piezas_prog,
## #   ²​tiempo_min, ³​esta_arranque, ⁴​laminas_procesadas, ⁵​tiempo_calidad
bdp2$piezas_prog <- as.integer(bdp2$piezas_prog)
str(bdp2)
## 'data.frame':    3985 obs. of  8 variables:
##  $ fecha             : Date, format: "2022-07-16" "2022-07-22" ...
##  $ cliente           : chr  "TRMX" "STABILUS 3" "STABILUS 3" "TRMX" ...
##  $ producto          : chr  "TGTX. CAJA RSC. ( 1 Pieza) con SOBRE. Kit: TR-059-19014" "MOTORGEAR. KIT. TAPA GRAL. Grapada. 1 Pza/ Kit. ( Kit 19211)" "MOTORGEAR. KIT. TAPA GRAL. Grapada. 1 Pza/ Kit. ( Kit 19211)" "TR13773. CAJA RSC Imp. Negra con SOBRE ( 2 Partes). PC0048." ...
##  $ piezas_prog       : int  1 1 1 1 1 1 2 2 2 2 ...
##  $ tiempo_min        : int  10 10 10 10 10 10 NA 10 10 10 ...
##  $ esta_arranque     : chr  "C1Y2" "C1Y2" "C1Y2" "C1" ...
##  $ laminas_procesadas: num  3 2 2 1 1 1 0 3 0 0 ...
##  $ tiempo_calidad    : num  1 1 2 1 1 NA 0 1 0 0 ...
bdp2$laminas_procesadas <- substr(bdp2$laminas_procesadas, start = 1, stop = 2)
tibble(bdp2)  
## # A tibble: 3,985 × 8
##    fecha      cliente    producto        pieza…¹ tiemp…² esta_…³ lamin…⁴ tiemp…⁵
##    <date>     <chr>      <chr>             <int>   <int> <chr>   <chr>     <dbl>
##  1 2022-07-16 TRMX       "TGTX. CAJA RS…       1      10 C1Y2    3             1
##  2 2022-07-22 STABILUS 3 "MOTORGEAR. KI…       1      10 C1Y2    2             1
##  3 2022-07-28 STABILUS 3 "MOTORGEAR. KI…       1      10 C1Y2    2             2
##  4 2022-08-12 TRMX       "TR13773. CAJA…       1      10 C1      1             1
##  5 2022-08-12 TRMX       "TR13776. CAJA…       1      10 C1      1             1
##  6 2022-09-10 DENSO      "MCV. VALVE. P…       1      10 c1y2    1            NA
##  7 2022-07-23 DENSO      "TOYOTA. MCV. …       2      NA CELDAS  0             0
##  8 2022-08-05 HELLA      "SUDAFRICA. TA…       2      10 C1Y2    3             1
##  9 2022-08-05 HELLA      "SUDAFRICA. \"…       2      10 C1Y2    0             0
## 10 2022-08-05 HELLA      "SUDAFRICA. PA…       2      10 C1Y2    0             0
## # … with 3,975 more rows, and abbreviated variable names ¹​piezas_prog,
## #   ²​tiempo_min, ³​esta_arranque, ⁴​laminas_procesadas, ⁵​tiempo_calidad
bdp2$laminas_procesadas <- as.integer(bdp2$laminas_procesadas)
str(bdp2) 
## 'data.frame':    3985 obs. of  8 variables:
##  $ fecha             : Date, format: "2022-07-16" "2022-07-22" ...
##  $ cliente           : chr  "TRMX" "STABILUS 3" "STABILUS 3" "TRMX" ...
##  $ producto          : chr  "TGTX. CAJA RSC. ( 1 Pieza) con SOBRE. Kit: TR-059-19014" "MOTORGEAR. KIT. TAPA GRAL. Grapada. 1 Pza/ Kit. ( Kit 19211)" "MOTORGEAR. KIT. TAPA GRAL. Grapada. 1 Pza/ Kit. ( Kit 19211)" "TR13773. CAJA RSC Imp. Negra con SOBRE ( 2 Partes). PC0048." ...
##  $ piezas_prog       : int  1 1 1 1 1 1 2 2 2 2 ...
##  $ tiempo_min        : int  10 10 10 10 10 10 NA 10 10 10 ...
##  $ esta_arranque     : chr  "C1Y2" "C1Y2" "C1Y2" "C1" ...
##  $ laminas_procesadas: int  3 2 2 1 1 1 0 3 0 0 ...
##  $ tiempo_calidad    : num  1 1 2 1 1 NA 0 1 0 0 ...

Paso 4. Cambiar de N/A a promedios

bdp3 <- bdp2
bdp3$tiempo_min[is.na(bdp3$tiempo_min)]<-mean(bdp3$tiempo_min, na.rm = TRUE)
summary (bdp3) 
##      fecha              cliente            producto          piezas_prog  
##  Min.   :2022-07-15   Length:3985        Length:3985        Min.   : 1.0  
##  1st Qu.:2022-08-03   Class :character   Class :character   1st Qu.:12.0  
##  Median :2022-08-20   Mode  :character   Mode  :character   Median :20.0  
##  Mean   :2022-08-19                                         Mean   :27.2  
##  3rd Qu.:2022-09-06                                         3rd Qu.:40.0  
##  Max.   :2022-09-21                                         Max.   :99.0  
##                                                             NA's   :179   
##    tiempo_min    esta_arranque      laminas_procesadas tiempo_calidad   
##  Min.   : 0.00   Length:3985        Min.   : 0.00      Min.   : 0.0000  
##  1st Qu.:15.00   Class :character   1st Qu.: 0.00      1st Qu.: 0.0000  
##  Median :22.13   Mode  :character   Median :19.00      Median : 1.0000  
##  Mean   :22.13                      Mean   :21.42      Mean   : 0.8628  
##  3rd Qu.:25.00                      3rd Qu.:32.00      3rd Qu.: 1.0000  
##  Max.   :90.00                      Max.   :98.00      Max.   :22.0000  
##                                                        NA's   :343

Paso 5. Cambiar de N/A a 0

bdp4 <- bdp3
bdp4$laminas_procesadas[bdp4$laminas_procesadas < 1]<- NA
summary (bdp4)
##      fecha              cliente            producto          piezas_prog  
##  Min.   :2022-07-15   Length:3985        Length:3985        Min.   : 1.0  
##  1st Qu.:2022-08-03   Class :character   Class :character   1st Qu.:12.0  
##  Median :2022-08-20   Mode  :character   Mode  :character   Median :20.0  
##  Mean   :2022-08-19                                         Mean   :27.2  
##  3rd Qu.:2022-09-06                                         3rd Qu.:40.0  
##  Max.   :2022-09-21                                         Max.   :99.0  
##                                                             NA's   :179   
##    tiempo_min    esta_arranque      laminas_procesadas tiempo_calidad   
##  Min.   : 0.00   Length:3985        Min.   : 1.00      Min.   : 0.0000  
##  1st Qu.:15.00   Class :character   1st Qu.:15.00      1st Qu.: 0.0000  
##  Median :22.13   Mode  :character   Median :21.00      Median : 1.0000  
##  Mean   :22.13                      Mean   :30.08      Mean   : 0.8628  
##  3rd Qu.:25.00                      3rd Qu.:41.00      3rd Qu.: 1.0000  
##  Max.   :90.00                      Max.   :98.00      Max.   :22.0000  
##                                     NA's   :1148       NA's   :343

Paso 6. Borra N/As

bdp5 <- bdp4
bdp5 <- na.omit(bdp5)    
str(bdp5)
## 'data.frame':    2679 obs. of  8 variables:
##  $ fecha             : Date, format: "2022-07-16" "2022-07-22" ...
##  $ cliente           : chr  "TRMX" "STABILUS 3" "STABILUS 3" "TRMX" ...
##  $ producto          : chr  "TGTX. CAJA RSC. ( 1 Pieza) con SOBRE. Kit: TR-059-19014" "MOTORGEAR. KIT. TAPA GRAL. Grapada. 1 Pza/ Kit. ( Kit 19211)" "MOTORGEAR. KIT. TAPA GRAL. Grapada. 1 Pza/ Kit. ( Kit 19211)" "TR13773. CAJA RSC Imp. Negra con SOBRE ( 2 Partes). PC0048." ...
##  $ piezas_prog       : int  1 1 1 1 1 2 3 3 4 4 ...
##  $ tiempo_min        : num  10 10 10 10 10 10 10 10 10 10 ...
##  $ esta_arranque     : chr  "C1Y2" "C1Y2" "C1Y2" "C1" ...
##  $ laminas_procesadas: int  3 2 2 1 1 3 2 5 5 10 ...
##  $ tiempo_calidad    : num  1 1 2 1 1 1 0 1 1 1 ...
##  - attr(*, "na.action")= 'omit' Named int [1:1306] 6 7 9 10 18 22 25 27 28 30 ...
##   ..- attr(*, "names")= chr [1:1306] "6" "7" "9" "10" ...

Verificar eliminacion de NA´s

colSums(is.na(bdp5))
##              fecha            cliente           producto        piezas_prog 
##                  0                  0                  0                  0 
##         tiempo_min      esta_arranque laminas_procesadas     tiempo_calidad 
##                  0                  0                  0                  0
summary(bdp5)
##      fecha              cliente            producto          piezas_prog   
##  Min.   :2022-07-15   Length:2679        Length:2679        Min.   : 1.00  
##  1st Qu.:2022-08-02   Class :character   Class :character   1st Qu.:13.00  
##  Median :2022-08-18   Mode  :character   Mode  :character   Median :20.00  
##  Mean   :2022-08-18                                         Mean   :26.53  
##  3rd Qu.:2022-09-02                                         3rd Qu.:32.50  
##  Max.   :2022-09-21                                         Max.   :99.00  
##    tiempo_min    esta_arranque      laminas_procesadas tiempo_calidad 
##  Min.   : 0.00   Length:2679        Min.   : 1.00      Min.   : 0.00  
##  1st Qu.:15.00   Class :character   1st Qu.:16.00      1st Qu.: 1.00  
##  Median :20.00   Mode  :character   Median :21.00      Median : 1.00  
##  Mean   :22.16                      Mean   :30.18      Mean   : 1.16  
##  3rd Qu.:25.00                      3rd Qu.:41.00      3rd Qu.: 1.00  
##  Max.   :90.00                      Max.   :98.00      Max.   :22.00
str(bdp5)
## 'data.frame':    2679 obs. of  8 variables:
##  $ fecha             : Date, format: "2022-07-16" "2022-07-22" ...
##  $ cliente           : chr  "TRMX" "STABILUS 3" "STABILUS 3" "TRMX" ...
##  $ producto          : chr  "TGTX. CAJA RSC. ( 1 Pieza) con SOBRE. Kit: TR-059-19014" "MOTORGEAR. KIT. TAPA GRAL. Grapada. 1 Pza/ Kit. ( Kit 19211)" "MOTORGEAR. KIT. TAPA GRAL. Grapada. 1 Pza/ Kit. ( Kit 19211)" "TR13773. CAJA RSC Imp. Negra con SOBRE ( 2 Partes). PC0048." ...
##  $ piezas_prog       : int  1 1 1 1 1 2 3 3 4 4 ...
##  $ tiempo_min        : num  10 10 10 10 10 10 10 10 10 10 ...
##  $ esta_arranque     : chr  "C1Y2" "C1Y2" "C1Y2" "C1" ...
##  $ laminas_procesadas: int  3 2 2 1 1 3 2 5 5 10 ...
##  $ tiempo_calidad    : num  1 1 2 1 1 1 0 1 1 1 ...
##  - attr(*, "na.action")= 'omit' Named int [1:1306] 6 7 9 10 18 22 25 27 28 30 ...
##   ..- attr(*, "names")= chr [1:1306] "6" "7" "9" "10" ...
summary(bdp5)
##      fecha              cliente            producto          piezas_prog   
##  Min.   :2022-07-15   Length:2679        Length:2679        Min.   : 1.00  
##  1st Qu.:2022-08-02   Class :character   Class :character   1st Qu.:13.00  
##  Median :2022-08-18   Mode  :character   Mode  :character   Median :20.00  
##  Mean   :2022-08-18                                         Mean   :26.53  
##  3rd Qu.:2022-09-02                                         3rd Qu.:32.50  
##  Max.   :2022-09-21                                         Max.   :99.00  
##    tiempo_min    esta_arranque      laminas_procesadas tiempo_calidad 
##  Min.   : 0.00   Length:2679        Min.   : 1.00      Min.   : 0.00  
##  1st Qu.:15.00   Class :character   1st Qu.:16.00      1st Qu.: 1.00  
##  Median :20.00   Mode  :character   Median :21.00      Median : 1.00  
##  Mean   :22.16                      Mean   :30.18      Mean   : 1.16  
##  3rd Qu.:25.00                      3rd Qu.:41.00      3rd Qu.: 1.00  
##  Max.   :90.00                      Max.   :98.00      Max.   :22.00

Clasificación de Variables

Variable<-c("Fecha ","cliente","producto", "Piezas programadas","tiempo min","Estacion de arranque","Laminas procesadas", "Tiempo de calidad")
Type<-c("Cualitativa","Cualitativa","Cualitativa", "Cuantitativa(Discreta)", "Cuantitativa(Discreta)","Cualitativa", "Cuantitativa(Discreta)", "Cuantitativa discreta")
Medicion <-c("Nominal", "Nominal","Nominal", "Intervalo", "Intervalo","Nominal", "Intervalo", "Intervalo") 
table<-data.frame(Variable,Type, Medicion)
knitr::kable(table)
Variable Type Medicion
Fecha Cualitativa Nominal
cliente Cualitativa Nominal
producto Cualitativa Nominal
Piezas programadas Cuantitativa(Discreta) Intervalo
tiempo min Cuantitativa(Discreta) Intervalo
Estacion de arranque Cualitativa Nominal
Laminas procesadas Cuantitativa(Discreta) Intervalo
Tiempo de calidad Cuantitativa discreta Intervalo

Exportar csv

write.csv(bdp5,"C:\\Users\\danyc\\OneDrive - Instituto Tecnologico y de Estudios Superiores de Monterrey\\Desktop\\Form_produccionbaselimpia.csv", row.names=FALSE)

Importar base de datos limpia

bdl<-read.csv("C:\\Users\\danyc\\OneDrive - Instituto Tecnologico y de Estudios Superiores de Monterrey\\Desktop\\Form_produccionbaselimpia.csv")
library(ggplot2)
#install.packages("webr")
library(webr)
library(dplyr)

1. Análisis Estadístico PRODUCCIÓN (5)

Gráficos

Cualitativo

Dentro de este gráfico se vio que el cliente que tuvo más piezas programadas fue Stabilus en el mes de Agosto, esto debido a que la mayor parte de las ventas fue llevado a cabo durante este mes segun podemos ver la tabla descriptiva.

detach(package:plyr)
PD = bdp5 %>% dplyr::group_by(month=lubridate:: floor_date(fecha, "month" ), cliente) %>% summarise(n = sum(piezas_prog))
## `summarise()` has grouped output by 'month'. You can override using the
## `.groups` argument.
print(PD)
## # A tibble: 28 × 3
## # Groups:   month [3]
##    month      cliente                  n
##    <date>     <chr>                <int>
##  1 2022-07-01 DENSO                 3849
##  2 2022-07-01 HANON SYSTEMS           48
##  3 2022-07-01 HELLA                  147
##  4 2022-07-01 MERIDIAN LIGHTWEIGHT   398
##  5 2022-07-01 STABILUS 1            4860
##  6 2022-07-01 STABILUS 3            2290
##  7 2022-07-01 TRMX                  2288
##  8 2022-07-01 VARROC                1496
##  9 2022-07-01 VL-017-13939            78
## 10 2022-07-01 VL-017-14086            98
## # … with 18 more rows
PieDonut(PD, aes(month, cliente, count=n), title = "Piezas por cliente")
## Warning: `guides(<scale> = FALSE)` is deprecated. Please use `guides(<scale> = "none")` instead.
## `guides(<scale> = FALSE)` is deprecated. Please use `guides(<scale> = "none")` instead.

Cuantitativo

En este histograma, podemos ver que la información de las laminas procesadas se encuentra en un 10-20 por lo que se nota en el gráfico como mayor parte, aquí nos podemos dar cuenta que este numero de láminas es el que con más frecuencia se produce.

produccion1 <- (bdp5$laminas_procesadas)
hist(produccion1)

Propuestas

  1. Ver un modelo predictivo para aumentar el numero de ventas lo cual nos daría un incremento en la producción. 2.Fomentar la lealtad en los compradores dandoles ventajas competitivas ante el mercado para evitar dejar de producir los numeros con más frecuencia lo cual provocaría un desbalance en nuestros numeros.

Sección 2. Análisis Exploratorio

Tabla de media, mediana y Std. Deviation

Creo que para este caso dentro de la producci’on se ve que tiene una desviacion dentro del rango ya que se muestra una disperción de 18.7 entre punto y punto que es menos que la media.

bd6<-bdl
median(bd6$piezas_prog, na.rm = TRUE)
## [1] 20
mean(bd6$piezas_prog, na.rm = TRUE)
## [1] 26.52781
sd(bd6$piezas_prog, na.rm = FALSE)
## [1] 18.71565
Variable<-c("Piezas")
Mediana<-c("20")
Media <- c("26.5")
Desviación_estandar<-c("18.7")
tablebaja <- tibble (Variable, Mediana , Media , Desviación_estandar)
knitr::kable(tablebaja)
Variable Mediana Media Desviación_estandar
Piezas 20 26.5 18.7

Graphs

Barplots

Recopilando la informacion me tope con estos datos lo cual nos informa acerca de los clientes mas destacados para form y el tiempo minimo de tardanza en el ensamblaje de los productos, en este caso el primer lugar con mas eficiencia por cliente fue stabilus en la primera vuelta.

bd6<-bd6 %>% group_by(cliente) %>% 
  summarise(piezas_prog=sum(piezas_prog),tiempo_min=sum(tiempo_min)) %>% arrange(desc(piezas_prog))

bd6<-bd6[-c(6,7,8,9,10,11),] 


ggplot(bd6,aes(x=reorder(tiempo_min,piezas_prog), y=piezas_prog,fill=cliente)) +
  geom_bar(stat="identity")

Barplots2

Dentro de esta segunda tabla de barras se puede ver desplegado la cantidad de piezas programadas que se tuvo por mes en los periodos de los meses julio, agosto y septiembre. Esto nos dice acerca de la mayor productividad de agosto, pero porque es esto?

datoscopia<-bdl
datoscopia$ano<-strftime(datoscopia$fecha, "%Y")
datoscopia$mes<-strftime(datoscopia$fecha, "%m")

data_agg<- aggregate(piezas_prog~mes + ano, datoscopia, FUN = sum)
data_agglamina<- aggregate(laminas_procesadas~mes + ano, datoscopia, FUN = sum)
ggplot(data_agg,aes(x=mes,y=piezas_prog)) +
  geom_bar(stat="identity")

Barplots 3

En esta grafica se puede visualizar la dependencia del tiempo minimo de produccion con las piezas programadas dependiendo de la estacion de arranque, la mayor productividad general tiene unarelacion con la estacion C1 y la C1y2 ya que se ve que es la que menos tiempo hace con mas procesamiento de laminas.

ggplot(datoscopia,aes(x=tiempo_min, y=piezas_prog,fill=esta_arranque)) +
  geom_bar(stat="identity")

Dispersion 1

En esta tabla se muestra un claro ejemplo de comparacion que entre mas tiempo de calidad se le de al cliente se lograra hacer un tiempo mucho mas minimo efectivizando los procesos y terminandolos mas rapido como fue con los clientes en azul.

ggplot(datoscopia, aes(x=tiempo_calidad, y=tiempo_min, color=cliente)) +
  geom_point() + geom_rug()

Dispersion 2

En esta grafica, se iene la intencion de ver a los compradores predominantes dentro de FORM durante los tres meses predictivos, esto para poder lograr una atencion especializada y ver mas o menos el tiempo que toman sus productos y generar un tipo de procesos mas fluido.

ggplot(datoscopia, aes(x=cliente, y=laminas_procesadas, color=mes)) +
  geom_point() + geom_rug()

Series de tiempo

Aqui se puede ver una serie de tiempo no lineal, lo cual nos dice que no se tienen procesos claros y estables para la produccion lo cual lo convierte en un proceso variable y con fallas en los tiempos de entregas como resultado.

ggplot(datoscopia,aes(x=tiempo_calidad))+
  geom_line(aes(y=piezas_prog),color="orange")+
  labs(x="Tiempo de Calidad",y="piezas programadas", color="orange")+
  ggtitle("Grafica de tasa de rendimiento")

Hallazgos

  1. Depende del posicionamiento inicial de la materia prima el tiempo en el que se producen las laminas.
  2. Hay clientes que compran más que otros y es por eso que la producción por falta de transporte tiene que dar dos vueltas haciendo mayor el tiempo de entrega.
  3. Hay retrasos no claros para algúnos clientes por lo cual debemos preguntar a Felipe acerca de estas.

Merma

#file.choose()
FORM <- read.csv("C:\\Users\\danyc\\Downloads\\FORM - Merma limpia.csv")

Sección 1. Limpieza de datos, Transformación y Entendimiento (1-4)

Entender Base de Datos

resumen <- summary(FORM)
resumen
##     Fecha               Kilos      
##  Length:42          Min.   : 1040  
##  Class :character   1st Qu.: 3682  
##  Mode  :character   Median : 4025  
##                     Mean   : 4415  
##                     3rd Qu.: 4325  
##                     Max.   :18900

Variables y registros de la base de datos

R= 52 registros y 2 variables
str(FORM)
## 'data.frame':    42 obs. of  2 variables:
##  $ Fecha: chr  "11/01/22" "22/01/22" "18/02/22" "24/02/22" ...
##  $ Kilos: num  8890 5670 18900 3930 4000 4190 2980 3290 4200 3810 ...
library(psych)
library(plyr)
## ------------------------------------------------------------------------------
## You have loaded plyr after dplyr - this is likely to cause problems.
## If you need functions from both plyr and dplyr, please load plyr first, then dplyr:
## library(plyr); library(dplyr)
## ------------------------------------------------------------------------------
## 
## Attaching package: 'plyr'
## The following object is masked from 'package:purrr':
## 
##     compact
## The following object is masked from 'package:crosstable':
## 
##     compact
## The following objects are masked from 'package:Hmisc':
## 
##     is.discrete, summarize
## The following objects are masked from 'package:dplyr':
## 
##     arrange, count, desc, failwith, id, mutate, rename, summarise,
##     summarize
#install.packages("psych")
describe(FORM)
## # A tibble: 1 × 26
##   described_…¹     n    na  mean    sd se_mean   IQR skewn…² kurto…³   p00   p01
##   <chr>        <int> <int> <dbl> <dbl>   <dbl> <dbl>   <dbl>   <dbl> <dbl> <dbl>
## 1 Kilos           42     0 4415. 2572.    397.  642.    4.61    25.6  1040 1487.
## # … with 15 more variables: p05 <dbl>, p10 <dbl>, p20 <dbl>, p25 <dbl>,
## #   p30 <dbl>, p40 <dbl>, p50 <dbl>, p60 <dbl>, p70 <dbl>, p75 <dbl>,
## #   p80 <dbl>, p90 <dbl>, p95 <dbl>, p99 <dbl>, p100 <dbl>, and abbreviated
## #   variable names ¹​described_variables, ²​skewness, ³​kurtosis

Nota:En esta base de datos se eliminaron la columa que no era relevante para el analisis, Se eliminaron los registros de total de merma y la columna de mes ya que no eran irrelevantes. Por lo tanto nos quedamos con 52 registros y 2 variables.

2.Para el caso de variables cuantitativas considerar la posibilidad de reemplazar la presencia de “missing values” con estadísticos descriptivos (por ejemplo, media, mediana, moda).

Eliminar N/A´s

Remplazar valores faltantes por la mediana: No se pueden cambiar debido a que los NA´S de la base de datos no tienen información por lo tanto se van a eliminar.

FORM_1<-FORM
FORM_1<- na.omit(FORM_1)
summary(FORM_1)
##     Fecha               Kilos      
##  Length:42          Min.   : 1040  
##  Class :character   1st Qu.: 3682  
##  Mode  :character   Median : 4025  
##                     Mean   : 4415  
##                     3rd Qu.: 4325  
##                     Max.   :18900
#summary(FORM) 
#str(FORM)
#FORM$Kilos<-as.numeric(FORM$Kilos)
#FORM<-FORM %>% mutate(Kilos=if_else(is.na(Kilos),median(Kilos,na.rm = T),Kilos))

Nota:En esta base de datos la unica variable que se puede remplazar por la mediana es la columna de kilos. Ya se remplazaron los valores faltantes por la mediana.

Cambiar nombres de columnas y variables

Respecto a variables cualitativas (por ejemplo, género, cliente,municipio, estado) homogenizar el nombre de las diferentes categorías.

Respecto a La base de datos analizada no aplica el paso de homogenizar las variables ya que en este caso solo se cuenta con dos variables en la base de datos.

#seleccionar columnas / variables.
#FORM<-FORM %>% select(-one_of('Fecha','Kilos'))

#Renombrar las columnas /variables seleccionadas. 
colnames(FORM_1) <-c ('Fecha','Kilo')
Variable<-c("`Fecha`", "` Kilos`")
Type<-c("Cuantitativa (continua)", "Cuantitativa (discreta)")
Measurement<-c("Razón","Razón")
table_Merma<-data.frame(Variable,Type,Measurement)

knitr::kable(table_Merma)
Variable Type Measurement
Fecha Cuantitativa (continua) Razón
Kilos Cuantitativa (discreta) Razón

1. Análisis Estadístico Merma (5)

Gráfico cuantitativo

Se puede notar en este gráfico de barras como dentro de los tres trimestres el segundo y tercero fueron los más estables por así decirlo, no hubo cantidades máximas preocupantes o excelentes minimas.

FORM_1$Fecha<-as.Date(FORM$Fecha,format="%d/%m/%y")
#install.packages("ggplot")
library(ggplot2)
ggplot(FORM_1, aes(x=Fecha, y=Kilo)) +
  geom_bar(stat="identity", color="blue", fill="white")

Propuestas

Se recomienda el dibujar probablemente con el proveedor de materia prima una figura para optimizar las materias o bien, utilizar maquinas precisas de laser para evitar cortes que desperdicien los materiales.

Sección 2. Análisis Exploratorio

Tabla de Media, Mediana, Moda y Desviación Estandard

Dentro de la tabla de análisis de variable se puede ver que el numero promedio es de 4,415 de merma, este es un numero alto dentro del rango ya que hablando de kilogramos el tener una media de 4 toneladas puede significar un alto desperdicio de carton y por ende de dinero.

median(FORM_1$Kilo, na.rm = TRUE)
## [1] 4025
mean(FORM_1$Kilo, na.rm = TRUE)
## [1] 4414.905
sd(FORM_1$Kilo, na.rm = FALSE)
## [1] 2571.793
#mfv(FORM_1$Kilo)

Variable<-c("Kilo")
Mediana<-c("4025")
Media <- c("4415")
Moda <- c("4190")
Desviación_estandar<-c("2571.793")
tablemerma <- data.frame (Variable, Mediana , Media , Moda , Desviación_estandar)
knitr::kable(tablemerma)
Variable Mediana Media Moda Desviación_estandar
Kilo 4025 4415 4190 2571.793

Time Serie Plots

Dentro de la gráfica mostrada, se puede observar una alza en los kilos de merma que se vieron en el primer trimestre del año, esta cantidad despues fue decrementando con el paso de los meses, esto nos puede indicar dos cosas, un incremento en producción o bien, un mal manejo de la materia prima.

#FORM_1$Fecha<-as.Date(FORM$Fecha,format="%d/%m/%y")

#install.packages("ggplot2")
library(ggplot2)
summary(FORM_1)
##      Fecha                 Kilo      
##  Min.   :2022-01-11   Min.   : 1040  
##  1st Qu.:2022-04-05   1st Qu.: 3682  
##  Median :2022-06-11   Median : 4025  
##  Mean   :2022-06-04   Mean   : 4415  
##  3rd Qu.:2022-08-10   3rd Qu.: 4325  
##  Max.   :2022-09-21   Max.   :18900
ggplot(FORM_1,aes(x=Fecha))+
  geom_line(aes(y=Kilo),color="blue")+
  labs(x="Fecha",y="Kilo", color="Legend")+
   ggtitle("Kilos de merma por mes")

Hallazgos

Las toneladas de merma, no representan todas las veces un coto para FORM ya que platicando con Felipe, estas son mayormente por causa del proveedor pero no representan un costo extra por lo cual se regala, lo interesante aquí sería encontrar al proveedor que más errores tiene y ver en el supply chain maneras de reutilizar esta merma.

Scrap

#file.choose()
SCRAP<- read.csv("C:\\Users\\danyc\\Downloads\\FORM - Scrap Limpia .csv")

Sección 1. Limpieza de datos, Transformación y Entendimiento (1-4)

Describe brevemente ¿porqué aplicaste dichas técnicas? ¿cómo te permitió la aplicación de dichas técnicas una mejor comprensión de las bases de datos?

Las técnicas de limpieza que se aplicaron para SCRAP fueron específicamente para dejar los datos con los que ibamos a trabajar en las gráficas, es decir, se dejaron los datos de importancia, de igual manera hubo eliminaciones de N/A´s y finalmente la corrección de nombres de nuestras variables.

La aplicación de dichas fechas me ayudó a ver más claro cuales eran los datos que quería para lograr hacer las gráficas.

Entender Base de Datos

Esto nos ayuda a saber que tipo de variable estamos viendo y ver si hay datos anormales.

resumen <- summary(SCRAP)
resumen
##   Referencia           Fecha               Hora             Producto        
##  Length:250         Length:250         Length:250         Length:250        
##  Class :character   Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character   Mode  :character  
##                                                                             
##                                                                             
##                                                                             
##     Cantidad      Unidad.de.medida   Ubicación.de.origen Ubicación.de.desecho
##  Min.   : 0.000   Length:250         Length:250          Length:250          
##  1st Qu.: 1.000   Class :character   Class :character    Class :character    
##  Median : 2.000   Mode  :character   Mode  :character    Mode  :character    
##  Mean   : 6.696                                                              
##  3rd Qu.: 7.000                                                              
##  Max.   :96.000                                                              
##     Estado         
##  Length:250        
##  Class :character  
##  Mode  :character  
##                    
##                    
## 

Variables y Registros

R= 250 registros y 9 variables
str(SCRAP)
## 'data.frame':    250 obs. of  9 variables:
##  $ Referencia          : chr  "SP/08731" "SP/08730" "SP/08729" "SP/08728" ...
##  $ Fecha               : chr  "31/08/2022" "31/08/2022" "31/08/2022" "31/08/2022" ...
##  $ 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" ...
#library(psych)
#install.packages("psych")

Eliminación de columnas

Nos quedamos con 5 variables y 250 observaciones.

Se seleccionaron las columnas de Referencia, unidades, ubicación y estado debido a que eran variables que no vamos a utilizar en nuestro análisis.

scrap2<- SCRAP
scrap2<-subset(SCRAP,select=-c(Referencia, Unidad.de.medida , Ubicación.de.desecho, Estado))
str(scrap2)
## 'data.frame':    250 obs. of  5 variables:
##  $ Fecha              : chr  "31/08/2022" "31/08/2022" "31/08/2022" "31/08/2022" ...
##  $ 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 ...
##  $ Ubicación.de.origen: chr  "SAB/Calidad/Entrega de PT" "SAB/Calidad/Entrega de PT" "SAB/Calidad/Entrega de PT" "SAB/Pre-Production" ...
summary(scrap2)
##     Fecha               Hora             Producto            Cantidad     
##  Length:250         Length:250         Length:250         Min.   : 0.000  
##  Class :character   Class :character   Class :character   1st Qu.: 1.000  
##  Mode  :character   Mode  :character   Mode  :character   Median : 2.000  
##                                                           Mean   : 6.696  
##                                                           3rd Qu.: 7.000  
##                                                           Max.   :96.000  
##  Ubicación.de.origen
##  Length:250         
##  Class :character   
##  Mode  :character   
##                     
##                     
## 

n/a reemplazar con promedios para evitar campos vacios en la medida de lo posible.

Clasificación de Variables

En esta clasificacion logramos introducir las variables que vamos a utilizar a sus clasificaciones para despues poder combinarlas de manera mas facil a la hora de compilar

Variable<- c("Fecha", "Hora", "Producto", " Cantidad" , "Ubicacion")
Tipo <- c("Cuantitativa Continua", "Cuantitativa Continua", "Cualitativa", "Cuantitativa Razón", "Cualitativa")
Escala <- c("Razon", "Discreta", "Nominal", "Razon" , "Nominal")
Table_Scrap <- data.frame(Variable, Tipo, Escala)
knitr::kable(Table_Scrap)
Variable Tipo Escala
Fecha Cuantitativa Continua Razon
Hora Cuantitativa Continua Discreta
Producto Cualitativa Nominal
Cantidad Cuantitativa Razón Razon
Ubicacion Cualitativa Nominal

Instalar Librerías

#install.packages("dplyr")
#install.packages("mirage")
#install.packages("dplyr")
#library(dplyr)
#library(mirage)

N/A´s

Debido a que en la base de datos no se encuentran Missing Values, en esta base de datos no se pueden remplazar valores por media, mediana y moda ya que no aplica.

sum(is.na(scrap2))
## [1] 0
sum(is.na(SCRAP))
## [1] 0
sapply(scrap2, function(x) sum(is.na(x)))
##               Fecha                Hora            Producto            Cantidad 
##                   0                   0                   0                   0 
## Ubicación.de.origen 
##                   0
sapply(SCRAP, function(x) sum(is.na(x)))
##           Referencia                Fecha                 Hora 
##                    0                    0                    0 
##             Producto             Cantidad     Unidad.de.medida 
##                    0                    0                    0 
##  Ubicación.de.origen Ubicación.de.desecho               Estado 
##                    0                    0                    0

Cambiar columnas y variables

Cambiar los nombres de las columnas / variables a nombres más cortos y específicos. Por ejemplo, municipio → mpio, salario mínimo diario → salario_min.

Se cambiaron los nombres de las variables a nombres mas cortos. Para no contar con nombres largos.

#seleccionar columnas / variables.
#scrap2<-SCRAP %>% select(one_of('Fecha','Hora','Producto','Cantidad','Ubicación.de.origen'))

#Renombrar las columnas /variables seleccionadas. 
colnames(scrap2) <-c ('Fecha','Hora','Prod.','Cant.','Origen')

1. Análisis Estadístico SCRAP (5)

Gráficos

Tabla de Frecuencia

Aquí se puede observar que el lugar en donde el Scrap se forma mas frecuentemente es en SAB/Pre-Producción por lo cuál se entiende que es el área en donde más carton se maneja para hacer un producto final, esto nos indica que se deberán hacer los cambios correspondientes para manejar estos desperdicios y bajarlos o bien, re-ubicarlos para otros tipos de utilización por lo que creo ya se utilizan.

#install.packages('epiDisplay')
library(epiDisplay)

tab1(scrap2$Origen, sort.group = "decreasing", cum.percent = TRUE, main = "Distribución del Origen del Scrap") 

## scrap2$Origen : 
##                           Frequency Percent Cum. percent
## SAB/Pre-Production              179    71.6         71.6
## SAB/Calidad/Entrega de PT        58    23.2         94.8
## SAB/Post-Production              13     5.2        100.0
##   Total                         250   100.0        100.0

Grafica cualitativa

Se denotan en correlacion con la fecuencia una mayor cantidad de kgs en la pre-produccion con una diferencia casi triplicada en comparacion de la cantidad mas pequeña, esto hace sentido al ser un área de menor manipulación de carton.

barplot(table(scrap2$Cant.,scrap2$Origen), col="orange", main = "Kilos de Scrap según su origen", xlab = "Origen", ylab = "Kilos" )

Propuestas

  1. Dar una investigación a la optimización de materiales para ver como se podría decrementar el scrap.

2. Análisis Exploratorio

Descargar librerías

#install.packages("kkbleExtra") 
#install.packages("sd")
#install.packages("modeest")
#library(modeest)
#install.packages("dplyr")
#library(dplyr)
#library(kbleExtra)
#summary(bd1)

Tabla de media, mediana, moda y desviación estandard

Dentro de esta tabla se pueden observar distintos resultados que nos informan acerca de las cantidades, por ejemplo el promedio o la media fue de 6.7 dentro de nuestros resultados de scrap, mientras que el que más se repitio fue 1, podríamos decir que basandonos en esto, no hubieron tantos desperdicios de SCRAP dentro de la producción.

sd(scrap2$Cantidad, na.rm= TRUE)  
## [1] NA
Variable<-c("Cant.")
Mediana<-c("2.00")
Media <- c("6.696")
Moda <- c("1") #EXCEL 
Desviación_estandar<-c("11.84885")
table1 <- data.frame (Variable, Mediana, Media, Moda, Desviación_estandar)
knitr::kable(table1)
Variable Mediana Media Moda Desviación_estandar
Cant. 2.00 6.696 1 11.84885

Gráficos

#install.packages("ggplot2")
#install.packages("barplot")
library(ggplot2)
summary(scrap2)
##     Fecha               Hora              Prod.               Cant.       
##  Length:250         Length:250         Length:250         Min.   : 0.000  
##  Class :character   Class :character   Class :character   1st Qu.: 1.000  
##  Mode  :character   Mode  :character   Mode  :character   Median : 2.000  
##                                                           Mean   : 6.696  
##                                                           3rd Qu.: 7.000  
##                                                           Max.   :96.000  
##     Origen         
##  Length:250        
##  Class :character  
##  Mode  :character  
##                    
##                    
## 

Time Series Plots

Aquí hablamos de las cantidades que se manejasn el los origenes, vemos que tambien en la pre-producción igual que en la tabla de frecuencia, se denota una cantidad aumentada en la Pre-producción, hablamos también de la generación creciente de esta en el área, por lo que habrá que darle un vistazo ultimadamente en el proveedor del raw material y ver como se puede acomodar para las necesidades que tiene FORM decrementando la cantidad de SCRAP que se produce.

ggplot(scrap2,aes(x=Cant.))+
  geom_line(aes(y=Origen),color="Orange")+
  labs(x="Cant",y="Origen", color="Legend")+
   ggtitle("Mayores cantidades de Scrap por origen")

Gráfico de Dispersión

Este gráfico de boxplot nos indica que un 25% de nuestros lugares de origenes tuvieron 60 Scraps mientras que el otro 25% tuvieron mas de 100 en cantidades de scrap lo cual nos idica una carga en solo un área.

boxplots=subset(scrap2,select=-c(Origen))
boxplot(table (scrap2$Origen), main = "Ubicación de Origen", xlab = "Origen", ylab = "Cantidad")

Hallazgos

En este analisis nos dimos cuenta que los datos estaban orgnaizados es decir no contaban con missing values por lo tanto es algo bueno para el analisis, de todos modos es importante considerarlos si es relevante para el analisis, en este caso no se hubieran eliminado si no que se hubieran reemplazado por la mediana dependiendte de la variable que estuvieramos analizando.

Analizando estas variables se confirma que en el area de pre-producción,es donde se genera la mayoria del scrap en su mayoria se genera casi el 85% de scrap, que generan dentro de la empresa, por lo tanto es alago alarmante por lo tanto se tienen que tomar decisiones importantes para poder realizar cambios en esta area para reducir la cantidad de scrap.

Sección 1 y 2 Base de Datos Externa

SECCION 1

library(psych)
library(lubridate)
## 
## Attaching package: 'lubridate'
## The following objects are masked from 'package:base':
## 
##     date, intersect, setdiff, union
library(ggplot2)
library(GGally)
## Registered S3 method overwritten by 'GGally':
##   method from   
##   +.gg   ggplot2
library(TSstudio)
library(forecast)
## Registered S3 method overwritten by 'quantmod':
##   method            from
##   as.zoo.data.frame zoo
Companies <-read.csv("C:\\Users\\danyc\\Downloads\\externa_bd1 csv1.csv")
summary(Companies)
##   Geography           Category          Data.Type             Unit          
##  Length:89          Length:89          Length:89          Length:89         
##  Class :character   Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character   Mode  :character  
##                                                                             
##                                                                             
##                                                                             
##  Current.Constant       X2016              X2017              X2018         
##  Length:89          Min.   :       0   Min.   :       0   Min.   :       0  
##  Class :character   1st Qu.:     421   1st Qu.:     432   1st Qu.:     527  
##  Mode  :character   Median :    4383   Median :    4804   Median :    5063  
##                     Mean   :  939400   Mean   :  993634   Mean   : 1193476  
##                     3rd Qu.:   37794   3rd Qu.:   38307   3rd Qu.:   40769  
##                     Max.   :25902010   Max.   :27472550   Max.   :35218716  
##      X2019              X2020              X2021         
##  Min.   :       0   Min.   :       0   Min.   :       0  
##  1st Qu.:     529   1st Qu.:     548   1st Qu.:     607  
##  Median :    4849   Median :    5020   Median :    5477  
##  Mean   : 1376491   Mean   : 1554963   Mean   : 1904399  
##  3rd Qu.:   43779   3rd Qu.:   44564   3rd Qu.:   51280  
##  Max.   :39310235   Max.   :41193660   Max.   :63857942

1. Limpieza, Transformación y Organización de Bases de Datos

str(Companies)
## 'data.frame':    89 obs. of  11 variables:
##  $ Geography       : chr  "Azerbaijan" "Bangladesh" "Cambodia" "China" ...
##  $ Category        : chr  "Corrugated Paper, Paperboard and Containers" "Corrugated Paper, Paperboard and Containers" "Corrugated Paper, Paperboard and Containers" "Corrugated Paper, Paperboard and Containers" ...
##  $ Data.Type       : chr  "Production (turnover) MSP" "Production (turnover) MSP" "Production (turnover) MSP" "Production (turnover) MSP" ...
##  $ Unit            : chr  "AZN million" "BDT million" "KHR million" "CNY million" ...
##  $ Current.Constant: chr  "Current Prices" "Current Prices" "Current Prices" "Current Prices" ...
##  $ X2016           : num  40.6 115106.8 247100 309386.9 212.1 ...
##  $ X2017           : num  44.6 135423.7 257700 301286.2 212.7 ...
##  $ X2018           : num  47.3 156788.3 299500 317612.9 217.5 ...
##  $ X2019           : num  52.2 180445.4 314000 310925.3 216.8 ...
##  $ X2020           : num  51.5 198883.5 281100 312534.7 196.7 ...
##  $ X2021           : num  66.1 222755.3 285994.4 344612.2 191.4 ...
describe(Companies)
## # A tibble: 6 × 26
##   describ…¹     n    na   mean     sd se_mean    IQR skewn…² kurto…³   p00   p01
##   <chr>     <int> <int>  <dbl>  <dbl>   <dbl>  <dbl>   <dbl>   <dbl> <dbl> <dbl>
## 1 X2016        89     0 9.39e5 4.18e6 443039. 37374.    5.19    27.1     0  20.7
## 2 X2017        89     0 9.94e5 4.40e6 466639. 37875.    5.12    26.3     0  20.7
## 3 X2018        89     0 1.19e6 5.40e6 572440. 40242.    5.28    28.3     0  23.1
## 4 X2019        89     0 1.38e6 6.29e6 667194. 43250.    5.19    26.7     0  24.0
## 5 X2020        89     0 1.55e6 7.16e6 759409. 44016.    5.08    24.9     0  20.1
## 6 X2021        89     0 1.90e6 9.14e6 968737. 50673.    5.53    31.3     0  23.8
## # … with 15 more variables: p05 <dbl>, p10 <dbl>, p20 <dbl>, p25 <dbl>,
## #   p30 <dbl>, p40 <dbl>, p50 <dbl>, p60 <dbl>, p70 <dbl>, p75 <dbl>,
## #   p80 <dbl>, p90 <dbl>, p95 <dbl>, p99 <dbl>, p100 <dbl>, and abbreviated
## #   variable names ¹​described_variables, ²​skewness, ³​kurtosis

Nota: Debido a la versión de R, nos deja descargar el paquete “psych”. Sin embargo, no nos deja llamar a la librería “psych”, por lo tanto utilizamos str, para obtener el numero de las variables de la base de datos.

Escala de Medición

Realizamos una tabla donde viene clasificado cada variable y agregamos una columna con la escala de medición para cada variable.

Variable<-c("Geography","Category","Data.Type", "Unit","Current Constant","Years")
Type<-c("Cualitativa", "Cualitativa", "Cualitativa", "Cualitativa", "Cualitativa", "Cuantitativa (Continua)")
Escala_de_Medición <- c("Países", "Producto", "Departamento","Tipo de Moneda", "Precio actual", "Ganancia (Razon)")
table<-data.frame(Variable,Type,Escala_de_Medición)
knitr::kable(table)
Variable Type Escala_de_Medición
Geography Cualitativa Países
Category Cualitativa Producto
Data.Type Cualitativa Departamento
Unit Cualitativa Tipo de Moneda
Current Constant Cualitativa Precio actual
Years Cuantitativa (Continua) Ganancia (Razon)

Limpieza de datos

La primer tecnica de limpieza que utilizamos fue, eliminar columnas debido a que contabamos con datos los cuales no eran relevantes para el análisis.
La segunda herramienta de limpieza que utilizamos para la visulización de los datos fue implementar una nueva columna como el total de la Producción de las variables que se producen por país.

Remover Valores Irrelevantes

Eliminar columnas

bd1 <- Companies
bd1<-subset(bd1,select=-c(Category,Data.Type,Current.Constant))
str(bd1)
## 'data.frame':    89 obs. of  8 variables:
##  $ Geography: chr  "Azerbaijan" "Bangladesh" "Cambodia" "China" ...
##  $ Unit     : chr  "AZN million" "BDT million" "KHR million" "CNY million" ...
##  $ X2016    : num  40.6 115106.8 247100 309386.9 212.1 ...
##  $ X2017    : num  44.6 135423.7 257700 301286.2 212.7 ...
##  $ X2018    : num  47.3 156788.3 299500 317612.9 217.5 ...
##  $ X2019    : num  52.2 180445.4 314000 310925.3 216.8 ...
##  $ X2020    : num  51.5 198883.5 281100 312534.7 196.7 ...
##  $ X2021    : num  66.1 222755.3 285994.4 344612.2 191.4 ...

Agregar Columnas

bd1$Total_Produccion<- bd1$X2016+bd1$X2017+bd1$X2018+bd1$X2019+bd1$X2020+bd1$X2021
bd1$Promedio_X2021<- mean(bd1$X2021)

summary(bd1)
##   Geography             Unit               X2016              X2017         
##  Length:89          Length:89          Min.   :       0   Min.   :       0  
##  Class :character   Class :character   1st Qu.:     421   1st Qu.:     432  
##  Mode  :character   Mode  :character   Median :    4383   Median :    4804  
##                                        Mean   :  939400   Mean   :  993634  
##                                        3rd Qu.:   37794   3rd Qu.:   38307  
##                                        Max.   :25902010   Max.   :27472550  
##      X2018              X2019              X2020              X2021         
##  Min.   :       0   Min.   :       0   Min.   :       0   Min.   :       0  
##  1st Qu.:     527   1st Qu.:     529   1st Qu.:     548   1st Qu.:     607  
##  Median :    5063   Median :    4849   Median :    5020   Median :    5477  
##  Mean   : 1193476   Mean   : 1376491   Mean   : 1554963   Mean   : 1904399  
##  3rd Qu.:   40769   3rd Qu.:   43779   3rd Qu.:   44564   3rd Qu.:   51280  
##  Max.   :35218716   Max.   :39310235   Max.   :41193660   Max.   :63857942  
##  Total_Produccion    Promedio_X2021   
##  Min.   :        0   Min.   :1904399  
##  1st Qu.:     3166   1st Qu.:1904399  
##  Median :    30333   Median :1904399  
##  Mean   :  7962363   Mean   :1904399  
##  3rd Qu.:   254492   3rd Qu.:1904399  
##  Max.   :204523302   Max.   :1904399
str(bd1)
## 'data.frame':    89 obs. of  10 variables:
##  $ Geography       : chr  "Azerbaijan" "Bangladesh" "Cambodia" "China" ...
##  $ Unit            : chr  "AZN million" "BDT million" "KHR million" "CNY million" ...
##  $ X2016           : num  40.6 115106.8 247100 309386.9 212.1 ...
##  $ X2017           : num  44.6 135423.7 257700 301286.2 212.7 ...
##  $ X2018           : num  47.3 156788.3 299500 317612.9 217.5 ...
##  $ X2019           : num  52.2 180445.4 314000 310925.3 216.8 ...
##  $ X2020           : num  51.5 198883.5 281100 312534.7 196.7 ...
##  $ X2021           : num  66.1 222755.3 285994.4 344612.2 191.4 ...
##  $ Total_Produccion: num  302 1009403 1685394 1896358 1247 ...
##  $ Promedio_X2021  : num  1904399 1904399 1904399 1904399 1904399 ...

¿Cuántos NA’s tengo en la base de datos?

sum(is.na(bd1))
## [1] 0

Nota: Se eliminan Category, Data.Type y Current.Constant, ya que no nos sirven, debido a que es el mismo dato para todos los registros y es algo que no nos aporta alguna información.

Análisis Exploratorio de las Bases de Datos

describe(bd1)
## # A tibble: 8 × 26
##   descr…¹     n    na   mean     sd se_mean    IQR skewn…² kurto…³    p00    p01
##   <chr>   <int> <int>  <dbl>  <dbl>   <dbl>  <dbl>   <dbl>   <dbl>  <dbl>  <dbl>
## 1 X2016      89     0 9.39e5 4.18e6  4.43e5 3.74e4    5.19    27.1 0      2.07e1
## 2 X2017      89     0 9.94e5 4.40e6  4.67e5 3.79e4    5.12    26.3 0      2.07e1
## 3 X2018      89     0 1.19e6 5.40e6  5.72e5 4.02e4    5.28    28.3 0      2.31e1
## 4 X2019      89     0 1.38e6 6.29e6  6.67e5 4.33e4    5.19    26.7 0      2.40e1
## 5 X2020      89     0 1.55e6 7.16e6  7.59e5 4.40e4    5.08    24.9 0      2.01e1
## 6 X2021      89     0 1.90e6 9.14e6  9.69e5 5.07e4    5.53    31.3 0      2.38e1
## 7 Total_…    89     0 7.96e6 3.60e7  3.82e6 2.51e5    5.03    24.4 0      1.51e2
## 8 Promed…    89     0 1.90e6 0       0      0       NaN      NaN   1.90e6 1.90e6
## # … with 15 more variables: p05 <dbl>, p10 <dbl>, p20 <dbl>, p25 <dbl>,
## #   p30 <dbl>, p40 <dbl>, p50 <dbl>, p60 <dbl>, p70 <dbl>, p75 <dbl>,
## #   p80 <dbl>, p90 <dbl>, p95 <dbl>, p99 <dbl>, p100 <dbl>, and abbreviated
## #   variable names ¹​described_variables, ²​skewness, ³​kurtosis

En el análisis descriptivo se muestran los valores promedio del total de producciones de 2016 a 2021.

Tabla de Frecuencia

bd2 <- table(bd1$Unit)
bd2 <- prop.table(bd2)
bd2
## 
## AED million AOA million ARS million AUD million AZN million BDT million 
##  0.01123596  0.01123596  0.01123596  0.01123596  0.01123596  0.01123596 
## BGN million BRL million BYR million CAD million CHF million CLP million 
##  0.01123596  0.01123596  0.01123596  0.01123596  0.01123596  0.01123596 
## CNY million COP million CRC million CUC million CZK million DKK million 
##  0.01123596  0.01123596  0.01123596  0.01123596  0.01123596  0.01123596 
## DOP million DZD million EGP million ETB million EUR million GBP million 
##  0.01123596  0.01123596  0.01123596  0.01123596  0.20224719  0.01123596 
## GEL million GHS million HKD million HRK million HuF million IDR million 
##  0.01123596  0.01123596  0.01123596  0.01123596  0.01123596  0.01123596 
## ILS million INR million IQD million IRR million ISK million JPY million 
##  0.01123596  0.01123596  0.01123596  0.01123596  0.01123596  0.01123596 
## KES million KHR million KRW million KWD million KZT million LKR million 
##  0.01123596  0.01123596  0.01123596  0.01123596  0.01123596  0.01123596 
## MAD million MXN million MYR million NGN million NOK million NZD million 
##  0.01123596  0.01123596  0.01123596  0.01123596  0.01123596  0.01123596 
## PAB million PEN million PHP million PKR million PLN million QAR million 
##  0.01123596  0.01123596  0.01123596  0.01123596  0.01123596  0.01123596 
## RON million RUB million SAR million SEK million SGD million THB million 
##  0.01123596  0.01123596  0.01123596  0.01123596  0.01123596  0.01123596 
## TND million TRY million TWD million UAH million USD million UYU million 
##  0.01123596  0.01123596  0.01123596  0.01123596  0.03370787  0.01123596 
## UZS million VND million XAF million ZAR million 
##  0.01123596  0.01123596  0.01123596  0.01123596

Tabla cruzada

table(bd1$Unit, bd1$Promedio_X2021)
##              
##               1904399.38539326
##   AED million                1
##   AOA million                1
##   ARS million                1
##   AUD million                1
##   AZN million                1
##   BDT million                1
##   BGN million                1
##   BRL million                1
##   BYR million                1
##   CAD million                1
##   CHF million                1
##   CLP million                1
##   CNY million                1
##   COP million                1
##   CRC million                1
##   CUC million                1
##   CZK million                1
##   DKK million                1
##   DOP million                1
##   DZD million                1
##   EGP million                1
##   ETB million                1
##   EUR million               18
##   GBP million                1
##   GEL million                1
##   GHS million                1
##   HKD million                1
##   HRK million                1
##   HuF million                1
##   IDR million                1
##   ILS million                1
##   INR million                1
##   IQD million                1
##   IRR million                1
##   ISK million                1
##   JPY million                1
##   KES million                1
##   KHR million                1
##   KRW million                1
##   KWD million                1
##   KZT million                1
##   LKR million                1
##   MAD million                1
##   MXN million                1
##   MYR million                1
##   NGN million                1
##   NOK million                1
##   NZD million                1
##   PAB million                1
##   PEN million                1
##   PHP million                1
##   PKR million                1
##   PLN million                1
##   QAR million                1
##   RON million                1
##   RUB million                1
##   SAR million                1
##   SEK million                1
##   SGD million                1
##   THB million                1
##   TND million                1
##   TRY million                1
##   TWD million                1
##   UAH million                1
##   USD million                3
##   UYU million                1
##   UZS million                1
##   VND million                1
##   XAF million                1
##   ZAR million                1

La tabla nos muestra la cantidad promedio en millones producida en 2021 por cada unidad monetaria. En este caso, vemos que en 2021 se produjo en promedio más de 1MM de “currencies” (no se puede definir una unidad monetaria específica debido a que estamos ponderando distintas monedas internacionales). Conforme se analiza la tabla, vemos que el euro generó 18 veces el promedio de producción de cartón estimado para 2021, es decir, es la moneda internacional que más produjo cartón a nivel internacional en 2021. La siguiente moneda con mayor capacidad de producción fue USD millions.

Gráficas de datos Cualitativas y Cuantitativas

Cualitativa con Unit

barplot(bd2, xlab='Tipo de Moneda',
        ylab='Frecuencia Relativa', las=1)

La gráfica nos muestra que de acuerdo a la frecuencia relativa de producción, Indonesia es la unidad monetaria que más cartón ha entregado.

Cuantitativa con Total_Produccion

bd3 <- bd1
aggregate(x=bd3$Total_Produccion, by=list(bd3$Geography),FUN=sum)
##                 Group.1 sum.bd3$Total_Produccion
## 1               Algeria                  26366.2
## 2                Angola                   4172.7
## 3             Argentina                 757754.2
## 4             Australia                  21642.9
## 5               Austria                  10233.5
## 6            Azerbaijan                    302.3
## 7            Bangladesh                1009403.0
## 8               Belarus                   2931.2
## 9               Belgium                   6339.5
## 10               Brazil                 129369.8
## 11             Bulgaria                   3166.2
## 12             Cambodia                1685394.4
## 13             Cameroon                 197101.1
## 14               Canada                  78979.4
## 15                Chile                6391369.9
## 16                China                1896358.2
## 17             Colombia               15542263.1
## 18           Costa Rica                 967034.3
## 19              Croatia                   8719.9
## 20                 Cuba                    619.6
## 21               Cyprus                    171.5
## 22       Czech Republic                 178808.7
## 23              Denmark                  32238.2
## 24   Dominican Republic                  37293.6
## 25              Ecuador                    949.5
## 26                Egypt                  96033.6
## 27              Estonia                    387.5
## 28             Ethiopia                   5442.2
## 29              Finland                   2612.9
## 30               France                  33450.4
## 31              Georgia                    194.3
## 32              Germany                  77218.5
## 33                Ghana                    673.7
## 34               Greece                   2573.7
## 35     Hong Kong, China                   1247.2
## 36              Hungary                1504747.7
## 37              Iceland                   5561.8
## 38                India                2264525.5
## 39            Indonesia              204523301.8
## 40                 Iran              186021771.8
## 41                 Iraq                  11680.2
## 42              Ireland                   1873.4
## 43               Israel                  22710.5
## 44                Italy                  50972.2
## 45                Japan               15807772.3
## 46           Kazakhstan                 203941.1
## 47                Kenya                 112343.7
## 48               Kuwait                    251.3
## 49               Latvia                    463.0
## 50            Lithuania                   1775.1
## 51           Luxembourg                      0.0
## 52             Malaysia                  23655.6
## 53               Mexico                 738215.0
## 54              Morocco                  16625.1
## 55          Netherlands                  13921.1
## 56          New Zealand                   7644.6
## 57              Nigeria                 206027.0
## 58               Norway                  11525.8
## 59             Pakistan                 628812.7
## 60               Panama                    221.3
## 61                 Peru                   5083.5
## 62          Philippines                 302208.8
## 63               Poland                 118115.9
## 64             Portugal                   5366.3
## 65          Puerto Rico                    537.2
## 66                Qatar                    189.5
## 67              Romania                  16388.7
## 68               Russia                1590911.6
## 69         Saudi Arabia                  36787.1
## 70            Singapore                   3636.7
## 71             Slovakia                   1317.9
## 72             Slovenia                   1137.3
## 73         South Africa                 277898.6
## 74          South Korea               59825405.8
## 75                Spain                  31015.4
## 76            Sri Lanka                 254492.0
## 77               Sweden                  60578.6
## 78          Switzerland                   5331.3
## 79               Taiwan                 615169.6
## 80             Thailand                 201398.4
## 81              Tunisia                   2715.6
## 82               Turkey                 195406.5
## 83              Ukraine                 128095.2
## 84 United Arab Emirates                  12957.3
## 85       United Kingdom                  30332.9
## 86              Uruguay                  83173.7
## 87                  USA                 323594.0
## 88           Uzbekistan                5103054.3
## 89              Vietnam              198028864.1

En la tabla anterior se muestra el total de producción generado por cada país. Haciendo una ponderación de los 5 países que mayor producción de cartón tienen (haciendo conteo histórico de 2016 a 2021), vemos que se destacan Irán, Vietnam, Corea del Sur, Japón e Indonesia.

hist(log(bd1$Total_Produccion), main = "Histograma de Producción Total", xlab="Producción Total", 
     ylab="Frecuencia", col="blue1")

En la gráfica anterior se simboliza la distribución de la muestra respecto a la producción total y la frecuencia de ésta. De acuerdo a la frecuencia total, vemos que se tiene una mayor producción por frecuencia entre 10 y 15, es decir, la producción total es más alta y tiene una frecuencia mayor a 15 que se muestra como el más elevado en el histograma.

Gráficas de Dispersión

Relación Geography con Producción Total

ggplot(bd1, aes(x=Total_Produccion, y=Geography)) + 
  geom_point(shape=19, size=3) + labs(title = "Relación entre los Países y la Producción Total",caption ="Passport_ProducciónCarton",x="Producción_Total", y="Geography") + theme_classic()

En la gráfica anterior se muestra la relación entre los países y la producción total. Se ve que hay una dispersión mayor para los países en el centro de la gráfica. Esto significa que hay más irregularidad en la producción total que han generado.

boxplot=subset(bd1,select = -c(Total_Produccion,Geography))
boxplot(bd1$Total_Produccion, main= "Total de producción")

En la gráfica anterior vemos el total de producción de acuerdo a la geografía. Al igual que la gráfica anterior, hay una correlación mayor acorde al total de producción.

Vol<-ts(boxplot,start=c(2016,1),frequency=12)
ts_plot(Vol,
        title = "Desempeño de la Industria Automotriz: Producción de cartón global de 2016 a 2021",
        Ytitle = "Unidades en miles",
        Xtitle = "Años", 
        slider = TRUE)

En esta gráfica se ve el desempeño de la industria automotriz de 2016 a 2021. En general, se muestra que el total de producción de cartón a nivel global fue mayor en 2021 contra otros años.

Predicción

Importar base de datos

bd5 <-read.csv("C:\\Users\\danyc\\Downloads\\externa_bd2 csv2.csv")
summary(bd5)
##   Geography             Unit                Año         Produccion      
##  Length:534         Length:534         Min.   :2016   Min.   :       0  
##  Class :character   Class :character   1st Qu.:2017   1st Qu.:     501  
##  Mode  :character   Mode  :character   Median :2018   Median :    4826  
##                                        Mean   :2018   Mean   : 1327061  
##                                        3rd Qu.:2020   3rd Qu.:   43907  
##                                        Max.   :2021   Max.   :63857942
sum(is.na(bd5))
## [1] 0
bd5$Total_Produccion<- bd1$X2016+bd1$X2017+bd1$X2018+bd1$X2019+bd1$X2020+bd1$X2021

summary(bd5)
##   Geography             Unit                Año         Produccion      
##  Length:534         Length:534         Min.   :2016   Min.   :       0  
##  Class :character   Class :character   1st Qu.:2017   1st Qu.:     501  
##  Mode  :character   Mode  :character   Median :2018   Median :    4826  
##                                        Mean   :2018   Mean   : 1327061  
##                                        3rd Qu.:2020   3rd Qu.:   43907  
##                                        Max.   :2021   Max.   :63857942  
##  Total_Produccion   
##  Min.   :        0  
##  1st Qu.:     3166  
##  Median :    30333  
##  Mean   :  7962363  
##  3rd Qu.:   254492  
##  Max.   :204523302
str(bd5)
## 'data.frame':    534 obs. of  5 variables:
##  $ Geography       : chr  "Azerbaijan" "Bangladesh" "Cambodia" "China" ...
##  $ Unit            : chr  "AZN million" "BDT million" "KHR million" "CNY million" ...
##  $ Año             : int  2016 2016 2016 2016 2016 2016 2016 2016 2016 2016 ...
##  $ Produccion      : num  40.6 115106.8 247100 309386.9 212.1 ...
##  $ Total_Produccion: num  302 1009403 1685394 1896358 1247 ...
sum(is.na(bd5))
## [1] 0

Modelos de regresión lineal múltiple

Modelos de regresión lineal múltiple: Producción de cartón en 2022 a nivel global

library(ggplot2)
library(dplyr)
library(broom)
library(ggpubr)
## 
## Attaching package: 'ggpubr'
## The following object is masked from 'package:forecast':
## 
##     gghistogram
## The following object is masked from 'package:plyr':
## 
##     mutate
industriaA <-read.csv("C:\\Users\\danyc\\Downloads\\Industria Auto.csv")

bd6 <-read.csv("C:\\Users\\danyc\\Downloads\\externa_bd3 csv3 (1).csv")

bd6 <- bd6[-c(1),]


summary(bd6)
##       Año            USA             MEX        
##  Min.   :2017   Min.   :51672   Min.   :112231  
##  1st Qu.:2018   1st Qu.:54006   1st Qu.:120639  
##  Median :2019   Median :54651   Median :128471  
##  Mean   :2019   Mean   :54949   Mean   :126954  
##  3rd Qu.:2020   3rd Qu.:55387   3rd Qu.:129871  
##  Max.   :2021   Max.   :59031   Max.   :143561
summary(industriaA)
##       year        trimestre       id_estado        estado         
##  Min.   :2014   Min.   :1.000   Min.   : 1.00   Length:690        
##  1st Qu.:2016   1st Qu.:1.000   1st Qu.:10.00   Class :character  
##  Median :2018   Median :2.000   Median :17.00   Mode  :character  
##  Mean   :2018   Mean   :2.399   Mean   :17.37                     
##  3rd Qu.:2020   3rd Qu.:3.000   3rd Qu.:26.00                     
##  Max.   :2022   Max.   :4.000   Max.   :32.00                     
##    idnueva          ventas_autopartes_anual      eci         
##  Length:690         Min.   :4.382e+03       Min.   :-0.9374  
##  Class :character   1st Qu.:2.256e+07       1st Qu.:-0.4630  
##  Mode  :character   Median :2.316e+08       Median : 0.7088  
##                     Mean   :3.307e+08       Mean   : 0.4391  
##                     3rd Qu.:5.759e+08       3rd Qu.: 0.9138  
##                     Max.   :1.467e+09       Max.   : 1.7810  
##  poblacion_ocupada_ensambladora_year exportaciones_anual iedanual_porestado
##  Length:690                          Length:690          Length:690        
##  Class :character                    Class :character    Class :character  
##  Mode  :character                    Mode  :character    Mode  :character  
##                                                                            
##                                                                            
## 
str(industriaA)
## 'data.frame':    690 obs. of  10 variables:
##  $ year                               : int  2014 2014 2014 2014 2014 2014 2014 2014 2014 2014 ...
##  $ trimestre                          : int  1 1 1 1 1 1 1 1 1 1 ...
##  $ id_estado                          : int  1 2 5 8 9 10 11 13 14 15 ...
##  $ estado                             : chr  "Aguascalientes" "Baja California" "Coahuila de Zaragoza" "Chihuahua" ...
##  $ idnueva                            : chr  "Agu20141" "Baj20141" "Coa20141" "Chi20141" ...
##  $ ventas_autopartes_anual            : int  297808938 180968923 638892837 415306918 424386804 2395458 599464057 490518 73197944 161883028 ...
##  $ eci                                : num  0.856 1.268 0.914 1.148 0.914 ...
##  $ poblacion_ocupada_ensambladora_year: chr  "5523" "41376" "19522" "93703" ...
##  $ exportaciones_anual                : chr  "8466008000" "35002851000" "34838926000" "1460627000" ...
##  $ iedanual_porestado                 : chr  "1008408044" "1102570984" "1567453720" "1462699524" ...
regresion1 <- lm(ventas_autopartes_anual ~  estado + exportaciones_anual + poblacion_ocupada_ensambladora_year ,data = industriaA)
summary(regresion1)
## 
## Call:
## lm(formula = ventas_autopartes_anual ~ estado + exportaciones_anual + 
##     poblacion_ocupada_ensambladora_year, data = industriaA)
## 
## Residuals:
##        Min         1Q     Median         3Q        Max 
## -506069374   -1448463          0    2162402  296273810 
## 
## Coefficients: (3 not defined because of singularities)
##                                             Estimate Std. Error t value
## (Intercept)                                316032420   79025905   3.999
## estadoBaja California                       82523284  111759507   0.738
## estadoCampeche                            -316015278  111759507  -2.828
## estadoChihuahua                            398034214  111759507   3.562
## estadoCiudad de Mexico                     571759097  111759507   5.116
## estadoCoahuila de Zaragoza                1151233158  111759507  10.301
## estadoColima                              -315905304  111759507  -2.827
## estadoDurango                             -251105163  111759507  -2.247
## estadoEstado de Mexico                     -38335193  111759507  -0.343
## estadoGuanajuato                           623474494  111759507   5.579
## estadoHidalgo                             -309386913  111759507  -2.768
## estadoJalisco                              -99121659  111759507  -0.887
## estadoMorelos                             -282142730  111759507  -2.525
## estadoNuevo Leon                           491777471  111759507   4.400
## estadoPuebla                               585598166  111759507   5.240
## estadoQueretaro                            741305945  111759507   6.633
## estadoQuintana Roo                        -315991405   96786572  -3.265
## estadoSan Luis Potosi                      124368409  111759507   1.113
## estadoSonora                              -227591089  111759507  -2.036
## estadoTamaulipas                           303676078  111759507   2.717
## estadoTlaxcala                            -279845202  111759507  -2.504
## estadoVeracruz de Ignacio de la Llave     -298360634  111759507  -2.670
## estadoYucatan                             -315911612  111759507  -2.827
## estadoZacatecas                           -293692225  111759507  -2.628
## exportaciones_anual10141642000            -633342919   91251256  -6.941
## exportaciones_anual10314836000            -243122117   91251256  -2.664
## exportaciones_anual10398672000             -83306231   96786572  -0.861
## exportaciones_anual10400467000            -214097642   91251256  -2.346
## exportaciones_anual10478612000            -227071679   91251256  -2.488
## exportaciones_anual10594592000            -660445310   91251256  -7.238
## exportaciones_anual10701591000            -184046450   96786572  -1.902
## exportaciones_anual11146761000            -328066976   96786572  -3.390
## exportaciones_anual1116042000                 -50913   91251256  -0.001
## exportaciones_anual1119625000                  16310   91251256   0.000
## exportaciones_anual11227331000            -195000075   91251256  -2.137
## exportaciones_anual11449692000             -52031743   91251256  -0.570
## exportaciones_anual1165750000             -155619675   91251256  -1.705
## exportaciones_anual11738889000            -320498675   91251256  -3.512
## exportaciones_anual11794073000              80649592   91251256   0.884
## exportaciones_anual12035000                   -28653   96786572   0.000
## exportaciones_anual12044484000             -42701116   96786572  -0.441
## exportaciones_anual1238308000               -2755770   96786572  -0.028
## exportaciones_anual1262654000                  37474   91251256   0.000
## exportaciones_anual1278536000              -29700606   91251256  -0.325
## exportaciones_anual12868798000            -152191028   91251256  -1.668
## exportaciones_anual1301171000               -5888596   91251256  -0.065
## exportaciones_anual1307252000              -28159308   91251256  -0.309
## exportaciones_anual1310801000              -24999653   91251256  -0.274
## exportaciones_anual1318941000               -4141097   91251256  -0.045
## exportaciones_anual1323153000               -5226323   91251256  -0.057
## exportaciones_anual13360587000            -213744406   91251256  -2.342
## exportaciones_anual13514349000            -461981584   91251256  -5.063
## exportaciones_anual13664629000            -141254716   91251256  -1.548
## exportaciones_anual1379964000              -23869307   91251256  -0.262
## exportaciones_anual14009625000             -74475970   91251256  -0.816
## exportaciones_anual1428633000               -3663704   96786572  -0.038
## exportaciones_anual1440918000              -16649460   91251256  -0.182
## exportaciones_anual1448674000               -9154406   91251256  -0.100
## exportaciones_anual14512000                   -14416   96786572   0.000
## exportaciones_anual1460627000             -202662429   91251256  -2.221
## exportaciones_anual1460865000               -8043655   91251256  -0.088
## exportaciones_anual1470940000                 -47686   91251256  -0.001
## exportaciones_anual15019152000            -613314608   91251256  -6.721
## exportaciones_anual15120233000              34228936   96786572   0.354
## exportaciones_anual15294350000            -165928588   91251256  -1.818
## exportaciones_anual15531676000            -107724661   91251256  -1.181
## exportaciones_anual15611884000              75774919   91251256   0.830
## exportaciones_anual16121000                   -30177   96786572   0.000
## exportaciones_anual1654784000              -63167299   91251256  -0.692
## exportaciones_anual16642906000             -34997843   96786572  -0.362
## exportaciones_anual1672357000              -62208412   91251256  -0.682
## exportaciones_anual16837910000            -507759556   91251256  -5.564
## exportaciones_anual16895883000             115296593   91251256   1.264
## exportaciones_anual17204369000            -247634512   91251256  -2.714
## exportaciones_anual1721651000               -5466936   91251256  -0.060
## exportaciones_anual1726504000               -5852596   91251256  -0.064
## exportaciones_anual17332223000             -94707222   91251256  -1.038
## exportaciones_anual17443597000             102705938   91251256   1.126
## exportaciones_anual1752495000              -62743887   91251256  -0.688
## exportaciones_anual17544423000             135514903   91251256   1.485
## exportaciones_anual17547974000            -447164471   91251256  -4.900
## exportaciones_anual17735407000             104259566   91251256   1.143
## exportaciones_anual17877862000              10618852   91251256   0.116
## exportaciones_anual1813156000             -214253693   96786572  -2.214
## exportaciones_anual18601992000             -87747401   91251256  -0.962
## exportaciones_anual1861966000              -62600427   91251256  -0.686
## exportaciones_anual18687648000             -24706585   91251256  -0.271
## exportaciones_anual18737712000            -123808645   91251256  -1.357
## exportaciones_anual18985000                    -5479   72140452   0.000
## exportaciones_anual191993000                      NA         NA      NA
## exportaciones_anual19737684000             -78238788   91251256  -0.857
## exportaciones_anual19840531000             197594823   91251256   2.165
## exportaciones_anual19863200000             229643101   91251256   2.517
## exportaciones_anual20010001000             -29475421   91251256  -0.323
## exportaciones_anual20026441000            -147417980   96786572  -1.523
## exportaciones_anual20093245000             -52714510   91251256  -0.578
## exportaciones_anual20335098000             -59363602   91251256  -0.651
## exportaciones_anual20787831000            -176885438   91251256  -1.938
## exportaciones_anual21133618000             -11919096   91251256  -0.131
## exportaciones_anual2127000000              -53259174   91251256  -0.584
## exportaciones_anual2128076000             -135947447   88353648  -1.539
## exportaciones_anual21392726000             -85136044   91251256  -0.933
## exportaciones_anual21659640000             -27746581   91251256  -0.304
## exportaciones_anual22099835000            -140806200   91251256  -1.543
## exportaciones_anual2242354000               -4851805   91251256  -0.053
## exportaciones_anual22472408000             -97592972   91251256  -1.069
## exportaciones_anual22985164000             -19566138   96786572  -0.202
## exportaciones_anual2299343000               -5280661   91251256  -0.058
## exportaciones_anual2301925000                     NA         NA      NA
## exportaciones_anual2302851000             -344468140   91251256  -3.775
## exportaciones_anual23360290000             -87808473   91251256  -0.962
## exportaciones_anual2376795000               -5540326   96786572  -0.057
## exportaciones_anual24048744000            -301202855   91251256  -3.301
## exportaciones_anual2452302000             -460231437   91251256  -5.044
## exportaciones_anual24926226000             -19992365   91251256  -0.219
## exportaciones_anual25065798000            -146940238   91251256  -1.610
## exportaciones_anual25504680000            -101969366   91251256  -1.117
## exportaciones_anual25507316000              -2426972   91251256  -0.027
## exportaciones_anual26300102000             -42846992   91251256  -0.470
## exportaciones_anual2630544000             -289995068   91251256  -3.178
## exportaciones_anual2632148000              -14585583   91251256  -0.160
## exportaciones_anual2667126000              -25511848   91251256  -0.280
## exportaciones_anual26736210000             -68439434   91251256  -0.750
## exportaciones_anual2684823000              -17118638   91251256  -0.188
## exportaciones_anual2705297000             -475872294   91251256  -5.215
## exportaciones_anual27314741000             108407180   91251256   1.188
## exportaciones_anual2737230000              -31938434   91251256  -0.350
## exportaciones_anual27397995000             -40140750   91251256  -0.440
## exportaciones_anual2760694000              -13930385   96786572  -0.144
## exportaciones_anual2793509000                7728884   91251256   0.085
## exportaciones_anual2873522000                1653824   91251256   0.018
## exportaciones_anual2880494000              -28125619   96786572  -0.291
## exportaciones_anual29130161000              79348605   91251256   0.870
## exportaciones_anual2946392000                2850874   91251256   0.031
## exportaciones_anual3026698000                1579766   91251256   0.017
## exportaciones_anual30529987000            -153881209   96786572  -1.590
## exportaciones_anual3086705000              -14291744   91251256  -0.157
## exportaciones_anual3086747000               -3612817   91251256  -0.040
## exportaciones_anual3141633000                2244200   91251256   0.025
## exportaciones_anual31513013000            -213302878   91251256  -2.338
## exportaciones_anual3157991000                8403585   96786572   0.087
## exportaciones_anual32177305000            -199208826   91251256  -2.183
## exportaciones_anual3325166000                4332750   91251256   0.047
## exportaciones_anual3402758000              -31045251   91251256  -0.340
## exportaciones_anual34511011000            -281714187   91251256  -3.087
## exportaciones_anual34522156000            -122777424   91251256  -1.345
## exportaciones_anual34590332000             -51405465   96786572  -0.531
## exportaciones_anual34838926000            -652547881   91251256  -7.151
## exportaciones_anual3490783000              -27486235   91251256  -0.301
## exportaciones_anual35002851000            -189871772   91251256  -2.081
## exportaciones_anual35997280000            -171707454   91251256  -1.882
## exportaciones_anual36004725000            -180452978   91251256  -1.978
## exportaciones_anual36251770000            -564945445   91251256  -6.191
## exportaciones_anual36315716000            -184526706   91251256  -2.022
## exportaciones_anual3657768000                2656603   91251256   0.029
## exportaciones_anual37699563000            -521630672   91251256  -5.716
## exportaciones_anual3791586000              -27851391   91251256  -0.305
## exportaciones_anual38441996000            -166179330   91251256  -1.821
## exportaciones_anual38572482000            -358805171   96786572  -3.707
## exportaciones_anual38950677000            -472455089   91251256  -5.178
## exportaciones_anual39615279000            -273384682   91251256  -2.996
## exportaciones_anual39857053000            -188893113   91251256  -2.070
## exportaciones_anual39896454000            -179369916   91251256  -1.966
## exportaciones_anual40659059000            -134947537   91251256  -1.479
## exportaciones_anual41034808000            -428473899   91251256  -4.696
## exportaciones_anual42396951000             -96879896   91251256  -1.062
## exportaciones_anual4339856000              -13715539   91251256  -0.150
## exportaciones_anual44961569000            -644854760   91251256  -7.067
## exportaciones_anual47659461000            -389638362   91251256  -4.270
## exportaciones_anual4862567000               -6250697   96786572  -0.065
## exportaciones_anual52231000                   -10472   79025905   0.000
## exportaciones_anual522839000                  738252  111759507   0.007
## exportaciones_anual5352788000               -9101610   88353648  -0.103
## exportaciones_anual5362863000              -12135351   88353648  -0.137
## exportaciones_anual582973000                  -81666   96786572  -0.001
## exportaciones_anual587504000              -173779186   91251256  -1.904
## exportaciones_anual606131000              -166997519   91251256  -1.830
## exportaciones_anual6367193000              -10360227   88353648  -0.117
## exportaciones_anual6697248000               -8465610   88353648  -0.096
## exportaciones_anual716061000                  -18237   96786572   0.000
## exportaciones_anual722027000                -7889813  111759507  -0.071
## exportaciones_anual726530000              -175201219   96786572  -1.810
## exportaciones_anual729883000              -274984075   91251256  -3.013
## exportaciones_anual735262000                  246347   96786572   0.003
## exportaciones_anual7830019000               53331418   91251256   0.584
## exportaciones_anual7870962000               60706600   91251256   0.665
## exportaciones_anual790859000               -15435643  111759507  -0.138
## exportaciones_anual80907000                   -21941   68438442   0.000
## exportaciones_anual820169000              -135474164   91251256  -1.485
## exportaciones_anual8466008000              -12575744   91251256  -0.138
## exportaciones_anual8476833000             -224960819   91251256  -2.465
## exportaciones_anual8495444000               55657928   91251256   0.610
## exportaciones_anual8534000                     -6324   72140452   0.000
## exportaciones_anual871638000              -105063931   91251256  -1.151
## exportaciones_anual8829410000              -40562505   96786572  -0.419
## exportaciones_anual9147776000             -258898283   91251256  -2.837
## exportaciones_anual9372970000             -640224591   91251256  -7.016
## exportaciones_anual9505026000             -229554589   91251256  -2.516
## exportaciones_anual9650719000               65416021   91251256   0.717
## exportaciones_anual9806397000             -212125633   91251256  -2.325
## poblacion_ocupada_ensambladora_year1004      -460559   91251256  -0.005
## poblacion_ocupada_ensambladora_year1017    -88043944   91251256  -0.965
## poblacion_ocupada_ensambladora_year10714    35863369   91251256   0.393
## poblacion_ocupada_ensambladora_year1075       -35206   91251256   0.000
## poblacion_ocupada_ensambladora_year10767     3518043   91251256   0.039
## poblacion_ocupada_ensambladora_year11050  -118555603  111759507  -1.061
## poblacion_ocupada_ensambladora_year11361   -54924139   91251256  -0.602
## poblacion_ocupada_ensambladora_year11806     4344197   91251256   0.048
## poblacion_ocupada_ensambladora_year12073    -3121269   96786572  -0.032
## poblacion_ocupada_ensambladora_year12094   -64875837   91251256  -0.711
## poblacion_ocupada_ensambladora_year12217     6288286   91251256   0.069
## poblacion_ocupada_ensambladora_year124585  -36854211   91251256  -0.404
## poblacion_ocupada_ensambladora_year1247       347242  111759507   0.003
## poblacion_ocupada_ensambladora_year12650    -1079792   91251256  -0.012
## poblacion_ocupada_ensambladora_year12836    -8672226   91251256  -0.095
## poblacion_ocupada_ensambladora_year13072   -16160578   96786572  -0.167
## poblacion_ocupada_ensambladora_year13538   -26780130  111759507  -0.240
## poblacion_ocupada_ensambladora_year13866   -40099449   91251256  -0.439
## poblacion_ocupada_ensambladora_year13927    -1153337   91251256  -0.013
## poblacion_ocupada_ensambladora_year13995     -302686   91251256  -0.003
## poblacion_ocupada_ensambladora_year14221   -85427604   91251256  -0.936
## poblacion_ocupada_ensambladora_year144         18849   91251256   0.000
## poblacion_ocupada_ensambladora_year15136       68628   91251256   0.001
## poblacion_ocupada_ensambladora_year15762   -41948849   91251256  -0.460
## poblacion_ocupada_ensambladora_year15901   -56960344   91251256  -0.624
## poblacion_ocupada_ensambladora_year1601    -71923505   91251256  -0.788
## poblacion_ocupada_ensambladora_year1629    -83095837  111759507  -0.744
## poblacion_ocupada_ensambladora_year16844     3457658   96786572   0.036
## poblacion_ocupada_ensambladora_year1751     50233479   91251256   0.550
## poblacion_ocupada_ensambladora_year17726   -19904172   91251256  -0.218
## poblacion_ocupada_ensambladora_year1776    -95219290   91251256  -1.043
## poblacion_ocupada_ensambladora_year17790     1084572  111759507   0.010
## poblacion_ocupada_ensambladora_year17806  -125382498   91251256  -1.374
## poblacion_ocupada_ensambladora_year17876   -42916198   91251256  -0.470
## poblacion_ocupada_ensambladora_year18197    -6777176   91251256  -0.074
## poblacion_ocupada_ensambladora_year1827     -2927497   91251256  -0.032
## poblacion_ocupada_ensambladora_year18338     -809771   91251256  -0.009
## poblacion_ocupada_ensambladora_year186       9165298   91251256   0.100
## poblacion_ocupada_ensambladora_year1890       -56677   96786572  -0.001
## poblacion_ocupada_ensambladora_year19056     -676860   91251256  -0.007
## poblacion_ocupada_ensambladora_year19219      311407   91251256   0.003
## poblacion_ocupada_ensambladora_year19286   -16058828   91251256  -0.176
## poblacion_ocupada_ensambladora_year1945     12467581   91251256   0.137
## poblacion_ocupada_ensambladora_year19522  -175824860   91251256  -1.927
## poblacion_ocupada_ensambladora_year20047     2203070   91251256   0.024
## poblacion_ocupada_ensambladora_year217       -142230   91251256  -0.002
## poblacion_ocupada_ensambladora_year22383     5551012   96786572   0.057
## poblacion_ocupada_ensambladora_year2252      -243013  111759507  -0.002
## poblacion_ocupada_ensambladora_year2275      -718489   91251256  -0.008
## poblacion_ocupada_ensambladora_year22783   -17304874   91251256  -0.190
## poblacion_ocupada_ensambladora_year23106   -52789396   91251256  -0.579
## poblacion_ocupada_ensambladora_year23160  -124029766   91251256  -1.359
## poblacion_ocupada_ensambladora_year23209   -13521731   91251256  -0.148
## poblacion_ocupada_ensambladora_year23991     -586001  111759507  -0.005
## poblacion_ocupada_ensambladora_year25113   -55792481  111759507  -0.499
## poblacion_ocupada_ensambladora_year25660   -20874860   91251256  -0.229
## poblacion_ocupada_ensambladora_year25840    -3586940   96786572  -0.037
## poblacion_ocupada_ensambladora_year26248     9162092   91251256   0.100
## poblacion_ocupada_ensambladora_year2695    -13312374   91251256  -0.146
## poblacion_ocupada_ensambladora_year26950   -82012426   91251256  -0.899
## poblacion_ocupada_ensambladora_year27190   -31434153   91251256  -0.344
## poblacion_ocupada_ensambladora_year2720      -897442   91251256  -0.010
## poblacion_ocupada_ensambladora_year27286    19980870   91251256   0.219
## poblacion_ocupada_ensambladora_year27319    -8580815   91251256  -0.094
## poblacion_ocupada_ensambladora_year281       -179512   96786572  -0.002
## poblacion_ocupada_ensambladora_year28299   -57488134   91251256  -0.630
## poblacion_ocupada_ensambladora_year28505    20100158   91251256   0.220
## poblacion_ocupada_ensambladora_year28631    13816454   91251256   0.151
## poblacion_ocupada_ensambladora_year29188  -167555153  111759507  -1.499
## poblacion_ocupada_ensambladora_year29560    45453217   91251256   0.498
## poblacion_ocupada_ensambladora_year29817   -25979462  111759507  -0.232
## poblacion_ocupada_ensambladora_year29949  -114226180   96786572  -1.180
## poblacion_ocupada_ensambladora_year3006       225081   91251256   0.002
## poblacion_ocupada_ensambladora_year30939   -25825311   91251256  -0.283
## poblacion_ocupada_ensambladora_year31       -3217378  111759507  -0.029
## poblacion_ocupada_ensambladora_year31326  -106568309   91251256  -1.168
## poblacion_ocupada_ensambladora_year31593  -104642318   91251256  -1.147
## poblacion_ocupada_ensambladora_year3167     -1798870   91251256  -0.020
## poblacion_ocupada_ensambladora_year31902  -121670560   91251256  -1.333
## poblacion_ocupada_ensambladora_year32058   -33656603   96786572  -0.348
## poblacion_ocupada_ensambladora_year32214    15554329   91251256   0.170
## poblacion_ocupada_ensambladora_year32397    37768179   91251256   0.414
## poblacion_ocupada_ensambladora_year32737   -53610402   91251256  -0.588
## poblacion_ocupada_ensambladora_year33776   215286084   91251256   2.359
## poblacion_ocupada_ensambladora_year34166   -94222870  111759507  -0.843
## poblacion_ocupada_ensambladora_year34184   -20954762   96786572  -0.217
## poblacion_ocupada_ensambladora_year3467      -904444   91251256  -0.010
## poblacion_ocupada_ensambladora_year35667   -69484094   91251256  -0.761
## poblacion_ocupada_ensambladora_year35925     5486149   96786572   0.057
## poblacion_ocupada_ensambladora_year36108   151827074   91251256   1.664
## poblacion_ocupada_ensambladora_year3639           NA         NA      NA
## poblacion_ocupada_ensambladora_year36416   -61548729  111759507  -0.551
## poblacion_ocupada_ensambladora_year3658    -43946892   91251256  -0.482
## poblacion_ocupada_ensambladora_year367       9654679   91251256   0.106
## poblacion_ocupada_ensambladora_year37632    38184829   91251256   0.418
## poblacion_ocupada_ensambladora_year37833    75736097   91251256   0.830
## poblacion_ocupada_ensambladora_year3798     -6966401   91251256  -0.076
## poblacion_ocupada_ensambladora_year38       -4404019   96786572  -0.046
## poblacion_ocupada_ensambladora_year38917  -117612533   91251256  -1.289
## poblacion_ocupada_ensambladora_year3903     -2301816   91251256  -0.025
## poblacion_ocupada_ensambladora_year4011    -17089163   91251256  -0.187
## poblacion_ocupada_ensambladora_year4036    -18221227   91251256  -0.200
## poblacion_ocupada_ensambladora_year40376    77445857   96786572   0.800
## poblacion_ocupada_ensambladora_year40801   -29163382   91251256  -0.320
## poblacion_ocupada_ensambladora_year41376   -27715009   91251256  -0.304
## poblacion_ocupada_ensambladora_year4155     -8749699   91251256  -0.096
## poblacion_ocupada_ensambladora_year4164   -108398680   91251256  -1.188
## poblacion_ocupada_ensambladora_year42428    -7362946   91251256  -0.081
## poblacion_ocupada_ensambladora_year447         75389   96786572   0.001
## poblacion_ocupada_ensambladora_year45674   -68623977   91251256  -0.752
## poblacion_ocupada_ensambladora_year45735    -6458650   91251256  -0.071
## poblacion_ocupada_ensambladora_year4615    293862359  111759507   2.629
## poblacion_ocupada_ensambladora_year46197   -46607356   91251256  -0.511
## poblacion_ocupada_ensambladora_year4650    -10890470   91251256  -0.119
## poblacion_ocupada_ensambladora_year47540   -16067982   91251256  -0.176
## poblacion_ocupada_ensambladora_year48229    31896093   91251256   0.350
## poblacion_ocupada_ensambladora_year48921   -91225168   91251256  -1.000
## poblacion_ocupada_ensambladora_year49658   -34749319  111759507  -0.311
## poblacion_ocupada_ensambladora_year5022     -3932948  111759507  -0.035
## poblacion_ocupada_ensambladora_year50292    -9813744   91251256  -0.108
## poblacion_ocupada_ensambladora_year5078     -3216880   91251256  -0.035
## poblacion_ocupada_ensambladora_year5096   -101087692   91251256  -1.108
## poblacion_ocupada_ensambladora_year50998   -20268445  111759507  -0.181
## poblacion_ocupada_ensambladora_year513       -274024   91251256  -0.003
## poblacion_ocupada_ensambladora_year52        -643859  111759507  -0.006
## poblacion_ocupada_ensambladora_year528      -2590548   91251256  -0.028
## poblacion_ocupada_ensambladora_year52931   -25848730   91251256  -0.283
## poblacion_ocupada_ensambladora_year542       -347818   91251256  -0.004
## poblacion_ocupada_ensambladora_year5455    -45699225   91251256  -0.501
## poblacion_ocupada_ensambladora_year5523     -5647738   91251256  -0.062
## poblacion_ocupada_ensambladora_year5628     52901970   91251256   0.580
## poblacion_ocupada_ensambladora_year589       1159688   91251256   0.013
## poblacion_ocupada_ensambladora_year59620   -48338233   96786572  -0.499
## poblacion_ocupada_ensambladora_year6014      2633896   91251256   0.029
## poblacion_ocupada_ensambladora_year604     -19689796   91251256  -0.216
## poblacion_ocupada_ensambladora_year6077    -21888684   91251256  -0.240
## poblacion_ocupada_ensambladora_year6144    -79169552   91251256  -0.868
## poblacion_ocupada_ensambladora_year6165     -1511709   96786572  -0.016
## poblacion_ocupada_ensambladora_year645     121634327   96786572   1.257
## poblacion_ocupada_ensambladora_year65410   -23297724   91251256  -0.255
## poblacion_ocupada_ensambladora_year658      -1402906   96786572  -0.014
## poblacion_ocupada_ensambladora_year6783    -22234167   91251256  -0.244
## poblacion_ocupada_ensambladora_year7005     67293287   91251256   0.737
## poblacion_ocupada_ensambladora_year7010      1938695   91251256   0.021
## poblacion_ocupada_ensambladora_year7161      8678999   91251256   0.095
## poblacion_ocupada_ensambladora_year7357      1422081   91251256   0.016
## poblacion_ocupada_ensambladora_year74914   -59645793   91251256  -0.654
## poblacion_ocupada_ensambladora_year7497     -4275771   91251256  -0.047
## poblacion_ocupada_ensambladora_year7538    -18424627  111759507  -0.165
## poblacion_ocupada_ensambladora_year76042  -114231092  111759507  -1.022
## poblacion_ocupada_ensambladora_year7608     29441648   96786572   0.304
## poblacion_ocupada_ensambladora_year76195    82961075   91251256   0.909
## poblacion_ocupada_ensambladora_year7631    -12884346  111759507  -0.115
## poblacion_ocupada_ensambladora_year7694    -48819924   91251256  -0.535
## poblacion_ocupada_ensambladora_year7695    -69773414   91251256  -0.765
## poblacion_ocupada_ensambladora_year7697      8339266   91251256   0.091
## poblacion_ocupada_ensambladora_year7710    -43854614   91251256  -0.481
## poblacion_ocupada_ensambladora_year781     -12619850   91251256  -0.138
## poblacion_ocupada_ensambladora_year786     -23329874   91251256  -0.256
## poblacion_ocupada_ensambladora_year7889      7014715   91251256   0.077
## poblacion_ocupada_ensambladora_year8134    -65589088   91251256  -0.719
## poblacion_ocupada_ensambladora_year82050   -23110587   96786572  -0.239
## poblacion_ocupada_ensambladora_year83186   -19096394   91251256  -0.209
## poblacion_ocupada_ensambladora_year8415    -27008420   91251256  -0.296
## poblacion_ocupada_ensambladora_year84649   -55353682   91251256  -0.607
## poblacion_ocupada_ensambladora_year8538     -8057359   91251256  -0.088
## poblacion_ocupada_ensambladora_year8589     39108540   96786572   0.404
## poblacion_ocupada_ensambladora_year8763    135729108   91251256   1.487
## poblacion_ocupada_ensambladora_year915       -688053   91251256  -0.008
## poblacion_ocupada_ensambladora_year9218     -5708698   96786572  -0.059
## poblacion_ocupada_ensambladora_year9264    -32598664   91251256  -0.357
## poblacion_ocupada_ensambladora_year93703   -96097287   91251256  -1.053
## poblacion_ocupada_ensambladora_year9692    -24590049   91251256  -0.269
## poblacion_ocupada_ensambladora_year9849    -92408345   91251256  -1.013
## poblacion_ocupada_ensambladora_year990       -189413   91251256  -0.002
##                                           Pr(>|t|)    
## (Intercept)                               7.91e-05 ***
## estadoBaja California                     0.460816    
## estadoCampeche                            0.004987 ** 
## estadoChihuahua                           0.000425 ***
## estadoCiudad de Mexico                    5.41e-07 ***
## estadoCoahuila de Zaragoza                 < 2e-16 ***
## estadoColima                              0.005002 ** 
## estadoDurango                             0.025336 *  
## estadoEstado de Mexico                    0.731814    
## estadoGuanajuato                          5.19e-08 ***
## estadoHidalgo                             0.005965 ** 
## estadoJalisco                             0.375793    
## estadoMorelos                             0.012071 *  
## estadoNuevo Leon                          1.48e-05 ***
## estadoPuebla                              2.93e-07 ***
## estadoQueretaro                           1.41e-10 ***
## estadoQuintana Roo                        0.001215 ** 
## estadoSan Luis Potosi                     0.266626    
## estadoSonora                              0.042535 *  
## estadoTamaulipas                          0.006944 ** 
## estadoTlaxcala                            0.012781 *  
## estadoVeracruz de Ignacio de la Llave     0.007983 ** 
## estadoYucatan                             0.005001 ** 
## estadoZacatecas                           0.009008 ** 
## exportaciones_anual10141642000            2.20e-11 ***
## exportaciones_anual10314836000            0.008108 ** 
## exportaciones_anual10398672000            0.390040    
## exportaciones_anual10400467000            0.019577 *  
## exportaciones_anual10478612000            0.013343 *  
## exportaciones_anual10594592000            3.45e-12 ***
## exportaciones_anual10701591000            0.058131 .  
## exportaciones_anual11146761000            0.000788 ***
## exportaciones_anual1116042000             0.999555    
## exportaciones_anual1119625000             0.999858    
## exportaciones_anual11227331000            0.033364 *  
## exportaciones_anual11449692000            0.568943    
## exportaciones_anual1165750000             0.089097 .  
## exportaciones_anual11738889000            0.000509 ***
## exportaciones_anual11794073000            0.377462    
## exportaciones_anual12035000               0.999764    
## exportaciones_anual12044484000            0.659376    
## exportaciones_anual1238308000             0.977303    
## exportaciones_anual1262654000             0.999673    
## exportaciones_anual1278536000             0.745031    
## exportaciones_anual12868798000            0.096335 .  
## exportaciones_anual1301171000             0.948587    
## exportaciones_anual1307252000             0.757835    
## exportaciones_anual1310801000             0.784289    
## exportaciones_anual1318941000             0.963832    
## exportaciones_anual1323153000             0.954363    
## exportaciones_anual13360587000            0.019778 *  
## exportaciones_anual13514349000            7.01e-07 ***
## exportaciones_anual13664629000            0.122623    
## exportaciones_anual1379964000             0.793816    
## exportaciones_anual14009625000            0.415017    
## exportaciones_anual1428633000             0.969828    
## exportaciones_anual1440918000             0.855340    
## exportaciones_anual1448674000             0.920153    
## exportaciones_anual14512000               0.999881    
## exportaciones_anual1460627000             0.027060 *  
## exportaciones_anual1460865000             0.929814    
## exportaciones_anual1470940000             0.999583    
## exportaciones_anual15019152000            8.35e-11 ***
## exportaciones_anual15120233000            0.723833    
## exportaciones_anual15294350000            0.069948 .  
## exportaciones_anual15531676000            0.238673    
## exportaciones_anual15611884000            0.406936    
## exportaciones_anual16121000               0.999751    
## exportaciones_anual1654784000             0.489295    
## exportaciones_anual16642906000            0.717893    
## exportaciones_anual1672357000             0.495908    
## exportaciones_anual16837910000            5.59e-08 ***
## exportaciones_anual16895883000            0.207333    
## exportaciones_anual17204369000            0.007015 ** 
## exportaciones_anual1721651000             0.952264    
## exportaciones_anual1726504000             0.948901    
## exportaciones_anual17332223000            0.300118    
## exportaciones_anual17443597000            0.261214    
## exportaciones_anual1752495000             0.492209    
## exportaciones_anual17544423000            0.138515    
## exportaciones_anual17547974000            1.53e-06 ***
## exportaciones_anual17735407000            0.254083    
## exportaciones_anual17877862000            0.907433    
## exportaciones_anual1813156000             0.027561 *  
## exportaciones_anual18601992000            0.336980    
## exportaciones_anual1861966000             0.493199    
## exportaciones_anual18687648000            0.786756    
## exportaciones_anual18737712000            0.175811    
## exportaciones_anual18985000               0.999939    
## exportaciones_anual191993000                    NA    
## exportaciones_anual19737684000            0.391870    
## exportaciones_anual19840531000            0.031101 *  
## exportaciones_anual19863200000            0.012341 *  
## exportaciones_anual20010001000            0.746897    
## exportaciones_anual20026441000            0.128721    
## exportaciones_anual20093245000            0.563885    
## exportaciones_anual20335098000            0.515806    
## exportaciones_anual20787831000            0.053454 .  
## exportaciones_anual21133618000            0.896160    
## exportaciones_anual2127000000             0.559867    
## exportaciones_anual2128076000             0.124878    
## exportaciones_anual21392726000            0.351536    
## exportaciones_anual21659640000            0.761275    
## exportaciones_anual22099835000            0.123811    
## exportaciones_anual2242354000             0.957630    
## exportaciones_anual22472408000            0.285657    
## exportaciones_anual22985164000            0.839923    
## exportaciones_anual2299343000             0.953889    
## exportaciones_anual2301925000                   NA    
## exportaciones_anual2302851000             0.000191 ***
## exportaciones_anual23360290000            0.336644    
## exportaciones_anual2376795000             0.954388    
## exportaciones_anual24048744000            0.001074 ** 
## exportaciones_anual2452302000             7.69e-07 ***
## exportaciones_anual24926226000            0.826719    
## exportaciones_anual25065798000            0.108328    
## exportaciones_anual25504680000            0.264642    
## exportaciones_anual25507316000            0.978798    
## exportaciones_anual26300102000            0.638999    
## exportaciones_anual2630544000             0.001629 ** 
## exportaciones_anual2632148000             0.873109    
## exportaciones_anual2667126000             0.779983    
## exportaciones_anual26736210000            0.453803    
## exportaciones_anual2684823000             0.851311    
## exportaciones_anual2705297000             3.32e-07 ***
## exportaciones_anual27314741000            0.235717    
## exportaciones_anual2737230000             0.726566    
## exportaciones_anual27397995000            0.660314    
## exportaciones_anual2760694000             0.885648    
## exportaciones_anual2793509000             0.932554    
## exportaciones_anual2873522000             0.985551    
## exportaciones_anual2880494000             0.771551    
## exportaciones_anual29130161000            0.385196    
## exportaciones_anual2946392000             0.975096    
## exportaciones_anual3026698000             0.986198    
## exportaciones_anual30529987000            0.112850    
## exportaciones_anual3086705000             0.875644    
## exportaciones_anual3086747000             0.968443    
## exportaciones_anual3141633000             0.980395    
## exportaciones_anual31513013000            0.020031 *  
## exportaciones_anual3157991000             0.930865    
## exportaciones_anual32177305000            0.029761 *  
## exportaciones_anual3325166000             0.962159    
## exportaciones_anual3402758000             0.733918    
## exportaciones_anual34511011000            0.002198 ** 
## exportaciones_anual34522156000            0.179426    
## exportaciones_anual34590332000            0.595705    
## exportaciones_anual34838926000            5.95e-12 ***
## exportaciones_anual3490783000             0.763448    
## exportaciones_anual35002851000            0.038256 *  
## exportaciones_anual35997280000            0.060790 .  
## exportaciones_anual36004725000            0.048844 *  
## exportaciones_anual36251770000            1.84e-09 ***
## exportaciones_anual36315716000            0.043994 *  
## exportaciones_anual3657768000             0.976793    
## exportaciones_anual37699563000            2.51e-08 ***
## exportaciones_anual3791586000             0.760401    
## exportaciones_anual38441996000            0.069528 .  
## exportaciones_anual38572482000            0.000247 ***
## exportaciones_anual38950677000            4.00e-07 ***
## exportaciones_anual39615279000            0.002951 ** 
## exportaciones_anual39857053000            0.039256 *  
## exportaciones_anual39896454000            0.050207 .  
## exportaciones_anual40659059000            0.140168    
## exportaciones_anual41034808000            3.96e-06 ***
## exportaciones_anual42396951000            0.289185    
## exportaciones_anual4339856000             0.880619    
## exportaciones_anual44961569000            1.01e-11 ***
## exportaciones_anual47659461000            2.58e-05 ***
## exportaciones_anual4862567000             0.948547    
## exportaciones_anual52231000               0.999894    
## exportaciones_anual522839000              0.994734    
## exportaciones_anual5352788000             0.918017    
## exportaciones_anual5362863000             0.890841    
## exportaciones_anual582973000              0.999327    
## exportaciones_anual587504000              0.057760 .  
## exportaciones_anual606131000              0.068173 .  
## exportaciones_anual6367193000             0.906729    
## exportaciones_anual6697248000             0.923728    
## exportaciones_anual716061000              0.999850    
## exportaciones_anual722027000              0.943763    
## exportaciones_anual726530000              0.071212 .  
## exportaciones_anual729883000              0.002790 ** 
## exportaciones_anual735262000              0.997971    
## exportaciones_anual7830019000             0.559335    
## exportaciones_anual7870962000             0.506361    
## exportaciones_anual790859000              0.890237    
## exportaciones_anual80907000               0.999744    
## exportaciones_anual820169000              0.138633    
## exportaciones_anual8466008000             0.890474    
## exportaciones_anual8476833000             0.014218 *  
## exportaciones_anual8495444000             0.542336    
## exportaciones_anual8534000                0.999930    
## exportaciones_anual871638000              0.250445    
## exportaciones_anual8829410000             0.675432    
## exportaciones_anual9147776000             0.004843 ** 
## exportaciones_anual9372970000             1.38e-11 ***
## exportaciones_anual9505026000             0.012374 *  
## exportaciones_anual9650719000             0.473976    
## exportaciones_anual9806397000             0.020721 *  
## poblacion_ocupada_ensambladora_year1004   0.995976    
## poblacion_ocupada_ensambladora_year1017   0.335352    
## poblacion_ocupada_ensambladora_year10714  0.694570    
## poblacion_ocupada_ensambladora_year1075   0.999692    
## poblacion_ocupada_ensambladora_year10767  0.969271    
## poblacion_ocupada_ensambladora_year11050  0.289581    
## poblacion_ocupada_ensambladora_year11361  0.547670    
## poblacion_ocupada_ensambladora_year11806  0.962059    
## poblacion_ocupada_ensambladora_year12073  0.974294    
## poblacion_ocupada_ensambladora_year12094  0.477631    
## poblacion_ocupada_ensambladora_year12217  0.945103    
## poblacion_ocupada_ensambladora_year124585 0.686575    
## poblacion_ocupada_ensambladora_year1247   0.997523    
## poblacion_ocupada_ensambladora_year12650  0.990566    
## poblacion_ocupada_ensambladora_year12836  0.924345    
## poblacion_ocupada_ensambladora_year13072  0.867499    
## poblacion_ocupada_ensambladora_year13538  0.810777    
## poblacion_ocupada_ensambladora_year13866  0.660641    
## poblacion_ocupada_ensambladora_year13927  0.989924    
## poblacion_ocupada_ensambladora_year13995  0.997355    
## poblacion_ocupada_ensambladora_year14221  0.349891    
## poblacion_ocupada_ensambladora_year144    0.999835    
## poblacion_ocupada_ensambladora_year15136  0.999400    
## poblacion_ocupada_ensambladora_year15762  0.646041    
## poblacion_ocupada_ensambladora_year15901  0.532934    
## poblacion_ocupada_ensambladora_year1601   0.431172    
## poblacion_ocupada_ensambladora_year1629   0.457714    
## poblacion_ocupada_ensambladora_year16844  0.971524    
## poblacion_ocupada_ensambladora_year1751   0.582365    
## poblacion_ocupada_ensambladora_year17726  0.827472    
## poblacion_ocupada_ensambladora_year1776   0.297516    
## poblacion_ocupada_ensambladora_year17790  0.992263    
## poblacion_ocupada_ensambladora_year17806  0.170398    
## poblacion_ocupada_ensambladora_year17876  0.638457    
## poblacion_ocupada_ensambladora_year18197  0.940843    
## poblacion_ocupada_ensambladora_year1827   0.974427    
## poblacion_ocupada_ensambladora_year18338  0.992925    
## poblacion_ocupada_ensambladora_year186    0.920058    
## poblacion_ocupada_ensambladora_year1890   0.999533    
## poblacion_ocupada_ensambladora_year19056  0.994086    
## poblacion_ocupada_ensambladora_year19219  0.997279    
## poblacion_ocupada_ensambladora_year19286  0.860418    
## poblacion_ocupada_ensambladora_year1945   0.891410    
## poblacion_ocupada_ensambladora_year19522  0.054893 .  
## poblacion_ocupada_ensambladora_year20047  0.980754    
## poblacion_ocupada_ensambladora_year217    0.998757    
## poblacion_ocupada_ensambladora_year22383  0.954300    
## poblacion_ocupada_ensambladora_year2252   0.998266    
## poblacion_ocupada_ensambladora_year2275   0.993723    
## poblacion_ocupada_ensambladora_year22783  0.849712    
## poblacion_ocupada_ensambladora_year23106  0.563332    
## poblacion_ocupada_ensambladora_year23160  0.175043    
## poblacion_ocupada_ensambladora_year23209  0.882294    
## poblacion_ocupada_ensambladora_year23991  0.995820    
## poblacion_ocupada_ensambladora_year25113  0.617970    
## poblacion_ocupada_ensambladora_year25660  0.819201    
## poblacion_ocupada_ensambladora_year25840  0.970460    
## poblacion_ocupada_ensambladora_year26248  0.920086    
## poblacion_ocupada_ensambladora_year2695   0.884103    
## poblacion_ocupada_ensambladora_year26950  0.369464    
## poblacion_ocupada_ensambladora_year27190  0.730714    
## poblacion_ocupada_ensambladora_year2720   0.992159    
## poblacion_ocupada_ensambladora_year27286  0.826817    
## poblacion_ocupada_ensambladora_year27319  0.925141    
## poblacion_ocupada_ensambladora_year281    0.998521    
## poblacion_ocupada_ensambladora_year28299  0.529148    
## poblacion_ocupada_ensambladora_year28505  0.825800    
## poblacion_ocupada_ensambladora_year28631  0.879747    
## poblacion_ocupada_ensambladora_year29188  0.134802    
## poblacion_ocupada_ensambladora_year29560  0.618750    
## poblacion_ocupada_ensambladora_year29817  0.816331    
## poblacion_ocupada_ensambladora_year29949  0.238808    
## poblacion_ocupada_ensambladora_year3006   0.998033    
## poblacion_ocupada_ensambladora_year30939  0.777351    
## poblacion_ocupada_ensambladora_year31     0.977051    
## poblacion_ocupada_ensambladora_year31326  0.243740    
## poblacion_ocupada_ensambladora_year31593  0.252347    
## poblacion_ocupada_ensambladora_year3167   0.984284    
## poblacion_ocupada_ensambladora_year31902  0.183369    
## poblacion_ocupada_ensambladora_year32058  0.728265    
## poblacion_ocupada_ensambladora_year32214  0.864760    
## poblacion_ocupada_ensambladora_year32397  0.679232    
## poblacion_ocupada_ensambladora_year32737  0.557283    
## poblacion_ocupada_ensambladora_year33776  0.018915 *  
## poblacion_ocupada_ensambladora_year34166  0.399814    
## poblacion_ocupada_ensambladora_year34184  0.828733    
## poblacion_ocupada_ensambladora_year3467   0.992098    
## poblacion_ocupada_ensambladora_year35667  0.446947    
## poblacion_ocupada_ensambladora_year35925  0.954833    
## poblacion_ocupada_ensambladora_year36108  0.097130 .  
## poblacion_ocupada_ensambladora_year3639         NA    
## poblacion_ocupada_ensambladora_year36416  0.582209    
## poblacion_ocupada_ensambladora_year3658   0.630419    
## poblacion_ocupada_ensambladora_year367    0.915805    
## poblacion_ocupada_ensambladora_year37632  0.675895    
## poblacion_ocupada_ensambladora_year37833  0.407177    
## poblacion_ocupada_ensambladora_year3798   0.939194    
## poblacion_ocupada_ensambladora_year38     0.963735    
## poblacion_ocupada_ensambladora_year38917  0.198374    
## poblacion_ocupada_ensambladora_year3903   0.979891    
## poblacion_ocupada_ensambladora_year4011   0.851564    
## poblacion_ocupada_ensambladora_year4036   0.841857    
## poblacion_ocupada_ensambladora_year40376  0.424209    
## poblacion_ocupada_ensambladora_year40801  0.749486    
## poblacion_ocupada_ensambladora_year41376  0.761538    
## poblacion_ocupada_ensambladora_year4155   0.923672    
## poblacion_ocupada_ensambladora_year4164   0.235754    
## poblacion_ocupada_ensambladora_year42428  0.935740    
## poblacion_ocupada_ensambladora_year447    0.999379    
## poblacion_ocupada_ensambladora_year45674  0.452587    
## poblacion_ocupada_ensambladora_year45735  0.943618    
## poblacion_ocupada_ensambladora_year4615   0.008969 ** 
## poblacion_ocupada_ensambladora_year46197  0.609875    
## poblacion_ocupada_ensambladora_year4650   0.905077    
## poblacion_ocupada_ensambladora_year47540  0.860339    
## poblacion_ocupada_ensambladora_year48229  0.726914    
## poblacion_ocupada_ensambladora_year48921  0.318209    
## poblacion_ocupada_ensambladora_year49658  0.756058    
## poblacion_ocupada_ensambladora_year5022   0.971949    
## poblacion_ocupada_ensambladora_year50292  0.914423    
## poblacion_ocupada_ensambladora_year5078   0.971900    
## poblacion_ocupada_ensambladora_year5096   0.268788    
## poblacion_ocupada_ensambladora_year50998  0.856202    
## poblacion_ocupada_ensambladora_year513    0.997606    
## poblacion_ocupada_ensambladora_year52     0.995407    
## poblacion_ocupada_ensambladora_year528    0.977370    
## poblacion_ocupada_ensambladora_year52931  0.777154    
## poblacion_ocupada_ensambladora_year542    0.996961    
## poblacion_ocupada_ensambladora_year5455   0.616854    
## poblacion_ocupada_ensambladora_year5523   0.950688    
## poblacion_ocupada_ensambladora_year5628   0.562501    
## poblacion_ocupada_ensambladora_year589    0.989868    
## poblacion_ocupada_ensambladora_year59620  0.617821    
## poblacion_ocupada_ensambladora_year6014   0.976991    
## poblacion_ocupada_ensambladora_year604    0.829301    
## poblacion_ocupada_ensambladora_year6077   0.810583    
## poblacion_ocupada_ensambladora_year6144   0.386268    
## poblacion_ocupada_ensambladora_year6165   0.987548    
## poblacion_ocupada_ensambladora_year645    0.209775    
## poblacion_ocupada_ensambladora_year65410  0.798646    
## poblacion_ocupada_ensambladora_year658    0.988444    
## poblacion_ocupada_ensambladora_year6783   0.807652    
## poblacion_ocupada_ensambladora_year7005   0.461392    
## poblacion_ocupada_ensambladora_year7010   0.983063    
## poblacion_ocupada_ensambladora_year7161   0.924287    
## poblacion_ocupada_ensambladora_year7357   0.987576    
## poblacion_ocupada_ensambladora_year74914  0.513814    
## poblacion_ocupada_ensambladora_year7497   0.962657    
## poblacion_ocupada_ensambladora_year7538   0.869159    
## poblacion_ocupada_ensambladora_year76042  0.307503    
## poblacion_ocupada_ensambladora_year7608   0.761181    
## poblacion_ocupada_ensambladora_year76195  0.363960    
## poblacion_ocupada_ensambladora_year7631   0.908291    
## poblacion_ocupada_ensambladora_year7694   0.593020    
## poblacion_ocupada_ensambladora_year7695   0.445059    
## poblacion_ocupada_ensambladora_year7697   0.927242    
## poblacion_ocupada_ensambladora_year7710   0.631137    
## poblacion_ocupada_ensambladora_year781    0.890093    
## poblacion_ocupada_ensambladora_year786    0.798374    
## poblacion_ocupada_ensambladora_year7889   0.938773    
## poblacion_ocupada_ensambladora_year8134   0.472808    
## poblacion_ocupada_ensambladora_year82050  0.811431    
## poblacion_ocupada_ensambladora_year83186  0.834369    
## poblacion_ocupada_ensambladora_year8415   0.767440    
## poblacion_ocupada_ensambladora_year84649  0.544544    
## poblacion_ocupada_ensambladora_year8538   0.929695    
## poblacion_ocupada_ensambladora_year8589   0.686433    
## poblacion_ocupada_ensambladora_year8763   0.137894    
## poblacion_ocupada_ensambladora_year915    0.993989    
## poblacion_ocupada_ensambladora_year9218   0.953003    
## poblacion_ocupada_ensambladora_year9264   0.721149    
## poblacion_ocupada_ensambladora_year93703  0.293092    
## poblacion_ocupada_ensambladora_year9692   0.787738    
## poblacion_ocupada_ensambladora_year9849   0.311983    
## poblacion_ocupada_ensambladora_year990    0.998345    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 79030000 on 318 degrees of freedom
## Multiple R-squared:  0.9716, Adjusted R-squared:  0.9384 
## F-statistic: 29.28 on 371 and 318 DF,  p-value: < 2.2e-16
regresion2 <- lm(Total_Produccion ~ Año + Produccion, data=bd5)
summary(regresion2)
## 
## Call:
## lm(formula = Total_Produccion ~ Año + Produccion, data = bd5)
## 
## Residuals:
##        Min         1Q     Median         3Q        Max 
## -156662104   -2346480    -288323     745268   98830383 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  2.083e+09  5.845e+08   3.563 0.000400 ***
## Año         -1.031e+06  2.896e+05  -3.561 0.000402 ***
## Produccion   5.394e+00  7.845e-02  68.757  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 11410000 on 531 degrees of freedom
## Multiple R-squared:  0.899,  Adjusted R-squared:  0.8986 
## F-statistic:  2364 on 2 and 531 DF,  p-value: < 2.2e-16
bd5 <- data.frame(Año=2022, Produccion= 170000000)
predict(regresion2,bd5)
##         1 
## 914196926
industria<- data.frame(Año=2022, estado= 79030000)
predict(regresion1,industriaA)
##            1            2            3            4            5            6 
## 2.978089e+08 1.809689e+08 6.388928e+08 4.153069e+08 4.243868e+08 2.395458e+06 
##            7            8            9           10           11           12 
## 5.994641e+08 4.905180e+05 7.319794e+07 1.618830e+08 7.197987e+06 5.515908e+08 
##           13           14           15           16           17           18 
## 2.385947e+08 7.192705e+08 1.236300e+04 1.715854e+08 1.383909e+08 4.729994e+08 
##           19           20           21           22           23           24 
## 5.589170e+06 2.014946e+07 3.034567e+08 2.086839e+08 8.147177e+08 5.114042e+08 
##           25           26           27           28           29           30 
## 4.119192e+08 2.326830e+06 6.918724e+08 1.178571e+06 9.310212e+07 1.801043e+08 
##           31           32           33           34           35           36 
## 6.038299e+06 5.945070e+08 2.411853e+08 7.984401e+08 2.154400e+08 1.642163e+08 
##           37           38           39           40           41           42 
## 5.795677e+08 6.486612e+06 6.989533e+04 1.872738e+07 3.034567e+08 2.086839e+08 
##           43           44           45           46           47           48 
## 8.147177e+08 5.114042e+08 4.119192e+08 2.326830e+06 6.918724e+08 1.178571e+06 
##           49           50           51           52           53           54 
## 9.310212e+07 1.801043e+08 6.038299e+06 5.945070e+08 2.411853e+08 7.984401e+08 
##           55           56           57           58           59           60 
## 2.154400e+08 1.642163e+08 5.795677e+08 6.486612e+06 6.989533e+04 1.872738e+07 
##           61           62           63           64           65           66 
## 3.034567e+08 2.086839e+08 8.147177e+08 5.114042e+08 4.119192e+08 2.326830e+06 
##           67           68           69           70           71           72 
## 6.918724e+08 1.178571e+06 9.310212e+07 1.801043e+08 6.038299e+06 5.945070e+08 
##           73           74           75           76           77           78 
## 2.411853e+08 7.984401e+08 2.154400e+08 1.642163e+08 5.795677e+08 6.486612e+06 
##           79           80           81           82           83           84 
## 6.989533e+04 1.872738e+07 3.259911e+08 2.163084e+08 7.769376e+08 4.988012e+08 
##           85           86           87           88           89           90 
## 4.042302e+08 1.880684e+06 6.977456e+08 6.034980e+05 9.857252e+07 1.838890e+08 
##           91           92           93           94           95           96 
## 2.496621e+06 5.610027e+08 2.556678e+08 7.421530e+08 2.149628e+08 1.723038e+08 
##           97           98           99          100          101          102 
## 5.232511e+08 6.229040e+06 3.791600e+04 2.239717e+07 3.716903e+08 2.323764e+08 
##          103          104          105          106          107          108 
## 9.023201e+08 5.584470e+08 4.275601e+08 2.183370e+06 7.626215e+08 7.929107e+05 
##          109          110          111          112          113          114 
## 1.386720e+08 1.925612e+08 2.844439e+06 6.850325e+08 2.682877e+08 8.432407e+08 
##          115          116          117          118          119          120 
## 2.660000e+04 2.282752e+08 2.037379e+08 5.768615e+08 8.027910e+06 3.741401e+06 
##          121          122          123          124          125          126 
## 7.312233e+04 2.667295e+07 3.716903e+08 2.323764e+08 9.023201e+08 5.584470e+08 
##          127          128          129          130          131          132 
## 4.275601e+08 2.183370e+06 7.626215e+08 7.929107e+05 1.386720e+08 1.925612e+08 
##          133          134          135          136          137          138 
## 2.844439e+06 6.850325e+08 2.682877e+08 8.432407e+08 2.282752e+08 2.037379e+08 
##          139          140          141          142          143          144 
## 5.768615e+08 8.027910e+06 3.741401e+06 7.312233e+04 2.667295e+07 3.716903e+08 
##          145          146          147          148          149          150 
## 2.323764e+08 9.023201e+08 5.584470e+08 4.275601e+08 2.183370e+06 7.626215e+08 
##          151          152          153          154          155          156 
## 7.929107e+05 1.386720e+08 1.925612e+08 2.844439e+06 6.850325e+08 2.682877e+08 
##          157          158          159          160          161          162 
## 8.432407e+08 2.282752e+08 2.037379e+08 5.768615e+08 8.027910e+06 7.312233e+04 
##          163          164          165          166          167          168 
## 2.667295e+07 3.679893e+08 2.170345e+08 8.602073e+08 5.211911e+08 4.349247e+08 
##          169          170          171          172          173          174 
## 6.066210e+05 7.417404e+08 7.569110e+05 2.140079e+08 1.892783e+08 4.361166e+06 
##          175          176          177          178          179          180 
## 6.000203e+08 2.705713e+08 7.923276e+08 2.195252e+08 2.066514e+08 5.788413e+08 
##          181          182          183          184          185          186 
## 8.885749e+06 3.495688e+06 1.605200e+04 3.200777e+07 3.767390e+08 2.268482e+08 
##          187          188          189          190          191          192 
## 1.714200e+04 9.456349e+08 5.402874e+08 5.433234e+08 1.759958e+06 7.987007e+08 
##          193          194          195          196          197          198 
## 7.569110e+05 2.275296e+08 1.829900e+08 5.764071e+06 6.086011e+08 2.614060e+08 
##          199          200          201          202          203          204 
## 8.142162e+08 2.108462e+08 2.239562e+08 5.997161e+08 1.118757e+07 3.956247e+06 
##          205          206          207          208          209          210 
## 1.582820e+05 3.006908e+07 3.767390e+08 2.268482e+08 9.456349e+08 5.402874e+08 
##          211          212          213          214          215          216 
## 5.433234e+08 1.759958e+06 7.987007e+08 2.275296e+08 1.829900e+08 6.086011e+08 
##          217          218          219          220          221          222 
## 2.614060e+08 8.142162e+08 2.108462e+08 2.239562e+08 5.997161e+08 1.118757e+07 
##          223          224          225          226          227          228 
## 3.956247e+06 1.582820e+05 3.006908e+07 3.767390e+08 2.268482e+08 9.456349e+08 
##          229          230          231          232          233          234 
## 5.402874e+08 5.433234e+08 1.759958e+06 7.987007e+08 7.569110e+05 2.275296e+08 
##          235          236          237          238          239          240 
## 1.829900e+08 5.764071e+06 6.086011e+08 2.614060e+08 8.142162e+08 2.108462e+08 
##          241          242          243          244          245          246 
## 2.239562e+08 5.997161e+08 1.118757e+07 3.956247e+06 1.582820e+05 3.006908e+07 
##          247          248          249          250          251          252 
## 3.777031e+08 2.075703e+08 9.253264e+08 5.102149e+08 5.025772e+08 2.041985e+06 
##          253          254          255          256          257          258 
## 7.967743e+08 2.123043e+08 1.728607e+08 3.475958e+06 6.651251e+08 2.774255e+08 
##          259          260          261          262          263          264 
## 7.814468e+08 2.301745e+08 2.067016e+08 5.486575e+08 1.141347e+07 5.536435e+06 
##          265          266          267          268          269          270 
## 1.779600e+05 2.826416e+07 3.693638e+08 2.140290e+08 9.948105e+08 5.470691e+08 
##          271          272          273          274          275          276 
## 5.977964e+08 2.718845e+06 8.516984e+08 1.419184e+06 1.922042e+08 1.899498e+08 
##          277          278          279          280          281          282 
## 6.403455e+06 6.273569e+08 2.883160e+08 8.302667e+08 1.083900e+04 2.266564e+08 
##          283          284          285          286          287          288 
## 1.911473e+08 6.172815e+08 1.231791e+07 5.536435e+06 1.025710e+05 2.391996e+07 
##          289          290          291          292          293          294 
## 3.693638e+08 2.140290e+08 9.948105e+08 5.470691e+08 5.977964e+08 2.718845e+06 
##          295          296          297          298          299          300 
## 8.516984e+08 1.419184e+06 1.922042e+08 1.899498e+08 6.403455e+06 6.273569e+08 
##          301          302          303          304          305          306 
## 2.883160e+08 8.302667e+08 2.266564e+08 1.911473e+08 6.172815e+08 1.231791e+07 
##          307          308          309          310          311          312 
## 5.536435e+06 2.391996e+07 3.693638e+08 2.140290e+08 9.948105e+08 5.470691e+08 
##          313          314          315          316          317          318 
## 5.977964e+08 2.718845e+06 8.516984e+08 1.419184e+06 1.922042e+08 1.899498e+08 
##          319          320          321          322          323          324 
## 6.403455e+06 6.273569e+08 2.883160e+08 8.302667e+08 2.266564e+08 1.911473e+08 
##          325          326          327          328          329          330 
## 6.172815e+08 1.231791e+07 5.536435e+06 1.025710e+05 2.391996e+07 3.884632e+08 
##          331          332          333          334          335          336 
## 1.933371e+08 9.567793e+08 5.536490e+08 8.012824e+08 4.890907e+06 7.955887e+08 
##          337          338          339          340          341          342 
## 1.519678e+06 2.141538e+08 2.102763e+08 4.769371e+08 3.058271e+08 8.353299e+08 
##          343          344          345          346          347          348 
## 2.088832e+08 2.889211e+08 6.105031e+08 1.257136e+07 7.311559e+06 2.350460e+07 
##          349          350          351          352          353          354 
## 3.814484e+08 2.191858e+08 1.038792e+09 6.090027e+08 8.732059e+08 1.166808e+07 
##          355          356          357          358          359          360 
## 8.375375e+08 1.793702e+06 2.049917e+08 2.183336e+08 3.674056e+07 5.344252e+08 
##          361          362          363          364          365          366 
## 3.938710e+08 8.623383e+08 2.744722e+08 3.180844e+08 7.281157e+08 1.953776e+07 
##          367          368          369          370          371          372 
## 7.311559e+06 3.914250e+04 2.458439e+07 3.814484e+08 2.191858e+08 1.038792e+09 
##          373          374          375          376          377          378 
## 6.090027e+08 8.732059e+08 1.166808e+07 8.375375e+08 1.793702e+06 2.049917e+08 
##          379          380          381          382          383          384 
## 2.183336e+08 3.674056e+07 5.344252e+08 3.938710e+08 8.623383e+08 3.054300e+04 
##          385          386          387          388          389          390 
## 2.744722e+08 3.180844e+08 7.281157e+08 1.953776e+07 7.311559e+06 2.458439e+07 
##          391          392          393          394          395          396 
## 3.814484e+08 2.191858e+08 1.038792e+09 6.090027e+08 8.732059e+08 1.166808e+07 
##          397          398          399          400          401          402 
## 8.375375e+08 1.793702e+06 2.049917e+08 2.183336e+08 3.674056e+07 5.344252e+08 
##          403          404          405          406          407          408 
## 3.938710e+08 8.623383e+08 3.054300e+04 2.744722e+08 3.180844e+08 7.281157e+08 
##          409          410          411          412          413          414 
## 1.953776e+07 7.311559e+06 3.914250e+04 2.458439e+07 3.744478e+08 2.104506e+08 
##          415          416          417          418          419          420 
## 9.729849e+08 5.552947e+08 8.425899e+08 1.692999e+07 7.397773e+08 1.383695e+06 
##          421          422          423          424          425          426 
## 2.029806e+08 2.236318e+08 2.925262e+07 4.972462e+08 4.105192e+08 8.353739e+08 
##          427          428          429          430          431          432 
## 1.907450e+04 3.000775e+08 2.786732e+08 6.524497e+08 2.492668e+07 9.206177e+06 
##          433          434          435          436          437          438 
## 3.621990e+05 2.318425e+07 3.966820e+08 3.016758e+08 1.077627e+09 5.785925e+08 
##          439          440          441          442          443          444 
## 8.622797e+08 3.298882e+07 7.925667e+08 1.364846e+06 1.891642e+08 2.482218e+08 
##          445          446          447          448          449          450 
## 1.959795e+07 6.189168e+08 4.544661e+08 9.051473e+08 1.907450e+04 3.326762e+08 
##          451          452          453          454          455          456 
## 2.860362e+08 6.990571e+08 2.814356e+07 9.206177e+06 1.371180e+05 2.399402e+07 
##          457          458          459          460          461          462 
## 3.966820e+08 3.016758e+08 1.077627e+09 5.785925e+08 8.622797e+08 3.298882e+07 
##          463          464          465          466          467          468 
## 7.925667e+08 1.364846e+06 1.891642e+08 2.482218e+08 1.959795e+07 6.189168e+08 
##          469          470          471          472          473          474 
## 4.544661e+08 9.051473e+08 1.907450e+04 3.326762e+08 2.860362e+08 6.990571e+08 
##          475          476          477          478          479          480 
## 2.814356e+07 9.206177e+06 1.371180e+05 2.399402e+07 3.966820e+08 3.016758e+08 
##          481          482          483          484          485          486 
## 1.077627e+09 5.785925e+08 8.622797e+08 3.298882e+07 7.925667e+08 1.364846e+06 
##          487          488          489          490          491          492 
## 1.891642e+08 2.482218e+08 1.959795e+07 6.189168e+08 4.544661e+08 9.051473e+08 
##          493          494          495          496          497          498 
## 1.907450e+04 3.326762e+08 2.860362e+08 6.990571e+08 2.814356e+07 9.206177e+06 
##          499          500          501          502          503          504 
## 1.371180e+05 2.399402e+07 3.312940e+08 2.955043e+08 1.037697e+09 5.220436e+08 
##          505          506          507          508          509          510 
## 7.518441e+08 5.001169e+07 7.901311e+08 1.785921e+06 1.841771e+08 2.534547e+08 
##          511          512          513          514          515          516 
## 5.715489e+08 4.925510e+08 8.725688e+08 3.553667e+04 3.350095e+08 2.308857e+08 
##          517          518          519          520          521          522 
## 6.270052e+08 2.966671e+07 8.570176e+06 3.104780e+05 2.530821e+07 2.640007e+08 
##          523          524          525          526          527          528 
## 2.636082e+08 8.224108e+08 4.390826e+08 7.518441e+08 4.780862e+07 6.383041e+08 
##          529          530          531          532          533          534 
## 2.504410e+06 1.641963e+08 2.032213e+08 5.260957e+08 4.396490e+08 7.368397e+08 
##          535          536          537          538          539          540 
## 2.991461e+08 1.927009e+08 5.512691e+08 2.703281e+07 8.570176e+06 2.499680e+07 
##          541          542          543          544          545          546 
## 2.640007e+08 2.636082e+08 8.224108e+08 4.390826e+08 7.518441e+08 4.780862e+07 
##          547          548          549          550          551          552 
## 6.383041e+08 2.504410e+06 1.641963e+08 2.032213e+08 5.260957e+08 4.396490e+08 
##          553          554          555          556          557          558 
## 7.368397e+08 3.553667e+04 2.991461e+08 1.927009e+08 5.512691e+08 2.703281e+07 
##          559          560          561          562          563          564 
## 8.570176e+06 3.671545e+05 2.499680e+07 2.640007e+08 2.636082e+08 8.224108e+08 
##          565          566          567          568          569          570 
## 4.390826e+08 7.518441e+08 4.780862e+07 6.383041e+08 2.504410e+06 1.641963e+08 
##          571          572          573          574          575          576 
## 2.032213e+08 1.845405e+07 5.260957e+08 4.396490e+08 7.368397e+08 3.553667e+04 
##          577          578          579          580          581          582 
## 2.991461e+08 1.927009e+08 5.512691e+08 2.703281e+07 8.570176e+06 3.671545e+05 
##          583          584          585          586          587          588 
## 2.499680e+07 3.049116e+08 2.988120e+08 9.942342e+08 1.271160e+05 5.157548e+08 
##          589          590          591          592          593          594 
## 7.951722e+08 6.493794e+07 7.885020e+08 3.710225e+06 1.609582e+08 2.318748e+08 
##          595          596          597          598          599          600 
## 6.202721e+08 5.678549e+08 9.124005e+08 3.469200e+04 3.409340e+08 2.001161e+08 
##          601          602          603          604          605          606 
## 6.056285e+08 3.101181e+07 7.017070e+06 6.160470e+05 3.420144e+07 2.754699e+08 
##          607          608          609          610          611          612 
## 3.471502e+08 1.108460e+09 5.388654e+08 6.735378e+08 5.938693e+07 7.920889e+08 
##          613          614          615          616          617          618 
## 3.889737e+06 1.819129e+08 2.349961e+08 6.539287e+08 5.735636e+08 8.732919e+08 
##          619          620          621          622          623          624 
## 3.469200e+04 3.570946e+08 1.226703e+08 6.001424e+08 3.252351e+07 1.142109e+07 
##          625          626          627          628          629          630 
## 8.590600e+05 3.074378e+07 2.754699e+08 3.471502e+08 1.108460e+09 5.388654e+08 
##          631          632          633          634          635          636 
## 6.735378e+08 5.938693e+07 7.920889e+08 3.889737e+06 1.819129e+08 2.349961e+08 
##          637          638          639          640          641          642 
## 2.599988e+07 6.539287e+08 5.735636e+08 8.732919e+08 3.469200e+04 3.570946e+08 
##          643          644          645          646          647          648 
## 1.226703e+08 6.001424e+08 3.252351e+07 1.142109e+07 3.074378e+07 3.031481e+08 
##          649          650          651          652          653          654 
## 3.638064e+08 1.299710e+09 5.998355e+08 8.046957e+08 6.434126e+07 8.837144e+08 
##          655          656          657          658          659          660 
## 6.001648e+06 1.909313e+08 2.592726e+08 7.135870e+08 1.195493e+09 9.387828e+08 
##          661          662          663          664          665          666 
## 4.101550e+04 4.136207e+08 6.817289e+07 5.581598e+08 3.225427e+07 1.445441e+07 
##          667          668          669          670          671          672 
## 4.680500e+05 2.342477e+07 3.160324e+08 3.985557e+08 1.467266e+09 7.140666e+08 
##          673          674          675          676          677          678 
## 8.877915e+08 6.492726e+07 9.395069e+08 6.645507e+06 2.169108e+08 2.776972e+08 
##          679          680          681          682          683          684 
## 3.388969e+07 8.078099e+08 9.016306e+08 1.057338e+09 4.101550e+04 4.404008e+08 
##          685          686          687          688          689          690 
## 8.844133e+07 6.197085e+08 3.618722e+07 1.767179e+07 1.208080e+05 2.234020e+07

Viendo los datos que se muestran en la regresión, se puede observar una alza en la significancia entre las variables de año y producción para nuestra dependiente. El año siendo negativa y la producción positiva en el impacto que deja.

El modelo anterior nos muestra cuánto se estima que se producirá a nivel global en la industria del cartón para 2022. De acuerdo a una producción total aproximada de 170 millones de cartón en 2021, se espera que en 2022 se produzcan 914,196,926. En este caso, el prónostico fue realizado al crear un nuevo ‘data frame’ y al implementar la función de ‘lm’, usada para crear análisis regresivos y predictivos.

Modelos de regresión lineal múltiple: Producción de cartón en 2022 para Estados Unidos y México

Importar base de datos (3)

bd6 <-read.csv("C:\\Users\\danyc\\Downloads\\externa_bd3 csv3 (1).csv")
summary(bd6)
##       Año            USA             MEX        
##  Min.   :2016   Min.   :48847   Min.   :103443  
##  1st Qu.:2017   1st Qu.:52256   1st Qu.:114333  
##  Median :2018   Median :54328   Median :124555  
##  Mean   :2018   Mean   :53932   Mean   :123036  
##  3rd Qu.:2020   3rd Qu.:55203   3rd Qu.:129521  
##  Max.   :2021   Max.   :59031   Max.   :143561
sum(is.na(bd6))
## [1] 0
summary(bd6)
##       Año            USA             MEX        
##  Min.   :2016   Min.   :48847   Min.   :103443  
##  1st Qu.:2017   1st Qu.:52256   1st Qu.:114333  
##  Median :2018   Median :54328   Median :124555  
##  Mean   :2018   Mean   :53932   Mean   :123036  
##  3rd Qu.:2020   3rd Qu.:55203   3rd Qu.:129521  
##  Max.   :2021   Max.   :59031   Max.   :143561
str(bd6)
## 'data.frame':    6 obs. of  3 variables:
##  $ Año: int  2016 2017 2018 2019 2020 2021
##  $ USA: num  48847 51672 54006 55387 54651 ...
##  $ MEX: num  103443 112231 120639 128471 129871 ...

Modelo de regresión múltiple: Producción de cartón en 2022: México

La predicción anterior nos arroja que hay un impacto positivo y significativo entre la variable Año y la variable dependiente. Esto significa que hay una predicción positiva de crecimiento acorde al año. De acuerdo a la producción total generada por México de 2016 a 2021 (740 M), el modelo pronóstico estima que en 2022 producirá 149,170.3. En la gráfica previa se muestra el punto de predicción. Si analizamos la producción de 2021 contra el pronóstico de 2022, se estima que la producción mexicana disminuirá. Podemos suponer que esto se debe a la deficiencia en la cadena de suministro global, así como factores económicos globales.

regresion3 <- lm(MEX ~ USA + Año, data=bd6)
summary(regresion3)
## 
## Call:
## lm(formula = MEX ~ USA + Año, data = bd6)
## 
## Residuals:
##      1      2      3      4      5      6 
##  574.6 -373.0 -664.0  478.2 -345.3  329.5 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)   
## (Intercept) -7.614e+06  1.010e+06  -7.540  0.00484 **
## USA          2.109e+00  2.749e-01   7.674  0.00460 **
## Año          3.777e+03  5.072e+02   7.446  0.00501 **
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 675 on 3 degrees of freedom
## Multiple R-squared:  0.9986, Adjusted R-squared:  0.9977 
## F-statistic:  1100 on 2 and 3 DF,  p-value: 5.023e-05
regresion3 <- lm(MEX ~ Año, data=bd6)
summary(regresion3)
## 
## Call:
## lm(formula = MEX ~ Año, data = bd6)
## 
## Residuals:
##       1       2       3       4       5       6 
##  -925.5   395.3  1336.2  1701.6 -4365.0  1857.6 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)    
## (Intercept) -1.495e+07  1.281e+06  -11.67 0.000308 ***
## Año          7.467e+03  6.347e+02   11.77 0.000299 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 2655 on 4 degrees of freedom
## Multiple R-squared:  0.9719, Adjusted R-squared:  0.9649 
## F-statistic: 138.4 on 1 and 4 DF,  p-value: 0.0002986
bd6 <- data.frame(Año=2022, Produccion= 740000)
predict(regresion3,bd6)
##        1 
## 149170.3
ggplot(bd6, aes(x=Año, y=Produccion))+
  geom_point() +
  geom_line(aes(y=Produccion), color="red", linetype="dashed") +
  geom_line(aes(y=Produccion), color="red", linetype="dashed") +
  geom_smooth(method=lm, formula=y~x, se=TRUE, level=0.95, col='blue', fill='pink2') +
  theme_light()
## geom_path: Each group consists of only one observation. Do you need to adjust
## the group aesthetic?
## geom_path: Each group consists of only one observation. Do you need to adjust
## the group aesthetic?

Modelos de regresión lineal múltiple: Producción de cartón en 2022 para Estados Unidos y México

Importar base de datos (3)

bd6 <-read.csv("C:\\Users\\danyc\\Downloads\\externa_bd3 csv3 (1).csv")
summary(bd6)
##       Año            USA             MEX        
##  Min.   :2016   Min.   :48847   Min.   :103443  
##  1st Qu.:2017   1st Qu.:52256   1st Qu.:114333  
##  Median :2018   Median :54328   Median :124555  
##  Mean   :2018   Mean   :53932   Mean   :123036  
##  3rd Qu.:2020   3rd Qu.:55203   3rd Qu.:129521  
##  Max.   :2021   Max.   :59031   Max.   :143561
sum(is.na(bd6))
## [1] 0
summary(bd6)
##       Año            USA             MEX        
##  Min.   :2016   Min.   :48847   Min.   :103443  
##  1st Qu.:2017   1st Qu.:52256   1st Qu.:114333  
##  Median :2018   Median :54328   Median :124555  
##  Mean   :2018   Mean   :53932   Mean   :123036  
##  3rd Qu.:2020   3rd Qu.:55203   3rd Qu.:129521  
##  Max.   :2021   Max.   :59031   Max.   :143561
str(bd6)
## 'data.frame':    6 obs. of  3 variables:
##  $ Año: int  2016 2017 2018 2019 2020 2021
##  $ USA: num  48847 51672 54006 55387 54651 ...
##  $ MEX: num  103443 112231 120639 128471 129871 ...

Modelos de regresión lineal múltiple: Producción de cartón en 2022: Estados Unidos

Para la predicción de Estados Unidos, vemos que habrá un incremento en la producción de cartón contra 2021. Sin embargo, al analizar la producción total de México contra la producción total de Estados Unidos, vemos que la mexicana es mucho mayor. Podemos suponer que esto se debe debido a la mano de obra económica del mercado mexicano.

De acuerdo a la predicción anterior, se ve un incremento positivo para la variable México con la variable dependiente, a diferencia del año que muestra un impacto menor y negativo, pero igualmente significativo.

regresion2 <- lm(USA ~ MEX + Año, data=bd6)
summary(regresion2)
## 
## Call:
## lm(formula = USA ~ MEX + Año, data = bd6)
## 
## Residuals:
##       1       2       3       4       5       6 
## -293.67  185.92  345.50 -187.61   63.41 -113.54 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)   
## (Intercept)  3.266e+06  8.915e+05   3.663   0.0352 * 
## MEX          4.511e-01  5.878e-02   7.674   0.0046 **
## Año         -1.619e+03  4.452e+02  -3.636   0.0358 * 
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 312.1 on 3 degrees of freedom
## Multiple R-squared:  0.9951, Adjusted R-squared:  0.9918 
## F-statistic: 304.3 on 2 and 3 DF,  p-value: 0.0003435
regresion2 <- lm(USA ~ Año, data=bd6)
summary(regresion2)
## 
## Call:
## lm(formula = USA ~ Año, data = bd6)
## 
## Residuals:
##       1       2       3       4       5       6 
##  -711.2   364.2   948.3   580.0 -1905.7   724.4 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)   
## (Intercept) -3477589.1   592456.5  -5.870  0.00421 **
## Año             1749.6      293.5   5.961  0.00398 **
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 1228 on 4 degrees of freedom
## Multiple R-squared:  0.8988, Adjusted R-squared:  0.8735 
## F-statistic: 35.53 on 1 and 4 DF,  p-value: 0.003977
bd6 <- data.frame(Año=2022, Produccion= 320000)
predict(regresion2,bd6)
##        1 
## 60055.85

Pronóstico

#install.packages("forecast")
library(forecast)

Pronosticar el desempeño de la industria automotriz (EUA y MEX) para los 3 periodos de tiempo.

#file.choose()
externo<- read.csv("C:\\Users\\danyc\\Downloads\\externa_bd3 csv3.csv")

Crear serie de tiempo

produccion_mexico<- c(externo$MEX)
produccion_usa<- c(externo$USA)
produccionm<-ts(data=produccion_mexico, start=c(2016,1), frequency=1)
produccionu<-ts(data=produccion_usa, start=c(2016,1), frequency=1)
produccionm
## Time Series:
## Start = 2016 
## End = 2021 
## Frequency = 1 
## [1] 103442.8 112230.6 120638.5 128470.9 129871.3 143560.9
produccionu
## Time Series:
## Start = 2016 
## End = 2021 
## Frequency = 1 
## [1] 48847.2 51672.2 54005.8 55387.1 54651.0 59030.7
modelom<- auto.arima(produccionm, D=1)
modelou<- auto.arima(produccionu, D=1)
modelom
## Series: produccionm 
## ARIMA(0,1,0) with drift 
## 
## Coefficients:
##          drift
##       8023.620
## s.e.  1752.032
## 
## sigma^2 = 19186921:  log likelihood = -48.46
## AIC=100.92   AICc=106.92   BIC=100.14
modelou
## Series: produccionu 
## ARIMA(0,1,0) 
## 
## sigma^2 = 7012061:  log likelihood = -46.5
## AIC=95   AICc=96.34   BIC=94.61
pronosticom <- forecast(modelom, level=c(95), h=4)
pronosticom
##      Point Forecast    Lo 95    Hi 95
## 2022       151584.5 142999.3 160169.7
## 2023       159608.1 147466.8 171749.5
## 2024       167631.8 152761.7 182501.8
## 2025       175655.4 158485.0 192825.8
plot(pronosticom)

pronosticou <- forecast(modelou, level=c(95), h=4)
pronosticou
##      Point Forecast    Lo 95    Hi 95
## 2022        59030.7 53840.66 64220.74
## 2023        59030.7 51690.87 66370.53
## 2024        59030.7 50041.28 68020.12
## 2025        59030.7 48650.61 69410.79
plot(pronosticou)

Pronosticar el desempeño de produccion de Form para los proximos 3 periodos de tiempo.

#file.choose()
formproduccion<- read.csv("C:\\Users\\danyc\\OneDrive - Instituto Tecnologico y de Estudios Superiores de Monterrey\\Desktop\\Form_produccionbaselimpia.csv")

Crear serie de tiempo

produccionform<- c(formproduccion$laminas_procesadas)
produccionf<-ts(data=produccionform, start=c(2022,7), end=c(2025, 12), frequency=12)

produccionf
##      Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
## 2022                           3   2   2   1   1   3
## 2023   2   5   5  10   5   1   5   7  12   4   7   1
## 2024  15   9   9   9  10  18  22  22   9  45  22  11
## 2025  22  11  11  21  11  11  11   6  11  11  11  11
modelof<- auto.arima(produccionf, D=1)

modelof
## Series: produccionf 
## ARIMA(2,1,0)(1,1,0)[12] 
## 
## Coefficients:
##           ar1      ar2     sar1
##       -0.7093  -0.3922  -0.6559
## s.e.   0.1707   0.1731   0.1338
## 
## sigma^2 = 79.45:  log likelihood = -106.7
## AIC=221.39   AICc=223.06   BIC=226.86
pronosticof <- forecast(modelof, level=c(95), h=3)
pronosticof
##          Point Forecast     Lo 95    Hi 95
## Jan 2026       16.15994 -1.310577 33.63046
## Feb 2026       10.94930 -7.244584 29.14318
## Mar 2026       12.23185 -7.267684 31.73139
plot(pronosticof)

Pronostico 2 FORM Bajas

#file.choose()
formbajas<- read.csv("C:\\Users\\danyc\\Downloads\\HR_Bajas 2.csv")

Crear serie de tiempo

bajasform<- c(formbajas$NO.DE.BAJAS)
bajasf<-ts(data=bajasform, start=c(2022,7), end=c(2025, 12), frequency=12)

bajasf
##      Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
## 2022                           5   6   7   8   9  11
## 2023  12  16  19  20  21  24  25  29  30  31  32  33
## 2024  34  43  70  80  82  83  84  85 110 129 130 145
## 2025 146 147 149 150 151 152 153 166 167 168 169 170
bmodelof<- auto.arima(bajasf, D=1)

bmodelof
## Series: bajasf 
## ARIMA(0,1,1)(0,1,0)[12] 
## 
## Coefficients:
##          ma1
##       0.3839
## s.e.  0.1814
## 
## sigma^2 = 118.8:  log likelihood = -109.99
## AIC=223.99   AICc=224.45   BIC=226.72
pronbaja <- forecast(bmodelof, level=c(95), h=3)
pronbaja
##          Point Forecast    Lo 95    Hi 95
## Jan 2026       165.2291 143.8665 186.5917
## Feb 2026       166.2291 129.7551 202.7030
## Mar 2026       168.2291 121.2787 215.1795
plot(pronbaja)

Describe los resultados

Realizamos una serie de tiempo tanto para la base de la industria automotriz como para la base de producción de FORM, este es enfocado a las laminas procesadas cada mes y en la industria es por año. Para poder realizar este Analisis de Resultado realizamos una grafica y un modelo de Predicción por medio de la función auto.arima. Gracias a esta función, le especificamos desde que Fecha empezará a obtener datos de la base de Datos y también colocamos la frecuencia, que se refiere a cómo se comporta, en cuestión a si se va a calcular por mes o por año. Así mismo, obtuvimos para la industria tanto en México como en EU, que son los países en los que se enfoca más FORM y obtengan mejor oportunidad de crecimiento. Al realizar este modelo calculamos para los próximos 3 periodos, en este caso para el 2025 y obtuvimos los siguientes resultados: - Industria Automotriz en México:

  1. Partiendo de un margen del 95%, queriendo decir, que este modelo es más preciso por lo que al ver la grafica obtenemos que tendrá un incremento constante en los próximos 3 años, partiendo del 2022.
  2. Este crecimiento de la industria automotriz en México se estima un crecimiento del 16% para 2025, lo que beneficia a FORM para continuar produciendo en el mercado Mexicano.
  • Industria Automotriz en Estados Unidos:

    1. Para 2022 el pronostico es de 59 mil, que este se puede mantener constante en los próximos 3 años hasta 2025
    2. Se obtiene un escenario optimista con la precisión del 95%, lo que quiere decir que para finales del 2025, puede estar igual en 59 mil o aumentar hasta los 69 mil. Esto indicaría que va en aumento año con año y terminaría el 2025 con un aumento del casi 20%. Lo que indicaría algo bueno para FORM, dandole oportunidad a aumentar su cartera de clientes dentro del mercado Estadounidense y teniendo un buen impacto de la industria para los próximos periodos.
  • Empresa FORM:

    1. Se hizo el pronostico por mes y dando un periodo hasta el 2026, partiendo del 2022 con 3 en cuanto a producción de laminas procesadas, se estima que este tenga un aumento constante, ademas de que entre el 2024 y 2025 tenga un punto de pique más alto, que posteriormente volverá a estabilizarse pero que se mantendrá constante entre los 10 a 20 en producción.
    2. Se pronostica que para el 2026 se tenga un 33 en producción del área de laminas procesadas, teniendo una precisión del 95% en un escenario optimista. Así mismo este se puede mantener constante en 10 o aumentar como se comentó anteriormente y este crecimiento a términos del 2026 tomando el escenario optimista, sería de poco mas del 90% lo que sería un gran aumento para FORM. También si fuera sin el 95% para inicios del 2026 serían 16 en producción con el 60% de aumento, lo que seguiría siendo algo importante para FORM.
  1. Se pronostica según el modelo realizado que las bajas de form irás incrementando cada vez más en los próximos 3 años, logrando así una tasa de rotación más alta de la que están considerando hoy en día, es por eso que se necesitarían hacer unos cambios preventivos para poder evitar ese tipo de tragedia que harían que FORM pierda dinero al tener que incurrir en una capacitación desde cero en lugar de cuidar a su personal actual.

K-Means

Cluster 1

Limpieza de datos y transformacion

Importar Base de Datos

file.choose()

Explorar datos

rh1<-rh %>% dplyr:: select(EDAD,DIAS.TRABAJADOS,SALARIO.DIARIO.IMSS,GENERO)
summary(rh1)
##       EDAD       DIAS.TRABAJADOS  SALARIO.DIARIO.IMSS    GENERO         
##  Min.   : 0.00   Min.   :  0.00   Min.   :151.6       Length:78         
##  1st Qu.:22.25   1st Qu.:  9.00   1st Qu.:180.7       Class :character  
##  Median :30.00   Median : 19.00   Median :180.7       Mode  :character  
##  Mean   :30.50   Mean   : 45.10   Mean   :174.3                         
##  3rd Qu.:36.00   3rd Qu.: 39.75   3rd Qu.:180.7                         
##  Max.   :52.00   Max.   :730.00   Max.   :183.7

Normalizar los datos

rh1_norm<-scale(rh1[2:3]) 

Numero Optimo de Clusters

fviz_nbclust(rh1_norm, kmeans, method="wss")+ # wss method considers total within sum of square
  geom_vline(xintercept=4, linetype=2)+           # optimal number of clusters is computed with the default method = "euclidean"
  labs(subtitle = "Elbow method")  

#file.choose()

Visualizar la info de clusters

rh1_cluster<-kmeans(rh1_norm,4)
rh1_cluster
## K-means clustering with 4 clusters of sizes 1, 17, 8, 52
## 
## Cluster means:
##   DIAS.TRABAJADOS SALARIO.DIARIO.IMSS
## 1       7.5323951           0.5246350
## 2       0.2712304          -1.8780410
## 3       0.6353722           0.4428101
## 4      -0.3312748           0.5357612
## 
## Clustering vector:
##  [1] 2 2 2 2 2 2 2 2 2 2 2 2 4 4 4 4 4 4 4 3 2 4 2 2 2 2 4 4 4 4 4 4 4 4 4 4 4 4
## [39] 4 4 4 4 4 4 4 3 4 4 3 3 3 1 4 4 3 4 4 4 4 4 4 4 4 4 4 4 4 3 3 4 4 4 4 4 4 4
## [77] 4 4
## 
## Within cluster sum of squares by cluster:
## [1] 0.000000 6.019937 3.270968 1.055662
##  (between_SS / total_SS =  93.3 %)
## 
## Available components:
## 
## [1] "cluster"      "centers"      "totss"        "withinss"     "tot.withinss"
## [6] "betweenss"    "size"         "iter"         "ifault"

Muestra que utilicemos 4 clusters para analizar y visualizar la información.

Visualizar Resultados

fviz_cluster(rh1_cluster,data=rh1_norm)

El primer cluster analiza la relación entre el salario diario IMSS y los días trabajados de los empleados que ya fueron dados de baja. En este caso, vemos que hay un impacto alto entre aquellos empleados que trabajaron de 2 a 8 días, pero tuvieron un salario diario bajo, mucho menor a 0 en la gráfica. Los otros dos resultados, se muestra que trabajaron menos días, pero al igual que el primer cluster explicado, tuvieron un salario muy bajo. Con estos tres, hay una correlación alta, significativa y negativa. Para el grupo de arriba, vemos que estos trabajaron un promedio de 2-3 días y tuvieron un salario diario muy alto. Podemos inferir que este grupo pertenece al área administrativa, que como vimos en análisis anteriores, son el grupo con un salario mucho más alto al resto.

rh2<-rh1
rh2$Clusters<-rh1_cluster$cluster
summary(rh2)
##       EDAD       DIAS.TRABAJADOS  SALARIO.DIARIO.IMSS    GENERO         
##  Min.   : 0.00   Min.   :  0.00   Min.   :151.6       Length:78         
##  1st Qu.:22.25   1st Qu.:  9.00   1st Qu.:180.7       Class :character  
##  Median :30.00   Median : 19.00   Median :180.7       Mode  :character  
##  Mean   :30.50   Mean   : 45.10   Mean   :174.3                         
##  3rd Qu.:36.00   3rd Qu.: 39.75   3rd Qu.:180.7                         
##  Max.   :52.00   Max.   :730.00   Max.   :183.7                         
##     Clusters    
##  Min.   :1.000  
##  1st Qu.:3.000  
##  Median :4.000  
##  Mean   :3.423  
##  3rd Qu.:4.000  
##  Max.   :4.000

Crear un dataset

rh3<-rh2 %>% group_by(Clusters) %>% summarise(SALARIO.DIARIO.IMSS=max(SALARIO.DIARIO.IMSS), DIAS.TRABAJADOS=mean(DIAS.TRABAJADOS)) %>% arrange(desc(SALARIO.DIARIO.IMSS))
summary(rh3)
##  SALARIO.DIARIO.IMSS DIAS.TRABAJADOS
##  Min.   :183.7       Min.   :45.1   
##  1st Qu.:183.7       1st Qu.:45.1   
##  Median :183.7       Median :45.1   
##  Mean   :183.7       Mean   :45.1   
##  3rd Qu.:183.7       3rd Qu.:45.1   
##  Max.   :183.7       Max.   :45.1

Agrupar clusters por nombre

rh2$Cluster_Names<-factor(rh2$Clusters,levels = c(1,2,3,4), 
                              labels=c("Bajo", "Promedio ", "Arriba del prom", "Alto"))
summary(rh2)
##       EDAD       DIAS.TRABAJADOS  SALARIO.DIARIO.IMSS    GENERO         
##  Min.   : 0.00   Min.   :  0.00   Min.   :151.6       Length:78         
##  1st Qu.:22.25   1st Qu.:  9.00   1st Qu.:180.7       Class :character  
##  Median :30.00   Median : 19.00   Median :180.7       Mode  :character  
##  Mean   :30.50   Mean   : 45.10   Mean   :174.3                         
##  3rd Qu.:36.00   3rd Qu.: 39.75   3rd Qu.:180.7                         
##  Max.   :52.00   Max.   :730.00   Max.   :183.7                         
##     Clusters             Cluster_Names
##  Min.   :1.000   Bajo           : 1   
##  1st Qu.:3.000   Promedio       :17   
##  Median :4.000   Arriba del prom: 8   
##  Mean   :3.423   Alto           :52   
##  3rd Qu.:4.000                        
##  Max.   :4.000

Muchos días trabajados y poco salario

Agrupar y dar resumen por nombres

rh4 <- rh2%>% group_by (Cluster_Names, GENERO) %>% dplyr:: summarize(DIAS.TRABAJADOS=max(DIAS.TRABAJADOS), 
                                                     SALARIO.DIARIO.IMSS =mean(SALARIO.DIARIO.IMSS),
                                                             Count=n())
## `summarise()` has grouped output by 'Cluster_Names'. You can override using the
## `.groups` argument.

Dar formato de tabla para enseñar la informacion de los clusters

clusters<-as.data.frame(rh4)
clusters
##     Cluster_Names    GENERO DIAS.TRABAJADOS SALARIO.DIARIO.IMSS Count
## 1            Bajo MASCULINO             730            180.6800     1
## 2       Promedio   FEMENINO             161            151.6100    10
## 3       Promedio  MASCULINO             169            151.6100     7
## 4 Arriba del prom  FEMENINO             251            180.0200     6
## 5 Arriba del prom MASCULINO              88            178.7000     2
## 6            Alto  FEMENINO              53            180.8151    37
## 7            Alto MASCULINO              33            180.8133    15

Graficar el no. de datos observados por nombre de clusters

ggplot(rh4,aes(x=reorder(Cluster_Names,Count),y=Count,fill=Cluster_Names)) +
  geom_bar(stat="identity")

De acuerdo a la clasificación de clusters, la gráfica anterior nos muestra el impacto y conteo de cada cluster dependiendo del grupo de baja analizado, es decir, vemos la relación entre días trabajados y salario diario, clasificando el conteo acorde a la cantidad de bajas obtenidas. En este caso, en la gráfica se muestra que aquellos que trabajaron más de 600 días y menos de 1900 días, obtuvieron un salario promedio de $500 pesos diario. Entra en la categoría de ‘bajo’, ya que sólo una persona obtuvo esta descripción. El promedio de las personas dadas de baja trabajaron más de 1900 días y obtuvieron un salario diario de $170 pesos. En la barra de ‘alto’ vemos a aquellos ex-empleados que trabajaron 421 días y tuvieron un salario diario de $150 pesos. Por último, vemos a aquellos ‘arriba del promedio’ y son aquellos que tabajaron un promedio de 455 días y tuvieron un salario diario de $180 pesos. Este último grupo es el que tuvo mayor conteo de personas, es decir, la mayoría de las bajas estuvieron laborando más de un año en FORM y tenían un salario diario de $180 pesos.

Ver Rangos

Rango de “Días trabajados” por nombre

ggplot(rh4, aes(x=Cluster_Names,y=DIAS.TRABAJADOS,fill= Cluster_Names,label=round(DIAS.TRABAJADOS,digits=2))) + 
  geom_col() + 
  geom_text()

La gráfica anterior nos presenta la cantidad de días trabajados de acuerdo a la clasificación explicada anteriormente de ‘bajo’, ‘promedio’, ‘arriba del promedio’ y ‘alto’. Con esto en mente, vemos que el promedio de los empleados juntaron un total de 1966 días trabajados, siguiéndole el grupo de ‘bajo’, los que laboraron un promedio de 628 días, luego ‘arriba del promedio’ que laboró 455 días y finalmente ‘alto’, que únicamente laboró 421 días. En todos los grupos, vemos que los empleados trabajaron por más de 1 año en FORM y ganaban un salario diario mayor a $150 pesos.

Ver el rango de Salario Diario

ggplot(rh4,aes(x=Cluster_Names,y=SALARIO.DIARIO.IMSS,fill= Cluster_Names,label=round(SALARIO.DIARIO.IMSS,digits=2))) + 
  geom_col() + 
  geom_text()

La gráfica anterior nos presenta la relación entre el salario diario IMSS y la clasificación explicada anteriormente de ‘bajo’, ‘promedio’, ‘arriba del promedio’ y ‘alto’. Con esto en mente, vemos que el segmento ‘bajo’ es el que tenía un salario más alto que la mayoría. El promedio ganaba un salario diario de $170,79 pesos, ‘arriba del promedio’ ganaba $180,54 pesos y el segmento ‘alto’ gabana un promedio de $151,61 pesos de salario diario. Esto denota una variabilidad alta y podemos suponer que esto se debía de acuerdo a las responsabilidades y puestos analizados.

Dispersion de Dias Trabajados

ggplot(rh2, aes(x=Cluster_Names, y=DIAS.TRABAJADOS, fill=Cluster_Names)) +
  geom_boxplot()+
  ggtitle("Dispersion of 'Días trabajados' by Clusters Names")

La gráfica anterior explica la dispersión de días trabajados de acuerdo a la clasificación explicada anteriormente de ‘bajo’, ‘promedio’, ‘arriba del promedio’ y ‘alto’. Con esto en mente, vemos que el grupo con mayor dispersión es ‘promedio’, pues hay una variabilidad más significativa en los datos de la cantidad de días trabajados, destacando la media de días trabajados, es decir, 1000 días. En el caso de ‘bajo’, hay una dispersión baja y poco variable. Para ‘arriba del promedio’, vemos que los puntos atípicos se salen del boxplot específico, lo cual quitarlos nos puede dar mayor claridad y visibilidad de la información. Para ‘alto’ se muestra una dispersión menor a ‘promedio’ y al igual que ‘arriba del promedio’, tiene aparición de puntos atípicos.

Dispersion de Salario diario

ggplot(rh2, aes(x=Cluster_Names, y=SALARIO.DIARIO.IMSS, fill=Cluster_Names)) +
  geom_boxplot()+
  ggtitle("Dispersion of 'Salario_Diario' by Clusters Names")

La gráfica anterior explica la dispersión de salario diario de acuerdo a la clasificación explicada anteriormente de ‘bajo’, ‘promedio’, ‘arriba del promedio’ y ‘alto’. ‘Bajo’ muestra un salario diario de $500 pesos, ‘promedio’ muestra un salario de $180 pesos aprox y puntos atípicos que podrían insinuar un salario menor, ‘arriba del promedio’ también muestra puntos atípicos. Sin embargo, todos se mantienen al igual que el dato anterior entre $170 y $180 pesos de salario diario, Finalmente, ‘alto’ muestra un salario diario abajo del promedio de aprox. $140 pesos.

Cluster 2

rhCluster2<-read.csv("C:\\Users\\danyc\\Downloads\\HR_Bajas 2.csv") 
summary(rhCluster2)
##   NO.DE.BAJAS      APELLIDOS            NOMBRE          FECHA.DE.NACIMIENTO
##  Min.   :  5.00   Length:78          Length:78          Min.   :25585      
##  1st Qu.: 49.75   Class :character   Class :character   1st Qu.:31751      
##  Median :167.50   Mode  :character   Mode  :character   Median :33797      
##  Mean   :139.60                                         Mean   :33611      
##  3rd Qu.:212.75                                         3rd Qu.:36519      
##  Max.   :238.00                                         Max.   :44632      
##       EDAD          GENERO          FECHA.DE.ALTA   MOTIVO.DE.BAJA    
##  Min.   : 0.00   Length:78          Min.   :43961   Length:78         
##  1st Qu.:22.25   Class :character   1st Qu.:44567   Class :character  
##  Median :30.00   Mode  :character   Median :44726   Mode  :character  
##  Mean   :30.50                      Mean   :44664                     
##  3rd Qu.:36.00                      3rd Qu.:44759                     
##  Max.   :52.00                      Max.   :44790                     
##  DIAS.TRABAJADOS       BAJA          PUESTO          DEPARTAMENTO      
##  Min.   :  0.00   Min.   :44569   Length:78          Length:78         
##  1st Qu.:  9.00   1st Qu.:44613   Class :character   Class :character  
##  Median : 19.00   Median :44741   Mode  :character   Mode  :character  
##  Mean   : 45.10   Mean   :44709                                        
##  3rd Qu.: 39.75   3rd Qu.:44784                                        
##  Max.   :730.00   Max.   :44814                                        
##  NO.SEGURO.SOCIAL   SALARIO.DIARIO.IMSS FACTOR.CRED.INFONAVIT
##  Length:78          Min.   :151.6       Min.   :   0.0       
##  Class :character   1st Qu.:180.7       1st Qu.:   0.0       
##  Mode  :character   Median :180.7       Median :   0.0       
##                     Mean   :174.3       Mean   : 130.4       
##                     3rd Qu.:180.7       3rd Qu.:   0.0       
##                     Max.   :183.7       Max.   :2795.3       
##  NO.CREDITO.INFONAVIT LUGAR.DE.NACIMIENTO     CURP              CALLE          
##  Min.   :0.000e+00    Length:78           Length:78          Length:78         
##  1st Qu.:0.000e+00    Class :character    Class :character   Class :character  
##  Median :0.000e+00    Mode  :character    Mode  :character   Mode  :character  
##  Mean   :1.871e+08                                                             
##  3rd Qu.:0.000e+00                                                             
##  Max.   :6.919e+09                                                             
##  NUMERO.INTERNO       COLONIA          CODIGO.POSTAL    MUNICIPIO        
##  Length:78          Length:78          Min.   :25019   Length:78         
##  Class :character   Class :character   1st Qu.:33604   Class :character  
##  Mode  :character   Mode  :character   Median :33604   Mode  :character  
##                                        Mean   :46508                     
##                                        3rd Qu.:66645                     
##                                        Max.   :67450                     
##     ESTADO          ESTADO.CIVIL       TARJETA.CUENTA    
##  Length:78          Length:78          Length:78         
##  Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character  
##                                                          
##                                                          
## 
str(rhCluster2)
## 'data.frame':    78 obs. of  26 variables:
##  $ NO.DE.BAJAS          : int  5 6 7 8 9 11 12 16 19 20 ...
##  $ APELLIDOS            : chr  "BERNAL FLORES" "SAUCEDO GUZMAN" "MEZA LLANAS" "TORRES LARA" ...
##  $ NOMBRE               : chr  "ERIKA ROSALINDA" "GUADALUPE" "YOANA CRISTINA" "CESAR ANTONIO" ...
##  $ FECHA.DE.NACIMIENTO  : int  33997 28106 34174 33491 26422 36970 32443 37872 37512 36915 ...
##  $ EDAD                 : int  29 46 29 31 50 21 34 19 20 21 ...
##  $ GENERO               : chr  "FEMENINO" "FEMENINO" "FEMENINO" "MASCULINO" ...
##  $ FECHA.DE.ALTA        : int  44518 44532 44532 44538 44551 44531 44532 44488 44541 44546 ...
##  $ MOTIVO.DE.BAJA       : chr  "RENUNCIA VOLUNTARIA" "BAJA POR FALTAS" "BAJA POR FALTAS" "BAJA POR FALTAS" ...
##  $ DIAS.TRABAJADOS      : int  51 37 37 31 18 40 39 86 33 28 ...
##  $ BAJA                 : int  44569 44569 44569 44569 44569 44571 44571 44574 44574 44574 ...
##  $ PUESTO               : chr  "AYUDANTE GENERAL" "AYUDANTE GENERAL" "AYUDANTE GENERAL" "AYUDANTE GENERAL" ...
##  $ DEPARTAMENTO         : chr  "VARIOS" "VARIOS" "VARIOS" "VARIOS" ...
##  $ NO.SEGURO.SOCIAL     : chr  "43109363747" "43937683647" "43099330201" "43099151714" ...
##  $ SALARIO.DIARIO.IMSS  : num  152 152 152 152 152 ...
##  $ FACTOR.CRED.INFONAVIT: num  0 1320 0 0 0 ...
##  $ NO.CREDITO.INFONAVIT : num  0.00 1.92e+09 0.00 0.00 0.00 ...
##  $ LUGAR.DE.NACIMIENTO  : chr  "NUEVO LEON" "NUEVO LEON" "NUEVO LEON" "NUEVO LEON" ...
##  $ CURP                 : chr  "BEFE930128MNLRLR05" "SAGG761212MNLCZD08" "MELY930724MNLZLN01" "TOLC910910HNLRRS09" ...
##  $ CALLE                : chr  "JULIAN VILLAGRAN" "PAPAGAYOS" "RIO AMANONAS" "PALMERA" ...
##  $ NUMERO.INTERNO       : chr  "452" "220" "300" "104" ...
##  $ COLONIA              : chr  "REFORMA" "GOLONDRINAS" "PUEBLO NUEVO" "MIRADOR DEL PARQUE" ...
##  $ CODIGO.POSTAL        : int  66640 66649 66646 67254 67114 66645 66646 66646 66645 66646 ...
##  $ MUNICIPIO            : chr  "APODACA" "APODACA" "APODACA" "JUAREZ" ...
##  $ ESTADO               : chr  "NUEVO LEON" "NUEVO LEON" "NUEVO LEON" "NUEVO LEON" ...
##  $ ESTADO.CIVIL         : chr  "SOLTERO/A" "SOLTERO/A" "UNION LIBRE" "UNION LIBRE" ...
##  $ TARJETA.CUENTA       : chr  "BANORTE" "BANORTE" "BANORTE" "BANORTE" ...

Explorar KMeans en edad por años

humanos5<-rhCluster2 %>% dplyr::select(EDAD,DIAS.TRABAJADOS,SALARIO.DIARIO.IMSS,ESTADO.CIVIL)
summary(humanos5)
##       EDAD       DIAS.TRABAJADOS  SALARIO.DIARIO.IMSS ESTADO.CIVIL      
##  Min.   : 0.00   Min.   :  0.00   Min.   :151.6       Length:78         
##  1st Qu.:22.25   1st Qu.:  9.00   1st Qu.:180.7       Class :character  
##  Median :30.00   Median : 19.00   Median :180.7       Mode  :character  
##  Mean   :30.50   Mean   : 45.10   Mean   :174.3                         
##  3rd Qu.:36.00   3rd Qu.: 39.75   3rd Qu.:180.7                         
##  Max.   :52.00   Max.   :730.00   Max.   :183.7

Normalizar los datos

rhCluster_norm<-scale(humanos5[1:2]) 

Sacar numero de clusters

fviz_nbclust() helps to determine and visualize the optimal number of clusters

fviz_nbclust(rhCluster_norm, kmeans, method="wss")+ # wss method considers total within sum of square
  geom_vline(xintercept=4, linetype=2)+           # optimal number of clusters is computed with the default method = "euclidean"
  labs(subtitle = "Elbow method")

Ver datos de los clusters

rh_cluster2<-kmeans(rh1_norm,4)
rh_cluster2
## K-means clustering with 4 clusters of sizes 1, 17, 8, 52
## 
## Cluster means:
##   DIAS.TRABAJADOS SALARIO.DIARIO.IMSS
## 1       7.5323951           0.5246350
## 2       0.2712304          -1.8780410
## 3       0.6353722           0.4428101
## 4      -0.3312748           0.5357612
## 
## Clustering vector:
##  [1] 2 2 2 2 2 2 2 2 2 2 2 2 4 4 4 4 4 4 4 3 2 4 2 2 2 2 4 4 4 4 4 4 4 4 4 4 4 4
## [39] 4 4 4 4 4 4 4 3 4 4 3 3 3 1 4 4 3 4 4 4 4 4 4 4 4 4 4 4 4 3 3 4 4 4 4 4 4 4
## [77] 4 4
## 
## Within cluster sum of squares by cluster:
## [1] 0.000000 6.019937 3.270968 1.055662
##  (between_SS / total_SS =  93.3 %)
## 
## Available components:
## 
## [1] "cluster"      "centers"      "totss"        "withinss"     "tot.withinss"
## [6] "betweenss"    "size"         "iter"         "ifault"

Visualizar clustering

fviz_cluster(rh_cluster2,data=rhCluster_norm)

La gráfica anterior muestra 4 clusters que analizan la relación entre edad y días trabajados. El cluster verde muestra que un alto número de personas tabajaba más días que el promedio y tenía una edad similar al promedio. El punto naranja muestra que pocos usuarios trabajaban más días que el promedio y al igual que el punto anterior, tenían una edad promedio. En el caso del punto azul y el morado, ambos muestran que un mayor grupo de personas laboraba ‘2 días’, pero tenía mayor variabilidad en la edad.

Agregar la info al data set original

humanos6<-humanos5
humanos6$Clusters<-rh_cluster2$cluster
summary(humanos6)
##       EDAD       DIAS.TRABAJADOS  SALARIO.DIARIO.IMSS ESTADO.CIVIL      
##  Min.   : 0.00   Min.   :  0.00   Min.   :151.6       Length:78         
##  1st Qu.:22.25   1st Qu.:  9.00   1st Qu.:180.7       Class :character  
##  Median :30.00   Median : 19.00   Median :180.7       Mode  :character  
##  Mean   :30.50   Mean   : 45.10   Mean   :174.3                         
##  3rd Qu.:36.00   3rd Qu.: 39.75   3rd Qu.:180.7                         
##  Max.   :52.00   Max.   :730.00   Max.   :183.7                         
##     Clusters    
##  Min.   :1.000  
##  1st Qu.:3.000  
##  Median :4.000  
##  Mean   :3.423  
##  3rd Qu.:4.000  
##  Max.   :4.000

Crear Dataset

lets create a dataset so we can identify some characteristics of “Edad” by cluster

humanos7<-humanos6 %>% group_by(Clusters, ESTADO.CIVIL) %>% summarise(EDAD=max(EDAD),DIAS.TRABAJADOS=mean(DIAS.TRABAJADOS)) %>% arrange(desc(EDAD))
summary(humanos7)
##       EDAD    DIAS.TRABAJADOS
##  Min.   :52   Min.   :45.1   
##  1st Qu.:52   1st Qu.:45.1   
##  Median :52   Median :45.1   
##  Mean   :52   Mean   :45.1   
##  3rd Qu.:52   3rd Qu.:45.1   
##  Max.   :52   Max.   :45.1

Agrupar clusters por nombre

humanos6$Cluster_Names<-factor(humanos6$Clusters,levels = c(1,2,3,4), 
                          labels=c("Joven", "Avanzado ", " Adulto", "Jubilado"))
summary(humanos6)
##       EDAD       DIAS.TRABAJADOS  SALARIO.DIARIO.IMSS ESTADO.CIVIL      
##  Min.   : 0.00   Min.   :  0.00   Min.   :151.6       Length:78         
##  1st Qu.:22.25   1st Qu.:  9.00   1st Qu.:180.7       Class :character  
##  Median :30.00   Median : 19.00   Median :180.7       Mode  :character  
##  Mean   :30.50   Mean   : 45.10   Mean   :174.3                         
##  3rd Qu.:36.00   3rd Qu.: 39.75   3rd Qu.:180.7                         
##  Max.   :52.00   Max.   :730.00   Max.   :183.7                         
##     Clusters       Cluster_Names
##  Min.   :1.000   Joven    : 1   
##  1st Qu.:3.000   Avanzado :17   
##  Median :4.000    Adulto  : 8   
##  Mean   :3.423   Jubilado :52   
##  3rd Qu.:4.000                  
##  Max.   :4.000

Entre más joven más días trabajados

Agrupar por clusters y resumir columnas

humanos8 <- humanos6 %>% group_by(Cluster_Names, ESTADO.CIVIL) %>% dplyr:: summarize(EDAD=max(EDAD), 
                                                       DIAS.TRABAJADOS =mean(DIAS.TRABAJADOS),
                                                         Count=n())
## `summarise()` has grouped output by 'Cluster_Names'. You can override using the
## `.groups` argument.

Convertir a tabla

clusters2<-as.data.frame(humanos8)
clusters2
##    Cluster_Names ESTADO.CIVIL EDAD DIAS.TRABAJADOS Count
## 1          Joven DIVORCIADO/A   32       730.00000     1
## 2      Avanzado      CASADO/A   28       155.00000     2
## 3      Avanzado     SOLTERO/A   50        76.44444     9
## 4      Avanzado   UNION LIBRE   35        31.33333     6
## 5         Adulto     CASADO/A   45       142.00000     3
## 6         Adulto DIVORCIADO/A   33        87.00000     1
## 7         Adulto    SOLTERO/A   27        67.00000     2
## 8         Adulto  UNION LIBRE   32        88.00000     2
## 9       Jubilado     CASADO/A   51        16.33333    18
## 10      Jubilado    SOLTERO/A   52        15.35000    20
## 11      Jubilado  UNION LIBRE   47        12.71429    14

Visualizar graficos

Ver los dias trabajados en general junto con la edad

ggplot(humanos8,aes(x=reorder(Cluster_Names,Count),y=Count,fill=Cluster_Names)) +
  geom_bar(stat="identity")

La gráfica anterior nos muestra la cantidad de días trabajados de acuerdo a la edad de los empleados. En este caso, vemos que el grupo de edad ‘joven’ tenían aprox. 31 años y representa un bajo porcentaje de los empleados. Para ‘avanzado’ son los empleados que tienen arriba de 32 años y laboraron la mayor cantidad de días (1067). Para ‘jubilado’, son las personas con un aprox. de 50 años y que laboraron durante 102 días. Finalmente, para el grupo de ‘adulto’ (el más elevado), son aquellos que laboraron un promedio de 44 días y tienen la edad de 52 años.

Dias trabajados por nombre de clusters

ggplot(humanos8, aes(x=Cluster_Names,y=DIAS.TRABAJADOS,fill= Cluster_Names,label=round(DIAS.TRABAJADOS,digits=2))) + 
  geom_col() + 
  geom_text()

La gráfica anterior nos muestra la cantidad de días trabajados de acuerdo a los días trabajados. En este caso, esto nos muestra que el grupo con mayor bajas fueron del segmento ‘adulto’ y es el que laboró en promedio un menor número de días contra ‘avanzado’ que es el segundo grupo más bajo y laboró el mayor número de días en promedio.

Edad por nombre de clusters

ggplot(humanos8,aes(x=Cluster_Names,y=EDAD,fill= Cluster_Names,label=round(EDAD,digits=2))) + 
  geom_col() + 
  geom_text()

La gráfica anterior nos muestra la edad promedio de cada uno de los grupos. Como explicamos anteriormente, se muestra que ‘adulto’ es el de empleados con mayor edad y ‘joven’ es el de personas de menor edad.

Dias trabajados por nombre de clusters

ggplot(humanos6, aes(x=Cluster_Names, y=EDAD, fill=Cluster_Names)) +
  geom_boxplot()+
  ggtitle("Dispersion of 'Edad' by Clusters Names")

La gráfica anterior nos muestra la dispersión de acuerdo a la edad de los empleados. En el caso de ‘adulto’, tiene una gran cantidad de puntos atípicos lo cual indica que hay datos fuera de serie. En el caso de ‘jubilado’, vemos que es el grupo con mayor dispersión, mostrando datos de edad entre 25 y 32 años.

Salario diario por nombre de clusters

ggplot(humanos6, aes(x=Cluster_Names, y=DIAS.TRABAJADOS, fill=Cluster_Names)) +
  geom_boxplot()+
  ggtitle("Dispersion of 'Dias_Trabajados' by Clusters Names")

La gráfica anterior muestra la dispersión de acuerdo a días trabajados y los grupos anterior explicados. Vemos que ‘avanzado’ es el gurpo con mayor dispersión, mostrando que el promedio de los empleados laboraron entre 550 y 1300 días. Es el grupo con mayor número de empleados que trabajaron en este periodo de tiempo. En el caso de ‘adulto’ y ‘jubilado’, son aquellos grupos que muestran una dispersión baja y una variedad de puntos atípicos, mientras que ‘joven’ destaca una baja dispersión y una media de más de 500 días trabajados.

Cluster 3

Importar la base de datos

cluster3<-read.csv("C:\\Users\\danyc\\Downloads\\HR_Bajas 2.csv") 
summary(cluster3)
##   NO.DE.BAJAS      APELLIDOS            NOMBRE          FECHA.DE.NACIMIENTO
##  Min.   :  5.00   Length:78          Length:78          Min.   :25585      
##  1st Qu.: 49.75   Class :character   Class :character   1st Qu.:31751      
##  Median :167.50   Mode  :character   Mode  :character   Median :33797      
##  Mean   :139.60                                         Mean   :33611      
##  3rd Qu.:212.75                                         3rd Qu.:36519      
##  Max.   :238.00                                         Max.   :44632      
##       EDAD          GENERO          FECHA.DE.ALTA   MOTIVO.DE.BAJA    
##  Min.   : 0.00   Length:78          Min.   :43961   Length:78         
##  1st Qu.:22.25   Class :character   1st Qu.:44567   Class :character  
##  Median :30.00   Mode  :character   Median :44726   Mode  :character  
##  Mean   :30.50                      Mean   :44664                     
##  3rd Qu.:36.00                      3rd Qu.:44759                     
##  Max.   :52.00                      Max.   :44790                     
##  DIAS.TRABAJADOS       BAJA          PUESTO          DEPARTAMENTO      
##  Min.   :  0.00   Min.   :44569   Length:78          Length:78         
##  1st Qu.:  9.00   1st Qu.:44613   Class :character   Class :character  
##  Median : 19.00   Median :44741   Mode  :character   Mode  :character  
##  Mean   : 45.10   Mean   :44709                                        
##  3rd Qu.: 39.75   3rd Qu.:44784                                        
##  Max.   :730.00   Max.   :44814                                        
##  NO.SEGURO.SOCIAL   SALARIO.DIARIO.IMSS FACTOR.CRED.INFONAVIT
##  Length:78          Min.   :151.6       Min.   :   0.0       
##  Class :character   1st Qu.:180.7       1st Qu.:   0.0       
##  Mode  :character   Median :180.7       Median :   0.0       
##                     Mean   :174.3       Mean   : 130.4       
##                     3rd Qu.:180.7       3rd Qu.:   0.0       
##                     Max.   :183.7       Max.   :2795.3       
##  NO.CREDITO.INFONAVIT LUGAR.DE.NACIMIENTO     CURP              CALLE          
##  Min.   :0.000e+00    Length:78           Length:78          Length:78         
##  1st Qu.:0.000e+00    Class :character    Class :character   Class :character  
##  Median :0.000e+00    Mode  :character    Mode  :character   Mode  :character  
##  Mean   :1.871e+08                                                             
##  3rd Qu.:0.000e+00                                                             
##  Max.   :6.919e+09                                                             
##  NUMERO.INTERNO       COLONIA          CODIGO.POSTAL    MUNICIPIO        
##  Length:78          Length:78          Min.   :25019   Length:78         
##  Class :character   Class :character   1st Qu.:33604   Class :character  
##  Mode  :character   Mode  :character   Median :33604   Mode  :character  
##                                        Mean   :46508                     
##                                        3rd Qu.:66645                     
##                                        Max.   :67450                     
##     ESTADO          ESTADO.CIVIL       TARJETA.CUENTA    
##  Length:78          Length:78          Length:78         
##  Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character  
##                                                          
##                                                          
## 
str(cluster3)
## 'data.frame':    78 obs. of  26 variables:
##  $ NO.DE.BAJAS          : int  5 6 7 8 9 11 12 16 19 20 ...
##  $ APELLIDOS            : chr  "BERNAL FLORES" "SAUCEDO GUZMAN" "MEZA LLANAS" "TORRES LARA" ...
##  $ NOMBRE               : chr  "ERIKA ROSALINDA" "GUADALUPE" "YOANA CRISTINA" "CESAR ANTONIO" ...
##  $ FECHA.DE.NACIMIENTO  : int  33997 28106 34174 33491 26422 36970 32443 37872 37512 36915 ...
##  $ EDAD                 : int  29 46 29 31 50 21 34 19 20 21 ...
##  $ GENERO               : chr  "FEMENINO" "FEMENINO" "FEMENINO" "MASCULINO" ...
##  $ FECHA.DE.ALTA        : int  44518 44532 44532 44538 44551 44531 44532 44488 44541 44546 ...
##  $ MOTIVO.DE.BAJA       : chr  "RENUNCIA VOLUNTARIA" "BAJA POR FALTAS" "BAJA POR FALTAS" "BAJA POR FALTAS" ...
##  $ DIAS.TRABAJADOS      : int  51 37 37 31 18 40 39 86 33 28 ...
##  $ BAJA                 : int  44569 44569 44569 44569 44569 44571 44571 44574 44574 44574 ...
##  $ PUESTO               : chr  "AYUDANTE GENERAL" "AYUDANTE GENERAL" "AYUDANTE GENERAL" "AYUDANTE GENERAL" ...
##  $ DEPARTAMENTO         : chr  "VARIOS" "VARIOS" "VARIOS" "VARIOS" ...
##  $ NO.SEGURO.SOCIAL     : chr  "43109363747" "43937683647" "43099330201" "43099151714" ...
##  $ SALARIO.DIARIO.IMSS  : num  152 152 152 152 152 ...
##  $ FACTOR.CRED.INFONAVIT: num  0 1320 0 0 0 ...
##  $ NO.CREDITO.INFONAVIT : num  0.00 1.92e+09 0.00 0.00 0.00 ...
##  $ LUGAR.DE.NACIMIENTO  : chr  "NUEVO LEON" "NUEVO LEON" "NUEVO LEON" "NUEVO LEON" ...
##  $ CURP                 : chr  "BEFE930128MNLRLR05" "SAGG761212MNLCZD08" "MELY930724MNLZLN01" "TOLC910910HNLRRS09" ...
##  $ CALLE                : chr  "JULIAN VILLAGRAN" "PAPAGAYOS" "RIO AMANONAS" "PALMERA" ...
##  $ NUMERO.INTERNO       : chr  "452" "220" "300" "104" ...
##  $ COLONIA              : chr  "REFORMA" "GOLONDRINAS" "PUEBLO NUEVO" "MIRADOR DEL PARQUE" ...
##  $ CODIGO.POSTAL        : int  66640 66649 66646 67254 67114 66645 66646 66646 66645 66646 ...
##  $ MUNICIPIO            : chr  "APODACA" "APODACA" "APODACA" "JUAREZ" ...
##  $ ESTADO               : chr  "NUEVO LEON" "NUEVO LEON" "NUEVO LEON" "NUEVO LEON" ...
##  $ ESTADO.CIVIL         : chr  "SOLTERO/A" "SOLTERO/A" "UNION LIBRE" "UNION LIBRE" ...
##  $ TARJETA.CUENTA       : chr  "BANORTE" "BANORTE" "BANORTE" "BANORTE" ...

Numero de clusters

Juntar los datos relacionados a edad en años

newbd<-cluster3 %>% dplyr::select(EDAD,SALARIO.DIARIO.IMSS,PUESTO)
summary(newbd)
##       EDAD       SALARIO.DIARIO.IMSS    PUESTO         
##  Min.   : 0.00   Min.   :151.6       Length:78         
##  1st Qu.:22.25   1st Qu.:180.7       Class :character  
##  Median :30.00   Median :180.7       Mode  :character  
##  Mean   :30.50   Mean   :174.3                         
##  3rd Qu.:36.00   3rd Qu.:180.7                         
##  Max.   :52.00   Max.   :183.7

Normalizar datos

newbdnorm<-scale(newbd[2:1])

Grafica para ver numero optimo de clusters

fviz_nbclust(newbdnorm, kmeans, method="wss")+ # wss method considers total within sum of square
  geom_vline(xintercept=4, linetype=2)+           # optimal number of clusters is computed with the default method = "euclidean"
  labs(subtitle = "Elbow method")

Visualizar informacion

newbd2clus<-kmeans(newbdnorm,4)
newbd2clus
## K-means clustering with 4 clusters of sizes 12, 17, 26, 23
## 
## Cluster means:
##   SALARIO.DIARIO.IMSS       EDAD
## 1           0.5317981  1.5586093
## 2          -1.8780410 -0.1112219
## 3           0.5184044 -0.8844567
## 4           0.5246350  0.2688407
## 
## Clustering vector:
##  [1] 2 2 2 2 2 2 2 2 2 2 2 2 1 3 3 4 3 3 3 3 2 1 2 2 2 2 4 4 1 1 1 3 3 4 4 3 3 4
## [39] 1 3 3 4 1 3 1 4 4 3 4 4 4 4 4 4 4 3 3 1 3 3 3 4 4 3 4 4 4 1 3 4 1 4 1 3 3 3
## [77] 3 3
## 
## Within cluster sum of squares by cluster:
## [1]  1.534968 15.627899  7.104697  1.698551
##  (between_SS / total_SS =  83.1 %)
## 
## Available components:
## 
## [1] "cluster"      "centers"      "totss"        "withinss"     "tot.withinss"
## [6] "betweenss"    "size"         "iter"         "ifault"

Ver resultados de clusters

fviz_cluster(newbd2clus,data=newbdnorm)

Agregar los resultados al dataset original para interpretacion

newbd3<-newbd 
newbd3$Clusters<-newbd2clus$cluster
summary(newbd3)
##       EDAD       SALARIO.DIARIO.IMSS    PUESTO             Clusters    
##  Min.   : 0.00   Min.   :151.6       Length:78          Min.   :1.000  
##  1st Qu.:22.25   1st Qu.:180.7       Class :character   1st Qu.:2.000  
##  Median :30.00   Median :180.7       Mode  :character   Median :3.000  
##  Mean   :30.50   Mean   :174.3                          Mean   :2.769  
##  3rd Qu.:36.00   3rd Qu.:180.7                          3rd Qu.:4.000  
##  Max.   :52.00   Max.   :183.7                          Max.   :4.000

Crear datasets para ver la info de caracteristicas por edad por clusters

newbd4<-newbd3 %>% group_by(Clusters,PUESTO) %>% summarise(EDAD=max(EDAD),SALARIO.DIARIO.IMSS=mean(SALARIO.DIARIO.IMSS)) %>% arrange(desc(EDAD))
summary(newbd4)
##       EDAD    SALARIO.DIARIO.IMSS
##  Min.   :52   Min.   :174.3      
##  1st Qu.:52   1st Qu.:174.3      
##  Median :52   Median :174.3      
##  Mean   :52   Mean   :174.3      
##  3rd Qu.:52   3rd Qu.:174.3      
##  Max.   :52   Max.   :174.3

Agrupar clusters por nombre

newbd3$Cluster_Names<-factor(newbd3$Clusters,levels = c(1,2,3,4), 
                          labels=c("Joven", "Avanzado ", " Adulto", "Jubilado"))
summary(newbd3)
##       EDAD       SALARIO.DIARIO.IMSS    PUESTO             Clusters    
##  Min.   : 0.00   Min.   :151.6       Length:78          Min.   :1.000  
##  1st Qu.:22.25   1st Qu.:180.7       Class :character   1st Qu.:2.000  
##  Median :30.00   Median :180.7       Mode  :character   Median :3.000  
##  Mean   :30.50   Mean   :174.3                          Mean   :2.769  
##  3rd Qu.:36.00   3rd Qu.:180.7                          3rd Qu.:4.000  
##  Max.   :52.00   Max.   :183.7                          Max.   :4.000  
##    Cluster_Names
##  Joven    :12   
##  Avanzado :17   
##   Adulto  :26   
##  Jubilado :23   
##                 
## 

Agrupar por nombre y por columna

newbd5 <- newbd3%>% dplyr::group_by(Cluster_Names,PUESTO) %>% dplyr:: summarize(EDAD=max(EDAD), 
                                                       SALARIO.DIARIO.IMSS =mean(SALARIO.DIARIO.IMSS),
                                                         Count=n())
## `summarise()` has grouped output by 'Cluster_Names'. You can override using the
## `.groups` argument.

Visualizar graficas

Poner como tabla los datos

clusterssalario<-as.data.frame(newbd5)
clusterssalario
##    Cluster_Names                      PUESTO EDAD SALARIO.DIARIO.IMSS Count
## 1          Joven            AYUDANTE GENERAL   52            181.2356     9
## 2          Joven                 COSTURERO/A   44            180.6800     1
## 3          Joven        GUARDIA DE SEGURIDAD   45            176.7200     1
## 4          Joven              MONTACARGUISTA   42            180.6800     1
## 5      Avanzado             AYUDANTE GENERAL   50            151.6100    17
## 6         Adulto       AYUDANTE DE EMBARQUES   21            176.7200     1
## 7         Adulto            AYUDANTE GENERAL   27            180.7670    23
## 8         Adulto        INSPECTOR DE CALIDAD   26            180.6800     1
## 9         Adulto                    SOLDADOR   25            180.6800     1
## 10      Jubilado            AYUDANTE GENERAL   38            180.6800    20
## 11      Jubilado JEFE DE SEGURIDAD E HIGIENE   34            180.6800     1
## 12      Jubilado              MONTACARGUISTA   37            180.6800     1
## 13      Jubilado                   RESIDENTE   31            180.6800     1

Graficar por nombre

ggplot(newbd5,aes(x=reorder(Cluster_Names,Count),y=Count,fill=Cluster_Names)) +
  geom_bar(stat="identity")

Salario diario por numero de clusters

ggplot(newbd5, aes(x=Cluster_Names,y=SALARIO.DIARIO.IMSS,fill= Cluster_Names,label=round(SALARIO.DIARIO.IMSS,digits=2))) + 
  geom_col() + 
  geom_text()

Aqui nos podemos dar cuenta acerca de que los sueldos no varian mucho entre edades pero es importante decir que se denota por centavos una mayoria en el sueldo de los jovenes especificamente más que en otros rangos de edades.

b. Identificación de características de clústers seleccionados

Graficar el no. de datos observados por Genero

ggplot(rh4,aes(x=reorder(Cluster_Names,Count),y=Count,fill=GENERO)) +
  geom_bar(stat="identity")

Ver los dias trabajados en general junto con la edad y Estado civil

ggplot(humanos8,aes(x=reorder(Cluster_Names,Count),y=Count,fill=ESTADO.CIVIL)) +
  geom_bar(stat="identity")

Graficar por nombre

ggplot(newbd5,aes(x=reorder(Cluster_Names,Count),y=Count,fill=PUESTO)) +
  geom_bar(stat="identity")

Hallazgos

[ 1 ] El salario diario promedio de FORM es de $180 pesos mexicanos, es decir, $5,400 pesos mensuales. De acuerdo a datos compartidos por la INEGI, se prevé que para 2022 el salario mínimo en México sea de $5,255 pesos mensuales. Esto refleja que el salario mensual de FORM es 2% mayor al salario mínimo del país. [ 2 ] Se destacan tres razones principales de bajas de empleados: bajas por faltas, renuncia voluntaria o término de contrato. En su mayoría, hubo una baja por faltas del puesto de ayudante general y renuncia voluntaria para el mismo puesto. [ 3 ] Hubo un alto número de bajas de empleados que trabajaron más de 200 días, es decir, la mayoría de los ex-empleados estuvieron en FORM más de 1 año y tenían un salario promedio de $180 pesos. [ 4 ] Los sueldos de los empleados no varían mucho dependiendo de la edad. Sin embargo, vemos que hay mayor rotación para el grupo ‘adulto’.

Gráficas ggalluvial

library(ggalluvial)
gall<-rh2

gall<-rh2 %>% filter(Clusters==1 | Clusters==3) %>% arrange(Clusters)
ggplot(as.data.frame(gall),
       aes(y=SALARIO.DIARIO.IMSS, axis1=EDAD, axis2=DIAS.TRABAJADOS)) +
  geom_alluvium(aes(fill=Cluster_Names), width = 1/12) +
  geom_stratum(width = 1/12, fill = "black", color = "grey") +
  geom_label(stat = "stratum", aes(label = after_stat(stratum))) +
  scale_x_discrete(limits = c("Edad", "Días Trabajados"), expand = c(.05, .05)) +
  scale_fill_brewer(type = "qual", palette = "Set1") +
  ggtitle("El Salario Diario por variables cualitativas")

Sección 4

Hallazgos

Sugerencias

Business Analytics y Business Intelligence

KPI´s

Referencias

Ana Karen García. (2022, September 8). Industria automotriz anota un buen agosto: crecen producción, exportaciones y ventas internas. El Economista; El Economista. https://www.eleconomista.com.mx/empresas/Industria-automotriz-anota-un-buen-agosto-crecen-produccion-exportaciones-y-ventas-internas-20220907-0031.html

Hernández, F., & Usuga, O. (2022). 9 Tablas de frecuencia | Manual de R. Retrieved 24 September 2022, from https://fhernanb.github.io/Manual-de-R/tablas.html#ejemplo-tabla-de-frecuencia-relativa-de-una-v%C3%ADa

9 Estilos y formatos de tabla | Tablas y graficos con R y R Studio. (2022). Retrieved 24 September 2022, from https://tables.investigaonline.com/tse-formateo.html

Anexo

LS0tDQp0aXRsZTogIkV2aWRlbmNpYSAyIg0KYXV0aG9yOiAiRGFuaWVsYSBDw6FyZGVuYXMgWmVydHVjaGUiDQpkYXRlOiAiMjAyMi0xMC0xOCINCm91dHB1dDogDQogICAgICBodG1sX2RvY3VtZW50Og0KICAgICAgICB0b2M6IHRydWUNCiAgICAgICAgdG9jX2Zsb2F0OiB0cnVlDQogICAgICAgIGNvZGVfZm9sZGluZzogImhpZGUiDQogICAgICAgIGNvZGVfZG93bmxvYWQ6IHRydWUNCi0tLQ0KIyA8aW1nIHNyYz0gIkM6XFxVc2Vyc1xcZGFueWNcXERvd25sb2Fkc1xcbG9nby5wbmciIC8+DQoNCg0KYGBge3Igd2FybmluZz1GQUxTRX0NCg0Ka25pdHI6OmluY2x1ZGVfdXJsKCJodHRwczovL2Zvcm0uY29tLm14LyIpDQoNCmBgYA0KDQoNCiMgPHNwYW4gc3R5bGUgPSAiY29sb3I6ZGFya29yYW5nZSI+IFJIIENvbGFib3JhZG9yZXMgIA0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbGlicmFyeShmb3JlaWduKQ0KbGlicmFyeShkcGx5cikgICAgICAgICMgZGF0YSBtYW5pcHVsYXRpb24gDQpsaWJyYXJ5KGZvcmNhdHMpICAgICAgIyB0byB3b3JrIHdpdGggY2F0ZWdvcmljYWwgdmFyaWFibGVzDQpsaWJyYXJ5KGdncGxvdDIpICAgICAgIyBkYXRhIHZpc3VhbGl6YXRpb24NCmxpYnJhcnkocmVhZHIpICAgICAgICAjIHJlYWQgc3BlY2lmaWMgY3N2IGZpbGVzDQpsaWJyYXJ5KGphbml0b3IpICAgICAgIyBkYXRhIGV4cGxvcmF0aW9uIGFuZCBjbGVhbmluZyANCmxpYnJhcnkoSG1pc2MpICAgICAgICAjIHNldmVyYWwgdXNlZnVsIGZ1bmN0aW9ucyBmb3IgZGF0YSBhbmFseXNpcyANCmxpYnJhcnkocHN5Y2gpICAgICAgICAjIGZ1bmN0aW9ucyBmb3IgbXVsdGl2YXJpYXRlIGFuYWx5c2lzIA0KbGlicmFyeShuYW5pYXIpICAgICAgICMgc3VtbWFyaWVzIGFuZCB2aXN1YWxpemF0aW9uIG9mIG1pc3NpbmcgdmFsdWVzIE5Bcw0KbGlicmFyeShkbG9va3IpICAgICAgICMgc3VtbWFyaWVzIGFuZCB2aXN1YWxpemF0aW9uIG9mIG1pc3NpbmcgdmFsdWVzIE5Bcw0KbGlicmFyeShjb3JycGxvdCkgICAgICMgY29ycmVsYXRpb24gcGxvdHMNCmxpYnJhcnkoanRvb2xzKSAgICAgICAjIHByZXNlbnRhdGlvbiBvZiByZWdyZXNzaW9uIGFuYWx5c2lzIA0KbGlicmFyeShsbXRlc3QpICAgICAgICMgZGlhZ25vc3RpYyBjaGVja3MgLSBsaW5lYXIgcmVncmVzc2lvbiBhbmFseXNpcyANCmxpYnJhcnkoY2FyKSAgICAgICAgICAjIGRpYWdub3N0aWMgY2hlY2tzIC0gbGluZWFyIHJlZ3Jlc3Npb24gYW5hbHlzaXMNCmxpYnJhcnkob2xzcnIpICAgICAgICAjIGRpYWdub3N0aWMgY2hlY2tzIC0gbGluZWFyIHJlZ3Jlc3Npb24gYW5hbHlzaXMgDQpsaWJyYXJ5KGthYmxlRXh0cmEpICAgIyBIVE1MIHRhYmxlIGF0dHJpYnV0ZXMNCmxpYnJhcnkoZ21vZGVscykNCmxpYnJhcnkob3Blbnhsc3gpDQpsaWJyYXJ5KGNyb3NzdGFibGUpDQpgYGANCiMjIFNlY2Npw7NuIDEuIExpbXBpZXphIGRlIGRhdG9zLCBUcmFuc2Zvcm1hY2nDs24geSBFbnRlbmRpbWllbnRvICgxLTQpIA0KYGBge3Igd2FybmluZz1GQUxTRX0NCmNvbGFiIDwtcmVhZC5jc3YoIkM6XFxVc2Vyc1xcZGFueWNcXERvd25sb2Fkc1xcaHIgY3N2IDEuY3N2IikNCnN1bW1hcnkoY29sYWIpDQpkZXNjcmliZShjb2xhYikNCmBgYA0KDQojIyMjIFZhcmlhYmxlcyB5IFJlZ2lzdHJvcyAgDQo8Y2VudGVyPiA8c3BhbiBzdHlsZT0iY29sb3I6UmVkIj4gUj0gMjggdmFyaWFibGVzIHkgMTEzIG9ic2VydmFjaW9uZXM8L2NlbnRlcj4NCg0KYGBge3J9DQpzdHIoY29sYWIpDQpgYGANCg0KIyMjIyBFbGltaW5hciBOL0HCtHMgDQpTZSBlbGltaW5hbiBsb3MgTi9BwrRzIHBhcmEgZXZpdGFyIGRhdG9zIG5vIHByZWNpc29zIG8gZXJyb25lb3MuDQpgYGB7ciB3YXJuaW5nPUZBTFNFfQ0Kc3VtKGlzLm5hKGNvbGFiKSkNCmBgYA0KDQojIyMjIEVsaW1pbmFyIGR1cGxpY2Fkb3MgDQpTZSBlbGltaW5hbiB2YWxvcmVzIGR1cGxpY2Fkb3MgcGFyYSBldml0YXIgbm8gdGVuZXIgZGF0b3Mgbm8gb3JnYW5pemFkb3MuDQpgYGB7cn0NCmNvbGFiMTwtY29sYWINCmNvbGFiMTwtZGlzdGluY3QoY29sYWIxKQ0KYGBgDQoNCiMjIyMgRWxpbWluYXIgQ29sdW1uYXMgDQpTZSBlbGltaW5hbiBjb2x1bW5hcyBwYXJhIGV2aXRhciB0ZW5lciBpbmZvcm1hY2nDs24gaW5uZWNlc2FyaWEgZW4gbGFzIGJhc2VzIGRlIGRhdG9zLg0KYGBge3Igd2FybmluZz1GQUxTRX0NCmNvbGFiMjwtY29sYWIxDQpjb2xhYjIgPC0gc3Vic2V0KGNvbGFiMiwgc2VsZWN0ID0tYyAoTk9NQlJFKSkNCmNvbGFiMiA8LSBzdWJzZXQoY29sYWIyLCBzZWxlY3QgPS1jIChBUEVMTElET1MpKQ0KY29sYWIyIDwtIHN1YnNldChjb2xhYjIsIHNlbGVjdCA9LWMgKFJGQykpDQpjb2xhYjIgPC0gc3Vic2V0KGNvbGFiMiwgc2VsZWN0ID0tYyAoQ1VBUlRPLk1FUykpDQpjb2xhYjIgPC0gc3Vic2V0KGNvbGFiMiwgc2VsZWN0ID0tYyAoRkFDVE9SLkNSRUQuSU5GT05BVklUKSkNCmNvbGFiMiA8LSBzdWJzZXQoY29sYWIyLCBzZWxlY3QgPS1jIChDVVJQKSkNCmNvbGFiMiA8LSBzdWJzZXQoY29sYWIyLCBzZWxlY3QgPS1jIChDQUxMRSkpDQpjb2xhYjIgPC0gc3Vic2V0KGNvbGFiMiwgc2VsZWN0ID0tYyAoTlVNRVJPLklOVEVSTk8pKQ0KY29sYWIyIDwtIHN1YnNldChjb2xhYjIsIHNlbGVjdCA9LWMgKFRBUkpFVEEuQ1VFTlRBKSkNCnN1bW1hcnkoY29sYWIyKQ0KYGBgDQoNCg0KIyMjIEVzY2FsYXMgZGUgdmFyaWFibGVzDQpgYGB7cn0NCg0KdmFyaWFibGVzIDwtIGMoDQogICJOby5EZS5FbXBsZWFkbyIsDQogICJBUEVMTElET1MiLA0KICAiTk9NQlJFIiwNCiAgIkZFQ0hBLkRFLk5BQ0lNSUVOVE8iLA0KICAiRURBRCIsDQogICJHRU5FUk8iLA0KICAiUkZDIiwNCiAgIkZFQ0hBLkRFLkFMVEEiLA0KICAiUFJJTUVSLk1FUyIsDQogICJDVUFSVE8uTUVTIiwNCiAgIkJBSkEiLA0KICAiUFVFU1RPIiwNCiAgIkRFUEFSVEFNRU5UTyIsDQogICJTQUxBUklPLkRJQVJJTy5JTVNTIiwNCiAgIkZBQ1RPUi5DUkVELklORk9OQVZJVCIsDQogICJOLkNSRURJVE8uSU5GT05BVklUIiwNCiAgIkxVR0FSLkRFLk5BQ0lNSUVOVE8iLA0KICAiQ1VSUCIsDQogICJDQUxMRSIsDQogICJOVU1FUk8uSU5URVJOTyIsDQogICJDT0xPTklBIiwNCiAgIk1VTklDSVBJTyIsDQogICJFU1RBRE8iLA0KICAiQ09ESUdPLlBPU1RBTCIsDQogICJFU1RBRE8uQ0lWSUwiLA0KICAiVEFSSkVUQS5DVUVOVEEiDQogICkNCg0KdGlwb3MgPC0gYygNCiAgICAgICAgICAgICAgIkN1YW50aXRhdGl2byIsDQogICAgICAgICAgICAgICJDdWFsaXRhdGl2byIsDQogICAgICAgICAgICAgICJDdWFsaXRhdGl2byIsDQogICAgICAgICAgICAgICJDdWFsaXRhdGl2byIsDQogICAgICAgICAgICAgICJDdWFudGl0YXRpdm8iLA0KICAgICAgICAgICAgICAiQ3VhbGl0YXRpdm8iLA0KICAgICAgICAgICAgICAiQ3VhbGl0YXRpdm8iLA0KICAgICAgICAgICAgICAiQ3VhbnRpdGF0aXZvIiwNCiAgICAgICAgICAgICAgIkN1YW50aXRhdGl2byIsDQogICAgICAgICAgICAgICJDdWFudGl0YXRpdm8iLA0KICAgICAgICAgICAgICAiQ3VhbnRpdGF0aXZvIiwNCiAgICAgICAgICAgICAgIkN1YWxpdGF0aXZvIiwNCiAgICAgICAgICAgICAgIkN1YWxpdGF0aXZvIiwNCiAgICAgICAgICAgICAgIkN1YW50aXRhdGl2byIsDQogICAgICAgICAgICAgICJDdWFudGl0YXRpdm8iLA0KICAgICAgICAgICAgICAiQ3VhbGl0YXRpdm8iLA0KICAgICAgICAgICAgICAiQ3VhbGl0YXRpdm8iLA0KICAgICAgICAgICAgICAiQ3VhbGl0YXRpdm8iLA0KICAgICAgICAgICAgICAiQ3VhbGl0YXRpdm8iLA0KICAgICAgICAgICAgICAiQ3VhbnRpdGF0aXZvIiwNCiAgICAgICAgICAgICAgIkN1YWxpdGF0aXZvIiwNCiAgICAgICAgICAgICAgIkN1YWxpdGF0aXZvIiwNCiAgICAgICAgICAgICAgIkN1YWxpdGF0aXZvIiwNCiAgICAgICAgICAgICAgIkN1YW50aXRhdGl2byIsDQogICAgICAgICAgICAgICJDdWFsaXRhdGl2byIsDQogICAgICAgICAgICAgICJDdWFsaXRhdGl2byINCiAgICAgICAgICAgICAgKQ0KDQplc2NhbGFzIDwtIGMoDQogICAgICAgICAgICAiSW50ZXJ2YWxvIiwNCiAgICAgICAgICAgICAiTm9taW5hbCIsDQogICAgICAgICAgICAgIk5vbWluYWwiLA0KICAgICAgICAgICAgICJJbnRlcnZhbG8iLA0KICAgICAgICAgICAgIkludGVydmFsbyIsDQogICAgICAgICAgICAgIk5vbWluYWwiLA0KICAgICAgICAgICAgIk5vbWluYWwiLA0KICAgICAgICAgICAgIlJhesOzbiIsDQogICAgICAgICAgICAiUmF6w7NuIiwNCiAgICAgICAgICAgICJSYXrDs24iLA0KICAgICAgICAgICAgIlJhesOzbiIsDQogICAgICAgICAgICAiT3JkaW5hbCIsDQogICAgICAgICAgICAiTm9taW5hbCIsDQogICAgICAgICAgICAiUmF6w7NuIiwNCiAgICAgICAgICAgICJSYXrDs24iLA0KICAgICAgICAgICAgIk5vbWluYWwiLA0KICAgICAgICAgICAgIk5vbWluYWwiLA0KICAgICAgICAgICAgIk5vbWluYWwiLA0KICAgICAgICAgICAgIk5vbWluYWwiLA0KICAgICAgICAgICAgIlJhesOzbiIsDQogICAgICAgICAgICAiTm9taW5hbCIsDQogICAgICAgICAgICAiTm9taW5hbCIsDQogICAgICAgICAgICAiTm9taW5hbCIsDQogICAgICAgICAgICAiT3JkaW5hbCIsDQogICAgICAgICAgICAiTm9taW5hbCIsDQogICAgICAgICAgICAiTm9taW5hbCINCiAgICAgICAgICAgICkNCg0KdGFibGVjb2xhYm9yYWRvcmVzIDwtIGRhdGEuZnJhbWUgKHZhcmlhYmxlcywgdGlwb3MsIGVzY2FsYXMpDQprbml0cjo6a2FibGUodGFibGVjb2xhYm9yYWRvcmVzKQ0KDQpgYGANCg0KIyMjIFRhYmxhIGRlIEZyZWN1ZW5jaWEgDQpFc3RhIHRhYmxhIGRlIGZyZWN1ZW5jaWEgcmVwcmVzZW50YSBlbCB2YWxvciBkZWNpbWFsIGRlbCBzYWxhcmlvIGRpYXJpbyBkZSBhY3VlcmRvIGFsIGfDqW5lcm8sIGVzIGRlY2lyLCBsYSBjYW50aWRhZCBkZSBlbXBsZWFkb3MgZW4gdmFsb3IgZGVjaW1hbCBxdWUgcmVjaWJlbiBjaWVydG8gc2FsYXJpbyBkaWFyaW8gZGUgYWN1ZXJkbyBhIHN1IGfDqW5lcm8uIA0KDQpgYGB7ciB3YXJuaW5nPUZBTFNFfQ0KI2luc3RhbGwucGFja2FnZXMoJ2VwaURpc3BsYXknKQ0KbGlicmFyeShlcGlEaXNwbGF5KQ0KDQp0YWIxKGNvbGFiMiRHRU5FUk8sIGNvbGFiMiRTQUxBUklPLkRJQVJJTy5JTVNTLCBzb3J0Lmdyb3VwID0gImRlY3JlYXNpbmciLCBjdW0ucGVyY2VudCA9IFRSVUUsIG1haW4gPSAiRGlzdHJpYnVjacOzbiBkZSBDb2xhYm9yYWRvcmVzIHBvciBHZW5lcm8iKQ0KDQpgYGANCg0KDQojIyBTZWNjacOzbiAyLiBBbsOhbGlzaXMgRXhwbG9yYXRvcmlvIA0KDQojIyMgVGFibGEgTWVkaWEsIE1lZGlhbmEgeSBEZXN2aWFjacOzbiBFc3RhbmRhciAgDQpgYGB7cn0gDQpkZXNjcmliZShjb2xhYjIpDQoNCmNvdW50KGNvbGFiMiwgR0VORVJPLCBzb3J0ID0gVFJVRSkNCmNvdW50KGNvbGFiMiwgUFVFU1RPLCBzb3J0ID0gVFJVRSkNCmNvdW50KGNvbGFiMiwgREVQQVJUQU1FTlRPLCBzb3J0ID0gVFJVRSkNCmNvdW50KGNvbGFiMiwgU0FMQVJJTy5ESUFSSU8uSU1TUywgc29ydCA9IFRSVUUpDQpjb3VudChjb2xhYjIsIExVR0FSLkRFLk5BQ0lNSUVOVE8sIHNvcnQgPSBUUlVFKQ0KDQp0aWJibGUoY29sYWIyKQ0KYGBgDQoNCkVuIGVzdGEgcHJpbWVyYSBwYXJ0ZSBkZWwgYW7DoWxpc2lzIGVzdGFkw61zdGljbyBkZXNjcmlwdGl2bywgdmVtb3MgcXVlIGVsIGNvbnRlbyB0b3RhbCBkZSBlbXBsZWFkb3MgYWN0dWFsZXMgZXMgZGUgMTEzIHkgaGF5IHVuIG1heW9yIG7Dum1lcm8gZGUgbXVqZXJlcyAoNTQlKSBjb250cmEgZW1wbGVhZG9zIHF1ZSBzb24gaG9tYnJlcyAoNDYlKS4NCg0KRW4gY3VhbnRvIGEgbG9zIHB1ZXN0b3MsIHZlbW9zIHF1ZSBleGlzdGUgdW5hIGdyYW4gY2FudGlkYWQgZGUgYXl1ZGFudGVzIGdlbmVyYWxlcywgcHVlcyBlcyBlbCBwdWVzdG8gcXVlIG9jdXBhIG1heW9yIGNhcGl0YWwgaHVtYW5vLCBjb250cmEgYXF1ZWxsb3MgcXVlIG9jdXBhbiBtZW5vcyBxdWUgdmFuIGRlc2RlIHNlcnZpY2lvIGFsIGNsaWVudGUgaGFzdGEgb3BlcmFkb3Jlcy4NCg0KRW50cmUgbG9zIGRlcGFydGFtZW50b3MgY29uIG1heW9yIGNhbnRpZGFkIGRlIGVtcGxlYWRvcywgdmVtb3MgcXVlIGVzdMOhIHZhcmlvcyB5IHByb2R1Y2Npw7NuIHJldG9ybm8uIEVsIGRlcGFydGFtZW50byBkZSAiVmFyaW9zIiBmdWUgY3JlYWRvIHBhcmEgY2F0YWxvZ2FyIGEgYXF1ZWxsb3MgZW1wbGVhZG9zIHF1ZSBlbiBsYSBiYXNlIGRlIGRhdG9zIG5vIHRlbsOtYW4gZGVmaW5pZGEgdW4gw6FyZWEgZW4gY29uY3JldG8uDQoNClZlbW9zIHF1ZSBsYSBtYXlvcsOtYSBkZSBsb3MgZW1wbGVhZG9zIGdhbmFuICQxODAuNjggcGVzb3MgZGUgc2FsYXJpbyBkaWFyaW8gcG9yIGVsIElNU1MgeSBkZSB0b2RvcyBsb3MgZW1wbGVhZG9zLCBzZSBjYWxjdWxhIHF1ZSB0aWVuZW4gdW4gcHJvbWVkaW8gZGUgc2FsYXJpbyBkaWFyaW8gZGUgJDIzNi42MiBwZXNvcy4NCg0KRW4gY3VhbnRvIGFsIGx1Z2FyIGRlIG9yaWdlbiwgdmVtb3MgcXVlIGxhIG1heW9yw61hIGRlIGxvcyBlbXBsZWFkb3MgcHJvdmllbmVuIGRlbCBFc3RhZG8gZGUgTnVldm8gTGXDs24gKDcwJSkgeSBWZXJhY3J1eiAoMTElKSwgdmllbmRvIHF1ZSBlbCAxOSUgcmVzdGFudGUgZGUgbG9zIGVtcGxlYWRvcyBzb24gcHJvdmVuaWVudGVzIGRlIFpvbmEgQ2VudHJvIG8gZXN0YWRvcyBjb2xpZGFudGVzIGRlIE51ZXZvIExlw7NuLg0KDQpBcXVpIGxhIHZhcmlhYmxlIHF1ZSBtw6FzIG5vcyBpbnRlcmVzYSBlcyBsYSBtZWRpYSBkZSBsYXMgYmFqYXMgdG90YWxlcyBxdWUgaGF5IGRlbnRybyBkZSBGT1JNLg0KYGBge3J9DQp0YWJsZWNvbGFib3JhZG9yZXM8LWRlc2NyaWJlKGNvbGFiMikNCmtuaXRyOjprYWJsZSh0YWJsZWNvbGFib3JhZG9yZXMpDQpgYGANCg0KDQojIyMgR3LDoWZpY2FzIGRlIERpc3BlcnNpw7NuICANCkRlbnRybyBkZSBlc3RhIGdyw6FmaWNhIGRlIGRpc3BlcnNpw7NuIHNlIHZlbiBlbiBwcm9tZWRpbyBxdWUgbGFzIGVkYWRlcyBubyBhZmVjdGFuIGVuIGVsIHBhcmFtZXRybyBkZWwgc2FsYXJpbyBkaWFyaW8sIHNlIG11ZXN0cmFuIHF1ZSBoYXkgYWxnw7pub3MgZGF0b3MgZnVlcmEgZGUgbGEgbWVkaWEgcGVybyBzZSBkZW5vdGEgdW5hIGVzdGFiaWxpZGFkIGRlIGxvcyBkYXRvcy4gDQpgYGB7cn0NCnBsb3QoeD1jb2xhYjIkU0FMQVJJTy5ESUFSSU8uSU1TUyAsIHk9Y29sYWIyJEVEQUQsIA0KICAgICB4bGFiPSAiU2FsYXJpbyBEaWFyaW8iLCB5bGFiPSJFZGFkIiwNCiAgICAgbWFpbj0iRGlzcGVyc2nDs24gZGUgRWRhZCBjb24gU2FsYXJpbyIpDQpgYGANCg0KDQoNCiMgPHNwYW4gc3R5bGUgPSAiY29sb3I6ZGFya29yYW5nZSI+ICBSSCBCYWphcw0KIyMgU2VjY2nDs24gMS4gTGltcGllemEgZGUgZGF0b3MsIFRyYW5zZm9ybWFjacOzbiB5IEVudGVuZGltaWVudG8gKDEtNCkgDQpQYXJhIGVzdGFzIGRvcyBiYXNlcyBkZSBkYXRvcywgc2UgdXRpbGl6YXJvbiBsYSBlbGltaW5hY2nDs24gZGUgTi9BwrRzLCBjYW1iaW8gZGUgbm9tYnJlIHkgcXVpdGFyIGNvbHVtbmFzIGRlIG51ZXN0cmEgYmFzZSBkZSBkYXRvcyBwYXJhIHBvZGVyIHV0aWxpemFybGFzIGRlIGxhIG1hbmVyYSBtw6FzIGFkZWN1YWRhLg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCg0KIyMjIEltcG9ydGFyIGJhc2UgZGUgZGF0b3MNCg0KYmFqYXMgPC1yZWFkLmNzdigiQzpcXFVzZXJzXFxkYW55Y1xcRG93bmxvYWRzXFxIUl9CYWphcyAyLmNzdiIpDQpgYGANCg0KIyMjIFZhcmlhYmxlcyB5IFJlZ2lzdHJvcw0KPGNlbnRlcj4gPHNwYW4gc3R5bGU9ImNvbG9yOlJlZCI+IFI9IDI2IHZhcmlhYmxlcyB5IDc4IG9ic2VydmFjaW9uZXMuPC9jZW50ZXI+DQpgYGB7cn0NCnN1bW1hcnkoYmFqYXMpDQpgYGANCg0KIyMjIyDCv0N1w6FudG9zIE5BJ3MgdGVuZ28gZW4gbGEgYmFzZSBkZSBkYXRvcz8gDQpgYGB7cn0NCnN1bShpcy5uYShiYWphcykpDQpgYGANCg0KDQojIyMjIEJvcnJhciB0b2RvcyBsb3MgcmVnaXN0cm9zIE5BJ3MgZGUgdW5hIHRhYmxhDQpgYGB7cn0NCmJhamFzMjwtYmFqYXMNCmJhamFzMjwtbmEub21pdChiYWphczIpDQpzdW1tYXJ5KGJhamFzMikNCmBgYA0KDQojIyMgRWxpbWluYXIgY29sdW1uYXMNCmBgYHtyfQ0KYmFqYXMzPC1iYWphczINCmJhamFzMyA8LSBzdWJzZXQoYmFqYXMzLCBzZWxlY3QgPS1jIChBUEVMTElET1MpKQ0KYmFqYXMzIDwtIHN1YnNldChiYWphczMsIHNlbGVjdCA9LWMgKE5PTUJSRSkpDQpiYWphczMgPC0gc3Vic2V0KGJhamFzMywgc2VsZWN0ID0tYyAoRkFDVE9SLkNSRUQuSU5GT05BVklUKSkNCmJhamFzMyA8LSBzdWJzZXQoYmFqYXMzLCBzZWxlY3QgPS1jIChDVVJQKSkNCmJhamFzMyA8LSBzdWJzZXQoYmFqYXMzLCBzZWxlY3QgPS1jIChDQUxMRSkpDQpiYWphczMgPC0gc3Vic2V0KGJhamFzMywgc2VsZWN0ID0tYyAoTlVNRVJPLklOVEVSTk8pKQ0KYmFqYXMzIDwtIHN1YnNldChiYWphczMsIHNlbGVjdCA9LWMgKFRBUkpFVEEuQ1VFTlRBKSkNCmBgYA0KDQoNCiMjIyDCv0N1w6FudG9zIE5BJ3MgdGVuZ28gZW4gbGEgYmFzZSBkZSBkYXRvcz8NCmBgYHtyfQ0Kc3VtKGlzLm5hKGJhamFzMykpDQpgYGANCg0KTm90YTogQ29uIGxvcyBkYXRvcyBwcmVzZW50YWRvcyBhbnRlcmlvcm1lbnRlLCB2ZW1vcyBxdWUgbGEgZWRhZCBwcm9tZWRpbyBkZSBsb3MgY29sYWJvcmFkb3JlcyBlcyBkZSAzNSBhw7FvcywgYWRlbcOhcyBkZSBxdWUgZ2FuYW4gdW4gcHJvbWVkaW8gZGUgJDE4MCBwZXNvcy4NCg0KDQojIyMgQ2xhc2lmaWNhY2nDs24gZGUgVmFyaWFibGVzDQoNCmBgYHtyfQ0KDQp2YXJpYWJsZXMgPC0gYygiTm8gZGUgYmFqYXMiLA0KICAiRkVDSEEuREUuTkFDSU1JRU5UTyIsDQogICJFREFEIiwNCiAgIkdFTkVSTyIsDQogICJGRUNIQS5ERS5BTFRBIiwNCiAgIk1vdGl2byBkZSBCYWphIiwNCiAgIkRpYXMgVHJhYmFqYWRvcyIsDQogICJCQUpBIiwNCiAgIlBVRVNUTyIsDQogICJEZXBhcnRhbWVudG8iLA0KICAiU2VndXJvIFNvY2lhbCIsDQogICJTQUxBUklPLkRJQVJJTy5JTVNTIiwNCiAgIk4uLkNSRURJVE8uSU5GT05BVklUIiwNCiAgIkxVR0FSLkRFLk5BQ0lNSUVOVE8iLA0KICAiQ09MT05JQSIsDQogICJDT0RJR08uUE9TVEFMIiwNCiAgIk1VTklDSVBJTyIsDQogICJFU1RBRE8iLA0KICAiRVNUQURPLkNJVklMIikNCg0KdGlwb3MgPC0gYygiQ3VhbnRpdGF0aXZvIiwNCiAgICAgICAgICAgICAgIkN1YWxpdGF0aXZvIiwNCiAgICAgICAgICAgICAgIkN1YW50aXRhdGl2byIsDQogICAgICAgICAgICAgICJDdWFsaXRhdGl2byIsDQogICAgICAgICAgICAgICJDdWFudGl0YXRpdm8iLA0KICAgICAgICAgICAgICAiQ3VhbGl0YXRpdm8iLA0KICAgICAgICAgICAgICAiQ3VhbnRpdGF0aXZvIiwNCiAgICAgICAgICAgICAgIkN1YW50aXRhdGl2byIsDQogICAgICAgICAgICAgICJjdWFsaXRhdGl2byIsDQogICAgICAgICAgICAgICJDdWFsaXRhdGl2byIsDQogICAgICAgICAgICAgICJDdWFsaXRhdGl2byIsDQogICAgICAgICAgICAgICJDdWFudGl0YXRpdm8iLA0KICAgICAgICAgICAgICAiQ3VhbGl0YXRpdm8iLA0KICAgICAgICAgICAgICAiQ3VhbGl0YXRpdm8iLA0KICAgICAgICAgICAgICAiQ3VhbGl0YXRpdm8iLA0KICAgICAgICAgICAgICAiQ3VhbnRpdGF0aXZvIiwNCiAgICAgICAgICAgICAgIkN1YWxpdGF0aXZvIiwNCiAgICAgICAgICAgICAgIkN1YWxpdGF0aXZvIiwNCiAgICAgICAgICAgICAgIkN1YWxpdGF0aXZvIikNCg0KZXNjYWxhcyA8LSBjKCJJbnRlcnZhbG8iLA0KICAgICAgICAgICAgICJOb21pbmFsIiwNCiAgICAgICAgICAgICAiSW50ZXJ2YWxvIiwNCiAgICAgICAgICAgICAiTm9taW5hbCIsDQogICAgICAgICAgICAiUmF6w7NuIiwNCiAgICAgICAgICAgICJOb21pbmFsIiwNCiAgICAgICAgICAgICJSYXrDs24iLA0KICAgICAgICAgICAgIlJhesOzbiIsDQogICAgICAgICAgICAiT3JkaW5hbCIsDQogICAgICAgICAgICAiTm9taW5hbCIsDQogICAgICAgICAgICAiTm9taW5hbCIsDQogICAgICAgICAgICAiUmF6b24iLA0KICAgICAgICAgICAgIk5vbWluYWwiLA0KICAgICAgICAgICAgIk5vbWluYWwiLA0KICAgICAgICAgICAgIk5vbWluYWwiLA0KICAgICAgICAgICAgIk9yZGluYXJpYSIsDQogICAgICAgICAgICAiTm9taW5hbCIsDQogICAgICAgICAgICAiTm9taW5hbCIsDQogICAgICAgICAgICAiTm9taW5hbCIpDQoNCnRhYmxlYmFqYXMgPC0gZGF0YS5mcmFtZSAodmFyaWFibGVzLCB0aXBvcywgZXNjYWxhcykNCmtuaXRyOjprYWJsZSh0YWJsZWJhamFzKQ0KDQpgYGANCg0KIyMgU2VjY2nDs24gMi4gQW7DoWxpc2lzIEV4cGxvcmF0b3JpbyANCg0KIyMjIE1lZGlhLCBNZWRpYW5hIHkgU3RkLiBEZXZpYXRpb24gDQpgYGB7cn0NCm1lZGlhbihiYWphczMkRElBUy5UUkFCQUpBRE9TLCBuYS5ybSA9IFRSVUUpDQptZWFuKGJhamFzMyRESUFTLlRSQUJBSkFET1MsIG5hLnJtID0gVFJVRSkNCnNkKGJhamFzMyRESUFTLlRSQUJBSkFET1MsIG5hLnJtID0gRkFMU0UpDQoNClZhcmlhYmxlPC1jKCJEaWFzIFRyYWJhamFkb3MiKQ0KTWVkaWFuYTwtYygiMTkiKQ0KTWVkaWEgPC0gYygiNDUiKQ0KRGVzdmlhY2nDs25fZXN0YW5kYXI8LWMoIjkwIikNCnRhYmxlYmFqYSA8LSB0aWJibGUgKFZhcmlhYmxlLCBNZWRpYW5hICwgTWVkaWEgLCBEZXN2aWFjacOzbl9lc3RhbmRhcikNCmtuaXRyOjprYWJsZSh0YWJsZWJhamEpDQoNCmBgYA0KIyMjIEdyYXBocyANCiMjIyMgVGFibGEgQ3J1emFkYSAxDQpFbiBsYSB0YWJsYSB2ZW1vcyBxdWUgc2UgZGVzdGFjYW4gdHJlcyByYXpvbmVzIHByaW5jaXBhbGVzIGRlIGJhamFzIGRlIGVtcGxlYWRvcywgbGFzIGN1YWxlcyBzb246IGJhamFzIHBvciBmYWx0YXMsIHJlbnVuY2lhIHZvbHVudGFyaWEgbyB0w6lybWlubyBkZSBjb250cmF0by4gRW4gc3UgbWF5b3LDrWEsIGh1Ym8gdW5hIGJhamEgcG9yIGZhbHRhcyBkZWwgcHVlc3RvIGRlIGF5dWRhbnRlIGdlbmVyYWwgeSByZW51bmNpYSB2b2x1bnRhcmlhIHBhcmEgZWwgbWlzbW8gcHVlc3RvLiBBbCBpZ3VhbCBxdWUgZW4gbGEgYmFzZSBkZSBkYXRvcyBhbnRlcmlvciwgdmVtb3MgcXVlIGVsIHB1ZXN0byBjb24gbWF5b3Igcm90YWNpw7NuIGEgbml2ZWwgaGlzdMOzcmljbyBlcyBkZSBheXVkYW50ZSBnZW5lcmFsLiBFc3RvIHN1Z2llcmUgcXVlIGV4aXN0ZSB1biBhbHRvIG7Dum1lcm8gZGUgY29udHJhdGFjaW9uZXMgcGFyYSBlbCBwdWVzdG8gZGViaWRvIGEgdW5hIG1hbGEgZ2VzdGnDs24gYWRtaW5pc3RyYXRpdmEgbyBiYWpvIHJlbmRpbWllbnRvIGRlIGxvcyBlbXBsZWFkb3MuDQpgYGB7cn0NCg0KdGFibGUoYmFqYXMzJFBVRVNUTywgYmFqYXMzJE1PVElWTy5ERS5CQUpBKQ0KYGBgDQoNCiMjIyMgVGFibGEgQ3J1emFkYSAyIA0KTGEgdGFibGEgY3J1emFkYSBhbnRlcmlvciBub3MgbXVlc3RyYSBsYSByZWxhY2nDs24gZW50cmUgbG9zIG1vdGl2b3MgZGUgYmFqYSBjb250cmEgZWwgZ8OpbmVybywgZXMgZGVjaXIsIGxhcyBwcmluY2lwYWxlcyByYXpvbmVzIGRlIGJhamEgZGUgYWN1ZXJkbyBhbCBnw6luZXJvIGRlIGNhZGEgZW1wbGVhZG8uIFZlbW9zIHF1ZSBodWJvIHVuIHRvdGFsIGRlIDUzIGJhamFzIGRlbCBnw6luZXJvIGZlbWVuaW5vLCBkZXN0YWNhbmRvIGxhcyBiYWphcyBwb3IgZmFsdGFzIChyZXByZXNlbnRhIHVuIDc1JSBkZSBsYXMgYmFqYXMgZmVtZW5pbmFzKS4gUGFyYSBlbCBnw6luZXJvIG1hc2N1bGlubywgaHVibyB1biB0b3RhbCBkZSAyNSBmYWx0YXMsIGRlc3RhY2FuZG8gcHJpbmNpcGFsbWVudGUgbGFzIGJhamFzIHBvciBmYWx0YXMgKHJlcHJlc2VudGEgdW4gNjAlIGRlIGxhcyBiYWphcyBtYXNjdWxpbmFzKS4gDQpgYGB7cn0NCg0KdGFibGUoYmFqYXMzJEdFTkVSTywgYmFqYXMzJE1PVElWTy5ERS5CQUpBKQ0KYGBgDQoNCiMjIyMgR3LDoWZpY29zIGRlIGRhdG9zIGN1YW50aXRhdGl2b3MgeSBjdWFsaXRhdGl2b3MgDQoNCkxhIGdyw6FmaWNhIG5vcyBtdWVzdHJhIHF1ZSBoYXkgdW4gbWF5b3IgbsO6bWVybyBkZSBleC1lbXBsZWFkb3MgcXVlIHZpdmVuIGVuIGVsIEVzdGFkbyBkZSBOdWV2byBMZcOzbi4gU2luIGVtYmFyZ28sIGhheSB1biBwb3JjZW50YWplIHF1ZSByZXNpZGUgZW4gQ29haHVpbGEuIEVzdG8gc2UgcHVlZGUgaW50ZXJwcmV0YXIgY29uIHF1ZSBoYXkgdW4gYWx0byBuaXZlbCBkZSByb3RhY2nDs24gZXhpc3RlbnRlIGRlYmlkbyBhIGxhIGxlamFuw61hIGRlIHJlc2lkZW5jaWEgZGUgbG9zIGVtcGxlYWRvcy4NCg0KYGBge3Igd2FybmluZz1GQUxTRX0NCg0KcGllKHRhYmxlKGJhamFzMyRFU1RBRE8pLCBjb2w9Yygib3JhbmdlIiwiY29yYWwxIiksDQogICAgbWFpbj0iUmVwcmVzZW50YWNpw7NuIGRlIGJhamFzIGFjb3JkZSBhbCBlc3RhZG8gZGUgcmVzaWRlbmNpYSIpDQpgYGANCg0KIyMjIyBHcsOhZmljbyBkZSBQaWUNCg0KTGEgYW50ZXJpb3IgZ3LDoWZpY2EgZGUgcGFzdGVsIHJlYWZpcm1hIGxvIHF1ZSBtZW5jaW9uYW1vcyBhbnRlcmlvcm1lbnRlLiBEZSBhY3VlcmRvIGEgbGFzIGJhamFzIHJlYWxpemFkYXMsIGxhIG1heW9yw61hIGRlIGxvcyBleC1lbXBsZWFkb3Mgc29uIGRlbCBnw6luZXJvIGZlbWVuaW5vLg0KDQpgYGB7ciB3YXJuaW5nPUZBTFNFfQ0KDQpwaWUodGFibGUoYmFqYXMzJEdFTkVSTyksIGNvbD1jKCJvcmFuZ2UiLCJjb3JhbDEiKSwNCiAgICBtYWluPSJSZXByZXNlbnRhY2nDs24gZGUgYmFqYXMgYWNvcmRlIGFsIGfDqW5lcm8iKQ0KDQpgYGANCg0KIyMjIyBHcsOhZmljYSBkZSBkaXNwZXJzacOzbiANCg0KTGEgZ3LDoWZpY2EgZGUgZGlzcGVyc2nDs24gbm9zIG11ZXN0cmEgbGEgaW50ZW5zaWRhZCBkZSByZWxhY2nDs24gZW50cmUgbGEgdmFyaWFibGUgZGUgZMOtYXMgdHJhYmFqYWRvcyB5IG7Dum1lcm8gZGUgYmFqYXMuIEVzdG8gbm9zIGRpY2UgcXVlIGh1Ym8gdW4gYWx0byBuw7ptZXJvIGRlIGJhamFzIGRlIGVtcGxlYWRvcyBxdWUgdHJhYmFqYXJvbiBtZW5vcyBkZSAyMDAgZMOtYXMsIGVzIGRlY2lyLCBsYSBtYXlvcsOtYSBkZSBsb3MgZXgtZW1wbGVhZG9zIGVzdHV2aWVyb24gZW4gRk9STSBtZW5vcyBkZSAxIGHDsW8uIA0KDQpgYGB7ciB3YXJuaW5nPUZBTFNFfQ0KDQoNCnBsb3QoeD0gYmFqYXMzJE5PLkRFLkJBSkFTLA0KICAgICB5PWJhamFzMyRESUFTLlRSQUJBSkFET1MsIG1haW49ICJOdW1lcm8gZGUgYmFqYXMgZW4gY29tcHJhY2nDs24gZGUgbG9zIGRpYXMgbGFib3JhZG9zIiwgeGxhYj0gIk51bWVybyBkZSBCYWphcyIsIHlsYWI9ICJEaWFzIFRyYWJhamFkb3MiKQ0KDQpgYGANCg0KDQojIyMjIEJveHBsb3QgDQpMYSBncsOhZmljYSBhbnRlcmlvciBub3MgbXVlc3RyYSBsYSBjb3JyZWxhY2nDs24gZW50cmUgZWwgZ8OpbmVybyB5IGVsIHNhbGFyaW8gZGlhcmlvIGRlIGxvcyBlbXBsZWFkb3MuIEVuIGVzdGUsIGVudGVuZGVtb3MgcXVlIGVsIGfDqW5lcm8gZmVtZW5pbm8gdGllbmUgdW4gc2FsYXJpbyBkaWFyaW8gdG90YWwgbcOhcyBhbHRvIHF1ZSBsb3MgZGUgZ8OpbmVybyBtYXNjdWxpbm8uDQpgYGB7ciB3YXJuaW5nPUZBTFNFfQ0KDQpnZ3Bsb3QoYmFqYXMzLCBhZXMoR0VORVJPLFNBTEFSSU8uRElBUklPLklNU1MsZmlsbD1HRU5FUk8pKSArDQpnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IikgKw0KICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlNldDIiKSArIGdndGl0bGUoIlNhbGFyaW8gZGlhcmlvIHBvciBnw6luZXJvIikNCmBgYA0KDQoNCg0KIyMgQ29uY2x1c2nDs25lcywgUHJvcHVlc3RhcyB5IEhhbGxhemdvcyBDb2xhYm9yYWRvcmVzIHkgQmFqYXMgDQoNClByaW1lcm8gcXVlIG5hZGEsIGVzIGJ1ZW5vIGVzcGVjaWZpY2FyIGxhIHV0aWxpemFjacOzbiBkZSB1bmEgYnVlbmEgbGltcGllemEgZGUgZGF0b3MsIGNvbW8gZXNwZWNpZmlxdWUgYW50ZXJpb3JtZW50ZSwgcHVkaW1vcyBub3RhciB1bmEgbWVqb3JhIGVuIGxhcyBiYXNlcyBkZSBkYXRvcyB5IGxhIG1hbmlwdWxhY2nDs24gZGUgZWxsYXMgYWwgbm8gdGVuZXIgdmFsb3JlcyB2YWNpb3MgZGVudHJvIGRlIG51ZXN0cmFzIGJhc2VzIGRlIHJlY3Vyc29zIGh1bWFub3MsIGVzdG8gdGFtYmllbiBub3MgcGVybWl0acOzIGdlbmVyYXIgaW5zaWdodHMgaW1wb3J0YW50ZXMgY29tbzogDQoxLiBMYXMgbXVqZXJlcyBnYW5hbiBtZWpvciBxdWUgbG9zIGhvbWJyZXMgZGVudHJvIGRlIGxhIGVtcHJlc2EgRk9STSANCjIuIExhcyBtdWplcmVzIHNvbiBsYXMgcXVlIG3DoXMgcmVudW5jaWFuIA0KMy5Mb3MgZW1wbGVhZG9zIGNvbiBtZW5vcyBkZSAyMDAgZMOtYXMgc2Ugdmllcm9uIG1lbm9zIGxlYWxlcyBhIGxhIGVtcHJlc2EgDQoNCkRlIGFxdcOtIHRhbWJpw6luIHN1cmdpZXJvbiBkaXN0aW50b3MgdGlwb3MgZGUgcHJvcHVlc3RhcyBjb21vOiAgDQoxLiBEZXNnbG9zYXIgc2kgbGFzIG11amVyZXMgcXVlIHJlbnVuY2lhcm9uIHRpZW5lbiBmYW1pbGlhcyB5IHNpIGVzIGFzw60gdmVyIGxhIG1hbmVyYSBlbiBsYSBjdWFsIHNlIHB1ZWRhbiBkYXIgYmFuYWZpY2lvcyBwYXJhIGxvcyBoaWpvcy4gDQoyLiBJbXBsZW1lbnRhciB1biBwbGFuIGRlIG1vdGl2YWRvcmVzIGRlc2RlIHF1ZSBsbGVnYSBlbCBwcmltZXIgZW1wbGVhZG8uIA0KMy4gSGFjZXIgdW4gcGxhbiB0b3VjaHBvaW50cyBpbnRlcm5vcyBjb24gbG9zIGVtcGxlYWRvcyBwYXJhIGRpc21pbnVpciBsYSB0YXNhIGRlIHJvdGFjacOzbi4gDQoNCg0KDQojIDxzcGFuIHN0eWxlID0gImNvbG9yOmRhcmtvcmFuZ2UiPiBEZWxpdmVyeSBQbGFuDQoNCiMjIFNlY2Npw7NuIDEuIExpbXBpZXphIGRlIGRhdG9zLCBUcmFuc2Zvcm1hY2nDs24geSBFbnRlbmRpbWllbnRvICgxLTQpDQojIyMgSW1wb3J0YXIgbGEgYmFzZSBkZSBkYXRvcyAgIA0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCiNmaWxlLmNob29zZSgpDQpkZWxpdmVyeTwtcmVhZC5jc3YoIkM6XFxVc2Vyc1xcZGFueWNcXERvd25sb2Fkc1xcREVMSVZFUlkuY3N2IikNCnN1bW1hcnkoZGVsaXZlcnkpDQpgYGANCjxzdHlsZT4NCmRpdi5ibHVlIHsgYmFja2dyb3VuZC1jb2xvcjojRkZEQkM4OyBib3JkZXItcmFkaXVzOiA1cHg7IHBhZGRpbmc6IDIwcHg7fQ0KPC9zdHlsZT4NCjxkaXYgY2xhc3MgPSAiYmx1ZSI+DQpOb3RhczoNCg0KMS5TZSBoaXpvIGxpbXBpZXphIG1hbnVhbCBkZSBsYSBiYXNlIGRlIGRhdG9zIHBhcmEgYWNvbW9kYXIgbG9zIGNsaWVudGVzIGNvbW8gdmFyaWFibGVzIHkgbGFzIGZlY2hhcyBjb21vIHJlZ2lzdHJvcy4NCg0KMi5TZSBzdXN0aXR1eWVyb24gTkFzIHBvciBjZXJvLg0KDQozLlNlIGVsaW1pbmFyb24gY29sdW1uYXMgbm8gdXNhZGFzIHkgcXVlIG5vIGFncmVlZ2FuIHZhbG9yIHBhcmEgZWwgYW5hbGlzaXMgcXVlIHNlIGJ1c2NhIGhhY2VyLg0KDQo8L2Rpdj4NCg0KIyMjIERlc2NhcmdhciBsaWJyZXLDrWFzIHkgcGFxdWV0ZXMgDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbGlicmFyeShmb3JlaWduKQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkoZm9yY2F0cykNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkocmVhZHIpDQpsaWJyYXJ5KGphbml0b3IpDQpsaWJyYXJ5KG5hbmlhcikNCmxpYnJhcnkoZGxvb2tyKQ0KYGBgDQoNCiMjIyBWYXJpYWJsZXMgeSBSZWdpc3Ryb3MgDQo8Y2VudGVyPiA8c3BhbiBzdHlsZT0iY29sb3I6UmVkIj4gUj0gMyB2YXJpYWJsZXMgeSAzODAgb2JzZXJ2YWNpb25lcy48L2NlbnRlcj4NCmBgYHtyfQ0Kc3RyKGRlbGl2ZXJ5KQ0KYGBgDQoNCiMjIyBDb250YXIgdG90YWwgZGUgcGVkaWRvcyBwb3IgY2xpZW50ZSANCipDb250YW1vcyBjb24gNTIsMDI4MSBwZWRpZG9zKg0KYGBge3J9DQpkZWxpdmVyeVNVTSA9IGNvbFN1bXMoZGVsaXZlcnlbNF0pDQoNCmFzLmRhdGEuZnJhbWUoZGVsaXZlcnlTVU0pDQpgYGANCg0KIyMjIEltcG9ydGFyIEJhc2UgQ2xpZW50ZXMgZm9ybSANCkNvbiBlc3RlIHBsb3QgcG9kZW1vcyB2ZXIgcXVlIGhheSBtdWNob3MgY2xpZW50ZXMgY29uIG11eSBwb2NvcyBwZWRpZG9zLg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCiNmaWxlLmNob29zZSgpDQpkZWxpdmVyeUNMSUVOVFM8LXJlYWQuY3N2KCJDOlxcVXNlcnNcXGRhbnljXFxEb3dubG9hZHNcXERlbGl2ZXJ5Q0xJRU5UUy54bHN4IC0gU2hlZXQxLmNzdiIpDQpzdW1tYXJ5KGRlbGl2ZXJ5Q0xJRU5UUykNCmBgYA0KDQpgYGB7cn0NCmRlbGl2ZXJ5Q0xJRU5UUyA9IGNvbFN1bXMoZGVsaXZlcnlDTElFTlRTWzI6MjFdKQ0KYXMuZGF0YS5mcmFtZShkZWxpdmVyeUNMSUVOVFMpDQpiYXJwbG90LmRlZmF1bHQoZGVsaXZlcnlDTElFTlRTKQ0KYGBgDQoNCg0KIyMjIFTDqWNuaWNhIDE6IGVsaW1pbmFyIE5BcyANClNlIGRlY2lkacOzIHJlYWxpemFyIGVzdMOhIHTDqWNuaWNhIHBhcmEgYXNlZ3VyYXJub3MgZGUgcXVlIG5vIHNlIHRlbmdhIGZhbHRhIGRlIGRhdG9zIHkgZW4gY2FzbyBkZSB0ZW5lcmxvcyBldml0YXIgcXVlIGVzdGFzIGV2aXRlbiB0ZW5lciB1biBhbmFsaXNpcyBhc2VydGl2byBhbCBubyBhZ3JlZ2FyIHZhbG9yIGEgbGEgYmFzZSBkZSBkYXRvcy4gDQoNCiMjIyMgwr9DdWFudG9zIE5BIHRlbmdvIGVuIGxhIGJhc2UgZGUgZGF0b3M/ICAgIA0KYGBge3J9DQpzdW0oaXMubmEoZGVsaXZlcnkpKQ0KYGBgDQoNCiMjIyMgwr9DdWFudG9zIE5BIHRlbmdvIHBvciB2YXJpYWJsZSAgDQoqKlNhcHBseToqKiBQYXJhIGNvbnRhciBsb3MgTkEuDQpTZSBlbmNvbnRyw7MgdW4gc29sbyBOQQ0KYGBge3J9DQpzYXBwbHkoZGVsaXZlcnksIGZ1bmN0aW9uKHgpIHN1bShpcy5uYSh4KSkpDQpgYGANCg0KDQojIyMgVMOpY25pY2EgMjogZWxpbWluYXIgZmlsYXMgIA0KU2UgZGVjaWTDsyByZWFsaXphciBlc3TDoSB0w6ljbmljYSBwYXJhIGVsaW1pbmFyIGxvcyBjbGllbnRlcyBxdWUgdGllbmVuIG1lbm9zIGRlIDUsMDAwIHBlZGlkb3MuIA0KDQojIyMjIEVsaW1pbmFyIGZpbGFzIGNvbiBlbCBub21icmUgZGUgbG9zIGNsaWVudGVzIHF1ZSBzZSBkZXNlYW4gZWxpbWluYXIuICAgDQpgYGB7cn0NCg0KI2RlbGl2ZXJ5MSA8LSBzdWJzZXQgKGRlbGl2ZXJ5MSwgIENMSUVOVEUgPT0gIlNUQjMiKSAjUGFyYSBjb25zZXJ2YXIgY2llcnRhcyBmaWxhcw0KDQpkZWxpdmVyeTE8LWRlbGl2ZXJ5DQoNCmRlbGl2ZXJ5MTwtZGVsaXZlcnkxW2RlbGl2ZXJ5MSRDTElFTlRFIT0iU1RCIDEiLCBdDQpkZWxpdmVyeTE8LWRlbGl2ZXJ5MVtkZWxpdmVyeTEkQ0xJRU5URSE9IllGIFJBTU9TIiwgXQ0KZGVsaXZlcnkxPC1kZWxpdmVyeTFbZGVsaXZlcnkxJENMSUVOVEUhPSJJTk9BQyBQT0xZVEVDIiwgXQ0KZGVsaXZlcnkxPC1kZWxpdmVyeTFbZGVsaXZlcnkxJENMSUVOVEUhPSJNRVJJRElBTiIsIF0NCmRlbGl2ZXJ5MTwtZGVsaXZlcnkxW2RlbGl2ZXJ5MSRDTElFTlRFIT0iWUFORkVORyBzbSIsIF0NCmRlbGl2ZXJ5MTwtZGVsaXZlcnkxW2RlbGl2ZXJ5MSRDTElFTlRFIT0iWUYgUVJPIiwgXQ0KZGVsaXZlcnkxPC1kZWxpdmVyeTFbZGVsaXZlcnkxJENMSUVOVEUhPSJTRUdST1ZFIiwgXQ0KZGVsaXZlcnkxPC1kZWxpdmVyeTFbZGVsaXZlcnkxJENMSUVOVEUhPSJIQU5PTiIsIF0NCmRlbGl2ZXJ5MTwtZGVsaXZlcnkxW2RlbGl2ZXJ5MSRDTElFTlRFIT0iQU5UT0xJTiBUT0xVQ0EiLCBdDQpkZWxpdmVyeTE8LWRlbGl2ZXJ5MVtkZWxpdmVyeTEkQ0xJRU5URSE9IkFOVE9MSU4gQVJURUFHQSIsIF0NCmRlbGl2ZXJ5MTwtZGVsaXZlcnkxW2RlbGl2ZXJ5MSRDTElFTlRFIT0iQUJDIFFVRVJFVEFSTyIsIF0NCmRlbGl2ZXJ5MTwtZGVsaXZlcnkxW2RlbGl2ZXJ5MSRDTElFTlRFIT0iVUZJIiwgXQ0KZGVsaXZlcnkxPC1kZWxpdmVyeTFbZGVsaXZlcnkxJENMSUVOVEUhPSJJU1JJIiwgXQ0KDQpzdW1tYXJ5KGRlbGl2ZXJ5MSkNCmBgYA0KDQojIyMgQ2xhc2lmaWNhY2nDs24gZGUgVmFyaWFibGVzIA0KDQpgYGB7cn0NClZhcmlhYmxlPC1jKCJGZWNoYSIsIlNUQjMiLCJZRlRPIiwgIlRSTVgiLCAiREVOU08iLCJIRUxMQSIsIlZBUlJPQyIsIlRvdGFsLnBlZGlkb3MubWVzIikNClR5cGU8LWMoIkN1YW50aXRhdGl2YSAoZGlzY3JldGEpIiwgIkN1YWxpdGF0aXZhIiwgIkN1YWxpdGF0aXZhIiwgIkN1YWxpdGF0aXZhIiwiQ3VhbGl0YXRpdmEiLCJDdWFsaXRhdGl2YSIsIkN1YWxpdGF0aXZhIiwiQ3VhbnRpdGF0aXZhIChkaXNjcmV0YSkiKQ0KTWVhc3VyZW1lbnQ8LWMoIlJhesOzbiIsIk5vbWluYWwiLCJOb21pbmFsIiwiTm9taW5hbCIsIk5vbWluYWwiLCJOb21pbmFsIiwiTm9taW5hbCIsIlJhesOzbiIpDQp0YWJsZTI8LXRpYmJsZShWYXJpYWJsZSxUeXBlLE1lYXN1cmVtZW50KQ0KDQprbml0cjo6a2FibGUodGFibGUyKQ0KYGBgDQojIyAxLiBBbsOhbGlzaXMgRXN0YWTDrXN0aWNvIERlbGl2ZXJ5IFBsYW4gKDUpDQojIyMgR3JhcGhzIA0KDQojIyMjIEdyw6FmaWNhIGN1YWxpdGF0aXZhICANCkNvbiBlc3RhIGdyw6FmaWNhIHBvZGVtb3MgZGFybm9zIGN1ZW50YSBkZSBsb3MgY2xpZW50ZXMgcXVlIHRpZW5lbiBtYXlvcmVzIHBlZGlkb3MgeSBlbiBlc3RlIGNhc28gZXMgSEVMTEEgZW4gcHJpbWVyIGx1Z2FyIHkgVFJNWCBlbiBzZWd1bmRvIGx1Z2FyLCBsbyBjdWFsIG5vcyBpbmRpY2EgcXVlIHNvbiBsb3MgbWVqb3JlcyBjbGllbnRlcyBwb3IgaW55ZWN0YXJsZSBtw6FzIGZsdWpvIGRlIGNvbXByYXMgYSBsYSBlbXByZXNhLg0KDQpgYGB7cn0NCiNpbnN0YWxsLnBhY2thZ2VzKCJwbHlyIikNCg0KbGlicmFyeShwbHlyKQ0KZGVsaXZlcnkyPC1kZWxpdmVyeTENCmRlbGl2ZXJ5MjwtIGFnZ3JlZ2F0ZShkZWxpdmVyeTIkUGVkaWRvcywgYnk9bGlzdChjYXRlZ29yeT1kZWxpdmVyeTIkQ0xJRU5URSksIEZVTj1zdW0pDQoNCnBpZShkZWxpdmVyeTIkYHN1bS5kZWxpdmVyeTIkUGVkaWRvc2AsIGxhYmVscyA9IGRlbGl2ZXJ5MiRjYXRlZ29yeSkNCmBgYA0KDQojIyMjIEdyw6FmaWNhIGN1YW50aXRhdGl2YSANCg0KRXN0YSBncsOhZmljYSBzaXJ2ZSBwYXJhIHRlbmVyIGRlIG1hbmVyYSBtw6FzIHZpc3VhbCBlbCBpbXBhY3RvIHF1ZSB0aWVuZSBjYWRhIHVubyBkZSBsb3MgY2xpZW50ZXMgZW4gbGEgZW1wcmVzYSBGT1JNLiBQb2RlbW9zIHZlciBxdWUgSEVMTEEgZXMgZWwgY2xpZW50ZSBtw6FzIHNpZ25pZmljYXRpdm8gY29uIGNhc2kgZWwgdHJpcGxlIGRlIHBlZGlkb3MgcXVlIGVsIHNpZ3VpZW50ZSBjbGllbnRlIGNvbiBtYXlvcmVzIHBlZGlkb3MsIFRSTVguIERlIGxhZG8gZGVyZWNobyBzZSB0aWVuZSB1biBsZWdlbmQgcXVlIG11ZXN0cmEgbGEgdG9uYWxpZGFkIGRlIGxvcyBwbG90cyBwYXJhIHZlciBxdWUgdGFudG9zIHBlZGlkb3MgdGllbmUsIHBvciBlbGxvIEhFTExBUyB0aWVuZSB1biBjb2xvciBhenVsIGNsYXJvLCByZXByZXNlbnRhbmRvIG3DoXMgZGUgMjUwLDAwMCBwZWRpZG9zLiANCg0KYGBge3J9DQpkZWxpdmVyeTI8LWRlbGl2ZXJ5MiAlPiUgZHBseXI6OnJlbmFtZShwZWRpZG9zPSJzdW0uZGVsaXZlcnkyJFBlZGlkb3MiKQ0KZGVsaXZlcnkyPC1kZWxpdmVyeTIgJT4lIGRwbHlyOjpyZW5hbWUoQ2xpZW50ZXM9ImNhdGVnb3J5IikNCg0KZGVsaXZlcnkyJENsaWVudGVzPC1hcy5mYWN0b3IoZGVsaXZlcnkyJENsaWVudGVzKQ0KZ2dwbG90KGRlbGl2ZXJ5MiwgYWVzKHg9Q2xpZW50ZXMsIHk9cGVkaWRvcywgZmlsbD1wZWRpZG9zKSkrDQogICAgICAgICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIpKw0KICAgICAgICAgdGhlbWVfbWluaW1hbCgpKw0KICAgICAgICAgbGFicyh0aXRsZT0iUGVkaWRvcyBwb3IgY2xpZW50ZSIpDQpgYGANCg0KIyMjIyBHcsOhZmljYSBkZSBsw61uZWFzICANCioqQ29tcG9ydGFtaWVudG8gZGUgY2xpZW50ZXMgcG9yIGZlY2hhICoqIA0KQ29uIGVzdGEgZ3LDoWZpY2EgdXRpbGl6YW1vcyBlbCBJRCBGZWNoYSBwYXJhIGNvbm9jZXIgbG9zIHBlZGlkb3MgcXVlIHNlIHRpZW5lIHBvciBjbGllbnRlIGNhZGEgbWVzIHkgdmVtb3MgdW4gc2lnbmlmaWNhdGl2byBpbmNyZW1lbnRvIGRlIHBlZGlkb3MgZW4gZWwgbWVzIGRlIHNlcHRpZW1icmUgeSBvY3R1YnJlLiBjb250YW1vcyBjb24gdW4gbGVnZW5kIHF1ZSBpbmRpY2EgY2FkYSBsw61uZWEgY29uIHVuIGNvbG9yIHBhcmEgbm9tYnJhciBsYSBpbmZvcm1hY2nDs24gZGUgY2FkYSB1bm8gZGUgbG9zIGNsaWVudGVzLiANCmBgYHtyfQ0Kc3VtbWFyeShkZWxpdmVyeTEpDQoNCmdncGxvdChkZWxpdmVyeTEsYWVzKHg9SURfRmVjaGEsIHk9UGVkaWRvcywgZ3JvdXA9Q0xJRU5URSxjb2xvdXI9Q0xJRU5URSkpKw0KICBnZW9tX2xpbmUoKSsNCiAgZ2d0aXRsZSgiQ29tcG9ydGFtaWVudG8gZGUgY2xpZW50ZXMgcG9yIGZlY2hhIikNCmBgYA0KDQojIyMjIEJveHBsb3QgDQpFbiBlc3RhIGdyw6FmaWNhIHBvZGVtb3MgdmlzdWFsaXphciBjdWFudG9zIHBlZGlkb3MgdGllbmUgcHJvZ3JhbWFkb3MgY2FkYSBjbGllbnRlIHkgbG9zIGNsaWVudGVzIHF1ZSBzb2JyZSBzYWxlbiBzb24gSEVMTEEgeSBUUk1YLCBhbGdvIG11eSByZWxldmFudGUgZW4gZXN0YSBncsOhZmljYSBlcyBxdWUgc2UgbXVlc3RyYSBsYSBtb2RhIGRlIGNhZGEgdW5vLCBhc8OtIGNvbW8gdGFtYmnDqW4gbGEgbWluaW1hIGRlIHBlZGlkb3MgeSBsYSBtw6F4aW1hLCB5IGVuIGVzdGUgY2FzbyBubyBzZSB0aWVuZSB1bmEgZGlzcGVyc2nDs24gcG9yIG5pbmd1bm8gZGUgbG9zIGNsaWVudGVzLiANCmBgYHtyfQ0KYm94cGxvdChkZWxpdmVyeTEkUGVkaWRvcywgbWFpbj0gIlBlZGlkb3MiKQ0KDQpkZWxpdmVyeTM8LWRlbGl2ZXJ5MQ0KZGVsaXZlcnkzJENMSUVOVEUgPC1hcy5mYWN0b3IoZGVsaXZlcnkzJENMSUVOVEUpDQpnZ3Bsb3QoZGVsaXZlcnkzLCBhZXMoeD1DTElFTlRFLCB5PVBlZGlkb3MpKSsNCiAgZ2VvbV9ib3hwbG90KGNvbG9yPSJibHVlIiwgZmlsbD0icHVycGxlIikNCmBgYA0KDQoNCiMjIyBQcm9wdWVzdGFzIA0KMS4gSGFjZXIgdW5hIHByZWRpY2Npw7NuIGFjZXJjYSBkZSBsb3MgcGVkaWRvcyBtZW5zdWFsZXMgcG9yIGNsaWVudGUgcGFyYSB2ZXIgYSBjdWFsZXMgZGFybGVzIHByaW9yaWRhZGVzIHkgYmVuZWZpY2lvcyBxdWUgY3JlZW4gdW5hIGxlYWx0YWQgaGFjw61hIEZPUk0uDQoNCiMjIFNlY2Npw7NuIDIuIEFuw6FsaXNpcyBFeHBsb3JhdG9yaW8gDQojIyMgVGFibGEgZGUgTWVkaWFuYSwgTWVkaWEgeSBTdC4gRGV2aWF0aW9uIA0KRGVudHJvIGRlIERlbGl2ZXJ5LCBwb2RlbW9zIHZlciB1bmEgbWVkaWEgZGUgbcOhcyBkZSA1LDAwMCBsbyBjdWFsIG5vcyBpbmRpY2EgdW5hIG11eSBidWVuYSBjYW50aWRhZCBlbiBwcm9tZWRpbyBtZW5zdWFsIHkgbGEgZGVzdmlhY2nDs24gZXN0YW5kYXIgZGUgMTAwOTMgbG8gY3VhbCBub3MgaW5kaWNhIHVuYSBkaXNwZXJzacOzbiBpZ3VhbCBhIGxhIG1lZGlhbmEgZGVudHJvIGRlbCByYW5nbywgbm8gZXMgbXV5IHNpZ25pZmljYXRpdm8gcGFyYSBlc3RlIGNhc28uDQpgYGB7cn0NCm1lZGlhbihkZWxpdmVyeTEkUGVkaWRvcywgbmEucm0gPSBUUlVFKQ0KbWVhbihkZWxpdmVyeTEkUGVkaWRvcywgbmEucm0gPSBUUlVFKQ0Kc2QoZGVsaXZlcnkxJFBlZGlkb3MsIG5hLnJtID0gRkFMU0UpDQoNClZhcmlhYmxlPC1jKCJQZWRpZG9zIikNCk1lZGlhbmE8LWMoIjEwMDkiKQ0KTWVkaWEgPC0gYygiNTMzOS4xNiIpDQpEZXN2aWFjacOzbl9lc3RhbmRhcjwtYygiMTAwOTMuMTkiKQ0KdGFibGVwbGFuIDwtIHRpYmJsZSAoVmFyaWFibGUsIE1lZGlhbmEgLCBNZWRpYSAsIERlc3ZpYWNpw7NuX2VzdGFuZGFyKQ0Ka25pdHI6OmthYmxlKHRhYmxlcGxhbikNCmBgYA0KIyMjIEdyYXBocyAgDQojIyMjIFRhYmxhIGRlIGRpc3BlcnNpw7NuDQpEZW50cm8gZGUgZXN0YSB0YWJsYSBwb2RlbW9zIHZpc3VhbGl6YXIgbGEgY2FudGlkYWQgZGUgcGVkaWRvcyBxdWUgc2UgbWFuZWphbiBtZW5zdWFsbWVudGUgbm8gdGllbmVuIHVuYSB2YXJpYWJsZSB0YW4gYW1wbGlhLCBwb3IgbG8gY3VhbCBzZSBtYW50aWVuZSBlc3RhYmxlIGR1cmFudGUgZWwgMjAyMiwgbG8gY3VhbCBub3MgZGljZSBkZSB1biBmbHVqbyBzaWVtcHJlIG1heW9yIGEgMCBkdXJhbnRlIGxvcyBtZXNlcy4NCmBgYHtyfQ0KcGxvdCh4PSBkZWxpdmVyeTEkSURfRmVjaGEsIHk9IGRlbGl2ZXJ5MSRQZWRpZG9zLCBjb2w9ZGVsaXZlcnkxJElEX0ZlY2hhKQ0KYGBgDQoNCiMjIyBIYWxsYXpnb3MgIA0KDQpQYXJhIHJlYWxpemFyIGVsIGFuw6FsaXNpcyBkZSBsYSBiYXNlIGRlIGRhdG9zIGRlICJEZWxpdmVyeSBQbGFuIiBmdcOpIG5lY2VzYXJpbyBwcmltZXJvIGhhY2VyIHVuIGFycmVnbG8gZGUgbGEgYmFzZSBkZSBkYXRvcyBkZSBtYW5lcmEgbWFudWFsIGVuIGVsIGV4Y2VsLiBFc3TDsyBwYXJhIHNpbXBsaWZpY2FyIGVsIHVzbyBkZSBsYSBiYXNlIGRlIGRhdG9zIHkgcGVybWl0aXIgcXVlIFIgcHVlZGEgYW5hbGl6YXJsYSB5IGV4dHJhZXIgbG9zIGRhdG9zIHBhcmEgZ2VuZXJhciBncsOhZmljYXMuIERlc3B1w6lzIGFwbGljYW1vcyBkb3MgZGlmZXJlbnRlcyBiYXNlcyBkZSBkYXRvcywgbm9zIGFzZWd1cmFtb3MgZGUgcXVlIG5vIGhheWEgTkFzIHkgZWxpbWluYW1vcyBmaWxhcyBxdWUgY29ycmVzcG9uZMOtYW4gYSBsb3MgY2xpZW50ZXMgcXVlIHRlbsOtYW4gbWVub3MgZGUgNSwwMDAgcGVkaWRvcy4gTm9zIHF1ZWRhbW9zIGNvbiB1bmEgYmFzZSBkZSBkYXRvcyBjb24gbG9zIDYgY2xpZW50ZXMgbcOhcyBzaWduaWZpY2F0aXZvcyBwYXJhIEZPUk0uIENvbnRpbnVhbW9zIGlkZW50aWZpY2FuZG8gbGFzIHZhcmlhYmxlcyBlbiBkw7NuZGUgNiBkZSA4IHZhcmlhYmxlcyBlcmFuIGN1YWxpdGF0aXZhcyBhbCBzZXIgbG9zIGNsaWVudGVzIGRlIEZPUk0uIA0KDQpHcmFmaWNhbW9zIHVuYSBncsOhZmljYSBkZSBQaWUgcGFyYSBpZGVudGlmaWNhciBkZSBtYW5lcmEgdmlzdWFsIGxvcyBtYXlvcmVzIGNsaWVudGVzLCBsb3MgcXVlIHZpZW5lbiBzaWVuZG8gSEVMTEEgeSBUUk1YLiBUYW1iacOpbiBoaWNpbW9zIHVuICJCYXJwbG90IiBwYXJhIG1vc3RyYXIgbGEgY2FudGlkYWQgZGUgcGVkaWRvcyBwcm9ncmFtYWRvcyBxdWUgdGllbmUgY2FkYSBjbGllbnRlLCBIZWxsYSBzaWVuZG8gZWwgY2xpZW50ZSBjb24gbWF5b3IgcGVkaWRvcyBjb24gbcOhcyBkZSAyMjUsMDAwIHkgVFJNWCBzaWd1aWVuZG8gY29uIDgwLDAwMC4gRGVjaWRpbW9zIHRhbWJpw6luIHZpc3VhbGl6YXIgZWwgY29tcG9ydGFtaWVudG8gZGUgbG9zIGNsaWVudGVzIHNlZ8O6biBsYSBmZWNoYSB5IG5vcyBkaW1vcyBjdWVudGEgcXVlIGVudHJlIGVsIG1lcyBkZSBzZXB0aWVtYnJlIHkgb2N0dWJyZSBodWJvIHVuIGluY3JlbWVudG8gZGUgcGVkaWRvcyBlc3RhYmxlY2lkb3MuIFkgcG9yIMO6bHRpbW8gc2UgcmVhbGl6w7MgZWwgIkJveHBsb3QiIHBhcmEgZGUgZXNlIG1vZG8gdmVyIGRlIG1hbmVyYSBwcmVjaXNhIGxhIG1vZGEgZGUgY2xvcyBwZWRpZG9zIHF1ZSBzdWVsZSBoYWNlciBjYWRhIHVubyBkZSBsb3MgY2xpZW50ZXMuIA0KDQoNCiMgPHNwYW4gc3R5bGUgPSAiY29sb3I6ZGFya29yYW5nZSI+IERlbGl2ZXJ5IFBlcmZvcm1hbmNlIA0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCg0KbGlicmFyeShmb3JlaWduKQ0KbGlicmFyeShkcGx5cikgICAgICAgICMgZGF0YSBtYW5pcHVsYXRpb24gDQpsaWJyYXJ5KGZvcmNhdHMpICAgICAgIyB0byB3b3JrIHdpdGggY2F0ZWdvcmljYWwgdmFyaWFibGVzDQpsaWJyYXJ5KGdncGxvdDIpICAgICAgIyBkYXRhIHZpc3VhbGl6YXRpb24gDQpsaWJyYXJ5KGphbml0b3IpICAgICAgIyBkYXRhIGV4cGxvcmF0aW9uIGFuZCBjbGVhbmluZyANCiNpbnN0YWxsLnBhY2thZ2VzKCJIbWlzYyIpDQojbGlicmFyeShIbWlzYykgICAgICAgICMgc2V2ZXJhbCB1c2VmdWwgZnVuY3Rpb25zIGZvciBkYXRhIGFuYWx5c2lzIA0KI2luc3RhbGwucGFja2FnZXMoInBzeWNoIikNCiNsaWJyYXJ5KHBzeWNoKSAgICAgICAgIyBmdW5jdGlvbnMgZm9yIG11bHRpdmFyaWF0ZSBhbmFseXNpcyANCiNpbnN0YWxsLnBhY2thZ2VzKCJuYW5pYXIiKQ0KI2xpYnJhcnkobmFuaWFyKSAgICAgICAjIHN1bW1hcmllcyBhbmQgdmlzdWFsaXphdGlvbiBvZiBtaXNzaW5nIHZhbHVlcyBOQXMNCiNpbnN0YWxsLnBhY2thZ2VzKCJkbG9va3IiKQ0KI2xpYnJhcnkoZGxvb2tyKSAgIyBzdW1tYXJpZXMgYW5kIHZpc3VhbGl6YXRpb24gb2YgbWlzc2luZyB2YWx1ZXMgTkFzDQojaW5zdGFsbC5wYWNrYWdlcygiY29ycnBsb3QiKQ0KI2xpYnJhcnkoY29ycnBsb3QpICAgICAjIGNvcnJlbGF0aW9uIHBsb3RzDQojaW5zdGFsbC5wYWNrYWdlcygianRvb2xzIikNCiNsaWJyYXJ5KGp0b29scykgICAgICAgIyBwcmVzZW50YXRpb24gb2YgcmVncmVzc2lvbiBhbmFseXNpcyANCiNpbnN0YWxsLnBhY2thZ2VzKCJsbXRlc3QiKQ0KI2xpYnJhcnkobG10ZXN0KSAgICAgICAjIGRpYWdub3N0aWMgY2hlY2tzIC0gbGluZWFyIHJlZ3Jlc3Npb24gYW5hbHlzaXMgDQojaW5zdGFsbC5wYWNrYWdlcygiY2FyIikNCiNsaWJyYXJ5KGNhcikgICAgICAgICAgIyBkaWFnbm9zdGljIGNoZWNrcyAtIGxpbmVhciByZWdyZXNzaW9uIGFuYWx5c2lzDQojaW5zdGFsbC5wYWNrYWdlcygib2xzcnIiKQ0KI2xpYnJhcnkob2xzcnIpICAgICAgICAjIGRpYWdub3N0aWMgY2hlY2tzIC0gbGluZWFyIHJlZ3Jlc3Npb24gYW5hbHlzaXMgDQojaW5zdGFsbC5wYWNrYWdlcygia2FibGVFeHRyYSIpDQojbGlicmFyeShrYWJsZUV4dHJhKSAgICMgSFRNTCB0YWJsZSBhdHRyaWJ1dGVzDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmBgYA0KDQoNCiMjIFNlY2Npw7NuIDE6IExpbXBpZXphIGRlIGRhdG9zLCBUcmFuc2Zvcm1hY2nDs24geSBFbnRlbmRpbWllbnRvIA0KDQpMYXMgdMOpY25pY2FzIGVsZWdpZGFzIGVuIG51ZXN0cmEgbGltcGlhIGRlIGRhdG9zIHNlIGVsaWdpZXJvbiBwb3IgbGFzIG5lY2VzaWRhZGVzIHF1ZSBwcmVzZW50YWJhIGxhIGJhc2UgeSBsYSB1dGlsaWRhZCBvIG5vIHF1ZSB0ZW7DrWFuIG51ZXN0cmFzIHZhcmlhYmxlcyANCmBgYHtyfQ0KI2ZpbGUuY2hvb3NlKCkNCmJhc2VfZGVfZGF0b3M8LXJlYWQuY3N2KCJDOlxcVXNlcnNcXGRhbnljXFxPbmVEcml2ZSAtIEluc3RpdHV0byBUZWNub2xvZ2ljbyB5IGRlIEVzdHVkaW9zIFN1cGVyaW9yZXMgZGUgTW9udGVycmV5XFxEZXNrdG9wXFxGb3JtXFxGb3JtZGVsaXZlcnlmaW5hbDMuY3N2IiApDQpgYGANCg0KIyMjIFZhcmlhYmxlcyB5IFJlZ2lzdHJvcyANCjxjZW50ZXI+IDxzcGFuIHN0eWxlPSJjb2xvcjpSZWQiPiBSPSA4IHZhcmlhYmxlcyB5IDE0NDAgcmVnaXN0cm9zIDwvY2VudGVyPg0KIA0KDQojIyMjIEVudGVuZGVyIGxhIEJEDQpgYGB7cn0NCg0KYmQ8LWJhc2VfZGVfZGF0b3MNCnN1bW1hcnkoYmQpDQpzdHIoYmQpDQpgYGANCg0KIyMjIEVzY2FsYXMgZGUgVmFyaWFibGVzDQpgYGB7cn0NCnZhcmlhYmxlcyA8LSBjKCJgVGFyZ2V0YCIsImBDbGllbnRlYCIsImBWdWVsdGFzYCIsImBQbGFuLmFycml2YWxgIiwiYFJlYWwuYXJyaXZhbGAiLCJgUmVhbC5kZXBhcnR1cmVgIiwiYERpZmVyZW5jZWAiLCJgRmVjaGFgIikNCnRpcG9zIDwtIGMoImN1YW50aXRhdGl2byAoZGlzY3JldG8pICAiLCAiY3VhbGl0YXRpdm8gICIsICJjdWFudGl0YXRpdm8gKGRpc2NyZXRvKSAgIiwgImN1YW50aXRhdGl2byAoY29udGludW8pICAiLCAiY3VhbnRpdGF0aXZvIChjb250aW51bykgICIsICJjdWFudGl0YXRpdm8gKGNvbnRpbnVvKSAgIiwgImN1YW50aXRhdGl2byAoY29udGludW8pICAiLCAiY3VhbGl0YXRpdm8gICIpDQplc2NhbGFzIDwtIGMoImludGVydmFsbyIsICJub21pbmFsIiwgInJhem9uIiwgInJhem9uIiwgInJhem9uIiwgInJhem9uIiwgInJhem9uIiwgIm9yZGluYWwiKQ0KdGFibGUxIDwtIGRhdGEuZnJhbWUgKHZhcmlhYmxlcywgdGlwb3MsIGVzY2FsYXMpDQprbml0cjo6a2FibGUodGFibGUxKQ0KYGBgDQoNCg0KIyMjIyBDT05WRVJTSU9OIERFIENBUkFDVEVSIEEgRkVDSEEgKFRFQ05JQ0EgREUgQ09OVkVSU0lPTiBERSBEQVRPUykgICANCmBgYHtyfQ0KYmQxPC1iZA0KYmQxJEZlY2hhPC0gYXMuRGF0ZShiZDEkRmVjaGEsIGZvcm1hdD0gIiVkLyVtLyV5IikNCnN1bW1hcnkoYmQxKQ0KdGliYmxlKGJkMSkNCmBgYA0KDQoNCiMjIyMgRWxpbWluYXIgY29sdW1uYXMgDQoNCmBgYHtyfQ0KYmQyPC1iZDENCmJkMiA8LSBzdWJzZXQoYmQyLCBzZWxlY3QgPS1jIChUYXJnZXQpKQ0KYGBgDQogKk5vdGE6Kg0KIFNlIGVsaW1pbmEgZWwgdGFyZ2V0IHlhIHF1ZSBubyBub3MgbXVlc3RyYSB1bmEgaW5mb3JtYWNpw7NuIGRldGFsbGFkYSBhbCBkYXJub3MgZGF0b3MgbnVsb3MgZGUgdGVuZXIgdW4gMSBlbiB0b2RvcyBsYWRvcy4NCg0KIyMjIyBMSU1QSUVaQSBQT1IgTUVUT0RPIEVTVEFESVNUSUNPICANCmBgYHtyfQ0KYmQzPC1iZDINCmJveHBsb3QoYmQzJFBsYW4uYXJyaXZhbCwgaG9yaXpvbnRhbD1UUlVFKQ0KYm94cGxvdChiZDMkUmVhbC5hcnJpdmFsLCBob3Jpem9udGFsPVRSVUUpDQpib3hwbG90KGJkMyRSZWFsLmRlcGFydHVyZSwgaG9yaXpvbnRhbD1UUlVFKQ0KDQpib3hwbG90KGJkMyREaWZlcmVuY2UsIGhvcml6b250YWw9VFJVRSkNCmBgYA0KDQojIyMjIEFncmVnYXIgY29sdW1uYSBkZSBwcm9tZWRpbyAgDQpgYGB7cn0NCmJkMyRQcm9tZWRpb19yZWFsX2Fycml2YWw8LSBtZWFuKGJkMyRSZWFsLmFycml2YWwpDQpgYGANCg0KIyMjIyBDb252ZXJ0aXIgdmFyaWFibGVzIGRlIGNhcmFjdGVyIGEgbnVtZXJpY28uICANCmBgYHtyfQ0KYmQzJFZ1ZWx0YXM8LWFzLm51bWVyaWMoYmQzJFZ1ZWx0YXMpICAgICAjIyMgbWlzc2luZyB2YWx1ZXMgYXJlIGNvbnZlcnRlZCB0byBOQSdzDQpiZDMkUGxhbi5hcnJpdmFsPC1hcy5udW1lcmljKGJkMyRQbGFuLmFycml2YWwpICANCmJkMyRSZWFsLmFycml2YWw8LWFzLm51bWVyaWMoYmQzJFJlYWwuYXJyaXZhbCkgIA0KYmQzJFJlYWwuZGVwYXJ0dXJlPC1hcy5udW1lcmljKGJkMyRSZWFsLmRlcGFydHVyZSkgIA0KYmQzJERpZmVyZW5jZTwtYXMubnVtZXJpYyhiZDMkRGlmZXJlbmNlKSAgDQpiZDMkUHJvbWVkaW9fcmVhbF9hcnJpdmFsPC1hcy5udW1lcmljKGJkMyRQcm9tZWRpb19yZWFsX2Fycml2YWwpIA0KDQpiZDM8LWFzLmRhdGEuZnJhbWUoYmQzKSANCmJkMyRGZWNoYTwtYXMuRGF0ZShiZDMkRmVjaGEsZm9ybWF0PSIlbS8lZC8lWSIpIA0KYmQzJENsaWVudGU8LWFzLmZhY3RvcihiZDMkQ2xpZW50ZSkgDQoNCnRpYmJsZShiZDMpDQpgYGANCg0KDQoqTm90YXM6KiANCiBTZSBtdWVzdHJhIHF1ZSBsYSBkaWZlcmVuY2lhIGRlIG51ZXN0cm9zIGFycml2YWxzIG5vIGVzIG11Y2hhLCBwZXJvIGhhYnLDrWEgcXVlIHJldmlzYXIgc2kgZWwgcHJvbWVkaW8gdG90YWwgbm9zIGF5dWRhcsOtYS4gDQogc2UgYWdyZWdvIHVuYSBjb2x1bW5hIGRlIHByb21lZGlvIGdlbmVyYWwgZGUgbnVlc3Ryb3MgYXJyaXZhbHMgcmVhbGVzLg0KIA0KYGBge3J9DQpiZF9saW1waWE8LWJkMw0Kd3JpdGUuY3N2KGJkX2xpbXBpYSwgZmlsZT0iZm9ybWJhc2VsaW1waWEuY3N2Iiwgcm93Lm5hbWVzID0gRkFMU0UpDQpgYGANCg0KDQojIyBTZWNjacOzbiAyOiBBbsOhbGlzaXMgRXhwbG9yYXRvcmlvIA0KYGBge3J9DQpiZF9saW1waWE8LXJlYWQuY3N2KCJDOlxcVXNlcnNcXGRhbnljXFxPbmVEcml2ZSAtIEluc3RpdHV0byBUZWNub2xvZ2ljbyB5IGRlIEVzdHVkaW9zIFN1cGVyaW9yZXMgZGUgTW9udGVycmV5XFxEZXNrdG9wXFxGb3JtXFxmb3JtYmFzZWxpbXBpYS5jc3YiKQ0KYGBgDQoNCg0KIyMjIFRhYmxhIG1lZGlhLCBtZWRpYW5hIHkgc3RkLiBkZXZpYXRpb24NCkVuIGVzdGEgcGFydGUgZGUgZGVzdmlhY2nDs24gZXN0YW5kYXIsIHBvZGVtb3Mgb2JzZXJ2YXIgcXVlIHNvbiBtdXkgcG9jb3MgbG9zIGNsaWVudGVzIHF1ZSB0aWVuZW4gcmV0cmFzb3MsIHBlcm8gY3VhbmRvIHNlIHRpZW5lbiBlc3RvcyByZXRyYXNvcyBzb24gZGUgYmFzdGFudGUgdGllbXBvIHBvciBsbyBjdWFsIHNlIHB1ZWRlbiB2ZXIgYWZlY3RhZG9zIGFsIG5vIGVzdGFyIGF2YW56YW5kbyBjb25mb3JtZSBhIGxhIGRlbWFuZGEuDQpgYGB7cn0NCmJkX2xpbXBpYSA8LSBiZDMNCnN1bW1hcnkoYmRfbGltcGlhKQ0Kc2QoYmRfbGltcGlhJFZ1ZWx0YXMsIG5hLnJtID0gRkFMU0UpDQpzZChiZF9saW1waWEkUC5hcnJpdmFsLCBuYS5ybSA9IEZBTFNFKQ0Kc2QoYmRfbGltcGlhJFIuYXJyaXZhbCwgbmEucm0gPSBGQUxTRSkNCnNkKGJkX2xpbXBpYSRSLmRlcCwgbmEucm0gPSBGQUxTRSkNCnNkKGJkX2xpbXBpYSREaWYsIG5hLnJtID0gRkFMU0UpDQoNClZhcmlhYmxlPC1jKCJWdWVsdGFzIiwiUC5hcnJpdmFsIiwgIlIuYXJyaXZhbCIsICJSLmRlcCIsICJEaWYiKQ0KTWVkaWFuYTwtYygiMS41MCAiLCI0LjAwMCIsIjAuMDAwICIsIjAuMDAwICIsIjAuMDAwMCAiKQ0KTWVkaWEgPC0gYygiMS43NSIsIjYuNjI1IiwiMy44MjMiLCI0LjE0MiIsIjQuMTQyIikNCk1vZGEgPC0gYygiMSIsIjAiLCIwIiwiMCIsIjAiKQ0KRGVzdmlhY2nDs25fZXN0YW5kYXI8LWMoIjAuODI5NDQ0MiIsIiA3LjUwMTU2MyIsIjYuNTA1OTAyIiwiNi45NDg2NjUiLCI2Ljk0ODY2NSIpDQp0YWJsZTEgPC0gZGF0YS5mcmFtZSAoVmFyaWFibGUsIE1lZGlhbmEsIE1lZGlhLCBNb2RhLCBEZXN2aWFjacOzbl9lc3RhbmRhcikNCmtuaXRyOjprYWJsZSh0YWJsZTEpDQpgYGANCg0KIyMjIEdyYXBocw0KIyMgVGFibGEgZGUgRnJlY3VlbmNpYSANCg0KYGBge3Igd2FybmluZz1GQUxTRX0NCiNpbnN0YWxsLnBhY2thZ2VzKCdlcGlEaXNwbGF5JykNCmxpYnJhcnkoZXBpRGlzcGxheSkNCnRhYjEoYmRfbGltcGlhJERpZmVyZW5jZSwgc29ydC5ncm91cCA9ICJkZWNyZWFzaW5nIiwgY3VtLnBlcmNlbnQgPSBUUlVFKSANCnRhYjEoYmRfbGltcGlhJFJlYWwuYXJyaXZhbCwgc29ydC5ncm91cCA9ICJkZWNyZWFzaW5nIiwgY3VtLnBlcmNlbnQgPSBUUlVFKQ0KYGBgDQoqTm90YXM6KiANClZpZW5kbyBlbCBncsOhZmljbyBkZSBkaXN0cmlidWNpw7NuIHNlIHB1ZWRlbiB2ZXIgbGFzIGZyZWN1ZW5jaWFzIGVuIGxhcyBkaWZlcmVuY2lhcywgc2UgdmUgdW5hIG1heW9yIHBhcnRlIGVuIGVsIG7Dum1lcm8gMCwgbG8gY3VhbCBub3MgaW5kaWNhIHVuIGJ1ZW4gZGVzYXJyb2xsbyBlbiBkZWxpdmVyeS4NCg0KIyMjIyBUaW1lIHNlcmllcyBwbG90cyAgDQoNCmBgYHtyfQ0KI0NoZWNhciBxdWUgbGEgYmFzZSBkZSBkYXRvcyBlc3RhIGVzdHJ1Y3R1cmFkYSB5IHVuIHJlc3VtZW4gZGUgbGEgZGVzY3JpcGNpw7NuIGVzdGFkaXN0aWNhDQpzdW1tYXJ5KGJkX2xpbXBpYSkNCg0KI0dyYWZpY2FyIA0KZ2dwbG90KGJkX2xpbXBpYSxhZXMoeD1GZWNoYSwgeT1EaWZlcmVuY2UsY29sb3I9Q2xpZW50ZSkpKw0KICBnZW9tX2xpbmUoKSsNCiAgbGFicyh4PSJGZWNoYSIseT0iRGVsYXkgaW4gTWludXRlcyIsIGNvbG9yPSJMZWdlbmQiKSsNCiAgZ2d0aXRsZSgiRGVsYXlzIGluIFBlcmZvcm1hbmNlIGJ5IENsaWVudCIpDQoNCmBgYA0KDQojIyMjIENoZWNhciBsYSBwcmVzZW5jaWEgZGUgbWlzc2luZyB2YWx1ZXMgIA0KYGBge3J9DQpiZF9saW1waWExIDwtIGJkX2xpbXBpYQ0KYmRfbGltcGlhMTwtYmRfbGltcGlhMVstYygzMDAsMjkyKSxdICMgUXVpdGFyIGxhcyBmaWxhcyAzMDAgeSAyOTIgcG9yIHF1ZSBwcmVzZW50YW4gZGF0b3MgbmVnYXRpdm9zIHkgcXVlIG5vIHNpcnZlbiBwYXJhIGVsIGFuYWxpc2lzLg0Kc3VtbWFyeShiZF9saW1waWExKSAjIG5vIG1pc3NpbmcgdmFsdWVzDQpgYGANCg0KDQojIyMjIFF1aXRhciBjbGllbnRlcyBxdWUgdGVuZ2FuIHZhbG9yIGRlIDAgZW4gbGEgYmFzZSBkZSBkYXRvcyAgDQpgYGB7cn0NCmJkX2xpbXBpYTE8LWJkX2xpbXBpYTFbYmRfbGltcGlhMSRDbGllbnRlIT0iTUFHTkEiLF0NCmJkX2xpbXBpYTE8LWJkX2xpbXBpYTFbYmRfbGltcGlhMSRDbGllbnRlIT0iVkFSUk9DIixdDQpzdW1tYXJ5KGJkX2xpbXBpYTEpDQpgYGANCg0KIyMjIyBSZWFsaXphciBsYSBncmFmaWNhIGNvbiBsb3MgMiBjbGllbnRlcyBxdWUgZWxpbWluYW1vcyAgDQpgYGB7cn0NCmdncGxvdChiZF9saW1waWExLGFlcyh4PUZlY2hhLCB5PURpZmVyZW5jZSxjb2xvcj1DbGllbnRlKSkrDQogIGdlb21fbGluZSgpKyAgZ2VvbV9obGluZSh5aW50ZXJjZXB0PTAuODAwMCxsaW5ldHlwZT0iZGFzaGVkIixjb2xvcj0iYmxhY2siKSsNCiAgbGFicyh4PSJGZWNoYSIseT0iRGlmZXJlbmNpYSBwb3IgZMOtYSIsIGNvbG9yPSJMZWdlbmQiKSsNCiAgZ2d0aXRsZSgiRGlmZXJlbmNpYSBkZSBlbnRyZWdhIHBvciBDbGllbnRlIikNCmBgYA0KDQojIyMgSGFsbGF6Z28geSBwcm9wdWVzdGENCkVuY29udHJhbW9zIGdyYWNpYXMgYSBsYSBncmFmaWNhIHJlYWxpemFkYSBkZSBsYSBEaWZlcmVuY2lhIGRlIHRpZW1wbyBlbiBsYSBlbnRyZWdhIGRlIHByb2R1Y3RvIHBvciBjbGllbnRlLCBxdWUgbG9zIGNsaWVudGVzIGNvbiBtYXlvciBEZWxheSBzb24gTUFITEUgWSBQUklOVEVMLCBhbCBtaXNtbyB0aWVtcG8gZW5jb250cmFtb3MgcXVlIGVudHJlIGVzdG9zIGRvcyBjbGllbnRlcywgZWwgcXVlIHRpZW5lIG1heW9yIERlbGF5IGVzIE1BSExFLCBwb3IgbG8gcXVlIHNlcsOtYSBidWVubyBwYXJhIGxhIGVtcHJlc2EgZWwgdGVuZXIgdW4gbWF5b3IgZW5mb3F1ZSwgb2J2aW8gZW4gYW1ib3MsIHBlcm8gdGFtYmllbiB1biBwb2NvIG3DoXMgZW4gTWFobGUsIHBhcmEgcXVlIHRlbmdhIG1lam9yIHJlZmVyZW5jaWEgZGUgZXN0ZSBjbGllbnRlIHkgbWF5b3IgY29uZmlhbnphIGNvbiBsYSBlbXByZXNhIGVuIGxhcyBlbnRyZWdhcy4gDQoNCg0KDQoNCg0KIyA8c3BhbiBzdHlsZSA9ICJjb2xvcjpkYXJrb3JhbmdlIj4gUHJvZHVjY2nDs24NCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCg0KbGlicmFyeShmb3JlaWduKQ0KbGlicmFyeShkcGx5cikgICAgICAgICMgZGF0YSBtYW5pcHVsYXRpb24gDQpsaWJyYXJ5KGZvcmNhdHMpICAgICAgIyB0byB3b3JrIHdpdGggY2F0ZWdvcmljYWwgdmFyaWFibGVzDQpsaWJyYXJ5KGdncGxvdDIpICAgICAgIyBkYXRhIHZpc3VhbGl6YXRpb24gDQpsaWJyYXJ5KGphbml0b3IpICAgICAgIyBkYXRhIGV4cGxvcmF0aW9uIGFuZCBjbGVhbmluZyANCiNpbnN0YWxsLnBhY2thZ2VzKCJIbWlzYyIpDQpsaWJyYXJ5KEhtaXNjKSAgICAgICAgIyBzZXZlcmFsIHVzZWZ1bCBmdW5jdGlvbnMgZm9yIGRhdGEgYW5hbHlzaXMgDQojaW5zdGFsbC5wYWNrYWdlcygicHN5Y2giKQ0KbGlicmFyeShwc3ljaCkgICAgICAgICMgZnVuY3Rpb25zIGZvciBtdWx0aXZhcmlhdGUgYW5hbHlzaXMgDQojaW5zdGFsbC5wYWNrYWdlcygibmFuaWFyIikNCmxpYnJhcnkobmFuaWFyKSAgICAgICAjIHN1bW1hcmllcyBhbmQgdmlzdWFsaXphdGlvbiBvZiBtaXNzaW5nIHZhbHVlcyBOQXMNCg0KI2luc3RhbGwucGFja2FnZXMoImRsb29rciIpDQpsaWJyYXJ5KGRsb29rcikgICMgc3VtbWFyaWVzIGFuZCB2aXN1YWxpemF0aW9uIG9mIG1pc3NpbmcgdmFsdWVzIE5Bcw0KI2luc3RhbGwucGFja2FnZXMoImNvcnJwbG90IikNCmxpYnJhcnkoY29ycnBsb3QpICAgICAjIGNvcnJlbGF0aW9uIHBsb3RzDQojaW5zdGFsbC5wYWNrYWdlcygianRvb2xzIikNCmxpYnJhcnkoanRvb2xzKSAgICAgICAjIHByZXNlbnRhdGlvbiBvZiByZWdyZXNzaW9uIGFuYWx5c2lzIA0KI2luc3RhbGwucGFja2FnZXMoImxtdGVzdCIpDQpsaWJyYXJ5KGxtdGVzdCkgICAgICAgIyBkaWFnbm9zdGljIGNoZWNrcyAtIGxpbmVhciByZWdyZXNzaW9uIGFuYWx5c2lzIA0KI2luc3RhbGwucGFja2FnZXMoImNhciIpDQpsaWJyYXJ5KGNhcikgICAgICAgICAgIyBkaWFnbm9zdGljIGNoZWNrcyAtIGxpbmVhciByZWdyZXNzaW9uIGFuYWx5c2lzDQojaW5zdGFsbC5wYWNrYWdlcygib2xzcnIiKQ0KbGlicmFyeShvbHNycikgICAgICAgICMgZGlhZ25vc3RpYyBjaGVja3MgLSBsaW5lYXIgcmVncmVzc2lvbiBhbmFseXNpcyANCiNpbnN0YWxsLnBhY2thZ2VzKCJrYWJsZUV4dHJhIikNCmxpYnJhcnkoa2FibGVFeHRyYSkgICAjIEhUTUwgdGFibGUgYXR0cmlidXRlcw0KbGlicmFyeSh0aWR5dmVyc2UpDQpgYGANCg0KIyMgU2VjY2nDs24gMS4gTGltcGllemEgZGUgZGF0b3MsIFRyYW5zZm9ybWFjacOzbiB5IEVudGVuZGltaWVudG8gKDEtNCkgDQoNCiMjIyBJbXBvcnRhciBCYXNlIGRlIERhdG9zIA0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCiNmaWxlLmNob29zZSgpDQpwcm9kdWNjaW9uPC1yZWFkLmNzdigiQzpcXFVzZXJzXFxkYW55Y1xcRG93bmxvYWRzXFxCYXNlIHByb2R1Y2Npb24gZm9ybSAtIEJhc2UgcHJvZHVjY2lvbiBmb3JtIC0gQmFzZSBwcm9kdWNjaW9uIGZvcm0gLSBCYXNlIHByb2R1Y2Npb24gZm9ybS5jc3YuY3N2LmNzdiIgKQ0KYGBgDQoNCiMjIyBWYXJpYWJsZXMgeSBSZWdpc3Ryb3MNCjxjZW50ZXI+IDxzcGFuIHN0eWxlPSJjb2xvcjpSZWQiPiBSPSAzOTg4IHJlZ2lzdHJvcyB5IDE1IHZhcmlhYmxlcyA8L2NlbnRlcj4NCg0KDQoNCiMjIyMgRW50ZW5kZXIgeSBsaW1waWFyIGxhIGJhc2UgZGUgZGF0b3MgDQpgYGB7cn0NCmRlc2NyaWJlKHByb2R1Y2Npb24pDQpgYGANCg0KDQojIyMjIFBhc28gMS4gRGUgY2FyYWN0ZXIgYSBmZWNoYSAoVGVjbmljYSA0LiBDb252ZXJ0aXIgdGlwb3MgZGUgZGF0b3MpIA0KYGBge3J9DQpiZHA8LXByb2R1Y2Npb24NCmJkcCRGZWNoYTwtIGFzLkRhdGUoYmRwJEZlY2hhLCBmb3JtYXQ9ICIlZC8lbS8lWSIpDQpzdW1tYXJ5KGJkcCkNCnRpYmJsZShiZHApDQpgYGANCg0KDQojIyMjIFBhc28gMi4gRWxpbWluYXIgY29sdW1uYXMgaW5zZXJ2aWJsZXMoVGVjbmljYSAxLiBSZW1vdmVyIHZhbG9yZXMgaXJyZWxldmFudGVzKSANCmBgYHtyfQ0KYmRwMTwtYmRwDQpiZHAxIDwtIHN1YnNldChiZHAxLCBzZWxlY3QgPS1jIChJRC5GT1JNKSkNCmJkcDEgPC0gc3Vic2V0KGJkcDEsIHNlbGVjdCA9LWMgKElOSUNJTy5TRVAuVVAsRklOLklOSUNJTy5ERS5TRVAuVVAsIFRJRU1QTy5NQVRFUklBTEVTKSkNCmJkcDEgPC0gc3Vic2V0KGJkcDEsIHNlbGVjdCA9LWMgKEhSLi5GSU4sIElOSUNJTy5kZS5QUk9DRVNPLCBGSU4uZGUuUFJPQ0VTTykpDQpgYGANCg0KIyMjIyBDYW1iaWFyIG5vbWJyZXMgDQpgYGB7cn0NCmNvbG5hbWVzKGJkcDEpPC1jKCdmZWNoYScsJ2NsaWVudGUnLCdwcm9kdWN0bycsJ3BpZXphc19wcm9nJywndGllbXBvX21pbicsJ2VzdGFfYXJyYW5xdWUnLCdsYW1pbmFzX3Byb2Nlc2FkYXMnLCd0aWVtcG9fY2FsaWRhZCcpDQpgYGANCg0KIyMjIyBQYXNvIDMuIENhbWJpYXIgZGUgY2FyYWN0ZXIgYSBOdW1lcmljbyAoVGVjbmljYSA0LiBDb252ZXJ0aXIgdGlwb3MgZGUgZGF0b3MpICANCg0KYGBge3J9DQpiZHAxJHBpZXphc19wcm9nPC1hcy5udW1lcmljKGJkcDEkcGllemFzX3Byb2cpICAgICAgICAgICAgICAgDQpiZHAxJHRpZW1wb19taW48LWFzLm51bWVyaWMoYmRwMSR0aWVtcG9fbWluKSAgICAgICAgICAgICAgICAgDQpiZHAxJGxhbWluYXNfcHJvY2VzYWRhczwtYXMubnVtZXJpYyhiZHAxJGxhbWluYXNfcHJvY2VzYWRhcykgDQpiZHAxJHRpZW1wb19jYWxpZGFkPC1hcy5udW1lcmljKGJkcDEkdGllbXBvX2NhbGlkYWQpICAgICAgICAgDQoNCmJkcDI8LWJkcDENCmJkcDIkdGllbXBvX21pbiA8LSBzdWJzdHIoYmRwMiR0aWVtcG9fbWluLCBzdGFydCA9IDEsIHN0b3AgPSAyKQ0KdGliYmxlKGJkcDIpICANCmJkcDIkdGllbXBvX21pbiA8LSBhcy5pbnRlZ2VyKGJkcDIkdGllbXBvX21pbikNCnN0cihiZHAyKSAgDQoNCmJkcDIkcGllemFzX3Byb2cgPC0gc3Vic3RyKGJkcDIkcGllemFzX3Byb2csIHN0YXJ0ID0gMSwgc3RvcCA9IDIpDQp0aWJibGUoYmRwMikgIA0KYmRwMiRwaWV6YXNfcHJvZyA8LSBhcy5pbnRlZ2VyKGJkcDIkcGllemFzX3Byb2cpDQpzdHIoYmRwMikNCg0KYmRwMiRsYW1pbmFzX3Byb2Nlc2FkYXMgPC0gc3Vic3RyKGJkcDIkbGFtaW5hc19wcm9jZXNhZGFzLCBzdGFydCA9IDEsIHN0b3AgPSAyKQ0KdGliYmxlKGJkcDIpICANCmJkcDIkbGFtaW5hc19wcm9jZXNhZGFzIDwtIGFzLmludGVnZXIoYmRwMiRsYW1pbmFzX3Byb2Nlc2FkYXMpDQpzdHIoYmRwMikgDQpgYGANCg0KDQojIyMjIFBhc28gNC4gQ2FtYmlhciBkZSBOL0EgYSBwcm9tZWRpb3MgDQpgYGB7cn0NCmJkcDMgPC0gYmRwMg0KYmRwMyR0aWVtcG9fbWluW2lzLm5hKGJkcDMkdGllbXBvX21pbildPC1tZWFuKGJkcDMkdGllbXBvX21pbiwgbmEucm0gPSBUUlVFKQ0Kc3VtbWFyeSAoYmRwMykgDQpgYGANCg0KDQojIyMjIFBhc28gNS4gQ2FtYmlhciBkZSBOL0EgYSAwIA0KYGBge3J9DQpiZHA0IDwtIGJkcDMNCmJkcDQkbGFtaW5hc19wcm9jZXNhZGFzW2JkcDQkbGFtaW5hc19wcm9jZXNhZGFzIDwgMV08LSBOQQ0Kc3VtbWFyeSAoYmRwNCkNCmBgYA0KDQoNCiMjIyMgUGFzbyA2LiBCb3JyYSBOL0FzIA0KYGBge3J9DQpiZHA1IDwtIGJkcDQNCmJkcDUgPC0gbmEub21pdChiZHA1KSAgICANCnN0cihiZHA1KQ0KYGBgDQoNCg0KIyMjIyBWZXJpZmljYXIgZWxpbWluYWNpb24gZGUgTkHCtHMgDQpgYGB7cn0NCmNvbFN1bXMoaXMubmEoYmRwNSkpDQpzdW1tYXJ5KGJkcDUpDQoNCnN0cihiZHA1KQ0Kc3VtbWFyeShiZHA1KQ0KYGBgDQoNCg0KIyMjIENsYXNpZmljYWNpw7NuIGRlIFZhcmlhYmxlcyANCg0KYGBge3J9DQpWYXJpYWJsZTwtYygiRmVjaGEgIiwiY2xpZW50ZSIsInByb2R1Y3RvIiwgIlBpZXphcyBwcm9ncmFtYWRhcyIsInRpZW1wbyBtaW4iLCJFc3RhY2lvbiBkZSBhcnJhbnF1ZSIsIkxhbWluYXMgcHJvY2VzYWRhcyIsICJUaWVtcG8gZGUgY2FsaWRhZCIpDQpUeXBlPC1jKCJDdWFsaXRhdGl2YSIsIkN1YWxpdGF0aXZhIiwiQ3VhbGl0YXRpdmEiLCAiQ3VhbnRpdGF0aXZhKERpc2NyZXRhKSIsICJDdWFudGl0YXRpdmEoRGlzY3JldGEpIiwiQ3VhbGl0YXRpdmEiLCAiQ3VhbnRpdGF0aXZhKERpc2NyZXRhKSIsICJDdWFudGl0YXRpdmEgZGlzY3JldGEiKQ0KTWVkaWNpb24gPC1jKCJOb21pbmFsIiwgIk5vbWluYWwiLCJOb21pbmFsIiwgIkludGVydmFsbyIsICJJbnRlcnZhbG8iLCJOb21pbmFsIiwgIkludGVydmFsbyIsICJJbnRlcnZhbG8iKSANCnRhYmxlPC1kYXRhLmZyYW1lKFZhcmlhYmxlLFR5cGUsIE1lZGljaW9uKQ0Ka25pdHI6OmthYmxlKHRhYmxlKQ0KYGBgDQoNCiMjIyMgRXhwb3J0YXIgY3N2IA0KYGBge3J9DQp3cml0ZS5jc3YoYmRwNSwiQzpcXFVzZXJzXFxkYW55Y1xcT25lRHJpdmUgLSBJbnN0aXR1dG8gVGVjbm9sb2dpY28geSBkZSBFc3R1ZGlvcyBTdXBlcmlvcmVzIGRlIE1vbnRlcnJleVxcRGVza3RvcFxcRm9ybV9wcm9kdWNjaW9uYmFzZWxpbXBpYS5jc3YiLCByb3cubmFtZXM9RkFMU0UpDQpgYGANCg0KIyMjIyBJbXBvcnRhciBiYXNlIGRlIGRhdG9zIGxpbXBpYSANCg0KYGBge3J9DQpiZGw8LXJlYWQuY3N2KCJDOlxcVXNlcnNcXGRhbnljXFxPbmVEcml2ZSAtIEluc3RpdHV0byBUZWNub2xvZ2ljbyB5IGRlIEVzdHVkaW9zIFN1cGVyaW9yZXMgZGUgTW9udGVycmV5XFxEZXNrdG9wXFxGb3JtX3Byb2R1Y2Npb25iYXNlbGltcGlhLmNzdiIpDQpsaWJyYXJ5KGdncGxvdDIpDQojaW5zdGFsbC5wYWNrYWdlcygid2ViciIpDQpsaWJyYXJ5KHdlYnIpDQpsaWJyYXJ5KGRwbHlyKQ0KYGBgDQoNCg0KIyMgMS4gQW7DoWxpc2lzIEVzdGFkw61zdGljbyBQUk9EVUNDScOTTiAoNSkgDQoNCiMjIyBHcsOhZmljb3MgDQojIyMjIEN1YWxpdGF0aXZvDQpEZW50cm8gZGUgZXN0ZSBncsOhZmljbyBzZSB2aW8gcXVlIGVsIGNsaWVudGUgcXVlIHR1dm8gbcOhcyBwaWV6YXMgcHJvZ3JhbWFkYXMgZnVlIFN0YWJpbHVzIGVuIGVsIG1lcyBkZSBBZ29zdG8sIGVzdG8gZGViaWRvIGEgcXVlIGxhIG1heW9yIHBhcnRlIGRlIGxhcyB2ZW50YXMgZnVlIGxsZXZhZG8gYSBjYWJvIGR1cmFudGUgZXN0ZSBtZXMgc2VndW4gcG9kZW1vcyB2ZXIgbGEgdGFibGEgZGVzY3JpcHRpdmEuDQpgYGB7cn0NCmRldGFjaChwYWNrYWdlOnBseXIpDQpQRCA9IGJkcDUgJT4lIGRwbHlyOjpncm91cF9ieShtb250aD1sdWJyaWRhdGU6OiBmbG9vcl9kYXRlKGZlY2hhLCAibW9udGgiICksIGNsaWVudGUpICU+JSBzdW1tYXJpc2UobiA9IHN1bShwaWV6YXNfcHJvZykpDQpwcmludChQRCkNCg0KUGllRG9udXQoUEQsIGFlcyhtb250aCwgY2xpZW50ZSwgY291bnQ9biksIHRpdGxlID0gIlBpZXphcyBwb3IgY2xpZW50ZSIpDQpgYGANCg0KIyMjIyBDdWFudGl0YXRpdm8gDQpFbiBlc3RlIGhpc3RvZ3JhbWEsIHBvZGVtb3MgdmVyIHF1ZSBsYSBpbmZvcm1hY2nDs24gZGUgbGFzIGxhbWluYXMgcHJvY2VzYWRhcyBzZSBlbmN1ZW50cmEgZW4gdW4gMTAtMjAgcG9yIGxvIHF1ZSBzZSBub3RhIGVuIGVsIGdyw6FmaWNvIGNvbW8gbWF5b3IgcGFydGUsIGFxdcOtIG5vcyBwb2RlbW9zIGRhciBjdWVudGEgcXVlIGVzdGUgbnVtZXJvIGRlIGzDoW1pbmFzIGVzIGVsIHF1ZSBjb24gbcOhcyBmcmVjdWVuY2lhIHNlIHByb2R1Y2UuDQpgYGB7cn0NCnByb2R1Y2Npb24xIDwtIChiZHA1JGxhbWluYXNfcHJvY2VzYWRhcykNCmhpc3QocHJvZHVjY2lvbjEpDQpgYGANCg0KDQojIyMgUHJvcHVlc3RhcyANCjEuIFZlciB1biBtb2RlbG8gcHJlZGljdGl2byBwYXJhIGF1bWVudGFyIGVsIG51bWVybyBkZSB2ZW50YXMgbG8gY3VhbCBub3MgZGFyw61hIHVuIGluY3JlbWVudG8gZW4gbGEgcHJvZHVjY2nDs24uIA0KMi5Gb21lbnRhciBsYSBsZWFsdGFkIGVuIGxvcyBjb21wcmFkb3JlcyBkYW5kb2xlcyB2ZW50YWphcyBjb21wZXRpdGl2YXMgYW50ZSBlbCBtZXJjYWRvIHBhcmEgZXZpdGFyIGRlamFyIGRlIHByb2R1Y2lyIGxvcyBudW1lcm9zIGNvbiBtw6FzIGZyZWN1ZW5jaWEgbG8gY3VhbCBwcm92b2NhcsOtYSB1biBkZXNiYWxhbmNlIGVuIG51ZXN0cm9zIG51bWVyb3MuIA0KDQojIyBTZWNjacOzbiAyLiBBbsOhbGlzaXMgRXhwbG9yYXRvcmlvIA0KDQojIyMgVGFibGEgZGUgbWVkaWEsIG1lZGlhbmEgeSBTdGQuIERldmlhdGlvbg0KQ3JlbyBxdWUgcGFyYSBlc3RlIGNhc28gZGVudHJvIGRlIGxhIHByb2R1Y2NpJ29uIHNlIHZlIHF1ZSB0aWVuZSB1bmEgZGVzdmlhY2lvbiBkZW50cm8gZGVsIHJhbmdvIHlhIHF1ZSBzZSBtdWVzdHJhIHVuYSBkaXNwZXJjacOzbiBkZSAxOC43IGVudHJlIHB1bnRvIHkgcHVudG8gcXVlIGVzIG1lbm9zIHF1ZSBsYSBtZWRpYS4NCg0KYGBge3J9DQpiZDY8LWJkbA0KbWVkaWFuKGJkNiRwaWV6YXNfcHJvZywgbmEucm0gPSBUUlVFKQ0KbWVhbihiZDYkcGllemFzX3Byb2csIG5hLnJtID0gVFJVRSkNCnNkKGJkNiRwaWV6YXNfcHJvZywgbmEucm0gPSBGQUxTRSkNCg0KVmFyaWFibGU8LWMoIlBpZXphcyIpDQpNZWRpYW5hPC1jKCIyMCIpDQpNZWRpYSA8LSBjKCIyNi41IikNCkRlc3ZpYWNpw7NuX2VzdGFuZGFyPC1jKCIxOC43IikNCnRhYmxlYmFqYSA8LSB0aWJibGUgKFZhcmlhYmxlLCBNZWRpYW5hICwgTWVkaWEgLCBEZXN2aWFjacOzbl9lc3RhbmRhcikNCmtuaXRyOjprYWJsZSh0YWJsZWJhamEpDQpgYGANCg0KIyMjIEdyYXBocyANCg0KIyMjIyBCYXJwbG90cyANCg0KUmVjb3BpbGFuZG8gbGEgaW5mb3JtYWNpb24gbWUgdG9wZSBjb24gZXN0b3MgZGF0b3MgbG8gY3VhbCBub3MgaW5mb3JtYSBhY2VyY2EgZGUgbG9zIGNsaWVudGVzIG1hcyBkZXN0YWNhZG9zIHBhcmEgZm9ybSB5IGVsIHRpZW1wbyBtaW5pbW8gZGUgdGFyZGFuemEgZW4gZWwgZW5zYW1ibGFqZSBkZSBsb3MgcHJvZHVjdG9zLCBlbiBlc3RlIGNhc28gZWwgcHJpbWVyIGx1Z2FyIGNvbiBtYXMgZWZpY2llbmNpYSBwb3IgY2xpZW50ZSBmdWUgc3RhYmlsdXMgZW4gbGEgcHJpbWVyYSB2dWVsdGEuDQoNCmBgYHtyfQ0KDQpiZDY8LWJkNiAlPiUgZ3JvdXBfYnkoY2xpZW50ZSkgJT4lIA0KICBzdW1tYXJpc2UocGllemFzX3Byb2c9c3VtKHBpZXphc19wcm9nKSx0aWVtcG9fbWluPXN1bSh0aWVtcG9fbWluKSkgJT4lIGFycmFuZ2UoZGVzYyhwaWV6YXNfcHJvZykpDQoNCmJkNjwtYmQ2Wy1jKDYsNyw4LDksMTAsMTEpLF0gDQoNCg0KZ2dwbG90KGJkNixhZXMoeD1yZW9yZGVyKHRpZW1wb19taW4scGllemFzX3Byb2cpLCB5PXBpZXphc19wcm9nLGZpbGw9Y2xpZW50ZSkpICsNCiAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiKQ0KYGBgDQoNCg0KIyMjIyBCYXJwbG90czIgDQpEZW50cm8gZGUgZXN0YSBzZWd1bmRhIHRhYmxhIGRlIGJhcnJhcyBzZSBwdWVkZSB2ZXIgZGVzcGxlZ2FkbyBsYSBjYW50aWRhZCBkZSBwaWV6YXMgcHJvZ3JhbWFkYXMgcXVlIHNlIHR1dm8gcG9yIG1lcyBlbiBsb3MgcGVyaW9kb3MgZGUgbG9zIG1lc2VzIGp1bGlvLCBhZ29zdG8geSBzZXB0aWVtYnJlLiBFc3RvIG5vcyBkaWNlIGFjZXJjYSBkZSBsYSBtYXlvciBwcm9kdWN0aXZpZGFkIGRlIGFnb3N0bywgcGVybyBwb3JxdWUgZXMgZXN0bz8NCmBgYHtyfQ0KZGF0b3Njb3BpYTwtYmRsDQpkYXRvc2NvcGlhJGFubzwtc3RyZnRpbWUoZGF0b3Njb3BpYSRmZWNoYSwgIiVZIikNCmRhdG9zY29waWEkbWVzPC1zdHJmdGltZShkYXRvc2NvcGlhJGZlY2hhLCAiJW0iKQ0KDQpkYXRhX2FnZzwtIGFnZ3JlZ2F0ZShwaWV6YXNfcHJvZ35tZXMgKyBhbm8sIGRhdG9zY29waWEsIEZVTiA9IHN1bSkNCmRhdGFfYWdnbGFtaW5hPC0gYWdncmVnYXRlKGxhbWluYXNfcHJvY2VzYWRhc35tZXMgKyBhbm8sIGRhdG9zY29waWEsIEZVTiA9IHN1bSkNCmdncGxvdChkYXRhX2FnZyxhZXMoeD1tZXMseT1waWV6YXNfcHJvZykpICsNCiAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiKQ0KYGBgDQoNCiMjIyMgQmFycGxvdHMgMyANCkVuIGVzdGEgZ3JhZmljYSBzZSBwdWVkZSB2aXN1YWxpemFyIGxhIGRlcGVuZGVuY2lhIGRlbCB0aWVtcG8gbWluaW1vIGRlIHByb2R1Y2Npb24gY29uIGxhcyBwaWV6YXMgcHJvZ3JhbWFkYXMgZGVwZW5kaWVuZG8gZGUgbGEgZXN0YWNpb24gZGUgYXJyYW5xdWUsIGxhIG1heW9yIHByb2R1Y3RpdmlkYWQgZ2VuZXJhbCB0aWVuZSB1bmFyZWxhY2lvbiBjb24gbGEgZXN0YWNpb24gQzEgeSBsYSBDMXkyIHlhIHF1ZSBzZSB2ZSBxdWUgZXMgbGEgcXVlIG1lbm9zIHRpZW1wbyBoYWNlIGNvbiBtYXMgcHJvY2VzYW1pZW50byBkZSBsYW1pbmFzLg0KYGBge3J9DQpnZ3Bsb3QoZGF0b3Njb3BpYSxhZXMoeD10aWVtcG9fbWluLCB5PXBpZXphc19wcm9nLGZpbGw9ZXN0YV9hcnJhbnF1ZSkpICsNCiAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiKQ0KYGBgDQoNCg0KIyMjIyBEaXNwZXJzaW9uIDEgIA0KRW4gZXN0YSB0YWJsYSBzZSBtdWVzdHJhIHVuIGNsYXJvIGVqZW1wbG8gZGUgY29tcGFyYWNpb24gcXVlIGVudHJlIG1hcyB0aWVtcG8gZGUgY2FsaWRhZCBzZSBsZSBkZSBhbCBjbGllbnRlIHNlIGxvZ3JhcmEgaGFjZXIgdW4gdGllbXBvIG11Y2hvIG1hcyBtaW5pbW8gZWZlY3Rpdml6YW5kbyBsb3MgcHJvY2Vzb3MgeSB0ZXJtaW5hbmRvbG9zIG1hcyByYXBpZG8gY29tbyBmdWUgY29uIGxvcyBjbGllbnRlcyBlbiBhenVsLg0KYGBge3J9DQpnZ3Bsb3QoZGF0b3Njb3BpYSwgYWVzKHg9dGllbXBvX2NhbGlkYWQsIHk9dGllbXBvX21pbiwgY29sb3I9Y2xpZW50ZSkpICsNCiAgZ2VvbV9wb2ludCgpICsgZ2VvbV9ydWcoKQ0KYGBgDQoNCg0KIyMjIyBEaXNwZXJzaW9uIDIgDQpFbiBlc3RhIGdyYWZpY2EsIHNlIGllbmUgbGEgaW50ZW5jaW9uIGRlIHZlciBhIGxvcyBjb21wcmFkb3JlcyBwcmVkb21pbmFudGVzIGRlbnRybyBkZSBGT1JNIGR1cmFudGUgbG9zIHRyZXMgbWVzZXMgcHJlZGljdGl2b3MsIGVzdG8gcGFyYSBwb2RlciBsb2dyYXIgdW5hIGF0ZW5jaW9uIGVzcGVjaWFsaXphZGEgeSB2ZXIgbWFzIG8gbWVub3MgZWwgdGllbXBvIHF1ZSB0b21hbiBzdXMgcHJvZHVjdG9zIHkgZ2VuZXJhciB1biB0aXBvIGRlIHByb2Nlc29zIG1hcyBmbHVpZG8uDQpgYGB7cn0NCmdncGxvdChkYXRvc2NvcGlhLCBhZXMoeD1jbGllbnRlLCB5PWxhbWluYXNfcHJvY2VzYWRhcywgY29sb3I9bWVzKSkgKw0KICBnZW9tX3BvaW50KCkgKyBnZW9tX3J1ZygpDQpgYGANCg0KDQojIyMjIFNlcmllcyBkZSB0aWVtcG8gDQpBcXVpIHNlIHB1ZWRlIHZlciB1bmEgc2VyaWUgZGUgdGllbXBvIG5vIGxpbmVhbCwgbG8gY3VhbCBub3MgZGljZSBxdWUgbm8gc2UgdGllbmVuIHByb2Nlc29zIGNsYXJvcyB5IGVzdGFibGVzIHBhcmEgbGEgcHJvZHVjY2lvbiBsbyBjdWFsIGxvIGNvbnZpZXJ0ZSBlbiB1biBwcm9jZXNvIHZhcmlhYmxlIHkgY29uIGZhbGxhcyBlbiBsb3MgdGllbXBvcyBkZSBlbnRyZWdhcyBjb21vIHJlc3VsdGFkby4NCmBgYHtyfQ0KDQpnZ3Bsb3QoZGF0b3Njb3BpYSxhZXMoeD10aWVtcG9fY2FsaWRhZCkpKw0KICBnZW9tX2xpbmUoYWVzKHk9cGllemFzX3Byb2cpLGNvbG9yPSJvcmFuZ2UiKSsNCiAgbGFicyh4PSJUaWVtcG8gZGUgQ2FsaWRhZCIseT0icGllemFzIHByb2dyYW1hZGFzIiwgY29sb3I9Im9yYW5nZSIpKw0KICBnZ3RpdGxlKCJHcmFmaWNhIGRlIHRhc2EgZGUgcmVuZGltaWVudG8iKQ0KYGBgDQoNCiMjIyBIYWxsYXpnb3MgDQoNCjEuIERlcGVuZGUgZGVsIHBvc2ljaW9uYW1pZW50byBpbmljaWFsIGRlIGxhIG1hdGVyaWEgcHJpbWEgZWwgdGllbXBvIGVuIGVsIHF1ZSBzZSBwcm9kdWNlbiBsYXMgbGFtaW5hcy4gDQoyLiBIYXkgY2xpZW50ZXMgcXVlIGNvbXByYW4gbcOhcyBxdWUgb3Ryb3MgeSBlcyBwb3IgZXNvIHF1ZSBsYSBwcm9kdWNjacOzbiBwb3IgZmFsdGEgZGUgdHJhbnNwb3J0ZSB0aWVuZSBxdWUgZGFyIGRvcyB2dWVsdGFzIGhhY2llbmRvIG1heW9yIGVsIHRpZW1wbyBkZSBlbnRyZWdhLiANCjMuIEhheSByZXRyYXNvcyBubyBjbGFyb3MgcGFyYSBhbGfDum5vcyBjbGllbnRlcyBwb3IgbG8gY3VhbCBkZWJlbW9zIHByZWd1bnRhciBhIEZlbGlwZSBhY2VyY2EgZGUgZXN0YXMuIA0KDQoNCiMgPHNwYW4gc3R5bGUgPSAiY29sb3I6ZGFya29yYW5nZSI+IE1lcm1hDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQojZmlsZS5jaG9vc2UoKQ0KRk9STSA8LSByZWFkLmNzdigiQzpcXFVzZXJzXFxkYW55Y1xcRG93bmxvYWRzXFxGT1JNIC0gTWVybWEgbGltcGlhLmNzdiIpDQpgYGANCg0KDQojIyBTZWNjacOzbiAxLiBMaW1waWV6YSBkZSBkYXRvcywgVHJhbnNmb3JtYWNpw7NuIHkgRW50ZW5kaW1pZW50byAoMS00KSANCg0KIyMjIEVudGVuZGVyIEJhc2UgZGUgRGF0b3MgIA0KYGBge3J9DQpyZXN1bWVuIDwtIHN1bW1hcnkoRk9STSkNCnJlc3VtZW4NCmBgYA0KDQojIyMgVmFyaWFibGVzIHkgcmVnaXN0cm9zIGRlIGxhIGJhc2UgZGUgZGF0b3MgIA0KPGNlbnRlcj4gPHNwYW4gc3R5bGU9ImNvbG9yOlJlZCI+IFI9IDUyIHJlZ2lzdHJvcyB5IDIgdmFyaWFibGVzIDwvY2VudGVyPg0KYGBge3Igd2FybmluZz1GQUxTRX0NCnN0cihGT1JNKQ0KbGlicmFyeShwc3ljaCkNCmxpYnJhcnkocGx5cikNCiNpbnN0YWxsLnBhY2thZ2VzKCJwc3ljaCIpDQpkZXNjcmliZShGT1JNKQ0KYGBgDQoNCjxzdHlsZT4NCmRpdi5ibHVlIHsgYmFja2dyb3VuZC1jb2xvcjojRkZEQkM4OyBib3JkZXItcmFkaXVzOiA1cHg7IHBhZGRpbmc6IDIwcHg7fQ0KPC9zdHlsZT4NCjxkaXYgY2xhc3MgPSAiYmx1ZSI+DQoNCioqTm90YToqKkVuIGVzdGEgYmFzZSBkZSBkYXRvcyBzZSBlbGltaW5hcm9uIGxhIGNvbHVtYSBxdWUgbm8gZXJhIHJlbGV2YW50ZSBwYXJhIGVsIGFuYWxpc2lzLCBTZSBlbGltaW5hcm9uIGxvcyByZWdpc3Ryb3MgZGUgdG90YWwgZGUgbWVybWEgeSBsYSBjb2x1bW5hIGRlIG1lcyB5YSBxdWUgbm8gZXJhbiBpcnJlbGV2YW50ZXMuIFBvciBsbyB0YW50byBub3MgcXVlZGFtb3MgY29uIDUyIHJlZ2lzdHJvcyB5IDIgdmFyaWFibGVzLiAgDQoNCioyLipQYXJhIGVsIGNhc28gZGUgdmFyaWFibGVzIGN1YW50aXRhdGl2YXMgY29uc2lkZXJhciBsYSBwb3NpYmlsaWRhZCBkZSByZWVtcGxhemFyIGxhIHByZXNlbmNpYSBkZSDigJxtaXNzaW5nIHZhbHVlc+KAnSBjb24gZXN0YWTDrXN0aWNvcyBkZXNjcmlwdGl2b3MgKHBvciBlamVtcGxvLCBtZWRpYSwgbWVkaWFuYSwgbW9kYSkuIA0KDQo8L2Rpdj4gDQoNCiMjIyBFbGltaW5hciBOL0HCtHMNClJlbXBsYXphciB2YWxvcmVzIGZhbHRhbnRlcyBwb3IgbGEgbWVkaWFuYTogTm8gc2UgcHVlZGVuIGNhbWJpYXIgZGViaWRvIGEgcXVlIGxvcyBOQcK0UyBkZSBsYSBiYXNlIGRlIGRhdG9zIG5vIHRpZW5lbiBpbmZvcm1hY2nDs24gcG9yIGxvIHRhbnRvIHNlIHZhbiBhIGVsaW1pbmFyLg0KYGBge3J9DQogDQpGT1JNXzE8LUZPUk0NCkZPUk1fMTwtIG5hLm9taXQoRk9STV8xKQ0Kc3VtbWFyeShGT1JNXzEpDQoNCiNzdW1tYXJ5KEZPUk0pIA0KI3N0cihGT1JNKQ0KI0ZPUk0kS2lsb3M8LWFzLm51bWVyaWMoRk9STSRLaWxvcykNCiNGT1JNPC1GT1JNICU+JSBtdXRhdGUoS2lsb3M9aWZfZWxzZShpcy5uYShLaWxvcyksbWVkaWFuKEtpbG9zLG5hLnJtID0gVCksS2lsb3MpKQ0KYGBgDQoNCioqTm90YToqKkVuIGVzdGEgYmFzZSBkZSBkYXRvcyBsYSB1bmljYSB2YXJpYWJsZSBxdWUgc2UgcHVlZGUgcmVtcGxhemFyIHBvciBsYSBtZWRpYW5hIGVzIGxhIGNvbHVtbmEgZGUga2lsb3MuIFlhIHNlIHJlbXBsYXphcm9uIGxvcyB2YWxvcmVzIGZhbHRhbnRlcyBwb3IgbGEgbWVkaWFuYS4gDQoNCiMjIyBDYW1iaWFyIG5vbWJyZXMgZGUgY29sdW1uYXMgeSB2YXJpYWJsZXMgIA0KUmVzcGVjdG8gYSB2YXJpYWJsZXMgY3VhbGl0YXRpdmFzIChwb3IgZWplbXBsbywgZ8OpbmVybywgY2xpZW50ZSxtdW5pY2lwaW8sIGVzdGFkbykgaG9tb2dlbml6YXIgZWwgbm9tYnJlIGRlIGxhcyBkaWZlcmVudGVzIGNhdGVnb3LDrWFzLiANCg0KUmVzcGVjdG8gYSBMYSBiYXNlIGRlIGRhdG9zIGFuYWxpemFkYSBubyBhcGxpY2EgZWwgcGFzbyBkZSBob21vZ2VuaXphciBsYXMgdmFyaWFibGVzIHlhIHF1ZSBlbiBlc3RlIGNhc28gc29sbyBzZSBjdWVudGEgY29uIGRvcyB2YXJpYWJsZXMgZW4gbGEgYmFzZSBkZSBkYXRvcy4gDQoNCmBgYHtyfQ0KI3NlbGVjY2lvbmFyIGNvbHVtbmFzIC8gdmFyaWFibGVzLg0KI0ZPUk08LUZPUk0gJT4lIHNlbGVjdCgtb25lX29mKCdGZWNoYScsJ0tpbG9zJykpDQoNCiNSZW5vbWJyYXIgbGFzIGNvbHVtbmFzIC92YXJpYWJsZXMgc2VsZWNjaW9uYWRhcy4gDQpjb2xuYW1lcyhGT1JNXzEpIDwtYyAoJ0ZlY2hhJywnS2lsbycpDQpgYGANCg0KYGBge3J9DQpWYXJpYWJsZTwtYygiYEZlY2hhYCIsICJgIEtpbG9zYCIpDQpUeXBlPC1jKCJDdWFudGl0YXRpdmEgKGNvbnRpbnVhKSIsICJDdWFudGl0YXRpdmEgKGRpc2NyZXRhKSIpDQpNZWFzdXJlbWVudDwtYygiUmF6w7NuIiwiUmF6w7NuIikNCnRhYmxlX01lcm1hPC1kYXRhLmZyYW1lKFZhcmlhYmxlLFR5cGUsTWVhc3VyZW1lbnQpDQoNCmtuaXRyOjprYWJsZSh0YWJsZV9NZXJtYSkNCmBgYA0KDQojIyAxLiBBbsOhbGlzaXMgRXN0YWTDrXN0aWNvIE1lcm1hICg1KQ0KIyMjIEdyw6FmaWNvIGN1YW50aXRhdGl2bw0KU2UgcHVlZGUgbm90YXIgZW4gZXN0ZSBncsOhZmljbyBkZSBiYXJyYXMgY29tbyBkZW50cm8gZGUgbG9zIHRyZXMgdHJpbWVzdHJlcyBlbCBzZWd1bmRvIHkgdGVyY2VybyBmdWVyb24gbG9zIG3DoXMgZXN0YWJsZXMgcG9yIGFzw60gZGVjaXJsbywgbm8gaHVibyBjYW50aWRhZGVzIG3DoXhpbWFzIHByZW9jdXBhbnRlcyBvIGV4Y2VsZW50ZXMgbWluaW1hcy4NCmBgYHtyfQ0KRk9STV8xJEZlY2hhPC1hcy5EYXRlKEZPUk0kRmVjaGEsZm9ybWF0PSIlZC8lbS8leSIpDQojaW5zdGFsbC5wYWNrYWdlcygiZ2dwbG90IikNCmxpYnJhcnkoZ2dwbG90MikNCmdncGxvdChGT1JNXzEsIGFlcyh4PUZlY2hhLCB5PUtpbG8pKSArDQogIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IiwgY29sb3I9ImJsdWUiLCBmaWxsPSJ3aGl0ZSIpDQpgYGANCg0KIyMjIFByb3B1ZXN0YXMNClNlIHJlY29taWVuZGEgZWwgZGlidWphciBwcm9iYWJsZW1lbnRlIGNvbiBlbCBwcm92ZWVkb3IgZGUgbWF0ZXJpYSBwcmltYSB1bmEgZmlndXJhIHBhcmEgb3B0aW1pemFyIGxhcyBtYXRlcmlhcyBvIGJpZW4sIHV0aWxpemFyIG1hcXVpbmFzIHByZWNpc2FzIGRlIGxhc2VyIHBhcmEgZXZpdGFyIGNvcnRlcyBxdWUgZGVzcGVyZGljaWVuIGxvcyBtYXRlcmlhbGVzLg0KDQojIyBTZWNjacOzbiAyLiBBbsOhbGlzaXMgRXhwbG9yYXRvcmlvIA0KIyMjIFRhYmxhIGRlIE1lZGlhLCBNZWRpYW5hLCBNb2RhIHkgRGVzdmlhY2nDs24gRXN0YW5kYXJkDQpEZW50cm8gZGUgbGEgdGFibGEgZGUgYW7DoWxpc2lzIGRlIHZhcmlhYmxlIHNlIHB1ZWRlIHZlciBxdWUgZWwgbnVtZXJvIHByb21lZGlvIGVzIGRlIDQsNDE1IGRlIG1lcm1hLCBlc3RlIGVzIHVuIG51bWVybyBhbHRvIGRlbnRybyBkZWwgcmFuZ28geWEgcXVlIGhhYmxhbmRvIGRlIGtpbG9ncmFtb3MgZWwgdGVuZXIgdW5hIG1lZGlhIGRlIDQgdG9uZWxhZGFzIHB1ZWRlIHNpZ25pZmljYXIgdW4gYWx0byBkZXNwZXJkaWNpbyBkZSBjYXJ0b24geSBwb3IgZW5kZSBkZSBkaW5lcm8uDQpgYGB7cn0NCm1lZGlhbihGT1JNXzEkS2lsbywgbmEucm0gPSBUUlVFKQ0KbWVhbihGT1JNXzEkS2lsbywgbmEucm0gPSBUUlVFKQ0Kc2QoRk9STV8xJEtpbG8sIG5hLnJtID0gRkFMU0UpDQojbWZ2KEZPUk1fMSRLaWxvKQ0KDQpWYXJpYWJsZTwtYygiS2lsbyIpDQpNZWRpYW5hPC1jKCI0MDI1IikNCk1lZGlhIDwtIGMoIjQ0MTUiKQ0KTW9kYSA8LSBjKCI0MTkwIikNCkRlc3ZpYWNpw7NuX2VzdGFuZGFyPC1jKCIyNTcxLjc5MyIpDQp0YWJsZW1lcm1hIDwtIGRhdGEuZnJhbWUgKFZhcmlhYmxlLCBNZWRpYW5hICwgTWVkaWEgLCBNb2RhICwgRGVzdmlhY2nDs25fZXN0YW5kYXIpDQprbml0cjo6a2FibGUodGFibGVtZXJtYSkNCmBgYA0KDQojIyMgVGltZSBTZXJpZSBQbG90cyAgDQpEZW50cm8gZGUgbGEgZ3LDoWZpY2EgbW9zdHJhZGEsIHNlIHB1ZWRlIG9ic2VydmFyIHVuYSBhbHphIGVuIGxvcyBraWxvcyBkZSBtZXJtYSBxdWUgc2Ugdmllcm9uIGVuIGVsIHByaW1lciB0cmltZXN0cmUgZGVsIGHDsW8sIGVzdGEgY2FudGlkYWQgZGVzcHVlcyBmdWUgZGVjcmVtZW50YW5kbyBjb24gZWwgcGFzbyBkZSBsb3MgbWVzZXMsIGVzdG8gbm9zIHB1ZWRlIGluZGljYXIgZG9zIGNvc2FzLCB1biBpbmNyZW1lbnRvIGVuIHByb2R1Y2Npw7NuIG8gYmllbiwgdW4gbWFsIG1hbmVqbyBkZSBsYSBtYXRlcmlhIHByaW1hLg0KYGBge3J9DQoNCiNGT1JNXzEkRmVjaGE8LWFzLkRhdGUoRk9STSRGZWNoYSxmb3JtYXQ9IiVkLyVtLyV5IikNCg0KI2luc3RhbGwucGFja2FnZXMoImdncGxvdDIiKQ0KbGlicmFyeShnZ3Bsb3QyKQ0Kc3VtbWFyeShGT1JNXzEpDQpnZ3Bsb3QoRk9STV8xLGFlcyh4PUZlY2hhKSkrDQogIGdlb21fbGluZShhZXMoeT1LaWxvKSxjb2xvcj0iYmx1ZSIpKw0KICBsYWJzKHg9IkZlY2hhIix5PSJLaWxvIiwgY29sb3I9IkxlZ2VuZCIpKw0KICAgZ2d0aXRsZSgiS2lsb3MgZGUgbWVybWEgcG9yIG1lcyIpDQpgYGANCg0KIyMjIEhhbGxhemdvcyAgDQpMYXMgdG9uZWxhZGFzIGRlIG1lcm1hLCBubyByZXByZXNlbnRhbiB0b2RhcyBsYXMgdmVjZXMgdW4gY290byBwYXJhIEZPUk0geWEgcXVlIHBsYXRpY2FuZG8gY29uIEZlbGlwZSwgZXN0YXMgc29uIG1heW9ybWVudGUgcG9yIGNhdXNhIGRlbCBwcm92ZWVkb3IgcGVybyBubyByZXByZXNlbnRhbiB1biBjb3N0byBleHRyYSBwb3IgbG8gY3VhbCBzZSByZWdhbGEsIGxvIGludGVyZXNhbnRlIGFxdcOtIHNlcsOtYSBlbmNvbnRyYXIgYWwgcHJvdmVlZG9yIHF1ZSBtw6FzIGVycm9yZXMgdGllbmUgeSB2ZXIgZW4gZWwgc3VwcGx5IGNoYWluIG1hbmVyYXMgZGUgcmV1dGlsaXphciBlc3RhIG1lcm1hLg0KDQojIDxzcGFuIHN0eWxlID0gImNvbG9yOmRhcmtvcmFuZ2UiPiBTY3JhcA0KICANCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQojZmlsZS5jaG9vc2UoKQ0KU0NSQVA8LSByZWFkLmNzdigiQzpcXFVzZXJzXFxkYW55Y1xcRG93bmxvYWRzXFxGT1JNIC0gU2NyYXAgTGltcGlhIC5jc3YiKQ0KYGBgDQoNCiMjIFNlY2Npw7NuIDEuIExpbXBpZXphIGRlIGRhdG9zLCBUcmFuc2Zvcm1hY2nDs24geSBFbnRlbmRpbWllbnRvICgxLTQpIA0KPHN0eWxlPg0KZGl2LmJsdWUgeyBiYWNrZ3JvdW5kLWNvbG9yOiNGRkRCQzg7IGJvcmRlci1yYWRpdXM6IDVweDsgcGFkZGluZzogMjBweDt9DQo8L3N0eWxlPg0KPGRpdiBjbGFzcyA9ICJibHVlIj4NCg0KRGVzY3JpYmUgYnJldmVtZW50ZSDCv3BvcnF1w6kgYXBsaWNhc3RlIGRpY2hhcyB0w6ljbmljYXM/IMK/Y8OzbW8gdGUgcGVybWl0acOzIGxhIGFwbGljYWNpw7NuIGRlIGRpY2hhcw0KdMOpY25pY2FzIHVuYSBtZWpvciBjb21wcmVuc2nDs24gZGUgbGFzIGJhc2VzIGRlIGRhdG9zPyAgDQoNCkxhcyB0w6ljbmljYXMgZGUgbGltcGllemEgcXVlIHNlIGFwbGljYXJvbiBwYXJhIFNDUkFQIGZ1ZXJvbiBlc3BlY8OtZmljYW1lbnRlIHBhcmEgZGVqYXIgbG9zIGRhdG9zIGNvbiBsb3MgcXVlIGliYW1vcyBhIHRyYWJhamFyIGVuIGxhcyBncsOhZmljYXMsIGVzIGRlY2lyLCBzZSBkZWphcm9uIGxvcyBkYXRvcyBkZSBpbXBvcnRhbmNpYSwgZGUgaWd1YWwgbWFuZXJhIGh1Ym8gZWxpbWluYWNpb25lcyBkZSBOL0HCtHMgeSBmaW5hbG1lbnRlIGxhIGNvcnJlY2Npw7NuIGRlIG5vbWJyZXMgZGUgbnVlc3RyYXMgdmFyaWFibGVzLiAgDQoNCkxhIGFwbGljYWNpw7NuIGRlIGRpY2hhcyBmZWNoYXMgbWUgYXl1ZMOzIGEgdmVyIG3DoXMgY2xhcm8gY3VhbGVzIGVyYW4gbG9zIGRhdG9zIHF1ZSBxdWVyw61hIHBhcmEgbG9ncmFyIGhhY2VyIGxhcyBncsOhZmljYXMuIA0KDQo8L2Rpdj4gDQoNCiMjIyBFbnRlbmRlciBCYXNlIGRlIERhdG9zICANCkVzdG8gbm9zIGF5dWRhIGEgc2FiZXIgcXVlIHRpcG8gZGUgdmFyaWFibGUgZXN0YW1vcyB2aWVuZG8geSB2ZXIgc2kgaGF5IGRhdG9zIGFub3JtYWxlcy4NCmBgYHtyfQ0KcmVzdW1lbiA8LSBzdW1tYXJ5KFNDUkFQKQ0KcmVzdW1lbg0KYGBgDQoNCiMjIyBWYXJpYWJsZXMgeSBSZWdpc3Ryb3MgIA0KPGNlbnRlcj4gPHNwYW4gc3R5bGU9ImNvbG9yOlJlZCI+IFI9IDI1MCByZWdpc3Ryb3MgeSA5IHZhcmlhYmxlcyA8L2NlbnRlcj4NCmBgYHtyfQ0Kc3RyKFNDUkFQKQ0KI2xpYnJhcnkocHN5Y2gpDQojaW5zdGFsbC5wYWNrYWdlcygicHN5Y2giKQ0KYGBgDQoNCg0KIyMjIEVsaW1pbmFjacOzbiBkZSBjb2x1bW5hcyAgDQoqKk5vcyBxdWVkYW1vcyBjb24gNSB2YXJpYWJsZXMgeSAyNTAgb2JzZXJ2YWNpb25lcy4qKiAgDQoNClNlIHNlbGVjY2lvbmFyb24gbGFzIGNvbHVtbmFzIGRlIFJlZmVyZW5jaWEsIHVuaWRhZGVzLCB1YmljYWNpw7NuIHkgZXN0YWRvIGRlYmlkbyBhIHF1ZSBlcmFuIHZhcmlhYmxlcyBxdWUgbm8gdmFtb3MgYSB1dGlsaXphciBlbiBudWVzdHJvIGFuw6FsaXNpcy4gDQoNCmBgYHtyfQ0Kc2NyYXAyPC0gU0NSQVANCnNjcmFwMjwtc3Vic2V0KFNDUkFQLHNlbGVjdD0tYyhSZWZlcmVuY2lhLCBVbmlkYWQuZGUubWVkaWRhICwgVWJpY2FjacOzbi5kZS5kZXNlY2hvLCBFc3RhZG8pKQ0Kc3RyKHNjcmFwMikNCnN1bW1hcnkoc2NyYXAyKQ0KYGBgDQpuL2EgcmVlbXBsYXphciBjb24gcHJvbWVkaW9zIHBhcmEgZXZpdGFyIGNhbXBvcyB2YWNpb3MgZW4gbGEgbWVkaWRhIGRlIGxvIHBvc2libGUuIA0KDQoNCiMjIyBDbGFzaWZpY2FjacOzbiBkZSBWYXJpYWJsZXMgDQpFbiBlc3RhIGNsYXNpZmljYWNpb24gbG9ncmFtb3MgaW50cm9kdWNpciBsYXMgdmFyaWFibGVzIHF1ZSB2YW1vcyBhIHV0aWxpemFyIGEgc3VzIGNsYXNpZmljYWNpb25lcyBwYXJhIGRlc3B1ZXMgcG9kZXIgY29tYmluYXJsYXMgZGUgbWFuZXJhIG1hcyBmYWNpbCBhIGxhIGhvcmEgZGUgY29tcGlsYXIgDQpgYGB7cn0NClZhcmlhYmxlPC0gYygiRmVjaGEiLCAiSG9yYSIsICJQcm9kdWN0byIsICIgQ2FudGlkYWQiICwgIlViaWNhY2lvbiIpDQpUaXBvIDwtIGMoIkN1YW50aXRhdGl2YSBDb250aW51YSIsICJDdWFudGl0YXRpdmEgQ29udGludWEiLCAiQ3VhbGl0YXRpdmEiLCAiQ3VhbnRpdGF0aXZhIFJhesOzbiIsICJDdWFsaXRhdGl2YSIpDQpFc2NhbGEgPC0gYygiUmF6b24iLCAiRGlzY3JldGEiLCAiTm9taW5hbCIsICJSYXpvbiIgLCAiTm9taW5hbCIpDQpUYWJsZV9TY3JhcCA8LSBkYXRhLmZyYW1lKFZhcmlhYmxlLCBUaXBvLCBFc2NhbGEpDQprbml0cjo6a2FibGUoVGFibGVfU2NyYXApDQpgYGANCg0KDQojIyMgSW5zdGFsYXIgTGlicmVyw61hcyAgDQpgYGB7cn0NCiNpbnN0YWxsLnBhY2thZ2VzKCJkcGx5ciIpDQojaW5zdGFsbC5wYWNrYWdlcygibWlyYWdlIikNCiNpbnN0YWxsLnBhY2thZ2VzKCJkcGx5ciIpDQojbGlicmFyeShkcGx5cikNCiNsaWJyYXJ5KG1pcmFnZSkNCg0KYGBgDQoNCiMjIyBOL0HCtHMgIA0KDQpEZWJpZG8gYSBxdWUgZW4gbGEgYmFzZSBkZSBkYXRvcyBubyBzZSBlbmN1ZW50cmFuIE1pc3NpbmcgVmFsdWVzLCBlbiBlc3RhIGJhc2UgZGUgZGF0b3Mgbm8gc2UgcHVlZGVuIHJlbXBsYXphciB2YWxvcmVzIHBvciBtZWRpYSwgbWVkaWFuYSB5IG1vZGEgeWEgcXVlIG5vIGFwbGljYS4gDQoNCmBgYHtyfQ0Kc3VtKGlzLm5hKHNjcmFwMikpDQpzdW0oaXMubmEoU0NSQVApKQ0Kc2FwcGx5KHNjcmFwMiwgZnVuY3Rpb24oeCkgc3VtKGlzLm5hKHgpKSkNCnNhcHBseShTQ1JBUCwgZnVuY3Rpb24oeCkgc3VtKGlzLm5hKHgpKSkNCmBgYA0KDQojIyMgQ2FtYmlhciBjb2x1bW5hcyB5IHZhcmlhYmxlcyAgDQpDYW1iaWFyIGxvcyBub21icmVzIGRlIGxhcyBjb2x1bW5hcyAvIHZhcmlhYmxlcyBhIG5vbWJyZXMgbcOhcyBjb3J0b3MgeSBlc3BlY8OtZmljb3MuIFBvciBlamVtcGxvLCBtdW5pY2lwaW8g4oaSIG1waW8sIHNhbGFyaW8gbcOtbmltbyBkaWFyaW8g4oaSIHNhbGFyaW9fbWluLiANCg0KU2UgY2FtYmlhcm9uIGxvcyBub21icmVzIGRlIGxhcyB2YXJpYWJsZXMgYSBub21icmVzIG1hcyBjb3J0b3MuIFBhcmEgbm8gY29udGFyIGNvbiBub21icmVzIGxhcmdvcy4gDQoNCmBgYHtyfQ0KI3NlbGVjY2lvbmFyIGNvbHVtbmFzIC8gdmFyaWFibGVzLg0KI3NjcmFwMjwtU0NSQVAgJT4lIHNlbGVjdChvbmVfb2YoJ0ZlY2hhJywnSG9yYScsJ1Byb2R1Y3RvJywnQ2FudGlkYWQnLCdVYmljYWNpw7NuLmRlLm9yaWdlbicpKQ0KDQojUmVub21icmFyIGxhcyBjb2x1bW5hcyAvdmFyaWFibGVzIHNlbGVjY2lvbmFkYXMuIA0KY29sbmFtZXMoc2NyYXAyKSA8LWMgKCdGZWNoYScsJ0hvcmEnLCdQcm9kLicsJ0NhbnQuJywnT3JpZ2VuJykNCg0KYGBgDQoNCiMjIDEuIEFuw6FsaXNpcyBFc3RhZMOtc3RpY28gU0NSQVAgKDUpIA0KIyMjIEdyw6FmaWNvcyAgDQojIyMgVGFibGEgZGUgRnJlY3VlbmNpYSAgDQpBcXXDrSBzZSBwdWVkZSBvYnNlcnZhciBxdWUgZWwgbHVnYXIgZW4gZG9uZGUgZWwgU2NyYXAgc2UgZm9ybWEgbWFzIGZyZWN1ZW50ZW1lbnRlIGVzIGVuIFNBQi9QcmUtUHJvZHVjY2nDs24gcG9yIGxvIGN1w6FsIHNlIGVudGllbmRlIHF1ZSBlcyBlbCDDoXJlYSBlbiBkb25kZSBtw6FzIGNhcnRvbiBzZSBtYW5lamEgcGFyYSBoYWNlciB1biBwcm9kdWN0byBmaW5hbCwgZXN0byBub3MgaW5kaWNhIHF1ZSBzZSBkZWJlcsOhbiBoYWNlciBsb3MgY2FtYmlvcyBjb3JyZXNwb25kaWVudGVzIHBhcmEgbWFuZWphciBlc3RvcyBkZXNwZXJkaWNpb3MgeSBiYWphcmxvcyBvIGJpZW4sIHJlLXViaWNhcmxvcyBwYXJhIG90cm9zIHRpcG9zIGRlIHV0aWxpemFjacOzbiBwb3IgbG8gcXVlIGNyZW8geWEgc2UgdXRpbGl6YW4uDQpgYGB7cn0NCiNpbnN0YWxsLnBhY2thZ2VzKCdlcGlEaXNwbGF5JykNCmxpYnJhcnkoZXBpRGlzcGxheSkNCg0KdGFiMShzY3JhcDIkT3JpZ2VuLCBzb3J0Lmdyb3VwID0gImRlY3JlYXNpbmciLCBjdW0ucGVyY2VudCA9IFRSVUUsIG1haW4gPSAiRGlzdHJpYnVjacOzbiBkZWwgT3JpZ2VuIGRlbCBTY3JhcCIpIA0KYGBgDQoNCiMjIyBHcmFmaWNhIGN1YWxpdGF0aXZhICANClNlIGRlbm90YW4gZW4gY29ycmVsYWNpb24gY29uIGxhIGZlY3VlbmNpYSB1bmEgbWF5b3IgY2FudGlkYWQgZGUga2dzIGVuIGxhIHByZS1wcm9kdWNjaW9uIGNvbiB1bmEgZGlmZXJlbmNpYSBjYXNpIHRyaXBsaWNhZGEgZW4gY29tcGFyYWNpb24gZGUgbGEgY2FudGlkYWQgbWFzIHBlcXVlw7FhLCBlc3RvIGhhY2Ugc2VudGlkbyBhbCBzZXIgdW4gw6FyZWEgZGUgbWVub3IgbWFuaXB1bGFjacOzbiBkZSBjYXJ0b24uDQpgYGB7cn0NCmJhcnBsb3QodGFibGUoc2NyYXAyJENhbnQuLHNjcmFwMiRPcmlnZW4pLCBjb2w9Im9yYW5nZSIsIG1haW4gPSAiS2lsb3MgZGUgU2NyYXAgc2Vnw7puIHN1IG9yaWdlbiIsIHhsYWIgPSAiT3JpZ2VuIiwgeWxhYiA9ICJLaWxvcyIgKQ0KYGBgDQoNCiMjIyBQcm9wdWVzdGFzDQoxLiBEYXIgdW5hIGludmVzdGlnYWNpw7NuIGEgbGEgb3B0aW1pemFjacOzbiBkZSBtYXRlcmlhbGVzIHBhcmEgdmVyIGNvbW8gc2UgcG9kcsOtYSBkZWNyZW1lbnRhciBlbCBzY3JhcC4NCg0KIyMgMi4gQW7DoWxpc2lzIEV4cGxvcmF0b3JpbyANCg0KIyMjIERlc2NhcmdhciBsaWJyZXLDrWFzIA0KYGBge3J9DQojaW5zdGFsbC5wYWNrYWdlcygia2tibGVFeHRyYSIpIA0KI2luc3RhbGwucGFja2FnZXMoInNkIikNCiNpbnN0YWxsLnBhY2thZ2VzKCJtb2RlZXN0IikNCiNsaWJyYXJ5KG1vZGVlc3QpDQojaW5zdGFsbC5wYWNrYWdlcygiZHBseXIiKQ0KI2xpYnJhcnkoZHBseXIpDQojbGlicmFyeShrYmxlRXh0cmEpDQojc3VtbWFyeShiZDEpDQpgYGANCiMjIyBUYWJsYSBkZSBtZWRpYSwgbWVkaWFuYSwgbW9kYSAgeSBkZXN2aWFjacOzbiBlc3RhbmRhcmQNCkRlbnRybyBkZSBlc3RhIHRhYmxhIHNlIHB1ZWRlbiBvYnNlcnZhciBkaXN0aW50b3MgcmVzdWx0YWRvcyBxdWUgbm9zIGluZm9ybWFuIGFjZXJjYSBkZSBsYXMgY2FudGlkYWRlcywgcG9yIGVqZW1wbG8gZWwgcHJvbWVkaW8gbyBsYSBtZWRpYSBmdWUgZGUgNi43IGRlbnRybyBkZSBudWVzdHJvcyByZXN1bHRhZG9zIGRlIHNjcmFwLCBtaWVudHJhcyBxdWUgZWwgcXVlIG3DoXMgc2UgcmVwaXRpbyBmdWUgMSwgcG9kcsOtYW1vcyBkZWNpciBxdWUgYmFzYW5kb25vcyBlbiBlc3RvLCBubyBodWJpZXJvbiB0YW50b3MgZGVzcGVyZGljaW9zIGRlIFNDUkFQIGRlbnRybyBkZSBsYSBwcm9kdWNjacOzbi4NCmBgYHtyfQ0Kc2Qoc2NyYXAyJENhbnRpZGFkLCBuYS5ybT0gVFJVRSkgIA0KDQpWYXJpYWJsZTwtYygiQ2FudC4iKQ0KTWVkaWFuYTwtYygiMi4wMCIpDQpNZWRpYSA8LSBjKCI2LjY5NiIpDQpNb2RhIDwtIGMoIjEiKSAjRVhDRUwgDQpEZXN2aWFjacOzbl9lc3RhbmRhcjwtYygiMTEuODQ4ODUiKQ0KdGFibGUxIDwtIGRhdGEuZnJhbWUgKFZhcmlhYmxlLCBNZWRpYW5hLCBNZWRpYSwgTW9kYSwgRGVzdmlhY2nDs25fZXN0YW5kYXIpDQprbml0cjo6a2FibGUodGFibGUxKQ0KYGBgDQoNCiMjIyBHcsOhZmljb3MgIA0KYGBge3J9DQojaW5zdGFsbC5wYWNrYWdlcygiZ2dwbG90MiIpDQojaW5zdGFsbC5wYWNrYWdlcygiYmFycGxvdCIpDQpsaWJyYXJ5KGdncGxvdDIpDQpzdW1tYXJ5KHNjcmFwMikNCmBgYA0KDQojIyMgVGltZSBTZXJpZXMgUGxvdHMNCkFxdcOtIGhhYmxhbW9zIGRlIGxhcyBjYW50aWRhZGVzIHF1ZSBzZSBtYW5lamFzbiBlbCBsb3Mgb3JpZ2VuZXMsIHZlbW9zIHF1ZSB0YW1iaWVuIGVuIGxhIHByZS1wcm9kdWNjacOzbiBpZ3VhbCBxdWUgZW4gbGEgdGFibGEgZGUgZnJlY3VlbmNpYSwgc2UgZGVub3RhIHVuYSBjYW50aWRhZCBhdW1lbnRhZGEgZW4gbGEgUHJlLXByb2R1Y2Npw7NuLCBoYWJsYW1vcyB0YW1iacOpbiBkZSBsYSBnZW5lcmFjacOzbiBjcmVjaWVudGUgZGUgZXN0YSBlbiBlbCDDoXJlYSwgcG9yIGxvIHF1ZSBoYWJyw6EgcXVlIGRhcmxlIHVuIHZpc3Rhem8gdWx0aW1hZGFtZW50ZSBlbiBlbCBwcm92ZWVkb3IgZGVsIHJhdyBtYXRlcmlhbCB5IHZlciBjb21vIHNlIHB1ZWRlIGFjb21vZGFyIHBhcmEgbGFzIG5lY2VzaWRhZGVzIHF1ZSB0aWVuZSBGT1JNIGRlY3JlbWVudGFuZG8gbGEgY2FudGlkYWQgZGUgU0NSQVAgcXVlIHNlIHByb2R1Y2UuDQpgYGB7cn0NCmdncGxvdChzY3JhcDIsYWVzKHg9Q2FudC4pKSsNCiAgZ2VvbV9saW5lKGFlcyh5PU9yaWdlbiksY29sb3I9Ik9yYW5nZSIpKw0KICBsYWJzKHg9IkNhbnQiLHk9Ik9yaWdlbiIsIGNvbG9yPSJMZWdlbmQiKSsNCiAgIGdndGl0bGUoIk1heW9yZXMgY2FudGlkYWRlcyBkZSBTY3JhcCBwb3Igb3JpZ2VuIikNCmBgYA0KDQoNCiMjIyBHcsOhZmljbyBkZSBEaXNwZXJzacOzbg0KRXN0ZSBncsOhZmljbyBkZSBib3hwbG90IG5vcyBpbmRpY2EgcXVlIHVuIDI1JSBkZSBudWVzdHJvcyBsdWdhcmVzIGRlIG9yaWdlbmVzIHR1dmllcm9uIDYwIFNjcmFwcyBtaWVudHJhcyBxdWUgZWwgb3RybyAyNSUgdHV2aWVyb24gbWFzIGRlIDEwMCBlbiBjYW50aWRhZGVzIGRlIHNjcmFwIGxvIGN1YWwgbm9zIGlkaWNhIHVuYSBjYXJnYSBlbiBzb2xvIHVuIMOhcmVhLg0KYGBge3J9DQpib3hwbG90cz1zdWJzZXQoc2NyYXAyLHNlbGVjdD0tYyhPcmlnZW4pKQ0KYm94cGxvdCh0YWJsZSAoc2NyYXAyJE9yaWdlbiksIG1haW4gPSAiVWJpY2FjacOzbiBkZSBPcmlnZW4iLCB4bGFiID0gIk9yaWdlbiIsIHlsYWIgPSAiQ2FudGlkYWQiKQ0KYGBgDQoNCiMjIyBIYWxsYXpnb3MNCg0KRW4gZXN0ZSBhbmFsaXNpcyBub3MgZGltb3MgY3VlbnRhIHF1ZSBsb3MgZGF0b3MgZXN0YWJhbiBvcmduYWl6YWRvcyBlcyBkZWNpciBubyBjb250YWJhbiBjb24gbWlzc2luZyB2YWx1ZXMgcG9yIGxvIHRhbnRvIGVzIGFsZ28gYnVlbm8gcGFyYSBlbCBhbmFsaXNpcywgZGUgdG9kb3MgbW9kb3MgZXMgaW1wb3J0YW50ZSBjb25zaWRlcmFybG9zIHNpIGVzIHJlbGV2YW50ZSBwYXJhIGVsIGFuYWxpc2lzLCBlbiBlc3RlIGNhc28gbm8gc2UgaHViaWVyYW4gZWxpbWluYWRvIHNpIG5vIHF1ZSBzZSBodWJpZXJhbiByZWVtcGxhemFkbyBwb3IgbGEgbWVkaWFuYSBkZXBlbmRpZW5kdGUgZGUgbGEgdmFyaWFibGUgcXVlIGVzdHV2aWVyYW1vcyBhbmFsaXphbmRvLg0KDQpBbmFsaXphbmRvIGVzdGFzIHZhcmlhYmxlcyBzZSBjb25maXJtYSBxdWUgZW4gZWwgYXJlYSBkZSBwcmUtcHJvZHVjY2nDs24sZXMgZG9uZGUgc2UgZ2VuZXJhIGxhIG1heW9yaWEgZGVsIHNjcmFwIGVuIHN1IG1heW9yaWEgc2UgZ2VuZXJhIGNhc2kgZWwgODUlIGRlIHNjcmFwLCBxdWUgZ2VuZXJhbiBkZW50cm8gZGUgbGEgZW1wcmVzYSwgcG9yIGxvIHRhbnRvIGVzIGFsYWdvIGFsYXJtYW50ZSBwb3IgbG8gdGFudG8gc2UgdGllbmVuIHF1ZSB0b21hciBkZWNpc2lvbmVzIGltcG9ydGFudGVzIHBhcmEgcG9kZXIgcmVhbGl6YXIgY2FtYmlvcyBlbiBlc3RhIGFyZWEgcGFyYSByZWR1Y2lyIGxhIGNhbnRpZGFkIGRlIHNjcmFwLg0KDQoNCiMgPHNwYW4gc3R5bGUgPSAiY29sb3I6ZGFya29yYW5nZSI+IFNlY2Npw7NuIDEgeSAyIEJhc2UgZGUgRGF0b3MgRXh0ZXJuYQ0KDQoNCiMjIFNFQ0NJT04gMSANCg0KDQoNCmBgYHtyfQ0KDQpsaWJyYXJ5KHBzeWNoKQ0KbGlicmFyeShsdWJyaWRhdGUpDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KEdHYWxseSkNCmxpYnJhcnkoVFNzdHVkaW8pDQpsaWJyYXJ5KGZvcmVjYXN0KQ0KYGBgDQoNCg0KDQoNCmBgYHtyfQ0KDQpDb21wYW5pZXMgPC1yZWFkLmNzdigiQzpcXFVzZXJzXFxkYW55Y1xcRG93bmxvYWRzXFxleHRlcm5hX2JkMSBjc3YxLmNzdiIpDQpzdW1tYXJ5KENvbXBhbmllcykNCmBgYA0KDQoNCiMjIyAxLiBMaW1waWV6YSwgVHJhbnNmb3JtYWNpw7NuIHkgT3JnYW5pemFjacOzbiBkZSBCYXNlcyBkZSBEYXRvcyAgDQpgYGB7cn0NCnN0cihDb21wYW5pZXMpDQpkZXNjcmliZShDb21wYW5pZXMpDQpgYGANCg0KIE5vdGE6IERlYmlkbyBhIGxhIHZlcnNpw7NuIGRlIFIsIG5vcyBkZWphIGRlc2NhcmdhciBlbCBwYXF1ZXRlICJwc3ljaCIuIFNpbiBlbWJhcmdvLCBubyBub3MgZGVqYSBsbGFtYXIgYSBsYSBsaWJyZXLDrWEgInBzeWNoIiwgcG9yIGxvIHRhbnRvIHV0aWxpemFtb3Mgc3RyLCBwYXJhIG9idGVuZXIgZWwgbnVtZXJvIGRlIGxhcyB2YXJpYWJsZXMgZGUgbGEgYmFzZSBkZSBkYXRvcy4NCg0KDQoNCiMjIyMgRXNjYWxhIGRlIE1lZGljacOzbiAgDQpSZWFsaXphbW9zIHVuYSB0YWJsYSBkb25kZSB2aWVuZSBjbGFzaWZpY2FkbyBjYWRhIHZhcmlhYmxlIHkgYWdyZWdhbW9zIHVuYSBjb2x1bW5hIGNvbiBsYSBlc2NhbGEgZGUgbWVkaWNpw7NuIHBhcmEgY2FkYSB2YXJpYWJsZS4gDQpgYGB7cn0NCg0KVmFyaWFibGU8LWMoIkdlb2dyYXBoeSIsIkNhdGVnb3J5IiwiRGF0YS5UeXBlIiwgIlVuaXQiLCJDdXJyZW50IENvbnN0YW50IiwiWWVhcnMiKQ0KVHlwZTwtYygiQ3VhbGl0YXRpdmEiLCAiQ3VhbGl0YXRpdmEiLCAiQ3VhbGl0YXRpdmEiLCAiQ3VhbGl0YXRpdmEiLCAiQ3VhbGl0YXRpdmEiLCAiQ3VhbnRpdGF0aXZhIChDb250aW51YSkiKQ0KRXNjYWxhX2RlX01lZGljacOzbiA8LSBjKCJQYcOtc2VzIiwgIlByb2R1Y3RvIiwgIkRlcGFydGFtZW50byIsIlRpcG8gZGUgTW9uZWRhIiwgIlByZWNpbyBhY3R1YWwiLCAiR2FuYW5jaWEgKFJhem9uKSIpDQp0YWJsZTwtZGF0YS5mcmFtZShWYXJpYWJsZSxUeXBlLEVzY2FsYV9kZV9NZWRpY2nDs24pDQprbml0cjo6a2FibGUodGFibGUpDQpgYGANCg0KDQoNCiMjIyMgTGltcGllemEgZGUgZGF0b3MgIA0KIExhIHByaW1lciB0ZWNuaWNhIGRlIGxpbXBpZXphIHF1ZSB1dGlsaXphbW9zIGZ1ZSwgZWxpbWluYXIgY29sdW1uYXMgZGViaWRvIGEgcXVlIGNvbnRhYmFtb3MgY29uIGRhdG9zIGxvcyBjdWFsZXMgbm8gZXJhbiByZWxldmFudGVzIHBhcmEgZWwgYW7DoWxpc2lzLiAgICANCiBMYSBzZWd1bmRhIGhlcnJhbWllbnRhIGRlIGxpbXBpZXphIHF1ZSB1dGlsaXphbW9zIHBhcmEgbGEgdmlzdWxpemFjacOzbiBkZSBsb3MgZGF0b3MgZnVlIGltcGxlbWVudGFyIHVuYSBudWV2YSBjb2x1bW5hIGNvbW8gZWwgdG90YWwgZGUgbGEgUHJvZHVjY2nDs24gZGUgbGFzIHZhcmlhYmxlcyBxdWUgc2UgcHJvZHVjZW4gcG9yIHBhw61zLg0KDQojIyMgUmVtb3ZlciBWYWxvcmVzIElycmVsZXZhbnRlcyANCg0KIyMjIyBFbGltaW5hciBjb2x1bW5hcyANCg0KYGBge3J9DQpiZDEgPC0gQ29tcGFuaWVzDQpiZDE8LXN1YnNldChiZDEsc2VsZWN0PS1jKENhdGVnb3J5LERhdGEuVHlwZSxDdXJyZW50LkNvbnN0YW50KSkNCnN0cihiZDEpDQpgYGANCg0KIyMjIyBBZ3JlZ2FyIENvbHVtbmFzIA0KYGBge3J9DQpiZDEkVG90YWxfUHJvZHVjY2lvbjwtIGJkMSRYMjAxNitiZDEkWDIwMTcrYmQxJFgyMDE4K2JkMSRYMjAxOStiZDEkWDIwMjArYmQxJFgyMDIxDQpiZDEkUHJvbWVkaW9fWDIwMjE8LSBtZWFuKGJkMSRYMjAyMSkNCg0Kc3VtbWFyeShiZDEpDQpzdHIoYmQxKQ0KYGBgDQoNCg0KIyMjIyDCv0N1w6FudG9zIE5BJ3MgdGVuZ28gZW4gbGEgYmFzZSBkZSBkYXRvcz8gDQoNCmBgYHtyfQ0Kc3VtKGlzLm5hKGJkMSkpDQpgYGANCiBOb3RhOiBTZSBlbGltaW5hbiBDYXRlZ29yeSwgRGF0YS5UeXBlIHkgQ3VycmVudC5Db25zdGFudCwgeWEgcXVlIG5vIG5vcyBzaXJ2ZW4sIGRlYmlkbyBhIHF1ZSBlcyBlbCBtaXNtbyBkYXRvIHBhcmEgdG9kb3MgbG9zIHJlZ2lzdHJvcyB5IGVzIGFsZ28gcXVlIG5vIG5vcyBhcG9ydGEgYWxndW5hIGluZm9ybWFjacOzbi4gDQoNCiMjIyAgQW7DoWxpc2lzIEV4cGxvcmF0b3JpbyBkZSBsYXMgQmFzZXMgZGUgRGF0b3MgDQpgYGB7cn0NCmRlc2NyaWJlKGJkMSkNCmBgYA0KDQoNCg0KRW4gZWwgYW7DoWxpc2lzIGRlc2NyaXB0aXZvIHNlIG11ZXN0cmFuIGxvcyB2YWxvcmVzIHByb21lZGlvIGRlbCB0b3RhbCBkZSBwcm9kdWNjaW9uZXMgZGUgMjAxNiBhIDIwMjEuDQoNCiMjIyBUYWJsYSBkZSBGcmVjdWVuY2lhIA0KYGBge3J9DQpiZDIgPC0gdGFibGUoYmQxJFVuaXQpDQpiZDIgPC0gcHJvcC50YWJsZShiZDIpDQpiZDINCmBgYA0KDQoNCiMjIyBUYWJsYSBjcnV6YWRhIA0KYGBge3J9DQp0YWJsZShiZDEkVW5pdCwgYmQxJFByb21lZGlvX1gyMDIxKQ0KYGBgDQoNCg0KTGEgdGFibGEgbm9zIG11ZXN0cmEgbGEgY2FudGlkYWQgcHJvbWVkaW8gZW4gbWlsbG9uZXMgcHJvZHVjaWRhIGVuIDIwMjEgcG9yIGNhZGEgdW5pZGFkIG1vbmV0YXJpYS4gRW4gZXN0ZSBjYXNvLCB2ZW1vcyBxdWUgZW4gMjAyMSBzZSBwcm9kdWpvIGVuIHByb21lZGlvIG3DoXMgZGUgMU1NIGRlICJjdXJyZW5jaWVzIiAobm8gc2UgcHVlZGUgZGVmaW5pciB1bmEgdW5pZGFkIG1vbmV0YXJpYSBlc3BlY8OtZmljYSBkZWJpZG8gYSBxdWUgZXN0YW1vcyBwb25kZXJhbmRvIGRpc3RpbnRhcyBtb25lZGFzIGludGVybmFjaW9uYWxlcykuIENvbmZvcm1lIHNlIGFuYWxpemEgbGEgdGFibGEsIHZlbW9zIHF1ZSBlbCBldXJvIGdlbmVyw7MgMTggdmVjZXMgZWwgcHJvbWVkaW8gZGUgcHJvZHVjY2nDs24gZGUgY2FydMOzbiBlc3RpbWFkbyBwYXJhIDIwMjEsIGVzIGRlY2lyLCBlcyBsYSBtb25lZGEgaW50ZXJuYWNpb25hbCBxdWUgbcOhcyBwcm9kdWpvIGNhcnTDs24gYSBuaXZlbCBpbnRlcm5hY2lvbmFsIGVuIDIwMjEuIExhIHNpZ3VpZW50ZSBtb25lZGEgY29uIG1heW9yIGNhcGFjaWRhZCBkZSBwcm9kdWNjacOzbiBmdWUgVVNEIG1pbGxpb25zLiANCg0KIyMjIEdyw6FmaWNhcyBkZSBkYXRvcyBDdWFsaXRhdGl2YXMgeSBDdWFudGl0YXRpdmFzIA0KDQojIyMjIEN1YWxpdGF0aXZhIGNvbiBVbml0IA0KYGBge3J9DQpiYXJwbG90KGJkMiwgeGxhYj0nVGlwbyBkZSBNb25lZGEnLA0KICAgICAgICB5bGFiPSdGcmVjdWVuY2lhIFJlbGF0aXZhJywgbGFzPTEpDQpgYGANCg0KDQpMYSBncsOhZmljYSBub3MgbXVlc3RyYSBxdWUgZGUgYWN1ZXJkbyBhIGxhIGZyZWN1ZW5jaWEgcmVsYXRpdmEgZGUgcHJvZHVjY2nDs24sIEluZG9uZXNpYSBlcyBsYSB1bmlkYWQgbW9uZXRhcmlhIHF1ZSBtw6FzIGNhcnTDs24gaGEgZW50cmVnYWRvLiANCg0KIyMjIyBDdWFudGl0YXRpdmEgY29uIFRvdGFsX1Byb2R1Y2Npb24gDQpgYGB7cn0NCmJkMyA8LSBiZDENCmFnZ3JlZ2F0ZSh4PWJkMyRUb3RhbF9Qcm9kdWNjaW9uLCBieT1saXN0KGJkMyRHZW9ncmFwaHkpLEZVTj1zdW0pDQpgYGANCg0KIEVuIGxhIHRhYmxhIGFudGVyaW9yIHNlIG11ZXN0cmEgZWwgdG90YWwgZGUgcHJvZHVjY2nDs24gZ2VuZXJhZG8gcG9yIGNhZGEgcGHDrXMuIEhhY2llbmRvIHVuYSBwb25kZXJhY2nDs24gZGUgbG9zIDUgcGHDrXNlcyBxdWUgbWF5b3IgcHJvZHVjY2nDs24gZGUgY2FydMOzbiB0aWVuZW4gKGhhY2llbmRvICBjb250ZW8gaGlzdMOzcmljbyBkZSAyMDE2IGEgMjAyMSksIHZlbW9zIHF1ZSBzZSBkZXN0YWNhbiBJcsOhbiwgVmlldG5hbSwgQ29yZWEgZGVsIFN1ciwgSmFww7NuIGUgSW5kb25lc2lhLiANCg0KYGBge3J9DQpoaXN0KGxvZyhiZDEkVG90YWxfUHJvZHVjY2lvbiksIG1haW4gPSAiSGlzdG9ncmFtYSBkZSBQcm9kdWNjacOzbiBUb3RhbCIsIHhsYWI9IlByb2R1Y2Npw7NuIFRvdGFsIiwgDQogICAgIHlsYWI9IkZyZWN1ZW5jaWEiLCBjb2w9ImJsdWUxIikNCmBgYA0KDQoNCiBFbiBsYSBncsOhZmljYSBhbnRlcmlvciBzZSBzaW1ib2xpemEgbGEgZGlzdHJpYnVjacOzbiBkZSBsYSBtdWVzdHJhIHJlc3BlY3RvIGEgbGEgcHJvZHVjY2nDs24gdG90YWwgeSBsYSBmcmVjdWVuY2lhIGRlIMOpc3RhLiBEZSBhY3VlcmRvIGEgbGEgZnJlY3VlbmNpYSB0b3RhbCwgdmVtb3MgcXVlIHNlIHRpZW5lIHVuYSBtYXlvciBwcm9kdWNjacOzbiBwb3IgZnJlY3VlbmNpYSBlbnRyZSAxMCB5IDE1LCBlcyBkZWNpciwgbGEgcHJvZHVjY2nDs24gdG90YWwgZXMgbcOhcyBhbHRhIHkgdGllbmUgdW5hIGZyZWN1ZW5jaWEgbWF5b3IgYSAxNSBxdWUgc2UgbXVlc3RyYSBjb21vIGVsIG3DoXMgZWxldmFkbyBlbiBlbCBoaXN0b2dyYW1hLg0KDQojIyMgR3LDoWZpY2FzIGRlIERpc3BlcnNpw7NuDQoNCiMjIyMgUmVsYWNpw7NuIEdlb2dyYXBoeSBjb24gUHJvZHVjY2nDs24gVG90YWwNCmBgYHtyfQ0KZ2dwbG90KGJkMSwgYWVzKHg9VG90YWxfUHJvZHVjY2lvbiwgeT1HZW9ncmFwaHkpKSArIA0KICBnZW9tX3BvaW50KHNoYXBlPTE5LCBzaXplPTMpICsgbGFicyh0aXRsZSA9ICJSZWxhY2nDs24gZW50cmUgbG9zIFBhw61zZXMgeSBsYSBQcm9kdWNjacOzbiBUb3RhbCIsY2FwdGlvbiA9IlBhc3Nwb3J0X1Byb2R1Y2Npw7NuQ2FydG9uIix4PSJQcm9kdWNjacOzbl9Ub3RhbCIsIHk9Ikdlb2dyYXBoeSIpICsgdGhlbWVfY2xhc3NpYygpDQoNCmBgYA0KDQogRW4gbGEgZ3LDoWZpY2EgYW50ZXJpb3Igc2UgbXVlc3RyYSBsYSByZWxhY2nDs24gZW50cmUgbG9zIHBhw61zZXMgeSBsYSBwcm9kdWNjacOzbiB0b3RhbC4gU2UgdmUgcXVlIGhheSB1bmEgZGlzcGVyc2nDs24gbWF5b3IgcGFyYSBsb3MgcGHDrXNlcyBlbiBlbCBjZW50cm8gZGUgbGEgZ3LDoWZpY2EuIEVzdG8gc2lnbmlmaWNhIHF1ZSBoYXkgbcOhcyBpcnJlZ3VsYXJpZGFkIGVuIGxhIHByb2R1Y2Npw7NuIHRvdGFsIHF1ZSBoYW4gZ2VuZXJhZG8uIA0KDQpgYGB7cn0NCmJveHBsb3Q9c3Vic2V0KGJkMSxzZWxlY3QgPSAtYyhUb3RhbF9Qcm9kdWNjaW9uLEdlb2dyYXBoeSkpDQpib3hwbG90KGJkMSRUb3RhbF9Qcm9kdWNjaW9uLCBtYWluPSAiVG90YWwgZGUgcHJvZHVjY2nDs24iKQ0KYGBgDQoNCg0KRW4gbGEgZ3LDoWZpY2EgYW50ZXJpb3IgdmVtb3MgZWwgdG90YWwgZGUgcHJvZHVjY2nDs24gZGUgYWN1ZXJkbyBhIGxhIGdlb2dyYWbDrWEuIEFsIGlndWFsIHF1ZSBsYSBncsOhZmljYSBhbnRlcmlvciwgaGF5IHVuYSBjb3JyZWxhY2nDs24gbWF5b3IgYWNvcmRlIGFsIHRvdGFsIGRlIHByb2R1Y2Npw7NuLiANCg0KYGBge3J9DQpWb2w8LXRzKGJveHBsb3Qsc3RhcnQ9YygyMDE2LDEpLGZyZXF1ZW5jeT0xMikNCnRzX3Bsb3QoVm9sLA0KICAgICAgICB0aXRsZSA9ICJEZXNlbXBlw7FvIGRlIGxhIEluZHVzdHJpYSBBdXRvbW90cml6OiBQcm9kdWNjacOzbiBkZSBjYXJ0w7NuIGdsb2JhbCBkZSAyMDE2IGEgMjAyMSIsDQogICAgICAgIFl0aXRsZSA9ICJVbmlkYWRlcyBlbiBtaWxlcyIsDQogICAgICAgIFh0aXRsZSA9ICJBw7FvcyIsIA0KICAgICAgICBzbGlkZXIgPSBUUlVFKQ0KYGBgDQoNCg0KIEVuIGVzdGEgZ3LDoWZpY2Egc2UgdmUgZWwgZGVzZW1wZcOxbyBkZSBsYSBpbmR1c3RyaWEgYXV0b21vdHJpeiBkZSAyMDE2IGEgMjAyMS4gRW4gZ2VuZXJhbCwgc2UgbXVlc3RyYSBxdWUgZWwgdG90YWwgZGUgcHJvZHVjY2nDs24gZGUgY2FydMOzbiBhIG5pdmVsIGdsb2JhbCBmdWUgbWF5b3IgZW4gMjAyMSBjb250cmEgb3Ryb3MgYcOxb3MuIA0KDQoNCiMgPHNwYW4gc3R5bGUgPSAiY29sb3I6ZGFya29yYW5nZSI+IFByZWRpY2Npw7NuDQojIyMgSW1wb3J0YXIgYmFzZSBkZSBkYXRvcyAgDQpgYGB7cn0NCmJkNSA8LXJlYWQuY3N2KCJDOlxcVXNlcnNcXGRhbnljXFxEb3dubG9hZHNcXGV4dGVybmFfYmQyIGNzdjIuY3N2IikNCnN1bW1hcnkoYmQ1KQ0KDQpzdW0oaXMubmEoYmQ1KSkNCg0KYmQ1JFRvdGFsX1Byb2R1Y2Npb248LSBiZDEkWDIwMTYrYmQxJFgyMDE3K2JkMSRYMjAxOCtiZDEkWDIwMTkrYmQxJFgyMDIwK2JkMSRYMjAyMQ0KDQpzdW1tYXJ5KGJkNSkNCnN0cihiZDUpDQoNCnN1bShpcy5uYShiZDUpKQ0KYGBgDQoNCg0KIyMjIyBNb2RlbG9zIGRlIHJlZ3Jlc2nDs24gbGluZWFsIG3Dumx0aXBsZSANCg0KIyMjIyBNb2RlbG9zIGRlIHJlZ3Jlc2nDs24gbGluZWFsIG3Dumx0aXBsZTogUHJvZHVjY2nDs24gZGUgY2FydMOzbiBlbiAyMDIyIGEgbml2ZWwgZ2xvYmFsIA0KYGBge3Igd2FybmluZz1GQUxTRX0NCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KGJyb29tKQ0KbGlicmFyeShnZ3B1YnIpDQoNCmluZHVzdHJpYUEgPC1yZWFkLmNzdigiQzpcXFVzZXJzXFxkYW55Y1xcRG93bmxvYWRzXFxJbmR1c3RyaWEgQXV0by5jc3YiKQ0KDQpiZDYgPC1yZWFkLmNzdigiQzpcXFVzZXJzXFxkYW55Y1xcRG93bmxvYWRzXFxleHRlcm5hX2JkMyBjc3YzICgxKS5jc3YiKQ0KDQpiZDYgPC0gYmQ2Wy1jKDEpLF0NCg0KDQpzdW1tYXJ5KGJkNikNCnN1bW1hcnkoaW5kdXN0cmlhQSkNCnN0cihpbmR1c3RyaWFBKQ0KDQpyZWdyZXNpb24xIDwtIGxtKHZlbnRhc19hdXRvcGFydGVzX2FudWFsIH4gIGVzdGFkbyArIGV4cG9ydGFjaW9uZXNfYW51YWwgKyBwb2JsYWNpb25fb2N1cGFkYV9lbnNhbWJsYWRvcmFfeWVhciAsZGF0YSA9IGluZHVzdHJpYUEpDQpzdW1tYXJ5KHJlZ3Jlc2lvbjEpDQoNCnJlZ3Jlc2lvbjIgPC0gbG0oVG90YWxfUHJvZHVjY2lvbiB+IEHDsW8gKyBQcm9kdWNjaW9uLCBkYXRhPWJkNSkNCnN1bW1hcnkocmVncmVzaW9uMikNCg0KYmQ1IDwtIGRhdGEuZnJhbWUoQcOxbz0yMDIyLCBQcm9kdWNjaW9uPSAxNzAwMDAwMDApDQpwcmVkaWN0KHJlZ3Jlc2lvbjIsYmQ1KQ0KDQppbmR1c3RyaWE8LSBkYXRhLmZyYW1lKEHDsW89MjAyMiwgZXN0YWRvPSA3OTAzMDAwMCkNCnByZWRpY3QocmVncmVzaW9uMSxpbmR1c3RyaWFBKQ0KDQoNCmBgYA0KDQpWaWVuZG8gbG9zIGRhdG9zIHF1ZSBzZSBtdWVzdHJhbiBlbiBsYSByZWdyZXNpw7NuLCBzZSBwdWVkZSBvYnNlcnZhciB1bmEgYWx6YSBlbiBsYSBzaWduaWZpY2FuY2lhIGVudHJlIGxhcyB2YXJpYWJsZXMgZGUgYcOxbyB5IHByb2R1Y2Npw7NuIHBhcmEgbnVlc3RyYSBkZXBlbmRpZW50ZS4gRWwgYcOxbyBzaWVuZG8gbmVnYXRpdmEgeSBsYSBwcm9kdWNjacOzbiBwb3NpdGl2YSBlbiBlbCBpbXBhY3RvIHF1ZSBkZWphLiANCg0KRWwgbW9kZWxvIGFudGVyaW9yIG5vcyBtdWVzdHJhIGN1w6FudG8gc2UgZXN0aW1hIHF1ZSBzZSBwcm9kdWNpcsOhIGEgbml2ZWwgZ2xvYmFsIGVuIGxhIGluZHVzdHJpYSBkZWwgY2FydMOzbiBwYXJhIDIwMjIuIERlIGFjdWVyZG8gYSB1bmEgcHJvZHVjY2nDs24gdG90YWwgYXByb3hpbWFkYSBkZSAxNzAgbWlsbG9uZXMgZGUgY2FydMOzbiBlbiAyMDIxLCBzZSBlc3BlcmEgcXVlIGVuIDIwMjIgc2UgcHJvZHV6Y2FuIDkxNCwxOTYsOTI2LiBFbiBlc3RlIGNhc28sIGVsIHByw7Nub3N0aWNvIGZ1ZSByZWFsaXphZG8gYWwgY3JlYXIgdW4gbnVldm8gJ2RhdGEgZnJhbWUnIHkgYWwgaW1wbGVtZW50YXIgbGEgZnVuY2nDs24gZGUgJ2xtJywgdXNhZGEgcGFyYSBjcmVhciBhbsOhbGlzaXMgcmVncmVzaXZvcyB5IHByZWRpY3Rpdm9zLiANCg0KDQoNCiMjIyMgTW9kZWxvcyBkZSByZWdyZXNpw7NuIGxpbmVhbCBtw7psdGlwbGU6IFByb2R1Y2Npw7NuIGRlIGNhcnTDs24gZW4gMjAyMiBwYXJhIEVzdGFkb3MgVW5pZG9zIHkgTcOpeGljbw0KDQojIyMgSW1wb3J0YXIgYmFzZSBkZSBkYXRvcyAoMykNCmBgYHtyIHdhcm5pbmc9RkFMU0V9DQpiZDYgPC1yZWFkLmNzdigiQzpcXFVzZXJzXFxkYW55Y1xcRG93bmxvYWRzXFxleHRlcm5hX2JkMyBjc3YzICgxKS5jc3YiKQ0Kc3VtbWFyeShiZDYpDQoNCnN1bShpcy5uYShiZDYpKQ0KDQpzdW1tYXJ5KGJkNikNCnN0cihiZDYpDQpgYGANCg0KDQojIyMgTW9kZWxvIGRlIHJlZ3Jlc2nDs24gbcO6bHRpcGxlOiBQcm9kdWNjacOzbiBkZSBjYXJ0w7NuIGVuIDIwMjI6IE3DqXhpY28gDQoNCiBMYSBwcmVkaWNjacOzbiBhbnRlcmlvciBub3MgYXJyb2phIHF1ZSBoYXkgdW4gaW1wYWN0byBwb3NpdGl2byB5IHNpZ25pZmljYXRpdm8gZW50cmUgbGEgdmFyaWFibGUgQcOxbyB5IGxhIHZhcmlhYmxlIGRlcGVuZGllbnRlLiBFc3RvIHNpZ25pZmljYSBxdWUgaGF5IHVuYSBwcmVkaWNjacOzbiBwb3NpdGl2YSBkZSBjcmVjaW1pZW50byBhY29yZGUgYWwgYcOxby4NCiBEZSBhY3VlcmRvIGEgbGEgcHJvZHVjY2nDs24gdG90YWwgZ2VuZXJhZGEgcG9yIE3DqXhpY28gZGUgMjAxNiBhIDIwMjEgKDc0MCBNKSwgZWwgbW9kZWxvIHByb27Ds3N0aWNvIGVzdGltYSBxdWUgZW4gMjAyMiBwcm9kdWNpcsOhIDE0OSwxNzAuMy4gRW4gbGEgZ3LDoWZpY2EgcHJldmlhIHNlIG11ZXN0cmEgZWwgcHVudG8gZGUgcHJlZGljY2nDs24uIFNpIGFuYWxpemFtb3MgbGEgcHJvZHVjY2nDs24gZGUgMjAyMSBjb250cmEgZWwgcHJvbsOzc3RpY28gZGUgMjAyMiwgc2UgZXN0aW1hIHF1ZSBsYSBwcm9kdWNjacOzbiBtZXhpY2FuYSBkaXNtaW51aXLDoS4gUG9kZW1vcyBzdXBvbmVyIHF1ZSBlc3RvIHNlIGRlYmUgYSBsYSBkZWZpY2llbmNpYSBlbiBsYSBjYWRlbmEgZGUgc3VtaW5pc3RybyBnbG9iYWwsIGFzw60gY29tbyBmYWN0b3JlcyBlY29uw7NtaWNvcyBnbG9iYWxlcy4gDQogDQpgYGB7ciB3YXJuaW5nPUZBTFNFfQ0KcmVncmVzaW9uMyA8LSBsbShNRVggfiBVU0EgKyBBw7FvLCBkYXRhPWJkNikNCnN1bW1hcnkocmVncmVzaW9uMykNCg0KcmVncmVzaW9uMyA8LSBsbShNRVggfiBBw7FvLCBkYXRhPWJkNikNCnN1bW1hcnkocmVncmVzaW9uMykNCg0KYmQ2IDwtIGRhdGEuZnJhbWUoQcOxbz0yMDIyLCBQcm9kdWNjaW9uPSA3NDAwMDApDQpwcmVkaWN0KHJlZ3Jlc2lvbjMsYmQ2KQ0KDQpnZ3Bsb3QoYmQ2LCBhZXMoeD1Bw7FvLCB5PVByb2R1Y2Npb24pKSsNCiAgZ2VvbV9wb2ludCgpICsNCiAgZ2VvbV9saW5lKGFlcyh5PVByb2R1Y2Npb24pLCBjb2xvcj0icmVkIiwgbGluZXR5cGU9ImRhc2hlZCIpICsNCiAgZ2VvbV9saW5lKGFlcyh5PVByb2R1Y2Npb24pLCBjb2xvcj0icmVkIiwgbGluZXR5cGU9ImRhc2hlZCIpICsNCiAgZ2VvbV9zbW9vdGgobWV0aG9kPWxtLCBmb3JtdWxhPXl+eCwgc2U9VFJVRSwgbGV2ZWw9MC45NSwgY29sPSdibHVlJywgZmlsbD0ncGluazInKSArDQogIHRoZW1lX2xpZ2h0KCkNCmBgYA0KDQoNCg0KDQojIyMjIE1vZGVsb3MgZGUgcmVncmVzacOzbiBsaW5lYWwgbcO6bHRpcGxlOiBQcm9kdWNjacOzbiBkZSBjYXJ0w7NuIGVuIDIwMjIgcGFyYSBFc3RhZG9zIFVuaWRvcyB5IE3DqXhpY28gDQoNCiMjIyBJbXBvcnRhciBiYXNlIGRlIGRhdG9zICgzKSANCmBgYHtyfQ0KYmQ2IDwtcmVhZC5jc3YoIkM6XFxVc2Vyc1xcZGFueWNcXERvd25sb2Fkc1xcZXh0ZXJuYV9iZDMgY3N2MyAoMSkuY3N2IikNCnN1bW1hcnkoYmQ2KQ0KDQpzdW0oaXMubmEoYmQ2KSkNCg0Kc3VtbWFyeShiZDYpDQpzdHIoYmQ2KQ0KYGBgDQoNCg0KDQojIyMjIE1vZGVsb3MgZGUgcmVncmVzacOzbiBsaW5lYWwgbcO6bHRpcGxlOiBQcm9kdWNjacOzbiBkZSBjYXJ0w7NuIGVuIDIwMjI6IEVzdGFkb3MgVW5pZG9zDQpQYXJhIGxhIHByZWRpY2Npw7NuIGRlIEVzdGFkb3MgVW5pZG9zLCB2ZW1vcyBxdWUgaGFicsOhIHVuIGluY3JlbWVudG8gZW4gbGEgcHJvZHVjY2nDs24gZGUgY2FydMOzbiBjb250cmEgMjAyMS4gU2luIGVtYmFyZ28sIGFsIGFuYWxpemFyIGxhIHByb2R1Y2Npw7NuIHRvdGFsIGRlIE3DqXhpY28gY29udHJhIGxhIHByb2R1Y2Npw7NuIHRvdGFsIGRlIEVzdGFkb3MgVW5pZG9zLCB2ZW1vcyBxdWUgbGEgbWV4aWNhbmEgZXMgbXVjaG8gbWF5b3IuIFBvZGVtb3Mgc3Vwb25lciBxdWUgZXN0byBzZSBkZWJlIGRlYmlkbyBhIGxhIG1hbm8gZGUgb2JyYSBlY29uw7NtaWNhIGRlbCBtZXJjYWRvIG1leGljYW5vLiANCg0KRGUgYWN1ZXJkbyBhIGxhIHByZWRpY2Npw7NuIGFudGVyaW9yLCBzZSB2ZSB1biBpbmNyZW1lbnRvIHBvc2l0aXZvIHBhcmEgbGEgdmFyaWFibGUgTcOpeGljbyBjb24gbGEgdmFyaWFibGUgZGVwZW5kaWVudGUsIGEgZGlmZXJlbmNpYSBkZWwgYcOxbyBxdWUgbXVlc3RyYSB1biBpbXBhY3RvIG1lbm9yIHkgbmVnYXRpdm8sIHBlcm8gaWd1YWxtZW50ZSBzaWduaWZpY2F0aXZvLiANCg0KYGBge3J9DQpyZWdyZXNpb24yIDwtIGxtKFVTQSB+IE1FWCArIEHDsW8sIGRhdGE9YmQ2KQ0Kc3VtbWFyeShyZWdyZXNpb24yKQ0KDQpyZWdyZXNpb24yIDwtIGxtKFVTQSB+IEHDsW8sIGRhdGE9YmQ2KQ0Kc3VtbWFyeShyZWdyZXNpb24yKQ0KDQpiZDYgPC0gZGF0YS5mcmFtZShBw7FvPTIwMjIsIFByb2R1Y2Npb249IDMyMDAwMCkNCnByZWRpY3QocmVncmVzaW9uMixiZDYpDQpgYGANCg0KDQoNCiMgPHNwYW4gc3R5bGUgPSAiY29sb3I6ZGFya29yYW5nZSI+IFByb27Ds3N0aWNvIA0KDQpgYGB7cn0NCiNpbnN0YWxsLnBhY2thZ2VzKCJmb3JlY2FzdCIpDQpsaWJyYXJ5KGZvcmVjYXN0KQ0KYGBgDQoNCg0KIyMjIFByb25vc3RpY2FyIGVsIGRlc2VtcGXDsW8gZGUgbGEgaW5kdXN0cmlhIGF1dG9tb3RyaXogKEVVQSB5IE1FWCkgcGFyYSBsb3MgMyBwZXJpb2RvcyBkZSB0aWVtcG8uDQpgYGB7cn0NCiNmaWxlLmNob29zZSgpDQpleHRlcm5vPC0gcmVhZC5jc3YoIkM6XFxVc2Vyc1xcZGFueWNcXERvd25sb2Fkc1xcZXh0ZXJuYV9iZDMgY3N2My5jc3YiKQ0KYGBgDQoNCiMjIyBDcmVhciBzZXJpZSBkZSB0aWVtcG8NCmBgYHtyfQ0KcHJvZHVjY2lvbl9tZXhpY288LSBjKGV4dGVybm8kTUVYKQ0KcHJvZHVjY2lvbl91c2E8LSBjKGV4dGVybm8kVVNBKQ0KYGBgDQoNCmBgYHtyfQ0KcHJvZHVjY2lvbm08LXRzKGRhdGE9cHJvZHVjY2lvbl9tZXhpY28sIHN0YXJ0PWMoMjAxNiwxKSwgZnJlcXVlbmN5PTEpDQpwcm9kdWNjaW9udTwtdHMoZGF0YT1wcm9kdWNjaW9uX3VzYSwgc3RhcnQ9YygyMDE2LDEpLCBmcmVxdWVuY3k9MSkNCnByb2R1Y2Npb25tDQpwcm9kdWNjaW9udQ0KYGBgDQoNCg0KYGBge3J9DQptb2RlbG9tPC0gYXV0by5hcmltYShwcm9kdWNjaW9ubSwgRD0xKQ0KbW9kZWxvdTwtIGF1dG8uYXJpbWEocHJvZHVjY2lvbnUsIEQ9MSkNCm1vZGVsb20NCm1vZGVsb3UNCmBgYA0KDQpgYGB7cn0NCnByb25vc3RpY29tIDwtIGZvcmVjYXN0KG1vZGVsb20sIGxldmVsPWMoOTUpLCBoPTQpDQpwcm9ub3N0aWNvbQ0KcGxvdChwcm9ub3N0aWNvbSkNCmBgYA0KDQpgYGB7cn0NCnByb25vc3RpY291IDwtIGZvcmVjYXN0KG1vZGVsb3UsIGxldmVsPWMoOTUpLCBoPTQpDQpwcm9ub3N0aWNvdQ0KcGxvdChwcm9ub3N0aWNvdSkNCmBgYA0KDQojIyMgUHJvbm9zdGljYXIgZWwgZGVzZW1wZcOxbyBkZSBwcm9kdWNjaW9uIGRlIEZvcm0gcGFyYSBsb3MgcHJveGltb3MgMyBwZXJpb2RvcyBkZSB0aWVtcG8uDQoNCmBgYHtyfQ0KI2ZpbGUuY2hvb3NlKCkNCmZvcm1wcm9kdWNjaW9uPC0gcmVhZC5jc3YoIkM6XFxVc2Vyc1xcZGFueWNcXE9uZURyaXZlIC0gSW5zdGl0dXRvIFRlY25vbG9naWNvIHkgZGUgRXN0dWRpb3MgU3VwZXJpb3JlcyBkZSBNb250ZXJyZXlcXERlc2t0b3BcXEZvcm1fcHJvZHVjY2lvbmJhc2VsaW1waWEuY3N2IikNCmBgYA0KIyMjIENyZWFyIHNlcmllIGRlIHRpZW1wbw0KYGBge3J9DQpwcm9kdWNjaW9uZm9ybTwtIGMoZm9ybXByb2R1Y2Npb24kbGFtaW5hc19wcm9jZXNhZGFzKQ0KDQpgYGANCg0KYGBge3J9DQpwcm9kdWNjaW9uZjwtdHMoZGF0YT1wcm9kdWNjaW9uZm9ybSwgc3RhcnQ9YygyMDIyLDcpLCBlbmQ9YygyMDI1LCAxMiksIGZyZXF1ZW5jeT0xMikNCg0KcHJvZHVjY2lvbmYNCmBgYA0KDQoNCmBgYHtyfQ0KbW9kZWxvZjwtIGF1dG8uYXJpbWEocHJvZHVjY2lvbmYsIEQ9MSkNCg0KbW9kZWxvZg0KDQpgYGANCg0KYGBge3J9DQpwcm9ub3N0aWNvZiA8LSBmb3JlY2FzdChtb2RlbG9mLCBsZXZlbD1jKDk1KSwgaD0zKQ0KcHJvbm9zdGljb2YNCnBsb3QocHJvbm9zdGljb2YpDQpgYGANCg0KDQojIyMgUHJvbm9zdGljbyAyIEZPUk0gQmFqYXMNCg0KYGBge3J9DQojZmlsZS5jaG9vc2UoKQ0KZm9ybWJhamFzPC0gcmVhZC5jc3YoIkM6XFxVc2Vyc1xcZGFueWNcXERvd25sb2Fkc1xcSFJfQmFqYXMgMi5jc3YiKQ0KYGBgDQoNCg0KIyMjIENyZWFyIHNlcmllIGRlIHRpZW1wbw0KYGBge3J9DQpiYWphc2Zvcm08LSBjKGZvcm1iYWphcyROTy5ERS5CQUpBUykNCg0KYGBgDQoNCmBgYHtyfQ0KYmFqYXNmPC10cyhkYXRhPWJhamFzZm9ybSwgc3RhcnQ9YygyMDIyLDcpLCBlbmQ9YygyMDI1LCAxMiksIGZyZXF1ZW5jeT0xMikNCg0KYmFqYXNmDQpgYGANCg0KYGBge3J9DQpibW9kZWxvZjwtIGF1dG8uYXJpbWEoYmFqYXNmLCBEPTEpDQoNCmJtb2RlbG9mDQoNCmBgYA0KYGBge3J9DQpwcm9uYmFqYSA8LSBmb3JlY2FzdChibW9kZWxvZiwgbGV2ZWw9Yyg5NSksIGg9MykNCnByb25iYWphDQpwbG90KHByb25iYWphKQ0KYGBgDQoNCiMjIyBEZXNjcmliZSBsb3MgcmVzdWx0YWRvcyANClJlYWxpemFtb3MgdW5hIHNlcmllIGRlIHRpZW1wbyB0YW50byBwYXJhIGxhIGJhc2UgZGUgbGEgaW5kdXN0cmlhIGF1dG9tb3RyaXogY29tbyBwYXJhIGxhIGJhc2UgZGUgcHJvZHVjY2nDs24gZGUgRk9STSwgZXN0ZSBlcyBlbmZvY2FkbyBhIGxhcyBsYW1pbmFzIHByb2Nlc2FkYXMgY2FkYSBtZXMgeSBlbiBsYSBpbmR1c3RyaWEgZXMgcG9yIGHDsW8uIFBhcmEgcG9kZXIgcmVhbGl6YXIgZXN0ZSBBbmFsaXNpcyBkZSBSZXN1bHRhZG8gcmVhbGl6YW1vcyB1bmEgZ3JhZmljYSB5IHVuIG1vZGVsbyBkZSBQcmVkaWNjacOzbiBwb3IgbWVkaW8gZGUgbGEgZnVuY2nDs24gYXV0by5hcmltYS4gR3JhY2lhcyBhIGVzdGEgZnVuY2nDs24sIGxlIGVzcGVjaWZpY2Ftb3MgZGVzZGUgcXVlIEZlY2hhIGVtcGV6YXLDoSBhIG9idGVuZXIgZGF0b3MgZGUgbGEgYmFzZSBkZSBEYXRvcyB5IHRhbWJpw6luIGNvbG9jYW1vcyBsYSBmcmVjdWVuY2lhLCBxdWUgc2UgcmVmaWVyZSBhIGPDs21vIHNlIGNvbXBvcnRhLCBlbiBjdWVzdGnDs24gYSBzaSBzZSB2YSBhIGNhbGN1bGFyIHBvciBtZXMgbyBwb3IgYcOxby4gQXPDrSBtaXNtbywgb2J0dXZpbW9zIHBhcmEgbGEgaW5kdXN0cmlhIHRhbnRvIGVuIE3DqXhpY28gY29tbyBlbiBFVSwgcXVlIHNvbiBsb3MgcGHDrXNlcyBlbiBsb3MgcXVlIHNlIGVuZm9jYSBtw6FzIEZPUk0geSBvYnRlbmdhbiBtZWpvciBvcG9ydHVuaWRhZCBkZSBjcmVjaW1pZW50by4gQWwgcmVhbGl6YXIgZXN0ZSBtb2RlbG8gY2FsY3VsYW1vcyBwYXJhIGxvcyBwcsOzeGltb3MgMyBwZXJpb2RvcywgZW4gZXN0ZSBjYXNvIHBhcmEgZWwgMjAyNSB5IG9idHV2aW1vcyBsb3Mgc2lndWllbnRlcyByZXN1bHRhZG9zOg0KLSAqSW5kdXN0cmlhIEF1dG9tb3RyaXogZW4gTcOpeGljbyo6IA0KDQogIDEuIFBhcnRpZW5kbyBkZSB1biBtYXJnZW4gZGVsIDk1JSwgcXVlcmllbmRvIGRlY2lyLCBxdWUgZXN0ZSBtb2RlbG8gZXMgbcOhcyBwcmVjaXNvIHBvciBsbyBxdWUgYWwgdmVyIGxhIGdyYWZpY2Egb2J0ZW5lbW9zICAgICAgcXVlIHRlbmRyw6EgdW4gaW5jcmVtZW50byBjb25zdGFudGUgZW4gbG9zIHByw7N4aW1vcyAzIGHDsW9zLCBwYXJ0aWVuZG8gZGVsIDIwMjIuIA0KICAyLiBFc3RlIGNyZWNpbWllbnRvIGRlIGxhIGluZHVzdHJpYSBhdXRvbW90cml6IGVuIE3DqXhpY28gc2UgZXN0aW1hIHVuIGNyZWNpbWllbnRvIGRlbCAxNiUgcGFyYSAyMDI1LCBsbyBxdWUgYmVuZWZpY2lhIGEgICAgICBGT1JNIHBhcmEgY29udGludWFyIHByb2R1Y2llbmRvIGVuIGVsIG1lcmNhZG8gTWV4aWNhbm8uIA0KDQotICpJbmR1c3RyaWEgQXV0b21vdHJpeiBlbiBFc3RhZG9zIFVuaWRvcyo6IA0KDQogIDEuIFBhcmEgMjAyMiBlbCBwcm9ub3N0aWNvIGVzIGRlIDU5IG1pbCwgcXVlIGVzdGUgc2UgcHVlZGUgbWFudGVuZXIgY29uc3RhbnRlIGVuIGxvcyBwcsOzeGltb3MgMyBhw7FvcyBoYXN0YSAyMDI1DQogIDIuIFNlIG9idGllbmUgdW4gZXNjZW5hcmlvIG9wdGltaXN0YSBjb24gbGEgcHJlY2lzacOzbiBkZWwgOTUlLCBsbyBxdWUgcXVpZXJlIGRlY2lyIHF1ZSBwYXJhIGZpbmFsZXMgZGVsIDIwMjUsIHB1ZWRlIGVzdGFyIGlndWFsIGVuIDU5IG1pbCBvIGF1bWVudGFyIGhhc3RhIGxvcyA2OSBtaWwuIEVzdG8gaW5kaWNhcsOtYSBxdWUgdmEgZW4gYXVtZW50byBhw7FvIGNvbiBhw7FvIHkgdGVybWluYXLDrWEgZWwgMjAyNSBjb24gdW4gYXVtZW50byBkZWwgY2FzaSAyMCUuIExvIHF1ZSBpbmRpY2Fyw61hIGFsZ28gYnVlbm8gcGFyYSBGT1JNLCBkYW5kb2xlIG9wb3J0dW5pZGFkIGEgYXVtZW50YXIgc3UgY2FydGVyYSBkZSBjbGllbnRlcyBkZW50cm8gZGVsIG1lcmNhZG8gRXN0YWRvdW5pZGVuc2UgeSB0ZW5pZW5kbyB1biBidWVuIGltcGFjdG8gZGUgbGEgaW5kdXN0cmlhIHBhcmEgbG9zIHByw7N4aW1vcyBwZXJpb2Rvcy4gDQogIA0KLSAqRW1wcmVzYSBGT1JNKjoNCg0KICAxLiBTZSBoaXpvIGVsIHByb25vc3RpY28gcG9yIG1lcyB5IGRhbmRvIHVuIHBlcmlvZG8gaGFzdGEgZWwgMjAyNiwgcGFydGllbmRvIGRlbCAyMDIyIGNvbiAzIGVuIGN1YW50byBhIHByb2R1Y2Npw7NuIGRlIGxhbWluYXMgcHJvY2VzYWRhcywgc2UgZXN0aW1hIHF1ZSBlc3RlIHRlbmdhIHVuIGF1bWVudG8gY29uc3RhbnRlLCBhZGVtYXMgZGUgcXVlIGVudHJlIGVsIDIwMjQgeSAyMDI1IHRlbmdhIHVuIHB1bnRvIGRlIHBpcXVlIG3DoXMgYWx0bywgcXVlIHBvc3Rlcmlvcm1lbnRlIHZvbHZlcsOhIGEgZXN0YWJpbGl6YXJzZSBwZXJvIHF1ZSBzZSBtYW50ZW5kcsOhIGNvbnN0YW50ZSBlbnRyZSBsb3MgMTAgYSAyMCBlbiBwcm9kdWNjacOzbi4gDQogIDIuIFNlIHByb25vc3RpY2EgcXVlIHBhcmEgZWwgMjAyNiBzZSB0ZW5nYSB1biAzMyBlbiBwcm9kdWNjacOzbiBkZWwgw6FyZWEgZGUgbGFtaW5hcyBwcm9jZXNhZGFzLCB0ZW5pZW5kbyB1bmEgcHJlY2lzacOzbiBkZWwgOTUlIGVuIHVuIGVzY2VuYXJpbyBvcHRpbWlzdGEuIEFzw60gbWlzbW8gZXN0ZSBzZSBwdWVkZSBtYW50ZW5lciBjb25zdGFudGUgZW4gMTAgbyBhdW1lbnRhciBjb21vIHNlIGNvbWVudMOzIGFudGVyaW9ybWVudGUgeSBlc3RlIGNyZWNpbWllbnRvIGEgdMOpcm1pbm9zIGRlbCAyMDI2IHRvbWFuZG8gZWwgZXNjZW5hcmlvIG9wdGltaXN0YSwgc2Vyw61hIGRlIHBvY28gbWFzIGRlbCA5MCUgbG8gcXVlIHNlcsOtYSB1biBncmFuIGF1bWVudG8gcGFyYSBGT1JNLiBUYW1iacOpbiBzaSBmdWVyYSBzaW4gZWwgOTUlIHBhcmEgaW5pY2lvcyBkZWwgMjAyNiBzZXLDrWFuIDE2IGVuIHByb2R1Y2Npw7NuIGNvbiBlbCA2MCUgZGUgYXVtZW50bywgbG8gcXVlIHNlZ3VpcsOtYSBzaWVuZG8gYWxnbyBpbXBvcnRhbnRlIHBhcmEgRk9STS4gDQozLiAgU2UgcHJvbm9zdGljYSBzZWfDum4gZWwgbW9kZWxvIHJlYWxpemFkbyBxdWUgbGFzIGJhamFzIGRlIGZvcm0gaXLDoXMgaW5jcmVtZW50YW5kbyBjYWRhIHZleiBtw6FzIGVuIGxvcyBwcsOzeGltb3MgMyBhw7FvcywgbG9ncmFuZG8gYXPDrSB1bmEgdGFzYSBkZSByb3RhY2nDs24gbcOhcyBhbHRhIGRlIGxhIHF1ZSBlc3TDoW4gY29uc2lkZXJhbmRvIGhveSBlbiBkw61hLCBlcyBwb3IgZXNvIHF1ZSBzZSBuZWNlc2l0YXLDrWFuIGhhY2VyIHVub3MgY2FtYmlvcyBwcmV2ZW50aXZvcyBwYXJhIHBvZGVyIGV2aXRhciBlc2UgdGlwbyBkZSB0cmFnZWRpYSBxdWUgaGFyw61hbiBxdWUgRk9STSBwaWVyZGEgZGluZXJvIGFsIHRlbmVyIHF1ZSBpbmN1cnJpciBlbiB1bmEgY2FwYWNpdGFjacOzbiBkZXNkZSBjZXJvIGVuIGx1Z2FyIGRlIGN1aWRhciBhIHN1IHBlcnNvbmFsIGFjdHVhbC4NCg0KDQojIDxzcGFuIHN0eWxlID0gImNvbG9yOmRhcmtvcmFuZ2UiPiBLLU1lYW5zDQoNCg0KIyMjICoqQ2x1c3RlciAxKiogDQoNCg0KDQpgYGB7ciwgaW5jbHVkZT1GQUxTRX0NCmxpYnJhcnkoZm9yZWlnbikNCmxpYnJhcnkoZHBseXIpICAgICAgICAjIGRhdGEgbWFuaXB1bGF0aW9uIA0KbGlicmFyeShnZ3Bsb3QyKSAgICAgICMgZGF0YSB2aXN1YWxpemF0aW9uIA0KbGlicmFyeShwc3ljaCkgICAgICAgICMgZnVuY3Rpb25zIGZvciBtdWx0aXZhcmlhdGUgYW5hbHlzaXMgDQpsaWJyYXJ5KGNvcnJwbG90KSAgICAgIyBjb3JyZWxhdGlvbiBwbG90cw0KbGlicmFyeShqdG9vbHMpICAgICAgICMgcHJlc2VudGF0aW9uIG9mIHJlZ3Jlc3Npb24gYW5hbHlzaXMgDQpsaWJyYXJ5KGxtdGVzdCkgICAgICAgIyBkaWFnbm9zdGljIGNoZWNrcyAtIGxpbmVhciByZWdyZXNzaW9uIGFuYWx5c2lzIA0KbGlicmFyeShjYXIpICAgICAgICAgICMgZGlhZ25vc3RpYyBjaGVja3MgLSBsaW5lYXIgcmVncmVzc2lvbiBhbmFseXNpcw0KbGlicmFyeShmYWN0b2V4dHJhKSAgICMgcHJvdmlkZXMgZnVuY3Rpb25zIHRvIGV4dHJhY3QgYW5kIHZpc3VhbGl6ZSB0aGUgb3V0cHV0IG9mIGV4cGxvcmF0b3J5IG11bHRpdmFyaWF0ZSBkYXRhIGFuYWx5c2VzDQpsaWJyYXJ5KGdnZm9ydGlmeSkgICAgIyBkYXRhIHZpc3VhbGl6YXRpb24gdG9vbHMgZm9yIHN0YXRpc3RpY2FsIGFuYWx5c2lzIHJlc3VsdHMNCmBgYA0KDQoNCiMjIyMgTGltcGllemEgZGUgZGF0b3MgeSB0cmFuc2Zvcm1hY2lvbiANCg0KIyMjIyBJbXBvcnRhciBCYXNlIGRlIERhdG9zICANCmZpbGUuY2hvb3NlKCkNCmBgYHtyLCBpbmNsdWRlPUZBTFNFfQ0Kcmg8LXJlYWQuY3N2KCJDOlxcVXNlcnNcXGRhbnljXFxEb3dubG9hZHNcXEhSX0JhamFzIDIuY3N2IikgDQpzdW1tYXJ5KHJoKQ0Kc3RyKHJoKQ0KYGBgDQoNCiMjIyMgRXhwbG9yYXIgZGF0b3MgDQoNCmBgYHtyfQ0KcmgxPC1yaCAlPiUgZHBseXI6OiBzZWxlY3QoRURBRCxESUFTLlRSQUJBSkFET1MsU0FMQVJJTy5ESUFSSU8uSU1TUyxHRU5FUk8pDQpzdW1tYXJ5KHJoMSkNCmBgYA0KDQoNCiMjIyMgTm9ybWFsaXphciBsb3MgZGF0b3MgDQpgYGB7cn0NCnJoMV9ub3JtPC1zY2FsZShyaDFbMjozXSkgDQpgYGANCg0KDQojIyMjIE51bWVybyBPcHRpbW8gZGUgQ2x1c3RlcnMgDQoNCmBgYHtyfQ0KDQpmdml6X25iY2x1c3QocmgxX25vcm0sIGttZWFucywgbWV0aG9kPSJ3c3MiKSsgIyB3c3MgbWV0aG9kIGNvbnNpZGVycyB0b3RhbCB3aXRoaW4gc3VtIG9mIHNxdWFyZQ0KICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQ9NCwgbGluZXR5cGU9MikrICAgICAgICAgICAjIG9wdGltYWwgbnVtYmVyIG9mIGNsdXN0ZXJzIGlzIGNvbXB1dGVkIHdpdGggdGhlIGRlZmF1bHQgbWV0aG9kID0gImV1Y2xpZGVhbiINCiAgbGFicyhzdWJ0aXRsZSA9ICJFbGJvdyBtZXRob2QiKSAgDQojZmlsZS5jaG9vc2UoKQ0KYGBgDQoNCiMjIyMgVmlzdWFsaXphciBsYSBpbmZvIGRlIGNsdXN0ZXJzIA0KDQpgYGB7cn0NCnJoMV9jbHVzdGVyPC1rbWVhbnMocmgxX25vcm0sNCkNCnJoMV9jbHVzdGVyDQpgYGANCg0KDQpNdWVzdHJhIHF1ZSB1dGlsaWNlbW9zIDQgY2x1c3RlcnMgcGFyYSBhbmFsaXphciB5IHZpc3VhbGl6YXIgbGEgaW5mb3JtYWNpw7NuLiANCg0KIyMjIyBWaXN1YWxpemFyIFJlc3VsdGFkb3MgDQoNCmBgYHtyfQ0KZnZpel9jbHVzdGVyKHJoMV9jbHVzdGVyLGRhdGE9cmgxX25vcm0pDQpgYGANCg0KRWwgcHJpbWVyIGNsdXN0ZXIgYW5hbGl6YSBsYSByZWxhY2nDs24gZW50cmUgZWwgc2FsYXJpbyBkaWFyaW8gSU1TUyB5IGxvcyBkw61hcyB0cmFiYWphZG9zIGRlIGxvcyBlbXBsZWFkb3MgcXVlIHlhIGZ1ZXJvbiBkYWRvcyBkZSBiYWphLiBFbiBlc3RlIGNhc28sIHZlbW9zIHF1ZSBoYXkgdW4gaW1wYWN0byBhbHRvIGVudHJlIGFxdWVsbG9zIGVtcGxlYWRvcyBxdWUgdHJhYmFqYXJvbiBkZSAyIGEgOCBkw61hcywgcGVybyB0dXZpZXJvbiB1biBzYWxhcmlvIGRpYXJpbyBiYWpvLCBtdWNobyBtZW5vciBhIDAgZW4gbGEgZ3LDoWZpY2EuIExvcyBvdHJvcyBkb3MgcmVzdWx0YWRvcywgc2UgbXVlc3RyYSBxdWUgdHJhYmFqYXJvbiBtZW5vcyBkw61hcywgcGVybyBhbCBpZ3VhbCBxdWUgZWwgcHJpbWVyIGNsdXN0ZXIgZXhwbGljYWRvLCB0dXZpZXJvbiB1biBzYWxhcmlvIG11eSBiYWpvLiBDb24gZXN0b3MgdHJlcywgaGF5IHVuYSBjb3JyZWxhY2nDs24gYWx0YSwgc2lnbmlmaWNhdGl2YSB5IG5lZ2F0aXZhLiBQYXJhIGVsIGdydXBvIGRlIGFycmliYSwgdmVtb3MgcXVlIGVzdG9zIHRyYWJhamFyb24gdW4gcHJvbWVkaW8gZGUgMi0zIGTDrWFzIHkgdHV2aWVyb24gdW4gc2FsYXJpbyBkaWFyaW8gbXV5IGFsdG8uIFBvZGVtb3MgaW5mZXJpciBxdWUgZXN0ZSBncnVwbyBwZXJ0ZW5lY2UgYWwgw6FyZWEgYWRtaW5pc3RyYXRpdmEsIHF1ZSBjb21vIHZpbW9zIGVuIGFuw6FsaXNpcyBhbnRlcmlvcmVzLCBzb24gZWwgZ3J1cG8gY29uIHVuIHNhbGFyaW8gbXVjaG8gbcOhcyBhbHRvIGFsIHJlc3RvLg0KDQogDQpgYGB7cn0NCnJoMjwtcmgxDQpyaDIkQ2x1c3RlcnM8LXJoMV9jbHVzdGVyJGNsdXN0ZXINCnN1bW1hcnkocmgyKQ0KYGBgDQoNCg0KIyMjIyBDcmVhciB1biBkYXRhc2V0IA0KDQpgYGB7cn0NCnJoMzwtcmgyICU+JSBncm91cF9ieShDbHVzdGVycykgJT4lIHN1bW1hcmlzZShTQUxBUklPLkRJQVJJTy5JTVNTPW1heChTQUxBUklPLkRJQVJJTy5JTVNTKSwgRElBUy5UUkFCQUpBRE9TPW1lYW4oRElBUy5UUkFCQUpBRE9TKSkgJT4lIGFycmFuZ2UoZGVzYyhTQUxBUklPLkRJQVJJTy5JTVNTKSkNCnN1bW1hcnkocmgzKQ0KYGBgDQoNCg0KIyMjIyBBZ3J1cGFyIGNsdXN0ZXJzIHBvciBub21icmUgDQoNCmBgYHtyfQ0KcmgyJENsdXN0ZXJfTmFtZXM8LWZhY3RvcihyaDIkQ2x1c3RlcnMsbGV2ZWxzID0gYygxLDIsMyw0KSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHM9YygiQmFqbyIsICJQcm9tZWRpbyAiLCAiQXJyaWJhIGRlbCBwcm9tIiwgIkFsdG8iKSkNCnN1bW1hcnkocmgyKQ0KYGBgDQoNCg0KTXVjaG9zIGTDrWFzIHRyYWJhamFkb3MgeSBwb2NvIHNhbGFyaW8NCg0KIyMjIyBBZ3J1cGFyIHkgZGFyIHJlc3VtZW4gcG9yIG5vbWJyZXMgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICANCmBgYHtyfQ0Kcmg0IDwtIHJoMiU+JSBncm91cF9ieSAoQ2x1c3Rlcl9OYW1lcywgR0VORVJPKSAlPiUgZHBseXI6OiBzdW1tYXJpemUoRElBUy5UUkFCQUpBRE9TPW1heChESUFTLlRSQUJBSkFET1MpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU0FMQVJJTy5ESUFSSU8uSU1TUyA9bWVhbihTQUxBUklPLkRJQVJJTy5JTVNTKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb3VudD1uKCkpDQoNCg0KYGBgDQoNCiMjIyMgRGFyIGZvcm1hdG8gZGUgdGFibGEgcGFyYSBlbnNlw7FhciBsYSBpbmZvcm1hY2lvbiBkZSBsb3MgY2x1c3RlcnMgDQoNCmBgYHtyfQ0KY2x1c3RlcnM8LWFzLmRhdGEuZnJhbWUocmg0KQ0KY2x1c3RlcnMNCmBgYA0KDQoNCiMjIyMgR3JhZmljYXIgZWwgbm8uIGRlIGRhdG9zIG9ic2VydmFkb3MgcG9yIG5vbWJyZSBkZSBjbHVzdGVycyAgDQoNCmBgYHtyfQ0KZ2dwbG90KHJoNCxhZXMoeD1yZW9yZGVyKENsdXN0ZXJfTmFtZXMsQ291bnQpLHk9Q291bnQsZmlsbD1DbHVzdGVyX05hbWVzKSkgKw0KICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIpDQpgYGANCg0KDQogRGUgYWN1ZXJkbyBhIGxhIGNsYXNpZmljYWNpw7NuIGRlIGNsdXN0ZXJzLCBsYSBncsOhZmljYSBhbnRlcmlvciBub3MgbXVlc3RyYSBlbCBpbXBhY3RvIHkgY29udGVvIGRlIGNhZGEgY2x1c3RlciBkZXBlbmRpZW5kbyBkZWwgZ3J1cG8gZGUgYmFqYSBhbmFsaXphZG8sIGVzIGRlY2lyLCB2ZW1vcyBsYSByZWxhY2nDs24gZW50cmUgZMOtYXMgdHJhYmFqYWRvcyB5IHNhbGFyaW8gZGlhcmlvLCBjbGFzaWZpY2FuZG8gZWwgY29udGVvIGFjb3JkZSBhIGxhIGNhbnRpZGFkIGRlIGJhamFzIG9idGVuaWRhcy4gRW4gZXN0ZSBjYXNvLCBlbiBsYSBncsOhZmljYSBzZSBtdWVzdHJhIHF1ZSBhcXVlbGxvcyBxdWUgdHJhYmFqYXJvbiBtw6FzIGRlIDYwMCBkw61hcyB5IG1lbm9zIGRlIDE5MDAgZMOtYXMsIG9idHV2aWVyb24gdW4gc2FsYXJpbyBwcm9tZWRpbyBkZSAkNTAwIHBlc29zIGRpYXJpby4gRW50cmEgZW4gbGEgY2F0ZWdvcsOtYSBkZSAnYmFqbycsIHlhIHF1ZSBzw7NsbyB1bmEgcGVyc29uYSBvYnR1dm8gZXN0YSBkZXNjcmlwY2nDs24uIEVsIHByb21lZGlvIGRlIGxhcyBwZXJzb25hcyBkYWRhcyBkZSBiYWphIHRyYWJhamFyb24gbcOhcyBkZSAxOTAwIGTDrWFzIHkgb2J0dXZpZXJvbiB1biBzYWxhcmlvIGRpYXJpbyBkZSAkMTcwIHBlc29zLiBFbiBsYSBiYXJyYSBkZSAnYWx0bycgdmVtb3MgYSBhcXVlbGxvcyBleC1lbXBsZWFkb3MgcXVlIHRyYWJhamFyb24gNDIxIGTDrWFzIHkgdHV2aWVyb24gdW4gc2FsYXJpbyBkaWFyaW8gZGUgJDE1MCBwZXNvcy4gUG9yIMO6bHRpbW8sIHZlbW9zIGEgYXF1ZWxsb3MgJ2FycmliYSBkZWwgcHJvbWVkaW8nIHkgc29uIGFxdWVsbG9zIHF1ZSB0YWJhamFyb24gdW4gcHJvbWVkaW8gZGUgNDU1IGTDrWFzIHkgdHV2aWVyb24gdW4gc2FsYXJpbyBkaWFyaW8gZGUgJDE4MCBwZXNvcy4gRXN0ZSDDumx0aW1vIGdydXBvIGVzIGVsIHF1ZSB0dXZvIG1heW9yIGNvbnRlbyBkZSBwZXJzb25hcywgZXMgZGVjaXIsIGxhIG1heW9yw61hIGRlIGxhcyBiYWphcyBlc3R1dmllcm9uIGxhYm9yYW5kbyBtw6FzIGRlIHVuIGHDsW8gZW4gRk9STSB5IHRlbsOtYW4gdW4gc2FsYXJpbyBkaWFyaW8gZGUgJDE4MCBwZXNvcy4NCg0KIyMjIFZlciBSYW5nb3MgDQoNCiMjIyMgUmFuZ28gZGUgIkTDrWFzIHRyYWJhamFkb3MiIHBvciBub21icmUgDQoNCmBgYHtyfQ0KZ2dwbG90KHJoNCwgYWVzKHg9Q2x1c3Rlcl9OYW1lcyx5PURJQVMuVFJBQkFKQURPUyxmaWxsPSBDbHVzdGVyX05hbWVzLGxhYmVsPXJvdW5kKERJQVMuVFJBQkFKQURPUyxkaWdpdHM9MikpKSArIA0KICBnZW9tX2NvbCgpICsgDQogIGdlb21fdGV4dCgpDQoNCmBgYA0KDQoNCiBMYSBncsOhZmljYSBhbnRlcmlvciBub3MgcHJlc2VudGEgbGEgY2FudGlkYWQgZGUgZMOtYXMgdHJhYmFqYWRvcyBkZSBhY3VlcmRvIGEgbGEgY2xhc2lmaWNhY2nDs24gZXhwbGljYWRhIGFudGVyaW9ybWVudGUgZGUgJ2Jham8nLCAncHJvbWVkaW8nLCAnYXJyaWJhIGRlbCBwcm9tZWRpbycgeSAnYWx0bycuIENvbiBlc3RvIGVuIG1lbnRlLCB2ZW1vcyBxdWUgZWwgcHJvbWVkaW8gZGUgbG9zIGVtcGxlYWRvcyBqdW50YXJvbiB1biB0b3RhbCBkZSAxOTY2IGTDrWFzIHRyYWJhamFkb3MsIHNpZ3Vpw6luZG9sZSBlbCBncnVwbyBkZSAnYmFqbycsIGxvcyBxdWUgbGFib3Jhcm9uIHVuIHByb21lZGlvIGRlIDYyOCBkw61hcywgbHVlZ28gJ2FycmliYSBkZWwgcHJvbWVkaW8nIHF1ZSBsYWJvcsOzIDQ1NSBkw61hcyB5IGZpbmFsbWVudGUgJ2FsdG8nLCBxdWUgw7puaWNhbWVudGUgbGFib3LDsyA0MjEgZMOtYXMuIEVuIHRvZG9zIGxvcyBncnVwb3MsIHZlbW9zIHF1ZSBsb3MgZW1wbGVhZG9zIHRyYWJhamFyb24gcG9yIG3DoXMgZGUgMSBhw7FvIGVuIEZPUk0geSBnYW5hYmFuIHVuIHNhbGFyaW8gZGlhcmlvIG1heW9yIGEgJDE1MCBwZXNvcy4NCiANCg0KIyMjIyBWZXIgZWwgcmFuZ28gZGUgU2FsYXJpbyBEaWFyaW8gIA0KYGBge3J9DQpnZ3Bsb3Qocmg0LGFlcyh4PUNsdXN0ZXJfTmFtZXMseT1TQUxBUklPLkRJQVJJTy5JTVNTLGZpbGw9IENsdXN0ZXJfTmFtZXMsbGFiZWw9cm91bmQoU0FMQVJJTy5ESUFSSU8uSU1TUyxkaWdpdHM9MikpKSArIA0KICBnZW9tX2NvbCgpICsgDQogIGdlb21fdGV4dCgpDQpgYGANCg0KDQoNCkxhIGdyw6FmaWNhIGFudGVyaW9yIG5vcyBwcmVzZW50YSBsYSByZWxhY2nDs24gZW50cmUgZWwgc2FsYXJpbyBkaWFyaW8gSU1TUyB5IGxhIGNsYXNpZmljYWNpw7NuIGV4cGxpY2FkYSBhbnRlcmlvcm1lbnRlIGRlICdiYWpvJywgJ3Byb21lZGlvJywgJ2FycmliYSBkZWwgcHJvbWVkaW8nIHkgJ2FsdG8nLiBDb24gZXN0byBlbiBtZW50ZSwgdmVtb3MgcXVlIGVsIHNlZ21lbnRvICdiYWpvJyBlcyBlbCBxdWUgdGVuw61hIHVuIHNhbGFyaW8gbcOhcyBhbHRvIHF1ZSBsYSBtYXlvcsOtYS4gRWwgcHJvbWVkaW8gZ2FuYWJhIHVuIHNhbGFyaW8gZGlhcmlvIGRlICQxNzAsNzkgcGVzb3MsICdhcnJpYmEgZGVsIHByb21lZGlvJyBnYW5hYmEgJDE4MCw1NCBwZXNvcyB5IGVsIHNlZ21lbnRvICdhbHRvJyBnYWJhbmEgdW4gcHJvbWVkaW8gZGUgJDE1MSw2MSBwZXNvcyBkZSBzYWxhcmlvIGRpYXJpby4gRXN0byBkZW5vdGEgdW5hIHZhcmlhYmlsaWRhZCBhbHRhIHkgcG9kZW1vcyBzdXBvbmVyIHF1ZSBlc3RvIHNlIGRlYsOtYSBkZSBhY3VlcmRvIGEgbGFzIHJlc3BvbnNhYmlsaWRhZGVzIHkgcHVlc3RvcyBhbmFsaXphZG9zLg0KDQoNCiMjIyMgRGlzcGVyc2lvbiBkZSBEaWFzIFRyYWJhamFkb3MgDQpgYGB7cn0NCmdncGxvdChyaDIsIGFlcyh4PUNsdXN0ZXJfTmFtZXMsIHk9RElBUy5UUkFCQUpBRE9TLCBmaWxsPUNsdXN0ZXJfTmFtZXMpKSArDQogIGdlb21fYm94cGxvdCgpKw0KICBnZ3RpdGxlKCJEaXNwZXJzaW9uIG9mICdEw61hcyB0cmFiYWphZG9zJyBieSBDbHVzdGVycyBOYW1lcyIpDQpgYGANCg0KTGEgZ3LDoWZpY2EgYW50ZXJpb3IgZXhwbGljYSBsYSBkaXNwZXJzacOzbiBkZSBkw61hcyB0cmFiYWphZG9zIGRlIGFjdWVyZG8gYSBsYSBjbGFzaWZpY2FjacOzbiBleHBsaWNhZGEgYW50ZXJpb3JtZW50ZSBkZSAnYmFqbycsICdwcm9tZWRpbycsICdhcnJpYmEgZGVsIHByb21lZGlvJyB5ICdhbHRvJy4gQ29uIGVzdG8gZW4gbWVudGUsIHZlbW9zIHF1ZSBlbCBncnVwbyBjb24gbWF5b3IgZGlzcGVyc2nDs24gZXMgJ3Byb21lZGlvJywgcHVlcyBoYXkgdW5hIHZhcmlhYmlsaWRhZCBtw6FzIHNpZ25pZmljYXRpdmEgZW4gbG9zIGRhdG9zIGRlIGxhIGNhbnRpZGFkIGRlIGTDrWFzIHRyYWJhamFkb3MsIGRlc3RhY2FuZG8gbGEgbWVkaWEgZGUgZMOtYXMgdHJhYmFqYWRvcywgZXMgZGVjaXIsIDEwMDAgZMOtYXMuIEVuIGVsIGNhc28gZGUgJ2Jham8nLCBoYXkgdW5hIGRpc3BlcnNpw7NuIGJhamEgeSBwb2NvIHZhcmlhYmxlLiBQYXJhICdhcnJpYmEgZGVsIHByb21lZGlvJywgdmVtb3MgcXVlIGxvcyBwdW50b3MgYXTDrXBpY29zIHNlIHNhbGVuIGRlbCBib3hwbG90IGVzcGVjw61maWNvLCBsbyBjdWFsIHF1aXRhcmxvcyBub3MgcHVlZGUgZGFyIG1heW9yIGNsYXJpZGFkIHkgdmlzaWJpbGlkYWQgZGUgbGEgaW5mb3JtYWNpw7NuLiBQYXJhICdhbHRvJyBzZSBtdWVzdHJhIHVuYSBkaXNwZXJzacOzbiBtZW5vciBhICdwcm9tZWRpbycgeSBhbCBpZ3VhbCBxdWUgJ2FycmliYSBkZWwgcHJvbWVkaW8nLCB0aWVuZSBhcGFyaWNpw7NuIGRlIHB1bnRvcyBhdMOtcGljb3MuDQoNCg0KIyMjIyBEaXNwZXJzaW9uIGRlIFNhbGFyaW8gZGlhcmlvIA0KYGBge3J9DQpnZ3Bsb3QocmgyLCBhZXMoeD1DbHVzdGVyX05hbWVzLCB5PVNBTEFSSU8uRElBUklPLklNU1MsIGZpbGw9Q2x1c3Rlcl9OYW1lcykpICsNCiAgZ2VvbV9ib3hwbG90KCkrDQogIGdndGl0bGUoIkRpc3BlcnNpb24gb2YgJ1NhbGFyaW9fRGlhcmlvJyBieSBDbHVzdGVycyBOYW1lcyIpDQpgYGANCg0KDQpMYSBncsOhZmljYSBhbnRlcmlvciBleHBsaWNhIGxhIGRpc3BlcnNpw7NuIGRlIHNhbGFyaW8gZGlhcmlvIGRlIGFjdWVyZG8gYSBsYSBjbGFzaWZpY2FjacOzbiBleHBsaWNhZGEgYW50ZXJpb3JtZW50ZSBkZSAnYmFqbycsICdwcm9tZWRpbycsICdhcnJpYmEgZGVsIHByb21lZGlvJyB5ICdhbHRvJy4gJ0Jham8nIG11ZXN0cmEgdW4gc2FsYXJpbyBkaWFyaW8gZGUgJDUwMCBwZXNvcywgJ3Byb21lZGlvJyBtdWVzdHJhIHVuIHNhbGFyaW8gZGUgJDE4MCBwZXNvcyBhcHJveCB5IHB1bnRvcyBhdMOtcGljb3MgcXVlIHBvZHLDrWFuIGluc2ludWFyIHVuIHNhbGFyaW8gbWVub3IsICdhcnJpYmEgZGVsIHByb21lZGlvJyB0YW1iacOpbiBtdWVzdHJhIHB1bnRvcyBhdMOtcGljb3MuIFNpbiBlbWJhcmdvLCB0b2RvcyBzZSBtYW50aWVuZW4gYWwgaWd1YWwgcXVlIGVsIGRhdG8gYW50ZXJpb3IgZW50cmUgJDE3MCB5ICQxODAgcGVzb3MgZGUgc2FsYXJpbyBkaWFyaW8sIEZpbmFsbWVudGUsICdhbHRvJyBtdWVzdHJhIHVuIHNhbGFyaW8gZGlhcmlvIGFiYWpvIGRlbCBwcm9tZWRpbyBkZSBhcHJveC4gJDE0MCBwZXNvcy4NCg0KDQojIyAqKkNsdXN0ZXIgMioqIA0KDQoNCg0KYGBge3J9DQpyaENsdXN0ZXIyPC1yZWFkLmNzdigiQzpcXFVzZXJzXFxkYW55Y1xcRG93bmxvYWRzXFxIUl9CYWphcyAyLmNzdiIpIA0Kc3VtbWFyeShyaENsdXN0ZXIyKQ0Kc3RyKHJoQ2x1c3RlcjIpDQpgYGANCg0KDQojIyMjIEV4cGxvcmFyIEtNZWFucyBlbiBlZGFkIHBvciBhw7FvcyANCmBgYHtyfQ0KaHVtYW5vczU8LXJoQ2x1c3RlcjIgJT4lIGRwbHlyOjpzZWxlY3QoRURBRCxESUFTLlRSQUJBSkFET1MsU0FMQVJJTy5ESUFSSU8uSU1TUyxFU1RBRE8uQ0lWSUwpDQpzdW1tYXJ5KGh1bWFub3M1KQ0KYGBgDQogDQoNCg0KIyMjIyBOb3JtYWxpemFyIGxvcyBkYXRvcyANCmBgYHtyfQ0KcmhDbHVzdGVyX25vcm08LXNjYWxlKGh1bWFub3M1WzE6Ml0pIA0KYGBgDQoNCg0KIyMjIyBTYWNhciBudW1lcm8gZGUgY2x1c3RlcnMgDQoNCiBmdml6X25iY2x1c3QoKSBoZWxwcyB0byBkZXRlcm1pbmUgYW5kIHZpc3VhbGl6ZSB0aGUgb3B0aW1hbCBudW1iZXIgb2YgY2x1c3RlcnMNCiANCmBgYHtyfQ0KZnZpel9uYmNsdXN0KHJoQ2x1c3Rlcl9ub3JtLCBrbWVhbnMsIG1ldGhvZD0id3NzIikrICMgd3NzIG1ldGhvZCBjb25zaWRlcnMgdG90YWwgd2l0aGluIHN1bSBvZiBzcXVhcmUNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0PTQsIGxpbmV0eXBlPTIpKyAgICAgICAgICAgIyBvcHRpbWFsIG51bWJlciBvZiBjbHVzdGVycyBpcyBjb21wdXRlZCB3aXRoIHRoZSBkZWZhdWx0IG1ldGhvZCA9ICJldWNsaWRlYW4iDQogIGxhYnMoc3VidGl0bGUgPSAiRWxib3cgbWV0aG9kIikNCg0KYGBgDQoNCiAgICAgICAgICAgICAgDQojIyMjIFZlciBkYXRvcyBkZSBsb3MgY2x1c3RlcnMgIA0KDQpgYGB7cn0NCnJoX2NsdXN0ZXIyPC1rbWVhbnMocmgxX25vcm0sNCkNCnJoX2NsdXN0ZXIyDQpgYGANCg0KIyMjIyBWaXN1YWxpemFyIGNsdXN0ZXJpbmcgIA0KYGBge3J9DQpmdml6X2NsdXN0ZXIocmhfY2x1c3RlcjIsZGF0YT1yaENsdXN0ZXJfbm9ybSkNCmBgYA0KDQoNCkxhIGdyw6FmaWNhIGFudGVyaW9yIG11ZXN0cmEgNCBjbHVzdGVycyBxdWUgYW5hbGl6YW4gbGEgcmVsYWNpw7NuIGVudHJlIGVkYWQgeSBkw61hcyB0cmFiYWphZG9zLiBFbCBjbHVzdGVyIHZlcmRlIG11ZXN0cmEgcXVlIHVuIGFsdG8gbsO6bWVybyBkZSBwZXJzb25hcyB0YWJhamFiYSBtw6FzIGTDrWFzIHF1ZSBlbCBwcm9tZWRpbyB5IHRlbsOtYSB1bmEgZWRhZCBzaW1pbGFyIGFsIHByb21lZGlvLiBFbCBwdW50byBuYXJhbmphIG11ZXN0cmEgcXVlIHBvY29zIHVzdWFyaW9zIHRyYWJhamFiYW4gbcOhcyBkw61hcyBxdWUgZWwgcHJvbWVkaW8geSBhbCBpZ3VhbCBxdWUgZWwgcHVudG8gYW50ZXJpb3IsIHRlbsOtYW4gdW5hIGVkYWQgcHJvbWVkaW8uIEVuIGVsIGNhc28gZGVsIHB1bnRvIGF6dWwgeSBlbCBtb3JhZG8sIGFtYm9zIG11ZXN0cmFuIHF1ZSB1biBtYXlvciBncnVwbyBkZSBwZXJzb25hcyBsYWJvcmFiYSAnMiBkw61hcycsIHBlcm8gdGVuw61hIG1heW9yIHZhcmlhYmlsaWRhZCBlbiBsYSBlZGFkLg0KDQojIyMjIEFncmVnYXIgbGEgaW5mbyBhbCBkYXRhIHNldCBvcmlnaW5hbCANCmBgYHtyfQ0KaHVtYW5vczY8LWh1bWFub3M1DQpodW1hbm9zNiRDbHVzdGVyczwtcmhfY2x1c3RlcjIkY2x1c3Rlcg0Kc3VtbWFyeShodW1hbm9zNikNCmBgYA0KDQoNCiMjIyMgQ3JlYXIgRGF0YXNldCANCmxldHMgY3JlYXRlIGEgZGF0YXNldCBzbyB3ZSBjYW4gaWRlbnRpZnkgc29tZSBjaGFyYWN0ZXJpc3RpY3Mgb2YgIkVkYWQiIGJ5IGNsdXN0ZXIgDQpgYGB7cn0NCmh1bWFub3M3PC1odW1hbm9zNiAlPiUgZ3JvdXBfYnkoQ2x1c3RlcnMsIEVTVEFETy5DSVZJTCkgJT4lIHN1bW1hcmlzZShFREFEPW1heChFREFEKSxESUFTLlRSQUJBSkFET1M9bWVhbihESUFTLlRSQUJBSkFET1MpKSAlPiUgYXJyYW5nZShkZXNjKEVEQUQpKQ0Kc3VtbWFyeShodW1hbm9zNykNCmBgYA0KDQoNCiMjIyMgQWdydXBhciBjbHVzdGVycyBwb3Igbm9tYnJlIA0KYGBge3J9DQpodW1hbm9zNiRDbHVzdGVyX05hbWVzPC1mYWN0b3IoaHVtYW5vczYkQ2x1c3RlcnMsbGV2ZWxzID0gYygxLDIsMyw0KSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscz1jKCJKb3ZlbiIsICJBdmFuemFkbyAiLCAiIEFkdWx0byIsICJKdWJpbGFkbyIpKQ0Kc3VtbWFyeShodW1hbm9zNikNCmBgYA0KDQoNCkVudHJlIG3DoXMgam92ZW4gbcOhcyBkw61hcyB0cmFiYWphZG9zDQoNCg0KIyMjIyBBZ3J1cGFyIHBvciBjbHVzdGVycyB5IHJlc3VtaXIgY29sdW1uYXMgDQpgYGB7cn0NCmh1bWFub3M4IDwtIGh1bWFub3M2ICU+JSBncm91cF9ieShDbHVzdGVyX05hbWVzLCBFU1RBRE8uQ0lWSUwpICU+JSBkcGx5cjo6IHN1bW1hcml6ZShFREFEPW1heChFREFEKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRElBUy5UUkFCQUpBRE9TID1tZWFuKERJQVMuVFJBQkFKQURPUyksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb3VudD1uKCkpDQoNCmBgYA0KDQojIyMjIENvbnZlcnRpciBhIHRhYmxhIA0KYGBge3J9DQpjbHVzdGVyczI8LWFzLmRhdGEuZnJhbWUoaHVtYW5vczgpDQpjbHVzdGVyczINCmBgYA0KDQojIyMgVmlzdWFsaXphciBncmFmaWNvcyANCg0KIyMjIyAgVmVyIGxvcyBkaWFzIHRyYWJhamFkb3MgZW4gZ2VuZXJhbCBqdW50byBjb24gbGEgZWRhZCANCmBgYHtyfQ0KZ2dwbG90KGh1bWFub3M4LGFlcyh4PXJlb3JkZXIoQ2x1c3Rlcl9OYW1lcyxDb3VudCkseT1Db3VudCxmaWxsPUNsdXN0ZXJfTmFtZXMpKSArDQogIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IikNCmBgYA0KDQoNCkxhIGdyw6FmaWNhIGFudGVyaW9yIG5vcyBtdWVzdHJhIGxhIGNhbnRpZGFkIGRlIGTDrWFzIHRyYWJhamFkb3MgZGUgYWN1ZXJkbyBhIGxhIGVkYWQgZGUgbG9zIGVtcGxlYWRvcy4gRW4gZXN0ZSBjYXNvLCB2ZW1vcyBxdWUgZWwgZ3J1cG8gZGUgZWRhZCAnam92ZW4nIHRlbsOtYW4gYXByb3guIDMxIGHDsW9zIHkgcmVwcmVzZW50YSB1biBiYWpvIHBvcmNlbnRhamUgZGUgbG9zIGVtcGxlYWRvcy4gUGFyYSAnYXZhbnphZG8nIHNvbiBsb3MgZW1wbGVhZG9zIHF1ZSB0aWVuZW4gYXJyaWJhIGRlIDMyIGHDsW9zIHkgbGFib3Jhcm9uIGxhIG1heW9yIGNhbnRpZGFkIGRlIGTDrWFzICgxMDY3KS4gUGFyYSAnanViaWxhZG8nLCBzb24gbGFzIHBlcnNvbmFzIGNvbiB1biBhcHJveC4gZGUgNTAgYcOxb3MgeSBxdWUgbGFib3Jhcm9uIGR1cmFudGUgMTAyIGTDrWFzLiBGaW5hbG1lbnRlLCBwYXJhIGVsIGdydXBvIGRlICdhZHVsdG8nIChlbCBtw6FzIGVsZXZhZG8pLCBzb24gYXF1ZWxsb3MgcXVlIGxhYm9yYXJvbiB1biBwcm9tZWRpbyBkZSA0NCBkw61hcyB5IHRpZW5lbiBsYSBlZGFkIGRlIDUyIGHDsW9zLg0KDQojIyMjIERpYXMgdHJhYmFqYWRvcyBwb3Igbm9tYnJlIGRlIGNsdXN0ZXJzIA0KDQpgYGB7cn0NCmdncGxvdChodW1hbm9zOCwgYWVzKHg9Q2x1c3Rlcl9OYW1lcyx5PURJQVMuVFJBQkFKQURPUyxmaWxsPSBDbHVzdGVyX05hbWVzLGxhYmVsPXJvdW5kKERJQVMuVFJBQkFKQURPUyxkaWdpdHM9MikpKSArIA0KICBnZW9tX2NvbCgpICsgDQogIGdlb21fdGV4dCgpDQpgYGANCg0KDQpMYSBncsOhZmljYSBhbnRlcmlvciBub3MgbXVlc3RyYSBsYSBjYW50aWRhZCBkZSBkw61hcyB0cmFiYWphZG9zIGRlIGFjdWVyZG8gYSBsb3MgZMOtYXMgdHJhYmFqYWRvcy4gRW4gZXN0ZSBjYXNvLCBlc3RvIG5vcyBtdWVzdHJhIHF1ZSBlbCBncnVwbyBjb24gbWF5b3IgYmFqYXMgZnVlcm9uIGRlbCBzZWdtZW50byAnYWR1bHRvJyB5IGVzIGVsIHF1ZSBsYWJvcsOzIGVuIHByb21lZGlvIHVuIG1lbm9yIG7Dum1lcm8gZGUgZMOtYXMgY29udHJhICdhdmFuemFkbycgcXVlIGVzIGVsIHNlZ3VuZG8gZ3J1cG8gbcOhcyBiYWpvIHkgbGFib3LDsyBlbCBtYXlvciBuw7ptZXJvIGRlIGTDrWFzIGVuIHByb21lZGlvLg0KDQojIyMjIEVkYWQgcG9yIG5vbWJyZSBkZSBjbHVzdGVycyANCg0KYGBge3J9DQpnZ3Bsb3QoaHVtYW5vczgsYWVzKHg9Q2x1c3Rlcl9OYW1lcyx5PUVEQUQsZmlsbD0gQ2x1c3Rlcl9OYW1lcyxsYWJlbD1yb3VuZChFREFELGRpZ2l0cz0yKSkpICsgDQogIGdlb21fY29sKCkgKyANCiAgZ2VvbV90ZXh0KCkNCmBgYA0KDQoNCiBMYSBncsOhZmljYSBhbnRlcmlvciBub3MgbXVlc3RyYSBsYSBlZGFkIHByb21lZGlvIGRlIGNhZGEgdW5vIGRlIGxvcyBncnVwb3MuIENvbW8gZXhwbGljYW1vcyBhbnRlcmlvcm1lbnRlLCBzZSBtdWVzdHJhIHF1ZSAnYWR1bHRvJyBlcyBlbCBkZSBlbXBsZWFkb3MgY29uIG1heW9yIGVkYWQgeSAnam92ZW4nIGVzIGVsIGRlIHBlcnNvbmFzIGRlIG1lbm9yIGVkYWQuDQoNCiMjIyMgRGlhcyB0cmFiYWphZG9zIHBvciBub21icmUgZGUgY2x1c3RlcnMgDQpgYGB7cn0NCmdncGxvdChodW1hbm9zNiwgYWVzKHg9Q2x1c3Rlcl9OYW1lcywgeT1FREFELCBmaWxsPUNsdXN0ZXJfTmFtZXMpKSArDQogIGdlb21fYm94cGxvdCgpKw0KICBnZ3RpdGxlKCJEaXNwZXJzaW9uIG9mICdFZGFkJyBieSBDbHVzdGVycyBOYW1lcyIpDQpgYGANCg0KIExhIGdyw6FmaWNhIGFudGVyaW9yIG5vcyBtdWVzdHJhIGxhIGRpc3BlcnNpw7NuIGRlIGFjdWVyZG8gYSBsYSBlZGFkIGRlIGxvcyBlbXBsZWFkb3MuIEVuIGVsIGNhc28gZGUgJ2FkdWx0bycsIHRpZW5lIHVuYSBncmFuIGNhbnRpZGFkIGRlIHB1bnRvcyBhdMOtcGljb3MgbG8gY3VhbCBpbmRpY2EgcXVlIGhheSBkYXRvcyBmdWVyYSBkZSBzZXJpZS4gRW4gZWwgY2FzbyBkZSAnanViaWxhZG8nLCB2ZW1vcyBxdWUgZXMgZWwgZ3J1cG8gY29uIG1heW9yIGRpc3BlcnNpw7NuLCBtb3N0cmFuZG8gZGF0b3MgZGUgZWRhZCBlbnRyZSAyNSB5IDMyIGHDsW9zLg0KIA0KIA0KDQojIyMjIFNhbGFyaW8gZGlhcmlvIHBvciBub21icmUgZGUgY2x1c3RlcnMgDQpgYGB7cn0NCmdncGxvdChodW1hbm9zNiwgYWVzKHg9Q2x1c3Rlcl9OYW1lcywgeT1ESUFTLlRSQUJBSkFET1MsIGZpbGw9Q2x1c3Rlcl9OYW1lcykpICsNCiAgZ2VvbV9ib3hwbG90KCkrDQogIGdndGl0bGUoIkRpc3BlcnNpb24gb2YgJ0RpYXNfVHJhYmFqYWRvcycgYnkgQ2x1c3RlcnMgTmFtZXMiKQ0KYGBgDQoNCg0KDQogTGEgZ3LDoWZpY2EgYW50ZXJpb3IgbXVlc3RyYSBsYSBkaXNwZXJzacOzbiBkZSBhY3VlcmRvIGEgZMOtYXMgdHJhYmFqYWRvcyB5IGxvcyBncnVwb3MgYW50ZXJpb3IgZXhwbGljYWRvcy4gVmVtb3MgcXVlICdhdmFuemFkbycgZXMgZWwgZ3VycG8gY29uIG1heW9yIGRpc3BlcnNpw7NuLCBtb3N0cmFuZG8gcXVlIGVsIHByb21lZGlvIGRlIGxvcyBlbXBsZWFkb3MgbGFib3Jhcm9uIGVudHJlIDU1MCB5IDEzMDAgZMOtYXMuIEVzIGVsIGdydXBvIGNvbiBtYXlvciBuw7ptZXJvIGRlIGVtcGxlYWRvcyBxdWUgdHJhYmFqYXJvbiBlbiBlc3RlIHBlcmlvZG8gZGUgdGllbXBvLiBFbiBlbCBjYXNvIGRlICdhZHVsdG8nIHkgJ2p1YmlsYWRvJywgc29uIGFxdWVsbG9zIGdydXBvcyBxdWUgbXVlc3RyYW4gdW5hIGRpc3BlcnNpw7NuIGJhamEgeSB1bmEgdmFyaWVkYWQgZGUgcHVudG9zIGF0w61waWNvcywgbWllbnRyYXMgcXVlICdqb3ZlbicgZGVzdGFjYSB1bmEgYmFqYSBkaXNwZXJzacOzbiB5IHVuYSBtZWRpYSBkZSBtw6FzIGRlIDUwMCBkw61hcyB0cmFiYWphZG9zLg0KIA0KIyMgKipDbHVzdGVyIDMqKiANCg0KIyMjIEltcG9ydGFyIGxhIGJhc2UgZGUgZGF0b3MgDQpgYGB7cn0NCmNsdXN0ZXIzPC1yZWFkLmNzdigiQzpcXFVzZXJzXFxkYW55Y1xcRG93bmxvYWRzXFxIUl9CYWphcyAyLmNzdiIpIA0Kc3VtbWFyeShjbHVzdGVyMykNCnN0cihjbHVzdGVyMykNCmBgYA0KDQojIyMgTnVtZXJvIGRlIGNsdXN0ZXJzIA0KDQojIyMjIEp1bnRhciBsb3MgZGF0b3MgcmVsYWNpb25hZG9zIGEgZWRhZCBlbiBhw7FvcyANCmBgYHtyfQ0KbmV3YmQ8LWNsdXN0ZXIzICU+JSBkcGx5cjo6c2VsZWN0KEVEQUQsU0FMQVJJTy5ESUFSSU8uSU1TUyxQVUVTVE8pDQpzdW1tYXJ5KG5ld2JkKQ0KYGBgDQoNCiMjIyMgTm9ybWFsaXphciBkYXRvcyANCmBgYHtyfQ0KbmV3YmRub3JtPC1zY2FsZShuZXdiZFsyOjFdKQ0KYGBgDQoNCiMjIyMgR3JhZmljYSBwYXJhIHZlciBudW1lcm8gb3B0aW1vIGRlIGNsdXN0ZXJzIA0KYGBge3J9DQpmdml6X25iY2x1c3QobmV3YmRub3JtLCBrbWVhbnMsIG1ldGhvZD0id3NzIikrICMgd3NzIG1ldGhvZCBjb25zaWRlcnMgdG90YWwgd2l0aGluIHN1bSBvZiBzcXVhcmUNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0PTQsIGxpbmV0eXBlPTIpKyAgICAgICAgICAgIyBvcHRpbWFsIG51bWJlciBvZiBjbHVzdGVycyBpcyBjb21wdXRlZCB3aXRoIHRoZSBkZWZhdWx0IG1ldGhvZCA9ICJldWNsaWRlYW4iDQogIGxhYnMoc3VidGl0bGUgPSAiRWxib3cgbWV0aG9kIikNCmBgYA0KDQojIyMjIFZpc3VhbGl6YXIgaW5mb3JtYWNpb24gIA0KYGBge3J9DQpuZXdiZDJjbHVzPC1rbWVhbnMobmV3YmRub3JtLDQpDQpuZXdiZDJjbHVzDQpgYGANCg0KIyMjIFZlciByZXN1bHRhZG9zIGRlIGNsdXN0ZXJzIA0KYGBge3J9DQpmdml6X2NsdXN0ZXIobmV3YmQyY2x1cyxkYXRhPW5ld2Jkbm9ybSkNCmBgYA0KDQojIyMjIEFncmVnYXIgbG9zIHJlc3VsdGFkb3MgYWwgZGF0YXNldCBvcmlnaW5hbCBwYXJhIGludGVycHJldGFjaW9uIA0KYGBge3J9DQpuZXdiZDM8LW5ld2JkIA0KbmV3YmQzJENsdXN0ZXJzPC1uZXdiZDJjbHVzJGNsdXN0ZXINCnN1bW1hcnkobmV3YmQzKQ0KYGBgDQoNCiMjIyMgQ3JlYXIgZGF0YXNldHMgcGFyYSB2ZXIgbGEgaW5mbyBkZSBjYXJhY3RlcmlzdGljYXMgcG9yIGVkYWQgcG9yIGNsdXN0ZXJzIA0KYGBge3J9DQpuZXdiZDQ8LW5ld2JkMyAlPiUgZ3JvdXBfYnkoQ2x1c3RlcnMsUFVFU1RPKSAlPiUgc3VtbWFyaXNlKEVEQUQ9bWF4KEVEQUQpLFNBTEFSSU8uRElBUklPLklNU1M9bWVhbihTQUxBUklPLkRJQVJJTy5JTVNTKSkgJT4lIGFycmFuZ2UoZGVzYyhFREFEKSkNCnN1bW1hcnkobmV3YmQ0KQ0KYGBgDQoNCiMjIyMgQWdydXBhciBjbHVzdGVycyBwb3Igbm9tYnJlIA0KYGBge3J9DQpuZXdiZDMkQ2x1c3Rlcl9OYW1lczwtZmFjdG9yKG5ld2JkMyRDbHVzdGVycyxsZXZlbHMgPSBjKDEsMiwzLDQpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzPWMoIkpvdmVuIiwgIkF2YW56YWRvICIsICIgQWR1bHRvIiwgIkp1YmlsYWRvIikpDQpzdW1tYXJ5KG5ld2JkMykNCmBgYA0KDQojIyMjIEFncnVwYXIgcG9yIG5vbWJyZSB5IHBvciBjb2x1bW5hIA0KYGBge3J9DQpuZXdiZDUgPC0gbmV3YmQzJT4lIGRwbHlyOjpncm91cF9ieShDbHVzdGVyX05hbWVzLFBVRVNUTykgJT4lIGRwbHlyOjogc3VtbWFyaXplKEVEQUQ9bWF4KEVEQUQpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTQUxBUklPLkRJQVJJTy5JTVNTID1tZWFuKFNBTEFSSU8uRElBUklPLklNU1MpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ291bnQ9bigpKQ0KYGBgDQoNCiMjIyBWaXN1YWxpemFyIGdyYWZpY2FzIA0KDQojIyMjIFBvbmVyIGNvbW8gdGFibGEgbG9zIGRhdG9zIA0KYGBge3J9DQpjbHVzdGVyc3NhbGFyaW88LWFzLmRhdGEuZnJhbWUobmV3YmQ1KQ0KY2x1c3RlcnNzYWxhcmlvDQpgYGANCg0KIyMjIyBHcmFmaWNhciBwb3Igbm9tYnJlIA0KYGBge3J9DQpnZ3Bsb3QobmV3YmQ1LGFlcyh4PXJlb3JkZXIoQ2x1c3Rlcl9OYW1lcyxDb3VudCkseT1Db3VudCxmaWxsPUNsdXN0ZXJfTmFtZXMpKSArDQogIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IikNCmBgYA0KDQojIyMjIFNhbGFyaW8gZGlhcmlvIHBvciBudW1lcm8gZGUgY2x1c3RlcnMgDQpgYGB7cn0NCmdncGxvdChuZXdiZDUsIGFlcyh4PUNsdXN0ZXJfTmFtZXMseT1TQUxBUklPLkRJQVJJTy5JTVNTLGZpbGw9IENsdXN0ZXJfTmFtZXMsbGFiZWw9cm91bmQoU0FMQVJJTy5ESUFSSU8uSU1TUyxkaWdpdHM9MikpKSArIA0KICBnZW9tX2NvbCgpICsgDQogIGdlb21fdGV4dCgpDQpgYGANCg0KQXF1aSBub3MgcG9kZW1vcyBkYXIgY3VlbnRhIGFjZXJjYSBkZSBxdWUgbG9zIHN1ZWxkb3Mgbm8gdmFyaWFuIG11Y2hvIGVudHJlIGVkYWRlcyBwZXJvIGVzIGltcG9ydGFudGUgZGVjaXIgcXVlIHNlIGRlbm90YSBwb3IgY2VudGF2b3MgdW5hIG1heW9yaWEgZW4gZWwgc3VlbGRvIGRlIGxvcyBqb3ZlbmVzIGVzcGVjaWZpY2FtZW50ZSBtw6FzIHF1ZSBlbiBvdHJvcyByYW5nb3MgZGUgZWRhZGVzLg0KDQoNCg0KIyMjICBiLiBJZGVudGlmaWNhY2nDs24gZGUgY2FyYWN0ZXLDrXN0aWNhcyBkZSBjbMO6c3RlcnMgc2VsZWNjaW9uYWRvcyANCg0KIyMjIyBHcmFmaWNhciBlbCBuby4gZGUgZGF0b3Mgb2JzZXJ2YWRvcyBwb3IgR2VuZXJvIA0KDQpgYGB7cn0NCmdncGxvdChyaDQsYWVzKHg9cmVvcmRlcihDbHVzdGVyX05hbWVzLENvdW50KSx5PUNvdW50LGZpbGw9R0VORVJPKSkgKw0KICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIpDQpgYGANCg0KIyMjIyAgVmVyIGxvcyBkaWFzIHRyYWJhamFkb3MgZW4gZ2VuZXJhbCBqdW50byBjb24gbGEgZWRhZCB5IEVzdGFkbyBjaXZpbCANCg0KYGBge3J9DQpnZ3Bsb3QoaHVtYW5vczgsYWVzKHg9cmVvcmRlcihDbHVzdGVyX05hbWVzLENvdW50KSx5PUNvdW50LGZpbGw9RVNUQURPLkNJVklMKSkgKw0KICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIpDQpgYGANCg0KIyMjIyBHcmFmaWNhciBwb3Igbm9tYnJlIA0KYGBge3J9DQpnZ3Bsb3QobmV3YmQ1LGFlcyh4PXJlb3JkZXIoQ2x1c3Rlcl9OYW1lcyxDb3VudCkseT1Db3VudCxmaWxsPVBVRVNUTykpICsNCiAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiKQ0KYGBgDQoNCg0KDQojIyBIYWxsYXpnb3MgDQpbIDEgXSBFbCBzYWxhcmlvIGRpYXJpbyBwcm9tZWRpbyBkZSBGT1JNIGVzIGRlICQxODAgcGVzb3MgbWV4aWNhbm9zLCBlcyBkZWNpciwgJDUsNDAwIHBlc29zIG1lbnN1YWxlcy4gRGUgYWN1ZXJkbyBhIGRhdG9zIGNvbXBhcnRpZG9zIHBvciBsYSBJTkVHSSwgc2UgcHJldsOpIHF1ZSBwYXJhIDIwMjIgZWwgc2FsYXJpbyBtw61uaW1vIGVuIE3DqXhpY28gc2VhIGRlICQ1LDI1NSBwZXNvcyBtZW5zdWFsZXMuIEVzdG8gcmVmbGVqYSBxdWUgZWwgc2FsYXJpbyBtZW5zdWFsIGRlIEZPUk0gZXMgMiUgbWF5b3IgYWwgc2FsYXJpbyBtw61uaW1vIGRlbCBwYcOtcy4gDQpbIDIgXSBTZSBkZXN0YWNhbiB0cmVzIHJhem9uZXMgcHJpbmNpcGFsZXMgZGUgYmFqYXMgZGUgZW1wbGVhZG9zOiBiYWphcyBwb3IgZmFsdGFzLCByZW51bmNpYSB2b2x1bnRhcmlhIG8gdMOpcm1pbm8gZGUgY29udHJhdG8uIEVuIHN1IG1heW9yw61hLCBodWJvIHVuYSBiYWphIHBvciBmYWx0YXMgZGVsIHB1ZXN0byBkZSBheXVkYW50ZSBnZW5lcmFsIHkgcmVudW5jaWEgdm9sdW50YXJpYSBwYXJhIGVsIG1pc21vIHB1ZXN0by4gDQpbIDMgXSBIdWJvIHVuIGFsdG8gbsO6bWVybyBkZSBiYWphcyBkZSBlbXBsZWFkb3MgcXVlIHRyYWJhamFyb24gbcOhcyBkZSAyMDAgZMOtYXMsIGVzIGRlY2lyLCBsYSBtYXlvcsOtYSBkZSBsb3MgZXgtZW1wbGVhZG9zIGVzdHV2aWVyb24gZW4gRk9STSBtw6FzIGRlIDEgYcOxbyB5IHRlbsOtYW4gdW4gc2FsYXJpbyBwcm9tZWRpbyBkZSAkMTgwIHBlc29zLiANClsgNCBdIExvcyBzdWVsZG9zIGRlIGxvcyBlbXBsZWFkb3Mgbm8gdmFyw61hbiBtdWNobyBkZXBlbmRpZW5kbyBkZSBsYSBlZGFkLiBTaW4gZW1iYXJnbywgdmVtb3MgcXVlIGhheSBtYXlvciByb3RhY2nDs24gcGFyYSBlbCBncnVwbyAnYWR1bHRvJy4gDQoNCiMjIEdyw6FmaWNhcyBnZ2FsbHV2aWFsIA0KYGBge3J9DQpsaWJyYXJ5KGdnYWxsdXZpYWwpDQpnYWxsPC1yaDINCg0KZ2FsbDwtcmgyICU+JSBmaWx0ZXIoQ2x1c3RlcnM9PTEgfCBDbHVzdGVycz09MykgJT4lIGFycmFuZ2UoQ2x1c3RlcnMpDQpnZ3Bsb3QoYXMuZGF0YS5mcmFtZShnYWxsKSwNCiAgICAgICBhZXMoeT1TQUxBUklPLkRJQVJJTy5JTVNTLCBheGlzMT1FREFELCBheGlzMj1ESUFTLlRSQUJBSkFET1MpKSArDQogIGdlb21fYWxsdXZpdW0oYWVzKGZpbGw9Q2x1c3Rlcl9OYW1lcyksIHdpZHRoID0gMS8xMikgKw0KICBnZW9tX3N0cmF0dW0od2lkdGggPSAxLzEyLCBmaWxsID0gImJsYWNrIiwgY29sb3IgPSAiZ3JleSIpICsNCiAgZ2VvbV9sYWJlbChzdGF0ID0gInN0cmF0dW0iLCBhZXMobGFiZWwgPSBhZnRlcl9zdGF0KHN0cmF0dW0pKSkgKw0KICBzY2FsZV94X2Rpc2NyZXRlKGxpbWl0cyA9IGMoIkVkYWQiLCAiRMOtYXMgVHJhYmFqYWRvcyIpLCBleHBhbmQgPSBjKC4wNSwgLjA1KSkgKw0KICBzY2FsZV9maWxsX2JyZXdlcih0eXBlID0gInF1YWwiLCBwYWxldHRlID0gIlNldDEiKSArDQogIGdndGl0bGUoIkVsIFNhbGFyaW8gRGlhcmlvIHBvciB2YXJpYWJsZXMgY3VhbGl0YXRpdmFzIikNCmBgYA0KDQojIDxzcGFuIHN0eWxlID0gImNvbG9yOmRhcmtvcmFuZ2UiPiBTZWNjacOzbiA0DQoNCiMjIEhhbGxhemdvcw0KIyMgU3VnZXJlbmNpYXMNCiMjIEJ1c2luZXNzIEFuYWx5dGljcyB5IEJ1c2luZXNzIEludGVsbGlnZW5jZSANCg0KIyA8c3BhbiBzdHlsZSA9ICJjb2xvcjpkYXJrb3JhbmdlIj5LUEnCtHMNCg0KIyA8c3BhbiBzdHlsZSA9ICJjb2xvcjpkYXJrb3JhbmdlIj5SZWZlcmVuY2lhcw0KDQogIEFuYSBLYXJlbiBHYXJjw61hLiAoMjAyMiwgU2VwdGVtYmVyIDgpLiBJbmR1c3RyaWEgYXV0b21vdHJpeiBhbm90YSB1biBidWVuIGFnb3N0bzogY3JlY2VuIHByb2R1Y2Npw7NuLCBleHBvcnRhY2lvbmVzIHkgdmVudGFzIGludGVybmFzLiBFbCBFY29ub21pc3RhOyBFbCBFY29ub21pc3RhLiBodHRwczovL3d3dy5lbGVjb25vbWlzdGEuY29tLm14L2VtcHJlc2FzL0luZHVzdHJpYS1hdXRvbW90cml6LWFub3RhLXVuLWJ1ZW4tYWdvc3RvLWNyZWNlbi1wcm9kdWNjaW9uLWV4cG9ydGFjaW9uZXMteS12ZW50YXMtaW50ZXJuYXMtMjAyMjA5MDctMDAzMS5odG1sIA0KICANCiAgSGVybsOhbmRleiwgRi4sICYgVXN1Z2EsIE8uICgyMDIyKS4gOSBUYWJsYXMgZGUgZnJlY3VlbmNpYSB8IE1hbnVhbCBkZSBSLiBSZXRyaWV2ZWQgMjQgU2VwdGVtYmVyIDIwMjIsIGZyb20gaHR0cHM6Ly9maGVybmFuYi5naXRodWIuaW8vTWFudWFsLWRlLVIvdGFibGFzLmh0bWwjZWplbXBsby10YWJsYS1kZS1mcmVjdWVuY2lhLXJlbGF0aXZhLWRlLXVuYS12JUMzJUFEYSANCg0KICA5IEVzdGlsb3MgeSBmb3JtYXRvcyBkZSB0YWJsYSB8IFRhYmxhcyB5IGdyYWZpY29zIGNvbiBSIHkgUiBTdHVkaW8uICgyMDIyKS4gUmV0cmlldmVkIDI0IFNlcHRlbWJlciAyMDIyLCBmcm9tIGh0dHBzOi8vdGFibGVzLmludmVzdGlnYW9ubGluZS5jb20vdHNlLWZvcm1hdGVvLmh0bWwgDQoNCiMgPHNwYW4gc3R5bGUgPSAiY29sb3I6ZGFya29yYW5nZSI+QW5leG8NCg==