1. Introducción

Este cuaderno de R tiene como objetivo presentar las estadísticas agrícolas del departamento de Boyacá, Colombia a través de representaciones gráficas y textuales. Por medio de este se conocerán algunas aplicaciones de la geomática en la agronomía.

knitr::opts_chunk$set(echo = TRUE)

2. Funciones de GIS

Los datos no espaciales de una región no permiten un gran análisis sin realizar un tratamiento estadístico. Por ello, es importante hacer uso de las librerías “dplyr” y “tidyverse” que son de gran utilidad para explorar y resumir estadísticas. Por otro lado, las operaciones geoespaciales sirven para comprender lo que sucede a nivel territorial. Por ejemplo, buscar la ubicación de los municipios con rendimientos más altos. Para hacer este tipo de operaciones se deben unir los datos espaciales con los datos no espaciales. 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.

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)
library(tidyverse)
library(rgeos)
library(maptools)
library(raster)
library(sf)
library(viridis)
library(rnaturalearth)
library(GSODR)
library(ggrepel)
library(cowplot)

3. Explorando las estadísticas agrícolas en Boyacá

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 Boyacá. Guardé el archivo con las filas restantes como un archivo local con el nombre EVA_Boyaca.csv A partir de la función “read.csv” se lee dicho archivo.

datos <- read_csv2("C:/Users/David Perdomo/Desktop/Geomatica/DOCS GEO/EVA_Boyaca.csv")
Using ',' as decimal and '.' as grouping mark. Use read_delim() for more control.
Parsed with column specification:
cols(
  COD_DEP = col_double(),
  DEPARTAMENTO = col_character(),
  COD_MUN = col_double(),
  MUNICIPIO = col_character(),
  GRUPO = col_character(),
  SUBGRUPO = col_character(),
  CULTIVO = col_character(),
  `DESAGREGACION REGIONAL Y/O SISTEMA PRODUCTIVO` = col_character(),
  YEAR = col_double(),
  PERIODO = col_character(),
  Area_Sembrada = col_double(),
  Area_Cosechada = col_double(),
  produccion = col_double(),
  rendimiento = col_double(),
  `ESTADO FISICO PRODUCCION` = col_character(),
  `NOMBRE 
CIENTIFICO` = col_character(),
  `CICLO DE CULTIVO` = col_character()
)
28 parsing failures.
 row        col               expected actual                                                               file
3724 produccion no trailing characters   .268 'C:/Users/David Perdomo/Desktop/Geomatica/DOCS GEO/EVA_Boyaca.csv'
3758 produccion no trailing characters   .272 'C:/Users/David Perdomo/Desktop/Geomatica/DOCS GEO/EVA_Boyaca.csv'
3837 produccion no trailing characters   .457 'C:/Users/David Perdomo/Desktop/Geomatica/DOCS GEO/EVA_Boyaca.csv'
3884 produccion no trailing characters   .527 'C:/Users/David Perdomo/Desktop/Geomatica/DOCS GEO/EVA_Boyaca.csv'
3977 produccion no trailing characters   .665 'C:/Users/David Perdomo/Desktop/Geomatica/DOCS GEO/EVA_Boyaca.csv'
.... .......... ...................... ...... ..................................................................
See problems(...) for more details.
head(datos)
tail(datos)

Tenga en cuenta que cada municipio tiene 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(MUNICIPIO, GRUPO) %>%
  summarise(rend_prom = mean(rendimiento, na.rm = TRUE)) -> rend_resumen
`summarise()` regrouping output by 'MUNICIPIO' (override with `.groups` argument)
head(rend_resumen)

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

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

Nótese que los mayores rendimientos corresponden a HORTALIZAS, FRUTALES y OTROS PERMANTES. Luego, busquemos cuáles son los municipios con mayor rendimiento para cada grupo de cultivos en 2018:

datos %>% 
  filter(YEAR==2018) %>% 
  group_by(GRUPO, MUNICIPIO) %>%
  summarize(max_rend = max(rendimiento, na.rm = TRUE)) %>%
    slice(which.max(max_rend)) -> rend_max_18
`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, MUNICIPIO) %>%
  summarize(max_area_cosechada = max(Area_Cosechada, na.rm = TRUE)) %>%
    slice(which.max(max_area_cosechada)) -> area_cosechada_max
`summarise()` regrouping output by 'GRUPO' (override with `.groups` argument)
area_cosechada_max

Nótese que la mayor superficie cosechada en 2018 correspondió a TUBERCULOS Y PLATANOS en CHIQUIZA. Quizás sepa que la economía de Maripi se basa se basa en la agricultura, la ganadería, la minería y el comercio. Entre los productos agrícolas del área ubicada en los pisos térmicos templado y cálido, se destaca la caña de azúcar, los cítricos, la yuca, el plátano y el Café Maripí ha sido reconocido a nivel regional por ser uno de los mayores productores de miel y panela, gracias a la calidad y cantidad de estos productos

Primero, seleccionemos la producción de Caña (toneladas) en Maripi para cada año

datos %>% 
  filter(MUNICIPIO=="CHIQUIZA" & SUBGRUPO=="PAPA") %>% 
  group_by(YEAR, CULTIVO) ->  chiquiza_papa

chiquiza_papa

Hagamos una exploración gráfica básica:

g <- ggplot(aes(x=YEAR, y=produccion/1000), data =chiquiza_papa) + geom_bar(stat='identity') + labs(y='Produccion de PAPA [Ton x 1000]', x='AÑO')
g + ggtitle("Evolución de la producción de papa en Chiquiza de 2007 a 2018 ") + labs(caption= "Basado en el Ministerio de Agricultura y Desarrollo Rural. 2019.")

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

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

Podemos ver que TUBERCULOS Y PLATANOS tuvieron la mayor proporción de área cosechada en 2018 para Boyacá.

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

datos %>%
  filter(GRUPO=="TUBERCULOS Y PLATANOS" & YEAR==2018) %>%
  group_by(CULTIVO) %>%
  summarize(sum_cosechada = sum(Area_Cosechada, na.rm = TRUE)) %>%
     arrange(desc(sum_cosechada)) -> total_cosechada
`summarise()` ungrouping output (override with `.groups` argument)
total_cosechada

Ahora, veamos cuáles son los municipios con mayor área cosechada por cada cultivo de TUBERCULOS Y PLATANOS en 2018:

datos %>% 
  filter(YEAR==2018 & GRUPO=="TUBERCULOS Y PLATANOS") %>% 
  group_by(CULTIVO, MUNICIPIO) %>%
  summarize(max_area2 = max(Area_Cosechada, 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 de TUBERCULOS Y PLATANOS. Antes de graficar, necesitaremos agregar, al objeto total_area_cosechada, un nuevo campo con abreviaturas para cada GRUPO de cultivos. De lo contrario, la trama se verá desordenada.

total_area_cosechada$CROP <- abbreviate(total_area_cosechada$GRUPO, 3)
g <- ggplot(aes(x=CROP, y=sum_area_cosechada), data = total_area_cosechada) + geom_bar(stat='identity') + labs(y='Área cosechadada total [Ha]')
g+ ggtitle("Área cosechada total por grupos de cultivos en 2018 para Boyacá") + theme(plot.title = element_text(hjust = 0.5)) +
   labs(caption= "Basado en el Ministerio de Agricultura y Desarrollo Rural. 2019.")

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

utilizar el shapefile correspondiente a Marco Geoestadistico Departamental que se encuentra disponible en DANE Geoportal.

Comencemos a leer los datos usando la biblioteca sf:

ant_munic <- sf::st_read("C:/Users/David Perdomo/Desktop/Geomatica/15_BOYACA/ADMINISTRATIVO/MGN_MPIO_POLITICO.shp")
Reading layer `MGN_MPIO_POLITICO' from data source `C:\Users\David Perdomo\Desktop\Geomatica\15_BOYACA\ADMINISTRATIVO\MGN_MPIO_POLITICO.shp' using driver `ESRI Shapefile'
Simple feature collection with 123 features and 9 fields
geometry type:  POLYGON
dimension:      XY
bbox:           xmin: -74.66496 ymin: 4.655196 xmax: -71.94885 ymax: 7.055557
geographic CRS: WGS 84
ant_munic
Simple feature collection with 123 features and 9 fields
geometry type:  POLYGON
dimension:      XY
bbox:           xmin: -74.66496 ymin: 4.655196 xmax: -71.94885 ymax: 7.055557
geographic CRS: WGS 84
First 10 features:
   DPTO_CCDGO MPIO_CCDGO MPIO_CNMBR
1          15      15001      TUNJA
2          15      15022    ALMEIDA
3          15      15047  AQUITANIA
4          15      15051   ARCABUCO
5          15      15087      BELÉN
6          15      15090     BERBEO
7          15      15092  BETÉITIVA
8          15      15097    BOAVITA
9          15      15104     BOYACÁ
10         15      15106    BRICEÑO
                             MPIO_CRSLC MPIO_NAREA MPIO_NANO
1                                  1541  119.68957      2017
2                                  1908   57.67212      2017
3                                  1789  942.14660      2017
4                                  1856  137.89859      2017
5                                  1756  163.08822      2017
6       Ordenanza 28 de Abril 9 de 1913   58.01301      2017
7                                  1754  101.89955      2017
8                                  1613  145.30529      2017
9                                  1537   48.02287      2017
10 Ordenanza 14 del 25 de Julio de 1890   64.59970      2017
   DPTO_CNMBR Shape_Leng  Shape_Area
1      BOYACÁ  0.5723744 0.009766301
2      BOYACÁ  0.3484692 0.004701759
3      BOYACÁ  1.8003115 0.076843504
4      BOYACÁ  0.7527090 0.011256738
5      BOYACÁ  0.6293489 0.013314920
6      BOYACÁ  0.4291743 0.004730850
7      BOYACÁ  0.4738184 0.008317810
8      BOYACÁ  0.6597822 0.011867743
9      BOYACÁ  0.3256140 0.003918022
10     BOYACÁ  0.4849753 0.005273255
                         geometry
1  POLYGON ((-73.34014 5.58308...
2  POLYGON ((-73.36793 5.01349...
3  POLYGON ((-72.76242 5.63856...
4  POLYGON ((-73.50487 5.84347...
5  POLYGON ((-72.91692 6.08612...
6  POLYGON ((-73.0677 5.27048,...
7  POLYGON ((-72.81796 5.97422...
8  POLYGON ((-72.64907 6.43640...
9  POLYGON ((-73.34806 5.47411...
10 POLYGON ((-73.89118 5.73749...

Para unir la información de las estadísticas agrícolas y la información municipal, inicialmente debemos generar un atributo en común entre ambos archivos, el cual, por conveniencia, será el código de cada municipio 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:

datos_2 <- datos
datos_2$TEMP <-  as.character(datos_2$COD_MUN)
datos_2$MPIO_CCDGO <- as.factor(datos_2$TEMP)
datos_2
datos_2 %>% filter(CULTIVO == "PAPA")  -> datos_3
datos_3
class(datos_3)
[1] "spec_tbl_df" "tbl_df"      "tbl"         "data.frame" 
datos_4 <- datos_3 %>% dplyr::select(MUNICIPIO, MPIO_CCDGO, YEAR, produccion, rendimiento) 
datos_4 %>% 
  gather("YEAR", "produccion", "rendimiento" , key = variable, value = number)
datos_4

Ésta es una tarea clave. Implica varios pasos para poder convertir la tabla de atributos de formato largo a formato ancho.

datos_4 %>% 
  group_by(MPIO_CCDGO) %>% 
  mutate(Visit = 1:n()) %>% 
  gather("YEAR", "produccion", "rendimiento", key = variable, value = number) %>% 
  unite(combi, variable, Visit) %>%
  spread(combi, number) -> datos_5
datos_5

Se realiza una copia de los datos originales por si se da la situacion de realizar algún cambio:

ant_munic2 <- ant_munic
ant_munic_stat =left_join(ant_munic2, datos_5, by="MPIO_CCDGO")
summary(ant_munic_stat)
  DPTO_CCDGO         MPIO_CCDGO         MPIO_CNMBR       
 Length:124         Length:124         Length:124        
 Class :character   Class :character   Class :character  
 Mode  :character   Mode  :character   Mode  :character  
                                                         
                                                         
                                                         
  MPIO_CRSLC          MPIO_NAREA        MPIO_NANO   
 Length:124         Min.   :  25.35   Min.   :2017  
 Class :character   1st Qu.:  64.43   1st Qu.:2017  
 Mode  :character   Median : 122.35   Median :2017  
                    Mean   : 187.31   Mean   :2017  
                    3rd Qu.: 201.57   3rd Qu.:2017  
                    Max.   :1513.60   Max.   :2017  
  DPTO_CNMBR          Shape_Leng       Shape_Area      
 Length:124         Min.   :0.2045   Min.   :0.002069  
 Class :character   1st Qu.:0.3861   1st Qu.:0.005259  
 Mode  :character   Median :0.5308   Median :0.009990  
                    Mean   :0.6347   Mean   :0.015287  
                    3rd Qu.:0.7495   3rd Qu.:0.016435  
                    Max.   :2.4039   Max.   :0.123610  
  MUNICIPIO          produccion_1    produccion_10    
 Length:124         Min.   :  1.08   Min.   :  1.008  
 Class :character   1st Qu.:  3.23   1st Qu.:  3.868  
 Mode  :character   Median : 11.00   Median : 23.451  
                    Mean   :167.64   Mean   :148.657  
                    3rd Qu.:191.50   3rd Qu.:203.000  
                    Max.   :960.00   Max.   :960.000  
 produccion_11     produccion_12     produccion_13    
 Min.   :  1.027   Min.   :  1.050   Min.   :  1.140  
 1st Qu.:  3.315   1st Qu.:  4.004   1st Qu.:  3.703  
 Median : 25.252   Median : 16.564   Median : 15.050  
 Mean   :158.639   Mean   :142.317   Mean   :147.038  
 3rd Qu.:197.000   3rd Qu.:160.000   3rd Qu.:172.500  
 Max.   :960.000   Max.   :900.000   Max.   :960.000  
 produccion_14     produccion_15     produccion_16   
 Min.   :  1.000   Min.   :  1.140   Min.   :  1.00  
 1st Qu.:  5.616   1st Qu.:  3.721   1st Qu.:  6.18  
 Median : 18.000   Median : 22.500   Median : 28.50  
 Mean   :156.517   Mean   :161.383   Mean   :169.71  
 3rd Qu.:192.000   3rd Qu.:180.000   3rd Qu.:246.50  
 Max.   :893.000   Max.   :900.000   Max.   :990.00  
 produccion_17     produccion_18    produccion_19      
 Min.   :  1.105   Min.   :  1.20   Min.   :      1.0  
 1st Qu.:  4.062   1st Qu.:  2.80   1st Qu.:      3.8  
 Median : 33.505   Median : 15.97   Median :     27.0  
 Mean   :185.834   Mean   :136.22   Mean   :  21835.8  
 3rd Qu.:239.500   3rd Qu.:150.00   3rd Qu.:    318.8  
 Max.   :999.000   Max.   :960.00   Max.   :1560094.0  
  produccion_2     produccion_20    produccion_21   
 Min.   :  1.120   Min.   :  1.00   Min.   :  1.02  
 1st Qu.:  3.185   1st Qu.:  3.40   1st Qu.:  3.60  
 Median : 13.500   Median : 20.77   Median : 24.00  
 Mean   :163.421   Mean   :117.88   Mean   :121.31  
 3rd Qu.:158.500   3rd Qu.:150.00   3rd Qu.:150.00  
 Max.   :980.000   Max.   :750.00   Max.   :936.00  
 produccion_22     produccion_23     produccion_24    
 Min.   :  1.248   Min.   :  1.014   Min.   :  1.040  
 1st Qu.:  4.150   1st Qu.:  3.506   1st Qu.:  3.058  
 Median : 28.000   Median : 15.650   Median : 20.400  
 Mean   :159.403   Mean   :102.551   Mean   : 96.924  
 3rd Qu.:233.500   3rd Qu.:130.500   3rd Qu.: 63.000  
 Max.   :960.000   Max.   :780.000   Max.   :900.000  
 produccion_25   produccion_26   produccion_27   
 Min.   :  1.5   Min.   :  1.2   Min.   :  1.35  
 1st Qu.: 37.5   1st Qu.: 10.0   1st Qu.:  9.50  
 Median :100.0   Median : 80.0   Median : 53.00  
 Mean   :206.9   Mean   :157.5   Mean   :166.75  
 3rd Qu.:348.5   3rd Qu.:234.0   3rd Qu.:195.00  
 Max.   :675.0   Max.   :700.0   Max.   :864.00  
 produccion_28    produccion_29     produccion_3   
 Min.   :  1.47   Min.   :  1.35   Min.   :  1.00  
 1st Qu.: 29.00   1st Qu.: 30.75   1st Qu.:  4.68  
 Median : 54.00   Median : 89.00   Median : 24.12  
 Mean   :216.88   Mean   :188.18   Mean   :180.94  
 3rd Qu.:369.50   3rd Qu.:266.25   3rd Qu.:199.00  
 Max.   :936.00   Max.   :900.00   Max.   :980.00  
 produccion_30   produccion_31    produccion_32   
 Min.   :  1.2   Min.   :  8.00   Min.   :  1.00  
 1st Qu.: 25.0   1st Qu.: 41.25   1st Qu.:  9.75  
 Median : 72.0   Median :130.50   Median : 51.50  
 Mean   :190.0   Mean   :241.01   Mean   :167.23  
 3rd Qu.:204.0   3rd Qu.:375.00   3rd Qu.:207.50  
 Max.   :954.0   Max.   :825.00   Max.   :918.00  
 produccion_33    produccion_34    produccion_35  
 Min.   :  1.25   Min.   :  1.58   Min.   :  1.4  
 1st Qu.: 30.00   1st Qu.: 26.71   1st Qu.: 15.6  
 Median : 80.00   Median : 73.00   Median : 67.0  
 Mean   :210.56   Mean   :252.18   Mean   :199.9  
 3rd Qu.:200.00   3rd Qu.:444.25   3rd Qu.:270.0  
 Max.   :846.00   Max.   :900.00   Max.   :780.0  
 produccion_36    produccion_37   produccion_38   
 Min.   :  1.20   Min.   :  2.8   Min.   :  1.40  
 1st Qu.: 11.21   1st Qu.: 24.0   1st Qu.: 28.75  
 Median : 70.00   Median :139.0   Median : 70.00  
 Mean   :193.71   Mean   :265.1   Mean   :177.31  
 3rd Qu.:360.00   3rd Qu.:517.5   3rd Qu.:290.00  
 Max.   :648.00   Max.   :740.0   Max.   :576.00  
 produccion_39     produccion_4      produccion_40   
 Min.   :  2.80   Min.   :    1.02   Min.   :  1.40  
 1st Qu.: 20.32   1st Qu.:    4.65   1st Qu.: 49.95  
 Median : 49.50   Median :   25.00   Median : 76.00  
 Mean   :122.51   Mean   :  323.77   Mean   :220.65  
 3rd Qu.:116.25   3rd Qu.:  165.00   3rd Qu.:472.50  
 Max.   :540.00   Max.   :15600.00   Max.   :550.00  
 produccion_41    produccion_42   produccion_43  
 Min.   :  3.40   Min.   :  1.4   Min.   :  3.4  
 1st Qu.: 35.38   1st Qu.:112.0   1st Qu.: 75.0  
 Median :150.00   Median :420.0   Median :420.0  
 Mean   :250.02   Mean   :311.9   Mean   :290.5  
 3rd Qu.:343.00   3rd Qu.:450.0   3rd Qu.:450.0  
 Max.   :840.00   Max.   :576.0   Max.   :504.0  
 produccion_44   produccion_45   produccion_46  produccion_5   
 Min.   : 60.0   Min.   : 75.0   Min.   :518   Min.   :  1.00  
 1st Qu.:270.0   1st Qu.:178.8   1st Qu.:518   1st Qu.:  4.68  
 Median :480.0   Median :282.5   Median :518   Median : 20.00  
 Mean   :343.3   Mean   :282.5   Mean   :518   Mean   :134.03  
 3rd Qu.:485.0   3rd Qu.:386.2   3rd Qu.:518   3rd Qu.:171.00  
 Max.   :490.0   Max.   :490.0   Max.   :518   Max.   :990.00  
  produccion_6      produccion_7     produccion_8    
 Min.   :  1.080   Min.   :  1.00   Min.   :  1.035  
 1st Qu.:  4.535   1st Qu.:  3.12   1st Qu.:  3.945  
 Median : 25.220   Median : 30.00   Median : 24.000  
 Mean   :143.545   Mean   :152.07   Mean   :139.103  
 3rd Qu.:187.500   3rd Qu.:217.50   3rd Qu.:161.000  
 Max.   :840.000   Max.   :960.00   Max.   :980.000  
  produccion_9     rendimiento_1    rendimiento_10  
 Min.   :  1.000   Min.   :   3.0   Min.   :   5.0  
 1st Qu.:  3.184   1st Qu.:  12.0   1st Qu.:  12.0  
 Median : 21.940   Median :  16.0   Median :  16.5  
 Mean   :153.358   Mean   : 342.6   Mean   : 411.7  
 3rd Qu.:204.250   3rd Qu.: 124.5   3rd Qu.: 148.0  
 Max.   :975.000   Max.   :2268.0   Max.   :4455.0  
 rendimiento_11   rendimiento_12   rendimiento_13  
 Min.   :   5.0   Min.   :   5.0   Min.   :   6.0  
 1st Qu.:  12.0   1st Qu.:  12.0   1st Qu.:  12.0  
 Median :  15.0   Median :  15.0   Median :  15.0  
 Mean   : 255.8   Mean   : 157.4   Mean   : 129.3  
 3rd Qu.:  85.0   3rd Qu.:  25.0   3rd Qu.:  20.0  
 Max.   :2457.0   Max.   :2932.0   Max.   :2176.0  
 rendimiento_14    rendimiento_15   rendimiento_16   
 Min.   :   4.00   Min.   :   4.0   Min.   :   3.00  
 1st Qu.:  10.00   1st Qu.:  12.0   1st Qu.:  12.00  
 Median :  15.00   Median :  15.0   Median :  15.00  
 Mean   :  63.57   Mean   : 134.7   Mean   :  58.99  
 3rd Qu.:  20.00   3rd Qu.:  22.0   3rd Qu.:  20.00  
 Max.   :1978.00   Max.   :2248.0   Max.   :1375.00  
 rendimiento_17   rendimiento_18   rendimiento_19  
 Min.   :   6.0   Min.   :   1.0   Min.   :   6.0  
 1st Qu.:  12.0   1st Qu.:  12.0   1st Qu.:  12.0  
 Median :  15.0   Median :  15.0   Median :  15.0  
 Mean   : 224.7   Mean   : 161.7   Mean   : 115.7  
 3rd Qu.:  25.0   3rd Qu.:  25.0   3rd Qu.:  20.0  
 Max.   :3011.0   Max.   :2967.0   Max.   :2375.0  
 rendimiento_2    rendimiento_20   rendimiento_21  
 Min.   :   3.0   Min.   :   4.0   Min.   :   4.0  
 1st Qu.:  12.0   1st Qu.:  12.0   1st Qu.:  12.0  
 Median :  15.0   Median :  16.0   Median :  16.0  
 Mean   : 384.5   Mean   : 205.6   Mean   : 202.1  
 3rd Qu.: 134.5   3rd Qu.:  25.0   3rd Qu.:  24.0  
 Max.   :2127.0   Max.   :2729.0   Max.   :3491.0  
 rendimiento_22    rendimiento_23   rendimiento_24  
 Min.   :   4.00   Min.   :   5.0   Min.   :   5.0  
 1st Qu.:  12.75   1st Qu.:  12.0   1st Qu.:  12.0  
 Median :  18.00   Median :  18.0   Median :  17.5  
 Mean   : 228.84   Mean   : 204.4   Mean   : 239.2  
 3rd Qu.:  30.00   3rd Qu.:  25.0   3rd Qu.:  24.0  
 Max.   :2707.00   Max.   :2473.0   Max.   :2708.0  
 rendimiento_25   rendimiento_26    rendimiento_27 
 Min.   :   5.0   Min.   :   4.00   Min.   : 2.00  
 1st Qu.:   9.5   1st Qu.:   9.00   1st Qu.: 8.75  
 Median :  12.0   Median :  12.00   Median :12.50  
 Mean   : 119.9   Mean   :  85.62   Mean   :14.88  
 3rd Qu.:  16.5   3rd Qu.:  15.00   3rd Qu.:16.50  
 Max.   :2125.0   Max.   :2126.00   Max.   :64.00  
 rendimiento_28  rendimiento_29  rendimiento_3   
 Min.   : 2.00   Min.   : 4.00   Min.   :   4.0  
 1st Qu.: 6.50   1st Qu.: 6.50   1st Qu.:  12.0  
 Median :10.00   Median :10.00   Median :  15.0  
 Mean   :14.26   Mean   :13.41   Mean   : 297.7  
 3rd Qu.:17.00   3rd Qu.:15.00   3rd Qu.: 152.0  
 Max.   :64.00   Max.   :64.00   Max.   :2133.0  
 rendimiento_30  rendimiento_31  rendimiento_32 
 Min.   : 4.00   Min.   : 5.00   Min.   : 4.00  
 1st Qu.: 7.50   1st Qu.: 8.00   1st Qu.: 6.50  
 Median :10.00   Median : 9.00   Median : 9.00  
 Mean   :11.15   Mean   :14.00   Mean   :13.50  
 3rd Qu.:15.00   3rd Qu.:15.75   3rd Qu.:14.25  
 Max.   :21.00   Max.   :75.00   Max.   :75.00  
 rendimiento_33  rendimiento_34    rendimiento_35   
 Min.   : 4.00   Min.   :   4.00   Min.   :   4.00  
 1st Qu.: 7.00   1st Qu.:   6.75   1st Qu.:   7.00  
 Median : 9.00   Median :  10.00   Median :  11.00  
 Mean   :14.06   Mean   :  83.06   Mean   : 121.00  
 3rd Qu.:13.00   3rd Qu.:  13.75   3rd Qu.:  12.25  
 Max.   :85.00   Max.   :1014.00   Max.   :1784.00  
 rendimiento_36  rendimiento_37  rendimiento_38 
 Min.   : 4.00   Min.   : 4.00   Min.   : 4.00  
 1st Qu.:10.00   1st Qu.: 8.00   1st Qu.: 9.00  
 Median :10.00   Median :10.00   Median :10.00  
 Mean   :10.92   Mean   :11.83   Mean   :12.36  
 3rd Qu.:12.00   3rd Qu.:13.50   3rd Qu.:15.00  
 Max.   :19.00   Max.   :25.00   Max.   :25.00  
 rendimiento_39  rendimiento_4    rendimiento_40 
 Min.   : 5.00   Min.   :   5.0   Min.   : 8.00  
 1st Qu.: 8.00   1st Qu.:  12.0   1st Qu.: 9.50  
 Median :12.50   Median :  15.0   Median :12.50  
 Mean   :12.38   Mean   : 420.1   Mean   :13.00  
 3rd Qu.:15.75   3rd Qu.: 449.0   3rd Qu.:15.75  
 Max.   :20.00   Max.   :3091.0   Max.   :20.00  
 rendimiento_41   rendimiento_42 rendimiento_43 rendimiento_44 
 Min.   :  8.00   Min.   :12.0   Min.   :12     Min.   :12.00  
 1st Qu.: 12.50   1st Qu.:14.0   1st Qu.:15     1st Qu.:13.00  
 Median : 15.00   Median :15.0   Median :15     Median :14.00  
 Mean   : 37.29   Mean   :15.8   Mean   :16     Mean   :13.67  
 3rd Qu.: 19.00   3rd Qu.:18.0   3rd Qu.:18     3rd Qu.:14.50  
 Max.   :175.00   Max.   :20.0   Max.   :20     Max.   :15.00  
 rendimiento_45  rendimiento_46 rendimiento_5   
 Min.   :14.00   Min.   :14     Min.   :   3.0  
 1st Qu.:14.25   1st Qu.:14     1st Qu.:  12.0  
 Median :14.50   Median :14     Median :  15.0  
 Mean   :14.50   Mean   :14     Mean   : 365.8  
 3rd Qu.:14.75   3rd Qu.:14     3rd Qu.: 135.0  
 Max.   :15.00   Max.   :14     Max.   :2187.0  
 rendimiento_6    rendimiento_7    rendimiento_8   
 Min.   :   5.0   Min.   :   5.0   Min.   :   5.0  
 1st Qu.:  12.0   1st Qu.:  12.0   1st Qu.:  12.0  
 Median :  15.0   Median :  15.0   Median :  16.0  
 Mean   : 406.2   Mean   : 363.7   Mean   : 266.4  
 3rd Qu.: 129.0   3rd Qu.: 125.0   3rd Qu.: 114.0  
 Max.   :2786.0   Max.   :2302.0   Max.   :2549.0  
 rendimiento_9        YEAR_1        YEAR_10        YEAR_11    
 Min.   :   2.0   Min.   :2006   Min.   :2009   Min.   :2010  
 1st Qu.:  12.0   1st Qu.:2006   1st Qu.:2011   1st Qu.:2011  
 Median :  16.0   Median :2006   Median :2011   Median :2011  
 Mean   : 247.2   Mean   :2006   Mean   :2012   Mean   :2012  
 3rd Qu.:  40.5   3rd Qu.:2006   3rd Qu.:2012   3rd Qu.:2013  
 Max.   :2578.0   Max.   :2015   Max.   :2018   Max.   :2018  
    YEAR_12        YEAR_13        YEAR_14        YEAR_15    
 Min.   :2010   Min.   :2011   Min.   :2011   Min.   :2012  
 1st Qu.:2012   1st Qu.:2012   1st Qu.:2013   1st Qu.:2013  
 Median :2012   Median :2012   Median :2013   Median :2013  
 Mean   :2013   Mean   :2013   Mean   :2014   Mean   :2014  
 3rd Qu.:2013   3rd Qu.:2014   3rd Qu.:2014   3rd Qu.:2015  
 Max.   :2018   Max.   :2018   Max.   :2017   Max.   :2018  
    YEAR_16        YEAR_17        YEAR_18        YEAR_19    
 Min.   :2012   Min.   :2007   Min.   :2008   Min.   :2006  
 1st Qu.:2014   1st Qu.:2014   1st Qu.:2015   1st Qu.:2015  
 Median :2014   Median :2014   Median :2015   Median :2015  
 Mean   :2015   Mean   :2015   Mean   :2015   Mean   :2015  
 3rd Qu.:2015   3rd Qu.:2015   3rd Qu.:2016   3rd Qu.:2016  
 Max.   :2018   Max.   :2018   Max.   :2018   Max.   :2018  
     YEAR_2        YEAR_20        YEAR_21        YEAR_22    
 Min.   :2007   Min.   :2007   Min.   :2009   Min.   :2007  
 1st Qu.:2007   1st Qu.:2016   1st Qu.:2016   1st Qu.:2017  
 Median :2007   Median :2016   Median :2016   Median :2017  
 Mean   :2007   Mean   :2016   Mean   :2016   Mean   :2017  
 3rd Qu.:2007   3rd Qu.:2016   3rd Qu.:2017   3rd Qu.:2017  
 Max.   :2016   Max.   :2018   Max.   :2018   Max.   :2018  
    YEAR_23        YEAR_24        YEAR_25        YEAR_26    
 Min.   :2006   Min.   :2006   Min.   :2006   Min.   :2007  
 1st Qu.:2017   1st Qu.:2017   1st Qu.:2007   1st Qu.:2008  
 Median :2017   Median :2018   Median :2009   Median :2009  
 Mean   :2016   Mean   :2016   Mean   :2011   Mean   :2011  
 3rd Qu.:2017   3rd Qu.:2018   3rd Qu.:2014   3rd Qu.:2013  
 Max.   :2018   Max.   :2018   Max.   :2018   Max.   :2018  
    YEAR_27        YEAR_28        YEAR_29         YEAR_3    
 Min.   :2007   Min.   :2008   Min.   :2008   Min.   :2007  
 1st Qu.:2009   1st Qu.:2009   1st Qu.:2010   1st Qu.:2007  
 Median :2010   Median :2010   Median :2011   Median :2007  
 Mean   :2011   Mean   :2011   Mean   :2012   Mean   :2007  
 3rd Qu.:2013   3rd Qu.:2014   3rd Qu.:2015   3rd Qu.:2007  
 Max.   :2018   Max.   :2017   Max.   :2018   Max.   :2014  
    YEAR_30        YEAR_31        YEAR_32        YEAR_33    
 Min.   :2009   Min.   :2009   Min.   :2010   Min.   :2010  
 1st Qu.:2010   1st Qu.:2012   1st Qu.:2011   1st Qu.:2012  
 Median :2011   Median :2013   Median :2013   Median :2013  
 Mean   :2012   Mean   :2013   Mean   :2014   Mean   :2014  
 3rd Qu.:2014   3rd Qu.:2015   3rd Qu.:2016   3rd Qu.:2017  
 Max.   :2017   Max.   :2017   Max.   :2017   Max.   :2018  
    YEAR_34        YEAR_35        YEAR_36        YEAR_37    
 Min.   :2012   Min.   :2012   Min.   :2013   Min.   :2013  
 1st Qu.:2013   1st Qu.:2014   1st Qu.:2014   1st Qu.:2015  
 Median :2015   Median :2014   Median :2015   Median :2016  
 Mean   :2015   Mean   :2015   Mean   :2015   Mean   :2016  
 3rd Qu.:2016   3rd Qu.:2016   3rd Qu.:2017   3rd Qu.:2017  
 Max.   :2018   Max.   :2018   Max.   :2017   Max.   :2018  
    YEAR_38        YEAR_39         YEAR_4        YEAR_40    
 Min.   :2014   Min.   :2014   Min.   :2007   Min.   :2015  
 1st Qu.:2015   1st Qu.:2015   1st Qu.:2008   1st Qu.:2016  
 Median :2016   Median :2016   Median :2008   Median :2016  
 Mean   :2016   Mean   :2016   Mean   :2008   Mean   :2016  
 3rd Qu.:2018   3rd Qu.:2017   3rd Qu.:2008   3rd Qu.:2017  
 Max.   :2018   Max.   :2017   Max.   :2014   Max.   :2018  
    YEAR_41        YEAR_42        YEAR_43        YEAR_44    
 Min.   :2015   Min.   :2016   Min.   :2016   Min.   :2017  
 1st Qu.:2016   1st Qu.:2016   1st Qu.:2017   1st Qu.:2017  
 Median :2017   Median :2017   Median :2017   Median :2017  
 Mean   :2017   Mean   :2017   Mean   :2017   Mean   :2017  
 3rd Qu.:2018   3rd Qu.:2017   3rd Qu.:2018   3rd Qu.:2018  
 Max.   :2018   Max.   :2017   Max.   :2018   Max.   :2018  
    YEAR_45        YEAR_46         YEAR_5         YEAR_6    
 Min.   :2017   Min.   :2018   Min.   :2008   Min.   :2008  
 1st Qu.:2017   1st Qu.:2018   1st Qu.:2008   1st Qu.:2009  
 Median :2018   Median :2018   Median :2008   Median :2009  
 Mean   :2018   Mean   :2018   Mean   :2009   Mean   :2010  
 3rd Qu.:2018   3rd Qu.:2018   3rd Qu.:2008   3rd Qu.:2009  
 Max.   :2018   Max.   :2018   Max.   :2016   Max.   :2016  
     YEAR_7         YEAR_8         YEAR_9    
 Min.   :2008   Min.   :2009   Min.   :2009  
 1st Qu.:2009   1st Qu.:2010   1st Qu.:2010  
 Median :2009   Median :2010   Median :2010  
 Mean   :2010   Mean   :2011   Mean   :2011  
 3rd Qu.:2010   3rd Qu.:2011   3rd Qu.:2011  
 Max.   :2016   Max.   :2017   Max.   :2017  
          geometry  
 POLYGON      :124  
 epsg:4326    :  0  
 +proj=long...:  0  
                    
                    
                    
 [ reached getOption("max.print") -- omitted 1 row ]

5. Plotting

install.packages("RColorBrewer")
Error in install.packages : Updating loaded packages
library(RColorBrewer)
library(leaflet)

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

bins <- c(0, 250, 500, 1000, 2000, 5000, 10000, 15000)
pal <- colorBin("YlOrRd", domain = ant_munic_stat$produccion_13, bins = bins)

  mapa <- leaflet(data = ant_munic_stat) %>%
  addTiles() %>%
  addPolygons(label = ~produccion_13,
              popup = ~MPIO_CNMBR,
              fillColor = ~pal(produccion_13),
              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 = ~produccion_13,
    title = "Producción de PAPA en Boyacá [Ton] (2018)",
    opacity = 1
  )
mapa

Tenga en cuenta que utilicé tanto etiquetas como ventanas emergentes en este mapa. Ahora trazaremos el rendimiento por municipio.

bins <- c(0, 250, 500, 1000, 2000, 5000, 10000, 15000)
pal <- colorBin("YlOrRd", domain = ant_munic_stat$rendimiento_13, bins = bins)

  mapa2 <- leaflet(data = ant_munic_stat) %>%
  addTiles() %>%
  addPolygons(label = ~rendimiento_13,
              popup = ~MPIO_CNMBR,
              fillColor = ~pal(rendimiento_13),
              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 = ~rendimiento_13,
    title = "Rendimiento de PAPA en Boyacá [Ton] (2018)",
    opacity = 1
  )
mapa2
LS0tDQp0aXRsZTogIkluZm9ybWUgVGVjbmljbyAxLiBFc3RhZGlzdGljYXMgYWdyb3BlY3VhcmlhcyBkZSBCb3lhY8OhIg0KYXV0aG9yOiAiSm9yZ2UgUGVyZG9tbyINCmRhdGU6ICIxMiBkZSBPY3R1YnJlIGRlIDIwMjAiDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KMS4gSW50cm9kdWNjacOzbg0KLS0tDQpFc3RlIGN1YWRlcm5vIGRlIFIgdGllbmUgY29tbyBvYmpldGl2byBwcmVzZW50YXIgbGFzIGVzdGFkw61zdGljYXMgYWdyw61jb2xhcyBkZWwgZGVwYXJ0YW1lbnRvIGRlIEJveWFjw6EsIENvbG9tYmlhIGEgdHJhdsOpcyBkZSByZXByZXNlbnRhY2lvbmVzIGdyw6FmaWNhcyB5IHRleHR1YWxlcy4gDQpQb3IgbWVkaW8gZGUgZXN0ZSBzZSBjb25vY2Vyw6FuIGFsZ3VuYXMgYXBsaWNhY2lvbmVzIGRlIGxhIGdlb23DoXRpY2EgZW4gbGEgYWdyb25vbcOtYS4NCmBgYHtyfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKQ0KYGBgDQoyLiBGdW5jaW9uZXMgZGUgR0lTDQotLS0NCkxvcyBkYXRvcyBubyBlc3BhY2lhbGVzIGRlIHVuYSByZWdpw7NuIG5vIHBlcm1pdGVuIHVuIGdyYW4gYW7DoWxpc2lzIHNpbiByZWFsaXphciB1biB0cmF0YW1pZW50byBlc3RhZMOtc3RpY28uIFBvciBlbGxvLCBlcyBpbXBvcnRhbnRlIGhhY2VyIHVzbyBkZSBsYXMgbGlicmVyw61hcyDigJxkcGx5cuKAnSB5IOKAnHRpZHl2ZXJzZeKAnSBxdWUgc29uIGRlIGdyYW4gdXRpbGlkYWQgcGFyYSBleHBsb3JhciB5IHJlc3VtaXIgZXN0YWTDrXN0aWNhcy4NClBvciBvdHJvIGxhZG8sIGxhcyBvcGVyYWNpb25lcyBnZW9lc3BhY2lhbGVzIHNpcnZlbiBwYXJhIGNvbXByZW5kZXIgbG8gcXVlIHN1Y2VkZSBhIG5pdmVsIHRlcnJpdG9yaWFsLiBQb3IgZWplbXBsbywgYnVzY2FyIGxhIHViaWNhY2nDs24gZGUgbG9zIG11bmljaXBpb3MgY29uIHJlbmRpbWllbnRvcyBtw6FzIGFsdG9zLiBQYXJhIGhhY2VyIGVzdGUgdGlwbyBkZSBvcGVyYWNpb25lcyBzZSBkZWJlbiB1bmlyIGxvcyBkYXRvcyBlc3BhY2lhbGVzIGNvbiBsb3MgZGF0b3Mgbm8gZXNwYWNpYWxlcy4NCkNvbWVuY2Vtb3MgZWxpbWluYW5kbyBlbCBjb250ZW5pZG8gZGUgbGEgbWVtb3JpYToNCmBgYHtyfQ0Kcm0obGlzdD1scygpKQ0KYGBgDQpBaG9yYSwgaW5zdGFsZW1vcyBsYXMgYmlibGlvdGVjYXMgcXVlIG5lY2VzaXRhbW9zLiBUZW5nYSBlbiBjdWVudGEgcXVlLCBlbiBlbCBzaWd1aWVudGUgZnJhZ21lbnRvLCBjdWFscXVpZXIgcGFxdWV0ZSBzZSBpbnN0YWxhIHNvbG8gc2kgbm8gc2UgaGEgaW5zdGFsYWRvIHByZXZpYW1lbnRlLg0KYGBge3J9DQpsaXN0Lm9mLnBhY2thZ2VzIDwtIGMoImhlcmUiLCAidGlkeXZlcnNlIiwgInJnZW9zIiwgIm1hcHRvb2xzIiwgInJhc3RlciIsICJzZiIsICAidmlyaWRpcyIsICJybmF0dXJhbGVhcnRoIiwgIkdTT0RSIiwgImdncmVwZWwiLCAiY293cGxvdCIpDQpuZXcucGFja2FnZXMgPC0gbGlzdC5vZi5wYWNrYWdlc1shKGxpc3Qub2YucGFja2FnZXMgJWluJSBpbnN0YWxsZWQucGFja2FnZXMoKVssIlBhY2thZ2UiXSldDQppZihsZW5ndGgobmV3LnBhY2thZ2VzKSkgaW5zdGFsbC5wYWNrYWdlcyhuZXcucGFja2FnZXMpDQpgYGANCkFob3JhLCBjYXJndWVtb3MgbGFzIGJpYmxpb3RlY2FzLg0KYGBge3J9DQpsaWJyYXJ5KGhlcmUpDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkocmdlb3MpDQpsaWJyYXJ5KG1hcHRvb2xzKQ0KbGlicmFyeShyYXN0ZXIpDQpsaWJyYXJ5KHNmKQ0KbGlicmFyeSh2aXJpZGlzKQ0KbGlicmFyeShybmF0dXJhbGVhcnRoKQ0KbGlicmFyeShHU09EUikNCmxpYnJhcnkoZ2dyZXBlbCkNCmxpYnJhcnkoY293cGxvdCkNCmBgYA0KMy4gRXhwbG9yYW5kbyBsYXMgZXN0YWTDrXN0aWNhcyBhZ3LDrWNvbGFzIGVuIEJveWFjw6ENCi0tLQ0KUHJldmlhbWVudGUsIGhlIGRlc2NhcmdhZG8gZGF0b3MgZXN0YWTDrXN0aWNvcywgZW4gZm9ybWF0byBjc3YsIHNvYnJlIEVzdGFkaXN0aWNhcyBNdW5pY2lwYWxlcyBBZ3JvcGVjdWFyaWFzIGEgbWkgY29tcHV0YWRvcmEuIEx1ZWdvLCBoZSB1c2FkbyBFeGNlbCBwYXJhIGVsaW1pbmFyIGZpbGFzIHBhcmEgbXVuaWNpcGlvcyBlbiBkZXBhcnRhbWVudG9zIGRpZmVyZW50ZXMgYSBCb3lhY8OhLiBHdWFyZMOpIGVsIGFyY2hpdm8gY29uIGxhcyBmaWxhcyByZXN0YW50ZXMgY29tbyB1biBhcmNoaXZvIGxvY2FsIGNvbiBlbCBub21icmUgRVZBX0JveWFjYS5jc3YgDQogQSBwYXJ0aXIgZGUgbGEgZnVuY2nDs24g4oCccmVhZC5jc3bigJ0gc2UgbGVlIGRpY2hvIGFyY2hpdm8uDQpgYGB7cn0NCmRhdG9zIDwtIHJlYWRfY3N2MigiQzovVXNlcnMvRGF2aWQgUGVyZG9tby9EZXNrdG9wL0dlb21hdGljYS9ET0NTIEdFTy9FVkFfQm95YWNhLmNzdiIpDQpgYGANCmBgYHtyfQ0KaGVhZChkYXRvcykNCmBgYA0KYGBge3J9DQp0YWlsKGRhdG9zKQ0KYGBgDQpUZW5nYSBlbiBjdWVudGEgcXVlIGNhZGEgbXVuaWNpcGlvIHRpZW5lIGVzdGFkw61zdGljYXMgc29icmUgc3VwZXJmaWNpZSBzZW1icmFkYSwgc3VwZXJmaWNpZSBjb3NlY2hhZGEgeSByZW5kaW1pZW50byBwYXJhIGRpZmVyZW50ZXMgY3VsdGl2b3MgZW4gZGlmZXJlbnRlcyBhw7Fvcy4gRWwgYXRyaWJ1dG8gU1VCR1JVUE8geSBDVUxUSVZPIHBhcmVjZW4gcmVmZXJpcnNlIGEgbG8gbWlzbW8gKGVzIGRlY2lyLCB1biBjdWx0aXZvKS4gTG9zIGN1bHRpdm9zIHNlIGNsYXNpZmljYW4gYWRlbcOhcyBlbiB1biBHUlVQTyBkZXRlcm1pbmFkby4NCkVuIGVzdGEgdGFibGEsIG5vIHRlbmVtb3MgdW5pZGFkZXMuIFNpbiBlbWJhcmdvLCBzaSByZXZpc2Ftb3MgZWwgYXJjaGl2byBjc3Ygb3JpZ2luYWwsIGVuY29udHJhbW9zIHF1ZSBsYXMgdW5pZGFkZXMgZGUgw6FyZWEgc29uIGhlY3TDoXJlYXMgeSBxdWUgbGFzIHVuaWRhZGVzIGRlIHJlbmRpbWllbnRvIHNvbiBUb24gLyBoYS4NClVzYXJlbW9zIGxhIGJpYmxpb3RlY2EgZHBseXIgcGFyYSBleHBsb3JhciBlbCBjb250ZW5pZG8gZGVsIG9iamV0byBkZSBkYXRvcy4NClByaW1lcm8sIG9idGVuZ2Ftb3MgdW4gcmVzdW1lbiBkZWwgcmVuZGltaWVudG8gKGVzIGRlY2lyLCBlbCByZW5kaW1pZW50byBwcm9tZWRpbyBkdXJhbnRlIHZhcmlvcyBhw7FvcykgcG9yIGdydXBvIHkgbXVuaWNpcGlvOg0KYGBge3J9DQpkYXRvcyAlPiUNCiAgZ3JvdXBfYnkoTVVOSUNJUElPLCBHUlVQTykgJT4lDQogIHN1bW1hcmlzZShyZW5kX3Byb20gPSBtZWFuKHJlbmRpbWllbnRvLCBuYS5ybSA9IFRSVUUpKSAtPiByZW5kX3Jlc3VtZW4NCmhlYWQocmVuZF9yZXN1bWVuKQ0KYGBgDQpUYW1iacOpbiBwb2RlbW9zIGNhbGN1bGFyIGVsIHJlbmRpbWllbnRvIHByb21lZGlvIHBvciBHUlVQTyBlbiBsb3MgbXVuaWNpcGlvcyBkZSBCb3lhY8OhOg0KYGBge3J9DQpkYXRvcyAlPiUNCiAgZ3JvdXBfYnkoR1JVUE8pICU+JQ0KICBzdW1tYXJpc2UocmVuZF9kZXAgPSBtZWFuKHJlbmRpbWllbnRvLCBuYS5ybSA9IFRSVUUpKSAtPiByZW5kX2JveWFjYQ0KDQpyZW5kX2JveWFjYQ0KYGBgDQpOw7N0ZXNlIHF1ZSBsb3MgbWF5b3JlcyByZW5kaW1pZW50b3MgY29ycmVzcG9uZGVuIGEgSE9SVEFMSVpBUywgRlJVVEFMRVMgeSBPVFJPUyBQRVJNQU5URVMuDQpMdWVnbywgYnVzcXVlbW9zIGN1w6FsZXMgc29uIGxvcyBtdW5pY2lwaW9zIGNvbiBtYXlvciByZW5kaW1pZW50byBwYXJhIGNhZGEgZ3J1cG8gZGUgY3VsdGl2b3MgZW4gMjAxODoNCmBgYHtyfQ0KZGF0b3MgJT4lIA0KICBmaWx0ZXIoWUVBUj09MjAxOCkgJT4lIA0KICBncm91cF9ieShHUlVQTywgTVVOSUNJUElPKSAlPiUNCiAgc3VtbWFyaXplKG1heF9yZW5kID0gbWF4KHJlbmRpbWllbnRvLCBuYS5ybSA9IFRSVUUpKSAlPiUNCiAgICBzbGljZSh3aGljaC5tYXgobWF4X3JlbmQpKSAtPiByZW5kX21heF8xOA0KDQpyZW5kX21heF8xOA0KYGBgDQpBaG9yYSwgYnVzcXVlbW9zIGN1w6FsZXMgc29uIGxvcyBtdW5pY2lwaW9zIGNvbiBtYXlvciDDoXJlYSBjb3NlY2hhZGEgcGFyYSBjYWRhIGdydXBvIGRlIGN1bHRpdm9zIGVuIDIwMTg6DQpgYGB7cn0NCmRhdG9zICU+JSANCiAgZmlsdGVyKFlFQVI9PTIwMTgpICU+JSANCiAgZ3JvdXBfYnkoR1JVUE8sIE1VTklDSVBJTykgJT4lDQogIHN1bW1hcml6ZShtYXhfYXJlYV9jb3NlY2hhZGEgPSBtYXgoQXJlYV9Db3NlY2hhZGEsIG5hLnJtID0gVFJVRSkpICU+JQ0KICAgIHNsaWNlKHdoaWNoLm1heChtYXhfYXJlYV9jb3NlY2hhZGEpKSAtPiBhcmVhX2Nvc2VjaGFkYV9tYXgNCg0KYXJlYV9jb3NlY2hhZGFfbWF4DQpgYGANCk7Ds3Rlc2UgcXVlIGxhIG1heW9yIHN1cGVyZmljaWUgY29zZWNoYWRhIGVuIDIwMTggY29ycmVzcG9uZGnDsyBhIFRVQkVSQ1VMT1MgWSBQTEFUQU5PUyBlbiAJQ0hJUVVJWkEuIFF1aXrDoXMgc2VwYSBxdWUgbGEgZWNvbm9tw61hIGRlIE1hcmlwaSBzZSBiYXNhIHNlIGJhc2EgZW4gbGEgYWdyaWN1bHR1cmEsIGxhIGdhbmFkZXLDrWEsIGxhIG1pbmVyw61hIHkgZWwgY29tZXJjaW8uIEVudHJlIGxvcyBwcm9kdWN0b3MgYWdyw61jb2xhcyBkZWwgw6FyZWEgdWJpY2FkYSBlbiBsb3MgcGlzb3MgdMOpcm1pY29zIHRlbXBsYWRvIHkgY8OhbGlkbywgc2UgZGVzdGFjYSBsYSBjYcOxYSBkZSBhesO6Y2FyLCBsb3MgY8OtdHJpY29zLCBsYSB5dWNhLCBlbCBwbMOhdGFubyB5IGVsIENhZsOpDQpNYXJpcMOtIGhhIHNpZG8gcmVjb25vY2lkbyBhIG5pdmVsIHJlZ2lvbmFsIHBvciBzZXIgdW5vIGRlIGxvcyBtYXlvcmVzIHByb2R1Y3RvcmVzIGRlIG1pZWwgeSBwYW5lbGEsIGdyYWNpYXMgYSBsYSBjYWxpZGFkIHkgY2FudGlkYWQgZGUgZXN0b3MgcHJvZHVjdG9zDQoNClByaW1lcm8sIHNlbGVjY2lvbmVtb3MgbGEgcHJvZHVjY2nDs24gZGUgQ2HDsWEgKHRvbmVsYWRhcykgZW4gTWFyaXBpIHBhcmEgY2FkYSBhw7FvDQpgYGB7cn0NCmRhdG9zICU+JSANCiAgZmlsdGVyKE1VTklDSVBJTz09IkNISVFVSVpBIiAmIFNVQkdSVVBPPT0iUEFQQSIpICU+JSANCiAgZ3JvdXBfYnkoWUVBUiwgQ1VMVElWTykgLT4gIGNoaXF1aXphX3BhcGENCg0KY2hpcXVpemFfcGFwYQ0KYGBgDQpIYWdhbW9zIHVuYSBleHBsb3JhY2nDs24gZ3LDoWZpY2EgYsOhc2ljYToNCmBgYHtyfQ0KZyA8LSBnZ3Bsb3QoYWVzKHg9WUVBUiwgeT1wcm9kdWNjaW9uLzEwMDApLCBkYXRhID1jaGlxdWl6YV9wYXBhKSArIGdlb21fYmFyKHN0YXQ9J2lkZW50aXR5JykgKyBsYWJzKHk9J1Byb2R1Y2Npb24gZGUgUEFQQSBbVG9uIHggMTAwMF0nLCB4PSdBw5FPJykNCmBgYA0KYGBge3J9DQpnICsgZ2d0aXRsZSgiRXZvbHVjacOzbiBkZSBsYSBwcm9kdWNjacOzbiBkZSBwYXBhIGVuIENoaXF1aXphIGRlIDIwMDcgYSAyMDE4ICIpICsgbGFicyhjYXB0aW9uPSAiQmFzYWRvIGVuIGVsIE1pbmlzdGVyaW8gZGUgQWdyaWN1bHR1cmEgeSBEZXNhcnJvbGxvIFJ1cmFsLiAyMDE5LiIpDQpgYGANCkFob3JhLCBpbnZlc3RpZ3VlbW9zIHF1w6kgY3VsdGl2b3MgdHV2aWVyb24gbGEgbWF5b3Igw6FyZWEgY29zZWNoYWRhIGVuIDIwMTg6DQpgYGB7cn0NCmRhdG9zICU+JSANCiAgZmlsdGVyKFlFQVI9PTIwMTgpICU+JSANCiAgZ3JvdXBfYnkoR1JVUE8pICU+JQ0KICBzdW1tYXJpemUoc3VtX2FyZWFfY29zZWNoYWRhID0gc3VtKEFyZWFfQ29zZWNoYWRhLCBuYS5ybSA9IFRSVUUpKSAlPiUNCiAgICAgYXJyYW5nZShkZXNjKHN1bV9hcmVhX2Nvc2VjaGFkYSkpIC0+IHRvdGFsX2FyZWFfY29zZWNoYWRhDQoNCnRvdGFsX2FyZWFfY29zZWNoYWRhDQpgYGANClBvZGVtb3MgdmVyIHF1ZSBUVUJFUkNVTE9TIFkgUExBVEFOT1MgdHV2aWVyb24gbGEgbWF5b3IgcHJvcG9yY2nDs24gZGUgw6FyZWEgY29zZWNoYWRhIGVuIDIwMTggcGFyYSBCb3lhY8OhLiANCg0KVGFtYmnDqW4gcG9kZW1vcyBidXNjYXIgZXN0YSBpbmZvcm1hY2nDs24gZW4gbG9zIHByb3Bpb3MgZGF0b3M6DQpgYGB7cn0NCmRhdG9zICU+JQ0KICBmaWx0ZXIoR1JVUE89PSJUVUJFUkNVTE9TIFkgUExBVEFOT1MiICYgWUVBUj09MjAxOCkgJT4lDQogIGdyb3VwX2J5KENVTFRJVk8pICU+JQ0KICBzdW1tYXJpemUoc3VtX2Nvc2VjaGFkYSA9IHN1bShBcmVhX0Nvc2VjaGFkYSwgbmEucm0gPSBUUlVFKSkgJT4lDQogICAgIGFycmFuZ2UoZGVzYyhzdW1fY29zZWNoYWRhKSkgLT4gdG90YWxfY29zZWNoYWRhDQoNCg0KdG90YWxfY29zZWNoYWRhDQpgYGANCkFob3JhLCB2ZWFtb3MgY3XDoWxlcyBzb24gbG9zIG11bmljaXBpb3MgY29uIG1heW9yIMOhcmVhIGNvc2VjaGFkYSBwb3IgY2FkYSBjdWx0aXZvIGRlIFRVQkVSQ1VMT1MgWSBQTEFUQU5PUyBlbiAyMDE4Og0KYGBge3J9DQpkYXRvcyAlPiUgDQogIGZpbHRlcihZRUFSPT0yMDE4ICYgR1JVUE89PSJUVUJFUkNVTE9TIFkgUExBVEFOT1MiKSAlPiUgDQogIGdyb3VwX2J5KENVTFRJVk8sIE1VTklDSVBJTykgJT4lDQogIHN1bW1hcml6ZShtYXhfYXJlYTIgPSBtYXgoQXJlYV9Db3NlY2hhZGEsIG5hLnJtID0gVFJVRSkpICU+JQ0KICAgIHNsaWNlKHdoaWNoLm1heChtYXhfYXJlYTIpKSAtPiBhcmVhX2Nvc2VjaGEyDQoNCmFyZWFfY29zZWNoYTINCmBgYA0KVm9sdmFtb3MgYSBsb3MgZGF0b3MgZGUgY3VsdGl2b3MgZGUgVFVCRVJDVUxPUyBZIFBMQVRBTk9TLiBBbnRlcyBkZSBncmFmaWNhciwgbmVjZXNpdGFyZW1vcyBhZ3JlZ2FyLCBhbCBvYmpldG8gdG90YWxfYXJlYV9jb3NlY2hhZGEsIHVuIG51ZXZvIGNhbXBvIGNvbiBhYnJldmlhdHVyYXMgcGFyYSBjYWRhIEdSVVBPIGRlIGN1bHRpdm9zLiBEZSBsbyBjb250cmFyaW8sIGxhIHRyYW1hIHNlIHZlcsOhIGRlc29yZGVuYWRhLg0KYGBge3J9DQp0b3RhbF9hcmVhX2Nvc2VjaGFkYSRDUk9QIDwtIGFiYnJldmlhdGUodG90YWxfYXJlYV9jb3NlY2hhZGEkR1JVUE8sIDMpDQpnIDwtIGdncGxvdChhZXMoeD1DUk9QLCB5PXN1bV9hcmVhX2Nvc2VjaGFkYSksIGRhdGEgPSB0b3RhbF9hcmVhX2Nvc2VjaGFkYSkgKyBnZW9tX2JhcihzdGF0PSdpZGVudGl0eScpICsgbGFicyh5PSfDgXJlYSBjb3NlY2hhZGFkYSB0b3RhbCBbSGFdJykNCmcrIGdndGl0bGUoIsOBcmVhIGNvc2VjaGFkYSB0b3RhbCBwb3IgZ3J1cG9zIGRlIGN1bHRpdm9zIGVuIDIwMTggcGFyYSBCb3lhY8OhIikgKyB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkgKw0KICAgbGFicyhjYXB0aW9uPSAiQmFzYWRvIGVuIGVsIE1pbmlzdGVyaW8gZGUgQWdyaWN1bHR1cmEgeSBEZXNhcnJvbGxvIFJ1cmFsLiAyMDE5LiIpDQpgYGANCjQuIEluY29ycG9yYWNpw7NuIGRlIGxhcyBlc3RhZMOtc3RpY2FzIGFncsOtY29sYXMgYSBsb3MgbXVuaWNpcGlvcw0KLS0tDQp1dGlsaXphciBlbCBzaGFwZWZpbGUgY29ycmVzcG9uZGllbnRlIGEgTWFyY28gR2VvZXN0YWRpc3RpY28gRGVwYXJ0YW1lbnRhbCBxdWUgc2UgZW5jdWVudHJhIGRpc3BvbmlibGUgZW4gREFORSBHZW9wb3J0YWwuDQoNCkNvbWVuY2Vtb3MgYSBsZWVyIGxvcyBkYXRvcyB1c2FuZG8gbGEgYmlibGlvdGVjYSBzZjoNCmBgYHtyfQ0KYW50X211bmljIDwtIHNmOjpzdF9yZWFkKCJDOi9Vc2Vycy9EYXZpZCBQZXJkb21vL0Rlc2t0b3AvR2VvbWF0aWNhLzE1X0JPWUFDQS9BRE1JTklTVFJBVElWTy9NR05fTVBJT19QT0xJVElDTy5zaHAiKQ0KYGBgDQpgYGB7cn0NCmFudF9tdW5pYw0KYGBgDQpQYXJhIHVuaXIgbGEgaW5mb3JtYWNpw7NuIGRlIGxhcyBlc3RhZMOtc3RpY2FzIGFncsOtY29sYXMgeSBsYSBpbmZvcm1hY2nDs24gbXVuaWNpcGFsLCBpbmljaWFsbWVudGUgZGViZW1vcyBnZW5lcmFyIHVuIGF0cmlidXRvIGVuIGNvbcO6biBlbnRyZSBhbWJvcyBhcmNoaXZvcywgZWwgY3VhbCwgcG9yIGNvbnZlbmllbmNpYSwgc2Vyw6EgZWwgY8OzZGlnbyBkZSBjYWRhIG11bmljaXBpbw0KUGFyYSBwb2RlciBoYWNlciBsYSB1bmnDs24sIG5lY2VzaXRhbW9zIGNhbWJpYXIgdGFudG8gZWwgdGlwbyBkZSBkYXRvcyBjb21vIGVsIGNvbnRlbmlkbyBkZWwgY8OzZGlnbyBxdWUgaWRlbnRpZmljYSBhIGNhZGEgbXVuaWNpcGlvLiBQYXJhIGVzdGEgdGFyZWEsIGVzIHVuYSBidWVuYSBpZGVhIGNyZWFyIHVuYSBjb3BpYSBkZSBsb3MgZGF0b3MgZXN0YWTDrXN0aWNvcyBvcmlnaW5hbGVzLiBDb24gZXN0ZSBlbmZvcXVlLCBjdWFscXVpZXIgbW92aW1pZW50byBmYWxzbyBubyBlc3Ryb3BlYXLDoSBsb3MgZGF0b3Mgb3JpZ2luYWxlcy4NCg0KUHJvY2VkYW1vcyBwYXNvIGEgcGFzbzoNCmBgYHtyfQ0KZGF0b3NfMiA8LSBkYXRvcw0KZGF0b3NfMiRURU1QIDwtICBhcy5jaGFyYWN0ZXIoZGF0b3NfMiRDT0RfTVVOKQ0KYGBgDQpgYGB7cn0NCmRhdG9zXzIkTVBJT19DQ0RHTyA8LSBhcy5mYWN0b3IoZGF0b3NfMiRURU1QKQ0KZGF0b3NfMg0KYGBgDQpgYGB7cn0NCmRhdG9zXzIgJT4lIGZpbHRlcihDVUxUSVZPID09ICJQQVBBIikgIC0+IGRhdG9zXzMNCmRhdG9zXzMNCmBgYA0KYGBge3J9DQpjbGFzcyhkYXRvc18zKQ0KYGBgDQpgYGB7cn0NCmRhdG9zXzQgPC0gZGF0b3NfMyAlPiUgZHBseXI6OnNlbGVjdChNVU5JQ0lQSU8sIE1QSU9fQ0NER08sIFlFQVIsIHByb2R1Y2Npb24sIHJlbmRpbWllbnRvKSANCmBgYA0KYGBge3J9DQpkYXRvc180ICU+JSANCiAgZ2F0aGVyKCJZRUFSIiwgInByb2R1Y2Npb24iLCAicmVuZGltaWVudG8iICwga2V5ID0gdmFyaWFibGUsIHZhbHVlID0gbnVtYmVyKQ0KYGBgDQpgYGB7cn0NCmRhdG9zXzQNCmBgYA0Kw4lzdGEgZXMgdW5hIHRhcmVhIGNsYXZlLiBJbXBsaWNhIHZhcmlvcyBwYXNvcyBwYXJhIHBvZGVyIGNvbnZlcnRpciBsYSB0YWJsYSBkZSBhdHJpYnV0b3MgZGUgZm9ybWF0byBsYXJnbyBhIGZvcm1hdG8gYW5jaG8uDQpgYGB7cn0NCmRhdG9zXzQgJT4lIA0KICBncm91cF9ieShNUElPX0NDREdPKSAlPiUgDQogIG11dGF0ZShWaXNpdCA9IDE6bigpKSAlPiUgDQogIGdhdGhlcigiWUVBUiIsICJwcm9kdWNjaW9uIiwgInJlbmRpbWllbnRvIiwga2V5ID0gdmFyaWFibGUsIHZhbHVlID0gbnVtYmVyKSAlPiUgDQogIHVuaXRlKGNvbWJpLCB2YXJpYWJsZSwgVmlzaXQpICU+JQ0KICBzcHJlYWQoY29tYmksIG51bWJlcikgLT4gZGF0b3NfNQ0KYGBgDQpgYGB7cn0NCmRhdG9zXzUNCmBgYA0KU2UgcmVhbGl6YSB1bmEgY29waWEgZGUgbG9zIGRhdG9zIG9yaWdpbmFsZXMgcG9yIHNpIHNlIGRhIGxhIHNpdHVhY2lvbiBkZSByZWFsaXphciBhbGfDum4gY2FtYmlvOg0KYGBge3J9DQphbnRfbXVuaWMyIDwtIGFudF9tdW5pYw0KYGBgDQoNCmBgYHtyfQ0KYW50X211bmljX3N0YXQgPWxlZnRfam9pbihhbnRfbXVuaWMyLCBkYXRvc181LCBieT0iTVBJT19DQ0RHTyIpDQpzdW1tYXJ5KGFudF9tdW5pY19zdGF0KQ0KYGBgDQo1LiBQbG90dGluZw0KLS0tDQpgYGB7cn0NCmluc3RhbGwucGFja2FnZXMoIlJDb2xvckJyZXdlciIpDQpgYGANCmBgYHtyfQ0KbGlicmFyeShSQ29sb3JCcmV3ZXIpDQpsaWJyYXJ5KGxlYWZsZXQpDQpgYGANCkdyYWZpcXVlbW9zIGxvcyBtdW5pY2lwaW9zIGNvbiBzdSBjb3JyZXNwb25kaWVudGUgcHJvZHVjY2nDs24gZGUgUEFQQSBwYXJhIHVuIHNvbG8gYcOxbzoNCmBgYHtyfQ0KYmlucyA8LSBjKDAsIDI1MCwgNTAwLCAxMDAwLCAyMDAwLCA1MDAwLCAxMDAwMCwgMTUwMDApDQpwYWwgPC0gY29sb3JCaW4oIllsT3JSZCIsIGRvbWFpbiA9IGFudF9tdW5pY19zdGF0JHByb2R1Y2Npb25fMTMsIGJpbnMgPSBiaW5zKQ0KDQogIG1hcGEgPC0gbGVhZmxldChkYXRhID0gYW50X211bmljX3N0YXQpICU+JQ0KICBhZGRUaWxlcygpICU+JQ0KICBhZGRQb2x5Z29ucyhsYWJlbCA9IH5wcm9kdWNjaW9uXzEzLA0KICAgICAgICAgICAgICBwb3B1cCA9IH5NUElPX0NOTUJSLA0KICAgICAgICAgICAgICBmaWxsQ29sb3IgPSB+cGFsKHByb2R1Y2Npb25fMTMpLA0KICAgICAgICAgICAgICBjb2xvciA9ICIjNDQ0NDQ0IiwNCiAgICAgICAgICAgICAgd2VpZ2h0ID0gMSwNCiAgICAgICAgICAgICAgc21vb3RoRmFjdG9yID0gMC41LA0KICAgICAgICAgICAgICBvcGFjaXR5ID0gMS4wLA0KICAgICAgICAgICAgICBmaWxsT3BhY2l0eSA9IDAuNSwNCiAgICAgICAgICAgICAgaGlnaGxpZ2h0T3B0aW9ucyA9IGhpZ2hsaWdodE9wdGlvbnMoY29sb3IgPSAid2hpdGUiLCB3ZWlnaHQgPSAyLCBicmluZ1RvRnJvbnQgPSBUUlVFKQ0KICAgICAgICAgICAgICApICU+JQ0KICBhZGRQcm92aWRlclRpbGVzKHByb3ZpZGVycyRPcGVuU3RyZWV0TWFwKSAlPiUNCiAgYWRkTGVnZW5kKCJib3R0b21yaWdodCIsIHBhbCA9IHBhbCwgdmFsdWVzID0gfnByb2R1Y2Npb25fMTMsDQogICAgdGl0bGUgPSAiUHJvZHVjY2nDs24gZGUgUEFQQSBlbiBCb3lhY8OhIFtUb25dICgyMDE4KSIsDQogICAgb3BhY2l0eSA9IDENCiAgKQ0KYGBgDQpgYGB7cn0NCm1hcGENCmBgYA0KVGVuZ2EgZW4gY3VlbnRhIHF1ZSB1dGlsaWPDqSB0YW50byBldGlxdWV0YXMgY29tbyB2ZW50YW5hcyBlbWVyZ2VudGVzIGVuIGVzdGUgbWFwYS4gDQpBaG9yYSB0cmF6YXJlbW9zIGVsIHJlbmRpbWllbnRvIHBvciBtdW5pY2lwaW8uDQpgYGB7cn0NCmJpbnMgPC0gYygwLCAyNTAsIDUwMCwgMTAwMCwgMjAwMCwgNTAwMCwgMTAwMDAsIDE1MDAwKQ0KcGFsIDwtIGNvbG9yQmluKCJZbE9yUmQiLCBkb21haW4gPSBhbnRfbXVuaWNfc3RhdCRyZW5kaW1pZW50b18xMywgYmlucyA9IGJpbnMpDQoNCiAgbWFwYTIgPC0gbGVhZmxldChkYXRhID0gYW50X211bmljX3N0YXQpICU+JQ0KICBhZGRUaWxlcygpICU+JQ0KICBhZGRQb2x5Z29ucyhsYWJlbCA9IH5yZW5kaW1pZW50b18xMywNCiAgICAgICAgICAgICAgcG9wdXAgPSB+TVBJT19DTk1CUiwNCiAgICAgICAgICAgICAgZmlsbENvbG9yID0gfnBhbChyZW5kaW1pZW50b18xMyksDQogICAgICAgICAgICAgIGNvbG9yID0gIiM0NDQ0NDQiLA0KICAgICAgICAgICAgICB3ZWlnaHQgPSAxLA0KICAgICAgICAgICAgICBzbW9vdGhGYWN0b3IgPSAwLjUsDQogICAgICAgICAgICAgIG9wYWNpdHkgPSAxLjAsDQogICAgICAgICAgICAgIGZpbGxPcGFjaXR5ID0gMC41LA0KICAgICAgICAgICAgICBoaWdobGlnaHRPcHRpb25zID0gaGlnaGxpZ2h0T3B0aW9ucyhjb2xvciA9ICJ3aGl0ZSIsIHdlaWdodCA9IDIsIGJyaW5nVG9Gcm9udCA9IFRSVUUpDQogICAgICAgICAgICAgICkgJT4lDQogIGFkZFByb3ZpZGVyVGlsZXMocHJvdmlkZXJzJE9wZW5TdHJlZXRNYXApICU+JQ0KICBhZGRMZWdlbmQoImJvdHRvbXJpZ2h0IiwgcGFsID0gcGFsLCB2YWx1ZXMgPSB+cmVuZGltaWVudG9fMTMsDQogICAgdGl0bGUgPSAiUmVuZGltaWVudG8gZGUgUEFQQSBlbiBCb3lhY8OhIFtUb25dICgyMDE4KSIsDQogICAgb3BhY2l0eSA9IDENCiAgKQ0KYGBgDQpgYGB7cn0NCm1hcGEyDQpgYGANCg0KDQoNCg==