Datos De Panel

Introducción

En esta clase veremos como construir un pool de datos de panel utilizando múltiples bases de la EPH. El ejercicio consiste en analizar las transiciones individuales entre las distintas categorías y estados ocupacionales. Trabajaremos con un caso sencillo, sin reclasificar a la población en más que las categorías definidas por la EPH. A su vez, para maximizar la cantidad de casos del ejercicio utilizando las bases recientemente publicadas, trabajaremos con transiciones entre trimestres (Aunque en la práctica suelen realizarse paneles anuales para observar más movilidad)

Comenzamos limpiando la memoria y creando los directorios

rm(list=ls())
dir <- paste0(dirname(rstudioapi::getActiveDocumentContext()$path),"/")
bases.dir      <-  paste0(dirname(dir),"/Fuentes/")
resultados.dir <- paste0(dirname(dir),"/Resultados/")

Cargamos la librería tidyverse con la cual trabajaremos para procesar la información

library(tidyverse, warn = FALSE)

Levantamos las Bases Individuales de 4 trimestres publicados.

individual.216 <- read.table(paste0(bases.dir, "usu_individual_t216.txt"), sep=";", dec=",", header = TRUE, fill = TRUE)
individual.316 <- read.table(paste0(bases.dir, "usu_individual_t316.txt"), sep=";", dec=",", header = TRUE, fill = TRUE)
individual.416 <- read.table(paste0(bases.dir, "usu_individual_t416.txt"), sep=";", dec=",", header = TRUE, fill = TRUE)
individual.117 <- read.table(paste0(bases.dir, "usu_individual_t117.txt"), sep=";", dec=",", header = TRUE, fill = TRUE)

Pasos para la construccion del Panel

  1. Creamos un Vector que contenga unicamente las variables de interés, para recortar luego la base con la funcion select.
  2. Unimos todas las bases con la función bind_rows, seleccionando solo las variables del vector.
  3. Filtramos de la base los casos de no respuesta y acotaremos en este ejercicio el analisis a la población entre 18 y 65 años.
  4. Creamos las categorías de análisis que deseamos observar en distintos perídos.
  5. Armamos un identificador ordinal para los registros de cada trimestre.
  6. Replicamos el dataframe construido y le cambiamos los nombres a todas las variables, a excepción de las que usaremos para identificar a un mismo individuo ( CODUSU, NRO_HOGAR, COMPONENTE).
  7. En la base replicada, modificamos el identificador ordinal en función de la amplitud que deseamos en las observaciones de panel. En nuestro caso como uniremos registros con distancia de 1 trimestre, le restamos 1 a cada valor
  8. Unimos ambas bases con la funcion inner_join que solo nos dejará registros que en ambas bases contengn los mismos CODUSU, NRO_HOGAR, COMPONENTE e identificador ordinal.
  9. Creamos la columna para las consistencias, y luego filtramos la base para eliminar los registros inconsistentes
#Paso 1
var.ind <- c('CODUSU','NRO_HOGAR','COMPONENTE', 'ANO4','TRIMESTRE','ESTADO','CAT_OCUP','PONDERA', 'CH04', 'CH06','P21','PP3E_TOT')
#Paso 2  
Bases_Continua <- bind_rows(
  individual.216  %>% select(var.ind),
  individual.316  %>% select(var.ind),
  individual.416  %>% select(var.ind),
  individual.117  %>% select(var.ind))
#Pasos 3  y 4
Bases_Continua <-  Bases_Continua %>% 
      filter(CH06 %in% c(18:65),ESTADO !=0) %>% 
      mutate(Categoria = case_when(ESTADO %in%  c(3,4)~"Inactivos",
                                   ESTADO   ==  2 ~"Desocupados",
                                   ESTADO   ==  1 & CAT_OCUP == 1 ~"Patrones",
                                   ESTADO   ==  1 & CAT_OCUP == 2 ~"Cuenta Propistas",
                                   ESTADO   ==  1 & CAT_OCUP == 3 ~"Asalariados",
                                   ESTADO   ==  1 & CAT_OCUP == 4 ~"Trabajador familiar s/r",
                              TRUE ~ "Otros"))
#Paso  5
Bases_Continua <- Bases_Continua %>% 
    mutate(Trimestre = paste(ANO4, TRIMESTRE, sep="_")) %>% 
    arrange(Trimestre) %>% 
    mutate(Id_Trimestre = match(Trimestre,unique(Trimestre)))
#Paso 6
Bases_Continua_Replica <- Bases_Continua
names(Bases_Continua_Replica)
 [1] "CODUSU"       "NRO_HOGAR"    "COMPONENTE"   "ANO4"         "TRIMESTRE"   
 [6] "ESTADO"       "CAT_OCUP"     "PONDERA"      "CH04"         "CH06"        
[11] "P21"          "PP3E_TOT"     "Categoria"    "Trimestre"    "Id_Trimestre"
names(Bases_Continua_Replica)[4:(length(Bases_Continua_Replica)-1)] <- 
  paste0(names(Bases_Continua_Replica)[4:(length(Bases_Continua_Replica)-1)],"_t1")
names(Bases_Continua_Replica)
 [1] "CODUSU"       "NRO_HOGAR"    "COMPONENTE"   "ANO4_t1"      "TRIMESTRE_t1"
 [6] "ESTADO_t1"    "CAT_OCUP_t1"  "PONDERA_t1"   "CH04_t1"      "CH06_t1"     
[11] "P21_t1"       "PP3E_TOT_t1"  "Categoria_t1" "Trimestre_t1" "Id_Trimestre"
#Paso 7
Bases_Continua_Replica$Id_Trimestre <- Bases_Continua_Replica$Id_Trimestre - 1
#Pasos 8 y 9
Panel_Continua <- inner_join(Bases_Continua,Bases_Continua_Replica)
Joining, by = c("CODUSU", "NRO_HOGAR", "COMPONENTE", "Id_Trimestre")
Panel_Continua <- Panel_Continua %>% 
    mutate(Consistencia = case_when(abs(CH06_t1-CH06) > 2 |
                                    CH04 != CH04_t1 ~ "inconsistente",
                                    TRUE ~ "consistente")) %>% 
    filter(Consistencia == "consistente")

Matrices de transición

Calculo de probabilidades de transición.

Realizaremos un breve ejercicio para identificar la magnitud relativa de las transiciones entre las distintas categorías ocupacionales. Para ello calculamos la suma ponderada de la cantidad de casos observados para cada posible combinación de Cateogria y Categoria_t1. Luego calcularemos la probabilidad de encontrarse en categoría en t1, condicional a haber pertenecido a las distintas categorías en t0.

Categorias_transiciones <- Panel_Continua %>% 
  #filter(Categoria != Categoria_t1) %>% 
  group_by(Categoria,Categoria_t1) %>% 
  summarise(frec_muestral = n(),
            frecuencia = sum((PONDERA+PONDERA_t1/2))) %>% 
  ungroup() %>% 
  group_by(Categoria) %>% 
  mutate(Prob_salida = frecuencia/sum(frecuencia))

Notese que la linea comentada en el medio de la cadena de pipes, nos permitiría iterar rapidamente sobre el procedimiento anterior agregando un filtro. En este ejemplo, podríamos recalcular las proporciones únicamente para aquellas personas que presentan un movimiento de categoría

Gráfico de Matriz de Transición

library(ggthemes)
ggplot(Categorias_transiciones, aes(x = Categoria_t1, 
                                    y = Categoria, fill = Prob_salida,
                                    label =round(Prob_salida*100,2))) +
  labs(title = "Probabilidades de Transicion de hacia las distintas Categorías")+
  geom_tile()+
  geom_text()+
  scale_fill_gradient(low = "grey100", high = "grey30")+
  theme_tufte()

Regresión lineal

A continuación veremos una breve introducción a los comandos básicos que se utilizan para realizar econometría en R. En primera instancia observaremos la correlación entre dos variables, y luego haremos un test de correlación. Elegimos un caso simple, como observar la relación entre la cantidad de horas de horas trabajadas en la ocupación principal ( PP3E_TOT ) y el ingreso por la ocupación principal ( P21). Retomamos el trabajo con la información completa de las bases, dejando a un lado el panel construido.

Visualización Previa de la información

Grafiquemos rápidamente para tener una intuición:

plot(Bases_Continua$PP3E_TOT,Bases_Continua$P21)

Como vemos aquí la función plot nos ayuda para mirar un poco la información antes de realizar un test o un modelo econométrico. En este caso, nos permite observar que en PP3E_TOT tenemos codificados con 999 a aquellos que no respondieron la pregunta por la cantidad de horas.

Bases_Continua_graf <- Bases_Continua %>% filter(PP3E_TOT != 999)
plot(Bases_Continua_graf$PP3E_TOT,Bases_Continua_graf$P21)

En una segunda mirada, podemos ver que tenemos algunos individuos que declarar trabajar las 168 horas de la semana, varios que declaran más de 100 horas, y otros tantos con ingreso 0, o -9 (código para los que no responden la pregunta de ingresos).
Aplicaremos un filtro más para restringir las horas trabajadas por semana a 84 (12*7) y quedarnos con ingresos positivos.

Bases_Continua_listo <- Bases_Continua %>% filter(P21>0,PP3E_TOT %in% c(1:84))
plot(Bases_Continua_listo$PP3E_TOT,Bases_Continua_listo$P21)

Correlación

Luego del pantallazo a través de los gráficos, pasemos a realizar el calculo de la correlación entre las variables a partir de la función cor. Los función puede tomar como argumento dos vectores por separado y calculará el coeficiente de correlación entre ambas variables, o bien puede tomar como argumento un dataframe (O algunas variables del mismo) y arrojará como resultado una matriz cuadrada con los coeficiente de correlación entre cada una de ellas.

cor(Bases_Continua_listo$P21,Bases_Continua_listo$PP3E_TOT)
[1] 0.27738
cor(Bases_Continua_listo$P21,Bases_Continua_listo$CH06)
[1] 0.1679269
cor(Bases_Continua_listo[,c("P21","PP3E_TOT","CH06")])
               P21   PP3E_TOT       CH06
P21      1.0000000 0.27738000 0.16792691
PP3E_TOT 0.2773800 1.00000000 0.01281683
CH06     0.1679269 0.01281683 1.00000000

La función cor.test nos ejecutará el test de correlación sobre dos variables. Necesariamente requiere como argumentos dos vectores por separado.
En la salida podremos observar: el valor del estimador t, el p-valor, la hipotesis alternativa del test y el intervalo de confianza de la estimación.

cor.test(Bases_Continua_listo$P21, Bases_Continua_listo$PP3E_TOT)

    Pearson's product-moment correlation

data:  Bases_Continua_listo$P21 and Bases_Continua_listo$PP3E_TOT
t = 76.274, df = 69797, p-value < 2.2e-16
alternative hypothesis: true correlation is not equal to 0
95 percent confidence interval:
 0.2705180 0.2842138
sample estimates:
    cor 
0.27738 

A su vez, la función tiene otros parametros como por ejemplo conf_level que nos permite definir a gusto el nivel de confianza con el que queremos realizar el test. Por otro lado, la función tiene seteado por default el test de Pearson, pero el parámetro “method” nos permite elejir otros tests.

cor.test(Bases_Continua_listo$P21, Bases_Continua_listo$PP3E_TOT,conf.level = 0.90,
         method = "spearman")
Cannot compute exact p-value with ties

    Spearman's rank correlation rho

data:  Bases_Continua_listo$P21 and Bases_Continua_listo$PP3E_TOT
S = 3.5649e+13, p-value < 2.2e-16
alternative hypothesis: true rho is not equal to 0
sample estimates:
      rho 
0.3710052 

Regresión lineal simple

Para realizar una regresión simple usaremos la función lm. En este caso probaremos la siguiente regresión con las variables que estamos observando: Ingreso de la Ocupación principal como la variable dependiente, y las horas trabajadas en la ocupación principal como la independiente \[ E(P_{21}/horas)= \beta_0 + \beta_1 horas \] La función lm tiene entre sus parametros principales:
formula: En el se especifican las variables que ingresan en el modelo de regresión. El signo de = del modelo se representa aquí mediante el signo ~.
data : Debe especificarse el dataframe que contiene la información de las variables a utilizar en el modelo.

Al ejectuar la función lm() con sus respectivos parametros, podremos visualizar los coeficientes estimados del modelo. Sin embargo, la función summary nos mostrará en más detalle los resultados.

lm(formula = P21 ~ PP3E_TOT, data = Bases_Continua_listo)

Call:
lm(formula = P21 ~ PP3E_TOT, data = Bases_Continua_listo)

Coefficients:
(Intercept)     PP3E_TOT  
     4775.9        153.7  
modelo.ajustado <-lm(formula = P21 ~ PP3E_TOT, data = Bases_Continua_listo)
 
summary(modelo.ajustado)

Call:
lm(formula = P21 ~ PP3E_TOT, data = Bases_Continua_listo)

Residuals:
   Min     1Q Median     3Q    Max 
-17484  -4849  -1996   2848 287540 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept) 4775.924     81.752   58.42   <2e-16 ***
PP3E_TOT     153.672      2.015   76.27   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 8284 on 69797 degrees of freedom
Multiple R-squared:  0.07694,   Adjusted R-squared:  0.07693 
F-statistic:  5818 on 1 and 69797 DF,  p-value: < 2.2e-16
LS0tDQp0aXRsZTogIkNsYXNlIDUuIFBvb2wgZGUgRGF0b3MgZW4gUGFuZWwsIE1hdHJpY2VzIGRlIFRyYW5zaWNpw7NuIHkgUmVncmVzaW9uZXMiDQphdXRob3I6ICJHdWlkbyBXZWtzbGVyIg0KZGF0ZTogIlZpZXJuZXMgMyBkZSBOb3ZpZW1icmUgZGUgMjAxNyINCm91dHB1dDoNCiAgaHRtbF9ub3RlYm9vazoNCiAgICB0b2M6IHllcw0KICAgIHRvY19mbG9hdDogeWVzDQogIGh0bWxfZG9jdW1lbnQ6DQogICAgdG9jOiB5ZXMNCmxhbmc6IGVzDQotLS0NCg0KI0RhdG9zIERlIFBhbmVsIA0KIyNJbnRyb2R1Y2Npw7NuDQpFbiBlc3RhIGNsYXNlIHZlcmVtb3MgY29tbyBjb25zdHJ1aXIgdW4gX3Bvb2xfIGRlIGRhdG9zIGRlIHBhbmVsIHV0aWxpemFuZG8gbcO6bHRpcGxlcyBiYXNlcyBkZSBsYSBFUEguIEVsIGVqZXJjaWNpbyBjb25zaXN0ZSBlbiBhbmFsaXphciBsYXMgdHJhbnNpY2lvbmVzIGluZGl2aWR1YWxlcyBlbnRyZSBsYXMgZGlzdGludGFzIGNhdGVnb3LDrWFzIHkgZXN0YWRvcyBvY3VwYWNpb25hbGVzLg0KVHJhYmFqYXJlbW9zIGNvbiB1biBjYXNvIHNlbmNpbGxvLCBzaW4gcmVjbGFzaWZpY2FyIGEgbGEgcG9ibGFjacOzbiBlbiBtw6FzIHF1ZSBsYXMgY2F0ZWdvcsOtYXMgZGVmaW5pZGFzIHBvciBsYSBFUEguIEEgc3UgdmV6LCBwYXJhIG1heGltaXphciBsYSBjYW50aWRhZCBkZSBjYXNvcyBkZWwgZWplcmNpY2lvIHV0aWxpemFuZG8gbGFzIGJhc2VzIHJlY2llbnRlbWVudGUgcHVibGljYWRhcywgdHJhYmFqYXJlbW9zIGNvbiB0cmFuc2ljaW9uZXMgZW50cmUgdHJpbWVzdHJlcyAoQXVucXVlIGVuIGxhIHByw6FjdGljYSBzdWVsZW4gcmVhbGl6YXJzZSBwYW5lbGVzIGFudWFsZXMgcGFyYSBvYnNlcnZhciBtw6FzIG1vdmlsaWRhZCkNCiANCkNvbWVuemFtb3MgbGltcGlhbmRvIGxhIG1lbW9yaWEgeSBjcmVhbmRvIGxvcyBkaXJlY3Rvcmlvcw0KDQpgYGB7ciwgd2FybmluZz1GQUxTRX0NCnJtKGxpc3Q9bHMoKSkNCg0KZGlyIDwtIHBhc3RlMChkaXJuYW1lKHJzdHVkaW9hcGk6OmdldEFjdGl2ZURvY3VtZW50Q29udGV4dCgpJHBhdGgpLCIvIikNCmJhc2VzLmRpciAgICAgIDwtICBwYXN0ZTAoZGlybmFtZShkaXIpLCIvRnVlbnRlcy8iKQ0KcmVzdWx0YWRvcy5kaXIgPC0gcGFzdGUwKGRpcm5hbWUoZGlyKSwiL1Jlc3VsdGFkb3MvIikNCmBgYA0KDQpDYXJnYW1vcyBsYSBsaWJyZXLDrWEgX3RpZHl2ZXJzZV8gY29uIGxhIGN1YWwgdHJhYmFqYXJlbW9zIHBhcmEgcHJvY2VzYXIgbGEgaW5mb3JtYWNpw7NuDQoNCmBgYHtyfQ0KbGlicmFyeSh0aWR5dmVyc2UsIHdhcm4gPSBGQUxTRSkNCmBgYA0KDQpMZXZhbnRhbW9zIGxhcyBCYXNlcyBJbmRpdmlkdWFsZXMgZGUgNCB0cmltZXN0cmVzIHB1YmxpY2Fkb3MuICAgICAgIA0KDQpgYGB7cn0NCmluZGl2aWR1YWwuMjE2IDwtIHJlYWQudGFibGUocGFzdGUwKGJhc2VzLmRpciwgInVzdV9pbmRpdmlkdWFsX3QyMTYudHh0IiksIHNlcD0iOyIsIGRlYz0iLCIsIGhlYWRlciA9IFRSVUUsIGZpbGwgPSBUUlVFKQ0KaW5kaXZpZHVhbC4zMTYgPC0gcmVhZC50YWJsZShwYXN0ZTAoYmFzZXMuZGlyLCAidXN1X2luZGl2aWR1YWxfdDMxNi50eHQiKSwgc2VwPSI7IiwgZGVjPSIsIiwgaGVhZGVyID0gVFJVRSwgZmlsbCA9IFRSVUUpDQppbmRpdmlkdWFsLjQxNiA8LSByZWFkLnRhYmxlKHBhc3RlMChiYXNlcy5kaXIsICJ1c3VfaW5kaXZpZHVhbF90NDE2LnR4dCIpLCBzZXA9IjsiLCBkZWM9IiwiLCBoZWFkZXIgPSBUUlVFLCBmaWxsID0gVFJVRSkNCmluZGl2aWR1YWwuMTE3IDwtIHJlYWQudGFibGUocGFzdGUwKGJhc2VzLmRpciwgInVzdV9pbmRpdmlkdWFsX3QxMTcudHh0IiksIHNlcD0iOyIsIGRlYz0iLCIsIGhlYWRlciA9IFRSVUUsIGZpbGwgPSBUUlVFKQ0KYGBgDQoNCiMjIFBhc29zIHBhcmEgbGEgY29uc3RydWNjaW9uIGRlbCBQYW5lbA0KMS4gQ3JlYW1vcyB1biBWZWN0b3IgcXVlIGNvbnRlbmdhIHVuaWNhbWVudGUgbGFzIHZhcmlhYmxlcyBkZSBpbnRlcsOpcywgcGFyYSByZWNvcnRhciBsdWVnbyBsYSBiYXNlIGNvbiBsYSBmdW5jaW9uIF9fc2VsZWN0X18uICAgICAgDQoyLiBVbmltb3MgdG9kYXMgbGFzIGJhc2VzIGNvbiBsYSBmdW5jacOzbiBfX2JpbmRfcm93c19fLCBzZWxlY2Npb25hbmRvIHNvbG8gbGFzIHZhcmlhYmxlcyBkZWwgdmVjdG9yLg0KMy4gRmlsdHJhbW9zIGRlIGxhIGJhc2UgbG9zIGNhc29zIGRlIG5vIHJlc3B1ZXN0YSB5IGFjb3RhcmVtb3MgZW4gZXN0ZSBlamVyY2ljaW8gZWwgYW5hbGlzaXMgYSBsYSBwb2JsYWNpw7NuIGVudHJlIDE4IHkgNjUgYcOxb3MuICANCjQuIENyZWFtb3MgbGFzIGNhdGVnb3LDrWFzIGRlIGFuw6FsaXNpcyBxdWUgZGVzZWFtb3Mgb2JzZXJ2YXIgZW4gZGlzdGludG9zIHBlcsOtZG9zLg0KNS4gQXJtYW1vcyB1biBfaWRlbnRpZmljYWRvciBvcmRpbmFsXyBwYXJhIGxvcyByZWdpc3Ryb3MgZGUgY2FkYSB0cmltZXN0cmUuDQo2LiBSZXBsaWNhbW9zIGVsIGRhdGFmcmFtZSBjb25zdHJ1aWRvIHkgbGUgY2FtYmlhbW9zIGxvcyBub21icmVzIGEgdG9kYXMgbGFzIHZhcmlhYmxlcywgYSBleGNlcGNpw7NuIGRlIGxhcyBxdWUgdXNhcmVtb3MgcGFyYSBpZGVudGlmaWNhciBhIHVuIG1pc21vIGluZGl2aWR1byAoIF9DT0RVU1VfLCBfTlJPX0hPR0FSXywgX0NPTVBPTkVOVEVfKS4NCjcuIEVuIGxhIGJhc2UgcmVwbGljYWRhLCBtb2RpZmljYW1vcyBlbCBfaWRlbnRpZmljYWRvciBvcmRpbmFsXyBlbiBmdW5jacOzbiBkZSBsYSBhbXBsaXR1ZCBxdWUgZGVzZWFtb3MgZW4gbGFzIG9ic2VydmFjaW9uZXMgZGUgcGFuZWwuIEVuIG51ZXN0cm8gY2FzbyBjb21vIHVuaXJlbW9zIHJlZ2lzdHJvcyBjb24gZGlzdGFuY2lhIGRlIDEgdHJpbWVzdHJlLCBsZSByZXN0YW1vcyBfMV8gYSBjYWRhIHZhbG9yDQo4LiBVbmltb3MgYW1iYXMgYmFzZXMgY29uIGxhIGZ1bmNpb24gX19pbm5lcl9qb2luX18gcXVlIHNvbG8gbm9zIGRlamFyw6EgcmVnaXN0cm9zIHF1ZSBlbiBhbWJhcyBiYXNlcyBjb250ZW5nbiBsb3MgbWlzbW9zIF9DT0RVU1VfLCBfTlJPX0hPR0FSXywgX0NPTVBPTkVOVEVfIGUgX2lkZW50aWZpY2Fkb3Igb3JkaW5hbF8uDQo5LiBDcmVhbW9zIGxhIGNvbHVtbmEgcGFyYSBsYXMgY29uc2lzdGVuY2lhcywgeSBsdWVnbyBmaWx0cmFtb3MgbGEgYmFzZSBwYXJhIGVsaW1pbmFyIGxvcyByZWdpc3Ryb3MgaW5jb25zaXN0ZW50ZXMNCmBgYHtyLHdhcm5pbmc9RkFMU0V9DQojUGFzbyAxDQp2YXIuaW5kIDwtIGMoJ0NPRFVTVScsJ05ST19IT0dBUicsJ0NPTVBPTkVOVEUnLCAnQU5PNCcsJ1RSSU1FU1RSRScsJ0VTVEFETycsJ0NBVF9PQ1VQJywnUE9OREVSQScsICdDSDA0JywgJ0NIMDYnLCdQMjEnLCdQUDNFX1RPVCcpDQoNCiNQYXNvIDIgIA0KQmFzZXNfQ29udGludWEgPC0gYmluZF9yb3dzKA0KICBpbmRpdmlkdWFsLjIxNiAgJT4lIHNlbGVjdCh2YXIuaW5kKSwNCiAgaW5kaXZpZHVhbC4zMTYgICU+JSBzZWxlY3QodmFyLmluZCksDQogIGluZGl2aWR1YWwuNDE2ICAlPiUgc2VsZWN0KHZhci5pbmQpLA0KICBpbmRpdmlkdWFsLjExNyAgJT4lIHNlbGVjdCh2YXIuaW5kKSkNCiNQYXNvcyAzICB5IDQNCkJhc2VzX0NvbnRpbnVhIDwtICBCYXNlc19Db250aW51YSAlPiUgDQogICAgICBmaWx0ZXIoQ0gwNiAlaW4lIGMoMTg6NjUpLEVTVEFETyAhPTApICU+JSANCiAgICAgIG11dGF0ZShDYXRlZ29yaWEgPSBjYXNlX3doZW4oRVNUQURPICVpbiUgIGMoMyw0KX4iSW5hY3Rpdm9zIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRVNUQURPICAgPT0gIDIgfiJEZXNvY3VwYWRvcyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVTVEFETyAgID09ICAxICYgQ0FUX09DVVAgPT0gMSB+IlBhdHJvbmVzIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRVNUQURPICAgPT0gIDEgJiBDQVRfT0NVUCA9PSAyIH4iQ3VlbnRhIFByb3Bpc3RhcyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVTVEFETyAgID09ICAxICYgQ0FUX09DVVAgPT0gMyB+IkFzYWxhcmlhZG9zIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRVNUQURPICAgPT0gIDEgJiBDQVRfT0NVUCA9PSA0IH4iVHJhYmFqYWRvciBmYW1pbGlhciBzL3IiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVFJVRSB+ICJPdHJvcyIpKQ0KI1Bhc28gIDUNCkJhc2VzX0NvbnRpbnVhIDwtIEJhc2VzX0NvbnRpbnVhICU+JSANCiAgICBtdXRhdGUoVHJpbWVzdHJlID0gcGFzdGUoQU5PNCwgVFJJTUVTVFJFLCBzZXA9Il8iKSkgJT4lIA0KICAgIGFycmFuZ2UoVHJpbWVzdHJlKSAlPiUgDQogICAgbXV0YXRlKElkX1RyaW1lc3RyZSA9IG1hdGNoKFRyaW1lc3RyZSx1bmlxdWUoVHJpbWVzdHJlKSkpDQoNCiNQYXNvIDYNCkJhc2VzX0NvbnRpbnVhX1JlcGxpY2EgPC0gQmFzZXNfQ29udGludWENCg0KbmFtZXMoQmFzZXNfQ29udGludWFfUmVwbGljYSkNCg0KbmFtZXMoQmFzZXNfQ29udGludWFfUmVwbGljYSlbNDoobGVuZ3RoKEJhc2VzX0NvbnRpbnVhX1JlcGxpY2EpLTEpXSA8LSANCiAgcGFzdGUwKG5hbWVzKEJhc2VzX0NvbnRpbnVhX1JlcGxpY2EpWzQ6KGxlbmd0aChCYXNlc19Db250aW51YV9SZXBsaWNhKS0xKV0sIl90MSIpDQoNCm5hbWVzKEJhc2VzX0NvbnRpbnVhX1JlcGxpY2EpDQoNCiNQYXNvIDcNCkJhc2VzX0NvbnRpbnVhX1JlcGxpY2EkSWRfVHJpbWVzdHJlIDwtIEJhc2VzX0NvbnRpbnVhX1JlcGxpY2EkSWRfVHJpbWVzdHJlIC0gMQ0KI1Bhc29zIDggeSA5DQpQYW5lbF9Db250aW51YSA8LSBpbm5lcl9qb2luKEJhc2VzX0NvbnRpbnVhLEJhc2VzX0NvbnRpbnVhX1JlcGxpY2EpDQpQYW5lbF9Db250aW51YSA8LSBQYW5lbF9Db250aW51YSAlPiUgDQogICAgbXV0YXRlKENvbnNpc3RlbmNpYSA9IGNhc2Vfd2hlbihhYnMoQ0gwNl90MS1DSDA2KSA+IDIgfA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ0gwNCAhPSBDSDA0X3QxIH4gImluY29uc2lzdGVudGUiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVFJVRSB+ICJjb25zaXN0ZW50ZSIpKSAlPiUgDQogICAgZmlsdGVyKENvbnNpc3RlbmNpYSA9PSAiY29uc2lzdGVudGUiKQ0KYGBgDQoNCiNNYXRyaWNlcyBkZSB0cmFuc2ljacOzbg0KIyMgQ2FsY3VsbyBkZSBwcm9iYWJpbGlkYWRlcyBkZSB0cmFuc2ljacOzbi4gDQpSZWFsaXphcmVtb3MgdW4gYnJldmUgZWplcmNpY2lvIHBhcmEgaWRlbnRpZmljYXIgbGEgbWFnbml0dWQgcmVsYXRpdmEgZGUgbGFzIHRyYW5zaWNpb25lcyBlbnRyZSBsYXMgZGlzdGludGFzIGNhdGVnb3LDrWFzIG9jdXBhY2lvbmFsZXMuIFBhcmEgZWxsbyBjYWxjdWxhbW9zIGxhIHN1bWEgcG9uZGVyYWRhIGRlIGxhIGNhbnRpZGFkIGRlIGNhc29zIG9ic2VydmFkb3MgcGFyYSBjYWRhIHBvc2libGUgY29tYmluYWNpw7NuIGRlIF9fQ2F0ZW9ncmlhX18geSBfX0NhdGVnb3JpYV90MV9fLiBMdWVnbyBjYWxjdWxhcmVtb3MgbGEgcHJvYmFiaWxpZGFkIGRlIGVuY29udHJhcnNlIGVuIGNhdGVnb3LDrWEgZW4gdDEsIGNvbmRpY2lvbmFsIGEgaGFiZXIgcGVydGVuZWNpZG8gYSBsYXMgZGlzdGludGFzIGNhdGVnb3LDrWFzIGVuIHQwLiAgDQoNCg0KYGBge3J9DQpDYXRlZ29yaWFzX3RyYW5zaWNpb25lcyA8LSBQYW5lbF9Db250aW51YSAlPiUgDQogICNmaWx0ZXIoQ2F0ZWdvcmlhICE9IENhdGVnb3JpYV90MSkgJT4lIA0KICBncm91cF9ieShDYXRlZ29yaWEsQ2F0ZWdvcmlhX3QxKSAlPiUgDQogIHN1bW1hcmlzZShmcmVjX211ZXN0cmFsID0gbigpLA0KICAgICAgICAgICAgZnJlY3VlbmNpYSA9IHN1bSgoUE9OREVSQStQT05ERVJBX3QxLzIpKSkgJT4lIA0KICB1bmdyb3VwKCkgJT4lIA0KICBncm91cF9ieShDYXRlZ29yaWEpICU+JSANCiAgbXV0YXRlKFByb2Jfc2FsaWRhID0gZnJlY3VlbmNpYS9zdW0oZnJlY3VlbmNpYSkpDQpgYGANCk5vdGVzZSBxdWUgbGEgbGluZWEgY29tZW50YWRhIGVuIGVsIG1lZGlvIGRlIGxhIGNhZGVuYSBkZSBwaXBlcywgbm9zIHBlcm1pdGlyw61hIGl0ZXJhciByYXBpZGFtZW50ZSBzb2JyZSBlbCBwcm9jZWRpbWllbnRvIGFudGVyaW9yIGFncmVnYW5kbyB1biBmaWx0cm8uIEVuIGVzdGUgZWplbXBsbywgcG9kcsOtYW1vcyByZWNhbGN1bGFyIGxhcyBwcm9wb3JjaW9uZXMgw7puaWNhbWVudGUgcGFyYSBhcXVlbGxhcyBwZXJzb25hcyBxdWUgcHJlc2VudGFuIHVuIG1vdmltaWVudG8gZGUgY2F0ZWdvcsOtYQ0KDQojI0dyw6FmaWNvIGRlIE1hdHJpeiBkZSBUcmFuc2ljacOzbg0KDQpgYGB7cn0NCmxpYnJhcnkoZ2d0aGVtZXMpDQpnZ3Bsb3QoQ2F0ZWdvcmlhc190cmFuc2ljaW9uZXMsIGFlcyh4ID0gQ2F0ZWdvcmlhX3QxLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkgPSBDYXRlZ29yaWEsIGZpbGwgPSBQcm9iX3NhbGlkYSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsID1yb3VuZChQcm9iX3NhbGlkYSoxMDAsMikpKSArDQogIGxhYnModGl0bGUgPSAiUHJvYmFiaWxpZGFkZXMgZGUgVHJhbnNpY2lvbiBkZSBoYWNpYSBsYXMgZGlzdGludGFzIENhdGVnb3LDrWFzIikrDQogIGdlb21fdGlsZSgpKw0KICBnZW9tX3RleHQoKSsNCiAgc2NhbGVfZmlsbF9ncmFkaWVudChsb3cgPSAiZ3JleTEwMCIsIGhpZ2ggPSAiZ3JleTMwIikrDQogIHRoZW1lX3R1ZnRlKCkNCmBgYA0KI1JlZ3Jlc2nDs24gbGluZWFsDQpBIGNvbnRpbnVhY2nDs24gdmVyZW1vcyB1bmEgYnJldmUgaW50cm9kdWNjacOzbiBhIGxvcyBjb21hbmRvcyBiw6FzaWNvcyBxdWUgc2UgdXRpbGl6YW4gcGFyYSByZWFsaXphciBlY29ub21ldHLDrWEgZW4gUi4gRW4gcHJpbWVyYSBpbnN0YW5jaWEgb2JzZXJ2YXJlbW9zIGxhIGNvcnJlbGFjacOzbiBlbnRyZSBkb3MgdmFyaWFibGVzLCB5IGx1ZWdvIGhhcmVtb3MgdW4gdGVzdCBkZSBjb3JyZWxhY2nDs24uIEVsZWdpbW9zIHVuIGNhc28gc2ltcGxlLCBjb21vIG9ic2VydmFyIGxhIHJlbGFjacOzbiBlbnRyZSBsYSBjYW50aWRhZCBkZSBob3JhcyBkZSBob3JhcyB0cmFiYWphZGFzIGVuIGxhIG9jdXBhY2nDs24gcHJpbmNpcGFsICggX19QUDNFX1RPVF9fICkgeSBlbCBpbmdyZXNvIHBvciBsYSBvY3VwYWNpw7NuIHByaW5jaXBhbCAoIF9fUDIxX18pLiBSZXRvbWFtb3MgZWwgdHJhYmFqbyBjb24gbGEgaW5mb3JtYWNpw7NuIGNvbXBsZXRhIGRlIGxhcyBiYXNlcywgZGVqYW5kbyBhIHVuIGxhZG8gZWwgcGFuZWwgY29uc3RydWlkby4gICANCg0KIyNWaXN1YWxpemFjacOzbiBQcmV2aWEgZGUgbGEgaW5mb3JtYWNpw7NuDQpHcmFmaXF1ZW1vcyByw6FwaWRhbWVudGUgcGFyYSB0ZW5lciB1bmEgaW50dWljacOzbjoNCmBgYHtyfQ0KcGxvdChCYXNlc19Db250aW51YSRQUDNFX1RPVCxCYXNlc19Db250aW51YSRQMjEpDQoNCmBgYA0KQ29tbyB2ZW1vcyBhcXXDrSBsYSBmdW5jacOzbiBfX3Bsb3RfXyBub3MgYXl1ZGEgcGFyYSBtaXJhciB1biBwb2NvIGxhIGluZm9ybWFjacOzbiBhbnRlcyBkZSByZWFsaXphciB1biB0ZXN0IG8gdW4gbW9kZWxvIGVjb25vbcOpdHJpY28uIEVuIGVzdGUgY2Fzbywgbm9zIHBlcm1pdGUgb2JzZXJ2YXIgcXVlIGVuIF9fUFAzRV9UT1RfXyB0ZW5lbW9zIGNvZGlmaWNhZG9zIGNvbiBfOTk5XyBhIGFxdWVsbG9zIHF1ZSBubyByZXNwb25kaWVyb24gbGEgcHJlZ3VudGEgcG9yIGxhIGNhbnRpZGFkIGRlIGhvcmFzLiANCmBgYHtyfQ0KQmFzZXNfQ29udGludWFfZ3JhZiA8LSBCYXNlc19Db250aW51YSAlPiUgZmlsdGVyKFBQM0VfVE9UICE9IDk5OSkNCg0KcGxvdChCYXNlc19Db250aW51YV9ncmFmJFBQM0VfVE9ULEJhc2VzX0NvbnRpbnVhX2dyYWYkUDIxKQ0KDQpgYGANCkVuIHVuYSBzZWd1bmRhIG1pcmFkYSwgcG9kZW1vcyB2ZXIgcXVlIHRlbmVtb3MgYWxndW5vcyBpbmRpdmlkdW9zIHF1ZSBkZWNsYXJhciB0cmFiYWphciBsYXMgMTY4IGhvcmFzIGRlIGxhIHNlbWFuYSwgdmFyaW9zIHF1ZSBkZWNsYXJhbiBtw6FzIGRlIDEwMCBob3JhcywgeSBvdHJvcyB0YW50b3MgY29uIGluZ3Jlc28gXzBfLCBvIF8tOV8gKGPDs2RpZ28gcGFyYSBsb3MgcXVlIG5vIHJlc3BvbmRlbiBsYSBwcmVndW50YSBkZSBpbmdyZXNvcykuICAgICAgICAgICANCkFwbGljYXJlbW9zIHVuIGZpbHRybyBtw6FzIHBhcmEgcmVzdHJpbmdpciBsYXMgaG9yYXMgdHJhYmFqYWRhcyBwb3Igc2VtYW5hIGEgODQgKDEyKjcpIHkgcXVlZGFybm9zIGNvbiBpbmdyZXNvcyBwb3NpdGl2b3MuDQpgYGB7cn0NCkJhc2VzX0NvbnRpbnVhX2xpc3RvIDwtIEJhc2VzX0NvbnRpbnVhICU+JSBmaWx0ZXIoUDIxPjAsUFAzRV9UT1QgJWluJSBjKDE6ODQpKQ0KDQpwbG90KEJhc2VzX0NvbnRpbnVhX2xpc3RvJFBQM0VfVE9ULEJhc2VzX0NvbnRpbnVhX2xpc3RvJFAyMSkNCg0KYGBgDQojI0NvcnJlbGFjacOzbg0KTHVlZ28gZGVsIHBhbnRhbGxhem8gYSB0cmF2w6lzIGRlIGxvcyBncsOhZmljb3MsIHBhc2Vtb3MgYSByZWFsaXphciBlbCBjYWxjdWxvIGRlIGxhIGNvcnJlbGFjacOzbiBlbnRyZSBsYXMgdmFyaWFibGVzIGEgcGFydGlyIGRlIGxhIGZ1bmNpw7NuIF9jb3JfLiBMb3MgZnVuY2nDs24gcHVlZGUgdG9tYXIgY29tbyBhcmd1bWVudG8gZG9zIHZlY3RvcmVzIHBvciBzZXBhcmFkbyB5IGNhbGN1bGFyw6EgZWwgY29lZmljaWVudGUgZGUgY29ycmVsYWNpw7NuIGVudHJlIGFtYmFzIHZhcmlhYmxlcywgbyBiaWVuIHB1ZWRlIHRvbWFyIGNvbW8gYXJndW1lbnRvIHVuIGRhdGFmcmFtZSAoTyBhbGd1bmFzIHZhcmlhYmxlcyBkZWwgbWlzbW8pIHkgYXJyb2phcsOhIGNvbW8gcmVzdWx0YWRvIHVuYSBtYXRyaXogY3VhZHJhZGEgY29uIGxvcyBjb2VmaWNpZW50ZSBkZSBjb3JyZWxhY2nDs24gZW50cmUgY2FkYSB1bmEgZGUgZWxsYXMuDQpgYGB7cn0NCmNvcihCYXNlc19Db250aW51YV9saXN0byRQMjEsQmFzZXNfQ29udGludWFfbGlzdG8kUFAzRV9UT1QpDQpjb3IoQmFzZXNfQ29udGludWFfbGlzdG8kUDIxLEJhc2VzX0NvbnRpbnVhX2xpc3RvJENIMDYpDQoNCmNvcihCYXNlc19Db250aW51YV9saXN0b1ssYygiUDIxIiwiUFAzRV9UT1QiLCJDSDA2IildKQ0KDQpgYGANCkxhIGZ1bmNpw7NuIF9fY29yLnRlc3RfXyBub3MgZWplY3V0YXLDoSBlbCB0ZXN0IGRlIGNvcnJlbGFjacOzbiBzb2JyZSBkb3MgdmFyaWFibGVzLiBOZWNlc2FyaWFtZW50ZSByZXF1aWVyZSBjb21vIGFyZ3VtZW50b3MgZG9zIHZlY3RvcmVzIHBvciBzZXBhcmFkby4gICAgICAgICAgDQpFbiBsYSBzYWxpZGEgcG9kcmVtb3Mgb2JzZXJ2YXI6IGVsIHZhbG9yIGRlbCBlc3RpbWFkb3IgdCwgZWwgcC12YWxvciwgbGEgaGlwb3Rlc2lzIGFsdGVybmF0aXZhIGRlbCB0ZXN0IHkgZWwgaW50ZXJ2YWxvIGRlIGNvbmZpYW56YSBkZSBsYSBlc3RpbWFjacOzbi4NCmBgYHtyfQ0KDQpjb3IudGVzdChCYXNlc19Db250aW51YV9saXN0byRQMjEsIEJhc2VzX0NvbnRpbnVhX2xpc3RvJFBQM0VfVE9UKQ0KDQpgYGANCkEgc3UgdmV6LCBsYSBmdW5jacOzbiB0aWVuZSBvdHJvcyBwYXJhbWV0cm9zIGNvbW8gcG9yIGVqZW1wbG8gX19jb25mX2xldmVsX18gcXVlIG5vcyBwZXJtaXRlIGRlZmluaXIgYSBndXN0byBlbCBuaXZlbCBkZSBjb25maWFuemEgY29uIGVsIHF1ZSBxdWVyZW1vcyByZWFsaXphciBlbCB0ZXN0LiBQb3Igb3RybyBsYWRvLCBsYSBmdW5jacOzbiB0aWVuZSBzZXRlYWRvIHBvciBkZWZhdWx0IGVsIHRlc3QgZGUgUGVhcnNvbiwgcGVybyBlbCBwYXLDoW1ldHJvIF9fIm1ldGhvZCJfXyBub3MgcGVybWl0ZSBlbGVqaXIgb3Ryb3MgdGVzdHMuDQpgYGB7cn0NCg0KY29yLnRlc3QoQmFzZXNfQ29udGludWFfbGlzdG8kUDIxLCBCYXNlc19Db250aW51YV9saXN0byRQUDNFX1RPVCxjb25mLmxldmVsID0gMC45MCwNCiAgICAgICAgIG1ldGhvZCA9ICJzcGVhcm1hbiIpDQpgYGANCiMjIyBSZWdyZXNpw7NuIGxpbmVhbCBzaW1wbGUNClBhcmEgcmVhbGl6YXIgdW5hIHJlZ3Jlc2nDs24gc2ltcGxlIHVzYXJlbW9zIGxhIGZ1bmNpw7NuIGBgYGxtYGBgLiBFbiBlc3RlIGNhc28gcHJvYmFyZW1vcyBsYSBzaWd1aWVudGUgcmVncmVzacOzbiBjb24gbGFzIHZhcmlhYmxlcyBxdWUgZXN0YW1vcyBvYnNlcnZhbmRvOiBJbmdyZXNvIGRlIGxhIE9jdXBhY2nDs24gcHJpbmNpcGFsIGNvbW8gbGEgdmFyaWFibGUgZGVwZW5kaWVudGUsIHkgbGFzIGhvcmFzIHRyYWJhamFkYXMgZW4gbGEgb2N1cGFjacOzbiBwcmluY2lwYWwgY29tbyBsYSBpbmRlcGVuZGllbnRlDQokJA0KRShQX3syMX0vaG9yYXMpPSBcYmV0YV8wICsgXGJldGFfMSBob3Jhcw0KJCQNCkxhIGZ1bmNpw7NuIGBgYGxtYGBgIHRpZW5lIGVudHJlIHN1cyBwYXJhbWV0cm9zIHByaW5jaXBhbGVzOiAgICANCmBgZm9ybXVsYWBgOiBFbiBlbCBzZSBlc3BlY2lmaWNhbiBsYXMgdmFyaWFibGVzIHF1ZSBpbmdyZXNhbiBlbiBlbCBtb2RlbG8gZGUgcmVncmVzacOzbi4gRWwgc2lnbm8gZGUgXz1fIGRlbCBtb2RlbG8gc2UgcmVwcmVzZW50YSBhcXXDrSBtZWRpYW50ZSBlbCBzaWdubyBgYGB+YGBgLiAgICAgICAgDQpgYGBkYXRhYGBgIDogRGViZSBlc3BlY2lmaWNhcnNlIGVsIGRhdGFmcmFtZSBxdWUgY29udGllbmUgbGEgaW5mb3JtYWNpw7NuIGRlIGxhcyB2YXJpYWJsZXMgYSB1dGlsaXphciBlbiBlbCBtb2RlbG8uICAgICAgIA0KDQpBbCBlamVjdHVhciBsYSBmdW5jacOzbiBsbSgpIGNvbiBzdXMgcmVzcGVjdGl2b3MgcGFyYW1ldHJvcywgcG9kcmVtb3MgdmlzdWFsaXphciBsb3MgY29lZmljaWVudGVzIGVzdGltYWRvcyBkZWwgbW9kZWxvLiBTaW4gZW1iYXJnbywgbGEgZnVuY2nDs24gX19zdW1tYXJ5X18gbm9zIG1vc3RyYXLDoSBlbiBtw6FzIGRldGFsbGUgbG9zIHJlc3VsdGFkb3MuDQpgYGB7cn0NCmxtKGZvcm11bGEgPSBQMjEgfiBQUDNFX1RPVCwgZGF0YSA9IEJhc2VzX0NvbnRpbnVhX2xpc3RvKQ0KDQptb2RlbG8uYWp1c3RhZG8gPC1sbShmb3JtdWxhID0gUDIxIH4gUFAzRV9UT1QsIGRhdGEgPSBCYXNlc19Db250aW51YV9saXN0bykNCiANCg0Kc3VtbWFyeShtb2RlbG8uYWp1c3RhZG8pDQpgYGANCg==