0. CRS transform
library(sf)
Popn_TWN = st_read("./data/Popn_TWN2.shp",options="ENCODING=BIG5")
options: ENCODING=BIG5
Reading layer `Popn_TWN2' from data source `C:\Users\user\Desktop\WK04\Data\Popn_TWN2.shp' using driver `ESRI Shapefile'
Simple feature collection with 368 features and 14 fields
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: -197572.5 ymin: 2295201 xmax: 606875.6 ymax: 2919551
Projected CRS: TWD97 / TM2 zone 121
st_crs(Popn_TWN)
Coordinate Reference System:
User input: TWD97 / TM2 zone 121
wkt:
PROJCRS["TWD97 / TM2 zone 121",
BASEGEOGCRS["TWD97",
DATUM["Taiwan Datum 1997",
ELLIPSOID["GRS 1980",6378137,298.257222101,
LENGTHUNIT["metre",1]]],
PRIMEM["Greenwich",0,
ANGLEUNIT["degree",0.0174532925199433]],
ID["EPSG",3824]],
CONVERSION["Taiwan 2-degree TM zone 121",
METHOD["Transverse Mercator",
ID["EPSG",9807]],
PARAMETER["Latitude of natural origin",0,
ANGLEUNIT["degree",0.0174532925199433],
ID["EPSG",8801]],
PARAMETER["Longitude of natural origin",121,
ANGLEUNIT["degree",0.0174532925199433],
ID["EPSG",8802]],
PARAMETER["Scale factor at natural origin",0.9999,
SCALEUNIT["unity",1],
ID["EPSG",8805]],
PARAMETER["False easting",250000,
LENGTHUNIT["metre",1],
ID["EPSG",8806]],
PARAMETER["False northing",0,
LENGTHUNIT["metre",1],
ID["EPSG",8807]]],
CS[Cartesian,2],
AXIS["easting (X)",east,
ORDER[1],
LENGTHUNIT["metre",1]],
AXIS["northing (Y)",north,
ORDER[2],
LENGTHUNIT["metre",1]],
USAGE[
SCOPE["Engineering survey, topographic mapping."],
AREA["Taiwan, Republic of China - between 120°E and 122°E, onshore and offshore - Taiwan Island."],
BBOX[20.41,119.99,26.72,122.06]],
ID["EPSG",3826]]
# EPSG:3826 TWD97-TM2 zone 121
# EPSG:4326 WGS84
Popn_TWN = st_transform(Popn_TWN, 4326)
st_crs(Popn_TWN)
Coordinate Reference System:
User input: EPSG:4326
wkt:
GEOGCRS["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)"],
MEMBER["World Geodetic System 1984 (G2296)"],
ELLIPSOID["WGS 84",6378137,298.257223563,
LENGTHUNIT["metre",1]],
ENSEMBLEACCURACY[2.0]],
PRIMEM["Greenwich",0,
ANGLEUNIT["degree",0.0174532925199433]],
CS[ellipsoidal,2],
AXIS["geodetic latitude (Lat)",north,
ORDER[1],
ANGLEUNIT["degree",0.0174532925199433]],
AXIS["geodetic longitude (Lon)",east,
ORDER[2],
ANGLEUNIT["degree",0.0174532925199433]],
USAGE[
SCOPE["Horizontal component of 3D system."],
AREA["World."],
BBOX[-90,-180,90,180]],
ID["EPSG",4326]]
# Popn_TWN = st_transform(Popn_TWN, st_crs(TWN))
1. load data: tracts_sf
rm(list = ls())
library(sf)
library(tmap)
load("./data/Sample3.RData")
head(tracts_sf)
Simple feature collection with 6 features and 77 fields
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: 534687.6 ymin: 173049.9 xmax: 569625.3 ymax: 188464.6
Projected CRS: +proj=lcc +datum=NAD27 +lon_0=-72d45 +lat_1=41d52 +lat_2=41d12 +lat_0=40d50 +x_0=182880.3657607315 +y_0=0 +units=us-ft +no_defs +ellps=clrk66 +nadgrids=@conus,@alaska,@ntv2_0.gsb,@ntv1_can.dat
AREA PERIMETER T009075H_ T009075H_I ARCINFOFPS ATLAS_S LOGRECNU STATEFPS CNTY MCD TRACTBNA MAPINFOFPS
0 38821430 39255.55 2 554 090091413 1413 003043 09 009 075 1413 090091413
1 20727120 21202.13 3 553 090091412 1412 003387 09 009 075 1412 090091412
2 45692640 33168.56 4 567 09009142601 142601 003470 09 009 075 142601 09009142601
3 16967620 19782.15 5 555 090091414 1414 003398 09 009 075 1414 090091414
4 17770100 17954.76 6 556 090091415 1415 003045 09 009 075 1415 090091415
5 15763400 16665.57 7 559 090091418 1418 003423 09 009 075 1418 090091418
STATE_ABBR CNTY_NAME LAND_AREA HSEHLD_1_M HSEHLD_1_F MARHH_CHD MARHH_NO_C MHH_CHILD MHH_NO_CHD FHH_CHILD
0 CT NEW HAVEN 3609 243 430 156 246 26 22 488
1 CT NEW HAVEN 1904 141 302 304 408 26 45 286
2 CT NEW HAVEN 3830 293 294 359 500 24 48 117
3 CT NEW HAVEN 1524 188 229 394 402 29 35 204
4 CT NEW HAVEN 1621 272 416 401 365 60 100 706
5 CT NEW HAVEN 1465 242 280 349 346 20 24 218
FHH_NO_CHD NONFAM_MHH NONFAM_FHH FAMHH_2PER FAMHH_3PER FAMHH_4PER FAMHH_5PER FAMHH_6PER FAMHH_7_UP NONFAM_1PE
0 128 59 66 405 283 196 97 48 37 673
1 120 65 70 502 305 231 97 31 23 443
2 109 106 54 541 322 190 69 25 10 587
3 96 152 107 442 310 219 113 42 34 417
4 266 81 48 573 516 399 232 90 88 688
5 87 65 66 397 306 202 91 34 14 522
NONFAM_2PE NONFAM_3PE NONFAM_4PE NONFAM_5PE NONFAM_6PE NONFAM_7_U HSE_UNITS OCCUPIED VACANT P_VACANT
0 88 15 8 11 0 3 1997 1864 133 6.659990
1 111 15 8 1 0 0 1944 1767 177 9.104938
2 142 13 2 1 2 0 2132 1904 228 10.694180
3 163 56 28 6 6 0 2000 1836 164 8.200000
4 103 21 5 0 0 0 3049 2715 334 10.954410
5 102 14 7 2 3 3 1885 1697 188 9.973475
OWNER_OCC RENTER_OCC P_OWNEROCC P_RENTROCC VACNT_RENT VACNT_SALE SEASONAL WH_OWNOCC BL_OWNOCC AM_OWNOCC
0 328 1536 16.42464 76.91537 70 10 8 271 53 1
1 877 890 45.11317 45.78189 86 28 1 601 264 3
2 930 974 43.62101 45.68480 113 50 1 825 88 4
3 833 1003 41.65000 50.15000 88 15 2 535 282 1
4 1022 1693 33.51919 55.52640 177 22 0 63 940 10
5 487 1210 25.83554 64.19098 129 6 3 336 139 0
AS_OWNOCC OT_OWNOCC WH_RENTOCC BL_RENTOCC AM_RENTOCC AS_RENTOCC OT_RENTOCC UNT_1ROOM UNT_2ROOMS UNT_3ROOMS
0 0 3 715 760 7 7 47 75 136 415
1 8 1 451 421 2 5 11 5 44 122
2 8 5 703 209 6 22 34 11 67 247
3 9 6 568 402 2 11 20 5 50 198
4 5 4 58 1603 8 0 24 65 103 202
5 9 3 547 455 5 174 29 79 210 388
UNT_4ROOMS UNT_5ROOMS UNT_6ROOMS UNT_7ROOMS UNT_8ROOMS UNT_9_UP UNT_1PER UNT_2PER UNT_3PER UNT_4PER UNT_5PER
0 577 492 168 77 34 23 673 493 298 204 108
1 656 543 342 134 54 44 443 613 320 239 98
2 826 544 285 88 32 32 587 683 335 192 70
3 301 576 268 261 155 186 417 605 366 247 119
4 580 1291 412 159 84 153 688 676 537 404 232
5 355 368 168 64 47 206 522 499 320 209 93
UNT_6PER UNT_7_UP PERS_UNIT SPLIT geometry
0 48 40 2.42 0 MULTIPOLYGON (((538629.8 18...
1 31 23 2.51 0 MULTIPOLYGON (((534687.6 18...
2 27 10 2.27 0 MULTIPOLYGON (((563501.1 18...
3 48 34 2.65 0 MULTIPOLYGON (((546803.4 18...
4 90 88 5.38 0 MULTIPOLYGON (((547544.8 18...
5 37 17 2.43 0 MULTIPOLYGON (((551828.6 18...
tm_shape(tracts_sf) +
tm_polygons("HSE_UNITS", palette = "Greens", style = "jenks", title = "No. of houses") +
tm_layout(frame = F, legend.position = c(1,0.5))
── tmap v3 code detected ───────────────────────────────────────────────────────────────────────────────────────
[v3->v4] `tm_polygons()`: instead of `style = "jenks"`, use fill.scale = `tm_scale_intervals()`.
ℹ Migrate the argument(s) 'style', 'palette' (rename to 'values') to 'tm_scale_intervals(<HERE>)'[v3->v4] `tm_polygons()`: migrate the argument(s) related to the legend of the visual variable `fill` namely
'title' to 'fill.legend = tm_legend(<HERE>)'[cols4all] color palettes: use palettes from the R package cols4all. Run `cols4all::c4a_gui()` to explore them.
The old palette name "Greens" is named "brewer.greens"Multiple palettes called "greens" found: "brewer.greens", "matplotlib.greens". The first one, "brewer.greens", is returned.

2.Buidlding fishnet
grid <- st_make_grid(tracts_sf, 5000,
crs = st_crs(tracts_sf),
what = "polygons", square = TRUE)
n <- length(lengths(grid))
grid_sf <- st_sf(index = 1:n, grid)
head(grid_sf)
Simple feature collection with 6 features and 1 field
Geometry type: POLYGON
Dimension: XY
Bounding box: xmin: 531731.9 ymin: 147854 xmax: 561731.9 ymax: 152854
Projected CRS: +proj=lcc +datum=NAD27 +lon_0=-72d45 +lat_1=41d52 +lat_2=41d12 +lat_0=40d50 +x_0=182880.3657607315 +y_0=0 +units=us-ft +no_defs +ellps=clrk66 +nadgrids=@conus,@alaska,@ntv2_0.gsb,@ntv1_can.dat
index grid
1 1 POLYGON ((531731.9 147854, ...
2 2 POLYGON ((536731.9 147854, ...
3 3 POLYGON ((541731.9 147854, ...
4 4 POLYGON ((546731.9 147854, ...
5 5 POLYGON ((551731.9 147854, ...
6 6 POLYGON ((556731.9 147854, ...
names(grid_sf) <- c("grd_id","grid")
grd_bg <- tm_shape(grid_sf) + tm_polygons("grey90")
tracts <- tm_shape(tracts_sf) + tm_borders(col = "red")
grd_bg + tracts

3. Spatial intersection
new_sf <- st_intersection(grid_sf, tracts_sf)
警告: attribute variables are assumed to be spatially constant throughout all geometries
new_lyr <- tm_shape(new_sf) + tm_polygons("grey90")
new_lyr

4. Field calculation
head(new_sf)
Simple feature collection with 6 features and 78 fields
Geometry type: POLYGON
Dimension: XY
Bounding box: xmin: 538629.8 ymin: 178187.5 xmax: 546803.4 ymax: 188464.6
Projected CRS: +proj=lcc +datum=NAD27 +lon_0=-72d45 +lat_1=41d52 +lat_2=41d12 +lat_0=40d50 +x_0=182880.3657607315 +y_0=0 +units=us-ft +no_defs +ellps=clrk66 +nadgrids=@conus,@alaska,@ntv2_0.gsb,@ntv1_can.dat
grd_id AREA PERIMETER T009075H_ T009075H_I ARCINFOFPS ATLAS_S LOGRECNU STATEFPS CNTY MCD TRACTBNA
50 50 38821430 39255.55 2 554 090091413 1413 003043 09 009 075 1413
51 51 38821430 39255.55 2 554 090091413 1413 003043 09 009 075 1413
58 58 38821430 39255.55 2 554 090091413 1413 003043 09 009 075 1413
59 59 38821430 39255.55 2 554 090091413 1413 003043 09 009 075 1413
60 60 38821430 39255.55 2 554 090091413 1413 003043 09 009 075 1413
67 67 38821430 39255.55 2 554 090091413 1413 003043 09 009 075 1413
MAPINFOFPS STATE_ABBR CNTY_NAME LAND_AREA HSEHLD_1_M HSEHLD_1_F MARHH_CHD MARHH_NO_C MHH_CHILD MHH_NO_CHD
50 090091413 CT NEW HAVEN 3609 243 430 156 246 26 22
51 090091413 CT NEW HAVEN 3609 243 430 156 246 26 22
58 090091413 CT NEW HAVEN 3609 243 430 156 246 26 22
59 090091413 CT NEW HAVEN 3609 243 430 156 246 26 22
60 090091413 CT NEW HAVEN 3609 243 430 156 246 26 22
67 090091413 CT NEW HAVEN 3609 243 430 156 246 26 22
FHH_CHILD FHH_NO_CHD NONFAM_MHH NONFAM_FHH FAMHH_2PER FAMHH_3PER FAMHH_4PER FAMHH_5PER FAMHH_6PER FAMHH_7_UP
50 488 128 59 66 405 283 196 97 48 37
51 488 128 59 66 405 283 196 97 48 37
58 488 128 59 66 405 283 196 97 48 37
59 488 128 59 66 405 283 196 97 48 37
60 488 128 59 66 405 283 196 97 48 37
67 488 128 59 66 405 283 196 97 48 37
NONFAM_1PE NONFAM_2PE NONFAM_3PE NONFAM_4PE NONFAM_5PE NONFAM_6PE NONFAM_7_U HSE_UNITS OCCUPIED VACANT
50 673 88 15 8 11 0 3 1997 1864 133
51 673 88 15 8 11 0 3 1997 1864 133
58 673 88 15 8 11 0 3 1997 1864 133
59 673 88 15 8 11 0 3 1997 1864 133
60 673 88 15 8 11 0 3 1997 1864 133
67 673 88 15 8 11 0 3 1997 1864 133
P_VACANT OWNER_OCC RENTER_OCC P_OWNEROCC P_RENTROCC VACNT_RENT VACNT_SALE SEASONAL WH_OWNOCC BL_OWNOCC
50 6.65999 328 1536 16.42464 76.91537 70 10 8 271 53
51 6.65999 328 1536 16.42464 76.91537 70 10 8 271 53
58 6.65999 328 1536 16.42464 76.91537 70 10 8 271 53
59 6.65999 328 1536 16.42464 76.91537 70 10 8 271 53
60 6.65999 328 1536 16.42464 76.91537 70 10 8 271 53
67 6.65999 328 1536 16.42464 76.91537 70 10 8 271 53
AM_OWNOCC AS_OWNOCC OT_OWNOCC WH_RENTOCC BL_RENTOCC AM_RENTOCC AS_RENTOCC OT_RENTOCC UNT_1ROOM UNT_2ROOMS
50 1 0 3 715 760 7 7 47 75 136
51 1 0 3 715 760 7 7 47 75 136
58 1 0 3 715 760 7 7 47 75 136
59 1 0 3 715 760 7 7 47 75 136
60 1 0 3 715 760 7 7 47 75 136
67 1 0 3 715 760 7 7 47 75 136
UNT_3ROOMS UNT_4ROOMS UNT_5ROOMS UNT_6ROOMS UNT_7ROOMS UNT_8ROOMS UNT_9_UP UNT_1PER UNT_2PER UNT_3PER
50 415 577 492 168 77 34 23 673 493 298
51 415 577 492 168 77 34 23 673 493 298
58 415 577 492 168 77 34 23 673 493 298
59 415 577 492 168 77 34 23 673 493 298
60 415 577 492 168 77 34 23 673 493 298
67 415 577 492 168 77 34 23 673 493 298
UNT_4PER UNT_5PER UNT_6PER UNT_7_UP PERS_UNIT SPLIT grid
50 204 108 48 40 2.42 0 POLYGON ((541731.9 182854, ...
51 204 108 48 40 2.42 0 POLYGON ((541731.9 182854, ...
58 204 108 48 40 2.42 0 POLYGON ((541731.9 182854, ...
59 204 108 48 40 2.42 0 POLYGON ((541731.9 182854, ...
60 204 108 48 40 2.42 0 POLYGON ((546731.9 183289.8...
67 204 108 48 40 2.42 0 POLYGON ((541856.5 187854, ...
new_sf$new_area<-st_area(new_sf)
new_sf$houses<- (new_sf$new_area / new_sf$AREA) * new_sf$HSE_UNITS
5. Grouping data
code example: pipes
library(tidyverse)
Popn_TWN = st_read("./data/Popn_TWN2.shp",options="ENCODING=BIG5")
options: ENCODING=BIG5
Reading layer `Popn_TWN2' from data source `C:\Users\user\Desktop\WK04\Data\Popn_TWN2.shp' using driver `ESRI Shapefile'
Simple feature collection with 368 features and 14 fields
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: -197572.5 ymin: 2295201 xmax: 606875.6 ymax: 2919551
Projected CRS: TWD97 / TM2 zone 121
head(Popn_TWN)
Simple feature collection with 6 features and 14 fields
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: -26119.97 ymin: 2700346 xmax: 201273.2 ymax: 2919551
Projected CRS: TWD97 / TM2 zone 121
TOWN_ID TOWN COUNTY_ID COUNTY A0A14_CNT A0A14_M A0A14_F A15A64_CNT A15A64_M A15A64_F A65UP_CNT A65UP_M
1 09007010 南竿鄉 09007 連江縣 971 499 472 5893 3391 2502 788 420
2 09007020 北竿鄉 09007 連江縣 249 136 113 1839 1035 804 316 167
3 09007030 莒光鄉 09007 連江縣 126 73 53 1296 815 481 216 114
4 09007040 東引鄉 09007 連江縣 179 107 72 1064 644 420 107 54
5 09020010 金城鎮 09020 金門縣 4501 2358 2143 33324 16606 16718 5478 2645
6 09020020 金沙鎮 09020 金門縣 1749 945 804 15916 7860 8056 2962 1412
A65UP_F INFO_TIME geometry
1 368 107Y06M MULTIPOLYGON (((145743.7 28...
2 149 107Y06M MULTIPOLYGON (((148122.7 28...
3 102 107Y06M MULTIPOLYGON (((146282.4 28...
4 53 107Y06M MULTIPOLYGON (((190338.5 28...
5 2833 107Y06M MULTIPOLYGON (((-19937.24 2...
6 1550 107Y06M MULTIPOLYGON (((-9544.077 2...
# Popn_County = group_by(Popn_TWN, COUNTY_ID)
# plot(Popn_County)
# Popn_County = summarise(Popn_County, OLD = sum(A65UP_CNT))
# head(Popn_County)
Popn_County = Popn_TWN %>% group_by(COUNTY_ID) %>% summarise(OLD = sum(A65UP_CNT))
plot(Popn_County)

head(Popn_County)
Simple feature collection with 6 features and 2 fields
Geometry type: GEOMETRY
Dimension: XY
Bounding box: xmin: -41955.91 ymin: 2631327 xmax: 606875.6 ymax: 2919551
Projected CRS: TWD97 / TM2 zone 121
using pipes for grouping data
# new_sf <- summarise(group_by(new_sf, grd_id), count = sum(houses))
new_sf <- new_sf %>% group_by(grd_id) %>% summarise(count = sum(houses))
tm_shape(new_sf)+ tm_polygons("grey90")

6. Mapping grid_sf
head(new_sf)
Simple feature collection with 6 features and 2 fields
Geometry type: POLYGON
Dimension: XY
Bounding box: xmin: 554157.4 ymin: 147854 xmax: 562192 ymax: 157854
Projected CRS: +proj=lcc +datum=NAD27 +lon_0=-72d45 +lat_1=41d52 +lat_2=41d12 +lat_0=40d50 +x_0=182880.3657607315 +y_0=0 +units=us-ft +no_defs +ellps=clrk66 +nadgrids=@conus,@alaska,@ntv2_0.gsb,@ntv1_can.dat
head(grid_sf)
Simple feature collection with 6 features and 1 field
Geometry type: POLYGON
Dimension: XY
Bounding box: xmin: 531731.9 ymin: 147854 xmax: 561731.9 ymax: 152854
Projected CRS: +proj=lcc +datum=NAD27 +lon_0=-72d45 +lat_1=41d52 +lat_2=41d12 +lat_0=40d50 +x_0=182880.3657607315 +y_0=0 +units=us-ft +no_defs +ellps=clrk66 +nadgrids=@conus,@alaska,@ntv2_0.gsb,@ntv1_can.dat
grd_id grid
1 1 POLYGON ((531731.9 147854, ...
2 2 POLYGON ((536731.9 147854, ...
3 3 POLYGON ((541731.9 147854, ...
4 4 POLYGON ((546731.9 147854, ...
5 5 POLYGON ((551731.9 147854, ...
6 6 POLYGON ((556731.9 147854, ...
grid_sf$houses <- 0
grid_sf$houses[new_sf$grd_id] <- new_sf$count # using [grd_id] as the index
tm_shape(grid_sf) +
tm_polygons("houses", palette = "Greens", style = "jenks", title = "No. of houses") +
tm_layout(frame = F, legend.position = c(1,0.5)) +
tm_shape(tracts_sf) + tm_borders(col = "red")
── tmap v3 code detected ───────────────────────────────────────────────────────────────────────────────────────
[v3->v4] `tm_polygons()`: instead of `style = "jenks"`, use fill.scale = `tm_scale_intervals()`.
ℹ Migrate the argument(s) 'style', 'palette' (rename to 'values') to 'tm_scale_intervals(<HERE>)'[v3->v4] `tm_polygons()`: migrate the argument(s) related to the legend of the visual variable `fill` namely
'title' to 'fill.legend = tm_legend(<HERE>)'[cols4all] color palettes: use palettes from the R package cols4all. Run `cols4all::c4a_gui()` to explore them.
The old palette name "Greens" is named "brewer.greens"Multiple palettes called "greens" found: "brewer.greens", "matplotlib.greens". The first one, "brewer.greens", is returned.

LS0tDQp0aXRsZTogIlNwYXRpYWwgQW5hbHlzaXM6IDA0Ig0KYXV0aG9yOiAiVHphaS1IdW5nIFdlbiINCmRhdGU6ICcyMDI1LTAzLTE3Jw0Kb3V0cHV0Og0KICBodG1sX25vdGVib29rOg0KICAgIHRvYzogdHJ1ZQ0KICAgIHRvY19kZXB0aDogNg0KICAgIHRvY19mbG9hdDogdHJ1ZQ0KLS0tDQojIDAuIENSUyB0cmFuc2Zvcm0NCmBgYHtyfQ0KbGlicmFyeShzZikNCg0KUG9wbl9UV04gPSBzdF9yZWFkKCIuL2RhdGEvUG9wbl9UV04yLnNocCIsb3B0aW9ucz0iRU5DT0RJTkc9QklHNSIpDQpzdF9jcnMoUG9wbl9UV04pDQoNCiMgRVBTRzozODI2IFRXRDk3LVRNMiB6b25lIDEyMQ0KIyBFUFNHOjQzMjYgV0dTODQNCg0KUG9wbl9UV04gPSBzdF90cmFuc2Zvcm0oUG9wbl9UV04sIDQzMjYpIA0Kc3RfY3JzKFBvcG5fVFdOKQ0KDQojIFBvcG5fVFdOID0gc3RfdHJhbnNmb3JtKFBvcG5fVFdOLCBzdF9jcnMoVFdOKSkNCg0KYGBgDQoNCg0KDQojIDEuIGxvYWQgZGF0YTogdHJhY3RzX3NmDQpgYGB7cn0NCnJtKGxpc3QgPSBscygpKQ0KDQpsaWJyYXJ5KHNmKQ0KbGlicmFyeSh0bWFwKQ0KDQpsb2FkKCIuL2RhdGEvU2FtcGxlMy5SRGF0YSIpDQoNCmhlYWQodHJhY3RzX3NmKQ0KDQp0bV9zaGFwZSh0cmFjdHNfc2YpICsgDQogIHRtX3BvbHlnb25zKCJIU0VfVU5JVFMiLCBwYWxldHRlID0gIkdyZWVucyIsIHN0eWxlID0gImplbmtzIiwgdGl0bGUgPSAiTm8uIG9mIGhvdXNlcyIpICsNCiAgdG1fbGF5b3V0KGZyYW1lID0gRiwgbGVnZW5kLnBvc2l0aW9uID0gYygxLDAuNSkpDQpgYGANCg0KIyAyLkJ1aWRsZGluZyBmaXNobmV0DQpgYGB7cn0NCmdyaWQgPC0gc3RfbWFrZV9ncmlkKHRyYWN0c19zZiwgNTAwMCwNCiAgICAgICAgICAgICAgICAgICAgIGNycyA9IHN0X2Nycyh0cmFjdHNfc2YpLA0KICAgICAgICAgICAgICAgICAgICAgd2hhdCA9ICJwb2x5Z29ucyIsIHNxdWFyZSA9IFRSVUUpDQoNCm4gPC0gbGVuZ3RoKGxlbmd0aHMoZ3JpZCkpDQoNCmdyaWRfc2YgPC0gc3Rfc2YoaW5kZXggPSAxOm4sIGdyaWQpDQpoZWFkKGdyaWRfc2YpDQpuYW1lcyhncmlkX3NmKSA8LSBjKCJncmRfaWQiLCJncmlkIikNCg0KZ3JkX2JnIDwtIHRtX3NoYXBlKGdyaWRfc2YpICsgdG1fcG9seWdvbnMoImdyZXk5MCIpDQp0cmFjdHMgPC0gdG1fc2hhcGUodHJhY3RzX3NmKSArIHRtX2JvcmRlcnMoY29sID0gInJlZCIpDQpncmRfYmcgKyB0cmFjdHMNCmBgYA0KDQojIDMuIFNwYXRpYWwgaW50ZXJzZWN0aW9uDQpgYGB7cn0NCm5ld19zZiA8LSBzdF9pbnRlcnNlY3Rpb24oZ3JpZF9zZiwgdHJhY3RzX3NmKQ0KbmV3X2x5ciA8LSB0bV9zaGFwZShuZXdfc2YpICsgdG1fcG9seWdvbnMoImdyZXk5MCIpDQpuZXdfbHlyDQpgYGANCg0KIyA0LiBGaWVsZCBjYWxjdWxhdGlvbg0KYGBge3J9DQpoZWFkKG5ld19zZikNCm5ld19zZiRuZXdfYXJlYTwtc3RfYXJlYShuZXdfc2YpDQpuZXdfc2YkaG91c2VzPC0gKG5ld19zZiRuZXdfYXJlYSAvIG5ld19zZiRBUkVBKSAqIG5ld19zZiRIU0VfVU5JVFMNCmBgYA0KDQojIDUuIEdyb3VwaW5nIGRhdGENCg0KIyMgY29kZSBleGFtcGxlOiBwaXBlcw0KYGBge3J9DQpsaWJyYXJ5KHRpZHl2ZXJzZSkNClBvcG5fVFdOID0gc3RfcmVhZCgiLi9kYXRhL1BvcG5fVFdOMi5zaHAiLG9wdGlvbnM9IkVOQ09ESU5HPUJJRzUiKQ0KaGVhZChQb3BuX1RXTikNCiMgUG9wbl9Db3VudHkgPSBncm91cF9ieShQb3BuX1RXTiwgQ09VTlRZX0lEKQ0KIyBwbG90KFBvcG5fQ291bnR5KQ0KIyBQb3BuX0NvdW50eSA9IHN1bW1hcmlzZShQb3BuX0NvdW50eSwgT0xEID0gc3VtKEE2NVVQX0NOVCkpDQojIGhlYWQoUG9wbl9Db3VudHkpDQoNClBvcG5fQ291bnR5ID0gUG9wbl9UV04gJT4lIGdyb3VwX2J5KENPVU5UWV9JRCkgJT4lIHN1bW1hcmlzZShPTEQgPSBzdW0oQTY1VVBfQ05UKSkNCnBsb3QoUG9wbl9Db3VudHkpDQpoZWFkKFBvcG5fQ291bnR5KQ0KYGBgDQoNCiMjIHVzaW5nIHBpcGVzIGZvciBncm91cGluZyBkYXRhDQpgYGB7cn0NCiMgbmV3X3NmIDwtIHN1bW1hcmlzZShncm91cF9ieShuZXdfc2YsIGdyZF9pZCksIGNvdW50ID0gc3VtKGhvdXNlcykpDQoNCm5ld19zZiA8LSBuZXdfc2YgJT4lIGdyb3VwX2J5KGdyZF9pZCkgJT4lIHN1bW1hcmlzZShjb3VudCA9IHN1bShob3VzZXMpKQ0KDQp0bV9zaGFwZShuZXdfc2YpKyB0bV9wb2x5Z29ucygiZ3JleTkwIikNCg0KYGBgDQoNCiMgNi4gTWFwcGluZyBncmlkX3NmDQpgYGB7cn0NCmhlYWQobmV3X3NmKQ0KaGVhZChncmlkX3NmKQ0KZ3JpZF9zZiRob3VzZXMgPC0gMA0KZ3JpZF9zZiRob3VzZXNbbmV3X3NmJGdyZF9pZF0gPC0gbmV3X3NmJGNvdW50ICAjIHVzaW5nIFtncmRfaWRdIGFzIHRoZSBpbmRleA0KDQp0bV9zaGFwZShncmlkX3NmKSArIA0KICB0bV9wb2x5Z29ucygiaG91c2VzIiwgcGFsZXR0ZSA9ICJHcmVlbnMiLCBzdHlsZSA9ICJqZW5rcyIsIHRpdGxlID0gIk5vLiBvZiBob3VzZXMiKSArDQogIHRtX2xheW91dChmcmFtZSA9IEYsIGxlZ2VuZC5wb3NpdGlvbiA9IGMoMSwwLjUpKSArDQogIHRtX3NoYXBlKHRyYWN0c19zZikgKyB0bV9ib3JkZXJzKGNvbCA9ICJyZWQiKQ0KYGBgDQoNCg==