Isaac Bell Geog 490
For my final project, I’ll be investigating a netCDF file showing
Palmer Drought Severity Index in the US. This dataset originally had
data from 1980 to 2024, but to make things simpler I’ve decided to only
focus on drought in the western states between 2000 and today. Palmer
Drought Severity (PDSI) uses data about both temperature and
precipitation to quantify how severe a drought is; relative to a
region’s normal climate, negative values represent dry, and positive
values represent wet. The dataset I’m using has values for the mean PDSI
every 5 days, gridded at a resolution of 1/24th degree or about 4km.
I wanted to use R to see what patterns there were to this data, and
which areas have been most or least affected by drought. To do this, I’m
going to be extracting the gridded data and associating it to Western US
states and counties.
First, loading libraries:
library(ncdf4)
library(CFtime)
library(lattice)
library(RColorBrewer)
library(maps)
library(sf)
library(terra)
library(tidyterra)
library(classInt)
library(ggplot2)
library(raster)
library(exactextractr)
library(reshape2)
Getting western states shapefiles:
state_sf <- st_as_sf(map("state", plot = FALSE, fill = TRUE, crs = "+proj=longlat +ellps=WGS84"))
selected_sf <- state_sf[state_sf$ID %in% c("washington","oregon","california","arizona","new mexico","nevada","idaho","utah","colorado","wyoming","montana"),]
state_geom <- st_geometry(selected_sf)
plot(selected_sf)
Getting county shapefiles:
county_sf <- st_as_sf(map("county", plot = FALSE, fill = TRUE))
county_sf$state <- sub(",.*", "", county_sf$ID)
selected_county <- county_sf[county_sf$state %in% c("washington","oregon","california","arizona","new mexico","nevada","idaho","utah","colorado","wyoming","montana"),]
county_geom <- st_geometry(selected_county)
plot(selected_county)
I’ll use these shapefiles to extract data spatially from my raster
dataset.
Loading and setting up netCDF file:
ncpath <- "/Users/isaacbell/Documents/geog490/final_proj/data/"
ncname <- "2000to2024"
ncfname <- paste(ncpath, ncname, ".nc", sep="")
ncin <- nc_open(ncfname)
dname <- "daily_mean_palmer_drought_severity_index"
lon <- ncvar_get(ncin,"lon")
nlon <- dim(lon)
lat <- ncvar_get(ncin,"lat")
nlat <- dim(lat)
title <- ncatt_get(ncin,0,"title")
institution <- ncatt_get(ncin,0,"institution")
datasource <- ncatt_get(ncin,0,"source")
references <- ncatt_get(ncin,0,"references")
history <- ncatt_get(ncin,0,"history")
Conventions <- ncatt_get(ncin,0,"Conventions")
pdsi_array <- ncvar_get(ncin,dname)
dlname <- ncatt_get(ncin,dname,"long_name")
dunits <- ncatt_get(ncin,dname,"units")
fillvalue <- ncatt_get(ncin,dname,"_FillValue")
dim(pdsi_array)
[1] 595 585 1753
Getting time from netCDF:
time <- ncvar_get(ncin,"day")
tunits <- ncatt_get(ncin,"day","units")
nt <- dim(time)
cf <- CFtime(tunits$value, calendar = "proleptic_gregorian", time)
timestamps <- CFtimestamp(cf)
months = CFfactor(cf,"month")
time_cf <- CFparse(cf, timestamps)
head(time_cf)
As you can see, the file contains measurements recurring every 5
days.
Making a raster from netCDF, and applying time values to it:
pdsi_raster <- rast(ncfname)
names(pdsi_raster) <- timestamps
stamps_date <- as.Date(timestamps)
time(pdsi_raster) <- stamps_date
This allows me to parse the raster stack by date.
Getting the overall mean PDSI values for the whole 2000-2024 raster
stack:
mean_raster = mean(pdsi_raster)
plot(mean_raster)
Geographic analysis
Now that I have the county and state geometries, I can use the
exact_extract()
function to pull the data from the raster
into the vector. This comes from the exactextratr
library,
and it allows me to write the average value within each polygon to a new
column on the vector data.
selected_sf$mean_alltime <- exact_extract(mean_raster, selected_sf, 'mean')
plot(selected_sf[,'mean_alltime'])
selected_county$mean_alltime <- exact_extract(mean_raster, selected_county, 'mean')
plot(selected_county[,'mean_alltime'])
(note that the scales are different for both plots)
In the state plots, you can see that every state in the west has seen
stronger dry conditions than wet conditions since 2000. Montana looks to
be the least affected, and Oregon has had the driest average conditions
(relative to normal).
Next, I’ll split up the raster stack into individual years, then use
exact_extract()
to get the means for each year into the
state and county shapefiles.
year_li <- seq(2000,2024)
for (i in year_li){
i <- toString(i)
a <- pdsi_raster[i]
selected_sf[, i] <- exact_extract(a, selected_sf, 'mean')
selected_county[, i] <- exact_extract(a, selected_county, 'mean')
}
(This might not be the most efficient method, but it works well
enough)
Here’s a quick time series plot of the average PDSI for each
state:
states_df <- st_drop_geometry(selected_sf)
drops <- c("ID","mean_alltime")
select_states_df <- states_df[ , !(names(states_df) %in% drops)]
select_states_df$metadata <- row.names(select_states_df)
select_states_df <- melt(select_states_df, "metadata")
ggplot(select_states_df, aes(variable, value, group = metadata, color = metadata)) +
geom_line()
Let’s plot the average PDSI rasters for a couple of years:
raster_2000 <- mean(pdsi_raster["2000"])
plot(raster_2000,
breaks=c(-4,-3,-2,-1,0,1,2,3,4),
col=brewer.pal(9, "RdYlGn"),
main="Mean PDSI: 2000"
)
raster_2023 <- mean(pdsi_raster["2023"])
plot(raster_2023,
breaks=c(-5,-4,-3,-2,-1,0,1,2,3,4,5),
col=brewer.pal(11, "RdYlGn"),
main="Mean PDSI: 2023"
)
For reference, the National Drought Mitigation Center considers PDSI
values from -3 to -4 ‘severe drought,’ and values above -4 as ‘extreme
drought.’
LS0tCnRpdGxlOiAiRHJvdWdodCBpbiB0aGUgV2VzdGVybiBVUzogMjAwMC0yMDI0IgpvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDoKICAgIGRmX3ByaW50OiBwYWdlZAotLS0KSXNhYWMgQmVsbApHZW9nIDQ5MAoKCkZvciBteSBmaW5hbCBwcm9qZWN0LCBJJ2xsIGJlIGludmVzdGlnYXRpbmcgYSBuZXRDREYgZmlsZSBzaG93aW5nIFBhbG1lciBEcm91Z2h0IFNldmVyaXR5IEluZGV4IGluIHRoZSBVUy4gVGhpcyBkYXRhc2V0IG9yaWdpbmFsbHkgaGFkIGRhdGEgZnJvbSAxOTgwIHRvIDIwMjQsIGJ1dCB0byBtYWtlIHRoaW5ncyBzaW1wbGVyIEkndmUgZGVjaWRlZCB0byBvbmx5IGZvY3VzIG9uIGRyb3VnaHQgaW4gdGhlIHdlc3Rlcm4gc3RhdGVzIGJldHdlZW4gMjAwMCBhbmQgdG9kYXkuIFBhbG1lciBEcm91Z2h0IFNldmVyaXR5IChQRFNJKSB1c2VzIGRhdGEgYWJvdXQgYm90aCB0ZW1wZXJhdHVyZSBhbmQgcHJlY2lwaXRhdGlvbiB0byBxdWFudGlmeSBob3cgc2V2ZXJlIGEgZHJvdWdodCBpczsgcmVsYXRpdmUgdG8gYSByZWdpb24ncyBub3JtYWwgY2xpbWF0ZSwgbmVnYXRpdmUgdmFsdWVzIHJlcHJlc2VudCBkcnksIGFuZCBwb3NpdGl2ZSB2YWx1ZXMgcmVwcmVzZW50IHdldC4gVGhlIGRhdGFzZXQgSSdtIHVzaW5nIGhhcyB2YWx1ZXMgZm9yIHRoZSBtZWFuIFBEU0kgZXZlcnkgNSBkYXlzLCBncmlkZGVkIGF0IGEgcmVzb2x1dGlvbiBvZiAxLzI0dGggZGVncmVlIG9yIGFib3V0IDRrbS4KCkkgd2FudGVkIHRvIHVzZSBSIHRvIHNlZSB3aGF0IHBhdHRlcm5zIHRoZXJlIHdlcmUgdG8gdGhpcyBkYXRhLCBhbmQgd2hpY2ggYXJlYXMgaGF2ZSBiZWVuIG1vc3Qgb3IgbGVhc3QgYWZmZWN0ZWQgYnkgZHJvdWdodC4gVG8gZG8gdGhpcywgSSdtIGdvaW5nIHRvIGJlIGV4dHJhY3RpbmcgdGhlIGdyaWRkZWQgZGF0YSBhbmQgYXNzb2NpYXRpbmcgaXQgdG8gV2VzdGVybiBVUyBzdGF0ZXMgYW5kIGNvdW50aWVzLgoKCkZpcnN0LCBsb2FkaW5nIGxpYnJhcmllczoKCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmxpYnJhcnkobmNkZjQpCmxpYnJhcnkoQ0Z0aW1lKQpsaWJyYXJ5KGxhdHRpY2UpCmxpYnJhcnkoUkNvbG9yQnJld2VyKQpsaWJyYXJ5KG1hcHMpCmxpYnJhcnkoc2YpCmxpYnJhcnkodGVycmEpCmxpYnJhcnkodGlkeXRlcnJhKQpsaWJyYXJ5KGNsYXNzSW50KQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkocmFzdGVyKQpsaWJyYXJ5KGV4YWN0ZXh0cmFjdHIpCmxpYnJhcnkocmVzaGFwZTIpCmBgYAoKCkdldHRpbmcgd2VzdGVybiBzdGF0ZXMgc2hhcGVmaWxlczoKCmBgYHtyfQpzdGF0ZV9zZiA8LSBzdF9hc19zZihtYXAoInN0YXRlIiwgcGxvdCA9IEZBTFNFLCBmaWxsID0gVFJVRSwgY3JzID0gIitwcm9qPWxvbmdsYXQgK2VsbHBzPVdHUzg0IikpCnNlbGVjdGVkX3NmIDwtIHN0YXRlX3NmW3N0YXRlX3NmJElEICVpbiUgYygid2FzaGluZ3RvbiIsIm9yZWdvbiIsImNhbGlmb3JuaWEiLCJhcml6b25hIiwibmV3IG1leGljbyIsIm5ldmFkYSIsImlkYWhvIiwidXRhaCIsImNvbG9yYWRvIiwid3lvbWluZyIsIm1vbnRhbmEiKSxdCnN0YXRlX2dlb20gPC0gc3RfZ2VvbWV0cnkoc2VsZWN0ZWRfc2YpCnBsb3Qoc2VsZWN0ZWRfc2YpCmBgYAoKCkdldHRpbmcgY291bnR5IHNoYXBlZmlsZXM6CgpgYGB7cn0KY291bnR5X3NmIDwtIHN0X2FzX3NmKG1hcCgiY291bnR5IiwgcGxvdCA9IEZBTFNFLCBmaWxsID0gVFJVRSkpCmNvdW50eV9zZiRzdGF0ZSA8LSBzdWIoIiwuKiIsICIiLCBjb3VudHlfc2YkSUQpCnNlbGVjdGVkX2NvdW50eSA8LSBjb3VudHlfc2ZbY291bnR5X3NmJHN0YXRlICVpbiUgYygid2FzaGluZ3RvbiIsIm9yZWdvbiIsImNhbGlmb3JuaWEiLCJhcml6b25hIiwibmV3IG1leGljbyIsIm5ldmFkYSIsImlkYWhvIiwidXRhaCIsImNvbG9yYWRvIiwid3lvbWluZyIsIm1vbnRhbmEiKSxdCmNvdW50eV9nZW9tIDwtIHN0X2dlb21ldHJ5KHNlbGVjdGVkX2NvdW50eSkKcGxvdChzZWxlY3RlZF9jb3VudHkpCmBgYApJJ2xsIHVzZSB0aGVzZSBzaGFwZWZpbGVzIHRvIGV4dHJhY3QgZGF0YSBzcGF0aWFsbHkgZnJvbSBteSByYXN0ZXIgZGF0YXNldC4KCkxvYWRpbmcgYW5kIHNldHRpbmcgdXAgbmV0Q0RGIGZpbGU6CgpgYGB7cn0KbmNwYXRoIDwtICIvVXNlcnMvaXNhYWNiZWxsL0RvY3VtZW50cy9nZW9nNDkwL2ZpbmFsX3Byb2ovZGF0YS8iCm5jbmFtZSA8LSAiMjAwMHRvMjAyNCIKbmNmbmFtZSA8LSBwYXN0ZShuY3BhdGgsIG5jbmFtZSwgIi5uYyIsIHNlcD0iIikKbmNpbiA8LSBuY19vcGVuKG5jZm5hbWUpCmRuYW1lIDwtICJkYWlseV9tZWFuX3BhbG1lcl9kcm91Z2h0X3NldmVyaXR5X2luZGV4Igpsb24gPC0gbmN2YXJfZ2V0KG5jaW4sImxvbiIpCm5sb24gPC0gZGltKGxvbikKbGF0IDwtIG5jdmFyX2dldChuY2luLCJsYXQiKQpubGF0IDwtIGRpbShsYXQpCnRpdGxlIDwtIG5jYXR0X2dldChuY2luLDAsInRpdGxlIikKaW5zdGl0dXRpb24gPC0gbmNhdHRfZ2V0KG5jaW4sMCwiaW5zdGl0dXRpb24iKQpkYXRhc291cmNlIDwtIG5jYXR0X2dldChuY2luLDAsInNvdXJjZSIpCnJlZmVyZW5jZXMgPC0gbmNhdHRfZ2V0KG5jaW4sMCwicmVmZXJlbmNlcyIpCmhpc3RvcnkgPC0gbmNhdHRfZ2V0KG5jaW4sMCwiaGlzdG9yeSIpCkNvbnZlbnRpb25zIDwtIG5jYXR0X2dldChuY2luLDAsIkNvbnZlbnRpb25zIikKcGRzaV9hcnJheSA8LSBuY3Zhcl9nZXQobmNpbixkbmFtZSkKZGxuYW1lIDwtIG5jYXR0X2dldChuY2luLGRuYW1lLCJsb25nX25hbWUiKQpkdW5pdHMgPC0gbmNhdHRfZ2V0KG5jaW4sZG5hbWUsInVuaXRzIikKZmlsbHZhbHVlIDwtIG5jYXR0X2dldChuY2luLGRuYW1lLCJfRmlsbFZhbHVlIikKZGltKHBkc2lfYXJyYXkpCmBgYAoKCkdldHRpbmcgdGltZSBmcm9tIG5ldENERjoKCmBgYHtyfQp0aW1lIDwtIG5jdmFyX2dldChuY2luLCJkYXkiKQp0dW5pdHMgPC0gbmNhdHRfZ2V0KG5jaW4sImRheSIsInVuaXRzIikKbnQgPC0gZGltKHRpbWUpCmNmIDwtIENGdGltZSh0dW5pdHMkdmFsdWUsIGNhbGVuZGFyID0gInByb2xlcHRpY19ncmVnb3JpYW4iLCB0aW1lKSAKdGltZXN0YW1wcyA8LSBDRnRpbWVzdGFtcChjZikKbW9udGhzID0gQ0ZmYWN0b3IoY2YsIm1vbnRoIikKdGltZV9jZiA8LSBDRnBhcnNlKGNmLCB0aW1lc3RhbXBzKQpoZWFkKHRpbWVfY2YpCmBgYApBcyB5b3UgY2FuIHNlZSwgdGhlIGZpbGUgY29udGFpbnMgbWVhc3VyZW1lbnRzIHJlY3VycmluZyBldmVyeSA1IGRheXMuCgoKTWFraW5nIGEgcmFzdGVyIGZyb20gbmV0Q0RGLCBhbmQgYXBwbHlpbmcgdGltZSB2YWx1ZXMgdG8gaXQ6CgpgYGB7cn0KcGRzaV9yYXN0ZXIgPC0gcmFzdChuY2ZuYW1lKQpuYW1lcyhwZHNpX3Jhc3RlcikgPC0gdGltZXN0YW1wcwpzdGFtcHNfZGF0ZSA8LSBhcy5EYXRlKHRpbWVzdGFtcHMpCnRpbWUocGRzaV9yYXN0ZXIpIDwtIHN0YW1wc19kYXRlCmBgYApUaGlzIGFsbG93cyBtZSB0byBwYXJzZSB0aGUgcmFzdGVyIHN0YWNrIGJ5IGRhdGUuCgoKR2V0dGluZyB0aGUgb3ZlcmFsbCBtZWFuIFBEU0kgdmFsdWVzIGZvciB0aGUgd2hvbGUgMjAwMC0yMDI0IHJhc3RlciBzdGFjazoKCmBgYHtyfQptZWFuX3Jhc3RlciA9IG1lYW4ocGRzaV9yYXN0ZXIpCnBsb3QobWVhbl9yYXN0ZXIpCmBgYAoKIyMgR2VvZ3JhcGhpYyBhbmFseXNpcwoKTm93IHRoYXQgSSBoYXZlIHRoZSBjb3VudHkgYW5kIHN0YXRlIGdlb21ldHJpZXMsIEkgY2FuIHVzZSB0aGUgYGV4YWN0X2V4dHJhY3QoKWAgZnVuY3Rpb24gdG8gcHVsbCB0aGUgZGF0YSBmcm9tIHRoZSByYXN0ZXIgaW50byB0aGUgdmVjdG9yLiBUaGlzIGNvbWVzIGZyb20gdGhlIGBleGFjdGV4dHJhdHJgIGxpYnJhcnksIGFuZCBpdCBhbGxvd3MgbWUgdG8gd3JpdGUgdGhlIGF2ZXJhZ2UgdmFsdWUgd2l0aGluIGVhY2ggcG9seWdvbiB0byBhIG5ldyBjb2x1bW4gb24gdGhlIHZlY3RvciBkYXRhLgoKYGBge3IgcmVzdWx0cz0naGlkZScsZmlnLmtlZXA9J2FsbCd9CnNlbGVjdGVkX3NmJG1lYW5fYWxsdGltZSA8LSBleGFjdF9leHRyYWN0KG1lYW5fcmFzdGVyLCBzZWxlY3RlZF9zZiwgJ21lYW4nKQpwbG90KHNlbGVjdGVkX3NmWywnbWVhbl9hbGx0aW1lJ10pCmBgYAoKYGBge3IgcmVzdWx0cz0naGlkZScsZmlnLmtlZXA9J2FsbCd9CnNlbGVjdGVkX2NvdW50eSRtZWFuX2FsbHRpbWUgPC0gZXhhY3RfZXh0cmFjdChtZWFuX3Jhc3Rlciwgc2VsZWN0ZWRfY291bnR5LCAnbWVhbicpCnBsb3Qoc2VsZWN0ZWRfY291bnR5WywnbWVhbl9hbGx0aW1lJ10pCmBgYAoobm90ZSB0aGF0IHRoZSBzY2FsZXMgYXJlIGRpZmZlcmVudCBmb3IgYm90aCBwbG90cykKCkluIHRoZSBzdGF0ZSBwbG90cywgeW91IGNhbiBzZWUgdGhhdCBldmVyeSBzdGF0ZSBpbiB0aGUgd2VzdCBoYXMgc2VlbiBzdHJvbmdlciBkcnkgY29uZGl0aW9ucyB0aGFuIHdldCBjb25kaXRpb25zIHNpbmNlIDIwMDAuIE1vbnRhbmEgbG9va3MgdG8gYmUgdGhlIGxlYXN0IGFmZmVjdGVkLCBhbmQgT3JlZ29uIGhhcyBoYWQgdGhlIGRyaWVzdCBhdmVyYWdlIGNvbmRpdGlvbnMgKHJlbGF0aXZlIHRvIG5vcm1hbCkuCgoKTmV4dCwgSSdsbCBzcGxpdCB1cCB0aGUgcmFzdGVyIHN0YWNrIGludG8gaW5kaXZpZHVhbCB5ZWFycywgdGhlbiB1c2UgYGV4YWN0X2V4dHJhY3QoKWAgdG8gZ2V0IHRoZSBtZWFucyBmb3IgZWFjaCB5ZWFyIGludG8gdGhlIHN0YXRlIGFuZCBjb3VudHkgc2hhcGVmaWxlcy4KCmBgYHtyIGVjaG89VFJVRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KeWVhcl9saSA8LSBzZXEoMjAwMCwyMDI0KQpmb3IgKGkgaW4geWVhcl9saSl7CmkgPC0gdG9TdHJpbmcoaSkKYSA8LSBwZHNpX3Jhc3RlcltpXQpzZWxlY3RlZF9zZlssIGldIDwtIGV4YWN0X2V4dHJhY3QoYSwgc2VsZWN0ZWRfc2YsICdtZWFuJykKc2VsZWN0ZWRfY291bnR5WywgaV0gPC0gZXhhY3RfZXh0cmFjdChhLCBzZWxlY3RlZF9jb3VudHksICdtZWFuJykKfQpgYGAKKFRoaXMgbWlnaHQgbm90IGJlIHRoZSBtb3N0IGVmZmljaWVudCBtZXRob2QsIGJ1dCBpdCB3b3JrcyB3ZWxsIGVub3VnaCkKCgpIZXJlJ3MgYSBxdWljayB0aW1lIHNlcmllcyBwbG90IG9mIHRoZSBhdmVyYWdlIFBEU0kgZm9yIGVhY2ggc3RhdGU6CgpgYGB7ciByZXN1bHRzPSdoaWRlJyxmaWcua2VlcD0nYWxsJ30Kc3RhdGVzX2RmIDwtIHN0X2Ryb3BfZ2VvbWV0cnkoc2VsZWN0ZWRfc2YpCmRyb3BzIDwtIGMoIklEIiwibWVhbl9hbGx0aW1lIikKc2VsZWN0X3N0YXRlc19kZiA8LSBzdGF0ZXNfZGZbICwgIShuYW1lcyhzdGF0ZXNfZGYpICVpbiUgZHJvcHMpXQpzZWxlY3Rfc3RhdGVzX2RmJG1ldGFkYXRhIDwtIHJvdy5uYW1lcyhzZWxlY3Rfc3RhdGVzX2RmKQpzZWxlY3Rfc3RhdGVzX2RmIDwtIG1lbHQoc2VsZWN0X3N0YXRlc19kZiwgIm1ldGFkYXRhIikKZ2dwbG90KHNlbGVjdF9zdGF0ZXNfZGYsIGFlcyh2YXJpYWJsZSwgdmFsdWUsIGdyb3VwID0gbWV0YWRhdGEsIGNvbG9yID0gbWV0YWRhdGEpKSArIApnZW9tX2xpbmUoKQpgYGAKCgpMZXQncyBwbG90IHRoZSBhdmVyYWdlIFBEU0kgcmFzdGVycyBmb3IgYSBjb3VwbGUgb2YgeWVhcnM6CgpgYGB7cn0KcmFzdGVyXzIwMDAgPC0gbWVhbihwZHNpX3Jhc3RlclsiMjAwMCJdKQpwbG90KHJhc3Rlcl8yMDAwLAogICAgIGJyZWFrcz1jKC00LC0zLC0yLC0xLDAsMSwyLDMsNCksCiAgICAgY29sPWJyZXdlci5wYWwoOSwgIlJkWWxHbiIpLAogICAgIG1haW49Ik1lYW4gUERTSTogMjAwMCIKICAgICApCmBgYApgYGB7cn0KcmFzdGVyXzIwMjMgPC0gbWVhbihwZHNpX3Jhc3RlclsiMjAyMyJdKQpwbG90KHJhc3Rlcl8yMDIzLAogICAgIGJyZWFrcz1jKC01LC00LC0zLC0yLC0xLDAsMSwyLDMsNCw1KSwKICAgICBjb2w9YnJld2VyLnBhbCgxMSwgIlJkWWxHbiIpLAogICAgIG1haW49Ik1lYW4gUERTSTogMjAyMyIKICAgICApCmBgYApGb3IgcmVmZXJlbmNlLCB0aGUgTmF0aW9uYWwgRHJvdWdodCBNaXRpZ2F0aW9uIENlbnRlciBjb25zaWRlcnMgUERTSSB2YWx1ZXMgZnJvbSAtMyB0byAtNCAnc2V2ZXJlIGRyb3VnaHQsJyBhbmQgdmFsdWVzIGFib3ZlIC00IGFzICdleHRyZW1lIGRyb3VnaHQuJwo=