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í.
3. Funcionamiento
3.1 Temporada
La temporada NBA suele comenzar a mediados de octubre, cuando comienza la temporada regular (regular season), en la que cada equipo jugará 82 partidos. Los calendarios y numero de enfrentamientos entre cada equipo lo dictamina la conferencia y la división en la que se encuentre cada equipo. Existen 2 conferencias, Este y Oeste, y cada una de ellas aportará sus 8 equipos mejor clasificados a la post-temporada (playoffs).
Debido al COVID-19, cada conferencia aportará 6 equipos fijos, mas 2 adicionales que resultarán de un play-in jugado por los puestos 7º, 8º, 9º y 10º de cada conferencia.
Finalmente, los playoffs, enfrentamientos al mejor de 7 partidos, en los que el ganador avanza de ronda y el perdedor queda eliminado. Los campeones de cada conferencia (equipos ganadores del cuadro), se disputarán la Final de la NBA.
3.2 Draft
El draft de la NBA es el proceso por el cuál los jóvenes universitarios y europeos acceden a la liga. A diferencia de como puede pasar en Europa con otros deportes como el fútbol, donde los equipos más ricos pueden llevarse a jugadores prometedores desde muy pequeños a golpe de talonario, en la NBA se realiza un sorteo similar a la lotería, donde los equipos son asignados con diversas rondas del draft (elecciones), con las que pueden elegir a estos talentos. Sólo jugadores menores de 22 años pueden declararse elegibles, y para ellos es la única vía de ingresar a la NBA hasta alcanzar dicha edad, cuando ya podrán firmar como agentes libres.
Este proceso supone la mayor baza en favor de la competitividad entre todas las franquicias integrantes, ya que los equipos con peores resultados en la temporada anterior, tienen mayor probabilidad de obtener rondas altas del draft, considerándose estas como las primeras elecciones. Tanto es así, que en muchas ocasiones, una buena elección en el draft de la NBA puede redirigir el rumbo de una franquicia perdedora hacia un candidato al título durante los años próximos, como lo fueron los Chicago Bulls de Michael Jordan (nº 3 en 1984), los San Antonio Spurs de Tim Duncan (nº 1 en 1997), o los Golden State Warriors de Stephen Curry (nº 7 en 2009), todos ellos superestrellas escogidas en el draft por el equipo campeón.
Para mostrar la importancia del draft en la competición:
lidert_part <- seasons_stats_jug %>%
select(Player, G) %>%
group_by(Player) %>%
mutate(total_part = sum(G)) %>%
arrange(desc(total_part)) %>%
distinct(Player, total_part)
lidert_part$Player <- gsub("[*]","",lidert_part$Player)
lidert_puntos <- seasons_stats_jug %>%
dplyr::rename( "triples" = "3P", "dospuntos" = "2P") %>%
select(Year, Player, triples, dospuntos, FT)
lidert_puntos[is.na(lidert_puntos)] <- 0
lidert_puntos2 <- lidert_puntos %>% mutate(puntos = triples*3 + dospuntos*2 + FT) %>%
select(Player, puntos) %>%
group_by(Player) %>%
mutate(total_puntos = sum(puntos)) %>%
arrange(desc(total_puntos)) %>%
distinct(Player, total_puntos)
lidert_puntos2$Player <- gsub("[*]","",lidert_puntos2$Player)
ppp <- left_join(lidert_part, lidert_puntos2, c('Player' = 'Player')) %>% mutate(pointspg = total_puntos/total_part) %>%
filter( pointspg < 500) %>%
arrange(desc(pointspg))
ppp_draft <- left_join(ppp, all_jug, c('Player' = 'player_name')) %>%
select(Player, total_part, total_puntos, pointspg, draft_number) %>%
distinct(pointspg, draft_number) %>% na.omit() %>% group_by(draft_number) %>%
mutate(media_draft = mean(pointspg)) %>%
distinct(draft_number, media_draft) %>%
arrange(desc(media_draft))
#correlación elección del draft con puntos anotados
ppp_draft[, c(1)] <- sapply(ppp_draft[, c(1)], as.numeric)
ppp_draft_num <- ppp_draft %>% filter(draft_number < 61) %>% filter(draft_number > 0)
gg_draft <- ggplot(ppp_draft_num, aes(x=draft_number, y=media_draft)) +
geom_point() +
geom_smooth(method=lm , color="red", fill="yellow", se=TRUE) +
scale_x_continuous(
breaks = seq(0, 60, 5),
limits = c(0, 60))+
scale_y_continuous(
breaks = seq(0, 18, 2),
limits = c(0, 18)) + theme(axis.line = element_line(colour = "yellow",
linetype = "solid"), panel.grid.major = element_line(linetype = "blank"),
panel.grid.minor = element_line(linetype = "blank"),
plot.title = element_text(size = 15,
hjust = 0.5), panel.background = element_rect(fill = "beige"),
plot.background = element_rect(fill = "beige")) +labs(title = "Media de puntos por elección",
x = "Nº Draft", y = "Media de puntos por partido")
ggplotly(gg_draft)
Para la realización de este gráfico, se han tenido en cuenta los puestos en los que han sido elegidos cada uno de los jugadores de la NBA en toda su historia, y la media de puntos por partido que poseen en su carrera. Y realizando la media por cada una de las posiciones, obtenemos una correlación positiva entre las primeras elecciones del draft, y los mayores valores en puntos por partido.
Por último, para afianzar esta idea, veamos la relación entre la posición de elección en el draft con el premio individual más prestigioso de la competición, el MVP.
premios <- awards %>% filter(winner == 'TRUE') %>% group_by(award, player) %>%
mutate(mas_premios = sum(NN = n())) %>%
distinct(player, award, mas_premios)
mvp <- premios %>% filter(award == 'nba mvp') %>% arrange(desc(mas_premios))
mvp$player <- iconv(mvp$player, from = 'UTF-8', to = 'LATIN1')
mvp_draft <- left_join(mvp, all_jug, c('player' = 'player_name')) %>%
distinct(player, award, mas_premios, draft_number) %>% na.omit() %>%
arrange(desc(draft_number))
mvp_draft[, c(4)] <- sapply(mvp_draft[, c(4)], as.numeric)
ggmvp <- ggplot(mvp_draft, aes(x = player, y = draft_number, size = mas_premios)) + geom_point(color='red') + coord_flip() + theme(panel.background = element_rect(fill = "beige"),
plot.background = element_rect(fill = "beige"),
legend.key = element_rect(fill = "beige"),
legend.background = element_rect(fill = "beige")) +labs(x = "Jugador", y = "Nº Draft", size = "Nº MVPs")
ggplotly(ggmvp)
Cabe mencionar que en el gráfico no aparecen todos los ganadores del MVP en la historia, ya que durante los comienzos el sistema de elección era diferente, por lo que no existe una asignación en el draft para los primeros ganadores.
En cuanto al gráfico, se aprecia perfectamente como los ganadores se sitúan en las primeras elecciones del draft, como Lebron James, nº1 del draft 2003 con 4 MVPs, o Michael Jordan, nº 3 del draft 1984 con 5 MVPs. A modo de excepción, tenemos al actual ganador, Nikola Jokic, que batió el record como MVP elegido más tarde en un Draft, concretamente en la posición nº 41 en 2014.
4. Líderes estadísticos
La estadística es un apartado fundamental en la NBA. El desempeño de los jugadores se mide en gran parte por la capacidad que éstos tienen para ayudar el equipo en términos cuantitativos con puntos anotados, asistencias, rebotes, etc…
Primero que nada, un repaso por los líderes estadísticos históricos
lidert_puntos <- seasons_stats_jug %>%
dplyr::rename( "triples" = "3P", "dospuntos" = "2P") %>%
select(Year, Player, triples, dospuntos, FT)
lidert_puntos[is.na(lidert_puntos)] <- 0
lidert_puntos2 <- lidert_puntos %>% mutate(puntos = triples*3 + dospuntos*2 + FT) %>%
select(Player, puntos) %>%
group_by(Player) %>%
mutate(total_puntos = sum(puntos)) %>%
arrange(desc(total_puntos)) %>%
distinct(Player, total_puntos) %>%
filter(total_puntos > 32000) %>%
rename('Nombre' = 'Player', 'Puntos' = 'total_puntos')
lidert_puntos2$Nombre <- gsub("[*]","",lidert_puntos2$Nombre)
knitr::kable(lidert_puntos2, caption = "Máximos Anotadores") %>%
kableExtra::kable_styling(bootstrap_options = c("striped", "hover")) %>%
kableExtra::kable_styling(fixed_thead = list(enabled = T, background = "orange"))
Máximos Anotadores
Nombre
|
Puntos
|
Kareem Abdul-Jabbar
|
38387
|
Karl Malone
|
36928
|
Wilt Chamberlain
|
33953
|
Kobe Bryant
|
33643
|
Michael Jordan
|
32292
|
Datos de 2017, a fecha de 07/01/2022, Lebron James es el 3er máximo anotador con 36.107 puntos
lidert_asist <- seasons_stats_jug %>%
select(Player, AST) %>%
group_by(Player) %>%
mutate(total_asist = sum(AST)) %>%
arrange(desc(total_asist)) %>%
distinct(Player, total_asist) %>%
filter(total_asist > 10000) %>%
rename('Nombre' = 'Player', 'Asistencias' = 'total_asist')
lidert_asist$Nombre <- gsub("[*]","",lidert_asist$Nombre)
knitr::kable(lidert_asist, caption = "Máximos Asistentes") %>%
kableExtra::kable_styling(bootstrap_options = c("striped", "hover")) %>%
kableExtra::kable_styling(fixed_thead = list(enabled = T, background = "orange"))
Máximos Asistentes
Nombre
|
Asistencias
|
John Stockton
|
15806
|
Jason Kidd
|
13393
|
Mark Jackson
|
11930
|
Steve Nash
|
10335
|
Magic Johnson
|
10141
|
lidert_rebotes <- seasons_stats_jug %>%
select(Player, TRB) %>%
group_by(Player) %>%
mutate(total_rebotes = sum(TRB)) %>%
arrange(desc(total_rebotes)) %>%
distinct(Player, total_rebotes) %>%
filter(total_rebotes > 17000) %>%
rename('Nombre' = 'Player', 'Rebotes' = 'total_rebotes')
lidert_rebotes$Nombre <- gsub("[*]","",lidert_rebotes$Nombre)
knitr::kable(lidert_rebotes, caption = "Máximos Reboteadores") %>%
kableExtra::kable_styling(bootstrap_options = c("striped", "hover")) %>%
kableExtra::kable_styling(fixed_thead = list(enabled = T, background = "orange"))
Máximos Reboteadores
Nombre
|
Rebotes
|
Wilt Chamberlain
|
25597
|
Bill Russell
|
21620
|
Kareem Abdul-Jabbar
|
17440
|
Walt Bellamy
|
17303
|
Moses Malone
|
17284
|
lidert_robos <- seasons_stats_jug %>%
select(Player, STL) %>%
group_by(Player) %>%
mutate(total_robos = sum(STL)) %>%
arrange(desc(total_robos)) %>%
distinct(Player, total_robos) %>%
filter(total_robos > 2400) %>%
rename('Nombre' = 'Player', 'Robos' = 'total_robos')
lidert_robos$Nombre <- gsub("[*]","",lidert_robos$Nombre)
knitr::kable(lidert_robos, caption = "Máximos Recuperadores") %>%
kableExtra::kable_styling(bootstrap_options = c("striped", "hover")) %>%
kableExtra::kable_styling(fixed_thead = list(enabled = T, background = "orange"))
Máximos Recuperadores
Nombre
|
Robos
|
John Stockton
|
3265
|
Jason Kidd
|
2944
|
Gary Payton
|
2578
|
Michael Jordan
|
2514
|
Maurice Cheeks
|
2434
|
lidert_tapones <- seasons_stats_jug %>%
select(Player, BLK) %>%
group_by(Player) %>%
mutate(total_tapones = sum(BLK)) %>%
arrange(desc(total_tapones)) %>%
distinct(Player, total_tapones) %>%
filter(total_tapones > 2900) %>%
rename('Nombre' = 'Player', 'Tapones' = 'total_tapones')
lidert_tapones$Nombre <- gsub("[*]","",lidert_tapones$Nombre)
knitr::kable(lidert_tapones, caption = "Máximos Taponadores", caption_colour = 'red') %>%
kableExtra::kable_styling(bootstrap_options = c("striped", "hover")) %>%
kableExtra::kable_styling(fixed_thead = list(enabled = T, background = "orange"))
Máximos Taponadores
Nombre
|
Tapones
|
Hakeem Olajuwon
|
3830
|
Dikembe Mutombo
|
3492
|
Mark Eaton
|
3064
|
Tim Duncan
|
3020
|
David Robinson
|
2954
|
4.1 Hacia el triple
Dentro del apartado estadístico, me interesa analizar la incidencia de los triples en la NBA actual.
Antes que nada, es preferible introducir la figura del tiro de 3 puntos. Se trata de una línea situada a 6,70 metros de distancia al aro desde las bandas, y a 7,25 metros desde la parte frontal. Estas medidas no corresponden con el baloncesto europeo (reglas FIBA) ni el baloncesto universitario, con líneas más próximas en ambos.
Esta implementación no se encontraba en las reglas del juego originales, y en la NBA no se implantó hasta la temporada 1979-1980. Se creó como una forma de contrarrestar la absoluta dominancia de los hombres más altos, los cuales dominaban la pintura provocando un sobreuso de los tiros en distancias cercanas.
Con el triple en la NBA, se produjo una mayor redistribución en la distancia de los tiros realizados, pero recientemente, especialmente desde la dinastía de los Golden State Warriors, la incidencia del triple en los partidos ha experimentado un ascenso meteórico. Mientras que antes se consideraba como un arma complementaria, con especialistas dedicados específicamente a lanzar desde la línea de 3, estos últimos años, el triple ha sido considerado como la principal herramienta de ataque para muchas franquicias.
Esto puede verse tanto en la distancia a la que están dispuestos a lanzar los tiradores hoy en día, como en los porcentajes de acierto.
Aquí podemos apreciar como la distancia media de los lanzamientos realizados ha aumentado considerablemente desde la temporada 1997-1998 hasta la actualidad, demostrándose como la cultura del triple ha sido cada vez más relevante.
player_shooting <- rio::import("./datos/nba_stats/player_shooting.csv")
dist_media <- player_shooting %>% group_by(season) %>%
mutate(media_dist = mean(avg_dist_fga, na.rm = TRUE)) %>%
distinct(season,media_dist) %>%
mutate(metros = media_dist/3.281)
curry <- readJPEG("./imagenes/curry.jpg")
curry <- rasterGrob(curry, width = unit(1, "npc"), height = unit(1, "npc"), interpolate = TRUE)
ggdist <- ggplot(dist_media, aes(x = season, y = metros)) +
annotation_custom(curry, xmin = -Inf, xmax = Inf, ymin = 1.7, ymax = 4.25) +
geom_ribbon(aes(xmin = 1995, xmax=2025, ymin = metros, ymax = Inf), fill = "beige") +
geom_ribbon(aes(xmin=-Inf, xmax= 1997), fill = "beige")+
#geom_ribbon(aes(xmin=-Inf, xmax= 1997), fill = "white")+
geom_line(size=1, colour="red") + geom_point(colour="red") +
scale_x_continuous(
breaks = seq(1997, 2022, 2),
limits = c(1997, 2022))+
scale_y_continuous(
breaks = seq(3, 4.5, 0.25),
limits = c(3, 4.5))+
labs(
title = "Distancia Media de Lanzamientos",
subtitle = "1997-2022",
x="Año",
y="Metros",
caption="Stephen Curry, realizando su triple nº 3000") +
theme_minimal() +
theme(plot.title = element_text(face="bold", hjust=0.5, size=rel(1.5)),
plot.subtitle = element_text(face="italic", hjust=0.5)) + theme(panel.grid.major = element_line(linetype = "blank"),
panel.grid.minor = element_line(linetype = "blank"),
panel.background = element_rect(fill = "beige"),
plot.background = element_rect(fill = "beige"))
ggdist
La evolución en cuanto a porcentajes, no hace más que confirmar la idea planteada anteriormente, cada vez se tiran más triples, y con mayor acierto.
seasons_stats_jug <- rio::import("./datos/nba_players_2/Seasons_Stats.csv")
perc_triple <- seasons_stats_jug %>% dplyr::rename( "three_perc" = "3P%") %>%
select(Year, Player, three_perc) %>%
group_by(Year) %>%
mutate(perc3_total = mean(three_perc, na.rm = TRUE)) %>%
distinct(Year, perc3_total)
perc_triple_pivot <- seasons_stats_jug %>% filter(Pos %in% c('C', 'PF', 'C-PF','PF-C')) %>%
dplyr::rename( "three_perc" = "3P%") %>%
select(Year, Player, three_perc) %>%
group_by(Year) %>%
mutate(perc3_total_pivot = mean(three_perc, na.rm = TRUE)) %>%
distinct(Year, perc3_total_pivot)
perc_3_final <- left_join(perc_triple, perc_triple_pivot, c('Year' = 'Year')) %>% filter(Year >= 1980) %>% round(digits = 2) %>%
mutate(porc_triple = perc3_total*100) %>%
mutate(porc_triple_pivot = perc3_total_pivot*100)
perc_3_final[, c(2)] <- sapply(perc_3_final[, c(2)], as.numeric)
perc_3_final[, c(3)] <- sapply(perc_3_final[, c(3)], as.numeric)
gg3total <- ggplot(perc_3_final, aes(x = Year, y = porc_triple)) + geom_line(colour = 'gray50', size = 1.2) +
theme(plot.title = element_text(size = 10,
hjust = 0.5), panel.background = element_rect(fill = "beige"),
plot.background = element_rect(fill = "beige")) +labs(title = "Evolución del % de acierto en triples",
x = "Año", y = "% acierto") + theme(panel.grid.major = element_line(linetype = "blank"),
panel.grid.minor = element_line(linetype = "blank"))
gg3pivot <- ggplot(perc_3_final, aes(x = Year, y = porc_triple_pivot)) + geom_line(colour = 'darkblue', size = 1.2) +
theme(plot.title = element_text(size = 10, hjust = 0.5), panel.background = element_rect(fill = "beige"),
plot.background = element_rect(fill = "beige")) +
labs(title = "Evolución del % de acierto en triples en PIVOTS", x = "Año", y = "% acierto") + theme(panel.grid.major = element_line(linetype = "blank"),
panel.grid.minor = element_line(linetype = "blank"))
ggarrange(gg3total, gg3pivot,
ncol = 2, nrow = 1)
Especialmente destacado el aumento del porcentaje en los pívots, los hombres más altos. En épocas anteriores, estas posiciones estaban dedicadas a proteger el aro en busca de rebotes y puntos fáciles cercanos a canasta, pero el 5 tradicional se está extinguiendo poco a poco. Cada vez es más raro que un jugador interior no se abra para lanzar de 3.
Este cambio de paradigma ha supuesto una gran polarización en cuanto al uso de las posesiones de cada conjunto. Actualmente, la gran mayoría de estas terminan con un lanzamiento de 3, o con un lanzamiento dentro de la zona (muy cercano al aro), dejando casi obsoleto el lanzamiento de media distancia, provocando que aquellos jugadores que no dominaban la faceta del triple, hayan tenido que implementarla en su juego, y por otra parte, aquellos que solo actuaban como triplistas, se hayan expandido a otros cometidos.
5. Palmarés
Por suerte o por desgracia, la máxima y única aspiración que poseen los equipos de la NBA es conseguir alzarse con el título de campeón al final de cada temporada.
mas_titulos <- campeones %>% group_by(name) %>% mutate(n_titulos = sum(NN = n())) %>%
distinct(name, n_titulos) %>%
arrange(desc(n_titulos))
id <- rownames(mas_titulos)
mas_titulos <- cbind(id=id, mas_titulos)
mas_titulos[, c(1)] <- sapply(mas_titulos[, c(1)], as.numeric)
label_titulos <- mas_titulos
number_of_bar <- nrow(label_titulos)
angle <- 90 - 360 * (label_titulos$id-0.5) /number_of_bar
label_titulos$hjust <- ifelse( angle < -90, 1, 0)
label_titulos$angle <- ifelse(angle < -90, angle+180, angle)
base_titulos <- mas_titulos %>%
group_by(name) %>%
summarise(start=min(id), end=max(id)) %>%
rowwise() %>%
mutate(title=mean(c(start, end)))
grid_titulos <- base_titulos
grid_titulos$end <- grid_titulos$end[ c( nrow(grid_titulos), 1:nrow(grid_titulos)-1)] + 1
grid_titulos$start <- grid_titulos$start - 1
grid_titulos <- grid_titulos[-1,]
gg_titulos <- ggplot(mas_titulos, aes(x=as.factor(year), y=n_titulos, fill=n_titulos, color = n_titulos)) + geom_bar(aes(x=as.factor(id), y=n_titulos, fill=n_titulos), stat="identity", alpha=0.5) +
geom_segment(data=grid_titulos, aes(x = 0.5, y = 17, xend = 20.9, yend = 17), colour = "grey", alpha=1, size=0.3 , inherit.aes = FALSE ) +
geom_segment(data=grid_titulos, aes(x = 0.5, y = 10, xend = 20.9, yend = 10), colour = "grey", alpha=1, size=0.3 , inherit.aes = FALSE ) +
geom_segment(data=grid_titulos, aes(x = 0.5, y = 5, xend = 20.9, yend = 5), colour = "grey", alpha=1, size=0.3 , inherit.aes = FALSE ) +
geom_segment(data=grid_titulos, aes(x = 0.5, y = 2, xend = 20.9, yend = 2), colour = "grey", alpha=1, size=0.3 , inherit.aes = FALSE ) +
annotate("text", x = 0.3, y = c(2, 5, 10, 17), label = c("2", "5", "10", "17") , color="grey", size=6 , angle=0, fontface="bold", hjust=1) +
geom_bar(aes(x=as.factor(id), y=n_titulos, fill=n_titulos), stat="identity", alpha=0.5) +
ylim(-10,21) +
theme_minimal() +
theme(
legend.position = "none",
axis.text = element_blank(),
axis.title = element_blank(),
panel.grid = element_blank(),
plot.margin = unit(rep(-1,4), "cm") ) +
coord_polar() +
geom_text(data=label_titulos, aes(x=id, y=n_titulos+1, label=name, hjust=hjust), color="black", fontface="bold",alpha=0.6, size=5, angle= label_titulos$angle, inherit.aes = FALSE ) +
theme(legend.text = element_text(colour = "black"),
legend.title = element_text( colour = "black"),
legend.background = element_rect(fill = "beige", colour = "beige"),
legend.key = element_rect(fill = "beige"),
legend.position = "right",
panel.background = element_rect(fill = "beige" , colour = "beige"),
plot.background = element_rect(fill = "beige" , colour = "beige"))+labs(colour = "Nº de campeonatos", fill = "Nº de campeonatos") + theme(legend.text = element_text(size = 12),
legend.title = element_text(size = 15))
#gg_titulos
#las siguientes lineas de codigo se utilizan para eliminar los bordes blancos
ggsave("./plots/gg_titulos.png", width = 18, height = 15)
Como claros dominadores, aparecen los Boston Celtics (Este) y Los Angeles Lakers (Oeste), con 17 campeonatos cada uno.
El hecho de que un total de 11 franquicias aún no hayan logrado ningún campeonato de la NBA, a pesar de las medidas de redistribución existentes como los topes salariales y la lotería del draft antes mencionada, pone de manifiesto que para alzarse con uno de los trofeos más importantes del deporte, se necesita mucho más que eso. La calidad y química del equipo, motivación, potencial financiero de la ciudad, buena planificación y un poco de suerte con las lesiones, completan el set de cualidades requeridas para alzarse con tan preciado título.
LS0tDQp0aXRsZTogIk5CQSBhIGJhc2UgZGUgZGF0b3MiDQpzdWJ0aXRsZTogIkNheWV0YW5vIEZlcm5hbmRvIFJvbWVybyBNb250ZWFndWRvKGNhcm9tb24zQGFsdW1uaS51di5lcykiDQphdXRob3I6ICJVbml2ZXJzaXRhdCBkZSBWYWzDqG5jaWEiDQpkYXRlOiAiRGljaWVtYnJlIGRlIDIwMjEgKGFjdHVhbGl6YWRvIGVsIGByIGZvcm1hdChTeXMudGltZSgpLCAnJWQtJW0tJVknKWApIg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIGNzczogIi4vYXNzZXRzL215X2Nzc19maWxlLmNzcyINCiAgICB0aGVtZTogcGFwZXINCiAgICBoaWdobGlnaHQ6IHRleHRtYXRlIA0KICAgIHRvYzogdHJ1ZQ0KICAgIHRvY19kZXB0aDogMyANCiAgICB0b2NfZmxvYXQ6IA0KICAgICAgY29sbGFwc2VkOiB0cnVlDQogICAgICBzbW9vdGhfc2Nyb2xsOiB0cnVlDQogICAgc2VsZl9jb250YWluZWQ6IHRydWUNCiAgICBudW1iZXJfc2VjdGlvbnM6IGZhbHNlDQogICAgZGZfcHJpbnQ6IGthYmxlDQogICAgY29kZV9mb2xkaW5nOiBoaWRlDQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQ0KZWRpdG9yX29wdGlvbnM6IA0KICBjaHVua19vdXRwdXRfdHlwZTogY29uc29sZQ0KLS0tDQoNCmBgYHtjc3MsIGVjaG89RkFMU0V9IA0KDQpzcGFuew0KICBmb250LWZhbWlseTogaGVsdmV0aWNhOw0KfQ0KDQphew0KICBmb250LWZhbWlseTogaGVsdmV0aWNhOw0KfQ0KDQoubmF2LXBpbGxzPmxpLmFjdGl2ZT5hOmZvY3VzIHsNCiAgICBjb2xvcjogI2ZmZmZmZjsNCn0NCg0KLmNvbnRhaW5lci1mbHVpZCwgLmNvbnRhaW5lci1mbHVpZCBoMSB7DQogICAgZm9udC1mYW1pbHk6IGhlbHZldGljYTsNCiAgICBsaW5lLWhlaWdodDogMS43Ow0KfQ0KDQouY29udGFpbmVyLWZsdWlkIHAgew0KICAgIGZvbnQtZmFtaWx5OiBoZWx2ZXRpY2E7DQp9DQoNCmgxLGgyLGgzLGg0LGg1LGg2LHAsIHRhYmxlIHsNCiAgZm9udC1mYW1pbHk6IGhlbHZldGljYTsNCn0NCmBgYA0KDQpgYGB7ciBwYWNrYWdlcy1zZXR1cCwgaW5jbHVkZSA9IEZBTFNFfQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KGtsaXBweSkgICMtIHJlbW90ZXM6Omluc3RhbGxfZ2l0aHViKCJybGVzdXIva2xpcHB5IikNCmxpYnJhcnkoa25pdHIpDQpsaWJyYXJ5KHJpbykNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoZ2dhbmltYXRlKQ0KbGlicmFyeShnZ1RoZW1lQXNzaXN0KQ0KbGlicmFyeShyZW1vdGVzKSANCmxpYnJhcnkoZ3QpDQpsaWJyYXJ5KHBsb3RseSkNCmxpYnJhcnkocmVhZHhsKQ0KbGlicmFyeSh0cmVlbWFwKSAjaW5zdGFsbC5wYWNrYWdlcyh0cmVlbWFwKQ0KbGlicmFyeShkM3RyZWVSKSAjcmVtb3Rlczo6aW5zdGFsbF9naXRodWIoImQzdHJlZVIvZDN0cmVlUiIpDQpsaWJyYXJ5KG1hZ2ljaykNCmxpYnJhcnkoc3RyaW5ncikNCmxpYnJhcnkodG1hcCkNCmxpYnJhcnkoZmxleHRhYmxlKQ0KbGlicmFyeShvZmZpY2VyKQ0KbGlicmFyeShwbmcpDQpsaWJyYXJ5KGdyaWQpDQpsaWJyYXJ5KGpwZWcpDQpsaWJyYXJ5KGdncHVicikgI2luc3RhbGwucGFja2FnZXMoJ2dncHVicicpDQoNCmBgYA0KDQpgYGB7ciBjaHVuay1zZXR1cCwgaW5jbHVkZSA9IEZBTFNFfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCBldmFsID0gVFJVRSwgbWVzc2FnZSA9IEZBTFNFLCB3YXJuaW5nID0gRkFMU0UsIA0KICAgICAgICAgICAgICAgICAgICAgICNyZXN1bHRzID0gImhvbGQiLA0KICAgICAgICAgICAgICAgICAgICAgIGNhY2hlID0gRkFMU0UsIGNhY2hlLnBhdGggPSAiL2NhY2hlcy8iLCBjb21tZW50ID0gIiM+IiwNCiAgICAgICAgICAgICAgICAgICAgICAjZmlnLndpZHRoID0gNywgI2ZpZy5oZWlnaHQ9IDcsICAgDQogICAgICAgICAgICAgICAgICAgICAgI291dC53aWR0aCA9IDcsIG91dC5oZWlnaHQgPSA3LA0KICAgICAgICAgICAgICAgICAgICAgIGNvbGxhcHNlID0gVFJVRSwgIGZpZy5zaG93ID0gImhvbGQiLA0KICAgICAgICAgICAgICAgICAgICAgIGZpZy5hc3AgPSAwLjYyOCwgb3V0LndpZHRoID0gIjc1JSIsIGZpZy5hbGlnbiA9ICJjZW50ZXIiKQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGRldiA9ICJwbmciLCBkZXYuYXJncyA9IGxpc3QodHlwZSA9ICJjYWlyby1wbmciKSkNCmBgYA0KDQoNCmBgYHtyIG9wdGlvbnMtc2V0dXAsIGluY2x1ZGUgPSBGQUxTRX0NCm9wdGlvbnMoc2NpcGVuID0gOTk5KSAjLSBwYXJhIHF1aXRhciBsYSBub3RhY2nDs24gY2llbnTDrWZpY2ENCm9wdGlvbnMoInlhbWwuZXZhbC5leHByIiA9IFRSVUUpIA0KYGBgDQoNCg0KYGBge3Iga2xpcHB5LCBlY2hvID0gRkFMU0V9DQprbGlwcHk6OmtsaXBweShwb3NpdGlvbiA9IGMoInRvcCIsICJyaWdodCIpKSAjLSByZW1vdGVzOjppbnN0YWxsX2dpdGh1Yigicmxlc3VyL2tsaXBweSIpDQpgYGANCg0KYGBge3IsIGVjaG89VFJVRX0NCmNvbnRyYXRvcyA8LSByaW86OmltcG9ydCgiLi9kYXRvcy9jb250cmF0b3MvbmJhX2NvbnRyYWN0c19oaXN0b3J5LmNzdiIpDQoNCmp1Z19hY3QyMDIxIDwtIGltcG9ydCgiLi9kYXRvcy9uYmFfMjEyMi9hY3RpdmVfcGxheWVyc18yLmNzdiIpDQpqdWdhZG9yZXMyMDIxIDwtIGltcG9ydCgiLi9kYXRvcy9uYmFfMjEyMi9wbGF5ZXJzLmNzdiIpDQoNCnBhcnRpZG9zX2RldGFsbGUgPC0gcmlvOjppbXBvcnQoIi4vZGF0b3MvbmJhX2dhbWVzL2dhbWVzX2RldGFpbHMuY3N2IikNCnBhcnRpZG9zIDwtIHJpbzo6aW1wb3J0KCIuL2RhdG9zL25iYV9nYW1lcy9nYW1lcy5jc3YiKQ0KanVnYWRfcGFydCA8LSByaW86OmltcG9ydCgiLi9kYXRvcy9uYmFfZ2FtZXMvcGxheWVycy5jc3YiKQ0KcmFua2luZ19wYXJ0IDwtIHJpbzo6aW1wb3J0KCIuL2RhdG9zL25iYV9nYW1lcy9yYW5raW5nLmNzdiIpDQplcXVpcG9zX3BhcnQgPC0gcmlvOjppbXBvcnQoIi4vZGF0b3MvbmJhX2dhbWVzL3RlYW1zLmNzdiIpDQoNCmFsbF9qdWcgPC0gcmlvOjppbXBvcnQoIi4vZGF0b3MvbmJhX3BsYXllcnMvYWxsX3NlYXNvbnMuY3N2IikNCg0KanVnX2luZm8gPC0gcmlvOjppbXBvcnQoIi4vZGF0b3MvbmJhX3BsYXllcnNfMi9wbGF5ZXJfZGF0YS5jc3YiKQ0KanVnX2NvbGxlZ2UgPC0gcmlvOjppbXBvcnQoIi4vZGF0b3MvbmJhX3BsYXllcnNfMi9QbGF5ZXJzLmNzdiIpDQpzZWFzb25zX3N0YXRzX2p1ZyA8LSByaW86OmltcG9ydCgiLi9kYXRvcy9uYmFfcGxheWVyc18yL1NlYXNvbnNfU3RhdHMuY3N2IikNCg0KYXdhcmRzIDwtIHJpbzo6aW1wb3J0KCIuL2RhdG9zL25iYV9zdGF0cy9wbGF5ZXJfYXdhcmRzLmNzdiIpDQphbGxfbmJhIDwtIHJpbzo6aW1wb3J0KCIuL2RhdG9zL25iYV9zdGF0cy9lbmRfc2Vhc29uX3RlYW1zLmNzdiIpDQp0ZWFtX3RvdGFscyA8LSByaW86OmltcG9ydCgiLi9kYXRvcy9uYmFfc3RhdHMvdGVhbV90b3RhbHMuY3N2IikNCnRlYW1fcGVyX2dhbWUgPC0gcmlvOjppbXBvcnQoIi4vZGF0b3MvbmJhX3N0YXRzL3RlYW1fcGVyX2dhbWUuY3N2IikNCmFkdmFuY2VkX3N0YXRzIDwtIHJpbzo6aW1wb3J0KCIuL2RhdG9zL25iYV9zdGF0cy9hZHZhbmNlZC5jc3YiKQ0KDQpwbGF5ZXJfc2hvb3RpbmcgPC0gcmlvOjppbXBvcnQoIi4vZGF0b3MvbmJhX3N0YXRzL3BsYXllcl9zaG9vdGluZy5jc3YiKQ0KDQpjYW1wZW9uZXMgPC0gcmlvOjppbXBvcnQoIi4vZGF0b3MvZnJhbnF1aWNpYXMueGxzeCIpDQpgYGANCg0KDQo8aHIgY2xhc3M9ImxpbmVhLWJsYWNrIj4NCg0KPCEtLSBFbCBww6FycmFmbyBkZSBhYmFqbyBoYXMgZGUgZGVqYXJsbyBjYXNpIGlndWFsLCBzb2xvIEhBUyBkZSBTVVNUSVRVSVIgInBlcmV6cDQ0IiBwb3IgdHUgdXN1YXJpbyBkZSBHaXRodWItLT4NClRyYWJham8gZWxhYm9yYWRvIHBhcmEgbGEgYXNpZ25hdHVyYSAiUHJvZ3JhbWFjacOzbiB5IG1hbmVqbyBkZSBkYXRvcyBlbiBsYSBlcmEgZGVsIEJpZyBEYXRhIiBkZSBsYSBVbml2ZXJzaXRhdCBkZSBWYWzDqG5jaWEgZHVyYW50ZSBlbCBjdXJzbyAyMDIxLTIwMjIuIEVsIHJlcG8gZGVsIHRyYWJham8gZXN0w6EgW2FxdcOtXShodHRwczovL2dpdGh1Yi5jb20vY2F5ZXRhbm8xMDgvdHJhYmFqb19CaWdEYXRhKXt0YXJnZXQ9Il9ibGFuayJ9LiANCg0KPCEtLSBFbCBww6FycmFmbyBkZSBhYmFqbyBoYXMgZGUgZGVqYXJsbyBleGFjdGFtZW50ZSBpZ3VhbCwgTk8gSEFTIERFIENBTUJJQVIgTkFEQS0tPg0KDQpMYSBww6FnaW5hIHdlYiBkZSBsYSBhc2lnbmF0dXJhIHkgbG9zIHRyYWJham9zIGRlIG1pcyBjb21wYcOxZXJvcyBwdWVkZW4gdmVyc2UgW2FxdcOtXShodHRwczovL3BlcmV6cDQ0LmdpdGh1Yi5pby9pbnRyby1kcy0yMS0yMi13ZWIvMDctdHJhYmFqb3MuaHRtbCl7dGFyZ2V0PSJfYmxhbmsifS4NCg0KDQo8aHIgY2xhc3M9ImxpbmVhLXJlZCI+DQoNCg0KPCEtLSBhcXXDrSBlbXBpZXphIGVsIHRyYWJham8gLS0+DQoNCg0KIyAxLiBJbnRyb2R1Y2Npw7NuDQoNCkxhIE5CQSBlcyB1bmEgZGUgbGFzIGNvbXBldGljaW9uZXMgbcOhcyBpbXBvcnRhbnRlcyB5IHNlZ3VpZGFzIGRlbCBtdW5kbywgYWRlbcOhcyBkZSBzZXIgbGEgY29tcGV0aWNpw7NuIG3DoXMgaW1wb3J0YW50ZSB5IGRlIG3DoXMgbml2ZWwgYmFsb25jZXN0w61zdGljby4gU2UgdHJhdGEgZGUgdW5hIGxpZ2EgY2VycmFkYSwgZGUgMzAgZXF1aXBvcywgc2luIGFzY2Vuc29zIG5pIGRlc2NlbnNvcywgYWwgY29udHJhcmlvIGRlIGxvIHF1ZSBlc3RhbW9zIGFjb3N0dW1icmFkb3MgZW4gbGFzIGNvbXBldGljaW9uZXMgZGVwb3J0aXZhcyBlbiBFc3Bhw7FhLg0KDQo8YnI+PGJyPg0KDQo8Y2VudGVyPg0KIVtdKC4vaW1hZ2VuZXMvbmJhd2FsbC5qcGcpe3dpZHRoPTU0MCBoZWlnaHQ9MzAwfQ0KPC9jZW50ZXI+DQoNCiMgMi4gRGF0b3MNCg0KTG9zIGRhdG9zIHV0aWxpemFkb3MgZW4gZWwgdHJhYmFqbywgaGFuIHNpZG8gb2J0ZW5pZG9zIGRlIGxhIHDDoWdpbmEgd2ViIFtrYWdnbGVdKGh0dHBzOi8vd3d3LmthZ2dsZS5jb20vKSwgd2ViIGNvbiBtw7psdGlwbGVzIGhlcnJhbWllbnRhcyDDunRpbGVzIHBhcmEgZWwgbWFuZWpvIHkgYW7DoWxpc2lzIGRlIGRhdG9zLCBjb21vIHB1ZWRlbiBzZXIgY29uanVudG9zIGRlIGRhdG9zLCBzY3JpcHRzLCBjb21wZXRpY2lvbmVzLCBldGMuIE3DoXMgY29uY3JldGFtZW50ZSwgbG9zIGNvbmp1bnRvcyBkZSBkYXRvcyB1dGlsaXphZG9zIHNvbjogW05CQSBQbGF5ZXJzXShodHRwczovL3d3dy5rYWdnbGUuY29tL2p1c3RpbmFzL25iYS1wbGF5ZXJzLWRhdGEpLCBbTkJBIGdhbWVzIGRhdGFdKGh0dHBzOi8vd3d3LmthZ2dsZS5jb20vbmF0aGFubGF1Z2EvbmJhLWdhbWVzKSwgW05CQSBQbGF5ZXJzIHN0YXRzIHNpbmNlIDE5NTBdKGh0dHBzOi8vd3d3LmthZ2dsZS5jb20vZHJnaWxlcm1vL25iYS1wbGF5ZXJzLXN0YXRzKSB5IFtOQkEgUGxheWVyIFNhbGFyeSBEYXRhc2V0ICgyMDE3IC0gMjAxOCldKGh0dHBzOi8vd3d3LmthZ2dsZS5jb20va29raTI1YW5kby9zYWxhcnkpDQoNCiMgMy4gRnVuY2lvbmFtaWVudG8NCg0KIyMgMy4xIFRlbXBvcmFkYQ0KDQpMYSB0ZW1wb3JhZGEgTkJBIHN1ZWxlIGNvbWVuemFyIGEgbWVkaWFkb3MgZGUgb2N0dWJyZSwgY3VhbmRvIGNvbWllbnphIGxhIHRlbXBvcmFkYSByZWd1bGFyIChyZWd1bGFyIHNlYXNvbiksIGVuIGxhIHF1ZSBjYWRhIGVxdWlwbyBqdWdhcsOhIDgyIHBhcnRpZG9zLiBMb3MgY2FsZW5kYXJpb3MgeSBudW1lcm8gZGUgZW5mcmVudGFtaWVudG9zIGVudHJlIGNhZGEgZXF1aXBvIGxvIGRpY3RhbWluYSBsYSBjb25mZXJlbmNpYSB5IGxhIGRpdmlzacOzbiBlbiBsYSBxdWUgc2UgZW5jdWVudHJlIGNhZGEgZXF1aXBvLiBFeGlzdGVuIDIgY29uZmVyZW5jaWFzLCBFc3RlIHkgT2VzdGUsIHkgY2FkYSB1bmEgZGUgZWxsYXMgYXBvcnRhcsOhIHN1cyA4IGVxdWlwb3MgbWVqb3IgY2xhc2lmaWNhZG9zIGEgbGEgcG9zdC10ZW1wb3JhZGEgKHBsYXlvZmZzKS4NCg0KWypEZWJpZG8gYWwgQ09WSUQtMTksIGNhZGEgY29uZmVyZW5jaWEgYXBvcnRhcsOhIDYgZXF1aXBvcyBmaWpvcywgbWFzIDIgYWRpY2lvbmFsZXMgcXVlIHJlc3VsdGFyw6FuIGRlIHVuIHBsYXktaW4ganVnYWRvIHBvciBsb3MgcHVlc3RvcyA3wrosIDjCuiwgOcK6IHkgMTDCuiBkZSBjYWRhIGNvbmZlcmVuY2lhLipdey5zbWFsbH0NCg0KRmluYWxtZW50ZSwgbG9zIHBsYXlvZmZzLCBlbmZyZW50YW1pZW50b3MgYWwgbWVqb3IgZGUgNyBwYXJ0aWRvcywgZW4gbG9zIHF1ZSBlbCBnYW5hZG9yIGF2YW56YSBkZSByb25kYSB5IGVsIHBlcmRlZG9yIHF1ZWRhIGVsaW1pbmFkby4NCkxvcyBjYW1wZW9uZXMgZGUgY2FkYSBjb25mZXJlbmNpYSAoZXF1aXBvcyBnYW5hZG9yZXMgZGVsIGN1YWRybyksIHNlIGRpc3B1dGFyw6FuIGxhIEZpbmFsIGRlIGxhIE5CQS4NCg0KPGJyPg0KDQo8Y2VudGVyPg0KIVtGcmFucXVpY2lhcyBzaXR1YWRhcyBlbiBlbCBtYXBhXSguL2ltYWdlbmVzL25iYW1hcDIucG5nKXt3aWR0aD01NDAgaGVpZ2h0PTQwMH0NCjwvY2VudGVyPg0KDQojIyAzLjIgRHJhZnQNCg0KRWwgZHJhZnQgZGUgbGEgTkJBIGVzIGVsIHByb2Nlc28gcG9yIGVsIGN1w6FsIGxvcyBqw7N2ZW5lcyB1bml2ZXJzaXRhcmlvcyB5IGV1cm9wZW9zIGFjY2VkZW4gYSBsYSBsaWdhLiBBIGRpZmVyZW5jaWEgZGUgY29tbyBwdWVkZSBwYXNhciBlbiBFdXJvcGEgY29uIG90cm9zIGRlcG9ydGVzIGNvbW8gZWwgZsO6dGJvbCwgZG9uZGUgbG9zIGVxdWlwb3MgbcOhcyByaWNvcyBwdWVkZW4gbGxldmFyc2UgYSBqdWdhZG9yZXMgcHJvbWV0ZWRvcmVzIGRlc2RlIG11eSBwZXF1ZcOxb3MgYSBnb2xwZSBkZSB0YWxvbmFyaW8sIGVuIGxhIE5CQSBzZSByZWFsaXphIHVuIHNvcnRlbyBzaW1pbGFyIGEgbGEgbG90ZXLDrWEsIGRvbmRlIGxvcyBlcXVpcG9zIHNvbiBhc2lnbmFkb3MgY29uIGRpdmVyc2FzIHJvbmRhcyBkZWwgZHJhZnQgKGVsZWNjaW9uZXMpLCBjb24gbGFzIHF1ZSBwdWVkZW4gZWxlZ2lyIGEgZXN0b3MgdGFsZW50b3MuIFPDs2xvIGp1Z2Fkb3JlcyBtZW5vcmVzIGRlIDIyIGHDsW9zIHB1ZWRlbiBkZWNsYXJhcnNlIGVsZWdpYmxlcywgeSBwYXJhIGVsbG9zIGVzIGxhIMO6bmljYSB2w61hIGRlIGluZ3Jlc2FyIGEgbGEgTkJBIGhhc3RhIGFsY2FuemFyIGRpY2hhIGVkYWQsIGN1YW5kbyB5YSBwb2Ryw6FuIGZpcm1hciBjb21vIGFnZW50ZXMgbGlicmVzLg0KDQpFc3RlIHByb2Nlc28gc3Vwb25lIGxhIG1heW9yIGJhemEgZW4gZmF2b3IgZGUgbGEgY29tcGV0aXRpdmlkYWQgZW50cmUgdG9kYXMgbGFzIGZyYW5xdWljaWFzIGludGVncmFudGVzLCB5YSBxdWUgbG9zIGVxdWlwb3MgY29uIHBlb3JlcyByZXN1bHRhZG9zIGVuIGxhIHRlbXBvcmFkYSBhbnRlcmlvciwgdGllbmVuIG1heW9yIHByb2JhYmlsaWRhZCBkZSBvYnRlbmVyIHJvbmRhcyBhbHRhcyBkZWwgZHJhZnQsIGNvbnNpZGVyw6FuZG9zZSBlc3RhcyBjb21vIGxhcyBwcmltZXJhcyBlbGVjY2lvbmVzLiBUYW50byBlcyBhc8OtLCBxdWUgZW4gbXVjaGFzIG9jYXNpb25lcywgdW5hIGJ1ZW5hIGVsZWNjacOzbiBlbiBlbCBkcmFmdCBkZSBsYSBOQkEgcHVlZGUgcmVkaXJpZ2lyIGVsIHJ1bWJvIGRlIHVuYSBmcmFucXVpY2lhIHBlcmRlZG9yYSBoYWNpYSB1biBjYW5kaWRhdG8gYWwgdMOtdHVsbyBkdXJhbnRlIGxvcyBhw7FvcyBwcsOzeGltb3MsIGNvbW8gbG8gZnVlcm9uIGxvcyBDaGljYWdvIEJ1bGxzIGRlIE1pY2hhZWwgSm9yZGFuIChuwrogMyBlbiAxOTg0KSwgbG9zIFNhbiBBbnRvbmlvIFNwdXJzIGRlIFRpbSBEdW5jYW4gKG7CuiAxIGVuIDE5OTcpLCBvIGxvcyBHb2xkZW4gU3RhdGUgV2FycmlvcnMgZGUgU3RlcGhlbiBDdXJyeSAobsK6IDcgZW4gMjAwOSksIHRvZG9zIGVsbG9zIHN1cGVyZXN0cmVsbGFzIGVzY29naWRhcyBlbiBlbCBkcmFmdCBwb3IgZWwgZXF1aXBvIGNhbXBlw7NuLg0KDQpQYXJhIG1vc3RyYXIgbGEgaW1wb3J0YW5jaWEgZGVsIGRyYWZ0IGVuIGxhIGNvbXBldGljacOzbjoNCg0KPGNlbnRlcj4NCg0KYGBge3J9DQoNCmxpZGVydF9wYXJ0IDwtIHNlYXNvbnNfc3RhdHNfanVnICU+JSANCiAgc2VsZWN0KFBsYXllciwgRykgJT4lICANCiAgZ3JvdXBfYnkoUGxheWVyKSAlPiUgDQogIG11dGF0ZSh0b3RhbF9wYXJ0ID0gc3VtKEcpKSAlPiUgDQogIGFycmFuZ2UoZGVzYyh0b3RhbF9wYXJ0KSkgJT4lIA0KICBkaXN0aW5jdChQbGF5ZXIsIHRvdGFsX3BhcnQpDQpsaWRlcnRfcGFydCRQbGF5ZXIgPC0gZ3N1YigiWypdIiwiIixsaWRlcnRfcGFydCRQbGF5ZXIpDQoNCg0KbGlkZXJ0X3B1bnRvcyA8LSBzZWFzb25zX3N0YXRzX2p1ZyAlPiUgDQogIGRwbHlyOjpyZW5hbWUoICJ0cmlwbGVzIiA9ICIzUCIsICAiZG9zcHVudG9zIiA9ICIyUCIpICU+JSANCiAgc2VsZWN0KFllYXIsIFBsYXllciwgdHJpcGxlcywgZG9zcHVudG9zLCBGVCkNCg0KbGlkZXJ0X3B1bnRvc1tpcy5uYShsaWRlcnRfcHVudG9zKV0gPC0gMA0KDQpsaWRlcnRfcHVudG9zMiA8LSBsaWRlcnRfcHVudG9zICU+JSBtdXRhdGUocHVudG9zID0gdHJpcGxlcyozICsgZG9zcHVudG9zKjIgKyBGVCkgJT4lIA0KICBzZWxlY3QoUGxheWVyLCBwdW50b3MpICU+JSAgDQogIGdyb3VwX2J5KFBsYXllcikgJT4lIA0KICBtdXRhdGUodG90YWxfcHVudG9zID0gc3VtKHB1bnRvcykpICU+JSANCiAgYXJyYW5nZShkZXNjKHRvdGFsX3B1bnRvcykpICU+JSANCiAgZGlzdGluY3QoUGxheWVyLCB0b3RhbF9wdW50b3MpDQpsaWRlcnRfcHVudG9zMiRQbGF5ZXIgPC0gZ3N1YigiWypdIiwiIixsaWRlcnRfcHVudG9zMiRQbGF5ZXIpDQoNCnBwcCA8LSBsZWZ0X2pvaW4obGlkZXJ0X3BhcnQsIGxpZGVydF9wdW50b3MyLCBjKCdQbGF5ZXInID0gJ1BsYXllcicpKSAlPiUgbXV0YXRlKHBvaW50c3BnID0gdG90YWxfcHVudG9zL3RvdGFsX3BhcnQpICU+JSANCiAgZmlsdGVyKCBwb2ludHNwZyA8IDUwMCkgJT4lIA0KICBhcnJhbmdlKGRlc2MocG9pbnRzcGcpKQ0KDQpwcHBfZHJhZnQgPC0gbGVmdF9qb2luKHBwcCwgYWxsX2p1ZywgYygnUGxheWVyJyA9ICdwbGF5ZXJfbmFtZScpKSAgJT4lIA0KICBzZWxlY3QoUGxheWVyLCB0b3RhbF9wYXJ0LCB0b3RhbF9wdW50b3MsIHBvaW50c3BnLCBkcmFmdF9udW1iZXIpICU+JSANCiAgZGlzdGluY3QocG9pbnRzcGcsIGRyYWZ0X251bWJlcikgJT4lIG5hLm9taXQoKSAlPiUgZ3JvdXBfYnkoZHJhZnRfbnVtYmVyKSAlPiUgDQogIG11dGF0ZShtZWRpYV9kcmFmdCA9IG1lYW4ocG9pbnRzcGcpKSAlPiUgDQogIGRpc3RpbmN0KGRyYWZ0X251bWJlciwgbWVkaWFfZHJhZnQpICU+JSANCiAgYXJyYW5nZShkZXNjKG1lZGlhX2RyYWZ0KSkNCg0KI2NvcnJlbGFjacOzbiBlbGVjY2nDs24gZGVsIGRyYWZ0IGNvbiBwdW50b3MgYW5vdGFkb3MNCnBwcF9kcmFmdFssIGMoMSldIDwtIHNhcHBseShwcHBfZHJhZnRbLCBjKDEpXSwgYXMubnVtZXJpYykNCg0KcHBwX2RyYWZ0X251bSA8LSBwcHBfZHJhZnQgJT4lICBmaWx0ZXIoZHJhZnRfbnVtYmVyIDwgNjEpICU+JSBmaWx0ZXIoZHJhZnRfbnVtYmVyID4gMCkgDQoNCg0KZ2dfZHJhZnQgPC0gZ2dwbG90KHBwcF9kcmFmdF9udW0sIGFlcyh4PWRyYWZ0X251bWJlciwgeT1tZWRpYV9kcmFmdCkpICsNCiAgZ2VvbV9wb2ludCgpICsNCiAgZ2VvbV9zbW9vdGgobWV0aG9kPWxtICwgY29sb3I9InJlZCIsIGZpbGw9InllbGxvdyIsIHNlPVRSVUUpICsgDQogICBzY2FsZV94X2NvbnRpbnVvdXMoDQogICAgYnJlYWtzID0gc2VxKDAsIDYwLCA1KSwNCiAgICBsaW1pdHMgPSBjKDAsIDYwKSkrDQogICBzY2FsZV95X2NvbnRpbnVvdXMoDQogICAgYnJlYWtzID0gc2VxKDAsIDE4LCAyKSwNCiAgICBsaW1pdHMgPSBjKDAsIDE4KSkgKyB0aGVtZShheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUoY29sb3VyID0gInllbGxvdyIsDQogICAgbGluZXR5cGUgPSAic29saWQiKSwgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShsaW5ldHlwZSA9ICJibGFuayIpLA0KICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXR5cGUgPSAiYmxhbmsiKSwNCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSwNCiAgICAgICAgaGp1c3QgPSAwLjUpLCBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAiYmVpZ2UiKSwNCiAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJiZWlnZSIpKSArbGFicyh0aXRsZSA9ICJNZWRpYSBkZSBwdW50b3MgcG9yIGVsZWNjacOzbiIsDQogICAgeCA9ICJOwrogRHJhZnQiLCB5ID0gIk1lZGlhIGRlIHB1bnRvcyBwb3IgcGFydGlkbyIpDQpnZ3Bsb3RseShnZ19kcmFmdCkNCg0KYGBgDQoNCjwvY2VudGVyPg0KDQpQYXJhIGxhIHJlYWxpemFjacOzbiBkZSBlc3RlIGdyw6FmaWNvLCBzZSBoYW4gdGVuaWRvIGVuIGN1ZW50YSBsb3MgcHVlc3RvcyBlbiBsb3MgcXVlIGhhbiBzaWRvIGVsZWdpZG9zIGNhZGEgdW5vIGRlIGxvcyBqdWdhZG9yZXMgZGUgbGEgTkJBIGVuIHRvZGEgc3UgaGlzdG9yaWEsIHkgbGEgbWVkaWEgZGUgcHVudG9zIHBvciBwYXJ0aWRvIHF1ZSBwb3NlZW4gZW4gc3UgY2FycmVyYS4gWSByZWFsaXphbmRvIGxhIG1lZGlhIHBvciBjYWRhIHVuYSBkZSBsYXMgcG9zaWNpb25lcywgb2J0ZW5lbW9zIHVuYSBjb3JyZWxhY2nDs24gcG9zaXRpdmEgZW50cmUgbGFzIHByaW1lcmFzIGVsZWNjaW9uZXMgZGVsIGRyYWZ0LCB5IGxvcyBtYXlvcmVzIHZhbG9yZXMgZW4gcHVudG9zIHBvciBwYXJ0aWRvLg0KDQoNClBvciDDumx0aW1vLCBwYXJhIGFmaWFuemFyIGVzdGEgaWRlYSwgdmVhbW9zIGxhIHJlbGFjacOzbiBlbnRyZSBsYSBwb3NpY2nDs24gZGUgZWxlY2Npw7NuIGVuIGVsIGRyYWZ0IGNvbiBlbCBwcmVtaW8gaW5kaXZpZHVhbCBtw6FzIHByZXN0aWdpb3NvIGRlIGxhIGNvbXBldGljacOzbiwgZWwgTVZQLg0KDQo8Y2VudGVyPg0KDQpgYGB7cn0NCnByZW1pb3MgPC0gYXdhcmRzICU+JSBmaWx0ZXIod2lubmVyID09ICdUUlVFJykgJT4lIGdyb3VwX2J5KGF3YXJkLCBwbGF5ZXIpICU+JSANCiAgbXV0YXRlKG1hc19wcmVtaW9zID0gc3VtKE5OID0gbigpKSkgJT4lIA0KICBkaXN0aW5jdChwbGF5ZXIsIGF3YXJkLCBtYXNfcHJlbWlvcykNCg0KbXZwIDwtIHByZW1pb3MgJT4lIGZpbHRlcihhd2FyZCA9PSAnbmJhIG12cCcpICU+JSBhcnJhbmdlKGRlc2MobWFzX3ByZW1pb3MpKSANCm12cCRwbGF5ZXIgPC0gaWNvbnYobXZwJHBsYXllciwgZnJvbSA9ICdVVEYtOCcsIHRvID0gJ0xBVElOMScpDQoNCm12cF9kcmFmdCA8LSBsZWZ0X2pvaW4obXZwLCBhbGxfanVnLCBjKCdwbGF5ZXInID0gJ3BsYXllcl9uYW1lJykpICU+JSANCiAgZGlzdGluY3QocGxheWVyLCBhd2FyZCwgbWFzX3ByZW1pb3MsIGRyYWZ0X251bWJlcikgJT4lIG5hLm9taXQoKSAlPiUNCiAgYXJyYW5nZShkZXNjKGRyYWZ0X251bWJlcikpDQoNCm12cF9kcmFmdFssIGMoNCldIDwtIHNhcHBseShtdnBfZHJhZnRbLCBjKDQpXSwgYXMubnVtZXJpYykNCg0KDQpnZ212cCA8LSBnZ3Bsb3QobXZwX2RyYWZ0LCBhZXMoeCA9IHBsYXllciwgeSA9IGRyYWZ0X251bWJlciwgc2l6ZSA9IG1hc19wcmVtaW9zKSkgKyBnZW9tX3BvaW50KGNvbG9yPSdyZWQnKSArIGNvb3JkX2ZsaXAoKSArIHRoZW1lKHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJiZWlnZSIpLA0KICAgIHBsb3QuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gImJlaWdlIiksDQogICAgbGVnZW5kLmtleSA9IGVsZW1lbnRfcmVjdChmaWxsID0gImJlaWdlIiksDQogICAgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJiZWlnZSIpKSArbGFicyh4ID0gIkp1Z2Fkb3IiLCB5ID0gIk7CuiBEcmFmdCIsIHNpemUgPSAiTsK6IE1WUHMiKSANCmdncGxvdGx5KGdnbXZwKQ0KYGBgDQoNCjwvY2VudGVyPg0KDQpDYWJlIG1lbmNpb25hciBxdWUgZW4gZWwgZ3LDoWZpY28gbm8gYXBhcmVjZW4gdG9kb3MgbG9zIGdhbmFkb3JlcyBkZWwgTVZQIGVuIGxhIGhpc3RvcmlhLCB5YSBxdWUgZHVyYW50ZSBsb3MgY29taWVuem9zIGVsIHNpc3RlbWEgZGUgZWxlY2Npw7NuIGVyYSBkaWZlcmVudGUsIHBvciBsbyBxdWUgbm8gZXhpc3RlIHVuYSBhc2lnbmFjacOzbiBlbiBlbCBkcmFmdCBwYXJhIGxvcyBwcmltZXJvcyBnYW5hZG9yZXMuDQoNCkVuIGN1YW50byBhbCBncsOhZmljbywgc2UgYXByZWNpYSBwZXJmZWN0YW1lbnRlIGNvbW8gbG9zIGdhbmFkb3JlcyBzZSBzaXTDumFuIGVuIGxhcyBwcmltZXJhcyBlbGVjY2lvbmVzIGRlbCBkcmFmdCwgY29tbyBMZWJyb24gSmFtZXMsIG7CujEgZGVsIGRyYWZ0IDIwMDMgY29uIDQgTVZQcywgbyBNaWNoYWVsIEpvcmRhbiwgbsK6IDMgZGVsIGRyYWZ0IDE5ODQgY29uIDUgTVZQcy4gQSBtb2RvIGRlIGV4Y2VwY2nDs24sIHRlbmVtb3MgYWwgYWN0dWFsIGdhbmFkb3IsIE5pa29sYSBKb2tpYywgcXVlIGJhdGnDsyBlbCByZWNvcmQgY29tbyBNVlAgZWxlZ2lkbyBtw6FzIHRhcmRlIGVuIHVuIERyYWZ0LCBjb25jcmV0YW1lbnRlIGVuIGxhIHBvc2ljacOzbiBuwrogNDEgZW4gMjAxNC4NCg0KDQoNCiMgNC4gTMOtZGVyZXMgZXN0YWTDrXN0aWNvcw0KDQpMYSBlc3RhZMOtc3RpY2EgZXMgdW4gYXBhcnRhZG8gZnVuZGFtZW50YWwgZW4gbGEgTkJBLiBFbCBkZXNlbXBlw7FvIGRlIGxvcyBqdWdhZG9yZXMgc2UgbWlkZSBlbiBncmFuIHBhcnRlIHBvciBsYSBjYXBhY2lkYWQgcXVlIMOpc3RvcyB0aWVuZW4gcGFyYSBheXVkYXIgZWwgZXF1aXBvIGVuIHTDqXJtaW5vcyBjdWFudGl0YXRpdm9zIGNvbiBwdW50b3MgYW5vdGFkb3MsIGFzaXN0ZW5jaWFzLCByZWJvdGVzLCBldGMuLi4NCg0KUHJpbWVybyBxdWUgbmFkYSwgdW4gcmVwYXNvIHBvciBsb3MgbMOtZGVyZXMgZXN0YWTDrXN0aWNvcyBoaXN0w7NyaWNvcw0KDQpgYGB7cn0NCmxpZGVydF9wdW50b3MgPC0gc2Vhc29uc19zdGF0c19qdWcgJT4lIA0KICBkcGx5cjo6cmVuYW1lKCAidHJpcGxlcyIgPSAiM1AiLCAgImRvc3B1bnRvcyIgPSAiMlAiKSAlPiUgDQogIHNlbGVjdChZZWFyLCBQbGF5ZXIsIHRyaXBsZXMsIGRvc3B1bnRvcywgRlQpDQoNCmxpZGVydF9wdW50b3NbaXMubmEobGlkZXJ0X3B1bnRvcyldIDwtIDANCg0KbGlkZXJ0X3B1bnRvczIgPC0gbGlkZXJ0X3B1bnRvcyAlPiUgbXV0YXRlKHB1bnRvcyA9IHRyaXBsZXMqMyArIGRvc3B1bnRvcyoyICsgRlQpICU+JSANCiAgc2VsZWN0KFBsYXllciwgcHVudG9zKSAlPiUgIA0KICBncm91cF9ieShQbGF5ZXIpICU+JSANCiAgbXV0YXRlKHRvdGFsX3B1bnRvcyA9IHN1bShwdW50b3MpKSAlPiUgDQogIGFycmFuZ2UoZGVzYyh0b3RhbF9wdW50b3MpKSAlPiUgDQogIGRpc3RpbmN0KFBsYXllciwgdG90YWxfcHVudG9zKSAlPiUgDQogIGZpbHRlcih0b3RhbF9wdW50b3MgPiAzMjAwMCkgJT4lIA0KICByZW5hbWUoJ05vbWJyZScgPSAnUGxheWVyJywgJ1B1bnRvcycgPSAndG90YWxfcHVudG9zJykNCg0KbGlkZXJ0X3B1bnRvczIkTm9tYnJlIDwtIGdzdWIoIlsqXSIsIiIsbGlkZXJ0X3B1bnRvczIkTm9tYnJlKQ0KDQprbml0cjo6a2FibGUobGlkZXJ0X3B1bnRvczIsIGNhcHRpb24gPSAiTcOheGltb3MgQW5vdGFkb3JlcyIpICU+JSANCiAga2FibGVFeHRyYTo6a2FibGVfc3R5bGluZyhib290c3RyYXBfb3B0aW9ucyA9IGMoInN0cmlwZWQiLCAiaG92ZXIiKSkgICU+JSANCiAga2FibGVFeHRyYTo6a2FibGVfc3R5bGluZyhmaXhlZF90aGVhZCA9IGxpc3QoZW5hYmxlZCA9IFQsIGJhY2tncm91bmQgPSAib3JhbmdlIikpDQpgYGANCg0KW0RhdG9zIGRlIDIwMTcsIGEgZmVjaGEgZGUgMDcvMDEvMjAyMiwgTGVicm9uIEphbWVzIGVzIGVsIDNlciBtw6F4aW1vIGFub3RhZG9yIGNvbiAzNi4xMDcgcHVudG9zXXsuc21hbGx9DQoNCmBgYHtyfQ0KbGlkZXJ0X2FzaXN0IDwtIHNlYXNvbnNfc3RhdHNfanVnICU+JSANCiAgc2VsZWN0KFBsYXllciwgQVNUKSAlPiUgIA0KICBncm91cF9ieShQbGF5ZXIpICU+JSANCiAgbXV0YXRlKHRvdGFsX2FzaXN0ID0gc3VtKEFTVCkpICU+JSANCiAgYXJyYW5nZShkZXNjKHRvdGFsX2FzaXN0KSkgJT4lIA0KICBkaXN0aW5jdChQbGF5ZXIsIHRvdGFsX2FzaXN0KSAlPiUgDQogIGZpbHRlcih0b3RhbF9hc2lzdCA+IDEwMDAwKSAlPiUgDQogIHJlbmFtZSgnTm9tYnJlJyA9ICdQbGF5ZXInLCAnQXNpc3RlbmNpYXMnID0gJ3RvdGFsX2FzaXN0JykNCmxpZGVydF9hc2lzdCROb21icmUgPC0gZ3N1YigiWypdIiwiIixsaWRlcnRfYXNpc3QkTm9tYnJlKQ0KDQprbml0cjo6a2FibGUobGlkZXJ0X2FzaXN0LCBjYXB0aW9uID0gIk3DoXhpbW9zIEFzaXN0ZW50ZXMiKSAlPiUgDQogIGthYmxlRXh0cmE6OmthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImhvdmVyIikpICAlPiUgDQogIGthYmxlRXh0cmE6OmthYmxlX3N0eWxpbmcoZml4ZWRfdGhlYWQgPSBsaXN0KGVuYWJsZWQgPSBULCBiYWNrZ3JvdW5kID0gIm9yYW5nZSIpKQ0KDQoNCmxpZGVydF9yZWJvdGVzIDwtIHNlYXNvbnNfc3RhdHNfanVnICU+JSANCiAgc2VsZWN0KFBsYXllciwgVFJCKSAlPiUgIA0KICBncm91cF9ieShQbGF5ZXIpICU+JSANCiAgbXV0YXRlKHRvdGFsX3JlYm90ZXMgPSBzdW0oVFJCKSkgJT4lIA0KICBhcnJhbmdlKGRlc2ModG90YWxfcmVib3RlcykpICU+JSANCiAgZGlzdGluY3QoUGxheWVyLCB0b3RhbF9yZWJvdGVzKSAlPiUgDQogIGZpbHRlcih0b3RhbF9yZWJvdGVzID4gMTcwMDApICU+JSANCiAgcmVuYW1lKCdOb21icmUnID0gJ1BsYXllcicsICdSZWJvdGVzJyA9ICd0b3RhbF9yZWJvdGVzJykNCmxpZGVydF9yZWJvdGVzJE5vbWJyZSA8LSBnc3ViKCJbKl0iLCIiLGxpZGVydF9yZWJvdGVzJE5vbWJyZSkNCg0Ka25pdHI6OmthYmxlKGxpZGVydF9yZWJvdGVzLCBjYXB0aW9uID0gIk3DoXhpbW9zIFJlYm90ZWFkb3JlcyIpICU+JSANCiAga2FibGVFeHRyYTo6a2FibGVfc3R5bGluZyhib290c3RyYXBfb3B0aW9ucyA9IGMoInN0cmlwZWQiLCAiaG92ZXIiKSkgICU+JSANCiAga2FibGVFeHRyYTo6a2FibGVfc3R5bGluZyhmaXhlZF90aGVhZCA9IGxpc3QoZW5hYmxlZCA9IFQsIGJhY2tncm91bmQgPSAib3JhbmdlIikpDQoNCg0KbGlkZXJ0X3JvYm9zIDwtICBzZWFzb25zX3N0YXRzX2p1ZyAlPiUgDQogIHNlbGVjdChQbGF5ZXIsIFNUTCkgJT4lICANCiAgZ3JvdXBfYnkoUGxheWVyKSAlPiUgDQogIG11dGF0ZSh0b3RhbF9yb2JvcyA9IHN1bShTVEwpKSAlPiUgDQogIGFycmFuZ2UoZGVzYyh0b3RhbF9yb2JvcykpICU+JSANCiAgZGlzdGluY3QoUGxheWVyLCB0b3RhbF9yb2JvcykgJT4lIA0KICBmaWx0ZXIodG90YWxfcm9ib3MgPiAyNDAwKSAlPiUgDQogIHJlbmFtZSgnTm9tYnJlJyA9ICdQbGF5ZXInLCAnUm9ib3MnID0gJ3RvdGFsX3JvYm9zJykNCmxpZGVydF9yb2JvcyROb21icmUgPC0gZ3N1YigiWypdIiwiIixsaWRlcnRfcm9ib3MkTm9tYnJlKQ0KDQprbml0cjo6a2FibGUobGlkZXJ0X3JvYm9zLCBjYXB0aW9uID0gIk3DoXhpbW9zIFJlY3VwZXJhZG9yZXMiKSAlPiUgDQogIGthYmxlRXh0cmE6OmthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImhvdmVyIikpICAlPiUgDQogIGthYmxlRXh0cmE6OmthYmxlX3N0eWxpbmcoZml4ZWRfdGhlYWQgPSBsaXN0KGVuYWJsZWQgPSBULCBiYWNrZ3JvdW5kID0gIm9yYW5nZSIpKQ0KDQoNCmxpZGVydF90YXBvbmVzIDwtIHNlYXNvbnNfc3RhdHNfanVnICU+JSANCiAgc2VsZWN0KFBsYXllciwgQkxLKSAlPiUgIA0KICBncm91cF9ieShQbGF5ZXIpICU+JSANCiAgbXV0YXRlKHRvdGFsX3RhcG9uZXMgPSBzdW0oQkxLKSkgJT4lIA0KICBhcnJhbmdlKGRlc2ModG90YWxfdGFwb25lcykpICU+JSANCiAgZGlzdGluY3QoUGxheWVyLCB0b3RhbF90YXBvbmVzKSAlPiUgDQogIGZpbHRlcih0b3RhbF90YXBvbmVzID4gMjkwMCkgJT4lIA0KICByZW5hbWUoJ05vbWJyZScgPSAnUGxheWVyJywgJ1RhcG9uZXMnID0gJ3RvdGFsX3RhcG9uZXMnKQ0KbGlkZXJ0X3RhcG9uZXMkTm9tYnJlIDwtIGdzdWIoIlsqXSIsIiIsbGlkZXJ0X3RhcG9uZXMkTm9tYnJlKQ0KDQprbml0cjo6a2FibGUobGlkZXJ0X3RhcG9uZXMsIGNhcHRpb24gPSAiTcOheGltb3MgVGFwb25hZG9yZXMiLCBjYXB0aW9uX2NvbG91ciA9ICdyZWQnKSAlPiUgDQogIGthYmxlRXh0cmE6OmthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImhvdmVyIikpICU+JSANCiAga2FibGVFeHRyYTo6a2FibGVfc3R5bGluZyhmaXhlZF90aGVhZCA9IGxpc3QoZW5hYmxlZCA9IFQsIGJhY2tncm91bmQgPSAib3JhbmdlIikpDQpgYGANCg0KDQojIyA0LjEgSGFjaWEgZWwgdHJpcGxlDQoNCkRlbnRybyBkZWwgYXBhcnRhZG8gZXN0YWTDrXN0aWNvLCBtZSBpbnRlcmVzYSBhbmFsaXphciBsYSBpbmNpZGVuY2lhIGRlIGxvcyB0cmlwbGVzIGVuIGxhIE5CQSBhY3R1YWwuDQoNCkFudGVzIHF1ZSBuYWRhLCBlcyBwcmVmZXJpYmxlIGludHJvZHVjaXIgbGEgZmlndXJhIGRlbCB0aXJvIGRlIDMgcHVudG9zLiBTZSB0cmF0YSBkZSB1bmEgbMOtbmVhIHNpdHVhZGEgYSA2LDcwIG1ldHJvcyBkZSBkaXN0YW5jaWEgYWwgYXJvIGRlc2RlIGxhcyBiYW5kYXMsIHkgYSA3LDI1IG1ldHJvcyBkZXNkZSBsYSBwYXJ0ZSBmcm9udGFsLiBFc3RhcyBtZWRpZGFzIG5vIGNvcnJlc3BvbmRlbiBjb24gZWwgYmFsb25jZXN0byBldXJvcGVvIChyZWdsYXMgRklCQSkgbmkgZWwgYmFsb25jZXN0byB1bml2ZXJzaXRhcmlvLCBjb24gbMOtbmVhcyBtw6FzIHByw7N4aW1hcyBlbiBhbWJvcy4NCg0KRXN0YSBpbXBsZW1lbnRhY2nDs24gbm8gc2UgZW5jb250cmFiYSBlbiBsYXMgcmVnbGFzIGRlbCBqdWVnbyBvcmlnaW5hbGVzLCB5IGVuIGxhIE5CQSBubyBzZSBpbXBsYW50w7MgaGFzdGEgbGEgdGVtcG9yYWRhIDE5NzktMTk4MC4gU2UgY3Jlw7MgY29tbyB1bmEgZm9ybWEgZGUgY29udHJhcnJlc3RhciBsYSBhYnNvbHV0YSBkb21pbmFuY2lhIGRlIGxvcyBob21icmVzIG3DoXMgYWx0b3MsIGxvcyBjdWFsZXMgZG9taW5hYmFuIGxhIHBpbnR1cmEgcHJvdm9jYW5kbyB1biBzb2JyZXVzbyBkZSBsb3MgdGlyb3MgZW4gZGlzdGFuY2lhcyBjZXJjYW5hcy4gDQoNCkNvbiBlbCB0cmlwbGUgZW4gbGEgTkJBLCBzZSBwcm9kdWpvIHVuYSBtYXlvciByZWRpc3RyaWJ1Y2nDs24gZW4gbGEgZGlzdGFuY2lhIGRlIGxvcyB0aXJvcyByZWFsaXphZG9zLCBwZXJvIHJlY2llbnRlbWVudGUsIGVzcGVjaWFsbWVudGUgZGVzZGUgbGEgZGluYXN0w61hIGRlIGxvcyBHb2xkZW4gU3RhdGUgV2FycmlvcnMsIGxhIGluY2lkZW5jaWEgZGVsIHRyaXBsZSBlbiBsb3MgcGFydGlkb3MgaGEgZXhwZXJpbWVudGFkbyB1biBhc2NlbnNvIG1ldGXDs3JpY28uIE1pZW50cmFzIHF1ZSBhbnRlcyBzZSBjb25zaWRlcmFiYSBjb21vIHVuIGFybWEgY29tcGxlbWVudGFyaWEsIGNvbiBlc3BlY2lhbGlzdGFzIGRlZGljYWRvcyBlc3BlY8OtZmljYW1lbnRlIGEgbGFuemFyIGRlc2RlIGxhIGzDrW5lYSBkZSAzLCBlc3RvcyDDumx0aW1vcyBhw7FvcywgZWwgdHJpcGxlIGhhIHNpZG8gY29uc2lkZXJhZG8gY29tbyBsYSBwcmluY2lwYWwgaGVycmFtaWVudGEgZGUgYXRhcXVlIHBhcmEgbXVjaGFzIGZyYW5xdWljaWFzLg0KDQpFc3RvIHB1ZWRlIHZlcnNlIHRhbnRvIGVuIGxhIGRpc3RhbmNpYSBhIGxhIHF1ZSBlc3TDoW4gZGlzcHVlc3RvcyBhIGxhbnphciBsb3MgdGlyYWRvcmVzIGhveSBlbiBkw61hLCBjb21vIGVuIGxvcyBwb3JjZW50YWplcyBkZSBhY2llcnRvLg0KDQoNCkFxdcOtIHBvZGVtb3MgYXByZWNpYXIgY29tbyBsYSBkaXN0YW5jaWEgbWVkaWEgZGUgbG9zIGxhbnphbWllbnRvcyByZWFsaXphZG9zIGhhIGF1bWVudGFkbyBjb25zaWRlcmFibGVtZW50ZSBkZXNkZSBsYSB0ZW1wb3JhZGEgMTk5Ny0xOTk4IGhhc3RhIGxhIGFjdHVhbGlkYWQsIGRlbW9zdHLDoW5kb3NlIGNvbW8gbGEgY3VsdHVyYSBkZWwgdHJpcGxlIGhhIHNpZG8gY2FkYSB2ZXogbcOhcyByZWxldmFudGUuDQoNCmBgYHtyfQ0KcGxheWVyX3Nob290aW5nIDwtIHJpbzo6aW1wb3J0KCIuL2RhdG9zL25iYV9zdGF0cy9wbGF5ZXJfc2hvb3RpbmcuY3N2IikNCg0KZGlzdF9tZWRpYSA8LSBwbGF5ZXJfc2hvb3RpbmcgJT4lIGdyb3VwX2J5KHNlYXNvbikgJT4lIA0KICBtdXRhdGUobWVkaWFfZGlzdCA9IG1lYW4oYXZnX2Rpc3RfZmdhLCBuYS5ybSA9IFRSVUUpKSAlPiUgDQogIGRpc3RpbmN0KHNlYXNvbixtZWRpYV9kaXN0KSAlPiUgDQogIG11dGF0ZShtZXRyb3MgPSBtZWRpYV9kaXN0LzMuMjgxKQ0KDQpjdXJyeSA8LSByZWFkSlBFRygiLi9pbWFnZW5lcy9jdXJyeS5qcGciKQ0KY3VycnkgPC0gcmFzdGVyR3JvYihjdXJyeSwgd2lkdGggPSB1bml0KDEsICJucGMiKSwgaGVpZ2h0ID0gdW5pdCgxLCAibnBjIiksIGludGVycG9sYXRlID0gVFJVRSkgDQoNCmdnZGlzdCA8LSBnZ3Bsb3QoZGlzdF9tZWRpYSwgYWVzKHggPSBzZWFzb24sIHkgPSBtZXRyb3MpKSArDQogIGFubm90YXRpb25fY3VzdG9tKGN1cnJ5LCB4bWluID0gLUluZiwgeG1heCA9IEluZiwgeW1pbiA9IDEuNywgeW1heCA9IDQuMjUpICsNCiAgZ2VvbV9yaWJib24oYWVzKHhtaW4gPSAxOTk1LCB4bWF4PTIwMjUsIHltaW4gPSBtZXRyb3MsIHltYXggPSBJbmYpLCBmaWxsID0gImJlaWdlIikgKw0KICBnZW9tX3JpYmJvbihhZXMoeG1pbj0tSW5mLCB4bWF4PSAxOTk3KSwgZmlsbCA9ICJiZWlnZSIpKw0KICAjZ2VvbV9yaWJib24oYWVzKHhtaW49LUluZiwgeG1heD0gMTk5NyksIGZpbGwgPSAid2hpdGUiKSsNCiAgDQogIGdlb21fbGluZShzaXplPTEsIGNvbG91cj0icmVkIikgKyBnZW9tX3BvaW50KGNvbG91cj0icmVkIikgKw0KICBzY2FsZV94X2NvbnRpbnVvdXMoDQogICAgYnJlYWtzID0gc2VxKDE5OTcsIDIwMjIsIDIpLA0KICAgIGxpbWl0cyA9IGMoMTk5NywgMjAyMikpKw0KICBzY2FsZV95X2NvbnRpbnVvdXMoDQogICAgYnJlYWtzID0gc2VxKDMsIDQuNSwgMC4yNSksDQogICAgbGltaXRzID0gYygzLCA0LjUpKSsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJEaXN0YW5jaWEgTWVkaWEgZGUgTGFuemFtaWVudG9zIiwNCiAgICBzdWJ0aXRsZSA9ICIxOTk3LTIwMjIiLA0KICAgIHg9IkHDsW8iLA0KICAgIHk9Ik1ldHJvcyIsDQogICAgY2FwdGlvbj0iU3RlcGhlbiBDdXJyeSwgcmVhbGl6YW5kbyBzdSB0cmlwbGUgbsK6IDMwMDAiKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoZmFjZT0iYm9sZCIsIGhqdXN0PTAuNSwgc2l6ZT1yZWwoMS41KSksDQogICAgICAgIHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoZmFjZT0iaXRhbGljIiwgaGp1c3Q9MC41KSkgKyB0aGVtZShwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGxpbmV0eXBlID0gImJsYW5rIiksDQogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShsaW5ldHlwZSA9ICJibGFuayIpLA0KICAgIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJiZWlnZSIpLA0KICAgIHBsb3QuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gImJlaWdlIikpDQoNCmdnZGlzdA0KYGBgDQoNCkxhIGV2b2x1Y2nDs24gZW4gY3VhbnRvIGEgcG9yY2VudGFqZXMsIG5vIGhhY2UgbcOhcyBxdWUgY29uZmlybWFyIGxhIGlkZWEgcGxhbnRlYWRhIGFudGVyaW9ybWVudGUsIGNhZGEgdmV6IHNlIHRpcmFuIG3DoXMgdHJpcGxlcywgeSBjb24gbWF5b3IgYWNpZXJ0by4NCg0KDQpgYGB7cn0NCnNlYXNvbnNfc3RhdHNfanVnIDwtIHJpbzo6aW1wb3J0KCIuL2RhdG9zL25iYV9wbGF5ZXJzXzIvU2Vhc29uc19TdGF0cy5jc3YiKQ0KDQpwZXJjX3RyaXBsZSA8LSBzZWFzb25zX3N0YXRzX2p1ZyAlPiUgZHBseXI6OnJlbmFtZSggInRocmVlX3BlcmMiID0gIjNQJSIpICU+JSANCiAgc2VsZWN0KFllYXIsIFBsYXllciwgdGhyZWVfcGVyYykgJT4lIA0KICBncm91cF9ieShZZWFyKSAlPiUgDQogIG11dGF0ZShwZXJjM190b3RhbCA9IG1lYW4odGhyZWVfcGVyYywgbmEucm0gPSBUUlVFKSkgJT4lDQogIGRpc3RpbmN0KFllYXIsIHBlcmMzX3RvdGFsKQ0KDQoNCnBlcmNfdHJpcGxlX3Bpdm90IDwtIHNlYXNvbnNfc3RhdHNfanVnICU+JSBmaWx0ZXIoUG9zICVpbiUgYygnQycsICdQRicsICdDLVBGJywnUEYtQycpKSAlPiUgDQogIGRwbHlyOjpyZW5hbWUoICJ0aHJlZV9wZXJjIiA9ICIzUCUiKSAlPiUgDQogIHNlbGVjdChZZWFyLCBQbGF5ZXIsIHRocmVlX3BlcmMpICU+JSANCiAgZ3JvdXBfYnkoWWVhcikgJT4lIA0KICBtdXRhdGUocGVyYzNfdG90YWxfcGl2b3QgPSBtZWFuKHRocmVlX3BlcmMsIG5hLnJtID0gVFJVRSkpICU+JQ0KICBkaXN0aW5jdChZZWFyLCBwZXJjM190b3RhbF9waXZvdCkNCg0KcGVyY18zX2ZpbmFsIDwtIGxlZnRfam9pbihwZXJjX3RyaXBsZSwgcGVyY190cmlwbGVfcGl2b3QsIGMoJ1llYXInID0gJ1llYXInKSkgJT4lIGZpbHRlcihZZWFyID49IDE5ODApICU+JSByb3VuZChkaWdpdHMgPSAyKSAlPiUgDQogIG11dGF0ZShwb3JjX3RyaXBsZSA9IHBlcmMzX3RvdGFsKjEwMCkgJT4lIA0KICBtdXRhdGUocG9yY190cmlwbGVfcGl2b3QgPSBwZXJjM190b3RhbF9waXZvdCoxMDApDQogIA0KDQpwZXJjXzNfZmluYWxbLCBjKDIpXSA8LSBzYXBwbHkocGVyY18zX2ZpbmFsWywgYygyKV0sIGFzLm51bWVyaWMpDQpwZXJjXzNfZmluYWxbLCBjKDMpXSA8LSBzYXBwbHkocGVyY18zX2ZpbmFsWywgYygzKV0sIGFzLm51bWVyaWMpDQoNCmdnM3RvdGFsIDwtIGdncGxvdChwZXJjXzNfZmluYWwsIGFlcyh4ID0gWWVhciwgeSA9IHBvcmNfdHJpcGxlKSkgKyBnZW9tX2xpbmUoY29sb3VyID0gJ2dyYXk1MCcsIHNpemUgPSAxLjIpICsgDQogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLA0KICAgIGhqdXN0ID0gMC41KSwgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gImJlaWdlIiksDQogICAgcGxvdC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAiYmVpZ2UiKSkgK2xhYnModGl0bGUgPSAiRXZvbHVjacOzbiBkZWwgJSBkZSBhY2llcnRvIGVuIHRyaXBsZXMiLA0KICAgIHggPSAiQcOxbyIsIHkgPSAiJSBhY2llcnRvIikgKyB0aGVtZShwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGxpbmV0eXBlID0gImJsYW5rIiksDQogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShsaW5ldHlwZSA9ICJibGFuayIpKQ0KDQoNCmdnM3Bpdm90IDwtIGdncGxvdChwZXJjXzNfZmluYWwsIGFlcyh4ID0gWWVhciwgeSA9IHBvcmNfdHJpcGxlX3Bpdm90KSkgKyBnZW9tX2xpbmUoY29sb3VyID0gJ2RhcmtibHVlJywgc2l6ZSA9IDEuMikgKyANCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGhqdXN0ID0gMC41KSwgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gImJlaWdlIiksIA0KICAgICAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJiZWlnZSIpKSArDQogIGxhYnModGl0bGUgPSAiRXZvbHVjacOzbiBkZWwgJSBkZSBhY2llcnRvIGVuIHRyaXBsZXMgZW4gUElWT1RTIiwgeCA9ICJBw7FvIiwgeSA9ICIlIGFjaWVydG8iKSArIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUobGluZXR5cGUgPSAiYmxhbmsiKSwNCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV0eXBlID0gImJsYW5rIikpDQoNCg0KZ2dhcnJhbmdlKGdnM3RvdGFsLCBnZzNwaXZvdCwNCiAgICAgICAgICBuY29sID0gMiwgbnJvdyA9IDEpDQpgYGANCg0KRXNwZWNpYWxtZW50ZSBkZXN0YWNhZG8gZWwgYXVtZW50byBkZWwgcG9yY2VudGFqZSBlbiBsb3MgcMOtdm90cywgbG9zIGhvbWJyZXMgbcOhcyBhbHRvcy4gRW4gw6lwb2NhcyBhbnRlcmlvcmVzLCBlc3RhcyBwb3NpY2lvbmVzIGVzdGFiYW4gZGVkaWNhZGFzIGEgcHJvdGVnZXIgZWwgYXJvIGVuICBidXNjYSBkZSByZWJvdGVzIHkgcHVudG9zIGbDoWNpbGVzIGNlcmNhbm9zIGEgY2FuYXN0YSwgcGVybyBlbCA1IHRyYWRpY2lvbmFsIHNlIGVzdMOhICoqZXh0aW5ndWllbmRvKiogcG9jbyBhIHBvY28uIENhZGEgdmV6IGVzIG3DoXMgcmFybyBxdWUgdW4ganVnYWRvciBpbnRlcmlvciBubyBzZSBhYnJhIHBhcmEgbGFuemFyIGRlIDMuDQoNCkVzdGUgY2FtYmlvIGRlIHBhcmFkaWdtYSBoYSBzdXB1ZXN0byB1bmEgZ3JhbiBwb2xhcml6YWNpw7NuIGVuIGN1YW50byBhbCB1c28gZGUgbGFzIHBvc2VzaW9uZXMgZGUgY2FkYSBjb25qdW50by4gQWN0dWFsbWVudGUsIGxhIGdyYW4gbWF5b3LDrWEgZGUgZXN0YXMgdGVybWluYW4gY29uIHVuIGxhbnphbWllbnRvIGRlIDMsIG8gY29uIHVuIGxhbnphbWllbnRvIGRlbnRybyBkZSBsYSB6b25hIChtdXkgY2VyY2FubyBhbCBhcm8pLCBkZWphbmRvIGNhc2kgb2Jzb2xldG8gZWwgbGFuemFtaWVudG8gZGUgbWVkaWEgZGlzdGFuY2lhLCBwcm92b2NhbmRvIHF1ZSBhcXVlbGxvcyBqdWdhZG9yZXMgcXVlICoqbm8qKiBkb21pbmFiYW4gbGEgZmFjZXRhIGRlbCB0cmlwbGUsIGhheWFuIHRlbmlkbyBxdWUgaW1wbGVtZW50YXJsYSBlbiBzdSBqdWVnbywgeSBwb3Igb3RyYSBwYXJ0ZSwgYXF1ZWxsb3MgcXVlICoqc29sbyoqIGFjdHVhYmFuIGNvbW8gdHJpcGxpc3Rhcywgc2UgaGF5YW4gZXhwYW5kaWRvIGEgb3Ryb3MgY29tZXRpZG9zLg0KDQojIDUuIFBhbG1hcsOpcw0KDQpQb3Igc3VlcnRlIG8gcG9yIGRlc2dyYWNpYSwgbGEgbcOheGltYSB5IMO6bmljYSBhc3BpcmFjacOzbiBxdWUgcG9zZWVuIGxvcyBlcXVpcG9zIGRlIGxhIE5CQSBlcyBjb25zZWd1aXIgYWx6YXJzZSBjb24gZWwgdMOtdHVsbyBkZSBjYW1wZcOzbiBhbCBmaW5hbCBkZSBjYWRhIHRlbXBvcmFkYS4NCg0KPGNlbnRlcj4NCg0KYGBge3J9DQoNCm1hc190aXR1bG9zIDwtIGNhbXBlb25lcyAlPiUgZ3JvdXBfYnkobmFtZSkgJT4lIG11dGF0ZShuX3RpdHVsb3MgPSBzdW0oTk4gPSBuKCkpKSAlPiUgDQogIGRpc3RpbmN0KG5hbWUsIG5fdGl0dWxvcykgJT4lIA0KICBhcnJhbmdlKGRlc2Mobl90aXR1bG9zKSkNCg0KaWQgPC0gcm93bmFtZXMobWFzX3RpdHVsb3MpDQptYXNfdGl0dWxvcyA8LSBjYmluZChpZD1pZCwgbWFzX3RpdHVsb3MpDQptYXNfdGl0dWxvc1ssIGMoMSldIDwtIHNhcHBseShtYXNfdGl0dWxvc1ssIGMoMSldLCBhcy5udW1lcmljKQ0KDQpsYWJlbF90aXR1bG9zIDwtIG1hc190aXR1bG9zDQpudW1iZXJfb2ZfYmFyIDwtIG5yb3cobGFiZWxfdGl0dWxvcykNCg0KYW5nbGUgPC0gOTAgLSAzNjAgKiAobGFiZWxfdGl0dWxvcyRpZC0wLjUpIC9udW1iZXJfb2ZfYmFyICAgIA0KbGFiZWxfdGl0dWxvcyRoanVzdCA8LSBpZmVsc2UoIGFuZ2xlIDwgLTkwLCAxLCAwKQ0KbGFiZWxfdGl0dWxvcyRhbmdsZSA8LSBpZmVsc2UoYW5nbGUgPCAtOTAsIGFuZ2xlKzE4MCwgYW5nbGUpDQoNCmJhc2VfdGl0dWxvcyA8LSBtYXNfdGl0dWxvcyAlPiUgDQogIGdyb3VwX2J5KG5hbWUpICU+JSANCiAgc3VtbWFyaXNlKHN0YXJ0PW1pbihpZCksIGVuZD1tYXgoaWQpKSAlPiUgDQogIHJvd3dpc2UoKSAlPiUgDQogIG11dGF0ZSh0aXRsZT1tZWFuKGMoc3RhcnQsIGVuZCkpKQ0KDQpncmlkX3RpdHVsb3MgPC0gYmFzZV90aXR1bG9zDQpncmlkX3RpdHVsb3MkZW5kIDwtIGdyaWRfdGl0dWxvcyRlbmRbIGMoIG5yb3coZ3JpZF90aXR1bG9zKSwgMTpucm93KGdyaWRfdGl0dWxvcyktMSldICsgMQ0KZ3JpZF90aXR1bG9zJHN0YXJ0IDwtIGdyaWRfdGl0dWxvcyRzdGFydCAtIDENCmdyaWRfdGl0dWxvcyA8LSBncmlkX3RpdHVsb3NbLTEsXQ0KDQpnZ190aXR1bG9zIDwtIGdncGxvdChtYXNfdGl0dWxvcywgYWVzKHg9YXMuZmFjdG9yKHllYXIpLCB5PW5fdGl0dWxvcywgZmlsbD1uX3RpdHVsb3MsIGNvbG9yID0gbl90aXR1bG9zKSkgKyBnZW9tX2JhcihhZXMoeD1hcy5mYWN0b3IoaWQpLCB5PW5fdGl0dWxvcywgZmlsbD1uX3RpdHVsb3MpLCBzdGF0PSJpZGVudGl0eSIsIGFscGhhPTAuNSkgKw0KICANCiAgZ2VvbV9zZWdtZW50KGRhdGE9Z3JpZF90aXR1bG9zLCBhZXMoeCA9IDAuNSwgeSA9IDE3LCB4ZW5kID0gMjAuOSwgeWVuZCA9IDE3KSwgY29sb3VyID0gImdyZXkiLCBhbHBoYT0xLCBzaXplPTAuMyAsIGluaGVyaXQuYWVzID0gRkFMU0UgKSArDQogIGdlb21fc2VnbWVudChkYXRhPWdyaWRfdGl0dWxvcywgYWVzKHggPSAwLjUsIHkgPSAxMCwgeGVuZCA9IDIwLjksIHllbmQgPSAxMCksIGNvbG91ciA9ICJncmV5IiwgYWxwaGE9MSwgc2l6ZT0wLjMgLCBpbmhlcml0LmFlcyA9IEZBTFNFICkgKw0KICBnZW9tX3NlZ21lbnQoZGF0YT1ncmlkX3RpdHVsb3MsIGFlcyh4ID0gMC41LCB5ID0gNSwgeGVuZCA9IDIwLjksIHllbmQgPSA1KSwgY29sb3VyID0gImdyZXkiLCBhbHBoYT0xLCBzaXplPTAuMyAsIGluaGVyaXQuYWVzID0gRkFMU0UgKSArDQogIGdlb21fc2VnbWVudChkYXRhPWdyaWRfdGl0dWxvcywgYWVzKHggPSAwLjUsIHkgPSAyLCB4ZW5kID0gMjAuOSwgeWVuZCA9IDIpLCBjb2xvdXIgPSAiZ3JleSIsIGFscGhhPTEsIHNpemU9MC4zICwgaW5oZXJpdC5hZXMgPSBGQUxTRSApICsNCiAgDQogIGFubm90YXRlKCJ0ZXh0IiwgeCA9IDAuMywgeSA9IGMoMiwgNSwgMTAsIDE3KSwgbGFiZWwgPSBjKCIyIiwgIjUiLCAiMTAiLCAiMTciKSAsIGNvbG9yPSJncmV5Iiwgc2l6ZT02ICwgYW5nbGU9MCwgZm9udGZhY2U9ImJvbGQiLCBoanVzdD0xKSArDQogIA0KICBnZW9tX2JhcihhZXMoeD1hcy5mYWN0b3IoaWQpLCB5PW5fdGl0dWxvcywgZmlsbD1uX3RpdHVsb3MpLCBzdGF0PSJpZGVudGl0eSIsIGFscGhhPTAuNSkgKw0KICB5bGltKC0xMCwyMSkgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZSgNCiAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsDQogICAgYXhpcy50ZXh0ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksDQogICAgcGFuZWwuZ3JpZCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBwbG90Lm1hcmdpbiA9IHVuaXQocmVwKC0xLDQpLCAiY20iKSApICsNCiAgY29vcmRfcG9sYXIoKSArIA0KICBnZW9tX3RleHQoZGF0YT1sYWJlbF90aXR1bG9zLCBhZXMoeD1pZCwgeT1uX3RpdHVsb3MrMSwgbGFiZWw9bmFtZSwgaGp1c3Q9aGp1c3QpLCBjb2xvcj0iYmxhY2siLCBmb250ZmFjZT0iYm9sZCIsYWxwaGE9MC42LCBzaXplPTUsIGFuZ2xlPSBsYWJlbF90aXR1bG9zJGFuZ2xlLCBpbmhlcml0LmFlcyA9IEZBTFNFICkgKyANCiAgdGhlbWUobGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoY29sb3VyID0gImJsYWNrIiksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KCBjb2xvdXIgPSAiYmxhY2siKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJiZWlnZSIsIGNvbG91ciA9ICJiZWlnZSIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlZ2VuZC5rZXkgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJiZWlnZSIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gImJlaWdlIiAsIGNvbG91ciA9ICJiZWlnZSIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBsb3QuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gImJlaWdlIiAsIGNvbG91ciA9ICJiZWlnZSIpKStsYWJzKGNvbG91ciA9ICJOwrogZGUgY2FtcGVvbmF0b3MiLCBmaWxsID0gIk7CuiBkZSBjYW1wZW9uYXRvcyIpICsgdGhlbWUobGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwNCiAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkNCiNnZ190aXR1bG9zDQoNCiNsYXMgc2lndWllbnRlcyBsaW5lYXMgZGUgY29kaWdvIHNlIHV0aWxpemFuIHBhcmEgZWxpbWluYXIgbG9zIGJvcmRlcyBibGFuY29zDQpnZ3NhdmUoIi4vcGxvdHMvZ2dfdGl0dWxvcy5wbmciLCB3aWR0aCA9IDE4LCBoZWlnaHQgPSAxNSkNCg0KYGBgDQoNCiFbXSguL3Bsb3RzL2dnX3RpdHVsb3MucG5nKXt3aWR0aD0xMDAwIGhlaWdodD03NTB9DQoNCjwvY2VudGVyPg0KDQpDb21vIGNsYXJvcyBkb21pbmFkb3JlcywgYXBhcmVjZW4gbG9zIEJvc3RvbiBDZWx0aWNzIChFc3RlKSB5IExvcyBBbmdlbGVzIExha2VycyAoT2VzdGUpLCBjb24gMTcgY2FtcGVvbmF0b3MgY2FkYSB1bm8uIA0KDQpFbCBoZWNobyBkZSBxdWUgdW4gdG90YWwgZGUgMTEgZnJhbnF1aWNpYXMgYcO6biBubyBoYXlhbiBsb2dyYWRvIG5pbmfDum4gY2FtcGVvbmF0byBkZSBsYSBOQkEsIGEgcGVzYXIgZGUgbGFzIG1lZGlkYXMgZGUgcmVkaXN0cmlidWNpw7NuIGV4aXN0ZW50ZXMgY29tbyBsb3MgdG9wZXMgc2FsYXJpYWxlcyB5IGxhIGxvdGVyw61hIGRlbCBkcmFmdCBhbnRlcyBtZW5jaW9uYWRhLCBwb25lIGRlIG1hbmlmaWVzdG8gcXVlIHBhcmEgYWx6YXJzZSBjb24gdW5vIGRlIGxvcyB0cm9mZW9zIG3DoXMgaW1wb3J0YW50ZXMgZGVsIGRlcG9ydGUsIHNlIG5lY2VzaXRhIG11Y2hvIG3DoXMgcXVlIGVzby4gTGEgY2FsaWRhZCB5IHF1w61taWNhIGRlbCBlcXVpcG8sIG1vdGl2YWNpw7NuLCBwb3RlbmNpYWwgZmluYW5jaWVybyBkZSBsYSBjaXVkYWQsIGJ1ZW5hIHBsYW5pZmljYWNpw7NuIHkgdW4gcG9jbyBkZSBzdWVydGUgY29uIGxhcyBsZXNpb25lcywgY29tcGxldGFuIGVsIHNldCBkZSBjdWFsaWRhZGVzIHJlcXVlcmlkYXMgcGFyYSBhbHphcnNlIGNvbiB0YW4gcHJlY2lhZG8gdMOtdHVsby4NCg0KDQojIEJpYmxpb2dyYWbDrWENCg0KSW5mb3JtYWNpw7NuIGVzdGFkw61zdGljYSBvYnRlbmlkYSBkZSBbSGlzcGFub3MgTkJBXShodHRwczovL3d3dy5oaXNwYW5vc25iYS5jb20vKSB5IFtCYXNrZXRiYWxsIFJlZmVyZW5jZV0oaHR0cHM6Ly93d3cuYmFza2V0YmFsbC1yZWZlcmVuY2UuY29tLykNCg0KRGF0YXNldHM6IA0KW2thZ2dsZV0oaHR0cHM6Ly93d3cua2FnZ2xlLmNvbS8pDQoNCjxicj4NCltOQkEgUGxheWVyc10oaHR0cHM6Ly93d3cua2FnZ2xlLmNvbS9qdXN0aW5hcy9uYmEtcGxheWVycy1kYXRhKQ0KDQo8YnI+DQoNCltOQkEgZ2FtZXMgZGF0YV0oaHR0cHM6Ly93d3cua2FnZ2xlLmNvbS9uYXRoYW5sYXVnYS9uYmEtZ2FtZXMpDQoNCjxicj4NCg0KW05CQSBQbGF5ZXJzIHN0YXRzIHNpbmNlIDE5NTBdKGh0dHBzOi8vd3d3LmthZ2dsZS5jb20vZHJnaWxlcm1vL25iYS1wbGF5ZXJzLXN0YXRzKQ0KDQo8YnI+DQoNCltOQkEgUGxheWVyIFNhbGFyeSBEYXRhc2V0ICgyMDE3IC0gMjAxOCldKGh0dHBzOi8vd3d3LmthZ2dsZS5jb20va29raTI1YW5kby9zYWxhcnkpDQoNCg0KPGJyPjxicj4NCg0KPGhyIGNsYXNzPSJsaW5lYS1ibGFjayI+DQo8aHIgY2xhc3M9ImxpbmVhLWJsYWNrIj4NCg0KPGJyPjxicj4NCg0KPGRpdiBjbGFzcz0idG9jaWZ5LWV4dGVuZC1wYWdlIiBkYXRhLXVuaXF1ZT0idG9jaWZ5LWV4dGVuZC1wYWdlIiBzdHlsZT0iaGVpZ2h0OiAwOyI+PC9kaXY+DQo8YnI+PGJyPg0KDQo8ZGl2IGNsYXNzPSJ0b2NpZnktZXh0ZW5kLXBhZ2UiIGRhdGEtdW5pcXVlPSJ0b2NpZnktZXh0ZW5kLXBhZ2UiIHN0eWxlPSJoZWlnaHQ6IDA7Ij48L2Rpdj4NCg==