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 2020-2021. El repo del trabajo está aquí. La página web de la asignatura y los trabajos de mis compañeros pueden verse aquí.
1. Introducción
En este trabajo muestro la cantidad de Grand Slam ganados por los mejores jugadores de la historia del Tenis.Donde podremos ver que hay algunos jugadores igualados pero existe un claro dominio por parte de Rafael Nadal en Roland Garros. He decidido realizar este trabajo porque me apasiona el tenis desde muy pequeño y por ello, me resulta interesante dar a conocer los siguientes datos.
2. Datos
Códigos de datos importados
grand_slam_ganados<- read_excel("./datos/grand_slam.xlsx")
ranking_por_paises <- read_excel("./datos/ranking_por_paises.xlsx")
3. Ranking por jugadores
Hasta el momento, 54 tenistas han ganado al menos un Grand Slam en la era abierta.En la siguiente tabla, se destaca a los 13 jugadores que han tenido una mayor cantidad de Grand Slam a lo largo de la historia del tenis. Por un lado, se pueden observar nombres de jugadores actualmente en activo como Roger Federer y por otro lado, jugadores retirados como Boris Becker.
En la segunda pestaña, podemos observar en un gráfico de barras el ranking de Grand Slam. A un lado, el nombre de los tenistas y al otro, el total de Grand Slam conseguidos por cada jugador. La superioridad de Rafael Nadal sobre tierra batida es incuestionable. Mucho más cuando el terreno se acota a Roland Garros. En el Grand Slam francés ha ganado la mayor cifra de títulos que cualquier jugador haya ganado jamás en un mismo escenario. Y gracias a ello, ha conseguido igualarse a Roger Federer en cantidad de Grand Slam conseguidos hasta la fecha.
Posiciones
Pos.
|
Nombre
|
Total
|
Australia
|
Roland Garros
|
Wimbledon
|
USA
|
1
|
Roger Federer
|
20
|
6
|
1
|
8
|
5
|
2
|
Rafael Nadal
|
20
|
1
|
13
|
2
|
4
|
3
|
Novak Djokovic
|
17
|
8
|
1
|
5
|
3
|
4
|
Pete Sampras
|
14
|
2
|
0
|
7
|
5
|
5
|
Björn Borg
|
11
|
0
|
6
|
5
|
0
|
6
|
Ivan Lendl
|
8
|
2
|
3
|
0
|
3
|
7
|
Jimmy Connors
|
8
|
1
|
0
|
2
|
5
|
8
|
Andre Agassi
|
8
|
4
|
1
|
1
|
2
|
9
|
John McEnroe
|
7
|
0
|
0
|
3
|
4
|
10
|
Stefan Edberg
|
6
|
2
|
0
|
2
|
2
|
11
|
Boris Becker
|
6
|
2
|
0
|
3
|
1
|
12
|
John Newcombe
|
5
|
2
|
0
|
2
|
1
|
13
|
Rod Laver
|
5
|
1
|
1
|
2
|
1
|
Gráfica
4.Diferentes premios y superficies
Premios
Junto a los trofeos, los jugadores reciben un premio monetario al proclamarse campeones.
Los tenistas ganan alrededor de 40.000 euros por participar en una primera ronda de un Grand Slam, más del doble de lo que ingresan en una primera ronda de un torneo Masters 1.000 (siguiente campeonato en importancia), y los premios por ganar un grande son mucho mayores que en cualquier torneo de la temporada.
A pesar de que depende de la recaudación y del Grand Slam que se trate, los tenistas que se proclaman campeones en la final reciben un premio que oscila entre los 2,5-3 millones de euros.
Superficies
En la siguiente imagen tenemos los diferentes tipos de pistas existentes y su composición.
En primer lugar, tierra batida. Este tipo de pistas están hechas de esquisto, piedra y arcilla.
En segundo y cuarto lugar de la imagen tenemos las pistas duras o de cemento. Estos tipos de pistas evitan irregularidades en la trayectoria de la pelota y proporcionan un juego intermedio.
En tercer lugar, las pistas de hierba donde el césped es la superficie original del tenis. Se trata de una superficie rápida, de bote irregular y la menos utilizada. La construcción y mantenimiento de este tipo de superficies es costoso y complejo.
5. Mapas de los estadios
Los siguientes mapas nos muestran la ubicación de cada uno de los estadios a partir de sus coordenadas correspondientes.
En primer lugar, en el MAPA 1 he decidido agrupar Roland Garros que se ubica en el sector sudoccidental de París, en el XVI distrito y, Wimbledon que se encuentra en el All England Lawn Tennis y Croquet Club de Londres.
En segundo lugar, en el MAPA 2 ubico el USTA Billie Jean King National Tennis Center que está localizado en el Flushing Meadows-Corona Park, en el borough de Queens en Nueva York y es la sede del Abierto de los Estados Unidos.
En tercer lugar, en el MAPA 3 tenemos el Rod Laver Arena, un recinto multipropósito usado principalmente como estadio de tenis para el Abierto de Australia y que es parte del complejo del parque de Melbourne.
6. Top 4 mejores
En esta gráfica si deslizamos el ratón por las barras podemos observar más detalladamente la cantidad de torneos Wimbledon ganados por cada uno de los 4 mejores en el ranking de Grand Slam. Cada uno tiene una distinta tonalidad de azul dependiendo de la cantidad que hayan ganado. Sin embargo, su orden en la gráfica corresponde al total de Grand Slam ganados entre los citados anteriormente.
Además, en la parte superior de la gráfica tenemos varias opciones por si se quiere descargar la gráfica como una imagen con formato png, también hacer zoom, entre otras.
7. El punto más largo de la historia
Con 54 golpes este punto que disputaron Djokovic vs Nadal en el Us Open 2013 se convirtió en el más largo de la historia.
Rafa Nadal se proclamó campeón del US Open después de doblegar en cuatro sets a Novak Djokovic en la final. Se trataba del título número 60 de su carrera, su 13º Grand Slam y la segunda vez que se coronaba en Nueva York.
8. Ranking por países
En la siguiente tabla podemos consultar el top ten de países con más Grand Slams de la historia. Tenemos las cifras totales y a su vez, de manera más específica la cantidad ganada por cada país en cada uno de los torneos.
Vemos como USA se encuentra a día de hoy dominando con diferencia de los demás con un total de 51 títulos y predominio en las superficies de hierba(Wimbledon) y pista dura(USA y Australia) ganados por 12 tenistas.
Roland Garros es el único Grand Slam que se le resiste a USA gracias a los españoles que tienen un alto nivel en las superificies de tierra batida. Y es por ello que, España se encuentra en segundo lugar de la tabla con un total de 31 títulos pero lejos de alcanzar a USA.
Tabla y WordCloud
Ranking
|
País
|
Total
|
Australia
|
Roland Garros
|
Wimbledon
|
USA
|
Nº tenistas
|
1
|
USA
|
51
|
13
|
4
|
15
|
19
|
12
|
2
|
ESPAÑA
|
31
|
1
|
21
|
3
|
6
|
8
|
3
|
SUECIA
|
25
|
6
|
9
|
7
|
3
|
4
|
4
|
SUIZA
|
23
|
7
|
2
|
8
|
6
|
2
|
5
|
AUSTRALIA
|
20
|
6
|
2
|
6
|
6
|
7
|
6
|
SERBIA
|
17
|
8
|
1
|
5
|
3
|
1
|
7
|
REPÚBLICA CHECA
|
12
|
3
|
5
|
1
|
3
|
3
|
8
|
ALEMANIA
|
7
|
2
|
0
|
4
|
1
|
2
|
9
|
ARGENTINA
|
6
|
2
|
2
|
0
|
2
|
3
|
10
|
RUSIA
|
4
|
2
|
1
|
0
|
1
|
2
|
9.Conclusión
Comparando las dos tablas, entre jugadores y países cabe destacar que los tres primeros jugadores y que actualmente están activamente jugando, han aportado gran parte de los títulos de sus respectivos países a lo largo de su carrera tenística.
Aunque podemos observar a Rafael Nadal y Roger Federer igualados en el ranking de Grand Slam, los duelos entre el español y el suizo vienen de lejos. Desde aquel primer partido en el Master 1000 de Miami en 2004, se han enfrentado en 40 ocasiones con un balance positivo para Nadal (24-16). Aunque el suizo cuenta con más títulos totales, Rafael Nadal le ha alcanzado en Grand Slams y ha conseguido más Máster 1000.
“EL éxito no es la victoria, sino todo lo que has peleado por ganar”. Rafael Nadal
10. Referencias
Para acabar este chunk para incluir tu session info
:
sessioninfo::session_info() %>% details::details(summary = 'current session info')
current session info
- Session info ---------------------------------------------------------------
setting value
version R version 4.0.2 (2020-06-22)
os Windows 10 x64
system x86_64, mingw32
ui RTerm
language (EN)
collate Spanish_Spain.1252
ctype Spanish_Spain.1252
tz Europe/Paris
date 2021-01-11
- Packages -------------------------------------------------------------------
package * version date lib source
assertthat 0.2.1 2019-03-21 [1] CRAN (R 4.0.3)
backports 1.2.1 2020-12-09 [1] CRAN (R 4.0.2)
broom 0.7.2 2020-10-20 [1] CRAN (R 4.0.3)
cellranger 1.1.0 2016-07-27 [1] CRAN (R 4.0.3)
cli 2.2.0 2020-11-20 [1] CRAN (R 4.0.3)
clipr 0.7.1 2020-10-08 [1] CRAN (R 4.0.3)
colorspace 2.0-0 2020-11-11 [1] CRAN (R 4.0.3)
crayon 1.3.4 2017-09-16 [1] CRAN (R 4.0.3)
crosstalk 1.1.0.1 2020-03-13 [1] CRAN (R 4.0.3)
curl 4.3 2019-12-02 [1] CRAN (R 4.0.3)
data.table 1.13.4 2020-12-08 [1] CRAN (R 4.0.3)
DBI 1.1.0 2019-12-15 [1] CRAN (R 4.0.3)
dbplyr 2.0.0 2020-11-03 [1] CRAN (R 4.0.3)
desc 1.2.0 2018-05-01 [1] CRAN (R 4.0.3)
details 0.2.1 2020-01-12 [1] CRAN (R 4.0.3)
digest 0.6.27 2020-10-24 [1] CRAN (R 4.0.3)
dplyr * 1.0.2 2020-08-18 [1] CRAN (R 4.0.3)
ellipsis 0.3.1 2020-05-15 [1] CRAN (R 4.0.3)
evaluate 0.14 2019-05-28 [1] CRAN (R 4.0.3)
extrafont 0.17 2014-12-08 [1] CRAN (R 4.0.3)
extrafontdb 1.0 2012-06-11 [1] CRAN (R 4.0.3)
fansi 0.4.1 2020-01-08 [1] CRAN (R 4.0.3)
farver 2.0.3 2020-01-16 [1] CRAN (R 4.0.3)
forcats * 0.5.0 2020-03-01 [1] CRAN (R 4.0.3)
fs 1.5.0 2020-07-31 [1] CRAN (R 4.0.3)
gdtools 0.2.2 2020-04-03 [1] CRAN (R 4.0.3)
generics 0.1.0 2020-10-31 [1] CRAN (R 4.0.3)
gganimate * 1.0.7 2020-10-15 [1] CRAN (R 4.0.3)
ggplot2 * 3.3.2 2020-06-19 [1] CRAN (R 4.0.3)
gifski 0.8.6 2018-09-28 [1] CRAN (R 4.0.3)
glue 1.4.2 2020-08-27 [1] CRAN (R 4.0.3)
gridExtra 2.3 2017-09-09 [1] CRAN (R 4.0.3)
gt * 0.2.2 2020-12-14 [1] Github (rstudio/gt@bae32f4)
gtable 0.3.0 2019-03-25 [1] CRAN (R 4.0.3)
haven 2.3.1 2020-06-01 [1] CRAN (R 4.0.3)
here 1.0.1 2020-12-13 [1] CRAN (R 4.0.2)
highr 0.8 2019-03-20 [1] CRAN (R 4.0.3)
hms 0.5.3 2020-01-08 [1] CRAN (R 4.0.3)
hrbrthemes * 0.8.0 2020-03-06 [1] CRAN (R 4.0.3)
htmltools 0.5.0 2020-06-16 [1] CRAN (R 4.0.3)
htmlwidgets 1.5.3 2020-12-10 [1] CRAN (R 4.0.3)
httr 1.4.2 2020-07-20 [1] CRAN (R 4.0.3)
jsonlite 1.7.2 2020-12-09 [1] CRAN (R 4.0.3)
kableExtra * 1.3.1 2020-10-22 [1] CRAN (R 4.0.3)
klippy * 0.0.0.9500 2020-12-17 [1] Github (rlesur/klippy@378c247)
knitr * 1.30 2020-09-22 [1] CRAN (R 4.0.3)
labeling 0.4.2 2020-10-20 [1] CRAN (R 4.0.3)
lazyeval 0.2.2 2019-03-15 [1] CRAN (R 4.0.3)
leaflet * 2.0.3 2019-11-16 [1] CRAN (R 4.0.3)
lifecycle 0.2.0 2020-03-06 [1] CRAN (R 4.0.3)
lubridate 1.7.9.2 2020-11-13 [1] CRAN (R 4.0.3)
magrittr 2.0.1 2020-11-17 [1] CRAN (R 4.0.3)
modelr 0.1.8 2020-05-19 [1] CRAN (R 4.0.3)
munsell 0.5.0 2018-06-12 [1] CRAN (R 4.0.3)
pillar 1.4.7 2020-11-20 [1] CRAN (R 4.0.3)
pkgconfig 2.0.3 2019-09-22 [1] CRAN (R 4.0.3)
plotly * 4.9.2.1 2020-04-04 [1] CRAN (R 4.0.3)
png 0.1-7 2013-12-03 [1] CRAN (R 4.0.3)
prettyunits 1.1.1 2020-01-24 [1] CRAN (R 4.0.3)
progress 1.2.2 2019-05-16 [1] CRAN (R 4.0.3)
purrr * 0.3.4 2020-04-17 [1] CRAN (R 4.0.3)
R6 2.5.0 2020-10-28 [1] CRAN (R 4.0.3)
Rcpp 1.0.5 2020-07-06 [1] CRAN (R 4.0.3)
reactable * 0.2.3 2020-10-04 [1] CRAN (R 4.0.3)
readr * 1.4.0 2020-10-05 [1] CRAN (R 4.0.3)
readxl * 1.3.1 2019-03-13 [1] CRAN (R 4.0.3)
reprex 0.3.0 2019-05-16 [1] CRAN (R 4.0.3)
rlang 0.4.9 2020-11-26 [1] CRAN (R 4.0.3)
rmarkdown 2.5 2020-10-21 [1] CRAN (R 4.0.3)
rprojroot 2.0.2 2020-11-15 [1] CRAN (R 4.0.3)
rstudioapi 0.13 2020-11-12 [1] CRAN (R 4.0.3)
Rttf2pt1 1.3.8 2020-01-10 [1] CRAN (R 4.0.3)
rvest 0.3.6 2020-07-25 [1] CRAN (R 4.0.3)
scales 1.1.1 2020-05-11 [1] CRAN (R 4.0.3)
sessioninfo 1.1.1 2018-11-05 [1] CRAN (R 4.0.3)
stringi 1.5.3 2020-09-09 [1] CRAN (R 4.0.3)
stringr * 1.4.0 2019-02-10 [1] CRAN (R 4.0.3)
systemfonts 0.3.2 2020-09-29 [1] CRAN (R 4.0.3)
tibble * 3.0.4 2020-10-12 [1] CRAN (R 4.0.3)
tidyr * 1.1.2 2020-08-27 [1] CRAN (R 4.0.3)
tidyselect 1.1.0 2020-05-11 [1] CRAN (R 4.0.3)
tidyverse * 1.3.0 2019-11-21 [1] CRAN (R 4.0.3)
tweenr 1.0.1 2018-12-14 [1] CRAN (R 4.0.3)
vctrs 0.3.5 2020-11-17 [1] CRAN (R 4.0.3)
vembedr * 0.1.4 2020-10-10 [1] CRAN (R 4.0.3)
viridis * 0.5.1 2018-03-29 [1] CRAN (R 4.0.3)
viridisLite * 0.3.0 2018-02-01 [1] CRAN (R 4.0.3)
webshot 0.5.2 2019-11-22 [1] CRAN (R 4.0.3)
withr 2.3.0 2020-09-22 [1] CRAN (R 4.0.3)
wordcloud2 * 0.2.1 2018-01-03 [1] CRAN (R 4.0.3)
xfun 0.19 2020-10-30 [1] CRAN (R 4.0.3)
xml2 1.3.2 2020-04-23 [1] CRAN (R 4.0.3)
yaml 2.2.1 2020-02-01 [1] CRAN (R 4.0.3)
[1] C:/Users/Antonio/Documents/R/win-library/4.0
[2] C:/Program Files/R/R-4.0.2/library
LS0tDQp0aXRsZTogPGNlbnRlcj48Rk9OVCBDT0xPUj0iZGFya2JsdWUiPkdSQU5EIFNMQU0gVEVOSVM8L0ZPTlQ+PC9jZW50ZXI+DQpzdWJ0aXRsZTogIkpvc8OpIE1hcsOtYSBGZXJuw6FuZGV6IChqb2ZlcmNhckBhbHVtbmkudXYuZXMpIiANCmF1dGhvcjogIlVuaXZlcnNpdGF0IGRlIFZhbMOobmNpYSINCmRhdGU6ICJEaWNpZW1icmUgZGUgMjAyMCAoYWN0dWFsaXphZG8gZWwgYHIgZm9ybWF0KFN5cy50aW1lKCksICclZC0lbS0lWScpYCkiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6DQogICAgI2NzczogIi4vYXNzZXRzL215X2Nzc19maWxlLmNzcyINCiAgICB0aGVtZTogam91cm5hbA0KICAgIGhpZ2hsaWdodDogdGV4dG1hdGUgDQogICAgdG9jOiB0cnVlDQogICAgdG9jX2RlcHRoOiAzIA0KICAgIHRvY19mbG9hdDogDQogICAgICBjb2xsYXBzZWQ6IHRydWUNCiAgICAgIHNtb290aF9zY3JvbGw6IHRydWUNCiAgICBzZWxmX2NvbnRhaW5lZDogdHJ1ZQ0KICAgIG51bWJlcl9zZWN0aW9uczogZmFsc2UNCiAgICBkZl9wcmludDoga2FibGUNCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlDQplZGl0b3Jfb3B0aW9uczogDQogIGNodW5rX291dHB1dF90eXBlOiBjb25zb2xlDQotLS0NCg0KYGBge3IgcGFja2FnZXMtc2V0dXAsIGluY2x1ZGUgPSBGQUxTRX0NCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShrbGlwcHkpICAjLSByZW1vdGVzOjppbnN0YWxsX2dpdGh1Yigicmxlc3VyL2tsaXBweSIpDQpsaWJyYXJ5KGtuaXRyKQ0KbGlicmFyeSh0aWR5cikgICAgDQpsaWJyYXJ5KGRwbHlyKSAgICANCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkocmVhZHhsKQ0KbGlicmFyeShsZWFmbGV0KQ0KbGlicmFyeShnZ2FuaW1hdGUpDQpsaWJyYXJ5KHBsb3RseSkNCmxpYnJhcnkodmVtYmVkcikNCmxpYnJhcnkoa2FibGVFeHRyYSkNCmxpYnJhcnkod29yZGNsb3VkMikNCmxpYnJhcnkocmVhY3RhYmxlKQ0KbGlicmFyeSh2aXJpZGlzKQ0KbGlicmFyeShocmJydGhlbWVzKQ0KbGlicmFyeShndCkNCmBgYA0KDQoNCmBgYHtyIGNodW5rLXNldHVwLCBpbmNsdWRlID0gRkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsIGV2YWwgPSBUUlVFLCBtZXNzYWdlID0gRkFMU0UsIHdhcm5pbmcgPSBGQUxTRSwgDQogICAgICAgICAgICAgICAgICAgICAgI3Jlc3VsdHMgPSAiaG9sZCIsDQogICAgICAgICAgICAgICAgICAgICAgY2FjaGUgPSBGQUxTRSwgY2FjaGUucGF0aCA9ICIvY2FjaGVzLyIsIGNvbW1lbnQgPSAiIz4iLA0KICAgICAgICAgICAgICAgICAgICAgICNmaWcud2lkdGggPSA3LCAjZmlnLmhlaWdodD0gNywgICANCiAgICAgICAgICAgICAgICAgICAgICAjb3V0LndpZHRoID0gNywgb3V0LmhlaWdodCA9IDcsDQogICAgICAgICAgICAgICAgICAgICAgY29sbGFwc2UgPSBUUlVFLCAgZmlnLnNob3cgPSAiaG9sZCIsDQogICAgICAgICAgICAgICAgICAgICAgZmlnLmFzcCA9IDcvOSwgb3V0LndpZHRoID0gIjYwJSIsIGZpZy5hbGlnbiA9ICJjZW50ZXIiKQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGRldiA9ICJwbmciLCBkZXYuYXJncyA9IGxpc3QodHlwZSA9ICJjYWlyby1wbmciKSkNCmBgYA0KDQoNCmBgYHtyIG9wdGlvbnMtc2V0dXAsIGluY2x1ZGUgPSBGQUxTRX0NCm9wdGlvbnMoc2NpcGVuID0gOTk5KSAjLSBwYXJhIHF1aXRhciBsYSBub3RhY2nDs24gY2llbnTDrWZpY2ENCm9wdGlvbnMoInlhbWwuZXZhbC5leHByIiA9IFRSVUUpIA0KYGBgDQoNCg0KYGBge3Iga2xpcHB5LCBlY2hvID0gRkFMU0V9DQoNCmtsaXBweTo6a2xpcHB5KHBvc2l0aW9uID0gYygidG9wIiwgInJpZ2h0IikpICMtIHJlbW90ZXM6Omluc3RhbGxfZ2l0aHViKCJybGVzdXIva2xpcHB5IikNCg0KYGBgDQoNCjxociBjbGFzcz0ibGluZWEtYmxhY2siPg0KDQpUcmFiYWpvIGVsYWJvcmFkbyBwYXJhIGxhIGFzaWduYXR1cmEgIlByb2dyYW1hY2nDs24geSBtYW5lam8gZGUgZGF0b3MgZW4gbGEgZXJhIGRlbCBCaWcgRGF0YSIgZGUgbGEgVW5pdmVyc2l0YXQgZGUgVmFsw6huY2lhIGR1cmFudGUgZWwgY3Vyc28gMjAyMC0yMDIxLiBFbCByZXBvIGRlbCB0cmFiYWpvIGVzdMOhIFthcXXDrV0oaHR0cHM6Ly9naXRodWIuY29tL2pvc2VtYWZjL3RyYWJham9fQmlnRGF0YSl7dGFyZ2V0PSJfYmxhbmsifS4gTGEgcMOhZ2luYSB3ZWIgZGUgbGEgYXNpZ25hdHVyYSB5IGxvcyB0cmFiYWpvcyBkZSBtaXMgY29tcGHDsWVyb3MgcHVlZGVuIHZlcnNlIFthcXXDrV0oaHR0cHM6Ly9wZXJlenA0NC5naXRodWIuaW8vaW50cm8tZHMtMjAtMjEtd2ViLzA3LXRyYWJham9zLmh0bWwpe3RhcmdldD0iX2JsYW5rIn0uDQoNCg0KDQo8aHIgY2xhc3M9ImxpbmVhLXJlZCI+DQoNCjxicj4NCg0KYGBge3IsIGVjaG89RkFMU0UsZXZhbD1UUlVFLCAgb3V0LndpZHRoPSI2MCUifQ0KDQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyAoaGVyZTo6aGVyZSggImltYWdlbiIsImljb25vc19ncmFuZF9zbGFtLmpwZyIpKQ0KDQpgYGANCg0KDQojIyAgIDxGT05UIENPTE9SPSJkZWVwc2t5Ymx1ZSI+MS4gSW50cm9kdWNjacOzbjwvRk9OVD4NCg0KDQpFbiBlc3RlIHRyYWJham8gbXVlc3RybyBsYSBjYW50aWRhZCBkZSBHcmFuZCBTbGFtIGdhbmFkb3MgcG9yIGxvcyBtZWpvcmVzIGp1Z2Fkb3JlcyBkZSBsYSBoaXN0b3JpYSBkZWwgVGVuaXMuRG9uZGUgcG9kcmVtb3MgdmVyIHF1ZSBoYXkgYWxndW5vcyBqdWdhZG9yZXMgaWd1YWxhZG9zIHBlcm8gZXhpc3RlIHVuIGNsYXJvIGRvbWluaW8gcG9yIHBhcnRlIGRlIFJhZmFlbCBOYWRhbCBlbiBSb2xhbmQgR2Fycm9zLiBIZSBkZWNpZGlkbyByZWFsaXphciBlc3RlIHRyYWJham8gcG9ycXVlIG1lIGFwYXNpb25hIGVsIHRlbmlzIGRlc2RlIG11eSBwZXF1ZcOxbyB5IHBvciBlbGxvLCBtZSByZXN1bHRhIGludGVyZXNhbnRlIGRhciBhIGNvbm9jZXIgbG9zIHNpZ3VpZW50ZXMgZGF0b3MuDQoNCi0tLS0tLS0tLS0tLS0tLS0NCg0KIyMgPEZPTlQgQ09MT1I9ImRlZXBza3libHVlIj4yLiBEYXRvczwvRk9OVD4gey50YWJzZXR9DQoNCiMjIyA8Rk9OVCBDT0xPUj0icmVkIj4qKkluZm9ybWFjacOzbioqPC9GT05UPg0KDQpIZSBlc2NvZ2lkbyBsYSBpbmZvcm1hY2nDs24gZGUgbGFzIHDDoWdpbmFzIEFUUFRvdXIsIFdpa2lwZWRpYSB5IGVsIHBlcmnDs2RpY28gIkVMIFBBw41TIiBwYXJhIHByb2NlZGVyIGEgZWxhYm9yYXIgdGFibGFzIGVuIGV4Y2VsIHF1ZSBhbG1hY2VubyBlbiBsYSBjYXJwZXRhIGRhdG9zIHkgbGFzIGltcG9ydG8gbWVkaWFudGUgbG9zIGPDs2RpZ29zIHF1ZSBzZSBvYnNlcnZhbiBlbiBsYSBwZXN0YcOxYSAiQ8OzZGlnb3MgZGUgZGF0b3MgaW1wb3J0YWRvcyINCg0KIyMjIDxGT05UIENPTE9SPSJyZWQiPioqQ8OzZGlnb3MgZGUgZGF0b3MgaW1wb3J0YWRvcyoqPC9GT05UPiANCg0KYGBge3IgZXZhbD1UUlVFLCBpbmNsdWRlPVRSVUUsIGVjaG89VFJVRX0NCg0KZ3JhbmRfc2xhbV9nYW5hZG9zPC0gcmVhZF9leGNlbCgiLi9kYXRvcy9ncmFuZF9zbGFtLnhsc3giKQ0KDQpyYW5raW5nX3Bvcl9wYWlzZXMgPC0gcmVhZF9leGNlbCgiLi9kYXRvcy9yYW5raW5nX3Bvcl9wYWlzZXMueGxzeCIpDQoNCmBgYA0KDQotLS0tLS0tLS0tLS0tLS0tDQoNCiMjICAgPEZPTlQgQ09MT1I9ImRlZXBza3libHVlIj4zLiBSYW5raW5nIHBvciBqdWdhZG9yZXMgPC9GT05UPiB7LnRhYnNldH0NCg0KSGFzdGEgZWwgbW9tZW50bywgNTQgdGVuaXN0YXMgaGFuIGdhbmFkbyBhbCBtZW5vcyB1biBHcmFuZCBTbGFtIGVuIGxhIGVyYSBhYmllcnRhLkVuIGxhIHNpZ3VpZW50ZSB0YWJsYSwgc2UgZGVzdGFjYSBhIGxvcyAxMyBqdWdhZG9yZXMgcXVlIGhhbiB0ZW5pZG8gdW5hIG1heW9yIGNhbnRpZGFkIGRlIEdyYW5kIFNsYW0gYSBsbyBsYXJnbyBkZSBsYSBoaXN0b3JpYSBkZWwgdGVuaXMuIA0KUG9yIHVuIGxhZG8sIHNlIHB1ZWRlbiBvYnNlcnZhciBub21icmVzIGRlIGp1Z2Fkb3JlcyBhY3R1YWxtZW50ZSBlbiBhY3Rpdm8gY29tbyBSb2dlciBGZWRlcmVyIHkgcG9yIG90cm8gbGFkbywganVnYWRvcmVzIHJldGlyYWRvcyBjb21vIEJvcmlzIEJlY2tlci4gDQoNCkVuIGxhIHNlZ3VuZGEgcGVzdGHDsWEsIHBvZGVtb3Mgb2JzZXJ2YXIgZW4gdW4gZ3LDoWZpY28gZGUgYmFycmFzIGVsIHJhbmtpbmcgZGUgR3JhbmQgU2xhbS4gQSB1biBsYWRvLCBlbCBub21icmUgZGUgbG9zIHRlbmlzdGFzIHkgYWwgb3RybywgZWwgdG90YWwgZGUgR3JhbmQgU2xhbSBjb25zZWd1aWRvcyBwb3IgY2FkYSBqdWdhZG9yLg0KTGEgc3VwZXJpb3JpZGFkIGRlIFJhZmFlbCBOYWRhbCBzb2JyZSB0aWVycmEgYmF0aWRhIGVzIGluY3Vlc3Rpb25hYmxlLiBNdWNobyBtw6FzIGN1YW5kbyBlbCB0ZXJyZW5vIHNlIGFjb3RhIGEgUm9sYW5kIEdhcnJvcy4gRW4gZWwgR3JhbmQgU2xhbSBmcmFuY8OpcyBoYSBnYW5hZG8gbGEgbWF5b3IgY2lmcmEgZGUgdMOtdHVsb3MgcXVlIGN1YWxxdWllciBqdWdhZG9yIGhheWEgZ2FuYWRvIGphbcOhcyBlbiB1biBtaXNtbyBlc2NlbmFyaW8uIFkgZ3JhY2lhcyBhIGVsbG8sIGhhIGNvbnNlZ3VpZG8gaWd1YWxhcnNlIGEgUm9nZXIgRmVkZXJlciBlbiBjYW50aWRhZCBkZSBHcmFuZCBTbGFtIGNvbnNlZ3VpZG9zIGhhc3RhIGxhIGZlY2hhLg0KDQojIyMgPEZPTlQgQ09MT1I9InJlZCI+KipQb3NpY2lvbmVzKio8L0ZPTlQ+DQoNCmBgYHtyLCBlY2hvPUZBTFNFLCBldmFsPVRSVUV9DQoNCmtuaXRyOjprYWJsZShncmFuZF9zbGFtX2dhbmFkb3MpICU+JQ0KICBrYWJsZUV4dHJhOjprYWJsZV9zdHlsaW5nKGZpeGVkX3RoZWFkID0gbGlzdChlbmFibGVkID0gVCwgYmFja2dyb3VuZCA9ICJkZWVwc2t5Ymx1ZSIpKSAlPiUgIGNvbHVtbl9zcGVjKDMsIGJvbGQgPSBULCBjb2xvciA9ICJ3aGl0ZSIsIGJhY2tncm91bmQgPSAiZGVlcHNreWJsdWUiKSANCiAgICAgICAgICANCmBgYA0KDQoNCiMjIyAgIDxGT05UIENPTE9SPSJyZWQiPioqR3LDoWZpY2EqKjwvRk9OVD4NCg0KYGBge3IgcHJlc3N1cmUsIGVjaG89RkFMU0UsIGV2YWw9VFJVRSwgIG91dC53aWR0aD0iODAlIn0NCg0KZ3JhbmRfc2xhbV9nYW5hZG9zIDwtIGdyYW5kX3NsYW1fZ2FuYWRvcyAlPiUgbXV0YXRlKE5vbWJyZSA9IGZvcmNhdHM6OmFzX2ZhY3RvcihOb21icmUpKSAgDQoNCmdyYW5kX3NsYW1fZ2FuYWRvcyA8LSBncmFuZF9zbGFtX2dhbmFkb3MgJT4lIG11dGF0ZShOb21icmUgPSBmb3JjYXRzOjpmY3RfcmVvcmRlcihOb21icmUsIFRvdGFsKSkgDQoNCnAgPC0gZ2dwbG90KGdyYW5kX3NsYW1fZ2FuYWRvcywgYWVzKHggPSBOb21icmUsIHkgPSBUb3RhbCkpICsgDQogIGdlb21fY29sKGZpbGwgPSAiY3lhbiIpDQoNCnAgKyBsYWJzKHRpdGxlID0gIkdSQU5EIFNMQU0iLA0KICAgICAgIHN1YnRpdGxlID0gIihSQU5LSU5HKSIsDQogICAgICAgY2FwdGlvbiA9ICJFbGFib3JhY2nDs24gcHJvcGlhIiwNCiAgICAgICB4ID0gIlRlbmlzdGFzIiwNCiAgICAgICB5ID0gIlRvdGFsIikgKyB0aGVtZV9saWdodCgpICsgDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBUb3RhbCksbnVkZ2VfeSA9MC41LCBjb2xvdXIgPSAiYmxhY2siKSArIGNvb3JkX2ZsaXAoKQ0KDQpgYGANCg0KLS0tLS0tLS0tLS0tLS0tLQ0KDQojIyA8Rk9OVCBDT0xPUj0iZGVlcHNreWJsdWUiPjQuRGlmZXJlbnRlcyBwcmVtaW9zIHkgc3VwZXJmaWNpZXM8L0ZPTlQ+ey50YWJzZXR9DQoNCiMjIyAgIDxGT05UIENPTE9SPSJyZWQiPioqUHJlbWlvcyoqPC9GT05UPg0KDQpKdW50byBhIGxvcyB0cm9mZW9zLCBsb3MganVnYWRvcmVzIHJlY2liZW4gdW4gcHJlbWlvIG1vbmV0YXJpbyBhbCBwcm9jbGFtYXJzZSBjYW1wZW9uZXMuDQoNCkxvcyB0ZW5pc3RhcyBnYW5hbiBhbHJlZGVkb3IgZGUgNDAuMDAwIGV1cm9zIHBvciBwYXJ0aWNpcGFyIGVuIHVuYSBwcmltZXJhIHJvbmRhIGRlIHVuIEdyYW5kIFNsYW0sIG3DoXMgZGVsIGRvYmxlIGRlIGxvIHF1ZSBpbmdyZXNhbiBlbiB1bmEgcHJpbWVyYSByb25kYSBkZSB1biB0b3JuZW8gTWFzdGVycyAxLjAwMCAoc2lndWllbnRlIGNhbXBlb25hdG8gZW4gaW1wb3J0YW5jaWEpLCB5IGxvcyBwcmVtaW9zIHBvciBnYW5hciB1biBncmFuZGUgc29uIG11Y2hvIG1heW9yZXMgcXVlIGVuIGN1YWxxdWllciB0b3JuZW8gZGUgbGEgdGVtcG9yYWRhLg0KDQpBIHBlc2FyIGRlIHF1ZSBkZXBlbmRlIGRlIGxhIHJlY2F1ZGFjacOzbiB5IGRlbCBHcmFuZCBTbGFtIHF1ZSBzZSB0cmF0ZSwgbG9zIHRlbmlzdGFzIHF1ZSBzZSBwcm9jbGFtYW4gY2FtcGVvbmVzIGVuIGxhIGZpbmFsIHJlY2liZW4gdW4gcHJlbWlvIHF1ZSBvc2NpbGEgZW50cmUgbG9zIDIsNS0zIG1pbGxvbmVzIGRlIGV1cm9zLg0KDQoNCmBgYHtyLCBlY2hvPUZBTFNFLGV2YWw9VFJVRSwgIG91dC53aWR0aD0iNjAlIn0NCg0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MgKGhlcmU6OmhlcmUoICJpbWFnZW4iLCJ0cm9mZW9zX3RlbmlzLnBuZyIpKQ0KDQpgYGANCg0KIyMjICAgPEZPTlQgQ09MT1I9InJlZCI+KipTdXBlcmZpY2llcyoqPC9GT05UPg0KDQoNCkVuIGxhIHNpZ3VpZW50ZSBpbWFnZW4gdGVuZW1vcyBsb3MgZGlmZXJlbnRlcyB0aXBvcyBkZSBwaXN0YXMgZXhpc3RlbnRlcyB5IHN1IGNvbXBvc2ljacOzbi4NCg0KRW4gcHJpbWVyIGx1Z2FyLCB0aWVycmEgYmF0aWRhLiBFc3RlIHRpcG8gZGUgcGlzdGFzIGVzdMOhbiBoZWNoYXMgZGUgZXNxdWlzdG8sIHBpZWRyYSB5IGFyY2lsbGEuDQoNCkVuIHNlZ3VuZG8geSBjdWFydG8gbHVnYXIgZGUgbGEgaW1hZ2VuIHRlbmVtb3MgbGFzIHBpc3RhcyBkdXJhcyBvIGRlIGNlbWVudG8uIEVzdG9zIHRpcG9zIGRlIHBpc3RhcyAgZXZpdGFuIGlycmVndWxhcmlkYWRlcyBlbiBsYSB0cmF5ZWN0b3JpYSBkZSBsYSBwZWxvdGEgeSBwcm9wb3JjaW9uYW4gdW4ganVlZ28gaW50ZXJtZWRpby4NCg0KRW4gdGVyY2VyIGx1Z2FyLCBsYXMgcGlzdGFzIGRlIGhpZXJiYSBkb25kZSBlbCBjw6lzcGVkIGVzIGxhIHN1cGVyZmljaWUgb3JpZ2luYWwgZGVsIHRlbmlzLiBTZSB0cmF0YSBkZSB1bmEgc3VwZXJmaWNpZSByw6FwaWRhLCBkZSBib3RlIGlycmVndWxhciB5IGxhIG1lbm9zIHV0aWxpemFkYS4gTGEgY29uc3RydWNjacOzbiB5IG1hbnRlbmltaWVudG8gZGUgZXN0ZSB0aXBvIGRlIHN1cGVyZmljaWVzIGVzIGNvc3Rvc28geSBjb21wbGVqby4NCg0KYGBge3IsIGVjaG89RkFMU0UsZXZhbD1UUlVFLCAgb3V0LndpZHRoPSI2MCUifQ0KDQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyAoaGVyZTo6aGVyZSggImltYWdlbiIsInBpc3Rhc19kZV90ZW5pcy5qcGciKSkNCg0KYGBgDQoNCi0tLS0tLS0tLS0tLS0tLS0NCg0KIyMgICA8Rk9OVCBDT0xPUj0iZGVlcHNreWJsdWUiPjUuIE1hcGFzIGRlIGxvcyBlc3RhZGlvcyA8L0ZPTlQ+IHsudGFic2V0fQ0KDQpMb3Mgc2lndWllbnRlcyBtYXBhcyBub3MgbXVlc3RyYW4gbGEgdWJpY2FjacOzbiBkZSBjYWRhIHVubyBkZSBsb3MgZXN0YWRpb3MgYSBwYXJ0aXIgZGUgc3VzIGNvb3JkZW5hZGFzIGNvcnJlc3BvbmRpZW50ZXMuDQoNCkVuIHByaW1lciBsdWdhciwgIGVuIGVsIE1BUEEgMSBoZSBkZWNpZGlkbyBhZ3J1cGFyIFJvbGFuZCBHYXJyb3MgcXVlIHNlIHViaWNhIGVuIGVsIHNlY3RvciBzdWRvY2NpZGVudGFsIGRlIFBhcsOtcywgZW4gZWwgWFZJIGRpc3RyaXRvIHksICBXaW1ibGVkb24gcXVlIHNlIGVuY3VlbnRyYSBlbiBlbCBBbGwgRW5nbGFuZCBMYXduIFRlbm5pcyB5IENyb3F1ZXQgQ2x1YiBkZSBMb25kcmVzLg0KDQpFbiBzZWd1bmRvIGx1Z2FyLCBlbiBlbCBNQVBBIDIgdWJpY28gZWwgVVNUQSBCaWxsaWUgSmVhbiBLaW5nIE5hdGlvbmFsIFRlbm5pcyBDZW50ZXIgcXVlIGVzdMOhIGxvY2FsaXphZG8gZW4gZWwgRmx1c2hpbmcgTWVhZG93cy1Db3JvbmEgUGFyaywgZW4gZWwgYm9yb3VnaCBkZSBRdWVlbnMgZW4gTnVldmEgWW9yayB5IGVzIGxhIHNlZGUgZGVsIEFiaWVydG8gZGUgbG9zIEVzdGFkb3MgVW5pZG9zLg0KDQpFbiB0ZXJjZXIgbHVnYXIsIGVuIGVsIE1BUEEgMyB0ZW5lbW9zIGVsIFJvZCBMYXZlciBBcmVuYSwgdW4gcmVjaW50byBtdWx0aXByb3DDs3NpdG8gdXNhZG8gcHJpbmNpcGFsbWVudGUgY29tbyBlc3RhZGlvIGRlIHRlbmlzIHBhcmEgZWwgQWJpZXJ0byBkZSBBdXN0cmFsaWEgeSAgcXVlIGVzIHBhcnRlIGRlbCBjb21wbGVqbyBkZWwgcGFycXVlIGRlIE1lbGJvdXJuZS4NCg0KDQojIyMgPEZPTlQgQ09MT1I9InJlZCI+KipNQVBBIDEqKjwvRk9OVD4NCg0KDQpgYGB7ciwgZWNobz1GQUxTRSwgZXZhbD1UUlVFLCAgb3V0LndpZHRoPSI4MCUifQ0KDQpwIDwtIGxlYWZsZXQoKSAlPiUNCiAgYWRkVGlsZXMoKSAlPiUgDQogIHNldFZpZXcobG5nID0gLTEsIGxhdCA9IDUwLCB6b29tID0gNS41KSAlPiUgDQogIGFkZE1hcmtlcnMobG5nID0gMi4yNTM2LCBsYXQgPSA0OC44NDY3LCBwb3B1cCA9ICJSb2xhbmQgR2Fycm9zIikgJT4lIA0KICBhZGRNYXJrZXJzKGxuZyA9IC0wLjIxNTIsIGxhdCA9IDUxLjQzMTksIHBvcHVwID0gIldpbWJsZWRvbiIpIA0KDQpwIA0KDQpgYGANCg0KDQojIyMgPEZPTlQgQ09MT1I9InJlZCI+KipNQVBBIDIqKjwvRk9OVD4NCg0KYGBge3IsIGVjaG89RkFMU0UsIGV2YWw9VFJVRSwgIG91dC53aWR0aD0iODAlIn0NCg0KcCA8LSBsZWFmbGV0KCkgJT4lDQogIGFkZFRpbGVzKCkgJT4lIA0KICBzZXRWaWV3KGxuZyA9IC03NCwgbGF0ID0gNDMsIHpvb20gPSA1KSAlPiUgDQogIGFkZE1hcmtlcnMobG5nID0gLTczLjg0NTYsIGxhdCA9IDQwLjc1MDQsIHBvcHVwID0gIk9wZW4gVVNBKSIpDQoNCg0KcCAgDQoNCmBgYA0KDQoNCiMjIyA8Rk9OVCBDT0xPUj0icmVkIj4qKk1BUEEgMyoqPC9GT05UPg0KDQpgYGB7ciwgZWNobz1GQUxTRSwgZXZhbD1UUlVFLCAgb3V0LndpZHRoPSI4MCUifQ0KDQpwIDwtIGxlYWZsZXQoKSAlPiUNCiAgYWRkVGlsZXMoKSAlPiUgDQogIHNldFZpZXcobG5nID0gMTQ1LCBsYXQgPSAtNDAsIHpvb20gPSAzLjUpICU+JSANCiAgYWRkTWFya2VycyhsbmcgPSAxNDQsNTIzNiwgbGF0ID0gLTM3LCBwb3B1cCA9ICJPcGVuIEF1c3RyYWxpYSIpIA0KDQoNCnAgIA0KDQpgYGANCg0KLS0tLS0tLS0tLS0tLS0tLQ0KDQojIyAgIDxGT05UIENPTE9SPSJkZWVwc2t5Ymx1ZSI+Ni4gVG9wIDQgbWVqb3JlcyA8L0ZPTlQ+IHsudGFic2V0fQ0KDQpFbiBlc3RhIGdyw6FmaWNhIHNpIGRlc2xpemFtb3MgZWwgcmF0w7NuIHBvciBsYXMgYmFycmFzIHBvZGVtb3Mgb2JzZXJ2YXIgbcOhcyBkZXRhbGxhZGFtZW50ZSBsYSBjYW50aWRhZCBkZSB0b3JuZW9zIFdpbWJsZWRvbiBnYW5hZG9zIHBvciBjYWRhIHVubyBkZSBsb3MgNCBtZWpvcmVzIGVuIGVsIHJhbmtpbmcgZGUgR3JhbmQgU2xhbS4gQ2FkYSB1bm8gdGllbmUgdW5hIGRpc3RpbnRhIHRvbmFsaWRhZCBkZSBhenVsIGRlcGVuZGllbmRvIGRlIGxhIGNhbnRpZGFkIHF1ZSBoYXlhbiBnYW5hZG8uIA0KU2luIGVtYmFyZ28sIHN1IG9yZGVuIGVuIGxhIGdyw6FmaWNhIGNvcnJlc3BvbmRlIGFsIHRvdGFsIGRlIEdyYW5kIFNsYW0gZ2FuYWRvcyBlbnRyZSBsb3MgY2l0YWRvcyBhbnRlcmlvcm1lbnRlLg0KDQpBZGVtw6FzLCBlbiBsYSBwYXJ0ZSBzdXBlcmlvciBkZSBsYSBncsOhZmljYSB0ZW5lbW9zIHZhcmlhcyBvcGNpb25lcyBwb3Igc2kgc2UgcXVpZXJlIGRlc2NhcmdhciBsYSBncsOhZmljYSBjb21vIHVuYSBpbWFnZW4gY29uIGZvcm1hdG8gcG5nLCB0YW1iacOpbiBoYWNlciB6b29tLCBlbnRyZSBvdHJhcy4NCg0KDQojIyMgPEZPTlQgQ09MT1I9InJlZCI+KipHcsOhZmljYSoqPC9GT05UPg0KDQpgYGB7ciwgZWNobz1GQUxTRSwgZXZhbD1UUlVFLCAgb3V0LndpZHRoPSI4MCUifQ0KZGZfMSA8LSBncmFuZF9zbGFtX2dhbmFkb3MgJT4lIHNsaWNlX21heChUb3RhbCwgbiA9IDQpDQoNCnAgPC0gZ2dwbG90KGRmXzEsIGFlcyh4ID0gTm9tYnJlLCB5ID0gVG90YWwpKSArIA0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IixhZXMoZmlsbCA9IFdpbWJsZWRvbikpDQoNCnA8LSBwICsgbGFicyh0aXRsZSA9ICJUw41UVUxPUyBXSU1CTEVET04iLA0KICAgICAgIHN1YnRpdGxlID0gIihSQU5LSU5HKSIsDQogICAgICAgY2FwdGlvbiA9ICJFbGFib3JhY2nDs24gcHJvcGlhIiwNCiAgICAgICB4ID0gIlRlbmlzdGFzIiwNCiAgICAgICB5ID0gIlRvdGFsIikgKyB0aGVtZV9saWdodCgpICsgDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBUb3RhbCksbnVkZ2VfeSA9MC41LCBjb2xvdXIgPSAiYmxhY2siKQ0KDQpnZ3Bsb3RseShwKQ0KDQoNCmBgYA0KDQotLS0tLS0tLS0tLS0tLS0tDQoNCiMjICAgPEZPTlQgQ09MT1I9ImRlZXBza3libHVlIj43LiBFbCBwdW50byBtw6FzIGxhcmdvIGRlIGxhIGhpc3RvcmlhIDwvRk9OVD4gey50YWJzZXR9DQoNCkNvbiA1NCBnb2xwZXMgZXN0ZSBwdW50byBxdWUgZGlzcHV0YXJvbiBEam9rb3ZpYyB2cyBOYWRhbCBlbiBlbCBVcyBPcGVuIDIwMTMgc2UgY29udmlydGnDsyBlbiBlbCBtw6FzIGxhcmdvIGRlIGxhIGhpc3RvcmlhLiANCg0KUmFmYSBOYWRhbCBzZSBwcm9jbGFtw7MgY2FtcGXDs24gZGVsIFVTIE9wZW4gZGVzcHXDqXMgZGUgZG9ibGVnYXIgZW4gY3VhdHJvIHNldHMgYSBOb3ZhayBEam9rb3ZpYyBlbiBsYSBmaW5hbC4gDQpTZSB0cmF0YWJhIGRlbCB0w610dWxvIG7Dum1lcm8gNjAgZGUgc3UgY2FycmVyYSwgc3UgMTPCuiBHcmFuZCBTbGFtIHkgbGEgc2VndW5kYSB2ZXogcXVlIHNlIGNvcm9uYWJhIGVuIE51ZXZhIFlvcmsuDQoNCg0KIyMjIDxGT05UIENPTE9SPSJyZWQiPioqVsOtZGVvKio8L0ZPTlQ+DQoNCg0KYGBge3IgZXZhbCA9IFRSVUUsIGVjaG8gPSBGQUxTRSB9DQoNCmVtYmVkX3VybCgiaHR0cHM6Ly93d3cueW91dHViZS5jb20vd2F0Y2g/dj1MRXZDTGROek5ZUSIpDQoNCmBgYA0KDQotLS0tLS0tLS0tLS0tLS0tDQoNCiMjICAgPEZPTlQgQ09MT1I9ImRlZXBza3libHVlIj44LiBSYW5raW5nIHBvciBwYcOtc2VzIDwvRk9OVD4gey50YWJzZXR9DQoNCkVuIGxhIHNpZ3VpZW50ZSB0YWJsYSBwb2RlbW9zIGNvbnN1bHRhciBlbCB0b3AgdGVuIGRlIHBhw61zZXMgY29uIG3DoXMgR3JhbmQgU2xhbXMgZGUgbGEgaGlzdG9yaWEuIFRlbmVtb3MgbGFzIGNpZnJhcyB0b3RhbGVzIHkgYSBzdSB2ZXosIGRlIG1hbmVyYSBtw6FzIGVzcGVjw61maWNhIGxhIGNhbnRpZGFkIGdhbmFkYSBwb3IgY2FkYSBwYcOtcyBlbiBjYWRhIHVubyBkZSBsb3MgdG9ybmVvcy4gDQoNClZlbW9zIGNvbW8gVVNBIHNlIGVuY3VlbnRyYSBhIGTDrWEgZGUgaG95IGRvbWluYW5kbyBjb24gZGlmZXJlbmNpYSBkZSBsb3MgZGVtw6FzIGNvbiB1biB0b3RhbCBkZSA1MSB0w610dWxvcyB5IHByZWRvbWluaW8gZW4gbGFzIHN1cGVyZmljaWVzIGRlIGhpZXJiYShXaW1ibGVkb24pIHkgcGlzdGEgZHVyYShVU0EgeSBBdXN0cmFsaWEpIGdhbmFkb3MgcG9yIDEyIHRlbmlzdGFzLg0KDQpSb2xhbmQgR2Fycm9zIGVzIGVsIMO6bmljbyBHcmFuZCBTbGFtIHF1ZSBzZSBsZSByZXNpc3RlIGEgVVNBIGdyYWNpYXMgYSBsb3MgZXNwYcOxb2xlcyBxdWUgdGllbmVuIHVuIGFsdG8gbml2ZWwgZW4gbGFzIHN1cGVyaWZpY2llcyBkZSB0aWVycmEgYmF0aWRhLiBZIGVzIHBvciBlbGxvIHF1ZSwgRXNwYcOxYSBzZSBlbmN1ZW50cmEgZW4gc2VndW5kbyBsdWdhciBkZSBsYSB0YWJsYSBjb24gdW4gdG90YWwgZGUgMzEgdMOtdHVsb3MgcGVybyBsZWpvcyBkZSBhbGNhbnphciBhIFVTQS4NCg0KIyMjIDxGT05UIENPTE9SPSJyZWQiPioqVGFibGEgeSBXb3JkQ2xvdWQqKjwvRk9OVD4NCg0KYGBge3IsIGVjaG89RkFMU0UsIGV2YWw9VFJVRX0NCg0Ka25pdHI6OmthYmxlKHJhbmtpbmdfcG9yX3BhaXNlcykgJT4lDQogIGthYmxlRXh0cmE6OmthYmxlX3N0eWxpbmcoZml4ZWRfdGhlYWQgPSBsaXN0KGVuYWJsZWQgPSBULCBiYWNrZ3JvdW5kID0gImRlZXBza3libHVlIikpICU+JSAgY29sdW1uX3NwZWMoMywgYm9sZCA9IFQsIGNvbG9yID0gIndoaXRlIiwgYmFja2dyb3VuZCA9ICJkZWVwc2t5Ymx1ZSIpIA0KICAgICAgICAgIA0KYGBgDQoNCg0KYGBge3IgZXZhbD1UUlVFLCBlY2hvPUZBTFNFLCBvdXQud2lkdGggPSAiODAlIn0NCg0KcmFua2luZ19wb3JfcGFpc2VzIDwtIHJhbmtpbmdfcG9yX3BhaXNlcyAlPiUgc2VsZWN0KGMoUGHDrXMsVG90YWwpKQ0KDQp3b3JkY2xvdWQyKGRhdGEgPSByYW5raW5nX3Bvcl9wYWlzZXMsIHNpemUgPSAwLjYpDQoNCmBgYA0KDQotLS0tLS0tLS0tLS0tLS0tDQoNCiMjICAgPEZPTlQgQ09MT1I9ImRlZXBza3libHVlIj45LkNvbmNsdXNpw7NuIDwvRk9OVD4gIHsudGFic2V0fQ0KDQpDb21wYXJhbmRvIGxhcyBkb3MgdGFibGFzLCBlbnRyZSBqdWdhZG9yZXMgeSBwYcOtc2VzIGNhYmUgZGVzdGFjYXIgcXVlIGxvcyB0cmVzIHByaW1lcm9zIGp1Z2Fkb3JlcyB5IHF1ZSBhY3R1YWxtZW50ZSBlc3TDoW4gYWN0aXZhbWVudGUganVnYW5kbywgaGFuIGFwb3J0YWRvIGdyYW4gcGFydGUgZGUgbG9zIHTDrXR1bG9zIGRlIHN1cyByZXNwZWN0aXZvcyBwYcOtc2VzIGEgbG8gbGFyZ28gZGUgc3UgY2FycmVyYSB0ZW7DrXN0aWNhLg0KDQpBdW5xdWUgcG9kZW1vcyBvYnNlcnZhciBhIFJhZmFlbCBOYWRhbCB5IFJvZ2VyIEZlZGVyZXIgaWd1YWxhZG9zIGVuIGVsIHJhbmtpbmcgZGUgR3JhbmQgU2xhbSwgbG9zIGR1ZWxvcyBlbnRyZSBlbCBlc3Bhw7FvbCB5IGVsIHN1aXpvIHZpZW5lbiBkZSBsZWpvcy4gRGVzZGUgYXF1ZWwgcHJpbWVyIHBhcnRpZG8gZW4gZWwgTWFzdGVyIDEwMDAgZGUgTWlhbWkgZW4gMjAwNCwgc2UgaGFuIGVuZnJlbnRhZG8gZW4gNDAgb2Nhc2lvbmVzIGNvbiB1biBiYWxhbmNlIHBvc2l0aXZvIHBhcmEgTmFkYWwgKDI0LTE2KS4gQXVucXVlIGVsIHN1aXpvIGN1ZW50YSBjb24gbcOhcyB0w610dWxvcyB0b3RhbGVzLCBSYWZhZWwgTmFkYWwgbGUgaGEgYWxjYW56YWRvIGVuIEdyYW5kIFNsYW1zIHkgaGEgY29uc2VndWlkbyBtw6FzIE3DoXN0ZXIgMTAwMC4NCg0KDQoNCmBgYHtyLCBlY2hvPUZBTFNFLGV2YWw9VFJVRSwgIG91dC53aWR0aD0iNjAlIn0NCg0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MgKGhlcmU6OmhlcmUoICJpbWFnZW4iLCJuYWRhbF9nYW5hX3JvbGFuZGdhcnJvcy5qcGciKSkNCg0KYGBgDQoNCj4gIkVMIMOpeGl0byBubyBlcyBsYSB2aWN0b3JpYSwgc2lubyB0b2RvIGxvIHF1ZSBoYXMgcGVsZWFkbyBwb3IgZ2FuYXIiLiBSYWZhZWwgTmFkYWwNCg0KLS0tLS0tLS0tLS0tLS0tLQ0KDQojIyAgIDxGT05UIENPTE9SPSJkZWVwc2t5Ymx1ZSI+MTAuIFJlZmVyZW5jaWFzIDwvRk9OVD4gDQoNCi0gW0VubGFjZSBhIEFUUFRvdXJdKGh0dHBzOi8vd3d3LmF0cHRvdXIuY29tL2VzL25ld3Mvcm9sYW5kLWdhcnJvcy0yMDIwLXByZXZpYS1maW5hbC1kYXRvcy1uYWRhbCkNCg0KLSBbRW5sYWNlIGEgV2lraXBlZGlhXShodHRwczovL2VzLndpa2lwZWRpYS5vcmcvd2lraS9HcmFuZF9TbGFtXyh0ZW5pcykjR3JhbmRfU2xhbSkNCg0KLSBbRW5sYWNlIGEgRUxQQUlTXShodHRwczovL2VscGFpcy5jb20vZGVwb3J0ZXMvMjAyMC0xMC0xMS9uYWRhbC1sb2dyYS1zdS0xMy1yb2xhbmQtZ2Fycm9zLWUtaWd1YWxhLWEtZmVkZXJlci1lbi1ncmFuZC1zbGFtcy5odG1sKQ0KDQotIFtFbmxhY2UgYSBNYXJjYV0oaHR0cHM6Ly93d3cubWFyY2EuY29tLzIwMTMvMDkvMTAvdGVuaXMvdXNfb3Blbi8xMzc4NzczMTY1Lmh0bWwpDQoNCi0gW0VubGFjZSBhIFR1dG9yaWFsZXNdKGh0dHBzOi8vcGVyZXpwNDQuZ2l0aHViLmlvL2ludHJvLWRzLTIwLTIxLXdlYi8wNC10dXRvcmlhbGVzLmh0bWwpDQoNCg0KLS0tLS0tLS0tLS0tLS0tLQ0KDQo8YnI+PGJyPg0KDQpQYXJhIGFjYWJhciBlc3RlIGNodW5rIHBhcmEgaW5jbHVpciB0dSBgc2Vzc2lvbiBpbmZvYDoNCg0KYGBge3J9DQpzZXNzaW9uaW5mbzo6c2Vzc2lvbl9pbmZvKCkgJT4lIGRldGFpbHM6OmRldGFpbHMoc3VtbWFyeSA9ICdjdXJyZW50IHNlc3Npb24gaW5mbycpIA0KYGBg