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

Logo Disney

Este trabajo es un análisis de una de las empresas más grandes de animación actualmente,The Walt Disney Company o Disney. Se fundo en 1923 de la mano de Walt Dinsey y Roy O. Disney.

Esta empresa en la actualidad no solo produce películas de animación, tiene sus propias tiendad de comercio (DisneyStore), su propia plataforma de streaming (Disney+) y sus propios parques de atracciones (DisneyLand Paris, Disney Ornaldo, etc).

Además dicha empresa esta formada por diferentes franquicias de cine que durante varios años Disney ha comprado. Estas son: Walt Disney Pictures, Pixar Animation Studios, Marvel Studios, Lucasfilm, 20th Century Studios,Searchlight Pictures, The Muppets.

En este trabajo, también analizaremos una de estas empresas, en partícular, la que esta más enfocada a los superheroes, Marvel.

Empresas Disney

2. Datos

Los datos que se van a utilizar durante el trabajo han sido sacados de Kaggle y GitHub, en la bibliografia se encuentra el link directo.

2.1. Procesando los datos

El trabajo se ha escrito sobre 4 dataframes.

Uno de ellos engloba todos los datos de Disney y los otros tres engloban los datos de Marvel.

El primero llamado ‘aa’ tiene 6 columnas y 579 observaciones. Este es el que engloba los datos de Disney

El segundo ‘bb’ tiene 9 columnas y 595 observaciones.

El tercero ‘cc’ tiene 39646 observaciones y 12 variables.

Por último, el ‘dd’ tiene 16376 observaciones y 13 variables.

Estás tres últimas engloban los datos de Marvel.

datos1 <- here::here("datosss", "disney_movies.csv")

aa <- rio::import(datos1) 

datos2 <- here::here("datosss", "charcters_stats_a.csv")

bb <- rio::import(datos2)


datos3 <- here::here("datosss", "marvelpersonajes.csv")

cc <- rio::import(datos3)

datos4 <- here::here("datosss", "marvelwiki.csv")

dd <- rio::import(datos4)

Una vez abiertos los datos, empezamos con el análisis de la primera compañía, Diseny.


2.2 ¿Cuántas películas tiene Disney de distintos géneros?

aa %>% count(genre) %>% arrange(-n) %>% 
 ggplot(aes(reorder(genre,n),n)) + geom_col(aes(fill=genre)) + coord_flip() +
  theme(legend.position="none") + 
  ylab("Número de películas") + xlab("Género") +
  geom_text(aes(label=n), position=position_dodge(width=1), hjust=1) +
  ggtitle("Número de peliculas según su genero")

Ante el gráfico formado, podemos dictaminar que el género que dóminan las películas Disney es la comedia con 182. Seguido por el segundo gérnero de Aventuras con 129 películas. En el último puesto, tenemos el género de Performance el cual Disney nada más ha hecho dos películas.

2.3 ¿Qué 10 películas son las que más beneficios tienen?

top_10_disney <- aa %>%
  arrange(desc(total_gross)) %>%
  head(10) 

 top_10_disney_plot <- ggplot(top_10_disney) + geom_col(data = top_10_disney, mapping=aes(y=movie_title, x=total_gross, color = movie_title)) + labs(title="TOP 10 películas de Disney", y="Títulos", x="Ingresos Brutos") + theme(legend.position="none")

 ggplotly(top_10_disney_plot)

Según nos muestra tanto el gráfico como la tabla que hemos obtenido, la película que más Ingresos Brutos ha obtenido a lo largo de la historia de la compañía es Star Wars Ep. VII:The Gorce Awaken de la firma Lucas Films, con un total de 9366662225 de dólares. Seguidamente, tendríamos The Avengers de la firma Marvel con un total de 623279547 dólares. Como última de las más taquilleras, encontramos Capitán América:Civil War, también de Marvel, con un total de 408084349 dólares.

Es curioso cómo ninguna de las películas con más ingresos de Disney, no sea ninguna original de la propia empresa. Con esto podemos refutar la importancia de las firmas que conformar el total de la empresa Disney.

Final Disney

3 ¿Qué es Marvel?

Marvel Worldwide, Inc., conocida como Marvel Comics, es una editorial de historietas estadounidense creada en 1939. Pero no fue hasta los años 1990 que la compañía no se posicionó como una de las principales editoriales de cómics. El 31 de agosto de 2009, The Walt Disney Company compró Marvel Entertainment por cerca de 4 000 millones de dólares, fusionándose con esta el 1 de enero de 2010.

Logo Marvel


3.1 ¿Cuantos superheroes nuevos hay cada año?

primera_aparicion <- cc %>% 
  group_by(Year) %>% 
  count() %>% 
  ungroup() 
  
 primera_apar_plot <- ggplot(primera_aparicion, aes(Year, n)) + geom_area(fill = "black", aplha = 0.5) +geom_smooth(color = "red") + labs(title="¿Cuántos nuevos superheroes hay por año?", y="Cantidad", x="Años")
  
ggplotly(primera_apar_plot)

Frente al gráfico que vemos, podemos afirmar que el año que más personajes se crearon de la indústria Marvel fue en 1993 creandose 1317 nuevos superheroes. Y que la época más baja fue a sus inicios en 1935 creandose solo 1 superheroes. La línea roja representa el cumulo de personajes que se han ido creando, viendo que en la actualidad ese número ha disminuido (parte de los superheroes ya no aparecen en los cómics).


3.2 ¿Cuántas hombres y mujeres superheroes hay?

hombres_heroes <- dd %>% 
  select(Year, name, SEX) %>% 
  group_by(SEX) %>% 
  filter(SEX == "Male Characters") %>% 
  summarise(Total_Hombres = n()) 

hombres_heroes
SEX Total_Hombres
Male Characters 11638
mujeres_heroes <- dd %>% 
  select(Year, name, SEX) %>% 
  group_by(SEX) %>% 
  filter(SEX == "Female Characters") %>% 
  summarise(Total_Mujeres = n()) 

mujeres_heroes
SEX Total_Mujeres
Female Characters 3837

En estas dos tablas podemos ver, el número de hombre y el número de mujeres que aparecen a lo largo de los cómics. Pueden ser villanos o superheroes. Hay una clara diferencia entre los géneros y salen claramente ganando los hombres.


3.3 Cuales superheroes aparecen más por genero.

max_hombres <- dd %>% 
  select(name, SEX, APPEARANCES) %>% 
  group_by(SEX) %>% 
  filter(SEX == "Male Characters") %>% 
  head(15)

generom_plot <- ggplot(max_hombres, aes(name, APPEARANCES, color = name)) +
  geom_point() + xlab("nombres") +  theme(
  axis.text.x = element_blank()) + labs(title="Top 15 Superheroes con más apariciones", y="Apariciones", x="") + theme(legend.position="none")


ggplotly(generom_plot)

Según el gráfico, el personaje hombre que más ha aparecido a lo largo de la histórida de Marvel es Spider-Man o Peter Parker el cual aparece 4043 veces. El segundo personaje masculino que más aparece es Capitan America o Steven Rogers, el cual aparece 3360. Y el último personaje que más apariciones tiene es Stephen Strange** con 1307 apariciones.

max_mujeres <- dd %>% 
  select(name, SEX, APPEARANCES) %>% 
  group_by(SEX) %>% 
  filter(SEX == "Female Characters") %>% 
  head(15)

genero_plot <- ggplot(max_mujeres, aes(name, APPEARANCES, color = name)) +
  geom_point() + xlab("nombres") +  theme(
  axis.text.x = element_blank()) + labs(title="Top 15 Superheroinas con más apariciones", y="Apariciones", x="") +  theme(legend.position="none")


ggplotly(genero_plot)

En el caso de las mujeres, la que más aparece es Susan Storm de los 4 Fántasticos, la cual aparece un total de 1713. Seguida por Ororo Munroe o Tormenta que aparece 1512 veces. La última mujer que más apariciones ha tenido ha sido Elizabeth Brant de Spiderman, con un total de 599 apariciones.

Cabe destacar que las mujeres con mayor apariciones tienen casi las mismas que el personaje hombre con menos apariciones del gráfico anterior.


3.4 ¿Cuáles son los 5 superheroes más poderosos?

poderes_buenos <- bb %>% 
  select(Name, Alignment, Total) %>% 
  group_by(Alignment) %>% 
   slice_max(Total, n = 5) %>% 
  filter( Alignment == "good")


poderes_buenos_plot <- ggplot(poderes_buenos, aes(x = Name, y = Total, fill = Alignment)) +
  geom_col(position = "dodge")+
  coord_polar() + ggtitle("Heroes más poderosos") + theme(
  axis.text.y = element_blank()) + ylab("Poderes") + xlab("Nombres")

poderes_buenos_plot

Ante este gráfico, podemos destacar que el superheroe con más poderes de Marvel es Thor, seguido por Phoenix y terminando con The Watcher.


3.5 ¿Cuáles son los 5 villanos más poderosos?

poderes_malos <- bb %>% 
  select(Name, Alignment, Total) %>% 
  group_by(Alignment) %>% 
   slice_max(Total, n = 5) %>% 
  filter( Alignment == "bad")

poderes_malos_plot <- ggplot(poderes_malos, aes(x = Name, y = Total, fill = Alignment)) +
  geom_col(position = "dodge")+
  coord_polar() + ggtitle("Villanos más poderosos") + theme(
  axis.text.y = element_blank()) + ylab("Poderes") + xlab("Nombres")

poderes_malos_plot

Frente al gráfico, podemos afirmar que Dormammu es el villano con más poderes, seguido por Magus y el último sería Onslaught.

Personajes Marvel

4. Trabajos en los que te has basado

Para los análisis mostrados en los trabajos de GitHub mencionados en el apartado de bibliográfica.


5. Bibliografía

https://www.kaggle.com/jonspags/disney-gross-income-analysis

https://www.kaggle.com/lily1917/disney-release-eda

https://www.kaggle.com/ekrembayar/marvel-universe-civil-war





Información de mi R-sesión:

- Session info ---------------------------------------------------------------
 setting  value                       
 version  R version 4.1.1 (2021-08-10)
 os       Windows 10 x64              
 system   x86_64, mingw32             
 ui       RTerm                       
 language (EN)                        
 collate  Spanish_Spain.1252          
 ctype    Spanish_Spain.1252          
 tz       Europe/Paris                
 date     2022-01-07                  

- Packages -------------------------------------------------------------------
 package     * version    date       lib source                        
 assertthat    0.2.1      2019-03-21 [1] CRAN (R 4.1.1)                
 backports     1.2.1      2020-12-09 [1] CRAN (R 4.1.1)                
 bit           4.0.4      2020-08-04 [1] CRAN (R 4.1.1)                
 bit64         4.0.5      2020-08-30 [1] CRAN (R 4.1.1)                
 broom         0.7.9      2021-07-27 [1] CRAN (R 4.1.1)                
 bslib         0.3.0      2021-09-02 [1] CRAN (R 4.1.1)                
 cellranger    1.1.0      2016-07-27 [1] CRAN (R 4.1.1)                
 cli           3.0.1      2021-07-17 [1] CRAN (R 4.1.1)                
 clipr         0.7.1      2020-10-08 [1] CRAN (R 4.1.1)                
 colorspace    2.0-2      2021-06-24 [1] CRAN (R 4.1.1)                
 crayon        1.4.1      2021-02-08 [1] CRAN (R 4.1.1)                
 crosstalk     1.1.1      2021-01-12 [1] CRAN (R 4.1.1)                
 curl          4.3.2      2021-06-23 [1] CRAN (R 4.1.1)                
 data.table    1.14.0     2021-02-21 [1] CRAN (R 4.1.1)                
 DBI           1.1.1      2021-01-15 [1] CRAN (R 4.1.1)                
 dbplyr        2.1.1      2021-04-06 [1] CRAN (R 4.1.1)                
 desc          1.4.0      2021-09-28 [1] CRAN (R 4.1.1)                
 details       0.2.1      2020-01-12 [1] CRAN (R 4.1.1)                
 digest        0.6.27     2020-10-24 [1] CRAN (R 4.1.1)                
 dplyr       * 1.0.7      2021-06-18 [1] CRAN (R 4.1.1)                
 ellipsis      0.3.2      2021-04-29 [1] CRAN (R 4.1.1)                
 evaluate      0.14       2019-05-28 [1] CRAN (R 4.1.1)                
 fansi         0.5.0      2021-05-25 [1] CRAN (R 4.1.1)                
 farver        2.1.0      2021-02-28 [1] CRAN (R 4.1.1)                
 fastmap       1.1.0      2021-01-25 [1] CRAN (R 4.1.1)                
 forcats     * 0.5.1      2021-01-27 [1] CRAN (R 4.1.1)                
 foreign       0.8-81     2020-12-22 [2] CRAN (R 4.1.1)                
 fs            1.5.0      2020-07-31 [1] CRAN (R 4.1.1)                
 generics      0.1.0      2020-10-31 [1] CRAN (R 4.1.1)                
 ggplot2     * 3.3.5      2021-06-25 [1] CRAN (R 4.1.1)                
 glue          1.4.2      2020-08-27 [1] CRAN (R 4.1.1)                
 gtable        0.3.0      2019-03-25 [1] CRAN (R 4.1.1)                
 haven         2.4.3      2021-08-04 [1] CRAN (R 4.1.1)                
 here          1.0.1      2020-12-13 [1] CRAN (R 4.1.1)                
 highr         0.9        2021-04-16 [1] CRAN (R 4.1.1)                
 hms           1.1.0      2021-05-17 [1] CRAN (R 4.1.1)                
 htmltools     0.5.2      2021-08-25 [1] CRAN (R 4.1.1)                
 htmlwidgets   1.5.4      2021-09-08 [1] CRAN (R 4.1.1)                
 httr          1.4.2      2020-07-20 [1] CRAN (R 4.1.1)                
 jquerylib     0.1.4      2021-04-26 [1] CRAN (R 4.1.1)                
 jsonlite      1.7.2      2020-12-09 [1] CRAN (R 4.1.1)                
 klippy      * 0.0.0.9500 2021-11-12 [1] Github (rlesur/klippy@378c247)
 knitr       * 1.34       2021-09-09 [1] CRAN (R 4.1.1)                
 labeling      0.4.2      2020-10-20 [1] CRAN (R 4.1.1)                
 lattice       0.20-44    2021-05-02 [2] CRAN (R 4.1.1)                
 lazyeval      0.2.2      2019-03-15 [1] CRAN (R 4.1.1)                
 lifecycle     1.0.0      2021-02-15 [1] CRAN (R 4.1.1)                
 lubridate     1.7.10     2021-02-26 [1] CRAN (R 4.1.1)                
 magick      * 2.7.3      2021-08-18 [1] CRAN (R 4.1.1)                
 magrittr    * 2.0.1      2020-11-17 [1] CRAN (R 4.1.1)                
 Matrix        1.3-4      2021-06-01 [2] CRAN (R 4.1.1)                
 mgcv          1.8-36     2021-06-01 [2] CRAN (R 4.1.1)                
 modelr        0.1.8      2020-05-19 [1] CRAN (R 4.1.1)                
 munsell       0.5.0      2018-06-12 [1] CRAN (R 4.1.1)                
 nlme          3.1-152    2021-02-04 [2] CRAN (R 4.1.1)                
 openxlsx      4.2.4      2021-06-16 [1] CRAN (R 4.1.1)                
 pillar        1.6.2      2021-07-29 [1] CRAN (R 4.1.1)                
 pkgconfig     2.0.3      2019-09-22 [1] CRAN (R 4.1.1)                
 plotly      * 4.9.4.1    2021-06-18 [1] CRAN (R 4.1.1)                
 png         * 0.1-7      2013-12-03 [1] CRAN (R 4.1.1)                
 purrr       * 0.3.4      2020-04-17 [1] CRAN (R 4.1.1)                
 R6            2.5.1      2021-08-19 [1] CRAN (R 4.1.1)                
 Rcpp          1.0.7      2021-07-07 [1] CRAN (R 4.1.1)                
 readr       * 2.0.1      2021-08-10 [1] CRAN (R 4.1.1)                
 readxl        1.3.1      2019-03-13 [1] CRAN (R 4.1.1)                
 reprex        2.0.1      2021-08-05 [1] CRAN (R 4.1.1)                
 rio         * 0.5.27     2021-06-21 [1] CRAN (R 4.1.1)                
 rlang         0.4.11     2021-04-30 [1] CRAN (R 4.1.1)                
 rmarkdown     2.11       2021-09-14 [1] CRAN (R 4.1.1)                
 rprojroot     2.0.2      2020-11-15 [1] CRAN (R 4.1.1)                
 rstudioapi    0.13       2020-11-12 [1] CRAN (R 4.1.1)                
 rvest         1.0.1      2021-07-26 [1] CRAN (R 4.1.1)                
 sass          0.4.0      2021-05-12 [1] CRAN (R 4.1.1)                
 scales        1.1.1      2020-05-11 [1] CRAN (R 4.1.1)                
 sessioninfo   1.1.1      2018-11-05 [1] CRAN (R 4.1.1)                
 stringi       1.7.4      2021-08-25 [1] CRAN (R 4.1.1)                
 stringr     * 1.4.0      2019-02-10 [1] CRAN (R 4.1.1)                
 tibble      * 3.1.4      2021-08-25 [1] CRAN (R 4.1.1)                
 tidyr       * 1.1.3      2021-03-03 [1] CRAN (R 4.1.1)                
 tidyselect    1.1.1      2021-04-30 [1] CRAN (R 4.1.1)                
 tidyverse   * 1.3.1      2021-04-15 [1] CRAN (R 4.1.1)                
 tzdb          0.1.2      2021-07-20 [1] CRAN (R 4.1.1)                
 utf8          1.2.2      2021-07-24 [1] CRAN (R 4.1.1)                
 vctrs         0.3.8      2021-04-29 [1] CRAN (R 4.1.1)                
 viridisLite   0.4.0      2021-04-13 [1] CRAN (R 4.1.1)                
 withr         2.4.2      2021-04-18 [1] CRAN (R 4.1.1)                
 xfun          0.26       2021-09-14 [1] CRAN (R 4.1.1)                
 xml2          1.3.2      2020-04-23 [1] CRAN (R 4.1.1)                
 yaml          2.2.1      2020-02-01 [1] CRAN (R 4.1.1)                
 zip           2.2.0      2021-05-31 [1] CRAN (R 4.1.1)                

[1] C:/Users/aleix/OneDrive/Documentos/R/win-library/4.1
[2] C:/Program Files/R/R-4.1.1/library






LS0tDQp0aXRsZTogIkFuw6FsaXNpcyBkZSBEaXNuZXkgeSBNYXJ2ZWwiDQpzdWJ0aXRsZTogIkFsZWl4YW5kcmEgQmxhc2NvIEdhcmNpYShhYmxhc2dhM0BhbHVtbmkudXYuZXMpIiAjLSBwb25nbyB0w7ogbm9tYnJlIGFow60gcGFyYSBxIGFwYXJlemNhIG3DoXMgZ3JhbmRlIHEgZWwgZGUgbGEgVVYNCmF1dGhvcjogIlVuaXZlcnNpdGF0IGRlIFZhbMOobmNpYSINCmRhdGU6ICJEaWNpZW1icmUgZGUgMjAyMSAoYWN0dWFsaXphZG8gZWwgYHIgZm9ybWF0KFN5cy50aW1lKCksICclZC0lbS0lWScpYCkiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6DQogICAgI2NzczogIi4vYXNzZXRzL215X2Nzc19maWxlLmNzcyINCiAgICB0aGVtZTogcGFwZXINCiAgICBoaWdobGlnaHQ6IHRleHRtYXRlIA0KICAgIHRvYzogdHJ1ZQ0KICAgIHRvY19kZXB0aDogMyANCiAgICB0b2NfZmxvYXQ6IA0KICAgICAgY29sbGFwc2VkOiB0cnVlDQogICAgICBzbW9vdGhfc2Nyb2xsOiB0cnVlDQogICAgc2VsZl9jb250YWluZWQ6IHRydWUNCiAgICBudW1iZXJfc2VjdGlvbnM6IGZhbHNlDQogICAgZGZfcHJpbnQ6IGthYmxlDQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQ0KZWRpdG9yX29wdGlvbnM6IA0KICBjaHVua19vdXRwdXRfdHlwZTogY29uc29sZQ0KLS0tDQpgYGB7Y3NzLCBlY2hvID0gRkFMU0V9DQouY29sdW1ucyB7ZGlzcGxheTpmbGV4O30NCmgxLnRpdGxlIHtmb250LXNpemU6IDQwIHB4O2NvbG9yOiAJI0ZGRjVFRX0NCmgxIHtjb2xvcjoJCSNGRkY1RUU7IGZvbnQtc2l6ZTogMzBweCA7Zm9udC1mYW1pbHk6IEFyaWFsIEJsYWNrfQ0KaDJ7Y29sb3I6IAkjRkZGNUVFOyBmb250LXNpemU6IDIwcHg7IGZvbnQtZmFtaWx5OiBBcmlhbH0NCmJvZHkgeyBiYWNrZ3JvdW5kLWNvbG9yOiAjRkY2MzQ3fQ0KYSB7Y29sb3I6ICMwMTAxMDE7fQ0KLmxpc3QtZ3JvdXAtaXRlbS5hY3RpdmUsIC5saXN0LWdyb3VwLWl0ZW0uYWN0aXZlOmZvY3VzLCAubGlzdC1ncm91cC1pdGVtLmFjdGl2ZTpob3ZlciB7DQogICAgei1pbmRleDogMjsNCiAgICBjb2xvcjogOw0KICAgIGJhY2tncm91bmQtY29sb3I6ICNjNDM0MmQ7DQogICAgYm9yZGVyLWNvbG9yOiBwYWxlcmVkOw0KfQ0KLm5hdi1waWxscyA+IGxpLmFjdGl2ZSA+IGEsIC5uYXYtcGlsbHMgPiBsaS5hY3RpdmUgPiBhOmhvdmVyLCAubmF2LXBpbGxzID4gbGkuYWN0aXZlID4gDQpgYGANCg0KDQpgYGB7ciBwYWNrYWdlcy1zZXR1cCwgaW5jbHVkZSA9IEZBTFNFfQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KGtsaXBweSkgICMtIHJlbW90ZXM6Omluc3RhbGxfZ2l0aHViKCJybGVzdXIva2xpcHB5IikNCmxpYnJhcnkoa25pdHIpDQpgYGANCg0KYGBge3IgY2h1bmstc2V0dXAsIGluY2x1ZGUgPSBGQUxTRX0NCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSwgZXZhbCA9IFRSVUUsIG1lc3NhZ2UgPSBGQUxTRSwgd2FybmluZyA9IEZBTFNFLCANCiAgICAgICAgICAgICAgICAgICAgICAjcmVzdWx0cyA9ICJob2xkIiwNCiAgICAgICAgICAgICAgICAgICAgICBjYWNoZSA9IEZBTFNFLCBjYWNoZS5wYXRoID0gIi9jYWNoZXMvIiwgY29tbWVudCA9ICIjPiIsDQogICAgICAgICAgICAgICAgICAgICAgI2ZpZy53aWR0aCA9IDcsICNmaWcuaGVpZ2h0PSA3LCAgIA0KICAgICAgICAgICAgICAgICAgICAgICNvdXQud2lkdGggPSA3LCBvdXQuaGVpZ2h0ID0gNywNCiAgICAgICAgICAgICAgICAgICAgICBjb2xsYXBzZSA9IFRSVUUsICBmaWcuc2hvdyA9ICJob2xkIiwNCiAgICAgICAgICAgICAgICAgICAgICBmaWcuYXNwID0gMC42MjgsIG91dC53aWR0aCA9ICI3NSUiLCBmaWcuYWxpZ24gPSAiY2VudGVyIikNCmtuaXRyOjpvcHRzX2NodW5rJHNldChkZXYgPSAicG5nIiwgZGV2LmFyZ3MgPSBsaXN0KHR5cGUgPSAiY2Fpcm8tcG5nIikpDQpgYGANCg0KDQpgYGB7ciBvcHRpb25zLXNldHVwLCBpbmNsdWRlID0gRkFMU0V9DQpvcHRpb25zKHNjaXBlbiA9IDk5OSkgIy0gcGFyYSBxdWl0YXIgbGEgbm90YWNpw7NuIGNpZW50w61maWNhDQpvcHRpb25zKCJ5YW1sLmV2YWwuZXhwciIgPSBUUlVFKSANCmBgYA0KDQoNCmBgYHtyIGtsaXBweSwgZWNobyA9IEZBTFNFfQ0Ka2xpcHB5OjprbGlwcHkocG9zaXRpb24gPSBjKCJ0b3AiLCAicmlnaHQiKSkgIy0gcmVtb3Rlczo6aW5zdGFsbF9naXRodWIoInJsZXN1ci9rbGlwcHkiKQ0KYGBgDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKQ0KbGlicmFyeShyaW8pDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShtYWdyaXR0cikNCmxpYnJhcnkocG5nKQ0KbGlicmFyeShncmlkKQ0KbGlicmFyeShtYWdpY2spDQpsaWJyYXJ5KHBsb3RseSkgDQpgYGANCjxociBjbGFzcz0ibGluZWEtYmxhY2siPg0KDQo8IS0tIEVsIHDDoXJyYWZvIGRlIGFiYWpvIGhhcyBkZSBkZWphcmxvIGNhc2kgaWd1YWwsIHNvbG8gSEFTIGRlIFNVU1RJVFVJUiAicGVyZXpwNDQiIHBvciB0dSB1c3VhcmlvIGRlIEdpdGh1Yi0tPg0KVHJhYmFqbyBlbGFib3JhZG8gcGFyYSBsYSBhc2lnbmF0dXJhICJQcm9ncmFtYWNpw7NuIHkgbWFuZWpvIGRlIGRhdG9zIGVuIGxhIGVyYSBkZWwgQmlnIERhdGEiIGRlIGxhIFVuaXZlcnNpdGF0IGRlIFZhbMOobmNpYSBkdXJhbnRlIGVsIGN1cnNvIDIwMjEtMjAyMi4gRWwgcmVwbyBkZWwgdHJhYmFqbyBlc3TDoSBbYXF1w61dKGh0dHBzOi8vZ2l0aHViLmNvbS9BbGVpeGFuZHJhQi90cmFiYWpvX0JpZ0RhdGEpe3RhcmdldD0iX2JsYW5rIn0uIA0KDQo8IS0tIEVsIHDDoXJyYWZvIGRlIGFiYWpvIGhhcyBkZSBkZWphcmxvIGV4YWN0YW1lbnRlIGlndWFsLCBOTyBIQVMgREUgQ0FNQklBUiBOQURBLS0+DQoNCkxhIHDDoWdpbmEgd2ViIGRlIGxhIGFzaWduYXR1cmEgeSBsb3MgdHJhYmFqb3MgZGUgbWlzIGNvbXBhw7Flcm9zIHB1ZWRlbiB2ZXJzZSBbYXF1w61dKGh0dHBzOi8vcGVyZXpwNDQuZ2l0aHViLmlvL2ludHJvLWRzLTIxLTIyLXdlYi8wNy10cmFiYWpvcy5odG1sKXt0YXJnZXQ9Il9ibGFuayJ9Lg0KDQoNCjxociBjbGFzcz0ibGluZWEtcmVkIj4NCg0KIyBbMS4gSW50cm9kdWNjacOzbl17LnZlcmRlY2l0b30NCg0KIVtMb2dvIERpc25leV0oLi9pbWFnZW5lcy9sb2dvLmpwZykNCg0KRXN0ZSB0cmFiYWpvIGVzIHVuIGFuw6FsaXNpcyBkZSB1bmEgZGUgbGFzIGVtcHJlc2FzIG3DoXMgZ3JhbmRlcyBkZSBhbmltYWNpw7NuIGFjdHVhbG1lbnRlLCoqVGhlIFdhbHQgRGlzbmV5IENvbXBhbnkgbyBEaXNuZXkqKi4gU2UgZnVuZG8gZW4gMTkyMyBkZSBsYSBtYW5vIGRlIFdhbHQgRGluc2V5IHkgUm95IE8uIERpc25leS4gDQoNCkVzdGEgZW1wcmVzYSBlbiBsYSBhY3R1YWxpZGFkIG5vIHNvbG8gcHJvZHVjZSBwZWzDrWN1bGFzIGRlIGFuaW1hY2nDs24sIHRpZW5lIHN1cyBwcm9waWFzIHRpZW5kYWQgZGUgY29tZXJjaW8gKCoqRGlzbmV5U3RvcmUqKiksIHN1IHByb3BpYSBwbGF0YWZvcm1hIGRlIHN0cmVhbWluZyAoKipEaXNuZXkrKiopIHkgc3VzIHByb3Bpb3MgcGFycXVlcyBkZSBhdHJhY2Npb25lcyAoKipEaXNuZXlMYW5kIFBhcmlzKiosICoqRGlzbmV5IE9ybmFsZG8qKiwgZXRjKS4gDQoNCkFkZW3DoXMgZGljaGEgZW1wcmVzYSBlc3RhIGZvcm1hZGEgcG9yIGRpZmVyZW50ZXMgZnJhbnF1aWNpYXMgZGUgY2luZSBxdWUgZHVyYW50ZSB2YXJpb3MgYcOxb3MgRGlzbmV5IGhhIGNvbXByYWRvLiBFc3RhcyBzb246IFdhbHQgRGlzbmV5IFBpY3R1cmVzLCBQaXhhciBBbmltYXRpb24gU3R1ZGlvcywgTWFydmVsIFN0dWRpb3MsIEx1Y2FzZmlsbSwgMjB0aCBDZW50dXJ5IFN0dWRpb3MsU2VhcmNobGlnaHQgUGljdHVyZXMsIFRoZSBNdXBwZXRzLg0KDQpFbiBlc3RlIHRyYWJham8sIHRhbWJpw6luIGFuYWxpemFyZW1vcyB1bmEgZGUgZXN0YXMgZW1wcmVzYXMsIGVuIHBhcnTDrWN1bGFyLCBsYSBxdWUgZXN0YSBtw6FzIGVuZm9jYWRhIGEgbG9zIHN1cGVyaGVyb2VzLCBNYXJ2ZWwuIA0KDQohW0VtcHJlc2FzIERpc25leV0oLi9pbWFnZW5lcy9lbXByZXNhc19kaXNuZXkuanBlZykNCjxicj4NCg0KDQojIDIuIERhdG9zDQoNCkxvcyBkYXRvcyBxdWUgc2UgdmFuIGEgdXRpbGl6YXIgZHVyYW50ZSBlbCB0cmFiYWpvIGhhbiBzaWRvIHNhY2Fkb3MgZGUgKipLYWdnbGUqKiB5ICoqR2l0SHViKiosIGVuIGxhIGJpYmxpb2dyYWZpYSBzZSBlbmN1ZW50cmEgZWwgbGluayBkaXJlY3RvLg0KDQoNCg0KIyMgMi4xLiBQcm9jZXNhbmRvIGxvcyBkYXRvcw0KDQpFbCB0cmFiYWpvIHNlIGhhIGVzY3JpdG8gc29icmUgKio0IGRhdGFmcmFtZXMqKi4gDQoNClVubyBkZSBlbGxvcyBlbmdsb2JhIHRvZG9zIGxvcyBkYXRvcyBkZSBEaXNuZXkgeSBsb3Mgb3Ryb3MgdHJlcyBlbmdsb2JhbiBsb3MgZGF0b3MgZGUgTWFydmVsLg0KDQpFbCBwcmltZXJvIGxsYW1hZG8gKionYWEnKiogdGllbmUgNiBjb2x1bW5hcyB5IDU3OSBvYnNlcnZhY2lvbmVzLiBFc3RlIGVzIGVsIHF1ZSBlbmdsb2JhIGxvcyBkYXRvcyBkZSAqKkRpc25leSoqDQoNCkVsIHNlZ3VuZG8gKionYmInKiogdGllbmUgOSBjb2x1bW5hcyB5IDU5NSBvYnNlcnZhY2lvbmVzLiANCg0KRWwgdGVyY2VybyAqKidjYycqKiB0aWVuZSAzOTY0NiBvYnNlcnZhY2lvbmVzIHkgMTIgdmFyaWFibGVzLg0KDQpQb3Igw7psdGltbywgZWwgKionZGQnKiogdGllbmUgMTYzNzYgb2JzZXJ2YWNpb25lcyB5IDEzIHZhcmlhYmxlcy4NCg0KRXN0w6FzIHRyZXMgw7psdGltYXMgZW5nbG9iYW4gbG9zIGRhdG9zIGRlIE1hcnZlbC4NCg0KDQpgYGB7ciwgaW5jbHVkZSA9IFRSVUUsIGVjaG89VFJVRSwgd2FybmluZz1GQUxTRX0NCg0KZGF0b3MxIDwtIGhlcmU6OmhlcmUoImRhdG9zc3MiLCAiZGlzbmV5X21vdmllcy5jc3YiKQ0KDQphYSA8LSByaW86OmltcG9ydChkYXRvczEpIA0KDQpkYXRvczIgPC0gaGVyZTo6aGVyZSgiZGF0b3NzcyIsICJjaGFyY3RlcnNfc3RhdHNfYS5jc3YiKQ0KDQpiYiA8LSByaW86OmltcG9ydChkYXRvczIpDQoNCg0KZGF0b3MzIDwtIGhlcmU6OmhlcmUoImRhdG9zc3MiLCAibWFydmVscGVyc29uYWplcy5jc3YiKQ0KDQpjYyA8LSByaW86OmltcG9ydChkYXRvczMpDQoNCmRhdG9zNCA8LSBoZXJlOjpoZXJlKCJkYXRvc3NzIiwgIm1hcnZlbHdpa2kuY3N2IikNCg0KZGQgPC0gcmlvOjppbXBvcnQoZGF0b3M0KQ0KDQpgYGANCg0KVW5hIHZleiBhYmllcnRvcyBsb3MgZGF0b3MsIGVtcGV6YW1vcyBjb24gZWwgYW7DoWxpc2lzIGRlIGxhIHByaW1lcmEgY29tcGHDscOtYSwgRGlzZW55Lg0KDQo8YnI+DQoNCiMjIDIuMiDCv0N1w6FudGFzIHBlbMOtY3VsYXMgdGllbmUgRGlzbmV5IGRlIGRpc3RpbnRvcyBnw6luZXJvcz8NCg0KDQpgYGB7ciwgaW5jbHVkZSA9IEZBTFNFLCBlY2hvPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KDQogYXR0YWNoKGFhKQ0KaGVhZChhYSwgbj01KQ0Kc3RyKGFhKQ0KDQpgYGANCg0KYGBge3IsIGluY2x1ZGUgPSBUUlVFLCBlY2hvPVRSVUUsIHdhcm5pbmc9RkFMU0V9DQphYSAlPiUgY291bnQoZ2VucmUpICU+JSBhcnJhbmdlKC1uKSAlPiUgDQogZ2dwbG90KGFlcyhyZW9yZGVyKGdlbnJlLG4pLG4pKSArIGdlb21fY29sKGFlcyhmaWxsPWdlbnJlKSkgKyBjb29yZF9mbGlwKCkgKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSArIA0KICB5bGFiKCJOw7ptZXJvIGRlIHBlbMOtY3VsYXMiKSArIHhsYWIoIkfDqW5lcm8iKSArDQogIGdlb21fdGV4dChhZXMobGFiZWw9biksIHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKHdpZHRoPTEpLCBoanVzdD0xKSArDQogIGdndGl0bGUoIk7Dum1lcm8gZGUgcGVsaWN1bGFzIHNlZ8O6biBzdSBnZW5lcm8iKQ0KDQpgYGANCkFudGUgZWwgZ3LDoWZpY28gZm9ybWFkbywgcG9kZW1vcyBkaWN0YW1pbmFyIHF1ZSBlbCBnw6luZXJvIHF1ZSBkw7NtaW5hbiBsYXMgcGVsw61jdWxhcyBEaXNuZXkgZXMgbGEgKipjb21lZGlhKiogY29uIDE4Mi4gU2VndWlkbyBwb3IgZWwgc2VndW5kbyBnw6lybmVybyBkZSAqKkF2ZW50dXJhcyoqIGNvbiAxMjkgcGVsw61jdWxhcy4gRW4gZWwgw7psdGltbyBwdWVzdG8sIHRlbmVtb3MgZWwgZ8OpbmVybyBkZSAqKlBlcmZvcm1hbmNlKiogZWwgY3VhbCBEaXNuZXkgbmFkYSBtw6FzIGhhIGhlY2hvIGRvcyBwZWzDrWN1bGFzLiANCjxicj4NCg0KIyMgMi4zIMK/UXXDqSAxMCBwZWzDrWN1bGFzIHNvbiBsYXMgcXVlIG3DoXMgYmVuZWZpY2lvcyB0aWVuZW4/DQpgYGB7ciwgaW5jbHVkZSA9IFRSVUUsIGVjaG89VFJVRSwgd2FybmluZz1GQUxTRX0NCnRvcF8xMF9kaXNuZXkgPC0gYWEgJT4lDQogIGFycmFuZ2UoZGVzYyh0b3RhbF9ncm9zcykpICU+JQ0KICBoZWFkKDEwKSANCg0KIHRvcF8xMF9kaXNuZXlfcGxvdCA8LSBnZ3Bsb3QodG9wXzEwX2Rpc25leSkgKyBnZW9tX2NvbChkYXRhID0gdG9wXzEwX2Rpc25leSwgbWFwcGluZz1hZXMoeT1tb3ZpZV90aXRsZSwgeD10b3RhbF9ncm9zcywgY29sb3IgPSBtb3ZpZV90aXRsZSkpICsgbGFicyh0aXRsZT0iVE9QIDEwIHBlbMOtY3VsYXMgZGUgRGlzbmV5IiwgeT0iVMOtdHVsb3MiLCB4PSJJbmdyZXNvcyBCcnV0b3MiKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpDQoNCiBnZ3Bsb3RseSh0b3BfMTBfZGlzbmV5X3Bsb3QpDQpgYGANClNlZ8O6biBub3MgbXVlc3RyYSB0YW50byBlbCBncsOhZmljbyBjb21vIGxhIHRhYmxhIHF1ZSBoZW1vcyBvYnRlbmlkbywgbGEgcGVsw61jdWxhIHF1ZSBtw6FzICoqSW5ncmVzb3MgQnJ1dG9zKiogaGEgb2J0ZW5pZG8gYSBsbyBsYXJnbyBkZSBsYSBoaXN0b3JpYSBkZSBsYSBjb21wYcOxw61hIGVzICoqU3RhciBXYXJzIEVwLiBWSUk6VGhlIEdvcmNlIEF3YWtlbioqIGRlIGxhIGZpcm1hIEx1Y2FzIEZpbG1zLCBjb24gdW4gdG90YWwgZGUgOTM2NjY2MjIyNSBkZSBkw7NsYXJlcy4gU2VndWlkYW1lbnRlLCB0ZW5kcsOtYW1vcyAqKlRoZSBBdmVuZ2VycyoqIGRlIGxhIGZpcm1hIE1hcnZlbCBjb24gdW4gdG90YWwgZGUgNjIzMjc5NTQ3IGTDs2xhcmVzLiBDb21vIMO6bHRpbWEgZGUgbGFzIG3DoXMgdGFxdWlsbGVyYXMsIGVuY29udHJhbW9zICoqQ2FwaXTDoW4gQW3DqXJpY2E6Q2l2aWwgV2FyKiosIHRhbWJpw6luIGRlIE1hcnZlbCwgY29uIHVuIHRvdGFsIGRlIDQwODA4NDM0OSBkw7NsYXJlcy4gDQoNCkVzIGN1cmlvc28gY8OzbW8gbmluZ3VuYSBkZSBsYXMgcGVsw61jdWxhcyBjb24gbcOhcyBpbmdyZXNvcyBkZSBEaXNuZXksIG5vIHNlYSBuaW5ndW5hIG9yaWdpbmFsIGRlIGxhIHByb3BpYSBlbXByZXNhLiBDb24gZXN0byBwb2RlbW9zIHJlZnV0YXIgbGEgaW1wb3J0YW5jaWEgZGUgbGFzIGZpcm1hcyBxdWUgY29uZm9ybWFyIGVsIHRvdGFsIGRlIGxhIGVtcHJlc2EgRGlzbmV5Lg0KDQohW0ZpbmFsIERpc25leV0oLi9pbWFnZW5lcy9wZXJzb25hamVzX2Rpc25leS5qcGcpDQo8YnI+DQoNCg0KIyAzIMK/UXXDqSBlcyBNYXJ2ZWw/IA0KDQpNYXJ2ZWwgV29ybGR3aWRlLCBJbmMuLCBjb25vY2lkYSBjb21vIE1hcnZlbCBDb21pY3MsIGVzIHVuYSBlZGl0b3JpYWwgZGUgaGlzdG9yaWV0YXMgZXN0YWRvdW5pZGVuc2UgY3JlYWRhIGVuIDE5MzkuICBQZXJvIG5vIGZ1ZSBoYXN0YSBsb3MgYcOxb3MgMTk5MCBxdWUgbGEgY29tcGHDscOtYSBubyBzZSBwb3NpY2lvbsOzIGNvbW8gdW5hIGRlIGxhcyBwcmluY2lwYWxlcyBlZGl0b3JpYWxlcyBkZSBjw7NtaWNzLiANCkVsIDMxIGRlIGFnb3N0byBkZSAyMDA5LCBUaGUgV2FsdCBEaXNuZXkgQ29tcGFueSBjb21wcsOzIE1hcnZlbCBFbnRlcnRhaW5tZW50IHBvciBjZXJjYSBkZSA0IDAwMCBtaWxsb25lcyBkZSBkw7NsYXJlcywgZnVzaW9uw6FuZG9zZSBjb24gZXN0YSBlbCAxIGRlIGVuZXJvIGRlIDIwMTAuDQoNCiFbTG9nbyBNYXJ2ZWxdKC4vaW1hZ2VuZXMvbG9nb19tYXJ2ZWwucG5nKQ0KDQo8YnI+DQoNCiMjIDMuMSDCv0N1YW50b3Mgc3VwZXJoZXJvZXMgbnVldm9zIGhheSBjYWRhIGHDsW8/DQpgYGB7ciwgaW5jbHVkZSA9IFRSVUUsIGVjaG89VFJVRSwgd2FybmluZz1GQUxTRX0NCnByaW1lcmFfYXBhcmljaW9uIDwtIGNjICU+JSANCiAgZ3JvdXBfYnkoWWVhcikgJT4lIA0KICBjb3VudCgpICU+JSANCiAgdW5ncm91cCgpIA0KICANCiBwcmltZXJhX2FwYXJfcGxvdCA8LSBnZ3Bsb3QocHJpbWVyYV9hcGFyaWNpb24sIGFlcyhZZWFyLCBuKSkgKyBnZW9tX2FyZWEoZmlsbCA9ICJibGFjayIsIGFwbGhhID0gMC41KSArZ2VvbV9zbW9vdGgoY29sb3IgPSAicmVkIikgKyBsYWJzKHRpdGxlPSLCv0N1w6FudG9zIG51ZXZvcyBzdXBlcmhlcm9lcyBoYXkgcG9yIGHDsW8/IiwgeT0iQ2FudGlkYWQiLCB4PSJBw7FvcyIpDQogIA0KZ2dwbG90bHkocHJpbWVyYV9hcGFyX3Bsb3QpDQpgYGANCg0KRnJlbnRlIGFsIGdyw6FmaWNvIHF1ZSB2ZW1vcywgcG9kZW1vcyBhZmlybWFyIHF1ZSBlbCBhw7FvIHF1ZSBtw6FzIHBlcnNvbmFqZXMgc2UgY3JlYXJvbiBkZSBsYSBpbmTDunN0cmlhIE1hcnZlbCBmdWUgZW4gKioxOTkzKiogY3JlYW5kb3NlIDEzMTcgbnVldm9zIHN1cGVyaGVyb2VzLiBZIHF1ZSBsYSDDqXBvY2EgbcOhcyBiYWphIGZ1ZSBhIHN1cyBpbmljaW9zIGVuICoqMTkzNSoqIGNyZWFuZG9zZSBzb2xvIDEgc3VwZXJoZXJvZXMuIExhIGzDrW5lYSByb2phIHJlcHJlc2VudGEgZWwgY3VtdWxvIGRlIHBlcnNvbmFqZXMgcXVlIHNlIGhhbiBpZG8gY3JlYW5kbywgdmllbmRvIHF1ZSBlbiBsYSBhY3R1YWxpZGFkIGVzZSBuw7ptZXJvIGhhIGRpc21pbnVpZG8gKHBhcnRlIGRlIGxvcyBzdXBlcmhlcm9lcyB5YSBubyBhcGFyZWNlbiBlbiBsb3MgY8OzbWljcykuDQoNCjxicj4NCg0KIyMgMy4yIMK/Q3XDoW50YXMgaG9tYnJlcyB5IG11amVyZXMgc3VwZXJoZXJvZXMgaGF5Pw0KDQpgYGB7ciwgaW5jbHVkZSA9IFRSVUUsIGVjaG89VFJVRSwgd2FybmluZz1GQUxTRX0NCmhvbWJyZXNfaGVyb2VzIDwtIGRkICU+JSANCiAgc2VsZWN0KFllYXIsIG5hbWUsIFNFWCkgJT4lIA0KICBncm91cF9ieShTRVgpICU+JSANCiAgZmlsdGVyKFNFWCA9PSAiTWFsZSBDaGFyYWN0ZXJzIikgJT4lIA0KICBzdW1tYXJpc2UoVG90YWxfSG9tYnJlcyA9IG4oKSkgDQoNCmhvbWJyZXNfaGVyb2VzDQogIA0KYGBgDQoNCmBgYHtyLCBpbmNsdWRlID0gVFJVRSwgZWNobz1UUlVFLCB3YXJuaW5nPUZBTFNFfQ0KbXVqZXJlc19oZXJvZXMgPC0gZGQgJT4lIA0KICBzZWxlY3QoWWVhciwgbmFtZSwgU0VYKSAlPiUgDQogIGdyb3VwX2J5KFNFWCkgJT4lIA0KICBmaWx0ZXIoU0VYID09ICJGZW1hbGUgQ2hhcmFjdGVycyIpICU+JSANCiAgc3VtbWFyaXNlKFRvdGFsX011amVyZXMgPSBuKCkpIA0KDQptdWplcmVzX2hlcm9lcw0KICANCmBgYA0KRW4gZXN0YXMgZG9zIHRhYmxhcyBwb2RlbW9zIHZlciwgZWwgbsO6bWVybyBkZSBob21icmUgeSBlbCBuw7ptZXJvIGRlIG11amVyZXMgcXVlIGFwYXJlY2VuIGEgbG8gbGFyZ28gZGUgbG9zIGPDs21pY3MuIFB1ZWRlbiBzZXIgdmlsbGFub3MgbyBzdXBlcmhlcm9lcy4gSGF5IHVuYSBjbGFyYSBkaWZlcmVuY2lhIGVudHJlIGxvcyBnw6luZXJvcyB5IHNhbGVuIGNsYXJhbWVudGUgZ2FuYW5kbyBsb3MgaG9tYnJlcy4NCg0KPGJyPg0KDQojIyAzLjMgQ3VhbGVzIHN1cGVyaGVyb2VzIGFwYXJlY2VuIG3DoXMgcG9yIGdlbmVyby4NCg0KDQpgYGB7ciwgaW5jbHVkZSA9IFRSVUUsIGVjaG89VFJVRSwgd2FybmluZz1GQUxTRX0NCm1heF9ob21icmVzIDwtIGRkICU+JSANCiAgc2VsZWN0KG5hbWUsIFNFWCwgQVBQRUFSQU5DRVMpICU+JSANCiAgZ3JvdXBfYnkoU0VYKSAlPiUgDQogIGZpbHRlcihTRVggPT0gIk1hbGUgQ2hhcmFjdGVycyIpICU+JSANCiAgaGVhZCgxNSkNCg0KZ2VuZXJvbV9wbG90IDwtIGdncGxvdChtYXhfaG9tYnJlcywgYWVzKG5hbWUsIEFQUEVBUkFOQ0VTLCBjb2xvciA9IG5hbWUpKSArDQogIGdlb21fcG9pbnQoKSArIHhsYWIoIm5vbWJyZXMiKSArICB0aGVtZSgNCiAgYXhpcy50ZXh0LnggPSBlbGVtZW50X2JsYW5rKCkpICsgbGFicyh0aXRsZT0iVG9wIDE1IFN1cGVyaGVyb2VzIGNvbiBtw6FzIGFwYXJpY2lvbmVzIiwgeT0iQXBhcmljaW9uZXMiLCB4PSIiKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpDQoNCg0KZ2dwbG90bHkoZ2VuZXJvbV9wbG90KQ0KYGBgDQpTZWfDum4gZWwgZ3LDoWZpY28sIGVsIHBlcnNvbmFqZSBob21icmUgcXVlIG3DoXMgaGEgYXBhcmVjaWRvIGEgbG8gbGFyZ28gZGUgbGEgaGlzdMOzcmlkYSBkZSBNYXJ2ZWwgZXMgKipTcGlkZXItTWFuKiogbyAqUGV0ZXIgUGFya2VyKiogZWwgY3VhbCBhcGFyZWNlIDQwNDMgdmVjZXMuIEVsIHNlZ3VuZG8gcGVyc29uYWplIG1hc2N1bGlubyBxdWUgbcOhcyBhcGFyZWNlIGVzICoqQ2FwaXRhbiBBbWVyaWNhKiogbyAqKlN0ZXZlbiBSb2dlcnMqKiwgZWwgY3VhbCBhcGFyZWNlIDMzNjAuIFkgZWwgw7psdGltbyBwZXJzb25hamUgcXVlIG3DoXMgYXBhcmljaW9uZXMgdGllbmUgZXMgKipTdGVwaGVuICpTdHJhbmdlKiogY29uIDEzMDcgYXBhcmljaW9uZXMuIA0KDQoNCmBgYHtyLCBpbmNsdWRlID0gVFJVRSwgZWNobz1UUlVFLCB3YXJuaW5nPUZBTFNFfQ0KbWF4X211amVyZXMgPC0gZGQgJT4lIA0KICBzZWxlY3QobmFtZSwgU0VYLCBBUFBFQVJBTkNFUykgJT4lIA0KICBncm91cF9ieShTRVgpICU+JSANCiAgZmlsdGVyKFNFWCA9PSAiRmVtYWxlIENoYXJhY3RlcnMiKSAlPiUgDQogIGhlYWQoMTUpDQoNCmdlbmVyb19wbG90IDwtIGdncGxvdChtYXhfbXVqZXJlcywgYWVzKG5hbWUsIEFQUEVBUkFOQ0VTLCBjb2xvciA9IG5hbWUpKSArDQogIGdlb21fcG9pbnQoKSArIHhsYWIoIm5vbWJyZXMiKSArICB0aGVtZSgNCiAgYXhpcy50ZXh0LnggPSBlbGVtZW50X2JsYW5rKCkpICsgbGFicyh0aXRsZT0iVG9wIDE1IFN1cGVyaGVyb2luYXMgY29uIG3DoXMgYXBhcmljaW9uZXMiLCB5PSJBcGFyaWNpb25lcyIsIHg9IiIpICsgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpDQoNCg0KZ2dwbG90bHkoZ2VuZXJvX3Bsb3QpDQpgYGANCkVuIGVsIGNhc28gZGUgbGFzIG11amVyZXMsIGxhIHF1ZSBtw6FzIGFwYXJlY2UgZXMgKipTdXNhbiBTdG9ybSoqIGRlIGxvcyA0IEbDoW50YXN0aWNvcywgbGEgY3VhbCBhcGFyZWNlIHVuIHRvdGFsIGRlIDE3MTMuIFNlZ3VpZGEgcG9yICoqT3Jvcm8gTXVucm9lKiogbyAqKlRvcm1lbnRhKiogIHF1ZSBhcGFyZWNlIDE1MTIgdmVjZXMuIExhIMO6bHRpbWEgbXVqZXIgcXVlIG3DoXMgYXBhcmljaW9uZXMgaGEgdGVuaWRvIGhhIHNpZG8gRWxpemFiZXRoIEJyYW50IGRlIFNwaWRlcm1hbiwgY29uIHVuIHRvdGFsIGRlIDU5OSBhcGFyaWNpb25lcy4NCg0KQ2FiZSBkZXN0YWNhciBxdWUgbGFzIG11amVyZXMgY29uIG1heW9yIGFwYXJpY2lvbmVzIHRpZW5lbiBjYXNpIGxhcyBtaXNtYXMgcXVlIGVsIHBlcnNvbmFqZSBob21icmUgY29uIG1lbm9zIGFwYXJpY2lvbmVzIGRlbCBncsOhZmljbyBhbnRlcmlvci4NCg0KPGJyPg0KDQojIyAzLjQgwr9DdcOhbGVzIHNvbiBsb3MgNSBzdXBlcmhlcm9lcyBtw6FzIHBvZGVyb3Nvcz8NCmBgYHtyLCBpbmNsdWRlID0gVFJVRSwgZWNobz1UUlVFLCB3YXJuaW5nPUZBTFNFfQ0KcG9kZXJlc19idWVub3MgPC0gYmIgJT4lIA0KICBzZWxlY3QoTmFtZSwgQWxpZ25tZW50LCBUb3RhbCkgJT4lIA0KICBncm91cF9ieShBbGlnbm1lbnQpICU+JSANCiAgIHNsaWNlX21heChUb3RhbCwgbiA9IDUpICU+JSANCiAgZmlsdGVyKCBBbGlnbm1lbnQgPT0gImdvb2QiKQ0KDQoNCnBvZGVyZXNfYnVlbm9zX3Bsb3QgPC0gZ2dwbG90KHBvZGVyZXNfYnVlbm9zLCBhZXMoeCA9IE5hbWUsIHkgPSBUb3RhbCwgZmlsbCA9IEFsaWdubWVudCkpICsNCiAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZG9kZ2UiKSsNCiAgY29vcmRfcG9sYXIoKSArIGdndGl0bGUoIkhlcm9lcyBtw6FzIHBvZGVyb3NvcyIpICsgdGhlbWUoDQogIGF4aXMudGV4dC55ID0gZWxlbWVudF9ibGFuaygpKSArIHlsYWIoIlBvZGVyZXMiKSArIHhsYWIoIk5vbWJyZXMiKQ0KDQpwb2RlcmVzX2J1ZW5vc19wbG90DQpgYGANCkFudGUgZXN0ZSBncsOhZmljbywgcG9kZW1vcyBkZXN0YWNhciBxdWUgZWwgc3VwZXJoZXJvZSBjb24gbcOhcyBwb2RlcmVzIGRlIE1hcnZlbCBlcyAqKlRob3IqKiwgc2VndWlkbyBwb3IgKlBob2VuaXgqIHkgdGVybWluYW5kbyBjb24gKlRoZSBXYXRjaGVyKi4NCg0KPGJyPg0KDQojIyAzLjUgwr9DdcOhbGVzIHNvbiBsb3MgNSB2aWxsYW5vcyBtw6FzIHBvZGVyb3Nvcz8NCmBgYHtyLCBpbmNsdWRlID0gVFJVRSwgZWNobz1UUlVFLCB3YXJuaW5nPUZBTFNFfQ0KcG9kZXJlc19tYWxvcyA8LSBiYiAlPiUgDQogIHNlbGVjdChOYW1lLCBBbGlnbm1lbnQsIFRvdGFsKSAlPiUgDQogIGdyb3VwX2J5KEFsaWdubWVudCkgJT4lIA0KICAgc2xpY2VfbWF4KFRvdGFsLCBuID0gNSkgJT4lIA0KICBmaWx0ZXIoIEFsaWdubWVudCA9PSAiYmFkIikNCg0KcG9kZXJlc19tYWxvc19wbG90IDwtIGdncGxvdChwb2RlcmVzX21hbG9zLCBhZXMoeCA9IE5hbWUsIHkgPSBUb3RhbCwgZmlsbCA9IEFsaWdubWVudCkpICsNCiAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZG9kZ2UiKSsNCiAgY29vcmRfcG9sYXIoKSArIGdndGl0bGUoIlZpbGxhbm9zIG3DoXMgcG9kZXJvc29zIikgKyB0aGVtZSgNCiAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X2JsYW5rKCkpICsgeWxhYigiUG9kZXJlcyIpICsgeGxhYigiTm9tYnJlcyIpDQoNCnBvZGVyZXNfbWFsb3NfcGxvdA0KYGBgDQpGcmVudGUgYWwgZ3LDoWZpY28sIHBvZGVtb3MgYWZpcm1hciBxdWUgKipEb3JtYW1tdSoqIGVzIGVsIHZpbGxhbm8gY29uIG3DoXMgcG9kZXJlcywgc2VndWlkbyBwb3IgKipNYWd1cyoqIHkgZWwgw7psdGltbyBzZXLDrWEgKipPbnNsYXVnaHQqKi4NCg0KIVtQZXJzb25hamVzIE1hcnZlbF0oLi9pbWFnZW5lcy9wZXJzb25hamVzX21hcnZlbC5qcGcpDQo8YnI+DQoNCiMgNC4gVHJhYmFqb3MgZW4gbG9zIHF1ZSB0ZSBoYXMgYmFzYWRvDQoNClBhcmEgbG9zIGFuw6FsaXNpcyBtb3N0cmFkb3MgZW4gbG9zIHRyYWJham9zIGRlIEdpdEh1YiBtZW5jaW9uYWRvcyBlbiBlbCBhcGFydGFkbyBkZSBiaWJsaW9ncsOhZmljYS4gDQoNCjxicj4NCg0KIyA1LiBCaWJsaW9ncmFmw61hDQoNCmh0dHBzOi8vd3d3LmthZ2dsZS5jb20vam9uc3BhZ3MvZGlzbmV5LWdyb3NzLWluY29tZS1hbmFseXNpcw0KDQpodHRwczovL3d3dy5rYWdnbGUuY29tL2xpbHkxOTE3L2Rpc25leS1yZWxlYXNlLWVkYQ0KDQpodHRwczovL3d3dy5rYWdnbGUuY29tL2VrcmVtYmF5YXIvbWFydmVsLXVuaXZlcnNlLWNpdmlsLXdhcg0KDQo8YnI+PGJyPg0KDQo8aHIgY2xhc3M9ImxpbmVhLXJlZCI+DQo8aHIgY2xhc3M9ImxpbmVhLXJlZCI+DQoNCg0KYGBge3IsIGVjaG8gPSBGQUxTRX0NCnNlc3Npb25pbmZvOjpzZXNzaW9uX2luZm8oKSAlPiUgZGV0YWlsczo6ZGV0YWlscyhzdW1tYXJ5ID0gJ0luZm9ybWFjacOzbiBkZSBtaSBSLXNlc2nDs246JykgDQpgYGANCg0KDQo8YnI+PGJyPg0KDQo8ZGl2IGNsYXNzPSJ0b2NpZnktZXh0ZW5kLXBhZ2UiIGRhdGEtdW5pcXVlPSJ0b2NpZnktZXh0ZW5kLXBhZ2UiIHN0eWxlPSJoZWlnaHQ6IDA7Ij48L2Rpdj4NCjxicj48YnI+DQoNCjxkaXYgY2xhc3M9InRvY2lmeS1leHRlbmQtcGFnZSIgZGF0YS11bmlxdWU9InRvY2lmeS1leHRlbmQtcGFnZSIgc3R5bGU9ImhlaWdodDogMDsiPjwvZGl2Pg0K