Mt. Baker ⛰️

Homework #1


Markdown Author: Jessie Bell

Download this Rmd: Top right corner → Code → Download Rmd

My Baker Map

All code reasoning is documented in the code below.

#load the things

mtbDEM <- rast("Mt_Baker/data/mtbDEM.tif") #you need data in raster form here to run through spatraster code below. 
mtb_hill <- rast("Mt_Baker/data/mtbHill.tif")
lines <- st_read("Mt_Baker/data/mtbChairLines.shp")
points <- st_read("Mt_Baker/data/mtbLodges.csv")

#check to see what is in the mtb_hill data
baker_hill_df <- as.data.frame(mtb_hill, xy=T)

#do it again with DEM
baker_DEM_df <- as.data.frame(mtbDEM, xy=T)

#create dataframe for points
points <- as.data.frame(points, xy=T)

#create sf for points (use this for ggplot)
lodges <- st_as_sf(points, coords = c("X", "Y"), crs = st_crs(32610))

#make pretty colors and ramp for continuous
cols <- c("#00007f", "#ff00ff", "#01ffff")
elevcols <- colorRampPalette(cols)(100)


#changing these for legend titles
lodges$Lodge <- as.factor(lodges$id)
lines$Lifts <- as.character(c("Chair 1", "Chair 2", "Chair 3", "Chair 4", "Chair 5", "Chair 6", "Chair 7", "Chair 8"))

#create ggplot

#1 call in hillshade and use gray colors with alpha for transparency

p1 <- ggplot()+
  geom_spatraster(data=mtb_hill, mapping = aes(fill=value))+
  scale_fill_gradientn(colors = gray.colors(100, start = 0.0, end=0.988), guide="none") 

#2 Call in DEM and use color ramp that you created above 
p2 <- p1 + new_scale_fill()+
  geom_spatraster(data=mtbDEM, mapping=aes(fill=elev), show.legend = F)+
  scale_fill_viridis_b(values=cols, alpha=0.3)

#3 Add in line data 
p3 <- p2 + geom_sf(data=lines, mapping=aes(color=Lifts), linewidth=1)

#4 Add in point data
p4 <- p3 + geom_sf(data=lodges,show.legend = F)+
  geom_sf_label(mapping = aes(label = Lodge), data=lodges)

#add in contours 
p5 <- p4 + geom_contour(data=baker_DEM_df,aes(x=x,y=y, z=as.integer(elev)),color="white", alpha=0.6, linewidth=0.3) + #addded contours
  guides(col= guide_legend(title= "", override.aes = list(fill=NA)))+
  theme(legend.position = "bottom")+
  labs(x="", y="", caption = "Elevation contours in 100 m intervals")

p5+ theme_minimal()

Mt. Baker 3D Map

Following Milos Makes Maps video

#trying to make a 3d map (using coords from Google Maps)
baker_lat <- 48.782079

baker_long <- -121.803322


#baker_3d <- plot_3d_vista(lat=baker_lat,long=baker_long,radius=5000, overlay_detail = 14, elevation_detail=13, zscale=5, img_provider = 'OpenStreetMap', cache_dir = 'testing',theta=25, phi=25, zoom=0.5,
 #            windowsize =1200, solid=T, background='grey10')

Andy’s Tutorial

Plot

mtbDEM <- rast("Mt_Baker/data/mtbDEM.tif")

mtbDEM
## class       : SpatRaster 
## dimensions  : 409, 628, 1  (nrow, ncol, nlyr)
## resolution  : 5, 5  (x, y)
## extent      : 596210.7, 599350.7, 5411132, 5413177  (xmin, xmax, ymin, ymax)
## coord. ref. : WGS 84 / UTM zone 10N (EPSG:32610) 
## source      : mtbDEM.tif 
## name        :      elev 
## min value   :  826.4308 
## max value   : 1689.3694
#quickplot of the data

mtbDEM <- as.data.frame(mtbDEM, xy=T)

ggplot()+
  geom_raster(data=mtbDEM, aes(x, y, fill=elev))+
  scale_fill_gradientn(colors=terrain.colors(100))+
  labs(x="Easting [m]", y="Northing [m]")+
                coord_equal()


Flow

[1] Take .tif and run it through rast() function

[2] Turn that into data frame by running it through as.data.frame function

[3] Use ggplot and ggraster function to create a nice map

Tidyterra

Using tidyterra package, grab geom_spatraster function and make it easier!

For fun colors you can use ?hypso.colors

#install.packages("tidyterra")

mtbDEM <- rast("Mt_Baker/data/mtbDEM.tif") #you need data in raster form here to run through spatraster code below. 

ggplot()+
  geom_spatraster(data=mtbDEM)+
  scale_fill_hypso_c(palette="usgs-gswa2")

|

The difference between this and geom_rast is that geom_spatraster uses coordinates to plot the data, while geom_rast uses meters. You can use spatrast in exactly the same way if you add coord_sf() into your arguments.

ggplot()+
  geom_spatraster(data=mtbDEM)+
  scale_fill_hypso_c(palette="usgs-gswa2")+
  coord_sf(datum = 32610)

Hillshade

mtb_hill <- rast("Mt_Baker/data/mtbHill.tif")

mtb_hill
## class       : SpatRaster 
## dimensions  : 409, 628, 1  (nrow, ncol, nlyr)
## resolution  : 5, 5  (x, y)
## extent      : 596210.7, 599350.7, 5411132, 5413177  (xmin, xmax, ymin, ymax)
## coord. ref. : WGS 84 / UTM zone 10N (EPSG:32610) 
## source      : mtbHill.tif 
## name        :    value 
## min value   : 0.000000 
## max value   : 0.999856
#make a quickplot

ggplot()+
  geom_spatraster(data=mtb_hill)

## oooo pretty!

Combined

p1 <- ggplot()+
  geom_spatraster(data=mtb_hill)+
  scale_fill_gradientn(colors=gray.colors(100, start=0.1, end=0.9), guide="none")+
  new_scale_fill()+
  geom_spatraster(data=mtbDEM)+
  scale_fill_hypso_c(name="Elevation [m]", 
                     palette="usgs-gswa2", alpha = 0.6)+
  theme_minimal()

p1

##ooooo v nice

Important

[1] Add hillshade in gray first

[2] Add elevation second with transparency

[3] Add multiple color scales (like gray and USGS) with new_scale_fill function

Shapefile

lines <- st_read("Mt_Baker/data/mtbChairLines.shp")
## Reading layer `mtbChairLines' from data source 
##   `C:\Users\jessi\Desktop\Rdata\ESCI_505\Mt_Baker\data\mtbChairLines.shp' 
##   using driver `ESRI Shapefile'
## Simple feature collection with 8 features and 1 field
## Geometry type: LINESTRING
## Dimension:     XY
## Bounding box:  xmin: 596713.7 ymin: 5411451 xmax: 599131.5 ymax: 5412970
## Projected CRS: UTM_Zone_10_Northern_Hemisphere
p2 <- p1+geom_sf(data=lines)
p2

.csv

(See datacarpentry .csv to sf object section)

points <- st_read("Mt_Baker/data/mtbLodges.csv")
## Reading layer `mtbLodges' from data source 
##   `C:\Users\jessi\Desktop\Rdata\ESCI_505\Mt_Baker\data\mtbLodges.csv' 
##   using driver `CSV'
## Warning: no simple feature geometries present: returning a data.frame or tbl_df
points <- as.data.frame(points, xy=T)

names(points)
## [1] "X"  "Y"  "id"
lodges <- st_as_sf(points, coords = c("X", "Y"), crs = st_crs(32610))


st_crs(lodges)
## Coordinate Reference System:
##   User input: EPSG:32610 
##   wkt:
## PROJCRS["WGS 84 / UTM zone 10N",
##     BASEGEOGCRS["WGS 84",
##         ENSEMBLE["World Geodetic System 1984 ensemble",
##             MEMBER["World Geodetic System 1984 (Transit)"],
##             MEMBER["World Geodetic System 1984 (G730)"],
##             MEMBER["World Geodetic System 1984 (G873)"],
##             MEMBER["World Geodetic System 1984 (G1150)"],
##             MEMBER["World Geodetic System 1984 (G1674)"],
##             MEMBER["World Geodetic System 1984 (G1762)"],
##             MEMBER["World Geodetic System 1984 (G2139)"],
##             ELLIPSOID["WGS 84",6378137,298.257223563,
##                 LENGTHUNIT["metre",1]],
##             ENSEMBLEACCURACY[2.0]],
##         PRIMEM["Greenwich",0,
##             ANGLEUNIT["degree",0.0174532925199433]],
##         ID["EPSG",4326]],
##     CONVERSION["UTM zone 10N",
##         METHOD["Transverse Mercator",
##             ID["EPSG",9807]],
##         PARAMETER["Latitude of natural origin",0,
##             ANGLEUNIT["degree",0.0174532925199433],
##             ID["EPSG",8801]],
##         PARAMETER["Longitude of natural origin",-123,
##             ANGLEUNIT["degree",0.0174532925199433],
##             ID["EPSG",8802]],
##         PARAMETER["Scale factor at natural origin",0.9996,
##             SCALEUNIT["unity",1],
##             ID["EPSG",8805]],
##         PARAMETER["False easting",500000,
##             LENGTHUNIT["metre",1],
##             ID["EPSG",8806]],
##         PARAMETER["False northing",0,
##             LENGTHUNIT["metre",1],
##             ID["EPSG",8807]]],
##     CS[Cartesian,2],
##         AXIS["(E)",east,
##             ORDER[1],
##             LENGTHUNIT["metre",1]],
##         AXIS["(N)",north,
##             ORDER[2],
##             LENGTHUNIT["metre",1]],
##     USAGE[
##         SCOPE["Navigation and medium accuracy spatial referencing."],
##         AREA["Between 126°W and 120°W, northern hemisphere between equator and 84°N, onshore and offshore. Canada - British Columbia (BC); Northwest Territories (NWT); Nunavut; Yukon. United States (USA) - Alaska (AK)."],
##         BBOX[0,-126,84,-120]],
##     ID["EPSG",32610]]

Multi-vector

p2+
  geom_sf(data=lodges)+
  ggtitle("Hi")

LS0tDQp0aXRsZTogIiAiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6DQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQ0KICAgIGNvZGVfZm9sZGluZzogaGlkZQ0KICAgIGNzczogc3R5bGUuY3NzDQotLS0NCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpDQpsaWJyYXJ5KHRlcnJhKSAjZm9yIHJhc3RlciBkYXRhDQpsaWJyYXJ5KHNmKSAjZm9yIHNpbXBsZSBmZWF0dXJlcyAocG9pbnQgZGF0YSkNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShnZ25ld3NjYWxlKQ0KbGlicmFyeSh0aWR5dGVycmEpICNmb3IgZ2VvbV9zcGF0cmFzdGVyDQpsaWJyYXJ5KHNwKQ0KbGlicmFyeShwbG90bHkpDQojZG93bmxvYWQgZnJvbSBnaXRodWINCiNkZXZ0b29sczo6aW5zdGFsbF9naXRodWIoIi1hLWdyYWhhbS9yYXl2aXN0YSIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgI2RlcGVuZGVuY2llcz1UKQ0KDQojaW5zdGFsbC5wYWNrYWdlcygiZWxldmF0ciIpDQoNCiNpbnN0YWxsLnBhY2thZ2VzKCJyZW1vdGVzIikNCg0KbGlicmFyeShyZW1vdGVzKQ0KDQojaW5zdGFsbC5wYWNrYWdlcygicmF5c2hhZGVyIikNCg0KI2luc3RhbGwucGFja2FnZXMoInJnbCIpDQpsaWJyYXJ5KHJheXNoYWRlcikNCm9wdGlvbnMocmdsLnVzZU5VTEwgPSBUKQ0KDQojIGEgbmV3IHdheSB0byBxdWlja2x5IGluc3RhbGwgYWxsIGxpYnJhcmllcw0KbGlicyA8LSBjKCJyYXl2aXN0YSIsICJlbGV2YXRyIiwgInJheXNoYWRlciIsICJzZiIsICJyZ2wiKQ0KDQppbnZpc2libGUobGFwcGx5KGxpYnMsIGxpYnJhcnksIGNoYXJhY3Rlci5vbmx5PVQpKQ0KDQpvcHRpb25zKHJnbC51c2VOVUxMID0gVFJVRSkgIyBTdXBwcmVzcyB0aGUgc2VwYXJhdGUgd2luZG93Lg0KDQpgYGANCg0KDQojIE10LiBCYWtlciDim7DvuI8gey50YWJzZXR9DQoNCiMjIyMjIEhvbWV3b3JrICMxDQoNCjxicj4NCg0KKipNYXJrZG93biBBdXRob3I6KiogSmVzc2llIEJlbGwNCg0KfA0KDQoqKkRvd25sb2FkIHRoaXMgUm1kOioqIFRvcCByaWdodCBjb3JuZXIgJnJhcnI7IENvZGUgJnJhcnI7IERvd25sb2FkIFJtZA0KDQojIyAqKk15IEJha2VyIE1hcCoqDQoNCnwNCkFsbCBjb2RlIHJlYXNvbmluZyBpcyBkb2N1bWVudGVkIGluIHRoZSBjb2RlIGJlbG93LiANCg0KYGBge3IgZmluYWwgbWFwLCB3YXJuaW5nPUYsIG1lc3NhZ2U9RiwgcmVzdWx0cz0naGlkZScsIGNhY2hlPVR9DQojbG9hZCB0aGUgdGhpbmdzDQoNCm10YkRFTSA8LSByYXN0KCJNdF9CYWtlci9kYXRhL210YkRFTS50aWYiKSAjeW91IG5lZWQgZGF0YSBpbiByYXN0ZXIgZm9ybSBoZXJlIHRvIHJ1biB0aHJvdWdoIHNwYXRyYXN0ZXIgY29kZSBiZWxvdy4gDQptdGJfaGlsbCA8LSByYXN0KCJNdF9CYWtlci9kYXRhL210YkhpbGwudGlmIikNCmxpbmVzIDwtIHN0X3JlYWQoIk10X0Jha2VyL2RhdGEvbXRiQ2hhaXJMaW5lcy5zaHAiKQ0KcG9pbnRzIDwtIHN0X3JlYWQoIk10X0Jha2VyL2RhdGEvbXRiTG9kZ2VzLmNzdiIpDQoNCiNjaGVjayB0byBzZWUgd2hhdCBpcyBpbiB0aGUgbXRiX2hpbGwgZGF0YQ0KYmFrZXJfaGlsbF9kZiA8LSBhcy5kYXRhLmZyYW1lKG10Yl9oaWxsLCB4eT1UKQ0KDQojZG8gaXQgYWdhaW4gd2l0aCBERU0NCmJha2VyX0RFTV9kZiA8LSBhcy5kYXRhLmZyYW1lKG10YkRFTSwgeHk9VCkNCg0KI2NyZWF0ZSBkYXRhZnJhbWUgZm9yIHBvaW50cw0KcG9pbnRzIDwtIGFzLmRhdGEuZnJhbWUocG9pbnRzLCB4eT1UKQ0KDQojY3JlYXRlIHNmIGZvciBwb2ludHMgKHVzZSB0aGlzIGZvciBnZ3Bsb3QpDQpsb2RnZXMgPC0gc3RfYXNfc2YocG9pbnRzLCBjb29yZHMgPSBjKCJYIiwgIlkiKSwgY3JzID0gc3RfY3JzKDMyNjEwKSkNCg0KI21ha2UgcHJldHR5IGNvbG9ycyBhbmQgcmFtcCBmb3IgY29udGludW91cw0KY29scyA8LSBjKCIjMDAwMDdmIiwgIiNmZjAwZmYiLCAiIzAxZmZmZiIpDQplbGV2Y29scyA8LSBjb2xvclJhbXBQYWxldHRlKGNvbHMpKDEwMCkNCg0KDQojY2hhbmdpbmcgdGhlc2UgZm9yIGxlZ2VuZCB0aXRsZXMNCmxvZGdlcyRMb2RnZSA8LSBhcy5mYWN0b3IobG9kZ2VzJGlkKQ0KbGluZXMkTGlmdHMgPC0gYXMuY2hhcmFjdGVyKGMoIkNoYWlyIDEiLCAiQ2hhaXIgMiIsICJDaGFpciAzIiwgIkNoYWlyIDQiLCAiQ2hhaXIgNSIsICJDaGFpciA2IiwgIkNoYWlyIDciLCAiQ2hhaXIgOCIpKQ0KDQojY3JlYXRlIGdncGxvdA0KDQojMSBjYWxsIGluIGhpbGxzaGFkZSBhbmQgdXNlIGdyYXkgY29sb3JzIHdpdGggYWxwaGEgZm9yIHRyYW5zcGFyZW5jeQ0KDQpwMSA8LSBnZ3Bsb3QoKSsNCiAgZ2VvbV9zcGF0cmFzdGVyKGRhdGE9bXRiX2hpbGwsIG1hcHBpbmcgPSBhZXMoZmlsbD12YWx1ZSkpKw0KICBzY2FsZV9maWxsX2dyYWRpZW50bihjb2xvcnMgPSBncmF5LmNvbG9ycygxMDAsIHN0YXJ0ID0gMC4wLCBlbmQ9MC45ODgpLCBndWlkZT0ibm9uZSIpIA0KDQojMiBDYWxsIGluIERFTSBhbmQgdXNlIGNvbG9yIHJhbXAgdGhhdCB5b3UgY3JlYXRlZCBhYm92ZSANCnAyIDwtIHAxICsgbmV3X3NjYWxlX2ZpbGwoKSsNCiAgZ2VvbV9zcGF0cmFzdGVyKGRhdGE9bXRiREVNLCBtYXBwaW5nPWFlcyhmaWxsPWVsZXYpLCBzaG93LmxlZ2VuZCA9IEYpKw0KICBzY2FsZV9maWxsX3ZpcmlkaXNfYih2YWx1ZXM9Y29scywgYWxwaGE9MC4zKQ0KDQojMyBBZGQgaW4gbGluZSBkYXRhIA0KcDMgPC0gcDIgKyBnZW9tX3NmKGRhdGE9bGluZXMsIG1hcHBpbmc9YWVzKGNvbG9yPUxpZnRzKSwgbGluZXdpZHRoPTEpDQoNCiM0IEFkZCBpbiBwb2ludCBkYXRhDQpwNCA8LSBwMyArIGdlb21fc2YoZGF0YT1sb2RnZXMsc2hvdy5sZWdlbmQgPSBGKSsNCiAgZ2VvbV9zZl9sYWJlbChtYXBwaW5nID0gYWVzKGxhYmVsID0gTG9kZ2UpLCBkYXRhPWxvZGdlcykNCg0KI2FkZCBpbiBjb250b3VycyANCnA1IDwtIHA0ICsgZ2VvbV9jb250b3VyKGRhdGE9YmFrZXJfREVNX2RmLGFlcyh4PXgseT15LCB6PWFzLmludGVnZXIoZWxldikpLGNvbG9yPSJ3aGl0ZSIsIGFscGhhPTAuNiwgbGluZXdpZHRoPTAuMykgKyAjYWRkZGVkIGNvbnRvdXJzDQogIGd1aWRlcyhjb2w9IGd1aWRlX2xlZ2VuZCh0aXRsZT0gIiIsIG92ZXJyaWRlLmFlcyA9IGxpc3QoZmlsbD1OQSkpKSsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpKw0KICBsYWJzKHg9IiIsIHk9IiIsIGNhcHRpb24gPSAiRWxldmF0aW9uIGNvbnRvdXJzIGluIDEwMCBtIGludGVydmFscyIpDQoNCnA1KyB0aGVtZV9taW5pbWFsKCkNCmBgYA0KDQoNCg0KIyMgTXQuIEJha2VyIDNEIE1hcCB7LnRhYnNldH0NCg0KfA0KDQpGb2xsb3dpbmcgTWlsb3MgTWFrZXMgTWFwcyBbdmlkZW9dKGh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9a0dhZEk2X1pJUjQpDQoNCmBgYHtyIDNkIG1hcCwgZmlnLmhlaWdodD01LCBmaWcud2lkdGg9MTV9DQoNCiN0cnlpbmcgdG8gbWFrZSBhIDNkIG1hcCAodXNpbmcgY29vcmRzIGZyb20gR29vZ2xlIE1hcHMpDQpiYWtlcl9sYXQgPC0gNDguNzgyMDc5DQoNCmJha2VyX2xvbmcgPC0gLTEyMS44MDMzMjINCg0KDQojYmFrZXJfM2QgPC0gcGxvdF8zZF92aXN0YShsYXQ9YmFrZXJfbGF0LGxvbmc9YmFrZXJfbG9uZyxyYWRpdXM9NTAwMCwgb3ZlcmxheV9kZXRhaWwgPSAxNCwgZWxldmF0aW9uX2RldGFpbD0xMywgenNjYWxlPTUsIGltZ19wcm92aWRlciA9ICdPcGVuU3RyZWV0TWFwJywgY2FjaGVfZGlyID0gJ3Rlc3RpbmcnLHRoZXRhPTI1LCBwaGk9MjUsIHpvb209MC41LA0KICMgICAgICAgICAgICB3aW5kb3dzaXplID0xMjAwLCBzb2xpZD1ULCBiYWNrZ3JvdW5kPSdncmV5MTAnKQ0KDQoNCg0KDQpgYGANCg0KDQojIyBBbmR5J3MgVHV0b3JpYWwgey50YWJzZXR9DQoNCiMjIyBQbG90DQoNCmBgYHtyIHJlYWRpbiBERU0sIGNsYXNzLnNvdXJjZT0iZm9sZC1zaG93In0NCm10YkRFTSA8LSByYXN0KCJNdF9CYWtlci9kYXRhL210YkRFTS50aWYiKQ0KDQptdGJERU0NCg0KI3F1aWNrcGxvdCBvZiB0aGUgZGF0YQ0KDQptdGJERU0gPC0gYXMuZGF0YS5mcmFtZShtdGJERU0sIHh5PVQpDQoNCmdncGxvdCgpKw0KICBnZW9tX3Jhc3RlcihkYXRhPW10YkRFTSwgYWVzKHgsIHksIGZpbGw9ZWxldikpKw0KICBzY2FsZV9maWxsX2dyYWRpZW50bihjb2xvcnM9dGVycmFpbi5jb2xvcnMoMTAwKSkrDQogIGxhYnMoeD0iRWFzdGluZyBbbV0iLCB5PSJOb3J0aGluZyBbbV0iKSsNCiAgICAgICAgICAgICAgICBjb29yZF9lcXVhbCgpDQpgYGANCg0KfA0KfA0KDQojIyMgRmxvdyANCg0KWzFdIFRha2UgLnRpZiBhbmQgcnVuIGl0IHRocm91Z2ggcmFzdCgpIGZ1bmN0aW9uDQoNClsyXSBUdXJuIHRoYXQgaW50byBkYXRhIGZyYW1lIGJ5IHJ1bm5pbmcgaXQgdGhyb3VnaCBhcy5kYXRhLmZyYW1lIGZ1bmN0aW9uDQoNClszXSBVc2UgZ2dwbG90IGFuZCBnZ3Jhc3RlciBmdW5jdGlvbiB0byBjcmVhdGUgYSBuaWNlIG1hcA0KDQojIyMgVGlkeXRlcnJhDQoNCnwNCg0KVXNpbmcgdGlkeXRlcnJhIHBhY2thZ2UsIGdyYWIgZ2VvbV9zcGF0cmFzdGVyIGZ1bmN0aW9uIGFuZCBtYWtlIGl0IGVhc2llciENCg0KfA0KDQpGb3IgZnVuIGNvbG9ycyB5b3UgY2FuIHVzZSA/aHlwc28uY29sb3JzDQoNCnwNCg0KDQoNCmBgYHtyIHRpZHl0ZXJyYSwgY2xhc3Muc291cmNlPSJmb2xkLXNob3ciLCB3YXJuaW5nPUZ9DQojaW5zdGFsbC5wYWNrYWdlcygidGlkeXRlcnJhIikNCg0KbXRiREVNIDwtIHJhc3QoIk10X0Jha2VyL2RhdGEvbXRiREVNLnRpZiIpICN5b3UgbmVlZCBkYXRhIGluIHJhc3RlciBmb3JtIGhlcmUgdG8gcnVuIHRocm91Z2ggc3BhdHJhc3RlciBjb2RlIGJlbG93LiANCg0KZ2dwbG90KCkrDQogIGdlb21fc3BhdHJhc3RlcihkYXRhPW10YkRFTSkrDQogIHNjYWxlX2ZpbGxfaHlwc29fYyhwYWxldHRlPSJ1c2dzLWdzd2EyIikNCg0KYGBgDQp8DQoNClRoZSBkaWZmZXJlbmNlIGJldHdlZW4gdGhpcyBhbmQgZ2VvbV9yYXN0IGlzIHRoYXQgZ2VvbV9zcGF0cmFzdGVyIHVzZXMgY29vcmRpbmF0ZXMgdG8gcGxvdCB0aGUgZGF0YSwgd2hpbGUgZ2VvbV9yYXN0IHVzZXMgbWV0ZXJzLiBZb3UgY2FuIHVzZSBzcGF0cmFzdCBpbiBleGFjdGx5IHRoZSBzYW1lIHdheSBpZiB5b3UgYWRkIGNvb3JkX3NmKCkgaW50byB5b3VyIGFyZ3VtZW50cy4gDQoNCmBgYHtyIGNvb3JkX3NmfQ0KZ2dwbG90KCkrDQogIGdlb21fc3BhdHJhc3RlcihkYXRhPW10YkRFTSkrDQogIHNjYWxlX2ZpbGxfaHlwc29fYyhwYWxldHRlPSJ1c2dzLWdzd2EyIikrDQogIGNvb3JkX3NmKGRhdHVtID0gMzI2MTApDQoNCmBgYA0KDQojIyMgSGlsbHNoYWRlDQoNCmBgYHtyIGhpbGxzaGFkZSwgY2xhc3Muc291cmNlPSJmb2xkLXNob3cifQ0KDQoNCm10Yl9oaWxsIDwtIHJhc3QoIk10X0Jha2VyL2RhdGEvbXRiSGlsbC50aWYiKQ0KDQptdGJfaGlsbA0KDQojbWFrZSBhIHF1aWNrcGxvdA0KDQpnZ3Bsb3QoKSsNCiAgZ2VvbV9zcGF0cmFzdGVyKGRhdGE9bXRiX2hpbGwpDQojIyBvb29vIHByZXR0eSENCmBgYA0KDQojIyMgQ29tYmluZWQNCg0KYGBge3IgY29tYmluZSwgY2xhc3Muc291cmNlPSJmb2xkLXNob3cifQ0KDQpwMSA8LSBnZ3Bsb3QoKSsNCiAgZ2VvbV9zcGF0cmFzdGVyKGRhdGE9bXRiX2hpbGwpKw0KICBzY2FsZV9maWxsX2dyYWRpZW50bihjb2xvcnM9Z3JheS5jb2xvcnMoMTAwLCBzdGFydD0wLjEsIGVuZD0wLjkpLCBndWlkZT0ibm9uZSIpKw0KICBuZXdfc2NhbGVfZmlsbCgpKw0KICBnZW9tX3NwYXRyYXN0ZXIoZGF0YT1tdGJERU0pKw0KICBzY2FsZV9maWxsX2h5cHNvX2MobmFtZT0iRWxldmF0aW9uIFttXSIsIA0KICAgICAgICAgICAgICAgICAgICAgcGFsZXR0ZT0idXNncy1nc3dhMiIsIGFscGhhID0gMC42KSsNCiAgdGhlbWVfbWluaW1hbCgpDQoNCnAxDQoNCiMjb29vb28gdiBuaWNlDQoNCmBgYA0KDQojIyMgSW1wb3J0YW50DQoNClsxXSBBZGQgaGlsbHNoYWRlIGluIGdyYXkgZmlyc3QNCg0KWzJdIEFkZCBlbGV2YXRpb24gc2Vjb25kIHdpdGggdHJhbnNwYXJlbmN5DQoNClszXSBBZGQgbXVsdGlwbGUgY29sb3Igc2NhbGVzIChsaWtlIGdyYXkgYW5kIFVTR1MpIHdpdGggbmV3X3NjYWxlX2ZpbGwgZnVuY3Rpb24NCg0KIyMjIFNoYXBlZmlsZQ0KDQpgYGB7ciBzaGFwZSwgY2xhc3Muc291cmNlPSJmb2xkLXNob3cifQ0KDQoNCg0KbGluZXMgPC0gc3RfcmVhZCgiTXRfQmFrZXIvZGF0YS9tdGJDaGFpckxpbmVzLnNocCIpDQoNCg0KDQpwMiA8LSBwMStnZW9tX3NmKGRhdGE9bGluZXMpDQpwMg0KDQpgYGANCg0KIyMjIC5jc3YNCg0KKFNlZSBkYXRhY2FycGVudHJ5IC5jc3YgdG8gc2Ygb2JqZWN0IHNlY3Rpb24pDQoNCmBgYHtyIGNzdiwgY2xhc3Muc291cmNlPSJmb2xkLXNob3cifQ0KDQoNCnBvaW50cyA8LSBzdF9yZWFkKCJNdF9CYWtlci9kYXRhL210YkxvZGdlcy5jc3YiKQ0KDQpwb2ludHMgPC0gYXMuZGF0YS5mcmFtZShwb2ludHMsIHh5PVQpDQoNCm5hbWVzKHBvaW50cykNCg0KbG9kZ2VzIDwtIHN0X2FzX3NmKHBvaW50cywgY29vcmRzID0gYygiWCIsICJZIiksIGNycyA9IHN0X2NycygzMjYxMCkpDQoNCg0Kc3RfY3JzKGxvZGdlcykNCg0KYGBgDQoNCiMjIyBNdWx0aS12ZWN0b3INCg0KYGBge3IgdmVjdG9ycywgY2xhc3Muc291cmNlPSJmb2xkLXNob3cifQ0KcDIrDQogIGdlb21fc2YoZGF0YT1sb2RnZXMpKw0KICBnZ3RpdGxlKCJIaSIpDQpgYGANCg0KDQo=