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
Spotify es el servicio digital de música, podcasts y vídeos, más utilizado actualmente a nivel mundial.En esta aplicación podras encontrar millones de canciones para todos los gustos, al igual que podcasts, ya que hay de todo tipo, de política, de economía de deportes, etc. En este trabajo, vamos a tratar varios temas sobre esta aplicación, en primer lugar, haremos un repaso sobre la evolución de Spotify a lo largo de los años, después nos adentraremos más en lo que más se ha escuchado en 2021 y comparaciones entre los distintos generos, y por último, nos referiremos más a aspectos musicales de las canciones, como la bailabilidad, la popularidad, los acordes… Al final de año, Spotify, muestra a sus usuarios un resumen de lo que mas ha escuchado durante ese año,de una forma interactiva y divertida, y de aqui es de donde me surgió la idea de realizar el trabajo sobre esta plataforma, a continuación podeis observar cual ha sido mi resumen de 2021
2. Datos
Los datos que he utilizado en este trabajo, han sido extraidos de kaggle en esta web he obtenido los datos sobre las canciones más escuhadas este 2021, de la propia web de Spotify aquí he extraido la información sobre los seguidores de los artistas y de Statista de esta web he sacado los datos sobre la evolución de los ingresos y de los oyentes.
2.1. Procesando los datos
En este apartado voy a mostrar como he manipulado los 4 dataframes, y que acciones he realizado en cada uno de ellos para eliminar fallos y dejarlos más organizados y con la información que me interesa.El df principal es el llamado spotify_dataset ya que este ha sido el que mas he manipulado, el que mas he utilizado y el que más in formación tiene.Los otros 3 df, **evolucion_usuarios, evolucion_ingresos, mas_seguidores* han sido más complementarios, ya que solo me han servido para hacer 2-3 gráficos.
#cambio estos nombres aqui debajo pq si no da error luego
spotify_dataset <- rio::import(file = "./datos/spotify_dataset.csv")
names(spotify_dataset)[names(spotify_dataset) == 'Artist Followers'] <- 'artist_followers'
names(spotify_dataset)[names(spotify_dataset) == 'Song Name'] <- 'song_name'
spotify_dataset$song_name <- iconv(spotify_dataset$song_name, from="UTF-8", to="LATIN1")
spotify_dataset$Artist <- iconv(spotify_dataset$Artist, from="UTF-8", to="LATIN1")
spotify_dataset$Streams <- as.numeric(gsub(",","",spotify_dataset$Streams))
spotify_dataset[is.na(spotify_dataset)] <- 0
evolucion_usuarios <- read_excel("datos/evolucion_usuarios.xlsx")
evolucion_ingresos <- read_excel("datos/evolucion_ingresos.xlsx")
mas_seguidores <- read_excel("datos/followers_artists_2021.xlsx")
3. La evolución de Spotify
Spotify es una aplicación que permite la reproducción de audio y video por medio del streaming, es decir, la transmisión en continuo de música o listas de música de distintos artistas alrededor del mundo.Este software multiplataforma, de origen sueco, cuenta con una versión gratuita que permite escuchar música de forma gratuita, con algunas limitaciones y publicidades. También, cuenta con otra modalidad Premium que ofrece mejor calidad de audio y otras funciones adicionales que funcionan con una suscripción de paga.
En este apartado, vamos a observar su evolución en distintos aspectos.
3.1 Evolución de los usuarios por año y trimestre
Conforme ha ido avanzando los smartphones y la tecnología,Spotify ha ido aumentando sus usuarios, ya que unicamente teniendo conexión a internet, te permite acceso ilimitado a miles de canciones.
evolucion_usuarios <- read_excel("datos/evolucion_usuarios.xlsx")
gg_usuarios <- ggplot(evolucion_usuarios, aes(x = year_trimester, y = usuarios )) +
geom_segment( aes(x=year_trimester, xend=year_trimester, y=0, yend=usuarios), size=0.5,
color="black", linetype="dotdash") +
geom_point( color="chartreuse3", size=3.5) +
theme_light() +
theme(
panel.grid.major.x = element_blank(),
panel.border = element_blank(),
axis.ticks.x = element_blank()) +
xlab("Año y trimestre ") +
ylab("Numero de Usuarios en millones")
ggplotly(gg_usuarios)
3.2 Evolución de los ingresos por año
Conforme Spotify ha ido aumentando los usuarios, también ha ido aumentando sus ingresos, ya que gran parte de estos nuevos usuarios se han unido de forma premium, lo que conlleva un pago mensual o anual a la plataforma, por ello, contra más usuarios nuevos, mayores ingresos.
evolucion_ingresos <- read_excel("datos/evolucion_ingresos.xlsx")
gg_ingresos <- ggplot(evolucion_ingresos, aes(x=year, y= ingresos)) +
geom_area() +
geom_point( size=1.5, color="chartreuse3", fill=alpha("chartreuse3", 8), shape=21, stroke=2) +
geom_line(color="chartreuse3", size=1.5) +
scale_x_continuous(
breaks = seq(2009, 2020, 1),
limits = c(2009, 2020)) + labs(x = "Año", y = "Ingresos en millones de €" ) + theme(panel.grid.major = element_line(colour = "white"),
panel.grid.minor = element_line(colour = "white"),
panel.background = element_rect(fill = "white"))
ggplotly(gg_ingresos)
3.2 Los logos de spotify a lo largo de su historia
Aunque no sea algo de vital importancia, Spotify a lo largo de los años, como cualquier marca, ha realizado modificaciones en el logo, haciendo cada vez más simples y menos recargados
logo2008 <- image_read("./imagenes/spotify-logo2008.png") %>% image_scale(., "500") %>% image_annotate(., "2008", size = 40, gravity = "southeast", color = "black")
logo2013 <- image_read("./imagenes/spotify_logo_2013.png") %>% image_scale(., "900") %>% image_annotate(., "2013", size = 80, gravity = "southeast", color = "black")
logo2015 <- image_read("./imagenes/spotify_logo_actual.png") %>% image_scale(., "500") %>% image_annotate(., "Actual", size = 40, gravity = "southeast", color = "black")
logos <- c(logo2008, logo2013, logo2015)
image_animate(image_scale(logos), fps = 0.5)
4. La música del 2021
En esta sección hablaré de lo que más se ha escuchado en el último año, los artistas más sonados, los más seguidos y las canciones más famosas.
4.1 TOP 30 Artistas del 2021
Como podemos observar, la artista más escuchada, en este 2021 ha sido la cantante estadounidense, Taylor Swift, con un total de 381480455 reproducciones.Por detrás, tenemos a la banda surcoreana de K-Pop, BTS con 238400020 reproducciones, y en tercer lugar, podemos encontrar al canadiense Justin Bieber con 225842427 reproducciones.
GRÁFICO DE BARRAS
total_streams_art <- spotify_dataset %>%
group_by(Artist) %>%
mutate(streams_totales = sum(Streams)) %>%
select(Artist, streams_totales, Genre)
total_streams_art_nodup <- total_streams_art[!duplicated(total_streams_art), ] %>%
group_by(streams_totales) %>%
arrange(desc(streams_totales)) %>%
filter(streams_totales > 46346067)
treinta_mas_escuchados <- total_streams_art_nodup[-c(4, 15, 19, 21, 23
, 25, 27, 33, 41), ]
treinta_mas_escuchados_no_dup <- treinta_mas_escuchados[-c(27, 32 ,33 ,34), ]
gg_masescuchados <- ggplot(treinta_mas_escuchados_no_dup, aes(x= Artist,
y= streams_totales, fill=Artist)) +
geom_bar(stat = "identity") +
coord_flip() +
theme(legend.position="none") + theme(panel.background = element_rect(fill = "white")) +labs(y = "Streams Totales")
ggplotly(gg_masescuchados)
GRÁFICO CIRCULAR
# Set highcharter options
options(highcharter.theme = hc_theme_smpl(tooltip = list(valueDecimals = 2)))
gg_masescuchados_circ <- treinta_mas_escuchados_no_dup %>%
hchart(
"pie", hcaes(x = Artist, y = streams_totales),
name = "Nº de reproducciones"
)
gg_masescuchados_circ
4.2 TOP 30 Artistas con más seguidores en spotify del 2021
En este gráfico de tarta, se puede ver que los artistas más seguidos, NO son los más escuchados, ya que los 3 con más fans en esta plataforma, son Ed Sheeran, Ariana Grande y Drake. Cuando Taylor Swift ha sido la más escuchada, pero la 7 más seguida, lo mismo pasa con BTS que ha pasado de ser el segundo a el décimo primero.Esto es porque el hecho de que sean más escuchados no significa que sean los más famosos, solo significa que han sacado más canciones en 2021 o mejor contenido.
mas_seguidores <- read_excel("datos/followers_artists_2021.xlsx")
# Set highcharter options
options(highcharter.theme = hc_theme_smpl(tooltip = list(valueDecimals = 2)))
gg_masseguidores <- mas_seguidores %>%
hchart(
"pie", hcaes(x = Artist, y = artist_followers),
name = "Nº de seguidores"
)
gg_masseguidores
4.3 TOP 30 canciones más sonadas en este 2021 ¨
Como podemos observar en este gráfico de caja las canciones más escuchadas en 2021 han sido, en primer lugar, Beggin’ del grupo italiano Måneskin con 48633449 reproducciones, esta canción fue la ganadora de Eurovision.En segundo lugar, esta STAY (with Justin Bieber) del rapero australiano The Kid LAROI y este tema, acumula 47248719 reproducciones en Spotify. Y en tercer lugar, la canción, good 4 u de la americana Olivia Rodrigo que tiene 40162559 reproducciones.
POR CANCIONES DENTRO DEL TOP 30
#top10 <- spotify_dataset %>% select(song_name, Artist, Streams) %>%
# filter(Streams > 14174752)
#library(treemap)
#gg_top_10 <- treemap(top10,
# index="group",
# vSize="value",
# type="index")
#gg_top10 <- treemap(top10,
#index=c("Artist","song_name"),
#vSize="Streams",
#type="index",
#vColor = "Artist",
#fontsize.labels=c(15,20),
#bg.labels=c("transparent"),
#palette = "Set1",
#align.labels=list(
# c("center", "center"),
# c("center", "bottom")),
#title = "TOP 10 2021",
#title.legend = "Artistas")
#gg_top10
inter_top10 <- d3tree2(gg_top10 , rootname = "TOP 30 Canciones más escuchadas del 2021 y sus Artistas")
inter_top10
TABLA RANKING TOP 30
knitr::kable(top10, caption = "TOP 30 2021") %>%
kableExtra::kable_styling(bootstrap_options = c("striped", "hover")) %>%
kableExtra::kable_styling(fixed_thead = list(enabled = T, background = "chartreuse"))
TOP 30 2021
song_name
|
Artist
|
Streams
|
Beggin’
|
Måneskin
|
48633449
|
STAY (with Justin Bieber)
|
The Kid LAROI
|
47248719
|
good 4 u
|
Olivia Rodrigo
|
40162559
|
Bad Habits
|
Ed Sheeran
|
37799456
|
INDUSTRY BABY (feat. Jack Harlow)
|
Lil Nas X
|
33948454
|
MONTERO (Call Me By Your Name)
|
Lil Nas X
|
30071134
|
Kiss Me More (feat. SZA)
|
Doja Cat
|
29356736
|
Intentions
|
Justin Bieber, Quavo
|
28509534
|
Todo De Ti
|
Rauw Alejandro
|
26951613
|
Yonaguni
|
Bad Bunny
|
25030128
|
I WANNA BE YOUR SLAVE
|
Måneskin
|
24551591
|
Levitating (feat. DaBaby)
|
Dua Lipa
|
23518010
|
All I Want for Christmas Is You
|
Mariah Carey
|
23235257
|
Qué Más Pues?
|
J Balvin, Maria Becerra
|
22405111
|
Permission to Dance
|
BTS
|
22062812
|
Last Christmas
|
Wham!
|
20709328
|
Peaches (feat. Daniel Caesar & Giveon)
|
Justin Bieber
|
20294457
|
Butter
|
BTS
|
19985713
|
traitor
|
Olivia Rodrigo
|
19480679
|
deja vu
|
Olivia Rodrigo
|
18571755
|
Save Your Tears (with Ariana Grande) (Remix)
|
The Weeknd
|
18053141
|
AM Remix
|
Nio Garcia, J Balvin, Bad Bunny
|
17617965
|
Need To Know
|
Doja Cat
|
16908917
|
Santa Tell Me
|
Ariana Grande
|
16657592
|
Rockin’ Around The Christmas Tree
|
Brenda Lee
|
16613649
|
Volando - Remix
|
Mora, Bad Bunny, Sech
|
16606925
|
Jingle Bell Rock
|
Bobby Helms
|
16527404
|
happiness
|
Taylor Swift
|
16213589
|
Ain’t Shit
|
Doja Cat
|
16126897
|
a p p l y i n g . p r e s s u r e
|
J. Cole
|
15967986
|
5. Reggaeton vs POP
Según varias fuentes de información, los dos generos más escuchados en la actualidad son el pop y el reggaeton.En este apartado vamos a comparar los dos generos mediante distintos aspectos, la suma de todas las reproducciones de cada género en 2021, la bailabilidad de cada género y la popularidad.
5.1 Que género ha tenido más reproducciones en 2021
Para comparar hemos sumado todas las reproducciones de las canciones de pop en 2021.En este gráfico de barras podemos ver, que el pop se ha escuchado mucho más que el reggaeton durante este año.
reggaeton <- spotify_dataset %>%
select(Artist, song_name, Streams, Genre, Popularity, Danceability, Energy) %>%
filter(stringr::str_detect(Genre, 'reggaeton') ) %>%
mutate(streams_totales = sum(Streams))
pop <- spotify_dataset %>%
select(Artist, song_name, Streams, Genre, Popularity, Danceability, Energy) %>%
filter(stringr::str_detect(Genre, 'pop') ) %>%
mutate(streams_totales = sum(Streams))
reggaeton_vs_pop <- rbind(reggaeton, pop) %>%
select(Genre, streams_totales)
reggaeton_vs_pop_solo_streams <- reggaeton_vs_pop[c(29,185), ]
gg_vs_streams <- ggplot(reggaeton_vs_pop_solo_streams, aes(x=Genre, y=streams_totales,
fill = streams_totales)) +
geom_bar(stat = "identity") +
theme(panel.background = element_rect(fill = "white")) +labs(x = "Genero", y = "Streams Totales")
ggplotly(gg_vs_streams)
5.2 Que género ha sido más bailable en 2021
Para llevar a cabo esta comparación, he realizado la media de la bailabilidad de todas las canciones de cada género, es decir, he sumado la bailabilidad de todas las canciones de pop y de reggaeton, y lo he dividido entre el nº de temas de cada uno .Y como podemos observar, las canciones de reggaeton han sido más bailables que las de pop en un 8%.
reggaeton_baila <- reggaeton %>% summarise(media_bailabilidad = mean(Danceability))
pop_baila <- pop %>% summarise(media_bailabilidad = mean(Danceability))
reggaeton_vs_pop_baila <- rbind(reggaeton_baila, pop_baila)
reggaeton_vs_pop_baila_bien <- cbind(reggaeton_vs_pop_baila, Genre=c("reggaeton","pop"))
gg_vs_baila <- ggplot(reggaeton_vs_pop_baila_bien, aes(x=Genre, y=media_bailabilidad,
fill = media_bailabilidad)) +
geom_bar(stat = "identity") + theme(panel.background = element_rect(fill = "white")) +labs(x = "Genero", y = "Media de Bailabilidad")
ggplotly(gg_vs_baila)
5.3 Que género ha sido más popular en 2021
Para realizar esta comparación, hemos sumado la popularidad de todas las canciones de cada género y lo hemos dividido entre el nº de canciones de cada uno.Tras observar el gráfico, podemos obtener una conclusión, las canciones de reggaeton son más populares que las de pop normalmente.
reggaeton_popu <- reggaeton %>% summarise(media_popularidad = mean(Popularity))
pop_popu <- pop %>% summarise(media_popularidad = mean(Popularity))
reggaeton_vs_pop_popu <- rbind(reggaeton_popu, pop_popu)
reggaeton_vs_pop_popu_bien <- cbind(reggaeton_vs_pop_popu, Genre=c("reggaeton",
"pop"))
gg_vs_popu <- ggplot(reggaeton_vs_pop_popu_bien, aes(x=Genre, y=media_popularidad,
fill = media_popularidad)) +
geom_bar(stat = "identity") +
theme(panel.background = element_rect(fill = "white")) +labs(x = "Genero", y = "Media de la Popularidad")
ggplotly(gg_vs_popu)
6. Aspectos musicales del 2021
En este apartado observaremos varias características que tienen que ver con la música, como es el tempo, los acordes, la energía y la bailabilidad
6.1 Que tempo deben tener las canciones para ser bailables?
Como podemos observar en este gráfico de dispersión, las canciones para ser bailables (danceability>= 0,75), han de tener un tempo entre 100 y 150, si tienen un tempo mayor son demasiado rápidas para ser bailadas por tanto su bailabilidad cae, y si tienen un tempo menor que 100, son demasiado lentas.
gg_1 <- ggplot(spotify_dataset) + geom_point(mapping = aes(x=Tempo, y=Danceability), colour = "chartreuse3") +
geom_smooth(mapping = aes(x=Tempo, y=Danceability), color = "black") +
labs(title="Tempo de la canción vs Bailabilidad") +
theme(panel.background = element_rect(fill = "white")) +labs(y = "Bailabilidad")
ggplotly(gg_1)
6.2 Que energia suelen tener las canciones más bailables?
Las canciones más bailables, según el gráfico de dispersion, suelen tener unas energía entre 0,60 y 0,75. Si las canciones tienen una energía menor, no incitan al movimiento y por tanto, tienen una bailabilidad muy baja
gg_2 <- ggplot(spotify_dataset) + geom_point(mapping = aes(x=Energy, y=Danceability), colour = "chartreuse3") +
geom_smooth(mapping = aes(x=Energy, y=Danceability), color = "black") +
labs(title="Energía de la canción vs Bailabilidad") +
theme(panel.background = element_rect(fill = "white")) +labs(x = "Energía de la Canción", y = "Bailabilidad")
ggplotly(gg_2)
6.3 Las canciones más populares son las más bailables?
La respuesta a esta pregunta es si, ya que como podemos ver, las canciones con una popularidad por encima de 75, que esto significa que son canciones populares a nivel mundial y que han estado en los tops varias veces, tienen una bailabilidad por encima de 0,65, es decir, que si son populares son bastante bailables, ya que estos significa que su ritmo, su letra y su melodia son más pegadizas.
gg_3 <- ggplot(spotify_dataset) + geom_point(mapping = aes(x=Danceability, y=Popularity), colour = "chartreuse3") +
geom_smooth(mapping = aes(x=Danceability, y=Popularity), color = "black") +
labs(title="Popularidad vs Bailabilidad") +
theme(panel.background = element_rect(fill = "white")) +labs(x = "Bailabilidad", y = "Popularidad")
ggplotly(gg_3)
6.4 Que acorde usan las canciones más populares?
En este gráfico de barras se puede observar que, las canciones con mayor popularidad son las que utilizan el acorde C#/Db, y las que menos populares son las que utilizan el acorde D#/Eb.
gg_4 <- ggplot(spotify_dataset, aes(x=Chord, y=Popularity)) +
geom_bar(stat = "identity", color ="black" ,fill = "chartreuse3") +
theme(panel.background = element_rect(fill = "white")) +labs(title = "Popularidad vs Acorde", x = "Acorde",
y = "Popularidad")
gg_4
7. Reggaeton en el 2021
En los ultimos años, este género musical ha ido aumentando su popularidad a niveles estratosféricos, ha pasado de ser solo escuchado en paises latinos, ha ser uno de los más famosos a nivel mundial.Este año, los 3 artistas de reggaeton más importantes han sido Bad Bunny, Rauw Alejandro y J Balvin.
bb_ra_j <- spotify_dataset %>%
select(Artist, Streams, artist_followers, song_name, `Number of Times Charted`) %>%
filter(Artist %in% c("Bad Bunny", "Rauw Alejandro","J Balvin"))
total_streams_bb_ra_j <- treinta_mas_escuchados[c(5,31,32), ] %>%
select(Artist, streams_totales)
comparacion_reggaeton <- full_join(bb_ra_j,total_streams_bb_ra_j, c("Artist" = "Artist")) %>%
select(Artist,streams_totales,artist_followers)
comparacion_reggaeton_3 <- comparacion_reggaeton[c(1,2,7), ]
comparacion_reggaeton_edad <- cbind(comparacion_reggaeton_3, Edad=c("27","28", "36"))
fotos_reggaeton_artistas <- c("./imagenes/bad_bunny.png", "./imagenes/rauw_alejandro.png","./imagenes/j_balvin.png")
fotos_pr_col <- c("./imagenes/Puerto_Rico.png","./imagenes/Puerto_Rico.png", "./imagenes/Colombia.png")
comparacion_reggaeton_bien <- comparacion_reggaeton_edad %>% add_column(fotos_reggaeton_artistas, fotos_pr_col)
library(gt)
reggaeton_tabla <- comparacion_reggaeton_bien %>% gt() %>%
text_transform( locations = cells_body(columns = c(fotos_reggaeton_artistas)), fn = function(x) {gt::local_image(x, height = 80)}) %>%
text_transform( locations = cells_body(columns = c(fotos_pr_col)), fn = function(x) {gt::local_image(x, height = 80)}) %>% tab_header(title = md("**TOP ARTISTAS REGGAETON 2021**"), subtitle = md("Comparación")) %>% cols_label(
Artist = html("Artista"),
streams_totales = html("Total Reproducciones"),
artist_followers = html("Seguidores Spotify"),
fotos_reggaeton_artistas = html(""),
fotos_pr_col = html("")) %>%
tab_options(table.background.color = "white", table.font.color.light = "chartreuse") %>%
cols_align(align = "center",
columns = everything())
reggaeton_tabla
Artista |
Total Reproducciones |
Seguidores Spotify |
Edad |
|
|
Rauw Alejandro |
52301649 |
6080597 |
27 |
|
|
Bad Bunny |
203813133 |
36142273 |
28 |
|
|
J Balvin |
50589690 |
29067437 |
36 |
|
|
LS0tDQp0aXRsZTogIkxBIEJBTkRBIFNPTk9SQSBERUwgMjAyMSINCnN1YnRpdGxlOiAiQ2FybG9zIEdhcmPDrWEgQ2FzdGlsbGEoZ2FyY2FzOEBhbHVtbmkudXYuZXMpIiAjLSBwb25nbyB0w7ogbm9tYnJlIGFow60gcGFyYSBxIGFwYXJlemNhIG3DoXMgZ3JhbmRlIHEgZWwgZGUgbGEgVVYNCmF1dGhvcjogIlVuaXZlcnNpdGF0IGRlIFZhbMOobmNpYSINCmRhdGU6ICJEaWNpZW1icmUgZGUgMjAyMSAoYWN0dWFsaXphZG8gZWwgYHIgZm9ybWF0KFN5cy50aW1lKCksICclZC0lbS0lWScpYCkiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6DQogICAgY3NzOiAiLi9hc3NldHMvbXlfY3NzX2ZpbGUuY3NzIg0KICAgIHRoZW1lOiBwYXBlcg0KICAgIGhpZ2hsaWdodDogdGV4dG1hdGUgDQogICAgdG9jOiB0cnVlDQogICAgdG9jX2RlcHRoOiAzIA0KICAgIHRvY19mbG9hdDogDQogICAgICBjb2xsYXBzZWQ6IHRydWUNCiAgICAgIHNtb290aF9zY3JvbGw6IHRydWUNCiAgICBzZWxmX2NvbnRhaW5lZDogdHJ1ZQ0KICAgIG51bWJlcl9zZWN0aW9uczogZmFsc2UNCiAgICBkZl9wcmludDoga2FibGUNCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlDQogICAgY29kZV9mb2xkaW5nOiBoaWRlDQplZGl0b3Jfb3B0aW9uczogDQogIGNodW5rX291dHB1dF90eXBlOiBjb25zb2xlDQotLS0NCg0KYGBge3IgcGFja2FnZXMtc2V0dXAsIGluY2x1ZGUgPSBGQUxTRX0NCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShrbGlwcHkpICAjLSByZW1vdGVzOjppbnN0YWxsX2dpdGh1Yigicmxlc3VyL2tsaXBweSIpDQpsaWJyYXJ5KGtuaXRyKQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KHJpbykNCmxpYnJhcnkoa2xpcHB5KQ0KbGlicmFyeShrbml0cikNCmxpYnJhcnkocmVhZHIpDQpsaWJyYXJ5KGhlcmUpDQpsaWJyYXJ5KGphbml0b3IpDQpsaWJyYXJ5KHNraW1yKQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkocmVhZHhsKQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShnYXBtaW5kZXIpDQpsaWJyYXJ5KHBsb3RseSkNCmxpYnJhcnkod29yZGNsb3VkMikNCmxpYnJhcnkoaGlnaGNoYXJ0ZXIpDQpsaWJyYXJ5KGQzdHJlZVIpDQpsaWJyYXJ5KG1hZ2ljaykNCmxpYnJhcnkoZ3QpDQpsaWJyYXJ5KGthYmxlRXh0cmEpDQpgYGANCg0KYGBge3IgY2h1bmstc2V0dXAsIGluY2x1ZGUgPSBGQUxTRX0NCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSwgZXZhbCA9IFRSVUUsIG1lc3NhZ2UgPSBGQUxTRSwgd2FybmluZyA9IEZBTFNFLCANCiAgICAgICAgICAgICAgICAgICAgICAjcmVzdWx0cyA9ICJob2xkIiwNCiAgICAgICAgICAgICAgICAgICAgICBjYWNoZSA9IEZBTFNFLCBjYWNoZS5wYXRoID0gIi9jYWNoZXMvIiwgY29tbWVudCA9ICIjPiIsDQogICAgICAgICAgICAgICAgICAgICAgI2ZpZy53aWR0aCA9IDcsICNmaWcuaGVpZ2h0PSA3LCAgIA0KICAgICAgICAgICAgICAgICAgICAgICNvdXQud2lkdGggPSA3LCBvdXQuaGVpZ2h0ID0gNywNCiAgICAgICAgICAgICAgICAgICAgICBjb2xsYXBzZSA9IFRSVUUsICBmaWcuc2hvdyA9ICJob2xkIiwNCiAgICAgICAgICAgICAgICAgICAgICBmaWcuYXNwID0gMC42MjgsIG91dC53aWR0aCA9ICI3NSUiLCBmaWcuYWxpZ24gPSAiY2VudGVyIikNCmtuaXRyOjpvcHRzX2NodW5rJHNldChkZXYgPSAicG5nIiwgZGV2LmFyZ3MgPSBsaXN0KHR5cGUgPSAiY2Fpcm8tcG5nIikpDQpgYGANCg0KDQpgYGB7ciBvcHRpb25zLXNldHVwLCBpbmNsdWRlID0gRkFMU0V9DQpvcHRpb25zKHNjaXBlbiA9IDk5OSkgIy0gcGFyYSBxdWl0YXIgbGEgbm90YWNpw7NuIGNpZW50w61maWNhDQpvcHRpb25zKCJ5YW1sLmV2YWwuZXhwciIgPSBUUlVFKSANCmBgYA0KDQoNCmBgYHtyIGtsaXBweSwgZWNobyA9IEZBTFNFfQ0Ka2xpcHB5OjprbGlwcHkocG9zaXRpb24gPSBjKCJ0b3AiLCAicmlnaHQiKSkgIy0gcmVtb3Rlczo6aW5zdGFsbF9naXRodWIoInJsZXN1ci9rbGlwcHkiKQ0KYGBgDQoNCjxkaXYgc3R5bGU9InRleHQtYWxpZ246IGp1c3RpZnkiPjxkaXYvPg0KDQo8aHIgY2xhc3M9ImxpbmVhLWJsYWNrIj4NCg0KPCEtLSBFbCBww6FycmFmbyBkZSBhYmFqbyBoYXMgZGUgZGVqYXJsbyBjYXNpIGlndWFsLCBzb2xvIEhBUyBkZSBTVVNUSVRVSVIgInBlcmV6cDQ0IiBwb3IgdHUgdXN1YXJpbyBkZSBHaXRodWItLT4NClRyYWJham8gZWxhYm9yYWRvIHBhcmEgbGEgYXNpZ25hdHVyYSAiUHJvZ3JhbWFjacOzbiB5IG1hbmVqbyBkZSBkYXRvcyBlbiBsYSBlcmEgZGVsIEJpZyBEYXRhIiBkZSBsYSBVbml2ZXJzaXRhdCBkZSBWYWzDqG5jaWEgZHVyYW50ZSBlbCBjdXJzbyAyMDIxLTIwMjIuIEVsIHJlcG8gZGVsIHRyYWJham8gZXN0w6EgW2FxdcOtXShodHRwczovL2dpdGh1Yi5jb20vZ2FyY2FzOC90cmFiYWpvX0JpZ0RhdGEpe3RhcmdldD0iX2JsYW5rIn0uIA0KDQo8IS0tIEVsIHDDoXJyYWZvIGRlIGFiYWpvIGhhcyBkZSBkZWphcmxvIGV4YWN0YW1lbnRlIGlndWFsLCBOTyBIQVMgREUgQ0FNQklBUiBOQURBLS0+DQoNCkxhIHDDoWdpbmEgd2ViIGRlIGxhIGFzaWduYXR1cmEgeSBsb3MgdHJhYmFqb3MgZGUgbWlzIGNvbXBhw7Flcm9zIHB1ZWRlbiB2ZXJzZSBbYXF1w61dKGh0dHBzOi8vcGVyZXpwNDQuZ2l0aHViLmlvL2ludHJvLWRzLTIxLTIyLXdlYi8wNy10cmFiYWpvcy5odG1sKXt0YXJnZXQ9Il9ibGFuayJ9Lg0KDQoNCjxociBjbGFzcz0ibGluZWEtcmVkIj4NCg0KIyBbMS4gSW50cm9kdWNjacOzbl17LnZlcmRlY2l0b30NCg0KKipTcG90aWZ5KiogZXMgZWwgKipzZXJ2aWNpbyBkaWdpdGFsKiogZGUgbcO6c2ljYSwgcG9kY2FzdHMgeSB2w61kZW9zLCBtw6FzIHV0aWxpemFkbyBhY3R1YWxtZW50ZSBhIG5pdmVsIG11bmRpYWwuRW4gZXN0YSBhcGxpY2FjacOzbiBwb2RyYXMgZW5jb250cmFyIG1pbGxvbmVzIGRlIGNhbmNpb25lcyBwYXJhIHRvZG9zIGxvcyBndXN0b3MsIGFsIGlndWFsIHF1ZSBwb2RjYXN0cywgeWEgcXVlIGhheSBkZSB0b2RvIHRpcG8sIGRlIHBvbMOtdGljYSwgZGUgZWNvbm9tw61hIGRlIGRlcG9ydGVzLCBldGMuIEVuIGVzdGUgdHJhYmFqbywgdmFtb3MgYSB0cmF0YXIgdmFyaW9zIHRlbWFzIHNvYnJlIGVzdGEgYXBsaWNhY2nDs24sIGVuIHByaW1lciBsdWdhciwgaGFyZW1vcyB1biByZXBhc28gc29icmUgbGEgZXZvbHVjacOzbiBkZSBTcG90aWZ5IGEgbG8gbGFyZ28gZGUgbG9zIGHDsW9zLCBkZXNwdcOpcyBub3MgYWRlbnRyYXJlbW9zIG3DoXMgZW4gbG8gcXVlIG3DoXMgc2UgaGEgZXNjdWNoYWRvIGVuIDIwMjEgeSBjb21wYXJhY2lvbmVzIGVudHJlIGxvcyBkaXN0aW50b3MgZ2VuZXJvcywgeSBwb3Igw7psdGltbywgbm9zIHJlZmVyaXJlbW9zIG3DoXMgYSBhc3BlY3RvcyBtdXNpY2FsZXMgZGUgbGFzIGNhbmNpb25lcywgY29tbyBsYSBiYWlsYWJpbGlkYWQsIGxhIHBvcHVsYXJpZGFkLCBsb3MgYWNvcmRlcy4uLg0KQWwgZmluYWwgZGUgYcOxbywgU3BvdGlmeSwgbXVlc3RyYSBhIHN1cyB1c3VhcmlvcyB1biByZXN1bWVuIGRlIGxvIHF1ZSBtYXMgaGEgZXNjdWNoYWRvIGR1cmFudGUgZXNlIGHDsW8sZGUgdW5hIGZvcm1hIGludGVyYWN0aXZhIHkgZGl2ZXJ0aWRhLCB5IGRlIGFxdWkgZXMgZGUgZG9uZGUgbWUgc3VyZ2nDsyBsYSBpZGVhIGRlIHJlYWxpemFyIGVsIHRyYWJham8gc29icmUgZXN0YSBwbGF0YWZvcm1hLCBhIGNvbnRpbnVhY2nDs24gcG9kZWlzIG9ic2VydmFyIGN1YWwgaGEgc2lkbyBtaSByZXN1bWVuIGRlIDIwMjENCg0KPGNlbnRlcj4NCg0KIVtXcmFwcGVkXSguL2ltYWdlbmVzL3dyYXBwZWQuanBlZyl7d2lkdGg9MzAwIGhlaWdodD01MDB9DQoNCjwvY2VudGVyPg0KDQoNCg0KDQojIDIuIERhdG9zDQoNCkxvcyBkYXRvcyBxdWUgaGUgdXRpbGl6YWRvIGVuIGVzdGUgdHJhYmFqbywgaGFuIHNpZG8gZXh0cmFpZG9zIGRlIFtrYWdnbGVdKGh0dHBzOi8vd3d3LmthZ2dsZS5jb20vKSBlbiBlc3RhIHdlYiBoZSBvYnRlbmlkbyBsb3MgZGF0b3Mgc29icmUgbGFzIGNhbmNpb25lcyBtw6FzIGVzY3VoYWRhcyBlc3RlIDIwMjEsIGRlIGxhIHByb3BpYSB3ZWIgZGUgW1Nwb3RpZnldKGh0dHBzOi8vd3d3LnNwb3RpZnkuY29tL2VzLykgYXF1w60gaGUgZXh0cmFpZG8gbGEgaW5mb3JtYWNpw7NuIHNvYnJlIGxvcyBzZWd1aWRvcmVzIGRlIGxvcyBhcnRpc3RhcyB5IGRlIFtTdGF0aXN0YV0oaHR0cHM6Ly93d3cuc3RhdGlzdGEuY29tL3RvcGljcy8yMDc1L3Nwb3RpZnkvI2Rvc3NpZXJLZXlmaWd1cmVzKSBkZSBlc3RhIHdlYiBoZSBzYWNhZG8gbG9zIGRhdG9zIHNvYnJlIGxhIGV2b2x1Y2nDs24gZGUgbG9zIGluZ3Jlc29zIHkgZGUgbG9zIG95ZW50ZXMuDQoNCg0KIyMgMi4xLiBQcm9jZXNhbmRvIGxvcyBkYXRvcw0KDQpFbiBlc3RlIGFwYXJ0YWRvIHZveSBhIG1vc3RyYXIgY29tbyBoZSBtYW5pcHVsYWRvIGxvcyA0IGRhdGFmcmFtZXMsIHkgcXVlIGFjY2lvbmVzIGhlIHJlYWxpemFkbyBlbiBjYWRhIHVubyBkZSBlbGxvcyBwYXJhIGVsaW1pbmFyIGZhbGxvcyB5IGRlamFybG9zIG3DoXMgb3JnYW5pemFkb3MgeSBjb24gbGEgaW5mb3JtYWNpw7NuIHF1ZSBtZSBpbnRlcmVzYS5FbCBkZiBwcmluY2lwYWwgZXMgZWwgbGxhbWFkbyAqKnNwb3RpZnlfZGF0YXNldCoqIHlhIHF1ZSBlc3RlIGhhIHNpZG8gZWwgcXVlIG1hcyBoZSBtYW5pcHVsYWRvLCBlbCBxdWUgbWFzIGhlIHV0aWxpemFkbyB5IGVsIHF1ZSBtw6FzIGluIGZvcm1hY2nDs24gdGllbmUuTG9zIG90cm9zIDMgZGYsICoqZXZvbHVjaW9uX3VzdWFyaW9zLCBldm9sdWNpb25faW5ncmVzb3MsIG1hc19zZWd1aWRvcmVzKiBoYW4gc2lkbyBtw6FzIGNvbXBsZW1lbnRhcmlvcywgeWEgcXVlIHNvbG8gbWUgaGFuIHNlcnZpZG8gcGFyYSBoYWNlciAyLTMgZ3LDoWZpY29zLg0KDQpgYGB7ciwgZXZhbCA9IFRSVUUsIGVjaG8gPSBUUlVFfQ0KI2NhbWJpbyBlc3RvcyBub21icmVzIGFxdWkgZGViYWpvIHBxIHNpIG5vIGRhIGVycm9yIGx1ZWdvDQoNCnNwb3RpZnlfZGF0YXNldCA8LSByaW86OmltcG9ydChmaWxlID0gIi4vZGF0b3Mvc3BvdGlmeV9kYXRhc2V0LmNzdiIpDQoNCm5hbWVzKHNwb3RpZnlfZGF0YXNldClbbmFtZXMoc3BvdGlmeV9kYXRhc2V0KSA9PSAnQXJ0aXN0IEZvbGxvd2VycyddIDwtICdhcnRpc3RfZm9sbG93ZXJzJw0KbmFtZXMoc3BvdGlmeV9kYXRhc2V0KVtuYW1lcyhzcG90aWZ5X2RhdGFzZXQpID09ICdTb25nIE5hbWUnXSA8LSAnc29uZ19uYW1lJw0KDQpzcG90aWZ5X2RhdGFzZXQkc29uZ19uYW1lIDwtIGljb252KHNwb3RpZnlfZGF0YXNldCRzb25nX25hbWUsIGZyb209IlVURi04IiwgdG89IkxBVElOMSIpDQpzcG90aWZ5X2RhdGFzZXQkQXJ0aXN0IDwtIGljb252KHNwb3RpZnlfZGF0YXNldCRBcnRpc3QsIGZyb209IlVURi04IiwgdG89IkxBVElOMSIpDQoNCnNwb3RpZnlfZGF0YXNldCRTdHJlYW1zIDwtIGFzLm51bWVyaWMoZ3N1YigiLCIsIiIsc3BvdGlmeV9kYXRhc2V0JFN0cmVhbXMpKQ0KDQoNCnNwb3RpZnlfZGF0YXNldFtpcy5uYShzcG90aWZ5X2RhdGFzZXQpXSA8LSAwDQoNCg0KDQpldm9sdWNpb25fdXN1YXJpb3MgPC0gcmVhZF9leGNlbCgiZGF0b3MvZXZvbHVjaW9uX3VzdWFyaW9zLnhsc3giKQ0KDQpldm9sdWNpb25faW5ncmVzb3MgPC0gcmVhZF9leGNlbCgiZGF0b3MvZXZvbHVjaW9uX2luZ3Jlc29zLnhsc3giKQ0KDQptYXNfc2VndWlkb3JlcyA8LSByZWFkX2V4Y2VsKCJkYXRvcy9mb2xsb3dlcnNfYXJ0aXN0c18yMDIxLnhsc3giKSANCmBgYA0KDQojIDMuIExhIGV2b2x1Y2nDs24gZGUgU3BvdGlmeQ0KDQoqKlNwb3RpZnkqKiBlcyB1bmEgYXBsaWNhY2nDs24gcXVlIHBlcm1pdGUgbGEgcmVwcm9kdWNjacOzbiBkZSBhdWRpbyB5IHZpZGVvIHBvciBtZWRpbyBkZWwgc3RyZWFtaW5nLCBlcyBkZWNpciwgbGEgdHJhbnNtaXNpw7NuIGVuIGNvbnRpbnVvIGRlIG3DunNpY2EgbyBsaXN0YXMgZGUgbcO6c2ljYSBkZSBkaXN0aW50b3MgYXJ0aXN0YXMgYWxyZWRlZG9yIGRlbCBtdW5kby5Fc3RlIHNvZnR3YXJlIG11bHRpcGxhdGFmb3JtYSwgZGUgb3JpZ2VuIHN1ZWNvLCBjdWVudGEgY29uIHVuYSB2ZXJzacOzbiBncmF0dWl0YSBxdWUgcGVybWl0ZSBlc2N1Y2hhciBtw7pzaWNhIGRlIGZvcm1hIGdyYXR1aXRhLCBjb24gYWxndW5hcyBsaW1pdGFjaW9uZXMgeSBwdWJsaWNpZGFkZXMuIFRhbWJpw6luLCBjdWVudGEgY29uIG90cmEgbW9kYWxpZGFkIFByZW1pdW0gcXVlIG9mcmVjZSBtZWpvciBjYWxpZGFkIGRlIGF1ZGlvIHkgb3RyYXMgZnVuY2lvbmVzIGFkaWNpb25hbGVzIHF1ZSBmdW5jaW9uYW4gY29uIHVuYSBzdXNjcmlwY2nDs24gZGUgcGFnYS4NCg0KRW4gZXN0ZSBhcGFydGFkbywgdmFtb3MgYSBvYnNlcnZhciBzdSBldm9sdWNpw7NuIGVuIGRpc3RpbnRvcyBhc3BlY3Rvcy4NCg0KDQojIyAzLjEgRXZvbHVjacOzbiBkZSBsb3MgdXN1YXJpb3MgcG9yIGHDsW8geSB0cmltZXN0cmUNCg0KQ29uZm9ybWUgaGEgaWRvIGF2YW56YW5kbyBsb3Mgc21hcnRwaG9uZXMgeSBsYSB0ZWNub2xvZ8OtYSwqKlNwb3RpZnkqKiBoYSBpZG8gYXVtZW50YW5kbyBzdXMgdXN1YXJpb3MsIHlhIHF1ZSB1bmljYW1lbnRlIHRlbmllbmRvIGNvbmV4acOzbiBhIGludGVybmV0LCB0ZSBwZXJtaXRlIGFjY2VzbyBpbGltaXRhZG8gYSBtaWxlcyBkZSBjYW5jaW9uZXMuDQoNCmBgYHtyLCBldmFsID0gVFJVRSwgZWNobyA9IFRSVUV9DQoNCmV2b2x1Y2lvbl91c3VhcmlvcyA8LSByZWFkX2V4Y2VsKCJkYXRvcy9ldm9sdWNpb25fdXN1YXJpb3MueGxzeCIpDQoNCmdnX3VzdWFyaW9zIDwtIGdncGxvdChldm9sdWNpb25fdXN1YXJpb3MsIGFlcyh4ID0geWVhcl90cmltZXN0ZXIsIHkgPSB1c3VhcmlvcyApKSArDQogIGdlb21fc2VnbWVudCggYWVzKHg9eWVhcl90cmltZXN0ZXIsIHhlbmQ9eWVhcl90cmltZXN0ZXIsIHk9MCwgeWVuZD11c3VhcmlvcyksIHNpemU9MC41LCANCiAgICAgICAgICAgICAgICBjb2xvcj0iYmxhY2siLCBsaW5ldHlwZT0iZG90ZGFzaCIpICsNCiAgZ2VvbV9wb2ludCggY29sb3I9ImNoYXJ0cmV1c2UzIiwgc2l6ZT0zLjUpICsNCiAgdGhlbWVfbGlnaHQoKSArDQogIHRoZW1lKA0KICAgIHBhbmVsLmdyaWQubWFqb3IueCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBwYW5lbC5ib3JkZXIgPSBlbGVtZW50X2JsYW5rKCksDQogICAgYXhpcy50aWNrcy54ID0gZWxlbWVudF9ibGFuaygpKSArDQogIHhsYWIoIkHDsW8geSB0cmltZXN0cmUgIikgKw0KICB5bGFiKCJOdW1lcm8gZGUgVXN1YXJpb3MgZW4gbWlsbG9uZXMiKQ0KICANCg0KZ2dwbG90bHkoZ2dfdXN1YXJpb3MpICAgDQoNCg0KDQoNCmBgYA0KDQojIyAzLjIgRXZvbHVjacOzbiBkZSBsb3MgaW5ncmVzb3MgcG9yIGHDsW8gDQoNCkNvbmZvcm1lICoqU3BvdGlmeSoqIGhhIGlkbyBhdW1lbnRhbmRvIGxvcyB1c3VhcmlvcywgdGFtYmnDqW4gaGEgaWRvIGF1bWVudGFuZG8gc3VzIGluZ3Jlc29zLCB5YSBxdWUgZ3JhbiBwYXJ0ZSBkZSBlc3RvcyBudWV2b3MgdXN1YXJpb3Mgc2UgaGFuIHVuaWRvIGRlIGZvcm1hIHByZW1pdW0sIGxvIHF1ZSBjb25sbGV2YSB1biBwYWdvIG1lbnN1YWwgbyBhbnVhbCBhIGxhIHBsYXRhZm9ybWEsIHBvciBlbGxvLCBjb250cmEgbcOhcyB1c3VhcmlvcyBudWV2b3MsIG1heW9yZXMgaW5ncmVzb3MuDQoNCg0KYGBge3IsIGV2YWwgPSBUUlVFLCBlY2hvID0gVFJVRX0NCg0KDQpldm9sdWNpb25faW5ncmVzb3MgPC0gcmVhZF9leGNlbCgiZGF0b3MvZXZvbHVjaW9uX2luZ3Jlc29zLnhsc3giKQ0KDQoNCmdnX2luZ3Jlc29zIDwtIGdncGxvdChldm9sdWNpb25faW5ncmVzb3MsIGFlcyh4PXllYXIsIHk9IGluZ3Jlc29zKSkgKw0KICBnZW9tX2FyZWEoKSArDQogIGdlb21fcG9pbnQoIHNpemU9MS41LCBjb2xvcj0iY2hhcnRyZXVzZTMiLCBmaWxsPWFscGhhKCJjaGFydHJldXNlMyIsIDgpLCBzaGFwZT0yMSwgc3Ryb2tlPTIpICsgIA0KICBnZW9tX2xpbmUoY29sb3I9ImNoYXJ0cmV1c2UzIiwgc2l6ZT0xLjUpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKA0KICAgIGJyZWFrcyA9IHNlcSgyMDA5LCAyMDIwLCAxKSwNCiAgICBsaW1pdHMgPSBjKDIwMDksIDIwMjApKSArIGxhYnMoeCA9ICJBw7FvIiwgeSA9ICJJbmdyZXNvcyBlbiBtaWxsb25lcyBkZSDigqwiICkgKyB0aGVtZShwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGNvbG91ciA9ICJ3aGl0ZSIpLA0KICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUoY29sb3VyID0gIndoaXRlIiksDQogICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gIndoaXRlIikpDQoNCg0KZ2dwbG90bHkoZ2dfaW5ncmVzb3MpDQoNCmBgYA0KDQoNCg0KIyMgMy4yIExvcyBsb2dvcyBkZSBzcG90aWZ5IGEgbG8gbGFyZ28gZGUgc3UgaGlzdG9yaWENCg0KQXVucXVlIG5vIHNlYSBhbGdvIGRlIHZpdGFsIGltcG9ydGFuY2lhLCAqKlNwb3RpZnkqKiBhIGxvIGxhcmdvIGRlIGxvcyBhw7FvcywgY29tbyBjdWFscXVpZXIgbWFyY2EsIGhhIHJlYWxpemFkbyBtb2RpZmljYWNpb25lcyBlbiBlbCBsb2dvLCBoYWNpZW5kbyBjYWRhIHZleiBtw6FzIHNpbXBsZXMgeSBtZW5vcyByZWNhcmdhZG9zDQoNCg0KYGBge3J9DQoNCmxvZ28yMDA4IDwtIGltYWdlX3JlYWQoIi4vaW1hZ2VuZXMvc3BvdGlmeS1sb2dvMjAwOC5wbmciKSAlPiUgaW1hZ2Vfc2NhbGUoLiwgIjUwMCIpICU+JSAgaW1hZ2VfYW5ub3RhdGUoLiwgIjIwMDgiLCBzaXplID0gNDAsIGdyYXZpdHkgPSAic291dGhlYXN0IiwgY29sb3IgPSAiYmxhY2siKQ0KDQpsb2dvMjAxMyA8LSBpbWFnZV9yZWFkKCIuL2ltYWdlbmVzL3Nwb3RpZnlfbG9nb18yMDEzLnBuZyIpICU+JSBpbWFnZV9zY2FsZSguLCAiOTAwIikgJT4lICBpbWFnZV9hbm5vdGF0ZSguLCAiMjAxMyIsIHNpemUgPSA4MCwgZ3Jhdml0eSA9ICJzb3V0aGVhc3QiLCBjb2xvciA9ICJibGFjayIpDQoNCmxvZ28yMDE1IDwtIGltYWdlX3JlYWQoIi4vaW1hZ2VuZXMvc3BvdGlmeV9sb2dvX2FjdHVhbC5wbmciKSAlPiUgaW1hZ2Vfc2NhbGUoLiwgIjUwMCIpICU+JSAgaW1hZ2VfYW5ub3RhdGUoLiwgIkFjdHVhbCIsIHNpemUgPSA0MCwgZ3Jhdml0eSA9ICJzb3V0aGVhc3QiLCBjb2xvciA9ICJibGFjayIpDQoNCmxvZ29zIDwtIGMobG9nbzIwMDgsIGxvZ28yMDEzLCBsb2dvMjAxNSkNCg0KaW1hZ2VfYW5pbWF0ZShpbWFnZV9zY2FsZShsb2dvcyksIGZwcyA9IDAuNSkNCmBgYA0KDQojIDQuIExhIG3DunNpY2EgZGVsIDIwMjENCg0KRW4gZXN0YSBzZWNjacOzbiBoYWJsYXLDqSBkZSBsbyBxdWUgbcOhcyBzZSBoYSBlc2N1Y2hhZG8gZW4gZWwgw7psdGltbyBhw7FvLCBsb3MgYXJ0aXN0YXMgbcOhcyBzb25hZG9zLCBsb3MgbcOhcyBzZWd1aWRvcyB5IGxhcyBjYW5jaW9uZXMgbcOhcyBmYW1vc2FzLg0KDQoNCiMjIDQuMSBUT1AgMzAgQXJ0aXN0YXMgZGVsIDIwMjEgey50YWJzZXR9DQoNCkNvbW8gcG9kZW1vcyBvYnNlcnZhciwgbGEgYXJ0aXN0YSBtw6FzIGVzY3VjaGFkYSwgZW4gZXN0ZSAyMDIxIGhhIHNpZG8gbGEgY2FudGFudGUgZXN0YWRvdW5pZGVuc2UsICoqVGF5bG9yIFN3aWZ0KiosIGNvbiB1biB0b3RhbCBkZSAzODE0ODA0NTUgcmVwcm9kdWNjaW9uZXMuUG9yIGRldHLDoXMsIHRlbmVtb3MgYSBsYSBiYW5kYSBzdXJjb3JlYW5hIGRlIEstUG9wLCAqKkJUUyoqIGNvbiAyMzg0MDAwMjAgcmVwcm9kdWNjaW9uZXMsIHkgZW4gdGVyY2VyIGx1Z2FyLCBwb2RlbW9zIGVuY29udHJhciBhbCBjYW5hZGllbnNlICoqSnVzdGluIEJpZWJlcioqIGNvbiAyMjU4NDI0MjcgcmVwcm9kdWNjaW9uZXMuDQoNCiMjIyBHUsOBRklDTyBERSBCQVJSQVMNCg0KYGBge3IsIGV2YWwgPSBUUlVFLCBlY2hvID0gVFJVRX0NCg0KdG90YWxfc3RyZWFtc19hcnQgPC0gc3BvdGlmeV9kYXRhc2V0ICU+JSANCiAgZ3JvdXBfYnkoQXJ0aXN0KSAlPiUgDQogIG11dGF0ZShzdHJlYW1zX3RvdGFsZXMgPSBzdW0oU3RyZWFtcykpICU+JSANCiAgc2VsZWN0KEFydGlzdCwgc3RyZWFtc190b3RhbGVzLCBHZW5yZSkNCg0KdG90YWxfc3RyZWFtc19hcnRfbm9kdXAgPC0gdG90YWxfc3RyZWFtc19hcnRbIWR1cGxpY2F0ZWQodG90YWxfc3RyZWFtc19hcnQpLCBdICU+JSANCiAgZ3JvdXBfYnkoc3RyZWFtc190b3RhbGVzKSAlPiUgDQogIGFycmFuZ2UoZGVzYyhzdHJlYW1zX3RvdGFsZXMpKSAlPiUgDQogIGZpbHRlcihzdHJlYW1zX3RvdGFsZXMgPiA0NjM0NjA2NykNCg0KDQp0cmVpbnRhX21hc19lc2N1Y2hhZG9zIDwtIHRvdGFsX3N0cmVhbXNfYXJ0X25vZHVwWy1jKDQsIDE1LCAxOSwgMjEsIDIzDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICwgMjUsIDI3LCAzMywgNDEpLCBdDQoNCnRyZWludGFfbWFzX2VzY3VjaGFkb3Nfbm9fZHVwIDwtIHRyZWludGFfbWFzX2VzY3VjaGFkb3NbLWMoMjcsIDMyICwzMyAsMzQpLCBdDQoNCg0KZ2dfbWFzZXNjdWNoYWRvcyA8LSBnZ3Bsb3QodHJlaW50YV9tYXNfZXNjdWNoYWRvc19ub19kdXAsIGFlcyh4PSBBcnRpc3QsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5PSBzdHJlYW1zX3RvdGFsZXMsIGZpbGw9QXJ0aXN0KSkgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IikgKw0KICBjb29yZF9mbGlwKCkgKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSArIHRoZW1lKHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJ3aGl0ZSIpKSArbGFicyh5ID0gIlN0cmVhbXMgVG90YWxlcyIpDQogIA0KZ2dwbG90bHkoZ2dfbWFzZXNjdWNoYWRvcykNCg0KDQoNCg0KDQoNCmBgYA0KDQojIyMgR1LDgUZJQ08gQ0lSQ1VMQVINCg0KYGBge3IsIGV2YWwgPSBUUlVFLCBlY2hvID0gVFJVRX0NCg0KDQojIFNldCBoaWdoY2hhcnRlciBvcHRpb25zDQpvcHRpb25zKGhpZ2hjaGFydGVyLnRoZW1lID0gaGNfdGhlbWVfc21wbCh0b29sdGlwID0gbGlzdCh2YWx1ZURlY2ltYWxzID0gMikpKQ0KDQpnZ19tYXNlc2N1Y2hhZG9zX2NpcmMgPC0gdHJlaW50YV9tYXNfZXNjdWNoYWRvc19ub19kdXAgJT4lDQogIGhjaGFydCgNCiAgICAicGllIiwgaGNhZXMoeCA9IEFydGlzdCwgeSA9IHN0cmVhbXNfdG90YWxlcyksDQogICAgbmFtZSA9ICJOwrogZGUgcmVwcm9kdWNjaW9uZXMiDQogICkNCg0KZ2dfbWFzZXNjdWNoYWRvc19jaXJjDQoNCg0KDQoNCmBgYA0KDQoNCg0KDQoNCg0KIyMgNC4yIFRPUCAzMCBBcnRpc3RhcyBjb24gbcOhcyBzZWd1aWRvcmVzIGVuIHNwb3RpZnkgZGVsIDIwMjENCg0KRW4gZXN0ZSBncsOhZmljbyBkZSB0YXJ0YSwgc2UgcHVlZGUgdmVyIHF1ZSBsb3MgYXJ0aXN0YXMgbcOhcyBzZWd1aWRvcywgKipOTyoqIHNvbiBsb3MgbcOhcyBlc2N1Y2hhZG9zLCB5YSBxdWUgbG9zIDMgY29uIG3DoXMgZmFucyBlbiBlc3RhIHBsYXRhZm9ybWEsIHNvbiBFZCBTaGVlcmFuLCBBcmlhbmEgR3JhbmRlIHkgRHJha2UuIEN1YW5kbyBUYXlsb3IgU3dpZnQgaGEgc2lkbyBsYSBtw6FzIGVzY3VjaGFkYSwgcGVybyBsYSA3IG3DoXMgc2VndWlkYSwgbG8gbWlzbW8gcGFzYSBjb24gQlRTIHF1ZSBoYSBwYXNhZG8gZGUgc2VyIGVsIHNlZ3VuZG8gYSBlbCBkw6ljaW1vIHByaW1lcm8uRXN0byBlcyBwb3JxdWUgZWwgaGVjaG8gZGUgcXVlIHNlYW4gbcOhcyBlc2N1Y2hhZG9zIG5vIHNpZ25pZmljYSBxdWUgc2VhbiBsb3MgbcOhcyBmYW1vc29zLCBzb2xvIHNpZ25pZmljYSBxdWUgaGFuIHNhY2FkbyBtw6FzIGNhbmNpb25lcyBlbiAyMDIxIG8gbWVqb3IgY29udGVuaWRvLg0KDQoNCmBgYHtyLCBldmFsID0gVFJVRSwgZWNobyA9IFRSVUV9DQoNCm1hc19zZWd1aWRvcmVzIDwtIHJlYWRfZXhjZWwoImRhdG9zL2ZvbGxvd2Vyc19hcnRpc3RzXzIwMjEueGxzeCIpIA0KDQoNCiMgU2V0IGhpZ2hjaGFydGVyIG9wdGlvbnMNCm9wdGlvbnMoaGlnaGNoYXJ0ZXIudGhlbWUgPSBoY190aGVtZV9zbXBsKHRvb2x0aXAgPSBsaXN0KHZhbHVlRGVjaW1hbHMgPSAyKSkpDQoNCmdnX21hc3NlZ3VpZG9yZXMgPC0gbWFzX3NlZ3VpZG9yZXMgJT4lDQogIGhjaGFydCgNCiAgICAicGllIiwgaGNhZXMoeCA9IEFydGlzdCwgeSA9IGFydGlzdF9mb2xsb3dlcnMpLA0KICAgIG5hbWUgPSAiTsK6IGRlIHNlZ3VpZG9yZXMiDQogICkNCg0KZ2dfbWFzc2VndWlkb3Jlcw0KDQoNCg0KYGBgDQoNCg0KDQojIyA0LjMgVE9QIDMwIGNhbmNpb25lcyBtw6FzIHNvbmFkYXMgZW4gZXN0ZSAyMDIxIMKoey50YWJzZXR9DQoNCkNvbW8gcG9kZW1vcyBvYnNlcnZhciBlbiBlc3RlIGdyw6FmaWNvIGRlIGNhamEgbGFzIGNhbmNpb25lcyBtw6FzIGVzY3VjaGFkYXMgZW4gMjAyMSBoYW4gc2lkbywgZW4gcHJpbWVyIGx1Z2FyLCAqKkJlZ2dpbicqKiBkZWwgZ3J1cG8gaXRhbGlhbm8gTcOlbmVza2luIGNvbiA0ODYzMzQ0OSByZXByb2R1Y2Npb25lcywgZXN0YSBjYW5jacOzbiBmdWUgbGEgZ2FuYWRvcmEgZGUgRXVyb3Zpc2lvbi5FbiBzZWd1bmRvIGx1Z2FyLCBlc3RhICoqU1RBWSAod2l0aCBKdXN0aW4gQmllYmVyKSoqIGRlbCByYXBlcm8gYXVzdHJhbGlhbm8gVGhlIEtpZCBMQVJPSSB5IGVzdGUgdGVtYSwgYWN1bXVsYSA0NzI0ODcxOSByZXByb2R1Y2Npb25lcyBlbiBTcG90aWZ5LiBZIGVuIHRlcmNlciBsdWdhciwgbGEgY2FuY2nDs24sICoqZ29vZCA0IHUqKiBkZSBsYSBhbWVyaWNhbmEgT2xpdmlhIFJvZHJpZ28gcXVlIHRpZW5lIDQwMTYyNTU5IHJlcHJvZHVjY2lvbmVzLg0KDQojIyMgUE9SIENBTkNJT05FUyBERU5UUk8gREVMIFRPUCAzMA0KDQpgYGB7ciwgZXZhbCA9IFRSVUUsIGVjaG8gPSBUUlVFLCBpbmNsdWRlID0gRkFMU0V9DQp0b3AxMCA8LSBzcG90aWZ5X2RhdGFzZXQgJT4lIHNlbGVjdChzb25nX25hbWUsIEFydGlzdCwgU3RyZWFtcykgJT4lIA0KIGFycmFuZ2UoZGVzYyhTdHJlYW1zKSkgJT4lIGZpbHRlcihTdHJlYW1zID4gMTU5Njc5ODUpDQoNCmxpYnJhcnkodHJlZW1hcCkNCg0KDQoNCg0KZ2dfdG9wMTAgPC0gdHJlZW1hcCh0b3AxMCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmRleD1jKCJBcnRpc3QiLCJzb25nX25hbWUiKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2U2l6ZT0iU3RyZWFtcyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZT0iaW5kZXgiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZDb2xvciA9ICJBcnRpc3QiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvbnRzaXplLmxhYmVscz1jKDE1LDIwKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBiZy5sYWJlbHM9YygidHJhbnNwYXJlbnQiKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWxldHRlID0gIlNldDEiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsaWduLmxhYmVscz1saXN0KA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYygiY2VudGVyIiwgImNlbnRlciIpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoImNlbnRlciIsICJib3R0b20iKSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGUgPSAiVE9QIDEwIDIwMjEiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlLmxlZ2VuZCA9ICJBcnRpc3RhcyIpIA0KDQpnZ190b3AxMA0KDQpgYGANCg0KYGBge3IsIGV2YWwgPSBUUlVFLCBlY2hvID0gVFJVRX0NCg0KI3RvcDEwIDwtIHNwb3RpZnlfZGF0YXNldCAlPiUgc2VsZWN0KHNvbmdfbmFtZSwgQXJ0aXN0LCBTdHJlYW1zKSAlPiUgDQogIyBmaWx0ZXIoU3RyZWFtcyA+IDE0MTc0NzUyKQ0KDQojbGlicmFyeSh0cmVlbWFwKQ0KDQojZ2dfdG9wXzEwIDwtIHRyZWVtYXAodG9wMTAsDQogIyAgICAgICBpbmRleD0iZ3JvdXAiLA0KICAjICAgICAgdlNpemU9InZhbHVlIiwNCiAgICMgICAgIHR5cGU9ImluZGV4IikNCg0KDQojZ2dfdG9wMTAgPC0gdHJlZW1hcCh0b3AxMCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAjaW5kZXg9YygiQXJ0aXN0Iiwic29uZ19uYW1lIiksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgI3ZTaXplPSJTdHJlYW1zIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAjdHlwZT0iaW5kZXgiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICN2Q29sb3IgPSAiQXJ0aXN0IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAjZm9udHNpemUubGFiZWxzPWMoMTUsMjApLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICNiZy5sYWJlbHM9YygidHJhbnNwYXJlbnQiKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAjcGFsZXR0ZSA9ICJTZXQxIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAjYWxpZ24ubGFiZWxzPWxpc3QoDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgYygiY2VudGVyIiwgImNlbnRlciIpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAjICBjKCJjZW50ZXIiLCAiYm90dG9tIikpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICN0aXRsZSA9ICJUT1AgMTAgMjAyMSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgI3RpdGxlLmxlZ2VuZCA9ICJBcnRpc3RhcyIpIA0KDQojZ2dfdG9wMTANCg0KDQoNCmBgYA0KDQpgYGB7ciwgZmlnLmFsaWduPSdjZW50ZXInLCBldmFsID0gVFJVRSwgZWNobyA9IFRSVUV9DQoNCmludGVyX3RvcDEwIDwtIGQzdHJlZTIoZ2dfdG9wMTAgLCAgcm9vdG5hbWUgPSAiVE9QIDMwIENhbmNpb25lcyBtw6FzIGVzY3VjaGFkYXMgZGVsIDIwMjEgeSBzdXMgQXJ0aXN0YXMiKQ0KaW50ZXJfdG9wMTANCg0KDQpgYGANCg0KIyMjIFRBQkxBIFJBTktJTkcgVE9QIDMwDQoNCmBgYHtyLCBldmFsID0gVFJVRSwgZWNobyA9IFRSVUV9DQoNCmtuaXRyOjprYWJsZSh0b3AxMCwgY2FwdGlvbiA9ICJUT1AgMzAgMjAyMSIpICU+JSANCiAga2FibGVFeHRyYTo6a2FibGVfc3R5bGluZyhib290c3RyYXBfb3B0aW9ucyA9IGMoInN0cmlwZWQiLCAiaG92ZXIiKSkgICU+JSANCiAga2FibGVFeHRyYTo6a2FibGVfc3R5bGluZyhmaXhlZF90aGVhZCA9IGxpc3QoZW5hYmxlZCA9IFQsIGJhY2tncm91bmQgPSAiY2hhcnRyZXVzZSIpKQ0KDQpgYGANCg0KIyA1LiBSZWdnYWV0b24gdnMgUE9QDQoNClNlZ8O6biB2YXJpYXMgZnVlbnRlcyBkZSBpbmZvcm1hY2nDs24sIGxvcyBkb3MgZ2VuZXJvcyBtw6FzIGVzY3VjaGFkb3MgZW4gbGEgYWN0dWFsaWRhZCBzb24gZWwgcG9wIHkgZWwgcmVnZ2FldG9uLkVuIGVzdGUgYXBhcnRhZG8gdmFtb3MgYSBjb21wYXJhciBsb3MgZG9zIGdlbmVyb3MgbWVkaWFudGUgZGlzdGludG9zIGFzcGVjdG9zLCBsYSBzdW1hIGRlIHRvZGFzIGxhcyByZXByb2R1Y2Npb25lcyBkZSBjYWRhIGfDqW5lcm8gZW4gMjAyMSwgbGEgYmFpbGFiaWxpZGFkIGRlIGNhZGEgZ8OpbmVybyB5IGxhIHBvcHVsYXJpZGFkLg0KDQojIyA1LjEgUXVlIGfDqW5lcm8gaGEgdGVuaWRvIG3DoXMgcmVwcm9kdWNjaW9uZXMgZW4gMjAyMQ0KDQpQYXJhIGNvbXBhcmFyIGhlbW9zIHN1bWFkbyB0b2RhcyBsYXMgcmVwcm9kdWNjaW9uZXMgZGUgbGFzIGNhbmNpb25lcyBkZSBwb3AgZW4gMjAyMS5FbiBlc3RlIGdyw6FmaWNvIGRlIGJhcnJhcyBwb2RlbW9zIHZlciwgcXVlIGVsIHBvcCBzZSBoYSBlc2N1Y2hhZG8gbXVjaG8gbcOhcyBxdWUgZWwgcmVnZ2FldG9uIGR1cmFudGUgZXN0ZSBhw7FvLg0KDQpgYGB7ciwgZXZhbCA9IFRSVUUsIGVjaG8gPSBUUlVFfQ0KcmVnZ2FldG9uIDwtIHNwb3RpZnlfZGF0YXNldCAlPiUgDQogIHNlbGVjdChBcnRpc3QsIHNvbmdfbmFtZSwgU3RyZWFtcywgR2VucmUsIFBvcHVsYXJpdHksIERhbmNlYWJpbGl0eSwgRW5lcmd5KSAlPiUNCiAgZmlsdGVyKHN0cmluZ3I6OnN0cl9kZXRlY3QoR2VucmUsICdyZWdnYWV0b24nKSApICU+JSANCiAgbXV0YXRlKHN0cmVhbXNfdG90YWxlcyA9IHN1bShTdHJlYW1zKSkgDQoNCg0KcG9wIDwtIHNwb3RpZnlfZGF0YXNldCAlPiUgDQogIHNlbGVjdChBcnRpc3QsIHNvbmdfbmFtZSwgU3RyZWFtcywgR2VucmUsIFBvcHVsYXJpdHksIERhbmNlYWJpbGl0eSwgRW5lcmd5KSAlPiUNCiAgZmlsdGVyKHN0cmluZ3I6OnN0cl9kZXRlY3QoR2VucmUsICdwb3AnKSApICU+JSANCiAgbXV0YXRlKHN0cmVhbXNfdG90YWxlcyA9IHN1bShTdHJlYW1zKSkNCg0KDQpyZWdnYWV0b25fdnNfcG9wIDwtIHJiaW5kKHJlZ2dhZXRvbiwgcG9wKSAlPiUgDQogIHNlbGVjdChHZW5yZSwgc3RyZWFtc190b3RhbGVzKQ0KDQpyZWdnYWV0b25fdnNfcG9wX3NvbG9fc3RyZWFtcyA8LSByZWdnYWV0b25fdnNfcG9wW2MoMjksMTg1KSwgXQ0KDQoNCmdnX3ZzX3N0cmVhbXMgPC0gZ2dwbG90KHJlZ2dhZXRvbl92c19wb3Bfc29sb19zdHJlYW1zLCBhZXMoeD1HZW5yZSwgeT1zdHJlYW1zX3RvdGFsZXMsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxsID0gc3RyZWFtc190b3RhbGVzKSkgKyANCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIpICsNCiAgdGhlbWUocGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gIndoaXRlIikpICtsYWJzKHggPSAiR2VuZXJvIiwgeSA9ICJTdHJlYW1zIFRvdGFsZXMiKQ0KDQoNCmdncGxvdGx5KGdnX3ZzX3N0cmVhbXMpDQoNCmBgYA0KDQoNCiMjIDUuMiBRdWUgZ8OpbmVybyBoYSBzaWRvIG3DoXMgYmFpbGFibGUgZW4gMjAyMQ0KDQpQYXJhIGxsZXZhciBhIGNhYm8gZXN0YSBjb21wYXJhY2nDs24sIGhlIHJlYWxpemFkbyBsYSBtZWRpYSBkZSBsYSBiYWlsYWJpbGlkYWQgZGUgdG9kYXMgbGFzIGNhbmNpb25lcyBkZSBjYWRhIGfDqW5lcm8sIGVzIGRlY2lyLCBoZSBzdW1hZG8gbGEgYmFpbGFiaWxpZGFkIGRlIHRvZGFzIGxhcyBjYW5jaW9uZXMgZGUgcG9wIHkgZGUgcmVnZ2FldG9uLCB5IGxvIGhlIGRpdmlkaWRvIGVudHJlIGVsIG7CuiBkZSB0ZW1hcyBkZSBjYWRhIHVubyAuWSBjb21vIHBvZGVtb3Mgb2JzZXJ2YXIsIGxhcyBjYW5jaW9uZXMgZGUgcmVnZ2FldG9uIGhhbiBzaWRvIG3DoXMgYmFpbGFibGVzIHF1ZSBsYXMgZGUgcG9wIGVuIHVuIDglLg0KDQpgYGB7ciwgZXZhbCA9IFRSVUUsIGVjaG8gPSBUUlVFfQ0KDQpyZWdnYWV0b25fYmFpbGEgPC0gcmVnZ2FldG9uICU+JSBzdW1tYXJpc2UobWVkaWFfYmFpbGFiaWxpZGFkID0gbWVhbihEYW5jZWFiaWxpdHkpKQ0KDQpwb3BfYmFpbGEgPC0gcG9wICU+JSBzdW1tYXJpc2UobWVkaWFfYmFpbGFiaWxpZGFkID0gbWVhbihEYW5jZWFiaWxpdHkpKQ0KDQpyZWdnYWV0b25fdnNfcG9wX2JhaWxhIDwtIHJiaW5kKHJlZ2dhZXRvbl9iYWlsYSwgcG9wX2JhaWxhKQ0KDQpyZWdnYWV0b25fdnNfcG9wX2JhaWxhX2JpZW4gPC0gY2JpbmQocmVnZ2FldG9uX3ZzX3BvcF9iYWlsYSwgR2VucmU9YygicmVnZ2FldG9uIiwicG9wIikpDQoNCmdnX3ZzX2JhaWxhIDwtIGdncGxvdChyZWdnYWV0b25fdnNfcG9wX2JhaWxhX2JpZW4sIGFlcyh4PUdlbnJlLCB5PW1lZGlhX2JhaWxhYmlsaWRhZCwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGwgPSBtZWRpYV9iYWlsYWJpbGlkYWQpKSArIA0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IikgICsgdGhlbWUocGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gIndoaXRlIikpICtsYWJzKHggPSAiR2VuZXJvIiwgeSA9ICJNZWRpYSBkZSBCYWlsYWJpbGlkYWQiKQ0KDQoNCg0KZ2dwbG90bHkoZ2dfdnNfYmFpbGEpDQoNCg0KYGBgDQoNCg0KIyMgNS4zIFF1ZSBnw6luZXJvIGhhIHNpZG8gbcOhcyBwb3B1bGFyIGVuIDIwMjENCg0KUGFyYSByZWFsaXphciBlc3RhIGNvbXBhcmFjacOzbiwgaGVtb3Mgc3VtYWRvIGxhIHBvcHVsYXJpZGFkIGRlIHRvZGFzIGxhcyBjYW5jaW9uZXMgZGUgY2FkYSBnw6luZXJvIHkgbG8gaGVtb3MgZGl2aWRpZG8gZW50cmUgZWwgbsK6IGRlIGNhbmNpb25lcyBkZSBjYWRhIHVuby5UcmFzIG9ic2VydmFyIGVsIGdyw6FmaWNvLCBwb2RlbW9zIG9idGVuZXIgdW5hIGNvbmNsdXNpw7NuLCBsYXMgY2FuY2lvbmVzIGRlIHJlZ2dhZXRvbiBzb24gbcOhcyBwb3B1bGFyZXMgcXVlIGxhcyBkZSBwb3Agbm9ybWFsbWVudGUuDQoNCg0KYGBge3IsIGV2YWwgPSBUUlVFLCBlY2hvID0gVFJVRX0NCg0KcmVnZ2FldG9uX3BvcHUgPC0gcmVnZ2FldG9uICU+JSBzdW1tYXJpc2UobWVkaWFfcG9wdWxhcmlkYWQgPSBtZWFuKFBvcHVsYXJpdHkpKQ0KDQpwb3BfcG9wdSA8LSBwb3AgJT4lIHN1bW1hcmlzZShtZWRpYV9wb3B1bGFyaWRhZCA9IG1lYW4oUG9wdWxhcml0eSkpDQoNCnJlZ2dhZXRvbl92c19wb3BfcG9wdSA8LSByYmluZChyZWdnYWV0b25fcG9wdSwgcG9wX3BvcHUpDQoNCnJlZ2dhZXRvbl92c19wb3BfcG9wdV9iaWVuIDwtIGNiaW5kKHJlZ2dhZXRvbl92c19wb3BfcG9wdSwgR2VucmU9YygicmVnZ2FldG9uIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJwb3AiKSkNCg0KZ2dfdnNfcG9wdSA8LSBnZ3Bsb3QocmVnZ2FldG9uX3ZzX3BvcF9wb3B1X2JpZW4sIGFlcyh4PUdlbnJlLCB5PW1lZGlhX3BvcHVsYXJpZGFkLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxsID0gbWVkaWFfcG9wdWxhcmlkYWQpKSArIA0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IikgKw0KICB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAid2hpdGUiKSkgK2xhYnMoeCA9ICJHZW5lcm8iLCB5ID0gIk1lZGlhIGRlIGxhIFBvcHVsYXJpZGFkIikNCg0KDQpnZ3Bsb3RseShnZ192c19wb3B1KQ0KDQpgYGANCg0KDQojIDYuIEFzcGVjdG9zIG11c2ljYWxlcyBkZWwgMjAyMQ0KDQpFbiBlc3RlIGFwYXJ0YWRvIG9ic2VydmFyZW1vcyB2YXJpYXMgY2FyYWN0ZXLDrXN0aWNhcyBxdWUgdGllbmVuIHF1ZSB2ZXIgY29uIGxhIG3DunNpY2EsIGNvbW8gZXMgZWwgKip0ZW1wbyoqLCBsb3MgKiphY29yZGVzKiosIGxhICoqZW5lcmfDrWEqKiB5IGxhICoqYmFpbGFiaWxpZGFkKioNCg0KIyMgNi4xIFF1ZSB0ZW1wbyBkZWJlbiB0ZW5lciBsYXMgY2FuY2lvbmVzIHBhcmEgc2VyIGJhaWxhYmxlcz8NCg0KQ29tbyBwb2RlbW9zIG9ic2VydmFyIGVuIGVzdGUgZ3LDoWZpY28gZGUgZGlzcGVyc2nDs24sIGxhcyBjYW5jaW9uZXMgcGFyYSBzZXIgYmFpbGFibGVzIChkYW5jZWFiaWxpdHk+PSAwLDc1KSwgaGFuIGRlIHRlbmVyIHVuIHRlbXBvIGVudHJlIDEwMCB5IDE1MCwgc2kgdGllbmVuIHVuIHRlbXBvIG1heW9yIHNvbiBkZW1hc2lhZG8gcsOhcGlkYXMgcGFyYSBzZXIgYmFpbGFkYXMgcG9yIHRhbnRvIHN1IGJhaWxhYmlsaWRhZCBjYWUsIHkgc2kgdGllbmVuIHVuIHRlbXBvIG1lbm9yIHF1ZSAxMDAsIHNvbiBkZW1hc2lhZG8gbGVudGFzLg0KDQpgYGB7ciwgZXZhbCA9IFRSVUUsIGVjaG8gPSBUUlVFfQ0KDQoNCmdnXzEgPC0gZ2dwbG90KHNwb3RpZnlfZGF0YXNldCkgKyBnZW9tX3BvaW50KG1hcHBpbmcgPSBhZXMoeD1UZW1wbywgeT1EYW5jZWFiaWxpdHkpLCBjb2xvdXIgPSAiY2hhcnRyZXVzZTMiKSArIA0KICBnZW9tX3Ntb290aChtYXBwaW5nID0gYWVzKHg9VGVtcG8sIHk9RGFuY2VhYmlsaXR5KSwgY29sb3IgPSAiYmxhY2siKSArIA0KICBsYWJzKHRpdGxlPSJUZW1wbyBkZSBsYSBjYW5jacOzbiB2cyBCYWlsYWJpbGlkYWQiKSArDQogIHRoZW1lKHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJ3aGl0ZSIpKSArbGFicyh5ID0gIkJhaWxhYmlsaWRhZCIpDQpnZ3Bsb3RseShnZ18xKQ0KDQoNCg0KYGBgDQoNCg0KIyMgNi4yIFF1ZSBlbmVyZ2lhIHN1ZWxlbiB0ZW5lciBsYXMgY2FuY2lvbmVzIG3DoXMgYmFpbGFibGVzPw0KDQpMYXMgY2FuY2lvbmVzIG3DoXMgYmFpbGFibGVzLCBzZWfDum4gZWwgZ3LDoWZpY28gZGUgZGlzcGVyc2lvbiwgc3VlbGVuIHRlbmVyIHVuYXMgZW5lcmfDrWEgZW50cmUgMCw2MCB5IDAsNzUuIFNpIGxhcyBjYW5jaW9uZXMgdGllbmVuIHVuYSBlbmVyZ8OtYSBtZW5vciwgbm8gaW5jaXRhbiBhbCBtb3ZpbWllbnRvIHkgcG9yIHRhbnRvLCB0aWVuZW4gdW5hIGJhaWxhYmlsaWRhZCBtdXkgYmFqYQ0KDQoNCmBgYHtyLCBldmFsID0gVFJVRSwgZWNobyA9IFRSVUV9DQoNCmdnXzIgPC0gZ2dwbG90KHNwb3RpZnlfZGF0YXNldCkgKyBnZW9tX3BvaW50KG1hcHBpbmcgPSBhZXMoeD1FbmVyZ3ksIHk9RGFuY2VhYmlsaXR5KSwgY29sb3VyID0gImNoYXJ0cmV1c2UzIikgKyANCiAgZ2VvbV9zbW9vdGgobWFwcGluZyA9IGFlcyh4PUVuZXJneSwgeT1EYW5jZWFiaWxpdHkpLCBjb2xvciA9ICJibGFjayIpICsgDQogIGxhYnModGl0bGU9IkVuZXJnw61hIGRlIGxhIGNhbmNpw7NuIHZzIEJhaWxhYmlsaWRhZCIpICsNCiAgdGhlbWUocGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gIndoaXRlIikpICtsYWJzKHggPSAiRW5lcmfDrWEgZGUgbGEgQ2FuY2nDs24iLCB5ID0gIkJhaWxhYmlsaWRhZCIpDQpnZ3Bsb3RseShnZ18yKQ0KDQoNCg0KYGBgDQoNCg0KIyMgNi4zIExhcyBjYW5jaW9uZXMgbcOhcyBwb3B1bGFyZXMgc29uIGxhcyBtw6FzIGJhaWxhYmxlcz8NCg0KTGEgcmVzcHVlc3RhIGEgZXN0YSBwcmVndW50YSBlcyBzaSwgeWEgcXVlIGNvbW8gcG9kZW1vcyB2ZXIsIGxhcyBjYW5jaW9uZXMgY29uIHVuYSBwb3B1bGFyaWRhZCBwb3IgZW5jaW1hIGRlIDc1LCBxdWUgZXN0byBzaWduaWZpY2EgcXVlIHNvbiBjYW5jaW9uZXMgcG9wdWxhcmVzIGEgbml2ZWwgbXVuZGlhbCB5IHF1ZSBoYW4gZXN0YWRvIGVuIGxvcyB0b3BzIHZhcmlhcyB2ZWNlcywgdGllbmVuIHVuYSBiYWlsYWJpbGlkYWQgcG9yIGVuY2ltYSBkZSAwLDY1LCBlcyBkZWNpciwgcXVlIHNpIHNvbiBwb3B1bGFyZXMgc29uIGJhc3RhbnRlIGJhaWxhYmxlcywgeWEgcXVlIGVzdG9zIHNpZ25pZmljYSBxdWUgc3Ugcml0bW8sIHN1IGxldHJhIHkgc3UgbWVsb2RpYSBzb24gbcOhcyBwZWdhZGl6YXMuDQoNCmBgYHtyLCBldmFsID0gVFJVRSwgZWNobyA9IFRSVUV9DQoNCmdnXzMgPC0gZ2dwbG90KHNwb3RpZnlfZGF0YXNldCkgKyBnZW9tX3BvaW50KG1hcHBpbmcgPSBhZXMoeD1EYW5jZWFiaWxpdHksIHk9UG9wdWxhcml0eSksIGNvbG91ciA9ICJjaGFydHJldXNlMyIpICsgDQogIGdlb21fc21vb3RoKG1hcHBpbmcgPSBhZXMoeD1EYW5jZWFiaWxpdHksIHk9UG9wdWxhcml0eSksIGNvbG9yID0gImJsYWNrIikgKyANCiAgbGFicyh0aXRsZT0iUG9wdWxhcmlkYWQgdnMgQmFpbGFiaWxpZGFkIikgKw0KICB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAid2hpdGUiKSkgK2xhYnMoeCA9ICJCYWlsYWJpbGlkYWQiLCB5ID0gIlBvcHVsYXJpZGFkIikNCmdncGxvdGx5KGdnXzMpDQoNCg0KYGBgDQoNCg0KIyMgNi40IFF1ZSBhY29yZGUgdXNhbiBsYXMgY2FuY2lvbmVzIG3DoXMgcG9wdWxhcmVzPw0KDQpFbiBlc3RlIGdyw6FmaWNvIGRlIGJhcnJhcyBzZSBwdWVkZSBvYnNlcnZhciBxdWUsIGxhcyBjYW5jaW9uZXMgY29uIG1heW9yIHBvcHVsYXJpZGFkIHNvbiBsYXMgcXVlIHV0aWxpemFuIGVsIGFjb3JkZSAqKkMjL0RiKiosIHkgbGFzIHF1ZSBtZW5vcyBwb3B1bGFyZXMgc29uIGxhcyBxdWUgdXRpbGl6YW4gZWwgYWNvcmRlICoqRCMvRWIqKi4NCg0KYGBge3IsIGV2YWwgPSBUUlVFLCBlY2hvID0gVFJVRX0NCg0KDQpnZ180IDwtIGdncGxvdChzcG90aWZ5X2RhdGFzZXQsIGFlcyh4PUNob3JkLCB5PVBvcHVsYXJpdHkpKSArIA0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgY29sb3IgPSJibGFjayIgLGZpbGwgPSAiY2hhcnRyZXVzZTMiKSArDQoNCiB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAid2hpdGUiKSkgK2xhYnModGl0bGUgPSAiUG9wdWxhcmlkYWQgdnMgQWNvcmRlIiwgeCA9ICJBY29yZGUiLA0KICAgIHkgPSAiUG9wdWxhcmlkYWQiKQ0KZ2dfNA0KDQoNCmBgYA0KDQoNCiMgNy4gUmVnZ2FldG9uIGVuIGVsIDIwMjENCg0KRW4gbG9zIHVsdGltb3MgYcOxb3MsIGVzdGUgZ8OpbmVybyBtdXNpY2FsIGhhIGlkbyBhdW1lbnRhbmRvIHN1IHBvcHVsYXJpZGFkIGEgbml2ZWxlcyBlc3RyYXRvc2bDqXJpY29zLCBoYSBwYXNhZG8gZGUgc2VyIHNvbG8gZXNjdWNoYWRvIGVuIHBhaXNlcyBsYXRpbm9zLCBoYSBzZXIgdW5vIGRlIGxvcyBtw6FzIGZhbW9zb3MgYSBuaXZlbCBtdW5kaWFsLkVzdGUgYcOxbywgbG9zIDMgYXJ0aXN0YXMgZGUgcmVnZ2FldG9uIG3DoXMgaW1wb3J0YW50ZXMgaGFuIHNpZG8gQmFkIEJ1bm55LCBSYXV3IEFsZWphbmRybyB5IEogQmFsdmluLg0KDQpgYGB7ciwgZXZhbCA9IFRSVUUsIGVjaG8gPSBUUlVFfQ0KDQpiYl9yYV9qIDwtIHNwb3RpZnlfZGF0YXNldCAlPiUgDQogIHNlbGVjdChBcnRpc3QsIFN0cmVhbXMsIGFydGlzdF9mb2xsb3dlcnMsIHNvbmdfbmFtZSwgYE51bWJlciBvZiBUaW1lcyBDaGFydGVkYCkgJT4lIA0KICBmaWx0ZXIoQXJ0aXN0ICVpbiUgYygiQmFkIEJ1bm55IiwgIlJhdXcgQWxlamFuZHJvIiwiSiBCYWx2aW4iKSkNCg0KdG90YWxfc3RyZWFtc19iYl9yYV9qIDwtIHRyZWludGFfbWFzX2VzY3VjaGFkb3NbYyg1LDMxLDMyKSwgXSAlPiUgDQogIHNlbGVjdChBcnRpc3QsIHN0cmVhbXNfdG90YWxlcykNCg0KY29tcGFyYWNpb25fcmVnZ2FldG9uIDwtIGZ1bGxfam9pbihiYl9yYV9qLHRvdGFsX3N0cmVhbXNfYmJfcmFfaiwgYygiQXJ0aXN0IiA9ICJBcnRpc3QiKSkgJT4lIA0KICBzZWxlY3QoQXJ0aXN0LHN0cmVhbXNfdG90YWxlcyxhcnRpc3RfZm9sbG93ZXJzKSANCg0KY29tcGFyYWNpb25fcmVnZ2FldG9uXzMgPC0gY29tcGFyYWNpb25fcmVnZ2FldG9uW2MoMSwyLDcpLCBdDQoNCmNvbXBhcmFjaW9uX3JlZ2dhZXRvbl9lZGFkIDwtIGNiaW5kKGNvbXBhcmFjaW9uX3JlZ2dhZXRvbl8zLCBFZGFkPWMoIjI3IiwiMjgiLCAiMzYiKSkNCg0KDQoNCmZvdG9zX3JlZ2dhZXRvbl9hcnRpc3RhcyA8LSBjKCIuL2ltYWdlbmVzL2JhZF9idW5ueS5wbmciLCAiLi9pbWFnZW5lcy9yYXV3X2FsZWphbmRyby5wbmciLCIuL2ltYWdlbmVzL2pfYmFsdmluLnBuZyIpDQoNCmZvdG9zX3ByX2NvbCA8LSBjKCIuL2ltYWdlbmVzL1B1ZXJ0b19SaWNvLnBuZyIsIi4vaW1hZ2VuZXMvUHVlcnRvX1JpY28ucG5nIiwgIi4vaW1hZ2VuZXMvQ29sb21iaWEucG5nIikNCg0KY29tcGFyYWNpb25fcmVnZ2FldG9uX2JpZW4gPC0gY29tcGFyYWNpb25fcmVnZ2FldG9uX2VkYWQgJT4lIGFkZF9jb2x1bW4oZm90b3NfcmVnZ2FldG9uX2FydGlzdGFzLCBmb3Rvc19wcl9jb2wpDQoNCmxpYnJhcnkoZ3QpDQoNCnJlZ2dhZXRvbl90YWJsYSA8LSBjb21wYXJhY2lvbl9yZWdnYWV0b25fYmllbiAlPiUgZ3QoKSAlPiUgDQogIHRleHRfdHJhbnNmb3JtKCBsb2NhdGlvbnMgPSBjZWxsc19ib2R5KGNvbHVtbnMgPSBjKGZvdG9zX3JlZ2dhZXRvbl9hcnRpc3RhcykpLCBmbiA9IGZ1bmN0aW9uKHgpIHtndDo6bG9jYWxfaW1hZ2UoeCwgaGVpZ2h0ID0gODApfSkgJT4lIA0KICB0ZXh0X3RyYW5zZm9ybSggbG9jYXRpb25zID0gY2VsbHNfYm9keShjb2x1bW5zID0gYyhmb3Rvc19wcl9jb2wpKSwgZm4gPSBmdW5jdGlvbih4KSB7Z3Q6OmxvY2FsX2ltYWdlKHgsIGhlaWdodCA9IDgwKX0pICU+JSB0YWJfaGVhZGVyKHRpdGxlID0gbWQoIioqVE9QIEFSVElTVEFTIFJFR0dBRVRPTiAyMDIxKioiKSwgc3VidGl0bGUgPSBtZCgiQ29tcGFyYWNpw7NuIikpICU+JSAgIGNvbHNfbGFiZWwoDQogICAgQXJ0aXN0ID0gaHRtbCgiQXJ0aXN0YSIpLA0KICAgIHN0cmVhbXNfdG90YWxlcyA9IGh0bWwoIlRvdGFsIFJlcHJvZHVjY2lvbmVzIiksDQogICAgYXJ0aXN0X2ZvbGxvd2VycyA9IGh0bWwoIlNlZ3VpZG9yZXMgU3BvdGlmeSIpLA0KICAgIGZvdG9zX3JlZ2dhZXRvbl9hcnRpc3RhcyA9IGh0bWwoIiIpLA0KICAgIGZvdG9zX3ByX2NvbCA9IGh0bWwoIiIpKSAlPiUgIA0KICB0YWJfb3B0aW9ucyh0YWJsZS5iYWNrZ3JvdW5kLmNvbG9yID0gIndoaXRlIiwgICB0YWJsZS5mb250LmNvbG9yLmxpZ2h0ID0gImNoYXJ0cmV1c2UiKSAlPiUgDQogIGNvbHNfYWxpZ24oYWxpZ24gPSAiY2VudGVyIiwNCiAgY29sdW1ucyA9IGV2ZXJ5dGhpbmcoKSkNCg0KcmVnZ2FldG9uX3RhYmxhDQoNCmBgYA0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCiMgNC4gQmlibGlvZ3JhZsOtYQ0KDQotIFtQw6FnaW5hIHdlYiBkZSBsYSBhc2lnbmF0dXJhLl0oaHR0cHM6Ly9wZXJlenA0NC5naXRodWIuaW8vaW50cm8tZHMtMjEtMjItd2ViLzA0LXR1dG9yaWFsZXMuaHRtbCkNCg0KLSBbS2FnZ2xlIHNvYnJlIFNwb3RpZnkuXShodHRwczovL3d3dy5rYWdnbGUuY29tL3Nhc2hhbmtwaWxsYWkvc3BvdGlmeS10b3AtMjAwLWNoYXJ0cy0yMDIwMjAyMSkNCg0KLSBbU3RhdGlzdGEuXShodHRwczovL3d3dy5zdGF0aXN0YS5jb20vdG9waWNzLzIwNzUvc3BvdGlmeS8jZG9zc2llcktleWZpZ3VyZXMpDQoNCi0gW0RhdG9zIFNwb3RpZnkgU2VtYW5hbGVzLl0oaHR0cHM6Ly9zcG90aWZ5Y2hhcnRzLmNvbS9yZWdpb25hbCkNCg0KPGJyPjxicj4NCg0KPGhyIGNsYXNzPSJsaW5lYS1yZWQiPg0KPGhyIGNsYXNzPSJsaW5lYS1yZWQiPg0KDQoNCg0KDQo8YnI+PGJyPg0KDQo8ZGl2IGNsYXNzPSJ0b2NpZnktZXh0ZW5kLXBhZ2UiIGRhdGEtdW5pcXVlPSJ0b2NpZnktZXh0ZW5kLXBhZ2UiIHN0eWxlPSJoZWlnaHQ6IDA7Ij48L2Rpdj4NCjxicj48YnI+DQoNCjxkaXYgY2xhc3M9InRvY2lmeS1leHRlbmQtcGFnZSIgZGF0YS11bmlxdWU9InRvY2lmeS1leHRlbmQtcGFnZSIgc3R5bGU9ImhlaWdodDogMDsiPjwvZGl2Pg0K