*These are updates. The 2022 version from Corey Sparks, Ph.D. can be found here.


In this example we will use the IPUMS USA data to produce survey-based estimates for various geographic levels present in the IPUMS. This example uses the 2014-2018 ACS 5-year microdata.

Click here for more info on setting chunk options.

The good folks at IPUMS have created a library to read in their data from the .gz file that you download. Be sure you right click and save the DDI codebook when you create your extract

This will save the .XML file that contains all the information on the data (what is contained in the data file) to your computer. When using IPUMS, it will have a name like usa_xxxxx.xml where the x’s represent the extract number (I’m on 2 as of today).

You will also need to download the data file, by right clicking the Download .DAT link in the above image. This will save a .GZ file to your computer, again with a name like: usa_xxxxx.dat.gz. Make sure this file and the XML file from above are in the same folder, preferably your class folder.

Be sure the ipumsr package is installed. Click here for a PDF of ipumsr package documentation.

library(ipumsr) #new library for GIS class
## Warning: package 'ipumsr' was built under R version 4.2.3
ddi <- read_ipums_ddi("usa_00004.xml") #R Markdown uses the same directory where you save this file, so no need to repeat unless your .xml is located elsewhere
data <- read_ipums_micro(ddi)
## Use of data from IPUMS USA is subject to conditions including that users should
## cite the data appropriately. Use command `ipums_conditions()` for more details.
data<-haven::zap_labels(data) #necessary to avoid problems with "labelled" data class (removes variable labels); 'ipumsr' imports package 'haven' to use zap_labels
names(data)<-tolower(names(data)) #tolower changes any uppercase letters in variable names to lowercase

Load Some Other Packages

library(survey, quietly = T)
## Warning: package 'survey' was built under R version 4.2.3
library(tidyverse, quietly = T)
library(car, quietly = T)
## Warning: package 'car' was built under R version 4.2.3
## Warning: package 'carData' was built under R version 4.2.3
library(ggplot2, quietly = T)
library(tigris, quietly = T)
library(classInt, quietly = T)
library(tmap, quietly = T)

Download Geographic Data for Public Use Microdata Areas (PUMAs)

The IPUMS data we just downloaded doesn’t come with any geographic data (i.e., it has FIPS codes, but not the geographic data component).

The Public Use Microdata Area is the lowest level of geography in the PUMS data. They correspond to geographic ares of ~ 100,000 people. Here are some helpful sites about PUMAs:

  1. Missouri Census Data Center - All About Public-Use Microdata Areas (PUMAs)

  2. US Census - Public Use Microdata Areas (PUMAs)

  3. US Census - 2020 Public Use Microdata Areas Program Frequently Asked Questions (FAQs)

For more information about tigris package click here and here.

options(tigris_class = "sf")
pumas<-pumas(state = "TX", #match these to the data you downloaded from IPUMS
             year = 2018, #match these to the data you downloaded from IPUMS
             cb = T)
## 
Downloading: 16 kB     
Downloading: 16 kB     
Downloading: 25 kB     
Downloading: 25 kB     
Downloading: 25 kB     
Downloading: 25 kB     
Downloading: 41 kB     
Downloading: 41 kB     
Downloading: 41 kB     
Downloading: 41 kB     
Downloading: 49 kB     
Downloading: 49 kB     
Downloading: 49 kB     
Downloading: 49 kB     
Downloading: 49 kB     
Downloading: 49 kB     
Downloading: 49 kB     
Downloading: 49 kB     
Downloading: 68 kB     
Downloading: 68 kB     
Downloading: 68 kB     
Downloading: 68 kB     
Downloading: 68 kB     
Downloading: 68 kB     
Downloading: 68 kB     
Downloading: 68 kB     
Downloading: 68 kB     
Downloading: 68 kB     
Downloading: 84 kB     
Downloading: 84 kB     
Downloading: 84 kB     
Downloading: 84 kB     
Downloading: 92 kB     
Downloading: 92 kB     
Downloading: 92 kB     
Downloading: 92 kB     
Downloading: 92 kB     
Downloading: 92 kB     
Downloading: 110 kB     
Downloading: 110 kB     
Downloading: 120 kB     
Downloading: 120 kB     
Downloading: 120 kB     
Downloading: 120 kB     
Downloading: 120 kB     
Downloading: 120 kB     
Downloading: 130 kB     
Downloading: 130 kB     
Downloading: 130 kB     
Downloading: 130 kB     
Downloading: 140 kB     
Downloading: 140 kB     
Downloading: 140 kB     
Downloading: 140 kB     
Downloading: 160 kB     
Downloading: 160 kB     
Downloading: 170 kB     
Downloading: 170 kB     
Downloading: 170 kB     
Downloading: 170 kB     
Downloading: 170 kB     
Downloading: 170 kB     
Downloading: 180 kB     
Downloading: 180 kB     
Downloading: 190 kB     
Downloading: 190 kB     
Downloading: 190 kB     
Downloading: 190 kB     
Downloading: 190 kB     
Downloading: 190 kB     
Downloading: 210 kB     
Downloading: 210 kB     
Downloading: 220 kB     
Downloading: 220 kB     
Downloading: 220 kB     
Downloading: 220 kB     
Downloading: 220 kB     
Downloading: 220 kB     
Downloading: 230 kB     
Downloading: 230 kB     
Downloading: 230 kB     
Downloading: 230 kB     
Downloading: 240 kB     
Downloading: 240 kB     
Downloading: 250 kB     
Downloading: 250 kB     
Downloading: 250 kB     
Downloading: 250 kB     
Downloading: 270 kB     
Downloading: 270 kB     
Downloading: 270 kB     
Downloading: 270 kB     
Downloading: 270 kB     
Downloading: 270 kB     
Downloading: 290 kB     
Downloading: 290 kB     
Downloading: 300 kB     
Downloading: 300 kB     
Downloading: 300 kB     
Downloading: 300 kB     
Downloading: 310 kB     
Downloading: 310 kB     
Downloading: 310 kB     
Downloading: 310 kB     
Downloading: 340 kB     
Downloading: 340 kB     
Downloading: 350 kB     
Downloading: 350 kB     
Downloading: 350 kB     
Downloading: 350 kB     
Downloading: 350 kB     
Downloading: 350 kB     
Downloading: 370 kB     
Downloading: 370 kB     
Downloading: 380 kB     
Downloading: 380 kB     
Downloading: 390 kB     
Downloading: 390 kB     
Downloading: 410 kB     
Downloading: 410 kB     
Downloading: 410 kB     
Downloading: 410 kB     
Downloading: 430 kB     
Downloading: 430 kB     
Downloading: 440 kB     
Downloading: 440 kB     
Downloading: 440 kB     
Downloading: 440 kB     
Downloading: 440 kB     
Downloading: 440 kB     
Downloading: 450 kB     
Downloading: 450 kB     
Downloading: 460 kB     
Downloading: 460 kB     
Downloading: 480 kB     
Downloading: 480 kB     
Downloading: 490 kB     
Downloading: 490 kB     
Downloading: 500 kB     
Downloading: 500 kB     
Downloading: 520 kB     
Downloading: 520 kB     
Downloading: 530 kB     
Downloading: 530 kB     
Downloading: 550 kB     
Downloading: 550 kB     
Downloading: 570 kB     
Downloading: 570 kB     
Downloading: 580 kB     
Downloading: 580 kB     
Downloading: 610 kB     
Downloading: 610 kB     
Downloading: 610 kB     
Downloading: 610 kB     
Downloading: 630 kB     
Downloading: 630 kB     
Downloading: 650 kB     
Downloading: 650 kB     
Downloading: 650 kB     
Downloading: 650 kB     
Downloading: 670 kB     
Downloading: 670 kB     
Downloading: 670 kB     
Downloading: 670 kB     
Downloading: 690 kB     
Downloading: 690 kB     
Downloading: 690 kB     
Downloading: 690 kB
plot(pumas["GEOID10"],
     main = "Public Use Microdata Areas in Texas")

mapview::mapview(pumas, zcol= "GEOID10")

Prepare Variables

Here Dr. Sparks recoded several demographic variables.

READ YOUR CODEBOOK (DDI).

Click here for R documentation on the function Recode.

Click here for R documentation on the function interaction.

Click here for R documentation on the function relevel.

Click here for R documentation on the function as.factor.

Click here for R documentation on the function ifelese.

READ YOUR CODEBOOK (DDI).

  • See how your variables are coded.

  • See how missing values are coded.

data$pwt <- data$perwt
data$hwt <- data$hhwt
#race/ethnicity
data$hisp <- Recode(data$hispan, recodes = "9=NA; 1:4='Hispanic'; 0='NonHispanic'")
data$race_rec <- Recode(data$race, recodes = "1='White'; 2='Black'; 3='Other'; 4:6='Asian'; 7:9='Other'")
data$race_eth <- interaction(data$hisp, data$race_rec, sep = "_")
data$race_eth  <- as.factor(ifelse(substr(as.character(data$race_eth),1,8) == "Hispanic", "Hispanic", as.character(data$race_eth)))
data$race_eth <- relevel(data$race_eth, ref = "NonHispanic_White")
#sex
data$male <- ifelse(data$sex == 1,1,0)
#education
data$educ_level<- Recode(data$educd, recodes = "2:61='0LT_HS';62:64='1_HSD/GED';65:80='2_somecoll';90:100='2_somecoll'; 81:83='3_AssocDegree';101='4_bachelordegree'; 110:116='4_BAplus_GradDegree'; else=NA")
#employment
data$employed <- Recode(data$wrklstwk, recodes = "1=0;2=1; else=NA")
#citizenship
data$cit<-Recode(data$citizen, recodes = "1='US born'; 2='naturalized'; 3:4='notcitizen';else=NA ")
#industry
data$ind_group<-Recode(data$ind, recodes = "170:490='ag_extract'; 770='construction'; 1070:3990='manufac'; 4070:5790='whole_retail'; 6070:6390='trans'; 6470:6780='information'; 6870:7190= 'fire'; 7270=7790='prof/sci/manage'; 7860:8470='edu/social'; 8560:8690='arts'; 8770:9290='other'; 9370:9590='public_adm'; 9670:9870='military'; else=NA ")
data$proftech <- Recode(data$ind, recodes = "7270:7490=1; 0=NA; else=0")
#age in 10 year intervals
data$agecat<-cut(data$age, breaks = c(0, 18, 20, 30, 40, 50, 65, 120), include.lowest = T)
data$income <- ifelse(data$incwage>=999998, NA, data$incwage) #if income is greater than 999998 then recode it as NA, otherwise keep as is

Generate Survey Design Object

Here we identify the person weights and the survey design variables. This is a stratified clustered sample. Here, for the ACS the strata are geographic chunks and the clusters are households. It’s not a random sample so need person weights.

head(data$perwt) #shows how many people each person in the sample represents (shows for the first 6 people)
## [1]  29  16  64 260  12  58
sum(data$perwt) #gives you the population of the place (in this case, Texas)
## [1] 28701845
des<-svydesign(ids = ~cluster, #these variables (cluster, strata, and pwt) are automatically downloaded from IPUMS
               strata = ~ strata,
               weights = ~pwt,
               data = data)

Perform Survey Estimation for PUMAs

The svyby() function allows us calculate estimates for different sub-domains within the data, this could be a demographic characteristic, but we’ll use our geographic level. Of course you could do both….

Click here or here for R documentation on svyby.

Click here for R documentation on the function svytable.

Click here for R documentation on formulas and ~.

Click here for R documentation on I.

test<-svytable(~I(cit=="US born")+puma+sex, design=des )
puma_est_edu<-svyby(formula = ~educ_level, #what I want to take the % of, I want the % in each education level
                    by = ~puma, #...so taking the % of each educational level in each PUMA
                    design = subset(des, age>25), #Census doesn't get education level for those age 25 and under; subsetting the dataset to only include those over 25
                    FUN=svymean, #the function I want is survey mean, so takes the mean of each level of this categorical variable and give a %
                    na.rm = TRUE ) #remove any missing values coded in the variable before it does calculations
puma_est_employ<-svyby(formula = ~employed, #employment rate (because coded 1,0)
                       by = ~puma,
                       design=subset(des, age %in% 18:65), #get working age people between age 18 and 65
                       FUN=svymean,
                       na.rm = TRUE )
puma_est_industry<-svyby(formula = ~proftech, #proportion of each PUMA where the workforce is proftech
                         by = ~puma+sex+race_eth,
                         design = subset(des, employed==1),
                         FUN = svymean,
                         na.rm = TRUE )
library(reldist)
## Warning: package 'reldist' was built under R version 4.2.3
## reldist: Relative Distribution Methods
## Version 1.7-2 created on 2023-02-16.
## copyright (c) 2003, Mark S. Handcock, University of California-Los Angeles
##  For citation information, type citation("reldist").
##  Type help(package="reldist") to get started.
gini.puma<-data%>% #calculate this measure of income inequality (Gini)
  filter(income >0, is.na(income)==F)%>% #filer to only have positive income (so not missing)
  group_by( puma, race_eth)%>% #group by PUMA and race/ethnicity; for every PUMA calculate income inequality between race/ethnicity groups
  summarize(ineq = gini(income, weights = pwt))%>% #gini function comes from the reldist package which allows person weights to calculate properly
  ungroup()
## `summarise()` has grouped output by 'puma'. You can override using the
## `.groups` argument.
head(puma_est_edu) #estimates of education by PUMA; first row shows about 23% of residents over age 25 in that PUMA have less than HS education; can map any column
head(puma_est_employ)
head(puma_est_industry) #first row shows for males non-Hispanic White is about 2% prof/tech in that PUMA

Join to Geography

Joining the survey estimates data to the geography data. Every row in each dataset is one PUMA.

See How to Do a Left Join in R (With Examples) and Merge Data Frames in R for some more insight into joins.

pumas$puma<-as.numeric(pumas$PUMACE10) #PUMACE10 is the PUMA variable in the spatial data; have to make it numeric because it's numeric in the survey estimates
geo1<-left_join(pumas, puma_est_employ, by=c("puma"= "puma")) #join the geography (pumas) to the statistical estimate (puma_est_employ); the variable captured in both is called "puma"
head(geo1)
geo2<-left_join(pumas, puma_est_industry, by=c("puma"= "puma"))
head(geo2)
geo3<-left_join(pumas, gini.puma, by=c("puma"= "puma"))
head(geo2)

Map Estimates

Employment Rates by PUMA

tmap_mode("view") #can use tmap because all spatial data
## tmap mode set to interactive viewing
geo1%>% #feed this employment dataset (made in last chunk) into tmap
  tm_shape()+
  tm_polygons("employed", #map the employed column
              style="kmeans", #type of mapping style breaks, could use Fisher or jenks or quantile etc.
              n=8, #8 classes
              legend.hist = TRUE) + #plot the histogram (if it weren't the interactive map)
  tm_layout(legend.outside = TRUE,  #plot the histogram/legend outside (if it weren't the interactive map)
            title = "Employment rate in Texas PUMAs \n 2014-2018") 
tmap_mode("plot") #"view" isn't working for some reason
## tmap mode set to plotting
geo2%>%
  tm_shape()+
  tm_polygons("proftech",
              style="kmeans",
              n=8,
              legend.hist = TRUE) +
 tm_layout(legend.outside = TRUE,
            title = "Professional/Scientific/Technical Employment in Texas PUMAs \n 2014-2018")  

tmap_mode("plot") #"view" isn't working for some reason 
## tmap mode set to plotting
geo3%>%
tm_shape()+
  tm_polygons("ineq",
              style="kmeans",
              n=8,
              legend.hist = TRUE) +
 tm_layout(legend.outside = TRUE,
            title = "Gini in Texas PUMAs \n 2014-2018")  

Estimation for Metro Areas

Here we use core based statistical areas instead of PUMAs. The geography corresponding to Metro Areas are Core Based Statistical Areas.

There are a lot of places in the state that aren’t Metropolitan areas, so they’re not represented at all in the map or the estimates.

mets<-core_based_statistical_areas(cb = T, year = 2018) #function from tigris to get these geographies
## 
Downloading: 25 kB     
Downloading: 25 kB     
Downloading: 49 kB     
Downloading: 49 kB     
Downloading: 57 kB     
Downloading: 57 kB     
Downloading: 57 kB     
Downloading: 57 kB     
Downloading: 82 kB     
Downloading: 82 kB     
Downloading: 82 kB     
Downloading: 82 kB     
Downloading: 97 kB     
Downloading: 97 kB     
Downloading: 97 kB     
Downloading: 97 kB     
Downloading: 120 kB     
Downloading: 120 kB     
Downloading: 140 kB     
Downloading: 140 kB     
Downloading: 150 kB     
Downloading: 150 kB     
Downloading: 160 kB     
Downloading: 160 kB     
Downloading: 160 kB     
Downloading: 160 kB     
Downloading: 200 kB     
Downloading: 200 kB     
Downloading: 220 kB     
Downloading: 220 kB     
Downloading: 240 kB     
Downloading: 240 kB     
Downloading: 240 kB     
Downloading: 240 kB     
Downloading: 270 kB     
Downloading: 270 kB     
Downloading: 280 kB     
Downloading: 280 kB     
Downloading: 280 kB     
Downloading: 280 kB     
Downloading: 300 kB     
Downloading: 300 kB     
Downloading: 310 kB     
Downloading: 310 kB     
Downloading: 310 kB     
Downloading: 310 kB     
Downloading: 330 kB     
Downloading: 330 kB     
Downloading: 330 kB     
Downloading: 330 kB     
Downloading: 350 kB     
Downloading: 350 kB     
Downloading: 370 kB     
Downloading: 370 kB     
Downloading: 370 kB     
Downloading: 370 kB     
Downloading: 400 kB     
Downloading: 400 kB     
Downloading: 410 kB     
Downloading: 410 kB     
Downloading: 410 kB     
Downloading: 410 kB     
Downloading: 480 kB     
Downloading: 480 kB     
Downloading: 500 kB     
Downloading: 500 kB     
Downloading: 520 kB     
Downloading: 520 kB     
Downloading: 530 kB     
Downloading: 530 kB     
Downloading: 540 kB     
Downloading: 540 kB     
Downloading: 540 kB     
Downloading: 540 kB     
Downloading: 560 kB     
Downloading: 560 kB     
Downloading: 590 kB     
Downloading: 590 kB     
Downloading: 600 kB     
Downloading: 600 kB     
Downloading: 620 kB     
Downloading: 620 kB     
Downloading: 640 kB     
Downloading: 640 kB     
Downloading: 650 kB     
Downloading: 650 kB     
Downloading: 650 kB     
Downloading: 650 kB     
Downloading: 670 kB     
Downloading: 670 kB     
Downloading: 670 kB     
Downloading: 670 kB     
Downloading: 690 kB     
Downloading: 690 kB     
Downloading: 690 kB     
Downloading: 690 kB     
Downloading: 720 kB     
Downloading: 720 kB     
Downloading: 720 kB     
Downloading: 720 kB     
Downloading: 720 kB     
Downloading: 720 kB     
Downloading: 740 kB     
Downloading: 740 kB     
Downloading: 770 kB     
Downloading: 770 kB     
Downloading: 780 kB     
Downloading: 780 kB     
Downloading: 780 kB     
Downloading: 780 kB     
Downloading: 790 kB     
Downloading: 790 kB     
Downloading: 790 kB     
Downloading: 790 kB     
Downloading: 790 kB     
Downloading: 790 kB     
Downloading: 810 kB     
Downloading: 810 kB     
Downloading: 830 kB     
Downloading: 830 kB     
Downloading: 840 kB     
Downloading: 840 kB     
Downloading: 840 kB     
Downloading: 840 kB     
Downloading: 870 kB     
Downloading: 870 kB     
Downloading: 870 kB     
Downloading: 870 kB     
Downloading: 890 kB     
Downloading: 890 kB     
Downloading: 910 kB     
Downloading: 910 kB     
Downloading: 930 kB     
Downloading: 930 kB     
Downloading: 930 kB     
Downloading: 930 kB     
Downloading: 960 kB     
Downloading: 960 kB     
Downloading: 970 kB     
Downloading: 970 kB     
Downloading: 970 kB     
Downloading: 970 kB     
Downloading: 990 kB     
Downloading: 990 kB     
Downloading: 990 kB     
Downloading: 990 kB     
Downloading: 1 MB     
Downloading: 1 MB     
Downloading: 1 MB     
Downloading: 1 MB     
Downloading: 1 MB     
Downloading: 1 MB     
Downloading: 1 MB     
Downloading: 1 MB     
Downloading: 1.1 MB     
Downloading: 1.1 MB     
Downloading: 1.1 MB     
Downloading: 1.1 MB     
Downloading: 1.1 MB     
Downloading: 1.1 MB     
Downloading: 1.1 MB     
Downloading: 1.1 MB     
Downloading: 1.1 MB     
Downloading: 1.1 MB     
Downloading: 1.1 MB     
Downloading: 1.1 MB     
Downloading: 1.2 MB     
Downloading: 1.2 MB     
Downloading: 1.2 MB     
Downloading: 1.2 MB     
Downloading: 1.2 MB     
Downloading: 1.2 MB     
Downloading: 1.2 MB     
Downloading: 1.2 MB     
Downloading: 1.2 MB     
Downloading: 1.2 MB     
Downloading: 1.2 MB     
Downloading: 1.2 MB     
Downloading: 1.2 MB     
Downloading: 1.2 MB     
Downloading: 1.2 MB     
Downloading: 1.2 MB     
Downloading: 1.2 MB     
Downloading: 1.2 MB     
Downloading: 1.3 MB     
Downloading: 1.3 MB     
Downloading: 1.3 MB     
Downloading: 1.3 MB     
Downloading: 1.3 MB     
Downloading: 1.3 MB     
Downloading: 1.3 MB     
Downloading: 1.3 MB     
Downloading: 1.3 MB     
Downloading: 1.3 MB     
Downloading: 1.4 MB     
Downloading: 1.4 MB     
Downloading: 1.4 MB     
Downloading: 1.4 MB     
Downloading: 1.4 MB     
Downloading: 1.4 MB     
Downloading: 1.4 MB     
Downloading: 1.4 MB     
Downloading: 1.5 MB     
Downloading: 1.5 MB     
Downloading: 1.5 MB     
Downloading: 1.5 MB     
Downloading: 1.5 MB     
Downloading: 1.5 MB     
Downloading: 1.5 MB     
Downloading: 1.5 MB     
Downloading: 1.5 MB     
Downloading: 1.5 MB     
Downloading: 1.5 MB     
Downloading: 1.5 MB     
Downloading: 1.6 MB     
Downloading: 1.6 MB     
Downloading: 1.6 MB     
Downloading: 1.6 MB     
Downloading: 1.6 MB     
Downloading: 1.6 MB     
Downloading: 1.6 MB     
Downloading: 1.6 MB     
Downloading: 1.6 MB     
Downloading: 1.6 MB     
Downloading: 1.6 MB     
Downloading: 1.6 MB     
Downloading: 1.6 MB     
Downloading: 1.6 MB     
Downloading: 1.6 MB     
Downloading: 1.6 MB     
Downloading: 1.6 MB     
Downloading: 1.6 MB     
Downloading: 1.7 MB     
Downloading: 1.7 MB     
Downloading: 1.7 MB     
Downloading: 1.7 MB     
Downloading: 1.7 MB     
Downloading: 1.7 MB     
Downloading: 1.7 MB     
Downloading: 1.7 MB     
Downloading: 1.7 MB     
Downloading: 1.7 MB     
Downloading: 1.7 MB     
Downloading: 1.7 MB     
Downloading: 1.7 MB     
Downloading: 1.7 MB     
Downloading: 1.7 MB     
Downloading: 1.7 MB     
Downloading: 1.7 MB     
Downloading: 1.7 MB     
Downloading: 1.7 MB     
Downloading: 1.7 MB     
Downloading: 1.7 MB     
Downloading: 1.7 MB     
Downloading: 1.8 MB     
Downloading: 1.8 MB     
Downloading: 1.8 MB     
Downloading: 1.8 MB     
Downloading: 1.8 MB     
Downloading: 1.8 MB     
Downloading: 1.8 MB     
Downloading: 1.8 MB     
Downloading: 1.8 MB     
Downloading: 1.8 MB     
Downloading: 1.8 MB     
Downloading: 1.8 MB     
Downloading: 1.8 MB     
Downloading: 1.8 MB     
Downloading: 1.8 MB     
Downloading: 1.8 MB     
Downloading: 1.9 MB     
Downloading: 1.9 MB     
Downloading: 1.9 MB     
Downloading: 1.9 MB     
Downloading: 1.9 MB     
Downloading: 1.9 MB     
Downloading: 1.9 MB     
Downloading: 1.9 MB     
Downloading: 1.9 MB     
Downloading: 1.9 MB     
Downloading: 2 MB     
Downloading: 2 MB     
Downloading: 2 MB     
Downloading: 2 MB     
Downloading: 2 MB     
Downloading: 2 MB     
Downloading: 2 MB     
Downloading: 2 MB     
Downloading: 2 MB     
Downloading: 2 MB     
Downloading: 2 MB     
Downloading: 2 MB     
Downloading: 2 MB     
Downloading: 2 MB     
Downloading: 2 MB     
Downloading: 2 MB     
Downloading: 2.1 MB     
Downloading: 2.1 MB     
Downloading: 2.1 MB     
Downloading: 2.1 MB     
Downloading: 2.1 MB     
Downloading: 2.1 MB     
Downloading: 2.1 MB     
Downloading: 2.1 MB     
Downloading: 2.1 MB     
Downloading: 2.1 MB     
Downloading: 2.1 MB     
Downloading: 2.1 MB     
Downloading: 2.1 MB     
Downloading: 2.1 MB     
Downloading: 2.1 MB     
Downloading: 2.1 MB     
Downloading: 2.2 MB     
Downloading: 2.2 MB     
Downloading: 2.2 MB     
Downloading: 2.2 MB     
Downloading: 2.2 MB     
Downloading: 2.2 MB     
Downloading: 2.2 MB     
Downloading: 2.2 MB     
Downloading: 2.2 MB     
Downloading: 2.2 MB     
Downloading: 2.2 MB     
Downloading: 2.2 MB     
Downloading: 2.2 MB     
Downloading: 2.2 MB     
Downloading: 2.3 MB     
Downloading: 2.3 MB     
Downloading: 2.3 MB     
Downloading: 2.3 MB     
Downloading: 2.3 MB     
Downloading: 2.3 MB     
Downloading: 2.3 MB     
Downloading: 2.3 MB     
Downloading: 2.3 MB     
Downloading: 2.3 MB     
Downloading: 2.3 MB     
Downloading: 2.3 MB     
Downloading: 2.3 MB     
Downloading: 2.3 MB     
Downloading: 2.4 MB     
Downloading: 2.4 MB     
Downloading: 2.4 MB     
Downloading: 2.4 MB     
Downloading: 2.4 MB     
Downloading: 2.4 MB     
Downloading: 2.4 MB     
Downloading: 2.4 MB     
Downloading: 2.4 MB     
Downloading: 2.4 MB     
Downloading: 2.4 MB     
Downloading: 2.4 MB     
Downloading: 2.4 MB     
Downloading: 2.4 MB     
Downloading: 2.5 MB     
Downloading: 2.5 MB     
Downloading: 2.5 MB     
Downloading: 2.5 MB     
Downloading: 2.5 MB     
Downloading: 2.5 MB     
Downloading: 2.5 MB     
Downloading: 2.5 MB     
Downloading: 2.5 MB     
Downloading: 2.5 MB     
Downloading: 2.5 MB     
Downloading: 2.5 MB     
Downloading: 2.6 MB     
Downloading: 2.6 MB     
Downloading: 2.6 MB     
Downloading: 2.6 MB     
Downloading: 2.6 MB     
Downloading: 2.6 MB     
Downloading: 2.6 MB     
Downloading: 2.6 MB     
Downloading: 2.6 MB     
Downloading: 2.6 MB     
Downloading: 2.6 MB     
Downloading: 2.6 MB     
Downloading: 2.6 MB     
Downloading: 2.6 MB     
Downloading: 2.7 MB     
Downloading: 2.7 MB     
Downloading: 2.7 MB     
Downloading: 2.7 MB     
Downloading: 2.7 MB     
Downloading: 2.7 MB     
Downloading: 2.7 MB     
Downloading: 2.7 MB     
Downloading: 2.7 MB     
Downloading: 2.7 MB     
Downloading: 2.7 MB     
Downloading: 2.7 MB     
Downloading: 2.7 MB     
Downloading: 2.7 MB     
Downloading: 2.8 MB     
Downloading: 2.8 MB     
Downloading: 2.8 MB     
Downloading: 2.8 MB     
Downloading: 2.8 MB     
Downloading: 2.8 MB     
Downloading: 2.8 MB     
Downloading: 2.8 MB     
Downloading: 2.8 MB     
Downloading: 2.8 MB     
Downloading: 2.8 MB     
Downloading: 2.8 MB     
Downloading: 2.8 MB     
Downloading: 2.8 MB     
Downloading: 2.8 MB     
Downloading: 2.8 MB     
Downloading: 2.9 MB     
Downloading: 2.9 MB     
Downloading: 2.9 MB     
Downloading: 2.9 MB     
Downloading: 2.9 MB     
Downloading: 2.9 MB     
Downloading: 2.9 MB     
Downloading: 2.9 MB     
Downloading: 2.9 MB     
Downloading: 2.9 MB     
Downloading: 3 MB     
Downloading: 3 MB     
Downloading: 3 MB     
Downloading: 3 MB     
Downloading: 3 MB     
Downloading: 3 MB     
Downloading: 3 MB     
Downloading: 3 MB     
Downloading: 3 MB     
Downloading: 3 MB     
Downloading: 3 MB     
Downloading: 3 MB     
Downloading: 3 MB     
Downloading: 3 MB     
Downloading: 3 MB     
Downloading: 3 MB     
Downloading: 3 MB     
Downloading: 3 MB     
Downloading: 3.1 MB     
Downloading: 3.1 MB     
Downloading: 3.1 MB     
Downloading: 3.1 MB     
Downloading: 3.1 MB     
Downloading: 3.1 MB     
Downloading: 3.1 MB     
Downloading: 3.1 MB     
Downloading: 3.1 MB     
Downloading: 3.1 MB     
Downloading: 3.1 MB     
Downloading: 3.1 MB     
Downloading: 3.1 MB     
Downloading: 3.1 MB     
Downloading: 3.1 MB     
Downloading: 3.1 MB     
Downloading: 3.2 MB     
Downloading: 3.2 MB     
Downloading: 3.2 MB     
Downloading: 3.2 MB     
Downloading: 3.2 MB     
Downloading: 3.2 MB     
Downloading: 3.2 MB     
Downloading: 3.2 MB     
Downloading: 3.2 MB     
Downloading: 3.2 MB     
Downloading: 3.3 MB     
Downloading: 3.3 MB     
Downloading: 3.3 MB     
Downloading: 3.3 MB     
Downloading: 3.3 MB     
Downloading: 3.3 MB     
Downloading: 3.3 MB     
Downloading: 3.3 MB     
Downloading: 3.3 MB     
Downloading: 3.3 MB     
Downloading: 3.3 MB     
Downloading: 3.3 MB     
Downloading: 3.3 MB     
Downloading: 3.3 MB     
Downloading: 3.4 MB     
Downloading: 3.4 MB     
Downloading: 3.4 MB     
Downloading: 3.4 MB     
Downloading: 3.4 MB     
Downloading: 3.4 MB     
Downloading: 3.4 MB     
Downloading: 3.4 MB     
Downloading: 3.4 MB     
Downloading: 3.4 MB     
Downloading: 3.4 MB     
Downloading: 3.4 MB     
Downloading: 3.5 MB     
Downloading: 3.5 MB     
Downloading: 3.5 MB     
Downloading: 3.5 MB     
Downloading: 3.5 MB     
Downloading: 3.5 MB     
Downloading: 3.5 MB     
Downloading: 3.5 MB     
Downloading: 3.5 MB     
Downloading: 3.5 MB     
Downloading: 3.5 MB     
Downloading: 3.5 MB     
Downloading: 3.5 MB     
Downloading: 3.5 MB     
Downloading: 3.5 MB     
Downloading: 3.5 MB     
Downloading: 3.5 MB     
Downloading: 3.5 MB     
Downloading: 3.6 MB     
Downloading: 3.6 MB     
Downloading: 3.6 MB     
Downloading: 3.6 MB     
Downloading: 3.6 MB     
Downloading: 3.6 MB     
Downloading: 3.6 MB     
Downloading: 3.6 MB     
Downloading: 3.6 MB     
Downloading: 3.6 MB     
Downloading: 3.6 MB     
Downloading: 3.6 MB     
Downloading: 3.7 MB     
Downloading: 3.7 MB     
Downloading: 3.7 MB     
Downloading: 3.7 MB     
Downloading: 3.7 MB     
Downloading: 3.7 MB     
Downloading: 3.7 MB     
Downloading: 3.7 MB     
Downloading: 3.7 MB     
Downloading: 3.7 MB     
Downloading: 3.7 MB     
Downloading: 3.7 MB     
Downloading: 3.7 MB     
Downloading: 3.7 MB     
Downloading: 3.8 MB     
Downloading: 3.8 MB     
Downloading: 3.8 MB     
Downloading: 3.8 MB     
Downloading: 3.8 MB     
Downloading: 3.8 MB     
Downloading: 3.8 MB     
Downloading: 3.8 MB     
Downloading: 3.8 MB     
Downloading: 3.8 MB     
Downloading: 3.8 MB     
Downloading: 3.8 MB     
Downloading: 3.8 MB     
Downloading: 3.8 MB     
Downloading: 3.8 MB     
Downloading: 3.8 MB     
Downloading: 3.8 MB     
Downloading: 3.8 MB     
Downloading: 3.9 MB     
Downloading: 3.9 MB     
Downloading: 3.9 MB     
Downloading: 3.9 MB     
Downloading: 3.9 MB     
Downloading: 3.9 MB     
Downloading: 3.9 MB     
Downloading: 3.9 MB     
Downloading: 3.9 MB     
Downloading: 3.9 MB     
Downloading: 3.9 MB     
Downloading: 3.9 MB     
Downloading: 3.9 MB     
Downloading: 3.9 MB     
Downloading: 3.9 MB     
Downloading: 3.9 MB     
Downloading: 3.9 MB     
Downloading: 3.9 MB     
Downloading: 4 MB     
Downloading: 4 MB     
Downloading: 4 MB     
Downloading: 4 MB     
Downloading: 4 MB     
Downloading: 4 MB     
Downloading: 4 MB     
Downloading: 4 MB     
Downloading: 4 MB     
Downloading: 4 MB     
Downloading: 4 MB     
Downloading: 4 MB     
Downloading: 4.1 MB     
Downloading: 4.1 MB     
Downloading: 4.1 MB     
Downloading: 4.1 MB     
Downloading: 4.1 MB     
Downloading: 4.1 MB     
Downloading: 4.1 MB     
Downloading: 4.1 MB     
Downloading: 4.1 MB     
Downloading: 4.1 MB     
Downloading: 4.1 MB     
Downloading: 4.1 MB     
Downloading: 4.1 MB     
Downloading: 4.1 MB     
Downloading: 4.1 MB     
Downloading: 4.1 MB     
Downloading: 4.2 MB     
Downloading: 4.2 MB     
Downloading: 4.2 MB     
Downloading: 4.2 MB     
Downloading: 4.2 MB     
Downloading: 4.2 MB     
Downloading: 4.2 MB     
Downloading: 4.2 MB     
Downloading: 4.2 MB     
Downloading: 4.2 MB     
Downloading: 4.2 MB     
Downloading: 4.2 MB     
Downloading: 4.3 MB     
Downloading: 4.3 MB     
Downloading: 4.3 MB     
Downloading: 4.3 MB     
Downloading: 4.3 MB     
Downloading: 4.3 MB     
Downloading: 4.3 MB     
Downloading: 4.3 MB     
Downloading: 4.3 MB     
Downloading: 4.3 MB     
Downloading: 4.3 MB     
Downloading: 4.3 MB     
Downloading: 4.3 MB     
Downloading: 4.3 MB     
Downloading: 4.3 MB     
Downloading: 4.3 MB     
Downloading: 4.3 MB     
Downloading: 4.3 MB     
Downloading: 4.4 MB     
Downloading: 4.4 MB     
Downloading: 4.4 MB     
Downloading: 4.4 MB     
Downloading: 4.4 MB     
Downloading: 4.4 MB     
Downloading: 4.4 MB     
Downloading: 4.4 MB     
Downloading: 4.4 MB     
Downloading: 4.4 MB     
Downloading: 4.4 MB     
Downloading: 4.4 MB     
Downloading: 4.4 MB     
Downloading: 4.4 MB     
Downloading: 4.5 MB     
Downloading: 4.5 MB     
Downloading: 4.5 MB     
Downloading: 4.5 MB     
Downloading: 4.5 MB     
Downloading: 4.5 MB     
Downloading: 4.5 MB     
Downloading: 4.5 MB     
Downloading: 4.5 MB     
Downloading: 4.5 MB     
Downloading: 4.5 MB     
Downloading: 4.5 MB     
Downloading: 4.5 MB     
Downloading: 4.5 MB     
Downloading: 4.5 MB     
Downloading: 4.5 MB     
Downloading: 4.5 MB     
Downloading: 4.5 MB     
Downloading: 4.5 MB     
Downloading: 4.5 MB     
Downloading: 4.5 MB     
Downloading: 4.5 MB     
Downloading: 4.6 MB     
Downloading: 4.6 MB     
Downloading: 4.6 MB     
Downloading: 4.6 MB     
Downloading: 4.6 MB     
Downloading: 4.6 MB
mets<-mets[grep(mets$NAME,pattern =  "TX"),]
plot(mets["NAME"])

sts<-states(cb=T, year=2018)
## 
  |                                                                            
  |                                                                      |   0%
  |                                                                            
  |=                                                                     |   1%
  |                                                                            
  |=                                                                     |   2%
  |                                                                            
  |==                                                                    |   2%
  |                                                                            
  |==                                                                    |   3%
  |                                                                            
  |===                                                                   |   4%
  |                                                                            
  |===                                                                   |   5%
  |                                                                            
  |====                                                                  |   5%
  |                                                                            
  |====                                                                  |   6%
  |                                                                            
  |=====                                                                 |   7%
  |                                                                            
  |======                                                                |   8%
  |                                                                            
  |======                                                                |   9%
  |                                                                            
  |=======                                                               |  10%
  |                                                                            
  |========                                                              |  11%
  |                                                                            
  |========                                                              |  12%
  |                                                                            
  |=========                                                             |  12%
  |                                                                            
  |==========                                                            |  14%
  |                                                                            
  |==========                                                            |  15%
  |                                                                            
  |===========                                                           |  16%
  |                                                                            
  |============                                                          |  17%
  |                                                                            
  |============                                                          |  18%
  |                                                                            
  |=============                                                         |  19%
  |                                                                            
  |==============                                                        |  20%
  |                                                                            
  |===============                                                       |  21%
  |                                                                            
  |===============                                                       |  22%
  |                                                                            
  |================                                                      |  23%
  |                                                                            
  |=================                                                     |  24%
  |                                                                            
  |=================                                                     |  25%
  |                                                                            
  |==================                                                    |  25%
  |                                                                            
  |==================                                                    |  26%
  |                                                                            
  |===================                                                   |  27%
  |                                                                            
  |===================                                                   |  28%
  |                                                                            
  |====================                                                  |  28%
  |                                                                            
  |====================                                                  |  29%
  |                                                                            
  |=====================                                                 |  30%
  |                                                                            
  |=====================                                                 |  31%
  |                                                                            
  |======================                                                |  31%
  |                                                                            
  |======================                                                |  32%
  |                                                                            
  |=======================                                               |  33%
  |                                                                            
  |=======================                                               |  34%
  |                                                                            
  |========================                                              |  34%
  |                                                                            
  |========================                                              |  35%
  |                                                                            
  |=========================                                             |  36%
  |                                                                            
  |==========================                                            |  37%
  |                                                                            
  |===========================                                           |  39%
  |                                                                            
  |============================                                          |  39%
  |                                                                            
  |============================                                          |  41%
  |                                                                            
  |=============================                                         |  41%
  |                                                                            
  |==============================                                        |  43%
  |                                                                            
  |===============================                                       |  45%
  |                                                                            
  |================================                                      |  45%
  |                                                                            
  |=================================                                     |  47%
  |                                                                            
  |==================================                                    |  49%
  |                                                                            
  |===================================                                   |  49%
  |                                                                            
  |===================================                                   |  51%
  |                                                                            
  |====================================                                  |  51%
  |                                                                            
  |=====================================                                 |  53%
  |                                                                            
  |======================================                                |  55%
  |                                                                            
  |=======================================                               |  55%
  |                                                                            
  |=======================================                               |  56%
  |                                                                            
  |========================================                              |  57%
  |                                                                            
  |=========================================                             |  58%
  |                                                                            
  |=========================================                             |  59%
  |                                                                            
  |==========================================                            |  60%
  |                                                                            
  |===========================================                           |  61%
  |                                                                            
  |============================================                          |  62%
  |                                                                            
  |============================================                          |  63%
  |                                                                            
  |=============================================                         |  64%
  |                                                                            
  |==============================================                        |  65%
  |                                                                            
  |==============================================                        |  66%
  |                                                                            
  |===============================================                       |  67%
  |                                                                            
  |================================================                      |  68%
  |                                                                            
  |================================================                      |  69%
  |                                                                            
  |=================================================                     |  70%
  |                                                                            
  |==================================================                    |  71%
  |                                                                            
  |===================================================                   |  72%
  |                                                                            
  |===================================================                   |  73%
  |                                                                            
  |====================================================                  |  74%
  |                                                                            
  |=====================================================                 |  75%
  |                                                                            
  |=====================================================                 |  76%
  |                                                                            
  |======================================================                |  77%
  |                                                                            
  |======================================================                |  78%
  |                                                                            
  |=======================================================               |  78%
  |                                                                            
  |=======================================================               |  79%
  |                                                                            
  |========================================================              |  80%
  |                                                                            
  |=========================================================             |  81%
  |                                                                            
  |==========================================================            |  82%
  |                                                                            
  |==========================================================            |  83%
  |                                                                            
  |===========================================================           |  84%
  |                                                                            
  |===========================================================           |  85%
  |                                                                            
  |============================================================          |  86%
  |                                                                            
  |=============================================================         |  87%
  |                                                                            
  |==============================================================        |  88%
  |                                                                            
  |==============================================================        |  89%
  |                                                                            
  |===============================================================       |  90%
  |                                                                            
  |================================================================      |  91%
  |                                                                            
  |================================================================      |  92%
  |                                                                            
  |=================================================================     |  93%
  |                                                                            
  |==================================================================    |  94%
  |                                                                            
  |==================================================================    |  95%
  |                                                                            
  |===================================================================   |  96%
  |                                                                            
  |====================================================================  |  97%
  |                                                                            
  |====================================================================  |  98%
  |                                                                            
  |===================================================================== |  98%
  |                                                                            
  |===================================================================== |  99%
  |                                                                            
  |======================================================================| 100%
sts<-sts%>%
  filter(GEOID==48)

Estimates by Metro Areas

Redo the survey estimation calculations, but this time use a different grouping variable met2013.

met_est_edu<-svyby(formula = ~educ_level,
                   by = ~met2013, #See, not PUMAs; Metro Areas to correspond to the Metro Areas geometries we just downloaded; rest of code is the same
                   design=subset(des,age>25),
                   FUN=svymean,
                   na.rm=T )
met_est_employ<-svyby(formula = ~employed,
                      by = ~met2013,
                      design=subset(des, age%in%18:65),
                      FUN=svymean,
                      na.rm=T )
met_est_industry<-svyby(formula = ~proftech,
                        by = ~met2013,
                        design=subset(des, employed==1),
                        FUN=svymean,
                        na.rm=T )
head(met_est_edu)
head(met_est_employ)
head(met_est_industry)
mets$met2013<-as.numeric(mets$GEOID)
geo3<-left_join(mets, met_est_employ,by=c("met2013"= "met2013"))

Note, grey Metros are ones that are not identified in the ACS because of the population limit (but they are in the spatial data).

tmap_mode("plot") #"view" isn't working for some reason
## tmap mode set to plotting
geo3%>%
  tm_shape()+
  tm_polygons("employed",
              style="kmeans",
              n=8,
              legend.hist = TRUE) +
 tm_layout(legend.outside = TRUE,
            title = "Employment rate in Texas Metro Areas \n 2014-2018")  

Estimation for Counties

cos<-counties(cb= T,state = "TX", year = 2018)
plot(cos["NAME"])

sts<-states(cb=T, year=2018)
sts<-sts%>%
  filter(GEOID==48)

Estimates by County Area

cos_est_edu<-svyby(formula = ~educ_level,
                   by = ~countyfip,
                   design=subset(des,age>25),
                   FUN=svymean, na.rm=T )
cos_est_employ<-svyby(formula = ~employed,
                      by = ~countyfip,
                      design=subset(des, age%in%18:65),
                      FUN=svymean, na.rm=T )
cos_est_industry<-svyby(formula = ~proftech,
                        by = ~countyfip,
                        design=subset(des, employed==1),
                        FUN=svymean, na.rm=T )
head(cos_est_edu)
head(cos_est_employ)
head(cos_est_industry)

Again, the ACS doesn’t identify counties in the microdata except for certain ones that fit this criteria mentioned in this link: here.

cos$cofip<-as.numeric(cos$COUNTYFP)
geo4<-left_join(cos, cos_est_employ,by=c("cofip"= "countyfip"))
tmap_mode("plot") #"view" isn't working for some reason
## tmap mode set to plotting
geo4%>%
  tm_shape()+
  tm_polygons("employed",
              style="kmeans",
              n=8,
              legend.hist = TRUE) +
 tm_layout(legend.outside = TRUE,
            title = "Employment rate in Texas Counties \n 2014-2018")  

LS0tDQp0aXRsZTogIlVzaW5nIElQVU1TIFVTQSBmb3IgRXN0aW1hdGlvbiBvZiBQb3B1bGF0aW9uIENoYXJhY3RlcmlzdGljcyBpbiBWYXJpb3VzIEdlb2dyYXBoaWMgQXJlYXMiDQphdXRob3I6ICJKdWxpYSBLYXkgV29sZiwgUGguRC4qIg0KZGF0ZTogImByIGZvcm1hdChTeXMudGltZSgpLCAnJWQgJUIsICVZJylgIg0Kb3V0cHV0Og0KICAgaHRtbF9kb2N1bWVudDoNCiAgICBkZl9wcmludDogcGFnZWQNCiAgICBmaWdfaGVpZ2h0OiA3DQogICAgZmlnX3dpZHRoOiA3DQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZmxvYXQ6IHllcw0KICAgIGNvZGVfZG93bmxvYWQ6IHRydWUNCi0tLQ0KKlRoZXNlIGFyZSB1cGRhdGVzLiBUaGUgMjAyMiB2ZXJzaW9uIGZyb20gQ29yZXkgU3BhcmtzLCBQaC5ELiBjYW4gYmUgZm91bmQgW2hlcmVdKGh0dHBzOi8vZ2l0aHViLmNvbS9jb3JleXNwYXJrcy9ERU03MDkzL3RyZWUvbWFpbi9jb2RlKS4gDQoNCioqKioqDQoNCkluIHRoaXMgZXhhbXBsZSB3ZSB3aWxsIHVzZSB0aGUgW0lQVU1TIFVTQV0oaHR0cHM6Ly91c2EuaXB1bXMub3JnL3VzYS8pIGRhdGEgdG8gcHJvZHVjZSBzdXJ2ZXktYmFzZWQgZXN0aW1hdGVzIGZvciB2YXJpb3VzIGdlb2dyYXBoaWMgbGV2ZWxzIHByZXNlbnQgaW4gdGhlIElQVU1TLiBUaGlzIGV4YW1wbGUgdXNlcyB0aGUgMjAxNC0yMDE4IEFDUyA1LXllYXIgbWljcm9kYXRhLiANCg0KQ2xpY2sgW2hlcmVdKGh0dHBzOi8veWlodWkub3JnL2tuaXRyL29wdGlvbnMvI2NodW5rLW9wdGlvbnMpIGZvciBtb3JlIGluZm8gb24gc2V0dGluZyBjaHVuayBvcHRpb25zLg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpICN0aGlzIGlzIHVzZWQgdG8gc2V0IHRoZSBkZWZhdWx0IHZhbHVlcyBvZiBjaHVuayBvcHRpb25zIGZvciB0aGlzIGRvY3VtZW50IA0KYGBgDQoNClRoZSBnb29kIGZvbGtzIGF0IElQVU1TIGhhdmUgY3JlYXRlZCBhIGxpYnJhcnkgdG8gcmVhZCBpbiB0aGVpciBkYXRhIGZyb20gdGhlIC5neiBmaWxlIHRoYXQgeW91IGRvd25sb2FkLiBCZSBzdXJlIHlvdSByaWdodCBjbGljayBhbmQgc2F2ZSB0aGUgRERJIGNvZGVib29rIHdoZW4geW91IGNyZWF0ZSB5b3VyIGV4dHJhY3QNCg0KIVtdKERESWltYWdlLnBuZykNCg0KVGhpcyB3aWxsIHNhdmUgdGhlIC5YTUwgZmlsZSB0aGF0IGNvbnRhaW5zIGFsbCB0aGUgaW5mb3JtYXRpb24gb24gdGhlIGRhdGEgKHdoYXQgaXMgY29udGFpbmVkIGluIHRoZSBkYXRhIGZpbGUpIHRvIHlvdXIgY29tcHV0ZXIuIFdoZW4gdXNpbmcgSVBVTVMsIGl0IHdpbGwgaGF2ZSBhIG5hbWUgbGlrZSBgdXNhX3h4eHh4LnhtbGAgd2hlcmUgdGhlIHgncyByZXByZXNlbnQgdGhlIGV4dHJhY3QgbnVtYmVyIChJJ20gb24gMiBhcyBvZiB0b2RheSkuIA0KDQpZb3Ugd2lsbCBhbHNvIG5lZWQgdG8gZG93bmxvYWQgdGhlIGRhdGEgZmlsZSwgYnkgcmlnaHQgY2xpY2tpbmcgdGhlICoqRG93bmxvYWQgLkRBVCoqIGxpbmsgaW4gdGhlIGFib3ZlIGltYWdlLiBUaGlzIHdpbGwgc2F2ZSBhIC5HWiBmaWxlIHRvIHlvdXIgY29tcHV0ZXIsIGFnYWluIHdpdGggYSBuYW1lIGxpa2U6IGB1c2FfeHh4eHguZGF0Lmd6YC4gTWFrZSBzdXJlIHRoaXMgZmlsZSBhbmQgdGhlIFhNTCBmaWxlIGZyb20gYWJvdmUgYXJlIGluIHRoZSBzYW1lIGZvbGRlciwgcHJlZmVyYWJseSB5b3VyIGNsYXNzIGZvbGRlci4gDQoNCkJlIHN1cmUgdGhlIGBpcHVtc3JgIHBhY2thZ2UgaXMgaW5zdGFsbGVkLiBDbGljayBbaGVyZV0oaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvd2ViL3BhY2thZ2VzL2lwdW1zci9pcHVtc3IucGRmKSBmb3IgYSBQREYgb2YgYGlwdW1zcmAgcGFja2FnZSBkb2N1bWVudGF0aW9uLg0KDQpgYGB7cn0NCmxpYnJhcnkoaXB1bXNyKSAjbmV3IGxpYnJhcnkgZm9yIEdJUyBjbGFzcw0KZGRpIDwtIHJlYWRfaXB1bXNfZGRpKCJ1c2FfMDAwMDQueG1sIikgI1IgTWFya2Rvd24gdXNlcyB0aGUgc2FtZSBkaXJlY3Rvcnkgd2hlcmUgeW91IHNhdmUgdGhpcyBmaWxlLCBzbyBubyBuZWVkIHRvIHJlcGVhdCB1bmxlc3MgeW91ciAueG1sIGlzIGxvY2F0ZWQgZWxzZXdoZXJlDQpkYXRhIDwtIHJlYWRfaXB1bXNfbWljcm8oZGRpKQ0KZGF0YTwtaGF2ZW46OnphcF9sYWJlbHMoZGF0YSkgI25lY2Vzc2FyeSB0byBhdm9pZCBwcm9ibGVtcyB3aXRoICJsYWJlbGxlZCIgZGF0YSBjbGFzcyAocmVtb3ZlcyB2YXJpYWJsZSBsYWJlbHMpOyAnaXB1bXNyJyBpbXBvcnRzIHBhY2thZ2UgJ2hhdmVuJyB0byB1c2UgemFwX2xhYmVscw0KbmFtZXMoZGF0YSk8LXRvbG93ZXIobmFtZXMoZGF0YSkpICN0b2xvd2VyIGNoYW5nZXMgYW55IHVwcGVyY2FzZSBsZXR0ZXJzIGluIHZhcmlhYmxlIG5hbWVzIHRvIGxvd2VyY2FzZQ0KYGBgDQoNCiMgTG9hZCBTb21lIE90aGVyIFBhY2thZ2VzDQpgYGB7ciwgbWVzc2FnZT1GQUxTRX0NCmxpYnJhcnkoc3VydmV5LCBxdWlldGx5ID0gVCkNCmxpYnJhcnkodGlkeXZlcnNlLCBxdWlldGx5ID0gVCkNCmxpYnJhcnkoY2FyLCBxdWlldGx5ID0gVCkNCmxpYnJhcnkoZ2dwbG90MiwgcXVpZXRseSA9IFQpDQpsaWJyYXJ5KHRpZ3JpcywgcXVpZXRseSA9IFQpDQpsaWJyYXJ5KGNsYXNzSW50LCBxdWlldGx5ID0gVCkNCmxpYnJhcnkodG1hcCwgcXVpZXRseSA9IFQpDQpgYGANCg0KDQojIERvd25sb2FkIEdlb2dyYXBoaWMgRGF0YSBmb3IgUHVibGljIFVzZSBNaWNyb2RhdGEgQXJlYXMgKFBVTUFzKQ0KVGhlIElQVU1TIGRhdGEgd2UganVzdCBkb3dubG9hZGVkIGRvZXNuJ3QgY29tZSB3aXRoIGFueSBnZW9ncmFwaGljIGRhdGEgKGkuZS4sIGl0IGhhcyBGSVBTIGNvZGVzLCBidXQgbm90IHRoZSBnZW9ncmFwaGljIGRhdGEgY29tcG9uZW50KS4NCg0KVGhlIFB1YmxpYyBVc2UgTWljcm9kYXRhIEFyZWEgaXMgdGhlIGxvd2VzdCBsZXZlbCBvZiBnZW9ncmFwaHkgaW4gdGhlIFBVTVMgZGF0YS4gVGhleSBjb3JyZXNwb25kIHRvIGdlb2dyYXBoaWMgYXJlcyBvZiB+IDEwMCwwMDAgcGVvcGxlLiANCkhlcmUgYXJlIHNvbWUgaGVscGZ1bCBzaXRlcyBhYm91dCBQVU1BczoNCg0KMS4gW01pc3NvdXJpIENlbnN1cyBEYXRhIENlbnRlciAtIEFsbCBBYm91dCBQdWJsaWMtVXNlIE1pY3JvZGF0YSBBcmVhcyAoUFVNQXMpXShodHRwczovL21jZGMubWlzc291cmkuZWR1L2dlb2dyYXBoeS9QVU1Bcy5odG1sKSAgDQoNCjIuIFtVUyBDZW5zdXMgLSBQdWJsaWMgVXNlIE1pY3JvZGF0YSBBcmVhcyAoUFVNQXMpXShodHRwczovL3d3dy5jZW5zdXMuZ292L3Byb2dyYW1zLXN1cnZleXMvZ2VvZ3JhcGh5L2d1aWRhbmNlL2dlby1hcmVhcy9wdW1hcy5odG1sKSAgDQoNCjMuIFtVUyBDZW5zdXMgLSAyMDIwIFB1YmxpYyBVc2UgTWljcm9kYXRhIEFyZWFzIFByb2dyYW0gRnJlcXVlbnRseSBBc2tlZCBRdWVzdGlvbnMgKEZBUXMpXShodHRwczovL3d3dzIuY2Vuc3VzLmdvdi9nZW8vcGRmcy9yZWZlcmVuY2UvcHVtYTIwMjAvMjAyMFBVTUFfRkFRcy5wZGYpDQoNCkZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IGB0aWdyaXNgIHBhY2thZ2UgY2xpY2sgW2hlcmVdKGh0dHBzOi8vcmRyci5pby9jcmFuL3RpZ3Jpcy9tYW4vdGlncmlzLmh0bWwpIGFuZCBbaGVyZV0oaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvd2ViL3BhY2thZ2VzL3RpZ3Jpcy90aWdyaXMucGRmKS4NCg0KYGBge3J9DQpvcHRpb25zKHRpZ3Jpc19jbGFzcyA9ICJzZiIpDQpwdW1hczwtcHVtYXMoc3RhdGUgPSAiVFgiLCAjbWF0Y2ggdGhlc2UgdG8gdGhlIGRhdGEgeW91IGRvd25sb2FkZWQgZnJvbSBJUFVNUw0KICAgICAgICAgICAgIHllYXIgPSAyMDE4LCAjbWF0Y2ggdGhlc2UgdG8gdGhlIGRhdGEgeW91IGRvd25sb2FkZWQgZnJvbSBJUFVNUw0KICAgICAgICAgICAgIGNiID0gVCkNCnBsb3QocHVtYXNbIkdFT0lEMTAiXSwNCiAgICAgbWFpbiA9ICJQdWJsaWMgVXNlIE1pY3JvZGF0YSBBcmVhcyBpbiBUZXhhcyIpDQptYXB2aWV3OjptYXB2aWV3KHB1bWFzLCB6Y29sPSAiR0VPSUQxMCIpDQpgYGANCg0KDQojIFByZXBhcmUgVmFyaWFibGVzDQpIZXJlIERyLiBTcGFya3MgcmVjb2RlZCBzZXZlcmFsIGRlbW9ncmFwaGljIHZhcmlhYmxlcy4NCg0KKlJFQUQgWU9VUiBDT0RFQk9PSyAoRERJKS4qDQoNCkNsaWNrIFtoZXJlXShodHRwczovL3d3dy5yZG9jdW1lbnRhdGlvbi5vcmcvcGFja2FnZXMvZHBseXIvdmVyc2lvbnMvMS4wLjEwL3RvcGljcy9yZWNvZGUpIGZvciBSIGRvY3VtZW50YXRpb24gb24gdGhlIGZ1bmN0aW9uIGBSZWNvZGVgLiAgDQoNCkNsaWNrIFtoZXJlXShodHRwczovL3d3dy5yZG9jdW1lbnRhdGlvbi5vcmcvcGFja2FnZXMvYmFzZS92ZXJzaW9ucy8zLjYuMi90b3BpY3MvaW50ZXJhY3Rpb24pIGZvciBSIGRvY3VtZW50YXRpb24gb24gdGhlIGZ1bmN0aW9uIGBpbnRlcmFjdGlvbmAuICANCg0KQ2xpY2sgW2hlcmVdKGh0dHBzOi8vd3d3LnJkb2N1bWVudGF0aW9uLm9yZy9wYWNrYWdlcy9zdGF0cy92ZXJzaW9ucy8zLjYuMi90b3BpY3MvcmVsZXZlbCkgZm9yIFIgZG9jdW1lbnRhdGlvbiBvbiB0aGUgZnVuY3Rpb24gYHJlbGV2ZWxgLiAgDQoNCkNsaWNrIFtoZXJlXShodHRwczovL3d3dy5yZG9jdW1lbnRhdGlvbi5vcmcvcGFja2FnZXMvYmFzZS92ZXJzaW9ucy8zLjYuMi90b3BpY3MvZmFjdG9yKSBmb3IgUiBkb2N1bWVudGF0aW9uIG9uIHRoZSBmdW5jdGlvbiBgYXMuZmFjdG9yYC4gIA0KDQpDbGljayBbaGVyZV0oaHR0cHM6Ly93d3cucmRvY3VtZW50YXRpb24ub3JnL3BhY2thZ2VzL2Jhc2UvdmVyc2lvbnMvMy42LjIvdG9waWNzL2lmZWxzZSkgZm9yIFIgZG9jdW1lbnRhdGlvbiBvbiB0aGUgZnVuY3Rpb24gYGlmZWxlc2VgLg0KDQoqUkVBRCBZT1VSIENPREVCT09LIChEREkpLioNCg0KKiBTZWUgaG93IHlvdXIgdmFyaWFibGVzIGFyZSBjb2RlZC4NCg0KKiBTZWUgaG93IG1pc3NpbmcgdmFsdWVzIGFyZSBjb2RlZC4NCmBgYHtyfQ0KZGF0YSRwd3QgPC0gZGF0YSRwZXJ3dA0KZGF0YSRod3QgPC0gZGF0YSRoaHd0DQojcmFjZS9ldGhuaWNpdHkNCmRhdGEkaGlzcCA8LSBSZWNvZGUoZGF0YSRoaXNwYW4sIHJlY29kZXMgPSAiOT1OQTsgMTo0PSdIaXNwYW5pYyc7IDA9J05vbkhpc3BhbmljJyIpDQpkYXRhJHJhY2VfcmVjIDwtIFJlY29kZShkYXRhJHJhY2UsIHJlY29kZXMgPSAiMT0nV2hpdGUnOyAyPSdCbGFjayc7IDM9J090aGVyJzsgNDo2PSdBc2lhbic7IDc6OT0nT3RoZXInIikNCmRhdGEkcmFjZV9ldGggPC0gaW50ZXJhY3Rpb24oZGF0YSRoaXNwLCBkYXRhJHJhY2VfcmVjLCBzZXAgPSAiXyIpDQpkYXRhJHJhY2VfZXRoICA8LSBhcy5mYWN0b3IoaWZlbHNlKHN1YnN0cihhcy5jaGFyYWN0ZXIoZGF0YSRyYWNlX2V0aCksMSw4KSA9PSAiSGlzcGFuaWMiLCAiSGlzcGFuaWMiLCBhcy5jaGFyYWN0ZXIoZGF0YSRyYWNlX2V0aCkpKQ0KZGF0YSRyYWNlX2V0aCA8LSByZWxldmVsKGRhdGEkcmFjZV9ldGgsIHJlZiA9ICJOb25IaXNwYW5pY19XaGl0ZSIpDQojc2V4DQpkYXRhJG1hbGUgPC0gaWZlbHNlKGRhdGEkc2V4ID09IDEsMSwwKQ0KI2VkdWNhdGlvbg0KZGF0YSRlZHVjX2xldmVsPC0gUmVjb2RlKGRhdGEkZWR1Y2QsIHJlY29kZXMgPSAiMjo2MT0nMExUX0hTJzs2Mjo2ND0nMV9IU0QvR0VEJzs2NTo4MD0nMl9zb21lY29sbCc7OTA6MTAwPScyX3NvbWVjb2xsJzsgODE6ODM9JzNfQXNzb2NEZWdyZWUnOzEwMT0nNF9iYWNoZWxvcmRlZ3JlZSc7IDExMDoxMTY9JzRfQkFwbHVzX0dyYWREZWdyZWUnOyBlbHNlPU5BIikNCiNlbXBsb3ltZW50DQpkYXRhJGVtcGxveWVkIDwtIFJlY29kZShkYXRhJHdya2xzdHdrLCByZWNvZGVzID0gIjE9MDsyPTE7IGVsc2U9TkEiKQ0KI2NpdGl6ZW5zaGlwDQpkYXRhJGNpdDwtUmVjb2RlKGRhdGEkY2l0aXplbiwgcmVjb2RlcyA9ICIxPSdVUyBib3JuJzsgMj0nbmF0dXJhbGl6ZWQnOyAzOjQ9J25vdGNpdGl6ZW4nO2Vsc2U9TkEgIikNCiNpbmR1c3RyeQ0KZGF0YSRpbmRfZ3JvdXA8LVJlY29kZShkYXRhJGluZCwgcmVjb2RlcyA9ICIxNzA6NDkwPSdhZ19leHRyYWN0JzsgNzcwPSdjb25zdHJ1Y3Rpb24nOyAxMDcwOjM5OTA9J21hbnVmYWMnOyA0MDcwOjU3OTA9J3dob2xlX3JldGFpbCc7IDYwNzA6NjM5MD0ndHJhbnMnOyA2NDcwOjY3ODA9J2luZm9ybWF0aW9uJzsgNjg3MDo3MTkwPSAnZmlyZSc7IDcyNzA9Nzc5MD0ncHJvZi9zY2kvbWFuYWdlJzsgNzg2MDo4NDcwPSdlZHUvc29jaWFsJzsgODU2MDo4NjkwPSdhcnRzJzsgODc3MDo5MjkwPSdvdGhlcic7IDkzNzA6OTU5MD0ncHVibGljX2FkbSc7IDk2NzA6OTg3MD0nbWlsaXRhcnknOyBlbHNlPU5BICIpDQpkYXRhJHByb2Z0ZWNoIDwtIFJlY29kZShkYXRhJGluZCwgcmVjb2RlcyA9ICI3MjcwOjc0OTA9MTsgMD1OQTsgZWxzZT0wIikNCiNhZ2UgaW4gMTAgeWVhciBpbnRlcnZhbHMNCmRhdGEkYWdlY2F0PC1jdXQoZGF0YSRhZ2UsIGJyZWFrcyA9IGMoMCwgMTgsIDIwLCAzMCwgNDAsIDUwLCA2NSwgMTIwKSwgaW5jbHVkZS5sb3dlc3QgPSBUKQ0KZGF0YSRpbmNvbWUgPC0gaWZlbHNlKGRhdGEkaW5jd2FnZT49OTk5OTk4LCBOQSwgZGF0YSRpbmN3YWdlKSAjaWYgaW5jb21lIGlzIGdyZWF0ZXIgdGhhbiA5OTk5OTggdGhlbiByZWNvZGUgaXQgYXMgTkEsIG90aGVyd2lzZSBrZWVwIGFzIGlzDQpgYGANCg0KDQoNCiMgR2VuZXJhdGUgU3VydmV5IERlc2lnbiBPYmplY3QNCkhlcmUgd2UgaWRlbnRpZnkgdGhlIHBlcnNvbiB3ZWlnaHRzIGFuZCB0aGUgc3VydmV5IGRlc2lnbiB2YXJpYWJsZXMuIFRoaXMgaXMgYSBzdHJhdGlmaWVkIGNsdXN0ZXJlZCBzYW1wbGUuIEhlcmUsIGZvciB0aGUgQUNTIHRoZSBzdHJhdGEgYXJlIGdlb2dyYXBoaWMgY2h1bmtzIGFuZCB0aGUgY2x1c3RlcnMgYXJlIGhvdXNlaG9sZHMuIEl0J3Mgbm90IGEgcmFuZG9tIHNhbXBsZSBzbyBuZWVkIHBlcnNvbiB3ZWlnaHRzLg0KDQpgYGB7cn0NCmhlYWQoZGF0YSRwZXJ3dCkgI3Nob3dzIGhvdyBtYW55IHBlb3BsZSBlYWNoIHBlcnNvbiBpbiB0aGUgc2FtcGxlIHJlcHJlc2VudHMgKHNob3dzIGZvciB0aGUgZmlyc3QgNiBwZW9wbGUpDQpzdW0oZGF0YSRwZXJ3dCkgI2dpdmVzIHlvdSB0aGUgcG9wdWxhdGlvbiBvZiB0aGUgcGxhY2UgKGluIHRoaXMgY2FzZSwgVGV4YXMpDQpgYGANCg0KDQpgYGB7cn0NCmRlczwtc3Z5ZGVzaWduKGlkcyA9IH5jbHVzdGVyLCAjdGhlc2UgdmFyaWFibGVzIChjbHVzdGVyLCBzdHJhdGEsIGFuZCBwd3QpIGFyZSBhdXRvbWF0aWNhbGx5IGRvd25sb2FkZWQgZnJvbSBJUFVNUw0KICAgICAgICAgICAgICAgc3RyYXRhID0gfiBzdHJhdGEsDQogICAgICAgICAgICAgICB3ZWlnaHRzID0gfnB3dCwNCiAgICAgICAgICAgICAgIGRhdGEgPSBkYXRhKQ0KYGBgDQoNCiMgUGVyZm9ybSBTdXJ2ZXkgRXN0aW1hdGlvbiBmb3IgUFVNQXMNClRoZSBgc3Z5YnkoKWAgZnVuY3Rpb24gYWxsb3dzIHVzIGNhbGN1bGF0ZSBlc3RpbWF0ZXMgZm9yIGRpZmZlcmVudCAqKnN1Yi1kb21haW5zKiogd2l0aGluIHRoZSBkYXRhLCB0aGlzIGNvdWxkIGJlIGEgZGVtb2dyYXBoaWMgY2hhcmFjdGVyaXN0aWMsIGJ1dCB3ZSdsbCB1c2Ugb3VyIGdlb2dyYXBoaWMgbGV2ZWwuIE9mIGNvdXJzZSB5b3UgY291bGQgZG8gYm90aC4uLi4gDQoNCkNsaWNrIFtoZXJlXShodHRwczovL3JkcnIuaW8vY3Jhbi9zdXJ2ZXkvbWFuL3N2eWJ5Lmh0bWwpIG9yIFtoZXJlXShodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvc3VydmV5L3N1cnZleS5wZGYpIGZvciBSIGRvY3VtZW50YXRpb24gb24gYHN2eWJ5YC4gIA0KDQpDbGljayBbaGVyZV0oaHR0cHM6Ly93d3cucmRvY3VtZW50YXRpb24ub3JnL3BhY2thZ2VzL3N1cnZleS92ZXJzaW9ucy80LjEtMS90b3BpY3Mvc3Z5dGFibGUpIGZvciBSIGRvY3VtZW50YXRpb24gb24gdGhlIGZ1bmN0aW9uIGBzdnl0YWJsZWAuICANCg0KQ2xpY2sgW2hlcmVdKGh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL3dlYi9wYWNrYWdlcy9sYXp5ZXZhbC92aWduZXR0ZXMvbGF6eWV2YWwuaHRtbCkgZm9yIFIgZG9jdW1lbnRhdGlvbiBvbiBmb3JtdWxhcyBhbmQgYH5gLiAgDQoNCkNsaWNrIFtoZXJlXShodHRwczovL3d3dy5yZG9jdW1lbnRhdGlvbi5vcmcvcGFja2FnZXMvYmFzZS92ZXJzaW9ucy8zLjYuMi90b3BpY3MvQXNJcykgZm9yIFIgZG9jdW1lbnRhdGlvbiBvbiBgSWAuDQoNCmBgYHtyfQ0KdGVzdDwtc3Z5dGFibGUofkkoY2l0PT0iVVMgYm9ybiIpK3B1bWErc2V4LCBkZXNpZ249ZGVzICkNCnB1bWFfZXN0X2VkdTwtc3Z5YnkoZm9ybXVsYSA9IH5lZHVjX2xldmVsLCAjd2hhdCBJIHdhbnQgdG8gdGFrZSB0aGUgJSBvZiwgSSB3YW50IHRoZSAlIGluIGVhY2ggZWR1Y2F0aW9uIGxldmVsDQogICAgICAgICAgICAgICAgICAgIGJ5ID0gfnB1bWEsICMuLi5zbyB0YWtpbmcgdGhlICUgb2YgZWFjaCBlZHVjYXRpb25hbCBsZXZlbCBpbiBlYWNoIFBVTUENCiAgICAgICAgICAgICAgICAgICAgZGVzaWduID0gc3Vic2V0KGRlcywgYWdlPjI1KSwgI0NlbnN1cyBkb2Vzbid0IGdldCBlZHVjYXRpb24gbGV2ZWwgZm9yIHRob3NlIGFnZSAyNSBhbmQgdW5kZXI7IHN1YnNldHRpbmcgdGhlIGRhdGFzZXQgdG8gb25seSBpbmNsdWRlIHRob3NlIG92ZXIgMjUNCiAgICAgICAgICAgICAgICAgICAgRlVOPXN2eW1lYW4sICN0aGUgZnVuY3Rpb24gSSB3YW50IGlzIHN1cnZleSBtZWFuLCBzbyB0YWtlcyB0aGUgbWVhbiBvZiBlYWNoIGxldmVsIG9mIHRoaXMgY2F0ZWdvcmljYWwgdmFyaWFibGUgYW5kIGdpdmUgYSAlDQogICAgICAgICAgICAgICAgICAgIG5hLnJtID0gVFJVRSApICNyZW1vdmUgYW55IG1pc3NpbmcgdmFsdWVzIGNvZGVkIGluIHRoZSB2YXJpYWJsZSBiZWZvcmUgaXQgZG9lcyBjYWxjdWxhdGlvbnMNCnB1bWFfZXN0X2VtcGxveTwtc3Z5YnkoZm9ybXVsYSA9IH5lbXBsb3llZCwgI2VtcGxveW1lbnQgcmF0ZSAoYmVjYXVzZSBjb2RlZCAxLDApDQogICAgICAgICAgICAgICAgICAgICAgIGJ5ID0gfnB1bWEsDQogICAgICAgICAgICAgICAgICAgICAgIGRlc2lnbj1zdWJzZXQoZGVzLCBhZ2UgJWluJSAxODo2NSksICNnZXQgd29ya2luZyBhZ2UgcGVvcGxlIGJldHdlZW4gYWdlIDE4IGFuZCA2NQ0KICAgICAgICAgICAgICAgICAgICAgICBGVU49c3Z5bWVhbiwNCiAgICAgICAgICAgICAgICAgICAgICAgbmEucm0gPSBUUlVFICkNCnB1bWFfZXN0X2luZHVzdHJ5PC1zdnlieShmb3JtdWxhID0gfnByb2Z0ZWNoLCAjcHJvcG9ydGlvbiBvZiBlYWNoIFBVTUEgd2hlcmUgdGhlIHdvcmtmb3JjZSBpcyBwcm9mdGVjaA0KICAgICAgICAgICAgICAgICAgICAgICAgIGJ5ID0gfnB1bWErc2V4K3JhY2VfZXRoLA0KICAgICAgICAgICAgICAgICAgICAgICAgIGRlc2lnbiA9IHN1YnNldChkZXMsIGVtcGxveWVkPT0xKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICBGVU4gPSBzdnltZWFuLA0KICAgICAgICAgICAgICAgICAgICAgICAgIG5hLnJtID0gVFJVRSApDQpgYGANCg0KDQpgYGB7cn0NCmxpYnJhcnkocmVsZGlzdCkNCmdpbmkucHVtYTwtZGF0YSU+JSAjY2FsY3VsYXRlIHRoaXMgbWVhc3VyZSBvZiBpbmNvbWUgaW5lcXVhbGl0eSAoR2luaSkNCiAgZmlsdGVyKGluY29tZSA+MCwgaXMubmEoaW5jb21lKT09RiklPiUgI2ZpbGVyIHRvIG9ubHkgaGF2ZSBwb3NpdGl2ZSBpbmNvbWUgKHNvIG5vdCBtaXNzaW5nKQ0KICBncm91cF9ieSggcHVtYSwgcmFjZV9ldGgpJT4lICNncm91cCBieSBQVU1BIGFuZCByYWNlL2V0aG5pY2l0eTsgZm9yIGV2ZXJ5IFBVTUEgY2FsY3VsYXRlIGluY29tZSBpbmVxdWFsaXR5IGJldHdlZW4gcmFjZS9ldGhuaWNpdHkgZ3JvdXBzDQogIHN1bW1hcml6ZShpbmVxID0gZ2luaShpbmNvbWUsIHdlaWdodHMgPSBwd3QpKSU+JSAjZ2luaSBmdW5jdGlvbiBjb21lcyBmcm9tIHRoZSByZWxkaXN0IHBhY2thZ2Ugd2hpY2ggYWxsb3dzIHBlcnNvbiB3ZWlnaHRzIHRvIGNhbGN1bGF0ZSBwcm9wZXJseQ0KICB1bmdyb3VwKCkNCmBgYA0KDQoNCmBgYHtyfQ0KaGVhZChwdW1hX2VzdF9lZHUpICNlc3RpbWF0ZXMgb2YgZWR1Y2F0aW9uIGJ5IFBVTUE7IGZpcnN0IHJvdyBzaG93cyBhYm91dCAyMyUgb2YgcmVzaWRlbnRzIG92ZXIgYWdlIDI1IGluIHRoYXQgUFVNQSBoYXZlIGxlc3MgdGhhbiBIUyBlZHVjYXRpb247IGNhbiBtYXAgYW55IGNvbHVtbg0KaGVhZChwdW1hX2VzdF9lbXBsb3kpDQpoZWFkKHB1bWFfZXN0X2luZHVzdHJ5KSAjZmlyc3Qgcm93IHNob3dzIGZvciBtYWxlcyBub24tSGlzcGFuaWMgV2hpdGUgaXMgYWJvdXQgMiUgcHJvZi90ZWNoIGluIHRoYXQgUFVNQQ0KYGBgDQoNCiMgSm9pbiB0byBHZW9ncmFwaHkNCg0KSm9pbmluZyB0aGUgc3VydmV5IGVzdGltYXRlcyBkYXRhIHRvIHRoZSBnZW9ncmFwaHkgZGF0YS4gRXZlcnkgcm93IGluIGVhY2ggZGF0YXNldCBpcyBvbmUgUFVNQS4NCg0KU2VlIFtIb3cgdG8gRG8gYSBMZWZ0IEpvaW4gaW4gUiAoV2l0aCBFeGFtcGxlcyldKGh0dHBzOi8vd3d3LnN0YXRvbG9neS5vcmcvbGVmdC1qb2luLWluLXIvKSBhbmQgW01lcmdlIERhdGEgRnJhbWVzIGluIFJdKGh0dHBzOi8vci1jb2Rlci5jb20vbWVyZ2Utci8pIGZvciBzb21lIG1vcmUgaW5zaWdodCBpbnRvIGpvaW5zLg0KDQpgYGB7cn0NCnB1bWFzJHB1bWE8LWFzLm51bWVyaWMocHVtYXMkUFVNQUNFMTApICNQVU1BQ0UxMCBpcyB0aGUgUFVNQSB2YXJpYWJsZSBpbiB0aGUgc3BhdGlhbCBkYXRhOyBoYXZlIHRvIG1ha2UgaXQgbnVtZXJpYyBiZWNhdXNlIGl0J3MgbnVtZXJpYyBpbiB0aGUgc3VydmV5IGVzdGltYXRlcw0KZ2VvMTwtbGVmdF9qb2luKHB1bWFzLCBwdW1hX2VzdF9lbXBsb3ksIGJ5PWMoInB1bWEiPSAicHVtYSIpKSAjam9pbiB0aGUgZ2VvZ3JhcGh5IChwdW1hcykgdG8gdGhlIHN0YXRpc3RpY2FsIGVzdGltYXRlIChwdW1hX2VzdF9lbXBsb3kpOyB0aGUgdmFyaWFibGUgY2FwdHVyZWQgaW4gYm90aCBpcyBjYWxsZWQgInB1bWEiDQpoZWFkKGdlbzEpDQpnZW8yPC1sZWZ0X2pvaW4ocHVtYXMsIHB1bWFfZXN0X2luZHVzdHJ5LCBieT1jKCJwdW1hIj0gInB1bWEiKSkNCmhlYWQoZ2VvMikNCmdlbzM8LWxlZnRfam9pbihwdW1hcywgZ2luaS5wdW1hLCBieT1jKCJwdW1hIj0gInB1bWEiKSkNCmhlYWQoZ2VvMikNCmBgYA0KDQojIE1hcCBFc3RpbWF0ZXMNCg0KIyMgRW1wbG95bWVudCBSYXRlcyBieSBQVU1BDQpgYGB7cn0NCnRtYXBfbW9kZSgidmlldyIpICNjYW4gdXNlIHRtYXAgYmVjYXVzZSBhbGwgc3BhdGlhbCBkYXRhDQpnZW8xJT4lICNmZWVkIHRoaXMgZW1wbG95bWVudCBkYXRhc2V0IChtYWRlIGluIGxhc3QgY2h1bmspIGludG8gdG1hcA0KICB0bV9zaGFwZSgpKw0KICB0bV9wb2x5Z29ucygiZW1wbG95ZWQiLCAjbWFwIHRoZSBlbXBsb3llZCBjb2x1bW4NCiAgICAgICAgICAgICAgc3R5bGU9ImttZWFucyIsICN0eXBlIG9mIG1hcHBpbmcgc3R5bGUgYnJlYWtzLCBjb3VsZCB1c2UgRmlzaGVyIG9yIGplbmtzIG9yIHF1YW50aWxlIGV0Yy4NCiAgICAgICAgICAgICAgbj04LCAjOCBjbGFzc2VzDQogICAgICAgICAgICAgIGxlZ2VuZC5oaXN0ID0gVFJVRSkgKyAjcGxvdCB0aGUgaGlzdG9ncmFtIChpZiBpdCB3ZXJlbid0IHRoZSBpbnRlcmFjdGl2ZSBtYXApDQogIHRtX2xheW91dChsZWdlbmQub3V0c2lkZSA9IFRSVUUsICAjcGxvdCB0aGUgaGlzdG9ncmFtL2xlZ2VuZCBvdXRzaWRlIChpZiBpdCB3ZXJlbid0IHRoZSBpbnRlcmFjdGl2ZSBtYXApDQogICAgICAgICAgICB0aXRsZSA9ICJFbXBsb3ltZW50IHJhdGUgaW4gVGV4YXMgUFVNQXMgXG4gMjAxNC0yMDE4IikgDQpgYGANCg0KYGBge3J9DQp0bWFwX21vZGUoInBsb3QiKSAjInZpZXciIGlzbid0IHdvcmtpbmcgZm9yIHNvbWUgcmVhc29uDQpnZW8yJT4lDQogIHRtX3NoYXBlKCkrDQogIHRtX3BvbHlnb25zKCJwcm9mdGVjaCIsDQogICAgICAgICAgICAgIHN0eWxlPSJrbWVhbnMiLA0KICAgICAgICAgICAgICBuPTgsDQogICAgICAgICAgICAgIGxlZ2VuZC5oaXN0ID0gVFJVRSkgKw0KIHRtX2xheW91dChsZWdlbmQub3V0c2lkZSA9IFRSVUUsDQogICAgICAgICAgICB0aXRsZSA9ICJQcm9mZXNzaW9uYWwvU2NpZW50aWZpYy9UZWNobmljYWwgRW1wbG95bWVudCBpbiBUZXhhcyBQVU1BcyBcbiAyMDE0LTIwMTgiKSAgDQpgYGANCg0KYGBge3J9DQp0bWFwX21vZGUoInBsb3QiKSAjInZpZXciIGlzbid0IHdvcmtpbmcgZm9yIHNvbWUgcmVhc29uIA0KZ2VvMyU+JQ0KdG1fc2hhcGUoKSsNCiAgdG1fcG9seWdvbnMoImluZXEiLA0KICAgICAgICAgICAgICBzdHlsZT0ia21lYW5zIiwNCiAgICAgICAgICAgICAgbj04LA0KICAgICAgICAgICAgICBsZWdlbmQuaGlzdCA9IFRSVUUpICsNCiB0bV9sYXlvdXQobGVnZW5kLm91dHNpZGUgPSBUUlVFLA0KICAgICAgICAgICAgdGl0bGUgPSAiR2luaSBpbiBUZXhhcyBQVU1BcyBcbiAyMDE0LTIwMTgiKSAgDQpgYGANCg0KDQojIyBFc3RpbWF0aW9uIGZvciBNZXRybyBBcmVhcw0KSGVyZSB3ZSB1c2UgY29yZSBiYXNlZCBzdGF0aXN0aWNhbCBhcmVhcyBpbnN0ZWFkIG9mIFBVTUFzLiBUaGUgZ2VvZ3JhcGh5IGNvcnJlc3BvbmRpbmcgdG8gTWV0cm8gQXJlYXMgYXJlIENvcmUgQmFzZWQgU3RhdGlzdGljYWwgQXJlYXMuDQoNClRoZXJlIGFyZSBhIGxvdCBvZiBwbGFjZXMgaW4gdGhlIHN0YXRlIHRoYXQgYXJlbid0IE1ldHJvcG9saXRhbiBhcmVhcywgc28gdGhleSdyZSBub3QgcmVwcmVzZW50ZWQgYXQgYWxsIGluIHRoZSBtYXAgb3IgdGhlIGVzdGltYXRlcy4NCg0KYGBge3J9DQptZXRzPC1jb3JlX2Jhc2VkX3N0YXRpc3RpY2FsX2FyZWFzKGNiID0gVCwgeWVhciA9IDIwMTgpICNmdW5jdGlvbiBmcm9tIHRpZ3JpcyB0byBnZXQgdGhlc2UgZ2VvZ3JhcGhpZXMNCm1ldHM8LW1ldHNbZ3JlcChtZXRzJE5BTUUscGF0dGVybiA9ICAiVFgiKSxdDQpwbG90KG1ldHNbIk5BTUUiXSkNCnN0czwtc3RhdGVzKGNiPVQsIHllYXI9MjAxOCkNCnN0czwtc3RzJT4lDQogIGZpbHRlcihHRU9JRD09NDgpDQpgYGANCg0KIyMgRXN0aW1hdGVzIGJ5IE1ldHJvIEFyZWFzDQoNClJlZG8gdGhlIHN1cnZleSBlc3RpbWF0aW9uIGNhbGN1bGF0aW9ucywgYnV0IHRoaXMgdGltZSB1c2UgYSBkaWZmZXJlbnQgZ3JvdXBpbmcgdmFyaWFibGUgYG1ldDIwMTNgLg0KYGBge3J9DQptZXRfZXN0X2VkdTwtc3Z5YnkoZm9ybXVsYSA9IH5lZHVjX2xldmVsLA0KICAgICAgICAgICAgICAgICAgIGJ5ID0gfm1ldDIwMTMsICNTZWUsIG5vdCBQVU1BczsgTWV0cm8gQXJlYXMgdG8gY29ycmVzcG9uZCB0byB0aGUgTWV0cm8gQXJlYXMgZ2VvbWV0cmllcyB3ZSBqdXN0IGRvd25sb2FkZWQ7IHJlc3Qgb2YgY29kZSBpcyB0aGUgc2FtZQ0KICAgICAgICAgICAgICAgICAgIGRlc2lnbj1zdWJzZXQoZGVzLGFnZT4yNSksDQogICAgICAgICAgICAgICAgICAgRlVOPXN2eW1lYW4sDQogICAgICAgICAgICAgICAgICAgbmEucm09VCApDQptZXRfZXN0X2VtcGxveTwtc3Z5YnkoZm9ybXVsYSA9IH5lbXBsb3llZCwNCiAgICAgICAgICAgICAgICAgICAgICBieSA9IH5tZXQyMDEzLA0KICAgICAgICAgICAgICAgICAgICAgIGRlc2lnbj1zdWJzZXQoZGVzLCBhZ2UlaW4lMTg6NjUpLA0KICAgICAgICAgICAgICAgICAgICAgIEZVTj1zdnltZWFuLA0KICAgICAgICAgICAgICAgICAgICAgIG5hLnJtPVQgKQ0KbWV0X2VzdF9pbmR1c3RyeTwtc3Z5YnkoZm9ybXVsYSA9IH5wcm9mdGVjaCwNCiAgICAgICAgICAgICAgICAgICAgICAgIGJ5ID0gfm1ldDIwMTMsDQogICAgICAgICAgICAgICAgICAgICAgICBkZXNpZ249c3Vic2V0KGRlcywgZW1wbG95ZWQ9PTEpLA0KICAgICAgICAgICAgICAgICAgICAgICAgRlVOPXN2eW1lYW4sDQogICAgICAgICAgICAgICAgICAgICAgICBuYS5ybT1UICkNCmhlYWQobWV0X2VzdF9lZHUpDQpoZWFkKG1ldF9lc3RfZW1wbG95KQ0KaGVhZChtZXRfZXN0X2luZHVzdHJ5KQ0KYGBgDQoNCg0KYGBge3J9DQptZXRzJG1ldDIwMTM8LWFzLm51bWVyaWMobWV0cyRHRU9JRCkNCmdlbzM8LWxlZnRfam9pbihtZXRzLCBtZXRfZXN0X2VtcGxveSxieT1jKCJtZXQyMDEzIj0gIm1ldDIwMTMiKSkNCmBgYA0KDQpOb3RlLCBncmV5IE1ldHJvcyBhcmUgb25lcyB0aGF0IGFyZSBub3QgaWRlbnRpZmllZCBpbiB0aGUgQUNTIGJlY2F1c2Ugb2YgdGhlIHBvcHVsYXRpb24gbGltaXQgKGJ1dCB0aGV5IGFyZSBpbiB0aGUgc3BhdGlhbCBkYXRhKS4NCmBgYHtyfQ0KdG1hcF9tb2RlKCJwbG90IikgIyJ2aWV3IiBpc24ndCB3b3JraW5nIGZvciBzb21lIHJlYXNvbg0KZ2VvMyU+JQ0KICB0bV9zaGFwZSgpKw0KICB0bV9wb2x5Z29ucygiZW1wbG95ZWQiLA0KICAgICAgICAgICAgICBzdHlsZT0ia21lYW5zIiwNCiAgICAgICAgICAgICAgbj04LA0KICAgICAgICAgICAgICBsZWdlbmQuaGlzdCA9IFRSVUUpICsNCiB0bV9sYXlvdXQobGVnZW5kLm91dHNpZGUgPSBUUlVFLA0KICAgICAgICAgICAgdGl0bGUgPSAiRW1wbG95bWVudCByYXRlIGluIFRleGFzIE1ldHJvIEFyZWFzIFxuIDIwMTQtMjAxOCIpICANCmBgYA0KDQoNCiMjIEVzdGltYXRpb24gZm9yIENvdW50aWVzDQoNCmBgYHtyLCByZXN1bHRzPSdoaWRlJ30NCmNvczwtY291bnRpZXMoY2I9IFQsc3RhdGUgPSAiVFgiLCB5ZWFyID0gMjAxOCkNCnBsb3QoY29zWyJOQU1FIl0pDQpzdHM8LXN0YXRlcyhjYj1ULCB5ZWFyPTIwMTgpDQpzdHM8LXN0cyU+JQ0KICBmaWx0ZXIoR0VPSUQ9PTQ4KQ0KYGBgDQoNCiMjIEVzdGltYXRlcyBieSBDb3VudHkgQXJlYQ0KYGBge3J9DQpjb3NfZXN0X2VkdTwtc3Z5YnkoZm9ybXVsYSA9IH5lZHVjX2xldmVsLA0KICAgICAgICAgICAgICAgICAgIGJ5ID0gfmNvdW50eWZpcCwNCiAgICAgICAgICAgICAgICAgICBkZXNpZ249c3Vic2V0KGRlcyxhZ2U+MjUpLA0KICAgICAgICAgICAgICAgICAgIEZVTj1zdnltZWFuLCBuYS5ybT1UICkNCmNvc19lc3RfZW1wbG95PC1zdnlieShmb3JtdWxhID0gfmVtcGxveWVkLA0KICAgICAgICAgICAgICAgICAgICAgIGJ5ID0gfmNvdW50eWZpcCwNCiAgICAgICAgICAgICAgICAgICAgICBkZXNpZ249c3Vic2V0KGRlcywgYWdlJWluJTE4OjY1KSwNCiAgICAgICAgICAgICAgICAgICAgICBGVU49c3Z5bWVhbiwgbmEucm09VCApDQpjb3NfZXN0X2luZHVzdHJ5PC1zdnlieShmb3JtdWxhID0gfnByb2Z0ZWNoLA0KICAgICAgICAgICAgICAgICAgICAgICAgYnkgPSB+Y291bnR5ZmlwLA0KICAgICAgICAgICAgICAgICAgICAgICAgZGVzaWduPXN1YnNldChkZXMsIGVtcGxveWVkPT0xKSwNCiAgICAgICAgICAgICAgICAgICAgICAgIEZVTj1zdnltZWFuLCBuYS5ybT1UICkNCmhlYWQoY29zX2VzdF9lZHUpDQpoZWFkKGNvc19lc3RfZW1wbG95KQ0KaGVhZChjb3NfZXN0X2luZHVzdHJ5KQ0KYGBgDQoNCkFnYWluLCB0aGUgQUNTIGRvZXNuJ3QgaWRlbnRpZnkgY291bnRpZXMgaW4gdGhlIG1pY3JvZGF0YSBleGNlcHQgZm9yIGNlcnRhaW4gb25lcyB0aGF0IGZpdCB0aGlzIGNyaXRlcmlhIG1lbnRpb25lZCBpbiB0aGlzIGxpbms6IFtoZXJlXShodHRwczovL3VzYS5pcHVtcy5vcmcvdXNhLWFjdGlvbi92YXJpYWJsZXMvQ09VTlRZRklQI2Rlc2NyaXB0aW9uX3NlY3Rpb24pLg0KDQpgYGB7cn0NCmNvcyRjb2ZpcDwtYXMubnVtZXJpYyhjb3MkQ09VTlRZRlApDQpnZW80PC1sZWZ0X2pvaW4oY29zLCBjb3NfZXN0X2VtcGxveSxieT1jKCJjb2ZpcCI9ICJjb3VudHlmaXAiKSkNCnRtYXBfbW9kZSgicGxvdCIpICMidmlldyIgaXNuJ3Qgd29ya2luZyBmb3Igc29tZSByZWFzb24NCmdlbzQlPiUNCiAgdG1fc2hhcGUoKSsNCiAgdG1fcG9seWdvbnMoImVtcGxveWVkIiwNCiAgICAgICAgICAgICAgc3R5bGU9ImttZWFucyIsDQogICAgICAgICAgICAgIG49OCwNCiAgICAgICAgICAgICAgbGVnZW5kLmhpc3QgPSBUUlVFKSArDQogdG1fbGF5b3V0KGxlZ2VuZC5vdXRzaWRlID0gVFJVRSwNCiAgICAgICAgICAgIHRpdGxlID0gIkVtcGxveW1lbnQgcmF0ZSBpbiBUZXhhcyBDb3VudGllcyBcbiAyMDE0LTIwMTgiKSAgDQpgYGANCg==