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

En el presente trabajo vamos a mostrar algunos datos de interés de una de las empresas multinacionales más conocidas a nivel mundial, McDonald’s. Por un lado, veremos el menú de esta franquicia, así como los macronutrientes que contienen los productos y los valores nutricionales, mostrando y explicando los aspectos más relevantes. También trataremos de compararlo con otros grandes restaurantes de comida rápida en los Estados Unidos, país que acoge más cantidad de marcas de restaurantes de comida rápida en el mundo por excelencia. En la parte final, comentaremos de forma general la popularidad de los locales por ciudad, así como la evolución de sus ventas a lo largo de los últimos años. Por lo que en este trabajo nuestro objetivo es informar y concienciar a los lectores un poco acerca de los productos ofrecidos por McDonald’s así como el impacto que este ha tenido sobre la población estadounidense.

Marca Franquicia

1.1 Breve Historia

El primer restaurante de McDonald’s se ubicaba en California, en el año 1948, como un bar de carretera. Fueron los dos hermanos Maurice y Richard Mcdonald quien llevaron a cabo este proyecto. Los elementos que lo caracterizaban y fueron motivo del éxito eran; por un lado, se podía pedir y recoger los productos desde el coche, los grandes ventanales que tenían permitían ver desde fuera como el pedido se preparaba y por último, los bajos precios que lo diferenciaban de competidores. Este último estuvo a punto de llevar a los hermanos a la quiebra, por lo que estos tuvieron que cerrar el negocio y organizar una buena estrategia. Resumiendo, Ray A. Kroc, alguien importante en los negocios por aquella zona, vio el potencial del restaurante en si y con la cesión del derecho de comercializar la marca por parte de los hermanos, abrió otro restaurante en Illinois. Y así se podría decir que empezó este negocio que actualmente tiene tanto éxito.

Primer local de McDonald’s

1.2 Logos.

Logo1

Logo1 1940-1948: La historia de la cadena de restaurantes de comida rápida más famosa del mundo comenzó en 1937 cuando Patrick McDonald lanzó «The Airdome», el primer restaurante de la familia. Tres años más tarde, sus hijos le cambiaron el nombre a «McDonald’s Famous Barbecue». El primer logotipo del restaurante estaba compuesto por una marca denominativa negra, distribuida en tres niveles y ejecutada en tres estilos diferentes.

Logo2

Logo2 1948-1953: El concepto de barbacoa fue reemplazado por las hamburguesas, que estaban ganando cada vez más popularidad en los Estados Unidos. El título del restaurante se modificó en 1948 y se rediseñó el logotipo. Se añade la especificación «buy em by the bag», para hacer hincapié en la posibilidad de consumir la comida también para llevar. En negrita (y repetido dos veces) aparece el precio super competitivo. Y un logotipo repleto de detalles, con la intención de resaltar todos los puntos fuertes del restaurante: la originalidad de la oferta, la modalidad de consumo y el ahorro.

Logo3

Logo3 1953-1968: La compañía finalmente cambió su nombre a simplemente MacDonald’s y aquí es donde comienza todo. El logo aún estaba lejos de lo que todos conocemos hoy, pero el color rojo apareció en la paleta de colores, dando la dirección correcta para la marca.Era un logotipo bastante memorable y reconocible, que permaneció en la empresa durante 15 años.

Logo4

Logo4 1961-1968: Es 1961 y hemos llegado a un momento decisivo para McDonald’s: el momento en que aparecen por primera vez los famosos «Golden Arches». Para el proyecto de un punto de venta en Downey (California), los hermanos McDonald encargan dos gigantescos arcos dorados en los extremos de la estructura. La idea era que se viese mejor incluso desde lejos. El logotipo de 1961, diseñado por el director creativo Jim Schindler, está inspirado en este detalle arquitectónico. Y eso no es todo: además se introduce el amarillo, un color que infunde el buen humor y que seguirá formando parte de la identidad visual de la empresa.

Logo5

Logo5 1975: La nueva imagen se incorporó a la identidad visual en 1975. El emblema con la marca denominativa se colocó dentro de un rectángulo rojo con ángulos redondeados. Las letras se cambiaron de negro a blanco, lo que parecía más amigable y acogedor. Esta insignia es probablemente la versión más reconocible de todos los logotipos de leyendas de comida rápida y la compañía todavía la usa, siendo reconocible instantáneamente en todo el mundo y evocando una sensación de alegría, felicidad y pasión.

Logo6

Logo6 A partir de 1985 se modifica y simplifica una vez más el logotipo en varios puntos del mundo : los arcos se solapan para formar la letra M. Hemos llegado al antepasado directo del logotipo de hoy.

Logo7

Logo7 A partir de 2009, La compañía McDonald’s cambia su tradicional logo de color rojo por uno verde, según anunció la marca. Este cambio de color simboliza teóricamente una imagen más ecológica y una nueva estrategia por parte de la empresa. El cambio de logo es una de las técnicasde marketing que adoptó la cadena de comida rápida. Con el objetivo de mostrar un perfil más comprometido con la preservación de los recursos naturales, McDonald’s lanzó su nueva campaña que consiste en cambiar el tradicional fondo rojo de su logo por un color verde intenso.

Logo8

Logo8 1993-Hoy: En Estados Unidos, McDonald’s introdujo a nivel nacional una línea de café llamada “McCafé”. A diferencia de lo que ocurre en otros países, “McCafé” es solo una línea de bebidas especiales, no una cafetería completa. El estilo del logotipo de McCafe no crea ningún vínculo con el logotipo de la marca matriz, McDonald’s. En cambio, las fuerzas del diseño detrás de McCafe han creado una identidad de marca distintiva y completamente independiente.

2. CARGAMOS DATOS Y PAQUETES

Este trabajo ha sido posible realizarlo con la ayuda de varias fuentes de donde hemos sacado los datos. En la página web facilitada por la asignatura (kaggle), hemos utilziado principalmente 5 datasests, que los indicaremos en la última parte, en la bibliografía. Por otro lado, hemos accedido a documentos oficiales del restaurante obtenidos en formato excel y los hemos transformado para trabajar con ellos y obtener más datos.

library(ggplot2)
library(dplyr)
library(reactable)
library(gt)
library(tibble)
library("plotly")
library(tidyverse)
library(hrbrthemes)
library(viridis)
library(patchwork)
library(gganimate)
library(wordcloud2)
library(webshot)
library(corrplot)
library(sqldf)
library(RColorBrewer) 
library(kableExtra)
library(ggThemeAssist)

menu <- rio::import("./datos/menu1.1.csv")
restaurantesUS <- rio::import("./datos/FastFoodRestaurants.csv")
fastfoodrestaurants <- rio::import("./datos/fastfoodrestaurants.csv")
ruta4 <- here::here("datos", "Datafiniti_Fast_Food_Restaurants_May19.csv")
fastfoodrestaurants19 <- rio::import(ruta4)
ingresos <- rio::import("./datos/ingresos1.csv")
ventas <- rio::import("./datos/sales.csv")

3. RESTAURANTES FAST FOOD EN ESTADOS UNIDOS

3.1 Número de restaurantes FastFood

En este apartado observamos mediante el siguiente gráfico de barras el número de restaurantes de fast food en todo el país de EEUU. Hemos acotado entre los 10 nombres más populares, entre ellos McDonald’s, Burguer King o Taco Bell.

mas_restaurantes <- restaurantesUS %>% 
  group_by(name) %>% 
  mutate(n_restaurantes = sum(NN = n())) %>%
  distinct(name, n_restaurantes) %>%
  arrange(desc(n_restaurantes)) %>%
  filter(n_restaurantes >=192) 

  gg_restaurantes <- ggplot(mas_restaurantes, aes(name, n_restaurantes)) +
  geom_bar(stat = "identity") + theme(panel.grid.major = element_line(colour = "gray"),
    panel.grid.minor = element_line(colour = "gray"),
    panel.background = element_rect(fill = "#FFC40C",
        colour = "aliceblue"), plot.background = element_rect(fill = "#FFC40C"))
  
gg_restaurantes

Como podemos ver, por clara diferencia, la marca con más locales es McDonald’s, seguida de Burguer King y luego de Taco Bell.

Una de las claves del éxito alcanzada por la empresa y que ha permitido su expansión mundial son las siguientes: por un lado, la consistencia. Esto es, en cualquier país en el que t encuentres, la experiencia en el restaurante va a ser muy similar, los clientes ya saben que esperar por lo que hace mucho más fáciles sus decisiones de que comer. Después destacaríamos la innovación, para que el negocio no quede estancado. Muy frecuentemente la franquicia lanza nuevos productos como respuesta de las demandas del cliente, se podría decir que evolucionan con el tiempo, como veremos un poco más adelante.

3.2 Ingresos restaurantes FastFood

En el siguiente apartado, analizaremos los ingresos en miles de millones de dólares de los mismos 10 restaurantes más famosos de EEUU.

 df_ingresos <- ggplot(ingresos, aes(x=reorder(Resturantes, Value), y=Value, fill=Resturantes))+
  geom_bar(stat="identity") +
  theme(legend.position = "none") +
  coord_polar(start = 0.01) +
  labs (x="Restaurantes") + labs(y="Miles de millones de dólares") + labs(title = "Ingresos de los Resturantes FastFood") + labs(subtitle = "En miles de millones de dólares") + theme(panel.background = element_rect(fill = "#FFC40C"),
    plot.background = element_rect(fill = "#FFC40C"))

df_ingresos

Como se observa claramente, en la primera posición volveríamos a encontrar a nuestro restaurante, que llega a los 40 mil millones de dólares anuales. Sus ingresos están muy por encima de cualquiera de las otras marcas.

4. MC DONALD’S

En este cuarto apartado, vamos a hablar sobre el restaurante en cuestión en términos generales y de los aspectos más relevantes.

4.1 Productos McDonalds

En la siguiente tabla, se pueden consultar todos los productos de la carta que ofrecen. Se muestran un total de 260 productos.

df_menu <- menu %>%
select(Item)

reactable(df_menu, defaultPageSize =  8,  paginationType = "jump", showPageSizeOptions =  TRUE , pageSizeOptions =  c ( 10 , 50 , 100, 150, 200, 260 ),defaultColDef = colDef(
    align = "center",
    minWidth = 70,
    headerStyle = list(background = "#FFD700"),
    filterable = TRUE),  highlight = TRUE, outlined = TRUE,
    columns = list(
  `Item` = colDef(style = function(value) {
    if (value > 0) {
      color <- "#F5C710"}
      else {
      color <- "#B22222"
    }
    list(color = color, fontWeight = "bold",background = "#CD2626")
  })))

4.2 Categorias de productos en McDonalds

De entre todos los productos, estos se podrían diferenciar en las siguientes categorías:

m <- list(
  l = 50,
  r = 50,
  b = 100,
  t = 100,
  pad = 4
)
marker = list(color = brewer.pal(9, "Set1"))
p <- plot_ly(
  x = menu$Category,
  marker = list(color = '#CD0BBC'),
    type = "histogram"
)%>%
  layout(         xaxis = list(title = ""),
         yaxis = list(title = ""),
         autosize = T)
p

Y aun que parezca sorprendente, este restaurante cuenta con más variedad en cafés y tés. Incluso aunque a primera vista lo más demandado sea una simple hamburguesa de carne, al menos en nuestro país. De lo que menos variedad hay sería de ensaladas. Quizá tenga sentido porque es uno de lo productos que se ha incorporado más recientemente.

5.VALORES NUTRICIONALES

A continuación, vamos a destacar los aspectos y los puntos más relevantes y quizá destacables de los productos que ofrece la marca pero en términos de los valores nutricionales.

5.1 ¿Cuál es el producto con más calorias?

El producto más calórico del restaurante, son los nugguets, también es porque cuenta con 40 piezas.

df_calorias <- menu %>%
select(Item, Calories) 

dftop1 <- df_calorias %>% slice_max(Calories, n=1)

Imagen <- "https://i.pinimg.com/originals/d5/5f/03/d55f035c37d84ec55934ba6d469bedce.jpg"

dftop1 <- dftop1 %>% add_column(Imagen)

Tabla_Pmascal <- dftop1 %>% gt()

Tabla_Pmascal <- Tabla_Pmascal %>%
                   tab_header(title = md("**Producto con mas calorias**"))
                   
Tabla_Pmascal <- Tabla_Pmascal %>%
                tab_options(heading.background.color = "coral") %>% tab_options(heading.title.font.size = 15,  column_labels.font.weight =  "bold")


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

Tabla_Pmascal
Producto con mas calorias
Item Calories Imagen
Chicken McNuggets (40 piece) 1880

5.2 ¿Cuál es el producto con menos calorias?

El menos calórico, lógicamente sería la botella de agua

dfmin1 <- df_calorias %>% 
slice_min(Calories, n=1) %>%
filter (Item == "Dasani Water Bottle") #Dasani Water Bottle es uno de los productos con menos calorias 

Imagen <- "https://i.pinimg.com/originals/3c/df/ae/3cdfaeaa504db8aaf100843a12aacc97.png"

dfmin1 <- dfmin1 %>% add_column(Imagen)


Tabla_Pmincal <- dfmin1 %>% gt()

Tabla_Pmincal <- Tabla_Pmincal %>%
                   tab_header(title = md("**Producto con menos calorias**"))
                   
Tabla_Pmincal <- Tabla_Pmincal %>%
                tab_options(heading.background.color = "coral") %>% tab_options(heading.title.font.size = 15,  column_labels.font.weight =  "bold")


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

Tabla_Pmincal
Producto con menos calorias
Item Calories Imagen
Dasani Water Bottle 0

5.3. Productos con mayor macronutrientes.

En este apartado, vamos a mostrar por separado, que 10 productos, en primer lugar, tienen más proteínas, luego cuáles cuentan con más grasas y cual está compuesto con más carbohidratos.

En los gráficos de cada macronutriente podemos verlo, sosteniendo el cursor sobre ellos.

Proteina

df14prod <- menu %>%
  select(Item, Protein) %>%
  head(Protein, n = 10L)%>%
  group_by(Item, Protein) %>%
  arrange(desc(Protein))

df14prod
Item Protein
Steak & Egg McMuffin 26
Sausage McMuffin with Egg 21
Sausage McMuffin with Egg Whites 21
Bacon, Egg & Cheese Biscuit with Egg Whites (Regular Biscuit) 20
Bacon, Egg & Cheese Biscuit with Egg Whites (Large Biscuit) 20
Bacon, Egg & Cheese Biscuit (Regular Biscuit) 19
Bacon, Egg & Cheese Biscuit (Large Biscuit) 19
Egg White Delight 18
Egg McMuffin 17
Sausage McMuffin 14
wordcloud2(data=df14prod, size=0.1)

Grasas

totalfat <- menu %>%
 select(Item, Fat) 


df_fat <- totalfat %>%
head(Fat, n= 10L) %>%
group_by(Item, Fat) %>%
arrange(desc(Fat))

df_fat
Item Fat
Bacon, Egg & Cheese Biscuit (Large Biscuit) 30
Sausage McMuffin with Egg 28
Bacon, Egg & Cheese Biscuit (Regular Biscuit) 26
Bacon, Egg & Cheese Biscuit with Egg Whites (Large Biscuit) 25
Sausage McMuffin 23
Sausage McMuffin with Egg Whites 23
Steak & Egg McMuffin 23
Bacon, Egg & Cheese Biscuit with Egg Whites (Regular Biscuit) 20
Egg McMuffin 13
Egg White Delight 8
plot_ly(x = df_fat$Item, y=df_fat$Fat,color = df_fat$Item,colors = palette("Pastel 2"), type = "box") %>% 
  layout(title = "Los 10 productos con más grasa",
         xaxis = list(title = ""),
         yaxis = list(title = ""),
         showlegend=FALSE,
         autosize = T) 

Carbohidratos

carbos <- menu %>%
select(Item,Carbohydrates)

df_carbos <- carbos %>%
head(Carbohydrates, n= 10L) %>%
group_by(Item, Carbohydrates) %>%
arrange(desc(Carbohydrates))

df_carbos
Item Carbohydrates
Bacon, Egg & Cheese Biscuit (Large Biscuit) 43
Bacon, Egg & Cheese Biscuit with Egg Whites (Large Biscuit) 42
Bacon, Egg & Cheese Biscuit (Regular Biscuit) 38
Bacon, Egg & Cheese Biscuit with Egg Whites (Regular Biscuit) 36
Egg McMuffin 31
Steak & Egg McMuffin 31
Egg White Delight 30
Sausage McMuffin with Egg 30
Sausage McMuffin with Egg Whites 30
Sausage McMuffin 29
plot_ly(x = df_carbos$Item, y=df_carbos$Carbohydrates,color = df_carbos$Item, colors = palette("alphabet"), type = "box") %>% 
         layout(title="Los 10 productos con más carbohidratos",
         xaxis = list(title = ""),
         yaxis = list(title = ""),
         showlegend=FALSE,
         autosize = T)

En cuanto al producto con más proteínas se encontraría el Steak & Egg McMuffin, que se encuenta dentro de la sección de los desayunos. Con más grasa y a la vez con más hidratos tendríamos al Bacon, Egg & Cheese Biscuit (Large Biscuit).

5.4. Productos con mayor micronutrientes .

VitaminaA

En este apartado, repetimos la misma operación que en el punto anterior pero ahora con los micronutrientes, separados en: vitamina A y C, fibra, calcio y hierro. En la parte inferior de cada lista, lo podemos observar también gráficamente

vitaminaA <- menu %>%
select(Item,VitaminA)

df_vitamina1 <- vitaminaA %>%
head(VitaminA, n= 10L)%>%
arrange(desc(VitaminA))

df_vitamina1
Item VitaminA
Sausage McMuffin with Egg 15
Steak & Egg McMuffin 15
Bacon, Egg & Cheese Biscuit (Large Biscuit) 15
Egg McMuffin 10
Bacon, Egg & Cheese Biscuit (Regular Biscuit) 10
Sausage McMuffin 8
Egg White Delight 6
Sausage McMuffin with Egg Whites 6
Bacon, Egg & Cheese Biscuit with Egg Whites (Large Biscuit) 6
Bacon, Egg & Cheese Biscuit with Egg Whites (Regular Biscuit) 2
grafico <- df_vitamina1 %>%
  ggplot( aes(Item, VitaminA, size = 0.75, color= "orange")) +
  geom_point() +
  theme_bw()+ 
  theme(legend.position = "none") +
  labs(x = NULL) + theme(axis.title.x=element_blank(),
        axis.text.x=element_blank(),
        axis.ticks.x=element_blank()) + labs(title= "Los 10 productos con más Vitamina A") +
  theme(panel.background = element_rect(fill = 'wheat1', colour = 'red')) + theme(panel.background = element_rect(fill = "#FFC40C"),
    plot.background = element_rect(fill = "#FFC40C",
        colour = "#FFC40C"))

ggplotly(grafico)

VitaminaC

vitaminaC <- menu %>%
select(Item,VitaminC)

df_vitamina2 <- vitaminaC %>%
head (VitaminC, n = 10L)%>%
arrange(desc(VitaminC))

df_vitamina2
Item VitaminC
Bacon, Egg & Cheese Biscuit (Regular Biscuit) 8
Bacon, Egg & Cheese Biscuit (Large Biscuit) 8
Bacon, Egg & Cheese Biscuit with Egg Whites (Regular Biscuit) 8
Bacon, Egg & Cheese Biscuit with Egg Whites (Large Biscuit) 8
Steak & Egg McMuffin 2
Egg McMuffin 0
Egg White Delight 0
Sausage McMuffin 0
Sausage McMuffin with Egg 0
Sausage McMuffin with Egg Whites 0
dfgrafico1 <- ggplot(df_vitamina2, aes(Item, color=VitaminC)) + 
  geom_bar(fill=NA) + 
  coord_flip() +
  theme(panel.background = element_rect(fill = 'lightblue1')) + theme(panel.background = element_rect(fill = "#FFC40C"),
    plot.background = element_rect(fill = "#FFC40C"),
    legend.background = element_rect(fill = "#FFC40C"))

ggplotly(dfgrafico1)

Fibra

fibra <- menu %>%
select(Item,DietaryFiber)

df_fibra <- fibra %>%
head(DietaryFiber, n= 10L) %>%
arrange(desc(DietaryFiber))

df_fibra
Item DietaryFiber
Egg McMuffin 4
Egg White Delight 4
Sausage McMuffin 4
Sausage McMuffin with Egg 4
Sausage McMuffin with Egg Whites 4
Steak & Egg McMuffin 4
Bacon, Egg & Cheese Biscuit (Large Biscuit) 3
Bacon, Egg & Cheese Biscuit with Egg Whites (Large Biscuit) 3
Bacon, Egg & Cheese Biscuit (Regular Biscuit) 2
Bacon, Egg & Cheese Biscuit with Egg Whites (Regular Biscuit) 2
m <- list(
  l = 50,
  r = 50,
  b = 100,
  t = 100,
  pad = 4
)
marker = list(color = brewer.pal(9, "Set1"))
p <- plot_ly(
  x = menu$Category,
  marker = list(color = '#45171D')
)
                
menu %>%  
plot_ly( x = df_fibra$Item, y = df_fibra$DietaryFiber, type="scatter", mode = "markers" , marker=list( color=colorRampPalette(brewer.pal(8,"Dark2"))(100) , opacity=0.9) ) %>% layout(title = "Los 10 productos con más fibra",
         xaxis = list(title = ""),
         yaxis = list(title = ""),
         showlegend=FALSE,autosize = F, width = 500, height = 400,margin=m)

Calcio

calcio <- menu %>%
select(Item,Calcium)

df_calcium <- calcio %>%
head(Calcium, n= 10L) %>%
arrange(desc(Calcium))

df_calcium
Item Calcium
Sausage McMuffin with Egg 30
Steak & Egg McMuffin 30
Egg McMuffin 25
Egg White Delight 25
Sausage McMuffin 25
Sausage McMuffin with Egg Whites 25
Bacon, Egg & Cheese Biscuit (Large Biscuit) 20
Bacon, Egg & Cheese Biscuit (Regular Biscuit) 15
Bacon, Egg & Cheese Biscuit with Egg Whites (Regular Biscuit) 15
Bacon, Egg & Cheese Biscuit with Egg Whites (Large Biscuit) 15
p <- ggplot(df_calcium, aes(Item, Calcium)) + 
  geom_point() + 
  geom_segment(aes(x=forcats::fct_reorder(Item, Calcium, .desc = TRUE),
                   xend=forcats::fct_reorder(Item, Calcium, .desc = TRUE),
                   y=0,
                   yend=Calcium, color=palette("Tableau 10"))) + 
  geom_smooth() +
  theme(axis.title.x=element_blank(),
        axis.text.x=element_blank(),
        axis.ticks.x=element_blank()) +
  labs(title = "Los 10 productos con más calcio",
              subtitle = "anño 2019", 
              caption = "Datos provenientes de Kaggle",
              x = "Productos",
              y = "Calcio") +
  theme(legend.position="none") + theme(panel.background = element_rect(fill = "#FFC40C"),
    plot.background = element_rect(fill = "#FFC40C"))


ggplotly(p)

Hierro

hierro <- menu %>%
 select(Item, Iron) 

df_hierro <- hierro %>%
head(Iron, n= 10L) %>%
group_by(Item, Iron) %>%
arrange(desc(Iron))

df_hierro
Item Iron
Steak & Egg McMuffin 20
Bacon, Egg & Cheese Biscuit (Large Biscuit) 20
Egg McMuffin 15
Sausage McMuffin with Egg 15
Bacon, Egg & Cheese Biscuit (Regular Biscuit) 15
Bacon, Egg & Cheese Biscuit with Egg Whites (Large Biscuit) 15
Sausage McMuffin 10
Sausage McMuffin with Egg Whites 10
Bacon, Egg & Cheese Biscuit with Egg Whites (Regular Biscuit) 10
Egg White Delight 8
df <- ggplot(df_hierro, aes(x=Item, y=Iron)) +
  geom_segment( aes(x=Item, xend=Item, y=0, yend=Iron)) +
  geom_point( size=5, color="red", fill=alpha("orange", 0.3), alpha=0.7, shape=21, stroke=2) + theme(axis.title.x=element_blank(),
        axis.text.x=element_blank(),
        axis.ticks.x=element_blank()) +  labs(title = "Los 10 productos con más calcio",
              subtitle = "anño 2019", 
              caption = "Datos provenientes de Kaggle",
              x = "Productos",
              y = "Calcio") + 
  theme(panel.background = element_rect(fill = "#FFC40C"),
    plot.background = element_rect(fill = "#FFC40C"))

ggplotly(df)

El desayuno de Sausage McMuffin with Egg, es el que encontramos con más vitamina A y el Bacon, Egg & Cheese Biscuit (Regular Biscuit), con más vitamina C.

En cuanto al alimento con más fibra, diríamos el Egg McMuffin, que en lugar de carne, posee un huevo en su interior.

Sausage McMuffin with Egg vuelve a repetirse como el producto con más calcio de entre todos y Steak & Egg McMuffin es el que aparece con más hierro.

5.5 Correlación

En este gráfico se concentra y se muestra la correlación que tienen entre sí los nutrientes de los productos que se encuentran en la carta de McDonald’s.

menu <- na.omit(menu)
scaledmenu <- data.frame(scale(menu[c(4:24)]))
menu1<-cbind(menu[1:3],scaledmenu)

M <- cor(scaledmenu)
cex.before <- par("cex")
par(cex = 0.7)
corrplot(M, insig = "blank", method = "square",  tl.cex = .75)
par(cex = cex.before)

5.6. Combi perfecta

En este punto llamamos combi perfecta, al producto menos calórico de cada categoría. Esto hace posible que aun siendo Mc Donald’s un lugar de comida poco saludable se pueda saber que opciones puede coger un cliente que pretenda comer las menos calorías posibles por lo que al tener los productos menos calóricos de cada categoria, el cliente puede conformarse así su propio menú atendiendo a lo que este solicita.

Mincal<-aggregate(menu$Calories, by=list(menu$Category), FUN=min)
colnames(Mincal)[1]<-"Category"
colnames(Mincal)[2]<-"Calories"
Mincalmenu<-sqldf("select a.Category,a.Item, a.Calories from menu a, Mincal b where a.Category==b.Category and a.Calories==b.Calories" )
## The below table gives the minumum Calorie Item from Each Category
Mincalmenu
Category Item Calories
Breakfast Hash Brown 150
Beef & Pork Hamburger 240
Chicken & Fish Chicken McNuggets (4 piece) 190
Salads Premium Bacon Ranch Salad (without Chicken) 140
Salads Premium Southwest Salad (without Chicken) 140
Snacks & Sides Apple Slices 15
Desserts Kids Ice Cream Cone 45
Beverages Diet Coke (Small) 0
Beverages Diet Coke (Medium) 0
Beverages Diet Coke (Large) 0
Beverages Diet Coke (Child) 0
Beverages Diet Dr Pepper (Small) 0
Beverages Diet Dr Pepper (Medium) 0
Beverages Diet Dr Pepper (Large) 0
Beverages Diet Dr Pepper (Child) 0
Beverages Dasani Water Bottle 0
Coffee & Tea Iced Tea (Small) 0
Coffee & Tea Iced Tea (Medium) 0
Coffee & Tea Iced Tea (Large) 0
Coffee & Tea Iced Tea (Child) 0
Coffee & Tea Coffee (Small) 0
Coffee & Tea Coffee (Medium) 0
Coffee & Tea Coffee (Large) 0
Smoothies & Shakes Strawberry Banana Smoothie (Small) 210
Smoothies & Shakes Mango Pineapple Smoothie (Small) 210
knitr::kable(Mincalmenu) %>%
  kableExtra::kable_styling(full_width = F) %>%
  column_spec(1, bold = T, border_right = T) %>%
  row_spec(1, bold = T, color = "white", background = palette("Pastel 2")) %>% 
  row_spec(2:2, bold = T, color = "white", background = palette("Tableau 10") ) %>%
  row_spec(3:3, bold = T, color = "white", background = palette("Polychrome 36") ) %>%
  row_spec(4:5, bold = T, color = "white", background = palette("Okabe-Ito") ) %>%
  row_spec(6:6, bold = T, color = "white", background = palette("Paired") ) %>%
  row_spec(7:7, bold = T, color = "white", background = "#2297E6") %>%
  row_spec(8:16, bold = T, color = "white", background = "#28E2E5") %>% 
  row_spec(17:23, bold = T, color = "white", background = "#61D04F") %>%
  row_spec(24:25, bold = T, color = "white", background = "#DF536B") %>% 
  row_spec(0, angle = 0)
Category Item Calories
Breakfast Hash Brown 150
Beef & Pork Hamburger 240
Chicken & Fish Chicken McNuggets (4 piece) 190
Salads Premium Bacon Ranch Salad (without Chicken) 140
Salads Premium Southwest Salad (without Chicken) 140
Snacks & Sides Apple Slices 15
Desserts Kids Ice Cream Cone 45
Beverages Diet Coke (Small) 0
Beverages Diet Coke (Medium) 0
Beverages Diet Coke (Large) 0
Beverages Diet Coke (Child) 0
Beverages Diet Dr Pepper (Small) 0
Beverages Diet Dr Pepper (Medium) 0
Beverages Diet Dr Pepper (Large) 0
Beverages Diet Dr Pepper (Child) 0
Beverages Dasani Water Bottle 0
Coffee & Tea Iced Tea (Small) 0
Coffee & Tea Iced Tea (Medium) 0
Coffee & Tea Iced Tea (Large) 0
Coffee & Tea Iced Tea (Child) 0
Coffee & Tea Coffee (Small) 0
Coffee & Tea Coffee (Medium) 0
Coffee & Tea Coffee (Large) 0
Smoothies & Shakes Strawberry Banana Smoothie (Small) 210
Smoothies & Shakes Mango Pineapple Smoothie (Small) 210

6.TIPOS DE ALIMENTOS

Como todos sabemos McDonald’s ofrece una carta muy amplia de productos de todo tipo, más grandes o más pequeños, más calórico o menos, más sanos o menos nutricionalmente hablando, etc. Es conocido sobretodo por las comidas y cenas siendo estas en las que van más clientes, sin embargo Mc donald’s desde que abrio la zona de Mc Cafe cuenta con una gran variedad de cafés para cualquier hora del día así como de desayunos y de snacks. Y cabe destacar que también ha querido adaptarse a opciones más saludables para así llegar a todas las personas, ofreciendo comida más sana y menos sana.Por eso vamos a mostrar 3 tipos de alimentos, que probablemente no sean conocidos ni asociados a una franquicia como Mc Donald’s tan arraigada a las hamburguesas.

6.1.Breakfast

ggplot(subset(menu,Category=="Breakfast"), aes(reorder(Item,Calories),Calories,fill=Calories)) + geom_bar(stat = "identity")  + theme(legend.position = "none")+ggtitle("Breakfast Vs Calories") + xlab("Item") + ylab("Calories")  + coord_flip() + theme(panel.background = element_rect(fill = "#FFC40C"),
    plot.background = element_rect(fill = "#FFC40C"))

6.2. Salad Menu

ggplot(subset(menu,Category=="Salads"), aes(reorder(Item,Calories),Calories,fill=Calories)) + geom_bar(stat = "identity")  + theme(legend.position = "none")+ggtitle("Salads Menu Vs Calories") + xlab("Item") + ylab("Calories")  + coord_flip() + theme(panel.background = element_rect(fill = "#FFC40C"),
    plot.background = element_rect(fill = "#FFC40C"))

6.3. Snacks

ggplot(subset(menu,Category=="Snacks & Sides"), aes(reorder(Item,Calories),Calories,fill=Calories)) + geom_bar(stat = "identity")  + theme(legend.position = "none")+ggtitle("Snacks & Sides Menu Vs Calories") + xlab("Item") + ylab("Calories")  + coord_flip() + theme(panel.background = element_rect(fill = "#FFC40C"),
    plot.background = element_rect(fill = "#FFC40C"))

6.4. Coffee and Tea

Coffeeandtea<-subset(menu,Category=="Coffee & Tea")
Coffeeandtea <- Coffeeandtea[order(-Coffeeandtea$Calories),]
Coffeeandtea<-Coffeeandtea[1:20,]
ggplot(Coffeeandtea, aes(reorder(Item,Calories),Calories,fill=Calories)) + geom_bar(stat = "identity")  + theme(legend.position = "none")+ggtitle("Coffee & Tea Menu Vs Calories") + xlab("Item") + ylab("Calories")  + coord_flip() + theme(panel.background = element_rect(fill = "#FFC40C"),
    plot.background = element_rect(fill = "#FFC40C"))

7.POPULARIDAD

En este apartado analizarmeos y mostraremos la “popularidad” de nuestro restaurante en algunas de las ciudades de EEUU, a través de un gráfico de barras. Veremos el número de locales de la franquicia con los que cuentan las ciudades que se muestran.

Restaurante Mc Donald’s

nummac <- restaurantesUS %>%
  select(city, name) %>%
   group_by(city) %>% 
  mutate(nn_mac = sum(NN=n())) %>% 
  filter(name == "McDonald's") %>% 
  distinct(city, nn_mac) %>%
  ungroup()

top10 <- nummac %>%
  slice_max(nn_mac , n=10) 

grafico1 <- ggplot (top10, aes(x=nn_mac, y = city), aes(fct_rev(nn_mac))) + geom_bar(stat="identity", fill = "red") + coord_flip() + labs(x = "Numero de McDonalds", y = "City")+labs(title = "Locales por ciudad")  + theme(panel.background = element_rect(fill = "#FFC40C"),
    plot.background = element_rect(fill = "#FFC40C"))

grafico1

Con gran ventaja sobre los demás, la ciudad que cuenta con más locales sería Cincinnati.

Y es que este restaurante es mundialmente reconocido, tanto por ser una organización comercial de alta calidad, como por ser una de las mejores oportunidades de oferta de Franquicias. Puede pues, que la clave de su éxito es tener una base muy firme en sus franquiciatarios.

8. VENTAS

Por último, vamos a hablar sobre las ventas del restaurante, información que hemos considerado importante tener en cuenta y por ello mostraros. Y es que esta marca cuenta con 26 mil locales en todo el mundo, 14 mil millones de comidas vendidas al año, 5 establecimientos nuevos se abren cada día, venta de 145 hamburguesas por segundo y un millón y medio de empleados.

ventasmc <- ventas%>%
  select(Años,Ventas)


 ggplot( data= ventas, aes(x=Años, y=Ventas)) +
    geom_line() +
    geom_point() +
    ggtitle("Evolución de las ventas de MC Donald's desde 2005-2019") +
   theme_ipsum() +
    ylab("Número de ventas") +
    transition_reveal(Años) + theme(plot.subtitle = element_text(family = "sans"),
    plot.caption = element_text(family = "sans"),
    axis.title = element_text(family = "sans"),
    plot.title = element_text(family = "sans"),
    panel.background = element_rect(fill = "#FFC40C"),
    plot.background = element_rect(fill = "#FFC40C"))

En este gráfico vemos la evolución de las ventas de McDonald’s entre 2005 y 2019

8.1 Locales y empleados

grafloc <- ggplot( data= ventas, aes(x=Años, y=Locales)) 
  
 grafloc +  geom_line() +
    geom_point() +
    ggtitle("Evolución de los establecimientos de MC Donald's desde 2005-2019") +
   theme_ipsum() +
    ylab("Número de establecimientos") +
    transition_reveal(Años)+
      labs(subtitle = "En miles") + theme(plot.subtitle = element_text(family = "sans"),
    plot.caption = element_text(family = "sans"),
    axis.title = element_text(family = "sans"),
    plot.title = element_text(family = "sans"),
    panel.background = element_rect(fill = "#FFC40C"),
    plot.background = element_rect(fill = "#FFC40C"))

 empleados <- ventas%>%
  select(Años,Empleados)
  
  grafempl <- ggplot( data= ventas, aes(x=Años, y=Empleados)) 
   grafempl+  geom_line() +
    geom_point() +
    ggtitle("Evolución del número de empleados de MC Donald's desde 2013-2019") +
   theme_ipsum() +
    ylab("Número de Empleados") +
    transition_reveal(Años) + theme(plot.subtitle = element_text(family = "sans"),
    plot.caption = element_text(family = "sans"),
    axis.title = element_text(family = "sans"),
    plot.title = element_text(family = "sans"),
    panel.background = element_rect(fill = "#FFC40C"),
    plot.background = element_rect(fill = "#FFC40C"))
 empleados<- na.omit(empleados)

Particularmente McDonald’s resulta un caso interesante a contemplar puesto que año con año es posible notar que tiene menos empleados pero crece de forma importante. La firma que en su momento pudo llegar a presumir de haber contratado a uno de cada ocho trabajadores en los Estados Unidos ha ido reduciendo la cantidad de colaboradores, cosa que podría parecer negativa pues el crecimiento muchas veces implica que es necesario sumar a más personas. Tal como lo presentamos en la gráfica de este día, de 2012 a 2018 es posible notar como ha ido disminuyendo de forma significativa la cantidad de empleados de McDonald’s a nivel global. Como se logra observar, durante 2012 había 440 mil trabajadores, para 2015 ya eran 420 mil mientras que para el año 2018 la cantidad ya se había reducido a la mitad con respecto a lo reportado en 2015, es decir, se tiene registro de solo 210 mil empleados hasta el año pasado.

¿Por qué hay menos empleados si hay más restaurantes?

El hecho de que la marca de los arcos dorados tenga menos personal y más restaurantes obedece principalmente a la visión a futuro de la compañía, a la tecnología y la forma en que ha decidido gestionarse. Específicamente en el caso de los empleados, es posible notar que McDonald’s ha decidido apostar en gran medida por acciones como la opción de que las personas pidan su comida a través de apps desde las cuales pueden incluso pagar y otras herramientas de self-service en los restaurantes, como kioscos desde los cuales los consumidores se encargan de gestionar sus órdenes. Se espera que para finales de este año, en Estados Unidos, más de 12 mil ubicaciones de McDonald’s cuenten con menús digitales y kioscos de autoservicio.

CONCLUSION

Después del análisis realizado en el presente trabajo podemos llegar a una serie de conclusiones respecto al restaurante en cuestión: Mc Donald’s. La franquicia más exitosa a nivel mundial, a pesar de haberse enfrentado a desafíos de competencia a nivel mundial, sigue en el top 1 de restaurantes del mundo.

Como todo el mundo sabe, el menú siempre ha sido muy parecido a lo largo de los años, suelen incorporar nuevos productos, suprimir otros, en función del éxito que tengan, pero como hemos mencionado anteriormente sí que es verdad que como destino para comer algo es una apuesta segura porque sabes perfectamente lo que vas a comer, el entorno o el local en el que te vas a encontrar, el ambiente, etc. Ya que todos los restaurantes, estés en la parte del mundo en la que estés, son muy similares entre sí.

A pesar de las críticas y opiniones que recibe este restaurante de comida rápida, la variedad de productos que ofrece es muy amplia y permite que el consumidor tenga diferentes opciones al gusto.

Otro aspecto importante comentado en este trabajo, es que aún que la gente no se pare a pensarlo, esta marca hace una gran labor social, con impacto positivo a la sociedad. Como por ejemplo en términos de puestos de trabajo, o como se menciona en la última parte, la inversión en nuevos métodos tecnológicos y la visión para el futuro que se prevé siempre adaptándose a los distintos cambios que suceden a nuestro alrededor.

Nuestro objetivo con este proyecto, y esperamos que conseguido, es dar a conocer un poco más el restaurante en lo que se trata de los productos que ofrece. Aunque ya bastante conocida es la marca y su menú, no está de más conocer completamente o por lo menos detalladamente los aspectos comentados aquí.

Por último, mencionar que el éxito que tuvo la franquicia en sus inicios ha continuado a lo largo de todos estos últimos años y se prevé que continúe al menos los mismos años que ya lleva en pie. Porque como ya hemos mencionado, es un destino atractivo para el público sobre todo joven y mientras siga así la demanda, la oferta no será menos.

LS0tCnRpdGxlOiAiRmFzdEZvb2Q6IEFuw6FsaXNpcyBkZWwgTWNEb25hbGRzIgphdXRob3I6ICJBbGJhIEVzdGVsYSBHYXJjaWEoYWxlc2dhcjNAYWx1bW5pLnV2LmVzKSAgXG5cbiBNZWxhbmllIE5ldWZjb3VyKG1lbmV1ZkBhbHVtbmkudXYuZXMpICBcbiBcbiBNaXJlaWEgWWFuZ8O8ZXoobWl5YW5vQGFsdW1uaS51di5lcykuIFxuXG4gVW5pdmVyc2l0YXQgZGUgVmFsw6huY2lhIgpkYXRlOiAiRGljaWVtYnJlIGRlIDIwMjEgKGFjdHVhbGl6YWRvIGVsIGByIGZvcm1hdChTeXMudGltZSgpLCAnJWQtJW0tJVknKWApIgpvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDoKICAgICNjc3M6ICIuL2Fzc2V0cy9teV9jc3NfZmlsZS5jc3MiCiAgICB0aGVtZTogcGFwZXIKICAgIGhpZ2hsaWdodDogdGV4dG1hdGUgCiAgICB0b2M6IHRydWUKICAgIHRvY19kZXB0aDogMyAKICAgIHRvY19mbG9hdDogCiAgICAgIGNvbGxhcHNlZDogdHJ1ZQogICAgICBzbW9vdGhfc2Nyb2xsOiB0cnVlCiAgICBzZWxmX2NvbnRhaW5lZDogdHJ1ZQogICAgbnVtYmVyX3NlY3Rpb25zOiBmYWxzZQogICAgZGZfcHJpbnQ6IGthYmxlCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICBjb2RlX2ZvbGRpbmc6IHNob3cKZWRpdG9yX29wdGlvbnM6IAogIGNodW5rX291dHB1dF90eXBlOiBjb25zb2xlCi0tLQoKYGBge2NzcywgZWNobyA9IEZBTFNFfQouY29sdW1ucyB7ZGlzcGxheTpmbGV4O30KaDEudGl0bGUge2ZvbnQtc2l6ZTogNDAgcHg7Y29sb3I6ICNkNzIzMWF9CmgxIHtjb2xvcjojZDcyMzFhOyBmb250LXNpemU6IDMwcHggO2ZvbnQtZmFtaWx5OiBBcmlhbCBCbGFja30KaDJ7Y29sb3I6ICNmYTMzNDQ7IGZvbnQtc2l6ZTogMjBweDsgZm9udC1mYW1pbHk6IEFyaWFsfQoKYm9keSB7IGJhY2tncm91bmQtY29sb3I6ICNGRkM0MEN9CmEge2NvbG9yOiAjMDEwMTAxO30KLmxpc3QtZ3JvdXAtaXRlbS5hY3RpdmUsIC5saXN0LWdyb3VwLWl0ZW0uYWN0aXZlOmZvY3VzLCAubGlzdC1ncm91cC1pdGVtLmFjdGl2ZTpob3ZlciB7CiAgICB6LWluZGV4OiAyOwogICAgY29sb3I6IDsKICAgIGJhY2tncm91bmQtY29sb3I6ICNjNDM0MmQ7CiAgICBib3JkZXItY29sb3I6IHBhbGVyZWQ7Cn0KLm5hdi1waWxscyA+IGxpLmFjdGl2ZSA+IGEsIC5uYXYtcGlsbHMgPiBsaS5hY3RpdmUgPiBhOmhvdmVyLCAubmF2LXBpbGxzID4gbGkuYWN0aXZlID4gCgpgYGAKCmBgYHtyIGNodW5rLXNldHVwLCBpbmNsdWRlID0gRkFMU0V9CmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSwgZXZhbCA9IFRSVUUsIG1lc3NhZ2UgPSBGQUxTRSwgd2FybmluZyA9IEZBTFNFLCAKICAgICAgICAgICAgICAgICAgICAgICNyZXN1bHRzID0gImhvbGQiLAogICAgICAgICAgICAgICAgICAgICAgY2FjaGUgPSBGQUxTRSwgY2FjaGUucGF0aCA9ICIvY2FjaGVzLyIsIGNvbW1lbnQgPSAiIz4iLAogICAgICAgICAgICAgICAgICAgICAgI2ZpZy53aWR0aCA9IDcsICNmaWcuaGVpZ2h0PSA3LCAgIAogICAgICAgICAgICAgICAgICAgICAgI291dC53aWR0aCA9IDcsIG91dC5oZWlnaHQgPSA3LAogICAgICAgICAgICAgICAgICAgICAgY29sbGFwc2UgPSBUUlVFLCAgZmlnLnNob3cgPSAiaG9sZCIsCiAgICAgICAgICAgICAgICAgICAgICBmaWcuYXNwID0gMC42MjgsIG91dC53aWR0aCA9ICI3NSUiLCBmaWcuYWxpZ24gPSAiY2VudGVyIikKYGBgCgpgYGB7ciBvcHRpb25zLXNldHVwLCBpbmNsdWRlID0gRkFMU0V9Cm9wdGlvbnMoc2NpcGVuID0gOTk5KSAjLSBwYXJhIHF1aXRhciBsYSBub3RhY2nDs24gY2llbnTDrWZpY2EKb3B0aW9ucygieWFtbC5ldmFsLmV4cHIiID0gVFJVRSkKYGBgCgpgYGB7ciBrbGlwcHksIGVjaG8gPSBGQUxTRX0Ka2xpcHB5OjprbGlwcHkocG9zaXRpb24gPSBjKCJ0b3AiLCAicmlnaHQiKSkgIy0gcmVtb3Rlczo6aW5zdGFsbF9naXRodWIoInJsZXN1ci9rbGlwcHkiKQpgYGAKCgoKPGhyIGNsYXNzPSJsaW5lYS1ibGFjayI+CgoKVHJhYmFqbyBlbGFib3JhZG8gcGFyYSBsYSBhc2lnbmF0dXJhICJQcm9ncmFtYWNpw7NuIHkgbWFuZWpvIGRlIGRhdG9zIGVuIGxhIGVyYSBkZWwgQmlnIERhdGEiIGRlIGxhIFVuaXZlcnNpdGF0IGRlIFZhbMOobmNpYSBkdXJhbnRlIGVsIGN1cnNvIDIwMjEtMjAyMi4gRWwgcmVwbyBkZWwgdHJhYmFqbyBlc3TDoSBbYXF1w61dKGh0dHBzOi8vZ2l0aHViLmNvbS9tZW5ldWYvdHJhYmFqb19CaWdEYXRhX2VxdWlwbyl7dGFyZ2V0PSJfYmxhbmsifS4gCgoKTGEgcMOhZ2luYSB3ZWIgZGUgbGEgYXNpZ25hdHVyYSB5IGxvcyB0cmFiYWpvcyBkZSBtaXMgY29tcGHDsWVyb3MgcHVlZGVuIHZlcnNlIFthcXXDrV0oaHR0cHM6Ly9wZXJlenA0NC5naXRodWIuaW8vaW50cm8tZHMtMjEtMjItd2ViLzA3LXRyYWJham9zLmh0bWwpe3RhcmdldD0iX2JsYW5rIn0uCgo8aHIgY2xhc3M9ImxpbmVhLXJlZCI+CgoKIyBbMS4gSU5UUk9EVUNDScOTTl17LnZlcmRlY2l0b30KCkVuIGVsIHByZXNlbnRlIHRyYWJham8gdmFtb3MgYSBtb3N0cmFyIGFsZ3Vub3MgZGF0b3MgZGUgaW50ZXLDqXMgZGUgdW5hIGRlIGxhcyBlbXByZXNhcyBtdWx0aW5hY2lvbmFsZXMgbcOhcyBjb25vY2lkYXMgYSBuaXZlbCBtdW5kaWFsLCBNY0RvbmFsZCdzLiBQb3IgdW4gbGFkbywgdmVyZW1vcyBlbCBtZW7DuiBkZSBlc3RhIGZyYW5xdWljaWEsIGFzw60gY29tbyBsb3MgbWFjcm9udXRyaWVudGVzIHF1ZSBjb250aWVuZW4gbG9zIHByb2R1Y3RvcyB5IGxvcyB2YWxvcmVzIG51dHJpY2lvbmFsZXMsIG1vc3RyYW5kbyB5IGV4cGxpY2FuZG8gbG9zIGFzcGVjdG9zIG3DoXMgcmVsZXZhbnRlcy4gVGFtYmnDqW4gdHJhdGFyZW1vcyBkZSBjb21wYXJhcmxvIGNvbiBvdHJvcyBncmFuZGVzIHJlc3RhdXJhbnRlcyBkZSBjb21pZGEgcsOhcGlkYSBlbiBsb3MgRXN0YWRvcyBVbmlkb3MsIHBhw61zIHF1ZSBhY29nZSBtw6FzIGNhbnRpZGFkIGRlIG1hcmNhcyBkZSByZXN0YXVyYW50ZXMgZGUgY29taWRhIHLDoXBpZGEgZW4gZWwgbXVuZG8gcG9yIGV4Y2VsZW5jaWEuIEVuIGxhIHBhcnRlIGZpbmFsLCBjb21lbnRhcmVtb3MgZGUgZm9ybWEgZ2VuZXJhbCBsYSBwb3B1bGFyaWRhZCBkZSBsb3MgbG9jYWxlcyBwb3IgY2l1ZGFkLCBhc8OtIGNvbW8gbGEgZXZvbHVjacOzbiBkZSBzdXMgdmVudGFzIGEgbG8gbGFyZ28gZGUgbG9zIMO6bHRpbW9zIGHDsW9zLiBQb3IgbG8gcXVlIGVuIGVzdGUgdHJhYmFqbyBudWVzdHJvIG9iamV0aXZvIGVzIGluZm9ybWFyIHkgY29uY2llbmNpYXIgYSBsb3MgbGVjdG9yZXMgdW4gcG9jbyBhY2VyY2EgZGUgbG9zIHByb2R1Y3RvcyBvZnJlY2lkb3MgcG9yIE1jRG9uYWxkJ3MgYXPDrSBjb21vIGVsIGltcGFjdG8gcXVlIGVzdGUgaGEgdGVuaWRvIHNvYnJlIGxhIHBvYmxhY2nDs24gZXN0YWRvdW5pZGVuc2UuCgohW01hcmNhIEZyYW5xdWljaWFdKC4vaW1hZ2VuZXMvaW50cm9kdWNjaW9uLmpwZWcpCgojIyAxLjEgQnJldmUgSGlzdG9yaWEKCkVsIHByaW1lciByZXN0YXVyYW50ZSBkZSBNY0RvbmFsZCdzIHNlIHViaWNhYmEgZW4gQ2FsaWZvcm5pYSwgZW4gZWwgYcOxbyAxOTQ4LCBjb21vIHVuIGJhciBkZSBjYXJyZXRlcmEuIEZ1ZXJvbiBsb3MgZG9zIGhlcm1hbm9zIE1hdXJpY2UgeSBSaWNoYXJkIE1jZG9uYWxkIHF1aWVuIGxsZXZhcm9uIGEgY2FibyBlc3RlIHByb3llY3RvLiBMb3MgZWxlbWVudG9zIHF1ZSBsbyBjYXJhY3Rlcml6YWJhbiB5IGZ1ZXJvbiBtb3Rpdm8gZGVsIMOpeGl0byBlcmFuOyBwb3IgdW4gbGFkbywgc2UgcG9kw61hIHBlZGlyIHkgcmVjb2dlciBsb3MgcHJvZHVjdG9zIGRlc2RlIGVsIGNvY2hlLCBsb3MgZ3JhbmRlcyB2ZW50YW5hbGVzIHF1ZSB0ZW7DrWFuIHBlcm1pdMOtYW4gdmVyIGRlc2RlIGZ1ZXJhIGNvbW8gZWwgcGVkaWRvIHNlIHByZXBhcmFiYSB5IHBvciDDumx0aW1vLCBsb3MgYmFqb3MgcHJlY2lvcyBxdWUgbG8gZGlmZXJlbmNpYWJhbiBkZSBjb21wZXRpZG9yZXMuIEVzdGUgw7psdGltbyBlc3R1dm8gYSBwdW50byBkZSBsbGV2YXIgYSBsb3MgaGVybWFub3MgYSBsYSBxdWllYnJhLCBwb3IgbG8gcXVlIGVzdG9zIHR1dmllcm9uIHF1ZSBjZXJyYXIgZWwgbmVnb2NpbyB5IG9yZ2FuaXphciB1bmEgYnVlbmEgZXN0cmF0ZWdpYS4gUmVzdW1pZW5kbywgUmF5IEEuIEtyb2MsIGFsZ3VpZW4gaW1wb3J0YW50ZSBlbiBsb3MgbmVnb2Npb3MgcG9yIGFxdWVsbGEgem9uYSwgdmlvIGVsIHBvdGVuY2lhbCBkZWwgcmVzdGF1cmFudGUgZW4gc2kgeSBjb24gbGEgY2VzacOzbiBkZWwgZGVyZWNobyBkZSBjb21lcmNpYWxpemFyIGxhIG1hcmNhIHBvciBwYXJ0ZSBkZSBsb3MgaGVybWFub3MsIGFicmnDsyBvdHJvIHJlc3RhdXJhbnRlIGVuIElsbGlub2lzLiBZIGFzw60gc2UgcG9kcsOtYSBkZWNpciBxdWUgZW1wZXrDsyBlc3RlIG5lZ29jaW8gcXVlIGFjdHVhbG1lbnRlIHRpZW5lIHRhbnRvIMOpeGl0by4KCgoKIVtQcmltZXIgbG9jYWwgZGUgTWNEb25hbGQnc10oLi9pbWFnZW5lcy9oaXN0b3JpYS5qcGVnKQoKCiMjIDEuMiAgTG9nb3M8L0ZPTlQ+LiB7LnRhYnNldH0KCiMjIyA8Rk9OVCBDT0xPUiA9IkZGNEQwMCI+TG9nbzE8L0ZPTlQ+CgohW0xvZ28xXSguL2ltYWdlbmVzL2xvZ28xLmpwZykKMTk0MC0xOTQ4OgpMYSBoaXN0b3JpYSBkZSBsYSBjYWRlbmEgZGUgcmVzdGF1cmFudGVzIGRlIGNvbWlkYSByw6FwaWRhIG3DoXMgZmFtb3NhIGRlbCBtdW5kbyBjb21lbnrDsyBlbiAxOTM3IGN1YW5kbyBQYXRyaWNrIE1jRG9uYWxkIGxhbnrDsyDCq1RoZSBBaXJkb21lwrssIGVsIHByaW1lciByZXN0YXVyYW50ZSBkZSBsYSBmYW1pbGlhLiBUcmVzIGHDsW9zIG3DoXMgdGFyZGUsIHN1cyBoaWpvcyBsZSBjYW1iaWFyb24gZWwgbm9tYnJlIGEgwqtNY0RvbmFsZOKAmXMgRmFtb3VzIEJhcmJlY3VlwrsuCkVsIHByaW1lciBsb2dvdGlwbyBkZWwgcmVzdGF1cmFudGUgZXN0YWJhIGNvbXB1ZXN0byBwb3IgdW5hIG1hcmNhIGRlbm9taW5hdGl2YSBuZWdyYSwgZGlzdHJpYnVpZGEgZW4gdHJlcyBuaXZlbGVzIHkgZWplY3V0YWRhIGVuIHRyZXMgZXN0aWxvcyBkaWZlcmVudGVzLgoKCiMjIyA8Rk9OVCBDT0xPUj0iRkY0RDAwIj5Mb2dvMjwvRk9OVD4KIVtMb2dvMl0oLi9pbWFnZW5lcy9sb2dvMi5qcGcpCjE5NDgtMTk1MzoKRWwgY29uY2VwdG8gZGUgYmFyYmFjb2EgZnVlIHJlZW1wbGF6YWRvIHBvciBsYXMgaGFtYnVyZ3Vlc2FzLCBxdWUgZXN0YWJhbiBnYW5hbmRvIGNhZGEgdmV6IG3DoXMgcG9wdWxhcmlkYWQgZW4gbG9zIEVzdGFkb3MgVW5pZG9zLiBFbCB0w610dWxvIGRlbCByZXN0YXVyYW50ZSBzZSBtb2RpZmljw7MgZW4gMTk0OCB5IHNlIHJlZGlzZcOxw7MgZWwgbG9nb3RpcG8uIFNlIGHDsWFkZSBsYSBlc3BlY2lmaWNhY2nDs24gwqtidXkgZW0gYnkgdGhlIGJhZ8K7LCBwYXJhIGhhY2VyIGhpbmNhcGnDqSBlbiBsYSBwb3NpYmlsaWRhZCBkZSBjb25zdW1pciBsYSBjb21pZGEgdGFtYmnDqW4gcGFyYSBsbGV2YXIuIEVuIG5lZ3JpdGEgKHkgcmVwZXRpZG8gZG9zIHZlY2VzKSBhcGFyZWNlIGVsIHByZWNpbyBzdXBlciBjb21wZXRpdGl2by4gWSB1biBsb2dvdGlwbyByZXBsZXRvIGRlIGRldGFsbGVzLCBjb24gbGEgaW50ZW5jacOzbiBkZSByZXNhbHRhciB0b2RvcyBsb3MgcHVudG9zIGZ1ZXJ0ZXMgZGVsIHJlc3RhdXJhbnRlOiBsYSBvcmlnaW5hbGlkYWQgZGUgbGEgb2ZlcnRhLCBsYSBtb2RhbGlkYWQgZGUgY29uc3VtbyB5IGVsIGFob3Jyby4KCiMjIyA8Rk9OVCBDT0xPUiA9IkZGNEQwMCI+TG9nbzM8L0ZPTlQ+CiFbTG9nbzNdKC4vaW1hZ2VuZXMvbG9nbzMuanBnKQoxOTUzLTE5Njg6CkxhIGNvbXBhw7HDrWEgZmluYWxtZW50ZSBjYW1iacOzIHN1IG5vbWJyZSBhIHNpbXBsZW1lbnRlIE1hY0RvbmFsZOKAmXMgeSBhcXXDrSBlcyBkb25kZSBjb21pZW56YSB0b2RvLiBFbCBsb2dvIGHDum4gZXN0YWJhIGxlam9zIGRlIGxvIHF1ZSB0b2RvcyBjb25vY2Vtb3MgaG95LCBwZXJvIGVsIGNvbG9yIHJvam8gYXBhcmVjacOzIGVuIGxhIHBhbGV0YSBkZSBjb2xvcmVzLCBkYW5kbyBsYSBkaXJlY2Npw7NuIGNvcnJlY3RhIHBhcmEgbGEgbWFyY2EuRXJhIHVuIGxvZ290aXBvIGJhc3RhbnRlIG1lbW9yYWJsZSB5IHJlY29ub2NpYmxlLCBxdWUgcGVybWFuZWNpw7MgZW4gbGEgZW1wcmVzYSBkdXJhbnRlIDE1IGHDsW9zLgoKIyMjIDxGT05UIENPTE9SPSJGRjREMDAiPkxvZ280PC9GT05UPgohW0xvZ280XSguL2ltYWdlbmVzL2xvZ280LmpwZykKMTk2MS0xOTY4OgpFcyAxOTYxIHkgaGVtb3MgbGxlZ2FkbyBhIHVuIG1vbWVudG8gZGVjaXNpdm8gcGFyYSBNY0RvbmFsZOKAmXM6IGVsIG1vbWVudG8gZW4gcXVlIGFwYXJlY2VuIHBvciBwcmltZXJhIHZleiBsb3MgZmFtb3NvcyDCq0dvbGRlbiBBcmNoZXPCuy4gUGFyYSBlbCBwcm95ZWN0byBkZSB1biBwdW50byBkZSB2ZW50YSBlbiBEb3duZXkgKENhbGlmb3JuaWEpLCBsb3MgaGVybWFub3MgTWNEb25hbGQgZW5jYXJnYW4gZG9zIGdpZ2FudGVzY29zIGFyY29zIGRvcmFkb3MgZW4gbG9zIGV4dHJlbW9zIGRlIGxhIGVzdHJ1Y3R1cmEuIExhIGlkZWEgZXJhIHF1ZSBzZSB2aWVzZSBtZWpvciBpbmNsdXNvIGRlc2RlIGxlam9zLiBFbCBsb2dvdGlwbyBkZSAxOTYxLCBkaXNlw7FhZG8gcG9yIGVsIGRpcmVjdG9yIGNyZWF0aXZvIEppbSBTY2hpbmRsZXIsIGVzdMOhIGluc3BpcmFkbyBlbiBlc3RlIGRldGFsbGUgYXJxdWl0ZWN0w7NuaWNvLiBZIGVzbyBubyBlcyB0b2RvOiBhZGVtw6FzIHNlIGludHJvZHVjZSBlbCBhbWFyaWxsbywgdW4gY29sb3IgcXVlIGluZnVuZGUgZWwgYnVlbiBodW1vciB5IHF1ZSBzZWd1aXLDoSBmb3JtYW5kbyBwYXJ0ZSBkZSBsYSBpZGVudGlkYWQgdmlzdWFsIGRlIGxhIGVtcHJlc2EuCgoKCiMjIyA8Rk9OVCBDT0xPUj0iRkY0RDAwIj5Mb2dvNTwvRk9OVD4KIVtMb2dvNV0oLi9pbWFnZW5lcy9sb2dvNS5qcGcpCjE5NzU6CkxhIG51ZXZhIGltYWdlbiBzZSBpbmNvcnBvcsOzIGEgbGEgaWRlbnRpZGFkIHZpc3VhbCBlbiAxOTc1LiBFbCBlbWJsZW1hIGNvbiBsYSBtYXJjYSBkZW5vbWluYXRpdmEgc2UgY29sb2PDsyBkZW50cm8gZGUgdW4gcmVjdMOhbmd1bG8gcm9qbyBjb24gw6FuZ3Vsb3MgcmVkb25kZWFkb3MuIExhcyBsZXRyYXMgc2UgY2FtYmlhcm9uIGRlIG5lZ3JvIGEgYmxhbmNvLCBsbyBxdWUgcGFyZWPDrWEgbcOhcyBhbWlnYWJsZSB5IGFjb2dlZG9yLgpFc3RhIGluc2lnbmlhIGVzIHByb2JhYmxlbWVudGUgbGEgdmVyc2nDs24gbcOhcyByZWNvbm9jaWJsZSBkZSB0b2RvcyBsb3MgbG9nb3RpcG9zIGRlIGxleWVuZGFzIGRlIGNvbWlkYSByw6FwaWRhIHkgbGEgY29tcGHDscOtYSB0b2RhdsOtYSBsYSB1c2EsIHNpZW5kbyByZWNvbm9jaWJsZSBpbnN0YW50w6FuZWFtZW50ZSBlbiB0b2RvIGVsIG11bmRvIHkgZXZvY2FuZG8gdW5hIHNlbnNhY2nDs24gZGUgYWxlZ3LDrWEsIGZlbGljaWRhZCB5IHBhc2nDs24uCgoKCiMjIyA8Rk9OVCBDT0xPUj0iRkY0RDAwIj5Mb2dvNjwvRk9OVD4KIVtMb2dvNl0oLi9pbWFnZW5lcy9sb2dvNi5qcGcpCkEgcGFydGlyIGRlIDE5ODUgIHNlIG1vZGlmaWNhIHkgc2ltcGxpZmljYSB1bmEgdmV6IG3DoXMgZWwgbG9nb3RpcG8gZW4gdmFyaW9zIHB1bnRvcyBkZWwgbXVuZG8gOiBsb3MgYXJjb3Mgc2Ugc29sYXBhbiBwYXJhIGZvcm1hciBsYSBsZXRyYSBNLiBIZW1vcyBsbGVnYWRvIGFsIGFudGVwYXNhZG8gZGlyZWN0byBkZWwgbG9nb3RpcG8gZGUgaG95LgoKCiMjIyA8Rk9OVCBDT0xPUj0iRkY0RDAwIj5Mb2dvNzwvRk9OVD4KIVtMb2dvN10oLi9pbWFnZW5lcy9sb2dvNy5qcGcpCkEgcGFydGlyIGRlIDIwMDksIExhIGNvbXBhw7HDrWEgTWNEb25hbGTigJlzIGNhbWJpYSBzdSB0cmFkaWNpb25hbCBsb2dvIGRlIGNvbG9yIHJvam8gcG9yIHVubyB2ZXJkZSwgc2Vnw7puIGFudW5jacOzIGxhIG1hcmNhLiBFc3RlIGNhbWJpbyBkZSBjb2xvciBzaW1ib2xpemEgdGXDs3JpY2FtZW50ZSB1bmEgaW1hZ2VuIG3DoXMgZWNvbMOzZ2ljYSB5IHVuYSBudWV2YSBlc3RyYXRlZ2lhIHBvciBwYXJ0ZSBkZSBsYSBlbXByZXNhLiBFbCBjYW1iaW8gZGUgbG9nbyBlcyB1bmEgZGUgbGFzIHTDqWNuaWNhc2RlIG1hcmtldGluZyBxdWUgYWRvcHTDsyBsYSBjYWRlbmEgZGUgY29taWRhIHLDoXBpZGEuIENvbiBlbCBvYmpldGl2byBkZSBtb3N0cmFyIHVuIHBlcmZpbCBtw6FzIGNvbXByb21ldGlkbyBjb24gbGEgcHJlc2VydmFjacOzbiBkZSBsb3MgcmVjdXJzb3MgbmF0dXJhbGVzLCBNY0RvbmFsZOKAmXMgbGFuesOzIHN1IG51ZXZhIGNhbXBhw7FhIHF1ZSBjb25zaXN0ZSBlbiBjYW1iaWFyIGVsIHRyYWRpY2lvbmFsIGZvbmRvIHJvam8gZGUgc3UgbG9nbyBwb3IgdW4gY29sb3IgdmVyZGUgaW50ZW5zby4KCgojIyMgPEZPTlQgQ09MT1I9IkZGNEQwMCI+TG9nbzg8L0ZPTlQ+CiFbTG9nbzhdKC4vaW1hZ2VuZXMvbG9nbzguanBnKQoxOTkzLUhveToKRW4gRXN0YWRvcyBVbmlkb3MsIE1jRG9uYWxkJ3MgaW50cm9kdWpvIGEgbml2ZWwgbmFjaW9uYWwgdW5hIGzDrW5lYSBkZSBjYWbDqSBsbGFtYWRhICJNY0NhZsOpIi4gQSBkaWZlcmVuY2lhIGRlIGxvIHF1ZSBvY3VycmUgZW4gb3Ryb3MgcGHDrXNlcywgIk1jQ2Fmw6kiIGVzIHNvbG8gdW5hIGzDrW5lYSBkZSBiZWJpZGFzIGVzcGVjaWFsZXMsIG5vIHVuYSBjYWZldGVyw61hIGNvbXBsZXRhLiBFbCBlc3RpbG8gZGVsIGxvZ290aXBvIGRlIE1jQ2FmZSBubyBjcmVhIG5pbmfDum4gdsOtbmN1bG8gY29uIGVsIGxvZ290aXBvIGRlIGxhIG1hcmNhIG1hdHJpeiwgTWNEb25hbGTigJlzLiBFbiBjYW1iaW8sIGxhcyBmdWVyemFzIGRlbCBkaXNlw7FvIGRldHLDoXMgZGUgTWNDYWZlIGhhbiBjcmVhZG8gdW5hIGlkZW50aWRhZCBkZSBtYXJjYSBkaXN0aW50aXZhIHkgY29tcGxldGFtZW50ZSBpbmRlcGVuZGllbnRlLgoKIyAyLiBDQVJHQU1PUyBEQVRPUyBZIFBBUVVFVEVTIAoKRXN0ZSB0cmFiYWpvIGhhIHNpZG8gcG9zaWJsZSByZWFsaXphcmxvIGNvbiBsYSBheXVkYSBkZSB2YXJpYXMgZnVlbnRlcyBkZSBkb25kZSBoZW1vcyBzYWNhZG8gbG9zIGRhdG9zLiBFbiBsYSBww6FnaW5hIHdlYiBmYWNpbGl0YWRhIHBvciBsYSBhc2lnbmF0dXJhIChrYWdnbGUpLCBoZW1vcyB1dGlsemlhZG8gcHJpbmNpcGFsbWVudGUgNSBkYXRhc2VzdHMsIHF1ZSBsb3MgaW5kaWNhcmVtb3MgZW4gbGEgw7psdGltYSBwYXJ0ZSwgZW4gbGEgYmlibGlvZ3JhZsOtYS4gUG9yIG90cm8gbGFkbywgaGVtb3MgYWNjZWRpZG8gYSBkb2N1bWVudG9zIG9maWNpYWxlcyBkZWwgcmVzdGF1cmFudGUgb2J0ZW5pZG9zIGVuIGZvcm1hdG8gZXhjZWwgeSBsb3MgaGVtb3MgdHJhbnNmb3JtYWRvIHBhcmEgdHJhYmFqYXIgY29uIGVsbG9zIHkgb2J0ZW5lciBtw6FzIGRhdG9zLgoKCmBgYHtyLCBldmFsID0gVFJVRX0KbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KHJlYWN0YWJsZSkKbGlicmFyeShndCkKbGlicmFyeSh0aWJibGUpCmxpYnJhcnkoInBsb3RseSIpCmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KGhyYnJ0aGVtZXMpCmxpYnJhcnkodmlyaWRpcykKbGlicmFyeShwYXRjaHdvcmspCmxpYnJhcnkoZ2dhbmltYXRlKQpsaWJyYXJ5KHdvcmRjbG91ZDIpCmxpYnJhcnkod2Vic2hvdCkKbGlicmFyeShjb3JycGxvdCkKbGlicmFyeShzcWxkZikKbGlicmFyeShSQ29sb3JCcmV3ZXIpIApsaWJyYXJ5KGthYmxlRXh0cmEpCmxpYnJhcnkoZ2dUaGVtZUFzc2lzdCkKCm1lbnUgPC0gcmlvOjppbXBvcnQoIi4vZGF0b3MvbWVudTEuMS5jc3YiKQpyZXN0YXVyYW50ZXNVUyA8LSByaW86OmltcG9ydCgiLi9kYXRvcy9GYXN0Rm9vZFJlc3RhdXJhbnRzLmNzdiIpCmZhc3Rmb29kcmVzdGF1cmFudHMgPC0gcmlvOjppbXBvcnQoIi4vZGF0b3MvZmFzdGZvb2RyZXN0YXVyYW50cy5jc3YiKQpydXRhNCA8LSBoZXJlOjpoZXJlKCJkYXRvcyIsICJEYXRhZmluaXRpX0Zhc3RfRm9vZF9SZXN0YXVyYW50c19NYXkxOS5jc3YiKQpmYXN0Zm9vZHJlc3RhdXJhbnRzMTkgPC0gcmlvOjppbXBvcnQocnV0YTQpCmluZ3Jlc29zIDwtIHJpbzo6aW1wb3J0KCIuL2RhdG9zL2luZ3Jlc29zMS5jc3YiKQp2ZW50YXMgPC0gcmlvOjppbXBvcnQoIi4vZGF0b3Mvc2FsZXMuY3N2IikKYGBgCgoKCiMgMy4gUkVTVEFVUkFOVEVTIEZBU1QgRk9PRCBFTiBFU1RBRE9TIFVOSURPUwoKIyMgMy4xIE7Dum1lcm8gZGUgcmVzdGF1cmFudGVzIEZhc3RGb29kCgpFbiBlc3RlIGFwYXJ0YWRvIG9ic2VydmFtb3MgIG1lZGlhbnRlIGVsIHNpZ3VpZW50ZSBncsOhZmljbyBkZSBiYXJyYXMgZWwgbsO6bWVybyBkZSByZXN0YXVyYW50ZXMgZGUgZmFzdCBmb29kIGVuIHRvZG8gZWwgcGHDrXMgZGUgRUVVVS4gSGVtb3MgYWNvdGFkbyBlbnRyZSBsb3MgMTAgbm9tYnJlcyBtw6FzIHBvcHVsYXJlcywgZW50cmUgZWxsb3MgTWNEb25hbGQncywgQnVyZ3VlciBLaW5nIG8gVGFjbyBCZWxsLgpgYGB7cn0KbWFzX3Jlc3RhdXJhbnRlcyA8LSByZXN0YXVyYW50ZXNVUyAlPiUgCiAgZ3JvdXBfYnkobmFtZSkgJT4lIAogIG11dGF0ZShuX3Jlc3RhdXJhbnRlcyA9IHN1bShOTiA9IG4oKSkpICU+JQogIGRpc3RpbmN0KG5hbWUsIG5fcmVzdGF1cmFudGVzKSAlPiUKICBhcnJhbmdlKGRlc2Mobl9yZXN0YXVyYW50ZXMpKSAlPiUKICBmaWx0ZXIobl9yZXN0YXVyYW50ZXMgPj0xOTIpIAoKICBnZ19yZXN0YXVyYW50ZXMgPC0gZ2dwbG90KG1hc19yZXN0YXVyYW50ZXMsIGFlcyhuYW1lLCBuX3Jlc3RhdXJhbnRlcykpICsKICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IikgKyB0aGVtZShwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGNvbG91ciA9ICJncmF5IiksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGNvbG91ciA9ICJncmF5IiksCiAgICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAiI0ZGQzQwQyIsCiAgICAgICAgY29sb3VyID0gImFsaWNlYmx1ZSIpLCBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICIjRkZDNDBDIikpCiAgCmdnX3Jlc3RhdXJhbnRlcwpgYGAKCkNvbW8gcG9kZW1vcyB2ZXIsIHBvciBjbGFyYSBkaWZlcmVuY2lhLCBsYSBtYXJjYSBjb24gbcOhcyBsb2NhbGVzIGVzIE1jRG9uYWxkJ3MsIHNlZ3VpZGEgZGUgQnVyZ3VlciBLaW5nIHkgbHVlZ28gZGUgVGFjbyBCZWxsLgoKVW5hIGRlIGxhcyBjbGF2ZXMgZGVsIMOpeGl0byBhbGNhbnphZGEgcG9yIGxhIGVtcHJlc2EgeSBxdWUgaGEgcGVybWl0aWRvIHN1IGV4cGFuc2nDs24gbXVuZGlhbCBzb24gbGFzIHNpZ3VpZW50ZXM6IHBvciB1biBsYWRvLCBsYSBjb25zaXN0ZW5jaWEuIEVzdG8gZXMsIGVuIGN1YWxxdWllciBwYcOtcyBlbiBlbCBxdWUgdCBlbmN1ZW50cmVzLCBsYSBleHBlcmllbmNpYSBlbiBlbCByZXN0YXVyYW50ZSB2YSBhIHNlciBtdXkgc2ltaWxhciwgbG9zIGNsaWVudGVzIHlhIHNhYmVuIHF1ZSBlc3BlcmFyIHBvciBsbyBxdWUgaGFjZSBtdWNobyBtw6FzIGbDoWNpbGVzIHN1cyBkZWNpc2lvbmVzIGRlIHF1ZSBjb21lci4gIERlc3B1w6lzIGRlc3RhY2Fyw61hbW9zIGxhIGlubm92YWNpw7NuLCBwYXJhIHF1ZSBlbCBuZWdvY2lvIG5vIHF1ZWRlIGVzdGFuY2Fkby4gTXV5IGZyZWN1ZW50ZW1lbnRlIGxhIGZyYW5xdWljaWEgbGFuemEgbnVldm9zIHByb2R1Y3RvcyBjb21vIHJlc3B1ZXN0YSBkZSBsYXMgZGVtYW5kYXMgZGVsIGNsaWVudGUsIHNlIHBvZHLDrWEgZGVjaXIgcXVlIGV2b2x1Y2lvbmFuIGNvbiBlbCB0aWVtcG8sIGNvbW8gdmVyZW1vcyB1biBwb2NvIG3DoXMgYWRlbGFudGUuCgojIyAzLjIgSW5ncmVzb3MgcmVzdGF1cmFudGVzIEZhc3RGb29kCgpFbiBlbCBzaWd1aWVudGUgYXBhcnRhZG8sIGFuYWxpemFyZW1vcyBsb3MgaW5ncmVzb3MgZW4gbWlsZXMgZGUgbWlsbG9uZXMgZGUgZMOzbGFyZXMgZGUgbG9zIG1pc21vcyAxMCByZXN0YXVyYW50ZXMgbcOhcyBmYW1vc29zIGRlIEVFVVUuCgpgYGB7cn0KIGRmX2luZ3Jlc29zIDwtIGdncGxvdChpbmdyZXNvcywgYWVzKHg9cmVvcmRlcihSZXN0dXJhbnRlcywgVmFsdWUpLCB5PVZhbHVlLCBmaWxsPVJlc3R1cmFudGVzKSkrCiAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArCiAgY29vcmRfcG9sYXIoc3RhcnQgPSAwLjAxKSArCiAgbGFicyAoeD0iUmVzdGF1cmFudGVzIikgKyBsYWJzKHk9Ik1pbGVzIGRlIG1pbGxvbmVzIGRlIGTDs2xhcmVzIikgKyBsYWJzKHRpdGxlID0gIkluZ3Jlc29zIGRlIGxvcyBSZXN0dXJhbnRlcyBGYXN0Rm9vZCIpICsgbGFicyhzdWJ0aXRsZSA9ICJFbiBtaWxlcyBkZSBtaWxsb25lcyBkZSBkw7NsYXJlcyIpICsgdGhlbWUocGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gIiNGRkM0MEMiKSwKICAgIHBsb3QuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gIiNGRkM0MEMiKSkKCmRmX2luZ3Jlc29zCmBgYAoKCkNvbW8gc2Ugb2JzZXJ2YSBjbGFyYW1lbnRlLCBlbiBsYSBwcmltZXJhIHBvc2ljacOzbiB2b2x2ZXLDrWFtb3MgYSBlbmNvbnRyYXIgYSBudWVzdHJvIHJlc3RhdXJhbnRlLCBxdWUgbGxlZ2EgYSBsb3MgNDAgbWlsIG1pbGxvbmVzIGRlIGTDs2xhcmVzIGFudWFsZXMuIFN1cyBpbmdyZXNvcyBlc3TDoW4gbXV5IHBvciBlbmNpbWEgZGUgY3VhbHF1aWVyYSBkZSBsYXMgb3RyYXMgbWFyY2FzLgoKIyA0LiBNQyBET05BTEQnUwpFbiBlc3RlIGN1YXJ0byBhcGFydGFkbywgdmFtb3MgYSBoYWJsYXIgc29icmUgZWwgcmVzdGF1cmFudGUgZW4gY3Vlc3Rpw7NuIGVuIHTDqXJtaW5vcyBnZW5lcmFsZXMgeSBkZSBsb3MgYXNwZWN0b3MgbcOhcyByZWxldmFudGVzLgoKCiMjIDQuMSBQcm9kdWN0b3MgTWNEb25hbGRzCgpFbiBsYSBzaWd1aWVudGUgdGFibGEsIHNlIHB1ZWRlbiBjb25zdWx0YXIgdG9kb3MgbG9zIHByb2R1Y3RvcyBkZSBsYSBjYXJ0YSBxdWUgb2ZyZWNlbi4gU2UgbXVlc3RyYW4gdW4gdG90YWwgZGUgMjYwIHByb2R1Y3Rvcy4KYGBge3J9CmRmX21lbnUgPC0gbWVudSAlPiUKc2VsZWN0KEl0ZW0pCgpyZWFjdGFibGUoZGZfbWVudSwgZGVmYXVsdFBhZ2VTaXplID0gIDgsICBwYWdpbmF0aW9uVHlwZSA9ICJqdW1wIiwgc2hvd1BhZ2VTaXplT3B0aW9ucyA9ICBUUlVFICwgcGFnZVNpemVPcHRpb25zID0gIGMgKCAxMCAsIDUwICwgMTAwLCAxNTAsIDIwMCwgMjYwICksZGVmYXVsdENvbERlZiA9IGNvbERlZigKICAgIGFsaWduID0gImNlbnRlciIsCiAgICBtaW5XaWR0aCA9IDcwLAogICAgaGVhZGVyU3R5bGUgPSBsaXN0KGJhY2tncm91bmQgPSAiI0ZGRDcwMCIpLAogICAgZmlsdGVyYWJsZSA9IFRSVUUpLCAgaGlnaGxpZ2h0ID0gVFJVRSwgb3V0bGluZWQgPSBUUlVFLAogICAgY29sdW1ucyA9IGxpc3QoCiAgYEl0ZW1gID0gY29sRGVmKHN0eWxlID0gZnVuY3Rpb24odmFsdWUpIHsKICAgIGlmICh2YWx1ZSA+IDApIHsKICAgICAgY29sb3IgPC0gIiNGNUM3MTAifQogICAgICBlbHNlIHsKICAgICAgY29sb3IgPC0gIiNCMjIyMjIiCiAgICB9CiAgICBsaXN0KGNvbG9yID0gY29sb3IsIGZvbnRXZWlnaHQgPSAiYm9sZCIsYmFja2dyb3VuZCA9ICIjQ0QyNjI2IikKICB9KSkpCmBgYAoKCgoKCiMjIDQuMiBDYXRlZ29yaWFzIGRlIHByb2R1Y3RvcyBlbiBNY0RvbmFsZHMKCkRlIGVudHJlIHRvZG9zIGxvcyBwcm9kdWN0b3MsIGVzdG9zIHNlIHBvZHLDrWFuIGRpZmVyZW5jaWFyIGVuIGxhcyBzaWd1aWVudGVzIGNhdGVnb3LDrWFzOgoKYGBge3J9Cm0gPC0gbGlzdCgKICBsID0gNTAsCiAgciA9IDUwLAogIGIgPSAxMDAsCiAgdCA9IDEwMCwKICBwYWQgPSA0CikKbWFya2VyID0gbGlzdChjb2xvciA9IGJyZXdlci5wYWwoOSwgIlNldDEiKSkKcCA8LSBwbG90X2x5KAogIHggPSBtZW51JENhdGVnb3J5LAogIG1hcmtlciA9IGxpc3QoY29sb3IgPSAnI0NEMEJCQycpLAogICAgdHlwZSA9ICJoaXN0b2dyYW0iCiklPiUKICBsYXlvdXQoICAgICAgICAgeGF4aXMgPSBsaXN0KHRpdGxlID0gIiIpLAogICAgICAgICB5YXhpcyA9IGxpc3QodGl0bGUgPSAiIiksCiAgICAgICAgIGF1dG9zaXplID0gVCkKcApgYGAKCgpZIGF1biBxdWUgcGFyZXpjYSBzb3JwcmVuZGVudGUsIGVzdGUgcmVzdGF1cmFudGUgY3VlbnRhIGNvbiBtw6FzIHZhcmllZGFkIGVuIGNhZsOpcyB5IHTDqXMuIEluY2x1c28gYXVucXVlIGEgcHJpbWVyYSB2aXN0YSBsbyBtw6FzIGRlbWFuZGFkbyBzZWEgdW5hIHNpbXBsZSBoYW1idXJndWVzYSBkZSBjYXJuZSwgYWwgbWVub3MgZW4gbnVlc3RybyBwYcOtcy4gRGUgbG8gcXVlIG1lbm9zIHZhcmllZGFkIGhheSBzZXLDrWEgZGUgZW5zYWxhZGFzLiBRdWl6w6EgdGVuZ2Egc2VudGlkbyBwb3JxdWUgZXMgdW5vIGRlIGxvIHByb2R1Y3RvcyBxdWUgc2UgaGEgaW5jb3Jwb3JhZG8gbcOhcyByZWNpZW50ZW1lbnRlLgoKCgoKCgojIDUuVkFMT1JFUyBOVVRSSUNJT05BTEVTCgpBIGNvbnRpbnVhY2nDs24sIHZhbW9zIGEgZGVzdGFjYXIgbG9zIGFzcGVjdG9zIHkgbG9zIHB1bnRvcyBtw6FzIHJlbGV2YW50ZXMgeSBxdWl6w6EgZGVzdGFjYWJsZXMgZGUgbG9zIHByb2R1Y3RvcyBxdWUgb2ZyZWNlIGxhIG1hcmNhIHBlcm8gZW4gdMOpcm1pbm9zIGRlIGxvcyB2YWxvcmVzIG51dHJpY2lvbmFsZXMuCgojIyA1LjEgwr9DdcOhbCBlcyBlbCBwcm9kdWN0byBjb24gbcOhcyBjYWxvcmlhcz8KCkVsIHByb2R1Y3RvIG3DoXMgY2Fsw7NyaWNvIGRlbCByZXN0YXVyYW50ZSwgc29uIGxvcyBudWdndWV0cywgdGFtYmnDqW4gZXMgcG9ycXVlIGN1ZW50YSBjb24gNDAgcGllemFzLgpgYGB7cn0KZGZfY2Fsb3JpYXMgPC0gbWVudSAlPiUKc2VsZWN0KEl0ZW0sIENhbG9yaWVzKSAKCmRmdG9wMSA8LSBkZl9jYWxvcmlhcyAlPiUgc2xpY2VfbWF4KENhbG9yaWVzLCBuPTEpCgpJbWFnZW4gPC0gImh0dHBzOi8vaS5waW5pbWcuY29tL29yaWdpbmFscy9kNS81Zi8wMy9kNTVmMDM1YzM3ZDg0ZWM1NTkzNGJhNmQ0NjliZWRjZS5qcGciCgpkZnRvcDEgPC0gZGZ0b3AxICU+JSBhZGRfY29sdW1uKEltYWdlbikKClRhYmxhX1BtYXNjYWwgPC0gZGZ0b3AxICU+JSBndCgpCgpUYWJsYV9QbWFzY2FsIDwtIFRhYmxhX1BtYXNjYWwgJT4lCiAgICAgICAgICAgICAgICAgICB0YWJfaGVhZGVyKHRpdGxlID0gbWQoIioqUHJvZHVjdG8gY29uIG1hcyBjYWxvcmlhcyoqIikpCiAgICAgICAgICAgICAgICAgICAKVGFibGFfUG1hc2NhbCA8LSBUYWJsYV9QbWFzY2FsICU+JQogICAgICAgICAgICAgICAgdGFiX29wdGlvbnMoaGVhZGluZy5iYWNrZ3JvdW5kLmNvbG9yID0gImNvcmFsIikgJT4lIHRhYl9vcHRpb25zKGhlYWRpbmcudGl0bGUuZm9udC5zaXplID0gMTUsICBjb2x1bW5fbGFiZWxzLmZvbnQud2VpZ2h0ID0gICJib2xkIikKCgpUYWJsYV9QbWFzY2FsIDwtIFRhYmxhX1BtYXNjYWwgICU+JQogIGd0Ojp0ZXh0X3RyYW5zZm9ybShsb2NhdGlvbnMgPSBjZWxsc19ib2R5KGNvbHVtbnMgPSBjKEltYWdlbikpLCBmbiA9IGZ1bmN0aW9uKHgpIHtndDo6d2ViX2ltYWdlKHgsIGhlaWdodCA9IDUwKX0pICU+JSAgY29sc19hbGlnbigKICAgYWxpZ24gPSAiY2VudGVyIikKClRhYmxhX1BtYXNjYWwKYGBgCgoKCgoKCiMjIDUuMiDCv0N1w6FsIGVzIGVsIHByb2R1Y3RvIGNvbiBtZW5vcyBjYWxvcmlhcz8KCkVsIG1lbm9zIGNhbMOzcmljbywgbMOzZ2ljYW1lbnRlIHNlcsOtYSBsYSBib3RlbGxhIGRlIGFndWEKYGBge3J9CmRmbWluMSA8LSBkZl9jYWxvcmlhcyAlPiUgCnNsaWNlX21pbihDYWxvcmllcywgbj0xKSAlPiUKZmlsdGVyIChJdGVtID09ICJEYXNhbmkgV2F0ZXIgQm90dGxlIikgI0Rhc2FuaSBXYXRlciBCb3R0bGUgZXMgdW5vIGRlIGxvcyBwcm9kdWN0b3MgY29uIG1lbm9zIGNhbG9yaWFzIAoKSW1hZ2VuIDwtICJodHRwczovL2kucGluaW1nLmNvbS9vcmlnaW5hbHMvM2MvZGYvYWUvM2NkZmFlYWE1MDRkYjhhYWYxMDA4NDNhMTJhYWNjOTcucG5nIgoKZGZtaW4xIDwtIGRmbWluMSAlPiUgYWRkX2NvbHVtbihJbWFnZW4pCgoKVGFibGFfUG1pbmNhbCA8LSBkZm1pbjEgJT4lIGd0KCkKClRhYmxhX1BtaW5jYWwgPC0gVGFibGFfUG1pbmNhbCAlPiUKICAgICAgICAgICAgICAgICAgIHRhYl9oZWFkZXIodGl0bGUgPSBtZCgiKipQcm9kdWN0byBjb24gbWVub3MgY2Fsb3JpYXMqKiIpKQogICAgICAgICAgICAgICAgICAgClRhYmxhX1BtaW5jYWwgPC0gVGFibGFfUG1pbmNhbCAlPiUKICAgICAgICAgICAgICAgIHRhYl9vcHRpb25zKGhlYWRpbmcuYmFja2dyb3VuZC5jb2xvciA9ICJjb3JhbCIpICU+JSB0YWJfb3B0aW9ucyhoZWFkaW5nLnRpdGxlLmZvbnQuc2l6ZSA9IDE1LCAgY29sdW1uX2xhYmVscy5mb250LndlaWdodCA9ICAiYm9sZCIpCgoKVGFibGFfUG1pbmNhbCA8LSBUYWJsYV9QbWluY2FsICAlPiUKICBndDo6dGV4dF90cmFuc2Zvcm0obG9jYXRpb25zID0gY2VsbHNfYm9keShjb2x1bW5zID0gYyhJbWFnZW4pKSwgZm4gPSBmdW5jdGlvbih4KSB7Z3Q6OndlYl9pbWFnZSh4LCBoZWlnaHQgPSA1MCl9KSAlPiUgIGNvbHNfYWxpZ24oCiAgIGFsaWduID0gImNlbnRlciIpCgpUYWJsYV9QbWluY2FsCmBgYAoKCgoKIyMgNS4zLiAgUHJvZHVjdG9zIGNvbiBtYXlvciBtYWNyb251dHJpZW50ZXM8L0ZPTlQ+LiB7LnRhYnNldH0KCkVuIGVzdGUgYXBhcnRhZG8sIHZhbW9zIGEgbW9zdHJhciBwb3Igc2VwYXJhZG8sIHF1ZSAxMCBwcm9kdWN0b3MsIGVuIHByaW1lciBsdWdhciwgdGllbmVuIG3DoXMgcHJvdGXDrW5hcywgbHVlZ28gY3XDoWxlcyBjdWVudGFuIGNvbiBtw6FzIGdyYXNhcyB5IGN1YWwgZXN0w6EgY29tcHVlc3RvIGNvbiBtw6FzIGNhcmJvaGlkcmF0b3MuCgpFbiBsb3MgZ3LDoWZpY29zIGRlIGNhZGEgbWFjcm9udXRyaWVudGUgcG9kZW1vcyB2ZXJsbywgc29zdGVuaWVuZG8gZWwgY3Vyc29yIHNvYnJlIGVsbG9zLgoKCiMjIyA8Rk9OVCBDT0xPUj0iRkY0RDAwIj5Qcm90ZWluYTwvRk9OVD4KYGBge3J9CmRmMTRwcm9kIDwtIG1lbnUgJT4lCiAgc2VsZWN0KEl0ZW0sIFByb3RlaW4pICU+JQogIGhlYWQoUHJvdGVpbiwgbiA9IDEwTCklPiUKICBncm91cF9ieShJdGVtLCBQcm90ZWluKSAlPiUKICBhcnJhbmdlKGRlc2MoUHJvdGVpbikpCgpkZjE0cHJvZAoKd29yZGNsb3VkMihkYXRhPWRmMTRwcm9kLCBzaXplPTAuMSkKYGBgCgoKIyMjIDxGT05UIENPTE9SPSJGRjREMDAiPkdyYXNhczwvRk9OVD4KYGBge3J9CnRvdGFsZmF0IDwtIG1lbnUgJT4lCiBzZWxlY3QoSXRlbSwgRmF0KSAKCgpkZl9mYXQgPC0gdG90YWxmYXQgJT4lCmhlYWQoRmF0LCBuPSAxMEwpICU+JQpncm91cF9ieShJdGVtLCBGYXQpICU+JQphcnJhbmdlKGRlc2MoRmF0KSkKCmRmX2ZhdAoKCnBsb3RfbHkoeCA9IGRmX2ZhdCRJdGVtLCB5PWRmX2ZhdCRGYXQsY29sb3IgPSBkZl9mYXQkSXRlbSxjb2xvcnMgPSBwYWxldHRlKCJQYXN0ZWwgMiIpLCB0eXBlID0gImJveCIpICU+JSAKICBsYXlvdXQodGl0bGUgPSAiTG9zIDEwIHByb2R1Y3RvcyBjb24gbcOhcyBncmFzYSIsCiAgICAgICAgIHhheGlzID0gbGlzdCh0aXRsZSA9ICIiKSwKICAgICAgICAgeWF4aXMgPSBsaXN0KHRpdGxlID0gIiIpLAogICAgICAgICBzaG93bGVnZW5kPUZBTFNFLAogICAgICAgICBhdXRvc2l6ZSA9IFQpIApgYGAKIAoKIyMjIDxGT05UIENPTE9SPSJGRjREMDAiPkNhcmJvaGlkcmF0b3M8L0ZPTlQ+CmBgYHtyfSAKY2FyYm9zIDwtIG1lbnUgJT4lCnNlbGVjdChJdGVtLENhcmJvaHlkcmF0ZXMpCgpkZl9jYXJib3MgPC0gY2FyYm9zICU+JQpoZWFkKENhcmJvaHlkcmF0ZXMsIG49IDEwTCkgJT4lCmdyb3VwX2J5KEl0ZW0sIENhcmJvaHlkcmF0ZXMpICU+JQphcnJhbmdlKGRlc2MoQ2FyYm9oeWRyYXRlcykpCgpkZl9jYXJib3MKCnBsb3RfbHkoeCA9IGRmX2NhcmJvcyRJdGVtLCB5PWRmX2NhcmJvcyRDYXJib2h5ZHJhdGVzLGNvbG9yID0gZGZfY2FyYm9zJEl0ZW0sIGNvbG9ycyA9IHBhbGV0dGUoImFscGhhYmV0IiksIHR5cGUgPSAiYm94IikgJT4lIAogICAgICAgICBsYXlvdXQodGl0bGU9IkxvcyAxMCBwcm9kdWN0b3MgY29uIG3DoXMgY2FyYm9oaWRyYXRvcyIsCiAgICAgICAgIHhheGlzID0gbGlzdCh0aXRsZSA9ICIiKSwKICAgICAgICAgeWF4aXMgPSBsaXN0KHRpdGxlID0gIiIpLAogICAgICAgICBzaG93bGVnZW5kPUZBTFNFLAogICAgICAgICBhdXRvc2l6ZSA9IFQpCmBgYAoKCkVuIGN1YW50byBhbCBwcm9kdWN0byBjb24gbcOhcyBwcm90ZcOtbmFzIHNlIGVuY29udHJhcsOtYSBlbCBTdGVhayAmIEVnZyBNY011ZmZpbiwgcXVlIHNlIGVuY3VlbnRhIGRlbnRybyBkZSBsYSBzZWNjacOzbiBkZSBsb3MgZGVzYXl1bm9zLiBDb24gbcOhcyBncmFzYSB5IGEgbGEgdmV6IGNvbiBtw6FzIGhpZHJhdG9zIHRlbmRyw61hbW9zIGFsIEJhY29uLCBFZ2cgJiBDaGVlc2UgQmlzY3VpdCAoTGFyZ2UgQmlzY3VpdCkuCgoKCgoKIyMgNS40LiAgUHJvZHVjdG9zIGNvbiBtYXlvciBtaWNyb251dHJpZW50ZXMgPC9GT05UPi4gey50YWJzZXR9IAoKIyMjIDxGT05UIENPTE9SPSJGRjREMDAiPlZpdGFtaW5hQTwvRk9OVD4KRW4gZXN0ZSBhcGFydGFkbywgcmVwZXRpbW9zIGxhIG1pc21hIG9wZXJhY2nDs24gcXVlIGVuIGVsIHB1bnRvIGFudGVyaW9yIHBlcm8gYWhvcmEgY29uIGxvcyBtaWNyb251dHJpZW50ZXMsIHNlcGFyYWRvcyBlbjogdml0YW1pbmEgQSB5IEMsIGZpYnJhLCBjYWxjaW8geSBoaWVycm8uIEVuIGxhIHBhcnRlIGluZmVyaW9yIGRlIGNhZGEgbGlzdGEsIGxvIHBvZGVtb3Mgb2JzZXJ2YXIgdGFtYmnDqW4gZ3LDoWZpY2FtZW50ZQoKYGBge3J9CnZpdGFtaW5hQSA8LSBtZW51ICU+JQpzZWxlY3QoSXRlbSxWaXRhbWluQSkKCmRmX3ZpdGFtaW5hMSA8LSB2aXRhbWluYUEgJT4lCmhlYWQoVml0YW1pbkEsIG49IDEwTCklPiUKYXJyYW5nZShkZXNjKFZpdGFtaW5BKSkKCmRmX3ZpdGFtaW5hMQoKZ3JhZmljbyA8LSBkZl92aXRhbWluYTEgJT4lCiAgZ2dwbG90KCBhZXMoSXRlbSwgVml0YW1pbkEsIHNpemUgPSAwLjc1LCBjb2xvcj0gIm9yYW5nZSIpKSArCiAgZ2VvbV9wb2ludCgpICsKICB0aGVtZV9idygpKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsKICBsYWJzKHggPSBOVUxMKSArIHRoZW1lKGF4aXMudGl0bGUueD1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50ZXh0Lng9ZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGlja3MueD1lbGVtZW50X2JsYW5rKCkpICsgbGFicyh0aXRsZT0gIkxvcyAxMCBwcm9kdWN0b3MgY29uIG3DoXMgVml0YW1pbmEgQSIpICsKICB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAnd2hlYXQxJywgY29sb3VyID0gJ3JlZCcpKSArIHRoZW1lKHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICIjRkZDNDBDIiksCiAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICIjRkZDNDBDIiwKICAgICAgICBjb2xvdXIgPSAiI0ZGQzQwQyIpKQoKZ2dwbG90bHkoZ3JhZmljbykKYGBgCgoKIyMjIDxGT05UIENPTE9SPSJGRjREMDAiPlZpdGFtaW5hQzwvRk9OVD4KYGBge3J9CnZpdGFtaW5hQyA8LSBtZW51ICU+JQpzZWxlY3QoSXRlbSxWaXRhbWluQykKCmRmX3ZpdGFtaW5hMiA8LSB2aXRhbWluYUMgJT4lCmhlYWQgKFZpdGFtaW5DLCBuID0gMTBMKSU+JQphcnJhbmdlKGRlc2MoVml0YW1pbkMpKQoKZGZfdml0YW1pbmEyCgoKZGZncmFmaWNvMSA8LSBnZ3Bsb3QoZGZfdml0YW1pbmEyLCBhZXMoSXRlbSwgY29sb3I9Vml0YW1pbkMpKSArIAogIGdlb21fYmFyKGZpbGw9TkEpICsgCiAgY29vcmRfZmxpcCgpICsKICB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAnbGlnaHRibHVlMScpKSArIHRoZW1lKHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICIjRkZDNDBDIiksCiAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICIjRkZDNDBDIiksCiAgICBsZWdlbmQuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gIiNGRkM0MEMiKSkKCmdncGxvdGx5KGRmZ3JhZmljbzEpCmBgYAoKCgojIyMgPEZPTlQgQ09MT1I9IkZGNEQwMCI+RmlicmE8L0ZPTlQ+ICAgICAgICAKYGBge3J9ICAgICAgICAKICAgICAgICAKZmlicmEgPC0gbWVudSAlPiUKc2VsZWN0KEl0ZW0sRGlldGFyeUZpYmVyKQoKZGZfZmlicmEgPC0gZmlicmEgJT4lCmhlYWQoRGlldGFyeUZpYmVyLCBuPSAxMEwpICU+JQphcnJhbmdlKGRlc2MoRGlldGFyeUZpYmVyKSkKCmRmX2ZpYnJhCgoKbSA8LSBsaXN0KAogIGwgPSA1MCwKICByID0gNTAsCiAgYiA9IDEwMCwKICB0ID0gMTAwLAogIHBhZCA9IDQKKQptYXJrZXIgPSBsaXN0KGNvbG9yID0gYnJld2VyLnBhbCg5LCAiU2V0MSIpKQpwIDwtIHBsb3RfbHkoCiAgeCA9IG1lbnUkQ2F0ZWdvcnksCiAgbWFya2VyID0gbGlzdChjb2xvciA9ICcjNDUxNzFEJykKKQogICAgICAgICAgICAgICAgCm1lbnUgJT4lICAKcGxvdF9seSggeCA9IGRmX2ZpYnJhJEl0ZW0sIHkgPSBkZl9maWJyYSREaWV0YXJ5RmliZXIsIHR5cGU9InNjYXR0ZXIiLCBtb2RlID0gIm1hcmtlcnMiICwgbWFya2VyPWxpc3QoIGNvbG9yPWNvbG9yUmFtcFBhbGV0dGUoYnJld2VyLnBhbCg4LCJEYXJrMiIpKSgxMDApICwgb3BhY2l0eT0wLjkpICkgJT4lIGxheW91dCh0aXRsZSA9ICJMb3MgMTAgcHJvZHVjdG9zIGNvbiBtw6FzIGZpYnJhIiwKICAgICAgICAgeGF4aXMgPSBsaXN0KHRpdGxlID0gIiIpLAogICAgICAgICB5YXhpcyA9IGxpc3QodGl0bGUgPSAiIiksCiAgICAgICAgIHNob3dsZWdlbmQ9RkFMU0UsYXV0b3NpemUgPSBGLCB3aWR0aCA9IDUwMCwgaGVpZ2h0ID0gNDAwLG1hcmdpbj1tKQpgYGAKCgojIyMgPEZPTlQgQ09MT1I9IkZGNEQwMCI+Q2FsY2lvPC9GT05UPgpgYGB7cn0gICAgICAgIApjYWxjaW8gPC0gbWVudSAlPiUKc2VsZWN0KEl0ZW0sQ2FsY2l1bSkKCmRmX2NhbGNpdW0gPC0gY2FsY2lvICU+JQpoZWFkKENhbGNpdW0sIG49IDEwTCkgJT4lCmFycmFuZ2UoZGVzYyhDYWxjaXVtKSkKCmRmX2NhbGNpdW0KCgpwIDwtIGdncGxvdChkZl9jYWxjaXVtLCBhZXMoSXRlbSwgQ2FsY2l1bSkpICsgCiAgZ2VvbV9wb2ludCgpICsgCiAgZ2VvbV9zZWdtZW50KGFlcyh4PWZvcmNhdHM6OmZjdF9yZW9yZGVyKEl0ZW0sIENhbGNpdW0sIC5kZXNjID0gVFJVRSksCiAgICAgICAgICAgICAgICAgICB4ZW5kPWZvcmNhdHM6OmZjdF9yZW9yZGVyKEl0ZW0sIENhbGNpdW0sIC5kZXNjID0gVFJVRSksCiAgICAgICAgICAgICAgICAgICB5PTAsCiAgICAgICAgICAgICAgICAgICB5ZW5kPUNhbGNpdW0sIGNvbG9yPXBhbGV0dGUoIlRhYmxlYXUgMTAiKSkpICsgCiAgZ2VvbV9zbW9vdGgoKSArCiAgdGhlbWUoYXhpcy50aXRsZS54PWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRleHQueD1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcy54PWVsZW1lbnRfYmxhbmsoKSkgKwogIGxhYnModGl0bGUgPSAiTG9zIDEwIHByb2R1Y3RvcyBjb24gbcOhcyBjYWxjaW8iLAogICAgICAgICAgICAgIHN1YnRpdGxlID0gImFuw7FvIDIwMTkiLCAKICAgICAgICAgICAgICBjYXB0aW9uID0gIkRhdG9zIHByb3ZlbmllbnRlcyBkZSBLYWdnbGUiLAogICAgICAgICAgICAgIHggPSAiUHJvZHVjdG9zIiwKICAgICAgICAgICAgICB5ID0gIkNhbGNpbyIpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSArIHRoZW1lKHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICIjRkZDNDBDIiksCiAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICIjRkZDNDBDIikpCgoKZ2dwbG90bHkocCkKYGBgCgoKCgojIyMgPEZPTlQgQ09MT1I9IkZGNEQwMCI+SGllcnJvPC9GT05UPgpgYGB7cn0KaGllcnJvIDwtIG1lbnUgJT4lCiBzZWxlY3QoSXRlbSwgSXJvbikgCgpkZl9oaWVycm8gPC0gaGllcnJvICU+JQpoZWFkKElyb24sIG49IDEwTCkgJT4lCmdyb3VwX2J5KEl0ZW0sIElyb24pICU+JQphcnJhbmdlKGRlc2MoSXJvbikpCgpkZl9oaWVycm8KCmRmIDwtIGdncGxvdChkZl9oaWVycm8sIGFlcyh4PUl0ZW0sIHk9SXJvbikpICsKICBnZW9tX3NlZ21lbnQoIGFlcyh4PUl0ZW0sIHhlbmQ9SXRlbSwgeT0wLCB5ZW5kPUlyb24pKSArCiAgZ2VvbV9wb2ludCggc2l6ZT01LCBjb2xvcj0icmVkIiwgZmlsbD1hbHBoYSgib3JhbmdlIiwgMC4zKSwgYWxwaGE9MC43LCBzaGFwZT0yMSwgc3Ryb2tlPTIpICsgdGhlbWUoYXhpcy50aXRsZS54PWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRleHQueD1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcy54PWVsZW1lbnRfYmxhbmsoKSkgKyAgbGFicyh0aXRsZSA9ICJMb3MgMTAgcHJvZHVjdG9zIGNvbiBtw6FzIGNhbGNpbyIsCiAgICAgICAgICAgICAgc3VidGl0bGUgPSAiYW7DsW8gMjAxOSIsIAogICAgICAgICAgICAgIGNhcHRpb24gPSAiRGF0b3MgcHJvdmVuaWVudGVzIGRlIEthZ2dsZSIsCiAgICAgICAgICAgICAgeCA9ICJQcm9kdWN0b3MiLAogICAgICAgICAgICAgIHkgPSAiQ2FsY2lvIikgKyAKICB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAiI0ZGQzQwQyIpLAogICAgcGxvdC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAiI0ZGQzQwQyIpKQoKZ2dwbG90bHkoZGYpCmBgYAoKCkVsIGRlc2F5dW5vIGRlIFNhdXNhZ2UgTWNNdWZmaW4gd2l0aCBFZ2csIGVzIGVsIHF1ZSBlbmNvbnRyYW1vcyBjb24gbcOhcyB2aXRhbWluYSBBIHkgZWwgQmFjb24sIEVnZyAmIENoZWVzZSBCaXNjdWl0IChSZWd1bGFyIEJpc2N1aXQpLCBjb24gbcOhcyB2aXRhbWluYSBDLgoKRW4gY3VhbnRvIGFsIGFsaW1lbnRvIGNvbiBtw6FzIGZpYnJhLCBkaXLDrWFtb3MgZWwgRWdnIE1jTXVmZmluLCBxdWUgZW4gbHVnYXIgZGUgY2FybmUsIHBvc2VlIHVuIGh1ZXZvIGVuIHN1IGludGVyaW9yLgoKU2F1c2FnZSBNY011ZmZpbiB3aXRoIEVnZyB2dWVsdmUgYSByZXBldGlyc2UgY29tbyBlbCBwcm9kdWN0byBjb24gbcOhcyBjYWxjaW8gZGUgZW50cmUgdG9kb3MgeSBTdGVhayAmIEVnZyBNY011ZmZpbiBlcyBlbCBxdWUgYXBhcmVjZSBjb24gbcOhcyBoaWVycm8uCgoKCgojIyA1LjUgQ29ycmVsYWNpw7NuCgpFbiBlc3RlIGdyw6FmaWNvIHNlIGNvbmNlbnRyYSB5IHNlIG11ZXN0cmEgbGEgY29ycmVsYWNpw7NuIHF1ZSB0aWVuZW4gZW50cmUgc8OtIGxvcyBudXRyaWVudGVzIGRlIGxvcyBwcm9kdWN0b3MgcXVlIHNlIGVuY3VlbnRyYW4gZW4gbGEgY2FydGEgZGUgTWNEb25hbGQncy4KYGBge3J9Cm1lbnUgPC0gbmEub21pdChtZW51KQpzY2FsZWRtZW51IDwtIGRhdGEuZnJhbWUoc2NhbGUobWVudVtjKDQ6MjQpXSkpCm1lbnUxPC1jYmluZChtZW51WzE6M10sc2NhbGVkbWVudSkKCk0gPC0gY29yKHNjYWxlZG1lbnUpCmNleC5iZWZvcmUgPC0gcGFyKCJjZXgiKQpwYXIoY2V4ID0gMC43KQpjb3JycGxvdChNLCBpbnNpZyA9ICJibGFuayIsIG1ldGhvZCA9ICJzcXVhcmUiLCAgdGwuY2V4ID0gLjc1KQpwYXIoY2V4ID0gY2V4LmJlZm9yZSkKYGBgCgoKCiMjIDUuNi4gQ29tYmkgcGVyZmVjdGEKCkVuIGVzdGUgcHVudG8gbGxhbWFtb3MgY29tYmkgcGVyZmVjdGEsIGFsIHByb2R1Y3RvIG1lbm9zIGNhbMOzcmljbyBkZSBjYWRhIGNhdGVnb3LDrWEuCkVzdG8gaGFjZSBwb3NpYmxlIHF1ZSBhdW4gc2llbmRvIE1jIERvbmFsZCdzIHVuIGx1Z2FyIGRlIGNvbWlkYSBwb2NvIHNhbHVkYWJsZSBzZSBwdWVkYSBzYWJlciBxdWUgb3BjaW9uZXMgcHVlZGUgY29nZXIgdW4gY2xpZW50ZSBxdWUgcHJldGVuZGEgY29tZXIgbGFzIG1lbm9zIGNhbG9yw61hcyBwb3NpYmxlcyBwb3IgbG8gcXVlIGFsIHRlbmVyIGxvcyBwcm9kdWN0b3MgbWVub3MgY2Fsw7NyaWNvcyBkZSBjYWRhIGNhdGVnb3JpYSwgZWwgY2xpZW50ZSBwdWVkZSBjb25mb3JtYXJzZSBhc8OtIHN1IHByb3BpbyBtZW7DuiBhdGVuZGllbmRvIGEgbG8gcXVlIGVzdGUgc29saWNpdGEuCmBgYHtyfQpNaW5jYWw8LWFnZ3JlZ2F0ZShtZW51JENhbG9yaWVzLCBieT1saXN0KG1lbnUkQ2F0ZWdvcnkpLCBGVU49bWluKQpjb2xuYW1lcyhNaW5jYWwpWzFdPC0iQ2F0ZWdvcnkiCmNvbG5hbWVzKE1pbmNhbClbMl08LSJDYWxvcmllcyIKTWluY2FsbWVudTwtc3FsZGYoInNlbGVjdCBhLkNhdGVnb3J5LGEuSXRlbSwgYS5DYWxvcmllcyBmcm9tIG1lbnUgYSwgTWluY2FsIGIgd2hlcmUgYS5DYXRlZ29yeT09Yi5DYXRlZ29yeSBhbmQgYS5DYWxvcmllcz09Yi5DYWxvcmllcyIgKQojIyBUaGUgYmVsb3cgdGFibGUgZ2l2ZXMgdGhlIG1pbnVtdW0gQ2Fsb3JpZSBJdGVtIGZyb20gRWFjaCBDYXRlZ29yeQpNaW5jYWxtZW51CgoKCmtuaXRyOjprYWJsZShNaW5jYWxtZW51KSAlPiUKICBrYWJsZUV4dHJhOjprYWJsZV9zdHlsaW5nKGZ1bGxfd2lkdGggPSBGKSAlPiUKICBjb2x1bW5fc3BlYygxLCBib2xkID0gVCwgYm9yZGVyX3JpZ2h0ID0gVCkgJT4lCiAgcm93X3NwZWMoMSwgYm9sZCA9IFQsIGNvbG9yID0gIndoaXRlIiwgYmFja2dyb3VuZCA9IHBhbGV0dGUoIlBhc3RlbCAyIikpICU+JSAKICByb3dfc3BlYygyOjIsIGJvbGQgPSBULCBjb2xvciA9ICJ3aGl0ZSIsIGJhY2tncm91bmQgPSBwYWxldHRlKCJUYWJsZWF1IDEwIikgKSAlPiUKICByb3dfc3BlYygzOjMsIGJvbGQgPSBULCBjb2xvciA9ICJ3aGl0ZSIsIGJhY2tncm91bmQgPSBwYWxldHRlKCJQb2x5Y2hyb21lIDM2IikgKSAlPiUKICByb3dfc3BlYyg0OjUsIGJvbGQgPSBULCBjb2xvciA9ICJ3aGl0ZSIsIGJhY2tncm91bmQgPSBwYWxldHRlKCJPa2FiZS1JdG8iKSApICU+JQogIHJvd19zcGVjKDY6NiwgYm9sZCA9IFQsIGNvbG9yID0gIndoaXRlIiwgYmFja2dyb3VuZCA9IHBhbGV0dGUoIlBhaXJlZCIpICkgJT4lCiAgcm93X3NwZWMoNzo3LCBib2xkID0gVCwgY29sb3IgPSAid2hpdGUiLCBiYWNrZ3JvdW5kID0gIiMyMjk3RTYiKSAlPiUKICByb3dfc3BlYyg4OjE2LCBib2xkID0gVCwgY29sb3IgPSAid2hpdGUiLCBiYWNrZ3JvdW5kID0gIiMyOEUyRTUiKSAlPiUgCiAgcm93X3NwZWMoMTc6MjMsIGJvbGQgPSBULCBjb2xvciA9ICJ3aGl0ZSIsIGJhY2tncm91bmQgPSAiIzYxRDA0RiIpICU+JQogIHJvd19zcGVjKDI0OjI1LCBib2xkID0gVCwgY29sb3IgPSAid2hpdGUiLCBiYWNrZ3JvdW5kID0gIiNERjUzNkIiKSAlPiUgCiAgcm93X3NwZWMoMCwgYW5nbGUgPSAwKQpgYGAKCgoKIyA2LlRJUE9TIERFIEFMSU1FTlRPUwoKQ29tbyB0b2RvcyBzYWJlbW9zIE1jRG9uYWxkJ3Mgb2ZyZWNlIHVuYSBjYXJ0YSBtdXkgYW1wbGlhIGRlIHByb2R1Y3RvcyBkZSB0b2RvIHRpcG8sIG3DoXMgZ3JhbmRlcyBvIG3DoXMgcGVxdWXDsW9zLCBtw6FzIGNhbMOzcmljbyBvIG1lbm9zLCBtw6FzIHNhbm9zIG8gbWVub3MgbnV0cmljaW9uYWxtZW50ZSBoYWJsYW5kbywgZXRjLiAKRXMgY29ub2NpZG8gc29icmV0b2RvIHBvciBsYXMgY29taWRhcyB5IGNlbmFzIHNpZW5kbyBlc3RhcyBlbiBsYXMgcXVlIHZhbiBtw6FzIGNsaWVudGVzLCBzaW4gZW1iYXJnbyBNYyBkb25hbGQncyBkZXNkZSBxdWUgYWJyaW8gbGEgem9uYSBkZSBNYyBDYWZlIGN1ZW50YSBjb24gdW5hIGdyYW4gdmFyaWVkYWQgZGUgY2Fmw6lzIHBhcmEgY3VhbHF1aWVyIGhvcmEgZGVsIGTDrWEgYXPDrSBjb21vIGRlIGRlc2F5dW5vcyB5IGRlIHNuYWNrcy4gWSBjYWJlIGRlc3RhY2FyIHF1ZSB0YW1iacOpbiBoYSBxdWVyaWRvIGFkYXB0YXJzZSBhIG9wY2lvbmVzIG3DoXMgc2FsdWRhYmxlcyBwYXJhIGFzw60gbGxlZ2FyIGEgdG9kYXMgbGFzIHBlcnNvbmFzLCBvZnJlY2llbmRvIGNvbWlkYSBtw6FzIHNhbmEgeSBtZW5vcyBzYW5hLlBvciBlc28gdmFtb3MgYSBtb3N0cmFyIDMgdGlwb3MgZGUgYWxpbWVudG9zLCBxdWUgcHJvYmFibGVtZW50ZSBubyBzZWFuIGNvbm9jaWRvcyBuaSBhc29jaWFkb3MgYSB1bmEgZnJhbnF1aWNpYSBjb21vIE1jIERvbmFsZCdzIHRhbiBhcnJhaWdhZGEgYSBsYXMgaGFtYnVyZ3Vlc2FzLgoKIyMgNi4xLkJyZWFrZmFzdAoKCmBgYHtyfQpnZ3Bsb3Qoc3Vic2V0KG1lbnUsQ2F0ZWdvcnk9PSJCcmVha2Zhc3QiKSwgYWVzKHJlb3JkZXIoSXRlbSxDYWxvcmllcyksQ2Fsb3JpZXMsZmlsbD1DYWxvcmllcykpICsgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIpICArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikrZ2d0aXRsZSgiQnJlYWtmYXN0IFZzIENhbG9yaWVzIikgKyB4bGFiKCJJdGVtIikgKyB5bGFiKCJDYWxvcmllcyIpICArIGNvb3JkX2ZsaXAoKSArIHRoZW1lKHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICIjRkZDNDBDIiksCiAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICIjRkZDNDBDIikpCmBgYAoKCiMjIDYuMi4gU2FsYWQgTWVudQpgYGB7cn0KZ2dwbG90KHN1YnNldChtZW51LENhdGVnb3J5PT0iU2FsYWRzIiksIGFlcyhyZW9yZGVyKEl0ZW0sQ2Fsb3JpZXMpLENhbG9yaWVzLGZpbGw9Q2Fsb3JpZXMpKSArIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiKSAgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpK2dndGl0bGUoIlNhbGFkcyBNZW51IFZzIENhbG9yaWVzIikgKyB4bGFiKCJJdGVtIikgKyB5bGFiKCJDYWxvcmllcyIpICArIGNvb3JkX2ZsaXAoKSArIHRoZW1lKHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICIjRkZDNDBDIiksCiAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICIjRkZDNDBDIikpCmBgYAoKCiMjIDYuMy4gU25hY2tzIApgYGB7cn0KZ2dwbG90KHN1YnNldChtZW51LENhdGVnb3J5PT0iU25hY2tzICYgU2lkZXMiKSwgYWVzKHJlb3JkZXIoSXRlbSxDYWxvcmllcyksQ2Fsb3JpZXMsZmlsbD1DYWxvcmllcykpICsgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIpICArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikrZ2d0aXRsZSgiU25hY2tzICYgU2lkZXMgTWVudSBWcyBDYWxvcmllcyIpICsgeGxhYigiSXRlbSIpICsgeWxhYigiQ2Fsb3JpZXMiKSAgKyBjb29yZF9mbGlwKCkgKyB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAiI0ZGQzQwQyIpLAogICAgcGxvdC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAiI0ZGQzQwQyIpKQpgYGAKCgojIyA2LjQuIENvZmZlZSBhbmQgVGVhCmBgYHtyfQpDb2ZmZWVhbmR0ZWE8LXN1YnNldChtZW51LENhdGVnb3J5PT0iQ29mZmVlICYgVGVhIikKQ29mZmVlYW5kdGVhIDwtIENvZmZlZWFuZHRlYVtvcmRlcigtQ29mZmVlYW5kdGVhJENhbG9yaWVzKSxdCkNvZmZlZWFuZHRlYTwtQ29mZmVlYW5kdGVhWzE6MjAsXQpnZ3Bsb3QoQ29mZmVlYW5kdGVhLCBhZXMocmVvcmRlcihJdGVtLENhbG9yaWVzKSxDYWxvcmllcyxmaWxsPUNhbG9yaWVzKSkgKyBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IikgICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKStnZ3RpdGxlKCJDb2ZmZWUgJiBUZWEgTWVudSBWcyBDYWxvcmllcyIpICsgeGxhYigiSXRlbSIpICsgeWxhYigiQ2Fsb3JpZXMiKSAgKyBjb29yZF9mbGlwKCkgKyB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAiI0ZGQzQwQyIpLAogICAgcGxvdC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAiI0ZGQzQwQyIpKQpgYGAKIAoKCiMgNy5QT1BVTEFSSURBRAoKRW4gZXN0ZSBhcGFydGFkbyBhbmFsaXphcm1lb3MgeSBtb3N0cmFyZW1vcyBsYSAicG9wdWxhcmlkYWQiIGRlIG51ZXN0cm8gcmVzdGF1cmFudGUgZW4gYWxndW5hcyBkZSBsYXMgY2l1ZGFkZXMgZGUgRUVVVSwgYSB0cmF2w6lzIGRlIHVuIGdyw6FmaWNvIGRlIGJhcnJhcy4gVmVyZW1vcyBlbCBuw7ptZXJvIGRlIGxvY2FsZXMgZGUgbGEgZnJhbnF1aWNpYSBjb24gbG9zIHF1ZSBjdWVudGFuIGxhcyBjaXVkYWRlcyBxdWUgc2UgbXVlc3RyYW4uCgohW1Jlc3RhdXJhbnRlIE1jIERvbmFsZCdzXSguL2ltYWdlbmVzL3BvcHUuanBlZykKCgoKYGBge3J9IApudW1tYWMgPC0gcmVzdGF1cmFudGVzVVMgJT4lCiAgc2VsZWN0KGNpdHksIG5hbWUpICU+JQogICBncm91cF9ieShjaXR5KSAlPiUgCiAgbXV0YXRlKG5uX21hYyA9IHN1bShOTj1uKCkpKSAlPiUgCiAgZmlsdGVyKG5hbWUgPT0gIk1jRG9uYWxkJ3MiKSAlPiUgCiAgZGlzdGluY3QoY2l0eSwgbm5fbWFjKSAlPiUKICB1bmdyb3VwKCkKCnRvcDEwIDwtIG51bW1hYyAlPiUKICBzbGljZV9tYXgobm5fbWFjICwgbj0xMCkgCgpncmFmaWNvMSA8LSBnZ3Bsb3QgKHRvcDEwLCBhZXMoeD1ubl9tYWMsIHkgPSBjaXR5KSwgYWVzKGZjdF9yZXYobm5fbWFjKSkpICsgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiLCBmaWxsID0gInJlZCIpICsgY29vcmRfZmxpcCgpICsgbGFicyh4ID0gIk51bWVybyBkZSBNY0RvbmFsZHMiLCB5ID0gIkNpdHkiKStsYWJzKHRpdGxlID0gIkxvY2FsZXMgcG9yIGNpdWRhZCIpICArIHRoZW1lKHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICIjRkZDNDBDIiksCiAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICIjRkZDNDBDIikpCgpncmFmaWNvMQpgYGAKCgoKQ29uIGdyYW4gdmVudGFqYSBzb2JyZSBsb3MgZGVtw6FzLCBsYSBjaXVkYWQgcXVlIGN1ZW50YSBjb24gbcOhcyBsb2NhbGVzIHNlcsOtYSBDaW5jaW5uYXRpLgoKWSBlcyBxdWUgZXN0ZSByZXN0YXVyYW50ZSBlcyBtdW5kaWFsbWVudGUgcmVjb25vY2lkbywgdGFudG8gcG9yIHNlciB1bmEgb3JnYW5pemFjacOzbiBjb21lcmNpYWwgZGUgYWx0YSBjYWxpZGFkLCBjb21vIHBvciBzZXIgdW5hIGRlIGxhcyBtZWpvcmVzIG9wb3J0dW5pZGFkZXMgZGUgb2ZlcnRhIGRlIEZyYW5xdWljaWFzLiBQdWVkZSBwdWVzLCBxdWUgbGEgY2xhdmUgZGUgc3Ugw6l4aXRvIGVzIHRlbmVyIHVuYSBiYXNlIG11eSBmaXJtZSBlbiBzdXMgZnJhbnF1aWNpYXRhcmlvcy4KCiMgOC4gVkVOVEFTCgpQb3Igw7psdGltbywgdmFtb3MgYSBoYWJsYXIgc29icmUgbGFzIHZlbnRhcyBkZWwgcmVzdGF1cmFudGUsIGluZm9ybWFjacOzbiBxdWUgaGVtb3MgY29uc2lkZXJhZG8gaW1wb3J0YW50ZSB0ZW5lciBlbiBjdWVudGEgeSBwb3IgZWxsbyBtb3N0cmFyb3MuIFkgZXMgcXVlIGVzdGEgbWFyY2EgY3VlbnRhIGNvbiAyNiBtaWwgbG9jYWxlcyBlbiB0b2RvIGVsIG11bmRvLCAxNCBtaWwgbWlsbG9uZXMgZGUgY29taWRhcyB2ZW5kaWRhcyBhbCBhw7FvLCA1IGVzdGFibGVjaW1pZW50b3MgbnVldm9zIHNlIGFicmVuIGNhZGEgZMOtYSwgdmVudGEgZGUgMTQ1IGhhbWJ1cmd1ZXNhcyBwb3Igc2VndW5kbyB5IHVuIG1pbGzDs24geSBtZWRpbyBkZSBlbXBsZWFkb3MuCgpgYGB7cn0KdmVudGFzbWMgPC0gdmVudGFzJT4lCiAgc2VsZWN0KEHDsW9zLFZlbnRhcykKCgogZ2dwbG90KCBkYXRhPSB2ZW50YXMsIGFlcyh4PUHDsW9zLCB5PVZlbnRhcykpICsKICAgIGdlb21fbGluZSgpICsKICAgIGdlb21fcG9pbnQoKSArCiAgICBnZ3RpdGxlKCJFdm9sdWNpw7NuIGRlIGxhcyB2ZW50YXMgZGUgTUMgRG9uYWxkJ3MgZGVzZGUgMjAwNS0yMDE5IikgKwogICB0aGVtZV9pcHN1bSgpICsKICAgIHlsYWIoIk7Dum1lcm8gZGUgdmVudGFzIikgKwogICAgdHJhbnNpdGlvbl9yZXZlYWwoQcOxb3MpICsgdGhlbWUocGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChmYW1pbHkgPSAic2FucyIpLAogICAgcGxvdC5jYXB0aW9uID0gZWxlbWVudF90ZXh0KGZhbWlseSA9ICJzYW5zIiksCiAgICBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KGZhbWlseSA9ICJzYW5zIiksCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGZhbWlseSA9ICJzYW5zIiksCiAgICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAiI0ZGQzQwQyIpLAogICAgcGxvdC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAiI0ZGQzQwQyIpKQpgYGAKCkVuIGVzdGUgZ3LDoWZpY28gdmVtb3MgbGEgZXZvbHVjacOzbiBkZSBsYXMgdmVudGFzIGRlIE1jRG9uYWxkJ3MgZW50cmUgMjAwNSB5IDIwMTkKCiMjIDguMSBMb2NhbGVzIHkgZW1wbGVhZG9zCgpgYGB7cn0KCmdyYWZsb2MgPC0gZ2dwbG90KCBkYXRhPSB2ZW50YXMsIGFlcyh4PUHDsW9zLCB5PUxvY2FsZXMpKSAKICAKIGdyYWZsb2MgKyAgZ2VvbV9saW5lKCkgKwogICAgZ2VvbV9wb2ludCgpICsKICAgIGdndGl0bGUoIkV2b2x1Y2nDs24gZGUgbG9zIGVzdGFibGVjaW1pZW50b3MgZGUgTUMgRG9uYWxkJ3MgZGVzZGUgMjAwNS0yMDE5IikgKwogICB0aGVtZV9pcHN1bSgpICsKICAgIHlsYWIoIk7Dum1lcm8gZGUgZXN0YWJsZWNpbWllbnRvcyIpICsKICAgIHRyYW5zaXRpb25fcmV2ZWFsKEHDsW9zKSsKICAgICAgbGFicyhzdWJ0aXRsZSA9ICJFbiBtaWxlcyIpICsgdGhlbWUocGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChmYW1pbHkgPSAic2FucyIpLAogICAgcGxvdC5jYXB0aW9uID0gZWxlbWVudF90ZXh0KGZhbWlseSA9ICJzYW5zIiksCiAgICBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KGZhbWlseSA9ICJzYW5zIiksCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGZhbWlseSA9ICJzYW5zIiksCiAgICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAiI0ZGQzQwQyIpLAogICAgcGxvdC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAiI0ZGQzQwQyIpKQpgYGAKCmBgYHtyfQogZW1wbGVhZG9zIDwtIHZlbnRhcyU+JQogIHNlbGVjdChBw7FvcyxFbXBsZWFkb3MpCiAgCiAgZ3JhZmVtcGwgPC0gZ2dwbG90KCBkYXRhPSB2ZW50YXMsIGFlcyh4PUHDsW9zLCB5PUVtcGxlYWRvcykpIAogICBncmFmZW1wbCsgIGdlb21fbGluZSgpICsKICAgIGdlb21fcG9pbnQoKSArCiAgICBnZ3RpdGxlKCJFdm9sdWNpw7NuIGRlbCBuw7ptZXJvIGRlIGVtcGxlYWRvcyBkZSBNQyBEb25hbGQncyBkZXNkZSAyMDEzLTIwMTkiKSArCiAgIHRoZW1lX2lwc3VtKCkgKwogICAgeWxhYigiTsO6bWVybyBkZSBFbXBsZWFkb3MiKSArCiAgICB0cmFuc2l0aW9uX3JldmVhbChBw7FvcykgKyB0aGVtZShwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KGZhbWlseSA9ICJzYW5zIiksCiAgICBwbG90LmNhcHRpb24gPSBlbGVtZW50X3RleHQoZmFtaWx5ID0gInNhbnMiKSwKICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoZmFtaWx5ID0gInNhbnMiKSwKICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoZmFtaWx5ID0gInNhbnMiKSwKICAgIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICIjRkZDNDBDIiksCiAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICIjRkZDNDBDIikpCiBlbXBsZWFkb3M8LSBuYS5vbWl0KGVtcGxlYWRvcykKYGBgCiAKIApQYXJ0aWN1bGFybWVudGUgTWNEb25hbGTigJlzIHJlc3VsdGEgdW4gY2FzbyBpbnRlcmVzYW50ZSBhIGNvbnRlbXBsYXIgcHVlc3RvIHF1ZSBhw7FvIGNvbiBhw7FvIGVzIHBvc2libGUgbm90YXIgcXVlIHRpZW5lIG1lbm9zIGVtcGxlYWRvcyBwZXJvIGNyZWNlIGRlIGZvcm1hIGltcG9ydGFudGUuIExhIGZpcm1hIHF1ZSBlbiBzdSBtb21lbnRvIHB1ZG8gbGxlZ2FyIGEgcHJlc3VtaXIgZGUgaGFiZXIgY29udHJhdGFkbyBhIHVubyBkZSBjYWRhIG9jaG8gdHJhYmFqYWRvcmVzIGVuIGxvcyBFc3RhZG9zIFVuaWRvcyBoYSBpZG8gcmVkdWNpZW5kbyBsYSBjYW50aWRhZCBkZSBjb2xhYm9yYWRvcmVzLCBjb3NhIHF1ZSBwb2Ryw61hIHBhcmVjZXIgbmVnYXRpdmEgcHVlcyBlbCBjcmVjaW1pZW50byBtdWNoYXMgdmVjZXMgaW1wbGljYSBxdWUgZXMgbmVjZXNhcmlvIHN1bWFyIGEgbcOhcyBwZXJzb25hcy4KVGFsIGNvbW8gbG8gcHJlc2VudGFtb3MgZW4gbGEgZ3LDoWZpY2EgZGUgZXN0ZSBkw61hLCBkZSAyMDEyIGEgMjAxOCBlcyBwb3NpYmxlIG5vdGFyIGNvbW8gaGEgaWRvIGRpc21pbnV5ZW5kbyBkZSBmb3JtYSBzaWduaWZpY2F0aXZhIGxhIGNhbnRpZGFkIGRlIGVtcGxlYWRvcyBkZSBNY0RvbmFsZOKAmXMgYSBuaXZlbCBnbG9iYWwuIENvbW8gc2UgbG9ncmEgb2JzZXJ2YXIsIGR1cmFudGUgMjAxMiBoYWLDrWEgNDQwIG1pbCB0cmFiYWphZG9yZXMsIHBhcmEgMjAxNSB5YSBlcmFuIDQyMCBtaWwgbWllbnRyYXMgcXVlIHBhcmEgZWwgYcOxbyAyMDE4IGxhIGNhbnRpZGFkIHlhIHNlIGhhYsOtYSByZWR1Y2lkbyBhIGxhIG1pdGFkIGNvbiByZXNwZWN0byBhIGxvIHJlcG9ydGFkbyBlbiAyMDE1LCBlcyBkZWNpciwgc2UgdGllbmUgcmVnaXN0cm8gZGUgc29sbyAyMTAgbWlsIGVtcGxlYWRvcyBoYXN0YSBlbCBhw7FvIHBhc2Fkby4KIArCv1BvciBxdcOpIGhheSBtZW5vcyBlbXBsZWFkb3Mgc2kgaGF5IG3DoXMgcmVzdGF1cmFudGVzPwoKRWwgaGVjaG8gZGUgcXVlIGxhIG1hcmNhIGRlIGxvcyBhcmNvcyBkb3JhZG9zIHRlbmdhIG1lbm9zIHBlcnNvbmFsIHkgbcOhcyByZXN0YXVyYW50ZXMgb2JlZGVjZSBwcmluY2lwYWxtZW50ZSBhIGxhIHZpc2nDs24gYSBmdXR1cm8gZGUgbGEgY29tcGHDscOtYSwgYSBsYSB0ZWNub2xvZ8OtYSB5IGxhIGZvcm1hIGVuIHF1ZSBoYSBkZWNpZGlkbyBnZXN0aW9uYXJzZS4gRXNwZWPDrWZpY2FtZW50ZSBlbiBlbCBjYXNvIGRlIGxvcyBlbXBsZWFkb3MsIGVzIHBvc2libGUgbm90YXIgcXVlIE1jRG9uYWxk4oCZcyBoYSBkZWNpZGlkbyBhcG9zdGFyIGVuIGdyYW4gbWVkaWRhIHBvciBhY2Npb25lcyBjb21vIGxhIG9wY2nDs24gZGUgcXVlIGxhcyBwZXJzb25hcyBwaWRhbiBzdSBjb21pZGEgYSB0cmF2w6lzIGRlIGFwcHMgZGVzZGUgbGFzIGN1YWxlcyBwdWVkZW4gaW5jbHVzbyBwYWdhciB5IG90cmFzIGhlcnJhbWllbnRhcyBkZSBzZWxmLXNlcnZpY2UgZW4gbG9zIHJlc3RhdXJhbnRlcywgY29tbyBraW9zY29zIGRlc2RlIGxvcyBjdWFsZXMgbG9zIGNvbnN1bWlkb3JlcyBzZSBlbmNhcmdhbiBkZSBnZXN0aW9uYXIgc3VzIMOzcmRlbmVzLiBTZSBlc3BlcmEgcXVlIHBhcmEgZmluYWxlcyBkZSBlc3RlIGHDsW8sIGVuIEVzdGFkb3MgVW5pZG9zLCBtw6FzIGRlIDEyIG1pbCB1YmljYWNpb25lcyBkZSBNY0RvbmFsZOKAmXMgY3VlbnRlbiBjb24gbWVuw7pzIGRpZ2l0YWxlcyB5IGtpb3Njb3MgZGUgYXV0b3NlcnZpY2lvLgoKCiMgQ09OQ0xVU0lPTgpEZXNwdcOpcyBkZWwgYW7DoWxpc2lzIHJlYWxpemFkbyBlbiBlbCBwcmVzZW50ZSB0cmFiYWpvIHBvZGVtb3MgbGxlZ2FyIGEgdW5hIHNlcmllIGRlIGNvbmNsdXNpb25lcyByZXNwZWN0byBhbCByZXN0YXVyYW50ZSBlbiBjdWVzdGnDs246IE1jIERvbmFsZOKAmXMuIExhIGZyYW5xdWljaWEgbcOhcyBleGl0b3NhIGEgbml2ZWwgbXVuZGlhbCwgYSBwZXNhciBkZSBoYWJlcnNlIGVuZnJlbnRhZG8gYSBkZXNhZsOtb3MgZGUgY29tcGV0ZW5jaWEgYSBuaXZlbCBtdW5kaWFsLCBzaWd1ZSBlbiBlbCB0b3AgMSBkZSByZXN0YXVyYW50ZXMgZGVsIG11bmRvLgoKQ29tbyB0b2RvIGVsIG11bmRvIHNhYmUsIGVsIG1lbsO6IHNpZW1wcmUgaGEgc2lkbyBtdXkgcGFyZWNpZG8gYSBsbyBsYXJnbyBkZSBsb3MgYcOxb3MsIHN1ZWxlbiBpbmNvcnBvcmFyIG51ZXZvcyBwcm9kdWN0b3MsIHN1cHJpbWlyIG90cm9zLCBlbiBmdW5jacOzbiBkZWwgw6l4aXRvIHF1ZSB0ZW5nYW4sIHBlcm8gY29tbyBoZW1vcyBtZW5jaW9uYWRvIGFudGVyaW9ybWVudGUgc8OtIHF1ZSBlcyB2ZXJkYWQgcXVlIGNvbW8gZGVzdGlubyBwYXJhIGNvbWVyIGFsZ28gZXMgdW5hIGFwdWVzdGEgc2VndXJhIHBvcnF1ZSBzYWJlcyBwZXJmZWN0YW1lbnRlIGxvIHF1ZSB2YXMgYSBjb21lciwgZWwgZW50b3JubyBvIGVsIGxvY2FsIGVuIGVsIHF1ZSB0ZSB2YXMgYSBlbmNvbnRyYXIsIGVsIGFtYmllbnRlLCBldGMuIFlhIHF1ZSB0b2RvcyBsb3MgcmVzdGF1cmFudGVzLCBlc3TDqXMgZW4gbGEgcGFydGUgZGVsIG11bmRvIGVuIGxhIHF1ZSBlc3TDqXMsIHNvbiBtdXkgc2ltaWxhcmVzIGVudHJlIHPDrS4gCgpBIHBlc2FyIGRlIGxhcyBjcsOtdGljYXMgeSBvcGluaW9uZXMgcXVlIHJlY2liZSBlc3RlIHJlc3RhdXJhbnRlIGRlIGNvbWlkYSByw6FwaWRhLCBsYSB2YXJpZWRhZCBkZSBwcm9kdWN0b3MgcXVlIG9mcmVjZSBlcyBtdXkgYW1wbGlhIHkgcGVybWl0ZSBxdWUgZWwgY29uc3VtaWRvciB0ZW5nYSBkaWZlcmVudGVzIG9wY2lvbmVzIGFsIGd1c3RvLgoKT3RybyBhc3BlY3RvIGltcG9ydGFudGUgY29tZW50YWRvIGVuIGVzdGUgdHJhYmFqbywgZXMgcXVlIGHDum4gcXVlIGxhIGdlbnRlIG5vIHNlIHBhcmUgYSBwZW5zYXJsbywgZXN0YSBtYXJjYSBoYWNlIHVuYSBncmFuIGxhYm9yIHNvY2lhbCwgY29uIGltcGFjdG8gcG9zaXRpdm8gYSBsYSBzb2NpZWRhZC4gQ29tbyBwb3IgZWplbXBsbyBlbiB0w6lybWlub3MgZGUgcHVlc3RvcyBkZSB0cmFiYWpvLCBvIGNvbW8gc2UgbWVuY2lvbmEgZW4gbGEgw7psdGltYSBwYXJ0ZSwgbGEgaW52ZXJzacOzbiBlbiBudWV2b3MgbcOpdG9kb3MgdGVjbm9sw7NnaWNvcyB5IGxhIHZpc2nDs24gcGFyYSBlbCBmdXR1cm8gcXVlIHNlIHByZXbDqSBzaWVtcHJlIGFkYXB0w6FuZG9zZSBhIGxvcyBkaXN0aW50b3MgY2FtYmlvcyBxdWUgc3VjZWRlbiBhIG51ZXN0cm8gYWxyZWRlZG9yLgoKTnVlc3RybyBvYmpldGl2byBjb24gZXN0ZSBwcm95ZWN0bywgeSBlc3BlcmFtb3MgcXVlIGNvbnNlZ3VpZG8sIGVzIGRhciBhIGNvbm9jZXIgdW4gcG9jbyBtw6FzIGVsIHJlc3RhdXJhbnRlIGVuIGxvIHF1ZSBzZSB0cmF0YSBkZSBsb3MgcHJvZHVjdG9zIHF1ZSBvZnJlY2UuIEF1bnF1ZSB5YSBiYXN0YW50ZSBjb25vY2lkYSBlcyBsYSBtYXJjYSB5IHN1IG1lbsO6LCBubyBlc3TDoSBkZSBtw6FzIGNvbm9jZXIgY29tcGxldGFtZW50ZSBvIHBvciBsbyBtZW5vcyBkZXRhbGxhZGFtZW50ZSBsb3MgYXNwZWN0b3MgY29tZW50YWRvcyBhcXXDrS4KClBvciDDumx0aW1vLCBtZW5jaW9uYXIgcXVlIGVsIMOpeGl0byBxdWUgdHV2byBsYSBmcmFucXVpY2lhIGVuIHN1cyBpbmljaW9zIGhhIGNvbnRpbnVhZG8gYSBsbyBsYXJnbyBkZSB0b2RvcyBlc3RvcyDDumx0aW1vcyBhw7FvcyB5IHNlIHByZXbDqSBxdWUgY29udGluw7plIGFsIG1lbm9zIGxvcyBtaXNtb3MgYcOxb3MgcXVlIHlhIGxsZXZhIGVuIHBpZS4gUG9ycXVlIGNvbW8geWEgaGVtb3MgbWVuY2lvbmFkbywgZXMgdW4gZGVzdGlubyBhdHJhY3Rpdm8gcGFyYSBlbCBww7pibGljbyBzb2JyZSB0b2RvIGpvdmVuIHkgbWllbnRyYXMgc2lnYSBhc8OtIGxhIGRlbWFuZGEsIGxhIG9mZXJ0YSBubyBzZXLDoSBtZW5vcy4KCgoKCgojIEJJQkxJT0dSQUZJQQoKLSBbZW5sYWNlIGEgbGEgcMOhZ2luYSB3ZWIgZGUgbGEgYXNpZ25hdHVyYV0oaHR0cHM6Ly9wZXJlenA0NC5naXRodWIuaW8vaW50cm8tZHMtMjEtMjItd2ViL2luZGV4Lmh0bWwpCi0gW2VubGFjZSBnYWxlcmlhIGRlIGdyw6FmaWNvcyBkZSBnZ3Bsb3QyXShodHRwczovL3d3dy5yLWdyYXBoLWdhbGxlcnkuY29tLykKLSBbcmVwb3NpdG9yaW8gZGUgbG9zIGRhdG9zIGRlbCB0cmFiYWpvXShodHRwczovL3d3dy5rYWdnbGUuY29tL2plc3lmYXgvbWMtZG9uYWxkLW1lbnUtYW5hbHlzaXMpCi0gW3JlcG9zaXRvcmlvIGRlIGxvcyBkYXRvcyBkZWwgdHJhYmFqb10oaHR0cHM6Ly93d3cua2FnZ2xlLmNvbS9tYXJjZGV2ZWF1eC9tY2RvbmFsZC1zLW1lbnUvc2NyaXB0KQotIFtyZXBvc2l0b3JpbyBkZSBsb3MgZGF0b3MgZGVsIHRyYWJham9dKGh0dHBzOi8vd3d3LmthZ2dsZS5jb20vZGV2aXNhbmdlZXRoYS9jYWxvcmllcy13ZS1lYXQtaW4tbWNkb25hbGQtcy9yZXBvcnQpCi0gW3JlcG9zaXRvcmlvIGRlIGxvcyBkYXRvcyBkZWwgdHJhYmFqb10oaHR0cHM6Ly93d3cua2FnZ2xlLmNvbS9tYXJjZGV2ZWF1eC9tY2RvbmFsZC1zLW1lbnUvc2NyaXB0KQotIFtyZXBvc2l0b3JpbyBkZSBsb3MgZGF0b3MgZGVsIHRyYWJham9dKGh0dHBzOi8vd3d3LmthZ2dsZS5jb20vYWRob2s5My9udXRyaXRpb24tdmFsdWUtaW4tbWNkb25hbGQtcy1mb29kL3JlcG9ydCkKLSBbZW5sYWNlIGEgbGEgcMOhZ2luYSB3ZWIgZGUgbG9zIGRhdG9zIGVjb27Ds21pY29zIGRlbCB0cmFiYWpvXShodHRwczovL2luZm9ncmFtLmNvbS9pbmdyZXNvcy1hbnVhbGVzLWRlLW1jZG9uYWxkcy1taWxlcy1kZS1taWxsb25lcy1kZS1kb2xhcmVzLTFobnE0MXFsMHczZDYzeikKLSBbZW5sYWNlIGEgbGEgcMOhZ2luYSB3ZWIgZGUgbG9zIGRhdG9zIGVjb27Ds21pY29zIGRlbCB0cmFiYWpvXShodHRwczovL2VzLndpa2lwZWRpYS5vcmcvd2lraS9BbmV4bzpDYWRlbmFzX2RlX2NvbWlkYV9yJUMzJUExcGlkYV9wb3JfaW5ncmVzb19hbnVhbCkKYGBgCgoKPGJyPjxicj4KCjxkaXYgY2xhc3M9InRvY2lmeS1leHRlbmQtcGFnZSIgZGF0YS11bmlxdWU9InRvY2lmeS1leHRlbmQtcGFnZSIgc3R5bGU9ImhlaWdodDogMDsiPjwvZGl2PgoKCgoKCgoKCgoK