#

Contexto

La base de datos es de la universidad de nueva York y contiene 90 observaciones que incluyen los costos de 6 aerolineas estadounidenses durante 15 años, de 1970 a 1984.

Las variables son:

  • I = Aerolinea
  • T = Año
  • Q = Output
  • C = Costo total en $1,000
  • PF = Precio del Combustible
  • LF = Factor de Carga

Instalar paquetes y llamar librerías

library(plm)
library(tidyverse)
library(forecast)
library(lavaan)
library(lavaanPlot)
library(DataExplorer)
library(ggplot2)
library(gplots)

Base de Datos

df <- read.csv("/Users/genarorodriguezalcantara/Desktop/Tec/Generacion de escenarios futuros con analítica (Gpo 101)/PIB/Actividad-4_Caso-de-Negocio-1_Costos-en-Aerolíneas/Cost Data for U.S. Airlines.csv")

Análisis Exploratorio

summary(df)
##        I             T            C                 Q          
##  Min.   :1.0   Min.   : 1   Min.   :  68978   Min.   :0.03768  
##  1st Qu.:2.0   1st Qu.: 4   1st Qu.: 292046   1st Qu.:0.14213  
##  Median :3.5   Median : 8   Median : 637001   Median :0.30503  
##  Mean   :3.5   Mean   : 8   Mean   :1122524   Mean   :0.54499  
##  3rd Qu.:5.0   3rd Qu.:12   3rd Qu.:1345968   3rd Qu.:0.94528  
##  Max.   :6.0   Max.   :15   Max.   :4748320   Max.   :1.93646  
##        PF                LF        
##  Min.   : 103795   Min.   :0.4321  
##  1st Qu.: 129848   1st Qu.:0.5288  
##  Median : 357434   Median :0.5661  
##  Mean   : 471683   Mean   :0.5605  
##  3rd Qu.: 849840   3rd Qu.:0.5947  
##  Max.   :1015610   Max.   :0.6763
str(df)
## 'data.frame':    90 obs. of  6 variables:
##  $ I : int  1 1 1 1 1 1 1 1 1 1 ...
##  $ T : int  1 2 3 4 5 6 7 8 9 10 ...
##  $ C : int  1140640 1215690 1309570 1511530 1676730 1823740 2022890 2314760 2639160 3247620 ...
##  $ Q : num  0.953 0.987 1.092 1.176 1.16 ...
##  $ PF: int  106650 110307 110574 121974 196606 265609 263451 316411 384110 569251 ...
##  $ LF: num  0.534 0.532 0.548 0.541 0.591 ...
head(df)
##   I T       C        Q     PF       LF
## 1 1 1 1140640 0.952757 106650 0.534487
## 2 1 2 1215690 0.986757 110307 0.532328
## 3 1 3 1309570 1.091980 110574 0.547736
## 4 1 4 1511530 1.175780 121974 0.540846
## 5 1 5 1676730 1.160170 196606 0.591167
## 6 1 6 1823740 1.173760 265609 0.575417
df$I <- as.factor(df$I)
df$Y <- df$T + 1969

summary(df)
##  I            T            C                 Q                 PF         
##  1:15   Min.   : 1   Min.   :  68978   Min.   :0.03768   Min.   : 103795  
##  2:15   1st Qu.: 4   1st Qu.: 292046   1st Qu.:0.14213   1st Qu.: 129848  
##  3:15   Median : 8   Median : 637001   Median :0.30503   Median : 357434  
##  4:15   Mean   : 8   Mean   :1122524   Mean   :0.54499   Mean   : 471683  
##  5:15   3rd Qu.:12   3rd Qu.:1345968   3rd Qu.:0.94528   3rd Qu.: 849840  
##  6:15   Max.   :15   Max.   :4748320   Max.   :1.93646   Max.   :1015610  
##        LF               Y       
##  Min.   :0.4321   Min.   :1970  
##  1st Qu.:0.5288   1st Qu.:1973  
##  Median :0.5661   Median :1977  
##  Mean   :0.5605   Mean   :1977  
##  3rd Qu.:0.5947   3rd Qu.:1981  
##  Max.   :0.6763   Max.   :1984
str(df)
## 'data.frame':    90 obs. of  7 variables:
##  $ I : Factor w/ 6 levels "1","2","3","4",..: 1 1 1 1 1 1 1 1 1 1 ...
##  $ T : int  1 2 3 4 5 6 7 8 9 10 ...
##  $ C : int  1140640 1215690 1309570 1511530 1676730 1823740 2022890 2314760 2639160 3247620 ...
##  $ Q : num  0.953 0.987 1.092 1.176 1.16 ...
##  $ PF: int  106650 110307 110574 121974 196606 265609 263451 316411 384110 569251 ...
##  $ LF: num  0.534 0.532 0.548 0.541 0.591 ...
##  $ Y : num  1970 1971 1972 1973 1974 ...
head(df)
##   I T       C        Q     PF       LF    Y
## 1 1 1 1140640 0.952757 106650 0.534487 1970
## 2 1 2 1215690 0.986757 110307 0.532328 1971
## 3 1 3 1309570 1.091980 110574 0.547736 1972
## 4 1 4 1511530 1.175780 121974 0.540846 1973
## 5 1 5 1676730 1.160170 196606 0.591167 1974
## 6 1 6 1823740 1.173760 265609 0.575417 1975
create_report
## function (data, output_format = html_document(toc = TRUE, toc_depth = 6, 
##     theme = "yeti"), output_file = "report.html", output_dir = getwd(), 
##     y = NULL, config = configure_report(), report_title = "Data Profiling Report", 
##     ...) 
## {
##     if (!is.data.table(data)) 
##         data <- data.table(data)
##     if (!is.null(y)) {
##         if (!(y %in% names(data))) 
##             stop("`", y, "` not found in data!")
##     }
##     report_dir <- system.file("rmd_template/report.rmd", package = "DataExplorer")
##     suppressWarnings(render(input = report_dir, output_format = output_format, 
##         output_file = output_file, output_dir = output_dir, intermediates_dir = output_dir, 
##         params = list(data = data, report_config = config, response = y, 
##             set_title = report_title), ...))
##     report_path <- path.expand(file.path(output_dir, output_file))
##     browseURL(report_path)
## }
## <bytecode: 0x109977040>
## <environment: namespace:DataExplorer>

Gráficas

#create_report(df)
plot_missing(df)

plot_histogram(df)

plot_correlation(df)

ggplot(df, aes(x = Y, y = C, color = I, group = I)) + 
  geom_line() +
  labs(title = "Costo por Aerolinea (en miles)", x = "Año", y = "Costo (USD)", color = "Aerolinea") + 
  theme_minimal()

ggplot(df, aes(x = Y, y = Q, color = I, group = I)) + 
  geom_line() +
  labs(title = "Millas Voladas (por pasajero)", x = "Año", y = "Indice Normalizado", color = "Aerolinea") + 
  theme_minimal()

ggplot(df, aes(x = Y, y = PF, color = I, group = I)) + 
  geom_line() +
  labs(title = "Precio del Combustible", x = "Año", y = "Costo (USD)", color = "Aerolinea") + 
  theme_minimal()

ggplot(df, aes(x = Y, y = LF, color = I, group = I)) + 
  geom_line() +
  labs(title = "Factor de Carga", x = "Año", y = "Porcentaje", color = "Aerolinea") + 
  theme_minimal()

# Tema 1. Datos de Panel ## Heterogeneidad

plotmeans(C~I, main = "Heterogeneidad entre Aerolineas", xlab = "Aerolinea", ylab = "Costo (Miles de USD)", data = df)

Como el valor promedio (círculo) y el rango intercuartil (líeas azules) varían entre individuos, se observa presencia de heterogeneidad.

Creacion de Datos de Panel

df_panel <- pdata.frame(df, index = c("I", "Y"))
df_panel <- df_panel %>% select(-c("I", "T", "Y"))

Modelo 1. Regression Agrupada (Pooled)

# El modelo de Regresión Agrupada (pooled) es una técnica de estimación de datos de panel donde se sasume que no hay efectos individuales especificos para cada unidad (Ej. Aerolineas) ni variaciones en el tiempo. Ignora heterogeneidad.
pooled <- plm(C ~ Q + PF + LF, data = df_panel, model = "pooling")
summary(pooled)
## Pooling Model
## 
## Call:
## plm(formula = C ~ Q + PF + LF, data = df_panel, model = "pooling")
## 
## Balanced Panel: n = 6, T = 15, N = 90
## 
## Residuals:
##    Min. 1st Qu.  Median 3rd Qu.    Max. 
## -520654 -250270   37333  208690  849700 
## 
## Coefficients:
##                Estimate  Std. Error t-value  Pr(>|t|)    
## (Intercept)  1.1586e+06  3.6059e+05  3.2129   0.00185 ** 
## Q            2.0261e+06  6.1807e+04 32.7813 < 2.2e-16 ***
## PF           1.2253e+00  1.0372e-01 11.8138 < 2.2e-16 ***
## LF          -3.0658e+06  6.9633e+05 -4.4027 3.058e-05 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Total Sum of Squares:    1.2647e+14
## Residual Sum of Squares: 6.8177e+12
## R-Squared:      0.94609
## Adj. R-Squared: 0.94421
## F-statistic: 503.118 on 3 and 86 DF, p-value: < 2.22e-16
# Prueba de Breusch-Pagan (BP): Para verufucar si elmodelo pooled es adecuado.
# p-value < 0.05 Avanzamos para usar un modelo de Efectos Fijos o Aleatorios
# p-value > 0.05 Podemos usar el modelo Pooled.

plmtest(pooled, type = "bp")
## 
##  Lagrange Multiplier Test - (Breusch-Pagan)
## 
## data:  C ~ Q + PF + LF
## chisq = 0.61309, df = 1, p-value = 0.4336
## alternative hypothesis: significant effects

Este modelo tiene un p-value mayor a 0.05, lo que nos dice que podemos utilizar el modelo Pooled.

Modelo 2. Efectos Fijos (Within)

within <- plm(C ~ Q + PF + LF, data = df_panel, model = "within")
summary(within)
## Oneway (individual) effect Within Model
## 
## Call:
## plm(formula = C ~ Q + PF + LF, data = df_panel, model = "within")
## 
## Balanced Panel: n = 6, T = 15, N = 90
## 
## Residuals:
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
## -551783 -159259    1796       0  137226  499296 
## 
## Coefficients:
##       Estimate  Std. Error t-value  Pr(>|t|)    
## Q   3.3190e+06  1.7135e+05 19.3694 < 2.2e-16 ***
## PF  7.7307e-01  9.7319e-02  7.9437 9.698e-12 ***
## LF -3.7974e+06  6.1377e+05 -6.1869 2.375e-08 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Total Sum of Squares:    5.0776e+13
## Residual Sum of Squares: 3.5865e+12
## R-Squared:      0.92937
## Adj. R-Squared: 0.92239
## F-statistic: 355.254 on 3 and 81 DF, p-value: < 2.22e-16

Modelo 3. Efectos Aleatorios (random) Método Walhus

walhus <- plm(C ~ Q + PF + LF, data = df_panel, model = "random", random.method = "walhus")
summary(walhus)
## Oneway (individual) effect Random Effect Model 
##    (Wallace-Hussain's transformation)
## 
## Call:
## plm(formula = C ~ Q + PF + LF, data = df_panel, model = "random", 
##     random.method = "walhus")
## 
## Balanced Panel: n = 6, T = 15, N = 90
## 
## Effects:
##                     var   std.dev share
## idiosyncratic 7.339e+10 2.709e+05 0.969
## individual    2.363e+09 4.861e+04 0.031
## theta: 0.1788
## 
## Residuals:
##    Min. 1st Qu.  Median 3rd Qu.    Max. 
## -524180 -243611   39332  199517  824905 
## 
## Coefficients:
##                Estimate  Std. Error z-value  Pr(>|z|)    
## (Intercept)  1.1267e+06  3.6994e+05  3.0455  0.002323 ** 
## Q            2.0647e+06  7.1927e+04 28.7051 < 2.2e-16 ***
## PF           1.2075e+00  1.0358e-01 11.6578 < 2.2e-16 ***
## LF          -3.0314e+06  7.1431e+05 -4.2438 2.198e-05 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Total Sum of Squares:    1.0182e+14
## Residual Sum of Squares: 6.5784e+12
## R-Squared:      0.93539
## Adj. R-Squared: 0.93314
## Chisq: 1245.09 on 3 DF, p-value: < 2.22e-16

Modelo 4. Efectos Aleatorios (random) Método Amemiya

amemiya <- plm(C ~ Q + PF + LF, data = df_panel, model = "random", random.method = "amemiya")
summary(amemiya)
## Oneway (individual) effect Random Effect Model 
##    (Amemiya's transformation)
## 
## Call:
## plm(formula = C ~ Q + PF + LF, data = df_panel, model = "random", 
##     random.method = "amemiya")
## 
## Balanced Panel: n = 6, T = 15, N = 90
## 
## Effects:
##                     var   std.dev share
## idiosyncratic 4.270e+10 2.066e+05 0.084
## individual    4.640e+11 6.812e+05 0.916
## theta: 0.9219
## 
## Residuals:
##    Min. 1st Qu.  Median 3rd Qu.    Max. 
## -603585 -144415   22641  158005  485417 
## 
## Coefficients:
##                Estimate  Std. Error z-value  Pr(>|z|)    
## (Intercept)  1.0746e+06  4.2105e+05  2.5522    0.0107 *  
## Q            3.2090e+06  1.6482e+05 19.4695 < 2.2e-16 ***
## PF           8.1014e-01  9.6147e-02  8.4260 < 2.2e-16 ***
## LF          -3.7168e+06  6.1330e+05 -6.0603 1.359e-09 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Total Sum of Squares:    5.1238e+13
## Residual Sum of Squares: 3.8227e+12
## R-Squared:      0.92539
## Adj. R-Squared: 0.92279
## Chisq: 1066.71 on 3 DF, p-value: < 2.22e-16

Modelo 5. Efectos Aleatorios (random) Método Nerlove

nerlove <- plm(C ~ Q + PF + LF, data = df_panel, model = "random", random.method = "nerlove")
summary(nerlove)
## Oneway (individual) effect Random Effect Model 
##    (Nerlove's transformation)
## 
## Call:
## plm(formula = C ~ Q + PF + LF, data = df_panel, model = "random", 
##     random.method = "nerlove")
## 
## Balanced Panel: n = 6, T = 15, N = 90
## 
## Effects:
##                     var   std.dev share
## idiosyncratic 3.985e+10 1.996e+05 0.066
## individual    5.602e+11 7.485e+05 0.934
## theta: 0.9313
## 
## Residuals:
##    Min. 1st Qu.  Median 3rd Qu.    Max. 
## -601947 -145039   18713  154903  483623 
## 
## Coefficients:
##                Estimate  Std. Error z-value  Pr(>|z|)    
## (Intercept)  1.0752e+06  4.4535e+05  2.4142   0.01577 *  
## Q            3.2323e+06  1.6521e+05 19.5652 < 2.2e-16 ***
## PF           8.0229e-01  9.5804e-02  8.3743 < 2.2e-16 ***
## LF          -3.7338e+06  6.0963e+05 -6.1247 9.084e-10 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Total Sum of Squares:    5.1133e+13
## Residual Sum of Squares: 3.7726e+12
## R-Squared:      0.92622
## Adj. R-Squared: 0.92365
## Chisq: 1079.63 on 3 DF, p-value: < 2.22e-16

Comparando sus R2 Ajustadas, el mejor método en el modelo de efectos aleatorios es el de Walhus.

Efectos Fijos vs Efectos Aleatorios

phtest(within,walhus)
## 
##  Hausman Test
## 
## data:  C ~ Q + PF + LF
## chisq = 65.039, df = 3, p-value = 4.919e-14
## alternative hypothesis: one model is inconsistent
df_a1 <- df[df$I == "1" ,]
ts_a1 <- ts(df_a1$C, start = 1970, frequency = 1)

df_a2 <- df[df$I == "1" ,]
ts_a2 <- ts(df_a2$C, start = 1970, frequency = 1)

df_a3 <- df[df$I == "1" ,]
ts_a3 <- ts(df_a3$C, start = 1970, frequency = 1)

df_a4 <- df[df$I == "1" ,]
ts_a4 <- ts(df_a4$C, start = 1970, frequency = 1)

df_a5 <- df[df$I == "1" ,]
ts_a5 <- ts(df_a5$C, start = 1970, frequency = 1)

df_a6 <- df[df$I == "1" ,]
ts_a6 <- ts(df_a6$C, start = 1970, frequency = 1)
arima_a1 <- auto.arima(ts_a1)
summary(arima_a1)
## Series: ts_a1 
## ARIMA(0,1,0) with drift 
## 
## Coefficients:
##           drift
##       257691.43
## s.e.   44509.37
## 
## sigma^2 = 2.987e+10:  log likelihood = -188.19
## AIC=380.37   AICc=381.46   BIC=381.65
## 
## Training set error measures:
##                    ME   RMSE      MAE       MPE     MAPE     MASE      ACF1
## Training set 58.86321 160892 129527.1 -1.742419 5.395122 0.502644 0.4084903
arima_a2 <- auto.arima(ts_a2)
summary(arima_a2)
## Series: ts_a2 
## ARIMA(0,1,0) with drift 
## 
## Coefficients:
##           drift
##       257691.43
## s.e.   44509.37
## 
## sigma^2 = 2.987e+10:  log likelihood = -188.19
## AIC=380.37   AICc=381.46   BIC=381.65
## 
## Training set error measures:
##                    ME   RMSE      MAE       MPE     MAPE     MASE      ACF1
## Training set 58.86321 160892 129527.1 -1.742419 5.395122 0.502644 0.4084903
arima_a3 <- auto.arima(ts_a3)
summary(arima_a3)
## Series: ts_a3 
## ARIMA(0,1,0) with drift 
## 
## Coefficients:
##           drift
##       257691.43
## s.e.   44509.37
## 
## sigma^2 = 2.987e+10:  log likelihood = -188.19
## AIC=380.37   AICc=381.46   BIC=381.65
## 
## Training set error measures:
##                    ME   RMSE      MAE       MPE     MAPE     MASE      ACF1
## Training set 58.86321 160892 129527.1 -1.742419 5.395122 0.502644 0.4084903
arima_a4 <- auto.arima(ts_a4)
summary(arima_a4)
## Series: ts_a4 
## ARIMA(0,1,0) with drift 
## 
## Coefficients:
##           drift
##       257691.43
## s.e.   44509.37
## 
## sigma^2 = 2.987e+10:  log likelihood = -188.19
## AIC=380.37   AICc=381.46   BIC=381.65
## 
## Training set error measures:
##                    ME   RMSE      MAE       MPE     MAPE     MASE      ACF1
## Training set 58.86321 160892 129527.1 -1.742419 5.395122 0.502644 0.4084903
arima_a5 <- auto.arima(ts_a5)
summary(arima_a5)
## Series: ts_a5 
## ARIMA(0,1,0) with drift 
## 
## Coefficients:
##           drift
##       257691.43
## s.e.   44509.37
## 
## sigma^2 = 2.987e+10:  log likelihood = -188.19
## AIC=380.37   AICc=381.46   BIC=381.65
## 
## Training set error measures:
##                    ME   RMSE      MAE       MPE     MAPE     MASE      ACF1
## Training set 58.86321 160892 129527.1 -1.742419 5.395122 0.502644 0.4084903
arima_a6 <- auto.arima(ts_a6)
summary(arima_a6)
## Series: ts_a6 
## ARIMA(0,1,0) with drift 
## 
## Coefficients:
##           drift
##       257691.43
## s.e.   44509.37
## 
## sigma^2 = 2.987e+10:  log likelihood = -188.19
## AIC=380.37   AICc=381.46   BIC=381.65
## 
## Training set error measures:
##                    ME   RMSE      MAE       MPE     MAPE     MASE      ACF1
## Training set 58.86321 160892 129527.1 -1.742419 5.395122 0.502644 0.4084903

Generar el Pronóstico

pronostico_a6 <- forecast(arima_a6, level = 95, h=5)
pronostico_a6
##      Point Forecast   Lo 95   Hi 95
## 1985        5006011 4667279 5344744
## 1986        5263703 4784663 5742743
## 1987        5521394 4934693 6108096
## 1988        5779086 5101621 6456550
## 1989        6036777 5279349 6794206
plot(pronostico_a6, main="Pronóstico de costo total (en miles)", xlab="Año", ylab="Dólares")

Tema 3. Modelo de Ecuaciones Estructurales

modelo <- '
            # Regresiones
            C ~ Q + PF + LF + I + Y
            Q ~ PF + I
            PF ~ Y
            LF ~ I
            # Variables Latentes
            # Varianzas y Covarianzas
            C ~~ C
            Q ~~ Q
            PF ~~ PF
            LF ~~ LF
            # Intercepto
          '

Generar el Analisis Factorial confirmatorio (CFA)

df_escalada <- df
df_escalada$I <- as.numeric(df_escalada$I)
df_escalada <- scale(df_escalada)
cfa <- cfa(modelo, df_escalada)
summary(cfa)
## lavaan 0.6-19 ended normally after 2 iterations
## 
##   Estimator                                         ML
##   Optimization method                           NLMINB
##   Number of model parameters                        13
## 
##   Number of observations                            90
## 
## Model Test User Model:
##                                                       
##   Test statistic                                63.804
##   Degrees of freedom                                 5
##   P-value (Chi-square)                           0.000
## 
## Parameter Estimates:
## 
##   Standard errors                             Standard
##   Information                                 Expected
##   Information saturated (h1) model          Structured
## 
## Regressions:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   C ~                                                 
##     Q                 1.000    0.053   18.826    0.000
##     PF                0.194    0.065    3.000    0.003
##     LF               -0.154    0.025   -6.248    0.000
##     I                 0.105    0.052    1.999    0.046
##     Y                 0.140    0.063    2.211    0.027
##   Q ~                                                 
##     PF                0.239    0.046    5.213    0.000
##     I                -0.871    0.046  -18.985    0.000
##   PF ~                                                
##     Y                 0.931    0.038   24.233    0.000
##   LF ~                                                
##     I                -0.340    0.099   -3.429    0.001
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .C                 0.048    0.007    6.708    0.000
##    .Q                 0.187    0.028    6.708    0.000
##    .PF                0.131    0.020    6.708    0.000
##    .LF                0.875    0.130    6.708    0.000
lavaanPlot(cfa)

Aplicación de Shiny

Link de la Aplicación

LS0tCnRpdGxlOiAiQWN0aXZpZGFkIDQuIENhc28gZGUgTmVnb2NpbyAxLiBDb3N0b3MgZW4gQWVyb2zDrW5lYXMiCmF1dGhvcjogIkdlbmFybyBSb2Ryw61ndWV6IEFsY8OhbnRhcmEgLSBBMDA4MzMxNzIiCmRhdGU6ICIyMDI1LTAyLTIwIgpvdXRwdXQ6IAogIGh0bWxfZG9jdW1lbnQ6CiAgICB0b2M6IHRydWUKICAgIHRvY19mbG9hdDogdHJ1ZQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQogICAgdGhlbWU6IGNlcnVsZWFuCi0tLQoKIyFbXSgvVXNlcnMvZ2VuYXJvcm9kcmlndWV6YWxjYW50YXJhL0Rlc2t0b3AvVGVjL0dlbmVyYWNpb24gZGUgZXNjZW5hcmlvcyBmdXR1cm9zIGNvbiBhbmFsacyBdGljYSAoR3BvIDEwMSkvUElCL0FjdGl2aWRhZC00X0Nhc28tZGUtTmVnb2Npby0xX0Nvc3Rvcy1lbi1BZXJvbGnMgW5lYXMvYTNmM2I3MjczZTE0MDNiYjg5MjM4NTdiZDM2NzEzODAuZ2lmKQoKIyA8c3BhbiBzdHlsZT0iY29sb3I6IGJyb3duOyI+Q29udGV4dG88L3NwYW4+CkxhIGJhc2UgZGUgZGF0b3MgZXMgZGUgbGEgdW5pdmVyc2lkYWQgZGUgbnVldmEgWW9yayB5IGNvbnRpZW5lIDkwIG9ic2VydmFjaW9uZXMgcXVlIGluY2x1eWVuIGxvcyBjb3N0b3MgZGUgNiBhZXJvbGluZWFzIGVzdGFkb3VuaWRlbnNlcyBkdXJhbnRlIDE1IGHDsW9zLCBkZSAxOTcwIGEgMTk4NC4KCkxhcyB2YXJpYWJsZXMgc29uOgoKKiBJID0gQWVyb2xpbmVhCiogVCA9IEHDsW8KKiBRID0gT3V0cHV0CiogQyA9IENvc3RvIHRvdGFsIGVuICQxLDAwMAoqIFBGID0gUHJlY2lvIGRlbCBDb21idXN0aWJsZQoqIExGID0gRmFjdG9yIGRlIENhcmdhCgojIDxzcGFuIHN0eWxlPSJjb2xvcjogYnJvd247Ij5JbnN0YWxhciBwYXF1ZXRlcyB5IGxsYW1hciBsaWJyZXLDrWFzPC9zcGFuPgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpsaWJyYXJ5KHBsbSkKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoZm9yZWNhc3QpCmxpYnJhcnkobGF2YWFuKQpsaWJyYXJ5KGxhdmFhblBsb3QpCmxpYnJhcnkoRGF0YUV4cGxvcmVyKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoZ3Bsb3RzKQpgYGAKCiMgPHNwYW4gc3R5bGU9ImNvbG9yOiBicm93bjsiPkJhc2UgZGUgRGF0b3M8L3NwYW4+CmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmRmIDwtIHJlYWQuY3N2KCIvVXNlcnMvZ2VuYXJvcm9kcmlndWV6YWxjYW50YXJhL0Rlc2t0b3AvVGVjL0dlbmVyYWNpb24gZGUgZXNjZW5hcmlvcyBmdXR1cm9zIGNvbiBhbmFsacyBdGljYSAoR3BvIDEwMSkvUElCL0FjdGl2aWRhZC00X0Nhc28tZGUtTmVnb2Npby0xX0Nvc3Rvcy1lbi1BZXJvbGnMgW5lYXMvQ29zdCBEYXRhIGZvciBVLlMuIEFpcmxpbmVzLmNzdiIpCmBgYAoKIyA8c3BhbiBzdHlsZT0iY29sb3I6IGJyb3duOyI+QW7DoWxpc2lzIEV4cGxvcmF0b3Jpbzwvc3Bhbj4KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0Kc3VtbWFyeShkZikKc3RyKGRmKQpoZWFkKGRmKQpkZiRJIDwtIGFzLmZhY3RvcihkZiRJKQpkZiRZIDwtIGRmJFQgKyAxOTY5CgpzdW1tYXJ5KGRmKQpzdHIoZGYpCmhlYWQoZGYpCmNyZWF0ZV9yZXBvcnQKYGBgCgojIyA8c3BhbiBzdHlsZT0iY29sb3I6IGJyb3duOyI+R3LDoWZpY2FzPC9zcGFuPgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojY3JlYXRlX3JlcG9ydChkZikKcGxvdF9taXNzaW5nKGRmKQpwbG90X2hpc3RvZ3JhbShkZikKcGxvdF9jb3JyZWxhdGlvbihkZikKYGBgCgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpnZ3Bsb3QoZGYsIGFlcyh4ID0gWSwgeSA9IEMsIGNvbG9yID0gSSwgZ3JvdXAgPSBJKSkgKyAKICBnZW9tX2xpbmUoKSArCiAgbGFicyh0aXRsZSA9ICJDb3N0byBwb3IgQWVyb2xpbmVhIChlbiBtaWxlcykiLCB4ID0gIkHDsW8iLCB5ID0gIkNvc3RvIChVU0QpIiwgY29sb3IgPSAiQWVyb2xpbmVhIikgKyAKICB0aGVtZV9taW5pbWFsKCkKCmdncGxvdChkZiwgYWVzKHggPSBZLCB5ID0gUSwgY29sb3IgPSBJLCBncm91cCA9IEkpKSArIAogIGdlb21fbGluZSgpICsKICBsYWJzKHRpdGxlID0gIk1pbGxhcyBWb2xhZGFzIChwb3IgcGFzYWplcm8pIiwgeCA9ICJBw7FvIiwgeSA9ICJJbmRpY2UgTm9ybWFsaXphZG8iLCBjb2xvciA9ICJBZXJvbGluZWEiKSArIAogIHRoZW1lX21pbmltYWwoKQoKZ2dwbG90KGRmLCBhZXMoeCA9IFksIHkgPSBQRiwgY29sb3IgPSBJLCBncm91cCA9IEkpKSArIAogIGdlb21fbGluZSgpICsKICBsYWJzKHRpdGxlID0gIlByZWNpbyBkZWwgQ29tYnVzdGlibGUiLCB4ID0gIkHDsW8iLCB5ID0gIkNvc3RvIChVU0QpIiwgY29sb3IgPSAiQWVyb2xpbmVhIikgKyAKICB0aGVtZV9taW5pbWFsKCkKCmdncGxvdChkZiwgYWVzKHggPSBZLCB5ID0gTEYsIGNvbG9yID0gSSwgZ3JvdXAgPSBJKSkgKyAKICBnZW9tX2xpbmUoKSArCiAgbGFicyh0aXRsZSA9ICJGYWN0b3IgZGUgQ2FyZ2EiLCB4ID0gIkHDsW8iLCB5ID0gIlBvcmNlbnRhamUiLCBjb2xvciA9ICJBZXJvbGluZWEiKSArIAogIHRoZW1lX21pbmltYWwoKQpgYGAKIyA8c3BhbiBzdHlsZT0iY29sb3I6IGJyb3duOyI+VGVtYSAxLiBEYXRvcyBkZSBQYW5lbDwvc3Bhbj4KIyMgPHNwYW4gc3R5bGU9ImNvbG9yOiBicm93bjsiPkhldGVyb2dlbmVpZGFkPC9zcGFuPgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpwbG90bWVhbnMoQ35JLCBtYWluID0gIkhldGVyb2dlbmVpZGFkIGVudHJlIEFlcm9saW5lYXMiLCB4bGFiID0gIkFlcm9saW5lYSIsIHlsYWIgPSAiQ29zdG8gKE1pbGVzIGRlIFVTRCkiLCBkYXRhID0gZGYpCmBgYAoKQ29tbyBlbCB2YWxvciBwcm9tZWRpbyAoY8OtcmN1bG8pIHkgZWwgcmFuZ28gaW50ZXJjdWFydGlsIChsw61lYXMgYXp1bGVzKSB2YXLDrWFuIGVudHJlIGluZGl2aWR1b3MsIHNlIG9ic2VydmEgKipwcmVzZW5jaWEgZGUgaGV0ZXJvZ2VuZWlkYWQqKi4gCgojIDxzcGFuIHN0eWxlPSJjb2xvcjogYnJvd247Ij5DcmVhY2lvbiBkZSBEYXRvcyBkZSBQYW5lbDwvc3Bhbj4KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KZGZfcGFuZWwgPC0gcGRhdGEuZnJhbWUoZGYsIGluZGV4ID0gYygiSSIsICJZIikpCmRmX3BhbmVsIDwtIGRmX3BhbmVsICU+JSBzZWxlY3QoLWMoIkkiLCAiVCIsICJZIikpCmBgYAoKIyMgPHNwYW4gc3R5bGU9ImNvbG9yOiBicm93bjsiPk1vZGVsbyAxLiBSZWdyZXNzaW9uIEFncnVwYWRhIChQb29sZWQpPC9zcGFuPgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIEVsIG1vZGVsbyBkZSBSZWdyZXNpw7NuIEFncnVwYWRhIChwb29sZWQpIGVzIHVuYSB0w6ljbmljYSBkZSBlc3RpbWFjacOzbiBkZSBkYXRvcyBkZSBwYW5lbCBkb25kZSBzZSBzYXN1bWUgcXVlIG5vIGhheSBlZmVjdG9zIGluZGl2aWR1YWxlcyBlc3BlY2lmaWNvcyBwYXJhIGNhZGEgdW5pZGFkIChFai4gQWVyb2xpbmVhcykgbmkgdmFyaWFjaW9uZXMgZW4gZWwgdGllbXBvLiBJZ25vcmEgaGV0ZXJvZ2VuZWlkYWQuCnBvb2xlZCA8LSBwbG0oQyB+IFEgKyBQRiArIExGLCBkYXRhID0gZGZfcGFuZWwsIG1vZGVsID0gInBvb2xpbmciKQpzdW1tYXJ5KHBvb2xlZCkKCiMgUHJ1ZWJhIGRlIEJyZXVzY2gtUGFnYW4gKEJQKTogUGFyYSB2ZXJ1ZnVjYXIgc2kgZWxtb2RlbG8gcG9vbGVkIGVzIGFkZWN1YWRvLgojIHAtdmFsdWUgPCAwLjA1IEF2YW56YW1vcyBwYXJhIHVzYXIgdW4gbW9kZWxvIGRlIEVmZWN0b3MgRmlqb3MgbyBBbGVhdG9yaW9zCiMgcC12YWx1ZSA+IDAuMDUgUG9kZW1vcyB1c2FyIGVsIG1vZGVsbyBQb29sZWQuCgpwbG10ZXN0KHBvb2xlZCwgdHlwZSA9ICJicCIpCmBgYAoKRXN0ZSBtb2RlbG8gdGllbmUgdW4gcC12YWx1ZSBtYXlvciBhIDAuMDUsIGxvIHF1ZSBub3MgZGljZSBxdWUgcG9kZW1vcyB1dGlsaXphciBlbCBtb2RlbG8gUG9vbGVkLgoKCiMjIDxzcGFuIHN0eWxlPSJjb2xvcjogYnJvd247Ij5Nb2RlbG8gMi4gRWZlY3RvcyBGaWpvcyAoV2l0aGluKTwvc3Bhbj4KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0Kd2l0aGluIDwtIHBsbShDIH4gUSArIFBGICsgTEYsIGRhdGEgPSBkZl9wYW5lbCwgbW9kZWwgPSAid2l0aGluIikKc3VtbWFyeSh3aXRoaW4pCmBgYAoKIyMgPHNwYW4gc3R5bGU9ImNvbG9yOiBicm93bjsiPk1vZGVsbyAzLiBFZmVjdG9zIEFsZWF0b3Jpb3MgKHJhbmRvbSkgTcOpdG9kbyBXYWxodXM8L3NwYW4+CmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CndhbGh1cyA8LSBwbG0oQyB+IFEgKyBQRiArIExGLCBkYXRhID0gZGZfcGFuZWwsIG1vZGVsID0gInJhbmRvbSIsIHJhbmRvbS5tZXRob2QgPSAid2FsaHVzIikKc3VtbWFyeSh3YWxodXMpCmBgYAoKIyMgPHNwYW4gc3R5bGU9ImNvbG9yOiBicm93bjsiPk1vZGVsbyA0LiBFZmVjdG9zIEFsZWF0b3Jpb3MgKHJhbmRvbSkgTcOpdG9kbyBBbWVtaXlhPC9zcGFuPgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQphbWVtaXlhIDwtIHBsbShDIH4gUSArIFBGICsgTEYsIGRhdGEgPSBkZl9wYW5lbCwgbW9kZWwgPSAicmFuZG9tIiwgcmFuZG9tLm1ldGhvZCA9ICJhbWVtaXlhIikKc3VtbWFyeShhbWVtaXlhKQpgYGAKCiMjIDxzcGFuIHN0eWxlPSJjb2xvcjogYnJvd247Ij5Nb2RlbG8gNS4gRWZlY3RvcyBBbGVhdG9yaW9zIChyYW5kb20pIE3DqXRvZG8gTmVybG92ZTwvc3Bhbj4KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KbmVybG92ZSA8LSBwbG0oQyB+IFEgKyBQRiArIExGLCBkYXRhID0gZGZfcGFuZWwsIG1vZGVsID0gInJhbmRvbSIsIHJhbmRvbS5tZXRob2QgPSAibmVybG92ZSIpCnN1bW1hcnkobmVybG92ZSkKYGBgCgpDb21wYXJhbmRvIHN1cyBSMiBBanVzdGFkYXMsIGVsIG1lam9yIG3DqXRvZG8gZW4gZWwgbW9kZWxvIGRlIGVmZWN0b3MgYWxlYXRvcmlvcyBlcyBlbCBkZSAqKldhbGh1cyoqLgoKIyMgPHNwYW4gc3R5bGU9ImNvbG9yOiBicm93bjsiPkVmZWN0b3MgRmlqb3MgdnMgRWZlY3RvcyBBbGVhdG9yaW9zPC9zcGFuPgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpwaHRlc3Qod2l0aGluLHdhbGh1cykKYGBgCgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpkZl9hMSA8LSBkZltkZiRJID09ICIxIiAsXQp0c19hMSA8LSB0cyhkZl9hMSRDLCBzdGFydCA9IDE5NzAsIGZyZXF1ZW5jeSA9IDEpCgpkZl9hMiA8LSBkZltkZiRJID09ICIxIiAsXQp0c19hMiA8LSB0cyhkZl9hMiRDLCBzdGFydCA9IDE5NzAsIGZyZXF1ZW5jeSA9IDEpCgpkZl9hMyA8LSBkZltkZiRJID09ICIxIiAsXQp0c19hMyA8LSB0cyhkZl9hMyRDLCBzdGFydCA9IDE5NzAsIGZyZXF1ZW5jeSA9IDEpCgpkZl9hNCA8LSBkZltkZiRJID09ICIxIiAsXQp0c19hNCA8LSB0cyhkZl9hNCRDLCBzdGFydCA9IDE5NzAsIGZyZXF1ZW5jeSA9IDEpCgpkZl9hNSA8LSBkZltkZiRJID09ICIxIiAsXQp0c19hNSA8LSB0cyhkZl9hNSRDLCBzdGFydCA9IDE5NzAsIGZyZXF1ZW5jeSA9IDEpCgpkZl9hNiA8LSBkZltkZiRJID09ICIxIiAsXQp0c19hNiA8LSB0cyhkZl9hNiRDLCBzdGFydCA9IDE5NzAsIGZyZXF1ZW5jeSA9IDEpCmBgYAoKYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KYXJpbWFfYTEgPC0gYXV0by5hcmltYSh0c19hMSkKc3VtbWFyeShhcmltYV9hMSkKCmFyaW1hX2EyIDwtIGF1dG8uYXJpbWEodHNfYTIpCnN1bW1hcnkoYXJpbWFfYTIpCgphcmltYV9hMyA8LSBhdXRvLmFyaW1hKHRzX2EzKQpzdW1tYXJ5KGFyaW1hX2EzKQoKYXJpbWFfYTQgPC0gYXV0by5hcmltYSh0c19hNCkKc3VtbWFyeShhcmltYV9hNCkKCmFyaW1hX2E1IDwtIGF1dG8uYXJpbWEodHNfYTUpCnN1bW1hcnkoYXJpbWFfYTUpCgphcmltYV9hNiA8LSBhdXRvLmFyaW1hKHRzX2E2KQpzdW1tYXJ5KGFyaW1hX2E2KQpgYGAKCiMjIDxzcGFuIHN0eWxlPSJjb2xvcjogYnJvd247Ij5HZW5lcmFyIGVsIFByb27Ds3N0aWNvPC9zcGFuPgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpwcm9ub3N0aWNvX2E2IDwtIGZvcmVjYXN0KGFyaW1hX2E2LCBsZXZlbCA9IDk1LCBoPTUpCnByb25vc3RpY29fYTYKCnBsb3QocHJvbm9zdGljb19hNiwgbWFpbj0iUHJvbsOzc3RpY28gZGUgY29zdG8gdG90YWwgKGVuIG1pbGVzKSIsIHhsYWI9IkHDsW8iLCB5bGFiPSJEw7NsYXJlcyIpCmBgYAoKIyA8c3BhbiBzdHlsZT0iY29sb3I6IGJyb3duOyI+VGVtYSAzLiBNb2RlbG8gZGUgRWN1YWNpb25lcyBFc3RydWN0dXJhbGVzPC9zcGFuPgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQptb2RlbG8gPC0gJwogICAgICAgICAgICAjIFJlZ3Jlc2lvbmVzCiAgICAgICAgICAgIEMgfiBRICsgUEYgKyBMRiArIEkgKyBZCiAgICAgICAgICAgIFEgfiBQRiArIEkKICAgICAgICAgICAgUEYgfiBZCiAgICAgICAgICAgIExGIH4gSQogICAgICAgICAgICAjIFZhcmlhYmxlcyBMYXRlbnRlcwogICAgICAgICAgICAjIFZhcmlhbnphcyB5IENvdmFyaWFuemFzCiAgICAgICAgICAgIEMgfn4gQwogICAgICAgICAgICBRIH5+IFEKICAgICAgICAgICAgUEYgfn4gUEYKICAgICAgICAgICAgTEYgfn4gTEYKICAgICAgICAgICAgIyBJbnRlcmNlcHRvCiAgICAgICAgICAnCmBgYAoKIyMgPHNwYW4gc3R5bGU9ImNvbG9yOiBicm93bjsiPkdlbmVyYXIgZWwgQW5hbGlzaXMgRmFjdG9yaWFsIGNvbmZpcm1hdG9yaW8gKENGQSk8L3NwYW4+CmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmRmX2VzY2FsYWRhIDwtIGRmCmRmX2VzY2FsYWRhJEkgPC0gYXMubnVtZXJpYyhkZl9lc2NhbGFkYSRJKQpkZl9lc2NhbGFkYSA8LSBzY2FsZShkZl9lc2NhbGFkYSkKY2ZhIDwtIGNmYShtb2RlbG8sIGRmX2VzY2FsYWRhKQpzdW1tYXJ5KGNmYSkKYGBgCgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpsYXZhYW5QbG90KGNmYSkKYGBgCgojIyA8c3BhbiBzdHlsZT0iY29sb3I6IGJyb3duOyI+QXBsaWNhY2nDs24gZGUgU2hpbnk8L3NwYW4+CltMaW5rIGRlIGxhIEFwbGljYWNpw7NuXShodHRwczovL2EwMDgzMzE3Mi5zaGlueWFwcHMuaW8vUElCQi8p