Equipo 4:

Regina Enriquez Chapa A01721435

Lorena Villarreal Vega A01720802

Daniela Garza Anzola A01721071

Raquel Garza Martínez A00830203

#Descargar librerías
library(foreign)
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(spdep)
## Loading required package: spData
## To access larger datasets in this package, install the spDataLarge
## package with: `install.packages('spDataLarge',
## repos='https://nowosad.github.io/drat/', type='source')`
## Loading required package: sf
## Linking to GEOS 3.11.0, GDAL 3.5.3, PROJ 9.1.0; sf_use_s2() is TRUE
library(tigris)
## To enable caching of data, set `options(tigris_use_cache = TRUE)`
## in your R script or .Rprofile.
library(rgeoda)
## Loading required package: digest
## 
## Attaching package: 'rgeoda'
## The following object is masked from 'package:spdep':
## 
##     skater
library(RColorBrewer)
library(viridis)
## Loading required package: viridisLite
library(ggplot2)
library(tmap)
## Breaking News: tmap 3.x is retiring. Please test v4, e.g. with
## remotes::install_github('r-tmap/tmap')
library(sf)
library(sp)
library(readr)
library(spdep)
#Importar base de datos
library(readr)
panel_dataset <- read.csv("/Users/reginaenriquez/Desktop/Act 1/panel_dataset.csv")

Variables Seleccionadas

Variable Dependiente:

new_fdi_real_mxn - New Foreign Direct Investment Inflows. Millions of Dollars.

Variables Independientes:

crime_rate - Crime Rate per 100,000 state’s population.
pop_density - Population per state’s land area km².
unemployment - Percentage of Unemployment population.
college_education - College Education

Sección A

  1. Estadísticos Descriptivos (Global y Regional). Incluir elementos gráficos (histogramas, gráfico de barras, etc.).

Para esta primera sección se realizaron subjuntos de datos de cada una de las regiones de México para después poder continuar visualizando la informacion de los flujos de Inversión Extranjera Directa (FDI) dentro de un gráfico de barras para cada una de las regiones.

Barplot Región Norte

norte <- subset(panel_dataset, state %in% c("Baja California","Chihuahua", "Coahuila", "Nuevo Leon", "Sonora", "Tamaulipas"))

ggplot(data = norte, aes(x = state, y = new_fdi_real_mxn)) +
  geom_bar(stat = "identity", fill = "steelblue") +
  theme_minimal() +
  labs(x = "Estados", y = "FDI", title = "FDI por Estados del Norte")

El gráfico de barras muestra los flujos de Inversión Extranjera Directa (FDI) en varios estados del norte de México. Se puede observar como Nuevo León lidera, seguido de Coahuila, Baja California, Tamaulipas, Chihuahua y Sonora. Esta información es clave para entender la distribución geográfica de la FDI y puede orientar políticas económicas y estrategias de desarrollo regional. Se puede decir que Nuevo León destaca gracias a su infraestructura industrial, ubicación estratégica y ambiente empresarial, mientras que Chihuahua y Sonora muestran flujos de inversión más bajos en comparación con otros estados.

Barplot Región Sur

sur <- subset(panel_dataset, state %in% c("Campeche", "Chiapas","Guerrero", "Oaxaca", "Quintana Roo", "Tabasco", "Veracruz", "Yucatan"))

ggplot(data=sur, aes(x=sur$state, y=sur$new_fdi_real_mxn)) +
  geom_bar(stat="identity", fill="red")+
  theme_minimal() +
  labs(x = "Estados", y = "FDI", title = "FDI por Estados del Sur")
## Warning: Use of `sur$state` is discouraged.
## ℹ Use `state` instead.
## Warning: Use of `sur$new_fdi_real_mxn` is discouraged.
## ℹ Use `new_fdi_real_mxn` instead.

Este gráfico de barras resalta las diferencias en los flujos de inversión directa entre los estados del sur de México. Veracruz lidera en términos de FDI, posiblemente debido a su infraestructura portuaria, recursos naturales y ubicación estratégica. Tabasco y Guerrero muestran flujos de inversión similares, lo que puede estar relacionado con la industria petrolera y turística, respectivamente. Oaxaca, Campeche, Yucatán y Chiapas siguen en orden descendente en términos de flujos de inversión, lo que puede estar influenciado por diversos factores como la infraestructura, los recursos naturales, las políticas gubernamentales y las condiciones económicas locales.

Barplot Región Centro

centro <- subset(panel_dataset, state %in% c("Ciudad de Mexico", "Hidalgo", "Mexico", "Morelos", "Puebla", "Tlaxcala"))

ggplot(data=centro, aes(x=centro$state, y=centro$new_fdi_real_mxn)) +
  geom_bar(stat="identity", fill="darkgreen")+
  theme_minimal()+
  labs(x = "Estados", y = "FDI", title = "FDI por Estados del Centro")
## Warning: Use of `centro$state` is discouraged.
## ℹ Use `state` instead.
## Warning: Use of `centro$new_fdi_real_mxn` is discouraged.
## ℹ Use `new_fdi_real_mxn` instead.

Se puede observar en el gráfico de barras de la región central de México como es que La Ciudad de México destaca como líder, lo cual puede ser debido a su posición como centro financiero y político. El Estado de México sigue, posiblemente debido a su proximidad con la capital y su infraestructura industrial. Puebla, reconocida por su industria automotriz, se sitúa en tercer lugar, mientras que Hidalgo, Morelos y Tlaxcala muestran flujos de inversión más bajos, sugiriendo una menor actividad económica o infraestructura industrial menos desarrollada.

Barplot Región Occidente

occidente <- subset(panel_dataset, state %in% c("Baja California Sur", "Colima", "Durango", "Jalisco" , "Michoacan", "Nayarit", "Sinaloa"))

ggplot(data=occidente, aes(x=occidente$state, y=occidente$new_fdi_real_mxn)) +
  geom_bar(stat="identity", fill="purple")+
  theme_minimal()+
  labs(x = "Estados", y = "FDI", title = "FDI por Estados del Occidente")
## Warning: Use of `occidente$state` is discouraged.
## ℹ Use `state` instead.
## Warning: Use of `occidente$new_fdi_real_mxn` is discouraged.
## ℹ Use `new_fdi_real_mxn` instead.

Continuando con el gráfico de barras de la región occidental de México, se observa a Jalisco en primer lugar, seguido por Baja California Sur y Michoacán. Jalisco lidera debido a su economía diversificada y sector tecnológico en crecimiento, mientras que Baja California Sur destaca por el turismo en Los Cabos y La Paz. Los otros estados muestran flujos descendentes, los cuales pueden estar impulsados por sectores como agricultura, pesca, minería y turismo. Colima cierra con flujos menores, probablemente debido a su tamaño y economía menos diversificada.

Barplot Región Bajío

bajio <- subset(panel_dataset, state %in% c("Aguascalientes", "Guanajuato","Queretaro ", "San Luis Potosi", "Zacatecas"))

ggplot(data=bajio, aes(x=bajio$state, y=bajio$new_fdi_real_mxn)) +
  geom_bar(stat="identity", fill="pink")+
  theme_minimal()+
  labs(x = "Estados", y = "FDI", title = "FDI por Estados del Bajio")
## Warning: Use of `bajio$state` is discouraged.
## ℹ Use `state` instead.
## Warning: Use of `bajio$new_fdi_real_mxn` is discouraged.
## ℹ Use `new_fdi_real_mxn` instead.

Por ultimo, dentro del grafico de la región Bajío de México, destaca Guanajuato en primer lugar, seguido por Querétaro y San Luis Potosí en segundo lugar, Zacatecas y finalmente Aguascalientes. Guanajuato destaca por su ubicación estratégica y fuerte infraestructura industrial, especialmente en sectores como la automotriz y la manufactura. Querétaro y San Luis Potosí comparten el segundo lugar, impulsados por el crecimiento en sectores como la aeroespacial y la manufactura. Zacatecas sigue, con una presencia importante en la minería y la agricultura. Aguascalientes, aunque muestra flujos más bajos, ha sido atractivo para inversiones en sectores como la automotriz y la electrónica.

Sección B

Estadísticos de Dispersión (Global y Regional). Incluir elementos gráficos (box plots, qq- plots, etc.).

Dentro de esta sección de podrán ubservar boxplots de cada región para cada una de las variables seleccionadas. Estos gráficos facilitan la comparación de las características entre las diferentes áreas geográficas.

Boxplot para la variable FDI

regiones_unicas <- unique(panel_dataset$region_a)
colores <- plasma(length(regiones_unicas))

boxplot(panel_dataset$new_fdi_real_mxn ~ panel_dataset$region_a,
        xlab = "Región",
        ylab = "FDI",
        main = "Boxplot de FDI por región",
        col = colores)

El boxplot de la variable FDI revela que los flujos de inversión en el centro de México tienen una mayor variabilidad en comparación con los demás. Aunque el centro muestra una diversidad considerable, su mediana es más baja que la del norte. Además, se observan valores atípicos en esta región. El Bajío presenta una mediana comparable a la del norte, indicando una alta concentración de inversión. Aunque los boxplots del occidente y sur tienen menor variabilidad, sus medianas son similares a las del centro.

Boxplot para la variable Unemployment

boxplot(panel_dataset$unemployment ~ panel_dataset$region_a,
        xlab = "Región",
        ylab = "Desempleo",
        main = "Boxplot de desempleo por región",
        col = colores)

Los boxplots para la variable de desempleo muestran que el norte tiene la mayor variabilidad en las tasas de desempleo, seguido por el occidente y el sur con variabilidades moderadas. Aunque el norte tiene una mediana similar al centro, muestra más valores extremadamente altos. El sur tiene una mayor presencia de valores altos en comparación con el occidente. En resumen, el norte tiene una variabilidad significativa con valores extremos, mientras que el sur destaca por valores altos, a pesar de una variabilidad moderada.

Boxplot para la variable Crime Rate

boxplot(panel_dataset$crime_rate ~ panel_dataset$region_a,
        xlab = "Región",
        ylab = "Crimen",
        main = "Boxplot de Crimen por región",
        col = colores)

Los boxplots muestran diferencias en las tasas de crimen entre las regiones de México. El del norte tiene la mayor variabilidad y presencia de valores altos, mientras que el del centro es el más pequeño, indicando menor variabilidad. Aunque el del norte es grande, su mediana es similar al occidente, mientras que la del Bajío es la más baja, sugiriendo tasas de crimen más bajas en promedio.

Boxplot para la variable Population Density

boxplot(panel_dataset$pop_density ~ panel_dataset$region_a,
        xlab = "Región",
        ylab = "Poblacion",
        main = "Boxplot de población por región",
        col = colores)

El boxplot de la región del centro de México es el más grande, lo que indica una mayor variabilidad en la población dentro de esta región en comparación con otras. La presencia de outliers muy altos en el centro contribuye a hacer que los boxplots de todas las demás regiones parezcan más pequeños en comparación. A pesar de que el boxplot del centro es el más grande, el boxplot del Bajío está aún más grande que el del norte, occidente y sur. Esto indica una mayor variabilidad en la población dentro del Bajío en comparación con el centro, lo que puede deberse a factores como el crecimiento económico y la urbanización en la región.

Boxplot para la variable College Education

boxplot(panel_dataset$college_education ~ panel_dataset$region_a,
        xlab = "Región",
        ylab = "Educación",
        main = "Boxplot de educación por región",
        col = colores)

Dentro de estos boxlplots de la variable educación, se puede observar que la región del norte tiene una menor variabilidad en los niveles de educación. La línea del primer cuartil en el boxplot del norte es más corta que todas las demás, lo que sugiere que la dispersión de los datos en la parte inferior del rango es menor en comparación con las otras regiones. La media de todos los boxplots es relativamente similar, pero la del occidente es la más alta y la del sur es la más baja. Esto sugiere que, en promedio, el nivel de educación tiende a ser más alto en el occidente y más bajo en el sur, en comparación con las otras regiones.

Scatter plot con línea de tendencia

plot(panel_dataset$crime_rate, panel_dataset$new_fdi_real_mxn,
     xlab = "Crimen",
     ylab = "FDI",
     main = "Relación entre crimen y FDI")
abline(lm(panel_dataset$new_fdi_real_mxn ~ panel_dataset$crime_rate), col = "red")

El análisis muestra que áreas con bajos niveles de crimen tienden a tener menor inversión directa (FDI). Aunque la relación es relativamente constante, hay un ligero declive en el FDI cuando aumenta el crimen, sugiriendo una posible relación negativa débil entre estas variables. Esto podría indicar que las empresas evitan invertir en áreas con alta criminalidad debido a preocupaciones de seguridad. Se necesitan análisis adicionales para comprender completamente esta relación. Sin embargo, es importante tener en cuenta otros factores y realizar un análisis más detallado para comprender completamente esta relación y sus implicaciones.

Sección C

Visualizar la distribución espacial de las variables seleccionadas usando mapas.

#Variables seleccionadas
panel_dataset2 <- panel_dataset[,c(1,2,3,9,25,24,8,14)]

Se creo un nuevo conjunto de datos donde se seleccionaron únicamente las variables específicas que se utilizarán en el análisis, simplificando así el conjunto de datos a solo las columnas relevantes.

### Importar shapefile 

# Estados de México (32) 
mx_state_map <- st_read("/Users/reginaenriquez/Desktop/esda/mx_maps/mx_states/mexlatlong.shp")
## Reading layer `mexlatlong' from data source 
##   `/Users/reginaenriquez/Desktop/esda/mx_maps/mx_states/mexlatlong.shp' 
##   using driver `ESRI Shapefile'
## Simple feature collection with 32 features and 19 fields
## Geometry type: MULTIPOLYGON
## Dimension:     XY
## Bounding box:  xmin: -118.4042 ymin: 14.55055 xmax: -86.73862 ymax: 32.71846
## Geodetic CRS:  WGS 84
mx_state_map <- read_sf("/Users/reginaenriquez/Desktop/esda/mx_maps/mx_states/mexlatlong.shp")

# Juntar datasets
state_geodata <- geo_join(mx_state_map,panel_dataset2,'OBJECTID','state_id',how='inner')
# Subset estados para el año 2019
datos_mapa_2019 <- subset(state_geodata, year == 2019)

# Subset estados para el año 2021
datos_mapa_2021 <- subset(state_geodata, year == 2021)

Mapeo de Distribución espacial del FDI 2019

datos_mapa_2019_filtered <- datos_mapa_2019 %>%
  filter(ADMIN_NAME != "Distrito Federal")

ggplot() +
  geom_sf(data = datos_mapa_2019_filtered, aes(fill = new_fdi_real_mxn)) +
  scale_fill_viridis_c() +
  labs(title = "Distribución Espacial del FDI en 2019",
       fill = "Tasa de FDI") +
  theme_minimal()

La Ciudad de México destaca como el principal receptor de Inversión Extranjera Directa (FDI), lo cual es coherente con su papel como centro financiero y económico de México. Dado su dominio en el panorama de la inversión, se optó por filtrar a la Ciudad de México fuera del mapa para permitir una mejor visualización de los otros estados del país.

Nuevo León y el Estado de México ocupan los siguientes lugares en términos de FDI, siendo centros económicos importantes con infraestructura industrial significativa, atractivos para inversiones en sectores como la manufactura y la tecnología. Otros estados destacados son Veracruz, Querétaro, Jalisco, Guanajuato y Coahuila, atribuyendo su atractivo a factores como ubicación estratégica y mano de obra calificada. Estos hallazgos indican la importancia de ciertos estados para la inversión extranjera, con implicaciones clave para el crecimiento económico y el desarrollo regional en México.

Mapeo de distribución espacial del FDI 2021

datos_mapa_2021_filtered <- datos_mapa_2021 %>%
  filter(ADMIN_NAME != "Distrito Federal")

ggplot() +
  geom_sf(data = datos_mapa_2021_filtered, aes(fill = new_fdi_real_mxn)) +
  scale_fill_viridis_c() +
  labs(title = "Distribución Espacial del FDI en 2021",
       fill = " Tasa de FDI") +
  theme_minimal()

En 2021, la Ciudad de México mantuvo su posición como el estado con el mayor FDI, consolidando su papel como centro económico y financiero del país, por lo que de igual forma, para una mejor visualización de los demás estados, se eliminó del mapa.

Nuevo León y Baja California Norte y Sur experimentaron un notable aumento en el FDI en comparación con 2019, posiblemente debido a políticas gubernamentales favorables y una infraestructura desarrollada. Michoacán, Veracruz y Tamaulipas también registraron incrementos significativos en el FDI en 2021. Mientras tanto, el Estado de México experimentó un descenso en el FDI y ya no figura entre los estados con mayores niveles de inversión extranjera directa.

Mapeo de distribución espacial del desempleo 2019

ggplot() +
  geom_sf(data = datos_mapa_2019, aes(fill = unemployment)) +
  scale_fill_viridis_c() +
  labs(title = "Distribución Espacial del Desempleo en 2019",
       fill = "Índice de Desempleo") +
  theme_minimal()

En 2019, Tabasco tuvo el mayor desempleo, lo cual puede estar relacionado con su dependencia en la industria petrolera, mientras que Baja California Norte y Guerrero mostraron los niveles más bajos, posiblemente por su diversificación económica y desarrollo turístico. Otros estados como Chiapas, Veracruz, Coahuila, Hidalgo, Guanajuato, Colima y Michoacán enfrentaron desafíos con índices de desempleo más altos, señalando la necesidad de políticas específicas para abordar las causas subyacentes en diferentes regiones.

Mapeo de distribución espacial del desempleo 2021

ggplot() +
  geom_sf(data = datos_mapa_2021, aes(fill = unemployment)) +
  scale_fill_viridis_c() +
  labs(title = "Distribución Espacial del Desempleo en 2021",
       fill = "Índice de Desempleo") +
  theme_minimal()

En 2021, se registra un aumento generalizado en la mayoría de los estados respecto a 2019, menos aquellos que mantenian las tasas más bajas, donde se observa una relativa estabilidad en el índice de desempleo. Se destaca un incremento significativo en Durango, Querétaro, Estado de México y Puebla, posiblemente debido a la desaceleración económica y los efectos de la pandemia de COVID-19. Estos hallazgos indican un panorama laboral más desafiante en México en 2021, destacando la necesidad de políticas efectivas para promover la creación de empleo y la recuperación económica post-pandemia.

Mapeo de distribución espacial de la educacion 2019

ggplot() +
  geom_sf(data = datos_mapa_2019, aes(fill = college_education)) +
  scale_fill_viridis_c() +
  labs(title = "Distribución Espacial de la Educación Universitaria en 2019",
       fill = "Índice de Educacion") +
  theme_minimal()

En 2019, Baja California Sur, Sinaloa y Ciudad de México cuentan con los índices más altos de educación universitaria, lo que sugiere una mayor proporción de población con niveles educativos superiores, posiblemente debido a mejores oportunidades de acceso y mayor inversión en educación. En contraste, Oaxaca, Nuevo León, Michoacán y Guanajuato mostraron los índices más bajos, indicando una menor proporción de población con niveles educativos más altos, posiblemente debido a barreras socioeconómicas, culturales o de acceso a la educación universitaria.

Mapeo de distribución espacial de la educación 2021

ggplot() +
  geom_sf(data = datos_mapa_2021, aes(fill = college_education)) +
  scale_fill_viridis_c() +
  labs(title = "Distribución Espacial de la Educación Universitaria en 2021",
       fill = "Índice de Educación") +
  theme_minimal()

En el año 2021 se observa una declinación en el índice de educación universitaria en Sonora, Coahuila y Tamaulipas, posiblemente debido a cambios en políticas educativas o situación económica. En contraste, Jalisco experimentó un aumento, posiblemente por iniciativas exitosas en educación. La Ciudad de México sigue teniendo la tasa más alta, mientras que Oaxaca mantiene la más baja, reflejando disparidades en los sistemas educativos y desafíos socioeconómicos en México.

Mapeo de distribucion espacial del crimen 2019

ggplot() +
  geom_sf(data = datos_mapa_2019, aes(fill = crime_rate)) +
  scale_fill_viridis_c() +
  labs(title = "Distribución Espacial del Crimen en 2019",
       fill = "Índice de Crimen") +
  theme_minimal()

Coahuila, Durango, Baja California Sur, Yucatán y Aguascalientes tienen niveles más bajos de crimen, sugiriendo una menor incidencia delictiva, posiblemente debido a la efectividad de las fuerzas de seguridad y estabilidad socioeconómica. En contraste, Colima, Chihuahua y Baja California Norte muestran niveles más altos de crimen, posiblemente debido a la presencia de grupos delictivos y problemas de seguridad pública. Estos hallazgos destacan las disparidades en los niveles de crimen en México y la importancia de abordar sus causas subyacentes mediante políticas de seguridad efectivas y fortalecimiento del sistema de justicia.

Mapeo de distribución espacial del crimen 2021

ggplot() +
  geom_sf(data = datos_mapa_2021, aes(fill = crime_rate)) +
  scale_fill_viridis_c() +
  labs(title = "Distribución Espacial del Crimen en 2021",
       fill = "Índice de Crimen") +
  theme_minimal()

Hubo un aumento significativo en Zacatecas y Sonora en 2021 en comparación con 2019, posiblemente debido a conflictos entre grupos delictivos o problemas de seguridad pública. En contraste, Colima experimentó una disminución en el crimen en 2021. La mayoría de los estados mostraron una tendencia general a la baja en los niveles de crimen entre 2019 y 2021, excepto Zacatecas y Sonora. Esto puede ser resultado de esfuerzos gubernamentales para mejorar la seguridad y abordar las causas subyacentes del crimen.

Mapeo de distribución espacial de la población en 2019

datos_mapa_2019_filtered2 <- datos_mapa_2019 %>%
  filter(ADMIN_NAME != "Distrito Federal" & ADMIN_NAME != "Mexico")


ggplot() +
  geom_sf(data = datos_mapa_2019_filtered2, aes(fill = pop_density)) +
  scale_fill_viridis_c() +
  labs(title = "Distribución Espacial de la Población en 2019",
       fill = "Índice de Poblacion") +
  theme_minimal()

La Ciudad de México se destaca como el área con la mayor concentración de población en comparación con otros estados en el 2019. Esto es consistente con su estatus como la ciudad más grande y densamente poblada de México. El Estado de México, que rodea la Ciudad de México, también se encuentra más poblado que el resto del país, por lo que debido a esto, se decidió filtrar tanto a la Ciudad de México como al estado de México para poder tener una visualización más clara acerca de los otros estados y su población.

Una vez observando el mapa sin la Ciudad ni el estado de México, se puede visualizar que los estados del centro continúan siendo los más poblados, mientras que la mayoría de los otros estados muestran una distribución más uniforme de población. Esto sugiere una distribución más equitativa en estos estados, sin concentraciones tan significativas como en los estados cercanos a la Ciudad de México.

Mapeo de distribucion espacial de la población en 2021

datos_mapa_2021_filtered2 <- datos_mapa_2021 %>%
  filter(ADMIN_NAME != "Distrito Federal" & ADMIN_NAME != "Mexico")

ggplot() +
  geom_sf(data = datos_mapa_2021_filtered2, aes(fill = pop_density)) +
  scale_fill_viridis_c() +
  labs(title = "Distribución Espacial de la Población en 2021",
       fill = "Índice de Población") +
  theme_minimal()

Al igual que en 2019, la Ciudad de México continúa destacando como el área con la mayor concentración de población en comparación con otros estados, seguido por el estado de México. Esto sugiere una persistencia en el estatus de la capital como el principal centro urbano y demográfico del país.

En la mayoría de los otros estados, la distribución de población permanece relativamente uniforme, como se evidencia en el mapa con tonos uniformes. Esto sugiere una estabilidad en la distribución poblacional en estos estados, sin cambios significativos con respecto a 2019.

Sección D

Elaborar y visualizar 1 – 2 matrices de conectividad para los estados / municipios de México

Estados de México - Distribution of FDI Inflows 2019

fdi <- tm_shape(datos_mapa_2019) + 
  tm_polygons(col = "new_fdi_real_mxn", palette="Blues", style="quantile", n=8, title="MXN FDI Inflows 2019") +
  tm_layout(main.title= 'New FDI Inflows',  title.position = c('right', 'top'), legend.position= c("left", "bottom"), title.size = 1)

unemployment <- tm_shape(datos_mapa_2019) + 
  tm_polygons(col = "unemployment", palette="BuGn", style="quantile", n=8, title="Unemployment") +
  tm_layout(main.title= 'Unemployment 2019',  title.position = c('right', 'top'), legend.position= c("left", "bottom"), title.size = 1)

crime <- tm_shape(datos_mapa_2019) + 
  tm_polygons(col = "crime_rate", palette="OrRd", style="quantile", n=8, title="Crime Rate") +
  tm_layout(main.title= 'Crime Rate 2019',  title.position = c('right', 'top'), legend.position= c("left", "bottom"), title.size = 1)

pop_den <- tm_shape(datos_mapa_2019) + 
  tm_polygons(col = "pop_density", palette="-viridis", style="quantile", n=8, title="Pop Density") +
  tm_layout(main.title= 'Population Density 2019',  title.position = c('right', 'top'), legend.position= c("left", "bottom"), title.size = 1)

education <- tm_shape(datos_mapa_2019) + 
  tm_polygons(col = "college_education", palette="-viridis", style="quantile", n=8, title="College Education") +
  tm_layout(main.title= 'College Education 2019',  title.position = c('right', 'top'), legend.position= c("left", "bottom"), title.size = 1)

# Panel de mapas
tmap_arrange(fdi, unemployment, education, crime, pop_den, ncol = 2)

Estados de México - Distribution of FDI Inflows 2021

fdi2 <- tm_shape(datos_mapa_2021) + 
  tm_polygons(col = "new_fdi_real_mxn", palette="Blues", style="quantile", n=8, title="MXN FDI Inflows 2021") +
  tm_layout(main.title= 'New FDI Inflows',  title.position = c('right', 'top'), legend.position= c("left", "bottom"), title.size = 1)

unemployment2 <- tm_shape(datos_mapa_2021) + 
  tm_polygons(col = "unemployment", palette="BuGn", style="quantile", n=8, title="Unemployment") +
  tm_layout(main.title= 'Unemployment 2021',  title.position = c('right', 'top'), legend.position= c("left", "bottom"), title.size = 1)

crime2 <- tm_shape(datos_mapa_2021) + 
  tm_polygons(col = "crime_rate", palette="OrRd", style="quantile", n=8, title="Crime Rate") +
  tm_layout(main.title= 'Crime Rate 2021',  title.position = c('right', 'top'), legend.position= c("left", "bottom"), title.size = 1)

pop_den2 <- tm_shape(datos_mapa_2021) + 
  tm_polygons(col = "pop_density", palette="-viridis", style="quantile", n=8, title="Pop Density") +
  tm_layout(main.title= 'Population Density 2021',  title.position = c('right', 'top'), legend.position= c("left", "bottom"), title.size = 1)

education2 <- tm_shape(datos_mapa_2021) + 
  tm_polygons(col = "college_education", palette="-viridis", style="quantile", n=8, title="College Education") +
  tm_layout(main.title= 'College Education 2021',  title.position = c('right', 'top'), legend.position= c("left", "bottom"), title.size = 1)

# Panel de Mapas
tmap_arrange(fdi2, unemployment2, education2, crime2, pop_den2, ncol = 2)

Matriz de conectividad de estados 2019 (Método “ROOK”)

# Utilizar el método de "ROOK" 
swm_rook_2019  <- poly2nb(datos_mapa_2019, queen=FALSE)

# Resumen 
summary(swm_rook_2019) 
## Neighbour list object:
## Number of regions: 32 
## Number of nonzero links: 130 
## Percentage nonzero weights: 12.69531 
## Average number of links: 4.0625 
## Link number distribution:
## 
## 1 2 3 4 5 6 7 8 
## 1 6 7 7 3 4 3 1 
## 1 least connected region:
## 31 with 1 link
## 1 most connected region:
## 20 with 8 links
# Convertir matriz a lista de pesos
sswm_rook_2019 <- nb2listw(swm_rook_2019, style="W", zero.policy = TRUE)

# Convertir el mapa de estados a formato spatial
datos_mapa_2019_a <- as(datos_mapa_2019, "Spatial")
datos_mapa_2019_centroid <- coordinates(datos_mapa_2019_a) 

# Graficar la matriz en el mapa
plot(datos_mapa_2019_a,border="blue",axes=FALSE,las=1, main="Estados de México 2019 con ROOK SWM")
plot(datos_mapa_2019_a,col="grey",border=grey(0.9),axes=T,add=T) 
plot(sswm_rook_2019,coords=datos_mapa_2019_centroid,pch=19,cex=0.1,col="red",add=T) 

Matriz de conectividad de estados 2021 (Método “ROOK”)

# Utilizar el método de "ROOK" 
swm_rook_2021  <- poly2nb(datos_mapa_2021, queen=FALSE)

# Resumen 
summary(swm_rook_2021) 
## Neighbour list object:
## Number of regions: 32 
## Number of nonzero links: 130 
## Percentage nonzero weights: 12.69531 
## Average number of links: 4.0625 
## Link number distribution:
## 
## 1 2 3 4 5 6 7 8 
## 1 6 7 7 3 4 3 1 
## 1 least connected region:
## 31 with 1 link
## 1 most connected region:
## 20 with 8 links
# Convertir matriz a lista de pesos
sswm_rook_2021 <- nb2listw(swm_rook_2021, style="W", zero.policy = TRUE)

# Convertir el mapa de estados a formato spatial
datos_mapa_2021_a <- as(datos_mapa_2021, "Spatial")
datos_mapa_2021_centroid <- coordinates(datos_mapa_2021_a) 

# Graficar la matriz en el mapa
plot(datos_mapa_2021_a,border="blue",axes=FALSE,las=1, main="Estados de México 2021 con ROOK SWM")
plot(datos_mapa_2021_a,col="grey",border=grey(0.9),axes=T,add=T) 
plot(sswm_rook_2021,coords=datos_mapa_2021_centroid,pch=19,cex=0.1,col="red",add=T) 

Sección E

Detectar la presencia de autocorrelación espacial global para cada una de las variables seleccionadas.

Globan Moran I nos indica si el valor observado de una variable en una localidad es independiente de los valores de la variable en localidades vecinas.

Moran Test Variable FDI Rook 2019

moran.test(datos_mapa_2019$new_fdi_real_mxn, sswm_rook_2019) 
## 
##  Moran I test under randomisation
## 
## data:  datos_mapa_2019$new_fdi_real_mxn  
## weights: sswm_rook_2019    
## 
## Moran I statistic standard deviate = 1.8555, p-value = 0.03176
## alternative hypothesis: greater
## sample estimates:
## Moran I statistic       Expectation          Variance 
##       0.097528220      -0.032258065       0.004892719

Es estadísticamente significativa debido a que el p value es menor al 0.05, Moran I statistic tiene un resultado mayor al 0.05, lo que nos indica que sí hay una autocorrelación espacial positiva.

Moran Test Variable FDI Rook 2021

moran.test(datos_mapa_2021$new_fdi_real_mxn, sswm_rook_2021) 
## 
##  Moran I test under randomisation
## 
## data:  datos_mapa_2021$new_fdi_real_mxn  
## weights: sswm_rook_2021    
## 
## Moran I statistic standard deviate = 1.4415, p-value = 0.07472
## alternative hypothesis: greater
## sample estimates:
## Moran I statistic       Expectation          Variance 
##        0.14077318       -0.03225806        0.01440759

El Moran I statistic es mayor al 0.05 lo cual dice que sí hay una autocorrelación espacial positiva. Sin embargo, la autocorrelación no es estadísticamente significativa ya que el p value es mayor al 0.05

Moran Test Variable Crime Rate Rook 2019

moran.test(datos_mapa_2019$crime_rate, sswm_rook_2019) 
## 
##  Moran I test under randomisation
## 
## data:  datos_mapa_2019$crime_rate  
## weights: sswm_rook_2019    
## 
## Moran I statistic standard deviate = 0.66232, p-value = 0.2539
## alternative hypothesis: greater
## sample estimates:
## Moran I statistic       Expectation          Variance 
##        0.04969026       -0.03225806        0.01530891

El p value es mayor al 0.05, esto nos indica que no es estadísticamente significativa. El Moran I statistic es menor al 0.05 lo cual indica que la autocorrelación espacial es negativa.

Moran Test Variable Crime Rate Rook 2021

moran.test(datos_mapa_2021$crime_rate, sswm_rook_2021) 
## 
##  Moran I test under randomisation
## 
## data:  datos_mapa_2021$crime_rate  
## weights: sswm_rook_2021    
## 
## Moran I statistic standard deviate = 0.068795, p-value = 0.4726
## alternative hypothesis: greater
## sample estimates:
## Moran I statistic       Expectation          Variance 
##       -0.02370829       -0.03225806        0.01544512

El p value es mayor al 0.05, esto nos indica que no es estadísticamente significativa. El Moran I statistic es menor al 0.05 lo cual nos indica que que la autocorrelación espacial es negativa.

Moran Test Variable Population Density Rook 2019

moran.test(datos_mapa_2019$pop_density, sswm_rook_2019) 
## 
##  Moran I test under randomisation
## 
## data:  datos_mapa_2019$pop_density  
## weights: sswm_rook_2019    
## 
## Moran I statistic standard deviate = 4.3896, p-value = 5.678e-06
## alternative hypothesis: greater
## sample estimates:
## Moran I statistic       Expectation          Variance 
##      0.0954011599     -0.0322580645      0.0008457681

El p value es menor al 0.05, lo que nos dice que la variable sí es estadísticamente significativa, y el Moran I statistic es mayor al 0.05 indicando que sí hay una autocorrelación espacial positiva. Sí podemos ver un patrón espacial en la población.

Moran Test Variable Population Density Rook 2021

moran.test(datos_mapa_2021$pop_density, sswm_rook_2021) 
## 
##  Moran I test under randomisation
## 
## data:  datos_mapa_2021$pop_density  
## weights: sswm_rook_2021    
## 
## Moran I statistic standard deviate = 4.3771, p-value = 6.014e-06
## alternative hypothesis: greater
## sample estimates:
## Moran I statistic       Expectation          Variance 
##      0.0961032264     -0.0322580645      0.0008599994

El p value es menor al 0.05, y el moran I statistic es mayor al 0.05, esto nos dice que la variable es estadísticamente significativa y cuenta con una autocorrelación espacial positiva. Hay un patrón espacial con la población.

Moran Test Variable Unemployment Rook 2019

moran.test(datos_mapa_2019$unemployment, sswm_rook_2019) 
## 
##  Moran I test under randomisation
## 
## data:  datos_mapa_2019$unemployment  
## weights: sswm_rook_2019    
## 
## Moran I statistic standard deviate = 0.3703, p-value = 0.3556
## alternative hypothesis: greater
## sample estimates:
## Moran I statistic       Expectation          Variance 
##        0.01231655       -0.03225806        0.01449003

El p value es mayor al 0.05 lo cual nos dice que no es estadísticamente significativa, el moran I statistic es menor al 0.05, esto nos indica que no hay autocorrelación espacial positiva. No hay un patrón espacial en la tasa de desempleo.

Moran Test Variable Unemployment Rook 2021

moran.test(datos_mapa_2021$unemployment, sswm_rook_2021) 
## 
##  Moran I test under randomisation
## 
## data:  datos_mapa_2021$unemployment  
## weights: sswm_rook_2021    
## 
## Moran I statistic standard deviate = 0.42545, p-value = 0.3353
## alternative hypothesis: greater
## sample estimates:
## Moran I statistic       Expectation          Variance 
##        0.02115556       -0.03225806        0.01576216

El p value es mayor al 0.05, esto nos dice que no es estadísticamente significativa. El Moran I statistic es menor al 0.05 lo cual indica que no hay una autocorrelación espacial positiva.

Moran Test Variable College Education Rook 2019

moran.test(datos_mapa_2019$college_education, sswm_rook_2019) 
## 
##  Moran I test under randomisation
## 
## data:  datos_mapa_2019$college_education  
## weights: sswm_rook_2019    
## 
## Moran I statistic standard deviate = 1.7495, p-value = 0.0401
## alternative hypothesis: greater
## sample estimates:
## Moran I statistic       Expectation          Variance 
##        0.18905303       -0.03225806        0.01600201

El p value es menor al 0.05, esto nos indica que sí es estadísticamente significativa. El Moran I statistic es mayor al 0.05 lo cual indica que sí hay una autocorrelación espacial positiva. Hay un patrón espacial con los niveles de educación universitarias.

Moran Test Variable College Education Rook 2021

moran.test(datos_mapa_2021$college_education, sswm_rook_2021) 
## 
##  Moran I test under randomisation
## 
## data:  datos_mapa_2021$college_education  
## weights: sswm_rook_2021    
## 
## Moran I statistic standard deviate = 2.1721, p-value = 0.01492
## alternative hypothesis: greater
## sample estimates:
## Moran I statistic       Expectation          Variance 
##        0.24108508       -0.03225806        0.01583643

El p value es menor al 0.05, esto nos indica que sí es estadísticamente significativa. El Moran I statistic es mayor al 0.05 lo cual indica que sí existe una autocorrelación espacial positiva. La educación universitaria se encuentra estar espacialmente agrupada.

Sección F y G

Detectar la presencia de autocorrelación espacial local para cada una de las variables seleccionadas. Identificar la posible presencia de clústers locales / regionales para cada una de las variables seleccionadas.

Para esta siguiente sección se tomaron en cuenta únicamente las variables previamente identificadas como relevantes y con significancia estadística para cada año.

Identificación de Clusters 2019

datos_mapa_2019$sp_lag_new_fdi_real_mxn <- lag.listw(sswm_rook_2019, datos_mapa_2019$new_fdi_real_mxn, zero.policy=TRUE) 
datos_mapa_2019$sp_lag_college_education <- lag.listw(sswm_rook_2019, datos_mapa_2019$college_education, zero.policy=TRUE) 
datos_mapa_2019$sp_lag_pop_density <- lag.listw(sswm_rook_2019, datos_mapa_2019$pop_density, zero.policy=TRUE) 

fdi_lag <- tm_shape(datos_mapa_2019) + 
  tm_polygons(col = "sp_lag_new_fdi_real_mxn", palette="Blues", style="quantile", n=8, title="MXN FDI Inflows") +
  tm_layout(main.title= 'Clusters of New FDI Inflows 2019',  title.position = c('right', 'top'), legend.position= c("left", "bottom"), title.size = 1)

education_lag <- tm_shape(datos_mapa_2019) + 
  tm_polygons(col = "sp_lag_college_education", palette="OrRd", style="quantile", n=8, title="College Education") +
  tm_layout(main.title= 'Clusters of College Education 2019',  title.position = c('right', 'top'), legend.position= c("left", "bottom"), title.size = 1)

pop_den_lag <- tm_shape(datos_mapa_2019) + 
  tm_polygons(col = "sp_lag_pop_density", palette="Blues", style="quantile", n=8, title="Population Density") +
  tm_layout(main.title= 'Clusters of Population Density 2019',  title.position = c('right', 'top'), legend.position= c("left", "bottom"), title.size = 1)
# tmap_arrange (2019)
tmap_arrange(fdi, fdi_lag, education, education_lag, pop_den, pop_den_lag, ncol = 2)

El cluster de la variable New FDI del año 2019 demuestra que los estados con mayor inversión extranjera son los estados de Tamaulipas, Estado de México y la Ciudad de México. Esto se debe a que el Estado y la Ciudad de México son importantes centros económicos, históricos y culturales, uno siendo la capital y el otro siendo el estado más poblado del país. Así mismo, la inversión en Tamaulipas se puede deber a su zona geográfica y su frontera con Estados Unidos. Por otro lado, los estados más bajos son Chihuahua, Sinaloa y Quintana Roo y esto se puede deber a temas de seguridad en las zonas y su distancia a los principales centros económicos.

El cluster de la variable de College Education demuestra un mayor índice de educación de universidad en la zona norte-occidente del país y Yucatan, esto puede ser por sus conexiones a Estados Unidos, su desarrollo económico y su presencia de universidades. Por otro lado, los estados de Guerrero y Oaxaca demuestran un índice más bajo y esto se puede deber a que son estados con menor desarrollo socioeconómico.

Por último, el cluster de densidad de población demuestra que la región más poblada del país es el centro, ya que como se menciona anteriormente, ahí se concentra la capital del país y es una zona económica, cultural e histórica, sin embargo, eso también se puede deber a que es una zona pequeña para la cantidad de gente que vive en la región. Por otro lado, se puede notar que uno de los estados con menor densidad de población es Chihuahua, que a contrario del centro, es un estado muy grande y esto puede causar a que la densidad sea pequeña.

Identificación de Clusters 2021

datos_mapa_2021$sp_lag_college_education <- lag.listw(sswm_rook_2021, datos_mapa_2021$college_education, zero.policy=TRUE) 
datos_mapa_2021$sp_lag_pop_density <- lag.listw(sswm_rook_2021, datos_mapa_2021$pop_density, zero.policy=TRUE) 

education_lag2 <- tm_shape(datos_mapa_2021) + 
  tm_polygons(col = "sp_lag_college_education", palette="OrRd", style="quantile", n=8, title="College Education") +
  tm_layout(main.title= 'Clusters of College Education 2021',  title.position = c('right', 'top'), legend.position= c("left", "bottom"), title.size = 1)

pop_den_lag2 <- tm_shape(datos_mapa_2021) + 
  tm_polygons(col = "sp_lag_pop_density", palette="Blues", style="quantile", n=8, title="Population Density") +
  tm_layout(main.title= 'Clusters of Population Density 2021',  title.position = c('right', 'top'), legend.position= c("left", "bottom"), title.size = 1)
# tmap_arrange (2021)
tmap_arrange(education2, education_lag2, pop_den2, pop_den_lag2, ncol = 2)

El cluster del índice de educación de universidad en el país permanece igual que en el año 2019, ya que la cultura de la educación y el desarrollo socioeconómico de la región continua creciendo.

Lo mismo se puede ver en el cluster de densidad de población, es muy similar al de dos años anteriores, ya que el centro es un lugar muy importante para el país y mantiene una población alta debida a la migración tanto de extranjeros como de mexicanos a esta región por distintos factores, especialmente las oportunidades que existen en la capital.

# Visualización de Clusters GeoDa college education 2019
sswm_education <- queen_weights(mx_state_map) # queen spatial weight matrix (alternative format)
lisa_education <- local_moran(sswm_education, datos_mapa_2019["college_education"]) 
datos_mapa_2019$cluster_education <- as.factor(lisa_education$GetClusterIndicators())
levels(datos_mapa_2019$cluster_education)<-lisa_education$GetLabels() 

ggplot(data=datos_mapa_2019) +
  geom_sf(aes(fill=cluster_education)) + 
  ggtitle(label = "College Education 2019", subtitle = "Mexico's States")

Querétaro clasificado como Baja-Alta sugiere que tiene una educación universitaria más baja en comparación con sus vecinos, pero más alta en comparación con el promedio general de los estados mexicanos. Esto podría indicar que Querétaro está relativamente bien posicionado en términos de educación universitaria, pero hay áreas circundantes con niveles más bajos de educación.

Estos estados clasificados como Baja-Baja indican que tienen niveles relativamente bajos de educación universitaria en comparación con sus vecinos y con el promedio general de los estados mexicanos. Esto sugiere que estas regiones pueden enfrentar desafíos en términos de acceso o calidad de la educación universitaria. Estos estados clasificados como Alta-Alta indican que tienen niveles relativamente altos de educación universitaria tanto en ellos mismos como en sus vecinos. Esto sugiere que Baja California y Sonora destacan como regiones con niveles superiores de educación universitaria en comparación con el promedio general de los estados mexicanos y en relación con sus vecinos.

La clasificación no significativa para todos los demás estados sugiere que sus niveles de educación universitaria no difieren significativamente de lo que se esperaría bajo la aleatoriedad espacial. Esto significa que estos estados no muestran un patrón espacial fuerte en términos de educación universitaria en relación con sus vecinos. Es importante considerar el contexto socioeconómico de cada estado al interpretar estos resultados. Factores como la inversión en educación, el acceso a instituciones educativas y las oportunidades laborales pueden influir en los niveles de educación universitaria en cada región.

# Visualización de Clusters GeoDa population density 2019
sswm_pop <- queen_weights(mx_state_map) # queen spatial weight matrix (alternative format)
lisa_pop <- local_moran(sswm_pop, datos_mapa_2019["pop_density"]) 
datos_mapa_2019$cluster_pop <- as.factor(lisa_pop$GetClusterIndicators())
levels(datos_mapa_2019$cluster_pop)<-lisa_pop$GetLabels() 

ggplot(data=datos_mapa_2019) +
  geom_sf(aes(fill=cluster_pop)) + 
  ggtitle(label = "Pop Density 2019", subtitle = "Mexico's States")

Ciudad de México, Morelos y Estado de México - Alta-Alta: Estos estados clasificados como Alta-Alta indican que tienen niveles relativamente altos de densidad de población tanto en ellos mismos como en sus vecinos. Esto sugiere que estas regiones, que son áreas metropolitanas importantes, tienen una alta concentración de población en comparación con el promedio general de los estados mexicanos y en relación con sus vecinos.

Yucatán, Nuevo León, Chihuahua, Durango, Sinaloa y Baja California - Baja-Baja: Estos estados clasificados como Baja-Baja indican que tienen niveles relativamente bajos de densidad de población tanto en ellos mismos como en sus vecinos. Esto sugiere que estas regiones pueden ser menos densamente pobladas en comparación con el promedio general de los estados mexicanos y en relación con sus vecinos.

Resto de los Estados - No Significativos: La clasificación no significativa para el resto de los estados sugiere que sus niveles de densidad de población no difieren significativamente de lo que se esperaría bajo la aleatoriedad espacial. Esto significa que estos estados no muestran un patrón espacial fuerte en términos de densidad de población en relación con sus vecinos.

# Visualización de Clusters GeoDa college education 2021
sswm_education2 <- queen_weights(mx_state_map) # queen spatial weight matrix (alternative format)
lisa_education2 <- local_moran(sswm_education2, datos_mapa_2021["college_education"]) 
datos_mapa_2021$cluster_education2 <- as.factor(lisa_education2$GetClusterIndicators())
levels(datos_mapa_2021$cluster_education2)<-lisa_education2$GetLabels() 

ggplot(data=datos_mapa_2021) +
  geom_sf(aes(fill=cluster_education2)) + 
  ggtitle(label = "College Education 2021", subtitle = "Mexico's States")

Baja California - Alta-Alta: Baja California clasificada como Alta-Alta indica que tiene niveles relativamente altos de educación universitaria tanto en ella misma como en sus vecinos. Esto sugiere que Baja California, y posiblemente sus áreas metropolitanas como Tijuana, tienen una alta concentración de personas con educación universitaria en comparación con el promedio general de los estados mexicanos y en relación con sus vecinos.

Guerrero, Oaxaca y Puebla - Baja-Baja: Estos estados clasificados como Baja-Baja indican que tienen niveles relativamente bajos de educación universitaria tanto en ellos mismos como en sus vecinos. Esto sugiere que Guerrero, Oaxaca y Puebla pueden enfrentar desafíos en términos de acceso o calidad de la educación universitaria en comparación con el promedio general de los estados mexicanos y en relación con sus vecinos.

Resto de los Estados - No Significativos: La clasificación no significativa para el resto de los estados sugiere que sus niveles de educación universitaria no difieren significativamente de lo que se esperaría bajo la aleatoriedad espacial. Esto significa que estos estados no muestran un patrón espacial fuerte en términos de educación universitaria en relación con sus vecinos.

# Visualización de Clusters GeoDa population density 2021
sswm_pop2 <- queen_weights(mx_state_map) # queen spatial weight matrix (alternative format)
lisa_pop2 <- local_moran(sswm_pop2, datos_mapa_2021["pop_density"]) 
datos_mapa_2021$cluster_pop2 <- as.factor(lisa_pop2$GetClusterIndicators())
levels(datos_mapa_2021$cluster_pop2)<-lisa_pop2$GetLabels() 

ggplot(data=datos_mapa_2021) +
  geom_sf(aes(fill=cluster_pop2)) + 
  ggtitle(label = "Pop Density 2021", subtitle = "Mexico's States")

La distribución de la densidad de población en los estados de México muestra una consistencia entre los años 2019 y 2021 en cuanto a la clasificación de los estados en las categorías High-High, Low-Low y No Significativos. Los estados de Ciudad de México, Morelos y Estado de México continúan siendo clasificados como High-High en ambos años, lo que indica una alta concentración de densidad de población en estas regiones.

Del mismo modo, los estados de Yucatán, Nuevo León, Chihuahua, Durango, Sinaloa y Baja California siguen siendo clasificados como Low-Low en ambos años, lo que indica niveles más bajos de densidad de población en estas regiones en comparación con el promedio general.

Los resultados sugieren cierta estabilidad en la distribución espacial de la densidad de población en los estados de México entre los años 2019 y 2021, con algunas regiones manteniendo su clasificación mientras que otras permanecen no significativas en ambos años.

# Cargar nuevas librerías
library(spatialreg)
## Loading required package: Matrix
## 
## Attaching package: 'spatialreg'
## The following objects are masked from 'package:spdep':
## 
##     get.ClusterOption, get.coresOption, get.mcOption,
##     get.VerboseOption, get.ZeroPolicyOption, set.ClusterOption,
##     set.coresOption, set.mcOption, set.VerboseOption,
##     set.ZeroPolicyOption
library(stargazer)
## 
## Please cite as:
##  Hlavac, Marek (2022). stargazer: Well-Formatted Regression and Summary Statistics Tables.
##  R package version 5.2.3. https://CRAN.R-project.org/package=stargazer

Actividad Extra 1

library(plm)
## 
## Attaching package: 'plm'
## The following objects are masked from 'package:dplyr':
## 
##     between, lag, lead
library(pspatreg)
# Importar panel dataset 
panel_data <- read.csv("/Users/reginaenriquez/Desktop/Act 1/panel_dataset.csv")

summary(panel_data)
##     state                year         state_id       new_fdi       
##  Length:512         Min.   :2006   Min.   : 888   Min.   :-958.11  
##  Class :character   1st Qu.:2010   1st Qu.:1047   1st Qu.:  59.33  
##  Mode  :character   Median :2014   Median :1081   Median : 196.00  
##                     Mean   :2014   Mean   :1219   Mean   : 367.61  
##                     3rd Qu.:2017   3rd Qu.:1118   3rd Qu.: 429.81  
##                     Max.   :2021   Max.   :2357   Max.   :4724.62  
##                                                                    
##  reinv_profits      intercom_acc        total_fdi        crime_rate     
##  Min.   : -55.23   Min.   :-796.120   Min.   :-405.5   Min.   :  1.710  
##  1st Qu.:  69.75   1st Qu.:   6.902   1st Qu.: 195.2   1st Qu.:  7.973  
##  Median : 156.84   Median :  81.315   Median : 493.6   Median : 13.745  
##  Mean   : 370.56   Mean   : 207.514   Mean   : 945.7   Mean   : 21.758  
##  3rd Qu.: 400.09   3rd Qu.: 328.062   3rd Qu.:1184.5   3rd Qu.: 25.828  
##  Max.   :4436.22   Max.   :1960.580   Max.   :8777.9   Max.   :181.510  
##                                                                         
##   unemployment       employment     business_activity   real_wage    
##  Min.   :0.01000   Min.   :0.8900   Min.   :-2.980    Min.   :239.3  
##  1st Qu.:0.03000   1st Qu.:0.9500   1st Qu.:-2.270    1st Qu.:281.1  
##  Median :0.04000   Median :0.9700   Median :-2.090    Median :304.8  
##  Mean   :0.04326   Mean   :0.9632   Mean   :-1.868    Mean   :312.8  
##  3rd Qu.:0.05000   3rd Qu.:0.9700   3rd Qu.:-1.887    3rd Qu.:333.9  
##  Max.   :0.10000   Max.   :0.9900   Max.   : 2.470    Max.   :466.8  
##                                                                      
##  real_ave_month_income  pop_density      good_governance  
##  Min.   :3281          Min.   :   7.74   Min.   :  0.000  
##  1st Qu.:4553          1st Qu.:  39.56   1st Qu.:  0.170  
##  Median :5247          Median :  61.49   Median :  0.480  
##  Mean   :5384          Mean   : 298.49   Mean   :  2.219  
##  3rd Qu.:6083          3rd Qu.: 149.11   3rd Qu.:  1.258  
##  Max.   :9206          Max.   :6195.59   Max.   :200.020  
##                                                           
##  ratio_public_investment   lq_primary     lq_secondary     lq_tertiary    
##  Min.   :0.000000        Min.   :0.010   Min.   :0.3200   Min.   :0.7800  
##  1st Qu.:0.000000        1st Qu.:0.400   1st Qu.:0.6700   1st Qu.:0.9400  
##  Median :0.000000        Median :0.740   Median :0.9900   Median :1.0100  
##  Mean   :0.005625        Mean   :1.057   Mean   :0.9869   Mean   :0.9996  
##  3rd Qu.:0.010000        3rd Qu.:1.350   3rd Qu.:1.2500   3rd Qu.:1.0700  
##  Max.   :0.030000        Max.   :4.700   Max.   :1.9900   Max.   :1.1800  
##                                                                           
##  exchange_rate    patents_rate         inpc        border_distance  
##  Min.   :10.85   Min.   : 0.000   Min.   : 62.69   Min.   :   8.83  
##  1st Qu.:12.87   1st Qu.: 0.330   1st Qu.: 74.14   1st Qu.: 613.26  
##  Median :14.14   Median : 0.800   Median : 85.48   Median : 751.64  
##  Mean   :15.69   Mean   : 1.557   Mean   : 86.75   Mean   : 704.92  
##  3rd Qu.:19.38   3rd Qu.: 1.923   3rd Qu.: 99.46   3rd Qu.: 875.76  
##  Max.   :20.52   Max.   :13.770   Max.   :117.31   Max.   :1252.66  
##                  NA's   :32                                         
##  college_education new_fdi_real_mxn log_new_fdi_real_mxn   region_a        
##  Min.   :0.1860    Min.   :-15305   Min.   :-4.185       Length:512        
##  1st Qu.:0.3050    1st Qu.:  1124   1st Qu.: 3.050       Class :character  
##  Median :0.3530    Median :  3496   Median : 3.544       Mode  :character  
##  Mean   :0.3599    Mean   :  6587   Mean   : 3.192                         
##  3rd Qu.:0.4140    3rd Qu.:  7558   3rd Qu.: 3.878                         
##  Max.   :0.5740    Max.   : 91516   Max.   : 4.961                         
##                                                                            
##     region_b     trump_election    exports        
##  Min.   :1.000   Min.   :0.00   Min.   :   14707  
##  1st Qu.:2.000   1st Qu.:0.00   1st Qu.: 1090699  
##  Median :3.000   Median :0.00   Median : 4125480  
##  Mean   :3.188   Mean   :0.25   Mean   :10202997  
##  3rd Qu.:4.250   3rd Qu.:0.25   3rd Qu.:16852403  
##  Max.   :5.000   Max.   :1.00   Max.   :58614915  
##                                 NA's   :32
pd_frame <- pdata.frame(panel_data, index = c("state", "year"), drop.index = TRUE)
# Especificar el modelo del panel 2019
panel_model_2019 <- new_fdi_real_mxn ~ crime_rate + pop_density + college_education + unemployment
# Estimar el modelo de regresión 
non_spatial_panel_model_2019 <- plm(panel_model_2019, data = pd_frame, model = "within", effect = "twoways")
summary(non_spatial_panel_model_2019)
## Twoways effects Within Model
## 
## Call:
## plm(formula = panel_model_2019, data = pd_frame, effect = "twoways", 
##     model = "within")
## 
## Balanced Panel: n = 32, T = 16, N = 512
## 
## Residuals:
##      Min.   1st Qu.    Median   3rd Qu.      Max. 
## -51967.33  -2522.85   -521.68   1769.87  50119.88 
## 
## Coefficients:
##                      Estimate  Std. Error t-value Pr(>|t|)
## crime_rate            -4.6261     21.3899 -0.2163   0.8289
## pop_density           30.9296     20.5189  1.5074   0.1324
## college_education -11717.1570  18391.2743 -0.6371   0.5244
## unemployment      -19921.0568  33541.1689 -0.5939   0.5529
## 
## Total Sum of Squares:    2.1112e+10
## Residual Sum of Squares: 2.0978e+10
## R-Squared:      0.0063194
## Adj. R-Squared: -0.10146
## F-statistic: 0.732947 on 4 and 461 DF, p-value: 0.5698
# Estimar el modelo de regresión espacial 
spatial_panel_model_2019 <- pspatfit(formula = panel_model_2019, data = pd_frame, listw = sswm_rook_2019, demean = FALSE, eff_demean = "twoways", type = "sar", index = c("state", "year"))
## 
## Fitting Model...
## 
##  Time to fit the model:  0.37 seconds
summary(spatial_panel_model_2019)
## 
##  Call 
## pspatfit(formula = panel_model_2019, data = pd_frame, listw = sswm_rook_2019, 
##     type = "sar", demean = FALSE, eff_demean = "twoways", index = c("state", 
##         "year"))
## 
##  Parametric Terms 
##                       Estimate  Std. Error t value Pr(>|t|)    
## (Intercept)        4.9279e+03  2.0696e+03  2.3811  0.01763 *  
## crime_rate        -5.2905e+00  1.6602e+01 -0.3187  0.75011    
## pop_density        6.4880e+00  3.5911e-01 18.0670  < 2e-16 ***
## college_education -3.0908e+03  4.8728e+03 -0.6343  0.52618    
## unemployment       9.3443e+03  2.6902e+04  0.3473  0.72848    
## rho                7.4430e-02  4.7211e-02  1.5765  0.11553    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
##  Goodness-of-Fit 
##  
##  EDF Total:      6 
##  Sigma: 8038.77 
##  AIC:  9722.67 
##  BIC:  9748.1
LS0tCnRpdGxlOiAiQWN0aXZpZGFkIDEgLSBBbsOhbGlzaXMgRXhwbG9yYXRvcmlvIEVzcGFjaWFsIGRlIERhdG9zIgpvdXRwdXQ6IAogIGh0bWxfZG9jdW1lbnQ6CiAgICB0b2M6IFRSVUUKICAgIHRvY19mbG9hdDoKICAgICAgY29sbGFwc2VkOiBUUlVFCiAgICBjb2RlX2Rvd25sb2FkOiBUUlVFCiAgICB0aGVtZTogZmxhdGx5CmRhdGU6ICIyMDI0LTA0LTAzIgotLS0KCiMjIyBFcXVpcG8gNDoKIyMjIyBSZWdpbmEgRW5yaXF1ZXogQ2hhcGEgCUEwMTcyMTQzNQojIyMjIExvcmVuYSBWaWxsYXJyZWFsIFZlZ2EJQTAxNzIwODAyCiMjIyMgRGFuaWVsYSBHYXJ6YSBBbnpvbGEJCUEwMTcyMTA3MQojIyMjIFJhcXVlbCBHYXJ6YSBNYXJ0w61uZXoJQTAwODMwMjAzCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKQpgYGAKCmBgYHtyfQojRGVzY2FyZ2FyIGxpYnJlcsOtYXMKbGlicmFyeShmb3JlaWduKQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KHNwZGVwKQpsaWJyYXJ5KHRpZ3JpcykKbGlicmFyeShyZ2VvZGEpCmxpYnJhcnkoUkNvbG9yQnJld2VyKQpsaWJyYXJ5KHZpcmlkaXMpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeSh0bWFwKQpsaWJyYXJ5KHNmKQpsaWJyYXJ5KHNwKQpsaWJyYXJ5KHJlYWRyKQpsaWJyYXJ5KHNwZGVwKQpgYGAKCmBgYHtyfQojSW1wb3J0YXIgYmFzZSBkZSBkYXRvcwpsaWJyYXJ5KHJlYWRyKQpwYW5lbF9kYXRhc2V0IDwtIHJlYWQuY3N2KCIvVXNlcnMvcmVnaW5hZW5yaXF1ZXovRGVza3RvcC9BY3QgMS9wYW5lbF9kYXRhc2V0LmNzdiIpCmBgYAoKIyBWYXJpYWJsZXMgU2VsZWNjaW9uYWRhcwojIyMgVmFyaWFibGUgRGVwZW5kaWVudGU6Cm5ld19mZGlfcmVhbF9teG4gLSBOZXcgRm9yZWlnbiBEaXJlY3QgSW52ZXN0bWVudCBJbmZsb3dzLiBNaWxsaW9ucyBvZiBEb2xsYXJzLiAgICAgICAgCgojIyMgVmFyaWFibGVzIEluZGVwZW5kaWVudGVzOgpjcmltZV9yYXRlIC0gQ3JpbWUgUmF0ZSBwZXIgMTAwLDAwMCBzdGF0ZSdzIHBvcHVsYXRpb24uICAgICAgICAKcG9wX2RlbnNpdHkgLSBQb3B1bGF0aW9uIHBlciBzdGF0ZSdzIGxhbmQgYXJlYSBrbcKyLiAgICAKdW5lbXBsb3ltZW50IC0gUGVyY2VudGFnZSBvZiBVbmVtcGxveW1lbnQgcG9wdWxhdGlvbi4gICAgICAKY29sbGVnZV9lZHVjYXRpb24gLSBDb2xsZWdlIEVkdWNhdGlvbiAgICAgICAKCiMgU2VjY2nDs24gQQoxLiBFc3RhZGnMgXN0aWNvcyBEZXNjcmlwdGl2b3MgKEdsb2JhbCB5IFJlZ2lvbmFsKS4gSW5jbHVpciBlbGVtZW50b3MgZ3JhzIFmaWNvcyAoaGlzdG9ncmFtYXMsIGdyYcyBZmljbyBkZSBiYXJyYXMsIGV0Yy4pLgoKUGFyYSBlc3RhIHByaW1lcmEgc2VjY2nDs24gc2UgcmVhbGl6YXJvbiBzdWJqdW50b3MgZGUgZGF0b3MgZGUgY2FkYSB1bmEgZGUgbGFzIHJlZ2lvbmVzIGRlIE3DqXhpY28gcGFyYSBkZXNwdcOpcyBwb2RlciBjb250aW51YXIgdmlzdWFsaXphbmRvIGxhIGluZm9ybWFjaW9uIGRlIGxvcyBmbHVqb3MgZGUgSW52ZXJzacOzbiBFeHRyYW5qZXJhIERpcmVjdGEgKEZESSkgZGVudHJvIGRlIHVuIGdyw6FmaWNvIGRlIGJhcnJhcyBwYXJhIGNhZGEgdW5hIGRlIGxhcyByZWdpb25lcy4gCgojIyMgQmFycGxvdCBSZWdpw7NuIE5vcnRlCmBgYHtyfQpub3J0ZSA8LSBzdWJzZXQocGFuZWxfZGF0YXNldCwgc3RhdGUgJWluJSBjKCJCYWphIENhbGlmb3JuaWEiLCJDaGlodWFodWEiLCAiQ29haHVpbGEiLCAiTnVldm8gTGVvbiIsICJTb25vcmEiLCAiVGFtYXVsaXBhcyIpKQoKZ2dwbG90KGRhdGEgPSBub3J0ZSwgYWVzKHggPSBzdGF0ZSwgeSA9IG5ld19mZGlfcmVhbF9teG4pKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIGZpbGwgPSAic3RlZWxibHVlIikgKwogIHRoZW1lX21pbmltYWwoKSArCiAgbGFicyh4ID0gIkVzdGFkb3MiLCB5ID0gIkZESSIsIHRpdGxlID0gIkZESSBwb3IgRXN0YWRvcyBkZWwgTm9ydGUiKQpgYGAKCkVsIGdyw6FmaWNvIGRlIGJhcnJhcyBtdWVzdHJhIGxvcyBmbHVqb3MgZGUgSW52ZXJzacOzbiBFeHRyYW5qZXJhIERpcmVjdGEgKEZESSkgZW4gdmFyaW9zIGVzdGFkb3MgZGVsIG5vcnRlIGRlIE3DqXhpY28uIFNlIHB1ZWRlIG9ic2VydmFyIGNvbW8gTnVldm8gTGXDs24gbGlkZXJhLCBzZWd1aWRvIGRlIENvYWh1aWxhLCBCYWphIENhbGlmb3JuaWEsIFRhbWF1bGlwYXMsIENoaWh1YWh1YSB5IFNvbm9yYS4gRXN0YSBpbmZvcm1hY2nDs24gZXMgY2xhdmUgcGFyYSBlbnRlbmRlciBsYSBkaXN0cmlidWNpw7NuIGdlb2dyw6FmaWNhIGRlIGxhIEZESSB5IHB1ZWRlIG9yaWVudGFyIHBvbMOtdGljYXMgZWNvbsOzbWljYXMgeSBlc3RyYXRlZ2lhcyBkZSBkZXNhcnJvbGxvIHJlZ2lvbmFsLiBTZSBwdWVkZSBkZWNpciBxdWUgTnVldm8gTGXDs24gZGVzdGFjYSBncmFjaWFzIGEgc3UgaW5mcmFlc3RydWN0dXJhIGluZHVzdHJpYWwsIHViaWNhY2nDs24gZXN0cmF0w6lnaWNhIHkgYW1iaWVudGUgZW1wcmVzYXJpYWwsIG1pZW50cmFzIHF1ZSBDaGlodWFodWEgeSBTb25vcmEgbXVlc3RyYW4gZmx1am9zIGRlIGludmVyc2nDs24gbcOhcyBiYWpvcyBlbiBjb21wYXJhY2nDs24gY29uIG90cm9zIGVzdGFkb3MuCgojIyMgQmFycGxvdCBSZWdpw7NuIFN1cgpgYGB7cn0Kc3VyIDwtIHN1YnNldChwYW5lbF9kYXRhc2V0LCBzdGF0ZSAlaW4lIGMoIkNhbXBlY2hlIiwgIkNoaWFwYXMiLCJHdWVycmVybyIsICJPYXhhY2EiLCAiUXVpbnRhbmEgUm9vIiwgIlRhYmFzY28iLCAiVmVyYWNydXoiLCAiWXVjYXRhbiIpKQoKZ2dwbG90KGRhdGE9c3VyLCBhZXMoeD1zdXIkc3RhdGUsIHk9c3VyJG5ld19mZGlfcmVhbF9teG4pKSArCiAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiLCBmaWxsPSJyZWQiKSsKICB0aGVtZV9taW5pbWFsKCkgKwogIGxhYnMoeCA9ICJFc3RhZG9zIiwgeSA9ICJGREkiLCB0aXRsZSA9ICJGREkgcG9yIEVzdGFkb3MgZGVsIFN1ciIpCmBgYAoKRXN0ZSBncsOhZmljbyBkZSBiYXJyYXMgcmVzYWx0YSBsYXMgZGlmZXJlbmNpYXMgZW4gbG9zIGZsdWpvcyBkZSBpbnZlcnNpw7NuIGRpcmVjdGEgZW50cmUgbG9zIGVzdGFkb3MgZGVsIHN1ciBkZSBNw6l4aWNvLiBWZXJhY3J1eiBsaWRlcmEgZW4gdMOpcm1pbm9zIGRlIEZESSwgcG9zaWJsZW1lbnRlIGRlYmlkbyBhIHN1IGluZnJhZXN0cnVjdHVyYSBwb3J0dWFyaWEsIHJlY3Vyc29zIG5hdHVyYWxlcyB5IHViaWNhY2nDs24gZXN0cmF0w6lnaWNhLiBUYWJhc2NvIHkgR3VlcnJlcm8gbXVlc3RyYW4gZmx1am9zIGRlIGludmVyc2nDs24gc2ltaWxhcmVzLCBsbyBxdWUgcHVlZGUgZXN0YXIgcmVsYWNpb25hZG8gY29uIGxhIGluZHVzdHJpYSBwZXRyb2xlcmEgeSB0dXLDrXN0aWNhLCByZXNwZWN0aXZhbWVudGUuIE9heGFjYSwgQ2FtcGVjaGUsIFl1Y2F0w6FuIHkgQ2hpYXBhcyBzaWd1ZW4gZW4gb3JkZW4gZGVzY2VuZGVudGUgZW4gdMOpcm1pbm9zIGRlIGZsdWpvcyBkZSBpbnZlcnNpw7NuLCBsbyBxdWUgcHVlZGUgZXN0YXIgaW5mbHVlbmNpYWRvIHBvciBkaXZlcnNvcyBmYWN0b3JlcyBjb21vIGxhIGluZnJhZXN0cnVjdHVyYSwgbG9zIHJlY3Vyc29zIG5hdHVyYWxlcywgbGFzIHBvbMOtdGljYXMgZ3ViZXJuYW1lbnRhbGVzIHkgbGFzIGNvbmRpY2lvbmVzIGVjb27Ds21pY2FzIGxvY2FsZXMuCgoKIyMjIEJhcnBsb3QgUmVnacOzbiBDZW50cm8KYGBge3J9CmNlbnRybyA8LSBzdWJzZXQocGFuZWxfZGF0YXNldCwgc3RhdGUgJWluJSBjKCJDaXVkYWQgZGUgTWV4aWNvIiwgIkhpZGFsZ28iLCAiTWV4aWNvIiwgIk1vcmVsb3MiLCAiUHVlYmxhIiwgIlRsYXhjYWxhIikpCgpnZ3Bsb3QoZGF0YT1jZW50cm8sIGFlcyh4PWNlbnRybyRzdGF0ZSwgeT1jZW50cm8kbmV3X2ZkaV9yZWFsX214bikpICsKICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIsIGZpbGw9ImRhcmtncmVlbiIpKwogIHRoZW1lX21pbmltYWwoKSsKICBsYWJzKHggPSAiRXN0YWRvcyIsIHkgPSAiRkRJIiwgdGl0bGUgPSAiRkRJIHBvciBFc3RhZG9zIGRlbCBDZW50cm8iKQpgYGAKClNlIHB1ZWRlIG9ic2VydmFyIGVuIGVsIGdyw6FmaWNvIGRlIGJhcnJhcyBkZSBsYSByZWdpw7NuIGNlbnRyYWwgZGUgTcOpeGljbyBjb21vIGVzIHF1ZSBMYSBDaXVkYWQgZGUgTcOpeGljbyBkZXN0YWNhIGNvbW8gbMOtZGVyLCBsbyBjdWFsIHB1ZWRlIHNlciBkZWJpZG8gYSBzdSBwb3NpY2nDs24gY29tbyBjZW50cm8gZmluYW5jaWVybyB5IHBvbMOtdGljby4gRWwgRXN0YWRvIGRlIE3DqXhpY28gc2lndWUsIHBvc2libGVtZW50ZSBkZWJpZG8gYSBzdSBwcm94aW1pZGFkIGNvbiBsYSBjYXBpdGFsIHkgc3UgaW5mcmFlc3RydWN0dXJhIGluZHVzdHJpYWwuIFB1ZWJsYSwgcmVjb25vY2lkYSBwb3Igc3UgaW5kdXN0cmlhIGF1dG9tb3RyaXosIHNlIHNpdMO6YSBlbiB0ZXJjZXIgbHVnYXIsIG1pZW50cmFzIHF1ZSBIaWRhbGdvLCBNb3JlbG9zIHkgVGxheGNhbGEgbXVlc3RyYW4gZmx1am9zIGRlIGludmVyc2nDs24gbcOhcyBiYWpvcywgc3VnaXJpZW5kbyB1bmEgbWVub3IgYWN0aXZpZGFkIGVjb27Ds21pY2EgbyBpbmZyYWVzdHJ1Y3R1cmEgaW5kdXN0cmlhbCBtZW5vcyBkZXNhcnJvbGxhZGEuCgoKIyMjIEJhcnBsb3QgUmVnacOzbiBPY2NpZGVudGUKYGBge3J9Cm9jY2lkZW50ZSA8LSBzdWJzZXQocGFuZWxfZGF0YXNldCwgc3RhdGUgJWluJSBjKCJCYWphIENhbGlmb3JuaWEgU3VyIiwgIkNvbGltYSIsICJEdXJhbmdvIiwgIkphbGlzY28iICwgIk1pY2hvYWNhbiIsICJOYXlhcml0IiwgIlNpbmFsb2EiKSkKCmdncGxvdChkYXRhPW9jY2lkZW50ZSwgYWVzKHg9b2NjaWRlbnRlJHN0YXRlLCB5PW9jY2lkZW50ZSRuZXdfZmRpX3JlYWxfbXhuKSkgKwogIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IiwgZmlsbD0icHVycGxlIikrCiAgdGhlbWVfbWluaW1hbCgpKwogIGxhYnMoeCA9ICJFc3RhZG9zIiwgeSA9ICJGREkiLCB0aXRsZSA9ICJGREkgcG9yIEVzdGFkb3MgZGVsIE9jY2lkZW50ZSIpCmBgYAoKQ29udGludWFuZG8gY29uIGVsIGdyw6FmaWNvIGRlIGJhcnJhcyBkZSBsYSByZWdpw7NuIG9jY2lkZW50YWwgZGUgTcOpeGljbywgc2Ugb2JzZXJ2YSBhIEphbGlzY28gZW4gcHJpbWVyIGx1Z2FyLCBzZWd1aWRvIHBvciBCYWphIENhbGlmb3JuaWEgU3VyIHkgTWljaG9hY8Ohbi4gSmFsaXNjbyBsaWRlcmEgZGViaWRvIGEgc3UgZWNvbm9tw61hIGRpdmVyc2lmaWNhZGEgeSBzZWN0b3IgdGVjbm9sw7NnaWNvIGVuIGNyZWNpbWllbnRvLCBtaWVudHJhcyBxdWUgQmFqYSBDYWxpZm9ybmlhIFN1ciBkZXN0YWNhIHBvciBlbCB0dXJpc21vIGVuIExvcyBDYWJvcyB5IExhIFBhei4gTG9zIG90cm9zIGVzdGFkb3MgbXVlc3RyYW4gZmx1am9zIGRlc2NlbmRlbnRlcywgbG9zIGN1YWxlcyBwdWVkZW4gZXN0YXIgaW1wdWxzYWRvcyBwb3Igc2VjdG9yZXMgY29tbyBhZ3JpY3VsdHVyYSwgcGVzY2EsIG1pbmVyw61hIHkgdHVyaXNtby4gQ29saW1hIGNpZXJyYSBjb24gZmx1am9zIG1lbm9yZXMsIHByb2JhYmxlbWVudGUgZGViaWRvIGEgc3UgdGFtYcOxbyB5IGVjb25vbcOtYSBtZW5vcyBkaXZlcnNpZmljYWRhLgoKCiMjIyBCYXJwbG90IFJlZ2nDs24gQmFqw61vCmBgYHtyfQpiYWppbyA8LSBzdWJzZXQocGFuZWxfZGF0YXNldCwgc3RhdGUgJWluJSBjKCJBZ3Vhc2NhbGllbnRlcyIsICJHdWFuYWp1YXRvIiwiUXVlcmV0YXJvICIsICJTYW4gTHVpcyBQb3Rvc2kiLCAiWmFjYXRlY2FzIikpCgpnZ3Bsb3QoZGF0YT1iYWppbywgYWVzKHg9YmFqaW8kc3RhdGUsIHk9YmFqaW8kbmV3X2ZkaV9yZWFsX214bikpICsKICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIsIGZpbGw9InBpbmsiKSsKICB0aGVtZV9taW5pbWFsKCkrCiAgbGFicyh4ID0gIkVzdGFkb3MiLCB5ID0gIkZESSIsIHRpdGxlID0gIkZESSBwb3IgRXN0YWRvcyBkZWwgQmFqaW8iKQpgYGAKClBvciB1bHRpbW8sIGRlbnRybyBkZWwgZ3JhZmljbyBkZSBsYSByZWdpw7NuIEJhasOtbyBkZSBNw6l4aWNvLCBkZXN0YWNhIEd1YW5hanVhdG8gZW4gcHJpbWVyIGx1Z2FyLCBzZWd1aWRvIHBvciBRdWVyw6l0YXJvIHkgU2FuIEx1aXMgUG90b3PDrSBlbiBzZWd1bmRvIGx1Z2FyLCBaYWNhdGVjYXMgeSBmaW5hbG1lbnRlIEFndWFzY2FsaWVudGVzLiBHdWFuYWp1YXRvIGRlc3RhY2EgcG9yIHN1IHViaWNhY2nDs24gZXN0cmF0w6lnaWNhIHkgZnVlcnRlIGluZnJhZXN0cnVjdHVyYSBpbmR1c3RyaWFsLCBlc3BlY2lhbG1lbnRlIGVuIHNlY3RvcmVzIGNvbW8gbGEgYXV0b21vdHJpeiB5IGxhIG1hbnVmYWN0dXJhLiBRdWVyw6l0YXJvIHkgU2FuIEx1aXMgUG90b3PDrSBjb21wYXJ0ZW4gZWwgc2VndW5kbyBsdWdhciwgaW1wdWxzYWRvcyBwb3IgZWwgY3JlY2ltaWVudG8gZW4gc2VjdG9yZXMgY29tbyBsYSBhZXJvZXNwYWNpYWwgeSBsYSBtYW51ZmFjdHVyYS4gWmFjYXRlY2FzIHNpZ3VlLCBjb24gdW5hIHByZXNlbmNpYSBpbXBvcnRhbnRlIGVuIGxhIG1pbmVyw61hIHkgbGEgYWdyaWN1bHR1cmEuIEFndWFzY2FsaWVudGVzLCBhdW5xdWUgbXVlc3RyYSBmbHVqb3MgbcOhcyBiYWpvcywgaGEgc2lkbyBhdHJhY3Rpdm8gcGFyYSBpbnZlcnNpb25lcyBlbiBzZWN0b3JlcyBjb21vIGxhIGF1dG9tb3RyaXogeSBsYSBlbGVjdHLDs25pY2EuCgojIFNlY2Npw7NuIEIKRXN0YWRpzIFzdGljb3MgZGUgRGlzcGVyc2lvzIFuIChHbG9iYWwgeSBSZWdpb25hbCkuIEluY2x1aXIgZWxlbWVudG9zIGdyYcyBZmljb3MgKGJveCBwbG90cywgcXEtIHBsb3RzLCBldGMuKS4KCkRlbnRybyBkZSBlc3RhIHNlY2Npw7NuIGRlIHBvZHLDoW4gdWJzZXJ2YXIgYm94cGxvdHMgZGUgY2FkYSByZWdpw7NuIHBhcmEgY2FkYSB1bmEgZGUgbGFzIHZhcmlhYmxlcyBzZWxlY2Npb25hZGFzLiBFc3RvcyBncsOhZmljb3MgZmFjaWxpdGFuIGxhIGNvbXBhcmFjacOzbiBkZSBsYXMgY2FyYWN0ZXLDrXN0aWNhcyBlbnRyZSBsYXMgZGlmZXJlbnRlcyDDoXJlYXMgZ2VvZ3LDoWZpY2FzLgoKIyMjIEJveHBsb3QgcGFyYSBsYSB2YXJpYWJsZSBGREkKYGBge3J9CnJlZ2lvbmVzX3VuaWNhcyA8LSB1bmlxdWUocGFuZWxfZGF0YXNldCRyZWdpb25fYSkKY29sb3JlcyA8LSBwbGFzbWEobGVuZ3RoKHJlZ2lvbmVzX3VuaWNhcykpCgpib3hwbG90KHBhbmVsX2RhdGFzZXQkbmV3X2ZkaV9yZWFsX214biB+IHBhbmVsX2RhdGFzZXQkcmVnaW9uX2EsCiAgICAgICAgeGxhYiA9ICJSZWdpw7NuIiwKICAgICAgICB5bGFiID0gIkZESSIsCiAgICAgICAgbWFpbiA9ICJCb3hwbG90IGRlIEZESSBwb3IgcmVnacOzbiIsCiAgICAgICAgY29sID0gY29sb3JlcykKYGBgCgpFbCBib3hwbG90IGRlIGxhIHZhcmlhYmxlIEZESSByZXZlbGEgcXVlIGxvcyBmbHVqb3MgZGUgaW52ZXJzacOzbiBlbiBlbCBjZW50cm8gZGUgTcOpeGljbyB0aWVuZW4gdW5hIG1heW9yIHZhcmlhYmlsaWRhZCBlbiBjb21wYXJhY2nDs24gY29uIGxvcyBkZW3DoXMuIEF1bnF1ZSBlbCBjZW50cm8gbXVlc3RyYSB1bmEgZGl2ZXJzaWRhZCBjb25zaWRlcmFibGUsIHN1IG1lZGlhbmEgZXMgbcOhcyBiYWphIHF1ZSBsYSBkZWwgbm9ydGUuIEFkZW3DoXMsIHNlIG9ic2VydmFuIHZhbG9yZXMgYXTDrXBpY29zIGVuIGVzdGEgcmVnacOzbi4gRWwgQmFqw61vIHByZXNlbnRhIHVuYSBtZWRpYW5hIGNvbXBhcmFibGUgYSBsYSBkZWwgbm9ydGUsIGluZGljYW5kbyB1bmEgYWx0YSBjb25jZW50cmFjacOzbiBkZSBpbnZlcnNpw7NuLiBBdW5xdWUgbG9zIGJveHBsb3RzIGRlbCBvY2NpZGVudGUgeSBzdXIgdGllbmVuIG1lbm9yIHZhcmlhYmlsaWRhZCwgc3VzIG1lZGlhbmFzIHNvbiBzaW1pbGFyZXMgYSBsYXMgZGVsIGNlbnRyby4KCiMjIyBCb3hwbG90IHBhcmEgbGEgdmFyaWFibGUgVW5lbXBsb3ltZW50CmBgYHtyfQpib3hwbG90KHBhbmVsX2RhdGFzZXQkdW5lbXBsb3ltZW50IH4gcGFuZWxfZGF0YXNldCRyZWdpb25fYSwKICAgICAgICB4bGFiID0gIlJlZ2nDs24iLAogICAgICAgIHlsYWIgPSAiRGVzZW1wbGVvIiwKICAgICAgICBtYWluID0gIkJveHBsb3QgZGUgZGVzZW1wbGVvIHBvciByZWdpw7NuIiwKICAgICAgICBjb2wgPSBjb2xvcmVzKQpgYGAKCkxvcyBib3hwbG90cyBwYXJhIGxhIHZhcmlhYmxlIGRlIGRlc2VtcGxlbyBtdWVzdHJhbiBxdWUgZWwgbm9ydGUgdGllbmUgbGEgbWF5b3IgdmFyaWFiaWxpZGFkIGVuIGxhcyB0YXNhcyBkZSBkZXNlbXBsZW8sIHNlZ3VpZG8gcG9yIGVsIG9jY2lkZW50ZSB5IGVsIHN1ciBjb24gdmFyaWFiaWxpZGFkZXMgbW9kZXJhZGFzLiBBdW5xdWUgZWwgbm9ydGUgdGllbmUgdW5hIG1lZGlhbmEgc2ltaWxhciBhbCBjZW50cm8sIG11ZXN0cmEgbcOhcyB2YWxvcmVzIGV4dHJlbWFkYW1lbnRlIGFsdG9zLiBFbCBzdXIgdGllbmUgdW5hIG1heW9yIHByZXNlbmNpYSBkZSB2YWxvcmVzIGFsdG9zIGVuIGNvbXBhcmFjacOzbiBjb24gZWwgb2NjaWRlbnRlLiBFbiByZXN1bWVuLCBlbCBub3J0ZSB0aWVuZSB1bmEgdmFyaWFiaWxpZGFkIHNpZ25pZmljYXRpdmEgY29uIHZhbG9yZXMgZXh0cmVtb3MsIG1pZW50cmFzIHF1ZSBlbCBzdXIgZGVzdGFjYSBwb3IgdmFsb3JlcyBhbHRvcywgYSBwZXNhciBkZSB1bmEgdmFyaWFiaWxpZGFkIG1vZGVyYWRhLgoKIyMjIEJveHBsb3QgcGFyYSBsYSB2YXJpYWJsZSBDcmltZSBSYXRlCmBgYHtyfQpib3hwbG90KHBhbmVsX2RhdGFzZXQkY3JpbWVfcmF0ZSB+IHBhbmVsX2RhdGFzZXQkcmVnaW9uX2EsCiAgICAgICAgeGxhYiA9ICJSZWdpw7NuIiwKICAgICAgICB5bGFiID0gIkNyaW1lbiIsCiAgICAgICAgbWFpbiA9ICJCb3hwbG90IGRlIENyaW1lbiBwb3IgcmVnacOzbiIsCiAgICAgICAgY29sID0gY29sb3JlcykKYGBgCgpMb3MgYm94cGxvdHMgbXVlc3RyYW4gZGlmZXJlbmNpYXMgZW4gbGFzIHRhc2FzIGRlIGNyaW1lbiBlbnRyZSBsYXMgcmVnaW9uZXMgZGUgTcOpeGljby4gRWwgZGVsIG5vcnRlIHRpZW5lIGxhIG1heW9yIHZhcmlhYmlsaWRhZCB5IHByZXNlbmNpYSBkZSB2YWxvcmVzIGFsdG9zLCBtaWVudHJhcyBxdWUgZWwgZGVsIGNlbnRybyBlcyBlbCBtw6FzIHBlcXVlw7FvLCBpbmRpY2FuZG8gbWVub3IgdmFyaWFiaWxpZGFkLiBBdW5xdWUgZWwgZGVsIG5vcnRlIGVzIGdyYW5kZSwgc3UgbWVkaWFuYSBlcyBzaW1pbGFyIGFsIG9jY2lkZW50ZSwgbWllbnRyYXMgcXVlIGxhIGRlbCBCYWrDrW8gZXMgbGEgbcOhcyBiYWphLCBzdWdpcmllbmRvIHRhc2FzIGRlIGNyaW1lbiBtw6FzIGJhamFzIGVuIHByb21lZGlvLgoKCiMjIyBCb3hwbG90IHBhcmEgbGEgdmFyaWFibGUgUG9wdWxhdGlvbiBEZW5zaXR5CmBgYHtyfQpib3hwbG90KHBhbmVsX2RhdGFzZXQkcG9wX2RlbnNpdHkgfiBwYW5lbF9kYXRhc2V0JHJlZ2lvbl9hLAogICAgICAgIHhsYWIgPSAiUmVnacOzbiIsCiAgICAgICAgeWxhYiA9ICJQb2JsYWNpb24iLAogICAgICAgIG1haW4gPSAiQm94cGxvdCBkZSBwb2JsYWNpw7NuIHBvciByZWdpw7NuIiwKICAgICAgICBjb2wgPSBjb2xvcmVzKQpgYGAKCkVsIGJveHBsb3QgZGUgbGEgcmVnacOzbiBkZWwgY2VudHJvIGRlIE3DqXhpY28gZXMgZWwgbcOhcyBncmFuZGUsIGxvIHF1ZSBpbmRpY2EgdW5hIG1heW9yIHZhcmlhYmlsaWRhZCBlbiBsYSBwb2JsYWNpw7NuIGRlbnRybyBkZSBlc3RhIHJlZ2nDs24gZW4gY29tcGFyYWNpw7NuIGNvbiBvdHJhcy4gTGEgcHJlc2VuY2lhIGRlIG91dGxpZXJzIG11eSBhbHRvcyBlbiBlbCBjZW50cm8gY29udHJpYnV5ZSBhIGhhY2VyIHF1ZSBsb3MgYm94cGxvdHMgZGUgdG9kYXMgbGFzIGRlbcOhcyByZWdpb25lcyBwYXJlemNhbiBtw6FzIHBlcXVlw7FvcyBlbiBjb21wYXJhY2nDs24uIEEgcGVzYXIgZGUgcXVlIGVsIGJveHBsb3QgZGVsIGNlbnRybyBlcyBlbCBtw6FzIGdyYW5kZSwgZWwgYm94cGxvdCBkZWwgQmFqw61vIGVzdMOhIGHDum4gbcOhcyBncmFuZGUgcXVlIGVsIGRlbCBub3J0ZSwgb2NjaWRlbnRlIHkgc3VyLiBFc3RvIGluZGljYSB1bmEgbWF5b3IgdmFyaWFiaWxpZGFkIGVuIGxhIHBvYmxhY2nDs24gZGVudHJvIGRlbCBCYWrDrW8gZW4gY29tcGFyYWNpw7NuIGNvbiBlbCBjZW50cm8sIGxvIHF1ZSBwdWVkZSBkZWJlcnNlIGEgZmFjdG9yZXMgY29tbyBlbCBjcmVjaW1pZW50byBlY29uw7NtaWNvIHkgbGEgdXJiYW5pemFjacOzbiBlbiBsYSByZWdpw7NuLgoKCiMjIyBCb3hwbG90IHBhcmEgbGEgdmFyaWFibGUgQ29sbGVnZSBFZHVjYXRpb24KYGBge3J9CmJveHBsb3QocGFuZWxfZGF0YXNldCRjb2xsZWdlX2VkdWNhdGlvbiB+IHBhbmVsX2RhdGFzZXQkcmVnaW9uX2EsCiAgICAgICAgeGxhYiA9ICJSZWdpw7NuIiwKICAgICAgICB5bGFiID0gIkVkdWNhY2nDs24iLAogICAgICAgIG1haW4gPSAiQm94cGxvdCBkZSBlZHVjYWNpw7NuIHBvciByZWdpw7NuIiwKICAgICAgICBjb2wgPSBjb2xvcmVzKQpgYGAKCkRlbnRybyBkZSBlc3RvcyBib3hscGxvdHMgZGUgbGEgdmFyaWFibGUgZWR1Y2FjacOzbiwgc2UgcHVlZGUgb2JzZXJ2YXIgcXVlIGxhIHJlZ2nDs24gZGVsIG5vcnRlIHRpZW5lIHVuYSBtZW5vciB2YXJpYWJpbGlkYWQgZW4gbG9zIG5pdmVsZXMgZGUgZWR1Y2FjacOzbi4gTGEgbMOtbmVhIGRlbCBwcmltZXIgY3VhcnRpbCBlbiBlbCBib3hwbG90IGRlbCBub3J0ZSBlcyBtw6FzIGNvcnRhIHF1ZSB0b2RhcyBsYXMgZGVtw6FzLCBsbyBxdWUgc3VnaWVyZSBxdWUgbGEgZGlzcGVyc2nDs24gZGUgbG9zIGRhdG9zIGVuIGxhIHBhcnRlIGluZmVyaW9yIGRlbCByYW5nbyBlcyBtZW5vciBlbiBjb21wYXJhY2nDs24gY29uIGxhcyBvdHJhcyByZWdpb25lcy4gTGEgbWVkaWEgZGUgdG9kb3MgbG9zIGJveHBsb3RzIGVzIHJlbGF0aXZhbWVudGUgc2ltaWxhciwgcGVybyBsYSBkZWwgb2NjaWRlbnRlIGVzIGxhIG3DoXMgYWx0YSB5IGxhIGRlbCBzdXIgZXMgbGEgbcOhcyBiYWphLiBFc3RvIHN1Z2llcmUgcXVlLCBlbiBwcm9tZWRpbywgZWwgbml2ZWwgZGUgZWR1Y2FjacOzbiB0aWVuZGUgYSBzZXIgbcOhcyBhbHRvIGVuIGVsIG9jY2lkZW50ZSB5IG3DoXMgYmFqbyBlbiBlbCBzdXIsIGVuIGNvbXBhcmFjacOzbiBjb24gbGFzIG90cmFzIHJlZ2lvbmVzLgoKIyMjIFNjYXR0ZXIgcGxvdCBjb24gbMOtbmVhIGRlIHRlbmRlbmNpYQpgYGB7cn0KcGxvdChwYW5lbF9kYXRhc2V0JGNyaW1lX3JhdGUsIHBhbmVsX2RhdGFzZXQkbmV3X2ZkaV9yZWFsX214biwKICAgICB4bGFiID0gIkNyaW1lbiIsCiAgICAgeWxhYiA9ICJGREkiLAogICAgIG1haW4gPSAiUmVsYWNpw7NuIGVudHJlIGNyaW1lbiB5IEZESSIpCmFibGluZShsbShwYW5lbF9kYXRhc2V0JG5ld19mZGlfcmVhbF9teG4gfiBwYW5lbF9kYXRhc2V0JGNyaW1lX3JhdGUpLCBjb2wgPSAicmVkIikKYGBgCgpFbCBhbsOhbGlzaXMgbXVlc3RyYSBxdWUgw6FyZWFzIGNvbiBiYWpvcyBuaXZlbGVzIGRlIGNyaW1lbiB0aWVuZGVuIGEgdGVuZXIgbWVub3IgaW52ZXJzacOzbiBkaXJlY3RhIChGREkpLiBBdW5xdWUgbGEgcmVsYWNpw7NuIGVzIHJlbGF0aXZhbWVudGUgY29uc3RhbnRlLCBoYXkgdW4gbGlnZXJvIGRlY2xpdmUgZW4gZWwgRkRJIGN1YW5kbyBhdW1lbnRhIGVsIGNyaW1lbiwgc3VnaXJpZW5kbyB1bmEgcG9zaWJsZSByZWxhY2nDs24gbmVnYXRpdmEgZMOpYmlsIGVudHJlIGVzdGFzIHZhcmlhYmxlcy4gRXN0byBwb2Ryw61hIGluZGljYXIgcXVlIGxhcyBlbXByZXNhcyBldml0YW4gaW52ZXJ0aXIgZW4gw6FyZWFzIGNvbiBhbHRhIGNyaW1pbmFsaWRhZCBkZWJpZG8gYSBwcmVvY3VwYWNpb25lcyBkZSBzZWd1cmlkYWQuIFNlIG5lY2VzaXRhbiBhbsOhbGlzaXMgYWRpY2lvbmFsZXMgcGFyYSBjb21wcmVuZGVyIGNvbXBsZXRhbWVudGUgZXN0YSByZWxhY2nDs24uIFNpbiBlbWJhcmdvLCBlcyBpbXBvcnRhbnRlIHRlbmVyIGVuIGN1ZW50YSBvdHJvcyBmYWN0b3JlcyB5IHJlYWxpemFyIHVuIGFuw6FsaXNpcyBtw6FzIGRldGFsbGFkbyBwYXJhIGNvbXByZW5kZXIgY29tcGxldGFtZW50ZSBlc3RhIHJlbGFjacOzbiB5IHN1cyBpbXBsaWNhY2lvbmVzLgoKCiMgU2VjY2nDs24gQwpWaXN1YWxpemFyIGxhIGRpc3RyaWJ1Y2lvzIFuIGVzcGFjaWFsIGRlIGxhcyB2YXJpYWJsZXMgc2VsZWNjaW9uYWRhcyB1c2FuZG8gbWFwYXMuCgoKYGBge3J9CiNWYXJpYWJsZXMgc2VsZWNjaW9uYWRhcwpwYW5lbF9kYXRhc2V0MiA8LSBwYW5lbF9kYXRhc2V0WyxjKDEsMiwzLDksMjUsMjQsOCwxNCldCmBgYApTZSBjcmVvIHVuIG51ZXZvIGNvbmp1bnRvIGRlIGRhdG9zIGRvbmRlIHNlIHNlbGVjY2lvbmFyb24gw7puaWNhbWVudGUgbGFzIHZhcmlhYmxlcyBlc3BlY8OtZmljYXMgcXVlIHNlIHV0aWxpemFyw6FuIGVuIGVsIGFuw6FsaXNpcywgc2ltcGxpZmljYW5kbyBhc8OtIGVsIGNvbmp1bnRvIGRlIGRhdG9zIGEgc29sbyBsYXMgY29sdW1uYXMgcmVsZXZhbnRlcy4KCmBgYHtyIHdhcm5pbmc9RkFMU0V9CiMjIyBJbXBvcnRhciBzaGFwZWZpbGUgCgojIEVzdGFkb3MgZGUgTcOpeGljbyAoMzIpIApteF9zdGF0ZV9tYXAgPC0gc3RfcmVhZCgiL1VzZXJzL3JlZ2luYWVucmlxdWV6L0Rlc2t0b3AvZXNkYS9teF9tYXBzL214X3N0YXRlcy9tZXhsYXRsb25nLnNocCIpCm14X3N0YXRlX21hcCA8LSByZWFkX3NmKCIvVXNlcnMvcmVnaW5hZW5yaXF1ZXovRGVza3RvcC9lc2RhL214X21hcHMvbXhfc3RhdGVzL21leGxhdGxvbmcuc2hwIikKCiMgSnVudGFyIGRhdGFzZXRzCnN0YXRlX2dlb2RhdGEgPC0gZ2VvX2pvaW4obXhfc3RhdGVfbWFwLHBhbmVsX2RhdGFzZXQyLCdPQkpFQ1RJRCcsJ3N0YXRlX2lkJyxob3c9J2lubmVyJykKYGBgCgpgYGB7cn0KIyBTdWJzZXQgZXN0YWRvcyBwYXJhIGVsIGHDsW8gMjAxOQpkYXRvc19tYXBhXzIwMTkgPC0gc3Vic2V0KHN0YXRlX2dlb2RhdGEsIHllYXIgPT0gMjAxOSkKCiMgU3Vic2V0IGVzdGFkb3MgcGFyYSBlbCBhw7FvIDIwMjEKZGF0b3NfbWFwYV8yMDIxIDwtIHN1YnNldChzdGF0ZV9nZW9kYXRhLCB5ZWFyID09IDIwMjEpCmBgYAoKCiMjIyBNYXBlbyBkZSBEaXN0cmlidWNpw7NuIGVzcGFjaWFsIGRlbCBGREkgMjAxOQpgYGB7cn0KZGF0b3NfbWFwYV8yMDE5X2ZpbHRlcmVkIDwtIGRhdG9zX21hcGFfMjAxOSAlPiUKICBmaWx0ZXIoQURNSU5fTkFNRSAhPSAiRGlzdHJpdG8gRmVkZXJhbCIpCgpnZ3Bsb3QoKSArCiAgZ2VvbV9zZihkYXRhID0gZGF0b3NfbWFwYV8yMDE5X2ZpbHRlcmVkLCBhZXMoZmlsbCA9IG5ld19mZGlfcmVhbF9teG4pKSArCiAgc2NhbGVfZmlsbF92aXJpZGlzX2MoKSArCiAgbGFicyh0aXRsZSA9ICJEaXN0cmlidWNpw7NuIEVzcGFjaWFsIGRlbCBGREkgZW4gMjAxOSIsCiAgICAgICBmaWxsID0gIlRhc2EgZGUgRkRJIikgKwogIHRoZW1lX21pbmltYWwoKQpgYGAKCkxhIENpdWRhZCBkZSBNw6l4aWNvIGRlc3RhY2EgY29tbyBlbCBwcmluY2lwYWwgcmVjZXB0b3IgZGUgSW52ZXJzacOzbiBFeHRyYW5qZXJhIERpcmVjdGEgKEZESSksIGxvIGN1YWwgZXMgY29oZXJlbnRlIGNvbiBzdSBwYXBlbCBjb21vIGNlbnRybyBmaW5hbmNpZXJvIHkgZWNvbsOzbWljbyBkZSBNw6l4aWNvLiBEYWRvIHN1IGRvbWluaW8gZW4gZWwgcGFub3JhbWEgZGUgbGEgaW52ZXJzacOzbiwgc2Ugb3B0w7MgcG9yIGZpbHRyYXIgYSBsYSBDaXVkYWQgZGUgTcOpeGljbyBmdWVyYSBkZWwgbWFwYSBwYXJhIHBlcm1pdGlyIHVuYSBtZWpvciB2aXN1YWxpemFjacOzbiBkZSBsb3Mgb3Ryb3MgZXN0YWRvcyBkZWwgcGHDrXMuCgpOdWV2byBMZcOzbiB5IGVsIEVzdGFkbyBkZSBNw6l4aWNvIG9jdXBhbiBsb3Mgc2lndWllbnRlcyBsdWdhcmVzIGVuIHTDqXJtaW5vcyBkZSBGREksIHNpZW5kbyBjZW50cm9zIGVjb27Ds21pY29zIGltcG9ydGFudGVzIGNvbiBpbmZyYWVzdHJ1Y3R1cmEgaW5kdXN0cmlhbCBzaWduaWZpY2F0aXZhLCBhdHJhY3Rpdm9zIHBhcmEgaW52ZXJzaW9uZXMgZW4gc2VjdG9yZXMgY29tbyBsYSBtYW51ZmFjdHVyYSB5IGxhIHRlY25vbG9nw61hLiBPdHJvcyBlc3RhZG9zIGRlc3RhY2Fkb3Mgc29uIFZlcmFjcnV6LCBRdWVyw6l0YXJvLCBKYWxpc2NvLCBHdWFuYWp1YXRvIHkgQ29haHVpbGEsIGF0cmlidXllbmRvIHN1IGF0cmFjdGl2byBhIGZhY3RvcmVzIGNvbW8gdWJpY2FjacOzbiBlc3RyYXTDqWdpY2EgeSBtYW5vIGRlIG9icmEgY2FsaWZpY2FkYS4gRXN0b3MgaGFsbGF6Z29zIGluZGljYW4gbGEgaW1wb3J0YW5jaWEgZGUgY2llcnRvcyBlc3RhZG9zIHBhcmEgbGEgaW52ZXJzacOzbiBleHRyYW5qZXJhLCBjb24gaW1wbGljYWNpb25lcyBjbGF2ZSBwYXJhIGVsIGNyZWNpbWllbnRvIGVjb27Ds21pY28geSBlbCBkZXNhcnJvbGxvIHJlZ2lvbmFsIGVuIE3DqXhpY28uCgoKIyMjIE1hcGVvIGRlIGRpc3RyaWJ1Y2nDs24gZXNwYWNpYWwgZGVsIEZESSAyMDIxCmBgYHtyfQpkYXRvc19tYXBhXzIwMjFfZmlsdGVyZWQgPC0gZGF0b3NfbWFwYV8yMDIxICU+JQogIGZpbHRlcihBRE1JTl9OQU1FICE9ICJEaXN0cml0byBGZWRlcmFsIikKCmdncGxvdCgpICsKICBnZW9tX3NmKGRhdGEgPSBkYXRvc19tYXBhXzIwMjFfZmlsdGVyZWQsIGFlcyhmaWxsID0gbmV3X2ZkaV9yZWFsX214bikpICsKICBzY2FsZV9maWxsX3ZpcmlkaXNfYygpICsKICBsYWJzKHRpdGxlID0gIkRpc3RyaWJ1Y2nDs24gRXNwYWNpYWwgZGVsIEZESSBlbiAyMDIxIiwKICAgICAgIGZpbGwgPSAiIFRhc2EgZGUgRkRJIikgKwogIHRoZW1lX21pbmltYWwoKQpgYGAKRW4gMjAyMSwgbGEgQ2l1ZGFkIGRlIE3DqXhpY28gbWFudHV2byBzdSBwb3NpY2nDs24gY29tbyBlbCBlc3RhZG8gY29uIGVsIG1heW9yIEZESSwgY29uc29saWRhbmRvIHN1IHBhcGVsIGNvbW8gY2VudHJvIGVjb27Ds21pY28geSBmaW5hbmNpZXJvIGRlbCBwYcOtcywgcG9yIGxvIHF1ZSBkZSBpZ3VhbCBmb3JtYSwgcGFyYSB1bmEgbWVqb3IgdmlzdWFsaXphY2nDs24gZGUgbG9zIGRlbcOhcyBlc3RhZG9zLCBzZSBlbGltaW7DsyBkZWwgbWFwYS4gCgpOdWV2byBMZcOzbiB5IEJhamEgQ2FsaWZvcm5pYSBOb3J0ZSB5IFN1ciBleHBlcmltZW50YXJvbiB1biBub3RhYmxlIGF1bWVudG8gZW4gZWwgRkRJIGVuIGNvbXBhcmFjacOzbiBjb24gMjAxOSwgcG9zaWJsZW1lbnRlIGRlYmlkbyBhIHBvbMOtdGljYXMgZ3ViZXJuYW1lbnRhbGVzIGZhdm9yYWJsZXMgeSB1bmEgaW5mcmFlc3RydWN0dXJhIGRlc2Fycm9sbGFkYS4gTWljaG9hY8OhbiwgVmVyYWNydXogeSBUYW1hdWxpcGFzIHRhbWJpw6luIHJlZ2lzdHJhcm9uIGluY3JlbWVudG9zIHNpZ25pZmljYXRpdm9zIGVuIGVsIEZESSBlbiAyMDIxLiBNaWVudHJhcyB0YW50bywgZWwgRXN0YWRvIGRlIE3DqXhpY28gZXhwZXJpbWVudMOzIHVuIGRlc2NlbnNvIGVuIGVsIEZESSB5IHlhIG5vIGZpZ3VyYSBlbnRyZSBsb3MgZXN0YWRvcyBjb24gbWF5b3JlcyBuaXZlbGVzIGRlIGludmVyc2nDs24gZXh0cmFuamVyYSBkaXJlY3RhLgoKCiMjIyBNYXBlbyBkZSBkaXN0cmlidWNpw7NuIGVzcGFjaWFsIGRlbCBkZXNlbXBsZW8gMjAxOQpgYGB7cn0KZ2dwbG90KCkgKwogIGdlb21fc2YoZGF0YSA9IGRhdG9zX21hcGFfMjAxOSwgYWVzKGZpbGwgPSB1bmVtcGxveW1lbnQpKSArCiAgc2NhbGVfZmlsbF92aXJpZGlzX2MoKSArCiAgbGFicyh0aXRsZSA9ICJEaXN0cmlidWNpw7NuIEVzcGFjaWFsIGRlbCBEZXNlbXBsZW8gZW4gMjAxOSIsCiAgICAgICBmaWxsID0gIsONbmRpY2UgZGUgRGVzZW1wbGVvIikgKwogIHRoZW1lX21pbmltYWwoKQpgYGAKCkVuIDIwMTksIFRhYmFzY28gdHV2byBlbCBtYXlvciBkZXNlbXBsZW8sIGxvIGN1YWwgcHVlZGUgZXN0YXIgcmVsYWNpb25hZG8gY29uIHN1IGRlcGVuZGVuY2lhIGVuIGxhIGluZHVzdHJpYSBwZXRyb2xlcmEsIG1pZW50cmFzIHF1ZSBCYWphIENhbGlmb3JuaWEgTm9ydGUgeSBHdWVycmVybyBtb3N0cmFyb24gbG9zIG5pdmVsZXMgbcOhcyBiYWpvcywgcG9zaWJsZW1lbnRlIHBvciBzdSBkaXZlcnNpZmljYWNpw7NuIGVjb27Ds21pY2EgeSBkZXNhcnJvbGxvIHR1csOtc3RpY28uIE90cm9zIGVzdGFkb3MgY29tbyBDaGlhcGFzLCBWZXJhY3J1eiwgQ29haHVpbGEsIEhpZGFsZ28sIEd1YW5hanVhdG8sIENvbGltYSB5IE1pY2hvYWPDoW4gZW5mcmVudGFyb24gZGVzYWbDrW9zIGNvbiDDrW5kaWNlcyBkZSBkZXNlbXBsZW8gbcOhcyBhbHRvcywgc2XDsWFsYW5kbyBsYSBuZWNlc2lkYWQgZGUgcG9sw610aWNhcyBlc3BlY8OtZmljYXMgcGFyYSBhYm9yZGFyIGxhcyBjYXVzYXMgc3VieWFjZW50ZXMgZW4gZGlmZXJlbnRlcyByZWdpb25lcy4KCgojIyMgTWFwZW8gZGUgZGlzdHJpYnVjacOzbiBlc3BhY2lhbCBkZWwgZGVzZW1wbGVvIDIwMjEKYGBge3J9CmdncGxvdCgpICsKICBnZW9tX3NmKGRhdGEgPSBkYXRvc19tYXBhXzIwMjEsIGFlcyhmaWxsID0gdW5lbXBsb3ltZW50KSkgKwogIHNjYWxlX2ZpbGxfdmlyaWRpc19jKCkgKwogIGxhYnModGl0bGUgPSAiRGlzdHJpYnVjacOzbiBFc3BhY2lhbCBkZWwgRGVzZW1wbGVvIGVuIDIwMjEiLAogICAgICAgZmlsbCA9ICLDjW5kaWNlIGRlIERlc2VtcGxlbyIpICsKICB0aGVtZV9taW5pbWFsKCkKYGBgCgpFbiAyMDIxLCBzZSByZWdpc3RyYSB1biBhdW1lbnRvIGdlbmVyYWxpemFkbyBlbiBsYSBtYXlvcsOtYSBkZSBsb3MgZXN0YWRvcyByZXNwZWN0byBhIDIwMTksIG1lbm9zIGFxdWVsbG9zIHF1ZSBtYW50ZW5pYW4gbGFzIHRhc2FzIG3DoXMgYmFqYXMsIGRvbmRlIHNlIG9ic2VydmEgdW5hIHJlbGF0aXZhIGVzdGFiaWxpZGFkIGVuIGVsIMOtbmRpY2UgZGUgZGVzZW1wbGVvLiBTZSBkZXN0YWNhIHVuIGluY3JlbWVudG8gc2lnbmlmaWNhdGl2byBlbiBEdXJhbmdvLCBRdWVyw6l0YXJvLCBFc3RhZG8gZGUgTcOpeGljbyB5IFB1ZWJsYSwgcG9zaWJsZW1lbnRlIGRlYmlkbyBhIGxhIGRlc2FjZWxlcmFjacOzbiBlY29uw7NtaWNhIHkgbG9zIGVmZWN0b3MgZGUgbGEgcGFuZGVtaWEgZGUgQ09WSUQtMTkuIEVzdG9zIGhhbGxhemdvcyBpbmRpY2FuIHVuIHBhbm9yYW1hIGxhYm9yYWwgbcOhcyBkZXNhZmlhbnRlIGVuIE3DqXhpY28gZW4gMjAyMSwgZGVzdGFjYW5kbyBsYSBuZWNlc2lkYWQgZGUgcG9sw610aWNhcyBlZmVjdGl2YXMgcGFyYSBwcm9tb3ZlciBsYSBjcmVhY2nDs24gZGUgZW1wbGVvIHkgbGEgcmVjdXBlcmFjacOzbiBlY29uw7NtaWNhIHBvc3QtcGFuZGVtaWEuCgojIyMgTWFwZW8gZGUgZGlzdHJpYnVjacOzbiBlc3BhY2lhbCBkZSBsYSBlZHVjYWNpb24gMjAxOQpgYGB7cn0KZ2dwbG90KCkgKwogIGdlb21fc2YoZGF0YSA9IGRhdG9zX21hcGFfMjAxOSwgYWVzKGZpbGwgPSBjb2xsZWdlX2VkdWNhdGlvbikpICsKICBzY2FsZV9maWxsX3ZpcmlkaXNfYygpICsKICBsYWJzKHRpdGxlID0gIkRpc3RyaWJ1Y2nDs24gRXNwYWNpYWwgZGUgbGEgRWR1Y2FjacOzbiBVbml2ZXJzaXRhcmlhIGVuIDIwMTkiLAogICAgICAgZmlsbCA9ICLDjW5kaWNlIGRlIEVkdWNhY2lvbiIpICsKICB0aGVtZV9taW5pbWFsKCkKYGBgCgpFbiAyMDE5LCBCYWphIENhbGlmb3JuaWEgU3VyLCBTaW5hbG9hIHkgQ2l1ZGFkIGRlIE3DqXhpY28gY3VlbnRhbiBjb24gbG9zIMOtbmRpY2VzIG3DoXMgYWx0b3MgZGUgZWR1Y2FjacOzbiB1bml2ZXJzaXRhcmlhLCBsbyBxdWUgc3VnaWVyZSB1bmEgbWF5b3IgcHJvcG9yY2nDs24gZGUgcG9ibGFjacOzbiBjb24gbml2ZWxlcyBlZHVjYXRpdm9zIHN1cGVyaW9yZXMsIHBvc2libGVtZW50ZSBkZWJpZG8gYSBtZWpvcmVzIG9wb3J0dW5pZGFkZXMgZGUgYWNjZXNvIHkgbWF5b3IgaW52ZXJzacOzbiBlbiBlZHVjYWNpw7NuLiBFbiBjb250cmFzdGUsIE9heGFjYSwgTnVldm8gTGXDs24sIE1pY2hvYWPDoW4geSBHdWFuYWp1YXRvIG1vc3RyYXJvbiBsb3Mgw61uZGljZXMgbcOhcyBiYWpvcywgaW5kaWNhbmRvIHVuYSBtZW5vciBwcm9wb3JjacOzbiBkZSBwb2JsYWNpw7NuIGNvbiBuaXZlbGVzIGVkdWNhdGl2b3MgbcOhcyBhbHRvcywgcG9zaWJsZW1lbnRlIGRlYmlkbyBhIGJhcnJlcmFzIHNvY2lvZWNvbsOzbWljYXMsIGN1bHR1cmFsZXMgbyBkZSBhY2Nlc28gYSBsYSBlZHVjYWNpw7NuIHVuaXZlcnNpdGFyaWEuCgojIyMgTWFwZW8gZGUgZGlzdHJpYnVjacOzbiBlc3BhY2lhbCBkZSBsYSBlZHVjYWNpw7NuIDIwMjEKYGBge3J9CmdncGxvdCgpICsKICBnZW9tX3NmKGRhdGEgPSBkYXRvc19tYXBhXzIwMjEsIGFlcyhmaWxsID0gY29sbGVnZV9lZHVjYXRpb24pKSArCiAgc2NhbGVfZmlsbF92aXJpZGlzX2MoKSArCiAgbGFicyh0aXRsZSA9ICJEaXN0cmlidWNpw7NuIEVzcGFjaWFsIGRlIGxhIEVkdWNhY2nDs24gVW5pdmVyc2l0YXJpYSBlbiAyMDIxIiwKICAgICAgIGZpbGwgPSAiw41uZGljZSBkZSBFZHVjYWNpw7NuIikgKwogIHRoZW1lX21pbmltYWwoKQpgYGAKCkVuIGVsIGHDsW8gMjAyMSBzZSBvYnNlcnZhIHVuYSBkZWNsaW5hY2nDs24gZW4gZWwgw61uZGljZSBkZSBlZHVjYWNpw7NuIHVuaXZlcnNpdGFyaWEgZW4gU29ub3JhLCBDb2FodWlsYSB5IFRhbWF1bGlwYXMsIHBvc2libGVtZW50ZSBkZWJpZG8gYSBjYW1iaW9zIGVuIHBvbMOtdGljYXMgZWR1Y2F0aXZhcyBvIHNpdHVhY2nDs24gZWNvbsOzbWljYS4gRW4gY29udHJhc3RlLCBKYWxpc2NvIGV4cGVyaW1lbnTDsyB1biBhdW1lbnRvLCBwb3NpYmxlbWVudGUgcG9yIGluaWNpYXRpdmFzIGV4aXRvc2FzIGVuIGVkdWNhY2nDs24uIExhIENpdWRhZCBkZSBNw6l4aWNvIHNpZ3VlIHRlbmllbmRvIGxhIHRhc2EgbcOhcyBhbHRhLCBtaWVudHJhcyBxdWUgT2F4YWNhIG1hbnRpZW5lIGxhIG3DoXMgYmFqYSwgcmVmbGVqYW5kbyBkaXNwYXJpZGFkZXMgZW4gbG9zIHNpc3RlbWFzIGVkdWNhdGl2b3MgeSBkZXNhZsOtb3Mgc29jaW9lY29uw7NtaWNvcyBlbiBNw6l4aWNvLgoKIyMjIE1hcGVvIGRlIGRpc3RyaWJ1Y2lvbiBlc3BhY2lhbCBkZWwgY3JpbWVuIDIwMTkKYGBge3J9CmdncGxvdCgpICsKICBnZW9tX3NmKGRhdGEgPSBkYXRvc19tYXBhXzIwMTksIGFlcyhmaWxsID0gY3JpbWVfcmF0ZSkpICsKICBzY2FsZV9maWxsX3ZpcmlkaXNfYygpICsKICBsYWJzKHRpdGxlID0gIkRpc3RyaWJ1Y2nDs24gRXNwYWNpYWwgZGVsIENyaW1lbiBlbiAyMDE5IiwKICAgICAgIGZpbGwgPSAiw41uZGljZSBkZSBDcmltZW4iKSArCiAgdGhlbWVfbWluaW1hbCgpCmBgYAoKQ29haHVpbGEsIER1cmFuZ28sIEJhamEgQ2FsaWZvcm5pYSBTdXIsIFl1Y2F0w6FuIHkgQWd1YXNjYWxpZW50ZXMgdGllbmVuIG5pdmVsZXMgbcOhcyBiYWpvcyBkZSBjcmltZW4sIHN1Z2lyaWVuZG8gdW5hIG1lbm9yIGluY2lkZW5jaWEgZGVsaWN0aXZhLCBwb3NpYmxlbWVudGUgZGViaWRvIGEgbGEgZWZlY3RpdmlkYWQgZGUgbGFzIGZ1ZXJ6YXMgZGUgc2VndXJpZGFkIHkgZXN0YWJpbGlkYWQgc29jaW9lY29uw7NtaWNhLiBFbiBjb250cmFzdGUsIENvbGltYSwgQ2hpaHVhaHVhIHkgQmFqYSBDYWxpZm9ybmlhIE5vcnRlIG11ZXN0cmFuIG5pdmVsZXMgbcOhcyBhbHRvcyBkZSBjcmltZW4sIHBvc2libGVtZW50ZSBkZWJpZG8gYSBsYSBwcmVzZW5jaWEgZGUgZ3J1cG9zIGRlbGljdGl2b3MgeSBwcm9ibGVtYXMgZGUgc2VndXJpZGFkIHDDumJsaWNhLiBFc3RvcyBoYWxsYXpnb3MgZGVzdGFjYW4gbGFzIGRpc3BhcmlkYWRlcyBlbiBsb3Mgbml2ZWxlcyBkZSBjcmltZW4gZW4gTcOpeGljbyB5IGxhIGltcG9ydGFuY2lhIGRlIGFib3JkYXIgc3VzIGNhdXNhcyBzdWJ5YWNlbnRlcyBtZWRpYW50ZSBwb2zDrXRpY2FzIGRlIHNlZ3VyaWRhZCBlZmVjdGl2YXMgeSBmb3J0YWxlY2ltaWVudG8gZGVsIHNpc3RlbWEgZGUganVzdGljaWEuCgojIyMgTWFwZW8gZGUgZGlzdHJpYnVjacOzbiBlc3BhY2lhbCBkZWwgY3JpbWVuIDIwMjEKYGBge3J9CmdncGxvdCgpICsKICBnZW9tX3NmKGRhdGEgPSBkYXRvc19tYXBhXzIwMjEsIGFlcyhmaWxsID0gY3JpbWVfcmF0ZSkpICsKICBzY2FsZV9maWxsX3ZpcmlkaXNfYygpICsKICBsYWJzKHRpdGxlID0gIkRpc3RyaWJ1Y2nDs24gRXNwYWNpYWwgZGVsIENyaW1lbiBlbiAyMDIxIiwKICAgICAgIGZpbGwgPSAiw41uZGljZSBkZSBDcmltZW4iKSArCiAgdGhlbWVfbWluaW1hbCgpCmBgYAoKSHVibyB1biBhdW1lbnRvIHNpZ25pZmljYXRpdm8gZW4gWmFjYXRlY2FzIHkgU29ub3JhIGVuIDIwMjEgZW4gY29tcGFyYWNpw7NuIGNvbiAyMDE5LCBwb3NpYmxlbWVudGUgZGViaWRvIGEgY29uZmxpY3RvcyBlbnRyZSBncnVwb3MgZGVsaWN0aXZvcyBvIHByb2JsZW1hcyBkZSBzZWd1cmlkYWQgcMO6YmxpY2EuIEVuIGNvbnRyYXN0ZSwgQ29saW1hIGV4cGVyaW1lbnTDsyB1bmEgZGlzbWludWNpw7NuIGVuIGVsIGNyaW1lbiBlbiAyMDIxLiBMYSBtYXlvcsOtYSBkZSBsb3MgZXN0YWRvcyBtb3N0cmFyb24gdW5hIHRlbmRlbmNpYSBnZW5lcmFsIGEgbGEgYmFqYSBlbiBsb3Mgbml2ZWxlcyBkZSBjcmltZW4gZW50cmUgMjAxOSB5IDIwMjEsIGV4Y2VwdG8gWmFjYXRlY2FzIHkgU29ub3JhLiBFc3RvIHB1ZWRlIHNlciByZXN1bHRhZG8gZGUgZXNmdWVyem9zIGd1YmVybmFtZW50YWxlcyBwYXJhIG1lam9yYXIgbGEgc2VndXJpZGFkIHkgYWJvcmRhciBsYXMgY2F1c2FzIHN1YnlhY2VudGVzIGRlbCBjcmltZW4uCgojIyMgTWFwZW8gZGUgZGlzdHJpYnVjacOzbiBlc3BhY2lhbCBkZSBsYSBwb2JsYWNpw7NuIGVuIDIwMTkKYGBge3J9CmRhdG9zX21hcGFfMjAxOV9maWx0ZXJlZDIgPC0gZGF0b3NfbWFwYV8yMDE5ICU+JQogIGZpbHRlcihBRE1JTl9OQU1FICE9ICJEaXN0cml0byBGZWRlcmFsIiAmIEFETUlOX05BTUUgIT0gIk1leGljbyIpCgoKZ2dwbG90KCkgKwogIGdlb21fc2YoZGF0YSA9IGRhdG9zX21hcGFfMjAxOV9maWx0ZXJlZDIsIGFlcyhmaWxsID0gcG9wX2RlbnNpdHkpKSArCiAgc2NhbGVfZmlsbF92aXJpZGlzX2MoKSArCiAgbGFicyh0aXRsZSA9ICJEaXN0cmlidWNpw7NuIEVzcGFjaWFsIGRlIGxhIFBvYmxhY2nDs24gZW4gMjAxOSIsCiAgICAgICBmaWxsID0gIsONbmRpY2UgZGUgUG9ibGFjaW9uIikgKwogIHRoZW1lX21pbmltYWwoKQpgYGAKCkxhIENpdWRhZCBkZSBNw6l4aWNvIHNlIGRlc3RhY2EgY29tbyBlbCDDoXJlYSBjb24gbGEgbWF5b3IgY29uY2VudHJhY2nDs24gZGUgcG9ibGFjacOzbiBlbiBjb21wYXJhY2nDs24gY29uIG90cm9zIGVzdGFkb3MgZW4gZWwgMjAxOS4gRXN0byBlcyBjb25zaXN0ZW50ZSBjb24gc3UgZXN0YXR1cyBjb21vIGxhIGNpdWRhZCBtw6FzIGdyYW5kZSB5IGRlbnNhbWVudGUgcG9ibGFkYSBkZSBNw6l4aWNvLiBFbCBFc3RhZG8gZGUgTcOpeGljbywgcXVlIHJvZGVhIGxhIENpdWRhZCBkZSBNw6l4aWNvLCB0YW1iacOpbiBzZSBlbmN1ZW50cmEgbcOhcyBwb2JsYWRvIHF1ZSBlbCByZXN0byBkZWwgcGHDrXMsIHBvciBsbyBxdWUgZGViaWRvIGEgZXN0bywgc2UgZGVjaWRpw7MgZmlsdHJhciB0YW50byBhIGxhIENpdWRhZCBkZSBNw6l4aWNvIGNvbW8gYWwgZXN0YWRvIGRlIE3DqXhpY28gcGFyYSBwb2RlciB0ZW5lciB1bmEgdmlzdWFsaXphY2nDs24gbcOhcyBjbGFyYSBhY2VyY2EgZGUgbG9zIG90cm9zIGVzdGFkb3MgeSBzdSBwb2JsYWNpw7NuLgoKVW5hIHZleiBvYnNlcnZhbmRvIGVsIG1hcGEgc2luIGxhIENpdWRhZCBuaSBlbCBlc3RhZG8gZGUgTcOpeGljbywgc2UgcHVlZGUgdmlzdWFsaXphciBxdWUgbG9zIGVzdGFkb3MgZGVsIGNlbnRybyBjb250aW7DumFuIHNpZW5kbyBsb3MgbcOhcyBwb2JsYWRvcywgbWllbnRyYXMgcXVlIGxhIG1heW9yw61hIGRlIGxvcyBvdHJvcyBlc3RhZG9zIG11ZXN0cmFuIHVuYSBkaXN0cmlidWNpw7NuIG3DoXMgdW5pZm9ybWUgZGUgcG9ibGFjacOzbi4gRXN0byBzdWdpZXJlIHVuYSBkaXN0cmlidWNpw7NuIG3DoXMgZXF1aXRhdGl2YSBlbiBlc3RvcyBlc3RhZG9zLCBzaW4gY29uY2VudHJhY2lvbmVzIHRhbiBzaWduaWZpY2F0aXZhcyBjb21vIGVuIGxvcyBlc3RhZG9zIGNlcmNhbm9zIGEgbGEgQ2l1ZGFkIGRlIE3DqXhpY28uCgojIyMgTWFwZW8gZGUgZGlzdHJpYnVjaW9uIGVzcGFjaWFsIGRlIGxhIHBvYmxhY2nDs24gZW4gMjAyMQpgYGB7cn0KZGF0b3NfbWFwYV8yMDIxX2ZpbHRlcmVkMiA8LSBkYXRvc19tYXBhXzIwMjEgJT4lCiAgZmlsdGVyKEFETUlOX05BTUUgIT0gIkRpc3RyaXRvIEZlZGVyYWwiICYgQURNSU5fTkFNRSAhPSAiTWV4aWNvIikKCmdncGxvdCgpICsKICBnZW9tX3NmKGRhdGEgPSBkYXRvc19tYXBhXzIwMjFfZmlsdGVyZWQyLCBhZXMoZmlsbCA9IHBvcF9kZW5zaXR5KSkgKwogIHNjYWxlX2ZpbGxfdmlyaWRpc19jKCkgKwogIGxhYnModGl0bGUgPSAiRGlzdHJpYnVjacOzbiBFc3BhY2lhbCBkZSBsYSBQb2JsYWNpw7NuIGVuIDIwMjEiLAogICAgICAgZmlsbCA9ICLDjW5kaWNlIGRlIFBvYmxhY2nDs24iKSArCiAgdGhlbWVfbWluaW1hbCgpCmBgYAoKQWwgaWd1YWwgcXVlIGVuIDIwMTksIGxhIENpdWRhZCBkZSBNw6l4aWNvIGNvbnRpbsO6YSBkZXN0YWNhbmRvIGNvbW8gZWwgw6FyZWEgY29uIGxhIG1heW9yIGNvbmNlbnRyYWNpw7NuIGRlIHBvYmxhY2nDs24gZW4gY29tcGFyYWNpw7NuIGNvbiBvdHJvcyBlc3RhZG9zLCBzZWd1aWRvIHBvciBlbCBlc3RhZG8gZGUgTcOpeGljby4gRXN0byBzdWdpZXJlIHVuYSBwZXJzaXN0ZW5jaWEgZW4gZWwgZXN0YXR1cyBkZSBsYSBjYXBpdGFsIGNvbW8gZWwgcHJpbmNpcGFsIGNlbnRybyB1cmJhbm8geSBkZW1vZ3LDoWZpY28gZGVsIHBhw61zLgoKRW4gbGEgbWF5b3LDrWEgZGUgbG9zIG90cm9zIGVzdGFkb3MsIGxhIGRpc3RyaWJ1Y2nDs24gZGUgcG9ibGFjacOzbiBwZXJtYW5lY2UgcmVsYXRpdmFtZW50ZSB1bmlmb3JtZSwgY29tbyBzZSBldmlkZW5jaWEgZW4gZWwgbWFwYSBjb24gdG9ub3MgdW5pZm9ybWVzLiBFc3RvIHN1Z2llcmUgdW5hIGVzdGFiaWxpZGFkIGVuIGxhIGRpc3RyaWJ1Y2nDs24gcG9ibGFjaW9uYWwgZW4gZXN0b3MgZXN0YWRvcywgc2luIGNhbWJpb3Mgc2lnbmlmaWNhdGl2b3MgY29uIHJlc3BlY3RvIGEgMjAxOS4KCgojIFNlY2Npw7NuIEQKRWxhYm9yYXIgeSB2aXN1YWxpemFyIDEg4oCTIDIgbWF0cmljZXMgZGUgY29uZWN0aXZpZGFkIHBhcmEgbG9zIGVzdGFkb3MgLyBtdW5pY2lwaW9zIGRlIE1lzIF4aWNvCgojIyMgRXN0YWRvcyBkZSBNw6l4aWNvIC0gRGlzdHJpYnV0aW9uIG9mIEZESSBJbmZsb3dzIDIwMTkKYGBge3J9CmZkaSA8LSB0bV9zaGFwZShkYXRvc19tYXBhXzIwMTkpICsgCiAgdG1fcG9seWdvbnMoY29sID0gIm5ld19mZGlfcmVhbF9teG4iLCBwYWxldHRlPSJCbHVlcyIsIHN0eWxlPSJxdWFudGlsZSIsIG49OCwgdGl0bGU9Ik1YTiBGREkgSW5mbG93cyAyMDE5IikgKwogIHRtX2xheW91dChtYWluLnRpdGxlPSAnTmV3IEZESSBJbmZsb3dzJywgIHRpdGxlLnBvc2l0aW9uID0gYygncmlnaHQnLCAndG9wJyksIGxlZ2VuZC5wb3NpdGlvbj0gYygibGVmdCIsICJib3R0b20iKSwgdGl0bGUuc2l6ZSA9IDEpCgp1bmVtcGxveW1lbnQgPC0gdG1fc2hhcGUoZGF0b3NfbWFwYV8yMDE5KSArIAogIHRtX3BvbHlnb25zKGNvbCA9ICJ1bmVtcGxveW1lbnQiLCBwYWxldHRlPSJCdUduIiwgc3R5bGU9InF1YW50aWxlIiwgbj04LCB0aXRsZT0iVW5lbXBsb3ltZW50IikgKwogIHRtX2xheW91dChtYWluLnRpdGxlPSAnVW5lbXBsb3ltZW50IDIwMTknLCAgdGl0bGUucG9zaXRpb24gPSBjKCdyaWdodCcsICd0b3AnKSwgbGVnZW5kLnBvc2l0aW9uPSBjKCJsZWZ0IiwgImJvdHRvbSIpLCB0aXRsZS5zaXplID0gMSkKCmNyaW1lIDwtIHRtX3NoYXBlKGRhdG9zX21hcGFfMjAxOSkgKyAKICB0bV9wb2x5Z29ucyhjb2wgPSAiY3JpbWVfcmF0ZSIsIHBhbGV0dGU9Ik9yUmQiLCBzdHlsZT0icXVhbnRpbGUiLCBuPTgsIHRpdGxlPSJDcmltZSBSYXRlIikgKwogIHRtX2xheW91dChtYWluLnRpdGxlPSAnQ3JpbWUgUmF0ZSAyMDE5JywgIHRpdGxlLnBvc2l0aW9uID0gYygncmlnaHQnLCAndG9wJyksIGxlZ2VuZC5wb3NpdGlvbj0gYygibGVmdCIsICJib3R0b20iKSwgdGl0bGUuc2l6ZSA9IDEpCgpwb3BfZGVuIDwtIHRtX3NoYXBlKGRhdG9zX21hcGFfMjAxOSkgKyAKICB0bV9wb2x5Z29ucyhjb2wgPSAicG9wX2RlbnNpdHkiLCBwYWxldHRlPSItdmlyaWRpcyIsIHN0eWxlPSJxdWFudGlsZSIsIG49OCwgdGl0bGU9IlBvcCBEZW5zaXR5IikgKwogIHRtX2xheW91dChtYWluLnRpdGxlPSAnUG9wdWxhdGlvbiBEZW5zaXR5IDIwMTknLCAgdGl0bGUucG9zaXRpb24gPSBjKCdyaWdodCcsICd0b3AnKSwgbGVnZW5kLnBvc2l0aW9uPSBjKCJsZWZ0IiwgImJvdHRvbSIpLCB0aXRsZS5zaXplID0gMSkKCmVkdWNhdGlvbiA8LSB0bV9zaGFwZShkYXRvc19tYXBhXzIwMTkpICsgCiAgdG1fcG9seWdvbnMoY29sID0gImNvbGxlZ2VfZWR1Y2F0aW9uIiwgcGFsZXR0ZT0iLXZpcmlkaXMiLCBzdHlsZT0icXVhbnRpbGUiLCBuPTgsIHRpdGxlPSJDb2xsZWdlIEVkdWNhdGlvbiIpICsKICB0bV9sYXlvdXQobWFpbi50aXRsZT0gJ0NvbGxlZ2UgRWR1Y2F0aW9uIDIwMTknLCAgdGl0bGUucG9zaXRpb24gPSBjKCdyaWdodCcsICd0b3AnKSwgbGVnZW5kLnBvc2l0aW9uPSBjKCJsZWZ0IiwgImJvdHRvbSIpLCB0aXRsZS5zaXplID0gMSkKCiMgUGFuZWwgZGUgbWFwYXMKdG1hcF9hcnJhbmdlKGZkaSwgdW5lbXBsb3ltZW50LCBlZHVjYXRpb24sIGNyaW1lLCBwb3BfZGVuLCBuY29sID0gMikKYGBgCgojIyMgRXN0YWRvcyBkZSBNw6l4aWNvIC0gRGlzdHJpYnV0aW9uIG9mIEZESSBJbmZsb3dzIDIwMjEKYGBge3J9CmZkaTIgPC0gdG1fc2hhcGUoZGF0b3NfbWFwYV8yMDIxKSArIAogIHRtX3BvbHlnb25zKGNvbCA9ICJuZXdfZmRpX3JlYWxfbXhuIiwgcGFsZXR0ZT0iQmx1ZXMiLCBzdHlsZT0icXVhbnRpbGUiLCBuPTgsIHRpdGxlPSJNWE4gRkRJIEluZmxvd3MgMjAyMSIpICsKICB0bV9sYXlvdXQobWFpbi50aXRsZT0gJ05ldyBGREkgSW5mbG93cycsICB0aXRsZS5wb3NpdGlvbiA9IGMoJ3JpZ2h0JywgJ3RvcCcpLCBsZWdlbmQucG9zaXRpb249IGMoImxlZnQiLCAiYm90dG9tIiksIHRpdGxlLnNpemUgPSAxKQoKdW5lbXBsb3ltZW50MiA8LSB0bV9zaGFwZShkYXRvc19tYXBhXzIwMjEpICsgCiAgdG1fcG9seWdvbnMoY29sID0gInVuZW1wbG95bWVudCIsIHBhbGV0dGU9IkJ1R24iLCBzdHlsZT0icXVhbnRpbGUiLCBuPTgsIHRpdGxlPSJVbmVtcGxveW1lbnQiKSArCiAgdG1fbGF5b3V0KG1haW4udGl0bGU9ICdVbmVtcGxveW1lbnQgMjAyMScsICB0aXRsZS5wb3NpdGlvbiA9IGMoJ3JpZ2h0JywgJ3RvcCcpLCBsZWdlbmQucG9zaXRpb249IGMoImxlZnQiLCAiYm90dG9tIiksIHRpdGxlLnNpemUgPSAxKQoKY3JpbWUyIDwtIHRtX3NoYXBlKGRhdG9zX21hcGFfMjAyMSkgKyAKICB0bV9wb2x5Z29ucyhjb2wgPSAiY3JpbWVfcmF0ZSIsIHBhbGV0dGU9Ik9yUmQiLCBzdHlsZT0icXVhbnRpbGUiLCBuPTgsIHRpdGxlPSJDcmltZSBSYXRlIikgKwogIHRtX2xheW91dChtYWluLnRpdGxlPSAnQ3JpbWUgUmF0ZSAyMDIxJywgIHRpdGxlLnBvc2l0aW9uID0gYygncmlnaHQnLCAndG9wJyksIGxlZ2VuZC5wb3NpdGlvbj0gYygibGVmdCIsICJib3R0b20iKSwgdGl0bGUuc2l6ZSA9IDEpCgpwb3BfZGVuMiA8LSB0bV9zaGFwZShkYXRvc19tYXBhXzIwMjEpICsgCiAgdG1fcG9seWdvbnMoY29sID0gInBvcF9kZW5zaXR5IiwgcGFsZXR0ZT0iLXZpcmlkaXMiLCBzdHlsZT0icXVhbnRpbGUiLCBuPTgsIHRpdGxlPSJQb3AgRGVuc2l0eSIpICsKICB0bV9sYXlvdXQobWFpbi50aXRsZT0gJ1BvcHVsYXRpb24gRGVuc2l0eSAyMDIxJywgIHRpdGxlLnBvc2l0aW9uID0gYygncmlnaHQnLCAndG9wJyksIGxlZ2VuZC5wb3NpdGlvbj0gYygibGVmdCIsICJib3R0b20iKSwgdGl0bGUuc2l6ZSA9IDEpCgplZHVjYXRpb24yIDwtIHRtX3NoYXBlKGRhdG9zX21hcGFfMjAyMSkgKyAKICB0bV9wb2x5Z29ucyhjb2wgPSAiY29sbGVnZV9lZHVjYXRpb24iLCBwYWxldHRlPSItdmlyaWRpcyIsIHN0eWxlPSJxdWFudGlsZSIsIG49OCwgdGl0bGU9IkNvbGxlZ2UgRWR1Y2F0aW9uIikgKwogIHRtX2xheW91dChtYWluLnRpdGxlPSAnQ29sbGVnZSBFZHVjYXRpb24gMjAyMScsICB0aXRsZS5wb3NpdGlvbiA9IGMoJ3JpZ2h0JywgJ3RvcCcpLCBsZWdlbmQucG9zaXRpb249IGMoImxlZnQiLCAiYm90dG9tIiksIHRpdGxlLnNpemUgPSAxKQoKIyBQYW5lbCBkZSBNYXBhcwp0bWFwX2FycmFuZ2UoZmRpMiwgdW5lbXBsb3ltZW50MiwgZWR1Y2F0aW9uMiwgY3JpbWUyLCBwb3BfZGVuMiwgbmNvbCA9IDIpCmBgYAoKIyMjIE1hdHJpeiBkZSBjb25lY3RpdmlkYWQgZGUgZXN0YWRvcyAyMDE5IChNw6l0b2RvICJST09LIikKYGBge3J9CiMgVXRpbGl6YXIgZWwgbcOpdG9kbyBkZSAiUk9PSyIgCnN3bV9yb29rXzIwMTkgIDwtIHBvbHkybmIoZGF0b3NfbWFwYV8yMDE5LCBxdWVlbj1GQUxTRSkKCiMgUmVzdW1lbiAKc3VtbWFyeShzd21fcm9va18yMDE5KSAKCiMgQ29udmVydGlyIG1hdHJpeiBhIGxpc3RhIGRlIHBlc29zCnNzd21fcm9va18yMDE5IDwtIG5iMmxpc3R3KHN3bV9yb29rXzIwMTksIHN0eWxlPSJXIiwgemVyby5wb2xpY3kgPSBUUlVFKQoKIyBDb252ZXJ0aXIgZWwgbWFwYSBkZSBlc3RhZG9zIGEgZm9ybWF0byBzcGF0aWFsCmRhdG9zX21hcGFfMjAxOV9hIDwtIGFzKGRhdG9zX21hcGFfMjAxOSwgIlNwYXRpYWwiKQpkYXRvc19tYXBhXzIwMTlfY2VudHJvaWQgPC0gY29vcmRpbmF0ZXMoZGF0b3NfbWFwYV8yMDE5X2EpIAoKIyBHcmFmaWNhciBsYSBtYXRyaXogZW4gZWwgbWFwYQpwbG90KGRhdG9zX21hcGFfMjAxOV9hLGJvcmRlcj0iYmx1ZSIsYXhlcz1GQUxTRSxsYXM9MSwgbWFpbj0iRXN0YWRvcyBkZSBNw6l4aWNvIDIwMTkgY29uIFJPT0sgU1dNIikKcGxvdChkYXRvc19tYXBhXzIwMTlfYSxjb2w9ImdyZXkiLGJvcmRlcj1ncmV5KDAuOSksYXhlcz1ULGFkZD1UKSAKcGxvdChzc3dtX3Jvb2tfMjAxOSxjb29yZHM9ZGF0b3NfbWFwYV8yMDE5X2NlbnRyb2lkLHBjaD0xOSxjZXg9MC4xLGNvbD0icmVkIixhZGQ9VCkgCmBgYAoKIyMjIE1hdHJpeiBkZSBjb25lY3RpdmlkYWQgZGUgZXN0YWRvcyAyMDIxIChNw6l0b2RvICJST09LIikKYGBge3J9CiMgVXRpbGl6YXIgZWwgbcOpdG9kbyBkZSAiUk9PSyIgCnN3bV9yb29rXzIwMjEgIDwtIHBvbHkybmIoZGF0b3NfbWFwYV8yMDIxLCBxdWVlbj1GQUxTRSkKCiMgUmVzdW1lbiAKc3VtbWFyeShzd21fcm9va18yMDIxKSAKCiMgQ29udmVydGlyIG1hdHJpeiBhIGxpc3RhIGRlIHBlc29zCnNzd21fcm9va18yMDIxIDwtIG5iMmxpc3R3KHN3bV9yb29rXzIwMjEsIHN0eWxlPSJXIiwgemVyby5wb2xpY3kgPSBUUlVFKQoKIyBDb252ZXJ0aXIgZWwgbWFwYSBkZSBlc3RhZG9zIGEgZm9ybWF0byBzcGF0aWFsCmRhdG9zX21hcGFfMjAyMV9hIDwtIGFzKGRhdG9zX21hcGFfMjAyMSwgIlNwYXRpYWwiKQpkYXRvc19tYXBhXzIwMjFfY2VudHJvaWQgPC0gY29vcmRpbmF0ZXMoZGF0b3NfbWFwYV8yMDIxX2EpIAoKIyBHcmFmaWNhciBsYSBtYXRyaXogZW4gZWwgbWFwYQpwbG90KGRhdG9zX21hcGFfMjAyMV9hLGJvcmRlcj0iYmx1ZSIsYXhlcz1GQUxTRSxsYXM9MSwgbWFpbj0iRXN0YWRvcyBkZSBNw6l4aWNvIDIwMjEgY29uIFJPT0sgU1dNIikKcGxvdChkYXRvc19tYXBhXzIwMjFfYSxjb2w9ImdyZXkiLGJvcmRlcj1ncmV5KDAuOSksYXhlcz1ULGFkZD1UKSAKcGxvdChzc3dtX3Jvb2tfMjAyMSxjb29yZHM9ZGF0b3NfbWFwYV8yMDIxX2NlbnRyb2lkLHBjaD0xOSxjZXg9MC4xLGNvbD0icmVkIixhZGQ9VCkgCmBgYAoKIyBTZWNjacOzbiBFCkRldGVjdGFyIGxhIHByZXNlbmNpYSBkZSBhdXRvY29ycmVsYWNpb8yBbiBlc3BhY2lhbCBnbG9iYWwgcGFyYSBjYWRhIHVuYSBkZSBsYXMgdmFyaWFibGVzIHNlbGVjY2lvbmFkYXMuCgpHbG9iYW4gTW9yYW4gSSBub3MgaW5kaWNhICBzaSBlbCB2YWxvciBvYnNlcnZhZG8gZGUgdW5hIHZhcmlhYmxlIGVuIHVuYSBsb2NhbGlkYWQgZXMgaW5kZXBlbmRpZW50ZSBkZSBsb3MgdmFsb3JlcyBkZSBsYSB2YXJpYWJsZSBlbiBsb2NhbGlkYWRlcyB2ZWNpbmFzLgoKIyMjIE1vcmFuIFRlc3QgVmFyaWFibGUgRkRJIFJvb2sgMjAxOQpgYGB7cn0KbW9yYW4udGVzdChkYXRvc19tYXBhXzIwMTkkbmV3X2ZkaV9yZWFsX214biwgc3N3bV9yb29rXzIwMTkpIApgYGAKCkVzIGVzdGFkw61zdGljYW1lbnRlIHNpZ25pZmljYXRpdmEgZGViaWRvIGEgcXVlIGVsIHAgdmFsdWUgZXMgbWVub3IgYWwgMC4wNSwKTW9yYW4gSSBzdGF0aXN0aWMgdGllbmUgdW4gcmVzdWx0YWRvIG1heW9yIGFsIDAuMDUsIGxvIHF1ZSBub3MgaW5kaWNhIHF1ZSBzw60gaGF5IHVuYSBhdXRvY29ycmVsYWNpw7NuIGVzcGFjaWFsIHBvc2l0aXZhLiAKCgojIyMgTW9yYW4gVGVzdCBWYXJpYWJsZSBGREkgUm9vayAyMDIxCmBgYHtyfQptb3Jhbi50ZXN0KGRhdG9zX21hcGFfMjAyMSRuZXdfZmRpX3JlYWxfbXhuLCBzc3dtX3Jvb2tfMjAyMSkgCmBgYAoKRWwgTW9yYW4gSSBzdGF0aXN0aWMgZXMgbWF5b3IgYWwgMC4wNSBsbyBjdWFsIGRpY2UgcXVlIHPDrSBoYXkgdW5hIGF1dG9jb3JyZWxhY2nDs24gZXNwYWNpYWwgcG9zaXRpdmEuIFNpbiBlbWJhcmdvLCBsYSBhdXRvY29ycmVsYWNpw7NuIG5vIGVzIGVzdGFkw61zdGljYW1lbnRlIHNpZ25pZmljYXRpdmEgeWEgcXVlIGVsIHAgdmFsdWUgZXMgbWF5b3IgYWwgMC4wNQoKIyMjIE1vcmFuIFRlc3QgVmFyaWFibGUgQ3JpbWUgUmF0ZSBSb29rIDIwMTkKYGBge3J9Cm1vcmFuLnRlc3QoZGF0b3NfbWFwYV8yMDE5JGNyaW1lX3JhdGUsIHNzd21fcm9va18yMDE5KSAKYGBgCgpFbCBwIHZhbHVlIGVzIG1heW9yIGFsIDAuMDUsIGVzdG8gbm9zIGluZGljYSBxdWUgbm8gZXMgZXN0YWTDrXN0aWNhbWVudGUgc2lnbmlmaWNhdGl2YS4gRWwgTW9yYW4gSSBzdGF0aXN0aWMgZXMgbWVub3IgYWwgMC4wNSBsbyBjdWFsIGluZGljYSBxdWUgbGEgYXV0b2NvcnJlbGFjacOzbiBlc3BhY2lhbCBlcyBuZWdhdGl2YS4gCgojIyMgTW9yYW4gVGVzdCBWYXJpYWJsZSBDcmltZSBSYXRlIFJvb2sgMjAyMQpgYGB7cn0KbW9yYW4udGVzdChkYXRvc19tYXBhXzIwMjEkY3JpbWVfcmF0ZSwgc3N3bV9yb29rXzIwMjEpIApgYGAKCkVsIHAgdmFsdWUgZXMgbWF5b3IgYWwgMC4wNSwgZXN0byBub3MgaW5kaWNhIHF1ZSBubyBlcyBlc3RhZMOtc3RpY2FtZW50ZSBzaWduaWZpY2F0aXZhLiBFbCBNb3JhbiBJIHN0YXRpc3RpYyBlcyBtZW5vciBhbCAwLjA1IGxvIGN1YWwgbm9zIGluZGljYSBxdWUgcXVlIGxhIGF1dG9jb3JyZWxhY2nDs24gZXNwYWNpYWwgZXMgbmVnYXRpdmEuIAoKIyMjIE1vcmFuIFRlc3QgVmFyaWFibGUgUG9wdWxhdGlvbiBEZW5zaXR5IFJvb2sgMjAxOQpgYGB7cn0KbW9yYW4udGVzdChkYXRvc19tYXBhXzIwMTkkcG9wX2RlbnNpdHksIHNzd21fcm9va18yMDE5KSAKYGBgCgpFbCBwIHZhbHVlIGVzIG1lbm9yIGFsIDAuMDUsIGxvIHF1ZSBub3MgZGljZSBxdWUgbGEgdmFyaWFibGUgc8OtIGVzIGVzdGFkw61zdGljYW1lbnRlIHNpZ25pZmljYXRpdmEsIHkgZWwgTW9yYW4gSSBzdGF0aXN0aWMgZXMgbWF5b3IgYWwgMC4wNSBpbmRpY2FuZG8gcXVlIHPDrSBoYXkgdW5hIGF1dG9jb3JyZWxhY2nDs24gZXNwYWNpYWwgcG9zaXRpdmEuClPDrSBwb2RlbW9zIHZlciB1biBwYXRyw7NuIGVzcGFjaWFsIGVuIGxhIHBvYmxhY2nDs24uCgojIyMgTW9yYW4gVGVzdCBWYXJpYWJsZSBQb3B1bGF0aW9uIERlbnNpdHkgUm9vayAyMDIxCmBgYHtyfQptb3Jhbi50ZXN0KGRhdG9zX21hcGFfMjAyMSRwb3BfZGVuc2l0eSwgc3N3bV9yb29rXzIwMjEpIApgYGAKCkVsIHAgdmFsdWUgZXMgbWVub3IgYWwgMC4wNSwgeSBlbCBtb3JhbiBJIHN0YXRpc3RpYyBlcyBtYXlvciBhbCAwLjA1LCBlc3RvIG5vcyBkaWNlIHF1ZSBsYSB2YXJpYWJsZSBlcyBlc3RhZMOtc3RpY2FtZW50ZSBzaWduaWZpY2F0aXZhIHkgY3VlbnRhIGNvbiB1bmEgYXV0b2NvcnJlbGFjacOzbiBlc3BhY2lhbCBwb3NpdGl2YS4gCkhheSB1biBwYXRyw7NuIGVzcGFjaWFsIGNvbiBsYSBwb2JsYWNpw7NuLgoKIyMjIE1vcmFuIFRlc3QgVmFyaWFibGUgVW5lbXBsb3ltZW50IFJvb2sgMjAxOQpgYGB7cn0KbW9yYW4udGVzdChkYXRvc19tYXBhXzIwMTkkdW5lbXBsb3ltZW50LCBzc3dtX3Jvb2tfMjAxOSkgCmBgYAoKRWwgcCB2YWx1ZSBlcyBtYXlvciBhbCAwLjA1IGxvIGN1YWwgbm9zIGRpY2UgcXVlIG5vIGVzIGVzdGFkw61zdGljYW1lbnRlIHNpZ25pZmljYXRpdmEsIGVsIG1vcmFuIEkgc3RhdGlzdGljIGVzIG1lbm9yIGFsIDAuMDUsIGVzdG8gbm9zIGluZGljYSBxdWUgbm8gaGF5IGF1dG9jb3JyZWxhY2nDs24gZXNwYWNpYWwgcG9zaXRpdmEuCk5vIGhheSB1biBwYXRyw7NuIGVzcGFjaWFsIGVuIGxhIHRhc2EgZGUgZGVzZW1wbGVvLgoKIyMjIE1vcmFuIFRlc3QgVmFyaWFibGUgVW5lbXBsb3ltZW50IFJvb2sgMjAyMQpgYGB7cn0KbW9yYW4udGVzdChkYXRvc19tYXBhXzIwMjEkdW5lbXBsb3ltZW50LCBzc3dtX3Jvb2tfMjAyMSkgCmBgYAoKRWwgcCB2YWx1ZSBlcyBtYXlvciBhbCAwLjA1LCBlc3RvIG5vcyBkaWNlIHF1ZSBubyBlcyBlc3RhZMOtc3RpY2FtZW50ZSBzaWduaWZpY2F0aXZhLiAKRWwgTW9yYW4gSSBzdGF0aXN0aWMgZXMgbWVub3IgYWwgMC4wNSBsbyBjdWFsIGluZGljYSBxdWUgbm8gaGF5IHVuYSBhdXRvY29ycmVsYWNpw7NuIGVzcGFjaWFsIHBvc2l0aXZhLiAKCiMjIyBNb3JhbiBUZXN0IFZhcmlhYmxlIENvbGxlZ2UgRWR1Y2F0aW9uIFJvb2sgMjAxOQpgYGB7cn0KbW9yYW4udGVzdChkYXRvc19tYXBhXzIwMTkkY29sbGVnZV9lZHVjYXRpb24sIHNzd21fcm9va18yMDE5KSAKYGBgCgpFbCBwIHZhbHVlIGVzIG1lbm9yIGFsIDAuMDUsIGVzdG8gbm9zIGluZGljYSBxdWUgc8OtIGVzIGVzdGFkw61zdGljYW1lbnRlIHNpZ25pZmljYXRpdmEuIEVsIE1vcmFuIEkgc3RhdGlzdGljIGVzIG1heW9yIGFsIDAuMDUgbG8gY3VhbCBpbmRpY2EgcXVlIHPDrSBoYXkgdW5hIGF1dG9jb3JyZWxhY2nDs24gZXNwYWNpYWwgcG9zaXRpdmEuIApIYXkgdW4gcGF0csOzbiBlc3BhY2lhbCBjb24gbG9zIG5pdmVsZXMgZGUgZWR1Y2FjacOzbiB1bml2ZXJzaXRhcmlhcy4KCiMjIyBNb3JhbiBUZXN0IFZhcmlhYmxlIENvbGxlZ2UgRWR1Y2F0aW9uIFJvb2sgMjAyMQpgYGB7cn0KbW9yYW4udGVzdChkYXRvc19tYXBhXzIwMjEkY29sbGVnZV9lZHVjYXRpb24sIHNzd21fcm9va18yMDIxKSAKYGBgCgpFbCBwIHZhbHVlIGVzIG1lbm9yIGFsIDAuMDUsIGVzdG8gbm9zIGluZGljYSBxdWUgc8OtIGVzIGVzdGFkw61zdGljYW1lbnRlIHNpZ25pZmljYXRpdmEuIEVsIE1vcmFuIEkgc3RhdGlzdGljIGVzIG1heW9yIGFsIDAuMDUgbG8gY3VhbCBpbmRpY2EgcXVlIHPDrSBleGlzdGUgdW5hIGF1dG9jb3JyZWxhY2nDs24gZXNwYWNpYWwgcG9zaXRpdmEuCkxhIGVkdWNhY2nDs24gdW5pdmVyc2l0YXJpYSBzZSBlbmN1ZW50cmEgZXN0YXIgZXNwYWNpYWxtZW50ZSBhZ3J1cGFkYS4KCgojIFNlY2Npw7NuIEYgeSBHCkRldGVjdGFyIGxhIHByZXNlbmNpYSBkZSBhdXRvY29ycmVsYWNpb8yBbiBlc3BhY2lhbCBsb2NhbCBwYXJhIGNhZGEgdW5hIGRlIGxhcyB2YXJpYWJsZXMgc2VsZWNjaW9uYWRhcy4KSWRlbnRpZmljYXIgbGEgcG9zaWJsZSBwcmVzZW5jaWEgZGUgY2x1zIFzdGVycyBsb2NhbGVzIC8gcmVnaW9uYWxlcyBwYXJhIGNhZGEgdW5hIGRlIGxhcyB2YXJpYWJsZXMgc2VsZWNjaW9uYWRhcy4KClBhcmEgZXN0YSBzaWd1aWVudGUgc2VjY2nDs24gc2UgdG9tYXJvbiBlbiBjdWVudGEgw7puaWNhbWVudGUgbGFzIHZhcmlhYmxlcyBwcmV2aWFtZW50ZSBpZGVudGlmaWNhZGFzIGNvbW8gcmVsZXZhbnRlcyB5IGNvbiBzaWduaWZpY2FuY2lhIGVzdGFkw61zdGljYSBwYXJhIGNhZGEgYcOxby4KCiMjIyBJZGVudGlmaWNhY2nDs24gZGUgQ2x1c3RlcnMgMjAxOSAKYGBge3J9CmRhdG9zX21hcGFfMjAxOSRzcF9sYWdfbmV3X2ZkaV9yZWFsX214biA8LSBsYWcubGlzdHcoc3N3bV9yb29rXzIwMTksIGRhdG9zX21hcGFfMjAxOSRuZXdfZmRpX3JlYWxfbXhuLCB6ZXJvLnBvbGljeT1UUlVFKSAKZGF0b3NfbWFwYV8yMDE5JHNwX2xhZ19jb2xsZWdlX2VkdWNhdGlvbiA8LSBsYWcubGlzdHcoc3N3bV9yb29rXzIwMTksIGRhdG9zX21hcGFfMjAxOSRjb2xsZWdlX2VkdWNhdGlvbiwgemVyby5wb2xpY3k9VFJVRSkgCmRhdG9zX21hcGFfMjAxOSRzcF9sYWdfcG9wX2RlbnNpdHkgPC0gbGFnLmxpc3R3KHNzd21fcm9va18yMDE5LCBkYXRvc19tYXBhXzIwMTkkcG9wX2RlbnNpdHksIHplcm8ucG9saWN5PVRSVUUpIAoKZmRpX2xhZyA8LSB0bV9zaGFwZShkYXRvc19tYXBhXzIwMTkpICsgCiAgdG1fcG9seWdvbnMoY29sID0gInNwX2xhZ19uZXdfZmRpX3JlYWxfbXhuIiwgcGFsZXR0ZT0iQmx1ZXMiLCBzdHlsZT0icXVhbnRpbGUiLCBuPTgsIHRpdGxlPSJNWE4gRkRJIEluZmxvd3MiKSArCiAgdG1fbGF5b3V0KG1haW4udGl0bGU9ICdDbHVzdGVycyBvZiBOZXcgRkRJIEluZmxvd3MgMjAxOScsICB0aXRsZS5wb3NpdGlvbiA9IGMoJ3JpZ2h0JywgJ3RvcCcpLCBsZWdlbmQucG9zaXRpb249IGMoImxlZnQiLCAiYm90dG9tIiksIHRpdGxlLnNpemUgPSAxKQoKZWR1Y2F0aW9uX2xhZyA8LSB0bV9zaGFwZShkYXRvc19tYXBhXzIwMTkpICsgCiAgdG1fcG9seWdvbnMoY29sID0gInNwX2xhZ19jb2xsZWdlX2VkdWNhdGlvbiIsIHBhbGV0dGU9Ik9yUmQiLCBzdHlsZT0icXVhbnRpbGUiLCBuPTgsIHRpdGxlPSJDb2xsZWdlIEVkdWNhdGlvbiIpICsKICB0bV9sYXlvdXQobWFpbi50aXRsZT0gJ0NsdXN0ZXJzIG9mIENvbGxlZ2UgRWR1Y2F0aW9uIDIwMTknLCAgdGl0bGUucG9zaXRpb24gPSBjKCdyaWdodCcsICd0b3AnKSwgbGVnZW5kLnBvc2l0aW9uPSBjKCJsZWZ0IiwgImJvdHRvbSIpLCB0aXRsZS5zaXplID0gMSkKCnBvcF9kZW5fbGFnIDwtIHRtX3NoYXBlKGRhdG9zX21hcGFfMjAxOSkgKyAKICB0bV9wb2x5Z29ucyhjb2wgPSAic3BfbGFnX3BvcF9kZW5zaXR5IiwgcGFsZXR0ZT0iQmx1ZXMiLCBzdHlsZT0icXVhbnRpbGUiLCBuPTgsIHRpdGxlPSJQb3B1bGF0aW9uIERlbnNpdHkiKSArCiAgdG1fbGF5b3V0KG1haW4udGl0bGU9ICdDbHVzdGVycyBvZiBQb3B1bGF0aW9uIERlbnNpdHkgMjAxOScsICB0aXRsZS5wb3NpdGlvbiA9IGMoJ3JpZ2h0JywgJ3RvcCcpLCBsZWdlbmQucG9zaXRpb249IGMoImxlZnQiLCAiYm90dG9tIiksIHRpdGxlLnNpemUgPSAxKQoKYGBgCgpgYGB7cn0KIyB0bWFwX2FycmFuZ2UgKDIwMTkpCnRtYXBfYXJyYW5nZShmZGksIGZkaV9sYWcsIGVkdWNhdGlvbiwgZWR1Y2F0aW9uX2xhZywgcG9wX2RlbiwgcG9wX2Rlbl9sYWcsIG5jb2wgPSAyKQpgYGAKCkVsIGNsdXN0ZXIgZGUgbGEgdmFyaWFibGUgTmV3IEZESSBkZWwgYcOxbyAyMDE5IGRlbXVlc3RyYSBxdWUgbG9zIGVzdGFkb3MgY29uIG1heW9yIGludmVyc2nDs24gZXh0cmFuamVyYSBzb24gbG9zIGVzdGFkb3MgZGUgVGFtYXVsaXBhcywgRXN0YWRvIGRlIE3DqXhpY28geSBsYSBDaXVkYWQgZGUgTcOpeGljby4gRXN0byBzZSBkZWJlIGEgcXVlIGVsIEVzdGFkbyB5IGxhIENpdWRhZCBkZSBNw6l4aWNvIHNvbiBpbXBvcnRhbnRlcyBjZW50cm9zIGVjb27Ds21pY29zLCBoaXN0w7NyaWNvcyB5IGN1bHR1cmFsZXMsIHVubyBzaWVuZG8gbGEgY2FwaXRhbCB5IGVsIG90cm8gc2llbmRvIGVsIGVzdGFkbyBtw6FzIHBvYmxhZG8gZGVsIHBhw61zLiBBc8OtIG1pc21vLCBsYSBpbnZlcnNpw7NuIGVuIFRhbWF1bGlwYXMgc2UgcHVlZGUgZGViZXIgYSBzdSB6b25hIGdlb2dyw6FmaWNhIHkgc3UgZnJvbnRlcmEgY29uIEVzdGFkb3MgVW5pZG9zLiBQb3Igb3RybyBsYWRvLCBsb3MgZXN0YWRvcyBtw6FzIGJham9zIHNvbiBDaGlodWFodWEsIFNpbmFsb2EgeSBRdWludGFuYSBSb28geSBlc3RvIHNlIHB1ZWRlIGRlYmVyIGEgdGVtYXMgZGUgc2VndXJpZGFkIGVuIGxhcyB6b25hcyB5IHN1IGRpc3RhbmNpYSBhIGxvcyBwcmluY2lwYWxlcyBjZW50cm9zIGVjb27Ds21pY29zLiAKCkVsIGNsdXN0ZXIgZGUgbGEgdmFyaWFibGUgZGUgQ29sbGVnZSBFZHVjYXRpb24gZGVtdWVzdHJhIHVuIG1heW9yIMOtbmRpY2UgZGUgZWR1Y2FjacOzbiBkZSB1bml2ZXJzaWRhZCBlbiBsYSB6b25hIG5vcnRlLW9jY2lkZW50ZSBkZWwgcGHDrXMgeSBZdWNhdGFuLCBlc3RvIHB1ZWRlIHNlciBwb3Igc3VzIGNvbmV4aW9uZXMgYSBFc3RhZG9zIFVuaWRvcywgc3UgZGVzYXJyb2xsbyBlY29uw7NtaWNvIHkgc3UgcHJlc2VuY2lhIGRlIHVuaXZlcnNpZGFkZXMuIFBvciBvdHJvIGxhZG8sIGxvcyBlc3RhZG9zIGRlIEd1ZXJyZXJvIHkgT2F4YWNhIGRlbXVlc3RyYW4gdW4gw61uZGljZSBtw6FzIGJham8geSBlc3RvIHNlIHB1ZWRlIGRlYmVyIGEgcXVlIHNvbiBlc3RhZG9zIGNvbiBtZW5vciBkZXNhcnJvbGxvIHNvY2lvZWNvbsOzbWljby4KClBvciDDumx0aW1vLCBlbCBjbHVzdGVyIGRlIGRlbnNpZGFkIGRlIHBvYmxhY2nDs24gZGVtdWVzdHJhIHF1ZSBsYSByZWdpw7NuIG3DoXMgcG9ibGFkYSBkZWwgcGHDrXMgZXMgZWwgY2VudHJvLCB5YSBxdWUgY29tbyBzZSBtZW5jaW9uYSBhbnRlcmlvcm1lbnRlLCBhaMOtIHNlIGNvbmNlbnRyYSBsYSBjYXBpdGFsIGRlbCBwYcOtcyB5IGVzIHVuYSB6b25hIGVjb27Ds21pY2EsIGN1bHR1cmFsIGUgaGlzdMOzcmljYSwgc2luIGVtYmFyZ28sIGVzbyB0YW1iacOpbiBzZSBwdWVkZSBkZWJlciBhIHF1ZSBlcyB1bmEgem9uYSBwZXF1ZcOxYSBwYXJhIGxhIGNhbnRpZGFkIGRlIGdlbnRlIHF1ZSB2aXZlIGVuIGxhIHJlZ2nDs24uIFBvciBvdHJvIGxhZG8sIHNlIHB1ZWRlIG5vdGFyIHF1ZSB1bm8gZGUgbG9zIGVzdGFkb3MgY29uIG1lbm9yIGRlbnNpZGFkIGRlIHBvYmxhY2nDs24gZXMgQ2hpaHVhaHVhLCBxdWUgYSBjb250cmFyaW8gZGVsIGNlbnRybywgZXMgdW4gZXN0YWRvIG11eSBncmFuZGUgeSBlc3RvIHB1ZWRlIGNhdXNhciBhIHF1ZSBsYSBkZW5zaWRhZCBzZWEgcGVxdWXDsWEuCgoKIyMjIElkZW50aWZpY2FjacOzbiBkZSBDbHVzdGVycyAyMDIxCmBgYHtyfQpkYXRvc19tYXBhXzIwMjEkc3BfbGFnX2NvbGxlZ2VfZWR1Y2F0aW9uIDwtIGxhZy5saXN0dyhzc3dtX3Jvb2tfMjAyMSwgZGF0b3NfbWFwYV8yMDIxJGNvbGxlZ2VfZWR1Y2F0aW9uLCB6ZXJvLnBvbGljeT1UUlVFKSAKZGF0b3NfbWFwYV8yMDIxJHNwX2xhZ19wb3BfZGVuc2l0eSA8LSBsYWcubGlzdHcoc3N3bV9yb29rXzIwMjEsIGRhdG9zX21hcGFfMjAyMSRwb3BfZGVuc2l0eSwgemVyby5wb2xpY3k9VFJVRSkgCgplZHVjYXRpb25fbGFnMiA8LSB0bV9zaGFwZShkYXRvc19tYXBhXzIwMjEpICsgCiAgdG1fcG9seWdvbnMoY29sID0gInNwX2xhZ19jb2xsZWdlX2VkdWNhdGlvbiIsIHBhbGV0dGU9Ik9yUmQiLCBzdHlsZT0icXVhbnRpbGUiLCBuPTgsIHRpdGxlPSJDb2xsZWdlIEVkdWNhdGlvbiIpICsKICB0bV9sYXlvdXQobWFpbi50aXRsZT0gJ0NsdXN0ZXJzIG9mIENvbGxlZ2UgRWR1Y2F0aW9uIDIwMjEnLCAgdGl0bGUucG9zaXRpb24gPSBjKCdyaWdodCcsICd0b3AnKSwgbGVnZW5kLnBvc2l0aW9uPSBjKCJsZWZ0IiwgImJvdHRvbSIpLCB0aXRsZS5zaXplID0gMSkKCnBvcF9kZW5fbGFnMiA8LSB0bV9zaGFwZShkYXRvc19tYXBhXzIwMjEpICsgCiAgdG1fcG9seWdvbnMoY29sID0gInNwX2xhZ19wb3BfZGVuc2l0eSIsIHBhbGV0dGU9IkJsdWVzIiwgc3R5bGU9InF1YW50aWxlIiwgbj04LCB0aXRsZT0iUG9wdWxhdGlvbiBEZW5zaXR5IikgKwogIHRtX2xheW91dChtYWluLnRpdGxlPSAnQ2x1c3RlcnMgb2YgUG9wdWxhdGlvbiBEZW5zaXR5IDIwMjEnLCAgdGl0bGUucG9zaXRpb24gPSBjKCdyaWdodCcsICd0b3AnKSwgbGVnZW5kLnBvc2l0aW9uPSBjKCJsZWZ0IiwgImJvdHRvbSIpLCB0aXRsZS5zaXplID0gMSkKCmBgYAoKYGBge3J9CiMgdG1hcF9hcnJhbmdlICgyMDIxKQp0bWFwX2FycmFuZ2UoZWR1Y2F0aW9uMiwgZWR1Y2F0aW9uX2xhZzIsIHBvcF9kZW4yLCBwb3BfZGVuX2xhZzIsIG5jb2wgPSAyKQpgYGAKCkVsIGNsdXN0ZXIgZGVsIMOtbmRpY2UgZGUgZWR1Y2FjacOzbiBkZSB1bml2ZXJzaWRhZCBlbiBlbCBwYcOtcyBwZXJtYW5lY2UgaWd1YWwgcXVlIGVuIGVsIGHDsW8gMjAxOSwgeWEgcXVlIGxhIGN1bHR1cmEgZGUgbGEgZWR1Y2FjacOzbiB5IGVsIGRlc2Fycm9sbG8gc29jaW9lY29uw7NtaWNvIGRlIGxhIHJlZ2nDs24gY29udGludWEgY3JlY2llbmRvLgoKTG8gbWlzbW8gc2UgcHVlZGUgdmVyIGVuIGVsIGNsdXN0ZXIgZGUgZGVuc2lkYWQgZGUgcG9ibGFjacOzbiwgZXMgbXV5IHNpbWlsYXIgYWwgZGUgZG9zIGHDsW9zIGFudGVyaW9yZXMsIHlhIHF1ZSBlbCBjZW50cm8gZXMgdW4gbHVnYXIgbXV5IGltcG9ydGFudGUgcGFyYSBlbCBwYcOtcyB5IG1hbnRpZW5lIHVuYSBwb2JsYWNpw7NuIGFsdGEgZGViaWRhIGEgbGEgbWlncmFjacOzbiB0YW50byBkZSBleHRyYW5qZXJvcyBjb21vIGRlIG1leGljYW5vcyBhIGVzdGEgcmVnacOzbiBwb3IgZGlzdGludG9zIGZhY3RvcmVzLCBlc3BlY2lhbG1lbnRlIGxhcyBvcG9ydHVuaWRhZGVzIHF1ZSBleGlzdGVuIGVuIGxhIGNhcGl0YWwuIAoKYGBge3J9CiMgVmlzdWFsaXphY2nDs24gZGUgQ2x1c3RlcnMgR2VvRGEgY29sbGVnZSBlZHVjYXRpb24gMjAxOQpzc3dtX2VkdWNhdGlvbiA8LSBxdWVlbl93ZWlnaHRzKG14X3N0YXRlX21hcCkgIyBxdWVlbiBzcGF0aWFsIHdlaWdodCBtYXRyaXggKGFsdGVybmF0aXZlIGZvcm1hdCkKbGlzYV9lZHVjYXRpb24gPC0gbG9jYWxfbW9yYW4oc3N3bV9lZHVjYXRpb24sIGRhdG9zX21hcGFfMjAxOVsiY29sbGVnZV9lZHVjYXRpb24iXSkgCmRhdG9zX21hcGFfMjAxOSRjbHVzdGVyX2VkdWNhdGlvbiA8LSBhcy5mYWN0b3IobGlzYV9lZHVjYXRpb24kR2V0Q2x1c3RlckluZGljYXRvcnMoKSkKbGV2ZWxzKGRhdG9zX21hcGFfMjAxOSRjbHVzdGVyX2VkdWNhdGlvbik8LWxpc2FfZWR1Y2F0aW9uJEdldExhYmVscygpIAoKZ2dwbG90KGRhdGE9ZGF0b3NfbWFwYV8yMDE5KSArCiAgZ2VvbV9zZihhZXMoZmlsbD1jbHVzdGVyX2VkdWNhdGlvbikpICsgCiAgZ2d0aXRsZShsYWJlbCA9ICJDb2xsZWdlIEVkdWNhdGlvbiAyMDE5Iiwgc3VidGl0bGUgPSAiTWV4aWNvJ3MgU3RhdGVzIikKYGBgCgpRdWVyw6l0YXJvIGNsYXNpZmljYWRvIGNvbW8gQmFqYS1BbHRhIHN1Z2llcmUgcXVlIHRpZW5lIHVuYSBlZHVjYWNpw7NuIHVuaXZlcnNpdGFyaWEgbcOhcyBiYWphIGVuIGNvbXBhcmFjacOzbiBjb24gc3VzIHZlY2lub3MsIHBlcm8gbcOhcyBhbHRhIGVuIGNvbXBhcmFjacOzbiBjb24gZWwgcHJvbWVkaW8gZ2VuZXJhbCBkZSBsb3MgZXN0YWRvcyBtZXhpY2Fub3MuIEVzdG8gcG9kcsOtYSBpbmRpY2FyIHF1ZSBRdWVyw6l0YXJvIGVzdMOhIHJlbGF0aXZhbWVudGUgYmllbiBwb3NpY2lvbmFkbyBlbiB0w6lybWlub3MgZGUgZWR1Y2FjacOzbiB1bml2ZXJzaXRhcmlhLCBwZXJvIGhheSDDoXJlYXMgY2lyY3VuZGFudGVzIGNvbiBuaXZlbGVzIG3DoXMgYmFqb3MgZGUgZWR1Y2FjacOzbi4KCkVzdG9zIGVzdGFkb3MgY2xhc2lmaWNhZG9zIGNvbW8gQmFqYS1CYWphIGluZGljYW4gcXVlIHRpZW5lbiBuaXZlbGVzIHJlbGF0aXZhbWVudGUgYmFqb3MgZGUgZWR1Y2FjacOzbiB1bml2ZXJzaXRhcmlhIGVuIGNvbXBhcmFjacOzbiBjb24gc3VzIHZlY2lub3MgeSBjb24gZWwgcHJvbWVkaW8gZ2VuZXJhbCBkZSBsb3MgZXN0YWRvcyBtZXhpY2Fub3MuIEVzdG8gc3VnaWVyZSBxdWUgZXN0YXMgcmVnaW9uZXMgcHVlZGVuIGVuZnJlbnRhciBkZXNhZsOtb3MgZW4gdMOpcm1pbm9zIGRlIGFjY2VzbyBvIGNhbGlkYWQgZGUgbGEgZWR1Y2FjacOzbiB1bml2ZXJzaXRhcmlhLgpFc3RvcyBlc3RhZG9zIGNsYXNpZmljYWRvcyBjb21vIEFsdGEtQWx0YSBpbmRpY2FuIHF1ZSB0aWVuZW4gbml2ZWxlcyByZWxhdGl2YW1lbnRlIGFsdG9zIGRlIGVkdWNhY2nDs24gdW5pdmVyc2l0YXJpYSB0YW50byBlbiBlbGxvcyBtaXNtb3MgY29tbyBlbiBzdXMgdmVjaW5vcy4gRXN0byBzdWdpZXJlIHF1ZSBCYWphIENhbGlmb3JuaWEgeSBTb25vcmEgZGVzdGFjYW4gY29tbyByZWdpb25lcyBjb24gbml2ZWxlcyBzdXBlcmlvcmVzIGRlIGVkdWNhY2nDs24gdW5pdmVyc2l0YXJpYSBlbiBjb21wYXJhY2nDs24gY29uIGVsIHByb21lZGlvIGdlbmVyYWwgZGUgbG9zIGVzdGFkb3MgbWV4aWNhbm9zIHkgZW4gcmVsYWNpw7NuIGNvbiBzdXMgdmVjaW5vcy4KCkxhIGNsYXNpZmljYWNpw7NuIG5vIHNpZ25pZmljYXRpdmEgcGFyYSB0b2RvcyBsb3MgZGVtw6FzIGVzdGFkb3Mgc3VnaWVyZSBxdWUgc3VzIG5pdmVsZXMgZGUgZWR1Y2FjacOzbiB1bml2ZXJzaXRhcmlhIG5vIGRpZmllcmVuIHNpZ25pZmljYXRpdmFtZW50ZSBkZSBsbyBxdWUgc2UgZXNwZXJhcsOtYSBiYWpvIGxhIGFsZWF0b3JpZWRhZCBlc3BhY2lhbC4gRXN0byBzaWduaWZpY2EgcXVlIGVzdG9zIGVzdGFkb3Mgbm8gbXVlc3RyYW4gdW4gcGF0csOzbiBlc3BhY2lhbCBmdWVydGUgZW4gdMOpcm1pbm9zIGRlIGVkdWNhY2nDs24gdW5pdmVyc2l0YXJpYSBlbiByZWxhY2nDs24gY29uIHN1cyB2ZWNpbm9zLgpFcyBpbXBvcnRhbnRlIGNvbnNpZGVyYXIgZWwgY29udGV4dG8gc29jaW9lY29uw7NtaWNvIGRlIGNhZGEgZXN0YWRvIGFsIGludGVycHJldGFyIGVzdG9zIHJlc3VsdGFkb3MuIEZhY3RvcmVzIGNvbW8gbGEgaW52ZXJzacOzbiBlbiBlZHVjYWNpw7NuLCBlbCBhY2Nlc28gYSBpbnN0aXR1Y2lvbmVzIGVkdWNhdGl2YXMgeSBsYXMgb3BvcnR1bmlkYWRlcyBsYWJvcmFsZXMgcHVlZGVuIGluZmx1aXIgZW4gbG9zIG5pdmVsZXMgZGUgZWR1Y2FjacOzbiB1bml2ZXJzaXRhcmlhIGVuIGNhZGEgcmVnacOzbi4KCmBgYHtyfQojIFZpc3VhbGl6YWNpw7NuIGRlIENsdXN0ZXJzIEdlb0RhIHBvcHVsYXRpb24gZGVuc2l0eSAyMDE5CnNzd21fcG9wIDwtIHF1ZWVuX3dlaWdodHMobXhfc3RhdGVfbWFwKSAjIHF1ZWVuIHNwYXRpYWwgd2VpZ2h0IG1hdHJpeCAoYWx0ZXJuYXRpdmUgZm9ybWF0KQpsaXNhX3BvcCA8LSBsb2NhbF9tb3Jhbihzc3dtX3BvcCwgZGF0b3NfbWFwYV8yMDE5WyJwb3BfZGVuc2l0eSJdKSAKZGF0b3NfbWFwYV8yMDE5JGNsdXN0ZXJfcG9wIDwtIGFzLmZhY3RvcihsaXNhX3BvcCRHZXRDbHVzdGVySW5kaWNhdG9ycygpKQpsZXZlbHMoZGF0b3NfbWFwYV8yMDE5JGNsdXN0ZXJfcG9wKTwtbGlzYV9wb3AkR2V0TGFiZWxzKCkgCgpnZ3Bsb3QoZGF0YT1kYXRvc19tYXBhXzIwMTkpICsKICBnZW9tX3NmKGFlcyhmaWxsPWNsdXN0ZXJfcG9wKSkgKyAKICBnZ3RpdGxlKGxhYmVsID0gIlBvcCBEZW5zaXR5IDIwMTkiLCBzdWJ0aXRsZSA9ICJNZXhpY28ncyBTdGF0ZXMiKQpgYGAKCkNpdWRhZCBkZSBNw6l4aWNvLCBNb3JlbG9zIHkgRXN0YWRvIGRlIE3DqXhpY28gLSBBbHRhLUFsdGE6IEVzdG9zIGVzdGFkb3MgY2xhc2lmaWNhZG9zIGNvbW8gQWx0YS1BbHRhIGluZGljYW4gcXVlIHRpZW5lbiBuaXZlbGVzIHJlbGF0aXZhbWVudGUgYWx0b3MgZGUgZGVuc2lkYWQgZGUgcG9ibGFjacOzbiB0YW50byBlbiBlbGxvcyBtaXNtb3MgY29tbyBlbiBzdXMgdmVjaW5vcy4gRXN0byBzdWdpZXJlIHF1ZSBlc3RhcyByZWdpb25lcywgcXVlIHNvbiDDoXJlYXMgbWV0cm9wb2xpdGFuYXMgaW1wb3J0YW50ZXMsIHRpZW5lbiB1bmEgYWx0YSBjb25jZW50cmFjacOzbiBkZSBwb2JsYWNpw7NuIGVuIGNvbXBhcmFjacOzbiBjb24gZWwgcHJvbWVkaW8gZ2VuZXJhbCBkZSBsb3MgZXN0YWRvcyBtZXhpY2Fub3MgeSBlbiByZWxhY2nDs24gY29uIHN1cyB2ZWNpbm9zLgoKWXVjYXTDoW4sIE51ZXZvIExlw7NuLCBDaGlodWFodWEsIER1cmFuZ28sIFNpbmFsb2EgeSBCYWphIENhbGlmb3JuaWEgLSBCYWphLUJhamE6IEVzdG9zIGVzdGFkb3MgY2xhc2lmaWNhZG9zIGNvbW8gQmFqYS1CYWphIGluZGljYW4gcXVlIHRpZW5lbiBuaXZlbGVzIHJlbGF0aXZhbWVudGUgYmFqb3MgZGUgZGVuc2lkYWQgZGUgcG9ibGFjacOzbiB0YW50byBlbiBlbGxvcyBtaXNtb3MgY29tbyBlbiBzdXMgdmVjaW5vcy4gRXN0byBzdWdpZXJlIHF1ZSBlc3RhcyByZWdpb25lcyBwdWVkZW4gc2VyIG1lbm9zIGRlbnNhbWVudGUgcG9ibGFkYXMgZW4gY29tcGFyYWNpw7NuIGNvbiBlbCBwcm9tZWRpbyBnZW5lcmFsIGRlIGxvcyBlc3RhZG9zIG1leGljYW5vcyB5IGVuIHJlbGFjacOzbiBjb24gc3VzIHZlY2lub3MuCgpSZXN0byBkZSBsb3MgRXN0YWRvcyAtIE5vIFNpZ25pZmljYXRpdm9zOiBMYSBjbGFzaWZpY2FjacOzbiBubyBzaWduaWZpY2F0aXZhIHBhcmEgZWwgcmVzdG8gZGUgbG9zIGVzdGFkb3Mgc3VnaWVyZSBxdWUgc3VzIG5pdmVsZXMgZGUgZGVuc2lkYWQgZGUgcG9ibGFjacOzbiBubyBkaWZpZXJlbiBzaWduaWZpY2F0aXZhbWVudGUgZGUgbG8gcXVlIHNlIGVzcGVyYXLDrWEgYmFqbyBsYSBhbGVhdG9yaWVkYWQgZXNwYWNpYWwuIEVzdG8gc2lnbmlmaWNhIHF1ZSBlc3RvcyBlc3RhZG9zIG5vIG11ZXN0cmFuIHVuIHBhdHLDs24gZXNwYWNpYWwgZnVlcnRlIGVuIHTDqXJtaW5vcyBkZSBkZW5zaWRhZCBkZSBwb2JsYWNpw7NuIGVuIHJlbGFjacOzbiBjb24gc3VzIHZlY2lub3MuCgpgYGB7cn0KIyBWaXN1YWxpemFjacOzbiBkZSBDbHVzdGVycyBHZW9EYSBjb2xsZWdlIGVkdWNhdGlvbiAyMDIxCnNzd21fZWR1Y2F0aW9uMiA8LSBxdWVlbl93ZWlnaHRzKG14X3N0YXRlX21hcCkgIyBxdWVlbiBzcGF0aWFsIHdlaWdodCBtYXRyaXggKGFsdGVybmF0aXZlIGZvcm1hdCkKbGlzYV9lZHVjYXRpb24yIDwtIGxvY2FsX21vcmFuKHNzd21fZWR1Y2F0aW9uMiwgZGF0b3NfbWFwYV8yMDIxWyJjb2xsZWdlX2VkdWNhdGlvbiJdKSAKZGF0b3NfbWFwYV8yMDIxJGNsdXN0ZXJfZWR1Y2F0aW9uMiA8LSBhcy5mYWN0b3IobGlzYV9lZHVjYXRpb24yJEdldENsdXN0ZXJJbmRpY2F0b3JzKCkpCmxldmVscyhkYXRvc19tYXBhXzIwMjEkY2x1c3Rlcl9lZHVjYXRpb24yKTwtbGlzYV9lZHVjYXRpb24yJEdldExhYmVscygpIAoKZ2dwbG90KGRhdGE9ZGF0b3NfbWFwYV8yMDIxKSArCiAgZ2VvbV9zZihhZXMoZmlsbD1jbHVzdGVyX2VkdWNhdGlvbjIpKSArIAogIGdndGl0bGUobGFiZWwgPSAiQ29sbGVnZSBFZHVjYXRpb24gMjAyMSIsIHN1YnRpdGxlID0gIk1leGljbydzIFN0YXRlcyIpCmBgYAoKQmFqYSBDYWxpZm9ybmlhIC0gQWx0YS1BbHRhOiBCYWphIENhbGlmb3JuaWEgY2xhc2lmaWNhZGEgY29tbyBBbHRhLUFsdGEgaW5kaWNhIHF1ZSB0aWVuZSBuaXZlbGVzIHJlbGF0aXZhbWVudGUgYWx0b3MgZGUgZWR1Y2FjacOzbiB1bml2ZXJzaXRhcmlhIHRhbnRvIGVuIGVsbGEgbWlzbWEgY29tbyBlbiBzdXMgdmVjaW5vcy4gRXN0byBzdWdpZXJlIHF1ZSBCYWphIENhbGlmb3JuaWEsIHkgcG9zaWJsZW1lbnRlIHN1cyDDoXJlYXMgbWV0cm9wb2xpdGFuYXMgY29tbyBUaWp1YW5hLCB0aWVuZW4gdW5hIGFsdGEgY29uY2VudHJhY2nDs24gZGUgcGVyc29uYXMgY29uIGVkdWNhY2nDs24gdW5pdmVyc2l0YXJpYSBlbiBjb21wYXJhY2nDs24gY29uIGVsIHByb21lZGlvIGdlbmVyYWwgZGUgbG9zIGVzdGFkb3MgbWV4aWNhbm9zIHkgZW4gcmVsYWNpw7NuIGNvbiBzdXMgdmVjaW5vcy4KCkd1ZXJyZXJvLCBPYXhhY2EgeSBQdWVibGEgLSBCYWphLUJhamE6IEVzdG9zIGVzdGFkb3MgY2xhc2lmaWNhZG9zIGNvbW8gQmFqYS1CYWphIGluZGljYW4gcXVlIHRpZW5lbiBuaXZlbGVzIHJlbGF0aXZhbWVudGUgYmFqb3MgZGUgZWR1Y2FjacOzbiB1bml2ZXJzaXRhcmlhIHRhbnRvIGVuIGVsbG9zIG1pc21vcyBjb21vIGVuIHN1cyB2ZWNpbm9zLiBFc3RvIHN1Z2llcmUgcXVlIEd1ZXJyZXJvLCBPYXhhY2EgeSBQdWVibGEgcHVlZGVuIGVuZnJlbnRhciBkZXNhZsOtb3MgZW4gdMOpcm1pbm9zIGRlIGFjY2VzbyBvIGNhbGlkYWQgZGUgbGEgZWR1Y2FjacOzbiB1bml2ZXJzaXRhcmlhIGVuIGNvbXBhcmFjacOzbiBjb24gZWwgcHJvbWVkaW8gZ2VuZXJhbCBkZSBsb3MgZXN0YWRvcyBtZXhpY2Fub3MgeSBlbiByZWxhY2nDs24gY29uIHN1cyB2ZWNpbm9zLgoKUmVzdG8gZGUgbG9zIEVzdGFkb3MgLSBObyBTaWduaWZpY2F0aXZvczogTGEgY2xhc2lmaWNhY2nDs24gbm8gc2lnbmlmaWNhdGl2YSBwYXJhIGVsIHJlc3RvIGRlIGxvcyBlc3RhZG9zIHN1Z2llcmUgcXVlIHN1cyBuaXZlbGVzIGRlIGVkdWNhY2nDs24gdW5pdmVyc2l0YXJpYSBubyBkaWZpZXJlbiBzaWduaWZpY2F0aXZhbWVudGUgZGUgbG8gcXVlIHNlIGVzcGVyYXLDrWEgYmFqbyBsYSBhbGVhdG9yaWVkYWQgZXNwYWNpYWwuIEVzdG8gc2lnbmlmaWNhIHF1ZSBlc3RvcyBlc3RhZG9zIG5vIG11ZXN0cmFuIHVuIHBhdHLDs24gZXNwYWNpYWwgZnVlcnRlIGVuIHTDqXJtaW5vcyBkZSBlZHVjYWNpw7NuIHVuaXZlcnNpdGFyaWEgZW4gcmVsYWNpw7NuIGNvbiBzdXMgdmVjaW5vcy4KCmBgYHtyfQojIFZpc3VhbGl6YWNpw7NuIGRlIENsdXN0ZXJzIEdlb0RhIHBvcHVsYXRpb24gZGVuc2l0eSAyMDIxCnNzd21fcG9wMiA8LSBxdWVlbl93ZWlnaHRzKG14X3N0YXRlX21hcCkgIyBxdWVlbiBzcGF0aWFsIHdlaWdodCBtYXRyaXggKGFsdGVybmF0aXZlIGZvcm1hdCkKbGlzYV9wb3AyIDwtIGxvY2FsX21vcmFuKHNzd21fcG9wMiwgZGF0b3NfbWFwYV8yMDIxWyJwb3BfZGVuc2l0eSJdKSAKZGF0b3NfbWFwYV8yMDIxJGNsdXN0ZXJfcG9wMiA8LSBhcy5mYWN0b3IobGlzYV9wb3AyJEdldENsdXN0ZXJJbmRpY2F0b3JzKCkpCmxldmVscyhkYXRvc19tYXBhXzIwMjEkY2x1c3Rlcl9wb3AyKTwtbGlzYV9wb3AyJEdldExhYmVscygpIAoKZ2dwbG90KGRhdGE9ZGF0b3NfbWFwYV8yMDIxKSArCiAgZ2VvbV9zZihhZXMoZmlsbD1jbHVzdGVyX3BvcDIpKSArIAogIGdndGl0bGUobGFiZWwgPSAiUG9wIERlbnNpdHkgMjAyMSIsIHN1YnRpdGxlID0gIk1leGljbydzIFN0YXRlcyIpCmBgYAoKTGEgZGlzdHJpYnVjacOzbiBkZSBsYSBkZW5zaWRhZCBkZSBwb2JsYWNpw7NuIGVuIGxvcyBlc3RhZG9zIGRlIE3DqXhpY28gbXVlc3RyYSB1bmEgY29uc2lzdGVuY2lhIGVudHJlIGxvcyBhw7FvcyAyMDE5IHkgMjAyMSBlbiBjdWFudG8gYSBsYSBjbGFzaWZpY2FjacOzbiBkZSBsb3MgZXN0YWRvcyBlbiBsYXMgY2F0ZWdvcsOtYXMgSGlnaC1IaWdoLCBMb3ctTG93IHkgTm8gU2lnbmlmaWNhdGl2b3MuCkxvcyBlc3RhZG9zIGRlIENpdWRhZCBkZSBNw6l4aWNvLCBNb3JlbG9zIHkgRXN0YWRvIGRlIE3DqXhpY28gY29udGluw7phbiBzaWVuZG8gY2xhc2lmaWNhZG9zIGNvbW8gSGlnaC1IaWdoIGVuIGFtYm9zIGHDsW9zLCBsbyBxdWUgaW5kaWNhIHVuYSBhbHRhIGNvbmNlbnRyYWNpw7NuIGRlIGRlbnNpZGFkIGRlIHBvYmxhY2nDs24gZW4gZXN0YXMgcmVnaW9uZXMuCgpEZWwgbWlzbW8gbW9kbywgbG9zIGVzdGFkb3MgZGUgWXVjYXTDoW4sIE51ZXZvIExlw7NuLCBDaGlodWFodWEsIER1cmFuZ28sIFNpbmFsb2EgeSBCYWphIENhbGlmb3JuaWEgc2lndWVuIHNpZW5kbyBjbGFzaWZpY2Fkb3MgY29tbyBMb3ctTG93IGVuIGFtYm9zIGHDsW9zLCBsbyBxdWUgaW5kaWNhIG5pdmVsZXMgbcOhcyBiYWpvcyBkZSBkZW5zaWRhZCBkZSBwb2JsYWNpw7NuIGVuIGVzdGFzIHJlZ2lvbmVzIGVuIGNvbXBhcmFjacOzbiBjb24gZWwgcHJvbWVkaW8gZ2VuZXJhbC4KCkxvcyByZXN1bHRhZG9zIHN1Z2llcmVuIGNpZXJ0YSBlc3RhYmlsaWRhZCBlbiBsYSBkaXN0cmlidWNpw7NuIGVzcGFjaWFsIGRlIGxhIGRlbnNpZGFkIGRlIHBvYmxhY2nDs24gZW4gbG9zIGVzdGFkb3MgZGUgTcOpeGljbyBlbnRyZSBsb3MgYcOxb3MgMjAxOSB5IDIwMjEsIGNvbiBhbGd1bmFzIHJlZ2lvbmVzIG1hbnRlbmllbmRvIHN1IGNsYXNpZmljYWNpw7NuIG1pZW50cmFzIHF1ZSBvdHJhcyBwZXJtYW5lY2VuIG5vIHNpZ25pZmljYXRpdmFzIGVuIGFtYm9zIGHDsW9zLgoKYGBge3J9CiMgQ2FyZ2FyIG51ZXZhcyBsaWJyZXLDrWFzCmxpYnJhcnkoc3BhdGlhbHJlZykKbGlicmFyeShzdGFyZ2F6ZXIpCmBgYAoKCgojIEFjdGl2aWRhZCBFeHRyYSAxCgpgYGB7cn0KbGlicmFyeShwbG0pCmxpYnJhcnkocHNwYXRyZWcpCmBgYAoKYGBge3J9CiMgSW1wb3J0YXIgcGFuZWwgZGF0YXNldCAKcGFuZWxfZGF0YSA8LSByZWFkLmNzdigiL1VzZXJzL3JlZ2luYWVucmlxdWV6L0Rlc2t0b3AvQWN0IDEvcGFuZWxfZGF0YXNldC5jc3YiKQoKc3VtbWFyeShwYW5lbF9kYXRhKQoKcGRfZnJhbWUgPC0gcGRhdGEuZnJhbWUocGFuZWxfZGF0YSwgaW5kZXggPSBjKCJzdGF0ZSIsICJ5ZWFyIiksIGRyb3AuaW5kZXggPSBUUlVFKQpgYGAKCmBgYHtyfQojIEVzcGVjaWZpY2FyIGVsIG1vZGVsbyBkZWwgcGFuZWwgMjAxOQpwYW5lbF9tb2RlbF8yMDE5IDwtIG5ld19mZGlfcmVhbF9teG4gfiBjcmltZV9yYXRlICsgcG9wX2RlbnNpdHkgKyBjb2xsZWdlX2VkdWNhdGlvbiArIHVuZW1wbG95bWVudApgYGAKCmBgYHtyfQojIEVzdGltYXIgZWwgbW9kZWxvIGRlIHJlZ3Jlc2nDs24gCm5vbl9zcGF0aWFsX3BhbmVsX21vZGVsXzIwMTkgPC0gcGxtKHBhbmVsX21vZGVsXzIwMTksIGRhdGEgPSBwZF9mcmFtZSwgbW9kZWwgPSAid2l0aGluIiwgZWZmZWN0ID0gInR3b3dheXMiKQpzdW1tYXJ5KG5vbl9zcGF0aWFsX3BhbmVsX21vZGVsXzIwMTkpCmBgYAoKYGBge3J9CiMgRXN0aW1hciBlbCBtb2RlbG8gZGUgcmVncmVzacOzbiBlc3BhY2lhbCAKc3BhdGlhbF9wYW5lbF9tb2RlbF8yMDE5IDwtIHBzcGF0Zml0KGZvcm11bGEgPSBwYW5lbF9tb2RlbF8yMDE5LCBkYXRhID0gcGRfZnJhbWUsIGxpc3R3ID0gc3N3bV9yb29rXzIwMTksIGRlbWVhbiA9IEZBTFNFLCBlZmZfZGVtZWFuID0gInR3b3dheXMiLCB0eXBlID0gInNhciIsIGluZGV4ID0gYygic3RhdGUiLCAieWVhciIpKQpzdW1tYXJ5KHNwYXRpYWxfcGFuZWxfbW9kZWxfMjAxOSkKYGBgCgoKCg==