contratos <- rio::import("./datos/contratos/nba_contracts_history.csv")

jug_act2021 <- import("./datos/nba_2122/active_players_2.csv")
jugadores2021 <- import("./datos/nba_2122/players.csv")

partidos_detalle <- rio::import("./datos/nba_games/games_details.csv")
partidos <- rio::import("./datos/nba_games/games.csv")
jugad_part <- rio::import("./datos/nba_games/players.csv")
ranking_part <- rio::import("./datos/nba_games/ranking.csv")
equipos_part <- rio::import("./datos/nba_games/teams.csv")

all_jug <- rio::import("./datos/nba_players/all_seasons.csv")

jug_info <- rio::import("./datos/nba_players_2/player_data.csv")
jug_college <- rio::import("./datos/nba_players_2/Players.csv")
seasons_stats_jug <- rio::import("./datos/nba_players_2/Seasons_Stats.csv")

awards <- rio::import("./datos/nba_stats/player_awards.csv")
all_nba <- rio::import("./datos/nba_stats/end_season_teams.csv")
team_totals <- rio::import("./datos/nba_stats/team_totals.csv")
team_per_game <- rio::import("./datos/nba_stats/team_per_game.csv")
advanced_stats <- rio::import("./datos/nba_stats/advanced.csv")

player_shooting <- rio::import("./datos/nba_stats/player_shooting.csv")

campeones <- rio::import("./datos/franquicias.xlsx")

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

La NBA es una de las competiciones más importantes y seguidas del mundo, además de ser la competición más importante y de más nivel baloncestístico. Se trata de una liga cerrada, de 30 equipos, sin ascensos ni descensos, al contrario de lo que estamos acostumbrados en las competiciones deportivas en España.



2. Datos

Los datos utilizados en el trabajo, han sido obtenidos de la página web kaggle, web con múltiples herramientas útiles para el manejo y análisis de datos, como pueden ser conjuntos de datos, scripts, competiciones, etc. Más concretamente, los conjuntos de datos utilizados son: NBA Players, NBA games data, NBA Players stats since 1950 y NBA Player Salary Dataset (2017 - 2018)

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.


Franquicias situadas en el mapa

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==