Purpose

The purpose of this project was to see how the current public transit system is serving New York City’s disabled population, as well as other populations that need elevators, like young children and people over 60.

Introduction and Background

New York City is famous for its robust transit system as it is one of the few in the United States. Grime and strangeness of the place aside, or perhaps because of it, the subway is a cultural hub. It is full of cross-class interactions, performance art, graffiti, murals and the unpredictability of a large population. It is worth asking who is excluded from this space.

As fares rise and gaggles of police spring up, ready to gun down fare evaders, one cannot help but ask if the money could be spent differently.

Results

###################Subway Data Import
#subway stop data
raw_MTA_Subway <- read_csv("/Users/zolahaber/Desktop/Stuff & Things/School/Grad School/DUE Methods 1/part2/data/raw/MTA_Subway_Stations_20241209.csv")

#just the accessible stops
Accessible_MTA <- raw_MTA_Subway|>
  filter(ADA >= 1)

#making the stops plottable
sf_accessible_MTA <-st_as_sf(Accessible_MTA, coords=c("GTFS Longitude", "GTFS Latitude"))

## importing the shapefile for the subway lines
lines <- st_read("~/Desktop/Stuff & Things/School/Grad School/DUE Methods 1/part2/data/raw/geo/Subway Lines.geojson")
#Converting to sf
lines_sf <- st_as_sf(lines)

#importing the shapefile for streets
streets <- st_read("~/Desktop/Stuff & Things/School/Grad School/DUE Methods 1/part2/data/raw/geo/NYC Street Centerline (CSCL).geojson")
#converting  sf
streets_sf <- st_as_sf(streets)

## import borough shapefiles from NYC Open Data
boros <- st_read("~/Desktop/Stuff & Things/School/Grad School/DUE Methods 1/part2/data/raw/geo/Borough Boundaries.geojson")
######################Accessible Data Import

pl_2020 <- load_variables(2020, "pl", cache = T)

# load a list of all acs variables
acs_vars_2020 <- load_variables(2022, "acs5", cache = T)

#getting data for age
raw_age <- get_acs(geography = "tract", 
                   variables = c(M_under_5 = "B01001_003",
                                 F_under_5 = "B01001_027",
                                 M_60_61 = "B01001_018",
                                 M_62_64 = "B01001_019",
                                 M_65_66 = "B01001_020",
                                 M_67_69 = "B01001_021",
                                 M_70_74 = "B01001_022",
                                 M_75_79 = "B01001_023",
                                 M_80_84 = "B01001_024",
                                 M_85_plus = "B01001_025",
                                 F_60_61 = "B01001_042",
                                 F_62_64 = "B01001_043",
                                 F_65_66 = "B01001_044",
                                 F_67_69 = "B01001_045",
                                 F_70_74 = "B01001_046",
                                 F_75_79 = "B01001_047",
                                 F_80_84 = "B01001_048",
                                 F_85_plus = "B01001_049",
                                 sex_by_age_tot = "B01001_001"), 
                   state = "NY",
                   county = c("Kings","New York","Bronx","Queens","Richmond"),
                   geometry = T,
                   year = 2022, 
                   output = "wide")

#getting data for disability
raw_disability <- get_acs(geography = "tract", 
                          variables = c(disability_status_tot = "B18101_001",
                                        M_under_5 = "B18101_004",
                                        M_5_17 = "B18101_007",
                                        M_18_34 = "B18101_010",
                                        M_35_64 = "B18101_013",
                                        M_65_74 = "B18101_016",
                                        M_75_up = "B18101_019",
                                        F_under_5 = "B18101_023",
                                        F_5_17 = "B18101_026",
                                        F_18_34 = "B18101_029",
                                        F_35_64 = "B18101_032",
                                        F_65_74 = "B18101_035",
                                        F_75_up = "B18101_038"),
                          state = "NY",
                          county = c("Kings","New York","Bronx","Queens","Richmond"),
                          geometry = T,
                          year = 2022, 
                          output = "wide")

#making the data nice
age_data <- raw_age|>
  mutate(under_5 = (`M_under_5E` + `F_under_5E`),
         M_60_plus = (`M_60_61E` + `M_62_64E` + `M_65_66E` + `M_67_69E` + 
                        `M_70_74E`+ `M_75_79E` + `M_80_84E` + `M_85_plusE`),
         F_60_plus = (`F_60_61E` + `F_62_64E` + `F_65_66E` + `F_67_69E` + 
                        `F_70_74E` + `F_75_79E` + `F_80_84E` + `F_85_plusE`),
         senior_citizen = (`F_60_plus` + `M_60_plus`))|>
  rename(sex_by_age_tot = sex_by_age_totE)|>
  select(GEOID, NAME, under_5, M_60_plus, F_60_plus, 
         senior_citizen,sex_by_age_tot)|>
  mutate(percent_under_5 = under_5/sex_by_age_tot,
         percent_senior = senior_citizen/sex_by_age_tot)

#making disability data nice
disability_data <- raw_disability|>
  mutate(disabled = M_under_5E,M_5_17E,M_18_34E,M_35_64E,M_65_74E,M_75_upE,F_under_5E,
         F_5_17E,F_18_34E,F_35_64E,F_65_74E,F_75_upE)|>
  select(GEOID,NAME, disability_status_totE, disabled)|>
  mutate(percent_disabled = disabled/disability_status_totE)|>
  rename(disability_status_tot=disability_status_totE)

Fig. 1:

This map shows that there is a small disabled population spread through Queens, the Bronx and upper Manhattan recorded in 2020.There does not seem to be much correlation of accessible stations to pockets of disabled populations within Brooklyn. A flaw with this data is that it does not specify the type disability. The populations in this data could have mobility related disabilities, but they could also be related to sight or hearing.

####################### Graphing time

#Disability Map
ggplot(data = boros)+
  geom_sf(color = "#fff",
          lwd = 0) +
  theme_void() +
  geom_sf(data = disability_data, mapping = aes(fill = disabled), 
          color = "transparent")+
  scale_fill_distiller(breaks=c(0,25,50,75,100),
                       palette = "YlOrRd",
                       direction = 1,
                       na.value = "transparent",
                       name="Disabled Population") +
  geom_sf(data=lines_sf, colour="blue", linewidth=.25)+
  geom_point(data= Accessible_MTA, 
             aes(x=`GTFS Longitude`, y=`GTFS Latitude`), colour="blue", 
             fill="white",pch=21, size=.5, alpha=I(0.5))+
  labs(
    title = "Disabled Populations and Accessible Subway Stations 
    in NYC",
    caption = "Sources: MTA, American Community Survey, 2020")+
  geom_sf(data = boros |> filter(boro_name == "Brooklyn"),
          color = "black", fill = NA, lwd = .25)+
  geom_sf(data = boros |> filter(boro_name == "Manhattan"),
          color = "black", fill = NA, lwd = .25)+
  geom_sf(data = boros |> filter(boro_name == "Bronx"),
          color = "black", fill = NA, lwd = .25)+
  geom_sf(data = boros |> filter(boro_name == "Staten Island"),
          color = "black", fill = NA, lwd = .25)+
  geom_sf(data = boros |> filter(boro_name == "Queens"),
          color = "black", fill = NA, lwd = .25)

Fig. 2:

This map shows that as of 2020, the majority of the elderly population lives in Upper Manhattan, Riverdale Bronx, Selton Falls Park Bronx, North Queens, Long Island, Charleston Staten Island, along Freshkills Park Staten Island, East Brooklyn and the Upper West Side.I chose to look at populations of 60 and over because that is the age when people start to struggle climbing stairs.

#Over 60
ggplot()+
  geom_sf(color = "#fff",
          lwd = 0) +
  theme_void() +
  geom_sf(data = age_data, mapping = aes(fill = percent_senior), 
          color = "transparent")+
  scale_fill_distiller(breaks=c(0,.25,.50,.75,1.00),
                       palette = "YlGnBu",
                       direction = 1,
                       na.value = "transparent",
                       name="Percent Population Over 60") +
  geom_sf(data=lines_sf, colour="magenta4", linewidth=.25)+
  geom_point(data= Accessible_MTA, 
             aes(x=`GTFS Longitude`, y=`GTFS Latitude`), colour="magenta4", 
             fill="white",pch=21, size=.5, alpha=I(0.5))+
  labs(
    title = "Population Concentration of People Over 60 
    and Accessible Stations",
    caption = "Sources: MTA, American Community Survey, 2020")+
  geom_sf(data = boros |> filter(boro_name == "Brooklyn"),
          color = "black", fill = NA, lwd = .25)+
  geom_sf(data = boros |> filter(boro_name == "Manhattan"),
          color = "black", fill = NA, lwd = .25)+
  geom_sf(data = boros |> filter(boro_name == "Bronx"),
          color = "black", fill = NA, lwd = .25)+
  geom_sf(data = boros |> filter(boro_name == "Staten Island"),
          color = "black", fill = NA, lwd = .25)+
  geom_sf(data = boros |> filter(boro_name == "Queens"),
          color = "black", fill = NA, lwd = .25)

Fig. 3:

This map shows that as of 2020, the highest concentrations of children under 5 are living in Borough Park Brooklyn, Clinton Hill Brooklyn and Pelham Bay Bronx. I chose to look at this population because children under 5 often need strollers.

#under 5
ggplot()+
  geom_sf(color = "#fff",
          lwd = 0) +
  theme_void() +
  geom_sf(data = age_data, mapping = aes(fill = percent_under_5), 
          color = "transparent")+
  scale_fill_distiller(breaks=c(0,.25,.50,.75,1.00),
                       palette = "RdPu",
                       direction = 1,
                       na.value = "transparent",
                       name="Percentage of Children Under 5") +
  geom_sf(data=lines_sf, colour="darkgreen", linewidth=.25)+
  geom_point(data= Accessible_MTA, 
             aes(x=`GTFS Longitude`, y=`GTFS Latitude`), colour="darkgreen", 
             fill="white",pch=21, size=.5, alpha=I(0.5))+
  labs(
    title = "Population Concentration of Children Under 5
    and Accessible Stations",
    caption = "Sources: MTA, American Community Survey, 2020")+
  geom_sf(data = boros |> filter(boro_name == "Brooklyn"),
          color = "black", fill = NA, lwd = .25)+
  geom_sf(data = boros |> filter(boro_name == "Manhattan"),
          color = "black", fill = NA, lwd = .25)+
  geom_sf(data = boros |> filter(boro_name == "Bronx"),
          color = "black", fill = NA, lwd = .25)+
  geom_sf(data = boros |> filter(boro_name == "Staten Island"),
          color = "black", fill = NA, lwd = .25)+
  geom_sf(data = boros |> filter(boro_name == "Queens"),
          color = "black", fill = NA, lwd = .25)

Fig. 4

This map shows all accessible stations and has the lines colored to its coordinating trains. There are also streets added so that it is easier to tell where the stations are. The purpose of this map is to show how sparse the accessible stations are, driving home how limiting our current system is for not only those who are listed as disabled, but for senior citizens and small children.

#the map
ggplot(data = boros)+
  geom_sf(color = "#fff",
          fill= "cornsilk1",
          lwd = 0) +
  theme_void() +
  geom_sf(data=streets_sf, colour="wheat4", linewidth=.05)+
  geom_sf(data=red_line, colour="red", linewidth=.25)+
  geom_sf(data=green_line, colour="green4", linewidth=.25)+
  geom_sf(data=purple_line, colour="purple", linewidth=.25)+
  geom_sf(data=blue_line, colour="blue", linewidth=.25)+
  geom_sf(data=orange_line, colour="orange", linewidth=.25)+
  geom_sf(data=light_green_line, colour="lightgreen", linewidth=.25)+
  geom_sf(data=brown_line, colour="brown", linewidth=.25)+
  geom_sf(data=grey_line, colour="grey", linewidth=.25)+
  geom_sf(data=yellow_line, colour="gold", linewidth=.25)+
  geom_point(data= Accessible_MTA, 
             aes(x=`GTFS Longitude`, y=`GTFS Latitude`), colour="black", 
             fill="white",pch=21, size=.5, alpha=I(0.5)) +
  labs(
    title = "Accessible Subway Stations in NYC",
    caption = "Source: MTA")+ 
  geom_sf(data = boros |> filter(boro_name == "Brooklyn"), 
          color = "black", fill = NA, lwd = .25)+
  geom_sf(data = boros |> filter(boro_name == "Manhattan"), 
          color = "black", fill = NA, lwd = .25)+
  geom_sf(data = boros |> filter(boro_name == "Bronx"), 
          color = "black", fill = NA, lwd = .25)+
  geom_sf(data = boros |> filter(boro_name == "Staten Island"), 
          color = "black", fill = NA, lwd = .25)+
  geom_sf(data = boros |> filter(boro_name == "Queens"), 
          color = "black", fill = NA, lwd = .25)

Fig. 5

This table shows the names of ADA accessible stations, the boroughs they are within, the trains you can access, as well as the ADA notes which shows the stations that are only accessible in one direction.

#making a table
user_friendly <- Accessible_MTA|>
  select("Stop Name","Borough","Daytime Routes","ADA Notes")

kable(user_friendly, format = "html") %>%
  kable_styling(bootstrap_options = c("striped", "hover"), full_width = F)
Stop Name Borough Daytime Routes ADA Notes
Astoria Blvd Q N W NA
57 St-7 Av M N Q R W NA
49 St M N R W Uptown only
Times Sq-42 St M N Q R W NA
34 St-Herald Sq M N Q R W NA
14 St-Union Sq M N Q R W NA
Cortlandt St M R W NA
Jay St-MetroTech Bk R NA
DeKalb Av Bk B Q R NA
Atlantic Av-Barclays Ctr Bk D N R NA
59 St Bk N R NA
86 St Bk R NA
Atlantic Av-Barclays Ctr Bk B Q NA
Prospect Park Bk B Q S NA
Avenue H Bk Q NA
Kings Hwy Bk B Q NA
Coney Island-Stillwell Av Bk D F N Q NA
62 St Bk D NA
Bay Pkwy Bk D NA
8 Av Bk N NA
New Utrecht Av Bk N NA
Flushing Av Bk M J NA
Marcy Av Bk M J Z NA
Chambers St M J Z NA
Fulton St M J Z NA
Middle Village-Metropolitan Av Q M NA
Myrtle-Wyckoff Avs Bk M NA
8 Av M L NA
6 Av M L NA
14 St-Union Sq M L NA
1 Av M L NA
Bedford Av Bk L NA
Lorimer St Bk L NA
Grand St Bk L NA
Myrtle-Wyckoff Avs Bk L NA
Wilson Av Bk L Manhattan-bound only
Livonia Av Bk L NA
Canarsie-Rockaway Pkwy Bk L NA
Franklin Av Bk S NA
Park Pl Bk S NA
Inwood-207 St M A NA
181 St M A NA
175 St M A NA
168 St M A C NA
125 St M A C B D NA
59 St-Columbus Circle M A C B D NA
50 St M C E Downtown only
42 St-Port Authority Bus Terminal M A C E NA
34 St-Penn Station M A C E NA
14 St M A C E NA
W 4 St-Wash Sq M A C E NA
W 4 St-Wash Sq M B D F M NA
World Trade Center M E NA
Fulton St M A C NA
Jay St-MetroTech Bk A C F NA
Franklin Av Bk C NA
Utica Av Bk A C NA
Euclid Av Bk A C NA
Ozone Park-Lefferts Blvd Q A NA
Aqueduct Racetrack Q A NA
Howard Beach-JFK Airport Q A NA
Rockaway Park-Beach 116 St Q A S NA
Beach 67 St Q A NA
Far Rockaway-Mott Av Q A NA
Bedford Park Blvd Bx B D NA
Kingsbridge Rd Bx B D NA
Tremont Av Bx B D NA
161 St-Yankee Stadium Bx B D NA
21 St-Queensbridge Q F NA
Roosevelt Island M F NA
Lexington Av/63 St M F Q NA
47-50 Sts-Rockefeller Ctr M B D F M NA
34 St-Herald Sq M B D F M NA
14 St M F M Uptown only
Broadway-Lafayette St M B D F M NA
7 Av Bk F G NA
Church Av Bk F G NA
Jamaica-179 St Q F NA
Kew Gardens-Union Tpke Q E F NA
Forest Hills-71 Av Q E F M R NA
Jackson Hts-Roosevelt Av Q E F M R NA
Queens Plaza Q E M R NA
Court Sq-23 St Q E M Manhattan-bound only
Lexington Av/53 St M E M NA
Jamaica Center-Parsons/Archer Q E J Z NA
Sutphin Blvd-Archer Av-JFK Airport Q E J Z NA
Jamaica-Van Wyck Q E NA
Court Sq Q G NA
Greenpoint Av Bk G NA
Metropolitan Av Bk G NA
231 St Bx 1 NA
Dyckman St M 1 NA
96 St M 1 2 3 NA
72 St M 1 2 3 NA
66 St-Lincoln Center M 1 NA
59 St-Columbus Circle M 1 NA
Times Sq-42 St M 1 2 3 NA
34 St-Penn Station M 1 2 3 NA
Chambers St M 1 2 3 NA
WTC Cortlandt M 1 NA
South Ferry M 1 NA
Fulton St M 2 3 NA
Borough Hall Bk 2 3 NA
Hoyt St Bk 2 3 Outbound only
Atlantic Av-Barclays Ctr Bk 2 3 4 5 NA
Eastern Pkwy-Brooklyn Museum Bk 2 3 NA
Crown Hts-Utica Av Bk 3 4 NA
Church Av Bk 2 5 NA
Flatbush Av-Brooklyn College Bk 2 5 NA
Pelham Bay Park Bx 6 NA
Hunts Point Av Bx 6 NA
E 149 St Bx 6 NA
Fordham Rd Bx 4 NA
170 St Bx 4 NA
161 St-Yankee Stadium Bx 4 NA
125 St M 4 5 6 NA
86 St M 4 5 6 Uptown local only
51 St M 6 NA
Grand Central-42 St M 4 5 6 NA
28 St M 6 Downtown only
23 St M 6 NA
Bleecker St M 6 NA
Canal St M 6 NA
Brooklyn Bridge-City Hall M 4 5 6 NA
Fulton St M 4 5 NA
Bowling Green M 4 5 NA
Borough Hall Bk 4 5 Manhattan-bound only
233 St Bx 2 5 NA
Gun Hill Rd Bx 2 5 NA
Pelham Pkwy Bx 2 5 NA
E 180 St Bx 2 5 NA
Simpson St Bx 2 5 NA
3 Av-149 St Bx 2 5 NA
135 St M 2 3 NA
Gun Hill Rd Bx 5 NA
Flushing-Main St Q 7 NA
Junction Blvd Q 7 NA
74 St-Broadway Q 7 NA
61 St-Woodside Q 7 NA
Court Sq Q 7 NA
Grand Central-42 St M 7 NA
Times Sq-42 St M 7 NA
Times Sq-42 St M S NA
Grand Central-42 St M S NA
34 St-Hudson Yards M 7 NA
96 St M Q NA
86 St M Q NA
72 St M Q NA
St George SI SIR NA
Dongan Hills SI SIR NA
New Dorp SI SIR NA
Great Kills SI SIR NA
Tottenville SI SIR NA
Arthur Kill SI SIR NA

Next Steps

Next steps for this project would be to do further research on the pockets of disabled populations, why they are so concentrated and how their needs could be better met by the New York transit system. I would also want to look deeper into the topic of disability and find more specific data on the concentrations of types of disability. I would then want to map the accommodations, both where they are and where they are needed. If my skills were more advanced I would ideally like to make a google maps-type of interactive map where those who need elevators could plan trips more easily, taking into account stations where it is only accessible in one direction as well as stations that are only accessible for transfers within the station.

Appendix

My data came from from the American Community Survey, the MTA and NYC OpenData. The American Community Survey provided data about the disabled populations of NYC, as well as the elderly and under five populations. The MTA supplied the data about the subway stations, including which ones were accessible for which trains. NYC OpenData provided the shapefiles for the streets as well as for the subway lines

LS0tCnRpdGxlOiAiQWNjZXNzaWJpbGl0eSBhbmQgdGhlIE1UQSIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKIyBQdXJwb3NlClRoZSBwdXJwb3NlIG9mIHRoaXMgcHJvamVjdCB3YXMgdG8gc2VlIGhvdyB0aGUgY3VycmVudCBwdWJsaWMgdHJhbnNpdCBzeXN0ZW0gaXMgc2VydmluZyBOZXcgWW9yayBDaXR5J3MgZGlzYWJsZWQgcG9wdWxhdGlvbiwgYXMgd2VsbCBhcyBvdGhlciBwb3B1bGF0aW9ucyB0aGF0IG5lZWQgZWxldmF0b3JzLCBsaWtlIHlvdW5nIGNoaWxkcmVuIGFuZCBwZW9wbGUgb3ZlciA2MC4KCiMgSW50cm9kdWN0aW9uIGFuZCBCYWNrZ3JvdW5kCk5ldyBZb3JrIENpdHkgaXMgZmFtb3VzIGZvciBpdHMgcm9idXN0IHRyYW5zaXQgc3lzdGVtIGFzIGl0IGlzIG9uZSBvZiB0aGUgZmV3IGluIHRoZSBVbml0ZWQgU3RhdGVzLiBHcmltZSBhbmQgc3RyYW5nZW5lc3Mgb2YgdGhlIHBsYWNlIGFzaWRlLCBvciBwZXJoYXBzIGJlY2F1c2Ugb2YgaXQsIHRoZSBzdWJ3YXkgaXMgYSBjdWx0dXJhbCBodWIuIEl0IGlzIGZ1bGwgb2YgY3Jvc3MtY2xhc3MgaW50ZXJhY3Rpb25zLCBwZXJmb3JtYW5jZSBhcnQsIGdyYWZmaXRpLCBtdXJhbHMgYW5kIHRoZSB1bnByZWRpY3RhYmlsaXR5IG9mIGEgbGFyZ2UgcG9wdWxhdGlvbi4gSXQgaXMgd29ydGggYXNraW5nIHdobyBpcyBleGNsdWRlZCBmcm9tIHRoaXMgc3BhY2UuIAoKQXMgZmFyZXMgcmlzZSBhbmQgZ2FnZ2xlcyBvZiBwb2xpY2Ugc3ByaW5nIHVwLCByZWFkeSB0byBndW4gZG93biBmYXJlIGV2YWRlcnMsIG9uZSBjYW5ub3QgaGVscCBidXQgYXNrIGlmIHRoZSBtb25leSBjb3VsZCBiZSBzcGVudCBkaWZmZXJlbnRseS4gCgojIFJlc3VsdHMKCmBgYHtyLCBlY2hvPUZBTFNFfQpsaWJyYXJ5KHNmKQpsaWJyYXJ5KHJlYWRyKQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoZ2dzcGF0aWFsKQpsaWJyYXJ5KG1hcHMpCmxpYnJhcnkoZ2dyZXBlbCkKbGlicmFyeShzY2FsZXMpCmBgYAoKYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHJlc3VsdHMgPSdoaWRlJ30KIyMjIyMjIyMjIyMjIyMjIyMjI1N1YndheSBEYXRhIEltcG9ydAojc3Vid2F5IHN0b3AgZGF0YQpyYXdfTVRBX1N1YndheSA8LSByZWFkX2NzdigiL1VzZXJzL3pvbGFoYWJlci9EZXNrdG9wL1N0dWZmICYgVGhpbmdzL1NjaG9vbC9HcmFkIFNjaG9vbC9EVUUgTWV0aG9kcyAxL3BhcnQyL2RhdGEvcmF3L01UQV9TdWJ3YXlfU3RhdGlvbnNfMjAyNDEyMDkuY3N2IikKCiNqdXN0IHRoZSBhY2Nlc3NpYmxlIHN0b3BzCkFjY2Vzc2libGVfTVRBIDwtIHJhd19NVEFfU3Vid2F5fD4KICBmaWx0ZXIoQURBID49IDEpCgojbWFraW5nIHRoZSBzdG9wcyBwbG90dGFibGUKc2ZfYWNjZXNzaWJsZV9NVEEgPC1zdF9hc19zZihBY2Nlc3NpYmxlX01UQSwgY29vcmRzPWMoIkdURlMgTG9uZ2l0dWRlIiwgIkdURlMgTGF0aXR1ZGUiKSkKCiMjIGltcG9ydGluZyB0aGUgc2hhcGVmaWxlIGZvciB0aGUgc3Vid2F5IGxpbmVzCmxpbmVzIDwtIHN0X3JlYWQoIn4vRGVza3RvcC9TdHVmZiAmIFRoaW5ncy9TY2hvb2wvR3JhZCBTY2hvb2wvRFVFIE1ldGhvZHMgMS9wYXJ0Mi9kYXRhL3Jhdy9nZW8vU3Vid2F5IExpbmVzLmdlb2pzb24iKQojQ29udmVydGluZyB0byBzZgpsaW5lc19zZiA8LSBzdF9hc19zZihsaW5lcykKCiNpbXBvcnRpbmcgdGhlIHNoYXBlZmlsZSBmb3Igc3RyZWV0cwpzdHJlZXRzIDwtIHN0X3JlYWQoIn4vRGVza3RvcC9TdHVmZiAmIFRoaW5ncy9TY2hvb2wvR3JhZCBTY2hvb2wvRFVFIE1ldGhvZHMgMS9wYXJ0Mi9kYXRhL3Jhdy9nZW8vTllDIFN0cmVldCBDZW50ZXJsaW5lIChDU0NMKS5nZW9qc29uIikKI2NvbnZlcnRpbmcgIHNmCnN0cmVldHNfc2YgPC0gc3RfYXNfc2Yoc3RyZWV0cykKCiMjIGltcG9ydCBib3JvdWdoIHNoYXBlZmlsZXMgZnJvbSBOWUMgT3BlbiBEYXRhCmJvcm9zIDwtIHN0X3JlYWQoIn4vRGVza3RvcC9TdHVmZiAmIFRoaW5ncy9TY2hvb2wvR3JhZCBTY2hvb2wvRFVFIE1ldGhvZHMgMS9wYXJ0Mi9kYXRhL3Jhdy9nZW8vQm9yb3VnaCBCb3VuZGFyaWVzLmdlb2pzb24iKQpgYGAKCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCByZXN1bHRzID0naGlkZSd9CiMjIyMjIyMjIyMjIyMjIyMjIyMjIyNBY2Nlc3NpYmxlIERhdGEgSW1wb3J0CgpwbF8yMDIwIDwtIGxvYWRfdmFyaWFibGVzKDIwMjAsICJwbCIsIGNhY2hlID0gVCkKCiMgbG9hZCBhIGxpc3Qgb2YgYWxsIGFjcyB2YXJpYWJsZXMKYWNzX3ZhcnNfMjAyMCA8LSBsb2FkX3ZhcmlhYmxlcygyMDIyLCAiYWNzNSIsIGNhY2hlID0gVCkKCiNnZXR0aW5nIGRhdGEgZm9yIGFnZQpyYXdfYWdlIDwtIGdldF9hY3MoZ2VvZ3JhcGh5ID0gInRyYWN0IiwgCiAgICAgICAgICAgICAgICAgICB2YXJpYWJsZXMgPSBjKE1fdW5kZXJfNSA9ICJCMDEwMDFfMDAzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRl91bmRlcl81ID0gIkIwMTAwMV8wMjciLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNXzYwXzYxID0gIkIwMTAwMV8wMTgiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNXzYyXzY0ID0gIkIwMTAwMV8wMTkiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNXzY1XzY2ID0gIkIwMTAwMV8wMjAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNXzY3XzY5ID0gIkIwMTAwMV8wMjEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNXzcwXzc0ID0gIkIwMTAwMV8wMjIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNXzc1Xzc5ID0gIkIwMTAwMV8wMjMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNXzgwXzg0ID0gIkIwMTAwMV8wMjQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNXzg1X3BsdXMgPSAiQjAxMDAxXzAyNSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZfNjBfNjEgPSAiQjAxMDAxXzA0MiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZfNjJfNjQgPSAiQjAxMDAxXzA0MyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZfNjVfNjYgPSAiQjAxMDAxXzA0NCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZfNjdfNjkgPSAiQjAxMDAxXzA0NSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZfNzBfNzQgPSAiQjAxMDAxXzA0NiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZfNzVfNzkgPSAiQjAxMDAxXzA0NyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZfODBfODQgPSAiQjAxMDAxXzA0OCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZfODVfcGx1cyA9ICJCMDEwMDFfMDQ5IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V4X2J5X2FnZV90b3QgPSAiQjAxMDAxXzAwMSIpLCAKICAgICAgICAgICAgICAgICAgIHN0YXRlID0gIk5ZIiwKICAgICAgICAgICAgICAgICAgIGNvdW50eSA9IGMoIktpbmdzIiwiTmV3IFlvcmsiLCJCcm9ueCIsIlF1ZWVucyIsIlJpY2htb25kIiksCiAgICAgICAgICAgICAgICAgICBnZW9tZXRyeSA9IFQsCiAgICAgICAgICAgICAgICAgICB5ZWFyID0gMjAyMiwgCiAgICAgICAgICAgICAgICAgICBvdXRwdXQgPSAid2lkZSIpCgojZ2V0dGluZyBkYXRhIGZvciBkaXNhYmlsaXR5CnJhd19kaXNhYmlsaXR5IDwtIGdldF9hY3MoZ2VvZ3JhcGh5ID0gInRyYWN0IiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyaWFibGVzID0gYyhkaXNhYmlsaXR5X3N0YXR1c190b3QgPSAiQjE4MTAxXzAwMSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNX3VuZGVyXzUgPSAiQjE4MTAxXzAwNCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNXzVfMTcgPSAiQjE4MTAxXzAwNyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNXzE4XzM0ID0gIkIxODEwMV8wMTAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTV8zNV82NCA9ICJCMTgxMDFfMDEzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1fNjVfNzQgPSAiQjE4MTAxXzAxNiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNXzc1X3VwID0gIkIxODEwMV8wMTkiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRl91bmRlcl81ID0gIkIxODEwMV8wMjMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRl81XzE3ID0gIkIxODEwMV8wMjYiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRl8xOF8zNCA9ICJCMTgxMDFfMDI5IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZfMzVfNjQgPSAiQjE4MTAxXzAzMiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGXzY1Xzc0ID0gIkIxODEwMV8wMzUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRl83NV91cCA9ICJCMTgxMDFfMDM4IiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdGUgPSAiTlkiLAogICAgICAgICAgICAgICAgICAgICAgICAgIGNvdW50eSA9IGMoIktpbmdzIiwiTmV3IFlvcmsiLCJCcm9ueCIsIlF1ZWVucyIsIlJpY2htb25kIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgZ2VvbWV0cnkgPSBULAogICAgICAgICAgICAgICAgICAgICAgICAgIHllYXIgPSAyMDIyLCAKICAgICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXQgPSAid2lkZSIpCgojbWFraW5nIHRoZSBkYXRhIG5pY2UKYWdlX2RhdGEgPC0gcmF3X2FnZXw+CiAgbXV0YXRlKHVuZGVyXzUgPSAoYE1fdW5kZXJfNUVgICsgYEZfdW5kZXJfNUVgKSwKICAgICAgICAgTV82MF9wbHVzID0gKGBNXzYwXzYxRWAgKyBgTV82Ml82NEVgICsgYE1fNjVfNjZFYCArIGBNXzY3XzY5RWAgKyAKICAgICAgICAgICAgICAgICAgICAgICAgYE1fNzBfNzRFYCsgYE1fNzVfNzlFYCArIGBNXzgwXzg0RWAgKyBgTV84NV9wbHVzRWApLAogICAgICAgICBGXzYwX3BsdXMgPSAoYEZfNjBfNjFFYCArIGBGXzYyXzY0RWAgKyBgRl82NV82NkVgICsgYEZfNjdfNjlFYCArIAogICAgICAgICAgICAgICAgICAgICAgICBgRl83MF83NEVgICsgYEZfNzVfNzlFYCArIGBGXzgwXzg0RWAgKyBgRl84NV9wbHVzRWApLAogICAgICAgICBzZW5pb3JfY2l0aXplbiA9IChgRl82MF9wbHVzYCArIGBNXzYwX3BsdXNgKSl8PgogIHJlbmFtZShzZXhfYnlfYWdlX3RvdCA9IHNleF9ieV9hZ2VfdG90RSl8PgogIHNlbGVjdChHRU9JRCwgTkFNRSwgdW5kZXJfNSwgTV82MF9wbHVzLCBGXzYwX3BsdXMsIAogICAgICAgICBzZW5pb3JfY2l0aXplbixzZXhfYnlfYWdlX3RvdCl8PgogIG11dGF0ZShwZXJjZW50X3VuZGVyXzUgPSB1bmRlcl81L3NleF9ieV9hZ2VfdG90LAogICAgICAgICBwZXJjZW50X3NlbmlvciA9IHNlbmlvcl9jaXRpemVuL3NleF9ieV9hZ2VfdG90KQoKI21ha2luZyBkaXNhYmlsaXR5IGRhdGEgbmljZQpkaXNhYmlsaXR5X2RhdGEgPC0gcmF3X2Rpc2FiaWxpdHl8PgogIG11dGF0ZShkaXNhYmxlZCA9IE1fdW5kZXJfNUUsTV81XzE3RSxNXzE4XzM0RSxNXzM1XzY0RSxNXzY1Xzc0RSxNXzc1X3VwRSxGX3VuZGVyXzVFLAogICAgICAgICBGXzVfMTdFLEZfMThfMzRFLEZfMzVfNjRFLEZfNjVfNzRFLEZfNzVfdXBFKXw+CiAgc2VsZWN0KEdFT0lELE5BTUUsIGRpc2FiaWxpdHlfc3RhdHVzX3RvdEUsIGRpc2FibGVkKXw+CiAgbXV0YXRlKHBlcmNlbnRfZGlzYWJsZWQgPSBkaXNhYmxlZC9kaXNhYmlsaXR5X3N0YXR1c190b3RFKXw+CiAgcmVuYW1lKGRpc2FiaWxpdHlfc3RhdHVzX3RvdD1kaXNhYmlsaXR5X3N0YXR1c190b3RFKQpgYGAKRmlnLiAxOgoKVGhpcyBtYXAgc2hvd3MgdGhhdCB0aGVyZSBpcyBhIHNtYWxsIGRpc2FibGVkIHBvcHVsYXRpb24gc3ByZWFkIHRocm91Z2ggUXVlZW5zLCB0aGUgQnJvbnggYW5kIHVwcGVyIE1hbmhhdHRhbiByZWNvcmRlZCBpbiAyMDIwLlRoZXJlIGRvZXMgbm90IHNlZW0gdG8gYmUgbXVjaCBjb3JyZWxhdGlvbiBvZiBhY2Nlc3NpYmxlIHN0YXRpb25zIHRvIHBvY2tldHMgb2YgZGlzYWJsZWQgcG9wdWxhdGlvbnMgd2l0aGluIEJyb29rbHluLiBBIGZsYXcgd2l0aCB0aGlzIGRhdGEgaXMgdGhhdCBpdCBkb2VzIG5vdCBzcGVjaWZ5IHRoZSB0eXBlIGRpc2FiaWxpdHkuIFRoZSBwb3B1bGF0aW9ucyBpbiB0aGlzIGRhdGEgY291bGQgaGF2ZSBtb2JpbGl0eSByZWxhdGVkIGRpc2FiaWxpdGllcywgYnV0IHRoZXkgY291bGQgYWxzbyBiZSByZWxhdGVkIHRvIHNpZ2h0IG9yIGhlYXJpbmcuIApgYGB7ciwgbWVzc2FnZT1GQUxTRSwgcmVzdWx0cyA9J2hpZGUnfQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyBHcmFwaGluZyB0aW1lCgojRGlzYWJpbGl0eSBNYXAKZ2dwbG90KGRhdGEgPSBib3JvcykrCiAgZ2VvbV9zZihjb2xvciA9ICIjZmZmIiwKICAgICAgICAgIGx3ZCA9IDApICsKICB0aGVtZV92b2lkKCkgKwogIGdlb21fc2YoZGF0YSA9IGRpc2FiaWxpdHlfZGF0YSwgbWFwcGluZyA9IGFlcyhmaWxsID0gZGlzYWJsZWQpLCAKICAgICAgICAgIGNvbG9yID0gInRyYW5zcGFyZW50IikrCiAgc2NhbGVfZmlsbF9kaXN0aWxsZXIoYnJlYWtzPWMoMCwyNSw1MCw3NSwxMDApLAogICAgICAgICAgICAgICAgICAgICAgIHBhbGV0dGUgPSAiWWxPclJkIiwKICAgICAgICAgICAgICAgICAgICAgICBkaXJlY3Rpb24gPSAxLAogICAgICAgICAgICAgICAgICAgICAgIG5hLnZhbHVlID0gInRyYW5zcGFyZW50IiwKICAgICAgICAgICAgICAgICAgICAgICBuYW1lPSJEaXNhYmxlZCBQb3B1bGF0aW9uIikgKwogIGdlb21fc2YoZGF0YT1saW5lc19zZiwgY29sb3VyPSJibHVlIiwgbGluZXdpZHRoPS4yNSkrCiAgZ2VvbV9wb2ludChkYXRhPSBBY2Nlc3NpYmxlX01UQSwgCiAgICAgICAgICAgICBhZXMoeD1gR1RGUyBMb25naXR1ZGVgLCB5PWBHVEZTIExhdGl0dWRlYCksIGNvbG91cj0iYmx1ZSIsIAogICAgICAgICAgICAgZmlsbD0id2hpdGUiLHBjaD0yMSwgc2l6ZT0uNSwgYWxwaGE9SSgwLjUpKSsKICBsYWJzKAogICAgdGl0bGUgPSAiRGlzYWJsZWQgUG9wdWxhdGlvbnMgYW5kIEFjY2Vzc2libGUgU3Vid2F5IFN0YXRpb25zIAogICAgaW4gTllDIiwKICAgIGNhcHRpb24gPSAiU291cmNlczogTVRBLCBBbWVyaWNhbiBDb21tdW5pdHkgU3VydmV5LCAyMDIwIikrCiAgZ2VvbV9zZihkYXRhID0gYm9yb3MgfD4gZmlsdGVyKGJvcm9fbmFtZSA9PSAiQnJvb2tseW4iKSwKICAgICAgICAgIGNvbG9yID0gImJsYWNrIiwgZmlsbCA9IE5BLCBsd2QgPSAuMjUpKwogIGdlb21fc2YoZGF0YSA9IGJvcm9zIHw+IGZpbHRlcihib3JvX25hbWUgPT0gIk1hbmhhdHRhbiIpLAogICAgICAgICAgY29sb3IgPSAiYmxhY2siLCBmaWxsID0gTkEsIGx3ZCA9IC4yNSkrCiAgZ2VvbV9zZihkYXRhID0gYm9yb3MgfD4gZmlsdGVyKGJvcm9fbmFtZSA9PSAiQnJvbngiKSwKICAgICAgICAgIGNvbG9yID0gImJsYWNrIiwgZmlsbCA9IE5BLCBsd2QgPSAuMjUpKwogIGdlb21fc2YoZGF0YSA9IGJvcm9zIHw+IGZpbHRlcihib3JvX25hbWUgPT0gIlN0YXRlbiBJc2xhbmQiKSwKICAgICAgICAgIGNvbG9yID0gImJsYWNrIiwgZmlsbCA9IE5BLCBsd2QgPSAuMjUpKwogIGdlb21fc2YoZGF0YSA9IGJvcm9zIHw+IGZpbHRlcihib3JvX25hbWUgPT0gIlF1ZWVucyIpLAogICAgICAgICAgY29sb3IgPSAiYmxhY2siLCBmaWxsID0gTkEsIGx3ZCA9IC4yNSkKYGBgCkZpZy4gMjoKClRoaXMgbWFwIHNob3dzIHRoYXQgYXMgb2YgMjAyMCwgdGhlIG1ham9yaXR5IG9mIHRoZSBlbGRlcmx5IHBvcHVsYXRpb24gbGl2ZXMgaW4gVXBwZXIgTWFuaGF0dGFuLCBSaXZlcmRhbGUgQnJvbngsIFNlbHRvbiBGYWxscyBQYXJrIEJyb254LCBOb3J0aCBRdWVlbnMsIExvbmcgSXNsYW5kLCBDaGFybGVzdG9uIFN0YXRlbiBJc2xhbmQsIGFsb25nIEZyZXNoa2lsbHMgUGFyayBTdGF0ZW4gSXNsYW5kLCBFYXN0IEJyb29rbHluIGFuZCB0aGUgVXBwZXIgV2VzdCBTaWRlLkkgY2hvc2UgdG8gbG9vayBhdCBwb3B1bGF0aW9ucyBvZiA2MCBhbmQgb3ZlciBiZWNhdXNlIHRoYXQgaXMgdGhlIGFnZSB3aGVuIHBlb3BsZSBzdGFydCB0byBzdHJ1Z2dsZSBjbGltYmluZyBzdGFpcnMuIApgYGB7ciwgbWVzc2FnZT1GQUxTRSwgcmVzdWx0cyA9J2hpZGUnfQojT3ZlciA2MApnZ3Bsb3QoKSsKICBnZW9tX3NmKGNvbG9yID0gIiNmZmYiLAogICAgICAgICAgbHdkID0gMCkgKwogIHRoZW1lX3ZvaWQoKSArCiAgZ2VvbV9zZihkYXRhID0gYWdlX2RhdGEsIG1hcHBpbmcgPSBhZXMoZmlsbCA9IHBlcmNlbnRfc2VuaW9yKSwgCiAgICAgICAgICBjb2xvciA9ICJ0cmFuc3BhcmVudCIpKwogIHNjYWxlX2ZpbGxfZGlzdGlsbGVyKGJyZWFrcz1jKDAsLjI1LC41MCwuNzUsMS4wMCksCiAgICAgICAgICAgICAgICAgICAgICAgcGFsZXR0ZSA9ICJZbEduQnUiLAogICAgICAgICAgICAgICAgICAgICAgIGRpcmVjdGlvbiA9IDEsCiAgICAgICAgICAgICAgICAgICAgICAgbmEudmFsdWUgPSAidHJhbnNwYXJlbnQiLAogICAgICAgICAgICAgICAgICAgICAgIG5hbWU9IlBlcmNlbnQgUG9wdWxhdGlvbiBPdmVyIDYwIikgKwogIGdlb21fc2YoZGF0YT1saW5lc19zZiwgY29sb3VyPSJtYWdlbnRhNCIsIGxpbmV3aWR0aD0uMjUpKwogIGdlb21fcG9pbnQoZGF0YT0gQWNjZXNzaWJsZV9NVEEsIAogICAgICAgICAgICAgYWVzKHg9YEdURlMgTG9uZ2l0dWRlYCwgeT1gR1RGUyBMYXRpdHVkZWApLCBjb2xvdXI9Im1hZ2VudGE0IiwgCiAgICAgICAgICAgICBmaWxsPSJ3aGl0ZSIscGNoPTIxLCBzaXplPS41LCBhbHBoYT1JKDAuNSkpKwogIGxhYnMoCiAgICB0aXRsZSA9ICJQb3B1bGF0aW9uIENvbmNlbnRyYXRpb24gb2YgUGVvcGxlIE92ZXIgNjAgCiAgICBhbmQgQWNjZXNzaWJsZSBTdGF0aW9ucyIsCiAgICBjYXB0aW9uID0gIlNvdXJjZXM6IE1UQSwgQW1lcmljYW4gQ29tbXVuaXR5IFN1cnZleSwgMjAyMCIpKwogIGdlb21fc2YoZGF0YSA9IGJvcm9zIHw+IGZpbHRlcihib3JvX25hbWUgPT0gIkJyb29rbHluIiksCiAgICAgICAgICBjb2xvciA9ICJibGFjayIsIGZpbGwgPSBOQSwgbHdkID0gLjI1KSsKICBnZW9tX3NmKGRhdGEgPSBib3JvcyB8PiBmaWx0ZXIoYm9yb19uYW1lID09ICJNYW5oYXR0YW4iKSwKICAgICAgICAgIGNvbG9yID0gImJsYWNrIiwgZmlsbCA9IE5BLCBsd2QgPSAuMjUpKwogIGdlb21fc2YoZGF0YSA9IGJvcm9zIHw+IGZpbHRlcihib3JvX25hbWUgPT0gIkJyb254IiksCiAgICAgICAgICBjb2xvciA9ICJibGFjayIsIGZpbGwgPSBOQSwgbHdkID0gLjI1KSsKICBnZW9tX3NmKGRhdGEgPSBib3JvcyB8PiBmaWx0ZXIoYm9yb19uYW1lID09ICJTdGF0ZW4gSXNsYW5kIiksCiAgICAgICAgICBjb2xvciA9ICJibGFjayIsIGZpbGwgPSBOQSwgbHdkID0gLjI1KSsKICBnZW9tX3NmKGRhdGEgPSBib3JvcyB8PiBmaWx0ZXIoYm9yb19uYW1lID09ICJRdWVlbnMiKSwKICAgICAgICAgIGNvbG9yID0gImJsYWNrIiwgZmlsbCA9IE5BLCBsd2QgPSAuMjUpCgpgYGAKRmlnLiAzOgoKVGhpcyBtYXAgc2hvd3MgdGhhdCBhcyBvZiAyMDIwLCB0aGUgaGlnaGVzdCBjb25jZW50cmF0aW9ucyBvZiBjaGlsZHJlbiB1bmRlciA1IGFyZSBsaXZpbmcgaW4gQm9yb3VnaCBQYXJrIEJyb29rbHluLCBDbGludG9uIEhpbGwgQnJvb2tseW4gYW5kIFBlbGhhbSBCYXkgQnJvbnguIEkgY2hvc2UgdG8gbG9vayBhdCB0aGlzIHBvcHVsYXRpb24gYmVjYXVzZSBjaGlsZHJlbiB1bmRlciA1IG9mdGVuIG5lZWQgc3Ryb2xsZXJzLiAKYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHJlc3VsdHMgPSdoaWRlJ30KI3VuZGVyIDUKZ2dwbG90KCkrCiAgZ2VvbV9zZihjb2xvciA9ICIjZmZmIiwKICAgICAgICAgIGx3ZCA9IDApICsKICB0aGVtZV92b2lkKCkgKwogIGdlb21fc2YoZGF0YSA9IGFnZV9kYXRhLCBtYXBwaW5nID0gYWVzKGZpbGwgPSBwZXJjZW50X3VuZGVyXzUpLCAKICAgICAgICAgIGNvbG9yID0gInRyYW5zcGFyZW50IikrCiAgc2NhbGVfZmlsbF9kaXN0aWxsZXIoYnJlYWtzPWMoMCwuMjUsLjUwLC43NSwxLjAwKSwKICAgICAgICAgICAgICAgICAgICAgICBwYWxldHRlID0gIlJkUHUiLAogICAgICAgICAgICAgICAgICAgICAgIGRpcmVjdGlvbiA9IDEsCiAgICAgICAgICAgICAgICAgICAgICAgbmEudmFsdWUgPSAidHJhbnNwYXJlbnQiLAogICAgICAgICAgICAgICAgICAgICAgIG5hbWU9IlBlcmNlbnRhZ2Ugb2YgQ2hpbGRyZW4gVW5kZXIgNSIpICsKICBnZW9tX3NmKGRhdGE9bGluZXNfc2YsIGNvbG91cj0iZGFya2dyZWVuIiwgbGluZXdpZHRoPS4yNSkrCiAgZ2VvbV9wb2ludChkYXRhPSBBY2Nlc3NpYmxlX01UQSwgCiAgICAgICAgICAgICBhZXMoeD1gR1RGUyBMb25naXR1ZGVgLCB5PWBHVEZTIExhdGl0dWRlYCksIGNvbG91cj0iZGFya2dyZWVuIiwgCiAgICAgICAgICAgICBmaWxsPSJ3aGl0ZSIscGNoPTIxLCBzaXplPS41LCBhbHBoYT1JKDAuNSkpKwogIGxhYnMoCiAgICB0aXRsZSA9ICJQb3B1bGF0aW9uIENvbmNlbnRyYXRpb24gb2YgQ2hpbGRyZW4gVW5kZXIgNQogICAgYW5kIEFjY2Vzc2libGUgU3RhdGlvbnMiLAogICAgY2FwdGlvbiA9ICJTb3VyY2VzOiBNVEEsIEFtZXJpY2FuIENvbW11bml0eSBTdXJ2ZXksIDIwMjAiKSsKICBnZW9tX3NmKGRhdGEgPSBib3JvcyB8PiBmaWx0ZXIoYm9yb19uYW1lID09ICJCcm9va2x5biIpLAogICAgICAgICAgY29sb3IgPSAiYmxhY2siLCBmaWxsID0gTkEsIGx3ZCA9IC4yNSkrCiAgZ2VvbV9zZihkYXRhID0gYm9yb3MgfD4gZmlsdGVyKGJvcm9fbmFtZSA9PSAiTWFuaGF0dGFuIiksCiAgICAgICAgICBjb2xvciA9ICJibGFjayIsIGZpbGwgPSBOQSwgbHdkID0gLjI1KSsKICBnZW9tX3NmKGRhdGEgPSBib3JvcyB8PiBmaWx0ZXIoYm9yb19uYW1lID09ICJCcm9ueCIpLAogICAgICAgICAgY29sb3IgPSAiYmxhY2siLCBmaWxsID0gTkEsIGx3ZCA9IC4yNSkrCiAgZ2VvbV9zZihkYXRhID0gYm9yb3MgfD4gZmlsdGVyKGJvcm9fbmFtZSA9PSAiU3RhdGVuIElzbGFuZCIpLAogICAgICAgICAgY29sb3IgPSAiYmxhY2siLCBmaWxsID0gTkEsIGx3ZCA9IC4yNSkrCiAgZ2VvbV9zZihkYXRhID0gYm9yb3MgfD4gZmlsdGVyKGJvcm9fbmFtZSA9PSAiUXVlZW5zIiksCiAgICAgICAgICBjb2xvciA9ICJibGFjayIsIGZpbGwgPSBOQSwgbHdkID0gLjI1KQpgYGAKRmlnLiA0CgpUaGlzIG1hcCBzaG93cyBhbGwgYWNjZXNzaWJsZSBzdGF0aW9ucyBhbmQgaGFzIHRoZSBsaW5lcyBjb2xvcmVkIHRvIGl0cyBjb29yZGluYXRpbmcgdHJhaW5zLiBUaGVyZSBhcmUgYWxzbyBzdHJlZXRzIGFkZGVkIHNvIHRoYXQgaXQgaXMgZWFzaWVyIHRvIHRlbGwgd2hlcmUgdGhlIHN0YXRpb25zIGFyZS4gVGhlIHB1cnBvc2Ugb2YgdGhpcyBtYXAgaXMgdG8gc2hvdyBob3cgc3BhcnNlIHRoZSBhY2Nlc3NpYmxlIHN0YXRpb25zIGFyZSwgZHJpdmluZyBob21lIGhvdyBsaW1pdGluZyBvdXIgY3VycmVudCBzeXN0ZW0gaXMgZm9yIG5vdCBvbmx5IHRob3NlIHdobyBhcmUgbGlzdGVkIGFzIGRpc2FibGVkLCBidXQgZm9yIHNlbmlvciBjaXRpemVucyBhbmQgc21hbGwgY2hpbGRyZW4uIApgYGB7ciwgbWVzc2FnZT1GQUxTRSwgcmVzdWx0cyA9J2hpZGUnfQojdGhlIG1hcApnZ3Bsb3QoZGF0YSA9IGJvcm9zKSsKICBnZW9tX3NmKGNvbG9yID0gIiNmZmYiLAogICAgICAgICAgZmlsbD0gImNvcm5zaWxrMSIsCiAgICAgICAgICBsd2QgPSAwKSArCiAgdGhlbWVfdm9pZCgpICsKICBnZW9tX3NmKGRhdGE9c3RyZWV0c19zZiwgY29sb3VyPSJ3aGVhdDQiLCBsaW5ld2lkdGg9LjA1KSsKICBnZW9tX3NmKGRhdGE9cmVkX2xpbmUsIGNvbG91cj0icmVkIiwgbGluZXdpZHRoPS4yNSkrCiAgZ2VvbV9zZihkYXRhPWdyZWVuX2xpbmUsIGNvbG91cj0iZ3JlZW40IiwgbGluZXdpZHRoPS4yNSkrCiAgZ2VvbV9zZihkYXRhPXB1cnBsZV9saW5lLCBjb2xvdXI9InB1cnBsZSIsIGxpbmV3aWR0aD0uMjUpKwogIGdlb21fc2YoZGF0YT1ibHVlX2xpbmUsIGNvbG91cj0iYmx1ZSIsIGxpbmV3aWR0aD0uMjUpKwogIGdlb21fc2YoZGF0YT1vcmFuZ2VfbGluZSwgY29sb3VyPSJvcmFuZ2UiLCBsaW5ld2lkdGg9LjI1KSsKICBnZW9tX3NmKGRhdGE9bGlnaHRfZ3JlZW5fbGluZSwgY29sb3VyPSJsaWdodGdyZWVuIiwgbGluZXdpZHRoPS4yNSkrCiAgZ2VvbV9zZihkYXRhPWJyb3duX2xpbmUsIGNvbG91cj0iYnJvd24iLCBsaW5ld2lkdGg9LjI1KSsKICBnZW9tX3NmKGRhdGE9Z3JleV9saW5lLCBjb2xvdXI9ImdyZXkiLCBsaW5ld2lkdGg9LjI1KSsKICBnZW9tX3NmKGRhdGE9eWVsbG93X2xpbmUsIGNvbG91cj0iZ29sZCIsIGxpbmV3aWR0aD0uMjUpKwogIGdlb21fcG9pbnQoZGF0YT0gQWNjZXNzaWJsZV9NVEEsIAogICAgICAgICAgICAgYWVzKHg9YEdURlMgTG9uZ2l0dWRlYCwgeT1gR1RGUyBMYXRpdHVkZWApLCBjb2xvdXI9ImJsYWNrIiwgCiAgICAgICAgICAgICBmaWxsPSJ3aGl0ZSIscGNoPTIxLCBzaXplPS41LCBhbHBoYT1JKDAuNSkpICsKICBsYWJzKAogICAgdGl0bGUgPSAiQWNjZXNzaWJsZSBTdWJ3YXkgU3RhdGlvbnMgaW4gTllDIiwKICAgIGNhcHRpb24gPSAiU291cmNlOiBNVEEiKSsgCiAgZ2VvbV9zZihkYXRhID0gYm9yb3MgfD4gZmlsdGVyKGJvcm9fbmFtZSA9PSAiQnJvb2tseW4iKSwgCiAgICAgICAgICBjb2xvciA9ICJibGFjayIsIGZpbGwgPSBOQSwgbHdkID0gLjI1KSsKICBnZW9tX3NmKGRhdGEgPSBib3JvcyB8PiBmaWx0ZXIoYm9yb19uYW1lID09ICJNYW5oYXR0YW4iKSwgCiAgICAgICAgICBjb2xvciA9ICJibGFjayIsIGZpbGwgPSBOQSwgbHdkID0gLjI1KSsKICBnZW9tX3NmKGRhdGEgPSBib3JvcyB8PiBmaWx0ZXIoYm9yb19uYW1lID09ICJCcm9ueCIpLCAKICAgICAgICAgIGNvbG9yID0gImJsYWNrIiwgZmlsbCA9IE5BLCBsd2QgPSAuMjUpKwogIGdlb21fc2YoZGF0YSA9IGJvcm9zIHw+IGZpbHRlcihib3JvX25hbWUgPT0gIlN0YXRlbiBJc2xhbmQiKSwgCiAgICAgICAgICBjb2xvciA9ICJibGFjayIsIGZpbGwgPSBOQSwgbHdkID0gLjI1KSsKICBnZW9tX3NmKGRhdGEgPSBib3JvcyB8PiBmaWx0ZXIoYm9yb19uYW1lID09ICJRdWVlbnMiKSwgCiAgICAgICAgICBjb2xvciA9ICJibGFjayIsIGZpbGwgPSBOQSwgbHdkID0gLjI1KQpgYGAKRmlnLiA1CgpUaGlzIHRhYmxlIHNob3dzIHRoZSBuYW1lcyBvZiBBREEgYWNjZXNzaWJsZSBzdGF0aW9ucywgdGhlIGJvcm91Z2hzIHRoZXkgYXJlIHdpdGhpbiwgdGhlIHRyYWlucyB5b3UgY2FuIGFjY2VzcywgYXMgd2VsbCBhcyB0aGUgQURBIG5vdGVzIHdoaWNoIHNob3dzIHRoZSBzdGF0aW9ucyB0aGF0IGFyZSBvbmx5IGFjY2Vzc2libGUgaW4gb25lIGRpcmVjdGlvbi4KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHJlc3VsdHMgPSdoaWRlJ30KI21ha2luZyBhIHRhYmxlCnVzZXJfZnJpZW5kbHkgPC0gQWNjZXNzaWJsZV9NVEF8PgogIHNlbGVjdCgiU3RvcCBOYW1lIiwiQm9yb3VnaCIsIkRheXRpbWUgUm91dGVzIiwiQURBIE5vdGVzIikKCmthYmxlKHVzZXJfZnJpZW5kbHksIGZvcm1hdCA9ICJodG1sIikgJT4lCiAga2FibGVfc3R5bGluZyhib290c3RyYXBfb3B0aW9ucyA9IGMoInN0cmlwZWQiLCAiaG92ZXIiKSwgZnVsbF93aWR0aCA9IEYpCmBgYAojIE5leHQgU3RlcHMKTmV4dCBzdGVwcyBmb3IgdGhpcyBwcm9qZWN0IHdvdWxkIGJlIHRvIGRvIGZ1cnRoZXIgcmVzZWFyY2ggb24gdGhlIHBvY2tldHMgb2YgZGlzYWJsZWQgcG9wdWxhdGlvbnMsIHdoeSB0aGV5IGFyZSBzbyBjb25jZW50cmF0ZWQgYW5kIGhvdyB0aGVpciBuZWVkcyBjb3VsZCBiZSBiZXR0ZXIgbWV0IGJ5IHRoZSBOZXcgWW9yayB0cmFuc2l0IHN5c3RlbS4gSSB3b3VsZCBhbHNvIHdhbnQgdG8gbG9vayBkZWVwZXIgaW50byB0aGUgdG9waWMgb2YgZGlzYWJpbGl0eSBhbmQgZmluZCBtb3JlIHNwZWNpZmljIGRhdGEgb24gdGhlIGNvbmNlbnRyYXRpb25zIG9mIHR5cGVzIG9mIGRpc2FiaWxpdHkuIEkgd291bGQgdGhlbiB3YW50IHRvIG1hcCB0aGUgYWNjb21tb2RhdGlvbnMsIGJvdGggd2hlcmUgdGhleSBhcmUgYW5kIHdoZXJlIHRoZXkgYXJlIG5lZWRlZC4gSWYgbXkgc2tpbGxzIHdlcmUgbW9yZSBhZHZhbmNlZCBJIHdvdWxkIGlkZWFsbHkgbGlrZSB0byBtYWtlIGEgZ29vZ2xlIG1hcHMtdHlwZSBvZiBpbnRlcmFjdGl2ZSBtYXAgd2hlcmUgdGhvc2Ugd2hvIG5lZWQgZWxldmF0b3JzIGNvdWxkIHBsYW4gdHJpcHMgbW9yZSBlYXNpbHksIHRha2luZyBpbnRvIGFjY291bnQgc3RhdGlvbnMgd2hlcmUgaXQgaXMgb25seSBhY2Nlc3NpYmxlIGluIG9uZSBkaXJlY3Rpb24gYXMgd2VsbCBhcyBzdGF0aW9ucyB0aGF0IGFyZSBvbmx5IGFjY2Vzc2libGUgZm9yIHRyYW5zZmVycyB3aXRoaW4gdGhlIHN0YXRpb24uIAoKIyBBcHBlbmRpeApNeSBkYXRhIGNhbWUgZnJvbSBmcm9tIHRoZSBBbWVyaWNhbiBDb21tdW5pdHkgU3VydmV5LCB0aGUgTVRBIGFuZCBOWUMgT3BlbkRhdGEuIFRoZSBBbWVyaWNhbiBDb21tdW5pdHkgU3VydmV5IHByb3ZpZGVkIGRhdGEgYWJvdXQgdGhlIGRpc2FibGVkIHBvcHVsYXRpb25zIG9mIE5ZQywgYXMgd2VsbCBhcyB0aGUgZWxkZXJseSBhbmQgdW5kZXIgZml2ZSBwb3B1bGF0aW9ucy4gVGhlIE1UQSBzdXBwbGllZCB0aGUgZGF0YSBhYm91dCB0aGUgc3Vid2F5IHN0YXRpb25zLCBpbmNsdWRpbmcgd2hpY2ggb25lcyB3ZXJlIGFjY2Vzc2libGUgZm9yIHdoaWNoIHRyYWlucy4gTllDIE9wZW5EYXRhIHByb3ZpZGVkIHRoZSBzaGFwZWZpbGVzIGZvciB0aGUgc3RyZWV0cyBhcyB3ZWxsIGFzIGZvciB0aGUgc3Vid2F5IGxpbmVzCgoKCgoKCg==