# Download ACS data for the year 2015 for Los Angeles County, California census tracts in R using the tidycensus library

LA_county <- get_acs(geography = 'tract',variables = c(totPop15 = "B01001_001", 
                                                   hispanic ="B03003_003", 
                                                   afrAm = "B02001_003"), 
                    year = 2015, state = 'CA', county="Los Angeles", geometry = TRUE) %>% 
            dplyr::select(GEOID, NAME, variable, estimate) %>% 
            spread(variable, estimate) %>% 
            mutate(hispPr15  = hispanic/totPop15, 
                   nhblackpr15 = afrAm/totPop15, racer=round((afrAm/hispanic)*100),1) %>%
            dplyr::select(GEOID,totPop15,hispPr15,nhblackpr15,racer)
## Getting data from the 2011-2015 5-year ACS
## Downloading feature geometry from the Census website.  To cache shapefiles for use in future sessions, set `options(tigris_use_cache = TRUE)`.
# Load County Boundary for California
lacounty<- counties(year=2015, state = "CA", refresh=T, cb = T, progress_bar=FALSE)

# ASsign same CSR for both the boundary and Race ratio shape files, then intersect it
LA_Boundary<- st_transform(lacounty, 4326)
LA_censustract <- st_transform(LA_county, 4326)
LAcounty <- st_intersection(LA_censustract,LA_Boundary)

# Filter out tracts without race ratios
LAcounty<-LAcounty%>%
  filter(complete.cases(racer))


Hispanic <- LAcounty%>%
  mutate(hispPr15=cut(hispPr15,
                  breaks = quantile(LAcounty$hispPr15,
                                    p=c(0, .25, .5, .75, 1)),
                  include.lowest = T))%>%
  ggplot()+
  geom_sf(aes(fill=hispPr15, color=hispPr15))+theme_void()+
  scale_fill_brewer(palette = "Blues")+
  scale_color_brewer(palette = "Blues")+
  ggtitle("Los Angeles Hispanic Race Proportion")+labs(fill="Hispanic Proportion", color="Hispanic Proportion")+
  theme(plot.title = element_text(size=10, hjust = 0.2)) +
  theme(
        legend.key.width = unit(0.25, "in"),
        legend.key.height = unit(0.2, "in"),
        legend.text = element_text(size=8))


Black <- LAcounty%>%
  mutate(nhblackpr15=cut(nhblackpr15,
                  breaks = quantile(LAcounty$nhblackpr15,
                                    p=c(0, .25, .5, .75, 1)),
                  include.lowest = T))%>%
  ggplot()+
  geom_sf(aes(fill=nhblackpr15, color=nhblackpr15))+theme_void()+
  scale_fill_brewer(palette = "Blues")+
  scale_color_brewer(palette = "Blues")+
  ggtitle("Los Angeles Non-Hispanic Black Race Proportion")+labs(fill="Non-HBlack Proportion", color="Non-HBlack Proportion")+
  theme(plot.title = element_text(size=10, hjust = 0.2)) +
  theme(
        legend.key.width = unit(0.25, "in"),
        legend.key.height = unit(0.2, "in"),
        legend.text = element_text(size=8))


BHRR <- LAcounty%>%
  mutate(racer=cut(racer,
                  breaks = quantile(LAcounty$racer,
                                    p=c(0, .25, .5, .75, 1)),
                  include.lowest = T))%>%
  ggplot()+
  geom_sf(aes(fill=racer, color=racer))+
  scale_fill_brewer(palette = "Blues")+
  scale_color_brewer(palette = "Blues")+theme_void()+
  ggtitle("Los Angeles Non-HBlack To Hispanic Race Ratio")+labs(fill="Black-Hispanic Race Ratio", color="Black-Hispanic Race Ratio")+
  theme(plot.title = element_text(size=10, hjust = 0.0)) +
  theme(
        legend.key.width = unit(0.25, "in"),
        legend.key.height = unit(0.2, "in"),
        legend.text = element_text(size=8))

grid.arrange(Hispanic, Black,BHRR, nrow = 2)

Queen-based contiquity

Lanb<-poly2nb(LAcounty, queen=T)
summary(Lanb)
## Neighbour list object:
## Number of regions: 2323 
## Number of nonzero links: 14728 
## Percentage nonzero weights: 0.2729263 
## Average number of links: 6.340077 
## Link number distribution:
## 
##   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  19  25 
##   4  10  51 201 469 610 484 274 132  51  23   5   1   2   1   2   2   1 
## 4 least connected regions:
## 145 264 1328 1329 with 1 link
## 1 most connected region:
## 1013 with 25 links
Lalw<-nb2listw(Lanb, style="W")

# Map Plots for the Neighbors 
plot(as(LAcounty, "Spatial"),
     main="Queen-based Neighbors")
plot(Lalw,
     coords=coordinates(as(LAcounty, "Spatial")),
     add=T,
     col=2)

k-nearest neighbor adjacency

knn<-knearneigh(x = coordinates(as(LAcounty, "Spatial")), k = 4)
knn3<-knn2nb(knn = knn)
Lalwk<-nb2listw(knn3, style="W")

# Map Plots for the Neighbors
plot(as(LAcounty, "Spatial"),
     main="k=4 Neighbors")
plot(knn3,
     coords=coordinates(as(LAcounty, "Spatial")),
     add=T,
     col=2)

Queen-based Moran I

#Moran test for the Hispanic population
moran.test(LAcounty$hispPr15, 
           listw=Lalw)
## 
##  Moran I test under randomisation
## 
## data:  LAcounty$hispPr15  
## weights: Lalw    
## 
## Moran I statistic standard deviate = 68.86, p-value < 2.2e-16
## alternative hypothesis: greater
## sample estimates:
## Moran I statistic       Expectation          Variance 
##      0.8191397397     -0.0004306632      0.0001416582
moran.mc(LAcounty$hispPr15,
         listw=Lalw,
         nsim=999)
## 
##  Monte-Carlo simulation of Moran I
## 
## data:  LAcounty$hispPr15 
## weights: Lalw  
## number of simulations + 1: 1000 
## 
## statistic = 0.81914, observed rank = 1000, p-value = 0.001
## alternative hypothesis: greater
#Moran Scatter plot Hispanic population
moran.plot(as.numeric(scale(LAcounty$hispPr15)),
           listw=Lalw)

# Moran test for the black population
moran.test(LAcounty$nhblackpr15, 
           listw=Lalw)
## 
##  Moran I test under randomisation
## 
## data:  LAcounty$nhblackpr15  
## weights: Lalw    
## 
## Moran I statistic standard deviate = 66.349, p-value < 2.2e-16
## alternative hypothesis: greater
## sample estimates:
## Moran I statistic       Expectation          Variance 
##      0.7871447555     -0.0004306632      0.0001408999
moran.mc(LAcounty$nhblackpr15,
         listw=Lalw,
         nsim=999)
## 
##  Monte-Carlo simulation of Moran I
## 
## data:  LAcounty$nhblackpr15 
## weights: Lalw  
## number of simulations + 1: 1000 
## 
## statistic = 0.78714, observed rank = 1000, p-value = 0.001
## alternative hypothesis: greater
#Moran Scatter plot for the black population
moran.plot(as.numeric(scale(LAcounty$nhblackpr15)),
           listw=Lalw)

Using the queen rule to define tracts that are neighbors, the global Moran I statistics is 0.83 . This shows that there is a significant strong positive association between the proportion of Hispanic population in tracts and their spatially lagged values(p-value=2.2e-16). We see the same relationship for the Non-Hispanic Black variable with a global Moran I statistics of 0.78 and a p-value of 2.2e-16

k-nearest Moran I

#Moran test for the Hispanic population
moran.test(LAcounty$hispPr15, 
           listw=Lalwk)
## 
##  Moran I test under randomisation
## 
## data:  LAcounty$hispPr15  
## weights: Lalwk    
## 
## Moran I statistic standard deviate = 60.405, p-value < 2.2e-16
## alternative hypothesis: greater
## sample estimates:
## Moran I statistic       Expectation          Variance 
##      0.8349493475     -0.0004306632      0.0001912561
moran.mc(LAcounty$hispPr15,
         listw=Lalwk,
         nsim=999)
## 
##  Monte-Carlo simulation of Moran I
## 
## data:  LAcounty$hispPr15 
## weights: Lalwk  
## number of simulations + 1: 1000 
## 
## statistic = 0.83495, observed rank = 1000, p-value = 0.001
## alternative hypothesis: greater
#Moran Scatter plot for the Hispanic population
moran.plot(as.numeric(scale(LAcounty$hispPr15)),
           listw=Lalwk)

#Moran test for the Black population
moran.test(LAcounty$nhblackpr15, 
           listw=Lalwk)
## 
##  Moran I test under randomisation
## 
## data:  LAcounty$nhblackpr15  
## weights: Lalwk    
## 
## Moran I statistic standard deviate = 56.331, p-value < 2.2e-16
## alternative hypothesis: greater
## sample estimates:
## Moran I statistic       Expectation          Variance 
##      0.7765172349     -0.0004306632      0.0001902322
moran.mc(LAcounty$nhblackpr15,
         listw=Lalwk,
         nsim=999)
## 
##  Monte-Carlo simulation of Moran I
## 
## data:  LAcounty$nhblackpr15 
## weights: Lalwk  
## number of simulations + 1: 1000 
## 
## statistic = 0.77652, observed rank = 1000, p-value = 0.001
## alternative hypothesis: greater
#Moran Scatter plot for the Black population
moran.plot(as.numeric(scale(LAcounty$nhblackpr15)),
           listw=Lalwk)

Using the k-nearest(k=4) rule to define tracts that are neighbors, the global Moran I statistics is 0.83 . This shows that there is a significant strong positive association between the proportion of Hispanic population in tracts and their spatially lagged values(p-value=2.2e-16). We see the same relationship for the Non-Hispanic Black variable with a global Moran I statistics of 0.78 and a p-value of 2.2e-16. There is no difference between the Moran I statistics of the two methods of defining neighbor tracts (Queen-based and k-nearest)

k-nearest Cluster Moran I

locali<-localmoran(LAcounty$hispPr15, 
           listw=Lalwk, p.adjust.method="fdr")
LAcounty$localr<-locali[,1]
LAcounty$locall<-locali[,5]

LAcounty$srr<-scale(LAcounty$hispPr15)
LAcounty$lag_rr<-lag.listw(var=LAcounty$srr, x = Lalwk)
LAcounty$quad_sig <- NA
LAcounty$quad_sig[(LAcounty$srr >= 0 & LAcounty$lag_rr >= 0) & (LAcounty$locall <= 0.05)] <- "H-H" #high high
LAcounty$quad_sig[(LAcounty$srr <= 0 & LAcounty$lag_rr <= 0) & (LAcounty$locall <= 0.05)] <- "L-L" #low low
LAcounty$quad_sig[(LAcounty$srr >= 0 & LAcounty$lag_rr <= 0) & (LAcounty$locall <= 0.05)] <- "H-L" #high low
LAcounty$quad_sig[(LAcounty$srr <= 0 & LAcounty$lag_rr >= 0) & (LAcounty$locall <= 0.05)] <- "L-H" #low high

#WE ASSIGN A # Set the breaks for the thematic map classes
breaks <- seq(1, 5, 1)

# Set the corresponding labels for the thematic map classes
labels <- c("High-High", "Low-Low", "High-Low", "Low-High", "Not Clustered")

# see ?findInterval - This is necessary for making a map
np <- findInterval(LAcounty$quad_sig, breaks)

# Assign colors to each map class
colors <- c("red", "blue", "lightpink", "skyblue2", "white")

his <- LAcounty%>%
  filter(complete.cases(hispPr15)) %>% 
  ggplot()+
  geom_sf(aes(fill = quad_sig))+
  ggtitle("Moran Cluster Map -\nProportion of Hispanic Population",
          sub=" Los Angeles County, CA")+labs(fill="Proportion of Hispanic", color="Proportion of Hispanic")+
  theme(plot.title = element_text(size=14, hjust = 0.2)) +theme_void()+
  theme(
        legend.key.width = unit(0.5, "in"),
        legend.key.height = unit(0.3, "in"),
        legend.text = element_text(size=8))
locali<-localmoran(LAcounty$nhblackpr15, 
           listw=Lalwk, p.adjust.method="fdr")
LAcounty$localr<-locali[,1]
LAcounty$locall<-locali[,5]

LAcounty$srr<-scale(LAcounty$hispPr15)
LAcounty$lag_rr<-lag.listw(var=LAcounty$srr, x = Lalwk)
LAcounty$quad_sig <- NA
LAcounty$quad_sig[(LAcounty$srr >= 0 & LAcounty$lag_rr >= 0) & (LAcounty$locall <= 0.05)] <- "H-H" #high high
LAcounty$quad_sig[(LAcounty$srr <= 0 & LAcounty$lag_rr <= 0) & (LAcounty$locall <= 0.05)] <- "L-L" #low low
LAcounty$quad_sig[(LAcounty$srr >= 0 & LAcounty$lag_rr <= 0) & (LAcounty$locall <= 0.05)] <- "H-L" #high low
LAcounty$quad_sig[(LAcounty$srr <= 0 & LAcounty$lag_rr >= 0) & (LAcounty$locall <= 0.05)] <- "L-H" #low high

#WE ASSIGN A # Set the breaks for the thematic map classes
breaks <- seq(1, 5, 1)

# Set the corresponding labels for the thematic map classes
labels <- c("High-High", "Low-Low", "High-Low", "Low-High", "Not Clustered")

# find Interval - This is necessary for making a map
np <- findInterval(LAcounty$quad_sig, breaks)

# Assign colors to each map class
colors <- c("red", "blue", "lightpink", "skyblue2", "white")

blk <- LAcounty%>%
  ggplot()+
  geom_sf(aes(fill = quad_sig))+
  ggtitle("Moran Cluster Map -\nProportion of Non-Hispanic Black Population",
          sub=" Los Angeles County, CA")+labs(fill="Non-Hispanic Black", color="Proportion of Non-Hispanic Black")+
  theme(plot.title = element_text(size=14, hjust = 0.2)) +theme_void()+
  theme(
        legend.key.width = unit(0.5, "in"),
        legend.key.height = unit(0.3, "in"),
        legend.text = element_text(size=))
grid.arrange(his, blk, nrow = 1)

Here is a LISA map for clusters of hispanic and Non-Hispanic black in Los Angeles county, CA, which shows areas of concentrated (clustered) low income clustering in red, and concentrated high income in blue.

The red and blue areas are so-called clusters, because they are areas with higher (or lower, for the blues) than average proportion of the races, surrounded by areas that also have higher than average race proportion for the two groups. The red clusters are so called “high-high clusters”, likewise the blue areas are called “low-low clusters”.

These maps suggests that LA county is highly segregated by race.

Likewise, possible values include light blue polygons, these are called low-high outliers, because they have low proportion of the non-hispanic black population, but are in a high proportion of other races spatial neighborhood.

LS0tCnRpdGxlOiAiU3BhdGlhbCBEZW1vZ3JhcGh5IC0gSG9tZXdrIDEgLSBFeHBsb3JhdG9yeSBBbmFseXNpcyIKYXV0aG9yOiAiU2Ftc29uIE9sb3dvbGFqdSwgTVBIIgpkYXRlOiAiYHIgZm9ybWF0KFN5cy50aW1lKCksICclZCAlQiwgJVknKWAiCm91dHB1dDoKICAgaHRtbF9kb2N1bWVudDoKICAgIGRmX3ByaW50OiBwYWdlZAogICAgZmlnX2hlaWdodDogNwogICAgZmlnX3dpZHRoOiA3CiAgICB0b2M6IHllcwogICAgdG9jX2Zsb2F0OiB5ZXMKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKLS0tCjxzdHlsZT4KYm9keSB7CnRleHQtYWxpZ246IGp1c3RpZnl9Cjwvc3R5bGU+CmBgYHtyLCBpbmNsdWRlPUZBTFNFfQojbG9hZCBQYWNrYWdlcyBmb3IgYW5hbHlzaXMKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoc3BkZXApCmxpYnJhcnkoc2YpCmxpYnJhcnkodGlkeWNlbnN1cykKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkodGlncmlzKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkodG1hcCkKbGlicmFyeShncmlkRXh0cmEpCmBgYAoKCmBgYHtyLCBtZXNzYWdlPVRSVUUsIHdhcm5pbmc9RkFMU0UsIHJlc3VsdHM9J2hpZGUnfQojIERvd25sb2FkIEFDUyBkYXRhIGZvciB0aGUgeWVhciAyMDE1IGZvciBMb3MgQW5nZWxlcyBDb3VudHksIENhbGlmb3JuaWEgY2Vuc3VzIHRyYWN0cyBpbiBSIHVzaW5nIHRoZSB0aWR5Y2Vuc3VzIGxpYnJhcnkKCkxBX2NvdW50eSA8LSBnZXRfYWNzKGdlb2dyYXBoeSA9ICd0cmFjdCcsdmFyaWFibGVzID0gYyh0b3RQb3AxNSA9ICJCMDEwMDFfMDAxIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhpc3BhbmljID0iQjAzMDAzXzAwMyIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZnJBbSA9ICJCMDIwMDFfMDAzIiksIAogICAgICAgICAgICAgICAgICAgIHllYXIgPSAyMDE1LCBzdGF0ZSA9ICdDQScsIGNvdW50eT0iTG9zIEFuZ2VsZXMiLCBnZW9tZXRyeSA9IFRSVUUpICU+JSAKICAgICAgICAgICAgZHBseXI6OnNlbGVjdChHRU9JRCwgTkFNRSwgdmFyaWFibGUsIGVzdGltYXRlKSAlPiUgCiAgICAgICAgICAgIHNwcmVhZCh2YXJpYWJsZSwgZXN0aW1hdGUpICU+JSAKICAgICAgICAgICAgbXV0YXRlKGhpc3BQcjE1ICA9IGhpc3BhbmljL3RvdFBvcDE1LCAKICAgICAgICAgICAgICAgICAgIG5oYmxhY2twcjE1ID0gYWZyQW0vdG90UG9wMTUsIHJhY2VyPXJvdW5kKChhZnJBbS9oaXNwYW5pYykqMTAwKSwxKSAlPiUKICAgICAgICAgICAgZHBseXI6OnNlbGVjdChHRU9JRCx0b3RQb3AxNSxoaXNwUHIxNSxuaGJsYWNrcHIxNSxyYWNlcikKCiMgTG9hZCBDb3VudHkgQm91bmRhcnkgZm9yIENhbGlmb3JuaWEKbGFjb3VudHk8LSBjb3VudGllcyh5ZWFyPTIwMTUsIHN0YXRlID0gIkNBIiwgcmVmcmVzaD1ULCBjYiA9IFQsIHByb2dyZXNzX2Jhcj1GQUxTRSkKCiMgQVNzaWduIHNhbWUgQ1NSIGZvciBib3RoIHRoZSBib3VuZGFyeSBhbmQgUmFjZSByYXRpbyBzaGFwZSBmaWxlcywgdGhlbiBpbnRlcnNlY3QgaXQKTEFfQm91bmRhcnk8LSBzdF90cmFuc2Zvcm0obGFjb3VudHksIDQzMjYpCkxBX2NlbnN1c3RyYWN0IDwtIHN0X3RyYW5zZm9ybShMQV9jb3VudHksIDQzMjYpCkxBY291bnR5IDwtIHN0X2ludGVyc2VjdGlvbihMQV9jZW5zdXN0cmFjdCxMQV9Cb3VuZGFyeSkKCiMgRmlsdGVyIG91dCB0cmFjdHMgd2l0aG91dCByYWNlIHJhdGlvcwpMQWNvdW50eTwtTEFjb3VudHklPiUKICBmaWx0ZXIoY29tcGxldGUuY2FzZXMocmFjZXIpKQoKCkhpc3BhbmljIDwtIExBY291bnR5JT4lCiAgbXV0YXRlKGhpc3BQcjE1PWN1dChoaXNwUHIxNSwKICAgICAgICAgICAgICAgICAgYnJlYWtzID0gcXVhbnRpbGUoTEFjb3VudHkkaGlzcFByMTUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHA9YygwLCAuMjUsIC41LCAuNzUsIDEpKSwKICAgICAgICAgICAgICAgICAgaW5jbHVkZS5sb3dlc3QgPSBUKSklPiUKICBnZ3Bsb3QoKSsKICBnZW9tX3NmKGFlcyhmaWxsPWhpc3BQcjE1LCBjb2xvcj1oaXNwUHIxNSkpK3RoZW1lX3ZvaWQoKSsKICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIkJsdWVzIikrCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGUgPSAiQmx1ZXMiKSsKICBnZ3RpdGxlKCJMb3MgQW5nZWxlcyBIaXNwYW5pYyBSYWNlIFByb3BvcnRpb24iKStsYWJzKGZpbGw9Ikhpc3BhbmljIFByb3BvcnRpb24iLCBjb2xvcj0iSGlzcGFuaWMgUHJvcG9ydGlvbiIpKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0xMCwgaGp1c3QgPSAwLjIpKSArCiAgdGhlbWUoCiAgICAgICAgbGVnZW5kLmtleS53aWR0aCA9IHVuaXQoMC4yNSwgImluIiksCiAgICAgICAgbGVnZW5kLmtleS5oZWlnaHQgPSB1bml0KDAuMiwgImluIiksCiAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT04KSkKCgpCbGFjayA8LSBMQWNvdW50eSU+JQogIG11dGF0ZShuaGJsYWNrcHIxNT1jdXQobmhibGFja3ByMTUsCiAgICAgICAgICAgICAgICAgIGJyZWFrcyA9IHF1YW50aWxlKExBY291bnR5JG5oYmxhY2twcjE1LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwPWMoMCwgLjI1LCAuNSwgLjc1LCAxKSksCiAgICAgICAgICAgICAgICAgIGluY2x1ZGUubG93ZXN0ID0gVCkpJT4lCiAgZ2dwbG90KCkrCiAgZ2VvbV9zZihhZXMoZmlsbD1uaGJsYWNrcHIxNSwgY29sb3I9bmhibGFja3ByMTUpKSt0aGVtZV92b2lkKCkrCiAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJCbHVlcyIpKwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIkJsdWVzIikrCiAgZ2d0aXRsZSgiTG9zIEFuZ2VsZXMgTm9uLUhpc3BhbmljIEJsYWNrIFJhY2UgUHJvcG9ydGlvbiIpK2xhYnMoZmlsbD0iTm9uLUhCbGFjayBQcm9wb3J0aW9uIiwgY29sb3I9Ik5vbi1IQmxhY2sgUHJvcG9ydGlvbiIpKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0xMCwgaGp1c3QgPSAwLjIpKSArCiAgdGhlbWUoCiAgICAgICAgbGVnZW5kLmtleS53aWR0aCA9IHVuaXQoMC4yNSwgImluIiksCiAgICAgICAgbGVnZW5kLmtleS5oZWlnaHQgPSB1bml0KDAuMiwgImluIiksCiAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT04KSkKCgpCSFJSIDwtIExBY291bnR5JT4lCiAgbXV0YXRlKHJhY2VyPWN1dChyYWNlciwKICAgICAgICAgICAgICAgICAgYnJlYWtzID0gcXVhbnRpbGUoTEFjb3VudHkkcmFjZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHA9YygwLCAuMjUsIC41LCAuNzUsIDEpKSwKICAgICAgICAgICAgICAgICAgaW5jbHVkZS5sb3dlc3QgPSBUKSklPiUKICBnZ3Bsb3QoKSsKICBnZW9tX3NmKGFlcyhmaWxsPXJhY2VyLCBjb2xvcj1yYWNlcikpKwogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiQmx1ZXMiKSsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZSA9ICJCbHVlcyIpK3RoZW1lX3ZvaWQoKSsKICBnZ3RpdGxlKCJMb3MgQW5nZWxlcyBOb24tSEJsYWNrIFRvIEhpc3BhbmljIFJhY2UgUmF0aW8iKStsYWJzKGZpbGw9IkJsYWNrLUhpc3BhbmljIFJhY2UgUmF0aW8iLCBjb2xvcj0iQmxhY2stSGlzcGFuaWMgUmFjZSBSYXRpbyIpKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0xMCwgaGp1c3QgPSAwLjApKSArCiAgdGhlbWUoCiAgICAgICAgbGVnZW5kLmtleS53aWR0aCA9IHVuaXQoMC4yNSwgImluIiksCiAgICAgICAgbGVnZW5kLmtleS5oZWlnaHQgPSB1bml0KDAuMiwgImluIiksCiAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT04KSkKCmdyaWQuYXJyYW5nZShIaXNwYW5pYywgQmxhY2ssQkhSUiwgbnJvdyA9IDIpCmBgYAoKIyMjIFF1ZWVuLWJhc2VkIGNvbnRpcXVpdHkgCmBgYHtyIH0KTGFuYjwtcG9seTJuYihMQWNvdW50eSwgcXVlZW49VCkKc3VtbWFyeShMYW5iKQpMYWx3PC1uYjJsaXN0dyhMYW5iLCBzdHlsZT0iVyIpCgojIE1hcCBQbG90cyBmb3IgdGhlIE5laWdoYm9ycyAKcGxvdChhcyhMQWNvdW50eSwgIlNwYXRpYWwiKSwKICAgICBtYWluPSJRdWVlbi1iYXNlZCBOZWlnaGJvcnMiKQpwbG90KExhbHcsCiAgICAgY29vcmRzPWNvb3JkaW5hdGVzKGFzKExBY291bnR5LCAiU3BhdGlhbCIpKSwKICAgICBhZGQ9VCwKICAgICBjb2w9MikKYGBgCgojIyMgay1uZWFyZXN0IG5laWdoYm9yIGFkamFjZW5jeSAKYGBge3J9Cmtubjwta25lYXJuZWlnaCh4ID0gY29vcmRpbmF0ZXMoYXMoTEFjb3VudHksICJTcGF0aWFsIikpLCBrID0gNCkKa25uMzwta25uMm5iKGtubiA9IGtubikKTGFsd2s8LW5iMmxpc3R3KGtubjMsIHN0eWxlPSJXIikKCiMgTWFwIFBsb3RzIGZvciB0aGUgTmVpZ2hib3JzCnBsb3QoYXMoTEFjb3VudHksICJTcGF0aWFsIiksCiAgICAgbWFpbj0iaz00IE5laWdoYm9ycyIpCnBsb3Qoa25uMywKICAgICBjb29yZHM9Y29vcmRpbmF0ZXMoYXMoTEFjb3VudHksICJTcGF0aWFsIikpLAogICAgIGFkZD1ULAogICAgIGNvbD0yKQoKYGBgCgojIyMgUXVlZW4tYmFzZWQgTW9yYW4gSQpgYGB7cn0KI01vcmFuIHRlc3QgZm9yIHRoZSBIaXNwYW5pYyBwb3B1bGF0aW9uCm1vcmFuLnRlc3QoTEFjb3VudHkkaGlzcFByMTUsIAogICAgICAgICAgIGxpc3R3PUxhbHcpCm1vcmFuLm1jKExBY291bnR5JGhpc3BQcjE1LAogICAgICAgICBsaXN0dz1MYWx3LAogICAgICAgICBuc2ltPTk5OSkKCiNNb3JhbiBTY2F0dGVyIHBsb3QgSGlzcGFuaWMgcG9wdWxhdGlvbgptb3Jhbi5wbG90KGFzLm51bWVyaWMoc2NhbGUoTEFjb3VudHkkaGlzcFByMTUpKSwKICAgICAgICAgICBsaXN0dz1MYWx3KQoKIyBNb3JhbiB0ZXN0IGZvciB0aGUgYmxhY2sgcG9wdWxhdGlvbgptb3Jhbi50ZXN0KExBY291bnR5JG5oYmxhY2twcjE1LCAKICAgICAgICAgICBsaXN0dz1MYWx3KQptb3Jhbi5tYyhMQWNvdW50eSRuaGJsYWNrcHIxNSwKICAgICAgICAgbGlzdHc9TGFsdywKICAgICAgICAgbnNpbT05OTkpCgojTW9yYW4gU2NhdHRlciBwbG90IGZvciB0aGUgYmxhY2sgcG9wdWxhdGlvbgptb3Jhbi5wbG90KGFzLm51bWVyaWMoc2NhbGUoTEFjb3VudHkkbmhibGFja3ByMTUpKSwKICAgICAgICAgICBsaXN0dz1MYWx3KQoKYGBgCgpVc2luZyB0aGUgcXVlZW4gcnVsZSB0byBkZWZpbmUgdHJhY3RzIHRoYXQgYXJlIG5laWdoYm9ycywgdGhlIGdsb2JhbCBNb3JhbiBJIHN0YXRpc3RpY3MgaXMgMC44MyAuIFRoaXMgc2hvd3MgdGhhdCB0aGVyZSBpcyBhIHNpZ25pZmljYW50IHN0cm9uZyBwb3NpdGl2ZSBhc3NvY2lhdGlvbiBiZXR3ZWVuIHRoZSBwcm9wb3J0aW9uIG9mIEhpc3BhbmljIHBvcHVsYXRpb24gaW4gdHJhY3RzIGFuZCB0aGVpciBzcGF0aWFsbHkgbGFnZ2VkIHZhbHVlcyhwLXZhbHVlPTIuMmUtMTYpLiBXZSBzZWUgdGhlIHNhbWUgcmVsYXRpb25zaGlwIGZvciB0aGUgTm9uLUhpc3BhbmljIEJsYWNrIHZhcmlhYmxlIHdpdGggYSBnbG9iYWwgTW9yYW4gSSBzdGF0aXN0aWNzIG9mIDAuNzggYW5kIGEgcC12YWx1ZSBvZiAyLjJlLTE2CgojIyMgay1uZWFyZXN0IE1vcmFuIEkKYGBge3Isd2FybmluZz1GQUxTRX0KI01vcmFuIHRlc3QgZm9yIHRoZSBIaXNwYW5pYyBwb3B1bGF0aW9uCm1vcmFuLnRlc3QoTEFjb3VudHkkaGlzcFByMTUsIAogICAgICAgICAgIGxpc3R3PUxhbHdrKQptb3Jhbi5tYyhMQWNvdW50eSRoaXNwUHIxNSwKICAgICAgICAgbGlzdHc9TGFsd2ssCiAgICAgICAgIG5zaW09OTk5KQoKI01vcmFuIFNjYXR0ZXIgcGxvdCBmb3IgdGhlIEhpc3BhbmljIHBvcHVsYXRpb24KbW9yYW4ucGxvdChhcy5udW1lcmljKHNjYWxlKExBY291bnR5JGhpc3BQcjE1KSksCiAgICAgICAgICAgbGlzdHc9TGFsd2spCgojTW9yYW4gdGVzdCBmb3IgdGhlIEJsYWNrIHBvcHVsYXRpb24KbW9yYW4udGVzdChMQWNvdW50eSRuaGJsYWNrcHIxNSwgCiAgICAgICAgICAgbGlzdHc9TGFsd2spCm1vcmFuLm1jKExBY291bnR5JG5oYmxhY2twcjE1LAogICAgICAgICBsaXN0dz1MYWx3aywKICAgICAgICAgbnNpbT05OTkpCgojTW9yYW4gU2NhdHRlciBwbG90IGZvciB0aGUgQmxhY2sgcG9wdWxhdGlvbgptb3Jhbi5wbG90KGFzLm51bWVyaWMoc2NhbGUoTEFjb3VudHkkbmhibGFja3ByMTUpKSwKICAgICAgICAgICBsaXN0dz1MYWx3aykKYGBgCgpVc2luZyB0aGUgay1uZWFyZXN0KGs9NCkgcnVsZSB0byBkZWZpbmUgdHJhY3RzIHRoYXQgYXJlIG5laWdoYm9ycywgdGhlIGdsb2JhbCBNb3JhbiBJIHN0YXRpc3RpY3MgaXMgMC44MyAuIFRoaXMgc2hvd3MgdGhhdCB0aGVyZSBpcyBhIHNpZ25pZmljYW50IHN0cm9uZyBwb3NpdGl2ZSBhc3NvY2lhdGlvbiBiZXR3ZWVuIHRoZSBwcm9wb3J0aW9uIG9mIEhpc3BhbmljIHBvcHVsYXRpb24gaW4gdHJhY3RzIGFuZCB0aGVpciBzcGF0aWFsbHkgbGFnZ2VkIHZhbHVlcyhwLXZhbHVlPTIuMmUtMTYpLiBXZSBzZWUgdGhlIHNhbWUgcmVsYXRpb25zaGlwIGZvciB0aGUgTm9uLUhpc3BhbmljIEJsYWNrIHZhcmlhYmxlIHdpdGggYSBnbG9iYWwgTW9yYW4gSSBzdGF0aXN0aWNzIG9mIDAuNzggYW5kIGEgcC12YWx1ZSBvZiAyLjJlLTE2LiBUaGVyZSBpcyBubyBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIE1vcmFuIEkgc3RhdGlzdGljcyBvZiB0aGUgdHdvIG1ldGhvZHMgb2YgZGVmaW5pbmcgbmVpZ2hib3IgdHJhY3RzIChRdWVlbi1iYXNlZCBhbmQgay1uZWFyZXN0KQoKIyMjIGstbmVhcmVzdCBDbHVzdGVyIE1vcmFuIEkKYGBge3IsIHdhcm5pbmc9RkFMU0V9CmxvY2FsaTwtbG9jYWxtb3JhbihMQWNvdW50eSRoaXNwUHIxNSwgCiAgICAgICAgICAgbGlzdHc9TGFsd2ssIHAuYWRqdXN0Lm1ldGhvZD0iZmRyIikKTEFjb3VudHkkbG9jYWxyPC1sb2NhbGlbLDFdCkxBY291bnR5JGxvY2FsbDwtbG9jYWxpWyw1XQoKTEFjb3VudHkkc3JyPC1zY2FsZShMQWNvdW50eSRoaXNwUHIxNSkKTEFjb3VudHkkbGFnX3JyPC1sYWcubGlzdHcodmFyPUxBY291bnR5JHNyciwgeCA9IExhbHdrKQpMQWNvdW50eSRxdWFkX3NpZyA8LSBOQQpMQWNvdW50eSRxdWFkX3NpZ1soTEFjb3VudHkkc3JyID49IDAgJiBMQWNvdW50eSRsYWdfcnIgPj0gMCkgJiAoTEFjb3VudHkkbG9jYWxsIDw9IDAuMDUpXSA8LSAiSC1IIiAjaGlnaCBoaWdoCkxBY291bnR5JHF1YWRfc2lnWyhMQWNvdW50eSRzcnIgPD0gMCAmIExBY291bnR5JGxhZ19yciA8PSAwKSAmIChMQWNvdW50eSRsb2NhbGwgPD0gMC4wNSldIDwtICJMLUwiICNsb3cgbG93CkxBY291bnR5JHF1YWRfc2lnWyhMQWNvdW50eSRzcnIgPj0gMCAmIExBY291bnR5JGxhZ19yciA8PSAwKSAmIChMQWNvdW50eSRsb2NhbGwgPD0gMC4wNSldIDwtICJILUwiICNoaWdoIGxvdwpMQWNvdW50eSRxdWFkX3NpZ1soTEFjb3VudHkkc3JyIDw9IDAgJiBMQWNvdW50eSRsYWdfcnIgPj0gMCkgJiAoTEFjb3VudHkkbG9jYWxsIDw9IDAuMDUpXSA8LSAiTC1IIiAjbG93IGhpZ2gKCiNXRSBBU1NJR04gQSAjIFNldCB0aGUgYnJlYWtzIGZvciB0aGUgdGhlbWF0aWMgbWFwIGNsYXNzZXMKYnJlYWtzIDwtIHNlcSgxLCA1LCAxKQoKIyBTZXQgdGhlIGNvcnJlc3BvbmRpbmcgbGFiZWxzIGZvciB0aGUgdGhlbWF0aWMgbWFwIGNsYXNzZXMKbGFiZWxzIDwtIGMoIkhpZ2gtSGlnaCIsICJMb3ctTG93IiwgIkhpZ2gtTG93IiwgIkxvdy1IaWdoIiwgIk5vdCBDbHVzdGVyZWQiKQoKIyBzZWUgP2ZpbmRJbnRlcnZhbCAtIFRoaXMgaXMgbmVjZXNzYXJ5IGZvciBtYWtpbmcgYSBtYXAKbnAgPC0gZmluZEludGVydmFsKExBY291bnR5JHF1YWRfc2lnLCBicmVha3MpCgojIEFzc2lnbiBjb2xvcnMgdG8gZWFjaCBtYXAgY2xhc3MKY29sb3JzIDwtIGMoInJlZCIsICJibHVlIiwgImxpZ2h0cGluayIsICJza3libHVlMiIsICJ3aGl0ZSIpCgpoaXMgPC0gTEFjb3VudHklPiUKICBmaWx0ZXIoY29tcGxldGUuY2FzZXMoaGlzcFByMTUpKSAlPiUgCiAgZ2dwbG90KCkrCiAgZ2VvbV9zZihhZXMoZmlsbCA9IHF1YWRfc2lnKSkrCiAgZ2d0aXRsZSgiTW9yYW4gQ2x1c3RlciBNYXAgLVxuUHJvcG9ydGlvbiBvZiBIaXNwYW5pYyBQb3B1bGF0aW9uIiwKICAgICAgICAgIHN1Yj0iIExvcyBBbmdlbGVzIENvdW50eSwgQ0EiKStsYWJzKGZpbGw9IlByb3BvcnRpb24gb2YgSGlzcGFuaWMiLCBjb2xvcj0iUHJvcG9ydGlvbiBvZiBIaXNwYW5pYyIpKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0xNCwgaGp1c3QgPSAwLjIpKSArdGhlbWVfdm9pZCgpKwogIHRoZW1lKAogICAgICAgIGxlZ2VuZC5rZXkud2lkdGggPSB1bml0KDAuNSwgImluIiksCiAgICAgICAgbGVnZW5kLmtleS5oZWlnaHQgPSB1bml0KDAuMywgImluIiksCiAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT04KSkKYGBgCgpgYGB7cix3YXJuaW5nPUZBTFNFfQpsb2NhbGk8LWxvY2FsbW9yYW4oTEFjb3VudHkkbmhibGFja3ByMTUsIAogICAgICAgICAgIGxpc3R3PUxhbHdrLCBwLmFkanVzdC5tZXRob2Q9ImZkciIpCkxBY291bnR5JGxvY2FscjwtbG9jYWxpWywxXQpMQWNvdW50eSRsb2NhbGw8LWxvY2FsaVssNV0KCkxBY291bnR5JHNycjwtc2NhbGUoTEFjb3VudHkkaGlzcFByMTUpCkxBY291bnR5JGxhZ19ycjwtbGFnLmxpc3R3KHZhcj1MQWNvdW50eSRzcnIsIHggPSBMYWx3aykKTEFjb3VudHkkcXVhZF9zaWcgPC0gTkEKTEFjb3VudHkkcXVhZF9zaWdbKExBY291bnR5JHNyciA+PSAwICYgTEFjb3VudHkkbGFnX3JyID49IDApICYgKExBY291bnR5JGxvY2FsbCA8PSAwLjA1KV0gPC0gIkgtSCIgI2hpZ2ggaGlnaApMQWNvdW50eSRxdWFkX3NpZ1soTEFjb3VudHkkc3JyIDw9IDAgJiBMQWNvdW50eSRsYWdfcnIgPD0gMCkgJiAoTEFjb3VudHkkbG9jYWxsIDw9IDAuMDUpXSA8LSAiTC1MIiAjbG93IGxvdwpMQWNvdW50eSRxdWFkX3NpZ1soTEFjb3VudHkkc3JyID49IDAgJiBMQWNvdW50eSRsYWdfcnIgPD0gMCkgJiAoTEFjb3VudHkkbG9jYWxsIDw9IDAuMDUpXSA8LSAiSC1MIiAjaGlnaCBsb3cKTEFjb3VudHkkcXVhZF9zaWdbKExBY291bnR5JHNyciA8PSAwICYgTEFjb3VudHkkbGFnX3JyID49IDApICYgKExBY291bnR5JGxvY2FsbCA8PSAwLjA1KV0gPC0gIkwtSCIgI2xvdyBoaWdoCgojV0UgQVNTSUdOIEEgIyBTZXQgdGhlIGJyZWFrcyBmb3IgdGhlIHRoZW1hdGljIG1hcCBjbGFzc2VzCmJyZWFrcyA8LSBzZXEoMSwgNSwgMSkKCiMgU2V0IHRoZSBjb3JyZXNwb25kaW5nIGxhYmVscyBmb3IgdGhlIHRoZW1hdGljIG1hcCBjbGFzc2VzCmxhYmVscyA8LSBjKCJIaWdoLUhpZ2giLCAiTG93LUxvdyIsICJIaWdoLUxvdyIsICJMb3ctSGlnaCIsICJOb3QgQ2x1c3RlcmVkIikKCiMgZmluZCBJbnRlcnZhbCAtIFRoaXMgaXMgbmVjZXNzYXJ5IGZvciBtYWtpbmcgYSBtYXAKbnAgPC0gZmluZEludGVydmFsKExBY291bnR5JHF1YWRfc2lnLCBicmVha3MpCgojIEFzc2lnbiBjb2xvcnMgdG8gZWFjaCBtYXAgY2xhc3MKY29sb3JzIDwtIGMoInJlZCIsICJibHVlIiwgImxpZ2h0cGluayIsICJza3libHVlMiIsICJ3aGl0ZSIpCgpibGsgPC0gTEFjb3VudHklPiUKICBnZ3Bsb3QoKSsKICBnZW9tX3NmKGFlcyhmaWxsID0gcXVhZF9zaWcpKSsKICBnZ3RpdGxlKCJNb3JhbiBDbHVzdGVyIE1hcCAtXG5Qcm9wb3J0aW9uIG9mIE5vbi1IaXNwYW5pYyBCbGFjayBQb3B1bGF0aW9uIiwKICAgICAgICAgIHN1Yj0iIExvcyBBbmdlbGVzIENvdW50eSwgQ0EiKStsYWJzKGZpbGw9Ik5vbi1IaXNwYW5pYyBCbGFjayIsIGNvbG9yPSJQcm9wb3J0aW9uIG9mIE5vbi1IaXNwYW5pYyBCbGFjayIpKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0xNCwgaGp1c3QgPSAwLjIpKSArdGhlbWVfdm9pZCgpKwogIHRoZW1lKAogICAgICAgIGxlZ2VuZC5rZXkud2lkdGggPSB1bml0KDAuNSwgImluIiksCiAgICAgICAgbGVnZW5kLmtleS5oZWlnaHQgPSB1bml0KDAuMywgImluIiksCiAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0pKQpncmlkLmFycmFuZ2UoaGlzLCBibGssIG5yb3cgPSAxKQpgYGAKCkhlcmUgaXMgYSBMSVNBIG1hcCBmb3IgY2x1c3RlcnMgb2YgaGlzcGFuaWMgYW5kIE5vbi1IaXNwYW5pYyBibGFjayBpbiBMb3MgQW5nZWxlcyBjb3VudHksIENBLCB3aGljaCBzaG93cyBhcmVhcyBvZiBjb25jZW50cmF0ZWQgKGNsdXN0ZXJlZCkgbG93IGluY29tZSBjbHVzdGVyaW5nIGluIHJlZCwgYW5kIGNvbmNlbnRyYXRlZCBoaWdoIGluY29tZSBpbiBibHVlLiAKClRoZSByZWQgYW5kIGJsdWUgYXJlYXMgYXJlIHNvLWNhbGxlZCAqY2x1c3RlcnMqLCBiZWNhdXNlIHRoZXkgYXJlIGFyZWFzIHdpdGggaGlnaGVyIChvciBsb3dlciwgZm9yIHRoZSBibHVlcykgdGhhbiBhdmVyYWdlIHByb3BvcnRpb24gb2YgdGhlIHJhY2VzLCBzdXJyb3VuZGVkIGJ5IGFyZWFzIHRoYXQgYWxzbyBoYXZlIGhpZ2hlciB0aGFuIGF2ZXJhZ2UgcmFjZSBwcm9wb3J0aW9uIGZvciB0aGUgdHdvIGdyb3Vwcy4gVGhlIHJlZCBjbHVzdGVycyBhcmUgc28gY2FsbGVkICJoaWdoLWhpZ2ggY2x1c3RlcnMiLCBsaWtld2lzZSB0aGUgYmx1ZSBhcmVhcyBhcmUgY2FsbGVkICJsb3ctbG93IGNsdXN0ZXJzIi4gCgpUaGVzZSBtYXBzIHN1Z2dlc3RzIHRoYXQgTEEgY291bnR5IGlzIGhpZ2hseSBzZWdyZWdhdGVkIGJ5IHJhY2UuCgpMaWtld2lzZSwgcG9zc2libGUgdmFsdWVzIGluY2x1ZGUgbGlnaHQgYmx1ZSBwb2x5Z29ucywgdGhlc2UgYXJlIGNhbGxlZCBsb3ctaGlnaCBvdXRsaWVycywgYmVjYXVzZSB0aGV5IGhhdmUgbG93IHByb3BvcnRpb24gb2YgdGhlIG5vbi1oaXNwYW5pYyBibGFjayBwb3B1bGF0aW9uLCBidXQgYXJlIGluIGEgaGlnaCBwcm9wb3J0aW9uIG9mIG90aGVyIHJhY2VzIHNwYXRpYWwgbmVpZ2hib3Job29kLgo=