Trabajo elaborado para la asignatura “Programación y manejo de datos en la era del Big Data” de la Universitat de València durante el curso 2021-2022. El repo del trabajo está aquí.

La página web de la asignatura y los trabajos de mis compañeros pueden verse aquí.


1. Introducción

El objetivo de este trabajo es ver como esta situado mi pueblo natal, Calp, respecto a sus vecinos comarcales en cuanto a población y a nivel turístico.


knitr::include_graphics(here::here("imagenes", "Calpe.png"))

2. Datos

Casi Todos los datos proceden de un portal de la Marina Alta que recoge estadísticas de sus municipios y de la región en general, y cuyo nombre es Observatorio Marina Alta.

3. POBLACIÓN EN LA MARINA ALTA

En el mapa que se presenta abajo, podemos observar los municipios de la Marina Alta con mayor población. Estos municipios coinciden con los costeros, en los que hay mayor actividad.


municipios_alicante <-rio::import(here::here("datos", "poblacion.xlsx"))

muni_A <- municipios_alicante %>% filter(year == 2018)

muni <- esp_get_munic(year = "2019", region = "Alicante")

df <- left_join(muni_A, muni, by = c("Ambito geografico" = "name" ))

df <- df %>% rename(municipio = "Ambito geografico")


pw<- ggplot(df) + geom_sf(aes(geometry = geometry, fill = Poblacion)) 

p1 <- pw+ scale_fill_viridis_c(option = "ligthgreen", trans = "sqrt") + 
  labs(title = 'Poblacion La Marina Ala',                                                                      subtitle = "(Por Municipios)",
       caption = "Datos provenientes de mapSpain (paquete) y observatoriomarinaalta.org",
       tag = "Mapa municipios")


world_points <- cbind(df, st_coordinates(st_centroid(df$geometry, of_largest_polygon = TRUE)))

p2 <- p1 + geom_text(data = world_points, 
          aes(x = X, y = Y, label = municipio), 
          color = "white", fontface = "bold", check_overlap = TRUE, size = 2.5) + 
  labs(y = NULL) +
  labs(x = NULL)

p2

3.1 Variación poblacional

Para mostrarlo hemos elegido los municipios que mayor variación tienen. Por norma general, esta situación se da en verano por la elevada afluencia de turistas que van a pueblos costeros para disfrutar de las vacaciones en la playa. Para bien o para mal, el turismo predominante es la zona es el de Sol y Playa.

pob <- rio::import(here::here("datos", "variacion_poblacional.xlsx"))

var_pob <- pob %>% rename(poblacion_estacional_maxima = "Población Estacional Máxima" , poblacion_empadronada = "Población Empadronada", ambito_geografico = "Ámbito geográfico" ) %>%
  group_by(`ambito_geografico`) %>%
  arrange(Año) %>%
  mutate(tasa_variacion_poblacional = (poblacion_estacional_maxima / poblacion_empadronada)*100) %>%
  ungroup()


pp <- ggplot(var_pob, aes(x = Año, y = tasa_variacion_poblacional, group = ambito_geografico, color=ambito_geografico))+
  geom_line()+ 
  geom_point() +
  ggtitle("Evolución de la tasa de variación poblacional") +
  theme_ipsum() +
  scale_x_continuous(breaks=seq(2011,2020,2),limits=c(2011,2020)) + labs(y = NULL,
                                                                         color = "Ámbito geográfico")
pp + transition_reveal(Año)

3.1.1. Variación poblacional de Calp

Para el caso específico de Calp, vemos que la variación de la población llega a un 800%, es decir, que la población es 8 veces mayor que la empadronada. Esto se debe, como ya hemos mencionado a la enorme afluencia de turistas que recibe la costa. No obstante, hay una clara bajada para el año 2020 debido a las restricciones de movilidad y el miedo causado por el COVID-19.

var_pob_calp <- var_pob %>% filter(`ambito_geografico`== "Calp")

ppob <- ggplot(var_pob_calp, aes(Año, tasa_variacion_poblacional, fill = tasa_variacion_poblacional)) +
  geom_col() +
  scale_fill_distiller(palette = "Blues", direction = 1) +
  theme_minimal() +
  theme(
    panel.grid = element_blank(),
    panel.grid.major.y = element_line(color = "white"),
    panel.ontop = TRUE
  ) + transition_states(Año, wrap = FALSE) +
  shadow_mark()
ppob

4. PARO EN LA MARINA ALTA

Para este análisis nos centraremos en los principales puntos turísticos de la región.

tasa_paro <- rio::import(here::here("datos", "tasa de paro segun actividad.xlsx"))

tasa_paro1 <- tasa_paro %>% select(Periodo, `Ámbito geográfico`, `Tasa de paro total (%)`) %>% 
  group_by(`Ámbito geográfico`) %>% 
  arrange(Periodo) %>%
  mutate(crec_tasa_paro = `Tasa de paro total (%)` - lag(`Tasa de paro total (%)`)) %>% 
  mutate(crec_tasa_paro_desde_2016 = `Tasa de paro total (%)` - first(`Tasa de paro total (%)`)) %>%
  ungroup()

DT::datatable(tasa_paro1, filter = 'top', options = list(
  pageLength = 6, autoWidth = TRUE, caption = htmltools::tags$caption(
    style = 'caption-side: bottom; text-align: center;',
    'Table 1: ', htmltools::em('Tasa de paro.')
  )
))

En líneas generales podemos decir que el paro ha descendido en la región por lo que parece ser que se va en la buena dirección. El municipio donde más ha bajado el paro desde 2016 es Jávea, en un -4.96%. No obstante, el paro en España es de un 14,5%, por debajo de los principales municipios de la Marina Alta. En cuanto a Calp, podemos ver que tiene un paro en el tercer trimestre del 2021 del 17.39%, una tasa considerable, ocupando el tercer puesto de los municipios de la tabla.

A continuación vamos a analizar las tasas de paro en el sector servicios y más adelante la de la construcción, los dos secotres claves de la región.

El sector servicios tiene una gran importancia y es el que más demanda tiene, debido a la dependencia del turismo en la zona.

tasa_paro2 <- tasa_paro %>% select(Periodo, `Ámbito geográfico`, `Tasa de paro Servicios (%)`) %>%
  group_by(`Ámbito geográfico`) %>%
  arrange(Periodo) %>%
  mutate(crec_tasa_paro_Servicios = `Tasa de paro Servicios (%)` - lag(`Tasa de paro Servicios (%)`)) %>%
  mutate(crec_tasa_paro_desde_2016_Servicios = `Tasa de paro Servicios (%)` - first(`Tasa de paro Servicios (%)`))  %>%
  ungroup()


DT::datatable(tasa_paro2, filter = 'top', options = list(
  pageLength = 6, autoWidth = TRUE, caption = htmltools::tags$caption(
    style = 'caption-side: bottom; text-align: center;',
    'Tabla 2: ', htmltools::em('Tasa de paro servicios.')
  )
))

Si nos fijamos únicamente en el sector servicios el municipio que más ha reducido su paro desde 2016 ha sido Calp, con una bajada del 5,06%, buen síntoma de recuperación ya que el paro no dejó de aumentar desde el inicio de la pandemia hasta el segundo trimestre de 2021. Cabe decir que todos los demás municipios han seguido la tendencia.

tasa_paro3 <- tasa_paro %>% select(Periodo, `Ámbito geográfico`, `Tasa de paro Construcción (%)`) %>%
  group_by(`Ámbito geográfico`) %>%
  arrange(Periodo) %>%
  mutate(crec_tasa_paro_Construcción = `Tasa de paro Construcción (%)` - lag(`Tasa de paro Construcción (%)`)) %>%
  mutate(crec_tasa_paro_Construcción_desde_2016 = `Tasa de paro Construcción (%)` - first(`Tasa de paro Construcción (%)`)) %>% 
  ungroup()

DT::datatable(tasa_paro3, filter = 'top', options = list(
  pageLength = 6, autoWidth = TRUE, caption = htmltools::tags$caption(
    style = 'caption-side: bottom; text-align: center;',
    'Tabla 3: ', htmltools::em('Tasa de paro construcción.')
  )
))

Respecto al sector de la construcción, observamos que también se ha reducido el paro desde 2016 siendo Calp el municipio en el que menos ha descendido y siendo Dénia y Els Poblets en los que la bajada ha sido mayor, de hasta un 9%.

El sector de servicios junto con la construcción, son los dos motores de la región debido a que la actividad principal es el turismo, pero puede conllevar problemas de masificación y contaminación.

El turismo es un sector estratégico, dinámico y esencial en el desarrollo de la Marina Alta. Siendo muy valorado y con una alta calidad de servicio. Este está inmerso en un proceso de mejora constante con la formación, la economía circular y la sostenibilidad ambiental.

5. Turismo

A continuación vamos a tratar de observar que municipio tiene un mayor número de plazas de alojamientos y veremos el porque de la importancia del sector de la construcción y de los servicios.

En el siguiente gráfico se muestra que Calp es el municipio con más plazas de alojamientos aún teniendo menos hoteles que por ejemplo Dénia. Esto quiere decir que Calp es el municipio con más capacidad para albergar turistas de la Marina Alta. Esto supone tener un gran entramado de, ya no hoteles, si no de apartamentos, camping de caravanas y todo tipo de alojamientos.


alojamientos <- rio::import(here::here("datos", "oferta alojamientos turísticos .xlsx"))

alojamientos_1 <- alojamientos %>% rename(num_total_plazas = "Nº Total Plazas") %>%
  filter(Año == 2020) %>% 
  select(Año, `Ámbito geográfico`, num_total_plazas) %>% 
  arrange(desc(num_total_plazas))

df <- alojamientos_1 %>% mutate(`Ámbito geográfico` = forcats::as_factor(`Ámbito geográfico`))

df <- df %>% mutate(`Ámbito geográfico` = forcats::fct_rev(`Ámbito geográfico`))


p <- ggplot(df, aes(x = num_total_plazas , y = `Ámbito geográfico` ))
p + geom_bar(stat = "identity",  fill = "steelblue") +
    labs(title = "Municipios con más plazas de alojamiento",
       caption = "Datos provenientes de Observatorio Marina Alta",
       x = "Plazas Totales",
       y = "Municipios" )

6. MEJORES PLAYAS

Para ver las mejores playas hemos extendido el análisis a los municipios con playas de la provincia de Alicante, podemos observar que el municipio que más Banderas azules tiene por kilometro de playa es Pilar de la Horadada. Calp, en este ranking está en el puesto número trece.

La Marina Alta se caracteriza por tener unas playas de calidad y limpias, además, también han sido galardonas con premios como los otorgados por la Asociación de Educación Ambiental y del Consumidor (Adeac).


banderas_azules <- rio::import(here::here("datos", "Municipios costeros banderas azules - Alicante.xlsx"))

BA <- banderas_azules %>% group_by(Municipio) %>%
  mutate(banderas_azules_por_kilometro = `Banderas Azules 2021`/ `Km. Costa`) %>% 
  mutate(banderas_por_playa = `Banderas Azules 2021`/ `Número Playas` ) %>%
  arrange(desc(banderas_azules_por_kilometro)) %>% ungroup()

BA
Municipio Número Playas Km. Costa Banderas Azules 2021 banderas_azules_por_kilometro banderas_por_playa
Pilar de la Horadada 5 5 6 1.2000000 1.20
Orihuela 5 10 11 1.1000000 2.20
Benitachell/Poble Nou de Benitatxell (El) 0 2 1 0.5000000 Inf
Finestrat 1 2 1 0.5000000 1.00
Altea 5 7 3 0.4285714 0.60
Torrevieja 4 14 6 0.4285714 1.50
Elche/Elx 4 12 5 0.4166667 1.25
Santa Pola 5 15 6 0.4000000 1.20
Teulada 4 8 3 0.3750000 0.75
Villajoyosa/Vila Joiosa (La) 4 15 5 0.3333333 1.25
Dénia 6 19 6 0.3157895 1.00
Benidorm 3 10 3 0.3000000 1.00
Calp 5 11 3 0.2727273 0.60
L’Alfàs del Pi 1 4 1 0.2500000 1.00
Benissa 1 4 1 0.2500000 1.00
Alicante/Alacant 5 23 5 0.2173913 1.00
Guardamar del Segura 4 14 3 0.2142857 0.75
Jávea/Xàbia 6 25 3 0.1200000 0.50
El Campello 2 23 2 0.0869565 1.00
Els Poblets 0 1 NA NA NA

7. Conclusiones

La Marina Alta depende del turismo, el cual es el motor de la economía en la region, esto trae consigo un elevado paro estacional que lastra el crecimiento económico, por lo que se debería seguir avanzando hacía un turismo menos de Sol y Playa y más cultural, deportivo, gastronómico, rural y medioambiental.

4. Bibliografía

Observatorio Marina Alta

Periódico Levante

La Marina Plaza





Información de mi R-sesión:

- Session info ---------------------------------------------------------------
 setting  value                       
 version  R version 4.1.1 (2021-08-10)
 os       Windows 10 x64              
 system   x86_64, mingw32             
 ui       RTerm                       
 language (EN)                        
 collate  Spanish_Spain.1252          
 ctype    Spanish_Spain.1252          
 tz       Europe/Paris                
 date     2022-01-07                  

- Packages -------------------------------------------------------------------
 package      * version    date       lib source                        
 assertthat     0.2.1      2019-03-21 [1] CRAN (R 4.1.1)                
 backports      1.2.1      2020-12-09 [1] CRAN (R 4.1.1)                
 broom          0.7.9      2021-07-27 [1] CRAN (R 4.1.1)                
 bslib          0.3.1      2021-10-06 [1] CRAN (R 4.1.1)                
 cellranger     1.1.0      2016-07-27 [1] CRAN (R 4.1.1)                
 class          7.3-19     2021-05-03 [2] CRAN (R 4.1.1)                
 classInt       0.4-3      2020-04-07 [1] CRAN (R 4.1.1)                
 cli            3.1.0      2021-10-27 [1] CRAN (R 4.1.2)                
 clipr          0.7.1      2020-10-08 [1] CRAN (R 4.1.1)                
 colorspace     2.0-2      2021-06-24 [1] CRAN (R 4.1.1)                
 countrycode    1.3.0      2021-07-15 [1] CRAN (R 4.1.1)                
 crayon         1.4.2      2021-10-29 [1] CRAN (R 4.1.1)                
 crosstalk      1.2.0      2021-11-04 [1] CRAN (R 4.1.2)                
 curl           4.3.2      2021-06-23 [1] CRAN (R 4.1.1)                
 data.table     1.14.0     2021-02-21 [1] CRAN (R 4.1.1)                
 DBI            1.1.1      2021-01-15 [1] CRAN (R 4.1.1)                
 dbplyr         2.1.1      2021-04-06 [1] CRAN (R 4.1.1)                
 desc           1.4.0      2021-09-28 [1] CRAN (R 4.1.1)                
 details        0.2.1      2020-01-12 [1] CRAN (R 4.1.1)                
 digest         0.6.28     2021-09-23 [1] CRAN (R 4.1.1)                
 dplyr        * 1.0.7      2021-06-18 [1] CRAN (R 4.1.1)                
 DT           * 0.19       2021-09-02 [1] CRAN (R 4.1.1)                
 e1071          1.7-8      2021-07-28 [1] CRAN (R 4.1.1)                
 ellipsis       0.3.2      2021-04-29 [1] CRAN (R 4.1.1)                
 evaluate       0.14       2019-05-28 [1] CRAN (R 4.1.1)                
 extrafont      0.17       2014-12-08 [1] CRAN (R 4.1.1)                
 extrafontdb    1.0        2012-06-11 [1] CRAN (R 4.1.1)                
 fansi          0.5.0      2021-05-25 [1] CRAN (R 4.1.1)                
 farver         2.1.0      2021-02-28 [1] CRAN (R 4.1.1)                
 fastmap        1.1.0      2021-01-25 [1] CRAN (R 4.1.1)                
 forcats      * 0.5.1      2021-01-27 [1] CRAN (R 4.1.1)                
 foreign        0.8-81     2020-12-22 [2] CRAN (R 4.1.1)                
 fs             1.5.0      2020-07-31 [1] CRAN (R 4.1.1)                
 gdtools        0.2.3      2021-01-06 [1] CRAN (R 4.1.1)                
 generics       0.1.1      2021-10-25 [1] CRAN (R 4.1.1)                
 gganimate    * 1.0.7      2020-10-15 [1] CRAN (R 4.1.1)                
 ggplot2      * 3.3.5      2021-06-25 [1] CRAN (R 4.1.1)                
 ggthemes     * 4.2.4      2021-01-20 [1] CRAN (R 4.1.1)                
 gifski         1.4.3-1    2021-05-02 [1] CRAN (R 4.1.1)                
 glue           1.4.2      2020-08-27 [1] CRAN (R 4.1.1)                
 gtable         0.3.0      2019-03-25 [1] CRAN (R 4.1.1)                
 haven          2.4.3      2021-08-04 [1] CRAN (R 4.1.1)                
 here           1.0.1      2020-12-13 [1] CRAN (R 4.1.1)                
 highr          0.9        2021-04-16 [1] CRAN (R 4.1.1)                
 hms            1.1.0      2021-05-17 [1] CRAN (R 4.1.1)                
 hrbrthemes   * 0.8.0      2020-03-06 [1] CRAN (R 4.1.1)                
 htmltools      0.5.2      2021-08-25 [1] CRAN (R 4.1.1)                
 htmlwidgets    1.5.4      2021-09-08 [1] CRAN (R 4.1.1)                
 httr           1.4.2      2020-07-20 [1] CRAN (R 4.1.1)                
 jquerylib      0.1.4      2021-04-26 [1] CRAN (R 4.1.1)                
 jsonlite       1.7.2      2020-12-09 [1] CRAN (R 4.1.1)                
 KernSmooth     2.23-20    2021-05-03 [2] CRAN (R 4.1.1)                
 klippy       * 0.0.0.9500 2021-11-12 [1] Github (rlesur/klippy@378c247)
 knitr        * 1.36       2021-09-29 [1] CRAN (R 4.1.1)                
 labeling       0.4.2      2020-10-20 [1] CRAN (R 4.1.1)                
 lazyeval       0.2.2      2019-03-15 [1] CRAN (R 4.1.1)                
 lifecycle      1.0.1      2021-09-24 [1] CRAN (R 4.1.1)                
 lubridate      1.7.10     2021-02-26 [1] CRAN (R 4.1.1)                
 magrittr       2.0.1      2020-11-17 [1] CRAN (R 4.1.1)                
 mapSpain     * 0.4.0      2021-10-14 [1] CRAN (R 4.1.2)                
 modelr         0.1.8      2020-05-19 [1] CRAN (R 4.1.1)                
 munsell        0.5.0      2018-06-12 [1] CRAN (R 4.1.1)                
 openxlsx       4.2.4      2021-06-16 [1] CRAN (R 4.1.1)                
 pillar         1.6.4      2021-10-18 [1] CRAN (R 4.1.1)                
 pkgconfig      2.0.3      2019-09-22 [1] CRAN (R 4.1.1)                
 plotly       * 4.10.0     2021-10-09 [1] CRAN (R 4.1.2)                
 plyr           1.8.6      2020-03-03 [1] CRAN (R 4.1.1)                
 png            0.1-7      2013-12-03 [1] CRAN (R 4.1.1)                
 prettyunits    1.1.1      2020-01-24 [1] CRAN (R 4.1.1)                
 progress       1.2.2      2019-05-16 [1] CRAN (R 4.1.1)                
 proxy          0.4-26     2021-06-07 [1] CRAN (R 4.1.1)                
 purrr        * 0.3.4      2020-04-17 [1] CRAN (R 4.1.1)                
 R6             2.5.1      2021-08-19 [1] CRAN (R 4.1.1)                
 rappdirs       0.3.3      2021-01-31 [1] CRAN (R 4.1.1)                
 RColorBrewer   1.1-2      2014-12-07 [1] CRAN (R 4.1.1)                
 Rcpp           1.0.7      2021-07-07 [1] CRAN (R 4.1.1)                
 readr        * 2.0.1      2021-08-10 [1] CRAN (R 4.1.1)                
 readxl         1.3.1      2019-03-13 [1] CRAN (R 4.1.1)                
 reprex         2.0.1      2021-08-05 [1] CRAN (R 4.1.1)                
 rio            0.5.27     2021-06-21 [1] CRAN (R 4.1.1)                
 rlang          0.4.12     2021-10-18 [1] CRAN (R 4.1.1)                
 rmarkdown      2.11       2021-09-14 [1] CRAN (R 4.1.1)                
 rprojroot      2.0.2      2020-11-15 [1] CRAN (R 4.1.1)                
 rstudioapi     0.13       2020-11-12 [1] CRAN (R 4.1.1)                
 Rttf2pt1       1.3.9      2021-07-22 [1] CRAN (R 4.1.1)                
 rvest          1.0.1      2021-07-26 [1] CRAN (R 4.1.1)                
 s2             1.0.7      2021-09-28 [1] CRAN (R 4.1.2)                
 sass           0.4.0      2021-05-12 [1] CRAN (R 4.1.1)                
 scales         1.1.1      2020-05-11 [1] CRAN (R 4.1.1)                
 sessioninfo    1.1.1      2018-11-05 [1] CRAN (R 4.1.1)                
 sf           * 1.0-2      2021-07-26 [1] CRAN (R 4.1.1)                
 stringi        1.7.5      2021-10-04 [1] CRAN (R 4.1.1)                
 stringr      * 1.4.0      2019-02-10 [1] CRAN (R 4.1.1)                
 systemfonts    1.0.3      2021-10-13 [1] CRAN (R 4.1.1)                
 tibble       * 3.1.5      2021-09-30 [1] CRAN (R 4.1.1)                
 tidyr        * 1.1.4      2021-09-27 [1] CRAN (R 4.1.1)                
 tidyselect     1.1.1      2021-04-30 [1] CRAN (R 4.1.1)                
 tidyverse    * 1.3.1      2021-04-15 [1] CRAN (R 4.1.1)                
 tweenr         1.0.2      2021-03-23 [1] CRAN (R 4.1.1)                
 tzdb           0.1.2      2021-07-20 [1] CRAN (R 4.1.1)                
 units          0.7-2      2021-06-08 [1] CRAN (R 4.1.1)                
 utf8           1.2.2      2021-07-24 [1] CRAN (R 4.1.1)                
 vctrs          0.3.8      2021-04-29 [1] CRAN (R 4.1.1)                
 viridisLite    0.4.0      2021-04-13 [1] CRAN (R 4.1.1)                
 withr          2.4.3      2021-11-30 [1] CRAN (R 4.1.2)                
 wk             0.5.0      2021-07-13 [1] CRAN (R 4.1.1)                
 xfun           0.25       2021-08-06 [1] CRAN (R 4.1.1)                
 xml2           1.3.2      2020-04-23 [1] CRAN (R 4.1.1)                
 yaml           2.2.1      2020-02-01 [1] CRAN (R 4.1.1)                
 zip            2.2.0      2021-05-31 [1] CRAN (R 4.1.1)                

[1] C:/Users/pepec/Documents/R/win-library/4.1
[2] C:/Program Files/R/R-4.1.1/library






LS0tDQp0aXRsZTogIkNhbHAgZGVudHJvIGRlIGxhIE1hcmluYSBBbHRhIg0Kc3VidGl0bGU6ICJKb3PDqSBQaW5lZGEgVG9ycmVzKHBpdG9qb0BhbHVtbmkudXYuZXMpIiANCmF1dGhvcjogIlVuaXZlcnNpdGF0IGRlIFZhbMOobmNpYSINCmRhdGU6ICJEaWNpZW1icmUgZGUgMjAyMSAoYWN0dWFsaXphZG8gZWwgYHIgZm9ybWF0KFN5cy50aW1lKCksICclZC0lbS0lWScpYCkiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6DQogICAgdGhlbWU6IHBhcGVyDQogICAgaGlnaGxpZ2h0OiB0ZXh0bWF0ZSANCiAgICB0b2M6IHRydWUNCiAgICB0b2NfZGVwdGg6IDMgDQogICAgdG9jX2Zsb2F0OiANCiAgICAgIGNvbGxhcHNlZDogdHJ1ZQ0KICAgICAgc21vb3RoX3Njcm9sbDogdHJ1ZQ0KICAgIHNlbGZfY29udGFpbmVkOiB0cnVlDQogICAgbnVtYmVyX3NlY3Rpb25zOiBmYWxzZQ0KICAgIGRmX3ByaW50OiBrYWJsZQ0KICAgIGNvZGVfZG93bmxvYWQ6IHRydWUNCiAgICBjb2RlX2ZvbGRpbmc6IHNob3cgDQplZGl0b3Jfb3B0aW9uczogDQogIGNodW5rX291dHB1dF90eXBlOiBjb25zb2xlDQotLS0NCg0KYGBge3IgcGFja2FnZXMtc2V0dXAsIGluY2x1ZGUgPSBGQUxTRX0NCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShrbGlwcHkpICAjLSByZW1vdGVzOjppbnN0YWxsX2dpdGh1Yigicmxlc3VyL2tsaXBweSIpDQpsaWJyYXJ5KGtuaXRyKQ0KbGlicmFyeShzZikNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkobWFwU3BhaW4pDQpsaWJyYXJ5KHBsb3RseSkNCmxpYnJhcnkoZ2dhbmltYXRlKQ0KbGlicmFyeShnZ3RoZW1lcykNCmxpYnJhcnkoaHJicnRoZW1lcykNCmxpYnJhcnkoRFQpDQpgYGANCg0KYGBge3IgY2h1bmstc2V0dXAsIGluY2x1ZGUgPSBGQUxTRX0NCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSwgZXZhbCA9IFRSVUUsIG1lc3NhZ2UgPSBGQUxTRSwgd2FybmluZyA9IEZBTFNFLCANCiAgICAgICAgICAgICAgICAgICAgICAjcmVzdWx0cyA9ICJob2xkIiwNCiAgICAgICAgICAgICAgICAgICAgICBjYWNoZSA9IEZBTFNFLCBjYWNoZS5wYXRoID0gIi9jYWNoZXMvIiwgY29tbWVudCA9ICIjPiIsDQogICAgICAgICAgICAgICAgICAgICAgI2ZpZy53aWR0aCA9IDcsICNmaWcuaGVpZ2h0PSA3LCAgIA0KICAgICAgICAgICAgICAgICAgICAgICNvdXQud2lkdGggPSA3LCBvdXQuaGVpZ2h0ID0gNywNCiAgICAgICAgICAgICAgICAgICAgICBjb2xsYXBzZSA9IFRSVUUsICBmaWcuc2hvdyA9ICJob2xkIiwNCiAgICAgICAgICAgICAgICAgICAgICBmaWcuYXNwID0gMC42MjgsIG91dC53aWR0aCA9ICI3NSUiLCBmaWcuYWxpZ24gPSAiY2VudGVyIikNCmtuaXRyOjpvcHRzX2NodW5rJHNldChkZXYgPSAicG5nIiwgZGV2LmFyZ3MgPSBsaXN0KHR5cGUgPSAiY2Fpcm8tcG5nIikpDQpgYGANCg0KDQpgYGB7ciBvcHRpb25zLXNldHVwLCBpbmNsdWRlID0gRkFMU0V9DQpvcHRpb25zKHNjaXBlbiA9IDk5OSkgIy0gcGFyYSBxdWl0YXIgbGEgbm90YWNpw7NuIGNpZW50w61maWNhDQpvcHRpb25zKCJ5YW1sLmV2YWwuZXhwciIgPSBUUlVFKSANCmBgYA0KDQoNCmBgYHtyIGtsaXBweSwgZWNobyA9IEZBTFNFfQ0Ka2xpcHB5OjprbGlwcHkocG9zaXRpb24gPSBjKCJ0b3AiLCAicmlnaHQiKSkgIy0gcmVtb3Rlczo6aW5zdGFsbF9naXRodWIoInJsZXN1ci9rbGlwcHkiKQ0KYGBgDQoNCg0KPGhyIGNsYXNzPSJsaW5lYS1ibGFjayI+DQoNCjwhLS0gRWwgcMOhcnJhZm8gZGUgYWJham8gaGFzIGRlIGRlamFybG8gY2FzaSBpZ3VhbCwgc29sbyBIQVMgZGUgU1VTVElUVUlSICJwZXJlenA0NCIgcG9yIHR1IHVzdWFyaW8gZGUgR2l0aHViLS0+DQpUcmFiYWpvIGVsYWJvcmFkbyBwYXJhIGxhIGFzaWduYXR1cmEgIlByb2dyYW1hY2nDs24geSBtYW5lam8gZGUgZGF0b3MgZW4gbGEgZXJhIGRlbCBCaWcgRGF0YSIgZGUgbGEgVW5pdmVyc2l0YXQgZGUgVmFsw6huY2lhIGR1cmFudGUgZWwgY3Vyc28gMjAyMS0yMDIyLiBFbCByZXBvIGRlbCB0cmFiYWpvIGVzdMOhIFthcXXDrV0oaHR0cHM6Ly9naXRodWIuY29tL3BpdG9qby90cmFiYWpvX0JpZ0RhdGEpe3RhcmdldD0iX2JsYW5rIn0uIA0KDQo8IS0tIEVsIHDDoXJyYWZvIGRlIGFiYWpvIGhhcyBkZSBkZWphcmxvIGV4YWN0YW1lbnRlIGlndWFsLCBOTyBIQVMgREUgQ0FNQklBUiBOQURBLS0+DQoNCkxhIHDDoWdpbmEgd2ViIGRlIGxhIGFzaWduYXR1cmEgeSBsb3MgdHJhYmFqb3MgZGUgbWlzIGNvbXBhw7Flcm9zIHB1ZWRlbiB2ZXJzZSBbYXF1w61dKGh0dHBzOi8vcGVyZXpwNDQuZ2l0aHViLmlvL2ludHJvLWRzLTIxLTIyLXdlYi8wNy10cmFiYWpvcy5odG1sKXt0YXJnZXQ9Il9ibGFuayJ9Lg0KDQoNCjxociBjbGFzcz0ibGluZWEtcmVkIj4NCg0KIyBbMS4gSW50cm9kdWNjacOzbl17LnZlcmRlY2l0b30NCg0KDQpFbCBvYmpldGl2byBkZSBlc3RlIHRyYWJham8gZXMgdmVyIGNvbW8gZXN0YSBzaXR1YWRvIG1pIHB1ZWJsbyBuYXRhbCwgQ2FscCwgcmVzcGVjdG8gYSBzdXMgdmVjaW5vcyBjb21hcmNhbGVzICoqZW4gY3VhbnRvIGEgcG9ibGFjacOzbiB5IGEgbml2ZWwgdHVyw61zdGljbyoqLiANCg0KYGBge3IgZXZhbD0gVFJVRX0NCg0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoaGVyZTo6aGVyZSgiaW1hZ2VuZXMiLCAiQ2FscGUucG5nIikpDQoNCg0KYGBgDQoNCiMgMi4gRGF0b3MNCg0KQ2FzaSBUb2RvcyBsb3MgZGF0b3MgcHJvY2VkZW4gZGUgdW4gcG9ydGFsIGRlIGxhIE1hcmluYSBBbHRhIHF1ZSByZWNvZ2UgZXN0YWTDrXN0aWNhcyBkZSBzdXMgbXVuaWNpcGlvcyB5IGRlIGxhIHJlZ2nDs24gZW4gZ2VuZXJhbCwgeSBjdXlvIG5vbWJyZSBlcyBbT2JzZXJ2YXRvcmlvIE1hcmluYSBBbHRhXShodHRwczovL29ic2VydmF0b3JpbWFyaW5hYWx0YS5vcmcvKS4NCg0KDQojIDMuIFBPQkxBQ0nDk04gRU4gTEEgTUFSSU5BIEFMVEENCg0KDQpFbiBlbCBtYXBhIHF1ZSBzZSBwcmVzZW50YSBhYmFqbywgcG9kZW1vcyBvYnNlcnZhciBsb3MgbXVuaWNpcGlvcyBkZSBsYSBNYXJpbmEgQWx0YSBjb24gbWF5b3IgcG9ibGFjacOzbi4gRXN0b3MgbXVuaWNpcGlvcyBjb2luY2lkZW4gY29uIGxvcyBjb3N0ZXJvcywgZW4gbG9zIHF1ZSBoYXkgbWF5b3IgYWN0aXZpZGFkLg0KDQpgYGB7ciwgZXZhbCA9IFRSVUV9DQoNCm11bmljaXBpb3NfYWxpY2FudGUgPC1yaW86OmltcG9ydChoZXJlOjpoZXJlKCJkYXRvcyIsICJwb2JsYWNpb24ueGxzeCIpKQ0KDQptdW5pX0EgPC0gbXVuaWNpcGlvc19hbGljYW50ZSAlPiUgZmlsdGVyKHllYXIgPT0gMjAxOCkNCg0KbXVuaSA8LSBlc3BfZ2V0X211bmljKHllYXIgPSAiMjAxOSIsIHJlZ2lvbiA9ICJBbGljYW50ZSIpDQoNCmRmIDwtIGxlZnRfam9pbihtdW5pX0EsIG11bmksIGJ5ID0gYygiQW1iaXRvIGdlb2dyYWZpY28iID0gIm5hbWUiICkpDQoNCmRmIDwtIGRmICU+JSByZW5hbWUobXVuaWNpcGlvID0gIkFtYml0byBnZW9ncmFmaWNvIikNCg0KDQpwdzwtIGdncGxvdChkZikgKyBnZW9tX3NmKGFlcyhnZW9tZXRyeSA9IGdlb21ldHJ5LCBmaWxsID0gUG9ibGFjaW9uKSkgDQoNCnAxIDwtIHB3KyBzY2FsZV9maWxsX3ZpcmlkaXNfYyhvcHRpb24gPSAibGlndGhncmVlbiIsIHRyYW5zID0gInNxcnQiKSArIA0KICBsYWJzKHRpdGxlID0gJ1BvYmxhY2lvbiBMYSBNYXJpbmEgQWxhJywgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VidGl0bGUgPSAiKFBvciBNdW5pY2lwaW9zKSIsDQogICAgICAgY2FwdGlvbiA9ICJEYXRvcyBwcm92ZW5pZW50ZXMgZGUgbWFwU3BhaW4gKHBhcXVldGUpIHkgb2JzZXJ2YXRvcmlvbWFyaW5hYWx0YS5vcmciLA0KICAgICAgIHRhZyA9ICJNYXBhIG11bmljaXBpb3MiKQ0KDQoNCndvcmxkX3BvaW50cyA8LSBjYmluZChkZiwgc3RfY29vcmRpbmF0ZXMoc3RfY2VudHJvaWQoZGYkZ2VvbWV0cnksIG9mX2xhcmdlc3RfcG9seWdvbiA9IFRSVUUpKSkNCg0KcDIgPC0gcDEgKyBnZW9tX3RleHQoZGF0YSA9IHdvcmxkX3BvaW50cywgDQogICAgICAgICAgYWVzKHggPSBYLCB5ID0gWSwgbGFiZWwgPSBtdW5pY2lwaW8pLCANCiAgICAgICAgICBjb2xvciA9ICJ3aGl0ZSIsIGZvbnRmYWNlID0gImJvbGQiLCBjaGVja19vdmVybGFwID0gVFJVRSwgc2l6ZSA9IDIuNSkgKyANCiAgbGFicyh5ID0gTlVMTCkgKw0KICBsYWJzKHggPSBOVUxMKQ0KDQpwMg0KDQpgYGANCg0KDQojIyAzLjEgVmFyaWFjacOzbiBwb2JsYWNpb25hbA0KDQoNClBhcmEgbW9zdHJhcmxvIGhlbW9zIGVsZWdpZG8gbG9zIG11bmljaXBpb3MgcXVlIG1heW9yIHZhcmlhY2nDs24gdGllbmVuLiBQb3Igbm9ybWEgZ2VuZXJhbCwgZXN0YSBzaXR1YWNpw7NuIHNlIGRhIGVuIHZlcmFubyBwb3IgbGEgZWxldmFkYSBhZmx1ZW5jaWEgZGUgdHVyaXN0YXMgcXVlIHZhbiBhIHB1ZWJsb3MgY29zdGVyb3MgcGFyYSBkaXNmcnV0YXIgZGUgbGFzIHZhY2FjaW9uZXMgZW4gbGEgcGxheWEuIFBhcmEgYmllbiBvIHBhcmEgbWFsLCBlbCB0dXJpc21vIHByZWRvbWluYW50ZSBlcyBsYSB6b25hIGVzIGVsIGRlIFNvbCB5IFBsYXlhLiANCg0KYGBge3IsIGV2YWwgPSBUUlVFfQ0KcG9iIDwtIHJpbzo6aW1wb3J0KGhlcmU6OmhlcmUoImRhdG9zIiwgInZhcmlhY2lvbl9wb2JsYWNpb25hbC54bHN4IikpDQoNCnZhcl9wb2IgPC0gcG9iICU+JSByZW5hbWUocG9ibGFjaW9uX2VzdGFjaW9uYWxfbWF4aW1hID0gIlBvYmxhY2nDs24gRXN0YWNpb25hbCBNw6F4aW1hIiAsIHBvYmxhY2lvbl9lbXBhZHJvbmFkYSA9ICJQb2JsYWNpw7NuIEVtcGFkcm9uYWRhIiwgYW1iaXRvX2dlb2dyYWZpY28gPSAiw4FtYml0byBnZW9ncsOhZmljbyIgKSAlPiUNCiAgZ3JvdXBfYnkoYGFtYml0b19nZW9ncmFmaWNvYCkgJT4lDQogIGFycmFuZ2UoQcOxbykgJT4lDQogIG11dGF0ZSh0YXNhX3ZhcmlhY2lvbl9wb2JsYWNpb25hbCA9IChwb2JsYWNpb25fZXN0YWNpb25hbF9tYXhpbWEgLyBwb2JsYWNpb25fZW1wYWRyb25hZGEpKjEwMCkgJT4lDQogIHVuZ3JvdXAoKQ0KDQoNCnBwIDwtIGdncGxvdCh2YXJfcG9iLCBhZXMoeCA9IEHDsW8sIHkgPSB0YXNhX3ZhcmlhY2lvbl9wb2JsYWNpb25hbCwgZ3JvdXAgPSBhbWJpdG9fZ2VvZ3JhZmljbywgY29sb3I9YW1iaXRvX2dlb2dyYWZpY28pKSsNCiAgZ2VvbV9saW5lKCkrIA0KICBnZW9tX3BvaW50KCkgKw0KICBnZ3RpdGxlKCJFdm9sdWNpw7NuIGRlIGxhIHRhc2EgZGUgdmFyaWFjacOzbiBwb2JsYWNpb25hbCIpICsNCiAgdGhlbWVfaXBzdW0oKSArDQogIHNjYWxlX3hfY29udGludW91cyhicmVha3M9c2VxKDIwMTEsMjAyMCwyKSxsaW1pdHM9YygyMDExLDIwMjApKSArIGxhYnMoeSA9IE5VTEwsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSAiw4FtYml0byBnZW9ncsOhZmljbyIpDQpwcCArIHRyYW5zaXRpb25fcmV2ZWFsKEHDsW8pDQoNCmBgYA0KDQojIyMgMy4xLjEuIFZhcmlhY2nDs24gcG9ibGFjaW9uYWwgZGUgQ2FscA0KDQpQYXJhIGVsIGNhc28gZXNwZWPDrWZpY28gZGUgQ2FscCwgdmVtb3MgcXVlIGxhIHZhcmlhY2nDs24gZGUgbGEgcG9ibGFjacOzbiBsbGVnYSBhIHVuIDgwMCUsIGVzIGRlY2lyLCBxdWUgbGEgcG9ibGFjacOzbiBlcyA4IHZlY2VzIG1heW9yIHF1ZSBsYSBlbXBhZHJvbmFkYS4gRXN0byBzZSBkZWJlLCBjb21vIHlhIGhlbW9zIG1lbmNpb25hZG8gYSBsYSBlbm9ybWUgYWZsdWVuY2lhIGRlIHR1cmlzdGFzIHF1ZSByZWNpYmUgbGEgY29zdGEuIE5vIG9ic3RhbnRlLCBoYXkgdW5hIGNsYXJhIGJhamFkYSBwYXJhIGVsIGHDsW8gMjAyMCBkZWJpZG8gYSBsYXMgcmVzdHJpY2Npb25lcyBkZSBtb3ZpbGlkYWQgeSBlbCBtaWVkbyBjYXVzYWRvIHBvciBlbCBDT1ZJRC0xOS4NCg0KDQpgYGB7ciwgZXZhbCA9IFRSVUV9DQp2YXJfcG9iX2NhbHAgPC0gdmFyX3BvYiAlPiUgZmlsdGVyKGBhbWJpdG9fZ2VvZ3JhZmljb2A9PSAiQ2FscCIpDQoNCnBwb2IgPC0gZ2dwbG90KHZhcl9wb2JfY2FscCwgYWVzKEHDsW8sIHRhc2FfdmFyaWFjaW9uX3BvYmxhY2lvbmFsLCBmaWxsID0gdGFzYV92YXJpYWNpb25fcG9ibGFjaW9uYWwpKSArDQogIGdlb21fY29sKCkgKw0KICBzY2FsZV9maWxsX2Rpc3RpbGxlcihwYWxldHRlID0gIkJsdWVzIiwgZGlyZWN0aW9uID0gMSkgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZSgNCiAgICBwYW5lbC5ncmlkID0gZWxlbWVudF9ibGFuaygpLA0KICAgIHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfbGluZShjb2xvciA9ICJ3aGl0ZSIpLA0KICAgIHBhbmVsLm9udG9wID0gVFJVRQ0KICApICsgdHJhbnNpdGlvbl9zdGF0ZXMoQcOxbywgd3JhcCA9IEZBTFNFKSArDQogIHNoYWRvd19tYXJrKCkNCnBwb2INCmBgYA0KDQoNCiMgNC4gUEFSTyBFTiBMQSBNQVJJTkEgQUxUQQ0KDQpQYXJhIGVzdGUgYW7DoWxpc2lzIG5vcyBjZW50cmFyZW1vcyBlbiBsb3MgcHJpbmNpcGFsZXMgcHVudG9zIHR1csOtc3RpY29zIGRlIGxhIHJlZ2nDs24uDQoNCmBgYHtyLCBldmFsID0gVFJVRX0NCnRhc2FfcGFybyA8LSByaW86OmltcG9ydChoZXJlOjpoZXJlKCJkYXRvcyIsICJ0YXNhIGRlIHBhcm8gc2VndW4gYWN0aXZpZGFkLnhsc3giKSkNCg0KdGFzYV9wYXJvMSA8LSB0YXNhX3Bhcm8gJT4lIHNlbGVjdChQZXJpb2RvLCBgw4FtYml0byBnZW9ncsOhZmljb2AsIGBUYXNhIGRlIHBhcm8gdG90YWwgKCUpYCkgJT4lIA0KICBncm91cF9ieShgw4FtYml0byBnZW9ncsOhZmljb2ApICU+JSANCiAgYXJyYW5nZShQZXJpb2RvKSAlPiUNCiAgbXV0YXRlKGNyZWNfdGFzYV9wYXJvID0gYFRhc2EgZGUgcGFybyB0b3RhbCAoJSlgIC0gbGFnKGBUYXNhIGRlIHBhcm8gdG90YWwgKCUpYCkpICU+JSANCiAgbXV0YXRlKGNyZWNfdGFzYV9wYXJvX2Rlc2RlXzIwMTYgPSBgVGFzYSBkZSBwYXJvIHRvdGFsICglKWAgLSBmaXJzdChgVGFzYSBkZSBwYXJvIHRvdGFsICglKWApKSAlPiUNCiAgdW5ncm91cCgpDQoNCkRUOjpkYXRhdGFibGUodGFzYV9wYXJvMSwgZmlsdGVyID0gJ3RvcCcsIG9wdGlvbnMgPSBsaXN0KA0KICBwYWdlTGVuZ3RoID0gNiwgYXV0b1dpZHRoID0gVFJVRSwgY2FwdGlvbiA9IGh0bWx0b29sczo6dGFncyRjYXB0aW9uKA0KICAgIHN0eWxlID0gJ2NhcHRpb24tc2lkZTogYm90dG9tOyB0ZXh0LWFsaWduOiBjZW50ZXI7JywNCiAgICAnVGFibGUgMTogJywgaHRtbHRvb2xzOjplbSgnVGFzYSBkZSBwYXJvLicpDQogICkNCikpDQoNCmBgYA0KDQoNCkVuIGzDrW5lYXMgZ2VuZXJhbGVzIHBvZGVtb3MgZGVjaXIgcXVlIGVsIHBhcm8gaGEgZGVzY2VuZGlkbyBlbiBsYSByZWdpw7NuIHBvciBsbyBxdWUgcGFyZWNlIHNlciBxdWUgc2UgdmEgZW4gbGEgYnVlbmEgZGlyZWNjacOzbi4gRWwgbXVuaWNpcGlvIGRvbmRlIG3DoXMgaGEgYmFqYWRvIGVsIHBhcm8gZGVzZGUgMjAxNiBlcyBKw6F2ZWEsIGVuIHVuIC00Ljk2JS4gTm8gb2JzdGFudGUsIGVsIHBhcm8gZW4gRXNwYcOxYSBlcyBkZSB1biAxNCw1JSwgcG9yIGRlYmFqbyBkZSBsb3MgcHJpbmNpcGFsZXMgbXVuaWNpcGlvcyBkZSBsYSBNYXJpbmEgQWx0YS4gRW4gY3VhbnRvIGEgQ2FscCwgcG9kZW1vcyB2ZXIgcXVlIHRpZW5lIHVuIHBhcm8gZW4gZWwgdGVyY2VyIHRyaW1lc3RyZSBkZWwgMjAyMSBkZWwgMTcuMzklLCB1bmEgdGFzYSBjb25zaWRlcmFibGUsIG9jdXBhbmRvIGVsIHRlcmNlciBwdWVzdG8gZGUgbG9zIG11bmljaXBpb3MgZGUgbGEgdGFibGEuDQoNCkEgY29udGludWFjacOzbiB2YW1vcyBhIGFuYWxpemFyIGxhcyB0YXNhcyBkZSBwYXJvIGVuIGVsIHNlY3RvciBzZXJ2aWNpb3MgeSBtw6FzIGFkZWxhbnRlIGxhIGRlIGxhIGNvbnN0cnVjY2nDs24sIGxvcyBkb3Mgc2Vjb3RyZXMgY2xhdmVzIGRlIGxhIHJlZ2nDs24uDQoNCkVsIHNlY3RvciBzZXJ2aWNpb3MgdGllbmUgdW5hIGdyYW4gaW1wb3J0YW5jaWEgeSBlcyBlbCBxdWUgbcOhcyBkZW1hbmRhIHRpZW5lLCBkZWJpZG8gYSBsYSBkZXBlbmRlbmNpYSBkZWwgdHVyaXNtbyBlbiBsYSB6b25hLg0KDQpgYGB7ciwgZXZhbCA9IFRSVUV9DQp0YXNhX3Bhcm8yIDwtIHRhc2FfcGFybyAlPiUgc2VsZWN0KFBlcmlvZG8sIGDDgW1iaXRvIGdlb2dyw6FmaWNvYCwgYFRhc2EgZGUgcGFybyBTZXJ2aWNpb3MgKCUpYCkgJT4lDQogIGdyb3VwX2J5KGDDgW1iaXRvIGdlb2dyw6FmaWNvYCkgJT4lDQogIGFycmFuZ2UoUGVyaW9kbykgJT4lDQogIG11dGF0ZShjcmVjX3Rhc2FfcGFyb19TZXJ2aWNpb3MgPSBgVGFzYSBkZSBwYXJvIFNlcnZpY2lvcyAoJSlgIC0gbGFnKGBUYXNhIGRlIHBhcm8gU2VydmljaW9zICglKWApKSAlPiUNCiAgbXV0YXRlKGNyZWNfdGFzYV9wYXJvX2Rlc2RlXzIwMTZfU2VydmljaW9zID0gYFRhc2EgZGUgcGFybyBTZXJ2aWNpb3MgKCUpYCAtIGZpcnN0KGBUYXNhIGRlIHBhcm8gU2VydmljaW9zICglKWApKSAgJT4lDQogIHVuZ3JvdXAoKQ0KDQoNCkRUOjpkYXRhdGFibGUodGFzYV9wYXJvMiwgZmlsdGVyID0gJ3RvcCcsIG9wdGlvbnMgPSBsaXN0KA0KICBwYWdlTGVuZ3RoID0gNiwgYXV0b1dpZHRoID0gVFJVRSwgY2FwdGlvbiA9IGh0bWx0b29sczo6dGFncyRjYXB0aW9uKA0KICAgIHN0eWxlID0gJ2NhcHRpb24tc2lkZTogYm90dG9tOyB0ZXh0LWFsaWduOiBjZW50ZXI7JywNCiAgICAnVGFibGEgMjogJywgaHRtbHRvb2xzOjplbSgnVGFzYSBkZSBwYXJvIHNlcnZpY2lvcy4nKQ0KICApDQopKQ0KYGBgDQoNCg0KU2kgbm9zIGZpamFtb3Mgw7puaWNhbWVudGUgZW4gZWwgc2VjdG9yIHNlcnZpY2lvcyBlbCBtdW5pY2lwaW8gcXVlIG3DoXMgaGEgcmVkdWNpZG8gc3UgcGFybyBkZXNkZSAyMDE2IGhhIHNpZG8gQ2FscCwgY29uIHVuYSBiYWphZGEgZGVsIDUsMDYlLCBidWVuIHPDrW50b21hIGRlIHJlY3VwZXJhY2nDs24geWEgcXVlIGVsIHBhcm8gbm8gZGVqw7MgZGUgYXVtZW50YXIgZGVzZGUgZWwgaW5pY2lvIGRlIGxhIHBhbmRlbWlhIGhhc3RhIGVsIHNlZ3VuZG8gdHJpbWVzdHJlIGRlIDIwMjEuIENhYmUgZGVjaXIgcXVlIHRvZG9zIGxvcyBkZW3DoXMgbXVuaWNpcGlvcyBoYW4gc2VndWlkbyBsYSB0ZW5kZW5jaWEuDQoNCg0KYGBge3IsIGV2YWwgPSBUUlVFfQ0KdGFzYV9wYXJvMyA8LSB0YXNhX3Bhcm8gJT4lIHNlbGVjdChQZXJpb2RvLCBgw4FtYml0byBnZW9ncsOhZmljb2AsIGBUYXNhIGRlIHBhcm8gQ29uc3RydWNjacOzbiAoJSlgKSAlPiUNCiAgZ3JvdXBfYnkoYMOBbWJpdG8gZ2VvZ3LDoWZpY29gKSAlPiUNCiAgYXJyYW5nZShQZXJpb2RvKSAlPiUNCiAgbXV0YXRlKGNyZWNfdGFzYV9wYXJvX0NvbnN0cnVjY2nDs24gPSBgVGFzYSBkZSBwYXJvIENvbnN0cnVjY2nDs24gKCUpYCAtIGxhZyhgVGFzYSBkZSBwYXJvIENvbnN0cnVjY2nDs24gKCUpYCkpICU+JQ0KICBtdXRhdGUoY3JlY190YXNhX3Bhcm9fQ29uc3RydWNjacOzbl9kZXNkZV8yMDE2ID0gYFRhc2EgZGUgcGFybyBDb25zdHJ1Y2Npw7NuICglKWAgLSBmaXJzdChgVGFzYSBkZSBwYXJvIENvbnN0cnVjY2nDs24gKCUpYCkpICU+JSANCiAgdW5ncm91cCgpDQoNCkRUOjpkYXRhdGFibGUodGFzYV9wYXJvMywgZmlsdGVyID0gJ3RvcCcsIG9wdGlvbnMgPSBsaXN0KA0KICBwYWdlTGVuZ3RoID0gNiwgYXV0b1dpZHRoID0gVFJVRSwgY2FwdGlvbiA9IGh0bWx0b29sczo6dGFncyRjYXB0aW9uKA0KICAgIHN0eWxlID0gJ2NhcHRpb24tc2lkZTogYm90dG9tOyB0ZXh0LWFsaWduOiBjZW50ZXI7JywNCiAgICAnVGFibGEgMzogJywgaHRtbHRvb2xzOjplbSgnVGFzYSBkZSBwYXJvIGNvbnN0cnVjY2nDs24uJykNCiAgKQ0KKSkNCmBgYA0KDQoNClJlc3BlY3RvIGFsIHNlY3RvciBkZSBsYSBjb25zdHJ1Y2Npw7NuLCBvYnNlcnZhbW9zIHF1ZSB0YW1iacOpbiBzZSBoYSByZWR1Y2lkbyBlbCBwYXJvIGRlc2RlIDIwMTYgc2llbmRvIENhbHAgZWwgbXVuaWNpcGlvIGVuIGVsIHF1ZSBtZW5vcyBoYSBkZXNjZW5kaWRvIHkgc2llbmRvIETDqW5pYSB5IEVscyBQb2JsZXRzIGVuIGxvcyBxdWUgbGEgYmFqYWRhIGhhIHNpZG8gbWF5b3IsIGRlIGhhc3RhIHVuIDklLg0KDQoNCkVsIHNlY3RvciBkZSBzZXJ2aWNpb3MganVudG8gY29uIGxhIGNvbnN0cnVjY2nDs24sIHNvbiBsb3MgZG9zIG1vdG9yZXMgZGUgbGEgcmVnacOzbiBkZWJpZG8gYSBxdWUgbGEgYWN0aXZpZGFkIHByaW5jaXBhbCBlcyBlbCB0dXJpc21vLCBwZXJvIHB1ZWRlIGNvbmxsZXZhciBwcm9ibGVtYXMgZGUgbWFzaWZpY2FjacOzbiB5IGNvbnRhbWluYWNpw7NuLiANCg0KRWwgdHVyaXNtbyBlcyB1biBzZWN0b3IgZXN0cmF0w6lnaWNvLCBkaW7DoW1pY28geSBlc2VuY2lhbCBlbiBlbCBkZXNhcnJvbGxvIGRlIGxhIE1hcmluYSBBbHRhLiBTaWVuZG8gbXV5IHZhbG9yYWRvIHkgY29uIHVuYSBhbHRhIGNhbGlkYWQgZGUgc2VydmljaW8uIEVzdGUgZXN0w6EgaW5tZXJzbyBlbiB1biBwcm9jZXNvIGRlIG1lam9yYSBjb25zdGFudGUgY29uIGxhIGZvcm1hY2nDs24sIGxhIGVjb25vbcOtYSBjaXJjdWxhciB5IGxhIHNvc3RlbmliaWxpZGFkIGFtYmllbnRhbC4NCg0KDQojIDUuIFR1cmlzbW8NCg0KDQpBIGNvbnRpbnVhY2nDs24gdmFtb3MgYSB0cmF0YXIgZGUgb2JzZXJ2YXIgcXVlIG11bmljaXBpbyB0aWVuZSB1biBtYXlvciBuw7ptZXJvIGRlIHBsYXphcyBkZSBhbG9qYW1pZW50b3MgeSB2ZXJlbW9zIGVsIHBvcnF1ZSBkZSBsYSBpbXBvcnRhbmNpYSBkZWwgc2VjdG9yIGRlIGxhIGNvbnN0cnVjY2nDs24geSBkZSBsb3Mgc2VydmljaW9zLg0KDQpFbiBlbCBzaWd1aWVudGUgZ3LDoWZpY28gc2UgbXVlc3RyYSBxdWUgQ2FscCBlcyBlbCBtdW5pY2lwaW8gY29uIG3DoXMgcGxhemFzIGRlIGFsb2phbWllbnRvcyBhw7puIHRlbmllbmRvIG1lbm9zIGhvdGVsZXMgcXVlIHBvciBlamVtcGxvIETDqW5pYS4gRXN0byBxdWllcmUgZGVjaXIgcXVlIENhbHAgZXMgZWwgbXVuaWNpcGlvIGNvbiBtw6FzIGNhcGFjaWRhZCBwYXJhIGFsYmVyZ2FyIHR1cmlzdGFzIGRlIGxhIE1hcmluYSBBbHRhLiBFc3RvIHN1cG9uZSB0ZW5lciB1biBncmFuIGVudHJhbWFkbyBkZSwgeWEgbm8gaG90ZWxlcywgc2kgbm8gZGUgYXBhcnRhbWVudG9zLCBjYW1waW5nIGRlIGNhcmF2YW5hcyB5IHRvZG8gdGlwbyBkZSBhbG9qYW1pZW50b3MuDQoNCg0KYGBge3IsIGV2YWwgPSBUUlVFfQ0KDQphbG9qYW1pZW50b3MgPC0gcmlvOjppbXBvcnQoaGVyZTo6aGVyZSgiZGF0b3MiLCAib2ZlcnRhIGFsb2phbWllbnRvcyB0dXLDrXN0aWNvcyAueGxzeCIpKQ0KDQphbG9qYW1pZW50b3NfMSA8LSBhbG9qYW1pZW50b3MgJT4lIHJlbmFtZShudW1fdG90YWxfcGxhemFzID0gIk7CuiBUb3RhbCBQbGF6YXMiKSAlPiUNCiAgZmlsdGVyKEHDsW8gPT0gMjAyMCkgJT4lIA0KICBzZWxlY3QoQcOxbywgYMOBbWJpdG8gZ2VvZ3LDoWZpY29gLCBudW1fdG90YWxfcGxhemFzKSAlPiUgDQogIGFycmFuZ2UoZGVzYyhudW1fdG90YWxfcGxhemFzKSkNCg0KZGYgPC0gYWxvamFtaWVudG9zXzEgJT4lIG11dGF0ZShgw4FtYml0byBnZW9ncsOhZmljb2AgPSBmb3JjYXRzOjphc19mYWN0b3IoYMOBbWJpdG8gZ2VvZ3LDoWZpY29gKSkNCg0KZGYgPC0gZGYgJT4lIG11dGF0ZShgw4FtYml0byBnZW9ncsOhZmljb2AgPSBmb3JjYXRzOjpmY3RfcmV2KGDDgW1iaXRvIGdlb2dyw6FmaWNvYCkpDQoNCg0KcCA8LSBnZ3Bsb3QoZGYsIGFlcyh4ID0gbnVtX3RvdGFsX3BsYXphcyAsIHkgPSBgw4FtYml0byBnZW9ncsOhZmljb2AgKSkNCnAgKyBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgIGZpbGwgPSAic3RlZWxibHVlIikgKw0KICAgIGxhYnModGl0bGUgPSAiTXVuaWNpcGlvcyBjb24gbcOhcyBwbGF6YXMgZGUgYWxvamFtaWVudG8iLA0KICAgICAgIGNhcHRpb24gPSAiRGF0b3MgcHJvdmVuaWVudGVzIGRlIE9ic2VydmF0b3JpbyBNYXJpbmEgQWx0YSIsDQogICAgICAgeCA9ICJQbGF6YXMgVG90YWxlcyIsDQogICAgICAgeSA9ICJNdW5pY2lwaW9zIiApDQoNCmBgYA0KDQoNCiMjIDYuIE1FSk9SRVMgUExBWUFTDQoNClBhcmEgdmVyIGxhcyBtZWpvcmVzIHBsYXlhcyBoZW1vcyBleHRlbmRpZG8gZWwgYW7DoWxpc2lzIGEgbG9zIG11bmljaXBpb3MgY29uIHBsYXlhcyBkZSBsYSBwcm92aW5jaWEgZGUgQWxpY2FudGUsIHBvZGVtb3Mgb2JzZXJ2YXIgcXVlIGVsIG11bmljaXBpbyBxdWUgbcOhcyBCYW5kZXJhcyBhenVsZXMgdGllbmUgcG9yIGtpbG9tZXRybyBkZSBwbGF5YSBlcyBQaWxhciBkZSBsYSBIb3JhZGFkYS4gQ2FscCwgZW4gZXN0ZSByYW5raW5nIGVzdMOhIGVuIGVsIHB1ZXN0byBuw7ptZXJvIHRyZWNlLg0KDQpMYSBNYXJpbmEgQWx0YSBzZSBjYXJhY3Rlcml6YSBwb3IgdGVuZXIgdW5hcyBwbGF5YXMgZGUgY2FsaWRhZCB5IGxpbXBpYXMsIGFkZW3DoXMsIHRhbWJpw6luIGhhbiBzaWRvIGdhbGFyZG9uYXMgY29uIHByZW1pb3MgY29tbyBsb3Mgb3RvcmdhZG9zIHBvciBsYSBBc29jaWFjacOzbiBkZSBFZHVjYWNpw7NuIEFtYmllbnRhbCB5IGRlbCBDb25zdW1pZG9yIChBZGVhYykuDQoNCmBgYHtyLCBldmFsID0gVFJVRX0NCg0KYmFuZGVyYXNfYXp1bGVzIDwtIHJpbzo6aW1wb3J0KGhlcmU6OmhlcmUoImRhdG9zIiwgIk11bmljaXBpb3MgY29zdGVyb3MgYmFuZGVyYXMgYXp1bGVzIC0gQWxpY2FudGUueGxzeCIpKQ0KDQpCQSA8LSBiYW5kZXJhc19henVsZXMgJT4lIGdyb3VwX2J5KE11bmljaXBpbykgJT4lDQogIG11dGF0ZShiYW5kZXJhc19henVsZXNfcG9yX2tpbG9tZXRybyA9IGBCYW5kZXJhcyBBenVsZXMgMjAyMWAvIGBLbS4gQ29zdGFgKSAlPiUgDQogIG11dGF0ZShiYW5kZXJhc19wb3JfcGxheWEgPSBgQmFuZGVyYXMgQXp1bGVzIDIwMjFgLyBgTsO6bWVybyBQbGF5YXNgICkgJT4lDQogIGFycmFuZ2UoZGVzYyhiYW5kZXJhc19henVsZXNfcG9yX2tpbG9tZXRybykpICU+JSB1bmdyb3VwKCkNCg0KQkENCg0KYGBgDQoNCiMgNy4gQ29uY2x1c2lvbmVzDQoNCkxhIE1hcmluYSBBbHRhIGRlcGVuZGUgZGVsIHR1cmlzbW8sIGVsIGN1YWwgZXMgZWwgbW90b3IgZGUgbGEgZWNvbm9tw61hIGVuIGxhIHJlZ2lvbiwgZXN0byB0cmFlIGNvbnNpZ28gdW4gZWxldmFkbyBwYXJvIGVzdGFjaW9uYWwgcXVlIGxhc3RyYSBlbCBjcmVjaW1pZW50byBlY29uw7NtaWNvLCBwb3IgbG8gcXVlIHNlIGRlYmVyw61hIHNlZ3VpciBhdmFuemFuZG8gaGFjw61hIHVuIHR1cmlzbW8gbWVub3MgZGUgU29sIHkgUGxheWEgeSBtw6FzIGN1bHR1cmFsLCBkZXBvcnRpdm8sIGdhc3Ryb27Ds21pY28sIHJ1cmFsIHkgbWVkaW9hbWJpZW50YWwuDQoNCg0KIyA0LiBCaWJsaW9ncmFmw61hDQoNCltPYnNlcnZhdG9yaW8gTWFyaW5hIEFsdGFdKGh0dHBzOi8vb2JzZXJ2YXRvcmltYXJpbmFhbHRhLm9yZy8pIA0KDQpbUGVyacOzZGljbyBMZXZhbnRlXShodHRwczovL3d3dy5sZXZhbnRlLWVtdi5jb20vbWFyaW5hLzIwMjAvMDMvMTYvY29uc3RydWNjaW9uLW1hcmluYS1hbHRhLTExNTk0MTMxLmh0bWwpDQoNCltMYSBNYXJpbmEgUGxhemFdKGh0dHBzOi8vbGFtYXJpbmFwbGF6YS5jb20vMjAyMC8wNS8wMi9lcy1wb3NpYmxlLXVuLWNhbWJpby1kZS1tb2RlbG8tZWNvbm9taWNvLWVuLWxhLW1hcmluYS1hbHRhLykNCg0KDQo8YnI+PGJyPg0KDQo8aHIgY2xhc3M9ImxpbmVhLXJlZCI+DQo8aHIgY2xhc3M9ImxpbmVhLXJlZCI+DQoNCg0KYGBge3IsIGVjaG8gPSBGQUxTRX0NCnNlc3Npb25pbmZvOjpzZXNzaW9uX2luZm8oKSAlPiUgZGV0YWlsczo6ZGV0YWlscyhzdW1tYXJ5ID0gJ0luZm9ybWFjacOzbiBkZSBtaSBSLXNlc2nDs246JykgDQpgYGANCg0KDQo8YnI+PGJyPg0KDQo8ZGl2IGNsYXNzPSJ0b2NpZnktZXh0ZW5kLXBhZ2UiIGRhdGEtdW5pcXVlPSJ0b2NpZnktZXh0ZW5kLXBhZ2UiIHN0eWxlPSJoZWlnaHQ6IDA7Ij48L2Rpdj4NCjxicj48YnI+DQoNCjxkaXYgY2xhc3M9InRvY2lmeS1leHRlbmQtcGFnZSIgZGF0YS11bmlxdWU9InRvY2lmeS1leHRlbmQtcGFnZSIgc3R5bGU9ImhlaWdodDogMDsiPjwvZGl2Pg0K