1. Introducción al código CSS

El lenguaje CSS (Cascading Style Sheets) corresponde a un lenguaje de marcado que nos ayuda a estilizar una página web acorde a cierta especificación. Además, es la segunda herramienta (después del conocimiento de HTML), necesaria para scrapear una página web.
Básicamente, el lenguaje CSS especifica reglas acerca de cómo un HTML se renderiza en un navegador, incluyendo cosas como el tamaño de la fuente, el color, el tipo de letra, etc. A continuación un ejemplo.

En este se puede observar que un selector construye su estilo entre { } colocando propiedades y valores.
2. Selectores CSS
Si bien no estamos particularmente interesados en cómo definir el estilo de una página web, sí nos interesa cómo estas definiciones se localizan dentro de un documento HTML. Así, los selectores CSS se encuentran definiendo el estilo de un determinado elemento dentro del código HTML, y estos son los que normalmente se utilizan para scrapear una página web con rvest. Veamos un ejemplo.

En este, el elemento paragraph se encuentra definido en la parte de abajo, y podemos usar la función html_nodes para localizar dicho elemento. De hecho, el lenguaje CSS le permite al desarrollador web definir estilos para cada elemento, al nivel más granular posible, para construir sitios web complejos y atractivos.
Cabe notar que existen operadores en estos selectores como *, que nos permiten seleccionar todas las etiquetas existentes o , que nos permite tomar varios selectores al mismo tiempo.
3. Clases CSS
Hasta el punto anterior podríamos scrapear páginas web muy sencillas sin necesidad de utilizar herramientas como inspeccionar. Sin embargo, los sitios web actualesson mucho más complejos y tienen cientos de elementos HTML. Por ello se crearon las classes y IDs, los cuales nos permiten identificar ciertas partes de un documento HTML.
Con las classes o clases, los elementos HTML pueden ser categorizados en grupos de estilo, donde cada elemento con la misma clase tiene aplicado el mismo estilo defindo en el CSS. Para especificar una clase en el CSS, se lo hace con un punto antes del nombre de la clase, por ejemplo: .prose-text. Al seleccionarlos dentro con html_nodes usaremos la misma lógica.

Veamos un ejemplo:
library(rvest)
library(tidyverse)
html <- read_html("https://www.eluniverso.com/noticias/ecuador/estado-de-excepcion-en-guayaquil-y-en-el-oro-se-ampliaria-por-30-dias-coe-hara-recomendacion-a-presidente-guillermo-lasso-nota/")
html %>% html_nodes(".prose-text")
{xml_nodeset (17)}
[1] <p class="prose-text">El Comité de Operaciones de Emergencia <b>(COE) </b>n ...
[2] <p class="prose-text">Así lo manifestó<b> Juan Zapata,</b> titular del COE, ...
[3] <p class="prose-text"><b>Zapata</b> agregó que se pide mantener todas las m ...
[4] <p class="prose-text">El argumento es el aumento de casos de la variante de ...
[5] <p class="prose-text">El <b>estado de excepción</b> rige hasta este<b> miér ...
[6] <p class="prose-text">Se inició el pasado 14 de julio con un <b>decreto </b ...
[7] <p class="prose-text"><b>Para Guayaquil </b>se limitó el aforo al 50 % en e ...
[8] <p class="prose-text">En la provincia de <b>El Oro</b>, los aforos son del ...
[9] <p class="prose-text">El transporte interprovincial quedó suspendido<b> des ...
[10] <p class="prose-text">El aforo en el transporte público es del 30 % y los a ...
[11] <p class="prose-text">El funcionario sostuvo que es facultad del presidente ...
[12] <p class="prose-text"><b>Según Garzón</b>, en El Oro, en 15 días “apenas te ...
[13] <p class="prose-text">Espera que con el aumento de la <b>población vacunada ...
[14] <p class="prose-text">La funcionaria aspira que, a <b>principios o mediados ...
[15] <p class="prose-text"><b>Este jueves, el COE </b>recibirá el informe de eva ...
[16] <p class="prose-text">Además, el COE generará <b>medidas complementarias</b ...
[17] <p class="prose-text">Las medidas complementarias podrían referirse a los t ...
Si por otro lado, deseamos seleccionar varias clases al mismo tiempo, tan solo las ponemos una junto a la otra, sin utilizar espacios, como se muestra a continuación.
library(rvest)
library(tidyverse)
html <- read_html("https://www.eluniverso.com/noticias/ecuador/estado-de-excepcion-en-guayaquil-y-en-el-oro-se-ampliaria-por-30-dias-coe-hara-recomendacion-a-presidente-guillermo-lasso-nota/")
html %>% html_nodes("div.resized-image.col-span-12.w-full.my-2.bg-grey-100") %>%
html_attrs()
[[1]]
class
"resized-image col-span-12 w-full my-2 bg-grey-100"
4. IDs
Los IDs por otro lado, son un tipo especial de clases y hacen identificables a cada nodo. Su diferencia yace en que deben ser únicos dentro de una página web. Estos se escriben dentro del CSS con un # al inicio, como se muestra a continuación.

Veamos un ejemplo práctico.
html %>% html_nodes("#R3T0A9DXCBF9GX")
{xml_nodeset (1)}
[1] <div id="R3T0A9DXCBF9GX" data-hook="review" class="a-section review aok-rela ...
A la final, en lugar de seleccionar todo con una cierta clase o ID, scrapearemos un sitio web combinando ambos para llegar a elemento en específico que estamos buscando.
De igual manera, podemos especificar aún más esta búsqueda utilizando pseudo-classes. Existen muchos tipos, pero las más importantes son las conocidos como first-child, last-child y nth-child. Como su nombre nos indica, nos ayudan a rastrear el hijo específico de un elemento HTML.

En la práctica estos se ven como:
html %>% html_nodes("div:nth-child(2) p:nth-child(15)")
{xml_nodeset (1)}
[1] <p>On Internet Explorer: <br>\nTop menu; FILE\\ OPEN\\ BROWSE <br> \nClick o ...
5. Combinadores CSS
Para utilizar selectores CSS de manera combinada usaremos los combinadores, que en total son 4. Estos siempre tienen la misma estructura: selector CSS, operador de combinación y otro selector. Estos operadores son:
- Espacio ( ), el cual también es llamado el combinador de descendencia. Este selecciona a todos los descendientes de un elemento HTML.
- Mayor que (>), el cual forma al combinador hijo. Este es un tipo específico del combinador de descendiente y selecciona a solo a los descendientes directos o hijos.
- Más (+), el cual también es llamado combinador de hermano adyacente. Este selecciona al hermano directo de un nodo, exceptuando a este nodo.
- Tilde (~), el cual es llamado combinador general de hermanos. Este funciona similar al anterior, pero selecciona a todos los hermanos.

Estos operadores son bastante útiles sobretodo cuando algún elemento HTML que estemos buscando no es directamente detectable a través de una clase o ID. Para identificarlos, nos serán de especial ayuda las herramientas de inspección.
LS0tDQp0aXRsZTogIldlYiBTY3JhcHBpbmcgY29uIFIiDQpzdWJ0aXRsZTogJ0NhcMOtdHVsbyA0OiBTZWxlY3RvcmVzIENTUycNCmF1dGhvcjogSHVnbyBQb3JyYXMNCm91dHB1dDogDQogIGh0bWxfbm90ZWJvb2s6DQogICAgY3NzOiBFc3RpbG9zLmNzcw0KICAgIHRvYzogdHJ1ZQ0KICAgIHRvY19kZXB0aDogMg0KICAgIHRvY19mbG9hdDoNCiAgICAgIGNvbGxhcHNlZDogdHJ1ZQ0KICAgICAgc21vb3RoX3Njcm9sbDogZmFsc2UNCmJpYmxpb2dyYXBoeTogQmlibGlvZ3JhZmlhLmJpYg0KY3NsOiBjZXBhbC54bWwNCi0tLQ0KDQojICoqMS4gSW50cm9kdWNjacOzbiBhbCBjw7NkaWdvIENTUyoqDQoNCiFbXShodHRwczovL3d3dy53M2RvY3MuY29tL3VwbG9hZHMvbWVkaWEvZGVmYXVsdC8wMDAxLzA1LzZkMDdhMzZlYmU2ZDU1MjczYjM5NDQwZjIzOTFmMWQ3ZTZkNDA5MmEucG5nKQ0KDQpFbCBsZW5ndWFqZSAqKkNTUyAoQ2FzY2FkaW5nIFN0eWxlIFNoZWV0cykqKiBjb3JyZXNwb25kZSBhIHVuIGxlbmd1YWplIGRlIG1hcmNhZG8gcXVlIG5vcyBheXVkYSBhIGVzdGlsaXphciB1bmEgcMOhZ2luYSB3ZWIgYWNvcmRlIGEgY2llcnRhIGVzcGVjaWZpY2FjacOzbi4gQWRlbcOhcywgZXMgbGEgc2VndW5kYSBoZXJyYW1pZW50YSAoZGVzcHXDqXMgZGVsIGNvbm9jaW1pZW50byBkZSBIVE1MKSwgbmVjZXNhcmlhIHBhcmEgc2NyYXBlYXIgdW5hIHDDoWdpbmEgd2ViLg0KDQpCw6FzaWNhbWVudGUsIGVsIGxlbmd1YWplIENTUyBlc3BlY2lmaWNhIHJlZ2xhcyBhY2VyY2EgZGUgY8OzbW8gdW4gSFRNTCBzZSByZW5kZXJpemEgZW4gdW4gbmF2ZWdhZG9yLCBpbmNsdXllbmRvIGNvc2FzIGNvbW8gZWwgdGFtYcOxbyBkZSBsYSBmdWVudGUsIGVsIGNvbG9yLCBlbCB0aXBvIGRlIGxldHJhLCBldGMuIEEgY29udGludWFjacOzbiB1biBlamVtcGxvLg0KDQohW10oaHR0cHM6Ly9tZG4ubW96aWxsYWRlbW9zLm9yZy9maWxlcy8xMTkyNS9jc3NwYXJ0ZXMucG5nKQ0KDQpFbiBlc3RlIHNlIHB1ZWRlIG9ic2VydmFyIHF1ZSB1biAqKnNlbGVjdG9yKiogY29uc3RydXllIHN1IGVzdGlsbyBlbnRyZSAqKnsqKiAqKn0qKiBjb2xvY2FuZG8gKipwcm9waWVkYWRlcyoqIHkgKip2YWxvcmVzKiouIA0KDQojICoqMi4gU2VsZWN0b3JlcyBDU1MqKg0KDQpTaSBiaWVuIG5vIGVzdGFtb3MgcGFydGljdWxhcm1lbnRlIGludGVyZXNhZG9zIGVuIGPDs21vIGRlZmluaXIgZWwgZXN0aWxvIGRlIHVuYSBww6FnaW5hIHdlYiwgc8OtIG5vcyBpbnRlcmVzYSBjw7NtbyBlc3RhcyBkZWZpbmljaW9uZXMgc2UgbG9jYWxpemFuIGRlbnRybyBkZSB1biBkb2N1bWVudG8gSFRNTC4gQXPDrSwgbG9zICoqc2VsZWN0b3JlcyBDU1MqKiBzZSBlbmN1ZW50cmFuIGRlZmluaWVuZG8gZWwgZXN0aWxvIGRlIHVuIGRldGVybWluYWRvIGVsZW1lbnRvIGRlbnRybyBkZWwgY8OzZGlnbyBIVE1MLCB5IGVzdG9zIHNvbiBsb3MgcXVlIG5vcm1hbG1lbnRlIHNlIHV0aWxpemFuIHBhcmEgc2NyYXBlYXIgdW5hIHDDoWdpbmEgd2ViIGNvbiBydmVzdC4gVmVhbW9zIHVuIGVqZW1wbG8uDQoNCiFbXShodHRwczovL3Jlc291cmNlcy5qZXRicmFpbnMuY29tL2hlbHAvaW1nL2lkZWEvMjAyMS4xL2Nzc19pbnRyb19jb21wbGV0aW9uX2xpZ2h0LnBuZykNCg0KRW4gZXN0ZSwgZWwgZWxlbWVudG8gKnBhcmFncmFwaCogc2UgZW5jdWVudHJhIGRlZmluaWRvIGVuIGxhIHBhcnRlIGRlIGFiYWpvLCB5IHBvZGVtb3MgdXNhciBsYSBmdW5jacOzbiAqKmh0bWxfbm9kZXMqKiBwYXJhIGxvY2FsaXphciBkaWNobyBlbGVtZW50by4gRGUgaGVjaG8sIGVsIGxlbmd1YWplIENTUyBsZSBwZXJtaXRlIGFsIGRlc2Fycm9sbGFkb3Igd2ViIGRlZmluaXIgZXN0aWxvcyBwYXJhIGNhZGEgZWxlbWVudG8sIGFsIG5pdmVsIG3DoXMgZ3JhbnVsYXIgcG9zaWJsZSwgcGFyYSBjb25zdHJ1aXIgc2l0aW9zIHdlYiBjb21wbGVqb3MgeSBhdHJhY3Rpdm9zLg0KDQpDYWJlIG5vdGFyIHF1ZSBleGlzdGVuIG9wZXJhZG9yZXMgZW4gZXN0b3Mgc2VsZWN0b3JlcyBjb21vICoqXCoqKiwgcXVlIG5vcyBwZXJtaXRlbiBzZWxlY2Npb25hciB0b2RhcyBsYXMgZXRpcXVldGFzIGV4aXN0ZW50ZXMgbyAqKiwqKiBxdWUgbm9zIHBlcm1pdGUgdG9tYXIgdmFyaW9zIHNlbGVjdG9yZXMgYWwgbWlzbW8gdGllbXBvLg0KDQojICoqMy4gQ2xhc2VzIENTUyoqDQoNCkhhc3RhIGVsIHB1bnRvIGFudGVyaW9yIHBvZHLDrWFtb3Mgc2NyYXBlYXIgcMOhZ2luYXMgd2ViIG11eSBzZW5jaWxsYXMgc2luIG5lY2VzaWRhZCBkZSB1dGlsaXphciBoZXJyYW1pZW50YXMgY29tbyAqKmluc3BlY2Npb25hcioqLiBTaW4gZW1iYXJnbywgbG9zIHNpdGlvcyB3ZWIgYWN0dWFsZXNzb24gbXVjaG8gbcOhcyBjb21wbGVqb3MgeSB0aWVuZW4gY2llbnRvcyBkZSBlbGVtZW50b3MgSFRNTC4gUG9yIGVsbG8gc2UgY3JlYXJvbiBsYXMgKipjbGFzc2VzKiogeSAqKklEcyoqLCBsb3MgY3VhbGVzIG5vcyBwZXJtaXRlbiBpZGVudGlmaWNhciBjaWVydGFzIHBhcnRlcyBkZSB1biBkb2N1bWVudG8gSFRNTC4NCg0KQ29uIGxhcyAqKmNsYXNzZXMqKiBvIGNsYXNlcywgbG9zIGVsZW1lbnRvcyBIVE1MIHB1ZWRlbiBzZXIgY2F0ZWdvcml6YWRvcyBlbiBncnVwb3MgZGUgZXN0aWxvLCBkb25kZSBjYWRhIGVsZW1lbnRvIGNvbiBsYSBtaXNtYSBjbGFzZSB0aWVuZSBhcGxpY2FkbyBlbCBtaXNtbyBlc3RpbG8gZGVmaW5kbyBlbiBlbCBDU1MuIFBhcmEgZXNwZWNpZmljYXIgdW5hIGNsYXNlIGVuIGVsIENTUywgc2UgbG8gaGFjZSBjb24gdW4gcHVudG8gYW50ZXMgZGVsIG5vbWJyZSBkZSBsYSBjbGFzZSwgcG9yIGVqZW1wbG86ICoqLnByb3NlLXRleHQqKi4gQWwgc2VsZWNjaW9uYXJsb3MgZGVudHJvIGNvbiAqKmh0bWxfbm9kZXMqKiB1c2FyZW1vcyBsYSBtaXNtYSBsw7NnaWNhLg0KDQohW10oaHR0cHM6Ly93d3cud2lraWhvdy5jb20vaW1hZ2VzL3RodW1iLzUvNTMvRGVmaW5lLWEtQ1NTLUNsYXNzLVN0eWxlLVN0ZXAtNC1WZXJzaW9uLTIuanBnL3Y0LTQ2MHB4LURlZmluZS1hLUNTUy1DbGFzcy1TdHlsZS1TdGVwLTQtVmVyc2lvbi0yLmpwZy53ZWJwKQ0KDQpWZWFtb3MgdW4gZWplbXBsbzoNCg0KYGBge3J9DQpsaWJyYXJ5KHJ2ZXN0KQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpodG1sIDwtIHJlYWRfaHRtbCgiaHR0cHM6Ly93d3cuZWx1bml2ZXJzby5jb20vbm90aWNpYXMvZWN1YWRvci9lc3RhZG8tZGUtZXhjZXBjaW9uLWVuLWd1YXlhcXVpbC15LWVuLWVsLW9yby1zZS1hbXBsaWFyaWEtcG9yLTMwLWRpYXMtY29lLWhhcmEtcmVjb21lbmRhY2lvbi1hLXByZXNpZGVudGUtZ3VpbGxlcm1vLWxhc3NvLW5vdGEvIikNCmh0bWwgJT4lIGh0bWxfbm9kZXMoIi5wcm9zZS10ZXh0IikNCmBgYA0KDQpTaSBwb3Igb3RybyBsYWRvLCBkZXNlYW1vcyBzZWxlY2Npb25hciB2YXJpYXMgY2xhc2VzIGFsIG1pc21vIHRpZW1wbywgdGFuIHNvbG8gbGFzIHBvbmVtb3MgdW5hIGp1bnRvIGEgbGEgb3RyYSwgc2luIHV0aWxpemFyIGVzcGFjaW9zLCBjb21vIHNlIG11ZXN0cmEgYSBjb250aW51YWNpw7NuLg0KDQpgYGB7cn0NCmh0bWwgJT4lIGh0bWxfbm9kZXMoImRpdi5yZXNpemVkLWltYWdlLmNvbC1zcGFuLTEyLnctZnVsbC5teS0yLmJnLWdyZXktMTAwIikgJT4lIA0KICBodG1sX2F0dHJzKCkNCmBgYA0KDQojICoqNC4gSURzKioNCg0KTG9zICoqSURzKiogcG9yIG90cm8gbGFkbywgc29uIHVuIHRpcG8gZXNwZWNpYWwgZGUgY2xhc2VzIHkgaGFjZW4gaWRlbnRpZmljYWJsZXMgYSBjYWRhIG5vZG8uIFN1IGRpZmVyZW5jaWEgeWFjZSBlbiBxdWUgZGViZW4gc2VyIMO6bmljb3MgZGVudHJvIGRlIHVuYSBww6FnaW5hIHdlYi4gRXN0b3Mgc2UgZXNjcmliZW4gZGVudHJvIGRlbCBDU1MgY29uIHVuICoqIyoqIGFsIGluaWNpbywgY29tbyBzZSBtdWVzdHJhIGEgY29udGludWFjacOzbi4NCg0KIVtdKGh0dHBzOi8vd3d3Lndpa2l0ZWNoeS5jb20vY3NzL2ltZy9jc3MtaW1hZ2VzL2NvZGUtZXhwbGFuYXRpb24tY3NzLWlkLXNlbGVjdG9yLnBuZykNCg0KVmVhbW9zIHVuIGVqZW1wbG8gcHLDoWN0aWNvLg0KDQpgYGB7cn0NCmh0bWwgPC0gcmVhZF9odG1sKCJodHRwczovL3d3dy5hbWF6b24uY29tLy0vZXMvU2NvdHQtU255ZGVyL2RwLzE3Nzk1MDc5NDEvcmVmPXNyXzFfMT9fX21rX2VzX1VTPSVDMyU4NU0lQzMlODUlQzUlQkQlQzMlOTUlQzMlOTEmZGNoaWxkPTEma2V5d29yZHM9ZGFyaytrbmlnaHRzK21ldGFsJnFpZD0xNjI3NTAxMTY3JnNyPTgtMSIpDQpodG1sICU+JSBodG1sX25vZGVzKCIjUjNUMEE5RFhDQkY5R1giKQ0KYGBgDQoNCkEgbGEgZmluYWwsIGVuIGx1Z2FyIGRlIHNlbGVjY2lvbmFyIHRvZG8gY29uIHVuYSBjaWVydGEgY2xhc2UgbyBJRCwgc2NyYXBlYXJlbW9zIHVuIHNpdGlvIHdlYiBjb21iaW5hbmRvIGFtYm9zIHBhcmEgbGxlZ2FyIGEgZWxlbWVudG8gZW4gZXNwZWPDrWZpY28gcXVlIGVzdGFtb3MgYnVzY2FuZG8uIA0KDQpEZSBpZ3VhbCBtYW5lcmEsIHBvZGVtb3MgZXNwZWNpZmljYXIgYcO6biBtw6FzIGVzdGEgYsO6c3F1ZWRhIHV0aWxpemFuZG8gKipwc2V1ZG8tY2xhc3NlcyoqLiBFeGlzdGVuIG11Y2hvcyB0aXBvcywgcGVybyBsYXMgbcOhcyBpbXBvcnRhbnRlcyBzb24gbGFzIGNvbm9jaWRvcyBjb21vICoqZmlyc3QtY2hpbGQqKiwgKipsYXN0LWNoaWxkKiogeSAqKm50aC1jaGlsZCoqLiBDb21vIHN1IG5vbWJyZSBub3MgaW5kaWNhLCBub3MgYXl1ZGFuIGEgcmFzdHJlYXIgZWwgaGlqbyBlc3BlY8OtZmljbyBkZSB1biBlbGVtZW50byBIVE1MLg0KDQohW10oaHR0cHM6Ly9zMy11cy13ZXN0LTIuYW1hem9uYXdzLmNvbS9kZXZjb2RlcHJvL21lZGlhL3R1dG9yaWFscy9wc2V1ZG9jbGFzZXMtY3NzLWZpcnN0LWNoaWxkLWxhc3QtY2hpbGQtbnRoLWNoaWxkLXQxLnBuZykNCg0KRW4gbGEgcHLDoWN0aWNhIGVzdG9zIHNlIHZlbiBjb21vOg0KDQpgYGB7cn0NCmh0bWwgPC0gcmVhZF9odG1sKCJodHRwczovL3d3dy55b3JrLmFjLnVrL3RlYWNoaW5nL2N3cy93d3Mvd2VicGFnZTEuaHRtbCIpDQpodG1sICU+JSBodG1sX25vZGVzKCJkaXY6bnRoLWNoaWxkKDIpIHA6bnRoLWNoaWxkKDE1KSIpDQpgYGANCg0KIyAqKjUuIENvbWJpbmFkb3JlcyBDU1MqKg0KDQpQYXJhIHV0aWxpemFyIHNlbGVjdG9yZXMgQ1NTIGRlIG1hbmVyYSBjb21iaW5hZGEgdXNhcmVtb3MgbG9zICoqY29tYmluYWRvcmVzKiosIHF1ZSBlbiB0b3RhbCBzb24gNC4gRXN0b3Mgc2llbXByZSB0aWVuZW4gbGEgbWlzbWEgZXN0cnVjdHVyYTogKipzZWxlY3RvciBDU1MsIG9wZXJhZG9yIGRlIGNvbWJpbmFjacOzbiB5IG90cm8gc2VsZWN0b3IqKi4gRXN0b3Mgb3BlcmFkb3JlcyBzb246DQoNCisgKipFc3BhY2lvICggKSoqLCBlbCBjdWFsIHRhbWJpw6luIGVzIGxsYW1hZG8gZWwgKipjb21iaW5hZG9yIGRlIGRlc2NlbmRlbmNpYSoqLiBFc3RlIHNlbGVjY2lvbmEgYSB0b2RvcyBsb3MgZGVzY2VuZGllbnRlcyBkZSB1biBlbGVtZW50byBIVE1MLg0KKyAqKk1heW9yIHF1ZSAoPikqKiwgZWwgY3VhbCBmb3JtYSBhbCAqKmNvbWJpbmFkb3IgaGlqbyoqLiBFc3RlIGVzIHVuIHRpcG8gZXNwZWPDrWZpY28gZGVsIGNvbWJpbmFkb3IgZGUgZGVzY2VuZGllbnRlIHkgc2VsZWNjaW9uYSBhIHNvbG8gYSBsb3MgZGVzY2VuZGllbnRlcyBkaXJlY3RvcyBvIGhpam9zLg0KKyAqKk3DoXMgKCspKiosIGVsIGN1YWwgdGFtYmnDqW4gZXMgbGxhbWFkbyBjb21iaW5hZG9yIGRlICoqaGVybWFubyBhZHlhY2VudGUqKi4gRXN0ZSBzZWxlY2Npb25hIGFsIGhlcm1hbm8gZGlyZWN0byBkZSB1biBub2RvLCBleGNlcHR1YW5kbyBhIGVzdGUgbm9kby4NCisgKipUaWxkZSAofikqKiwgZWwgY3VhbCBlcyBsbGFtYWRvIGNvbWJpbmFkb3IgKipnZW5lcmFsIGRlIGhlcm1hbm9zKiouIEVzdGUgZnVuY2lvbmEgc2ltaWxhciBhbCBhbnRlcmlvciwgcGVybyBzZWxlY2Npb25hIGEgdG9kb3MgbG9zIGhlcm1hbm9zLg0KDQohW10oaHR0cHM6Ly9pMC53cC5jb20vd3d3LnR1dG9yaWFsYnJhaW4uY29tL3dwLWNvbnRlbnQvdXBsb2Fkcy8yMDE5LzA2L0NTUy1DT01CSU5BVE9SLnBuZz9maXQ9NDc0JTJDMzc5JnNzbD0xKQ0KDQpFc3RvcyBvcGVyYWRvcmVzIHNvbiBiYXN0YW50ZSDDunRpbGVzIHNvYnJldG9kbyBjdWFuZG8gYWxnw7puIGVsZW1lbnRvIEhUTUwgcXVlIGVzdGVtb3MgYnVzY2FuZG8gKipubyBlcyBkaXJlY3RhbWVudGUgZGV0ZWN0YWJsZSBhIHRyYXbDqXMgZGUgdW5hIGNsYXNlIG8gSUQqKi4gUGFyYSBpZGVudGlmaWNhcmxvcywgbm9zIHNlcsOhbiBkZSBlc3BlY2lhbCBheXVkYSBsYXMgaGVycmFtaWVudGFzIGRlIGluc3BlY2Npw7NuLg0KDQoNCg==