library("ggplot2")
library("dplyr")
library("tidyverse")
-- Attaching packages --------------------------------------- tidyverse 1.2.1 --
v tidyr   0.8.2     v purrr   0.2.5
v readr   1.1.1     v stringr 1.3.1
v tidyr   0.8.2     v forcats 0.3.0
-- Conflicts ------------------------------------------ tidyverse_conflicts() --
x dplyr::filter() masks stats::filter()
x dplyr::lag()    masks stats::lag()
library("tibble")
install.packages("tidyverse")

Introducción al análisis de datos. en el texto se trata: “Reestructura de datos y el principio de los datos limpios” y “Estrategia divide-aplica-combina”.

La limpieza y orden de los datos es elemental para facilitar el trabajo de análisis, en este texto se muestran técnicas para hacer de la data un lugar más conveniente donde trabajar.

La idea es limpiar los datos de la información que no necesitamos y almacenarlos de una manera consistente que nos permita enfocarnos en responder las dudas antes de estar luchando por descifrarlos. A fin de cuentas, una data ordenada y limpia nos ayuda a trabajar en la: Manipulación, visualización y modelación de los datos.

En resumen:

Lo importante de armar una tabla ordenada es comenzar por identificar las variables, en el siguiente caso, las variable será las anotaciones de Camilo y Luciano con la camiseta de su club universitario, Club Atlético Cenicero (CAC).

comenzaremos por asignarle nombre a la data, en este caso le pondremos Goles_por_partido, siendo el primer dato el nombre del jugador, separado por un guión bajo el número correspondiente a la fecha:

Goles_por_partido <- tibble(camilo_1 = c(2),
       camilo_2 = c(3),
       camilo_3 = c(1),
       luciano_1 = c(1),
       luciano_2 = c(3),
       luciano_3 = c(0)
       )

A continuación la tabla:

tibble(camilo_1 = c(2),
       camilo_2 = c(3),
       camilo_3 = c(1),
       luciano_1 = c(1),
       luciano_2 = c(3),
       luciano_3 = c(0)
)

En este caso, las varibles son identificables como “nombres” (Camilo y Luciano), “fechas” y goles marcados. Los datos se encuentran en una sola líne sin una tabla clara.

Por otro lado, existen muchos errores posibles a la hora de ordenar una data, analizarla y extraer datos. Los errores más comunes dentro de este ejercicio pueden ser que: Los encabezados de las columnas son valores numéricos; pueden haber más de una variable por columna; las variables están organizadas tanto en filas como en columnas; más de un tipo de observación en una tabla o una misma unidad observacional está almacenada en múltiples tablas.

Es por eso que el paquete tidyr: tiene dos funciones claves para facilitar la tarea:

En el caso de tener una tabla con datos desordenados e ilegibles, debemos ocupar tidy para ordenarla. Para comenzar se deben alargar los datos y así reconocer las dos columnas que se agrupan key y value. Para hacer esto ocupamos la función gather.

Dato importante

Si queremos restar de las columnas alguna variable es se debe anteponer el signo menos (-) antes de la variable a eliminar.

Para ejemplificar usaremos el primer ejemplo de este archivo, en el cual destacaban las variables relacionadas con los partidos de fútbol jugados por Camilo y Luciano, datos que sólo se presentan de manera lineal, para ordenar utilizaremos la función gather.

tidyr::gather(data = Goles_por_partido,
              key = "Fecha_jugada",
              value = "goles_marcados")

También puede pasar que una columna presente dos variables diferentes, en este caso podemos utilizar la función de tidy “separate”. Lo que hace es recibir la información:

En general, el paquete tidy es una herramienta muy útil en la visualización de datos en RStudio, ordena los datos para hacerlos más legibles a través de distintos métodos y funciones, como por ejemplo Gather y Spread.

Goles_Por_Partido_tidy <- gather(data = Goles_por_partido,
       key = "Fecha_jugada",
       value = "goles_marcados") %>%
separate(Fecha_jugada, into = c("Nombre", "Fecha"), sep = "_")
gather(data = Goles_por_partido,
       key = "Fecha_jugada",
       value = "goles_marcados") %>%
separate(Fecha_jugada, into = c("Nombre", "Fecha"), sep = "_")

Es elemental en este proceso tener en cuenta identificar de la mejor manera las diferentes variables presentes en la tabla, no sólo a modo infirmativo, sino que también para saber cuáles de estas son necesarias para nuestro trabajo. Por otra parte, es necesario tener en cuenta 5 puntos que son claves para la visualización de datos con tidy:

Otra forma de ordenar una data ilegible o enredada es la clásica forma de aplica-combina, que consiste en romper un problema en pedazos, separar todas las variables y dejarlas como información parcelada, para luego unir de la mejor forma y así ordenar.

Para esto es necesario tener en cuenta 3 conceptos:

Finalmente, si hablamos de ordenar datos no podemos dejar fuera a “dplyr”, en él se encuentran varias funciones, como por ejemplo:

En la siguiente tabla buscaremos dar un ejemplo de una de las funciones de dplyr, en base a la tabla utilizada con los goles por jugador y fecha. En este caso, ejemplificaremos con la función Filter:

filter(Goles_Por_Partido_tidy, goles_marcados == "0")

En la tabla anterior, filtramos los datos para extraer la información que necesitamos, en este caso para sacar el número de veces que un jugador no anotó en alguna fecha, dando como resultado que el jugador “Luciano” no anotó en la fecha número 3.

A diferencia del paquete tidy, en este caso generalmente se trabaja con una data ordenada, que previamente ordenamos o que ya se encontraba legible y útil para nuestro trabajo. Sin embargo, estas funciones funcionan de manera similar, reciben de entrada un dataframe, los argumentos que siguen indican qué trabajo realizaremos y nos arroja la nueva información.

LS0tDQp0aXRsZTogIlJlc3VtZW4gdGlkeWRhdGEiDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQpgYGB7cn0NCmxpYnJhcnkoImdncGxvdDIiKQ0KbGlicmFyeSgiZHBseXIiKQ0KbGlicmFyeSgidGlkeXZlcnNlIikNCmxpYnJhcnkoInRpYmJsZSIpDQpgYGANCg0KYGBge3J9DQppbnN0YWxsLnBhY2thZ2VzKCJ0aWR5dmVyc2UiKQ0KYGBgDQoNCiMjI0ludHJvZHVjY2nzbiBhbCBhbuFsaXNpcyBkZSBkYXRvcy4gZW4gZWwgdGV4dG8gc2UgdHJhdGE6ICJSZWVzdHJ1Y3R1cmEgZGUgZGF0b3MgeSBlbCBwcmluY2lwaW8gZGUgbG9zIGRhdG9zIGxpbXBpb3MiIHkgIkVzdHJhdGVnaWEgZGl2aWRlLWFwbGljYS1jb21iaW5hIi4NCg0KDQoNCkxhIGxpbXBpZXphIHkgb3JkZW4gZGUgbG9zIGRhdG9zIGVzIGVsZW1lbnRhbCBwYXJhIGZhY2lsaXRhciBlbCB0cmFiYWpvIGRlIGFu4Wxpc2lzLCBlbiBlc3RlIHRleHRvIHNlIG11ZXN0cmFuIHTpY25pY2FzIHBhcmEgaGFjZXIgZGUgbGEgZGF0YSB1biBsdWdhciBt4XMgY29udmVuaWVudGUgZG9uZGUgdHJhYmFqYXIuDQoNCg0KDQpMYSBpZGVhIGVzIGxpbXBpYXIgbG9zIGRhdG9zIGRlIGxhIGluZm9ybWFjafNuIHF1ZSBubyBuZWNlc2l0YW1vcyB5IGFsbWFjZW5hcmxvcyBkZSB1bmEgbWFuZXJhIGNvbnNpc3RlbnRlIHF1ZSBub3MgcGVybWl0YSBlbmZvY2Fybm9zIGVuIHJlc3BvbmRlciBsYXMgZHVkYXMgYW50ZXMgZGUgZXN0YXIgbHVjaGFuZG8gcG9yIGRlc2NpZnJhcmxvcy4gQSBmaW4gZGUgY3VlbnRhcywgdW5hIGRhdGEgb3JkZW5hZGEgeSBsaW1waWEgbm9zIGF5dWRhIGEgdHJhYmFqYXIgZW4gbGE6IE1hbmlwdWxhY2nzbiwgdmlzdWFsaXphY2nzbiB5IG1vZGVsYWNp824gZGUgbG9zIGRhdG9zLg0KDQoNCg0KRW4gcmVzdW1lbjoNCg0KDQoNCi0gQ2FkYSB2YXJpYWJsZSBmb3JtYSB1bmEgY29sdW1uYQ0KDQoNCg0KLSBDYWRhIG9ic2VydmFjafNuIGZvcm1hIHVuIHJlbmds824NCg0KDQoNCi0gQ2FkYSB0aXBvIGRlIHVuaWRhZCBvYnNlcnZhY2lvbmFsIGZvcm1hIHVuYSB0YWJsYQ0KDQoNCg0KDQoNCkxvIGltcG9ydGFudGUgZGUgYXJtYXIgdW5hIHRhYmxhIG9yZGVuYWRhIGVzIGNvbWVuemFyIHBvciBpZGVudGlmaWNhciBsYXMgdmFyaWFibGVzLCBlbiBlbCBzaWd1aWVudGUgY2FzbywgbGFzIHZhcmlhYmxlIHNlcuEgbGFzIGFub3RhY2lvbmVzIGRlIENhbWlsbyB5IEx1Y2lhbm8gY29uIGxhIGNhbWlzZXRhIGRlIHN1IGNsdWIgdW5pdmVyc2l0YXJpbywgQ2x1YiBBdGzpdGljbyBDZW5pY2VybyAoKipDQUMqKikuDQoNCmNvbWVuemFyZW1vcyBwb3IgYXNpZ25hcmxlIG5vbWJyZSBhIGxhIGRhdGEsIGVuIGVzdGUgY2FzbyBsZSBwb25kcmVtb3MgKkdvbGVzX3Bvcl9wYXJ0aWRvKiwgc2llbmRvIGVsIHByaW1lciBkYXRvIGVsIG5vbWJyZSBkZWwganVnYWRvciwgc2VwYXJhZG8gcG9yIHVuIGd1afNuIGJham8gZWwgbvptZXJvIGNvcnJlc3BvbmRpZW50ZSBhIGxhIGZlY2hhOg0KDQpgYGB7cn0NCkdvbGVzX3Bvcl9wYXJ0aWRvIDwtIHRpYmJsZShjYW1pbG9fMSA9IGMoMiksDQogICAgICAgY2FtaWxvXzIgPSBjKDMpLA0KICAgICAgIGNhbWlsb18zID0gYygxKSwNCiAgICAgICBsdWNpYW5vXzEgPSBjKDEpLA0KICAgICAgIGx1Y2lhbm9fMiA9IGMoMyksDQogICAgICAgbHVjaWFub18zID0gYygwKQ0KICAgICAgICkNCmBgYA0KDQpBIGNvbnRpbnVhY2nzbiBsYSB0YWJsYToNCg0KYGBge3J9DQp0aWJibGUoY2FtaWxvXzEgPSBjKDIpLA0KICAgICAgIGNhbWlsb18yID0gYygzKSwNCiAgICAgICBjYW1pbG9fMyA9IGMoMSksDQogICAgICAgbHVjaWFub18xID0gYygxKSwNCiAgICAgICBsdWNpYW5vXzIgPSBjKDMpLA0KICAgICAgIGx1Y2lhbm9fMyA9IGMoMCkNCikNCmBgYA0KDQoNCkVuIGVzdGUgY2FzbywgbGFzIHZhcmlibGVzIHNvbiBpZGVudGlmaWNhYmxlcyBjb21vICJub21icmVzIiAoQ2FtaWxvIHkgTHVjaWFubyksICJmZWNoYXMiIHkgZ29sZXMgbWFyY2Fkb3MuIExvcyBkYXRvcyBzZSBlbmN1ZW50cmFuIGVuIHVuYSBzb2xhIGztbmUgc2luIHVuYSB0YWJsYSBjbGFyYS4NCg0KDQpQb3Igb3RybyBsYWRvLCBleGlzdGVuIG11Y2hvcyBlcnJvcmVzIHBvc2libGVzIGEgbGEgaG9yYSBkZSBvcmRlbmFyIHVuYSBkYXRhLCBhbmFsaXphcmxhIHkgZXh0cmFlciBkYXRvcy4gTG9zIGVycm9yZXMgbeFzIGNvbXVuZXMgZGVudHJvIGRlIGVzdGUgZWplcmNpY2lvIHB1ZWRlbiBzZXIgcXVlOiBMb3MgZW5jYWJlemFkb3MgZGUgbGFzIGNvbHVtbmFzIHNvbiB2YWxvcmVzIG51belyaWNvczsgcHVlZGVuIGhhYmVyIG3hcyBkZSB1bmEgdmFyaWFibGUgcG9yIGNvbHVtbmE7IGxhcyB2YXJpYWJsZXMgZXN04W4gb3JnYW5pemFkYXMgdGFudG8gZW4gZmlsYXMgY29tbyBlbiBjb2x1bW5hczsgbeFzIGRlIHVuIHRpcG8gZGUgb2JzZXJ2YWNp824gZW4gdW5hIHRhYmxhIG8gdW5hIG1pc21hIHVuaWRhZCBvYnNlcnZhY2lvbmFsIGVzdOEgYWxtYWNlbmFkYSBlbiBt+mx0aXBsZXMgdGFibGFzLg0KDQoNCg0KRXMgcG9yIGVzbyBxdWUgZWwgcGFxdWV0ZSAqdGlkeXI6KiB0aWVuZSBkb3MgZnVuY2lvbmVzIGNsYXZlcyBwYXJhIGZhY2lsaXRhciBsYSB0YXJlYToNCg0KDQoNCi0gKipHYXRoZXIqKjogSnVudGEgbGFzIGNvbHVtbmFzIGVuIHBhcmVzIGRlIHZhbG9yZXMgeSBub21icmVzLCBjb25jcmV0ZSBsb3MgZGF0b3MgYW5jaG9zIGVuIGxhcmdvcy4NCg0KDQoNCi0gKipTcHJlYWQqKjogU2VwYXJhIGRvcyBjb2x1bW5hcyBwYXJhIGhhY2VyIGxvcyBkYXRvcyBt4XMgYW5jaG9zLg0KDQoNCg0KDQoNCkVuIGVsIGNhc28gZGUgdGVuZXIgdW5hIHRhYmxhIGNvbiBkYXRvcyBkZXNvcmRlbmFkb3MgZSBpbGVnaWJsZXMsIGRlYmVtb3Mgb2N1cGFyIHRpZHkgcGFyYSBvcmRlbmFybGEuIFBhcmEgY29tZW56YXIgc2UgZGViZW4gYWxhcmdhciBsb3MgZGF0b3MgeSBhc+0gcmVjb25vY2VyIGxhcyBkb3MgY29sdW1uYXMgcXVlIHNlIGFncnVwYW4gKmtleSogeSAqdmFsdWUqLiBQYXJhIGhhY2VyIGVzdG8gb2N1cGFtb3MgbGEgZnVuY2nzbiAqZ2F0aGVyKi4NCg0KDQoNCi0gKipLZXkqKjogTm9tYnJlIGRlIGxhIG51ZXZhIHZhcmlhYmxlIHF1ZSBjb250aWVuZSBsbyBxdWUgZnVlcm9uIGxvcyBub21icmVzIGRlIGNvbHVtbmFzIHF1ZSBhcGlsYW1vcy4NCg0KDQoNCi0gKipWYWx1ZSoqOiBOb21icmUgZGUgbGEgdmFyaWFibGUgcXVlIGFsbWFjZW5hcuEgbG9zIHZhbG9yZXMgcXVlIGNvcnJlc3BvbmRlbiBhIGNhZGEgKmtleSouDQoNCg0KDQojIyNEYXRvIGltcG9ydGFudGUjIyMgDQoNCg0KDQpTaSBxdWVyZW1vcyByZXN0YXIgZGUgbGFzIGNvbHVtbmFzIGFsZ3VuYSB2YXJpYWJsZSBlcyBzZSBkZWJlIGFudGVwb25lciBlbCBzaWdubyBtZW5vcyAoLSkgYW50ZXMgZGUgbGEgdmFyaWFibGUgYSBlbGltaW5hci4NCg0KDQpQYXJhIGVqZW1wbGlmaWNhciB1c2FyZW1vcyBlbCBwcmltZXIgZWplbXBsbyBkZSBlc3RlIGFyY2hpdm8sIGVuIGVsIGN1YWwgZGVzdGFjYWJhbiBsYXMgdmFyaWFibGVzIHJlbGFjaW9uYWRhcyBjb24gbG9zIHBhcnRpZG9zIGRlIGb6dGJvbCBqdWdhZG9zIHBvciBDYW1pbG8geSBMdWNpYW5vLCBkYXRvcyBxdWUgc/NsbyBzZSBwcmVzZW50YW4gZGUgbWFuZXJhIGxpbmVhbCwgcGFyYSBvcmRlbmFyIHV0aWxpemFyZW1vcyBsYSBmdW5jafNuICpnYXRoZXIqLg0KDQpgYGB7cn0NCnRpZHlyOjpnYXRoZXIoZGF0YSA9IEdvbGVzX3Bvcl9wYXJ0aWRvLA0KICAgICAgICAgICAgICBrZXkgPSAiRmVjaGFfanVnYWRhIiwNCiAgICAgICAgICAgICAgdmFsdWUgPSAiZ29sZXNfbWFyY2Fkb3MiKQ0KYGBgDQoNCg0KDQpUYW1iaeluIHB1ZWRlIHBhc2FyIHF1ZSB1bmEgY29sdW1uYSBwcmVzZW50ZSBkb3MgdmFyaWFibGVzIGRpZmVyZW50ZXMsIGVuIGVzdGUgY2FzbyBwb2RlbW9zIHV0aWxpemFyIGxhIGZ1bmNp824gZGUgdGlkeSAic2VwYXJhdGUiLiBMbyBxdWUgaGFjZSBlcyByZWNpYmlyIGxhIGluZm9ybWFjafNuOg0KDQoNCg0KLSBOb21icmUgZGUgbGEgYmFzZSBkZSBkYXRvcy4NCg0KLSBFbCBub21icmUgZGUgbGEgdmFyaWFibGUgcXVlIGRlc2VhbW9zIHNlcGFyYXIgZW4gbeFzIGRlIHVuYS4NCg0KLSBMYSBwb3NpY2nzbiBkZSBkb25kZSBkZXNlYW1vcyAiY29ydGFyIi4gTGEgZnVuY2nzbiBlcyBzZXBhcmFyIHZhbG9yZXMgZW4gZGlzdGludG9zIHB1bnRvcyBkZSBsYSBjb2x1bW5hIHNpZW1wcmUgeSBjdWFuZG8gZXN0YSBubyB0ZW5nYSB1biB2YWxvciBhbGZhIG51belyaWNvLiAoZXNwYWNpbywgZ3Vp824sIHB1bnRvLCBldGMuKS4NCg0KDQoNCkVuIGdlbmVyYWwsIGVsIHBhcXVldGUgdGlkeSBlcyB1bmEgaGVycmFtaWVudGEgbXV5IPp0aWwgZW4gbGEgdmlzdWFsaXphY2nzbiBkZSBkYXRvcyBlbiBSU3R1ZGlvLCBvcmRlbmEgbG9zIGRhdG9zIHBhcmEgaGFjZXJsb3MgbeFzIGxlZ2libGVzIGEgdHJhdulzIGRlIGRpc3RpbnRvcyBt6XRvZG9zIHkgZnVuY2lvbmVzLCBjb21vIHBvciBlamVtcGxvICpHYXRoZXIqIHkgKlNwcmVhZCouIA0KDQoNCg0KYGBge3J9DQpHb2xlc19Qb3JfUGFydGlkb190aWR5IDwtIGdhdGhlcihkYXRhID0gR29sZXNfcG9yX3BhcnRpZG8sDQogICAgICAga2V5ID0gIkZlY2hhX2p1Z2FkYSIsDQogICAgICAgdmFsdWUgPSAiZ29sZXNfbWFyY2Fkb3MiKSAlPiUNCnNlcGFyYXRlKEZlY2hhX2p1Z2FkYSwgaW50byA9IGMoIk5vbWJyZSIsICJGZWNoYSIpLCBzZXAgPSAiXyIpDQpgYGANCg0KYGBge3J9DQpnYXRoZXIoZGF0YSA9IEdvbGVzX3Bvcl9wYXJ0aWRvLA0KICAgICAgIGtleSA9ICJGZWNoYV9qdWdhZGEiLA0KICAgICAgIHZhbHVlID0gImdvbGVzX21hcmNhZG9zIikgJT4lDQpzZXBhcmF0ZShGZWNoYV9qdWdhZGEsIGludG8gPSBjKCJOb21icmUiLCAiRmVjaGEiKSwgc2VwID0gIl8iKQ0KYGBgDQoNCg0KDQpFcyBlbGVtZW50YWwgZW4gZXN0ZSBwcm9jZXNvIHRlbmVyIGVuIGN1ZW50YSBpZGVudGlmaWNhciBkZSBsYSBtZWpvciBtYW5lcmEgbGFzIGRpZmVyZW50ZXMgdmFyaWFibGVzIHByZXNlbnRlcyBlbiBsYSB0YWJsYSwgbm8gc/NsbyBhIG1vZG8gaW5maXJtYXRpdm8sIHNpbm8gcXVlIHRhbWJp6W4gcGFyYSBzYWJlciBjdeFsZXMgZGUgZXN0YXMgc29uIG5lY2VzYXJpYXMgcGFyYSBudWVzdHJvIHRyYWJham8uIFBvciBvdHJhIHBhcnRlLCBlcyBuZWNlc2FyaW8gdGVuZXIgZW4gY3VlbnRhIDUgcHVudG9zIHF1ZSBzb24gY2xhdmVzIHBhcmEgbGEgdmlzdWFsaXphY2nzbiBkZSBkYXRvcyBjb24gdGlkeToNCg0KDQoNCi0gSW5jbHVpciB1biBlbmNhYmV6YWRvIGNvbiBlbCBub21icmUgZGUgbGFzIHZhcmlhYmxlcy4NCg0KLSBMb3Mgbm9tYnJlcyBkZSBsYXMgdmFyaWFibGVzIGRlYmVuIHNlciBlbnRlbmRpYmxlcy4gKFBlbmRlamV0ZXMgZXMgbWVqb3IgcXVlIFBvYkluZmFudGlsTWVub3JBMTgpLg0KDQotIEVuIGdlbmVyYWwgbG9zIGRhdG9zIHNlIGRlYmVuIGd1YXJkYXIgZW4gdW4gYXJjaGl2byBwb3IgdGFibGEuDQoNCi0gRXNjcmliaXIgdW4gc2NyaXB0IGNvbiBsYXMgbW9kaWZpY2FjaW9uZXMgcXVlIHNlIGhpY2llcm9uIGEgbG9zIGRhdG9zIGNydWRvcyAocmVwcm9kdWNpYmlsaWRhZCkuDQoNCi0gU2VsZWNjafNuIGRlIHZhcmlhYmxlcywgZGF0b3MgZmFsdGFudGVzLCB0aXBvcyB5IGRldGVjY2nzbiBkZSB2YWxvcmVzIGF07XBpY29zLg0KDQoNCg0KT3RyYSBmb3JtYSBkZSBvcmRlbmFyIHVuYSBkYXRhIGlsZWdpYmxlIG8gZW5yZWRhZGEgZXMgbGEgY2zhc2ljYSBmb3JtYSBkZSAqYXBsaWNhLWNvbWJpbmEqLCBxdWUgY29uc2lzdGUgZW4gcm9tcGVyIHVuIHByb2JsZW1hIGVuIHBlZGF6b3MsIHNlcGFyYXIgdG9kYXMgbGFzIHZhcmlhYmxlcyB5IGRlamFybGFzIGNvbW8gaW5mb3JtYWNp824gcGFyY2VsYWRhLCBwYXJhIGx1ZWdvIHVuaXIgZGUgbGEgbWVqb3IgZm9ybWEgeSBhc+0gb3JkZW5hci4NCg0KDQoNClBhcmEgZXN0byBlcyBuZWNlc2FyaW8gdGVuZXIgZW4gY3VlbnRhIDMgY29uY2VwdG9zOg0KDQoNCg0KLSAqKlNlcGFyYSoqIGxhIGJhc2UgZGUgZGF0b3Mgb3JpZ2luYWwuDQoNCi0gKipBcGxpY2EqKiBmdW5jaW9uZXMgYSBjYWRhIHN1YmNvbmp1bnRvLg0KDQotICoqQ29tYmluYSoqIGxvcyByZXN1bHRhZG9zIGVuIHVuYSBudWV2YSBiYXNlIGRlIGRhdG9zLg0KDQoNCg0KRmluYWxtZW50ZSwgc2kgaGFibGFtb3MgZGUgb3JkZW5hciBkYXRvcyBubyBwb2RlbW9zIGRlamFyIGZ1ZXJhIGEgImRwbHlyIiwgZW4g6Wwgc2UgZW5jdWVudHJhbiB2YXJpYXMgZnVuY2lvbmVzLCBjb21vIHBvciBlamVtcGxvOg0KDQoNCg0KLSAqKkZpbHRlcioqOiBQYXJhIG9idGVuZXIgdW4gc3ViY29uanVudG8gYSBlbGVjY2nzbi4NCg0KLSAqKlNlbGVjdCoqOiBTZWxlY2Npb25hIGNvbHVtbmFzIHNlZ/puIGVsIG5vbWJyZS4NCg0KLSAqKkFycmFuZ2UqKjogUmVvcmRlbmEgZmlsYXMuDQoNCi0gKipNdXRhdGUqKjogQWdyZWdhIG51ZXZhcyB2YXJpYWJsZXMuDQoNCi0gKipTdW1tYXJpc2UqKjogUmVkdWNlIHZhcmlhYmxlcyBhIHZhbG9yZXMgKHByb21lZGlvKS4NCg0KDQpFbiBsYSBzaWd1aWVudGUgdGFibGEgYnVzY2FyZW1vcyBkYXIgdW4gZWplbXBsbyBkZSB1bmEgZGUgbGFzIGZ1bmNpb25lcyBkZSAqZHBseXIqLCBlbiBiYXNlIGEgbGEgdGFibGEgdXRpbGl6YWRhIGNvbiBsb3MgZ29sZXMgcG9yIGp1Z2Fkb3IgeSBmZWNoYS4gRW4gZXN0ZSBjYXNvLCBlamVtcGxpZmljYXJlbW9zIGNvbiBsYSBmdW5jafNuICpGaWx0ZXIqOg0KDQpgYGB7cn0NCmZpbHRlcihHb2xlc19Qb3JfUGFydGlkb190aWR5LCBnb2xlc19tYXJjYWRvcyA9PSAiMCIpDQpgYGANCg0KRW4gbGEgdGFibGEgYW50ZXJpb3IsIGZpbHRyYW1vcyBsb3MgZGF0b3MgcGFyYSBleHRyYWVyIGxhIGluZm9ybWFjafNuIHF1ZSBuZWNlc2l0YW1vcywgZW4gZXN0ZSBjYXNvIHBhcmEgc2FjYXIgZWwgbvptZXJvIGRlIHZlY2VzIHF1ZSB1biBqdWdhZG9yIG5vIGFub3TzIGVuIGFsZ3VuYSBmZWNoYSwgZGFuZG8gY29tbyByZXN1bHRhZG8gcXVlIGVsIGp1Z2Fkb3IgIkx1Y2lhbm8iIG5vIGFub3TzIGVuIGxhIGZlY2hhIG76bWVybyAzLg0KDQpBIGRpZmVyZW5jaWEgZGVsIHBhcXVldGUgdGlkeSwgZW4gZXN0ZSBjYXNvIGdlbmVyYWxtZW50ZSBzZSB0cmFiYWphIGNvbiB1bmEgZGF0YSBvcmRlbmFkYSwgcXVlIHByZXZpYW1lbnRlIG9yZGVuYW1vcyBvIHF1ZSB5YSBzZSBlbmNvbnRyYWJhIGxlZ2libGUgeSD6dGlsIHBhcmEgbnVlc3RybyB0cmFiYWpvLiBTaW4gZW1iYXJnbywgZXN0YXMgZnVuY2lvbmVzIGZ1bmNpb25hbiBkZSBtYW5lcmEgc2ltaWxhciwgcmVjaWJlbiBkZSBlbnRyYWRhIHVuICpkYXRhZnJhbWUqLCBsb3MgYXJndW1lbnRvcyBxdWUgc2lndWVuIGluZGljYW4gcXXpIHRyYWJham8gcmVhbGl6YXJlbW9zIHkgbm9zIGFycm9qYSBsYSBudWV2YSBpbmZvcm1hY2nzbi4NCg0KDQo=