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==