Option 3
Conduct an age-period-cohort analysis. Make plots of the different dimensions. Develop a parsimonious model of what you think is going on. Explain your results.
Exploratory Data Analysis
library(knitr)
library(tidyverse)
library(skimr) #https://ropensci.org/blog/2017/07/11/skimr/
library(ggplot2)
library(ggthemes)
library(plyr)
library(jcolors) #https://github.com/jaredhuling/jcolors/
library(Epi)
library(rms)
For this lab I looked at variable “ABANY”, which codes responses to the question “Please tell me whether or not you think it should be possible for a pregnant woman [sic] to obtain a legal abortion if [t]he woman [sic] wants it for any reason?” where 1 = “yes” and 2 = “no”.
Here we can see respondents’ ages range from 18 to 89, their birth years range from 1888 to 1998, and the years surveyed range from 1977 to 2016.
ggplot(data = data, aes(COHORT)) + geom_histogram(bins = 20)
As expected, the cohorts fall along a normal distribution, with a mean birth year in the 1950s.
ggplot(data = data, aes(AGE)) + geom_histogram(bins = 20)
The age of respondents falls along a right-skewed distribution, with the highest number of respondents in their 20s to 40s.
data_cut <- data %>%
mutate(year_cut = cut(YEAR, breaks = 10, labels = F, right = F),
age_cut = cut(AGE, breaks = 10, labels = F, right = F),
cohort_cut = cut(COHORT, breaks = 10, labels = F, right = F))
tabulate_age_cohort <- stat.table(index = list("AGE" = age_cut, "COHORT" = cohort_cut), contents = mean(ABANY), margins = TRUE, data = data_cut)
print(tabulate_age_cohort, digits = 3)
Breaking the age and cohort variables into ten categories and tabulating ABANY by age and cohort, we can that support for abortion slowly increases with each successive cohort, and cohorts 6 to 10 increased their support as they aged, with later cohorts increasing their support more quickly year-to-year.
ddply(data_cut, "year_cut", summarise, min = min(YEAR), max = max(YEAR))
ddply(data_cut, "cohort_cut", summarise, min = min(COHORT), max = max(COHORT))
ddply(data_cut, "age_cut", summarise, min = min(AGE), max = max(AGE))
The above tables tell us which cohorts, ages, and years correspond to each category.
data_cut_age_cohort <- ddply(data_cut, c("age_cut", "cohort_cut"), summarise, ABANY = mean(ABANY))
ggplot(data_cut_age_cohort, aes(x = age_cut, y = ABANY, group = cohort_cut, color = factor(cohort_cut))) +
geom_point(size = 3) +
geom_line() +
scale_x_continuous(breaks = 1:10, labels = c("18-25", "26-32", "33-39", "40-46", "47-53", "54-60", "61-67", "68-74", "75-81", "82-89")) +
theme_fivethirtyeight() +
theme(panel.grid.major.x = element_blank(),
legend.position = "top") +
scale_color_jacksonlab() +
labs(title = "Do you support abortion for any reason?",
subtitle = "By cohort and age, responses 1 = Yes, 2 = No",
color = "Cohort #1 born 1888-1898\nCohort #10 born 1987-1998",
caption = "\nSource: ICPSR cumulative General Social Survey, 1977-2016")
Graphing each cohort by age shows a generational split between cohorts 5 and 6. The first five cohorts (born 1988 to 1942) generally decreased their support over time. Cohorts 4 and 5 started in the same range as cohorts 6-8 but ended up in the same range as cohorts 1-3. Cohorts 6-8 show a similar age effect in the same age cuts, but their support never drops below their initial response average in age cut 1. Cohorts 6-10 uniformly increased support as they moved from age cut 1 to age cut 4, which is likely to be an age effect, but each subsequent cohort begins at a higher level of support.
Models
summary(lm(ABANY ~ COHORT + AGE + YEAR, data = data))
Running a naïve model we see extreme collinearity, where cohort is very significant, age is not significant, and the year effects cannot even be calculated.
APC_factor_all = lm(ABANY ~ factor(age_cut) + factor(year_cut) + factor(cohort_cut), data = data_cut)
summary(APC_factor_all)
Running the model with each cut as a dummy variable, we see that year cuts 4-5 (1989-1996) and 9-10 (2010-2016) are statistically significant, and age cuts 2-3 (26-39) and 9-10 (76-89) are almost significant.
data_cut <- data_cut %>%
mutate(elderly = case_when(AGE >= 70 ~ 1,
TRUE ~ 0)) %>%
mutate(young = case_when(AGE <= 40 ~ 1,
TRUE ~ 0))
To isolate the end-range age effects, I created indicator variables for being elderly (70 and up) and young (40 and under).
summary(lm(ABANY ~ young + elderly + factor(year_cut) + factor(cohort_cut), data = data_cut))
Adding in these age indicators, only the elderly category is statistically significant. The year cuts effects remain, although with less significance in the most recent year cuts. However cohorts 6-10 (born 1943 and onward) are all very statistically significant.
data_cut <- data_cut %>%
mutate(prewar_cohort = case_when(COHORT <= 1940 ~ 1,
TRUE ~ 0))
To isolate the new cohort effect, I created an indicator variable for one’s cohort being pre-war, that is, born before 1941.
summary(lm(ABANY ~ young + elderly + factor(year_cut) + prewar_cohort, data = data_cut))
Adding in this cohort indicator, we see it is quite statistically significant, and the elderly indicator remains significant. The year cut effects remain the same, which was puzzling to me.
data_cut <- data_cut %>%
mutate(Reagan_era = case_when(YEAR == 1981 ~ 1,
YEAR == 1982 ~ 1,
YEAR == 1983 ~ 1,
YEAR == 1984 ~ 1,
YEAR == 1985 ~ 1,
YEAR == 1986 ~ 1,
YEAR == 1987 ~ 1,
YEAR == 1988 ~ 1,
YEAR == 1989 ~ 1,
YEAR == 1990 ~ 1,
YEAR == 1991 ~ 1,
TRUE ~ 0)) %>%
mutate(Obama_era = case_when(YEAR >= 2009 ~ 1,
TRUE ~ 0))
Considering the years these cuts represent – 1989-1996 and 2010-2016 – I realized that these align roughly with the Reagan Era and Obama Era respectively. I then created two indicator variables to isolate these year effects.
APC_factor_specific = lm(ABANY ~ young + elderly + Reagan_era + Obama_era + prewar_cohort, data = data_cut)
summary(APC_factor_specific)
In the final model, almost every indicator variable is statistically significant. Being over 69 decreases support 0.044, being born before 1941 decreases support by 0.099, the Reagan Era decreased support by 0.015, and the Obama Era increased support by 0.016.
# Compare R^2
c(Model1 = summary(APC_factor_all)$adj, Model2 = summary(APC_factor_specific)$adj)
Comparing the second model with only dummy variables to the final model with only indicator variables, the R-squared decreases slightly, but the final model obviates age and cohort effects the second model obscures.
Conclusion
The age-cohort visualization of support for abortion shows evidence of both age and cohort effects similar to the significant indicators in the final model. However it was not possible to see the two distinct year effects of the Reagan-era and Obama-era political shifts. Concerning the model itself, it is possible that shifting from dummy variables to indicator variables in a different order – isolating the year effects first, for instance – might yield different significance for the final indicators, or even suggest different break points for each of the age, cohort, and year effects. If I were to continue investigating this topic, I would try modeling the cohort effects of coming of age under the period effects of the Reagan Era, and possibly even the Obama Era, though properly analysis the latter would likely need to wait a further decade.
LS0tCnRpdGxlOiAiSG9tZXdvcmsgMSIKYXV0aG9yOiAiQWxpc29uIFJ5bGFuZCIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKIyMgTm90ZQoKVGhpcyBhc3NpZ25tZW50IGFuYWx5emVzIHN1cHBvcnQgZm9yIG9yIGFnYWluc3QgYWJvcnRpb24uCgoKIyMgT3B0aW9uIDMKCipDb25kdWN0IGFuIGFnZS1wZXJpb2QtY29ob3J0IGFuYWx5c2lzLiBNYWtlIHBsb3RzIG9mIHRoZSBkaWZmZXJlbnQgZGltZW5zaW9ucy4gRGV2ZWxvcCBhIHBhcnNpbW9uaW91cyBtb2RlbCBvZiB3aGF0IHlvdSB0aGluayBpcyBnb2luZyBvbi4gRXhwbGFpbiB5b3VyIHJlc3VsdHMuKgoKIyMjIEV4cGxvcmF0b3J5IERhdGEgQW5hbHlzaXMKCmBgYHtyLCBtZXNzYWdlID0gRkFMU0V9CmxpYnJhcnkoa25pdHIpCmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KHNraW1yKSAjaHR0cHM6Ly9yb3BlbnNjaS5vcmcvYmxvZy8yMDE3LzA3LzExL3NraW1yLwpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoZ2d0aGVtZXMpCmxpYnJhcnkocGx5cikKbGlicmFyeShqY29sb3JzKSAjaHR0cHM6Ly9naXRodWIuY29tL2phcmVkaHVsaW5nL2pjb2xvcnMvCmxpYnJhcnkoRXBpKQpsaWJyYXJ5KHJtcykKYGBgCgpGb3IgdGhpcyBsYWIgSSBsb29rZWQgYXQgdmFyaWFibGUgIkFCQU5ZIiwgd2hpY2ggY29kZXMgcmVzcG9uc2VzIHRvIHRoZSBxdWVzdGlvbiAiUGxlYXNlIHRlbGwgbWUgd2hldGhlciBvciBub3QgeW91IHRoaW5rIGl0IHNob3VsZCBiZSBwb3NzaWJsZSBmb3IgYSBwcmVnbmFudCB3b21hbiBbc2ljXSB0byBvYnRhaW4gYSBsZWdhbCBhYm9ydGlvbiBpZiBbdF1oZSB3b21hbiBbc2ljXSB3YW50cyBpdCBmb3IgYW55IHJlYXNvbj8iIHdoZXJlIDEgPSAieWVzIiBhbmQgMiA9ICJubyIuCgpgYGB7ciwgcmVzdWx0cyA9ICdoaWRlJ30KbG9hZCgiMzY3OTctMDAwMS1EYXRhLnJkYSIpCgpkYXRhIDwtIGRhMzY3OTcuMDAwMSAlPiUKICBzZWxlY3QoQUJBTlksIFlFQVIsIEFHRSwgQ09IT1JULCBTRVgpICU+JQogIGRyb3BfbmEoKSAlPiUKICBtdXRhdGVfaWYoaXMuZmFjdG9yLCBhcy5udW1lcmljKQoKc2tpbShkYXRhKQpgYGAKCkhlcmUgd2UgY2FuIHNlZSByZXNwb25kZW50cycgYWdlcyByYW5nZSBmcm9tIDE4IHRvIDg5LCB0aGVpciBiaXJ0aCB5ZWFycyByYW5nZSBmcm9tIDE4ODggdG8gMTk5OCwgYW5kIHRoZSB5ZWFycyBzdXJ2ZXllZCByYW5nZSBmcm9tIDE5NzcgdG8gMjAxNi4KCmBgYHtyfQpnZ3Bsb3QoZGF0YSA9IGRhdGEsIGFlcyhDT0hPUlQpKSArIGdlb21faGlzdG9ncmFtKGJpbnMgPSAyMCkKYGBgCgpBcyBleHBlY3RlZCwgdGhlIGNvaG9ydHMgZmFsbCBhbG9uZyBhIG5vcm1hbCBkaXN0cmlidXRpb24sIHdpdGggYSBtZWFuIGJpcnRoIHllYXIgaW4gdGhlIDE5NTBzLgoKYGBge3J9CmdncGxvdChkYXRhID0gZGF0YSwgYWVzKEFHRSkpICsgZ2VvbV9oaXN0b2dyYW0oYmlucyA9IDIwKQpgYGAKClRoZSBhZ2Ugb2YgcmVzcG9uZGVudHMgZmFsbHMgYWxvbmcgYSByaWdodC1za2V3ZWQgZGlzdHJpYnV0aW9uLCB3aXRoIHRoZSBoaWdoZXN0IG51bWJlciBvZiByZXNwb25kZW50cyBpbiB0aGVpciAyMHMgdG8gNDBzLgoKYGBge3J9CmRhdGFfY3V0IDwtIGRhdGEgJT4lCiAgbXV0YXRlKHllYXJfY3V0ID0gY3V0KFlFQVIsIGJyZWFrcyA9IDEwLCBsYWJlbHMgPSBGLCByaWdodCA9IEYpLAogICAgICAgICBhZ2VfY3V0ID0gY3V0KEFHRSwgYnJlYWtzID0gMTAsIGxhYmVscyA9IEYsIHJpZ2h0ID0gRiksCiAgICAgICAgIGNvaG9ydF9jdXQgPSBjdXQoQ09IT1JULCBicmVha3MgPSAxMCwgbGFiZWxzID0gRiwgcmlnaHQgPSBGKSkKCnRhYnVsYXRlX2FnZV9jb2hvcnQgPC0gc3RhdC50YWJsZShpbmRleCA9IGxpc3QoIkFHRSIgPSBhZ2VfY3V0LCAiQ09IT1JUIiA9IGNvaG9ydF9jdXQpLCBjb250ZW50cyA9IG1lYW4oQUJBTlkpLCBtYXJnaW5zID0gVFJVRSwgZGF0YSA9IGRhdGFfY3V0KQoKcHJpbnQodGFidWxhdGVfYWdlX2NvaG9ydCwgZGlnaXRzID0gMykKYGBgCgpCcmVha2luZyB0aGUgYWdlIGFuZCBjb2hvcnQgdmFyaWFibGVzIGludG8gdGVuIGNhdGVnb3JpZXMgYW5kIHRhYnVsYXRpbmcgQUJBTlkgYnkgYWdlIGFuZCBjb2hvcnQsIHdlIGNhbiB0aGF0IHN1cHBvcnQgZm9yIGFib3J0aW9uIHNsb3dseSBpbmNyZWFzZXMgd2l0aCBlYWNoIHN1Y2Nlc3NpdmUgY29ob3J0LCBhbmQgY29ob3J0cyA2IHRvIDEwIGluY3JlYXNlZCB0aGVpciBzdXBwb3J0IGFzIHRoZXkgYWdlZCwgd2l0aCBsYXRlciBjb2hvcnRzIGluY3JlYXNpbmcgdGhlaXIgc3VwcG9ydCBtb3JlIHF1aWNrbHkgeWVhci10by15ZWFyLgoKYGBge3J9CmRkcGx5KGRhdGFfY3V0LCAieWVhcl9jdXQiLCBzdW1tYXJpc2UsIG1pbiA9IG1pbihZRUFSKSwgbWF4ID0gbWF4KFlFQVIpKQpgYGAKCmBgYHtyfQpkZHBseShkYXRhX2N1dCwgImNvaG9ydF9jdXQiLCBzdW1tYXJpc2UsIG1pbiA9IG1pbihDT0hPUlQpLCBtYXggPSBtYXgoQ09IT1JUKSkKYGBgCgpgYGB7cn0KZGRwbHkoZGF0YV9jdXQsICJhZ2VfY3V0Iiwgc3VtbWFyaXNlLCBtaW4gPSBtaW4oQUdFKSwgbWF4ID0gbWF4KEFHRSkpCmBgYAoKVGhlIGFib3ZlIHRhYmxlcyB0ZWxsIHVzIHdoaWNoIGNvaG9ydHMsIGFnZXMsIGFuZCB5ZWFycyBjb3JyZXNwb25kIHRvIGVhY2ggY2F0ZWdvcnkuCgpgYGB7cn0KZGF0YV9jdXRfYWdlX2NvaG9ydCA8LSBkZHBseShkYXRhX2N1dCwgYygiYWdlX2N1dCIsICJjb2hvcnRfY3V0IiksIHN1bW1hcmlzZSwgQUJBTlkgPSBtZWFuKEFCQU5ZKSkKCmdncGxvdChkYXRhX2N1dF9hZ2VfY29ob3J0LCBhZXMoeCA9IGFnZV9jdXQsIHkgPSBBQkFOWSwgZ3JvdXAgPSBjb2hvcnRfY3V0LCBjb2xvciA9IGZhY3Rvcihjb2hvcnRfY3V0KSkpICsgCiAgZ2VvbV9wb2ludChzaXplID0gMykgKyAKICBnZW9tX2xpbmUoKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IDE6MTAsIGxhYmVscyA9IGMoIjE4LTI1IiwgIjI2LTMyIiwgIjMzLTM5IiwgIjQwLTQ2IiwgIjQ3LTUzIiwgIjU0LTYwIiwgIjYxLTY3IiwgIjY4LTc0IiwgIjc1LTgxIiwgIjgyLTg5IikpICsKICB0aGVtZV9maXZldGhpcnR5ZWlnaHQoKSArCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci54ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiKSArCiAgc2NhbGVfY29sb3JfamFja3NvbmxhYigpICsKICBsYWJzKHRpdGxlID0gIkRvIHlvdSBzdXBwb3J0IGFib3J0aW9uIGZvciBhbnkgcmVhc29uPyIsCiAgICAgICBzdWJ0aXRsZSA9ICJCeSBjb2hvcnQgYW5kIGFnZSwgcmVzcG9uc2VzIDEgPSBZZXMsIDIgPSBObyIsCiAgICAgICBjb2xvciA9ICJDb2hvcnQgIzEgYm9ybiAxODg4LTE4OThcbkNvaG9ydCAjMTAgYm9ybiAxOTg3LTE5OTgiLAogICAgICAgY2FwdGlvbiA9ICJcblNvdXJjZTogSUNQU1IgY3VtdWxhdGl2ZSBHZW5lcmFsIFNvY2lhbCBTdXJ2ZXksIDE5NzctMjAxNiIpCmBgYAoKR3JhcGhpbmcgZWFjaCBjb2hvcnQgYnkgYWdlIHNob3dzIGEgZ2VuZXJhdGlvbmFsIHNwbGl0IGJldHdlZW4gY29ob3J0cyA1IGFuZCA2LiBUaGUgZmlyc3QgZml2ZSBjb2hvcnRzIChib3JuIDE5ODggdG8gMTk0MikgZ2VuZXJhbGx5IGRlY3JlYXNlZCB0aGVpciBzdXBwb3J0IG92ZXIgdGltZS4gQ29ob3J0cyA0IGFuZCA1IHN0YXJ0ZWQgaW4gdGhlIHNhbWUgcmFuZ2UgYXMgY29ob3J0cyA2LTggYnV0IGVuZGVkIHVwIGluIHRoZSBzYW1lIHJhbmdlIGFzIGNvaG9ydHMgMS0zLiBDb2hvcnRzIDYtOCBzaG93IGEgc2ltaWxhciBhZ2UgZWZmZWN0IGluIHRoZSBzYW1lIGFnZSBjdXRzLCBidXQgdGhlaXIgc3VwcG9ydCBuZXZlciBkcm9wcyBiZWxvdyB0aGVpciBpbml0aWFsIHJlc3BvbnNlIGF2ZXJhZ2UgaW4gYWdlIGN1dCAxLiBDb2hvcnRzIDYtMTAgdW5pZm9ybWx5IGluY3JlYXNlZCBzdXBwb3J0IGFzIHRoZXkgbW92ZWQgZnJvbSBhZ2UgY3V0IDEgdG8gYWdlIGN1dCA0LCB3aGljaCBpcyBsaWtlbHkgdG8gYmUgYW4gYWdlIGVmZmVjdCwgYnV0IGVhY2ggc3Vic2VxdWVudCBjb2hvcnQgYmVnaW5zIGF0IGEgaGlnaGVyIGxldmVsIG9mIHN1cHBvcnQuCgoKIyMjIE1vZGVscwoKYGBge3J9CnN1bW1hcnkobG0oQUJBTlkgfiBDT0hPUlQgKyBBR0UgKyBZRUFSLCBkYXRhID0gZGF0YSkpCmBgYAoKUnVubmluZyBhIG5hw692ZSBtb2RlbCB3ZSBzZWUgZXh0cmVtZSBjb2xsaW5lYXJpdHksIHdoZXJlIGNvaG9ydCBpcyB2ZXJ5IHNpZ25pZmljYW50LCBhZ2UgaXMgbm90IHNpZ25pZmljYW50LCBhbmQgdGhlIHllYXIgZWZmZWN0cyBjYW5ub3QgZXZlbiBiZSBjYWxjdWxhdGVkLgoKYGBge3J9CkFQQ19mYWN0b3JfYWxsID0gbG0oQUJBTlkgfiBmYWN0b3IoYWdlX2N1dCkgKyBmYWN0b3IoeWVhcl9jdXQpICsgZmFjdG9yKGNvaG9ydF9jdXQpLCBkYXRhID0gZGF0YV9jdXQpCgpzdW1tYXJ5KEFQQ19mYWN0b3JfYWxsKQpgYGAKClJ1bm5pbmcgdGhlIG1vZGVsIHdpdGggZWFjaCBjdXQgYXMgYSBkdW1teSB2YXJpYWJsZSwgd2Ugc2VlIHRoYXQgeWVhciBjdXRzIDQtNSAoMTk4OS0xOTk2KSBhbmQgOS0xMCAoMjAxMC0yMDE2KSBhcmUgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCwgYW5kIGFnZSBjdXRzIDItMyAoMjYtMzkpIGFuZCA5LTEwICg3Ni04OSkgYXJlIGFsbW9zdCBzaWduaWZpY2FudC4KCmBgYHtyfQpkYXRhX2N1dCA8LSBkYXRhX2N1dCAlPiUgCiAgbXV0YXRlKGVsZGVybHkgPSBjYXNlX3doZW4oQUdFID49IDcwIH4gMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUUlVFICAgICAgfiAwKSkgJT4lCiAgbXV0YXRlKHlvdW5nID0gY2FzZV93aGVuKEFHRSA8PSA0MCB+IDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFRSVUUgICAgICB+IDApKQpgYGAKClRvIGlzb2xhdGUgdGhlIGVuZC1yYW5nZSBhZ2UgZWZmZWN0cywgSSBjcmVhdGVkIGluZGljYXRvciB2YXJpYWJsZXMgZm9yIGJlaW5nIGVsZGVybHkgKDcwIGFuZCB1cCkgYW5kIHlvdW5nICg0MCBhbmQgdW5kZXIpLgoKYGBge3J9CnN1bW1hcnkobG0oQUJBTlkgfiB5b3VuZyArIGVsZGVybHkgKyBmYWN0b3IoeWVhcl9jdXQpICsgZmFjdG9yKGNvaG9ydF9jdXQpLCBkYXRhID0gZGF0YV9jdXQpKQpgYGAKCkFkZGluZyBpbiB0aGVzZSBhZ2UgaW5kaWNhdG9ycywgb25seSB0aGUgZWxkZXJseSBjYXRlZ29yeSBpcyBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50LiBUaGUgeWVhciBjdXRzIGVmZmVjdHMgcmVtYWluLCBhbHRob3VnaCB3aXRoIGxlc3Mgc2lnbmlmaWNhbmNlIAppbiB0aGUgbW9zdCByZWNlbnQgeWVhciBjdXRzLiBIb3dldmVyIGNvaG9ydHMgNi0xMCAoYm9ybiAxOTQzIGFuZCBvbndhcmQpIGFyZSBhbGwgdmVyeSBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50LiAKCmBgYHtyfQpkYXRhX2N1dCA8LSBkYXRhX2N1dCAlPiUgCiAgbXV0YXRlKHByZXdhcl9jb2hvcnQgPSBjYXNlX3doZW4oQ09IT1JUIDw9IDE5NDAgfiAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRSVUUgICAgICAgICAgIH4gMCkpIApgYGAKClRvIGlzb2xhdGUgdGhlIG5ldyBjb2hvcnQgZWZmZWN0LCBJIGNyZWF0ZWQgYW4gaW5kaWNhdG9yIHZhcmlhYmxlIGZvciBvbmUncyBjb2hvcnQgYmVpbmcgcHJlLXdhciwgdGhhdCBpcywgYm9ybiBiZWZvcmUgMTk0MS4KCmBgYHtyfQpzdW1tYXJ5KGxtKEFCQU5ZIH4geW91bmcgKyBlbGRlcmx5ICsgZmFjdG9yKHllYXJfY3V0KSArIHByZXdhcl9jb2hvcnQsIGRhdGEgPSBkYXRhX2N1dCkpCmBgYAoKQWRkaW5nIGluIHRoaXMgY29ob3J0IGluZGljYXRvciwgd2Ugc2VlIGl0IGlzIHF1aXRlIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQsIGFuZCB0aGUgZWxkZXJseSBpbmRpY2F0b3IgcmVtYWlucyBzaWduaWZpY2FudC4gVGhlIHllYXIgY3V0IGVmZmVjdHMgCnJlbWFpbiB0aGUgc2FtZSwgd2hpY2ggd2FzIHB1enpsaW5nIHRvIG1lLgoKYGBge3J9CmRhdGFfY3V0IDwtIGRhdGFfY3V0ICU+JSAKICBtdXRhdGUoUmVhZ2FuX2VyYSA9IGNhc2Vfd2hlbihZRUFSID09IDE5ODEgfiAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFlFQVIgPT0gMTk4MiB+IDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWUVBUiA9PSAxOTgzIH4gMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBZRUFSID09IDE5ODQgfiAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFlFQVIgPT0gMTk4NSB+IDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWUVBUiA9PSAxOTg2IH4gMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBZRUFSID09IDE5ODcgfiAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFlFQVIgPT0gMTk4OCB+IDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWUVBUiA9PSAxOTg5IH4gMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBZRUFSID09IDE5OTAgfiAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFlFQVIgPT0gMTk5MSB+IDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVFJVRSAgICAgICAgfiAwKSkgJT4lCiAgbXV0YXRlKE9iYW1hX2VyYSA9IGNhc2Vfd2hlbihZRUFSID49IDIwMDkgfiAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVFJVRSAgICAgICAgIH4gMCkpCmBgYAoKQ29uc2lkZXJpbmcgdGhlIHllYXJzIHRoZXNlIGN1dHMgcmVwcmVzZW50IC0tIDE5ODktMTk5NiBhbmQgMjAxMC0yMDE2IC0tIEkgcmVhbGl6ZWQgdGhhdCB0aGVzZSBhbGlnbiByb3VnaGx5IHdpdGggdGhlIFJlYWdhbiBFcmEgYW5kIE9iYW1hIEVyYSByZXNwZWN0aXZlbHkuIEkgdGhlbiBjcmVhdGVkIHR3byBpbmRpY2F0b3IgdmFyaWFibGVzIHRvIGlzb2xhdGUgdGhlc2UgeWVhciBlZmZlY3RzLgoKYGBge3J9CkFQQ19mYWN0b3Jfc3BlY2lmaWMgPSBsbShBQkFOWSB+IHlvdW5nICsgZWxkZXJseSArIFJlYWdhbl9lcmEgKyBPYmFtYV9lcmEgKyBwcmV3YXJfY29ob3J0LCBkYXRhID0gZGF0YV9jdXQpCgpzdW1tYXJ5KEFQQ19mYWN0b3Jfc3BlY2lmaWMpCmBgYAoKSW4gdGhlIGZpbmFsIG1vZGVsLCBhbG1vc3QgZXZlcnkgaW5kaWNhdG9yIHZhcmlhYmxlIGlzIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQuIEJlaW5nIG92ZXIgNjkgZGVjcmVhc2VzIHN1cHBvcnQgMC4wNDQsIGJlaW5nIGJvcm4gYmVmb3JlIDE5NDEgCmRlY3JlYXNlcyBzdXBwb3J0IGJ5IDAuMDk5LCB0aGUgUmVhZ2FuIEVyYSBkZWNyZWFzZWQgc3VwcG9ydCBieSAwLjAxNSwgYW5kIHRoZSBPYmFtYSBFcmEgaW5jcmVhc2VkIHN1cHBvcnQgYnkgMC4wMTYuCgpgYGB7cn0KIyBDb21wYXJlIFJeMgoKYyhNb2RlbDEgPSBzdW1tYXJ5KEFQQ19mYWN0b3JfYWxsKSRhZGosIE1vZGVsMiA9IHN1bW1hcnkoQVBDX2ZhY3Rvcl9zcGVjaWZpYykkYWRqKQpgYGAKCkNvbXBhcmluZyB0aGUgc2Vjb25kIG1vZGVsIHdpdGggb25seSBkdW1teSB2YXJpYWJsZXMgdG8gdGhlIGZpbmFsIG1vZGVsIHdpdGggb25seSBpbmRpY2F0b3IgdmFyaWFibGVzLCB0aGUgUi1zcXVhcmVkIGRlY3JlYXNlcyBzbGlnaHRseSwgYnV0IHRoZSBmaW5hbCBtb2RlbCBvYnZpYXRlcyBhZ2UgYW5kIGNvaG9ydCBlZmZlY3RzIHRoZSBzZWNvbmQgbW9kZWwgb2JzY3VyZXMuCgoKIyMjIENvbmNsdXNpb24KClRoZSBhZ2UtY29ob3J0IHZpc3VhbGl6YXRpb24gb2Ygc3VwcG9ydCBmb3IgYWJvcnRpb24gc2hvd3MgZXZpZGVuY2Ugb2YgYm90aCBhZ2UgYW5kIGNvaG9ydCBlZmZlY3RzIHNpbWlsYXIgdG8gdGhlIHNpZ25pZmljYW50IGluZGljYXRvcnMgaW4gdGhlIGZpbmFsIG1vZGVsLiBIb3dldmVyIGl0IHdhcyBub3QgcG9zc2libGUgdG8gc2VlIHRoZSB0d28gZGlzdGluY3QgeWVhciBlZmZlY3RzIG9mIHRoZSBSZWFnYW4tZXJhIGFuZCBPYmFtYS1lcmEgcG9saXRpY2FsIHNoaWZ0cy4gQ29uY2VybmluZyB0aGUgbW9kZWwgaXRzZWxmLCAKaXQgaXMgcG9zc2libGUgdGhhdCBzaGlmdGluZyBmcm9tIGR1bW15IHZhcmlhYmxlcyB0byBpbmRpY2F0b3IgdmFyaWFibGVzIGluIGEgZGlmZmVyZW50IG9yZGVyIC0tIGlzb2xhdGluZyB0aGUgeWVhciBlZmZlY3RzIGZpcnN0LCBmb3IgaW5zdGFuY2UgLS0gbWlnaHQKeWllbGQgZGlmZmVyZW50IHNpZ25pZmljYW5jZSBmb3IgdGhlIGZpbmFsIGluZGljYXRvcnMsIG9yIGV2ZW4gc3VnZ2VzdCBkaWZmZXJlbnQgYnJlYWsgcG9pbnRzIGZvciBlYWNoIG9mIHRoZSBhZ2UsIGNvaG9ydCwgYW5kIHllYXIgZWZmZWN0cy4gSWYgSSB3ZXJlIAp0byBjb250aW51ZSBpbnZlc3RpZ2F0aW5nIHRoaXMgdG9waWMsIEkgd291bGQgdHJ5IG1vZGVsaW5nIHRoZSBjb2hvcnQgZWZmZWN0cyBvZiBjb21pbmcgb2YgYWdlIHVuZGVyIHRoZSBwZXJpb2QgZWZmZWN0cyBvZiB0aGUgUmVhZ2FuIEVyYSwgYW5kIHBvc3NpYmx5IGV2ZW4gdGhlIE9iYW1hIEVyYSwgdGhvdWdoIHByb3Blcmx5IGFuYWx5c2lzIHRoZSBsYXR0ZXIgd291bGQgbGlrZWx5IG5lZWQgdG8gd2FpdCBhIGZ1cnRoZXIgZGVjYWRlLgo=