Licença

This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License. To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/4.0/ or send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.

License: CC BY-SA 4.0

License: CC BY-SA 4.0

Citação

Sugestão de citação: FIGUEIREDO, Adriano Marcos Rodrigues. Econometria: Salários de advogados - Wooldridge(exemplo 7.8) adaptado de MOHR (2018). Campo Grande-MS,Brasil: RStudio/Rpubs, 2019. Disponível em http://rpubs.com/amrofi/wooldridge_ex7_8.

1 Introdução

O dataset contém dados sobre a mediana dos salários iniciais dos formados em Direito. Uma variável explicativa é a classificação da faculdade cursada. O grupo base é das faculdades com rank maior que 100.

2 Dados

O data.frame contém 156 observações de 21 variáveis. O dataset está no pacote wooldridge acessado fazendo data("lawsch85"):

  • VARIÁVEL DEPENDENTE:
    • salary: median starting salary
  • CARACTERISTICAS DOS ENTRANTES
    • LSAT: median LSAT (Law School Admission Test) score
    • GPA: median college GPA (Grade Point Average)
  • CARACTERISTICAS DA ESCOLA
    • rank: law school ranking
    • cost: law school cost
    • libvol: no. volumes in lib., 1000s
  • VARIAVEIS DERIVADAS
    • lsalary: log(salary)
    • top10: =1 if ranked in top 10
    • r11_25: =1 if ranked 11-25
    • r26_40: =1 if ranked 26-40
    • r41_60: =1 if ranked 41-60
    • llibvol: log(libvol)
    • lcost: log(cost)

3 Resultados

library(wooldridge)
data("lawsch85")
# Gerar dummies - Não era necessário, pois já estavam no dataset, mas
# criamos abaixo para ver como o dataset contem uma variável rank para os
# salarios (salary)
top10 <- as.numeric(lawsch85$rank <= 10)
r11.25 <- as.numeric(lawsch85$rank >= 11 & lawsch85$rank <= 25)
r26.40 <- as.numeric(lawsch85$rank >= 26 & lawsch85$rank <= 40)
r41.60 <- as.numeric(lawsch85$rank >= 41 & lawsch85$rank <= 60)
r61.100 <- as.numeric(lawsch85$rank >= 61 & lawsch85$rank <= 100)
attach(lawsch85)
dados <- as.data.frame(cbind(salary, rank, LSAT, GPA, libvol, cost, top10, r11_25, 
    r26_40, r41_60, r61.100))
detach(lawsch85)
attach(dados)
mod1 <- lm(log(salary) ~ log(rank) + log(LSAT) + log(GPA) + log(libvol) + log(cost), 
    data = dados)
mod2 <- lm((salary) ~ (rank) + (LSAT) + (GPA) + (libvol) + (cost), data = dados)
mod3 <- lm(log(salary) ~ top10 + r11_25 + r26_40 + r41_60 + r61.100 + log(LSAT) + 
    log(GPA) + log(libvol) + log(cost), data = dados)
mod1$AIC <- AIC(mod1)
mod2$AIC <- AIC(mod2)
mod3$AIC <- AIC(mod3)
mod1$BIC <- BIC(mod1)
mod2$BIC <- BIC(mod2)
mod3$BIC <- BIC(mod3)
library(stargazer)
star.1 <- stargazer(mod1, mod2, mod3, title = "Título: Resultados das Regressões", 
    column.labels = c("MQO-mod1", "MQO-mod2", "MQO-mod3"), align = TRUE, type = "text", 
    keep.stat = c("aic", "bic", "rsq", "adj.rsq", "n"))

Título: Resultados das Regressões
=========================================================
                             Dependent variable:         
                    -------------------------------------
                    log(salary)   (salary)    log(salary)
                     MQO-mod1     MQO-mod2     MQO-mod3  
                        (1)          (2)          (3)    
---------------------------------------------------------
log(rank)            -0.227***                           
                      (0.019)                            
                                                         
top10                                          0.700***  
                                                (0.053)  
                                                         
r11_25                                         0.593***  
                                                (0.039)  
                                                         
r26_40                                         0.374***  
                                                (0.034)  
                                                         
r41_60                                         0.262***  
                                                (0.028)  
                                                         
r61.100                                        0.131***  
                                                (0.021)  
                                                         
log(LSAT)              0.726                    0.885*   
                      (0.559)                   (0.472)  
                                                         
log(GPA)               0.191                     0.057   
                      (0.282)                   (0.239)  
                                                         
log(libvol)            0.017                     0.036   
                      (0.033)                   (0.026)  
                                                         
log(cost)              0.008                     0.001   
                      (0.029)                   (0.025)  
                                                         
rank                             -115.815***             
                                  (16.153)               
                                                         
LSAT                               155.286               
                                  (192.598)              
                                                         
GPA                             14,500.240***            
                                 (4,357.070)             
                                                         
libvol                            12.956***              
                                   (3.261)               
                                                         
cost                               0.366**               
                                   (0.146)               
                                                         
Constant             7.383***    -33,124.550    5.562**  
                      (2.577)   (25,210.760)    (2.141)  
                                                         
---------------------------------------------------------
Observations            136          136          136    
R2                     0.870        0.806        0.911   
Adjusted R2            0.865        0.798        0.905   
Akaike Inf. Crit.    -227.844     2,737.692    -271.086  
Bayesian Inf. Crit.  -207.455     2,758.080    -239.046  
=========================================================
Note:                         *p<0.1; **p<0.05; ***p<0.01

3.1 Correlação

library(corrplot)
corel <- cor(dados)
corrplot(corel, method = "number")

3.2 Teste de Multicolinearidade (vif)

library(car)
reg1.vif <- vif(mod1)
reg1.vif
  log(rank)   log(LSAT)    log(GPA) log(libvol)   log(cost) 
   4.676860    3.456882    3.636916    2.475024    1.621828 
reg2.vif <- vif(mod2)
reg2.vif
    rank     LSAT      GPA   libvol     cost 
2.777994 3.469461 3.264910 1.735231 1.558141 
reg3.vif <- vif(mod3)
reg3.vif
      top10      r11_25      r26_40      r41_60     r61.100   log(LSAT) 
   3.488650    2.635882    1.730471    1.589780    1.542470    3.478267 
   log(GPA) log(libvol)   log(cost) 
   3.693818    2.225695    1.653360 

Conclusão: Não tenho evidências de multicolinearidade prejudicial ao modelo.

3.3 Heterocedasticidade no modelo 3

3.3.1 Teste de White

lmtest::bptest(mod3, ~log(LSAT) + log(GPA) + log(libvol) + log(cost) + I(log(LSAT)^2) + 
    I(log(GPA)^2) + I(log(libvol)^2) + I(log(cost)^2), data = dados)

    studentized Breusch-Pagan test

data:  mod3
BP = 15.673, df = 8, p-value = 0.04731

Concluo pela presença de heterocedasticidade dos resíduos em mod3.

3.3.2 Correção de Var-cov conforme White

library(car)
# possibilidades: hccm(regressao1,type=c('hc0','hc1','hc2','hc3','hc4'))
vcov.white0 <- hccm(mod3, type = c("hc1"))
# 
lmtest::coeftest(mod3, vcov.white0)

t test of coefficients:

             Estimate Std. Error t value  Pr(>|t|)    
(Intercept) 5.5619076  2.1432862  2.5950   0.01058 *  
top10       0.7002290  0.0572244 12.2365 < 2.2e-16 ***
r11_25      0.5931739  0.0467471 12.6890 < 2.2e-16 ***
r26_40      0.3744336  0.0524192  7.1431 6.463e-11 ***
r41_60      0.2623891  0.0263407  9.9613 < 2.2e-16 ***
r61.100     0.1311293  0.0181522  7.2239 4.248e-11 ***
log(LSAT)   0.8847047  0.4854581  1.8224   0.07076 .  
log(GPA)    0.0570718  0.2579492  0.2213   0.82525    
log(libvol) 0.0362878  0.0259046  1.4008   0.16372    
log(cost)   0.0010463  0.0293381  0.0357   0.97161    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
summary(mod3)

Call:
lm(formula = log(salary) ~ top10 + r11_25 + r26_40 + r41_60 + 
    r61.100 + log(LSAT) + log(GPA) + log(libvol) + log(cost), 
    data = dados)

Residuals:
      Min        1Q    Median        3Q       Max 
-0.294920 -0.040379 -0.001164  0.044715  0.277004 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept) 5.561908   2.140706   2.598   0.0105 *  
top10       0.700229   0.052517  13.333  < 2e-16 ***
r11_25      0.593174   0.039208  15.129  < 2e-16 ***
r26_40      0.374434   0.034036  11.001  < 2e-16 ***
r41_60      0.262389   0.027979   9.378 3.57e-16 ***
r61.100     0.131129   0.021049   6.230 6.42e-09 ***
log(LSAT)   0.884705   0.471736   1.875   0.0630 .  
log(GPA)    0.057072   0.239032   0.239   0.8117    
log(libvol) 0.036288   0.025998   1.396   0.1652    
log(cost)   0.001046   0.025055   0.042   0.9668    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 0.08558 on 126 degrees of freedom
  (20 observations deleted due to missingness)
Multiple R-squared:  0.9111,    Adjusted R-squared:  0.9047 
F-statistic: 143.4 on 9 and 126 DF,  p-value: < 2.2e-16
# fazer stargazer com dois modelos
cov <- vcov.white0
robust.se <- sqrt(diag(cov))

stargazer(mod3, mod3, se = list(NULL, robust.se), column.labels = c("MQO-mod3", 
    "mod3 robusto"), title = "Título: Resultado da Regressão", align = TRUE, 
    type = "text", style = "all", keep.stat = c("aic", "bic", "rsq", "adj.rsq", 
        "n"))

Título: Resultado da Regressão
================================================
                        Dependent variable:     
                    ----------------------------
                            log(salary)         
                       MQO-mod3    mod3 robusto 
                         (1)            (2)     
------------------------------------------------
top10                  0.700***      0.700***   
                       (0.053)        (0.057)   
                      t = 13.333    t = 12.237  
                      p = 0.000      p = 0.000  
r11_25                 0.593***      0.593***   
                       (0.039)        (0.047)   
                      t = 15.129    t = 12.689  
                      p = 0.000      p = 0.000  
r26_40                 0.374***      0.374***   
                       (0.034)        (0.052)   
                      t = 11.001     t = 7.143  
                      p = 0.000      p = 0.000  
r41_60                 0.262***      0.262***   
                       (0.028)        (0.026)   
                      t = 9.378      t = 9.961  
                      p = 0.000      p = 0.000  
r61.100                0.131***      0.131***   
                       (0.021)        (0.018)   
                      t = 6.230      t = 7.224  
                      p = 0.000      p = 0.000  
log(LSAT)               0.885*        0.885*    
                       (0.472)        (0.485)   
                      t = 1.875      t = 1.822  
                      p = 0.064      p = 0.069  
log(GPA)                0.057          0.057    
                       (0.239)        (0.258)   
                      t = 0.239      t = 0.221  
                      p = 0.812      p = 0.825  
log(libvol)             0.036          0.036    
                       (0.026)        (0.026)   
                      t = 1.396      t = 1.401  
                      p = 0.166      p = 0.162  
log(cost)               0.001          0.001    
                       (0.025)        (0.029)   
                      t = 0.042      t = 0.036  
                      p = 0.967      p = 0.972  
Constant               5.562**       5.562***   
                       (2.141)        (2.143)   
                      t = 2.598      t = 2.595  
                      p = 0.011      p = 0.010  
------------------------------------------------
Observations             136            136     
R2                      0.911          0.911    
Adjusted R2             0.905          0.905    
Akaike Inf. Crit.      -271.086      -271.086   
Bayesian Inf. Crit.    -239.046      -239.046   
================================================
Note:                *p<0.1; **p<0.05; ***p<0.01

3.4 Autocorrelação dos resíduos

library(car)
library(lmtest)
library(sandwich)

dw.mod3 <- dwtest(mod3)
dw.mod3

    Durbin-Watson test

data:  mod3
DW = 1.9225, p-value = 0.3026
alternative hypothesis: true autocorrelation is greater than 0

Fiz uma rotina para rodar vários BGtest até ordem 12.

# padrao do teste de BG, com distribuição qui-quadrado
bgorder = 1:12  # definindo até a máxima ordem do bgtest
d = NULL
for (p in bgorder) {
    bgtest.chi <- bgtest(mod3, order = p, type = c("Chisq"), data = dados)
    print(bgtest.chi)
    d = rbind(d, data.frame(bgtest.chi$statistic, bgtest.chi$p.value))
}

    Breusch-Godfrey test for serial correlation of order up to 1

data:  mod3
LM test = 0.1924, df = 1, p-value = 0.6609


    Breusch-Godfrey test for serial correlation of order up to 2

data:  mod3
LM test = 0.20033, df = 2, p-value = 0.9047


    Breusch-Godfrey test for serial correlation of order up to 3

data:  mod3
LM test = 0.20195, df = 3, p-value = 0.9773


    Breusch-Godfrey test for serial correlation of order up to 4

data:  mod3
LM test = 0.28421, df = 4, p-value = 0.9908


    Breusch-Godfrey test for serial correlation of order up to 5

data:  mod3
LM test = 0.46994, df = 5, p-value = 0.9932


    Breusch-Godfrey test for serial correlation of order up to 6

data:  mod3
LM test = 0.47794, df = 6, p-value = 0.9981


    Breusch-Godfrey test for serial correlation of order up to 7

data:  mod3
LM test = 0.5817, df = 7, p-value = 0.9991


    Breusch-Godfrey test for serial correlation of order up to 8

data:  mod3
LM test = 0.78819, df = 8, p-value = 0.9993


    Breusch-Godfrey test for serial correlation of order up to 9

data:  mod3
LM test = 0.89366, df = 9, p-value = 0.9996


    Breusch-Godfrey test for serial correlation of order up to 10

data:  mod3
LM test = 0.9225, df = 10, p-value = 0.9999


    Breusch-Godfrey test for serial correlation of order up to 11

data:  mod3
LM test = 1.2522, df = 11, p-value = 0.9998


    Breusch-Godfrey test for serial correlation of order up to 12

data:  mod3
LM test = 2.1526, df = 12, p-value = 0.9991
d

Conclusão: não tenho autocorrelação residual.

3.5 Teste de Jarque-Bera para normalidade

u.hat <- resid(mod3)
library(tseries)
JB.mod3 <- jarque.bera.test(u.hat)
JB.mod3

    Jarque Bera Test

data:  u.hat
X-squared = 20.538, df = 2, p-value = 3.47e-05

Rejeito H0 e concluo por resíduos não normais. Preciso verificar outliers.

3.6 Teste RESET de Ramsey com potencias de 2 e 3

TesteRESET.power <- lmtest::resettest(mod3, power = 2:3)
TesteRESET.power

    RESET test

data:  mod3
RESET = 0.30745, df1 = 2, df2 = 124, p-value = 0.7359

3.7 Investigação de outliers - teste de Bonferroni para outlier

outlierTest(mod3)
   rstudent unadjusted p-value Bonferroni p
3 -3.850327          0.0001873     0.025473
qqPlot(mod3)

[1]  3 47
vif(mod3)
      top10      r11_25      r26_40      r41_60     r61.100   log(LSAT) 
   3.488650    2.635882    1.730471    1.589780    1.542470    3.478267 
   log(GPA) log(libvol)   log(cost) 
   3.693818    2.225695    1.653360 

As observações 3 e 47 sugerem outliers a serem controlados. Colocarei uma dummy para ambos.

dados$dummy <- 0
dados$dummy[3] = 1
dados$dummy[47] = 1
dados$dummy[79] = 1

Farei nova regressão partindo de mod3 :

attach(dados)
mod4 <- lm(log(salary) ~ top10 + r11_25 + r26_40 + r41_60 + r61.100 + log(LSAT) + 
    log(GPA) + log(libvol) + log(cost) + dummy + I(dummy * LSAT), data = dados)
mod4$AIC <- AIC(mod4)
mod4$BIC <- BIC(mod4)
mod5 <- lm(log(salary) ~ top10 + r11_25 + r26_40 + r41_60 + r61.100 + log(LSAT) + 
    log(GPA) + log(libvol) + log(cost) + dummy + I(dummy * GPA), data = dados)
mod5$AIC <- AIC(mod5)
mod5$BIC <- BIC(mod5)
mod6 <- lm(log(salary) ~ top10 + r11_25 + r26_40 + r41_60 + r61.100 + log(LSAT) + 
    log(GPA) + log(libvol) + log(cost) + dummy + I(dummy * libvol), data = dados)
mod6$AIC <- AIC(mod6)
mod6$BIC <- BIC(mod6)
mod7 <- lm(log(salary) ~ top10 + r11_25 + r26_40 + r41_60 + r61.100 + log(LSAT) + 
    log(GPA) + log(libvol) + log(cost) + dummy + I(dummy * cost), data = dados)
mod7$AIC <- AIC(mod7)
mod7$BIC <- BIC(mod7)
library(stargazer)
star.2 <- stargazer(mod4, mod5, mod6, mod7, title = "Título: Resultados das Regressões", 
    column.labels = c("MQO-mod4", "MQO-mod5", "MQO-mod6", "MQO-mod7"), align = TRUE, 
    type = "text", keep.stat = c("aic", "bic", "rsq", "adj.rsq", "n"))

Título: Resultados das Regressões
==========================================================
                             Dependent variable:          
                    --------------------------------------
                                 log(salary)              
                    MQO-mod4  MQO-mod5 MQO-mod6  MQO-mod7 
                       (1)      (2)       (3)       (4)   
----------------------------------------------------------
top10               0.717***  0.713*** 0.752***  0.745*** 
                     (0.051)  (0.052)   (0.047)   (0.046) 
                                                          
r11_25              0.604***  0.602*** 0.630***  0.624*** 
                     (0.038)  (0.039)   (0.035)   (0.035) 
                                                          
r26_40              0.356***  0.356*** 0.412***  0.389*** 
                     (0.033)  (0.034)   (0.031)   (0.030) 
                                                          
r41_60              0.268***  0.267*** 0.285***  0.280*** 
                     (0.027)  (0.027)   (0.025)   (0.025) 
                                                          
r61.100             0.134***  0.134*** 0.148***  0.143*** 
                     (0.020)  (0.021)   (0.019)   (0.018) 
                                                          
log(LSAT)            0.853*    0.898*   0.923**   0.774*  
                     (0.461)  (0.468)   (0.417)   (0.417) 
                                                          
log(GPA)             -0.003    0.005    -0.090    -0.074  
                     (0.231)  (0.235)   (0.211)   (0.210) 
                                                          
log(libvol)           0.035    0.034     0.023     0.031  
                     (0.025)  (0.026)   (0.023)   (0.023) 
                                                          
log(cost)            -0.005    -0.005   -0.017    -0.011  
                     (0.025)  (0.025)   (0.022)   (0.022) 
                                                          
dummy               -5.833*** -2.467** 8.269***  -8.352***
                     (2.031)  (1.211)   (1.368)   (1.385) 
                                                          
I(dummy * LSAT)     0.038***                              
                     (0.013)                              
                                                          
I(dummy * GPA)                0.775**                     
                              (0.365)                     
                                                          
I(dummy * libvol)                      -0.020***          
                                        (0.003)           
                                                          
I(dummy * cost)                                  0.0005***
                                                 (0.0001) 
                                                          
Constant            5.852***  5.623*** 5.772***  6.410*** 
                     (2.087)  (2.118)   (1.890)   (1.889) 
                                                          
----------------------------------------------------------
Observations           136      136       136       136   
R2                    0.919    0.917     0.933     0.934  
Adjusted R2           0.912    0.909     0.927     0.928  
Akaike Inf. Crit.   -280.148  -275.942 -305.474  -306.833 
Bayesian Inf. Crit. -242.284  -238.077 -267.610  -268.968 
==========================================================
Note:                          *p<0.1; **p<0.05; ***p<0.01

Testarei novamente para normalidade:

dados$obs <- 1:156
u.hat <- resid(mod7)
library(tseries)
JB.mod7 <- jarque.bera.test(u.hat)
JB.mod7

    Jarque Bera Test

data:  u.hat
X-squared = 0.44485, df = 2, p-value = 0.8006
outlierTest(mod7)
No Studentized residuals with Bonferroni p < 0.05
Largest |rstudent|:
   rstudent unadjusted p-value Bonferroni p
96 2.444258           0.015933           NA
# detectei que o 79 também é outlier
qqPlot(mod7)

[1]  96 134

Agora sim, colocando 3, 47 e 79 como dummies consegui resíduos normais.

TesteRESET.power <- lmtest::resettest(mod7, power = 2:3)
TesteRESET.power

    RESET test

data:  mod7
RESET = 2.2131, df1 = 2, df2 = 122, p-value = 0.1137

Posso considerar o modelo 7 bem especificado, não autocorrelacionado conforme abaixo.

# padrao do teste de BG, com distribuição qui-quadrado
bgorder = 1:12  # definindo até a máxima ordem do bgtest
d = NULL
for (p in bgorder) {
    bgtest.chi <- bgtest(mod7, order = p, type = c("Chisq"), data = dados)
    print(bgtest.chi)
    d = rbind(d, data.frame(bgtest.chi$statistic, bgtest.chi$p.value))
}

    Breusch-Godfrey test for serial correlation of order up to 1

data:  mod7
LM test = 0.06658, df = 1, p-value = 0.7964


    Breusch-Godfrey test for serial correlation of order up to 2

data:  mod7
LM test = 0.72076, df = 2, p-value = 0.6974


    Breusch-Godfrey test for serial correlation of order up to 3

data:  mod7
LM test = 0.8096, df = 3, p-value = 0.8472


    Breusch-Godfrey test for serial correlation of order up to 4

data:  mod7
LM test = 2.1152, df = 4, p-value = 0.7146


    Breusch-Godfrey test for serial correlation of order up to 5

data:  mod7
LM test = 2.2408, df = 5, p-value = 0.8149


    Breusch-Godfrey test for serial correlation of order up to 6

data:  mod7
LM test = 2.2696, df = 6, p-value = 0.8933


    Breusch-Godfrey test for serial correlation of order up to 7

data:  mod7
LM test = 2.2961, df = 7, p-value = 0.9417


    Breusch-Godfrey test for serial correlation of order up to 8

data:  mod7
LM test = 2.3205, df = 8, p-value = 0.9696


    Breusch-Godfrey test for serial correlation of order up to 9

data:  mod7
LM test = 3.0965, df = 9, p-value = 0.9603


    Breusch-Godfrey test for serial correlation of order up to 10

data:  mod7
LM test = 3.4961, df = 10, p-value = 0.9672


    Breusch-Godfrey test for serial correlation of order up to 11

data:  mod7
LM test = 3.4961, df = 11, p-value = 0.9824


    Breusch-Godfrey test for serial correlation of order up to 12

data:  mod7
LM test = 6.1923, df = 12, p-value = 0.9061
d

Vou checar a heterocedasticidade. A dummy somente entra em nível, não adiantando colocar ao quadrado. Não detecto heterocedasticidade. OU seja, ao controlar pelos outliers, resolvi o problema de heterocedasticidade.

lmtest::bptest(mod7, ~log(LSAT) + log(GPA) + log(libvol) + log(cost) + dummy + 
    I(dummy * cost) + I(log(LSAT)^2) + I(log(GPA)^2) + I(log(libvol)^2) + I(log(cost)^2), 
    data = dados)

    studentized Breusch-Pagan test

data:  mod7
BP = 14.633, df = 10, p-value = 0.146

Referências

WOOLDRIDGE, J.M. Introdução à econometria. São Paulo: CENGAGE, 4.ed. 2011.

MOHR, Franz. Chapter 7: Multiple Regression Analysis with Qualitative Information. February 4, 2018. Disponível em: https://www.r-econometrics.com/reproduction/wooldridge/wooldridge07/

LS0tDQp0aXRsZTogIkVjb25vbWV0cmlhOiBTYWzDoXJpb3MgZGUgYWR2b2dhZG9zIC0gV29vbGRyaWRnZShleGVtcGxvIDcuOCkgYWRhcHRhZG8gZGUgTU9IUiAoMjAxOCkiDQphdXRob3I6ICJBZHJpYW5vIE1hcmNvcyBSb2RyaWd1ZXMgRmlndWVpcmVkbywgKmUtbWFpbDogYWRyaWFuby5maWd1ZWlyZWRvQHVmbXMuYnIqIg0KYWJzdHJhY3Q6IA0KICBUaGlzIGlzIGFuIHVuZGVyZ3JhZCBzdHVkZW50IGxldmVsIGV4ZXJjaXNlIGZvciBjbGFzcyB1c2UuIA0KZGF0ZTogImByIGZvcm1hdChTeXMuRGF0ZSgpLCAnJWQgJUIgJVknKWAiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6DQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQ0KICAgIHRoZW1lOiBkZWZhdWx0DQogICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZmxvYXQ6IHllcw0KICAgIGRmX3ByaW50OiBwYWdlZA0KICAgIGZpZ19jYXB0aW9uOiB0cnVlDQogIHBkZl9kb2N1bWVudDoNCiAgICB0b2M6IHllcw0KLS0tDQoNCmBgYHtyIGtuaXRyX2luaXQsIGVjaG89RkFMU0UsIGNhY2hlPUZBTFNFfQ0KbGlicmFyeShrbml0cikNCmxpYnJhcnkocm1hcmtkb3duKQ0KbGlicmFyeShybWRmb3JtYXRzKQ0KDQojIyBHbG9iYWwgb3B0aW9ucw0Kb3B0aW9ucyhtYXgucHJpbnQ9IjEwMCIpDQpvcHRzX2NodW5rJHNldChlY2hvPVRSVUUsDQoJICAgICAgICAgICAgIGNhY2hlPVRSVUUsDQogICAgICAgICAgICAgICBwcm9tcHQ9RkFMU0UsDQogICAgICAgICAgICAgICB0aWR5PVRSVUUsDQogICAgICAgICAgICAgICBjb21tZW50PU5BLA0KICAgICAgICAgICAgICAgbWVzc2FnZT1GQUxTRSwNCiAgICAgICAgICAgICAgIHdhcm5pbmc9RkFMU0UpDQpvcHRzX2tuaXQkc2V0KHdpZHRoPTEwMCkNCmBgYA0KDQoNCkxpY2Vuw6dhIHstI0xpY2Vuw6dhfQ0KPT09PT09PT09PT09PT09PT09PQ0KDQpUaGlzIHdvcmsgaXMgbGljZW5zZWQgdW5kZXIgdGhlIENyZWF0aXZlIENvbW1vbnMgQXR0cmlidXRpb24tU2hhcmVBbGlrZSA0LjAgSW50ZXJuYXRpb25hbCBMaWNlbnNlLiBUbyB2aWV3IGEgY29weSBvZiB0aGlzIGxpY2Vuc2UsIHZpc2l0IDxodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9saWNlbnNlcy9ieS1zYS80LjAvPiBvciBzZW5kIGEgbGV0dGVyIHRvIENyZWF0aXZlIENvbW1vbnMsIFBPIEJveCAxODY2LCBNb3VudGFpbiBWaWV3LCBDQSA5NDA0MiwgVVNBLg0KDQohW0xpY2Vuc2U6IENDIEJZLVNBIDQuMF0oaHR0cHM6Ly9taXJyb3JzLmNyZWF0aXZlY29tbW9ucy5vcmcvcHJlc3NraXQvYnV0dG9ucy84OHgzMS9wbmcvYnktc2EucG5nKXsgd2lkdGg9MjUlIH0NCg0KQ2l0YcOnw6NvIHstI0NpdGHDp8Ojb30NCj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09DQoNClN1Z2VzdMOjbyBkZSBjaXRhw6fDo286DQpGSUdVRUlSRURPLCBBZHJpYW5vIE1hcmNvcyBSb2RyaWd1ZXMuIEVjb25vbWV0cmlhOiBTYWzDoXJpb3MgZGUgYWR2b2dhZG9zIC0gV29vbGRyaWRnZShleGVtcGxvIDcuOCkgYWRhcHRhZG8gZGUgTU9IUiAoMjAxOCkuIENhbXBvIEdyYW5kZS1NUyxCcmFzaWw6IFJTdHVkaW8vUnB1YnMsIDIwMTkuIERpc3BvbsOtdmVsIGVtIDxodHRwOi8vcnB1YnMuY29tL2Ftcm9maS93b29sZHJpZGdlX2V4N184Pi4gDQoNCkludHJvZHXDp8Ojbw0KPT09PT09PT09PT09PT09PT09PQ0KDQoNCj4gTyBkYXRhc2V0IGNvbnTDqW0gZGFkb3Mgc29icmUgYSBtZWRpYW5hIGRvcyBzYWzDoXJpb3MgaW5pY2lhaXMgZG9zIGZvcm1hZG9zIGVtIERpcmVpdG8uIFVtYSB2YXJpw6F2ZWwgZXhwbGljYXRpdmEgw6kgYSBjbGFzc2lmaWNhw6fDo28gZGEgZmFjdWxkYWRlIGN1cnNhZGEuIE8gZ3J1cG8gYmFzZSDDqSBkYXMgZmFjdWxkYWRlcyBjb20gcmFuayBtYWlvciBxdWUgMTAwLiANCg0KRGFkb3MNCj09PT09PT09PT09PT09PT09PT0NCg0KTyBkYXRhLmZyYW1lIGNvbnTDqW0gMTU2IG9ic2VydmHDp8O1ZXMgZGUgMjEgdmFyacOhdmVpcy4gTyBkYXRhc2V0IGVzdMOhIG5vIHBhY290ZSBgd29vbGRyaWRnZWAgYWNlc3NhZG8gZmF6ZW5kbyBgZGF0YSgibGF3c2NoODUiKWA6DQoNCi0gICBWQVJJw4FWRUwgREVQRU5ERU5URTogDQogICAgLSBgc2FsYXJ5YDogbWVkaWFuIHN0YXJ0aW5nIHNhbGFyeQ0KLSAgIENBUkFDVEVSSVNUSUNBUyBET1MgRU5UUkFOVEVTDQogICAgLSBgTFNBVGA6IG1lZGlhbiBMU0FUIChMYXcgU2Nob29sIEFkbWlzc2lvbiBUZXN0KSBzY29yZSANCiAgICAtIGBHUEFgOiBtZWRpYW4gY29sbGVnZSBHUEEgKEdyYWRlIFBvaW50IEF2ZXJhZ2UpDQotICAgQ0FSQUNURVJJU1RJQ0FTIERBIEVTQ09MQQ0KICAgIC0gYHJhbmtgOiBsYXcgc2Nob29sIHJhbmtpbmcNCiAgICAtIGBjb3N0YDogbGF3IHNjaG9vbCBjb3N0DQogICAgLSBgbGlidm9sYDogbm8uIHZvbHVtZXMgaW4gbGliLiwgMTAwMHMNCi0gICBWQVJJQVZFSVMgREVSSVZBREFTDQogICAgLSBgbHNhbGFyeWA6IGxvZyhzYWxhcnkpDQogICAgLSBgdG9wMTBgOiA9MSBpZiByYW5rZWQgaW4gdG9wIDEwDQogICAgLSBgcjExXzI1YDogPTEgaWYgcmFua2VkIDExLTI1DQogICAgLSBgcjI2XzQwYDogPTEgaWYgcmFua2VkIDI2LTQwDQogICAgLSBgcjQxXzYwYDogPTEgaWYgcmFua2VkIDQxLTYwDQogICAgLSBgbGxpYnZvbGA6IGxvZyhsaWJ2b2wpDQogICAgLSBgbGNvc3RgOiBsb2coY29zdCkNCg0KUmVzdWx0YWRvcw0KPT09PT09PT09PT09PT09PT09PQ0KDQpgYGB7cn0NCmxpYnJhcnkod29vbGRyaWRnZSkNCmRhdGEoImxhd3NjaDg1IikNCiMgR2VyYXIgZHVtbWllcyAtIE7Do28gZXJhIG5lY2Vzc8OhcmlvLCBwb2lzIGrDoSBlc3RhdmFtDQojIG5vIGRhdGFzZXQsIG1hcyBjcmlhbW9zIGFiYWl4byBwYXJhIHZlciBjb21vIA0KIyBvIGRhdGFzZXQgY29udGVtIHVtYSB2YXJpw6F2ZWwgcmFuayBwYXJhIG9zIHNhbGFyaW9zIChzYWxhcnkpDQp0b3AxMCA8LSBhcy5udW1lcmljKGxhd3NjaDg1JHJhbmsgPD0gMTApDQpyMTEuMjUgPC0gYXMubnVtZXJpYyhsYXdzY2g4NSRyYW5rID49IDExICYgbGF3c2NoODUkcmFuayA8PSAyNSkNCnIyNi40MCA8LSBhcy5udW1lcmljKGxhd3NjaDg1JHJhbmsgPj0gMjYgJiBsYXdzY2g4NSRyYW5rIDw9IDQwKQ0KcjQxLjYwIDwtIGFzLm51bWVyaWMobGF3c2NoODUkcmFuayA+PSA0MSAmIGxhd3NjaDg1JHJhbmsgPD0gNjApDQpyNjEuMTAwIDwtIGFzLm51bWVyaWMobGF3c2NoODUkcmFuayA+PSA2MSAmIGxhd3NjaDg1JHJhbmsgPD0gMTAwKQ0KYXR0YWNoKGxhd3NjaDg1KQ0KZGFkb3M8LWFzLmRhdGEuZnJhbWUoY2JpbmQoc2FsYXJ5LHJhbmssTFNBVCxHUEEsbGlidm9sLGNvc3QsdG9wMTAscjExXzI1LHIyNl80MCxyNDFfNjAscjYxLjEwMCkpDQpkZXRhY2gobGF3c2NoODUpDQphdHRhY2goZGFkb3MpDQptb2QxIDwtIGxtKGxvZyhzYWxhcnkpIH4gbG9nKHJhbmspICsgbG9nKExTQVQpICsgbG9nKEdQQSkgDQogICAgICAgICAgICsgbG9nKGxpYnZvbCkgKyBsb2coY29zdCksIGRhdGEgPSBkYWRvcykNCm1vZDIgPC0gbG0oKHNhbGFyeSkgfiAocmFuaykgKyAoTFNBVCkgKyAoR1BBKSANCiAgICAgICAgICAgKyAobGlidm9sKSArIChjb3N0KSwgZGF0YSA9IGRhZG9zKQ0KbW9kMyA8LSBsbShsb2coc2FsYXJ5KSB+IHRvcDEwICsgcjExXzI1ICsgcjI2XzQwICsgcjQxXzYwICsgcjYxLjEwMCANCiAgICAgICAgICAgKyBsb2coTFNBVCkgKyBsb2coR1BBKSArIGxvZyhsaWJ2b2wpICsgbG9nKGNvc3QpLCBkYXRhID0gZGFkb3MpDQptb2QxJEFJQyA8LSBBSUMobW9kMSkNCm1vZDIkQUlDIDwtIEFJQyhtb2QyKQ0KbW9kMyRBSUMgPC0gQUlDKG1vZDMpDQptb2QxJEJJQyA8LSBCSUMobW9kMSkNCm1vZDIkQklDIDwtIEJJQyhtb2QyKQ0KbW9kMyRCSUMgPC0gQklDKG1vZDMpDQpsaWJyYXJ5KHN0YXJnYXplcikNCnN0YXIuMSA8LSBzdGFyZ2F6ZXIobW9kMSwgbW9kMiwgbW9kMywNCiAgICAgICAgICAgICAgICAgICAgdGl0bGU9IlTDrXR1bG86IFJlc3VsdGFkb3MgZGFzIFJlZ3Jlc3PDtWVzIiwNCiAgICAgICAgICAgICAgICAgICAgY29sdW1uLmxhYmVscz1jKCJNUU8tbW9kMSIsIk1RTy1tb2QyIiwiTVFPLW1vZDMiKSwNCiAgICAgICAgICAgICAgICAgICAgYWxpZ249VFJVRSwNCiAgICAgICAgICAgICAgICAgICAgdHlwZSA9ICJ0ZXh0IiwNCiAgICAgICAgICAgICAgICAgICAga2VlcC5zdGF0PWMoImFpYyIsImJpYyIsInJzcSIsICJhZGoucnNxIiwibiIpDQopDQoNCmBgYA0KDQojIyBDb3JyZWxhw6fDo28NCg0KDQpgYGB7cn0NCmxpYnJhcnkoY29ycnBsb3QpDQpjb3JlbCA8LSBjb3IoZGFkb3MpDQpjb3JycGxvdChjb3JlbCwgbWV0aG9kID0gIm51bWJlciIpDQpgYGANCg0KIyMgVGVzdGUgZGUgTXVsdGljb2xpbmVhcmlkYWRlICh2aWYpDQoNCmBgYHtyfQ0KbGlicmFyeShjYXIpDQpyZWcxLnZpZjwtdmlmKG1vZDEpDQpyZWcxLnZpZg0KcmVnMi52aWY8LXZpZihtb2QyKQ0KcmVnMi52aWYNCnJlZzMudmlmPC12aWYobW9kMykNCnJlZzMudmlmDQpgYGANCg0KQ29uY2x1c8OjbzogTsOjbyB0ZW5obyBldmlkw6puY2lhcyBkZSBtdWx0aWNvbGluZWFyaWRhZGUgcHJlanVkaWNpYWwgYW8gbW9kZWxvLg0KDQojIyBIZXRlcm9jZWRhc3RpY2lkYWRlIG5vIG1vZGVsbyAzDQoNCiMjIyBUZXN0ZSBkZSBXaGl0ZQ0KDQpgYGB7cn0NCmxtdGVzdDo6YnB0ZXN0KG1vZDMsfiBsb2coTFNBVCkgKyBsb2coR1BBKSArIGxvZyhsaWJ2b2wpICsgbG9nKGNvc3QpKw0KICAgICAgICAgICAgICAgICAgIEkobG9nKExTQVQpXjIpK0kobG9nKEdQQSleMikrDQogICAgICAgICAgICAgICAgICAgSShsb2cobGlidm9sKV4yKStJKGxvZyhjb3N0KV4yKSwgZGF0YSA9IGRhZG9zKQ0KYGBgDQoNCkNvbmNsdW8gcGVsYSBwcmVzZW7Dp2EgZGUgaGV0ZXJvY2VkYXN0aWNpZGFkZSBkb3MgcmVzw61kdW9zIGVtIG1vZDMuDQoNCiMjIyBDb3JyZcOnw6NvIGRlIFZhci1jb3YgY29uZm9ybWUgV2hpdGUNCg0KYGBge3J9DQpsaWJyYXJ5KGNhcikgDQojcG9zc2liaWxpZGFkZXM6IGhjY20ocmVncmVzc2FvMSx0eXBlPWMoImhjMCIsImhjMSIsImhjMiIsImhjMyIsImhjNCIpKQ0KdmNvdi53aGl0ZTA8LWhjY20obW9kMyx0eXBlPWMoImhjMSIpKQ0KIw0KbG10ZXN0Ojpjb2VmdGVzdChtb2QzLHZjb3Yud2hpdGUwKQ0Kc3VtbWFyeShtb2QzKQ0KIyBmYXplciBzdGFyZ2F6ZXIgY29tIGRvaXMgbW9kZWxvcw0KY292IDwtIHZjb3Yud2hpdGUwDQpyb2J1c3Quc2UgPC0gc3FydChkaWFnKGNvdikpDQoNCnN0YXJnYXplcihtb2QzLCBtb2QzLA0KICAgICAgICAgIHNlPWxpc3QoTlVMTCwgcm9idXN0LnNlKSwNCiAgICAgICAgICBjb2x1bW4ubGFiZWxzPWMoIk1RTy1tb2QzIiwibW9kMyByb2J1c3RvIiksIA0KICAgICAgICAgIHRpdGxlPSJUw610dWxvOiBSZXN1bHRhZG8gZGEgUmVncmVzc8OjbyIsDQogICAgICAgICAgYWxpZ249VFJVRSwNCiAgICAgICAgICB0eXBlID0gInRleHQiLCBzdHlsZSA9ICJhbGwiLA0KICAgICAgICAgIGtlZXAuc3RhdD1jKCJhaWMiLCJiaWMiLCJyc3EiLCAiYWRqLnJzcSIsIm4iKSkNCmBgYA0KDQojIyBBdXRvY29ycmVsYcOnw6NvIGRvcyByZXPDrWR1b3MNCg0KYGBge3J9DQpsaWJyYXJ5KGNhcik7IGxpYnJhcnkobG10ZXN0KTtsaWJyYXJ5KHNhbmR3aWNoKQ0KDQpkdy5tb2QzPC1kd3Rlc3QobW9kMykNCmR3Lm1vZDMNCmBgYA0KDQpGaXogdW1hIHJvdGluYSBwYXJhIHJvZGFyIHbDoXJpb3MgQkd0ZXN0IGF0w6kgb3JkZW0gMTIuDQoNCmBgYHtyfQ0KIyBwYWRyYW8gZG8gdGVzdGUgZGUgQkcsIGNvbSBkaXN0cmlidWnDp8OjbyBxdWktcXVhZHJhZG8NCmJnb3JkZXIgPSAxOjEyICAjIGRlZmluaW5kbyBhdMOpIGEgbcOheGltYSBvcmRlbSBkbyBiZ3Rlc3QNCmQ9TlVMTA0KZm9yIChwIGluIGJnb3JkZXIpIHsNCiAgYmd0ZXN0LmNoaTwtYmd0ZXN0KG1vZDMsDQogICAgICAgICAgICAgICAgICAgICBvcmRlciA9IHAsdHlwZT1jKCJDaGlzcSIpLCBkYXRhID0gZGFkb3MpDQogIHByaW50KGJndGVzdC5jaGkpIA0KICBkID0gcmJpbmQoZCwgDQogICAgICAgICAgICAgICAgIGRhdGEuZnJhbWUoYmd0ZXN0LmNoaSRzdGF0aXN0aWMsYmd0ZXN0LmNoaSRwLnZhbHVlKSkNCiAgfQ0KZA0KYGBgDQoNCkNvbmNsdXPDo286IG7Do28gdGVuaG8gYXV0b2NvcnJlbGHDp8OjbyByZXNpZHVhbC4NCg0KIyMgVGVzdGUgZGUgSmFycXVlLUJlcmEgcGFyYSBub3JtYWxpZGFkZQ0KDQpgYGB7cn0NCnUuaGF0PC1yZXNpZChtb2QzKQ0KbGlicmFyeSh0c2VyaWVzKQ0KSkIubW9kMzwtamFycXVlLmJlcmEudGVzdCh1LmhhdCkNCkpCLm1vZDMNCmBgYA0KDQpSZWplaXRvIEgwIGUgY29uY2x1byBwb3IgcmVzw61kdW9zIG7Do28gbm9ybWFpcy4gUHJlY2lzbyB2ZXJpZmljYXIgb3V0bGllcnMuDQoNCiMjIFRlc3RlIFJFU0VUIGRlIFJhbXNleSBjb20gcG90ZW5jaWFzIGRlIDIgZSAzIA0KDQpgYGB7cn0NClRlc3RlUkVTRVQucG93ZXI8LWxtdGVzdDo6cmVzZXR0ZXN0KG1vZDMsIHBvd2VyID0gMjozKQ0KVGVzdGVSRVNFVC5wb3dlcg0KDQpgYGANCg0KIyMgSW52ZXN0aWdhw6fDo28gZGUgb3V0bGllcnMgLSB0ZXN0ZSBkZSBCb25mZXJyb25pIHBhcmEgb3V0bGllcg0KDQpgYGB7cn0NCm91dGxpZXJUZXN0KG1vZDMpDQpxcVBsb3QobW9kMykNCnZpZihtb2QzKQ0KYGBgDQoNCkFzIG9ic2VydmHDp8O1ZXMgMyBlIDQ3IHN1Z2VyZW0gb3V0bGllcnMgYSBzZXJlbSBjb250cm9sYWRvcy4gQ29sb2NhcmVpIHVtYSBkdW1teSBwYXJhIGFtYm9zLiANCg0KYGBge3J9DQpkYWRvcyRkdW1teTwtMA0KZGFkb3MkZHVtbXlbM109MQ0KZGFkb3MkZHVtbXlbNDddPTENCmRhZG9zJGR1bW15Wzc5XT0xDQpgYGANCg0KRmFyZWkgbm92YSByZWdyZXNzw6NvIHBhcnRpbmRvIGRlIG1vZDMgOg0KDQpgYGB7cn0NCmF0dGFjaChkYWRvcykNCm1vZDQgPC0gbG0obG9nKHNhbGFyeSkgfiB0b3AxMCArIHIxMV8yNSArIHIyNl80MCArIHI0MV82MCArIHI2MS4xMDAgDQogICAgICAgICAgICsgbG9nKExTQVQpICsgbG9nKEdQQSkgKyBsb2cobGlidm9sKSArIGxvZyhjb3N0KStkdW1teSsNCiAgICAgICAgICAgICBJKGR1bW15KkxTQVQpLCBkYXRhID0gZGFkb3MpDQptb2Q0JEFJQyA8LSBBSUMobW9kNCkNCm1vZDQkQklDIDwtIEJJQyhtb2Q0KQ0KbW9kNSA8LSBsbShsb2coc2FsYXJ5KSB+IHRvcDEwICsgcjExXzI1ICsgcjI2XzQwICsgcjQxXzYwICsgcjYxLjEwMCANCiAgICAgICAgICAgKyBsb2coTFNBVCkgKyBsb2coR1BBKSArIGxvZyhsaWJ2b2wpICsgbG9nKGNvc3QpK2R1bW15Kw0KICAgICAgICAgICAgIEkoZHVtbXkqR1BBKSwgZGF0YSA9IGRhZG9zKQ0KbW9kNSRBSUMgPC0gQUlDKG1vZDUpDQptb2Q1JEJJQyA8LSBCSUMobW9kNSkNCm1vZDYgPC0gbG0obG9nKHNhbGFyeSkgfiB0b3AxMCArIHIxMV8yNSArIHIyNl80MCArIHI0MV82MCArIHI2MS4xMDAgDQogICAgICAgICAgICsgbG9nKExTQVQpICsgbG9nKEdQQSkgKyBsb2cobGlidm9sKSArIGxvZyhjb3N0KStkdW1teSsNCiAgICAgICAgICAgICBJKGR1bW15KmxpYnZvbCksIGRhdGEgPSBkYWRvcykNCm1vZDYkQUlDIDwtIEFJQyhtb2Q2KQ0KbW9kNiRCSUMgPC0gQklDKG1vZDYpDQptb2Q3IDwtIGxtKGxvZyhzYWxhcnkpIH4gdG9wMTAgKyByMTFfMjUgKyByMjZfNDAgKyByNDFfNjAgKyByNjEuMTAwIA0KICAgICAgICAgICArIGxvZyhMU0FUKSArIGxvZyhHUEEpICsgbG9nKGxpYnZvbCkgKyBsb2coY29zdCkrZHVtbXkrDQogICAgICAgICAgICAgSShkdW1teSpjb3N0KSwgZGF0YSA9IGRhZG9zKQ0KbW9kNyRBSUMgPC0gQUlDKG1vZDcpDQptb2Q3JEJJQyA8LSBCSUMobW9kNykNCmxpYnJhcnkoc3RhcmdhemVyKQ0Kc3Rhci4yIDwtIHN0YXJnYXplcihtb2Q0LCBtb2Q1LG1vZDYsbW9kNywNCiAgICAgICAgICAgICAgICAgICAgdGl0bGU9IlTDrXR1bG86IFJlc3VsdGFkb3MgZGFzIFJlZ3Jlc3PDtWVzIiwNCiAgICAgICAgICAgICAgICAgICAgY29sdW1uLmxhYmVscz1jKCJNUU8tbW9kNCIsIk1RTy1tb2Q1IiwiTVFPLW1vZDYiLCJNUU8tbW9kNyIpLA0KICAgICAgICAgICAgICAgICAgICBhbGlnbj1UUlVFLA0KICAgICAgICAgICAgICAgICAgICB0eXBlID0gInRleHQiLA0KICAgICAgICAgICAgICAgICAgICBrZWVwLnN0YXQ9YygiYWljIiwiYmljIiwicnNxIiwgImFkai5yc3EiLCJuIikNCikNCg0KYGBgDQoNClRlc3RhcmVpIG5vdmFtZW50ZSBwYXJhIG5vcm1hbGlkYWRlOg0KDQpgYGB7cn0NCmRhZG9zJG9iczwtMToxNTYNCnUuaGF0PC1yZXNpZChtb2Q3KQ0KbGlicmFyeSh0c2VyaWVzKQ0KSkIubW9kNzwtamFycXVlLmJlcmEudGVzdCh1LmhhdCkNCkpCLm1vZDcNCm91dGxpZXJUZXN0KG1vZDcpDQojIGRldGVjdGVpIHF1ZSBvIDc5IHRhbWLDqW0gw6kgb3V0bGllcg0KcXFQbG90KG1vZDcpDQpgYGANCg0KQWdvcmEgc2ltLCBjb2xvY2FuZG8gMywgNDcgZSA3OSBjb21vIGR1bW1pZXMgY29uc2VndWkgcmVzw61kdW9zIG5vcm1haXMuDQoNCmBgYHtyfQ0KVGVzdGVSRVNFVC5wb3dlcjwtbG10ZXN0OjpyZXNldHRlc3QobW9kNywgcG93ZXIgPSAyOjMpDQpUZXN0ZVJFU0VULnBvd2VyDQoNCmBgYA0KDQpQb3NzbyBjb25zaWRlcmFyIG8gbW9kZWxvIDcgYmVtIGVzcGVjaWZpY2FkbywgbsOjbyBhdXRvY29ycmVsYWNpb25hZG8gY29uZm9ybWUgYWJhaXhvLg0KDQpgYGB7cn0NCiMgcGFkcmFvIGRvIHRlc3RlIGRlIEJHLCBjb20gZGlzdHJpYnVpw6fDo28gcXVpLXF1YWRyYWRvDQpiZ29yZGVyID0gMToxMiAgIyBkZWZpbmluZG8gYXTDqSBhIG3DoXhpbWEgb3JkZW0gZG8gYmd0ZXN0DQpkPU5VTEwNCmZvciAocCBpbiBiZ29yZGVyKSB7DQogIGJndGVzdC5jaGk8LWJndGVzdChtb2Q3LA0KICAgICAgICAgICAgICAgICAgICAgb3JkZXIgPSBwLHR5cGU9YygiQ2hpc3EiKSwgZGF0YSA9IGRhZG9zKQ0KICBwcmludChiZ3Rlc3QuY2hpKSANCiAgZCA9IHJiaW5kKGQsIA0KICAgICAgICAgICAgICAgICBkYXRhLmZyYW1lKGJndGVzdC5jaGkkc3RhdGlzdGljLGJndGVzdC5jaGkkcC52YWx1ZSkpDQogIH0NCmQNCmBgYA0KDQpWb3UgY2hlY2FyIGEgaGV0ZXJvY2VkYXN0aWNpZGFkZS4gQSBkdW1teSBzb21lbnRlIGVudHJhIGVtIG7DrXZlbCwgbsOjbyBhZGlhbnRhbmRvIGNvbG9jYXIgYW8gcXVhZHJhZG8uIE7Do28gZGV0ZWN0byBoZXRlcm9jZWRhc3RpY2lkYWRlLiBPVSBzZWphLCBhbyBjb250cm9sYXIgcGVsb3Mgb3V0bGllcnMsIHJlc29sdmkgbyBwcm9ibGVtYSBkZSBoZXRlcm9jZWRhc3RpY2lkYWRlLg0KDQpgYGB7cn0NCmxtdGVzdDo6YnB0ZXN0KG1vZDcsfiBsb2coTFNBVCkgKyBsb2coR1BBKSArIGxvZyhsaWJ2b2wpICsgbG9nKGNvc3QpDQogICAgICAgICAgICAgICAgICtkdW1teStJKGR1bW15KmNvc3QpKw0KICAgICAgICAgICAgICAgICAgIEkobG9nKExTQVQpXjIpK0kobG9nKEdQQSleMikrDQogICAgICAgICAgICAgICAgICAgSShsb2cobGlidm9sKV4yKStJKGxvZyhjb3N0KV4yKSwgZGF0YSA9IGRhZG9zKQ0KYGBgDQoNCg0KUmVmZXLDqm5jaWFzIHstI1JlZmVyw6puY2lhc30NCj09PT09PT09PT09PT09PT09PT09PT09PQ0KDQpXT09MRFJJREdFLCBKLk0uIEludHJvZHXDp8OjbyDDoCBlY29ub21ldHJpYS4gU8OjbyBQYXVsbzogQ0VOR0FHRSwgNC5lZC4gMjAxMS4gICAgDQoNCk1PSFIsIEZyYW56LiBDaGFwdGVyIDc6IE11bHRpcGxlIFJlZ3Jlc3Npb24gQW5hbHlzaXMgd2l0aCBRdWFsaXRhdGl2ZSBJbmZvcm1hdGlvbi4NCiBGZWJydWFyeSA0LCAyMDE4LiBEaXNwb27DrXZlbCBlbTogPGh0dHBzOi8vd3d3LnItZWNvbm9tZXRyaWNzLmNvbS9yZXByb2R1Y3Rpb24vd29vbGRyaWRnZS93b29sZHJpZGdlMDcvPiA=