El primer ejemplo de informe que vimos se convirtió en un archivo
html. Pero ¿qué pasa con los archivos Word o PDF, que pueden ser más
útiles o esperados en algunas situaciones? RMarkdown, y todo un
ecosistema de otros paquetes, permite generar documentos en múltiples
formatos utilizando el mismo archivo de texto plano.
La forma de generar el formato del archivo de salida es cambiando la
opción output
del encabezado.
Vuelve al informe de ejemplo y busca la línea que empieza por
output:
. Cambia html_document
por
pdf_document
.
También podes usar el botón “knit”, haciendo clic en la flechita de
la derecha para ver todas las opciones.
Ahora utiliza el botón para generar un documento de Word. ¿Qué
cambios ves en el encabezado del archivo?
Control del código
Nuestro ejemplo parece bastante ordenado. Hemos ocultado todo el
código y los mensajes de R para que puedas concentrar tu atención en la
tabla y las figuras. Pero este no es el comportamiento por defecto de un
archivo Rmd. Por lo general, la salida tendrá tanto el código como su
resultado, lo cual está bien cuando vos o la persona que leerá el
informe quiere ver el código que genera esos resultados, pero podría no
ser lo que la audiencia final del informe podría necesitar. Vos decidis
si quieres mostrar el código o no.
Para cambiar las opciones de un chunk de código, todo lo que tiene
que hacer es enumerar las opciones dentro de las llaves. Por
ejemplo:
```{r nombre-del-chunk, echo = FALSE, message = FALSE}
```
Un conjunto de opciones particularmente importante son las que
controlan si el código se ejecuta y si el resultado del código
permanecerá en el informe o no:
eval = FALSE
impide que se ejecute el código del
chunk, por lo que tampoco mostrará los resultados. Es útil para mostrar
código de ejemplo si estás escribiendo, por ejemplo, un documento para
enseñar R.
echo = FALSE
ejecuta el código del chunk y muestra
los resultados, pero oculta el código en el informe. Esto es útil para
escribir informes para personas que no necesitan ver el código R que
generó el gráfico o la tabla.
include = FALSE
ejecuta el código pero oculta tanto
el código como los resultados. Es útil para configuración general donde
se cargan las librerías.
Si estás escribiendo un informe en el que no quieres que se muestre
ningún código, añadir echo = FALSE
a cada nuevo chunk se
vuelve tedioso. La solución es cambiar la opción globalmente para que se
aplique a todos los chunks. Esto se hace con la función
knitr::opts_chunk$set()
, que establece las opciones
globales de los chunks que le siguen. Encontrarás esta función en el
primer chunk “setup”.
```{r setup, include = FALSE}
knitr::opts_chunk$set(echo = FALSE,
message = FALSE,
warning = FALSE)
```
¿Tienes curiosidad por saber cómo funcionan las opciones? Cámbialas
de una en una y toca el archivo cada vez para ver qué cambia.
Automatización
Al principio de este taller te pedimos que cambiaras el cultivar en
el informe de ejemplo. La tarea no fue fácil porque “ACA 861” aparece
varias veces y es fácil equivocarse. Parametrizar un informe nos permite
definir ese tipo de parámetros en un solo lugar y obtener diferentes
análisis a partir del mismo archivo.
Para generar un informe parametrizado hay que añadir un elemento
llamado params
a la cabecera con la lista de parámetros y
sus valores por defecto.
params:
cultivar: ACA 861
A partir de ahora, tendrás acceso a una variable llamada
params
que es una lista que contiene los parámetros y su
valor. Para acceder al valor de cada parámetro se utiliza el operador
$
de la siguiente manera:
## [1] "ACA 861"
De este modo, el código original puede modificarse para utilizar el
valor de la especie almacenada en params$cultivar
.
cultivares %>%
filter(Cultivar == params$cultivar) %>%
ggplot(aes(x = Rendimiento_Ajustado, y = Aceite_porcentaje)) +
geom_point(color = "darkorange",
size = 3,
alpha = 0.8) +
geom_smooth(method = "lm", se = FALSE, color = "darkorange") +
theme_minimal() +
labs(title = "Rendimiento y porcentaje de aceite",
subtitle = paste("Cultivar", params$cultivar),
x = "Rendimiento Ajustado (kg/ha)",
y = "Porcentaje de Aceite (%)",
color = "Cultivar")
Aquí cambiamos el subtítulo para concatenar palabras con el valor
almacenado en params$cultivar
, de esta manera podemos
construir el subtítulo de forma programática.
Ahora el informe está listo para funcionar como un informe
parametrizado.
Por último, cambia “ACA 861” en el yaml para generar un nuevo informe
para una de las otras especies.
Publicación
Querés compartir tus resultados y tenés un archivo RMarkdown o Quarto
en el que estuviste trabajando. Podrías compartir la carpeta del
proyecto o un link a un repositorio pero sería ideal que cualquier
persona pueda ver esos hermosos resultados sin necesidad de correr
código. La otra alternativa es knitear el documento para compartir un
PDF o archivo de Word. Las opciones no terminan ahí, Rmarkdown/Quarto
abre un mundo de posibilidades para trabajar con código de R, texto y
además compartir los resultados (y cualquier otra cosa!).
Sitio web de una sola página
Si sabés cómo generar un reporte en formato html usando R Markdown,
¡ya sabés todo lo que necesitás para publicar un sitio web simple! Lo
único que hace falta es un servicio que hostee el archivo y lo
muestre a los visitantes. Uno de ellos es Netlify, que permite crear un sitio
web con sólo arrastrar una carpeta.
Pequeño detalle: seguramente tu reporte (tu archivo
RMarkdown) tiene algún nombre descriptivo consistente con su contenido.
Para que convertirlo en una página web el archivo tiene que
tener un nombre especial: “index.html”. Adelante, nombrá a tu documento
como index.Rmd y knitea a HTML como de costumbre.
Ahora deberías tener como resultado archivo llamado “index.html” en
la carpeta de tu proyecto. ¡Felicitaciones! Creaste tu primer página
web.
Publicación
Solo falta publicar tu página web para no viva solo en tu
computadora. Veamos como se hace en Netlify.
Entrá a https://app.netlify.com/drop y arrastrar la carpeta que
contiene el archivo index.html en el recuadro. Netlify va a crear una
página web con un nombre aleatorio y posiblemente imposible de
deletrear, pero está publicada!
Aqui hay un
video con los pasos a seguir
Tal vez notaste que Netlify borra los sitios web luego de 24 horas.
Para que tu sitio sea permanente tenés que crearte una cuenta en
Netlify. Eso además te va a permitir cambiarle el nombre a tu página,
por ejemplo agroreporte.netlify.app
Publiquemos nuestro reporte en la web! Compartan el link a su pagina
web :-)
LS0tDQp0aXRsZTogIkluZm9ybWVzIGRlIHR1IHRyYWJham8iDQpvdXRwdXQ6IA0KICBodG1sX2RvY3VtZW50Og0KICAgIGNvZGVfZG93bmxvYWQ6IHRydWUNCiAgICB0b2M6IHRydWUNCiAgICB0b2NfZmxvYXQ6IGZhbHNlDQogICAgaGlnaGxpZ2h0OiB0YW5nbw0KLS0tDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKQ0KDQpjaHVuayA8LSAiYGBgIg0KYGBgDQoNCg0KRWwgcHJpbWVyIGVqZW1wbG8gZGUgaW5mb3JtZSBxdWUgdmltb3Mgc2UgY29udmlydGnDsyBlbiB1biBhcmNoaXZvIGh0bWwuIFBlcm8gwr9xdcOpIHBhc2EgY29uIGxvcyBhcmNoaXZvcyBXb3JkIG8gUERGLCBxdWUgcHVlZGVuIHNlciBtw6FzIMO6dGlsZXMgbyBlc3BlcmFkb3MgZW4gYWxndW5hcyBzaXR1YWNpb25lcz8gUk1hcmtkb3duLCB5IHRvZG8gdW4gZWNvc2lzdGVtYSBkZSBvdHJvcyBwYXF1ZXRlcywgcGVybWl0ZSBnZW5lcmFyIGRvY3VtZW50b3MgZW4gbcO6bHRpcGxlcyBmb3JtYXRvcyB1dGlsaXphbmRvIGVsIG1pc21vIGFyY2hpdm8gZGUgdGV4dG8gcGxhbm8uDQoNCkxhIGZvcm1hIGRlIGdlbmVyYXIgZWwgZm9ybWF0byBkZWwgYXJjaGl2byBkZSBzYWxpZGEgZXMgY2FtYmlhbmRvIGxhIG9wY2nDs24gYG91dHB1dGAgZGVsIGVuY2FiZXphZG8uDQoNCj4gVnVlbHZlIGFsIGluZm9ybWUgZGUgZWplbXBsbyB5IGJ1c2NhIGxhIGzDrW5lYSBxdWUgZW1waWV6YSBwb3IgYG91dHB1dDpgLiBDYW1iaWEgYGh0bWxfZG9jdW1lbnRgIHBvciBgcGRmX2RvY3VtZW50YC4NCg0KVGFtYmnDqW4gcG9kZXMgdXNhciBlbCBib3TDs24gImtuaXQiLCBoYWNpZW5kbyBjbGljIGVuIGxhIGZsZWNoaXRhIGRlIGxhIGRlcmVjaGEgcGFyYSB2ZXIgdG9kYXMgbGFzIG9wY2lvbmVzLiANCg0KPiBBaG9yYSB1dGlsaXphIGVsIGJvdMOzbiBwYXJhIGdlbmVyYXIgdW4gZG9jdW1lbnRvIGRlIFdvcmQuIMK/UXXDqSBjYW1iaW9zIHZlcyBlbiBlbCBlbmNhYmV6YWRvIGRlbCBhcmNoaXZvPw0KDQojIyBDb250cm9sIGRlbCBjw7NkaWdvDQoNCk51ZXN0cm8gZWplbXBsbyBwYXJlY2UgYmFzdGFudGUgb3JkZW5hZG8uIEhlbW9zIG9jdWx0YWRvIHRvZG8gZWwgY8OzZGlnbyB5IGxvcyBtZW5zYWplcyBkZSBSIHBhcmEgcXVlIHB1ZWRhcyBjb25jZW50cmFyIHR1IGF0ZW5jacOzbiBlbiBsYSB0YWJsYSB5IGxhcyBmaWd1cmFzLiBQZXJvIGVzdGUgbm8gZXMgZWwgY29tcG9ydGFtaWVudG8gcG9yIGRlZmVjdG8gZGUgdW4gYXJjaGl2byBSbWQuIFBvciBsbyBnZW5lcmFsLCBsYSBzYWxpZGEgdGVuZHLDoSB0YW50byBlbCBjw7NkaWdvIGNvbW8gc3UgcmVzdWx0YWRvLCBsbyBjdWFsIGVzdMOhIGJpZW4gY3VhbmRvIHZvcyBvIGxhIHBlcnNvbmEgcXVlIGxlZXLDoSBlbCBpbmZvcm1lIHF1aWVyZSB2ZXIgZWwgY8OzZGlnbyBxdWUgZ2VuZXJhIGVzb3MgcmVzdWx0YWRvcywgcGVybyBwb2Ryw61hIG5vIHNlciBsbyBxdWUgbGEgYXVkaWVuY2lhIGZpbmFsIGRlbCBpbmZvcm1lIHBvZHLDrWEgbmVjZXNpdGFyLiBWb3MgZGVjaWRpcyBzaSBxdWllcmVzIG1vc3RyYXIgZWwgY8OzZGlnbyBvIG5vLiANCg0KUGFyYSBjYW1iaWFyIGxhcyBvcGNpb25lcyBkZSB1biBjaHVuayBkZSBjw7NkaWdvLCB0b2RvIGxvIHF1ZSB0aWVuZSBxdWUgaGFjZXIgZXMgZW51bWVyYXIgbGFzIG9wY2lvbmVzIGRlbnRybyBkZSBsYXMgbGxhdmVzLiBQb3IgZWplbXBsbzoNCg0KICAgIGByIGNodW5rYHtyIG5vbWJyZS1kZWwtY2h1bmssIGVjaG8gPSBGQUxTRSwgbWVzc2FnZSA9IEZBTFNFfQ0KICAgIA0KICAgIGByIGNodW5rYA0KDQpVbiBjb25qdW50byBkZSBvcGNpb25lcyBwYXJ0aWN1bGFybWVudGUgaW1wb3J0YW50ZSBzb24gbGFzIHF1ZSBjb250cm9sYW4gc2kgZWwgY8OzZGlnbyBzZSBlamVjdXRhIHkgc2kgZWwgcmVzdWx0YWRvIGRlbCBjw7NkaWdvIHBlcm1hbmVjZXLDoSBlbiBlbCBpbmZvcm1lIG8gbm86DQoNCiogYGV2YWwgPSBGQUxTRWAgaW1waWRlIHF1ZSBzZSBlamVjdXRlIGVsIGPDs2RpZ28gZGVsIGNodW5rLCBwb3IgbG8gcXVlIHRhbXBvY28gbW9zdHJhcsOhIGxvcyByZXN1bHRhZG9zLiBFcyDDunRpbCBwYXJhIG1vc3RyYXIgY8OzZGlnbyBkZSBlamVtcGxvIHNpIGVzdMOhcyBlc2NyaWJpZW5kbywgcG9yIGVqZW1wbG8sIHVuIGRvY3VtZW50byBwYXJhIGVuc2XDsWFyIFIuDQoNCiogYGVjaG8gPSBGQUxTRWAgZWplY3V0YSBlbCBjw7NkaWdvIGRlbCBjaHVuayB5IG11ZXN0cmEgbG9zIHJlc3VsdGFkb3MsIHBlcm8gb2N1bHRhIGVsIGPDs2RpZ28gZW4gZWwgaW5mb3JtZS4gRXN0byBlcyDDunRpbCBwYXJhIGVzY3JpYmlyIGluZm9ybWVzIHBhcmEgcGVyc29uYXMgcXVlIG5vIG5lY2VzaXRhbiB2ZXIgZWwgY8OzZGlnbyBSIHF1ZSBnZW5lcsOzIGVsIGdyw6FmaWNvIG8gbGEgdGFibGEuDQoNCiogYGluY2x1ZGUgPSBGQUxTRWAgZWplY3V0YSBlbCBjw7NkaWdvIHBlcm8gb2N1bHRhIHRhbnRvIGVsIGPDs2RpZ28gY29tbyBsb3MgcmVzdWx0YWRvcy4gRXMgw7p0aWwgcGFyYSBjb25maWd1cmFjacOzbiBnZW5lcmFsIGRvbmRlIHNlIGNhcmdhbiBsYXMgbGlicmVyw61hcy4NCg0KU2kgZXN0w6FzIGVzY3JpYmllbmRvIHVuIGluZm9ybWUgZW4gZWwgcXVlIG5vIHF1aWVyZXMgcXVlIHNlIG11ZXN0cmUgbmluZ8O6biBjw7NkaWdvLCBhw7FhZGlyIGBlY2hvID0gRkFMU0VgIGEgY2FkYSBudWV2byBjaHVuayBzZSB2dWVsdmUgdGVkaW9zby4gTGEgc29sdWNpw7NuIGVzIGNhbWJpYXIgbGEgb3BjacOzbiBnbG9iYWxtZW50ZSBwYXJhIHF1ZSBzZSBhcGxpcXVlIGEgdG9kb3MgbG9zIGNodW5rcy4gRXN0byBzZSBoYWNlIGNvbiBsYSBmdW5jacOzbiBga25pdHI6Om9wdHNfY2h1bmskc2V0KClgLCBxdWUgZXN0YWJsZWNlIGxhcyBvcGNpb25lcyBnbG9iYWxlcyBkZSBsb3MgY2h1bmtzIHF1ZSBsZSBzaWd1ZW4uIEVuY29udHJhcsOhcyBlc3RhIGZ1bmNpw7NuIGVuIGVsIHByaW1lciBjaHVuayAic2V0dXAiLg0KDQogICAgYHIgY2h1bmtge3Igc2V0dXAsIGluY2x1ZGUgPSBGQUxTRX0NCiAgICBrbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IEZBTFNFLCANCiAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gRkFMU0UsDQogICAgICAgICAgICAgICAgICAgICAgd2FybmluZyA9IEZBTFNFKQ0KICAgIGByIGNodW5rYA0KICAgIA0KPiDCv1RpZW5lcyBjdXJpb3NpZGFkIHBvciBzYWJlciBjw7NtbyBmdW5jaW9uYW4gbGFzIG9wY2lvbmVzPyBDw6FtYmlhbGFzIGRlIHVuYSBlbiB1bmEgeSB0b2NhIGVsIGFyY2hpdm8gY2FkYSB2ZXogcGFyYSB2ZXIgcXXDqSBjYW1iaWEuDQoNCg0KIyMgQXV0b21hdGl6YWNpw7NuDQoNCkFsIHByaW5jaXBpbyBkZSBlc3RlIHRhbGxlciB0ZSBwZWRpbW9zIHF1ZSBjYW1iaWFyYXMgZWwgY3VsdGl2YXIgZW4gZWwgaW5mb3JtZSBkZSBlamVtcGxvLiBMYSB0YXJlYSBubyBmdWUgZsOhY2lsIHBvcnF1ZSAiQUNBIDg2MSIgYXBhcmVjZSB2YXJpYXMgdmVjZXMgeSBlcyBmw6FjaWwgZXF1aXZvY2Fyc2UuIFBhcmFtZXRyaXphciB1biBpbmZvcm1lIG5vcyBwZXJtaXRlIGRlZmluaXIgZXNlIHRpcG8gZGUgcGFyw6FtZXRyb3MgZW4gdW4gc29sbyBsdWdhciB5IG9idGVuZXIgZGlmZXJlbnRlcyBhbsOhbGlzaXMgYSBwYXJ0aXIgZGVsIG1pc21vIGFyY2hpdm8uIA0KDQpQYXJhIGdlbmVyYXIgdW4gaW5mb3JtZSBwYXJhbWV0cml6YWRvIGhheSBxdWUgYcOxYWRpciB1biBlbGVtZW50byBsbGFtYWRvIGBwYXJhbXNgIGEgbGEgY2FiZWNlcmEgY29uIGxhIGxpc3RhIGRlIHBhcsOhbWV0cm9zIHkgc3VzIHZhbG9yZXMgcG9yIGRlZmVjdG8uDQoNCmBgYHlhbWwNCnBhcmFtczoNCiAgY3VsdGl2YXI6IEFDQSA4NjENCmBgYA0KDQpgYGB7ciwgaW5jbHVkZT1GQUxTRX0NCnBhcmFtcyA8LSBsaXN0KGN1bHRpdmFyID0gIkFDQSA4NjEiKQ0KYGBgDQoNCkEgcGFydGlyIGRlIGFob3JhLCB0ZW5kcsOhcyBhY2Nlc28gYSB1bmEgdmFyaWFibGUgbGxhbWFkYSBgcGFyYW1zYCBxdWUgZXMgdW5hIGxpc3RhIHF1ZSBjb250aWVuZSBsb3MgcGFyw6FtZXRyb3MgeSBzdSB2YWxvci4gUGFyYSBhY2NlZGVyIGFsIHZhbG9yIGRlIGNhZGEgcGFyw6FtZXRybyBzZSB1dGlsaXphIGVsIG9wZXJhZG9yIGAkYCBkZSBsYSBzaWd1aWVudGUgbWFuZXJhOg0KDQpgYGB7cn0NCnBhcmFtcyRjdWx0aXZhcg0KYGBgDQoNCkRlIGVzdGUgbW9kbywgZWwgY8OzZGlnbyBvcmlnaW5hbCBwdWVkZSBtb2RpZmljYXJzZSBwYXJhIHV0aWxpemFyIGVsIHZhbG9yIGRlIGxhIGVzcGVjaWUgYWxtYWNlbmFkYSBlbiBgcGFyYW1zJGN1bHRpdmFyYC4NCg0KYGBge3IgZXZhbD1GQUxTRX0NCmN1bHRpdmFyZXMgJT4lIA0KICBmaWx0ZXIoQ3VsdGl2YXIgPT0gcGFyYW1zJGN1bHRpdmFyKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IFJlbmRpbWllbnRvX0FqdXN0YWRvLCB5ID0gQWNlaXRlX3BvcmNlbnRhamUpKSArDQogIGdlb21fcG9pbnQoY29sb3IgPSAiZGFya29yYW5nZSIsDQogICAgICAgICAgICAgc2l6ZSA9IDMsDQogICAgICAgICAgICAgYWxwaGEgPSAwLjgpICsNCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBGQUxTRSwgY29sb3IgPSAiZGFya29yYW5nZSIpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgbGFicyh0aXRsZSA9ICJSZW5kaW1pZW50byB5IHBvcmNlbnRhamUgZGUgYWNlaXRlIiwNCiAgICAgICBzdWJ0aXRsZSA9IHBhc3RlKCJDdWx0aXZhciIsIHBhcmFtcyRjdWx0aXZhciksDQogICAgICAgeCA9ICJSZW5kaW1pZW50byBBanVzdGFkbyAoa2cvaGEpIiwNCiAgICAgICB5ID0gIlBvcmNlbnRhamUgZGUgQWNlaXRlICglKSIsDQogICAgICAgY29sb3IgPSAiQ3VsdGl2YXIiKSANCmBgYA0KDQpBcXXDrSBjYW1iaWFtb3MgZWwgc3VidMOtdHVsbyBwYXJhIGNvbmNhdGVuYXIgcGFsYWJyYXMgY29uIGVsIHZhbG9yIGFsbWFjZW5hZG8gZW4gYHBhcmFtcyRjdWx0aXZhcmAsIGRlIGVzdGEgbWFuZXJhIHBvZGVtb3MgY29uc3RydWlyIGVsIHN1YnTDrXR1bG8gZGUgZm9ybWEgcHJvZ3JhbcOhdGljYS4NCg0KQWhvcmEgZWwgaW5mb3JtZSBlc3TDoSBsaXN0byBwYXJhIGZ1bmNpb25hciBjb21vIHVuIGluZm9ybWUgcGFyYW1ldHJpemFkby4NCg0KPiBQb3Igw7psdGltbywgY2FtYmlhICJBQ0EgODYxIiBlbiBlbCB5YW1sIHBhcmEgZ2VuZXJhciB1biBudWV2byBpbmZvcm1lIHBhcmEgdW5hIGRlIGxhcyBvdHJhcyBlc3BlY2llcy4gDQoNCiMjIFB1YmxpY2FjacOzbg0KDQpRdWVyw6lzIGNvbXBhcnRpciB0dXMgcmVzdWx0YWRvcyB5IHRlbsOpcyB1biBhcmNoaXZvIFJNYXJrZG93biBvIFF1YXJ0byBlbiBlbCBxdWUgZXN0dXZpc3RlIHRyYWJhamFuZG8uIFBvZHLDrWFzIGNvbXBhcnRpciBsYSBjYXJwZXRhIGRlbCBwcm95ZWN0byBvIHVuIGxpbmsgYSB1biByZXBvc2l0b3JpbyBwZXJvIHNlcsOtYSBpZGVhbCBxdWUgY3VhbHF1aWVyIHBlcnNvbmEgcHVlZGEgdmVyIGVzb3MgaGVybW9zb3MgcmVzdWx0YWRvcyBzaW4gbmVjZXNpZGFkIGRlIGNvcnJlciBjw7NkaWdvLiBMYSBvdHJhIGFsdGVybmF0aXZhIGVzIGtuaXRlYXIgZWwgZG9jdW1lbnRvIHBhcmEgY29tcGFydGlyIHVuIFBERiBvIGFyY2hpdm8gZGUgV29yZC4gTGFzIG9wY2lvbmVzIG5vIHRlcm1pbmFuIGFow60sIFJtYXJrZG93bi9RdWFydG8gYWJyZSB1biBtdW5kbyBkZSBwb3NpYmlsaWRhZGVzIHBhcmEgdHJhYmFqYXIgY29uIGPDs2RpZ28gZGUgUiwgdGV4dG8geSBhZGVtw6FzIGNvbXBhcnRpciBsb3MgcmVzdWx0YWRvcyAoeSBjdWFscXVpZXIgb3RyYSBjb3NhISkuDQoNCiMjIFNpdGlvIHdlYiBkZSB1bmEgc29sYSBww6FnaW5hDQoNClNpIHNhYsOpcyBjw7NtbyBnZW5lcmFyIHVuIHJlcG9ydGUgZW4gZm9ybWF0byBodG1sIHVzYW5kbyBSIE1hcmtkb3duLCDCoXlhIHNhYsOpcyB0b2RvIGxvIHF1ZSBuZWNlc2l0w6FzIHBhcmEgcHVibGljYXIgdW4gc2l0aW8gd2ViIHNpbXBsZSEgTG8gw7puaWNvIHF1ZSBoYWNlIGZhbHRhIGVzIHVuIHNlcnZpY2lvIHF1ZSAqaG9zdGVlKiBlbCBhcmNoaXZvIHkgbG8gbXVlc3RyZSBhIGxvcyB2aXNpdGFudGVzLiBVbm8gZGUgZWxsb3MgZXMgW05ldGxpZnldKGh0dHBzOi8vd3d3Lm5ldGxpZnkuY29tLyksIHF1ZSBwZXJtaXRlIGNyZWFyIHVuIHNpdGlvIHdlYiBjb24gc8OzbG8gYXJyYXN0cmFyIHVuYSBjYXJwZXRhLg0KDQoqKlBlcXVlw7FvIGRldGFsbGU6Kiogc2VndXJhbWVudGUgdHUgcmVwb3J0ZSAodHUgYXJjaGl2byBSTWFya2Rvd24pIHRpZW5lIGFsZ8O6biBub21icmUgZGVzY3JpcHRpdm8gY29uc2lzdGVudGUgY29uIHN1IGNvbnRlbmlkby4gUGFyYSBxdWUgKmNvbnZlcnRpcmxvKiBlbiB1bmEgcMOhZ2luYSB3ZWIgZWwgYXJjaGl2byB0aWVuZSBxdWUgdGVuZXIgdW4gbm9tYnJlIGVzcGVjaWFsOiAiaW5kZXguaHRtbCIuIEFkZWxhbnRlLCBub21icsOhIGEgdHUgZG9jdW1lbnRvIGNvbW8gaW5kZXguUm1kIHkga25pdGVhIGEgSFRNTCBjb21vIGRlIGNvc3R1bWJyZS4NCg0KQWhvcmEgZGViZXLDrWFzIHRlbmVyIGNvbW8gcmVzdWx0YWRvIGFyY2hpdm8gbGxhbWFkbyAiaW5kZXguaHRtbCIgZW4gbGEgY2FycGV0YSBkZSB0dSBwcm95ZWN0by4gwqFGZWxpY2l0YWNpb25lcyEgQ3JlYXN0ZSB0dSBwcmltZXIgcMOhZ2luYSB3ZWIuDQoNCiMjIyBQdWJsaWNhY2nDs24NCg0KU29sbyBmYWx0YSBwdWJsaWNhciB0dSBww6FnaW5hIHdlYiBwYXJhIG5vIHZpdmEgc29sbyBlbiB0dSBjb21wdXRhZG9yYS4gVmVhbW9zIGNvbW8gc2UgaGFjZSBlbiBOZXRsaWZ5Lg0KDQpFbnRyw6EgYSA8aHR0cHM6Ly9hcHAubmV0bGlmeS5jb20vZHJvcD4geSBhcnJhc3RyYXIgbGEgY2FycGV0YSBxdWUgY29udGllbmUgZWwgYXJjaGl2byBpbmRleC5odG1sIGVuIGVsIHJlY3VhZHJvLiBOZXRsaWZ5IHZhIGEgY3JlYXIgdW5hIHDDoWdpbmEgd2ViIGNvbiB1biBub21icmUgYWxlYXRvcmlvIHkgcG9zaWJsZW1lbnRlIGltcG9zaWJsZSBkZSBkZWxldHJlYXIsIHBlcm8gZXN0w6EgcHVibGljYWRhIQ0KDQpbQXF1aSBoYXkgdW4gdmlkZW8gY29uIGxvcyBwYXNvcyBhIHNlZ3Vpcl0oaHR0cHM6Ly93d3cueW91dHViZS5jb20vd2F0Y2g/dj1oWjhUcGZjTDFsOCkNCg0KVGFsIHZleiBub3Rhc3RlIHF1ZSBOZXRsaWZ5IGJvcnJhIGxvcyBzaXRpb3Mgd2ViIGx1ZWdvIGRlIDI0IGhvcmFzLiBQYXJhIHF1ZSB0dSBzaXRpbyBzZWEgcGVybWFuZW50ZSB0ZW7DqXMgcXVlIGNyZWFydGUgdW5hIGN1ZW50YSBlbiBOZXRsaWZ5LiBFc28gYWRlbcOhcyB0ZSB2YSBhIHBlcm1pdGlyIGNhbWJpYXJsZSBlbCBub21icmUgYSB0dSBww6FnaW5hLCBwb3IgZWplbXBsbyBhZ3JvcmVwb3J0ZS5uZXRsaWZ5LmFwcA0KDQo+IFB1YmxpcXVlbW9zIG51ZXN0cm8gcmVwb3J0ZSBlbiBsYSB3ZWIhICBDb21wYXJ0YW4gZWwgbGluayBhIHN1IHBhZ2luYSB3ZWIgOi0pDQo=