Importar paquetes y llamar librerias

#install.packages("readxl")
library(readxl)
#install.packages("plm")
library(plm)
#install.packages("gplots")
library(gplots)

Parte 1. Patentes

INSTRUCCIONES: Genera el mejor modelo de la Base de Datos “Patentes” y genera predicciones.

df1 <- read_excel("/Users/adriana/Downloads/PATENT 3.xls")
summary(df1)
##      cusip            merger           employ            return       
##  Min.   :   800   Min.   :0.0000   Min.   :  0.085   Min.   :-73.022  
##  1st Qu.:368514   1st Qu.:0.0000   1st Qu.:  1.227   1st Qu.:  5.128  
##  Median :501116   Median :0.0000   Median :  3.842   Median :  7.585  
##  Mean   :514536   Mean   :0.0177   Mean   : 18.826   Mean   :  8.003  
##  3rd Qu.:754688   3rd Qu.:0.0000   3rd Qu.: 15.442   3rd Qu.: 10.501  
##  Max.   :878555   Max.   :1.0000   Max.   :506.531   Max.   : 48.675  
##                                    NAs    :21        NAs    :8        
##     patents         patentsg           stckpr              rnd           
##  Min.   :  0.0   Min.   :   0.00   Min.   :  0.1875   Min.   :   0.0000  
##  1st Qu.:  1.0   1st Qu.:   1.00   1st Qu.:  7.6250   1st Qu.:   0.6847  
##  Median :  3.0   Median :   4.00   Median : 16.5000   Median :   2.1456  
##  Mean   : 22.9   Mean   :  27.14   Mean   : 22.6270   Mean   :  29.3398  
##  3rd Qu.: 15.0   3rd Qu.:  19.00   3rd Qu.: 29.2500   3rd Qu.:  11.9168  
##  Max.   :906.0   Max.   :1063.00   Max.   :402.0000   Max.   :1719.3535  
##                                    NAs    :2                             
##     rndeflt             rndstck              sales                sic      
##  Min.   :   0.0000   Min.   :   0.1253   Min.   :    1.222   Min.   :2000  
##  1st Qu.:   0.4788   1st Qu.:   5.1520   1st Qu.:   52.995   1st Qu.:2890  
##  Median :   1.4764   Median :  13.3532   Median :  174.065   Median :3531  
##  Mean   :  19.7238   Mean   : 163.8234   Mean   : 1219.601   Mean   :3333  
##  3rd Qu.:   8.7527   3rd Qu.:  74.5625   3rd Qu.:  728.964   3rd Qu.:3661  
##  Max.   :1000.7876   Max.   :9755.3516   Max.   :44224.000   Max.   :9997  
##                      NAs    :157         NAs    :3                         
##       year     
##  Min.   :2012  
##  1st Qu.:2014  
##  Median :2016  
##  Mean   :2016  
##  3rd Qu.:2019  
##  Max.   :2021  
## 
#patents y rnd están muy sesgados: la mitad de las empresas tiene 3 patentes o menos, pero hay una con 906; y hay 538 filas con 0 patentes. Con datos así, un modelo en niveles no es buena idea, por eso usamos logaritmos (log(x+1) para poder incluir los ceros).
df1$log_patents <- log(df1$patents + 1)
df1$log_rnd <- log(df1$rnd + 1)
df1 <- pdata.frame(df1, index = c("cusip", "year"))
modelo_regresion <- lm(log_patents ~ log_rnd, data = df1)
summary(modelo_regresion) #En logaritmos el modelo ajusta mucho mejor (R2 de 0.60 contra 0.31 en niveles) y los residuos son mucho más chicos y estables.
## 
## Call:
## lm(formula = log_patents ~ log_rnd, data = df1)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -3.5640 -0.6233  0.0149  0.6954  2.8844 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  0.40127    0.03046   13.18   <2e-16 ***
## log_rnd      0.79002    0.01344   58.77   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.9754 on 2258 degrees of freedom
## Multiple R-squared:  0.6047, Adjusted R-squared:  0.6046 
## F-statistic:  3454 on 1 and 2258 DF,  p-value: < 2.2e-16
#Prueba de Heterogeneidad
plotmeans(log_patents ~ cusip, data = df1)

#INTERPRETACIÓN: La línea no es horizontal: hay empresas con muchas más patentes que otras, así que sí hay heterogeneidad.
# Opcion 1 - Modelo de Regresión Agrupada (Pooled)
pooled <- plm(log_patents ~ log_rnd, data = df1, model = "pooling")
summary(pooled)
## Pooling Model
## 
## Call:
## plm(formula = log_patents ~ log_rnd, data = df1, model = "pooling")
## 
## Balanced Panel: n = 226, T = 10, N = 2260
## 
## Residuals:
##    Min. 1st Qu.  Median 3rd Qu.    Max. 
## -3.5640 -0.6233  0.0149  0.6954  2.8844 
## 
## Coefficients:
##             Estimate Std. Error t-value  Pr(>|t|)    
## (Intercept) 0.401272   0.030457  13.175 < 2.2e-16 ***
## log_rnd     0.790021   0.013441  58.775 < 2.2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Total Sum of Squares:    5435.2
## Residual Sum of Squares: 2148.4
## R-Squared:      0.60473
## Adj. R-Squared: 0.60455
## F-statistic: 3454.49 on 1 and 2258 DF, p-value: < 2.22e-16
#Opcion 2 - Modelo de Efectos Fijos (within)
within <- plm(log_patents ~ log_rnd, data = df1, model = "within")
summary(within)
## Oneway (individual) effect Within Model
## 
## Call:
## plm(formula = log_patents ~ log_rnd, data = df1, model = "within")
## 
## Balanced Panel: n = 226, T = 10, N = 2260
## 
## Residuals:
##    Min. 1st Qu.  Median 3rd Qu.    Max. 
## -2.7726 -0.2953  0.0371  0.3467  1.7910 
## 
## Coefficients:
##          Estimate Std. Error t-value  Pr(>|t|)    
## log_rnd -0.522079   0.036694 -14.228 < 2.2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Total Sum of Squares:    777.46
## Residual Sum of Squares: 707.06
## R-Squared:      0.090556
## Adj. R-Squared: -0.010543
## F-statistic: 202.432 on 1 and 2033 DF, p-value: < 2.22e-16
#Prueba F
#INTERPRETACIÓN: Si la p es menor a 0.05 no usar POOLED, si p es mayor a 0.05 usar pooled.
pFtest(within, pooled) 
## 
##  F test for individual effects
## 
## data:  log_patents ~ log_rnd
## F = 18.419, df1 = 225, df2 = 2033, p-value < 2.2e-16
## alternative hypothesis: significant effects
#Opcion 3 - Modelo de Efectos Aleatorios (Random)
random <- plm(log_patents ~ log_rnd, data = df1, model = "random")
summary(random)
## Oneway (individual) effect Random Effect Model 
##    (Swamy-Arora's transformation)
## 
## Call:
## plm(formula = log_patents ~ log_rnd, data = df1, model = "random")
## 
## Balanced Panel: n = 226, T = 10, N = 2260
## 
## Effects:
##                  var std.dev share
## idiosyncratic 0.3478  0.5897 0.465
## individual    0.3999  0.6324 0.535
## theta: 0.7171
## 
## Residuals:
##    Min. 1st Qu.  Median 3rd Qu.    Max. 
## -3.0612 -0.4923  0.0738  0.5252  1.8901 
## 
## Coefficients:
##             Estimate Std. Error z-value  Pr(>|z|)    
## (Intercept) 1.193600   0.068539  17.415 < 2.2e-16 ***
## log_rnd     0.316866   0.026990  11.740 < 2.2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Total Sum of Squares:    1150.1
## Residual Sum of Squares: 1084
## R-Squared:      0.057528
## Adj. R-Squared: 0.05711
## Chisq: 137.826 on 1 DF, p-value: < 2.22e-16
#Prueba de Hausman
#INTERPRETACIÓN: Si la p es menor a 0.05 usar efectos fijos, si sale mayor usar efectos aleatorios.
phtest(random, within) 
## 
##  Hausman Test
## 
## data:  log_patents ~ log_rnd
## chisq = 1138.9, df = 1, p-value < 2.2e-16
## alternative hypothesis: one model is inconsistent
#Por lo tanto, el mejor modelo para este panel es el de EFECTOS FIJOS. La prueba F rechaza Pooled (sí hay heterogeneidad) y la prueba de Hausman rechaza Aleatorios (esa heterogeneidad está correlacionada con el gasto en I+D: las empresas que más patentan también son las que más invierten).
#Pronóstico: como el modelo está en logaritmos, hay que "devolver" la predicción a patentes con exp()-1 al final
df1_pronostico <- data.frame(
  cusip = c("149123", "369604", "459200"),
  year = c(2022, 2022, 2022),
  rnd = c(226.5315, 813.7559, 1611.4912) * 1.10
)
df1_pronostico$log_rnd <- log(df1_pronostico$rnd + 1)
intercepto <- fixef(within)
pendiente <- coef(within)["log_rnd"]
df1_pronostico$log_patentes <- intercepto[df1_pronostico$cusip] + pendiente * df1_pronostico$log_rnd
df1_pronostico$patentes <- exp(df1_pronostico$log_patentes) - 1
df1_pronostico[, c("cusip","patentes")]
##    cusip patentes
## 1 149123 141.5081
## 2 369604 498.0288
## 3 459200 281.9298

CONCLUSIÓN: El mejor modelo sigue siendo el de Efectos Fijos, pero usando logaritmos en vez de niveles, porque patents y rnd están muy sesgados (pocas empresas concentran la mayoría de las patentes y del gasto). En logaritmos el modelo ajusta mucho mejor y el coeficiente se interpreta como elasticidad: cuánto cambia el % de patentes por cada % de cambio en I+D. Revisando los datos empresa por empresa encontré algo importante: 2021 (el último año de la base) tiene una caída rarísima en patentes para casi todas las empresas grandes, después de años estables en cientos — es un problema típico de las bases de patentes, donde el último año sale bajo porque el trámite tarda y muchas patentes recientes todavía no se habían registrado cuando se armó la base. Por eso el pronóstico 2022 sale más alto que las patentes “oficiales” de 2021: el modelo se basa en el nivel histórico normal de cada empresa, no en ese último año atípico.

Parte 2. Cuidado de la piel

INSTRUCCIONES: ¿En cuál categoría invertirías y por qué? Si tuvieras que invertir en alguna subcategoría, ¿en cuál lo harías? Justifica de acuerdo al modelo.

df2_excel <- read_excel("/Users/adriana/Downloads/Market sizes.xls")
summary(df2_excel)
##      Geography       Category      Data Type         Unit     Current Constant
##  Length   :13   Length   :13   Length   :13   Length   :13   Length   :13     
##  N.unique : 1   N.unique :13   N.unique : 1   N.unique : 1   N.unique : 1     
##  N.blank  : 0   N.blank  : 0   N.blank  : 0   N.blank  : 0   N.blank  : 0     
##  Min.nchar: 6   Min.nchar: 8   Min.nchar:16   Min.nchar:11   Min.nchar:14     
##  Max.nchar: 6   Max.nchar:39   Max.nchar:16   Max.nchar:11   Max.nchar:14     
##                                                                               
##         2011           2012           2013           2014           2015   
##  Length   :13   Length   :13   Length   :13   Length   :13   Length   :13  
##  N.unique :12   N.unique :12   N.unique :12   N.unique :12   N.unique :12  
##  N.blank  : 0   N.blank  : 0   N.blank  : 0   N.blank  : 0   N.blank  : 0  
##  Min.nchar: 1   Min.nchar: 1   Min.nchar: 1   Min.nchar: 1   Min.nchar: 1  
##  Max.nchar:18   Max.nchar:18   Max.nchar:18   Max.nchar:18   Max.nchar:18  
##                                                                            
##       2016             2017             2018             2019       
##  Min.   :  1188   Min.   :  1320   Min.   :  1439   Min.   :  1516  
##  1st Qu.: 11482   1st Qu.: 12123   1st Qu.: 12490   1st Qu.: 12960  
##  Median : 21783   Median : 24478   Median : 26344   Median : 27806  
##  Mean   : 37710   Mean   : 40692   Mean   : 42891   Mean   : 44853  
##  3rd Qu.: 32384   3rd Qu.: 34260   3rd Qu.: 35597   3rd Qu.: 37247  
##  Max.   :170488   Max.   :183580   Max.   :192727   Max.   :200916  
##       2020             2021             2022             2023       
##  Min.   :  1491   Min.   :  1564   Min.   :  1689   Min.   :  1850  
##  1st Qu.: 13835   1st Qu.: 15091   1st Qu.: 16815   1st Qu.: 19001  
##  Median : 23213   Median : 30225   Median : 37173   Median : 43366  
##  Mean   : 42589   Mean   : 47822   Mean   : 53823   Mean   : 61738  
##  3rd Qu.: 36951   3rd Qu.: 39555   3rd Qu.: 42739   3rd Qu.: 46900  
##  Max.   :191490   Max.   :211921   Max.   :236406   Max.   :268852  
##       2024             2025       
##  Min.   :  1802   Min.   :  1873  
##  1st Qu.: 20235   1st Qu.: 21342  
##  Median : 47334   Median : 49508  
##  Mean   : 68537   Mean   : 72844  
##  3rd Qu.: 53798   3rd Qu.: 58846  
##  Max.   :296120   Max.   :313593
df2 <- data.frame(
  categoria = c(rep("Bath and Shower",15), rep("Deodorants",15), rep("Depilatories",15),
                rep("Fragrances",15), rep("Hair Care",15), rep("Mens Grooming",15),
                rep("Skin Care",15), rep("Sun Care",15)),
  anio = rep(2011:2025, 8),
  valor = c(
    8410.4, 9085, 9711.1, 10226.9, 10814.8, 11481.6, 12123.1, 12490.1, 12959.5, 14633.9, 15469.3, 16815.3, 19001, 20234.6, 21341.7,
    9151, 10148.3, 10697.7, 11469.7, 12379.2, 13723.4, 14891.6, 15913.6, 16745.1, 13834.8, 15091.1, 17872.4, 19454.9, 20787.8, 21824.1,
    802.5, 897.7, 969.9, 1036.3, 1106.4, 1187.9, 1319.5, 1439.1, 1516.1, 1491.2, 1563.5, 1688.6, 1850.2, 1802, 1872.8,
    18727.9, 19957.2, 20651.8, 20979.6, 22567.6, 24208.9, 26152.3, 27536, 28483.1, 25516.1, 31800.8, 37172.8, 45318.9, 51579.2, 56742.1,
    24853.9, 26565.6, 27672.5, 29154.6, 30416.2, 32383.6, 34260, 35597.2, 37247.4, 36950.7, 39554.7, 42738.8, 46900.3, 53024.9, 56289.8,
    18672.1, 20694.4, 22133.4, 23175.3, 24774, 27446, 29497.2, 31498.1, 32693.3, 29669.4, 32938.6, 37702.4, 43366.2, 47333.8, 49508.4,
    25650.3, 27306.2, 28366.9, 29438.3, 30964, 33054.3, 35787.8, 38067.5, 40637.5, 42196.5, 47980.6, 52939.6, 61023.6, 68590.4, 71830,
    1144.7, 1303.1, 1417.3, 1552.8, 1693.3, 1944.1, 2143.3, 2266.5, 2443.8, 2042.9, 2293.6, 2862, 3736.4, 4183.4, 4326.4
  )
)
df2$t <- df2$anio #copia numérica de anio; anio ya es el índice del panel, así que si lo usamos directo en el modelo R lo vuelve categórico (uno por año) en vez de número, y por eso salían los NA
df2 <- pdata.frame(df2, index = c("categoria","anio"))
modelo_regresion2 <- lm(valor ~ t, data = df2)
summary(modelo_regresion2)
## 
## Call:
## lm(formula = valor ~ t, data = df2)
## 
## Residuals:
##    Min     1Q Median     3Q    Max 
## -30062 -10733   -673  13521  39895 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)    
## (Intercept) -2937049.2   670768.7  -4.379 2.60e-05 ***
## t               1466.2      332.4   4.411 2.29e-05 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 15730 on 118 degrees of freedom
## Multiple R-squared:  0.1415, Adjusted R-squared:  0.1343 
## F-statistic: 19.46 on 1 and 118 DF,  p-value: 2.287e-05
#Prueba de Heterogeneidad
plotmeans(valor ~ categoria, data = df2)

#INTERPRETACIÓN: Skin Care y Hair Care operan en un nivel de mercado mucho más grande que Depilatories o Sun Care: sí hay heterogeneidad.
# Opcion 1 - Modelo de Regresión Agrupada (Pooled)
pooled2 <- plm(valor ~ t, data = df2, model = "pooling")
summary(pooled2)
## Pooling Model
## 
## Call:
## plm(formula = valor ~ t, data = df2, model = "pooling")
## 
## Balanced Panel: n = 8, T = 15, N = 120
## 
## Residuals:
##    Min. 1st Qu.  Median 3rd Qu.    Max. 
##  -30062  -10733    -673   13521   39895 
## 
## Coefficients:
##                Estimate  Std. Error t-value  Pr(>|t|)    
## (Intercept) -2937049.22   670768.71 -4.3786 2.598e-05 ***
## t               1466.17      332.39  4.4110 2.287e-05 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Total Sum of Squares:    3.4018e+10
## Residual Sum of Squares: 2.9203e+10
## R-Squared:      0.14155
## Adj. R-Squared: 0.13427
## F-statistic: 19.4565 on 1 and 118 DF, p-value: 2.2866e-05
#Opcion 2 - Modelo de Efectos Fijos (within)
within2 <- plm(valor ~ t, data = df2, model = "within")
summary(within2)
## Oneway (individual) effect Within Model
## 
## Call:
## plm(formula = valor ~ t, data = df2, model = "within")
## 
## Balanced Panel: n = 8, T = 15, N = 120
## 
## Residuals:
##    Min. 1st Qu.  Median 3rd Qu.    Max. 
##   -9760   -3015   -1523    2555   19311 
## 
## Coefficients:
##   Estimate Std. Error t-value  Pr(>|t|)    
## t  1466.17     116.12  12.626 < 2.2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Total Sum of Squares:    8.168e+09
## Residual Sum of Squares: 3352800000
## R-Squared:      0.58952
## Adj. R-Squared: 0.55993
## F-statistic: 159.413 on 1 and 111 DF, p-value: < 2.22e-16
#Prueba F
pFtest(within2, pooled2) 
## 
##  F test for individual effects
## 
## data:  valor ~ t
## F = 122.26, df1 = 7, df2 = 111, p-value < 2.2e-16
## alternative hypothesis: significant effects
#Opcion 3 - Modelo de Efectos Aleatorios (Random)
random2 <- plm(valor ~ t, data = df2, model = "random")
summary(random2)
## Oneway (individual) effect Random Effect Model 
##    (Swamy-Arora's transformation)
## 
## Call:
## plm(formula = valor ~ t, data = df2, model = "random")
## 
## Balanced Panel: n = 8, T = 15, N = 120
## 
## Effects:
##                     var   std.dev share
## idiosyncratic  30205839      5496  0.11
## individual    244180653     15626  0.89
## theta: 0.9096
## 
## Residuals:
##    Min. 1st Qu.  Median 3rd Qu.    Max. 
##  -11596   -3144    -709    1841   21173 
## 
## Coefficients:
##                Estimate  Std. Error z-value  Pr(>|z|)    
## (Intercept) -2937049.22   234403.59 -12.530 < 2.2e-16 ***
## t               1466.17      116.12  12.626 < 2.2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Total Sum of Squares:    8379500000
## Residual Sum of Squares: 3564300000
## R-Squared:      0.57464
## Adj. R-Squared: 0.57104
## Chisq: 159.413 on 1 DF, p-value: < 2.22e-16
#Prueba de Hausman
#INTERPRETACIÓN: Si la p es menor a 0.05 usar efectos fijos, si sale mayor usar efectos aleatorios.
phtest(random2, within2) 
## 
##  Hausman Test
## 
## data:  valor ~ t
## chisq = 1.9543e-12, df = 1, p-value = 1
## alternative hypothesis: one model is inconsistent
#Por lo tanto, el mejor modelo para este panel es el de EFECTOS ALEATORIOS.
#Pronóstico 2026 para cada categoría de producto
df2_pronostico <- data.frame(
  categoria = c("Bath and Shower","Deodorants","Depilatories","Fragrances","Hair Care","Mens Grooming","Skin Care","Sun Care"),
  t = rep(2026, 8)
)
intercepto2 <- coef(random2)["(Intercept)"]
pendiente2 <- coef(random2)["t"]
efectos2 <- ranef(random2)
df2_pronostico$valor <- intercepto2 + efectos2[df2_pronostico$categoria] + pendiente2*df2_pronostico$t
df2_pronostico[order(-df2_pronostico$valor), c("categoria","valor")]
##         categoria    valor
## 7       Skin Care 53816.52
## 5       Hair Care 48512.05
## 6   Mens Grooming 43056.53
## 4      Fragrances 42150.12
## 2      Deodorants 26716.76
## 1 Bath and Shower 25448.13
## 8        Sun Care 14244.21
## 3    Depilatories 13264.96
df3 <- data.frame(
  categoria = c(rep("Premium",10), rep("Prestige",10), rep("Mass",10), rep("Dermocosmetics",10)),
  anio = rep(2016:2025, 4),
  valor = c(
    21782.8, 24478.4, 26344, 27806.3, 23212.9, 30224.8, 37374.7, 46017.8, 53798.1, 58845.9,
    19715, 21722.1, 23189.7, 24244.8, 19409.1, 25615.4, 31797.5, 38290.7, 44287.3, 48538.1,
    129002.7, 138197.6, 145032.6, 151178.5, 146414.9, 158941.4, 174599.9, 195814, 213682.8, 225083.1,
    3808.3, 4841.9, 5483.3, 6216.3, 6792.4, 8288.2, 9733.7, 12967.4, 15551.4, 17172.2
  )
)
df3$t <- df3$anio #misma razón: copia numérica para el modelo, anio se queda como índice del panel
df3 <- pdata.frame(df3, index = c("categoria","anio"))
#Prueba de Heterogeneidad
plotmeans(valor ~ categoria, data = df3)

#INTERPRETACIÓN: Mass es mucho más grandes que Dermocosmetics: sí hay heterogeneidad.
# Opcion 1 - Modelo de Regresión Agrupada (Pooled)
pooled3 <- plm(valor ~ t, data = df3, model = "pooling")
summary(pooled3)
## Pooling Model
## 
## Call:
## plm(formula = valor ~ t, data = df3, model = "pooling")
## 
## Balanced Panel: n = 4, T = 10, N = 40
## 
## Residuals:
##    Min. 1st Qu.  Median 3rd Qu.    Max. 
##  -64823  -37524  -27657    9359  143088 
## 
## Coefficients:
##               Estimate Std. Error t-value Pr(>|t|)
## (Intercept) -9641543.5  7277989.5 -1.3248   0.1932
## t               4801.7     3602.1  1.3331   0.1905
## 
## Total Sum of Squares:    1.7031e+11
## Residual Sum of Squares: 1.6271e+11
## R-Squared:      0.044675
## Adj. R-Squared: 0.019535
## F-statistic: 1.77703 on 1 and 38 DF, p-value: 0.19045
#Opcion 2 - Modelo de Efectos Fijos (within)
within3 <- plm(valor ~ t, data = df3, model = "within")
summary(within3)
## Oneway (individual) effect Within Model
## 
## Call:
## plm(formula = valor ~ t, data = df3, model = "within")
## 
## Balanced Panel: n = 4, T = 10, N = 40
## 
## Residuals:
##    Min. 1st Qu.  Median 3rd Qu.    Max. 
##  -18979   -7934   -1587    5709   35680 
## 
## Coefficients:
##   Estimate Std. Error t-value Pr(>|t|)    
## t  4801.75     667.31  7.1957 2.14e-08 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Total Sum of Squares:    1.2752e+10
## Residual Sum of Squares: 5143300000
## R-Squared:      0.59667
## Adj. R-Squared: 0.55058
## F-statistic: 51.7777 on 1 and 35 DF, p-value: 2.1398e-08
#Prueba F
pFtest(within3, pooled3)
## 
##  F test for individual effects
## 
## data:  valor ~ t
## F = 357.4, df1 = 3, df2 = 35, p-value < 2.2e-16
## alternative hypothesis: significant effects
#Opcion 3 - Modelo de Efectos Aleatorios (Random)
random3 <- plm(valor ~ t, data = df3, model = "random")
summary(random3)
## Oneway (individual) effect Random Effect Model 
##    (Swamy-Arora's transformation)
## 
## Call:
## plm(formula = valor ~ t, data = df3, model = "random")
## 
## Balanced Panel: n = 4, T = 10, N = 40
## 
## Effects:
##                     var   std.dev share
## idiosyncratic 1.470e+08 1.212e+04 0.027
## individual    5.237e+09 7.237e+04 0.973
## theta: 0.9471
## 
## Residuals:
##    Min. 1st Qu.  Median 3rd Qu.    Max. 
##  -16235   -7355   -3169    5035   41362 
## 
## Coefficients:
##                Estimate  Std. Error z-value  Pr(>|z|)    
## (Intercept) -9641543.53  1348787.76 -7.1483 8.786e-13 ***
## t               4801.75      667.31  7.1957 6.215e-13 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Total Sum of Squares:    1.3193e+10
## Residual Sum of Squares: 5584100000
## R-Squared:      0.57673
## Adj. R-Squared: 0.56559
## Chisq: 51.7777 on 1 DF, p-value: 6.2154e-13
#Prueba de Hausman
phtest(random3, within3)
## 
##  Hausman Test
## 
## data:  valor ~ t
## chisq = 5.1971e-13, df = 1, p-value = 1
## alternative hypothesis: one model is inconsistent
#Por lo tanto, el mejor modelo para este panel también es el de EFECTOS ALEATORIOS, por la misma razón que en las categorías de producto.
#Pronóstico 2026 para cada subcategoría
categorias_tier <- c("Premium", "Prestige", "Mass", "Dermocosmetics")
df3_pronostico <- data.frame(categoria = categorias_tier, t = rep(2026, 4))
intercepto3 <- coef(random3)["(Intercept)"]
pendiente3 <- coef(random3)["t"]
efectos3 <- ranef(random3)
df3_pronostico$valor <- intercepto3 + efectos3[df3_pronostico$categoria] + pendiente3*df3_pronostico$t
df3_pronostico[order(-df3_pronostico$valor), c("categoria","valor")]
##        categoria     valor
## 3           Mass 193903.84
## 1        Premium  61469.25
## 2       Prestige  56176.50
## 4 Dermocosmetics  35638.66

CONCLUSIÓN: En los dos paneles el modelo que mejor funcionó fue el de Efectos Aleatorios, porque sí hay diferencias de tamaño entre categorías pero no interfieren con la tendencia en el tiempo. Invertiría en Skin Care porque ya es la categoría más grande del mercado y encima sigue proyectándose como la de mayor valor para 2026. Y a una subcategoría, invertiria en Dermocosmetics: todavía es chica, pero es la que más rápido está creciendo (casi el doble que las demás), así que es donde veo más potencial a futuro.

Parte 3. Banco mundial

PIB (crecimiento anual, %) y Desempleo (% de la fuerza laboral) — 5 países, 2000-2023

INSTRUCCIONES: Importa datos del Banco Mundial y genera el mejor modelo, incluyendo predicciones, conclusiones y gráficas.

wb <- tryCatch({
  library(WDI)
  d <- WDI(country = c("MX","BR","CA","US","AR"),
           indicator = c(pib_crecimiento = "NY.GDP.MKTP.KD.ZG",
                         desempleo = "SL.UEM.TOTL.ZS"),
           start = 2000, end = 2023)
  d <- na.omit(d[, c("country","year","pib_crecimiento","desempleo")])
  names(d) <- c("pais","anio","pib_crecimiento","desempleo")
  d
}, error = function(e) read.csv("panel_wb.csv"))

pdfWB <- pdata.frame(wb, index = c("pais", "anio"))
modelo_regresion4 <- lm(pib_crecimiento ~ desempleo, data = pdfWB)
summary(modelo_regresion4)
## 
## Call:
## lm(formula = pib_crecimiento ~ desempleo, data = pdfWB)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -11.1604  -1.4021   0.2238   1.3557   8.6690 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)   3.4172     0.8283   4.126 6.92e-05 ***
## desempleo    -0.1882     0.1039  -1.811   0.0726 .  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 3.586 on 118 degrees of freedom
## Multiple R-squared:  0.02706,    Adjusted R-squared:  0.01881 
## F-statistic: 3.282 on 1 and 118 DF,  p-value: 0.07261
#Prueba de Heterogeneidad
plotmeans(pib_crecimiento ~ pais, data = wb, n.label = FALSE)

#INTERPRETACIÓN: Aquí la línea sale más plana el crecimiento promedio del PIB no varía tanto entre estos 5 países, así que podría no haber heterogeneidad fuerte.
# Opcion 1 - Modelo de Regresión Agrupada (Pooled)
pooled4 <- plm(pib_crecimiento ~ desempleo, data = pdfWB, model = "pooling")
summary(pooled4)
## Pooling Model
## 
## Call:
## plm(formula = pib_crecimiento ~ desempleo, data = pdfWB, model = "pooling")
## 
## Balanced Panel: n = 5, T = 24, N = 120
## 
## Residuals:
##    Min. 1st Qu.  Median 3rd Qu.    Max. 
## -11.160  -1.402   0.224   1.356   8.669 
## 
## Coefficients:
##             Estimate Std. Error t-value  Pr(>|t|)    
## (Intercept)  3.41718    0.82826  4.1257 6.915e-05 ***
## desempleo   -0.18823    0.10391 -1.8115   0.07261 .  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Total Sum of Squares:    1559.7
## Residual Sum of Squares: 1517.5
## R-Squared:      0.027057
## Adj. R-Squared: 0.018812
## F-statistic: 3.28151 on 1 and 118 DF, p-value: 0.072608
#Opcion 2 - Modelo de Efectos Fijos (within)
within4 <- plm(pib_crecimiento ~ desempleo, data = pdfWB, model = "within")
summary(within4)
## Oneway (individual) effect Within Model
## 
## Call:
## plm(formula = pib_crecimiento ~ desempleo, data = pdfWB, model = "within")
## 
## Balanced Panel: n = 5, T = 24, N = 120
## 
## Residuals:
##    Min. 1st Qu.  Median 3rd Qu.    Max. 
## -11.025  -0.982   0.106   1.504   9.647 
## 
## Coefficients:
##           Estimate Std. Error t-value Pr(>|t|)   
## desempleo -0.49609    0.15661 -3.1677 0.001972 **
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Total Sum of Squares:    1553
## Residual Sum of Squares: 1427.3
## R-Squared:      0.080901
## Adj. R-Squared: 0.040589
## F-statistic: 10.0345 on 1 and 114 DF, p-value: 0.001972
#Prueba F
#INTERPRETACIÓN: Si la p es menor a 0.05 no usar POOLED, si p es mayor a 0.05 usar pooled.
pFtest(within4, pooled4)
## 
##  F test for individual effects
## 
## data:  pib_crecimiento ~ desempleo
## F = 1.8007, df1 = 4, df2 = 114, p-value = 0.1335
## alternative hypothesis: significant effects
#Opcion 3 - Modelo de Efectos Aleatorios (Random)
random4 <- plm(pib_crecimiento ~ desempleo, data = pdfWB, model = "random")
summary(random4)
## Oneway (individual) effect Random Effect Model 
##    (Swamy-Arora's transformation)
## 
## Call:
## plm(formula = pib_crecimiento ~ desempleo, data = pdfWB, model = "random")
## 
## Balanced Panel: n = 5, T = 24, N = 120
## 
## Effects:
##                  var std.dev share
## idiosyncratic 12.520   3.538     1
## individual     0.000   0.000     0
## theta: 0
## 
## Residuals:
##    Min. 1st Qu.  Median 3rd Qu.    Max. 
## -11.160  -1.402   0.224   1.356   8.669 
## 
## Coefficients:
##             Estimate Std. Error z-value  Pr(>|z|)    
## (Intercept)  3.41718    0.82826  4.1257 3.696e-05 ***
## desempleo   -0.18823    0.10391 -1.8115   0.07006 .  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Total Sum of Squares:    1559.7
## Residual Sum of Squares: 1517.5
## R-Squared:      0.027057
## Adj. R-Squared: 0.018812
## Chisq: 3.28151 on 1 DF, p-value: 0.070064
#Prueba de Hausman
phtest(random4, within4)
## 
##  Hausman Test
## 
## data:  pib_crecimiento ~ desempleo
## chisq = 6.9035, df = 1, p-value = 0.008603
## alternative hypothesis: one model is inconsistent
#Por lo tanto, el mejor modelo para este panel es el de POOLED. La prueba F da p > 0.05: con solo 5 países, no hay evidencia suficiente de heterogeneidad como para justificar Efectos Fijos o Aleatorios.
#Pronóstico 2024 para cada país, a partir de su desempleo observado en 2023
intercepto4 <- coef(pooled4)["(Intercept)"]
pendiente4 <- coef(pooled4)["desempleo"]
df4_pronostico <- wb[wb$anio == max(wb$anio), c("pais", "desempleo", "pib_crecimiento")]
names(df4_pronostico)[3] <- "pib_observado"
df4_pronostico$pib_2024_pred <- intercepto4 + pendiente4 * df4_pronostico$desempleo
df4_pronostico[order(-df4_pronostico$pib_2024_pred), ]
##              pais desempleo pib_observado pib_2024_pred
## 96         Mexico     2.765      3.106796      2.896729
## 120 United States     3.638      2.934363      2.732406
## 72         Canada     5.415      1.953086      2.397927
## 24      Argentina     6.139     -1.855788      2.261650
## 48         Brazil     7.947      3.241655      1.921335
#Gráfica: relación PIB vs. desempleo
plot(wb$desempleo, wb$pib_crecimiento, col = as.factor(wb$pais), pch = 19,
     xlab = "Desempleo (%)", ylab = "PIB, crecimiento anual (%)",
     main = "PIB vs. Desempleo, 2000-2023 (5 países)")
abline(a = intercepto4, b = pendiente4, col = "black", lwd = 2)
legend("topright", legend = levels(as.factor(wb$pais)), col = 1:5, pch = 19, cex = 0.8)

CONCLUSIÓN: El mejor modelo para el panel de PIB y desempleo es el Pooled, porque con solo 5 países la prueba F no encuentra evidencia suficiente de heterogeneidad entre ellos. Existe una relación negativa entre desempleo y crecimiento del PIB: por cada punto porcentual adicional de desempleo, el PIB crece en promedio 0.19 puntos porcentuales menos.

LS0tCnRpdGxlOiAiQWN0aXZpZGFkIDEiCmF1dGhvcjogIkFkcmlhbmEgTWFkcmlnYWwiCmRhdGU6ICIyMDI2LTA4LTEzIgpvdXRwdXQ6IAogIGh0bWxfZG9jdW1lbnQ6CiAgICB0b2M6IFRSVUUKICAgIHRvY19mbG9hdDogVFJVRQogICAgY29kZV9kb3dubG9hZDogVFJVRQogICAgdGhlbWU6IGNvc21vCiAgICBzZWxmX2NvbnRhaW5lZDogRkFMU0UKLS0tCgpgYGB7PWh0bWx9CjxzdHlsZT4KYm9keSB7IGZvbnQtZmFtaWx5OiAiVHJlYnVjaGV0IE1TIiwgc2Fucy1zZXJpZjsgfQpoMSB7IGNvbG9yOiAjYjU1NDhiOyBib3JkZXItYm90dG9tOiAzcHggc29saWQgI2I1NTQ4YjsgcGFkZGluZy1ib3R0b206IDZweDsgfQpoMiB7IGNvbG9yOiAjNmM1Y2U3OyB9CmltZy5naWYtc2VjY2lvbiB7IGRpc3BsYXk6IGJsb2NrOyBtYXJnaW46IDEycHggYXV0bzsgYm9yZGVyLXJhZGl1czogMTJweDsgfQo8L3N0eWxlPgpgYGAKCiMgSW1wb3J0YXIgcGFxdWV0ZXMgeSBsbGFtYXIgbGlicmVyaWFzIApgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojaW5zdGFsbC5wYWNrYWdlcygicmVhZHhsIikKbGlicmFyeShyZWFkeGwpCiNpbnN0YWxsLnBhY2thZ2VzKCJwbG0iKQpsaWJyYXJ5KHBsbSkKI2luc3RhbGwucGFja2FnZXMoImdwbG90cyIpCmxpYnJhcnkoZ3Bsb3RzKQpgYGAKCiMgUGFydGUgMS4gKipQYXRlbnRlcyoqCgo8aW1nIGNsYXNzPSJnaWYtc2VjY2lvbiIgc3JjPSJodHRwczovL21lZGlhMS5naXBoeS5jb20vbWVkaWEvdjEuWTJsa1BUYzVNR0kzTmpFeGEyNXJaek01ZHpaek5XRnVlR1o1TnpkM2JXNXJZblIyYm5kMVozUjVibkptTTNGc01UWXlaeVpsY0QxMk1WOW5hV1p6WDNObFlYSmphQ1pqZEQxbi9TSDhiUjRxN3ZPNW5mZE1MdnIvMjAwLmdpZiIgd2lkdGg9IjIyMCI+CgpJTlNUUlVDQ0lPTkVTOiBHZW5lcmEgZWwgbWVqb3IgbW9kZWxvIGRlIGxhIEJhc2UgZGUgRGF0b3MgIlBhdGVudGVzIiB5IGdlbmVyYSBwcmVkaWNjaW9uZXMuIAoKYGBge3J9CmRmMSA8LSByZWFkX2V4Y2VsKCIvVXNlcnMvYWRyaWFuYS9Eb3dubG9hZHMvUEFURU5UIDMueGxzIikKc3VtbWFyeShkZjEpCmBgYAoKYGBge3J9CiNwYXRlbnRzIHkgcm5kIGVzdMOhbiBtdXkgc2VzZ2Fkb3M6IGxhIG1pdGFkIGRlIGxhcyBlbXByZXNhcyB0aWVuZSAzIHBhdGVudGVzIG8gbWVub3MsIHBlcm8gaGF5IHVuYSBjb24gOTA2OyB5IGhheSA1MzggZmlsYXMgY29uIDAgcGF0ZW50ZXMuIENvbiBkYXRvcyBhc8OtLCB1biBtb2RlbG8gZW4gbml2ZWxlcyBubyBlcyBidWVuYSBpZGVhLCBwb3IgZXNvIHVzYW1vcyBsb2dhcml0bW9zIChsb2coeCsxKSBwYXJhIHBvZGVyIGluY2x1aXIgbG9zIGNlcm9zKS4KZGYxJGxvZ19wYXRlbnRzIDwtIGxvZyhkZjEkcGF0ZW50cyArIDEpCmRmMSRsb2dfcm5kIDwtIGxvZyhkZjEkcm5kICsgMSkKZGYxIDwtIHBkYXRhLmZyYW1lKGRmMSwgaW5kZXggPSBjKCJjdXNpcCIsICJ5ZWFyIikpCm1vZGVsb19yZWdyZXNpb24gPC0gbG0obG9nX3BhdGVudHMgfiBsb2dfcm5kLCBkYXRhID0gZGYxKQpzdW1tYXJ5KG1vZGVsb19yZWdyZXNpb24pICNFbiBsb2dhcml0bW9zIGVsIG1vZGVsbyBhanVzdGEgbXVjaG8gbWVqb3IgKFIyIGRlIDAuNjAgY29udHJhIDAuMzEgZW4gbml2ZWxlcykgeSBsb3MgcmVzaWR1b3Mgc29uIG11Y2hvIG3DoXMgY2hpY29zIHkgZXN0YWJsZXMuCmBgYApgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojUHJ1ZWJhIGRlIEhldGVyb2dlbmVpZGFkCnBsb3RtZWFucyhsb2dfcGF0ZW50cyB+IGN1c2lwLCBkYXRhID0gZGYxKQojSU5URVJQUkVUQUNJw5NOOiBMYSBsw61uZWEgbm8gZXMgaG9yaXpvbnRhbDogaGF5IGVtcHJlc2FzIGNvbiBtdWNoYXMgbcOhcyBwYXRlbnRlcyBxdWUgb3RyYXMsIGFzw60gcXVlIHPDrSBoYXkgaGV0ZXJvZ2VuZWlkYWQuCmBgYAoKYGBge3J9CiMgT3BjaW9uIDEgLSBNb2RlbG8gZGUgUmVncmVzacOzbiBBZ3J1cGFkYSAoUG9vbGVkKQpwb29sZWQgPC0gcGxtKGxvZ19wYXRlbnRzIH4gbG9nX3JuZCwgZGF0YSA9IGRmMSwgbW9kZWwgPSAicG9vbGluZyIpCnN1bW1hcnkocG9vbGVkKQpgYGAKCmBgYHtyfQojT3BjaW9uIDIgLSBNb2RlbG8gZGUgRWZlY3RvcyBGaWpvcyAod2l0aGluKQp3aXRoaW4gPC0gcGxtKGxvZ19wYXRlbnRzIH4gbG9nX3JuZCwgZGF0YSA9IGRmMSwgbW9kZWwgPSAid2l0aGluIikKc3VtbWFyeSh3aXRoaW4pCmBgYAoKYGBge3J9CiNQcnVlYmEgRgojSU5URVJQUkVUQUNJw5NOOiBTaSBsYSBwIGVzIG1lbm9yIGEgMC4wNSBubyB1c2FyIFBPT0xFRCwgc2kgcCBlcyBtYXlvciBhIDAuMDUgdXNhciBwb29sZWQuCnBGdGVzdCh3aXRoaW4sIHBvb2xlZCkgCmBgYAoKYGBge3J9CiNPcGNpb24gMyAtIE1vZGVsbyBkZSBFZmVjdG9zIEFsZWF0b3Jpb3MgKFJhbmRvbSkKcmFuZG9tIDwtIHBsbShsb2dfcGF0ZW50cyB+IGxvZ19ybmQsIGRhdGEgPSBkZjEsIG1vZGVsID0gInJhbmRvbSIpCnN1bW1hcnkocmFuZG9tKQpgYGAKCmBgYHtyfQojUHJ1ZWJhIGRlIEhhdXNtYW4KI0lOVEVSUFJFVEFDScOTTjogU2kgbGEgcCBlcyBtZW5vciBhIDAuMDUgdXNhciBlZmVjdG9zIGZpam9zLCBzaSBzYWxlIG1heW9yIHVzYXIgZWZlY3RvcyBhbGVhdG9yaW9zLgpwaHRlc3QocmFuZG9tLCB3aXRoaW4pIAojUG9yIGxvIHRhbnRvLCBlbCBtZWpvciBtb2RlbG8gcGFyYSBlc3RlIHBhbmVsIGVzIGVsIGRlIEVGRUNUT1MgRklKT1MuIExhIHBydWViYSBGIHJlY2hhemEgUG9vbGVkIChzw60gaGF5IGhldGVyb2dlbmVpZGFkKSB5IGxhIHBydWViYSBkZSBIYXVzbWFuIHJlY2hhemEgQWxlYXRvcmlvcyAoZXNhIGhldGVyb2dlbmVpZGFkIGVzdMOhIGNvcnJlbGFjaW9uYWRhIGNvbiBlbCBnYXN0byBlbiBJK0Q6IGxhcyBlbXByZXNhcyBxdWUgbcOhcyBwYXRlbnRhbiB0YW1iacOpbiBzb24gbGFzIHF1ZSBtw6FzIGludmllcnRlbikuCmBgYApgYGB7cn0KI1Byb27Ds3N0aWNvOiBjb21vIGVsIG1vZGVsbyBlc3TDoSBlbiBsb2dhcml0bW9zLCBoYXkgcXVlICJkZXZvbHZlciIgbGEgcHJlZGljY2nDs24gYSBwYXRlbnRlcyBjb24gZXhwKCktMSBhbCBmaW5hbApkZjFfcHJvbm9zdGljbyA8LSBkYXRhLmZyYW1lKAogIGN1c2lwID0gYygiMTQ5MTIzIiwgIjM2OTYwNCIsICI0NTkyMDAiKSwKICB5ZWFyID0gYygyMDIyLCAyMDIyLCAyMDIyKSwKICBybmQgPSBjKDIyNi41MzE1LCA4MTMuNzU1OSwgMTYxMS40OTEyKSAqIDEuMTAKKQpkZjFfcHJvbm9zdGljbyRsb2dfcm5kIDwtIGxvZyhkZjFfcHJvbm9zdGljbyRybmQgKyAxKQppbnRlcmNlcHRvIDwtIGZpeGVmKHdpdGhpbikKcGVuZGllbnRlIDwtIGNvZWYod2l0aGluKVsibG9nX3JuZCJdCmRmMV9wcm9ub3N0aWNvJGxvZ19wYXRlbnRlcyA8LSBpbnRlcmNlcHRvW2RmMV9wcm9ub3N0aWNvJGN1c2lwXSArIHBlbmRpZW50ZSAqIGRmMV9wcm9ub3N0aWNvJGxvZ19ybmQKZGYxX3Byb25vc3RpY28kcGF0ZW50ZXMgPC0gZXhwKGRmMV9wcm9ub3N0aWNvJGxvZ19wYXRlbnRlcykgLSAxCmRmMV9wcm9ub3N0aWNvWywgYygiY3VzaXAiLCJwYXRlbnRlcyIpXQpgYGAKQ09OQ0xVU0nDk046IEVsIG1lam9yIG1vZGVsbyBzaWd1ZSBzaWVuZG8gZWwgZGUgRWZlY3RvcyBGaWpvcywgcGVybyB1c2FuZG8gbG9nYXJpdG1vcyBlbiB2ZXogZGUgbml2ZWxlcywgcG9ycXVlIHBhdGVudHMgeSBybmQgZXN0w6FuIG11eSBzZXNnYWRvcyAocG9jYXMgZW1wcmVzYXMgY29uY2VudHJhbiBsYSBtYXlvcsOtYSBkZSBsYXMgcGF0ZW50ZXMgeSBkZWwgZ2FzdG8pLiBFbiBsb2dhcml0bW9zIGVsIG1vZGVsbyBhanVzdGEgbXVjaG8gbWVqb3IgeSBlbCBjb2VmaWNpZW50ZSBzZSBpbnRlcnByZXRhIGNvbW8gZWxhc3RpY2lkYWQ6IGN1w6FudG8gY2FtYmlhIGVsICUgZGUgcGF0ZW50ZXMgcG9yIGNhZGEgJSBkZSBjYW1iaW8gZW4gSStELiBSZXZpc2FuZG8gbG9zIGRhdG9zIGVtcHJlc2EgcG9yIGVtcHJlc2EgZW5jb250csOpIGFsZ28gaW1wb3J0YW50ZTogMjAyMSAoZWwgw7psdGltbyBhw7FvIGRlIGxhIGJhc2UpIHRpZW5lIHVuYSBjYcOtZGEgcmFyw61zaW1hIGVuIHBhdGVudGVzIHBhcmEgY2FzaSB0b2RhcyBsYXMgZW1wcmVzYXMgZ3JhbmRlcywgZGVzcHXDqXMgZGUgYcOxb3MgZXN0YWJsZXMgZW4gY2llbnRvcyDigJQgZXMgdW4gcHJvYmxlbWEgdMOtcGljbyBkZSBsYXMgYmFzZXMgZGUgcGF0ZW50ZXMsIGRvbmRlIGVsIMO6bHRpbW8gYcOxbyBzYWxlIGJham8gcG9ycXVlIGVsIHRyw6FtaXRlIHRhcmRhIHkgbXVjaGFzIHBhdGVudGVzIHJlY2llbnRlcyB0b2RhdsOtYSBubyBzZSBoYWLDrWFuIHJlZ2lzdHJhZG8gY3VhbmRvIHNlIGFybcOzIGxhIGJhc2UuIFBvciBlc28gZWwgcHJvbsOzc3RpY28gMjAyMiBzYWxlIG3DoXMgYWx0byBxdWUgbGFzIHBhdGVudGVzICJvZmljaWFsZXMiIGRlIDIwMjE6IGVsIG1vZGVsbyBzZSBiYXNhIGVuIGVsIG5pdmVsIGhpc3TDs3JpY28gbm9ybWFsIGRlIGNhZGEgZW1wcmVzYSwgbm8gZW4gZXNlIMO6bHRpbW8gYcOxbyBhdMOtcGljby4KCiMgUGFydGUgMi4gICoqQ3VpZGFkbyBkZSBsYSBwaWVsKioKCjxpbWcgY2xhc3M9ImdpZi1zZWNjaW9uIiBzcmM9Imh0dHBzOi8vbWVkaWExLmdpcGh5LmNvbS9tZWRpYS92MS5ZMmxrUFRjNU1HSTNOakV4T1RWaGFEQnFPV280WlhBemNETnhOR0Y1ZDNKeU1HRnRkMlpwWkdWdWMzQjBhV0o0Ykdad2R5WmxjRDEyTVY5bmFXWnpYM05sWVhKamFDWmpkRDFuL2hvcjdEM1oyU2NENlNtcjBPcy9naXBoeS5naWYiIHdpZHRoPSIyMjAiPgoKSU5TVFJVQ0NJT05FUzogwr9FbiBjdcOhbCBjYXRlZ29yw61hIGludmVydGlyw61hcyB5IHBvciBxdcOpPyBTaSB0dXZpZXJhcyBxdWUgaW52ZXJ0aXIgZW4gYWxndW5hIHN1YmNhdGVnb3LDrWEsIMK/ZW4gY3XDoWwgbG8gaGFyw61hcz8gSnVzdGlmaWNhIGRlIGFjdWVyZG8gYWwgbW9kZWxvLgpgYGB7cn0KZGYyX2V4Y2VsIDwtIHJlYWRfZXhjZWwoIi9Vc2Vycy9hZHJpYW5hL0Rvd25sb2Fkcy9NYXJrZXQgc2l6ZXMueGxzIikKc3VtbWFyeShkZjJfZXhjZWwpCmBgYAoKYGBge3J9CmRmMiA8LSBkYXRhLmZyYW1lKAogIGNhdGVnb3JpYSA9IGMocmVwKCJCYXRoIGFuZCBTaG93ZXIiLDE1KSwgcmVwKCJEZW9kb3JhbnRzIiwxNSksIHJlcCgiRGVwaWxhdG9yaWVzIiwxNSksCiAgICAgICAgICAgICAgICByZXAoIkZyYWdyYW5jZXMiLDE1KSwgcmVwKCJIYWlyIENhcmUiLDE1KSwgcmVwKCJNZW5zIEdyb29taW5nIiwxNSksCiAgICAgICAgICAgICAgICByZXAoIlNraW4gQ2FyZSIsMTUpLCByZXAoIlN1biBDYXJlIiwxNSkpLAogIGFuaW8gPSByZXAoMjAxMToyMDI1LCA4KSwKICB2YWxvciA9IGMoCiAgICA4NDEwLjQsIDkwODUsIDk3MTEuMSwgMTAyMjYuOSwgMTA4MTQuOCwgMTE0ODEuNiwgMTIxMjMuMSwgMTI0OTAuMSwgMTI5NTkuNSwgMTQ2MzMuOSwgMTU0NjkuMywgMTY4MTUuMywgMTkwMDEsIDIwMjM0LjYsIDIxMzQxLjcsCiAgICA5MTUxLCAxMDE0OC4zLCAxMDY5Ny43LCAxMTQ2OS43LCAxMjM3OS4yLCAxMzcyMy40LCAxNDg5MS42LCAxNTkxMy42LCAxNjc0NS4xLCAxMzgzNC44LCAxNTA5MS4xLCAxNzg3Mi40LCAxOTQ1NC45LCAyMDc4Ny44LCAyMTgyNC4xLAogICAgODAyLjUsIDg5Ny43LCA5NjkuOSwgMTAzNi4zLCAxMTA2LjQsIDExODcuOSwgMTMxOS41LCAxNDM5LjEsIDE1MTYuMSwgMTQ5MS4yLCAxNTYzLjUsIDE2ODguNiwgMTg1MC4yLCAxODAyLCAxODcyLjgsCiAgICAxODcyNy45LCAxOTk1Ny4yLCAyMDY1MS44LCAyMDk3OS42LCAyMjU2Ny42LCAyNDIwOC45LCAyNjE1Mi4zLCAyNzUzNiwgMjg0ODMuMSwgMjU1MTYuMSwgMzE4MDAuOCwgMzcxNzIuOCwgNDUzMTguOSwgNTE1NzkuMiwgNTY3NDIuMSwKICAgIDI0ODUzLjksIDI2NTY1LjYsIDI3NjcyLjUsIDI5MTU0LjYsIDMwNDE2LjIsIDMyMzgzLjYsIDM0MjYwLCAzNTU5Ny4yLCAzNzI0Ny40LCAzNjk1MC43LCAzOTU1NC43LCA0MjczOC44LCA0NjkwMC4zLCA1MzAyNC45LCA1NjI4OS44LAogICAgMTg2NzIuMSwgMjA2OTQuNCwgMjIxMzMuNCwgMjMxNzUuMywgMjQ3NzQsIDI3NDQ2LCAyOTQ5Ny4yLCAzMTQ5OC4xLCAzMjY5My4zLCAyOTY2OS40LCAzMjkzOC42LCAzNzcwMi40LCA0MzM2Ni4yLCA0NzMzMy44LCA0OTUwOC40LAogICAgMjU2NTAuMywgMjczMDYuMiwgMjgzNjYuOSwgMjk0MzguMywgMzA5NjQsIDMzMDU0LjMsIDM1Nzg3LjgsIDM4MDY3LjUsIDQwNjM3LjUsIDQyMTk2LjUsIDQ3OTgwLjYsIDUyOTM5LjYsIDYxMDIzLjYsIDY4NTkwLjQsIDcxODMwLAogICAgMTE0NC43LCAxMzAzLjEsIDE0MTcuMywgMTU1Mi44LCAxNjkzLjMsIDE5NDQuMSwgMjE0My4zLCAyMjY2LjUsIDI0NDMuOCwgMjA0Mi45LCAyMjkzLjYsIDI4NjIsIDM3MzYuNCwgNDE4My40LCA0MzI2LjQKICApCikKZGYyJHQgPC0gZGYyJGFuaW8gI2NvcGlhIG51bcOpcmljYSBkZSBhbmlvOyBhbmlvIHlhIGVzIGVsIMOtbmRpY2UgZGVsIHBhbmVsLCBhc8OtIHF1ZSBzaSBsbyB1c2Ftb3MgZGlyZWN0byBlbiBlbCBtb2RlbG8gUiBsbyB2dWVsdmUgY2F0ZWfDs3JpY28gKHVubyBwb3IgYcOxbykgZW4gdmV6IGRlIG7Dum1lcm8sIHkgcG9yIGVzbyBzYWzDrWFuIGxvcyBOQQpkZjIgPC0gcGRhdGEuZnJhbWUoZGYyLCBpbmRleCA9IGMoImNhdGVnb3JpYSIsImFuaW8iKSkKYGBgCgoKYGBge3J9Cm1vZGVsb19yZWdyZXNpb24yIDwtIGxtKHZhbG9yIH4gdCwgZGF0YSA9IGRmMikKc3VtbWFyeShtb2RlbG9fcmVncmVzaW9uMikKYGBgCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiNQcnVlYmEgZGUgSGV0ZXJvZ2VuZWlkYWQKcGxvdG1lYW5zKHZhbG9yIH4gY2F0ZWdvcmlhLCBkYXRhID0gZGYyKQojSU5URVJQUkVUQUNJw5NOOiBTa2luIENhcmUgeSBIYWlyIENhcmUgb3BlcmFuIGVuIHVuIG5pdmVsIGRlIG1lcmNhZG8gbXVjaG8gbcOhcyBncmFuZGUgcXVlIERlcGlsYXRvcmllcyBvIFN1biBDYXJlOiBzw60gaGF5IGhldGVyb2dlbmVpZGFkLgpgYGAKCmBgYHtyfQojIE9wY2lvbiAxIC0gTW9kZWxvIGRlIFJlZ3Jlc2nDs24gQWdydXBhZGEgKFBvb2xlZCkKcG9vbGVkMiA8LSBwbG0odmFsb3IgfiB0LCBkYXRhID0gZGYyLCBtb2RlbCA9ICJwb29saW5nIikKc3VtbWFyeShwb29sZWQyKQpgYGAKYGBge3J9CiNPcGNpb24gMiAtIE1vZGVsbyBkZSBFZmVjdG9zIEZpam9zICh3aXRoaW4pCndpdGhpbjIgPC0gcGxtKHZhbG9yIH4gdCwgZGF0YSA9IGRmMiwgbW9kZWwgPSAid2l0aGluIikKc3VtbWFyeSh3aXRoaW4yKQpgYGAKCmBgYHtyfQojUHJ1ZWJhIEYKcEZ0ZXN0KHdpdGhpbjIsIHBvb2xlZDIpIApgYGAKYGBge3J9CiNPcGNpb24gMyAtIE1vZGVsbyBkZSBFZmVjdG9zIEFsZWF0b3Jpb3MgKFJhbmRvbSkKcmFuZG9tMiA8LSBwbG0odmFsb3IgfiB0LCBkYXRhID0gZGYyLCBtb2RlbCA9ICJyYW5kb20iKQpzdW1tYXJ5KHJhbmRvbTIpCmBgYApgYGB7cn0KI1BydWViYSBkZSBIYXVzbWFuCiNJTlRFUlBSRVRBQ0nDk046IFNpIGxhIHAgZXMgbWVub3IgYSAwLjA1IHVzYXIgZWZlY3RvcyBmaWpvcywgc2kgc2FsZSBtYXlvciB1c2FyIGVmZWN0b3MgYWxlYXRvcmlvcy4KcGh0ZXN0KHJhbmRvbTIsIHdpdGhpbjIpIAojUG9yIGxvIHRhbnRvLCBlbCBtZWpvciBtb2RlbG8gcGFyYSBlc3RlIHBhbmVsIGVzIGVsIGRlIEVGRUNUT1MgQUxFQVRPUklPUy4KYGBgCmBgYHtyfQojUHJvbsOzc3RpY28gMjAyNiBwYXJhIGNhZGEgY2F0ZWdvcsOtYSBkZSBwcm9kdWN0bwpkZjJfcHJvbm9zdGljbyA8LSBkYXRhLmZyYW1lKAogIGNhdGVnb3JpYSA9IGMoIkJhdGggYW5kIFNob3dlciIsIkRlb2RvcmFudHMiLCJEZXBpbGF0b3JpZXMiLCJGcmFncmFuY2VzIiwiSGFpciBDYXJlIiwiTWVucyBHcm9vbWluZyIsIlNraW4gQ2FyZSIsIlN1biBDYXJlIiksCiAgdCA9IHJlcCgyMDI2LCA4KQopCmludGVyY2VwdG8yIDwtIGNvZWYocmFuZG9tMilbIihJbnRlcmNlcHQpIl0KcGVuZGllbnRlMiA8LSBjb2VmKHJhbmRvbTIpWyJ0Il0KZWZlY3RvczIgPC0gcmFuZWYocmFuZG9tMikKZGYyX3Byb25vc3RpY28kdmFsb3IgPC0gaW50ZXJjZXB0bzIgKyBlZmVjdG9zMltkZjJfcHJvbm9zdGljbyRjYXRlZ29yaWFdICsgcGVuZGllbnRlMipkZjJfcHJvbm9zdGljbyR0CmRmMl9wcm9ub3N0aWNvW29yZGVyKC1kZjJfcHJvbm9zdGljbyR2YWxvciksIGMoImNhdGVnb3JpYSIsInZhbG9yIildCmBgYAoKYGBge3J9CmRmMyA8LSBkYXRhLmZyYW1lKAogIGNhdGVnb3JpYSA9IGMocmVwKCJQcmVtaXVtIiwxMCksIHJlcCgiUHJlc3RpZ2UiLDEwKSwgcmVwKCJNYXNzIiwxMCksIHJlcCgiRGVybW9jb3NtZXRpY3MiLDEwKSksCiAgYW5pbyA9IHJlcCgyMDE2OjIwMjUsIDQpLAogIHZhbG9yID0gYygKICAgIDIxNzgyLjgsIDI0NDc4LjQsIDI2MzQ0LCAyNzgwNi4zLCAyMzIxMi45LCAzMDIyNC44LCAzNzM3NC43LCA0NjAxNy44LCA1Mzc5OC4xLCA1ODg0NS45LAogICAgMTk3MTUsIDIxNzIyLjEsIDIzMTg5LjcsIDI0MjQ0LjgsIDE5NDA5LjEsIDI1NjE1LjQsIDMxNzk3LjUsIDM4MjkwLjcsIDQ0Mjg3LjMsIDQ4NTM4LjEsCiAgICAxMjkwMDIuNywgMTM4MTk3LjYsIDE0NTAzMi42LCAxNTExNzguNSwgMTQ2NDE0LjksIDE1ODk0MS40LCAxNzQ1OTkuOSwgMTk1ODE0LCAyMTM2ODIuOCwgMjI1MDgzLjEsCiAgICAzODA4LjMsIDQ4NDEuOSwgNTQ4My4zLCA2MjE2LjMsIDY3OTIuNCwgODI4OC4yLCA5NzMzLjcsIDEyOTY3LjQsIDE1NTUxLjQsIDE3MTcyLjIKICApCikKZGYzJHQgPC0gZGYzJGFuaW8gI21pc21hIHJhesOzbjogY29waWEgbnVtw6lyaWNhIHBhcmEgZWwgbW9kZWxvLCBhbmlvIHNlIHF1ZWRhIGNvbW8gw61uZGljZSBkZWwgcGFuZWwKZGYzIDwtIHBkYXRhLmZyYW1lKGRmMywgaW5kZXggPSBjKCJjYXRlZ29yaWEiLCJhbmlvIikpCgpgYGAKCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiNQcnVlYmEgZGUgSGV0ZXJvZ2VuZWlkYWQKcGxvdG1lYW5zKHZhbG9yIH4gY2F0ZWdvcmlhLCBkYXRhID0gZGYzKQojSU5URVJQUkVUQUNJw5NOOiBNYXNzIGVzIG11Y2hvIG3DoXMgZ3JhbmRlcyBxdWUgRGVybW9jb3NtZXRpY3M6IHPDrSBoYXkgaGV0ZXJvZ2VuZWlkYWQuCmBgYApgYGB7cn0KIyBPcGNpb24gMSAtIE1vZGVsbyBkZSBSZWdyZXNpw7NuIEFncnVwYWRhIChQb29sZWQpCnBvb2xlZDMgPC0gcGxtKHZhbG9yIH4gdCwgZGF0YSA9IGRmMywgbW9kZWwgPSAicG9vbGluZyIpCnN1bW1hcnkocG9vbGVkMykKCiNPcGNpb24gMiAtIE1vZGVsbyBkZSBFZmVjdG9zIEZpam9zICh3aXRoaW4pCndpdGhpbjMgPC0gcGxtKHZhbG9yIH4gdCwgZGF0YSA9IGRmMywgbW9kZWwgPSAid2l0aGluIikKc3VtbWFyeSh3aXRoaW4zKQoKI1BydWViYSBGCnBGdGVzdCh3aXRoaW4zLCBwb29sZWQzKQoKI09wY2lvbiAzIC0gTW9kZWxvIGRlIEVmZWN0b3MgQWxlYXRvcmlvcyAoUmFuZG9tKQpyYW5kb20zIDwtIHBsbSh2YWxvciB+IHQsIGRhdGEgPSBkZjMsIG1vZGVsID0gInJhbmRvbSIpCnN1bW1hcnkocmFuZG9tMykKCiNQcnVlYmEgZGUgSGF1c21hbgpwaHRlc3QocmFuZG9tMywgd2l0aGluMykKI1BvciBsbyB0YW50bywgZWwgbWVqb3IgbW9kZWxvIHBhcmEgZXN0ZSBwYW5lbCB0YW1iacOpbiBlcyBlbCBkZSBFRkVDVE9TIEFMRUFUT1JJT1MsIHBvciBsYSBtaXNtYSByYXrDs24gcXVlIGVuIGxhcyBjYXRlZ29yw61hcyBkZSBwcm9kdWN0by4KYGBgCmBgYHtyfQojUHJvbsOzc3RpY28gMjAyNiBwYXJhIGNhZGEgc3ViY2F0ZWdvcsOtYQpjYXRlZ29yaWFzX3RpZXIgPC0gYygiUHJlbWl1bSIsICJQcmVzdGlnZSIsICJNYXNzIiwgIkRlcm1vY29zbWV0aWNzIikKZGYzX3Byb25vc3RpY28gPC0gZGF0YS5mcmFtZShjYXRlZ29yaWEgPSBjYXRlZ29yaWFzX3RpZXIsIHQgPSByZXAoMjAyNiwgNCkpCmludGVyY2VwdG8zIDwtIGNvZWYocmFuZG9tMylbIihJbnRlcmNlcHQpIl0KcGVuZGllbnRlMyA8LSBjb2VmKHJhbmRvbTMpWyJ0Il0KZWZlY3RvczMgPC0gcmFuZWYocmFuZG9tMykKZGYzX3Byb25vc3RpY28kdmFsb3IgPC0gaW50ZXJjZXB0bzMgKyBlZmVjdG9zM1tkZjNfcHJvbm9zdGljbyRjYXRlZ29yaWFdICsgcGVuZGllbnRlMypkZjNfcHJvbm9zdGljbyR0CmRmM19wcm9ub3N0aWNvW29yZGVyKC1kZjNfcHJvbm9zdGljbyR2YWxvciksIGMoImNhdGVnb3JpYSIsInZhbG9yIildCmBgYApDT05DTFVTScOTTjogRW4gbG9zIGRvcyBwYW5lbGVzIGVsIG1vZGVsbyBxdWUgbWVqb3IgZnVuY2lvbsOzIGZ1ZSBlbCBkZSBFZmVjdG9zIEFsZWF0b3Jpb3MsIHBvcnF1ZSBzw60gaGF5IGRpZmVyZW5jaWFzIGRlIHRhbWHDsW8gZW50cmUgY2F0ZWdvcsOtYXMgcGVybyBubyBpbnRlcmZpZXJlbiBjb24gbGEgdGVuZGVuY2lhIGVuIGVsIHRpZW1wby4gSW52ZXJ0aXLDrWEgZW4gU2tpbiBDYXJlIHBvcnF1ZSB5YSBlcyBsYSBjYXRlZ29yw61hIG3DoXMgZ3JhbmRlIGRlbCBtZXJjYWRvIHkgZW5jaW1hIHNpZ3VlIHByb3llY3TDoW5kb3NlIGNvbW8gbGEgZGUgbWF5b3IgdmFsb3IgcGFyYSAyMDI2LiBZIGEgdW5hIHN1YmNhdGVnb3LDrWEsIGludmVydGlyaWEgZW4gRGVybW9jb3NtZXRpY3M6IHRvZGF2w61hIGVzIGNoaWNhLCBwZXJvIGVzIGxhIHF1ZSBtw6FzIHLDoXBpZG8gZXN0w6EgY3JlY2llbmRvIChjYXNpIGVsIGRvYmxlIHF1ZSBsYXMgZGVtw6FzKSwgYXPDrSBxdWUgZXMgZG9uZGUgdmVvIG3DoXMgcG90ZW5jaWFsIGEgZnV0dXJvLgoKCiMgUGFydGUgMy4gKipCYW5jbyBtdW5kaWFsKiogCioqUElCIChjcmVjaW1pZW50byBhbnVhbCwgJSkgeSBEZXNlbXBsZW8gKCUgZGUgbGEgZnVlcnphIGxhYm9yYWwpIOKAlCA1IHBhw61zZXMsIDIwMDAtMjAyMyoqCgo8aW1nIGNsYXNzPSJnaWYtc2VjY2lvbiIgc3JjPSJodHRwczovL21lZGlhMS5naXBoeS5jb20vbWVkaWEvdjEuWTJsa1BUYzVNR0kzTmpFeFlXdzBPVFZtZFdOMk1qbGlNbll4YlhwaGQzQTFkR05qWkdWNmJYaDNkV0Z0TTJ4bk5tTnhNU1psY0QxMk1WOW5hV1p6WDNObFlYSmphQ1pqZEQxbi9Za1hOakFrRzdDZkVWeDNnY3kvZ2lwaHkuZ2lmIiB3aWR0aD0iMjIwIj4KCklOU1RSVUNDSU9ORVM6IEltcG9ydGEgZGF0b3MgZGVsIEJhbmNvIE11bmRpYWwgeSBnZW5lcmEgZWwgbWVqb3IgbW9kZWxvLCBpbmNsdXllbmRvIHByZWRpY2Npb25lcywgY29uY2x1c2lvbmVzIHkgZ3LDoWZpY2FzLgpgYGB7cn0Kd2IgPC0gdHJ5Q2F0Y2goewogIGxpYnJhcnkoV0RJKQogIGQgPC0gV0RJKGNvdW50cnkgPSBjKCJNWCIsIkJSIiwiQ0EiLCJVUyIsIkFSIiksCiAgICAgICAgICAgaW5kaWNhdG9yID0gYyhwaWJfY3JlY2ltaWVudG8gPSAiTlkuR0RQLk1LVFAuS0QuWkciLAogICAgICAgICAgICAgICAgICAgICAgICAgZGVzZW1wbGVvID0gIlNMLlVFTS5UT1RMLlpTIiksCiAgICAgICAgICAgc3RhcnQgPSAyMDAwLCBlbmQgPSAyMDIzKQogIGQgPC0gbmEub21pdChkWywgYygiY291bnRyeSIsInllYXIiLCJwaWJfY3JlY2ltaWVudG8iLCJkZXNlbXBsZW8iKV0pCiAgbmFtZXMoZCkgPC0gYygicGFpcyIsImFuaW8iLCJwaWJfY3JlY2ltaWVudG8iLCJkZXNlbXBsZW8iKQogIGQKfSwgZXJyb3IgPSBmdW5jdGlvbihlKSByZWFkLmNzdigicGFuZWxfd2IuY3N2IikpCgpwZGZXQiA8LSBwZGF0YS5mcmFtZSh3YiwgaW5kZXggPSBjKCJwYWlzIiwgImFuaW8iKSkKYGBgCgpgYGB7cn0KbW9kZWxvX3JlZ3Jlc2lvbjQgPC0gbG0ocGliX2NyZWNpbWllbnRvIH4gZGVzZW1wbGVvLCBkYXRhID0gcGRmV0IpCnN1bW1hcnkobW9kZWxvX3JlZ3Jlc2lvbjQpCmBgYAoKYGBge3J9CiNQcnVlYmEgZGUgSGV0ZXJvZ2VuZWlkYWQKcGxvdG1lYW5zKHBpYl9jcmVjaW1pZW50byB+IHBhaXMsIGRhdGEgPSB3Yiwgbi5sYWJlbCA9IEZBTFNFKQojSU5URVJQUkVUQUNJw5NOOiBBcXXDrSBsYSBsw61uZWEgc2FsZSBtw6FzIHBsYW5hIGVsIGNyZWNpbWllbnRvIHByb21lZGlvIGRlbCBQSUIgbm8gdmFyw61hIHRhbnRvIGVudHJlIGVzdG9zIDUgcGHDrXNlcywgYXPDrSBxdWUgcG9kcsOtYSBubyBoYWJlciBoZXRlcm9nZW5laWRhZCBmdWVydGUuCmBgYApgYGB7cn0KIyBPcGNpb24gMSAtIE1vZGVsbyBkZSBSZWdyZXNpw7NuIEFncnVwYWRhIChQb29sZWQpCnBvb2xlZDQgPC0gcGxtKHBpYl9jcmVjaW1pZW50byB+IGRlc2VtcGxlbywgZGF0YSA9IHBkZldCLCBtb2RlbCA9ICJwb29saW5nIikKc3VtbWFyeShwb29sZWQ0KQoKI09wY2lvbiAyIC0gTW9kZWxvIGRlIEVmZWN0b3MgRmlqb3MgKHdpdGhpbikKd2l0aGluNCA8LSBwbG0ocGliX2NyZWNpbWllbnRvIH4gZGVzZW1wbGVvLCBkYXRhID0gcGRmV0IsIG1vZGVsID0gIndpdGhpbiIpCnN1bW1hcnkod2l0aGluNCkKCiNQcnVlYmEgRgojSU5URVJQUkVUQUNJw5NOOiBTaSBsYSBwIGVzIG1lbm9yIGEgMC4wNSBubyB1c2FyIFBPT0xFRCwgc2kgcCBlcyBtYXlvciBhIDAuMDUgdXNhciBwb29sZWQuCnBGdGVzdCh3aXRoaW40LCBwb29sZWQ0KQoKI09wY2lvbiAzIC0gTW9kZWxvIGRlIEVmZWN0b3MgQWxlYXRvcmlvcyAoUmFuZG9tKQpyYW5kb200IDwtIHBsbShwaWJfY3JlY2ltaWVudG8gfiBkZXNlbXBsZW8sIGRhdGEgPSBwZGZXQiwgbW9kZWwgPSAicmFuZG9tIikKc3VtbWFyeShyYW5kb200KQoKI1BydWViYSBkZSBIYXVzbWFuCnBodGVzdChyYW5kb200LCB3aXRoaW40KQojUG9yIGxvIHRhbnRvLCBlbCBtZWpvciBtb2RlbG8gcGFyYSBlc3RlIHBhbmVsIGVzIGVsIGRlIFBPT0xFRC4gTGEgcHJ1ZWJhIEYgZGEgcCA+IDAuMDU6IGNvbiBzb2xvIDUgcGHDrXNlcywgbm8gaGF5IGV2aWRlbmNpYSBzdWZpY2llbnRlIGRlIGhldGVyb2dlbmVpZGFkIGNvbW8gcGFyYSBqdXN0aWZpY2FyIEVmZWN0b3MgRmlqb3MgbyBBbGVhdG9yaW9zLgpgYGAKYGBge3J9CgojUHJvbsOzc3RpY28gMjAyNCBwYXJhIGNhZGEgcGHDrXMsIGEgcGFydGlyIGRlIHN1IGRlc2VtcGxlbyBvYnNlcnZhZG8gZW4gMjAyMwppbnRlcmNlcHRvNCA8LSBjb2VmKHBvb2xlZDQpWyIoSW50ZXJjZXB0KSJdCnBlbmRpZW50ZTQgPC0gY29lZihwb29sZWQ0KVsiZGVzZW1wbGVvIl0KZGY0X3Byb25vc3RpY28gPC0gd2Jbd2IkYW5pbyA9PSBtYXgod2IkYW5pbyksIGMoInBhaXMiLCAiZGVzZW1wbGVvIiwgInBpYl9jcmVjaW1pZW50byIpXQpuYW1lcyhkZjRfcHJvbm9zdGljbylbM10gPC0gInBpYl9vYnNlcnZhZG8iCmRmNF9wcm9ub3N0aWNvJHBpYl8yMDI0X3ByZWQgPC0gaW50ZXJjZXB0bzQgKyBwZW5kaWVudGU0ICogZGY0X3Byb25vc3RpY28kZGVzZW1wbGVvCmRmNF9wcm9ub3N0aWNvW29yZGVyKC1kZjRfcHJvbm9zdGljbyRwaWJfMjAyNF9wcmVkKSwgXQoKI0dyw6FmaWNhOiByZWxhY2nDs24gUElCIHZzLiBkZXNlbXBsZW8KcGxvdCh3YiRkZXNlbXBsZW8sIHdiJHBpYl9jcmVjaW1pZW50bywgY29sID0gYXMuZmFjdG9yKHdiJHBhaXMpLCBwY2ggPSAxOSwKICAgICB4bGFiID0gIkRlc2VtcGxlbyAoJSkiLCB5bGFiID0gIlBJQiwgY3JlY2ltaWVudG8gYW51YWwgKCUpIiwKICAgICBtYWluID0gIlBJQiB2cy4gRGVzZW1wbGVvLCAyMDAwLTIwMjMgKDUgcGHDrXNlcykiKQphYmxpbmUoYSA9IGludGVyY2VwdG80LCBiID0gcGVuZGllbnRlNCwgY29sID0gImJsYWNrIiwgbHdkID0gMikKbGVnZW5kKCJ0b3ByaWdodCIsIGxlZ2VuZCA9IGxldmVscyhhcy5mYWN0b3Iod2IkcGFpcykpLCBjb2wgPSAxOjUsIHBjaCA9IDE5LCBjZXggPSAwLjgpCmBgYApDT05DTFVTScOTTjogRWwgbWVqb3IgbW9kZWxvIHBhcmEgZWwgcGFuZWwgZGUgUElCIHkgZGVzZW1wbGVvIGVzIGVsIFBvb2xlZCwgcG9ycXVlIGNvbiBzb2xvIDUgcGHDrXNlcyBsYSBwcnVlYmEgRiBubyBlbmN1ZW50cmEgZXZpZGVuY2lhIHN1ZmljaWVudGUgZGUgaGV0ZXJvZ2VuZWlkYWQgZW50cmUgZWxsb3MuIEV4aXN0ZSB1bmEgcmVsYWNpw7NuIG5lZ2F0aXZhIGVudHJlIGRlc2VtcGxlbyB5IGNyZWNpbWllbnRvIGRlbCBQSUI6IHBvciBjYWRhIHB1bnRvIHBvcmNlbnR1YWwgYWRpY2lvbmFsIGRlIGRlc2VtcGxlbywgZWwgUElCIGNyZWNlIGVuIHByb21lZGlvIDAuMTkgcHVudG9zIHBvcmNlbnR1YWxlcyBtZW5vcy4K