Agradecimientos

  • Agradezco enormemente a Ivan Lizarazo por su documento guía publicado en Rpubs. Sus documentos son muy valiosos para todos aquellos que como yo queremos aprender un poco acerca de Sistemas de Información Geográfica con R.

SoilGrids

Bibliotecas

library(rgdal)
library(gdalUtils)
library(raster)
library(sf)
library(tidyverse)
library(ggspatial)

Raster Nitrógeno

nitro <- raster("https://files.isric.org/soilgrids/latest/data/nitrogen/nitrogen_15-30cm_mean.vrt")
nitro
class      : RasterLayer 
dimensions : 58034, 159246, 9241682364  (nrow, ncol, ncell)
resolution : 250, 250  (x, y)
extent     : -19949750, 19861750, -6147500, 8361000  (xmin, xmax, ymin, ymax)
crs        : +proj=igh +lon_0=0 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs 
source     : https://files.isric.org/soilgrids/latest/data/nitrogen/nitrogen_15-30cm_mean.vrt 
names      : nitrogen_15.30cm_mean 
values     : -32768, 32767  (min, max)

Shape Colombia

deptos <- st_read("data_shapes/MGN_DPTO_POLITICO.shp")
Reading layer `MGN_DPTO_POLITICO' from data source `D:\DocumentosEdimer\Github\Spatial-Data-Science\SoilGrids\data_shapes\MGN_DPTO_POLITICO.shp' using driver `ESRI Shapefile'
Simple feature collection with 33 features and 9 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: -81.73562 ymin: -4.229406 xmax: -66.84722 ymax: 13.39473
Geodetic CRS:  WGS 84
igh <- '+proj=igh +lat_0=0 +lon_0=0 +datum=WGS84 +units=m +no_defs'
colombia_igh <- st_transform(deptos, igh)
colombia_igh
Simple feature collection with 33 features and 9 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: -9147200 ymin: -470815.4 xmax: -7442381 ymax: 1491094
CRS:           +proj=igh +lat_0=0 +lon_0=0 +datum=WGS84 +units=m +no_defs
First 10 features:
   DPTO_CCDGO DPTO_CNMBR DPTO_ANO_C                                     DPTO_ACT_A DPTO_NAREA
1          05  ANTIOQUIA       1886                  Constitucion Politica de 1886   62804.71
2          23    CÓRDOBA       1951              Ley 9 del 18 de Diciembre de 1951   25086.55
3          27      CHOCÓ       1947              Ley 13 del 3 de Noviembre de 1947   48353.22
4          70      SUCRE       1966                 Ley 47 del 8 de Agosto de 1966   10591.85
5          08  ATLÁNTICO       1910                                 Ley 21 de 1910    3313.81
6          13    BOLÍVAR       1886                  Constitucion Politica de 1886   26719.21
7          47  MAGDALENA       1964                                           1964   23135.94
8          20      CESAR       1967                    Ley 25  21 de junio de 1967   22565.31
9          44 LA GUAJIRA       1964 Acto Legislativo No. 1 de Diciembre 28 de 1964   20619.01
10         19      CAUCA       1857                            15 de junio de 1857   31242.91
   DPTO_CSMBL DPTO_VGNC Shape_Leng  Shape_Area                       geometry
1           3      2020  2397127.4 64104708675 MULTIPOLYGON (((-8537745 98...
2           3      2020  1084739.0 25771851296 MULTIPOLYGON (((-8487485 10...
3           3      2020  2305005.9 49095252907 MULTIPOLYGON (((-8641428 96...
4           3      2020   960645.8 10927904055 MULTIPOLYGON (((-8449360 11...
5           3      2020   286201.3  3452348633 MULTIPOLYGON (((-8384559 12...
6           3      2020  1820039.5 27531715587 MULTIPOLYGON (((-8426196 12...
7           3      2020  1213551.0 24044561103 MULTIPOLYGON (((-8298708 12...
8           3      2020  1410287.8 23352037403 MULTIPOLYGON (((-8229790 12...
9           3      2020  1211484.9 21584067313 MULTIPOLYGON (((-8050536 13...
10          3      2020  1553621.4 31435492565 MULTIPOLYGON (((-8515823 37...
  • Área de interés (Colombia):
area <- st_bbox(colombia_igh)
area
      xmin       ymin       xmax       ymax 
-9147200.3  -470815.4 -7442381.4  1491094.3 
  • Límites: formato numérico necesario para rgdal
ulx <- area$xmin
uly <- area$ymax
lrx <- area$xmax
lry <- area$ymin
limites <- c(ulx, uly, lrx, lry)
limites
      xmin       ymax       xmax       ymin 
-9147200.3  1491094.3 -7442381.4  -470815.4 

Nitrógeno Colombia (.tif)

  • Obtención de datos con GDAL: este proceso se demora algunos minutos. Dará como resultado un archivo con formato .tif en la ruta especificada. Importante: es necesario tener instalado GDAL en nuestro computador (ver anexos para más información).
sg_url <- "/vsicurl/https://files.isric.org/soilgrids/latest/data/nitrogen/nitrogen_15-30cm_mean.vrt"
lfile <- "data_shapes/nitrogeno_colombia.tif"

gdal_translate(sg_url, lfile ,
               tr = c(250,250),
               projwin = limites,
               projwin_srs = igh,
               verbose = TRUE)
Checking gdal_installation...
Scanning for GDAL installations...
Checking Sys.which...
GDAL version 3.2.2
GDAL command being used: "C:\Program Files\GDAL\gdal_translate.exe" -tr 250 250 -projwin -9147200.27432083 1491094.27369704 -7442381.38468577 -470815.374159958 -of "GTiff" -projwin_srs "+proj=igh +lat_0=0 +lon_0=0 +datum=WGS84 +units=m +no_defs" "/vsicurl/https://files.isric.org/soilgrids/latest/data/nitrogen/nitrogen_15-30cm_mean.vrt" "data_shapes/nitrogeno_colombia.tif"
Input file size is 159246, 580340...10...20...30ERROR 1: Request for 390313-406512 failed...40...50...60...70...80...90...100 - done.
NULL

Raster Nitrógeno Colombia


  • Dividimos por 100 para tener las unidades originales (cg/kg)
nitro_colombia <- raster("data_shapes/nitrogeno_colombia.tif") / 100
plot(nitro_colombia)

Corte Colombia

  • Corte con el shape de Colombia que tiene el mismo tipo de coordenadas:
corte_colombia <- nitro_colombia %>% 
  crop(colombia_igh) %>% 
  mask(colombia_igh)
plot(corte_colombia)

  • Corte con shape obtenido con biblioteca raster:
# Mapa Colombia
ejemplo <- getData(name = "GADM", country = "COL", level = 0)
probando la URL 'https://biogeo.ucdavis.edu/data/gadm3.6/Rsp/gadm36_COL_0_sp.rds'
Content type 'à|ˆqþ' length 541789 bytes (529 KB)
downloaded 529 KB
ejemplo_sf <- st_as_sf(ejemplo)

# Reproyección
ejemplo_igh <- st_transform(ejemplo_sf, igh)

# Corte
corte_ejemplo <- nitro_colombia %>% 
  crop(ejemplo_igh) %>% 
  mask(ejemplo_igh)
plot(corte_ejemplo)

  • Corte cambiando sistema de coordenadas:
nuevo_sistema <- "+proj=longlat +datum=WGS84 +no_defs"
prueba <- projectRaster(nitro_colombia, crs = nuevo_sistema)

# Corte
prueba_ejemplo <- prueba %>% 
  crop(ejemplo_sf) %>% 
  mask(ejemplo_sf)
plot(prueba_ejemplo)

Valle del Cauca

Filtro

valle <- colombia_igh %>% 
  filter(DPTO_CNMBR == "VALLE DEL CAUCA")

Corte

corte_valle <- nitro_colombia %>% 
  crop(valle) %>% 
  mask(valle)
plot(corte_valle, colNA = "black")

Mapa ggplot2

  • Conversión a tibble: esta base de datos queda con 323589 observaciones.
valle_df <- corte_valle %>% 
  as("SpatialPixelsDataFrame") %>% 
  as_tibble()

valle_df %>% head()
ggplot() +
  geom_raster(data = valle_df, aes(x = x, y = y, fill = nitrogeno_colombia)) +
  geom_sf(data = valle, alpha = 0, fill = "transparent") +
  labs(fill = "Nitrógeno (cg/kg)",
       x = "Longitud", y = "Latitud") +
  annotation_north_arrow(location = "tl") +
  scale_fill_viridis_c(direction = -1) +
  theme_bw()

Antioquia

Filtro

antioquia <- colombia_igh %>% 
  filter(DPTO_CNMBR == "ANTIOQUIA")

Corte

corte_antioquia <- nitro_colombia %>% 
  crop(antioquia) %>% 
  mask(antioquia)
plot(corte_antioquia, colNA = "black")

Mapa ggplot2

  • Conversión a tibble: esta base de datos queda con 995651 observaciones.
antioquia_df <- corte_antioquia %>% 
  as("SpatialPixelsDataFrame") %>% 
  as_tibble()

antioquia_df %>% head()
ggplot() +
  geom_raster(data = antioquia_df, aes(x = x, y = y, fill = nitrogeno_colombia)) +
  geom_sf(data = antioquia, alpha = 0) +
  labs(fill = "Nitrógeno (cg/kg)",
       x = "Longitud", y = "Latitud") +
  annotation_north_arrow(location = "tr") +
  scale_fill_gradientn(colours = rainbow(30)) +
  theme_bw()

LS0tDQp0aXRsZTogIkV4dHJhY2Npw7NuIGRlIGRhdG9zIFNvaWxHcmlkcyINCnN1YnRpdGxlOiAiRWplbXBsbyBOaXRyw7NnZW5vICgxNS0zMCBjbSkgQ29sb21iaWEiDQphdXRob3I6ICJbRWRpbWVyIChTaWRlcmV1cyldKGh0dHBzOi8vZWRpbWVyLmdpdGh1Yi5pby8pIg0KZGF0ZTogIkFicmlsIGRlIDIwMjEiDQpvdXRwdXQ6DQogIGh0bWxfbm90ZWJvb2s6DQogICAgdG9jOiB0cnVlDQogICAgdG9jX2Zsb2F0Og0KICAgICAgc21vb3RoX3Njcm9sbDogZmFsc2UNCiAgICAgIGNvbGxhcHNlZDogZmFsc2UNCiAgICB0aGVtZTogY29zbW8NCiAgICBkZl9wcmludDogcGFnZWQNCiAgICBjc3M6IGVzdGlsby5jc3MNCiAgICBoaWdobGlnaHQ6IHB5Z21lbnRzDQogICAgY29kZV9mb2xkaW5nOiBzaG93DQogICAgDQotLS0NCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsIHdhcm5pbmcgPSBGQUxTRSwgbWVzc2FnZSA9IEZBTFNFLA0KICAgICAgICAgICAgICAgICAgICAgIGZpZy53aWR0aCA9IDgsIGZpZy5hbGlnbiA9ICJjZW50ZXIiKQ0KYGBgDQoNCiMgQWdyYWRlY2ltaWVudG9zDQoNCi0gQWdyYWRlemNvIGVub3JtZW1lbnRlIGEgW0l2YW4gTGl6YXJhem9dKGh0dHBzOi8vcnB1YnMuY29tL2lhbHMydW4pIHBvciBzdSBbZG9jdW1lbnRvIGd1w61hXShodHRwczovL3JwdWJzLmNvbS9pYWxzMnVuL3NvaWxncmlkc193ZWJkYXYpIHB1YmxpY2FkbyBlbiBbUnB1YnMuXShodHRwczovL3JwdWJzLmNvbS8pIFN1cyBkb2N1bWVudG9zIHNvbiBtdXkgdmFsaW9zb3MgcGFyYSB0b2RvcyBhcXVlbGxvcyBxdWUgY29tbyB5byBxdWVyZW1vcyBhcHJlbmRlciB1biBwb2NvIGFjZXJjYSBkZSBTaXN0ZW1hcyBkZSBJbmZvcm1hY2nDs24gR2VvZ3LDoWZpY2EgY29uIFIuDQoNCiMgU29pbEdyaWRzDQoNCi0gW1NvaWxHcmlkc10oaHR0cHM6Ly9zb2lsZ3JpZHMub3JnLykNCg0KPGNlbnRlcj4NCjxpbWcgc3JjID0gImh0dHBzOi8vd3d3LmlzcmljLm9yZy9zaXRlcy9kZWZhdWx0L2ZpbGVzL3N0eWxlcy9nYWxsZXJ5X2JpZ19pbWFnZV85MDB4NzAwL3B1YmxpYy9Tb2lsR3JpZHNfYmFubmVyX3dlYi5wbmciIC8+DQo8L2NlbnRlcj4NCg0KIyBCaWJsaW90ZWNhcw0KDQpgYGB7cn0NCmxpYnJhcnkocmdkYWwpDQpsaWJyYXJ5KGdkYWxVdGlscykNCmxpYnJhcnkocmFzdGVyKQ0KbGlicmFyeShzZikNCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShnZ3NwYXRpYWwpDQpgYGANCg0KIyBSYXN0ZXIgTml0csOzZ2Vubw0KDQotIFtEYXRvcyBTb2lsR3JpZHNdKGh0dHBzOi8vZmlsZXMuaXNyaWMub3JnL3NvaWxncmlkcy9sYXRlc3QvZGF0YS8pDQotIFtJU1JJQ10oaHR0cHM6Ly93d3cuaXNyaWMub3JnL2V4cGxvcmUpDQotIFtBcnTDrWN1bG8gU29pbEdyaWRzXShodHRwczovL2pvdXJuYWxzLnBsb3Mub3JnL3Bsb3NvbmUvYXJ0aWNsZT9pZD0xMC4xMzcxL2pvdXJuYWwucG9uZS4wMTY5NzQ4KQ0KDQpgYGB7cn0NCm5pdHJvIDwtIHJhc3RlcigiaHR0cHM6Ly9maWxlcy5pc3JpYy5vcmcvc29pbGdyaWRzL2xhdGVzdC9kYXRhL25pdHJvZ2VuL25pdHJvZ2VuXzE1LTMwY21fbWVhbi52cnQiKQ0KYGBgDQoNCmBgYHtyfQ0Kbml0cm8NCmBgYA0KDQoNCiMgU2hhcGUgQ29sb21iaWENCg0KLSBbQ29sb21iaWEgU2hhcGUgLSBOaXZlbCBnZW9ncsOhZmljbyBkZXBhcnRhbWVudG9zXShodHRwczovL2dlb3BvcnRhbC5kYW5lLmdvdi5jby9zZXJ2aWNpb3MvZGVzY2FyZ2EteS1tZXRhZGF0b3MvZGVzY2FyZ2EtbWduLW1hcmNvLWdlb2VzdGFkaXN0aWNvLW5hY2lvbmFsLykNCg0KYGBge3J9DQpkZXB0b3MgPC0gc3RfcmVhZCgiZGF0YV9zaGFwZXMvTUdOX0RQVE9fUE9MSVRJQ08uc2hwIikNCmBgYA0KDQotIFByb3llY2Npw7NuIGRlIGNvb3JkZW5hZGFzOiB0cmFuc2Zvcm1hY2nDs24gYSBbcHJveWVjY2nDs24gaG9tb2xvc2VuYSBkZSBHb29kZV0oaHR0cHM6Ly9lcy53aWtpcGVkaWEub3JnL3dpa2kvUHJveWVjY2klQzMlQjNuX2RlX0dvb2RlKSANCg0KYGBge3J9DQppZ2ggPC0gJytwcm9qPWlnaCArbGF0XzA9MCArbG9uXzA9MCArZGF0dW09V0dTODQgK3VuaXRzPW0gK25vX2RlZnMnDQpjb2xvbWJpYV9pZ2ggPC0gc3RfdHJhbnNmb3JtKGRlcHRvcywgaWdoKQ0KYGBgDQoNCmBgYHtyfQ0KY29sb21iaWFfaWdoDQpgYGANCg0KLSDDgXJlYSBkZSBpbnRlcsOpcyAoQ29sb21iaWEpOg0KDQpgYGB7cn0NCmFyZWEgPC0gc3RfYmJveChjb2xvbWJpYV9pZ2gpDQphcmVhDQpgYGANCg0KLSBMw61taXRlczogZm9ybWF0byBudW3DqXJpY28gbmVjZXNhcmlvIHBhcmEgYHJnZGFsYA0KDQpgYGB7cn0NCnVseCA8LSBhcmVhJHhtaW4NCnVseSA8LSBhcmVhJHltYXgNCmxyeCA8LSBhcmVhJHhtYXgNCmxyeSA8LSBhcmVhJHltaW4NCmxpbWl0ZXMgPC0gYyh1bHgsIHVseSwgbHJ4LCBscnkpDQpsaW1pdGVzDQpgYGANCg0KDQojIE5pdHLDs2dlbm8gQ29sb21iaWEgKC50aWYpDQoNCi0gT2J0ZW5jacOzbiBkZSBkYXRvcyBjb24gKipHREFMKio6IGVzdGUgcHJvY2VzbyBzZSBkZW1vcmEgYWxndW5vcyBtaW51dG9zLiBEYXLDoSBjb21vIHJlc3VsdGFkbyB1biBhcmNoaXZvIGNvbiBmb3JtYXRvICoudGlmKiBlbiBsYSBydXRhIGVzcGVjaWZpY2FkYS4gKipJbXBvcnRhbnRlOioqIGVzIG5lY2VzYXJpbyB0ZW5lciBpbnN0YWxhZG8gR0RBTCBlbiBudWVzdHJvIGNvbXB1dGFkb3IgKHZlciBhbmV4b3MgcGFyYSBtw6FzIGluZm9ybWFjacOzbikuDQoNCmBgYHtyfQ0Kc2dfdXJsIDwtICIvdnNpY3VybC9odHRwczovL2ZpbGVzLmlzcmljLm9yZy9zb2lsZ3JpZHMvbGF0ZXN0L2RhdGEvbml0cm9nZW4vbml0cm9nZW5fMTUtMzBjbV9tZWFuLnZydCINCmxmaWxlIDwtICJkYXRhX3NoYXBlcy9uaXRyb2dlbm9fY29sb21iaWEudGlmIg0KDQpnZGFsX3RyYW5zbGF0ZShzZ191cmwsIGxmaWxlICwNCiAgICAgICAgICAgICAgIHRyID0gYygyNTAsMjUwKSwNCiAgICAgICAgICAgICAgIHByb2p3aW4gPSBsaW1pdGVzLA0KICAgICAgICAgICAgICAgcHJvandpbl9zcnMgPSBpZ2gsDQogICAgICAgICAgICAgICB2ZXJib3NlID0gVFJVRSkNCmBgYA0KDQojIFJhc3RlciBOaXRyw7NnZW5vIENvbG9tYmlhDQoNCi0gW0NvbnN1bHRhciB1bmlkYWRlcyBkZWwgbml0csOzZ2Vub10oaHR0cHM6Ly93d3cuaXNyaWMub3JnL2V4cGxvcmUvc29pbGdyaWRzL2ZhcS1zb2lsZ3JpZHMjV2hhdF9pc19Tb2lsR3JpZHMpDQoNCjxjZW50ZXI+DQo8aW1nIHNyYyA9ICJpbWcvdmFyaWFibGVzX3NvaWxncmlkcy5QTkciIC8+DQo8L2NlbnRlcj4NCg0KPGJyPg0KDQotIERpdmlkaW1vcyBwb3IgMTAwIHBhcmEgdGVuZXIgbGFzIHVuaWRhZGVzIG9yaWdpbmFsZXMgKGNnL2tnKQ0KDQpgYGB7cn0NCm5pdHJvX2NvbG9tYmlhIDwtIHJhc3RlcigiZGF0YV9zaGFwZXMvbml0cm9nZW5vX2NvbG9tYmlhLnRpZiIpIC8gMTAwDQpgYGANCg0KYGBge3J9DQpwbG90KG5pdHJvX2NvbG9tYmlhKQ0KYGBgDQoNCiMgQ29ydGUgQ29sb21iaWENCg0KLSBDb3J0ZSBjb24gZWwgc2hhcGUgZGUgQ29sb21iaWEgcXVlIHRpZW5lIGVsIG1pc21vIHRpcG8gZGUgY29vcmRlbmFkYXM6DQoNCmBgYHtyfQ0KY29ydGVfY29sb21iaWEgPC0gbml0cm9fY29sb21iaWEgJT4lIA0KICBjcm9wKGNvbG9tYmlhX2lnaCkgJT4lIA0KICBtYXNrKGNvbG9tYmlhX2lnaCkNCmBgYA0KDQpgYGB7cn0NCnBsb3QoY29ydGVfY29sb21iaWEpDQpgYGANCg0KLSBDb3J0ZSBjb24gc2hhcGUgb2J0ZW5pZG8gY29uIGJpYmxpb3RlY2EgYHJhc3RlcmA6DQoNCmBgYHtyfQ0KIyBNYXBhIENvbG9tYmlhDQplamVtcGxvIDwtIGdldERhdGEobmFtZSA9ICJHQURNIiwgY291bnRyeSA9ICJDT0wiLCBsZXZlbCA9IDApDQplamVtcGxvX3NmIDwtIHN0X2FzX3NmKGVqZW1wbG8pDQoNCiMgUmVwcm95ZWNjacOzbg0KZWplbXBsb19pZ2ggPC0gc3RfdHJhbnNmb3JtKGVqZW1wbG9fc2YsIGlnaCkNCg0KIyBDb3J0ZQ0KY29ydGVfZWplbXBsbyA8LSBuaXRyb19jb2xvbWJpYSAlPiUgDQogIGNyb3AoZWplbXBsb19pZ2gpICU+JSANCiAgbWFzayhlamVtcGxvX2lnaCkNCmBgYA0KDQpgYGB7cn0NCnBsb3QoY29ydGVfZWplbXBsbykNCmBgYA0KDQotIENvcnRlIGNhbWJpYW5kbyBzaXN0ZW1hIGRlIGNvb3JkZW5hZGFzOg0KDQpgYGB7cn0NCm51ZXZvX3Npc3RlbWEgPC0gIitwcm9qPWxvbmdsYXQgK2RhdHVtPVdHUzg0ICtub19kZWZzIg0KcHJ1ZWJhIDwtIHByb2plY3RSYXN0ZXIobml0cm9fY29sb21iaWEsIGNycyA9IG51ZXZvX3Npc3RlbWEpDQoNCiMgQ29ydGUNCnBydWViYV9lamVtcGxvIDwtIHBydWViYSAlPiUgDQogIGNyb3AoZWplbXBsb19zZikgJT4lIA0KICBtYXNrKGVqZW1wbG9fc2YpDQpgYGANCg0KYGBge3J9DQpwbG90KHBydWViYV9lamVtcGxvKQ0KYGBgDQoNCiMgVmFsbGUgZGVsIENhdWNhDQoNCiMjIEZpbHRybw0KDQpgYGB7cn0NCnZhbGxlIDwtIGNvbG9tYmlhX2lnaCAlPiUgDQogIGZpbHRlcihEUFRPX0NOTUJSID09ICJWQUxMRSBERUwgQ0FVQ0EiKQ0KYGBgDQoNCiMjIENvcnRlDQoNCmBgYHtyfQ0KY29ydGVfdmFsbGUgPC0gbml0cm9fY29sb21iaWEgJT4lIA0KICBjcm9wKHZhbGxlKSAlPiUgDQogIG1hc2sodmFsbGUpDQpgYGANCg0KYGBge3J9DQpwbG90KGNvcnRlX3ZhbGxlLCBjb2xOQSA9ICJibGFjayIpDQpgYGANCg0KIyMgTWFwYSBgZ2dwbG90MmANCg0KLSBDb252ZXJzacOzbiBhIHRpYmJsZTogZXN0YSBiYXNlIGRlIGRhdG9zIHF1ZWRhIGNvbiAzMjM1ODkgb2JzZXJ2YWNpb25lcy4NCg0KYGBge3J9DQp2YWxsZV9kZiA8LSBjb3J0ZV92YWxsZSAlPiUgDQogIGFzKCJTcGF0aWFsUGl4ZWxzRGF0YUZyYW1lIikgJT4lIA0KICBhc190aWJibGUoKQ0KDQp2YWxsZV9kZiAlPiUgaGVhZCgpDQpgYGANCg0KDQpgYGB7cn0NCmdncGxvdCgpICsNCiAgZ2VvbV9yYXN0ZXIoZGF0YSA9IHZhbGxlX2RmLCBhZXMoeCA9IHgsIHkgPSB5LCBmaWxsID0gbml0cm9nZW5vX2NvbG9tYmlhKSkgKw0KICBnZW9tX3NmKGRhdGEgPSB2YWxsZSwgYWxwaGEgPSAwLCBmaWxsID0gInRyYW5zcGFyZW50IikgKw0KICBsYWJzKGZpbGwgPSAiTml0csOzZ2VubyAoY2cva2cpIiwNCiAgICAgICB4ID0gIkxvbmdpdHVkIiwgeSA9ICJMYXRpdHVkIikgKw0KICBhbm5vdGF0aW9uX25vcnRoX2Fycm93KGxvY2F0aW9uID0gInRsIikgKw0KICBzY2FsZV9maWxsX3ZpcmlkaXNfYyhkaXJlY3Rpb24gPSAtMSkgKw0KICB0aGVtZV9idygpDQpgYGANCg0KIyBBbnRpb3F1aWENCg0KIyMgRmlsdHJvDQoNCmBgYHtyfQ0KYW50aW9xdWlhIDwtIGNvbG9tYmlhX2lnaCAlPiUgDQogIGZpbHRlcihEUFRPX0NOTUJSID09ICJBTlRJT1FVSUEiKQ0KYGBgDQoNCiMjIENvcnRlDQoNCmBgYHtyfQ0KY29ydGVfYW50aW9xdWlhIDwtIG5pdHJvX2NvbG9tYmlhICU+JSANCiAgY3JvcChhbnRpb3F1aWEpICU+JSANCiAgbWFzayhhbnRpb3F1aWEpDQpgYGANCg0KYGBge3J9DQpwbG90KGNvcnRlX2FudGlvcXVpYSwgY29sTkEgPSAiYmxhY2siKQ0KYGBgDQoNCiMjIE1hcGEgYGdncGxvdDJgDQoNCi0gQ29udmVyc2nDs24gYSB0aWJibGU6IGVzdGEgYmFzZSBkZSBkYXRvcyBxdWVkYSBjb24gOTk1NjUxIG9ic2VydmFjaW9uZXMuDQoNCmBgYHtyfQ0KYW50aW9xdWlhX2RmIDwtIGNvcnRlX2FudGlvcXVpYSAlPiUgDQogIGFzKCJTcGF0aWFsUGl4ZWxzRGF0YUZyYW1lIikgJT4lIA0KICBhc190aWJibGUoKQ0KDQphbnRpb3F1aWFfZGYgJT4lIGhlYWQoKQ0KYGBgDQoNCg0KYGBge3J9DQpnZ3Bsb3QoKSArDQogIGdlb21fcmFzdGVyKGRhdGEgPSBhbnRpb3F1aWFfZGYsIGFlcyh4ID0geCwgeSA9IHksIGZpbGwgPSBuaXRyb2dlbm9fY29sb21iaWEpKSArDQogIGdlb21fc2YoZGF0YSA9IGFudGlvcXVpYSwgYWxwaGEgPSAwKSArDQogIGxhYnMoZmlsbCA9ICJOaXRyw7NnZW5vIChjZy9rZykiLA0KICAgICAgIHggPSAiTG9uZ2l0dWQiLCB5ID0gIkxhdGl0dWQiKSArDQogIGFubm90YXRpb25fbm9ydGhfYXJyb3cobG9jYXRpb24gPSAidHIiKSArDQogIHNjYWxlX2ZpbGxfZ3JhZGllbnRuKGNvbG91cnMgPSByYWluYm93KDMwKSkgKw0KICB0aGVtZV9idygpDQpgYGANCg0KIyBBbmV4b3MNCg0KIyMgUmVjdXJzb3MgZGUgaW5mb3JtYWNpw7NuDQoNCi0gW2dkYWwub3JnXShodHRwczovL2dkYWwub3JnLykNCi0gW2dpc2ludGVybmFscy5jb21dKGh0dHBzOi8vd3d3Lmdpc2ludGVybmFscy5jb20vcmVsZWFzZS5waHApDQotIFtUdXRvcmlhbCBpbnN0YWxhY2nDs24gZ2RhbCBXaW5kb3dzIChpbmdsw6lzKV0oaHR0cHM6Ly9zYW5kYm94LmlkcmUudWNsYS5lZHUvc2FuZGJveC90dXRvcmlhbHMvaW5zdGFsbGluZy1nZGFsLWZvci13aW5kb3dzKQ0KLSBbVHV0b3JpYWwgaW5zdGFsYWNpw7NuIGdkYWwgV2luZG93cyAoZXNwYcOxb2wpXShodHRwOi8vc2lnZGVsZXRyYXMuY29tLzIwMTYvaW5zdGFsYWNpb24tZGUtcHl0aG9uLXktZ2RhbC1lbi13aW5kb3dzLykNCg==