This is an R Markdown Notebook. When you execute code within the notebook, the results appear beneath the code.

Try executing this chunk by clicking the Run button within the chunk or by placing your cursor inside it and pressing Ctrl+Shift+Enter.

debo llamar los datos

dir.create('data', showWarnings = FALSE)
if (!file.exists('data/rs/samples.rds')) {
    download.file('https://biogeo.ucdavis.edu/data/rspatial/rsdata.zip', dest = 'G:/Cursos/PR/rsdata/rsdata/data/rsdata.zip')
    unzip('data/rsdata.zip', exdir='data')
}

Add a new chunk by clicking the Insert Chunk button on the toolbar or by pressing Ctrl+Alt+I.

When you save the notebook, an HTML file containing the code and output will be saved alongside it (click the Preview button or press Ctrl+Shift+K to preview the HTML file).

The preview shows you a rendered HTML copy of the contents of the editor. Consequently, unlike Knit, Preview does not run any R code chunks. Instead, the output of the chunk when it was last run in the editor is displayed.

G:

getwd() 

definio la ruta


library (raster)

# Blue
b2 = raster('./rsdata/data/rs/LC08_044034_20170614_B2.tif')
b2
class      : RasterLayer 
dimensions : 1245, 1497, 1863765  (nrow, ncol, ncell)
resolution : 30, 30  (x, y)
extent     : 594090, 639000, 4190190, 4227540  (xmin, xmax, ymin, ymax)
crs        : +proj=utm +zone=10 +datum=WGS84 +units=m +no_defs +ellps=WGS84 +towgs84=0,0,0 
source     : G:/Cursos/PR/rsdata/data/rs/LC08_044034_20170614_B2.tif 
names      : LC08_044034_20170614_B2 
values     : 0.0748399, 0.7177562  (min, max)

# Green
b3 = raster('./rsdata/data/rs/LC08_044034_20170614_B3.tif')
b3
class      : RasterLayer 
dimensions : 1245, 1497, 1863765  (nrow, ncol, ncell)
resolution : 30, 30  (x, y)
extent     : 594090, 639000, 4190190, 4227540  (xmin, xmax, ymin, ymax)
crs        : +proj=utm +zone=10 +datum=WGS84 +units=m +no_defs +ellps=WGS84 +towgs84=0,0,0 
source     : G:/Cursos/PR/rsdata/data/rs/LC08_044034_20170614_B3.tif 
names      : LC08_044034_20170614_B3 
values     : 0.04259216, 0.6924697  (min, max)
# Red
b4 = raster('./rsdata/data/rs/LC08_044034_20170614_B4.tif')
b4
class      : RasterLayer 
dimensions : 1245, 1497, 1863765  (nrow, ncol, ncell)
resolution : 30, 30  (x, y)
extent     : 594090, 639000, 4190190, 4227540  (xmin, xmax, ymin, ymax)
crs        : +proj=utm +zone=10 +datum=WGS84 +units=m +no_defs +ellps=WGS84 +towgs84=0,0,0 
source     : G:/Cursos/PR/rsdata/data/rs/LC08_044034_20170614_B4.tif 
names      : LC08_044034_20170614_B4 
values     : 0.02084067, 0.7861769  (min, max)

Near Infrared (NIR)

b5 = raster(‘./rsdata/data/rs/LC08_044034_20170614_B5.tif’) b2

# Near Infrared (NIR)
b5 = raster('./rsdata/data/rs/LC08_044034_20170614_B5.tif')
b5
class      : RasterLayer 
dimensions : 1245, 1497, 1863765  (nrow, ncol, ncell)
resolution : 30, 30  (x, y)
extent     : 594090, 639000, 4190190, 4227540  (xmin, xmax, ymin, ymax)
crs        : +proj=utm +zone=10 +datum=WGS84 +units=m +no_defs +ellps=WGS84 +towgs84=0,0,0 
source     : G:/Cursos/PR/rsdata/data/rs/LC08_044034_20170614_B5.tif 
names      : LC08_044034_20170614_B5 
values     : 0.0008457669, 1.012432  (min, max)
b2
class      : RasterLayer 
dimensions : 1245, 1497, 1863765  (nrow, ncol, ncell)
resolution : 30, 30  (x, y)
extent     : 594090, 639000, 4190190, 4227540  (xmin, xmax, ymin, ymax)
crs        : +proj=utm +zone=10 +datum=WGS84 +units=m +no_defs +ellps=WGS84 +towgs84=0,0,0 
source     : G:/Cursos/PR/rsdata/data/rs/LC08_044034_20170614_B2.tif 
names      : LC08_044034_20170614_B2 
values     : 0.0748399, 0.7177562  (min, max)
## class      : RasterLayer
## dimensions : 1245, 1497, 1863765  (nrow, ncol, ncell)
## resolution : 30, 30  (x, y)
## extent     : 594090, 639000, 4190190, 4227540  (xmin, xmax, ymin, ymax)
## crs        : +proj=utm +zone=10 +datum=WGS84 +units=m +no_defs +ellps=WGS84 +towgs84=0,0,0
## source     : c:/github/rspatial/rspatial-web/source/rs/_R/data/rs/LC08_044034_20170614_B2.tif
## names      : LC08_044034_20170614_B2
## values     : 0.0748399, 0.7177562  (min, max)
# coordinate reference system (CRS)
crs(b2)
CRS arguments:
 +proj=utm +zone=10 +datum=WGS84 +units=m +no_defs +ellps=WGS84 +towgs84=0,0,0 
## CRS arguments:
##  +proj=utm +zone=10 +datum=WGS84 +units=m +no_defs +ellps=WGS84
## +towgs84=0,0,0
# Number of cells, rows, columns
ncell(b2)
[1] 1863765
## [1] 1863765
dim(b2)
[1] 1245 1497    1
## [1] 1245 1497    1
# spatial resolution
res(b2)
[1] 30 30
## [1] 30 30
# Number of bands
nlayers(b2)
[1] 1
## [1] 1
# Do the bands have the same extent, number of rows and columns, projection, resolution, and origin
compareRaster(b2,b3)
[1] TRUE
## [1] TRUE
s <- stack(b5, b4, b3)
# Check the properties of the RasterStack
s
class      : RasterStack 
dimensions : 1245, 1497, 1863765, 3  (nrow, ncol, ncell, nlayers)
resolution : 30, 30  (x, y)
extent     : 594090, 639000, 4190190, 4227540  (xmin, xmax, ymin, ymax)
crs        : +proj=utm +zone=10 +datum=WGS84 +units=m +no_defs +ellps=WGS84 +towgs84=0,0,0 
names      : LC08_044034_20170614_B5, LC08_044034_20170614_B4, LC08_044034_20170614_B3 
min values :            0.0008457669,            0.0208406653,            0.0425921641 
max values :               1.0124315,               0.7861769,               0.6924697 
## class      : RasterStack
## dimensions : 1245, 1497, 1863765, 3  (nrow, ncol, ncell, nlayers)
## resolution : 30, 30  (x, y)
## extent     : 594090, 639000, 4190190, 4227540  (xmin, xmax, ymin, ymax)
## crs        : +proj=utm +zone=10 +datum=WGS84 +units=m +no_defs +ellps=WGS84 +towgs84=0,0,0
## names      : LC08_044034_20170614_B5, LC08_044034_20170614_B4, LC08_044034_20170614_B3
## min values :            0.0008457669,            0.0208406653,            0.0425921641
## max values :               1.0124315,               0.7861769,               0.6924697
# first create a list of raster layers to use
filenames <- paste0('./rsdata/data/rs/LC08_044034_20170614_B', 1:11, ".tif")
filenames
 [1] "./rsdata/data/rs/LC08_044034_20170614_B1.tif"  "./rsdata/data/rs/LC08_044034_20170614_B2.tif"  "./rsdata/data/rs/LC08_044034_20170614_B3.tif" 
 [4] "./rsdata/data/rs/LC08_044034_20170614_B4.tif"  "./rsdata/data/rs/LC08_044034_20170614_B5.tif"  "./rsdata/data/rs/LC08_044034_20170614_B6.tif" 
 [7] "./rsdata/data/rs/LC08_044034_20170614_B7.tif"  "./rsdata/data/rs/LC08_044034_20170614_B8.tif"  "./rsdata/data/rs/LC08_044034_20170614_B9.tif" 
[10] "./rsdata/data/rs/LC08_044034_20170614_B10.tif" "./rsdata/data/rs/LC08_044034_20170614_B11.tif"
##  [1] "data/rs/LC08_044034_20170614_B1.tif"
##  [2] "data/rs/LC08_044034_20170614_B2.tif"
##  [3] "data/rs/LC08_044034_20170614_B3.tif"
##  [4] "data/rs/LC08_044034_20170614_B4.tif"
##  [5] "data/rs/LC08_044034_20170614_B5.tif"
##  [6] "data/rs/LC08_044034_20170614_B6.tif"
##  [7] "data/rs/LC08_044034_20170614_B7.tif"
##  [8] "data/rs/LC08_044034_20170614_B8.tif"
##  [9] "data/rs/LC08_044034_20170614_B9.tif"
## [10] "data/rs/LC08_044034_20170614_B10.tif"
## [11] "data/rs/LC08_044034_20170614_B11.tif"
landsat = stack(filenames)
landsat
class      : RasterStack 
dimensions : 1245, 1497, 1863765, 11  (nrow, ncol, ncell, nlayers)
resolution : 30, 30  (x, y)
extent     : 594090, 639000, 4190190, 4227540  (xmin, xmax, ymin, ymax)
crs        : +proj=utm +zone=10 +datum=WGS84 +units=m +no_defs +ellps=WGS84 +towgs84=0,0,0 
names      : LC08_044034_20170614_B1, LC08_044034_20170614_B2, LC08_044034_20170614_B3, LC08_044034_20170614_B4, LC08_044034_20170614_B5, LC08_044034_20170614_B6, LC08_044034_20170614_B7, LC08_044034_20170614_B8, LC08_044034_20170614_B9, LC08_044034_20170614_B10, LC08_044034_20170614_B11 
min values :            9.641791e-02,            7.483990e-02,            4.259216e-02,            2.084067e-02,            8.457669e-04,           -7.872183e-03,           -5.052945e-03,            3.931751e-02,           -4.337332e-04,             2.897978e+02,             2.885000e+02 
max values :              0.73462820,              0.71775615,              0.69246972,              0.78617686,              1.01243150,              1.04320455,              1.11793602,              0.82673049,              0.03547901,             322.43139648,             317.99530029 
## class      : RasterStack
## dimensions : 1245, 1497, 1863765, 11  (nrow, ncol, ncell, nlayers)
## resolution : 30, 30  (x, y)
## extent     : 594090, 639000, 4190190, 4227540  (xmin, xmax, ymin, ymax)
## crs        : +proj=utm +zone=10 +datum=WGS84 +units=m +no_defs +ellps=WGS84 +towgs84=0,0,0
## names      : LC08_044034_20170614_B1, LC08_044034_20170614_B2, LC08_044034_20170614_B3, LC08_044034_20170614_B4, LC08_044034_20170614_B5, LC08_044034_20170614_B6, LC08_044034_20170614_B7, LC08_044034_20170614_B8, LC08_044034_20170614_B9, LC08_044034_20170614_B10, LC08_044034_20170614_B11
## min values :            9.641791e-02,            7.483990e-02,            4.259216e-02,            2.084067e-02,            8.457669e-04,           -7.872183e-03,           -5.052945e-03,            3.931751e-02,           -4.337332e-04,             2.897978e+02,             2.885000e+02
## max values :              0.73462820,              0.71775615,              0.69246972,      
par(mfrow = c(2,2))
plot(b2, main = "Blue", col = gray(0:100 / 100))
plot(b3, main = "Green", col = gray(0:100 / 100))
plot(b4, main = "Red", col = gray(0:100 / 100))
plot(b5, main = "NIR", col = gray(0:100 / 100))

landsatRGB <- stack(b4, b3, b2)
plotRGB(landsatRGB, axes = TRUE, stretch = "lin", main = "Landsat True Color Composite")

par(mfrow = c(1,2))
plotRGB(landsatRGB, axes=TRUE, stretch="lin", main="Landsat True Color Composite")
landsatFCC <- stack(b5, b4, b3)
plotRGB(landsatFCC, axes=TRUE, stretch="lin", main="Landsat False Color Composite")

# select first 3 bands only
landsatsub1 <- subset(landsat, 1:3)
# same
landsatsub2 <- landsat[[1:3]]
# Number of bands in the original and new data
nlayers(landsat)
[1] 11
## [1] 11
nlayers(landsatsub1)
[1] 3
## [1] 3
nlayers(landsatsub2)
[1] 3
## [1] 3
landsat <- subset(landsat, 1:7)
names(landsat)
[1] "LC08_044034_20170614_B1" "LC08_044034_20170614_B2" "LC08_044034_20170614_B3" "LC08_044034_20170614_B4" "LC08_044034_20170614_B5" "LC08_044034_20170614_B6"
[7] "LC08_044034_20170614_B7"
## [1] "LC08_044034_20170614_B1" "LC08_044034_20170614_B2"
## [3] "LC08_044034_20170614_B3" "LC08_044034_20170614_B4"
## [5] "LC08_044034_20170614_B5" "LC08_044034_20170614_B6"
## [7] "LC08_044034_20170614_B7"
names(landsat) <- c('ultra-blue', 'blue', 'green', 'red', 'NIR', 'SWIR1', 'SWIR2')
names(landsat)
[1] "ultra.blue" "blue"       "green"      "red"        "NIR"        "SWIR1"      "SWIR2"     
## [1] "ultra.blue" "blue"       "green"      "red"        "NIR"
## [6] "SWIR1"      "SWIR2"
# Using extent
extent(landsat)
class      : Extent 
xmin       : 594090 
xmax       : 639000 
ymin       : 4190190 
ymax       : 4227540 
## class      : Extent
## xmin       : 594090
## xmax       : 639000
## ymin       : 4190190
## ymax       : 4227540
e <- extent(624387, 635752, 4200047, 4210939)
# crop landsat by the extent
landsatcrop <- crop(landsat, e)
x <- writeRaster(landsatcrop, filename="cropped-landsat.tif", overwrite=TRUE)
writeRaster(landsatcrop, filename="cropped-landsat.grd", overwrite=TRUE)

pairs(landsatcrop[[1:2]], main = "Ultra-blue versus Blue")

pairs(landsatcrop[[4:5]], main = "Red versus NIR")

# load the polygons with land use land cover information
samp <- readRDS('./rsdata/data/rs/samples.rds')
# generate 300 point samples from the polygons
ptsamp <- spsample(samp, 300, type='regular')
# add the land cover class to the points
ptsamp$class <- over(ptsamp, samp)$class
# extract values with points
df <- extract(landsat, ptsamp)
# To see some of the reflectance values
head(df)
     ultra.blue      blue     green       red       NIR     SWIR1     SWIR2
[1,]  0.1394872 0.1241549 0.1140490 0.1182128 0.1937900 0.2363822 0.1976068
[2,]  0.1363426 0.1197091 0.1095816 0.1129864 0.1844866 0.2381171 0.2014020
[3,]  0.1354318 0.1336969 0.1478582 0.2043296 0.3610792 0.3619901 0.2104669
[4,]  0.1269958 0.1180827 0.1185164 0.1564026 0.2825093 0.3155811 0.1909925
[5,]  0.1429570 0.1458413 0.1698265 0.2372280 0.3815729 0.4079219 0.2431484
[6,]  0.1380125 0.1214441 0.1093647 0.1094515 0.1923370 0.2201391 0.1791083
##      ultra.blue      blue      green        red       NIR     SWIR1
## [1,]  0.1367547 0.1197091 0.10429009 0.10507080 0.1670290 0.2161921
## [2,]  0.1343041 0.1163694 0.09889016 0.09752392 0.1686988 0.2066501
## [3,]  0.1383812 0.1375354 0.15377855 0.20988137 0.3602552 0.3594528
## [4,]  0.1293813 0.1254127 0.13582218 0.18546245 0.3094872 0.2950440
## [5,]  0.1481184 0.1531496 0.17986734 0.24896033 0.3882957 0.4010257
## [6,]  0.1342608 0.1158490 0.10029978 0.09932390 0.1649471 0.2108356
##          SWIR2
## [1,] 0.1817324
## [2,] 0.1710843
## [3,] 0.2157801
## [4,] 0.1653591
## [5,] 0.2454254
## [6,] 0.1800408
ms <- aggregate(df, list(ptsamp$class), mean)
# instead of the first column, we use row names
rownames(ms) <- ms[,1]
ms <- ms[,-1]
ms
##          ultra.blue      blue      green       red        NIR      SWIR1
## built     0.1864925 0.1795371 0.17953317 0.1958414 0.25448447 0.24850197
## cropland  0.1129813 0.0909645 0.08596722 0.0550344 0.48335462 0.16142085
## fallow    0.1319198 0.1164869 0.10453764 0.1151243 0.18012962 0.23139228
## open      0.1388014 0.1375235 0.15273163 0.2066425 0.34476670 0.35820877
## water     0.1336242 0.1165728 0.09922726 0.0785947 0.04909201 0.03360047
##               SWIR2
## built    0.20001306
## cropland 0.07314186
## fallow   0.19143030
## open     0.21346343
## water    0.02723398
# Create a vector of color for the land cover classes for use in plotting
mycolor <- c('darkred', 'yellow', 'burlywood', 'cyan', 'blue')
#transform ms from a data.frame to a matrix
ms <- as.matrix(ms)
# First create an empty plot
plot(0, ylim=c(0,0.6), xlim = c(1,7), type='n', xlab="Bands", ylab = "Reflectance")
# add the different classes
for (i in 1:nrow(ms)){
  lines(ms[i,], type = "l", lwd = 3, lty = 1, col = mycolor[i])
}
# Title
title(main="Spectral Profile from Landsat", font.main = 2)
# Legend
legend("topleft", rownames(ms),
       cex=0.8, col=mycolor, lty = 1, lwd =3, bty = "n")

LS0tDQp0aXRsZTogImltYWdlbiBjYWxpZm9ybmlhIg0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCg0KVGhpcyBpcyBhbiBbUiBNYXJrZG93bl0oaHR0cDovL3JtYXJrZG93bi5yc3R1ZGlvLmNvbSkgTm90ZWJvb2suIFdoZW4geW91IGV4ZWN1dGUgY29kZSB3aXRoaW4gdGhlIG5vdGVib29rLCB0aGUgcmVzdWx0cyBhcHBlYXIgYmVuZWF0aCB0aGUgY29kZS4gDQoNClRyeSBleGVjdXRpbmcgdGhpcyBjaHVuayBieSBjbGlja2luZyB0aGUgKlJ1biogYnV0dG9uIHdpdGhpbiB0aGUgY2h1bmsgb3IgYnkgcGxhY2luZyB5b3VyIGN1cnNvciBpbnNpZGUgaXQgYW5kIHByZXNzaW5nICpDdHJsK1NoaWZ0K0VudGVyKi4gDQoNCiMjIyMgZGVibyBsbGFtYXIgbG9zIGRhdG9zDQoNCmBgYHtyfQ0KZGlyLmNyZWF0ZSgnZGF0YScsIHNob3dXYXJuaW5ncyA9IEZBTFNFKQ0KaWYgKCFmaWxlLmV4aXN0cygnZGF0YS9ycy9zYW1wbGVzLnJkcycpKSB7DQogICAgZG93bmxvYWQuZmlsZSgnaHR0cHM6Ly9iaW9nZW8udWNkYXZpcy5lZHUvZGF0YS9yc3BhdGlhbC9yc2RhdGEuemlwJywgZGVzdCA9ICdHOkN1cnNvcy9QUi9yc2RhdGEvcnNkYXRhL2RhdGEvcnMuemlwJykNCiAgICB1bnppcCgnZGF0YS9yc2RhdGEuemlwJywgZXhkaXI9J2RhdGEnKQ0KfQ0KYGBgDQoNCg0KQWRkIGEgbmV3IGNodW5rIGJ5IGNsaWNraW5nIHRoZSAqSW5zZXJ0IENodW5rKiBidXR0b24gb24gdGhlIHRvb2xiYXIgb3IgYnkgcHJlc3NpbmcgKkN0cmwrQWx0K0kqLg0KDQpXaGVuIHlvdSBzYXZlIHRoZSBub3RlYm9vaywgYW4gSFRNTCBmaWxlIGNvbnRhaW5pbmcgdGhlIGNvZGUgYW5kIG91dHB1dCB3aWxsIGJlIHNhdmVkIGFsb25nc2lkZSBpdCAoY2xpY2sgdGhlICpQcmV2aWV3KiBidXR0b24gb3IgcHJlc3MgKkN0cmwrU2hpZnQrSyogdG8gcHJldmlldyB0aGUgSFRNTCBmaWxlKS4NCg0KVGhlIHByZXZpZXcgc2hvd3MgeW91IGEgcmVuZGVyZWQgSFRNTCBjb3B5IG9mIHRoZSBjb250ZW50cyBvZiB0aGUgZWRpdG9yLiBDb25zZXF1ZW50bHksIHVubGlrZSAqS25pdCosICpQcmV2aWV3KiBkb2VzIG5vdCBydW4gYW55IFIgY29kZSBjaHVua3MuIEluc3RlYWQsIHRoZSBvdXRwdXQgb2YgdGhlIGNodW5rIHdoZW4gaXQgd2FzIGxhc3QgcnVuIGluIHRoZSBlZGl0b3IgaXMgZGlzcGxheWVkLg0KDQojIyMgRzpcQ3Vyc29zXFBSXHJzZGF0YVxkYXRhXHJzDQoNCiMjIyANCg0KYGBge3J9DQpnZXR3ZCgpIA0KYGBgDQoNCiMjIyBkZWZpbmlvIGxhIHJ1dGENCg0KYGBge3J9DQoNCmxpYnJhcnkgKHJhc3RlcikNCg0KIyBCbHVlDQpiMiA9IHJhc3RlcignLi9yc2RhdGEvZGF0YS9ycy9MQzA4XzA0NDAzNF8yMDE3MDYxNF9CMi50aWYnKQ0KYjINCg0KYGBgDQoNCmBgYHtyfQ0KDQojIEdyZWVuDQpiMyA9IHJhc3RlcignLi9yc2RhdGEvZGF0YS9ycy9MQzA4XzA0NDAzNF8yMDE3MDYxNF9CMy50aWYnKQ0KYjMNCg0KYGBgDQoNCmBgYHtyfQ0KIyBSZWQNCmI0ID0gcmFzdGVyKCcuL3JzZGF0YS9kYXRhL3JzL0xDMDhfMDQ0MDM0XzIwMTcwNjE0X0I0LnRpZicpDQpiNA0KYGBgDQoNCiMgTmVhciBJbmZyYXJlZCAoTklSKQ0KYjUgPSByYXN0ZXIoJy4vcnNkYXRhL2RhdGEvcnMvTEMwOF8wNDQwMzRfMjAxNzA2MTRfQjUudGlmJykNCmIyDQpgYGB7cn0NCiMgTmVhciBJbmZyYXJlZCAoTklSKQ0KYjUgPSByYXN0ZXIoJy4vcnNkYXRhL2RhdGEvcnMvTEMwOF8wNDQwMzRfMjAxNzA2MTRfQjUudGlmJykNCmI1DQpgYGANCmBgYHtyfQ0KYjINCiMjIGNsYXNzICAgICAgOiBSYXN0ZXJMYXllcg0KIyMgZGltZW5zaW9ucyA6IDEyNDUsIDE0OTcsIDE4NjM3NjUgIChucm93LCBuY29sLCBuY2VsbCkNCiMjIHJlc29sdXRpb24gOiAzMCwgMzAgICh4LCB5KQ0KIyMgZXh0ZW50ICAgICA6IDU5NDA5MCwgNjM5MDAwLCA0MTkwMTkwLCA0MjI3NTQwICAoeG1pbiwgeG1heCwgeW1pbiwgeW1heCkNCiMjIGNycyAgICAgICAgOiArcHJvaj11dG0gK3pvbmU9MTAgK2RhdHVtPVdHUzg0ICt1bml0cz1tICtub19kZWZzICtlbGxwcz1XR1M4NCArdG93Z3M4ND0wLDAsMA0KIyMgc291cmNlICAgICA6IGM6L2dpdGh1Yi9yc3BhdGlhbC9yc3BhdGlhbC13ZWIvc291cmNlL3JzL19SL2RhdGEvcnMvTEMwOF8wNDQwMzRfMjAxNzA2MTRfQjIudGlmDQojIyBuYW1lcyAgICAgIDogTEMwOF8wNDQwMzRfMjAxNzA2MTRfQjINCiMjIHZhbHVlcyAgICAgOiAwLjA3NDgzOTksIDAuNzE3NzU2MiAgKG1pbiwgbWF4KQ0KYGBgDQoNCmBgYHtyfQ0KIyBjb29yZGluYXRlIHJlZmVyZW5jZSBzeXN0ZW0gKENSUykNCmNycyhiMikNCiMjIENSUyBhcmd1bWVudHM6DQojIyAgK3Byb2o9dXRtICt6b25lPTEwICtkYXR1bT1XR1M4NCArdW5pdHM9bSArbm9fZGVmcyArZWxscHM9V0dTODQNCiMjICt0b3dnczg0PTAsMCwwDQojIE51bWJlciBvZiBjZWxscywgcm93cywgY29sdW1ucw0KbmNlbGwoYjIpDQojIyBbMV0gMTg2Mzc2NQ0KZGltKGIyKQ0KIyMgWzFdIDEyNDUgMTQ5NyAgICAxDQojIHNwYXRpYWwgcmVzb2x1dGlvbg0KcmVzKGIyKQ0KIyMgWzFdIDMwIDMwDQojIE51bWJlciBvZiBiYW5kcw0KbmxheWVycyhiMikNCiMjIFsxXSAxDQojIERvIHRoZSBiYW5kcyBoYXZlIHRoZSBzYW1lIGV4dGVudCwgbnVtYmVyIG9mIHJvd3MgYW5kIGNvbHVtbnMsIHByb2plY3Rpb24sIHJlc29sdXRpb24sIGFuZCBvcmlnaW4NCmNvbXBhcmVSYXN0ZXIoYjIsYjMpDQojIyBbMV0gVFJVRQ0KYGBgDQpgYGB7cn0NCnMgPC0gc3RhY2soYjUsIGI0LCBiMykNCiMgQ2hlY2sgdGhlIHByb3BlcnRpZXMgb2YgdGhlIFJhc3RlclN0YWNrDQpzDQojIyBjbGFzcyAgICAgIDogUmFzdGVyU3RhY2sNCiMjIGRpbWVuc2lvbnMgOiAxMjQ1LCAxNDk3LCAxODYzNzY1LCAzICAobnJvdywgbmNvbCwgbmNlbGwsIG5sYXllcnMpDQojIyByZXNvbHV0aW9uIDogMzAsIDMwICAoeCwgeSkNCiMjIGV4dGVudCAgICAgOiA1OTQwOTAsIDYzOTAwMCwgNDE5MDE5MCwgNDIyNzU0MCAgKHhtaW4sIHhtYXgsIHltaW4sIHltYXgpDQojIyBjcnMgICAgICAgIDogK3Byb2o9dXRtICt6b25lPTEwICtkYXR1bT1XR1M4NCArdW5pdHM9bSArbm9fZGVmcyArZWxscHM9V0dTODQgK3Rvd2dzODQ9MCwwLDANCiMjIG5hbWVzICAgICAgOiBMQzA4XzA0NDAzNF8yMDE3MDYxNF9CNSwgTEMwOF8wNDQwMzRfMjAxNzA2MTRfQjQsIExDMDhfMDQ0MDM0XzIwMTcwNjE0X0IzDQojIyBtaW4gdmFsdWVzIDogICAgICAgICAgICAwLjAwMDg0NTc2NjksICAgICAgICAgICAgMC4wMjA4NDA2NjUzLCAgICAgICAgICAgIDAuMDQyNTkyMTY0MQ0KIyMgbWF4IHZhbHVlcyA6ICAgICAgICAgICAgICAgMS4wMTI0MzE1LCAgICAgICAgICAgICAgIDAuNzg2MTc2OSwgICAgICAgICAgICAgICAwLjY5MjQ2OTcNCmBgYA0KDQpgYGB7cn0NCiMgZmlyc3QgY3JlYXRlIGEgbGlzdCBvZiByYXN0ZXIgbGF5ZXJzIHRvIHVzZQ0KZmlsZW5hbWVzIDwtIHBhc3RlMCgnLi9yc2RhdGEvZGF0YS9ycy9MQzA4XzA0NDAzNF8yMDE3MDYxNF9CJywgMToxMSwgIi50aWYiKQ0KZmlsZW5hbWVzDQojIyAgWzFdICJkYXRhL3JzL0xDMDhfMDQ0MDM0XzIwMTcwNjE0X0IxLnRpZiINCiMjICBbMl0gImRhdGEvcnMvTEMwOF8wNDQwMzRfMjAxNzA2MTRfQjIudGlmIg0KIyMgIFszXSAiZGF0YS9ycy9MQzA4XzA0NDAzNF8yMDE3MDYxNF9CMy50aWYiDQojIyAgWzRdICJkYXRhL3JzL0xDMDhfMDQ0MDM0XzIwMTcwNjE0X0I0LnRpZiINCiMjICBbNV0gImRhdGEvcnMvTEMwOF8wNDQwMzRfMjAxNzA2MTRfQjUudGlmIg0KIyMgIFs2XSAiZGF0YS9ycy9MQzA4XzA0NDAzNF8yMDE3MDYxNF9CNi50aWYiDQojIyAgWzddICJkYXRhL3JzL0xDMDhfMDQ0MDM0XzIwMTcwNjE0X0I3LnRpZiINCiMjICBbOF0gImRhdGEvcnMvTEMwOF8wNDQwMzRfMjAxNzA2MTRfQjgudGlmIg0KIyMgIFs5XSAiZGF0YS9ycy9MQzA4XzA0NDAzNF8yMDE3MDYxNF9COS50aWYiDQojIyBbMTBdICJkYXRhL3JzL0xDMDhfMDQ0MDM0XzIwMTcwNjE0X0IxMC50aWYiDQojIyBbMTFdICJkYXRhL3JzL0xDMDhfMDQ0MDM0XzIwMTcwNjE0X0IxMS50aWYiDQpsYW5kc2F0ID0gc3RhY2soZmlsZW5hbWVzKQ0KbGFuZHNhdA0KIyMgY2xhc3MgICAgICA6IFJhc3RlclN0YWNrDQojIyBkaW1lbnNpb25zIDogMTI0NSwgMTQ5NywgMTg2Mzc2NSwgMTEgIChucm93LCBuY29sLCBuY2VsbCwgbmxheWVycykNCiMjIHJlc29sdXRpb24gOiAzMCwgMzAgICh4LCB5KQ0KIyMgZXh0ZW50ICAgICA6IDU5NDA5MCwgNjM5MDAwLCA0MTkwMTkwLCA0MjI3NTQwICAoeG1pbiwgeG1heCwgeW1pbiwgeW1heCkNCiMjIGNycyAgICAgICAgOiArcHJvaj11dG0gK3pvbmU9MTAgK2RhdHVtPVdHUzg0ICt1bml0cz1tICtub19kZWZzICtlbGxwcz1XR1M4NCArdG93Z3M4ND0wLDAsMA0KIyMgbmFtZXMgICAgICA6IExDMDhfMDQ0MDM0XzIwMTcwNjE0X0IxLCBMQzA4XzA0NDAzNF8yMDE3MDYxNF9CMiwgTEMwOF8wNDQwMzRfMjAxNzA2MTRfQjMsIExDMDhfMDQ0MDM0XzIwMTcwNjE0X0I0LCBMQzA4XzA0NDAzNF8yMDE3MDYxNF9CNSwgTEMwOF8wNDQwMzRfMjAxNzA2MTRfQjYsIExDMDhfMDQ0MDM0XzIwMTcwNjE0X0I3LCBMQzA4XzA0NDAzNF8yMDE3MDYxNF9COCwgTEMwOF8wNDQwMzRfMjAxNzA2MTRfQjksIExDMDhfMDQ0MDM0XzIwMTcwNjE0X0IxMCwgTEMwOF8wNDQwMzRfMjAxNzA2MTRfQjExDQojIyBtaW4gdmFsdWVzIDogICAgICAgICAgICA5LjY0MTc5MWUtMDIsICAgICAgICAgICAgNy40ODM5OTBlLTAyLCAgICAgICAgICAgIDQuMjU5MjE2ZS0wMiwgICAgICAgICAgICAyLjA4NDA2N2UtMDIsICAgICAgICAgICAgOC40NTc2NjllLTA0LCAgICAgICAgICAgLTcuODcyMTgzZS0wMywgICAgICAgICAgIC01LjA1Mjk0NWUtMDMsICAgICAgICAgICAgMy45MzE3NTFlLTAyLCAgICAgICAgICAgLTQuMzM3MzMyZS0wNCwgICAgICAgICAgICAgMi44OTc5NzhlKzAyLCAgICAgICAgICAgICAyLjg4NTAwMGUrMDINCiMjIG1heCB2YWx1ZXMgOiAgICAgICAgICAgICAgMC43MzQ2MjgyMCwgICAgICAgICAgICAgIDAuNzE3NzU2MTUsICAgICAgICAgICAgICAwLjY5MjQ2OTcyLCAgICAgIA0KYGBgDQpgYGB7cn0NCnBhcihtZnJvdyA9IGMoMiwyKSkNCnBsb3QoYjIsIG1haW4gPSAiQmx1ZSIsIGNvbCA9IGdyYXkoMDoxMDAgLyAxMDApKQ0KcGxvdChiMywgbWFpbiA9ICJHcmVlbiIsIGNvbCA9IGdyYXkoMDoxMDAgLyAxMDApKQ0KcGxvdChiNCwgbWFpbiA9ICJSZWQiLCBjb2wgPSBncmF5KDA6MTAwIC8gMTAwKSkNCnBsb3QoYjUsIG1haW4gPSAiTklSIiwgY29sID0gZ3JheSgwOjEwMCAvIDEwMCkpDQpgYGANCmBgYHtyfQ0KbGFuZHNhdFJHQiA8LSBzdGFjayhiNCwgYjMsIGIyKQ0KcGxvdFJHQihsYW5kc2F0UkdCLCBheGVzID0gVFJVRSwgc3RyZXRjaCA9ICJsaW4iLCBtYWluID0gIkxhbmRzYXQgVHJ1ZSBDb2xvciBDb21wb3NpdGUiKQ0KYGBgDQpgYGB7cn0NCnBhcihtZnJvdyA9IGMoMSwyKSkNCnBsb3RSR0IobGFuZHNhdFJHQiwgYXhlcz1UUlVFLCBzdHJldGNoPSJsaW4iLCBtYWluPSJMYW5kc2F0IFRydWUgQ29sb3IgQ29tcG9zaXRlIikNCmxhbmRzYXRGQ0MgPC0gc3RhY2soYjUsIGI0LCBiMykNCnBsb3RSR0IobGFuZHNhdEZDQywgYXhlcz1UUlVFLCBzdHJldGNoPSJsaW4iLCBtYWluPSJMYW5kc2F0IEZhbHNlIENvbG9yIENvbXBvc2l0ZSIpDQpgYGANCmBgYHtyfQ0KIyBzZWxlY3QgZmlyc3QgMyBiYW5kcyBvbmx5DQpsYW5kc2F0c3ViMSA8LSBzdWJzZXQobGFuZHNhdCwgMTozKQ0KIyBzYW1lDQpsYW5kc2F0c3ViMiA8LSBsYW5kc2F0W1sxOjNdXQ0KIyBOdW1iZXIgb2YgYmFuZHMgaW4gdGhlIG9yaWdpbmFsIGFuZCBuZXcgZGF0YQ0KbmxheWVycyhsYW5kc2F0KQ0KIyMgWzFdIDExDQpubGF5ZXJzKGxhbmRzYXRzdWIxKQ0KIyMgWzFdIDMNCm5sYXllcnMobGFuZHNhdHN1YjIpDQojIyBbMV0gMw0KYGBgDQpgYGB7cn0NCmxhbmRzYXQgPC0gc3Vic2V0KGxhbmRzYXQsIDE6NykNCmBgYA0KYGBge3J9DQpuYW1lcyhsYW5kc2F0KQ0KIyMgWzFdICJMQzA4XzA0NDAzNF8yMDE3MDYxNF9CMSIgIkxDMDhfMDQ0MDM0XzIwMTcwNjE0X0IyIg0KIyMgWzNdICJMQzA4XzA0NDAzNF8yMDE3MDYxNF9CMyIgIkxDMDhfMDQ0MDM0XzIwMTcwNjE0X0I0Ig0KIyMgWzVdICJMQzA4XzA0NDAzNF8yMDE3MDYxNF9CNSIgIkxDMDhfMDQ0MDM0XzIwMTcwNjE0X0I2Ig0KIyMgWzddICJMQzA4XzA0NDAzNF8yMDE3MDYxNF9CNyINCm5hbWVzKGxhbmRzYXQpIDwtIGMoJ3VsdHJhLWJsdWUnLCAnYmx1ZScsICdncmVlbicsICdyZWQnLCAnTklSJywgJ1NXSVIxJywgJ1NXSVIyJykNCm5hbWVzKGxhbmRzYXQpDQojIyBbMV0gInVsdHJhLmJsdWUiICJibHVlIiAgICAgICAiZ3JlZW4iICAgICAgInJlZCIgICAgICAgICJOSVIiDQojIyBbNl0gIlNXSVIxIiAgICAgICJTV0lSMiINCmBgYA0KDQpgYGB7cn0NCiMgVXNpbmcgZXh0ZW50DQpleHRlbnQobGFuZHNhdCkNCiMjIGNsYXNzICAgICAgOiBFeHRlbnQNCiMjIHhtaW4gICAgICAgOiA1OTQwOTANCiMjIHhtYXggICAgICAgOiA2MzkwMDANCiMjIHltaW4gICAgICAgOiA0MTkwMTkwDQojIyB5bWF4ICAgICAgIDogNDIyNzU0MA0KZSA8LSBleHRlbnQoNjI0Mzg3LCA2MzU3NTIsIDQyMDAwNDcsIDQyMTA5MzkpDQojIGNyb3AgbGFuZHNhdCBieSB0aGUgZXh0ZW50DQpsYW5kc2F0Y3JvcCA8LSBjcm9wKGxhbmRzYXQsIGUpDQpgYGANCg0KYGBge3J9DQp4IDwtIHdyaXRlUmFzdGVyKGxhbmRzYXRjcm9wLCBmaWxlbmFtZT0iY3JvcHBlZC1sYW5kc2F0LnRpZiIsIG92ZXJ3cml0ZT1UUlVFKQ0KYGBgDQoNCmBgYHtyfQ0Kd3JpdGVSYXN0ZXIobGFuZHNhdGNyb3AsIGZpbGVuYW1lPSJjcm9wcGVkLWxhbmRzYXQuZ3JkIiwgb3ZlcndyaXRlPVRSVUUpDQpgYGANCiMjIw0KYGBge3J9DQpwYWlycyhsYW5kc2F0Y3JvcFtbMToyXV0sIG1haW4gPSAiVWx0cmEtYmx1ZSB2ZXJzdXMgQmx1ZSIpDQpgYGANCmBgYHtyfQ0KcGFpcnMobGFuZHNhdGNyb3BbWzQ6NV1dLCBtYWluID0gIlJlZCB2ZXJzdXMgTklSIikNCmBgYA0KYGBge3J9DQojIGxvYWQgdGhlIHBvbHlnb25zIHdpdGggbGFuZCB1c2UgbGFuZCBjb3ZlciBpbmZvcm1hdGlvbg0Kc2FtcCA8LSByZWFkUkRTKCcuL3JzZGF0YS9kYXRhL3JzL3NhbXBsZXMucmRzJykNCiMgZ2VuZXJhdGUgMzAwIHBvaW50IHNhbXBsZXMgZnJvbSB0aGUgcG9seWdvbnMNCnB0c2FtcCA8LSBzcHNhbXBsZShzYW1wLCAzMDAsIHR5cGU9J3JlZ3VsYXInKQ0KIyBhZGQgdGhlIGxhbmQgY292ZXIgY2xhc3MgdG8gdGhlIHBvaW50cw0KcHRzYW1wJGNsYXNzIDwtIG92ZXIocHRzYW1wLCBzYW1wKSRjbGFzcw0KIyBleHRyYWN0IHZhbHVlcyB3aXRoIHBvaW50cw0KZGYgPC0gZXh0cmFjdChsYW5kc2F0LCBwdHNhbXApDQojIFRvIHNlZSBzb21lIG9mIHRoZSByZWZsZWN0YW5jZSB2YWx1ZXMNCmhlYWQoZGYpDQojIyAgICAgIHVsdHJhLmJsdWUgICAgICBibHVlICAgICAgZ3JlZW4gICAgICAgIHJlZCAgICAgICBOSVIgICAgIFNXSVIxDQojIyBbMSxdICAwLjEzNjc1NDcgMC4xMTk3MDkxIDAuMTA0MjkwMDkgMC4xMDUwNzA4MCAwLjE2NzAyOTAgMC4yMTYxOTIxDQojIyBbMixdICAwLjEzNDMwNDEgMC4xMTYzNjk0IDAuMDk4ODkwMTYgMC4wOTc1MjM5MiAwLjE2ODY5ODggMC4yMDY2NTAxDQojIyBbMyxdICAwLjEzODM4MTIgMC4xMzc1MzU0IDAuMTUzNzc4NTUgMC4yMDk4ODEzNyAwLjM2MDI1NTIgMC4zNTk0NTI4DQojIyBbNCxdICAwLjEyOTM4MTMgMC4xMjU0MTI3IDAuMTM1ODIyMTggMC4xODU0NjI0NSAwLjMwOTQ4NzIgMC4yOTUwNDQwDQojIyBbNSxdICAwLjE0ODExODQgMC4xNTMxNDk2IDAuMTc5ODY3MzQgMC4yNDg5NjAzMyAwLjM4ODI5NTcgMC40MDEwMjU3DQojIyBbNixdICAwLjEzNDI2MDggMC4xMTU4NDkwIDAuMTAwMjk5NzggMC4wOTkzMjM5MCAwLjE2NDk0NzEgMC4yMTA4MzU2DQojIyAgICAgICAgICBTV0lSMg0KIyMgWzEsXSAwLjE4MTczMjQNCiMjIFsyLF0gMC4xNzEwODQzDQojIyBbMyxdIDAuMjE1NzgwMQ0KIyMgWzQsXSAwLjE2NTM1OTENCiMjIFs1LF0gMC4yNDU0MjU0DQojIyBbNixdIDAuMTgwMDQwOA0KYGBgDQpgYGB7cn0NCm1zIDwtIGFnZ3JlZ2F0ZShkZiwgbGlzdChwdHNhbXAkY2xhc3MpLCBtZWFuKQ0KIyBpbnN0ZWFkIG9mIHRoZSBmaXJzdCBjb2x1bW4sIHdlIHVzZSByb3cgbmFtZXMNCnJvd25hbWVzKG1zKSA8LSBtc1ssMV0NCm1zIDwtIG1zWywtMV0NCm1zDQojIyAgICAgICAgICB1bHRyYS5ibHVlICAgICAgYmx1ZSAgICAgIGdyZWVuICAgICAgIHJlZCAgICAgICAgTklSICAgICAgU1dJUjENCiMjIGJ1aWx0ICAgICAwLjE4NjQ5MjUgMC4xNzk1MzcxIDAuMTc5NTMzMTcgMC4xOTU4NDE0IDAuMjU0NDg0NDcgMC4yNDg1MDE5Nw0KIyMgY3JvcGxhbmQgIDAuMTEyOTgxMyAwLjA5MDk2NDUgMC4wODU5NjcyMiAwLjA1NTAzNDQgMC40ODMzNTQ2MiAwLjE2MTQyMDg1DQojIyBmYWxsb3cgICAgMC4xMzE5MTk4IDAuMTE2NDg2OSAwLjEwNDUzNzY0IDAuMTE1MTI0MyAwLjE4MDEyOTYyIDAuMjMxMzkyMjgNCiMjIG9wZW4gICAgICAwLjEzODgwMTQgMC4xMzc1MjM1IDAuMTUyNzMxNjMgMC4yMDY2NDI1IDAuMzQ0NzY2NzAgMC4zNTgyMDg3Nw0KIyMgd2F0ZXIgICAgIDAuMTMzNjI0MiAwLjExNjU3MjggMC4wOTkyMjcyNiAwLjA3ODU5NDcgMC4wNDkwOTIwMSAwLjAzMzYwMDQ3DQojIyAgICAgICAgICAgICAgIFNXSVIyDQojIyBidWlsdCAgICAwLjIwMDAxMzA2DQojIyBjcm9wbGFuZCAwLjA3MzE0MTg2DQojIyBmYWxsb3cgICAwLjE5MTQzMDMwDQojIyBvcGVuICAgICAwLjIxMzQ2MzQzDQojIyB3YXRlciAgICAwLjAyNzIzMzk4DQpgYGANCmBgYHtyfQ0KIyBDcmVhdGUgYSB2ZWN0b3Igb2YgY29sb3IgZm9yIHRoZSBsYW5kIGNvdmVyIGNsYXNzZXMgZm9yIHVzZSBpbiBwbG90dGluZw0KbXljb2xvciA8LSBjKCdkYXJrcmVkJywgJ3llbGxvdycsICdidXJseXdvb2QnLCAnY3lhbicsICdibHVlJykNCiN0cmFuc2Zvcm0gbXMgZnJvbSBhIGRhdGEuZnJhbWUgdG8gYSBtYXRyaXgNCm1zIDwtIGFzLm1hdHJpeChtcykNCiMgRmlyc3QgY3JlYXRlIGFuIGVtcHR5IHBsb3QNCnBsb3QoMCwgeWxpbT1jKDAsMC42KSwgeGxpbSA9IGMoMSw3KSwgdHlwZT0nbicsIHhsYWI9IkJhbmRzIiwgeWxhYiA9ICJSZWZsZWN0YW5jZSIpDQojIGFkZCB0aGUgZGlmZmVyZW50IGNsYXNzZXMNCmZvciAoaSBpbiAxOm5yb3cobXMpKXsNCiAgbGluZXMobXNbaSxdLCB0eXBlID0gImwiLCBsd2QgPSAzLCBsdHkgPSAxLCBjb2wgPSBteWNvbG9yW2ldKQ0KfQ0KIyBUaXRsZQ0KdGl0bGUobWFpbj0iU3BlY3RyYWwgUHJvZmlsZSBmcm9tIExhbmRzYXQiLCBmb250Lm1haW4gPSAyKQ0KIyBMZWdlbmQNCmxlZ2VuZCgidG9wbGVmdCIsIHJvd25hbWVzKG1zKSwNCiAgICAgICBjZXg9MC44LCBjb2w9bXljb2xvciwgbHR5ID0gMSwgbHdkID0zLCBidHkgPSAibiIpDQpgYGANCmBgYHtyfQ0KDQpgYGANCiANCg==