Ya se tiene descargado los datos de precipitación formato tif

De los global-pentad nombre: Chirps.v.2.0 2020.03.6

Arreglo de los datos

library(rgdal)
Loading required package: sp
rgdal: version: 1.5-10, (SVN revision 1006)
Geospatial Data Abstraction Library extensions to R successfully loaded
Loaded GDAL runtime: GDAL 3.0.4, released 2020/01/28
Path to GDAL shared files: C:/Users/amor/Documents/R/win-library/4.0/rgdal/gdal
GDAL binary built with GEOS: TRUE 
Loaded PROJ runtime: Rel. 6.3.1, February 10th, 2020, [PJ_VERSION: 631]
Path to PROJ shared files: C:/Users/amor/Documents/R/win-library/4.0/rgdal/proj
Linking to sp version:1.4-2
To mute warnings of possible GDAL/OSR exportToProj4() degradation,
use options("rgdal_show_exportToProj4_warnings"="none") before loading rgdal.
library(raster)
library(sf)
Linking to GEOS 3.8.0, GDAL 3.0.4, PROJ 6.3.1
library(tidyverse)
Registered S3 methods overwritten by 'dbplyr':
  method         from
  print.tbl_lazy     
  print.tbl_sql      
-- Attaching packages --------------------------------------- tidyverse 1.3.0 --
v ggplot2 3.3.2     v purrr   0.3.4
v tibble  3.0.1     v dplyr   1.0.0
v tidyr   1.1.0     v stringr 1.4.0
v readr   1.3.1     v forcats 0.5.0
-- Conflicts ------------------------------------------ tidyverse_conflicts() --
x tidyr::extract() masks raster::extract()
x dplyr::filter()  masks stats::filter()
x dplyr::lag()     masks stats::lag()
x dplyr::select()  masks raster::select()
library(tmap)
library(gstat)
library(sp)

3. Preprocesamiento de datos CHIRPS

Lea el archivo CHIRPS sin comprimir:

precip <- raster("C:/Users/amor/Desktop/Rstudio/chirps-v2.0.2020.03.6.tif")

Como ya habrá notado, este archivo representa la lluvia acumulada en los últimos días de marzo de 2020 (es decir, la precipitación del 26 al 31 de marzo).

Verifique el contenido del objeto precip

precip
class      : RasterLayer 
dimensions : 2000, 7200, 14400000  (nrow, ncol, ncell)
resolution : 0.05, 0.05  (x, y)
extent     : -180, 180, -50, 50  (xmin, xmax, ymin, ymax)
crs        : +proj=longlat +datum=WGS84 +no_defs 
source     : C:/Users/amor/Desktop/Rstudio/chirps-v2.0.2020.03.6.tif 
names      : chirps.v2.0.2020.03.6 

Tenga en cuenta que este es un conjunto de datos con cobertura global. Su CRS es un sistema de coordenadas geográficas.

Carguemos un archivo shape que represente nuestra área de interés:

(aoi <- shapefile("C:/Users/amor/Desktop/Rstudio/MGN2017_50_META/50_META/ADMINISTRATIVO/MGN_MPIO_POLITICO.shp"))
class       : SpatialPolygonsDataFrame 
features    : 29 
extent      : -74.89921, -71.07753, 1.604238, 4.899101  (xmin, xmax, ymin, ymax)
CRS object has comment, which is lost in output
crs         : +proj=longlat +datum=WGS84 +no_defs 
variables   : 9
names       : DPTO_CCDGO, MPIO_CCDGO,   MPIO_CNMBR,                           MPIO_CRSLC,    MPIO_NAREA, MPIO_NANO, DPTO_CNMBR,    Shape_Leng,       Shape_Area 
min values  :         50,      50001,     ACACÍAS,                                 1840,  117.34108343,      2017,       META, 0.43640580036, 0.00955216818621 
max values  :         50,      50711, VISTAHERMOSA, Ordenanza 63 de Noviembre 21 de 1965, 17247.6864753,      2017,       META, 8.63318071739,    1.40216640329 

Tenga en cuenta que los sistemas de referencia de coordenadas para ambos conjuntos de datos son los mismos.

Ahora, recortemos los datos de precipitación:

# Datos de precipitación de cultivos por extensión de área de interés
precip.crop <- raster::crop(precip, extent(aoi))

Ahora, enmascarar la capa de trama:

precip.mask <- mask(x = precip.crop, mask = aoi)

Verifique la salida:

precip.mask 
class      : RasterLayer 
dimensions : 66, 76, 5016  (nrow, ncol, ncell)
resolution : 0.05, 0.05  (x, y)
extent     : -74.9, -71.1, 1.599999, 4.899999  (xmin, xmax, ymin, ymax)
crs        : +proj=longlat +datum=WGS84 +no_defs 
source     : memory
names      : chirps.v2.0.2020.03.6 
values     : 0.9892889, 34.25411  (min, max)

Luego, se plotea la capa Raster recortada:

plot(precip.mask, main= "CHIRPS precipitaciones en Meta desde 26.03. hasta 30.03 en 2020 [mm] ")
plot(aoi, add=TRUE)

Se puede hacer un mejor mapa con Leaflet usando la función addRasterImage:

library(leaflet)
library(RColorBrewer)
pal <- colorNumeric(c("red", "orange", "yellow", "blue", "darkblue"), values(precip.mask),
  na.color = "transparent")

leaflet() %>% addTiles() %>%
  addRasterImage(precip.mask, colors = pal, opacity = 0.6) %>%
  addLegend(pal = pal, values = values(precip.mask),
    title = "CHIRPS precipitaciones en Meta desde 26.03. hasta 30.03 en 2020 [mm]")
Discarded ellps WGS 84 in CRS definition: +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defsDiscarded datum WGS_1984 in CRS definitionUsing PROJ not WKT2 stringsDiscarded ellps WGS 84 in CRS definition: +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defsDiscarded datum WGS_1984 in CRS definitionDiscarded ellps WGS 84 in CRS definition: +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defsDiscarded datum WGS_1984 in CRS definitionUsing PROJ not WKT2 stringsDiscarded ellps WGS 84 in CRS definition: +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defsDiscarded datum WGS_1984 in CRS definitionDiscarded ellps WGS 84 in CRS definition: +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defsDiscarded datum WGS_1984 in CRS definitionUsing PROJ not WKT2 stringsDiscarded ellps WGS 84 in CRS definition: +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defsDiscarded datum WGS_1984 in CRS definitionUsing PROJ not WKT2 stringsDiscarded ellps WGS 84 in CRS definition: +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defsDiscarded datum WGS_1984 in CRS definitionDiscarded ellps WGS 84 in CRS definition: +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defsDiscarded datum WGS_1984 in CRS definitionUsing PROJ not WKT2 strings

La conversión de ráster en puntos se puede realizar utilizando la función rasterToPoints de la biblioteca ráster:

precip.points <- rasterToPoints(precip.mask, spatial = TRUE)
precip.points
class       : SpatialPointsDataFrame 
features    : 2765 
extent      : -74.875, -71.125, 1.624999, 4.824999  (xmin, xmax, ymin, ymax)
CRS object has comment, which is lost in output
crs         : +proj=longlat +datum=WGS84 +no_defs 
variables   : 1
names       : chirps.v2.0.2020.03.6 
min values  :     0.989288926124573 
max values  :      34.2541122436523 
names(precip.points) <- "Lluvia"
precip.points
class       : SpatialPointsDataFrame 
features    : 2765 
extent      : -74.875, -71.125, 1.624999, 4.824999  (xmin, xmax, ymin, ymax)
CRS object has comment, which is lost in output
crs         : +proj=longlat +datum=WGS84 +no_defs 
variables   : 1
names       :            Lluvia 
min values  : 0.989288926124573 
max values  :  34.2541122436523 
str(precip.points)
Formal class 'SpatialPointsDataFrame' [package "sp"] with 5 slots
  ..@ data       :'data.frame': 2765 obs. of  1 variable:
  .. ..$ Lluvia: num [1:2765] 8 7.8 6.26 7.17 8.09 ...
  ..@ coords.nrs : num(0) 
  ..@ coords     : num [1:2765, 1:2] -71.2 -71.1 -71.3 -71.2 -71.2 ...
  .. ..- attr(*, "dimnames")=List of 2
  .. .. ..$ : NULL
  .. .. ..$ : chr [1:2] "x" "y"
  ..@ bbox       : num [1:2, 1:2] -74.87 1.62 -71.12 4.82
  .. ..- attr(*, "dimnames")=List of 2
  .. .. ..$ : chr [1:2] "x" "y"
  .. .. ..$ : chr [1:2] "min" "max"
  ..@ proj4string:Formal class 'CRS' [package "sp"] with 1 slot
  .. .. ..@ projargs: chr "+proj=longlat +datum=WGS84 +no_defs"

Tracemos los puntos:

plot(precip.mask, main= "CHIRPS precipitaciones en Meta desde 26.03. hasta 30.03 en 2020 [mm]")
plot(aoi, add=TRUE)
points(precip.points$x, precip.points$y, col = "red", cex = .4)

Escribamos los objetos espaciales de puntos en un archivo de disco. Solo para ahorrar tiempo y trabajo en caso de que algo salga mal.

geojsonio::geojson_write(precip.points, file = "C:/Users/amor/Desktop/Rstudio/ppoints.geojson")
Success! File is at C:/Users/amor/Desktop/Rstudio/ppoints.geojson
<geojson-file>
  Path:       C:/Users/amor/Desktop/Rstudio/ppoints.geojson
  From class: SpatialPointsDataFrame

Leamos los puntos de precipitación. Consulte la documentación de geojsonio para comprender qué parámetros deben pasarse a la función geojson_read.

precip.points <- geojsonio::geojson_read("C:/Users/amor/Desktop/Rstudio/ppoints.geojson", what="sp")

Verifiquemos cuál es el objeto de puntos precip.:

precip.points
class       : SpatialPointsDataFrame 
features    : 2765 
extent      : -74.875, -71.125, 1.624999, 4.824999  (xmin, xmax, ymin, ymax)
CRS object has comment, which is lost in output
crs         : +proj=longlat +datum=WGS84 +no_defs 
variables   : 1
names       :            Lluvia 
min values  : 0.989288926124573 
max values  :  34.2541122436523 

¿Cuál es el punto de convertir los datos de precipitación ráster en datos de precipitación puntual?

Bueno, hay pocas estaciones meteorológicas de la Organización Meteorológica Mundial (OMM) en nuestro país:

Por lo tanto, CHIRPS puede ser una opción para obtener los datos de precipitación puntuales necesarios para obtener una superficie de precipitación continua.

Preparación adicional

En caso de que se pierda la conexión, podemos leer nuevamente el archivo de forma con el área de interés:

(aoi <- shapefile("C:/Users/amor/Desktop/Rstudio/MGN2017_50_META/50_META/ADMINISTRATIVO/MGN_MPIO_POLITICO.shp"))
class       : SpatialPolygonsDataFrame 
features    : 29 
extent      : -74.89921, -71.07753, 1.604238, 4.899101  (xmin, xmax, ymin, ymax)
CRS object has comment, which is lost in output
crs         : +proj=longlat +datum=WGS84 +no_defs 
variables   : 9
names       : DPTO_CCDGO, MPIO_CCDGO,   MPIO_CNMBR,                           MPIO_CRSLC,    MPIO_NAREA, MPIO_NANO, DPTO_CNMBR,    Shape_Leng,       Shape_Area 
min values  :         50,      50001,     ACACÍAS,                                 1840,  117.34108343,      2017,       META, 0.43640580036, 0.00955216818621 
max values  :         50,      50711, VISTAHERMOSA, Ordenanza 63 de Noviembre 21 de 1965, 17247.6864753,      2017,       META, 8.63318071739,    1.40216640329 

Necesitamos convertirlo a una característica espacial:

meta_sf <-  sf::st_as_sf(aoi)

Ahora, disuelva los límites internos:

(border_sf <-
  meta_sf %>%
  summarise(area = sum(MPIO_NAREA)))
Simple feature collection with 1 feature and 1 field
geometry type:  POLYGON
dimension:      XY
bbox:           xmin: -74.89921 ymin: 1.604238 xmax: -71.07753 ymax: 4.899101
geographic CRS: WGS 84
      area                       geometry
1 85524.79 POLYGON ((-73.44639 2.38595...

Convertir de característica espacial a dataframe espacial:

 (border <- as(border_sf, 'Spatial')) 
class       : SpatialPolygonsDataFrame 
features    : 1 
extent      : -74.89921, -71.07753, 1.604238, 4.899101  (xmin, xmax, ymin, ymax)
CRS object has comment, which is lost in output
crs         : +proj=longlat +datum=WGS84 +no_defs 
variables   : 1
names       :           area 
value       : 85524.79262911 

otra conversion

(meta.sf <- st_as_sf(aoi) %>% mutate(MUNIC = MPIO_CNMBR, CODIGO = MPIO_CCDGO) %>% select(MUNIC, CODIGO))
Simple feature collection with 29 features and 2 fields
geometry type:  POLYGON
dimension:      XY
bbox:           xmin: -74.89921 ymin: 1.604238 xmax: -71.07753 ymax: 4.899101
geographic CRS: WGS 84
First 10 features:
               MUNIC CODIGO                       geometry
1      VILLAVICENCIO  50001 POLYGON ((-73.69288 4.28821...
2      ACACÃ\u008dAS  50006 POLYGON ((-73.80268 4.19734...
3   BARRANCA DE UPIA  50110 POLYGON ((-73.01607 4.63503...
4           CABUYARO  50124 POLYGON ((-73.08865 4.46048...
5  CASTILLA LA NUEVA  50150 POLYGON ((-73.7252 3.91777,...
6           CUBARRAL  50223 POLYGON ((-74.20143 4.0118,...
7            CUMARAL  50226 POLYGON ((-73.55407 4.31821...
8        EL CALVARIO  50245 POLYGON ((-73.74639 4.45008...
9        EL CASTILLO  50251 POLYGON ((-73.92004 3.74881...
10         EL DORADO  50270 POLYGON ((-73.83554 3.76362...

Ahora, intentaremos una tarea st_intersection. (https://cran.r-project.org/web/packages/sf/vignettes/sf3.html#geometrical_operations) se hace usando la biblioteca sf

# conversion
p.sf <- st_as_sf(precip.points)
## intersecta polígonos con puntos, manteniendo la información de ambos
(precip.sf = st_intersection(meta.sf, p.sf))
although coordinates are longitude/latitude, st_intersection assumes that they are planar
attribute variables are assumed to be spatially constant throughout all geometries
Simple feature collection with 2765 features and 3 fields
geometry type:  POINT
dimension:      XY
bbox:           xmin: -74.875 ymin: 1.624999 xmax: -71.125 ymax: 4.824999
geographic CRS: WGS 84
First 10 features:
              MUNIC CODIGO   Lluvia                 geometry
29   PUERTO GAITÃ\u0081N  50568 7.996710 POINT (-71.175 4.824999)
29.1 PUERTO GAITÃ\u0081N  50568 7.801209 POINT (-71.125 4.824999)
29.2 PUERTO GAITÃ\u0081N  50568 6.263782 POINT (-71.275 4.774999)
29.3 PUERTO GAITÃ\u0081N  50568 7.165887 POINT (-71.225 4.774999)
29.4 PUERTO GAITÃ\u0081N  50568 8.093927 POINT (-71.175 4.774999)
29.5 PUERTO GAITÃ\u0081N  50568 8.186864 POINT (-71.125 4.774999)
29.6 PUERTO GAITÃ\u0081N  50568 5.463953 POINT (-71.425 4.724999)
29.7 PUERTO GAITÃ\u0081N  50568 8.316946 POINT (-71.375 4.724999)
29.8 PUERTO GAITÃ\u0081N  50568 6.087829 POINT (-71.325 4.724999)
29.9 PUERTO GAITÃ\u0081N  50568 6.038989 POINT (-71.275 4.724999)

Dos tareas reproyecciones

p.sf.magna <- st_transform(precip.sf, crs=3116)
meta.sf.magna <- st_transform(meta.sf, crs=3116)

Una conversion

(precip2 <- as(p.sf.magna, 'Spatial'))
Discarded datum Unknown based on GRS80 ellipsoid in CRS definition,
 but +towgs84= values preserved
class       : SpatialPointsDataFrame 
features    : 2765 
extent      : 911335.8, 1328392, 671451.4, 1026012  (xmin, xmax, ymin, ymax)
CRS object has comment, which is lost in output
crs         : +proj=tmerc +lat_0=4.59620041666667 +lon_0=-74.0775079166667 +k=1 +x_0=1000000 +y_0=1000000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs 
variables   : 3
names       :        MUNIC, CODIGO,            Lluvia 
min values  :     ACACÍAS,  50001, 0.989288926124573 
max values  : VISTAHERMOSA,  50711,  34.2541122436523 

Nuevamente, podemos escribir el conjunto de datos intermedio (por si acaso):

shapefile(precip2, filename='C:/Users/amor/Desktop/Rstudio/precip2.shp', overwrite=TRUE)

Si es necesario, léelo. De lo contrario, sigue adelante

precip2$precipitaciones<- round(precip2$Lluvia, 1)

Lo que tenemos

precip2
class       : SpatialPointsDataFrame 
features    : 2765 
extent      : 911335.8, 1328392, 671451.4, 1026012  (xmin, xmax, ymin, ymax)
CRS object has comment, which is lost in output
crs         : +proj=tmerc +lat_0=4.59620041666667 +lon_0=-74.0775079166667 +k=1 +x_0=1000000 +y_0=1000000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs 
variables   : 4
names       :        MUNIC, CODIGO,            Lluvia, precipitaciones 
min values  :     ACACÍAS,  50001, 0.989288926124573,               1 
max values  : VISTAHERMOSA,  50711,  34.2541122436523,            34.3 
(meta2 <- as(meta.sf.magna, 'Spatial'))
Discarded datum Unknown based on GRS80 ellipsoid in CRS definition,
 but +towgs84= values preserved
class       : SpatialPolygonsDataFrame 
features    : 29 
extent      : 908647.3, 1333690, 669155.7, 1034240  (xmin, xmax, ymin, ymax)
CRS object has comment, which is lost in output
crs         : +proj=tmerc +lat_0=4.59620041666667 +lon_0=-74.0775079166667 +k=1 +x_0=1000000 +y_0=1000000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs 
variables   : 2
names       :        MUNIC, CODIGO 
min values  :     ACACÍAS,  50001 
max values  : VISTAHERMOSA,  50711 

Es posible que desee escribir el nuevo objeto (por si acaso):

shapefile(meta2, filename='C:/Users/amor/Desktop/Rstudio/meta2.shp', overwrite=TRUE)

Asegúrese de que las dos extensiones coincidan:

# Replace point boundary extent with that of meta
precip2@bbox <- meta2@bbox

División de datos en conjuntos de datos de capacitación y validación

train_index <- sample(1:nrow(precip2), 0.75 * nrow(precip2))
test_index <- setdiff(1:nrow(precip2), train_index)
ptos_train <- precip2[train_index, ]
ptos_test  <- precip2[test_index,]
ptrain <- spTransform(ptos_train, crs(precip.mask))
ptest <- spTransform(ptos_test, crs(precip.mask))
#install.packages("htmltools")
library(htmltools)
library(leaflet.extras)
# Primero preparar leaflet plot ...
lplot <- leaflet(data = precip2) %>% # data = cuerpo original - para obtener el zoom correcto
  addProviderTiles("CartoDB.Positron") %>% 
  addRasterImage(precip.mask, colors = pal, opacity = 0.6) %>%
  addCircleMarkers(data = ptrain, # primer grupo
                   radius = 1,
                   fillOpacity = .7,
                   stroke = FALSE,
                   popup = ~htmlEscape(precipitaciones),
                   color = pal(ptos_train$precipitaciones), # usando una paleta ya creada
                   clusterOptions = markerClusterOptions(),
                   group = "Training") %>% 
  addCircleMarkers(data = ptest, # segundo grupo
                   radius = 10,
                   fillOpacity = .7,
                   stroke = FALSE,
                   popup = ~htmlEscape(precipitaciones),
                   color = pal(ptos_test$precipitaciones), # using already created palette
                   clusterOptions = markerClusterOptions(),
                   group = "Test") %>% 
  addLegend(position = "bottomright",
            values = ~precipitaciones,
            opacity = .7,
            pal = pal, # palette declared previously
            title = "CHIRPS precipitaciones en Meta \ndesde 26.03. hasta 30.03 en 2020 [mm]") %>% 
  leaflet::addLayersControl(overlayGroups = c("Training", "Test"),
                   options = layersControlOptions(collapsed = FALSE)) %>% 
  addResetMapButton()
Discarded ellps WGS 84 in CRS definition: +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defsDiscarded datum WGS_1984 in CRS definitionUsing PROJ not WKT2 stringsDiscarded ellps WGS 84 in CRS definition: +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defsDiscarded datum WGS_1984 in CRS definitionDiscarded ellps WGS 84 in CRS definition: +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defsDiscarded datum WGS_1984 in CRS definitionUsing PROJ not WKT2 stringsDiscarded ellps WGS 84 in CRS definition: +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defsDiscarded datum WGS_1984 in CRS definitionDiscarded ellps WGS 84 in CRS definition: +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defsDiscarded datum WGS_1984 in CRS definitionUsing PROJ not WKT2 stringsDiscarded ellps WGS 84 in CRS definition: +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defsDiscarded datum WGS_1984 in CRS definitionUsing PROJ not WKT2 stringsDiscarded ellps WGS 84 in CRS definition: +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defsDiscarded datum WGS_1984 in CRS definitionDiscarded ellps WGS 84 in CRS definition: +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defsDiscarded datum WGS_1984 in CRS definitionUsing PROJ not WKT2 stringsSome values were outside the color scale and will be treated as NASome values were outside the color scale and will be treated as NA
lplot #  ... display the map
LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQojIyMjIFlhIHNlIHRpZW5lIGRlc2NhcmdhZG8gbG9zIGRhdG9zIGRlIHByZWNpcGl0YWNpw7NuIGZvcm1hdG8gdGlmIA0KIyMjIyBEZSBsb3MgZ2xvYmFsLXBlbnRhZCBub21icmU6IENoaXJwcy52LjIuMCAyMDIwLjAzLjYNCiMjIyMgQXJyZWdsbyBkZSBsb3MgZGF0b3MgDQoNCg0KDQpgYGB7cn0NCmxpYnJhcnkocmdkYWwpDQpgYGANCg0KYGBge3J9DQpsaWJyYXJ5KHJhc3RlcikNCmxpYnJhcnkoc2YpDQpgYGANCmBgYHtyfQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpgYGANCmBgYHtyfQ0KbGlicmFyeSh0bWFwKQ0KbGlicmFyeShnc3RhdCkNCmxpYnJhcnkoc3ApDQpgYGANCg0KIyMjIyAzLiBQcmVwcm9jZXNhbWllbnRvIGRlIGRhdG9zIENISVJQUw0KIyMjIyBMZWEgZWwgYXJjaGl2byBDSElSUFMgc2luIGNvbXByaW1pcjoNCmBgYHtyfQ0KcHJlY2lwIDwtIHJhc3RlcigiQzovVXNlcnMvYW1vci9EZXNrdG9wL1JzdHVkaW8vY2hpcnBzLXYyLjAuMjAyMC4wMy42LnRpZiIpDQpgYGANCg0KIyMjIyBDb21vIHlhIGhhYnLDoSBub3RhZG8sIGVzdGUgYXJjaGl2byByZXByZXNlbnRhIGxhIGxsdXZpYSBhY3VtdWxhZGEgZW4gbG9zIMO6bHRpbW9zIGTDrWFzIGRlIG1hcnpvIGRlIDIwMjAgKGVzIGRlY2lyLCBsYSBwcmVjaXBpdGFjacOzbiBkZWwgMjYgYWwgMzEgZGUgbWFyem8pLg0KDQojIyMgVmVyaWZpcXVlIGVsIGNvbnRlbmlkbyBkZWwgb2JqZXRvIHByZWNpcA0KDQpgYGB7cn0NCnByZWNpcA0KYGBgDQoNCiMjIyBUZW5nYSBlbiBjdWVudGEgcXVlIGVzdGUgZXMgdW4gY29uanVudG8gZGUgZGF0b3MgY29uIGNvYmVydHVyYSBnbG9iYWwuIFN1IENSUyBlcyB1biBzaXN0ZW1hIGRlIGNvb3JkZW5hZGFzIGdlb2dyw6FmaWNhcy4NCg0KIyMjIENhcmd1ZW1vcyB1biBhcmNoaXZvIHNoYXBlIHF1ZSByZXByZXNlbnRlIG51ZXN0cmEgw6FyZWEgZGUgaW50ZXLDqXM6DQoNCmBgYHtyfQ0KKGFvaSA8LSBzaGFwZWZpbGUoIkM6L1VzZXJzL2Ftb3IvRGVza3RvcC9Sc3R1ZGlvL01HTjIwMTdfNTBfTUVUQS81MF9NRVRBL0FETUlOSVNUUkFUSVZPL01HTl9NUElPX1BPTElUSUNPLnNocCIpKQ0KYGBgDQoNCg0KIyMjIFRlbmdhIGVuIGN1ZW50YSBxdWUgbG9zIHNpc3RlbWFzIGRlIHJlZmVyZW5jaWEgZGUgY29vcmRlbmFkYXMgcGFyYSBhbWJvcyBjb25qdW50b3MgZGUgZGF0b3Mgc29uIGxvcyBtaXNtb3MuDQoNCiMjIyBBaG9yYSwgcmVjb3J0ZW1vcyBsb3MgZGF0b3MgZGUgcHJlY2lwaXRhY2nDs246DQoNCmBgYHtyfQ0KIyBEYXRvcyBkZSBwcmVjaXBpdGFjacOzbiBkZSBjdWx0aXZvcyBwb3IgZXh0ZW5zacOzbiBkZSDDoXJlYSBkZSBpbnRlcsOpcw0KcHJlY2lwLmNyb3AgPC0gcmFzdGVyOjpjcm9wKHByZWNpcCwgZXh0ZW50KGFvaSkpDQpgYGANCiMjIyMgQWhvcmEsIGVubWFzY2FyYXIgbGEgY2FwYSBkZSB0cmFtYToNCmBgYHtyfQ0KcHJlY2lwLm1hc2sgPC0gbWFzayh4ID0gcHJlY2lwLmNyb3AsIG1hc2sgPSBhb2kpDQpgYGANCiMjIyBWZXJpZmlxdWUgbGEgc2FsaWRhOg0KYGBge3J9DQpwcmVjaXAubWFzayANCmBgYA0KIyMjIEx1ZWdvLCBzZSBwbG90ZWEgbGEgY2FwYSBSYXN0ZXIgcmVjb3J0YWRhOg0KDQpgYGB7cn0NCnBsb3QocHJlY2lwLm1hc2ssIG1haW49ICJDSElSUFMgcHJlY2lwaXRhY2lvbmVzIGVuIE1ldGEgZGVzZGUgMjYuMDMuIGhhc3RhIDMwLjAzIGVuIDIwMjAgW21tXSAiKQ0KcGxvdChhb2ksIGFkZD1UUlVFKQ0KYGBgDQojIyMjIFNlIHB1ZWRlIGhhY2VyIHVuIG1lam9yIG1hcGEgY29uIExlYWZsZXQgdXNhbmRvIGxhIGZ1bmNpw7NuIGFkZFJhc3RlckltYWdlOg0KDQpgYGB7cn0NCmxpYnJhcnkobGVhZmxldCkNCmxpYnJhcnkoUkNvbG9yQnJld2VyKQ0KcGFsIDwtIGNvbG9yTnVtZXJpYyhjKCJyZWQiLCAib3JhbmdlIiwgInllbGxvdyIsICJibHVlIiwgImRhcmtibHVlIiksIHZhbHVlcyhwcmVjaXAubWFzayksDQogIG5hLmNvbG9yID0gInRyYW5zcGFyZW50IikNCg0KbGVhZmxldCgpICU+JSBhZGRUaWxlcygpICU+JQ0KICBhZGRSYXN0ZXJJbWFnZShwcmVjaXAubWFzaywgY29sb3JzID0gcGFsLCBvcGFjaXR5ID0gMC42KSAlPiUNCiAgYWRkTGVnZW5kKHBhbCA9IHBhbCwgdmFsdWVzID0gdmFsdWVzKHByZWNpcC5tYXNrKSwNCiAgICB0aXRsZSA9ICJDSElSUFMgcHJlY2lwaXRhY2lvbmVzIGVuIE1ldGEgZGVzZGUgMjYuMDMuIGhhc3RhIDMwLjAzIGVuIDIwMjAgW21tXSIpDQpgYGANCg0KIyMjIExhIGNvbnZlcnNpw7NuIGRlIHLDoXN0ZXIgZW4gcHVudG9zIHNlIHB1ZWRlIHJlYWxpemFyIHV0aWxpemFuZG8gbGEgZnVuY2nDs24gcmFzdGVyVG9Qb2ludHMgZGUgbGEgYmlibGlvdGVjYSByw6FzdGVyOg0KYGBge3J9DQpwcmVjaXAucG9pbnRzIDwtIHJhc3RlclRvUG9pbnRzKHByZWNpcC5tYXNrLCBzcGF0aWFsID0gVFJVRSkNCmBgYA0KYGBge3J9DQpwcmVjaXAucG9pbnRzDQpgYGANCmBgYHtyfQ0KbmFtZXMocHJlY2lwLnBvaW50cykgPC0gIkxsdXZpYSINCmBgYA0KYGBge3J9DQpwcmVjaXAucG9pbnRzDQpgYGANCmBgYHtyfQ0Kc3RyKHByZWNpcC5wb2ludHMpDQpgYGANCg0KIyMjIyBUcmFjZW1vcyBsb3MgcHVudG9zOg0KYGBge3J9DQpwbG90KHByZWNpcC5tYXNrLCBtYWluPSAiQ0hJUlBTIHByZWNpcGl0YWNpb25lcyBlbiBNZXRhIGRlc2RlIDI2LjAzLiBoYXN0YSAzMC4wMyBlbiAyMDIwIFttbV0iKQ0KcGxvdChhb2ksIGFkZD1UUlVFKQ0KcG9pbnRzKHByZWNpcC5wb2ludHMkeCwgcHJlY2lwLnBvaW50cyR5LCBjb2wgPSAicmVkIiwgY2V4ID0gLjQpDQpgYGANCg0KIyMjIyBFc2NyaWJhbW9zIGxvcyBvYmpldG9zIGVzcGFjaWFsZXMgZGUgcHVudG9zIGVuIHVuIGFyY2hpdm8gZGUgZGlzY28uIFNvbG8gcGFyYSBhaG9ycmFyIHRpZW1wbyB5IHRyYWJham8gZW4gY2FzbyBkZSBxdWUgYWxnbyBzYWxnYSBtYWwuDQoNCmBgYHtyfQ0KZ2VvanNvbmlvOjpnZW9qc29uX3dyaXRlKHByZWNpcC5wb2ludHMsIGZpbGUgPSAiQzovVXNlcnMvYW1vci9EZXNrdG9wL1JzdHVkaW8vcHBvaW50cy5nZW9qc29uIikNCmBgYA0KDQojIyMjIExlYW1vcyBsb3MgcHVudG9zIGRlIHByZWNpcGl0YWNpw7NuLiBDb25zdWx0ZSBsYSBkb2N1bWVudGFjacOzbiBkZSBnZW9qc29uaW8gcGFyYSBjb21wcmVuZGVyIHF1w6kgcGFyw6FtZXRyb3MgZGViZW4gcGFzYXJzZSBhIGxhIGZ1bmNpw7NuIGdlb2pzb25fcmVhZC4NCg0KYGBge3J9DQpwcmVjaXAucG9pbnRzIDwtIGdlb2pzb25pbzo6Z2VvanNvbl9yZWFkKCJDOi9Vc2Vycy9hbW9yL0Rlc2t0b3AvUnN0dWRpby9wcG9pbnRzLmdlb2pzb24iLCB3aGF0PSJzcCIpDQpgYGANCg0KIyMjIFZlcmlmaXF1ZW1vcyBjdcOhbCBlcyBlbCBvYmpldG8gZGUgcHVudG9zIHByZWNpcC46DQpgYGB7cn0NCnByZWNpcC5wb2ludHMNCmBgYA0KDQojIyMjIMK/Q3XDoWwgZXMgZWwgcHVudG8gZGUgY29udmVydGlyIGxvcyBkYXRvcyBkZSBwcmVjaXBpdGFjacOzbiByw6FzdGVyIGVuIGRhdG9zIGRlIHByZWNpcGl0YWNpw7NuIHB1bnR1YWw/DQoNCiMjIyMgQnVlbm8sIGhheSBwb2NhcyBlc3RhY2lvbmVzIG1ldGVvcm9sw7NnaWNhcyBkZSBsYSBPcmdhbml6YWNpw7NuIE1ldGVvcm9sw7NnaWNhIE11bmRpYWwgKE9NTSkgZW4gbnVlc3RybyBwYcOtczoNCg0KIyMjIyBQb3IgbG8gdGFudG8sIENISVJQUyBwdWVkZSBzZXIgdW5hIG9wY2nDs24gcGFyYSBvYnRlbmVyIGxvcyBkYXRvcyBkZSBwcmVjaXBpdGFjacOzbiBwdW50dWFsZXMgbmVjZXNhcmlvcyBwYXJhIG9idGVuZXIgdW5hIHN1cGVyZmljaWUgZGUgcHJlY2lwaXRhY2nDs24gY29udGludWEuDQoNCiMjIyMgUHJlcGFyYWNpw7NuIGFkaWNpb25hbA0KIyMjIyBFbiBjYXNvIGRlIHF1ZSBzZSBwaWVyZGEgbGEgY29uZXhpw7NuLCBwb2RlbW9zIGxlZXIgbnVldmFtZW50ZSBlbCBhcmNoaXZvIGRlIGZvcm1hIGNvbiBlbCDDoXJlYSBkZSBpbnRlcsOpczoNCmBgYHtyfQ0KKGFvaSA8LSBzaGFwZWZpbGUoIkM6L1VzZXJzL2Ftb3IvRGVza3RvcC9Sc3R1ZGlvL01HTjIwMTdfNTBfTUVUQS81MF9NRVRBL0FETUlOSVNUUkFUSVZPL01HTl9NUElPX1BPTElUSUNPLnNocCIpKQ0KYGBgDQoNCiMjIyMgTmVjZXNpdGFtb3MgY29udmVydGlybG8gYSB1bmEgY2FyYWN0ZXLDrXN0aWNhIGVzcGFjaWFsOg0KDQpgYGB7cn0NCm1ldGFfc2YgPC0gIHNmOjpzdF9hc19zZihhb2kpDQpgYGANCiMjIyMgQWhvcmEsIGRpc3VlbHZhIGxvcyBsw61taXRlcyBpbnRlcm5vczoNCmBgYHtyfQ0KKGJvcmRlcl9zZiA8LQ0KICBtZXRhX3NmICU+JQ0KICBzdW1tYXJpc2UoYXJlYSA9IHN1bShNUElPX05BUkVBKSkpDQpgYGANCg0KIyMjIyBDb252ZXJ0aXIgZGUgY2FyYWN0ZXLDrXN0aWNhIGVzcGFjaWFsIGEgZGF0YWZyYW1lIGVzcGFjaWFsOg0KDQoNCmBgYHtyfQ0KIChib3JkZXIgPC0gYXMoYm9yZGVyX3NmLCAnU3BhdGlhbCcpKSANCmBgYA0KDQojIyMjIG90cmEgY29udmVyc2lvbiANCg0KYGBge3J9DQoobWV0YS5zZiA8LSBzdF9hc19zZihhb2kpICU+JSBtdXRhdGUoTVVOSUMgPSBNUElPX0NOTUJSLCBDT0RJR08gPSBNUElPX0NDREdPKSAlPiUgc2VsZWN0KE1VTklDLCBDT0RJR08pKQ0KYGBgDQojIyMjIEFob3JhLCBpbnRlbnRhcmVtb3MgdW5hIHRhcmVhIHN0X2ludGVyc2VjdGlvbi4gKGh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL3dlYi9wYWNrYWdlcy9zZi92aWduZXR0ZXMvc2YzLmh0bWwjZ2VvbWV0cmljYWxfb3BlcmF0aW9ucykgc2UgaGFjZSB1c2FuZG8gbGEgYmlibGlvdGVjYSBzZg0KDQpgYGB7cn0NCiMgY29udmVyc2lvbg0KcC5zZiA8LSBzdF9hc19zZihwcmVjaXAucG9pbnRzKQ0KYGBgDQpgYGB7cn0NCiMjIGludGVyc2VjdGEgcG9sw61nb25vcyBjb24gcHVudG9zLCBtYW50ZW5pZW5kbyBsYSBpbmZvcm1hY2nDs24gZGUgYW1ib3MNCihwcmVjaXAuc2YgPSBzdF9pbnRlcnNlY3Rpb24obWV0YS5zZiwgcC5zZikpDQpgYGANCiMjIyMgRG9zIHRhcmVhcyByZXByb3llY2Npb25lcyANCmBgYHtyfQ0KcC5zZi5tYWduYSA8LSBzdF90cmFuc2Zvcm0ocHJlY2lwLnNmLCBjcnM9MzExNikNCmBgYA0KYGBge3J9DQptZXRhLnNmLm1hZ25hIDwtIHN0X3RyYW5zZm9ybShtZXRhLnNmLCBjcnM9MzExNikNCmBgYA0KIyMjIFVuYSBjb252ZXJzaW9uIA0KYGBge3J9DQoocHJlY2lwMiA8LSBhcyhwLnNmLm1hZ25hLCAnU3BhdGlhbCcpKQ0KYGBgDQojIyMjIE51ZXZhbWVudGUsIHBvZGVtb3MgZXNjcmliaXIgZWwgY29uanVudG8gZGUgZGF0b3MgaW50ZXJtZWRpbyAocG9yIHNpIGFjYXNvKToNCmBgYHtyfQ0Kc2hhcGVmaWxlKHByZWNpcDIsIGZpbGVuYW1lPSdDOi9Vc2Vycy9hbW9yL0Rlc2t0b3AvUnN0dWRpby9wcmVjaXAyLnNocCcsIG92ZXJ3cml0ZT1UUlVFKQ0KYGBgDQojIyMgU2kgZXMgbmVjZXNhcmlvLCBsw6llbG8uIERlIGxvIGNvbnRyYXJpbywgc2lndWUgYWRlbGFudGUNCg0KYGBge3J9DQpwcmVjaXAyJHByZWNpcGl0YWNpb25lczwtIHJvdW5kKHByZWNpcDIkTGx1dmlhLCAxKQ0KYGBgDQoNCiMjIyMgTG8gcXVlIHRlbmVtb3MNCmBgYHtyfQ0KcHJlY2lwMg0KYGBgDQpgYGB7cn0NCihtZXRhMiA8LSBhcyhtZXRhLnNmLm1hZ25hLCAnU3BhdGlhbCcpKQ0KYGBgDQojIyMjIEVzIHBvc2libGUgcXVlIGRlc2VlIGVzY3JpYmlyIGVsIG51ZXZvIG9iamV0byAocG9yIHNpIGFjYXNvKToNCg0KYGBge3J9DQpzaGFwZWZpbGUobWV0YTIsIGZpbGVuYW1lPSdDOi9Vc2Vycy9hbW9yL0Rlc2t0b3AvUnN0dWRpby9tZXRhMi5zaHAnLCBvdmVyd3JpdGU9VFJVRSkNCmBgYA0KIyMjIyBBc2Vnw7pyZXNlIGRlIHF1ZSBsYXMgZG9zIGV4dGVuc2lvbmVzIGNvaW5jaWRhbjoNCg0KYGBge3J9DQojIFJlcGxhY2UgcG9pbnQgYm91bmRhcnkgZXh0ZW50IHdpdGggdGhhdCBvZiBtZXRhDQpwcmVjaXAyQGJib3ggPC0gbWV0YTJAYmJveA0KYGBgDQoNCg0KIyMjIERpdmlzacOzbiBkZSBkYXRvcyBlbiBjb25qdW50b3MgZGUgZGF0b3MgZGUgY2FwYWNpdGFjacOzbiB5IHZhbGlkYWNpw7NuDQpgYGB7cn0NCnRyYWluX2luZGV4IDwtIHNhbXBsZSgxOm5yb3cocHJlY2lwMiksIDAuNzUgKiBucm93KHByZWNpcDIpKQ0KdGVzdF9pbmRleCA8LSBzZXRkaWZmKDE6bnJvdyhwcmVjaXAyKSwgdHJhaW5faW5kZXgpDQpwdG9zX3RyYWluIDwtIHByZWNpcDJbdHJhaW5faW5kZXgsIF0NCnB0b3NfdGVzdCAgPC0gcHJlY2lwMlt0ZXN0X2luZGV4LF0NCnB0cmFpbiA8LSBzcFRyYW5zZm9ybShwdG9zX3RyYWluLCBjcnMocHJlY2lwLm1hc2spKQ0KcHRlc3QgPC0gc3BUcmFuc2Zvcm0ocHRvc190ZXN0LCBjcnMocHJlY2lwLm1hc2spKQ0KYGBgDQoNCmBgYHtyfQ0KI2luc3RhbGwucGFja2FnZXMoImh0bWx0b29scyIpDQpsaWJyYXJ5KGh0bWx0b29scykNCmxpYnJhcnkobGVhZmxldC5leHRyYXMpDQpgYGANCg0KDQpgYGB7cn0NCiMgUHJpbWVybyBwcmVwYXJhciBsZWFmbGV0IHBsb3QgLi4uDQpscGxvdCA8LSBsZWFmbGV0KGRhdGEgPSBwcmVjaXAyKSAlPiUgIyBkYXRhID0gY3VlcnBvIG9yaWdpbmFsIC0gcGFyYSBvYnRlbmVyIGVsIHpvb20gY29ycmVjdG8NCiAgYWRkUHJvdmlkZXJUaWxlcygiQ2FydG9EQi5Qb3NpdHJvbiIpICU+JSANCiAgYWRkUmFzdGVySW1hZ2UocHJlY2lwLm1hc2ssIGNvbG9ycyA9IHBhbCwgb3BhY2l0eSA9IDAuNikgJT4lDQogIGFkZENpcmNsZU1hcmtlcnMoZGF0YSA9IHB0cmFpbiwgIyBwcmltZXIgZ3J1cG8NCiAgICAgICAgICAgICAgICAgICByYWRpdXMgPSAxLA0KICAgICAgICAgICAgICAgICAgIGZpbGxPcGFjaXR5ID0gLjcsDQogICAgICAgICAgICAgICAgICAgc3Ryb2tlID0gRkFMU0UsDQogICAgICAgICAgICAgICAgICAgcG9wdXAgPSB+aHRtbEVzY2FwZShwcmVjaXBpdGFjaW9uZXMpLA0KICAgICAgICAgICAgICAgICAgIGNvbG9yID0gcGFsKHB0b3NfdHJhaW4kcHJlY2lwaXRhY2lvbmVzKSwgIyB1c2FuZG8gdW5hIHBhbGV0YSB5YSBjcmVhZGENCiAgICAgICAgICAgICAgICAgICBjbHVzdGVyT3B0aW9ucyA9IG1hcmtlckNsdXN0ZXJPcHRpb25zKCksDQogICAgICAgICAgICAgICAgICAgZ3JvdXAgPSAiVHJhaW5pbmciKSAlPiUgDQogIGFkZENpcmNsZU1hcmtlcnMoZGF0YSA9IHB0ZXN0LCAjIHNlZ3VuZG8gZ3J1cG8NCiAgICAgICAgICAgICAgICAgICByYWRpdXMgPSAxMCwNCiAgICAgICAgICAgICAgICAgICBmaWxsT3BhY2l0eSA9IC43LA0KICAgICAgICAgICAgICAgICAgIHN0cm9rZSA9IEZBTFNFLA0KICAgICAgICAgICAgICAgICAgIHBvcHVwID0gfmh0bWxFc2NhcGUocHJlY2lwaXRhY2lvbmVzKSwNCiAgICAgICAgICAgICAgICAgICBjb2xvciA9IHBhbChwdG9zX3Rlc3QkcHJlY2lwaXRhY2lvbmVzKSwgIyB1c2luZyBhbHJlYWR5IGNyZWF0ZWQgcGFsZXR0ZQ0KICAgICAgICAgICAgICAgICAgIGNsdXN0ZXJPcHRpb25zID0gbWFya2VyQ2x1c3Rlck9wdGlvbnMoKSwNCiAgICAgICAgICAgICAgICAgICBncm91cCA9ICJUZXN0IikgJT4lIA0KICBhZGRMZWdlbmQocG9zaXRpb24gPSAiYm90dG9tcmlnaHQiLA0KICAgICAgICAgICAgdmFsdWVzID0gfnByZWNpcGl0YWNpb25lcywNCiAgICAgICAgICAgIG9wYWNpdHkgPSAuNywNCiAgICAgICAgICAgIHBhbCA9IHBhbCwgIyBwYWxldHRlIGRlY2xhcmVkIHByZXZpb3VzbHkNCiAgICAgICAgICAgIHRpdGxlID0gIkNISVJQUyBwcmVjaXBpdGFjaW9uZXMgZW4gTWV0YSBcbmRlc2RlIDI2LjAzLiBoYXN0YSAzMC4wMyBlbiAyMDIwIFttbV0iKSAlPiUgDQogIGxlYWZsZXQ6OmFkZExheWVyc0NvbnRyb2wob3ZlcmxheUdyb3VwcyA9IGMoIlRyYWluaW5nIiwgIlRlc3QiKSwNCiAgICAgICAgICAgICAgICAgICBvcHRpb25zID0gbGF5ZXJzQ29udHJvbE9wdGlvbnMoY29sbGFwc2VkID0gRkFMU0UpKSAlPiUgDQogIGFkZFJlc2V0TWFwQnV0dG9uKCkNCmBgYA0KDQpgYGB7cn0NCmxwbG90ICMgIC4uLiBkaXNwbGF5IHRoZSBtYXANCmBgYA0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg==