1.Introducción

Este cuaderno corresponde al segundo informe técnico de la asignatura Geomatica Básica, fue realizado mediante la plataforma RStudio Cloud por una estudiante vinculada al programa de Ingeniería Agronómica de la Universidad Nacional de colombia. En este cuaderno, se aplican los conceptos de cartografia temática para plasmar datos de las Evaluaciones Agropecuarias Municipales y Necesidades Básicas insatisfechas (NBI) en el Departamento de Vichada

2. Cartografia temática

La cartografia temática , se basa en mapas que se encargan de representar un tema o fenómeno en particular empleando un lenguaje gráfico o visual. Los mapas temáticos se componen de un mapa base que provee la localización geográfica y la información de los atributos; El tipo de información que se desee transmitir y el publico al que está dirigido constituyen su propósito y a partir de el, se eligen los elementos y el tipo de mapa que usemos para representar dicha información.Dentro de los tipos de mapas se encuentran los mapas de coropletas , simbolos graduados , isolineas y puntos.

2.1 Mapa de Coropletas

Este tipo de mapas se encarga de representar las variables cuantitativas en un área definida a través de una variable visual, principalmente a través del color,donde este ultimo puede corresponder a un rango de valores o a un valor en espécifico.En los mapas de coropletas los límites de las áreas no se relacionan con las variables y en la mayoria de casos se elige a los límites administrativos para este propósito

2.2 Mapa de simbolos proporcionales

Se encarga de representar variables cuantitativas a través del tamaño de los símbolos ,es decir el tamaño del simbolo es proporcional al valor que toma el fenómeno que se quiere representar,la forma de los simbolos empleados en el mapa debe ser la misma , estos simbolos pueden estar representados por por diferentes figuras como cuadros o barras aunque generalmente se opta por el círculo

2.3 Mapa isarítmico o de contorno

Este tipo de mapas utiliza isolíneas para plasmar variables cuantitativas y contínuas . El tipo de dato representado generalmente es escalar y proveniente de una medida , incluye valores tridimensionales como la elevación.Las isolíneas representan la unión de puntos que tienen el mismo valor de la variable y en los mapas isaritmicos se cumple que existen valores más altos y otros más bajos en comparación con la isolínea

2.4 Mapa de puntos

Usa puntos para mostrar variables que representan algún tipo de cantidad .En este tipo de mapa, los puntos se reparten mediante un patrón espacial y cada uno de ellos representa una o varias unidades pero , todos tienen la misma forma y tamaño a lo largo de un mapa

3. Datos

Para realizar los mapas se usarán los datos correspondientes a las Necesidades Básicas Insatisfechas
NBI del censo nacional de población y vivienda en el año 2018 realizados por el Departamento Administrativo Nacional de Estadística , Algunos ejemplos de mapas temáticos,relacionados con variables demográficas a nivel nacional tambiém pueden encontrarse aqui.

El NBI es uno de los métodos multidimensionales de la medición de la pobreza , busca identificar cuales hogares son pobres en función de las necesidades básicas.Según el DANE ,las necesidades consideradas básicas se miden a través de indicadores simples los cuales son : Viviendas inadecuadas, Viviendas con hacinamiento crítico, Viviendas con servicios inadecuados, Viviendas con alta dependencia económica y Viviendas con niños en edad escolar que no asisten a la escuela.

Los datos disponibles para NBI , fueron descargados en formato .xlsx y por medio de Microsoft Excel se eliminaron los datos de los municipios que no correspondian al departamento de Vichada así como varias filas que no contenian información o que correspondían a imagenes institucionales

Luego , de los datos de NBI disponibles para los municipios de Vichada, se conservaron las columnas que se refieren a la totalidad del municipio, es decir ,también se eliminaron las columnas de “cabecera” y “zona rural” . Finalmente, se guardaron los datos resultantes como “NBI_VICHADA.xlsx” en el computador y fueron cargados al espacio de trabajo en RStudio Cloud en la carpeta “Vichada”

4.Preparación

Primero, se limpia la memoria

rm(list=ls())

Posteriormente se instalan las librerias necesarias

list.of.packages <- c("tidyverse", "rgeos", "sf", "raster", "cartography", "SpatialPosition")
new.packages <- list.of.packages[!(list.of.packages %in% installed.packages()[,"Package"])]
if(length(new.packages)) install.packages(new.packages)

Luego, se cargan las ibrerias

library(pacman)
pacman::p_load(tidyverse, rgeos, raster, sf, cartography, SpatialPosition,readxl)

5.Leer los datos de NBI

Mediante el siguiente código, se lee el archivo .xlsx que fue importado al espacio de trabajo

nbi <- read_excel("./NBI_VICHADA.xlsx")

Con la función “head” se puede ver los atributos de las primeras filas de la variable nbi

head(nbi)

Mediante el siguiente código se averiguará cual es el municipio con mayor porcentaje de NBI

nbi %>%slice(which.max(NBI)) -> nbi_max
nbi_max

Además , se usará “wich.min” para conocer cual es el municipio con menor porcentaje del NBI

nbi %>% slice(which.min(NBI)) -> nbi_min
nbi_min

Luego, se ordenan los municipios por NBI en orden descendente

nbi %>%arrange(desc(NBI))  -> nbi_ord
nbi_ord

6.Unir los datos de NBI a los municipios

En primera medida, se lee archivo Shapefile correspondiente a los municipios de Vichada con ayuda del paquete sf

Vichada_munic <- st_read("./ADMINISTRATIVO/MGN_MPIO_POLITICO.shp")
Reading layer `MGN_MPIO_POLITICO' from data source `/cloud/project/Vichada/ADMINISTRATIVO/MGN_MPIO_POLITICO.shp' using driver `ESRI Shapefile'
Simple feature collection with 4 features and 9 fields
geometry type:  POLYGON
dimension:      XY
bbox:           xmin: -71.07793 ymin: 2.737109 xmax: -67.4098 ymax: 6.324317
CRS:            4326

Se puede ver que hay en el objeto “Vichada Munic”, hay una columna llamada MPIO_CNMBR, para ver que hay dentro de este atributo se puede hacer uso de la función “head()”

head(Vichada_munic$MPIO_CNMBR)
[1] SANTA ROSALÍA  PUERTO CARREÑO LA PRIMAVERA   CUMARIBO      
Levels: CUMARIBO LA PRIMAVERA PUERTO CARREÑO SANTA ROSALÍA

Para realizar la unión entre el objeto “Vichada_munic” y los datos de NBI se hace uso de la función left_join considerando que , la variable clave que corresponde al código de los municipios tiene diferente nombre en cada objeto

nbi_Vmunic = left_join(Vichada_munic, nbi, by=c("MPIO_CCDGO"="CODIGO"))

Se seleccionan las variables del nombre del municipio, el código , el nbi y se almacenan en el objeto “check_nbi_munic”

nbi_Vmunic %>%dplyr::select(MUNICIPIO, MPIO_CCDGO, NBI)  ->  check_nbi_munic
head(check_nbi_munic)
Simple feature collection with 4 features and 3 fields
geometry type:  POLYGON
dimension:      XY
bbox:           xmin: -71.07793 ymin: 2.737109 xmax: -67.4098 ymax: 6.324317
CRS:            4326
       MUNICIPIO MPIO_CCDGO      NBI                       geometry
1  SANTA ROSALÍA      99624 36.52150 POLYGON ((-70.65378 5.37297...
2 PUERTO CARREÑO      99001 41.84217 POLYGON ((-67.80972 6.32431...
3   LA PRIMAVERA      99524 46.47443 POLYGON ((-69.03359 6.21869...
4       CUMARIBO      99773 87.37048 POLYGON ((-68.47074 5.55046...

Ahora, se reproyectan los municipios

nbi_munic_new <- st_transform(nbi_Vmunic, crs = 3116)

7. Ejemplos de mapas temáticos

Para esta sección , se hará uso de la libreria Cartography , esta tiene como objetivo crear mapas temáticos con una calidad visual de aquellos que se construyen en su software GIS.Esta libreria cuenta con funciones intuitivas y es compatible con los flujos de trabajo comunes en R. La libreria Cartography usa elemetos sf o sp para producir gráficos base.La mayoria de los componentes internos de este paquete se basan en funcionalidades sf y por esto, se suelen usar los objetos espaciales en formato sf

7.1 Mapa base por OpenStreetMap y símbolos proporcionales

Se usa la función getTiles() o tilesLayer para descargar y mostrar los mosaicos de OpenStreetMap. La función propSymbolsLayer() muestra simbolos con áreas proporcionales a una variable cuantitativa ; Se hace uso del argumento pulgadas para personalizar el tamaño de los simbolos, estos simbolos pueden ser circulos,cuadrados y barras, para este mapa en particular se usarán los circulos como simbolos

mapa_base <- getTiles(x = nbi_munic_new, type = "OpenStreetMap", zoom = 7, cachedir = TRUE, crop = FALSE)

En el siguiente código se establecen las márgenes y de forma posterior, se agregan diferentes opciones para la función propSymbolsLayer() , entre estas opciones se encuentra el tipo de simbolo, el color , el tamaño y la posición de la convención o leyenda que ayudará a interpretar el mapa . Con layoutLayer() se traza una capa de diseño , en esta se incluyen elementos como el título del mapa , la escala , el nombre del autor y las fuentes de información . Por último se agreg la flecha que indica el norte

opar <- par(mar = c(0,0,1.2,0))
tilesLayer(x = mapa_base)
plot(st_geometry(nbi_munic_new), col = NA, border = "gray20", add=TRUE)
propSymbolsLayer(x = nbi_munic_new, var = "NBI", inches = 0.21, col = "salmon3",legend.title.cex = 0.8,
  legend.values.cex = 0.55, legend.pos = "right",  legend.title.txt ="NBI", legend.style = "c",legend.frame = FALSE)
layoutLayer(title = " Distribución de NBI en Vichada",
            sources = "Fuentes: DANE, 2018\n© OpenStreetMap",
            author = " Angie Alejandra Juyo ",
            frame = TRUE, north = FALSE, tabtitle = TRUE, scale = "auto")
north(pos = "topleft")

7.2 Mapa de coropletas

En los mapas de coropletas , las áreas se sombrean de acuerdo al cambio en una variable cuantitativa determinada , este tipo de mapas es usado para representar razones o indices y en este caso la varible cuantitativa a utilizar es el porcentaje de necesidades básicas insatisfechas

La función que permite realizar mapas de coropletas es choroLayer() .Los argumentos nclass , method y breaks permiten personalizar la clasificación de la variable, la función getbreaks() también permiten clasificar la variable fuera de choroLayer() . Las paletas de colores se definen con col y se puede crear un conjunto de colores con carto.pal()

opar <- par(mar = c(0,0,1.2,0))
par(bg="grey90")
plot(st_geometry(nbi_munic_new), col = NA, border = NA, bg = "white")
choroLayer(x = nbi_munic_new, var = "NBI",method = "geom",nclass=5,
  col = carto.pal(pal1 = "red.pal", n1 = 5),
  border = "gray20", lwd = 0.5,legend.pos = "topright", legend.title.txt = "NBI",add = TRUE) 
layoutLayer(title = "Distribución NBI Vichada", sources = "Fuente: DANE, 2018",author = "Angie Alejaandra Juyo ", frame = TRUE, north = FALSE, tabtitle = TRUE, col="black") 
north(pos = "topleft")

De los datos presentados con anterioridad y la información obtenida se concluye que en el departamento Vichada ,el municipio de Cumaribo tiene el porcentaje de NBI más alto .El objetivo de estos indicadores y , en esta stuación específica el catalogar la poblacion de este municipio como pobre , es permitir a los organismos a nivel nacional y departamental la toma de desiciones y el desarrollo de planes que busquen satisfacer el tipo de necesidades que presentan sus habitantes.

7.3 Simbolos proporcionales y mapa de tipología

7.3.1 Niveles de pobreza

La función propSymbolsTypoLayer() permite representar variables cuantitativas y cualitativas de forma simultánea , se trata de un símbolo cuyo tamaño depende de la variable cuantitativa y cuyo color varía de acuerdo a la variable cualitativa, utilizando una combinación de los argumentos propSymbolsLayer() y typolayer().Para poder realizar este mapa se debe crear una función cualitativa con ayuda de la función mutate()

nbi_munic_p <- dplyr::mutate(nbi_munic_new, Pobreza = ifelse(MISERIA > 20, "Extrema", ifelse(HACINAMIENTO > 5, "Alta","Intermedia")))

El nuevo atributo pobreza , se almacenó en el objeto “nbi_munic_2” , y se clasificó a traves de los valores definidos a continuación : Si la variable MISERIA es mayor a 20, se catalogará como pobreza extrema ; Aquellos municipios que posean un valor de miseria menor a 20 se clasifican de acuerdo a los valores de HACINAMIENTO , si este último es mayor a 5 se clasificará como pobreza alta , de lo contrario será pobreza intermedia.Al usar la función head() , se ve la nueva columna con la variable pobreza clasificada con los parámetros definidos con anterioridad

head(nbi_munic_p)
Simple feature collection with 4 features and 21 fields
geometry type:  POLYGON
dimension:      XY
bbox:           xmin: 1332850 ymin: 794950.2 xmax: 1739856 ymax: 1195302
CRS:            EPSG:3116
  DPTO_CCDGO MPIO_CCDGO     MPIO_CNMBR
1         99      99624  SANTA ROSALÍA
2         99      99001 PUERTO CARREÑO
3         99      99524   LA PRIMAVERA
4         99      99773       CUMARIBO
                            MPIO_CRSLC MPIO_NAREA MPIO_NANO DPTO_CNMBR
1 Ordenanza 19 de Noviembre 26 de 1993   3898.569      2017    VICHADA
2       Decreto 1594 de Ago 5  de 1974  12205.614      2017    VICHADA
3       Decreto 676 de Abril13 de 1987  18361.979      2017    VICHADA
4 Ordenanza 66 de Noviembre 22 de 1996  65599.702      2017    VICHADA
  Shape_Leng Shape_Area COD_DEP DEPARTAMENTO COD_MUN      MUNICIPIO
1   3.296708  0.3167324      99      VICHADA     624  SANTA ROSALÍA
2   5.474851  0.9859169      99      VICHADA     001 PUERTO CARREÑO
3   7.572214  1.4894508      99      VICHADA     524   LA PRIMAVERA
4  18.794383  5.3085803      99      VICHADA     773       CUMARIBO
       NBI  MISERIA VIVIENDA SERVICIOS HACINAMIENTO INASISTENCIA
1 36.52150 14.47078 25.55127  5.209482     13.50606     2.122381
2 41.84217 24.00106 31.24307 16.326207     21.32489     7.785695
3 46.47443 19.44132 37.02410  8.965983     13.86574     4.201397
4 87.37048 73.55208 75.77214 71.607348     44.92416    12.619512
  DEP_ECONOMICA                       geometry Pobreza
1      12.37596 POLYGON ((1379688 1086961, ...    Alta
2      11.40143 POLYGON ((1694871 1195302, ... Extrema
3      12.02974 POLYGON ((1558915 1182093, ...    Alta
4      19.81529 POLYGON ((1622218 1108477, ... Extrema
library(sf)
library(cartography)
opar <- par(mar = c(0,0,1.2,0))
plot(st_geometry(nbi_munic_p), col="#fafbff", border="#262624", bg = "#edf2ff", lwd = 0.5)
propSymbolsTypoLayer(x = nbi_munic_p, var = "NBI", inches = 0.7, symbols = "square", border = "white", lwd = .5,legend.var.pos = "left", legend.var.title.txt = "NBI",var2 = "Pobreza", legend.var2.values.order = c("Extrema", "Alta"),col = carto.pal(pal1 = "multi.pal", n1 = 2), legend.var2.pos = "right", legend.var2.title.txt = "Pobreza") 
layoutLayer(title="Distribución del NBI en Vichada", author = "Angie Alejandra Juyo",  sources = "Fuentes: DANE, 2018", scale = 1, tabtitle = TRUE, frame = TRUE)
north(pos = "topleft")

En el anterior mapa se puede ver que los municipios de Vichada son clasificados con pobreza alta y extrema , esto se debe a que Vichada es considerado como uno de los departamentos más pobres de acuerdo con la medida de Pobreza multidimensional, que es otro método aplicado por el DANE para la medición de la pobreza a nivel nacional con datos tomados de la encuesta nacional de calidad de vida:

7.3.2 Condiciones Sanitarias para los municipios de Vichada

En el índice de Viviendas con servicios inadecuados se toma en cuenta el acceso a condiciones sanitarias mínimas.Aunque en los ultimos años se ha ampliado la cobertura de acueducto y alcantarillado en el departamento

El IRCA (Índice de Riesgo de la Calidad del Agua) es un índice expresado a través de porcentajes , este determina el grado de riesgo a la salud relacionado con la calidad de agua para consumo humano a través de el análisis de características físicas , químicas y microbiológicas.El agua se considera apta para el consumo humano cuando este índice está entre 0 - 5 % ,y según los datos del estudio sectorial de los servicios públicos de acueducto y alcantarillado, realizado por la superintendencia de servicios públicos domiciliarios se ha clasificado el agua que llega a la población del Vichada como agua no apta para consumo humano por presentar un índice de 11.8% y 14.8% en los años 2017 y 2018 respectivamente

En el siguiente código se clasificarán las condiciones sanitarias de los municipios de Vichada de acuerdo con el valor que tomen en la variable “SERVICIOS”

nbi_munic_s <- dplyr::mutate(nbi_munic_new, Servicios_inadecuados= ifelse(SERVICIOS > 50, "Muy Bajas", ifelse(SERVICIOS > 16, "Bajas","Aceptables")))

Se comprueba que en el nuevo objeto aparezca la nueva variable cualitativa correctamente clasificada de acuerdo a los valores asignados

head(nbi_munic_s)
Simple feature collection with 4 features and 21 fields
geometry type:  POLYGON
dimension:      XY
bbox:           xmin: 1332850 ymin: 794950.2 xmax: 1739856 ymax: 1195302
CRS:            EPSG:3116
  DPTO_CCDGO MPIO_CCDGO     MPIO_CNMBR
1         99      99624  SANTA ROSALÍA
2         99      99001 PUERTO CARREÑO
3         99      99524   LA PRIMAVERA
4         99      99773       CUMARIBO
                            MPIO_CRSLC MPIO_NAREA MPIO_NANO DPTO_CNMBR
1 Ordenanza 19 de Noviembre 26 de 1993   3898.569      2017    VICHADA
2       Decreto 1594 de Ago 5  de 1974  12205.614      2017    VICHADA
3       Decreto 676 de Abril13 de 1987  18361.979      2017    VICHADA
4 Ordenanza 66 de Noviembre 22 de 1996  65599.702      2017    VICHADA
  Shape_Leng Shape_Area COD_DEP DEPARTAMENTO COD_MUN      MUNICIPIO
1   3.296708  0.3167324      99      VICHADA     624  SANTA ROSALÍA
2   5.474851  0.9859169      99      VICHADA     001 PUERTO CARREÑO
3   7.572214  1.4894508      99      VICHADA     524   LA PRIMAVERA
4  18.794383  5.3085803      99      VICHADA     773       CUMARIBO
       NBI  MISERIA VIVIENDA SERVICIOS HACINAMIENTO INASISTENCIA
1 36.52150 14.47078 25.55127  5.209482     13.50606     2.122381
2 41.84217 24.00106 31.24307 16.326207     21.32489     7.785695
3 46.47443 19.44132 37.02410  8.965983     13.86574     4.201397
4 87.37048 73.55208 75.77214 71.607348     44.92416    12.619512
  DEP_ECONOMICA                       geometry Servicios_inadecuados
1      12.37596 POLYGON ((1379688 1086961, ...            Aceptables
2      11.40143 POLYGON ((1694871 1195302, ...                 Bajas
3      12.02974 POLYGON ((1558915 1182093, ...            Aceptables
4      19.81529 POLYGON ((1622218 1108477, ...             Muy Bajas
library(sf)
library(cartography)
opar <- par(mar = c(0,0,1.2,0))
plot(st_geometry(nbi_munic_s), col="#dde0dc", border="#353635", bg ="white", lwd = 0.5)
propSymbolsTypoLayer(x = nbi_munic_s, var = "NBI", inches = 0.35, symbols = "circle", border = "black", lwd = .4, legend.var.pos = "left", legend.var.title.txt = "NBI",var2 = "Servicios_inadecuados", legend.var2.values.order = c("Muy Bajas", "Bajas", "Aceptables"),col = carto.pal(pal1 = "multi.pal", n1 = 3),
  legend.var2.pos = "right", legend.var2.title.txt = "Condiciones Sanitarias") 
layoutLayer(title="Distribución del NBI en Vichada", 
            author = "Angie Alejandra Juyo", 
            sources = "Fuentes: DANE, 2018", 
            scale = 1 , tabtitle = TRUE, frame = TRUE)
north(pos = "topleft")

7.4 Mapa de etiquetas

En este mapa se combinan las funciones ChoroLayer() y labelLayer() para que se coloreen las áreas correspondientes a municipio de acuerdo con el porcentaje de NBI y además de eso , se pueda visualizar en el mapa el nombre del municipio al cual corresponde cada área

library(sf)
library(cartography)
opar <- par(mar = c(0,0,1.2,0))
par(bg="grey25")
plot(st_geometry(nbi_munic_p), col = "#e4e9de", border = "darkseagreen4", 
     bg = "grey75", lwd = 0.5)
choroLayer( x = nbi_munic_new, var = "NBI", method = "geom", nclass=5, col = carto.pal(pal1 = "wine.pal", n1 = 5), border = "white", lwd = 0.5, legend.pos = "topright", legend.title.txt = "NBI", add = TRUE) 
labelLayer(x = nbi_munic_p, txt = "MUNICIPIO", col= "white", cex = 0.4, font = 4, halo = TRUE, bg = "grey25", r = 0.1, overlap = FALSE, show.lines = FALSE)
layoutLayer( title = "Municipios de Vichada", 
  sources = "Fuentes: DANE, 2018",  author = "Angie Alejandra Juyo", 
  frame = TRUE,
  north = TRUE, 
  tabtitle = TRUE, 
  theme = "taupe.pal") 

8 Mapas empleando las estadísticas agricolas municipales

8.1 Mapas de isopletas

Se realizará un mapa de isopletas para mostrar la distribución de la producción de Yuca en el departamento del Vichada.Los mapas de isopletas se basan en el supuesto de que el fenómeno a representar tiene una distribución continua y a diferencia de los mapas coropléticos los mapas de isopleatas no se rigen por la división territorial. Este tipo de mapas se realizan con ayuda de de la función smoothLayer() que depende en gran medida de la libreria Spatial position , para poder mostrar una capa de isopleta se le asignan una serie de parámetros a la función

Como ya se habia mencionado el mapa corresponderá a la distribución de la producción de Yuca ,por tanto se usará el archivo correspondiente a las evaluaciones agropecuarias municipales que se encuentra en el directorio de trabajo, pues fue usado en un cuaderno anterior para ilustrar las uniones basadas en atibutos.Se usa el siguiente código para leer el archivo “EVA_VICHADA” que se encuentra en formato .xlsx y que contiene estos datos para el año 2018

cultivos2018 <- read_excel("./EVA_VICHADA.xlsx")

Se usa de nuevo la función head para ver el contenido

head(cultivos2018) 

Se filtra el cultivo de nuestro interés

cultivos2018 %>%
  filter(Cultivo == "YUCA") -> Y2018

Se crea una nueva variable correspondiente al codigo del municipio donde se transforma a caracter y luego a factor para poder realizar de forma posterior la unión con los datos espaciales

Y2018$TEMP <- as.character(Y2018$COD_MUN)
Y2018$MPIO_CCDGO <- as.factor(paste(Y2018$TEMP))
Y_munic = left_join(Vichada_munic, Y2018, by="MPIO_CCDGO")

Se revisa el producto de la unión entre los atributos y la capa espacial

head(Y_munic)
Simple feature collection with 4 features and 24 fields
geometry type:  POLYGON
dimension:      XY
bbox:           xmin: -71.07793 ymin: 2.737109 xmax: -67.4098 ymax: 6.324317
CRS:            4326
  DPTO_CCDGO MPIO_CCDGO     MPIO_CNMBR
1         99      99624  SANTA ROSALÍA
2         99      99001 PUERTO CARREÑO
3         99      99524   LA PRIMAVERA
4         99      99773       CUMARIBO
                            MPIO_CRSLC MPIO_NAREA MPIO_NANO DPTO_CNMBR
1 Ordenanza 19 de Noviembre 26 de 1993   3898.569      2017    VICHADA
2       Decreto 1594 de Ago 5  de 1974  12205.614      2017    VICHADA
3       Decreto 676 de Abril13 de 1987  18361.979      2017    VICHADA
4 Ordenanza 66 de Noviembre 22 de 1996  65599.702      2017    VICHADA
  Shape_Leng Shape_Area COD_DEP Departamento COD_MUN      Municipio
1   3.296708  0.3167324      99      VICHADA   99624  SANTA ROSALIA
2   5.474851  0.9859169      99      VICHADA   99001 PUERTO CARREÑO
3   7.572214  1.4894508      99      VICHADA   99524   LA PRIMAVERA
4  18.794383  5.3085803      99      VICHADA   99773       CUMARIBO
                  Grupo Subgrupo Cultivo Periodo Area _Sembrada
1 TUBERCULOS Y PLATANOS     YUCA    YUCA    2018             40
2 TUBERCULOS Y PLATANOS     YUCA    YUCA    2018            105
3 TUBERCULOS Y PLATANOS     YUCA    YUCA    2018             90
4 TUBERCULOS Y PLATANOS     YUCA    YUCA    2018            540
  Area_Cosechada Produccion Rendimiento           Estado Ciclo  TEMP
1             40        280        7.00 TUBERCULO FRESCO ANUAL 99624
2            105       1220       11.62 TUBERCULO FRESCO ANUAL 99001
3             90       1350       15.00 TUBERCULO FRESCO ANUAL 99524
4            540       5680       10.52 TUBERCULO FRESCO ANUAL 99773
                        geometry
1 POLYGON ((-70.65378 5.37297...
2 POLYGON ((-67.80972 6.32431...
3 POLYGON ((-69.03359 6.21869...
4 POLYGON ((-68.47074 5.55046...

Se reproyectan los municipios y por ultimo se ejecuta el codigo para visualizar el mapa

rep_Y <- st_transform(Y_munic, crs = 3116)
opar <- par(mar = c(0,0,1.2,0))
plot(st_geometry(rep_Y), col = NA, border = "black", bg = "white")
smoothLayer(x = rep_Y, var = 'Produccion', typefct = "exponential", span = 75000, beta = 2, nclass = 6, col = carto.pal(pal1 = 'blue.pal', n1 = 6), border = "grey", lwd = 0.5, mask = rep_Y, legend.values.rnd = -1, legend.title.txt = "Produccion", legend.pos = "topright", add=TRUE)
layoutLayer(title = "Distribución en la producción de Yuca en Vichada",sources = "Fuente: DANE y MADR, 2018",author = "Alejandra Juyo",frame = FALSE, north = FALSE, tabtitle = TRUE, theme = "blue.pal")
north(pos = "topleft")

8.2 Guardar Mapas

Ahora se va a realizar otro mapa de producción de Yuca en Vichada para el año 2018. Esta vez se van a usar símbolos proporcionales y mapas de coropletas. La salida se guardará como un archivo .png en el directorio de trabajo.

propSymbolsChoroLaer() crea una mapa de símbolos que son proporcionales a los valores de una primera variable y coloreados para reflejar la clasificación de una segunda variable.

Se utiliza una combinación de argumentos propSymbolsLayer() y ChoroLayer(). El siguiente chunk no muestra un mapa. Para poder visualizarlo se intserta el archivo png con la síntaxis de RMarkdown

png("./yuca_2018.png", width = 2048, height = 1526)
opar <- par(mar = c(0,0,5,5))
plot(st_geometry(rep_Y), col="darkseagreen3", border="darkseagreen4", bg = "white", lwd = 0.6)
propSymbolsChoroLayer(x = rep_Y, var = "Produccion", var2 = "Rendimiento", col = carto.pal(pal1 = "blue.pal", n1 = 3, pal2 = "orange.pal", n2=3), inches = 1, method = "q6", border = "grey50", lwd = 1, legend.title.cex = 2, legend.values.cex = 2,legend.var.pos = "right", legend.var2.pos = "left", legend.var2.values.rnd = 2, legend.var2.title.txt = "Rendimiento\n(Ton/Ha)", legend.var.title.txt = "Producción de Yuca en 2018", legend.var.style = "e")
labelLayer(x = rep_Y, txt = "MPIO_CNMBR", col= "white", cex = 2.0, font = 4,halo = FALSE, bg = "white", r = 0.1,  overlap = FALSE, show.lines = FALSE)
layoutLayer(title="Producción y Rendimiento de Platano 2018", author = "Angie Alejandra Juyo", sources = "Fuentes: MADR & DANE, 2018", scale = 85, tabtitle = FALSE, frame = TRUE)
north(pos = "topleft")
title(main="Cultivo de Yuca en Vichada, 2018", cex.main=3,
      sub= "Fuentes: MADR & DANE, 2018", cex.sub=4)
graticule = TRUE
par(opar)
dev.off()
null device 
          1 

.:

Mapa de puntos

Como se habia mencionado de forma anterior el mapa de puntos es utilizado para representar variables que indiquen cantidad, la población es una de ellas , por esto el siguiente ejemplo de mapa temático corresponde a la representación del número de habitantes en los municipios de Vichada en el año 2018 a través de una mapa de puntos

Los datos fueron obtenidos del censo del 2018, se tomó los datos correspondientes a Población Total Censada en Hogares Particulares y en Lugares Especiales de Alojamiento (LEA) por área total en el departamento de interés y se almacenó en el archivo “CENSO.xlsx” ,el archico fue leido mediante la función “read_excel” y se realizó el procedimiento de unión de forma análoga a los mapas representados con aterioridad

poblacion <- read_excel("./CENSO.xlsx")
poblacion$TEMP <- as.character(poblacion$CODIGO)
poblacion$MPIO_CCDGO <- as.factor(paste(poblacion$TEMP))
V_pob = left_join(Vichada_munic, poblacion, by="MPIO_CCDGO")

Se revisa el Join de los atributos con la capa espacial

head(V_pob)
Simple feature collection with 4 features and 14 fields
geometry type:  POLYGON
dimension:      XY
bbox:           xmin: -71.07793 ymin: 2.737109 xmax: -67.4098 ymax: 6.324317
CRS:            4326
  DPTO_CCDGO MPIO_CCDGO     MPIO_CNMBR                           MPIO_CRSLC MPIO_NAREA MPIO_NANO
1         99      99624  SANTA ROSALÍA Ordenanza 19 de Noviembre 26 de 1993   3898.569      2017
2         99      99001 PUERTO CARREÑO       Decreto 1594 de Ago 5  de 1974  12205.614      2017
3         99      99524   LA PRIMAVERA       Decreto 676 de Abril13 de 1987  18361.979      2017
4         99      99773       CUMARIBO Ordenanza 66 de Noviembre 22 de 1996  65599.702      2017
  DPTO_CNMBR Shape_Leng Shape_Area CODIGO DEPARTAMENTO      MUNICIPIO POBLACION  TEMP
1    VICHADA   3.296708  0.3167324  99624      Vichada  Santa Rosalía      4026 99624
2    VICHADA   5.474851  0.9859169  99001      Vichada Puerto Carreño     19788 99001
3    VICHADA   7.572214  1.4894508  99524      Vichada   La Primavera      9690 99524
4    VICHADA  18.794383  5.3085803  99773      Vichada       Cumaribo     43138 99773
                        geometry
1 POLYGON ((-70.65378 5.37297...
2 POLYGON ((-67.80972 6.32431...
3 POLYGON ((-69.03359 6.21869...
4 POLYGON ((-68.47074 5.55046...
rep_V <- st_transform(V_pob, crs = 3116)

Finalmente se ejecuta el codigo para realizar el mapa de puntos con la función “dotDensityLayer”, en los argumentos se le asignó a cada punto un total de 200 personas

opar <- par(mar = c(0,0,5,5))
plot(st_geometry(rep_V), col="#999999", border="black", bg = "white", lwd = 0.68)
dotDensityLayer(x = rep_V, var = "POBLACION", n=200, pch=1, cex = 0.28, type = "random", col="red",  legend.pos = "right", legend.txt = "200 personas", legend.cex = 0.8, legend.col = "black", legend.frame = TRUE)
layoutLayer(title = "Población en Vichada en 2018",sources = "Fuente: DANE",author = "Alejandra Juyo",frame = FALSE, north = FALSE, tabtitle = TRUE)
north(pos = "topleft")

sessionInfo()
R version 3.6.0 (2019-04-26)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Ubuntu 16.04.6 LTS

Matrix products: default
BLAS:   /usr/lib/atlas-base/atlas/libblas.so.3.0
LAPACK: /usr/lib/atlas-base/atlas/liblapack.so.3.0

locale:
 [1] LC_CTYPE=C.UTF-8       LC_NUMERIC=C           LC_TIME=C.UTF-8        LC_COLLATE=C.UTF-8    
 [5] LC_MONETARY=C.UTF-8    LC_MESSAGES=C.UTF-8    LC_PAPER=C.UTF-8       LC_NAME=C             
 [9] LC_ADDRESS=C           LC_TELEPHONE=C         LC_MEASUREMENT=C.UTF-8 LC_IDENTIFICATION=C   

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

other attached packages:
 [1] readxl_1.3.1          SpatialPosition_2.0.1 cartography_2.4.1     rgeos_0.5-2          
 [5] forcats_0.5.0         stringr_1.4.0         dplyr_0.8.5           purrr_0.3.3          
 [9] readr_1.3.1           tidyr_1.0.2           tibble_3.0.1          ggplot2_3.3.0        
[13] tidyverse_1.3.0       pacman_0.5.1          sf_0.9-3              raster_3.0-12        
[17] sp_1.4-1             

loaded via a namespace (and not attached):
 [1] Rcpp_1.0.4.6       lubridate_1.7.8    lattice_0.20-38    class_7.3-15       assertthat_0.2.1  
 [6] digest_0.6.25      R6_2.4.1           cellranger_1.1.0   backports_1.1.5    reprex_0.3.0      
[11] evaluate_0.14      e1071_1.7-3        httr_1.4.1         pillar_1.4.3       rlang_0.4.5       
[16] rstudioapi_0.11    rmarkdown_2.1      munsell_0.5.0      broom_0.5.5        compiler_3.6.0    
[21] modelr_0.1.6       xfun_0.12          base64enc_0.1-3    pkgconfig_2.0.3    htmltools_0.4.0   
[26] tidyselect_1.0.0   codetools_0.2-16   fansi_0.4.1        crayon_1.3.4       dbplyr_1.4.2      
[31] withr_2.1.2        grid_3.6.0         nlme_3.1-139       jsonlite_1.6.1     gtable_0.3.0      
[36] lifecycle_0.2.0    DBI_1.1.0          magrittr_1.5       units_0.6-6        scales_1.1.0      
[41] KernSmooth_2.23-15 cli_2.0.2          stringi_1.4.6      fs_1.4.1           xml2_1.3.1        
[46] ellipsis_0.3.0     generics_0.0.2     vctrs_0.2.4        tools_3.6.0        glue_1.4.1        
[51] hms_0.5.3          yaml_2.2.1         colorspace_1.4-1   isoband_0.2.0      classInt_0.4-3    
[56] rvest_0.3.5        knitr_1.28         haven_2.2.0       
LS0tCnRpdGxlOiAiQ2FydG9ncmFmaWEgdGVtw6F0aWNhIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKYXV0aG9yOiAiQW5naWUgQWxlamFuZHJhIEp1eW8gQnVpdHJhZ28iCmRhdGU6ICJNYXlvIDIwMjAiCgotLS0KPGRpdiBzdHlsZT0idGV4dC1hbGlnbjoganVzdGlmeSI+CgojIyMgMS5JbnRyb2R1Y2Npw7NuCgpFc3RlIGN1YWRlcm5vIGNvcnJlc3BvbmRlIGFsIHNlZ3VuZG8gaW5mb3JtZSB0w6ljbmljbyBkZSBsYSBhc2lnbmF0dXJhIEdlb21hdGljYSBCw6FzaWNhLCBmdWUgcmVhbGl6YWRvIG1lZGlhbnRlIGxhIHBsYXRhZm9ybWEgUlN0dWRpbyBDbG91ZCBwb3IgdW5hIGVzdHVkaWFudGUgdmluY3VsYWRhIGFsIHByb2dyYW1hIGRlIEluZ2VuaWVyw61hIEFncm9uw7NtaWNhIGRlIGxhIFVuaXZlcnNpZGFkIE5hY2lvbmFsIGRlIGNvbG9tYmlhLiBFbiBlc3RlIGN1YWRlcm5vLCBzZSBhcGxpY2FuIGxvcyBjb25jZXB0b3MgZGUgY2FydG9ncmFmaWEgdGVtw6F0aWNhIHBhcmEgcGxhc21hciBkYXRvcyBkZSBsYXMgRXZhbHVhY2lvbmVzIEFncm9wZWN1YXJpYXMgTXVuaWNpcGFsZXMgeSBOZWNlc2lkYWRlcyBCw6FzaWNhcyBpbnNhdGlzZmVjaGFzIChOQkkpIGVuIGVsIERlcGFydGFtZW50byBkZSBWaWNoYWRhCgoKIyMjIDIuIENhcnRvZ3JhZmlhIHRlbcOhdGljYQoKTGEgY2FydG9ncmFmaWEgdGVtw6F0aWNhICwgc2UgYmFzYSBlbiBtYXBhcyBxdWUgc2UgZW5jYXJnYW4gZGUgcmVwcmVzZW50YXIgdW4gdGVtYSBvIGZlbsOzbWVubyBlbiBwYXJ0aWN1bGFyIGVtcGxlYW5kbyB1biBsZW5ndWFqZSBncsOhZmljbyBvIHZpc3VhbC4gTG9zIG1hcGFzIHRlbcOhdGljb3Mgc2UgY29tcG9uZW4gZGUgdW4gbWFwYSBiYXNlIHF1ZSBwcm92ZWUgbGEgbG9jYWxpemFjacOzbiBnZW9ncsOhZmljYSB5IGxhIGluZm9ybWFjacOzbiBkZSBsb3MgYXRyaWJ1dG9zOyBFbCB0aXBvIGRlIGluZm9ybWFjacOzbiBxdWUgc2UgZGVzZWUgdHJhbnNtaXRpciB5IGVsIHB1YmxpY28gYWwgcXVlIGVzdMOhIGRpcmlnaWRvIGNvbnN0aXR1eWVuIHN1IHByb3DDs3NpdG8geSBhIHBhcnRpciBkZSBlbCwgc2UgZWxpZ2VuIGxvcyBlbGVtZW50b3MgeSBlbCB0aXBvIGRlIG1hcGEgcXVlIHVzZW1vcyBwYXJhIHJlcHJlc2VudGFyIGRpY2hhIGluZm9ybWFjacOzbi5EZW50cm8gZGUgbG9zIHRpcG9zICBkZSBtYXBhcyBzZSBlbmN1ZW50cmFuIGxvcyBtYXBhcyBkZSBjb3JvcGxldGFzICwgc2ltYm9sb3MgZ3JhZHVhZG9zICwgaXNvbGluZWFzIHkgcHVudG9zLgoKIyMjIyAyLjEgTWFwYSBkZSBDb3JvcGxldGFzCgpFc3RlIHRpcG8gZGUgbWFwYXMgc2UgZW5jYXJnYSBkZSByZXByZXNlbnRhciBsYXMgdmFyaWFibGVzIGN1YW50aXRhdGl2YXMgIGVuIHVuIMOhcmVhIGRlZmluaWRhIGEgdHJhdsOpcyBkZSB1bmEgdmFyaWFibGUgdmlzdWFsLCBwcmluY2lwYWxtZW50ZSBhIHRyYXbDqXMgZGVsIGNvbG9yLGRvbmRlIGVzdGUgdWx0aW1vIHB1ZWRlIGNvcnJlc3BvbmRlciBhIHVuIHJhbmdvIGRlIHZhbG9yZXMgbyBhIHVuIHZhbG9yIGVuIGVzcMOpY2lmaWNvLkVuIGxvcyBtYXBhcyBkZSBjb3JvcGxldGFzIGxvcyBsw61taXRlcyBkZSBsYXMgw6FyZWFzIG5vIHNlIHJlbGFjaW9uYW4gY29uIGxhcyB2YXJpYWJsZXMgeSBlbiBsYSBtYXlvcmlhIGRlIGNhc29zIHNlIGVsaWdlIGEgbG9zIGzDrW1pdGVzIGFkbWluaXN0cmF0aXZvcyBwYXJhIGVzdGUgcHJvcMOzc2l0bwoKCiMjIyMgMi4yIE1hcGEgZGUgc2ltYm9sb3MgcHJvcG9yY2lvbmFsZXMKClNlIGVuY2FyZ2EgZGUgcmVwcmVzZW50YXIgdmFyaWFibGVzIGN1YW50aXRhdGl2YXMgYSB0cmF2w6lzIGRlbCB0YW1hw7FvIGRlIGxvcyBzw61tYm9sb3MgLGVzIGRlY2lyIGVsIHRhbWHDsW8gZGVsIHNpbWJvbG8gZXMgcHJvcG9yY2lvbmFsIGFsIHZhbG9yIHF1ZSB0b21hIGVsIGZlbsOzbWVubyAgcXVlIHNlIHF1aWVyZSByZXByZXNlbnRhcixsYSBmb3JtYSBkZSBsb3Mgc2ltYm9sb3MgZW1wbGVhZG9zIGVuIGVsIG1hcGEgZGViZSBzZXIgbGEgbWlzbWEgLCBlc3RvcyBzaW1ib2xvcyBwdWVkZW4gZXN0YXIgcmVwcmVzZW50YWRvcyBwb3IgcG9yIGRpZmVyZW50ZXMgZmlndXJhcyBjb21vIGN1YWRyb3MgbyBiYXJyYXMgYXVucXVlIGdlbmVyYWxtZW50ZSBzZSBvcHRhIHBvciBlbCBjw61yY3VsbyAKCgojIyMjIDIuMyBNYXBhIGlzYXLDrXRtaWNvIG8gZGUgY29udG9ybm8gCgoKRXN0ZSB0aXBvIGRlIG1hcGFzIHV0aWxpemEgaXNvbMOtbmVhcyBwYXJhIHBsYXNtYXIgdmFyaWFibGVzIGN1YW50aXRhdGl2YXMgeSBjb250w61udWFzIC4gRWwgdGlwbyBkZSBkYXRvIHJlcHJlc2VudGFkbyBnZW5lcmFsbWVudGUgZXMgZXNjYWxhciB5IHByb3ZlbmllbnRlIGRlIHVuYSBtZWRpZGEgLCBpbmNsdXllIHZhbG9yZXMgdHJpZGltZW5zaW9uYWxlcyBjb21vIGxhIGVsZXZhY2nDs24uTGFzIGlzb2zDrW5lYXMgcmVwcmVzZW50YW4gbGEgdW5pw7NuIGRlICBwdW50b3MgcXVlIHRpZW5lbiBlbCBtaXNtbyB2YWxvciBkZSBsYSB2YXJpYWJsZSB5IGVuIGxvcyBtYXBhcyBpc2FyaXRtaWNvcyBzZSBjdW1wbGUgcXVlIGV4aXN0ZW4gdmFsb3JlcyBtw6FzIGFsdG9zIHkgb3Ryb3MgbcOhcyBiYWpvcyBlbiBjb21wYXJhY2nDs24gY29uIGxhIGlzb2zDrW5lYQoKCiMjIyMgMi40IE1hcGEgZGUgcHVudG9zCgpVc2EgcHVudG9zIHBhcmEgbW9zdHJhciB2YXJpYWJsZXMgcXVlIHJlcHJlc2VudGFuIGFsZ8O6biB0aXBvIGRlIGNhbnRpZGFkIC5FbiBlc3RlIHRpcG8gZGUgbWFwYSwgbG9zIHB1bnRvcyBzZSByZXBhcnRlbiBtZWRpYW50ZSB1biBwYXRyw7NuIGVzcGFjaWFsIHkgY2FkYSB1bm8gZGUgZWxsb3MgcmVwcmVzZW50YSB1bmEgbyB2YXJpYXMgdW5pZGFkZXMgcGVybyAsIHRvZG9zIHRpZW5lbiBsYSBtaXNtYSBmb3JtYSB5IHRhbWHDsW8gYSBsbyBsYXJnbyBkZSB1biBtYXBhCgoKIyMjIDMuIERhdG9zCgpQYXJhIHJlYWxpemFyIGxvcyBtYXBhcyBzZSB1c2Fyw6FuIGxvcyBkYXRvcyBjb3JyZXNwb25kaWVudGVzIGEgbGFzIE5lY2VzaWRhZGVzIELDoXNpY2FzIEluc2F0aXNmZWNoYXMgIApbTkJJXShodHRwczovL3d3dy5kYW5lLmdvdi5jby9pbmRleC5waHAvZXN0YWRpc3RpY2FzLXBvci10ZW1hL3BvYnJlemEteS1jb25kaWNpb25lcy1kZS12aWRhL25lY2VzaWRhZGVzLWJhc2ljYXMtaW5zYXRpc2ZlY2hhcy1uYmkpIGRlbCBjZW5zbyBuYWNpb25hbCBkZSBwb2JsYWNpw7NuIHkgdml2aWVuZGEgZW4gZWwgYcOxbyAyMDE4IHJlYWxpemFkb3MgcG9yIGVsIERlcGFydGFtZW50byBBZG1pbmlzdHJhdGl2byBOYWNpb25hbCBkZSBFc3RhZMOtc3RpY2EgLCBBbGd1bm9zIGVqZW1wbG9zIGRlIG1hcGFzIHRlbcOhdGljb3MscmVsYWNpb25hZG9zIGNvbiB2YXJpYWJsZXMgZGVtb2dyw6FmaWNhcyBhIG5pdmVsIG5hY2lvbmFsIHRhbWJpw6ltIHB1ZWRlbiBlbmNvbnRyYXJzZSBbYXF1aV0oaHR0cHM6Ly93d3cuZGFuZS5nb3YuY28vaW5kZXgucGhwL2VzdGFkaXN0aWNhcy1wb3ItdGVtYS9kZW1vZ3JhZmlhLXktcG9ibGFjaW9uL2NlbnNvLW5hY2lvbmFsLWRlLXBvYmxhY2lvbi15LXZpdmVuZGEtMjAxOC9oZXJyYW1pZW50YXMvbWFwYXMtdGVtYXRpY29zLWNucHYpLgoKRWwgTkJJIGVzIHVubyBkZSBsb3MgbcOpdG9kb3MgbXVsdGlkaW1lbnNpb25hbGVzIGRlIGxhIG1lZGljacOzbiBkZSBsYSBwb2JyZXphICwgYnVzY2EgaWRlbnRpZmljYXIgY3VhbGVzIGhvZ2FyZXMgc29uIHBvYnJlcyBlbiBmdW5jacOzbiBkZSBsYXMgbmVjZXNpZGFkZXMgYsOhc2ljYXMuU2Vnw7puIGVsIERBTkUgLGxhcyBuZWNlc2lkYWRlcyBjb25zaWRlcmFkYXMgYsOhc2ljYXMgc2UgbWlkZW4gYSB0cmF2w6lzIGRlIGluZGljYWRvcmVzIHNpbXBsZXMgbG9zIGN1YWxlcyBzb24gOiBWaXZpZW5kYXMgaW5hZGVjdWFkYXMsIFZpdmllbmRhcyBjb24gaGFjaW5hbWllbnRvIGNyw610aWNvLCBWaXZpZW5kYXMgY29uIHNlcnZpY2lvcyBpbmFkZWN1YWRvcywgVml2aWVuZGFzIGNvbiBhbHRhIGRlcGVuZGVuY2lhIGVjb27Ds21pY2EgeSBWaXZpZW5kYXMgY29uIG5pw7FvcyBlbiBlZGFkIGVzY29sYXIgcXVlIG5vIGFzaXN0ZW4gYSBsYSBlc2N1ZWxhLgoKTG9zIGRhdG9zIGRpc3BvbmlibGVzIHBhcmEgTkJJICwgZnVlcm9uIGRlc2NhcmdhZG9zIGVuIGZvcm1hdG8gLnhsc3ggeSBwb3IgbWVkaW8gZGUgTWljcm9zb2Z0IEV4Y2VsIHNlIGVsaW1pbmFyb24gbG9zIGRhdG9zIGRlIGxvcyBtdW5pY2lwaW9zIHF1ZSBubyBjb3JyZXNwb25kaWFuIGFsIGRlcGFydGFtZW50byBkZSBWaWNoYWRhIGFzw60gY29tbyB2YXJpYXMgZmlsYXMgcXVlIG5vIGNvbnRlbmlhbiBpbmZvcm1hY2nDs24gbyBxdWUgY29ycmVzcG9uZMOtYW4gYSBpbWFnZW5lcyBpbnN0aXR1Y2lvbmFsZXMKCkx1ZWdvICwgZGUgbG9zIGRhdG9zIGRlIE5CSSBkaXNwb25pYmxlcyBwYXJhIGxvcyBtdW5pY2lwaW9zIGRlIFZpY2hhZGEsICBzZSBjb25zZXJ2YXJvbiBsYXMgY29sdW1uYXMgcXVlIHNlIHJlZmllcmVuIGEgbGEgdG90YWxpZGFkIGRlbCBtdW5pY2lwaW8sIGVzIGRlY2lyICx0YW1iacOpbiBzZSBlbGltaW5hcm9uIGxhcyBjb2x1bW5hcyBkZSAiY2FiZWNlcmEiIHkgInpvbmEgcnVyYWwiIC4gRmluYWxtZW50ZSwgc2UgZ3VhcmRhcm9uIGxvcyBkYXRvcyByZXN1bHRhbnRlcyBjb21vICJOQklfVklDSEFEQS54bHN4IiBlbiBlbCBjb21wdXRhZG9yIHkgZnVlcm9uIGNhcmdhZG9zIGFsIGVzcGFjaW8gZGUgdHJhYmFqbyBlbiBSU3R1ZGlvIENsb3VkIGVuIGxhIGNhcnBldGEgIlZpY2hhZGEiCgoKIyMjIDQuUHJlcGFyYWNpw7NuCgpQcmltZXJvLCBzZSBsaW1waWEgbGEgbWVtb3JpYQpgYGB7cn0Kcm0obGlzdD1scygpKQpgYGAKUG9zdGVyaW9ybWVudGUgc2UgaW5zdGFsYW4gbGFzIGxpYnJlcmlhcyBuZWNlc2FyaWFzCmBgYHtyfQpsaXN0Lm9mLnBhY2thZ2VzIDwtIGMoInRpZHl2ZXJzZSIsICJyZ2VvcyIsICJzZiIsICJyYXN0ZXIiLCAiY2FydG9ncmFwaHkiLCAiU3BhdGlhbFBvc2l0aW9uIikKbmV3LnBhY2thZ2VzIDwtIGxpc3Qub2YucGFja2FnZXNbIShsaXN0Lm9mLnBhY2thZ2VzICVpbiUgaW5zdGFsbGVkLnBhY2thZ2VzKClbLCJQYWNrYWdlIl0pXQppZihsZW5ndGgobmV3LnBhY2thZ2VzKSkgaW5zdGFsbC5wYWNrYWdlcyhuZXcucGFja2FnZXMpCmBgYApMdWVnbywgc2UgY2FyZ2FuIGxhcyBpYnJlcmlhcwpgYGB7cn0KbGlicmFyeShwYWNtYW4pCnBhY21hbjo6cF9sb2FkKHRpZHl2ZXJzZSwgcmdlb3MsIHJhc3Rlciwgc2YsIGNhcnRvZ3JhcGh5LCBTcGF0aWFsUG9zaXRpb24scmVhZHhsKQpgYGAKIyMjIDUuTGVlciBsb3MgZGF0b3MgZGUgTkJJCk1lZGlhbnRlIGVsIHNpZ3VpZW50ZSBjw7NkaWdvLCBzZSBsZWUgZWwgYXJjaGl2byAueGxzeCBxdWUgZnVlIGltcG9ydGFkbyBhbCBlc3BhY2lvIGRlIHRyYWJham8KYGBge3J9Cm5iaSA8LSByZWFkX2V4Y2VsKCIuL05CSV9WSUNIQURBLnhsc3giKQpgYGAKQ29uIGxhIGZ1bmNpw7NuICJoZWFkIiBzZSBwdWVkZSB2ZXIgbG9zIGF0cmlidXRvcyBkZSBsYXMgcHJpbWVyYXMgZmlsYXMgZGUgbGEgdmFyaWFibGUgbmJpCmBgYHtyfQpoZWFkKG5iaSkKYGBgCk1lZGlhbnRlIGVsIHNpZ3VpZW50ZSBjw7NkaWdvIHNlIGF2ZXJpZ3VhcsOhIGN1YWwgZXMgZWwgbXVuaWNpcGlvIGNvbiBtYXlvciBwb3JjZW50YWplIGRlIE5CSQpgYGB7cn0KbmJpICU+JXNsaWNlKHdoaWNoLm1heChOQkkpKSAtPiBuYmlfbWF4Cm5iaV9tYXgKYGBgCkFkZW3DoXMgLCBzZSB1c2Fyw6EgIndpY2gubWluIiBwYXJhIGNvbm9jZXIgY3VhbCBlcyBlbCBtdW5pY2lwaW8gY29uIG1lbm9yIHBvcmNlbnRhamUgZGVsIE5CSSAKYGBge3J9Cm5iaSAlPiUgc2xpY2Uod2hpY2gubWluKE5CSSkpIC0+IG5iaV9taW4KbmJpX21pbgpgYGAKTHVlZ28sIHNlIG9yZGVuYW4gbG9zIG11bmljaXBpb3MgcG9yIE5CSSBlbiBvcmRlbiBkZXNjZW5kZW50ZQpgYGB7cn0KbmJpICU+JWFycmFuZ2UoZGVzYyhOQkkpKSAgLT4gbmJpX29yZApuYmlfb3JkCmBgYAojIyMgNi5VbmlyIGxvcyBkYXRvcyBkZSBOQkkgYSBsb3MgbXVuaWNpcGlvcwpFbiBwcmltZXJhIG1lZGlkYSwgc2UgbGVlIGFyY2hpdm8gU2hhcGVmaWxlIGNvcnJlc3BvbmRpZW50ZSBhIGxvcyBtdW5pY2lwaW9zIGRlIFZpY2hhZGEgY29uIGF5dWRhIGRlbCBwYXF1ZXRlICpzZioKYGBge3J9ClZpY2hhZGFfbXVuaWMgPC0gc3RfcmVhZCgiLi9BRE1JTklTVFJBVElWTy9NR05fTVBJT19QT0xJVElDTy5zaHAiKQpgYGAKU2UgcHVlZGUgdmVyIHF1ZSBoYXkgZW4gZWwgb2JqZXRvICJWaWNoYWRhIE11bmljIiwgaGF5IHVuYSBjb2x1bW5hIGxsYW1hZGEgTVBJT19DTk1CUiwgcGFyYSB2ZXIgcXVlIGhheSBkZW50cm8gZGUgZXN0ZSBhdHJpYnV0byBzZSBwdWVkZSBoYWNlciB1c28gZGUgbGEgZnVuY2nDs24gImhlYWQoKSIKYGBge3J9CmhlYWQoVmljaGFkYV9tdW5pYyRNUElPX0NOTUJSKQpgYGAKUGFyYSByZWFsaXphciBsYSB1bmnDs24gZW50cmUgZWwgb2JqZXRvICJWaWNoYWRhX211bmljIiB5IGxvcyBkYXRvcyBkZSBOQkkgc2UgaGFjZSB1c28gZGUgbGEgZnVuY2nDs24gKmxlZnRfam9pbiogY29uc2lkZXJhbmRvIHF1ZSAsIGxhIHZhcmlhYmxlIGNsYXZlIHF1ZSBjb3JyZXNwb25kZSBhbCBjw7NkaWdvIGRlIGxvcyBtdW5pY2lwaW9zIHRpZW5lIGRpZmVyZW50ZSBub21icmUgZW4gY2FkYSBvYmpldG8KYGBge3J9Cm5iaV9WbXVuaWMgPSBsZWZ0X2pvaW4oVmljaGFkYV9tdW5pYywgbmJpLCBieT1jKCJNUElPX0NDREdPIj0iQ09ESUdPIikpCmBgYApTZSBzZWxlY2Npb25hbiBsYXMgdmFyaWFibGVzIGRlbCBub21icmUgZGVsIG11bmljaXBpbywgZWwgY8OzZGlnbyAsIGVsIG5iaSB5IHNlIGFsbWFjZW5hbiBlbiBlbCBvYmpldG8gImNoZWNrX25iaV9tdW5pYyIKYGBge3J9Cm5iaV9WbXVuaWMgJT4lZHBseXI6OnNlbGVjdChNVU5JQ0lQSU8sIE1QSU9fQ0NER08sIE5CSSkgIC0+ICBjaGVja19uYmlfbXVuaWMKaGVhZChjaGVja19uYmlfbXVuaWMpCmBgYApBaG9yYSwgc2UgcmVwcm95ZWN0YW4gbG9zIG11bmljaXBpb3MKYGBge3J9Cm5iaV9tdW5pY19uZXcgPC0gc3RfdHJhbnNmb3JtKG5iaV9WbXVuaWMsIGNycyA9IDMxMTYpCmBgYAojIyMgNy4gRWplbXBsb3MgZGUgbWFwYXMgdGVtw6F0aWNvcwpQYXJhIGVzdGEgc2VjY2nDs24gLCBzZSBoYXLDoSB1c28gZGUgbGEgbGlicmVyaWEgKkNhcnRvZ3JhcGh5KiAsIGVzdGEgdGllbmUgY29tbyBvYmpldGl2byBjcmVhciBtYXBhcyB0ZW3DoXRpY29zIGNvbiB1bmEgY2FsaWRhZCB2aXN1YWwgZGUgYXF1ZWxsb3MgcXVlIHNlIGNvbnN0cnV5ZW4gZW4gc3Ugc29mdHdhcmUgR0lTLkVzdGEgbGlicmVyaWEgY3VlbnRhIGNvbiBmdW5jaW9uZXMgaW50dWl0aXZhcyB5IGVzIGNvbXBhdGlibGUgY29uIGxvcyBmbHVqb3MgZGUgdHJhYmFqbyBjb211bmVzIGVuIFIuCkxhIGxpYnJlcmlhIENhcnRvZ3JhcGh5IHVzYSBlbGVtZXRvcyAqc2YqIG8gKnNwKiBwYXJhIHByb2R1Y2lyIGdyw6FmaWNvcyBiYXNlLkxhIG1heW9yaWEgZGUgbG9zIGNvbXBvbmVudGVzIGludGVybm9zIGRlIGVzdGUgcGFxdWV0ZSBzZSBiYXNhbiBlbiBmdW5jaW9uYWxpZGFkZXMgKnNmKiB5IHBvciBlc3RvLCBzZSBzdWVsZW4gdXNhciBsb3Mgb2JqZXRvcyBlc3BhY2lhbGVzIGVuIGZvcm1hdG8gKnNmKgoKIyMjIyA3LjEgTWFwYSBiYXNlIHBvciBPcGVuU3RyZWV0TWFwIHkgc8OtbWJvbG9zIHByb3BvcmNpb25hbGVzClNlIHVzYSBsYSBmdW5jacOzbiAqKmdldFRpbGVzKCkqKiBvICoqdGlsZXNMYXllcioqIHBhcmEgZGVzY2FyZ2FyIHkgbW9zdHJhciBsb3MgbW9zYWljb3MgZGUgT3BlblN0cmVldE1hcC4gTGEgZnVuY2nDs24gKipwcm9wU3ltYm9sc0xheWVyKCkqKiBtdWVzdHJhIHNpbWJvbG9zIGNvbiDDoXJlYXMgcHJvcG9yY2lvbmFsZXMgYSB1bmEgdmFyaWFibGUgY3VhbnRpdGF0aXZhIDsgU2UgaGFjZSB1c28gZGVsIGFyZ3VtZW50byBwdWxnYWRhcyBwYXJhIHBlcnNvbmFsaXphciBlbCB0YW1hw7FvIGRlIGxvcyBzaW1ib2xvcywgZXN0b3Mgc2ltYm9sb3MgcHVlZGVuIHNlciBjaXJjdWxvcyxjdWFkcmFkb3MgeSBiYXJyYXMsIHBhcmEgZXN0ZSBtYXBhIGVuIHBhcnRpY3VsYXIgc2UgdXNhcsOhbiBsb3MgY2lyY3Vsb3MgY29tbyBzaW1ib2xvcwpgYGB7cn0KbWFwYV9iYXNlIDwtIGdldFRpbGVzKHggPSBuYmlfbXVuaWNfbmV3LCB0eXBlID0gIk9wZW5TdHJlZXRNYXAiLCB6b29tID0gNywgY2FjaGVkaXIgPSBUUlVFLCBjcm9wID0gRkFMU0UpCmBgYApFbiBlbCBzaWd1aWVudGUgY8OzZGlnbyBzZSBlc3RhYmxlY2VuIGxhcyBtw6FyZ2VuZXMgeSBkZSBmb3JtYSBwb3N0ZXJpb3IsIHNlIGFncmVnYW4gZGlmZXJlbnRlcyBvcGNpb25lcyBwYXJhIGxhIGZ1bmNpw7NuICoqcHJvcFN5bWJvbHNMYXllcigpKiogLCBlbnRyZSBlc3RhcyBvcGNpb25lcyBzZSBlbmN1ZW50cmEgZWwgdGlwbyBkZSBzaW1ib2xvLCBlbCBjb2xvciAsIGVsIHRhbWHDsW8geSBsYSBwb3NpY2nDs24gZGUgbGEgY29udmVuY2nDs24gbyBsZXllbmRhIHF1ZSBheXVkYXLDoSBhIGludGVycHJldGFyIGVsIG1hcGEgLiBDb24gbGF5b3V0TGF5ZXIoKSBzZSB0cmF6YSB1bmEgY2FwYSBkZSBkaXNlw7FvICwgZW4gZXN0YSBzZSBpbmNsdXllbiBlbGVtZW50b3MgY29tbyBlbCB0w610dWxvIGRlbCBtYXBhICwgbGEgZXNjYWxhICwgZWwgbm9tYnJlIGRlbCBhdXRvciB5IGxhcyBmdWVudGVzIGRlIGluZm9ybWFjacOzbiAuIFBvciDDumx0aW1vIHNlIGFncmVnIGxhIGZsZWNoYSAgcXVlIGluZGljYSBlbCBub3J0ZQpgYGB7cn0Kb3BhciA8LSBwYXIobWFyID0gYygwLDAsMS4yLDApKQp0aWxlc0xheWVyKHggPSBtYXBhX2Jhc2UpCnBsb3Qoc3RfZ2VvbWV0cnkobmJpX211bmljX25ldyksIGNvbCA9IE5BLCBib3JkZXIgPSAiZ3JheTIwIiwgYWRkPVRSVUUpCnByb3BTeW1ib2xzTGF5ZXIoeCA9IG5iaV9tdW5pY19uZXcsIHZhciA9ICJOQkkiLCBpbmNoZXMgPSAwLjIxLCBjb2wgPSAic2FsbW9uMyIsbGVnZW5kLnRpdGxlLmNleCA9IDAuOCwKICBsZWdlbmQudmFsdWVzLmNleCA9IDAuNTUsIGxlZ2VuZC5wb3MgPSAicmlnaHQiLCAgbGVnZW5kLnRpdGxlLnR4dCA9Ik5CSSIsIGxlZ2VuZC5zdHlsZSA9ICJjIixsZWdlbmQuZnJhbWUgPSBGQUxTRSkKbGF5b3V0TGF5ZXIodGl0bGUgPSAiIERpc3RyaWJ1Y2nDs24gZGUgTkJJIGVuIFZpY2hhZGEiLAogICAgICAgICAgICBzb3VyY2VzID0gIkZ1ZW50ZXM6IERBTkUsIDIwMThcbsKpIE9wZW5TdHJlZXRNYXAiLAogICAgICAgICAgICBhdXRob3IgPSAiIEFuZ2llIEFsZWphbmRyYSBKdXlvICIsCiAgICAgICAgICAgIGZyYW1lID0gVFJVRSwgbm9ydGggPSBGQUxTRSwgdGFidGl0bGUgPSBUUlVFLCBzY2FsZSA9ICJhdXRvIikKbm9ydGgocG9zID0gInRvcGxlZnQiKQpgYGAKIyMjIyA3LjIgTWFwYSBkZSBjb3JvcGxldGFzCkVuIGxvcyBtYXBhcyBkZSBjb3JvcGxldGFzICwgbGFzIMOhcmVhcyBzZSBzb21icmVhbiBkZSBhY3VlcmRvIGFsIGNhbWJpbyBlbiB1bmEgdmFyaWFibGUgY3VhbnRpdGF0aXZhIGRldGVybWluYWRhICwgZXN0ZSB0aXBvIGRlIG1hcGFzIGVzIHVzYWRvIHBhcmEgcmVwcmVzZW50YXIgcmF6b25lcyBvIGluZGljZXMgeSBlbiBlc3RlIGNhc28gbGEgdmFyaWJsZSBjdWFudGl0YXRpdmEgYSB1dGlsaXphciBlcyBlbCBwb3JjZW50YWplIGRlIG5lY2VzaWRhZGVzIGLDoXNpY2FzIGluc2F0aXNmZWNoYXMKCkxhIGZ1bmNpw7NuIHF1ZSBwZXJtaXRlIHJlYWxpemFyIG1hcGFzIGRlIGNvcm9wbGV0YXMgZXMgKipjaG9yb0xheWVyKCkqKiAuTG9zIGFyZ3VtZW50b3MgKm5jbGFzcyogLCAqbWV0aG9kKiB5ICpicmVha3MqIHBlcm1pdGVuIHBlcnNvbmFsaXphciBsYSBjbGFzaWZpY2FjacOzbiBkZSBsYSB2YXJpYWJsZSwgbGEgZnVuY2nDs24gKipnZXRicmVha3MoKSoqIHRhbWJpw6luIHBlcm1pdGVuIGNsYXNpZmljYXIgbGEgdmFyaWFibGUgZnVlcmEgZGUgKipjaG9yb0xheWVyKCkqKiAuIExhcyBwYWxldGFzIGRlIGNvbG9yZXMgc2UgZGVmaW5lbiBjb24gKmNvbCogeSBzZSBwdWVkZSBjcmVhciB1biBjb25qdW50byBkZSBjb2xvcmVzIGNvbiAgKipjYXJ0by5wYWwoKSoqCmBgYHtyfQpvcGFyIDwtIHBhcihtYXIgPSBjKDAsMCwxLjIsMCkpCnBhcihiZz0iZ3JleTkwIikKcGxvdChzdF9nZW9tZXRyeShuYmlfbXVuaWNfbmV3KSwgY29sID0gTkEsIGJvcmRlciA9IE5BLCBiZyA9ICJ3aGl0ZSIpCmNob3JvTGF5ZXIoeCA9IG5iaV9tdW5pY19uZXcsIHZhciA9ICJOQkkiLG1ldGhvZCA9ICJnZW9tIixuY2xhc3M9NSwKICBjb2wgPSBjYXJ0by5wYWwocGFsMSA9ICJyZWQucGFsIiwgbjEgPSA1KSwKICBib3JkZXIgPSAiZ3JheTIwIiwgbHdkID0gMC41LGxlZ2VuZC5wb3MgPSAidG9wcmlnaHQiLCBsZWdlbmQudGl0bGUudHh0ID0gIk5CSSIsYWRkID0gVFJVRSkgCmxheW91dExheWVyKHRpdGxlID0gIkRpc3RyaWJ1Y2nDs24gTkJJIFZpY2hhZGEiLCBzb3VyY2VzID0gIkZ1ZW50ZTogREFORSwgMjAxOCIsYXV0aG9yID0gIkFuZ2llIEFsZWphYW5kcmEgSnV5byAiLCBmcmFtZSA9IFRSVUUsIG5vcnRoID0gRkFMU0UsIHRhYnRpdGxlID0gVFJVRSwgY29sPSJibGFjayIpIApub3J0aChwb3MgPSAidG9wbGVmdCIpCmBgYApEZSBsb3MgZGF0b3MgcHJlc2VudGFkb3MgY29uIGFudGVyaW9yaWRhZCB5IGxhIGluZm9ybWFjacOzbiBvYnRlbmlkYSBzZSBjb25jbHV5ZSBxdWUgZW4gIGVsIGRlcGFydGFtZW50byBWaWNoYWRhICxlbCBtdW5pY2lwaW8gZGUgQ3VtYXJpYm8gdGllbmUgZWwgcG9yY2VudGFqZSBkZSBOQkkgbcOhcyBhbHRvIC5FbCBvYmpldGl2byBkZSBlc3RvcyBpbmRpY2Fkb3JlcyB5ICwgZW4gZXN0YSBzdHVhY2nDs24gZXNwZWPDrWZpY2EgZWwgY2F0YWxvZ2FyIGxhIHBvYmxhY2lvbiBkZSBlc3RlIG11bmljaXBpbyBjb21vIHBvYnJlICwgZXMgcGVybWl0aXIgYSBsb3Mgb3JnYW5pc21vcyBhIG5pdmVsIG5hY2lvbmFsIHkgZGVwYXJ0YW1lbnRhbCBsYSB0b21hIGRlIGRlc2ljaW9uZXMgeSBlbCBkZXNhcnJvbGxvIGRlIHBsYW5lcyBxdWUgYnVzcXVlbiBzYXRpc2ZhY2VyIGVsIHRpcG8gZGUgbmVjZXNpZGFkZXMgcXVlIHByZXNlbnRhbiBzdXMgaGFiaXRhbnRlcy4KCiMjIyMgNy4zIFNpbWJvbG9zIHByb3BvcmNpb25hbGVzIHkgbWFwYSBkZSB0aXBvbG9nw61hCgojIyMjIyA3LjMuMSBOaXZlbGVzIGRlIHBvYnJlemEKTGEgZnVuY2nDs24gKipwcm9wU3ltYm9sc1R5cG9MYXllcigpKiogcGVybWl0ZSByZXByZXNlbnRhciB2YXJpYWJsZXMgY3VhbnRpdGF0aXZhcyB5IGN1YWxpdGF0aXZhcyBkZSBmb3JtYSBzaW11bHTDoW5lYSAsIHNlIHRyYXRhIGRlIHVuIHPDrW1ib2xvIGN1eW8gdGFtYcOxbyBkZXBlbmRlIGRlIGxhIHZhcmlhYmxlIGN1YW50aXRhdGl2YSB5IGN1eW8gY29sb3IgdmFyw61hIGRlIGFjdWVyZG8gYSBsYSB2YXJpYWJsZSBjdWFsaXRhdGl2YSwgdXRpbGl6YW5kbyB1bmEgY29tYmluYWNpw7NuIGRlIGxvcyBhcmd1bWVudG9zIHByb3BTeW1ib2xzTGF5ZXIoKSB5IHR5cG9sYXllcigpLlBhcmEgcG9kZXIgcmVhbGl6YXIgZXN0ZSBtYXBhIHNlIGRlYmUgY3JlYXIgdW5hIGZ1bmNpw7NuIGN1YWxpdGF0aXZhIGNvbiBheXVkYSBkZSBsYSBmdW5jacOzbiBtdXRhdGUoKQpgYGB7cn0KbmJpX211bmljX3AgPC0gZHBseXI6Om11dGF0ZShuYmlfbXVuaWNfbmV3LCBQb2JyZXphID0gaWZlbHNlKE1JU0VSSUEgPiAyMCwgIkV4dHJlbWEiLCBpZmVsc2UoSEFDSU5BTUlFTlRPID4gNSwgIkFsdGEiLCJJbnRlcm1lZGlhIikpKQpgYGAKRWwgbnVldm8gYXRyaWJ1dG8gcG9icmV6YSAsIHNlIGFsbWFjZW7DsyBlbiBlbCBvYmpldG8gIm5iaV9tdW5pY18yIiAsIHkgc2UgY2xhc2lmaWPDsyBhIHRyYXZlcyBkZSBsb3MgdmFsb3JlcyBkZWZpbmlkb3MgYSBjb250aW51YWNpw7NuIDogU2kgbGEgdmFyaWFibGUgTUlTRVJJQSBlcyBtYXlvciBhIDIwLCBzZSBjYXRhbG9nYXLDoSBjb21vIHBvYnJlemEgZXh0cmVtYSA7IEFxdWVsbG9zIG11bmljaXBpb3MgcXVlIHBvc2VhbiB1biB2YWxvciBkZSBtaXNlcmlhIG1lbm9yIGEgMjAgc2UgY2xhc2lmaWNhbiBkZSBhY3VlcmRvIGEgbG9zIHZhbG9yZXMgZGUgSEFDSU5BTUlFTlRPICwgc2kgZXN0ZSDDumx0aW1vIGVzIG1heW9yIGEgNSBzZSBjbGFzaWZpY2Fyw6EgY29tbyBwb2JyZXphIGFsdGEgLCBkZSBsbyBjb250cmFyaW8gc2Vyw6EgcG9icmV6YSBpbnRlcm1lZGlhLkFsIHVzYXIgbGEgZnVuY2nDs24gKmhlYWQoKSogLCBzZSB2ZSBsYSBudWV2YSBjb2x1bW5hIGNvbiBsYSB2YXJpYWJsZSBwb2JyZXphIGNsYXNpZmljYWRhIGNvbiBsb3MgcGFyw6FtZXRyb3MgZGVmaW5pZG9zIGNvbiBhbnRlcmlvcmlkYWQKYGBge3J9CmhlYWQobmJpX211bmljX3ApCmBgYApgYGB7cn0KbGlicmFyeShzZikKbGlicmFyeShjYXJ0b2dyYXBoeSkKb3BhciA8LSBwYXIobWFyID0gYygwLDAsMS4yLDApKQpwbG90KHN0X2dlb21ldHJ5KG5iaV9tdW5pY19wKSwgY29sPSIjZmFmYmZmIiwgYm9yZGVyPSIjMjYyNjI0IiwgYmcgPSAiI2VkZjJmZiIsIGx3ZCA9IDAuNSkKcHJvcFN5bWJvbHNUeXBvTGF5ZXIoeCA9IG5iaV9tdW5pY19wLCB2YXIgPSAiTkJJIiwgaW5jaGVzID0gMC43LCBzeW1ib2xzID0gInNxdWFyZSIsIGJvcmRlciA9ICJ3aGl0ZSIsIGx3ZCA9IC41LGxlZ2VuZC52YXIucG9zID0gImxlZnQiLCBsZWdlbmQudmFyLnRpdGxlLnR4dCA9ICJOQkkiLHZhcjIgPSAiUG9icmV6YSIsIGxlZ2VuZC52YXIyLnZhbHVlcy5vcmRlciA9IGMoIkV4dHJlbWEiLCAiQWx0YSIpLGNvbCA9IGNhcnRvLnBhbChwYWwxID0gIm11bHRpLnBhbCIsIG4xID0gMiksIGxlZ2VuZC52YXIyLnBvcyA9ICJyaWdodCIsIGxlZ2VuZC52YXIyLnRpdGxlLnR4dCA9ICJQb2JyZXphIikgCmxheW91dExheWVyKHRpdGxlPSJEaXN0cmlidWNpw7NuIGRlbCBOQkkgZW4gVmljaGFkYSIsIGF1dGhvciA9ICJBbmdpZSBBbGVqYW5kcmEgSnV5byIsICBzb3VyY2VzID0gIkZ1ZW50ZXM6IERBTkUsIDIwMTgiLCBzY2FsZSA9IDEsIHRhYnRpdGxlID0gVFJVRSwgZnJhbWUgPSBUUlVFKQpub3J0aChwb3MgPSAidG9wbGVmdCIpCmBgYApFbiBlbCBhbnRlcmlvciBtYXBhIHNlIHB1ZWRlIHZlciBxdWUgbG9zIG11bmljaXBpb3MgZGUgVmljaGFkYSBzb24gY2xhc2lmaWNhZG9zIGNvbiBwb2JyZXphIGFsdGEgeSBleHRyZW1hICwgZXN0byBzZSBkZWJlIGEgcXVlIFZpY2hhZGEgZXMgY29uc2lkZXJhZG8gY29tbyB1bm8gZGUgbG9zIGRlcGFydGFtZW50b3MgbcOhcyBwb2JyZXMgZGUgYWN1ZXJkbyBjb24gbGEgbWVkaWRhIGRlICBbUG9icmV6YSBtdWx0aWRpbWVuc2lvbmFsXShodHRwczovL3d3dy5kYW5lLmdvdi5jby9pbmRleC5waHAvZXN0YWRpc3RpY2FzLXBvci10ZW1hL3BvYnJlemEteS1jb25kaWNpb25lcy1kZS12aWRhL3BvYnJlemEteS1kZXNpZ3VhbGRhZC9tZWRpZGEtZGUtcG9icmV6YS1tdWx0aWRpbWVuc2lvbmFsLWRlLWZ1ZW50ZS1jZW5zYWwpLCBxdWUgZXMgb3RybyBtw6l0b2RvIGFwbGljYWRvIHBvciBlbCBEQU5FIHBhcmEgbGEgbWVkaWNpw7NuIGRlIGxhIHBvYnJlemEgYSBuaXZlbCBuYWNpb25hbCBjb24gZGF0b3MgdG9tYWRvcyBkZSBsYSBlbmN1ZXN0YSBuYWNpb25hbCBkZSBjYWxpZGFkIGRlIHZpZGE6ICFbXSguL2lwbS5wbmcpIAoKIyMjIyMgNy4zLjIgQ29uZGljaW9uZXMgU2FuaXRhcmlhcyBwYXJhIGxvcyBtdW5pY2lwaW9zIGRlIFZpY2hhZGEKCkVuIGVsIMOtbmRpY2UgZGUgVml2aWVuZGFzIGNvbiBzZXJ2aWNpb3MgaW5hZGVjdWFkb3Mgc2UgdG9tYSBlbiBjdWVudGEgZWwgYWNjZXNvIGEgY29uZGljaW9uZXMgc2FuaXRhcmlhcyBtw61uaW1hcy5BdW5xdWUgZW4gbG9zIHVsdGltb3MgYcOxb3Mgc2UgaGEgYW1wbGlhZG8gbGEgY29iZXJ0dXJhIGRlIGFjdWVkdWN0byB5IGFsY2FudGFyaWxsYWRvIGVuIGVsIGRlcGFydGFtZW50byAKCkVsIElSQ0EgKMONbmRpY2UgZGUgUmllc2dvIGRlIGxhIENhbGlkYWQgZGVsIEFndWEpIGVzIHVuIMOtbmRpY2UgZXhwcmVzYWRvIGEgdHJhdsOpcyBkZSBwb3JjZW50YWplcyAsIGVzdGUgZGV0ZXJtaW5hIGVsIGdyYWRvIGRlIHJpZXNnbyBhIGxhIHNhbHVkIHJlbGFjaW9uYWRvIGNvbiAgbGEgY2FsaWRhZCBkZSBhZ3VhIHBhcmEgY29uc3VtbyBodW1hbm8gYSB0cmF2w6lzIGRlIGVsIGFuw6FsaXNpcyBkZSBjYXJhY3RlcsOtc3RpY2FzIGbDrXNpY2FzICwgcXXDrW1pY2FzIHkgbWljcm9iaW9sw7NnaWNhcy5FbCBhZ3VhIHNlIGNvbnNpZGVyYSBhcHRhIHBhcmEgZWwgY29uc3VtbyBodW1hbm8gY3VhbmRvIGVzdGUgw61uZGljZSBlc3TDoSBlbnRyZSAqKjAgLSA1ICUgKiogLHkgc2Vnw7puIGxvcyBkYXRvcyAgZGVsIGVzdHVkaW8gc2VjdG9yaWFsIGRlIGxvcyBzZXJ2aWNpb3MgcMO6YmxpY29zIGRlIGFjdWVkdWN0byB5IGFsY2FudGFyaWxsYWRvLCByZWFsaXphZG8gcG9yIGxhIHN1cGVyaW50ZW5kZW5jaWEgZGUgc2VydmljaW9zIHDDumJsaWNvcyBkb21pY2lsaWFyaW9zIHNlIGhhIGNsYXNpZmljYWRvIGVsIGFndWEgcXVlIGxsZWdhIGEgbGEgcG9ibGFjacOzbiBkZWwgVmljaGFkYSBjb21vIGFndWEgbm8gYXB0YSBwYXJhIGNvbnN1bW8gaHVtYW5vIHBvciBwcmVzZW50YXIgdW4gw61uZGljZSBkZSAqKjExLjglIHkgMTQuOCUqKiAgZW4gbG9zIGHDsW9zIDIwMTcgeSAyMDE4IHJlc3BlY3RpdmFtZW50ZQoKRW4gZWwgc2lndWllbnRlIGPDs2RpZ28gc2UgY2xhc2lmaWNhcsOhbiBsYXMgY29uZGljaW9uZXMgc2FuaXRhcmlhcyBkZSBsb3MgbXVuaWNpcGlvcyBkZSBWaWNoYWRhIGRlIGFjdWVyZG8gY29uIGVsIHZhbG9yIHF1ZSB0b21lbiBlbiBsYSB2YXJpYWJsZSAqIlNFUlZJQ0lPUyIqCmBgYHtyfQpuYmlfbXVuaWNfcyA8LSBkcGx5cjo6bXV0YXRlKG5iaV9tdW5pY19uZXcsIFNlcnZpY2lvc19pbmFkZWN1YWRvcz0gaWZlbHNlKFNFUlZJQ0lPUyA+IDUwLCAiTXV5IEJhamFzIiwgaWZlbHNlKFNFUlZJQ0lPUyA+IDE2LCAiQmFqYXMiLCJBY2VwdGFibGVzIikpKQpgYGAKU2UgY29tcHJ1ZWJhIHF1ZSBlbiBlbCBudWV2byBvYmpldG8gYXBhcmV6Y2EgbGEgbnVldmEgdmFyaWFibGUgY3VhbGl0YXRpdmEgY29ycmVjdGFtZW50ZSBjbGFzaWZpY2FkYSBkZSBhY3VlcmRvIGEgbG9zIHZhbG9yZXMgYXNpZ25hZG9zCmBgYHtyfQpoZWFkKG5iaV9tdW5pY19zKQpgYGAKYGBge3J9CmxpYnJhcnkoc2YpCmxpYnJhcnkoY2FydG9ncmFwaHkpCm9wYXIgPC0gcGFyKG1hciA9IGMoMCwwLDEuMiwwKSkKcGxvdChzdF9nZW9tZXRyeShuYmlfbXVuaWNfcyksIGNvbD0iI2RkZTBkYyIsIGJvcmRlcj0iIzM1MzYzNSIsIGJnID0id2hpdGUiLCBsd2QgPSAwLjUpCnByb3BTeW1ib2xzVHlwb0xheWVyKHggPSBuYmlfbXVuaWNfcywgdmFyID0gIk5CSSIsIGluY2hlcyA9IDAuMzUsIHN5bWJvbHMgPSAiY2lyY2xlIiwgYm9yZGVyID0gImJsYWNrIiwgbHdkID0gLjQsIGxlZ2VuZC52YXIucG9zID0gImxlZnQiLCBsZWdlbmQudmFyLnRpdGxlLnR4dCA9ICJOQkkiLHZhcjIgPSAiU2VydmljaW9zX2luYWRlY3VhZG9zIiwgbGVnZW5kLnZhcjIudmFsdWVzLm9yZGVyID0gYygiTXV5IEJhamFzIiwgIkJhamFzIiwgIkFjZXB0YWJsZXMiKSxjb2wgPSBjYXJ0by5wYWwocGFsMSA9ICJtdWx0aS5wYWwiLCBuMSA9IDMpLAogIGxlZ2VuZC52YXIyLnBvcyA9ICJyaWdodCIsIGxlZ2VuZC52YXIyLnRpdGxlLnR4dCA9ICJDb25kaWNpb25lcyBTYW5pdGFyaWFzIikgCmxheW91dExheWVyKHRpdGxlPSJEaXN0cmlidWNpw7NuIGRlbCBOQkkgZW4gVmljaGFkYSIsIAogICAgICAgICAgICBhdXRob3IgPSAiQW5naWUgQWxlamFuZHJhIEp1eW8iLCAKICAgICAgICAgICAgc291cmNlcyA9ICJGdWVudGVzOiBEQU5FLCAyMDE4IiwgCiAgICAgICAgICAgIHNjYWxlID0gMSAsIHRhYnRpdGxlID0gVFJVRSwgZnJhbWUgPSBUUlVFKQpub3J0aChwb3MgPSAidG9wbGVmdCIpCmBgYAojIyMjIDcuNCBNYXBhIGRlIGV0aXF1ZXRhcwpFbiBlc3RlIG1hcGEgc2UgY29tYmluYW4gbGFzIGZ1bmNpb25lcyAqKkNob3JvTGF5ZXIoKSoqIHkgKipsYWJlbExheWVyKCkqKiBwYXJhIHF1ZSBzZSBjb2xvcmVlbiBsYXMgw6FyZWFzIGNvcnJlc3BvbmRpZW50ZXMgYSBtdW5pY2lwaW8gZGUgYWN1ZXJkbyBjb24gZWwgcG9yY2VudGFqZSBkZSBOQkkgeSBhZGVtw6FzIGRlIGVzbyAsIHNlIHB1ZWRhIHZpc3VhbGl6YXIgZW4gZWwgbWFwYSBlbCBub21icmUgZGVsIG11bmljaXBpbyBhbCBjdWFsIGNvcnJlc3BvbmRlIGNhZGEgw6FyZWEKYGBge3J9CmxpYnJhcnkoc2YpCmxpYnJhcnkoY2FydG9ncmFwaHkpCm9wYXIgPC0gcGFyKG1hciA9IGMoMCwwLDEuMiwwKSkKcGFyKGJnPSJncmV5MjUiKQpwbG90KHN0X2dlb21ldHJ5KG5iaV9tdW5pY19wKSwgY29sID0gIiNlNGU5ZGUiLCBib3JkZXIgPSAiZGFya3NlYWdyZWVuNCIsIAogICAgIGJnID0gImdyZXk3NSIsIGx3ZCA9IDAuNSkKY2hvcm9MYXllciggeCA9IG5iaV9tdW5pY19uZXcsIHZhciA9ICJOQkkiLCBtZXRob2QgPSAiZ2VvbSIsIG5jbGFzcz01LCBjb2wgPSBjYXJ0by5wYWwocGFsMSA9ICJ3aW5lLnBhbCIsIG4xID0gNSksIGJvcmRlciA9ICJ3aGl0ZSIsIGx3ZCA9IDAuNSwgbGVnZW5kLnBvcyA9ICJ0b3ByaWdodCIsIGxlZ2VuZC50aXRsZS50eHQgPSAiTkJJIiwgYWRkID0gVFJVRSkgCmxhYmVsTGF5ZXIoeCA9IG5iaV9tdW5pY19wLCB0eHQgPSAiTVVOSUNJUElPIiwgY29sPSAid2hpdGUiLCBjZXggPSAwLjQsIGZvbnQgPSA0LCBoYWxvID0gVFJVRSwgYmcgPSAiZ3JleTI1IiwgciA9IDAuMSwgb3ZlcmxhcCA9IEZBTFNFLCBzaG93LmxpbmVzID0gRkFMU0UpCmxheW91dExheWVyKCB0aXRsZSA9ICJNdW5pY2lwaW9zIGRlIFZpY2hhZGEiLCAKICBzb3VyY2VzID0gIkZ1ZW50ZXM6IERBTkUsIDIwMTgiLCAgYXV0aG9yID0gIkFuZ2llIEFsZWphbmRyYSBKdXlvIiwgCiAgZnJhbWUgPSBUUlVFLAogIG5vcnRoID0gVFJVRSwgCiAgdGFidGl0bGUgPSBUUlVFLCAKICB0aGVtZSA9ICJ0YXVwZS5wYWwiKSAKYGBgCiMjIyMgOCBNYXBhcyBlbXBsZWFuZG8gbGFzIGVzdGFkw61zdGljYXMgYWdyaWNvbGFzIG11bmljaXBhbGVzCgojIyMjIyA4LjEgTWFwYXMgZGUgaXNvcGxldGFzIAoKClNlIHJlYWxpemFyw6EgdW4gbWFwYSBkZSBpc29wbGV0YXMgcGFyYSBtb3N0cmFyIGxhIGRpc3RyaWJ1Y2nDs24gZGUgbGEgcHJvZHVjY2nDs24gZGUgWXVjYSBlbiBlbCBkZXBhcnRhbWVudG8gZGVsIFZpY2hhZGEuTG9zIG1hcGFzIGRlIGlzb3BsZXRhcyBzZSBiYXNhbiBlbiBlbCBzdXB1ZXN0byBkZSBxdWUgZWwgZmVuw7NtZW5vIGEgcmVwcmVzZW50YXIgdGllbmUgdW5hIGRpc3RyaWJ1Y2nDs24gY29udGludWEgeSBhIGRpZmVyZW5jaWEgZGUgbG9zIG1hcGFzIGNvcm9wbMOpdGljb3MgbG9zIG1hcGFzIGRlIGlzb3BsZWF0YXMgbm8gc2UgcmlnZW4gcG9yIGxhIGRpdmlzacOzbiB0ZXJyaXRvcmlhbC4gRXN0ZSB0aXBvIGRlIG1hcGFzIHNlIHJlYWxpemFuIGNvbiBheXVkYSBkZSBkZSBsYSBmdW5jacOzbiBzbW9vdGhMYXllcigpIHF1ZSBkZXBlbmRlIGVuIGdyYW4gbWVkaWRhIGRlIGxhIGxpYnJlcmlhIFNwYXRpYWwgcG9zaXRpb24gLCBwYXJhIHBvZGVyIG1vc3RyYXIgdW5hIGNhcGEgZGUgaXNvcGxldGEgc2UgbGUgYXNpZ25hbiB1bmEgc2VyaWUgZGUgcGFyw6FtZXRyb3MgYSBsYSBmdW5jacOzbiAKCkNvbW8geWEgc2UgaGFiaWEgbWVuY2lvbmFkbyBlbCBtYXBhIGNvcnJlc3BvbmRlcsOhIGEgbGEgZGlzdHJpYnVjacOzbiBkZSBsYSBwcm9kdWNjacOzbiBkZSBZdWNhICxwb3IgdGFudG8gc2UgdXNhcsOhIGVsIGFyY2hpdm8gY29ycmVzcG9uZGllbnRlIGEgbGFzIGV2YWx1YWNpb25lcyBhZ3JvcGVjdWFyaWFzIG11bmljaXBhbGVzIHF1ZSBzZSBlbmN1ZW50cmEgZW4gZWwgZGlyZWN0b3JpbyBkZSB0cmFiYWpvLCBwdWVzIGZ1ZSB1c2FkbyBlbiB1biBjdWFkZXJubyBhbnRlcmlvciBwYXJhIGlsdXN0cmFyIGxhcyB1bmlvbmVzIGJhc2FkYXMgZW4gYXRpYnV0b3MuU2UgdXNhIGVsIHNpZ3VpZW50ZSBjw7NkaWdvIHBhcmEgbGVlciBlbCBhcmNoaXZvICoiRVZBX1ZJQ0hBREEiKiBxdWUgc2UgZW5jdWVudHJhIGVuIGZvcm1hdG8gLnhsc3ggeSBxdWUgY29udGllbmUgZXN0b3MgZGF0b3MgcGFyYSBlbCBhw7FvIDIwMTggCmBgYHtyfQpjdWx0aXZvczIwMTggPC0gcmVhZF9leGNlbCgiLi9FVkFfVklDSEFEQS54bHN4IikKYGBgClNlIHVzYSBkZSBudWV2byBsYSBmdW5jacOzbiBoZWFkIHBhcmEgdmVyIGVsIGNvbnRlbmlkbwpgYGB7cn0KaGVhZChjdWx0aXZvczIwMTgpIApgYGAKU2UgZmlsdHJhIGVsIGN1bHRpdm8gZGUgbnVlc3RybyBpbnRlcsOpcwpgYGB7cn0KY3VsdGl2b3MyMDE4ICU+JQogIGZpbHRlcihDdWx0aXZvID09ICJZVUNBIikgLT4gWTIwMTgKYGBgClNlIGNyZWEgdW5hIG51ZXZhIHZhcmlhYmxlIGNvcnJlc3BvbmRpZW50ZSBhbCBjb2RpZ28gZGVsIG11bmljaXBpbyBkb25kZSBzZSB0cmFuc2Zvcm1hIGEgY2FyYWN0ZXIgeSBsdWVnbyBhIGZhY3RvciBwYXJhIHBvZGVyIHJlYWxpemFyIGRlIGZvcm1hIHBvc3RlcmlvciBsYSB1bmnDs24gY29uIGxvcyBkYXRvcyBlc3BhY2lhbGVzIApgYGB7cn0KWTIwMTgkVEVNUCA8LSBhcy5jaGFyYWN0ZXIoWTIwMTgkQ09EX01VTikKWTIwMTgkTVBJT19DQ0RHTyA8LSBhcy5mYWN0b3IocGFzdGUoWTIwMTgkVEVNUCkpCmBgYApgYGB7cn0KWV9tdW5pYyA9IGxlZnRfam9pbihWaWNoYWRhX211bmljLCBZMjAxOCwgYnk9Ik1QSU9fQ0NER08iKQpgYGAKU2UgcmV2aXNhIGVsIHByb2R1Y3RvIGRlIGxhIHVuacOzbiBlbnRyZSBsb3MgYXRyaWJ1dG9zIHkgbGEgY2FwYSBlc3BhY2lhbApgYGB7cn0KaGVhZChZX211bmljKQpgYGAKU2UgcmVwcm95ZWN0YW4gbG9zIG11bmljaXBpb3MgeSBwb3IgdWx0aW1vIHNlIGVqZWN1dGEgZWwgY29kaWdvIHBhcmEgdmlzdWFsaXphciBlbCBtYXBhCmBgYHtyfQpyZXBfWSA8LSBzdF90cmFuc2Zvcm0oWV9tdW5pYywgY3JzID0gMzExNikKYGBgCmBgYHtyfQpvcGFyIDwtIHBhcihtYXIgPSBjKDAsMCwxLjIsMCkpCnBsb3Qoc3RfZ2VvbWV0cnkocmVwX1kpLCBjb2wgPSBOQSwgYm9yZGVyID0gImJsYWNrIiwgYmcgPSAid2hpdGUiKQpzbW9vdGhMYXllcih4ID0gcmVwX1ksIHZhciA9ICdQcm9kdWNjaW9uJywgdHlwZWZjdCA9ICJleHBvbmVudGlhbCIsIHNwYW4gPSA3NTAwMCwgYmV0YSA9IDIsIG5jbGFzcyA9IDYsIGNvbCA9IGNhcnRvLnBhbChwYWwxID0gJ2JsdWUucGFsJywgbjEgPSA2KSwgYm9yZGVyID0gImdyZXkiLCBsd2QgPSAwLjUsIG1hc2sgPSByZXBfWSwgbGVnZW5kLnZhbHVlcy5ybmQgPSAtMSwgbGVnZW5kLnRpdGxlLnR4dCA9ICJQcm9kdWNjaW9uIiwgbGVnZW5kLnBvcyA9ICJ0b3ByaWdodCIsIGFkZD1UUlVFKQpsYXlvdXRMYXllcih0aXRsZSA9ICJEaXN0cmlidWNpw7NuIGVuIGxhIHByb2R1Y2Npw7NuIGRlIFl1Y2EgZW4gVmljaGFkYSIsc291cmNlcyA9ICJGdWVudGU6IERBTkUgeSBNQURSLCAyMDE4IixhdXRob3IgPSAiQWxlamFuZHJhIEp1eW8iLGZyYW1lID0gRkFMU0UsIG5vcnRoID0gRkFMU0UsIHRhYnRpdGxlID0gVFJVRSwgdGhlbWUgPSAiYmx1ZS5wYWwiKQpub3J0aChwb3MgPSAidG9wbGVmdCIpCmBgYAoKIyMjIyA4LjIgR3VhcmRhciBNYXBhcwoKQWhvcmEgc2UgdmEgYSByZWFsaXphciBvdHJvIG1hcGEgZGUgcHJvZHVjY2nDs24gZGUgWXVjYSBlbiBWaWNoYWRhIHBhcmEgZWwgYcOxbyAyMDE4LiBFc3RhIHZleiBzZSB2YW4gYSB1c2FyIHPDrW1ib2xvcyBwcm9wb3JjaW9uYWxlcyB5IG1hcGFzIGRlIGNvcm9wbGV0YXMuIExhIHNhbGlkYSBzZSBndWFyZGFyw6EgY29tbyB1biBhcmNoaXZvIC5wbmcgZW4gZWwgZGlyZWN0b3JpbyBkZSB0cmFiYWpvLiAKCnByb3BTeW1ib2xzQ2hvcm9MYWVyKCkgY3JlYSB1bmEgbWFwYSBkZSBzw61tYm9sb3MgcXVlIHNvbiBwcm9wb3JjaW9uYWxlcyBhIGxvcyB2YWxvcmVzIGRlIHVuYSBwcmltZXJhIHZhcmlhYmxlIHkgY29sb3JlYWRvcyBwYXJhIHJlZmxlamFyIGxhIGNsYXNpZmljYWNpw7NuIGRlIHVuYSBzZWd1bmRhIHZhcmlhYmxlLgoKU2UgdXRpbGl6YSB1bmEgY29tYmluYWNpw7NuIGRlIGFyZ3VtZW50b3MgcHJvcFN5bWJvbHNMYXllcigpIHkgQ2hvcm9MYXllcigpLiBFbCBzaWd1aWVudGUgY2h1bmsgbm8gbXVlc3RyYSB1biBtYXBhLiBQYXJhIHBvZGVyIHZpc3VhbGl6YXJsbyBzZSBpbnRzZXJ0YSBlbCBhcmNoaXZvIHBuZyBjb24gbGEgc8OtbnRheGlzIGRlIFJNYXJrZG93bgpgYGB7cn0KcG5nKCIuL3l1Y2FfMjAxOC5wbmciLCB3aWR0aCA9IDIwNDgsIGhlaWdodCA9IDE1MjYpCm9wYXIgPC0gcGFyKG1hciA9IGMoMCwwLDUsNSkpCnBsb3Qoc3RfZ2VvbWV0cnkocmVwX1kpLCBjb2w9ImRhcmtzZWFncmVlbjMiLCBib3JkZXI9ImRhcmtzZWFncmVlbjQiLCBiZyA9ICJ3aGl0ZSIsIGx3ZCA9IDAuNikKcHJvcFN5bWJvbHNDaG9yb0xheWVyKHggPSByZXBfWSwgdmFyID0gIlByb2R1Y2Npb24iLCB2YXIyID0gIlJlbmRpbWllbnRvIiwgY29sID0gY2FydG8ucGFsKHBhbDEgPSAiYmx1ZS5wYWwiLCBuMSA9IDMsIHBhbDIgPSAib3JhbmdlLnBhbCIsIG4yPTMpLCBpbmNoZXMgPSAxLCBtZXRob2QgPSAicTYiLCBib3JkZXIgPSAiZ3JleTUwIiwgbHdkID0gMSwgbGVnZW5kLnRpdGxlLmNleCA9IDIsIGxlZ2VuZC52YWx1ZXMuY2V4ID0gMixsZWdlbmQudmFyLnBvcyA9ICJyaWdodCIsIGxlZ2VuZC52YXIyLnBvcyA9ICJsZWZ0IiwgbGVnZW5kLnZhcjIudmFsdWVzLnJuZCA9IDIsIGxlZ2VuZC52YXIyLnRpdGxlLnR4dCA9ICJSZW5kaW1pZW50b1xuKFRvbi9IYSkiLCBsZWdlbmQudmFyLnRpdGxlLnR4dCA9ICJQcm9kdWNjacOzbiBkZSBZdWNhIGVuIDIwMTgiLCBsZWdlbmQudmFyLnN0eWxlID0gImUiKQpsYWJlbExheWVyKHggPSByZXBfWSwgdHh0ID0gIk1QSU9fQ05NQlIiLCBjb2w9ICJ3aGl0ZSIsIGNleCA9IDIuMCwgZm9udCA9IDQsaGFsbyA9IEZBTFNFLCBiZyA9ICJ3aGl0ZSIsIHIgPSAwLjEsICBvdmVybGFwID0gRkFMU0UsIHNob3cubGluZXMgPSBGQUxTRSkKbGF5b3V0TGF5ZXIodGl0bGU9IlByb2R1Y2Npw7NuIHkgUmVuZGltaWVudG8gZGUgUGxhdGFubyAyMDE4IiwgYXV0aG9yID0gIkFuZ2llIEFsZWphbmRyYSBKdXlvIiwgc291cmNlcyA9ICJGdWVudGVzOiBNQURSICYgREFORSwgMjAxOCIsIHNjYWxlID0gODUsIHRhYnRpdGxlID0gRkFMU0UsIGZyYW1lID0gVFJVRSkKbm9ydGgocG9zID0gInRvcGxlZnQiKQp0aXRsZShtYWluPSJDdWx0aXZvIGRlIFl1Y2EgZW4gVmljaGFkYSwgMjAxOCIsIGNleC5tYWluPTMsCiAgICAgIHN1Yj0gIkZ1ZW50ZXM6IE1BRFIgJiBEQU5FLCAyMDE4IiwgY2V4LnN1Yj00KQpncmF0aWN1bGUgPSBUUlVFCnBhcihvcGFyKQpkZXYub2ZmKCkKYGBgCgouOiAhW10oLi95dWNhXzIwMTgucG5nKSAKCgojIyMjIE1hcGEgZGUgcHVudG9zCgpDb21vIHNlIGhhYmlhIG1lbmNpb25hZG8gZGUgZm9ybWEgYW50ZXJpb3IgZWwgbWFwYSBkZSBwdW50b3MgZXMgdXRpbGl6YWRvIHBhcmEgcmVwcmVzZW50YXIgdmFyaWFibGVzIHF1ZSBpbmRpcXVlbiBjYW50aWRhZCwgbGEgcG9ibGFjacOzbiBlcyB1bmEgZGUgZWxsYXMgLCBwb3IgZXN0byBlbCBzaWd1aWVudGUgZWplbXBsbyBkZSBtYXBhIHRlbcOhdGljbyBjb3JyZXNwb25kZSBhIGxhIHJlcHJlc2VudGFjacOzbiBkZWwgbsO6bWVybyBkZSBoYWJpdGFudGVzIGVuIGxvcyBtdW5pY2lwaW9zIGRlIFZpY2hhZGEgZW4gZWwgYcOxbyAyMDE4IGEgdHJhdsOpcyBkZSB1bmEgbWFwYSBkZSBwdW50b3MKCkxvcyBkYXRvcyBmdWVyb24gb2J0ZW5pZG9zIGRlbCBjZW5zbyBkZWwgMjAxOCwgc2UgdG9tw7MgbG9zIGRhdG9zIGNvcnJlc3BvbmRpZW50ZXMgYSBQb2JsYWNpw7NuIFRvdGFsIENlbnNhZGEgZW4gSG9nYXJlcyBQYXJ0aWN1bGFyZXMgeSBlbiBMdWdhcmVzIEVzcGVjaWFsZXMgZGUgQWxvamFtaWVudG8gKExFQSkgIHBvciDDoXJlYSB0b3RhbCBlbiBlbCBkZXBhcnRhbWVudG8gZGUgaW50ZXLDqXMgeSBzZSBhbG1hY2Vuw7MgZW4gZWwgYXJjaGl2byAiQ0VOU08ueGxzeCIgLGVsIGFyY2hpY28gZnVlIGxlaWRvIG1lZGlhbnRlIGxhIGZ1bmNpw7NuICJyZWFkX2V4Y2VsIiB5IHNlIHJlYWxpesOzIGVsIHByb2NlZGltaWVudG8gZGUgdW5pw7NuIGRlIGZvcm1hIGFuw6Fsb2dhIGEgbG9zIG1hcGFzIHJlcHJlc2VudGFkb3MgY29uIGF0ZXJpb3JpZGFkCgpgYGB7cn0KcG9ibGFjaW9uIDwtIHJlYWRfZXhjZWwoIi4vQ0VOU08ueGxzeCIpCmBgYAoKYGBge3J9CnBvYmxhY2lvbiRURU1QIDwtIGFzLmNoYXJhY3Rlcihwb2JsYWNpb24kQ09ESUdPKQpwb2JsYWNpb24kTVBJT19DQ0RHTyA8LSBhcy5mYWN0b3IocGFzdGUocG9ibGFjaW9uJFRFTVApKQpgYGAKYGBge3J9ClZfcG9iID0gbGVmdF9qb2luKFZpY2hhZGFfbXVuaWMsIHBvYmxhY2lvbiwgYnk9Ik1QSU9fQ0NER08iKQpgYGAKU2UgcmV2aXNhIGVsIEpvaW4gZGUgbG9zIGF0cmlidXRvcyBjb24gbGEgY2FwYSBlc3BhY2lhbApgYGB7cn0KaGVhZChWX3BvYikKYGBgCmBgYHtyfQpyZXBfViA8LSBzdF90cmFuc2Zvcm0oVl9wb2IsIGNycyA9IDMxMTYpCmBgYApGaW5hbG1lbnRlIHNlICBlamVjdXRhIGVsIGNvZGlnbyBwYXJhIHJlYWxpemFyIGVsIG1hcGEgZGUgcHVudG9zIGNvbiBsYSBmdW5jacOzbiAiZG90RGVuc2l0eUxheWVyIiwgZW4gbG9zIGFyZ3VtZW50b3Mgc2UgbGUgYXNpZ27DsyBhIGNhZGEgcHVudG8gdW4gdG90YWwgZGUgMjAwIHBlcnNvbmFzCmBgYHtyfQpvcGFyIDwtIHBhcihtYXIgPSBjKDAsMCw1LDUpKQpwbG90KHN0X2dlb21ldHJ5KHJlcF9WKSwgY29sPSIjOTk5OTk5IiwgYm9yZGVyPSJibGFjayIsIGJnID0gIndoaXRlIiwgbHdkID0gMC42OCkKZG90RGVuc2l0eUxheWVyKHggPSByZXBfViwgdmFyID0gIlBPQkxBQ0lPTiIsIG49MjAwLCBwY2g9MSwgY2V4ID0gMC4yOCwgdHlwZSA9ICJyYW5kb20iLCBjb2w9InJlZCIsICBsZWdlbmQucG9zID0gInJpZ2h0IiwgbGVnZW5kLnR4dCA9ICIyMDAgcGVyc29uYXMiLCBsZWdlbmQuY2V4ID0gMC44LCBsZWdlbmQuY29sID0gImJsYWNrIiwgbGVnZW5kLmZyYW1lID0gVFJVRSkKbGF5b3V0TGF5ZXIodGl0bGUgPSAiUG9ibGFjacOzbiBlbiBWaWNoYWRhIGVuIDIwMTgiLHNvdXJjZXMgPSAiRnVlbnRlOiBEQU5FIixhdXRob3IgPSAiQWxlamFuZHJhIEp1eW8iLGZyYW1lID0gRkFMU0UsIG5vcnRoID0gRkFMU0UsIHRhYnRpdGxlID0gVFJVRSkKbm9ydGgocG9zID0gInRvcGxlZnQiKQpgYGAKCgoKCgoKYGBge3J9CnNlc3Npb25JbmZvKCkKYGBgCgo=