Overview

In this notebook, we’ll hone our data manipulation skills by examining conflict event data generated by the Armed Conflict Location & Event Data Project (ACLED). The aim is to practice some of the tidyverse functions covered in the lecture.

As always, we need to make sure we have the tidyverse packages installed and loaded.

# install.packages("tidyverse")  
require(tidyverse) 

Data

ACLED is a “disaggregated data collection, analysis, and crisis mapping project. ACLED collects the dates, actors, locations, fatalities, and modalities of all reported political violence and protest events across Africa, South Asia, Southeast Asia, the Middle East, Central Asia and the Caucasus, Latin America and the Caribbean, and Southeastern and Eastern Europe and the Balkans.” For this exercise, we’ll focus just on the data pertaining to Africa. For more information regarding these data, please consult the ACLED methodology.

acled <- read_csv("https://raw.githubusercontent.com/edunford/enhance_and_advance_R/master/lectures/wrangling/walkthroughs/acled_africa.csv")
Parsed with column specification:
cols(
  .default = col_character(),
  data_id = col_double(),
  iso = col_double(),
  event_id_no_cnty = col_double(),
  year = col_double(),
  time_precision = col_double(),
  inter1 = col_double(),
  inter2 = col_double(),
  interaction = col_double(),
  latitude = col_double(),
  longitude = col_double(),
  geo_precision = col_double(),
  fatalities = col_double(),
  timestamp = col_double()
)
See spec(...) for full column specifications.
head(acled)

Know your data

To understand a dataset, one needs to ask a lot of questions of it. To get a better feel for the ACLED data, let’s explore the following questions:

1. What’s the temporal coverage of the data?

acled %>% 
  group_by(country) %>% 
  summarize(min_year = min(year),
            max_year = max(year))
`summarise()` ungrouping output (override with `.groups` argument)

2. How many events are recorded for each country?

acled %>% 
  count(country,sort=T)

3. How many events are recorded for each year?

acled %>% 
  count(year,sort=T)

4. What’s the most common event type in the data?

acled %>% 
  group_by(event_type) %>% 
  summarize(n_events = n()) %>% 
  arrange(desc(n_events))
`summarise()` ungrouping output (override with `.groups` argument)

5. How many sub_ event types are there for each event type?

acled %>% 
  group_by(event_type) %>% 
  summarize(n_subtypes = n_distinct(sub_event_type)) %>% 
  arrange(desc(n_subtypes))
`summarise()` ungrouping output (override with `.groups` argument)

6. Which countries had the highest number of reported fatalities?

Political Violence → Economic Growth

Let’s say we wanted to estimate the impact of political violence on economic growth. Specifically, we want to known how the number of fatalities as a result of political instability impacts the economic growth of a country. Construct a data set that would allow you to answer this question and use OLS to estimate the relationship model.

Data on Economic Growth

First, I’ve provided data from the World Bank that captures the economic growth rate by country-year.

# install.packages(wbstats) # API for downloading WB data
require(wbstats)

# Download the data
gdppp_growth <- wb(country = "countries_only",indicator = "NY.GDP.PCAP.KD.ZG") %>% 
  mutate(date=as.numeric(date))

# Look at the top of the data
head(gdppp_growth)

Transform the event data

The unit of analysis of the acled data is set at the location-day. We need to aggregate these data so that it is at the country-year. Relying only on the tidyverse function, generate a new data frame that has the following fields:

  • country (unit);
  • year (time);
  • fatalities = total number of fatalities in a given country-year;
  • ln_fatalities = natural log of the number of fatalities (main IV);
  • n_events = total number of events that took place in a given country;
  • ln_n_events = natural log of the number of events (control).
acled_country_year <-
  acled %>% 
  group_by(country,year) %>% 
  summarize(fatalities = sum(fatalities),
            ln_fatalities = log(fatalities + 1),
            n_events = n(),
            ln_n_events = log(n_events + 1)) %>% 
  ungroup
`summarise()` regrouping output by 'country' (override with `.groups` argument)
acled_country_year %>% sample_n(5)

Join the Data

Now that we’ve converted our event-level data into coutry-year-level data, let’s merge the growth data onto the conflict data.

A few things to keep in mind:

  • Country names might be spelled differently, so we’ll want to double check that no data was lost in the merge.
  • There are more countries in the wb data than the acled data, so we’ll want to make sure we merge onto the acled data and not the other way around.
# Reduce the acled data down.
gdppp_growth2 <- gdppp_growth %>% select(country, year = date, growth = value)

# join
dat <- left_join(acled_country_year,gdppp_growth2,by=c("country","year"))

# look at the data 
dat %>% sample_n(5)

Are we missing any countries? That is, did we any countries not come through when merging?

dat %>% 
  group_by(country) %>% 
  summarize(n_missing = sum(is.na(growth)),
            total = n(),
            prop_missing = n_missing/total) %>% 
  arrange(desc(n_missing))
`summarise()` ungrouping output (override with `.groups` argument)

Oh no – loooks like we missed a few. Let’s explore why. As we can see below, it looks like the WB has different naming conventions for some of the countries.

gdppp_growth2 %>% 
  filter(str_detect(country,"Congo")) %>% 
  distinct(country)

Note a problem! Let’s standardize the naming conventions using the countrycode package.

# install.packages(countrycode)
require(countrycode)

# Standardize the country names for the WB data
gdppp_growth3 <- 
  gdppp_growth2 %>% 
  mutate(country = countrycode(country,"country.name","country.name"))

# Standardize the country names for the ACLED data
acled_country_year2 <- 
  acled_country_year %>% 
  mutate(country = countrycode(country,"country.name","country.name"))
  

# join
dat <- left_join(acled_country_year2,gdppp_growth3,by=c("country","year"))

# look at the data 
dat %>% sample_n(5)

Check again if there are any issues?

dat %>% 
  group_by(country) %>% 
  summarize(n_missing = sum(is.na(growth)),
            total = n(),
            prop_missing = n_missing/total) %>% 
  arrange(desc(n_missing))
`summarise()` ungrouping output (override with `.groups` argument)

Still missing data for Somalia. Why is this? Doesn’t look like the WB has growth data for Somalia after 1990.

gdppp_growth3 %>% 
  filter(country == "Somalia") %>% 
  summary()
   country               year          growth         
 Length:30          Min.   :1961   Min.   :-20.97435  
 Class :character   1st Qu.:1968   1st Qu.: -6.81114  
 Mode  :character   Median :1976   Median :  0.02207  
                    Mean   :1976   Mean   : -0.74568  
                    3rd Qu.:1983   3rd Qu.:  3.17685  
                    Max.   :1990   Max.   : 21.78373  

Run model

Let’s now run our (very basic) analysis!

dat %>% 
  lm(growth ~ ln_fatalities, data = .) %>% 
  summary(.)

Call:
lm(formula = growth ~ ln_fatalities, data = .)

Residuals:
    Min      1Q  Median      3Q     Max 
-62.938  -1.862   0.003   1.940 137.591 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept)    2.77997    0.40920   6.794 1.88e-11 ***
ln_fatalities -0.25760    0.09809  -2.626  0.00876 ** 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 8.123 on 996 degrees of freedom
  (105 observations deleted due to missingness)
Multiple R-squared:  0.006878,  Adjusted R-squared:  0.00588 
F-statistic: 6.897 on 1 and 996 DF,  p-value: 0.008764

Now controlling for the number of event in the country.

dat %>% 
  lm(growth ~ ln_fatalities + ln_n_events, data = .) %>% 
  summary(.)

Call:
lm(formula = growth ~ ln_fatalities + ln_n_events, data = .)

Residuals:
    Min      1Q  Median      3Q     Max 
-62.857  -1.874   0.002   2.013 137.433 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept)    3.48722    0.58441   5.967 3.35e-09 ***
ln_fatalities -0.04803    0.15785  -0.304   0.7610    
ln_n_events   -0.39617    0.23392  -1.694   0.0907 .  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 8.116 on 995 degrees of freedom
  (105 observations deleted due to missingness)
Multiple R-squared:  0.009732,  Adjusted R-squared:  0.007742 
F-statistic: 4.889 on 2 and 995 DF,  p-value: 0.007709
LS0tCnRpdGxlOiB8CiB8IEVuaGFuY2UgYW5kIEFkdmFuY2UKIHwgSW50cm9kdWN0aW9uIHRvIFIKc3VidGl0bGU6ICJNYW5pcHVsYXRpbmcgQ29uZmxpY3QgRXZlbnQgRGF0YSIgCmF1dGhvcjogRXJpYyBEdW5mb3JkCmFmZmlsaWF0aW9uOiAiR2VvcmdldG93biBVbml2ZXJzaXR5IgpkYXRlOiAiU3VtbWVyIDIwMjAiIApvdXRwdXQ6IAogIGh0bWxfbm90ZWJvb2s6CiAgICB0aGVtZTogZmxhdGx5CiAgICB0b2M6IHRydWUKICAgIHRvY19mbG9hdDogdHJ1ZQogICAgdG9jX2RlcHRoOiAzCi0tLQoKYGBge3IsaW5jbHVkZSA9IEZ9CmtuaXRyOjpvcHRzX2NodW5rJHNldChlcnJvcj1GLHdhcm5pbmcgPSBGKQpgYGAKCiMgT3ZlcnZpZXcKCkluIHRoaXMgbm90ZWJvb2ssIHdlJ2xsIGhvbmUgb3VyIGRhdGEgbWFuaXB1bGF0aW9uIHNraWxscyBieSBleGFtaW5pbmcgY29uZmxpY3QgZXZlbnQgZGF0YSBnZW5lcmF0ZWQgYnkgdGhlIFtBcm1lZCBDb25mbGljdCBMb2NhdGlvbiAmIEV2ZW50IERhdGEgUHJvamVjdCAoQUNMRUQpXShodHRwczovL2FjbGVkZGF0YS5jb20vIy9kYXNoYm9hcmQpLiBUaGUgYWltIGlzIHRvIHByYWN0aWNlIHNvbWUgb2YgdGhlIHRpZHl2ZXJzZSBmdW5jdGlvbnMgY292ZXJlZCBpbiB0aGUgbGVjdHVyZS4gCgpBcyBhbHdheXMsIHdlIG5lZWQgdG8gbWFrZSBzdXJlIHdlIGhhdmUgdGhlIGB0aWR5dmVyc2VgIHBhY2thZ2VzIGluc3RhbGxlZCBhbmQgbG9hZGVkLiAKCmBgYHtyfQojIGluc3RhbGwucGFja2FnZXMoInRpZHl2ZXJzZSIpICAKcmVxdWlyZSh0aWR5dmVyc2UpIApgYGAKCgojIERhdGEgCgpBQ0xFRCBpcyBhICJkaXNhZ2dyZWdhdGVkIGRhdGEgY29sbGVjdGlvbiwgYW5hbHlzaXMsIGFuZCBjcmlzaXMgbWFwcGluZyBwcm9qZWN0LiBBQ0xFRCBjb2xsZWN0cyB0aGUgZGF0ZXMsIGFjdG9ycywgbG9jYXRpb25zLCBmYXRhbGl0aWVzLCBhbmQgbW9kYWxpdGllcyBvZiBhbGwgcmVwb3J0ZWQgcG9saXRpY2FsIHZpb2xlbmNlIGFuZCBwcm90ZXN0IGV2ZW50cyBhY3Jvc3MgQWZyaWNhLCBTb3V0aCBBc2lhLCBTb3V0aGVhc3QgQXNpYSwgdGhlIE1pZGRsZSBFYXN0LCBDZW50cmFsIEFzaWEgYW5kIHRoZSBDYXVjYXN1cywgTGF0aW4gQW1lcmljYSBhbmQgdGhlIENhcmliYmVhbiwgYW5kIFNvdXRoZWFzdGVybiBhbmQgRWFzdGVybiBFdXJvcGUgYW5kIHRoZSBCYWxrYW5zLiIgRm9yIHRoaXMgZXhlcmNpc2UsIHdlJ2xsIGZvY3VzIGp1c3Qgb24gdGhlIGRhdGEgcGVydGFpbmluZyB0byBfQWZyaWNhXy4gRm9yIG1vcmUgaW5mb3JtYXRpb24gcmVnYXJkaW5nIHRoZXNlIGRhdGEsIHBsZWFzZSBjb25zdWx0IHRoZSBbQUNMRUQgbWV0aG9kb2xvZ3ldKGh0dHBzOi8vYWNsZWRkYXRhLmNvbS9yZXNvdXJjZXMvbWV0aG9kb2xvZ3kvKS4KCmBgYHtyfQphY2xlZCA8LSByZWFkX2NzdigiaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL2VkdW5mb3JkL2VuaGFuY2VfYW5kX2FkdmFuY2VfUi9tYXN0ZXIvbGVjdHVyZXMvd3JhbmdsaW5nL3dhbGt0aHJvdWdocy9hY2xlZF9hZnJpY2EuY3N2IikKaGVhZChhY2xlZCkKYGBgCgoKIyBLbm93IHlvdXIgZGF0YQoKVG8gdW5kZXJzdGFuZCBhIGRhdGFzZXQsIG9uZSBuZWVkcyB0byBhc2sgYSBsb3Qgb2YgcXVlc3Rpb25zIG9mIGl0LiBUbyBnZXQgYSBiZXR0ZXIgZmVlbCBmb3IgdGhlIEFDTEVEIGRhdGEsIGxldCdzIGV4cGxvcmUgdGhlIGZvbGxvd2luZyBxdWVzdGlvbnM6CgojIyMjIDEuIFdoYXQncyB0aGUgdGVtcG9yYWwgY292ZXJhZ2Ugb2YgdGhlIGRhdGE/CgpgYGB7cn0KYWNsZWQgJT4lIAogIGdyb3VwX2J5KGNvdW50cnkpICU+JSAKICBzdW1tYXJpemUobWluX3llYXIgPSBtaW4oeWVhciksCiAgICAgICAgICAgIG1heF95ZWFyID0gbWF4KHllYXIpKQpgYGAKCgojIyMjIDIuIEhvdyBtYW55IGV2ZW50cyBhcmUgcmVjb3JkZWQgZm9yIGVhY2ggY291bnRyeT8gCgpgYGB7cn0KYWNsZWQgJT4lIAogIGNvdW50KGNvdW50cnksc29ydD1UKQpgYGAKCiMjIyMgMy4gSG93IG1hbnkgZXZlbnRzIGFyZSByZWNvcmRlZCBmb3IgZWFjaCB5ZWFyPwoKYGBge3J9CmFjbGVkICU+JSAKICBjb3VudCh5ZWFyLHNvcnQ9VCkKYGBgCgoKIyMjIyA0LiBXaGF0J3MgdGhlIG1vc3QgY29tbW9uIGV2ZW50IHR5cGUgaW4gdGhlIGRhdGE/CgpgYGB7cn0KYWNsZWQgJT4lIAogIGdyb3VwX2J5KGV2ZW50X3R5cGUpICU+JSAKICBzdW1tYXJpemUobl9ldmVudHMgPSBuKCkpICU+JSAKICBhcnJhbmdlKGRlc2Mobl9ldmVudHMpKQpgYGAKCgojIyMjIDUuIEhvdyBtYW55IGBzdWJfYCBldmVudCB0eXBlcyBhcmUgdGhlcmUgZm9yIGVhY2ggZXZlbnQgdHlwZT8KCmBgYHtyfQphY2xlZCAlPiUgCiAgZ3JvdXBfYnkoZXZlbnRfdHlwZSkgJT4lIAogIHN1bW1hcml6ZShuX3N1YnR5cGVzID0gbl9kaXN0aW5jdChzdWJfZXZlbnRfdHlwZSkpICU+JSAKICBhcnJhbmdlKGRlc2Mobl9zdWJ0eXBlcykpCmBgYAoKCiMjIyMgNi4gV2hpY2ggY291bnRyaWVzIGhhZCB0aGUgaGlnaGVzdCBudW1iZXIgb2YgcmVwb3J0ZWQgZmF0YWxpdGllcz8gCgpgYGB7cn0KbmV3X2RhdGEgPC0gCiAgYWNsZWQgJT4lIAogIGdyb3VwX2J5KGNvdW50cnkseWVhcikgJT4lIAogIHN1bW1hcml6ZShmYXRhbGl0aWVzID0gc3VtKGZhdGFsaXRpZXMpKSAlPiUgCiAgYXJyYW5nZShkZXNjKGZhdGFsaXRpZXMpKQoKbmV3X2RhdGEKYGBgCgoKIyBQb2xpdGljYWwgVmlvbGVuY2UgJnJhcnI7IEVjb25vbWljIEdyb3d0aAoKTGV0J3Mgc2F5IHdlIHdhbnRlZCB0byBlc3RpbWF0ZSB0aGUgaW1wYWN0IG9mIHBvbGl0aWNhbCB2aW9sZW5jZSBvbiBlY29ub21pYyBncm93dGguIFNwZWNpZmljYWxseSwgd2Ugd2FudCB0byBrbm93biBob3cgdGhlIG51bWJlciBvZiBmYXRhbGl0aWVzIGFzIGEgcmVzdWx0IG9mIHBvbGl0aWNhbCBpbnN0YWJpbGl0eSBpbXBhY3RzIHRoZSBlY29ub21pYyBncm93dGggb2YgYSBjb3VudHJ5LiBDb25zdHJ1Y3QgYSBkYXRhIHNldCB0aGF0IHdvdWxkIGFsbG93IHlvdSB0byBhbnN3ZXIgdGhpcyBxdWVzdGlvbiBhbmQgdXNlIE9MUyB0byBlc3RpbWF0ZSB0aGUgcmVsYXRpb25zaGlwIG1vZGVsLgoKCiMjIERhdGEgb24gRWNvbm9taWMgR3Jvd3RoCgpGaXJzdCwgSSd2ZSBwcm92aWRlZCBkYXRhIGZyb20gdGhlIGBXb3JsZCBCYW5rYCB0aGF0IGNhcHR1cmVzIHRoZSBlY29ub21pYyBncm93dGggcmF0ZSBieSBjb3VudHJ5LXllYXIuCgpgYGB7cn0KIyBpbnN0YWxsLnBhY2thZ2VzKHdic3RhdHMpICMgQVBJIGZvciBkb3dubG9hZGluZyBXQiBkYXRhCnJlcXVpcmUod2JzdGF0cykKCiMgRG93bmxvYWQgdGhlIGRhdGEKZ2RwcHBfZ3Jvd3RoIDwtIHdiKGNvdW50cnkgPSAiY291bnRyaWVzX29ubHkiLGluZGljYXRvciA9ICJOWS5HRFAuUENBUC5LRC5aRyIpICU+JSAKICBtdXRhdGUoZGF0ZT1hcy5udW1lcmljKGRhdGUpKQoKIyBMb29rIGF0IHRoZSB0b3Agb2YgdGhlIGRhdGEKaGVhZChnZHBwcF9ncm93dGgpCmBgYAoKIyMgVHJhbnNmb3JtIHRoZSBldmVudCBkYXRhCgpUaGUgdW5pdCBvZiBhbmFseXNpcyBvZiB0aGUgYWNsZWQgZGF0YSBpcyBzZXQgYXQgdGhlIGxvY2F0aW9uLWRheS4gV2UgbmVlZCB0byBhZ2dyZWdhdGUgdGhlc2UgZGF0YSBzbyB0aGF0IGl0IGlzIGF0IHRoZSBjb3VudHJ5LXllYXIuIFJlbHlpbmcgb25seSBvbiB0aGUgdGlkeXZlcnNlIGZ1bmN0aW9uLCBnZW5lcmF0ZSBhIG5ldyBkYXRhIGZyYW1lIHRoYXQgaGFzIHRoZSBmb2xsb3dpbmcgZmllbGRzOgoKLSBgY291bnRyeWAgKHVuaXQpOwotIGB5ZWFyYCAodGltZSk7Ci0gYGZhdGFsaXRpZXNgID0gdG90YWwgbnVtYmVyIG9mIGZhdGFsaXRpZXMgaW4gYSBnaXZlbiBjb3VudHJ5LXllYXI7Ci0gYGxuX2ZhdGFsaXRpZXNgID0gbmF0dXJhbCBsb2cgb2YgdGhlIG51bWJlciBvZiBmYXRhbGl0aWVzIChtYWluIElWKTsKLSBgbl9ldmVudHNgID0gdG90YWwgbnVtYmVyIG9mIGV2ZW50cyB0aGF0IHRvb2sgcGxhY2UgaW4gYSBnaXZlbiBjb3VudHJ5OwotIGBsbl9uX2V2ZW50c2AgPSBuYXR1cmFsIGxvZyBvZiB0aGUgbnVtYmVyIG9mIGV2ZW50cyAoY29udHJvbCkuCgogCgpgYGB7cn0KYWNsZWRfY291bnRyeV95ZWFyIDwtCiAgYWNsZWQgJT4lIAogIGdyb3VwX2J5KGNvdW50cnkseWVhcikgJT4lIAogIHN1bW1hcml6ZShmYXRhbGl0aWVzID0gc3VtKGZhdGFsaXRpZXMpLAogICAgICAgICAgICBsbl9mYXRhbGl0aWVzID0gbG9nKGZhdGFsaXRpZXMgKyAxKSwKICAgICAgICAgICAgbl9ldmVudHMgPSBuKCksCiAgICAgICAgICAgIGxuX25fZXZlbnRzID0gbG9nKG5fZXZlbnRzICsgMSkpICU+JSAKICB1bmdyb3VwCgphY2xlZF9jb3VudHJ5X3llYXIgJT4lIHNhbXBsZV9uKDUpCmBgYAoKIyMgSm9pbiB0aGUgRGF0YQoKTm93IHRoYXQgd2UndmUgY29udmVydGVkIG91ciBldmVudC1sZXZlbCBkYXRhIGludG8gY291dHJ5LXllYXItbGV2ZWwgZGF0YSwgbGV0J3MgbWVyZ2UgdGhlIGdyb3d0aCBkYXRhIG9udG8gdGhlIGNvbmZsaWN0IGRhdGEuCgpBIGZldyB0aGluZ3MgdG8ga2VlcCBpbiBtaW5kOgoKLSBDb3VudHJ5IG5hbWVzIG1pZ2h0IGJlIHNwZWxsZWQgZGlmZmVyZW50bHksIHNvIHdlJ2xsIHdhbnQgdG8gZG91YmxlIGNoZWNrIHRoYXQgbm8gZGF0YSB3YXMgbG9zdCBpbiB0aGUgbWVyZ2UuIAotIFRoZXJlIGFyZSBtb3JlIGNvdW50cmllcyBpbiB0aGUgd2IgZGF0YSB0aGFuIHRoZSBhY2xlZCBkYXRhLCBzbyB3ZSdsbCB3YW50IHRvIG1ha2Ugc3VyZSB3ZSBtZXJnZSBfb250b18gdGhlIGFjbGVkIGRhdGEgYW5kIG5vdCB0aGUgb3RoZXIgd2F5IGFyb3VuZC4gCgpgYGB7cn0KIyBSZWR1Y2UgdGhlIGFjbGVkIGRhdGEgZG93bi4KZ2RwcHBfZ3Jvd3RoMiA8LSBnZHBwcF9ncm93dGggJT4lIHNlbGVjdChjb3VudHJ5LCB5ZWFyID0gZGF0ZSwgZ3Jvd3RoID0gdmFsdWUpCgojIGpvaW4KZGF0IDwtIGxlZnRfam9pbihhY2xlZF9jb3VudHJ5X3llYXIsZ2RwcHBfZ3Jvd3RoMixieT1jKCJjb3VudHJ5IiwieWVhciIpKQoKIyBsb29rIGF0IHRoZSBkYXRhIApkYXQgJT4lIHNhbXBsZV9uKDUpCmBgYApBcmUgd2UgbWlzc2luZyBhbnkgY291bnRyaWVzPyBUaGF0IGlzLCBkaWQgd2UgYW55IGNvdW50cmllcyBub3QgY29tZSB0aHJvdWdoIHdoZW4gbWVyZ2luZz8KCmBgYHtyfQpkYXQgJT4lIAogIGdyb3VwX2J5KGNvdW50cnkpICU+JSAKICBzdW1tYXJpemUobl9taXNzaW5nID0gc3VtKGlzLm5hKGdyb3d0aCkpLAogICAgICAgICAgICB0b3RhbCA9IG4oKSwKICAgICAgICAgICAgcHJvcF9taXNzaW5nID0gbl9taXNzaW5nL3RvdGFsKSAlPiUgCiAgYXJyYW5nZShkZXNjKG5fbWlzc2luZykpCmBgYAoKT2ggbm8gLS0gbG9vb2tzIGxpa2Ugd2UgbWlzc2VkIGEgZmV3LiBMZXQncyBleHBsb3JlIHdoeS4gQXMgd2UgY2FuIHNlZSBiZWxvdywgaXQgbG9va3MgbGlrZSB0aGUgV0IgaGFzIGRpZmZlcmVudCBuYW1pbmcgY29udmVudGlvbnMgZm9yIHNvbWUgb2YgdGhlIGNvdW50cmllcy4gCgpgYGB7cn0KZ2RwcHBfZ3Jvd3RoMiAlPiUgCiAgZmlsdGVyKHN0cl9kZXRlY3QoY291bnRyeSwiQ29uZ28iKSkgJT4lIAogIGRpc3RpbmN0KGNvdW50cnkpCmBgYAoKTm90ZSBhIHByb2JsZW0hIExldCdzIHN0YW5kYXJkaXplIHRoZSBuYW1pbmcgY29udmVudGlvbnMgdXNpbmcgdGhlIGBjb3VudHJ5Y29kZWAgcGFja2FnZS4KCmBgYHtyfQojIGluc3RhbGwucGFja2FnZXMoY291bnRyeWNvZGUpCnJlcXVpcmUoY291bnRyeWNvZGUpCgojIFN0YW5kYXJkaXplIHRoZSBjb3VudHJ5IG5hbWVzIGZvciB0aGUgV0IgZGF0YQpnZHBwcF9ncm93dGgzIDwtIAogIGdkcHBwX2dyb3d0aDIgJT4lIAogIG11dGF0ZShjb3VudHJ5ID0gY291bnRyeWNvZGUoY291bnRyeSwiY291bnRyeS5uYW1lIiwiY291bnRyeS5uYW1lIikpCgojIFN0YW5kYXJkaXplIHRoZSBjb3VudHJ5IG5hbWVzIGZvciB0aGUgQUNMRUQgZGF0YQphY2xlZF9jb3VudHJ5X3llYXIyIDwtIAogIGFjbGVkX2NvdW50cnlfeWVhciAlPiUgCiAgbXV0YXRlKGNvdW50cnkgPSBjb3VudHJ5Y29kZShjb3VudHJ5LCJjb3VudHJ5Lm5hbWUiLCJjb3VudHJ5Lm5hbWUiKSkKICAKCiMgam9pbgpkYXQgPC0gbGVmdF9qb2luKGFjbGVkX2NvdW50cnlfeWVhcjIsZ2RwcHBfZ3Jvd3RoMyxieT1jKCJjb3VudHJ5IiwieWVhciIpKQoKIyBsb29rIGF0IHRoZSBkYXRhIApkYXQgJT4lIHNhbXBsZV9uKDUpCmBgYAoKQ2hlY2sgYWdhaW4gaWYgdGhlcmUgYXJlIGFueSBpc3N1ZXM/IAoKYGBge3J9CmRhdCAlPiUgCiAgZ3JvdXBfYnkoY291bnRyeSkgJT4lIAogIHN1bW1hcml6ZShuX21pc3NpbmcgPSBzdW0oaXMubmEoZ3Jvd3RoKSksCiAgICAgICAgICAgIHRvdGFsID0gbigpLAogICAgICAgICAgICBwcm9wX21pc3NpbmcgPSBuX21pc3NpbmcvdG90YWwpICU+JSAKICBhcnJhbmdlKGRlc2Mobl9taXNzaW5nKSkKYGBgCgoKU3RpbGwgbWlzc2luZyBkYXRhIGZvciBTb21hbGlhLiBXaHkgaXMgdGhpcz8gRG9lc24ndCBsb29rIGxpa2UgdGhlIFdCIGhhcyBncm93dGggZGF0YSBmb3IgU29tYWxpYSBhZnRlciAxOTkwLiAKCmBgYHtyfQpnZHBwcF9ncm93dGgzICU+JSAKICBmaWx0ZXIoY291bnRyeSA9PSAiU29tYWxpYSIpICU+JSAKICBzdW1tYXJ5KCkKYGBgCgojIyBSdW4gbW9kZWwKCkxldCdzIG5vdyBydW4gb3VyICh2ZXJ5IGJhc2ljKSBhbmFseXNpcyEKCmBgYHtyfQpkYXQgJT4lIAogIGxtKGdyb3d0aCB+IGxuX2ZhdGFsaXRpZXMsIGRhdGEgPSAuKSAlPiUgCiAgc3VtbWFyeSguKQpgYGAKTm93IGNvbnRyb2xsaW5nIGZvciB0aGUgbnVtYmVyIG9mIGV2ZW50IGluIHRoZSBjb3VudHJ5LgoKYGBge3J9CmRhdCAlPiUgCiAgbG0oZ3Jvd3RoIH4gbG5fZmF0YWxpdGllcyArIGxuX25fZXZlbnRzLCBkYXRhID0gLikgJT4lIAogIHN1bW1hcnkoLikKYGBgCg==