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

Para la asignatura de ā€œProgramaciĆ³n y manejo de datos en la era del Big Dataā€ hemos decidido realizar un ensayo (en formato rmd) de relevancia general que afecta a todos los ciudadanos (especialmente a los agentes con menor poder adquisitivo), como es la inflaciĆ³n.

Resumen: El encarecimiento de los precios de la energĆ­a, junto la falta de microprocesadores y los estĆ­mulos monetarios mĆ”s ambiciosos en la historia reciente, estĆ”n ocasionando la apariciĆ³n de datos de inflaciĆ³n que no se alcanzaban desde la crisis del petrĆ³leo de los aƱos 70. En particular, la economĆ­a europea, y en especial la espaƱola, se encuentran en el peor momento posible para afrontar este desajuste en una de las principales variables macroeconĆ³micas, los precios. Esta circunstancia, estĆ” afectando especialmente a las rentas mĆ”s bajas y generando un problema de desabastecimiento de ciertos productos a escala mundial, en uno de los contextos mĆ”s inciertos del reciente siglo como consecuencia de la evoluciĆ³n de la crisis sanitaria provocada por el COVID-19.

The Abstract: Rising energy prices, together with the lack of microprocessors and the most ambitious monetary stimuli in recent history, are causing the emergence of inflation data that had not been reached since the oil crisis of the 1970s. In particular, The European economy, and especially the Spanish one, is in the worst possible moment to face this imbalance in one of the main macroeconomic variables, prices. This circumstance is especially affecting the lowest incomes and generating a problem of shortages of certain products on a global scale, in one of the most uncertain contexts of the recent century as a consequence of the evolution of the health crisis caused by COVID-19.

Palabras Clave: EnergĆ­a, InflaciĆ³n, EspaƱa, Europa, BCE, microprocesadores, precio, precios, gas, precios de la energĆ­a, expectativa.


2. Motivaciones

La inflaciĆ³n es una de las principales variables macroeconĆ³micas que mayor distorsiĆ³n de expectativas pueden generar en los agentes econĆ³micos. ĀæPor quĆ©? se puede preguntar el lector. Esto es debido a que la fluctuaciĆ³n en precios es un concepto bĆ”sico que todo individuo de una sociedad, independientemente de si dispone de ciertos conocimientos econĆ³micos, rĆ”pidamente sabe analizar e interpretar. Este efecto, bajo el supuesto de racionalidad de los agentes que interactĆŗan en la economĆ­a, ocasiona un cambio en la toma de decisiones. La conclusiĆ³n es clara, a mayores precios, es decir, a mayor cantidad de unidades monetarias requeridas para la compra de un determinado bien, menor serĆ” la satisfacciĆ³n que nos da dicho intercambio. Si este efecto lo trasladamos al conjunto de bienes de una economĆ­a, las conclusiones sĆ³n las mismas, los agentes econĆ³micos (por norma general) dispondremos de menor poder adquisitivo, por lo tanto, seremos mĆ”s pobres.

Consideramos que el tema de estudio de la inflaciĆ³n es un tema actual, que afecta a la mayorĆ­a de las economĆ­as desarrolladas y del que no hay un cierto consenso dentro de la comunidad econĆ³mica sobre sus principales causas y, especialmente, su evoluciĆ³n en el corto/medio plazo.

En el momento que estamos desarrollando este breve artĆ­culo, la inflaciĆ³n a nivel mundial se encuentra ā€œdisparadaā€ si la comparamos con la media histĆ³rica de los Ćŗltimos 20 aƱos en la gran mayorĆ­a de economĆ­as. Por poner en contexto al lector, el pasado octubre la economĆ­a estadounidense registrĆ³ una de sus mayores tasas de inflaciĆ³n en los Ćŗltimos 20 aƱos, un 6,2%. Alemania, otra economĆ­a caracterizada por tener ciertos recelos a presentar datos de inflaciĆ³n elevados, tambiĆ©n registra tasas superiores al 4%. La tĆ³nica inflacionista no es un efecto Ćŗnico de la economĆ­a germana, sinĆ³ que se estĆ” observando en la mayorĆ­a de economĆ­as que conforman la UniĆ³n Europea.


  • Record de inflaciĆ³n:
  • Que hacer ante la subida del IPCA, ĀæSubida de tipos de interes?
  • Importancia del augmento de las energias


Las motivaciones que nos ha llevado a la elecciĆ³n de esta tema sĆ³n varias;

  • Estudiar este fenĆ³meno tan excepcional en las economĆ­as europeas, y especialmente en nuestra economĆ­a domĆ©stica. Desde que empezamos a interesarnos por el mundo de las ciencias econĆ³micas no hemos vivido un perĆ­odo de alta inflaciĆ³n, por tanto, es una circunstancia que nos llama muchĆ­simo la atenciĆ³n.

  • Desarrollar tanto los conocimientos econĆ³micos (teĆ³ricos y prĆ”cticos) que hemos adquirido en la carrera, como en el curso de R.Studio. Al respecto de este punto, queremos remarcar que nos ha llamado particularmente la atenciĆ³n la gran variedad de grĆ”ficos profesionalizados, como los anteriormente expuestos, que referentes economistas estĆ”n compartiendo para analizar el tema de interĆ©s. Esta es una motivaciĆ³n extra para nuestro artĆ­culo, tratar de crear grĆ”ficos profesionalizados.

Nuestro principal objetivo es tratar de dar respuesta de cuĆ”les sĆ³n las principales causas de la inflaciĆ³n y cĆ³mo puede afectar al crecimiento de nuestra economĆ­a en el corto/medio plazo.


3. Datos utilizados

Comentarios

Para la realizaciĆ³n del trabajo ha sido necesaria la obtenciĆ³n de informaciĆ³n procedente de diversas fuentes como por ejemplo el INE y Eurostat.

Para poder utilizar estos datos ha sido necesario modificarlos y adaptarlos antes de emplearlos y hacer grĆ”ficas. Esta adaptaciĆ³n la podemos encontrar dentro del apartado tidy, donde se recogen todas las modificaciones realizadas desde la descarga de un archivo como puede ser xlsx o cvs hasta tener un data frame cargado en el Global Environment.



Tidy


#Hemos adquirido un dataframe de la inflaciĆ³n por agrupaciones, por ello cargamos el dataframe para poder observarlo en Data y lo convertimos en formato long. 
inflacion_agrupaciones <- read_excel("datos/inflacion_agrupaciones.xlsx")

inflacion_agrupaciones <- inflacion_agrupaciones %>% pivot_longer(cols = 3:63, names_to = "date") 

#Una vez lo hemos hecho, las variables data y value estaban en formato character, por ello hemos tenido que exportar este documento y cambiar estas variables a fomato numƩrico manualmente, obteniendo asƭ el data frame inflacion_agrup. Una vez hecho esto podemos cargar directamente. 

inflacion_agrup <- inflacion_agrupaciones

#rio::export(inflacion_agrup, "./datos/inflacion_agrup.csv")

inflacion_agrup <- read_csv("datos/inflacion_agrup.csv", 
    col_types = cols(date = col_date(format = "%Y"), 
        value = col_number()))
#DATOS PARA LOS PAISES.

#Hemos realizado los pasos anteriores pero esta vez aplicandolos al dataframe que contienen los paises, obteniendo un nuevo dataframe inflacion_country que podemos cargar directamente. 
inflacion_paises <- read_excel("datos/inflacion_paises.xlsx")
inflacion_paises <- inflacion_paises %>% pivot_longer(cols = 4:64, names_to = "date") 
inflacion_paises$code<-tolower(countrycode(inflacion_paises$country_name,origin = 'country.name', destination = 'iso2c'))

#Una vez lo hemos hecho, las variables data y value estaban en formato character, por ello hemos tenido que exportar este documento y cambiar estas variables a fomato numƩrico manualmente, obteniendo asƭ el data frame inflacion_country. Una vez hecho esto podemos cargar directamente. 

inflacion_country <- inflacion_paises

#rio::export(inflacion_country, "./datos/inflacion_country.csv")

inflacion_country <- read_csv("datos/inflacion_country.csv", 
    col_types = cols(date = col_date(format = "%Y"), 
        value = col_number()))
#DATOS PARA LA CREACIƓN DE MAPAS

#En este paso hemos jutado el dataframe world con el anterior para poder importarle las geometrias y poder hacer mapas.

world <- rnaturalearth::ne_countries(scale = "medium", returnclass = "sf")
world <- world %>% filter(subregion != "Antarctica") %>% filter(admin != "Greenland")
world <- world %>% dplyr::select(name, iso_a3, geometry)

inflacion_geom <- full_join(inflacion_country, world, by = c("country-code" = "iso_a3"))

# Para poder realizar un treemap hemos adquirdo datos sobre la evoluciĆ³n de varios componentes y los hemos tratado de la siguiente forma 

contribucion <- read_excel("datos/contribucion.xls")
contribucion <- contribucion %>% pivot_longer(cols = 2:23, names_to = "date") 

#rio::export(contribucion, "./datos/contribucion.csv") 

contribucion <- read_csv("datos/contribucion.csv", 
    col_types = cols(date = col_date(format = "%Y/%m")))

# Alguna mierda que hagamos con estos datos 

prc_hicp_manr <- read_excel("datos/prc_hicp_manr.xls")

prc_hicp_manr <- prc_hicp_manr %>% pivot_longer(cols = 2:35, names_to = "date")
prc_hicp_manr <- prc_hicp_manr %>% rename(country = `GEO/TIME`) 

# rio::export(prc_hicp_manr, "./datos/prc_hicp_manr.csv")

prc_hicp_manr <- read_csv("datos/prc_hicp_manr.csv", 
                          col_types = cols(date = col_date(format = "%Y/%m")))

inflacion_europea <- read_excel("datos/inflacion_europea.xlsx")

inflacion_europea <- inflacion_europea %>% pivot_longer(cols = 2:35, names_to = "date")
inflacion_europea <- inflacion_europea %>% rename(country = `GEO/TIME`) 

#rio::export(inflacion_europea, "./datos/inflacion_europea.csv")

inflacion_europea <- read_csv("datos/inflacion_europea.csv", 
                              col_types = cols(date = col_date(format = "%Y/%m")))
library(tidyverse)
world <- rnaturalearth::ne_countries(scale = "medium", returnclass = "sf")
world <- world %>% filter(subregion != "Antarctica") %>% filter(admin != "Greenland")
world <- world %>% dplyr::select(name, iso_a3, geometry)

inflacion_geom_europ <- left_join(inflacion_europea, world, by = c("country" = "name")) %>%
  filter(date >= "2020-01-01")

inflacion_eurozona <- read_excel("datos/inflacion_eurozona.xlsx")

inflacion_eurozona <- inflacion_eurozona %>% pivot_longer(cols = 3:14, names_to = "date")


#rio::export(inflacion_eurozona,"./datos/inflacion_eurozona.csv")

inflacion_eurozona <- read_csv("datos/inflacion_eurozona.csv", 
    col_types = cols(date = col_date(format = "%Y/%m")))

inflacion_esp <- read_excel("datos/inflacion_esp.xlsx")

inflacion_esp <- inflacion_esp  %>% pivot_longer(cols = 2:23, names_to = "date")


#rio::export(inflacion_esp,"./datos/inflacion_esp.csv")

inflacion_esp <- read_csv("datos/inflacion_esp.csv", 
    col_types = cols(date = col_date(format = "%Y/%m")))

ponderacion_componentesIPC <- read_excel("datos/ponderacion_componentesIPC.xls")

ponderacion_componentesIPC <- ponderacion_componentesIPC %>% pivot_longer(cols = 2:6, names_to = "date")


#rio::export(ponderacion_componentesIPC,"./datos/ponderacion_componentesIPC.csv")



ponderacion_componentesIPC <- read_csv("datos/ponderacion_componentesIPC.csv", 
                                       col_types = cols(date = col_number(), 
                                                        value = col_number()))
 
inflacion_coumindades <- read_excel("datos/inflacion_coumindades.xls")

inflacion_coumindades <- inflacion_coumindades %>% pivot_longer(cols = 2:23, names_to = "date")


#rio::export(inflacion_coumindades,"./datos/inflacion_coumindades.csv")

inflacion_comunidades <- read_csv("datos/inflacion_coumindades.csv", 
    col_types = cols(date = col_date(format = "%Y/%m")))

inflacion_provincias <- read_excel("datos/inflacion_provincias.xls")

inflacion_provincias <- inflacion_provincias %>% pivot_longer(cols = 2:23, names_to = "date")

#rio::export(inflacion_provincias,"./datos/inflacion_provincias.csv")

inflacion_provincias <- read_csv("datos/inflacion_provincias.csv", 
    col_types = cols(date = col_date(format = "%Y/%m")))
inflacion_var_esp <- read_excel("datos/var_interanual_esp.xlsx")

inflacion_var_esp <- inflacion_var_esp  %>% pivot_longer(cols = 2:360, names_to = "date")

#rio::export(inflacion_var_esp,"./datos/inflacion_var_esp.csv")

inflacion_var_esp <- read_csv("datos/inflacion_var_esp.csv", 
    col_types = cols(date = col_date(format = "%Y/%m")))

#Datos en formato polĆ­gono para poder eralizar un mapa de coropletas interactivo
shapefile_provincias <- shapefile("shp/Provincias_ETRS89_30N.shp")

#Datos para la realizaciĆ³n del grĆ”fico sobre la predicciĆ³n
prediccion_inflacion <- read_csv("datos/prediccion_inflacion.csv", 
                                 col_types = cols(Value = col_number()))
library(readr)

#my_url <- "https://ec.europa.eu/eurostat/api/dissemination/sdmx/2.1/data/SDG_17_40/A.PC_GDP.S13.GD.EU27_2020+BE+BG+CZ+DK+DE+EE+IE+EL+ES+FR+HR+IT+CY+LV+LT+LU+HU+MT+NL+AT+PL+PT+RO+SI+SK+FI+SE+IS+NO+CH+UK/?format=SDMX-CSV&startPeriod=2020&endPeriod=2020"

#curl::curl_download(my_url, "./datos/deuda_eu.csv")

df_csv <- rio::import("./datos/deuda_eu.csv")

deuda_eu <- read_csv("./datos/deuda_eu.csv", 
                    col_types = cols(OBS_VALUE = col_number())) %>%
  dplyr::select(geo, OBS_VALUE) %>%
  mutate(value = OBS_VALUE/100)

# Datos del Banco de espaƱa para tratar de analizar la influencia de la inflaciĆ³n en la poblaciĆ³n 
#Este primero estĆ” relacionado con el porcentaje de activos reales que posee cada percentil de renta

datos_esp_prop <- read_excel("datos/datos_esp_prop.xlsx", 
                             col_types = c("text", "numeric", "numeric", 
                                           "numeric", "numeric"))

datos_esp_prop <- datos_esp_prop %>% pivot_longer(cols = 2:5, names_to = "Propiedad")

# Este segundo esta relacionado con la propiedad de activos financieros de cada percentil de renta
datos_esp_inv <- read_excel("datos/datos_esp_inv.xlsx", 
                            col_types = c("text", "numeric", "numeric", 
                                          "numeric", "numeric"))

datos_esp_inv <- datos_esp_inv %>% pivot_longer(cols = 2:5, names_to = "Act_real")

# Datos de la OCDE de la prevision del crecimiento del PIB eurozon

crecimiento <- read_csv("datos/crecimiento.csv", 
                        col_types = cols(Value = col_number()))


4. Estudio mundial

4.1 EvoluciĆ³n del mundo

En primer lugar, un breve repaso histĆ³rico acerca de la inflaciĆ³n.

Para la serie histĆ³rica analizada se puede observar como la inflaciĆ³n mundial ha experimentado una reducciĆ³n drĆ”stica en los Ćŗltimos 30 aƱos.


#GRAFICO 1

p1 <- inflacion_agrup %>%
  filter(country_name == "Mundo") %>%
  filter(date >= 1981) %>% filter(series == "subyacente") %>% 
  dplyr::select(-(series))
p1 <- p1 %>%  dplyr::select(-(country_name))

p11 <- inflacion_agrup %>%
  filter(country_name == "Mundo") %>%
  filter(date >= 1981) %>% filter(series == "general") %>% 
  dplyr::select(-(series))
p11 <- p11 %>%  dplyr::select(-(country_name))

subyacente <- xts(p1$value, order.by = p1$date, frequency = 365) 


general <- xts(p11$value, order.by = p11$date, frequency = 365)

p <- cbind(subyacente,general) 
  
dygraph(p, ylab= "% inflaciĆ³n",
        main = "EvoluciĆ³n InflaciĆ³n") %>% 
  dyOptions(colors = c("blue", "brownw")) %>% 
  dyRangeSelector()

ĀæA quĆ© se debe esta reducciĆ³n generalizada para todas las economĆ­as ?

Especialmente a los beneficios de la globalizaciĆ³n sobre el crecimiento econĆ³mico : La globalizaciĆ³n ha generado un efecto escala, que se deriva del mayor tamaƱo de mercado. Este mayor tamaƱo de mercado incentiva a las empresas a crecer y a adquirir mayores conocimientos, lo cual aumenta la productividad agregada y, con ello, se produce un aumento de la oferta agregada a nivel mundial. A todo esto le tenemos que sumar la importancia del avance tecnolĆ³gico en las Ćŗltimas dĆ©cadas.


4.2 EvoluciĆ³n de las 9 economĆ­as principales

4.2.1 GrƔfico de lineas

Si desagregamos, se puede confirmar lo anteriormente mencionado, aunque las economĆ­as tienen un ajuste diferente todas llegan al mismo destino, a una inflaciĆ³n caracterizada por tasas de crecimiento estables.



inflacion_g9 <- inflacion_country %>% mutate(paises = country_name) %>% filter(country_name %in% c("United States","China", "Japan", "Germany", "United Kingdom", "India","France","Italy", "Korea, Rep.")) %>% filter(`Series Name` == "general") 

inflacion_g9 <- ggplot(inflacion_g9, aes(x=date, y=value)) +
  geom_line(data=inflacion_g9 %>% dplyr::select(-country_name), aes(group=paises), color="grey", size=0.5, alpha=1) +
  geom_line( aes(color=country_name), color="#69b3a2", size=1.2 )+
  scale_color_viridis(discrete = TRUE) +
  theme_ipsum() +
  theme(
    legend.position="none",
    plot.title = element_text(size=14),
    panel.grid = element_blank()) +
  
  facet_wrap(~country_name) + theme(plot.subtitle = element_text(family = "serif"),
                                    plot.caption = element_text(family = "serif"),
                                    axis.title = element_text(family = "serif"),
                                    plot.title = element_text(family = "serif")) +
  
  labs(
      caption = "Fuente: ElaboraciĆ³n propia con datos del Banco Mundial") + 
      labs(x = NULL, y = "Valores en %")

4.2.2 InflaciĆ³n acumulada

Desde que abandonamos el patrĆ³n oro, la mayorĆ­a de las economĆ­as han adoptado por un incremento sostenido y controlado de precios para fomentar su crecimiento. Aunque no vamos a entrar a valorar, ya que darĆ­a para otro artĆ­culo la efectividad de esta estrategia, desde la crisis del petrĆ³leo de los aƱos 70 la economĆ­a mundial se ha caracterizado por una estabilidad de precios, al menos, con lo que respecta a las economĆ­as del G-20. Ejemplo de este razonamiento lo tenemos en la confianza que el mercado de divisas tiene en las monedas de dicha agrupaciĆ³n (G-20), divisas como el dĆ³lar o el euro se han instaurado como activos ā€œsegurosā€. Toda esta ā€œrelativa estabilidadā€ ha seguido mejorando la confianza internacional a la hora de desarrollar y profundizar en el comercio internacional, potenciando los beneficios anteriormente descritos sobre el conjunto de la economĆ­a.


inflacion_barras <- read_excel("datos/inflacion_barras.xlsx", 
                               col_types = c("text", "text", "text", 
                                             "numeric", "numeric", "numeric", 
                                             "text", "numeric")) %>% 
 dplyr::select(-(nada))


inflacion_barras <- inflacion_barras %>% 
  group_by(date) %>% 
  arrange(date, desc(acumulada)) %>% 
  mutate(ranking = row_number()) %>%
  filter(ranking <=9) %>% 
  ungroup() 

tabla_1 <- ggplot(inflacion_barras, aes(ranking, acumulada, country = code, size = 20)) +
  geom_col(aes(ranking, acumulada,  fill = country_name)) +
  scale_fill_brewer(palette = "Spectral") +
  geom_flag(aes(ranking, acumulada, country = code), size = 10) +
  geom_text(aes(ranking, acumulada, label = as.factor(acumulada), size = 40), hjust= -0.5) +
  geom_text(aes(x=9, y=600, label = as.factor(date)), vjust = 0.2, alpha = 0.5,  col = "gray", size = 15) +
  
  scale_x_reverse() +
  coord_flip(clip = "off", expand = FALSE) +
  theme_light() +
  theme(
    panel.grid = element_blank(), 
    legend.position = "none",
    axis.ticks.y = element_blank(),
    axis.title.y = element_blank(),
    axis.text.y = element_blank()) +
  lims(y = c(NA,700)) + theme(axis.line = element_line(colour = NA),
                              axis.ticks = element_line(colour = NA),
                              panel.grid.major = element_line(colour = NA),
                              panel.grid.minor = element_line(colour = NA),
                              axis.text = element_text(colour = NA),
                              plot.background = element_rect(colour = NA)) +labs(x = NULL, y = NULL)+
  labs(title = "AcumulaciĆ³n historica de la inflaciĆ³n",
       subtitle = "InflaciĆ³n general desde 1971 hasta 2020.",
       caption = "Fuente: ElaboraciĆ³n propia con datos del Banco Mundial") +
  
  transition_states(as.factor(date),transition_length = 1, state_length = 0, wrap = FALSE)

tabla_1 <- tabla_1 +  theme(legend.position = "none") 

#gganimate::animate(tabla_1, nframes = 650, fps = 30)


4.3 Mapa de coropletas

Mapa Mundi

Si ampliamos el foco (vĆ©ase mapa mundi y tablas) no todas las economĆ­as han contribuido en la misma proporciĆ³n al crecimiento sostenido en precios, aunque a nivel agregado la tendencia es a una reducciĆ³n de la tasa de crecimiento de los precios hasta estabilizarse en valores ā€œrazonablesā€ desde una perspectiva actual (vĆ©ase punto 4.4).

Como se puede apreciar, las economĆ­as menos desarrolladas, disponen de mayores tasas de crecimiento en precios, esto se puede a diversidad de factores que no vamos a entrar a analizar, simplemente para hacer saber al lector que no en todos los paĆ­ses del mundo se ha instaurado la estabilidad en precios. Es por eso que no los tendremos en cuenta a la hora de analizar el problema actual, ya que sĆ³n economĆ­as que per se, disponen de tasas de inflaciĆ³n mucho mĆ”s elevadas que las economĆ­as donde la estabilidad en precios si ha sido en la historia mĆ”s reciente un autĆ©ntico Ć©xito. Dicho lo cual, para analizar este problema nos vamos a centrar en el contexto europeo y en especial, en el contexto espaƱol. Por variedad de razones;

  1. Son economĆ­as que comparten polĆ­tica monetaria y moneda comĆŗn, hecho que facilita el anĆ”lisis.

  2. Son economĆ­as similares, donde su estudio nos puede facilitar la comparaciĆ³n.

  3. Son el economƭas que cumplen los requisitos establecido para nuestro anƔlisis (ruptura de la tendencia en estabilidad relativa en precios).


library(lubridate)

inflacion_geom_2 <- inflacion_geom %>%  filter(`Series Name` == "general") %>% 
  mutate(anyo = lubridate::year(date)) %>% 
  group_by(date) %>% 
  filter(anyo >= 2000) %>%
  mutate(deciles = ntile(value, n = 10)) 

mapa <- ggplot() +
  geom_sf(data = inflacion_geom_2, aes(geometry = geometry, fill = deciles)) +
  theme_void()  +
  theme(plot.subtitle = element_text(family = "serif", face = "italic"),
        plot.title = element_text(family = "serif", face =  "italic")) +
  labs(title = "Mapa:InflaciĆ³n mundial", fill = "InflaciĆ³n")  +
  scale_fill_continuous(low="#fffcbf",high="#3e9851") + 
  transition_manual(anyo)+
  labs(title = "AƱo: {current_frame}",
       caption = "Fuente: ElaboraciĆ³n propia con datos del Banco Mundial")

# gganimate::animate(mapa, nframes= 100, fps= 4, end_pause = 5)

Note el lector, que para el anƔlisis de dicho problema, tambiƩn se podrƭa haber estudiado la economƭa norteamericana y haber extraƭdo conclusiones similares.



Tabla

inflacion_country_sub <- inflacion_country %>%
  filter(`Series Name` == "subyacente")

inflacion_country_gen <- inflacion_country %>%
  filter(`Series Name` == "general")

tabla_mundo <- left_join(inflacion_country_sub, inflacion_country_gen, by = c("country-code" = "country-code", "date" = "date"))

tabla_mundo <- tabla_mundo %>% 
  dplyr::select(country_name.x, date, value.x, value.y) %>% 
  dplyr::rename(country = country_name.x, subyacente_1 = value.x, general_1 = value.y) %>% filter(country != "Afghanistan") %>% 
  filter(country != "Albania") 

tabla_mundo <- tabla_mundo %>% 
  mutate(subyacente = round(subyacente_1, digits = 2)) %>% 
  mutate(general = round(general_1, digits = 2)) %>% 
  dplyr::select(-c(subyacente_1, general_1))
  
  

datatable(tabla_mundo, class ="stripe hover compact row-border" , filter = 'top')


4.4 ComparaciĆ³n por zonas geogrĆ”ficas

AquĆ­ el lector puede apreciar lo anteriormente expuesto, y consultar en caso de que resulte de su interes la evoluciĆ³n histĆ³rica para cada zona geogrĆ”fica.

4.4.1 AmƩrica latina VS Mundo

america_latina <- inflacion_agrup %>% filter(series == "general") %>% 
  filter(country_name %in% c("AmƩrica Latina y el Caribe", "Mundo")) %>% filter( date >= 1971)

america_latina <- ggplot() +
  geom_line(data = america_latina, aes(date, value, color = country_name), size=1) +
  scale_color_viridis(discrete = TRUE) +
  theme(
    legend.position="none",
    plot.title = element_text(size=14)
  ) +
  ggtitle("Inflacion mundial") +
  theme_ipsum() + theme(plot.subtitle = element_text(family = "serif"),
                        plot.caption = element_text(family = "serif"),
                        axis.title = element_text(family = "serif"),
                        plot.title = element_text(family = "serif")) +labs(title = "Grafica 3: America latina vs Mundo", subtitle = "(InflaciĆ³n general)",
                                                                           x = NULL, y = "Valores en %") + theme(legend.text = element_text(size = 12),
                                                                                                                                                                                                legend.position = "bottom", legend.direction = "horizontal") +labs(colour = NULL, caption = "Fuente: ElaboraciĆ³n propia con datos del Banco Mundial")

america_latina



4.4.2 AmƩrica del norte VS Mundo


america_norte <- inflacion_agrup %>% filter(series == "general") %>% 
  filter(country_name %in% c ("AmƩrica del Norte", "Mundo")) %>% filter( date >= 1971)

america_norte <- ggplot() +
  geom_line(data = america_norte, aes(date, value, color = country_name), size=1) +
  scale_color_viridis(discrete = TRUE) +
  theme(
    legend.position="none",
    plot.title = element_text(size=14)
  ) +
  ggtitle("Inflacion mundial") +
  theme_ipsum() + theme(plot.subtitle = element_text(family = "serif"),
                        plot.caption = element_text(family = "serif"),
                        axis.title = element_text(family = "serif"),
                        plot.title = element_text(family = "serif")) +labs(title = "Grafica 3: America del Norte vs Mundo", subtitle = "(InflaciĆ³n general)",
                                                                           x = NULL, y = "Valores en %") + theme(legend.text = element_text(size = 12),
                                                                                                                                                                                                legend.position = "bottom", legend.direction = "horizontal") +labs(colour = NULL, caption = "Fuente: ElaboraciĆ³n propia con datos del Banco Mundial")

america_norte



4.4.3 UniĆ³n Europea VS Mundo


union_europea <- inflacion_agrup %>% filter(series == "general") %>% 
  filter(country_name %in% c("UniĆ³n Europea", "Mundo")) %>% filter(date >= 1971) 

union_europea <- ggplot() +
  geom_line(data = union_europea, aes(date, value, color = country_name), size=1) +
  scale_color_viridis(discrete = TRUE) +
  theme(
    legend.position="none",
    plot.title = element_text(size=14)
  ) +
  ggtitle("Inflacion mundial") +
  theme_ipsum() + theme(plot.subtitle = element_text(family = "serif"),
                        plot.caption = element_text(family = "serif"),
                        axis.title = element_text(family = "serif"),
                        plot.title = element_text(family = "serif")) +labs(title = "Grafica 3: Union Europea vs Mundo", subtitle = "(InflaciĆ³n general)",
                                                                           x = NULL, y = "Valores en %") + theme(legend.text = element_text(size = 12),
                                                                                                                                                                                                legend.position = "bottom", legend.direction = "horizontal") +labs(colour = NULL, caption = "Fuente: ElaboraciĆ³n propia con datos del Banco Mundial")

union_europea



4.4.4 Ɓfrica VS Mundo


africa_sahara <- inflacion_agrup %>% filter(series == "general") %>% 
  filter(country_name %in% c("Ɓfrica al sur del Sahara", "Mundo")) %>% filter( date >= 1971)

africa_sahara <- ggplot(africa_sahara, aes(date, value, color=country_name)) +
  geom_line(size=1) +
  scale_color_viridis(discrete = TRUE) +
  theme(
    legend.position="none",
    plot.title = element_text(size=14)
  ) +
  ggtitle("Inflacion mundial") +
  theme_ipsum() + theme(plot.subtitle = element_text(family = "serif"),
                        plot.caption = element_text(family = "serif"),
                        axis.title = element_text(family = "serif"),
                        plot.title = element_text(family = "serif")) +labs(title = "Grafica 3: Africa Subsahariana vs Mundo", subtitle = "(InflaciĆ³n general)",
                                                                           x = NULL, y = "Valores en %") + theme(legend.text = element_text(size = 12),
                                                                                                                 legend.position = "bottom", legend.direction = "horizontal") +labs(colour = NULL, caption = "Fuente: ElaboraciĆ³n propia con datos del Banco Mundial")

africa_sahara



4.4.5 Ɓsia VS Mundo


asia_pacifico <- inflacion_agrup %>% filter(series == "general") %>% 
  filter(country_name %in% c("Asia oriental y el PacĆ­fico", "Mundo")) %>% filter( date >= 1971)

asia_pacifico <- ggplot(asia_pacifico, aes(date, value, color=country_name)) +
  geom_line(size=1) +
  scale_color_viridis(discrete = TRUE) +
  theme(
    legend.position="none",
    plot.title = element_text(size=14)
  ) +
  ggtitle("Inflacion mundial") +
  theme_ipsum() + theme(plot.subtitle = element_text(family = "serif"),
                        plot.caption = element_text(family = "serif"),
                        axis.title = element_text(family = "serif"),
                        plot.title = element_text(family = "serif")) +labs(title = "Grafica 3:Asia y el Pacifico vs Mundo", subtitle = "(InflaciĆ³n general)",
                                                                           x = NULL, y = "Valores en %") + theme(legend.text = element_text(size = 12),
                                                                                                                 legend.position = "bottom", legend.direction = "horizontal") +labs(colour = NULL, caption = "Fuente: ElaboraciĆ³n propia con datos del Banco Mundial")

asia_pacifico



4.5 Outliers 2020

Las excepciones anteriormente mencionadas, valores que pueden ser considerados como ā€œoutliersā€, en nuestro estudio. No tiene ningun sentido estudiar el problema inflacionista actual en economias que histĆ³ricamente presentan distorsiones estructurales en la variable estudio.


library(patchwork)

inflacion_country_2 <- inflacion_country %>% mutate(anyo =lubridate::year(date))

inflacion_country_top <- inflacion_country_2 %>%
  filter(`Series Name` == "general") %>%
  filter(anyo == 2020) %>%
  mutate(valor = round(value, digits = 2)) %>%
  mutate(simbolo = "+") %>%
  mutate(simbolo2 = "%") %>%
  slice_max(value, n=5)

deflacion_country_min <- inflacion_country_2 %>% filter(`Series Name` == "general") %>%
  filter( anyo == 2020) %>% 
  mutate(valor = round(value, digits = 2)) %>%
  slice_min(value, n = 5)

  
  
p2 <- ggplot( inflacion_country_top, aes( reorder(country_name, value), value, fill = country_name, country=code, width = 0.5 ))+
  geom_bar( stat = "identity") +
  scale_fill_brewer(palette = "Spectral") +
  geom_flag( y= -18, size=15 ) +
  coord_flip() +
  geom_text( aes(label= simbolo),
             hjust = -0.4, size = 5,
             position = position_dodge(width = 1),
             inherit.aes = TRUE) +
  geom_text( aes(label = valor),
             hjust = -0.4, size = 5,
             inherit. = TRUE) +
  theme(aspect.ratio = 0.5) +
  lims(y= c(NA,700))  + theme(axis.text = element_text(size = 11,
    face = "bold"), axis.text.x = element_text(size = 0,
    colour = "white")) +labs(x = "Valores expresado en %", y = NULL) + theme(panel.background = element_rect(fill = NA)) + theme(plot.subtitle = element_text(size = 14),
    axis.text.x = element_text(vjust = 0),
    plot.title = element_text(size = 15,
        face = "bold")) +labs(title = "Diferencias entre los extremos",
    subtitle = "Paises con mayor inflaciĆ³n y deflaciĆ³n general en 2020") + 
  theme(axis.line = element_line(colour = NA),
    axis.ticks = element_line(colour = NA))  + theme(legend.position = "none")


p3 <- ggplot(deflacion_country_min, aes(reorder(country_name, value), value, fill = country_name, country=code))+
  geom_bar(stat = "identity") +
  geom_flag(y = 2, size = 15) +
  scale_fill_brewer(palette = "Greens") +
  geom_text( aes(label = valor),
             vjust = 1.2, size = 5,
             inherit. = TRUE) +
  geom_text( aes(label = country_name),
             vjust = -2, size = 5,
             inherit. = TRUE) +
  lims(y= c(-31,4)) + 
  theme(plot.subtitle = element_text(size = 14,
    face = "bold"), axis.line = element_line(colour = NA),
    axis.ticks = element_line(colour = NA),
    axis.text = element_text(colour = NA),
    panel.background = element_rect(fill = NA),
    plot.background = element_rect(colour = NA)) +labs( x= NULL, y = NULL,  caption = "Fuente: ElaboraciĆ³n propia con datos del Banco Mundial.") + theme(legend.position = "none")
  



p2 + inset_element(p3, left = 0.3, right = 1, bottom = -0.2, top = 0.8)

En resumen y la conslusiĆ³n que queremos remarcar antes de entrar en materia, es que en los Ćŗltimos 30 aƱos se ha acelerado el proceso de especializaciĆ³n productiva (si no tenemos en cuenta las excepciones), reduciendo los costes de producciĆ³n y fomentando el avance tecnolĆ³gico. Todo esto se traduce en una reducciĆ³n de los precios de los bienes y servicios que se comercian a nivel internacional, mejorando la calidad de vida de los agentes econĆ³micos.


5. InflaciĆ³n en la actualidad

El fenĆ³meno anteriormente descrito (reducciĆ³n mundial de los datos de inflaciĆ³n) tambiĆ©n se ha hecho visible en el viejo continente. En los Ćŗltimos aƱos, casi toda eurozona, se habĆ­a acostumbrado a que los precios altos dejarĆ”n de ser un dolor de cabeza. MĆ”s aĆŗn, cuando, a diferencia de otras economĆ­as como bien puede ser la estadounidense, el BCE se ha comprometido, casi desde su creaciĆ³n, a fijar su polĆ­tica monetaria para asegurar que la inflaciĆ³n se estabilice en su objetivo del 2 % a medio plazo.


5.1. Cambio de tendencia

Desde finales de verano de 2021, esta tendencia de estabilidad relativa de precios se ha quebrado.



mapa_2 <- ggplot() +
  geom_sf(data = inflacion_geom_europ, aes(geometry = geometry, fill = value )) +
  theme_void()  +
  theme(plot.subtitle = element_text(family = "serif", face = "italic"),
        plot.title = element_text(family = "serif", face =  "italic")) +
  labs(title = "Mapa:InflaciĆ³n mundial", fill = "InflaciĆ³n")  +
  scale_fill_continuous(low="#fffcbf",high="#d7372a") +
  lims(y =c(35,70)) +
  lims(x = c(-20, 40)) + transition_manual(date) +
  labs(title = "AƱo: {current_frame}",
       caption = "Datos de Eurostat")

gganimate::animate(mapa_2, nframes = 200, fps = 20, end_pause = 6)


5.2. Componentes/causas de la inflaciĆ³n

El encarecimiento de la energĆ­a, los cuellos de botella de las cadenas de producciĆ³n y la estratĆ©gia en polĆ­tica monetaria adoptada para luchar contra la covid (incremento del flujo monetario en la economĆ­a) han despertado a la inflaciĆ³n en la mayorĆ­a de las economĆ­as.

Si nos centramos en el contexto europeo, la principal causa de inflaciĆ³n es clara (grĆ”fico aportaciĆ³n componentes a la inflaciĆ³n), los precios de la energĆ­a han experimentado un repunte exponencial en los dos Ćŗltimos trimestres.

Estos altos precios energƩticos deben a se deben a varios factores:

  • La fuerte revalorizaciĆ³n del gas natural en los mercados.
  • Subida de los derechos del Co2.Estos derechos han subido en mĆ”s de un 100 % en tan solo seis meses, algo que afecta en los precios elĆ©ctricos diarios en Europa.
  • La escasez de oferta y el alto precio del gas natural y carbĆ³n estĆ” causando un desvĆ­o masivo hacia el petrĆ³leo y sus derivados para la generaciĆ³n de electricidad y usos industriales, segĆŗn el informe sobre el mercado del petrĆ³leo que elabora la Agencia Internacional de la EnergĆ­a (AIE).
  • La falta de chips semiconductores (circuitos integrados) son muchos y la soluciĆ³n no va a llegar rĆ”pido.

contribucion <- contribucion  %>%
  filter(date == "2021-10-01") %>%
  slice_max (value , n = 20)



componentes_europa <- treemap(contribucion,
                          index="componente",
                          vSize="value",
                          type="index",
                          title="AportaciĆ³n componentes a la inflaciĆ³n interanual de Octubre 2021",
                          palette="Spectral",
                          border.col=c("white"), 
                          border.lwds=3, 
                          fontface.labels=1,
                          bg.labels=c("transparent"),              
                          align.labels=c("center", "center"),                                  
                          overlap.labels=0.5)


5.3. InflaciĆ³n ā€œen el peor momentoā€

La variaciĆ³n interanual del Ć­ndice de precios de consumo armonizado (IPCA) para la eurozona fue del 4,4% en octubre, en el momento de su publicaciĆ³n, fue la cifra mĆ”s alta en la serie histĆ³rica de la oficina europea de estadĆ­sticas, que arranca en 1997. Este insĆ³lito rĆ©cord ha sido batido solo un mes despuĆ©s, con un nuevo mĆ”ximo histĆ³rico en el dato de variaciĆ³n interanual de precios de consumo armonizado (IPCA) situĆ”ndose en el 4,9 %, 0,8 p.Ā p.Ā superior al del mes anterior.

Un apunte a destacar, para que el lector pueda formarse una mejor opiniĆ³n al respecto, es que estos datos sĆ³lo representan una media, es decir, como podrĆ” observar mediante la tabla adjunta en el punto 5.4 con los datos de inflaciĆ³n, tendremos economĆ­as por encima del 4,4% y economĆ­as por debajo. Alemania, por ejemplo, economĆ­a siempre sensible a los movimientos de los precios, llega a tener datos de IPC anual del 4,6% para octubre. EspaƱa se queda en el 5,4%. Un solo mes ha bastado para que Eurostat presente nuevos rĆ©cords en los datos de inflaciĆ³n. Alemania incrementa su Ćŗltimo dato en 1,4 puntos para llegar su IPC anual al 6%. BĆ©lgica se sitĆŗa en algo mĆ”s del 7%, y le superan los tres paĆ­ses bĆ”lticos (Lituania, Letonia y Estonia). EspaƱa, por su parte, se queda en el 5,6%. Los Ćŗnicos paĆ­ses de la zona euro en los que podrĆ­a hablarse de una inflaciĆ³n contenida son Francia (3,4%) y Portugal (2,7%): De todos modos, la gran mayorĆ­a de economĆ­as del viejo continente superaron el objetivo establecido en el 2%, anteriormente mencionado.


inflacion_eurozona <- inflacion_eurozona %>% filter( TIME == "European Union - 27 countries (from 2020)")

inflacion_eurozona_sub <- inflacion_eurozona %>% filter(Tipo == "subyacente")
inflacion_eurozona_gen <- inflacion_eurozona %>% filter(Tipo == "general")

europa <- ggplot() +
  
  geom_col(data = inflacion_eurozona_sub, aes(date, value, fill = value), color= "grey",  alpha = 0.5) +
  scale_fill_continuous(low="#ffffbf",high="#fee08b")  +
  geom_text(data = inflacion_eurozona_sub, aes(date, value, label = value), y=-0.2 ) +
  geom_text(data = inflacion_eurozona_sub, aes(date, value, label = "%"), y=-0.2, hjust = -1 ) +
  
  geom_line(data = inflacion_eurozona_gen, aes(date, value, color = value),size = 1.5) +
  scale_color_continuous(low="#3288bd",high="#3288bd") +
  geom_text(data = inflacion_eurozona_gen, aes(date, value, label = value), vjust = -2,hjust = 1) +
  geom_text(data = inflacion_eurozona_gen, aes(date, value, label = "%"), vjust = -2, hjust = -0.2) +
  
  geom_point(data = inflacion_eurozona_gen, aes(date, value), size = 4, color = "#3288bd") +
  
  geom_hline(yintercept = 2,
             size = 1.5,
             colour = "#abdda4",
             linetype = "dashed") +
  
  annotate(geom = "text",
           x= as.Date("2020-11-21"),
           y = 2.2,
           label = "Objetivo inflacion 2%",
           size = 4,
           color = "black")  + 
  
  theme(axis.text.x = element_text(angle = 70, hjust = 1)) +
  
  scale_x_date(date_labels="%b %y",date_breaks  ="1 month") +
  
  lims(y= c(-0.3,5)) + 
  
  theme(panel.grid.major = element_line(colour = "darkgray", 
                           linetype = "dashed"), 
        panel.grid.minor = element_line(colour = NA),
        panel.background = element_rect(fill = NA),
        plot.background = element_rect(colour = NA),
        legend.position = "none") +labs(x = NULL, y = "Valores expresados en %") + 
  theme(panel.grid.major = element_line(colour = NA)) +
  theme(legend.position = "right", legend.direction = "horizontal") +
  labs(fill = "Subyacente") + 
  theme(legend.position = c(0.20, 0.8)) +
  labs(colour = "General") + 
  theme(legend.text = element_text(colour = NA),
      legend.title = element_text(face = "bold"),
      legend.key = element_rect(fill = NA),
      legend.background = element_rect(fill = NA))+labs(colour = "General       ") + 
  theme(axis.text = element_text(size = 12,
      face = "bold"), axis.text.y = element_text(size = 12)) + 
  theme(axis.line = element_line(linetype = "solid")) + 
  theme(axis.line = element_line(linetype = "blank"),
      axis.ticks = element_line(colour = NA,
      linetype = "blank"), plot.title = element_text(size = 14,
      face = "bold"), legend.text = element_text(colour = "black")) +labs(title = "EvoluciĆ³n de la inflaciĆ³n en la Comunidad Europea",
      subtitle = "InclaciĆ³n mensual ", caption = "Fuente: ElaboracĆ³n propia con datos de Eurostat") + 
  theme(axis.ticks = element_line(linetype = "solid"),
    axis.text = element_text(colour = NA),
    axis.text.x = element_text(colour = "black")) +labs(subtitle = "InclaciĆ³n mensual (Europa de los 27)") +
  labs(y = NULL)  

europa

Este problema nos llega en el peor momento posible para toda la eurozona. Aunque si hay economĆ­as con una buena estructura macroeconĆ³mica, otras, como el caso de la espaƱola o la italiana presentan ciertos desajustes que solo han hecho mĆ”s que de agravarse desde la llegada de la Covid-19. Cabe recordar que en la UE, la polĆ­tica monetaria estĆ” completamente supeditada por el BCE, por tanto las diferentes naciones no gozan de autonomĆ­a monetaria. La conclusiĆ³n es clara, la economĆ­a estĆ” sufriendo un shock dentro de su camino de recuperaciĆ³n del anterior shock , uno protagonizado por el alza en precios y otro por la paralizaciĆ³n econĆ³mica como consecuencia de la pandemia, por tanto, el problema original, como a continuaciĆ³n expondremos, solo ha hecho que complicar la incierta situaciĆ³n en la que desgraciadamente en los Ćŗltimos aƱos nos desenvolvemos.


5.4 Tabla

library(tidyverse)
library(DT)

inflacion_eurozona <- read_csv("datos/inflacion_eurozona.csv", 
                               col_types = cols(date = col_date(format = "%Y/%m")))

inflacion_eurozona_sub <- inflacion_eurozona %>% filter(Tipo == "subyacente") %>% rename(country = TIME) 
inflacion_eurozona_gen <- inflacion_eurozona %>% filter(Tipo == "general") %>% rename(country = TIME) 
tabla_inflacion <- left_join(inflacion_eurozona_gen, inflacion_eurozona_sub, by = c("date" = "date", "country" = "country"))

tabla_inflacion <- tabla_inflacion %>% 
  dplyr::select(country, date, Tipo.x, value.x, Tipo.y, value.y) %>% 
  dplyr::select(-(c(Tipo.x , Tipo.y))) %>% 
  rename(general = value.x, subyacente = value.y) 

datatable(tabla_inflacion, class ="stripe hover compact row-border" , filter = 'top')


6 InflaciĆ³n en el contexto EspaƱol.

El precio de la luz dispara el IPC hasta el 5,6 %, su tasa mƔs alta en 29 aƱos.

6.1 General y Subyacente, el efecto inflacionista para EspaƱa.

Si nos centramos en el contexto espaƱol, la situaciĆ³n, como ya avanzamos, es tambiĆ©n crĆ­tica. El Ćŗltimo dato publicado por el Instituto Nacional de EstadĆ­stica (INE), marca un nuevo pico para la inflaciĆ³n este aƱo (5,6%), su tasa mĆ”s alta en 29 aƱos. Nuestra economĆ­a domĆ©stica se encuentra en una tendencia alcista desde el pasado marzo. La implicaciĆ³n econĆ³mica es clara; se estĆ” produciendo un encarecimiento del coste de la vida. Las causas sĆ³n las mismas que las anteriormente mencionadas para el contexto europeo (altos precios de la electricidad y los combustibles, el repunte del consumo y los problemas en las cadenas de suministro globales, falta de contenedores, escasez de trabajadores, carencia de chipsā€¦).

inflacion_esp_gen <- inflacion_esp %>% filter(tipo == "general")
inflacion_esp_sub <- inflacion_esp %>% filter(tipo == "subyacente")


esp <- ggplot() +
  
  geom_line(data = inflacion_esp_gen, aes(date, value, colour = tipo), size = 1.5) +
  geom_point(data = inflacion_esp_gen, aes(date, value,  colour = tipo, shape = tipo), size = 3) +
  geom_text(data = inflacion_esp_gen, aes(date, value, label = value, colour = tipo), vjust = 2.5,hjust = 0.5, size = 3) +
  geom_text(data = inflacion_esp_gen, aes(date, value, label = "%", colour = tipo), vjust = 2.5,hjust = -1, size = 3) +
  
  geom_line(data = inflacion_esp_sub, aes(date, value,  colour = tipo), size = 1.5) +
  geom_point(data = inflacion_esp_sub, aes(date, value, colour = tipo, shape = tipo), size = 3) +
  geom_text(data = inflacion_esp_sub, aes(date, value, label = value, colour = tipo), vjust = -1.5,hjust = 0.75, size = 3) +
  geom_text(data = inflacion_esp_sub, aes(date, value, label = "%", colour = tipo), vjust = -1.5,hjust = -0.5, size = 3) +
  
  
  scale_color_manual(breaks = c("general", "subyacente"),
                     values=c("#00008B", "#00BFFF")) +
  
  geom_hline(yintercept = 0,
             size = 0.25,
             colour = "black",
             linetype = "dashed") +
  
  scale_x_date(date_labels="%b %y",date_breaks  = "1 month") +
  
  theme(axis.text.x = element_text(angle = 70, hjust = 1)) +
  
  lims(y= c(-1, 6.5)) +
  labs(x = NULL) +
  labs(caption = "Fuente: ElaboraciĆ³n propia con datos de INEbase") +
  theme(panel.grid.major = element_line(colour = NA)) + 
  theme(panel.background = element_rect(fill = "transparent")) +
  theme(legend.title=element_blank()) +
  theme(axis.title.y=element_blank(), axis.text.y=element_blank(),
        axis.ticks.y=element_blank()) +
  labs(colour = "General")  + theme(plot.subtitle = element_text(colour = "gray24"),
    panel.grid.major = element_line(colour = "white"),
    panel.grid.minor = element_line(colour = "white"),
    panel.background = element_rect(colour = "white"),
    legend.position = "bottom", legend.background = element_rect(fill = "transparent"),
    legend.direction = "horizontal") +
  labs(title = "EvoluciĆ³n anual del IPC", subtitle = "ƍndice general y subyacente.") +
  guides(shape = FALSE) 



#grafico 2


esp_1 <- ggplot() +
  geom_line(data = inflacion_var_esp, aes(date, value), colour = "#212F3D", size = 1.5) +
  
  scale_x_date(date_labels="%Y",date_breaks  ="5 years") +
  
  geom_hline(yintercept =0,
             size = 0.25,
             colour = "black")  + 
  
  annotate("rect",
           xmin = as.Date("2020-01-01"),
           xmax = as.Date("2022-11-01"),
           ymin = -Inf,
           ymax = Inf,
           alpha = 0.4,
           fill = "pink") +
  
  scale_y_continuous(breaks = seq(-1, 6, 1)) +
  labs(title = "VariaciĆ³n en los ultimos 30 aƱos.", subtitle = "ƍndice general.") +
  theme(axis.line = element_line(size = 0.05,
    linetype = "solid"), panel.grid.major = element_line(colour = "gray88",
    size = 0.25, linetype = "twodash"), panel.grid.minor = element_line(colour = NA),
    axis.text = element_text(face = "italic",
        colour = "gray10"), axis.text.x = element_text(colour = "gray10"),
    panel.background = element_rect(fill = NA,
        colour = "aquamarine4"))+labs(x = NULL, y = NULL)




#esp + inset_element(esp_1, left = 0, right = 0.4, bottom = 0.5, top = 0.9)


6.2 PonderaciĆ³n componentes

En lo que respecta a la ponderaciĆ³n por componentes, como se puede apreciar, el patrĆ³n de pesos de cada partida que considera el INE para calcular el IPC no ha experimentado significativos cambios desde 2017. Puede sorprender que la partida de 04, aunque sĆ­ ha experimentado un incremento, no es tan marcado como el real, esto se debe simplemente al formato de cĆ”lculo. Con todo, el gran incremento del grupo 01 compensa las pequeƱas bajadas que han experimentado grupos como Ocio y cultura y RestauraciĆ³n y hoteles. Bajadas razonables si tenemos en consideraciĆ³n la situaciĆ³n sanitaria de los Ćŗltimos 2 aƱos.


componentes <- ggplot(ponderacion_componentesIPC, aes(Componentes, value, fill = as_factor(date)))+
  geom_col(position = position_stack(reverse = TRUE)) +
  coord_flip() +
  scale_fill_brewer(palette = "Spectral") + 
  
  
  theme(panel.grid.major = element_line(colour = NA),
    panel.grid.minor = element_line(colour = NA),
    axis.text = element_text(face = "bold"),
    legend.title = element_text(size = 14,
      face = "bold"), panel.background = element_rect(fill = NA),
    plot.background = element_rect(colour = NA),
    legend.position = "bottom", legend.direction = "horizontal") +
    labs(title = "Ponderaciones por grupos IPC",
    x = NULL, y = "Unidades: %1000 en base 2016",
    fill = NULL, subtitle = "AcumulaciĆ³n por grupos del periodo 2017-2021") + 
  theme(legend.position = "left", legend.direction = "vertical") +
  labs(caption = "Fuente: Elaboracion propia con datos del INE")

componentes <- ggplotly(componentes)

componentes


6.3 InflaciĆ³n Comunidades AutĆ³nomas/ Provincias.

Si minimizamos el foco de anĆ”lisis y desagregamos por CCAA, podemos observar como todas, exceptuando las islas canarias, disponen de peores datos que la media para la UE_27. Mayores conclusiones podemos extraer si analizamos el problema mediante datos por provincias (vĆ©ase mapa de provincias). Los mayores datos de inflaciĆ³n se encuentran en aquellas provincias caracterizadas por realizar actividades primarias/secundarias. Una explicaciĆ³n razonable se puede deber a la falta de capacidad de estos sectores para trasladar todo el sobrecoste adicional de los precios de la electricidad y materias primas a los siguientes eslabones en la cadena de valor. Aunque consideramos que puede ser un tema muy interesante, no vamos a entrar a estudiar en profundidad estos subtemas que surgen en nuestro artĆ­culo, ya que nos estamos a centrando mĆ”s en el estudio de la inflaciĆ³n a mayor escala, perĆ³ sĆ­ nos parece relevante al menos presentar los datos desagregados para observar en quĆ© zonas geogrĆ”ficas de EspaƱa, la pĆ©rdida de poder adquisitivo de las familias es mĆ”s acusada.


comunidades <- inflacion_comunidades %>%
  filter(date == "2021-10-01") %>%
  mutate(id = seq(1:19))

number_of_bar <- nrow(comunidades)
angle <-  90 - 360 * (comunidades$id-0.5) /number_of_bar     

comunidades$hjust<-ifelse( angle < -90, 1, 0)

comunidades$angle<-ifelse(angle < -90, angle+180, angle)


p <- ggplot(comunidades, aes( as.factor(id),value, fill=nombre_comunidad)) +       
  geom_bar(stat="identity") +
  scale_fill_manual(breaks = c("AndalucĆ­a", "AragĆ³n", "Principado de Asturias","Illes Balears","Canarias","        Cantabria","Castilla y LeĆ³n","Castilla - La Mancha","CataluƱa","Comunitat Valenciana","Extremadura","Galicia","Comunidad de Madrid","RegiĆ³n de Murcia","Comunidad Foral de Navarra","PaĆ­s Vasco","La Rioja","Ceuta","Melilla"),
                 values=c("#546e7a", "#fb8c00","#1b5e20","#00897b","#f4511e","#689f38","#ffca28","#4dd0e1","#01579b","#bdbdbd","#1a237e","#82b1ff","#5e35b1","#ffff00","#d500f9","#d4e157","#6d4c41","#e57373","#c51162")) +
  ylim(-5,7) +
  theme_minimal() +
  theme(
    axis.text = element_blank(),
    axis.title = element_blank(),
    panel.grid = element_blank(),
    plot.margin = unit(rep(-1,4), "cm")) +
  
  coord_polar(start = 0) +
  
  geom_text(data=comunidades, aes(id, value+0.5, label=value, hjust=hjust ), color="black", fontface="bold",alpha=0.6, size=5, angle= comunidades$angle, inherit.aes = FALSE ) + labs(fill = "Comunidades") +
  labs(x = NULL, fill = NULL)

p

Provinicas

Mapa

data_prov <- tidy(shapefile_provincias)

data_prov$group <- as.character(data_prov$group) 

nombres_provincias <- read_excel("datos/nombres_provincias.xlsx")

data_provincias_mapa <- left_join(data_prov, nombres_provincias, by = "id") %>% rename(prov = shapefile_provincias.Texto)

inflacion_prov <- read_excel("shp/inflacion_prov.xlsx")
inflacion_prov <- inflacion_prov %>% rename(id2 = id)

mapa_prov <- left_join(inflacion_prov, data_provincias_mapa, by = c("id2" = "id")) 


aa <- mapa_prov %>%
  ggplot(aes( x= long, y = lat, group = group)) +
  geom_polygon(aes(fill=value),
               color = "white", size = 0.2) +
  labs( title = "Tasa de Riesgo de Pobreza por Comunidades AutĆ³nomas",
        subtitle = "Unidades: Porcentaje",
        caption = "Fuente: INE",
        fill = "Tasa (%)") +
  theme_minimal() +
  theme(
    axis.line = element_blank(),
    axis.text = element_blank(),
    axis.title = element_blank(),
    axis.ticks = element_blank(),
    plot.background = element_rect(fill = "snow", color = NA),
    panel.background = element_rect(fill= "snow", color = NA),
    plot.title = element_text(size = 16, hjust = 0),
    plot.subtitle = element_text(size = 12, hjust = 0),
    plot.caption = element_text(size = 8, hjust = 1),
    legend.title = element_text(color = "grey40", size = 8),
    legend.text = element_text(color = "grey40", size = 7, hjust = 0),
    legend.position = c(0.93, 0.3),
    plot.margin = unit(c(0.5,2,0.5,1), "cm")) +
  theme_minimal() +
  theme(
    axis.line = element_blank(),
    axis.text = element_blank(),
    axis.title = element_blank(),
    axis.ticks = element_blank(),
    panel.background = element_rect(colour= "darkgrey", size= 0.5)) +
  ggtitle("Provincias EspaƱolas")


aa <- ggplotly(aa)
aa

provincia_max <- inflacion_provincias %>% filter(date == "2021-10-01") %>% slice_max(value, n=1) %>% 
  dplyr::select(-date) %>% 
  rename(inflacion = value)

banderas <- c("https://upload.wikimedia.org/wikipedia/commons/6/63/Bandera_de_Le%C3%B3n_%28ciudad%29.svg", "https://upload.wikimedia.org/wikipedia/commons/b/bf/Bandera_de_la_provincia_de_Toledo.svg")


provincia_max_urls <- provincia_max %>% group_by(nombre_provincia) %>% 
  add_column(banderas) %>% ungroup()



Tabla_max <- provincia_max_urls %>% gt()

Tabla_max <- Tabla_max %>%
  tab_header(title = md("**Provincia con mayor inflaciĆ³n**"),subtitle = md("A fecha: 01-10-2021"))

Tabla_max <- Tabla_max %>%
  tab_options(heading.background.color = "#9ccc65") %>% tab_options(heading.title.font.size = 15, heading.subtitle.font.size = 13,  column_labels.font.weight =  "bold")


Tabla_max <- Tabla_max  %>%
  gt::text_transform(locations = cells_body(columns = vars(banderas)), fn = function(x) {gt::web_image(x, height = 50)}) %>%  cols_align(
    align = "center")


provincia_min <- inflacion_provincias %>% filter(date == "2021-10-01") %>% 
slice_min(value, n=1) %>% 
  dplyr::select(-date) %>% rename(inflacion = value)


bandera <- c("https://upload.wikimedia.org/wikipedia/commons/9/9c/Bandera_Provincial_de_Las_Palmas.png")


provincia_min_urls <- provincia_min %>% group_by(nombre_provincia) %>% 
  add_column(bandera) %>% ungroup()



Tabla_min <- provincia_min_urls %>% gt()

Tabla_min <- Tabla_min %>%
  tab_header(title = md("**Provincia con menor inflaciĆ³n**"),subtitle = md("A fecha: 01-10-2021"))

Tabla_min <- Tabla_min %>%
  tab_options(heading.background.color = "#9ccc65") %>% tab_options(heading.title.font.size = 15, heading.subtitle.font.size = 13,  column_labels.font.weight =  "bold")


Tabla_min <- Tabla_min  %>%
  gt::text_transform(locations = cells_body(columns = vars(bandera)), fn = function(x) {gt::web_image(x, height = 50)}) %>%  cols_align(
    align = "center")


Tabla

inflacion_provincias <- inflacion_provincias %>%
  filter(date == "2021-10-01") %>% 
  rename(inflacion = value) 
  

datatable(inflacion_provincias, class ="stripe hover compact row-border" , filter = 'top')


6.4. La dependencia energƩtica

Para el caso espaƱol esta situaciĆ³n (aumento de los precios energĆ©ticos) le perjudica en mayor medida. Como es bien sabido, nuestra economĆ­a se caracteriza por una fuerte dependencia energĆ©tica exterior. Si consultamos los Ćŗltimos datos del Instituto Nacional de EstadĆ­stica (INE), en EspaƱa apenas se produce un tercio de la energĆ­a que se consume. Estos datos sitĆŗan a EspaƱa como uno de los paĆ­ses de la UniĆ³n Europea mĆ”s dependientes energĆ©tica, ya que la media de la UE se sitĆŗa cerca del 50%. Este factor es clave para entender, en parte, el problema actual, y es una de las variables en las que se deberĆ­a empezar a centrar EspaƱa. Si no es asĆ­, las futuras fluctuaciones del precio de la energĆ­a, generan inestabilidades en el coste de vida periĆ³dicamente, y en paralelo a los shocks. El futuro es incierto, y aunque se ha gozado de un perĆ­odo de estabilidad, nadie nos garantiza que las fluctuaciones no se repitan de forma prolongada.


7. Consecuencias de la inflaciĆ³n

Una inflaciĆ³n suficientemente alta perjudica a todo el mundo (o a casi todo el mundo), especialmente cuando Ć©sta es prolongada. Pero si tomamos como referencia las hipĆ³tesis que estĆ”n adoptando organismos internacionales y banco central europeo:



Es decir, si asumimos que la inflaciĆ³n va a ser transitoria, que efectos puede tener sobre los agentes econĆ³micos, Āæa quiĆ©n afecta mĆ”s la inflaciĆ³n?


7.1 ĀæA quiĆ©n afecta mĆ”s la inflaciĆ³n?

Los efectos redistributivos en un perĆ­odo corto de inflaciĆ³n ā€œcontroladaā€ dependen de la estructura patrimonial y de la estructura de ingresos y gastos de los distintos individuos que conforman una determinada economĆ­a. La inflaciĆ³n es mĆ”s daƱina para aquellos agentes que tengan en cartera activos de renta fija en lugar de activos de renta variable (histĆ³ricamente Ć©sta se revalorizan en perĆ­odos de inflaciĆ³n). Es decir, aquellos agentes que carezcan de deuda (o cuya deuda estĆ© indexada a la inflaciĆ³n) y que dispongan de ingresos/gastos insensibles a la inflaciĆ³n en el corto plazo pueden verse beneficiados por la alza de precios. Por tanto, los agentes que no se hallen en esta situaciĆ³n (no disponen de una cartera patrimonial que se revalorice con la inflaciĆ³n) verĆ”n cĆ³mo su patrimonio neto se reduce en tĆ©rminos reales, junto a su capacidad de generaciĆ³n de nuevo ahorro en tĆ©rminos reales (bajo supuesto que no se producen revalorizaciones salariales en dicho perĆ­odo mayores a la inflaciĆ³n).

La pregunta que debe formularse el lector es clara:

ĀæEn quĆ© medida se encuentran distribuidos las familias entre dichas categorĆ­as?

Analicemos, pues, en quƩ medida los ricos y los pobres se hallan en estas distintas categorƭas en nuestra economƭa domƩstica.

SegĆŗn los Ćŗltimos datos que dispone el Banco de EspaƱa, el porcentaje de familias con activos reales incrementa con la renta. Recuerde el lector dichos activos se caracterizan por tener cierta capacidad de revalorizarse con la inflaciĆ³n. Como se puede observar, mientras que 9 de cada 10 familias que conforman el decil con mayores ingresos disponen de vivienda principal en propiedad, solo el 65% aproximadamente del quintil mĆ”s pobre dispone de ella. Obtenemos resultados similares respecto a otros activos reales como las otras propiedades:

  1. Negocios por trabajo por cuenta propia (22% vs 5%).
  2. Joyas, obras de arteā€¦ (35 vs 10%).
  3. Inmobiliarias (70 vs 20)

prop <- ggplot() +
  geom_col(data = datos_esp_prop, aes(x = reorder(Propiedad, value), y = value, fill = `Percentil de renta`), position = "dodge") +
  scale_fill_brewer(palette = "Greens") + theme(axis.text.x = element_text(colour = "black"),
    panel.background = element_rect(fill = "white"),
    plot.background = element_rect(fill = "white")) +labs(title = "Propiedad activos reales ",
    x = NULL, y = NULL, caption = "Fuente: ElaboraciĆ³n propia con datos del Banco de EspaƱa")+labs(y = "Valore en %") + 
  theme(legend.position = "bottom", legend.direction = "horizontal")


Para la composiciĆ³n de los activos financieros disponemos de resultados similares. Como se puede observar, las familias situadas en los primeros deciles estĆ”n sesgadas hacia los activos de renta fija.


inv <- ggplot() +
  geom_col(data = datos_esp_inv, aes( x = reorder (Act_real, value), y = value, fill = `PERCENTIL DE RENTA`), position = "dodge") +
  scale_fill_brewer() + 
  theme(panel.background = element_rect(fill = "white")) +
  labs(title = "Porcentaje de activos financieros",
    x = NULL, y = "valores en %", caption = "Fuente: ElaboraciĆ³n propia con datos del Banco de EspaƱa ") + 
  theme(legend.position = "bottom", legend.direction = "horizontal")


A todo esto, cabe destacar, que por norma general, los ingresos/gastos de las rentas altas tienen la capacidad de adaptarse mejor a Ć©pocas de inflaciĆ³n. Esto es debido a variedad de motivos que afectan en mayor medida a las clases mĆ”s bajas; menor poder de negociaciĆ³n salarial, menores salarios, disponer de mayores proporciĆ³n de gastos fijos dependientes de la inflaciĆ³n, etc.

Queremos remarcar que estas conclusiĆ³n no debe ser aplicada a otras economĆ­as, los resultados dependen de cĆ³mo es la proporciĆ³n de posesiĆ³n de activos de renta fija vs renta variable en cada economĆ­a, sumado a otras variables que por simplicidad no hemos entrado a valorar en profundidad como bien puede ser la estructura del mercado de trabajo y la influencia que pueda tener la inflaciĆ³n sobre esta, el riesgo divisa, el volumen de paro, etc. PerĆ², bajo el supuesto de BCE (del que todos esperemos que no vaya mal encaminado), una conclusiĆ³n es clara; en EspaƱa la inflaciĆ³n perjudica especialmente a los mĆ”s pobres.


7.2 Estimaciones.

7.2.1. Previsiones en la evoluciĆ³n de la inflaciĆ³n por la OCDE.

Las estimaciones de la OCDE sobre la evoluciĆ³n de la inflaciĆ³n estima que se volverĆ”n a datos por debajo del objetivo del 2%, tanto para Europa como para EspaƱa, a finales del 2022. Si no se cumplen las hipĆ³tesis, escenario no descartable ya que estos organismos se han caracterizado muchas veces por presentar errores en sus estimaciones, podemos esperar un perĆ­odo, donde se prorrogue mĆ”s de un Ćŗnico perĆ­odo. No sabemos quĆ© nos depararĆ” el futuro, pero una cosa queda clara, si las estimaciones no se cumplen, la alta inflaciĆ³n serĆ” desgarradora para una economĆ­a frĆ”gil que se encuentra en su senda de recuperaciĆ³n post-covid.



prediccion_df <- prediccion_inflacion %>%
  dplyr::select(LOCATION, TIME, Value) %>%
  mutate(fecha = lubridate::yq(TIME)) %>%
  mutate(value = round(Value, 2)) %>%
  dplyr::select(-TIME,-Value)

prediccion_df_ea17 <- prediccion_inflacion %>%
  dplyr::select(LOCATION, TIME, Value) %>%
  mutate(fecha = lubridate::yq(TIME)) %>%
  mutate(value = round(Value, 2)) %>%
  dplyr::select(-TIME,-Value) %>%
  filter(LOCATION == "EA17") 

prediccion_df_esp <- prediccion_inflacion %>%
  dplyr::select(LOCATION, TIME, Value) %>%
  mutate(fecha = lubridate::yq(TIME)) %>%
  mutate(value = round(Value, 2)) %>%
  dplyr::select(-TIME,-Value) %>%
  filter(LOCATION == "ESP") 
  

gg <- ggplot() +
  
  geom_line(data = prediccion_df, aes(fecha, value, color = LOCATION), alpha = 0.2) +
  geom_line(data = prediccion_df_ea17, aes(fecha, value), color= "#0288d1", size = 1.5) +
  geom_point(data = prediccion_df_ea17, aes(fecha, value), color= "#0288d1", size = 3) +
  geom_text(data = prediccion_df_ea17, aes(fecha, value, label = value, vjust = -2, hjust= 0.5)) + 
  geom_text(data = prediccion_df_ea17, aes(fecha, value, label = "%"), vjust = -2, hjust= -1.3) +
  
  geom_hline(yintercept = 2,
             size = 1.5,
             colour = "#2e7d32",
             linetype = "dashed") +
  
  annotate("rect",
           xmin = as.Date("2021-09-01"),
           xmax = as.Date("2021-11-01"),
           ymin = -Inf,
           ymax = Inf,
           alpha = 0.4,
           fill = "pink") +
  
  annotate(geom = "label",
           x= as.Date("2023-07-01"),
           y = 1,
           label = "Zona montearia Europea",
           size = 4,
           color = "#0288d1")  + 
  
  annotate(geom = "text",
           x= as.Date("2020-04-01"),
           y = 2.2,
           label = "Objetivo inflacion 2%",
           size = 4,
           color = "black")  + 
  
  scale_x_date(date_labels="%Y-%m",date_breaks  ="3 months") +
  theme(axis.text.x = element_text(angle = 90, hjust = 1)) + 
  theme(panel.background = element_rect(fill = "white"),
    legend.position = "none", legend.direction = "horizontal") +
  labs(y = NULL, colour = NULL) + 
  theme(axis.ticks = element_line(linetype = "blank"),
    axis.text.y = element_text(colour = "white")) + 
  theme(legend.position = NULL) + 
  theme(legend.position = "none")+
  labs(x = NULL)
  





gg1 <- ggplot() +
  geom_line(data = prediccion_df, aes(fecha, value, color = LOCATION), alpha = 0.2) +
  geom_line(data = prediccion_df_esp, aes(fecha, value), color= "#b71c1c", size = 1.5) +
  geom_point(data = prediccion_df_esp, aes(fecha, value), color= "#b71c1c", size = 3) +
  geom_text(data = prediccion_df_esp, aes(fecha, value, label = value, vjust = -2, hjust= 0.5)) + 
  geom_text(data = prediccion_df_esp, aes(fecha, value, label = "%"), vjust = -2, hjust= -1.3) +
  
  geom_hline(yintercept = 2,
             size = 1.5,
             colour = "#2e7d32",
             linetype = "dashed") +
  
  annotate("rect",
           xmin = as.Date("2021-09-01"),
           xmax = as.Date("2021-11-01"),
           ymin = -Inf,
           ymax = Inf,
           alpha = 0.4,
           fill = "pink") +
  
  annotate(geom = "label",
           x= as.Date("2023-07-01"),
           y = 1,
           label = "EspaƱa",
           size = 4,
           color = "#b71c1c")  + 
  
  annotate(geom = "text",
           x= as.Date("2020-04-01"),
           y = 2.2,
           label = "Objetivo inflacion 2%",
           size = 4,
           color = "black")  + 
  
  scale_x_date(date_labels="%Y-%m",date_breaks  ="3 months") +
  
  theme(axis.text.x = element_text(angle = 90, hjust = 1)) + 
      theme(panel.background = element_rect(fill = "white"),
  legend.position = "none", legend.direction = "horizontal") +
  labs(y = NULL, colour = NULL) + 
  theme(axis.ticks = element_line(linetype = "blank"),
    axis.text.y = element_text(colour = "white")) + 
  theme(legend.position = NULL) + 
  theme(legend.position = "none")+
  labs(x = NULL)





  


7.2.2. Crecimiento del PIB.

Las conclusiones extraĆ­das para las estimaciones de inflaciĆ³n sĆ³n aplicables a las del PIB, es decir, si nos situamos en el mejor de los casos, todos los indicadores apuntan que hasta al menos un aƱo, no vamos a estabilizar la situaciĆ³n, por tanto, serĆ­a razonable pensar que el 2022 va ser un aƱo de dura recuperaciĆ³n econĆ³mica para las principales economĆ­as, especialmente en aquellas que ya tienen problemas de base antes del inicio de la escalada en precios, como bien puede ser la espaƱola.


crecimiento_df <- crecimiento %>%
  dplyr::select(LOCATION, TIME, Value) %>%
  mutate(fecha = lubridate::yq(TIME)) %>%
  mutate(value = round(Value, 2)) %>%
  filter(LOCATION %in% c("ESP","EA17")) %>%
  dplyr::select(-TIME,-Value)

crecimiento <- ggplot(crecimiento_df, aes(fecha,value, color= LOCATION)) +
  geom_line(size=2, linetype=7) +
  scale_x_date(date_labels="%Y-%m",date_breaks  ="3 months") +
  theme(axis.text.x = element_text(angle = 90, hjust = 1)) + 
  scale_color_manual(breaks = c("ESP","EA17"),values = c("#E04644","#7CCCE5")) +
  facet_wrap(
    vars(LOCATION), nrow = 2, ncol = 1) +
  annotate("rect",
           xmin = as.Date("2020-01-01"),
           xmax = as.Date("2020-07-01"),
           ymin = -Inf,
           ymax = Inf,
           alpha = 0.4,
           fill = "grey") + 
  geom_hline(yintercept = 100,
             size = 1,
             colour = "grey",
             linetype = "dashed") +
  
  theme(panel.grid.major = element_line(colour = "gray90"),
    panel.grid.minor = element_line(colour = NA),
    plot.title = element_text(size = 10,
        face = "bold"), panel.background = element_rect(fill = NA),
    legend.position = "none") +
  labs(title = "PredicciĆ³n de crecimiento PIB Eurozona",
    x = NULL, y = NULL, colour = NULL, subtitle = "AƱo 2019 en base 100",
    caption = "Fuente:ElaboraciĆ³n propia con datos de la OCDE.") +
  theme(strip.background =element_rect(fill="#424254")) +
  theme(strip.text = element_text(colour = 'white')) +
  theme(strip.text = element_text(size =  15))

crecimiento


7.3 ĀæComo se prevee actuar?

Aunque existe un fuerte debate dentro de la doctrina econĆ³mica sobre si el Banco Central Europeo (BCE) debe empezar a retirar estĆ­mulos, con las duras implicaciones que esto puede tener para las economĆ­as endeudadas como la espaƱola o la italiana, la estratĆ©gia adoptada por las autoridades monetarias europeas al momento de escribir este artĆ­culo es clara, no habrĆ” (por el momento) reducciĆ³n de los estĆ­mulos monetarios. Sobre esta lĆ­nea ya nos avanzaba el diario econĆ³mico francĆ©s Les Echos, en su entrevista al vicepresidente del BCE Luis de Guindos :

ā€œDejamos claro que comenzaremos a subir los tipos poco despuĆ©s de haber finalizado nuestras compras netas de activos. ConfĆ­o en que esas compras netas continuarĆ”n durante el prĆ³ximo aƱoā€

Esta estratĆ©gia, que ya tiene muchos detractores, especialmente las economĆ­as que presentan mayores datos inflaciĆ³n, podrĆ­amos definirla como razonable por variedad de razones:

  1. Las principales causas de inflaciĆ³n no se deben a la polĆ­tica monetaria llevada a cabo por el BCE: La diferencia entre inflaciĆ³n general y subyacente (a juicio de los autores) es bastante grande. Como hemos mostrado mediante los dos Ćŗltimos grĆ”ficos, detrĆ”s de este aumento estĆ”n los sospechosos habituales de los Ćŗltimos meses: electricidad e hidrocarburos. En una palabra, la energĆ­a. Por tanto, delante de este problema de oferta, al que tambiĆ©n tenemos que sumarle la falta de microprocesadores, entre otros productos intermedios, poco se puede hacer actuando sobre la demanda (retirando estĆ­mulos monetarios).

  2. Adicionalmente, el problema inflacionista llega en el peor momento posible. Por una parte, el nivel de endeudamiento de gran parte de las economĆ­as que conforman la eurozona disponen de ratios de Deuda/PIB (vĆ©ase grĆ”fico de endeudamiento) superiores al 100%. Esto supone una restricciĆ³n importante a la hora de tratar controlar la inflaciĆ³n mediante el aumento de tipos de interĆ©s, ya que, puede suponer un aumento en el coste amortizaciĆ³n de la deuda que ralentiza la recuperaciĆ³n econĆ³mica post-pandemia. Por otra parte, tambiĆ©n es poco probable que el BCE retire de forma anticipada los estĆ­mulos monetarios, mĆ”s todavĆ­a con la irrupciĆ³n de la variante Ć³micron, que supone un riesgo adicional para el crecimiento econĆ³mico



p <- ggplot() +
  geom_col(data = deuda_eu, aes(x = reorder(geo, -value), y = value, fill = value)) +
  scale_fill_continuous(low="#81F7F3", high="#0B615E") +
  coord_flip() +
  geom_hline(yintercept = 0.6,
             size = 0.25,
             colour = "blue",
             linetype = "dashed") +
  labs(x = NULL) +
  labs (y = NULL) +
  scale_y_continuous(labels = scales::percent) +
  theme(panel.background = element_rect(fill = "transparent")) +
  labs(title = "Deuda/PIB 2020.",
       caption = "Fuente: ElaboraciĆ³n propia con datos de Eurostat") +
  guides (fill = FALSE)


p

En resumen, para saber si el campo para tomar decisiones se ensancha en el futuro cercano, se tendrĆ” que despejar la incĆ³gnita de cuĆ”nto tiempo van a mantenerse los precios a esta altura y cĆ³mo se implementa, en caso de ser necesario, este tipo de polĆ­tica sin que Ć©sta ocasione una distorsiĆ³n de expectativas que lastre considerablemente el crecimiento econĆ³mico. Es decir la variable clave va a ser el tiempo. Un dato importante acerca de este tema nos la da la Ćŗltima rueda de prensa del presidente del la Reserva Federal (FED) Jerome Powell el pasado 30 de Noviembre, para la FED, despues de una exhaustiva reuniĆ³n, acaban de determinar que empezaran a retirar estĆ­mulos monetarios porque interpretan que la inflaciĆ³n ya no se puede considerar un fenĆ³meno transitorio.



Salvando las distancias, ya que los datos de inflaciĆ³n sĆ³n mĆ”s preocupantes en la economĆ­a americana, si lo podemos considerar como un cambio de tendencia que nos puede empezar a invitar a la reflexiĆ³n acerca de la transitoriedad de la inflaciĆ³n. Por su parte, el banco central sigue apostando a que la subida es coyuntural y que entrado 2022 la inflaciĆ³n perderĆ” fuelle. Aunque no disponemos de la evidencia empĆ­rica suficiente para contrastar la validez de la hipĆ³tesis del BCE, consideramos que la soluciĆ³n no pasa sĆ³lo por reducir los estĆ­mulos monetarios, porque, como hemos visto, el principal problema que experimenta la economĆ­a europea y mundial es un problema de oferta. Nos hemos topado con cuellos de botella en diversas partes de nuestra estructura de producciĆ³n (los microchips, el gas, el carbĆ³n, el transporte, los contenedores, los trabajadores bien formadosā€¦), en un contexto donde se han presentado los mayores paquetes de estĆ­mulo monetarios en la historia. Si no solucionamos el problema de forma inmediata, tanto por el lado de la oferta como por el de la demanda, podemos tener un problema de descontrol inflacionario que cada vez tendrĆ” una mayor complejidad a la hora de implementar soluciones. La conclusiĆ³n es clara, debemos empezar a tomarnos en serio la inflaciĆ³n.


8. Conclusiones

La elaboraciĆ³n del artĆ­culo nos ha servido para aprender en diversos aspectos. Por una parte, hemos mejorado nuestras capacidades de bĆŗsqueda y anĆ”lisis de datos (aunque hemos de reconocer la mĆ”s costosa de la disciplina ā€œdata scienceā€), por otra parte, hemos profundizado mĆ”s en nuestro conocimiento de R.Studio. Si miramos en retrospectiva, los tres autores consideramos que R.Studio es una herramienta potente para trabajar con datos, nunca nos habrĆ­amos imaginado todas las opciones que nos puede dar la programaciĆ³n y en especial la presentaciĆ³n de informes mediante un fichero Rmarckdawn. Creemos que sĆ­ hemos conseguido nuestros objetivos establecidos el primer dĆ­a que nos pusimos en marcha, desarrollar tanto los conocimientos econĆ³micos como los aprendidos mediante el curso de R-studio. Salvando la distancia, si hemos conseguido realizar grĆ”ficos, bajo nuestro criterio, suficientemente elegantes como los compartidos por diferentes economistas que elaboran sus propios grĆ”ficos en su labor de divulgaciĆ³n. Ɖs un tema bastante complejo, y que invita a la profunda reflexiĆ³n y estudio, pero, sin pecar de ambiciosos, creemos que sĆ­ hemos aportado nuestro, insisto, pequeƱƭsimo granito de arena a mostrar un problema econĆ³mico mediante el anĆ”lisis de datos y la elaboraciĆ³n de grĆ”ficos de una forma ya mĆ”s profesionalizada.


9. Referencias

Para la realizaciĆ³n de los grĆ”ficos y los comentarios pertinentes nos hemos basado en la informaciĆ³n que vamos a exponer en los siguientes pĆ”rrafos.

Para poder realizar los comentarios, nos hemos formado con artĆ­culos como los siguientes:

Para poder realizar grƔficos animados, nos hemos basado en las explicaciones de como implementar el paquete gganimate en nuestro proyecto.

Con el paquete dygraph, ademĆ”s de conseguir realizar un grĆ”fico interactivo,este nos permite realizar zoom en cualquier parte del mismo que nos llame la atenciĆ³n.

Dados los problemas para conseguir realizar un mapa intercativo con geom_sf, nos descargamos unos archivos shapelfield con lo que conseguimos hacer un mapa de las provincias de EspaƱa.

AdemĆ”s, para la elaboraciĆ³n de grĆ”ficos que nos parecĆ­an Ćŗtiles para implementar en el trabajo, hemos consultado informaciĆ³n sobre como elaborar un treemap, para observar la importancia de los componentes, un barplot circular, para representar las comunidades autĆ³nomas, y un Spaghetti plot, para en un mismo grĆ”fico de lineas resaltar la que nos interese.

Por Ćŗltimo, destacar como tambiĆ©m hemos consultado trabajos realizados por nuestros compaƱeros el aƱo anterior. Estos Ćŗltimos los podemos encontrar aqui



Para concluir este apartado incluimos la session info:

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

- 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     2021-12-15                  

- Packages -------------------------------------------------------------------
 package           * version    date       lib
 assertthat          0.2.1      2019-03-21 [1]
 backports           1.2.1      2020-12-09 [1]
 base64enc           0.1-3      2015-07-28 [1]
 BiocManager         1.30.16    2021-06-15 [1]
 bit                 4.0.4      2020-08-04 [1]
 bit64               4.0.5      2020-08-30 [1]
 broom             * 0.7.9      2021-07-27 [1]
 bslib               0.3.1      2021-10-06 [1]
 cellranger          1.1.0      2016-07-27 [1]
 checkmate           2.0.0      2020-02-06 [1]
 class               7.3-19     2021-05-03 [2]
 classInt            0.4-3      2020-04-07 [1]
 cli                 3.0.1      2021-07-17 [1]
 clipr               0.7.1      2020-10-08 [1]
 codetools           0.2-18     2020-11-04 [2]
 colorspace          2.0-2      2021-06-24 [1]
 countrycode       * 1.3.0      2021-07-15 [1]
 crayon              1.4.2      2021-10-29 [1]
 crosstalk           1.1.1      2021-01-12 [1]
 curl                4.3.2      2021-06-23 [1]
 data.table          1.14.0     2021-02-21 [1]
 DBI                 1.1.1      2021-01-15 [1]
 dbplyr              2.1.1      2021-04-06 [1]
 desc                1.3.0      2021-03-05 [1]
 details             0.2.1      2020-01-12 [1]
 digest              0.6.28     2021-09-23 [1]
 dplyr             * 1.0.7      2021-06-18 [1]
 DT                * 0.19       2021-09-02 [1]
 dygraphs          * 1.1.1.6    2018-07-11 [1]
 e1071               1.7-8      2021-07-28 [1]
 ellipsis            0.3.2      2021-04-29 [1]
 evaluate            0.14       2019-05-28 [1]
 extrafont           0.17       2014-12-08 [1]
 extrafontdb         1.0        2012-06-11 [1]
 fansi               0.5.0      2021-05-25 [1]
 farver              2.1.0      2021-02-28 [1]
 fastmap             1.1.0      2021-01-25 [1]
 forcats           * 0.5.1      2021-01-27 [1]
 foreign             0.8-81     2020-12-22 [2]
 fs                  1.5.0      2020-07-31 [1]
 gdtools             0.2.3      2021-01-06 [1]
 generics            0.1.1      2021-10-25 [1]
 gganimate         * 1.0.7      2020-10-15 [1]
 ggflags           * 0.0.2      2021-11-03 [1]
 ggplot2           * 3.3.5      2021-06-25 [1]
 ggrepel           * 0.9.1      2021-01-15 [1]
 ggspatial         * 1.1.5      2021-01-04 [1]
 gifski            * 1.4.3-1    2021-05-02 [1]
 glue                1.4.2      2020-08-27 [1]
 gridBase            0.4-7      2014-02-24 [1]
 gridExtra           2.3        2017-09-09 [1]
 grImport2           0.2-0      2019-11-25 [1]
 gt                * 0.3.1      2021-08-07 [1]
 gtable              0.3.0      2019-03-25 [1]
 haven               2.4.3      2021-08-04 [1]
 here              * 1.0.1      2020-12-13 [1]
 highr               0.9        2021-04-16 [1]
 hms                 1.1.1      2021-09-26 [1]
 hrbrthemes        * 0.8.0      2020-03-06 [1]
 htmltools           0.5.2      2021-08-25 [1]
 htmlwidgets         1.5.4      2021-09-08 [1]
 httpuv              1.6.3      2021-09-09 [1]
 httr                1.4.2      2020-07-20 [1]
 igraph              1.2.8      2021-11-07 [1]
 jpeg                0.1-9      2021-07-24 [1]
 jquerylib           0.1.4      2021-04-26 [1]
 jsonlite            1.7.2      2020-12-09 [1]
 kableExtra        * 1.3.4      2021-02-20 [1]
 KernSmooth          2.23-20    2021-05-03 [2]
 klippy            * 0.0.0.9500 2021-11-12 [1]
 knitr             * 1.36       2021-09-29 [1]
 labeling            0.4.2      2020-10-20 [1]
 later               1.3.0      2021-08-18 [1]
 lattice             0.20-44    2021-05-02 [2]
 lazyeval            0.2.2      2019-03-15 [1]
 leafem            * 0.1.6      2021-05-24 [1]
 leaflet           * 2.0.4.1    2021-01-07 [1]
 lifecycle           1.0.1      2021-09-24 [1]
 lubridate         * 1.8.0      2021-10-07 [1]
 magrittr            2.0.1      2020-11-17 [1]
 mapview           * 2.10.0     2021-06-05 [1]
 mime                0.12       2021-09-28 [1]
 modelr              0.1.8      2020-05-19 [1]
 munsell             0.5.0      2018-06-12 [1]
 openxlsx            4.2.4      2021-06-16 [1]
 pacman              0.5.1      2019-03-11 [1]
 patchwork         * 1.1.1      2020-12-17 [1]
 pillar              1.6.4      2021-10-18 [1]
 pkgconfig           2.0.3      2019-09-22 [1]
 plotly            * 4.10.0     2021-10-09 [1]
 plyr                1.8.6      2020-03-03 [1]
 png                 0.1-7      2013-12-03 [1]
 prettyunits         1.1.1      2020-01-24 [1]
 progress            1.2.2      2019-05-16 [1]
 promises            1.2.0.1    2021-02-11 [1]
 proxy               0.4-26     2021-06-07 [1]
 purrr             * 0.3.4      2020-04-17 [1]
 R6                  2.5.1      2021-08-19 [1]
 raster            * 3.4-13     2021-06-18 [1]
 RColorBrewer        1.1-2      2014-12-07 [1]
 Rcpp                1.0.7      2021-07-07 [1]
 readr             * 2.0.1      2021-08-10 [1]
 readxl            * 1.3.1      2019-03-13 [1]
 reprex              2.0.1      2021-08-05 [1]
 rgdal             * 1.5-27     2021-09-16 [1]
 rgeos             * 0.5-8      2021-09-22 [1]
 rio               * 0.5.27     2021-06-21 [1]
 rlang               0.4.12     2021-10-18 [1]
 rmarkdown           2.11       2021-09-14 [1]
 rnaturalearth     * 0.1.0      2017-03-21 [1]
 rnaturalearthdata * 0.1.0      2017-02-21 [1]
 rprojroot           2.0.2      2020-11-15 [1]
 rstudioapi          0.13       2020-11-12 [1]
 Rttf2pt1            1.3.9      2021-07-22 [1]
 rvest               1.0.1      2021-07-26 [1]
 sass                0.4.0      2021-05-12 [1]
 satellite           1.0.4      2021-10-12 [1]
 scales            * 1.1.1      2020-05-11 [1]
 sessioninfo         1.1.1      2018-11-05 [1]
 sf                * 1.0-2      2021-07-26 [1]
 shiny               1.7.1      2021-10-02 [1]
 sp                * 1.4-5      2021-01-10 [1]
 streamgraph       * 0.9.0      2021-11-19 [1]
 stringi             1.7.5      2021-10-04 [1]
 stringr           * 1.4.0      2019-02-10 [1]
 svglite             2.0.0      2021-02-20 [1]
 systemfonts         1.0.3      2021-10-13 [1]
 terra               1.4-20     2021-11-16 [1]
 tibble            * 3.1.6      2021-11-07 [1]
 tidyr             * 1.1.4      2021-09-27 [1]
 tidyselect          1.1.1      2021-04-30 [1]
 tidyverse         * 1.3.1      2021-04-15 [1]
 treemap           * 2.4-3      2021-08-22 [1]
 tweenr              1.0.2      2021-03-23 [1]
 tweetrmd            0.0.9      2021-12-03 [1]
 tzdb                0.1.2      2021-07-20 [1]
 units               0.7-2      2021-06-08 [1]
 utf8                1.2.2      2021-07-24 [1]
 vctrs               0.3.8      2021-04-29 [1]
 viridis           * 0.6.2      2021-10-13 [1]
 viridisLite       * 0.4.0      2021-04-13 [1]
 vroom               1.5.4      2021-08-05 [1]
 webshot             0.5.2      2019-11-22 [1]
 withr               2.4.2      2021-04-18 [1]
 xfun                0.27       2021-10-18 [1]
 XML                 3.99-0.7   2021-08-17 [1]
 xml2                1.3.2      2020-04-23 [1]
 xtable              1.8-4      2019-04-21 [1]
 xts               * 0.12.1     2020-09-09 [1]
 yaml                2.2.1      2020-02-01 [1]
 zip                 2.2.0      2021-05-31 [1]
 zoo               * 1.8-9      2021-03-09 [1]
 source                               
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.2)                       
 Github (rensa/ggflags@e3c6e51)       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.2)                       
 CRAN (R 4.1.2)                       
 CRAN (R 4.1.2)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.2)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.2)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.2)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 Github (rlesur/klippy@378c247)       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.2)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.2)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.2)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 Github (hrbrmstr/streamgraph@76f7173)
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.2)                       
 CRAN (R 4.1.2)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 Github (gadenbuie/tweetrmd@075102b)  
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       
 CRAN (R 4.1.1)                       

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


LS0tDQp0aXRsZTogIkluZmxhY2nDs24gZW4gdGllbXBvcyBkZSBwYW5kZW1pYSINCmF1dGhvcjogIkZyYW5jaXNjbyBNYXJ0w61uZXogQ2FiYWxsZXJvIChmcmFtYTM2QGFsdW1uaS51di5lcykgIFxuXG4gSmVzdXMgTGxvcmV0IFF1ZXJvIChqZWxsb3F1ZUBhbHVtbmkudXYuZXMpICBcbiBcbiBWaWNlbnQgTW9tcG8gQ3Jlc3BvIChtb21jcmVzQGFsdW1uaS51di5lcykuIFxuXG4gVW5pdmVyc2l0YXQgZGUgVmFsw6huY2lhIg0KZGF0ZTogIkRpY2llbWJyZSBkZSAyMDIxIChhY3R1YWxpemFkbyBlbCBgciBmb3JtYXQoU3lzLnRpbWUoKSwgJyVkLSVtLSVZJylgKSINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDogDQogICAgY3NzOiAiLi9hc3NldHMvZXN0aWxvXzEuY3NzIg0KICAgIHNlbGZfY29udGFpbmVkOiB0cnVlDQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQ0KICAgIGNvZGVfZm9sZGluZzogImhpZGUiDQogICAgdGhlbWU6IGRhcmsNCiAgICB0b2M6IHllcw0KICAgIHRvY19mbG9hdDoNCiAgICAgIGNvbGxhcHNlZDogeWVzDQogICAgICBzbW9vdGhfc2Nyb2xsOiB5ZXMNCiAgICBkZl9wcmludDoga2FibGUNCmVkaXRvcl9vcHRpb25zOiANCiAgY2h1bmtfb3V0cHV0X3R5cGU6IGNvbnNvbGUNCi0tLQ0KDQpgYGB7ciBwYWNrYWdlcy1zZXR1cCwgaW5jbHVkZSA9IEZBTFNFfQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KGtsaXBweSkgICAjcmVtb3Rlczo6aW5zdGFsbF9naXRodWIoInJsZXN1ci9rbGlwcHkiKQ0KbGlicmFyeShrbml0cikNCmxpYnJhcnkocmlvKQ0KbGlicmFyeShyZWFkeGwpDQpsaWJyYXJ5KGNvdW50cnljb2RlKQ0KbGlicmFyeShnZ2ZsYWdzKQ0KbGlicmFyeShybmF0dXJhbGVhcnRoKQ0KbGlicmFyeShybmF0dXJhbGVhcnRoZGF0YSkNCmxpYnJhcnkoaHJicnRoZW1lcykNCmxpYnJhcnkoa2FibGVFeHRyYSkNCm9wdGlvbnMoa25pdHIudGFibGUuZm9ybWF0ID0gImh0bWwiKQ0KbGlicmFyeShzdHJlYW1ncmFwaCkNCmxpYnJhcnkodmlyaWRpcykNCmxpYnJhcnkoRFQpDQpsaWJyYXJ5KHBsb3RseSkNCmxpYnJhcnkoZ2dhbmltYXRlKQ0KbGlicmFyeSh4dHMpDQpsaWJyYXJ5KGR5Z3JhcGhzKQ0KbGlicmFyeSh0cmVlbWFwKQ0KbGlicmFyeShnaWZza2kpDQpsaWJyYXJ5KHJnZGFsKQ0KbGlicmFyeShicm9vbSkNCmxpYnJhcnkoc2NhbGVzKQ0KbGlicmFyeShzcCkNCmxpYnJhcnkoZ3QpDQpwYWNtYW46OnBfbG9hZChyYXN0ZXIsIHJnZGwsIHJnZW9zLCBicm9vbSkNCnBhY21hbjo6cF9sb2FkKGtuaXRyLCBoZXJlLCB0aWR5dmVyc2UsIHBhdGNod29yaywgZ2dyZXBlbCkNCnBhY21hbjo6cF9sb2FkKHNmLCBybmF0dXJhbGVhcnRoLCBybmF0dXJhbGVhcnRoZGF0YSwgZ2dzcGF0aWFsLCBtYXB2aWV3LCBsZWFmZW0sIGxlYWZsZXQpDQoNCiNkZXZ0b29sczo6aW5zdGFsbF9naXRodWIoImRncnR3by9nZ2FuaW1hdGUiKQ0KI2luc3RhbGwucGFja2FnZXMgKCJ0cmVlbWFwIikNCiNpbnN0YWxsLnBhY2thZ2VzKCJocmJydGhlbWVzIikNCiNpbnN0YWxsLnBhY2thZ2VzKCJrYWJsZUV4dHJhIikNCiNkZXZ0b29sczo6aW5zdGFsbF9naXRodWIoImhyYnJtc3RyL3N0cmVhbWdyYXBoIikNCiNpZiAoIXJlcXVpcmUoImRldnRvb2xzIikpIA0KICAjaW5zdGFsbC5wYWNrYWdlcygiZGV2dG9vbHMiKQ0KDQojZGV2dG9vbHM6Omluc3RhbGxfZ2l0aHViKCJzam1nYXJuaWVyL3ZpcmlkaXMiKQ0KDQpgYGANCg0KDQoNCg0KYGBge3IgY2h1bmstc2V0dXAsIGluY2x1ZGUgPSBGQUxTRX0NCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSwgZXZhbCA9IFRSVUUsIG1lc3NhZ2UgPSBGQUxTRSwgd2FybmluZyA9IEZBTFNFLCANCiAgICAgICAgICAgICAgICAgICAgICAjcmVzdWx0cyA9ICJob2xkIiwNCiAgICAgICAgICAgICAgICAgICAgICBjYWNoZSA9IEZBTFNFLCBjYWNoZS5wYXRoID0gIi9jYWNoZXMvIiwgY29tbWVudCA9ICIjPiIsDQogICAgICAgICAgICAgICAgICAgICAgI2ZpZy53aWR0aCA9IDcsICNmaWcuaGVpZ2h0PSA3LCAgIA0KICAgICAgICAgICAgICAgICAgICAgICNvdXQud2lkdGggPSA3LCBvdXQuaGVpZ2h0ID0gNywNCiAgICAgICAgICAgICAgICAgICAgICBjb2xsYXBzZSA9IFRSVUUsICBmaWcuc2hvdyA9ICJob2xkIiwNCiAgICAgICAgICAgICAgICAgICAgICBmaWcuYXNwID0gMC42MjgsIG91dC53aWR0aCA9ICI5NSUiLCBmaWcuYWxpZ24gPSAiY2VudGVyIikNCmtuaXRyOjpvcHRzX2NodW5rJHNldChkZXYgPSAicG5nIiwgZGV2LmFyZ3MgPSBsaXN0KHR5cGUgPSAiY2Fpcm8tcG5nIikpDQpgYGANCg0KYGBge3Igb3B0aW9ucy1zZXR1cCwgaW5jbHVkZSA9IEZBTFNFfQ0Kb3B0aW9ucyhzY2lwZW4gPSA5OTkpICMtIHBhcmEgcXVpdGFyIGxhIG5vdGFjacOzbiBjaWVudMOtZmljYQ0Kb3B0aW9ucygieWFtbC5ldmFsLmV4cHIiID0gVFJVRSkgDQpgYGANCg0KDQpgYGB7ciBrbGlwcHksIGVjaG8gPSBGQUxTRX0NCmtsaXBweTo6a2xpcHB5KHBvc2l0aW9uID0gYygidG9wIiwgInJpZ2h0IikpICMtIHJlbW90ZXM6Omluc3RhbGxfZ2l0aHViKCJybGVzdXIva2xpcHB5IikNCmBgYA0KDQo8ZGl2IHN0eWxlPSJ0ZXh0LWFsaWduOiBqdXN0aWZ5Ij48ZGl2Lz4NCg0KPGhyIGNsYXNzPSJsaW5lYS1ibGFjayI+DQoNCjwhLS0gRWwgcMOhcnJhZm8gZGUgYWJham8gaGFzIGRlIGRlamFybG8gY2FzaSBpZ3VhbCwgc29sbyBIQVMgZGUgU1VTVElUVUlSICJwZXJlenA0NCIgcG9yIHR1IHVzdWFyaW8gZGUgR2l0aHViLS0+DQpUcmFiYWpvIGVsYWJvcmFkbyBwYXJhIGxhIGFzaWduYXR1cmEgIlByb2dyYW1hY2nDs24geSBtYW5lam8gZGUgZGF0b3MgZW4gbGEgZXJhIGRlbCBCaWcgRGF0YSIgZGUgbGEgVW5pdmVyc2l0YXQgZGUgVmFsw6huY2lhIGR1cmFudGUgZWwgY3Vyc28gMjAyMS0yMDIyLiBFbCByZXBvIGRlbCB0cmFiYWpvIGVzdMOhIFthcXXDrV0oaHR0cHM6Ly9naXRodWIuY29tL2ZyYW4yMjAwL3RyYWJham9fQmlnRGF0YV9lcXVpcG8pe3RhcmdldD0iX2JsYW5rIn0uIA0KDQo8IS0tIEVsIHDDoXJyYWZvIGRlIGFiYWpvIGhhcyBkZSBkZWphcmxvIGV4YWN0YW1lbnRlIGlndWFsLCBOTyBoYXMgZGUgY2FtYmlhciBuYWRhLS0+DQoNCkxhIHDDoWdpbmEgd2ViIGRlIGxhIGFzaWduYXR1cmEgeSBsb3MgdHJhYmFqb3MgZGUgbWlzIGNvbXBhw7Flcm9zIHB1ZWRlbiB2ZXJzZSBbYXF1w61dKGh0dHBzOi8vcGVyZXpwNDQuZ2l0aHViLmlvL2ludHJvLWRzLTIxLTIyLXdlYi8wNy10cmFiYWpvcy5odG1sKXt0YXJnZXQ9Il9ibGFuayJ9Lg0KDQo8aHIgY2xhc3M9ImxpbmVhLXJlZCI+DQoNCg0KIyMgMS4gSW50cm9kdWNjacOzbg0KDQpQYXJhIGxhIGFzaWduYXR1cmEgZGUgIlByb2dyYW1hY2nDs24geSBtYW5lam8gZGUgZGF0b3MgZW4gbGEgZXJhIGRlbCBCaWcgRGF0YSIgaGVtb3MgZGVjaWRpZG8gcmVhbGl6YXIgdW4gZW5zYXlvIChlbiBmb3JtYXRvIHJtZCkgZGUgcmVsZXZhbmNpYSBnZW5lcmFsIHF1ZSBhZmVjdGEgYSB0b2RvcyBsb3MgY2l1ZGFkYW5vcyAoZXNwZWNpYWxtZW50ZSBhIGxvcyBhZ2VudGVzIGNvbiBtZW5vciBwb2RlciBhZHF1aXNpdGl2byksIGNvbW8gZXMgbGEgKippbmZsYWNpw7NuKiouICANCg0KKipSZXN1bWVuOioqIEVsIGVuY2FyZWNpbWllbnRvIGRlIGxvcyBwcmVjaW9zIGRlIGxhIGVuZXJnw61hLCBqdW50byBsYSBmYWx0YSBkZSBtaWNyb3Byb2Nlc2Fkb3JlcyB5IGxvcyBlc3TDrW11bG9zIG1vbmV0YXJpb3MgbcOhcyBhbWJpY2lvc29zIGVuIGxhIGhpc3RvcmlhIHJlY2llbnRlLCBlc3TDoW4gb2Nhc2lvbmFuZG8gbGEgYXBhcmljacOzbiBkZSBkYXRvcyBkZSBpbmZsYWNpw7NuIHF1ZSBubyBzZSBhbGNhbnphYmFuIGRlc2RlIGxhIGNyaXNpcyBkZWwgcGV0csOzbGVvIGRlIGxvcyBhw7FvcyA3MC4gRW4gcGFydGljdWxhciwgbGEgZWNvbm9tw61hIGV1cm9wZWEsIHkgZW4gZXNwZWNpYWwgbGEgZXNwYcOxb2xhLCBzZSBlbmN1ZW50cmFuIGVuIGVsIHBlb3IgbW9tZW50byBwb3NpYmxlIHBhcmEgYWZyb250YXIgZXN0ZSBkZXNhanVzdGUgZW4gdW5hIGRlIGxhcyBwcmluY2lwYWxlcyB2YXJpYWJsZXMgbWFjcm9lY29uw7NtaWNhcywgbG9zIHByZWNpb3MuIEVzdGEgY2lyY3Vuc3RhbmNpYSwgZXN0w6EgYWZlY3RhbmRvIGVzcGVjaWFsbWVudGUgYSBsYXMgcmVudGFzIG3DoXMgYmFqYXMgeSBnZW5lcmFuZG8gdW4gcHJvYmxlbWEgZGUgZGVzYWJhc3RlY2ltaWVudG8gZGUgY2llcnRvcyBwcm9kdWN0b3MgYSBlc2NhbGEgbXVuZGlhbCwgZW4gdW5vIGRlIGxvcyBjb250ZXh0b3MgbcOhcyBpbmNpZXJ0b3MgZGVsIHJlY2llbnRlIHNpZ2xvIGNvbW8gY29uc2VjdWVuY2lhIGRlIGxhIGV2b2x1Y2nDs24gZGUgbGEgY3Jpc2lzIHNhbml0YXJpYSBwcm92b2NhZGEgcG9yIGVsIENPVklELTE5Lg0KDQoqKlRoZSBBYnN0cmFjdDoqKiBSaXNpbmcgZW5lcmd5IHByaWNlcywgdG9nZXRoZXIgd2l0aCB0aGUgbGFjayBvZiBtaWNyb3Byb2Nlc3NvcnMgYW5kIHRoZSBtb3N0IGFtYml0aW91cyBtb25ldGFyeSBzdGltdWxpIGluIHJlY2VudCBoaXN0b3J5LCBhcmUgY2F1c2luZyB0aGUgZW1lcmdlbmNlIG9mIGluZmxhdGlvbiBkYXRhIHRoYXQgaGFkIG5vdCBiZWVuIHJlYWNoZWQgc2luY2UgdGhlIG9pbCBjcmlzaXMgb2YgdGhlIDE5NzBzLiBJbiBwYXJ0aWN1bGFyLCBUaGUgRXVyb3BlYW4gZWNvbm9teSwgYW5kIGVzcGVjaWFsbHkgdGhlIFNwYW5pc2ggb25lLCBpcyBpbiB0aGUgd29yc3QgcG9zc2libGUgbW9tZW50IHRvIGZhY2UgdGhpcyBpbWJhbGFuY2UgaW4gb25lIG9mIHRoZSBtYWluIG1hY3JvZWNvbm9taWMgdmFyaWFibGVzLCBwcmljZXMuIFRoaXMgY2lyY3Vtc3RhbmNlIGlzIGVzcGVjaWFsbHkgYWZmZWN0aW5nIHRoZSBsb3dlc3QgaW5jb21lcyBhbmQgZ2VuZXJhdGluZyBhIHByb2JsZW0gb2Ygc2hvcnRhZ2VzIG9mIGNlcnRhaW4gcHJvZHVjdHMgb24gYSBnbG9iYWwgc2NhbGUsIGluIG9uZSBvZiB0aGUgbW9zdCB1bmNlcnRhaW4gY29udGV4dHMgb2YgdGhlIHJlY2VudCBjZW50dXJ5IGFzIGEgY29uc2VxdWVuY2Ugb2YgdGhlIGV2b2x1dGlvbiBvZiB0aGUgaGVhbHRoIGNyaXNpcyBjYXVzZWQgYnkgQ09WSUQtMTkuDQoNCioqUGFsYWJyYXMgQ2xhdmU6KiogRW5lcmfDrWEsIEluZmxhY2nDs24sIEVzcGHDsWEsIEV1cm9wYSwgQkNFLCBtaWNyb3Byb2Nlc2Fkb3JlcywgcHJlY2lvLCBwcmVjaW9zLCBnYXMsIHByZWNpb3MgZGUgbGEgZW5lcmfDrWEsIGV4cGVjdGF0aXZhLg0KDQo8YnI+DQoNCiMjIDIuIE1vdGl2YWNpb25lcw0KDQpMYSAqKmluZmxhY2nDs24qKiBlcyB1bmEgZGUgbGFzIHByaW5jaXBhbGVzIHZhcmlhYmxlcyBtYWNyb2Vjb27Ds21pY2FzIHF1ZSBtYXlvciBkaXN0b3JzacOzbiBkZSBleHBlY3RhdGl2YXMgcHVlZGVuIGdlbmVyYXIgZW4gbG9zIGFnZW50ZXMgZWNvbsOzbWljb3MuIMK/UG9yIHF1w6k/IHNlIHB1ZWRlIHByZWd1bnRhciBlbCBsZWN0b3IuIEVzdG8gZXMgZGViaWRvIGEgcXVlIGxhIGZsdWN0dWFjacOzbiBlbiBwcmVjaW9zIGVzIHVuIGNvbmNlcHRvIGLDoXNpY28gcXVlIHRvZG8gaW5kaXZpZHVvIGRlIHVuYSBzb2NpZWRhZCwgaW5kZXBlbmRpZW50ZW1lbnRlIGRlIHNpIGRpc3BvbmUgZGUgY2llcnRvcyBjb25vY2ltaWVudG9zIGVjb27Ds21pY29zLCByw6FwaWRhbWVudGUgc2FiZSBhbmFsaXphciBlIGludGVycHJldGFyLiBFc3RlIGVmZWN0bywgYmFqbyBlbCBzdXB1ZXN0byBkZSByYWNpb25hbGlkYWQgZGUgbG9zIGFnZW50ZXMgcXVlIGludGVyYWN0w7phbiBlbiBsYSBlY29ub23DrWEsIG9jYXNpb25hIHVuIGNhbWJpbyBlbiBsYSB0b21hIGRlIGRlY2lzaW9uZXMuIExhIGNvbmNsdXNpw7NuIGVzIGNsYXJhLCBhIG1heW9yZXMgcHJlY2lvcywgZXMgZGVjaXIsIGEgbWF5b3IgY2FudGlkYWQgZGUgdW5pZGFkZXMgbW9uZXRhcmlhcyByZXF1ZXJpZGFzIHBhcmEgbGEgY29tcHJhIGRlIHVuIGRldGVybWluYWRvIGJpZW4sIG1lbm9yIHNlcsOhIGxhIHNhdGlzZmFjY2nDs24gcXVlIG5vcyBkYSBkaWNobyBpbnRlcmNhbWJpby4gU2kgZXN0ZSBlZmVjdG8gbG8gdHJhc2xhZGFtb3MgYWwgY29uanVudG8gZGUgYmllbmVzIGRlIHVuYSBlY29ub23DrWEsIGxhcyBjb25jbHVzaW9uZXMgc8OzbiBsYXMgbWlzbWFzLCBsb3MgYWdlbnRlcyBlY29uw7NtaWNvcyAocG9yIG5vcm1hIGdlbmVyYWwpIGRpc3BvbmRyZW1vcyBkZSBtZW5vciBwb2RlciBhZHF1aXNpdGl2bywgcG9yIGxvIHRhbnRvLCBzZXJlbW9zIG3DoXMgcG9icmVzLg0KDQpDb25zaWRlcmFtb3MgcXVlIGVsIHRlbWEgZGUgZXN0dWRpbyBkZSBsYSBpbmZsYWNpw7NuIGVzIHVuIHRlbWEgYWN0dWFsLCBxdWUgYWZlY3RhIGEgbGEgbWF5b3LDrWEgZGUgbGFzIGVjb25vbcOtYXMgZGVzYXJyb2xsYWRhcyB5IGRlbCBxdWUgbm8gaGF5IHVuIGNpZXJ0byBjb25zZW5zbyBkZW50cm8gZGUgbGEgY29tdW5pZGFkIGVjb27Ds21pY2Egc29icmUgc3VzIHByaW5jaXBhbGVzIGNhdXNhcyB5LCBlc3BlY2lhbG1lbnRlLCAgc3UgIGV2b2x1Y2nDs24gZW4gZWwgY29ydG8vbWVkaW8gcGxhem8uDQoNCkVuIGVsIG1vbWVudG8gcXVlIGVzdGFtb3MgZGVzYXJyb2xsYW5kbyBlc3RlIGJyZXZlIGFydMOtY3VsbywgbGEgaW5mbGFjacOzbiBhIG5pdmVsIG11bmRpYWwgc2UgZW5jdWVudHJhIOKAnGRpc3BhcmFkYeKAnSBzaSBsYSBjb21wYXJhbW9zIGNvbiBsYSBtZWRpYSBoaXN0w7NyaWNhIGRlIGxvcyDDumx0aW1vcyAyMCBhw7FvcyBlbiBsYSBncmFuIG1heW9yw61hIGRlIGVjb25vbcOtYXMuIFBvciBwb25lciBlbiBjb250ZXh0byBhbCBsZWN0b3IsIGVsIHBhc2FkbyBvY3R1YnJlIGxhIGVjb25vbcOtYSBlc3RhZG91bmlkZW5zZSByZWdpc3Ryw7MgdW5hIGRlIHN1cyBtYXlvcmVzIHRhc2FzIGRlIGluZmxhY2nDs24gZW4gbG9zIMO6bHRpbW9zIDIwIGHDsW9zLCB1biA2LDIlLiBBbGVtYW5pYSwgb3RyYSBlY29ub23DrWEgY2FyYWN0ZXJpemFkYSBwb3IgdGVuZXIgY2llcnRvcyByZWNlbG9zIGEgcHJlc2VudGFyIGRhdG9zIGRlIGluZmxhY2nDs24gZWxldmFkb3MsIHRhbWJpw6luIHJlZ2lzdHJhIHRhc2FzIHN1cGVyaW9yZXMgYWwgNCUuIExhIHTDs25pY2EgaW5mbGFjaW9uaXN0YSAgbm8gZXMgdW4gZWZlY3RvIMO6bmljbyBkZSBsYSBlY29ub23DrWEgZ2VybWFuYSwgc2luw7MgcXVlIHNlIGVzdMOhIG9ic2VydmFuZG8gZW4gbGEgbWF5b3LDrWEgZGUgZWNvbm9tw61hcyBxdWUgY29uZm9ybWFuIGxhIFVuacOzbiBFdXJvcGVhLg0KDQo8YnI+DQoNCjo6OiBjb2x1bW5zDQo6Ojogey5jb2x1bW4gd2lkdGg9IjMyJSJ9DQotICAgUmVjb3JkIGRlIGluZmxhY2nDs246DQoNCmBgYHtyLCBlY2hvID0gRkFMU0UsIG91dC53aWR0aCA9ICI2MCUifQ0KdHdlZXRybWQ6OnR3ZWV0X2VtYmVkKCJodHRwczovL3R3aXR0ZXIuY29tL3Jkb21lbmVjaHYvc3RhdHVzLzE0NjU5MzYxNDM3ODcxNzE4NDA/cz0yMCIsIHRoZW1lID0gImxpZ2h0IiwgYWxpZ24gPSAiY2VudGVyIiwgZG50ID0gVFJVRSwgbWF4d2lkdGggPSA0MDApDQpgYGANCjo6Og0KDQo6Ojogey5jb2x1bW4gd2lkdGg9IjElIn0NCjwhLS0gYW4gZW1wdHkgRGl2ICh3aXRoIGEgd2hpdGUgc3BhY2UpIGhhY2llbmRvIGRlIHNlcGFyYWRvciAtLT4NCjo6Og0KDQo6Ojogey5jb2x1bW4gd2lkdGg9IjMyJSJ9DQotICAgUXVlIGhhY2VyIGFudGUgbGEgc3ViaWRhIGRlbCBJUENBLCDCv1N1YmlkYSBkZSB0aXBvcyBkZSBpbnRlcmVzPw0KDQpgYGB7ciwgZWNobyA9IEZBTFNFLCBvdXQud2lkdGggPSAiNjAlIn0NCnR3ZWV0cm1kOjp0d2VldF9lbWJlZCgiaHR0cHM6Ly90d2l0dGVyLmNvbS9kZnVlbnRlc2Nhc3Ryby9zdGF0dXMvMTQ1NDQzNzE2OTk2ODMzNjg5Nz9zPTIwIiwgdGhlbWUgPSAibGlnaHQiLCBhbGlnbiA9ICJjZW50ZXIiLCBkbnQgPSBUUlVFLCBtYXh3aWR0aCA9IDQwMCkNCmBgYA0KOjo6DQoNCjo6OiB7LmNvbHVtbiB3aWR0aD0iMSUifQ0KPCEtLSBhbiBlbXB0eSBEaXYgKHdpdGggYSB3aGl0ZSBzcGFjZSkgaGFjaWVuZG8gZGUgc2VwYXJhZG9yIC0tPg0KOjo6DQoNCjo6OiB7LmNvbHVtbiB3aWR0aD0iMzIlIn0NCi0gICBJbXBvcnRhbmNpYSBkZWwgYXVnbWVudG8gZGUgbGFzIGVuZXJnaWFzDQoNCmBgYHtyLCBlY2hvID0gRkFMU0UsIG91dC53aWR0aCA9ICI2MCUifQ0KdHdlZXRybWQ6OnR3ZWV0X2VtYmVkKCJodHRwczovL3R3aXR0ZXIuY29tL2hlaW1iZXJnZWNvbi9zdGF0dXMvMTQ2Mzc2MjM2ODEyNzc2NjUzMD9zPTIwIiwgdGhlbWUgPSAibGlnaHQiLCBhbGlnbiA9ICJjZW50ZXIiLCBkbnQgPSBUUlVFLCBtYXh3aWR0aCA9IDQwMCkNCmBgYA0KOjo6DQo6OjoNCg0KPGJyPg0KDQpMYXMgKiptb3RpdmFjaW9uZXMqKiBxdWUgbm9zIGhhIGxsZXZhZG8gYSBsYSBlbGVjY2nDs24gZGUgZXN0YSB0ZW1hIHPDs24gdmFyaWFzOw0KDQotIEVzdHVkaWFyIGVzdGUgZmVuw7NtZW5vIHRhbiBleGNlcGNpb25hbCBlbiBsYXMgZWNvbm9tw61hcyBldXJvcGVhcywgeSBlc3BlY2lhbG1lbnRlIGVuIG51ZXN0cmEgZWNvbm9tw61hIGRvbcOpc3RpY2EuIERlc2RlIHF1ZSBlbXBlemFtb3MgYSBpbnRlcmVzYXJub3MgcG9yIGVsIG11bmRvIGRlIGxhcyBjaWVuY2lhcyBlY29uw7NtaWNhcyBubyBoZW1vcyB2aXZpZG8gdW4gcGVyw61vZG8gZGUgYWx0YSBpbmZsYWNpw7NuLCBwb3IgdGFudG8sIGVzIHVuYSBjaXJjdW5zdGFuY2lhIHF1ZSBub3MgbGxhbWEgbXVjaMOtc2ltbyBsYSBhdGVuY2nDs24uDQoNCi0gRGVzYXJyb2xsYXIgdGFudG8gbG9zIGNvbm9jaW1pZW50b3MgZWNvbsOzbWljb3MgKHRlw7NyaWNvcyB5IHByw6FjdGljb3MpIHF1ZSBoZW1vcyBhZHF1aXJpZG8gZW4gbGEgY2FycmVyYSwgY29tbyBlbiBlbCBjdXJzbyBkZSAgUi5TdHVkaW8uIEFsIHJlc3BlY3RvIGRlIGVzdGUgcHVudG8sIHF1ZXJlbW9zIHJlbWFyY2FyIHF1ZSBub3MgaGEgbGxhbWFkbyBwYXJ0aWN1bGFybWVudGUgbGEgYXRlbmNpw7NuIGxhIGdyYW4gdmFyaWVkYWQgZGUgZ3LDoWZpY29zIHByb2Zlc2lvbmFsaXphZG9zLCBjb21vIGxvcyBhbnRlcmlvcm1lbnRlIGV4cHVlc3RvcywgcXVlIHJlZmVyZW50ZXMgZWNvbm9taXN0YXMgZXN0w6FuIGNvbXBhcnRpZW5kbyBwYXJhIGFuYWxpemFyIGVsIHRlbWEgZGUgaW50ZXLDqXMuIEVzdGEgZXMgdW5hIG1vdGl2YWNpw7NuIGV4dHJhIHBhcmEgbnVlc3RybyBhcnTDrWN1bG8sIHRyYXRhciBkZSBjcmVhciBncsOhZmljb3MgcHJvZmVzaW9uYWxpemFkb3MuDQoNCj4gTnVlc3RybyBwcmluY2lwYWwgb2JqZXRpdm8gZXMgdHJhdGFyIGRlIGRhciByZXNwdWVzdGEgZGUgY3XDoWxlcyBzw7NuIGxhcyBwcmluY2lwYWxlcyBjYXVzYXMgZGUgbGEgaW5mbGFjacOzbiB5IGPDs21vIHB1ZWRlIGFmZWN0YXIgYWwgY3JlY2ltaWVudG8gZGUgbnVlc3RyYSBlY29ub23DrWEgZW4gZWwgY29ydG8vbWVkaW8gcGxhem8uDQoNCjxicj4NCg0KIyMgMy4gRGF0b3MgdXRpbGl6YWRvc3sudGFic2V0IC50YWJzZXQtcGlsbHN9DQoNCg0KIyMjIENvbWVudGFyaW9zDQoNClBhcmEgbGEgcmVhbGl6YWNpw7NuIGRlbCB0cmFiYWpvIGhhIHNpZG8gbmVjZXNhcmlhIGxhIG9idGVuY2nDs24gZGUgaW5mb3JtYWNpw7NuIHByb2NlZGVudGUgZGUgZGl2ZXJzYXMgZnVlbnRlcyBjb21vIHBvciBlamVtcGxvIGVsIElORSB5IEV1cm9zdGF0Lg0KDQpQYXJhIHBvZGVyIHV0aWxpemFyIGVzdG9zIGRhdG9zIGhhIHNpZG8gbmVjZXNhcmlvIG1vZGlmaWNhcmxvcyB5IGFkYXB0YXJsb3MgYW50ZXMgZGUgZW1wbGVhcmxvcyB5IGhhY2VyIGdyw6FmaWNhcy4gRXN0YSBhZGFwdGFjacOzbiBsYSBwb2RlbW9zIGVuY29udHJhciBkZW50cm8gZGVsIGFwYXJ0YWRvIHRpZHksIGRvbmRlIHNlIHJlY29nZW4gdG9kYXMgbGFzIG1vZGlmaWNhY2lvbmVzIHJlYWxpemFkYXMgZGVzZGUgbGEgZGVzY2FyZ2EgZGUgdW4gYXJjaGl2byBjb21vIHB1ZWRlIHNlciB4bHN4IG8gY3ZzIGhhc3RhIHRlbmVyIHVuIGRhdGEgZnJhbWUgY2FyZ2FkbyBlbiBlbCBHbG9iYWwgRW52aXJvbm1lbnQuDQoNCg0KDQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQo8YnI+DQoNCiMjIyBUaWR5IA0KDQpgYGB7ciBlY2hvPVRSVUUsIHdhcm5pbmc9RkFMU0UgfQ0KDQojSGVtb3MgYWRxdWlyaWRvIHVuIGRhdGFmcmFtZSBkZSBsYSBpbmZsYWNpw7NuIHBvciBhZ3J1cGFjaW9uZXMsIHBvciBlbGxvIGNhcmdhbW9zIGVsIGRhdGFmcmFtZSBwYXJhIHBvZGVyIG9ic2VydmFybG8gZW4gRGF0YSB5IGxvIGNvbnZlcnRpbW9zIGVuIGZvcm1hdG8gbG9uZy4gDQppbmZsYWNpb25fYWdydXBhY2lvbmVzIDwtIHJlYWRfZXhjZWwoImRhdG9zL2luZmxhY2lvbl9hZ3J1cGFjaW9uZXMueGxzeCIpDQoNCmluZmxhY2lvbl9hZ3J1cGFjaW9uZXMgPC0gaW5mbGFjaW9uX2FncnVwYWNpb25lcyAlPiUgcGl2b3RfbG9uZ2VyKGNvbHMgPSAzOjYzLCBuYW1lc190byA9ICJkYXRlIikgDQoNCiNVbmEgdmV6IGxvIGhlbW9zIGhlY2hvLCBsYXMgdmFyaWFibGVzIGRhdGEgeSB2YWx1ZSBlc3RhYmFuIGVuIGZvcm1hdG8gY2hhcmFjdGVyLCBwb3IgZWxsbyBoZW1vcyB0ZW5pZG8gcXVlIGV4cG9ydGFyIGVzdGUgZG9jdW1lbnRvIHkgY2FtYmlhciBlc3RhcyB2YXJpYWJsZXMgYSBmb21hdG8gbnVtw6lyaWNvIG1hbnVhbG1lbnRlLCBvYnRlbmllbmRvIGFzw60gZWwgZGF0YSBmcmFtZSBpbmZsYWNpb25fYWdydXAuIFVuYSB2ZXogaGVjaG8gZXN0byBwb2RlbW9zIGNhcmdhciBkaXJlY3RhbWVudGUuIA0KDQppbmZsYWNpb25fYWdydXAgPC0gaW5mbGFjaW9uX2FncnVwYWNpb25lcw0KDQojcmlvOjpleHBvcnQoaW5mbGFjaW9uX2FncnVwLCAiLi9kYXRvcy9pbmZsYWNpb25fYWdydXAuY3N2IikNCg0KaW5mbGFjaW9uX2FncnVwIDwtIHJlYWRfY3N2KCJkYXRvcy9pbmZsYWNpb25fYWdydXAuY3N2IiwgDQogICAgY29sX3R5cGVzID0gY29scyhkYXRlID0gY29sX2RhdGUoZm9ybWF0ID0gIiVZIiksIA0KICAgICAgICB2YWx1ZSA9IGNvbF9udW1iZXIoKSkpDQoNCmBgYA0KDQpgYGB7ciwgZWNobyA9IFRSVUUsIHdhcm5pbmc9IEZBTFNFfQ0KI0RBVE9TIFBBUkEgTE9TIFBBSVNFUy4NCg0KI0hlbW9zIHJlYWxpemFkbyBsb3MgcGFzb3MgYW50ZXJpb3JlcyBwZXJvIGVzdGEgdmV6IGFwbGljYW5kb2xvcyBhbCBkYXRhZnJhbWUgcXVlIGNvbnRpZW5lbiBsb3MgcGFpc2VzLCBvYnRlbmllbmRvIHVuIG51ZXZvIGRhdGFmcmFtZSBpbmZsYWNpb25fY291bnRyeSBxdWUgcG9kZW1vcyBjYXJnYXIgZGlyZWN0YW1lbnRlLiANCmluZmxhY2lvbl9wYWlzZXMgPC0gcmVhZF9leGNlbCgiZGF0b3MvaW5mbGFjaW9uX3BhaXNlcy54bHN4IikNCmluZmxhY2lvbl9wYWlzZXMgPC0gaW5mbGFjaW9uX3BhaXNlcyAlPiUgcGl2b3RfbG9uZ2VyKGNvbHMgPSA0OjY0LCBuYW1lc190byA9ICJkYXRlIikgDQppbmZsYWNpb25fcGFpc2VzJGNvZGU8LXRvbG93ZXIoY291bnRyeWNvZGUoaW5mbGFjaW9uX3BhaXNlcyRjb3VudHJ5X25hbWUsb3JpZ2luID0gJ2NvdW50cnkubmFtZScsIGRlc3RpbmF0aW9uID0gJ2lzbzJjJykpDQoNCiNVbmEgdmV6IGxvIGhlbW9zIGhlY2hvLCBsYXMgdmFyaWFibGVzIGRhdGEgeSB2YWx1ZSBlc3RhYmFuIGVuIGZvcm1hdG8gY2hhcmFjdGVyLCBwb3IgZWxsbyBoZW1vcyB0ZW5pZG8gcXVlIGV4cG9ydGFyIGVzdGUgZG9jdW1lbnRvIHkgY2FtYmlhciBlc3RhcyB2YXJpYWJsZXMgYSBmb21hdG8gbnVtw6lyaWNvIG1hbnVhbG1lbnRlLCBvYnRlbmllbmRvIGFzw60gZWwgZGF0YSBmcmFtZSBpbmZsYWNpb25fY291bnRyeS4gVW5hIHZleiBoZWNobyBlc3RvIHBvZGVtb3MgY2FyZ2FyIGRpcmVjdGFtZW50ZS4gDQoNCmluZmxhY2lvbl9jb3VudHJ5IDwtIGluZmxhY2lvbl9wYWlzZXMNCg0KI3Jpbzo6ZXhwb3J0KGluZmxhY2lvbl9jb3VudHJ5LCAiLi9kYXRvcy9pbmZsYWNpb25fY291bnRyeS5jc3YiKQ0KDQppbmZsYWNpb25fY291bnRyeSA8LSByZWFkX2NzdigiZGF0b3MvaW5mbGFjaW9uX2NvdW50cnkuY3N2IiwgDQogICAgY29sX3R5cGVzID0gY29scyhkYXRlID0gY29sX2RhdGUoZm9ybWF0ID0gIiVZIiksIA0KICAgICAgICB2YWx1ZSA9IGNvbF9udW1iZXIoKSkpDQoNCmBgYA0KYGBge3IsIGVjaG8gPSBUUlVFLCB3YXJuaW5nPSBGQUxTRX0NCiNEQVRPUyBQQVJBIExBIENSRUFDScOTTiBERSBNQVBBUw0KDQojRW4gZXN0ZSBwYXNvIGhlbW9zIGp1dGFkbyBlbCBkYXRhZnJhbWUgd29ybGQgY29uIGVsIGFudGVyaW9yIHBhcmEgcG9kZXIgaW1wb3J0YXJsZSBsYXMgZ2VvbWV0cmlhcyB5IHBvZGVyIGhhY2VyIG1hcGFzLg0KDQp3b3JsZCA8LSBybmF0dXJhbGVhcnRoOjpuZV9jb3VudHJpZXMoc2NhbGUgPSAibWVkaXVtIiwgcmV0dXJuY2xhc3MgPSAic2YiKQ0Kd29ybGQgPC0gd29ybGQgJT4lIGZpbHRlcihzdWJyZWdpb24gIT0gIkFudGFyY3RpY2EiKSAlPiUgZmlsdGVyKGFkbWluICE9ICJHcmVlbmxhbmQiKQ0Kd29ybGQgPC0gd29ybGQgJT4lIGRwbHlyOjpzZWxlY3QobmFtZSwgaXNvX2EzLCBnZW9tZXRyeSkNCg0KaW5mbGFjaW9uX2dlb20gPC0gZnVsbF9qb2luKGluZmxhY2lvbl9jb3VudHJ5LCB3b3JsZCwgYnkgPSBjKCJjb3VudHJ5LWNvZGUiID0gImlzb19hMyIpKQ0KDQpgYGANCg0KYGBge3IsIGVjaG8gPSBUUlVFLCB3YXJuaW5nPSBGQUxTRX0NCg0KIyBQYXJhIHBvZGVyIHJlYWxpemFyIHVuIHRyZWVtYXAgaGVtb3MgYWRxdWlyZG8gZGF0b3Mgc29icmUgbGEgZXZvbHVjacOzbiBkZSB2YXJpb3MgY29tcG9uZW50ZXMgeSBsb3MgaGVtb3MgdHJhdGFkbyBkZSBsYSBzaWd1aWVudGUgZm9ybWEgDQoNCmNvbnRyaWJ1Y2lvbiA8LSByZWFkX2V4Y2VsKCJkYXRvcy9jb250cmlidWNpb24ueGxzIikNCmNvbnRyaWJ1Y2lvbiA8LSBjb250cmlidWNpb24gJT4lIHBpdm90X2xvbmdlcihjb2xzID0gMjoyMywgbmFtZXNfdG8gPSAiZGF0ZSIpIA0KDQojcmlvOjpleHBvcnQoY29udHJpYnVjaW9uLCAiLi9kYXRvcy9jb250cmlidWNpb24uY3N2IikgDQoNCmNvbnRyaWJ1Y2lvbiA8LSByZWFkX2NzdigiZGF0b3MvY29udHJpYnVjaW9uLmNzdiIsIA0KICAgIGNvbF90eXBlcyA9IGNvbHMoZGF0ZSA9IGNvbF9kYXRlKGZvcm1hdCA9ICIlWS8lbSIpKSkNCg0KYGBgDQoNCmBgYHtyLCBlY2hvID0gVFJVRSwgd2FybmluZz0gRkFMU0V9DQoNCiMgQWxndW5hIG1pZXJkYSBxdWUgaGFnYW1vcyBjb24gZXN0b3MgZGF0b3MgDQoNCnByY19oaWNwX21hbnIgPC0gcmVhZF9leGNlbCgiZGF0b3MvcHJjX2hpY3BfbWFuci54bHMiKQ0KDQpwcmNfaGljcF9tYW5yIDwtIHByY19oaWNwX21hbnIgJT4lIHBpdm90X2xvbmdlcihjb2xzID0gMjozNSwgbmFtZXNfdG8gPSAiZGF0ZSIpDQpwcmNfaGljcF9tYW5yIDwtIHByY19oaWNwX21hbnIgJT4lIHJlbmFtZShjb3VudHJ5ID0gYEdFTy9USU1FYCkgDQoNCiMgcmlvOjpleHBvcnQocHJjX2hpY3BfbWFuciwgIi4vZGF0b3MvcHJjX2hpY3BfbWFuci5jc3YiKQ0KDQpwcmNfaGljcF9tYW5yIDwtIHJlYWRfY3N2KCJkYXRvcy9wcmNfaGljcF9tYW5yLmNzdiIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xfdHlwZXMgPSBjb2xzKGRhdGUgPSBjb2xfZGF0ZShmb3JtYXQgPSAiJVkvJW0iKSkpDQoNCmBgYA0KDQoNCmBgYHtyLCBlY2hvID0gVFJVRSwgd2FybmluZz0gRkFMU0V9DQoNCmluZmxhY2lvbl9ldXJvcGVhIDwtIHJlYWRfZXhjZWwoImRhdG9zL2luZmxhY2lvbl9ldXJvcGVhLnhsc3giKQ0KDQppbmZsYWNpb25fZXVyb3BlYSA8LSBpbmZsYWNpb25fZXVyb3BlYSAlPiUgcGl2b3RfbG9uZ2VyKGNvbHMgPSAyOjM1LCBuYW1lc190byA9ICJkYXRlIikNCmluZmxhY2lvbl9ldXJvcGVhIDwtIGluZmxhY2lvbl9ldXJvcGVhICU+JSByZW5hbWUoY291bnRyeSA9IGBHRU8vVElNRWApIA0KDQojcmlvOjpleHBvcnQoaW5mbGFjaW9uX2V1cm9wZWEsICIuL2RhdG9zL2luZmxhY2lvbl9ldXJvcGVhLmNzdiIpDQoNCmluZmxhY2lvbl9ldXJvcGVhIDwtIHJlYWRfY3N2KCJkYXRvcy9pbmZsYWNpb25fZXVyb3BlYS5jc3YiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbF90eXBlcyA9IGNvbHMoZGF0ZSA9IGNvbF9kYXRlKGZvcm1hdCA9ICIlWS8lbSIpKSkNCmxpYnJhcnkodGlkeXZlcnNlKQ0Kd29ybGQgPC0gcm5hdHVyYWxlYXJ0aDo6bmVfY291bnRyaWVzKHNjYWxlID0gIm1lZGl1bSIsIHJldHVybmNsYXNzID0gInNmIikNCndvcmxkIDwtIHdvcmxkICU+JSBmaWx0ZXIoc3VicmVnaW9uICE9ICJBbnRhcmN0aWNhIikgJT4lIGZpbHRlcihhZG1pbiAhPSAiR3JlZW5sYW5kIikNCndvcmxkIDwtIHdvcmxkICU+JSBkcGx5cjo6c2VsZWN0KG5hbWUsIGlzb19hMywgZ2VvbWV0cnkpDQoNCmluZmxhY2lvbl9nZW9tX2V1cm9wIDwtIGxlZnRfam9pbihpbmZsYWNpb25fZXVyb3BlYSwgd29ybGQsIGJ5ID0gYygiY291bnRyeSIgPSAibmFtZSIpKSAlPiUNCiAgZmlsdGVyKGRhdGUgPj0gIjIwMjAtMDEtMDEiKQ0KDQpgYGANCg0KYGBge3IsIGVjaG8gPSBUUlVFLCB3YXJuaW5nPSBGQUxTRX0NCg0KaW5mbGFjaW9uX2V1cm96b25hIDwtIHJlYWRfZXhjZWwoImRhdG9zL2luZmxhY2lvbl9ldXJvem9uYS54bHN4IikNCg0KaW5mbGFjaW9uX2V1cm96b25hIDwtIGluZmxhY2lvbl9ldXJvem9uYSAlPiUgcGl2b3RfbG9uZ2VyKGNvbHMgPSAzOjE0LCBuYW1lc190byA9ICJkYXRlIikNCg0KDQojcmlvOjpleHBvcnQoaW5mbGFjaW9uX2V1cm96b25hLCIuL2RhdG9zL2luZmxhY2lvbl9ldXJvem9uYS5jc3YiKQ0KDQppbmZsYWNpb25fZXVyb3pvbmEgPC0gcmVhZF9jc3YoImRhdG9zL2luZmxhY2lvbl9ldXJvem9uYS5jc3YiLCANCiAgICBjb2xfdHlwZXMgPSBjb2xzKGRhdGUgPSBjb2xfZGF0ZShmb3JtYXQgPSAiJVkvJW0iKSkpDQoNCg0KDQoNCmBgYA0KDQpgYGB7ciwgZWNobyA9IFRSVUUsIHdhcm5pbmc9IEZBTFNFfQ0KDQppbmZsYWNpb25fZXNwIDwtIHJlYWRfZXhjZWwoImRhdG9zL2luZmxhY2lvbl9lc3AueGxzeCIpDQoNCmluZmxhY2lvbl9lc3AgPC0gaW5mbGFjaW9uX2VzcCAgJT4lIHBpdm90X2xvbmdlcihjb2xzID0gMjoyMywgbmFtZXNfdG8gPSAiZGF0ZSIpDQoNCg0KI3Jpbzo6ZXhwb3J0KGluZmxhY2lvbl9lc3AsIi4vZGF0b3MvaW5mbGFjaW9uX2VzcC5jc3YiKQ0KDQppbmZsYWNpb25fZXNwIDwtIHJlYWRfY3N2KCJkYXRvcy9pbmZsYWNpb25fZXNwLmNzdiIsIA0KICAgIGNvbF90eXBlcyA9IGNvbHMoZGF0ZSA9IGNvbF9kYXRlKGZvcm1hdCA9ICIlWS8lbSIpKSkNCg0KYGBgDQoNCmBgYHtyLCBlY2hvID0gVFJVRSwgd2FybmluZz0gRkFMU0V9DQoNCnBvbmRlcmFjaW9uX2NvbXBvbmVudGVzSVBDIDwtIHJlYWRfZXhjZWwoImRhdG9zL3BvbmRlcmFjaW9uX2NvbXBvbmVudGVzSVBDLnhscyIpDQoNCnBvbmRlcmFjaW9uX2NvbXBvbmVudGVzSVBDIDwtIHBvbmRlcmFjaW9uX2NvbXBvbmVudGVzSVBDICU+JSBwaXZvdF9sb25nZXIoY29scyA9IDI6NiwgbmFtZXNfdG8gPSAiZGF0ZSIpDQoNCg0KI3Jpbzo6ZXhwb3J0KHBvbmRlcmFjaW9uX2NvbXBvbmVudGVzSVBDLCIuL2RhdG9zL3BvbmRlcmFjaW9uX2NvbXBvbmVudGVzSVBDLmNzdiIpDQoNCg0KDQpwb25kZXJhY2lvbl9jb21wb25lbnRlc0lQQyA8LSByZWFkX2NzdigiZGF0b3MvcG9uZGVyYWNpb25fY29tcG9uZW50ZXNJUEMuY3N2IiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xfdHlwZXMgPSBjb2xzKGRhdGUgPSBjb2xfbnVtYmVyKCksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IGNvbF9udW1iZXIoKSkpDQoNCmBgYA0KDQpgYGB7ciwgZWNobyA9IFRSVUUsIHdhcm5pbmc9IEZBTFNFfQ0KIA0KaW5mbGFjaW9uX2NvdW1pbmRhZGVzIDwtIHJlYWRfZXhjZWwoImRhdG9zL2luZmxhY2lvbl9jb3VtaW5kYWRlcy54bHMiKQ0KDQppbmZsYWNpb25fY291bWluZGFkZXMgPC0gaW5mbGFjaW9uX2NvdW1pbmRhZGVzICU+JSBwaXZvdF9sb25nZXIoY29scyA9IDI6MjMsIG5hbWVzX3RvID0gImRhdGUiKQ0KDQoNCiNyaW86OmV4cG9ydChpbmZsYWNpb25fY291bWluZGFkZXMsIi4vZGF0b3MvaW5mbGFjaW9uX2NvdW1pbmRhZGVzLmNzdiIpDQoNCmluZmxhY2lvbl9jb211bmlkYWRlcyA8LSByZWFkX2NzdigiZGF0b3MvaW5mbGFjaW9uX2NvdW1pbmRhZGVzLmNzdiIsIA0KICAgIGNvbF90eXBlcyA9IGNvbHMoZGF0ZSA9IGNvbF9kYXRlKGZvcm1hdCA9ICIlWS8lbSIpKSkNCg0KYGBgDQoNCmBgYHtyLCBlY2hvID0gVFJVRSwgd2FybmluZz0gRkFMU0V9DQoNCmluZmxhY2lvbl9wcm92aW5jaWFzIDwtIHJlYWRfZXhjZWwoImRhdG9zL2luZmxhY2lvbl9wcm92aW5jaWFzLnhscyIpDQoNCmluZmxhY2lvbl9wcm92aW5jaWFzIDwtIGluZmxhY2lvbl9wcm92aW5jaWFzICU+JSBwaXZvdF9sb25nZXIoY29scyA9IDI6MjMsIG5hbWVzX3RvID0gImRhdGUiKQ0KDQojcmlvOjpleHBvcnQoaW5mbGFjaW9uX3Byb3ZpbmNpYXMsIi4vZGF0b3MvaW5mbGFjaW9uX3Byb3ZpbmNpYXMuY3N2IikNCg0KaW5mbGFjaW9uX3Byb3ZpbmNpYXMgPC0gcmVhZF9jc3YoImRhdG9zL2luZmxhY2lvbl9wcm92aW5jaWFzLmNzdiIsIA0KICAgIGNvbF90eXBlcyA9IGNvbHMoZGF0ZSA9IGNvbF9kYXRlKGZvcm1hdCA9ICIlWS8lbSIpKSkNCg0KYGBgDQoNCmBgYHtyLCBlY2hvID0gVFJVRSwgd2FybmluZz0gRkFMU0V9DQppbmZsYWNpb25fdmFyX2VzcCA8LSByZWFkX2V4Y2VsKCJkYXRvcy92YXJfaW50ZXJhbnVhbF9lc3AueGxzeCIpDQoNCmluZmxhY2lvbl92YXJfZXNwIDwtIGluZmxhY2lvbl92YXJfZXNwICAlPiUgcGl2b3RfbG9uZ2VyKGNvbHMgPSAyOjM2MCwgbmFtZXNfdG8gPSAiZGF0ZSIpDQoNCiNyaW86OmV4cG9ydChpbmZsYWNpb25fdmFyX2VzcCwiLi9kYXRvcy9pbmZsYWNpb25fdmFyX2VzcC5jc3YiKQ0KDQppbmZsYWNpb25fdmFyX2VzcCA8LSByZWFkX2NzdigiZGF0b3MvaW5mbGFjaW9uX3Zhcl9lc3AuY3N2IiwgDQogICAgY29sX3R5cGVzID0gY29scyhkYXRlID0gY29sX2RhdGUoZm9ybWF0ID0gIiVZLyVtIikpKQ0KDQoNCmBgYA0KDQpgYGB7ciwgZWNobyA9IFRSVUUsIHdhcm5pbmc9IEZBTFNFfQ0KDQojRGF0b3MgZW4gZm9ybWF0byBwb2zDrWdvbm8gcGFyYSBwb2RlciBlcmFsaXphciB1biBtYXBhIGRlIGNvcm9wbGV0YXMgaW50ZXJhY3Rpdm8NCnNoYXBlZmlsZV9wcm92aW5jaWFzIDwtIHNoYXBlZmlsZSgic2hwL1Byb3ZpbmNpYXNfRVRSUzg5XzMwTi5zaHAiKQ0KDQojRGF0b3MgcGFyYSBsYSByZWFsaXphY2nDs24gZGVsIGdyw6FmaWNvIHNvYnJlIGxhIHByZWRpY2Npw7NuDQpwcmVkaWNjaW9uX2luZmxhY2lvbiA8LSByZWFkX2NzdigiZGF0b3MvcHJlZGljY2lvbl9pbmZsYWNpb24uY3N2IiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xfdHlwZXMgPSBjb2xzKFZhbHVlID0gY29sX251bWJlcigpKSkNCg0KYGBgDQoNCmBgYHtyLCBlY2hvID0gVFJVRSwgd2FybmluZz0gRkFMU0V9DQpsaWJyYXJ5KHJlYWRyKQ0KDQojbXlfdXJsIDwtICJodHRwczovL2VjLmV1cm9wYS5ldS9ldXJvc3RhdC9hcGkvZGlzc2VtaW5hdGlvbi9zZG14LzIuMS9kYXRhL1NER18xN180MC9BLlBDX0dEUC5TMTMuR0QuRVUyN18yMDIwK0JFK0JHK0NaK0RLK0RFK0VFK0lFK0VMK0VTK0ZSK0hSK0lUK0NZK0xWK0xUK0xVK0hVK01UK05MK0FUK1BMK1BUK1JPK1NJK1NLK0ZJK1NFK0lTK05PK0NIK1VLLz9mb3JtYXQ9U0RNWC1DU1Ymc3RhcnRQZXJpb2Q9MjAyMCZlbmRQZXJpb2Q9MjAyMCINCg0KI2N1cmw6OmN1cmxfZG93bmxvYWQobXlfdXJsLCAiLi9kYXRvcy9kZXVkYV9ldS5jc3YiKQ0KDQpkZl9jc3YgPC0gcmlvOjppbXBvcnQoIi4vZGF0b3MvZGV1ZGFfZXUuY3N2IikNCg0KZGV1ZGFfZXUgPC0gcmVhZF9jc3YoIi4vZGF0b3MvZGV1ZGFfZXUuY3N2IiwgDQogICAgICAgICAgICAgICAgICAgIGNvbF90eXBlcyA9IGNvbHMoT0JTX1ZBTFVFID0gY29sX251bWJlcigpKSkgJT4lDQogIGRwbHlyOjpzZWxlY3QoZ2VvLCBPQlNfVkFMVUUpICU+JQ0KICBtdXRhdGUodmFsdWUgPSBPQlNfVkFMVUUvMTAwKQ0KDQpgYGANCg0KYGBge3IsIGVjaG8gPSBUUlVFLCB3YXJuaW5nPSBGQUxTRX0NCg0KIyBEYXRvcyBkZWwgQmFuY28gZGUgZXNwYcOxYSBwYXJhIHRyYXRhciBkZSBhbmFsaXphciBsYSBpbmZsdWVuY2lhIGRlIGxhIGluZmxhY2nDs24gZW4gbGEgcG9ibGFjacOzbiANCiNFc3RlIHByaW1lcm8gZXN0w6EgcmVsYWNpb25hZG8gY29uIGVsIHBvcmNlbnRhamUgZGUgYWN0aXZvcyByZWFsZXMgcXVlIHBvc2VlIGNhZGEgcGVyY2VudGlsIGRlIHJlbnRhDQoNCmRhdG9zX2VzcF9wcm9wIDwtIHJlYWRfZXhjZWwoImRhdG9zL2RhdG9zX2VzcF9wcm9wLnhsc3giLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sX3R5cGVzID0gYygidGV4dCIsICJudW1lcmljIiwgIm51bWVyaWMiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibnVtZXJpYyIsICJudW1lcmljIikpDQoNCmRhdG9zX2VzcF9wcm9wIDwtIGRhdG9zX2VzcF9wcm9wICU+JSBwaXZvdF9sb25nZXIoY29scyA9IDI6NSwgbmFtZXNfdG8gPSAiUHJvcGllZGFkIikNCg0KIyBFc3RlIHNlZ3VuZG8gZXN0YSByZWxhY2lvbmFkbyBjb24gbGEgcHJvcGllZGFkIGRlIGFjdGl2b3MgZmluYW5jaWVyb3MgZGUgY2FkYSBwZXJjZW50aWwgZGUgcmVudGENCmRhdG9zX2VzcF9pbnYgPC0gcmVhZF9leGNlbCgiZGF0b3MvZGF0b3NfZXNwX2ludi54bHN4IiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sX3R5cGVzID0gYygidGV4dCIsICJudW1lcmljIiwgIm51bWVyaWMiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJudW1lcmljIiwgIm51bWVyaWMiKSkNCg0KZGF0b3NfZXNwX2ludiA8LSBkYXRvc19lc3BfaW52ICU+JSBwaXZvdF9sb25nZXIoY29scyA9IDI6NSwgbmFtZXNfdG8gPSAiQWN0X3JlYWwiKQ0KDQoNCmBgYA0KDQpgYGB7ciwgZWNobyA9IFRSVUUsIHdhcm5pbmc9IEZBTFNFfQ0KDQojIERhdG9zIGRlIGxhIE9DREUgZGUgbGEgcHJldmlzaW9uIGRlbCBjcmVjaW1pZW50byBkZWwgUElCIGV1cm96b24NCg0KY3JlY2ltaWVudG8gPC0gcmVhZF9jc3YoImRhdG9zL2NyZWNpbWllbnRvLmNzdiIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgY29sX3R5cGVzID0gY29scyhWYWx1ZSA9IGNvbF9udW1iZXIoKSkpDQoNCg0KYGBgDQoNCg0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KPGJyPg0KDQojIyA0LiBFc3R1ZGlvICoqbXVuZGlhbCoqDQoNCiMjIyA0LjEgRXZvbHVjacOzbiBkZWwgbXVuZG8NCg0KRW4gcHJpbWVyIGx1Z2FyLCB1biBicmV2ZSByZXBhc28gaGlzdMOzcmljbyBhY2VyY2EgZGUgbGEgaW5mbGFjacOzbi4gDQoNClBhcmEgbGEgc2VyaWUgaGlzdMOzcmljYSBhbmFsaXphZGEgc2UgcHVlZGUgb2JzZXJ2YXIgY29tbyBsYSBpbmZsYWNpw7NuIG11bmRpYWwgaGEgZXhwZXJpbWVudGFkbyB1bmEgcmVkdWNjacOzbiBkcsOhc3RpY2EgZW4gbG9zIMO6bHRpbW9zIDMwIGHDsW9zLiANCg0KYGBge3IsIGVjaG8gPSBUUlVFLCB3YXJuaW5nPSBGQUxTRX0NCg0KI0dSQUZJQ08gMQ0KDQpwMSA8LSBpbmZsYWNpb25fYWdydXAgJT4lDQogIGZpbHRlcihjb3VudHJ5X25hbWUgPT0gIk11bmRvIikgJT4lDQogIGZpbHRlcihkYXRlID49IDE5ODEpICU+JSBmaWx0ZXIoc2VyaWVzID09ICJzdWJ5YWNlbnRlIikgJT4lIA0KICBkcGx5cjo6c2VsZWN0KC0oc2VyaWVzKSkNCnAxIDwtIHAxICU+JSAgZHBseXI6OnNlbGVjdCgtKGNvdW50cnlfbmFtZSkpDQoNCnAxMSA8LSBpbmZsYWNpb25fYWdydXAgJT4lDQogIGZpbHRlcihjb3VudHJ5X25hbWUgPT0gIk11bmRvIikgJT4lDQogIGZpbHRlcihkYXRlID49IDE5ODEpICU+JSBmaWx0ZXIoc2VyaWVzID09ICJnZW5lcmFsIikgJT4lIA0KICBkcGx5cjo6c2VsZWN0KC0oc2VyaWVzKSkNCnAxMSA8LSBwMTEgJT4lICBkcGx5cjo6c2VsZWN0KC0oY291bnRyeV9uYW1lKSkNCg0Kc3VieWFjZW50ZSA8LSB4dHMocDEkdmFsdWUsIG9yZGVyLmJ5ID0gcDEkZGF0ZSwgZnJlcXVlbmN5ID0gMzY1KSANCg0KDQpnZW5lcmFsIDwtIHh0cyhwMTEkdmFsdWUsIG9yZGVyLmJ5ID0gcDExJGRhdGUsIGZyZXF1ZW5jeSA9IDM2NSkNCg0KcCA8LSBjYmluZChzdWJ5YWNlbnRlLGdlbmVyYWwpIA0KICANCmR5Z3JhcGgocCwgeWxhYj0gIiUgaW5mbGFjacOzbiIsDQogICAgICAgIG1haW4gPSAiRXZvbHVjacOzbiBJbmZsYWNpw7NuIikgJT4lIA0KICBkeU9wdGlvbnMoY29sb3JzID0gYygiYmx1ZSIsICJicm93bnciKSkgJT4lIA0KICBkeVJhbmdlU2VsZWN0b3IoKQ0KDQpgYGANCg0Kwr9BIHF1w6kgc2UgZGViZSBlc3RhIHJlZHVjY2nDs24gZ2VuZXJhbGl6YWRhIHBhcmEgdG9kYXMgbGFzIGVjb25vbcOtYXMgPyANCiANCkVzcGVjaWFsbWVudGUgYSBsb3MgKipiZW5lZmljaW9zIGRlIGxhIGdsb2JhbGl6YWNpw7NuIHNvYnJlIGVsIGNyZWNpbWllbnRvIGVjb27Ds21pY28qKiA6IExhIGdsb2JhbGl6YWNpw7NuIGhhIGdlbmVyYWRvIHVuICplZmVjdG8gZXNjYWxhKiwgcXVlIHNlIGRlcml2YSBkZWwgbWF5b3IgdGFtYcOxbyBkZSBtZXJjYWRvLiBFc3RlIG1heW9yIHRhbWHDsW8gZGUgbWVyY2FkbyBpbmNlbnRpdmEgYSBsYXMgZW1wcmVzYXMgYSBjcmVjZXIgeSBhIGFkcXVpcmlyIG1heW9yZXMgY29ub2NpbWllbnRvcywgbG8gY3VhbCBhdW1lbnRhIGxhIHByb2R1Y3RpdmlkYWQgYWdyZWdhZGEgeSwgY29uIGVsbG8sIHNlIHByb2R1Y2UgdW4gYXVtZW50byBkZSBsYSBvZmVydGEgYWdyZWdhZGEgYSBuaXZlbCBtdW5kaWFsLiBBIHRvZG8gZXN0byBsZSB0ZW5lbW9zIHF1ZSBzdW1hciBsYSBpbXBvcnRhbmNpYSBkZWwgYXZhbmNlIHRlY25vbMOzZ2ljbyBlbiBsYXMgw7psdGltYXMgZMOpY2FkYXMuDQoNCjxicj4NCg0KIyMjIDQuMiBFdm9sdWNpw7NuIGRlIGxhcyA5IGVjb25vbcOtYXMgcHJpbmNpcGFsZXMNCg0KIyMjIyA0LjIuMSBHcsOhZmljbyBkZSBsaW5lYXMNCg0KU2kgZGVzYWdyZWdhbW9zLCBzZSBwdWVkZSBjb25maXJtYXIgbG8gYW50ZXJpb3JtZW50ZSBtZW5jaW9uYWRvLCBhdW5xdWUgbGFzIGVjb25vbcOtYXMgdGllbmVuIHVuIGFqdXN0ZSBkaWZlcmVudGUgdG9kYXMgbGxlZ2FuIGFsIG1pc21vIGRlc3Rpbm8sIGEgdW5hIGluZmxhY2nDs24gY2FyYWN0ZXJpemFkYSBwb3IgdGFzYXMgZGUgY3JlY2ltaWVudG8gZXN0YWJsZXMuDQoNCmBgYHtyLCBlY2hvID0gVFJVRSwgd2FybmluZz0gRkFMU0UsIGZpZy53aWR0aD0xNSwgZmlnLmhlaWdodD0xNX0NCg0KDQppbmZsYWNpb25fZzkgPC0gaW5mbGFjaW9uX2NvdW50cnkgJT4lIG11dGF0ZShwYWlzZXMgPSBjb3VudHJ5X25hbWUpICU+JSBmaWx0ZXIoY291bnRyeV9uYW1lICVpbiUgYygiVW5pdGVkIFN0YXRlcyIsIkNoaW5hIiwgIkphcGFuIiwgIkdlcm1hbnkiLCAiVW5pdGVkIEtpbmdkb20iLCAiSW5kaWEiLCJGcmFuY2UiLCJJdGFseSIsICJLb3JlYSwgUmVwLiIpKSAlPiUgZmlsdGVyKGBTZXJpZXMgTmFtZWAgPT0gImdlbmVyYWwiKSANCg0KaW5mbGFjaW9uX2c5IDwtIGdncGxvdChpbmZsYWNpb25fZzksIGFlcyh4PWRhdGUsIHk9dmFsdWUpKSArDQogIGdlb21fbGluZShkYXRhPWluZmxhY2lvbl9nOSAlPiUgZHBseXI6OnNlbGVjdCgtY291bnRyeV9uYW1lKSwgYWVzKGdyb3VwPXBhaXNlcyksIGNvbG9yPSJncmV5Iiwgc2l6ZT0wLjUsIGFscGhhPTEpICsNCiAgZ2VvbV9saW5lKCBhZXMoY29sb3I9Y291bnRyeV9uYW1lKSwgY29sb3I9IiM2OWIzYTIiLCBzaXplPTEuMiApKw0KICBzY2FsZV9jb2xvcl92aXJpZGlzKGRpc2NyZXRlID0gVFJVRSkgKw0KICB0aGVtZV9pcHN1bSgpICsNCiAgdGhlbWUoDQogICAgbGVnZW5kLnBvc2l0aW9uPSJub25lIiwNCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MTQpLA0KICAgIHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCkpICsNCiAgDQogIGZhY2V0X3dyYXAofmNvdW50cnlfbmFtZSkgKyB0aGVtZShwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KGZhbWlseSA9ICJzZXJpZiIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGxvdC5jYXB0aW9uID0gZWxlbWVudF90ZXh0KGZhbWlseSA9ICJzZXJpZiIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChmYW1pbHkgPSAic2VyaWYiKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoZmFtaWx5ID0gInNlcmlmIikpICsNCiAgDQogIGxhYnMoDQogICAgICBjYXB0aW9uID0gIkZ1ZW50ZTogRWxhYm9yYWNpw7NuIHByb3BpYSBjb24gZGF0b3MgZGVsIEJhbmNvIE11bmRpYWwiKSArIA0KICAgICAgbGFicyh4ID0gTlVMTCwgeSA9ICJWYWxvcmVzIGVuICUiKQ0KDQpgYGANCg0KDQo8Y2VudGVyPjxpbWcgc3JjPSJpbWFnZW5lcy9pbmZsYWNpb25fRzkucG5nIiB3aWR0aCA9ICIxMTAwcHgiIC8+PC9jZW50ZXI+DQoNCg0KIyMjIyA0LjIuMiBJbmZsYWNpw7NuIGFjdW11bGFkYSANCg0KRGVzZGUgcXVlIGFiYW5kb25hbW9zIGVsIHBhdHLDs24gb3JvLCBsYSBtYXlvcsOtYSBkZSBsYXMgZWNvbm9tw61hcyBoYW4gYWRvcHRhZG8gcG9yIHVuIGluY3JlbWVudG8gc29zdGVuaWRvIHkgY29udHJvbGFkbyBkZSBwcmVjaW9zIHBhcmEgZm9tZW50YXIgc3UgY3JlY2ltaWVudG8uIEF1bnF1ZSBubyB2YW1vcyBhIGVudHJhciBhIHZhbG9yYXIsIHlhIHF1ZSBkYXLDrWEgcGFyYSBvdHJvIGFydMOtY3VsbyBsYSBlZmVjdGl2aWRhZCBkZSBlc3RhIGVzdHJhdGVnaWEsIGRlc2RlIGxhIGNyaXNpcyBkZWwgcGV0csOzbGVvIGRlIGxvcyBhw7FvcyA3MCBsYSBlY29ub23DrWEgbXVuZGlhbCBzZSBoYSBjYXJhY3Rlcml6YWRvIHBvciB1bmEgZXN0YWJpbGlkYWQgZGUgcHJlY2lvcywgYWwgbWVub3MsIGNvbiBsbyBxdWUgcmVzcGVjdGEgYSBsYXMgZWNvbm9tw61hcyBkZWwgRy0yMC4gRWplbXBsbyBkZSBlc3RlIHJhem9uYW1pZW50byBsbyB0ZW5lbW9zIGVuIGxhIGNvbmZpYW56YSBxdWUgZWwgbWVyY2FkbyBkZSBkaXZpc2FzIHRpZW5lIGVuIGxhcyBtb25lZGFzIGRlIGRpY2hhIGFncnVwYWNpw7NuIChHLTIwKSwgZGl2aXNhcyBjb21vIGVsIGTDs2xhciBvIGVsIGV1cm8gc2UgaGFuIGluc3RhdXJhZG8gY29tbyBhY3Rpdm9zIOKAnHNlZ3Vyb3PigJ0uIFRvZGEgZXN0YSDigJxyZWxhdGl2YSBlc3RhYmlsaWRhZOKAnSBoYSBzZWd1aWRvIG1lam9yYW5kbyBsYSBjb25maWFuemEgaW50ZXJuYWNpb25hbCBhIGxhIGhvcmEgZGUgZGVzYXJyb2xsYXIgeSBwcm9mdW5kaXphciBlbiBlbCBjb21lcmNpbyBpbnRlcm5hY2lvbmFsLCBwb3RlbmNpYW5kbyBsb3MgYmVuZWZpY2lvcyBhbnRlcmlvcm1lbnRlIGRlc2NyaXRvcyBzb2JyZSBlbCBjb25qdW50byBkZSBsYSBlY29ub23DrWEuDQoNCmBgYHtyLCBlY2hvID0gVFJVRSwgd2FybmluZz0gRkFMU0V9DQoNCmluZmxhY2lvbl9iYXJyYXMgPC0gcmVhZF9leGNlbCgiZGF0b3MvaW5mbGFjaW9uX2JhcnJhcy54bHN4IiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sX3R5cGVzID0gYygidGV4dCIsICJ0ZXh0IiwgInRleHQiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJudW1lcmljIiwgIm51bWVyaWMiLCAibnVtZXJpYyIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRleHQiLCAibnVtZXJpYyIpKSAlPiUgDQogZHBseXI6OnNlbGVjdCgtKG5hZGEpKQ0KDQoNCmluZmxhY2lvbl9iYXJyYXMgPC0gaW5mbGFjaW9uX2JhcnJhcyAlPiUgDQogIGdyb3VwX2J5KGRhdGUpICU+JSANCiAgYXJyYW5nZShkYXRlLCBkZXNjKGFjdW11bGFkYSkpICU+JSANCiAgbXV0YXRlKHJhbmtpbmcgPSByb3dfbnVtYmVyKCkpICU+JQ0KICBmaWx0ZXIocmFua2luZyA8PTkpICU+JSANCiAgdW5ncm91cCgpIA0KDQp0YWJsYV8xIDwtIGdncGxvdChpbmZsYWNpb25fYmFycmFzLCBhZXMocmFua2luZywgYWN1bXVsYWRhLCBjb3VudHJ5ID0gY29kZSwgc2l6ZSA9IDIwKSkgKw0KICBnZW9tX2NvbChhZXMocmFua2luZywgYWN1bXVsYWRhLCAgZmlsbCA9IGNvdW50cnlfbmFtZSkpICsNCiAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJTcGVjdHJhbCIpICsNCiAgZ2VvbV9mbGFnKGFlcyhyYW5raW5nLCBhY3VtdWxhZGEsIGNvdW50cnkgPSBjb2RlKSwgc2l6ZSA9IDEwKSArDQogIGdlb21fdGV4dChhZXMocmFua2luZywgYWN1bXVsYWRhLCBsYWJlbCA9IGFzLmZhY3RvcihhY3VtdWxhZGEpLCBzaXplID0gNDApLCBoanVzdD0gLTAuNSkgKw0KICBnZW9tX3RleHQoYWVzKHg9OSwgeT02MDAsIGxhYmVsID0gYXMuZmFjdG9yKGRhdGUpKSwgdmp1c3QgPSAwLjIsIGFscGhhID0gMC41LCAgY29sID0gImdyYXkiLCBzaXplID0gMTUpICsNCiAgDQogIHNjYWxlX3hfcmV2ZXJzZSgpICsNCiAgY29vcmRfZmxpcChjbGlwID0gIm9mZiIsIGV4cGFuZCA9IEZBTFNFKSArDQogIHRoZW1lX2xpZ2h0KCkgKw0KICB0aGVtZSgNCiAgICBwYW5lbC5ncmlkID0gZWxlbWVudF9ibGFuaygpLCANCiAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsDQogICAgYXhpcy50aWNrcy55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfYmxhbmsoKSkgKw0KICBsaW1zKHkgPSBjKE5BLDcwMCkpICsgdGhlbWUoYXhpcy5saW5lID0gZWxlbWVudF9saW5lKGNvbG91ciA9IE5BKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF4aXMudGlja3MgPSBlbGVtZW50X2xpbmUoY29sb3VyID0gTkEpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSBOQSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGNvbG91ciA9IE5BKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChjb2xvdXIgPSBOQSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoY29sb3VyID0gTkEpKSArbGFicyh4ID0gTlVMTCwgeSA9IE5VTEwpKw0KICBsYWJzKHRpdGxlID0gIkFjdW11bGFjacOzbiBoaXN0b3JpY2EgZGUgbGEgaW5mbGFjacOzbiIsDQogICAgICAgc3VidGl0bGUgPSAiSW5mbGFjacOzbiBnZW5lcmFsIGRlc2RlIDE5NzEgaGFzdGEgMjAyMC4iLA0KICAgICAgIGNhcHRpb24gPSAiRnVlbnRlOiBFbGFib3JhY2nDs24gcHJvcGlhIGNvbiBkYXRvcyBkZWwgQmFuY28gTXVuZGlhbCIpICsNCiAgDQogIHRyYW5zaXRpb25fc3RhdGVzKGFzLmZhY3RvcihkYXRlKSx0cmFuc2l0aW9uX2xlbmd0aCA9IDEsIHN0YXRlX2xlbmd0aCA9IDAsIHdyYXAgPSBGQUxTRSkNCg0KdGFibGFfMSA8LSB0YWJsYV8xICsgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgDQoNCiNnZ2FuaW1hdGU6OmFuaW1hdGUodGFibGFfMSwgbmZyYW1lcyA9IDY1MCwgZnBzID0gMzApDQoNCg0KDQpgYGANCg0KPGNlbnRlcj48aW1nIHNyYz0iaW1hZ2VuZXMvaW5mbGFjaW9uX2FjdW11bGFkYS5naWYiIHdpZHRoID0gIjgwMHB4IiAvPjwvY2VudGVyPg0KDQoNCjxicj4NCg0KDQojIyMgNC4zIE1hcGEgZGUgY29yb3BsZXRhc3sudGFic2V0IC50YWJzZXQtcGlsbHN9DQoNCiMjIyMgTWFwYSBNdW5kaQ0KDQpTaSBhbXBsaWFtb3MgZWwgZm9jbyAodsOpYXNlIG1hcGEgbXVuZGkgeSB0YWJsYXMpICoqbm8gdG9kYXMgbGFzIGVjb25vbcOtYXMgaGFuIGNvbnRyaWJ1aWRvIGVuIGxhIG1pc21hIHByb3BvcmNpw7NuIGFsIGNyZWNpbWllbnRvIHNvc3RlbmlkbyBlbiBwcmVjaW9zKiosIGF1bnF1ZSBhIG5pdmVsIGFncmVnYWRvIGxhIHRlbmRlbmNpYSBlcyBhIHVuYSByZWR1Y2Npw7NuIGRlIGxhIHRhc2EgZGUgY3JlY2ltaWVudG8gZGUgbG9zIHByZWNpb3MgaGFzdGEgZXN0YWJpbGl6YXJzZSBlbiB2YWxvcmVzIOKAnHJhem9uYWJsZXPigJ0gZGVzZGUgdW5hIHBlcnNwZWN0aXZhIGFjdHVhbCAodsOpYXNlIHB1bnRvIDQuNCkuIA0KDQpDb21vIHNlIHB1ZWRlIGFwcmVjaWFyLCBsYXMgZWNvbm9tw61hcyBtZW5vcyBkZXNhcnJvbGxhZGFzLCBkaXNwb25lbiBkZSBtYXlvcmVzIHRhc2FzIGRlIGNyZWNpbWllbnRvIGVuIHByZWNpb3MsIGVzdG8gc2UgcHVlZGUgYSBkaXZlcnNpZGFkIGRlIGZhY3RvcmVzIHF1ZSBubyB2YW1vcyBhIGVudHJhciBhIGFuYWxpemFyLCBzaW1wbGVtZW50ZSBwYXJhIGhhY2VyIHNhYmVyIGFsIGxlY3RvciBxdWUgbm8gZW4gdG9kb3MgbG9zIHBhw61zZXMgZGVsIG11bmRvIHNlIGhhIGluc3RhdXJhZG8gbGEgZXN0YWJpbGlkYWQgZW4gcHJlY2lvcy4gRXMgcG9yIGVzbyBxdWUgbm8gbG9zIHRlbmRyZW1vcyBlbiBjdWVudGEgYSBsYSBob3JhIGRlIGFuYWxpemFyIGVsIHByb2JsZW1hIGFjdHVhbCwgeWEgcXVlIHPDs24gZWNvbm9tw61hcyBxdWUgcGVyIHNlLCBkaXNwb25lbiBkZSB0YXNhcyBkZSBpbmZsYWNpw7NuIG11Y2hvIG3DoXMgZWxldmFkYXMgcXVlIGxhcyBlY29ub23DrWFzIGRvbmRlIGxhIGVzdGFiaWxpZGFkIGVuIHByZWNpb3Mgc2kgaGEgc2lkbyBlbiBsYSBoaXN0b3JpYSBtw6FzIHJlY2llbnRlIHVuIGF1dMOpbnRpY28gw6l4aXRvLiBEaWNobyBsbyBjdWFsLCBwYXJhIGFuYWxpemFyIGVzdGUgcHJvYmxlbWEgbm9zIHZhbW9zIGEgY2VudHJhciBlbiBlbCBjb250ZXh0byBldXJvcGVvIHkgZW4gZXNwZWNpYWwsIGVuIGVsIGNvbnRleHRvIGVzcGHDsW9sLiBQb3IgdmFyaWVkYWQgZGUgcmF6b25lczsNCg0KMS4gU29uIGVjb25vbcOtYXMgcXVlIGNvbXBhcnRlbiBwb2zDrXRpY2EgbW9uZXRhcmlhIHkgbW9uZWRhIGNvbcO6biwgaGVjaG8gcXVlIGZhY2lsaXRhIGVsIGFuw6FsaXNpcy4NCg0KMi4gU29uIGVjb25vbcOtYXMgc2ltaWxhcmVzLCBkb25kZSBzdSBlc3R1ZGlvIG5vcyBwdWVkZSBmYWNpbGl0YXIgbGEgY29tcGFyYWNpw7NuLg0KDQozLiBTb24gZWwgZWNvbm9tw61hcyBxdWUgY3VtcGxlbiBsb3MgcmVxdWlzaXRvcyBlc3RhYmxlY2lkbyBwYXJhIG51ZXN0cm8gYW7DoWxpc2lzICgqcnVwdHVyYSBkZSBsYSB0ZW5kZW5jaWEgZW4gIGVzdGFiaWxpZGFkIHJlbGF0aXZhIGVuIHByZWNpb3MqKS4NCg0KYGBge3IsIGVjaG8gPSBUUlVFLCB3YXJuaW5nPSBGQUxTRX0NCg0KbGlicmFyeShsdWJyaWRhdGUpDQoNCmluZmxhY2lvbl9nZW9tXzIgPC0gaW5mbGFjaW9uX2dlb20gJT4lICBmaWx0ZXIoYFNlcmllcyBOYW1lYCA9PSAiZ2VuZXJhbCIpICU+JSANCiAgbXV0YXRlKGFueW8gPSBsdWJyaWRhdGU6OnllYXIoZGF0ZSkpICU+JSANCiAgZ3JvdXBfYnkoZGF0ZSkgJT4lIA0KICBmaWx0ZXIoYW55byA+PSAyMDAwKSAlPiUNCiAgbXV0YXRlKGRlY2lsZXMgPSBudGlsZSh2YWx1ZSwgbiA9IDEwKSkgDQoNCm1hcGEgPC0gZ2dwbG90KCkgKw0KICBnZW9tX3NmKGRhdGEgPSBpbmZsYWNpb25fZ2VvbV8yLCBhZXMoZ2VvbWV0cnkgPSBnZW9tZXRyeSwgZmlsbCA9IGRlY2lsZXMpKSArDQogIHRoZW1lX3ZvaWQoKSAgKw0KICB0aGVtZShwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KGZhbWlseSA9ICJzZXJpZiIsIGZhY2UgPSAiaXRhbGljIiksDQogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoZmFtaWx5ID0gInNlcmlmIiwgZmFjZSA9ICAiaXRhbGljIikpICsNCiAgbGFicyh0aXRsZSA9ICJNYXBhOkluZmxhY2nDs24gbXVuZGlhbCIsIGZpbGwgPSAiSW5mbGFjacOzbiIpICArDQogIHNjYWxlX2ZpbGxfY29udGludW91cyhsb3c9IiNmZmZjYmYiLGhpZ2g9IiMzZTk4NTEiKSArIA0KICB0cmFuc2l0aW9uX21hbnVhbChhbnlvKSsNCiAgbGFicyh0aXRsZSA9ICJBw7FvOiB7Y3VycmVudF9mcmFtZX0iLA0KICAgICAgIGNhcHRpb24gPSAiRnVlbnRlOiBFbGFib3JhY2nDs24gcHJvcGlhIGNvbiBkYXRvcyBkZWwgQmFuY28gTXVuZGlhbCIpDQoNCiMgZ2dhbmltYXRlOjphbmltYXRlKG1hcGEsIG5mcmFtZXM9IDEwMCwgZnBzPSA0LCBlbmRfcGF1c2UgPSA1KQ0KDQoNCg0KYGBgDQoNCjxjZW50ZXI+PGltZyBzcmM9ImltYWdlbmVzL211bmRvLmdpZiIgd2lkdGggPSAiODAwcHgiIC8+PC9jZW50ZXI+DQoNCk5vdGUgZWwgbGVjdG9yLCBxdWUgcGFyYSBlbCBhbsOhbGlzaXMgZGUgZGljaG8gcHJvYmxlbWEsIHRhbWJpw6luIHNlIHBvZHLDrWEgaGFiZXIgZXN0dWRpYWRvIGxhIGVjb25vbcOtYSBub3J0ZWFtZXJpY2FuYSB5IGhhYmVyIGV4dHJhw61kbyBjb25jbHVzaW9uZXMgc2ltaWxhcmVzLg0KDQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQo8YnI+DQoNCiMjIyMgVGFibGEgDQoNCmBgYHtyLCBlY2hvID0gVFJVRSwgd2FybmluZz0gRkFMU0V9DQppbmZsYWNpb25fY291bnRyeV9zdWIgPC0gaW5mbGFjaW9uX2NvdW50cnkgJT4lDQogIGZpbHRlcihgU2VyaWVzIE5hbWVgID09ICJzdWJ5YWNlbnRlIikNCg0KaW5mbGFjaW9uX2NvdW50cnlfZ2VuIDwtIGluZmxhY2lvbl9jb3VudHJ5ICU+JQ0KICBmaWx0ZXIoYFNlcmllcyBOYW1lYCA9PSAiZ2VuZXJhbCIpDQoNCnRhYmxhX211bmRvIDwtIGxlZnRfam9pbihpbmZsYWNpb25fY291bnRyeV9zdWIsIGluZmxhY2lvbl9jb3VudHJ5X2dlbiwgYnkgPSBjKCJjb3VudHJ5LWNvZGUiID0gImNvdW50cnktY29kZSIsICJkYXRlIiA9ICJkYXRlIikpDQoNCnRhYmxhX211bmRvIDwtIHRhYmxhX211bmRvICU+JSANCiAgZHBseXI6OnNlbGVjdChjb3VudHJ5X25hbWUueCwgZGF0ZSwgdmFsdWUueCwgdmFsdWUueSkgJT4lIA0KICBkcGx5cjo6cmVuYW1lKGNvdW50cnkgPSBjb3VudHJ5X25hbWUueCwgc3VieWFjZW50ZV8xID0gdmFsdWUueCwgZ2VuZXJhbF8xID0gdmFsdWUueSkgJT4lIGZpbHRlcihjb3VudHJ5ICE9ICJBZmdoYW5pc3RhbiIpICU+JSANCiAgZmlsdGVyKGNvdW50cnkgIT0gIkFsYmFuaWEiKSANCg0KdGFibGFfbXVuZG8gPC0gdGFibGFfbXVuZG8gJT4lIA0KICBtdXRhdGUoc3VieWFjZW50ZSA9IHJvdW5kKHN1YnlhY2VudGVfMSwgZGlnaXRzID0gMikpICU+JSANCiAgbXV0YXRlKGdlbmVyYWwgPSByb3VuZChnZW5lcmFsXzEsIGRpZ2l0cyA9IDIpKSAlPiUgDQogIGRwbHlyOjpzZWxlY3QoLWMoc3VieWFjZW50ZV8xLCBnZW5lcmFsXzEpKQ0KICANCiAgDQoNCmRhdGF0YWJsZSh0YWJsYV9tdW5kbywgY2xhc3MgPSJzdHJpcGUgaG92ZXIgY29tcGFjdCByb3ctYm9yZGVyIiAsIGZpbHRlciA9ICd0b3AnKQ0KDQpgYGANCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCjxicj4NCg0KDQojIyMgNC40IENvbXBhcmFjacOzbiBwb3Igem9uYXMgZ2VvZ3LDoWZpY2FzIHsudGFic2V0IC50YWJzZXQtcGlsbHN9DQoNCkFxdcOtIGVsIGxlY3RvciBwdWVkZSBhcHJlY2lhciBsbyBhbnRlcmlvcm1lbnRlIGV4cHVlc3RvLCB5IGNvbnN1bHRhciBlbiBjYXNvIGRlIHF1ZSByZXN1bHRlIGRlIHN1IGludGVyZXMgbGEgZXZvbHVjacOzbiBoaXN0w7NyaWNhIHBhcmEgY2FkYSB6b25hIGdlb2dyw6FmaWNhLg0KDQoNCiMjIyMgNC40LjEgQW3DqXJpY2EgbGF0aW5hIFZTIE11bmRvIA0KDQpgYGB7ciwgZWNobyA9IFRSVUUsIHdhcm5pbmc9IEZBTFNFfQ0KYW1lcmljYV9sYXRpbmEgPC0gaW5mbGFjaW9uX2FncnVwICU+JSBmaWx0ZXIoc2VyaWVzID09ICJnZW5lcmFsIikgJT4lIA0KICBmaWx0ZXIoY291bnRyeV9uYW1lICVpbiUgYygiQW3DqXJpY2EgTGF0aW5hIHkgZWwgQ2FyaWJlIiwgIk11bmRvIikpICU+JSBmaWx0ZXIoIGRhdGUgPj0gMTk3MSkNCg0KYW1lcmljYV9sYXRpbmEgPC0gZ2dwbG90KCkgKw0KICBnZW9tX2xpbmUoZGF0YSA9IGFtZXJpY2FfbGF0aW5hLCBhZXMoZGF0ZSwgdmFsdWUsIGNvbG9yID0gY291bnRyeV9uYW1lKSwgc2l6ZT0xKSArDQogIHNjYWxlX2NvbG9yX3ZpcmlkaXMoZGlzY3JldGUgPSBUUlVFKSArDQogIHRoZW1lKA0KICAgIGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIsDQogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTE0KQ0KICApICsNCiAgZ2d0aXRsZSgiSW5mbGFjaW9uIG11bmRpYWwiKSArDQogIHRoZW1lX2lwc3VtKCkgKyB0aGVtZShwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KGZhbWlseSA9ICJzZXJpZiIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgcGxvdC5jYXB0aW9uID0gZWxlbWVudF90ZXh0KGZhbWlseSA9ICJzZXJpZiIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChmYW1pbHkgPSAic2VyaWYiKSwNCiAgICAgICAgICAgICAgICAgICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoZmFtaWx5ID0gInNlcmlmIikpICtsYWJzKHRpdGxlID0gIkdyYWZpY2EgMzogQW1lcmljYSBsYXRpbmEgdnMgTXVuZG8iLCBzdWJ0aXRsZSA9ICIoSW5mbGFjacOzbiBnZW5lcmFsKSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4ID0gTlVMTCwgeSA9ICJWYWxvcmVzIGVuICUiKSArIHRoZW1lKGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwgbGVnZW5kLmRpcmVjdGlvbiA9ICJob3Jpem9udGFsIikgK2xhYnMoY29sb3VyID0gTlVMTCwgY2FwdGlvbiA9ICJGdWVudGU6IEVsYWJvcmFjacOzbiBwcm9waWEgY29uIGRhdG9zIGRlbCBCYW5jbyBNdW5kaWFsIikNCg0KYW1lcmljYV9sYXRpbmENCg0KYGBgDQoNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCjxicj4NCg0KIyMjIyA0LjQuMiBBbcOpcmljYSBkZWwgbm9ydGUgVlMgTXVuZG8gDQoNCmBgYHtyLCBlY2hvID0gVFJVRSwgd2FybmluZz0gRkFMU0V9DQoNCmFtZXJpY2Ffbm9ydGUgPC0gaW5mbGFjaW9uX2FncnVwICU+JSBmaWx0ZXIoc2VyaWVzID09ICJnZW5lcmFsIikgJT4lIA0KICBmaWx0ZXIoY291bnRyeV9uYW1lICVpbiUgYyAoIkFtw6lyaWNhIGRlbCBOb3J0ZSIsICJNdW5kbyIpKSAlPiUgZmlsdGVyKCBkYXRlID49IDE5NzEpDQoNCmFtZXJpY2Ffbm9ydGUgPC0gZ2dwbG90KCkgKw0KICBnZW9tX2xpbmUoZGF0YSA9IGFtZXJpY2Ffbm9ydGUsIGFlcyhkYXRlLCB2YWx1ZSwgY29sb3IgPSBjb3VudHJ5X25hbWUpLCBzaXplPTEpICsNCiAgc2NhbGVfY29sb3JfdmlyaWRpcyhkaXNjcmV0ZSA9IFRSVUUpICsNCiAgdGhlbWUoDQogICAgbGVnZW5kLnBvc2l0aW9uPSJub25lIiwNCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MTQpDQogICkgKw0KICBnZ3RpdGxlKCJJbmZsYWNpb24gbXVuZGlhbCIpICsNCiAgdGhlbWVfaXBzdW0oKSArIHRoZW1lKHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoZmFtaWx5ID0gInNlcmlmIiksDQogICAgICAgICAgICAgICAgICAgICAgICBwbG90LmNhcHRpb24gPSBlbGVtZW50X3RleHQoZmFtaWx5ID0gInNlcmlmIiksDQogICAgICAgICAgICAgICAgICAgICAgICBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KGZhbWlseSA9ICJzZXJpZiIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChmYW1pbHkgPSAic2VyaWYiKSkgK2xhYnModGl0bGUgPSAiR3JhZmljYSAzOiBBbWVyaWNhIGRlbCBOb3J0ZSB2cyBNdW5kbyIsIHN1YnRpdGxlID0gIihJbmZsYWNpw7NuIGdlbmVyYWwpIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHggPSBOVUxMLCB5ID0gIlZhbG9yZXMgZW4gJSIpICsgdGhlbWUobGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iLCBsZWdlbmQuZGlyZWN0aW9uID0gImhvcml6b250YWwiKSArbGFicyhjb2xvdXIgPSBOVUxMLCBjYXB0aW9uID0gIkZ1ZW50ZTogRWxhYm9yYWNpw7NuIHByb3BpYSBjb24gZGF0b3MgZGVsIEJhbmNvIE11bmRpYWwiKQ0KDQphbWVyaWNhX25vcnRlDQoNCmBgYA0KDQoNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCjxicj4NCg0KIyMjIyA0LjQuMyBVbmnDs24gRXVyb3BlYSBWUyBNdW5kbyANCg0KYGBge3IsIGVjaG8gPSBUUlVFLCB3YXJuaW5nPSBGQUxTRX0NCg0KdW5pb25fZXVyb3BlYSA8LSBpbmZsYWNpb25fYWdydXAgJT4lIGZpbHRlcihzZXJpZXMgPT0gImdlbmVyYWwiKSAlPiUgDQogIGZpbHRlcihjb3VudHJ5X25hbWUgJWluJSBjKCJVbmnDs24gRXVyb3BlYSIsICJNdW5kbyIpKSAlPiUgZmlsdGVyKGRhdGUgPj0gMTk3MSkgDQoNCnVuaW9uX2V1cm9wZWEgPC0gZ2dwbG90KCkgKw0KICBnZW9tX2xpbmUoZGF0YSA9IHVuaW9uX2V1cm9wZWEsIGFlcyhkYXRlLCB2YWx1ZSwgY29sb3IgPSBjb3VudHJ5X25hbWUpLCBzaXplPTEpICsNCiAgc2NhbGVfY29sb3JfdmlyaWRpcyhkaXNjcmV0ZSA9IFRSVUUpICsNCiAgdGhlbWUoDQogICAgbGVnZW5kLnBvc2l0aW9uPSJub25lIiwNCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MTQpDQogICkgKw0KICBnZ3RpdGxlKCJJbmZsYWNpb24gbXVuZGlhbCIpICsNCiAgdGhlbWVfaXBzdW0oKSArIHRoZW1lKHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoZmFtaWx5ID0gInNlcmlmIiksDQogICAgICAgICAgICAgICAgICAgICAgICBwbG90LmNhcHRpb24gPSBlbGVtZW50X3RleHQoZmFtaWx5ID0gInNlcmlmIiksDQogICAgICAgICAgICAgICAgICAgICAgICBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KGZhbWlseSA9ICJzZXJpZiIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChmYW1pbHkgPSAic2VyaWYiKSkgK2xhYnModGl0bGUgPSAiR3JhZmljYSAzOiBVbmlvbiBFdXJvcGVhIHZzIE11bmRvIiwgc3VidGl0bGUgPSAiKEluZmxhY2nDs24gZ2VuZXJhbCkiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeCA9IE5VTEwsIHkgPSAiVmFsb3JlcyBlbiAlIikgKyB0aGVtZShsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIsIGxlZ2VuZC5kaXJlY3Rpb24gPSAiaG9yaXpvbnRhbCIpICtsYWJzKGNvbG91ciA9IE5VTEwsIGNhcHRpb24gPSAiRnVlbnRlOiBFbGFib3JhY2nDs24gcHJvcGlhIGNvbiBkYXRvcyBkZWwgQmFuY28gTXVuZGlhbCIpDQoNCnVuaW9uX2V1cm9wZWENCg0KYGBgDQoNCg0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KPGJyPg0KDQojIyMjIDQuNC40IMOBZnJpY2EgVlMgTXVuZG8gDQoNCmBgYHtyLCBlY2hvID0gVFJVRSwgd2FybmluZz0gRkFMU0V9DQoNCmFmcmljYV9zYWhhcmEgPC0gaW5mbGFjaW9uX2FncnVwICU+JSBmaWx0ZXIoc2VyaWVzID09ICJnZW5lcmFsIikgJT4lIA0KICBmaWx0ZXIoY291bnRyeV9uYW1lICVpbiUgYygiw4FmcmljYSBhbCBzdXIgZGVsIFNhaGFyYSIsICJNdW5kbyIpKSAlPiUgZmlsdGVyKCBkYXRlID49IDE5NzEpDQoNCmFmcmljYV9zYWhhcmEgPC0gZ2dwbG90KGFmcmljYV9zYWhhcmEsIGFlcyhkYXRlLCB2YWx1ZSwgY29sb3I9Y291bnRyeV9uYW1lKSkgKw0KICBnZW9tX2xpbmUoc2l6ZT0xKSArDQogIHNjYWxlX2NvbG9yX3ZpcmlkaXMoZGlzY3JldGUgPSBUUlVFKSArDQogIHRoZW1lKA0KICAgIGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIsDQogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTE0KQ0KICApICsNCiAgZ2d0aXRsZSgiSW5mbGFjaW9uIG11bmRpYWwiKSArDQogIHRoZW1lX2lwc3VtKCkgKyB0aGVtZShwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KGZhbWlseSA9ICJzZXJpZiIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgcGxvdC5jYXB0aW9uID0gZWxlbWVudF90ZXh0KGZhbWlseSA9ICJzZXJpZiIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChmYW1pbHkgPSAic2VyaWYiKSwNCiAgICAgICAgICAgICAgICAgICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoZmFtaWx5ID0gInNlcmlmIikpICtsYWJzKHRpdGxlID0gIkdyYWZpY2EgMzogQWZyaWNhIFN1YnNhaGFyaWFuYSB2cyBNdW5kbyIsIHN1YnRpdGxlID0gIihJbmZsYWNpw7NuIGdlbmVyYWwpIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHggPSBOVUxMLCB5ID0gIlZhbG9yZXMgZW4gJSIpICsgdGhlbWUobGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIsIGxlZ2VuZC5kaXJlY3Rpb24gPSAiaG9yaXpvbnRhbCIpICtsYWJzKGNvbG91ciA9IE5VTEwsIGNhcHRpb24gPSAiRnVlbnRlOiBFbGFib3JhY2nDs24gcHJvcGlhIGNvbiBkYXRvcyBkZWwgQmFuY28gTXVuZGlhbCIpDQoNCmFmcmljYV9zYWhhcmENCg0KYGBgDQoNCg0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KPGJyPg0KDQojIyMjIDQuNC41IMOBc2lhIFZTIE11bmRvIA0KDQpgYGB7ciwgZWNobyA9IFRSVUUsIHdhcm5pbmc9IEZBTFNFfQ0KDQphc2lhX3BhY2lmaWNvIDwtIGluZmxhY2lvbl9hZ3J1cCAlPiUgZmlsdGVyKHNlcmllcyA9PSAiZ2VuZXJhbCIpICU+JSANCiAgZmlsdGVyKGNvdW50cnlfbmFtZSAlaW4lIGMoIkFzaWEgb3JpZW50YWwgeSBlbCBQYWPDrWZpY28iLCAiTXVuZG8iKSkgJT4lIGZpbHRlciggZGF0ZSA+PSAxOTcxKQ0KDQphc2lhX3BhY2lmaWNvIDwtIGdncGxvdChhc2lhX3BhY2lmaWNvLCBhZXMoZGF0ZSwgdmFsdWUsIGNvbG9yPWNvdW50cnlfbmFtZSkpICsNCiAgZ2VvbV9saW5lKHNpemU9MSkgKw0KICBzY2FsZV9jb2xvcl92aXJpZGlzKGRpc2NyZXRlID0gVFJVRSkgKw0KICB0aGVtZSgNCiAgICBsZWdlbmQucG9zaXRpb249Im5vbmUiLA0KICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0xNCkNCiAgKSArDQogIGdndGl0bGUoIkluZmxhY2lvbiBtdW5kaWFsIikgKw0KICB0aGVtZV9pcHN1bSgpICsgdGhlbWUocGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChmYW1pbHkgPSAic2VyaWYiKSwNCiAgICAgICAgICAgICAgICAgICAgICAgIHBsb3QuY2FwdGlvbiA9IGVsZW1lbnRfdGV4dChmYW1pbHkgPSAic2VyaWYiKSwNCiAgICAgICAgICAgICAgICAgICAgICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoZmFtaWx5ID0gInNlcmlmIiksDQogICAgICAgICAgICAgICAgICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGZhbWlseSA9ICJzZXJpZiIpKSArbGFicyh0aXRsZSA9ICJHcmFmaWNhIDM6QXNpYSB5IGVsIFBhY2lmaWNvIHZzIE11bmRvIiwgc3VidGl0bGUgPSAiKEluZmxhY2nDs24gZ2VuZXJhbCkiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeCA9IE5VTEwsIHkgPSAiVmFsb3JlcyBlbiAlIikgKyB0aGVtZShsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwgbGVnZW5kLmRpcmVjdGlvbiA9ICJob3Jpem9udGFsIikgK2xhYnMoY29sb3VyID0gTlVMTCwgY2FwdGlvbiA9ICJGdWVudGU6IEVsYWJvcmFjacOzbiBwcm9waWEgY29uIGRhdG9zIGRlbCBCYW5jbyBNdW5kaWFsIikNCg0KYXNpYV9wYWNpZmljbw0KDQpgYGANCg0KDQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQo8YnI+DQoNCiMjIyA0LjUgT3V0bGllcnMgMjAyMA0KDQpMYXMgZXhjZXBjaW9uZXMgYW50ZXJpb3JtZW50ZSBtZW5jaW9uYWRhcywgdmFsb3JlcyBxdWUgcHVlZGVuIHNlciBjb25zaWRlcmFkb3MgY29tbyAqIm91dGxpZXJzIiosIGVuIG51ZXN0cm8gZXN0dWRpby4gTm8gdGllbmUgbmluZ3VuIHNlbnRpZG8gZXN0dWRpYXIgZWwgcHJvYmxlbWEgaW5mbGFjaW9uaXN0YSBhY3R1YWwgZW4gZWNvbm9taWFzIHF1ZSBoaXN0w7NyaWNhbWVudGUgcHJlc2VudGFuIGRpc3RvcnNpb25lcyBlc3RydWN0dXJhbGVzIGVuIGxhIHZhcmlhYmxlIGVzdHVkaW8uDQoNCmBgYHtyIGVjaG89VFJVRSwgd2FybmluZz1GQUxTRX0NCg0KbGlicmFyeShwYXRjaHdvcmspDQoNCmluZmxhY2lvbl9jb3VudHJ5XzIgPC0gaW5mbGFjaW9uX2NvdW50cnkgJT4lIG11dGF0ZShhbnlvID1sdWJyaWRhdGU6OnllYXIoZGF0ZSkpDQoNCmluZmxhY2lvbl9jb3VudHJ5X3RvcCA8LSBpbmZsYWNpb25fY291bnRyeV8yICU+JQ0KICBmaWx0ZXIoYFNlcmllcyBOYW1lYCA9PSAiZ2VuZXJhbCIpICU+JQ0KICBmaWx0ZXIoYW55byA9PSAyMDIwKSAlPiUNCiAgbXV0YXRlKHZhbG9yID0gcm91bmQodmFsdWUsIGRpZ2l0cyA9IDIpKSAlPiUNCiAgbXV0YXRlKHNpbWJvbG8gPSAiKyIpICU+JQ0KICBtdXRhdGUoc2ltYm9sbzIgPSAiJSIpICU+JQ0KICBzbGljZV9tYXgodmFsdWUsIG49NSkNCg0KZGVmbGFjaW9uX2NvdW50cnlfbWluIDwtIGluZmxhY2lvbl9jb3VudHJ5XzIgJT4lIGZpbHRlcihgU2VyaWVzIE5hbWVgID09ICJnZW5lcmFsIikgJT4lDQogIGZpbHRlciggYW55byA9PSAyMDIwKSAlPiUgDQogIG11dGF0ZSh2YWxvciA9IHJvdW5kKHZhbHVlLCBkaWdpdHMgPSAyKSkgJT4lDQogIHNsaWNlX21pbih2YWx1ZSwgbiA9IDUpDQoNCiAgDQogIA0KcDIgPC0gZ2dwbG90KCBpbmZsYWNpb25fY291bnRyeV90b3AsIGFlcyggcmVvcmRlcihjb3VudHJ5X25hbWUsIHZhbHVlKSwgdmFsdWUsIGZpbGwgPSBjb3VudHJ5X25hbWUsIGNvdW50cnk9Y29kZSwgd2lkdGggPSAwLjUgKSkrDQogIGdlb21fYmFyKCBzdGF0ID0gImlkZW50aXR5IikgKw0KICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlNwZWN0cmFsIikgKw0KICBnZW9tX2ZsYWcoIHk9IC0xOCwgc2l6ZT0xNSApICsNCiAgY29vcmRfZmxpcCgpICsNCiAgZ2VvbV90ZXh0KCBhZXMobGFiZWw9IHNpbWJvbG8pLA0KICAgICAgICAgICAgIGhqdXN0ID0gLTAuNCwgc2l6ZSA9IDUsDQogICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDEpLA0KICAgICAgICAgICAgIGluaGVyaXQuYWVzID0gVFJVRSkgKw0KICBnZW9tX3RleHQoIGFlcyhsYWJlbCA9IHZhbG9yKSwNCiAgICAgICAgICAgICBoanVzdCA9IC0wLjQsIHNpemUgPSA1LA0KICAgICAgICAgICAgIGluaGVyaXQuID0gVFJVRSkgKw0KICB0aGVtZShhc3BlY3QucmF0aW8gPSAwLjUpICsNCiAgbGltcyh5PSBjKE5BLDcwMCkpICArIHRoZW1lKGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTEsDQogICAgZmFjZSA9ICJib2xkIiksIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAwLA0KICAgIGNvbG91ciA9ICJ3aGl0ZSIpKSArbGFicyh4ID0gIlZhbG9yZXMgZXhwcmVzYWRvIGVuICUiLCB5ID0gTlVMTCkgKyB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSBOQSkpICsgdGhlbWUocGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQpLA0KICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHZqdXN0ID0gMCksDQogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsDQogICAgICAgIGZhY2UgPSAiYm9sZCIpKSArbGFicyh0aXRsZSA9ICJEaWZlcmVuY2lhcyBlbnRyZSBsb3MgZXh0cmVtb3MiLA0KICAgIHN1YnRpdGxlID0gIlBhaXNlcyBjb24gbWF5b3IgaW5mbGFjacOzbiB5IGRlZmxhY2nDs24gZ2VuZXJhbCBlbiAyMDIwIikgKyANCiAgdGhlbWUoYXhpcy5saW5lID0gZWxlbWVudF9saW5lKGNvbG91ciA9IE5BKSwNCiAgICBheGlzLnRpY2tzID0gZWxlbWVudF9saW5lKGNvbG91ciA9IE5BKSkgICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQ0KDQoNCnAzIDwtIGdncGxvdChkZWZsYWNpb25fY291bnRyeV9taW4sIGFlcyhyZW9yZGVyKGNvdW50cnlfbmFtZSwgdmFsdWUpLCB2YWx1ZSwgZmlsbCA9IGNvdW50cnlfbmFtZSwgY291bnRyeT1jb2RlKSkrDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiKSArDQogIGdlb21fZmxhZyh5ID0gMiwgc2l6ZSA9IDE1KSArDQogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiR3JlZW5zIikgKw0KICBnZW9tX3RleHQoIGFlcyhsYWJlbCA9IHZhbG9yKSwNCiAgICAgICAgICAgICB2anVzdCA9IDEuMiwgc2l6ZSA9IDUsDQogICAgICAgICAgICAgaW5oZXJpdC4gPSBUUlVFKSArDQogIGdlb21fdGV4dCggYWVzKGxhYmVsID0gY291bnRyeV9uYW1lKSwNCiAgICAgICAgICAgICB2anVzdCA9IC0yLCBzaXplID0gNSwNCiAgICAgICAgICAgICBpbmhlcml0LiA9IFRSVUUpICsNCiAgbGltcyh5PSBjKC0zMSw0KSkgKyANCiAgdGhlbWUocGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQsDQogICAgZmFjZSA9ICJib2xkIiksIGF4aXMubGluZSA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSBOQSksDQogICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSBOQSksDQogICAgYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KGNvbG91ciA9IE5BKSwNCiAgICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSBOQSksDQogICAgcGxvdC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGNvbG91ciA9IE5BKSkgK2xhYnMoIHg9IE5VTEwsIHkgPSBOVUxMLCAgY2FwdGlvbiA9ICJGdWVudGU6IEVsYWJvcmFjacOzbiBwcm9waWEgY29uIGRhdG9zIGRlbCBCYW5jbyBNdW5kaWFsLiIpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQ0KICANCg0KDQoNCnAyICsgaW5zZXRfZWxlbWVudChwMywgbGVmdCA9IDAuMywgcmlnaHQgPSAxLCBib3R0b20gPSAtMC4yLCB0b3AgPSAwLjgpDQoNCmBgYA0KDQoNCkVuIHJlc3VtZW4geSAqbGEgY29uc2x1c2nDs24gcXVlIHF1ZXJlbW9zIHJlbWFyY2FyIGFudGVzIGRlIGVudHJhciBlbiBtYXRlcmlhKiwgZXMgcXVlICoqZW4gbG9zIMO6bHRpbW9zIDMwIGHDsW9zIHNlIGhhIGFjZWxlcmFkbyBlbCBwcm9jZXNvIGRlIGVzcGVjaWFsaXphY2nDs24gcHJvZHVjdGl2YSoqICgqc2kgbm8gdGVuZW1vcyBlbiBjdWVudGEgbGFzIGV4Y2VwY2lvbmVzKiksIHJlZHVjaWVuZG8gbG9zIGNvc3RlcyBkZSBwcm9kdWNjacOzbiB5IGZvbWVudGFuZG8gZWwgYXZhbmNlIHRlY25vbMOzZ2ljby4gVG9kbyBlc3RvIHNlIHRyYWR1Y2UgZW4gdW5hIHJlZHVjY2nDs24gZGUgbG9zIHByZWNpb3MgZGUgbG9zIGJpZW5lcyB5IHNlcnZpY2lvcyBxdWUgc2UgY29tZXJjaWFuIGEgbml2ZWwgaW50ZXJuYWNpb25hbCwgbWVqb3JhbmRvIGxhIGNhbGlkYWQgZGUgdmlkYSBkZSBsb3MgYWdlbnRlcyBlY29uw7NtaWNvcy4NCg0KPGJyPg0KDQojIyA1LiBJbmZsYWNpw7NuIGVuIGxhIGFjdHVhbGlkYWQgDQoNCkVsIGZlbsOzbWVubyBhbnRlcmlvcm1lbnRlIGRlc2NyaXRvIChyZWR1Y2Npw7NuIG11bmRpYWwgZGUgbG9zIGRhdG9zIGRlIGluZmxhY2nDs24pIHRhbWJpw6luIHNlIGhhIGhlY2hvIHZpc2libGUgZW4gZWwgdmllam8gY29udGluZW50ZS4gRW4gbG9zIMO6bHRpbW9zIGHDsW9zLCBjYXNpIHRvZGEgZXVyb3pvbmEsIHNlIGhhYsOtYSBhY29zdHVtYnJhZG8gYSBxdWUgbG9zIHByZWNpb3MgYWx0b3MgZGVqYXLDoW4gZGUgc2VyIHVuIGRvbG9yIGRlIGNhYmV6YS4gIE3DoXMgYcO6biwgY3VhbmRvLCBhIGRpZmVyZW5jaWEgZGUgb3RyYXMgZWNvbm9tw61hcyBjb21vIGJpZW4gcHVlZGUgc2VyIGxhIGVzdGFkb3VuaWRlbnNlLCAgZWwgQkNFIHNlIGhhIGNvbXByb21ldGlkbywgY2FzaSBkZXNkZSBzdSBjcmVhY2nDs24sIGEgZmlqYXIgc3UgcG9sw610aWNhIG1vbmV0YXJpYSBwYXJhIGFzZWd1cmFyIHF1ZSBsYSBpbmZsYWNpw7NuIHNlIGVzdGFiaWxpY2UgZW4gc3Ugb2JqZXRpdm8gZGVsIDIgJSBhIG1lZGlvIHBsYXpvLg0KDQo8YnI+DQoNCiMjIyA1LjEuIENhbWJpbyBkZSB0ZW5kZW5jaWENCg0KRGVzZGUgZmluYWxlcyBkZSB2ZXJhbm8gZGUgMjAyMSwgZXN0YSB0ZW5kZW5jaWEgZGUgZXN0YWJpbGlkYWQgcmVsYXRpdmEgZGUgcHJlY2lvcyBzZSBoYSBxdWVicmFkby4NCg0KYGBge3IsIGVjaG8gPSBUUlVFLCB3YXJuaW5nPSBGQUxTRX0NCg0KDQptYXBhXzIgPC0gZ2dwbG90KCkgKw0KICBnZW9tX3NmKGRhdGEgPSBpbmZsYWNpb25fZ2VvbV9ldXJvcCwgYWVzKGdlb21ldHJ5ID0gZ2VvbWV0cnksIGZpbGwgPSB2YWx1ZSApKSArDQogIHRoZW1lX3ZvaWQoKSAgKw0KICB0aGVtZShwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KGZhbWlseSA9ICJzZXJpZiIsIGZhY2UgPSAiaXRhbGljIiksDQogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoZmFtaWx5ID0gInNlcmlmIiwgZmFjZSA9ICAiaXRhbGljIikpICsNCiAgbGFicyh0aXRsZSA9ICJNYXBhOkluZmxhY2nDs24gbXVuZGlhbCIsIGZpbGwgPSAiSW5mbGFjacOzbiIpICArDQogIHNjYWxlX2ZpbGxfY29udGludW91cyhsb3c9IiNmZmZjYmYiLGhpZ2g9IiNkNzM3MmEiKSArDQogIGxpbXMoeSA9YygzNSw3MCkpICsNCiAgbGltcyh4ID0gYygtMjAsIDQwKSkgKyB0cmFuc2l0aW9uX21hbnVhbChkYXRlKSArDQogIGxhYnModGl0bGUgPSAiQcOxbzoge2N1cnJlbnRfZnJhbWV9IiwNCiAgICAgICBjYXB0aW9uID0gIkRhdG9zIGRlIEV1cm9zdGF0IikNCg0KZ2dhbmltYXRlOjphbmltYXRlKG1hcGFfMiwgbmZyYW1lcyA9IDIwMCwgZnBzID0gMjAsIGVuZF9wYXVzZSA9IDYpDQpgYGANCg0KPGJyPg0KDQoNCiMjIyA1LjIuIENvbXBvbmVudGVzL2NhdXNhcyBkZSBsYSBpbmZsYWNpw7NuDQoNCg0KRWwgZW5jYXJlY2ltaWVudG8gZGUgbGEgZW5lcmfDrWEsIGxvcyBjdWVsbG9zIGRlIGJvdGVsbGEgZGUgbGFzIGNhZGVuYXMgZGUgcHJvZHVjY2nDs24geSBsYSBlc3RyYXTDqWdpYSBlbiBwb2zDrXRpY2EgbW9uZXRhcmlhIGFkb3B0YWRhIHBhcmEgbHVjaGFyIGNvbnRyYSBsYSBjb3ZpZCAoaW5jcmVtZW50byBkZWwgZmx1am8gbW9uZXRhcmlvIGVuIGxhIGVjb25vbcOtYSkgaGFuIGRlc3BlcnRhZG8gYSBsYSBpbmZsYWNpw7NuIGVuIGxhIG1heW9yw61hIGRlIGxhcyBlY29ub23DrWFzLg0KDQpTaSBub3MgY2VudHJhbW9zIGVuIGVsIGNvbnRleHRvIGV1cm9wZW8sIGxhICoqcHJpbmNpcGFsIGNhdXNhIGRlIGluZmxhY2nDs24qKiBlcyBjbGFyYSAoKmdyw6FmaWNvIGFwb3J0YWNpw7NuIGNvbXBvbmVudGVzIGEgbGEgaW5mbGFjacOzbiopLCBsb3MgKipwcmVjaW9zIGRlIGxhIGVuZXJnw61hKiogaGFuIGV4cGVyaW1lbnRhZG8gdW4gcmVwdW50ZSBleHBvbmVuY2lhbCBlbiBsb3MgZG9zIMO6bHRpbW9zIHRyaW1lc3RyZXMuIA0KDQpFc3RvcyBhbHRvcyBwcmVjaW9zIGVuZXJnw6l0aWNvcyBkZWJlbiBhIHNlIGRlYmVuIGEgdmFyaW9zIGZhY3RvcmVzOg0KDQotIExhIGZ1ZXJ0ZSByZXZhbG9yaXphY2nDs24gZGVsIGdhcyBuYXR1cmFsIGVuIGxvcyBtZXJjYWRvcy4NCi0gU3ViaWRhIGRlIGxvcyBkZXJlY2hvcyBkZWwgQ28yLkVzdG9zIGRlcmVjaG9zIGhhbiBzdWJpZG8gZW4gbcOhcyBkZSB1biAxMDAgJSBlbiB0YW4gc29sbyBzZWlzIG1lc2VzLCBhbGdvIHF1ZSBhZmVjdGEgZW4gbG9zIHByZWNpb3MgZWzDqWN0cmljb3MgZGlhcmlvcyBlbiBFdXJvcGEuDQotIExhIGVzY2FzZXogZGUgb2ZlcnRhIHkgZWwgYWx0byBwcmVjaW8gZGVsIGdhcyBuYXR1cmFsIHkgY2FyYsOzbiBlc3TDoSBjYXVzYW5kbyB1biBkZXN2w61vIG1hc2l2byBoYWNpYSBlbCBwZXRyw7NsZW8geSBzdXMgZGVyaXZhZG9zIHBhcmEgbGEgZ2VuZXJhY2nDs24gZGUgZWxlY3RyaWNpZGFkIHkgdXNvcyBpbmR1c3RyaWFsZXMsIHNlZ8O6biBlbCAgaW5mb3JtZSBzb2JyZSBlbCBtZXJjYWRvIGRlbCBwZXRyw7NsZW8gcXVlIGVsYWJvcmEgbGEgQWdlbmNpYSBJbnRlcm5hY2lvbmFsIGRlIGxhIEVuZXJnw61hIChBSUUpLg0KLSBMYSBmYWx0YSBkZSBjaGlwcyBzZW1pY29uZHVjdG9yZXMgKGNpcmN1aXRvcyBpbnRlZ3JhZG9zKSBzb24gbXVjaG9zIHkgbGEgc29sdWNpw7NuIG5vIHZhIGEgbGxlZ2FyIHLDoXBpZG8uDQoNCg0KYGBge3IsIGVjaG8gPSBUUlVFLCB3YXJuaW5nPSBGQUxTRX0NCg0KY29udHJpYnVjaW9uIDwtIGNvbnRyaWJ1Y2lvbiAgJT4lDQogIGZpbHRlcihkYXRlID09ICIyMDIxLTEwLTAxIikgJT4lDQogIHNsaWNlX21heCAodmFsdWUgLCBuID0gMjApDQoNCg0KDQpjb21wb25lbnRlc19ldXJvcGEgPC0gdHJlZW1hcChjb250cmlidWNpb24sDQogICAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4PSJjb21wb25lbnRlIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgdlNpemU9InZhbHVlIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZT0iaW5kZXgiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICB0aXRsZT0iQXBvcnRhY2nDs24gY29tcG9uZW50ZXMgYSBsYSBpbmZsYWNpw7NuIGludGVyYW51YWwgZGUgT2N0dWJyZSAyMDIxIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgcGFsZXR0ZT0iU3BlY3RyYWwiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICBib3JkZXIuY29sPWMoIndoaXRlIiksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICBib3JkZXIubHdkcz0zLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgZm9udGZhY2UubGFiZWxzPTEsDQogICAgICAgICAgICAgICAgICAgICAgICAgIGJnLmxhYmVscz1jKCJ0cmFuc3BhcmVudCIpLCAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICAgICAgICAgIGFsaWduLmxhYmVscz1jKCJjZW50ZXIiLCAiY2VudGVyIiksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgICAgICAgICAgICBvdmVybGFwLmxhYmVscz0wLjUpDQoNCg0KDQpgYGANCg0KPGJyPg0KDQojIyMgNS4zLiBJbmZsYWNpw7NuICJlbiBlbCBwZW9yIG1vbWVudG8iDQoNCkxhICoqdmFyaWFjacOzbiBpbnRlcmFudWFsKiogZGVsIMOtbmRpY2UgZGUgcHJlY2lvcyBkZSBjb25zdW1vIGFybW9uaXphZG8gKElQQ0EpIHBhcmEgbGEgZXVyb3pvbmEgZnVlIGRlbCA0LDQlIGVuIG9jdHVicmUsIGVuIGVsIG1vbWVudG8gZGUgc3UgcHVibGljYWNpw7NuLCBmdWUgbGEgY2lmcmEgbcOhcyBhbHRhIGVuIGxhIHNlcmllIGhpc3TDs3JpY2EgZGUgbGEgb2ZpY2luYSBldXJvcGVhIGRlIGVzdGFkw61zdGljYXMsIHF1ZSBhcnJhbmNhIGVuIDE5OTcuIEVzdGUgaW5zw7NsaXRvIHLDqWNvcmQgaGEgc2lkbyBiYXRpZG8gc29sbyB1biBtZXMgZGVzcHXDqXMsIGNvbiB1biBudWV2byBtw6F4aW1vIGhpc3TDs3JpY28gZW4gZWwgZGF0byBkZSB2YXJpYWNpw7NuIGludGVyYW51YWwgZGUgcHJlY2lvcyBkZSBjb25zdW1vIGFybW9uaXphZG8gKElQQ0EpIHNpdHXDoW5kb3NlIGVuIGVsIDQsOSAlLCAwLDggcC4gcC4gc3VwZXJpb3IgYWwgZGVsIG1lcyBhbnRlcmlvci4NCg0KVW4gYXB1bnRlIGEgZGVzdGFjYXIsIHBhcmEgcXVlIGVsIGxlY3RvciBwdWVkYSBmb3JtYXJzZSB1bmEgbWVqb3Igb3BpbmnDs24gYWwgcmVzcGVjdG8sIGVzIHF1ZSAqZXN0b3MgZGF0b3Mgc8OzbG8gcmVwcmVzZW50YW4gdW5hIG1lZGlhKiwgZXMgZGVjaXIsICpjb21vIHBvZHLDoSBvYnNlcnZhciBtZWRpYW50ZSBsYSB0YWJsYSBhZGp1bnRhIGVuIGVsIHB1bnRvIDUuNCBjb24gbG9zIGRhdG9zIGRlIGluZmxhY2nDs24qLCB0ZW5kcmVtb3MgZWNvbm9tw61hcyBwb3IgZW5jaW1hIGRlbCA0LDQlIHkgZWNvbm9tw61hcyBwb3IgZGViYWpvLiBBbGVtYW5pYSwgcG9yIGVqZW1wbG8sIGVjb25vbcOtYSBzaWVtcHJlIHNlbnNpYmxlIGEgbG9zIG1vdmltaWVudG9zIGRlIGxvcyBwcmVjaW9zLCBsbGVnYSBhIHRlbmVyIGRhdG9zIGRlIElQQyBhbnVhbCBkZWwgNCw2JSBwYXJhIG9jdHVicmUuICoqRXNwYcOxYSoqIHNlIHF1ZWRhIGVuIGVsICoqNSw0JSoqLiAgVW4gc29sbyBtZXMgaGEgYmFzdGFkbyBwYXJhIHF1ZSBFdXJvc3RhdCBwcmVzZW50ZSAqKm51ZXZvcyByw6ljb3JkcyoqIGVuIGxvcyBkYXRvcyBkZSBpbmZsYWNpw7NuLiBBbGVtYW5pYSBpbmNyZW1lbnRhIHN1IMO6bHRpbW8gZGF0byBlbiAxLDQgcHVudG9zIHBhcmEgbGxlZ2FyIHN1IElQQyBhbnVhbCBhbCA2JS4gQsOpbGdpY2Egc2Ugc2l0w7phIGVuIGFsZ28gbcOhcyBkZWwgNyUsIHkgbGUgc3VwZXJhbiBsb3MgdHJlcyBwYcOtc2VzIGLDoWx0aWNvcyAoTGl0dWFuaWEsIExldG9uaWEgeSBFc3RvbmlhKS4gKipFc3Bhw7FhKiosIHBvciBzdSBwYXJ0ZSwgc2UgcXVlZGEgZW4gZWwgKio1LDYlKiouIExvcyDDum5pY29zIHBhw61zZXMgZGUgbGEgem9uYSBldXJvIGVuIGxvcyBxdWUgcG9kcsOtYSBoYWJsYXJzZSBkZSB1bmEgaW5mbGFjacOzbiBjb250ZW5pZGEgc29uIEZyYW5jaWEgKDMsNCUpIHkgUG9ydHVnYWwgKDIsNyUpOiBEZSB0b2RvcyBtb2RvcywgbGEgZ3JhbiBtYXlvcsOtYSBkZSBlY29ub23DrWFzIGRlbCB2aWVqbyBjb250aW5lbnRlIHN1cGVyYXJvbiBlbCBvYmpldGl2byBlc3RhYmxlY2lkbyBlbiBlbCAyJSwgYW50ZXJpb3JtZW50ZSBtZW5jaW9uYWRvLg0KDQpgYGB7ciBlY2hvPVRSVUUsIHdhcm5pbmc9RkFMU0V9DQoNCmluZmxhY2lvbl9ldXJvem9uYSA8LSBpbmZsYWNpb25fZXVyb3pvbmEgJT4lIGZpbHRlciggVElNRSA9PSAiRXVyb3BlYW4gVW5pb24gLSAyNyBjb3VudHJpZXMgKGZyb20gMjAyMCkiKQ0KDQppbmZsYWNpb25fZXVyb3pvbmFfc3ViIDwtIGluZmxhY2lvbl9ldXJvem9uYSAlPiUgZmlsdGVyKFRpcG8gPT0gInN1YnlhY2VudGUiKQ0KaW5mbGFjaW9uX2V1cm96b25hX2dlbiA8LSBpbmZsYWNpb25fZXVyb3pvbmEgJT4lIGZpbHRlcihUaXBvID09ICJnZW5lcmFsIikNCg0KZXVyb3BhIDwtIGdncGxvdCgpICsNCiAgDQogIGdlb21fY29sKGRhdGEgPSBpbmZsYWNpb25fZXVyb3pvbmFfc3ViLCBhZXMoZGF0ZSwgdmFsdWUsIGZpbGwgPSB2YWx1ZSksIGNvbG9yPSAiZ3JleSIsICBhbHBoYSA9IDAuNSkgKw0KICBzY2FsZV9maWxsX2NvbnRpbnVvdXMobG93PSIjZmZmZmJmIixoaWdoPSIjZmVlMDhiIikgICsNCiAgZ2VvbV90ZXh0KGRhdGEgPSBpbmZsYWNpb25fZXVyb3pvbmFfc3ViLCBhZXMoZGF0ZSwgdmFsdWUsIGxhYmVsID0gdmFsdWUpLCB5PS0wLjIgKSArDQogIGdlb21fdGV4dChkYXRhID0gaW5mbGFjaW9uX2V1cm96b25hX3N1YiwgYWVzKGRhdGUsIHZhbHVlLCBsYWJlbCA9ICIlIiksIHk9LTAuMiwgaGp1c3QgPSAtMSApICsNCiAgDQogIGdlb21fbGluZShkYXRhID0gaW5mbGFjaW9uX2V1cm96b25hX2dlbiwgYWVzKGRhdGUsIHZhbHVlLCBjb2xvciA9IHZhbHVlKSxzaXplID0gMS41KSArDQogIHNjYWxlX2NvbG9yX2NvbnRpbnVvdXMobG93PSIjMzI4OGJkIixoaWdoPSIjMzI4OGJkIikgKw0KICBnZW9tX3RleHQoZGF0YSA9IGluZmxhY2lvbl9ldXJvem9uYV9nZW4sIGFlcyhkYXRlLCB2YWx1ZSwgbGFiZWwgPSB2YWx1ZSksIHZqdXN0ID0gLTIsaGp1c3QgPSAxKSArDQogIGdlb21fdGV4dChkYXRhID0gaW5mbGFjaW9uX2V1cm96b25hX2dlbiwgYWVzKGRhdGUsIHZhbHVlLCBsYWJlbCA9ICIlIiksIHZqdXN0ID0gLTIsIGhqdXN0ID0gLTAuMikgKw0KICANCiAgZ2VvbV9wb2ludChkYXRhID0gaW5mbGFjaW9uX2V1cm96b25hX2dlbiwgYWVzKGRhdGUsIHZhbHVlKSwgc2l6ZSA9IDQsIGNvbG9yID0gIiMzMjg4YmQiKSArDQogIA0KICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAyLA0KICAgICAgICAgICAgIHNpemUgPSAxLjUsDQogICAgICAgICAgICAgY29sb3VyID0gIiNhYmRkYTQiLA0KICAgICAgICAgICAgIGxpbmV0eXBlID0gImRhc2hlZCIpICsNCiAgDQogIGFubm90YXRlKGdlb20gPSAidGV4dCIsDQogICAgICAgICAgIHg9IGFzLkRhdGUoIjIwMjAtMTEtMjEiKSwNCiAgICAgICAgICAgeSA9IDIuMiwNCiAgICAgICAgICAgbGFiZWwgPSAiT2JqZXRpdm8gaW5mbGFjaW9uIDIlIiwNCiAgICAgICAgICAgc2l6ZSA9IDQsDQogICAgICAgICAgIGNvbG9yID0gImJsYWNrIikgICsgDQogIA0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDcwLCBoanVzdCA9IDEpKSArDQogIA0KICBzY2FsZV94X2RhdGUoZGF0ZV9sYWJlbHM9IiViICV5IixkYXRlX2JyZWFrcyAgPSIxIG1vbnRoIikgKw0KICANCiAgbGltcyh5PSBjKC0wLjMsNSkpICsgDQogIA0KICB0aGVtZShwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGNvbG91ciA9ICJkYXJrZ3JheSIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgbGluZXR5cGUgPSAiZGFzaGVkIiksIA0KICAgICAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGNvbG91ciA9IE5BKSwNCiAgICAgICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gTkEpLA0KICAgICAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoY29sb3VyID0gTkEpLA0KICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICtsYWJzKHggPSBOVUxMLCB5ID0gIlZhbG9yZXMgZXhwcmVzYWRvcyBlbiAlIikgKyANCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSBOQSkpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwgbGVnZW5kLmRpcmVjdGlvbiA9ICJob3Jpem9udGFsIikgKw0KICBsYWJzKGZpbGwgPSAiU3VieWFjZW50ZSIpICsgDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9IGMoMC4yMCwgMC44KSkgKw0KICBsYWJzKGNvbG91ciA9ICJHZW5lcmFsIikgKyANCiAgdGhlbWUobGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoY29sb3VyID0gTkEpLA0KICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIpLA0KICAgICAgbGVnZW5kLmtleSA9IGVsZW1lbnRfcmVjdChmaWxsID0gTkEpLA0KICAgICAgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9IE5BKSkrbGFicyhjb2xvdXIgPSAiR2VuZXJhbCAgICAgICAiKSArIA0KICB0aGVtZShheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyLA0KICAgICAgZmFjZSA9ICJib2xkIiksIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMikpICsgDQogIHRoZW1lKGF4aXMubGluZSA9IGVsZW1lbnRfbGluZShsaW5ldHlwZSA9ICJzb2xpZCIpKSArIA0KICB0aGVtZShheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUobGluZXR5cGUgPSAiYmxhbmsiKSwNCiAgICAgIGF4aXMudGlja3MgPSBlbGVtZW50X2xpbmUoY29sb3VyID0gTkEsDQogICAgICBsaW5ldHlwZSA9ICJibGFuayIpLCBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCwNCiAgICAgIGZhY2UgPSAiYm9sZCIpLCBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChjb2xvdXIgPSAiYmxhY2siKSkgK2xhYnModGl0bGUgPSAiRXZvbHVjacOzbiBkZSBsYSBpbmZsYWNpw7NuIGVuIGxhIENvbXVuaWRhZCBFdXJvcGVhIiwNCiAgICAgIHN1YnRpdGxlID0gIkluY2xhY2nDs24gbWVuc3VhbCAiLCBjYXB0aW9uID0gIkZ1ZW50ZTogRWxhYm9yYWPDs24gcHJvcGlhIGNvbiBkYXRvcyBkZSBFdXJvc3RhdCIpICsgDQogIHRoZW1lKGF4aXMudGlja3MgPSBlbGVtZW50X2xpbmUobGluZXR5cGUgPSAic29saWQiKSwNCiAgICBheGlzLnRleHQgPSBlbGVtZW50X3RleHQoY29sb3VyID0gTkEpLA0KICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGNvbG91ciA9ICJibGFjayIpKSArbGFicyhzdWJ0aXRsZSA9ICJJbmNsYWNpw7NuIG1lbnN1YWwgKEV1cm9wYSBkZSBsb3MgMjcpIikgKw0KICBsYWJzKHkgPSBOVUxMKSAgDQoNCmV1cm9wYQ0KDQpgYGANCg0KRXN0ZSBwcm9ibGVtYSAqKm5vcyBsbGVnYSBlbiBlbCBwZW9yIG1vbWVudG8qKiBwb3NpYmxlIHBhcmEgdG9kYSBsYSBldXJvem9uYS4gQXVucXVlIHNpIGhheSBlY29ub23DrWFzIGNvbiB1bmEgYnVlbmEgZXN0cnVjdHVyYSBtYWNyb2Vjb27Ds21pY2EsIG90cmFzLCBjb21vIGVsIGNhc28gZGUgbGEgZXNwYcOxb2xhIG8gbGEgaXRhbGlhbmEgcHJlc2VudGFuIGNpZXJ0b3MgZGVzYWp1c3RlcyBxdWUgc29sbyBoYW4gaGVjaG8gbcOhcyBxdWUgZGUgYWdyYXZhcnNlIGRlc2RlIGxhIGxsZWdhZGEgZGUgbGEgQ292aWQtMTkuIENhYmUgcmVjb3JkYXIgcXVlIGVuIGxhIFVFLCBsYSBwb2zDrXRpY2EgbW9uZXRhcmlhIGVzdMOhIGNvbXBsZXRhbWVudGUgc3VwZWRpdGFkYSBwb3IgZWwgQkNFLCBwb3IgdGFudG8gbGFzIGRpZmVyZW50ZXMgbmFjaW9uZXMgbm8gZ296YW4gZGUgYXV0b25vbcOtYSBtb25ldGFyaWEuIExhIGNvbmNsdXNpw7NuIGVzIGNsYXJhLCBsYSBlY29ub23DrWEgZXN0w6Egc3VmcmllbmRvIHVuICoqc2hvY2sqKiBkZW50cm8gZGUgc3UgY2FtaW5vIGRlIHJlY3VwZXJhY2nDs24gZGVsIGFudGVyaW9yICoqc2hvY2sqKiAsIHVubyBwcm90YWdvbml6YWRvIHBvciBlbCBhbHphIGVuIHByZWNpb3MgeSBvdHJvIHBvciBsYSBwYXJhbGl6YWNpw7NuIGVjb27Ds21pY2EgY29tbyBjb25zZWN1ZW5jaWEgZGUgbGEgcGFuZGVtaWEsIHBvciB0YW50bywgZWwgcHJvYmxlbWEgb3JpZ2luYWwsIGNvbW8gYSBjb250aW51YWNpw7NuIGV4cG9uZHJlbW9zLCBzb2xvIGhhIGhlY2hvIHF1ZSBjb21wbGljYXIgbGEgaW5jaWVydGEgc2l0dWFjacOzbiBlbiBsYSBxdWUgZGVzZ3JhY2lhZGFtZW50ZSBlbiBsb3Mgw7psdGltb3MgYcOxb3Mgbm9zIGRlc2Vudm9sdmVtb3MuDQoNCg0KPGJyPg0KDQojIyMgNS40IFRhYmxhIA0KDQpgYGB7cn0NCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShEVCkNCg0KaW5mbGFjaW9uX2V1cm96b25hIDwtIHJlYWRfY3N2KCJkYXRvcy9pbmZsYWNpb25fZXVyb3pvbmEuY3N2IiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sX3R5cGVzID0gY29scyhkYXRlID0gY29sX2RhdGUoZm9ybWF0ID0gIiVZLyVtIikpKQ0KDQppbmZsYWNpb25fZXVyb3pvbmFfc3ViIDwtIGluZmxhY2lvbl9ldXJvem9uYSAlPiUgZmlsdGVyKFRpcG8gPT0gInN1YnlhY2VudGUiKSAlPiUgcmVuYW1lKGNvdW50cnkgPSBUSU1FKSANCmluZmxhY2lvbl9ldXJvem9uYV9nZW4gPC0gaW5mbGFjaW9uX2V1cm96b25hICU+JSBmaWx0ZXIoVGlwbyA9PSAiZ2VuZXJhbCIpICU+JSByZW5hbWUoY291bnRyeSA9IFRJTUUpIA0KdGFibGFfaW5mbGFjaW9uIDwtIGxlZnRfam9pbihpbmZsYWNpb25fZXVyb3pvbmFfZ2VuLCBpbmZsYWNpb25fZXVyb3pvbmFfc3ViLCBieSA9IGMoImRhdGUiID0gImRhdGUiLCAiY291bnRyeSIgPSAiY291bnRyeSIpKQ0KDQp0YWJsYV9pbmZsYWNpb24gPC0gdGFibGFfaW5mbGFjaW9uICU+JSANCiAgZHBseXI6OnNlbGVjdChjb3VudHJ5LCBkYXRlLCBUaXBvLngsIHZhbHVlLngsIFRpcG8ueSwgdmFsdWUueSkgJT4lIA0KICBkcGx5cjo6c2VsZWN0KC0oYyhUaXBvLnggLCBUaXBvLnkpKSkgJT4lIA0KICByZW5hbWUoZ2VuZXJhbCA9IHZhbHVlLngsIHN1YnlhY2VudGUgPSB2YWx1ZS55KSANCg0KZGF0YXRhYmxlKHRhYmxhX2luZmxhY2lvbiwgY2xhc3MgPSJzdHJpcGUgaG92ZXIgY29tcGFjdCByb3ctYm9yZGVyIiAsIGZpbHRlciA9ICd0b3AnKQ0KDQpgYGANCg0KPGJyPg0KDQojIyA2IEluZmxhY2nDs24gZW4gZWwgY29udGV4dG8gRXNwYcOxb2wuDQoNCj4gRWwgcHJlY2lvIGRlIGxhIGx1eiBkaXNwYXJhIGVsIElQQyBoYXN0YSBlbCA1LDYgJSwgc3UgdGFzYSBtw6FzIGFsdGEgZW4gMjkgYcOxb3MuDQoNCiMjIyA2LjEgR2VuZXJhbCB5IFN1YnlhY2VudGUsIGVsIGVmZWN0byBpbmZsYWNpb25pc3RhIHBhcmEgRXNwYcOxYS4gDQoNClNpIG5vcyBjZW50cmFtb3MgZW4gZWwgY29udGV4dG8gZXNwYcOxb2wsIGxhICoqc2l0dWFjacOzbioqLCBjb21vIHlhIGF2YW56YW1vcywgZXMgdGFtYmnDqW4gICoqY3LDrXRpY2EqKi4gRWwgw7psdGltbyBkYXRvIHB1YmxpY2FkbyBwb3IgZWwgSW5zdGl0dXRvIE5hY2lvbmFsIGRlIEVzdGFkw61zdGljYSAoSU5FKSwgbWFyY2EgdW4gbnVldm8gcGljbyBwYXJhIGxhIGluZmxhY2nDs24gZXN0ZSBhw7FvICg1LDYlKSwgKipzdSB0YXNhIG3DoXMgYWx0YSBlbiAyOSBhw7FvcyoqLiBOdWVzdHJhIGVjb25vbcOtYSBkb23DqXN0aWNhIHNlIGVuY3VlbnRyYSBlbiB1bmEgdGVuZGVuY2lhIGFsY2lzdGEgZGVzZGUgZWwgcGFzYWRvIG1hcnpvLiBMYSBpbXBsaWNhY2nDs24gZWNvbsOzbWljYSBlcyBjbGFyYTsgc2UgZXN0w6EgcHJvZHVjaWVuZG8gdW4gKiplbmNhcmVjaW1pZW50byBkZWwgY29zdGUgZGUgbGEgdmlkYSoqLiBMYXMgY2F1c2FzIHPDs24gbGFzIG1pc21hcyBxdWUgbGFzIGFudGVyaW9ybWVudGUgbWVuY2lvbmFkYXMgcGFyYSBlbCBjb250ZXh0byBldXJvcGVvIChhbHRvcyBwcmVjaW9zIGRlIGxhIGVsZWN0cmljaWRhZCB5IGxvcyBjb21idXN0aWJsZXMsIGVsIHJlcHVudGUgZGVsIGNvbnN1bW8geSBsb3MgcHJvYmxlbWFzIGVuIGxhcyBjYWRlbmFzIGRlIHN1bWluaXN0cm8gZ2xvYmFsZXMsIGZhbHRhIGRlIGNvbnRlbmVkb3JlcywgZXNjYXNleiBkZSB0cmFiYWphZG9yZXMsIGNhcmVuY2lhIGRlIGNoaXBz4oCmKS4NCg0KYGBge3IgZWNobz1UUlVFLCB3YXJuaW5nPUZBTFNFICwgcmVzdWx0cz0naGlkZSd9DQppbmZsYWNpb25fZXNwX2dlbiA8LSBpbmZsYWNpb25fZXNwICU+JSBmaWx0ZXIodGlwbyA9PSAiZ2VuZXJhbCIpDQppbmZsYWNpb25fZXNwX3N1YiA8LSBpbmZsYWNpb25fZXNwICU+JSBmaWx0ZXIodGlwbyA9PSAic3VieWFjZW50ZSIpDQoNCg0KZXNwIDwtIGdncGxvdCgpICsNCiAgDQogIGdlb21fbGluZShkYXRhID0gaW5mbGFjaW9uX2VzcF9nZW4sIGFlcyhkYXRlLCB2YWx1ZSwgY29sb3VyID0gdGlwbyksIHNpemUgPSAxLjUpICsNCiAgZ2VvbV9wb2ludChkYXRhID0gaW5mbGFjaW9uX2VzcF9nZW4sIGFlcyhkYXRlLCB2YWx1ZSwgIGNvbG91ciA9IHRpcG8sIHNoYXBlID0gdGlwbyksIHNpemUgPSAzKSArDQogIGdlb21fdGV4dChkYXRhID0gaW5mbGFjaW9uX2VzcF9nZW4sIGFlcyhkYXRlLCB2YWx1ZSwgbGFiZWwgPSB2YWx1ZSwgY29sb3VyID0gdGlwbyksIHZqdXN0ID0gMi41LGhqdXN0ID0gMC41LCBzaXplID0gMykgKw0KICBnZW9tX3RleHQoZGF0YSA9IGluZmxhY2lvbl9lc3BfZ2VuLCBhZXMoZGF0ZSwgdmFsdWUsIGxhYmVsID0gIiUiLCBjb2xvdXIgPSB0aXBvKSwgdmp1c3QgPSAyLjUsaGp1c3QgPSAtMSwgc2l6ZSA9IDMpICsNCiAgDQogIGdlb21fbGluZShkYXRhID0gaW5mbGFjaW9uX2VzcF9zdWIsIGFlcyhkYXRlLCB2YWx1ZSwgIGNvbG91ciA9IHRpcG8pLCBzaXplID0gMS41KSArDQogIGdlb21fcG9pbnQoZGF0YSA9IGluZmxhY2lvbl9lc3Bfc3ViLCBhZXMoZGF0ZSwgdmFsdWUsIGNvbG91ciA9IHRpcG8sIHNoYXBlID0gdGlwbyksIHNpemUgPSAzKSArDQogIGdlb21fdGV4dChkYXRhID0gaW5mbGFjaW9uX2VzcF9zdWIsIGFlcyhkYXRlLCB2YWx1ZSwgbGFiZWwgPSB2YWx1ZSwgY29sb3VyID0gdGlwbyksIHZqdXN0ID0gLTEuNSxoanVzdCA9IDAuNzUsIHNpemUgPSAzKSArDQogIGdlb21fdGV4dChkYXRhID0gaW5mbGFjaW9uX2VzcF9zdWIsIGFlcyhkYXRlLCB2YWx1ZSwgbGFiZWwgPSAiJSIsIGNvbG91ciA9IHRpcG8pLCB2anVzdCA9IC0xLjUsaGp1c3QgPSAtMC41LCBzaXplID0gMykgKw0KICANCiAgDQogIHNjYWxlX2NvbG9yX21hbnVhbChicmVha3MgPSBjKCJnZW5lcmFsIiwgInN1YnlhY2VudGUiKSwNCiAgICAgICAgICAgICAgICAgICAgIHZhbHVlcz1jKCIjMDAwMDhCIiwgIiMwMEJGRkYiKSkgKw0KICANCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCwNCiAgICAgICAgICAgICBzaXplID0gMC4yNSwNCiAgICAgICAgICAgICBjb2xvdXIgPSAiYmxhY2siLA0KICAgICAgICAgICAgIGxpbmV0eXBlID0gImRhc2hlZCIpICsNCiAgDQogIHNjYWxlX3hfZGF0ZShkYXRlX2xhYmVscz0iJWIgJXkiLGRhdGVfYnJlYWtzICA9ICIxIG1vbnRoIikgKw0KICANCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA3MCwgaGp1c3QgPSAxKSkgKw0KICANCiAgbGltcyh5PSBjKC0xLCA2LjUpKSArDQogIGxhYnMoeCA9IE5VTEwpICsNCiAgbGFicyhjYXB0aW9uID0gIkZ1ZW50ZTogRWxhYm9yYWNpw7NuIHByb3BpYSBjb24gZGF0b3MgZGUgSU5FYmFzZSIpICsNCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSBOQSkpICsgDQogIHRoZW1lKHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJ0cmFuc3BhcmVudCIpKSArDQogIHRoZW1lKGxlZ2VuZC50aXRsZT1lbGVtZW50X2JsYW5rKCkpICsNCiAgdGhlbWUoYXhpcy50aXRsZS55PWVsZW1lbnRfYmxhbmsoKSwgYXhpcy50ZXh0Lnk9ZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLnRpY2tzLnk9ZWxlbWVudF9ibGFuaygpKSArDQogIGxhYnMoY29sb3VyID0gIkdlbmVyYWwiKSAgKyB0aGVtZShwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KGNvbG91ciA9ICJncmF5MjQiKSwNCiAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGNvbG91ciA9ICJ3aGl0ZSIpLA0KICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUoY29sb3VyID0gIndoaXRlIiksDQogICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChjb2xvdXIgPSAid2hpdGUiKSwNCiAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJ0cmFuc3BhcmVudCIpLA0KICAgIGxlZ2VuZC5kaXJlY3Rpb24gPSAiaG9yaXpvbnRhbCIpICsNCiAgbGFicyh0aXRsZSA9ICJFdm9sdWNpw7NuIGFudWFsIGRlbCBJUEMiLCBzdWJ0aXRsZSA9ICLDjW5kaWNlIGdlbmVyYWwgeSBzdWJ5YWNlbnRlLiIpICsNCiAgZ3VpZGVzKHNoYXBlID0gRkFMU0UpIA0KDQoNCg0KI2dyYWZpY28gMg0KDQoNCmVzcF8xIDwtIGdncGxvdCgpICsNCiAgZ2VvbV9saW5lKGRhdGEgPSBpbmZsYWNpb25fdmFyX2VzcCwgYWVzKGRhdGUsIHZhbHVlKSwgY29sb3VyID0gIiMyMTJGM0QiLCBzaXplID0gMS41KSArDQogIA0KICBzY2FsZV94X2RhdGUoZGF0ZV9sYWJlbHM9IiVZIixkYXRlX2JyZWFrcyAgPSI1IHllYXJzIikgKw0KICANCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0wLA0KICAgICAgICAgICAgIHNpemUgPSAwLjI1LA0KICAgICAgICAgICAgIGNvbG91ciA9ICJibGFjayIpICArIA0KICANCiAgYW5ub3RhdGUoInJlY3QiLA0KICAgICAgICAgICB4bWluID0gYXMuRGF0ZSgiMjAyMC0wMS0wMSIpLA0KICAgICAgICAgICB4bWF4ID0gYXMuRGF0ZSgiMjAyMi0xMS0wMSIpLA0KICAgICAgICAgICB5bWluID0gLUluZiwNCiAgICAgICAgICAgeW1heCA9IEluZiwNCiAgICAgICAgICAgYWxwaGEgPSAwLjQsDQogICAgICAgICAgIGZpbGwgPSAicGluayIpICsNCiAgDQogIHNjYWxlX3lfY29udGludW91cyhicmVha3MgPSBzZXEoLTEsIDYsIDEpKSArDQogIGxhYnModGl0bGUgPSAiVmFyaWFjacOzbiBlbiBsb3MgdWx0aW1vcyAzMCBhw7Fvcy4iLCBzdWJ0aXRsZSA9ICLDjW5kaWNlIGdlbmVyYWwuIikgKw0KICB0aGVtZShheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUoc2l6ZSA9IDAuMDUsDQogICAgbGluZXR5cGUgPSAic29saWQiKSwgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSAiZ3JheTg4IiwNCiAgICBzaXplID0gMC4yNSwgbGluZXR5cGUgPSAidHdvZGFzaCIpLCBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGNvbG91ciA9IE5BKSwNCiAgICBheGlzLnRleHQgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJpdGFsaWMiLA0KICAgICAgICBjb2xvdXIgPSAiZ3JheTEwIiksIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGNvbG91ciA9ICJncmF5MTAiKSwNCiAgICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSBOQSwNCiAgICAgICAgY29sb3VyID0gImFxdWFtYXJpbmU0IikpK2xhYnMoeCA9IE5VTEwsIHkgPSBOVUxMKQ0KDQoNCg0KDQojZXNwICsgaW5zZXRfZWxlbWVudChlc3BfMSwgbGVmdCA9IDAsIHJpZ2h0ID0gMC40LCBib3R0b20gPSAwLjUsIHRvcCA9IDAuOSkNCg0KYGBgDQoNCjxjZW50ZXI+PGltZyBzcmM9ImltYWdlbmVzL2luZmxhY2lvbl9lc3BhbmEucG5nIiB3aWR0aCA9ICIxMDAwcHgiIC8+PC9jZW50ZXI+DQoNCjxicj4NCg0KIyMjIDYuMiBQb25kZXJhY2nDs24gY29tcG9uZW50ZXMgDQoNCg0KRW4gbG8gcXVlIHJlc3BlY3RhIGEgbGEgcG9uZGVyYWNpw7NuIHBvciBjb21wb25lbnRlcywgY29tbyBzZSBwdWVkZSBhcHJlY2lhciwgZWwgcGF0csOzbiBkZSBwZXNvcyBkZSBjYWRhIHBhcnRpZGEgcXVlIGNvbnNpZGVyYSBlbCBJTkUgcGFyYSBjYWxjdWxhciBlbCBJUEMgbm8gaGEgZXhwZXJpbWVudGFkbyBzaWduaWZpY2F0aXZvcyBjYW1iaW9zIGRlc2RlIDIwMTcuIFB1ZWRlIHNvcnByZW5kZXIgcXVlIGxhIHBhcnRpZGEgZGUgKiowNCoqLCBhdW5xdWUgIHPDrSBoYSBleHBlcmltZW50YWRvIHVuIGluY3JlbWVudG8sIG5vIGVzIHRhbiBtYXJjYWRvIGNvbW8gZWwgcmVhbCwgZXN0byBzZSBkZWJlIHNpbXBsZW1lbnRlIGFsIGZvcm1hdG8gZGUgY8OhbGN1bG8uIENvbiB0b2RvLCBlbCBncmFuIGluY3JlbWVudG8gZGVsIGdydXBvICoqMDEqKiBjb21wZW5zYSBsYXMgcGVxdWXDsWFzIGJhamFkYXMgcXVlIGhhbiBleHBlcmltZW50YWRvIGdydXBvcyBjb21vICoqT2NpbyB5IGN1bHR1cmEqKiB5ICoqUmVzdGF1cmFjacOzbiB5IGhvdGVsZXMqKi4gQmFqYWRhcyByYXpvbmFibGVzIHNpIHRlbmVtb3MgZW4gY29uc2lkZXJhY2nDs24gbGEgc2l0dWFjacOzbiBzYW5pdGFyaWEgZGUgbG9zIMO6bHRpbW9zIDIgYcOxb3MuDQoNCmBgYHtyLCBlY2hvID0gVFJVRSwgd2FybmluZz0gRkFMU0V9DQoNCmNvbXBvbmVudGVzIDwtIGdncGxvdChwb25kZXJhY2lvbl9jb21wb25lbnRlc0lQQywgYWVzKENvbXBvbmVudGVzLCB2YWx1ZSwgZmlsbCA9IGFzX2ZhY3RvcihkYXRlKSkpKw0KICBnZW9tX2NvbChwb3NpdGlvbiA9IHBvc2l0aW9uX3N0YWNrKHJldmVyc2UgPSBUUlVFKSkgKw0KICBjb29yZF9mbGlwKCkgKw0KICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlNwZWN0cmFsIikgKyANCiAgDQogIA0KICB0aGVtZShwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGNvbG91ciA9IE5BKSwNCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGNvbG91ciA9IE5BKSwNCiAgICBheGlzLnRleHQgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiksDQogICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCwNCiAgICAgIGZhY2UgPSAiYm9sZCIpLCBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSBOQSksDQogICAgcGxvdC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGNvbG91ciA9IE5BKSwNCiAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwgbGVnZW5kLmRpcmVjdGlvbiA9ICJob3Jpem9udGFsIikgKw0KICAgIGxhYnModGl0bGUgPSAiUG9uZGVyYWNpb25lcyBwb3IgZ3J1cG9zIElQQyIsDQogICAgeCA9IE5VTEwsIHkgPSAiVW5pZGFkZXM6ICUxMDAwIGVuIGJhc2UgMjAxNiIsDQogICAgZmlsbCA9IE5VTEwsIHN1YnRpdGxlID0gIkFjdW11bGFjacOzbiBwb3IgZ3J1cG9zIGRlbCBwZXJpb2RvIDIwMTctMjAyMSIpICsgDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJsZWZ0IiwgbGVnZW5kLmRpcmVjdGlvbiA9ICJ2ZXJ0aWNhbCIpICsNCiAgbGFicyhjYXB0aW9uID0gIkZ1ZW50ZTogRWxhYm9yYWNpb24gcHJvcGlhIGNvbiBkYXRvcyBkZWwgSU5FIikNCg0KY29tcG9uZW50ZXMgPC0gZ2dwbG90bHkoY29tcG9uZW50ZXMpDQoNCmNvbXBvbmVudGVzDQoNCmBgYA0KDQo8YnI+DQoNCiMjIyA2LjMgSW5mbGFjacOzbiBDb211bmlkYWRlcyBBdXTDs25vbWFzLyBQcm92aW5jaWFzLg0KDQpTaSBtaW5pbWl6YW1vcyBlbCBmb2NvIGRlIGFuw6FsaXNpcyB5IGRlc2FncmVnYW1vcyBwb3IgQ0NBQSwgcG9kZW1vcyBvYnNlcnZhciBjb21vIHRvZGFzLCBleGNlcHR1YW5kbyAqKmxhcyBpc2xhcyBjYW5hcmlhcyoqLCBkaXNwb25lbiBkZSBwZW9yZXMgZGF0b3MgcXVlIGxhIG1lZGlhIHBhcmEgbGEgVUVfMjcuIE1heW9yZXMgY29uY2x1c2lvbmVzIHBvZGVtb3MgZXh0cmFlciBzaSBhbmFsaXphbW9zIGVsIHByb2JsZW1hIG1lZGlhbnRlIGRhdG9zIHBvciBwcm92aW5jaWFzICh2w6lhc2UgbWFwYSBkZSBwcm92aW5jaWFzKS4gTG9zIG1heW9yZXMgZGF0b3MgZGUgaW5mbGFjacOzbiBzZSBlbmN1ZW50cmFuIGVuIGFxdWVsbGFzIHByb3ZpbmNpYXMgY2FyYWN0ZXJpemFkYXMgcG9yIHJlYWxpemFyIGFjdGl2aWRhZGVzIHByaW1hcmlhcy9zZWN1bmRhcmlhcy4gVW5hIGV4cGxpY2FjacOzbiByYXpvbmFibGUgc2UgcHVlZGUgZGViZXIgYSBsYSBmYWx0YSBkZSBjYXBhY2lkYWQgZGUgZXN0b3Mgc2VjdG9yZXMgcGFyYSB0cmFzbGFkYXIgdG9kbyBlbCBzb2JyZWNvc3RlIGFkaWNpb25hbCBkZSBsb3MgcHJlY2lvcyBkZSBsYSBlbGVjdHJpY2lkYWQgeSBtYXRlcmlhcyBwcmltYXMgYSBsb3Mgc2lndWllbnRlcyBlc2xhYm9uZXMgZW4gbGEgY2FkZW5hIGRlIHZhbG9yLiBBdW5xdWUgY29uc2lkZXJhbW9zIHF1ZSBwdWVkZSBzZXIgdW4gdGVtYSBtdXkgaW50ZXJlc2FudGUsIG5vIHZhbW9zIGEgZW50cmFyIGEgZXN0dWRpYXIgZW4gcHJvZnVuZGlkYWQgZXN0b3Mgc3VidGVtYXMgcXVlIHN1cmdlbiBlbiBudWVzdHJvIGFydMOtY3VsbywgeWEgcXVlIG5vcyBlc3RhbW9zIGEgY2VudHJhbmRvIG3DoXMgZW4gZWwgZXN0dWRpbyBkZSBsYSBpbmZsYWNpw7NuIGEgbWF5b3IgZXNjYWxhLCBwZXLDsyBzw60gbm9zIHBhcmVjZSByZWxldmFudGUgYWwgbWVub3MgcHJlc2VudGFyIGxvcyBkYXRvcyBkZXNhZ3JlZ2Fkb3MgcGFyYSBvYnNlcnZhciBlbiBxdcOpIHpvbmFzIGdlb2dyw6FmaWNhcyBkZSBFc3Bhw7FhLCBsYSBww6lyZGlkYSBkZSBwb2RlciAgYWRxdWlzaXRpdm8gZGUgbGFzIGZhbWlsaWFzIGVzIG3DoXMgYWN1c2FkYS4NCg0KYGBge3IsIGVjaG8gPSBUUlVFLCB3YXJuaW5nPSBGQUxTRX0NCg0KY29tdW5pZGFkZXMgPC0gaW5mbGFjaW9uX2NvbXVuaWRhZGVzICU+JQ0KICBmaWx0ZXIoZGF0ZSA9PSAiMjAyMS0xMC0wMSIpICU+JQ0KICBtdXRhdGUoaWQgPSBzZXEoMToxOSkpDQoNCm51bWJlcl9vZl9iYXIgPC0gbnJvdyhjb211bmlkYWRlcykNCmFuZ2xlIDwtICA5MCAtIDM2MCAqIChjb211bmlkYWRlcyRpZC0wLjUpIC9udW1iZXJfb2ZfYmFyICAgICANCg0KY29tdW5pZGFkZXMkaGp1c3Q8LWlmZWxzZSggYW5nbGUgPCAtOTAsIDEsIDApDQoNCmNvbXVuaWRhZGVzJGFuZ2xlPC1pZmVsc2UoYW5nbGUgPCAtOTAsIGFuZ2xlKzE4MCwgYW5nbGUpDQoNCg0KcCA8LSBnZ3Bsb3QoY29tdW5pZGFkZXMsIGFlcyggYXMuZmFjdG9yKGlkKSx2YWx1ZSwgZmlsbD1ub21icmVfY29tdW5pZGFkKSkgKyAgICAgICANCiAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiKSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKGJyZWFrcyA9IGMoIkFuZGFsdWPDrWEiLCAiQXJhZ8OzbiIsICJQcmluY2lwYWRvIGRlIEFzdHVyaWFzIiwiSWxsZXMgQmFsZWFycyIsIkNhbmFyaWFzIiwiICAgICAgICBDYW50YWJyaWEiLCJDYXN0aWxsYSB5IExlw7NuIiwiQ2FzdGlsbGEgLSBMYSBNYW5jaGEiLCJDYXRhbHXDsWEiLCJDb211bml0YXQgVmFsZW5jaWFuYSIsIkV4dHJlbWFkdXJhIiwiR2FsaWNpYSIsIkNvbXVuaWRhZCBkZSBNYWRyaWQiLCJSZWdpw7NuIGRlIE11cmNpYSIsIkNvbXVuaWRhZCBGb3JhbCBkZSBOYXZhcnJhIiwiUGHDrXMgVmFzY28iLCJMYSBSaW9qYSIsIkNldXRhIiwiTWVsaWxsYSIpLA0KICAgICAgICAgICAgICAgICB2YWx1ZXM9YygiIzU0NmU3YSIsICIjZmI4YzAwIiwiIzFiNWUyMCIsIiMwMDg5N2IiLCIjZjQ1MTFlIiwiIzY4OWYzOCIsIiNmZmNhMjgiLCIjNGRkMGUxIiwiIzAxNTc5YiIsIiNiZGJkYmQiLCIjMWEyMzdlIiwiIzgyYjFmZiIsIiM1ZTM1YjEiLCIjZmZmZjAwIiwiI2Q1MDBmOSIsIiNkNGUxNTciLCIjNmQ0YzQxIiwiI2U1NzM3MyIsIiNjNTExNjIiKSkgKw0KICB5bGltKC01LDcpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoDQogICAgYXhpcy50ZXh0ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksDQogICAgcGFuZWwuZ3JpZCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBwbG90Lm1hcmdpbiA9IHVuaXQocmVwKC0xLDQpLCAiY20iKSkgKw0KICANCiAgY29vcmRfcG9sYXIoc3RhcnQgPSAwKSArDQogIA0KICBnZW9tX3RleHQoZGF0YT1jb211bmlkYWRlcywgYWVzKGlkLCB2YWx1ZSswLjUsIGxhYmVsPXZhbHVlLCBoanVzdD1oanVzdCApLCBjb2xvcj0iYmxhY2siLCBmb250ZmFjZT0iYm9sZCIsYWxwaGE9MC42LCBzaXplPTUsIGFuZ2xlPSBjb211bmlkYWRlcyRhbmdsZSwgaW5oZXJpdC5hZXMgPSBGQUxTRSApICsgbGFicyhmaWxsID0gIkNvbXVuaWRhZGVzIikgKw0KICBsYWJzKHggPSBOVUxMLCBmaWxsID0gTlVMTCkNCg0KcA0KDQpgYGANCg0KDQoNCiMjIyMgUHJvdmluaWNhcyB7LnRhYnNldCAudGFic2V0LXBpbGxzfQ0KDQojIyMjIyBNYXBhIA0KDQpgYGB7ciwgZWNobyA9IFRSVUUsIHdhcm5pbmc9IEZBTFNFfQ0KDQpkYXRhX3Byb3YgPC0gdGlkeShzaGFwZWZpbGVfcHJvdmluY2lhcykNCg0KZGF0YV9wcm92JGdyb3VwIDwtIGFzLmNoYXJhY3RlcihkYXRhX3Byb3YkZ3JvdXApIA0KDQpub21icmVzX3Byb3ZpbmNpYXMgPC0gcmVhZF9leGNlbCgiZGF0b3Mvbm9tYnJlc19wcm92aW5jaWFzLnhsc3giKQ0KDQpkYXRhX3Byb3ZpbmNpYXNfbWFwYSA8LSBsZWZ0X2pvaW4oZGF0YV9wcm92LCBub21icmVzX3Byb3ZpbmNpYXMsIGJ5ID0gImlkIikgJT4lIHJlbmFtZShwcm92ID0gc2hhcGVmaWxlX3Byb3ZpbmNpYXMuVGV4dG8pDQoNCmluZmxhY2lvbl9wcm92IDwtIHJlYWRfZXhjZWwoInNocC9pbmZsYWNpb25fcHJvdi54bHN4IikNCmluZmxhY2lvbl9wcm92IDwtIGluZmxhY2lvbl9wcm92ICU+JSByZW5hbWUoaWQyID0gaWQpDQoNCm1hcGFfcHJvdiA8LSBsZWZ0X2pvaW4oaW5mbGFjaW9uX3Byb3YsIGRhdGFfcHJvdmluY2lhc19tYXBhLCBieSA9IGMoImlkMiIgPSAiaWQiKSkgDQoNCg0KYWEgPC0gbWFwYV9wcm92ICU+JQ0KICBnZ3Bsb3QoYWVzKCB4PSBsb25nLCB5ID0gbGF0LCBncm91cCA9IGdyb3VwKSkgKw0KICBnZW9tX3BvbHlnb24oYWVzKGZpbGw9dmFsdWUpLA0KICAgICAgICAgICAgICAgY29sb3IgPSAid2hpdGUiLCBzaXplID0gMC4yKSArDQogIGxhYnMoIHRpdGxlID0gIlRhc2EgZGUgUmllc2dvIGRlIFBvYnJlemEgcG9yIENvbXVuaWRhZGVzIEF1dMOzbm9tYXMiLA0KICAgICAgICBzdWJ0aXRsZSA9ICJVbmlkYWRlczogUG9yY2VudGFqZSIsDQogICAgICAgIGNhcHRpb24gPSAiRnVlbnRlOiBJTkUiLA0KICAgICAgICBmaWxsID0gIlRhc2EgKCUpIikgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZSgNCiAgICBheGlzLmxpbmUgPSBlbGVtZW50X2JsYW5rKCksDQogICAgYXhpcy50ZXh0ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksDQogICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJzbm93IiwgY29sb3IgPSBOQSksDQogICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsPSAic25vdyIsIGNvbG9yID0gTkEpLA0KICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE2LCBoanVzdCA9IDApLA0KICAgIHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyLCBoanVzdCA9IDApLA0KICAgIHBsb3QuY2FwdGlvbiA9IGVsZW1lbnRfdGV4dChzaXplID0gOCwgaGp1c3QgPSAxKSwNCiAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoY29sb3IgPSAiZ3JleTQwIiwgc2l6ZSA9IDgpLA0KICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImdyZXk0MCIsIHNpemUgPSA3LCBoanVzdCA9IDApLA0KICAgIGxlZ2VuZC5wb3NpdGlvbiA9IGMoMC45MywgMC4zKSwNCiAgICBwbG90Lm1hcmdpbiA9IHVuaXQoYygwLjUsMiwwLjUsMSksICJjbSIpKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKA0KICAgIGF4aXMubGluZSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLnRleHQgPSBlbGVtZW50X2JsYW5rKCksDQogICAgYXhpcy50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLnRpY2tzID0gZWxlbWVudF9ibGFuaygpLA0KICAgIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoY29sb3VyPSAiZGFya2dyZXkiLCBzaXplPSAwLjUpKSArDQogIGdndGl0bGUoIlByb3ZpbmNpYXMgRXNwYcOxb2xhcyIpDQoNCg0KYWEgPC0gZ2dwbG90bHkoYWEpDQphYQ0KDQoNCmBgYA0KDQpgYGB7ciwgZWNobyA9IFRSVUUsIHdhcm5pbmc9IEZBTFNFfQ0KDQpwcm92aW5jaWFfbWF4IDwtIGluZmxhY2lvbl9wcm92aW5jaWFzICU+JSBmaWx0ZXIoZGF0ZSA9PSAiMjAyMS0xMC0wMSIpICU+JSBzbGljZV9tYXgodmFsdWUsIG49MSkgJT4lIA0KICBkcGx5cjo6c2VsZWN0KC1kYXRlKSAlPiUgDQogIHJlbmFtZShpbmZsYWNpb24gPSB2YWx1ZSkNCg0KYmFuZGVyYXMgPC0gYygiaHR0cHM6Ly91cGxvYWQud2lraW1lZGlhLm9yZy93aWtpcGVkaWEvY29tbW9ucy82LzYzL0JhbmRlcmFfZGVfTGUlQzMlQjNuXyUyOGNpdWRhZCUyOS5zdmciLCAiaHR0cHM6Ly91cGxvYWQud2lraW1lZGlhLm9yZy93aWtpcGVkaWEvY29tbW9ucy9iL2JmL0JhbmRlcmFfZGVfbGFfcHJvdmluY2lhX2RlX1RvbGVkby5zdmciKQ0KDQoNCnByb3ZpbmNpYV9tYXhfdXJscyA8LSBwcm92aW5jaWFfbWF4ICU+JSBncm91cF9ieShub21icmVfcHJvdmluY2lhKSAlPiUgDQogIGFkZF9jb2x1bW4oYmFuZGVyYXMpICU+JSB1bmdyb3VwKCkNCg0KDQoNClRhYmxhX21heCA8LSBwcm92aW5jaWFfbWF4X3VybHMgJT4lIGd0KCkNCg0KVGFibGFfbWF4IDwtIFRhYmxhX21heCAlPiUNCiAgdGFiX2hlYWRlcih0aXRsZSA9IG1kKCIqKlByb3ZpbmNpYSBjb24gbWF5b3IgaW5mbGFjacOzbioqIiksc3VidGl0bGUgPSBtZCgiQSBmZWNoYTogMDEtMTAtMjAyMSIpKQ0KDQpUYWJsYV9tYXggPC0gVGFibGFfbWF4ICU+JQ0KICB0YWJfb3B0aW9ucyhoZWFkaW5nLmJhY2tncm91bmQuY29sb3IgPSAiIzljY2M2NSIpICU+JSB0YWJfb3B0aW9ucyhoZWFkaW5nLnRpdGxlLmZvbnQuc2l6ZSA9IDE1LCBoZWFkaW5nLnN1YnRpdGxlLmZvbnQuc2l6ZSA9IDEzLCAgY29sdW1uX2xhYmVscy5mb250LndlaWdodCA9ICAiYm9sZCIpDQoNCg0KVGFibGFfbWF4IDwtIFRhYmxhX21heCAgJT4lDQogIGd0Ojp0ZXh0X3RyYW5zZm9ybShsb2NhdGlvbnMgPSBjZWxsc19ib2R5KGNvbHVtbnMgPSB2YXJzKGJhbmRlcmFzKSksIGZuID0gZnVuY3Rpb24oeCkge2d0Ojp3ZWJfaW1hZ2UoeCwgaGVpZ2h0ID0gNTApfSkgJT4lICBjb2xzX2FsaWduKA0KICAgIGFsaWduID0gImNlbnRlciIpDQoNCg0KcHJvdmluY2lhX21pbiA8LSBpbmZsYWNpb25fcHJvdmluY2lhcyAlPiUgZmlsdGVyKGRhdGUgPT0gIjIwMjEtMTAtMDEiKSAlPiUgDQpzbGljZV9taW4odmFsdWUsIG49MSkgJT4lIA0KICBkcGx5cjo6c2VsZWN0KC1kYXRlKSAlPiUgcmVuYW1lKGluZmxhY2lvbiA9IHZhbHVlKQ0KDQoNCmJhbmRlcmEgPC0gYygiaHR0cHM6Ly91cGxvYWQud2lraW1lZGlhLm9yZy93aWtpcGVkaWEvY29tbW9ucy85LzljL0JhbmRlcmFfUHJvdmluY2lhbF9kZV9MYXNfUGFsbWFzLnBuZyIpDQoNCg0KcHJvdmluY2lhX21pbl91cmxzIDwtIHByb3ZpbmNpYV9taW4gJT4lIGdyb3VwX2J5KG5vbWJyZV9wcm92aW5jaWEpICU+JSANCiAgYWRkX2NvbHVtbihiYW5kZXJhKSAlPiUgdW5ncm91cCgpDQoNCg0KDQpUYWJsYV9taW4gPC0gcHJvdmluY2lhX21pbl91cmxzICU+JSBndCgpDQoNClRhYmxhX21pbiA8LSBUYWJsYV9taW4gJT4lDQogIHRhYl9oZWFkZXIodGl0bGUgPSBtZCgiKipQcm92aW5jaWEgY29uIG1lbm9yIGluZmxhY2nDs24qKiIpLHN1YnRpdGxlID0gbWQoIkEgZmVjaGE6IDAxLTEwLTIwMjEiKSkNCg0KVGFibGFfbWluIDwtIFRhYmxhX21pbiAlPiUNCiAgdGFiX29wdGlvbnMoaGVhZGluZy5iYWNrZ3JvdW5kLmNvbG9yID0gIiM5Y2NjNjUiKSAlPiUgdGFiX29wdGlvbnMoaGVhZGluZy50aXRsZS5mb250LnNpemUgPSAxNSwgaGVhZGluZy5zdWJ0aXRsZS5mb250LnNpemUgPSAxMywgIGNvbHVtbl9sYWJlbHMuZm9udC53ZWlnaHQgPSAgImJvbGQiKQ0KDQoNClRhYmxhX21pbiA8LSBUYWJsYV9taW4gICU+JQ0KICBndDo6dGV4dF90cmFuc2Zvcm0obG9jYXRpb25zID0gY2VsbHNfYm9keShjb2x1bW5zID0gdmFycyhiYW5kZXJhKSksIGZuID0gZnVuY3Rpb24oeCkge2d0Ojp3ZWJfaW1hZ2UoeCwgaGVpZ2h0ID0gNTApfSkgJT4lICBjb2xzX2FsaWduKA0KICAgIGFsaWduID0gImNlbnRlciIpDQoNCmBgYA0KDQo6Ojogey5jb2x1bW4gd2lkdGg9IjQ3JSJ9DQoNCjxjZW50ZXI+PGltZyBzcmM9ImltYWdlbmVzL2xlb25feV90b2xlZG8ucG5nIiB3aWR0aCA9ICIzMDBweCIgLz48L2NlbnRlcj4NCg0KOjo6DQoNCjo6OiB7LmNvbHVtbiB3aWR0aD0iMSUifQ0KPCEtLSBhbiBlbXB0eSBEaXYgKHdpdGggYSB3aGl0ZSBzcGFjZSkgaGFjaWVuZG8gZGUgc2VwYXJhZG9yIC0tPg0KOjo6DQoNCjo6OiB7LmNvbHVtbiB3aWR0aD0iNDclIn0NCg0KPGNlbnRlcj48aW1nIHNyYz0iaW1hZ2VuZXMvbGFzX3BhbG1hcy5wbmciIHdpZHRoID0gIjMwMHB4IiAvPjwvY2VudGVyPg0KDQo6OjoNCg0KDQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQo8YnI+DQoNCiMjIyMjIFRhYmxhDQoNCmBgYHtyLCBlY2hvID0gVFJVRSwgd2FybmluZz0gRkFMU0V9DQoNCmluZmxhY2lvbl9wcm92aW5jaWFzIDwtIGluZmxhY2lvbl9wcm92aW5jaWFzICU+JQ0KICBmaWx0ZXIoZGF0ZSA9PSAiMjAyMS0xMC0wMSIpICU+JSANCiAgcmVuYW1lKGluZmxhY2lvbiA9IHZhbHVlKSANCiAgDQoNCmRhdGF0YWJsZShpbmZsYWNpb25fcHJvdmluY2lhcywgY2xhc3MgPSJzdHJpcGUgaG92ZXIgY29tcGFjdCByb3ctYm9yZGVyIiAsIGZpbHRlciA9ICd0b3AnKQ0KDQpgYGANCg0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KPGJyPg0KDQojIyMgNi40LiBMYSBkZXBlbmRlbmNpYSBlbmVyZ8OpdGljYQ0KDQpQYXJhIGVsIGNhc28gZXNwYcOxb2wgZXN0YSBzaXR1YWNpw7NuICgqYXVtZW50byBkZSBsb3MgcHJlY2lvcyBlbmVyZ8OpdGljb3MqKSBsZSBwZXJqdWRpY2EgZW4gbWF5b3IgbWVkaWRhLiBDb21vIGVzIGJpZW4gc2FiaWRvLCBudWVzdHJhIGVjb25vbcOtYSBzZSBjYXJhY3Rlcml6YSBwb3IgdW5hICoqZnVlcnRlIGRlcGVuZGVuY2lhIGVuZXJnw6l0aWNhIGV4dGVyaW9yKiouIFNpIGNvbnN1bHRhbW9zIGxvcyDDumx0aW1vcyBkYXRvcyBkZWwgSW5zdGl0dXRvIE5hY2lvbmFsIGRlIEVzdGFkw61zdGljYSAoSU5FKSwgZW4gRXNwYcOxYSBhcGVuYXMgKipzZSBwcm9kdWNlIHVuIHRlcmNpbyBkZSBsYSBlbmVyZ8OtYSBxdWUgc2UgY29uc3VtZSoqLiBFc3RvcyBkYXRvcyBzaXTDumFuIGEgRXNwYcOxYSBjb21vIHVubyBkZSBsb3MgcGHDrXNlcyBkZSBsYSBVbmnDs24gRXVyb3BlYSBtw6FzIGRlcGVuZGllbnRlcyBlbmVyZ8OpdGljYSwgeWEgcXVlIGxhIG1lZGlhIGRlIGxhIFVFIHNlIHNpdMO6YSBjZXJjYSBkZWwgNTAlLiBFc3RlIGZhY3RvciBlcyBjbGF2ZSBwYXJhIGVudGVuZGVyLCBlbiBwYXJ0ZSwgZWwgcHJvYmxlbWEgYWN0dWFsLCB5IGVzIHVuYSBkZSBsYXMgKip2YXJpYWJsZXMgZW4gbGFzIHF1ZSBzZSBkZWJlcsOtYSBlbXBlemFyIGEgY2VudHJhciBFc3Bhw7FhKiouIFNpIG5vIGVzIGFzw60sIGxhcyBmdXR1cmFzIGZsdWN0dWFjaW9uZXMgZGVsIHByZWNpbyBkZSBsYSBlbmVyZ8OtYSwgZ2VuZXJhbiBpbmVzdGFiaWxpZGFkZXMgZW4gZWwgY29zdGUgZGUgdmlkYSBwZXJpw7NkaWNhbWVudGUsIHkgZW4gcGFyYWxlbG8gYSBsb3Mgc2hvY2tzLiBFbCBmdXR1cm8gZXMgaW5jaWVydG8sIHkgYXVucXVlIHNlIGhhIGdvemFkbyBkZSB1biBwZXLDrW9kbyBkZSBlc3RhYmlsaWRhZCwgbmFkaWUgbm9zIGdhcmFudGl6YSBxdWUgbGFzIGZsdWN0dWFjaW9uZXMgbm8gc2UgcmVwaXRhbiBkZSBmb3JtYSBwcm9sb25nYWRhLiANCg0KPGJyPg0KDQojIyA3LiBDb25zZWN1ZW5jaWFzIGRlIGxhIGluZmxhY2nDs24NCg0KVW5hIGluZmxhY2nDs24gc3VmaWNpZW50ZW1lbnRlIGFsdGEgcGVyanVkaWNhIGEgKip0b2RvKiogZWwgbXVuZG8gKCpvIGEgY2FzaSB0b2RvIGVsIG11bmRvKiksIGVzcGVjaWFsbWVudGUgY3VhbmRvIMOpc3RhIGVzIHByb2xvbmdhZGEuIFBlcm8gc2kgdG9tYW1vcyBjb21vIHJlZmVyZW5jaWEgbGFzIGhpcMOzdGVzaXMgcXVlIGVzdMOhbiBhZG9wdGFuZG8gb3JnYW5pc21vcyBpbnRlcm5hY2lvbmFsZXMgeSBiYW5jbyBjZW50cmFsIGV1cm9wZW86DQoNCjxicj4NCg0KOjo6IGNvbHVtbnMNCg0KYGBge3IsIGVjaG8gPSBGQUxTRSwgb3V0LndpZHRoID0gIjYwJSJ9DQp0d2VldHJtZDo6dHdlZXRfZW1iZWQoImh0dHBzOi8vdHdpdHRlci5jb20vZWxFY29ub21pc3RhZXMvc3RhdHVzLzE0NjY3MDc2NTc3NzE4NTk5NzE/cz0yMCIsIHRoZW1lID0gImxpZ2h0IiwgYWxpZ24gPSAiY2VudGVyIiwgZG50ID0gVFJVRSwgbWF4d2lkdGggPSA0MDApDQpgYGANCjo6Og0KDQoNCjxicj4NCg0KRXMgZGVjaXIsIHNpIGFzdW1pbW9zIHF1ZSBsYSBpbmZsYWNpw7NuIHZhIGEgc2VyIHRyYW5zaXRvcmlhLCBxdWUgZWZlY3RvcyBwdWVkZSB0ZW5lciBzb2JyZSBsb3MgYWdlbnRlcyBlY29uw7NtaWNvcywgwr9hIHF1acOpbiBhZmVjdGEgbcOhcyBsYSBpbmZsYWNpw7NuPw0KDQo8YnI+DQoNCiMjIyA3LjEgwr9BIHF1acOpbiBhZmVjdGEgbcOhcyBsYSBpbmZsYWNpw7NuPw0KDQpMb3MgZWZlY3RvcyByZWRpc3RyaWJ1dGl2b3MgZW4gdW4gcGVyw61vZG8gY29ydG8gZGUgaW5mbGFjacOzbiDigJxjb250cm9sYWRh4oCdIGRlcGVuZGVuIGRlIGxhIGVzdHJ1Y3R1cmEgcGF0cmltb25pYWwgeSBkZSBsYSBlc3RydWN0dXJhIGRlIGluZ3Jlc29zIHkgZ2FzdG9zIGRlIGxvcyBkaXN0aW50b3MgaW5kaXZpZHVvcyBxdWUgY29uZm9ybWFuIHVuYSBkZXRlcm1pbmFkYSBlY29ub23DrWEuIExhICoqaW5mbGFjacOzbiBlcyBtw6FzIGRhw7FpbmEgcGFyYSBhcXVlbGxvcyBhZ2VudGVzIHF1ZSB0ZW5nYW4gZW4gY2FydGVyYSBhY3Rpdm9zIGRlIHJlbnRhIGZpamEqKiBlbiBsdWdhciBkZSBhY3Rpdm9zIGRlIHJlbnRhIHZhcmlhYmxlICgqaGlzdMOzcmljYW1lbnRlICDDqXN0YSBzZSByZXZhbG9yaXphbiBlbiBwZXLDrW9kb3MgZGUgaW5mbGFjacOzbiopLiBFcyBkZWNpciwgYXF1ZWxsb3MgYWdlbnRlcyBxdWUgY2FyZXpjYW4gZGUgZGV1ZGEgKG8gY3V5YSBkZXVkYSBlc3TDqSBpbmRleGFkYSBhIGxhIGluZmxhY2nDs24pIHkgcXVlIGRpc3BvbmdhbiBkZSBpbmdyZXNvcy9nYXN0b3MgaW5zZW5zaWJsZXMgYSBsYSBpbmZsYWNpw7NuIGVuIGVsIGNvcnRvIHBsYXpvIHB1ZWRlbiB2ZXJzZSBiZW5lZmljaWFkb3MgcG9yIGxhIGFsemEgZGUgcHJlY2lvcy4gUG9yIHRhbnRvLCBsb3MgYWdlbnRlcyBxdWUgbm8gc2UgaGFsbGVuIGVuIGVzdGEgc2l0dWFjacOzbiAobm8gZGlzcG9uZW4gZGUgdW5hIGNhcnRlcmEgcGF0cmltb25pYWwgcXVlIHNlIHJldmFsb3JpY2UgY29uIGxhIGluZmxhY2nDs24pICoqdmVyw6FuIGPDs21vIHN1IHBhdHJpbW9uaW8gbmV0byBzZSByZWR1Y2UgZW4gdMOpcm1pbm9zIHJlYWxlcywganVudG8gYSBzdSBjYXBhY2lkYWQgZGUgZ2VuZXJhY2nDs24gZGUgbnVldm8gYWhvcnJvICBlbiB0w6lybWlub3MgcmVhbGVzKiogKCpiYWpvIHN1cHVlc3RvIHF1ZSBubyBzZSBwcm9kdWNlbiByZXZhbG9yaXphY2lvbmVzIHNhbGFyaWFsZXMgZW4gZGljaG8gcGVyw61vZG8gbWF5b3JlcyBhIGxhIGluZmxhY2nDs24qKS4gDQoNCkxhIHByZWd1bnRhIHF1ZSBkZWJlIGZvcm11bGFyc2UgZWwgbGVjdG9yIGVzIGNsYXJhOg0KDQo+IMK/RW4gcXXDqSBtZWRpZGEgc2UgZW5jdWVudHJhbiBkaXN0cmlidWlkb3MgbGFzIGZhbWlsaWFzIGVudHJlIGRpY2hhcyBjYXRlZ29yw61hcz8NCg0KQW5hbGljZW1vcywgcHVlcywgZW4gcXXDqSBtZWRpZGEgbG9zIHJpY29zIHkgbG9zIHBvYnJlcyBzZSBoYWxsYW4gZW4gZXN0YXMgZGlzdGludGFzIGNhdGVnb3LDrWFzIGVuIG51ZXN0cmEgZWNvbm9tw61hIGRvbcOpc3RpY2EuDQoNClNlZ8O6biBsb3Mgw7psdGltb3MgZGF0b3MgcXVlIGRpc3BvbmUgZWwgQmFuY28gZGUgRXNwYcOxYSwgKiplbCBwb3JjZW50YWplIGRlIGZhbWlsaWFzIGNvbiBhY3Rpdm9zIHJlYWxlcyBpbmNyZW1lbnRhIGNvbiBsYSByZW50YSoqLiBSZWN1ZXJkZSBlbCBsZWN0b3IgZGljaG9zIGFjdGl2b3Mgc2UgY2FyYWN0ZXJpemFuIHBvciB0ZW5lciBjaWVydGEgY2FwYWNpZGFkIGRlIHJldmFsb3JpemFyc2UgY29uIGxhIGluZmxhY2nDs24uIENvbW8gc2UgcHVlZGUgb2JzZXJ2YXIsIG1pZW50cmFzIHF1ZSA5IGRlIGNhZGEgMTAgZmFtaWxpYXMgcXVlIGNvbmZvcm1hbiBlbCBkZWNpbCBjb24gbWF5b3JlcyBpbmdyZXNvcyBkaXNwb25lbiBkZSB2aXZpZW5kYSBwcmluY2lwYWwgZW4gcHJvcGllZGFkLCBzb2xvIGVsIDY1JSBhcHJveGltYWRhbWVudGUgZGVsIHF1aW50aWwgbcOhcyBwb2JyZSBkaXNwb25lIGRlIGVsbGEuIE9idGVuZW1vcyByZXN1bHRhZG9zIHNpbWlsYXJlcyByZXNwZWN0byBhIG90cm9zIGFjdGl2b3MgcmVhbGVzIGNvbW8gbGFzIG90cmFzIHByb3BpZWRhZGVzOg0KDQoxLiBOZWdvY2lvcyBwb3IgdHJhYmFqbyBwb3IgY3VlbnRhIHByb3BpYSAoKjIyJSB2cyA1JSopLg0KMi4gSm95YXMsIG9icmFzIGRlIGFydGXigKYgKCozNSB2cyAxMCUqKS4NCjMuIElubW9iaWxpYXJpYXMgKCo3MCB2cyAyMCopDQoNCg0KYGBge3IsIGVjaG8gPSBUUlVFLCB3YXJuaW5nPSBGQUxTRX0NCg0KcHJvcCA8LSBnZ3Bsb3QoKSArDQogIGdlb21fY29sKGRhdGEgPSBkYXRvc19lc3BfcHJvcCwgYWVzKHggPSByZW9yZGVyKFByb3BpZWRhZCwgdmFsdWUpLCB5ID0gdmFsdWUsIGZpbGwgPSBgUGVyY2VudGlsIGRlIHJlbnRhYCksIHBvc2l0aW9uID0gImRvZGdlIikgKw0KICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIkdyZWVucyIpICsgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoY29sb3VyID0gImJsYWNrIiksDQogICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gIndoaXRlIiksDQogICAgcGxvdC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAid2hpdGUiKSkgK2xhYnModGl0bGUgPSAiUHJvcGllZGFkIGFjdGl2b3MgcmVhbGVzICIsDQogICAgeCA9IE5VTEwsIHkgPSBOVUxMLCBjYXB0aW9uID0gIkZ1ZW50ZTogRWxhYm9yYWNpw7NuIHByb3BpYSBjb24gZGF0b3MgZGVsIEJhbmNvIGRlIEVzcGHDsWEiKStsYWJzKHkgPSAiVmFsb3JlIGVuICUiKSArIA0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwgbGVnZW5kLmRpcmVjdGlvbiA9ICJob3Jpem9udGFsIikNCg0KDQpgYGANCg0KPGNlbnRlcj48aW1nIHNyYz0iaW1hZ2VuZXMvcHJvcC5wbmciIHdpZHRoID0gIjExMDBweCIgLz48L2NlbnRlcj4NCg0KPGJyPg0KDQpQYXJhIGxhIGNvbXBvc2ljacOzbiBkZSBsb3MgYWN0aXZvcyBmaW5hbmNpZXJvcyBkaXNwb25lbW9zIGRlIHJlc3VsdGFkb3Mgc2ltaWxhcmVzLiBDb21vIHNlIHB1ZWRlIG9ic2VydmFyLCAqKmxhcyBmYW1pbGlhcyBzaXR1YWRhcyBlbiBsb3MgcHJpbWVyb3MgZGVjaWxlcyBlc3TDoW4gc2VzZ2FkYXMgaGFjaWEgbG9zIGFjdGl2b3MgZGUgcmVudGEgZmlqYSoqLiANCg0KYGBge3IsIGVjaG8gPSBUUlVFLCB3YXJuaW5nPSBGQUxTRX0NCg0KaW52IDwtIGdncGxvdCgpICsNCiAgZ2VvbV9jb2woZGF0YSA9IGRhdG9zX2VzcF9pbnYsIGFlcyggeCA9IHJlb3JkZXIgKEFjdF9yZWFsLCB2YWx1ZSksIHkgPSB2YWx1ZSwgZmlsbCA9IGBQRVJDRU5USUwgREUgUkVOVEFgKSwgcG9zaXRpb24gPSAiZG9kZ2UiKSArDQogIHNjYWxlX2ZpbGxfYnJld2VyKCkgKyANCiAgdGhlbWUocGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gIndoaXRlIikpICsNCiAgbGFicyh0aXRsZSA9ICJQb3JjZW50YWplIGRlIGFjdGl2b3MgZmluYW5jaWVyb3MiLA0KICAgIHggPSBOVUxMLCB5ID0gInZhbG9yZXMgZW4gJSIsIGNhcHRpb24gPSAiRnVlbnRlOiBFbGFib3JhY2nDs24gcHJvcGlhIGNvbiBkYXRvcyBkZWwgQmFuY28gZGUgRXNwYcOxYSAiKSArIA0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwgbGVnZW5kLmRpcmVjdGlvbiA9ICJob3Jpem9udGFsIikNCg0KYGBgDQoNCjxjZW50ZXI+PGltZyBzcmM9ImltYWdlbmVzL2ludi5wbmciIHdpZHRoID0gIjExMDBweCIgLz48L2NlbnRlcj4NCg0KPGJyPg0KDQpBIHRvZG8gZXN0bywgY2FiZSBkZXN0YWNhciwgcXVlIHBvciBub3JtYSBnZW5lcmFsLCBsb3MgaW5ncmVzb3MvZ2FzdG9zIGRlIGxhcyByZW50YXMgYWx0YXMgdGllbmVuIGxhIGNhcGFjaWRhZCBkZSBhZGFwdGFyc2UgbWVqb3IgYSDDqXBvY2FzIGRlIGluZmxhY2nDs24uIEVzdG8gZXMgZGViaWRvIGEgdmFyaWVkYWQgZGUgbW90aXZvcyBxdWUgYWZlY3RhbiBlbiBtYXlvciBtZWRpZGEgYSBsYXMgY2xhc2VzIG3DoXMgYmFqYXM7IG1lbm9yIHBvZGVyIGRlIG5lZ29jaWFjacOzbiBzYWxhcmlhbCwgbWVub3JlcyBzYWxhcmlvcywgZGlzcG9uZXIgZGUgbWF5b3JlcyBwcm9wb3JjacOzbiBkZSBnYXN0b3MgZmlqb3MgZGVwZW5kaWVudGVzIGRlIGxhIGluZmxhY2nDs24sIGV0Yy4NCg0KUXVlcmVtb3MgcmVtYXJjYXIgcXVlIGVzdGFzIGNvbmNsdXNpw7NuIG5vIGRlYmUgc2VyIGFwbGljYWRhIGEgb3RyYXMgZWNvbm9tw61hcywgbG9zIHJlc3VsdGFkb3MgZGVwZW5kZW4gZGUgY8OzbW8gZXMgbGEgcHJvcG9yY2nDs24gZGUgcG9zZXNpw7NuIGRlIGFjdGl2b3MgZGUgcmVudGEgZmlqYSB2cyByZW50YSB2YXJpYWJsZSBlbiBjYWRhIGVjb25vbcOtYSwgc3VtYWRvIGEgb3RyYXMgdmFyaWFibGVzIHF1ZSBwb3Igc2ltcGxpY2lkYWQgbm8gaGVtb3MgZW50cmFkbyBhIHZhbG9yYXIgZW4gcHJvZnVuZGlkYWQgY29tbyBiaWVuIHB1ZWRlIHNlciBsYSBlc3RydWN0dXJhIGRlbCBtZXJjYWRvIGRlIHRyYWJham8geSBsYSBpbmZsdWVuY2lhIHF1ZSBwdWVkYSB0ZW5lciBsYSBpbmZsYWNpw7NuIHNvYnJlIGVzdGEsIGVsIHJpZXNnbyBkaXZpc2EsIGVsIHZvbHVtZW4gZGUgcGFybywgZXRjLiAgUGVyw7IsIGJham8gZWwgc3VwdWVzdG8gZGUgQkNFICgqZGVsIHF1ZSB0b2RvcyBlc3BlcmVtb3MgcXVlIG5vIHZheWEgbWFsIGVuY2FtaW5hZG8qKSwgdW5hIGNvbmNsdXNpw7NuIGVzIGNsYXJhOyAgKiplbiBFc3Bhw7FhIGxhIGluZmxhY2nDs24gcGVyanVkaWNhIGVzcGVjaWFsbWVudGUgYSBsb3MgbcOhcyBwb2JyZXMqKi4NCg0KPGJyPg0KDQojIyMgNy4yIEVzdGltYWNpb25lcy4NCg0KDQojIyMjIDcuMi4xLiBQcmV2aXNpb25lcyBlbiBsYSBldm9sdWNpw7NuIGRlIGxhIGluZmxhY2nDs24gcG9yIGxhIE9DREUuDQoNCkxhcyBlc3RpbWFjaW9uZXMgZGUgbGEgT0NERSBzb2JyZSBsYSBldm9sdWNpw7NuIGRlIGxhIGluZmxhY2nDs24gZXN0aW1hIHF1ZSBzZSB2b2x2ZXLDoW4gYSBkYXRvcyBwb3IgZGViYWpvIGRlbCBvYmpldGl2byBkZWwgMiUsIHRhbnRvIHBhcmEgRXVyb3BhIGNvbW8gcGFyYSBFc3Bhw7FhLCBhIGZpbmFsZXMgZGVsIDIwMjIuIFNpIG5vIHNlIGN1bXBsZW4gbGFzIGhpcMOzdGVzaXMsICplc2NlbmFyaW8gbm8gZGVzY2FydGFibGUgeWEgcXVlIGVzdG9zIG9yZ2FuaXNtb3Mgc2UgaGFuIGNhcmFjdGVyaXphZG8gbXVjaGFzIHZlY2VzIHBvciBwcmVzZW50YXIgZXJyb3JlcyBlbiBzdXMgZXN0aW1hY2lvbmVzKiwgcG9kZW1vcyBlc3BlcmFyIHVuIHBlcsOtb2RvLCBkb25kZSBzZSBwcm9ycm9ndWUgbcOhcyBkZSB1biDDum5pY28gcGVyw61vZG8uIE5vIHNhYmVtb3MgcXXDqSBub3MgZGVwYXJhcsOhIGVsIGZ1dHVybywgIHBlcm8gdW5hIGNvc2EgcXVlZGEgY2xhcmEsIHNpIGxhcyBlc3RpbWFjaW9uZXMgbm8gc2UgY3VtcGxlbiwgbGEgYWx0YSBpbmZsYWNpw7NuIHNlcsOhIGRlc2dhcnJhZG9yYSBwYXJhIHVuYSBlY29ub23DrWEgZnLDoWdpbCBxdWUgc2UgZW5jdWVudHJhIGVuIHN1ICBzZW5kYSBkZSByZWN1cGVyYWNpw7NuIHBvc3QtY292aWQuIA0KDQpgYGB7ciwgZWNobyA9IFRSVUUsIHdhcm5pbmc9IEZBTFNFfQ0KDQoNCnByZWRpY2Npb25fZGYgPC0gcHJlZGljY2lvbl9pbmZsYWNpb24gJT4lDQogIGRwbHlyOjpzZWxlY3QoTE9DQVRJT04sIFRJTUUsIFZhbHVlKSAlPiUNCiAgbXV0YXRlKGZlY2hhID0gbHVicmlkYXRlOjp5cShUSU1FKSkgJT4lDQogIG11dGF0ZSh2YWx1ZSA9IHJvdW5kKFZhbHVlLCAyKSkgJT4lDQogIGRwbHlyOjpzZWxlY3QoLVRJTUUsLVZhbHVlKQ0KDQpwcmVkaWNjaW9uX2RmX2VhMTcgPC0gcHJlZGljY2lvbl9pbmZsYWNpb24gJT4lDQogIGRwbHlyOjpzZWxlY3QoTE9DQVRJT04sIFRJTUUsIFZhbHVlKSAlPiUNCiAgbXV0YXRlKGZlY2hhID0gbHVicmlkYXRlOjp5cShUSU1FKSkgJT4lDQogIG11dGF0ZSh2YWx1ZSA9IHJvdW5kKFZhbHVlLCAyKSkgJT4lDQogIGRwbHlyOjpzZWxlY3QoLVRJTUUsLVZhbHVlKSAlPiUNCiAgZmlsdGVyKExPQ0FUSU9OID09ICJFQTE3IikgDQoNCnByZWRpY2Npb25fZGZfZXNwIDwtIHByZWRpY2Npb25faW5mbGFjaW9uICU+JQ0KICBkcGx5cjo6c2VsZWN0KExPQ0FUSU9OLCBUSU1FLCBWYWx1ZSkgJT4lDQogIG11dGF0ZShmZWNoYSA9IGx1YnJpZGF0ZTo6eXEoVElNRSkpICU+JQ0KICBtdXRhdGUodmFsdWUgPSByb3VuZChWYWx1ZSwgMikpICU+JQ0KICBkcGx5cjo6c2VsZWN0KC1USU1FLC1WYWx1ZSkgJT4lDQogIGZpbHRlcihMT0NBVElPTiA9PSAiRVNQIikgDQogIA0KDQpnZyA8LSBnZ3Bsb3QoKSArDQogIA0KICBnZW9tX2xpbmUoZGF0YSA9IHByZWRpY2Npb25fZGYsIGFlcyhmZWNoYSwgdmFsdWUsIGNvbG9yID0gTE9DQVRJT04pLCBhbHBoYSA9IDAuMikgKw0KICBnZW9tX2xpbmUoZGF0YSA9IHByZWRpY2Npb25fZGZfZWExNywgYWVzKGZlY2hhLCB2YWx1ZSksIGNvbG9yPSAiIzAyODhkMSIsIHNpemUgPSAxLjUpICsNCiAgZ2VvbV9wb2ludChkYXRhID0gcHJlZGljY2lvbl9kZl9lYTE3LCBhZXMoZmVjaGEsIHZhbHVlKSwgY29sb3I9ICIjMDI4OGQxIiwgc2l6ZSA9IDMpICsNCiAgZ2VvbV90ZXh0KGRhdGEgPSBwcmVkaWNjaW9uX2RmX2VhMTcsIGFlcyhmZWNoYSwgdmFsdWUsIGxhYmVsID0gdmFsdWUsIHZqdXN0ID0gLTIsIGhqdXN0PSAwLjUpKSArIA0KICBnZW9tX3RleHQoZGF0YSA9IHByZWRpY2Npb25fZGZfZWExNywgYWVzKGZlY2hhLCB2YWx1ZSwgbGFiZWwgPSAiJSIpLCB2anVzdCA9IC0yLCBoanVzdD0gLTEuMykgKw0KICANCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMiwNCiAgICAgICAgICAgICBzaXplID0gMS41LA0KICAgICAgICAgICAgIGNvbG91ciA9ICIjMmU3ZDMyIiwNCiAgICAgICAgICAgICBsaW5ldHlwZSA9ICJkYXNoZWQiKSArDQogIA0KICBhbm5vdGF0ZSgicmVjdCIsDQogICAgICAgICAgIHhtaW4gPSBhcy5EYXRlKCIyMDIxLTA5LTAxIiksDQogICAgICAgICAgIHhtYXggPSBhcy5EYXRlKCIyMDIxLTExLTAxIiksDQogICAgICAgICAgIHltaW4gPSAtSW5mLA0KICAgICAgICAgICB5bWF4ID0gSW5mLA0KICAgICAgICAgICBhbHBoYSA9IDAuNCwNCiAgICAgICAgICAgZmlsbCA9ICJwaW5rIikgKw0KICANCiAgYW5ub3RhdGUoZ2VvbSA9ICJsYWJlbCIsDQogICAgICAgICAgIHg9IGFzLkRhdGUoIjIwMjMtMDctMDEiKSwNCiAgICAgICAgICAgeSA9IDEsDQogICAgICAgICAgIGxhYmVsID0gIlpvbmEgbW9udGVhcmlhIEV1cm9wZWEiLA0KICAgICAgICAgICBzaXplID0gNCwNCiAgICAgICAgICAgY29sb3IgPSAiIzAyODhkMSIpICArIA0KICANCiAgYW5ub3RhdGUoZ2VvbSA9ICJ0ZXh0IiwNCiAgICAgICAgICAgeD0gYXMuRGF0ZSgiMjAyMC0wNC0wMSIpLA0KICAgICAgICAgICB5ID0gMi4yLA0KICAgICAgICAgICBsYWJlbCA9ICJPYmpldGl2byBpbmZsYWNpb24gMiUiLA0KICAgICAgICAgICBzaXplID0gNCwNCiAgICAgICAgICAgY29sb3IgPSAiYmxhY2siKSAgKyANCiAgDQogIHNjYWxlX3hfZGF0ZShkYXRlX2xhYmVscz0iJVktJW0iLGRhdGVfYnJlYWtzICA9IjMgbW9udGhzIikgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCBoanVzdCA9IDEpKSArIA0KICB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAid2hpdGUiKSwNCiAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsIGxlZ2VuZC5kaXJlY3Rpb24gPSAiaG9yaXpvbnRhbCIpICsNCiAgbGFicyh5ID0gTlVMTCwgY29sb3VyID0gTlVMTCkgKyANCiAgdGhlbWUoYXhpcy50aWNrcyA9IGVsZW1lbnRfbGluZShsaW5ldHlwZSA9ICJibGFuayIpLA0KICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KGNvbG91ciA9ICJ3aGl0ZSIpKSArIA0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSBOVUxMKSArIA0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpKw0KICBsYWJzKHggPSBOVUxMKQ0KICANCg0KDQoNCg0KDQpnZzEgPC0gZ2dwbG90KCkgKw0KICBnZW9tX2xpbmUoZGF0YSA9IHByZWRpY2Npb25fZGYsIGFlcyhmZWNoYSwgdmFsdWUsIGNvbG9yID0gTE9DQVRJT04pLCBhbHBoYSA9IDAuMikgKw0KICBnZW9tX2xpbmUoZGF0YSA9IHByZWRpY2Npb25fZGZfZXNwLCBhZXMoZmVjaGEsIHZhbHVlKSwgY29sb3I9ICIjYjcxYzFjIiwgc2l6ZSA9IDEuNSkgKw0KICBnZW9tX3BvaW50KGRhdGEgPSBwcmVkaWNjaW9uX2RmX2VzcCwgYWVzKGZlY2hhLCB2YWx1ZSksIGNvbG9yPSAiI2I3MWMxYyIsIHNpemUgPSAzKSArDQogIGdlb21fdGV4dChkYXRhID0gcHJlZGljY2lvbl9kZl9lc3AsIGFlcyhmZWNoYSwgdmFsdWUsIGxhYmVsID0gdmFsdWUsIHZqdXN0ID0gLTIsIGhqdXN0PSAwLjUpKSArIA0KICBnZW9tX3RleHQoZGF0YSA9IHByZWRpY2Npb25fZGZfZXNwLCBhZXMoZmVjaGEsIHZhbHVlLCBsYWJlbCA9ICIlIiksIHZqdXN0ID0gLTIsIGhqdXN0PSAtMS4zKSArDQogIA0KICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAyLA0KICAgICAgICAgICAgIHNpemUgPSAxLjUsDQogICAgICAgICAgICAgY29sb3VyID0gIiMyZTdkMzIiLA0KICAgICAgICAgICAgIGxpbmV0eXBlID0gImRhc2hlZCIpICsNCiAgDQogIGFubm90YXRlKCJyZWN0IiwNCiAgICAgICAgICAgeG1pbiA9IGFzLkRhdGUoIjIwMjEtMDktMDEiKSwNCiAgICAgICAgICAgeG1heCA9IGFzLkRhdGUoIjIwMjEtMTEtMDEiKSwNCiAgICAgICAgICAgeW1pbiA9IC1JbmYsDQogICAgICAgICAgIHltYXggPSBJbmYsDQogICAgICAgICAgIGFscGhhID0gMC40LA0KICAgICAgICAgICBmaWxsID0gInBpbmsiKSArDQogIA0KICBhbm5vdGF0ZShnZW9tID0gImxhYmVsIiwNCiAgICAgICAgICAgeD0gYXMuRGF0ZSgiMjAyMy0wNy0wMSIpLA0KICAgICAgICAgICB5ID0gMSwNCiAgICAgICAgICAgbGFiZWwgPSAiRXNwYcOxYSIsDQogICAgICAgICAgIHNpemUgPSA0LA0KICAgICAgICAgICBjb2xvciA9ICIjYjcxYzFjIikgICsgDQogIA0KICBhbm5vdGF0ZShnZW9tID0gInRleHQiLA0KICAgICAgICAgICB4PSBhcy5EYXRlKCIyMDIwLTA0LTAxIiksDQogICAgICAgICAgIHkgPSAyLjIsDQogICAgICAgICAgIGxhYmVsID0gIk9iamV0aXZvIGluZmxhY2lvbiAyJSIsDQogICAgICAgICAgIHNpemUgPSA0LA0KICAgICAgICAgICBjb2xvciA9ICJibGFjayIpICArIA0KICANCiAgc2NhbGVfeF9kYXRlKGRhdGVfbGFiZWxzPSIlWS0lbSIsZGF0ZV9icmVha3MgID0iMyBtb250aHMiKSArDQogIA0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCBoanVzdCA9IDEpKSArIA0KICAgICAgdGhlbWUocGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gIndoaXRlIiksDQogIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwgbGVnZW5kLmRpcmVjdGlvbiA9ICJob3Jpem9udGFsIikgKw0KICBsYWJzKHkgPSBOVUxMLCBjb2xvdXIgPSBOVUxMKSArIA0KICB0aGVtZShheGlzLnRpY2tzID0gZWxlbWVudF9saW5lKGxpbmV0eXBlID0gImJsYW5rIiksDQogICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoY29sb3VyID0gIndoaXRlIikpICsgDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9IE5VTEwpICsgDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikrDQogIGxhYnMoeCA9IE5VTEwpDQoNCg0KDQoNCg0KICANCmBgYA0KPGNlbnRlcj48aW1nIHNyYz0iaW1hZ2VuZXMvcHJlZGljY2lvbl9ldXJvcGEuanBlZyIgd2lkdGggPSAiNjAwcHgiIC8+PC9jZW50ZXI+DQo8Y2VudGVyPjxpbWcgc3JjPSJpbWFnZW5lcy9wcmVkaWNjaW9uX2VzcGFuYS5qcGVnIiB3aWR0aCA9ICI2MDBweCIgLz48L2NlbnRlcj4NCg0KPGJyPg0KDQoNCiMjIyMgNy4yLjIuIENyZWNpbWllbnRvIGRlbCBQSUIuDQoNCkxhcyBjb25jbHVzaW9uZXMgZXh0cmHDrWRhcyBwYXJhIGxhcyBlc3RpbWFjaW9uZXMgZGUgaW5mbGFjacOzbiBzw7NuIGFwbGljYWJsZXMgYSBsYXMgZGVsIFBJQiwgZXMgZGVjaXIsICoqc2kgbm9zIHNpdHVhbW9zIGVuIGVsIG1lam9yIGRlIGxvcyBjYXNvcyoqLCB0b2RvcyBsb3MgaW5kaWNhZG9yZXMgYXB1bnRhbiBxdWUgaGFzdGEgYWwgbWVub3MgdW4gYcOxbywgbm8gdmFtb3MgYSBlc3RhYmlsaXphciBsYSBzaXR1YWNpw7NuLCBwb3IgdGFudG8sICBzZXLDrWEgcmF6b25hYmxlIHBlbnNhciBxdWUgZWwgMjAyMiB2YSBzZXIgdW4gYcOxbyBkZSBkdXJhIHJlY3VwZXJhY2nDs24gZWNvbsOzbWljYSBwYXJhIGxhcyBwcmluY2lwYWxlcyBlY29ub23DrWFzLCBlc3BlY2lhbG1lbnRlIGVuIGFxdWVsbGFzIHF1ZSB5YSB0aWVuZW4gcHJvYmxlbWFzIGRlIGJhc2UgYW50ZXMgZGVsIGluaWNpbyBkZSBsYSBlc2NhbGFkYSBlbiBwcmVjaW9zLCBjb21vIGJpZW4gcHVlZGUgc2VyIGxhIGVzcGHDsW9sYS4gDQoNCmBgYHtyIGVjaG89VFJVRSwgd2FybmluZz1GQUxTRX0NCg0KY3JlY2ltaWVudG9fZGYgPC0gY3JlY2ltaWVudG8gJT4lDQogIGRwbHlyOjpzZWxlY3QoTE9DQVRJT04sIFRJTUUsIFZhbHVlKSAlPiUNCiAgbXV0YXRlKGZlY2hhID0gbHVicmlkYXRlOjp5cShUSU1FKSkgJT4lDQogIG11dGF0ZSh2YWx1ZSA9IHJvdW5kKFZhbHVlLCAyKSkgJT4lDQogIGZpbHRlcihMT0NBVElPTiAlaW4lIGMoIkVTUCIsIkVBMTciKSkgJT4lDQogIGRwbHlyOjpzZWxlY3QoLVRJTUUsLVZhbHVlKQ0KDQpjcmVjaW1pZW50byA8LSBnZ3Bsb3QoY3JlY2ltaWVudG9fZGYsIGFlcyhmZWNoYSx2YWx1ZSwgY29sb3I9IExPQ0FUSU9OKSkgKw0KICBnZW9tX2xpbmUoc2l6ZT0yLCBsaW5ldHlwZT03KSArDQogIHNjYWxlX3hfZGF0ZShkYXRlX2xhYmVscz0iJVktJW0iLGRhdGVfYnJlYWtzICA9IjMgbW9udGhzIikgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCBoanVzdCA9IDEpKSArIA0KICBzY2FsZV9jb2xvcl9tYW51YWwoYnJlYWtzID0gYygiRVNQIiwiRUExNyIpLHZhbHVlcyA9IGMoIiNFMDQ2NDQiLCIjN0NDQ0U1IikpICsNCiAgZmFjZXRfd3JhcCgNCiAgICB2YXJzKExPQ0FUSU9OKSwgbnJvdyA9IDIsIG5jb2wgPSAxKSArDQogIGFubm90YXRlKCJyZWN0IiwNCiAgICAgICAgICAgeG1pbiA9IGFzLkRhdGUoIjIwMjAtMDEtMDEiKSwNCiAgICAgICAgICAgeG1heCA9IGFzLkRhdGUoIjIwMjAtMDctMDEiKSwNCiAgICAgICAgICAgeW1pbiA9IC1JbmYsDQogICAgICAgICAgIHltYXggPSBJbmYsDQogICAgICAgICAgIGFscGhhID0gMC40LA0KICAgICAgICAgICBmaWxsID0gImdyZXkiKSArIA0KICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAxMDAsDQogICAgICAgICAgICAgc2l6ZSA9IDEsDQogICAgICAgICAgICAgY29sb3VyID0gImdyZXkiLA0KICAgICAgICAgICAgIGxpbmV0eXBlID0gImRhc2hlZCIpICsNCiAgDQogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUoY29sb3VyID0gImdyYXk5MCIpLA0KICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUoY29sb3VyID0gTkEpLA0KICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLA0KICAgICAgICBmYWNlID0gImJvbGQiKSwgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gTkEpLA0KICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgKw0KICBsYWJzKHRpdGxlID0gIlByZWRpY2Npw7NuIGRlIGNyZWNpbWllbnRvIFBJQiBFdXJvem9uYSIsDQogICAgeCA9IE5VTEwsIHkgPSBOVUxMLCBjb2xvdXIgPSBOVUxMLCBzdWJ0aXRsZSA9ICJBw7FvIDIwMTkgZW4gYmFzZSAxMDAiLA0KICAgIGNhcHRpb24gPSAiRnVlbnRlOkVsYWJvcmFjacOzbiBwcm9waWEgY29uIGRhdG9zIGRlIGxhIE9DREUuIikgKw0KICB0aGVtZShzdHJpcC5iYWNrZ3JvdW5kID1lbGVtZW50X3JlY3QoZmlsbD0iIzQyNDI1NCIpKSArDQogIHRoZW1lKHN0cmlwLnRleHQgPSBlbGVtZW50X3RleHQoY29sb3VyID0gJ3doaXRlJykpICsNCiAgdGhlbWUoc3RyaXAudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gIDE1KSkNCg0KY3JlY2ltaWVudG8NCg0KYGBgDQoNCjxicj4NCg0KDQojIyMgNy4zIMK/Q29tbyBzZSBwcmV2ZWUgYWN0dWFyPw0KDQpBdW5xdWUgZXhpc3RlIHVuIGZ1ZXJ0ZSBkZWJhdGUgZGVudHJvIGRlIGxhIGRvY3RyaW5hIGVjb27Ds21pY2Egc29icmUgc2kgZWwgQmFuY28gQ2VudHJhbCBFdXJvcGVvIChCQ0UpIGRlYmUgZW1wZXphciBhIHJldGlyYXIgZXN0w61tdWxvcywgY29uIGxhcyBkdXJhcyBpbXBsaWNhY2lvbmVzIHF1ZSBlc3RvIHB1ZWRlIHRlbmVyIHBhcmEgbGFzIGVjb25vbcOtYXMgZW5kZXVkYWRhcyBjb21vIGxhIGVzcGHDsW9sYSBvIGxhIGl0YWxpYW5hLCBsYSBlc3RyYXTDqWdpYSBhZG9wdGFkYSBwb3IgbGFzIGF1dG9yaWRhZGVzIG1vbmV0YXJpYXMgZXVyb3BlYXMgYWwgbW9tZW50byBkZSBlc2NyaWJpciBlc3RlIGFydMOtY3VsbyBlcyBjbGFyYSwgbm8gaGFicsOhIChwb3IgZWwgbW9tZW50bykgcmVkdWNjacOzbiBkZSBsb3MgZXN0w61tdWxvcyBtb25ldGFyaW9zLiBTb2JyZSBlc3RhIGzDrW5lYSB5YSBub3MgYXZhbnphYmEgZWwgZGlhcmlvIGVjb27Ds21pY28gZnJhbmPDqXMgKkxlcyBFY2hvcyosIGVuIHN1IGVudHJldmlzdGEgYWwgKnZpY2VwcmVzaWRlbnRlIGRlbCBCQ0UgTHVpcyBkZSBHdWluZG9zKiA6DQoNCj4g4oCcRGVqYW1vcyBjbGFybyBxdWUgY29tZW56YXJlbW9zIGEgc3ViaXIgbG9zIHRpcG9zIHBvY28gZGVzcHXDqXMgZGUgaGFiZXIgZmluYWxpemFkbyBudWVzdHJhcyBjb21wcmFzIG5ldGFzIGRlIGFjdGl2b3MuIENvbmbDrW8gZW4gcXVlIGVzYXMgY29tcHJhcyBuZXRhcyBjb250aW51YXLDoW4gZHVyYW50ZSBlbCBwcsOzeGltbyBhw7Fv4oCdDQoNCkVzdGEgZXN0cmF0w6lnaWEsIHF1ZSB5YSB0aWVuZSBtdWNob3MgZGV0cmFjdG9yZXMsIGVzcGVjaWFsbWVudGUgbGFzIGVjb25vbcOtYXMgcXVlIHByZXNlbnRhbiBtYXlvcmVzIGRhdG9zIGluZmxhY2nDs24sIHBvZHLDrWFtb3MgZGVmaW5pcmxhIGNvbW8gcmF6b25hYmxlIHBvciB2YXJpZWRhZCBkZSByYXpvbmVzOg0KDQoxLiBMYXMgcHJpbmNpcGFsZXMgY2F1c2FzIGRlIGluZmxhY2nDs24gbm8gc2UgZGViZW4gYSBsYSBwb2zDrXRpY2EgbW9uZXRhcmlhIGxsZXZhZGEgYSBjYWJvIHBvciBlbCBCQ0U6IExhIGRpZmVyZW5jaWEgZW50cmUgaW5mbGFjacOzbiBnZW5lcmFsIHkgc3VieWFjZW50ZSAoYSBqdWljaW8gZGUgbG9zIGF1dG9yZXMpIGVzIGJhc3RhbnRlIGdyYW5kZS4gQ29tbyBoZW1vcyBtb3N0cmFkbyBtZWRpYW50ZSBsb3MgZG9zIMO6bHRpbW9zIGdyw6FmaWNvcywgZGV0csOhcyBkZSBlc3RlIGF1bWVudG8gZXN0w6FuIGxvcyBzb3NwZWNob3NvcyBoYWJpdHVhbGVzIGRlIGxvcyDDumx0aW1vcyBtZXNlczogZWxlY3RyaWNpZGFkIGUgaGlkcm9jYXJidXJvcy4gRW4gdW5hIHBhbGFicmEsICoqbGEgZW5lcmfDrWEqKi4gUG9yIHRhbnRvLCBkZWxhbnRlIGRlIGVzdGUgcHJvYmxlbWEgZGUgb2ZlcnRhLCBhbCBxdWUgdGFtYmnDqW4gdGVuZW1vcyBxdWUgc3VtYXJsZSBsYSBmYWx0YSBkZSBtaWNyb3Byb2Nlc2Fkb3JlcywgZW50cmUgb3Ryb3MgcHJvZHVjdG9zIGludGVybWVkaW9zLCBwb2NvIHNlIHB1ZWRlIGhhY2VyIGFjdHVhbmRvIHNvYnJlIGxhIGRlbWFuZGEgKHJldGlyYW5kbyBlc3TDrW11bG9zIG1vbmV0YXJpb3MpLg0KDQoyLiBBZGljaW9uYWxtZW50ZSwgZWwgcHJvYmxlbWEgaW5mbGFjaW9uaXN0YSBsbGVnYSBlbiBlbCAqKnBlb3IgbW9tZW50byBwb3NpYmxlKiouIFBvciB1bmEgcGFydGUsIGVsIG5pdmVsIGRlIGVuZGV1ZGFtaWVudG8gZGUgZ3JhbiBwYXJ0ZSBkZSBsYXMgZWNvbm9tw61hcyBxdWUgY29uZm9ybWFuIGxhIGV1cm96b25hIGRpc3BvbmVuIGRlIHJhdGlvcyBkZSBEZXVkYS9QSUIgKHbDqWFzZSBncsOhZmljbyBkZSBlbmRldWRhbWllbnRvKSBzdXBlcmlvcmVzIGFsIDEwMCUuIEVzdG8gc3Vwb25lIHVuYSAqcmVzdHJpY2Npw7NuIGltcG9ydGFudGUqIGEgbGEgaG9yYSBkZSB0cmF0YXIgY29udHJvbGFyIGxhIGluZmxhY2nDs24gbWVkaWFudGUgZWwgYXVtZW50byBkZSB0aXBvcyBkZSBpbnRlcsOpcywgeWEgcXVlLCBwdWVkZSBzdXBvbmVyIHVuIGF1bWVudG8gZW4gZWwgY29zdGUgYW1vcnRpemFjacOzbiBkZSBsYSBkZXVkYSBxdWUgcmFsZW50aXphIGxhIHJlY3VwZXJhY2nDs24gZWNvbsOzbWljYSBwb3N0LXBhbmRlbWlhLiBQb3Igb3RyYSBwYXJ0ZSwgdGFtYmnDqW4gZXMgcG9jbyBwcm9iYWJsZSBxdWUgZWwgQkNFIHJldGlyZSBkZSBmb3JtYSBhbnRpY2lwYWRhIGxvcyBlc3TDrW11bG9zIG1vbmV0YXJpb3MsIG3DoXMgdG9kYXbDrWEgY29uIGxhIGlycnVwY2nDs24gZGUgbGEgdmFyaWFudGUgw7NtaWNyb24sIHF1ZSBzdXBvbmUgdW4gcmllc2dvIGFkaWNpb25hbCBwYXJhIGVsIGNyZWNpbWllbnRvIGVjb27Ds21pY28NCg0KPGJyPg0KDQpgYGB7ciBlY2hvPVRSVUUsIHdhcm5pbmc9RkFMU0V9DQoNCnAgPC0gZ2dwbG90KCkgKw0KICBnZW9tX2NvbChkYXRhID0gZGV1ZGFfZXUsIGFlcyh4ID0gcmVvcmRlcihnZW8sIC12YWx1ZSksIHkgPSB2YWx1ZSwgZmlsbCA9IHZhbHVlKSkgKw0KICBzY2FsZV9maWxsX2NvbnRpbnVvdXMobG93PSIjODFGN0YzIiwgaGlnaD0iIzBCNjE1RSIpICsNCiAgY29vcmRfZmxpcCgpICsNCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMC42LA0KICAgICAgICAgICAgIHNpemUgPSAwLjI1LA0KICAgICAgICAgICAgIGNvbG91ciA9ICJibHVlIiwNCiAgICAgICAgICAgICBsaW5ldHlwZSA9ICJkYXNoZWQiKSArDQogIGxhYnMoeCA9IE5VTEwpICsNCiAgbGFicyAoeSA9IE5VTEwpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6cGVyY2VudCkgKw0KICB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAidHJhbnNwYXJlbnQiKSkgKw0KICBsYWJzKHRpdGxlID0gIkRldWRhL1BJQiAyMDIwLiIsDQogICAgICAgY2FwdGlvbiA9ICJGdWVudGU6IEVsYWJvcmFjacOzbiBwcm9waWEgY29uIGRhdG9zIGRlIEV1cm9zdGF0IikgKw0KICBndWlkZXMgKGZpbGwgPSBGQUxTRSkNCg0KDQpwDQoNCmBgYA0KDQpFbiByZXN1bWVuLCBwYXJhIHNhYmVyIHNpIGVsIGNhbXBvIHBhcmEgdG9tYXIgZGVjaXNpb25lcyBzZSBlbnNhbmNoYSBlbiBlbCBmdXR1cm8gY2VyY2Fubywgc2UgdGVuZHLDoSBxdWUgZGVzcGVqYXIgbGEgaW5jw7Nnbml0YSBkZSAqKmN1w6FudG8gdGllbXBvIHZhbiBhIG1hbnRlbmVyc2UgbG9zIHByZWNpb3MgYSBlc3RhIGFsdHVyYSoqIHkgY8OzbW8gc2UgaW1wbGVtZW50YSwgKmVuIGNhc28gZGUgc2VyIG5lY2VzYXJpbyosIGVzdGUgdGlwbyBkZSBwb2zDrXRpY2Egc2luIHF1ZSDDqXN0YSBvY2FzaW9uZSB1bmEgZGlzdG9yc2nDs24gZGUgZXhwZWN0YXRpdmFzIHF1ZSBsYXN0cmUgY29uc2lkZXJhYmxlbWVudGUgZWwgY3JlY2ltaWVudG8gZWNvbsOzbWljby4gRXMgZGVjaXIgbGEgdmFyaWFibGUgY2xhdmUgdmEgYSBzZXIgZWwgdGllbXBvLiBVbiBkYXRvIGltcG9ydGFudGUgYWNlcmNhIGRlIGVzdGUgdGVtYSBub3MgbGEgZGEgbGEgw7psdGltYSBydWVkYSBkZSBwcmVuc2EgZGVsIHByZXNpZGVudGUgZGVsIGxhIFJlc2VydmEgRmVkZXJhbCAoRkVEKSAqKkplcm9tZSBQb3dlbGwqKiBlbCBwYXNhZG8gMzAgZGUgTm92aWVtYnJlLCBwYXJhIGxhIEZFRCwgZGVzcHVlcyBkZSB1bmEgZXhoYXVzdGl2YSByZXVuacOzbiwgYWNhYmFuIGRlIGRldGVybWluYXIgcXVlIGVtcGV6YXJhbiBhIHJldGlyYXIgZXN0w61tdWxvcyBtb25ldGFyaW9zIHBvcnF1ZSBpbnRlcnByZXRhbiBxdWUgbGEgaW5mbGFjacOzbiAqKnlhIG5vIHNlIHB1ZWRlIGNvbnNpZGVyYXIgdW4gZmVuw7NtZW5vIHRyYW5zaXRvcmlvKiouIA0KDQo8YnI+DQoNCjo6OiBjb2x1bW5zDQoNCmBgYHtyLCBlY2hvID0gRkFMU0UsIG91dC53aWR0aCA9ICI2MCUifQ0KdHdlZXRybWQ6OnR3ZWV0X2VtYmVkKCJodHRwczovL3R3aXR0ZXIuY29tL1NjaHVsZGVuc3VlaG5lci9zdGF0dXMvMTQ2NTcwOTU2NTY5ODE0MjIxNz9zPTIwIiwgdGhlbWUgPSAibGlnaHQiLCBhbGlnbiA9ICJjZW50ZXIiLCBkbnQgPSBUUlVFLCBtYXh3aWR0aCA9IDQwMCkNCmBgYA0KOjo6DQoNCjxicj4NCg0KU2FsdmFuZG8gbGFzIGRpc3RhbmNpYXMsIHlhIHF1ZSBsb3MgZGF0b3MgZGUgaW5mbGFjacOzbiBzw7NuIG3DoXMgcHJlb2N1cGFudGVzIGVuIGxhIGVjb25vbcOtYSBhbWVyaWNhbmEsIHNpIGxvIHBvZGVtb3MgY29uc2lkZXJhciBjb21vIHVuIGNhbWJpbyBkZSB0ZW5kZW5jaWEgcXVlIG5vcyBwdWVkZSBlbXBlemFyIGEgIGludml0YXIgYSBsYSByZWZsZXhpw7NuIGFjZXJjYSBkZSBsYSAqdHJhbnNpdG9yaWVkYWQqIGRlIGxhIGluZmxhY2nDs24uIFBvciBzdSBwYXJ0ZSwgZWwgYmFuY28gY2VudHJhbCBzaWd1ZSBhcG9zdGFuZG8gYSBxdWUgbGEgc3ViaWRhIGVzIGNveXVudHVyYWwgeSBxdWUgZW50cmFkbyAyMDIyIGxhIGluZmxhY2nDs24gcGVyZGVyw6EgZnVlbGxlLiBBdW5xdWUgbm8gZGlzcG9uZW1vcyBkZSBsYSBldmlkZW5jaWEgZW1ww61yaWNhIHN1ZmljaWVudGUgcGFyYSBjb250cmFzdGFyIGxhIHZhbGlkZXogZGUgbGEgaGlww7N0ZXNpcyBkZWwgQkNFLCBjb25zaWRlcmFtb3MgcXVlIGxhIHNvbHVjacOzbiBubyBwYXNhIHPDs2xvIHBvciByZWR1Y2lyIGxvcyBlc3TDrW11bG9zIG1vbmV0YXJpb3MsIHBvcnF1ZSwgY29tbyBoZW1vcyB2aXN0bywgZWwgcHJpbmNpcGFsIHByb2JsZW1hIHF1ZSBleHBlcmltZW50YSBsYSBlY29ub23DrWEgZXVyb3BlYSB5IG11bmRpYWwgZXMgdW4gKipwcm9ibGVtYSBkZSBvZmVydGEqKi4gTm9zIGhlbW9zIHRvcGFkbyBjb24gY3VlbGxvcyBkZSBib3RlbGxhIGVuIGRpdmVyc2FzIHBhcnRlcyBkZSBudWVzdHJhIGVzdHJ1Y3R1cmEgZGUgcHJvZHVjY2nDs24gKGxvcyBtaWNyb2NoaXBzLCBlbCBnYXMsIGVsIGNhcmLDs24sIGVsIHRyYW5zcG9ydGUsIGxvcyBjb250ZW5lZG9yZXMsIGxvcyB0cmFiYWphZG9yZXMgYmllbiBmb3JtYWRvc+KApiksIGVuIHVuIGNvbnRleHRvIGRvbmRlIHNlIGhhbiBwcmVzZW50YWRvIGxvcyBtYXlvcmVzIHBhcXVldGVzIGRlIGVzdMOtbXVsbyBtb25ldGFyaW9zIGVuIGxhIGhpc3RvcmlhLiBTaSBubyBzb2x1Y2lvbmFtb3MgZWwgcHJvYmxlbWEgZGUgZm9ybWEgaW5tZWRpYXRhLCB0YW50byBwb3IgZWwgbGFkbyBkZSBsYSBvZmVydGEgY29tbyBwb3IgZWwgZGUgbGEgZGVtYW5kYSwgcG9kZW1vcyB0ZW5lciB1biBwcm9ibGVtYSBkZSBkZXNjb250cm9sIGluZmxhY2lvbmFyaW8gcXVlIGNhZGEgdmV6IHRlbmRyw6EgdW5hIG1heW9yIGNvbXBsZWppZGFkIGEgbGEgaG9yYSBkZSBpbXBsZW1lbnRhciBzb2x1Y2lvbmVzLiBMYSBjb25jbHVzacOzbiBlcyBjbGFyYSwgKipkZWJlbW9zIGVtcGV6YXIgYSB0b21hcm5vcyBlbiBzZXJpbyBsYSBpbmZsYWNpw7NuKiouDQoNCjxicj4NCg0KIyMgOC4gQ29uY2x1c2lvbmVzDQoNCkxhIGVsYWJvcmFjacOzbiBkZWwgYXJ0w61jdWxvIG5vcyBoYSBzZXJ2aWRvIHBhcmEgYXByZW5kZXIgZW4gZGl2ZXJzb3MgYXNwZWN0b3MuIFBvciB1bmEgcGFydGUsIGhlbW9zIG1lam9yYWRvIG51ZXN0cmFzIGNhcGFjaWRhZGVzIGRlIGLDunNxdWVkYSB5IGFuw6FsaXNpcyBkZSBkYXRvcyAoYXVucXVlICBoZW1vcyBkZSByZWNvbm9jZXIgbGEgbcOhcyBjb3N0b3NhIGRlIGxhIGRpc2NpcGxpbmEg4oCcZGF0YSBzY2llbmNl4oCdKSwgcG9yIG90cmEgcGFydGUsIGhlbW9zIHByb2Z1bmRpemFkbyBtw6FzIGVuIG51ZXN0cm8gY29ub2NpbWllbnRvIGRlIFIuU3R1ZGlvLiBTaSBtaXJhbW9zIGVuIHJldHJvc3BlY3RpdmEsIGxvcyB0cmVzIGF1dG9yZXMgY29uc2lkZXJhbW9zIHF1ZSBSLlN0dWRpbyBlcyB1bmEgaGVycmFtaWVudGEgcG90ZW50ZSBwYXJhIHRyYWJhamFyIGNvbiBkYXRvcywgbnVuY2Egbm9zIGhhYnLDrWFtb3MgaW1hZ2luYWRvIHRvZGFzIGxhcyBvcGNpb25lcyBxdWUgbm9zIHB1ZWRlIGRhciBsYSBwcm9ncmFtYWNpw7NuIHkgZW4gZXNwZWNpYWwgbGEgcHJlc2VudGFjacOzbiBkZSBpbmZvcm1lcyBtZWRpYW50ZSB1biBmaWNoZXJvIFJtYXJja2Rhd24uIENyZWVtb3MgcXVlIHPDrSBoZW1vcyBjb25zZWd1aWRvIG51ZXN0cm9zIG9iamV0aXZvcyBlc3RhYmxlY2lkb3MgZWwgcHJpbWVyIGTDrWEgcXVlIG5vcyBwdXNpbW9zIGVuIG1hcmNoYSwgZGVzYXJyb2xsYXIgdGFudG8gbG9zIGNvbm9jaW1pZW50b3MgZWNvbsOzbWljb3MgY29tbyBsb3MgYXByZW5kaWRvcyBtZWRpYW50ZSBlbCBjdXJzbyBkZSBSLXN0dWRpby4gU2FsdmFuZG8gbGEgZGlzdGFuY2lhLCBzaSBoZW1vcyBjb25zZWd1aWRvIHJlYWxpemFyIGdyw6FmaWNvcywgYmFqbyBudWVzdHJvIGNyaXRlcmlvLCBzdWZpY2llbnRlbWVudGUgZWxlZ2FudGVzIGNvbW8gbG9zIGNvbXBhcnRpZG9zIHBvciBkaWZlcmVudGVzIGVjb25vbWlzdGFzIHF1ZSBlbGFib3JhbiBzdXMgcHJvcGlvcyBncsOhZmljb3MgZW4gc3UgbGFib3IgZGUgZGl2dWxnYWNpw7NuLiDDiXMgdW4gdGVtYSBiYXN0YW50ZSBjb21wbGVqbywgeSBxdWUgaW52aXRhIGEgbGEgcHJvZnVuZGEgcmVmbGV4acOzbiB5IGVzdHVkaW8sIHBlcm8sIHNpbiBwZWNhciBkZSBhbWJpY2lvc29zLCBjcmVlbW9zIHF1ZSBzw60gaGVtb3MgYXBvcnRhZG8gbnVlc3RybywgaW5zaXN0bywgcGVxdWXDscOtc2ltbyBncmFuaXRvIGRlIGFyZW5hIGEgbW9zdHJhciB1biBwcm9ibGVtYSBlY29uw7NtaWNvIG1lZGlhbnRlIGVsIGFuw6FsaXNpcyBkZSBkYXRvcyB5IGxhIGVsYWJvcmFjacOzbiBkZSBncsOhZmljb3MgZGUgdW5hIGZvcm1hIHlhIG3DoXMgcHJvZmVzaW9uYWxpemFkYS4NCg0KPGJyPg0KDQojIyA5LiBSZWZlcmVuY2lhcw0KDQpQYXJhIGxhIHJlYWxpemFjacOzbiBkZSBsb3MgZ3LDoWZpY29zIHkgbG9zIGNvbWVudGFyaW9zIHBlcnRpbmVudGVzIG5vcyBoZW1vcyBiYXNhZG8gZW4gbGEgaW5mb3JtYWNpw7NuIHF1ZSB2YW1vcyBhIGV4cG9uZXIgZW4gbG9zIHNpZ3VpZW50ZXMgcMOhcnJhZm9zLg0KDQpQYXJhIHBvZGVyIHJlYWxpemFyIGxvcyBjb21lbnRhcmlvcywgbm9zIGhlbW9zIGZvcm1hZG8gY29uIGFydMOtY3Vsb3MgY29tbyBsb3Mgc2lndWllbnRlczoNCg0KLSA8YSBocmVmPSJodHRwczovL3d3dy5lbGVjb25vbWlzdGEuZXMvZWNvbm9taWEvYW1wLzExNTAxMzY5L1Bvd2VsbC1hbGVydGEtZGUtcXVlLXRyYXMtT21uaWNyb24tbGEtaW5mbGFjaW9uLXlhLW5vLWVzLXRyYW5zaXRvcmlhIj5odHRwczovL3d3dy5lbGVjb25vbWlzdGEuZXMvZWNvbm9taWEvYW1wLzExNTAxMzY5L1Bvd2VsbC1hbGVydGEtZGUtcXVlLXRyYXMtT21uaWNyb24tbGEtaW5mbGFjaW9uLXlhLW5vLWVzLXRyYW5zaXRvcmlhPC9hPg0KDQotIDxhIGhyZWY9Imh0dHBzOi8vd3d3LmNhaXhhYmFua3Jlc2VhcmNoLmNvbS9lbi9wdWJsaWNhY2lvbmVzL25vdGFzLWJyZXZlcy1hY3R1YWxpZGFkLWVjb25vbWljYS15LWZpbmFuY2llcmEvaW50ZXJuYWNpb25hbC9hdW1lbnRvLWdlbmVyYWxpemFkby15Ij5odHRwczovL3d3dy5jYWl4YWJhbmtyZXNlYXJjaC5jb20vZW4vcHVibGljYWNpb25lcy9ub3Rhcy1icmV2ZXMtYWN0dWFsaWRhZC1lY29ub21pY2EteS1maW5hbmNpZXJhL2ludGVybmFjaW9uYWwvYXVtZW50by1nZW5lcmFsaXphZG8teTwvYT4NCg0KLSA8YSBocmVmPSJodHRwczovL3d3dy5lbGVjb25vbWlzdGEuZXMvZmxhc2gvI2ZsYXNoXzE1NDUwIj5odHRwczovL3d3dy5lbGVjb25vbWlzdGEuZXMvZmxhc2gvI2ZsYXNoXzE1NDUwPC9hPg0KDQpQYXJhIHBvZGVyIHJlYWxpemFyIGdyw6FmaWNvcyBbYW5pbWFkb3NdKGh0dHBzOi8vZ2dhbmltYXRlLmNvbS8pLCBub3MgaGVtb3MgYmFzYWRvIGVuIGxhcyBleHBsaWNhY2lvbmVzIGRlIGNvbW8gaW1wbGVtZW50YXIgZWwgcGFxdWV0ZSBnZ2FuaW1hdGUgZW4gbnVlc3RybyBwcm95ZWN0by4NCg0KQ29uIGVsIHBhcXVldGUgW2R5Z3JhcGhdKGh0dHBzOi8vcnN0dWRpby5naXRodWIuaW8vZHlncmFwaHMvKSwgYWRlbcOhcyBkZSBjb25zZWd1aXIgcmVhbGl6YXIgdW4gZ3LDoWZpY28gaW50ZXJhY3Rpdm8sZXN0ZSBub3MgcGVybWl0ZSByZWFsaXphciB6b29tIGVuIGN1YWxxdWllciBwYXJ0ZSBkZWwgbWlzbW8gcXVlIG5vcyBsbGFtZSBsYSBhdGVuY2nDs24uDQoNCkRhZG9zIGxvcyBwcm9ibGVtYXMgcGFyYSBjb25zZWd1aXIgcmVhbGl6YXIgdW4gbWFwYSBpbnRlcmNhdGl2byBjb24gZ2VvbV9zZiwgbm9zIGRlc2NhcmdhbW9zIHVub3MgYXJjaGl2b3MgW3NoYXBlbGZpZWxkXShodHRwczovL2NlbnRyb2RlZGVzY2FyZ2FzLmNuaWcuZXMvQ2VudHJvRGVzY2FyZ2FzL2NhdGFsb2dvLmRvP1NlcmllPUNBQU5FKSBjb24gbG8gcXVlIGNvbnNlZ3VpbW9zIGhhY2VyIHVuIG1hcGEgZGUgbGFzIFtwcm92aW5jaWFzXShodHRwczovL3JxdWVyLm5ldGxpZnkuYXBwL21hcGFzX3NwYWluLykgZGUgRXNwYcOxYS4NCg0KQWRlbcOhcywgcGFyYSBsYSBlbGFib3JhY2nDs24gZGUgZ3LDoWZpY29zIHF1ZSBub3MgcGFyZWPDrWFuIMO6dGlsZXMgcGFyYSBpbXBsZW1lbnRhciBlbiBlbCB0cmFiYWpvLCBoZW1vcyBjb25zdWx0YWRvIGluZm9ybWFjacOzbiBzb2JyZSBjb21vIGVsYWJvcmFyIHVuIFt0cmVlbWFwXShodHRwczovL3d3dy5yLWdyYXBoLWdhbGxlcnkuY29tL3RyZWVtYXAuaHRtbCIpLCBwYXJhIG9ic2VydmFyIGxhIGltcG9ydGFuY2lhIGRlIGxvcyBjb21wb25lbnRlcywgdW4gW2JhcnBsb3QgY2lyY3VsYXJdKGh0dHBzOi8vd3d3LnItZ3JhcGgtZ2FsbGVyeS5jb20vMjk2LWFkZC1sYWJlbHMtdG8tY2lyY3VsYXItYmFycGxvdC5odG1sKSwgcGFyYSByZXByZXNlbnRhciBsYXMgY29tdW5pZGFkZXMgYXV0w7Nub21hcywgeSB1biBbU3BhZ2hldHRpIHBsb3RdKGh0dHBzOi8vd3d3LmRhdGEtdG8tdml6LmNvbS9jYXZlYXQvc3BhZ2hldHRpLmh0bWwpLCBwYXJhIGVuIHVuIG1pc21vIGdyw6FmaWNvIGRlIGxpbmVhcyByZXNhbHRhciBsYSBxdWUgbm9zIGludGVyZXNlLg0KDQpQb3Igw7psdGltbywgZGVzdGFjYXIgY29tbyB0YW1iacOpbSBoZW1vcyBjb25zdWx0YWRvIHRyYWJham9zIHJlYWxpemFkb3MgcG9yIG51ZXN0cm9zIGNvbXBhw7Flcm9zIGVsIGHDsW8gYW50ZXJpb3IuIEVzdG9zIMO6bHRpbW9zIGxvcyBwb2RlbW9zIGVuY29udHJhciBbYXF1aV0oaHR0cHM6Ly9wZXJlenA0NC5naXRodWIuaW8vaW50cm8tZHMtMjAtMjEtd2ViLzA3LXRyYWJham9zLmh0bWwpIA0KDQotLS0tLS0tLS0tLS0tLS0tDQoNCjxicj4NCg0KUGFyYSBjb25jbHVpciBlc3RlIGFwYXJ0YWRvIGluY2x1aW1vcyBsYSBgc2Vzc2lvbiBpbmZvYDoNCg0KYGBge3J9DQpzZXNzaW9uaW5mbzo6c2Vzc2lvbl9pbmZvKCkgJT4lIGRldGFpbHM6OmRldGFpbHMoc3VtbWFyeSA9ICdjdXJyZW50IHNlc3Npb24gaW5mbycpIA0KYGBgDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg==