1. Introducción

Este cuaderno, ha sido creado desde RStudio Cloud e ilustra las funcionalidades de la biblioteca Smapr , en particular en este cuaderno se adquieren y se procesan los datos de humedad del suelo : SMAP (Soil Moisture Active-Passive) de la NASA. Además, se recortan los datos para que coincidan con el área de estudio y se generan visualizaciones simples de la humedad del suelo en el departamento del Vichada

2. Datos SMAP

La misión SMAP , mide la cantidad de agua en la superficie del suelo en todas partes de la Tierrae .Es decir, está diseñado para medir la humedad del suelo, cada 2-3 días

Algunos datos de esta misión SMAP , son proporcionados por el centro nacional de datos de nieve y hielo (NSIDC) . En la página del NSIDC se describen diferentes niveles de datos , principalmente se encuentran datos de nivel 3 que son productos compuestos globales y datos nivel 4 productos de datos globales modelados cada tres horas

Por otro lado,describen los productos de nivel 1 como mediciones de instrumentos brutos o calibrados y geolocalizados del radar y el radiometro SMAP, mientras que los datos de Nivel 2 , contienen recuperaciones del suelo derivadas de archivos auxiliares y los datos del nivel 1 .Estos 2 nieveles de datos tienen una resolución temporal de 49 minutos , que es el tiempo que tarda el satélite en completar media órbita de la tierra

Los productos del Nivel 3 son compuestos diarios de los datos de humedad del suelo del Nivel 2 y del estado de congelación/descongelación. Los productos del Nivel 4 proporcionan un modelo derivado de la humedad del suelo de la zona de las raíces y el intercambio de carbono neto del ecosistema.

Algunos de los datos que se obtienen del Satelite SMAP se listan a continuación

Productos SMAP

Productos SMAP

3.Autenticación en NSIDC

Para poder acceder los datos de la NASA a traves del NSDIC , se deben autenticar el nombre de usuario y la contraseña de Erathdata en el espacio de trabajo de RStudio

La forma más recomendada para la autenticación es usar Usar set_smap_credentials(‘nombre de usuario’, ‘contraseña’), una vez que se tenga instalada y cargada la libreria smapr.

4. Instalar y cargar paquetes

La isntalación y carga de paquetes se realizaron en la consola,los paquetes que fueron instalados fueron : Isoband (Desde el repositorio Git Hub),rhdf5 y smapr . Siendo esta última la libreria que permitirá obtener, descargar y extraer datos de nuestro interés

Autenticación

Como ya se habia mencionado , Se autenticará el acceso mediante el código que se mencionó en el numeral 3 , a traves de un usuario y contraseña de Earthdata . Se usa {r , include=FALSE} para que no se muestre este codigo en la salida

5. Encontrar datos SMAP

La función find_smap , devuelve los datos que estén disponibles según un criterio de búsqueda , que cosniste en la identificación del producto,la fecha y la versión a la que este pertenece , en este caso se buscarán los datos del Análisis global de la humedad en superficie y zona de raices

available_data <- find_smap(id = "SPL4SMAU", date = "2020-04-10", version = 4)
str(available_data)
'data.frame':   8 obs. of  3 variables:
 $ name: chr  "SMAP_L4_SM_aup_20200410T030000_Vv4030_001" "SMAP_L4_SM_aup_20200410T060000_Vv4030_001" "SMAP_L4_SM_aup_20200410T090000_Vv4030_001" "SMAP_L4_SM_aup_20200410T120000_Vv4030_001" ...
 $ date: Date, format: "2020-04-10" "2020-04-10" "2020-04-10" ...
 $ dir : chr  "SPL4SMAU.004/2020.04.10/" "SPL4SMAU.004/2020.04.10/" "SPL4SMAU.004/2020.04.10/" "SPL4SMAU.004/2020.04.10/" ...

6. Descargar Datos

En esta ocasión se descargara el producto mejorado de humedad del suelo de nivel 3 (L3) recuperadas por el radiómetro SMAP. Primero , se usará la función find_smap que se mencionó en el numeral anteriror

Archivos <- find_smap(id = "SPL3SMP_E", dates = "2020-04-28", version = 3)
Archivos

Luego, se descargan en la carpeta “suelo” que se crea en el directorio de trabajo

local_dir <- "./suelo"
downloads <- download_smap(Archivos[1, ], local_dir)
Downloading https://n5eil01u.ecs.nsidc.org/SMAP/SPL3SMP_E.003/2020.04.28/SMAP_L3_SM_P_E_20200428_R16515_001.h5
Downloading https://n5eil01u.ecs.nsidc.org/SMAP/SPL3SMP_E.003/2020.04.28/SMAP_L3_SM_P_E_20200428_R16515_001.qa
Downloading https://n5eil01u.ecs.nsidc.org/SMAP/SPL3SMP_E.003/2020.04.28/SMAP_L3_SM_P_E_20200428_R16515_001.h5.iso.xml

Se puede ver el contenido del objeto “downloads”

downloads

con la fución list_smap se puede ver el contenido (Formato HDF5) y los metadatos de lo que se descargó en el paso anterior

list_smap(downloads, all = TRUE)
$SMAP_L3_SM_P_E_20200428_R16515_001
NA

7. Visualiación de los Datos

Luego , podemos plotear la humedad del suelo de acuerdo al recorrido y los datos que recogió el satelite que se encuentra en el archivo descargado como “soil_mosture”

sm_raster1 <- extract_smap(downloads, "/Soil_Moisture_Retrieval_Data_AM/soil_moisture")
## sm_raster <- extract_smap("./soil/SMAP_L4_Antioquia/SMAP_L4_SM_lmc_00000000T000000_Vv4030_001", ## "/Geophysical_Data/sm_rootzone_wetness")
plot(sm_raster1, main = "Humedad del suelo nivel 3: 28 Marzo 2020")

Se puede realizar el mismo procedimiento pero para los datos existentes en otra hora del día

sm_raster <- extract_smap(downloads, "/Soil_Moisture_Retrieval_Data_PM/soil_moisture_pm")
## sm_raster <- extract_smap("./soil/SMAP_L4_Antioquia/SMAP_L4_SM_lmc_00000000T000000_Vv4030_001", ## "/Geophysical_Data/sm_rootzone_wetness")
plot(sm_raster, main = "Humedad del suelo nivel 3 : 28 Marzo 2020")

En los codigos anteriores , estos datos fueron almacenados en los objetos : sm_raster y sm_raster1 , se puede observar que hay en cada uno de esos objetos mediante los siguientes codigos:

sm_raster
class      : RasterLayer 
dimensions : 1624, 3856, 6262144  (nrow, ncol, ncell)
resolution : 9008.055, 9008.054  (x, y)
extent     : -17367530, 17367530, -7314540, 7314540  (xmin, xmax, ymin, ymax)
crs        : +proj=cea +lon_0=0 +lat_ts=30 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs +ellps=WGS84 +towgs84=0,0,0 
source     : /home/rstudio-user/.cache/smap/tmp.tif 
names      : SMAP_L3_SM_P_E_20200428_R16515_001 
values     : 0.01999992, 0.882247  (min, max)
sm_raster1
class      : RasterLayer 
dimensions : 1624, 3856, 6262144  (nrow, ncol, ncell)
resolution : 9008.055, 9008.054  (x, y)
extent     : -17367530, 17367530, -7314540, 7314540  (xmin, xmax, ymin, ymax)
crs        : +proj=cea +lon_0=0 +lat_ts=30 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs +ellps=WGS84 +towgs84=0,0,0 
source     : /home/rstudio-user/.cache/smap/tmp.tif 
names      : SMAP_L3_SM_P_E_20200428_R16515_001 
values     : 0.01999992, 0.8830189  (min, max)

Además , se puede indagar sobre el sistema de coordenadas de referencia de cada uno de los objetos

crs(sm_raster)
CRS arguments:
 +proj=cea +lon_0=0 +lat_ts=30 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs
+ellps=WGS84 +towgs84=0,0,0 

Posterior a esa operación, se lee el archivo shapefile correspondiente al departamento de vichada

Vichada <- read_sf("./ADMINISTRATIVO/MGN_DPTO_POLITICO.shp")
Vichada
Simple feature collection with 1 feature and 7 fields
geometry type:  POLYGON
dimension:      XY
bbox:           xmin: -71.07793 ymin: 2.737109 xmax: -67.4098 ymax: 6.324317
CRS:            4326

¿Cuál es la extensión de los datos vectoriales?

extent(Vichada)
class      : Extent 
xmin       : -71.07793 
xmax       : -67.4098 
ymin       : 2.737109 
ymax       : 6.324317 

Los datos vectoriales están referidos a coordenadas geograficas , por tanto se deben reproyectar para que coincida con el sistema de referencia de los datos raster

cea_Vichada <- st_transform(Vichada, crs = crs(sm_raster))
cea_Vichada1 <- st_transform(Vichada, crs = crs(sm_raster1))

Se comprueba que ahora este objeto tiene el mismo sistema de referencia de los datos raster

crs(cea_Vichada)
[1] "+proj=cea +lon_0=0 +lat_ts=30 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs "
crs(cea_Vichada1)
[1] "+proj=cea +lon_0=0 +lat_ts=30 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs "

8.Recorte y Visualización de datos para el Área de estudio

Se hace uso de la función crop para que los datos raster de las diferentes horas del dia tengan la misma extensión del archivo shapefile

smap.sub <- crop(sm_raster, extent(cea_Vichada))
smap.sub1 <- crop(sm_raster1, extent(cea_Vichada1))

Se comprueba que los archivos tengan la extensión que se definió en el código anterior

smap.sub
class      : RasterLayer 
dimensions : 50, 39, 1950  (nrow, ncol, ncell)
resolution : 9008.055, 9008.054  (x, y)
extent     : -6855130, -6503816, 351314.1, 801716.8  (xmin, xmax, ymin, ymax)
crs        : +proj=cea +lon_0=0 +lat_ts=30 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs +ellps=WGS84 +towgs84=0,0,0 
source     : memory
names      : SMAP_L3_SM_P_E_20200428_R16515_001 
values     : 0.08976348, 0.5132492  (min, max)
smap.sub1
class      : RasterLayer 
dimensions : 50, 39, 1950  (nrow, ncol, ncell)
resolution : 9008.055, 9008.054  (x, y)
extent     : -6855130, -6503816, 351314.1, 801716.8  (xmin, xmax, ymin, ymax)
crs        : +proj=cea +lon_0=0 +lat_ts=30 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs +ellps=WGS84 +towgs84=0,0,0 
source     : memory
names      : SMAP_L3_SM_P_E_20200428_R16515_001 
values     : 0.08976348, 0.5132492  (min, max)

Se crea la función para convertir los valores en porcentajes,multiplicandolos x100

normalize <- function(x) {
  return(round(100*x))
}

Se aplica la función a los valores obtenidos

nuevo_smap = normalize(smap.sub)
nuevo_smap1 = normalize(smap.sub1)  

Se observa el contenido de los objetos

nuevo_smap
class      : RasterLayer 
dimensions : 50, 39, 1950  (nrow, ncol, ncell)
resolution : 9008.055, 9008.054  (x, y)
extent     : -6855130, -6503816, 351314.1, 801716.8  (xmin, xmax, ymin, ymax)
crs        : +proj=cea +lon_0=0 +lat_ts=30 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs +ellps=WGS84 +towgs84=0,0,0 
source     : memory
names      : layer 
values     : 9, 51  (min, max)
nuevo_smap1
class      : RasterLayer 
dimensions : 50, 39, 1950  (nrow, ncol, ncell)
resolution : 9008.055, 9008.054  (x, y)
extent     : -6855130, -6503816, 351314.1, 801716.8  (xmin, xmax, ymin, ymax)
crs        : +proj=cea +lon_0=0 +lat_ts=30 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs +ellps=WGS84 +towgs84=0,0,0 
source     : memory
names      : layer 
values     : 9, 51  (min, max)

Se crea un nuevo raster con la función “mask”

nuevo_smap2 <- mask(x = nuevo_smap, mask = cea_Vichada)
nuevo_smap1_2 <- mask(x = nuevo_smap1, mask = cea_Vichada1)

Se visualizan los datos con ayuda de la libreria leaflet, además se crea una nueva paleta de acuerdo a los valores que tome la humedad del suelo en el objeto “nuevo_smap2”

pal <- colorNumeric(c( "#FFFFCC", "#41B6C4","#0C2C84"), values(nuevo_smap2), na.color = "transparent")

leaflet() %>% addTiles() %>% addRasterImage(nuevo_smap2, colors = pal, opacity = 0.8) %>%
addLegend(pal = pal, values = values(nuevo_smap2), title = "Humedad del suelo en Vichada, 28 Marzo 2020 [%]")

Finalmente , se guardan los datos raster para ser usados en tareas posteriores

sm <- writeRaster(nuevo_smap2, filename="./suelo/sm_Vichada1_28_04_2020.tif", format="GTiff", datatype='INT1U', overwrite=TRUE)

Se guardan los datos para humedad del suelo

sm <- writeRaster(nuevo_smap1_2, filename="./suelo/sm_Vichada2_28_04_2020.tif", format="GTiff", datatype='INT1U', overwrite=TRUE)
LS0tCnRpdGxlOiAiRGF0b3MgZGUgaHVtZWRhZCBkZWwgc3VlbG8gZW4gVmljaGFkYSIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKCiMjIyAxLiBJbnRyb2R1Y2Npw7NuCgpFc3RlIGN1YWRlcm5vLCBoYSBzaWRvIGNyZWFkbyBkZXNkZSBSU3R1ZGlvIENsb3VkIGUgaWx1c3RyYSBsYXMgZnVuY2lvbmFsaWRhZGVzIGRlIGxhIGJpYmxpb3RlY2EgU21hcHIgLCBlbiBwYXJ0aWN1bGFyIGVuIGVzdGUgY3VhZGVybm8gc2UgYWRxdWllcmVuIHkgc2UgcHJvY2VzYW4gbG9zIGRhdG9zIGRlIGh1bWVkYWQgZGVsIHN1ZWxvIDogIFNNQVAgIChTb2lsIE1vaXN0dXJlIEFjdGl2ZS1QYXNzaXZlKSBkZSBsYSBOQVNBLiAgQWRlbcOhcywgc2UgcmVjb3J0YW4gbG9zIGRhdG9zIHBhcmEgcXVlIGNvaW5jaWRhbiBjb24gZWwgw6FyZWEgZGUgZXN0dWRpbyB5IHNlIGdlbmVyYW4gdmlzdWFsaXphY2lvbmVzIHNpbXBsZXMgZGUgbGEgaHVtZWRhZCBkZWwgc3VlbG8gZW4gZWwgZGVwYXJ0YW1lbnRvIGRlbCBWaWNoYWRhCgojIyMgMi4gRGF0b3MgU01BUAoKTGEgbWlzacOzbiBTTUFQICwgbWlkZSBsYSBjYW50aWRhZCBkZSBhZ3VhIGVuIGxhIHN1cGVyZmljaWUgZGVsIHN1ZWxvIGVuIHRvZGFzIHBhcnRlcyBkZSBsYSBUaWVycmFlIC5FcyBkZWNpciwgZXN0w6EgZGlzZcOxYWRvIHBhcmEgbWVkaXIgbGEgaHVtZWRhZCBkZWwgc3VlbG8sIGNhZGEgMi0zIGTDrWFzCgpBbGd1bm9zIGRhdG9zIGRlIGVzdGEgbWlzacOzbiBTTUFQICwgc29uIHByb3BvcmNpb25hZG9zIHBvciBlbCBjZW50cm8gbmFjaW9uYWwgZGUgZGF0b3MgZGUgbmlldmUgeSBoaWVsbyAoTlNJREMpIC4gRW4gbGEgcMOhZ2luYSBkZWwgIFtOU0lEQ10oaHR0cHM6Ly9uc2lkYy5vcmcvZGF0YS9zbWFwL3NtYXAtZGF0YS5odG1sKSBzZSBkZXNjcmliZW4gIGRpZmVyZW50ZXMgbml2ZWxlcyBkZSBkYXRvcyAsIHByaW5jaXBhbG1lbnRlIHNlIGVuY3VlbnRyYW4gZGF0b3MgZGUgbml2ZWwgMyBxdWUgc29uIHByb2R1Y3RvcyBjb21wdWVzdG9zIGdsb2JhbGVzIHkgZGF0b3Mgbml2ZWwgNCBwcm9kdWN0b3MgZGUgZGF0b3MgZ2xvYmFsZXMgbW9kZWxhZG9zIGNhZGEgdHJlcyBob3JhcwoKUG9yIG90cm8gbGFkbyxkZXNjcmliZW4gbG9zIHByb2R1Y3RvcyBkZSBuaXZlbCAxIGNvbW8gbWVkaWNpb25lcyBkZSBpbnN0cnVtZW50b3MgYnJ1dG9zIG8gY2FsaWJyYWRvcyB5IGdlb2xvY2FsaXphZG9zIGRlbCByYWRhciB5IGVsIHJhZGlvbWV0cm8gU01BUCwgbWllbnRyYXMgcXVlIGxvcyBkYXRvcyBkZSBOaXZlbCAyICwgY29udGllbmVuIHJlY3VwZXJhY2lvbmVzIGRlbCBzdWVsbyBkZXJpdmFkYXMgZGUgYXJjaGl2b3MgYXV4aWxpYXJlcyAgeSBsb3MgZGF0b3MgZGVsIG5pdmVsIDEgLkVzdG9zIDIgbmlldmVsZXMgZGUgZGF0b3MgdGllbmVuIHVuYSByZXNvbHVjacOzbiB0ZW1wb3JhbCBkZSA0OSBtaW51dG9zICwgcXVlIGVzIGVsIHRpZW1wbyAgcXVlIHRhcmRhIGVsIHNhdMOpbGl0ZSBlbiBjb21wbGV0YXIgbWVkaWEgw7NyYml0YSBkZSBsYSB0aWVycmEKCkxvcyBwcm9kdWN0b3MgZGVsIE5pdmVsIDMgc29uIGNvbXB1ZXN0b3MgZGlhcmlvcyBkZSBsb3MgZGF0b3MgZGUgaHVtZWRhZCBkZWwgc3VlbG8gZGVsIE5pdmVsIDIgeSBkZWwgZXN0YWRvIGRlIGNvbmdlbGFjacOzbi9kZXNjb25nZWxhY2nDs24uIExvcyBwcm9kdWN0b3MgZGVsIE5pdmVsIDQgcHJvcG9yY2lvbmFuIHVuIG1vZGVsbyBkZXJpdmFkbyBkZSBsYSBodW1lZGFkIGRlbCBzdWVsbyBkZSBsYSB6b25hIGRlIGxhcyByYcOtY2VzIHkgZWwgaW50ZXJjYW1iaW8gZGUgY2FyYm9ubyBuZXRvIGRlbCBlY29zaXN0ZW1hLgoKQWxndW5vcyBkZSBsb3MgZGF0b3MgcXVlIHNlIG9idGllbmVuIGRlbCBTYXRlbGl0ZSBTTUFQIHNlIGxpc3RhbiBhIGNvbnRpbnVhY2nDs24KCgoKIVtQcm9kdWN0b3MgU01BUF0oLi9kYXRvU01BUC5wbmcpCgojIyMgMy5BdXRlbnRpY2FjacOzbiBlbiBOU0lEQwoKClBhcmEgcG9kZXIgYWNjZWRlciBsb3MgZGF0b3MgZGUgbGEgTkFTQSBhIHRyYXZlcyBkZWwgTlNESUMgLCBzZSBkZWJlbiBhdXRlbnRpY2FyIGVsIG5vbWJyZSBkZSB1c3VhcmlvIHkgbGEgY29udHJhc2XDsWEgZGUgRXJhdGhkYXRhIGVuIGVsIGVzcGFjaW8gZGUgdHJhYmFqbyBkZSBSU3R1ZGlvCgoKTGEgZm9ybWEgbcOhcyByZWNvbWVuZGFkYSBwYXJhIGxhIGF1dGVudGljYWNpw7NuIGVzIHVzYXIgClVzYXIgc2V0X3NtYXBfY3JlZGVudGlhbHMoJ25vbWJyZSBkZSB1c3VhcmlvJywgJ2NvbnRyYXNlw7FhJyksIHVuYSB2ZXogcXVlIHNlIHRlbmdhIGluc3RhbGFkYSB5IGNhcmdhZGEgbGEgbGlicmVyaWEgc21hcHIuCgoKIyMjIDQuIEluc3RhbGFyIHkgY2FyZ2FyIHBhcXVldGVzCgpMYSBpc250YWxhY2nDs24geSBjYXJnYSBkZSBwYXF1ZXRlcyBzZSByZWFsaXphcm9uIGVuIGxhIGNvbnNvbGEsbG9zIHBhcXVldGVzIHF1ZSBmdWVyb24gaW5zdGFsYWRvcyBmdWVyb24gOiBJc29iYW5kIChEZXNkZSBlbCByZXBvc2l0b3JpbyBHaXQgSHViKSxyaGRmNSB5IHNtYXByIC4gU2llbmRvIGVzdGEgw7psdGltYSBsYSBsaWJyZXJpYSBxdWUgcGVybWl0aXLDoSBvYnRlbmVyLCBkZXNjYXJnYXIgeSBleHRyYWVyIGRhdG9zIGRlIG51ZXN0cm8gaW50ZXLDqXMKCgojIyMjIyBBdXRlbnRpY2FjacOzbgoKQ29tbyB5YSBzZSBoYWJpYSBtZW5jaW9uYWRvICwgU2UgYXV0ZW50aWNhcsOhIGVsIGFjY2VzbyBtZWRpYW50ZSBlbCBjw7NkaWdvIHF1ZSBzZSBtZW5jaW9uw7MgZW4gZWwgbnVtZXJhbCAzICwgYSB0cmF2ZXMgZGUgIHVuIHVzdWFyaW8geSBjb250cmFzZcOxYSBkZSBFYXJ0aGRhdGEgLiAgU2UgdXNhICp7ciAsIGluY2x1ZGU9RkFMU0V9KiBwYXJhIHF1ZSBubyBzZSBtdWVzdHJlIGVzdGUgY29kaWdvIGVuIGxhIHNhbGlkYSAKCmBgYHtyIGNyZWRlbmNpYWwsIGluY2x1ZGU9RkFMU0V9CnNldF9zbWFwX2NyZWRlbnRpYWxzKCJBanV5byIsICJBbmdpZTM5NTQyMjY4Iiwgb3ZlcndyaXRlPVRSVUUpCmBgYAoKCmBgYHtyLCBpbmNsdWRlPUZBTFNFfQpsaWJyYXJ5KGh0dHIpCnNldF9jb25maWcoY29uZmlnKHNzbF92ZXJpZnlwZWVyID0gMEwpKQpgYGAKCgojIyMgNS4gRW5jb250cmFyIGRhdG9zIFNNQVAgCgpMYSBmdW5jacOzbiBmaW5kX3NtYXAgLCBkZXZ1ZWx2ZSBsb3MgZGF0b3MgcXVlIGVzdMOpbiBkaXNwb25pYmxlcyBzZWfDum4gdW4gY3JpdGVyaW8gZGUgYsO6c3F1ZWRhICwgcXVlIGNvc25pc3RlIGVuIGxhIGlkZW50aWZpY2FjacOzbiBkZWwgcHJvZHVjdG8sbGEgZmVjaGEgeSBsYSB2ZXJzacOzbiBhIGxhIHF1ZSBlc3RlIHBlcnRlbmVjZSAsIGVuIGVzdGUgY2FzbyBzZSBidXNjYXLDoW4gbG9zIGRhdG9zIGRlbCBBbsOhbGlzaXMgZ2xvYmFsIGRlIGxhIGh1bWVkYWQgZW4gc3VwZXJmaWNpZSB5IHpvbmEgZGUgcmFpY2VzCgoKYGBge3J9CmF2YWlsYWJsZV9kYXRhIDwtIGZpbmRfc21hcChpZCA9ICJTUEw0U01BVSIsIGRhdGUgPSAiMjAyMC0wNC0xMCIsIHZlcnNpb24gPSA0KQpzdHIoYXZhaWxhYmxlX2RhdGEpCmBgYAoKIyMjIDYuIERlc2NhcmdhciBEYXRvcwoKRW4gZXN0YSBvY2FzacOzbiBzZSBkZXNjYXJnYXJhIGVsIHByb2R1Y3RvIG1lam9yYWRvIGRlIGh1bWVkYWQgZGVsIHN1ZWxvIGRlIG5pdmVsIDMgKEwzKSByZWN1cGVyYWRhcyBwb3IgZWwgcmFkacOzbWV0cm8gU01BUC4gUHJpbWVybyAsICBzZSB1c2Fyw6EgbGEgZnVuY2nDs24gZmluZF9zbWFwIHF1ZSBzZSBtZW5jaW9uw7MgZW4gZWwgbnVtZXJhbCBhbnRlcmlyb3IKCmBgYHtyfQpBcmNoaXZvcyA8LSBmaW5kX3NtYXAoaWQgPSAiU1BMM1NNUF9FIiwgZGF0ZXMgPSAiMjAyMC0wNC0yOCIsIHZlcnNpb24gPSAzKQpgYGAKCmBgYHtyfQpBcmNoaXZvcwpgYGAKTHVlZ28sIHNlIGRlc2NhcmdhbiBlbiAgbGEgY2FycGV0YSAic3VlbG8iIHF1ZSBzZSBjcmVhIGVuIGVsIGRpcmVjdG9yaW8gZGUgdHJhYmFqbyAKYGBge3J9CmxvY2FsX2RpciA8LSAiLi9zdWVsbyIKZG93bmxvYWRzIDwtIGRvd25sb2FkX3NtYXAoQXJjaGl2b3NbMSwgXSwgbG9jYWxfZGlyKQpgYGAKClNlIHB1ZWRlIHZlciBlbCBjb250ZW5pZG8gZGVsIG9iamV0byAiZG93bmxvYWRzIgoKYGBge3J9CmRvd25sb2FkcwpgYGAKY29uIGxhIGZ1Y2nDs24gbGlzdF9zbWFwIHNlIHB1ZWRlIHZlciBlbCBjb250ZW5pZG8gKEZvcm1hdG8gSERGNSkgeSBsb3MgbWV0YWRhdG9zIGRlIGxvIHF1ZSBzZSBkZXNjYXJnw7MgZW4gZWwgcGFzbyBhbnRlcmlvcgpgYGB7cn0KbGlzdF9zbWFwKGRvd25sb2FkcywgYWxsID0gVFJVRSkKYGBgCgojIyMgNy4gVmlzdWFsaWFjacOzbiBkZSBsb3MgRGF0b3MKCkx1ZWdvICwgcG9kZW1vcyBwbG90ZWFyIGxhIGh1bWVkYWQgZGVsIHN1ZWxvIGRlIGFjdWVyZG8gYWwgcmVjb3JyaWRvIHkgbG9zIGRhdG9zIHF1ZSByZWNvZ2nDsyBlbCBzYXRlbGl0ZSBxdWUgc2UgZW5jdWVudHJhIGVuIGVsIGFyY2hpdm8gZGVzY2FyZ2FkbyBjb21vICJzb2lsX21vc3R1cmUiCmBgYHtyfQpzbV9yYXN0ZXIxIDwtIGV4dHJhY3Rfc21hcChkb3dubG9hZHMsICIvU29pbF9Nb2lzdHVyZV9SZXRyaWV2YWxfRGF0YV9BTS9zb2lsX21vaXN0dXJlIikKIyMgc21fcmFzdGVyIDwtIGV4dHJhY3Rfc21hcCgiLi9zb2lsL1NNQVBfTDRfQW50aW9xdWlhL1NNQVBfTDRfU01fbG1jXzAwMDAwMDAwVDAwMDAwMF9WdjQwMzBfMDAxIiwgIyMgIi9HZW9waHlzaWNhbF9EYXRhL3NtX3Jvb3R6b25lX3dldG5lc3MiKQpwbG90KHNtX3Jhc3RlcjEsIG1haW4gPSAiSHVtZWRhZCBkZWwgc3VlbG8gbml2ZWwgMzogMjggTWFyem8gMjAyMCIpCmBgYApTZSBwdWVkZSByZWFsaXphciBlbCBtaXNtbyBwcm9jZWRpbWllbnRvIHBlcm8gcGFyYSBsb3MgZGF0b3MgZXhpc3RlbnRlcyBlbiBvdHJhIGhvcmEgZGVsIGTDrWEKCmBgYHtyfQpzbV9yYXN0ZXIgPC0gZXh0cmFjdF9zbWFwKGRvd25sb2FkcywgIi9Tb2lsX01vaXN0dXJlX1JldHJpZXZhbF9EYXRhX1BNL3NvaWxfbW9pc3R1cmVfcG0iKQojIyBzbV9yYXN0ZXIgPC0gZXh0cmFjdF9zbWFwKCIuL3NvaWwvU01BUF9MNF9BbnRpb3F1aWEvU01BUF9MNF9TTV9sbWNfMDAwMDAwMDBUMDAwMDAwX1Z2NDAzMF8wMDEiLCAjIyAiL0dlb3BoeXNpY2FsX0RhdGEvc21fcm9vdHpvbmVfd2V0bmVzcyIpCnBsb3Qoc21fcmFzdGVyLCBtYWluID0gIkh1bWVkYWQgZGVsIHN1ZWxvIG5pdmVsIDMgOiAyOCBNYXJ6byAyMDIwIikKYGBgCkVuIGxvcyBjb2RpZ29zIGFudGVyaW9yZXMgLCBlc3RvcyBkYXRvcyBmdWVyb24gYWxtYWNlbmFkb3MgZW4gbG9zIG9iamV0b3MgOiAqc21fcmFzdGVyKiB5ICpzbV9yYXN0ZXIxKiAsIHNlIHB1ZWRlIG9ic2VydmFyIHF1ZSBoYXkgZW4gY2FkYSB1bm8gZGUgZXNvcyBvYmpldG9zIG1lZGlhbnRlIGxvcyBzaWd1aWVudGVzIGNvZGlnb3M6CmBgYHtyfQpzbV9yYXN0ZXIKYGBgCmBgYHtyfQpzbV9yYXN0ZXIxCmBgYApBZGVtw6FzICwgc2UgcHVlZGUgaW5kYWdhciBzb2JyZSBlbCBzaXN0ZW1hIGRlIGNvb3JkZW5hZGFzIGRlIHJlZmVyZW5jaWEgZGUgY2FkYSB1bm8gZGUgbG9zIG9iamV0b3MKYGBge3J9CmNycyhzbV9yYXN0ZXIpCmBgYApQb3N0ZXJpb3IgYSBlc2Egb3BlcmFjacOzbiwgc2UgbGVlIGVsIGFyY2hpdm8gc2hhcGVmaWxlIGNvcnJlc3BvbmRpZW50ZSBhbCBkZXBhcnRhbWVudG8gZGUgdmljaGFkYQpgYGB7cn0KVmljaGFkYSA8LSByZWFkX3NmKCIuL0FETUlOSVNUUkFUSVZPL01HTl9EUFRPX1BPTElUSUNPLnNocCIpClZpY2hhZGEKYGBgCsK/Q3XDoWwgZXMgbGEgZXh0ZW5zacOzbiBkZSBsb3MgZGF0b3MgdmVjdG9yaWFsZXM/CmBgYHtyfQpleHRlbnQoVmljaGFkYSkKYGBgCkxvcyBkYXRvcyB2ZWN0b3JpYWxlcyBlc3TDoW4gcmVmZXJpZG9zIGEgY29vcmRlbmFkYXMgZ2VvZ3JhZmljYXMgLCBwb3IgdGFudG8gc2UgZGViZW4gcmVwcm95ZWN0YXIgcGFyYSBxdWUgY29pbmNpZGEgY29uIGVsIHNpc3RlbWEgZGUgcmVmZXJlbmNpYSBkZSBsb3MgZGF0b3MgcmFzdGVyCmBgYHtyfQpjZWFfVmljaGFkYSA8LSBzdF90cmFuc2Zvcm0oVmljaGFkYSwgY3JzID0gY3JzKHNtX3Jhc3RlcikpCmNlYV9WaWNoYWRhMSA8LSBzdF90cmFuc2Zvcm0oVmljaGFkYSwgY3JzID0gY3JzKHNtX3Jhc3RlcjEpKQpgYGAKU2UgY29tcHJ1ZWJhIHF1ZSBhaG9yYSBlc3RlIG9iamV0byB0aWVuZSBlbCBtaXNtbyBzaXN0ZW1hIGRlIHJlZmVyZW5jaWEgZGUgbG9zIGRhdG9zIHJhc3RlcgpgYGB7cn0KY3JzKGNlYV9WaWNoYWRhKQpgYGAKYGBge3J9CmNycyhjZWFfVmljaGFkYTEpCmBgYAojIyMgOC5SZWNvcnRlIHkgVmlzdWFsaXphY2nDs24gZGUgZGF0b3MgcGFyYSBlbCDDgXJlYSBkZSBlc3R1ZGlvIApTZSBoYWNlIHVzbyBkZSBsYSBmdW5jacOzbiBjcm9wIHBhcmEgcXVlIGxvcyBkYXRvcyByYXN0ZXIgZGUgbGFzIGRpZmVyZW50ZXMgaG9yYXMgZGVsIGRpYSB0ZW5nYW4gbGEgbWlzbWEgZXh0ZW5zacOzbiBkZWwgYXJjaGl2byBzaGFwZWZpbGUKCmBgYHtyfQpzbWFwLnN1YiA8LSBjcm9wKHNtX3Jhc3RlciwgZXh0ZW50KGNlYV9WaWNoYWRhKSkKc21hcC5zdWIxIDwtIGNyb3Aoc21fcmFzdGVyMSwgZXh0ZW50KGNlYV9WaWNoYWRhMSkpCmBgYApTZSBjb21wcnVlYmEgcXVlIGxvcyBhcmNoaXZvcyB0ZW5nYW4gbGEgZXh0ZW5zacOzbiBxdWUgc2UgZGVmaW5pw7MgZW4gZWwgY8OzZGlnbyBhbnRlcmlvcgpgYGB7cn0Kc21hcC5zdWIKYGBgCmBgYHtyfQpzbWFwLnN1YjEKYGBgClNlIGNyZWEgbGEgZnVuY2nDs24gcGFyYSBjb252ZXJ0aXIgbG9zIHZhbG9yZXMgZW4gcG9yY2VudGFqZXMsbXVsdGlwbGljYW5kb2xvcyB4MTAwCmBgYHtyfQpub3JtYWxpemUgPC0gZnVuY3Rpb24oeCkgewogIHJldHVybihyb3VuZCgxMDAqeCkpCn0KYGBgClNlICBhcGxpY2EgbGEgZnVuY2nDs24gYSBsb3MgdmFsb3JlcyBvYnRlbmlkb3MKYGBge3J9Cm51ZXZvX3NtYXAgPSBub3JtYWxpemUoc21hcC5zdWIpCm51ZXZvX3NtYXAxID0gbm9ybWFsaXplKHNtYXAuc3ViMSkgIApgYGAKU2Ugb2JzZXJ2YSBlbCBjb250ZW5pZG8gZGUgbG9zIG9iamV0b3MKYGBge3J9Cm51ZXZvX3NtYXAKYGBgCmBgYHtyfQpudWV2b19zbWFwMQpgYGAKU2UgY3JlYSB1biBudWV2byByYXN0ZXIgY29uIGxhIGZ1bmNpw7NuICJtYXNrIgpgYGB7cn0KbnVldm9fc21hcDIgPC0gbWFzayh4ID0gbnVldm9fc21hcCwgbWFzayA9IGNlYV9WaWNoYWRhKQpudWV2b19zbWFwMV8yIDwtIG1hc2soeCA9IG51ZXZvX3NtYXAxLCBtYXNrID0gY2VhX1ZpY2hhZGExKQpgYGAKU2UgdmlzdWFsaXphbiBsb3MgZGF0b3MgY29uIGF5dWRhIGRlIGxhIGxpYnJlcmlhIGxlYWZsZXQsIGFkZW3DoXMgc2UgY3JlYSB1bmEgbnVldmEgcGFsZXRhIGRlIGFjdWVyZG8gYSBsb3MgdmFsb3JlcyBxdWUgdG9tZSBsYSBodW1lZGFkIGRlbCBzdWVsbyBlbiBlbCBvYmpldG8gIm51ZXZvX3NtYXAyIiAKYGBge3J9CnBhbCA8LSBjb2xvck51bWVyaWMoYyggIiNGRkZGQ0MiLCAiIzQxQjZDNCIsIiMwQzJDODQiKSwgdmFsdWVzKG51ZXZvX3NtYXAyKSwgbmEuY29sb3IgPSAidHJhbnNwYXJlbnQiKQoKbGVhZmxldCgpICU+JSBhZGRUaWxlcygpICU+JSBhZGRSYXN0ZXJJbWFnZShudWV2b19zbWFwMiwgY29sb3JzID0gcGFsLCBvcGFjaXR5ID0gMC44KSAlPiUKYWRkTGVnZW5kKHBhbCA9IHBhbCwgdmFsdWVzID0gdmFsdWVzKG51ZXZvX3NtYXAyKSwgdGl0bGUgPSAiSHVtZWRhZCBkZWwgc3VlbG8gZW4gVmljaGFkYSwgMjggTWFyem8gMjAyMCBbJV0iKQpgYGAKCgpGaW5hbG1lbnRlICwgc2UgZ3VhcmRhbiBsb3MgZGF0b3MgcmFzdGVyIHBhcmEgc2VyIHVzYWRvcyBlbiB0YXJlYXMgcG9zdGVyaW9yZXMgCgpgYGB7cn0Kc20gPC0gd3JpdGVSYXN0ZXIobnVldm9fc21hcDIsIGZpbGVuYW1lPSIuL3N1ZWxvL3NtX1ZpY2hhZGExXzI4XzA0XzIwMjAudGlmIiwgZm9ybWF0PSJHVGlmZiIsIGRhdGF0eXBlPSdJTlQxVScsIG92ZXJ3cml0ZT1UUlVFKQpgYGAKClNlIGd1YXJkYW4gbG9zIGRhdG9zIHBhcmEgaHVtZWRhZCBkZWwgc3VlbG8gCmBgYHtyfQpzbSA8LSB3cml0ZVJhc3RlcihudWV2b19zbWFwMV8yLCBmaWxlbmFtZT0iLi9zdWVsby9zbV9WaWNoYWRhMl8yOF8wNF8yMDIwLnRpZiIsIGZvcm1hdD0iR1RpZmYiLCBkYXRhdHlwZT0nSU5UMVUnLCBvdmVyd3JpdGU9VFJVRSkKYGBgCgoKCgoKCgoKCg==