Diego Arturo Gonzalez Delgadillo 20 de Mayo

La cartografia tematica es una herramienta util para plasmar variables estadisticas, geografoas economicas, etc, las cuales se pueden evaluar, nterpretar y utilizar de una manera mas eficiente y sencilla. En este informe se plasmaran diferentes tipos de mapas tematicos correspondientes a los niveles de NBI y de produccion de platano en el departamento de Arauca, con el objetivo de poner en practica las herramientas y paquetes cartograficos de R, asi como la de conocer la realidad socieconomica del departamento.

Se comienza limpieando la memoria.

rm(list=ls())

Se instalan los paquetes necesarios para la realizacion de mapas tematicos.

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)

Se cargan los paquetes.

library(tidyverse)
library(readxl)
library(rgeos)
library(raster)
library(sf)
library(cartography)
library(SpatialPosition)

Se leen los datos NBI adaptados previamente para el departamento de Arauca.

NBI <- read_excel("C:/Users/Lina Maria Ayala.LinaMariaAyala/Documents/R/TRABAJOS GEOMATICA/ARAUCA/NBI_2018_ARAUCA.xlsx")

Los atributos de los datos son los siguientes:

head(NBI)

Se filtran los datos para saber cual es la poblacion con mayor NBI.

NBI %>% 
    slice(which.max(NBI)) -> MAX_NBI

MAX_NBI

Se filtran los datos para saber cual es la poblacion con menor NBI.

NBI %>% 
    slice(which.min(NBI)) -> MIN_NBI

MIN_NBI

Se ordenal los municipios por NBI de forma descendiente.

NBI %>% 
  arrange(desc(NBI))  -> DESC_NBI

DESC_NBI

Para hacer el empalme de los datos NBI con los datos administrativos del departamento de arauca se deben leer primero estos ultimos datos.

MUNIC <- st_read("C:/Users/Lina Maria Ayala.LinaMariaAyala/Documents/R/TRABAJOS GEOMATICA/ARAUCA/ADMINISTRATIVO/MGN_MPIO_POLITICO.shp")
Reading layer `MGN_MPIO_POLITICO' from data source `C:\Users\Lina Maria Ayala.LinaMariaAyala\Documents\R\TRABAJOS GEOMATICA\ARAUCA\ADMINISTRATIVO\MGN_MPIO_POLITICO.shp' using driver `ESRI Shapefile'
Simple feature collection with 7 features and 9 fields
geometry type:  POLYGON
dimension:      XY
bbox:           xmin: -72.36662 ymin: 6.036228 xmax: -69.42756 ymax: 7.104381
CRS:            4326

Los atributos de MPIO_CCDGO son:

head(MUNIC$MPIO_CNMBR)
[1] ARAUCA        PUERTO RONDÓN CRAVO NORTE   ARAUQUITA     FORTUL       
[6] SARAVENA     
Levels: ARAUCA ARAUQUITA CRAVO NORTE FORTUL PUERTO RONDÓN SARAVENA TAME

Se hace ahora el empalme.

NBI_MUNIC = left_join(MUNIC, NBI, by=c("MPIO_CCDGO"="CODIGO"))
NBI_MUNIC %>%
  dplyr::select(MUNICIPIO, MPIO_CCDGO, NBI)  ->  CHECK_NBI_MUNIC

head(CHECK_NBI_MUNIC)
Simple feature collection with 6 features and 3 fields
geometry type:  POLYGON
dimension:      XY
bbox:           xmin: -72.12902 ymin: 6.036228 xmax: -69.42756 ymax: 7.104381
CRS:            4326
      MUNICIPIO MPIO_CCDGO      NBI                       geometry
1        ARAUCA      81001 31.31959 POLYGON ((-70.68038 7.09393...
2 PUERTO RONDÓN      81591 22.77443 POLYGON ((-70.87879 6.62133...
3   CRAVO NORTE      81220 29.61032 POLYGON ((-70.40276 6.64639...
4     ARAUQUITA      81065 41.38370 POLYGON ((-71.58441 7.04298...
5        FORTUL      81300 34.35667 POLYGON ((-71.54473 6.75924...
6      SARAVENA      81736 27.70381 POLYGON ((-71.76224 7.06602...

Se reproyectan los municipios.

NBI_MUNIC_NUEVO <- st_transform(NBI_MUNIC, crs = 3116)

MAPAS TEMATICOS

Mapa base de OpenStreetMap y símbolos proporcionales.

En primer lugar se hara un mapa tematico usando el paquete cartografico que represente los niveles de NBI por cad municipio por medio depuntos o simbolos.

MUN.OSM <- getTiles(
x = NBI_MUNIC_NUEVO, 
type = "OpenStreetMap", 
zoom = 8,
cachedir = TRUE,
crop = FALSE
)

Se establecen las margenes, los limites municipales, color, diseño la flecha que indica el norte.

opar <- par(mar = c(0,0,1.2,0))
tilesLayer(x = MUN.OSM)
plot(st_geometry(NBI_MUNIC_NUEVO), col = NA, border = "darkred", add=TRUE)
propSymbolsLayer(
  x = NBI_MUNIC_NUEVO, 
  var = "NBI", 
  inches = 0.2, 
  col = "darkorange2",
  legend.pos = "topright",  
  legend.title.txt = "Total NBI")
layoutLayer(title = "DISTRIBUCION NBI EN ARAUCA",
            sources = "Fuente: DANE, 2018\n© OpenStreetMap",
            author = "Diego Arturo Gonzalez Delgadillo",
            frame = TRUE, north = FALSE, tabtitle = TRUE)
north(pos = "topleft")

Mapas Choropleth

En los mapas coropléticos, las áreas se sombrean de acuerdo con la variación de una variable cuantitativa. Se usan para representar razones o índices.

Se establecen las margenes,color de fondo,limites municipales,diseño y felcha indicativa del norte.

opar <- par(mar = c(0,0,1.2,0))
par(bg="grey98")
plot(st_geometry(NBI_MUNIC_NUEVO), col = NA, border = NA, bg = "#C6C638")
choroLayer(
  x = NBI_MUNIC_NUEVO, 
  var = "NBI",
  method = "geom",
  nclass=5,
  col = carto.pal(pal1 = "blue.pal", n1 = 5),
  border = "white", 
  lwd = 0.5,
  legend.pos = "topright", 
  legend.title.txt = "NBI",
  add = TRUE
) 
layoutLayer(title = "DISTRIBUCION NBI EN ARAUCA", 
            sources = "Fuente: DANE, 2018",
            author = "Diego Arturo Gonzalez Delgadillo", 
            frame = TRUE, north = TRUE, tabtitle = TRUE, col="black") 
north(pos = "topleft")

Símbolos proporcionales y mapa de tipología

Este mapa se crean simnolos proporcionales al tamaño de una variables en zonas especificas. En primer lugar se deb crear una variable cuantutativa con los datos que ya se tenian.

NBI_MUNIC_NUEVO2<- dplyr::mutate(NBI_MUNIC_NUEVO, Pobreza = ifelse(MISERIA > 10, "Extreme", 
                                                         ifelse(HACINAMIENTO >8,"High", "Intermediate")))

Estos son los nuevos atributos:

head(NBI_MUNIC_NUEVO2)
Simple feature collection with 6 features and 21 fields
geometry type:  POLYGON
dimension:      XY
bbox:           xmin: 1215550 ymin: 1161263 xmax: 1515269 ymax: 1278742
CRS:            EPSG:3116
  DPTO_CCDGO MPIO_CCDGO    MPIO_CNMBR                           MPIO_CRSLC
1         81      81001        ARAUCA                                 1959
2         81      81591 PUERTO RONDÓN Decreto Nal 677 de Abril 13 de  1987
3         81      81220   CRAVO NORTE Decreto Nal 677 de Abril 13 de  1987
4         81      81065     ARAUQUITA Decreto 1447 del 28 de Julio de 1971
5         81      81300        FORTUL                 Decreto 2926 de 1989
6         81      81736      SARAVENA     Decreto Nal 204 de Feb 3 de 1976
  MPIO_NAREA MPIO_NANO DPTO_CNMBR Shape_Leng Shape_Area COD_DEPTO  DEPTO COD_MUN
1  5787.9421      2017     ARAUCA   4.668016 0.47162612        81 ARAUCA     001
2  2281.4291      2017     ARAUCA   2.932376 0.18593602        81 ARAUCA     591
3  5212.6908      2017     ARAUCA   3.963937 0.42393331        81 ARAUCA     220
4  3046.8789      2017     ARAUCA   3.258765 0.24864660        81 ARAUCA     065
5  1158.6276      2017     ARAUCA   2.056433 0.09461063        81 ARAUCA     300
6   945.1354      2017     ARAUCA   1.294126 0.07721413        81 ARAUCA     736
      MUNICIPIO      NBI   MISERIA VIVIENDA SERVICIOS HACINAMIENTO INASISTENCIA
1        ARAUCA 31.31959  9.524767 23.55534  2.840414     9.164355     2.342002
2 PUERTO RONDÓN 22.77443  7.406514 12.42461  1.013269     7.696019     4.511460
3   CRAVO NORTE 29.61032  8.726674 16.10867  2.661910     8.616905     2.661910
4     ARAUQUITA 41.38370 10.664613 33.61016  2.495926     7.563682     2.824102
5        FORTUL 34.35667 10.451880 24.40497  4.553294     9.060596     2.385880
6      SARAVENA 27.70381  7.932591 20.45794  2.582348     7.748957     2.515398
  ECONOMICA                       geometry      Pobreza
1  5.690207 POLYGON ((1375506 1277590, ...         High
2  7.985525 POLYGON ((1353901 1225089, ... Intermediate
3 10.592755 POLYGON ((1406614 1228231, ...         High
4  8.773692 POLYGON ((1275536 1271316, ...      Extreme
5  9.457284 POLYGON ((1280090 1239930, ...      Extreme
6  5.866713 POLYGON ((1255857 1273763, ... Intermediate

Se establecen las margenes,color de fondo,limites municipales,diseño y felcha indicativa del norte.

library(sf)
library(cartography)
opar <- par(mar = c(0,0,1.2,0))

plot(st_geometry(NBI_MUNIC_NUEVO2), col="#99ff99", border="#5454AA", bg = "#FFFF00", 
     lwd = 0.5)
propSymbolsTypoLayer(
  x = NBI_MUNIC_NUEVO2, 
  var = "NBI", 
  inches = 0.35,
  symbols = "square",
  border = "white",
  lwd = .5,
  legend.var.pos = c(100000, 14100000), 
  legend.var.title.txt = "NBI",
  var2 = "Pobreza",
  legend.var2.values.order = c("Extreme", "High", 
                               "Intermediate"),
  col = carto.pal(pal1 = "harmo.pal", n1 = 3),
  legend.var2.pos = c(100000, 14100000), 
  legend.var2.title.txt = "Pobreza"
) 
layoutLayer(title="DISTRIBUCION NBI EN ARAUCA", 
            author = "Diego Arturo Gonzalez Delgadillo", 
            sources = "Fuente: DANE, 2018", 
            scale = 1, tabtitle = TRUE, frame = TRUE)

north(pos = "topleft")

Mapas con etiquetas

En este tipo de mapas se intenta combinar nombres con variables. Se establecen las margenes,color de fondo,limites municipales,diseño y felcha indicativa del norte.

library(sf)
library(cartography)
opar <- par(mar = c(0,0,1.2,0))
par(bg="grey25")
plot(st_geometry(NBI_MUNIC_NUEVO2), col = "#99ff99", border = "grey", 
     bg = "deepskyblue3", lwd = 0.5)
choroLayer(
  x = NBI_MUNIC_NUEVO, 
  var = "NBI",
  method = "geom",
  nclass=5,
  col = carto.pal(pal1 = "red.pal", n1 = 5),
  border = "white", 
  lwd = 0.5,
  legend.pos = "topright", 
  legend.title.txt = "NBI",
  add = TRUE
) 
labelLayer(
  x = NBI_MUNIC_NUEVO2, 
  txt = "MUNICIPIO", 
  col= "white", 
  cex = 0.7, 
  font = 4,
  halo = TRUE, 
  bg = "grey25", 
  r = 0.1, 
  overlap = FALSE, 
  show.lines = FALSE
)
layoutLayer(
  title = "MUNICIPIO DE ARAUCA Y SUS NIVELES DE NBI", 
  sources = "FUENTE: DANE, 2018",  
  author = "Diego Arturo Gonzalez Delgadillo", 
  frame = TRUE,
  north = TRUE, 
  tabtitle = TRUE, 
  theme = "red.pal"
) 

Mapas Isopleth

Estos mapas se basan en variables de distribucion continua en un area determinada, para ello entonces en este caso integraremos los datos de produccion de platano en Arauca con el paquete cartorafico.

Se leen primeros los datos productivos.

CULTIVOS2018 <- read_excel("C:/Users/Lina Maria Ayala.LinaMariaAyala/Documents/R/TRABAJOS GEOMATICA/ARAUCA/Evaluaciones_Agropecuarias_Municipales_EVA 2.xlsx")

Estos son los atributos.

head(CULTIVOS2018)

Se filtran los datos por correspondientes al cultivo de platano.

CULTIVOS2018 %>%
  filter(CULTIVO == "PLATANO") -> PLATANO2018

Se crea un nuevo atributo que coincida con los codigos del municipio.

PLATANO2018$TEMP <-  as.character(PLATANO2018$COD_MUN)
PLATANO2018$MPIO_CCDGO <- as.factor(PLATANO2018$TEMP)

Se hace ahora la union.

PLATANO_MUNIC = left_join(MUNIC, PLATANO2018, by="MPIO_CCDGO")

Se verifican los atributos de salida.

head(PLATANO_MUNIC)
Simple feature collection with 6 features and 25 fields
geometry type:  POLYGON
dimension:      XY
bbox:           xmin: -72.12902 ymin: 6.036228 xmax: -69.42756 ymax: 7.104381
CRS:            4326
  DPTO_CCDGO MPIO_CCDGO    MPIO_CNMBR                           MPIO_CRSLC
1         81      81001        ARAUCA                                 1959
2         81      81591 PUERTO RONDÓN Decreto Nal 677 de Abril 13 de  1987
3         81      81220   CRAVO NORTE Decreto Nal 677 de Abril 13 de  1987
4         81      81065     ARAUQUITA Decreto 1447 del 28 de Julio de 1971
5         81      81300        FORTUL                 Decreto 2926 de 1989
6         81      81736      SARAVENA     Decreto Nal 204 de Feb 3 de 1976
  MPIO_NAREA MPIO_NANO DPTO_CNMBR Shape_Leng Shape_Area COD_DEP DEPARTAMENTO
1  5787.9421      2017     ARAUCA   4.668016 0.47162612      81       ARAUCA
2  2281.4291      2017     ARAUCA   2.932376 0.18593602      81       ARAUCA
3  5212.6908      2017     ARAUCA   3.963937 0.42393331      81       ARAUCA
4  3046.8789      2017     ARAUCA   3.258765 0.24864660      81       ARAUCA
5  1158.6276      2017     ARAUCA   2.056433 0.09461063      81       ARAUCA
6   945.1354      2017     ARAUCA   1.294126 0.07721413      81       ARAUCA
  COD_MUN     MUNICIPIO                 GRUPO SUBGRUPO CULTIVO YEAR PERIODO
1   81001        ARAUCA TUBERCULOS Y PLATANOS  PLATANO PLATANO 2018    2018
2   81591 PUERTO RONDON TUBERCULOS Y PLATANOS  PLATANO PLATANO 2018    2018
3   81220   CRAVO NORTE TUBERCULOS Y PLATANOS  PLATANO PLATANO 2018    2018
4   81065     ARAUQUITA TUBERCULOS Y PLATANOS  PLATANO PLATANO 2018    2018
5   81300        FORTUL TUBERCULOS Y PLATANOS  PLATANO PLATANO 2018    2018
6   81736      SARAVENA TUBERCULOS Y PLATANOS  PLATANO PLATANO 2018    2018
  Area_Siembra Area_Cosecha Produccion Rendimiento       ESTADO      CICLO
1          605          365       8019          22 FRUTO FRESCO PERMANENTE
2          451          236       3071          13 FRUTO FRESCO PERMANENTE
3          139          114       2052          18 FRUTO FRESCO PERMANENTE
4         6666         3646      72920          20 FRUTO FRESCO PERMANENTE
5         3527         2927      58540          20 FRUTO FRESCO PERMANENTE
6         4105         3805      83710          22 FRUTO FRESCO PERMANENTE
   TEMP                       geometry
1 81001 POLYGON ((-70.68038 7.09393...
2 81591 POLYGON ((-70.87879 6.62133...
3 81220 POLYGON ((-70.40276 6.64639...
4 81065 POLYGON ((-71.58441 7.04298...
5 81300 POLYGON ((-71.54473 6.75924...
6 81736 POLYGON ((-71.76224 7.06602...
install.packages("lwgeom")
library(lwgeom)

Se re proyecta los municipios.

REP_PLATANO <- st_transform(PLATANO_MUNIC, crs = 3116)

Ahora se mapea. Se establecen las margenes,color de fondo,limites municipales,diseño y felcha indicativa del norte.

opar <- par(mar = c(0,0,1.2,0))
plot(st_geometry(REP_PLATANO), col = NA, border = "white", bg = "olivedrab2")
smoothLayer(
  x = REP_PLATANO, 
  var = 'Produccion',
  typefct = "exponential",
  span = 25000,
  beta = 2,
  nclass = 10,
  col = carto.pal(pal1 = 'orange.pal', n1 = 10),
  border = "black",
  lwd = 0.1, 
  mask = REP_PLATANO, 
  legend.values.rnd = -3,
  legend.title.txt = "Produccion",
  legend.pos = "topright", 
  add=TRUE
)
text(x = 650000, y = 1200000, cex = 0.6, adj = 0, font = 3,  labels = 
       "Distance function:\n- type = exponential\n- beta = 2\n- span = 20 km")
layoutLayer(title = "DISTRIBUCION DE LA PRODUCCION DE PLATANO EN ARAUCA, 2018",
            sources = "FUENTE: DANE and MADR, 2018",
            author = "Diego Arturo Gonzalez Delgadillo",
            frame = FALSE, north = FALSE, tabtitle = TRUE, theme = "grey.pal")
north(pos = "topleft")

Guardar Mapas

Se produse otro mapa de producción de platano en arauca en el año 2018. Esta vez se usaran símbolos proporcionales y mapas de coropletas.El resultado se guardará como un archivo .png

png("C:/Users/Lina Maria Ayala.LinaMariaAyala/Documents/R/TRABAJOS GEOMATICA/ARAUCA/PLATANO_2018.png", width = 2048, height = 1526)

opar <- par(mar = c(0,0,5,5))

plot(st_geometry(REP_PLATANO), col="navajowhite", border="black",  
     bg = "white", lwd = 0.6)
propSymbolsChoroLayer(x = REP_PLATANO, var = "Produccion", var2 = "Rendimiento",
                      col = carto.pal(pal1 = "blue.pal", n1 = 3,
                                      pal2 = "orange.pal", n2 = 3),
                      inches = 1.5, method = "q6",
                      border = "slateblue4", lwd = 1,
                      legend.title.cex = 2,5,
                      legend.values.cex = 2.1,
                      legend.var.pos = "topright", 
                      legend.var2.pos = "left",
                      legend.var2.values.rnd = 2,
                      legend.var2.title.txt = "Rendimiento\n(in Ton/Ha)",
                      legend.var.title.txt = "PRODUCCION DE PLATANO EN 2018",
                      legend.var.style = "e")
labelLayer(
  x = REP_PLATANO, 
  txt = "MPIO_CNMBR", 
  col= "black", 
  cex = 2.0, 
  font = 2,
  halo = FALSE, 
  bg = "white", 
  r = 1.1, 
  overlap = FALSE, 
  show.lines = FALSE
)
layoutLayer(title="PRODUCCION Y RENDIMIENTO DE PLATANO EN ARAUCA, 2018",
            author = "Diego Arturo Gonzalez Delgadillo", 
            sources = "FUENTE: MADR & DANE, 2018", 
            scale = 50, tabtitle = FALSE, frame = TRUE)
north(pos = "topleft")
title(main="PRODUCCION Y RENDIMIENTO DE PLATANO EN ARAUCA, 2018", cex.main=3,
      sub= "FUENTE: MADR & DANE, 2018", cex.sub=3)
graticule = TRUE
par(opar)
dev.off()
library(ggplot2)
library(knitr)
include_graphics("C:/Users/Lina Maria Ayala.LinaMariaAyala/Documents/R/TRABAJOS GEOMATICA/ARAUCA/PLATANO_2018.png")

NA

Produccion de platano en Arauca, 2018

sessionInfo()
R version 3.6.3 (2020-02-29)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 7 x64 (build 7601) Service Pack 1

Matrix products: default

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

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

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

loaded via a namespace (and not attached):
 [1] Rcpp_1.0.4         lubridate_1.7.8    lattice_0.20-38    png_0.1-7         
 [5] class_7.3-15       digest_0.6.25      assertthat_0.2.1   R6_2.4.1          
 [9] cellranger_1.1.0   backports_1.1.5    reprex_0.3.0       evaluate_0.14     
[13] e1071_1.7-3        httr_1.4.1         pillar_1.4.3       rlang_0.4.5       
[17] rstudioapi_0.11    rmarkdown_2.1      rgdal_1.4-8        munsell_0.5.0     
[21] broom_0.5.5        compiler_3.6.3     modelr_0.1.6       xfun_0.12         
[25] base64enc_0.1-3    pkgconfig_2.0.3    htmltools_0.4.0    tidyselect_1.0.0  
[29] codetools_0.2-16   fansi_0.4.1        crayon_1.3.4       dbplyr_1.4.2      
[33] withr_2.1.2        grid_3.6.3         nlme_3.1-144       jsonlite_1.6.1    
[37] gtable_0.3.0       lifecycle_0.2.0    DBI_1.1.0          magrittr_1.5      
[41] units_0.6-6        scales_1.1.0       KernSmooth_2.23-16 cli_2.0.2         
[45] stringi_1.4.6      fs_1.4.1           xml2_1.3.1         ellipsis_0.3.0    
[49] generics_0.0.2     vctrs_0.2.4        tools_3.6.3        glue_1.3.2        
[53] hms_0.5.3          yaml_2.2.1         slippymath_0.3.1   colorspace_1.4-1  
[57] classInt_0.4-2     rvest_0.3.5        isoband_0.2.0      haven_2.2.0       
LS0tDQp0aXRsZTogIkNBUlRPR1JBRklBIFRFTUFUSUNBIFBBUkEgRUwgREVQQVJUQU1FTlRPIERFIEFSQVVDQSINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KLS0tDQpEaWVnbyBBcnR1cm8gR29uemFsZXogRGVsZ2FkaWxsbw0KMjAgZGUgTWF5bw0KDQpMYSBjYXJ0b2dyYWZpYSB0ZW1hdGljYSBlcyB1bmEgaGVycmFtaWVudGEgdXRpbCBwYXJhIHBsYXNtYXIgdmFyaWFibGVzIGVzdGFkaXN0aWNhcywgZ2VvZ3JhZm9hcyBlY29ub21pY2FzLCBldGMsIGxhcyBjdWFsZXMgc2UgcHVlZGVuIGV2YWx1YXIsIG50ZXJwcmV0YXIgeSB1dGlsaXphciBkZSB1bmEgbWFuZXJhIG1hcyBlZmljaWVudGUgeSBzZW5jaWxsYS4NCkVuIGVzdGUgaW5mb3JtZSBzZSBwbGFzbWFyYW4gZGlmZXJlbnRlcyB0aXBvcyBkZSBtYXBhcyB0ZW1hdGljb3MgY29ycmVzcG9uZGllbnRlcyBhIGxvcyBuaXZlbGVzIGRlIE5CSSB5IGRlIHByb2R1Y2Npb24gZGUgcGxhdGFubyBlbiBlbCBkZXBhcnRhbWVudG8gZGUgQXJhdWNhLCBjb24gZWwgb2JqZXRpdm8gZGUgcG9uZXIgZW4gcHJhY3RpY2EgbGFzIGhlcnJhbWllbnRhcyB5IHBhcXVldGVzIGNhcnRvZ3JhZmljb3MgZGUgUiwgYXNpIGNvbW8gbGEgZGUgY29ub2NlciBsYSByZWFsaWRhZCBzb2NpZWNvbm9taWNhIGRlbCBkZXBhcnRhbWVudG8uDQoNClNlIGNvbWllbnphIGxpbXBpZWFuZG8gbGEgbWVtb3JpYS4NCmBgYHtyfQ0Kcm0obGlzdD1scygpKQ0KYGBgDQpTZSBpbnN0YWxhbiBsb3MgcGFxdWV0ZXMgbmVjZXNhcmlvcyBwYXJhIGxhIHJlYWxpemFjaW9uIGRlIG1hcGFzIHRlbWF0aWNvcy4NCmBgYHtyfQ0KbGlzdC5vZi5wYWNrYWdlcyA8LSBjKCJ0aWR5dmVyc2UiLCAicmdlb3MiLCAic2YiLCAicmFzdGVyIiwgImNhcnRvZ3JhcGh5IiwgIlNwYXRpYWxQb3NpdGlvbiIpDQpuZXcucGFja2FnZXMgPC0gbGlzdC5vZi5wYWNrYWdlc1shKGxpc3Qub2YucGFja2FnZXMgJWluJSBpbnN0YWxsZWQucGFja2FnZXMoKVssIlBhY2thZ2UiXSldDQppZihsZW5ndGgobmV3LnBhY2thZ2VzKSkgaW5zdGFsbC5wYWNrYWdlcyhuZXcucGFja2FnZXMpDQpgYGANClNlIGNhcmdhbiBsb3MgcGFxdWV0ZXMuDQpgYGB7cn0NCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShyZWFkeGwpDQpsaWJyYXJ5KHJnZW9zKQ0KbGlicmFyeShyYXN0ZXIpDQpsaWJyYXJ5KHNmKQ0KbGlicmFyeShjYXJ0b2dyYXBoeSkNCmxpYnJhcnkoU3BhdGlhbFBvc2l0aW9uKQ0KYGBgDQpTZSBsZWVuIGxvcyBkYXRvcyBOQkkgYWRhcHRhZG9zIHByZXZpYW1lbnRlIHBhcmEgZWwgZGVwYXJ0YW1lbnRvIGRlIEFyYXVjYS4NCmBgYHtyfQ0KTkJJIDwtIHJlYWRfZXhjZWwoIkM6L1VzZXJzL0xpbmEgTWFyaWEgQXlhbGEuTGluYU1hcmlhQXlhbGEvRG9jdW1lbnRzL1IvVFJBQkFKT1MgR0VPTUFUSUNBL0FSQVVDQS9OQklfMjAxOF9BUkFVQ0EueGxzeCIpDQpgYGANCkxvcyBhdHJpYnV0b3MgZGUgbG9zIGRhdG9zIHNvbiBsb3Mgc2lndWllbnRlczoNCmBgYHtyfQ0KaGVhZChOQkkpDQpgYGANClNlIGZpbHRyYW4gbG9zIGRhdG9zIHBhcmEgc2FiZXIgY3VhbCBlcyBsYSBwb2JsYWNpb24gY29uIG1heW9yIE5CSS4NCmBgYHtyfQ0KTkJJICU+JSANCiAgICBzbGljZSh3aGljaC5tYXgoTkJJKSkgLT4gTUFYX05CSQ0KDQpNQVhfTkJJDQpgYGANClNlIGZpbHRyYW4gbG9zIGRhdG9zIHBhcmEgc2FiZXIgY3VhbCBlcyBsYSBwb2JsYWNpb24gY29uIG1lbm9yIE5CSS4NCmBgYHtyfQ0KTkJJICU+JSANCiAgICBzbGljZSh3aGljaC5taW4oTkJJKSkgLT4gTUlOX05CSQ0KDQpNSU5fTkJJDQpgYGANClNlIG9yZGVuYWwgbG9zIG11bmljaXBpb3MgcG9yIE5CSSBkZSBmb3JtYSBkZXNjZW5kaWVudGUuDQpgYGB7cn0NCk5CSSAlPiUgDQogIGFycmFuZ2UoZGVzYyhOQkkpKSAgLT4gREVTQ19OQkkNCg0KREVTQ19OQkkNCmBgYA0KUGFyYSBoYWNlciBlbCBlbXBhbG1lIGRlIGxvcyBkYXRvcyBOQkkgY29uIGxvcyBkYXRvcyBhZG1pbmlzdHJhdGl2b3MgZGVsIGRlcGFydGFtZW50byBkZSBhcmF1Y2Egc2UgZGViZW4gbGVlciBwcmltZXJvIGVzdG9zIHVsdGltb3MgZGF0b3MuDQpgYGB7cn0NCk1VTklDIDwtIHN0X3JlYWQoIkM6L1VzZXJzL0xpbmEgTWFyaWEgQXlhbGEuTGluYU1hcmlhQXlhbGEvRG9jdW1lbnRzL1IvVFJBQkFKT1MgR0VPTUFUSUNBL0FSQVVDQS9BRE1JTklTVFJBVElWTy9NR05fTVBJT19QT0xJVElDTy5zaHAiKQ0KYGBgDQpMb3MgYXRyaWJ1dG9zIGRlIE1QSU9fQ0NER08gc29uOg0KYGBge3J9DQpoZWFkKE1VTklDJE1QSU9fQ05NQlIpDQpgYGANClNlIGhhY2UgYWhvcmEgZWwgZW1wYWxtZS4NCmBgYHtyfQ0KTkJJX01VTklDID0gbGVmdF9qb2luKE1VTklDLCBOQkksIGJ5PWMoIk1QSU9fQ0NER08iPSJDT0RJR08iKSkNCmBgYA0KYGBge3J9DQpOQklfTVVOSUMgJT4lDQogIGRwbHlyOjpzZWxlY3QoTVVOSUNJUElPLCBNUElPX0NDREdPLCBOQkkpICAtPiAgQ0hFQ0tfTkJJX01VTklDDQoNCmhlYWQoQ0hFQ0tfTkJJX01VTklDKQ0KYGBgDQpTZSByZXByb3llY3RhbiBsb3MgbXVuaWNpcGlvcy4NCmBgYHtyfQ0KTkJJX01VTklDX05VRVZPIDwtIHN0X3RyYW5zZm9ybShOQklfTVVOSUMsIGNycyA9IDMxMTYpDQpgYGANCg0KTUFQQVMgVEVNQVRJQ09TDQoNCk1hcGEgYmFzZSBkZSBPcGVuU3RyZWV0TWFwIHkgc8OtbWJvbG9zIHByb3BvcmNpb25hbGVzLg0KDQpFbiBwcmltZXIgbHVnYXIgc2UgaGFyYSB1biBtYXBhIHRlbWF0aWNvIHVzYW5kbyBlbCBwYXF1ZXRlIGNhcnRvZ3JhZmljbyBxdWUgcmVwcmVzZW50ZSBsb3Mgbml2ZWxlcyBkZSBOQkkgcG9yIGNhZCBtdW5pY2lwaW8gcG9yIG1lZGlvIGRlcHVudG9zIG8gc2ltYm9sb3MuDQpgYGB7cn0NCk1VTi5PU00gPC0gZ2V0VGlsZXMoDQp4ID0gTkJJX01VTklDX05VRVZPLCANCnR5cGUgPSAiT3BlblN0cmVldE1hcCIsIA0Kem9vbSA9IDgsDQpjYWNoZWRpciA9IFRSVUUsDQpjcm9wID0gRkFMU0UNCikNCmBgYA0KU2UgZXN0YWJsZWNlbiBsYXMgbWFyZ2VuZXMsIGxvcyBsaW1pdGVzIG11bmljaXBhbGVzLCBjb2xvciwgZGlzZcOxbyBsYSBmbGVjaGEgcXVlIGluZGljYSBlbCBub3J0ZS4NCmBgYHtyfQ0Kb3BhciA8LSBwYXIobWFyID0gYygwLDAsMS4yLDApKQ0KdGlsZXNMYXllcih4ID0gTVVOLk9TTSkNCnBsb3Qoc3RfZ2VvbWV0cnkoTkJJX01VTklDX05VRVZPKSwgY29sID0gTkEsIGJvcmRlciA9ICJkYXJrcmVkIiwgYWRkPVRSVUUpDQpwcm9wU3ltYm9sc0xheWVyKA0KICB4ID0gTkJJX01VTklDX05VRVZPLCANCiAgdmFyID0gIk5CSSIsIA0KICBpbmNoZXMgPSAwLjIsIA0KICBjb2wgPSAiZGFya29yYW5nZTIiLA0KICBsZWdlbmQucG9zID0gInRvcHJpZ2h0IiwgIA0KICBsZWdlbmQudGl0bGUudHh0ID0gIlRvdGFsIE5CSSIpDQpsYXlvdXRMYXllcih0aXRsZSA9ICJESVNUUklCVUNJT04gTkJJIEVOIEFSQVVDQSIsDQogICAgICAgICAgICBzb3VyY2VzID0gIkZ1ZW50ZTogREFORSwgMjAxOFxuwqkgT3BlblN0cmVldE1hcCIsDQogICAgICAgICAgICBhdXRob3IgPSAiRGllZ28gQXJ0dXJvIEdvbnphbGV6IERlbGdhZGlsbG8iLA0KICAgICAgICAgICAgZnJhbWUgPSBUUlVFLCBub3J0aCA9IEZBTFNFLCB0YWJ0aXRsZSA9IFRSVUUpDQpub3J0aChwb3MgPSAidG9wbGVmdCIpDQoNCmBgYA0KTWFwYXMgQ2hvcm9wbGV0aA0KDQpFbiBsb3MgbWFwYXMgY29yb3Bsw6l0aWNvcywgbGFzIMOhcmVhcyBzZSBzb21icmVhbiBkZSBhY3VlcmRvIGNvbiBsYSB2YXJpYWNpw7NuIGRlIHVuYSB2YXJpYWJsZSBjdWFudGl0YXRpdmEuIFNlIHVzYW4gcGFyYSByZXByZXNlbnRhciByYXpvbmVzIG8gw61uZGljZXMuDQoNClNlIGVzdGFibGVjZW4gbGFzIG1hcmdlbmVzLGNvbG9yIGRlIGZvbmRvLGxpbWl0ZXMgbXVuaWNpcGFsZXMsZGlzZcOxbyB5IGZlbGNoYSBpbmRpY2F0aXZhIGRlbCBub3J0ZS4NCmBgYHtyfQ0Kb3BhciA8LSBwYXIobWFyID0gYygwLDAsMS4yLDApKQ0KcGFyKGJnPSJncmV5OTgiKQ0KcGxvdChzdF9nZW9tZXRyeShOQklfTVVOSUNfTlVFVk8pLCBjb2wgPSBOQSwgYm9yZGVyID0gTkEsIGJnID0gIiNDNkM2MzgiKQ0KY2hvcm9MYXllcigNCiAgeCA9IE5CSV9NVU5JQ19OVUVWTywgDQogIHZhciA9ICJOQkkiLA0KICBtZXRob2QgPSAiZ2VvbSIsDQogIG5jbGFzcz01LA0KICBjb2wgPSBjYXJ0by5wYWwocGFsMSA9ICJibHVlLnBhbCIsIG4xID0gNSksDQogIGJvcmRlciA9ICJ3aGl0ZSIsIA0KICBsd2QgPSAwLjUsDQogIGxlZ2VuZC5wb3MgPSAidG9wcmlnaHQiLCANCiAgbGVnZW5kLnRpdGxlLnR4dCA9ICJOQkkiLA0KICBhZGQgPSBUUlVFDQopIA0KbGF5b3V0TGF5ZXIodGl0bGUgPSAiRElTVFJJQlVDSU9OIE5CSSBFTiBBUkFVQ0EiLCANCiAgICAgICAgICAgIHNvdXJjZXMgPSAiRnVlbnRlOiBEQU5FLCAyMDE4IiwNCiAgICAgICAgICAgIGF1dGhvciA9ICJEaWVnbyBBcnR1cm8gR29uemFsZXogRGVsZ2FkaWxsbyIsIA0KICAgICAgICAgICAgZnJhbWUgPSBUUlVFLCBub3J0aCA9IFRSVUUsIHRhYnRpdGxlID0gVFJVRSwgY29sPSJibGFjayIpIA0Kbm9ydGgocG9zID0gInRvcGxlZnQiKQ0KYGBgDQpTw61tYm9sb3MgcHJvcG9yY2lvbmFsZXMgeSBtYXBhIGRlIHRpcG9sb2fDrWENCg0KRXN0ZSBtYXBhIHNlIGNyZWFuIHNpbW5vbG9zIHByb3BvcmNpb25hbGVzIGFsIHRhbWHDsW8gZGUgdW5hIHZhcmlhYmxlcyBlbiB6b25hcyBlc3BlY2lmaWNhcy4gDQpFbiBwcmltZXIgbHVnYXIgc2UgZGViIGNyZWFyIHVuYSB2YXJpYWJsZSBjdWFudHV0YXRpdmEgY29uIGxvcyBkYXRvcyBxdWUgeWEgc2UgdGVuaWFuLg0KYGBge3J9DQpOQklfTVVOSUNfTlVFVk8yPC0gZHBseXI6Om11dGF0ZShOQklfTVVOSUNfTlVFVk8sIFBvYnJlemEgPSBpZmVsc2UoTUlTRVJJQSA+IDEwLCAiRXh0cmVtZSIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKEhBQ0lOQU1JRU5UTyA+OCwiSGlnaCIsICJJbnRlcm1lZGlhdGUiKSkpDQpgYGANCkVzdG9zIHNvbiBsb3MgbnVldm9zIGF0cmlidXRvczoNCmBgYHtyfQ0KaGVhZChOQklfTVVOSUNfTlVFVk8yKQ0KYGBgDQpTZSBlc3RhYmxlY2VuIGxhcyBtYXJnZW5lcyxjb2xvciBkZSBmb25kbyxsaW1pdGVzIG11bmljaXBhbGVzLGRpc2XDsW8geSBmZWxjaGEgaW5kaWNhdGl2YSBkZWwgbm9ydGUuDQpgYGB7cn0NCmxpYnJhcnkoc2YpDQpsaWJyYXJ5KGNhcnRvZ3JhcGh5KQ0Kb3BhciA8LSBwYXIobWFyID0gYygwLDAsMS4yLDApKQ0KDQpwbG90KHN0X2dlb21ldHJ5KE5CSV9NVU5JQ19OVUVWTzIpLCBjb2w9IiM5OWZmOTkiLCBib3JkZXI9IiM1NDU0QUEiLCBiZyA9ICIjRkZGRjAwIiwgDQogICAgIGx3ZCA9IDAuNSkNCnByb3BTeW1ib2xzVHlwb0xheWVyKA0KICB4ID0gTkJJX01VTklDX05VRVZPMiwgDQogIHZhciA9ICJOQkkiLCANCiAgaW5jaGVzID0gMC4zNSwNCiAgc3ltYm9scyA9ICJzcXVhcmUiLA0KICBib3JkZXIgPSAid2hpdGUiLA0KICBsd2QgPSAuNSwNCiAgbGVnZW5kLnZhci5wb3MgPSBjKDEwMDAwMCwgMTQxMDAwMDApLCANCiAgbGVnZW5kLnZhci50aXRsZS50eHQgPSAiTkJJIiwNCiAgdmFyMiA9ICJQb2JyZXphIiwNCiAgbGVnZW5kLnZhcjIudmFsdWVzLm9yZGVyID0gYygiRXh0cmVtZSIsICJIaWdoIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkludGVybWVkaWF0ZSIpLA0KICBjb2wgPSBjYXJ0by5wYWwocGFsMSA9ICJoYXJtby5wYWwiLCBuMSA9IDMpLA0KICBsZWdlbmQudmFyMi5wb3MgPSBjKDEwMDAwMCwgMTQxMDAwMDApLCANCiAgbGVnZW5kLnZhcjIudGl0bGUudHh0ID0gIlBvYnJlemEiDQopIA0KbGF5b3V0TGF5ZXIodGl0bGU9IkRJU1RSSUJVQ0lPTiBOQkkgRU4gQVJBVUNBIiwgDQogICAgICAgICAgICBhdXRob3IgPSAiRGllZ28gQXJ0dXJvIEdvbnphbGV6IERlbGdhZGlsbG8iLCANCiAgICAgICAgICAgIHNvdXJjZXMgPSAiRnVlbnRlOiBEQU5FLCAyMDE4IiwgDQogICAgICAgICAgICBzY2FsZSA9IDEsIHRhYnRpdGxlID0gVFJVRSwgZnJhbWUgPSBUUlVFKQ0KDQpub3J0aChwb3MgPSAidG9wbGVmdCIpDQpgYGANCk1hcGFzIGNvbiBldGlxdWV0YXMNCg0KRW4gZXN0ZSB0aXBvIGRlIG1hcGFzIHNlIGludGVudGEgY29tYmluYXIgbm9tYnJlcyBjb24gdmFyaWFibGVzLg0KU2UgZXN0YWJsZWNlbiBsYXMgbWFyZ2VuZXMsY29sb3IgZGUgZm9uZG8sbGltaXRlcyBtdW5pY2lwYWxlcyxkaXNlw7FvIHkgZmVsY2hhIGluZGljYXRpdmEgZGVsIG5vcnRlLg0KYGBge3J9DQpsaWJyYXJ5KHNmKQ0KbGlicmFyeShjYXJ0b2dyYXBoeSkNCm9wYXIgPC0gcGFyKG1hciA9IGMoMCwwLDEuMiwwKSkNCnBhcihiZz0iZ3JleTI1IikNCnBsb3Qoc3RfZ2VvbWV0cnkoTkJJX01VTklDX05VRVZPMiksIGNvbCA9ICIjOTlmZjk5IiwgYm9yZGVyID0gImdyZXkiLCANCiAgICAgYmcgPSAiZGVlcHNreWJsdWUzIiwgbHdkID0gMC41KQ0KY2hvcm9MYXllcigNCiAgeCA9IE5CSV9NVU5JQ19OVUVWTywgDQogIHZhciA9ICJOQkkiLA0KICBtZXRob2QgPSAiZ2VvbSIsDQogIG5jbGFzcz01LA0KICBjb2wgPSBjYXJ0by5wYWwocGFsMSA9ICJyZWQucGFsIiwgbjEgPSA1KSwNCiAgYm9yZGVyID0gIndoaXRlIiwgDQogIGx3ZCA9IDAuNSwNCiAgbGVnZW5kLnBvcyA9ICJ0b3ByaWdodCIsIA0KICBsZWdlbmQudGl0bGUudHh0ID0gIk5CSSIsDQogIGFkZCA9IFRSVUUNCikgDQpsYWJlbExheWVyKA0KICB4ID0gTkJJX01VTklDX05VRVZPMiwgDQogIHR4dCA9ICJNVU5JQ0lQSU8iLCANCiAgY29sPSAid2hpdGUiLCANCiAgY2V4ID0gMC43LCANCiAgZm9udCA9IDQsDQogIGhhbG8gPSBUUlVFLCANCiAgYmcgPSAiZ3JleTI1IiwgDQogIHIgPSAwLjEsIA0KICBvdmVybGFwID0gRkFMU0UsIA0KICBzaG93LmxpbmVzID0gRkFMU0UNCikNCmxheW91dExheWVyKA0KICB0aXRsZSA9ICJNVU5JQ0lQSU8gREUgQVJBVUNBIFkgU1VTIE5JVkVMRVMgREUgTkJJIiwgDQogIHNvdXJjZXMgPSAiRlVFTlRFOiBEQU5FLCAyMDE4IiwgIA0KICBhdXRob3IgPSAiRGllZ28gQXJ0dXJvIEdvbnphbGV6IERlbGdhZGlsbG8iLCANCiAgZnJhbWUgPSBUUlVFLA0KICBub3J0aCA9IFRSVUUsIA0KICB0YWJ0aXRsZSA9IFRSVUUsIA0KICB0aGVtZSA9ICJyZWQucGFsIg0KKSANCmBgYA0KTWFwYXMgSXNvcGxldGggDQoNCkVzdG9zIG1hcGFzIHNlIGJhc2FuIGVuIHZhcmlhYmxlcyBkZSBkaXN0cmlidWNpb24gY29udGludWEgZW4gdW4gYXJlYSBkZXRlcm1pbmFkYSwgcGFyYSBlbGxvIGVudG9uY2VzIGVuIGVzdGUgY2FzbyBpbnRlZ3JhcmVtb3MgbG9zIGRhdG9zIGRlIHByb2R1Y2Npb24gZGUgcGxhdGFubyBlbiBBcmF1Y2EgY29uIGVsIHBhcXVldGUgY2FydG9yYWZpY28uDQoNClNlIGxlZW4gcHJpbWVyb3MgbG9zIGRhdG9zIHByb2R1Y3Rpdm9zLg0KYGBge3J9DQpDVUxUSVZPUzIwMTggPC0gcmVhZF9leGNlbCgiQzovVXNlcnMvTGluYSBNYXJpYSBBeWFsYS5MaW5hTWFyaWFBeWFsYS9Eb2N1bWVudHMvUi9UUkFCQUpPUyBHRU9NQVRJQ0EvQVJBVUNBL0V2YWx1YWNpb25lc19BZ3JvcGVjdWFyaWFzX011bmljaXBhbGVzX0VWQSAyLnhsc3giKQ0KYGBgDQpFc3RvcyBzb24gbG9zIGF0cmlidXRvcy4NCmBgYHtyfQ0KaGVhZChDVUxUSVZPUzIwMTgpDQpgYGANClNlIGZpbHRyYW4gbG9zIGRhdG9zIHBvciBjb3JyZXNwb25kaWVudGVzIGFsIGN1bHRpdm8gZGUgcGxhdGFuby4NCmBgYHtyfQ0KQ1VMVElWT1MyMDE4ICU+JQ0KICBmaWx0ZXIoQ1VMVElWTyA9PSAiUExBVEFOTyIpIC0+IFBMQVRBTk8yMDE4DQpgYGANClNlIGNyZWEgdW4gbnVldm8gYXRyaWJ1dG8gcXVlIGNvaW5jaWRhIGNvbiBsb3MgY29kaWdvcyBkZWwgbXVuaWNpcGlvLg0KYGBge3J9DQpQTEFUQU5PMjAxOCRURU1QIDwtICBhcy5jaGFyYWN0ZXIoUExBVEFOTzIwMTgkQ09EX01VTikNCmBgYA0KYGBge3J9DQpQTEFUQU5PMjAxOCRNUElPX0NDREdPIDwtIGFzLmZhY3RvcihQTEFUQU5PMjAxOCRURU1QKQ0KYGBgDQpTZSBoYWNlIGFob3JhIGxhIHVuaW9uLg0KYGBge3J9DQpQTEFUQU5PX01VTklDID0gbGVmdF9qb2luKE1VTklDLCBQTEFUQU5PMjAxOCwgYnk9Ik1QSU9fQ0NER08iKQ0KYGBgDQpTZSB2ZXJpZmljYW4gbG9zIGF0cmlidXRvcyBkZSBzYWxpZGEuDQpgYGB7cn0NCmhlYWQoUExBVEFOT19NVU5JQykNCmBgYA0KYGBge3J9DQppbnN0YWxsLnBhY2thZ2VzKCJsd2dlb20iKQ0KYGBgDQpgYGB7cn0NCmxpYnJhcnkobHdnZW9tKQ0KYGBgDQoNClNlIHJlIHByb3llY3RhIGxvcyBtdW5pY2lwaW9zLg0KYGBge3J9DQpSRVBfUExBVEFOTyA8LSBzdF90cmFuc2Zvcm0oUExBVEFOT19NVU5JQywgY3JzID0gMzExNikNCmBgYA0KQWhvcmEgc2UgbWFwZWEuDQpTZSBlc3RhYmxlY2VuIGxhcyBtYXJnZW5lcyxjb2xvciBkZSBmb25kbyxsaW1pdGVzIG11bmljaXBhbGVzLGRpc2XDsW8geSBmZWxjaGEgaW5kaWNhdGl2YSBkZWwgbm9ydGUuDQpgYGB7cn0NCm9wYXIgPC0gcGFyKG1hciA9IGMoMCwwLDEuMiwwKSkNCnBsb3Qoc3RfZ2VvbWV0cnkoUkVQX1BMQVRBTk8pLCBjb2wgPSBOQSwgYm9yZGVyID0gIndoaXRlIiwgYmcgPSAib2xpdmVkcmFiMiIpDQpzbW9vdGhMYXllcigNCiAgeCA9IFJFUF9QTEFUQU5PLCANCiAgdmFyID0gJ1Byb2R1Y2Npb24nLA0KICB0eXBlZmN0ID0gImV4cG9uZW50aWFsIiwNCiAgc3BhbiA9IDI1MDAwLA0KICBiZXRhID0gMiwNCiAgbmNsYXNzID0gMTAsDQogIGNvbCA9IGNhcnRvLnBhbChwYWwxID0gJ29yYW5nZS5wYWwnLCBuMSA9IDEwKSwNCiAgYm9yZGVyID0gImJsYWNrIiwNCiAgbHdkID0gMC4xLCANCiAgbWFzayA9IFJFUF9QTEFUQU5PLCANCiAgbGVnZW5kLnZhbHVlcy5ybmQgPSAtMywNCiAgbGVnZW5kLnRpdGxlLnR4dCA9ICJQcm9kdWNjaW9uIiwNCiAgbGVnZW5kLnBvcyA9ICJ0b3ByaWdodCIsIA0KICBhZGQ9VFJVRQ0KKQ0KdGV4dCh4ID0gNjUwMDAwLCB5ID0gMTIwMDAwMCwgY2V4ID0gMC42LCBhZGogPSAwLCBmb250ID0gMywgIGxhYmVscyA9IA0KICAgICAgICJEaXN0YW5jZSBmdW5jdGlvbjpcbi0gdHlwZSA9IGV4cG9uZW50aWFsXG4tIGJldGEgPSAyXG4tIHNwYW4gPSAyMCBrbSIpDQpsYXlvdXRMYXllcih0aXRsZSA9ICJESVNUUklCVUNJT04gREUgTEEgUFJPRFVDQ0lPTiBERSBQTEFUQU5PIEVOIEFSQVVDQSwgMjAxOCIsDQogICAgICAgICAgICBzb3VyY2VzID0gIkZVRU5URTogREFORSBhbmQgTUFEUiwgMjAxOCIsDQogICAgICAgICAgICBhdXRob3IgPSAiRGllZ28gQXJ0dXJvIEdvbnphbGV6IERlbGdhZGlsbG8iLA0KICAgICAgICAgICAgZnJhbWUgPSBGQUxTRSwgbm9ydGggPSBGQUxTRSwgdGFidGl0bGUgPSBUUlVFLCB0aGVtZSA9ICJncmV5LnBhbCIpDQpub3J0aChwb3MgPSAidG9wbGVmdCIpDQpgYGANCkd1YXJkYXIgTWFwYXMNCg0KU2UgcHJvZHVzZSBvdHJvIG1hcGEgZGUgcHJvZHVjY2nDs24gZGUgcGxhdGFubyBlbiBhcmF1Y2EgZW4gZWwgYcOxbyAyMDE4LiBFc3RhIHZleiBzZSB1c2FyYW4gc8OtbWJvbG9zIHByb3BvcmNpb25hbGVzIHkgbWFwYXMgZGUgY29yb3BsZXRhcy5FbCByZXN1bHRhZG8gc2UgZ3VhcmRhcsOhIGNvbW8gdW4gYXJjaGl2byAucG5nDQpgYGB7cn0NCnBuZygiQzovVXNlcnMvTGluYSBNYXJpYSBBeWFsYS5MaW5hTWFyaWFBeWFsYS9Eb2N1bWVudHMvUi9UUkFCQUpPUyBHRU9NQVRJQ0EvQVJBVUNBL1BMQVRBTk9fMjAxOC5wbmciLCB3aWR0aCA9IDIwNDgsIGhlaWdodCA9IDE1MjYpDQoNCm9wYXIgPC0gcGFyKG1hciA9IGMoMCwwLDUsNSkpDQoNCnBsb3Qoc3RfZ2VvbWV0cnkoUkVQX1BMQVRBTk8pLCBjb2w9Im5hdmFqb3doaXRlIiwgYm9yZGVyPSJibGFjayIsICANCiAgICAgYmcgPSAid2hpdGUiLCBsd2QgPSAwLjYpDQpwcm9wU3ltYm9sc0Nob3JvTGF5ZXIoeCA9IFJFUF9QTEFUQU5PLCB2YXIgPSAiUHJvZHVjY2lvbiIsIHZhcjIgPSAiUmVuZGltaWVudG8iLA0KICAgICAgICAgICAgICAgICAgICAgIGNvbCA9IGNhcnRvLnBhbChwYWwxID0gImJsdWUucGFsIiwgbjEgPSAzLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWwyID0gIm9yYW5nZS5wYWwiLCBuMiA9IDMpLA0KICAgICAgICAgICAgICAgICAgICAgIGluY2hlcyA9IDEuNSwgbWV0aG9kID0gInE2IiwNCiAgICAgICAgICAgICAgICAgICAgICBib3JkZXIgPSAic2xhdGVibHVlNCIsIGx3ZCA9IDEsDQogICAgICAgICAgICAgICAgICAgICAgbGVnZW5kLnRpdGxlLmNleCA9IDIsNSwNCiAgICAgICAgICAgICAgICAgICAgICBsZWdlbmQudmFsdWVzLmNleCA9IDIuMSwNCiAgICAgICAgICAgICAgICAgICAgICBsZWdlbmQudmFyLnBvcyA9ICJ0b3ByaWdodCIsIA0KICAgICAgICAgICAgICAgICAgICAgIGxlZ2VuZC52YXIyLnBvcyA9ICJsZWZ0IiwNCiAgICAgICAgICAgICAgICAgICAgICBsZWdlbmQudmFyMi52YWx1ZXMucm5kID0gMiwNCiAgICAgICAgICAgICAgICAgICAgICBsZWdlbmQudmFyMi50aXRsZS50eHQgPSAiUmVuZGltaWVudG9cbihpbiBUb24vSGEpIiwNCiAgICAgICAgICAgICAgICAgICAgICBsZWdlbmQudmFyLnRpdGxlLnR4dCA9ICJQUk9EVUNDSU9OIERFIFBMQVRBTk8gRU4gMjAxOCIsDQogICAgICAgICAgICAgICAgICAgICAgbGVnZW5kLnZhci5zdHlsZSA9ICJlIikNCmxhYmVsTGF5ZXIoDQogIHggPSBSRVBfUExBVEFOTywgDQogIHR4dCA9ICJNUElPX0NOTUJSIiwgDQogIGNvbD0gImJsYWNrIiwgDQogIGNleCA9IDIuMCwgDQogIGZvbnQgPSAyLA0KICBoYWxvID0gRkFMU0UsIA0KICBiZyA9ICJ3aGl0ZSIsIA0KICByID0gMS4xLCANCiAgb3ZlcmxhcCA9IEZBTFNFLCANCiAgc2hvdy5saW5lcyA9IEZBTFNFDQopDQpsYXlvdXRMYXllcih0aXRsZT0iUFJPRFVDQ0lPTiBZIFJFTkRJTUlFTlRPIERFIFBMQVRBTk8gRU4gQVJBVUNBLCAyMDE4IiwNCiAgICAgICAgICAgIGF1dGhvciA9ICJEaWVnbyBBcnR1cm8gR29uemFsZXogRGVsZ2FkaWxsbyIsIA0KICAgICAgICAgICAgc291cmNlcyA9ICJGVUVOVEU6IE1BRFIgJiBEQU5FLCAyMDE4IiwgDQogICAgICAgICAgICBzY2FsZSA9IDUwLCB0YWJ0aXRsZSA9IEZBTFNFLCBmcmFtZSA9IFRSVUUpDQpub3J0aChwb3MgPSAidG9wbGVmdCIpDQp0aXRsZShtYWluPSJQUk9EVUNDSU9OIFkgUkVORElNSUVOVE8gREUgUExBVEFOTyBFTiBBUkFVQ0EsIDIwMTgiLCBjZXgubWFpbj0zLA0KICAgICAgc3ViPSAiRlVFTlRFOiBNQURSICYgREFORSwgMjAxOCIsIGNleC5zdWI9MykNCmdyYXRpY3VsZSA9IFRSVUUNCnBhcihvcGFyKQ0KZGV2Lm9mZigpDQpgYGANCmBgYHtyIG91dC53aWR0aD0iMTAwJSJ9DQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KGtuaXRyKQ0KaW5jbHVkZV9ncmFwaGljcygiQzovVXNlcnMvTGluYSBNYXJpYSBBeWFsYS5MaW5hTWFyaWFBeWFsYS9Eb2N1bWVudHMvUi9UUkFCQUpPUyBHRU9NQVRJQ0EvQVJBVUNBL1BMQVRBTk9fMjAxOC5wbmciKQ0KDQpgYGANClByb2R1Y2Npb24gZGUgcGxhdGFubyBlbiBBcmF1Y2EsIDIwMTgNCmBgYHtyfQ0Kc2Vzc2lvbkluZm8oKQ0KYGBgDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQo=