Maykol Linares

1. INTRODUCCIÓN

En este libro elaborado con el programa R-Studio es posible elaborar analisis estadisticos a traes de la lectura, filtro y edición de documentos que contengan información que lo recquieran. En este trabajo se realizara el respectivo analisis de un documento excel (*.xls) suministrado por la Unidad de Planeación Rural Agropecuaria (UPRA), como parte de su programa Evaluaciónes Agropecuarias Municipales (EVA), por parte del gobierno de Colombia.

2. Arreglos

Para empezar es necesario contar con las librerias necesarias para hacer uso de las funciones necesarias. La primera libreria que se instalara será “tidyverse”, después “readxl” y al final se cargara esta ultima libreria. Una vez realizado este comando en un chunk, se les asignara a cada una (excepto a la carga de la libreria “readxl”) un comentario “#”, para que despues de realizar el comando estas no se vuelvan a ejecutar.

#install.packages('tidyverse')
#install.packages('readxl')
library(tidyverse)
library(readxl)

3. Leyendo el archivo excel con las estadisticas agropecuarias municipales

Para comenzar con el analisis en el archivo se encuentran mas que cifras agricolas, en este también hay estadisticas del ambito pecuario, su separación se realizara en futuros pasos.

El comando list.files nos permite obtener un listado de los archivos que cumplan con cierta caracteristica o extensión.

(archivos = list.files(pattern = 'xls'))
[1] "UPRA_EVA.xlsx"
(hojas = readxl::excel_sheets("UPRA_EVA.xlsx"))
[1] "Agrícola_SIPRA_AGRONET"       "InventarioBovino"             "InventarioPorcino"           
[4] "InvBufalosCaprinoOvinoEquino" "InvAves"                     

Seleccionamos la hoja que nos muestra el sector agricola (las demas hojas son pecuarias):

eva2020 = readxl::read_excel("UPRA_EVA.xlsx", sheet = "Agrícola_SIPRA_AGRONET")

y obtenemos los siguiente:

eva2020

4. Seleccionar de entre la tabla el departamento de interes

Filtramos de toda la lista el departamento de interes, en este caso es el Cauca:

(cauca2020 = dplyr::filter(eva2020, Departamento == "Cauca"))

5.“Limpiar” los datos filtrados

Ahora proseguimos con la seleccion de las columnas de interes, note que otras columnas como el codigo del mucipio o nombre cientifico del cultivo no nos son relevantes para el estudio que vamos a realizar.

(cauca2020.tmp <-  cauca2020 %>% select('Código del Municipio':'Ciclo del cultivo'))

Vamos a “limpiar” en el archivo excel los nombres, si se fija, los nombres con espacios y tildes son problematicos, los softwares de programación suelen tener problemas con esto. Ahora corregimos los nombres de las columnas:

cauca2020.tmp %>% rename(Cod_Mun = 'Código del Municipio', 
                         Grupo = 'Grupo cultivo según especie', 
                         Subgrupo = 'Subgrupo cultivo según especie',
                         AreaSiembra = 'Area Sembrada (ha)',
                         AreaCosecha = 'Area Cosechada (ha)',
                         Produccion = 'Producción (t)',                              
                         Rendimiento = 'Rendimiento (t/ha)', Ciclo='Ciclo del cultivo') ->                                  ncauca2020

Obtenemos:

ncauca2020

Otro problema… los datos mostrados en la tabla se encuentran como caracteres, es decir, las columnas en las que se trabajan datos numericos son vistos como algun tipo de letra, esto significa que no podremos realizar operaciones entre ellas. Lo corregimos de esta manera:

(ncauca2020 %>% mutate(AreaSiembra = as.numeric(AreaSiembra),
                       AreaCosecha = as.numeric(AreaCosecha),
                       Produccion = as.numeric(Produccion),
                       Rendimiento = as.numeric(Rendimiento)) -> ncauca2020 )

6. Procesamiento y analisis de los datos

Comencemos por ver los cultivos cuya producción sea mayor a cero y los organizaremos de mayor a menor:

ncauca2020 %>%
  filter(Produccion > 0) %>%
  group_by(Cultivo) %>%
  summarize(total_produccion = sum(Produccion)) %>% 
  arrange(desc(total_produccion))

Fijemonos que los principales cultivos son la caña azucarera, la yuca y la papa.

Ahora podemos fijarnos en los municipios con la maxima producción de un determinado cultivo, es decir, que es lo que más se produce en el municipio a analizar:

ncauca2020 %>%
  group_by(Cultivo, Municipio) %>%
  summarize(max_prod = max(Produccion, na.rm = TRUE)) %>%
  slice(which.max(max_prod))  %>%
  arrange(desc(max_prod))
`summarise()` has grouped output by 'Cultivo'. You can override using the `.groups` argument.

Ahora vemos que el principal cultivo del departamento de Cauca (Caña azucarera) se encuentra producida en mayor cantidad en el municipio de Miranda, probablemente la economia en ese lugar sea mejor.

Debido a que los cultivos cambian constantemente a lo largo de los años es importante conocer el grupo de cultivos en el area de estudio. A pesar de que el agricultor cambie de cultivo, no le sera tan facil cambiar de grupo, debido a que el grupo al que pertenece la planta tiene una serie de caracteristicas que les permiten ser cultivadas en areas especiales, esto puede ser la altura, temperatura, presipitaciones, etc…

ncauca2020 %>%
  group_by(Grupo,Municipio) %>%
  summarize(max_prod = max(Produccion, na.rm = TRUE)) %>%
  slice(which.max(max_prod))  %>%
  arrange(desc(max_prod))
`summarise()` has grouped output by 'Grupo'. You can override using the `.groups` argument.

En el municipio de Miranda se encuentran los Cultivos Tropicales Tradicionales, es decir, alli no solo se ve la caña azucarera, sino también la caña panelera.

Tomemos los grupos de cultivos mas importantes y guardemolos en un comando para despues exportarlos a archivos csv de manera que puedan ser leidos desde cualquier otro software:

ncauca2020 %>%
  group_by(Cod_Mun, Municipio, Grupo) %>%
  filter(Grupo=='Cultivos Tropicales Tradicionales') %>% 
  summarize(max_prod = max(Produccion, na.rm = TRUE)) %>%
  arrange(desc(max_prod)) -> caucaTropicales2020
`summarise()` has grouped output by 'Cod_Mun', 'Municipio'. You can override using the `.groups` argument.
caucaTropicales2020
ncauca2020 %>%
  group_by(Cod_Mun, Municipio, Grupo) %>%
  filter(Grupo=='Tubérculos Y Plátanos') %>% 
  summarize(max_prod = max(Produccion, na.rm = TRUE)) %>%
  arrange(desc(max_prod)) -> caucaTuberculos2020
`summarise()` has grouped output by 'Cod_Mun', 'Municipio'. You can override using the `.groups` argument.
caucaTuberculos2020
(ncauca2020 %>%
  group_by(Cod_Mun, Municipio, Grupo) %>%
  filter(Grupo=='Plátanos') %>% 
  summarize(max_prod = max(Produccion, na.rm = TRUE)) %>%
  arrange(desc(max_prod)) -> caucaPlatanos2020)
`summarise()` has grouped output by 'Cod_Mun', 'Municipio'. You can override using the `.groups` argument.

7. Guardando los comandos a archivos csv

Con el comando “write_csv” guardamos los comandos a archivos:

write_csv(caucaPlatanos2020, "./cauca_platanos_2020.csv")
write_csv(caucaTuberculos2020, "./cauca_tuberculos_2020.csv")
write_csv(caucaTropicales2020, "./cauca_tropicales_2020.csv")

8. Información de la secion utilizada en el programa

sessionInfo()
R version 3.6.1 (2019-07-05)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 17763)

Matrix products: default

locale:
[1] LC_COLLATE=Spanish_Colombia.1252  LC_CTYPE=Spanish_Colombia.1252    LC_MONETARY=Spanish_Colombia.1252
[4] LC_NUMERIC=C                      LC_TIME=Spanish_Colombia.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
 [1] readxl_1.3.1    forcats_0.5.1   stringr_1.4.0   dplyr_1.0.6     purrr_0.3.4     readr_1.4.0     tidyr_1.1.3    
 [8] tibble_3.1.1    ggplot2_3.3.5   tidyverse_1.3.1

loaded via a namespace (and not attached):
 [1] tidyselect_1.1.1 xfun_0.10        haven_2.4.1      colorspace_1.4-1 vctrs_0.3.8      generics_0.0.2   htmltools_0.3.6 
 [8] yaml_2.2.0       base64enc_0.1-3  utf8_1.1.4       rlang_0.4.11     pillar_1.7.0     glue_1.4.2       withr_2.5.0     
[15] DBI_1.0.0        dbplyr_2.1.1     modelr_0.1.8     lifecycle_1.0.1  munsell_0.5.0    gtable_0.3.0     cellranger_1.1.0
[22] rvest_1.0.2      evaluate_0.14    knitr_1.25       fansi_0.4.0      broom_0.7.12     Rcpp_1.0.2       backports_1.1.4 
[29] scales_1.0.0     jsonlite_1.7.2   fs_1.3.1         hms_1.1.1        digest_0.6.21    stringi_1.4.3    grid_3.6.1      
[36] cli_2.5.0        tools_3.6.1      magrittr_2.0.1   crayon_1.5.0     pkgconfig_2.0.3  ellipsis_0.3.2   xml2_1.3.2      
[43] reprex_2.0.1     lubridate_1.7.10 rstudioapi_0.13  assertthat_0.2.1 rmarkdown_1.16   httr_1.4.2       R6_2.4.0        
[50] compiler_3.6.1  
LS0tDQp0aXRsZTogIkFOQUxJU0lTIEVTVEFESVNUSUNPIERFIExBIEFHUklDVUxUVVJBIEVOIENPTE9NQklBLCBBw5FPIDIwMjAgIg0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCjxoMT4gTWF5a29sIExpbmFyZXMgPC9oMT4NCiMjIDEuIElOVFJPRFVDQ0nDk04gDQpFbiBlc3RlIGxpYnJvIGVsYWJvcmFkbyBjb24gZWwgcHJvZ3JhbWEgUi1TdHVkaW8gZXMgcG9zaWJsZSBlbGFib3JhciBhbmFsaXNpcyBlc3RhZGlzdGljb3MgYSB0cmFlcyBkZSBsYSBsZWN0dXJhLCBmaWx0cm8geSBlZGljacOzbiBkZSBkb2N1bWVudG9zIHF1ZSBjb250ZW5nYW4gaW5mb3JtYWNpw7NuIHF1ZSBsbyByZWNxdWllcmFuLiBFbiBlc3RlIHRyYWJham8gc2UgcmVhbGl6YXJhIGVsIHJlc3BlY3Rpdm8gYW5hbGlzaXMgZGUgdW4gZG9jdW1lbnRvIGV4Y2VsICgqLnhscykgc3VtaW5pc3RyYWRvIHBvciBsYSBVbmlkYWQgZGUgUGxhbmVhY2nDs24gUnVyYWwgQWdyb3BlY3VhcmlhIChVUFJBKSwgY29tbyBwYXJ0ZSBkZSBzdSBwcm9ncmFtYSBFdmFsdWFjacOzbmVzIEFncm9wZWN1YXJpYXMgTXVuaWNpcGFsZXMgKEVWQSksIHBvciBwYXJ0ZSBkZWwgZ29iaWVybm8gZGUgQ29sb21iaWEuIA0KDQojIyAyLiBBcnJlZ2xvcw0KDQpQYXJhIGVtcGV6YXIgZXMgbmVjZXNhcmlvIGNvbnRhciBjb24gbGFzIGxpYnJlcmlhcyBuZWNlc2FyaWFzIHBhcmEgaGFjZXIgdXNvIGRlIGxhcyBmdW5jaW9uZXMgbmVjZXNhcmlhcy4gTGEgcHJpbWVyYSBsaWJyZXJpYSBxdWUgc2UgaW5zdGFsYXJhIHNlcsOhICJ0aWR5dmVyc2UiLCBkZXNwdcOpcyAicmVhZHhsIiB5IGFsIGZpbmFsIHNlIGNhcmdhcmEgZXN0YSB1bHRpbWEgbGlicmVyaWEuIFVuYSB2ZXogcmVhbGl6YWRvIGVzdGUgY29tYW5kbyBlbiB1biBjaHVuaywgc2UgbGVzIGFzaWduYXJhIGEgY2FkYSB1bmEgKGV4Y2VwdG8gYSBsYSBjYXJnYSBkZSBsYSBsaWJyZXJpYSAicmVhZHhsIikgdW4gY29tZW50YXJpbyAiIyIsIHBhcmEgcXVlIGRlc3B1ZXMgZGUgcmVhbGl6YXIgZWwgY29tYW5kbyBlc3RhcyBubyBzZSB2dWVsdmFuIGEgZWplY3V0YXIuDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0V9DQojaW5zdGFsbC5wYWNrYWdlcygndGlkeXZlcnNlJykNCiNpbnN0YWxsLnBhY2thZ2VzKCdyZWFkeGwnKQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KHJlYWR4bCkNCmBgYA0KDQoNCg0KIyMgMy4gTGV5ZW5kbyBlbCBhcmNoaXZvIGV4Y2VsIGNvbiBsYXMgZXN0YWRpc3RpY2FzIGFncm9wZWN1YXJpYXMgbXVuaWNpcGFsZXMNCg0KUGFyYSBjb21lbnphciBjb24gZWwgYW5hbGlzaXMgZW4gZWwgYXJjaGl2byBzZSBlbmN1ZW50cmFuIG1hcyBxdWUgY2lmcmFzIGFncmljb2xhcywgZW4gZXN0ZSB0YW1iacOpbiBoYXkgZXN0YWRpc3RpY2FzIGRlbCBhbWJpdG8gcGVjdWFyaW8sIHN1IHNlcGFyYWNpw7NuIHNlIHJlYWxpemFyYSBlbiBmdXR1cm9zIHBhc29zLiANCg0KRWwgY29tYW5kbyBsaXN0LmZpbGVzIG5vcyBwZXJtaXRlIG9idGVuZXIgdW4gbGlzdGFkbyBkZSBsb3MgYXJjaGl2b3MgcXVlIGN1bXBsYW4gY29uIGNpZXJ0YSBjYXJhY3RlcmlzdGljYSBvIGV4dGVuc2nDs24uDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0V9DQooYXJjaGl2b3MgPSBsaXN0LmZpbGVzKHBhdHRlcm4gPSAneGxzJykpDQpgYGANCg0KYGBge3J9DQooaG9qYXMgPSByZWFkeGw6OmV4Y2VsX3NoZWV0cygiVVBSQV9FVkEueGxzeCIpKQ0KYGBgDQoNClNlbGVjY2lvbmFtb3MgbGEgaG9qYSBxdWUgbm9zIG11ZXN0cmEgZWwgc2VjdG9yIGFncmljb2xhIChsYXMgZGVtYXMgaG9qYXMgc29uIHBlY3Vhcmlhcyk6DQoNCmBgYHtyfQ0KZXZhMjAyMCA9IHJlYWR4bDo6cmVhZF9leGNlbCgiVVBSQV9FVkEueGxzeCIsIHNoZWV0ID0gIkFncsOtY29sYV9TSVBSQV9BR1JPTkVUIikNCmBgYA0KDQp5IG9idGVuZW1vcyBsb3Mgc2lndWllbnRlOg0KDQpgYGB7cn0NCmV2YTIwMjANCmBgYA0KDQoNCiMjIDQuIFNlbGVjY2lvbmFyIGRlIGVudHJlIGxhIHRhYmxhIGVsIGRlcGFydGFtZW50byBkZSBpbnRlcmVzDQoNCkZpbHRyYW1vcyBkZSB0b2RhIGxhIGxpc3RhIGVsIGRlcGFydGFtZW50byBkZSBpbnRlcmVzLCBlbiBlc3RlIGNhc28gZXMgZWwgQ2F1Y2E6DQoNCmBgYHtyfQ0KKGNhdWNhMjAyMCA9IGRwbHlyOjpmaWx0ZXIoZXZhMjAyMCwgRGVwYXJ0YW1lbnRvID09ICJDYXVjYSIpKQ0KYGBgDQoNCg0KDQojIyA1LiJMaW1waWFyIiBsb3MgZGF0b3MgZmlsdHJhZG9zDQoNCkFob3JhIHByb3NlZ3VpbW9zIGNvbiBsYSBzZWxlY2Npb24gZGUgbGFzIGNvbHVtbmFzIGRlIGludGVyZXMsIG5vdGUgcXVlIG90cmFzIGNvbHVtbmFzIGNvbW8gZWwgY29kaWdvIGRlbCBtdWNpcGlvIG8gbm9tYnJlIGNpZW50aWZpY28gZGVsIGN1bHRpdm8gbm8gbm9zIHNvbiByZWxldmFudGVzIHBhcmEgZWwgZXN0dWRpbyBxdWUgdmFtb3MgYSByZWFsaXphci4NCg0KYGBge3J9DQooY2F1Y2EyMDIwLnRtcCA8LSAgY2F1Y2EyMDIwICU+JSBzZWxlY3QoJ0PDs2RpZ28gZGVsIE11bmljaXBpbyc6J0NpY2xvIGRlbCBjdWx0aXZvJykpDQpgYGANCg0KIFZhbW9zIGEgImxpbXBpYXIiIGVuIGVsIGFyY2hpdm8gZXhjZWwgbG9zIG5vbWJyZXMsIHNpIHNlIGZpamEsIGxvcyBub21icmVzIGNvbiBlc3BhY2lvcyB5IHRpbGRlcyBzb24gcHJvYmxlbWF0aWNvcywgbG9zIHNvZnR3YXJlcyBkZSBwcm9ncmFtYWNpw7NuIHN1ZWxlbiB0ZW5lciBwcm9ibGVtYXMgY29uIGVzdG8uIEFob3JhIGNvcnJlZ2ltb3MgbG9zIG5vbWJyZXMgZGUgbGFzIGNvbHVtbmFzOg0KDQpgYGB7cn0NCmNhdWNhMjAyMC50bXAgJT4lIHJlbmFtZShDb2RfTXVuID0gJ0PDs2RpZ28gZGVsIE11bmljaXBpbycsIA0KICAgICAgICAgICAgICAgICAgICAgICAgIEdydXBvID0gJ0dydXBvIGN1bHRpdm8gc2Vnw7puIGVzcGVjaWUnLCANCiAgICAgICAgICAgICAgICAgICAgICAgICBTdWJncnVwbyA9ICdTdWJncnVwbyBjdWx0aXZvIHNlZ8O6biBlc3BlY2llJywNCiAgICAgICAgICAgICAgICAgICAgICAgICBBcmVhU2llbWJyYSA9ICdBcmVhIFNlbWJyYWRhIChoYSknLA0KICAgICAgICAgICAgICAgICAgICAgICAgIEFyZWFDb3NlY2hhID0gJ0FyZWEgQ29zZWNoYWRhIChoYSknLA0KICAgICAgICAgICAgICAgICAgICAgICAgIFByb2R1Y2Npb24gPSAnUHJvZHVjY2nDs24gKHQpJywgICAgICAgICAgICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgICAgICBSZW5kaW1pZW50byA9ICdSZW5kaW1pZW50byAodC9oYSknLCBDaWNsbz0nQ2ljbG8gZGVsIGN1bHRpdm8nKSAtPiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuY2F1Y2EyMDIwDQpgYGANCg0KT2J0ZW5lbW9zOg0KDQpgYGB7cn0NCm5jYXVjYTIwMjANCmBgYA0KDQpPdHJvIHByb2JsZW1hLi4uIGxvcyBkYXRvcyBtb3N0cmFkb3MgZW4gbGEgdGFibGEgc2UgZW5jdWVudHJhbiBjb21vIGNhcmFjdGVyZXMsIGVzIGRlY2lyLCBsYXMgY29sdW1uYXMgZW4gbGFzIHF1ZSBzZSB0cmFiYWphbiBkYXRvcyBudW1lcmljb3Mgc29uIHZpc3RvcyBjb21vIGFsZ3VuIHRpcG8gZGUgbGV0cmEsIGVzdG8gc2lnbmlmaWNhIHF1ZSBubyBwb2RyZW1vcyByZWFsaXphciBvcGVyYWNpb25lcyBlbnRyZSBlbGxhcy4gTG8gY29ycmVnaW1vcyBkZSBlc3RhIG1hbmVyYToNCg0KYGBge3IgbWVzc2FnZT1GQUxTRX0NCihuY2F1Y2EyMDIwICU+JSBtdXRhdGUoQXJlYVNpZW1icmEgPSBhcy5udW1lcmljKEFyZWFTaWVtYnJhKSwNCiAgICAgICAgICAgICAgICAgICAgICAgQXJlYUNvc2VjaGEgPSBhcy5udW1lcmljKEFyZWFDb3NlY2hhKSwNCiAgICAgICAgICAgICAgICAgICAgICAgUHJvZHVjY2lvbiA9IGFzLm51bWVyaWMoUHJvZHVjY2lvbiksDQogICAgICAgICAgICAgICAgICAgICAgIFJlbmRpbWllbnRvID0gYXMubnVtZXJpYyhSZW5kaW1pZW50bykpIC0+IG5jYXVjYTIwMjAgKQ0KYGBgDQoNCg0KDQojIyA2LiBQcm9jZXNhbWllbnRvIHkgYW5hbGlzaXMgZGUgbG9zIGRhdG9zDQoNCkNvbWVuY2Vtb3MgcG9yIHZlciBsb3MgY3VsdGl2b3MgY3V5YSBwcm9kdWNjacOzbiBzZWEgbWF5b3IgYSBjZXJvIHkgbG9zIG9yZ2FuaXphcmVtb3MgZGUgbWF5b3IgYSBtZW5vcjoNCg0KYGBge3J9DQpuY2F1Y2EyMDIwICU+JQ0KICBmaWx0ZXIoUHJvZHVjY2lvbiA+IDApICU+JQ0KICBncm91cF9ieShDdWx0aXZvKSAlPiUNCiAgc3VtbWFyaXplKHRvdGFsX3Byb2R1Y2Npb24gPSBzdW0oUHJvZHVjY2lvbikpICU+JSANCiAgYXJyYW5nZShkZXNjKHRvdGFsX3Byb2R1Y2Npb24pKQ0KYGBgDQpGaWplbW9ub3MgcXVlIGxvcyBwcmluY2lwYWxlcyBjdWx0aXZvcyBzb24gbGEgY2HDsWEgYXp1Y2FyZXJhLCBsYSB5dWNhIHkgbGEgcGFwYS4NCg0KQWhvcmEgcG9kZW1vcyBmaWphcm5vcyBlbiBsb3MgbXVuaWNpcGlvcyBjb24gbGEgbWF4aW1hIHByb2R1Y2Npw7NuIGRlIHVuIGRldGVybWluYWRvIGN1bHRpdm8sIGVzIGRlY2lyLCBxdWUgZXMgbG8gcXVlIG3DoXMgc2UgcHJvZHVjZSBlbiBlbCBtdW5pY2lwaW8gYSBhbmFsaXphcjoNCg0KYGBge3J9DQpuY2F1Y2EyMDIwICU+JQ0KICBncm91cF9ieShDdWx0aXZvLCBNdW5pY2lwaW8pICU+JQ0KICBzdW1tYXJpemUobWF4X3Byb2QgPSBtYXgoUHJvZHVjY2lvbiwgbmEucm0gPSBUUlVFKSkgJT4lDQogIHNsaWNlKHdoaWNoLm1heChtYXhfcHJvZCkpICAlPiUNCiAgYXJyYW5nZShkZXNjKG1heF9wcm9kKSkNCmBgYA0KQWhvcmEgdmVtb3MgcXVlIGVsIHByaW5jaXBhbCBjdWx0aXZvIGRlbCBkZXBhcnRhbWVudG8gZGUgQ2F1Y2EgKENhw7FhIGF6dWNhcmVyYSkgc2UgZW5jdWVudHJhIHByb2R1Y2lkYSBlbiBtYXlvciBjYW50aWRhZCBlbiBlbCBtdW5pY2lwaW8gZGUgTWlyYW5kYSwgcHJvYmFibGVtZW50ZSBsYSBlY29ub21pYSBlbiBlc2UgbHVnYXIgc2VhIG1lam9yLg0KDQpEZWJpZG8gYSBxdWUgbG9zIGN1bHRpdm9zIGNhbWJpYW4gY29uc3RhbnRlbWVudGUgYSBsbyBsYXJnbyBkZSBsb3MgYcOxb3MgZXMgaW1wb3J0YW50ZSBjb25vY2VyIGVsIGdydXBvIGRlIGN1bHRpdm9zIGVuIGVsIGFyZWEgZGUgZXN0dWRpby4gQSBwZXNhciBkZSBxdWUgZWwgYWdyaWN1bHRvciBjYW1iaWUgZGUgY3VsdGl2bywgbm8gbGUgc2VyYSB0YW4gZmFjaWwgY2FtYmlhciBkZSBncnVwbywgZGViaWRvIGEgcXVlIGVsIGdydXBvIGFsIHF1ZSBwZXJ0ZW5lY2UgbGEgcGxhbnRhIHRpZW5lIHVuYSBzZXJpZSBkZSBjYXJhY3RlcmlzdGljYXMgcXVlIGxlcyBwZXJtaXRlbiBzZXIgY3VsdGl2YWRhcyBlbiBhcmVhcyBlc3BlY2lhbGVzLCBlc3RvIHB1ZWRlIHNlciBsYSBhbHR1cmEsIHRlbXBlcmF0dXJhLCBwcmVzaXBpdGFjaW9uZXMsIGV0Yy4uLg0KDQpgYGB7cn0NCm5jYXVjYTIwMjAgJT4lDQogIGdyb3VwX2J5KEdydXBvLE11bmljaXBpbykgJT4lDQogIHN1bW1hcml6ZShtYXhfcHJvZCA9IG1heChQcm9kdWNjaW9uLCBuYS5ybSA9IFRSVUUpKSAlPiUNCiAgc2xpY2Uod2hpY2gubWF4KG1heF9wcm9kKSkgICU+JQ0KICBhcnJhbmdlKGRlc2MobWF4X3Byb2QpKQ0KYGBgDQoNCkVuIGVsIG11bmljaXBpbyBkZSBNaXJhbmRhIHNlIGVuY3VlbnRyYW4gbG9zIEN1bHRpdm9zIFRyb3BpY2FsZXMgVHJhZGljaW9uYWxlcywgZXMgZGVjaXIsIGFsbGkgbm8gc29sbyBzZSB2ZSBsYSBjYcOxYSBhenVjYXJlcmEsIHNpbm8gdGFtYmnDqW4gbGEgY2HDsWEgcGFuZWxlcmEuDQoNClRvbWVtb3MgbG9zIGdydXBvcyBkZSBjdWx0aXZvcyBtYXMgaW1wb3J0YW50ZXMgeSBndWFyZGVtb2xvcyBlbiB1biBjb21hbmRvIHBhcmEgZGVzcHVlcyBleHBvcnRhcmxvcyBhIGFyY2hpdm9zIGNzdiBkZSBtYW5lcmEgcXVlIHB1ZWRhbiBzZXIgbGVpZG9zIGRlc2RlIGN1YWxxdWllciBvdHJvIHNvZnR3YXJlOg0KDQpgYGB7cn0NCm5jYXVjYTIwMjAgJT4lDQogIGdyb3VwX2J5KENvZF9NdW4sIE11bmljaXBpbywgR3J1cG8pICU+JQ0KICBmaWx0ZXIoR3J1cG89PSdDdWx0aXZvcyBUcm9waWNhbGVzIFRyYWRpY2lvbmFsZXMnKSAlPiUgDQogIHN1bW1hcml6ZShtYXhfcHJvZCA9IG1heChQcm9kdWNjaW9uLCBuYS5ybSA9IFRSVUUpKSAlPiUNCiAgYXJyYW5nZShkZXNjKG1heF9wcm9kKSkgLT4gY2F1Y2FUcm9waWNhbGVzMjAyMA0KYGBgDQoNCmBgYHtyfQ0KY2F1Y2FUcm9waWNhbGVzMjAyMA0KYGBgDQoNCmBgYHtyfQ0KbmNhdWNhMjAyMCAlPiUNCiAgZ3JvdXBfYnkoQ29kX011biwgTXVuaWNpcGlvLCBHcnVwbykgJT4lDQogIGZpbHRlcihHcnVwbz09J1R1YsOpcmN1bG9zIFkgUGzDoXRhbm9zJykgJT4lIA0KICBzdW1tYXJpemUobWF4X3Byb2QgPSBtYXgoUHJvZHVjY2lvbiwgbmEucm0gPSBUUlVFKSkgJT4lDQogIGFycmFuZ2UoZGVzYyhtYXhfcHJvZCkpIC0+IGNhdWNhVHViZXJjdWxvczIwMjANCmBgYA0KDQpgYGB7cn0NCmNhdWNhVHViZXJjdWxvczIwMjANCmBgYA0KDQpgYGB7cn0NCihuY2F1Y2EyMDIwICU+JQ0KICBncm91cF9ieShDb2RfTXVuLCBNdW5pY2lwaW8sIEdydXBvKSAlPiUNCiAgZmlsdGVyKEdydXBvPT0nUGzDoXRhbm9zJykgJT4lIA0KICBzdW1tYXJpemUobWF4X3Byb2QgPSBtYXgoUHJvZHVjY2lvbiwgbmEucm0gPSBUUlVFKSkgJT4lDQogIGFycmFuZ2UoZGVzYyhtYXhfcHJvZCkpIC0+IGNhdWNhUGxhdGFub3MyMDIwKQ0KYGBgDQoNCiMjIDcuIEd1YXJkYW5kbyBsb3MgY29tYW5kb3MgYSBhcmNoaXZvcyBjc3YNCg0KQ29uIGVsIGNvbWFuZG8gIndyaXRlX2NzdiIgZ3VhcmRhbW9zIGxvcyBjb21hbmRvcyBhIGFyY2hpdm9zOg0KDQpgYGB7cn0NCndyaXRlX2NzdihjYXVjYVBsYXRhbm9zMjAyMCwgIi4vY2F1Y2FfcGxhdGFub3NfMjAyMC5jc3YiKQ0Kd3JpdGVfY3N2KGNhdWNhVHViZXJjdWxvczIwMjAsICIuL2NhdWNhX3R1YmVyY3Vsb3NfMjAyMC5jc3YiKQ0Kd3JpdGVfY3N2KGNhdWNhVHJvcGljYWxlczIwMjAsICIuL2NhdWNhX3Ryb3BpY2FsZXNfMjAyMC5jc3YiKQ0KYGBgDQoNCiMjIDguIEluZm9ybWFjacOzbiBkZSBsYSBzZWNpb24gdXRpbGl6YWRhIGVuIGVsIHByb2dyYW1hDQoNCmBgYHtyfQ0Kc2Vzc2lvbkluZm8oKQ0KYGBgDQoNCg0KDQoNCg0KDQo=