Paula Virguez Gómez

28 de marzo de 2020

1.Introducción

Instalar paquetes

install.packages("rgdal")
install.packages("raster")
install.packages("elevatr")
install.packages("rasterVis")
install.packages("rgl")
library(rasterVis)
Loading required package: raster
Loading required package: lattice
Loading required package: latticeExtra
library(raster)
library(rgl)
library(rgdal)
library(elevatr)

2. Obtención datos de elevación Raster Revisar el contenido de la carpeta del dpartamento deamazonas del DANE.

list.files("G:/Geomatica/Datos_de _elevacion_en_R/Amazonas_datos_DANE/91_AMAZONAS/ADMINISTRATIVO")
 [1] "MGN_DPTO_POLITICO.cpg"     "MGN_DPTO_POLITICO.dbf"    
 [3] "MGN_DPTO_POLITICO.prj"     "MGN_DPTO_POLITICO.sbn"    
 [5] "MGN_DPTO_POLITICO.sbx"     "MGN_DPTO_POLITICO.shp"    
 [7] "MGN_DPTO_POLITICO.shp.xml" "MGN_DPTO_POLITICO.shx"    
 [9] "MGN_MPIO_POLITICO.cpg"     "MGN_MPIO_POLITICO.dbf"    
[11] "MGN_MPIO_POLITICO.prj"     "MGN_MPIO_POLITICO.sbn"    
[13] "MGN_MPIO_POLITICO.sbx"     "MGN_MPIO_POLITICO.shp"    
[15] "MGN_MPIO_POLITICO.shp.xml" "MGN_MPIO_POLITICO.shx"    

Ahora, leer el shaoe usando la función del paquete raster:

(munic <- shapefile("G:/Geomatica/Datos_de _elevacion_en_R/Amazonas_datos_DANE/91_AMAZONAS/ADMINISTRATIVO/MGN_MPIO_POLITICO.shp"))
class       : SpatialPolygonsDataFrame 
features    : 11 
extent      : -74.39634, -69.3955, -4.229406, 0.09725686  (xmin, xmax, ymin, ymax)
crs         : +proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0 
variables   : 9
names       : DPTO_CCDGO, MPIO_CCDGO, MPIO_CNMBR,                      MPIO_CRSLC,    MPIO_NAREA, MPIO_NANO, DPTO_CNMBR,    Shape_Leng,     Shape_Area 
min values  :         91,      91001, EL ENCANTO, Decreto 106 de Enero 18 de 1984, 1432.79497455,      2017,   AMAZONAS, 1.96885902115, 0.116086252919 
max values  :         91,      91798,  TARAPACÁ,     ORD 24 DE AGOSTO 01 DE 1997, 16866.1197714,      2017,   AMAZONAS, 10.6360457915,  1.36686628423 

Atributos de munic:

head(munic)

Seleccionar solamente la capital ldel departamento

ltc <- munic[munic$MPIO_CNMBR=="LETICIA",]
plot(ltc, main="Leticia", axes=TRUE)
plot(munic, add=TRUE)
invisible(text(coordinates(munic), labels=as.character(munic$MPIO_CNMBR), cex=0.6))

Descargar los datos de elevación:

elevacion <- get_elev_raster(ltc, z=9)

Verificar que hay dentro del objeto de elevación:

elevacion
class      : RasterLayer 
dimensions : 2057, 1550, 3188350  (nrow, ncol, ncell)
resolution : 0.00137, 0.00137  (x, y)
extent     : -71.02247, -68.89897, -5.622611, -2.804521  (xmin, xmax, ymin, ymax)
crs        : +proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0 
source     : memory
names      : layer 
values     : -1267.138, 1273.577  (min, max)
plot(elevacion, main="DEM descargado (metros)")
plot(ltc, add=TRUE)

3.Recorte de datos para que coincidan con la extension del area de estudio

writeRaster(elevacion, filename = ".dem/elev_z9.tif", dataType('FLT4S', overwrite=TRUE))
elev_crop = crop(elevacion, ltc)
plot(elev_crop, main="Modelo de elevación digital recortado")
plot(ltc, add=TRUE)

Ver nuevo proyecto

elev_crop
class      : RasterLayer 
dimensions : 895, 475, 425125  (nrow, ncol, ncell)
resolution : 0.00137, 0.00137  (x, y)
extent     : -70.36487, -69.71412, -4.229321, -3.003171  (xmin, xmax, ymin, ymax)
crs        : +proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0 
source     : memory
names      : layer 
values     : -607.5793, 435.8793  (min, max)

4. Reproyectar los datos de elevación

spatialref <-"+proj=tmerc +lat_0=4.596200416666666 +lon_0=-74.07750791666666 +k=1 +x_0=1000000 +y_0=1000000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs"

Reproyectar los datos de elevación de las coordenadas geograficas WGS84 en la zona MAGNA de Colombia BogotÔ

pr3 <- projectExtent(elev_crop,spatialref)
res(pr3) <- 100
rep_elev <- projectRaster(elev_crop,pr3)
rep_elev
class      : RasterLayer 
dimensions : 1362, 731, 995622  (nrow, ncol, ncell)
resolution : 100, 100  (x, y)
extent     : 1412458, 1485558, 22789.2, 158989.2  (xmin, xmax, ymin, ymax)
crs        : +proj=tmerc +lat_0=4.596200416666666 +lon_0=-74.07750791666666 +k=1 +x_0=1000000 +y_0=1000000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs 
source     : memory
names      : layer 
values     : -470.7503, 401.2846  (min, max)

Ahora reproyectamos el Spatial PolygonsDataFrame que representa la capital de amazonas:

(rep_ltc = spTransform(ltc,spatialref))
class       : SpatialPolygonsDataFrame 
features    : 1 
extent      : 1412656, 1485526, 22875.46, 158875.8  (xmin, xmax, ymin, ymax)
crs         : +proj=tmerc +lat_0=4.596200416666666 +lon_0=-74.07750791666666 +k=1 +x_0=1000000 +y_0=1000000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs 
variables   : 9
names       : DPTO_CCDGO, MPIO_CCDGO, MPIO_CNMBR,                    MPIO_CRSLC,    MPIO_NAREA, MPIO_NANO, DPTO_CNMBR,    Shape_Leng,     Shape_Area 
value       :         91,      91001,    LETICIA, Decreto 352 de Feb 20 de 1964, 6183.12917992,      2017,   AMAZONAS, 3.88000064403, 0.500701815381 
plot(rep_elev,main="Modelo de elevación digital reproyectado")
plot(rep_ltc, add=TRUE)

writeRaster(rep_elev, filename = "./rep_ltc_elev.tif", datatype = 'INT4S', overwrite = TRUE)

5. Estadísticas bÔsicas de los datos de elevación

Exploración de las estadísticas de los DEM

hist(rep_elev)

promedio <- cellStats(rep_elev, 'mean')
minimo <- cellStats(rep_elev, 'min')
maximo <-cellStats(rep_elev,'max')
desviacion <- cellStats(rep_elev, 'sd')

Crear vector unidimensional

metricas <- c('mean', 'min', 'max', 'std')
valores <- c(promedio, minimo, maximo, desviacion)
(df_estadisticas <- data.frame(metricas,valores))

6. Obtención de variables geomorfométricas

slope = terrain(rep_elev, opt='slope', unit='degrees')
aspect= terrain(rep_elev, opt='aspect', unit='degrees')
hill= hillShade(slope,aspect,40,315)

Plot elevación

plot(rep_elev,main="DEM para Leticia (metros)", col=terrain.colors(25,alpha=0.7))

Plot pendiente

plot(slope,main="Pendiente para Leticia (grados)", col=rainbow(25,alpha = 0.7))

Plot Orientación

plot(aspect,main="Exposición para Leticia (grados)", col=rainbow(25,alpha = 0.7))

Plot combinado

plot(hill,
     col=grey(1:100/100),
     legend=FALSE,
     main="DEM para Leticia",
     axes=FALSE)

plot(rep_elev,
     axes=FALSE,
     col=rainbow(12,alpha = 0.35), add=TRUE)

**7. Mapeo de datos de elevación con rayshader

install.packages("rayshader")
library(rayshader)
elmat = raster_to_matrix(rep_elev)
[1] "Dimensions of matrix are: 731x1362."
elmat %>%
  sphere_shade(texture = "imhof2") %>%
  plot_map()

elmat %>%
  sphere_shade(texture = "desert")%>%
  add_water(detect_water(elmat), color = "desert") %>%
  plot_map()

elmat %>%
  sphere_shade(texture = "desert") %>%
  add_water(detect_water(elmat), color = "desert") %>%
  add_shadow(ray_shade(elmat), 0.5) %>%
  plot_map()

8.Otra forma de vizualización

install.packages("jpeg")
library(jpeg)
getv=function(i,a,s){
  ct=dim(i)[1:2]/2
  sx=values(s)/90 * ct[1]
  sy=values(s)/90 * ct[2]
  a =values(a) * 0.01745
  px = floor(ct[1] + sx * -sin(a))
  py = floor(ct[2] + sy * cos(a))
  
  template = brick(s,s,s)
  values(template)=NA
  
  cellr = px + py * ct[1]*2
  cellg = px + py * ct[1]*2 + (ct[1]*2*ct[2]*2)
  cellb = px + py * ct[1]*2 + 2*(ct[1]*2*ct[2]*2)
  
  template[[1]] = i[cellr]
  template[[2]] = i[cellr]
  template[[3]] = i[cellb]
  
  template =  template * 256
  
  template
}
map = readJPEG("G:/Geomatica/Datos_de _elevacion_en_R/Amazonas_datos_DANE/9pvbHjN.jpg")

out= getv(map, aspect, slope)
ning昼㹔n argumento finito para min; retornando Infningun argumento finito para max; retornando -Infning昼㹔n argumento finito para min; retornando Infningun argumento finito para max; retornando -Infning昼㹔n argumento finito para min; retornando Infningun argumento finito para max; retornando -Infning昼㹔n argumento finito para min; retornando Infningun argumento finito para max; retornando -Infning昼㹔n argumento finito para min; retornando Infningun argumento finito para max; retornando -Infning昼㹔n argumento finito para min; retornando Infningun argumento finito para max; retornando -Inf
plotRGB(out, main = "'Elevacion' en Leticia")

LS0tDQp0aXRsZTogIkRhdG9zIGRlIGVsZXZhY2nDs24gZW4gUiINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KLS0tDQpQYXVsYSBWaXJndWV6IEfDs21leg0KDQoyOCBkZSBtYXJ6byBkZSAyMDIwDQoNCioqMS5JbnRyb2R1Y2Npw7NuKioNCg0KSW5zdGFsYXIgcGFxdWV0ZXMNCmBgYHtyfQ0KaW5zdGFsbC5wYWNrYWdlcygicmdkYWwiKQ0KaW5zdGFsbC5wYWNrYWdlcygicmFzdGVyIikNCmluc3RhbGwucGFja2FnZXMoImVsZXZhdHIiKQ0KaW5zdGFsbC5wYWNrYWdlcygicmFzdGVyVmlzIikNCmluc3RhbGwucGFja2FnZXMoInJnbCIpDQpgYGANCg0KYGBge3J9DQpsaWJyYXJ5KHJhc3RlclZpcykNCmBgYA0KDQpgYGB7cn0NCmxpYnJhcnkocmFzdGVyKQ0KbGlicmFyeShyZ2wpDQpsaWJyYXJ5KHJnZGFsKQ0KYGBgDQoNCmBgYHtyfQ0KbGlicmFyeShlbGV2YXRyKQ0KYGBgDQoNCioqMi4gT2J0ZW5jacOzbiBkYXRvcyBkZSBlbGV2YWNpw7NuIFJhc3RlcioqDQpSZXZpc2FyIGVsIGNvbnRlbmlkbyBkZSBsYSBjYXJwZXRhIGRlbCBkcGFydGFtZW50byBkZWFtYXpvbmFzIGRlbCBEQU5FLg0KYGBge3J9DQpsaXN0LmZpbGVzKCJHOi9HZW9tYXRpY2EvRGF0b3NfZGUgX2VsZXZhY2lvbl9lbl9SL0FtYXpvbmFzX2RhdG9zX0RBTkUvOTFfQU1BWk9OQVMvQURNSU5JU1RSQVRJVk8iKQ0KYGBgDQoNCkFob3JhLCBsZWVyIGVsIHNoYW9lIHVzYW5kbyBsYSBmdW5jacOzbiBkZWwgcGFxdWV0ZSByYXN0ZXI6DQpgYGB7cn0NCihtdW5pYyA8LSBzaGFwZWZpbGUoIkc6L0dlb21hdGljYS9EYXRvc19kZSBfZWxldmFjaW9uX2VuX1IvQW1hem9uYXNfZGF0b3NfREFORS85MV9BTUFaT05BUy9BRE1JTklTVFJBVElWTy9NR05fTVBJT19QT0xJVElDTy5zaHAiKSkNCmBgYA0KDQpBdHJpYnV0b3MgZGUgKm11bmljKjoNCmBgYHtyfQ0KaGVhZChtdW5pYykNCmBgYA0KDQpTZWxlY2Npb25hciBzb2xhbWVudGUgbGEgY2FwaXRhbCBsZGVsIGRlcGFydGFtZW50bw0KYGBge3J9DQpsdGMgPC0gbXVuaWNbbXVuaWMkTVBJT19DTk1CUj09IkxFVElDSUEiLF0NCnBsb3QobHRjLCBtYWluPSJMZXRpY2lhIiwgYXhlcz1UUlVFKQ0KcGxvdChtdW5pYywgYWRkPVRSVUUpDQppbnZpc2libGUodGV4dChjb29yZGluYXRlcyhtdW5pYyksIGxhYmVscz1hcy5jaGFyYWN0ZXIobXVuaWMkTVBJT19DTk1CUiksIGNleD0wLjYpKQ0KYGBgDQoNCkRlc2NhcmdhciBsb3MgZGF0b3MgZGUgZWxldmFjacOzbjoNCmBgYHtyfQ0KZWxldmFjaW9uIDwtIGdldF9lbGV2X3Jhc3RlcihsdGMsIHo9OSkNCmBgYA0KDQpWZXJpZmljYXIgcXVlIGhheSBkZW50cm8gZGVsIG9iamV0byBkZSBlbGV2YWNpw7NuOg0KYGBge3J9DQplbGV2YWNpb24NCmBgYA0KDQpgYGB7cn0NCnBsb3QoZWxldmFjaW9uLCBtYWluPSJERU0gZGVzY2FyZ2FkbyAobWV0cm9zKSIpDQpwbG90KGx0YywgYWRkPVRSVUUpDQpgYGANCg0KKiozLlJlY29ydGUgZGUgZGF0b3MgcGFyYSBxdWUgY29pbmNpZGFuIGNvbiBsYSBleHRlbnNpb24gZGVsIGFyZWEgZGUgZXN0dWRpbyoqDQpgYGB7cg0Kd3JpdGVSYXN0ZXIoZWxldmFjaW9uLCBmaWxlbmFtZSA9ICIuZGVtL2VsZXZfejkudGlmIiwgZGF0YVR5cGUoJ0ZMVDRTJywgb3ZlcndyaXRlPVRSVUUpKQ0KYGBgDQoNCmBgYHtyfQ0KZWxldl9jcm9wID0gY3JvcChlbGV2YWNpb24sIGx0YykNCnBsb3QoZWxldl9jcm9wLCBtYWluPSJNb2RlbG8gZGUgZWxldmFjacOzbiBkaWdpdGFsIHJlY29ydGFkbyIpDQpwbG90KGx0YywgYWRkPVRSVUUpDQpgYGANCg0KVmVyIG51ZXZvIHByb3llY3RvDQpgYGB7cn0NCmVsZXZfY3JvcA0KYGBgDQoNCioqNC4gUmVwcm95ZWN0YXIgbG9zIGRhdG9zIGRlIGVsZXZhY2nDs24qKg0KYGBge3J9DQpzcGF0aWFscmVmIDwtIitwcm9qPXRtZXJjICtsYXRfMD00LjU5NjIwMDQxNjY2NjY2NiArbG9uXzA9LTc0LjA3NzUwNzkxNjY2NjY2ICtrPTEgK3hfMD0xMDAwMDAwICt5XzA9MTAwMDAwMCArZWxscHM9R1JTODAgK3Rvd2dzODQ9MCwwLDAsMCwwLDAsMCArdW5pdHM9bSArbm9fZGVmcyINCmBgYA0KDQpSZXByb3llY3RhciBsb3MgZGF0b3MgZGUgZWxldmFjacOzbiBkZSBsYXMgY29vcmRlbmFkYXMgZ2VvZ3JhZmljYXMgV0dTODQgZW4gbGEgem9uYSBNQUdOQSAgZGUgQ29sb21iaWEgQm9nb3TDoQ0KYGBge3J9DQpwcjMgPC0gcHJvamVjdEV4dGVudChlbGV2X2Nyb3Asc3BhdGlhbHJlZikNCnJlcyhwcjMpIDwtIDEwMA0KcmVwX2VsZXYgPC0gcHJvamVjdFJhc3RlcihlbGV2X2Nyb3AscHIzKQ0KYGBgDQoNCmBgYHtyfQ0KcmVwX2VsZXYNCmBgYA0KDQpBaG9yYSByZXByb3llY3RhbW9zIGVsIFNwYXRpYWwgUG9seWdvbnNEYXRhRnJhbWUgcXVlIHJlcHJlc2VudGEgbGEgY2FwaXRhbCBkZSBhbWF6b25hczoNCmBgYHtyfQ0KKHJlcF9sdGMgPSBzcFRyYW5zZm9ybShsdGMsc3BhdGlhbHJlZikpDQpgYGANCg0KYGBge3J9DQpwbG90KHJlcF9lbGV2LG1haW49Ik1vZGVsbyBkZSBlbGV2YWNpw7NuIGRpZ2l0YWwgcmVwcm95ZWN0YWRvIikNCnBsb3QocmVwX2x0YywgYWRkPVRSVUUpDQpgYGANCg0KYGBge3J9DQp3cml0ZVJhc3RlcihyZXBfZWxldiwgZmlsZW5hbWUgPSAiLi9yZXBfbHRjX2VsZXYudGlmIiwgZGF0YXR5cGUgPSAnSU5UNFMnLCBvdmVyd3JpdGUgPSBUUlVFKQ0KYGBgDQoNCioqNS4gRXN0YWTDrXN0aWNhcyBiw6FzaWNhcyBkZSBsb3MgZGF0b3MgZGUgZWxldmFjacOzbioqDQoNCkV4cGxvcmFjacOzbiBkZSBsYXMgZXN0YWTDrXN0aWNhcyBkZSBsb3MgREVNDQpgYGB7cn0NCmhpc3QocmVwX2VsZXYpDQpgYGANCg0KYGBge3J9DQpwcm9tZWRpbyA8LSBjZWxsU3RhdHMocmVwX2VsZXYsICdtZWFuJykNCm1pbmltbyA8LSBjZWxsU3RhdHMocmVwX2VsZXYsICdtaW4nKQ0KbWF4aW1vIDwtY2VsbFN0YXRzKHJlcF9lbGV2LCdtYXgnKQ0KZGVzdmlhY2lvbiA8LSBjZWxsU3RhdHMocmVwX2VsZXYsICdzZCcpDQpgYGANCg0KQ3JlYXIgdmVjdG9yIHVuaWRpbWVuc2lvbmFsDQpgYGB7cn0NCm1ldHJpY2FzIDwtIGMoJ21lYW4nLCAnbWluJywgJ21heCcsICdzdGQnKQ0KdmFsb3JlcyA8LSBjKHByb21lZGlvLCBtaW5pbW8sIG1heGltbywgZGVzdmlhY2lvbikNCmBgYA0KDQpgYGB7cn0NCihkZl9lc3RhZGlzdGljYXMgPC0gZGF0YS5mcmFtZShtZXRyaWNhcyx2YWxvcmVzKSkNCmBgYA0KDQoqKjYuIE9idGVuY2nDs24gZGUgdmFyaWFibGVzIGdlb21vcmZvbcOpdHJpY2FzKioNCg0KYGBge3J9DQpzbG9wZSA9IHRlcnJhaW4ocmVwX2VsZXYsIG9wdD0nc2xvcGUnLCB1bml0PSdkZWdyZWVzJykNCmFzcGVjdD0gdGVycmFpbihyZXBfZWxldiwgb3B0PSdhc3BlY3QnLCB1bml0PSdkZWdyZWVzJykNCmhpbGw9IGhpbGxTaGFkZShzbG9wZSxhc3BlY3QsNDAsMzE1KQ0KYGBgDQoNClBsb3QgZWxldmFjacOzbg0KYGBge3J9DQpwbG90KHJlcF9lbGV2LG1haW49IkRFTSBwYXJhIExldGljaWEgKG1ldHJvcykiLCBjb2w9dGVycmFpbi5jb2xvcnMoMjUsYWxwaGE9MC43KSkNCmBgYA0KDQpQbG90IHBlbmRpZW50ZQ0KYGBge3J9DQpwbG90KHNsb3BlLG1haW49IlBlbmRpZW50ZSBwYXJhIExldGljaWEgKGdyYWRvcykiLCBjb2w9cmFpbmJvdygyNSxhbHBoYSA9IDAuNykpDQpgYGANCg0KUGxvdCBPcmllbnRhY2nDs24NCmBgYHtyfQ0KcGxvdChhc3BlY3QsbWFpbj0iRXhwb3NpY2nDs24gcGFyYSBMZXRpY2lhIChncmFkb3MpIiwgY29sPXJhaW5ib3coMjUsYWxwaGEgPSAwLjcpKQ0KYGBgDQoNClBsb3QgY29tYmluYWRvDQpgYGB7cn0NCnBsb3QoaGlsbCwNCiAgICAgY29sPWdyZXkoMToxMDAvMTAwKSwNCiAgICAgbGVnZW5kPUZBTFNFLA0KICAgICBtYWluPSJERU0gcGFyYSBMZXRpY2lhIiwNCiAgICAgYXhlcz1GQUxTRSkNCg0KcGxvdChyZXBfZWxldiwNCiAgICAgYXhlcz1GQUxTRSwNCiAgICAgY29sPXJhaW5ib3coMTIsYWxwaGEgPSAwLjM1KSwgYWRkPVRSVUUpDQpgYGANCg0KKio3LiBNYXBlbyBkZSBkYXRvcyBkZSBlbGV2YWNpw7NuIGNvbiByYXlzaGFkZXINCmBgYHtyfQ0KaW5zdGFsbC5wYWNrYWdlcygicmF5c2hhZGVyIikNCmBgYA0KDQpgYGB7cn0NCmxpYnJhcnkocmF5c2hhZGVyKQ0KYGBgDQoNCmBgYHtyfQ0KZWxtYXQgPSByYXN0ZXJfdG9fbWF0cml4KHJlcF9lbGV2KQ0KYGBgDQoNCmBgYHtyfQ0KZWxtYXQgJT4lDQogIHNwaGVyZV9zaGFkZSh0ZXh0dXJlID0gImltaG9mMiIpICU+JQ0KICBwbG90X21hcCgpDQpgYGANCg0KYGBge3J9DQplbG1hdCAlPiUNCiAgc3BoZXJlX3NoYWRlKHRleHR1cmUgPSAiZGVzZXJ0IiklPiUNCiAgYWRkX3dhdGVyKGRldGVjdF93YXRlcihlbG1hdCksIGNvbG9yID0gImRlc2VydCIpICU+JQ0KICBwbG90X21hcCgpDQpgYGANCg0KYGBge3J9DQplbG1hdCAlPiUNCiAgc3BoZXJlX3NoYWRlKHRleHR1cmUgPSAiZGVzZXJ0IikgJT4lDQogIGFkZF93YXRlcihkZXRlY3Rfd2F0ZXIoZWxtYXQpLCBjb2xvciA9ICJkZXNlcnQiKSAlPiUNCiAgYWRkX3NoYWRvdyhyYXlfc2hhZGUoZWxtYXQpLCAwLjUpICU+JQ0KICBwbG90X21hcCgpDQpgYGANCg0KKio4Lk90cmEgZm9ybWEgZGUgdml6dWFsaXphY2nDs24qKg0KYGBge3J9DQppbnN0YWxsLnBhY2thZ2VzKCJqcGVnIikNCmBgYA0KDQpgYGB7cn0NCmxpYnJhcnkoanBlZykNCmBgYA0KDQpgYGB7cn0NCmdldHY9ZnVuY3Rpb24oaSxhLHMpew0KICBjdD1kaW0oaSlbMToyXS8yDQogIHN4PXZhbHVlcyhzKS85MCAqIGN0WzFdDQogIHN5PXZhbHVlcyhzKS85MCAqIGN0WzJdDQogIGEgPXZhbHVlcyhhKSAqIDAuMDE3NDUNCiAgcHggPSBmbG9vcihjdFsxXSArIHN4ICogLXNpbihhKSkNCiAgcHkgPSBmbG9vcihjdFsyXSArIHN5ICogY29zKGEpKQ0KICANCiAgdGVtcGxhdGUgPSBicmljayhzLHMscykNCiAgdmFsdWVzKHRlbXBsYXRlKT1OQQ0KICANCiAgY2VsbHIgPSBweCArIHB5ICogY3RbMV0qMg0KICBjZWxsZyA9IHB4ICsgcHkgKiBjdFsxXSoyICsgKGN0WzFdKjIqY3RbMl0qMikNCiAgY2VsbGIgPSBweCArIHB5ICogY3RbMV0qMiArIDIqKGN0WzFdKjIqY3RbMl0qMikNCiAgDQogIHRlbXBsYXRlW1sxXV0gPSBpW2NlbGxyXQ0KICB0ZW1wbGF0ZVtbMl1dID0gaVtjZWxscl0NCiAgdGVtcGxhdGVbWzNdXSA9IGlbY2VsbGJdDQogIA0KICB0ZW1wbGF0ZSA9ICB0ZW1wbGF0ZSAqIDI1Ng0KICANCiAgdGVtcGxhdGUNCn0NCmBgYA0KDQpgYGB7cn0NCm1hcCA9IHJlYWRKUEVHKCJHOi9HZW9tYXRpY2EvRGF0b3NfZGUgX2VsZXZhY2lvbl9lbl9SL0FtYXpvbmFzX2RhdG9zX0RBTkUvOXB2YkhqTi5qcGciKQ0KDQpvdXQ9IGdldHYobWFwLCBhc3BlY3QsIHNsb3BlKQ0KDQpwbG90UkdCKG91dCwgbWFpbiA9ICInRWxldmFjaW9uJyBlbiBMZXRpY2lhIikNCmBgYA0KDQo=