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
Este trabajo se realiza con el fin de analizar las estadisticas de los equipos y jugadores de la primera division de la liga de Inglaterra. Considerada una de las 5 grandes ligas europeas que para muchos, sus 38 jornadas, la convierten en la mas competitiva y relevante del mundo, tambien gracias a su historia y a la participacion de tantos grandes clubes como Manchester United, Chelsea, Liverpool entre otros. Ilutraremos la tabla de clasificacion de cada equipo, el Campeon de la liga, los descensos a la segunda division y los equipos que alcanzaron las maximas competiciones europeas (Champions League y Europa League). Ademas estudiaremos los maximos goleadores de la temporada tanto por equipos como jugadores mediante la utilizacion de graficos ilustrativos. Por ultimo, conoceremos los estadios donde se juegan los partidos de esta maxima competicion, señalando varios aspectos interesantes que nos ayudaran a adentrarnos a un mas en esta grandiosa competicion inglesa.
Datos
Fuente de los Datos
Los datos fueron obtenidos de varias paginas como el diario Marca, Wikipedia y la pagina oficial de la Premier League y luego fueron modificados por mi en un excel incluido en la carpeta datos. La manipulacion de los datos se realizaron gracias a los slides y tutoriales suministrados por el profesor de la materia Pedro Perez.
Codigos
clasif <- read_excel("./datos/premier-league.xlsx", sheet = 1)
max_gol <- read_excel("./datos/premier-league.xlsx", sheet = 2 )
asistencia <- read_excel("./datos/premier-league.xlsx", sheet = 3 )
premio <- read_excel("./datos/premier-league.xlsx", sheet = 4 )
clasif_1 <- clasif %>% filter(!(is.na(Clasif2021))) %>% select(Pos, Equipo, Pts, Clasif2021)
str(clasif_1)
#> tibble [10 x 4] (S3: tbl_df/tbl/data.frame)
#> $ Pos : num [1:10] 1 2 3 4 5 6 8 18 19 20
#> $ Equipo : chr [1:10] "Liverpool (C)" "Manchester City" "Manchester United" "Chelsea" ...
#> $ Pts : num [1:10] 99 81 66 66 62 59 56 34 34 21
#> $ Clasif2021: chr [1:10] "Fase de grupos de la Liga de Campeones" "Fase de grupos de la Liga de Campeones" "Fase de grupos de la Liga de Campeones" "Fase de grupos de la Liga de Campeones" ...
clasif_1 <- clasif_1 %>% mutate(Equipo = forcats::as_factor(Equipo))
str(clasif_1)
#> tibble [10 x 4] (S3: tbl_df/tbl/data.frame)
#> $ Pos : num [1:10] 1 2 3 4 5 6 8 18 19 20
#> $ Equipo : Factor w/ 10 levels "Liverpool (C)",..: 1 2 3 4 5 6 7 8 9 10
#> $ Pts : num [1:10] 99 81 66 66 62 59 56 34 34 21
#> $ Clasif2021: chr [1:10] "Fase de grupos de la Liga de Campeones" "Fase de grupos de la Liga de Campeones" "Fase de grupos de la Liga de Campeones" "Fase de grupos de la Liga de Campeones" ...
levels(clasif_1$Equipo)
#> [1] "Liverpool (C)" "Manchester City" "Manchester United"
#> [4] "Chelsea" "Leicester City" "Tottenham Hotspur"
#> [7] "Arsenal" "Bournemouth (R)" "Watford (R)"
#> [10] "Norwich City (R)"
clasif_1 <- clasif_1 %>% mutate(Equipo = forcats::fct_reorder(Equipo, Pts))
levels(clasif_1$Equipo)
#> [1] "Norwich City (R)" "Bournemouth (R)" "Watford (R)"
#> [4] "Arsenal" "Tottenham Hotspur" "Leicester City"
#> [7] "Manchester United" "Chelsea" "Manchester City"
#> [10] "Liverpool (C)"
top_gf <- clasif %>% select(Equipo, GF) %>% slice_max(GF, n = 5)
str(top_gf)
#> tibble [5 x 2] (S3: tbl_df/tbl/data.frame)
#> $ Equipo: chr [1:5] "Manchester City" "Liverpool (C)" "Chelsea" "Leicester City" ...
#> $ GF : num [1:5] 102 85 69 67 66
top_gf <- top_gf %>% mutate(Equipo = forcats::as_factor(Equipo))
str(top_gf)
#> tibble [5 x 2] (S3: tbl_df/tbl/data.frame)
#> $ Equipo: Factor w/ 5 levels "Manchester City",..: 1 2 3 4 5
#> $ GF : num [1:5] 102 85 69 67 66
levels(top_gf$Equipo)
#> [1] "Manchester City" "Liverpool (C)" "Chelsea"
#> [4] "Leicester City" "Manchester United"
top_gf <- top_gf %>% mutate(Equipo = forcats::fct_reorder(Equipo, GF))
levels(top_gf$Equipo)
#> [1] "Manchester United" "Leicester City" "Chelsea"
#> [4] "Liverpool (C)" "Manchester City"
leaflet() %>% addTiles() %>% leafem::addMouseCoordinates()
2. Tabla de la English Premier League Temporada 2019/2020
La temporada 2019/2020 fue un año muy singular y esto debido a la pandemia mundial que todos conocemos como lo fue el coronavirus. Esta situacion pandemica provoco la detencion de los partidos desde la jornada 28 del 1 de Marzo hasta el 17 de junio que se pudo reanudar. Sin embargo y pese a estos 3 meses de la falta de este gran futbol, dejo varios aspectos relevantes: lograr el Liverpool conseguir el titulo de campeon después de 30 años tras su última victoria y primero con la denominacion Premier League. Ademas haberlo conseguido rompiendo varios records como ser el primer equipo de la competición y de Europa que clasificó más anticipadamente a la fase de grupos de la Liga de Campeones de la UEFA (12 fechas de anticipación). Tambien cabe a destacar que introdujo por primera vez la tecnologia VAR (Video Arbitraje).
“Es increíble ser campeón con este equipo. Ha sido muy fácil motivar a los jugadores por la gran historia que tiene el club. Es un logro increíble para mis jugadores, lo es todo lo que han hecho durante los últimos tres años”. Jürgen Klopp
Pos
|
Equipo
|
Pts
|
PJ
|
G
|
E
|
P
|
GF
|
GC
|
Dif
|
Clasif2021
|
1
|
Liverpool (C)
|
99
|
38
|
32
|
3
|
3
|
85
|
33
|
52
|
Fase de grupos de la Liga de Campeones
|
2
|
Manchester City
|
81
|
38
|
26
|
3
|
9
|
102
|
35
|
67
|
Fase de grupos de la Liga de Campeones
|
3
|
Manchester United
|
66
|
38
|
18
|
12
|
8
|
66
|
36
|
30
|
Fase de grupos de la Liga de Campeones
|
4
|
Chelsea
|
66
|
38
|
20
|
6
|
12
|
69
|
54
|
15
|
Fase de grupos de la Liga de Campeones
|
5
|
Leicester City
|
62
|
38
|
18
|
8
|
12
|
67
|
41
|
26
|
Fase de grupos de la Liga Europa
|
6
|
Tottenham Hotspur
|
59
|
38
|
16
|
11
|
11
|
61
|
47
|
14
|
Segunda ronda de la Liga Europa
|
7
|
Wolverhampton Wanderers
|
59
|
38
|
15
|
14
|
9
|
51
|
40
|
11
|
NA
|
8
|
Arsenal
|
56
|
38
|
14
|
14
|
10
|
56
|
48
|
8
|
Fase de grupos de la Liga Europa
|
9
|
Sheffield United
|
54
|
38
|
14
|
12
|
12
|
39
|
39
|
0
|
NA
|
10
|
Burnley
|
54
|
38
|
15
|
9
|
14
|
43
|
50
|
-7
|
NA
|
11
|
Southampton
|
52
|
38
|
15
|
7
|
16
|
51
|
60
|
-9
|
NA
|
12
|
Everton
|
49
|
38
|
13
|
10
|
15
|
44
|
56
|
-12
|
NA
|
13
|
Newcastle United
|
44
|
38
|
11
|
11
|
16
|
38
|
58
|
-20
|
NA
|
14
|
Crystal Palace
|
43
|
38
|
11
|
10
|
17
|
31
|
50
|
-19
|
NA
|
15
|
Brighton & Hove Albion
|
41
|
38
|
9
|
14
|
15
|
39
|
54
|
-15
|
NA
|
16
|
West Ham United
|
39
|
38
|
10
|
9
|
19
|
49
|
62
|
-13
|
NA
|
17
|
Aston Villa
|
35
|
38
|
9
|
8
|
21
|
41
|
67
|
-26
|
NA
|
18
|
Bournemouth (R)
|
34
|
38
|
9
|
7
|
22
|
40
|
65
|
-25
|
Descenso de Categoria
|
19
|
Watford (R)
|
34
|
38
|
8
|
10
|
20
|
36
|
64
|
-28
|
Descenso de Categoria
|
20
|
Norwich City (R)
|
21
|
38
|
5
|
6
|
27
|
26
|
75
|
-49
|
Descenso de Categoria
|
3. Analisis Clasificacion Siguiente Temporada
Competiciones Europeas y Descenso de Categoria
En esta grafica podemos observar la clasificacon a competiciones europeas de los primeros clasificados en la tabla y sus respectivos puntos onseguidos, los primeros 4 puestos clasifican a la Champions League y los 5 y 6 lugar a la Europa Legue. Podemos destacar la actuacion del Arsenal que al haber ganado la FA Cup tuvo como premio formar parte de la Europa League. Por ultimo, observamos los 3 equipos con menos puntos (Watford, Bournemouth y Norwich City) que jugaran la proxima temporada 20/21 en la segunda division de inglaterra (EFL Championship).
Grafico 1
Grafico 2
4. Analisis Goles Anotados
Equipos con mas Goles Anotados
En este grafico 3 estudiamos a los 5 grandes clubes que anotaron mayores goles esta temporada. Destacamos al Manchester City que logro sobrepasar la brecha de los 100 goles anotando 102 goles esta temporada. Tambien podemos concluir que estos equipos son igualmente los 5 primeros en la tabla de clasificacion por lo que mientras mas goles anotados mas posibilidades tienes de sumar mayor cantidad de puntos y colocarse en lo mas alto de la tabla. En el grafico 4 encontramos a todos los equipos de la temporada, con 1034 goles y una media de 51,4 goles por equipo y de 27,21 goles por partido termina la tempoara atipica en Inglaterra.
Grafico 3
Grafico 4
Los Pichichis (Jugadores con mas goles en la temporada)
En esta tabla podemos observar a los maximos anotadores y las estadisticas de cada jugador respecto a los partidos y minutos jugados en todos los partidos de la temporada. En el como maximo goleador aparece el jugador ingles Jamie Vardy (Leicester City) con 23 dianas, seguido de un empate en goles y terminando el podio el jugador gabones Pierre-Emerick Aubameyang (Arsenal) y el jugador ingles Danny Ings (Southampton).
jugador
|
goles
|
partidosjugados
|
Promediogpp
|
minutosjugados
|
minutopgol
|
Club
|
Jamie Vardy
|
23
|
35
|
0.66
|
3034
|
132
|
Leicester City
|
Pierre-Emerick Aubameyang
|
22
|
36
|
0.61
|
3138
|
143
|
Arsenal
|
Danny Ings
|
22
|
38
|
0.58
|
2812
|
128
|
Southampton
|
Raheem Sterling
|
20
|
33
|
0.61
|
2660
|
133
|
Manchester City
|
Mohamed Salah
|
19
|
34
|
0.56
|
2884
|
152
|
Liverpool
|
Harry Kane
|
18
|
29
|
0.62
|
2589
|
144
|
Tottenham
|
Sadio Mané
|
18
|
35
|
0.51
|
2753
|
153
|
Liverpool
|
Marcus Rashford
|
17
|
31
|
0.55
|
2653
|
156
|
Manchester United
|
Anthony Martial
|
17
|
32
|
0.53
|
2638
|
155
|
Manchester United
|
Raúl Jiménez
|
17
|
38
|
0.45
|
3244
|
191
|
Wolverhampton
|
6. Premios en la Temporada
Los mas galardonados de la temporada, ya mencionado anteriormente, sin duda alguna el mas destacado, el futbolista kevin De Bruyne fue el MVP mejor jugador de la temporada y recibio el premio playmaker al mejor armador de juego en la temporada. Tambien podemos destacar el gol de la temporada anotado por el coreano Heugh-Min Son que lo podemos ver luego de la tabla. La bota de Oro para el mayor anotador mencionado antes Jamie Vardy. mejor jugador mas joven o golden boy de la temporada se lo lleva el jugador del Liverpool Alexander-Arnold. Tambien vemos premios como al mejor manager Jurguen Klopp y el guante de oro para el portero del Manchester City Ederson.
7. Estadios de los Equipos de Primera Division Temporada 19/20
Para complementar este analisis conoceremos los estadios de los 20 equipos que se dejaron la piel este año combatiendo partido a partido en estos grandes campos de juego. Nos encontramos con la ubicacion de cada uno de los campos en las distintas ciudades de Inglaterra. Como dato interesante la distancia mas larga recorrida entre dos equipos es de 568 kilometros, que es la distancia que tienen que recorrer los equipos New Castle United y Bournemouth para sus respectivos enfrentamientos. Ademas podemos destacar la ciudad de Liverpool donde los estadios del Liverpool y el Everton los separa una distancia solo de 1,9 kilometros. Por ultimo podemos observar que en la ciudad de Londres se encuentran 5 equipos los cuales son: West Ham United, Chelsea, Tottenham, Arsenal y el Crystal Palace.
8. Conclusión
La atipica temporada 2019-2020 nos ha dejado unos recuerdos inolvidables que son para la historia de este gran campeonato. La pandemia del covid-19 no impidio que el Liverpool levantara su ansiada y esperada Premier League luego de 30 años de sequia domestica. Su futbol arrollador y dominante destaco rompiendo records y consiguiendo una unica derrota en toda la temporada. Ademas, La inclusion del VAR desde mi punto de vista ha sido favorable para esta competicion ya que ha dotado al conjunto arbitral con una ayuda extra en el estudio de jugadas decisivas. Tambien podemos acotar que no hubo una gran competencia o disputa para la consecucion de los puestos para la Champions League ya que tanto el Liverpool (campeon) y el Manchester City presentaban una amplia ventaja en puntos con el resto de sus competidores. Sin embargo, la fuerte pelea por estos ultimos puestos europeos (tercero y cuarto clasificado) fue la frenetica disputa de varios equipos (Leicester, Tottenham, Wolves) que al final terminaron como vencedores el Chelsea y el Manchester United.
Referencias
Para la realización del trabajo he utilizado:
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-16
- Packages -------------------------------------------------------------------
package * version date lib source
assertthat 0.2.1 2019-03-21 [1] CRAN (R 4.0.2)
backports 1.1.10 2020-09-15 [1] CRAN (R 4.0.2)
base64enc 0.1-3 2015-07-28 [1] CRAN (R 4.0.0)
blob 1.2.1 2020-01-20 [1] CRAN (R 4.0.2)
broom 0.7.0 2020-07-09 [1] CRAN (R 4.0.2)
cellranger 1.1.0 2016-07-27 [1] CRAN (R 4.0.2)
checkmate 2.0.0 2020-02-06 [1] CRAN (R 4.0.2)
class 7.3-17 2020-04-26 [2] CRAN (R 4.0.2)
classInt 0.4-3 2020-04-07 [1] CRAN (R 4.0.2)
cli 2.0.2 2020-02-28 [1] CRAN (R 4.0.2)
codetools 0.2-16 2018-12-24 [2] CRAN (R 4.0.2)
colorspace 1.4-1 2019-03-18 [1] CRAN (R 4.0.2)
commonmark 1.7 2018-12-01 [1] CRAN (R 4.0.2)
cpp11 0.2.1 2020-08-11 [1] CRAN (R 4.0.2)
crayon 1.3.4 2017-09-16 [1] CRAN (R 4.0.2)
crosstalk 1.1.0.1 2020-03-13 [1] CRAN (R 4.0.2)
curl 4.3 2019-12-02 [1] CRAN (R 4.0.2)
data.table 1.13.0 2020-07-24 [1] CRAN (R 4.0.2)
DBI 1.1.0 2019-12-15 [1] CRAN (R 4.0.2)
dbplyr 1.4.4 2020-05-27 [1] CRAN (R 4.0.2)
digest 0.6.25 2020-02-23 [1] CRAN (R 4.0.2)
dplyr * 1.0.2 2020-08-18 [1] CRAN (R 4.0.2)
e1071 1.7-3 2019-11-26 [1] CRAN (R 4.0.2)
ellipsis 0.3.1 2020-05-15 [1] CRAN (R 4.0.2)
evaluate 0.14 2019-05-28 [1] CRAN (R 4.0.2)
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.2)
farver 2.0.3 2020-01-16 [1] CRAN (R 4.0.2)
forcats * 0.5.0 2020-03-01 [1] CRAN (R 4.0.2)
fs 1.5.0 2020-07-31 [1] CRAN (R 4.0.2)
gdtools 0.2.2 2020-04-03 [1] CRAN (R 4.0.2)
generics 0.0.2 2018-11-29 [1] CRAN (R 4.0.2)
gganimate * 1.0.6 2020-07-08 [1] CRAN (R 4.0.2)
ggplot2 * 3.3.2 2020-06-19 [1] CRAN (R 4.0.2)
ggrepel 0.8.2 2020-03-08 [1] CRAN (R 4.0.2)
ggthemes * 4.2.0 2019-05-13 [1] CRAN (R 4.0.2)
gifski 0.8.6 2018-09-28 [1] CRAN (R 4.0.2)
glue 1.4.2 2020-08-27 [1] CRAN (R 4.0.2)
gridExtra 2.3 2017-09-09 [1] CRAN (R 4.0.2)
gt * 0.2.2 2020-08-05 [1] CRAN (R 4.0.3)
gtable 0.3.0 2019-03-25 [1] CRAN (R 4.0.2)
haven 2.3.1 2020-06-01 [1] CRAN (R 4.0.2)
here 0.1 2017-05-28 [1] CRAN (R 4.0.2)
highr 0.8 2019-03-20 [1] CRAN (R 4.0.2)
hms 0.5.3 2020-01-08 [1] CRAN (R 4.0.2)
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.2)
htmlwidgets 1.5.1 2019-10-08 [1] CRAN (R 4.0.2)
httr 1.4.2 2020-07-20 [1] CRAN (R 4.0.2)
jsonlite 1.7.1 2020-09-07 [1] CRAN (R 4.0.2)
kableExtra * 1.3.1 2020-10-22 [1] CRAN (R 4.0.3)
KernSmooth 2.23-17 2020-04-26 [2] CRAN (R 4.0.2)
klippy * 0.0.0.9500 2020-11-13 [1] Github (rlesur/klippy@378c247)
knitr * 1.29 2020-06-23 [1] CRAN (R 4.0.2)
labeling 0.3 2014-08-23 [1] CRAN (R 4.0.0)
lattice 0.20-41 2020-04-02 [2] CRAN (R 4.0.2)
lazyeval 0.2.2 2019-03-15 [1] CRAN (R 4.0.2)
leafem 0.1.3 2020-07-26 [1] CRAN (R 4.0.2)
leaflet * 2.0.3 2019-11-16 [1] CRAN (R 4.0.2)
lifecycle 0.2.0 2020-03-06 [1] CRAN (R 4.0.2)
lubridate 1.7.9 2020-06-08 [1] CRAN (R 4.0.2)
magrittr 1.5 2014-11-22 [1] CRAN (R 4.0.2)
modelr 0.1.8 2020-05-19 [1] CRAN (R 4.0.2)
munsell 0.5.0 2018-06-12 [1] CRAN (R 4.0.2)
pillar 1.4.6 2020-07-10 [1] CRAN (R 4.0.2)
pkgconfig 2.0.3 2019-09-22 [1] CRAN (R 4.0.2)
plotly * 4.9.2.1 2020-04-04 [1] CRAN (R 4.0.2)
png 0.1-7 2013-12-03 [1] CRAN (R 4.0.0)
prettyunits 1.1.1 2020-01-24 [1] CRAN (R 4.0.2)
progress 1.2.2 2019-05-16 [1] CRAN (R 4.0.2)
purrr * 0.3.4 2020-04-17 [1] CRAN (R 4.0.2)
R6 2.4.1 2019-11-12 [1] CRAN (R 4.0.2)
raster 3.3-13 2020-07-17 [1] CRAN (R 4.0.2)
Rcpp 1.0.5 2020-07-06 [1] CRAN (R 4.0.2)
reactable * 0.2.3 2020-10-04 [1] CRAN (R 4.0.3)
readr * 1.3.1 2018-12-21 [1] CRAN (R 4.0.2)
readxl * 1.3.1 2019-03-13 [1] CRAN (R 4.0.2)
reprex 0.3.0 2019-05-16 [1] CRAN (R 4.0.2)
rlang 0.4.7 2020-07-09 [1] CRAN (R 4.0.2)
rmarkdown 2.3 2020-06-18 [1] CRAN (R 4.0.2)
rprojroot 1.3-2 2018-01-03 [1] CRAN (R 4.0.2)
rstudioapi 0.11 2020-02-07 [1] CRAN (R 4.0.2)
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.2)
sass 0.2.0 2020-03-18 [1] CRAN (R 4.0.3)
scales 1.1.1 2020-05-11 [1] CRAN (R 4.0.2)
sessioninfo 1.1.1 2018-11-05 [1] CRAN (R 4.0.2)
sf 0.9-6 2020-09-13 [1] CRAN (R 4.0.2)
sp 1.4-2 2020-05-20 [1] CRAN (R 4.0.2)
stringi 1.5.3 2020-09-09 [1] CRAN (R 4.0.2)
stringr * 1.4.0 2019-02-10 [1] CRAN (R 4.0.2)
systemfonts 0.3.1 2020-09-08 [1] CRAN (R 4.0.2)
tibble * 3.0.3 2020-07-10 [1] CRAN (R 4.0.2)
tidyr * 1.1.2 2020-08-27 [1] CRAN (R 4.0.2)
tidyselect 1.1.0 2020-05-11 [1] CRAN (R 4.0.2)
tidyverse * 1.3.0 2019-11-21 [1] CRAN (R 4.0.2)
tweenr 1.0.1 2018-12-14 [1] CRAN (R 4.0.2)
units 0.6-7 2020-06-13 [1] CRAN (R 4.0.2)
vctrs 0.3.4 2020-08-29 [1] CRAN (R 4.0.2)
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.2)
viridisLite * 0.3.0 2018-02-01 [1] CRAN (R 4.0.2)
webshot 0.5.2 2019-11-22 [1] CRAN (R 4.0.2)
withr 2.2.0 2020-04-20 [1] CRAN (R 4.0.2)
wordcloud2 * 0.2.1 2018-01-03 [1] CRAN (R 4.0.3)
xfun 0.17 2020-09-09 [1] CRAN (R 4.0.2)
xml2 1.3.2 2020-04-23 [1] CRAN (R 4.0.2)
yaml 2.2.1 2020-02-01 [1] CRAN (R 4.0.2)
[1] C:/Users/Vicente Celis/Documents/R/win-library/4.0
[2] C:/Program Files/R/R-4.0.2/library
LS0tDQp0aXRsZTogPGNlbnRlcj48Rk9OVCBDT0xPUj0iZGFya2JsdWUiPkVuZ2xpc2ggUHJlbWllciBMZWFndWUgMjAxOS8yMDIwPC9GT05UPjwvY2VudGVyPg0Kc3VidGl0bGU6ICJWaWNlbnRlIENlbGlzICh2aWNlcm9uQGFsdW1uaS51di5lcykiDQphdXRob3I6ICJVbml2ZXJzaXRhdCBkZSBWYWzDqG5jaWEiDQpkYXRlOiAiRGljaWVtYnJlIGRlIDIwMjAgKGFjdHVhbGl6YWRvIGVsIGByIGZvcm1hdChTeXMudGltZSgpLCAnJWQtJW0tJVknKWApIg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgICNjc3M6ICIuL2Fzc2V0cy9teV9jc3NfZmlsZS5jc3MiDQogICAgdGhlbWU6IGpvdXJuYWwNCiAgICBoaWdobGlnaHQ6IHRleHRtYXRlIA0KICAgIHRvYzogdHJ1ZQ0KICAgIHRvY19kZXB0aDogMyANCiAgICB0b2NfZmxvYXQ6IA0KICAgICAgY29sbGFwc2VkOiB0cnVlDQogICAgICBzbW9vdGhfc2Nyb2xsOiB0cnVlDQogICAgc2VsZl9jb250YWluZWQ6IHRydWUNCiAgICBudW1iZXJfc2VjdGlvbnM6IGZhbHNlDQogICAgZGZfcHJpbnQ6IGthYmxlDQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQ0KZWRpdG9yX29wdGlvbnM6IA0KICBjaHVua19vdXRwdXRfdHlwZTogY29uc29sZQ0KLS0tDQoNCmBgYHtyIHBhY2thZ2VzLXNldHVwLCBpbmNsdWRlID0gRkFMU0V9DQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoa2xpcHB5KSAgDQpsaWJyYXJ5KGtuaXRyKQ0KbGlicmFyeShyZWFkeGwpDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeShnZ3RoZW1lcykNCmxpYnJhcnkobGVhZmxldCkNCmxpYnJhcnkoZ2dhbmltYXRlKQ0KbGlicmFyeShwbG90bHkpDQpsaWJyYXJ5KGthYmxlRXh0cmEpDQpsaWJyYXJ5KHdvcmRjbG91ZDIpDQpsaWJyYXJ5KHJlYWN0YWJsZSkNCmxpYnJhcnkodmVtYmVkcikNCmxpYnJhcnkodmlyaWRpcykNCmxpYnJhcnkoaHJicnRoZW1lcykNCmxpYnJhcnkoZ3QpDQpgYGANCg0KYGBge3IgY2h1bmstc2V0dXAsIGluY2x1ZGUgPSBGQUxTRX0NCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSwgZXZhbCA9IFRSVUUsIG1lc3NhZ2UgPSBGQUxTRSwgd2FybmluZyA9IEZBTFNFLCANCiAgICAgICAgICAgICAgICAgICAgICAjcmVzdWx0cyA9ICJob2xkIiwNCiAgICAgICAgICAgICAgICAgICAgICBjYWNoZSA9IEZBTFNFLCBjYWNoZS5wYXRoID0gIi9jYWNoZXMvIiwgY29tbWVudCA9ICIjPiIsDQogICAgICAgICAgICAgICAgICAgICAgI2ZpZy53aWR0aCA9IDcsICNmaWcuaGVpZ2h0PSA3LCAgIA0KICAgICAgICAgICAgICAgICAgICAgICNvdXQud2lkdGggPSA3LCBvdXQuaGVpZ2h0ID0gNywNCiAgICAgICAgICAgICAgICAgICAgICBjb2xsYXBzZSA9IFRSVUUsICBmaWcuc2hvdyA9ICJob2xkIiwNCiAgICAgICAgICAgICAgICAgICAgICBmaWcuYXNwID0gNy85LCBvdXQud2lkdGggPSAiNjAlIiwgZmlnLmFsaWduID0gImNlbnRlciIpDQprbml0cjo6b3B0c19jaHVuayRzZXQoZGV2ID0gInBuZyIsIGRldi5hcmdzID0gbGlzdCh0eXBlID0gImNhaXJvLXBuZyIpKQ0KYGBgDQoNCmBgYHtyIG9wdGlvbnMtc2V0dXAsIGluY2x1ZGUgPSBGQUxTRX0NCm9wdGlvbnMoc2NpcGVuID0gOTk5KSAjLSBwYXJhIHF1aXRhciBsYSBub3RhY2nDs24gY2llbnTDrWZpY2ENCm9wdGlvbnMoInlhbWwuZXZhbC5leHByIiA9IFRSVUUpIA0KYGBgDQoNCg0KYGBge3Iga2xpcHB5LCBlY2hvID0gRkFMU0V9DQprbGlwcHk6OmtsaXBweShwb3NpdGlvbiA9IGMoInRvcCIsICJyaWdodCIpKSAjLSByZW1vdGVzOjppbnN0YWxsX2dpdGh1Yigicmxlc3VyL2tsaXBweSIpDQpgYGANCg0KPGhyIGNsYXNzPSJsaW5lYS1ibGFjayI+DQoNClRyYWJham8gZWxhYm9yYWRvIHBhcmEgbGEgYXNpZ25hdHVyYSAiUHJvZ3JhbWFjacOzbiB5IG1hbmVqbyBkZSBkYXRvcyBlbiBsYSBlcmEgZGVsIEJpZyBEYXRhIiBkZSBsYSBVbml2ZXJzaXRhdCBkZSBWYWzDqG5jaWEgZHVyYW50ZSBlbCBjdXJzbyAyMDIwLTIwMjEuIEVsIHJlcG8gZGVsIHRyYWJham8gZXN0w6EgW2FxdcOtXShodHRwczovL2dpdGh1Yi5jb20vdmljZW50ZWNlbGlzci90cmFiYWpvX0JpZ0RhdGEpe3RhcmdldD0iX2JsYW5rIn0uIExhIHDDoWdpbmEgd2ViIGRlIGxhIGFzaWduYXR1cmEgeSBsb3MgdHJhYmFqb3MgZGUgbWlzIGNvbXBhw7Flcm9zIHB1ZWRlbiB2ZXJzZSBbYXF1w61dKGh0dHBzOi8vcGVyZXpwNDQuZ2l0aHViLmlvL2ludHJvLWRzLTIwLTIxLXdlYi8wNy10cmFiYWpvcy5odG1sKXt0YXJnZXQ9Il9ibGFuayJ9Lg0KDQo8aHIgY2xhc3M9ImxpbmVhLXJlZCI+DQoNCg0KLS0tLS0tLS0tLS0tLS0tLS0NCg0KPGJyPg0KDQpgYGB7ciBldmFsPVRSVUUsIGVjaG89RkFMU0V9DQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhoZXJlOjpoZXJlKCJpbWFnZW5lcyIsICJwcmVtaWVybC5wbmciKSkNCg0KYGBgDQoNCg0KIyA8Rk9OVCBDT0xPUj0iZGFya2JsdWUiPjEuIEludHJvZHVjY2nDs248L0ZPTlQ+DQoNCkVzdGUgdHJhYmFqbyBzZSByZWFsaXphIGNvbiBlbCBmaW4gZGUgYW5hbGl6YXIgbGFzIGVzdGFkaXN0aWNhcyBkZSBsb3MgZXF1aXBvcyB5IGp1Z2Fkb3JlcyBkZSBsYSBwcmltZXJhIGRpdmlzaW9uIGRlIGxhIGxpZ2EgZGUgSW5nbGF0ZXJyYS4gQ29uc2lkZXJhZGEgdW5hIGRlIGxhcyA1IGdyYW5kZXMgbGlnYXMgZXVyb3BlYXMgcXVlIHBhcmEgbXVjaG9zLCBzdXMgMzggam9ybmFkYXMsIGxhIGNvbnZpZXJ0ZW4gZW4gbGEgbWFzIGNvbXBldGl0aXZhIHkgcmVsZXZhbnRlIGRlbCBtdW5kbywgdGFtYmllbiBncmFjaWFzIGEgc3UgaGlzdG9yaWEgeSBhIGxhIHBhcnRpY2lwYWNpb24gZGUgdGFudG9zIGdyYW5kZXMgY2x1YmVzIGNvbW8gTWFuY2hlc3RlciBVbml0ZWQsIENoZWxzZWEsIExpdmVycG9vbCBlbnRyZSBvdHJvcy4gSWx1dHJhcmVtb3MgbGEgdGFibGEgZGUgY2xhc2lmaWNhY2lvbiBkZSBjYWRhIGVxdWlwbywgZWwgQ2FtcGVvbiBkZSBsYSBsaWdhLCBsb3MgZGVzY2Vuc29zIGEgbGEgc2VndW5kYSBkaXZpc2lvbiB5IGxvcyBlcXVpcG9zIHF1ZSBhbGNhbnphcm9uIGxhcyBtYXhpbWFzIGNvbXBldGljaW9uZXMgZXVyb3BlYXMgKENoYW1waW9ucyBMZWFndWUgeSBFdXJvcGEgTGVhZ3VlKS4gQWRlbWFzIGVzdHVkaWFyZW1vcyBsb3MgbWF4aW1vcyBnb2xlYWRvcmVzIGRlIGxhIHRlbXBvcmFkYSB0YW50byBwb3IgZXF1aXBvcyBjb21vIGp1Z2Fkb3JlcyBtZWRpYW50ZSBsYSB1dGlsaXphY2lvbiBkZSBncmFmaWNvcyBpbHVzdHJhdGl2b3MuIFBvciB1bHRpbW8sIGNvbm9jZXJlbW9zIGxvcyBlc3RhZGlvcyBkb25kZSBzZSBqdWVnYW4gbG9zIHBhcnRpZG9zIGRlIGVzdGEgbWF4aW1hIGNvbXBldGljaW9uLCBzZcOxYWxhbmRvIHZhcmlvcyBhc3BlY3RvcyBpbnRlcmVzYW50ZXMgcXVlIG5vcyBheXVkYXJhbiBhIGFkZW50cmFybm9zIGEgdW4gbWFzIGVuIGVzdGEgZ3JhbmRpb3NhIGNvbXBldGljaW9uIGluZ2xlc2EuIA0KDQotLS0tLS0tLS0tLS0tLS0tDQoNCiMjIDxGT05UIENPTE9SPSJkYXJrYmx1ZSI+RGF0b3M8L0ZPTlQ+IHsudGFic2V0IC50YWJzZXQtcGlsbHN9DQoNCiMjIyA8Rk9OVCBDT0xPUj0iZGFya2JsdWUiPioqRnVlbnRlIGRlIGxvcyBEYXRvcyoqPC9GT05UPiANCg0KDQpMb3MgZGF0b3MgZnVlcm9uIG9idGVuaWRvcyBkZSB2YXJpYXMgcGFnaW5hcyBjb21vIGVsIGRpYXJpbyBNYXJjYSwgV2lraXBlZGlhIHkgbGEgcGFnaW5hIG9maWNpYWwgZGUgbGEgUHJlbWllciBMZWFndWUgeSBsdWVnbyBmdWVyb24gbW9kaWZpY2Fkb3MgcG9yIG1pIGVuIHVuIGV4Y2VsIGluY2x1aWRvIGVuIGxhIGNhcnBldGEgZGF0b3MuIExhIG1hbmlwdWxhY2lvbiBkZSBsb3MgZGF0b3Mgc2UgcmVhbGl6YXJvbiBncmFjaWFzIGEgbG9zIHNsaWRlcyB5IHR1dG9yaWFsZXMgc3VtaW5pc3RyYWRvcyBwb3IgZWwgcHJvZmVzb3IgZGUgbGEgbWF0ZXJpYSBQZWRybyBQZXJlei4NCg0KDQojIyMgPEZPTlQgQ09MT1I9ImRhcmtibHVlIj4qKkNvZGlnb3MqKjwvRk9OVD4NCg0KYGBge3IgZXZhbD1UUlVFLCBpbmNsdWRlPVRSVUUsIGVjaG89VFJVRX0NCg0KY2xhc2lmIDwtIHJlYWRfZXhjZWwoIi4vZGF0b3MvcHJlbWllci1sZWFndWUueGxzeCIsIHNoZWV0ID0gMSkNCg0KbWF4X2dvbCA8LSByZWFkX2V4Y2VsKCIuL2RhdG9zL3ByZW1pZXItbGVhZ3VlLnhsc3giLCBzaGVldCA9IDIgKQ0KDQphc2lzdGVuY2lhIDwtIHJlYWRfZXhjZWwoIi4vZGF0b3MvcHJlbWllci1sZWFndWUueGxzeCIsIHNoZWV0ID0gMyApDQoNCnByZW1pbyA8LSByZWFkX2V4Y2VsKCIuL2RhdG9zL3ByZW1pZXItbGVhZ3VlLnhsc3giLCBzaGVldCA9IDQgKQ0KDQpjbGFzaWZfMSA8LSBjbGFzaWYgJT4lIGZpbHRlcighKGlzLm5hKENsYXNpZjIwMjEpKSkgJT4lIHNlbGVjdChQb3MsIEVxdWlwbywgUHRzLCBDbGFzaWYyMDIxKQ0KDQpzdHIoY2xhc2lmXzEpICANCg0KY2xhc2lmXzEgPC0gY2xhc2lmXzEgJT4lIG11dGF0ZShFcXVpcG8gPSBmb3JjYXRzOjphc19mYWN0b3IoRXF1aXBvKSkgIA0KDQpzdHIoY2xhc2lmXzEpIA0KDQpsZXZlbHMoY2xhc2lmXzEkRXF1aXBvKQ0KDQpjbGFzaWZfMSA8LSBjbGFzaWZfMSAlPiUgbXV0YXRlKEVxdWlwbyA9IGZvcmNhdHM6OmZjdF9yZW9yZGVyKEVxdWlwbywgUHRzKSkgDQoNCmxldmVscyhjbGFzaWZfMSRFcXVpcG8pDQoNCnRvcF9nZiA8LSBjbGFzaWYgJT4lIHNlbGVjdChFcXVpcG8sIEdGKSAlPiUgc2xpY2VfbWF4KEdGLCBuID0gNSkNCg0Kc3RyKHRvcF9nZikgIA0KDQp0b3BfZ2YgPC0gdG9wX2dmICU+JSBtdXRhdGUoRXF1aXBvID0gZm9yY2F0czo6YXNfZmFjdG9yKEVxdWlwbykpICANCg0Kc3RyKHRvcF9nZikgDQoNCmxldmVscyh0b3BfZ2YkRXF1aXBvKQ0KDQp0b3BfZ2YgPC0gdG9wX2dmICU+JSBtdXRhdGUoRXF1aXBvID0gZm9yY2F0czo6ZmN0X3Jlb3JkZXIoRXF1aXBvLCBHRikpIA0KDQpsZXZlbHModG9wX2dmJEVxdWlwbykNCg0KDQpsZWFmbGV0KCkgJT4lIGFkZFRpbGVzKCkgJT4lIGxlYWZlbTo6YWRkTW91c2VDb29yZGluYXRlcygpDQoNCmBgYA0KDQoNCi0tLS0tLS0tLS0tLS0tLS0NCg0KIyAgPEZPTlQgQ09MT1I9ImRhcmtibHVlIj4yLiBUYWJsYSBkZSBsYSBFbmdsaXNoIFByZW1pZXIgTGVhZ3VlIFRlbXBvcmFkYSAyMDE5LzIwMjA8L0ZPTlQ+DQoNCkxhIHRlbXBvcmFkYSAyMDE5LzIwMjAgZnVlIHVuIGHDsW8gbXV5IHNpbmd1bGFyIHkgZXN0byBkZWJpZG8gYSBsYSBwYW5kZW1pYSBtdW5kaWFsIHF1ZSB0b2RvcyBjb25vY2Vtb3MgY29tbyBsbyBmdWUgZWwgY29yb25hdmlydXMuIEVzdGEgc2l0dWFjaW9uIHBhbmRlbWljYSBwcm92b2NvIGxhIGRldGVuY2lvbiBkZSBsb3MgcGFydGlkb3MgZGVzZGUgbGEgam9ybmFkYSAyOCBkZWwgMSBkZSBNYXJ6byBoYXN0YSBlbCAxNyBkZSBqdW5pbyBxdWUgc2UgcHVkbyByZWFudWRhci4gU2luIGVtYmFyZ28geSBwZXNlIGEgZXN0b3MgMyBtZXNlcyBkZSBsYSBmYWx0YSBkZSBlc3RlIGdyYW4gZnV0Ym9sLCBkZWpvIHZhcmlvcyBhc3BlY3RvcyByZWxldmFudGVzOiBsb2dyYXIgZWwgTGl2ZXJwb29sIGNvbnNlZ3VpciBlbCB0aXR1bG8gZGUgY2FtcGVvbiBkZXNwdcOpcyBkZSAzMCBhw7FvcyB0cmFzIHN1IMO6bHRpbWEgdmljdG9yaWEgeSBwcmltZXJvIGNvbiBsYSBkZW5vbWluYWNpb24gUHJlbWllciBMZWFndWUuIEFkZW1hcyBoYWJlcmxvIGNvbnNlZ3VpZG8gcm9tcGllbmRvIHZhcmlvcyByZWNvcmRzIGNvbW8gc2VyIGVsIHByaW1lciBlcXVpcG8gZGUgbGEgY29tcGV0aWNpw7NuIHkgZGUgRXVyb3BhIHF1ZSBjbGFzaWZpY8OzIG3DoXMgYW50aWNpcGFkYW1lbnRlIGEgbGEgZmFzZSBkZSBncnVwb3MgZGUgbGEgTGlnYSBkZSBDYW1wZW9uZXMgZGUgbGEgVUVGQSAoMTIgZmVjaGFzIGRlIGFudGljaXBhY2nDs24pLiBUYW1iaWVuIGNhYmUgYSBkZXN0YWNhciBxdWUgaW50cm9kdWpvIHBvciBwcmltZXJhIHZleiBsYSB0ZWNub2xvZ2lhIFZBUiAoVmlkZW8gQXJiaXRyYWplKS4NCg0KPiAiRXMgaW5jcmXDrWJsZSBzZXIgY2FtcGXDs24gY29uIGVzdGUgZXF1aXBvLiBIYSBzaWRvIG11eSBmw6FjaWwgbW90aXZhciBhIGxvcyBqdWdhZG9yZXMgcG9yIGxhIGdyYW4gaGlzdG9yaWEgcXVlIHRpZW5lIGVsIGNsdWIuIEVzIHVuIGxvZ3JvIGluY3Jlw61ibGUgcGFyYSBtaXMganVnYWRvcmVzLCBsbyBlcyB0b2RvIGxvIHF1ZSBoYW4gaGVjaG8gZHVyYW50ZSBsb3Mgw7psdGltb3MgdHJlcyBhw7FvcyIuIErDvHJnZW4gS2xvcHAgDQoNCmBgYHtyIGV2YWw9VFJVRSwgZWNobz1GQUxTRX0NCg0Ka2FibGUoY2xhc2lmKSAlPiUNCiAga2FibGVFeHRyYTo6a2FibGVfc3R5bGluZyhmaXhlZF90aGVhZCA9IGxpc3QoZW5hYmxlZCA9IFQsIGJhY2tncm91bmQgPSAibGlnaHRibHVlIikpICU+JSAgY29sdW1uX3NwZWMoMywgYm9sZCA9IFQsIGNvbG9yID0gIndoaXRlIiwgYmFja2dyb3VuZCA9ICJsaWdodGJsdWUiKSANCg0KDQpgYGANCg0KDQojIyMgPEZPTlQgQ09MT1I9ImRhcmtibHVlIj5VbmEgZm9ybWEgZGUgdmlzdWFsaXphciBsb3MgcHVudG9zIG9idGVuaWRvcyBlbiBsYSBsaWdhPC9GT05UPg0KDQpgYGB7ciBldmFsPVRSVUUsIGVjaG89RkFMU0UsIG91dC53aWR0aCA9ICI4MCUifQ0KDQpjbGFzaWZfMiA8LSBjbGFzaWYgJT4lIHNlbGVjdChjKEVxdWlwbywgUHRzKSkNCg0Kd29yZGNsb3VkMihkYXRhID0gY2xhc2lmXzIsIHNpemUgPSAwLjMpDQoNCmBgYA0KDQotLS0tLS0tLS0tLS0tLS0tDQoNCmBgYHtyIGV2YWwgPSBUUlVFLCBlY2hvID0gRkFMU0V9DQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhoZXJlOjpoZXJlKCJpbWFnZW5lcyIsICJsaXZlcnBvb2wtY2hhbXBpb25zLmpwZyIpKQ0KDQpgYGANCg0KLS0tLS0tLS0tLS0tLS0tLQ0KDQojICAgPEZPTlQgQ09MT1I9ImRhcmtibHVlIj4zLiBBbmFsaXNpcyBDbGFzaWZpY2FjaW9uIFNpZ3VpZW50ZSBUZW1wb3JhZGE8L0ZPTlQ+IA0KIyMgPEZPTlQgQ09MT1I9ImRhcmtibHVlIj5Db21wZXRpY2lvbmVzIEV1cm9wZWFzIHkgRGVzY2Vuc28gZGUgQ2F0ZWdvcmlhPC9GT05UPiB7LnRhYnNldCAudGFic2V0LXBpbGxzfQ0KDQoNCkVuIGVzdGEgZ3JhZmljYSBwb2RlbW9zIG9ic2VydmFyIGxhIGNsYXNpZmljYWNvbiBhIGNvbXBldGljaW9uZXMgZXVyb3BlYXMgZGUgbG9zIHByaW1lcm9zIGNsYXNpZmljYWRvcyBlbiBsYSB0YWJsYSB5IHN1cyByZXNwZWN0aXZvcyBwdW50b3Mgb25zZWd1aWRvcywgbG9zIHByaW1lcm9zIDQgcHVlc3RvcyBjbGFzaWZpY2FuIGEgbGEgQ2hhbXBpb25zIExlYWd1ZSB5IGxvcyA1IHkgNiBsdWdhciBhIGxhIEV1cm9wYSBMZWd1ZS4gUG9kZW1vcyBkZXN0YWNhciBsYSBhY3R1YWNpb24gZGVsIEFyc2VuYWwgcXVlIGFsIGhhYmVyIGdhbmFkbyBsYSBGQSBDdXAgdHV2byBjb21vIHByZW1pbyBmb3JtYXIgcGFydGUgZGUgbGEgRXVyb3BhIExlYWd1ZS4gUG9yIHVsdGltbywgb2JzZXJ2YW1vcyBsb3MgMyBlcXVpcG9zIGNvbiBtZW5vcyBwdW50b3MgKFdhdGZvcmQsIEJvdXJuZW1vdXRoIHkgTm9yd2ljaCBDaXR5KSBxdWUganVnYXJhbiBsYSBwcm94aW1hIHRlbXBvcmFkYSAyMC8yMSBlbiBsYSBzZWd1bmRhIGRpdmlzaW9uIGRlIGluZ2xhdGVycmEgKEVGTCBDaGFtcGlvbnNoaXApLg0KDQoNCg0KIyMjIDxGT05UIENPTE9SPSJkYXJrYmx1ZSI+KipHcmFmaWNvIDEqKjwvRk9OVD4gDQoNCmBgYHtyIGV2YWwgPSBUUlVFLCBlY2hvID0gRkFMU0UsIG91dC53aWR0aCA9ICI4MCUifQ0KDQpwIDwtIGdncGxvdChjbGFzaWZfMSwgYWVzKHggPSBFcXVpcG8sIHkgPSBQdHMpKSArIA0KICBnZW9tX2NvbChmaWxsID0gYygibWlkbmlnaHRibHVlIiwgIm1pZG5pZ2h0Ymx1ZSIsICJtaWRuaWdodGJsdWUiLCANCiAgICAgICAgICAgICAgICAgICAgICAibWlkbmlnaHRibHVlIiwgImNob2NvbGF0ZTEiLCAiY2hvY29sYXRlMSIsICJjaG9jb2xhdGUxIiwgInJlZCIsICJyZWQiLCAicmVkIikpIA0KDQpwICsgbGFicyh0aXRsZSA9ICJDbGFzaWZpY2FjaW9uIFNpZ3VpZW50ZSBUZW1wb3JhZGEiLA0KICAgICAgIHN1YnRpdGxlID0gIihFdXJvcGEgeSBEZXNjZW5zbykiLA0KICAgICAgIGNhcHRpb24gPSAiRWxhYm9yYWNpb24gcHJvcGlhIiwNCiAgICAgICB4ID0gIkVxdWlwb3MiLA0KICAgICAgIHkgPSAiUHVudG9zIHRvdGFsZXMiKSArIHRoZW1lX2xpZ2h0KCkgKyANCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IFB0cyksbnVkZ2VfeSA9IDMsIGNvbG91ciA9ICJibGFjayIpICsgY29vcmRfZmxpcCgpICsNCiAgYW5ub3RhdGUoZ2VvbSA9ICJ0ZXh0IiwgeCA9IDIsIHkgPSA1NSwgbGFiZWwgPSAiRGVzY2Vuc28iLCBzaXplID0gNCkgKw0KICBhbm5vdGF0ZShnZW9tID0gInRleHQiLCB4PSA1LCB5ID0gODAsIGxhYmVsID0gIkV1cm9wYSBMZWFndWUiLCBzaXplID0gNCkgKw0KICBhbm5vdGF0ZShnZW9tID0gInRleHQiLCB4PSA4LCB5ID0gOTAsIGxhYmVsID0gIkNoYW1waW9ucyBMZWFndWUiLCBzaXplID0gNCkNCg0KYGBgDQoNCg0KIyMjIDxGT05UIENPTE9SPSJkYXJrYmx1ZSI+KipHcmFmaWNvIDIqKjwvRk9OVD4gDQoNCg0KYGBge3IsIGV2YWwgPSBUUlVFLCBlY2hvID0gRkFMU0UsIG91dC53aWR0aCA9ICI4MCUifQ0KDQpnMiA8LSBnZ3Bsb3QgKGNsYXNpZl8xLCBhZXMoeD1FcXVpcG8sIHkgPSBQdHMpLCBhZXMoZmN0X3JldihFcXVpcG8pKSkgKyANCiAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiLGFlcyhmaWxsID0gQ2xhc2lmMjAyMSkpICsgc2NhbGVfeV9kaXNjcmV0ZShicmVha3M9IGMoJzAnLCAnMjUnLCAnNTAnLCAnNzUnLCAnMTAwJykpICsNCiAgY29vcmRfZmxpcCgpICsgdGhlbWVfYncoKSArIGxhYnModGl0bGUgPSAiQ2xhc2lmaWNhY2lvbiBTaWd1aWVudGUgVGVtcG9yYWRhIiwNCiAgICAgICAgICAgc3VidGl0bGUgPSAiKEV1cm9wYSB5IERlc2NlbnNvKSIsDQogICAgICAgICAgIGNhcHRpb24gPSAiRWxhYm9yYWNpb24gcHJvcGlhIiwNCiAgICAgICAgICAgeCA9ICJFcXVpcG9zIiwNCiAgICAgICAgICAgeSA9ICJQdW50b3MgdG90YWxlcyIpDQoNCmcyDQoNCmBgYA0KDQoNCg0KLS0tLS0tLS0tLS0tLS0tLQ0KDQoNCiMgICA8Rk9OVCBDT0xPUj0iZGFya2JsdWUiPjQuIEFuYWxpc2lzIEdvbGVzIEFub3RhZG9zPC9GT05UPiANCg0KIyMgPEZPTlQgQ09MT1I9ImRhcmtibHVlIj5FcXVpcG9zIGNvbiBtYXMgR29sZXMgQW5vdGFkb3M8L0ZPTlQ+IHsudGFic2V0IC50YWJzZXQtcGlsbHN9DQoNCkVuIGVzdGUgZ3JhZmljbyAzIGVzdHVkaWFtb3MgYSBsb3MgNSBncmFuZGVzIGNsdWJlcyBxdWUgYW5vdGFyb24gbWF5b3JlcyBnb2xlcyBlc3RhIHRlbXBvcmFkYS4gRGVzdGFjYW1vcyBhbCBNYW5jaGVzdGVyIENpdHkgcXVlIGxvZ3JvIHNvYnJlcGFzYXIgbGEgYnJlY2hhIGRlIGxvcyAxMDAgZ29sZXMgYW5vdGFuZG8gMTAyIGdvbGVzIGVzdGEgdGVtcG9yYWRhLiBUYW1iaWVuIHBvZGVtb3MgY29uY2x1aXIgcXVlIGVzdG9zIGVxdWlwb3Mgc29uIGlndWFsbWVudGUgbG9zIDUgcHJpbWVyb3MgZW4gbGEgdGFibGEgZGUgY2xhc2lmaWNhY2lvbiBwb3IgbG8gcXVlIG1pZW50cmFzIG1hcyBnb2xlcyBhbm90YWRvcyBtYXMgcG9zaWJpbGlkYWRlcyB0aWVuZXMgZGUgc3VtYXIgbWF5b3IgY2FudGlkYWQgZGUgcHVudG9zIHkgY29sb2NhcnNlIGVuIGxvIG1hcyBhbHRvIGRlIGxhIHRhYmxhLiBFbiBlbCBncmFmaWNvIDQgZW5jb250cmFtb3MgYSB0b2RvcyBsb3MgZXF1aXBvcyBkZSBsYSB0ZW1wb3JhZGEsIGNvbiAxMDM0IGdvbGVzIHkgdW5hIG1lZGlhIGRlIDUxLDQgZ29sZXMgcG9yIGVxdWlwbyB5IGRlIDI3LDIxIGdvbGVzIHBvciBwYXJ0aWRvIHRlcm1pbmEgbGEgdGVtcG9hcmEgYXRpcGljYSBlbiBJbmdsYXRlcnJhLg0KDQoNCiMjIyA8Rk9OVCBDT0xPUj0iZGFya2JsdWUiPioqR3JhZmljbyAzKio8L0ZPTlQ+IA0KDQpgYGB7ciBldmFsPVRSVUUsIGVjaG89RkFMU0UsIG91dC53aWR0aCA9ICI4MCUifQ0KDQpwIDwtIGdncGxvdCh0b3BfZ2YsIGFlcyh4ID0gRXF1aXBvLCB5ID0gR0YpKSArIA0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgZmlsbCA9IGMoImNhZGV0Ymx1ZTEiLCAicmVkIiwgIm1lZGl1bWJsdWUiLCAibWVkaXVtYmx1ZSIsICJyZWQiKSkgKw0KICB0aGVtZV9idygpIA0KDQpwIDwtIHAgKyBsYWJzKHRpdGxlID0gIkdyw6FmaWNvIDE6IEVxdWlwb3MgR29sZWFkb3JlcyBlbiBsYSBUZW1wb3JhZGEgMTkvMjAiLA0KICAgICAgIHN1YnRpdGxlID0gIihUb3AgNSBNYXMgR29sZXMgQW5vdGFkb3MpIiwNCiAgICAgICBjYXB0aW9uID0gIkVsYWJvcmFjaW9uIHByb3BpYSIsDQogICAgICAgeCA9ICJFcXVpcG9zIiwNCiAgICAgICB5ID0gIkdvbGVzIEEgRmF2b3IiKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBHRiksbnVkZ2VfeSA9IDMsIGNvbG91ciA9ICJibGFjayIpDQoNCnANCg0KYGBgDQoNCg0KIyMjIDxGT05UIENPTE9SPSJkYXJrYmx1ZSI+KipHcmFmaWNvIDQqKjwvRk9OVD4gDQoNCmBgYHtyIGV2YWwgPSBUUlVFLCBlY2hvPUZBTFNFLCBvdXQud2lkdGggPSAiODAlIn0NCg0KZzQgPC0gZ2dwbG90KGNsYXNpZiwgYWVzKHg9RXF1aXBvLCB5PUdGKSkgKyANCiAgICBnZW9tX3BvaW50KGNvbD0iZGFya2JsdWUiLCBzaXplPTMpICsgICANCiAgICBnZW9tX3NlZ21lbnQoYWVzKHg9RXF1aXBvLCANCiAgICAgICAgICAgICAgICAgICAgIHhlbmQ9RXF1aXBvLCANCiAgICAgICAgICAgICAgICAgICAgIHk9bWluKEdGKSwgDQogICAgICAgICAgICAgICAgICAgICB5ZW5kPW1heChHRikpLCANCiAgICAgICAgICAgICAgICAgbGluZXR5cGU9ImRvdHRlZCIsIA0KICAgICAgICAgICAgICAgICBzaXplPTAuMSkgKyAgIA0KICAgIGxhYnModGl0bGU9Ik1hcyBHb2xlcyBBbm90YWRvcyIsIA0KICAgICAgICAgc3VidGl0bGU9IlRlbXBvcmFkYSAxOS8yMCIsIA0KICAgICAgICAgY2FwdGlvbj0iRWxhYm9yYWNpb24gcHJvcGlhIiwgeSA9ICJHb2xlcyBBIEZhdm9yIikgKyAgDQogICAgY29vcmRfZmxpcCgpDQoNCmc0DQoNCmBgYA0KDQoNCi0tLS0tLS0tLS0tLS0tLS0NCg0KIyMgIDxGT05UIENPTE9SPSJkYXJrYmx1ZSI+TG9zIFBpY2hpY2hpcyAoSnVnYWRvcmVzIGNvbiBtYXMgZ29sZXMgZW4gbGEgdGVtcG9yYWRhKTwvRk9OVD4NCg0KYGBge3IgZXZhbCA9IFRSVUUsIGVjaG8gPSBGQUxTRX0NCg0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoaGVyZTo6aGVyZSgiaW1hZ2VuZXMiLCAiSmFtaWUtVmFyZHkuanBnIikpDQoNCmBgYA0KDQoNCkVuIGVzdGEgdGFibGEgcG9kZW1vcyBvYnNlcnZhciBhIGxvcyBtYXhpbW9zIGFub3RhZG9yZXMgeSBsYXMgZXN0YWRpc3RpY2FzIGRlIGNhZGEganVnYWRvciByZXNwZWN0byBhIGxvcyBwYXJ0aWRvcyB5IG1pbnV0b3MganVnYWRvcyBlbiB0b2RvcyBsb3MgcGFydGlkb3MgZGUgbGEgdGVtcG9yYWRhLiBFbiBlbCBjb21vIG1heGltbyBnb2xlYWRvciBhcGFyZWNlIGVsIGp1Z2Fkb3IgaW5nbGVzIEphbWllIFZhcmR5IChMZWljZXN0ZXIgQ2l0eSkgY29uIDIzIGRpYW5hcywgc2VndWlkbyBkZSB1biBlbXBhdGUgZW4gZ29sZXMgeSB0ZXJtaW5hbmRvIGVsIHBvZGlvIGVsIGp1Z2Fkb3IgZ2Fib25lcyBQaWVycmUtRW1lcmljayBBdWJhbWV5YW5nIChBcnNlbmFsKSB5IGVsIGp1Z2Fkb3IgaW5nbGVzIERhbm55IEluZ3MgKFNvdXRoYW1wdG9uKS4NCg0KDQpgYGB7ciBldmFsID0gVFJVRSwgZWNobyA9IEZBTFNFfQ0KDQprYWJsZShtYXhfZ29sKSAlPiUNCiAga2FibGVFeHRyYTo6a2FibGVfc3R5bGluZyhmaXhlZF90aGVhZCA9IGxpc3QoZW5hYmxlZCA9IFQsIGJhY2tncm91bmQgPSAibGlnaHRibHVlIikpICU+JQ0KICBrYWJsZV9wYXBlcihmdWxsX3dpZHRoID0gRikgJT4lIGNvbHVtbl9zcGVjKDQsIGNvbG9yID0gIndoaXRlIiwNCiAgICAgICAgICAgIGJhY2tncm91bmQgPSBzcGVjX2NvbG9yKG10Y2FycyRkcmF0WzE6OF0sIGVuZCA9IDAuNyksDQogICAgICAgICAgICBwb3BvdmVyID0gcGFzdGUoImFtOiIsIG10Y2FycyRhbVsxOjhdKSkgJT4lDQogIGNvbHVtbl9zcGVjKDIsIGNvbG9yID0gc3BlY19jb2xvcihtdGNhcnMkbXBnWzE6OF0pLA0KICAgICAgICAgICAgICBsaW5rID0gImh0dHBzOi8vd3d3LnByZW1pZXJsZWFndWUuY29tL3N0YXRzL3RvcC9wbGF5ZXJzL2dvYWxzP3NlPTI3NCIpDQoNCmBgYA0KDQoNCiMjIyA8Rk9OVCBDT0xPUj0iZGFya2JsdWUiPk90cmEgZm9ybWEgZGUgdmlzdWFsaXphciBsb3MgZ29sZWFkb3JlcyBkZSBsYSB0ZW1wb3JhZGE8L0ZPTlQ+DQoNCkVzdGEgdmV6IGFuYWxpemFtb3MgbG9zIGdvbGVzIGFub3RhZG9zIHBvciBjYWRhIG1pbnV0byBkZSBqdWVnbywgcG9kZW1vcyBvYnNlcnZhciBxdWUgbG9zIGp1Z2FvZHJlcyBjb24gbWVub3IgcmF0aW8gZGUgZ29sZXMgcG9yIG1pbnV0byB5IHF1ZSB0aWVuZW4gbWVub3MgbWludXRvcyBkZW50cm8gZGUgbGEgY2FuY2hhIHNvbiBsb3MganVnYWRvcmVzIGNvbiBtYXMgZWZlY3RpdmlkYWQgZGVudHJvIGRlbCB0ZXJyZW5vIGRlIGp1ZWdvLiBFc3RvcyBqdWdhZG9yZXMgc29uIFJhaGVlbSBTdGVybGluZyB5IEhhcnJ5IEthbmUgcXVlIHNvbiBsb3MgcXVlIHNlIGVuY3VlbnRyYW4gbWFzIGhhY2lhIGFiYWpvIHkgYSBsYSBpenF1aWVyZGEgZGUgbGEgZ3JhZmljYSANCg0KDQpgYGB7ciBldmFsID0gVFJVRSwgZWNobyA9IEZBTFNFLCBvdXQud2lkdGggPSAiODUlIn0NCg0KZzUgPC0gZ2dwbG90KG1heF9nb2wsIGFlcyh4PW1pbnV0b3NqdWdhZG9zLCB5PW1pbnV0b3Bnb2wsIGNvbG9yID0ganVnYWRvcikpICsNCiAgZ2VvbV9wb2ludCgpICsgbGFicyh0aXRsZT0iR29sZXMgcG9yIE1pbnV0byBKdWdhZG9zIHBvciBKdWdhZG9yIiwgDQogICAgICAgc3VidGl0bGU9IlRlbXBvcmFkYSAxOS8yMCIsIA0KICAgICAgIGNhcHRpb249IkVsYWJvcmFjaW9uIHByb3BpYSIsIHggPSAiTWludXRvcyBKdWdhZG9zIiwgeSA9ICJHb2wgcG9yIE1pbnV0byIpICsNCiAgdGhlbWVfc3RhdGEoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgKw0KICBnZ3JlcGVsOjpnZW9tX2xhYmVsX3JlcGVsKGdncGxvdDI6OmFlcyhsYWJlbCA9IGp1Z2Fkb3IpKQ0KDQoNCmc1DQoNCg0KYGBgDQoNCg0KDQpgYGB7ciBldmFsID0gVFJVRSwgZWNobyA9IEZBTFNFIH0NCg0KZW1iZWRfdXJsKCJodHRwczovL3d3dy55b3V0dWJlLmNvbS93YXRjaD92PU1lT3k0dWJtckdJJmFiX2NoYW5uZWw9TENGQyIpDQoNCmBgYA0KDQoNCi0tLS0tLS0tLS0tLS0tLS0NCg0KIyA8Rk9OVCBDT0xPUj0iZGFya2JsdWUiPjUuIEFuYWxpc2lzIEFzaXN0ZW5jaWFzPC9GT05UPg0KDQpFbCBtYXhpbW8gYXNpc3RpZG9yIHkgY29uIG11Y2hhIGRpZmVyZW5jaWEgZXMgZWwgZnV0Ym9saXN0YSBiZWxnYSBLZXZpbiBEZSBCcnV5bmUgY29uIHVuYXMgMjAgYXNpc3RlbmNpYXMgc2VndWlkbyBkZSAzIGp1Z2Fkb3JlcyBkZWwgY2x1YiBjYW1wZW9uIGVsIExpdmVycG9vbCBsb3MgY3VhbGVzIHNvbiBUcmVudCBBbGV4YW5kZXItQXJub2xkLCBBbmRyZXcgUm9iZXJ0c29uIHkgTW9oYW1lZCBTYWxhaC4gRWwganVnYWRvciBiZWxnYSBjb25zaWRlcmFkbyBlbCBtZWpvciBtZWRpb2NhbXBpc3RhIG9mZW5zaXZvIGRlIGxhIGVwb2NhIGhhIHNpZG8gcHJlbWlhZG8gY29uIGVsIHByZW1pbyBwbGF5bWFrZXIgZW4gbGEgbGlnYSBxdWUgZXMgZWwgbnVldm8gcHJlbWlvIHF1ZSBlbnRyZWdhcsOhIGxhIFByZW1pZXIgTGVhZ3VlIHBhcmEgcmVjb25vY2VyIGFsIG1lam9yIG9ycXVlc3RhZG9yIGRlIGxhIHRlbXBvcmFkYS4gDQoNCg0KPiJNZSBzaWVudG8gYmllbi4gU2lnbmlmaWNhIHF1ZSBoZSBoZWNobyB1biBidWVuIHRyYWJham8uIFNveSB1biBjcmVhZG9yIHkgdHJhdG8gZGUgY3JlYXIgb3BvcnR1bmlkYWRlcyBwYXJhIG1pcyBjb21wYcOxZXJvcyBkZSBlcXVpcG8uIFNpIGFub3Rhbiwgb2J0ZW5nbyBsYSBhc2lzdGVuY2lhIHkgbWUgdmVvIGJpZW4iIEtldmluIERlIEJydXluZS4NCg0KQSBlc2FzIGFzaXN0ZW5jaWFzIHRhbWJpw6luIGhheSBxdWUgc3VtYXJsZSA4IHRhbnRvcywgcG9yIGxvIHF1ZSBzdSBpbXBhY3RvIGVuIGVsIGp1ZWdvIGxlIGhhIHByb3BvcmNpb25hZG8gYWwgTWFuY2hlc3RlciBDaXR5IHVuIHRvdGFsIGRlIDI0IGdvbGVzLiBTdSB0ZW1wb3JhZGEgZW4gdG9kYXMgbGFzIGNvbXBldGljaW9uZXMgc2UgcmVzdW1lIGNvbiB1bm9zIGV4Y2VsZW50ZXMgbsO6bWVyb3M6IDEyIGdvbGVzIHkgMjEgYXNpc3RlbmNpYXMgZW4gNTIgcGFydGlkb3MuDQoNCg0KDQpgYGB7ciBldmFsID0gVFJVRSwgZWNobyA9IEZBTFNFfQ0KDQphc2lzdGVuY2lhIDwtIGFzaXN0ZW5jaWEgJT4lIHNlbGVjdChjKEp1Z2Fkb3IsIGFzaXN0ZW5jaWFzLCBuYWNpb25hbGlkYWQpKQ0KDQoNCmFzaXN0ZW5jaWEgJT4lIGd0KCkgJT4lIA0KICBndDo6dGV4dF90cmFuc2Zvcm0obG9jYXRpb25zID0gY2VsbHNfYm9keShjb2x1bW5zID0gdmFycyhuYWNpb25hbGlkYWQpKSwNCiAgICAgICAgICAgICAgICAgICAgIGZuID0gZnVuY3Rpb24oeCkge2d0Ojp3ZWJfaW1hZ2UoYygiaHR0cHM6Ly9zaW1ib2xvZ2lhZGVsbXVuZG8uY29tL3dwLWNvbnRlbnQvdXBsb2Fkcy8yMDE2LzA2L3ItYmVsZ2ljYS5wbmciLA0KICAgICAgICAgICAgICAgICAgImh0dHBzOi8vdXBsb2FkLndpa2ltZWRpYS5vcmcvd2lraXBlZGlhL2NvbW1vbnMvYi9iZS9GbGFnX29mX0VuZ2xhbmQuc3ZnIiwNCiAgICAgICAgICAgICAgICAgICJodHRwczovL3RydWNvc2xvbmRyZXMuY29tL3dwLWNvbnRlbnQvdXBsb2Fkcy8yMDE3LzA5L3Njb3RsYW5kLTg5MTkxNF8xOTIwLTMwMHgxODAucG5nIiwNCiAgICAgICAgICAgICAgICAgICJodHRwczovL3VwbG9hZC53aWtpbWVkaWEub3JnL3dpa2lwZWRpYS9jb21tb25zL2YvZmUvRmxhZ19vZl9FZ3lwdC5zdmciLA0KICAgICAgICAgICAgICAgICAgImh0dHBzOi8vdXBsb2FkLndpa2ltZWRpYS5vcmcvd2lraXBlZGlhL2NvbW1vbnMvdGh1bWIvOS85YS9GbGFnX29mX1NwYWluLnN2Zy8xMjAwcHgtRmxhZ19vZl9TcGFpbi5zdmcucG5nIiwNCiAgICAgICAgICAgICAgICAgICJodHRwczovL3VwbG9hZC53aWtpbWVkaWEub3JnL3dpa2lwZWRpYS9jb21tb25zLzAvMDkvRmxhZ19vZl9Tb3V0aF9Lb3JlYS5zdmciLA0KICAgICAgICAgICAgICAgICAgImh0dHBzOi8vdXBsb2FkLndpa2ltZWRpYS5vcmcvd2lraXBlZGlhL2NvbW1vbnMvNy83Ny9GbGFnX29mX0FsZ2VyaWEuc3ZnIiwNCiAgICAgICAgICAgICAgICAgICJodHRwczovL3VwbG9hZC53aWtpbWVkaWEub3JnL3dpa2lwZWRpYS9jb21tb25zL3RodW1iLzkvOWEvRmxhZ19vZl9TcGFpbi5zdmcvMTIwMHB4LUZsYWdfb2ZfU3BhaW4uc3ZnLnBuZyIsDQogICAgICAgICAgICAgICAgICAiaHR0cHM6Ly91cGxvYWQud2lraW1lZGlhLm9yZy93aWtpcGVkaWEvY29tbW9ucy9iL2JlL0ZsYWdfb2ZfRW5nbGFuZC5zdmciLA0KICAgICAgICAgICAgICAgICAgImh0dHBzOi8vdXBsb2FkLndpa2ltZWRpYS5vcmcvd2lraXBlZGlhL2NvbW1vbnMvdGh1bWIvMC8wNS9GbGFnX29mX0JyYXppbC5zdmcvMzAwcHgtRmxhZ19vZl9CcmF6aWwuc3ZnLnBuZyIpLCBoZWlnaHQgPSAyMCl9KSAlPiUgdGFiX2hlYWRlcih0aXRsZSA9IG1kKCIqKk1heGltb3MgQXNpc3RpZG9yZXMqKiIpLHN1YnRpdGxlID0gbWQoIioqVGVtcG9yYWRhIDIwMTkvMjAyMCoqIikpICU+JQ0KICB0YWJfb3B0aW9ucyhoZWFkaW5nLmJhY2tncm91bmQuY29sb3IgPSAibGlnaHRibHVlIiwgY29sdW1uX2xhYmVscy5mb250LndlaWdodCA9ICJib2xkIikNCg0KYGBgDQoNCg0KLS0tLS0tLS0tLS0tLS0tLQ0KDQojIDxGT05UIENPTE9SPSJkYXJrYmx1ZSI+Ni4gUHJlbWlvcyBlbiBsYSBUZW1wb3JhZGE8L0ZPTlQ+DQoNCg0KTG9zIG1hcyBnYWxhcmRvbmFkb3MgZGUgbGEgdGVtcG9yYWRhLCB5YSBtZW5jaW9uYWRvIGFudGVyaW9ybWVudGUsIHNpbiBkdWRhIGFsZ3VuYSBlbCBtYXMgZGVzdGFjYWRvLCBlbCBmdXRib2xpc3RhIGtldmluIERlIEJydXluZSBmdWUgZWwgTVZQIG1lam9yIGp1Z2Fkb3IgZGUgbGEgdGVtcG9yYWRhIHkgcmVjaWJpbyBlbCBwcmVtaW8gcGxheW1ha2VyIGFsIG1lam9yIGFybWFkb3IgZGUganVlZ28gZW4gbGEgdGVtcG9yYWRhLiBUYW1iaWVuIHBvZGVtb3MgZGVzdGFjYXIgZWwgZ29sIGRlIGxhIHRlbXBvcmFkYSBhbm90YWRvIHBvciBlbCBjb3JlYW5vIEhldWdoLU1pbiBTb24gcXVlIGxvIHBvZGVtb3MgdmVyIGx1ZWdvIGRlIGxhIHRhYmxhLiBMYSBib3RhIGRlIE9ybyBwYXJhIGVsIG1heW9yIGFub3RhZG9yIG1lbmNpb25hZG8gYW50ZXMgSmFtaWUgVmFyZHkuIG1lam9yIGp1Z2Fkb3IgbWFzIGpvdmVuIG8gZ29sZGVuIGJveSBkZSBsYSB0ZW1wb3JhZGEgc2UgbG8gbGxldmEgZWwganVnYWRvciBkZWwgTGl2ZXJwb29sIEFsZXhhbmRlci1Bcm5vbGQuIFRhbWJpZW4gdmVtb3MgcHJlbWlvcyBjb21vIGFsIG1lam9yIG1hbmFnZXIgSnVyZ3VlbiBLbG9wcCB5IGVsIGd1YW50ZSBkZSBvcm8gcGFyYSBlbCBwb3J0ZXJvIGRlbCBNYW5jaGVzdGVyIENpdHkgRWRlcnNvbi4gDQoNCg0KYGBge3IgZXZhbCA9IFRSVUUsIGVjaG8gPSBGQUxTRX0NCg0Ka2FibGUocHJlbWlvKSAlPiUNCiAga2FibGVFeHRyYTo6a2FibGVfc3R5bGluZyhmaXhlZF90aGVhZCA9IGxpc3QoZW5hYmxlZCA9IFQsIGJhY2tncm91bmQgPSAibGlnaHRibHVlIikpICU+JQ0KICBrYWJsZV9wYXBlcihmdWxsX3dpZHRoID0gRikgJT4lIHJvd19zcGVjKDEsIGJvbGQgPSBULCBjb2xvciA9ICJ3aGl0ZSIsIGJhY2tncm91bmQgPSAiI0Q3MjYxRSIpICU+JSByb3dfc3BlYyg3LCBib2xkID0gVCwgY29sb3IgPSAid2hpdGUiLCBiYWNrZ3JvdW5kID0gIiNENzI2MUUiKSAlPiUNCiAgY29sdW1uX3NwZWMoMiwgY29sb3IgPSAiYmxhY2siLA0KICAgICAgICAgICAgICBsaW5rID0gImh0dHBzOi8vd3d3LnR1ZG4uY29tL2Z1dGJvbC9wcmVtaWVyLWxlYWd1ZS9qdXJnZW4ta2xvcHAteS1rZXZpbi1kZS1icnV5bmUtc29uLWVsLW1lam9yLXRlY25pY28teS1qdWdhZG9yLWRlLWxhLXByZW1pZXItbGVhZ3VlIikNCg0KDQpgYGANCg0KDQpgYGB7ciBldmFsID0gVFJVRSwgZWNobyA9IEZBTFNFIH0NCg0KZW1iZWRfdXJsKCJodHRwczovL3d3dy55b3V0dWJlLmNvbS93YXRjaD92PUl3SDRLUmVKNEtFJmFiX2NoYW5uZWw9VG90dGVuaGFtSG90c3B1ciIpDQoNCmBgYA0KDQoNCg0KLS0tLS0tLS0tLS0tLS0tLQ0KDQojICA8Rk9OVCBDT0xPUj0iZGFya2JsdWUiPjcuIEVzdGFkaW9zIGRlIGxvcyBFcXVpcG9zIGRlIFByaW1lcmEgRGl2aXNpb24gVGVtcG9yYWRhIDE5LzIwPC9GT05UPg0KDQpQYXJhIGNvbXBsZW1lbnRhciBlc3RlIGFuYWxpc2lzIGNvbm9jZXJlbW9zIGxvcyBlc3RhZGlvcyBkZSBsb3MgMjAgZXF1aXBvcyBxdWUgc2UgZGVqYXJvbiBsYSBwaWVsIGVzdGUgYcOxbyBjb21iYXRpZW5kbyBwYXJ0aWRvIGEgcGFydGlkbyBlbiBlc3RvcyBncmFuZGVzIGNhbXBvcyBkZSBqdWVnby4gTm9zIGVuY29udHJhbW9zIGNvbiBsYSB1YmljYWNpb24gZGUgY2FkYSB1bm8gZGUgbG9zIGNhbXBvcyBlbiBsYXMgZGlzdGludGFzIGNpdWRhZGVzIGRlIEluZ2xhdGVycmEuIENvbW8gZGF0byBpbnRlcmVzYW50ZSBsYSBkaXN0YW5jaWEgbWFzIGxhcmdhIHJlY29ycmlkYSBlbnRyZSBkb3MgZXF1aXBvcyBlcyBkZSA1Njgga2lsb21ldHJvcywgcXVlIGVzIGxhIGRpc3RhbmNpYSBxdWUgdGllbmVuIHF1ZSByZWNvcnJlciBsb3MgZXF1aXBvcyBOZXcgQ2FzdGxlIFVuaXRlZCB5IEJvdXJuZW1vdXRoIHBhcmEgc3VzIHJlc3BlY3Rpdm9zIGVuZnJlbnRhbWllbnRvcy4gQWRlbWFzIHBvZGVtb3MgZGVzdGFjYXIgbGEgY2l1ZGFkIGRlIExpdmVycG9vbCBkb25kZSBsb3MgZXN0YWRpb3MgZGVsIExpdmVycG9vbCB5IGVsIEV2ZXJ0b24gbG9zIHNlcGFyYSB1bmEgZGlzdGFuY2lhIHNvbG8gZGUgMSw5IGtpbG9tZXRyb3MuIFBvciB1bHRpbW8gcG9kZW1vcyBvYnNlcnZhciBxdWUgZW4gbGEgY2l1ZGFkIGRlIExvbmRyZXMgc2UgZW5jdWVudHJhbiA1IGVxdWlwb3MgbG9zIGN1YWxlcyBzb246IFdlc3QgSGFtIFVuaXRlZCwgQ2hlbHNlYSwgVG90dGVuaGFtLCBBcnNlbmFsIHkgZWwgQ3J5c3RhbCBQYWxhY2UuIA0KDQoNCmBgYHtyIGV2YWwgPSBUUlVFLCBlY2hvID0gRkFMU0V9DQoNCnAgPC0gbGVhZmxldCgpICU+JQ0KICBhZGRUaWxlcygpICU+JSANCiAgc2V0VmlldyhsbmcgPSAtMi40MzU5NzMsIGxhdCA9IDUyLjM3ODA1MSwgem9vbSA9IDYpICU+JSANCiAgYWRkTWFya2VycyhsbmcgPSAtMC4xOTA5LCBsYXQgPSA1MS40ODE4LCBwb3B1cCA9ICJTdGFtZm9yZCBCcmlkZ2UgKENoZWxzZWEpIikgJT4lIA0KICBhZGRNYXJrZXJzKGxuZyA9IC0wLjAxNjMsIGxhdCA9IDUxLjUzODgsIHBvcHVwID0gIkxvbmRvbiBTdGFkaXVtIChXZXN0IEhhbSBVbml0ZWQpIikgJT4lDQogIGFkZE1hcmtlcnMobG5nID0gLTAuMTA4NCwgbGF0ID0gNTEuNTU1MCwgcG9wdXAgPSAiRW1pcmF0ZXMgU3RhZGl1bSAoQXJzZW5hbCkiKSAlPiUNCiAgYWRkTWFya2VycyhsbmcgPSAtMC4wNjYzLCBsYXQgPSA1MS42MDQ0LCBwb3B1cCA9ICJUb3R0ZW5oYW0gSG90c3B1ciBTdGFkaXVtIChUb3R0ZW5oYW0pIikgJT4lDQogIGFkZE1hcmtlcnMobG5nID0gLTAuMDg1NiwgbGF0ID0gNTEuNDAwMCwgcG9wdXAgPSAiU2VsaHVyc3QgUGFyayAoQ3J5c3RhbCBQYWxhY2UpIikgJT4lDQogIGFkZE1hcmtlcnMobG5nID0gLTIuOTYwNywgbGF0ID0gNTMuNDMwOSwgcG9wdXAgPSAiQW5maWVsZCAoTGl2ZXJwb29sKSIpICU+JQ0KICBhZGRNYXJrZXJzKGxuZyA9IC0yLjIwMDQsIGxhdCA9IDUzLjQ4MzIsIHBvcHVwID0gIkV0aWhhZCBTdGFkaXVtIChNYW5jaGVzdGVyIENpdHkpIikgJT4lDQogIGFkZE1hcmtlcnMobG5nID0gLTIuMjkxMSwgbGF0ID0gNTMuNDYzNSwgcG9wdXAgPSAiT2xkIFRyYWZmb3JkIChNYW5jaGVzdGVyIFVuaXRlZCkiKSAlPiUNCiAgYWRkTWFya2VycyhsbmcgPSAtMi45NjYzLCBsYXQgPSA1My40Mzg5LCBwb3B1cCA9ICJHb29kaXNvbiBQYXJrIChFdmVydG9uKSIpICU+JQ0KICBhZGRNYXJrZXJzKGxuZyA9IC0xLjE0MjEsIGxhdCA9IDUyLjYyMDUsIHBvcHVwID0gIktpbmcgUG93ZXIgU3RhZGl1bSAoTGVpY2VzdGVyIENpdHkpIikgJT4lDQogIGFkZE1hcmtlcnMobG5nID0gLTIuMTMwMywgbGF0ID0gNTIuNTkwMywgcG9wdXAgPSAiTW9saW5ldXggU3RhZGl1bSAoV29sdmVyaGFtcHRvbiBXYW5kZXJlcnMpIikgJT4lDQogIGFkZE1hcmtlcnMobG5nID0gLTEuNDY5OCwgbGF0ID0gNTMuMzcwMSwgcG9wdXAgPSAiQnJhbWFsbCBMYW5lIChTaGVmZmllbGQgVW5pdGVkKSIpICU+JQ0KICBhZGRNYXJrZXJzKGxuZyA9IC0xLjYyMTYsIGxhdCA9IDU0Ljk3NTYsIHBvcHVwID0gIlN0IEphbWVzIFBhcmsgKE5ldyBDYXN0bGUgVW5pdGVkIikgJT4lDQogIGFkZE1hcmtlcnMobG5nID0gLTIuMjMwNCwgbGF0ID0gNTMuNzg4OCwgcG9wdXAgPSAiVHVyZiBNb29yIChCdXJubGV5KSIpICU+JQ0KICBhZGRNYXJrZXJzKGxuZyA9IC0xLjM5MDksIGxhdCA9IDUwLjkwNjAsIHBvcHVwID0gIlN0IE1hcnlzIFN0YWRpdW0gKFNvdXRoYW1wdG9uKSIpICU+JQ0KICBhZGRNYXJrZXJzKGxuZyA9IC0wLjA4NDksIGxhdCA9IDUwLjg2MzAsIHBvcHVwID0gIkZhbG1lciBTdGFkaXVtIChCcmlnaHRvbiAmIEhvdmUgQWxiaW9uKSIpICU+JQ0KICBhZGRNYXJrZXJzKGxuZyA9ICAxLjMwOTUsIGxhdCA9IDUyLjYyMzIsIHBvcHVwID0gIkNhcnJvdyBSb2FkIChOb3J3aWNoIENpdHkpIikgJT4lDQogIGFkZE1hcmtlcnMobG5nID0gLTAuNDAxNiwgbGF0ID0gNTEuNjUwMCwgcG9wdXAgPSAiVmljYXJhZ2UgUm9hZCAoV2F0Zm9yZCkiKSAlPiUNCiAgYWRkTWFya2VycyhsbmcgPSAtMS44MzgyLCBsYXQgPSA1MC43MzU0LCBwb3B1cCA9ICJEZWFuIENvdXJ0IChCb3VybmVtb3V0aCkiKSAlPiUNCiAgYWRkTWFya2VycyhsbmcgPSAtMS44ODQ4LCBsYXQgPSA1Mi41MDkyLCBwb3B1cCA9ICJWaWxsYSBQYXJrIChBc3RvbiBWaWxsYSkiKQ0KDQpwDQoNCmBgYA0KDQotLS0tLS0tLS0tLS0tLS0tDQoNCiMgIDxGT05UIENPTE9SPSJkYXJrYmx1ZSI+OC4gQ29uY2x1c2nDs248L0ZPTlQ+DQoNCkxhIGF0aXBpY2EgdGVtcG9yYWRhIDIwMTktMjAyMCBub3MgaGEgZGVqYWRvIHVub3MgcmVjdWVyZG9zIGlub2x2aWRhYmxlcyBxdWUgc29uIHBhcmEgbGEgaGlzdG9yaWEgZGUgZXN0ZSBncmFuIGNhbXBlb25hdG8uIExhIHBhbmRlbWlhIGRlbCBjb3ZpZC0xOSBubyBpbXBpZGlvIHF1ZSBlbCBMaXZlcnBvb2wgbGV2YW50YXJhIHN1IGFuc2lhZGEgeSBlc3BlcmFkYSBQcmVtaWVyIExlYWd1ZSBsdWVnbyBkZSAzMCBhw7FvcyBkZSBzZXF1aWEgZG9tZXN0aWNhLiBTdSBmdXRib2wgYXJyb2xsYWRvciB5IGRvbWluYW50ZSBkZXN0YWNvIHJvbXBpZW5kbyByZWNvcmRzIHkgY29uc2lndWllbmRvIHVuYSB1bmljYSBkZXJyb3RhIGVuIHRvZGEgbGEgdGVtcG9yYWRhLiBBZGVtYXMsIExhIGluY2x1c2lvbiBkZWwgVkFSIGRlc2RlIG1pIHB1bnRvIGRlIHZpc3RhIGhhIHNpZG8gZmF2b3JhYmxlIHBhcmEgZXN0YSBjb21wZXRpY2lvbiB5YSBxdWUgaGEgZG90YWRvIGFsIGNvbmp1bnRvIGFyYml0cmFsIGNvbiB1bmEgYXl1ZGEgZXh0cmEgZW4gZWwgZXN0dWRpbyBkZSBqdWdhZGFzIGRlY2lzaXZhcy4gVGFtYmllbiBwb2RlbW9zIGFjb3RhciBxdWUgbm8gaHVibyB1bmEgZ3JhbiBjb21wZXRlbmNpYSBvIGRpc3B1dGEgcGFyYSBsYSBjb25zZWN1Y2lvbiBkZSBsb3MgcHVlc3RvcyBwYXJhIGxhIENoYW1waW9ucyBMZWFndWUgeWEgcXVlIHRhbnRvIGVsIExpdmVycG9vbCAoY2FtcGVvbikgeSBlbCBNYW5jaGVzdGVyIENpdHkgcHJlc2VudGFiYW4gdW5hIGFtcGxpYSB2ZW50YWphIGVuIHB1bnRvcyBjb24gZWwgcmVzdG8gZGUgc3VzIGNvbXBldGlkb3Jlcy4gU2luIGVtYmFyZ28sIGxhIGZ1ZXJ0ZSBwZWxlYSBwb3IgZXN0b3MgdWx0aW1vcyBwdWVzdG9zIGV1cm9wZW9zICh0ZXJjZXJvIHkgY3VhcnRvIGNsYXNpZmljYWRvKSBmdWUgbGEgZnJlbmV0aWNhIGRpc3B1dGEgZGUgdmFyaW9zIGVxdWlwb3MgKExlaWNlc3RlciwgVG90dGVuaGFtLCBXb2x2ZXMpIHF1ZSBhbCBmaW5hbCB0ZXJtaW5hcm9uIGNvbW8gdmVuY2Vkb3JlcyBlbCBDaGVsc2VhIHkgZWwgTWFuY2hlc3RlciBVbml0ZWQuIA0KIA0KDQoNCiMgIDxGT05UIENPTE9SPSJkYXJrYmx1ZSI+UmVmZXJlbmNpYXM8L0ZPTlQ+DQoNClBhcmEgbGEgcmVhbGl6YWNpw7NuIGRlbCB0cmFiYWpvIGhlIHV0aWxpemFkbzoNCg0KLSBbZW5sYWNlIGEgRWwgQ29tZXJjaW9dKGh0dHBzOi8vZWxjb21lcmNpby5wZS9kZXBvcnRlLXRvdGFsL2Z1dGJvbC1tdW5kaWFsL2xpdmVycG9vbC1jYW1wZW9uLWp1cmdlbi1rbG9wcC10cmFzLWdhbmFyLWxhLXByZW1pZXItbGVhZ3VlLWVzLWluY3JlaWJsZS1zZXItY2FtcGVvbi1jb24tZXN0ZS1lcXVpcG8tbm90aWNpYS8pDQoNCi0gW2VubGFjZSBhIE1hcmNhXShodHRwczovL3d3dy5tYXJjYS5jb20vY2xhcm8tbXgvZnV0Ym9sL3ByZW1pZXItbGVhZ3VlL3Bvc2ljaW9uZXMuaHRtbCkNCg0KLSBbZW5sYWNlIGEgd2lraXBlZGlhXShodHRwczovL2VzLndpa2lwZWRpYS5vcmcvd2lraS9QcmVtaWVyX0xlYWd1ZV8yMDE5LTIwKQ0KDQotIFtlbmxhY2UgYSBUaGUgUiBHcmFwaCBHYWxsZXJ5XShodHRwczovL3d3dy5yLWdyYXBoLWdhbGxlcnkuY29tLykNCg0KLSBbZW5sYWNlIGEgdHV0b3JpYWxlc10oaHR0cHM6Ly9wZXJlenA0NC5naXRodWIuaW8vaW50cm8tZHMtMjAtMjEtd2ViLzA0LXR1dG9yaWFsZXMuaHRtbCkNCg0KLSBbZW5sYWNlIGEgcGFnaW5hIG9maWNpYWwgZGUgbGEgbGlnYSBkZSBJbmdsYXRlcnJhXShodHRwczovL3d3dy5wcmVtaWVybGVhZ3VlLmNvbS9zdGF0cy90b3AvcGxheWVycy9nb2Fscz9zZT0yNzQpDQoNCi0gW2VubGFjZSBhIFRVRE5dKGh0dHBzOi8vd3d3LnR1ZG4uY29tL2Z1dGJvbC9wcmVtaWVyLWxlYWd1ZS9qdXJnZW4ta2xvcHAteS1rZXZpbi1kZS1icnV5bmUtc29uLWVsLW1lam9yLXRlY25pY28teS1qdWdhZG9yLWRlLWxhLXByZW1pZXItbGVhZ3VlKQ0KDQoNCg0KDQoNCmBgYHtyLCBldmFsID0gVFJVRSwgZWNobyA9IEZBTFNFLCBvdXQud2lkdGggPSAiODAlIn0NCg0KZzIgPC0gZ2dwbG90IChjbGFzaWZfMSwgYWVzKHg9RXF1aXBvLCB5ID0gUHRzKSwgYWVzKGZjdF9yZXYoRXF1aXBvKSkpICsgDQogIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IixhZXMoZmlsbCA9IENsYXNpZjIwMjEpKSArIHNjYWxlX3lfZGlzY3JldGUoYnJlYWtzPSBjKCcwJywgJzI1JywgJzUwJywgJzc1JywgJzEwMCcpKSArDQogIGNvb3JkX2ZsaXAoKSArIHRoZW1lX2J3KCkgKyBsYWJzKHRpdGxlID0gIkNsYXNpZmljYWNpb24gU2lndWllbnRlIFRlbXBvcmFkYSIsDQogICAgICAgICAgIHN1YnRpdGxlID0gIihFdXJvcGEgeSBEZXNjZW5zbykiLA0KICAgICAgICAgICBjYXB0aW9uID0gIkVsYWJvcmFjaW9uIHByb3BpYSIsDQogICAgICAgICAgIHggPSAiRXF1aXBvcyIsDQogICAgICAgICAgIHkgPSAiUHVudG9zIHRvdGFsZXMiKQ0KDQoNCg0KYGBgDQoNCg0KYGBge3IsIGV2YWwgPSBUUlVFLCBlY2hvID0gRkFMU0UsIG91dC53aWR0aCA9ICI4MCUifQ0KDQoNCmdncGxvdGx5KGcyKQ0KDQpgYGANCg0KDQoNCg0KLS0tLS0tLS0tLS0tLS0tLQ0KDQo8YnI+PGJyPg0KDQpQYXJhIGFjYWJhciBlc3RlIGNodW5rIHBhcmEgaW5jbHVpciB0dSBgc2Vzc2lvbiBpbmZvYDoNCg0KYGBge3J9DQpzZXNzaW9uaW5mbzo6c2Vzc2lvbl9pbmZvKCkgJT4lIGRldGFpbHM6OmRldGFpbHMoc3VtbWFyeSA9ICdjdXJyZW50IHNlc3Npb24gaW5mbycpIA0KYGBgDQoNCg0K