1. Introducción

En este cuaderno utilizaremos como fuente de datos la Evaluaciones Agropecuarias Municipales - EVA (2007-2018), un conjunto de datos proporcionado por el Ministerio de Agricultura y Desarrollo Rural para ilustrar algunos datos estadísticos relacionados al cultivo de yuca en el municipio de Turbo del departamento de Antioquia.

Para esto, también vamos a utilizar las principales funcionalidades de la biblioteca dplyr. Las cuales son:

Todas éstas funciones se combinan de forma natural con group_by, que permite realizar cualquier operación “por grupo”.

2. Configuración

Primero se deben instalar las librerías requeridas:

3. Descargar el conjunto de datos EVA para el departamento seleccionado (Antioquia)

Ir al siguiente enlace: https://www.datos.gov.co/Agricultura-y-Desarrollo-Rural/Evaluaciones-Agropecuarias-Municipales-EVA/2pnw-mmge/data

En el sitio web filtrar y descargar los datos del departamento. Buscar el archivo en el equipo y moverlo al directorio en donde se encuentra el trabajo en proceso.

4. Leer el conjunto de datos EVA

list.files()
[1] "EVA.nb.html"       "EVA.Rmd"           "EVA_Antioquia.csv"
(eva = read.csv("./EVA_Antioquia.csv"))

En la tabla se pueden observar datos estadísticos de diferentes años, cultivos, municipios, entre otros más específicos.

Ahora vamos a revisar los nombres que le da el propio software a las diferentes características allí expuestas.

names(eva)
 [1] "CÓD...DEP."                                   
 [2] "DEPARTAMENTO"                                 
 [3] "CÓD..MUN."                                    
 [4] "MUNICIPIO"                                    
 [5] "GRUPO..DE.CULTIVO"                            
 [6] "SUBGRUPO..DE.CULTIVO"                         
 [7] "CULTIVO"                                      
 [8] "DESAGREGACIÓN.REGIONAL.Y.O.SISTEMA.PRODUCTIVO"
 [9] "AÑO"                                          
[10] "PERIODO"                                      
[11] "Área.Sembrada..ha."                           
[12] "Área.Cosechada..ha."                          
[13] "Producción..t."                               
[14] "Rendimiento..t.ha."                           
[15] "ESTADO.FISICO.PRODUCCION"                     
[16] "NOMBRE..CIENTIFICO"                           
[17] "CICLO.DE.CULTIVO"                             

5. Limpiar los datos EVA

Vamos a seleccionar aquellos atributos de nuestro interés:

(eva %>% dplyr::select("CÓD..MUN.":"ESTADO.FISICO.PRODUCCION") -> eva.tmp)
eva.tmp

Ahora comprobamos la salida del objeto y verificamos que se hayan seleccionado los objetos de nuestro interés.

A continuación vamos a cambiar los nombres de algunas de las columnas, teniendo en cuenta usar los nombres que están en el objeto eva.tmp:

(eva.tmp %>%  dplyr::rename("Cod_Mun" = "CÓD..MUN.", 
                         "Grupo" = "GRUPO..DE.CULTIVO",
                         "Municipio" = "MUNICIPIO",
                         "Subgrupo" = "SUBGRUPO..DE.CULTIVO",
                         "Cultivo" = "CULTIVO",
                         "Year" = "AÑO",
                         "Periodo" = "PERIODO",
                         "Area_Sembrada" = "Área.Sembrada..ha.",
                         "Area_Cosechada" = "Área.Cosechada..ha.",
                         "Produccion" = "Producción..t.",                                                                "Rendimiento" = "Rendimiento..t.ha.",   
                         "Sistema" = "DESAGREGACIÓN.REGIONAL.Y.O.SISTEMA.PRODUCTIVO",
                         "Estado" = "ESTADO.FISICO.PRODUCCION")) -> new_eva
new_eva

Ahora, comprobamos que la tabla anterior tenga los atributos cuantitativos como tipos de datos numéricos (no como tipos de datos de cadena).

6. Análisis de datos

Los análisis de datos pueden utilizarse de manera: dividir-aplicar-combinar, así, dividir los datos en grupos, aplicar algún análisis a cada grupo y combinar los resultados.

De esta manera, como ya fueron mencionadas las funciones de la biblioteca dplyr, vamos a ponerlas en acción.

6.1 Los cultivos más importantes en el periodo de 2007-2018

  • Si queremos conocer la producción total por grupo de cultivos
new_eva %>%
  ##filter(Produccion > 0) %>%
  group_by(Grupo) %>%
  summarize(Total_produccion = sum(Produccion)) %>% 
  arrange(desc(Total_produccion)) 

Ya con estos datos obtenidos podemos observar que los frutales son el cultivo de mayor producción en el departamento seguido por los tubérculos y los plátanos. Por otro lado, los de menor producción en este periodo (2007-2018) fueron las plantas aromáticas, condimentarias y medicinales.

Para guardar la producción total en un objeto:

new_eva %>%
  group_by(Grupo) %>%
  summarize(Total_produccion = sum(Produccion)) -> PT 

Para filtrar las producciones más importantes:

PT %>% 
  filter(Total_produccion > 1000000) -> main.groups

Para conocer la producción total de los principales grupos de cultivos:

(value = sum(main.groups$Total_produccion))
[1] 36312945

Para añadir un nuevo atributo con el porcentaje de la producción total:

main.groups$percent = main.groups$Total_produccion/value

Para crear un gráfico circular de la producción total de main.groups:

  • #barplot
bp<- ggplot(main.groups, aes(x="", y=percent, fill=Grupo))+
geom_bar(width = 1, stat = "identity")
  • #Piechart
pie <- bp + coord_polar("y", start=0)
pie

6.2 El municipio y cultivo con mayor producción en el periodo de 2007-2018

  • Producción de cada grupo de cultivos: municipios que lideran la producción en cada uno de los cultivos del departamento.
new_eva %>%
  group_by(Grupo, Municipio) %>%
  summarize(Total_Prod = sum(Produccion, na.rm = TRUE)) %>%
  slice(which.max(Total_Prod))  %>%
  arrange(desc(Total_Prod))
`summarise()` has grouped output by 'Grupo'. You can override using the `.groups` argument.

Para guardar el objeto:

new_eva %>%
  group_by(Grupo, Municipio) %>%
  summarize(Total_Prod = sum(Produccion, na.rm = TRUE)) %>%
  slice(which.max(Total_Prod))  -> leaders
`summarise()` has grouped output by 'Grupo'. You can override using the `.groups` argument.
leaders

Aquí vamos a filtrar los municipios más importantes desde el punto de vista agrícola:

leaders %>% 
  filter(Total_Prod > 100000) -> main.leaders

Vamos a trazar los líderes filtrados:

p<-ggplot(data=main.leaders, aes(x=Municipio, y=Total_Prod)) +
  geom_bar(stat="identity")
p

6.3 Dinámica de un cultivo importante entre 2007 y 2018

new_eva %>% 
  filter(Municipio=="TURBO" & CULTIVO=="YUCA") %>% 
  group_by(Year, Cultivo) %>%
  select(Municipio, Cultivo, Produccion, Year) ->  Turbo_Yuca

Comprobamos:

Turbo_Yuca

En seguida haremos un gráfico de la producción de yuca en el municipio de Turbo durante todo el periodo cubierto por el conjunto de datos EVA:

g <- ggplot(aes(x=Year, y=Produccion/1000), data = Turbo_Yuca) + geom_bar(stat='identity') + labs(y='Produccion de Yuca [Ton x 1000]')

Añadimos un título y visualizamos:

g + ggtitle("Producción de yuca en el municipio de Turbo en el periodo de 2007-2018") + labs(caption= "Basado en datos de EVA  (Minagricultura, 2023)")

6.4 Área sembrada y cosechada de yuca en Turbo (2007 y 2018)

new_eva %>% 
  filter(Municipio=="TURBO" & Cultivo=="YUCA") %>% 
  group_by(Year, Cultivo) %>%
  select(Municipio, Cultivo, Area_Sembrada, Area_Cosechada, Year) ->  Turbo_Yuca_SemyCos
Turbo_Yuca_SemyCos

7. Datos adicionales de los cultivos producidos en Turbo

Por último, se muestran algunos datos de relevancia en el municipio de Turbo Antioquia como lo son los cultivos producidos allí y aquellos de mayor y menor producción.

7.1 Cultivos producidos en el municipio de Turbo (Antioquia)

new_eva %>% 
  filter(Municipio=="TURBO") %>% 
  group_by(Cultivo) %>%
  select(Municipio, Cultivo, Produccion, Rendimiento) ->  Turbo_Cultivos
Turbo_Cultivos

7.2 Cultivos de mayor y menor producción en el municipio de Turbo (Antioquia)

p<-ggplot(data=main.leaders, aes(x=Cultivo, y=Total_Prod)) +
  geom_bar(stat="identity")
new_eva %>%
  group_by(Cultivo) %>%
  summarize(Total_Prod = sum(Produccion, na.rm = TRUE)) %>%
  slice(which.max(Total_Prod))  -> Cultivo_Max
Cultivo_Max
new_eva %>%
  group_by(Cultivo) %>%
  summarize(Total_Prod = sum(Produccion, na.rm = TRUE)) %>%
  slice(which.min(Total_Prod))  -> Cultivo_Min
Cultivo_Min

8. BIBLIOGRAFÍA

sessionInfo()
R version 4.3.1 (2023-06-16 ucrt)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 19045)

Matrix products: default


locale:
[1] LC_COLLATE=Spanish_Colombia.utf8  LC_CTYPE=Spanish_Colombia.utf8   
[3] LC_MONETARY=Spanish_Colombia.utf8 LC_NUMERIC=C                     
[5] LC_TIME=Spanish_Colombia.utf8    

time zone: America/Bogota
tzcode source: internal

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

other attached packages:
 [1] readxl_1.4.3    lubridate_1.9.2 forcats_1.0.0   stringr_1.5.0   dplyr_1.1.3    
 [6] purrr_1.0.2     readr_2.1.4     tidyr_1.3.0     tibble_3.2.1    ggplot2_3.4.3  
[11] tidyverse_2.0.0

loaded via a namespace (and not attached):
 [1] sass_0.4.7        utf8_1.2.3        generics_0.1.3    stringi_1.7.12   
 [5] hms_1.1.3         digest_0.6.33     magrittr_2.0.3    evaluate_0.21    
 [9] grid_4.3.1        timechange_0.2.0  fastmap_1.1.1     cellranger_1.1.0 
[13] jsonlite_1.8.7    fansi_1.0.4       scales_1.2.1      jquerylib_0.1.4  
[17] cli_3.6.1         crayon_1.5.2      rlang_1.1.1       bit64_4.0.5      
[21] munsell_0.5.0     withr_2.5.0       cachem_1.0.8      yaml_2.3.7       
[25] parallel_4.3.1    tools_4.3.1       tzdb_0.4.0        colorspace_2.1-0 
[29] vctrs_0.6.3       R6_2.5.1          lifecycle_1.0.3   bit_4.0.5        
[33] vroom_1.6.3       pkgconfig_2.0.3   pillar_1.9.0      bslib_0.5.1      
[37] gtable_0.3.4      glue_1.6.2        xfun_0.40         tidyselect_1.2.0 
[41] rstudioapi_0.15.0 knitr_1.44        farver_2.1.1      htmltools_0.5.6  
[45] labeling_0.4.3    rmarkdown_2.25    compiler_4.3.1   
LS0tDQp0aXRsZTogIlByb2R1Y2Npw7NuIGRlbCBjdWx0aXZvIGRlIHl1Y2EgZW4gZWwgbXVuaWNpcGlvIGRlIFR1cmJvLUFudGlvcXVpYSINCmF1dGhvcjogIk5hdGFsaWEgQWxmb25zbyBNYXJ0w61uZXoiDQpkYXRlOiAiMTkvMDkvMjAyMyINCm91dHB1dDoNCiAgaHRtbF9ub3RlYm9vazogZGVmYXVsdA0KICBodG1sX2RvY3VtZW50Og0KICAgIGRmX3ByaW50OiBwYWdlZA0KICBwZGZfZG9jdW1lbnQ6IGRlZmF1bHQNCi0tLQ0KDQojIyAxLiBJbnRyb2R1Y2Npw7NuIA0KDQpFbiBlc3RlIGN1YWRlcm5vIHV0aWxpemFyZW1vcyBjb21vIGZ1ZW50ZSBkZSBkYXRvcyBsYSBFdmFsdWFjaW9uZXMgQWdyb3BlY3VhcmlhcyBNdW5pY2lwYWxlcyAtIEVWQSAoMjAwNy0yMDE4KSwgdW4gY29uanVudG8gZGUgZGF0b3MgcHJvcG9yY2lvbmFkbyBwb3IgZWwgTWluaXN0ZXJpbyBkZSBBZ3JpY3VsdHVyYSB5IERlc2Fycm9sbG8gUnVyYWwgcGFyYSBpbHVzdHJhciBhbGd1bm9zIGRhdG9zIGVzdGFkw61zdGljb3MgcmVsYWNpb25hZG9zIGFsIGN1bHRpdm8gZGUgeXVjYSBlbiBlbCBtdW5pY2lwaW8gZGUgVHVyYm8gZGVsIGRlcGFydGFtZW50byBkZSBBbnRpb3F1aWEuDQoNClBhcmEgZXN0bywgdGFtYmnDqW4gdmFtb3MgYSB1dGlsaXphciBsYXMgcHJpbmNpcGFsZXMgZnVuY2lvbmFsaWRhZGVzIGRlIGxhIGJpYmxpb3RlY2EgZHBseXIuIExhcyBjdWFsZXMgc29uOg0KDQotIG11dGF0ZTogYcOxYWRlIG51ZXZhcyB2YXJpYWJsZXMgcXVlIHNvbiBmdW5jaW9uZXMgZGUgdmFyaWFibGVzIGV4aXN0ZW50ZXMuDQotIHNlbGVjdDogc2VsZWNjaW9uYSB2YXJpYWJsZXMgYmFzw6FuZG9zZSBlbiBzdXMgbm9tYnJlcy4NCi0gZmlsdGVyOiBzZWxlY2Npb25hIGNhc29zIGJhc8OhbmRvc2UgZW4gc3VzIHZhbG9yZXMuDQotIHN1bW1hcmlzZTogY3JlZHVjZSBtw7psdGlwbGVzIHZhbG9yZXMgYSB1biDDum5pY28gcmVzdW1lbi4NCi0gYXJyYW5nZTogY2FtYmlhIGVsIG9yZGVuIGRlIGxhcyBmaWxhcy4NCg0KVG9kYXMgw6lzdGFzIGZ1bmNpb25lcyBzZSBjb21iaW5hbiBkZSBmb3JtYSBuYXR1cmFsIGNvbiBncm91cF9ieSwgcXVlIHBlcm1pdGUgcmVhbGl6YXIgY3VhbHF1aWVyIG9wZXJhY2nDs24gInBvciBncnVwbyIuDQoNCg0KIyMgMi4gQ29uZmlndXJhY2nDs24NCg0KUHJpbWVybyBzZSBkZWJlbiBpbnN0YWxhciBsYXMgbGlicmVyw61hcyByZXF1ZXJpZGFzOg0KDQotIGluc3RhbGwucGFja2FnZXMgKCJ0aWR5dmVyc2UiKQ0KLSBpbnN0YWxsLnBhY2thZ2VzICgicmVhZHhsIikNCi0gaW5zdGFsbC5wYWNrYWdlcyAoImRwbHlyIikNCi0gaW5zdGFsbC5wYWNrYWdlcyAoImdncGxvdDIiKQ0KDQpgYGB7cn0NCmxpYnJhcnkodGlkeXZlcnNlKQ0KYGBgDQpgYGB7cn0NCmxpYnJhcnkoZHBseXIpDQpgYGANCmBgYHtyfQ0KbGlicmFyeShyZWFkcikNCmBgYA0KYGBge3J9DQpsaWJyYXJ5KHJlYWR4bCkNCmBgYA0KYGBge3J9DQpsaWJyYXJ5KGdncGxvdDIpDQpgYGANCg0KDQojIyAzLiBEZXNjYXJnYXIgZWwgY29uanVudG8gZGUgZGF0b3MgRVZBIHBhcmEgZWwgZGVwYXJ0YW1lbnRvIHNlbGVjY2lvbmFkbyAoQW50aW9xdWlhKQ0KDQpJciBhbCBzaWd1aWVudGUgZW5sYWNlOiBodHRwczovL3d3dy5kYXRvcy5nb3YuY28vQWdyaWN1bHR1cmEteS1EZXNhcnJvbGxvLVJ1cmFsL0V2YWx1YWNpb25lcy1BZ3JvcGVjdWFyaWFzLU11bmljaXBhbGVzLUVWQS8ycG53LW1tZ2UvZGF0YQ0KDQpFbiBlbCBzaXRpbyB3ZWIgZmlsdHJhciB5IGRlc2NhcmdhciBsb3MgZGF0b3MgZGVsIGRlcGFydGFtZW50by4gQnVzY2FyIGVsIGFyY2hpdm8gZW4gZWwgZXF1aXBvIHkgbW92ZXJsbyBhbCBkaXJlY3RvcmlvIGVuIGRvbmRlIHNlIGVuY3VlbnRyYSBlbCB0cmFiYWpvIGVuIHByb2Nlc28uDQoNCg0KIyMgNC4gTGVlciBlbCBjb25qdW50byBkZSBkYXRvcyBFVkEgDQoNCmBgYHtyfQ0KbGlzdC5maWxlcygpDQpgYGANCmBgYHtyfQ0KKGV2YSA9IHJlYWQuY3N2KCIuL0VWQV9BbnRpb3F1aWEuY3N2IikpDQpgYGANCg0KRW4gbGEgdGFibGEgc2UgcHVlZGVuIG9ic2VydmFyIGRhdG9zIGVzdGFkw61zdGljb3MgZGUgZGlmZXJlbnRlcyBhw7FvcywgY3VsdGl2b3MsIG11bmljaXBpb3MsIGVudHJlIG90cm9zIG3DoXMgZXNwZWPDrWZpY29zLg0KDQpBaG9yYSB2YW1vcyBhIHJldmlzYXIgbG9zIG5vbWJyZXMgcXVlIGxlIGRhIGVsIHByb3BpbyBzb2Z0d2FyZSBhIGxhcyBkaWZlcmVudGVzIGNhcmFjdGVyw61zdGljYXMgYWxsw60gZXhwdWVzdGFzLg0KDQpgYGB7cn0NCm5hbWVzKGV2YSkNCmBgYA0KDQojIyA1LiBMaW1waWFyIGxvcyBkYXRvcyBFVkENCg0KVmFtb3MgYSBzZWxlY2Npb25hciBhcXVlbGxvcyBhdHJpYnV0b3MgZGUgbnVlc3RybyBpbnRlcsOpczoNCg0KYGBge3J9DQooZXZhICU+JSBkcGx5cjo6c2VsZWN0KCJDw5NELi5NVU4uIjoiRVNUQURPLkZJU0lDTy5QUk9EVUNDSU9OIikgLT4gZXZhLnRtcCkNCmBgYA0KYGBge3J9DQpldmEudG1wDQpgYGANCg0KQWhvcmEgY29tcHJvYmFtb3MgbGEgc2FsaWRhIGRlbCBvYmpldG8geSB2ZXJpZmljYW1vcyBxdWUgc2UgaGF5YW4gc2VsZWNjaW9uYWRvIGxvcyBvYmpldG9zIGRlIG51ZXN0cm8gaW50ZXLDqXMuDQoNCkEgY29udGludWFjacOzbiB2YW1vcyBhIGNhbWJpYXIgbG9zIG5vbWJyZXMgZGUgYWxndW5hcyBkZSBsYXMgY29sdW1uYXMsIHRlbmllbmRvIGVuIGN1ZW50YSB1c2FyIGxvcyBub21icmVzIHF1ZSBlc3TDoW4gZW4gZWwgb2JqZXRvIGV2YS50bXA6DQoNCmBgYHtyfQ0KKGV2YS50bXAgJT4lICBkcGx5cjo6cmVuYW1lKCJDb2RfTXVuIiA9ICJDw5NELi5NVU4uIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIkdydXBvIiA9ICJHUlVQTy4uREUuQ1VMVElWTyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgIk11bmljaXBpbyIgPSAiTVVOSUNJUElPIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAiU3ViZ3J1cG8iID0gIlNVQkdSVVBPLi5ERS5DVUxUSVZPIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAiQ3VsdGl2byIgPSAiQ1VMVElWTyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgIlllYXIiID0gIkHDkU8iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICJQZXJpb2RvIiA9ICJQRVJJT0RPIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAiQXJlYV9TZW1icmFkYSIgPSAiw4FyZWEuU2VtYnJhZGEuLmhhLiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgIkFyZWFfQ29zZWNoYWRhIiA9ICLDgXJlYS5Db3NlY2hhZGEuLmhhLiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgIlByb2R1Y2Npb24iID0gIlByb2R1Y2Npw7NuLi50LiIsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJSZW5kaW1pZW50byIgPSAiUmVuZGltaWVudG8uLnQuaGEuIiwgICANCiAgICAgICAgICAgICAgICAgICAgICAgICAiU2lzdGVtYSIgPSAiREVTQUdSRUdBQ0nDk04uUkVHSU9OQUwuWS5PLlNJU1RFTUEuUFJPRFVDVElWTyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgIkVzdGFkbyIgPSAiRVNUQURPLkZJU0lDTy5QUk9EVUNDSU9OIikpIC0+IG5ld19ldmENCmBgYA0KDQpgYGB7cn0NCm5ld19ldmENCmBgYA0KQWhvcmEsIGNvbXByb2JhbW9zIHF1ZSBsYSB0YWJsYSBhbnRlcmlvciB0ZW5nYSBsb3MgYXRyaWJ1dG9zIGN1YW50aXRhdGl2b3MgY29tbyB0aXBvcyBkZSBkYXRvcyBudW3DqXJpY29zIChubyBjb21vIHRpcG9zIGRlIGRhdG9zIGRlIGNhZGVuYSkuDQoNCg0KIyMgNi4gQW7DoWxpc2lzIGRlIGRhdG9zDQoNCkxvcyBhbsOhbGlzaXMgZGUgZGF0b3MgcHVlZGVuIHV0aWxpemFyc2UgZGUgbWFuZXJhOiBkaXZpZGlyLWFwbGljYXItY29tYmluYXIsIGFzw60sIGRpdmlkaXIgbG9zIGRhdG9zIGVuIGdydXBvcywgYXBsaWNhciBhbGfDum4gYW7DoWxpc2lzIGEgY2FkYSBncnVwbyB5IGNvbWJpbmFyIGxvcyByZXN1bHRhZG9zLg0KDQpEZSBlc3RhIG1hbmVyYSwgY29tbyB5YSBmdWVyb24gbWVuY2lvbmFkYXMgbGFzIGZ1bmNpb25lcyBkZSBsYSBiaWJsaW90ZWNhIGRwbHlyLCB2YW1vcyBhIHBvbmVybGFzIGVuIGFjY2nDs24uDQoNCiMjIyA2LjEgTG9zIGN1bHRpdm9zIG3DoXMgaW1wb3J0YW50ZXMgZW4gZWwgcGVyaW9kbyBkZSAyMDA3LTIwMTgNCg0KLSBTaSBxdWVyZW1vcyBjb25vY2VyIGxhIHByb2R1Y2Npw7NuIHRvdGFsIHBvciBncnVwbyBkZSBjdWx0aXZvcw0KDQpgYGB7cn0NCm5ld19ldmEgJT4lDQogICMjZmlsdGVyKFByb2R1Y2Npb24gPiAwKSAlPiUNCiAgZ3JvdXBfYnkoR3J1cG8pICU+JQ0KICBzdW1tYXJpemUoVG90YWxfcHJvZHVjY2lvbiA9IHN1bShQcm9kdWNjaW9uKSkgJT4lIA0KICBhcnJhbmdlKGRlc2MoVG90YWxfcHJvZHVjY2lvbikpIA0KYGBgDQoNCllhIGNvbiBlc3RvcyBkYXRvcyBvYnRlbmlkb3MgcG9kZW1vcyBvYnNlcnZhciBxdWUgbG9zIGZydXRhbGVzIHNvbiBlbCBjdWx0aXZvIGRlIG1heW9yIHByb2R1Y2Npw7NuIGVuIGVsIGRlcGFydGFtZW50byBzZWd1aWRvIHBvciBsb3MgdHViw6lyY3Vsb3MgeSBsb3MgcGzDoXRhbm9zLiBQb3Igb3RybyBsYWRvLCBsb3MgZGUgbWVub3IgcHJvZHVjY2nDs24gZW4gZXN0ZSBwZXJpb2RvICgyMDA3LTIwMTgpIGZ1ZXJvbiBsYXMgcGxhbnRhcyBhcm9tw6F0aWNhcywgY29uZGltZW50YXJpYXMgeSBtZWRpY2luYWxlcy4NCg0KUGFyYSBndWFyZGFyIGxhIHByb2R1Y2Npw7NuIHRvdGFsIGVuIHVuIG9iamV0bzoNCg0KYGBge3J9DQpuZXdfZXZhICU+JQ0KICBncm91cF9ieShHcnVwbykgJT4lDQogIHN1bW1hcml6ZShUb3RhbF9wcm9kdWNjaW9uID0gc3VtKFByb2R1Y2Npb24pKSAtPiBQVCANCmBgYA0KDQpQYXJhIGZpbHRyYXIgbGFzIHByb2R1Y2Npb25lcyBtw6FzIGltcG9ydGFudGVzOg0KDQpgYGB7cn0NClBUICU+JSANCiAgZmlsdGVyKFRvdGFsX3Byb2R1Y2Npb24gPiAxMDAwMDAwKSAtPiBtYWluLmdyb3Vwcw0KYGBgDQoNClBhcmEgY29ub2NlciBsYSBwcm9kdWNjacOzbiB0b3RhbCBkZSBsb3MgcHJpbmNpcGFsZXMgZ3J1cG9zIGRlIGN1bHRpdm9zOg0KDQpgYGB7cn0NCih2YWx1ZSA9IHN1bShtYWluLmdyb3VwcyRUb3RhbF9wcm9kdWNjaW9uKSkNCmBgYA0KUGFyYSBhw7FhZGlyIHVuIG51ZXZvIGF0cmlidXRvIGNvbiBlbCBwb3JjZW50YWplIGRlIGxhIHByb2R1Y2Npw7NuIHRvdGFsOg0KDQpgYGB7cn0NCm1haW4uZ3JvdXBzJHBlcmNlbnQgPSBtYWluLmdyb3VwcyRUb3RhbF9wcm9kdWNjaW9uL3ZhbHVlDQpgYGANCg0KUGFyYSBjcmVhciB1biBncsOhZmljbyBjaXJjdWxhciBkZSBsYSBwcm9kdWNjacOzbiB0b3RhbCBkZSBtYWluLmdyb3VwczoNCg0KLSAqI2JhcnBsb3QqDQpgYGB7cn0NCmJwPC0gZ2dwbG90KG1haW4uZ3JvdXBzLCBhZXMoeD0iIiwgeT1wZXJjZW50LCBmaWxsPUdydXBvKSkrDQpnZW9tX2Jhcih3aWR0aCA9IDEsIHN0YXQgPSAiaWRlbnRpdHkiKQ0KYGBgDQoNCi0gKiNQaWVjaGFydCoNCmBgYHtyfQ0KcGllIDwtIGJwICsgY29vcmRfcG9sYXIoInkiLCBzdGFydD0wKQ0KcGllDQpgYGANCg0KIyMjIDYuMiBFbCBtdW5pY2lwaW8geSBjdWx0aXZvIGNvbiBtYXlvciBwcm9kdWNjacOzbiBlbiBlbCBwZXJpb2RvIGRlIDIwMDctMjAxOA0KDQotIFByb2R1Y2Npw7NuIGRlIGNhZGEgZ3J1cG8gZGUgY3VsdGl2b3M6IG11bmljaXBpb3MgcXVlIGxpZGVyYW4gbGEgcHJvZHVjY2nDs24gZW4gY2FkYSB1bm8gZGUgbG9zIGN1bHRpdm9zIGRlbCBkZXBhcnRhbWVudG8uDQoNCmBgYHtyfQ0KbmV3X2V2YSAlPiUNCiAgZ3JvdXBfYnkoR3J1cG8sIE11bmljaXBpbykgJT4lDQogIHN1bW1hcml6ZShUb3RhbF9Qcm9kID0gc3VtKFByb2R1Y2Npb24sIG5hLnJtID0gVFJVRSkpICU+JQ0KICBzbGljZSh3aGljaC5tYXgoVG90YWxfUHJvZCkpICAlPiUNCiAgYXJyYW5nZShkZXNjKFRvdGFsX1Byb2QpKQ0KYGBgDQpQYXJhIGd1YXJkYXIgZWwgb2JqZXRvOg0KDQpgYGB7cn0NCm5ld19ldmEgJT4lDQogIGdyb3VwX2J5KEdydXBvLCBNdW5pY2lwaW8pICU+JQ0KICBzdW1tYXJpemUoVG90YWxfUHJvZCA9IHN1bShQcm9kdWNjaW9uLCBuYS5ybSA9IFRSVUUpKSAlPiUNCiAgc2xpY2Uod2hpY2gubWF4KFRvdGFsX1Byb2QpKSAgLT4gbGVhZGVycw0KYGBgDQpgYGB7cn0NCmxlYWRlcnMNCmBgYA0KDQpBcXXDrSB2YW1vcyBhIGZpbHRyYXIgbG9zIG11bmljaXBpb3MgbcOhcyBpbXBvcnRhbnRlcyBkZXNkZSBlbCBwdW50byBkZSB2aXN0YSBhZ3LDrWNvbGE6DQoNCmBgYHtyfQ0KbGVhZGVycyAlPiUgDQogIGZpbHRlcihUb3RhbF9Qcm9kID4gMTAwMDAwKSAtPiBtYWluLmxlYWRlcnMNCmBgYA0KDQpWYW1vcyBhIHRyYXphciBsb3MgbMOtZGVyZXMgZmlsdHJhZG9zOg0KDQpgYGB7cn0NCnA8LWdncGxvdChkYXRhPW1haW4ubGVhZGVycywgYWVzKHg9TXVuaWNpcGlvLCB5PVRvdGFsX1Byb2QpKSArDQogIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IikNCnANCmBgYA0KDQojIyMgNi4zIERpbsOhbWljYSBkZSB1biBjdWx0aXZvIGltcG9ydGFudGUgZW50cmUgMjAwNyB5IDIwMTgNCg0KYGBge3J9DQpuZXdfZXZhICU+JSANCiAgZmlsdGVyKE11bmljaXBpbz09IlRVUkJPIiAmIENVTFRJVk89PSJZVUNBIikgJT4lIA0KICBncm91cF9ieShZZWFyLCBDdWx0aXZvKSAlPiUNCiAgc2VsZWN0KE11bmljaXBpbywgQ3VsdGl2bywgUHJvZHVjY2lvbiwgWWVhcikgLT4gIFR1cmJvX1l1Y2ENCmBgYA0KDQpDb21wcm9iYW1vczoNCg0KYGBge3J9DQpUdXJib19ZdWNhDQpgYGANCg0KRW4gc2VndWlkYSBoYXJlbW9zIHVuIGdyw6FmaWNvIGRlIGxhIHByb2R1Y2Npw7NuIGRlIHl1Y2EgZW4gZWwgbXVuaWNpcGlvIGRlIFR1cmJvIGR1cmFudGUgdG9kbyBlbCBwZXJpb2RvIGN1YmllcnRvIHBvciBlbCBjb25qdW50byBkZSBkYXRvcyBFVkE6DQoNCmBgYHtyfQ0KZyA8LSBnZ3Bsb3QoYWVzKHg9WWVhciwgeT1Qcm9kdWNjaW9uLzEwMDApLCBkYXRhID0gVHVyYm9fWXVjYSkgKyBnZW9tX2JhcihzdGF0PSdpZGVudGl0eScpICsgbGFicyh5PSdQcm9kdWNjaW9uIGRlIFl1Y2EgW1RvbiB4IDEwMDBdJykNCmBgYA0KDQpBw7FhZGltb3MgdW4gdMOtdHVsbyB5IHZpc3VhbGl6YW1vczoNCg0KYGBge3J9DQpnICsgZ2d0aXRsZSgiUHJvZHVjY2nDs24gZGUgeXVjYSBlbiBlbCBtdW5pY2lwaW8gZGUgVHVyYm8gZW4gZWwgcGVyaW9kbyBkZSAyMDA3LTIwMTgiKSArIGxhYnMoY2FwdGlvbj0gIkJhc2FkbyBlbiBkYXRvcyBkZSBFVkEgIChNaW5hZ3JpY3VsdHVyYSwgMjAyMykiKQ0KYGBgDQojIyMgNi40IMOBcmVhIHNlbWJyYWRhIHkgY29zZWNoYWRhIGRlIHl1Y2EgZW4gVHVyYm8gKDIwMDcgeSAyMDE4KQ0KDQpgYGB7cn0NCm5ld19ldmEgJT4lIA0KICBmaWx0ZXIoTXVuaWNpcGlvPT0iVFVSQk8iICYgQ3VsdGl2bz09IllVQ0EiKSAlPiUgDQogIGdyb3VwX2J5KFllYXIsIEN1bHRpdm8pICU+JQ0KICBzZWxlY3QoTXVuaWNpcGlvLCBDdWx0aXZvLCBBcmVhX1NlbWJyYWRhLCBBcmVhX0Nvc2VjaGFkYSwgWWVhcikgLT4gIFR1cmJvX1l1Y2FfU2VteUNvcw0KYGBgDQoNCmBgYHtyfQ0KVHVyYm9fWXVjYV9TZW15Q29zDQpgYGANCg0KDQojIyA3LiBEYXRvcyBhZGljaW9uYWxlcyBkZSBsb3MgY3VsdGl2b3MgcHJvZHVjaWRvcyBlbiBUdXJibw0KDQpQb3Igw7psdGltbywgc2UgbXVlc3RyYW4gYWxndW5vcyBkYXRvcyBkZSByZWxldmFuY2lhIGVuIGVsIG11bmljaXBpbyBkZSBUdXJibyBBbnRpb3F1aWEgY29tbyBsbyBzb24gbG9zIGN1bHRpdm9zIHByb2R1Y2lkb3MgYWxsw60geSBhcXVlbGxvcyBkZSBtYXlvciB5IG1lbm9yIHByb2R1Y2Npw7NuLg0KDQojIyMgNy4xIEN1bHRpdm9zIHByb2R1Y2lkb3MgZW4gZWwgbXVuaWNpcGlvIGRlIFR1cmJvIChBbnRpb3F1aWEpDQoNCmBgYHtyfQ0KbmV3X2V2YSAlPiUgDQogIGZpbHRlcihNdW5pY2lwaW89PSJUVVJCTyIpICU+JSANCiAgZ3JvdXBfYnkoQ3VsdGl2bykgJT4lDQogIHNlbGVjdChNdW5pY2lwaW8sIEN1bHRpdm8sIFByb2R1Y2Npb24sIFJlbmRpbWllbnRvKSAtPiAgVHVyYm9fQ3VsdGl2b3MNCmBgYA0KDQpgYGB7cn0NClR1cmJvX0N1bHRpdm9zDQpgYGANCg0KIyMjIDcuMiBDdWx0aXZvcyBkZSBtYXlvciB5IG1lbm9yIHByb2R1Y2Npw7NuIGVuIGVsIG11bmljaXBpbyBkZSBUdXJibyAoQW50aW9xdWlhKQ0KDQpgYGB7cn0NCnA8LWdncGxvdChkYXRhPW1haW4ubGVhZGVycywgYWVzKHg9Q3VsdGl2bywgeT1Ub3RhbF9Qcm9kKSkgKw0KICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIpDQpgYGANCg0KYGBge3J9DQpuZXdfZXZhICU+JQ0KICBncm91cF9ieShDdWx0aXZvKSAlPiUNCiAgc3VtbWFyaXplKFRvdGFsX1Byb2QgPSBzdW0oUHJvZHVjY2lvbiwgbmEucm0gPSBUUlVFKSkgJT4lDQogIHNsaWNlKHdoaWNoLm1heChUb3RhbF9Qcm9kKSkgIC0+IEN1bHRpdm9fTWF4DQpgYGANCg0KYGBge3J9DQpDdWx0aXZvX01heA0KYGBgDQpgYGB7cn0NCm5ld19ldmEgJT4lDQogIGdyb3VwX2J5KEN1bHRpdm8pICU+JQ0KICBzdW1tYXJpemUoVG90YWxfUHJvZCA9IHN1bShQcm9kdWNjaW9uLCBuYS5ybSA9IFRSVUUpKSAlPiUNCiAgc2xpY2Uod2hpY2gubWluKFRvdGFsX1Byb2QpKSAgLT4gQ3VsdGl2b19NaW4NCmBgYA0KDQpgYGB7cn0NCkN1bHRpdm9fTWluDQpgYGANCg0KDQoNCiMjIDguIEJJQkxJT0dSQUbDjUENCg0KYGBge3J9DQpzZXNzaW9uSW5mbygpDQpgYGANCg0KDQo=