1. Why this notebook?

Este es un Cuaderno de R Markdown que ilustra estadisticas agricolas para el departamento de Cauca en Colombia, tiene como objetivo la comprención de los conceptos básicos de geomática útiles para la agronomía como respuesta a lo enseñado en el curso de Geomatica Básica de la Universidad Nacional de Colombia.

2. Funciones de GIS

La exploración de estadísticas no espaciales es fundamental para comprender lo que sucede en los territorios. Varias bibliotecas de R, en particular dplyr y tidyverse, son muy útiles para explorar y resumir estadísticas.

Por otro lado, las operaciones geoespaciales pueden mejorar nuestra comprensión de varios problemas que afectan a las regiones geográficas. Por ejemplo, desea averiguar cuál es la ubicación de los municipios cuyos rendimientos de cultivos son sobresalientes (o, alternativamente, más bajos que el promedio). Para realizar dicha exploración, necesitamos unir datos no espaciales con datos espaciales.

Además, también podríamos explorar combinaciones espaciales. Estas operaciones se basan en la intersección entre dos objetos espaciales, a menudo puntos y polígonos. Hay muchas formas en que podemos unir objetos, que pueden incluir opciones específicas como cruces, cerca, dentro, toques, etc. El punto es no presionarlo, ¡podemos hacerlo en otro R Notebook!

Comencemos eliminando el contenido de la memoria:

rm(list=ls())

Ahora, instalemos las bibliotecas que necesitamos. Tenga en cuenta que, en el siguiente fragmento, cualquier paquete se instala solo si no se ha instalado previamente. Se recomienda correr uno por uno en la consola para detectar posibles errores

#list.of.packages <- c("here", "tidyverse", "rgeos", "maptools", "raster", "sf",  "viridis", "rnaturalearth", "GSODR", "ggrepel", "cowplot")
#new.packages <- list.of.packages[!(list.of.packages %in% installed.packages()[,"Package"])]
#if(length(new.packages)) install.packages(new.packages)

Ahora, carguemos las bibliotecas.

library(here)
here() starts at C:/Users/rojas/OneDrive/Escritorio/R estudio/Geomatica/trabajo7
library(tidyverse)
Registered S3 methods overwritten by 'dbplyr':
  method         from
  print.tbl_lazy     
  print.tbl_sql      
-- Attaching packages --------------------------------------- tidyverse 1.3.0 --
v ggplot2 3.3.2     v purrr   0.3.4
v tibble  3.0.3     v dplyr   1.0.2
v tidyr   1.1.2     v stringr 1.4.0
v readr   1.3.1     v forcats 0.5.0
-- Conflicts ------------------------------------------ tidyverse_conflicts() --
x tidyr::extract() masks raster::extract()
x dplyr::filter()  masks stats::filter()
x dplyr::lag()     masks stats::lag()
x dplyr::select()  masks raster::select()
library(rgeos)
rgeos version: 0.5-5, (SVN revision 640)
 GEOS runtime version: 3.8.0-CAPI-1.13.1 
 Linking to sp version: 1.4-2 
 Polygon checking: TRUE 
library(maptools)
Checking rgeos availability: TRUE
library(raster)
library(sf)
Linking to GEOS 3.8.0, GDAL 3.0.4, PROJ 6.3.1
library(viridis)
Loading required package: viridisLite
library(rnaturalearth)
library(GSODR)
Registered S3 method overwritten by 'data.table':
  method           from
  print.data.table     
library(ggrepel)
library(cowplot)

3. Explorando las estadísticas agrícolas en Cauca.

Previamente, he descargado datos estadísticos, en formato csv, sobre Estadisticas Municipales Agropecuarias a mi computadora. Luego, he usado Excel para eliminar filas para municipios en departamentos diferentes a Cauca, cree una nueva fila con el nombre COD donde esta registrado el ID+1 no que nos será útil más adenate. Guardé el archivo con las filas restantes como un archivo local con el nombre EVA_cauca.csv en mi computadora.

Leamos el archivo csv con “estadisticas municipales agropecuarias” para Cauca.

setwd("C:/Users/rojas/OneDrive/Escritorio/R estudio/Geomatica/trabajo7")
datos<-read_csv("C:/Users/rojas/OneDrive/Escritorio/R estudio/Geomatica/trabajo7/EVA_cauca.csv")
Parsed with column specification:
cols(
  ID = col_double(),
  COD = col_character(),
  MUN = col_character(),
  GRUPO = col_character(),
  SUBGRUPO = col_character(),
  CULTIVO = col_character(),
  DESAGR = col_character(),
  YEAR = col_double(),
  PERIODO = col_character(),
  HA_SIEMBRA = col_double(),
  HA_COSECHA = col_double(),
  TON_PROD = col_double(),
  REND = col_double(),
  ESTADO = col_character(),
  NOMBRE = col_character(),
  CICLO = col_character()
)

Veamos cuáles son los atributos de los datos.

head(datos)
NA
tail(datos)

Teniendo en cuenta que cada municipio dispone de estadísticas sobre superficie sembrada, superficie cosechada y rendimiento para diferentes cultivos en diferentes años. El atributo SUBGRUPO y CULTIVO parecen referirse a lo mismo (es decir, un cultivo). Los cultivos se clasifican además en un GRUPO determinado.

En esta tabla, no tenemos unidades. Sin embargo, si revisamos el archivo csv original, encontramos que las unidades de área son hectáreas y que las unidades de rendimiento son Ton / ha.

Usaremos la biblioteca dplyr para explorar el contenido del objeto de datos.

Primero, obtengamos un resumen del rendimiento (es decir, el rendimiento promedio durante varios años) por grupo y municipio:

datos %>%
  group_by(MUN, GRUPO) %>%
  summarise(rend_prom = mean(REND, na.rm = TRUE)) -> rend_resumen
`summarise()` regrouping output by 'MUN' (override with `.groups` argument)
### Revisaremos solo los 6 primeros datos.
head(rend_resumen)

También podemos calcular el rendimiento promedio por GRUPO en los municipios de Cauca:

datos %>%
  group_by(GRUPO) %>%
  summarise(rend_dep = mean(REND, na.rm = TRUE)) -> rend_cauca
`summarise()` ungrouping output (override with `.groups` argument)
rend_cauca

Nótese que los mayores rendimientos corresponden a HORTALIZAS, FLORES Y FOLLAJES y OTROS PERMANENTES.

Luego, busquemos cuáles son los municipios con mayor rendimiento para cada grupo de cultivos en 2018:

datos %>% 
  filter(YEAR==2018) %>% 
  group_by(GRUPO, MUN) %>%
  summarize(max_rend = max(REND, na.rm = TRUE)) %>%
    slice(which.max(max_rend)) -> rend_max_18
ningun argumento finito para max; retornando -Inf`summarise()` regrouping output by 'GRUPO' (override with `.groups` argument)
rend_max_18

Ahora, busquemos cuáles son los municipios con mayor área cosechada para cada grupo de cultivos en 2018:

datos %>% 
  filter(YEAR==2018) %>% 
  group_by(GRUPO, MUN) %>%
  summarize(max_HA_COSECHA = max(HA_COSECHA, na.rm = TRUE)) %>%
    slice(which.max(max_HA_COSECHA)) -> HA_COSECHA_max
`summarise()` regrouping output by 'GRUPO' (override with `.groups` argument)
HA_COSECHA_max

Nótese que la mayor superficie cosechada en 2018 correspondió a OTROS PERMANENTES en EL TAMBO, Quizás sepa que la economía de EL TAMBO está soportada principalmente por la producción cafetera intercalada con plátano.

Primero, seleccionemos la producción de cafe (toneladas) en EL TAMBO para cada año:

datos %>% 
  filter(MUN=="EL TAMBO" & SUBGRUPO=="CAFE") %>% 
  group_by(YEAR, CULTIVO) ->  TAMBO_CAFE

TAMBO_CAFE

Hagamos una exploración gráfica básica usando la biblioteca ggplot2:

g<- ggplot(aes(x=YEAR, y=TON_PROD/1000), data = TAMBO_CAFE) + geom_bar(stat='identity') + labs(y='Producción de Cafe [Ton x 1000]', x='Año')
g + ggtitle("Evolución de la producción de café en El Tambo de 2007 a 2018") + labs(caption= "Basado en datos de EMA (DANE, 2018)")

Ahora, investiguemos qué cultivos tuvieron la mayor área cosechada en 2018:

datos %>% 
  filter(YEAR==2018) %>% 
  group_by(GRUPO) %>%
  summarize(sum_HA_COSECHA = sum(HA_COSECHA, na.rm = TRUE)) %>%
     arrange(desc(sum_HA_COSECHA)) -> total_HA_COSECHA
`summarise()` ungrouping output (override with `.groups` argument)
total_HA_COSECHA

Podemos ver que otros cultivos permanentes también tuvieron la mayor proporción de área cosechada en 2018 para Cauca. ¿Qué cultivos pertenecen a este GRUPO? Puede buscar más información en DANE, la agencia gubernamental a cargo de las estadísticas nacionales en Colombia.

También podemos buscar esta información en los propios datos:

datos %>%
  filter(GRUPO=="OTROS PERMANENTES" & YEAR==2018) %>%
  group_by(CULTIVO) %>%
  summarize(sum_cosecha = sum(HA_COSECHA, na.rm = TRUE)) %>%
     arrange(desc(sum_cosecha)) -> total_cosecha
`summarise()` ungrouping output (override with `.groups` argument)
total_cosecha

¡Tenga en cuenta que el departamento del Cauca hace parte del llamado nuevo eje cafetero!

Ahora, veamos cuáles son los municipios con mayor área cosechada por cada cultivo permanente en 2018:

datos %>% 
  filter(YEAR==2018 & GRUPO=="OTROS PERMANENTES") %>% 
  group_by(CULTIVO, MUN) %>%
  summarize(max_area2 = max(HA_COSECHA, na.rm = TRUE)) %>%
    slice(which.max(max_area2)) -> area_cosecha2
`summarise()` regrouping output by 'CULTIVO' (override with `.groups` argument)
area_cosecha2

Volvamos a los datos de cultivos permanentes. Antes de graficar, necesitaremos agregar, al objeto total_area_cosecha, un nuevo campo con abreviaturas para cada GRUPO de cultivos. De lo contrario, la trama se verá desordenada.

total_HA_COSECHA$CROP <- abbreviate(total_HA_COSECHA$GRUPO, 3)

Ahora es el momento de trazar usando la biblioteca ggplot2:

g <- ggplot(aes(x=CROP, y=sum_HA_COSECHA), data = total_HA_COSECHA) + geom_bar(stat='identity') + labs(y='Área total cosechada [Ha]', x= 'Cultivo')
g+ ggtitle("Superficie total cosechada por grupos de cultivos en 2018 para Cauca") + theme(plot.title = element_text(hjust = 0.5)) +
   labs(caption= "Basado en datos de EMA (DANE, 2018)") 

Ya que uno de los principales productos agricolas del Cauca es el cafe, odservaremos el rendimiento máximo de este producto en los diferentes municipios para el año 2018, como ha sido la evolución de su producción a través de los años y por ultimo revisaremos cuales han sido los municipios con mayor área cosecheada en el 2018. Primero el rendimiento máximo del cafe en los diferentes municipios para el año 2018 y cuales municipios tuvieron mayor Área de cosecha de Cafe en 2018:

datos %>% 
  filter( YEAR==2018 &GRUPO=="OTROS PERMANENTES" & SUBGRUPO=="CAFE") %>% 
   group_by(MUN,GRUPO,CULTIVO,YEAR) %>%
  summarize(max_rend = max(REND, na.rm = TRUE)) %>%
    slice(which.max(max_rend)) -> rendcafe_max_18
`summarise()` regrouping output by 'MUN', 'GRUPO', 'CULTIVO' (override with `.groups` argument)
rendcafe_max_18

Ahora miraremos la evolución de la producción del año 2007 a al 2018:

datos %>% 
  filter(SUBGRUPO=="CAFE") %>% 
  group_by(YEAR, CULTIVO) ->  CAUCA_CAFE

head(CAUCA_CAFE)
g<- ggplot(aes(x=YEAR, y=TON_PROD/1000), data = CAUCA_CAFE) + geom_bar(stat='identity') + labs(y='Producción de Cafe [Ton x 1000]', x='Año')
g + ggtitle("Evolución de la producción de café en Cauca de 2017 a 2018") + labs(caption= "Basado en datos de EMA (DANE, 2018)")

Hola veremos lo municipios de Cauca con mayor área cosechada para el 2018

datos %>% 
  filter(YEAR==2018 & SUBGRUPO=="CAFE") %>% 
  group_by(MUN, CULTIVO) %>%
  summarize(sum_cosecha = sum(HA_COSECHA, na.rm = TRUE)) %>%
  filter(sum_cosecha>4000) %>%
  arrange(desc(sum_cosecha)) -> MUN2
`summarise()` regrouping output by 'MUN' (override with `.groups` argument)
MUN2
NA
MUN2$MUN <- abbreviate(MUN2$MUN , 4)
MUN2
g <- ggplot(aes(x=MUN, y=sum_cosecha), data = MUN2) + geom_bar(stat='identity') + labs(y='Área total cosechada [Ha]', x= 'Municipio')
g+ ggtitle("Municipos con mayor área cosechada de cafe en Cauca (2018)") + theme(plot.title = element_text(hjust = 0.3)) +
   labs(caption= "Basado en datos de EMA (DANE, 2018)")

4. Incorporación de las estadísticas agrícolas a los municipios

Comencemos a leer los datos administrativos de Cauca, dados por Marco Geoestadistico Departamental que se encuentra disponible en DANE Geoportal, usando la biblioteca sf:

cau_munic <- sf::st_read("C:/Users/rojas/OneDrive/Escritorio/R estudio/Geomatica/Departamento/19_CAUCA/Cauca/ADMINISTRATIVO/MGN_MPIO_POLITICO.shp")
Reading layer `MGN_MPIO_POLITICO' from data source `C:\Users\rojas\OneDrive\Escritorio\R estudio\Geomatica\Departamento\19_CAUCA\Cauca\ADMINISTRATIVO\MGN_MPIO_POLITICO.shp' using driver `ESRI Shapefile'
Simple feature collection with 42 features and 9 fields
geometry type:  POLYGON
dimension:      XY
bbox:           xmin: -77.92834 ymin: 0.9580285 xmax: -75.74782 ymax: 3.328941
geographic CRS: WGS 84

¿Qué es ant_munic?

cau_munic
Simple feature collection with 42 features and 9 fields
geometry type:  POLYGON
dimension:      XY
bbox:           xmin: -77.92834 ymin: 0.9580285 xmax: -75.74782 ymax: 3.328941
geographic CRS: WGS 84
First 10 features:
   DPTO_CCDGO MPIO_CCDGO   MPIO_CNMBR                         MPIO_CRSLC
1          19      19001      POPAYÁN                               1537
2          19      19022     ALMAGUER                               1799
3          19      19050      ARGELIA Ordenanza 2 de Noviembre 8 de 1967
4          19      19075       BALBOA  Ordenanza 1 de Octubre 20 de 1967
5          19      19100      BOLÍVAR                               1793
6          19      19110 BUENOS AIRES                               1851
7          19      19130      CAJIBÍO                               1824
8          19      19137      CALDONO                               1746
9          19      19142       CALOTO                               1543
10         19      19212      CORINTO                               1868
   MPIO_NAREA MPIO_NANO DPTO_CNMBR Shape_Leng Shape_Area
1    480.1798      2017      CAUCA  1.3729371 0.03897000
2    236.7148      2017      CAUCA  0.7102530 0.01919657
3    775.7878      2017      CAUCA  1.2241529 0.06288063
4    413.2112      2017      CAUCA  1.0163274 0.03349049
5    797.8203      2017      CAUCA  1.8027866 0.06468337
6    435.0623      2017      CAUCA  1.6333631 0.03532030
7    552.2877      2017      CAUCA  1.3822054 0.04482019
8    354.7387      2017      CAUCA  1.1029614 0.02880277
9    266.5987      2017      CAUCA  1.3621191 0.02164894
10   325.9156      2017      CAUCA  0.8276564 0.02647947
                         geometry
1  POLYGON ((-76.74145 2.57230...
2  POLYGON ((-76.80864 1.98674...
3  POLYGON ((-77.3107 2.508326...
4  POLYGON ((-77.1431 2.156948...
5  POLYGON ((-76.92984 2.11058...
6  POLYGON ((-76.76916 3.23128...
7  POLYGON ((-76.83997 2.76373...
8  POLYGON ((-76.36326 2.90734...
9  POLYGON ((-76.42866 3.20990...
10 POLYGON ((-76.28278 3.22879...

Tenga en cuenta que ant_munic es una colección de funciones simple. Asegúrese de revisar este enlace para comprender qué es una característica simple.

Tenga en cuenta también que los datos utilizan el sistema de referencia de coordenadas geográficas WGS1984 (es decir, el código 4326 epsg).

Podemos usar la función left_join para unir los municipios y las estadísticas agrícolas seleccionadas.

Necesitamos un atributo común (o variable compartida) en el que basar la unión. El mejor atributo es una identificación. En cau_munic, el atributo MPIO_CCDGO parece estar bien (lee 19001 para Popayán). En datos, el atributo correspondiente es COD_MUN (lee 19001 para Popayán).

Verifiquemos la última declaración:

datos %>% filter (MUN =="POPAYAN") ->  med_datos
med_datos
class(med_datos$COD)
[1] "character"

Para poder hacer la unión, necesitamos cambiar tanto el tipo de datos como el contenido del código que identifica a cada municipio. Para esta tarea, es una buena idea crear una copia de los datos estadísticos originales. Con este enfoque, cualquier movimiento falso no estropeará los datos originales.

Procedamos paso a paso:

datos2 <- datos
datos2$TEMP <-  as.character(datos2$COD)
datos2$MPIO_CCDGO <- as.factor(paste(datos2$TEMP, sep=""))
head(datos2)

Asegúrese de verificar, en el objeto datos 2, las características del nuevo atributo MPIO_CCDGO.

Ahora, filtremos un solo año y seleccionemos solo dos atributos relevantes:

datos2 %>% filter(CULTIVO == "CAFE")  -> datos3
head(datos3)
class(datos3)
[1] "spec_tbl_df" "tbl_df"      "tbl"         "data.frame" 
datos4 <- datos3 %>% dplyr::select(MUN, MPIO_CCDGO, YEAR, TON_PROD, REND)
datos4
datos4 %>% 
  gather("YEAR", "TON_PROD", "REND" , key = variable, value = number)
head(datos4)

Ésta es una tarea clave. Implica varios pasos para poder convertir la tabla de atributos de formato largo a formato ancho. Más información sobre estos pasos aquí.

datos4 %>% 
  group_by(MPIO_CCDGO) %>% 
  mutate(Visit = 1:n()) %>% 
  gather("YEAR", "TON_PROD", "REND", key = variable, value = number) %>% 
  unite(combi, variable, Visit) %>%
  spread(combi, number) -> datos5
head(datos5)
tail(datos5)

También haremos una copia de la colección de características simples (nuevamente, solo en caso de un movimiento en falso):

cau_munic2 <- cau_munic

Ahora es el momento de unirse:

cau_munic_stat = left_join(cau_munic2, datos5, by="MPIO_CCDGO")
summary(cau_munic_stat)
  DPTO_CCDGO         MPIO_CCDGO         MPIO_CNMBR       
 Length:42          Length:42          Length:42         
 Class :character   Class :character   Class :character  
 Mode  :character   Mode  :character   Mode  :character  
                                                         
                                                         
                                                         
                                                         
  MPIO_CRSLC          MPIO_NAREA        MPIO_NANO     DPTO_CNMBR       
 Length:42          Min.   :  56.65   Min.   :2017   Length:42         
 Class :character   1st Qu.: 214.88   1st Qu.:2017   Class :character  
 Mode  :character   Median : 457.62   Median :2017   Mode  :character  
                    Mean   : 743.88   Mean   :2017                     
                    3rd Qu.: 770.66   3rd Qu.:2017                     
                    Max.   :3619.37   Max.   :2017                     
                                                                       
   Shape_Leng       Shape_Area           MUN                REND_1      
 Min.   :0.3676   Min.   :0.004592   Length:42          Min.   :0.5200  
 1st Qu.:0.9546   1st Qu.:0.017436   Class :character   1st Qu.:0.6600  
 Median :1.2427   Median :0.037145   Mode  :character   Median :0.8300  
 Mean   :1.4087   Mean   :0.060343                      Mean   :0.8574  
 3rd Qu.:1.6100   3rd Qu.:0.062469                      3rd Qu.:0.9900  
 Max.   :3.6742   Max.   :0.293595                      Max.   :1.6400  
                                                        NA's   :7       
    REND_10         REND_11         REND_12          REND_2      
 Min.   :0.900   Min.   :0.660   Min.   :0.620   Min.   :0.4700  
 1st Qu.:1.040   1st Qu.:0.840   1st Qu.:0.860   1st Qu.:0.6150  
 Median :1.110   Median :1.100   Median :1.100   Median :0.7500  
 Mean   :1.122   Mean   :1.097   Mean   :1.106   Mean   :0.7926  
 3rd Qu.:1.190   3rd Qu.:1.260   3rd Qu.:1.290   3rd Qu.:0.9050  
 Max.   :1.520   Max.   :1.820   Max.   :1.870   Max.   :1.4600  
 NA's   :11      NA's   :11      NA's   :12      NA's   :8       
     REND_3           REND_4           REND_5           REND_6      
 Min.   :0.4400   Min.   :0.4500   Min.   :0.4500   Min.   :0.4500  
 1st Qu.:0.5950   1st Qu.:0.5875   1st Qu.:0.5750   1st Qu.:0.7450  
 Median :0.7200   Median :0.7200   Median :0.6800   Median :1.0500  
 Mean   :0.7809   Mean   :0.7872   Mean   :0.7023   Mean   :0.9061  
 3rd Qu.:0.8550   3rd Qu.:0.9325   3rd Qu.:0.8300   3rd Qu.:1.1000  
 Max.   :1.8200   Max.   :1.8700   Max.   :1.0600   Max.   :1.1000  
 NA's   :10       NA's   :10       NA's   :11       NA's   :11      
     REND_7           REND_8           REND_9        TON_PROD_1  
 Min.   :0.5500   Min.   :0.5900   Min.   :0.870   Min.   :   4  
 1st Qu.:0.7250   1st Qu.:0.7800   1st Qu.:1.010   1st Qu.: 405  
 Median :0.8100   Median :0.8900   Median :1.070   Median : 963  
 Mean   :0.7548   Mean   :0.8258   Mean   :1.075   Mean   :1472  
 3rd Qu.:0.8200   3rd Qu.:0.8900   3rd Qu.:1.150   3rd Qu.:1748  
 Max.   :0.8600   Max.   :1.1300   Max.   :1.220   Max.   :7306  
 NA's   :11       NA's   :11       NA's   :11      NA's   :7     
  TON_PROD_10     TON_PROD_11     TON_PROD_12       TON_PROD_2    
 Min.   :  270   Min.   :  187   Min.   : 228.0   Min.   :   0.0  
 1st Qu.: 1358   1st Qu.:  823   1st Qu.: 821.8   1st Qu.: 394.5  
 Median : 1864   Median : 2128   Median :2245.5   Median : 876.0  
 Mean   : 2913   Mean   : 3096   Mean   :2967.8   Mean   :1394.6  
 3rd Qu.: 3854   3rd Qu.: 4161   3rd Qu.:3994.5   3rd Qu.:1757.5  
 Max.   :11571   Max.   :11315   Max.   :9500.0   Max.   :6176.0  
 NA's   :11      NA's   :11      NA's   :12       NA's   :7       
   TON_PROD_3     TON_PROD_4       TON_PROD_5       TON_PROD_6  
 Min.   :  36   Min.   :  35.0   Min.   :   5.0   Min.   :  88  
 1st Qu.: 445   1st Qu.: 586.2   1st Qu.: 555.5   1st Qu.: 560  
 Median :1030   Median : 840.5   Median : 768.0   Median :1260  
 Mean   :1529   Mean   :1465.9   Mean   :1337.8   Mean   :1775  
 3rd Qu.:1917   3rd Qu.:1899.2   3rd Qu.:1592.5   3rd Qu.:2456  
 Max.   :6323   Max.   :6074.0   Max.   :5599.0   Max.   :7238  
 NA's   :10     NA's   :10       NA's   :11       NA's   :11    
   TON_PROD_7       TON_PROD_8     TON_PROD_9       YEAR_1    
 Min.   : 135.0   Min.   : 148   Min.   : 223   Min.   :2007  
 1st Qu.: 752.5   1st Qu.: 886   1st Qu.:1266   1st Qu.:2007  
 Median :1289.0   Median :1530   Median :1783   Median :2007  
 Mean   :1834.3   Mean   :2133   Mean   :2711   Mean   :2007  
 3rd Qu.:2417.5   3rd Qu.:2712   3rd Qu.:3807   3rd Qu.:2007  
 Max.   :5726.0   Max.   :8487   Max.   :8899   Max.   :2011  
 NA's   :11       NA's   :11     NA's   :11     NA's   :7     
    YEAR_10        YEAR_11        YEAR_12         YEAR_2    
 Min.   :2016   Min.   :2017   Min.   :2018   Min.   :2008  
 1st Qu.:2016   1st Qu.:2017   1st Qu.:2018   1st Qu.:2008  
 Median :2016   Median :2017   Median :2018   Median :2008  
 Mean   :2016   Mean   :2017   Mean   :2018   Mean   :2008  
 3rd Qu.:2016   3rd Qu.:2017   3rd Qu.:2018   3rd Qu.:2008  
 Max.   :2017   Max.   :2018   Max.   :2018   Max.   :2012  
 NA's   :11     NA's   :11     NA's   :12     NA's   :7     
     YEAR_3         YEAR_4         YEAR_5         YEAR_6    
 Min.   :2009   Min.   :2010   Min.   :2011   Min.   :2012  
 1st Qu.:2009   1st Qu.:2010   1st Qu.:2011   1st Qu.:2012  
 Median :2009   Median :2010   Median :2011   Median :2012  
 Mean   :2009   Mean   :2010   Mean   :2011   Mean   :2012  
 3rd Qu.:2009   3rd Qu.:2010   3rd Qu.:2011   3rd Qu.:2012  
 Max.   :2017   Max.   :2018   Max.   :2011   Max.   :2013  
 NA's   :10     NA's   :10     NA's   :11     NA's   :11    
     YEAR_7         YEAR_8         YEAR_9              geometry 
 Min.   :2013   Min.   :2014   Min.   :2015   POLYGON      :42  
 1st Qu.:2013   1st Qu.:2014   1st Qu.:2015   epsg:4326    : 0  
 Median :2013   Median :2014   Median :2015   +proj=long...: 0  
 Mean   :2013   Mean   :2014   Mean   :2015                     
 3rd Qu.:2013   3rd Qu.:2014   3rd Qu.:2015                     
 Max.   :2014   Max.   :2015   Max.   :2016                     
 NA's   :11     NA's   :11     NA's   :11                       

5. Trazado

Para realizar el trazado necesitaremos instalar RColorBrewer:

#install.packages("RColorBrewer")
library(RColorBrewer)
library(leaflet)
Registered S3 method overwritten by 'htmlwidgets':
  method           from         
  print.htmlwidget tools:rstudio

Grafiquemos los municipios con su correspondiente producción de café para un solo año:

bins <- c(0, 250, 500, 1000, 2000, 5000, 10000, 15000)
pal <- colorBin("BuPu", domain = cau_munic_stat$Produccion_12, bins = bins)

  mapa <- leaflet(data = cau_munic_stat) %>%
  addTiles() %>%
  addPolygons(label = ~TON_PROD_12, 
              popup = ~MPIO_CNMBR,
              fillColor = ~pal(TON_PROD_12),
              color = "#444444",
              weight = 1,
              smoothFactor = 0.5,
              opacity = 1.0,
              fillOpacity = 0.5,
              highlightOptions = highlightOptions(color = "white", weight = 2, bringToFront = TRUE)
              ) %>%
  addProviderTiles(providers$OpenStreetMap) %>%
  addLegend("bottomright", pal = pal, values = ~TON_PROD_12,
    title = "Producción de café en Cauca [Ton] (2018)",
    opacity = 1
  )
mapa  
sessionInfo() 
R version 4.0.2 (2020-06-22)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 18363)

Matrix products: default

locale:
[1] LC_COLLATE=Spanish_Mexico.1252  LC_CTYPE=Spanish_Mexico.1252   
[3] LC_MONETARY=Spanish_Mexico.1252 LC_NUMERIC=C                   
[5] LC_TIME=Spanish_Mexico.1252    

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

other attached packages:
 [1] leaflet_2.0.3       RColorBrewer_1.1-2  cowplot_1.1.0      
 [4] ggrepel_0.8.2       GSODR_2.1.2         rnaturalearth_0.1.0
 [7] viridis_0.5.1       viridisLite_0.3.0   sf_0.9-5           
[10] maptools_1.0-2      rgeos_0.5-5        
LS0tDQp0aXRsZTogIkVzdGFkaXN0aWNhcyBtdW5pY2lwYWxlcyBkZSBsYSBhZ3JpY3VsdHVyYSBlbiBDYXVjYSINCmF1dGhvcjogIkpvaGFuIFMuIFJvamFzIENoLiINCmRhdGU6ICI3LzEwLzIwMjAiDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KIyMgMS4gV2h5IHRoaXMgbm90ZWJvb2s/DQpFc3RlIGVzIHVuIEN1YWRlcm5vIGRlIFtSIE1hcmtkb3duXShodHRwOi8vcm1hcmtkb3duLnJzdHVkaW8uY29tKSBxdWUgaWx1c3RyYSBlc3RhZGlzdGljYXMgYWdyaWNvbGFzIHBhcmEgZWwgZGVwYXJ0YW1lbnRvIGRlIENhdWNhIGVuIENvbG9tYmlhLCAgdGllbmUgY29tbyBvYmpldGl2byBsYSBjb21wcmVuY2nDs24gZGUgbG9zIGNvbmNlcHRvcyBiw6FzaWNvcyBkZSBnZW9tw6F0aWNhIMO6dGlsZXMgcGFyYSBsYSBhZ3Jvbm9tw61hIGNvbW8gcmVzcHVlc3RhIGEgbG8gZW5zZcOxYWRvIGVuIGVsIGN1cnNvIGRlIEdlb21hdGljYSBCw6FzaWNhIGRlIGxhIFVuaXZlcnNpZGFkIE5hY2lvbmFsIGRlIENvbG9tYmlhLg0KDQojIyAyLiBGdW5jaW9uZXMgZGUgR0lTDQpMYSBleHBsb3JhY2nDs24gZGUgZXN0YWTDrXN0aWNhcyBubyBlc3BhY2lhbGVzIGVzIGZ1bmRhbWVudGFsIHBhcmEgY29tcHJlbmRlciBsbyBxdWUgc3VjZWRlIGVuIGxvcyB0ZXJyaXRvcmlvcy4gVmFyaWFzIGJpYmxpb3RlY2FzIGRlIFIsIGVuIHBhcnRpY3VsYXIgZHBseXIgeSB0aWR5dmVyc2UsIHNvbiBtdXkgw7p0aWxlcyBwYXJhIGV4cGxvcmFyIHkgcmVzdW1pciBlc3RhZMOtc3RpY2FzLg0KDQpQb3Igb3RybyBsYWRvLCBsYXMgb3BlcmFjaW9uZXMgZ2VvZXNwYWNpYWxlcyBwdWVkZW4gbWVqb3JhciBudWVzdHJhIGNvbXByZW5zacOzbiBkZSB2YXJpb3MgcHJvYmxlbWFzIHF1ZSBhZmVjdGFuIGEgbGFzIHJlZ2lvbmVzIGdlb2dyw6FmaWNhcy4gUG9yIGVqZW1wbG8sIGRlc2VhIGF2ZXJpZ3VhciBjdcOhbCBlcyBsYSB1YmljYWNpw7NuIGRlIGxvcyBtdW5pY2lwaW9zIGN1eW9zIHJlbmRpbWllbnRvcyBkZSBjdWx0aXZvcyBzb24gc29icmVzYWxpZW50ZXMgKG8sIGFsdGVybmF0aXZhbWVudGUsIG3DoXMgYmFqb3MgcXVlIGVsIHByb21lZGlvKS4gUGFyYSByZWFsaXphciBkaWNoYSBleHBsb3JhY2nDs24sIG5lY2VzaXRhbW9zIHVuaXIgZGF0b3Mgbm8gZXNwYWNpYWxlcyBjb24gZGF0b3MgZXNwYWNpYWxlcy4NCg0KQWRlbcOhcywgdGFtYmnDqW4gcG9kcsOtYW1vcyBleHBsb3JhciBjb21iaW5hY2lvbmVzIGVzcGFjaWFsZXMuIEVzdGFzIG9wZXJhY2lvbmVzIHNlIGJhc2FuIGVuIGxhIGludGVyc2VjY2nDs24gZW50cmUgZG9zIG9iamV0b3MgZXNwYWNpYWxlcywgYSBtZW51ZG8gcHVudG9zIHkgcG9sw61nb25vcy4gSGF5IG11Y2hhcyBmb3JtYXMgZW4gcXVlIHBvZGVtb3MgdW5pciBvYmpldG9zLCBxdWUgcHVlZGVuIGluY2x1aXIgb3BjaW9uZXMgZXNwZWPDrWZpY2FzIGNvbW8gY3J1Y2VzLCBjZXJjYSwgZGVudHJvLCB0b3F1ZXMsIGV0Yy4gRWwgcHVudG8gZXMgbm8gcHJlc2lvbmFybG8sIMKhcG9kZW1vcyBoYWNlcmxvIGVuIG90cm8gUiBOb3RlYm9vayENCg0KQ29tZW5jZW1vcyBlbGltaW5hbmRvIGVsIGNvbnRlbmlkbyBkZSBsYSBtZW1vcmlhOg0KDQpgYGB7cn0NCnJtKGxpc3Q9bHMoKSkNCmBgYA0KQWhvcmEsIGluc3RhbGVtb3MgbGFzIGJpYmxpb3RlY2FzIHF1ZSBuZWNlc2l0YW1vcy4gVGVuZ2EgZW4gY3VlbnRhIHF1ZSwgZW4gZWwgc2lndWllbnRlIGZyYWdtZW50bywgY3VhbHF1aWVyIHBhcXVldGUgc2UgaW5zdGFsYSBzb2xvIHNpIG5vIHNlIGhhIGluc3RhbGFkbyBwcmV2aWFtZW50ZS4NClNlIHJlY29taWVuZGEgY29ycmVyIHVubyBwb3IgdW5vIGVuIGxhIGNvbnNvbGEgcGFyYSBkZXRlY3RhciBwb3NpYmxlcyBlcnJvcmVzIA0KYGBge3J9DQojbGlzdC5vZi5wYWNrYWdlcyA8LSBjKCJoZXJlIiwgInRpZHl2ZXJzZSIsICJyZ2VvcyIsICJtYXB0b29scyIsICJyYXN0ZXIiLCAic2YiLCAgInZpcmlkaXMiLCAicm5hdHVyYWxlYXJ0aCIsICJHU09EUiIsICJnZ3JlcGVsIiwgImNvd3Bsb3QiKQ0KI25ldy5wYWNrYWdlcyA8LSBsaXN0Lm9mLnBhY2thZ2VzWyEobGlzdC5vZi5wYWNrYWdlcyAlaW4lIGluc3RhbGxlZC5wYWNrYWdlcygpWywiUGFja2FnZSJdKV0NCiNpZihsZW5ndGgobmV3LnBhY2thZ2VzKSkgaW5zdGFsbC5wYWNrYWdlcyhuZXcucGFja2FnZXMpDQpgYGANCkFob3JhLCBjYXJndWVtb3MgbGFzIGJpYmxpb3RlY2FzLg0KYGBge3J9DQpsaWJyYXJ5KGhlcmUpDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkocmdlb3MpDQpsaWJyYXJ5KG1hcHRvb2xzKQ0KbGlicmFyeShyYXN0ZXIpDQpsaWJyYXJ5KHNmKQ0KbGlicmFyeSh2aXJpZGlzKQ0KbGlicmFyeShybmF0dXJhbGVhcnRoKQ0KbGlicmFyeShHU09EUikNCmxpYnJhcnkoZ2dyZXBlbCkNCmxpYnJhcnkoY293cGxvdCkNCmBgYA0KIyMgMy4gRXhwbG9yYW5kbyBsYXMgZXN0YWTDrXN0aWNhcyBhZ3LDrWNvbGFzIGVuIENhdWNhLg0KUHJldmlhbWVudGUsIGhlIGRlc2NhcmdhZG8gZGF0b3MgZXN0YWTDrXN0aWNvcywgZW4gZm9ybWF0byBjc3YsIHNvYnJlIFtFc3RhZGlzdGljYXMgTXVuaWNpcGFsZXMgQWdyb3BlY3Vhcmlhc10oaHR0cHM6Ly93d3cuZGF0b3MuZ292LmNvL0FncmljdWx0dXJhLXktRGVzYXJyb2xsby1SdXJhbC9FdmFsdWFjaW9uZXMtQWdyb3BlY3Vhcmlhcy1NdW5pY2lwYWxlcy1FVkEvMnBudy1tbWdlKSBhIG1pIGNvbXB1dGFkb3JhLiBMdWVnbywgaGUgdXNhZG8gRXhjZWwgcGFyYSBlbGltaW5hciBmaWxhcyBwYXJhIG11bmljaXBpb3MgZW4gZGVwYXJ0YW1lbnRvcyBkaWZlcmVudGVzIGEgQ2F1Y2EsIGNyZWUgdW5hIG51ZXZhIGZpbGEgY29uIGVsIG5vbWJyZSBDT0QgZG9uZGUgZXN0YSByZWdpc3RyYWRvIGVsIElEKzEgbm8gcXVlIG5vcyBzZXLDoSDDunRpbCBtw6FzIGFkZW5hdGUuIEd1YXJkw6kgZWwgYXJjaGl2byBjb24gbGFzIGZpbGFzIHJlc3RhbnRlcyBjb21vIHVuIGFyY2hpdm8gbG9jYWwgY29uIGVsIG5vbWJyZSBFVkFfY2F1Y2EuY3N2IGVuIG1pIGNvbXB1dGFkb3JhLiANCg0KTGVhbW9zIGVsIGFyY2hpdm8gY3N2IGNvbiDigJxlc3RhZGlzdGljYXMgbXVuaWNpcGFsZXMgYWdyb3BlY3Vhcmlhc+KAnSBwYXJhIENhdWNhLg0KYGBge3J9DQpzZXR3ZCgiQzovVXNlcnMvcm9qYXMvT25lRHJpdmUvRXNjcml0b3Jpby9SIGVzdHVkaW8vR2VvbWF0aWNhL3RyYWJham83IikNCmRhdG9zPC1yZWFkX2NzdigiQzovVXNlcnMvcm9qYXMvT25lRHJpdmUvRXNjcml0b3Jpby9SIGVzdHVkaW8vR2VvbWF0aWNhL3RyYWJham83L0VWQV9jYXVjYS5jc3YiKQ0KYGBgDQpWZWFtb3MgY3XDoWxlcyBzb24gbG9zIGF0cmlidXRvcyBkZSBsb3MgZGF0b3MuDQpgYGB7cn0NCmhlYWQoZGF0b3MpDQoNCmBgYA0KYGBge3J9DQp0YWlsKGRhdG9zKQ0KYGBgDQpUZW5pZW5kbyBlbiBjdWVudGEgcXVlIGNhZGEgbXVuaWNpcGlvIGRpc3BvbmUgZGUgZXN0YWTDrXN0aWNhcyBzb2JyZSBzdXBlcmZpY2llIHNlbWJyYWRhLCBzdXBlcmZpY2llIGNvc2VjaGFkYSB5IHJlbmRpbWllbnRvIHBhcmEgZGlmZXJlbnRlcyBjdWx0aXZvcyBlbiBkaWZlcmVudGVzIGHDsW9zLiBFbCBhdHJpYnV0byBTVUJHUlVQTyB5IENVTFRJVk8gcGFyZWNlbiByZWZlcmlyc2UgYSBsbyBtaXNtbyAoZXMgZGVjaXIsIHVuIGN1bHRpdm8pLiBMb3MgY3VsdGl2b3Mgc2UgY2xhc2lmaWNhbiBhZGVtw6FzIGVuIHVuIEdSVVBPIGRldGVybWluYWRvLg0KDQpFbiBlc3RhIHRhYmxhLCBubyB0ZW5lbW9zIHVuaWRhZGVzLiBTaW4gZW1iYXJnbywgc2kgcmV2aXNhbW9zIGVsIGFyY2hpdm8gY3N2IG9yaWdpbmFsLCBlbmNvbnRyYW1vcyBxdWUgbGFzIHVuaWRhZGVzIGRlIMOhcmVhIHNvbiBoZWN0w6FyZWFzIHkgcXVlIGxhcyB1bmlkYWRlcyBkZSByZW5kaW1pZW50byBzb24gVG9uIC8gaGEuDQoNClVzYXJlbW9zIGxhIGJpYmxpb3RlY2EgZHBseXIgcGFyYSBleHBsb3JhciBlbCBjb250ZW5pZG8gZGVsIG9iamV0byBkZSBkYXRvcy4NCg0KUHJpbWVybywgb2J0ZW5nYW1vcyB1biByZXN1bWVuIGRlbCByZW5kaW1pZW50byAoZXMgZGVjaXIsIGVsIHJlbmRpbWllbnRvIHByb21lZGlvIGR1cmFudGUgdmFyaW9zIGHDsW9zKSBwb3IgZ3J1cG8geSBtdW5pY2lwaW86DQpgYGB7cn0NCmRhdG9zICU+JQ0KICBncm91cF9ieShNVU4sIEdSVVBPKSAlPiUNCiAgc3VtbWFyaXNlKHJlbmRfcHJvbSA9IG1lYW4oUkVORCwgbmEucm0gPSBUUlVFKSkgLT4gcmVuZF9yZXN1bWVuDQojIyMgUmV2aXNhcmVtb3Mgc29sbyBsb3MgNiBwcmltZXJvcyBkYXRvcy4NCmhlYWQocmVuZF9yZXN1bWVuKQ0KYGBgDQpUYW1iacOpbiBwb2RlbW9zIGNhbGN1bGFyIGVsIHJlbmRpbWllbnRvIHByb21lZGlvIHBvciBHUlVQTyBlbiBsb3MgbXVuaWNpcGlvcyBkZSBDYXVjYToNCmBgYHtyfQ0KZGF0b3MgJT4lDQogIGdyb3VwX2J5KEdSVVBPKSAlPiUNCiAgc3VtbWFyaXNlKHJlbmRfZGVwID0gbWVhbihSRU5ELCBuYS5ybSA9IFRSVUUpKSAtPiByZW5kX2NhdWNhDQoNCnJlbmRfY2F1Y2ENCmBgYA0KTsOzdGVzZSBxdWUgbG9zIG1heW9yZXMgcmVuZGltaWVudG9zIGNvcnJlc3BvbmRlbiBhIEhPUlRBTElaQVMsIEZMT1JFUyBZIEZPTExBSkVTIHkgT1RST1MgUEVSTUFORU5URVMuDQoNCkx1ZWdvLCBidXNxdWVtb3MgY3XDoWxlcyBzb24gbG9zIG11bmljaXBpb3MgY29uIG1heW9yIHJlbmRpbWllbnRvIHBhcmEgY2FkYSBncnVwbyBkZSBjdWx0aXZvcyBlbiAyMDE4Og0KYGBge3J9DQpkYXRvcyAlPiUgDQogIGZpbHRlcihZRUFSPT0yMDE4KSAlPiUgDQogIGdyb3VwX2J5KEdSVVBPLCBNVU4pICU+JQ0KICBzdW1tYXJpemUobWF4X3JlbmQgPSBtYXgoUkVORCwgbmEucm0gPSBUUlVFKSkgJT4lDQogICAgc2xpY2Uod2hpY2gubWF4KG1heF9yZW5kKSkgLT4gcmVuZF9tYXhfMTgNCg0KcmVuZF9tYXhfMTgNCmBgYA0KQWhvcmEsIGJ1c3F1ZW1vcyBjdcOhbGVzIHNvbiBsb3MgbXVuaWNpcGlvcyBjb24gbWF5b3Igw6FyZWEgY29zZWNoYWRhIHBhcmEgY2FkYSBncnVwbyBkZSBjdWx0aXZvcyBlbiAyMDE4Og0KYGBge3J9DQpkYXRvcyAlPiUgDQogIGZpbHRlcihZRUFSPT0yMDE4KSAlPiUgDQogIGdyb3VwX2J5KEdSVVBPLCBNVU4pICU+JQ0KICBzdW1tYXJpemUobWF4X0hBX0NPU0VDSEEgPSBtYXgoSEFfQ09TRUNIQSwgbmEucm0gPSBUUlVFKSkgJT4lDQogICAgc2xpY2Uod2hpY2gubWF4KG1heF9IQV9DT1NFQ0hBKSkgLT4gSEFfQ09TRUNIQV9tYXgNCg0KSEFfQ09TRUNIQV9tYXgNCmBgYA0KTsOzdGVzZSBxdWUgbGEgbWF5b3Igc3VwZXJmaWNpZSBjb3NlY2hhZGEgZW4gMjAxOCBjb3JyZXNwb25kacOzIGEgT1RST1MgUEVSTUFORU5URVMgZW4gRUwgVEFNQk8sIFF1aXrDoXMgc2VwYSBxdWUgbGEgW2Vjb25vbcOtYSBkZSBFTCBUQU1CT10oaHR0cDovL3d3dy5lbHRhbWJvLWNhdWNhLmdvdi5jby9tdW5pY2lwaW8vbnVlc3Ryby1tdW5pY2lwaW8jOn46dGV4dD1TdSUyMGVjb25vbcOtYSUyMGVzdMOhJTIwc29wb3J0YWRhJTIwcHJpbmNpcGFsbWVudGUsKFBBTSklMjBkZSUyMDE5OTQlMkMlMjBlc3RvcykgZXN0w6Egc29wb3J0YWRhIHByaW5jaXBhbG1lbnRlIHBvciBsYSBwcm9kdWNjacOzbiBjYWZldGVyYSBpbnRlcmNhbGFkYSBjb24gcGzDoXRhbm8uIA0KDQpQcmltZXJvLCBzZWxlY2Npb25lbW9zIGxhIHByb2R1Y2Npw7NuIGRlIGNhZmUgKHRvbmVsYWRhcykgZW4gRUwgVEFNQk8gcGFyYSBjYWRhIGHDsW86DQpgYGB7cn0NCmRhdG9zICU+JSANCiAgZmlsdGVyKE1VTj09IkVMIFRBTUJPIiAmIFNVQkdSVVBPPT0iQ0FGRSIpICU+JSANCiAgZ3JvdXBfYnkoWUVBUiwgQ1VMVElWTykgLT4gIFRBTUJPX0NBRkUNCg0KVEFNQk9fQ0FGRQ0KYGBgDQpIYWdhbW9zIHVuYSBleHBsb3JhY2nDs24gZ3LDoWZpY2EgYsOhc2ljYSB1c2FuZG8gbGEgYmlibGlvdGVjYSBnZ3Bsb3QyOg0KYGBge3J9DQpnPC0gZ2dwbG90KGFlcyh4PVlFQVIsIHk9VE9OX1BST0QvMTAwMCksIGRhdGEgPSBUQU1CT19DQUZFKSArIGdlb21fYmFyKHN0YXQ9J2lkZW50aXR5JykgKyBsYWJzKHk9J1Byb2R1Y2Npw7NuIGRlIENhZmUgW1RvbiB4IDEwMDBdJywgeD0nQcOxbycpDQpgYGANCmBgYHtyfQ0KZyArIGdndGl0bGUoIkV2b2x1Y2nDs24gZGUgbGEgcHJvZHVjY2nDs24gZGUgY2Fmw6kgZW4gRWwgVGFtYm8gZGUgMjAwNyBhIDIwMTgiKSArIGxhYnMoY2FwdGlvbj0gIkJhc2FkbyBlbiBkYXRvcyBkZSBFTUEgKERBTkUsIDIwMTgpIikNCmBgYA0KQWhvcmEsIGludmVzdGlndWVtb3MgcXXDqSBjdWx0aXZvcyB0dXZpZXJvbiBsYSBtYXlvciDDoXJlYSBjb3NlY2hhZGEgZW4gMjAxODoNCmBgYHtyfQ0KZGF0b3MgJT4lIA0KICBmaWx0ZXIoWUVBUj09MjAxOCkgJT4lIA0KICBncm91cF9ieShHUlVQTykgJT4lDQogIHN1bW1hcml6ZShzdW1fSEFfQ09TRUNIQSA9IHN1bShIQV9DT1NFQ0hBLCBuYS5ybSA9IFRSVUUpKSAlPiUNCiAgICAgYXJyYW5nZShkZXNjKHN1bV9IQV9DT1NFQ0hBKSkgLT4gdG90YWxfSEFfQ09TRUNIQQ0KDQp0b3RhbF9IQV9DT1NFQ0hBDQpgYGANClBvZGVtb3MgdmVyIHF1ZSBvdHJvcyBjdWx0aXZvcyBwZXJtYW5lbnRlcyB0YW1iacOpbiB0dXZpZXJvbiBsYSBtYXlvciBwcm9wb3JjacOzbiBkZSDDoXJlYSBjb3NlY2hhZGEgZW4gMjAxOCBwYXJhIENhdWNhLiDCv1F1w6kgY3VsdGl2b3MgcGVydGVuZWNlbiBhIGVzdGUgR1JVUE8/IFB1ZWRlIGJ1c2NhciBtw6FzIGluZm9ybWFjacOzbiBlbiBEQU5FLCBsYSBhZ2VuY2lhIGd1YmVybmFtZW50YWwgYSBjYXJnbyBkZSBsYXMgZXN0YWTDrXN0aWNhcyBuYWNpb25hbGVzIGVuIENvbG9tYmlhLg0KDQpUYW1iacOpbiBwb2RlbW9zIGJ1c2NhciBlc3RhIGluZm9ybWFjacOzbiBlbiBsb3MgcHJvcGlvcyBkYXRvczoNCmBgYHtyfQ0KZGF0b3MgJT4lDQogIGZpbHRlcihHUlVQTz09Ik9UUk9TIFBFUk1BTkVOVEVTIiAmIFlFQVI9PTIwMTgpICU+JQ0KICBncm91cF9ieShDVUxUSVZPKSAlPiUNCiAgc3VtbWFyaXplKHN1bV9jb3NlY2hhID0gc3VtKEhBX0NPU0VDSEEsIG5hLnJtID0gVFJVRSkpICU+JQ0KICAgICBhcnJhbmdlKGRlc2Moc3VtX2Nvc2VjaGEpKSAtPiB0b3RhbF9jb3NlY2hhDQoNCg0KdG90YWxfY29zZWNoYQ0KYGBgDQrCoVRlbmdhIGVuIGN1ZW50YSBxdWUgW2VsIGRlcGFydGFtZW50byBkZWwgQ2F1Y2EgaGFjZSBwYXJ0ZSBkZWwgbGxhbWFkbyBudWV2byBlamUgY2FmZXRlcm9dKGh0dHBzOi8vZGlhcmlvbGFlY29ub21pYS5jb20vdG9tZW1vcy1jYWZlL2l0ZW0vNDgwMy1jYWZlLWJlbmRpdG8tZGVsLWNhdWNhLXVuLXNhY3JpbGVnaW8tbm8tdG9tYXJsby5odG1sKSENCg0KQWhvcmEsIHZlYW1vcyBjdcOhbGVzIHNvbiBsb3MgbXVuaWNpcGlvcyBjb24gbWF5b3Igw6FyZWEgY29zZWNoYWRhIHBvciBjYWRhIGN1bHRpdm8gcGVybWFuZW50ZSBlbiAyMDE4Og0KYGBge3J9DQpkYXRvcyAlPiUgDQogIGZpbHRlcihZRUFSPT0yMDE4ICYgR1JVUE89PSJPVFJPUyBQRVJNQU5FTlRFUyIpICU+JSANCiAgZ3JvdXBfYnkoQ1VMVElWTywgTVVOKSAlPiUNCiAgc3VtbWFyaXplKG1heF9hcmVhMiA9IG1heChIQV9DT1NFQ0hBLCBuYS5ybSA9IFRSVUUpKSAlPiUNCiAgICBzbGljZSh3aGljaC5tYXgobWF4X2FyZWEyKSkgLT4gYXJlYV9jb3NlY2hhMg0KDQphcmVhX2Nvc2VjaGEyDQpgYGANClZvbHZhbW9zIGEgbG9zIGRhdG9zIGRlIGN1bHRpdm9zIHBlcm1hbmVudGVzLiBBbnRlcyBkZSBncmFmaWNhciwgbmVjZXNpdGFyZW1vcyBhZ3JlZ2FyLCBhbCBvYmpldG8gdG90YWxfYXJlYV9jb3NlY2hhLCB1biBudWV2byBjYW1wbyBjb24gYWJyZXZpYXR1cmFzIHBhcmEgY2FkYSBHUlVQTyBkZSBjdWx0aXZvcy4gRGUgbG8gY29udHJhcmlvLCBsYSB0cmFtYSBzZSB2ZXLDoSBkZXNvcmRlbmFkYS4NCmBgYHtyfQ0KdG90YWxfSEFfQ09TRUNIQSRDUk9QIDwtIGFiYnJldmlhdGUodG90YWxfSEFfQ09TRUNIQSRHUlVQTywgMykNCmBgYA0KQWhvcmEgZXMgZWwgbW9tZW50byBkZSB0cmF6YXIgdXNhbmRvIGxhIGJpYmxpb3RlY2EgZ2dwbG90MjoNCmBgYHtyfQ0KZyA8LSBnZ3Bsb3QoYWVzKHg9Q1JPUCwgeT1zdW1fSEFfQ09TRUNIQSksIGRhdGEgPSB0b3RhbF9IQV9DT1NFQ0hBKSArIGdlb21fYmFyKHN0YXQ9J2lkZW50aXR5JykgKyBsYWJzKHk9J8OBcmVhIHRvdGFsIGNvc2VjaGFkYSBbSGFdJywgeD0gJ0N1bHRpdm8nKQ0KYGBgDQpgYGB7cn0NCmcrIGdndGl0bGUoIlN1cGVyZmljaWUgdG90YWwgY29zZWNoYWRhIHBvciBncnVwb3MgZGUgY3VsdGl2b3MgZW4gMjAxOCBwYXJhIENhdWNhIikgKyB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkgKw0KICAgbGFicyhjYXB0aW9uPSAiQmFzYWRvIGVuIGRhdG9zIGRlIEVNQSAoREFORSwgMjAxOCkiKSANCmBgYA0KWWEgcXVlIHVubyBkZSBsb3MgcHJpbmNpcGFsZXMgcHJvZHVjdG9zIGFncmljb2xhcyBkZWwgQ2F1Y2EgZXMgZWwgY2FmZSwgb2RzZXJ2YXJlbW9zIGVsIHJlbmRpbWllbnRvIG3DoXhpbW8gZGUgZXN0ZSBwcm9kdWN0byBlbiBsb3MgZGlmZXJlbnRlcyBtdW5pY2lwaW9zIHBhcmEgZWwgYcOxbyAyMDE4LCBjb21vIGhhIHNpZG8gbGEgZXZvbHVjacOzbiBkZSBzdSBwcm9kdWNjacOzbiBhIHRyYXbDqXMgZGUgbG9zIGHDsW9zIHkgcG9yIHVsdGltbyByZXZpc2FyZW1vcyBjdWFsZXMgaGFuIHNpZG8gbG9zIG11bmljaXBpb3MgY29uIG1heW9yIMOhcmVhIGNvc2VjaGVhZGEgZW4gZWwgMjAxOC4NClByaW1lcm8gZWwgcmVuZGltaWVudG8gbcOheGltbyBkZWwgY2FmZSBlbiBsb3MgZGlmZXJlbnRlcyBtdW5pY2lwaW9zIHBhcmEgZWwgYcOxbyAyMDE4IHkgY3VhbGVzIG11bmljaXBpb3MgdHV2aWVyb24gbWF5b3Igw4FyZWEgZGUgY29zZWNoYSBkZSBDYWZlIGVuIDIwMTg6DQpgYGB7cn0NCmRhdG9zICU+JSANCiAgZmlsdGVyKCBZRUFSPT0yMDE4ICZHUlVQTz09Ik9UUk9TIFBFUk1BTkVOVEVTIiAmIFNVQkdSVVBPPT0iQ0FGRSIpICU+JSANCiAgIGdyb3VwX2J5KE1VTixHUlVQTyxDVUxUSVZPLFlFQVIpICU+JQ0KICBzdW1tYXJpemUobWF4X3JlbmQgPSBtYXgoUkVORCwgbmEucm0gPSBUUlVFKSkgJT4lDQogICAgc2xpY2Uod2hpY2gubWF4KG1heF9yZW5kKSkgLT4gcmVuZGNhZmVfbWF4XzE4DQoNCnJlbmRjYWZlX21heF8xOA0KYGBgDQpBaG9yYSBtaXJhcmVtb3MgbGEgZXZvbHVjacOzbiBkZSBsYSBwcm9kdWNjacOzbiBkZWwgYcOxbyAyMDA3IGEgYWwgMjAxODoNCmBgYHtyfQ0KZGF0b3MgJT4lIA0KICBmaWx0ZXIoU1VCR1JVUE89PSJDQUZFIikgJT4lIA0KICBncm91cF9ieShZRUFSLCBDVUxUSVZPKSAtPiAgQ0FVQ0FfQ0FGRQ0KDQpoZWFkKENBVUNBX0NBRkUpDQpgYGANCmBgYHtyfQ0KZzwtIGdncGxvdChhZXMoeD1ZRUFSLCB5PVRPTl9QUk9ELzEwMDApLCBkYXRhID0gQ0FVQ0FfQ0FGRSkgKyBnZW9tX2JhcihzdGF0PSdpZGVudGl0eScpICsgbGFicyh5PSdQcm9kdWNjacOzbiBkZSBDYWZlIFtUb24geCAxMDAwXScsIHg9J0HDsW8nKQ0KYGBgDQpgYGB7cn0NCmcgKyBnZ3RpdGxlKCJFdm9sdWNpw7NuIGRlIGxhIHByb2R1Y2Npw7NuIGRlIGNhZsOpIGVuIENhdWNhIGRlIDIwMTcgYSAyMDE4IikgKyBsYWJzKGNhcHRpb249ICJCYXNhZG8gZW4gZGF0b3MgZGUgRU1BIChEQU5FLCAyMDE4KSIpDQpgYGANCkhvbGEgdmVyZW1vcyBsbyBtdW5pY2lwaW9zIGRlIENhdWNhIGNvbiBtYXlvciDDoXJlYSBjb3NlY2hhZGEgcGFyYSBlbCAyMDE4DQpgYGB7cn0NCmRhdG9zICU+JSANCiAgZmlsdGVyKFlFQVI9PTIwMTggJiBTVUJHUlVQTz09IkNBRkUiKSAlPiUgDQogIGdyb3VwX2J5KE1VTiwgQ1VMVElWTykgJT4lDQogIHN1bW1hcml6ZShzdW1fY29zZWNoYSA9IHN1bShIQV9DT1NFQ0hBLCBuYS5ybSA9IFRSVUUpKSAlPiUNCiAgZmlsdGVyKHN1bV9jb3NlY2hhPjQwMDApICU+JQ0KICBhcnJhbmdlKGRlc2Moc3VtX2Nvc2VjaGEpKSAtPiBNVU4yDQoNCk1VTjINCg0KYGBgDQpgYGB7cn0NCk1VTjIkTVVOIDwtIGFiYnJldmlhdGUoTVVOMiRNVU4gLCA0KQ0KTVVOMg0KYGBgDQoNCmBgYHtyfQ0KZyA8LSBnZ3Bsb3QoYWVzKHg9TVVOLCB5PXN1bV9jb3NlY2hhKSwgZGF0YSA9IE1VTjIpICsgZ2VvbV9iYXIoc3RhdD0naWRlbnRpdHknKSArIGxhYnMoeT0nw4FyZWEgdG90YWwgY29zZWNoYWRhIFtIYV0nLCB4PSAnTXVuaWNpcGlvJykNCmBgYA0KYGBge3J9DQpnKyBnZ3RpdGxlKCJNdW5pY2lwb3MgY29uIG1heW9yIMOhcmVhIGNvc2VjaGFkYSBkZSBjYWZlIGVuIENhdWNhICgyMDE4KSIpICsgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuMykpICsNCiAgIGxhYnMoY2FwdGlvbj0gIkJhc2FkbyBlbiBkYXRvcyBkZSBFTUEgKERBTkUsIDIwMTgpIikNCmBgYA0KDQojIyA0LiBJbmNvcnBvcmFjacOzbiBkZSBsYXMgZXN0YWTDrXN0aWNhcyBhZ3LDrWNvbGFzIGEgbG9zIG11bmljaXBpb3MNCkNvbWVuY2Vtb3MgYSBsZWVyIGxvcyBkYXRvcyBhZG1pbmlzdHJhdGl2b3MgZGUgQ2F1Y2EsIGRhZG9zIHBvciBNYXJjbyBHZW9lc3RhZGlzdGljbyBEZXBhcnRhbWVudGFsIHF1ZSBzZSBlbmN1ZW50cmEgZGlzcG9uaWJsZSBlbiBEQU5FIEdlb3BvcnRhbCwgdXNhbmRvIGxhIGJpYmxpb3RlY2Egc2Y6DQpgYGB7cn0NCmNhdV9tdW5pYyA8LSBzZjo6c3RfcmVhZCgiQzovVXNlcnMvcm9qYXMvT25lRHJpdmUvRXNjcml0b3Jpby9SIGVzdHVkaW8vR2VvbWF0aWNhL0RlcGFydGFtZW50by8xOV9DQVVDQS9DYXVjYS9BRE1JTklTVFJBVElWTy9NR05fTVBJT19QT0xJVElDTy5zaHAiKQ0KYGBgDQrCv1F1w6kgZXMgYW50X211bmljPw0KYGBge3J9DQpjYXVfbXVuaWMNCmBgYA0KVGVuZ2EgZW4gY3VlbnRhIHF1ZSBhbnRfbXVuaWMgZXMgdW5hIGNvbGVjY2nDs24gZGUgZnVuY2lvbmVzIHNpbXBsZS4gQXNlZ8O6cmVzZSBkZSByZXZpc2FyIFtlc3RlIGVubGFjZV0oaHR0cHM6Ly9yLXNwYXRpYWwuZ2l0aHViLmlvL3NmL2FydGljbGVzL3NmMS5odG1sKSBwYXJhIGNvbXByZW5kZXIgcXXDqSBlcyB1bmEgY2FyYWN0ZXLDrXN0aWNhIHNpbXBsZS4NCg0KVGVuZ2EgZW4gY3VlbnRhIHRhbWJpw6luIHF1ZSBsb3MgZGF0b3MgdXRpbGl6YW4gZWwgc2lzdGVtYSBkZSByZWZlcmVuY2lhIGRlIGNvb3JkZW5hZGFzIGdlb2dyw6FmaWNhcyBXR1MxOTg0IChlcyBkZWNpciwgZWwgY8OzZGlnbyA0MzI2IGVwc2cpLg0KDQpQb2RlbW9zIHVzYXIgbGEgZnVuY2nDs24gbGVmdF9qb2luIHBhcmEgdW5pciBsb3MgbXVuaWNpcGlvcyB5IGxhcyBlc3RhZMOtc3RpY2FzIGFncsOtY29sYXMgc2VsZWNjaW9uYWRhcy4gDQoNCk5lY2VzaXRhbW9zIHVuIGF0cmlidXRvIGNvbcO6biAobyB2YXJpYWJsZSBjb21wYXJ0aWRhKSBlbiBlbCBxdWUgYmFzYXIgbGEgdW5pw7NuLiBFbCBtZWpvciBhdHJpYnV0byBlcyB1bmEgaWRlbnRpZmljYWNpw7NuLiBFbiBjYXVfbXVuaWMsIGVsIGF0cmlidXRvIE1QSU9fQ0NER08gcGFyZWNlIGVzdGFyIGJpZW4gKGxlZSAxOTAwMSBwYXJhIFBvcGF5w6FuKS4gRW4gZGF0b3MsIGVsIGF0cmlidXRvIGNvcnJlc3BvbmRpZW50ZSBlcyBDT0RfTVVOIChsZWUgMTkwMDEgcGFyYSBQb3BhecOhbikuDQoNClZlcmlmaXF1ZW1vcyBsYSDDumx0aW1hIGRlY2xhcmFjacOzbjoNCmBgYHtyfQ0KZGF0b3MgJT4lIGZpbHRlciAoTVVOID09IlBPUEFZQU4iKSAtPiAgbWVkX2RhdG9zDQpgYGANCg0KDQpgYGB7cn0NCm1lZF9kYXRvcw0KYGBgDQpgYGB7cn0NCmNsYXNzKG1lZF9kYXRvcyRDT0QpDQpgYGANClBhcmEgcG9kZXIgaGFjZXIgbGEgdW5pw7NuLCBuZWNlc2l0YW1vcyBjYW1iaWFyIHRhbnRvIGVsIHRpcG8gZGUgZGF0b3MgY29tbyBlbCBjb250ZW5pZG8gZGVsIGPDs2RpZ28gcXVlIGlkZW50aWZpY2EgYSBjYWRhIG11bmljaXBpby4gUGFyYSBlc3RhIHRhcmVhLCBlcyB1bmEgYnVlbmEgaWRlYSBjcmVhciB1bmEgY29waWEgZGUgbG9zIGRhdG9zIGVzdGFkw61zdGljb3Mgb3JpZ2luYWxlcy4gQ29uIGVzdGUgZW5mb3F1ZSwgY3VhbHF1aWVyIG1vdmltaWVudG8gZmFsc28gbm8gZXN0cm9wZWFyw6EgbG9zIGRhdG9zIG9yaWdpbmFsZXMuDQoNClByb2NlZGFtb3MgcGFzbyBhIHBhc286DQpgYGB7cn0NCmRhdG9zMiA8LSBkYXRvcw0KYGBgDQoNCmBgYHtyfQ0KZGF0b3MyJFRFTVAgPC0gIGFzLmNoYXJhY3RlcihkYXRvczIkQ09EKQ0KYGBgDQpgYGB7cn0NCmRhdG9zMiRNUElPX0NDREdPIDwtIGFzLmZhY3RvcihwYXN0ZShkYXRvczIkVEVNUCwgc2VwPSIiKSkNCmBgYA0KDQpgYGB7cn0NCmhlYWQoZGF0b3MyKQ0KYGBgDQpBc2Vnw7pyZXNlIGRlIHZlcmlmaWNhciwgZW4gZWwgb2JqZXRvIGRhdG9zIDIsIGxhcyBjYXJhY3RlcsOtc3RpY2FzIGRlbCBudWV2byBhdHJpYnV0byBNUElPX0NDREdPLg0KDQpBaG9yYSwgZmlsdHJlbW9zIHVuIHNvbG8gYcOxbyB5IHNlbGVjY2lvbmVtb3Mgc29sbyBkb3MgYXRyaWJ1dG9zIHJlbGV2YW50ZXM6DQpgYGB7cn0NCmRhdG9zMiAlPiUgZmlsdGVyKENVTFRJVk8gPT0gIkNBRkUiKSAgLT4gZGF0b3MzDQpgYGANCg0KDQpgYGB7cn0NCmhlYWQoZGF0b3MzKQ0KYGBgDQpgYGB7cn0NCmNsYXNzKGRhdG9zMykNCmBgYA0KYGBge3J9DQpkYXRvczQgPC0gZGF0b3MzICU+JSBkcGx5cjo6c2VsZWN0KE1VTiwgTVBJT19DQ0RHTywgWUVBUiwgVE9OX1BST0QsIFJFTkQpDQpgYGANCmBgYHtyfQ0KZGF0b3M0DQpgYGANCmBgYHtyfQ0KZGF0b3M0ICU+JSANCiAgZ2F0aGVyKCJZRUFSIiwgIlRPTl9QUk9EIiwgIlJFTkQiICwga2V5ID0gdmFyaWFibGUsIHZhbHVlID0gbnVtYmVyKQ0KYGBgDQpgYGB7cn0NCmhlYWQoZGF0b3M0KQ0KYGBgDQrDiXN0YSBlcyB1bmEgdGFyZWEgY2xhdmUuIEltcGxpY2EgdmFyaW9zIHBhc29zIHBhcmEgcG9kZXIgY29udmVydGlyIGxhIHRhYmxhIGRlIGF0cmlidXRvcyBkZSBmb3JtYXRvIGxhcmdvIGEgZm9ybWF0byBhbmNoby4gTcOhcyBpbmZvcm1hY2nDs24gc29icmUgZXN0b3MgcGFzb3MgW2FxdcOtXShodHRwczovL2RhdGFzY2llbmNlcGx1cy5jb20vY29udmVydGluZy1kYXRhLWZyb20tbG9uZy10by13aWRlLWFuZC1mcm9tLXdpZGUtdG8tbG9uZy1zaW1wbGlmaWVkLXRpZHl2ZXJzZS1wYWNrYWdlLykuDQpgYGB7cn0NCmRhdG9zNCAlPiUgDQogIGdyb3VwX2J5KE1QSU9fQ0NER08pICU+JSANCiAgbXV0YXRlKFZpc2l0ID0gMTpuKCkpICU+JSANCiAgZ2F0aGVyKCJZRUFSIiwgIlRPTl9QUk9EIiwgIlJFTkQiLCBrZXkgPSB2YXJpYWJsZSwgdmFsdWUgPSBudW1iZXIpICU+JSANCiAgdW5pdGUoY29tYmksIHZhcmlhYmxlLCBWaXNpdCkgJT4lDQogIHNwcmVhZChjb21iaSwgbnVtYmVyKSAtPiBkYXRvczUNCmBgYA0KYGBge3J9DQpoZWFkKGRhdG9zNSkNCmBgYA0KYGBge3J9DQp0YWlsKGRhdG9zNSkNCmBgYA0KVGFtYmnDqW4gaGFyZW1vcyB1bmEgY29waWEgZGUgbGEgY29sZWNjacOzbiBkZSBjYXJhY3RlcsOtc3RpY2FzIHNpbXBsZXMgKG51ZXZhbWVudGUsIHNvbG8gZW4gY2FzbyBkZSB1biBtb3ZpbWllbnRvIGVuIGZhbHNvKToNCmBgYHtyfQ0KY2F1X211bmljMiA8LSBjYXVfbXVuaWMNCmBgYA0KQWhvcmEgZXMgZWwgbW9tZW50byBkZSB1bmlyc2U6DQpgYGB7cn0NCmNhdV9tdW5pY19zdGF0ID0gbGVmdF9qb2luKGNhdV9tdW5pYzIsIGRhdG9zNSwgYnk9Ik1QSU9fQ0NER08iKQ0KYGBgDQpgYGB7cn0NCnN1bW1hcnkoY2F1X211bmljX3N0YXQpDQpgYGANCiMjIDUuIFRyYXphZG8NClBhcmEgcmVhbGl6YXIgZWwgdHJhemFkbyBuZWNlc2l0YXJlbW9zIGluc3RhbGFyIFJDb2xvckJyZXdlcjoNCmBgYHtyfQ0KI2luc3RhbGwucGFja2FnZXMoIlJDb2xvckJyZXdlciIpDQpsaWJyYXJ5KFJDb2xvckJyZXdlcikNCmxpYnJhcnkobGVhZmxldCkNCmBgYA0KR3JhZmlxdWVtb3MgbG9zIG11bmljaXBpb3MgY29uIHN1IGNvcnJlc3BvbmRpZW50ZSBwcm9kdWNjacOzbiBkZSBjYWbDqSBwYXJhIHVuIHNvbG8gYcOxbzoNCmBgYHtyfQ0KYmlucyA8LSBjKDAsIDI1MCwgNTAwLCAxMDAwLCAyMDAwLCA1MDAwLCAxMDAwMCwgMTUwMDApDQpwYWwgPC0gY29sb3JCaW4oIkJ1UHUiLCBkb21haW4gPSBjYXVfbXVuaWNfc3RhdCRQcm9kdWNjaW9uXzEyLCBiaW5zID0gYmlucykNCg0KICBtYXBhIDwtIGxlYWZsZXQoZGF0YSA9IGNhdV9tdW5pY19zdGF0KSAlPiUNCiAgYWRkVGlsZXMoKSAlPiUNCiAgYWRkUG9seWdvbnMobGFiZWwgPSB+VE9OX1BST0RfMTIsIA0KICAgICAgICAgICAgICBwb3B1cCA9IH5NUElPX0NOTUJSLA0KICAgICAgICAgICAgICBmaWxsQ29sb3IgPSB+cGFsKFRPTl9QUk9EXzEyKSwNCiAgICAgICAgICAgICAgY29sb3IgPSAiIzQ0NDQ0NCIsDQogICAgICAgICAgICAgIHdlaWdodCA9IDEsDQogICAgICAgICAgICAgIHNtb290aEZhY3RvciA9IDAuNSwNCiAgICAgICAgICAgICAgb3BhY2l0eSA9IDEuMCwNCiAgICAgICAgICAgICAgZmlsbE9wYWNpdHkgPSAwLjUsDQogICAgICAgICAgICAgIGhpZ2hsaWdodE9wdGlvbnMgPSBoaWdobGlnaHRPcHRpb25zKGNvbG9yID0gIndoaXRlIiwgd2VpZ2h0ID0gMiwgYnJpbmdUb0Zyb250ID0gVFJVRSkNCiAgICAgICAgICAgICAgKSAlPiUNCiAgYWRkUHJvdmlkZXJUaWxlcyhwcm92aWRlcnMkT3BlblN0cmVldE1hcCkgJT4lDQogIGFkZExlZ2VuZCgiYm90dG9tcmlnaHQiLCBwYWwgPSBwYWwsIHZhbHVlcyA9IH5UT05fUFJPRF8xMiwNCiAgICB0aXRsZSA9ICJQcm9kdWNjacOzbiBkZSBjYWbDqSBlbiBDYXVjYSBbVG9uXSAoMjAxOCkiLA0KICAgIG9wYWNpdHkgPSAxDQogICkNCmBgYA0KYGBge3J9DQptYXBhICANCmBgYA0KDQpgYGB7cn0NCnNlc3Npb25JbmZvKCkgDQpgYGANCg0KDQoNCg0K