Este es nuestro informe para la presentación del día 18 de diciembre. Aquí comentaremos de que trata nuestro trabajo y las transformaciones que hemos realizado, así como, el código de estas y los diferentes paquetes utilizados.

1. INTRODUCCIÓN

Nuestro trabajo consiste en la manipulación de datos del INE en lo referente a nombres y apellidos en España. Para esto, descargaremos desde R los datos de frecuencia de nombres y apellidos españoles del INE y también descargaremos un excel de forma manual de la distribución geográfica provincial de nuestro nombre y primer apellido.

2. CARGAMOS DATOS Y PAQUETES

Vamos a cargar diferentes paquetes que iremos utilizando a lo largo del trabajo.


#Habría que hacer un install.packages(" ") con cada uno si no los tuvieramos ya en nuestra biblioteca.
# library(tidyverse)
# library(klippy)  #- remotes::install_github("rlesur/klippy")
# library(knitr)
# library(readxl)
# library(reactable)
# library(ggplot2)
# library(stringi)
# library(ggThemeAssist)
# library(plotly)
# library(patchwork)
# library(ggrepel)
# library(sf)
# library(crosstalk)
# library(gganimate)
# library(hrbrthemes)
# library(sf)
# library(RColorBrewer)

Ahora descargaremos los diferentes informes para manipularlos y los transformaremos para poder hacerlos visibles. Tendremos 2 dataframes de apellidos, uno para frecuencia >100 y otros para frecuencia <100 y >20. Así mismo, tendremos 2 dataframes de nombres, uno para hombres y otro para mujeres.

#APELLIDOS
#- descargamos los datos en "./Datos/frecuencia.xls"

# url <- "https://www.ine.es/daco/daco42/nombyapel/apellidos_frecuencia.xls"
# archivo_de_destino <- here::here("Datos", "frecuencia.xls")
# download.file(url, archivo_de_destino)

#- Vamos a importar los datos tipo excel con la función readxl y mediante el sheet=1 cogeremos la HOJA 1 del excel y mediante el range, cogeremos desde el Orden hasta el último total, ya que, si importamos directamente el EXCEL tendriamos que eliminar algunas de las primeras filas, por lo que, mediante esto ya lo tenemos como queremos.
df_apellidos1 <- read_excel ("./Datos/frecuencia.xls", sheet=1, range="A5:E25798")
df_apellidos2 <- read_excel ("./Datos/frecuencia.xls", sheet=2, range="A5:E50393")


#NOMBRES

# url2 <- "https://www.ine.es/daco/daco42/nombyapel/nombres_por_edad_media.xls"
# archivo_de_destino2 <- here::here("Datos", "frecuencianombre.xls")
# download.file(url2, archivo_de_destino2)

# Vamos a importar los datos tipo excel con la función readxl y mediante el sheet=1 cogeremos la HOJA 1 del excel y mediante el range, cogeremos desde el Orden hasta el último total, ya que, si importamos directamente el EXCEL tendriamos que eliminar algunas de las primeras filas, por lo que, mediante esto ya lo tenemos como queremos.
df_nombre1 <- read_excel ("./Datos/frecuencianombre.xls", sheet=1, range="A7:D25790")
df_nombre <- read_excel ("./Datos/frecuencianombre.xls", sheet=2, range="A7:D26499")



#Daniel y Laura frecuencia y provincias
df_Daniel <- read_excel ("./Datos/Daniel_Laura2.xlsx", sheet=1)
df_Laura <- read_excel ("./Datos/Daniel_Laura2.xlsx", sheet=2)

3. MODIFICAMOS NUESTROS DATAFRAMES

Si abriesemos los dataframes de apellidos, vemos que aparecen varias variables que se llaman “Total” las cuales van referidas a algo. Vamos a modificar los nombres por aquello a lo que correspondes esos “totales”.


#Modificamos los nombres de las columnas que se llaman total, por aquello a lo que le corresponde (es un total, pero un total de algo, lo llamaremos conforme ese ALGO)
df_apellidos1 <- df_apellidos1 %>% rename(Frec_1er_Apellido = Total...3,
  Frec_2o_Apellido= Total...4,
  Frec_Ambos_Apellidos= Total...5)

df_apellidos2 <- df_apellidos2 %>% rename(Frec_1er_Apellido = Total...3,
  Frec_2o_Apellido= Total...4,
  Frec_Ambos_Apellidos= Total...5)


df_apellidosmodif <- suppressWarnings(transform(df_apellidos2, Frec_2o_Apellido= as.numeric(Frec_2o_Apellido),
  Frec_Ambos_Apellidos=as.numeric(Frec_Ambos_Apellidos)
  )
  )

4. TRANSFORMACIONES

4.1 TABLAS

Ahora, vamos a manipular nuestros dataframes para hacer ciertas construcciones, en este caso empezaremos con unas tablas. Estas, van a recoger los nombres y apellidos agrupados por la letra que empiecen y con distintos colores de celda dependiendo la frecuencia, siendo verde frecuencia alta, naranja frecuencia media y rojo frecuencia baja, es decir, poco frecuentes.

Primero de todo, necesitaremos unir ambas tablas, tanto de nombres como de apellidos en una sola.

#APELLIDOS
df_apellidos_conjuntos <- full_join(df_apellidos1, df_apellidosmodif, by= c("Orden","Apellido","Frec_1er_Apellido","Frec_2o_Apellido","Frec_Ambos_Apellidos"))

df_apellidos_conjuntos2 <- df_apellidos_conjuntos %>%
  mutate(Letra= stri_sub(Apellido,1,1)) %>%
  arrange(Letra)


#NOMBRES
df_nombreH<- df_nombre1 %>%
  mutate(Sexo="Hombre") %>%
  rename(Edad= `Edad Media (*)`)%>%
  select(-c(Orden))

df_nombreM <- df_nombre %>%
  mutate(Sexo="Mujer") %>%
  rename(Edad= `Edad Media (*)`) %>%
  select(-c(Orden))


df_NombresJuntos<- full_join(df_nombreH, df_nombreM, by= c("Nombre","Frecuencia","Edad","Sexo")) %>% arrange(desc(Frecuencia))

df_NombresJuntos2 <- df_NombresJuntos %>%
  mutate(Letra= stri_sub(Nombre,1,1)) %>%
  arrange(Letra)

De esta forma, haremos una tabla con buscador de NOMBRES y otra para APELLIDOS

4.1.1 TABLA NOMBRES


4.1.2 TABLA APELLIDOS

4.2. GRÁFICAS

Para los gráficos, haremos 3 gráficos de barras. El primer gráfico esta relacionado con los 10 nombres con más edad media y los 10 nombres con menos edad media. Por otro lado, los dos graficos siguientes representan los 10 apellidos más frecuentes y los 10 nombres más frecuentes.

Primero, necesitaremos transformar los datos:

#APELLIDOS
df_apellidos <- df_apellidos1 %>% select(Apellido, Frec_1er_Apellido, Frec_2o_Apellido) %>% mutate(Frec_Total= Frec_1er_Apellido + Frec_2o_Apellido) %>% slice_max(Frec_Total, n=10)  #Seleccionamos las columnas de apellido, Frec_1er_Apellido y Frec_2o_Apellido que són las que necesitaremos para nuestro gráfico, después obtenemos la frecuencia total sumando la frecuencia del primer apellido más la del segundo y cogemos solo los 10 apellidos con mayor frecuencia.

#ordenar de mayor a menor

df_apellidos <- transform(df_apellidos, Apellido = reorder(Apellido, -Frec_Total))

#NOMBRES
df_nombres <- full_join(df_nombre, df_nombre1) #Tenemos dos df de nombres uno para los nombres de hombre y otro para los nombres de mujer, entonces juntamos los dos df para obtener solo uno.

df_nombres3 <-df_nombres %>% select(Nombre, Frecuencia) %>% slice_max(Frecuencia, n=10) %>% mutate(Nombre = forcats::as_factor(Nombre)) %>% mutate(Nombre = forcats::fct_reorder(Nombre, Frecuencia)) #Seleccionamos las columnas que nos interesan para nuestro gráfico y seleccionamos los 10 nombres con mayor frecuencia. Convertimos la variable Nombre a factor con as_factor(). Después ordenamos las columnas de menor a mayor con fct_reorder().


GRÁFICO DE LOS 10 NOMBRES CON MÁS EDAD MEDIA Y LOS 10 NOMBRES CON MENOS EDAD MEDIA

library(tidyverse)

#10 MÁS FRECUENTES Y 10 QUE MENOS
df_nombres_edadmedia <- df_nombres %>% select(Nombre, `Edad Media (*)`) %>% arrange(desc(`Edad Media (*)`)) %>%
  slice(c(1,2,3,4,5,6,7,8,9,10,n()-9,n()-8,n()-7,n()-6,n()-5,n()-4,n()-3,n()-2,n()-1, n()))%>%
  mutate(Nombre = forcats::as_factor(Nombre)) %>% mutate(Nombre = forcats::fct_reorder(Nombre, `Edad Media (*)`))#Seleccionamos las variables nombre y edad media para después poder hacer el gráfico. Con arrange ordenamos la Edad Media de mayor a menor y con slice seleccionamos los 10 nombres con mayor y menor media.Por último, con mutate ordenamos de mayor a menor.

r <- ggplot(df_nombres_edadmedia, aes(Nombre, `Edad Media (*)`)) + geom_col(fill="mediumpurple") + coord_flip() + theme(plot.caption = element_text(face = "bold.italic"), 
    axis.ticks = element_line(size = 0.6), 
    axis.title = element_text(size = 10, 
        face = "bold", vjust = 0,5), axis.text = element_text(size = 10, 
        face = "bold"), plot.title = element_text(face = "bold", size = 8, 
        hjust = 0, vjust = 1,5), panel.background = element_rect(fill = "lavender")) +labs(title = "LOS 10 NOMBRES CON MÁS Y MENOS EDAD MEDIA",
    caption = "Datos provenientes del INE") 

ggplotly(r)


En este grafico hemos querido observar cuales són los 10 nombres con mayor edad media en contraposición con los 10 nombres con menos edad media. Los primeros corresponden a nombres más tradicionales correspondientes a una epoca más rural, que actualmente practicamente ya no se utilizan. Y los segundos corresponden a nombres más nuevos basados en modas, anglicismos… etc. Según nuestro grafico el nombre con más edad media correspondería a Afrodisia con una edad media de 84,8. Y el nombre con menos edad media correspondería a Vaiana con una edad media de 1.

GRÁFICO LOS 10 APELLIDOS MÁS FRECUENTES


#obtenemos un vector de diferentes colores del Set1 de brewer.pal
Miscolores <- brewer.pal(10, "Set3")

#asignamos un color diferente a cada factor de apellido

names(Miscolores)<- df_apellidos$Apellido

#Ahora podemos usar los colores asignados a los 10 apellidos para colorear la barra

t <- ggplot(df_apellidos, aes(Apellido, Frec_Total, fill=Apellido)) + geom_bar(stat="identity") + scale_colour_manual(values=Miscolores)

t + theme(plot.caption = element_text(size = 11, 
    face = "bold.italic"), axis.line = element_line(size = 1.2), 
    axis.title = element_text(size = 14, 
        face = "bold"), axis.text = element_text(size = 13, 
        face = "bold"), axis.text.x = element_text(size = 13, 
        vjust = 0.5, angle = 40), plot.title = element_text(face = "bold", 
        hjust = 0.5, vjust = 1.5), legend.title = element_text(size = 12, 
        face = "bold"), legend.key = element_rect(fill = "gray91"), 
    legend.background = element_rect(fill = "gray97")) +labs(title = "LOS 10 APELLIDOS MÁS FRECUENTES DE ESPAÑA", 
    caption = "Datos provenientes del INE")

En este gráfico podemos observar los 10 apellidos más frecuentes de España ordenamos de mayor a menor frecuencia.

GRÁFICO LOS 10 NOMBRES MÁS FRECUENTES


#obtenemos un vector de diferentes colores del Set1 de brewer.pal
Miscolores <- brewer.pal(10, "Set3")

#asignamos un color diferente a cada factor de apellido

names(Miscolores)<- df_nombres3$Nombre

s <- ggplot(df_nombres3, aes(Nombre, Frecuencia, fill=Nombre)) + geom_bar(stat="Identity")+ scale_colour_manual(values=Miscolores)

s + theme(plot.caption = element_text(size = 10, 
    face = "bold.italic"), panel.grid.major = element_line(size = 1), 
    panel.grid.minor = element_line(size = 1), 
    axis.title = element_text(size = 15, 
        face = "bold", vjust = 1), axis.text = element_text(size = 15, 
        face = "bold"), axis.text.x = element_text(size = 10, 
        vjust = 0.75, angle = 25), plot.title = element_text(face = "bold.italic", 
        hjust = 0.5, vjust = 2), legend.text = element_text(face = "italic"), 
    legend.title = element_text(size = 12, 
        face = "bold.italic"), panel.background = element_rect(fill = "gray89"), 
    legend.background = element_rect(fill = "gray85")) +labs(title = "LOS 10 NOMBRES MÁS FRECUENTES DE ESPAÑA", 
    caption = "Datos provenientes del INE") 

En este segundo gráfico podemos observar los 10 nombres más frecuentes de España ordenados de menor a mayor.


4.3. MAPAS

Cargaremos primero las geometrías de la carpeta Datos

load("./Datos/geometrias_clase_10.RData")

Y ahora haremos un mapa de España con la distribución de las personas con nombre de Daniel:


#Hacemos un mapa de coropletas del país para el total del nombre "Daniel"
dfDaniel <- full_join(Provincias, df_Daniel, by = c("NombreProv" = "Provincia"))
ggplot(dfDaniel,aes(geometry = geometry)) + geom_sf(aes(fill= Total))  + scale_fill_viridis_c(option = "viridis", trans = "sqrt", direction = -1) + coord_sf(xlim = c(-20,10)) + annotate(geom = "text", x = 4, y = 37, label = "Mar Mediterráneo", fontface = "italic", color = "grey22", size = 3) + labs (title = "Mapa 1: Distribución de personas llamadas Daniel en España",
       subtitle = "Por províncias",
       caption = "Datos provenientes del INE") + theme_void() 

Ahora, vamos a mostrar las tres provincias con mayor personas llamadas “Daniel” y las tres provincias con menos personas llamadas Daniel.

 
#Las tres provincincias con más personas llamadas Daniel.
Provincias_mayor<- dfDaniel %>% slice_max(Total, n = 3) 
provincias_point <- st_centroid(Provincias_mayor) #Cambiamos la geometry por el centroide
provincias_points <- cbind(Provincias_mayor, st_coordinates(st_centroid(Provincias_mayor$geometry)))

MasProvDan<- ggplot() + geom_sf(data = dfDaniel) + geom_sf(data = Provincias_mayor, fill = "green")+ coord_sf(ylim = c(35,45), xlim = c(-10,5)) + theme_minimal() + labs (title = "Mapa 2: Provincias con más personas llamadas Daniel", size = 3)  +geom_text(data = provincias_points, 
            aes(x = X, y = Y, label = NombreProv), 
            color = "Black", fontface = "bold", check_overlap = TRUE, size = 2.5) +theme_test()

#Las tres provincias con menos personas llamadas Daniel.
Provincias_menor<- dfDaniel %>% slice_min(Total, n = 5)
Provincias_point <- st_centroid(Provincias_menor) #Cambiamos la geometry por el centroide
Provincias_points <- cbind(Provincias_menor, st_coordinates(st_centroid(Provincias_menor$geometry)))

MenosProvDan<- ggplot() + geom_sf(data = dfDaniel) + geom_sf(data = Provincias_menor, fill = "red")+ coord_sf(ylim = c(35,45), xlim = c(-10,5)) + theme_minimal() + labs (title = "Mapa 3: Provincias con menos personas llamadas Daniel", size = 3)  +geom_text(data = Provincias_points, 
            aes(x = X, y = Y, label = NombreProv), 
            color = "White", fontface = "bold", check_overlap = TRUE, size = 2.5) +theme_test()

#Mostramos los plots

MasProvDan + MenosProvDan

Por tanto, las tres provincias donde abunda más el nombre de “Daniel” son: Madrid, Barcelona y Sevilla. En cambio, en Teruel, Soria y Álava, no es tan frecuente este nombre.


Ahora haremos un mapa de España con la distribución de las personas pero con nombre de Laura:


#Hacemos otro mapa de coropletas para el total del nombre "Laura".
dfLaura<-full_join(Provincias,df_Laura, by = c("NombreProv" = "Provincia")) %>%select(-c(INECodCCAA, NombreCCAA, INECodProv))

ggplot(data = dfLaura, aes(geometry = geometry)) + geom_sf(aes(fill = Total)) + scale_fill_viridis_c(option = "inferno", trans = "sqrt", direction = -1) + coord_sf(xlim = c(-20,10)) +
  annotate(geom = "text", x = 4, y = 37, 
           label = "Mar Mediterráneo", fontface = "italic", color = "grey22", size = 3) + labs (title = "Mapa 4: Distribución de personas llamadas Laura en España",
       subtitle = "Por províncias",
       caption = "Datos provenientes del INE") + theme_void() 

Y a continuación, otro mapa de coropletas con el nombre de Laura, por provincias:


#Mapa de las provincias con más personas llamadas Laura
Provincias_mayor<- dfLaura %>% slice_max(Total, n = 3)
provincias_points <- st_centroid(Provincias_mayor) #Cambiamos la geometry por el centroide
provincias_points <- cbind(Provincias_mayor, st_coordinates(st_centroid(Provincias_mayor$geometry)))

ggplot() + geom_sf(data = dfLaura) + geom_sf(data = Provincias_mayor, fill = "green")+ coord_sf(ylim = c(35,45), xlim = c(-10,5)) + theme_minimal() + labs (title = "Mapa 5: Provincias con más personas llamadas Laura", size = 3)  + geom_text(data = provincias_points, 
            aes(x = X, y = Y, label = NombreProv), 
            color = "Black", fontface = "bold", check_overlap = TRUE, size = 2.5) + theme_test()

#Mapa de las provincias con menos personas llamadas Laura
Provincias_menor<- dfLaura %>% slice_min(Total, n = 5)
provincias_points <- st_centroid(Provincias_menor) #Cambiamos la geometry por el centroide
provincias_points <- cbind(Provincias_menor, st_coordinates(st_centroid(Provincias_menor$geometry)))

ggplot() + geom_sf(data = dfLaura) + geom_sf(data = Provincias_menor, fill = "red")+ coord_sf(ylim = c(35,45), xlim = c(-10,5)) + theme_minimal() + labs (title = "Mapa 6: Provincias con menos personas llamadas Laura", size = 3)  + geom_text(data = provincias_points,
            aes(x = X, y = Y, label = NombreProv), 
            color = "White", fontface = "bold", check_overlap = TRUE, size = 2.5) +theme_test()

Aquí observamos que las provincias donde abunda el nombre Laura son: Madrid, Barcelona y Valencia. Por otra parte, donde el nombre Laura es menos típico es en Teruel, Soria y Segovia.

4.4. GRÁFICO ANIMADO

Hemos querido ver como ha evolucionado la frecuencia de nuestros nombres durante las distintas décadas en España. Para ello, hemos realizado un gráfico de líneas dinámico o animado, por el cual, las lineas crecen o decrecen conforme la frecuencia de nuestros nombres aumenta o disminuye a través de las diferentes décadas hasta 2010.

Para ello, antes de nada hemos obtenido dos EXCEL del INE con la evolución de nuestros nombres (“Daniel” y “Laura”) y hemos manipulado los datos para poder crear así el gráfico animado.



#DANIEL
DecadaDaniel <- read_excel("Datos/DecadaDaniel.xls")

DecadaDaniel1<- DecadaDaniel %>% select(Nombre, Províncias, `1930`, `1940`, `1950`, `1950`, `1960`, `1970`, `1980`, `1990`, `2000`,`2010`)

DecadaDaniel2 <- DecadaDaniel1 %>% pivot_longer(cols=3:11,names_to="año",values_to="frecuencia")

DecadaDanielDEF <- DecadaDaniel2 %>% filter(!is.na(frecuencia)) %>% group_by(Nombre,año) %>% summarise(suma=sum(frecuencia))


#LAURA
DecadaLaura<- read_excel("Datos/DecadaLaura.xls")


DecadaLaura1<- DecadaLaura %>% select(Nombre, Províncias, `1930`, `1940`, `1950`, `1950`, `1960`, `1970`, `1980`, `1990`, `2000`,`2010`)

DecadaLaura2 <- DecadaLaura1 %>% pivot_longer(cols=3:11,names_to="año",values_to="frecuencia")

DecadaLauraDEF <- DecadaLaura2 %>% filter(!is.na(frecuencia)) %>% group_by(Nombre,año) %>% summarise(suma=sum(frecuencia))


DecadaJuntos<- full_join(DecadaDanielDEF,DecadaLauraDEF) %>% mutate(año1= as.numeric(as.character(año))) %>% select(Nombre,año1,suma)

5. COMENTARIO FINAL

Para concluir el trabajo, comentar que hemos aprendido sobre las diferentes maneras de mostrar los datos, así como manipular estos de distintas formas, hacer gráficos interactivos y animados, además de los tradicionales gráficos de barras. También hemos aprendido como implementar mapas, transformarlos y extraer información útil de ellos.

El tema que hemos escogido, lo hemos escogido por la curiosidad que nos surgía saber si teníamos un nombre y apellido común, por conocer la frecuencia de estos en nuestro territorio y por ser un tema un poco más distendido, no queríamos estar únicamente manipulando números, queríamos hacer algo un poco diferente, pero, con la información suficiente como para poder realizar distintas transformaciones y así poder realizar diferentes tareas con estas.

REFERENCIAS

Para la realización del trabajo hemos utilizado:




Para acabar este chunk para incluir tu session info:

sessioninfo::session_info() %>% details::details(summary = 'current session info') 

current session info


─ Session info ───────────────────────────────────────────────────────────────
 setting  value                       
 version  R version 4.0.2 (2020-06-22)
 os       macOS Catalina 10.15.7      
 system   x86_64, darwin17.0          
 ui       X11                         
 language (EN)                        
 collate  es_ES.UTF-8                 
 ctype    es_ES.UTF-8                 
 tz       Europe/Madrid               
 date     2020-12-17                  

─ Packages ───────────────────────────────────────────────────────────────────
 package       * version    date       lib
 assertthat      0.2.1      2019-03-21 [1]
 backports       1.1.10     2020-09-15 [1]
 base64enc       0.1-3      2015-07-28 [1]
 blob            1.2.1      2020-01-20 [1]
 broom           0.7.0      2020-07-09 [1]
 cellranger      1.1.0      2016-07-27 [1]
 class           7.3-17     2020-04-26 [1]
 classInt        0.4-3      2020-04-07 [1]
 cli             2.0.2      2020-02-28 [1]
 colorspace      1.4-1      2019-03-18 [1]
 cpp11           0.2.1      2020-08-11 [1]
 crayon          1.3.4      2017-09-16 [1]
 crosstalk     * 1.1.0.1    2020-03-13 [1]
 data.table      1.13.0     2020-07-24 [1]
 DBI             1.1.0      2019-12-15 [1]
 dbplyr          1.4.4      2020-05-27 [1]
 digest          0.6.25     2020-02-23 [1]
 dplyr         * 1.0.2      2020-08-18 [1]
 e1071           1.7-3      2019-11-26 [1]
 ellipsis        0.3.1      2020-05-15 [1]
 evaluate        0.14       2019-05-28 [1]
 extrafont       0.17       2014-12-08 [1]
 extrafontdb     1.0        2012-06-11 [1]
 fansi           0.4.1      2020-01-08 [1]
 farver          2.0.3      2020-01-16 [1]
 fastmap         1.0.1      2019-10-08 [1]
 forcats       * 0.5.0      2020-03-01 [1]
 formatR         1.7        2019-06-11 [1]
 fs              1.5.0      2020-07-31 [1]
 gdtools         0.2.2      2020-04-03 [1]
 generics        0.1.0      2020-10-31 [1]
 gganimate     * 1.0.7      2020-10-15 [1]
 ggplot2       * 3.3.2      2020-06-19 [1]
 ggrepel       * 0.8.2      2020-03-08 [1]
 ggThemeAssist * 0.1.5.9001 2020-11-13 [1]
 gifski          0.8.6      2018-09-28 [1]
 glue            1.4.2      2020-08-27 [1]
 gtable          0.3.0      2019-03-25 [1]
 haven           2.3.1      2020-06-01 [1]
 hms             0.5.3      2020-01-08 [1]
 hrbrthemes    * 0.8.0      2020-03-06 [1]
 htmltools       0.5.0      2020-06-16 [1]
 htmlwidgets     1.5.1      2019-10-08 [1]
 httpuv          1.5.4      2020-06-06 [1]
 httr            1.4.2      2020-07-20 [1]
 jsonlite        1.7.1      2020-09-07 [1]
 KernSmooth      2.23-17    2020-04-26 [1]
 klippy        * 0.0.0.9500 2020-11-17 [1]
 knitr         * 1.29       2020-06-23 [1]
 labeling        0.3        2014-08-23 [1]
 later           1.1.0.1    2020-06-05 [1]
 lazyeval        0.2.2      2019-03-15 [1]
 lifecycle       0.2.0      2020-03-06 [1]
 lubridate       1.7.9      2020-06-08 [1]
 magrittr        1.5        2014-11-22 [1]
 mime            0.9        2020-02-04 [1]
 miniUI          0.1.1.1    2018-05-18 [1]
 modelr          0.1.8      2020-05-19 [1]
 munsell         0.5.0      2018-06-12 [1]
 patchwork     * 1.1.0      2020-11-09 [1]
 pillar          1.4.6      2020-07-10 [1]
 pkgconfig       2.0.3      2019-09-22 [1]
 plotly        * 4.9.2.1    2020-04-04 [1]
 plyr            1.8.6      2020-03-03 [1]
 prettyunits     1.1.1      2020-01-24 [1]
 progress        1.2.2      2019-05-16 [1]
 promises        1.1.1      2020-06-09 [1]
 purrr         * 0.3.4      2020-04-17 [1]
 R6              2.4.1      2019-11-12 [1]
 RColorBrewer  * 1.1-2      2014-12-07 [1]
 Rcpp            1.0.5      2020-07-06 [1]
 reactable     * 0.2.3      2020-10-04 [1]
 reactR          0.4.3      2020-07-12 [1]
 readr         * 1.3.1      2018-12-21 [1]
 readxl        * 1.3.1      2019-03-13 [1]
 rematch         1.0.1      2016-04-21 [1]
 reprex          0.3.0      2019-05-16 [1]
 rlang           0.4.7      2020-07-09 [1]
 rmarkdown       2.3        2020-06-18 [1]
 rstudioapi      0.11       2020-02-07 [1]
 Rttf2pt1        1.3.8      2020-01-10 [1]
 rvest           0.3.6      2020-07-25 [1]
 scales          1.1.1      2020-05-11 [1]
 sessioninfo     1.1.1      2018-11-05 [1]
 sf            * 0.9-6      2020-09-13 [1]
 shiny           1.5.0      2020-06-23 [1]
 stringi       * 1.5.3      2020-09-09 [1]
 stringr       * 1.4.0      2019-02-10 [1]
 systemfonts     0.3.1      2020-09-08 [1]
 tibble        * 3.0.3      2020-07-10 [1]
 tidyr         * 1.1.2      2020-08-27 [1]
 tidyselect      1.1.0      2020-05-11 [1]
 tidyverse     * 1.3.0      2019-11-21 [1]
 tweenr          1.0.1      2018-12-14 [1]
 units           0.6-7      2020-06-13 [1]
 vctrs           0.3.4      2020-08-29 [1]
 viridisLite     0.3.0      2018-02-01 [1]
 withr           2.2.0      2020-04-20 [1]
 xfun            0.17       2020-09-09 [1]
 xml2            1.3.2      2020-04-23 [1]
 xtable          1.8-4      2019-04-21 [1]
 yaml            2.2.1      2020-02-01 [1]
 source                                   
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.1)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 Github (calligross/ggthemeassist@35b720f)
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 Github (rlesur/klippy@378c247)           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.1)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           
 CRAN (R 4.0.2)                           

[1] /Library/Frameworks/R.framework/Versions/4.0/Resources/library


LS0tCnRpdGxlOiA8Y2VudGVyPiBOT01CUkVTIFkgQVBFTExJRE9TIEVOIEVTUEHDkUEgPC9jZW50ZXI+CmF1dGhvcjogIk1pZW1icm9zIGRlbCBncnVwbzogXG5cblxuICoqRGFuaWVsIENhc2lubyoqIChkYWNhYmE0QGFsdW1uaS51di5lcyksIFxuXG4gKipMYXVyYSBCb3Jyw6FzKiogKGxhdWJvcGFAYWx1bW5pLnV2LmVzKSBcblxuICoqTGF1cmEgQWxiZXJ0KiogKGxhdWFsbW9zQGFsdW1uaS51di5lcykgXG5cbiBVbml2ZXJzaXRhdCBkZSBWYWzDqG5jaWEiCmRhdGU6ICJEaWNpZW1icmUgZGUgMjAyMCAoYWN0dWFsaXphZG8gZWwgYHIgZm9ybWF0KFN5cy50aW1lKCksICclZC0lbS0lWScpYCkiCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgdGhlbWU6IHJlYWRhYmxlCiAgICBoaWdobGlnaHQ6IHB5Z21lbnRzIAogICAgdG9jOiB0cnVlCiAgICB0b2NfZGVwdGg6IDMgCiAgICB0b2NfZmxvYXQ6IAogICAgICBjb2xsYXBzZWQ6IHRydWUKICAgICAgc21vb3RoX3Njcm9sbDogdHJ1ZQogICAgc2VsZl9jb250YWluZWQ6IHRydWUKICAgIG51bWJlcl9zZWN0aW9uczogZmFsc2UKICAgIGRmX3ByaW50OiBrYWJsZQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQplZGl0b3Jfb3B0aW9uczogCiAgY2h1bmtfb3V0cHV0X3R5cGU6IGNvbnNvbGUKLS0tCgpgYGB7ciBwYWNrYWdlcy1zZXR1cCwgaW5jbHVkZSA9IEZBTFNFfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShrbGlwcHkpICAjLSByZW1vdGVzOjppbnN0YWxsX2dpdGh1Yigicmxlc3VyL2tsaXBweSIpCmxpYnJhcnkoa25pdHIpCmxpYnJhcnkocmVhZHhsKQpsaWJyYXJ5KHJlYWN0YWJsZSkKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KHN0cmluZ2kpCmxpYnJhcnkoZ2dUaGVtZUFzc2lzdCkKbGlicmFyeShwbG90bHkpCmxpYnJhcnkocGF0Y2h3b3JrKQpsaWJyYXJ5KGdncmVwZWwpCmxpYnJhcnkoc2YpCmxpYnJhcnkoY3Jvc3N0YWxrKQpsaWJyYXJ5KGdnYW5pbWF0ZSkKbGlicmFyeShocmJydGhlbWVzKQpsaWJyYXJ5KHNmKQpsaWJyYXJ5KFJDb2xvckJyZXdlcikKYGBgCgpgYGB7ciBjaHVuay1zZXR1cCwgaW5jbHVkZSA9IEZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsIGV2YWwgPSBUUlVFLCBtZXNzYWdlID0gRkFMU0UsIHdhcm5pbmcgPSBGQUxTRSwgCiAgICAgICAgICAgICAgICAgICAgICAjcmVzdWx0cyA9ICJob2xkIiwKICAgICAgICAgICAgICAgICAgICAgIGNhY2hlID0gRkFMU0UsIGNhY2hlLnBhdGggPSAiL2NhY2hlcy8iLCBjb21tZW50ID0gIiM+IiwKICAgICAgICAgICAgICAgICAgICAgICNmaWcud2lkdGggPSA3LCAjZmlnLmhlaWdodD0gNywgICAKICAgICAgICAgICAgICAgICAgICAgICNvdXQud2lkdGggPSA3LCBvdXQuaGVpZ2h0ID0gNywKICAgICAgICAgICAgICAgICAgICAgIGNvbGxhcHNlID0gVFJVRSwgIGZpZy5zaG93ID0gImhvbGQiLAogICAgICAgICAgICAgICAgICAgICAgZmlnLmFzcCA9IDcvOSwgb3V0LndpZHRoID0gIjYwJSIsIGZpZy5hbGlnbiA9ICJjZW50ZXIiKQprbml0cjo6b3B0c19jaHVuayRzZXQoZGV2ID0gInBuZyIsIGRldi5hcmdzID0gbGlzdCh0eXBlID0gImNhaXJvLXBuZyIpKQpgYGAKCmBgYHtyIG9wdGlvbnMtc2V0dXAsIGluY2x1ZGUgPSBGQUxTRX0Kb3B0aW9ucyhzY2lwZW4gPSA5OTkpIApvcHRpb25zKCJ5YW1sLmV2YWwuZXhwciIgPSBUUlVFKSAKYGBgCgoKYGBge3Iga2xpcHB5LCBlY2hvID0gRkFMU0V9CmtsaXBweTo6a2xpcHB5KHBvc2l0aW9uID0gYygidG9wIiwgInJpZ2h0IikpICMtIHJlbW90ZXM6Omluc3RhbGxfZ2l0aHViKCJybGVzdXIva2xpcHB5IikKYGBgCjxkaXYgc3R5bGU9InRleHQtYWxpZ246IGp1c3RpZnkiPjxkaXYvPgotLS0tLS0tLS0tLS0tLS0tLQoKPGJyPgoKRXN0ZSBlcyBudWVzdHJvIGluZm9ybWUgcGFyYSBsYSBwcmVzZW50YWNpw7NuIGRlbCBkw61hIDE4IGRlIGRpY2llbWJyZS4gQXF1w60gY29tZW50YXJlbW9zIGRlIHF1ZSB0cmF0YSBudWVzdHJvIHRyYWJham8geSBsYXMgdHJhbnNmb3JtYWNpb25lcyBxdWUgaGVtb3MgcmVhbGl6YWRvLCBhc8OtIGNvbW8sIGVsIGPDs2RpZ28gZGUgZXN0YXMgeSBsb3MgZGlmZXJlbnRlcyBwYXF1ZXRlcyB1dGlsaXphZG9zLgoKIyMgMS4gSU5UUk9EVUNDScOTTgoKTnVlc3RybyB0cmFiYWpvIGNvbnNpc3RlIGVuIGxhICoqbWFuaXB1bGFjacOzbiBkZSBkYXRvcyBkZWwgSU5FIGVuIGxvIHJlZmVyZW50ZSBhIG5vbWJyZXMgeSBhcGVsbGlkb3MgZW4gRXNwYcOxYS4qKiAKUGFyYSBlc3RvLCBkZXNjYXJnYXJlbW9zIGRlc2RlIFIgbG9zIGRhdG9zIGRlIGZyZWN1ZW5jaWEgZGUgbm9tYnJlcyB5IGFwZWxsaWRvcyBlc3Bhw7FvbGVzIGRlbCBJTkUgeSB0YW1iacOpbiBkZXNjYXJnYXJlbW9zIHVuIGV4Y2VsIGRlIGZvcm1hIG1hbnVhbCBkZSBsYSBkaXN0cmlidWNpw7NuIGdlb2dyw6FmaWNhIHByb3ZpbmNpYWwgZGUgbnVlc3RybyBub21icmUgeSBwcmltZXIgYXBlbGxpZG8uCgoKIyMgMi4gIENBUkdBTU9TIERBVE9TIFkgUEFRVUVURVMKClZhbW9zIGEgY2FyZ2FyIGRpZmVyZW50ZXMgcGFxdWV0ZXMgcXVlIGlyZW1vcyB1dGlsaXphbmRvIGEgbG8gbGFyZ28gZGVsIHRyYWJham8uCgpgYGB7ciBlY2hvPVRSVUUsIGV2YWw9IEZBTFNFfQoKI0hhYnLDrWEgcXVlIGhhY2VyIHVuIGluc3RhbGwucGFja2FnZXMoIiAiKSBjb24gY2FkYSB1bm8gc2kgbm8gbG9zIHR1dmllcmFtb3MgeWEgZW4gbnVlc3RyYSBiaWJsaW90ZWNhLgojIGxpYnJhcnkodGlkeXZlcnNlKQojIGxpYnJhcnkoa2xpcHB5KSAgIy0gcmVtb3Rlczo6aW5zdGFsbF9naXRodWIoInJsZXN1ci9rbGlwcHkiKQojIGxpYnJhcnkoa25pdHIpCiMgbGlicmFyeShyZWFkeGwpCiMgbGlicmFyeShyZWFjdGFibGUpCiPCoGxpYnJhcnkoZ2dwbG90MikKIyBsaWJyYXJ5KHN0cmluZ2kpCiPCoGxpYnJhcnkoZ2dUaGVtZUFzc2lzdCkKIyBsaWJyYXJ5KHBsb3RseSkKIyBsaWJyYXJ5KHBhdGNod29yaykKIyBsaWJyYXJ5KGdncmVwZWwpCiPCoGxpYnJhcnkoc2YpCiMgbGlicmFyeShjcm9zc3RhbGspCiPCoGxpYnJhcnkoZ2dhbmltYXRlKQojIGxpYnJhcnkoaHJicnRoZW1lcykKIyBsaWJyYXJ5KHNmKQojIGxpYnJhcnkoUkNvbG9yQnJld2VyKQpgYGAKCkFob3JhIGRlc2NhcmdhcmVtb3MgbG9zIGRpZmVyZW50ZXMgaW5mb3JtZXMgcGFyYSBtYW5pcHVsYXJsb3MgeSBsb3MgdHJhbnNmb3JtYXJlbW9zIHBhcmEgcG9kZXIgaGFjZXJsb3MgdmlzaWJsZXMuIApUZW5kcmVtb3MgMiBkYXRhZnJhbWVzIGRlIGFwZWxsaWRvcywgdW5vIHBhcmEgZnJlY3VlbmNpYSA+MTAwIHkgb3Ryb3MgcGFyYSBmcmVjdWVuY2lhIDwxMDAgeSA+MjAuCkFzw60gbWlzbW8sIHRlbmRyZW1vcyAyIGRhdGFmcmFtZXMgZGUgbm9tYnJlcywgdW5vIHBhcmEgaG9tYnJlcyB5IG90cm8gcGFyYSBtdWplcmVzLgpgYGB7ciBlY2hvID0gVFJVRSwgZXZhbD1UUlVFfQojQVBFTExJRE9TCiMtIGRlc2NhcmdhbW9zIGxvcyBkYXRvcyBlbiAiLi9EYXRvcy9mcmVjdWVuY2lhLnhscyIKCiMgdXJsIDwtICJodHRwczovL3d3dy5pbmUuZXMvZGFjby9kYWNvNDIvbm9tYnlhcGVsL2FwZWxsaWRvc19mcmVjdWVuY2lhLnhscyIKIyBhcmNoaXZvX2RlX2Rlc3Rpbm8gPC0gaGVyZTo6aGVyZSgiRGF0b3MiLCAiZnJlY3VlbmNpYS54bHMiKQojIGRvd25sb2FkLmZpbGUodXJsLCBhcmNoaXZvX2RlX2Rlc3Rpbm8pCgojLSBWYW1vcyBhIGltcG9ydGFyIGxvcyBkYXRvcyB0aXBvIGV4Y2VsIGNvbiBsYSBmdW5jacOzbiByZWFkeGwgeSBtZWRpYW50ZSBlbCBzaGVldD0xIGNvZ2VyZW1vcyBsYSBIT0pBIDEgZGVsIGV4Y2VsIHkgbWVkaWFudGUgZWwgcmFuZ2UsIGNvZ2VyZW1vcyBkZXNkZSBlbCBPcmRlbiBoYXN0YSBlbCDDumx0aW1vIHRvdGFsLCB5YSBxdWUsIHNpIGltcG9ydGFtb3MgZGlyZWN0YW1lbnRlIGVsIEVYQ0VMIHRlbmRyaWFtb3MgcXVlIGVsaW1pbmFyIGFsZ3VuYXMgZGUgbGFzIHByaW1lcmFzIGZpbGFzLCBwb3IgbG8gcXVlLCBtZWRpYW50ZSBlc3RvIHlhIGxvIHRlbmVtb3MgY29tbyBxdWVyZW1vcy4KZGZfYXBlbGxpZG9zMSA8LSByZWFkX2V4Y2VsICgiLi9EYXRvcy9mcmVjdWVuY2lhLnhscyIsIHNoZWV0PTEsIHJhbmdlPSJBNTpFMjU3OTgiKQpkZl9hcGVsbGlkb3MyIDwtIHJlYWRfZXhjZWwgKCIuL0RhdG9zL2ZyZWN1ZW5jaWEueGxzIiwgc2hlZXQ9MiwgcmFuZ2U9IkE1OkU1MDM5MyIpCgoKI05PTUJSRVMKCiMgdXJsMiA8LSAiaHR0cHM6Ly93d3cuaW5lLmVzL2RhY28vZGFjbzQyL25vbWJ5YXBlbC9ub21icmVzX3Bvcl9lZGFkX21lZGlhLnhscyIKIyBhcmNoaXZvX2RlX2Rlc3Rpbm8yIDwtIGhlcmU6OmhlcmUoIkRhdG9zIiwgImZyZWN1ZW5jaWFub21icmUueGxzIikKIyBkb3dubG9hZC5maWxlKHVybDIsIGFyY2hpdm9fZGVfZGVzdGlubzIpCgojIFZhbW9zIGEgaW1wb3J0YXIgbG9zIGRhdG9zIHRpcG8gZXhjZWwgY29uIGxhIGZ1bmNpw7NuIHJlYWR4bCB5IG1lZGlhbnRlIGVsIHNoZWV0PTEgY29nZXJlbW9zIGxhIEhPSkEgMSBkZWwgZXhjZWwgeSBtZWRpYW50ZSBlbCByYW5nZSwgY29nZXJlbW9zIGRlc2RlIGVsIE9yZGVuIGhhc3RhIGVsIMO6bHRpbW8gdG90YWwsIHlhIHF1ZSwgc2kgaW1wb3J0YW1vcyBkaXJlY3RhbWVudGUgZWwgRVhDRUwgdGVuZHJpYW1vcyBxdWUgZWxpbWluYXIgYWxndW5hcyBkZSBsYXMgcHJpbWVyYXMgZmlsYXMsIHBvciBsbyBxdWUsIG1lZGlhbnRlIGVzdG8geWEgbG8gdGVuZW1vcyBjb21vIHF1ZXJlbW9zLgpkZl9ub21icmUxIDwtIHJlYWRfZXhjZWwgKCIuL0RhdG9zL2ZyZWN1ZW5jaWFub21icmUueGxzIiwgc2hlZXQ9MSwgcmFuZ2U9IkE3OkQyNTc5MCIpCmRmX25vbWJyZSA8LSByZWFkX2V4Y2VsICgiLi9EYXRvcy9mcmVjdWVuY2lhbm9tYnJlLnhscyIsIHNoZWV0PTIsIHJhbmdlPSJBNzpEMjY0OTkiKQoKCgojRGFuaWVsIHkgTGF1cmEgZnJlY3VlbmNpYSB5IHByb3ZpbmNpYXMKZGZfRGFuaWVsIDwtIHJlYWRfZXhjZWwgKCIuL0RhdG9zL0RhbmllbF9MYXVyYTIueGxzeCIsIHNoZWV0PTEpCmRmX0xhdXJhIDwtIHJlYWRfZXhjZWwgKCIuL0RhdG9zL0RhbmllbF9MYXVyYTIueGxzeCIsIHNoZWV0PTIpCgoKCgpgYGAKCgoKIyMgMy4gTU9ESUZJQ0FNT1MgTlVFU1RST1MgREFUQUZSQU1FUwpTaSBhYnJpZXNlbW9zIGxvcyBkYXRhZnJhbWVzIGRlIGFwZWxsaWRvcywgdmVtb3MgcXVlIGFwYXJlY2VuIHZhcmlhcyB2YXJpYWJsZXMgcXVlIHNlIGxsYW1hbiAiVG90YWwiIGxhcyBjdWFsZXMgdmFuIHJlZmVyaWRhcyBhIGFsZ28uIFZhbW9zIGEgbW9kaWZpY2FyIGxvcyBub21icmVzIHBvciBhcXVlbGxvIGEgbG8gcXVlIGNvcnJlc3BvbmRlcyBlc29zICJ0b3RhbGVzIi4KYGBge3IgZWNobyA9IFRSVUUsIGV2YWw9VFJVRX0KCiNNb2RpZmljYW1vcyBsb3Mgbm9tYnJlcyBkZSBsYXMgY29sdW1uYXMgcXVlIHNlIGxsYW1hbiB0b3RhbCwgcG9yIGFxdWVsbG8gYSBsbyBxdWUgbGUgY29ycmVzcG9uZGUgKGVzIHVuIHRvdGFsLCBwZXJvIHVuIHRvdGFsIGRlIGFsZ28sIGxvIGxsYW1hcmVtb3MgY29uZm9ybWUgZXNlIEFMR08pCmRmX2FwZWxsaWRvczEgPC0gZGZfYXBlbGxpZG9zMSAlPiUgcmVuYW1lKEZyZWNfMWVyX0FwZWxsaWRvID0gVG90YWwuLi4zLAogIEZyZWNfMm9fQXBlbGxpZG89IFRvdGFsLi4uNCwKICBGcmVjX0FtYm9zX0FwZWxsaWRvcz0gVG90YWwuLi41KQoKZGZfYXBlbGxpZG9zMiA8LSBkZl9hcGVsbGlkb3MyICU+JSByZW5hbWUoRnJlY18xZXJfQXBlbGxpZG8gPSBUb3RhbC4uLjMsCiAgRnJlY18yb19BcGVsbGlkbz0gVG90YWwuLi40LAogIEZyZWNfQW1ib3NfQXBlbGxpZG9zPSBUb3RhbC4uLjUpCgoKZGZfYXBlbGxpZG9zbW9kaWYgPC0gc3VwcHJlc3NXYXJuaW5ncyh0cmFuc2Zvcm0oZGZfYXBlbGxpZG9zMiwgRnJlY18yb19BcGVsbGlkbz0gYXMubnVtZXJpYyhGcmVjXzJvX0FwZWxsaWRvKSwKICBGcmVjX0FtYm9zX0FwZWxsaWRvcz1hcy5udW1lcmljKEZyZWNfQW1ib3NfQXBlbGxpZG9zKQogICkKICApCmBgYAoKCgojIyA0LiBUUkFOU0ZPUk1BQ0lPTkVTCiMjIyA0LjEgVEFCTEFTCkFob3JhLCB2YW1vcyBhIG1hbmlwdWxhciBudWVzdHJvcyBkYXRhZnJhbWVzIHBhcmEgaGFjZXIgY2llcnRhcyBjb25zdHJ1Y2Npb25lcywgZW4gZXN0ZSBjYXNvIGVtcGV6YXJlbW9zIGNvbiB1bmFzICoqdGFibGFzLioqIEVzdGFzLCB2YW4gYSByZWNvZ2VyIGxvcyBub21icmVzIHkgYXBlbGxpZG9zIGFncnVwYWRvcyBwb3IgbGEgbGV0cmEgcXVlIGVtcGllY2VuIHkgY29uIGRpc3RpbnRvcyBjb2xvcmVzIGRlIGNlbGRhIGRlcGVuZGllbmRvIGxhIGZyZWN1ZW5jaWEsIHNpZW5kbyB2ZXJkZSBmcmVjdWVuY2lhIGFsdGEsIG5hcmFuamEgZnJlY3VlbmNpYSBtZWRpYSB5IHJvam8gZnJlY3VlbmNpYSBiYWphLCBlcyBkZWNpciwgcG9jbyBmcmVjdWVudGVzLgoKUHJpbWVybyBkZSB0b2RvLCBuZWNlc2l0YXJlbW9zIHVuaXIgYW1iYXMgdGFibGFzLCB0YW50byBkZSBub21icmVzIGNvbW8gZGUgYXBlbGxpZG9zIGVuIHVuYSBzb2xhLgoKYGBge3IgZWNobz0gVFJVRSwgZXZhbD1UUlVFfQojQVBFTExJRE9TCmRmX2FwZWxsaWRvc19jb25qdW50b3MgPC0gZnVsbF9qb2luKGRmX2FwZWxsaWRvczEsIGRmX2FwZWxsaWRvc21vZGlmLCBieT0gYygiT3JkZW4iLCJBcGVsbGlkbyIsIkZyZWNfMWVyX0FwZWxsaWRvIiwiRnJlY18yb19BcGVsbGlkbyIsIkZyZWNfQW1ib3NfQXBlbGxpZG9zIikpCgpkZl9hcGVsbGlkb3NfY29uanVudG9zMiA8LSBkZl9hcGVsbGlkb3NfY29uanVudG9zICU+JQogIG11dGF0ZShMZXRyYT0gc3RyaV9zdWIoQXBlbGxpZG8sMSwxKSkgJT4lCiAgYXJyYW5nZShMZXRyYSkKCgojTk9NQlJFUwpkZl9ub21icmVIPC0gZGZfbm9tYnJlMSAlPiUKICBtdXRhdGUoU2V4bz0iSG9tYnJlIikgJT4lCiAgcmVuYW1lKEVkYWQ9IGBFZGFkIE1lZGlhICgqKWApJT4lCiAgc2VsZWN0KC1jKE9yZGVuKSkKCmRmX25vbWJyZU0gPC0gZGZfbm9tYnJlICU+JQogIG11dGF0ZShTZXhvPSJNdWplciIpICU+JQogIHJlbmFtZShFZGFkPSBgRWRhZCBNZWRpYSAoKilgKSAlPiUKICBzZWxlY3QoLWMoT3JkZW4pKQoKCmRmX05vbWJyZXNKdW50b3M8LSBmdWxsX2pvaW4oZGZfbm9tYnJlSCwgZGZfbm9tYnJlTSwgYnk9IGMoIk5vbWJyZSIsIkZyZWN1ZW5jaWEiLCJFZGFkIiwiU2V4byIpKSAlPiUgYXJyYW5nZShkZXNjKEZyZWN1ZW5jaWEpKQoKZGZfTm9tYnJlc0p1bnRvczIgPC0gZGZfTm9tYnJlc0p1bnRvcyAlPiUKICBtdXRhdGUoTGV0cmE9IHN0cmlfc3ViKE5vbWJyZSwxLDEpKSAlPiUKICBhcnJhbmdlKExldHJhKQoKYGBgCgpEZSBlc3RhIGZvcm1hLCBoYXJlbW9zIHVuYSB0YWJsYSBjb24gYnVzY2Fkb3IgZGUgKipOT01CUkVTKiogeSBvdHJhIHBhcmEgKipBUEVMTElET1MqKgoKIyMjIyA0LjEuMSBUQUJMQSBOT01CUkVTCmBgYHtyIGVjaG8gPSBGQUxTRSwgZXZhbD1UUlVFfQoKZGF0YSA8LSBTaGFyZWREYXRhJG5ldyhkZl9Ob21icmVzSnVudG9zMikKCmJzY29scygKICB3aWR0aHMgPSBjKDMsNiksCiAgbGlzdCgKICAgIGZpbHRlcl9jaGVja2JveCgiTGV0cmEiLCJMZXRyYSIsIGRhdGEsIH5MZXRyYSwgY29sdW1ucyA9IDMpLAogICAgZmlsdGVyX3NsaWRlcigiRnJlY3VlbmNpYSIsIkZyZWN1ZW5jaWEiLGRhdGEsIH5GcmVjdWVuY2lhLCB3aWR0aCA9ICIxMDAlIikKICApLApyZWFjdGFibGUoZGF0YSwKICBjb2x1bW5zPSBsaXN0KEZyZWN1ZW5jaWE9IGNvbERlZigKICAgIGFsaWduPSJjZW50ZXIiLAogIHN0eWxlID0gZnVuY3Rpb24odmFsdWUsIGluZGV4LCBuYW1lLCBtZWRpYSkgewogICAgaWYgKGlzLm51bWVyaWModmFsdWUpICYmIHZhbHVlID49IDI1MDAwKSB7CiAgICAgIGxpc3QoZm9udFdlaWdodCA9ICJib2xkIiwgYmFja2dyb3VuZCA9ICJyZ2JhKDAsMjU1LDAsMC4zKSIpCgogICAgfWVsc2UgaWYgKGlzLm51bWVyaWModmFsdWUpICYmIHZhbHVlID49IG1lYW4oZGZfTm9tYnJlc0p1bnRvczIkRnJlY3VlbmNpYSkpewogICAgICBsaXN0KGZvbnRXZWlnaHQ9ImJvbGQiLCBiYWNrZ3JvdW5kPSJyZ2JhKDI1NSwyNTUsMCwwLjMpIikKCiAgICB9ZWxzZXsKICAgICAgICBsaXN0KGZvbnRXZWlnaHQ9ImJvbGQiLCBiYWNrZ3JvdW5kPSJyZ2JhKDI1NSwwLDAsMC4zKSIpCiAgICAgIH0KICB9KSwKICAgIE5vbWJyZT1jb2xEZWYoCiAgICAgIGFsaWduPSJjZW50ZXIiCiAgICApLAogICAgRWRhZD1jb2xEZWYoCiAgICAgIGFsaWduPSJjZW50ZXIiCiAgICApLAogICAgU2V4bz1jb2xEZWYoCiAgICAgIGFsaWduPSJjZW50ZXIiCiAgICApLAogICAgTGV0cmE9Y29sRGVmKAogICAgICBhbGlnbj0iY2VudGVyIgogICAgKQopLAogIHJlc2l6YWJsZT0gVFJVRSwKICBzaG93UGFnZVNpemVPcHRpb25zID0gVFJVRSwKICBvdXRsaW5lZCA9IFRSVUUsCiAgYm9yZGVyZWQgPSBUUlVFLAogIHRoZW1lID0gcmVhY3RhYmxlVGhlbWUoCiAgICBib3JkZXJDb2xvciA9ICIjI2ExYTFhMSIsCiAgICBzZWFyY2hJbnB1dFN0eWxlID0gbGlzdCh3aWR0aCA9ICIxMDAlIikKICApLAogIHNlYXJjaGFibGUgPSBUUlVFLAogIHBhZ2luYXRpb25UeXBlID0gInNpbXBsZSIsCiAgbGFuZ3VhZ2UgPSByZWFjdGFibGVMYW5nKAogICAgc2VhcmNoUGxhY2Vob2xkZXIgPSAiQnVzY2FyLi4uIiwKICAgIG5vRGF0YSA9ICJObyBoYXkgcmVzdWx0YWRvcyIsCiAgICBwYWdlSW5mbyA9ICJ7cm93U3RhcnR9IGRlIHtyb3dFbmR9IGRlIGxhcyB7cm93c30gZW50cmFkYXMiLAogICAgcGFnZVByZXZpb3VzID0gIlx1Mjc2ZSIsCiAgICBwYWdlTmV4dCA9ICJcdTI3NmYiLAogICAgcGFnZVByZXZpb3VzTGFiZWwgPSAiUMOhZ2luYSBhbnRlcmlvciIsCiAgICBwYWdlTmV4dExhYmVsID0gIlDDoWdpbmEgc2lndWllbnRlIgogICkKICApCikKCgpgYGAKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIyMjIDQuMS4yIFRBQkxBIEFQRUxMSURPUwpgYGB7ciBlY2hvID0gRkFMU0UsIGV2YWw9VFJVRX0KCnJlYWN0YWJsZSgKICBkZl9hcGVsbGlkb3NfY29uanVudG9zMiwKICBncm91cEJ5ID0gIkxldHJhIiwKICBib3JkZXJlZD0gVFJVRSwKICBzdHJpcGVkPVRSVUUsCiAgaGlnaGxpZ2h0ID0gVFJVRSwKICB0aGVtZT1yZWFjdGFibGVUaGVtZSgKICAgIHN0cmlwZWRDb2xvciA9ICIjZWRlZGVkIiwKICAgIGhpZ2hsaWdodENvbG9yID0gIiNiZmJmYmYiCiAgKSwKICBzZWFyY2hhYmxlID0gVFJVRSwKICBwYWdpbmF0aW9uVHlwZSA9ICJzaW1wbGUiLAogIGxhbmd1YWdlID0gcmVhY3RhYmxlTGFuZygKICAgIHNlYXJjaFBsYWNlaG9sZGVyID0gIkJ1c2Nhci4uLiIsCiAgICBub0RhdGEgPSAiTm8gaGF5IHJlc3VsdGFkb3MiLAogICAgcGFnZUluZm8gPSAie3Jvd1N0YXJ0fSBkZSB7cm93RW5kfSBkZSBsYXMge3Jvd3N9IGVudHJhZGFzIiwKICAgIHBhZ2VQcmV2aW91cyA9ICJcdTI3NmUiLAogICAgcGFnZU5leHQgPSAiXHUyNzZmIiwKICAgIHBhZ2VQcmV2aW91c0xhYmVsID0gIlDDoWdpbmEgYW50ZXJpb3IiLAogICAgcGFnZU5leHRMYWJlbCA9ICJQw6FnaW5hIHNpZ3VpZW50ZSIKICApCikKYGBgCgoKCgojIyMgNC4yLiBHUsOBRklDQVMgey50YWJzZXR9CgpQYXJhIGxvcyBncsOhZmljb3MsIGhhcmVtb3MgMyBncsOhZmljb3MgZGUgYmFycmFzLiBFbCBwcmltZXIgZ3LDoWZpY28gZXN0YSByZWxhY2lvbmFkbyBjb24gbG9zICoqMTAgbm9tYnJlcyBjb24gbcOhcyBlZGFkIG1lZGlhKiogeSBsb3MgKioxMCBub21icmVzIGNvbiBtZW5vcyBlZGFkIG1lZGlhLioqIFBvciBvdHJvIGxhZG8sIGxvcyBkb3MgZ3JhZmljb3Mgc2lndWllbnRlcyByZXByZXNlbnRhbiBsb3MgKioxMCBhcGVsbGlkb3MgbcOhcyBmcmVjdWVudGVzIHkgbG9zIDEwIG5vbWJyZXMgbcOhcyBmcmVjdWVudGVzLioqCgpQcmltZXJvLCBuZWNlc2l0YXJlbW9zIHRyYW5zZm9ybWFyIGxvcyBkYXRvczoKCmBgYHtyIGVjaG89IFRSVUUsIGV2YWw9VFJVRX0KI0FQRUxMSURPUwpkZl9hcGVsbGlkb3MgPC0gZGZfYXBlbGxpZG9zMSAlPiUgc2VsZWN0KEFwZWxsaWRvLCBGcmVjXzFlcl9BcGVsbGlkbywgRnJlY18yb19BcGVsbGlkbykgJT4lIG11dGF0ZShGcmVjX1RvdGFsPSBGcmVjXzFlcl9BcGVsbGlkbyArIEZyZWNfMm9fQXBlbGxpZG8pICU+JSBzbGljZV9tYXgoRnJlY19Ub3RhbCwgbj0xMCkgICNTZWxlY2Npb25hbW9zIGxhcyBjb2x1bW5hcyBkZSBhcGVsbGlkbywgRnJlY18xZXJfQXBlbGxpZG8geSBGcmVjXzJvX0FwZWxsaWRvIHF1ZSBzw7NuIGxhcyBxdWUgbmVjZXNpdGFyZW1vcyBwYXJhIG51ZXN0cm8gZ3LDoWZpY28sIGRlc3B1w6lzIG9idGVuZW1vcyBsYSBmcmVjdWVuY2lhIHRvdGFsIHN1bWFuZG8gbGEgZnJlY3VlbmNpYSBkZWwgcHJpbWVyIGFwZWxsaWRvIG3DoXMgbGEgZGVsIHNlZ3VuZG8geSBjb2dlbW9zIHNvbG8gbG9zIDEwIGFwZWxsaWRvcyBjb24gbWF5b3IgZnJlY3VlbmNpYS4KCiNvcmRlbmFyIGRlIG1heW9yIGEgbWVub3IKCmRmX2FwZWxsaWRvcyA8LSB0cmFuc2Zvcm0oZGZfYXBlbGxpZG9zLCBBcGVsbGlkbyA9IHJlb3JkZXIoQXBlbGxpZG8sIC1GcmVjX1RvdGFsKSkKCiNOT01CUkVTCmRmX25vbWJyZXMgPC0gZnVsbF9qb2luKGRmX25vbWJyZSwgZGZfbm9tYnJlMSkgI1RlbmVtb3MgZG9zIGRmIGRlIG5vbWJyZXMgdW5vIHBhcmEgbG9zIG5vbWJyZXMgZGUgaG9tYnJlIHkgb3RybyBwYXJhIGxvcyBub21icmVzIGRlIG11amVyLCBlbnRvbmNlcyBqdW50YW1vcyBsb3MgZG9zIGRmIHBhcmEgb2J0ZW5lciBzb2xvIHVuby4KCmRmX25vbWJyZXMzIDwtZGZfbm9tYnJlcyAlPiUgc2VsZWN0KE5vbWJyZSwgRnJlY3VlbmNpYSkgJT4lIHNsaWNlX21heChGcmVjdWVuY2lhLCBuPTEwKSAlPiUgbXV0YXRlKE5vbWJyZSA9IGZvcmNhdHM6OmFzX2ZhY3RvcihOb21icmUpKSAlPiUgbXV0YXRlKE5vbWJyZSA9IGZvcmNhdHM6OmZjdF9yZW9yZGVyKE5vbWJyZSwgRnJlY3VlbmNpYSkpICNTZWxlY2Npb25hbW9zIGxhcyBjb2x1bW5hcyBxdWUgbm9zIGludGVyZXNhbiBwYXJhIG51ZXN0cm8gZ3LDoWZpY28geSBzZWxlY2Npb25hbW9zIGxvcyAxMCBub21icmVzIGNvbiBtYXlvciBmcmVjdWVuY2lhLiBDb252ZXJ0aW1vcyBsYSB2YXJpYWJsZSBOb21icmUgYSBmYWN0b3IgY29uIGFzX2ZhY3RvcigpLiBEZXNwdcOpcyBvcmRlbmFtb3MgbGFzIGNvbHVtbmFzIGRlIG1lbm9yIGEgbWF5b3IgY29uIGZjdF9yZW9yZGVyKCkuCgoKYGBgCgo8YnI+CgojIyMjIEdSw4FGSUNPIERFIExPUyAxMCBOT01CUkVTIENPTiBNw4FTIEVEQUQgTUVESUEgWSBMT1MgMTAgTk9NQlJFUyBDT04gTUVOT1MgRURBRCBNRURJQQpgYGB7ciwgZmlnLndpZHRoPTUsZmlnLmhlaWdodD01MH0KbGlicmFyeSh0aWR5dmVyc2UpCgojMTAgTcOBUyBGUkVDVUVOVEVTIFkgMTAgUVVFIE1FTk9TCmRmX25vbWJyZXNfZWRhZG1lZGlhIDwtIGRmX25vbWJyZXMgJT4lIHNlbGVjdChOb21icmUsIGBFZGFkIE1lZGlhICgqKWApICU+JSBhcnJhbmdlKGRlc2MoYEVkYWQgTWVkaWEgKCopYCkpICU+JQogIHNsaWNlKGMoMSwyLDMsNCw1LDYsNyw4LDksMTAsbigpLTksbigpLTgsbigpLTcsbigpLTYsbigpLTUsbigpLTQsbigpLTMsbigpLTIsbigpLTEsIG4oKSkpJT4lCiAgbXV0YXRlKE5vbWJyZSA9IGZvcmNhdHM6OmFzX2ZhY3RvcihOb21icmUpKSAlPiUgbXV0YXRlKE5vbWJyZSA9IGZvcmNhdHM6OmZjdF9yZW9yZGVyKE5vbWJyZSwgYEVkYWQgTWVkaWEgKCopYCkpI1NlbGVjY2lvbmFtb3MgbGFzIHZhcmlhYmxlcyBub21icmUgeSBlZGFkIG1lZGlhIHBhcmEgZGVzcHXDqXMgcG9kZXIgaGFjZXIgZWwgZ3LDoWZpY28uIENvbiBhcnJhbmdlIG9yZGVuYW1vcyBsYSBFZGFkIE1lZGlhIGRlIG1heW9yIGEgbWVub3IgeSBjb24gc2xpY2Ugc2VsZWNjaW9uYW1vcyBsb3MgMTAgbm9tYnJlcyBjb24gbWF5b3IgeSBtZW5vciBtZWRpYS5Qb3Igw7psdGltbywgY29uIG11dGF0ZSBvcmRlbmFtb3MgZGUgbWF5b3IgYSBtZW5vci4KCnIgPC0gZ2dwbG90KGRmX25vbWJyZXNfZWRhZG1lZGlhLCBhZXMoTm9tYnJlLCBgRWRhZCBNZWRpYSAoKilgKSkgKyBnZW9tX2NvbChmaWxsPSJtZWRpdW1wdXJwbGUiKSArIGNvb3JkX2ZsaXAoKSArIHRoZW1lKHBsb3QuY2FwdGlvbiA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQuaXRhbGljIiksIAogICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfbGluZShzaXplID0gMC42KSwgCiAgICBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgCiAgICAgICAgZmFjZSA9ICJib2xkIiwgdmp1c3QgPSAwLDUpLCBheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCAKICAgICAgICBmYWNlID0gImJvbGQiKSwgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiLCBzaXplID0gOCwgCiAgICAgICAgaGp1c3QgPSAwLCB2anVzdCA9IDEsNSksIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJsYXZlbmRlciIpKSArbGFicyh0aXRsZSA9ICJMT1MgMTAgTk9NQlJFUyBDT04gTcOBUyBZIE1FTk9TIEVEQUQgTUVESUEiLAogICAgY2FwdGlvbiA9ICJEYXRvcyBwcm92ZW5pZW50ZXMgZGVsIElORSIpIAoKZ2dwbG90bHkocikKCmBgYAoKPGJyPgpFbiBlc3RlIGdyYWZpY28gaGVtb3MgcXVlcmlkbyBvYnNlcnZhciBjdWFsZXMgc8OzbiBsb3MgKioxMCBub21icmVzIGNvbiBtYXlvciBlZGFkIG1lZGlhIGVuIGNvbnRyYXBvc2ljacOzbiBjb24gbG9zIDEwIG5vbWJyZXMgY29uIG1lbm9zIGVkYWQgbWVkaWEuKiogTG9zIHByaW1lcm9zIGNvcnJlc3BvbmRlbiBhIG5vbWJyZXMgbcOhcyB0cmFkaWNpb25hbGVzIGNvcnJlc3BvbmRpZW50ZXMgYSB1bmEgZXBvY2EgbcOhcyBydXJhbCwgcXVlIGFjdHVhbG1lbnRlIHByYWN0aWNhbWVudGUgeWEgbm8gc2UgdXRpbGl6YW4uIFkgbG9zIHNlZ3VuZG9zIGNvcnJlc3BvbmRlbiBhIG5vbWJyZXMgbcOhcyBudWV2b3MgYmFzYWRvcyBlbiBtb2RhcywgYW5nbGljaXNtb3MuLi4gZXRjLiBTZWfDum4gbnVlc3RybyBncmFmaWNvIGVsIG5vbWJyZSBjb24gbcOhcyBlZGFkIG1lZGlhIGNvcnJlc3BvbmRlcsOtYSBhICoqQWZyb2Rpc2lhKiogY29uIHVuYSBlZGFkIG1lZGlhIGRlIDg0LDguIFkgZWwgbm9tYnJlIGNvbiBtZW5vcyBlZGFkIG1lZGlhIGNvcnJlc3BvbmRlcsOtYSBhICoqVmFpYW5hKiogY29uIHVuYSBlZGFkIG1lZGlhIGRlIDEuCjxicj4KCgojIyMjIEdSw4FGSUNPIExPUyAxMCBBUEVMTElET1MgTcOBUyBGUkVDVUVOVEVTCgpgYGB7ciBlY2hvPVRSVUUsIGV2YWw9VFJVRX0KCiNvYnRlbmVtb3MgdW4gdmVjdG9yIGRlIGRpZmVyZW50ZXMgY29sb3JlcyBkZWwgU2V0MSBkZSBicmV3ZXIucGFsCk1pc2NvbG9yZXMgPC0gYnJld2VyLnBhbCgxMCwgIlNldDMiKQoKI2FzaWduYW1vcyB1biBjb2xvciBkaWZlcmVudGUgYSBjYWRhIGZhY3RvciBkZSBhcGVsbGlkbwoKbmFtZXMoTWlzY29sb3Jlcyk8LSBkZl9hcGVsbGlkb3MkQXBlbGxpZG8KCiNBaG9yYSBwb2RlbW9zIHVzYXIgbG9zIGNvbG9yZXMgYXNpZ25hZG9zIGEgbG9zIDEwIGFwZWxsaWRvcyBwYXJhIGNvbG9yZWFyIGxhIGJhcnJhCgp0IDwtIGdncGxvdChkZl9hcGVsbGlkb3MsIGFlcyhBcGVsbGlkbywgRnJlY19Ub3RhbCwgZmlsbD1BcGVsbGlkbykpICsgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiKSArIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzPU1pc2NvbG9yZXMpCgp0ICsgdGhlbWUocGxvdC5jYXB0aW9uID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMSwgCiAgICBmYWNlID0gImJvbGQuaXRhbGljIiksIGF4aXMubGluZSA9IGVsZW1lbnRfbGluZShzaXplID0gMS4yKSwgCiAgICBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCwgCiAgICAgICAgZmFjZSA9ICJib2xkIiksIGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTMsIAogICAgICAgIGZhY2UgPSAiYm9sZCIpLCBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTMsIAogICAgICAgIHZqdXN0ID0gMC41LCBhbmdsZSA9IDQwKSwgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiLCAKICAgICAgICBoanVzdCA9IDAuNSwgdmp1c3QgPSAxLjUpLCBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyLCAKICAgICAgICBmYWNlID0gImJvbGQiKSwgbGVnZW5kLmtleSA9IGVsZW1lbnRfcmVjdChmaWxsID0gImdyYXk5MSIpLCAKICAgIGxlZ2VuZC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAiZ3JheTk3IikpICtsYWJzKHRpdGxlID0gIkxPUyAxMCBBUEVMTElET1MgTcOBUyBGUkVDVUVOVEVTIERFIEVTUEHDkUEiLCAKICAgIGNhcHRpb24gPSAiRGF0b3MgcHJvdmVuaWVudGVzIGRlbCBJTkUiKQoKYGBgCkVuIGVzdGUgZ3LDoWZpY28gcG9kZW1vcyBvYnNlcnZhciBsb3MgKioxMCBhcGVsbGlkb3MgbcOhcyBmcmVjdWVudGVzIGRlIEVzcGHDsWEgb3JkZW5hbW9zIGRlIG1heW9yIGEgbWVub3IgZnJlY3VlbmNpYS4qKgoKCiMjIyMgIEdSw4FGSUNPIExPUyAxMCBOT01CUkVTIE3DgVMgRlJFQ1VFTlRFUwpgYGB7ciBlY2hvPVRSVUUsIGV2YWw9VFJVRX0KCiNvYnRlbmVtb3MgdW4gdmVjdG9yIGRlIGRpZmVyZW50ZXMgY29sb3JlcyBkZWwgU2V0MSBkZSBicmV3ZXIucGFsCk1pc2NvbG9yZXMgPC0gYnJld2VyLnBhbCgxMCwgIlNldDMiKQoKI2FzaWduYW1vcyB1biBjb2xvciBkaWZlcmVudGUgYSBjYWRhIGZhY3RvciBkZSBhcGVsbGlkbwoKbmFtZXMoTWlzY29sb3Jlcyk8LSBkZl9ub21icmVzMyROb21icmUKCnMgPC0gZ2dwbG90KGRmX25vbWJyZXMzLCBhZXMoTm9tYnJlLCBGcmVjdWVuY2lhLCBmaWxsPU5vbWJyZSkpICsgZ2VvbV9iYXIoc3RhdD0iSWRlbnRpdHkiKSsgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXM9TWlzY29sb3JlcykKCnMgKyB0aGVtZShwbG90LmNhcHRpb24gPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCAKICAgIGZhY2UgPSAiYm9sZC5pdGFsaWMiKSwgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShzaXplID0gMSksIAogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShzaXplID0gMSksIAogICAgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIAogICAgICAgIGZhY2UgPSAiYm9sZCIsIHZqdXN0ID0gMSksIGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIAogICAgICAgIGZhY2UgPSAiYm9sZCIpLCBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIAogICAgICAgIHZqdXN0ID0gMC43NSwgYW5nbGUgPSAyNSksIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkLml0YWxpYyIsIAogICAgICAgIGhqdXN0ID0gMC41LCB2anVzdCA9IDIpLCBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChmYWNlID0gIml0YWxpYyIpLCAKICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIsIAogICAgICAgIGZhY2UgPSAiYm9sZC5pdGFsaWMiKSwgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gImdyYXk4OSIpLCAKICAgIGxlZ2VuZC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAiZ3JheTg1IikpICtsYWJzKHRpdGxlID0gIkxPUyAxMCBOT01CUkVTIE3DgVMgRlJFQ1VFTlRFUyBERSBFU1BBw5FBIiwgCiAgICBjYXB0aW9uID0gIkRhdG9zIHByb3ZlbmllbnRlcyBkZWwgSU5FIikgCgoKCmBgYApFbiBlc3RlIHNlZ3VuZG8gZ3LDoWZpY28gcG9kZW1vcyBvYnNlcnZhciBsb3MgKioxMCBub21icmVzIG3DoXMgZnJlY3VlbnRlcyBkZSBFc3Bhw7FhIG9yZGVuYWRvcyBkZSBtZW5vciBhIG1heW9yLioqCgo8YnI+CgoKIyMjIDQuMy4gTUFQQVMKQ2FyZ2FyZW1vcyBwcmltZXJvIGxhcyBnZW9tZXRyw61hcyBkZSBsYSBjYXJwZXRhIERhdG9zCmBgYHtyIGVjaG89VFJVRSwgZXZhbD1UUlVFfQpsb2FkKCIuL0RhdG9zL2dlb21ldHJpYXNfY2xhc2VfMTAuUkRhdGEiKQpgYGAKClkgYWhvcmEgaGFyZW1vcyB1biBtYXBhIGRlIEVzcGHDsWEgY29uIGxhIGRpc3RyaWJ1Y2nDs24gZGUgbGFzIHBlcnNvbmFzIGNvbiBub21icmUgZGUgRGFuaWVsOgpgYGB7ciBlY2hvPVRSVUUsIGV2YWw9VFJVRX0KCiNIYWNlbW9zIHVuIG1hcGEgZGUgY29yb3BsZXRhcyBkZWwgcGHDrXMgcGFyYSBlbCB0b3RhbCBkZWwgbm9tYnJlICJEYW5pZWwiCmRmRGFuaWVsIDwtIGZ1bGxfam9pbihQcm92aW5jaWFzLCBkZl9EYW5pZWwsIGJ5ID0gYygiTm9tYnJlUHJvdiIgPSAiUHJvdmluY2lhIikpCmdncGxvdChkZkRhbmllbCxhZXMoZ2VvbWV0cnkgPSBnZW9tZXRyeSkpICsgZ2VvbV9zZihhZXMoZmlsbD0gVG90YWwpKSAgKyBzY2FsZV9maWxsX3ZpcmlkaXNfYyhvcHRpb24gPSAidmlyaWRpcyIsIHRyYW5zID0gInNxcnQiLCBkaXJlY3Rpb24gPSAtMSkgKyBjb29yZF9zZih4bGltID0gYygtMjAsMTApKSArIGFubm90YXRlKGdlb20gPSAidGV4dCIsIHggPSA0LCB5ID0gMzcsIGxhYmVsID0gIk1hciBNZWRpdGVycsOhbmVvIiwgZm9udGZhY2UgPSAiaXRhbGljIiwgY29sb3IgPSAiZ3JleTIyIiwgc2l6ZSA9IDMpICsgbGFicyAodGl0bGUgPSAiTWFwYSAxOiBEaXN0cmlidWNpw7NuIGRlIHBlcnNvbmFzIGxsYW1hZGFzIERhbmllbCBlbiBFc3Bhw7FhIiwKICAgICAgIHN1YnRpdGxlID0gIlBvciBwcm92w61uY2lhcyIsCiAgICAgICBjYXB0aW9uID0gIkRhdG9zIHByb3ZlbmllbnRlcyBkZWwgSU5FIikgKyB0aGVtZV92b2lkKCkgCgpgYGAKCkFob3JhLCB2YW1vcyBhIG1vc3RyYXIgbGFzICoqdHJlcyBwcm92aW5jaWFzIGNvbiBtYXlvciBwZXJzb25hcyBsbGFtYWRhcyAiRGFuaWVsIiB5IGxhcyB0cmVzIHByb3ZpbmNpYXMgY29uIG1lbm9zIHBlcnNvbmFzIGxsYW1hZGFzIERhbmllbC4qKgpgYGB7ciBlY2hvPVRSVUUsIGV2YWw9VFJVRX0KIAojTGFzIHRyZXMgcHJvdmluY2luY2lhcyBjb24gbcOhcyBwZXJzb25hcyBsbGFtYWRhcyBEYW5pZWwuClByb3ZpbmNpYXNfbWF5b3I8LSBkZkRhbmllbCAlPiUgc2xpY2VfbWF4KFRvdGFsLCBuID0gMykgCnByb3ZpbmNpYXNfcG9pbnQgPC0gc3RfY2VudHJvaWQoUHJvdmluY2lhc19tYXlvcikgI0NhbWJpYW1vcyBsYSBnZW9tZXRyeSBwb3IgZWwgY2VudHJvaWRlCnByb3ZpbmNpYXNfcG9pbnRzIDwtIGNiaW5kKFByb3ZpbmNpYXNfbWF5b3IsIHN0X2Nvb3JkaW5hdGVzKHN0X2NlbnRyb2lkKFByb3ZpbmNpYXNfbWF5b3IkZ2VvbWV0cnkpKSkKCk1hc1Byb3ZEYW48LSBnZ3Bsb3QoKSArIGdlb21fc2YoZGF0YSA9IGRmRGFuaWVsKSArIGdlb21fc2YoZGF0YSA9IFByb3ZpbmNpYXNfbWF5b3IsIGZpbGwgPSAiZ3JlZW4iKSsgY29vcmRfc2YoeWxpbSA9IGMoMzUsNDUpLCB4bGltID0gYygtMTAsNSkpICsgdGhlbWVfbWluaW1hbCgpICsgbGFicyAodGl0bGUgPSAiTWFwYSAyOiBQcm92aW5jaWFzIGNvbiBtw6FzIHBlcnNvbmFzIGxsYW1hZGFzIERhbmllbCIsIHNpemUgPSAzKSAgK2dlb21fdGV4dChkYXRhID0gcHJvdmluY2lhc19wb2ludHMsIAogICAgICAgICAgICBhZXMoeCA9IFgsIHkgPSBZLCBsYWJlbCA9IE5vbWJyZVByb3YpLCAKICAgICAgICAgICAgY29sb3IgPSAiQmxhY2siLCBmb250ZmFjZSA9ICJib2xkIiwgY2hlY2tfb3ZlcmxhcCA9IFRSVUUsIHNpemUgPSAyLjUpICt0aGVtZV90ZXN0KCkKCiNMYXMgdHJlcyBwcm92aW5jaWFzIGNvbiBtZW5vcyBwZXJzb25hcyBsbGFtYWRhcyBEYW5pZWwuClByb3ZpbmNpYXNfbWVub3I8LSBkZkRhbmllbCAlPiUgc2xpY2VfbWluKFRvdGFsLCBuID0gNSkKUHJvdmluY2lhc19wb2ludCA8LSBzdF9jZW50cm9pZChQcm92aW5jaWFzX21lbm9yKSAjQ2FtYmlhbW9zIGxhIGdlb21ldHJ5IHBvciBlbCBjZW50cm9pZGUKUHJvdmluY2lhc19wb2ludHMgPC0gY2JpbmQoUHJvdmluY2lhc19tZW5vciwgc3RfY29vcmRpbmF0ZXMoc3RfY2VudHJvaWQoUHJvdmluY2lhc19tZW5vciRnZW9tZXRyeSkpKQoKTWVub3NQcm92RGFuPC0gZ2dwbG90KCkgKyBnZW9tX3NmKGRhdGEgPSBkZkRhbmllbCkgKyBnZW9tX3NmKGRhdGEgPSBQcm92aW5jaWFzX21lbm9yLCBmaWxsID0gInJlZCIpKyBjb29yZF9zZih5bGltID0gYygzNSw0NSksIHhsaW0gPSBjKC0xMCw1KSkgKyB0aGVtZV9taW5pbWFsKCkgKyBsYWJzICh0aXRsZSA9ICJNYXBhIDM6IFByb3ZpbmNpYXMgY29uIG1lbm9zIHBlcnNvbmFzIGxsYW1hZGFzIERhbmllbCIsIHNpemUgPSAzKSAgK2dlb21fdGV4dChkYXRhID0gUHJvdmluY2lhc19wb2ludHMsIAogICAgICAgICAgICBhZXMoeCA9IFgsIHkgPSBZLCBsYWJlbCA9IE5vbWJyZVByb3YpLCAKICAgICAgICAgICAgY29sb3IgPSAiV2hpdGUiLCBmb250ZmFjZSA9ICJib2xkIiwgY2hlY2tfb3ZlcmxhcCA9IFRSVUUsIHNpemUgPSAyLjUpICt0aGVtZV90ZXN0KCkKCiNNb3N0cmFtb3MgbG9zIHBsb3RzCgpNYXNQcm92RGFuICsgTWVub3NQcm92RGFuCgoKYGBgClBvciB0YW50bywgbGFzIHRyZXMgcHJvdmluY2lhcyAqKmRvbmRlIGFidW5kYSBtw6FzIGVsIG5vbWJyZSBkZSAiRGFuaWVsIiBzb246IE1hZHJpZCwgQmFyY2Vsb25hIHkgU2V2aWxsYS4qKiBFbiBjYW1iaW8sIGVuICoqVGVydWVsLCBTb3JpYSB5IMOBbGF2YSwgbm8gZXMgdGFuIGZyZWN1ZW50ZSBlc3RlIG5vbWJyZS4qKgoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKQWhvcmEgaGFyZW1vcyB1biBtYXBhIGRlIEVzcGHDsWEgY29uIGxhIGRpc3RyaWJ1Y2nDs24gZGUgbGFzIHBlcnNvbmFzIHBlcm8gY29uIG5vbWJyZSBkZSBMYXVyYToKYGBge3IgZWNobz1UUlVFLCBldmFsPVRSVUV9CgojSGFjZW1vcyBvdHJvIG1hcGEgZGUgY29yb3BsZXRhcyBwYXJhIGVsIHRvdGFsIGRlbCBub21icmUgIkxhdXJhIi4KZGZMYXVyYTwtZnVsbF9qb2luKFByb3ZpbmNpYXMsZGZfTGF1cmEsIGJ5ID0gYygiTm9tYnJlUHJvdiIgPSAiUHJvdmluY2lhIikpICU+JXNlbGVjdCgtYyhJTkVDb2RDQ0FBLCBOb21icmVDQ0FBLCBJTkVDb2RQcm92KSkKCmdncGxvdChkYXRhID0gZGZMYXVyYSwgYWVzKGdlb21ldHJ5ID0gZ2VvbWV0cnkpKSArIGdlb21fc2YoYWVzKGZpbGwgPSBUb3RhbCkpICsgc2NhbGVfZmlsbF92aXJpZGlzX2Mob3B0aW9uID0gImluZmVybm8iLCB0cmFucyA9ICJzcXJ0IiwgZGlyZWN0aW9uID0gLTEpICsgY29vcmRfc2YoeGxpbSA9IGMoLTIwLDEwKSkgKwogIGFubm90YXRlKGdlb20gPSAidGV4dCIsIHggPSA0LCB5ID0gMzcsIAogICAgICAgICAgIGxhYmVsID0gIk1hciBNZWRpdGVycsOhbmVvIiwgZm9udGZhY2UgPSAiaXRhbGljIiwgY29sb3IgPSAiZ3JleTIyIiwgc2l6ZSA9IDMpICsgbGFicyAodGl0bGUgPSAiTWFwYSA0OiBEaXN0cmlidWNpw7NuIGRlIHBlcnNvbmFzIGxsYW1hZGFzIExhdXJhIGVuIEVzcGHDsWEiLAogICAgICAgc3VidGl0bGUgPSAiUG9yIHByb3bDrW5jaWFzIiwKICAgICAgIGNhcHRpb24gPSAiRGF0b3MgcHJvdmVuaWVudGVzIGRlbCBJTkUiKSArIHRoZW1lX3ZvaWQoKSAKYGBgCgpZIGEgY29udGludWFjacOzbiwgb3RybyBtYXBhIGRlIGNvcm9wbGV0YXMgY29uIGVsIG5vbWJyZSBkZSAqKkxhdXJhLCBwb3IgcHJvdmluY2lhczoqKgpgYGB7ciBlY2hvPVRSVUUsIGV2YWw9VFJVRX0KCiNNYXBhIGRlIGxhcyBwcm92aW5jaWFzIGNvbiBtw6FzIHBlcnNvbmFzIGxsYW1hZGFzIExhdXJhClByb3ZpbmNpYXNfbWF5b3I8LSBkZkxhdXJhICU+JSBzbGljZV9tYXgoVG90YWwsIG4gPSAzKQpwcm92aW5jaWFzX3BvaW50cyA8LSBzdF9jZW50cm9pZChQcm92aW5jaWFzX21heW9yKSAjQ2FtYmlhbW9zIGxhIGdlb21ldHJ5IHBvciBlbCBjZW50cm9pZGUKcHJvdmluY2lhc19wb2ludHMgPC0gY2JpbmQoUHJvdmluY2lhc19tYXlvciwgc3RfY29vcmRpbmF0ZXMoc3RfY2VudHJvaWQoUHJvdmluY2lhc19tYXlvciRnZW9tZXRyeSkpKQoKZ2dwbG90KCkgKyBnZW9tX3NmKGRhdGEgPSBkZkxhdXJhKSArIGdlb21fc2YoZGF0YSA9IFByb3ZpbmNpYXNfbWF5b3IsIGZpbGwgPSAiZ3JlZW4iKSsgY29vcmRfc2YoeWxpbSA9IGMoMzUsNDUpLCB4bGltID0gYygtMTAsNSkpICsgdGhlbWVfbWluaW1hbCgpICsgbGFicyAodGl0bGUgPSAiTWFwYSA1OiBQcm92aW5jaWFzIGNvbiBtw6FzIHBlcnNvbmFzIGxsYW1hZGFzIExhdXJhIiwgc2l6ZSA9IDMpICArIGdlb21fdGV4dChkYXRhID0gcHJvdmluY2lhc19wb2ludHMsIAogICAgICAgICAgICBhZXMoeCA9IFgsIHkgPSBZLCBsYWJlbCA9IE5vbWJyZVByb3YpLCAKICAgICAgICAgICAgY29sb3IgPSAiQmxhY2siLCBmb250ZmFjZSA9ICJib2xkIiwgY2hlY2tfb3ZlcmxhcCA9IFRSVUUsIHNpemUgPSAyLjUpICsgdGhlbWVfdGVzdCgpCgojTWFwYSBkZSBsYXMgcHJvdmluY2lhcyBjb24gbWVub3MgcGVyc29uYXMgbGxhbWFkYXMgTGF1cmEKUHJvdmluY2lhc19tZW5vcjwtIGRmTGF1cmEgJT4lIHNsaWNlX21pbihUb3RhbCwgbiA9IDUpCnByb3ZpbmNpYXNfcG9pbnRzIDwtIHN0X2NlbnRyb2lkKFByb3ZpbmNpYXNfbWVub3IpICNDYW1iaWFtb3MgbGEgZ2VvbWV0cnkgcG9yIGVsIGNlbnRyb2lkZQpwcm92aW5jaWFzX3BvaW50cyA8LSBjYmluZChQcm92aW5jaWFzX21lbm9yLCBzdF9jb29yZGluYXRlcyhzdF9jZW50cm9pZChQcm92aW5jaWFzX21lbm9yJGdlb21ldHJ5KSkpCgpnZ3Bsb3QoKSArIGdlb21fc2YoZGF0YSA9IGRmTGF1cmEpICsgZ2VvbV9zZihkYXRhID0gUHJvdmluY2lhc19tZW5vciwgZmlsbCA9ICJyZWQiKSsgY29vcmRfc2YoeWxpbSA9IGMoMzUsNDUpLCB4bGltID0gYygtMTAsNSkpICsgdGhlbWVfbWluaW1hbCgpICsgbGFicyAodGl0bGUgPSAiTWFwYSA2OiBQcm92aW5jaWFzIGNvbiBtZW5vcyBwZXJzb25hcyBsbGFtYWRhcyBMYXVyYSIsIHNpemUgPSAzKSAgKyBnZW9tX3RleHQoZGF0YSA9IHByb3ZpbmNpYXNfcG9pbnRzLAogICAgICAgICAgICBhZXMoeCA9IFgsIHkgPSBZLCBsYWJlbCA9IE5vbWJyZVByb3YpLCAKICAgICAgICAgICAgY29sb3IgPSAiV2hpdGUiLCBmb250ZmFjZSA9ICJib2xkIiwgY2hlY2tfb3ZlcmxhcCA9IFRSVUUsIHNpemUgPSAyLjUpICt0aGVtZV90ZXN0KCkKYGBgCkFxdcOtIG9ic2VydmFtb3MgcXVlICoqbGFzIHByb3ZpbmNpYXMgZG9uZGUgYWJ1bmRhIGVsIG5vbWJyZSBMYXVyYSBzb246IE1hZHJpZCwgQmFyY2Vsb25hIHkgVmFsZW5jaWEuKiogUG9yIG90cmEgcGFydGUsICoqZG9uZGUgZWwgbm9tYnJlIExhdXJhIGVzIG1lbm9zIHTDrXBpY28gZXMgZW4gVGVydWVsLCBTb3JpYSB5IFNlZ292aWEuKioKCgoKCiMjIyA0LjQuIEdSw4FGSUNPIEFOSU1BRE8KSGVtb3MgcXVlcmlkbyB2ZXIgKipjb21vIGhhIGV2b2x1Y2lvbmFkbyBsYSBmcmVjdWVuY2lhIGRlIG51ZXN0cm9zIG5vbWJyZXMgZHVyYW50ZSBsYXMgZGlzdGludGFzIGTDqWNhZGFzIGVuIEVzcGHDsWEuKiogUGFyYSBlbGxvLCBoZW1vcyByZWFsaXphZG8gdW4gZ3LDoWZpY28gZGUgbMOtbmVhcyBkaW7DoW1pY28gbyBhbmltYWRvLCBwb3IgZWwgY3VhbCwgbGFzIGxpbmVhcyBjcmVjZW4gbyBkZWNyZWNlbiBjb25mb3JtZSBsYSBmcmVjdWVuY2lhIGRlIG51ZXN0cm9zIG5vbWJyZXMgYXVtZW50YSBvIGRpc21pbnV5ZSBhIHRyYXbDqXMgZGUgbGFzIGRpZmVyZW50ZXMgZMOpY2FkYXMgaGFzdGEgMjAxMC4KClBhcmEgZWxsbywgYW50ZXMgZGUgbmFkYSBoZW1vcyBvYnRlbmlkbyBkb3MgRVhDRUwgZGVsIElORSBjb24gbGEgZXZvbHVjacOzbiBkZSBudWVzdHJvcyBub21icmVzICgiRGFuaWVsIiB5ICJMYXVyYSIpIHkgaGVtb3MgbWFuaXB1bGFkbyBsb3MgZGF0b3MgcGFyYSBwb2RlciBjcmVhciBhc8OtIGVsIGdyw6FmaWNvIGFuaW1hZG8uCmBgYHtyIGVjaG89VFJVRSwgZXZhbD1UUlVFfQoKCiNEQU5JRUwKRGVjYWRhRGFuaWVsIDwtIHJlYWRfZXhjZWwoIkRhdG9zL0RlY2FkYURhbmllbC54bHMiKQoKRGVjYWRhRGFuaWVsMTwtIERlY2FkYURhbmllbCAlPiUgc2VsZWN0KE5vbWJyZSwgUHJvdsOtbmNpYXMsIGAxOTMwYCwgYDE5NDBgLCBgMTk1MGAsIGAxOTUwYCwgYDE5NjBgLCBgMTk3MGAsIGAxOTgwYCwgYDE5OTBgLCBgMjAwMGAsYDIwMTBgKQoKRGVjYWRhRGFuaWVsMiA8LSBEZWNhZGFEYW5pZWwxICU+JSBwaXZvdF9sb25nZXIoY29scz0zOjExLG5hbWVzX3RvPSJhw7FvIix2YWx1ZXNfdG89ImZyZWN1ZW5jaWEiKQoKRGVjYWRhRGFuaWVsREVGIDwtIERlY2FkYURhbmllbDIgJT4lIGZpbHRlcighaXMubmEoZnJlY3VlbmNpYSkpICU+JSBncm91cF9ieShOb21icmUsYcOxbykgJT4lIHN1bW1hcmlzZShzdW1hPXN1bShmcmVjdWVuY2lhKSkKCgojTEFVUkEKRGVjYWRhTGF1cmE8LSByZWFkX2V4Y2VsKCJEYXRvcy9EZWNhZGFMYXVyYS54bHMiKQoKCkRlY2FkYUxhdXJhMTwtIERlY2FkYUxhdXJhICU+JSBzZWxlY3QoTm9tYnJlLCBQcm92w61uY2lhcywgYDE5MzBgLCBgMTk0MGAsIGAxOTUwYCwgYDE5NTBgLCBgMTk2MGAsIGAxOTcwYCwgYDE5ODBgLCBgMTk5MGAsIGAyMDAwYCxgMjAxMGApCgpEZWNhZGFMYXVyYTIgPC0gRGVjYWRhTGF1cmExICU+JSBwaXZvdF9sb25nZXIoY29scz0zOjExLG5hbWVzX3RvPSJhw7FvIix2YWx1ZXNfdG89ImZyZWN1ZW5jaWEiKQoKRGVjYWRhTGF1cmFERUYgPC0gRGVjYWRhTGF1cmEyICU+JSBmaWx0ZXIoIWlzLm5hKGZyZWN1ZW5jaWEpKSAlPiUgZ3JvdXBfYnkoTm9tYnJlLGHDsW8pICU+JSBzdW1tYXJpc2Uoc3VtYT1zdW0oZnJlY3VlbmNpYSkpCgoKRGVjYWRhSnVudG9zPC0gZnVsbF9qb2luKERlY2FkYURhbmllbERFRixEZWNhZGFMYXVyYURFRikgJT4lIG11dGF0ZShhw7FvMT0gYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoYcOxbykpKSAlPiUgc2VsZWN0KE5vbWJyZSxhw7FvMSxzdW1hKQoKYGBgCgpgYGB7ciBlY2hvPUZBTFNFLCBldmFsPVRSVUV9CgojIFBMT1QKRGVjYWRhSnVudG9zICU+JQogIGdncGxvdCggYWVzKHg9YcOxbzEsIHk9c3VtYSwgZ3JvdXA9Tm9tYnJlLCBjb2xvcj1Ob21icmUpKSArCiAgZ2VvbV9saW5lKCkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2d0aXRsZSgiRnJlY3VlbmNpYSBkZSAyIG5vbWJyZXMgZHVyYW50ZSBkw6ljYWRhcyAiKSArCiAgdGhlbWVfaXBzdW0oKSArCiAgeWxhYigiRnJlY3VlbmNpYSIpICsKICB0cmFuc2l0aW9uX3JldmVhbChhw7FvMSkKCmBgYAoKCiMjIDUuIENPTUVOVEFSSU8gRklOQUwKUGFyYSBjb25jbHVpciBlbCB0cmFiYWpvLCBjb21lbnRhciBxdWUgaGVtb3MgYXByZW5kaWRvIHNvYnJlIGxhcyBkaWZlcmVudGVzIG1hbmVyYXMgZGUgbW9zdHJhciBsb3MgZGF0b3MsIGFzw60gY29tbyBtYW5pcHVsYXIgZXN0b3MgZGUgZGlzdGludGFzIGZvcm1hcywgaGFjZXIgZ3LDoWZpY29zIGludGVyYWN0aXZvcyB5IGFuaW1hZG9zLCBhZGVtw6FzIGRlIGxvcyB0cmFkaWNpb25hbGVzIGdyw6FmaWNvcyBkZSBiYXJyYXMuIFRhbWJpw6luIGhlbW9zIGFwcmVuZGlkbyBjb21vIGltcGxlbWVudGFyIG1hcGFzLCB0cmFuc2Zvcm1hcmxvcyB5IGV4dHJhZXIgaW5mb3JtYWNpw7NuIMO6dGlsIGRlIGVsbG9zLgoKRWwgdGVtYSBxdWUgaGVtb3MgZXNjb2dpZG8sIGxvIGhlbW9zIGVzY29naWRvIHBvciBsYSBjdXJpb3NpZGFkIHF1ZSBub3Mgc3VyZ8OtYSBzYWJlciBzaSB0ZW7DrWFtb3MgdW4gbm9tYnJlIHkgYXBlbGxpZG8gY29tw7puLCBwb3IgY29ub2NlciBsYSBmcmVjdWVuY2lhIGRlIGVzdG9zIGVuIG51ZXN0cm8gdGVycml0b3JpbyB5IHBvciBzZXIgdW4gdGVtYSB1biBwb2NvIG3DoXMgZGlzdGVuZGlkbywgbm8gcXVlcsOtYW1vcyBlc3RhciDDum5pY2FtZW50ZSBtYW5pcHVsYW5kbyBuw7ptZXJvcywgcXVlcsOtYW1vcyBoYWNlciBhbGdvIHVuIHBvY28gZGlmZXJlbnRlLCBwZXJvLCBjb24gbGEgaW5mb3JtYWNpw7NuIHN1ZmljaWVudGUgY29tbyBwYXJhIHBvZGVyIHJlYWxpemFyIGRpc3RpbnRhcyB0cmFuc2Zvcm1hY2lvbmVzIHkgYXPDrSBwb2RlciByZWFsaXphciBkaWZlcmVudGVzIHRhcmVhcyBjb24gZXN0YXMuCgoKIyMgUkVGRVJFTkNJQVMKUGFyYSBsYSByZWFsaXphY2nDs24gZGVsIHRyYWJham8gaGVtb3MgdXRpbGl6YWRvOgoKCi0gRGF0b3Mgbm9tYnJlcyBJTkU6IGh0dHBzOi8vd3d3LmluZS5lcy9kYWNvL2RhY280Mi9ub21ieWFwZWwvbm9tYnJlc19wb3JfZWRhZF9tZWRpYS54bHMKCi0gRGF0b3MgYXBlbGxpZG9zIElORTogaHR0cHM6Ly93d3cuaW5lLmVzL2RhY28vZGFjbzQyL25vbWJ5YXBlbC9hcGVsbGlkb3NfZnJlY3VlbmNpYS54bHMKCi0gRGF0b3MgY29uY3JldG9zICJEYW5pZWwiIHkgIkxhdXJhIjogaHR0cHM6Ly93d3cuaW5lLmVzL3Rub21icmVzL2Zvcm1HZW5lcmFscmVzdWx0LmRvIAoKLSBFamVtcGxvcyBkZSByZWFkdGFibGVzOiBodHRwczovL2dsaW4uZ2l0aHViLmlvL3JlYWN0YWJsZS9hcnRpY2xlcy9leGFtcGxlcy5odG1sCgotIEdyw6FmaWNvczogaHR0cHM6Ly9yc3R1ZGlvLXB1YnMtc3RhdGljLnMzLmFtYXpvbmF3cy5jb20vMTc5ODAzXzU2MTJjMGJjNTRkNTQ2OTZiYzA5NjIyYjY5ZDYzNGIxLmh0bWwKCi0gRGF0YSBtdW5naW5nOiBodHRwczovL3BlcmV6cDQ0LmdpdGh1Yi5pby9pbnRyby1kcy0yMC0yMS13ZWIvdHV0b3JpYWxlcy90dF8wNV9kYXRhLW11bmdpbmcuaHRtbAoKLSBHR1BMT1Q6IGh0dHBzOi8vcGVyZXpwNDQuZ2l0aHViLmlvL2ludHJvLWRzLTIwLTIxLXdlYi90dXRvcmlhbGVzL3R0XzA2X2dncGxvdDIuaHRtbAoKLSBBbmltYXRlZCBsaW5lIGNoYXJ0OiBodHRwczovL3d3dy5yLWdyYXBoLWdhbGxlcnkuY29tLzI4Ny1zbW9vdGgtYW5pbWF0aW9uLXdpdGgtdHdlZW5yLmh0bWwgCgotIEdlb21ldHLDrWFzIGRhZGFzIGVuIGNsYXNlIHBvciBlbCBwcm9mZXNvci4KCi0tLS0tLS0tLS0tLS0tLS0KCjxicj48YnI+CgpQYXJhIGFjYWJhciBlc3RlIGNodW5rIHBhcmEgaW5jbHVpciB0dSBgc2Vzc2lvbiBpbmZvYDoKCmBgYHtyfQpzZXNzaW9uaW5mbzo6c2Vzc2lvbl9pbmZvKCkgJT4lIGRldGFpbHM6OmRldGFpbHMoc3VtbWFyeSA9ICdjdXJyZW50IHNlc3Npb24gaW5mbycpIApgYGAK