Por defecto, la forma en que R Markdown muestra tablas es bastante feo porque muestra lo que verías si corrieras el código en la consola.

library(dplyr)
paises <- readr::read_csv("datos/paises.csv")
paises_seleccion <- paises %>% 
  filter(pais %in% c("Argentina", "Uruguay", "Chile")) %>% 
  filter(anio %in% c(2007, 2002)) %>%
  select(-continente)
paises_seleccion
## # A tibble: 6 x 5
##   pais       anio esperanza_de_vida poblacion pib_per_capita
##   <chr>     <dbl>             <dbl>     <dbl>          <dbl>
## 1 Argentina  2002              74.3  38331121          8798.
## 2 Argentina  2007              75.3  40301927         12779.
## 3 Chile      2002              77.9  15497046         10779.
## 4 Chile      2007              78.6  16284741         13172.
## 5 Uruguay    2002              75.3   3363085          7727.
## 6 Uruguay    2007              76.4   3447496         10611.

Tablas simples con kable

Existen varios paquetes para mostrar tablas lindas pero una forma simple y sin vueltas es usando la función kable del paquete {knitr}. Sólo usando esta función ya devuelve una tabla más que razonable:

library(knitr)
kable(paises_seleccion)
pais anio esperanza_de_vida poblacion pib_per_capita
Argentina 2002 74.340 38331121 8797.641
Argentina 2007 75.320 40301927 12779.380
Chile 2002 77.860 15497046 10778.784
Chile 2007 78.553 16284741 13171.639
Uruguay 2002 75.307 3363085 7727.002
Uruguay 2007 76.384 3447496 10611.463

La mayoría de las veces, el nombre de las columnas que queremos mostrar no va a ser igual que el nombre de las columnas en R. En la tabla paises, los nombres están en minúscula, sin espacios y sin “caracteres especiales” como “ñ” o “í”. Esto es útil para comunicarse con R, pero no está bueno para comunicados a seres humanos. El argumento col.names permite especificar el nombre de las columnas para mostrar:

kable(paises_seleccion, 
      col.names = c("País", "Año", "Esperanza de vida", "Población", "PBI per cápita"))
País Año Esperanza de vida Población PBI per cápita
Argentina 2002 74.340 38331121 8797.641
Argentina 2007 75.320 40301927 12779.380
Chile 2002 77.860 15497046 10778.784
Chile 2007 78.553 16284741 13171.639
Uruguay 2002 75.307 3363085 7727.002
Uruguay 2007 76.384 3447496 10611.463

En Español, en general usamos la coma para separar los decimales y el punto como separador de miles. Para eso, hay que modificar el argumento format.args de esta manera:

kable(paises_seleccion, 
      col.names = c("País", "Año", "Esperanza de vida", "Población", "PBI per cápita"),
      format.args = list(decimal.mark = ",", big.mark = "."))
País Año Esperanza de vida Población PBI per cápita
Argentina 2.002 74,340 38.331.121 8.797,641
Argentina 2.007 75,320 40.301.927 12.779,380
Chile 2.002 77,860 15.497.046 10.778,784
Chile 2.007 78,553 16.284.741 13.171,639
Uruguay 2.002 75,307 3.363.085 7.727,002
Uruguay 2.007 76,384 3.447.496 10.611,463

Uff… pero ponerle el punto de miles a los años queda raro. La solución es convertir la columna anio en caracter. De esta manera, no se ve afectada por el formato numérico.

paises_seleccion %>% 
  mutate(anio = as.character(anio)) %>% 
  kable(col.names = c("País", "Año", "Esperanza de vida", "Población", "PBI per cápita"),
        format.args = list(decimal.mark = ",", big.mark = "."))
País Año Esperanza de vida Población PBI per cápita
Argentina 2002 74,340 38.331.121 8.797,641
Argentina 2007 75,320 40.301.927 12.779,380
Chile 2002 77,860 15.497.046 10.778,784
Chile 2007 78,553 16.284.741 13.171,639
Uruguay 2002 75,307 3.363.085 7.727,002
Uruguay 2007 76,384 3.447.496 10.611,463

hacer kable, que es una función diseñada para ser simple y hacer pocas cosas. Para hacer cosas un poco mas complicadas está el paquete {kableExtra}.

Supertablas con {kableExtra}

El paquete {kableExtra}, como su nombre lo indica, nació para extender el poder de la función kable.

library(kableExtra)  # instalar con install.packages("kableExtra")
## 
## Attaching package: 'kableExtra'
## The following object is masked from 'package:dplyr':
## 
##     group_rows
paises_tabla <- paises_seleccion %>% 
  mutate(anio = as.character(anio)) %>% 
  kable(col.names = c("País", "Año", "Esperanza de vida", "Población", "PBI per cápita"),
        format.args = list(decimal.mark = ",", big.mark = "."))

La primera columna de la tabla de arriba es un tanto redundante. Sería mejor agrupar las filas según el país. Esto se consigue con la función collapse_rows:

paises_tabla %>% 
  collapse_rows(columns = 1, valign = "top")  %>% 
  kable_styling() 
País Año Esperanza de vida Población PBI per cápita
Argentina 2002 74,340 38.331.121 8.797,641
2007 75,320 40.301.927 12.779,380
Chile 2002 77,860 15.497.046 10.778,784
2007 78,553 16.284.741 13.171,639
Uruguay 2002 75,307 3.363.085 7.727,002
2007 76,384 3.447.496 10.611,463

El primer argumento es el número de la columna que queremos agrupar. En este caso, la columna pais es la primera. El segundo argumento es la alineación vertical. Por defecto, collapse_rows pone las etiquetas en el centro, pero la convención más general es ponerlas arriba.

¿Qué es esa kable_styling()? {kableExtra} permite cambiar el estilo de las tablas muy fácilmente. kable_styling es el estilo por defecto, que es igual al que produce kable, pero tiene muchos otros. Si viste tablas hechas en LaTeX, quizás este estilo te resulte familiar:

paises_tabla %>% 
  collapse_rows(columns = 1, valign = "top")  %>% 
  kable_classic_2()
País Año Esperanza de vida Población PBI per cápita
Argentina 2002 74,340 38.331.121 8.797,641
2007 75,320 40.301.927 12.779,380
Chile 2002 77,860 15.497.046 10.778,784
2007 78,553 16.284.741 13.171,639
Uruguay 2002 75,307 3.363.085 7.727,002
2007 76,384 3.447.496 10.611,463

La función column_spec permite cambiar los parámetros gráficos de una o más columnas. En este caso cambiamos la primera columna (column = 1) para que las palabras aparezcan italizadas (italic = TRUE):

paises_tabla %>% 
  column_spec(column = 1, italic = TRUE) %>%
  collapse_rows(columns = 1, valign = "top")  %>%
  kable_styling() 
País Año Esperanza de vida Población PBI per cápita
Argentina 2002 74,340 38.331.121 8.797,641
2007 75,320 40.301.927 12.779,380
Chile 2002 77,860 15.497.046 10.778,784
2007 78,553 16.284.741 13.171,639
Uruguay 2002 75,307 3.363.085 7.727,002
2007 76,384 3.447.496 10.611,463

Lo notable de column_spec es que en sus argumentos se pueden poner vectores de manera de generar formato condicional. Para resaltar con negrita únicamente el país “Argentina”:

paises_tabla %>% 
  column_spec(column = 1, bold = (paises_seleccion$pais == "Argentina")) %>%
  collapse_rows(columns = 1, valign = "top")  %>%
  kable_styling() 
País Año Esperanza de vida Población PBI per cápita
Argentina 2002 74,340 38.331.121 8.797,641
2007 75,320 40.301.927 12.779,380
Chile 2002 77,860 15.497.046 10.778,784
2007 78,553 16.284.741 13.171,639
Uruguay 2002 75,307 3.363.085 7.727,002
2007 76,384 3.447.496 10.611,463

Conviene detenerse para mirar un poco con detalle el código. La llamada a column_spec está cambiando el formato de la columna 1. En particular, va a determinar si el texto es en negrita (bold) o no. Y la forma para determinarlo es el vector paises$pais == "Argentina". ¿Qué es ese vector?

paises_seleccion$pais == "Argentina"
## [1]  TRUE  TRUE FALSE FALSE FALSE FALSE

Por lo tanto, column_spec(column = 1, bold = (paises$pais == "Argentina")) va a hacer que las dos primera filas de la columna uno estén en negrita, y las demás no. Luego, collapse_rows colapsa las filas según el país y entonces esas dos primeras filas se transforman en una.

Esto da un montón de flexibilidad en el estilo del texto. Por ejemplo, se puede hacer que el color del texto cambie según el valor usando column_spec y spec_color.

paises_tabla %>% 
  column_spec(3, color = spec_color(paises_seleccion$esperanza_de_vida)) %>% 
  collapse_rows(columns = 1, valign = "top")  %>%
  kable_styling() 
País Año Esperanza de vida Población PBI per cápita
Argentina 2002 74,340 38.331.121 8.797,641
2007 75,320 40.301.927 12.779,380
Chile 2002 77,860 15.497.046 10.778,784
2007 78,553 16.284.741 13.171,639
Uruguay 2002 75,307 3.363.085 7.727,002
2007 76,384 3.447.496 10.611,463

La función nueva, spec_color genera colores a partir de un vector. Podés ver cómo funciona en esta linea:

spec_color(paises_seleccion$esperanza_de_vida)
## [1] "#440154FF" "#3D4D8AFF" "#90D743FF" "#FDE725FF" "#3D4D8AFF" "#228D8DFF"

Esos números son representaciones en hexadecimal de los colores que ves en la tabla. Podés pasarle cualquier serie de colores, no sólo la creada con spec_color.

Así como se puede cambiar el estilo de las columnas con column_spec, se puede cambiar el estilo de las filas con row_spec. Por ejemplo, se puede resaltar cada 2 líneas con este código:

paises_tabla %>% 
  row_spec(row = seq(2, nrow(paises_seleccion), by = 2), background = "azure") %>% 
  collapse_rows(columns = 1, valign = "top")  %>%
  kable_styling() 
País Año Esperanza de vida Población PBI per cápita
Argentina 2002 74,340 38.331.121 8.797,641
2007 75,320 40.301.927 12.779,380
Chile 2002 77,860 15.497.046 10.778,784
2007 78,553 16.284.741 13.171,639
Uruguay 2002 75,307 3.363.085 7.727,002
2007 76,384 3.447.496 10.611,463

row_spec está cambiando el fondo (background) al color “azure” (que es ese celestito) a las filas indicadas por seq(2, nrow(paises_seleccion), by = 2). ¿Qué es eso? seq genera una secuencia (de sequence) de números empezando en 2, terminando en la cantidad de filas de paises_seleccion y saltando de a dos. En resumen:

seq(2, nrow(paises_seleccion), by = 2)
## [1] 2 4 6

Como caso especial, se puede usar row = 0 en row_spec para cambiar el formato del encabezado.

paises_tabla %>% 
  row_spec(row = 0, underline = TRUE) %>% 
  collapse_rows(columns = 1, valign = "top")  %>%
  kable_styling() 
País Año Esperanza de vida Población PBI per cápita
Argentina 2002 74,340 38.331.121 8.797,641
2007 75,320 40.301.927 12.779,380
Chile 2002 77,860 15.497.046 10.778,784
2007 78,553 16.284.741 13.171,639
Uruguay 2002 75,307 3.363.085 7.727,002
2007 76,384 3.447.496 10.611,463

Esto es sólo una mínima parte de lo que se puede hacer con el paquete {kableExtra}. Para ejemplos mucho más detallados, te recomendamos leer la viñeta completa

LS0tCnRpdGxlOiAiVGFibGFzIgpvdXRwdXQ6IAogIGh0bWxfZG9jdW1lbnQ6CiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICB0b2M6IHRydWUKICAgIHRvY19mbG9hdDogZmFsc2UKICAgIGhpZ2hsaWdodDogdGFuZ28KLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKQpgYGAKCgpQb3IgZGVmZWN0bywgbGEgZm9ybWEgZW4gcXVlIFIgTWFya2Rvd24gbXVlc3RyYSB0YWJsYXMgZXMgYmFzdGFudGUgZmVvIHBvcnF1ZSBtdWVzdHJhIGxvIHF1ZSB2ZXLDrWFzIHNpIGNvcnJpZXJhcyBlbCBjw7NkaWdvIGVuIGxhIGNvbnNvbGEuIAoKYGBge3IsIG1lc3NhZ2U9RkFMU0V9CmxpYnJhcnkoZHBseXIpCnBhaXNlcyA8LSByZWFkcjo6cmVhZF9jc3YoImRhdG9zL3BhaXNlcy5jc3YiKQpwYWlzZXNfc2VsZWNjaW9uIDwtIHBhaXNlcyAlPiUgCiAgZmlsdGVyKHBhaXMgJWluJSBjKCJBcmdlbnRpbmEiLCAiVXJ1Z3VheSIsICJDaGlsZSIpKSAlPiUgCiAgZmlsdGVyKGFuaW8gJWluJSBjKDIwMDcsIDIwMDIpKSAlPiUKICBzZWxlY3QoLWNvbnRpbmVudGUpCnBhaXNlc19zZWxlY2Npb24KYGBgCgojIyBUYWJsYXMgc2ltcGxlcyBjb24gYGthYmxlYAoKRXhpc3RlbiB2YXJpb3MgcGFxdWV0ZXMgcGFyYSBtb3N0cmFyIHRhYmxhcyBsaW5kYXMgcGVybyB1bmEgZm9ybWEgc2ltcGxlIHkgc2luIHZ1ZWx0YXMgZXMgdXNhbmRvIGxhIGZ1bmNpw7NuIGBrYWJsZWAgZGVsIHBhcXVldGUge2tuaXRyfS4gU8OzbG8gdXNhbmRvIGVzdGEgZnVuY2nDs24geWEgZGV2dWVsdmUgdW5hIHRhYmxhIG3DoXMgcXVlIHJhem9uYWJsZToKCmBgYHtyfQpsaWJyYXJ5KGtuaXRyKQprYWJsZShwYWlzZXNfc2VsZWNjaW9uKQpgYGAKCkxhIG1heW9yw61hIGRlIGxhcyB2ZWNlcywgZWwgbm9tYnJlIGRlIGxhcyBjb2x1bW5hcyBxdWUgcXVlcmVtb3MgbW9zdHJhciBubyB2YSBhIHNlciBpZ3VhbCBxdWUgZWwgbm9tYnJlIGRlIGxhcyBjb2x1bW5hcyBlbiBSLiBFbiBsYSB0YWJsYSBgcGFpc2VzYCwgbG9zIG5vbWJyZXMgZXN0w6FuIGVuIG1pbsO6c2N1bGEsIHNpbiBlc3BhY2lvcyB5IHNpbiAiY2FyYWN0ZXJlcyBlc3BlY2lhbGVzIiBjb21vICLDsSIgbyAiw60iLiBFc3RvIGVzIMO6dGlsIHBhcmEgY29tdW5pY2Fyc2UgY29uIFIsIHBlcm8gbm8gZXN0w6EgYnVlbm8gcGFyYSBjb211bmljYWRvcyBhIHNlcmVzIGh1bWFub3MuIEVsIGFyZ3VtZW50byBgY29sLm5hbWVzYCBwZXJtaXRlIGVzcGVjaWZpY2FyIGVsIG5vbWJyZSBkZSBsYXMgY29sdW1uYXMgcGFyYSBtb3N0cmFyOgoKYGBge3J9CmthYmxlKHBhaXNlc19zZWxlY2Npb24sIAogICAgICBjb2wubmFtZXMgPSBjKCJQYcOtcyIsICJBw7FvIiwgIkVzcGVyYW56YSBkZSB2aWRhIiwgIlBvYmxhY2nDs24iLCAiUEJJIHBlciBjw6FwaXRhIikpCmBgYAoKRW4gRXNwYcOxb2wsIGVuIGdlbmVyYWwgdXNhbW9zIGxhIGNvbWEgcGFyYSBzZXBhcmFyIGxvcyBkZWNpbWFsZXMgeSBlbCBwdW50byBjb21vIHNlcGFyYWRvciBkZSBtaWxlcy4gUGFyYSBlc28sIGhheSBxdWUgbW9kaWZpY2FyIGVsIGFyZ3VtZW50byBgZm9ybWF0LmFyZ3NgIGRlIGVzdGEgbWFuZXJhOgoKYGBge3J9CmthYmxlKHBhaXNlc19zZWxlY2Npb24sIAogICAgICBjb2wubmFtZXMgPSBjKCJQYcOtcyIsICJBw7FvIiwgIkVzcGVyYW56YSBkZSB2aWRhIiwgIlBvYmxhY2nDs24iLCAiUEJJIHBlciBjw6FwaXRhIiksCiAgICAgIGZvcm1hdC5hcmdzID0gbGlzdChkZWNpbWFsLm1hcmsgPSAiLCIsIGJpZy5tYXJrID0gIi4iKSkKYGBgCgpVZmYuLi4gcGVybyBwb25lcmxlIGVsIHB1bnRvIGRlIG1pbGVzIGEgbG9zIGHDsW9zIHF1ZWRhIHJhcm8uIExhIHNvbHVjacOzbiBlcyBjb252ZXJ0aXIgbGEgY29sdW1uYSBgYW5pb2AgZW4gY2FyYWN0ZXIuIERlIGVzdGEgbWFuZXJhLCBubyBzZSB2ZSBhZmVjdGFkYSBwb3IgZWwgZm9ybWF0byBudW3DqXJpY28uIAoKYGBge3J9CnBhaXNlc19zZWxlY2Npb24gJT4lIAogIG11dGF0ZShhbmlvID0gYXMuY2hhcmFjdGVyKGFuaW8pKSAlPiUgCiAga2FibGUoY29sLm5hbWVzID0gYygiUGHDrXMiLCAiQcOxbyIsICJFc3BlcmFuemEgZGUgdmlkYSIsICJQb2JsYWNpw7NuIiwgIlBCSSBwZXIgY8OhcGl0YSIpLAogICAgICAgIGZvcm1hdC5hcmdzID0gbGlzdChkZWNpbWFsLm1hcmsgPSAiLCIsIGJpZy5tYXJrID0gIi4iKSkKYGBgCgpoYWNlciBga2FibGVgLCBxdWUgZXMgdW5hIGZ1bmNpw7NuIGRpc2XDsWFkYSBwYXJhIHNlciBzaW1wbGUgeSBoYWNlciBwb2NhcyBjb3Nhcy4gUGFyYSBoYWNlciBjb3NhcyB1biBwb2NvIG1hcyBjb21wbGljYWRhcyBlc3TDoSBlbCBwYXF1ZXRlIHtrYWJsZUV4dHJhfS4gCgojIyBTdXBlcnRhYmxhcyBjb24ge2thYmxlRXh0cmF9CgpFbCBwYXF1ZXRlIHtrYWJsZUV4dHJhfSwgY29tbyBzdSBub21icmUgbG8gaW5kaWNhLCBuYWNpw7MgcGFyYSBleHRlbmRlciBlbCBwb2RlciBkZSBsYSBmdW5jacOzbiBga2FibGVgLiAKCgpgYGB7cn0KbGlicmFyeShrYWJsZUV4dHJhKSAgIyBpbnN0YWxhciBjb24gaW5zdGFsbC5wYWNrYWdlcygia2FibGVFeHRyYSIpCmBgYAoKYGBge3J9CnBhaXNlc190YWJsYSA8LSBwYWlzZXNfc2VsZWNjaW9uICU+JSAKICBtdXRhdGUoYW5pbyA9IGFzLmNoYXJhY3RlcihhbmlvKSkgJT4lIAogIGthYmxlKGNvbC5uYW1lcyA9IGMoIlBhw61zIiwgIkHDsW8iLCAiRXNwZXJhbnphIGRlIHZpZGEiLCAiUG9ibGFjacOzbiIsICJQQkkgcGVyIGPDoXBpdGEiKSwKICAgICAgICBmb3JtYXQuYXJncyA9IGxpc3QoZGVjaW1hbC5tYXJrID0gIiwiLCBiaWcubWFyayA9ICIuIikpCmBgYAoKTGEgcHJpbWVyYSBjb2x1bW5hIGRlIGxhIHRhYmxhIGRlIGFycmliYSBlcyB1biB0YW50byByZWR1bmRhbnRlLiBTZXLDrWEgbWVqb3IgYWdydXBhciBsYXMgZmlsYXMgc2Vnw7puIGVsIHBhw61zLiBFc3RvIHNlIGNvbnNpZ3VlIGNvbiBsYSBmdW5jacOzbiBgY29sbGFwc2Vfcm93c2A6CgoKYGBge3J9CnBhaXNlc190YWJsYSAlPiUgCiAgY29sbGFwc2Vfcm93cyhjb2x1bW5zID0gMSwgdmFsaWduID0gInRvcCIpICAlPiUgCiAga2FibGVfc3R5bGluZygpIApgYGAKCgpFbCBwcmltZXIgYXJndW1lbnRvIGVzIGVsIG7Dum1lcm8gZGUgbGEgY29sdW1uYSBxdWUgcXVlcmVtb3MgYWdydXBhci4gRW4gZXN0ZSBjYXNvLCBsYSBjb2x1bW5hIGBwYWlzYCBlcyBsYSBwcmltZXJhLiBFbCBzZWd1bmRvIGFyZ3VtZW50byBlcyBsYSBhbGluZWFjacOzbiB2ZXJ0aWNhbC4gUG9yIGRlZmVjdG8sIGBjb2xsYXBzZV9yb3dzYCBwb25lIGxhcyBldGlxdWV0YXMgZW4gZWwgY2VudHJvLCBwZXJvIGxhIGNvbnZlbmNpw7NuIG3DoXMgZ2VuZXJhbCBlcyBwb25lcmxhcyBhcnJpYmEuIAoKwr9RdcOpIGVzIGVzYSBga2FibGVfc3R5bGluZygpYD8ge2thYmxlRXh0cmF9IHBlcm1pdGUgY2FtYmlhciBlbCBlc3RpbG8gZGUgbGFzIHRhYmxhcyBtdXkgZsOhY2lsbWVudGUuIGBrYWJsZV9zdHlsaW5nYCBlcyBlbCBlc3RpbG8gcG9yIGRlZmVjdG8sIHF1ZSBlcyBpZ3VhbCBhbCBxdWUgcHJvZHVjZSBga2FibGVgLCBwZXJvIHRpZW5lIG11Y2hvcyBvdHJvcy4gU2kgdmlzdGUgdGFibGFzIGhlY2hhcyBlbiBMYVRlWCwgcXVpesOhcyBlc3RlIGVzdGlsbyB0ZSByZXN1bHRlIGZhbWlsaWFyOgoKYGBge3J9CnBhaXNlc190YWJsYSAlPiUgCiAgY29sbGFwc2Vfcm93cyhjb2x1bW5zID0gMSwgdmFsaWduID0gInRvcCIpICAlPiUgCiAga2FibGVfY2xhc3NpY18yKCkKYGBgCgpMYSBmdW5jacOzbiBgY29sdW1uX3NwZWNgIHBlcm1pdGUgY2FtYmlhciBsb3MgcGFyw6FtZXRyb3MgZ3LDoWZpY29zIGRlIHVuYSBvIG3DoXMgY29sdW1uYXMuIEVuIGVzdGUgY2FzbyBjYW1iaWFtb3MgbGEgcHJpbWVyYSBjb2x1bW5hIChgY29sdW1uID0gMWApIHBhcmEgcXVlIGxhcyBwYWxhYnJhcyBhcGFyZXpjYW4gaXRhbGl6YWRhcyAoYGl0YWxpYyA9IFRSVUVgKToKCmBgYHtyfQpwYWlzZXNfdGFibGEgJT4lIAogIGNvbHVtbl9zcGVjKGNvbHVtbiA9IDEsIGl0YWxpYyA9IFRSVUUpICU+JQogIGNvbGxhcHNlX3Jvd3MoY29sdW1ucyA9IDEsIHZhbGlnbiA9ICJ0b3AiKSAgJT4lCiAga2FibGVfc3R5bGluZygpIApgYGAKCkxvIG5vdGFibGUgZGUgYGNvbHVtbl9zcGVjYCBlcyBxdWUgZW4gc3VzIGFyZ3VtZW50b3Mgc2UgcHVlZGVuIHBvbmVyIHZlY3RvcmVzIGRlIG1hbmVyYSBkZSBnZW5lcmFyIGZvcm1hdG8gY29uZGljaW9uYWwuIFBhcmEgcmVzYWx0YXIgY29uIG5lZ3JpdGEgw7puaWNhbWVudGUgZWwgcGHDrXMgIkFyZ2VudGluYSI6CgpgYGB7cn0KcGFpc2VzX3RhYmxhICU+JSAKICBjb2x1bW5fc3BlYyhjb2x1bW4gPSAxLCBib2xkID0gKHBhaXNlc19zZWxlY2Npb24kcGFpcyA9PSAiQXJnZW50aW5hIikpICU+JQogIGNvbGxhcHNlX3Jvd3MoY29sdW1ucyA9IDEsIHZhbGlnbiA9ICJ0b3AiKSAgJT4lCiAga2FibGVfc3R5bGluZygpIApgYGAKCkNvbnZpZW5lIGRldGVuZXJzZSBwYXJhIG1pcmFyIHVuIHBvY28gY29uIGRldGFsbGUgZWwgY8OzZGlnby4gTGEgbGxhbWFkYSBhIGBjb2x1bW5fc3BlY2AgZXN0w6EgY2FtYmlhbmRvIGVsIGZvcm1hdG8gZGUgbGEgY29sdW1uYSAxLiBFbiBwYXJ0aWN1bGFyLCB2YSBhIGRldGVybWluYXIgc2kgZWwgdGV4dG8gZXMgZW4gbmVncml0YSAoYm9sZCkgbyBuby4gWSBsYSBmb3JtYSBwYXJhIGRldGVybWluYXJsbyBlcyBlbCB2ZWN0b3IgYHBhaXNlcyRwYWlzID09ICJBcmdlbnRpbmEiYC4gwr9RdcOpIGVzIGVzZSB2ZWN0b3I/CgoKYGBge3J9CnBhaXNlc19zZWxlY2Npb24kcGFpcyA9PSAiQXJnZW50aW5hIgpgYGAKClBvciBsbyB0YW50bywgYGNvbHVtbl9zcGVjKGNvbHVtbiA9IDEsIGJvbGQgPSAocGFpc2VzJHBhaXMgPT0gIkFyZ2VudGluYSIpKWAgdmEgYSBoYWNlciBxdWUgbGFzIGRvcyBwcmltZXJhIGZpbGFzIGRlIGxhIGNvbHVtbmEgdW5vIGVzdMOpbiBlbiBuZWdyaXRhLCB5IGxhcyBkZW3DoXMgbm8uIEx1ZWdvLCBgY29sbGFwc2Vfcm93c2AgY29sYXBzYSBsYXMgZmlsYXMgc2Vnw7puIGVsIHBhw61zIHkgZW50b25jZXMgZXNhcyBkb3MgcHJpbWVyYXMgZmlsYXMgc2UgdHJhbnNmb3JtYW4gZW4gdW5hLiAKCkVzdG8gZGEgdW4gbW9udMOzbiBkZSBmbGV4aWJpbGlkYWQgZW4gZWwgZXN0aWxvIGRlbCB0ZXh0by4gUG9yIGVqZW1wbG8sIHNlIHB1ZWRlIGhhY2VyIHF1ZSBlbCBjb2xvciBkZWwgdGV4dG8gY2FtYmllIHNlZ8O6biBlbCB2YWxvciB1c2FuZG8gYGNvbHVtbl9zcGVjYCB5IGBzcGVjX2NvbG9yYC4KCmBgYHtyfQpwYWlzZXNfdGFibGEgJT4lIAogIGNvbHVtbl9zcGVjKDMsIGNvbG9yID0gc3BlY19jb2xvcihwYWlzZXNfc2VsZWNjaW9uJGVzcGVyYW56YV9kZV92aWRhKSkgJT4lIAogIGNvbGxhcHNlX3Jvd3MoY29sdW1ucyA9IDEsIHZhbGlnbiA9ICJ0b3AiKSAgJT4lCiAga2FibGVfc3R5bGluZygpIApgYGAKCkxhIGZ1bmNpw7NuIG51ZXZhLCBgc3BlY19jb2xvcmAgZ2VuZXJhIGNvbG9yZXMgYSBwYXJ0aXIgZGUgdW4gdmVjdG9yLiBQb2TDqXMgdmVyIGPDs21vIGZ1bmNpb25hIGVuIGVzdGEgbGluZWE6CgpgYGB7cn0Kc3BlY19jb2xvcihwYWlzZXNfc2VsZWNjaW9uJGVzcGVyYW56YV9kZV92aWRhKQpgYGAKCkVzb3MgbsO6bWVyb3Mgc29uIHJlcHJlc2VudGFjaW9uZXMgZW4gaGV4YWRlY2ltYWwgZGUgbG9zIGNvbG9yZXMgcXVlIHZlcyBlbiBsYSB0YWJsYS4gUG9kw6lzIHBhc2FybGUgY3VhbHF1aWVyIHNlcmllIGRlIGNvbG9yZXMsIG5vIHPDs2xvIGxhIGNyZWFkYSBjb24gYHNwZWNfY29sb3JgLiAKCkFzw60gY29tbyBzZSBwdWVkZSBjYW1iaWFyIGVsIGVzdGlsbyBkZSBsYXMgY29sdW1uYXMgY29uIGBjb2x1bW5fc3BlY2AsIHNlIHB1ZWRlIGNhbWJpYXIgZWwgZXN0aWxvIGRlIGxhcyBmaWxhcyBjb24gYHJvd19zcGVjYC4gUG9yIGVqZW1wbG8sIHNlIHB1ZWRlIHJlc2FsdGFyIGNhZGEgMiBsw61uZWFzIGNvbiBlc3RlIGPDs2RpZ286CgpgYGB7cn0KcGFpc2VzX3RhYmxhICU+JSAKICByb3dfc3BlYyhyb3cgPSBzZXEoMiwgbnJvdyhwYWlzZXNfc2VsZWNjaW9uKSwgYnkgPSAyKSwgYmFja2dyb3VuZCA9ICJhenVyZSIpICU+JSAKICBjb2xsYXBzZV9yb3dzKGNvbHVtbnMgPSAxLCB2YWxpZ24gPSAidG9wIikgICU+JQogIGthYmxlX3N0eWxpbmcoKSAKYGBgCgpgcm93X3NwZWNgIGVzdMOhIGNhbWJpYW5kbyBlbCBmb25kbyAoYmFja2dyb3VuZCkgYWwgY29sb3IgImF6dXJlIiAocXVlIGVzIGVzZSBjZWxlc3RpdG8pIGEgbGFzIGZpbGFzIGluZGljYWRhcyBwb3IgYHNlcSgyLCBucm93KHBhaXNlc19zZWxlY2Npb24pLCBieSA9IDIpYC4gwr9RdcOpIGVzIGVzbz8gYHNlcWAgZ2VuZXJhIHVuYSBzZWN1ZW5jaWEgKGRlICoqc2VxKip1ZW5jZSkgZGUgbsO6bWVyb3MgZW1wZXphbmRvIGVuIDIsIHRlcm1pbmFuZG8gZW4gbGEgY2FudGlkYWQgZGUgZmlsYXMgZGUgYHBhaXNlc19zZWxlY2Npb25gIHkgc2FsdGFuZG8gZGUgYSBkb3MuIEVuIHJlc3VtZW46CgpgYGB7cn0Kc2VxKDIsIG5yb3cocGFpc2VzX3NlbGVjY2lvbiksIGJ5ID0gMikKYGBgCgpDb21vIGNhc28gZXNwZWNpYWwsIHNlIHB1ZWRlIHVzYXIgYHJvdyA9IDBgIGVuIGByb3dfc3BlY2AgcGFyYSBjYW1iaWFyIGVsIGZvcm1hdG8gZGVsIGVuY2FiZXphZG8uCgpgYGB7cn0KcGFpc2VzX3RhYmxhICU+JSAKICByb3dfc3BlYyhyb3cgPSAwLCB1bmRlcmxpbmUgPSBUUlVFKSAlPiUgCiAgY29sbGFwc2Vfcm93cyhjb2x1bW5zID0gMSwgdmFsaWduID0gInRvcCIpICAlPiUKICBrYWJsZV9zdHlsaW5nKCkgCmBgYAoKCkVzdG8gZXMgc8OzbG8gdW5hIG3DrW5pbWEgcGFydGUgZGUgbG8gcXVlIHNlIHB1ZWRlIGhhY2VyIGNvbiBlbCBwYXF1ZXRlIHtrYWJsZUV4dHJhfS4gUGFyYSBlamVtcGxvcyBtdWNobyBtw6FzIGRldGFsbGFkb3MsIHRlIHJlY29tZW5kYW1vcyBsZWVyIFtsYSB2acOxZXRhIGNvbXBsZXRhXShodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMva2FibGVFeHRyYS92aWduZXR0ZXMvYXdlc29tZV90YWJsZV9pbl9odG1sLmh0bWwpCgoKPGRpdiBjbGFzcz0iYnRuLWdyb3VwIiByb2xlPSJncm91cCIgYXJpYS1sYWJlbD0iTmF2ZWdhY2nDs24iPgogIDxhIGhyZWY9ICIxMC1yZXBvcnRlcy1JSS5odG1sIiBjbGFzcyA9ICJidG4gYnRuLXByaW1hcnkiPkFudGVyaW9yPC9hPgogIDxhIGhyZWY9ICIxMi1nZ3Bsb3QtSUlJLmh0bWwiIGNsYXNzID0gImJ0biBidG4tcHJpbWFyeSI+U2lndWllbnRlPC9hPgo8L2Rpdj4=