Assignment
Read: - the tmap package document and the replication code - the tigris package document
Map: - Use the tigris package to retrieve county-level spatial shapefiles; - Use Social Explorer to retrieve county-level information of your own choice; - Map your county-level information using the tmap package. What can you see from this map? - Present the same county-level information in a more convention, non-spatial way
Discuss: - the strengths and weaknesses of the two approaches (i.e., spatial vs. non-spatial) - What does the “cb = TRUE” do? - What will happen if you change it to “cb = FALSE”? - Show an example
Introduction
The National Historical Geographic Information System (NHGIS) is a project that aggregates census data for usage in spatial mapping. The LEHD (Longitudinal Employer Household Dynamics) was last updated by NHGIS in 2015. The NHGIS data can be sourced from SocialExplorer, and I am looking at the total number of jobs across the continental United States. An additional bit of data needed is map shape files, which can be obtained through the Tigris package, as shown below.
Data
#get map files
library(tigris)
options(tigris_class = "sf")
#this next line does all the data downloading and cleaning
t_county <- counties(cb = TRUE)
names(t_county)
[1] "STATEFP" "COUNTYFP" "COUNTYNS" "AFFGEOID" "GEOID" "NAME" "LSAD" "ALAND" "AWATER"
[10] "geometry"
library(readr)
jdata <- read_csv(“/Users/meredithpowers/Desktop/alljobs.csv”)
# combine the two files
library(dplyr)
jdata <- jdata %>%
mutate(TotalJobs = as.integer(ORGRACN_B001_001)) %>%
mutate(fips = parse_integer(Geo_FIPS))
# a common mistake when joining a dataset by a variable is when you try to use two TYPES (categorical and integer, for example)
# something easily goes wrong at this next step unless you make sure they are both numerical variables, hence parse_integer function which is part of readr package
t_county <- t_county %>%
mutate(fips = parse_integer(GEOID))
# always a good idea to use the map file as base data, in case there are missing values in the other file
comb_data <- t_county %>%
left_join(jdata, by = "fips")
#subset of data limited to continental US
comb_data_sub <- subset(comb_data, STATEFP != "02") %>%
subset(STATEFP != "02") %>%
subset(STATEFP != "15") %>%
subset(STATEFP != "60") %>%
subset(STATEFP != "66") %>%
subset(STATEFP != "69") %>%
subset(STATEFP != "72") %>%
subset(STATEFP != "78")
Mapping
# draw the map with state borders and cleaned up county lines for visual impact
tm_shape(comb_data_sub) +
tm_polygons("TotalJobs", border.col = "grey", border.alpha = .4) +
tm_shape(us_states) +
tm_borders(lwd = .36, col = "black", alpha = 1)

Histogramming
library(ggplot2)
theme_set(theme_bw())
jobdata <- ggplot(comb_data_sub, aes(TotalJobs))
jobdata + geom_histogram(mapping = aes(x = TotalJobs)) +
ggtitle("Distribution of Counties by Number of Jobs") +
theme(plot.title = element_text(hjust = 0.5)) +
labs(x = "Number of Jobs", y = "Number of Counties") +
labs(caption = "There are a few counties with a much greater number of jobs than the majority of counties") +
theme(plot.caption = element_text(hjust = 0.5))

Discussion
The map clearly shows that most counties are the same shade of light yellow, indicating 0-1million jobs, while a few counties stand out as much darker and have 2-3 million or 4-5 million jobs. The map implies a positive skewed distribution, though the details are less clear. The map is useful for showing where the outliers are, which can lead to focusing on geographic regions for further study and comparison. It’s also great for presenting information to others, since the heatmap is easy to grasp. Still, there’s a lot of room in that “0 to 1 million jobs” category, and the map does not easily show off any of this variation.
The histogram shows us that this is a positively skewed distribution, showing that a very small number of counties have a much higher number of jobs that the rest of the country. The histogram is useful for confirming the appearance of the map, and it is also useful in showing the specific shape of the distribution – it very clearly offers a good estimation of the actual number of counties and the actual number of jobs. There are a lot of counties with under a million jobs, and this shows just how many are on the low end of that range (should prob change the scale for even more clarity).
What does the “cb = TRUE” do? What happens if we use “cb = FALSE” instead?
When cb is set to TRUE, tigris will download a generalized (1:500k) file. When cb is set to FALSE, tigris downloads the most detailed TIGER file – in this case, the boundary lines on the counties map file would be much more detailed. When looking at the general continental US, this is probably unnecessary and may needlessly increase loading time. However, when looking at a more zoomed in view of a state or a few specific counties, setting cb to FALSE could provide valuable information.
Even though I don’t think it matters for this case, here is an example of a new map using the CB false command
Example of cb = FALSE
#get detailed map files
options(tigris_class = "sf")
#this next line does all the data downloading and cleaning
c_county <- counties(cb = FALSE)
names(c_county)
[1] "STATEFP" "COUNTYFP" "COUNTYNS" "GEOID" "NAME" "NAMELSAD" "LSAD" "CLASSFP" "MTFCC"
[10] "CSAFP" "CBSAFP" "METDIVFP" "FUNCSTAT" "ALAND" "AWATER" "INTPTLAT" "INTPTLON" "geometry"
More variables! More detail?!
# combine two new files
jdata <- jdata %>%
mutate(TotalJobs = as.integer(ORGRACN_B001_001)) %>%
mutate(fips = parse_integer(Geo_FIPS))
c_county <- c_county %>%
mutate(fips = parse_integer(GEOID))
newdata <- c_county %>%
left_join(jdata, by = "fips")
#subset of data limited to continental US
newdata_sub <- subset(newdata, STATEFP != "02") %>%
subset(STATEFP != "02") %>%
subset(STATEFP != "15") %>%
subset(STATEFP != "60") %>%
subset(STATEFP != "66") %>%
subset(STATEFP != "69") %>%
subset(STATEFP != "72") %>%
subset(STATEFP != "78")
#draw the new detailed map
tm_shape(newdata_sub) +
tm_polygons("TotalJobs", border.col = "grey", border.alpha = .4) +
tm_shape(us_states) +
tm_borders(lwd = .36, col = "black", alpha = 1)

This is definitely a more detailed map, and it’s nice that some of the distracting lines (e.g., around the Great Lakes) are now gone!
LS0tCnRpdGxlOiAiSG9tZXdvcmsgMTA6IE1hcHBpbmcgRW1wbG95bWVudCBhY3Jvc3MgdGhlIFVTIgpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazoKICAgIHRoZW1lOiBsdW1lbgogIGh0bWxfZG9jdW1lbnQ6CiAgICBkZl9wcmludDogcGFnZWQKLS0tCgojIEFzc2lnbm1lbnQKCipSZWFkOioKLSB0aGUgdG1hcCBwYWNrYWdlIGRvY3VtZW50IGFuZCB0aGUgcmVwbGljYXRpb24gY29kZQotIHRoZSB0aWdyaXMgcGFja2FnZSBkb2N1bWVudAoKKk1hcDoqCi0gVXNlIHRoZSB0aWdyaXMgcGFja2FnZSB0byByZXRyaWV2ZSBjb3VudHktbGV2ZWwgc3BhdGlhbCBzaGFwZWZpbGVzOwotIFVzZSBTb2NpYWwgRXhwbG9yZXIgdG8gcmV0cmlldmUgY291bnR5LWxldmVsIGluZm9ybWF0aW9uIG9mIHlvdXIgb3duIGNob2ljZTsKLSBNYXAgeW91ciBjb3VudHktbGV2ZWwgaW5mb3JtYXRpb24gdXNpbmcgdGhlIHRtYXAgcGFja2FnZS4gV2hhdCBjYW4geW91IHNlZSBmcm9tIHRoaXMgbWFwPyAKLSBQcmVzZW50IHRoZSBzYW1lIGNvdW50eS1sZXZlbCBpbmZvcm1hdGlvbiBpbiBhIG1vcmUgY29udmVudGlvbiwgbm9uLXNwYXRpYWwgd2F5CgoqRGlzY3VzczoqCi0gdGhlIHN0cmVuZ3RocyBhbmQgd2Vha25lc3NlcyBvZiB0aGUgdHdvIGFwcHJvYWNoZXMgKGkuZS4sIHNwYXRpYWwgdnMuIG5vbi1zcGF0aWFsKQotIFdoYXQgZG9lcyB0aGUgImNiID0gVFJVRSIgZG8/Ci0gV2hhdCB3aWxsIGhhcHBlbiBpZiB5b3UgY2hhbmdlIGl0IHRvICJjYiA9IEZBTFNFIj8KLSBTaG93IGFuIGV4YW1wbGUKCiMgSW50cm9kdWN0aW9uIAoKVGhlIE5hdGlvbmFsIEhpc3RvcmljYWwgR2VvZ3JhcGhpYyBJbmZvcm1hdGlvbiBTeXN0ZW0gKE5IR0lTKSBpcyBhIHByb2plY3QgdGhhdCBhZ2dyZWdhdGVzIGNlbnN1cyBkYXRhIGZvciB1c2FnZSBpbiBzcGF0aWFsIG1hcHBpbmcuIFRoZSBMRUhEIChMb25naXR1ZGluYWwgRW1wbG95ZXIgSG91c2Vob2xkIER5bmFtaWNzKSB3YXMgbGFzdCB1cGRhdGVkIGJ5IE5IR0lTIGluIDIwMTUuIFRoZSBOSEdJUyBkYXRhIGNhbiBiZSBzb3VyY2VkIGZyb20gU29jaWFsRXhwbG9yZXIsIGFuZCBJIGFtIGxvb2tpbmcgYXQgdGhlIHRvdGFsIG51bWJlciBvZiBqb2JzIGFjcm9zcyB0aGUgY29udGluZW50YWwgVW5pdGVkIFN0YXRlcy4gQW4gYWRkaXRpb25hbCBiaXQgb2YgZGF0YSBuZWVkZWQgaXMgbWFwIHNoYXBlIGZpbGVzLCB3aGljaCBjYW4gYmUgb2J0YWluZWQgdGhyb3VnaCB0aGUgKlRpZ3JpcyogcGFja2FnZSwgYXMgc2hvd24gYmVsb3cuCgojIERhdGEKYGBge3J9CiNnZXQgbWFwIGZpbGVzCmxpYnJhcnkodGlncmlzKQpvcHRpb25zKHRpZ3Jpc19jbGFzcyA9ICJzZiIpCiN0aGlzIG5leHQgbGluZSBkb2VzIGFsbCB0aGUgZGF0YSBkb3dubG9hZGluZyBhbmQgY2xlYW5pbmcKdF9jb3VudHkgPC0gY291bnRpZXMoY2IgPSBUUlVFKQpuYW1lcyh0X2NvdW50eSkKYGBgCgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQojIHJlYWQgdGhlIGRhdGEgZmlsZQpsaWJyYXJ5KHJlYWRyKQpqZGF0YSA8LSByZWFkX2NzdigiL1VzZXJzL21lcmVkaXRocG93ZXJzL0Rlc2t0b3AvYWxsam9icy5jc3YiKQpgYGAKCmxpYnJhcnkocmVhZHIpCgpqZGF0YSA8LSByZWFkX2NzdigiL1VzZXJzL21lcmVkaXRocG93ZXJzL0Rlc2t0b3AvYWxsam9icy5jc3YiKQoKYGBge3J9CiMgY29tYmluZSB0aGUgdHdvIGZpbGVzCmxpYnJhcnkoZHBseXIpCmpkYXRhIDwtIGpkYXRhICU+JSAKICBtdXRhdGUoVG90YWxKb2JzID0gYXMuaW50ZWdlcihPUkdSQUNOX0IwMDFfMDAxKSkgJT4lCiAgbXV0YXRlKGZpcHMgPSBwYXJzZV9pbnRlZ2VyKEdlb19GSVBTKSkKIyBhIGNvbW1vbiBtaXN0YWtlIHdoZW4gam9pbmluZyBhIGRhdGFzZXQgYnkgYSB2YXJpYWJsZSBpcyB3aGVuIHlvdSB0cnkgdG8gdXNlIHR3byBUWVBFUyAoY2F0ZWdvcmljYWwgYW5kIGludGVnZXIsIGZvciBleGFtcGxlKQojIHNvbWV0aGluZyBlYXNpbHkgZ29lcyB3cm9uZyBhdCB0aGlzIG5leHQgc3RlcCB1bmxlc3MgeW91IG1ha2Ugc3VyZSB0aGV5IGFyZSBib3RoIG51bWVyaWNhbCB2YXJpYWJsZXMsIGhlbmNlIHBhcnNlX2ludGVnZXIgZnVuY3Rpb24gd2hpY2ggaXMgcGFydCBvZiByZWFkciBwYWNrYWdlCnRfY291bnR5IDwtIHRfY291bnR5ICU+JSAKICBtdXRhdGUoZmlwcyA9IHBhcnNlX2ludGVnZXIoR0VPSUQpKSAKIyBhbHdheXMgYSBnb29kIGlkZWEgdG8gdXNlIHRoZSBtYXAgZmlsZSBhcyBiYXNlIGRhdGEsIGluIGNhc2UgdGhlcmUgYXJlIG1pc3NpbmcgdmFsdWVzIGluIHRoZSBvdGhlciBmaWxlCmNvbWJfZGF0YSA8LSB0X2NvdW50eSAlPiUgCiAgbGVmdF9qb2luKGpkYXRhLCBieSA9ICJmaXBzIikKYGBgCgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojc3Vic2V0IG9mIGRhdGEgbGltaXRlZCB0byBjb250aW5lbnRhbCBVUwpjb21iX2RhdGFfc3ViIDwtIHN1YnNldChjb21iX2RhdGEsIFNUQVRFRlAgIT0gIjAyIikgJT4lCiAgICAgICAgICAgICAgICAgc3Vic2V0KFNUQVRFRlAgIT0gIjAyIikgJT4lIAogICAgICAgICAgICAgICAgIHN1YnNldChTVEFURUZQICE9ICIxNSIpICU+JSAKICAgICAgICAgICAgICAgICBzdWJzZXQoU1RBVEVGUCAhPSAiNjAiKSAlPiUgCiAgICAgICAgICAgICAgICAgc3Vic2V0KFNUQVRFRlAgIT0gIjY2IikgJT4lIAogICAgICAgICAgICAgICAgIHN1YnNldChTVEFURUZQICE9ICI2OSIpICU+JSAKICAgICAgICAgICAgICAgICBzdWJzZXQoU1RBVEVGUCAhPSAiNzIiKSAlPiUgCiAgICAgICAgICAgICAgICAgc3Vic2V0KFNUQVRFRlAgIT0gIjc4IikKYGBgCgojIE1hcHBpbmcKCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiMgZHJhdyB0aGUgbWFwIHdpdGggc3RhdGUgYm9yZGVycyBhbmQgY2xlYW5lZCB1cCBjb3VudHkgbGluZXMgZm9yIHZpc3VhbCBpbXBhY3QKdG1fc2hhcGUoY29tYl9kYXRhX3N1YikgKyAKICB0bV9wb2x5Z29ucygiVG90YWxKb2JzIiwgYm9yZGVyLmNvbCA9ICJncmV5IiwgYm9yZGVyLmFscGhhID0gLjQpICsgCiAgdG1fc2hhcGUodXNfc3RhdGVzKSArIAogIHRtX2JvcmRlcnMobHdkID0gLjM2LCBjb2wgPSAiYmxhY2siLCBhbHBoYSA9IDEpCgpgYGAKCiMgSGlzdG9ncmFtbWluZwoKYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KbGlicmFyeShnZ3Bsb3QyKQp0aGVtZV9zZXQodGhlbWVfYncoKSkKam9iZGF0YSA8LSBnZ3Bsb3QoY29tYl9kYXRhX3N1YiwgYWVzKFRvdGFsSm9icykpCmpvYmRhdGEgKyBnZW9tX2hpc3RvZ3JhbShtYXBwaW5nID0gYWVzKHggPSBUb3RhbEpvYnMpKSArCiAgZ2d0aXRsZSgiRGlzdHJpYnV0aW9uIG9mIENvdW50aWVzIGJ5IE51bWJlciBvZiBKb2JzIikgKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpKSArCiAgbGFicyh4ID0gIk51bWJlciBvZiBKb2JzIiwgeSA9ICJOdW1iZXIgb2YgQ291bnRpZXMiKSArCiAgbGFicyhjYXB0aW9uID0gIlRoZXJlIGFyZSBhIGZldyBjb3VudGllcyB3aXRoIGEgbXVjaCBncmVhdGVyIG51bWJlciBvZiBqb2JzIHRoYW4gdGhlIG1ham9yaXR5IG9mIGNvdW50aWVzIikgKwogIHRoZW1lKHBsb3QuY2FwdGlvbiA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpCmBgYAoKIyBEaXNjdXNzaW9uCgpUaGUgbWFwIGNsZWFybHkgc2hvd3MgdGhhdCBtb3N0IGNvdW50aWVzIGFyZSB0aGUgc2FtZSBzaGFkZSBvZiBsaWdodCB5ZWxsb3csIGluZGljYXRpbmcgMC0xbWlsbGlvbiBqb2JzLCB3aGlsZSBhIGZldyBjb3VudGllcyBzdGFuZCBvdXQgYXMgbXVjaCBkYXJrZXIgYW5kIGhhdmUgMi0zIG1pbGxpb24gb3IgNC01IG1pbGxpb24gam9icy4gVGhlIG1hcCBpbXBsaWVzIGEgcG9zaXRpdmUgc2tld2VkIGRpc3RyaWJ1dGlvbiwgdGhvdWdoIHRoZSBkZXRhaWxzIGFyZSBsZXNzIGNsZWFyLiBUaGUgbWFwIGlzIHVzZWZ1bCBmb3Igc2hvd2luZyB3aGVyZSB0aGUgb3V0bGllcnMgYXJlLCB3aGljaCBjYW4gbGVhZCB0byBmb2N1c2luZyBvbiBnZW9ncmFwaGljIHJlZ2lvbnMgZm9yIGZ1cnRoZXIgc3R1ZHkgYW5kIGNvbXBhcmlzb24uIEl0J3MgYWxzbyBncmVhdCBmb3IgcHJlc2VudGluZyBpbmZvcm1hdGlvbiB0byBvdGhlcnMsIHNpbmNlIHRoZSBoZWF0bWFwIGlzIGVhc3kgdG8gZ3Jhc3AuIFN0aWxsLCB0aGVyZSdzIGEgbG90IG9mIHJvb20gaW4gdGhhdCAiMCB0byAxIG1pbGxpb24gam9icyIgY2F0ZWdvcnksIGFuZCB0aGUgbWFwIGRvZXMgbm90IGVhc2lseSBzaG93IG9mZiBhbnkgb2YgdGhpcyB2YXJpYXRpb24uCgpUaGUgaGlzdG9ncmFtIHNob3dzIHVzIHRoYXQgdGhpcyBpcyBhIHBvc2l0aXZlbHkgc2tld2VkIGRpc3RyaWJ1dGlvbiwgc2hvd2luZyB0aGF0IGEgdmVyeSBzbWFsbCBudW1iZXIgb2YgY291bnRpZXMgaGF2ZSBhIG11Y2ggaGlnaGVyIG51bWJlciBvZiBqb2JzIHRoYXQgdGhlIHJlc3Qgb2YgdGhlIGNvdW50cnkuIFRoZSBoaXN0b2dyYW0gaXMgdXNlZnVsIGZvciBjb25maXJtaW5nIHRoZSBhcHBlYXJhbmNlIG9mIHRoZSBtYXAsIGFuZCBpdCBpcyBhbHNvIHVzZWZ1bCBpbiBzaG93aW5nIHRoZSBzcGVjaWZpYyBzaGFwZSBvZiB0aGUgZGlzdHJpYnV0aW9uIC0tIGl0IHZlcnkgY2xlYXJseSBvZmZlcnMgYSBnb29kIGVzdGltYXRpb24gb2YgdGhlIGFjdHVhbCBudW1iZXIgb2YgY291bnRpZXMgYW5kIHRoZSBhY3R1YWwgbnVtYmVyIG9mIGpvYnMuIFRoZXJlIGFyZSBhIGxvdCBvZiBjb3VudGllcyB3aXRoIHVuZGVyIGEgbWlsbGlvbiBqb2JzLCBhbmQgdGhpcyBzaG93cyBqdXN0IGhvdyBtYW55IGFyZSBvbiB0aGUgbG93IGVuZCBvZiB0aGF0IHJhbmdlIChzaG91bGQgcHJvYiBjaGFuZ2UgdGhlIHNjYWxlIGZvciBldmVuIG1vcmUgY2xhcml0eSkuCgoKIyMjIyMgV2hhdCBkb2VzIHRoZSAiY2IgPSBUUlVFIiBkbz8gV2hhdCBoYXBwZW5zIGlmIHdlIHVzZSAiY2IgPSBGQUxTRSIgaW5zdGVhZD8KCldoZW4gY2IgaXMgc2V0IHRvIFRSVUUsICp0aWdyaXMqIHdpbGwgZG93bmxvYWQgYSBnZW5lcmFsaXplZCAoMTo1MDBrKSBmaWxlLiBXaGVuIGNiIGlzIHNldCB0byBGQUxTRSwgKnRpZ3JpcyogZG93bmxvYWRzIHRoZSBtb3N0IGRldGFpbGVkIFRJR0VSIGZpbGUgLS0gaW4gdGhpcyBjYXNlLCB0aGUgYm91bmRhcnkgbGluZXMgb24gdGhlIGNvdW50aWVzIG1hcCBmaWxlIHdvdWxkIGJlIG11Y2ggbW9yZSBkZXRhaWxlZC4gV2hlbiBsb29raW5nIGF0IHRoZSBnZW5lcmFsIGNvbnRpbmVudGFsIFVTLCB0aGlzIGlzIHByb2JhYmx5IHVubmVjZXNzYXJ5IGFuZCBtYXkgbmVlZGxlc3NseSBpbmNyZWFzZSBsb2FkaW5nIHRpbWUuIEhvd2V2ZXIsIHdoZW4gbG9va2luZyBhdCBhIG1vcmUgem9vbWVkIGluIHZpZXcgb2YgYSBzdGF0ZSBvciBhIGZldyBzcGVjaWZpYyBjb3VudGllcywgc2V0dGluZyBjYiB0byBGQUxTRSBjb3VsZCBwcm92aWRlIHZhbHVhYmxlIGluZm9ybWF0aW9uLgoKRXZlbiB0aG91Z2ggSSBkb24ndCB0aGluayBpdCBtYXR0ZXJzIGZvciB0aGlzIGNhc2UsIGhlcmUgaXMgYW4gZXhhbXBsZSBvZiBhIG5ldyBtYXAgdXNpbmcgdGhlIENCIGZhbHNlIGNvbW1hbmQKCiMjIEV4YW1wbGUgb2YgY2IgPSBGQUxTRQoKYGBge3J9CiNnZXQgZGV0YWlsZWQgbWFwIGZpbGVzCm9wdGlvbnModGlncmlzX2NsYXNzID0gInNmIikKI3RoaXMgbmV4dCBsaW5lIGRvZXMgYWxsIHRoZSBkYXRhIGRvd25sb2FkaW5nIGFuZCBjbGVhbmluZwpjX2NvdW50eSA8LSBjb3VudGllcyhjYiA9IEZBTFNFKQpuYW1lcyhjX2NvdW50eSkKYGBgCgoKTW9yZSB2YXJpYWJsZXMhIE1vcmUgZGV0YWlsPyEKCgpgYGB7cn0KIyBjb21iaW5lIHR3byBuZXcgZmlsZXMKamRhdGEgPC0gamRhdGEgJT4lIAogIG11dGF0ZShUb3RhbEpvYnMgPSBhcy5pbnRlZ2VyKE9SR1JBQ05fQjAwMV8wMDEpKSAlPiUKICBtdXRhdGUoZmlwcyA9IHBhcnNlX2ludGVnZXIoR2VvX0ZJUFMpKQpjX2NvdW50eSA8LSBjX2NvdW50eSAlPiUgCiAgbXV0YXRlKGZpcHMgPSBwYXJzZV9pbnRlZ2VyKEdFT0lEKSkgCm5ld2RhdGEgPC0gY19jb3VudHkgJT4lIAogIGxlZnRfam9pbihqZGF0YSwgYnkgPSAiZmlwcyIpCmBgYAoKCmBgYHtyfQojc3Vic2V0IG9mIGRhdGEgbGltaXRlZCB0byBjb250aW5lbnRhbCBVUwpuZXdkYXRhX3N1YiA8LSBzdWJzZXQobmV3ZGF0YSwgU1RBVEVGUCAhPSAiMDIiKSAlPiUKICAgICAgICAgICAgICAgICBzdWJzZXQoU1RBVEVGUCAhPSAiMDIiKSAlPiUgCiAgICAgICAgICAgICAgICAgc3Vic2V0KFNUQVRFRlAgIT0gIjE1IikgJT4lIAogICAgICAgICAgICAgICAgIHN1YnNldChTVEFURUZQICE9ICI2MCIpICU+JSAKICAgICAgICAgICAgICAgICBzdWJzZXQoU1RBVEVGUCAhPSAiNjYiKSAlPiUgCiAgICAgICAgICAgICAgICAgc3Vic2V0KFNUQVRFRlAgIT0gIjY5IikgJT4lIAogICAgICAgICAgICAgICAgIHN1YnNldChTVEFURUZQICE9ICI3MiIpICU+JSAKICAgICAgICAgICAgICAgICBzdWJzZXQoU1RBVEVGUCAhPSAiNzgiKQpgYGAKCmBgYHtyfQojZHJhdyB0aGUgbmV3IGRldGFpbGVkIG1hcAp0bV9zaGFwZShuZXdkYXRhX3N1YikgKyAKICB0bV9wb2x5Z29ucygiVG90YWxKb2JzIiwgYm9yZGVyLmNvbCA9ICJncmV5IiwgYm9yZGVyLmFscGhhID0gLjQpICsgCiAgdG1fc2hhcGUodXNfc3RhdGVzKSArIAogIHRtX2JvcmRlcnMobHdkID0gLjM2LCBjb2wgPSAiYmxhY2siLCBhbHBoYSA9IDEpCmBgYAoKVGhpcyBpcyBkZWZpbml0ZWx5IGEgbW9yZSBkZXRhaWxlZCBtYXAsIGFuZCBpdCdzIG5pY2UgdGhhdCBzb21lIG9mIHRoZSBkaXN0cmFjdGluZyBsaW5lcyAoZS5nLiwgYXJvdW5kIHRoZSBHcmVhdCBMYWtlcykgYXJlIG5vdyBnb25lIQoKCg==